summaryrefslogtreecommitdiff
path: root/indra
diff options
context:
space:
mode:
authorMerov Linden <merov@lindenlab.com>2012-06-26 17:05:16 -0700
committerMerov Linden <merov@lindenlab.com>2012-06-26 17:05:16 -0700
commitc233f0c9494d7dddbd8baab0f87b0ad54f42b0f9 (patch)
tree503aa347e72dc9730e24e3c468745c39311f75dd /indra
parent94e6e4bd3d8260894a3d76e5101858cd1582be59 (diff)
CHUI-164 : Fix crash when closing ad-hoc conversations; insure consistency of the conversation list when adding and removing items from it
Diffstat (limited to 'indra')
-rw-r--r--indra/newview/llimfloater.cpp9
-rw-r--r--indra/newview/llimfloatercontainer.cpp56
-rw-r--r--indra/newview/llimfloatercontainer.h8
3 files changed, 58 insertions, 15 deletions
diff --git a/indra/newview/llimfloater.cpp b/indra/newview/llimfloater.cpp
index 98ebc82f99..f89bafc7ea 100644
--- a/indra/newview/llimfloater.cpp
+++ b/indra/newview/llimfloater.cpp
@@ -540,8 +540,10 @@ LLIMFloater* LLIMFloater::show(const LLUUID& session_id)
}
}
+ // Test the existence of the floater before we try to create it
bool exist = findInstance(session_id);
+ // Get the floater: this will create the instance if it didn't exist
LLIMFloater* floater = getInstance(session_id);
if (!floater)
return NULL;
@@ -550,18 +552,21 @@ LLIMFloater* LLIMFloater::show(const LLUUID& session_id)
{
LLIMFloaterContainer* floater_container = LLIMFloaterContainer::getInstance();
- // do not add existed floaters to avoid adding torn off instances
+ // Do not add again existing floaters
if (!exist)
{
// LLTabContainer::eInsertionPoint i_pt = user_initiated ? LLTabContainer::RIGHT_OF_CURRENT : LLTabContainer::END;
// TODO: mantipov: use LLTabContainer::RIGHT_OF_CURRENT if it exists
LLTabContainer::eInsertionPoint i_pt = LLTabContainer::END;
-
if (floater_container)
{
floater_container->addFloater(floater, TRUE, i_pt);
}
}
+
+ // Add a conversation list item in the left pane: nothing will be done if already in there
+ // but relevant clean up will be done to ensure consistency of the conversation list
+ floater_container->addConversationListItem(floater->getTitle(), session_id, floater);
floater->openFloater(floater->getKey());
}
diff --git a/indra/newview/llimfloatercontainer.cpp b/indra/newview/llimfloatercontainer.cpp
index 33b96b20f3..f6bcf8bbe9 100644
--- a/indra/newview/llimfloatercontainer.cpp
+++ b/indra/newview/llimfloatercontainer.cpp
@@ -146,7 +146,7 @@ void LLIMFloaterContainer::addFloater(LLFloater* floaterp,
LLUUID session_id = floaterp->getKey();
// Add a conversation list item in the left pane
- addConversationListItem(floaterp->getTitle(), session_id, floaterp, this);
+ addConversationListItem(floaterp->getTitle(), session_id, floaterp);
LLView* floater_contents = floaterp->getChild<LLView>("contents_view");
@@ -408,18 +408,33 @@ void LLIMFloaterContainer::onAvatarPicked(const uuid_vec_t& ids)
}
// CHUI-137 : Temporary implementation of conversations list
-void LLIMFloaterContainer::addConversationListItem(std::string name, const LLUUID& uuid, LLFloater* floaterp, LLIMFloaterContainer* containerp)
+void LLIMFloaterContainer::addConversationListItem(std::string name, const LLUUID& uuid, LLFloater* floaterp)
{
- // Check if the item is not already in the list, exit if it is (nothing to do)
+ // Check if the item is not already in the list, exit if it is and has the same name and points to the same floater (nothing to do)
// Note: this happens often, when reattaching a torn off conversation for instance
conversations_items_map::iterator item_it = mConversationsItems.find(uuid);
if (item_it != mConversationsItems.end())
{
- return;
+ LLConversationItem* item = item_it->second;
+ // Check if the item has changed
+ if (item->hasSameValues(name,floaterp))
+ {
+ // If it hasn't, nothing to do -> exit
+ return;
+ }
+ // If it has, remove it: it'll be recreated anew further down
+ removeConversationListItem(uuid,false);
+ }
+
+ // Reverse find and clean up: we need to make sure that no other uuid is pointing to that same floater
+ LLUUID found_id = LLUUID::null;
+ if (findConversationItem(floaterp,found_id))
+ {
+ removeConversationListItem(found_id,false);
}
// Create a conversation item
- LLConversationItem* item = new LLConversationItem(name, uuid, floaterp, containerp);
+ LLConversationItem* item = new LLConversationItem(name, uuid, floaterp, this);
mConversationsItems[uuid] = item;
// Create a widget from it
@@ -439,7 +454,7 @@ void LLIMFloaterContainer::addConversationListItem(std::string name, const LLUUI
return;
}
-void LLIMFloaterContainer::removeConversationListItem(const LLUUID& session_id)
+void LLIMFloaterContainer::removeConversationListItem(const LLUUID& session_id, bool change_focus)
{
// Delete the widget and the associated conversation item
// Note : since the mConversationsItems is also the listener to the widget, deleting
@@ -469,16 +484,35 @@ void LLIMFloaterContainer::removeConversationListItem(const LLUUID& session_id)
}
// Don't let the focus fall IW, select and refocus on the first conversation in the list
- setFocus(TRUE);
- conversations_items_map::iterator item_it = mConversationsItems.begin();
- if (item_it != mConversationsItems.end())
+ if (change_focus)
{
- LLConversationItem* item = item_it->second;
- item->selectItem();
+ setFocus(TRUE);
+ conversations_items_map::iterator item_it = mConversationsItems.begin();
+ if (item_it != mConversationsItems.end())
+ {
+ LLConversationItem* item = item_it->second;
+ item->selectItem();
+ }
}
return;
}
+bool LLIMFloaterContainer::findConversationItem(LLFloater* floaterp, LLUUID& uuid)
+{
+ bool found = false;
+ for (conversations_items_map::iterator item_it = mConversationsItems.begin(); item_it != mConversationsItems.end(); ++item_it)
+ {
+ LLConversationItem* item = item_it->second;
+ uuid = item_it->first;
+ if (item->hasSameValue(floaterp))
+ {
+ found = true;
+ break;
+ }
+ }
+ return found;
+}
+
LLFolderViewItem* LLIMFloaterContainer::createConversationItemWidget(LLConversationItem* item)
{
LLFolderViewItem::Params params;
diff --git a/indra/newview/llimfloatercontainer.h b/indra/newview/llimfloatercontainer.h
index c6e7c6a3d9..2a8cbf3e1c 100644
--- a/indra/newview/llimfloatercontainer.h
+++ b/indra/newview/llimfloatercontainer.h
@@ -112,6 +112,9 @@ public:
EDragAndDropType cargo_type,
void* cargo_data,
std::string& tooltip_msg) { return FALSE; }
+
+ bool hasSameValues(std::string name, LLFloater* floaterp) { return ((name == mName) && (floaterp == mFloater)); }
+ bool hasSameValue(LLFloater* floaterp) { return (floaterp == mFloater); }
private:
std::string mName;
const LLUUID mUUID;
@@ -183,9 +186,10 @@ private:
// CHUI-137 : Temporary implementation of conversations list
public:
- void removeConversationListItem(const LLUUID& session_id);
+ void removeConversationListItem(const LLUUID& session_id, bool change_focus = true);
+ void addConversationListItem(std::string name, const LLUUID& uuid, LLFloater* floaterp);
+ bool findConversationItem(LLFloater* floaterp, LLUUID& uuid);
private:
- void addConversationListItem(std::string name, const LLUUID& uuid, LLFloater* floaterp, LLIMFloaterContainer* containerp);
LLFolderViewItem* createConversationItemWidget(LLConversationItem* item);
// Conversation list data
LLPanel* mConversationsListPanel; // This is the widget we add items to (i.e. clickable title for each conversation)