From 38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4 Mon Sep 17 00:00:00 2001 From: Jacek Antonelli Date: Fri, 15 Aug 2008 23:44:46 -0500 Subject: Second Life viewer sources 1.13.2.12 --- linden/indra/newview/llpanelgroupvoting.cpp | 1385 +++++++++++++++++++++++++++ 1 file changed, 1385 insertions(+) create mode 100644 linden/indra/newview/llpanelgroupvoting.cpp (limited to 'linden/indra/newview/llpanelgroupvoting.cpp') diff --git a/linden/indra/newview/llpanelgroupvoting.cpp b/linden/indra/newview/llpanelgroupvoting.cpp new file mode 100644 index 0000000..1be6bf0 --- /dev/null +++ b/linden/indra/newview/llpanelgroupvoting.cpp @@ -0,0 +1,1385 @@ +/** + * @file llpanelgroupvoting.h + * @brief LLPanelGroupVoting class definition. + * + * Copyright (c) 2003-2007, Linden Research, Inc. + * + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlife.com/developers/opensource/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at http://secondlife.com/developers/opensource/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + */ + +#include "llviewerprecompiledheaders.h" + +#include "roles_constants.h" + +#include "lllineeditor.h" +#include "lltextbox.h" +#include "lltexteditor.h" +#include "llscrolllistctrl.h" +#include "llradiogroup.h" +#include "llspinctrl.h" +#include "llpanelgroupvoting.h" +#include "llnamelistctrl.h" +#include "llbutton.h" + +#include "llagent.h" +#include "llfocusmgr.h" +#include "llviewercontrol.h" +#include "llviewerwindow.h" + +class LLPanelGroupVoting::impl +{ +public: + impl(const LLUUID& group_id); + ~impl(); + + static void onClickCreateProposal(void* userdata); + static void onClickYes(void *userdata); + static void onClickNo(void *userdata); + static void onClickAbstain(void *userdata); + static void onClickSubmitProposal(void *userdata); + static void onClickCancelProposal(void *userdata); + static void onClickViewProposalList(void *userdata); + static void onClickViewProposalItem(void *userdata); + static void onDoubleClickProposal(void *userdata); + + static void onDoubleClickHistoryItem(void *userdata); + static void onClickViewHistoryItem(void *userdata); + static void onClickViewHistoryList(void *userdata); + + void sendGroupProposalsRequest(const LLUUID& group_id); + void sendStartGroupProposal(); + void sendGroupProposalBallot(const char* vote); + void sendGroupVoteHistoryRequest(const LLUUID& group_id); + + void setEnableCreateProposal(); + void setEnableVoteProposal(); + void setEnableListProposals(); + void setEnableHistoryItem(); + void setEnableHistoryList(); + + void updateQuorumText(); + void addPendingActiveScrollListItem(LLFontGL* font, + unsigned int current, + unsigned int expected, + EAddPosition pos); + void addPendingHistoryScrollListItem(LLFontGL* font, + unsigned int current, + unsigned int expected, + EAddPosition pos); + void addNoActiveScrollListItem(LLFontGL* font, EAddPosition pos); + void addNoHistoryScrollListItem(LLFontGL* font, EAddPosition pos); + + + static void processGroupActiveProposalItemReply(LLMessageSystem* msg, + void** data); + static void processGroupVoteHistoryItemReply(LLMessageSystem* msg, + void** data); + +public: + LLUUID mGroupID; + LLUUID mProposalID; + + LLTextBox *mQuorumText; + LLSpinCtrl *mQuorum; + LLTextBox *mQuorumLbl; + LLSpinCtrl *mDuration; + LLTextBox *mDurationLbl; + LLTextBox *mDurationText; + LLRadioGroup *mMajority; + LLTextBox *mMajorityLbl; + LLTextBox *mInstructions; + LLTextBox *mProposalHeader; + LLTextBox *mProposalLbl; + LLTextBox *mStartLbl; + LLTextBox *mEndLbl; + LLTextBox *mStartDate; + LLTextBox *mEndDate; + + LLButton *mBtnYes; + LLButton *mBtnNo; + LLButton *mBtnAbstain; + + LLScrollListCtrl *mProposals; + LLTextEditor *mProposalText; + LLButton *mBtnCreateProposal; + LLButton *mBtnSubmitProposal; + LLButton *mBtnCancelProposal; + LLButton *mBtnViewProposalList; + LLButton *mBtnViewProposalItem; + + LLScrollListCtrl *mVotesHistory; + LLTextBox *mVotesHistoryLbl; + LLTextEditor *mVoteHistoryText; + LLTextBox *mVoteHistoryTextLbl; + LLButton *mBtnViewHistoryList; + LLButton *mBtnViewHistoryItem; + + std::string mViewProposalHeaderText; + std::string mCreateProposalHeaderText; + std::string mVoteProposalHeaderText; + std::string mEmptyProposalText; + + int mNumGroupMembers; + + std::vector mActiveReceived; + std::vector mHistoryReceived; + + int mProposalColumnWidths[10]; + int mHistoryColumnWidths[10]; + + LLUUID mProposalTransID; + LLUUID mHistoryTransID; + + static std::map sGroupIDs; +}; + +//**************************************** +//** LLPanelGroupVoting::impl Functions ** +//**************************************** + +LLPanelGroupVoting::impl::impl(const LLUUID& group_id) +{ + mGroupID = group_id; + + mNumGroupMembers = 0; + + mProposalTransID = LLUUID::null; + mHistoryTransID = LLUUID::null; + + mProposalColumnWidths[0] = -1; + mProposalColumnWidths[1] = 210; + mProposalColumnWidths[2] = 120; + mProposalColumnWidths[3] = -1; + mProposalColumnWidths[4] = 30; + for (int index = 5; index < 10; index++) + { + mProposalColumnWidths[index] = -1; + } + + mHistoryColumnWidths[0] = -1; + mHistoryColumnWidths[1] = 210; // vote text sans non-printable + mHistoryColumnWidths[2] = 120; + mHistoryColumnWidths[3] = -1; + mHistoryColumnWidths[4] = -1; + mHistoryColumnWidths[5] = -1; // full vote text + + //problem what if someone has both the group floater open and the finder + //open to the same group? Some maps that map group ids to panels + //will then only be working for the last panel for a given group id :( + sGroupIDs[group_id] = this; + + mQuorumText = NULL; + mQuorum = NULL; + mQuorumLbl = NULL; + mDuration = NULL; + mDurationLbl = NULL; + mDurationText = NULL; + mMajority = NULL; + mMajorityLbl = NULL; + mInstructions = NULL; + mProposalHeader = NULL; + mProposalLbl = NULL; + mStartLbl = NULL; + mEndLbl = NULL; + mStartDate = NULL; + mEndDate = NULL; + + mBtnYes = NULL; + mBtnNo = NULL; + mBtnAbstain = NULL; + + mProposals = NULL; + mProposalText = NULL; + mBtnCreateProposal = NULL; + mBtnSubmitProposal = NULL; + mBtnViewProposalList = NULL; + mBtnViewProposalItem = NULL; + + mVotesHistory = NULL; + mVotesHistoryLbl = NULL; + mVoteHistoryText = NULL; + mVoteHistoryTextLbl = NULL; + mBtnViewHistoryList = NULL; + mBtnViewHistoryItem = NULL; +} + +LLPanelGroupVoting::impl::~impl() +{ + sGroupIDs.erase(mGroupID); +} + +void LLPanelGroupVoting::impl::setEnableListProposals() +{ + //we make the assumption here that anyone who has the start + //or vote powers should also have the view powers + + /* This power was removed to make group roles simpler + if (!gAgent.hasPowerInGroup(mGroupID, GP_PROPOSAL_VIEW) && + !gAgent.hasPowerInGroup(mGroupID, GP_PROPOSAL_VOTE) && + !gAgent.hasPowerInGroup(mGroupID, GP_PROPOSAL_START) ) + */ + if (!gAgent.isInGroup(mGroupID)) + return; + + + mProposalHeader->setText(mViewProposalHeaderText); + mInstructions->setText("Double Click on the proposal you would like to vote on or press\n" + "Create Proposal to create a new proposal."); + mProposalLbl->setText("Proposal Voting Ends Voted?"); + mProposals->setVisible(TRUE); + mProposals->setBgSelectedColor(gColors.getColor("ScrollSelectedBGColor")); + mProposalText->setVisible(FALSE); + mBtnYes->setEnabled(FALSE); + mBtnYes->setVisible(FALSE); + mBtnNo->setEnabled(FALSE); + mBtnNo->setVisible(FALSE); + mBtnAbstain->setEnabled(FALSE); + mBtnAbstain->setVisible(FALSE); + mBtnSubmitProposal->setEnabled(FALSE); + mBtnSubmitProposal->setVisible(FALSE); + mBtnCancelProposal->setEnabled(FALSE); + mBtnCancelProposal->setVisible(FALSE); + + mBtnViewProposalItem->setEnabled(TRUE); + mBtnViewProposalItem->setVisible(TRUE); + + mBtnViewProposalList->setEnabled(FALSE); + mBtnViewProposalList->setVisible(FALSE); + + mQuorumLbl->setVisible(FALSE); + mQuorum->setEnabled(FALSE); + mQuorum->setVisible(FALSE); + mQuorumText->setVisible(FALSE); + + mDurationLbl->setVisible(FALSE); + mDuration->setEnabled(FALSE); + mDuration->setVisible(FALSE); + mDurationText->setVisible(FALSE); + + mMajorityLbl->setVisible(FALSE); + mMajority->setEnabled(FALSE); + mMajority->setVisible(FALSE); + mStartLbl->setVisible(FALSE); + mStartDate->setVisible(FALSE); + mEndLbl->setVisible(FALSE); + mEndDate->setVisible(FALSE); + + //check to see if the agent can create proposals when enabling the + //create proposal button + BOOL can_create = gAgent.hasPowerInGroup(mGroupID, GP_PROPOSAL_START); + + mBtnCreateProposal->setEnabled(can_create); + mBtnCreateProposal->setVisible(can_create); +} + +void LLPanelGroupVoting::impl::setEnableVoteProposal() +{ + if (!gAgent.hasPowerInGroup(mGroupID, GP_PROPOSAL_VOTE)) + return; + + LLScrollListItem *item = mProposals->getFirstSelected(); + if (item) + { + std::string already_voted; + std::string vote_cast; + + mProposalID = item->getUUID(); + // col 0: index id + mProposalText->setText(item->getColumn(1)->getText()); //proposal text + mEndDate->setText(item->getColumn(2)->getText()); //end date + // col 3: Vote Type + already_voted = item->getColumn(4)->getText(); //already voted + mStartDate->setText(item->getColumn(5)->getText()); //start date + vote_cast = item->getColumn(6)->getText(); // Vote Cast + // col 7: Vote Initiator + mQuorum->set((F32)atoi(item->getColumn(8)->getText().c_str())); //quorum + F32 majority = (F32)atof(item->getColumn(9)->getText().c_str()); //majority + + if(majority == 0.0f) + { // Select the Simple Majority + mMajority->setSelectedIndex(0); + } + else if (majority == 1.0f) + { + //Select Unanimous + mMajority->setSelectedIndex(2); + } + else + { + //Select 2/3 Majority + mMajority->setSelectedIndex(1); + } + + if (already_voted == "Yes") + { + char message[MAX_STRING]; + sprintf(message, "You have voted: %s ", vote_cast.c_str()); + mInstructions->setText(message); + + mBtnYes->setEnabled(FALSE); + mBtnNo->setEnabled(FALSE); + mBtnAbstain->setEnabled(FALSE); + } + else + { + mInstructions->setText("Press the Yes or No button to vote on the proposal, \n" + "or choose to Abstain voting on this proposal."); + + mBtnYes->setEnabled(TRUE); + mBtnNo->setEnabled(TRUE); + mBtnAbstain->setEnabled(TRUE); + } + + mProposalHeader->setText(mVoteProposalHeaderText); + mProposalLbl->setText("Proposal Description"); + mProposals->setVisible(FALSE); + mProposalText->setEnabled(FALSE); + mProposalText->setVisible(TRUE); + mBtnYes->setVisible(TRUE); + mBtnNo->setVisible(TRUE); + mBtnAbstain->setVisible(TRUE); + mBtnSubmitProposal->setEnabled(FALSE); + mBtnSubmitProposal->setVisible(FALSE); + mBtnCreateProposal->setEnabled(FALSE); + mBtnCreateProposal->setVisible(FALSE); + mBtnCancelProposal->setEnabled(FALSE); + mBtnCancelProposal->setVisible(FALSE); + + mBtnViewProposalItem->setEnabled(FALSE); + mBtnViewProposalItem->setVisible(FALSE); + + mBtnViewProposalList->setEnabled(TRUE); + mBtnViewProposalList->setVisible(TRUE); + + mQuorumLbl->setVisible(TRUE); + mQuorum->setEnabled(FALSE); + mQuorum->setVisible(TRUE); + mQuorumText->setVisible(TRUE); + + mDurationLbl->setVisible(FALSE); + mDuration->setEnabled(FALSE); + mDuration->setVisible(FALSE); + mDurationText->setVisible(FALSE); + + mMajorityLbl->setVisible(TRUE); + mMajority->setEnabled(FALSE); + mMajority->setVisible(TRUE); + mStartLbl->setVisible(TRUE); + mStartDate->setVisible(TRUE); + mEndLbl->setVisible(TRUE); + mEndDate->setVisible(TRUE); + } +} + +void LLPanelGroupVoting::impl::setEnableCreateProposal() +{ + if ( !gAgent.hasPowerInGroup(mGroupID, GP_PROPOSAL_START) ) + return; + + mProposalHeader->setText(mCreateProposalHeaderText); + mInstructions->setText("Type the Proposal Description for the new proposal. You can change the\nQuorum, Duration and Majority required to pass the proposal."); + mProposalLbl->setText("Proposal Description"); + mProposals->setVisible(FALSE); + mProposalText->setEnabled(TRUE); + mProposalText->setVisible(TRUE); + mProposalText->setText(""); + mBtnYes->setEnabled(FALSE); + mBtnYes->setVisible(FALSE); + mBtnNo->setEnabled(FALSE); + mBtnNo->setVisible(FALSE); + mBtnAbstain->setEnabled(FALSE); + mBtnAbstain->setVisible(FALSE); + mBtnSubmitProposal->setEnabled(TRUE); + mBtnSubmitProposal->setVisible(TRUE); + mBtnCancelProposal->setEnabled(TRUE); + mBtnCancelProposal->setVisible(TRUE); + mBtnCreateProposal->setEnabled(FALSE); + mBtnCreateProposal->setVisible(FALSE); + + mBtnViewProposalItem->setEnabled(FALSE); + mBtnViewProposalItem->setVisible(FALSE); + + mBtnViewProposalList->setEnabled(FALSE); + mBtnViewProposalList->setVisible(FALSE); + + mQuorumLbl->setVisible(TRUE); + mQuorum->setEnabled(TRUE); + mQuorum->setVisible(TRUE); + mQuorumText->setVisible(TRUE); + + mDurationLbl->setVisible(TRUE); + mDuration->setEnabled(TRUE); + mDuration->setVisible(TRUE); + mDurationText->setVisible(TRUE); + + mMajorityLbl->setVisible(TRUE); + mMajority->setEnabled(TRUE); + mMajority->setVisible(TRUE); + mStartLbl->setVisible(FALSE); + mStartDate->setVisible(FALSE); + mEndLbl->setVisible(FALSE); + mEndDate->setVisible(FALSE); + + if (mQuorum->get() == 0) + { + mQuorum->set((F32)mNumGroupMembers); + } + mQuorum->setMaxValue((F32)mNumGroupMembers); +} + +void LLPanelGroupVoting::impl::setEnableHistoryList() +{ + //we make the assumption here that anyone who has the start + //or vote powers should also have the view powers + + /* This power was removed to make group roles simpler + if (!gAgent.hasPowerInGroup(mGroupID, GP_PROPOSAL_VIEW) && + !gAgent.hasPowerInGroup(mGroupID, GP_PROPOSAL_VOTE) && + !gAgent.hasPowerInGroup(mGroupID, GP_PROPOSAL_START) ) + return; + */ + if (!gAgent.isInGroup(mGroupID)) + return; + + mVotesHistoryLbl->setVisible(TRUE); + mVotesHistory->setVisible(TRUE); + mVotesHistory->setEnabled(TRUE); + + mVoteHistoryTextLbl->setVisible(FALSE); + mVoteHistoryText->setVisible(FALSE); + mBtnViewHistoryList->setVisible(FALSE); + + mBtnViewHistoryItem->setVisible(TRUE); + mBtnViewHistoryItem->setEnabled(TRUE); +} + +void LLPanelGroupVoting::impl::setEnableHistoryItem() +{ + //we make the assumption here that anyone who has the start + //or vote powers should also have the view powers + + /* This power was removed to make group roles simpler + if (!gAgent.hasPowerInGroup(mGroupID, GP_PROPOSAL_VIEW) && + !gAgent.hasPowerInGroup(mGroupID, GP_PROPOSAL_VOTE) && + !gAgent.hasPowerInGroup(mGroupID, GP_PROPOSAL_START) ) + return; + */ + + if (!gAgent.isInGroup(mGroupID)) + return; + + LLScrollListItem *item = mVotesHistory->getFirstSelected(); + // Get full text, not stripped version. + const LLScrollListCell *cell = item->getColumn(5); + mVoteHistoryText->setText(cell->getText()); + + mVotesHistoryLbl->setVisible(FALSE); + mVotesHistory->setVisible(FALSE); + + mVoteHistoryTextLbl->setVisible(TRUE); + mVoteHistoryText->setVisible(TRUE); + mVoteHistoryText->setEnabled(FALSE); + + mBtnViewHistoryList->setVisible(TRUE); + mBtnViewHistoryList->setEnabled(TRUE); + mBtnViewHistoryItem->setVisible(FALSE); +} + +void LLPanelGroupVoting::impl::sendGroupProposalsRequest(const LLUUID& group_id) +{ + //we make the assumption here that anyone who has the start + //or vote powers should also have the view powers + + /* This power was removed to make group roles simpler + if (!gAgent.hasPowerInGroup(mGroupID, GP_PROPOSAL_VIEW) && + !gAgent.hasPowerInGroup(mGroupID, GP_PROPOSAL_VOTE) && + !gAgent.hasPowerInGroup(mGroupID, GP_PROPOSAL_START) ) + return; + */ + if ( !gAgent.isInGroup(mGroupID) ) + return; + + mProposalTransID.generate(); + mProposals->deleteAllItems(); //this should delete all the objects + mActiveReceived.clear(); + + //fill in some text so the user will at least know that + //we're pining the server in high latency situations + LLFontGL* font = LLFontGL::sSansSerifSmall; + addPendingActiveScrollListItem(font, 0, 0, ADD_BOTTOM); + mProposals->setCanSelect(FALSE); + + LLMessageSystem *msg = gMessageSystem; + msg->newMessageFast(_PREHASH_GroupActiveProposalsRequest); + msg->nextBlockFast(_PREHASH_AgentData); + msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID() ); + msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID() ); + msg->nextBlockFast(_PREHASH_GroupData); + msg->addUUIDFast(_PREHASH_GroupID, group_id ); + msg->nextBlockFast(_PREHASH_TransactionData); + msg->addUUIDFast(_PREHASH_TransactionID, mProposalTransID); + gAgent.sendReliableMessage(); +} + +void LLPanelGroupVoting::impl::sendStartGroupProposal() +{ + if ( !gAgent.hasPowerInGroup(mGroupID, GP_PROPOSAL_START) ) + return; + + F32 majority = 0.f; + S32 duration_seconds = (S32)mDuration->get()*24*60*60; // duration days * 24hours/day * 60min/hr * 60sec/min + + switch (mMajority->getSelectedIndex()) + { + case 0: // Simple Majority + majority = 0.f; + break; + case 1: // 2/3 Majority + majority = 2.f/3.f; + break; + case 2: // Unanimous + majority = 1.0f; + break; + } + + S32 quorum = llfloor(mQuorum->get()); + + LLMessageSystem *msg = gMessageSystem; + + msg->newMessageFast(_PREHASH_StartGroupProposal); + msg->nextBlockFast(_PREHASH_AgentData); + msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID() ); + msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID() ); + + msg->nextBlockFast(_PREHASH_ProposalData); + msg->addUUIDFast(_PREHASH_GroupID, mGroupID); + msg->addF32Fast(_PREHASH_Majority, majority ); + msg->addS32Fast(_PREHASH_Quorum, quorum ); + msg->addS32Fast(_PREHASH_Duration, duration_seconds ); + msg->addStringFast(_PREHASH_ProposalText, mProposalText->getText().c_str()); + + gAgent.sendReliableMessage(); +} + +void LLPanelGroupVoting::impl::sendGroupProposalBallot(const char* vote) +{ + if ( !gAgent.hasPowerInGroup(mGroupID, GP_PROPOSAL_VOTE) ) + return; + + LLMessageSystem *msg = gMessageSystem; + + msg->newMessageFast(_PREHASH_GroupProposalBallot); + msg->nextBlockFast(_PREHASH_AgentData); + msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID() ); + msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID() ); + + msg->nextBlockFast(_PREHASH_ProposalData); + msg->addUUIDFast(_PREHASH_ProposalID, mProposalID); + msg->addUUIDFast(_PREHASH_GroupID, mGroupID); + msg->addStringFast(_PREHASH_VoteCast, vote); + + gAgent.sendReliableMessage(); +} + +void LLPanelGroupVoting::impl::sendGroupVoteHistoryRequest(const LLUUID& group_id) +{ + //we make the assumption here that anyone who has the start + //or vote powers should also have the view powers + + /* This power was removed to make group roles simpler + if (mAwaitingFirstHistoryItem || + (!gAgent.hasPowerInGroup(mGroupID, GP_PROPOSAL_VIEW) && + !gAgent.hasPowerInGroup(mGroupID, GP_PROPOSAL_VOTE) && + !gAgent.hasPowerInGroup(mGroupID, GP_PROPOSAL_START)) ) + return; + */ + + if (!gAgent.isInGroup(mGroupID)) + return; + + mVotesHistory->deleteAllItems(); + mHistoryTransID.generate(); + mHistoryReceived.clear(); + + //add some text so the user knows we're doing something + LLFontGL* font = LLFontGL::sSansSerifSmall; + addPendingHistoryScrollListItem(font, 0, 0, ADD_BOTTOM); + mVotesHistory->setCanSelect(FALSE); + + LLMessageSystem *msg = gMessageSystem; + msg->newMessageFast(_PREHASH_GroupVoteHistoryRequest); + msg->nextBlockFast(_PREHASH_AgentData); + msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID() ); + msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID() ); + msg->nextBlockFast(_PREHASH_GroupData); + msg->addUUIDFast(_PREHASH_GroupID, group_id ); + msg->nextBlockFast(_PREHASH_TransactionData); + msg->addUUIDFast(_PREHASH_TransactionID, mHistoryTransID); + gAgent.sendReliableMessage(); +} + +void LLPanelGroupVoting::impl::updateQuorumText() +{ + if ( mQuorumText ) + { + //update the quorum count + char quorum_text[MAX_STRING]; + sprintf(quorum_text, + " out of %d members must vote", + mNumGroupMembers); + mQuorumText->setText(quorum_text); + } +} + +void LLPanelGroupVoting::impl::addPendingActiveScrollListItem(LLFontGL* font, + unsigned int current, + unsigned int expected, + EAddPosition pos) +{ + LLScrollListItem* row = new LLScrollListItem( TRUE, NULL, LLUUID::null); + if (!row) return; + + std::stringstream pending; + pending << "Retrieving active proposals (" + << current + << "\\" << expected << ")"; + row->addColumn(pending.str(), font); + + mProposals->addItem(row, pos); +} + +void LLPanelGroupVoting::impl::addNoActiveScrollListItem(LLFontGL* font, + EAddPosition pos) +{ + LLScrollListItem* row = new LLScrollListItem( TRUE, NULL, LLUUID::null); + if (!row) return; + + row->addColumn("There are currently no active proposals", font); + mProposals->addItem(row, pos); +} + +void LLPanelGroupVoting::impl::addNoHistoryScrollListItem(LLFontGL* font, + EAddPosition pos) +{ + LLScrollListItem* row = new LLScrollListItem( TRUE, NULL, LLUUID::null); + if (!row) return; + + row->addColumn("There are currently no archived proposals", font); + mVotesHistory->addItem(row, pos); +} + +void LLPanelGroupVoting::impl::addPendingHistoryScrollListItem(LLFontGL* font, + unsigned int current, + unsigned int expected, + EAddPosition pos) +{ + LLScrollListItem* row = new LLScrollListItem( TRUE, NULL, LLUUID::null); + if (!row) return; + + std::stringstream pending; + pending << "Retrieving archived proposals (" + << current + << "\\" << expected << ")"; + row->addColumn(pending.str(), font); + + mVotesHistory->addItem(row, pos); +} + + +//static +std::map LLPanelGroupVoting::impl::sGroupIDs; + +//static +void LLPanelGroupVoting::impl::processGroupActiveProposalItemReply(LLMessageSystem *msg, void**) +{ + LLUUID agent_id; + msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID, agent_id ); + if (gAgent.getID() != agent_id) + { + llwarns << "Got active group proposals reply for another agent!" + << " Probably a userserver bug!" << llendl; + return; + } + + LLUUID group_id; + LLUUID trans_id; + msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_GroupID, group_id ); + impl* self = get_if_there(sGroupIDs, group_id, (impl*) NULL); + if (!self) + { + return; + } + + msg->getUUIDFast(_PREHASH_TransactionData, + _PREHASH_TransactionID, + trans_id); + + if ( self->mProposalTransID != trans_id ) return; + + + U32 num_expected; + const S32 MAX_STRING_NUM_LEN = 20; + char item_num_string[DB_TERSE_DATETIME_BUF_SIZE]; + char proposal_text[DB_VOTE_TEXT_BUF_SIZE]; + char vote_cast[DB_VOTE_RESULT_BUF_SIZE]; + char start_datetime[DB_DATETIME_BUF_SIZE]; + char end_datetime[DB_DATETIME_BUF_SIZE]; + char vote_type[DB_VOTE_TYPE_BUF_SIZE]; + char majority_text[MAX_STRING_NUM_LEN]; + char quorum_text[MAX_STRING_NUM_LEN]; + char vote_initiator_string[UUID_STR_LENGTH]; + + LLUUID vote_id; + LLUUID vote_initiator; + + F32 majority; + S32 quorum; + BOOL already_voted; + LLFontGL* font = LLFontGL::sSansSerifSmall; + S32 num_proposals = msg->getNumberOfBlocksFast(_PREHASH_ProposalData); + + msg->getU32Fast(_PREHASH_TransactionData, + _PREHASH_TotalNumItems, + num_expected); + + //the first item should be indicative that we + //are currently receiving information or have it all + self->mProposals->deleteSingleItem(0); + + for (int i = 0; i < num_proposals; i++) + { + msg->getStringFast(_PREHASH_ProposalData, _PREHASH_TerseDateID, DB_TERSE_DATETIME_BUF_SIZE, item_num_string, i ); + msg->getUUIDFast(_PREHASH_ProposalData, _PREHASH_VoteID, vote_id, i ); + msg->getStringFast(_PREHASH_ProposalData, _PREHASH_StartDateTime, DB_DATETIME_BUF_SIZE, start_datetime, i ); + msg->getStringFast(_PREHASH_ProposalData, _PREHASH_EndDateTime, DB_DATETIME_BUF_SIZE, end_datetime, i ); + msg->getUUIDFast(_PREHASH_ProposalData, _PREHASH_VoteInitiator, vote_initiator, i ); + msg->getBOOLFast(_PREHASH_ProposalData,_PREHASH_AlreadyVoted, already_voted, i ); + msg->getStringFast(_PREHASH_ProposalData,_PREHASH_VoteCast, DB_VOTE_RESULT_BUF_SIZE, vote_cast, i ); + msg->getStringFast(_PREHASH_ProposalData, _PREHASH_ProposalText, DB_VOTE_TEXT_BUF_SIZE, proposal_text, i ); + msg->getF32Fast(_PREHASH_ProposalData, _PREHASH_Majority, majority, i ); + msg->getS32Fast(_PREHASH_ProposalData, _PREHASH_Quorum, quorum, i ); + + vote_initiator.toString(vote_initiator_string); + sprintf(majority_text, "%f", majority); + sprintf(quorum_text, "%i", quorum); + + LLScrollListItem *row = new LLScrollListItem( TRUE, NULL, vote_id ); + if (!row) return; + S32 index = 0; + + row->addColumn(item_num_string, font, self->mProposalColumnWidths[index++]); // Use less readable datatime for sorting... + row->addColumn(proposal_text, font, self->mProposalColumnWidths[index++]); + row->addColumn(end_datetime, font, self->mProposalColumnWidths[index++]); + row->addColumn(vote_type, font, self->mProposalColumnWidths[index++]); + row->addColumn(already_voted ? "Yes" : "No", font, self->mProposalColumnWidths[index++]); + row->addColumn(start_datetime, font, self->mProposalColumnWidths[index++]); + row->addColumn(vote_cast, font, self->mProposalColumnWidths[index++]); + row->addColumn(vote_initiator_string, font, self->mProposalColumnWidths[index++]); + row->addColumn(quorum_text, font, self->mProposalColumnWidths[index++]); + row->addColumn(majority_text, font, self->mProposalColumnWidths[index++]); + self->mActiveReceived.push_back(row); + } + + int received = self->mActiveReceived.size(); + if ( num_expected == 0 ) + { + //we are expecting 0 items, put up a message indicating tehre are + //no active proposals and make the scroll list unselectable + self->addNoActiveScrollListItem(font, ADD_BOTTOM); + self->mProposals->setCanSelect(FALSE); + } + else if ( (U32)received != num_expected ) + { + self->addPendingActiveScrollListItem(font, + received, + num_expected, + ADD_BOTTOM); + self->mProposals->setCanSelect(FALSE); + } + else + { + //all done display all of the items + std::vector::iterator it = self->mActiveReceived.begin(); + std::vector::iterator end = self->mActiveReceived.end(); + + for (; it != end; it++) + { + self->mProposals->addItem((*it), ADD_SORTED); + } + + self->mProposals->setCanSelect(TRUE); + } +} + +//static +void LLPanelGroupVoting::impl::processGroupVoteHistoryItemReply(LLMessageSystem *msg, void**) +{ + LLFontGL *font = LLFontGL::sSansSerifSmall; + LLUUID agent_id; + msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID, agent_id ); + if (gAgent.getID() != agent_id) + { + llwarns << "Got group voting history reply for another agent!" + << " Probably a userserver bug!" << llendl; + return; + } + + LLUUID group_id; + msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_GroupID, group_id ); + impl* self = sGroupIDs[group_id]; + if (!self) + { + return; + } + + LLUUID trans_id; + U32 num_expected; + + msg->getU32Fast(_PREHASH_TransactionData, + _PREHASH_TotalNumItems, + num_expected); + msg->getUUIDFast(_PREHASH_TransactionData, + _PREHASH_TransactionID, + trans_id); + + if ( self->mHistoryTransID != trans_id ) return; + + //the first item should be some text + //explaining that we are attempting to receive information + //or are currently receiving information, so we should clear out + //the first line + self->mVotesHistory->deleteSingleItem(0); + + if ( num_expected == 0 ) + { + //we are expecting 0 items, put up a message indicating tehre are + //no active proposals and make the scroll list unselectable + self->addNoHistoryScrollListItem(font, ADD_BOTTOM); + self->mVotesHistory->setCanSelect(FALSE); + + return; + } + + const S32 ITEM_NUM_MAX_BUF_LEN = 15; + char item_num_string[ITEM_NUM_MAX_BUF_LEN]; + char proposal_text[DB_VOTE_TEXT_BUF_SIZE]; + char vote_result[MAX_STRING]; + char start_datetime[DB_DATETIME_BUF_SIZE]; + char end_datetime[DB_DATETIME_BUF_SIZE]; + char vote_type[DB_VOTE_TYPE_BUF_SIZE]; + + LLString vote_text; + LLUUID vote_id; + LLUUID vote_initiator; + LLUUID winner_id; + + F32 majority; + S32 quorum; + + msg->getStringFast(_PREHASH_HistoryItemData, _PREHASH_TerseDateID, ITEM_NUM_MAX_BUF_LEN, item_num_string ); + msg->getUUIDFast(_PREHASH_HistoryItemData, _PREHASH_VoteID, vote_id ); + msg->getStringFast(_PREHASH_HistoryItemData, _PREHASH_StartDateTime, DB_DATETIME_BUF_SIZE, start_datetime ); + msg->getStringFast(_PREHASH_HistoryItemData, _PREHASH_EndDateTime, DB_DATETIME_BUF_SIZE, end_datetime ); + msg->getUUIDFast(_PREHASH_HistoryItemData, _PREHASH_VoteInitiator, vote_initiator); + msg->getStringFast(_PREHASH_HistoryItemData, _PREHASH_VoteType, DB_VOTE_TYPE_BUF_SIZE, vote_type); + msg->getStringFast(_PREHASH_HistoryItemData,_PREHASH_VoteResult, DB_VOTE_RESULT_BUF_SIZE, vote_result); + msg->getStringFast(_PREHASH_HistoryItemData, _PREHASH_ProposalText, DB_VOTE_TEXT_BUF_SIZE, proposal_text ); + msg->getF32Fast(_PREHASH_HistoryItemData, _PREHASH_Majority, majority); + msg->getS32Fast(_PREHASH_HistoryItemData, _PREHASH_Quorum, quorum); + + S32 vote_items = msg->getNumberOfBlocksFast(_PREHASH_VoteItem); + + if (vote_items > 0) + { + if (!strcmp(vote_type, "Proposal")) + { + LLScrollListItem *row = new LLScrollListItem( TRUE, NULL, vote_id ); + if (!row) return; + row->addColumn(item_num_string, font, self->mHistoryColumnWidths[0]); + + vote_text.assign(proposal_text); + vote_text.append("\n\n--\n"); + if (!strcmp(vote_result, "Success")) + { + vote_text.append("Proposal PASSED."); + } + else + { + vote_text.append("Proposal FAILED."); + } + vote_text.append(" Votes->\n"); + + char vote_result[DB_VOTE_RESULT_BUF_SIZE]; + char result_msg[MAX_STRING]; + S32 num_votes; + + for (S32 i = 0; i < vote_items; ++i) + { + msg->getStringFast(_PREHASH_VoteItem, _PREHASH_VoteCast, DB_VOTE_RESULT_BUF_SIZE, vote_result, i); + msg->getS32Fast(_PREHASH_VoteItem, _PREHASH_NumVotes, num_votes, i); + sprintf(result_msg, + " %s: %d\n", + vote_result, + num_votes); + vote_text.append(result_msg); + } + + vote_text.append("\n"); + + LLString vote_text_stripped = vote_text; + LLString::stripNonprintable(vote_text_stripped); + + row->addColumn(vote_text_stripped, font, self->mHistoryColumnWidths[1]); + row->addColumn(end_datetime, font, self->mHistoryColumnWidths[2]); + row->addColumn(vote_type, font, self->mHistoryColumnWidths[3]); + row->addColumn(vote_result, font, self->mHistoryColumnWidths[4]); + row->addColumn(vote_text, font, self->mHistoryColumnWidths[5]); + + self->mHistoryReceived.push_back(row); + } //end if proposal + } //end if vote_items > 0 + + int received = self->mHistoryReceived.size(); + if ( (U32)received != num_expected ) + { + self->addPendingHistoryScrollListItem(font, + received, + num_expected, + ADD_BOTTOM); + self->mVotesHistory->setCanSelect(FALSE); + } + else + { + //all done display all of the items + std::vector::iterator it = self->mHistoryReceived.begin(); + std::vector::iterator end = self->mHistoryReceived.end(); + + for (; it != end; it++) + { + self->mVotesHistory->addItem((*it), ADD_SORTED); + } + + self->mVotesHistory->setCanSelect(TRUE); + } +} + +//static +void LLPanelGroupVoting::impl::onClickCreateProposal(void* userdata) +{ + impl* self = (impl*)userdata; + if ( self ) self->setEnableCreateProposal(); +} + +//static +void LLPanelGroupVoting::impl::onClickYes(void *userdata) +{ + LLPanelGroupVoting::impl* self = (LLPanelGroupVoting::impl*)userdata; + + if ( self && self->mInstructions ) + { + self->mInstructions->setText("Submitting Yes to proposal..."); + self->sendGroupProposalBallot("Yes"); + + //refresh the proposals now that we've hit yes + self->sendGroupProposalsRequest(self->mGroupID); + self->sendGroupVoteHistoryRequest(self->mGroupID); + self->setEnableListProposals(); + } +} + +//static +void LLPanelGroupVoting::impl::onClickNo(void *userdata) +{ + LLPanelGroupVoting::impl* self = (LLPanelGroupVoting::impl*)userdata; + + if ( self && self->mInstructions ) + { + self->mInstructions->setText("Submitting No to proposal..."); + self->sendGroupProposalBallot("No"); + + //refresh the proposals now that we've hit no + self->sendGroupProposalsRequest(self->mGroupID); + self->sendGroupVoteHistoryRequest(self->mGroupID); + self->setEnableListProposals(); + } +} + +//static +void LLPanelGroupVoting::impl::onClickAbstain(void *userdata) +{ + impl* self = (LLPanelGroupVoting::impl*) userdata; + + if ( self && self->mInstructions ) + { + self->mInstructions->setText("Submitting Abstention to proposal..."); + self->sendGroupProposalBallot("Abstain"); + + //refresh the proposals now that we've hit abstain + self->sendGroupProposalsRequest(self->mGroupID); + self->sendGroupVoteHistoryRequest(self->mGroupID); + self->setEnableListProposals(); + } +} + +//static +void LLPanelGroupVoting::impl::onClickSubmitProposal(void *userdata) +{ + gFocusMgr.setKeyboardFocus(NULL, NULL); + impl* self = (impl*)userdata; + + if ( self && self->mInstructions && self->mProposalText ) + { + //check to see if the proposal has any text for some form of + //"validation" + if ( self->mProposalText->getText().empty() ) + { + //throw up an error dialog + LLString::format_map_t args; + args["[MESSAGE]"] = self->mEmptyProposalText; + gViewerWindow->alertXml("GenericAlert", args); + return; + } + + self->mInstructions->setText("Submitting new Proposal..."); + self->sendStartGroupProposal(); + + //refresh the proposals now that we've submitted a new one + self->sendGroupProposalsRequest(self->mGroupID); + self->setEnableListProposals(); + } +} + +//static +void LLPanelGroupVoting::impl::onClickCancelProposal(void* userdata) +{ + impl* self = (impl*)userdata; + + if ( self ) + { + self->setEnableListProposals(); + } +} + +//static +void LLPanelGroupVoting::impl::onClickViewProposalList(void *userdata) +{ + impl* self = (LLPanelGroupVoting::impl*)userdata; + + if ( self ) self->setEnableListProposals(); +} + +//static +void LLPanelGroupVoting::impl::onClickViewProposalItem(void *userdata) +{ + impl* self = (LLPanelGroupVoting::impl*)userdata; + + if ( self && self->mProposals ) + { + if (self->mProposals->getFirstSelected() != NULL) + { + self->setEnableVoteProposal(); + } + else + { + gViewerWindow->alertXml("SelectProposalToView"); + } + } +} + +//static +void LLPanelGroupVoting::impl::onDoubleClickProposal(void *userdata) +{ + impl* self = (impl*)userdata; + if ( self && self->mProposals->getFirstSelected() != NULL ) + { + self->setEnableVoteProposal(); + } +} + +//static +void LLPanelGroupVoting::impl::onDoubleClickHistoryItem(void *userdata) +{ + impl* self = (impl*)userdata; + if ( self && self->mVotesHistory->getFirstSelected() != NULL ) + { + self->setEnableHistoryItem(); + } +} + +//static +void LLPanelGroupVoting::impl::onClickViewHistoryItem(void *userdata) +{ + impl* self = (impl*)userdata; + + if (self->mVotesHistory->getFirstSelected() != NULL) + { + self->setEnableHistoryItem(); + } + else + { + gViewerWindow->alertXml("SelectHistoryItemToView"); + } +} + +//static +void LLPanelGroupVoting::impl::onClickViewHistoryList(void *userdata) +{ + impl* self = (impl*)userdata; + + if ( self) self->setEnableHistoryList(); +} + +//********************************** +//** LLPanelGroupVoting Functions ** +//********************************** + +// static +void* LLPanelGroupVoting::createTab(void* data) +{ + LLUUID* group_id = static_cast(data); + return new LLPanelGroupVoting("panel group voting", *group_id); +} + +LLPanelGroupVoting::LLPanelGroupVoting(const std::string& name, + const LLUUID& group_id) + : LLPanelGroupTab(name, group_id) +{ + mImpl = new impl(group_id); +} + +LLPanelGroupVoting::~LLPanelGroupVoting() +{ + delete mImpl; +} + +BOOL LLPanelGroupVoting::isVisibleByAgent(LLAgent* agentp) +{ + //if they are in the group, the panel is viewable + return mAllowEdit && agentp->isInGroup(mGroupID); +} + +BOOL LLPanelGroupVoting::postBuild() +{ + bool recurse = true; + + mImpl->mQuorumText = (LLTextBox*) getChildByName("quorum_text", recurse); + mImpl->mDurationText = (LLTextBox*) getChildByName("duration_text", + recurse); + mImpl->mQuorum = (LLSpinCtrl*) getChildByName("quorum", recurse); + mImpl->mQuorumLbl = (LLTextBox*) getChildByName("quorum_lbl", recurse); + mImpl->mDuration = (LLSpinCtrl*) getChildByName("duration", recurse); + mImpl->mDurationLbl = (LLTextBox*) getChildByName("duration_lbl", recurse); + mImpl->mMajority = (LLRadioGroup*) getChildByName("majority", recurse); + mImpl->mMajorityLbl = (LLTextBox*) getChildByName("majority_lbl", recurse); + mImpl->mInstructions = (LLTextBox*) getChildByName("proposal_instructions", + recurse); + mImpl->mProposalHeader = (LLTextBox*) getChildByName("proposal_header", + recurse); + + mImpl->mProposalLbl = (LLTextBox*) getChildByName("proposal_lbl", recurse); + mImpl->mStartLbl = (LLTextBox*) getChildByName("start_lbl", recurse); + mImpl->mEndLbl = (LLTextBox*) getChildByName("end_lbl", recurse); + mImpl->mStartDate = (LLTextBox*) getChildByName("start_date", recurse); + mImpl->mEndDate = (LLTextBox*) getChildByName("end_date", recurse); + + mImpl->mBtnYes = (LLButton*) getChildByName("btn_yes", recurse); + mImpl->mBtnNo = (LLButton*) getChildByName("btn_no", recurse); + mImpl->mBtnAbstain = (LLButton*) getChildByName("btn_abstain", recurse); + + mImpl->mProposals = + (LLScrollListCtrl*) getChildByName("proposals", recurse); + mImpl->mProposalText = + (LLTextEditor*) getChildByName("proposal_text", recurse); + + mImpl->mBtnCreateProposal = (LLButton*) getChildByName("btn_proposal", + recurse); + mImpl->mBtnSubmitProposal = (LLButton*) getChildByName("btn_submit", + recurse); + mImpl->mBtnCancelProposal = (LLButton*) getChildByName("btn_cancel", + recurse); + + mImpl->mBtnViewProposalList = + (LLButton*) getChildByName("btn_view_proposal_list", recurse); + mImpl->mBtnViewProposalItem = + (LLButton*) getChildByName("btn_view_proposal_item", recurse); + + mImpl->mVotesHistory = (LLScrollListCtrl*)getChildByName("history_list", + recurse); + mImpl->mVotesHistoryLbl = (LLTextBox*) getChildByName("history_list_lbl", + recurse); + mImpl->mVoteHistoryText = (LLTextEditor*) getChildByName("vote_text", + recurse); + mImpl->mVoteHistoryTextLbl = (LLTextBox*) getChildByName("vote_text_lbl", + recurse); + + mImpl->mBtnViewHistoryList = + (LLButton*)getChildByName("btn_view_history_list", recurse); + mImpl->mBtnViewHistoryItem = + (LLButton*)getChildByName("btn_view_history_item", recurse); + + LLTextBox *txt = (LLTextBox*) getChildByName("proposals_header_view_txt", + recurse); + if (txt) + { + mImpl->mViewProposalHeaderText = txt->getText(); + removeChild(txt); + } + + txt = (LLTextBox*) getChildByName("proposals_header_create_txt", recurse); + if (txt) + { + mImpl->mCreateProposalHeaderText = txt->getText(); + removeChild(txt); + } + + txt = (LLTextBox*) getChildByName("proposals_header_vote_txt", recurse); + if (txt) + { + mImpl->mVoteProposalHeaderText = txt->getText(); + removeChild(txt); + } + + txt = (LLTextBox*) getChildByName("empty_proposal_txt", recurse); + if (txt) + { + mImpl->mEmptyProposalText = txt->getText(); + removeChild(txt); + } + + mImpl->updateQuorumText(); + + bool success = (mImpl->mQuorumText && + mImpl->mDurationText && + mImpl->mQuorum && + mImpl->mQuorumLbl && + mImpl->mDuration && + mImpl->mDurationLbl && + mImpl->mMajority && + mImpl->mMajorityLbl && + mImpl->mInstructions && + mImpl->mProposalHeader && + mImpl->mProposalLbl && + mImpl->mStartLbl && + mImpl->mEndLbl && + mImpl->mStartDate && + mImpl->mEndDate && + mImpl->mBtnYes && + mImpl->mBtnNo && + mImpl->mBtnAbstain && + mImpl->mProposals && + mImpl->mProposalText && + mImpl->mBtnCreateProposal && + mImpl->mBtnSubmitProposal && + mImpl->mBtnCancelProposal && + mImpl->mBtnViewProposalList && + mImpl->mBtnViewProposalItem && + mImpl->mVotesHistory && + mImpl->mVotesHistoryLbl && + mImpl->mVoteHistoryText && + mImpl->mVoteHistoryTextLbl && + mImpl->mBtnViewHistoryList && + mImpl->mBtnViewHistoryItem ); + + //associate callbacks + if ( success ) + { + mImpl->mProposals->setDoubleClickCallback(impl::onDoubleClickProposal); + mImpl->mProposals->setCallbackUserData(mImpl); + + mImpl->mVotesHistory->setDoubleClickCallback(impl::onDoubleClickHistoryItem); + mImpl->mVotesHistory->setCallbackUserData(mImpl); + + mImpl->mBtnAbstain->setClickedCallback(impl::onClickAbstain); + mImpl->mBtnAbstain->setCallbackUserData(mImpl); + + mImpl->mBtnNo->setClickedCallback(impl::onClickNo); + mImpl->mBtnNo->setCallbackUserData(mImpl); + + mImpl->mBtnYes->setClickedCallback(impl::onClickYes); + mImpl->mBtnYes->setCallbackUserData(mImpl); + + mImpl->mBtnCreateProposal->setClickedCallback(impl::onClickCreateProposal); + mImpl->mBtnCreateProposal->setCallbackUserData(mImpl); + + mImpl->mBtnSubmitProposal->setClickedCallback(impl::onClickSubmitProposal); + mImpl->mBtnSubmitProposal->setCallbackUserData(mImpl); + + mImpl->mBtnCancelProposal->setClickedCallback(impl::onClickCancelProposal); + mImpl->mBtnCancelProposal->setCallbackUserData(mImpl); + + mImpl->mBtnViewProposalList->setClickedCallback(impl::onClickViewProposalList); + mImpl->mBtnViewProposalList->setCallbackUserData(mImpl); + + mImpl->mBtnViewProposalItem->setClickedCallback(impl::onClickViewProposalItem); + mImpl->mBtnViewProposalItem->setCallbackUserData(mImpl); + + mImpl->mBtnViewHistoryList->setClickedCallback(impl::onClickViewHistoryList); + mImpl->mBtnViewHistoryList->setCallbackUserData(mImpl); + + mImpl->mBtnViewHistoryItem->setClickedCallback(impl::onClickViewHistoryItem); + mImpl->mBtnViewHistoryItem->setCallbackUserData(mImpl); + + gMessageSystem->setHandlerFuncFast(_PREHASH_GroupActiveProposalItemReply, + impl::processGroupActiveProposalItemReply); + gMessageSystem->setHandlerFuncFast(_PREHASH_GroupVoteHistoryItemReply, + impl::processGroupVoteHistoryItemReply); + } + + return success && LLPanelGroupTab::postBuild(); +} + + +void LLPanelGroupVoting::activate() +{ + gGroupMgr->sendGroupPropertiesRequest(mGroupID); + update(GC_ALL); + + mImpl->setEnableListProposals(); + mImpl->setEnableHistoryList(); +} + +bool LLPanelGroupVoting::needsApply(LLString& mesg) +{ + return false; +} + +bool LLPanelGroupVoting::apply(LLString& mesg) +{ + return true; +} + +void LLPanelGroupVoting::update(LLGroupChange gc) +{ + LLGroupMgrGroupData* group_datap = NULL; + group_datap = gGroupMgr->getGroupData(mGroupID); + + if ( group_datap ) + { + S32 num_group_members = group_datap->mMemberCount; + mImpl->mNumGroupMembers = num_group_members; + + mImpl->updateQuorumText(); + } + + mImpl->sendGroupProposalsRequest(mGroupID); + mImpl->sendGroupVoteHistoryRequest(mGroupID); +} + -- cgit v1.1