merging in latest changes

master
Gilbert Gonzales 2012-11-15 15:45:02 -08:00
commit e775e95416
28 changed files with 194 additions and 38 deletions

View File

@ -351,3 +351,5 @@ b61afe175b829c149d369524a4e974dfda99facf DRTVWR-219
e664473c16df1d82ffaff382e7b3e023da202d52 3.4.2-beta2
0891d7a773a31397dcad48be3fa66531d567a821 DRTVWR-242
710785535362b3cb801b6a3dc4703be3373bd0cd 3.4.2-beta3
e9a5886052433d5db9e504ffaca10890f9932979 DRTVWR-243
73b84b9864dc650fe7c8fc9f52361450f0849004 3.4.2-beta4

View File

@ -2247,7 +2247,8 @@ LLFloaterView::LLFloaterView (const Params& p)
mFocusCycleMode(FALSE),
mMinimizePositionVOffset(0),
mSnapOffsetBottom(0),
mSnapOffsetRight(0)
mSnapOffsetRight(0),
mFrontChild(NULL)
{
mSnapView = getHandle();
}
@ -2396,6 +2397,13 @@ LLRect LLFloaterView::findNeighboringPosition( LLFloater* reference_floater, LLF
void LLFloaterView::bringToFront(LLFloater* child, BOOL give_focus)
{
if (mFrontChild == child)
{
return;
}
mFrontChild = child;
// *TODO: make this respect floater's mAutoFocus value, instead of
// using parameter
if (child->getHost())

View File

@ -576,6 +576,7 @@ private:
S32 mMinimizePositionVOffset;
typedef std::vector<std::pair<LLHandle<LLFloater>, boost::signals2::connection> > hidden_floaters_t;
hidden_floaters_t mHiddenFloaters;
LLFloater * mFrontChild;
};
//

View File

@ -118,6 +118,7 @@ protected:
// For now assuming all colors are the same in derived classes.
static LLUIColor sFgColor;
static LLUIColor sFgDisabledColor;
static LLUIColor sHighlightBgColor;
static LLUIColor sHighlightFgColor;
static LLUIColor sFocusOutlineColor;

View File

@ -873,7 +873,7 @@ class LLIMWellChiclet : public LLSysWellChiclet, LLIMSessionObserver
{
friend class LLUICtrlFactory;
public:
/*virtual*/ void sessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id) {}
/*virtual*/ void sessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id, BOOL has_offline_msg) {}
/*virtual*/ void sessionActivated(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id) {}
/*virtual*/ void sessionVoiceOrIMStarted(const LLUUID& session_id) {};
/*virtual*/ void sessionRemoved(const LLUUID& session_id) { messageCountChanged(LLSD()); }

View File

@ -84,7 +84,7 @@ LLIMChiclet* LLChicletBar::createIMChiclet(const LLUUID& session_id)
}
//virtual
void LLChicletBar::sessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id)
void LLChicletBar::sessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id, BOOL has_offline_msg)
{
if (!getChicletPanel()) return;

View File

@ -50,7 +50,7 @@ public:
LLChicletPanel* getChicletPanel() { return mChicletPanel; }
// LLIMSessionObserver observe triggers
/*virtual*/ void sessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id);
/*virtual*/ void sessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id, BOOL has_offline_msg);
/*virtual*/ void sessionActivated(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id) {};
/*virtual*/ void sessionVoiceOrIMStarted(const LLUUID& session_id) {};
/*virtual*/ void sessionRemoved(const LLUUID& session_id);

View File

@ -223,13 +223,17 @@ void LLConversationLog::enableLogging(bool enable)
notifyObservers();
}
void LLConversationLog::logConversation(const LLUUID& session_id)
void LLConversationLog::logConversation(const LLUUID& session_id, BOOL has_offline_msg)
{
const LLIMModel::LLIMSession* session = LLIMModel::instance().findIMSession(session_id);
LLConversation* conversation = findConversation(session);
if (session && conversation)
{
if(has_offline_msg)
{
updateOfflineIMs(session, has_offline_msg);
}
updateConversationTimestamp(conversation);
}
else if (session && !conversation)
@ -265,7 +269,22 @@ void LLConversationLog::updateConversationName(const LLIMModel::LLIMSession* ses
if (conversation)
{
conversation->setConverstionName(name);
notifyPrticularConversationObservers(conversation->getSessionID(), LLConversationLogObserver::CHANGED_NAME);
notifyParticularConversationObservers(conversation->getSessionID(), LLConversationLogObserver::CHANGED_NAME);
}
}
void LLConversationLog::updateOfflineIMs(const LLIMModel::LLIMSession* session, BOOL new_messages)
{
if (!session)
{
return;
}
LLConversation* conversation = findConversation(session);
if (conversation)
{
conversation->setOfflineMessages(new_messages);
notifyParticularConversationObservers(conversation->getSessionID(), LLConversationLogObserver::CHANGED_OfflineIMs);
}
}
@ -274,7 +293,7 @@ void LLConversationLog::updateConversationTimestamp(LLConversation* conversation
if (conversation)
{
conversation->updateTimestamp();
notifyPrticularConversationObservers(conversation->getSessionID(), LLConversationLogObserver::CHANGED_TIME);
notifyParticularConversationObservers(conversation->getSessionID(), LLConversationLogObserver::CHANGED_TIME);
}
}
@ -337,9 +356,9 @@ void LLConversationLog::removeObserver(LLConversationLogObserver* observer)
mObservers.erase(observer);
}
void LLConversationLog::sessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id)
void LLConversationLog::sessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id, BOOL has_offline_msg)
{
logConversation(session_id);
logConversation(session_id, has_offline_msg);
}
void LLConversationLog::cache()
@ -477,7 +496,7 @@ void LLConversationLog::notifyObservers()
}
}
void LLConversationLog::notifyPrticularConversationObservers(const LLUUID& session_id, U32 mask)
void LLConversationLog::notifyParticularConversationObservers(const LLUUID& session_id, U32 mask)
{
std::set<LLConversationLogObserver*>::const_iterator iter = mObservers.begin();
for (; iter != mObservers.end(); ++iter)
@ -489,7 +508,7 @@ void LLConversationLog::notifyPrticularConversationObservers(const LLUUID& sessi
void LLConversationLog::onNewMessageReceived(const LLSD& data)
{
const LLUUID session_id = data["session_id"].asUUID();
logConversation(session_id);
logConversation(session_id, false);
}
void LLConversationLog::onAvatarNameCache(const LLUUID& participant_id, const LLAvatarName& av_name, const LLIMModel::LLIMSession* session)

View File

@ -59,7 +59,7 @@ public:
bool hasOfflineMessages() const { return mHasOfflineIMs; }
void setConverstionName(std::string conv_name) { mConversationName = conv_name; }
void setOfflineMessages(bool new_messages) { mHasOfflineIMs = new_messages; }
bool isOlderThan(U32 days) const;
/*
@ -123,7 +123,7 @@ public:
void removeObserver(LLConversationLogObserver* observer);
// LLIMSessionObserver triggers
virtual void sessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id);
virtual void sessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id, BOOL has_offline_msg);
virtual void sessionActivated(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id) {}; // Stub
virtual void sessionRemoved(const LLUUID& session_id){} // Stub
virtual void sessionVoiceOrIMStarted(const LLUUID& session_id){}; // Stub
@ -147,9 +147,9 @@ private:
/**
* adds conversation to the conversation list and notifies observers
*/
void logConversation(const LLUUID& session_id);
void logConversation(const LLUUID& session_id, BOOL has_offline_msg);
void notifyPrticularConversationObservers(const LLUUID& session_id, U32 mask);
void notifyParticularConversationObservers(const LLUUID& session_id, U32 mask);
/**
* constructs file name in which conversations log will be saved
@ -165,6 +165,7 @@ private:
void createConversation(const LLIMModel::LLIMSession* session);
void updateConversationTimestamp(LLConversation* conversation);
void updateConversationName(const LLIMModel::LLIMSession* session, const std::string& name);
void updateOfflineIMs(const LLIMModel::LLIMSession* session, BOOL new_messages);
LLConversation* findConversation(const LLIMModel::LLIMSession* session);
@ -184,7 +185,8 @@ public:
enum EConversationChange
{
CHANGED_TIME = 1, // last interaction time changed
CHANGED_NAME = 2 // conversation name changed
CHANGED_NAME = 2, // conversation name changed
CHANGED_OfflineIMs = 3
};
virtual ~LLConversationLogObserver(){}

View File

@ -171,6 +171,10 @@ void LLConversationLogList::changed(const LLUUID& session_id, U32 mask)
mIsDirty = true;
}
}
else if (mask & LLConversationLogObserver::CHANGED_OfflineIMs)
{
item->updateOfflineIMs();
}
}
void LLConversationLogList::addNewItem(const LLConversation* conversation)

View File

@ -119,6 +119,11 @@ void LLConversationLogListItem::updateName()
mConversationName->setValue(mConversation->getConversationName());
}
void LLConversationLogListItem::updateOfflineIMs()
{
getChild<LLIconCtrl>("unread_ims_icon")->setVisible(mConversation->hasOfflineMessages());
}
void LLConversationLogListItem::onMouseEnter(S32 x, S32 y, MASK mask)
{
getChildView("hovered_icon")->setVisible(true);

View File

@ -69,6 +69,7 @@ public:
*/
void updateTimestamp();
void updateName();
void updateOfflineIMs();
private:

View File

@ -409,6 +409,7 @@ BOOL LLConversationViewParticipant::postBuild()
void LLConversationViewParticipant::draw()
{
static LLUIColor sFgColor = LLUIColorTable::instance().getColor("MenuItemEnabledColor", DEFAULT_WHITE);
static LLUIColor sFgDisabledColor = LLUIColorTable::instance().getColor("MenuItemDisabledColor", DEFAULT_WHITE);
static LLUIColor sHighlightFgColor = LLUIColorTable::instance().getColor("MenuItemHighlightFgColor", DEFAULT_WHITE);
static LLUIColor sHighlightBgColor = LLUIColorTable::instance().getColor("MenuItemHighlightBgColor", DEFAULT_WHITE);
static LLUIColor sFocusOutlineColor = LLUIColorTable::instance().getColor("InventoryFocusOutlineColor", DEFAULT_WHITE);
@ -421,7 +422,18 @@ void LLConversationViewParticipant::draw()
F32 y = (F32)getRect().getHeight() - font->getLineHeight() - (F32)mTextPad;
F32 text_left = (F32)getLabelXPos();
LLColor4 color = mIsSelected ? sHighlightFgColor : sFgColor;
LLColor4 color;
LLLocalSpeakerMgr *speakerMgr = LLLocalSpeakerMgr::getInstance();
if (speakerMgr && speakerMgr->isSpeakerToBeRemoved(mUUID))
{
color = sFgDisabledColor;
}
else
{
color = mIsSelected ? sHighlightFgColor : sFgColor;
}
drawHighlight(show_context, mIsSelected, sHighlightBgColor, sFocusOutlineColor, sMouseOverColor);
drawLabel(font, text_left, y, color, right_x);

View File

@ -96,6 +96,18 @@ LLVolumeImplFlexible::~LLVolumeImplFlexible()
//static
void LLVolumeImplFlexible::updateClass()
{
// XXX stinson 11/13/2012 : This hack removes the optimization for limiting the number of flexi-prims
// updated. With the optimization, flexi-prims attached to the users avatar were not being
// animated correctly immediately following teleport. With the optimization removed, the bug went away.
#define XXX_STINSON_MAINT_1890_HACK_FIX 1
#if XXX_STINSON_MAINT_1890_HACK_FIX
for (std::vector<LLVolumeImplFlexible*>::iterator iter = sInstanceList.begin();
iter != sInstanceList.end();
++iter)
{
(*iter)->doIdleUpdate();
}
#else // XXX_STINSON_MAINT_1890_HACK_FIX
std::vector<S32>::iterator delay_iter = sUpdateDelay.begin();
for (std::vector<LLVolumeImplFlexible*>::iterator iter = sInstanceList.begin();
@ -109,6 +121,7 @@ void LLVolumeImplFlexible::updateClass()
}
++delay_iter;
}
#endif // XXX_STINSON_MAINT_1890_HACK_FIX
}
LLVector3 LLVolumeImplFlexible::getFramePosition() const
@ -430,6 +443,15 @@ void LLVolumeImplFlexible::doFlexibleUpdate()
//the object is not visible
return ;
}
// stinson 11/12/2012: Need to check with davep on the following.
// Skipping the flexible update if render res is negative. If we were to continue with a negative value,
// the subsequent S32 num_render_sections = 1<<mRenderRes; code will specify a really large number of
// render sections which will then create a length exception in the std::vector::resize() method.
if (mRenderRes < 0)
{
return;
}
S32 num_sections = 1 << mSimulateRes;

View File

@ -96,7 +96,7 @@ LLFloaterIMContainer::~LLFloaterIMContainer()
}
}
void LLFloaterIMContainer::sessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id)
void LLFloaterIMContainer::sessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id, BOOL has_offline_msg)
{
addConversationListItem(session_id);
LLFloaterIMSessionTab::addToHost(session_id);
@ -717,15 +717,18 @@ void LLFloaterIMContainer::onCustomAction(const LLSD& userdata)
}
if ("chat_preferences" == command)
{
LLFloaterPreference* floater_prefs = LLFloaterReg::showTypedInstance<LLFloaterPreference>("preferences");
if (floater_prefs)
LLFloaterPreference * floater_prefp = LLFloaterReg::showTypedInstance<LLFloaterPreference>("preferences");
if (floater_prefp)
{
LLTabContainer* tab_container = floater_prefs->getChild<LLTabContainer>("pref core");
LLPanel* chat_panel = tab_container->getPanelByName("chat");
if (tab_container && chat_panel)
{
tab_container->selectTabPanel(chat_panel);
}
floater_prefp->selectChatPanel();
}
}
if ("privacy_preferences" == command)
{
LLFloaterPreference * floater_prefp = LLFloaterReg::showTypedInstance<LLFloaterPreference>("preferences");
if (floater_prefp)
{
floater_prefp->selectPrivacyPanel();
}
}
}

View File

@ -85,7 +85,7 @@ public:
static void idle(void* user_data);
// LLIMSessionObserver observe triggers
/*virtual*/ void sessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id);
/*virtual*/ void sessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id, BOOL has_offline_msg);
/*virtual*/ void sessionActivated(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id);
/*virtual*/ void sessionVoiceOrIMStarted(const LLUUID& session_id);
/*virtual*/ void sessionRemoved(const LLUUID& session_id);

View File

@ -142,7 +142,7 @@ void LLFloaterIMSession::newIMCallback(const LLSD& data)
LLFloaterIMSession* floater = LLFloaterReg::findTypedInstance<LLFloaterIMSession>("impanel", session_id);
// update if visible, otherwise will be updated when opened
if (floater && floater->getVisible())
if (floater && (floater->getHost()? floater->hasFocus() : floater->getVisible()))
{
floater->updateMessages();
}

View File

@ -1570,6 +1570,26 @@ void LLFloaterPreference::setCacheLocation(const LLStringExplicit& location)
cache_location_editor->setToolTip(location);
}
void LLFloaterPreference::selectPanel(const LLSD& name)
{
LLTabContainer * tab_containerp = getChild<LLTabContainer>("pref core");
LLPanel * panel = tab_containerp->getPanelByName(name);
if (NULL != panel)
{
tab_containerp->selectTabPanel(panel);
}
}
void LLFloaterPreference::selectPrivacyPanel()
{
selectPanel("im");
}
void LLFloaterPreference::selectChatPanel()
{
selectPanel("chat");
}
//------------------------------Updater---------------------------------------
static bool handleBandwidthChanged(const LLSD& newvalue)

View File

@ -82,6 +82,8 @@ public:
void processProfileProperties(const LLAvatarData* pAvatarData );
void storeAvatarProperties( const LLAvatarData* pAvatarData );
void saveAvatarProperties( void );
void selectPrivacyPanel();
void selectChatPanel();
protected:
void onBtnOK();
@ -164,6 +166,8 @@ public:
void buildPopupLists();
static void refreshSkin(void* data);
void selectPanel(const LLSD& name);
private:
static std::string sSkin;
bool mClickActionDirty; ///< Set to true when the click/double-click options get changed by user.

View File

@ -724,7 +724,7 @@ bool LLIMModel::newSession(const LLUUID& session_id, const std::string& name, co
// When notifying observer, name of session is used instead of "name", because they may not be the
// same if it is an adhoc session (in this case name is localized in LLIMSession constructor).
std::string session_name = LLIMModel::getInstance()->getName(session_id);
LLIMMgr::getInstance()->notifyObserverSessionAdded(session_id, session_name, other_participant_id);
LLIMMgr::getInstance()->notifyObserverSessionAdded(session_id, session_name, other_participant_id,has_offline_msg);
return true;
@ -2978,11 +2978,11 @@ void LLIMMgr::clearPendingAgentListUpdates(const LLUUID& session_id)
}
}
void LLIMMgr::notifyObserverSessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id)
void LLIMMgr::notifyObserverSessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id, bool has_offline_msg)
{
for (session_observers_list_t::iterator it = mSessionObservers.begin(); it != mSessionObservers.end(); it++)
{
(*it)->sessionAdded(session_id, name, other_participant_id);
(*it)->sessionAdded(session_id, name, other_participant_id, has_offline_msg);
}
}

View File

@ -295,7 +295,7 @@ class LLIMSessionObserver
{
public:
virtual ~LLIMSessionObserver() {}
virtual void sessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id) = 0;
virtual void sessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id, BOOL has_offline_msg) = 0;
virtual void sessionActivated(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id) = 0;
virtual void sessionVoiceOrIMStarted(const LLUUID& session_id) = 0;
virtual void sessionRemoved(const LLUUID& session_id) = 0;
@ -462,7 +462,7 @@ private:
static void onInviteNameLookup(LLSD payload, const LLUUID& id, const std::string& name, bool is_group);
void notifyObserverSessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id);
void notifyObserverSessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id, bool has_offline_msg);
//Triggers when a session has already been added
void notifyObserverSessionActivated(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id);
void notifyObserverSessionVoiceOrIMStarted(const LLUUID& session_id);

View File

@ -5453,6 +5453,7 @@ void LLObjectBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
p.on_enable.parameter = cbparams;
LLView* parent = attachment->getIsHUDAttachment() ? attach_hud_menu : attach_menu;
LLUICtrlFactory::create<LLMenuItemCallGL>(p, parent);
items.push_back(p.name);
}
}
}

View File

@ -254,6 +254,10 @@ bool LLSpeakersDelayActionsStorage::onTimerActionCallback(const LLUUID& speaker_
return true;
}
bool LLSpeakersDelayActionsStorage::isTimerStarted(const LLUUID& speaker_id)
{
return (mActionTimersMap.size() > 0) && (mActionTimersMap.find(speaker_id) != mActionTimersMap.end());
}
//
// ModerationResponder
@ -603,6 +607,10 @@ const LLUUID LLSpeakerMgr::getSessionID()
return mVoiceChannel->getSessionID();
}
bool LLSpeakerMgr::isSpeakerToBeRemoved(const LLUUID& speaker_id)
{
return mSpeakerDelayRemover && mSpeakerDelayRemover->isTimerStarted(speaker_id);
}
void LLSpeakerMgr::setSpeakerTyping(const LLUUID& speaker_id, BOOL typing)
{

View File

@ -193,6 +193,8 @@ public:
void unsetActionTimer(const LLUUID& speaker_id);
void removeAllTimers();
bool isTimerStarted(const LLUUID& speaker_id);
private:
/**
* Callback of the each instance of LLSpeakerActionTimer.
@ -237,6 +239,7 @@ public:
void getSpeakerList(speaker_list_t* speaker_list, BOOL include_text);
LLVoiceChannel* getVoiceChannel() { return mVoiceChannel; }
const LLUUID getSessionID();
bool isSpeakerToBeRemoved(const LLUUID& speaker_id);
/**
* Removes avaline speaker.

View File

@ -617,7 +617,7 @@ BOOL LLIMWellWindow::postBuild()
//virtual
void LLIMWellWindow::sessionAdded(const LLUUID& session_id,
const std::string& name, const LLUUID& other_participant_id)
const std::string& name, const LLUUID& other_participant_id, BOOL has_offline_msg)
{
LLIMModel::LLIMSession* session = LLIMModel::getInstance()->findIMSession(session_id);
if (!session) return;

View File

@ -170,7 +170,7 @@ public:
/*virtual*/ BOOL postBuild();
// LLIMSessionObserver observe triggers
/*virtual*/ void sessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id);
/*virtual*/ void sessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id, BOOL has_offline_msg);
/*virtual*/ void sessionActivated(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id) {}
/*virtual*/ void sessionVoiceOrIMStarted(const LLUUID& session_id) {};
/*virtual*/ void sessionRemoved(const LLUUID& session_id);

View File

@ -2577,26 +2577,59 @@ static LLFastTimer::DeclareTimer FTM_REBUILD_PRIORITY_GROUPS("Rebuild Priority G
void LLPipeline::clearRebuildGroups()
{
LLSpatialGroup::sg_vector_t hudGroups;
mGroupQ1Locked = true;
// Iterate through all drawables on the priority build queue,
for (LLSpatialGroup::sg_vector_t::iterator iter = mGroupQ1.begin();
iter != mGroupQ1.end(); ++iter)
{
LLSpatialGroup* group = *iter;
group->clearState(LLSpatialGroup::IN_BUILD_Q1);
// If the group contains HUD objects, save the group
if (group->isHUDGroup())
{
hudGroups.push_back(group);
}
// Else, no HUD objects so clear the build state
else
{
group->clearState(LLSpatialGroup::IN_BUILD_Q1);
}
}
// Clear the group
mGroupQ1.clear();
// Copy the saved HUD groups back in
mGroupQ1.assign(hudGroups.begin(), hudGroups.end());
mGroupQ1Locked = false;
// Clear the HUD groups
hudGroups.clear();
mGroupQ2Locked = true;
for (LLSpatialGroup::sg_vector_t::iterator iter = mGroupQ2.begin();
iter != mGroupQ2.end(); ++iter)
{
LLSpatialGroup* group = *iter;
group->clearState(LLSpatialGroup::IN_BUILD_Q2);
}
// If the group contains HUD objects, save the group
if (group->isHUDGroup())
{
hudGroups.push_back(group);
}
// Else, no HUD objects so clear the build state
else
{
group->clearState(LLSpatialGroup::IN_BUILD_Q2);
}
}
// Clear the group
mGroupQ2.clear();
// Copy the saved HUD groups back in
mGroupQ2.assign(hudGroups.begin(), hudGroups.end());
mGroupQ2Locked = false;
}

View File

@ -68,6 +68,13 @@
function="IMFloaterContainer.Action"
parameter="chat_preferences" />
</menu_item_call>
<menu_item_call
label="Privacy preferences..."
name="privacy_preferences">
<on_click
function="IMFloaterContainer.Action"
parameter="privacy_preferences" />
</menu_item_call>
<menu_item_check
label="Open conversation log"
name="Conversation"