llpanelgroupvoting.cpp

Go to the documentation of this file.
00001 
00032 #include "llviewerprecompiledheaders.h"
00033 
00034 #include "roles_constants.h"
00035 
00036 #include "lllineeditor.h"
00037 #include "lltextbox.h"
00038 #include "lltexteditor.h"
00039 #include "llscrolllistctrl.h"
00040 #include "llradiogroup.h"
00041 #include "llspinctrl.h"
00042 #include "llpanelgroupvoting.h"
00043 #include "llnamelistctrl.h"
00044 #include "llbutton.h"
00045 #include "llnotify.h"
00046 
00047 #include "llagent.h"
00048 #include "llfocusmgr.h"
00049 #include "llviewercontrol.h"
00050 #include "llviewerwindow.h"
00051 #include "llviewerregion.h"
00052 
00053 class LLPanelGroupVoting::impl
00054 {
00055 public:
00056         impl(LLPanelGroupVoting& panel, const LLUUID& group_id);
00057         ~impl();
00058 
00059         static void onClickCreateProposal(void* userdata);
00060         static void onClickYes(void *userdata);
00061         static void onClickNo(void *userdata);
00062         static void onClickAbstain(void *userdata);
00063         static void onClickSubmitProposal(void *userdata);
00064         static void onClickCancelProposal(void *userdata);
00065         static void onClickViewProposalList(void *userdata);
00066         static void onClickViewProposalItem(void *userdata);
00067         static void onDoubleClickProposal(void *userdata);
00068 
00069         static void onDoubleClickHistoryItem(void *userdata);
00070         static void onClickViewHistoryItem(void *userdata);
00071         static void onClickViewHistoryList(void *userdata);
00072 
00073         void sendGroupProposalsRequest(const LLUUID& group_id);
00074         void sendStartGroupProposal();
00075         void sendGroupProposalBallot(const char* vote);
00076         void sendGroupVoteHistoryRequest(const LLUUID& group_id);
00077 
00078         void setEnableCreateProposal();
00079         void setEnableVoteProposal();
00080         void setEnableListProposals();
00081         void setEnableHistoryItem();
00082         void setEnableHistoryList();
00083 
00084         void updateQuorumText();
00085         void addPendingActiveScrollListItem(unsigned int current,
00086                                                                                 unsigned int expected,
00087                                                                                 EAddPosition pos);
00088         void addPendingHistoryScrollListItem(unsigned int current,
00089                                                                                  unsigned int expected,
00090                                                                                  EAddPosition pos);
00091         void addNoActiveScrollListItem(EAddPosition pos);
00092         void addNoHistoryScrollListItem(EAddPosition pos);
00093                                                                                                          
00094 
00095         static void processGroupActiveProposalItemReply(LLMessageSystem* msg,
00096                                                                                                         void** data);
00097         static void processGroupVoteHistoryItemReply(LLMessageSystem* msg,
00098                                                                                                  void** data);
00099 
00100 public:
00101         LLUUID mGroupID;
00102         LLUUID mProposalID;
00103 
00104         LLPanelGroupVoting& mPanel;
00105         
00106         LLSpinCtrl              *mQuorum;
00107         LLTextBox               *mQuorumLbl;
00108         LLSpinCtrl              *mDuration;
00109         LLTextBox               *mDurationLbl;
00110         LLTextBox       *mDurationText;
00111         LLRadioGroup    *mMajority;
00112         LLTextBox               *mMajorityLbl;
00113         LLTextBox               *mStartLbl;
00114         LLTextBox           *mEndLbl;
00115         LLTextBox           *mStartDate;
00116         LLTextBox           *mEndDate;
00117 
00118         LLButton *mBtnYes;
00119         LLButton *mBtnNo;
00120         LLButton *mBtnAbstain;
00121 
00122         LLScrollListCtrl *mProposals;
00123         LLTextEditor     *mProposalText;
00124         LLButton             *mBtnCreateProposal;
00125         LLButton             *mBtnSubmitProposal;
00126         LLButton         *mBtnCancelProposal;
00127         LLButton             *mBtnViewProposalList;
00128         LLButton             *mBtnViewProposalItem;
00129 
00130         LLScrollListCtrl *mVotesHistory;
00131         LLTextBox            *mVotesHistoryLbl;
00132         LLTextEditor     *mVoteHistoryText;
00133         LLTextBox        *mVoteHistoryTextLbl;
00134         LLButton                 *mBtnViewHistoryList;
00135         LLButton                 *mBtnViewHistoryItem;
00136 
00137         int     mNumGroupMembers;
00138 
00139         std::vector<LLSD> mActiveReceived;
00140         std::vector<LLSD> mHistoryReceived;
00141 
00142         int mProposalColumnWidths[10];
00143         int mHistoryColumnWidths[10];
00144 
00145         LLUUID mProposalTransID;
00146         LLUUID mHistoryTransID;
00147 
00148         static std::map<LLUUID, LLPanelGroupVoting::impl*> sGroupIDs;
00149 };
00150 
00151 // ****************************************
00152 // ** LLPanelGroupVoting::impl Functions **
00153 // ****************************************
00154 
00155 LLPanelGroupVoting::impl::impl(LLPanelGroupVoting& panel, const LLUUID& group_id)
00156         : mPanel(panel),
00157           mGroupID(group_id)
00158 {
00159 
00160         mNumGroupMembers = 0;
00161 
00162         mProposalTransID = LLUUID::null;
00163         mHistoryTransID  = LLUUID::null;
00164 
00165         mProposalColumnWidths[0] = -1;
00166         mProposalColumnWidths[1] = 210;
00167         mProposalColumnWidths[2] = 120;
00168         mProposalColumnWidths[3] = -1;
00169         mProposalColumnWidths[4] = 30;
00170         for (int index = 5; index < 10; index++)
00171         {
00172                 mProposalColumnWidths[index] = -1;
00173         }
00174 
00175         mHistoryColumnWidths[0] = -1;
00176         mHistoryColumnWidths[1] = 210; // vote text sans non-printable
00177         mHistoryColumnWidths[2] = 120;
00178         mHistoryColumnWidths[3] = -1;
00179         mHistoryColumnWidths[4] = -1;
00180         mHistoryColumnWidths[5] = -1;   // full vote text
00181 
00182         //problem what if someone has both the group floater open and the finder
00183         //open to the same group?  Some maps that map group ids to panels
00184         //will then only be working for the last panel for a given group id :(
00185         sGroupIDs[group_id] = this;
00186 
00187         mQuorum         = NULL;
00188         mQuorumLbl      = NULL;
00189         mDuration       = NULL;
00190         mDurationLbl    = NULL;
00191         mDurationText   = NULL;
00192         mMajority       = NULL;
00193         mMajorityLbl    = NULL;
00194         mStartLbl       = NULL;
00195         mEndLbl         = NULL;
00196         mStartDate      = NULL;
00197         mEndDate        = NULL;
00198 
00199         mBtnYes     = NULL;
00200         mBtnNo      = NULL;
00201         mBtnAbstain = NULL;
00202 
00203         mProposals           = NULL;
00204         mProposalText        = NULL;
00205         mBtnCreateProposal   = NULL;
00206         mBtnSubmitProposal   = NULL;
00207         mBtnCancelProposal   = NULL;
00208         mBtnViewProposalList = NULL;
00209         mBtnViewProposalItem = NULL;
00210 
00211         mVotesHistory       = NULL;
00212         mVotesHistoryLbl    = NULL;
00213         mVoteHistoryText    = NULL;
00214         mVoteHistoryTextLbl = NULL;
00215         mBtnViewHistoryList = NULL;
00216         mBtnViewHistoryItem = NULL;
00217 }
00218 
00219 LLPanelGroupVoting::impl::~impl()
00220 {
00221         sGroupIDs.erase(mGroupID);
00222 }
00223 
00224 void LLPanelGroupVoting::impl::setEnableListProposals()
00225 {
00226         //we make the assumption here that anyone who has the start
00227         //or vote powers should also have the view powers
00228         
00229         /* This power was removed to make group roles simpler
00230         if (!gAgent.hasPowerInGroup(mGroupID, GP_PROPOSAL_VIEW) &&
00231                 !gAgent.hasPowerInGroup(mGroupID, GP_PROPOSAL_VOTE) &&
00232                 !gAgent.hasPowerInGroup(mGroupID, GP_PROPOSAL_START) )
00233         */
00234         if (!gAgent.isInGroup(mGroupID))
00235                 return;
00236 
00237 
00238         mPanel.childSetText("proposal_header", mPanel.getString("proposals_header_view_txt"));
00239         mPanel.childSetText("proposal_instructions", mPanel.getString("proposals_header_view_inst"));
00240         mPanel.childSetVisible("proposal_lbl", FALSE);
00241         mPanel.childSetVisible("proposal_voting_lbl", TRUE);
00242         mProposals->setVisible(TRUE);
00243         mProposals->setBgSelectedColor(gColors.getColor("ScrollSelectedBGColor"));
00244         mProposalText->setVisible(FALSE);
00245         mBtnYes->setEnabled(FALSE);
00246         mBtnYes->setVisible(FALSE);
00247         mBtnNo->setEnabled(FALSE);
00248         mBtnNo->setVisible(FALSE);
00249         mBtnAbstain->setEnabled(FALSE);
00250         mBtnAbstain->setVisible(FALSE);
00251         mBtnSubmitProposal->setEnabled(FALSE);
00252         mBtnSubmitProposal->setVisible(FALSE);
00253         mBtnCancelProposal->setEnabled(FALSE);
00254         mBtnCancelProposal->setVisible(FALSE);
00255 
00256         mBtnViewProposalItem->setEnabled(TRUE);
00257         mBtnViewProposalItem->setVisible(TRUE);
00258 
00259         mBtnViewProposalList->setEnabled(FALSE);
00260         mBtnViewProposalList->setVisible(FALSE);
00261 
00262         mQuorumLbl->setVisible(FALSE);
00263         mQuorum->setEnabled(FALSE);
00264         mQuorum->setVisible(FALSE);
00265         mPanel.childSetVisible("quorum_text", FALSE);
00266 
00267         mDurationLbl->setVisible(FALSE);
00268         mDuration->setEnabled(FALSE);
00269         mDuration->setVisible(FALSE);
00270         mDurationText->setVisible(FALSE);
00271 
00272         mMajorityLbl->setVisible(FALSE);
00273         mMajority->setEnabled(FALSE);
00274         mMajority->setVisible(FALSE);
00275         mStartLbl->setVisible(FALSE);
00276         mStartDate->setVisible(FALSE);
00277         mEndLbl->setVisible(FALSE);
00278         mEndDate->setVisible(FALSE);
00279 
00280         //check to see if the agent can create proposals when enabling the
00281         //create proposal button
00282         BOOL can_create = gAgent.hasPowerInGroup(mGroupID, GP_PROPOSAL_START);
00283 
00284         mBtnCreateProposal->setEnabled(can_create);
00285         mBtnCreateProposal->setVisible(can_create);
00286 }
00287 
00288 void LLPanelGroupVoting::impl::setEnableVoteProposal()
00289 {
00290         if (!gAgent.hasPowerInGroup(mGroupID, GP_PROPOSAL_VOTE))
00291                 return;
00292 
00293         LLScrollListItem *item = mProposals->getFirstSelected();
00294         if (item)
00295         {
00296                 std::string already_voted;
00297                 std::string vote_cast;
00298 
00299                 mProposalID = item->getUUID();
00300                 
00301                 // col 0: index id
00302                 LLScrollListCell * proposal_cell = item->getColumn(1);
00303                 if ( proposal_cell )
00304                 {
00305                          //proposal text
00306                         mProposalText->setText(proposal_cell->getValue().asString());
00307                 }
00308                 else
00309                 {       // Something's wrong... should have some text
00310                         mProposalText->setText(LLString());
00311                 }
00312 
00313                 proposal_cell = item->getColumn(2);
00314                 if (proposal_cell)
00315                 {
00316                         //end date
00317                         mEndDate->setText(proposal_cell->getValue().asString());
00318                 }
00319                 else
00320                 {       // Something's wrong... should have some text
00321                         mEndDate->setText(LLString());
00322                 }
00323 
00324                 // col 3: Vote Type
00325                 proposal_cell = item->getColumn(3);
00326                 if (proposal_cell)
00327                 {
00328                         //already voted
00329                         already_voted = proposal_cell->getValue().asString();
00330                 }
00331                 else
00332                 {       // Something's wrong... should have some text
00333                         already_voted = "";
00334                 }
00335 
00336                 proposal_cell = item->getColumn(5);
00337                 if (proposal_cell)
00338                 {
00339                         //start date
00340                         mStartDate->setText(proposal_cell->getValue().asString());
00341                 }
00342                 else
00343                 {       // Something's wrong... should have some text
00344                         mStartDate->setText(LLString());
00345                 }
00346 
00347                 proposal_cell = item->getColumn(6);
00348                 if (proposal_cell)
00349                 {
00350                         // Vote Cast
00351                         vote_cast = proposal_cell->getValue().asString();
00352                 }
00353 
00354                 // col 8: Vote Initiator
00355                 proposal_cell = item->getColumn(8);
00356                 if (proposal_cell)
00357                 {
00358                         //quorum
00359                         mQuorum->set(
00360                                 (F32)atoi(proposal_cell->getValue().asString().c_str()));
00361                 }
00362                 else
00363                 {
00364                         mQuorum->set(0);
00365                 }
00366 
00367                 F32 majority = 0.0f;
00368                 proposal_cell = item->getColumn(9);
00369                 if (proposal_cell)
00370                 {
00371                         //majority
00372                         majority =
00373                                 (F32)atof(proposal_cell->getValue().asString().c_str());
00374                 }
00375 
00376                 if(majority == 0.0f)
00377                 {       // Select the Simple Majority
00378                         mMajority->setSelectedIndex(0);
00379                 }
00380                 else if (majority == 1.0f)
00381                 {
00382                         //Select Unanimous
00383                         mMajority->setSelectedIndex(2);
00384                 }
00385                 else
00386                 {
00387                         //Select 2/3 Majority
00388                         mMajority->setSelectedIndex(1);
00389                 }
00390 
00391                 if (already_voted == "Yes")
00392                 {
00393                         LLUIString votestr = mPanel.getString("proposals_header_voted_inst");
00394                         votestr.setArg("[VOTE]", vote_cast);
00395                         mPanel.childSetText("proposal_instructions", votestr.getString());
00396 
00397                         mBtnYes->setEnabled(FALSE);
00398                         mBtnNo->setEnabled(FALSE);
00399                         mBtnAbstain->setEnabled(FALSE);
00400                 }
00401                 else
00402                 {
00403                         mPanel.childSetText("proposal_instructions", mPanel.getString("proposals_header_vote_inst"));
00404 
00405                         mBtnYes->setEnabled(TRUE);
00406                         mBtnNo->setEnabled(TRUE);
00407                         mBtnAbstain->setEnabled(TRUE);
00408                 }
00409 
00410                 mPanel.childSetText("proposal_header", mPanel.getString("proposals_header_vote_txt"));
00411                 mPanel.childSetVisible("proposal_lbl", TRUE);
00412                 mPanel.childSetVisible("proposal_voting_lbl", FALSE);
00413                 mProposals->setVisible(FALSE);
00414                 mProposalText->setEnabled(FALSE);
00415                 mProposalText->setVisible(TRUE);
00416                 mBtnYes->setVisible(TRUE);
00417                 mBtnNo->setVisible(TRUE);
00418                 mBtnAbstain->setVisible(TRUE);
00419                 mBtnSubmitProposal->setEnabled(FALSE);
00420                 mBtnSubmitProposal->setVisible(FALSE);
00421                 mBtnCreateProposal->setEnabled(FALSE);
00422                 mBtnCreateProposal->setVisible(FALSE);
00423                 mBtnCancelProposal->setEnabled(FALSE);
00424                 mBtnCancelProposal->setVisible(FALSE);
00425 
00426                 mBtnViewProposalItem->setEnabled(FALSE);
00427                 mBtnViewProposalItem->setVisible(FALSE);
00428 
00429                 mBtnViewProposalList->setEnabled(TRUE);
00430                 mBtnViewProposalList->setVisible(TRUE);
00431 
00432                 mQuorumLbl->setVisible(TRUE);
00433                 mQuorum->setEnabled(FALSE);
00434                 mQuorum->setVisible(TRUE);
00435                 mPanel.childSetVisible("quorum_text", TRUE);
00436 
00437                 mDurationLbl->setVisible(FALSE);
00438                 mDuration->setEnabled(FALSE);
00439                 mDuration->setVisible(FALSE);
00440                 mDurationText->setVisible(FALSE);
00441 
00442                 mMajorityLbl->setVisible(TRUE);
00443                 mMajority->setEnabled(FALSE);
00444                 mMajority->setVisible(TRUE);
00445                 mStartLbl->setVisible(TRUE);
00446                 mStartDate->setVisible(TRUE);
00447                 mEndLbl->setVisible(TRUE);
00448                 mEndDate->setVisible(TRUE);
00449         }
00450 }
00451 
00452 void LLPanelGroupVoting::impl::setEnableCreateProposal()
00453 {
00454         if ( !gAgent.hasPowerInGroup(mGroupID, GP_PROPOSAL_START) )
00455                  return;
00456 
00457         mPanel.childSetText("proposal_header", mPanel.getString("proposals_header_create_txt"));
00458         mPanel.childSetText("proposal_instructions", mPanel.getString("proposals_header_create_inst"));
00459         mPanel.childSetVisible("proposal_lbl", TRUE);
00460         mPanel.childSetVisible("proposal_voting_lbl", FALSE);
00461         mProposals->setVisible(FALSE); 
00462         mProposalText->setEnabled(TRUE);
00463         mProposalText->setVisible(TRUE);
00464         mProposalText->setText(LLString::null);
00465         mBtnYes->setEnabled(FALSE);
00466         mBtnYes->setVisible(FALSE);
00467         mBtnNo->setEnabled(FALSE);
00468         mBtnNo->setVisible(FALSE);
00469         mBtnAbstain->setEnabled(FALSE);
00470         mBtnAbstain->setVisible(FALSE);
00471         mBtnSubmitProposal->setEnabled(TRUE);
00472         mBtnSubmitProposal->setVisible(TRUE);
00473         mBtnCancelProposal->setEnabled(TRUE);
00474         mBtnCancelProposal->setVisible(TRUE);
00475         mBtnCreateProposal->setEnabled(FALSE);
00476         mBtnCreateProposal->setVisible(FALSE);
00477 
00478         mBtnViewProposalItem->setEnabled(FALSE);
00479         mBtnViewProposalItem->setVisible(FALSE);
00480 
00481         mBtnViewProposalList->setEnabled(FALSE);
00482         mBtnViewProposalList->setVisible(FALSE);
00483 
00484         mQuorumLbl->setVisible(TRUE);
00485         mQuorum->setEnabled(TRUE);
00486         mQuorum->setVisible(TRUE);
00487         mPanel.childSetVisible("quorum_text", TRUE);
00488 
00489         mDurationLbl->setVisible(TRUE);
00490         mDuration->setEnabled(TRUE);
00491         mDuration->setVisible(TRUE);
00492         mDurationText->setVisible(TRUE);
00493 
00494         mMajorityLbl->setVisible(TRUE);
00495         mMajority->setEnabled(TRUE);
00496         mMajority->setVisible(TRUE);
00497         mStartLbl->setVisible(FALSE);
00498         mStartDate->setVisible(FALSE);
00499         mEndLbl->setVisible(FALSE);
00500         mEndDate->setVisible(FALSE);
00501 
00502         if (mQuorum->get() == 0)
00503         {
00504                 mQuorum->set((F32)mNumGroupMembers);
00505         }
00506         mQuorum->setMaxValue((F32)mNumGroupMembers);
00507 }
00508 
00509 void LLPanelGroupVoting::impl::setEnableHistoryList()
00510 {
00511         //we make the assumption here that anyone who has the start
00512         //or vote powers should also have the view powers
00513 
00514         /* This power was removed to make group roles simpler
00515         if (!gAgent.hasPowerInGroup(mGroupID, GP_PROPOSAL_VIEW) &&
00516                 !gAgent.hasPowerInGroup(mGroupID, GP_PROPOSAL_VOTE) &&
00517                 !gAgent.hasPowerInGroup(mGroupID, GP_PROPOSAL_START) )
00518                 return;
00519         */
00520         if (!gAgent.isInGroup(mGroupID))
00521                 return;
00522 
00523         mVotesHistoryLbl->setVisible(TRUE);
00524         mVotesHistory->setVisible(TRUE);
00525         mVotesHistory->setEnabled(TRUE);
00526 
00527         mVoteHistoryTextLbl->setVisible(FALSE);
00528         mVoteHistoryText->setVisible(FALSE);    
00529         mBtnViewHistoryList->setVisible(FALSE);
00530 
00531         mBtnViewHistoryItem->setVisible(TRUE);
00532         mBtnViewHistoryItem->setEnabled(TRUE);
00533 }
00534 
00535 void LLPanelGroupVoting::impl::setEnableHistoryItem()
00536 {
00537         //we make the assumption here that anyone who has the start
00538         //or vote powers should also have the view powers
00539         
00540         /* This power was removed to make group roles simpler
00541         if (!gAgent.hasPowerInGroup(mGroupID, GP_PROPOSAL_VIEW) &&
00542                 !gAgent.hasPowerInGroup(mGroupID, GP_PROPOSAL_VOTE) &&
00543                 !gAgent.hasPowerInGroup(mGroupID, GP_PROPOSAL_START) )
00544                 return;
00545         */
00546         
00547         if (!gAgent.isInGroup(mGroupID))
00548                 return;
00549 
00550         LLScrollListItem *item = mVotesHistory->getFirstSelected();
00551         // Get full text, not stripped version.
00552         const LLScrollListCell *cell = item->getColumn(5);
00553         if (cell)
00554         {
00555                 mVoteHistoryText->setText(cell->getValue().asString());
00556         }
00557         else
00558         {       // Something's wrong...
00559                 mVoteHistoryText->setText(LLString());
00560         }
00561         mVotesHistoryLbl->setVisible(FALSE);
00562         mVotesHistory->setVisible(FALSE);
00563 
00564         mVoteHistoryTextLbl->setVisible(TRUE);
00565         mVoteHistoryText->setVisible(TRUE);     
00566         mVoteHistoryText->setEnabled(FALSE);
00567 
00568         mBtnViewHistoryList->setVisible(TRUE);
00569         mBtnViewHistoryList->setEnabled(TRUE);
00570         mBtnViewHistoryItem->setVisible(FALSE);
00571 }
00572 
00573 void LLPanelGroupVoting::impl::sendGroupProposalsRequest(const LLUUID& group_id)
00574 {
00575         //we make the assumption here that anyone who has the start
00576         //or vote powers should also have the view powers
00577         
00578         /* This power was removed to make group roles simpler
00579         if (!gAgent.hasPowerInGroup(mGroupID, GP_PROPOSAL_VIEW) &&
00580                 !gAgent.hasPowerInGroup(mGroupID, GP_PROPOSAL_VOTE) &&
00581                 !gAgent.hasPowerInGroup(mGroupID, GP_PROPOSAL_START) )
00582                 return;
00583         */
00584         if ( !gAgent.isInGroup(mGroupID) )
00585                 return;
00586 
00587         mProposalTransID.generate();
00588         mProposals->deleteAllItems(); //this should delete all the objects
00589         mActiveReceived.clear();
00590 
00591         //fill in some text so the user will at least know that
00592         //we're pining the server in high latency situations
00593         addPendingActiveScrollListItem(0, 0, ADD_BOTTOM);
00594         mProposals->setCanSelect(FALSE);
00595 
00596         LLMessageSystem *msg = gMessageSystem;
00597         msg->newMessageFast(_PREHASH_GroupActiveProposalsRequest);
00598         msg->nextBlockFast(_PREHASH_AgentData);
00599         msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID() );
00600         msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID() );
00601         msg->nextBlockFast(_PREHASH_GroupData);
00602         msg->addUUIDFast(_PREHASH_GroupID, group_id );
00603         msg->nextBlockFast(_PREHASH_TransactionData);
00604         msg->addUUIDFast(_PREHASH_TransactionID, mProposalTransID);
00605         gAgent.sendReliableMessage();
00606 }
00607 
00608 void LLPanelGroupVoting::handleResponse(
00609         const LLUUID& group_id,
00610         ResponseType response,
00611         bool success)
00612 {
00613         impl* self = NULL;
00614 
00615         //see if the voting ballot for the group is still even open
00616         std::map<LLUUID, LLPanelGroupVoting::impl*>::const_iterator self_iter =
00617                 LLPanelGroupVoting::impl::sGroupIDs.find(group_id);
00618 
00619         if ( LLPanelGroupVoting::impl::sGroupIDs.end() != self_iter )
00620         {
00621                 //cool, we found the panel's implementation
00622                 //(the panel is still open)
00623                 //then we want to do some other stuff :)
00624                 self = self_iter->second;
00625         }
00626 
00627         if ( self )
00628         {
00629                 //refresh the proposals now that we've hit no
00630                 self->sendGroupProposalsRequest(self->mGroupID);
00631                 
00632                 if (response == BALLOT)
00633                 {
00634                         LLString::format_map_t args;
00635         
00636                         if (success)
00637                         {
00638                                 args["[MESSAGE]"] = self->mPanel.getString("vote_recorded");
00639                         }
00640                         else
00641                         {
00642                                 args["[MESSAGE]"] = self->mPanel.getString("vote_previously_recorded");
00643                         }
00644 
00645                         LLNotifyBox::showXml("SystemMessage", args);
00646 
00647                         self->sendGroupVoteHistoryRequest(self->mGroupID);
00648                 }
00649                 self->setEnableListProposals();
00650         }
00651 }
00652 
00653 void LLPanelGroupVoting::handleFailure(
00654         const LLUUID& group_id)
00655 {
00656         impl* self = NULL;
00657 
00658         //see if the voting ballot for the group is still even open
00659         std::map<LLUUID, LLPanelGroupVoting::impl*>::const_iterator self_iter =
00660                 LLPanelGroupVoting::impl::sGroupIDs.find(group_id);
00661 
00662         if ( LLPanelGroupVoting::impl::sGroupIDs.end() != self_iter )
00663         {
00664                 //cool, we found the panel's implementation
00665                 //(the panel is still open)
00666                 //then we want to do some other stuff :)
00667                 self = self_iter->second;
00668         }
00669 
00670         if ( self )
00671         {
00672                 self->setEnableListProposals();         
00673         }
00674 }
00675 
00676 class LLStartGroupVoteResponder : public LLHTTPClient::Responder
00677 {
00678 public:
00679         LLStartGroupVoteResponder(const LLUUID& group_id)
00680         {
00681                 mGroupID = group_id;
00682         }
00683 
00684         //If we get back a normal response, handle it here
00685         virtual void result(const LLSD& content)
00686         {
00687                 //Ack'd the proposal initialization, now let's finish up.
00688                 LLPanelGroupVoting::handleResponse(
00689                         mGroupID,
00690                         LLPanelGroupVoting::START_VOTE);
00691         }
00692 
00693         //If we get back an error (not found, etc...), handle it here
00694         virtual void error(U32 status, const std::string& reason)
00695         {
00696                 llinfos << "LLPanelGroupVotingResponder::error "
00697                         << status << ": " << reason << llendl;
00698 
00699                 LLPanelGroupVoting::handleFailure(mGroupID);
00700         }
00701 private:
00702         LLUUID mGroupID;
00703 };
00704 
00705 class LLGroupProposalBallotResponder : public LLHTTPClient::Responder
00706 {
00707 public:
00708         LLGroupProposalBallotResponder(const LLUUID& group_id)
00709         {
00710                 mGroupID = group_id;
00711         }
00712 
00713         //If we get back a normal response, handle it here
00714         virtual void result(const LLSD& content)
00715         {
00716                 //Ack'd the proposal initialization, now let's finish up.
00717                 LLPanelGroupVoting::handleResponse(
00718                         mGroupID,
00719                         LLPanelGroupVoting::BALLOT,
00720                         content["voted"].asBoolean());
00721         }
00722 
00723         //If we get back an error (not found, etc...), handle it here
00724         virtual void error(U32 status, const std::string& reason)
00725         {
00726                 llinfos << "LLPanelGroupVotingResponder::error "
00727                         << status << ": " << reason << llendl;
00728 
00729                 LLPanelGroupVoting::handleFailure(mGroupID);
00730         }
00731 private:
00732         LLUUID mGroupID;
00733 };
00734 
00735 void LLPanelGroupVoting::impl::sendStartGroupProposal()
00736 {
00737         if ( !gAgent.hasPowerInGroup(mGroupID, GP_PROPOSAL_START) )
00738                 return;
00739 
00740         F32 majority = 0.f;
00741         S32 duration_seconds = (S32)mDuration->get()*24*60*60; // duration days * 24hours/day * 60min/hr * 60sec/min
00742 
00743         switch (mMajority->getSelectedIndex())
00744         {
00745         case 0: // Simple Majority
00746                 majority = 0.f;
00747                 break;
00748         case 1: // 2/3 Majority
00749                 majority = 2.f/3.f;
00750                 break;
00751         case 2: // Unanimous
00752                 majority = 1.0f;
00753                 break;
00754         }
00755 
00756         S32 quorum = llfloor(mQuorum->get());
00757 
00758         //*************************************Conversion to capability
00759         LLSD body;
00760 
00761         std::string url = gAgent.getRegion()->getCapability("StartGroupProposal");
00762 
00763         if (!url.empty())
00764         {
00765                 body["agent-id"]                = gAgent.getID();
00766                 body["session-id"]              = gAgent.getSessionID();
00767 
00768                 body["group-id"]                = mGroupID;
00769                 body["majority"]                = majority;
00770                 body["quorum"]                  = quorum;
00771                 body["duration"]                = duration_seconds;
00772                 body["proposal-text"]   = mProposalText->getText();
00773 
00774                 LLHTTPClient::post(
00775                         url,
00776                         body,
00777                         new LLStartGroupVoteResponder(mGroupID),
00778                         300);
00779         }
00780         else
00781         {       //DEPRECATED!!!!!!!  This is a fallback just in case our backend cap is not there.  Delete this block ASAP!
00782                 LLMessageSystem *msg = gMessageSystem;
00783 
00784                 msg->newMessageFast(_PREHASH_StartGroupProposal);
00785                 msg->nextBlockFast(_PREHASH_AgentData);
00786                 msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID() );
00787                 msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID() );
00788 
00789                 msg->nextBlockFast(_PREHASH_ProposalData);
00790                 msg->addUUIDFast(_PREHASH_GroupID, mGroupID);
00791                 msg->addF32Fast(_PREHASH_Majority, majority );
00792                 msg->addS32Fast(_PREHASH_Quorum, quorum );
00793                 msg->addS32Fast(_PREHASH_Duration, duration_seconds );
00794                 msg->addStringFast(_PREHASH_ProposalText, mProposalText->getText().c_str());
00795 
00796                 gAgent.sendReliableMessage();
00797 
00798                 //This code was moved from the callers to here as part of deprecation.
00799                 sendGroupProposalsRequest(mGroupID);
00800                 setEnableListProposals();
00801         }
00802 }
00803 
00804 void LLPanelGroupVoting::impl::sendGroupProposalBallot(const char* vote)
00805 {
00806         if ( !gAgent.hasPowerInGroup(mGroupID, GP_PROPOSAL_VOTE) )
00807                 return;
00808         
00809         LLSD body;
00810 
00811         std::string url = gAgent.getRegion()->getCapability("GroupProposalBallot");
00812 
00813         if (!url.empty())
00814         {
00815                 body["agent-id"]                = gAgent.getID();
00816                 body["session-id"]              = gAgent.getSessionID();
00817                 body["proposal-id"]             = mProposalID;
00818                 body["group-id"]                = mGroupID;
00819                 body["vote"]    = vote;
00820 
00821                 LLHTTPClient::post(
00822                         url,
00823                         body,
00824                         new LLGroupProposalBallotResponder(mGroupID),
00825                         300);
00826         }
00827         else
00828         {       //DEPRECATED!!!!!!!  This is a fallback just in case our backend cap is not there.  Delete this block ASAP!
00829                 LLMessageSystem *msg = gMessageSystem;
00830 
00831                 msg->newMessageFast(_PREHASH_GroupProposalBallot);
00832                 msg->nextBlockFast(_PREHASH_AgentData);
00833                 msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID() );
00834                 msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID() );
00835 
00836                 msg->nextBlockFast(_PREHASH_ProposalData);
00837                 msg->addUUIDFast(_PREHASH_ProposalID, mProposalID);
00838                 msg->addUUIDFast(_PREHASH_GroupID, mGroupID);
00839                 msg->addStringFast(_PREHASH_VoteCast, vote);
00840 
00841                 gAgent.sendReliableMessage();
00842 
00843                 //This code was moved from the callers to here as part of deprecation.
00844                 sendGroupProposalsRequest(mGroupID);
00845                 sendGroupVoteHistoryRequest(mGroupID);
00846                 setEnableListProposals();
00847         }
00848 }
00849 
00850 void LLPanelGroupVoting::impl::sendGroupVoteHistoryRequest(const LLUUID& group_id)
00851 {
00852         //we make the assumption here that anyone who has the start
00853         //or vote powers should also have the view powers
00854         
00855         /* This power was removed to make group roles simpler
00856         if (mAwaitingFirstHistoryItem ||
00857                 (!gAgent.hasPowerInGroup(mGroupID, GP_PROPOSAL_VIEW) &&
00858                  !gAgent.hasPowerInGroup(mGroupID, GP_PROPOSAL_VOTE) &&
00859                  !gAgent.hasPowerInGroup(mGroupID, GP_PROPOSAL_START)) )
00860                 return;
00861         */
00862 
00863         if (!gAgent.isInGroup(mGroupID))
00864                 return;
00865 
00866         mVotesHistory->deleteAllItems();
00867         mHistoryTransID.generate();
00868         mHistoryReceived.clear();
00869 
00870         //add some text so the user knows we're doing something
00871         addPendingHistoryScrollListItem(0, 0, ADD_BOTTOM);
00872         mVotesHistory->setCanSelect(FALSE);
00873 
00874         LLMessageSystem *msg = gMessageSystem;
00875         msg->newMessageFast(_PREHASH_GroupVoteHistoryRequest);
00876         msg->nextBlockFast(_PREHASH_AgentData);
00877         msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID() );
00878         msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID() );
00879         msg->nextBlockFast(_PREHASH_GroupData);
00880         msg->addUUIDFast(_PREHASH_GroupID, group_id );
00881         msg->nextBlockFast(_PREHASH_TransactionData);
00882         msg->addUUIDFast(_PREHASH_TransactionID, mHistoryTransID);
00883         gAgent.sendReliableMessage();
00884 }
00885 
00886 void LLPanelGroupVoting::impl::updateQuorumText()
00887 {
00888         mPanel.childSetTextArg("quorum_text", "[MEMBERS]", llformat("%d", mNumGroupMembers));
00889 }
00890 
00891 void LLPanelGroupVoting::impl::addPendingActiveScrollListItem(unsigned int current,
00892                                                                                                                           unsigned int expected,
00893                                                                                                                           EAddPosition pos)
00894 {
00895         std::stringstream pending;
00896         //*TODO: translate
00897         pending << "Retrieving active proposals ("
00898                         << current
00899                         << "\\" << expected  << ")";
00900 
00901         mProposals->addCommentText(pending.str());
00902 }
00903 
00904 void LLPanelGroupVoting::impl::addNoActiveScrollListItem(EAddPosition pos)
00905 {
00906         //*TODO: translate
00907         mProposals->addCommentText("There are currently no active proposals", pos);
00908 }
00909 
00910 void LLPanelGroupVoting::impl::addNoHistoryScrollListItem(EAddPosition pos)
00911 {
00912         //*TODO: translate
00913         mVotesHistory->addCommentText("There are currently no archived proposals", pos);
00914 }
00915 
00916 void LLPanelGroupVoting::impl::addPendingHistoryScrollListItem(unsigned int current,
00917                                                                                                                           unsigned int expected,
00918                                                                                                                           EAddPosition pos)
00919 {
00920         //*TODO: translate
00921         std::stringstream pending;
00922         pending << "Retrieving archived proposals ("
00923                         << current
00924                         << "\\" << expected  << ")";
00925 
00926         mVotesHistory->addCommentText(pending.str());
00927 }
00928                                                                                                                                                 
00929 
00930 //static
00931 std::map<LLUUID, LLPanelGroupVoting::impl*> LLPanelGroupVoting::impl::sGroupIDs;
00932 
00933 //static
00934 void LLPanelGroupVoting::impl::processGroupActiveProposalItemReply(LLMessageSystem *msg, void**)
00935 {
00936         LLUUID agent_id;
00937         msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID, agent_id );
00938         if (gAgent.getID() != agent_id)
00939         {
00940                 llwarns << "Got active group proposals reply for another agent!" << llendl;
00941                 return;
00942         }
00943 
00944         LLUUID group_id;
00945         LLUUID trans_id;
00946         msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_GroupID, group_id );
00947         impl* self = get_if_there(sGroupIDs, group_id, (impl*) NULL);
00948         if (!self) 
00949         {
00950                 return;
00951         }
00952 
00953         msg->getUUIDFast(_PREHASH_TransactionData,
00954                                          _PREHASH_TransactionID,
00955                                          trans_id);
00956 
00957         if ( self->mProposalTransID != trans_id ) return;
00958 
00959 
00960         U32 num_expected;
00961         const S32 MAX_STRING_NUM_LEN = 20;
00962         char item_num_string[DB_TERSE_DATETIME_BUF_SIZE];               /*Flawfinder: ignore*/
00963         char proposal_text[DB_VOTE_TEXT_BUF_SIZE];              /*Flawfinder: ignore*/
00964         char vote_cast[DB_VOTE_RESULT_BUF_SIZE];                /*Flawfinder: ignore*/
00965         char start_datetime[DB_DATETIME_BUF_SIZE];              /*Flawfinder: ignore*/
00966         char end_datetime[DB_DATETIME_BUF_SIZE];                /*Flawfinder: ignore*/
00967         char vote_type[DB_VOTE_TYPE_BUF_SIZE];          /*Flawfinder: ignore*/
00968         char majority_text[MAX_STRING_NUM_LEN];         /*Flawfinder: ignore*/
00969         char quorum_text[MAX_STRING_NUM_LEN];           /*Flawfinder: ignore*/
00970         char vote_initiator_string[UUID_STR_LENGTH];            /*Flawfinder: ignore*/
00971 
00972         LLUUID vote_id;
00973         LLUUID vote_initiator;
00974 
00975         F32  majority;
00976         S32  quorum;
00977         BOOL already_voted;
00978         S32 num_proposals = msg->getNumberOfBlocksFast(_PREHASH_ProposalData);
00979         
00980         msg->getU32Fast(_PREHASH_TransactionData,
00981                                         _PREHASH_TotalNumItems,
00982                                         num_expected);
00983 
00984         //the first item should be indicative that we
00985         //are currently receiving information or have it all
00986         self->mProposals->deleteAllItems();
00987         // make sure column indices are correct when populating with real data
00988         self->mProposals->clearColumns();
00989 
00990         for (int i = 0; i < num_proposals; i++)
00991         {
00992                 msg->getStringFast(_PREHASH_ProposalData, _PREHASH_TerseDateID, DB_TERSE_DATETIME_BUF_SIZE, item_num_string, i );
00993                 msg->getUUIDFast(_PREHASH_ProposalData, _PREHASH_VoteID,        vote_id, i );
00994                 msg->getStringFast(_PREHASH_ProposalData, _PREHASH_StartDateTime, DB_DATETIME_BUF_SIZE, start_datetime, i );
00995                 msg->getStringFast(_PREHASH_ProposalData, _PREHASH_EndDateTime, DB_DATETIME_BUF_SIZE, end_datetime, i );
00996                 msg->getUUIDFast(_PREHASH_ProposalData, _PREHASH_VoteInitiator, vote_initiator, i );
00997                 msg->getBOOLFast(_PREHASH_ProposalData,_PREHASH_AlreadyVoted, already_voted, i );
00998                 msg->getStringFast(_PREHASH_ProposalData,_PREHASH_VoteCast, DB_VOTE_RESULT_BUF_SIZE, vote_cast, i );
00999                 msg->getStringFast(_PREHASH_ProposalData, _PREHASH_ProposalText, DB_VOTE_TEXT_BUF_SIZE, proposal_text, i );
01000                 msg->getF32Fast(_PREHASH_ProposalData, _PREHASH_Majority, majority, i );
01001                 msg->getS32Fast(_PREHASH_ProposalData, _PREHASH_Quorum, quorum, i );
01002 
01003                 vote_initiator.toString(vote_initiator_string);
01004                 snprintf(majority_text, MAX_STRING_NUM_LEN, "%f", majority);                    /* Flawfinder: ignore */
01005                 snprintf(quorum_text, MAX_STRING_NUM_LEN, "%i", quorum);                        /* Flawfinder: ignore */
01006 
01007                 LLSD row;
01008                 S32 index = 0;
01009                 row["id"] = vote_id;
01010                 row["columns"][0]["column"] = "item_num";
01011                 row["columns"][0]["value"] = item_num_string;
01012                 row["columns"][0]["font"] = "SANSSERIF_SMALL";
01013                 row["columns"][0]["width"] = self->mProposalColumnWidths[index++];
01014 
01015                 row["columns"][1]["column"] = "proposal_text";
01016                 row["columns"][1]["value"] = proposal_text;
01017                 row["columns"][1]["font"] = "SANSSERIF_SMALL";
01018                 row["columns"][1]["width"] = self->mProposalColumnWidths[index++];
01019 
01020                 row["columns"][2]["column"] = "end_datetime";
01021                 row["columns"][2]["value"] = end_datetime;
01022                 row["columns"][2]["font"] = "SANSSERIF_SMALL";
01023                 row["columns"][2]["width"] = self->mProposalColumnWidths[index++];
01024 
01025                 row["columns"][3]["column"] = "vote_type";
01026                 row["columns"][3]["value"] = vote_type;
01027                 row["columns"][3]["font"] = "SANSSERIF_SMALL";
01028                 row["columns"][3]["width"] = self->mProposalColumnWidths[index++];
01029 
01030                 row["columns"][4]["column"] = "already_voted";
01031                 row["columns"][4]["value"] = already_voted ? "Yes" : "No";
01032                 row["columns"][4]["font"] = "SANSSERIF_SMALL";
01033                 row["columns"][4]["width"] = self->mProposalColumnWidths[index++];
01034 
01035                 row["columns"][5]["column"] = "start_datetime";
01036                 row["columns"][5]["value"] = start_datetime;
01037                 row["columns"][5]["font"] = "SANSSERIF_SMALL";
01038                 row["columns"][5]["width"] = self->mProposalColumnWidths[index++];
01039 
01040                 row["columns"][6]["column"] = "vote_cast";
01041                 row["columns"][6]["value"] = vote_cast;
01042                 row["columns"][6]["font"] = "SANSSERIF_SMALL";
01043                 row["columns"][6]["width"] = self->mProposalColumnWidths[index++];
01044 
01045                 row["columns"][7]["column"] = "vote_initator_string";
01046                 row["columns"][7]["value"] = vote_initiator_string;
01047                 row["columns"][7]["font"] = "SANSSERIF_SMALL";
01048                 row["columns"][7]["width"] = self->mProposalColumnWidths[index++];
01049 
01050                 row["columns"][8]["column"] = "quorum_text";
01051                 row["columns"][8]["value"] = quorum_text;
01052                 row["columns"][8]["font"] = "SANSSERIF_SMALL";
01053                 row["columns"][8]["width"] = self->mProposalColumnWidths[index++];
01054 
01055                 row["columns"][9]["column"] = "majority_text";
01056                 row["columns"][9]["value"] = majority_text;
01057                 row["columns"][9]["font"] = "SANSSERIF_SMALL";
01058                 row["columns"][9]["width"] = self->mProposalColumnWidths[index++];
01059                 
01060                 self->mActiveReceived.push_back(row);
01061         }
01062 
01063         int received = self->mActiveReceived.size();
01064         if ( num_expected == 0 )
01065         {
01066                 //we are expecting 0 items, put up a message indicating tehre are
01067                 //no active proposals and make the scroll list unselectable
01068                 self->addNoActiveScrollListItem(ADD_BOTTOM);
01069                 self->mProposals->setCanSelect(FALSE);
01070         }
01071         else if ( (U32)received != num_expected )
01072         {
01073                 self->addPendingActiveScrollListItem(received,
01074                                                                                          num_expected,
01075                                                                                          ADD_BOTTOM);
01076                 self->mProposals->setCanSelect(FALSE);
01077         }
01078         else
01079         {
01080                 //all done display all of the items
01081                 std::vector<LLSD>::iterator it = self->mActiveReceived.begin();
01082                 std::vector<LLSD>::iterator end = self->mActiveReceived.end();
01083 
01084                 for (; it != end; it++)
01085                 {
01086                         self->mProposals->addElement((*it), ADD_SORTED);
01087                 }
01088 
01089                 self->mProposals->setCanSelect(TRUE);
01090         }
01091 }
01092 
01093 //static
01094 void LLPanelGroupVoting::impl::processGroupVoteHistoryItemReply(LLMessageSystem *msg, void**)
01095 {
01096         LLUUID agent_id;
01097         msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID, agent_id );
01098         if (gAgent.getID() != agent_id)
01099         {
01100                 llwarns << "Got group voting history reply for another agent!" << llendl;
01101                 return;
01102         }
01103 
01104         LLUUID group_id;
01105         msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_GroupID, group_id );
01106         impl* self = sGroupIDs[group_id];
01107         if (!self) 
01108         {
01109                 return;
01110         }
01111 
01112         LLUUID trans_id;
01113         U32     num_expected;
01114         
01115         msg->getU32Fast(_PREHASH_TransactionData,
01116                                         _PREHASH_TotalNumItems,
01117                                         num_expected);
01118         msg->getUUIDFast(_PREHASH_TransactionData,
01119                                          _PREHASH_TransactionID,
01120                                          trans_id);
01121 
01122         if ( self->mHistoryTransID != trans_id ) return;
01123 
01124         //the first item should be some text
01125         //explaining that we are attempting to receive information
01126         //or are currently receiving information, so we should clear out
01127         //the first line
01128         self->mVotesHistory->deleteAllItems();
01129         // make sure column indices are correct when populating with real data
01130         self->mVotesHistory->clearColumns();
01131 
01132         if ( num_expected == 0 )
01133         {
01134                 //we are expecting 0 items, put up a message indicating tehre are
01135                 //no active proposals and make the scroll list unselectable
01136                 self->addNoHistoryScrollListItem(ADD_BOTTOM);
01137                 self->mVotesHistory->setCanSelect(FALSE);
01138 
01139                 return;
01140         }
01141 
01142         const S32 ITEM_NUM_MAX_BUF_LEN = 15;
01143         char item_num_string[ITEM_NUM_MAX_BUF_LEN];             /*Flawfinder: ignore*/
01144         char proposal_text[DB_VOTE_TEXT_BUF_SIZE];              /*Flawfinder: ignore*/
01145         char vote_result[MAX_STRING];           /*Flawfinder: ignore*/
01146         char start_datetime[DB_DATETIME_BUF_SIZE];              /*Flawfinder: ignore*/
01147         char end_datetime[DB_DATETIME_BUF_SIZE];                /*Flawfinder: ignore*/
01148         char vote_type[DB_VOTE_TYPE_BUF_SIZE];          /*Flawfinder: ignore*/
01149 
01150         LLString vote_text;
01151         LLUUID vote_id;
01152         LLUUID vote_initiator;
01153         LLUUID winner_id;
01154 
01155         F32     majority;
01156         S32     quorum;
01157 
01158         msg->getStringFast(_PREHASH_HistoryItemData, _PREHASH_TerseDateID, ITEM_NUM_MAX_BUF_LEN, item_num_string );
01159         msg->getUUIDFast(_PREHASH_HistoryItemData, _PREHASH_VoteID,     vote_id );
01160         msg->getStringFast(_PREHASH_HistoryItemData, _PREHASH_StartDateTime, DB_DATETIME_BUF_SIZE, start_datetime );
01161         msg->getStringFast(_PREHASH_HistoryItemData, _PREHASH_EndDateTime, DB_DATETIME_BUF_SIZE, end_datetime );
01162         msg->getUUIDFast(_PREHASH_HistoryItemData, _PREHASH_VoteInitiator, vote_initiator);
01163         msg->getStringFast(_PREHASH_HistoryItemData, _PREHASH_VoteType, DB_VOTE_TYPE_BUF_SIZE, vote_type);
01164         msg->getStringFast(_PREHASH_HistoryItemData,_PREHASH_VoteResult, DB_VOTE_RESULT_BUF_SIZE, vote_result);
01165         msg->getStringFast(_PREHASH_HistoryItemData, _PREHASH_ProposalText, DB_VOTE_TEXT_BUF_SIZE, proposal_text );
01166         msg->getF32Fast(_PREHASH_HistoryItemData, _PREHASH_Majority, majority);
01167         msg->getS32Fast(_PREHASH_HistoryItemData, _PREHASH_Quorum, quorum);
01168 
01169         S32 vote_items = msg->getNumberOfBlocksFast(_PREHASH_VoteItem);
01170 
01171         if (vote_items > 0)
01172         {
01173                 if (!strcmp(vote_type, "Proposal"))
01174                 {
01175                         LLSD row;
01176                         row["id"] = vote_id;
01177 
01178                         S32 index = 0;
01179                         row["columns"][0]["column"] = "item_num";
01180                         row["columns"][0]["value"] = item_num_string;
01181                         row["columns"][0]["font"] = "SANSSERIF_SMALL";
01182                         row["columns"][0]["width"] = self->mHistoryColumnWidths[index++];
01183                         
01184                         vote_text.assign(proposal_text);
01185                         vote_text.append("\n\n--\n");
01186                         if (!strcmp(vote_result, "Success"))
01187                         {
01188                                 vote_text.append("Proposal PASSED.");
01189                         }
01190                         else
01191                         {
01192                                 vote_text.append("Proposal FAILED.");
01193                         }
01194                         vote_text.append("  Votes->\n");
01195 
01196                         char vote_result[DB_VOTE_RESULT_BUF_SIZE];              /*Flawfinder: ignore*/
01197                         char result_msg[MAX_STRING];            /*Flawfinder: ignore*/
01198                         S32 num_votes;
01199 
01200                         for (S32 i = 0; i < vote_items; ++i)
01201                         {
01202                                 msg->getStringFast(_PREHASH_VoteItem, _PREHASH_VoteCast, DB_VOTE_RESULT_BUF_SIZE, vote_result, i);
01203                                 msg->getS32Fast(_PREHASH_VoteItem, _PREHASH_NumVotes, num_votes, i);
01204                                 snprintf(result_msg, MAX_STRING,                        /* Flawfinder: ignore */
01205                                                 "    %s: %d\n",
01206                                                 vote_result,
01207                                                 num_votes);
01208                                 vote_text.append(result_msg);
01209                         }
01210 
01211                         vote_text.append("\n");
01212 
01213                         LLString vote_text_stripped = vote_text;
01214                         LLString::stripNonprintable(vote_text_stripped);
01215 
01216                         row["columns"][1]["column"] = "vote_text_stripped";
01217                         row["columns"][1]["value"] = vote_text_stripped;
01218                         row["columns"][1]["font"] = "SANSSERIF_SMALL";
01219                         row["columns"][1]["width"] = self->mHistoryColumnWidths[index++];
01220 
01221                         row["columns"][2]["column"] = "end_datetime";
01222                         row["columns"][2]["value"] = end_datetime;
01223                         row["columns"][2]["font"] = "SANSSERIF_SMALL";
01224                         row["columns"][2]["width"] = self->mHistoryColumnWidths[index++];
01225 
01226                         row["columns"][3]["column"] = "vote_type";
01227                         row["columns"][3]["value"] = vote_type;
01228                         row["columns"][3]["font"] = "SANSSERIF_SMALL";
01229                         row["columns"][3]["width"] = self->mHistoryColumnWidths[index++];
01230 
01231                         row["columns"][4]["column"] = "vote_result";
01232                         row["columns"][4]["value"] = vote_result;
01233                         row["columns"][4]["font"] = "SANSSERIF_SMALL";
01234                         row["columns"][4]["width"] = self->mHistoryColumnWidths[index++];
01235 
01236                         row["columns"][5]["column"] = "vote_text";
01237                         row["columns"][5]["value"] = vote_text;
01238                         row["columns"][5]["font"] = "SANSSERIF_SMALL";
01239                         row["columns"][5]["width"] = self->mHistoryColumnWidths[index++];
01240 
01241                         //row->addColumn(vote_text_stripped, font, self->mHistoryColumnWidths[1]);
01242                         //row->addColumn(end_datetime, font, self->mHistoryColumnWidths[2]);
01243                         //row->addColumn(vote_type, font, self->mHistoryColumnWidths[3]);
01244                         //row->addColumn(vote_result, font, self->mHistoryColumnWidths[4]);
01245                         //row->addColumn(vote_text, font, self->mHistoryColumnWidths[5]);
01246 
01247                         self->mHistoryReceived.push_back(row);
01248                 } //end if proposal
01249         } //end if vote_items > 0
01250 
01251         int received = self->mHistoryReceived.size();
01252         if ( (U32)received != num_expected )
01253         {
01254                 self->addPendingHistoryScrollListItem(received,
01255                                                                                           num_expected,
01256                                                                                           ADD_BOTTOM);
01257                 self->mVotesHistory->setCanSelect(FALSE);
01258         }
01259         else
01260         {
01261                 //all done display all of the items
01262                 std::vector<LLSD>::iterator it = self->mHistoryReceived.begin();
01263                 std::vector<LLSD>::iterator end = self->mHistoryReceived.end();
01264 
01265                 for (; it != end; it++)
01266                 {
01267                         self->mVotesHistory->addElement((*it), ADD_SORTED);
01268                 }
01269 
01270                 self->mVotesHistory->setCanSelect(TRUE);
01271         }
01272 }
01273 
01274 //static
01275 void LLPanelGroupVoting::impl::onClickCreateProposal(void* userdata)
01276 {
01277         impl* self = (impl*)userdata;
01278         if ( self ) self->setEnableCreateProposal();
01279 }
01280 
01281 //static
01282 void LLPanelGroupVoting::impl::onClickYes(void *userdata)
01283 {
01284         LLPanelGroupVoting::impl* self = (LLPanelGroupVoting::impl*)userdata;
01285 
01286         if ( self )
01287         {
01288                 self->mPanel.childSetText("proposal_instructions", self->mPanel.getString("proposals_submit_yes_txt"));
01289                 self->sendGroupProposalBallot("Yes");
01290         }
01291 }
01292 
01293 //static
01294 void LLPanelGroupVoting::impl::onClickNo(void *userdata)
01295 {
01296         LLPanelGroupVoting::impl* self = (LLPanelGroupVoting::impl*)userdata;
01297 
01298         if ( self )
01299         {
01300                 self->mPanel.childSetText("proposal_instructions", self->mPanel.getString("proposals_submit_no_txt"));
01301                 self->sendGroupProposalBallot("No");
01302         }
01303 }
01304 
01305 //static
01306 void LLPanelGroupVoting::impl::onClickAbstain(void *userdata)
01307 {
01308         impl* self = (LLPanelGroupVoting::impl*) userdata;
01309 
01310         if ( self )
01311         {
01312                 self->mPanel.childSetText("proposal_instructions", self->mPanel.getString("proposals_submit_abstain_txt"));
01313                 self->sendGroupProposalBallot("Abstain");
01314         }
01315 }
01316 
01317 
01318 //static
01319 void LLPanelGroupVoting::impl::onClickSubmitProposal(void *userdata)
01320 {
01321         gFocusMgr.setKeyboardFocus(NULL); 
01322         impl* self = (impl*)userdata;
01323 
01324         if ( self && self->mProposalText )
01325         {
01326                 //check to see if the proposal has any text for some form of
01327                 //"validation"
01328                 if ( self->mProposalText->getText().empty() )
01329                 {
01330                         //throw up an error dialog
01331                         LLString::format_map_t args;
01332                         args["[MESSAGE]"] = self->mPanel.getString("empty_proposal_txt");
01333                         gViewerWindow->alertXml("GenericAlert", args);
01334                         return;
01335                 }
01336 
01337                 self->mPanel.childSetText("proposal_instructions", self->mPanel.getString("proposals_submit_new_txt"));
01338                 self->sendStartGroupProposal();
01339         }
01340 }
01341 
01342 //static
01343 void LLPanelGroupVoting::impl::onClickCancelProposal(void* userdata)
01344 {
01345         impl* self = (impl*)userdata;
01346 
01347         if ( self )
01348         {
01349                 self->setEnableListProposals();
01350         }
01351 }
01352 
01353 //static
01354 void LLPanelGroupVoting::impl::onClickViewProposalList(void *userdata)
01355 {
01356         impl* self = (LLPanelGroupVoting::impl*)userdata;
01357 
01358         if ( self ) self->setEnableListProposals();
01359 }
01360 
01361 //static
01362 void LLPanelGroupVoting::impl::onClickViewProposalItem(void *userdata)
01363 {
01364         impl* self = (LLPanelGroupVoting::impl*)userdata;
01365 
01366         if ( self && self->mProposals )
01367         {
01368                 LLScrollListItem * proposal = self->mProposals->getFirstSelected();
01369                 // Check if it has anything in column 2.  If not, assume it's the "There are currently no active proposals" text
01370                 if (proposal && proposal->getColumn(2))
01371                 {
01372                         self->setEnableVoteProposal();
01373                 }
01374                 else
01375                 {
01376                         gViewerWindow->alertXml("SelectProposalToView");
01377                 }
01378         }
01379 }
01380 
01381 //static
01382 void LLPanelGroupVoting::impl::onDoubleClickProposal(void *userdata)
01383 {
01384         impl* self = (impl*)userdata;
01385         if ( self && self->mProposals->getFirstSelected() != NULL )
01386         {
01387                 self->setEnableVoteProposal();
01388         }
01389 }
01390 
01391 //static
01392 void LLPanelGroupVoting::impl::onDoubleClickHistoryItem(void *userdata)
01393 {
01394         impl* self = (impl*)userdata;
01395         if ( self && self->mVotesHistory->getFirstSelected() != NULL )
01396         {
01397                 self->setEnableHistoryItem();
01398         }
01399 }
01400 
01401 //static
01402 void LLPanelGroupVoting::impl::onClickViewHistoryItem(void *userdata)
01403 {
01404         impl* self = (impl*)userdata;
01405 
01406         if ( self && self->mVotesHistory )
01407         {
01408                 LLScrollListItem * historic = self->mVotesHistory->getFirstSelected();
01409                 // Check if it has anything in column 2.  If not, assume it's the "There are currently no active proposals" text
01410                 if (historic && historic->getColumn(2))
01411                 {
01412                         self->setEnableHistoryItem();
01413                 }
01414                 else
01415                 {
01416                         gViewerWindow->alertXml("SelectHistoryItemToView");
01417                 }
01418         }
01419 }
01420 
01421 //static
01422 void LLPanelGroupVoting::impl::onClickViewHistoryList(void *userdata)
01423 {
01424         impl* self = (impl*)userdata;
01425 
01426         if ( self) self->setEnableHistoryList();
01427 }
01428 
01429 //**********************************
01430 //** LLPanelGroupVoting Functions **
01431 //**********************************
01432 
01433 // static
01434 void* LLPanelGroupVoting::createTab(void* data)
01435 {
01436         LLUUID* group_id = static_cast<LLUUID*>(data);
01437         return new LLPanelGroupVoting("panel group voting", *group_id);
01438 }
01439 
01440 LLPanelGroupVoting::LLPanelGroupVoting(const std::string& name, 
01441                                                                   const LLUUID& group_id)
01442         : LLPanelGroupTab(name, group_id)
01443 {
01444         mImpl = new impl(*this, group_id);
01445 }
01446 
01447 LLPanelGroupVoting::~LLPanelGroupVoting()
01448 {
01449         delete mImpl;
01450 }
01451 
01452 BOOL LLPanelGroupVoting::isVisibleByAgent(LLAgent* agentp)
01453 {
01454          //if they are in the group, the panel is viewable
01455         return mAllowEdit && agentp->isInGroup(mGroupID);
01456 }
01457 
01458 BOOL LLPanelGroupVoting::postBuild()
01459 {
01460         bool recurse = true;
01461 
01462         mImpl->mDurationText = getChild<LLTextBox>("duration_text",
01463                                                                                                            recurse);
01464         mImpl->mQuorum       = getChild<LLSpinCtrl>("quorum", recurse);
01465         mImpl->mQuorumLbl    = getChild<LLTextBox>("quorum_lbl", recurse);
01466         mImpl->mDuration     = getChild<LLSpinCtrl>("duration", recurse);
01467         mImpl->mDurationLbl  = getChild<LLTextBox>("duration_lbl", recurse);
01468         mImpl->mMajority     = getChild<LLRadioGroup>("majority", recurse);
01469         mImpl->mMajorityLbl  = getChild<LLTextBox>("majority_lbl", recurse);
01470 
01471         mImpl->mStartLbl     = getChild<LLTextBox>("start_lbl", recurse);
01472         mImpl->mEndLbl       = getChild<LLTextBox>("end_lbl", recurse);
01473         mImpl->mStartDate    = getChild<LLTextBox>("start_date", recurse);
01474         mImpl->mEndDate      = getChild<LLTextBox>("end_date", recurse);
01475 
01476         mImpl->mBtnYes     = getChild<LLButton>("btn_yes", recurse);
01477         mImpl->mBtnNo      = getChild<LLButton>("btn_no", recurse);
01478         mImpl->mBtnAbstain = getChild<LLButton>("btn_abstain", recurse);
01479 
01480         mImpl->mProposals =
01481                 getChild<LLScrollListCtrl>("proposals", recurse);
01482         mImpl->mProposalText =
01483                 getChild<LLTextEditor>("proposal_text", recurse);
01484 
01485         mImpl->mBtnCreateProposal = getChild<LLButton>("btn_proposal",
01486                                                                                                                    recurse);
01487         mImpl->mBtnSubmitProposal = getChild<LLButton>("btn_submit",
01488                                                                                                                    recurse);
01489         mImpl->mBtnCancelProposal = getChild<LLButton>("btn_cancel",
01490                                                                                                                    recurse);
01491 
01492         mImpl->mBtnViewProposalList =
01493                 getChild<LLButton>("btn_view_proposal_list", recurse);
01494         mImpl->mBtnViewProposalItem =
01495                 getChild<LLButton>("btn_view_proposal_item", recurse);
01496 
01497         mImpl->mVotesHistory       = getChild<LLScrollListCtrl>("history_list",
01498                                                                                                                                    recurse);
01499         mImpl->mVotesHistoryLbl    = getChild<LLTextBox>("history_list_lbl",
01500                                                                                                                          recurse);
01501         mImpl->mVoteHistoryText    = getChild<LLTextEditor>("vote_text",
01502                                                                                                                                 recurse);
01503         mImpl->mVoteHistoryTextLbl = getChild<LLTextBox>("vote_text_lbl",
01504                                                                                                                          recurse);
01505 
01506         mImpl->mBtnViewHistoryList =
01507                 getChild<LLButton>("btn_view_history_list", recurse);
01508         mImpl->mBtnViewHistoryItem =
01509                 getChild<LLButton>("btn_view_history_item", recurse);
01510 
01511         mImpl->updateQuorumText();
01512 
01513         bool success = (mImpl->mDurationText &&
01514                                         mImpl->mQuorum &&
01515                                         mImpl->mQuorumLbl &&
01516                                         mImpl->mDuration &&
01517                                         mImpl->mDurationLbl &&
01518                                         mImpl->mMajority &&
01519                                         mImpl->mMajorityLbl &&
01520                                         mImpl->mStartLbl &&
01521                                         mImpl->mEndLbl &&
01522                                         mImpl->mStartDate &&
01523                                         mImpl->mEndDate &&
01524                                         mImpl->mBtnYes &&
01525                                         mImpl->mBtnNo &&
01526                                         mImpl->mBtnAbstain &&
01527                                         mImpl->mProposals &&
01528                                         mImpl->mProposalText &&
01529                                         mImpl->mBtnCreateProposal &&
01530                                         mImpl->mBtnSubmitProposal &&
01531                                         mImpl->mBtnCancelProposal &&
01532                                         mImpl->mBtnViewProposalList &&
01533                                         mImpl->mBtnViewProposalItem &&
01534                                         mImpl->mVotesHistory &&
01535                                         mImpl->mVotesHistoryLbl &&
01536                                         mImpl->mVoteHistoryText &&
01537                                         mImpl->mVoteHistoryTextLbl &&
01538                                         mImpl->mBtnViewHistoryList &&
01539                                         mImpl->mBtnViewHistoryItem );
01540 
01541         //associate callbacks
01542         if ( success )
01543         {
01544                 mImpl->mProposals->setDoubleClickCallback(impl::onDoubleClickProposal);
01545                 mImpl->mProposals->setCallbackUserData(mImpl);
01546 
01547                 mImpl->mVotesHistory->setDoubleClickCallback(impl::onDoubleClickHistoryItem);
01548                 mImpl->mVotesHistory->setCallbackUserData(mImpl);
01549 
01550                 mImpl->mBtnAbstain->setClickedCallback(impl::onClickAbstain);
01551                 mImpl->mBtnAbstain->setCallbackUserData(mImpl);
01552 
01553                 mImpl->mBtnNo->setClickedCallback(impl::onClickNo);
01554                 mImpl->mBtnNo->setCallbackUserData(mImpl);
01555 
01556                 mImpl->mBtnYes->setClickedCallback(impl::onClickYes);
01557                 mImpl->mBtnYes->setCallbackUserData(mImpl);
01558 
01559                 mImpl->mBtnCreateProposal->setClickedCallback(impl::onClickCreateProposal);
01560                 mImpl->mBtnCreateProposal->setCallbackUserData(mImpl);
01561 
01562                 mImpl->mBtnSubmitProposal->setClickedCallback(impl::onClickSubmitProposal);
01563                 mImpl->mBtnSubmitProposal->setCallbackUserData(mImpl);
01564 
01565                 mImpl->mBtnCancelProposal->setClickedCallback(impl::onClickCancelProposal);
01566                 mImpl->mBtnCancelProposal->setCallbackUserData(mImpl);
01567 
01568                 mImpl->mBtnViewProposalList->setClickedCallback(impl::onClickViewProposalList);
01569                 mImpl->mBtnViewProposalList->setCallbackUserData(mImpl);
01570 
01571                 mImpl->mBtnViewProposalItem->setClickedCallback(impl::onClickViewProposalItem);
01572                 mImpl->mBtnViewProposalItem->setCallbackUserData(mImpl);
01573 
01574                 mImpl->mBtnViewHistoryList->setClickedCallback(impl::onClickViewHistoryList);
01575                 mImpl->mBtnViewHistoryList->setCallbackUserData(mImpl);
01576 
01577                 mImpl->mBtnViewHistoryItem->setClickedCallback(impl::onClickViewHistoryItem);
01578                 mImpl->mBtnViewHistoryItem->setCallbackUserData(mImpl);
01579 
01580                 gMessageSystem->setHandlerFuncFast(_PREHASH_GroupActiveProposalItemReply, 
01581                                                                                    impl::processGroupActiveProposalItemReply);
01582                 gMessageSystem->setHandlerFuncFast(_PREHASH_GroupVoteHistoryItemReply, 
01583                                                                                    impl::processGroupVoteHistoryItemReply);
01584         }
01585 
01586         return success && LLPanelGroupTab::postBuild();
01587 }
01588 
01589 
01590 void LLPanelGroupVoting::activate()
01591 {
01592         LLGroupMgr::getInstance()->sendGroupPropertiesRequest(mGroupID);
01593         update(GC_ALL);
01594 
01595         mImpl->setEnableListProposals();
01596         mImpl->setEnableHistoryList();
01597 }
01598 
01599 bool LLPanelGroupVoting::needsApply(LLString& mesg)
01600 {
01601         return false;
01602 }
01603 
01604 bool LLPanelGroupVoting::apply(LLString& mesg)
01605 {
01606         return true;
01607 }
01608 
01609 void LLPanelGroupVoting::update(LLGroupChange gc)
01610 {
01611         LLGroupMgrGroupData* group_datap = NULL;
01612         group_datap = LLGroupMgr::getInstance()->getGroupData(mGroupID);
01613 
01614         if ( group_datap )
01615         {
01616                 S32 num_group_members = group_datap->mMemberCount;
01617                 mImpl->mNumGroupMembers = num_group_members;
01618 
01619                 mImpl->updateQuorumText();
01620         }
01621 
01622         mImpl->sendGroupProposalsRequest(mGroupID);
01623         mImpl->sendGroupVoteHistoryRequest(mGroupID);
01624 }
01625 
01626 

Generated on Fri May 16 08:33:54 2008 for SecondLife by  doxygen 1.5.5