Files
SingularityViewer/indra/newview/llpanelgroupvoting.cpp

1653 lines
48 KiB
C++

/**
* @file llpanelgroupvoting.cpp
* @brief LLPanelGroupVoting class definition.
*
* $LicenseInfo:firstyear=2003&license=viewergpl$
*
* Copyright (c) 2003-2009, Linden Research, Inc.
*
* Second Life Viewer Source Code
* 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://secondlifegrid.net/programs/open_source/licensing/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://secondlifegrid.net/programs/open_source/licensing/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.
* $/LicenseInfo$
*/
#include "llviewerprecompiledheaders.h"
#include "roles_constants.h"
#include "lllineeditor.h"
#include "llnotificationsutil.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 "llnotify.h"
#include "llagent.h"
#include "llfocusmgr.h"
#include "llviewercontrol.h"
#include "llviewerwindow.h"
#include "llviewerregion.h"
class AIHTTPTimeoutPolicy;
extern AIHTTPTimeoutPolicy startGroupVoteResponder_timeout;
extern AIHTTPTimeoutPolicy groupProposalBallotResponder_timeout;
class LLPanelGroupVoting::impl
{
public:
impl(LLPanelGroupVoting& panel, 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 std::string& vote);
void sendGroupVoteHistoryRequest(const LLUUID& group_id);
void setEnableCreateProposal();
void setEnableVoteProposal();
void setEnableListProposals();
void setEnableHistoryItem();
void setEnableHistoryList();
void updateQuorumText();
void addPendingActiveScrollListItem(unsigned int current,
unsigned int expected,
EAddPosition pos);
void addPendingHistoryScrollListItem(unsigned int current,
unsigned int expected,
EAddPosition pos);
void addNoActiveScrollListItem(EAddPosition pos);
void addNoHistoryScrollListItem(EAddPosition pos);
static void processGroupActiveProposalItemReply(LLMessageSystem* msg,
void** data);
static void processGroupVoteHistoryItemReply(LLMessageSystem* msg,
void** data);
public:
LLUUID mGroupID;
LLUUID mProposalID;
LLPanelGroupVoting& mPanel;
LLSpinCtrl *mQuorum;
LLTextBox *mQuorumLbl;
LLSpinCtrl *mDuration;
LLTextBox *mDurationLbl;
LLTextBox *mDurationText;
LLRadioGroup *mMajority;
LLTextBox *mMajorityLbl;
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;
int mNumGroupMembers;
std::vector<LLSD> mActiveReceived;
std::vector<LLSD> mHistoryReceived;
U32 mOtherGroupHistoryItems;
int mProposalColumnWidths[10];
int mHistoryColumnWidths[10];
LLUUID mProposalTransID;
LLUUID mHistoryTransID;
static std::map<LLUUID, LLPanelGroupVoting::impl*> sGroupIDs;
};
// ****************************************
// ** LLPanelGroupVoting::impl Functions **
// ****************************************
LLPanelGroupVoting::impl::impl(LLPanelGroupVoting& panel, const LLUUID& group_id)
: mPanel(panel),
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;
mQuorum = NULL;
mQuorumLbl = NULL;
mDuration = NULL;
mDurationLbl = NULL;
mDurationText = NULL;
mMajority = NULL;
mMajorityLbl = NULL;
mStartLbl = NULL;
mEndLbl = NULL;
mStartDate = NULL;
mEndDate = NULL;
mBtnYes = NULL;
mBtnNo = NULL;
mBtnAbstain = NULL;
mProposals = NULL;
mProposalText = NULL;
mBtnCreateProposal = NULL;
mBtnSubmitProposal = NULL;
mBtnCancelProposal = NULL;
mBtnViewProposalList = NULL;
mBtnViewProposalItem = NULL;
mVotesHistory = NULL;
mVotesHistoryLbl = NULL;
mVoteHistoryText = NULL;
mVoteHistoryTextLbl = NULL;
mBtnViewHistoryList = NULL;
mBtnViewHistoryItem = NULL;
mOtherGroupHistoryItems = 0;
}
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;
mPanel.childSetText("proposal_header", mPanel.getString("proposals_header_view_txt"));
mPanel.childSetText("proposal_instructions", mPanel.getString("proposals_header_view_inst"));
mPanel.childSetVisible("proposal_lbl", FALSE);
mPanel.childSetVisible("proposal_voting_lbl", TRUE);
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);
mPanel.childSetVisible("quorum_text", 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
LLScrollListCell * proposal_cell = item->getColumn(1);
if ( proposal_cell )
{
//proposal text
mProposalText->setText(proposal_cell->getValue().asString());
}
else
{ // Something's wrong... should have some text
mProposalText->setText(LLStringUtil::null);
}
proposal_cell = item->getColumn(2);
if (proposal_cell)
{
//end date
mEndDate->setText(proposal_cell->getValue().asString());
}
else
{ // Something's wrong... should have some text
mEndDate->setText(LLStringUtil::null);
}
// col 3: Vote Type
proposal_cell = item->getColumn(3);
if (proposal_cell)
{
//already voted
already_voted = proposal_cell->getValue().asString();
}
else
{ // Something's wrong... should have some text
already_voted = "";
}
proposal_cell = item->getColumn(5);
if (proposal_cell)
{
//start date
mStartDate->setText(proposal_cell->getValue().asString());
}
else
{ // Something's wrong... should have some text
mStartDate->setText(LLStringUtil::null);
}
proposal_cell = item->getColumn(6);
if (proposal_cell)
{
// Vote Cast
vote_cast = proposal_cell->getValue().asString();
}
// col 8: Vote Initiator
proposal_cell = item->getColumn(8);
if (proposal_cell)
{
//quorum
mQuorum->set(
(F32)atoi(proposal_cell->getValue().asString().c_str()));
}
else
{
mQuorum->set(0);
}
F32 majority = 0.0f;
proposal_cell = item->getColumn(9);
if (proposal_cell)
{
//majority
majority =
(F32)atof(proposal_cell->getValue().asString().c_str());
}
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")
{
LLUIString votestr = mPanel.getString("proposals_header_voted_inst");
votestr.setArg("[VOTE]", vote_cast);
mPanel.childSetText("proposal_instructions", votestr.getString());
mBtnYes->setEnabled(FALSE);
mBtnNo->setEnabled(FALSE);
mBtnAbstain->setEnabled(FALSE);
}
else
{
mPanel.childSetText("proposal_instructions", mPanel.getString("proposals_header_vote_inst"));
mBtnYes->setEnabled(TRUE);
mBtnNo->setEnabled(TRUE);
mBtnAbstain->setEnabled(TRUE);
}
mPanel.childSetText("proposal_header", mPanel.getString("proposals_header_vote_txt"));
mPanel.childSetVisible("proposal_lbl", TRUE);
mPanel.childSetVisible("proposal_voting_lbl", FALSE);
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);
mPanel.childSetVisible("quorum_text", 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;
mPanel.childSetText("proposal_header", mPanel.getString("proposals_header_create_txt"));
mPanel.childSetText("proposal_instructions", mPanel.getString("proposals_header_create_inst"));
mPanel.childSetVisible("proposal_lbl", TRUE);
mPanel.childSetVisible("proposal_voting_lbl", FALSE);
mProposals->setVisible(FALSE);
mProposalText->setEnabled(TRUE);
mProposalText->setVisible(TRUE);
mProposalText->setText(LLStringUtil::null);
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);
mPanel.childSetVisible("quorum_text", 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);
if (cell)
{
mVoteHistoryText->setText(cell->getValue().asString());
}
else
{ // Something's wrong...
mVoteHistoryText->setText(LLStringUtil::null);
}
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();
mOtherGroupHistoryItems = 0;
//fill in some text so the user will at least know that
//we're pining the server in high latency situations
addPendingActiveScrollListItem(0, 0, ADD_BOTTOM);
mProposals->setCanSelect(FALSE);
mBtnViewProposalItem->setEnabled(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::handleResponse(
const LLUUID& group_id,
ResponseType response,
bool success)
{
impl* self = NULL;
//see if the voting ballot for the group is still even open
std::map<LLUUID, LLPanelGroupVoting::impl*>::const_iterator self_iter =
LLPanelGroupVoting::impl::sGroupIDs.find(group_id);
if ( LLPanelGroupVoting::impl::sGroupIDs.end() != self_iter )
{
//cool, we found the panel's implementation
//(the panel is still open)
//then we want to do some other stuff :)
self = self_iter->second;
}
if ( self )
{
//refresh the proposals now that we've hit no
self->sendGroupProposalsRequest(self->mGroupID);
if (response == BALLOT)
{
LLSD args;
if (success)
{
args["MESSAGE"] = self->mPanel.getString("vote_recorded");
}
else
{
args["MESSAGE"] = self->mPanel.getString("vote_previously_recorded");
}
LLNotificationsUtil::add("SystemMessage", args);
self->sendGroupVoteHistoryRequest(self->mGroupID);
}
self->setEnableListProposals();
}
}
void LLPanelGroupVoting::handleFailure(
const LLUUID& group_id)
{
impl* self = NULL;
//see if the voting ballot for the group is still even open
std::map<LLUUID, LLPanelGroupVoting::impl*>::const_iterator self_iter =
LLPanelGroupVoting::impl::sGroupIDs.find(group_id);
if ( LLPanelGroupVoting::impl::sGroupIDs.end() != self_iter )
{
//cool, we found the panel's implementation
//(the panel is still open)
//then we want to do some other stuff :)
self = self_iter->second;
}
if ( self )
{
self->setEnableListProposals();
}
}
class LLStartGroupVoteResponder : public LLHTTPClient::ResponderWithResult
{
public:
LLStartGroupVoteResponder(const LLUUID& group_id)
{
mGroupID = group_id;
}
//If we get back a normal response, handle it here
virtual void result(const LLSD& content)
{
//Ack'd the proposal initialization, now let's finish up.
LLPanelGroupVoting::handleResponse(
mGroupID,
LLPanelGroupVoting::START_VOTE);
}
//If we get back an error (not found, etc...), handle it here
virtual void error(U32 status, const std::string& reason)
{
llinfos << "LLPanelGroupVotingResponder::error "
<< status << ": " << reason << llendl;
LLPanelGroupVoting::handleFailure(mGroupID);
}
//Return our timeout policy.
virtual AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return startGroupVoteResponder_timeout; }
private:
LLUUID mGroupID;
};
class LLGroupProposalBallotResponder : public LLHTTPClient::ResponderWithResult
{
public:
LLGroupProposalBallotResponder(const LLUUID& group_id)
{
mGroupID = group_id;
}
//If we get back a normal response, handle it here
virtual void result(const LLSD& content)
{
//Ack'd the proposal initialization, now let's finish up.
LLPanelGroupVoting::handleResponse(
mGroupID,
LLPanelGroupVoting::BALLOT,
content["voted"].asBoolean());
}
//If we get back an error (not found, etc...), handle it here
virtual void error(U32 status, const std::string& reason)
{
llinfos << "LLPanelGroupVotingResponder::error "
<< status << ": " << reason << llendl;
LLPanelGroupVoting::handleFailure(mGroupID);
}
//Return out timeout policy.
virtual AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return groupProposalBallotResponder_timeout; }
private:
LLUUID mGroupID;
};
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());
// *************************************Conversion to capability
LLSD body;
std::string url = gAgent.getRegion()->getCapability("StartGroupProposal");
if (!url.empty())
{
body["agent-id"] = gAgent.getID();
body["session-id"] = gAgent.getSessionID();
body["group-id"] = mGroupID;
body["majority"] = majority;
body["quorum"] = quorum;
body["duration"] = duration_seconds;
body["proposal-text"] = mProposalText->getText();
LLHTTPClient::post(
url,
body,
new LLStartGroupVoteResponder(mGroupID));
}
else
{ //DEPRECATED!!!!!!! This is a fallback just in case our backend cap is not there. Delete this block ASAP!
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());
gAgent.sendReliableMessage();
//This code was moved from the callers to here as part of deprecation.
sendGroupProposalsRequest(mGroupID);
setEnableListProposals();
}
}
void LLPanelGroupVoting::impl::sendGroupProposalBallot(const std::string& vote)
{
if ( !gAgent.hasPowerInGroup(mGroupID, GP_PROPOSAL_VOTE) )
return;
LLSD body;
std::string url = gAgent.getRegion()->getCapability("GroupProposalBallot");
if (!url.empty())
{
body["agent-id"] = gAgent.getID();
body["session-id"] = gAgent.getSessionID();
body["proposal-id"] = mProposalID;
body["group-id"] = mGroupID;
body["vote"] = vote;
LLHTTPClient::post(
url,
body,
new LLGroupProposalBallotResponder(mGroupID));
}
else
{ //DEPRECATED!!!!!!! This is a fallback just in case our backend cap is not there. Delete this block ASAP!
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();
//This code was moved from the callers to here as part of deprecation.
sendGroupProposalsRequest(mGroupID);
sendGroupVoteHistoryRequest(mGroupID);
setEnableListProposals();
}
}
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
addPendingHistoryScrollListItem(0, 0, ADD_BOTTOM);
mVotesHistory->setCanSelect(FALSE);
mBtnViewHistoryItem->setEnabled(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()
{
mPanel.childSetTextArg("quorum_text", "[MEMBERS]", llformat("%d", mNumGroupMembers));
}
void LLPanelGroupVoting::impl::addPendingActiveScrollListItem(unsigned int current,
unsigned int expected,
EAddPosition pos)
{
std::stringstream pending;
// *TODO: translate
pending << "Retrieving active proposals ("
<< current
<< "\\" << expected << ")";
mProposals->addCommentText(pending.str());
}
void LLPanelGroupVoting::impl::addNoActiveScrollListItem(EAddPosition pos)
{
// *TODO: translate
mProposals->addCommentText(std::string("There are currently no active proposals"), pos);
}
void LLPanelGroupVoting::impl::addNoHistoryScrollListItem(EAddPosition pos)
{
// *TODO: translate
mVotesHistory->addCommentText(std::string("There are currently no archived proposals"), pos);
}
void LLPanelGroupVoting::impl::addPendingHistoryScrollListItem(unsigned int current,
unsigned int expected,
EAddPosition pos)
{
// *TODO: translate
std::stringstream pending;
pending << "Retrieving archived proposals ("
<< current
<< "\\" << expected << ")";
mVotesHistory->addCommentText(pending.str());
}
//static
std::map<LLUUID, LLPanelGroupVoting::impl*> LLPanelGroupVoting::impl::sGroupIDs;
static std::string format_date(std::string date)
{
tm t;
if (sscanf(date.c_str(), "%u/%u/%u %u:%u",
&t.tm_mon, &t.tm_mday, &t.tm_year, &t.tm_hour, &t.tm_min) == 5
&& t.tm_year > 1900)
{
t.tm_year -= 1900;
t.tm_mon--;
t.tm_sec = 0;
std::string format = gSavedSettings.getString("ShortDateFormat");
format += " " + gSavedSettings.getString("ShortTimeFormat");
timeStructToFormattedString(&t, format, date);
}
return date;
}
//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!" << 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;
std::string item_num_string;
std::string proposal_text;
std::string vote_cast;
std::string start_datetime;
std::string end_datetime;
std::string vote_type;
std::string majority_text;
std::string quorum_text;
std::string vote_initiator_string;
LLUUID vote_id;
LLUUID vote_initiator;
F32 majority;
S32 quorum;
BOOL already_voted;
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->deleteAllItems();
// make sure column indices are correct when populating with real data
self->mProposals->clearColumns();
for (int i = 0; i < num_proposals; i++)
{
msg->getStringFast(_PREHASH_ProposalData, _PREHASH_TerseDateID, item_num_string, i );
msg->getUUIDFast(_PREHASH_ProposalData, _PREHASH_VoteID, vote_id, i );
msg->getStringFast(_PREHASH_ProposalData, _PREHASH_StartDateTime, start_datetime, i );
msg->getStringFast(_PREHASH_ProposalData, _PREHASH_EndDateTime, 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, vote_cast, i );
msg->getStringFast(_PREHASH_ProposalData, _PREHASH_ProposalText, 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);
majority_text = llformat("%f", majority);
quorum_text = llformat("%i", quorum);
LLSD row;
S32 index = 0;
row["id"] = vote_id;
row["columns"][0]["column"] = "item_num";
row["columns"][0]["value"] = item_num_string;
row["columns"][0]["font"] = "SANSSERIF_SMALL";
row["columns"][0]["width"] = self->mProposalColumnWidths[index++];
row["columns"][1]["column"] = "proposal_text";
row["columns"][1]["value"] = proposal_text;
row["columns"][1]["font"] = "SANSSERIF_SMALL";
row["columns"][1]["width"] = self->mProposalColumnWidths[index++];
row["columns"][2]["column"] = "end_datetime";
row["columns"][2]["value"] = format_date(end_datetime);
row["columns"][2]["font"] = "SANSSERIF_SMALL";
row["columns"][2]["width"] = self->mProposalColumnWidths[index++];
row["columns"][3]["column"] = "vote_type";
row["columns"][3]["value"] = vote_type;
row["columns"][3]["font"] = "SANSSERIF_SMALL";
row["columns"][3]["width"] = self->mProposalColumnWidths[index++];
row["columns"][4]["column"] = "already_voted";
row["columns"][4]["value"] = already_voted ? "Yes" : "No";
row["columns"][4]["font"] = "SANSSERIF_SMALL";
row["columns"][4]["width"] = self->mProposalColumnWidths[index++];
row["columns"][5]["column"] = "start_datetime";
row["columns"][5]["value"] = format_date(start_datetime);
row["columns"][5]["font"] = "SANSSERIF_SMALL";
row["columns"][5]["width"] = self->mProposalColumnWidths[index++];
row["columns"][6]["column"] = "vote_cast";
row["columns"][6]["value"] = vote_cast;
row["columns"][6]["font"] = "SANSSERIF_SMALL";
row["columns"][6]["width"] = self->mProposalColumnWidths[index++];
row["columns"][7]["column"] = "vote_initator_string";
row["columns"][7]["value"] = vote_initiator_string;
row["columns"][7]["font"] = "SANSSERIF_SMALL";
row["columns"][7]["width"] = self->mProposalColumnWidths[index++];
row["columns"][8]["column"] = "quorum_text";
row["columns"][8]["value"] = quorum_text;
row["columns"][8]["font"] = "SANSSERIF_SMALL";
row["columns"][8]["width"] = self->mProposalColumnWidths[index++];
row["columns"][9]["column"] = "majority_text";
row["columns"][9]["value"] = majority_text;
row["columns"][9]["font"] = "SANSSERIF_SMALL";
row["columns"][9]["width"] = 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(ADD_BOTTOM);
self->mProposals->setCanSelect(FALSE);
self->mBtnViewProposalItem->setEnabled(FALSE);
}
else if ( (U32)received != num_expected )
{
self->addPendingActiveScrollListItem(received,
num_expected,
ADD_BOTTOM);
self->mProposals->setCanSelect(FALSE);
self->mBtnViewProposalItem->setEnabled(FALSE);
}
else
{
//all done display all of the items
std::vector<LLSD>::iterator it = self->mActiveReceived.begin();
std::vector<LLSD>::iterator end = self->mActiveReceived.end();
for (; it != end; it++)
{
self->mProposals->addElement((*it), ADD_SORTED);
}
self->mProposals->setCanSelect(TRUE);
self->mBtnViewProposalItem->setEnabled(TRUE);
}
}
//static
void LLPanelGroupVoting::impl::processGroupVoteHistoryItemReply(LLMessageSystem *msg, void**)
{
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!" << 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->deleteAllItems();
// make sure column indices are correct when populating with real data
self->mVotesHistory->clearColumns();
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(ADD_BOTTOM);
self->mVotesHistory->setCanSelect(FALSE);
self->mBtnViewHistoryItem->setEnabled(FALSE);
return;
}
std::string item_num_string;
std::string proposal_text;
std::string vote_result;
std::string start_datetime;
std::string end_datetime;
std::string vote_type;
std::string vote_text;
LLUUID vote_id;
LLUUID vote_initiator;
LLUUID winner_id;
F32 majority;
S32 quorum;
msg->getStringFast(_PREHASH_HistoryItemData, _PREHASH_TerseDateID, item_num_string );
msg->getUUIDFast(_PREHASH_HistoryItemData, _PREHASH_VoteID, vote_id );
msg->getStringFast(_PREHASH_HistoryItemData, _PREHASH_StartDateTime, start_datetime );
msg->getStringFast(_PREHASH_HistoryItemData, _PREHASH_EndDateTime, end_datetime );
msg->getUUIDFast(_PREHASH_HistoryItemData, _PREHASH_VoteInitiator, vote_initiator);
msg->getStringFast(_PREHASH_HistoryItemData, _PREHASH_VoteType, vote_type);
msg->getStringFast(_PREHASH_HistoryItemData,_PREHASH_VoteResult, vote_result);
msg->getStringFast(_PREHASH_HistoryItemData, _PREHASH_ProposalText, 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 (vote_type == "Proposal")
{
LLSD row;
row["id"] = vote_id;
S32 index = 0;
row["columns"][0]["column"] = "item_num";
row["columns"][0]["value"] = item_num_string;
row["columns"][0]["font"] = "SANSSERIF_SMALL";
row["columns"][0]["width"] = self->mHistoryColumnWidths[index++];
vote_text.assign(proposal_text);
vote_text.append("\n\n--\n");
if (vote_result == "Success")
{
vote_text.append("Proposal PASSED.");
}
else
{
vote_text.append("Proposal FAILED.");
}
vote_text.append(" Votes->\n");
std::string vote_result;
S32 num_votes;
for (S32 i = 0; i < vote_items; ++i)
{
msg->getStringFast(_PREHASH_VoteItem, _PREHASH_VoteCast, vote_result, i);
msg->getS32Fast(_PREHASH_VoteItem, _PREHASH_NumVotes, num_votes, i);
vote_text.append(llformat(" %s: %d\n", vote_result.c_str(), num_votes));
}
vote_text.append("\n");
std::string vote_text_stripped = vote_text;
LLStringUtil::stripNonprintable(vote_text_stripped);
row["columns"][1]["column"] = "vote_text_stripped";
row["columns"][1]["value"] = vote_text_stripped;
row["columns"][1]["font"] = "SANSSERIF_SMALL";
row["columns"][1]["width"] = self->mHistoryColumnWidths[index++];
row["columns"][2]["column"] = "end_datetime";
row["columns"][2]["value"] = format_date(end_datetime);
row["columns"][2]["font"] = "SANSSERIF_SMALL";
row["columns"][2]["width"] = self->mHistoryColumnWidths[index++];
row["columns"][3]["column"] = "vote_type";
row["columns"][3]["value"] = vote_type;
row["columns"][3]["font"] = "SANSSERIF_SMALL";
row["columns"][3]["width"] = self->mHistoryColumnWidths[index++];
row["columns"][4]["column"] = "vote_result";
row["columns"][4]["value"] = vote_result;
row["columns"][4]["font"] = "SANSSERIF_SMALL";
row["columns"][4]["width"] = self->mHistoryColumnWidths[index++];
row["columns"][5]["column"] = "vote_text";
row["columns"][5]["value"] = vote_text;
row["columns"][5]["font"] = "SANSSERIF_SMALL";
row["columns"][5]["width"] = self->mHistoryColumnWidths[index++];
//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
else
{
llinfos << "Vote is not a proposal, but a " << vote_type << llendl;
self->mOtherGroupHistoryItems++;
}
} //end if vote_items > 0
int received = self->mHistoryReceived.size();
if ( (U32)received + self->mOtherGroupHistoryItems != num_expected )
{
self->addPendingHistoryScrollListItem(received,
num_expected,
ADD_BOTTOM);
self->mVotesHistory->setCanSelect(FALSE);
self->mBtnViewHistoryItem->setEnabled(FALSE);
}
else
{
//all done display all of the items
std::vector<LLSD>::iterator it = self->mHistoryReceived.begin();
std::vector<LLSD>::iterator end = self->mHistoryReceived.end();
for (; it != end; it++)
{
self->mVotesHistory->addElement((*it), ADD_SORTED);
}
self->mVotesHistory->setCanSelect(TRUE);
self->mBtnViewHistoryItem->setEnabled(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->mPanel.childSetText("proposal_instructions", self->mPanel.getString("proposals_submit_yes_txt"));
self->sendGroupProposalBallot("Yes");
}
}
//static
void LLPanelGroupVoting::impl::onClickNo(void *userdata)
{
LLPanelGroupVoting::impl* self = (LLPanelGroupVoting::impl*)userdata;
if ( self )
{
self->mPanel.childSetText("proposal_instructions", self->mPanel.getString("proposals_submit_no_txt"));
self->sendGroupProposalBallot("No");
}
}
//static
void LLPanelGroupVoting::impl::onClickAbstain(void *userdata)
{
impl* self = (LLPanelGroupVoting::impl*) userdata;
if ( self )
{
self->mPanel.childSetText("proposal_instructions", self->mPanel.getString("proposals_submit_abstain_txt"));
self->sendGroupProposalBallot("Abstain");
}
}
//static
void LLPanelGroupVoting::impl::onClickSubmitProposal(void *userdata)
{
gFocusMgr.setKeyboardFocus(NULL);
impl* self = (impl*)userdata;
if ( self && 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
LLSD args;
args["MESSAGE"] = self->mPanel.getString("empty_proposal_txt");
LLNotificationsUtil::add("GenericAlert", args);
return;
}
self->mPanel.childSetText("proposal_instructions", self->mPanel.getString("proposals_submit_new_txt"));
self->sendStartGroupProposal();
}
}
//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 )
{
LLScrollListItem * proposal = self->mProposals->getFirstSelected();
// Check if it has anything in column 2. If not, assume it's the "There are currently no active proposals" text
if (proposal && proposal->getColumn(2))
{
self->setEnableVoteProposal();
}
else
{
LLNotificationsUtil::add("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 && self->mVotesHistory )
{
LLScrollListItem * historic = self->mVotesHistory->getFirstSelected();
// Check if it has anything in column 2. If not, assume it's the "There are currently no active proposals" text
if (historic && historic->getColumn(2))
{
self->setEnableHistoryItem();
}
else
{
LLNotificationsUtil::add("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<LLUUID*>(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(*this, 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->mDurationText = getChild<LLTextBox>("duration_text",
recurse);
mImpl->mQuorum = getChild<LLSpinCtrl>("quorum", recurse);
mImpl->mQuorumLbl = getChild<LLTextBox>("quorum_lbl", recurse);
mImpl->mDuration = getChild<LLSpinCtrl>("duration", recurse);
mImpl->mDurationLbl = getChild<LLTextBox>("duration_lbl", recurse);
mImpl->mMajority = getChild<LLRadioGroup>("majority", recurse);
mImpl->mMajorityLbl = getChild<LLTextBox>("majority_lbl", recurse);
mImpl->mStartLbl = getChild<LLTextBox>("start_lbl", recurse);
mImpl->mEndLbl = getChild<LLTextBox>("end_lbl", recurse);
mImpl->mStartDate = getChild<LLTextBox>("start_date", recurse);
mImpl->mEndDate = getChild<LLTextBox>("end_date", recurse);
mImpl->mBtnYes = getChild<LLButton>("btn_yes", recurse);
mImpl->mBtnNo = getChild<LLButton>("btn_no", recurse);
mImpl->mBtnAbstain = getChild<LLButton>("btn_abstain", recurse);
mImpl->mProposals =
getChild<LLScrollListCtrl>("proposals", recurse);
mImpl->mProposalText =
getChild<LLTextEditor>("proposal_text", recurse);
mImpl->mBtnCreateProposal = getChild<LLButton>("btn_proposal",
recurse);
mImpl->mBtnSubmitProposal = getChild<LLButton>("btn_submit",
recurse);
mImpl->mBtnCancelProposal = getChild<LLButton>("btn_cancel",
recurse);
mImpl->mBtnViewProposalList =
getChild<LLButton>("btn_view_proposal_list", recurse);
mImpl->mBtnViewProposalItem =
getChild<LLButton>("btn_view_proposal_item", recurse);
mImpl->mVotesHistory = getChild<LLScrollListCtrl>("history_list",
recurse);
mImpl->mVotesHistoryLbl = getChild<LLTextBox>("history_list_lbl",
recurse);
mImpl->mVoteHistoryText = getChild<LLTextEditor>("vote_text",
recurse);
mImpl->mVoteHistoryTextLbl = getChild<LLTextBox>("vote_text_lbl",
recurse);
mImpl->mBtnViewHistoryList =
getChild<LLButton>("btn_view_history_list", recurse);
mImpl->mBtnViewHistoryItem =
getChild<LLButton>("btn_view_history_item", recurse);
mImpl->updateQuorumText();
bool success = (mImpl->mDurationText &&
mImpl->mQuorum &&
mImpl->mQuorumLbl &&
mImpl->mDuration &&
mImpl->mDurationLbl &&
mImpl->mMajority &&
mImpl->mMajorityLbl &&
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(boost::bind(&LLPanelGroupVoting::impl::onDoubleClickProposal,mImpl));
mImpl->mVotesHistory->setDoubleClickCallback(boost::bind(&LLPanelGroupVoting::impl::onDoubleClickHistoryItem,mImpl));
mImpl->mBtnAbstain->setClickedCallback(boost::bind(&impl::onClickAbstain,mImpl));
mImpl->mBtnNo->setClickedCallback(boost::bind(&impl::onClickNo,mImpl));
mImpl->mBtnYes->setClickedCallback(boost::bind(&impl::onClickYes,mImpl));
mImpl->mBtnCreateProposal->setClickedCallback(boost::bind(&impl::onClickCreateProposal,mImpl));
mImpl->mBtnSubmitProposal->setClickedCallback(boost::bind(&impl::onClickSubmitProposal,mImpl));
mImpl->mBtnCancelProposal->setClickedCallback(boost::bind(&impl::onClickCancelProposal,mImpl));
mImpl->mBtnViewProposalList->setClickedCallback(boost::bind(&impl::onClickViewProposalList,mImpl));
mImpl->mBtnViewProposalItem->setClickedCallback(boost::bind(&impl::onClickViewProposalItem,mImpl));
mImpl->mBtnViewHistoryList->setClickedCallback(boost::bind(&impl::onClickViewHistoryList,mImpl));
mImpl->mBtnViewHistoryItem->setClickedCallback(boost::bind(&impl::onClickViewHistoryItem,mImpl));
gMessageSystem->setHandlerFuncFast(_PREHASH_GroupActiveProposalItemReply,
impl::processGroupActiveProposalItemReply);
gMessageSystem->setHandlerFuncFast(_PREHASH_GroupVoteHistoryItemReply,
impl::processGroupVoteHistoryItemReply);
}
return success && LLPanelGroupTab::postBuild();
}
void LLPanelGroupVoting::activate()
{
LLGroupMgr::getInstance()->sendGroupPropertiesRequest(mGroupID);
update(GC_ALL);
mImpl->setEnableListProposals();
mImpl->setEnableHistoryList();
}
bool LLPanelGroupVoting::needsApply(std::string& mesg)
{
return false;
}
bool LLPanelGroupVoting::apply(std::string& mesg)
{
return true;
}
void LLPanelGroupVoting::update(LLGroupChange gc)
{
LLGroupMgrGroupData* group_datap = NULL;
group_datap = LLGroupMgr::getInstance()->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);
}