diff options
author | Merov Linden <merov@lindenlab.com> | 2012-06-26 17:05:16 -0700 |
---|---|---|
committer | Merov Linden <merov@lindenlab.com> | 2012-06-26 17:05:16 -0700 |
commit | c233f0c9494d7dddbd8baab0f87b0ad54f42b0f9 (patch) | |
tree | 503aa347e72dc9730e24e3c468745c39311f75dd /indra | |
parent | 94e6e4bd3d8260894a3d76e5101858cd1582be59 (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.cpp | 9 | ||||
-rw-r--r-- | indra/newview/llimfloatercontainer.cpp | 56 | ||||
-rw-r--r-- | indra/newview/llimfloatercontainer.h | 8 |
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) |