llpanelgrouproles.cpp

Go to the documentation of this file.
00001 
00032 #include "llviewerprecompiledheaders.h"
00033 
00034 #include "llcheckboxctrl.h"
00035 
00036 #include "llagent.h"
00037 #include "llbutton.h"
00038 #include "llfloateravatarinfo.h"
00039 #include "llfloatergroupinvite.h"
00040 #include "lliconctrl.h"
00041 #include "lllineeditor.h"
00042 #include "llnamelistctrl.h"
00043 #include "llnotify.h"
00044 #include "llpanelgrouproles.h"
00045 #include "llscrolllistctrl.h"
00046 #include "lltabcontainer.h"
00047 #include "lltextbox.h"
00048 #include "lltexteditor.h"
00049 #include "llviewerimagelist.h"
00050 #include "llviewerwindow.h"
00051 #include "llfocusmgr.h"
00052 
00053 #include "roles_constants.h"
00054 
00055 bool agentCanRemoveFromRole(const LLUUID& group_id,
00056                                                         const LLUUID& role_id)
00057 {
00058         return gAgent.hasPowerInGroup(group_id, GP_ROLE_REMOVE_MEMBER);
00059 }
00060 
00061 bool agentCanAddToRole(const LLUUID& group_id,
00062                                            const LLUUID& role_id)
00063 {
00064         LLGroupMgrGroupData* gdatap = gGroupMgr->getGroupData(group_id);
00065         if (!gdatap) 
00066         {
00067                 llwarns << "agentCanAddToRole "
00068                                 << "-- No group data!" << llendl;
00069                 return false;
00070         }
00071 
00072         //make sure the agent is in the group
00073         LLGroupMgrGroupData::member_iter mi = gdatap->mMembers.find(gAgent.getID());
00074         if (mi == gdatap->mMembers.end())
00075         {
00076                 return false;
00077         }
00078         
00079         LLGroupMemberData* member_data = (*mi).second;
00080 
00081         // Owners can add to any role.
00082         if ( member_data->isInRole(gdatap->mOwnerRole) )
00083         {
00084                 return true;
00085         }
00086 
00087         // 'Limited assign members' can add to roles the user is in.
00088         if ( gAgent.hasPowerInGroup(group_id, GP_ROLE_ASSIGN_MEMBER_LIMITED) &&
00089                         member_data->isInRole(role_id) )
00090         {
00091                 return true;
00092         }
00093 
00094         // 'assign members' can add to non-owner roles.
00095         if ( gAgent.hasPowerInGroup(group_id, GP_ROLE_ASSIGN_MEMBER) &&
00096                          role_id != gdatap->mOwnerRole )
00097         {
00098                 return true;
00099         }
00100 
00101         return false;
00102 }
00103 
00104 // static
00105 void* LLPanelGroupRoles::createTab(void* data)
00106 {
00107         LLUUID* group_id = static_cast<LLUUID*>(data);
00108         return new LLPanelGroupRoles("panel group roles", *group_id);
00109 }
00110 
00111 LLPanelGroupRoles::LLPanelGroupRoles(const std::string& name, const LLUUID& group_id)
00112 :       LLPanelGroupTab(name, group_id),
00113         mCurrentTab(NULL),
00114         mRequestedTab( NULL ),
00115         mSubTabContainer( NULL ),
00116         mFirstUse( TRUE ),
00117         mIgnoreTransition( FALSE )
00118 {
00119 }
00120 
00121 LLPanelGroupRoles::~LLPanelGroupRoles()
00122 {
00123         int i;
00124         for (i = 0; i < mSubTabContainer->getTabCount(); ++i)
00125         {
00126                 LLPanelGroupSubTab* subtabp = (LLPanelGroupSubTab*) mSubTabContainer->getPanelByIndex(i);
00127 
00128                 subtabp->removeObserver(this);
00129         }
00130 }
00131 
00132 BOOL LLPanelGroupRoles::postBuild()
00133 {
00134         lldebugs << "LLPanelGroupRoles::postBuild()" << llendl;
00135 
00136         mSubTabContainer = (LLTabContainerCommon*) getChildByName("roles_tab_container");
00137 
00138         if (!mSubTabContainer) return FALSE;
00139 
00140         // Hook up each sub-tabs callback and widgets.
00141         S32 i;
00142         for (i = 0; i < mSubTabContainer->getTabCount(); ++i)
00143         {
00144                 LLPanelGroupSubTab* subtabp = (LLPanelGroupSubTab*) mSubTabContainer->getPanelByIndex(i);
00145 
00146                 // Add click callbacks to all the tabs.
00147                 mSubTabContainer->setTabChangeCallback(subtabp, onClickSubTab);
00148                 mSubTabContainer->setTabUserData(subtabp, this);
00149 
00150                 // Hand the subtab a pointer to this LLPanelGroupRoles, so that it can
00151                 // look around for the widgets it is interested in.
00152                 if (!subtabp->postBuildSubTab(this)) return FALSE;
00153 
00154                 subtabp->addObserver(this);
00155         }
00156 
00157         // Set the current tab to whatever is currently being shown.
00158         mCurrentTab = (LLPanelGroupTab*) mSubTabContainer->getCurrentPanel();
00159         if (!mCurrentTab)
00160         {
00161                 // Need to select a tab.
00162                 mSubTabContainer->selectFirstTab();
00163                 mCurrentTab = (LLPanelGroupTab*) mSubTabContainer->getCurrentPanel();
00164         }
00165 
00166         if (!mCurrentTab) return FALSE;
00167 
00168         // Act as though this tab was just activated.
00169         mCurrentTab->activate();
00170 
00171         // Read apply text from the xml file.
00172         LLTextBox* txt;
00173         // Don't recurse for this, since we don't currently have a recursive removeChild()
00174         txt = (LLTextBox*)getChildByName("default_needs_apply_text");
00175         if (txt)
00176         {
00177                 mDefaultNeedsApplyMesg = txt->getText();
00178                 removeChild(txt, TRUE);
00179         }
00180         txt = (LLTextBox*)getChildByName("want_apply_text");
00181         if (txt)
00182         {
00183                 mWantApplyMesg = txt->getText();
00184                 removeChild(txt, TRUE);
00185         }
00186 
00187         return LLPanelGroupTab::postBuild();
00188 }
00189 
00190 BOOL LLPanelGroupRoles::isVisibleByAgent(LLAgent* agentp)
00191 {
00192         if (agentp->isGodlike())
00193                 return TRUE;
00194         
00195         /* This power was removed to make group roles simpler
00196         return agentp->hasPowerInGroup(mGroupID, 
00197                                                                    GP_ROLE_CREATE |
00198                                                                    GP_ROLE_DELETE |
00199                                                                    GP_ROLE_PROPERTIES |
00200                                                                    GP_ROLE_VIEW |
00201                                                                    GP_ROLE_ASSIGN_MEMBER |
00202                                                                    GP_ROLE_REMOVE_MEMBER |
00203                                                                    GP_ROLE_CHANGE_ACTIONS |
00204                                                                    GP_MEMBER_INVITE |
00205                                                                    GP_MEMBER_EJECT |
00206                                                                    GP_MEMBER_OPTIONS );
00207         */
00208         return mAllowEdit && agentp->isInGroup(mGroupID);
00209                                                                    
00210 }
00211 
00212 // static
00213 void LLPanelGroupRoles::onClickSubTab(void* user_data, bool from_click)
00214 {
00215         LLPanelGroupRoles* self = static_cast<LLPanelGroupRoles*>(user_data);
00216         self->handleClickSubTab();
00217 }
00218 
00219 void LLPanelGroupRoles::handleClickSubTab()
00220 {
00221         // If we are already handling a transition,
00222         // ignore this.
00223         if (mIgnoreTransition)
00224         {
00225                 return;
00226         }
00227 
00228         mRequestedTab = (LLPanelGroupTab*) mSubTabContainer->getCurrentPanel();
00229 
00230         // Make sure they aren't just clicking the same tab...
00231         if (mRequestedTab == mCurrentTab)
00232         {
00233                 return;
00234         }
00235 
00236         // Try to switch from the current panel to the panel the user selected.
00237         attemptTransition();
00238 }
00239 
00240 BOOL LLPanelGroupRoles::attemptTransition()
00241 {
00242         // Check if the current tab needs to be applied.
00243         LLString mesg;
00244         if (mCurrentTab && mCurrentTab->needsApply(mesg))
00245         {
00246                 // If no message was provided, give a generic one.
00247                 if (mesg.empty())
00248                 {
00249                         mesg = mDefaultNeedsApplyMesg;
00250                 }
00251                 // Create a notify box, telling the user about the unapplied tab.
00252                 LLString::format_map_t args;
00253                 args["[NEEDS_APPLY_MESSAGE]"] = mesg;
00254                 args["[WANT_APPLY_MESSAGE]"] = mWantApplyMesg;
00255                 gViewerWindow->alertXml("PanelGroupApply", args,
00256                                                                 onNotifyCallback, (void*) this);
00257                 mHasModal = TRUE;
00258                 // We need to reselect the current tab, since it isn't finished.
00259                 if (mSubTabContainer)
00260                 {
00261                         mIgnoreTransition = TRUE;
00262                         mSubTabContainer->selectTabPanel( mCurrentTab );
00263                         mIgnoreTransition = FALSE;
00264                 }
00265                 // Returning FALSE will block a close action from finishing until
00266                 // we get a response back from the user.
00267                 return FALSE;
00268         }
00269         else
00270         {
00271                 // The current panel didn't have anything it needed to apply.
00272                 if (mRequestedTab)
00273                 {
00274                         transitionToTab();
00275                 }
00276                 return TRUE;
00277         }
00278 }
00279 
00280 void LLPanelGroupRoles::transitionToTab()
00281 {
00282         // Tell the current panel that it is being deactivated.
00283         if (mCurrentTab)
00284         {
00285                 mCurrentTab->deactivate();
00286         }
00287         
00288         // Tell the new panel that it is being activated.
00289         if (mRequestedTab)
00290         {
00291                 // This is now the current tab;
00292                 mCurrentTab = mRequestedTab;
00293                 mCurrentTab->activate();
00294         }
00295 }
00296 
00297 // static
00298 void LLPanelGroupRoles::onNotifyCallback(S32 option, void* user_data)
00299 {
00300         LLPanelGroupRoles* self = static_cast<LLPanelGroupRoles*>(user_data);
00301         if (self)
00302         {
00303                 self->handleNotifyCallback(option);
00304         }
00305 }
00306 
00307 void LLPanelGroupRoles::handleNotifyCallback(S32 option)
00308 {
00309         mHasModal = FALSE;
00310         switch (option)
00311         {
00312         case 0: // "Apply Changes"
00313         {
00314                 // Try to apply changes, and switch to the requested tab.
00315                 LLString apply_mesg;
00316                 if ( !apply( apply_mesg ) )
00317                 {
00318                         // There was a problem doing the apply.
00319                         if ( !apply_mesg.empty() )
00320                         {
00321                                 mHasModal = TRUE;
00322                                 LLString::format_map_t args;
00323                                 args["[MESSAGE]"] = apply_mesg;
00324                                 gViewerWindow->alertXml("GenericAlert", args, onModalClose, (void*) this);
00325                         }
00326                         // Skip switching tabs.
00327                         break;
00328                 }
00329 
00330                 // This panel's info successfully applied.
00331                 // Switch to the next panel.
00332                 // No break!  Continue into 'Ignore Changes' which just switches tabs.
00333                 mIgnoreTransition = TRUE;
00334                 mSubTabContainer->selectTabPanel( mRequestedTab );
00335                 mIgnoreTransition = FALSE;
00336                 transitionToTab();
00337                 break;
00338         }
00339         case 1: // "Ignore Changes"
00340                 // Switch to the requested panel without applying changes
00341                 cancel();
00342                 mIgnoreTransition = TRUE;
00343                 mSubTabContainer->selectTabPanel( mRequestedTab );
00344                 mIgnoreTransition = FALSE;
00345                 transitionToTab();
00346                 break;
00347         case 2: // "Cancel"
00348         default:
00349                 // Do nothing.  The user is canceling the action.
00350                 break;
00351         }
00352 }
00353 
00354 // static
00355 void LLPanelGroupRoles::onModalClose(S32 option, void* user_data)
00356 {
00357         LLPanelGroupRoles* self = static_cast<LLPanelGroupRoles*>(user_data);
00358         if (self)
00359         {
00360                 self->mHasModal = FALSE;
00361         }
00362 }
00363 
00364 
00365 bool LLPanelGroupRoles::apply(LLString& mesg)
00366 {
00367         // Pass this along to the currently visible sub tab.
00368         if (!mSubTabContainer) return false;
00369 
00370         LLPanelGroupTab* panelp = (LLPanelGroupTab*) mSubTabContainer->getCurrentPanel();
00371         if (!panelp) return false;
00372         
00373         // Ignore the needs apply message.
00374         LLString ignore_mesg;
00375         if ( !panelp->needsApply(ignore_mesg) )
00376         {
00377                 // We don't need to apply anything.
00378                 // We're done.
00379                 return true;
00380         }
00381 
00382         // Try to do the actual apply.
00383         return panelp->apply(mesg);
00384 }
00385 
00386 void LLPanelGroupRoles::cancel()
00387 {
00388         // Pass this along to the currently visible sub tab.
00389         if (!mSubTabContainer) return;
00390 
00391         LLPanelGroupTab* panelp = (LLPanelGroupTab*) mSubTabContainer->getCurrentPanel();
00392         if (!panelp) return;
00393 
00394         panelp->cancel();
00395 }
00396 
00397 // Pass all of these messages to the currently visible sub tab.
00398 LLString LLPanelGroupRoles::getHelpText() const
00399 {
00400         LLPanelGroupTab* panelp = (LLPanelGroupTab*) mSubTabContainer->getCurrentPanel();
00401         if (panelp)
00402         {
00403                 return panelp->getHelpText();
00404         }
00405         else
00406         {
00407                 return mHelpText;
00408         }
00409 }
00410 
00411 void LLPanelGroupRoles::update(LLGroupChange gc)
00412 {
00413         if (mGroupID.isNull()) return;
00414 
00415         LLPanelGroupTab* panelp = (LLPanelGroupTab*) mSubTabContainer->getCurrentPanel();
00416         if (panelp)
00417         {
00418                 panelp->update(gc);
00419         }
00420         else
00421         {
00422                 llwarns << "LLPanelGroupRoles::update() -- No subtab to update!" << llendl;
00423         }
00424 }
00425 
00426 void LLPanelGroupRoles::activate()
00427 {
00428         // Start requesting member and role data if needed.
00429         LLGroupMgrGroupData* gdatap = gGroupMgr->getGroupData(mGroupID);
00430         //if (!gdatap || mFirstUse)
00431         {
00432                 // Check member data.
00433                 
00434                 if (!gdatap || !gdatap->isMemberDataComplete() )
00435                 {
00436                         gGroupMgr->sendGroupMembersRequest(mGroupID);
00437                 }
00438 
00439                 // Check role data.
00440                 if (!gdatap || !gdatap->isRoleDataComplete() )
00441                 {
00442                         // Mildly hackish - clear all pending changes
00443                         cancel();
00444 
00445                         gGroupMgr->sendGroupRoleDataRequest(mGroupID);
00446                 }
00447 
00448                 // Check role-member mapping data.
00449                 if (!gdatap || !gdatap->isRoleMemberDataComplete() )
00450                 {
00451                         gGroupMgr->sendGroupRoleMembersRequest(mGroupID);
00452                 }
00453 
00454                 // Need this to get base group member powers
00455                 if (!gdatap || !gdatap->isGroupPropertiesDataComplete() )
00456                 {
00457                         gGroupMgr->sendGroupPropertiesRequest(mGroupID);
00458                 }
00459 
00460                 mFirstUse = FALSE;
00461         }
00462 
00463         LLPanelGroupTab* panelp = (LLPanelGroupTab*) mSubTabContainer->getCurrentPanel();
00464         if (panelp) panelp->activate();
00465 }
00466 
00467 void LLPanelGroupRoles::deactivate()
00468 {
00469         LLPanelGroupTab* panelp = (LLPanelGroupTab*) mSubTabContainer->getCurrentPanel();
00470         if (panelp) panelp->deactivate();
00471 }
00472 
00473 bool LLPanelGroupRoles::needsApply(LLString& mesg)
00474 {
00475         LLPanelGroupTab* panelp = (LLPanelGroupTab*) mSubTabContainer->getCurrentPanel();
00476         if (!panelp) return false;
00477                 
00478         return panelp->needsApply(mesg);
00479 }
00480 
00481 BOOL LLPanelGroupRoles::hasModal()
00482 {
00483         if (mHasModal) return TRUE;
00484 
00485         LLPanelGroupTab* panelp = (LLPanelGroupTab*) mSubTabContainer->getCurrentPanel();
00486         if (!panelp) return FALSE;
00487                 
00488         return panelp->hasModal();
00489 }
00490 
00491 // PanelGroupTab observer trigger
00492 void LLPanelGroupRoles::tabChanged()
00493 {
00494         notifyObservers();
00495 }
00496 
00498 // LLPanelGroupSubTab
00500 LLPanelGroupSubTab::LLPanelGroupSubTab(const std::string& name, const LLUUID& group_id)
00501 :       LLPanelGroupTab(name, group_id),
00502         mHeader(NULL),
00503         mFooter(NULL),
00504         mSearchLineEditor(NULL),
00505         mSearchButton(NULL),
00506         mShowAllButton(NULL)
00507 {
00508 }
00509 
00510 LLPanelGroupSubTab::~LLPanelGroupSubTab()
00511 {
00512 }
00513 
00514 BOOL LLPanelGroupSubTab::postBuild()
00515 {
00516         // Hook up the search widgets.
00517         bool recurse = true;
00518         mSearchLineEditor = (LLLineEditor*) getChildByName("search_text", recurse);
00519 
00520         if (!mSearchLineEditor) return FALSE;
00521         mSearchLineEditor->setKeystrokeCallback(onSearchKeystroke);
00522         mSearchLineEditor->setCallbackUserData(this);
00523 
00524         mSearchButton = (LLButton*) getChildByName("search_button", recurse);
00525 
00526         if (!mSearchButton) return FALSE;
00527         mSearchButton->setClickedCallback(onClickSearch);
00528         mSearchButton->setCallbackUserData(this);
00529         mSearchButton->setEnabled(FALSE);
00530 
00531         mShowAllButton = (LLButton*) getChildByName("show_all_button", recurse);
00532 
00533         if (!mShowAllButton) return FALSE;
00534         mShowAllButton->setClickedCallback(onClickShowAll);
00535         mShowAllButton->setCallbackUserData(this);
00536         mShowAllButton->setEnabled(FALSE);
00537         
00538         // Get icons for later use.
00539         mActionIcons.clear();
00540 
00541         bool no_recurse = false;
00542 
00543         LLIconCtrl* icon = (LLIconCtrl*) getChildByName("power_folder_icon",no_recurse);
00544         if (icon && icon->getImage().notNull())
00545         {
00546                 mActionIcons["folder"] = icon->getImage();
00547                 removeChild(icon, TRUE);
00548         }
00549 
00550         icon = (LLIconCtrl*) getChildByName("power_all_have_icon",no_recurse);
00551         if (icon && icon->getImage().notNull())
00552         {
00553                 mActionIcons["full"] = icon->getImage();
00554                 removeChild(icon, TRUE);
00555         }
00556 
00557         icon = (LLIconCtrl*) getChildByName("power_partial_icon",no_recurse);
00558         if (icon && icon->getImage().notNull())
00559         {
00560                 mActionIcons["partial"] = icon->getImage();
00561                 removeChild(icon, TRUE);
00562         }
00563 
00564         return LLPanelGroupTab::postBuild();
00565 }
00566 
00567 // static
00568 void LLPanelGroupSubTab::onSearchKeystroke(LLLineEditor* caller, void* user_data)
00569 {
00570         LLPanelGroupSubTab* self = static_cast<LLPanelGroupSubTab*>(user_data);
00571         self->handleSearchKeystroke(caller);
00572 }
00573 
00574 void LLPanelGroupSubTab::handleSearchKeystroke(LLLineEditor* caller)
00575 {
00576         if (caller->getText().size())
00577         {
00578                 setDefaultBtn( mSearchButton );
00579                 mSearchButton->setEnabled(TRUE);
00580         }
00581         else
00582         {
00583                 setDefaultBtn( NULL );
00584                 mSearchButton->setEnabled(FALSE);
00585         }
00586 }
00587 
00588 // static 
00589 void LLPanelGroupSubTab::onClickSearch(void* user_data)
00590 {
00591         LLPanelGroupSubTab* self = static_cast<LLPanelGroupSubTab*>(user_data);
00592         self->handleClickSearch();
00593 }
00594  
00595 void LLPanelGroupSubTab::handleClickSearch()
00596 {
00597         lldebugs << "LLPanelGroupSubTab::handleClickSearch()" << llendl;
00598 
00599         if (0 == mSearchLineEditor->getText().size())
00600         {
00601                 // No search text.  (This shouldn't happen... the search button should have been disabled).
00602                 llwarns << "handleClickSearch with no search text!" << llendl;
00603                 mSearchButton->setEnabled(FALSE);
00604                 return;
00605         }
00606 
00607         setSearchFilter( mSearchLineEditor->getText() );
00608         mShowAllButton->setEnabled(TRUE);
00609 }
00610 
00611 // static
00612 void LLPanelGroupSubTab::onClickShowAll(void* user_data)
00613 {
00614         LLPanelGroupSubTab* self = static_cast<LLPanelGroupSubTab*>(user_data);
00615         self->handleClickShowAll();
00616 }
00617 
00618 void LLPanelGroupSubTab::handleClickShowAll()
00619 {
00620         lldebugs << "LLPanelGroupSubTab::handleClickShowAll()" << llendl;
00621         setSearchFilter( LLString::null );
00622         mShowAllButton->setEnabled(FALSE);
00623 }
00624 
00625 void LLPanelGroupSubTab::setSearchFilter(const LLString& filter)
00626 {
00627         lldebugs << "LLPanelGroupSubTab::setSearchFilter() ==> '" << filter << "'" << llendl;
00628         mSearchFilter = filter;
00629         LLString::toLower(mSearchFilter);
00630         update(GC_ALL);
00631 }
00632 
00633 void LLPanelGroupSubTab::activate()
00634 {
00635         lldebugs << "LLPanelGroupSubTab::activate()" << llendl;
00636         setOthersVisible(TRUE);
00637 }
00638 
00639 void LLPanelGroupSubTab::deactivate()
00640 {
00641         lldebugs << "LLPanelGroupSubTab::deactivate()" << llendl;
00642         setOthersVisible(FALSE);
00643 }
00644 
00645 void LLPanelGroupSubTab::setOthersVisible(BOOL b)
00646 {
00647         if (mHeader)
00648         {
00649                 mHeader->setVisible( b );
00650         }
00651         else
00652         {
00653                 llwarns << "LLPanelGroupSubTab missing header!" << llendl;
00654         }
00655 
00656         if (mFooter)
00657         {
00658                 mFooter->setVisible( b );
00659         }
00660         else
00661         {
00662                 llwarns << "LLPanelGroupSubTab missing footer!" << llendl;
00663         }
00664 }
00665 
00666 bool LLPanelGroupSubTab::matchesActionSearchFilter(std::string action)
00667 {
00668         // If the search filter is empty, everything passes.
00669         if (mSearchFilter.empty()) return true;
00670 
00671         LLString::toLower(action);
00672         std::string::size_type match = action.find(mSearchFilter);
00673 
00674         if (std::string::npos == match)
00675         {
00676                 // not found
00677                 return false;
00678         }
00679         else
00680         {
00681                 return true;
00682         }
00683 }
00684 
00685 void LLPanelGroupSubTab::buildActionsList(LLScrollListCtrl* ctrl, 
00686                                                                                   U64 allowed_by_some, 
00687                                                                                   U64 allowed_by_all,
00688                                                                                   icon_map_t& icons,
00689                                                                                   void (*commit_callback)(LLUICtrl*,void*),
00690                                                                                   BOOL show_all,
00691                                                                                   BOOL filter,
00692                                                                                   BOOL is_owner_role)
00693 {
00694         if (gGroupMgr->mRoleActionSets.empty())
00695         {
00696                 llwarns << "Can't build action list - no actions found." << llendl;
00697                 return;
00698         }
00699 
00700         std::vector<LLRoleActionSet*>::iterator ras_it = gGroupMgr->mRoleActionSets.begin();
00701         std::vector<LLRoleActionSet*>::iterator ras_end = gGroupMgr->mRoleActionSets.end();
00702 
00703         for ( ; ras_it != ras_end; ++ras_it)
00704         {
00705                 buildActionCategory(ctrl,
00706                                                         allowed_by_some,
00707                                                         allowed_by_all,
00708                                                         (*ras_it),
00709                                                         icons, 
00710                                                         commit_callback,
00711                                                         show_all,
00712                                                         filter,
00713                                                         is_owner_role);
00714         }
00715 }
00716 
00717 void LLPanelGroupSubTab::buildActionCategory(LLScrollListCtrl* ctrl,
00718                                                                                          U64 allowed_by_some,
00719                                                                                          U64 allowed_by_all,
00720                                                                                          LLRoleActionSet* action_set,
00721                                                                                          icon_map_t& icons,
00722                                                                                          void (*commit_callback)(LLUICtrl*,void*),
00723                                                                                          BOOL show_all,
00724                                                                                          BOOL filter,
00725                                                                                          BOOL is_owner_role)
00726 {
00727         lldebugs << "Building role list for: " << action_set->mActionSetData->mName << llendl;
00728         // See if the allow mask matches anything in this category.
00729         if (show_all || (allowed_by_some & action_set->mActionSetData->mPowerBit))
00730         {
00731                 // List all the actions in this category that at least some members have.
00732                 LLSD row;
00733 
00734                 row["columns"][0]["column"] = "icon";
00735                 icon_map_t::iterator iter = icons.find("folder");
00736                 if (iter != icons.end())
00737                 {
00738                         row["columns"][0]["type"] = "icon";
00739                         row["columns"][0]["value"] = (*iter).second;
00740                 }
00741 
00742                 row["columns"][1]["column"] = "action";
00743                 row["columns"][1]["value"] = action_set->mActionSetData->mName;
00744                 row["columns"][1]["font-style"] = "BOLD";
00745 
00746                 LLScrollListItem* title_row = ctrl->addElement(row, ADD_BOTTOM, action_set->mActionSetData);
00747 
00748                 bool category_matches_filter = (filter) ? matchesActionSearchFilter(action_set->mActionSetData->mName) : true;
00749 
00750                 std::vector<LLRoleAction*>::iterator ra_it = action_set->mActions.begin();
00751                 std::vector<LLRoleAction*>::iterator ra_end = action_set->mActions.end();
00752 
00753                 bool items_match_filter = false;
00754                 BOOL can_change_actions = (!is_owner_role && gAgent.hasPowerInGroup(mGroupID, GP_ROLE_CHANGE_ACTIONS));
00755 
00756                 for ( ; ra_it != ra_end; ++ra_it)
00757                 {
00758                         // See if anyone has these action.
00759                         if (!show_all && !(allowed_by_some & (*ra_it)->mPowerBit))
00760                         {
00761                                 continue;
00762                         }
00763 
00764                         // See if we are filtering out these actions
00765                         // If we aren't using filters, category_matches_filter will be true.
00766                         if (!category_matches_filter
00767                                 && !matchesActionSearchFilter((*ra_it)->mDescription))
00768                         {
00769                                 continue;                                                                               
00770                         }
00771 
00772                         items_match_filter = true;
00773 
00774                         // See if everyone has these actions.
00775                         bool show_full_strength = false;
00776                         if ( (allowed_by_some & (*ra_it)->mPowerBit) == (allowed_by_all & (*ra_it)->mPowerBit) )
00777                         {
00778                                 show_full_strength = true;
00779                         }
00780 
00781                         LLSD row;
00782 
00783                         S32 column_index = 0;
00784                         row["columns"][column_index]["column"] = "icon";
00785                         ++column_index;
00786 
00787                         
00788                         S32 check_box_index = -1;
00789                         if (commit_callback)
00790                         {
00791                                 row["columns"][column_index]["column"] = "checkbox";
00792                                 row["columns"][column_index]["type"] = "checkbox";
00793                                 row["columns"][column_index]["value"] = (*ra_it)->mName;
00794                                 check_box_index = column_index;
00795                                 ++column_index;
00796                         }
00797                         else
00798                         {
00799                                 if (show_full_strength)
00800                                 {
00801                                         icon_map_t::iterator iter = icons.find("full");
00802                                         if (iter != icons.end())
00803                                         {
00804                                                 row["columns"][column_index]["column"] = "checkbox";
00805                                                 row["columns"][column_index]["type"] = "icon";
00806                                                 row["columns"][column_index]["value"] = (*iter).second;
00807                                                 ++column_index;
00808                                         }
00809                                 }
00810                                 else
00811                                 {
00812                                         icon_map_t::iterator iter = icons.find("partial");
00813                                         if (iter != icons.end())
00814                                         {
00815                                                 row["columns"][column_index]["column"] = "checkbox";
00816                                                 row["columns"][column_index]["type"] = "icon";
00817                                                 row["columns"][column_index]["value"] = (*iter).second;
00818                                                 ++column_index;
00819                                         }
00820                                         row["enabled"] = false;
00821                                 }
00822                         }
00823 
00824                         row["columns"][column_index]["column"] = "action";
00825                         row["columns"][column_index]["value"] = (*ra_it)->mDescription;
00826                         row["columns"][column_index]["font"] = "SANSSERIFSMALL";
00827 
00828                         LLScrollListItem* item = ctrl->addElement(row, ADD_BOTTOM, (*ra_it));
00829 
00830                         if (-1 != check_box_index)
00831                         {
00832                                 // Extract the checkbox that was created.
00833                                 LLScrollListCheck* check_cell = (LLScrollListCheck*) item->getColumn(check_box_index);
00834                                 LLCheckBoxCtrl* check = check_cell->getCheckBox();
00835                                 check->setEnabled(can_change_actions);
00836                                 check->setCommitCallback(commit_callback);
00837                                 check->setCallbackUserData(ctrl->getCallbackUserData());
00838                                 check->setToolTip( check->getLabel() );
00839 
00840                                 if (show_all)
00841                                 {
00842                                         check->setTentative(FALSE);
00843                                         if (allowed_by_some & (*ra_it)->mPowerBit)
00844                                         {
00845                                                 check->set(TRUE);
00846                                         }
00847                                         else
00848                                         {
00849                                                 check->set(FALSE);
00850                                         }
00851                                 }
00852                                 else
00853                                 {
00854                                         check->set(TRUE);
00855                                         if (show_full_strength)
00856                                         {
00857                                                 check->setTentative(FALSE);
00858                                         }
00859                                         else
00860                                         {
00861                                                 check->setTentative(TRUE);
00862                                         }
00863                                 }
00864                         }
00865                 }
00866 
00867                 if (!items_match_filter)
00868                 {
00869                         S32 title_index = ctrl->getItemIndex(title_row);
00870                         ctrl->deleteSingleItem(title_index);
00871                 }
00872         }
00873 }
00874 
00875 void LLPanelGroupSubTab::setFooterEnabled(BOOL enable)
00876 {
00877         if (mFooter)
00878         {
00879                 mFooter->setAllChildrenEnabled(enable);
00880         }
00881 }
00882 
00884 // LLPanelGroupMembersSubTab
00886 
00887 // static
00888 void* LLPanelGroupMembersSubTab::createTab(void* data)
00889 {
00890         LLUUID* group_id = static_cast<LLUUID*>(data);
00891         return new LLPanelGroupMembersSubTab("panel group members sub tab", *group_id);
00892 }
00893 
00894 LLPanelGroupMembersSubTab::LLPanelGroupMembersSubTab(const std::string& name, const LLUUID& group_id)
00895 :       LLPanelGroupSubTab(name, group_id),
00896         mMembersList(NULL),
00897         mAssignedRolesList(NULL),
00898         mAllowedActionsList(NULL),
00899         mChanged(FALSE),
00900         mPendingMemberUpdate(FALSE),
00901         mHasMatch(FALSE),
00902         mNumOwnerAdditions(0)
00903 {
00904 }
00905 
00906 LLPanelGroupMembersSubTab::~LLPanelGroupMembersSubTab()
00907 {
00908 }
00909 
00910 BOOL LLPanelGroupMembersSubTab::postBuildSubTab(LLView* root)
00911 {
00912         // Upcast parent so we can ask it for sibling controls.
00913         LLPanelGroupRoles* parent = (LLPanelGroupRoles*) root;
00914 
00915         // Look recursively from the parent to find all our widgets.
00916         bool recurse = true;
00917         mHeader = (LLPanel*) parent->getChildByName("members_header", recurse);
00918         mFooter = (LLPanel*) parent->getChildByName("members_footer", recurse);
00919 
00920         mMembersList            = (LLNameListCtrl*)     parent->getChildByName("member_list", recurse);
00921         mAssignedRolesList      = (LLScrollListCtrl*)   parent->getChildByName("member_assigned_roles", recurse);
00922         mAllowedActionsList     = (LLScrollListCtrl*)   parent->getChildByName("member_allowed_actions", recurse);
00923 
00924         if (!mMembersList || !mAssignedRolesList || !mAllowedActionsList) return FALSE;
00925 
00926         // We want to be notified whenever a member is selected.
00927         mMembersList->setCallbackUserData(this);
00928         mMembersList->setCommitOnSelectionChange(TRUE);
00929         mMembersList->setCommitCallback(onMemberSelect);
00930         // Show the member's profile on double click.
00931         mMembersList->setDoubleClickCallback(onMemberDoubleClick);
00932 
00933         LLButton* button = (LLButton*) parent->getChildByName("member_invite", recurse);
00934         if ( button )
00935         {
00936                 button->setClickedCallback(onInviteMember);
00937                 button->setCallbackUserData(this);
00938                 button->setEnabled(gAgent.hasPowerInGroup(mGroupID, GP_MEMBER_INVITE));
00939         }
00940 
00941         mEjectBtn = (LLButton*) parent->getChildByName("member_eject", recurse);
00942         if ( mEjectBtn )
00943         {
00944                 mEjectBtn->setClickedCallback(onEjectMembers);
00945                 mEjectBtn->setCallbackUserData(this);
00946                 mEjectBtn->setEnabled(FALSE);
00947         }
00948 
00949         return TRUE;
00950 }
00951 
00952 
00953 // static
00954 void LLPanelGroupMembersSubTab::onMemberSelect(LLUICtrl* ctrl, void* user_data)
00955 {
00956         LLPanelGroupMembersSubTab* self = static_cast<LLPanelGroupMembersSubTab*>(user_data);
00957         self->handleMemberSelect();
00958 }
00959 
00960 void LLPanelGroupMembersSubTab::handleMemberSelect()
00961 {
00962         lldebugs << "LLPanelGroupMembersSubTab::handleMemberSelect" << llendl;
00963 
00964         mAssignedRolesList->deleteAllItems();
00965         mAllowedActionsList->deleteAllItems();
00966         
00967         LLGroupMgrGroupData* gdatap = gGroupMgr->getGroupData(mGroupID);
00968         if (!gdatap) 
00969         {
00970                 llwarns << "LLPanelGroupMembersSubTab::handleMemberSelect() "
00971                                 << "-- No group data!" << llendl;
00972                 return;
00973         }
00974 
00975         // Check if there is anything selected.
00976         std::vector<LLScrollListItem*> selection = mMembersList->getAllSelected();
00977         if (selection.empty()) return;
00978 
00979         // Build a vector of all selected members, and gather allowed actions.
00980         std::vector<LLUUID> selected_members;
00981         U64 allowed_by_all = 0xffffffffffffLL;
00982         U64 allowed_by_some = 0;
00983 
00984         std::vector<LLScrollListItem*>::iterator itor;
00985         for (itor = selection.begin();
00986                  itor != selection.end(); ++itor)
00987         {
00988                 selected_members.push_back( (*itor)->getUUID() );
00989                 // Get this member's power mask including any unsaved changes
00990 
00991                 U64 powers = getAgentPowersBasedOnRoleChanges((*itor)->getUUID());
00992 
00993                 allowed_by_all &= powers;
00994                 allowed_by_some |= powers;
00995         }
00996         std::sort(selected_members.begin(), selected_members.end());
00997 
00999         // Build the allowed actions list.
01001         buildActionsList(mAllowedActionsList,
01002                                          allowed_by_some,
01003                                          allowed_by_all,
01004                                          mActionIcons,
01005                                          NULL,
01006                                          FALSE,
01007                                          FALSE,
01008                                          FALSE);
01009 
01011         // Build the assigned roles list.
01013         // Add each role to the assigned roles list.
01014         LLGroupMgrGroupData::role_iter iter = gdatap->mRoles.begin();
01015         LLGroupMgrGroupData::role_iter end  = gdatap->mRoles.end();
01016 
01017         BOOL can_eject_members = gAgent.hasPowerInGroup(mGroupID,
01018                                                                                                         GP_MEMBER_EJECT);
01019         BOOL member_is_owner = FALSE;
01020         
01021         for( ; iter != end; ++iter)
01022         {
01023                 // Count how many selected users are in this role.
01024                 const LLUUID& role_id = iter->first;
01025                 LLGroupRoleData* group_role_data = iter->second;
01026 
01027                 if (group_role_data)
01028                 {
01029                         const BOOL needs_sort = FALSE;
01030                         S32 count = group_role_data->getMembersInRole(
01031                                                                                         selected_members, needs_sort);
01032                         //check if the user has permissions to assign/remove
01033                         //members to/from the role (but the ability to add/remove
01034                         //should only be based on the "saved" changes to the role
01035                         //not in the temp/meta data. -jwolk
01036                         BOOL cb_enable = ( (count > 0) ?
01037                                                            agentCanRemoveFromRole(mGroupID, role_id) :
01038                                                            agentCanAddToRole(mGroupID, role_id) );
01039 
01040 
01041                         // Owner role has special enabling permissions for removal.
01042                         if (cb_enable && (count > 0) && role_id == gdatap->mOwnerRole)
01043                         {
01044                                 // Check if any owners besides this agent are selected.
01045                                 std::vector<LLUUID>::const_iterator member_iter;
01046                                 std::vector<LLUUID>::const_iterator member_end =
01047                                                                                                 selected_members.end();
01048                                 for (member_iter = selected_members.begin();
01049                                          member_iter != member_end;     
01050                                          ++member_iter)
01051                                 {
01052                                         // Don't count the agent.
01053                                         if ((*member_iter) == gAgent.getID()) continue;
01054                                         
01055                                         // Look up the member data.
01056                                         LLGroupMgrGroupData::member_iter mi = 
01057                                                                         gdatap->mMembers.find((*member_iter));
01058                                         if (mi == gdatap->mMembers.end()) continue;
01059                                         LLGroupMemberData* member_data = (*mi).second;
01060                                         // Is the member an owner?
01061                                         if ( member_data->isInRole(gdatap->mOwnerRole) )
01062                                         {
01063                                                 // Can't remove other owners.
01064                                                 cb_enable = FALSE;
01065                                                 break;
01066                                         }
01067                                 }
01068                         }
01069 
01070                         //now see if there are any role changes for the selected
01071                         //members and remember to include them
01072                         std::vector<LLUUID>::iterator sel_mem_iter = selected_members.begin();
01073                         for (; sel_mem_iter != selected_members.end(); sel_mem_iter++)
01074                         {
01075                                 LLRoleMemberChangeType type;
01076                                 if ( getRoleChangeType(*sel_mem_iter, role_id, type) )
01077                                 {
01078                                         if ( type == RMC_ADD ) count++;
01079                                         else if ( type == RMC_REMOVE ) count--;
01080                                 }
01081                         }
01082                         
01083                         // If anyone selected is in any role besides 'Everyone' then they can't be ejected.
01084                         if (role_id.notNull() && (count > 0))
01085                         {
01086                                 can_eject_members = FALSE;
01087                                 if (role_id == gdatap->mOwnerRole)
01088                                 {
01089                                         member_is_owner = TRUE;
01090                                 }
01091                         }
01092 
01093                         LLRoleData rd;
01094                         if (gdatap->getRoleData(role_id,rd))
01095                         {
01096                                 std::ostringstream label;
01097                                 label << rd.mRoleName;
01098                                 // Don't bother showing a count, if there is only 0 or 1.
01099                                 if (count > 1)
01100                                 {
01101                                         label << ": " << count ;
01102                                 }
01103         
01104                                 LLSD row;
01105                                 row["id"] = role_id;
01106 
01107                                 row["columns"][0]["column"] = "checkbox";
01108                                 row["columns"][0]["type"] = "checkbox";
01109 
01110                                 row["columns"][1]["column"] = "role";
01111                                 row["columns"][1]["value"] = label.str();
01112 
01113                                 if (row["id"].asUUID().isNull())
01114                                 {
01115                                         // This is the everyone role, you can't take people out of the everyone role!
01116                                         row["enabled"] = false;
01117                                 }
01118 
01119                                 LLScrollListItem* item = mAssignedRolesList->addElement(row);
01120 
01121                                 // Extract the checkbox that was created.
01122                                 LLScrollListCheck* check_cell = (LLScrollListCheck*) item->getColumn(0);
01123                                 LLCheckBoxCtrl* check = check_cell->getCheckBox();
01124                                 check->setCommitCallback(onRoleCheck);
01125                                 check->setCallbackUserData(this);
01126                                 check->set( count > 0 );
01127                                 check->setTentative(
01128                                         (0 != count)
01129                                         && (selected_members.size() !=
01130                                                 (std::vector<LLUUID>::size_type)count));
01131 
01132                                 //NOTE: as of right now a user can break the group
01133                                 //by removing himself from a role if he is the
01134                                 //last owner.  We should check for this special case
01135                                 // -jwolk
01136                                 check->setEnabled(cb_enable);
01137                         }
01138                 }
01139                 else
01140                 {
01141                         // This could happen if changes are not synced right on sub-panel change.
01142                         llwarns << "No group role data for " << iter->second << llendl;
01143                 }
01144         }
01145         mAssignedRolesList->setEnabled(TRUE);
01146 
01147         if (!can_eject_members && !member_is_owner)
01148         {
01149                 // Maybe we can eject them because we are an owner...
01150                 LLGroupMgrGroupData::member_iter mi = gdatap->mMembers.find(gAgent.getID());
01151                 if (mi != gdatap->mMembers.end())
01152                 {
01153                         LLGroupMemberData* member_data = (*mi).second;
01154 
01155                         if ( member_data && member_data->isInRole(gdatap->mOwnerRole) )
01156                         {
01157                                 can_eject_members = TRUE;
01158                         }
01159                 }
01160         }
01161 
01162         mEjectBtn->setEnabled(can_eject_members);
01163 }
01164 
01165 // static
01166 void LLPanelGroupMembersSubTab::onMemberDoubleClick(void* user_data)
01167 {
01168         LLPanelGroupMembersSubTab* self = static_cast<LLPanelGroupMembersSubTab*>(user_data);
01169         self->handleMemberDoubleClick();
01170 }
01171 
01172 //static
01173 void LLPanelGroupMembersSubTab::onInviteMember(void *userdata)
01174 {
01175         LLPanelGroupMembersSubTab* selfp = (LLPanelGroupMembersSubTab*) userdata;
01176 
01177         if ( selfp )
01178         {
01179                 selfp->handleInviteMember();
01180         }
01181 }
01182 
01183 void LLPanelGroupMembersSubTab::handleInviteMember()
01184 {
01185         LLFloaterGroupInvite::showForGroup(mGroupID);
01186 }
01187 
01188 void LLPanelGroupMembersSubTab::onEjectMembers(void *userdata)
01189 {
01190         LLPanelGroupMembersSubTab* selfp = (LLPanelGroupMembersSubTab*) userdata;
01191 
01192         if ( selfp )
01193         {
01194                 selfp->handleEjectMembers();
01195         }
01196 }
01197 
01198 void LLPanelGroupMembersSubTab::handleEjectMembers()
01199 {
01200         //send down an eject message
01201         std::vector<LLUUID> selected_members;
01202 
01203         std::vector<LLScrollListItem*> selection = mMembersList->getAllSelected();
01204         if (selection.empty()) return;
01205 
01206         std::vector<LLScrollListItem*>::iterator itor;
01207         for (itor = selection.begin() ; 
01208                  itor != selection.end(); ++itor)
01209         {
01210                 selected_members.push_back((*itor)->getUUID());
01211         }
01212 
01213         mMembersList->deleteSelectedItems();
01214 
01215         gGroupMgr->sendGroupMemberEjects(mGroupID,
01216                                                                          selected_members);
01217 }
01218 
01219 void LLPanelGroupMembersSubTab::handleRoleCheck(const LLUUID& role_id,
01220                                                                                                 LLRoleMemberChangeType type)
01221 {
01222         LLGroupMgrGroupData* gdatap = gGroupMgr->getGroupData(mGroupID);
01223         if (!gdatap) return;
01224 
01225         //add that the user is requesting to change the roles for selected
01226         //members
01227         U64 powers_all_have  = 0xffffffffffffLL;
01228         U64 powers_some_have = 0;
01229 
01230         BOOL   is_owner_role = ( gdatap->mOwnerRole == role_id );
01231         LLUUID member_id;
01232         
01233 
01234         member_role_change_iter           member_end = mMemberRoleChangeData.end();
01235         member_role_change_iter           member;
01236         role_change_data_map_t           *role_change_datap;
01237         role_change_data_map_t::iterator  role_end;
01238         role_change_data_map_t::iterator  role;
01239 
01240         std::vector<LLScrollListItem*> selection = mMembersList->getAllSelected();
01241         if (selection.empty()) return;
01242 
01243         std::vector<LLScrollListItem*>::iterator itor;
01244         for (itor = selection.begin() ; 
01245                  itor != selection.end(); ++itor)
01246         {
01247                 member_id = (*itor)->getUUID();
01248 
01249                 //see if we requested a change for this member before
01250                 member = mMemberRoleChangeData.find(member_id);
01251                 if ( member != member_end )
01252                 {
01253                         //this member had previously had their role data changed
01254                         //so grab it
01255                         role_change_datap = (*member).second;
01256                 }
01257                 else
01258                 {
01259                         role_change_datap = new role_change_data_map_t;
01260                         mMemberRoleChangeData[member_id] = role_change_datap;
01261                 }
01262 
01263                 //now check to see if the selected group member
01264                 //had changed his association with the selected role before
01265                 role_end = role_change_datap->end();
01266                 role     = role_change_datap->find(role_id);
01267 
01268                 if ( role != role_end )
01269                 {
01270                         //see if the new change type cancels out the previous change
01271                         if (role->second != type)
01272                         {
01273                                 role_change_datap->erase(role_id);
01274                                 if ( is_owner_role ) mNumOwnerAdditions--;
01275                         }
01276                         //else do nothing
01277 
01278                         if ( role_change_datap->empty() )
01279                         {
01280                                 //the current member now has no role changes
01281                                 //so erase the role change and erase the member's entry
01282                                 delete role_change_datap;
01283                 role_change_datap = NULL;
01284 
01285                                 mMemberRoleChangeData.erase(member_id);
01286                         }
01287                 }
01288                 else
01289                 {
01290                         //a previously unchanged role is being changed
01291                         (*role_change_datap)[role_id] = type;
01292                         if ( is_owner_role && type == RMC_ADD ) mNumOwnerAdditions++;
01293                 }
01294 
01295                 //we need to calculate what powers the selected members
01296                 //have (including the role changes we're making)
01297                 //so that we can rebuild the action list
01298                 U64 new_powers = getAgentPowersBasedOnRoleChanges(member_id);
01299 
01300                 powers_all_have  &= new_powers;
01301                 powers_some_have |= new_powers;
01302         }
01303 
01304         
01305         mChanged = !mMemberRoleChangeData.empty();
01306         notifyObservers();
01307 
01308         //alrighty now we need to update the actions list
01309         //to reflect the changes
01310         mAllowedActionsList->deleteAllItems();
01311         buildActionsList(mAllowedActionsList,
01312                                          powers_some_have,
01313                                          powers_all_have,
01314                                          mActionIcons,
01315                                          NULL,
01316                                          FALSE,
01317                                          FALSE,
01318                                          FALSE);
01319 }
01320 
01321 
01322 // static 
01323 void LLPanelGroupMembersSubTab::onRoleCheck(LLUICtrl* ctrl, void* user_data)
01324 {
01325         LLPanelGroupMembersSubTab* self = static_cast<LLPanelGroupMembersSubTab*>(user_data);
01326         LLCheckBoxCtrl* check_box = static_cast<LLCheckBoxCtrl*>(ctrl);
01327         if (!check_box || !self) return;
01328 
01329         LLScrollListItem* first_selected =
01330                 self->mAssignedRolesList->getFirstSelected();
01331         if (first_selected)
01332         {
01333                 LLUUID role_id = first_selected->getUUID();
01334                 LLRoleMemberChangeType change_type = (check_box->get() ? 
01335                                                       RMC_ADD : 
01336                                                       RMC_REMOVE);
01337                 
01338                 self->handleRoleCheck(role_id, change_type);
01339         }
01340 }
01341 
01342 void LLPanelGroupMembersSubTab::handleMemberDoubleClick()
01343 {
01344         LLScrollListItem* selected = mMembersList->getFirstSelected();
01345         if (selected)
01346         {
01347                 LLFloaterAvatarInfo::showFromDirectory( selected->getUUID() );
01348         }
01349 }
01350 
01351 void LLPanelGroupMembersSubTab::activate()
01352 {
01353         LLPanelGroupSubTab::activate();
01354 
01355         update(GC_ALL);
01356 }
01357 
01358 void LLPanelGroupMembersSubTab::deactivate()
01359 {
01360         LLPanelGroupSubTab::deactivate();
01361 }
01362 
01363 bool LLPanelGroupMembersSubTab::needsApply(LLString& mesg)
01364 {
01365         return mChanged;
01366 }
01367 
01368 void LLPanelGroupMembersSubTab::cancel()
01369 {
01370         if ( mChanged )
01371         {
01372                 std::for_each(mMemberRoleChangeData.begin(),
01373                                           mMemberRoleChangeData.end(),
01374                                           DeletePairedPointer());
01375                 mMemberRoleChangeData.clear();
01376 
01377                 mChanged = FALSE;
01378                 notifyObservers();
01379         }
01380 }
01381 
01382 bool LLPanelGroupMembersSubTab::apply(LLString& mesg)
01383 {
01384         LLGroupMgrGroupData* gdatap = gGroupMgr->getGroupData(mGroupID);
01385         if (!gdatap)
01386         {
01387                 llwarns << "Unable to get group data for group " << mGroupID << llendl;
01388 
01389                 mesg.assign("Unable to save member data.  Try again later.");
01390                 return false;
01391         }
01392 
01393         if (mChanged)
01394         {
01395                 //figure out if we are somehow adding an owner or not and alert
01396                 //the user...possibly make it ignorable
01397                 if ( mNumOwnerAdditions > 0 )
01398                 {
01399                         LLRoleData rd;
01400                         LLStringBase<char>::format_map_t args;
01401 
01402                         if ( gdatap->getRoleData(gdatap->mOwnerRole, rd) )
01403                         {
01404                                 mHasModal = TRUE;
01405                                 args["[ROLE_NAME]"] = rd.mRoleName;
01406                                 gViewerWindow->alertXml("AddGroupOwnerWarning",
01407                                                                                 args,
01408                                                                                 addOwnerCB,
01409                                                                                 this);
01410                         }
01411                         else
01412                         {
01413                                 llwarns << "Unable to get role information for the owner role in group " << mGroupID << llendl;
01414 
01415                                 mesg.assign("Unable to retried specific group information.  Try again later");
01416                                 return false;
01417                         }
01418                                  
01419                 }
01420                 else
01421                 {
01422                         applyMemberChanges();
01423                 }
01424         }
01425 
01426         return true;
01427 }
01428 
01429 //static
01430 void LLPanelGroupMembersSubTab::addOwnerCB(S32 option, void* data)
01431 {
01432         LLPanelGroupMembersSubTab* self = (LLPanelGroupMembersSubTab*) data;
01433 
01434         if (!self) return;
01435         
01436         self->mHasModal = FALSE;
01437 
01438         if (0 == option)
01439         {
01440                 // User clicked "Yes"
01441                 self->applyMemberChanges();
01442         }
01443 }
01444 
01445 void LLPanelGroupMembersSubTab::applyMemberChanges()
01446 {
01447         //sucks to do a find again here, but it is in constant time, so, could
01448         //be worse
01449         LLGroupMgrGroupData* gdatap = gGroupMgr->getGroupData(mGroupID);
01450         if (!gdatap)
01451         {
01452                 llwarns << "Unable to get group data for group " << mGroupID << llendl;
01453                 return;
01454         }
01455 
01456         //we need to add all of the changed roles data
01457         //for each member whose role changed
01458         member_role_change_iter member_end = mMemberRoleChangeData.end();
01459         member_role_change_iter member     = mMemberRoleChangeData.begin();
01460 
01461         for (; member != member_end; member++)
01462         {
01463                 role_change_data_map_t::iterator role_end = member->second->end();
01464                 role_change_data_map_t::iterator role     = member->second->begin();
01465 
01466                 for (; role != role_end; role++)
01467                 {
01468                         gdatap->changeRoleMember(role->first, //role_id
01469                                                                          member->first, //member_id
01470                                                                          role->second); //add/remove
01471                 }
01472 
01473                 member->second->clear();
01474                 delete member->second;
01475         }
01476         mMemberRoleChangeData.clear();
01477 
01478         gGroupMgr->sendGroupRoleMemberChanges(mGroupID);        
01479         //force a UI update
01480         handleMemberSelect();
01481 
01482         mChanged = FALSE;
01483         mNumOwnerAdditions = 0;
01484         notifyObservers();
01485 }
01486 
01487 bool LLPanelGroupMembersSubTab::matchesSearchFilter(char* first, char* last)
01488 {
01489         // If the search filter is empty, everything passes.
01490         if (mSearchFilter.empty()) return true;
01491 
01492         // Create a full name, and compare it to the search filter.
01493         LLString fullname;
01494         fullname.assign(first);
01495         fullname.append(1, ' ');
01496         fullname.append(last);
01497         LLString::toLower(fullname);
01498 
01499         std::string::size_type match = fullname.find(mSearchFilter);
01500 
01501         if (std::string::npos == match)
01502         {
01503                 // not found
01504                 return false;
01505         }
01506         else
01507         {
01508                 return true;
01509         }
01510 }
01511 
01512 U64 LLPanelGroupMembersSubTab::getAgentPowersBasedOnRoleChanges(const LLUUID& agent_id)
01513 {
01514         //we loop over all of the changes
01515         //if we are adding a role, then we simply add the role's powers
01516         //if we are removing a role, we store that role id away
01517         //and then we have to build the powers up bases on the roles the agent
01518         //is in
01519         member_role_change_iter          member_end = mMemberRoleChangeData.end();
01520         member_role_change_iter          member;
01521         role_change_data_map_t          *role_change_datap = NULL;
01522         role_change_data_map_t::iterator role_end;
01523         role_change_data_map_t::iterator role;
01524 
01525         LLGroupMgrGroupData* gdatap = gGroupMgr->getGroupData(mGroupID);
01526         if (!gdatap) 
01527         {
01528                 llwarns << "LLPanelGroupMembersSubTab::getAgentPowersBasedOnRoleChanges() -- No group data!" << llendl;
01529                 return GP_NO_POWERS;
01530         }
01531 
01532         LLGroupMemberData* member_data = gdatap->mMembers[agent_id];
01533         if ( !member_data )
01534         {
01535                 llwarns << "LLPanelGroupMembersSubTab::getAgentPowersBasedOnRoleChanges() -- No member data for member with UUID " << agent_id << llendl;
01536                 return GP_NO_POWERS;
01537         }
01538 
01539         //see if there are unsaved role changes for this agent
01540         member = mMemberRoleChangeData.find(agent_id);
01541         if ( member != member_end )
01542         {
01543                 //this member has unsaved role changes
01544                 //so grab them
01545                 role_change_datap = (*member).second;
01546         }
01547 
01548         U64 new_powers = GP_NO_POWERS;
01549 
01550         if ( role_change_datap )
01551         {
01552                 std::vector<LLUUID> roles_to_be_removed;
01553 
01554                 role_end = role_change_datap->end();
01555                 role     = role_change_datap->begin();
01556 
01557                 for (; role != role_end; role++)
01558                 {
01559                         if ( role->second == RMC_ADD )
01560                                 new_powers |= gdatap->getRolePowers(role->first);
01561                         else
01562                         {
01563                                 roles_to_be_removed.push_back(role->first);
01564                         }
01565                 }
01566 
01567                 //loop over the member's current roles, summing up
01568                 //the powers (not including the role we are removing)
01569                 std::map<LLUUID,LLGroupRoleData*>::iterator current_role =
01570                         member_data->roleBegin();
01571                 std::map<LLUUID,LLGroupRoleData*>::iterator end_role = 
01572                         member_data->roleEnd();
01573 
01574                 for (; current_role != end_role; current_role++)
01575                 {
01576                         bool role_in_remove_list =
01577                                 (std::find(roles_to_be_removed.begin(),
01578                                                    roles_to_be_removed.end(),
01579                                                    current_role->second->getID()) !=
01580                                  roles_to_be_removed.end());
01581 
01582                         if ( !role_in_remove_list )
01583                         {
01584                                 new_powers |= 
01585                                         current_role->second->getRoleData().mRolePowers;
01586                         }
01587                 }
01588         }
01589         else
01590         {
01591                 //there are no changes for this member
01592                 //the member's powers are just the ones stored in the group
01593                 //manager
01594                 new_powers = member_data->getAgentPowers();
01595         }
01596 
01597         return new_powers;
01598 }
01599 
01600 //If there is no change, returns false be sure to verify
01601 //that there is a role change before attempting to get it or else
01602 //the data will make no sense.  Stores the role change type
01603 bool LLPanelGroupMembersSubTab::getRoleChangeType(const LLUUID& member_id,
01604                                                                                                   const LLUUID& role_id,
01605                                                                                                   LLRoleMemberChangeType& type)
01606 {
01607         member_role_change_iter           member_changes_iter;
01608         role_change_data_map_t::iterator  role_changes_iter;
01609 
01610         member_changes_iter = mMemberRoleChangeData.find(member_id);
01611         if ( member_changes_iter != mMemberRoleChangeData.end() )
01612         {
01613                 role_changes_iter = member_changes_iter->second->find(role_id);
01614                 if ( role_changes_iter != member_changes_iter->second->end() )
01615                 {
01616                         type = role_changes_iter->second;
01617                         return true;
01618                 }
01619         }
01620 
01621         return false;
01622 }
01623 
01624 void LLPanelGroupMembersSubTab::draw()
01625 {
01626         LLPanelGroupSubTab::draw();
01627 
01628         if (mPendingMemberUpdate)
01629         {
01630                 updateMembers();
01631         }
01632 }
01633 
01634 void LLPanelGroupMembersSubTab::update(LLGroupChange gc)
01635 {
01636         if (mGroupID.isNull()) return;
01637 
01638         if ( GC_TITLES == gc || GC_PROPERTIES == gc )
01639         {
01640                 // Don't care about title or general group properties updates.
01641                 return;
01642         }
01643 
01644         LLGroupMgrGroupData* gdatap = gGroupMgr->getGroupData(mGroupID);
01645         if (!gdatap) 
01646         {
01647                 llwarns << "LLPanelGroupMembersSubTab::update() -- No group data!" << llendl;
01648                 return;
01649         }
01650 
01651         // Rebuild the members list.
01652         mMembersList->deleteAllItems();
01653 
01654         // Wait for both all data to be retrieved before displaying anything.
01655         if (   gdatap->isMemberDataComplete() 
01656                 && gdatap->isRoleDataComplete()
01657                 && gdatap->isRoleMemberDataComplete())
01658         {
01659                 mMemberProgress = gdatap->mMembers.begin();
01660                 mPendingMemberUpdate = TRUE;
01661                 mHasMatch = FALSE;
01662         }
01663         else
01664         {
01665                 // Build a string with info on retrieval progress.
01666                 std::ostringstream retrieved;
01667                 if ( !gdatap->isMemberDataComplete() )
01668                 {
01669                         // Still busy retreiving member list.
01670                         retrieved << "Retrieving member list (" << gdatap->mMembers.size()
01671                                           << " / " << gdatap->mMemberCount << ")...";
01672                 }
01673                 else if( !gdatap->isRoleDataComplete() )
01674                 {
01675                         // Still busy retreiving role list.
01676                         retrieved << "Retrieving role list (" << gdatap->mRoles.size()
01677                                           << " / " << gdatap->mRoleCount << ")...";
01678                 }
01679                 else // (!gdatap->isRoleMemberDataComplete())
01680                 {
01681                         // Still busy retreiving role/member mappings.
01682                         retrieved << "Retrieving role member mappings...";
01683                 }
01684                 mMembersList->setEnabled(FALSE);
01685                 mMembersList->addSimpleItem(retrieved.str());
01686         }
01687 }
01688 
01689 void LLPanelGroupMembersSubTab::updateMembers()
01690 {
01691         mPendingMemberUpdate = FALSE;
01692 
01693         lldebugs << "LLPanelGroupMembersSubTab::updateMembers()" << llendl;
01694 
01695         LLGroupMgrGroupData* gdatap = gGroupMgr->getGroupData(mGroupID);
01696         if (!gdatap) 
01697         {
01698                 llwarns << "LLPanelGroupMembersSubTab::updateMembers() -- No group data!" << llendl;
01699                 return;
01700         }
01701 
01702         // Make sure all data is still complete.  Incomplete data
01703         // may occur if we refresh.
01704         if (   !gdatap->isMemberDataComplete() 
01705                 || !gdatap->isRoleDataComplete()
01706                 || !gdatap->isRoleMemberDataComplete())
01707         {
01708                 return;
01709         }
01710                 
01711         LLGroupMgrGroupData::member_iter end = gdatap->mMembers.end();
01712 
01713         char first[DB_FIRST_NAME_BUF_SIZE];             /*Flawfinder: ignore*/
01714         char last[DB_LAST_NAME_BUF_SIZE];               /*Flawfinder: ignore*/
01715         S32 i = 0;
01716         for( ; mMemberProgress != end && i<UPDATE_MEMBERS_PER_FRAME; 
01717                         ++mMemberProgress, ++i)
01718         {
01719                 if (!mMemberProgress->second)
01720                         continue;
01721                 // Do filtering on name if it is already in the cache.
01722                 bool add_member = true;
01723 
01724                 if (gCacheName->getName(mMemberProgress->first, first, last))
01725                 {
01726                         if ( !matchesSearchFilter(first, last) )
01727                         {
01728                                 add_member = false;
01729                         }
01730                 }
01731 
01732                 if (add_member)
01733                 {
01734                         // Build the donated tier string.
01735                         std::ostringstream donated;
01736                         donated << mMemberProgress->second->getContribution() << " sq. m.";
01737 
01738                         LLSD row;
01739                         row["id"] = (*mMemberProgress).first;
01740 
01741                         row["columns"][0]["column"] = "name";
01742                         // value is filled in by name list control
01743 
01744                         row["columns"][1]["column"] = "donated";
01745                         row["columns"][1]["value"] = donated.str();
01746 
01747                         row["columns"][2]["column"] = "online";
01748                         row["columns"][2]["value"] = mMemberProgress->second->getOnlineStatus();
01749                         row["columns"][2]["font"] = "SANSSERIFSMALL";
01750 
01751                         mMembersList->addElement(row);//, ADD_SORTED);
01752                         mHasMatch = TRUE;
01753                 }
01754         }
01755 
01756         if (mMemberProgress == end)
01757         {
01758                 if (mHasMatch)
01759                 {
01760                         mMembersList->setEnabled(TRUE);
01761                 }
01762                 else
01763                 {
01764                         mMembersList->setEnabled(FALSE);
01765                         mMembersList->addSimpleItem("No match.");
01766                 }
01767         }
01768         else
01769         {
01770                 mPendingMemberUpdate = TRUE;
01771         }
01772 
01773         // This should clear the other two lists, since nothing is selected.
01774         handleMemberSelect();
01775 }
01776 
01777 
01778 
01780 // LLPanelGroupRolesSubTab
01782 
01783 // static
01784 void* LLPanelGroupRolesSubTab::createTab(void* data)
01785 {
01786         LLUUID* group_id = static_cast<LLUUID*>(data);
01787         return new LLPanelGroupRolesSubTab("panel group roles sub tab", *group_id);
01788 }
01789 
01790 LLPanelGroupRolesSubTab::LLPanelGroupRolesSubTab(const std::string& name, const LLUUID& group_id)
01791 : LLPanelGroupSubTab(name, group_id), mHasRoleChange(FALSE)
01792 {
01793 }
01794 
01795 LLPanelGroupRolesSubTab::~LLPanelGroupRolesSubTab()
01796 {
01797 }
01798 
01799 BOOL LLPanelGroupRolesSubTab::postBuildSubTab(LLView* root)
01800 {
01801         // Upcast parent so we can ask it for sibling controls.
01802         LLPanelGroupRoles* parent = (LLPanelGroupRoles*) root;
01803 
01804         // Look recursively from the parent to find all our widgets.
01805         bool recurse = true;
01806         mHeader = (LLPanel*) parent->getChildByName("roles_header", recurse);
01807         mFooter = (LLPanel*) parent->getChildByName("roles_footer", recurse);
01808 
01809 
01810         mRolesList              = (LLScrollListCtrl*)   parent->getChildByName("role_list", recurse);
01811         mAssignedMembersList    = (LLNameListCtrl*)     parent->getChildByName("role_assigned_members", recurse);
01812         mAllowedActionsList     = (LLScrollListCtrl*)   parent->getChildByName("role_allowed_actions", recurse);
01813 
01814         mRoleName = (LLLineEditor*) parent->getChildByName("role_name", recurse);
01815         mRoleTitle = (LLLineEditor*) parent->getChildByName("role_title", recurse);
01816         mRoleDescription = (LLTextEditor*) parent->getChildByName("role_description", recurse);
01817 
01818         mMemberVisibleCheck = (LLCheckBoxCtrl*) parent->getChildByName("role_visible_in_list", recurse);
01819 
01820         if (!mRolesList || !mAssignedMembersList || !mAllowedActionsList
01821                 || !mRoleName || !mRoleTitle || !mRoleDescription || !mMemberVisibleCheck)
01822         {
01823                 llwarns << "ARG! element not found." << llendl;
01824                 return FALSE;
01825         }
01826 
01827         LLTextBox* txt = (LLTextBox*) parent->getChildByName("cant_delete_role", FALSE);
01828         if (txt)
01829         {
01830                 mRemoveEveryoneTxt = txt->getText();
01831                 parent->removeChild(txt, TRUE);
01832         }
01833 
01834         mCreateRoleButton = 
01835                 (LLButton*) parent->getChildByName("role_create", recurse);
01836         if ( mCreateRoleButton )
01837         {
01838                 mCreateRoleButton->setCallbackUserData(this);
01839                 mCreateRoleButton->setClickedCallback(onCreateRole);
01840                 mCreateRoleButton->setEnabled(FALSE);
01841         }
01842         
01843         mDeleteRoleButton =  
01844                 (LLButton*) parent->getChildByName("role_delete", recurse);
01845         if ( mDeleteRoleButton )
01846         {
01847                 mDeleteRoleButton->setCallbackUserData(this);
01848                 mDeleteRoleButton->setClickedCallback(onDeleteRole);
01849                 mDeleteRoleButton->setEnabled(FALSE);
01850         }
01851 
01852         mRolesList->setCommitOnSelectionChange(TRUE);
01853         mRolesList->setCallbackUserData(this);
01854         mRolesList->setCommitCallback(onRoleSelect);
01855 
01856         mMemberVisibleCheck->setCallbackUserData(this);
01857         mMemberVisibleCheck->setCommitCallback(onMemberVisibilityChange);
01858 
01859         mAllowedActionsList->setCommitOnSelectionChange(TRUE);
01860         mAllowedActionsList->setCallbackUserData(this);
01861 
01862         mRoleName->setCommitOnFocusLost(TRUE);
01863         mRoleName->setCallbackUserData(this);
01864         mRoleName->setKeystrokeCallback(onPropertiesKey);
01865 
01866         mRoleTitle->setCommitOnFocusLost(TRUE);
01867         mRoleTitle->setCallbackUserData(this);
01868         mRoleTitle->setKeystrokeCallback(onPropertiesKey);
01869 
01870         mRoleDescription->setCommitOnFocusLost(TRUE);
01871         mRoleDescription->setCallbackUserData(this);
01872         mRoleDescription->setCommitCallback(onDescriptionCommit);
01873         mRoleDescription->setFocusReceivedCallback(onDescriptionCommit);
01874 
01875         setFooterEnabled(FALSE);
01876 
01877         return TRUE;
01878 }
01879 
01880 void LLPanelGroupRolesSubTab::activate()
01881 {
01882         LLPanelGroupSubTab::activate();
01883 
01884         mRolesList->deselectAllItems();
01885         mAssignedMembersList->deleteAllItems();
01886         mAllowedActionsList->deleteAllItems();
01887         mRoleName->clear();
01888         mRoleDescription->clear();
01889         mRoleTitle->clear();
01890 
01891         setFooterEnabled(FALSE);
01892 
01893         mHasRoleChange = FALSE;
01894         update(GC_ALL);
01895 }
01896 
01897 void LLPanelGroupRolesSubTab::deactivate()
01898 {
01899         lldebugs << "LLPanelGroupRolesSubTab::deactivate()" << llendl;
01900 
01901         LLPanelGroupSubTab::deactivate();
01902 }
01903 
01904 bool LLPanelGroupRolesSubTab::needsApply(LLString& mesg)
01905 {
01906         lldebugs << "LLPanelGroupRolesSubTab::needsApply()" << llendl;
01907 
01908         LLGroupMgrGroupData* gdatap = gGroupMgr->getGroupData(mGroupID);
01909 
01910         return (mHasRoleChange                                                          // Text changed in current role
01911                         || (gdatap && gdatap->pendingRoleChanges()));   // Pending role changes in the group
01912 }
01913 
01914 bool LLPanelGroupRolesSubTab::apply(LLString& mesg)
01915 {
01916         lldebugs << "LLPanelGroupRolesSubTab::apply()" << llendl;
01917 
01918         saveRoleChanges();
01919         gGroupMgr->sendGroupRoleChanges(mGroupID);
01920 
01921         notifyObservers();
01922 
01923         return true;
01924 }
01925 
01926 void LLPanelGroupRolesSubTab::cancel()
01927 {
01928         mHasRoleChange = FALSE;
01929         gGroupMgr->cancelGroupRoleChanges(mGroupID);
01930 
01931         notifyObservers();
01932 }
01933 
01934 LLSD LLPanelGroupRolesSubTab::createRoleItem(const LLUUID& role_id, 
01935                                                                  std::string name, 
01936                                                                  std::string title, 
01937                                                                  S32 members)
01938 {
01939         LLSD row;
01940         row["id"] = role_id;
01941 
01942         row["columns"][0]["column"] = "name";
01943         row["columns"][0]["value"] = name;
01944 
01945         row["columns"][1]["column"] = "title";
01946         row["columns"][1]["value"] = title;
01947 
01948         row["columns"][2]["column"] = "members";
01949         row["columns"][2]["value"] = members;
01950         
01951         return row;
01952 }
01953 
01954 bool LLPanelGroupRolesSubTab::matchesSearchFilter(std::string rolename, std::string roletitle)
01955 {
01956         // If the search filter is empty, everything passes.
01957         if (mSearchFilter.empty()) return true;
01958 
01959         LLString::toLower(rolename);
01960         LLString::toLower(roletitle);
01961         std::string::size_type match_name = rolename.find(mSearchFilter);
01962         std::string::size_type match_title = roletitle.find(mSearchFilter);
01963 
01964         if ( (std::string::npos == match_name)
01965                 && (std::string::npos == match_title))
01966         {
01967                 // not found
01968                 return false;
01969         }
01970         else
01971         {
01972                 return true;
01973         }
01974 }
01975 
01976 void LLPanelGroupRolesSubTab::update(LLGroupChange gc)
01977 {
01978         lldebugs << "LLPanelGroupRolesSubTab::update()" << llendl;
01979 
01980         if (mGroupID.isNull()) return;
01981 
01982         LLGroupMgrGroupData* gdatap = gGroupMgr->getGroupData(mGroupID);
01983 
01984         if (!gdatap || !gdatap->isRoleDataComplete())
01985         {
01986                 gGroupMgr->sendGroupRoleDataRequest(mGroupID);
01987         }
01988         else
01989         {
01990                 bool had_selection = false;
01991                 LLUUID last_selected;
01992                 if (mRolesList->getFirstSelected())
01993                 {
01994                         last_selected = mRolesList->getFirstSelected()->getUUID();
01995                         had_selection = true;
01996                 }
01997                 mRolesList->deleteAllItems();
01998 
01999                 LLScrollListItem* item = NULL;
02000 
02001                 LLGroupMgrGroupData::role_iter rit = gdatap->mRoles.begin();
02002                 LLGroupMgrGroupData::role_iter end = gdatap->mRoles.end();
02003 
02004                 for ( ; rit != end; ++rit)
02005                 {
02006                         LLRoleData rd;
02007                         if (gdatap->getRoleData((*rit).first,rd))
02008                         {
02009                                 if (matchesSearchFilter(rd.mRoleName, rd.mRoleTitle))
02010                                 {
02011                                         // If this is the everyone role, then EVERYONE is in it.
02012                                         S32 members_in_role = (*rit).first.isNull() ? gdatap->mMembers.size() : (*rit).second->getTotalMembersInRole();
02013                                         LLSD row = createRoleItem((*rit).first,rd.mRoleName, rd.mRoleTitle, members_in_role);
02014                                         item = mRolesList->addElement(row, ((*rit).first.isNull()) ? ADD_TOP : ADD_BOTTOM, this);
02015                                         if (had_selection && ((*rit).first == last_selected))
02016                                         {
02017                                                 item->setSelected(TRUE);
02018                                         }
02019                                 }
02020                         }
02021                         else
02022                         {
02023                                 llwarns << "LLPanelGroupRolesSubTab::update() No role data for role " << (*rit).first << llendl;
02024                         }
02025                 }
02026 
02027                 mRolesList->sortByColumn("name", TRUE);
02028 
02029                 if ( (gdatap->mRoles.size() < (U32)MAX_ROLES)
02030                         && gAgent.hasPowerInGroup(mGroupID, GP_ROLE_CREATE) )
02031                 {
02032                         mCreateRoleButton->setEnabled(TRUE);
02033                 }
02034                 else
02035                 {
02036                         mCreateRoleButton->setEnabled(FALSE);
02037                 }
02038 
02039                 if (had_selection)
02040                 {
02041                         handleRoleSelect();
02042                 }
02043                 else
02044                 {
02045                         mAssignedMembersList->deleteAllItems();
02046                         mAllowedActionsList->deleteAllItems();
02047                         mRoleName->clear();
02048                         mRoleDescription->clear();
02049                         mRoleTitle->clear();
02050                         setFooterEnabled(FALSE);
02051                         mDeleteRoleButton->setEnabled(FALSE);
02052                 }
02053         }
02054 
02055         if (!gdatap || !gdatap->isMemberDataComplete())
02056         {
02057                 gGroupMgr->sendGroupMembersRequest(mGroupID);
02058         }
02059         
02060         if (!gdatap || !gdatap->isRoleMemberDataComplete())
02061         {
02062                 gGroupMgr->sendGroupRoleMembersRequest(mGroupID);
02063         }
02064 
02065         if ((GC_ROLE_MEMBER_DATA == gc || GC_MEMBER_DATA == gc)
02066             && gdatap
02067             && gdatap->isMemberDataComplete()
02068             && gdatap->isRoleMemberDataComplete())
02069         {
02070                 buildMembersList();
02071         }
02072 }
02073 
02074 // static
02075 void LLPanelGroupRolesSubTab::onRoleSelect(LLUICtrl* ctrl, void* user_data)
02076 {
02077         LLPanelGroupRolesSubTab* self = static_cast<LLPanelGroupRolesSubTab*>(user_data);
02078         self->handleRoleSelect();
02079 }
02080 
02081 void LLPanelGroupRolesSubTab::handleRoleSelect()
02082 {
02083         BOOL can_delete = TRUE;
02084         lldebugs << "LLPanelGroupRolesSubTab::handleRoleSelect()" << llendl;
02085 
02086         mAssignedMembersList->deleteAllItems();
02087         mAllowedActionsList->deleteAllItems();
02088         
02089         LLGroupMgrGroupData* gdatap = gGroupMgr->getGroupData(mGroupID);
02090         if (!gdatap) 
02091         {
02092                 llwarns << "LLPanelGroupRolesSubTab::handleRoleSelect() "
02093                                 << "-- No group data!" << llendl;
02094                 return;
02095         }
02096 
02097         saveRoleChanges();
02098 
02099         // Check if there is anything selected.
02100         LLScrollListItem* item = mRolesList->getFirstSelected();
02101         if (!item)
02102         {
02103                 setFooterEnabled(FALSE);
02104                 return;
02105         }
02106 
02107         setFooterEnabled(TRUE);
02108 
02109         LLRoleData rd;
02110         if (gdatap->getRoleData(item->getUUID(),rd))
02111         {
02112                 BOOL is_owner_role = ( gdatap->mOwnerRole == item->getUUID() );
02113                 mRoleName->setText(rd.mRoleName);
02114                 mRoleTitle->setText(rd.mRoleTitle);
02115                 mRoleDescription->setText(rd.mRoleDescription);
02116 
02117                 mAllowedActionsList->setEnabled(gAgent.hasPowerInGroup(mGroupID,
02118                                                                            GP_ROLE_CHANGE_ACTIONS));
02119                 buildActionsList(mAllowedActionsList,
02120                                                  rd.mRolePowers,
02121                                                  0LL,
02122                                                  mActionIcons,
02123                                                  onActionCheck,
02124                                                  TRUE,
02125                                                  FALSE,
02126                                                  is_owner_role);
02127 
02128 
02129                 mMemberVisibleCheck->set((rd.mRolePowers & GP_MEMBER_VISIBLE_IN_DIR) == GP_MEMBER_VISIBLE_IN_DIR);
02130                 mRoleName->setEnabled(!is_owner_role &&
02131                                 gAgent.hasPowerInGroup(mGroupID, GP_ROLE_PROPERTIES));
02132                 mRoleTitle->setEnabled(gAgent.hasPowerInGroup(mGroupID, GP_ROLE_PROPERTIES));
02133                 mRoleDescription->setEnabled(gAgent.hasPowerInGroup(mGroupID, GP_ROLE_PROPERTIES));
02134                 mMemberVisibleCheck->setEnabled(gAgent.hasPowerInGroup(mGroupID, GP_ROLE_PROPERTIES));
02135 
02136                 if (item->getUUID().isNull())
02137                 {
02138                         // Everyone role, can't edit description or name or delete
02139                         mRoleDescription->setEnabled(FALSE);
02140                         mRoleName->setEnabled(FALSE);
02141                         can_delete = FALSE;
02142                 }
02143                 //you can't delete the owner role
02144                 if ( is_owner_role ) can_delete = FALSE;
02145         }
02146         else
02147         {
02148                 mRolesList->deselectAllItems();
02149                 mAssignedMembersList->deleteAllItems();
02150                 mAllowedActionsList->deleteAllItems();
02151                 mRoleName->clear();
02152                 mRoleDescription->clear();
02153                 mRoleTitle->clear();
02154                 setFooterEnabled(FALSE);
02155 
02156                 can_delete = FALSE;
02157         }
02158         mSelectedRole = item->getUUID();
02159         buildMembersList();
02160 
02161         can_delete = can_delete && gAgent.hasPowerInGroup(mGroupID,
02162                                                                                                           GP_ROLE_DELETE);
02163         mDeleteRoleButton->setEnabled(can_delete);
02164 }
02165 
02166 void LLPanelGroupRolesSubTab::buildMembersList()
02167 {
02168         mAssignedMembersList->deleteAllItems();
02169 
02170         LLGroupMgrGroupData* gdatap = gGroupMgr->getGroupData(mGroupID);
02171         if (!gdatap) 
02172         {
02173                 llwarns << "LLPanelGroupRolesSubTab::handleRoleSelect() "
02174                                 << "-- No group data!" << llendl;
02175                 return;
02176         }
02177 
02178         // Check if there is anything selected.
02179         LLScrollListItem* item = mRolesList->getFirstSelected();
02180         if (!item) return;
02181 
02182         if (item->getUUID().isNull())
02183         {
02184                 // Special cased 'Everyone' role
02185                 LLGroupMgrGroupData::member_iter mit = gdatap->mMembers.begin();
02186                 LLGroupMgrGroupData::member_iter end = gdatap->mMembers.end();
02187                 for ( ; mit != end; ++mit)
02188                 {
02189                         mAssignedMembersList->addNameItem((*mit).first);
02190                 }
02191         }
02192         else
02193         {
02194                 LLGroupMgrGroupData::role_iter rit = gdatap->mRoles.find(item->getUUID());
02195                 if (rit != gdatap->mRoles.end())
02196                 {
02197                         LLGroupRoleData* rdatap = (*rit).second;
02198                         if (rdatap)
02199                         {
02200                                 std::vector<LLUUID>::const_iterator mit = rdatap->getMembersBegin();
02201                                 std::vector<LLUUID>::const_iterator end = rdatap->getMembersEnd();
02202                                 for ( ; mit != end; ++mit)
02203                                 {
02204                                         mAssignedMembersList->addNameItem((*mit));
02205                                 }
02206                         }
02207                 }
02208         }
02209 }
02210 
02211 // static
02212 void LLPanelGroupRolesSubTab::onActionCheck(LLUICtrl* ctrl, void* user_data)
02213 {
02214         LLPanelGroupRolesSubTab* self = static_cast<LLPanelGroupRolesSubTab*>(user_data);
02215         LLCheckBoxCtrl* check = static_cast<LLCheckBoxCtrl*>(ctrl);
02216         if (!check || !self) return;
02217 
02218         self->handleActionCheck(check);
02219 }
02220 
02221 struct ActionCBData
02222 {
02223         LLPanelGroupRolesSubTab*        mSelf;
02224         LLCheckBoxCtrl*                         mCheck;
02225 };
02226 
02227 void LLPanelGroupRolesSubTab::handleActionCheck(LLCheckBoxCtrl* check, bool force)
02228 {
02229         lldebugs << "LLPanelGroupRolesSubTab::handleActionSelect()" << llendl;
02230 
02231         LLGroupMgrGroupData* gdatap = gGroupMgr->getGroupData(mGroupID);
02232         if (!gdatap) 
02233         {
02234                 llwarns << "LLPanelGroupRolesSubTab::handleRoleSelect() "
02235                                 << "-- No group data!" << llendl;
02236                 return;
02237         }
02238 
02239         LLScrollListItem* action_item = mAllowedActionsList->getFirstSelected();
02240         if (!action_item)
02241         {
02242                 return;
02243         }
02244 
02245         LLScrollListItem* role_item = mRolesList->getFirstSelected();
02246         if (!role_item)
02247         {
02248                 return;
02249         }
02250         LLUUID role_id = role_item->getUUID();
02251 
02252         LLRoleAction* rap = (LLRoleAction*)action_item->getUserdata();
02253         U64 power = rap->mPowerBit;
02254 
02255         if (check->get())
02256         {
02257                 if (!force && (    (GP_ROLE_ASSIGN_MEMBER == power)
02258                                                 || (GP_ROLE_CHANGE_ACTIONS == power) ))
02259                 {
02260                         // Uncheck the item, for now.  It will be
02261                         // checked if they click 'Yes', below.
02262                         check->set(FALSE);
02263 
02264                         LLRoleData rd;
02265                         LLStringBase<char>::format_map_t args;
02266 
02267                         if ( gdatap->getRoleData(role_id, rd) )
02268                         {
02269                                 args["[ACTION_NAME]"] = rap->mDescription;
02270                                 args["[ROLE_NAME]"] = rd.mRoleName;
02271                                 struct ActionCBData* cb_data = new ActionCBData;
02272                                 cb_data->mSelf = this;
02273                                 cb_data->mCheck = check;
02274                                 mHasModal = TRUE;
02275                                 LLString warning = "AssignDangerousActionWarning";
02276                                 if (GP_ROLE_CHANGE_ACTIONS == power)
02277                                 {
02278                                         warning = "AssignDangerousAbilityWarning";
02279                                 }
02280                                 gViewerWindow->alertXml(warning, args, addActionCB, cb_data);
02281                         }
02282                         else
02283                         {
02284                                 llwarns << "Unable to look up role information for role id: "
02285                                                 << role_id << llendl;
02286                         }
02287                 }
02288                 else
02289                 {
02290                         gdatap->addRolePower(role_id,power);
02291                 }
02292         }
02293         else
02294         {
02295                 gdatap->removeRolePower(role_id,power);
02296         }
02297 
02298         mHasRoleChange = TRUE;
02299         notifyObservers();
02300 }
02301 
02302 //static
02303 void LLPanelGroupRolesSubTab::addActionCB(S32 option, void* data)
02304 {
02305         struct ActionCBData* cb_data = (struct ActionCBData*) data;
02306 
02307         if (!cb_data || !cb_data->mSelf || !cb_data->mCheck) return;
02308 
02309         cb_data->mSelf->mHasModal = FALSE;
02310 
02311         if (0 == option)
02312         {
02313                 // User clicked "Yes"
02314                 cb_data->mCheck->set(TRUE);
02315                 const bool force_add = true;
02316                 cb_data->mSelf->handleActionCheck(cb_data->mCheck, force_add);
02317         }
02318 }
02319 
02320 
02321 // static
02322 void LLPanelGroupRolesSubTab::onPropertiesKey(LLLineEditor* ctrl, void* user_data)
02323 {
02324         LLPanelGroupRolesSubTab* self = static_cast<LLPanelGroupRolesSubTab*>(user_data);
02325         if (!self) return;
02326 
02327         self->mHasRoleChange = TRUE;
02328         self->notifyObservers();
02329 }
02330 
02331 // static 
02332 void LLPanelGroupRolesSubTab::onDescriptionCommit(LLUICtrl* ctrl, void* user_data)
02333 {
02334         LLPanelGroupRolesSubTab* self = static_cast<LLPanelGroupRolesSubTab*>(user_data);
02335         if (!self) return;
02336 
02337         self->mHasRoleChange = TRUE;
02338         self->notifyObservers();
02339 }
02340 
02341 // static 
02342 void LLPanelGroupRolesSubTab::onMemberVisibilityChange(LLUICtrl* ctrl, void* user_data)
02343 {
02344         LLPanelGroupRolesSubTab* self = static_cast<LLPanelGroupRolesSubTab*>(user_data);
02345         LLCheckBoxCtrl* check = static_cast<LLCheckBoxCtrl*>(ctrl);
02346         if (!check || !self) return;
02347 
02348         self->handleMemberVisibilityChange(check->get());
02349 }
02350 
02351 void LLPanelGroupRolesSubTab::handleMemberVisibilityChange(bool value)
02352 {
02353         lldebugs << "LLPanelGroupRolesSubTab::handleMemberVisibilityChange()" << llendl;
02354 
02355         LLGroupMgrGroupData* gdatap = gGroupMgr->getGroupData(mGroupID);
02356         if (!gdatap) 
02357         {
02358                 llwarns << "LLPanelGroupRolesSubTab::handleRoleSelect() "
02359                                 << "-- No group data!" << llendl;
02360                 return;
02361         }
02362 
02363         LLScrollListItem* role_item = mRolesList->getFirstSelected();
02364         if (!role_item)
02365         {
02366                 return;
02367         }
02368 
02369         if (value)
02370         {
02371                 gdatap->addRolePower(role_item->getUUID(),GP_MEMBER_VISIBLE_IN_DIR);
02372         }
02373         else
02374         {
02375                 gdatap->removeRolePower(role_item->getUUID(),GP_MEMBER_VISIBLE_IN_DIR);
02376         }
02377 }
02378 
02379 // static 
02380 void LLPanelGroupRolesSubTab::onCreateRole(void* user_data)
02381 {
02382         LLPanelGroupRolesSubTab* self = static_cast<LLPanelGroupRolesSubTab*>(user_data);
02383         if (!self) return;
02384 
02385         self->handleCreateRole();
02386 }
02387 
02388 void LLPanelGroupRolesSubTab::handleCreateRole()
02389 {
02390         LLGroupMgrGroupData* gdatap = gGroupMgr->getGroupData(mGroupID);
02391 
02392         if (!gdatap) return;
02393 
02394         LLUUID new_role_id;
02395         new_role_id.generate();
02396 
02397         LLRoleData rd;
02398         rd.mRoleName = "New Role";
02399         gdatap->createRole(new_role_id,rd);
02400 
02401         mRolesList->deselectAllItems(TRUE);
02402         LLSD row;
02403         row["id"] = new_role_id;
02404         row["columns"][0]["column"] = "name";
02405         row["columns"][0]["value"] = rd.mRoleName;
02406         mRolesList->addElement(row, ADD_BOTTOM, this);
02407         mRolesList->selectByID(new_role_id);
02408 
02409         // put focus on name field and select its contents
02410         if(mRoleName)
02411         {
02412                 mRoleName->setFocus(TRUE);
02413                 mRoleName->onTabInto();
02414                 gFocusMgr.triggerFocusFlash();
02415         }
02416 
02417         notifyObservers();
02418 }
02419 
02420 // static 
02421 void LLPanelGroupRolesSubTab::onDeleteRole(void* user_data)
02422 {
02423         LLPanelGroupRolesSubTab* self = static_cast<LLPanelGroupRolesSubTab*>(user_data);
02424         if (!self) return;
02425 
02426         self->handleDeleteRole();
02427 }
02428 
02429 void LLPanelGroupRolesSubTab::handleDeleteRole()
02430 {
02431         LLGroupMgrGroupData* gdatap = gGroupMgr->getGroupData(mGroupID);
02432 
02433         if (!gdatap) return;
02434 
02435         LLScrollListItem* role_item = mRolesList->getFirstSelected();
02436         if (!role_item)
02437         {
02438                 return;
02439         }
02440 
02441         if (role_item->getUUID().isNull() || role_item->getUUID() == gdatap->mOwnerRole)
02442         {
02443                 LLString::format_map_t args;
02444                 args["[MESSAGE]"] = mRemoveEveryoneTxt;
02445                 LLNotifyBox::showXml("GenericNotify", args);
02446                 return;
02447         }
02448 
02449         gdatap->deleteRole(role_item->getUUID());
02450         mRolesList->deleteSingleItem(mRolesList->getFirstSelectedIndex());
02451         mRolesList->selectFirstItem();
02452 
02453         notifyObservers();
02454 }
02455 
02456 void LLPanelGroupRolesSubTab::saveRoleChanges()
02457 {
02458         LLGroupMgrGroupData* gdatap = gGroupMgr->getGroupData(mGroupID);
02459 
02460         if (!gdatap) return;
02461 
02462         if (mHasRoleChange)
02463         {
02464                 LLRoleData rd;
02465                 if (!gdatap->getRoleData(mSelectedRole,rd)) return;
02466 
02467                 rd.mRoleName = mRoleName->getText();
02468                 rd.mRoleDescription = mRoleDescription->getText();
02469                 rd.mRoleTitle = mRoleTitle->getText();
02470 
02471                 gdatap->setRoleData(mSelectedRole,rd);
02472 
02473                 mRolesList->deleteSingleItem(mRolesList->getItemIndex(mSelectedRole));
02474                 
02475                 LLSD row = createRoleItem(mSelectedRole,rd.mRoleName,rd.mRoleTitle,0);
02476                 LLScrollListItem* item = mRolesList->addElement(row, ADD_BOTTOM, this);
02477                 item->setSelected(TRUE);
02478 
02479                 mHasRoleChange = FALSE;
02480         }
02481 }
02483 // LLPanelGroupActionsSubTab
02485 
02486 // static
02487 void* LLPanelGroupActionsSubTab::createTab(void* data)
02488 {
02489         LLUUID* group_id = static_cast<LLUUID*>(data);
02490         return new LLPanelGroupActionsSubTab("panel group actions sub tab", *group_id);
02491 }
02492 
02493 LLPanelGroupActionsSubTab::LLPanelGroupActionsSubTab(const std::string& name, const LLUUID& group_id)
02494 : LLPanelGroupSubTab(name, group_id)
02495 {
02496 }
02497 
02498 LLPanelGroupActionsSubTab::~LLPanelGroupActionsSubTab()
02499 {
02500 }
02501 
02502 BOOL LLPanelGroupActionsSubTab::postBuildSubTab(LLView* root)
02503 {
02504         // Upcast parent so we can ask it for sibling controls.
02505         LLPanelGroupRoles* parent = (LLPanelGroupRoles*) root;
02506 
02507         // Look recursively from the parent to find all our widgets.
02508         bool recurse = true;
02509         mHeader = (LLPanel*) parent->getChildByName("actions_header", recurse);
02510         mFooter = (LLPanel*) parent->getChildByName("actions_footer", recurse);
02511 
02512         mActionDescription = (LLTextEditor*) parent->getChildByName("action_description", recurse);
02513 
02514         mActionList = (LLScrollListCtrl*) parent->getChildByName("action_list",recurse);
02515         mActionRoles = (LLScrollListCtrl*) parent->getChildByName("action_roles",recurse);
02516         mActionMembers  = (LLNameListCtrl*) parent->getChildByName("action_members",recurse);
02517 
02518         if (!mActionList || !mActionDescription || !mActionRoles || !mActionMembers) return FALSE;
02519 
02520         mActionList->setCallbackUserData(this);
02521         mActionList->setCommitOnSelectionChange(TRUE);
02522         mActionList->setCommitCallback(onActionSelect);
02523 
02524         mActionMembers->setCallbackUserData(this);
02525         mActionRoles->setCallbackUserData(this);
02526 
02527         update(GC_ALL);
02528 
02529         return TRUE;
02530 }
02531 
02532 void LLPanelGroupActionsSubTab::activate()
02533 {
02534         LLPanelGroupSubTab::activate();
02535         lldebugs << "LLPanelGroupActionsSubTab::activate()" << llendl;
02536 
02537         mActionList->deselectAllItems();
02538         mActionMembers->deleteAllItems();
02539         mActionRoles->deleteAllItems();
02540         mActionDescription->clear();
02541 }
02542 
02543 void LLPanelGroupActionsSubTab::deactivate()
02544 {
02545         lldebugs << "LLPanelGroupActionsSubTab::deactivate()" << llendl;
02546 
02547         LLPanelGroupSubTab::deactivate();
02548 }
02549 
02550 bool LLPanelGroupActionsSubTab::needsApply(LLString& mesg)
02551 {
02552         lldebugs << "LLPanelGroupActionsSubTab::needsApply()" << llendl;
02553 
02554         return false;
02555 }
02556 
02557 bool LLPanelGroupActionsSubTab::apply(LLString& mesg)
02558 {
02559         lldebugs << "LLPanelGroupActionsSubTab::apply()" << llendl;
02560         return true;
02561 }
02562 
02563 void LLPanelGroupActionsSubTab::update(LLGroupChange gc)
02564 {
02565         lldebugs << "LLPanelGroupActionsSubTab::update()" << llendl;
02566 
02567         if (mGroupID.isNull()) return;
02568 
02569         mActionList->deselectAllItems();
02570         mActionMembers->deleteAllItems();
02571         mActionRoles->deleteAllItems();
02572         mActionDescription->clear();
02573 
02574         mActionList->deleteAllItems();
02575         buildActionsList(mActionList,
02576                                          GP_ALL_POWERS,
02577                                          GP_ALL_POWERS,
02578                                          mActionIcons,
02579                                          NULL,
02580                                          FALSE,
02581                                          TRUE,
02582                                          FALSE);
02583 }
02584 
02585 // static 
02586 void LLPanelGroupActionsSubTab::onActionSelect(LLUICtrl* scroll, void* data)
02587 {
02588         LLPanelGroupActionsSubTab* self = static_cast<LLPanelGroupActionsSubTab*>(data);
02589         self->handleActionSelect();
02590 }
02591 
02592 void LLPanelGroupActionsSubTab::handleActionSelect()
02593 {
02594         mActionMembers->deleteAllItems();
02595         mActionRoles->deleteAllItems();
02596 
02597         U64 power_mask = GP_NO_POWERS;
02598         std::vector<LLScrollListItem*> selection = 
02599                                                         mActionList->getAllSelected();
02600         if (selection.empty()) return;
02601 
02602         LLRoleAction* rap;
02603 
02604         std::vector<LLScrollListItem*>::iterator itor;
02605         for (itor = selection.begin() ; 
02606                  itor != selection.end(); ++itor)
02607         {
02608                 rap = (LLRoleAction*)( (*itor)->getUserdata() );
02609                 power_mask |= rap->mPowerBit;
02610         }
02611 
02612         if (selection.size() == 1)
02613         {
02614                 LLScrollListItem* item = selection[0];
02615                 rap = (LLRoleAction*)(item->getUserdata());
02616 
02617                 if (rap->mLongDescription.empty())
02618                 {
02619                         mActionDescription->setText(rap->mDescription);
02620                 }
02621                 else
02622                 {
02623                         mActionDescription->setText(rap->mLongDescription);
02624                 }
02625         }
02626         else
02627         {
02628                 mActionDescription->clear();
02629         }
02630 
02631         LLGroupMgrGroupData* gdatap = gGroupMgr->getGroupData(mGroupID);
02632 
02633         if (!gdatap) return;
02634 
02635         if (gdatap->isMemberDataComplete())
02636         {
02637                 LLGroupMgrGroupData::member_iter it = gdatap->mMembers.begin();
02638                 LLGroupMgrGroupData::member_iter end = gdatap->mMembers.end();
02639                 LLGroupMemberData* gmd;
02640 
02641                 for ( ; it != end; ++it)
02642                 {
02643                         gmd = (*it).second;
02644                         if (!gmd) continue;
02645                         if ((gmd->getAgentPowers() & power_mask) == power_mask)
02646                         {
02647                                 mActionMembers->addNameItem(gmd->getID());
02648                         }
02649                 }
02650         }
02651         else
02652         {
02653                 gGroupMgr->sendGroupMembersRequest(mGroupID);
02654         }
02655 
02656         if (gdatap->isRoleDataComplete())
02657         {
02658                 LLGroupMgrGroupData::role_iter it = gdatap->mRoles.begin();
02659                 LLGroupMgrGroupData::role_iter end = gdatap->mRoles.end();
02660                 LLGroupRoleData* rmd;
02661 
02662                 for ( ; it != end; ++it)
02663                 {
02664                         rmd = (*it).second;
02665                         if (!rmd) continue;
02666                         if ((rmd->getRoleData().mRolePowers & power_mask) == power_mask)
02667                         {
02668                                 mActionRoles->addSimpleItem(rmd->getRoleData().mRoleName);
02669                         }
02670                 }
02671         }
02672         else
02673         {
02674                 gGroupMgr->sendGroupRoleDataRequest(mGroupID);
02675         }
02676 }

Generated on Thu Jul 1 06:08:58 2010 for Second Life Viewer by  doxygen 1.4.7