PageRenderTime 205ms CodeModel.GetById 21ms app.highlight 167ms RepoModel.GetById 1ms app.codeStats 1ms

/indra/newview/llpanelgrouplandmoney.cpp

https://bitbucket.org/lindenlab/viewer-beta/
C++ | 1636 lines | 1203 code | 306 blank | 127 comment | 124 complexity | 8e955a1cb2822d10a5e81a11031c7aaa MD5 | raw file
   1/** 
   2 * @file llpanelgrouplandmoney.cpp
   3 * @brief Panel for group land and L$.
   4 *
   5 * $LicenseInfo:firstyear=2006&license=viewerlgpl$
   6 * Second Life Viewer Source Code
   7 * Copyright (C) 2010, Linden Research, Inc.
   8 * 
   9 * This library is free software; you can redistribute it and/or
  10 * modify it under the terms of the GNU Lesser General Public
  11 * License as published by the Free Software Foundation;
  12 * version 2.1 of the License only.
  13 * 
  14 * This library is distributed in the hope that it will be useful,
  15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  17 * Lesser General Public License for more details.
  18 * 
  19 * You should have received a copy of the GNU Lesser General Public
  20 * License along with this library; if not, write to the Free Software
  21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
  22 * 
  23 * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
  24 * $/LicenseInfo$
  25 */
  26
  27#include "llviewerprecompiledheaders.h"
  28
  29#include "llpanelgrouplandmoney.h"
  30
  31#include "lluiconstants.h"
  32#include "roles_constants.h"
  33
  34#include "llparcel.h"
  35#include "llqueryflags.h"
  36
  37#include "llagent.h"
  38#include "lldateutil.h"
  39#include "lliconctrl.h"
  40#include "llfloaterreg.h"
  41#include "lllineeditor.h"
  42#include "llproductinforequest.h"
  43#include "llscrolllistctrl.h"
  44#include "llscrolllistitem.h"
  45#include "llscrolllistcell.h"
  46#include "lltextbox.h"
  47#include "lltabcontainer.h"
  48#include "lltexteditor.h"
  49#include "lltrans.h"
  50#include "lltransactiontypes.h"
  51#include "lltrans.h"
  52#include "lluictrlfactory.h"
  53
  54#include "llstatusbar.h"
  55#include "llfloaterworldmap.h"
  56#include "llviewermessage.h"
  57
  58static LLRegisterPanelClassWrapper<LLPanelGroupLandMoney> t_panel_group_money("panel_group_land_money");
  59
  60
  61
  62////////////////////////////////////////////////////////////////////////////
  63//*************************************************
  64//** LLGroupMoneyTabEventHandler::impl Functions **
  65//*************************************************
  66
  67class LLGroupMoneyTabEventHandlerImpl
  68{
  69public:
  70	LLGroupMoneyTabEventHandlerImpl(LLButton* earlier_buttonp,
  71		 LLButton* later_buttonp,
  72		 LLTextEditor* text_editorp,
  73		 LLPanel* tabpanelp,
  74		 const std::string& loading_text,
  75		 S32 interval_length_days,
  76		 S32 max_interval_days);
  77	~LLGroupMoneyTabEventHandlerImpl();
  78
  79	bool getCanClickLater();
  80	bool getCanClickEarlier();
  81
  82	void updateButtons();
  83
  84	void setGroupID(const LLUUID&	group_id) { mGroupID = group_id; } ;
  85	const LLUUID&	getGroupID() const { return mGroupID;} 
  86
  87
  88//member variables
  89public:
  90	LLUUID mPanelID;
  91	LLUUID mGroupID;
  92
  93	LLPanel* mTabPanelp;
  94
  95	int mIntervalLength;
  96	int mMaxInterval;
  97	int mCurrentInterval;
  98
  99	LLTextEditor* mTextEditorp;
 100	LLButton*     mEarlierButtonp;
 101	LLButton*     mLaterButtonp;
 102
 103	std::string mLoadingText;
 104};
 105
 106
 107class LLGroupMoneyTabEventHandler
 108{
 109public:
 110	LLGroupMoneyTabEventHandler(LLButton* earlier_button,
 111								LLButton* later_button,
 112								LLTextEditor* text_editor,
 113								LLTabContainer* tab_containerp,
 114								LLPanel* panelp,
 115								const std::string& loading_text,
 116								S32 interval_length_days,
 117								S32 max_interval_days);
 118	virtual ~LLGroupMoneyTabEventHandler();
 119
 120	virtual void requestData(LLMessageSystem* msg);
 121	virtual void processReply(LLMessageSystem* msg, void** data);
 122
 123	virtual void onClickEarlier();
 124	virtual void onClickLater();
 125	virtual void onClickTab();
 126
 127	void setGroupID(const LLUUID&	group_id) { if(mImplementationp) mImplementationp->setGroupID(group_id); } ;
 128
 129	static void clickEarlierCallback(void* data);
 130	static void clickLaterCallback(void* data);
 131
 132
 133
 134	static LLMap<LLUUID, LLGroupMoneyTabEventHandler*> sInstanceIDs;
 135	static std::map<LLPanel*, LLGroupMoneyTabEventHandler*> sTabsToHandlers;
 136protected:
 137	LLGroupMoneyTabEventHandlerImpl* mImplementationp;
 138};
 139
 140class LLGroupMoneyDetailsTabEventHandler : public LLGroupMoneyTabEventHandler
 141{
 142public:
 143	LLGroupMoneyDetailsTabEventHandler(LLButton* earlier_buttonp,
 144									   LLButton* later_buttonp,
 145									   LLTextEditor* text_editorp,
 146									   LLTabContainer* tab_containerp,
 147									   LLPanel* panelp,
 148									   const std::string& loading_text
 149									   );
 150	virtual ~LLGroupMoneyDetailsTabEventHandler();
 151
 152	virtual void requestData(LLMessageSystem* msg);
 153	virtual void processReply(LLMessageSystem* msg, void** data);
 154};
 155
 156
 157class LLGroupMoneySalesTabEventHandler : public LLGroupMoneyTabEventHandler
 158{
 159public:
 160	LLGroupMoneySalesTabEventHandler(LLButton* earlier_buttonp,
 161									 LLButton* later_buttonp,
 162									 LLTextEditor* text_editorp,
 163									 LLTabContainer* tab_containerp,
 164									 LLPanel* panelp,
 165									 const std::string& loading_text
 166									 );
 167	virtual ~LLGroupMoneySalesTabEventHandler();
 168
 169	virtual void requestData(LLMessageSystem* msg);
 170	virtual void processReply(LLMessageSystem* msg, void** data);
 171};
 172
 173class LLGroupMoneyPlanningTabEventHandler : public LLGroupMoneyTabEventHandler
 174{
 175public:
 176	LLGroupMoneyPlanningTabEventHandler(LLTextEditor* text_editor,
 177										LLTabContainer* tab_containerp,
 178										LLPanel* panelp,
 179										const std::string& loading_text
 180										);
 181	virtual ~LLGroupMoneyPlanningTabEventHandler();
 182
 183	virtual void requestData(LLMessageSystem* msg);
 184	virtual void processReply(LLMessageSystem* msg, void** data);
 185};
 186
 187////////////////////////////////////////////////////////////////////////////
 188
 189class LLPanelGroupLandMoney::impl
 190{
 191public:
 192	impl(LLPanelGroupLandMoney& panel); //constructor
 193	virtual ~impl();
 194
 195	void requestGroupLandInfo();
 196
 197	int getStoredContribution();
 198	void setYourContributionTextField(int contrib);
 199	void setYourMaxContributionTextBox(int max);
 200
 201	virtual void onMapButton();
 202	virtual bool applyContribution();
 203	virtual void processGroupLand(LLMessageSystem* msg);
 204
 205	static void mapCallback(void* data);
 206	static void contributionCommitCallback(LLUICtrl* ctrl, void* userdata);
 207	static void contributionKeystrokeCallback(LLLineEditor* caller, void* userdata);
 208
 209//member variables
 210public:
 211	LLPanelGroupLandMoney& mPanel;
 212	
 213	LLTextBox* mGroupOverLimitTextp;
 214	LLIconCtrl* mGroupOverLimitIconp;
 215
 216	LLLineEditor* mYourContributionEditorp;
 217
 218	LLButton* mMapButtonp;
 219
 220	LLGroupMoneyTabEventHandler* mMoneyDetailsTabEHp;
 221	LLGroupMoneyTabEventHandler* mMoneyPlanningTabEHp;
 222	LLGroupMoneyTabEventHandler* mMoneySalesTabEHp;
 223
 224	LLScrollListCtrl* mGroupParcelsp;
 225
 226	LLUUID mTransID;
 227
 228	bool mBeenActivated;
 229	bool mNeedsSendGroupLandRequest;
 230	bool mNeedsApply;
 231
 232	std::string mCantViewParcelsText;
 233	std::string mCantViewAccountsText;
 234	std::string mEmptyParcelsText;
 235};
 236
 237//*******************************************
 238//** LLPanelGroupLandMoney::impl Functions **
 239//*******************************************
 240LLPanelGroupLandMoney::impl::impl(LLPanelGroupLandMoney& panel)
 241	: mPanel(panel)
 242{
 243	mTransID = LLUUID::null;
 244
 245	mBeenActivated = false;
 246	mNeedsSendGroupLandRequest = true;
 247	mNeedsApply = false;
 248
 249	mYourContributionEditorp = NULL;
 250	mMapButtonp = NULL;
 251	mGroupParcelsp = NULL;
 252	mGroupOverLimitTextp = NULL;
 253	mGroupOverLimitIconp = NULL;
 254
 255	mMoneySalesTabEHp    = NULL;
 256	mMoneyPlanningTabEHp = NULL;
 257	mMoneyDetailsTabEHp  = NULL;
 258}
 259
 260LLPanelGroupLandMoney::impl::~impl()
 261{
 262	if ( mMoneySalesTabEHp ) delete mMoneySalesTabEHp;
 263	if ( mMoneyDetailsTabEHp ) delete mMoneyDetailsTabEHp;
 264	if ( mMoneyPlanningTabEHp ) delete mMoneyPlanningTabEHp;
 265}
 266
 267void LLPanelGroupLandMoney::impl::requestGroupLandInfo()
 268{
 269	U32 query_flags = DFQ_GROUP_OWNED;
 270
 271	mTransID.generate();
 272	mGroupParcelsp->deleteAllItems();
 273
 274	send_places_query(mPanel.mGroupID, mTransID, "", query_flags, LLParcel::C_ANY, "");
 275}
 276
 277void LLPanelGroupLandMoney::impl::onMapButton()
 278{
 279	LLScrollListItem* itemp;
 280	itemp = mGroupParcelsp->getFirstSelected();
 281	if (!itemp) return;
 282
 283	const LLScrollListCell* cellp;
 284	cellp = itemp->getColumn(itemp->getNumColumns() - 1);	// hidden column is last
 285
 286	F32 global_x = 0.f;
 287	F32 global_y = 0.f;
 288	sscanf(cellp->getValue().asString().c_str(), "%f %f", &global_x, &global_y);
 289
 290	// Hack: Use the agent's z-height
 291	F64 global_z = gAgent.getPositionGlobal().mdV[VZ];
 292
 293	LLVector3d pos_global(global_x, global_y, global_z);
 294	LLFloaterWorldMap* worldmap_instance = LLFloaterWorldMap::getInstance();
 295    if(worldmap_instance)
 296	{
 297		worldmap_instance->trackLocation(pos_global);
 298		LLFloaterReg::showInstance("world_map", "center");
 299	}
 300}
 301
 302bool LLPanelGroupLandMoney::impl::applyContribution()
 303{
 304	// calculate max donation, which is sum of available and current.
 305	S32 your_contribution = 0;
 306	S32 sqm_avail;
 307
 308	your_contribution = getStoredContribution();
 309	sqm_avail = your_contribution;
 310	
 311	if(gStatusBar)
 312	{
 313		sqm_avail += gStatusBar->getSquareMetersLeft();
 314	}
 315
 316	// get new contribution and compare to available
 317	S32 new_contribution = atoi(mYourContributionEditorp->getText().c_str());
 318
 319	if( new_contribution != your_contribution &&
 320		new_contribution >= 0 && 
 321	    new_contribution <= sqm_avail )
 322	{
 323		// update group info and server
 324		if(!gAgent.setGroupContribution(mPanel.mGroupID, new_contribution))
 325		{
 326			// should never happen...
 327			llwarns << "Unable to set contribution." << llendl;
 328			return false;
 329		}
 330	}
 331	else
 332	{
 333		//TODO: throw up some error message here and return?  right now we just
 334		//fail silently and force the previous value  -jwolk
 335		new_contribution =  your_contribution;
 336	}
 337
 338	//set your contribution
 339	setYourContributionTextField(new_contribution);
 340
 341	return true;
 342}
 343
 344// Retrieves the land contribution for this agent that is currently
 345// stored in the database, NOT what is currently entered in the text field
 346int LLPanelGroupLandMoney::impl::getStoredContribution()
 347{
 348	LLGroupData group_data;
 349
 350	group_data.mContribution = 0;
 351	gAgent.getGroupData(mPanel.mGroupID, group_data);
 352
 353	return group_data.mContribution;
 354}
 355
 356// Fills in the text field with the contribution, contrib
 357void LLPanelGroupLandMoney::impl::setYourContributionTextField(int contrib)
 358{
 359	std::string buffer = llformat("%d", contrib);
 360
 361	if ( mYourContributionEditorp )
 362	{
 363		mYourContributionEditorp->setText(buffer);
 364	}
 365}
 366
 367void LLPanelGroupLandMoney::impl::setYourMaxContributionTextBox(int max)
 368{
 369	mPanel.getChild<LLUICtrl>("your_contribution_max_value")->setTextArg("[AMOUNT]", llformat("%d", max));
 370}
 371
 372//static
 373void LLPanelGroupLandMoney::impl::mapCallback(void* data)
 374{
 375	LLPanelGroupLandMoney::impl* selfp = (LLPanelGroupLandMoney::impl*) data;
 376
 377	if ( selfp ) selfp->onMapButton();
 378}
 379
 380void LLPanelGroupLandMoney::impl::contributionCommitCallback(LLUICtrl* ctrl, 
 381															 void* userdata)
 382{
 383	LLPanelGroupLandMoney* tabp    = (LLPanelGroupLandMoney*) userdata;
 384	LLLineEditor*          editorp = (LLLineEditor*) ctrl;
 385
 386	if ( tabp && editorp )
 387	{
 388		impl* self = tabp->mImplementationp;
 389		int your_contribution = 0;
 390		int new_contribution = 0;
 391
 392		new_contribution= atoi(editorp->getText().c_str());
 393		your_contribution = self->getStoredContribution();
 394
 395		//reset their junk data to be "good" data to us
 396		self->setYourContributionTextField(new_contribution);
 397
 398		//check to see if they're contribution text has changed
 399		self->mNeedsApply = new_contribution != your_contribution;
 400		tabp->notifyObservers();
 401	}
 402}
 403
 404void LLPanelGroupLandMoney::impl::contributionKeystrokeCallback(LLLineEditor* caller,
 405																void* userdata)
 406{
 407	impl::contributionCommitCallback(caller, userdata);
 408}
 409
 410//static
 411void LLPanelGroupLandMoney::impl::processGroupLand(LLMessageSystem* msg)
 412{
 413	S32 count = msg->getNumberOfBlocks("QueryData");
 414	if(count > 0)
 415	{
 416		S32 first_block = 0;
 417
 418		LLUUID owner_id;
 419		LLUUID trans_id;
 420
 421		msg->getUUID("QueryData", "OwnerID", owner_id, 0);
 422		msg->getUUID("TransactionData", "TransactionID", trans_id);
 423
 424		if(owner_id.isNull())
 425		{
 426			// special block which has total contribution
 427			++first_block;
 428			
 429			S32 total_contribution;
 430			msg->getS32("QueryData", "ActualArea", total_contribution, 0);
 431			mPanel.getChild<LLUICtrl>("total_contributed_land_value")->setTextArg("[AREA]", llformat("%d", total_contribution));
 432
 433			S32 committed;
 434			msg->getS32("QueryData", "BillableArea", committed, 0);
 435			mPanel.getChild<LLUICtrl>("total_land_in_use_value")->setTextArg("[AREA]", llformat("%d", committed));
 436			
 437			S32 available = total_contribution - committed;
 438			mPanel.getChild<LLUICtrl>("land_available_value")->setTextArg("[AREA]", llformat("%d", available));
 439
 440			if ( mGroupOverLimitTextp && mGroupOverLimitIconp )
 441			{
 442				mGroupOverLimitIconp->setVisible(available < 0);
 443				mGroupOverLimitTextp->setVisible(available < 0);
 444			}
 445		}
 446
 447		if ( trans_id != mTransID ) return;
 448		// This power was removed to make group roles simpler
 449		//if ( !gAgent.hasPowerInGroup(mGroupID, GP_LAND_VIEW_OWNED) ) return;
 450		if (!gAgent.isInGroup(mPanel.mGroupID)) return;
 451		mGroupParcelsp->setCommentText(mEmptyParcelsText);
 452
 453		std::string name;
 454		std::string desc;
 455		S32 actual_area;
 456		S32 billable_area;
 457		U8 flags;
 458		F32 global_x;
 459		F32 global_y;
 460		std::string sim_name;
 461		std::string land_sku;
 462		std::string land_type;
 463		
 464		for(S32 i = first_block; i < count; ++i)
 465		{
 466			msg->getUUID("QueryData", "OwnerID", owner_id, i);
 467			msg->getString("QueryData", "Name", name, i);
 468			msg->getString("QueryData", "Desc", desc, i);
 469			msg->getS32("QueryData", "ActualArea", actual_area, i);
 470			msg->getS32("QueryData", "BillableArea", billable_area, i);
 471			msg->getU8("QueryData", "Flags", flags, i);
 472			msg->getF32("QueryData", "GlobalX", global_x, i);
 473			msg->getF32("QueryData", "GlobalY", global_y, i);
 474			msg->getString("QueryData", "SimName", sim_name, i);
 475
 476			if ( msg->getSizeFast(_PREHASH_QueryData, i, _PREHASH_ProductSKU) > 0 )
 477			{
 478				msg->getStringFast(	_PREHASH_QueryData, _PREHASH_ProductSKU, land_sku, i);
 479				llinfos << "Land sku: " << land_sku << llendl;
 480				land_type = LLProductInfoRequestManager::instance().getDescriptionForSku(land_sku);
 481			}
 482			else
 483			{
 484				land_sku.clear();
 485				land_type = LLTrans::getString("land_type_unknown");
 486			}
 487
 488			S32 region_x = llround(global_x) % REGION_WIDTH_UNITS;
 489			S32 region_y = llround(global_y) % REGION_WIDTH_UNITS;
 490			std::string location = sim_name + llformat(" (%d, %d)", region_x, region_y);
 491			std::string area;
 492			if(billable_area == actual_area)
 493			{
 494				area = llformat("%d", billable_area);
 495			}
 496			else
 497			{
 498				area = llformat("%d / %d", billable_area, actual_area);	
 499			}
 500			
 501			std::string hidden;
 502			hidden = llformat("%f %f", global_x, global_y);
 503
 504			LLSD row;
 505
 506			row["columns"][0]["column"] = "name";
 507			row["columns"][0]["value"] = name;
 508			row["columns"][0]["font"] = "SANSSERIF_SMALL";
 509
 510			row["columns"][1]["column"] = "location";
 511			row["columns"][1]["value"] = location;
 512			row["columns"][1]["font"] = "SANSSERIF_SMALL";
 513			
 514			row["columns"][2]["column"] = "area";
 515			row["columns"][2]["value"] = area;
 516			row["columns"][2]["font"] = "SANSSERIF_SMALL";
 517			
 518			row["columns"][3]["column"] = "type";
 519			row["columns"][3]["value"] = land_type;
 520			row["columns"][3]["font"] = "SANSSERIFSMALL";
 521			
 522			// hidden is always last column
 523			row["columns"][4]["column"] = "hidden";
 524			row["columns"][4]["value"] = hidden;
 525			
 526			mGroupParcelsp->addElement(row);
 527		}
 528	}
 529}
 530
 531//*************************************
 532//** LLPanelGroupLandMoney Functions **
 533//*************************************
 534
 535
 536//static
 537LLMap<LLUUID, LLPanelGroupLandMoney*> LLPanelGroupLandMoney::sGroupIDs;
 538
 539LLPanelGroupLandMoney::LLPanelGroupLandMoney() :
 540	LLPanelGroupTab() 
 541{
 542	//FIXME - add setGroupID();
 543	mImplementationp = new impl(*this);
 544
 545	//problem what if someone has both the group floater open and the finder
 546	//open to the same group?  Some maps that map group ids to panels
 547	//will then only be working for the last panel for a given group id :(
 548
 549	//FIXME - add to setGroupID()
 550	//LLPanelGroupLandMoney::sGroupIDs.addData(group_id, this);
 551}
 552
 553LLPanelGroupLandMoney::~LLPanelGroupLandMoney()
 554{
 555	delete mImplementationp;
 556	LLPanelGroupLandMoney::sGroupIDs.removeData(mGroupID);
 557}
 558
 559void LLPanelGroupLandMoney::activate()
 560{
 561	if ( !mImplementationp->mBeenActivated )
 562	{
 563		//select the first tab
 564		LLTabContainer* tabp = getChild<LLTabContainer>("group_money_tab_container");
 565
 566		if ( tabp )
 567		{
 568			tabp->selectFirstTab();
 569			mImplementationp->mBeenActivated = true;
 570		}
 571
 572		//fill in the max contribution
 573
 574		//This calculation is unfortunately based on
 575		//the status bar's concept of how much land the user has
 576		//which can change dynamically if the user buys new land, gives
 577		//more land to a group, etc.
 578		//A race condition can occur if we want to update the UI's
 579		//concept of the user's max contribution before the status
 580		//bar has been updated from a change in the user's group contribution.
 581
 582		//Since the max contribution should not change solely on changing
 583		//a user's group contribution, (it would only change through
 584		//purchasing of new land) this code is placed here
 585		//and only updated once to prevent the race condition
 586		//at the price of having stale data.
 587		//We need to have the status bar have observers
 588		//or find better way of distributing up to date land data. - jwolk
 589		S32 max_avail = mImplementationp->getStoredContribution();
 590		if(gStatusBar)
 591		{
 592			max_avail += gStatusBar->getSquareMetersLeft();
 593		}
 594		mImplementationp->setYourMaxContributionTextBox(max_avail);
 595	}
 596
 597	mImplementationp->mMapButtonp->setEnabled(false);
 598	update(GC_ALL);
 599}
 600
 601void LLPanelGroupLandMoney::update(LLGroupChange gc)
 602{
 603	if (gc != GC_ALL) return;  //Don't update if it's the wrong panel!
 604
 605	LLTabContainer* tabp = getChild<LLTabContainer>("group_money_tab_container");
 606
 607	if ( tabp )
 608	{
 609		LLPanel* panelp;
 610		LLGroupMoneyTabEventHandler* eh;
 611
 612		panelp = tabp->getCurrentPanel();
 613
 614		//now pull the event handler associated with that L$ tab
 615		if ( panelp )
 616		{
 617			eh = get_if_there(LLGroupMoneyTabEventHandler::sTabsToHandlers,
 618							  panelp,
 619							  (LLGroupMoneyTabEventHandler*)NULL);
 620			if ( eh ) eh->onClickTab();
 621		}
 622	}
 623
 624	mImplementationp->requestGroupLandInfo();
 625	mImplementationp->setYourContributionTextField(mImplementationp->getStoredContribution());
 626}
 627
 628bool LLPanelGroupLandMoney::needsApply(std::string& mesg)
 629{
 630	return mImplementationp->mNeedsApply;
 631}
 632
 633bool LLPanelGroupLandMoney::apply(std::string& mesg)
 634{
 635	if (!mImplementationp->applyContribution() )
 636	{
 637		mesg = getString("land_contrib_error"); 
 638		return false;
 639	}
 640
 641	mImplementationp->mNeedsApply = false;
 642	notifyObservers();
 643
 644	return true;
 645}
 646
 647void LLPanelGroupLandMoney::cancel()
 648{
 649	//set the contribution back to the "stored value"
 650	mImplementationp->setYourContributionTextField(mImplementationp->getStoredContribution());
 651
 652	mImplementationp->mNeedsApply = false;
 653	notifyObservers();
 654}
 655
 656
 657BOOL LLPanelGroupLandMoney::postBuild()
 658{
 659	/* This power was removed to make group roles simpler
 660	bool has_parcel_view     = gAgent.hasPowerInGroup(mGroupID,
 661													  GP_LAND_VIEW_OWNED);
 662	bool has_accounting_view = gAgent.hasPowerInGroup(mGroupID,
 663													  GP_ACCOUNTING_VIEW);
 664	*/
 665	
 666	bool can_view = gAgent.isInGroup(mGroupID);
 667
 668	mImplementationp->mGroupOverLimitIconp = 
 669		getChild<LLIconCtrl>("group_over_limit_icon");
 670	mImplementationp->mGroupOverLimitTextp = 
 671		getChild<LLTextBox>("group_over_limit_text");
 672
 673	mImplementationp->mYourContributionEditorp 
 674		= getChild<LLLineEditor>("your_contribution_line_editor");
 675	if ( mImplementationp->mYourContributionEditorp )
 676	{
 677		LLLineEditor* editor = mImplementationp->mYourContributionEditorp;
 678
 679	    editor->setCommitCallback(mImplementationp->contributionCommitCallback, this);
 680		editor->setKeystrokeCallback(mImplementationp->contributionKeystrokeCallback, this);
 681	}
 682
 683	mImplementationp->mMapButtonp = getChild<LLButton>("map_button");
 684
 685	mImplementationp->mGroupParcelsp = 
 686		getChild<LLScrollListCtrl>("group_parcel_list");
 687
 688	if ( mImplementationp->mGroupParcelsp )
 689	{
 690		mImplementationp->mGroupParcelsp->setCommitCallback(boost::bind(&LLPanelGroupLandMoney::onLandSelectionChanged, this));
 691		mImplementationp->mGroupParcelsp->setCommitOnSelectionChange(true);
 692	}
 693
 694	mImplementationp->mCantViewParcelsText = getString("cant_view_group_land_text");
 695	mImplementationp->mCantViewAccountsText = getString("cant_view_group_accounting_text");
 696	mImplementationp->mEmptyParcelsText = getString("epmty_view_group_land_text");
 697	
 698	if ( mImplementationp->mMapButtonp )
 699	{
 700		mImplementationp->mMapButtonp->setClickedCallback(LLPanelGroupLandMoney::impl::mapCallback, mImplementationp);
 701	}
 702
 703	if ( mImplementationp->mGroupOverLimitTextp )
 704	{
 705		mImplementationp->mGroupOverLimitTextp->setVisible(FALSE);
 706	}
 707
 708	if ( mImplementationp->mGroupOverLimitIconp )
 709	{
 710		mImplementationp->mGroupOverLimitIconp->setVisible(FALSE);
 711	}
 712
 713	if ( !can_view )
 714	{
 715		if ( mImplementationp->mGroupParcelsp )
 716		{
 717			mImplementationp->mGroupParcelsp->setCommentText(
 718							mImplementationp->mCantViewParcelsText);
 719			mImplementationp->mGroupParcelsp->setEnabled(FALSE);
 720		}
 721	}
 722
 723
 724
 725	LLButton* earlierp, *laterp;
 726	LLTextEditor* textp;
 727	LLPanel* panelp;
 728
 729	LLTabContainer* tabcp = getChild<LLTabContainer>("group_money_tab_container");
 730
 731	if ( !can_view )
 732	{
 733		if ( tabcp )
 734		{
 735			S32 i;
 736			S32 tab_count = tabcp->getTabCount();
 737
 738			for (i = tab_count - 1; i >=0; --i)
 739			{
 740				tabcp->enableTabButton(i, false);
 741			}
 742		}
 743	}
 744
 745	std::string loading_text = getString("loading_txt");
 746	
 747	//pull out the widgets for the L$ details tab
 748	earlierp = getChild<LLButton>("earlier_details_button", true);
 749	laterp = getChild<LLButton>("later_details_button", true);
 750	textp = getChild<LLTextEditor>("group_money_details_text", true);
 751	panelp = getChild<LLPanel>("group_money_details_tab", true);
 752
 753	if ( !can_view )
 754	{
 755		textp->setText(mImplementationp->mCantViewAccountsText);
 756	}
 757	else
 758	{
 759		mImplementationp->mMoneyDetailsTabEHp = 
 760			new LLGroupMoneyDetailsTabEventHandler(earlierp,
 761												   laterp,
 762												   textp,
 763												   tabcp,
 764												   panelp,
 765												   loading_text);
 766	}
 767
 768	textp = getChild<LLTextEditor>("group_money_planning_text", true);
 769	panelp = getChild<LLPanel>("group_money_planning_tab", true);
 770
 771	if ( !can_view )
 772	{
 773		textp->setText(mImplementationp->mCantViewAccountsText);
 774	}
 775	else
 776	{
 777		//Temporally disabled for DEV-11287.
 778		mImplementationp->mMoneyPlanningTabEHp = 
 779			new LLGroupMoneyPlanningTabEventHandler(textp,
 780													tabcp,
 781													panelp,
 782													loading_text);
 783	}
 784
 785	//pull out the widgets for the L$ sales tab
 786	earlierp = getChild<LLButton>("earlier_sales_button", true);
 787	laterp = getChild<LLButton>("later_sales_button", true);
 788	textp = getChild<LLTextEditor>("group_money_sales_text", true);
 789	panelp = getChild<LLPanel>("group_money_sales_tab", true);
 790
 791	if ( !can_view )
 792	{
 793		textp->setText(mImplementationp->mCantViewAccountsText);
 794	}
 795	else
 796	{
 797		mImplementationp->mMoneySalesTabEHp = 
 798			new LLGroupMoneySalesTabEventHandler(earlierp,
 799												 laterp,
 800												 textp,
 801												 tabcp,
 802												 panelp,
 803												 loading_text);
 804	}
 805
 806	return LLPanelGroupTab::postBuild();
 807}
 808
 809void LLPanelGroupLandMoney::onLandSelectionChanged()
 810{
 811	mImplementationp->mMapButtonp->setEnabled( mImplementationp->mGroupParcelsp->getItemCount() > 0 );
 812}
 813
 814BOOL LLPanelGroupLandMoney::isVisibleByAgent(LLAgent* agentp)
 815{
 816	return mAllowEdit && agentp->isInGroup(mGroupID);
 817}
 818
 819void LLPanelGroupLandMoney::processPlacesReply(LLMessageSystem* msg, void**)
 820{
 821	LLUUID group_id;
 822	msg->getUUID("AgentData", "QueryID", group_id);
 823
 824	LLPanelGroupLandMoney* selfp = sGroupIDs.getIfThere(group_id);
 825	if(!selfp)
 826	{
 827		llinfos << "Group Panel Land L$ " << group_id << " no longer in existence."
 828				<< llendl;
 829		return;
 830	}
 831
 832	selfp->mImplementationp->processGroupLand(msg);
 833}
 834
 835
 836LLGroupMoneyTabEventHandlerImpl::LLGroupMoneyTabEventHandlerImpl(LLButton* earlier_buttonp,
 837										LLButton* later_buttonp,
 838										LLTextEditor* text_editorp,
 839										LLPanel* tabpanelp,
 840										const std::string& loading_text,
 841										S32 interval_length_days,
 842										S32 max_interval_days)
 843{
 844	mPanelID.generate();
 845
 846	mIntervalLength = interval_length_days;
 847	mMaxInterval = max_interval_days;
 848	mCurrentInterval = 0;
 849
 850	mTextEditorp = text_editorp;
 851	mEarlierButtonp = earlier_buttonp;
 852	mLaterButtonp = later_buttonp;
 853	mTabPanelp = tabpanelp;
 854
 855	mLoadingText = loading_text;
 856}
 857
 858LLGroupMoneyTabEventHandlerImpl::~LLGroupMoneyTabEventHandlerImpl()
 859{
 860}
 861
 862bool LLGroupMoneyTabEventHandlerImpl::getCanClickEarlier()
 863{
 864	return (mCurrentInterval < mMaxInterval);
 865}
 866
 867bool LLGroupMoneyTabEventHandlerImpl::getCanClickLater()
 868{
 869	return ( mCurrentInterval > 0 );
 870}
 871
 872void LLGroupMoneyTabEventHandlerImpl::updateButtons()
 873{
 874	if ( mEarlierButtonp )
 875	{
 876		mEarlierButtonp->setEnabled(getCanClickEarlier());
 877	}
 878	if ( mLaterButtonp )
 879	{
 880		mLaterButtonp->setEnabled(getCanClickLater());
 881	}
 882}
 883
 884//*******************************************
 885//** LLGroupMoneyTabEventHandler Functions **
 886//*******************************************
 887
 888LLMap<LLUUID, LLGroupMoneyTabEventHandler*> LLGroupMoneyTabEventHandler::sInstanceIDs;
 889std::map<LLPanel*, LLGroupMoneyTabEventHandler*> LLGroupMoneyTabEventHandler::sTabsToHandlers;
 890
 891LLGroupMoneyTabEventHandler::LLGroupMoneyTabEventHandler(LLButton* earlier_buttonp,
 892														 LLButton* later_buttonp,
 893														 LLTextEditor* text_editorp,
 894														 LLTabContainer* tab_containerp,
 895														 LLPanel* panelp,
 896														 const std::string& loading_text,
 897														 S32 interval_length_days,
 898														 S32 max_interval_days)
 899{
 900	mImplementationp = new LLGroupMoneyTabEventHandlerImpl(earlier_buttonp,
 901								later_buttonp,
 902								text_editorp,
 903								panelp,
 904								loading_text,
 905								interval_length_days,
 906								max_interval_days);
 907
 908	if ( earlier_buttonp )
 909	{
 910		earlier_buttonp->setClickedCallback(clickEarlierCallback, this);
 911	}
 912
 913	if ( later_buttonp )
 914	{
 915		later_buttonp->setClickedCallback(clickLaterCallback, this);
 916	}
 917
 918	mImplementationp->updateButtons();
 919
 920	if ( tab_containerp && panelp )
 921	{
 922		tab_containerp->setCommitCallback(boost::bind(&LLGroupMoneyTabEventHandler::onClickTab, this));
 923	}
 924
 925	sInstanceIDs.addData(mImplementationp->mPanelID, this);
 926	sTabsToHandlers[panelp] = this;
 927}
 928
 929LLGroupMoneyTabEventHandler::~LLGroupMoneyTabEventHandler()
 930{
 931	sInstanceIDs.removeData(mImplementationp->mPanelID);
 932	sTabsToHandlers.erase(mImplementationp->mTabPanelp);
 933
 934	delete mImplementationp;
 935}
 936
 937
 938void LLGroupMoneyTabEventHandler::onClickTab()
 939{
 940	requestData(gMessageSystem);
 941}
 942
 943void LLGroupMoneyTabEventHandler::requestData(LLMessageSystem* msg)
 944{
 945	//do nothing
 946}
 947
 948void LLGroupMoneyTabEventHandler::processReply(LLMessageSystem* msg, void** data)
 949{
 950	//do nothing
 951}
 952
 953void LLGroupMoneyTabEventHandler::onClickEarlier()
 954{
 955	if ( mImplementationp->mTextEditorp) 
 956	{
 957		mImplementationp->mTextEditorp->setText(mImplementationp->mLoadingText);
 958	}
 959	mImplementationp->mCurrentInterval++;
 960
 961	mImplementationp->updateButtons();
 962
 963	requestData(gMessageSystem);
 964}
 965
 966void LLGroupMoneyTabEventHandler::onClickLater()
 967{
 968	if ( mImplementationp->mTextEditorp )
 969	{
 970		mImplementationp->mTextEditorp->setText(mImplementationp->mLoadingText);
 971	}
 972	mImplementationp->mCurrentInterval--;
 973
 974	mImplementationp->updateButtons();
 975
 976	requestData(gMessageSystem);
 977}
 978
 979//static
 980void LLGroupMoneyTabEventHandler::clickEarlierCallback(void* data)
 981{
 982	LLGroupMoneyTabEventHandler* selfp = (LLGroupMoneyTabEventHandler*) data;
 983
 984	if ( selfp ) selfp->onClickEarlier();
 985}
 986
 987//static
 988void LLGroupMoneyTabEventHandler::clickLaterCallback(void* data)
 989{
 990	LLGroupMoneyTabEventHandler* selfp = (LLGroupMoneyTabEventHandler*) data;
 991	if ( selfp ) selfp->onClickLater();
 992}
 993
 994//**************************************************
 995//** LLGroupMoneyDetailsTabEventHandler Functions **
 996//**************************************************
 997
 998LLGroupMoneyDetailsTabEventHandler::LLGroupMoneyDetailsTabEventHandler(LLButton* earlier_buttonp,
 999																	   LLButton* later_buttonp,
1000																	   LLTextEditor* text_editorp,
1001																	   LLTabContainer* tab_containerp,
1002																	   LLPanel* panelp,
1003																	   const std::string& loading_text)
1004	: LLGroupMoneyTabEventHandler(earlier_buttonp,
1005								  later_buttonp,
1006								  text_editorp,
1007								  tab_containerp,
1008								  panelp,
1009								  loading_text,
1010								  SUMMARY_INTERVAL,
1011								  SUMMARY_MAX)
1012{
1013}
1014
1015LLGroupMoneyDetailsTabEventHandler::~LLGroupMoneyDetailsTabEventHandler()
1016{
1017}
1018
1019void LLGroupMoneyDetailsTabEventHandler::requestData(LLMessageSystem* msg)
1020{
1021	msg->newMessageFast(_PREHASH_GroupAccountDetailsRequest);
1022	msg->nextBlockFast(_PREHASH_AgentData);
1023	msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID() );
1024	msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID() );
1025	msg->addUUIDFast(_PREHASH_GroupID,  mImplementationp->getGroupID() );
1026	msg->nextBlockFast(_PREHASH_MoneyData);
1027	msg->addUUIDFast(_PREHASH_RequestID, mImplementationp->mPanelID );
1028	msg->addS32Fast(_PREHASH_IntervalDays, mImplementationp->mIntervalLength );
1029	msg->addS32Fast(_PREHASH_CurrentInterval, mImplementationp->mCurrentInterval);
1030
1031	gAgent.sendReliableMessage();
1032
1033	if ( mImplementationp->mTextEditorp )
1034	{
1035		mImplementationp->mTextEditorp->setText(mImplementationp->mLoadingText);
1036	}
1037
1038	LLGroupMoneyTabEventHandler::requestData(msg);
1039}
1040
1041void LLGroupMoneyDetailsTabEventHandler::processReply(LLMessageSystem* msg, 
1042													  void** data)
1043{
1044	LLUUID group_id;
1045	msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_GroupID, group_id );
1046	if (mImplementationp->getGroupID() != group_id) 
1047	{
1048		llwarns << "Group Account details not for this group!" << llendl;
1049		return;
1050	}
1051
1052	std::string start_date;
1053	S32 interval_days;
1054	S32 current_interval;
1055
1056	msg->getS32Fast(_PREHASH_MoneyData, _PREHASH_IntervalDays, interval_days );
1057	msg->getS32Fast(_PREHASH_MoneyData, _PREHASH_CurrentInterval, current_interval );
1058	msg->getStringFast(_PREHASH_MoneyData, _PREHASH_StartDate, start_date);
1059
1060	std::string time_str = LLTrans::getString("GroupMoneyDate");
1061	LLSD substitution;
1062
1063	// We don't do time zone corrections of the calculated number of seconds
1064	// because we don't have a full time stamp, only a date.
1065	substitution["datetime"] = LLDateUtil::secondsSinceEpochFromString("%Y-%m-%d", start_date);
1066	LLStringUtil::format (time_str, substitution);
1067
1068	if ( interval_days != mImplementationp->mIntervalLength || 
1069		 current_interval != mImplementationp->mCurrentInterval )
1070	{
1071		llinfos << "Out of date details packet " << interval_days << " " 
1072			<< current_interval << llendl;
1073		return;
1074	}
1075
1076	std::string text = time_str;
1077	text.append("\n\n");
1078
1079	S32 total_amount = 0;
1080	S32 transactions = msg->getNumberOfBlocksFast(_PREHASH_HistoryData);
1081	for(S32 i = 0; i < transactions; i++)
1082	{
1083		S32 amount = 0;
1084		std::string desc;
1085
1086		msg->getStringFast(_PREHASH_HistoryData, _PREHASH_Description, desc, i );
1087		msg->getS32Fast(_PREHASH_HistoryData, _PREHASH_Amount, amount, i);
1088
1089		if (amount != 0)
1090		{
1091			text.append(llformat("%-24s %6d\n", desc.c_str(), amount));
1092		}
1093		else
1094		{
1095			// skip it
1096		}
1097
1098		total_amount += amount;
1099	}
1100
1101	text.append(1, '\n');
1102
1103	text.append(llformat("%-24s %6d\n", LLTrans::getString("GroupMoneyTotal").c_str(), total_amount));
1104
1105	if ( mImplementationp->mTextEditorp )
1106	{
1107		mImplementationp->mTextEditorp->setText(text);
1108	}
1109}
1110
1111//static
1112void LLPanelGroupLandMoney::processGroupAccountDetailsReply(LLMessageSystem* msg, 
1113															void** data)
1114{
1115	LLUUID agent_id;
1116	msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID, agent_id );
1117	if (gAgent.getID() != agent_id)
1118	{
1119		llwarns << "Got group L$ history reply for another agent!" << llendl;
1120		return;
1121	}
1122
1123	LLUUID request_id;
1124	msg->getUUIDFast(_PREHASH_MoneyData, _PREHASH_RequestID, request_id );
1125	LLGroupMoneyTabEventHandler* selfp = LLGroupMoneyTabEventHandler::sInstanceIDs.getIfThere(request_id);
1126	if (!selfp)
1127	{
1128		llwarns << "GroupAccountDetails recieved for non-existent group panel." << llendl;
1129		return;
1130	}
1131
1132	selfp->processReply(msg, data);
1133}
1134
1135//************************************************
1136//** LLGroupMoneySalesTabEventHandler Functions **
1137//************************************************
1138
1139LLGroupMoneySalesTabEventHandler::LLGroupMoneySalesTabEventHandler(LLButton* earlier_buttonp,
1140																   LLButton* later_buttonp,
1141																   LLTextEditor* text_editorp,
1142																   LLTabContainer* tab_containerp,
1143																   LLPanel* panelp,
1144																   const std::string& loading_text)
1145	: LLGroupMoneyTabEventHandler(earlier_buttonp,
1146								  later_buttonp,
1147								  text_editorp,
1148								  tab_containerp,
1149								  panelp,
1150								  loading_text,
1151								  SUMMARY_INTERVAL,
1152								  SUMMARY_MAX)
1153{
1154}
1155
1156LLGroupMoneySalesTabEventHandler::~LLGroupMoneySalesTabEventHandler()
1157{
1158}
1159
1160void LLGroupMoneySalesTabEventHandler::requestData(LLMessageSystem* msg)
1161{
1162	msg->newMessageFast(_PREHASH_GroupAccountTransactionsRequest);
1163	msg->nextBlockFast(_PREHASH_AgentData);
1164	msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID() );
1165	msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID() );
1166	msg->addUUIDFast(_PREHASH_GroupID, mImplementationp->getGroupID() );
1167	msg->nextBlockFast(_PREHASH_MoneyData);
1168	msg->addUUIDFast(_PREHASH_RequestID, mImplementationp->mPanelID );
1169	msg->addS32Fast(_PREHASH_IntervalDays, mImplementationp->mIntervalLength );
1170	msg->addS32Fast(_PREHASH_CurrentInterval, mImplementationp->mCurrentInterval);
1171
1172	gAgent.sendReliableMessage();
1173
1174	if ( mImplementationp->mTextEditorp )
1175	{
1176		mImplementationp->mTextEditorp->setText(mImplementationp->mLoadingText);
1177	}
1178
1179	LLGroupMoneyTabEventHandler::requestData(msg);
1180}
1181
1182void LLGroupMoneySalesTabEventHandler::processReply(LLMessageSystem* msg, 
1183													void** data)
1184{
1185	LLUUID group_id;
1186	msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_GroupID, group_id );
1187	if (mImplementationp->getGroupID() != group_id) 
1188	{
1189		llwarns << "Group Account Transactions not for this group!" << llendl;
1190		return;
1191	}
1192
1193	std::string text = mImplementationp->mTextEditorp->getText();
1194
1195	std::string start_date;
1196	S32 interval_days;
1197	S32 current_interval;
1198
1199	msg->getS32Fast(_PREHASH_MoneyData, _PREHASH_IntervalDays, interval_days );
1200	msg->getS32Fast(_PREHASH_MoneyData, _PREHASH_CurrentInterval, current_interval );
1201	msg->getStringFast(_PREHASH_MoneyData, _PREHASH_StartDate, start_date);
1202
1203	if (interval_days != mImplementationp->mIntervalLength ||
1204	    current_interval != mImplementationp->mCurrentInterval)
1205	{
1206		llinfos << "Out of date details packet " << interval_days << " " 
1207			<< current_interval << llendl;
1208		return;
1209	}
1210
1211	// If this is the first packet, clear the text, don't append.
1212	// Start with the date.
1213	if (text == mImplementationp->mLoadingText)
1214	{
1215		std::string time_str = LLTrans::getString("GroupMoneyDate");
1216		LLSD substitution;
1217
1218		// We don't do time zone corrections of the calculated number of seconds
1219		// because we don't have a full time stamp, only a date.
1220		substitution["datetime"] = LLDateUtil::secondsSinceEpochFromString("%Y-%m-%d", start_date);
1221		LLStringUtil::format (time_str, substitution);
1222
1223		text = time_str + "\n\n";
1224	}
1225
1226	S32 transactions = msg->getNumberOfBlocksFast(_PREHASH_HistoryData);
1227	if (transactions == 0)
1228	{
1229		text.append(LLTrans::getString("none_text")); 
1230	}
1231	else
1232	{
1233		for(S32 i = 0; i < transactions; i++)
1234		{
1235			std::string	time;
1236			S32			type = 0;
1237			S32			amount = 0;
1238			std::string	user;
1239			std::string	item;
1240
1241			msg->getStringFast(_PREHASH_HistoryData, _PREHASH_Time,		time, i);
1242			msg->getStringFast(_PREHASH_HistoryData, _PREHASH_User,		user, i );
1243			msg->getS32Fast(_PREHASH_HistoryData, _PREHASH_Type,		type, i);
1244			msg->getStringFast(_PREHASH_HistoryData, _PREHASH_Item,		item, i );
1245			msg->getS32Fast(_PREHASH_HistoryData, _PREHASH_Amount,		amount, i);
1246
1247			if (amount != 0)
1248			{
1249				std::string verb;
1250
1251				switch(type)
1252				{
1253				case TRANS_OBJECT_SALE:
1254					verb = LLTrans::getString("GroupMoneyBought").c_str();
1255					break;
1256				case TRANS_GIFT:
1257					verb = LLTrans::getString("GroupMoneyPaidYou").c_str();
1258					break;
1259				case TRANS_PAY_OBJECT:
1260					verb = LLTrans::getString("GroupMoneyPaidInto").c_str();
1261					break;
1262				case TRANS_LAND_PASS_SALE:
1263					verb = LLTrans::getString("GroupMoneyBoughtPassTo").c_str();
1264					break;
1265				case TRANS_EVENT_FEE:
1266					verb = LLTrans::getString("GroupMoneyPaidFeeForEvent").c_str();
1267					break;
1268				case TRANS_EVENT_PRIZE:
1269					verb = LLTrans::getString("GroupMoneyPaidPrizeForEvent").c_str();
1270					break;
1271				default:
1272					verb = "";
1273					break;
1274				}
1275
1276				std::string line = llformat("%s %6d - %s %s %s\n", time.c_str(), amount, user.c_str(), verb.c_str(), item.c_str());
1277				text.append(line);
1278			}
1279		}
1280	}
1281
1282	if ( mImplementationp->mTextEditorp)
1283	{
1284		mImplementationp->mTextEditorp->setText(text);
1285	}
1286}
1287
1288//static
1289void LLPanelGroupLandMoney::processGroupAccountTransactionsReply(LLMessageSystem* msg, 
1290																 void** data)
1291{
1292	LLUUID agent_id;
1293	msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID, agent_id );
1294	if (gAgent.getID() != agent_id)
1295	{
1296		llwarns << "Got group L$ history reply for another agent!" << llendl;
1297		return;
1298	}
1299
1300	LLUUID request_id;
1301	msg->getUUIDFast(_PREHASH_MoneyData, _PREHASH_RequestID, request_id );
1302
1303	LLGroupMoneyTabEventHandler* self;
1304
1305	self = LLGroupMoneyTabEventHandler::sInstanceIDs.getIfThere(request_id);
1306	if (!self)
1307	{
1308		llwarns << "GroupAccountTransactions recieved for non-existent group panel." << llendl;
1309		return;
1310	}
1311
1312	self->processReply(msg, data);
1313}
1314
1315//***************************************************
1316//** LLGroupMoneyPlanningTabEventHandler Functions **
1317//***************************************************
1318
1319LLGroupMoneyPlanningTabEventHandler::LLGroupMoneyPlanningTabEventHandler(LLTextEditor* text_editorp,
1320																		 LLTabContainer* tab_containerp,
1321																		 LLPanel* panelp,
1322																		 const std::string& loading_text)
1323	: LLGroupMoneyTabEventHandler(NULL,
1324								  NULL,
1325								  text_editorp,
1326								  tab_containerp,
1327								  panelp,
1328								  loading_text,
1329								  SUMMARY_INTERVAL,
1330								  SUMMARY_MAX)
1331{
1332}
1333
1334LLGroupMoneyPlanningTabEventHandler::~LLGroupMoneyPlanningTabEventHandler()
1335{
1336}
1337
1338void LLGroupMoneyPlanningTabEventHandler::requestData(LLMessageSystem* msg)
1339{
1340	msg->newMessageFast(_PREHASH_GroupAccountSummaryRequest);
1341	msg->nextBlockFast(_PREHASH_AgentData);
1342	msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID() );
1343	msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID() );
1344	msg->addUUIDFast(_PREHASH_GroupID, mImplementationp->getGroupID() );
1345	msg->nextBlockFast(_PREHASH_MoneyData);
1346	msg->addUUIDFast(_PREHASH_RequestID, mImplementationp->mPanelID );
1347	msg->addS32Fast(_PREHASH_IntervalDays, mImplementationp->mIntervalLength);
1348	msg->addS32Fast(_PREHASH_CurrentInterval, 0); //planning has 0 interval
1349
1350	gAgent.sendReliableMessage();
1351
1352	if ( mImplementationp->mTextEditorp )
1353	{
1354		mImplementationp->mTextEditorp->setText(mImplementationp->mLoadingText);
1355	}
1356
1357	LLGroupMoneyTabEventHandler::requestData(msg);
1358}
1359
1360void LLGroupMoneyPlanningTabEventHandler::processReply(LLMessageSystem* msg, 
1361															void** data)
1362{
1363	LLUUID group_id;
1364	msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_GroupID, group_id );
1365	if (mImplementationp->getGroupID() != group_id) 
1366	{
1367		llwarns << "Group Account Summary received not for this group!" << llendl;
1368		return;
1369	}
1370
1371	std::string text;
1372
1373	std::string start_date;
1374	std::string last_stipend_date;
1375	std::string next_stipend_date;
1376	S32 interval_days;
1377	S32 current_interval;
1378	S32 balance;
1379	S32 total_credits;
1380	S32 total_debits;
1381	S32 cur_object_tax;
1382	S32 cur_light_tax;
1383	S32 cur_land_tax;
1384	S32 cur_group_tax;
1385	S32 cur_parcel_dir_fee;
1386	S32 cur_total_tax;
1387	S32 proj_object_tax;
1388	S32 proj_light_tax;
1389	S32 proj_land_tax;
1390	S32 proj_group_tax;
1391	S32 proj_parcel_dir_fee;
1392	S32 proj_total_tax;
1393	S32	non_exempt_members;
1394
1395	msg->getS32Fast(_PREHASH_MoneyData, _PREHASH_IntervalDays, interval_days );
1396	msg->getS32Fast(_PREHASH_MoneyData, _PREHASH_CurrentInterval, current_interval );
1397	msg->getS32Fast(_PREHASH_MoneyData, _PREHASH_Balance, balance );
1398	msg->getS32Fast(_PREHASH_MoneyData, _PREHASH_TotalCredits, total_credits );
1399	msg->getS32Fast(_PREHASH_MoneyData, _PREHASH_TotalDebits, total_debits );
1400	msg->getS32Fast(_PREHASH_MoneyData, _PREHASH_ObjectTaxCurrent, cur_object_tax );
1401	msg->getS32Fast(_PREHASH_MoneyData, _PREHASH_LightTaxCurrent, cur_light_tax );
1402	msg->getS32Fast(_PREHASH_MoneyData, _PREHASH_LandTaxCurrent, cur_land_tax );
1403	msg->getS32Fast(_PREHASH_MoneyData, _PREHASH_GroupTaxCurrent, cur_group_tax );
1404	msg->getS32Fast(_PREHASH_MoneyData, _PREHASH_ParcelDirFeeCurrent, cur_parcel_dir_fee );
1405	msg->getS32Fast(_PREHASH_MoneyData, _PREHASH_ObjectTaxEstimate, proj_object_tax );
1406	msg->getS32Fast(_PREHASH_MoneyData, _PREHASH_LightTaxEstimate, proj_light_tax );
1407	msg->getS32Fast(_PREHASH_MoneyData, _PREHASH_LandTaxEstimate, proj_land_tax );
1408	msg->getS32Fast(_PREHASH_MoneyData, _PREHASH_GroupTaxEstimate, proj_group_tax );
1409	msg->getS32Fast(_PREHASH_MoneyData, _PREHASH_ParcelDirFeeEstimate, proj_parcel_dir_fee );
1410	msg->getS32Fast(_PREHASH_MoneyData, _PREHASH_NonExemptMembers, non_exempt_members );
1411
1412	msg->getStringFast(_PREHASH_MoneyData, _PREHASH_StartDate, start_date);
1413	msg->getStringFast(_PREHASH_MoneyData, _PREHASH_LastTaxDate, last_stipend_date);
1414	msg->getStringFast(_PREHASH_MoneyData, _PREHASH_TaxDate, next_stipend_date);
1415
1416	cur_total_tax = cur_object_tax + cur_light_tax + cur_land_tax + cur_group_tax +  cur_parcel_dir_fee;
1417	proj_total_tax = proj_object_tax + proj_light_tax + proj_land_tax + proj_group_tax + proj_parcel_dir_fee;
1418
1419	if (interval_days != mImplementationp->mIntervalLength || 
1420		current_interval != mImplementationp->mCurrentInterval)
1421	{
1422		llinfos << "Out of date summary packet " << interval_days << " " 
1423			<< current_interval << llendl;
1424		return;
1425	}
1426
1427	text.append(LLTrans::getString("SummaryForTheWeek"));
1428
1429	std::string date_format_str = LLTrans::getString("GroupPlanningDate");
1430	std::string time_str = date_format_str;
1431	LLSD substitution;
1432	// We don't do time zone corrections of the calculated number of seconds
1433	// because we don't have a full time stamp, only a date.
1434	substitution["datetime"] = LLDateUtil::secondsSinceEpochFromString("%Y-%m-%d", start_date);
1435	LLStringUtil::format (time_str, substitution);
1436
1437	text.append(time_str);
1438	text.append(".  ");
1439
1440	if (current_interval == 0)
1441	{
1442		text.append(LLTrans::getString("NextStipendDay"));
1443
1444		time_str = date_format_str;
1445		substitution["datetime"] = LLDateUtil::secondsSinceEpochFromString("%Y-%m-%d", next_stipend_date);
1446		LLStringUtil::format (time_str, substitution);
1447
1448		text.append(time_str);
1449		text.append(".\n\n");
1450		text.append(llformat("%-23sL$%6d\n", LLTrans::getString("GroupMoneyBalance").c_str(), balance ));
1451		text.append(1, '\n');
1452	}
1453
1454	// [DEV-29503] Hide the individual info since
1455	// non_exempt_member here is a wrong choice to calculate individual shares.
1456// 	text.append( LLTrans::getString("GroupIndividualShare"));
1457// 	text.append(llformat( "%-24s %6d      %6d \n", LLTrans::getString("GroupMoneyCredits").c_str(), total_credits, (S32)floor((F32)total_credits/(F32)non_exempt_members)));
1458// 	text.append(llformat( "%-24s %6d      %6d \n", LLTrans::getString("GroupMoneyDebits").c_str(), total_debits, (S32)floor((F32)total_debits/(F32)non_exempt_members)));
1459// 	text.append(llformat( "%-24s %6d      %6d \n", LLTrans::getString("GroupMoneyTotal").c_str(), total_credits + total_debits,  (S32)floor((F32)(total_credits + total_debits)/(F32)non_exempt_members)));
1460
1461	text.append(llformat( "%s\n", LLTrans::getString("GroupColumn").c_str()));
1462	text.append(llformat( "%-24s %6d\n", LLTrans::getString("GroupMoneyCredits").c_str(), total_credits));
1463	text.append(llformat( "%-24s %6d\n", LLTrans::getString("GroupMoneyDebits").c_str(), total_debits));
1464	text.append(llformat( "%-24s %6d\n", LLTrans::getString("GroupMoneyTotal").c_str(), total_credits + total_debits));
1465	
1466	if ( mImplementationp->mTextEditorp )
1467	{
1468		mImplementationp->mTextEditorp->setText(text);
1469	}
1470}
1471
1472//static
1473void LLPanelGroupLandMoney::processGroupAccountSummaryReply(LLMessageSystem* msg, 
1474															void** data)
1475{
1476	LLUUID agent_id;
1477	msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID, agent_id );
1478	if (gAgent.getID() != agent_id)
1479	{
1480		llwarns << "Got group L$ history reply for another agent!" << llendl;
1481		return;
1482	}
1483
1484	LLUUID request_id;
1485	msg->getUUIDFast(_PREHASH_MoneyData, _PREHASH_RequestID, request_id );
1486
1487	LLGroupMoneyTabEventHandler* self;
1488
1489	self = LLGroupMoneyTabEventHandler::sInstanceIDs.getIfThere(request_id);
1490	if (!self)
1491	{
1492		llwarns << "GroupAccountSummary recieved for non-existent group L$ planning tab." << llendl;
1493		return;
1494	}
1495
1496	self->processReply(msg, data);
1497}
1498
1499void LLPanelGroupLandMoney::setGroupID(const LLUUID& id)
1500{
1501	LLPanelGroupLandMoney::sGroupIDs.removeData(mGroupID);
1502	LLPanelGroupTab::setGroupID(id);
1503	LLPanelGroupLandMoney::sGroupIDs.addData(mGroupID, this);
1504
1505
1506	bool can_view = gAgent.isInGroup(mGroupID);
1507
1508	mImplementationp->mGroupOverLimitIconp = 
1509		getChild<LLIconCtrl>("group_over_limit_icon");
1510	mImplementationp->mGroupOverLimitTextp = 
1511		getChild<LLTextBox>("group_over_limit_text");
1512
1513	mImplementationp->mYourContributionEditorp 
1514		= getChild<LLLineEditor>("your_contribution_line_editor");
1515	if ( mImplementationp->mYourContributionEditorp )
1516	{
1517		LLLineEditor* editor = mImplementationp->mYourContributionEditorp;
1518
1519	    editor->setCommitCallback(mImplementationp->contributionCommitCallback, this);
1520		editor->setKeystrokeCallback(mImplementationp->contributionKeystrokeCallback, this);
1521	}
1522
1523	mImplementationp->mMapButtonp = getChild<LLButton>("map_button");
1524
1525	mImplementationp->mGroupParcelsp = 
1526		getChild<LLScrollListCtrl>("group_parcel_list");
1527
1528	if ( mImplementationp->mGroupParcelsp )
1529	{
1530		mImplementationp->mGroupParcelsp->setCommitCallback(boost::bind(&LLPanelGroupLandMoney::onLandSelectionChanged, this));
1531		mImplementationp->mGroupParcelsp->setCommitOnSelectionChange(true);
1532	}
1533
1534	mImplementationp->mCantViewParcelsText = getString("cant_view_group_land_text");
1535	mImplementationp->mCantViewAccountsText = getString("cant_view_group_accounting_text");
1536	
1537	if ( mImplementationp->mMapButtonp )
1538	{
1539		mImplementationp->mMapButtonp->setClickedCallback(LLPanelGroupLandMoney::impl::mapCallback, mImplementationp);
1540	}
1541
1542	if ( mImplementationp->mGroupOverLimitTextp )
1543	{
1544		mImplementationp->mGroupOverLimitTextp->setVisible(FALSE);
1545	}
1546
1547	if ( mImplementationp->mGroupOverLimitIconp )
1548	{
1549		mImplementationp->mGroupOverLimitIconp->setVisible(FALSE);
1550	}
1551
1552	if ( mImplementationp->mGroupParcelsp )
1553	{
1554		mImplementationp->mGroupParcelsp->setEnabled(can_view);
1555	}
1556
1557	if ( !can_view && mImplementationp->mGroupParcelsp )
1558	{
1559		mImplementationp->mGroupParcelsp->setEnabled(FALSE);
1560	}
1561
1562
1563	LLButton* earlierp, *laterp;
1564	LLTextEditor* textp;
1565	LLPanel* panelp;
1566
1567	LLTabContainer* tabcp = getChild<LLTabContainer>("group_money_tab_container");
1568
1569	if ( tabcp )
1570	{
1571		S32 i;
1572		S32 tab_count = tabcp->getTabCount();
1573
1574		for (i = tab_count - 1; i >=0; --i)
1575		{
1576			tabcp->enableTabButton(i, can_view );
1577		}
1578	}
1579
1580	std::string loading_text = getString("loading_txt");
1581	
1582	//pull out the widgets for the L$ details tab
1583	earlierp = getChild<LLButton>("earlier_details_button", true);
1584	laterp = getChild<LLButton>("later_details_button", true);
1585	textp = getChild<LLTextEditor>("group_money_details_text", true);
1586	panelp = getChild<LLPanel>("group_money_details_tab", true);
1587
1588	if ( !can_view )
1589	{
1590		textp->setText(mImplementationp->mCantViewAccountsText);
1591	}
1592	else
1593	{
1594		if(mImplementationp->mMoneyDetailsTabEHp == 0)
1595			mImplementationp->mMoneyDetailsTabEHp = new LLGroupMoneyDetailsTabEventHandler(earlierp,laterp,textp,tabcp,panelp,loading_text);
1596		mImplementationp->mMoneyDetailsTabEHp->setGroupID(mGroupID);
1597	}
1598
1599	textp = getChild<LLTextEditor>("group_money_planning_text", true);
1600	
1601
1602	if ( !can_view )
1603	{
1604		textp->setText(mImplementationp->mCantViewAccountsText);
1605	}
1606	else
1607	{
1608		panelp = getChild<LLPanel>("group_money_planning_tab", true);
1609		if(mImplementationp->mMoneyPlanningTabEHp == 0)
1610			mImplementationp->mMoneyPlanningTabEHp = new LLGroupMoneyPlanningTabEventHandler(textp,tabcp,panelp,loading_text);
1611		mImplementationp->mMoneyPlanningTabEHp->setGroupID(mGroupID);
1612	}
1613
1614	//pull out the widgets for the L$ sales tab
1615	textp = getChild<LLTextEditor>("group_money_sales_text", true);
1616
1617
1618	if ( !can_view )
1619	{
1620		textp->setText(mImplementationp->mCantViewAccountsText);
1621	}
1622	else
1623	{
1624		earlierp = getChild<LLButton>("earlier_sales_button", true);
1625		laterp = getChild<LLButton>("later_sales_button", true);
1626		panelp = getChild<LLPanel>("group_money_sales_tab", true);
1627		if(mImplementationp->mMoneySalesTabEHp == NULL) 
1628			mImplementationp->mMoneySalesTabEHp = new LLGroupMoneySalesTabEventHandler(earlierp,laterp,textp,tabcp,panelp,loading_text);
1629		mImplementationp->mMoneySalesTabEHp->setGroupID(mGroupID);
1630	}
1631
1632	mImplementationp->mBeenActivated = false;
1633
1634	activate();
1635}
1636