diff options
-rw-r--r-- | indra/llui/llfolderviewmodel.h | 11 | ||||
-rw-r--r-- | indra/newview/llconversationloglist.cpp | 17 | ||||
-rw-r--r-- | indra/newview/llconversationmodel.h | 4 | ||||
-rw-r--r-- | indra/newview/llfloaterconversationlog.cpp | 5 | ||||
-rw-r--r-- | indra/newview/llfloaterconversationpreview.cpp | 40 | ||||
-rw-r--r-- | indra/newview/llfloaterconversationpreview.h | 2 | ||||
-rw-r--r-- | indra/newview/llimfloatercontainer.cpp | 128 | ||||
-rw-r--r-- | indra/newview/llimfloatercontainer.h | 6 | ||||
-rw-r--r-- | indra/newview/llparticipantlist.cpp | 13 | ||||
-rw-r--r-- | indra/newview/skins/default/xui/en/menu_conversation_log_gear.xml | 28 | ||||
-rw-r--r-- | indra/newview/skins/default/xui/en/menu_conversation_log_view.xml | 8 | ||||
-rw-r--r-- | indra/newview/skins/default/xui/en/menu_participant_view.xml | 7 |
12 files changed, 216 insertions, 53 deletions
diff --git a/indra/llui/llfolderviewmodel.h b/indra/llui/llfolderviewmodel.h index 16d9c86fd7..22bfc4dfb4 100644 --- a/indra/llui/llfolderviewmodel.h +++ b/indra/llui/llfolderviewmodel.h @@ -209,6 +209,7 @@ protected: }; + class LLFolderViewModelItemCommon : public LLFolderViewModelItem { public: @@ -249,6 +250,8 @@ public: std::string::size_type getFilterStringOffset(); std::string::size_type getFilterStringSize(); + typedef std::list<LLFolderViewModelItem*> child_list_t; + virtual void addChild(LLFolderViewModelItem* child) { mChildren.push_back(child); @@ -271,7 +274,11 @@ public: mChildren.clear(); dirtyFilter(); } - + + child_list_t::const_iterator getChildrenBegin() const { return mChildren.begin(); } + child_list_t::const_iterator getChildrenEnd() const { return mChildren.end(); } + child_list_t::size_type getChildrenCount() const { return mChildren.size(); } + void setPassedFilter(bool passed, S32 filter_generation, std::string::size_type string_offset = std::string::npos, std::string::size_type string_size = 0) { mPassedFilter = passed; @@ -325,8 +332,6 @@ protected: S32 mLastFolderFilterGeneration; S32 mMostFilteredDescendantGeneration; - - typedef std::list<LLFolderViewModelItem*> child_list_t; child_list_t mChildren; LLFolderViewModelItem* mParent; LLFolderViewModelInterface& mRootViewModel; diff --git a/indra/newview/llconversationloglist.cpp b/indra/newview/llconversationloglist.cpp index 257ec082a5..94be9055bd 100644 --- a/indra/newview/llconversationloglist.cpp +++ b/indra/newview/llconversationloglist.cpp @@ -241,15 +241,18 @@ void LLConversationLogList::onCustomAction(const LLSD& userdata) { LLAvatarActions::offerTeleport(selected_id); } - else if("add_rem_friend" == command_name) + else if("add_friend" == command_name) { - if (LLAvatarActions::isFriend(selected_id)) + if (!LLAvatarActions::isFriend(selected_id)) { - LLAvatarActions::removeFriendDialog(selected_id); + LLAvatarActions::requestFriendshipDialog(selected_id); } - else + } + else if("remove_friend" == command_name) + { + if (LLAvatarActions::isFriend(selected_id)) { - LLAvatarActions::requestFriendshipDialog(selected_id); + LLAvatarActions::removeFriendDialog(selected_id); } } else if ("invite_to_group" == command_name) @@ -336,6 +339,10 @@ bool LLConversationLogList::isActionChecked(const LLSD& userdata) { return is_p2p && LLAvatarActions::isFriend(selected_id); } + else if ("is_not_friend" == command_name) + { + return is_p2p && !LLAvatarActions::isFriend(selected_id); + } return false; } diff --git a/indra/newview/llconversationmodel.h b/indra/newview/llconversationmodel.h index af3756c45d..1a2e09dfab 100644 --- a/indra/newview/llconversationmodel.h +++ b/indra/newview/llconversationmodel.h @@ -59,8 +59,8 @@ public: virtual LLPointer<LLUIImage> getOpenIcon() const { return getIcon(); } virtual LLFontGL::StyleFlags getLabelStyle() const { return LLFontGL::NORMAL; } virtual std::string getLabelSuffix() const { return LLStringUtil::null; } - virtual BOOL isItemRenameable() const { return FALSE; } - virtual BOOL renameItem(const std::string& new_name) { return FALSE; } + virtual BOOL isItemRenameable() const { return TRUE; } + virtual BOOL renameItem(const std::string& new_name) { mName = new_name; return TRUE; } virtual BOOL isItemMovable( void ) const { return FALSE; } virtual BOOL isItemRemovable( void ) const { return FALSE; } virtual BOOL isItemInTrash( void) const { return FALSE; } diff --git a/indra/newview/llfloaterconversationlog.cpp b/indra/newview/llfloaterconversationlog.cpp index c77a9e74bb..4375ce5726 100644 --- a/indra/newview/llfloaterconversationlog.cpp +++ b/indra/newview/llfloaterconversationlog.cpp @@ -28,6 +28,7 @@ #include "llconversationloglist.h" #include "llfiltereditor.h" #include "llfloaterconversationlog.h" +#include "llfloaterreg.h" #include "llmenubutton.h" LLFloaterConversationLog::LLFloaterConversationLog(const LLSD& key) @@ -97,6 +98,10 @@ void LLFloaterConversationLog::onCustomAction (const LLSD& userdata) { mConversationLogList->toggleSortFriendsOnTop(); } + else if ("view_nearby_chat_history" == command_name) + { + LLFloaterReg::showInstance("preview_conversation", LLSD(LLUUID::null), true); + } } bool LLFloaterConversationLog::isActionEnabled(const LLSD& userdata) diff --git a/indra/newview/llfloaterconversationpreview.cpp b/indra/newview/llfloaterconversationpreview.cpp index ae6f1441eb..7083fb987d 100644 --- a/indra/newview/llfloaterconversationpreview.cpp +++ b/indra/newview/llfloaterconversationpreview.cpp @@ -29,6 +29,7 @@ #include "llfloaterconversationpreview.h" #include "llimview.h" #include "lllineeditor.h" +#include "lltrans.h" LLFloaterConversationPreview::LLFloaterConversationPreview(const LLSD& session_id) : LLFloater(session_id), @@ -44,20 +45,28 @@ BOOL LLFloaterConversationPreview::postBuild() getChild<LLUICtrl>("more_history")->setCommitCallback(boost::bind(&LLFloaterConversationPreview::onMoreHistoryBtnClick, this)); const LLConversation* conv = LLConversationLog::instance().getConversation(mSessionID); - if (conv) - { - std::string name = conv->getConversationName(); - LLStringUtil::format_map_t args; - args["[NAME]"] = name; - std::string title = getString("Title", args); - setTitle(title); + std::string name; + std::string file; - getChild<LLLineEditor>("description")->setValue(name); + if (mSessionID != LLUUID::null && conv) + { + name = conv->getConversationName(); + file = conv->getHistoryFileName(); + } + else + { + name = LLTrans::getString("NearbyChatTitle"); + file = "chat"; } - std::string file = conv->getHistoryFileName(); - LLLogChat::loadChatHistory(file, mMessages, true); + LLStringUtil::format_map_t args; + args["[NAME]"] = name; + std::string title = getString("Title", args); + setTitle(title); + + getChild<LLLineEditor>("description")->setValue(name); + LLLogChat::loadChatHistory(file, mMessages, true); mCurrentPage = mMessages.size() / mPageSize; return LLFloater::postBuild(); @@ -68,7 +77,7 @@ void LLFloaterConversationPreview::draw() LLFloater::draw(); } -void LLFloaterConversationPreview::onOpen(const LLSD& session_id) +void LLFloaterConversationPreview::onOpen(const LLSD& key) { showHistory(); } @@ -88,13 +97,8 @@ void LLFloaterConversationPreview::showHistory() int delta = 0; if (mCurrentPage) { - // stinson 08/28/2012 : This operation could be simplified using integer math with the mod (%) operator. - // e.g. The following code should give the same output. - // int remainder = mMessages.size() % mPageSize; - // delta = (remainder == 0) ? 0 : (mPageSize - remainder); - // Though without examining further, the remainder might be a more appropriate value. - double num_of_pages = static_cast<double>(mMessages.size()) / static_cast<double>(mPageSize); - delta = static_cast<int>((ceil(num_of_pages) - num_of_pages) * static_cast<double>(mPageSize)); + int remainder = mMessages.size() % mPageSize; + delta = (remainder == 0) ? 0 : (mPageSize - remainder); } std::advance(iter, (mCurrentPage * mPageSize) - delta); diff --git a/indra/newview/llfloaterconversationpreview.h b/indra/newview/llfloaterconversationpreview.h index 5105ef3702..2246a44761 100644 --- a/indra/newview/llfloaterconversationpreview.h +++ b/indra/newview/llfloaterconversationpreview.h @@ -39,7 +39,7 @@ public: virtual BOOL postBuild(); virtual void draw(); - virtual void onOpen(const LLSD& session_id); + virtual void onOpen(const LLSD& key); private: void onMoreHistoryBtnClick(); diff --git a/indra/newview/llimfloatercontainer.cpp b/indra/newview/llimfloatercontainer.cpp index d382b61921..5261d30cd9 100644 --- a/indra/newview/llimfloatercontainer.cpp +++ b/indra/newview/llimfloatercontainer.cpp @@ -40,6 +40,7 @@ #include "llavatarnamecache.h" #include "llgroupiconctrl.h" #include "llfloateravatarpicker.h" +#include "llfloaterpreference.h" #include "llimview.h" #include "lltransientfloatermgr.h" #include "llviewercontrol.h" @@ -53,6 +54,8 @@ LLIMFloaterContainer::LLIMFloaterContainer(const LLSD& seed) mExpandCollapseBtn(NULL), mConversationsRoot(NULL) { + mCommitCallbackRegistrar.add("IMFloaterContainer.Action", boost::bind(&LLIMFloaterContainer::onCustomAction, this, _2)); + // Firstly add our self to IMSession observers, so we catch session events LLIMMgr::getInstance()->addSessionObserver(this); @@ -437,6 +440,25 @@ void LLIMFloaterContainer::onAvatarPicked(const uuid_vec_t& ids) } } +void LLIMFloaterContainer::onCustomAction(const LLSD& userdata) +{ + std::string command = userdata.asString(); + + if ("chat_preferences" == command) + { + LLFloaterPreference* floater_prefs = LLFloaterReg::showTypedInstance<LLFloaterPreference>("preferences"); + if (floater_prefs) + { + 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); + } + } + } +} + void LLIMFloaterContainer::repositioningWidgets() { LLRect panel_rect = mConversationsListPanel->getRect(); @@ -444,21 +466,45 @@ void LLIMFloaterContainer::repositioningWidgets() int index = 0; for (conversations_widgets_map::iterator widget_it = mConversationsWidgets.begin(); widget_it != mConversationsWidgets.end(); - widget_it++, ++index) + widget_it++) { - LLFolderViewItem* widget = widget_it->second; + LLFolderViewFolder* widget = dynamic_cast<LLFolderViewFolder*>(widget_it->second); widget->setVisible(TRUE); widget->setRect(LLRect(0, panel_rect.getHeight() - item_height*index, panel_rect.getWidth(), panel_rect.getHeight() - item_height*(index+1))); + index++; + // Reposition the children as well + // Merov : This is highly suspiscious but gets the debug hack to work. This needs to be revised though. + if (widget->getItemsCount() != 0) + { + BOOL is_open = widget->isOpen(); + widget->setOpen(TRUE); + LLFolderViewFolder::items_t::const_iterator current = widget->getItemsBegin(); + LLFolderViewFolder::items_t::const_iterator end = widget->getItemsEnd(); + while (current != end) + { + LLFolderViewItem* item = (*current); + item->setVisible(TRUE); + item->setRect(LLRect(0, + panel_rect.getHeight() - item_height*index, + panel_rect.getWidth(), + panel_rect.getHeight() - item_height*(index+1))); + index++; + current++; + } + widget->setOpen(is_open); + } } } // CHUI-137 : Temporary implementation of conversations list void LLIMFloaterContainer::addConversationListItem(const LLUUID& uuid) { - std::string display_name = uuid.isNull()? LLTrans::getString("NearbyChatTitle") : LLIMModel::instance().getName(uuid); + bool is_nearby_chat = uuid.isNull(); + + std::string display_name = is_nearby_chat ? LLTrans::getString("NearbyChatTitle") : LLIMModel::instance().getName(uuid); // Check if the item is not already in the list, exit if it is and has the same name and uuid (nothing to do) // Note: this happens often, when reattaching a torn off conversation for instance @@ -472,24 +518,69 @@ void LLIMFloaterContainer::addConversationListItem(const LLUUID& uuid) // and nothing wrong will happen removing it if it doesn't exist removeConversationListItem(uuid,false); - // Create a conversation item - LLConversationItem* item = new LLConversationItemSession(display_name, uuid, getRootViewModel()); + // Create a conversation session model + LLConversationItem* item = NULL; + LLSpeakerMgr* speaker_manager = (is_nearby_chat ? (LLSpeakerMgr*)(LLLocalSpeakerMgr::getInstance()) : LLIMModel::getInstance()->getSpeakerManager(uuid)); + if (speaker_manager) + { + item = new LLParticipantList(speaker_manager, NULL, getRootViewModel(), true, false); + } + if (!item) + { + llinfos << "Merov debug : Couldn't create conversation session item : " << display_name << llendl; + return; + } + // *TODO: Should we flag LLConversationItemSession with a mIsNearbyChat? + item->renameItem(display_name); + mConversationsItems[uuid] = item; // Create a widget from it - LLFolderViewItem* widget = createConversationItemWidget(item); + LLConversationViewSession* widget = createConversationItemWidget(item); mConversationsWidgets[uuid] = widget; - // Add a new conversation widget to the root folder of a folder view. + // Add a new conversation widget to the root folder of the folder view widget->addToFolder(mConversationsRoot); // Add it to the UI + mConversationsListPanel->addChild(widget); widget->setVisible(TRUE); + + // Create the participants widgets now + // Note: usually, we do not get an updated avatar list at that point + LLFolderViewModelItemCommon::child_list_t::const_iterator current_participant_model = item->getChildrenBegin(); + LLFolderViewModelItemCommon::child_list_t::const_iterator end_participant_model = item->getChildrenEnd(); + llinfos << "Merov debug : create participant, children size = " << item->getChildrenCount() << llendl; + while (current_participant_model != end_participant_model) + { + LLConversationItem* participant_model = dynamic_cast<LLConversationItem*>(*current_participant_model); + LLConversationViewParticipant* participant_view = createConversationViewParticipant(participant_model); + participant_view->addToFolder(widget); + mConversationsListPanel->addChild(participant_view); + participant_view->setVisible(TRUE); + current_participant_model++; + } + // Debugging hack : uncomment to force the creation of a dummy participant + // This hack is to be eventually deleted + if (item->getChildrenCount() == 0) + { + llinfos << "Merov debug : create dummy participant" << llendl; + // Create a dummy participant : we let that leak but that's just for debugging... + std::string name("Debug Test : "); + name += display_name; + LLUUID test_id; + test_id.generate(name); + LLConversationItemParticipant* participant_model = new LLConversationItemParticipant(name, test_id, getRootViewModel()); + // Create the dummy widget + LLConversationViewParticipant* participant_view = createConversationViewParticipant(participant_model); + participant_view->addToFolder(widget); + mConversationsListPanel->addChild(participant_view); + participant_view->setVisible(TRUE); + } + // End debugging hack repositioningWidgets(); - mConversationsListPanel->addChild(widget); - return; } @@ -524,7 +615,7 @@ void LLIMFloaterContainer::removeConversationListItem(const LLUUID& uuid, bool c } } -LLFolderViewItem* LLIMFloaterContainer::createConversationItemWidget(LLConversationItem* item) +LLConversationViewSession* LLIMFloaterContainer::createConversationItemWidget(LLConversationItem* item) { LLConversationViewSession::Params params; @@ -541,4 +632,21 @@ LLFolderViewItem* LLIMFloaterContainer::createConversationItemWidget(LLConversat return LLUICtrlFactory::create<LLConversationViewSession>(params); } +LLConversationViewParticipant* LLIMFloaterContainer::createConversationViewParticipant(LLConversationItem* item) +{ + LLConversationViewSession::Params params; + + params.name = item->getDisplayName(); + //params.icon = bridge->getIcon(); + //params.icon_open = bridge->getOpenIcon(); + //params.creation_date = bridge->getCreationDate(); + params.root = mConversationsRoot; + params.listener = item; + params.rect = LLRect (0, 0, 0, 0); + params.tool_tip = params.name; + params.container = this; + + return LLUICtrlFactory::create<LLConversationViewParticipant>(params); +} + // EOF diff --git a/indra/newview/llimfloatercontainer.h b/indra/newview/llimfloatercontainer.h index d6dda8ea2d..a72a3e2221 100644 --- a/indra/newview/llimfloatercontainer.h +++ b/indra/newview/llimfloatercontainer.h @@ -37,6 +37,7 @@ #include "llgroupmgr.h" #include "lltrans.h" #include "llconversationmodel.h" +#include "llconversationview.h" class LLButton; class LLLayoutPanel; @@ -102,6 +103,8 @@ private: void onAddButtonClicked(); void onAvatarPicked(const uuid_vec_t& ids); + void onCustomAction (const LLSD& userdata); + LLButton* mExpandCollapseBtn; LLLayoutPanel* mMessagesPane; LLLayoutPanel* mConversationsPane; @@ -113,7 +116,8 @@ public: void addConversationListItem(const LLUUID& uuid); private: - LLFolderViewItem* createConversationItemWidget(LLConversationItem* item); + LLConversationViewSession* createConversationItemWidget(LLConversationItem* item); + LLConversationViewParticipant* createConversationViewParticipant(LLConversationItem* item); // Conversation list data LLPanel* mConversationsListPanel; // This is the main widget we add conversation widget to diff --git a/indra/newview/llparticipantlist.cpp b/indra/newview/llparticipantlist.cpp index 35c1a34a26..fa3432fc89 100644 --- a/indra/newview/llparticipantlist.cpp +++ b/indra/newview/llparticipantlist.cpp @@ -648,10 +648,10 @@ void LLParticipantList::addAvatarIDExceptAgent(const LLUUID& avatar_id) if (is_avatar) { - // Create a participant view model instance and add it to the linked list + // Create a participant view model instance LLAvatarName avatar_name; bool has_name = LLAvatarNameCache::get(avatar_id, &avatar_name); - participant = new LLConversationItemParticipant(!has_name ? "Avatar" : avatar_name.mDisplayName , avatar_id, mRootViewModel); + participant = new LLConversationItemParticipant(!has_name ? LLTrans::getString("AvatarNameWaiting") : avatar_name.mDisplayName , avatar_id, mRootViewModel); if (mAvatarList) { mAvatarList->getIDs().push_back(avatar_id); @@ -661,7 +661,7 @@ void LLParticipantList::addAvatarIDExceptAgent(const LLUUID& avatar_id) else { std::string display_name = LLVoiceClient::getInstance()->getDisplayName(avatar_id); - // Create a participant view model instance and add it to the linked list + // Create a participant view model instance participant = new LLConversationItemParticipant(display_name.empty() ? LLTrans::getString("AvatarNameWaiting") : display_name, avatar_id, mRootViewModel); if (mAvatarList) { @@ -672,6 +672,13 @@ void LLParticipantList::addAvatarIDExceptAgent(const LLUUID& avatar_id) // *TODO : Merov : need to declare and bind a name update callback on that "participant" instance. See LLAvatarListItem::updateAvatarName() for pattern. // For the moment, we'll get the correct name only if it's already in the name cache (see call to LLAvatarNameCache::get() here above) + + // *TODO : Merov : need to update the online/offline status of the participant. + // Hack for this: LLAvatarTracker::instance().isBuddyOnline(avatar_id)) + + llinfos << "Merov debug : added participant, name = " << participant->getName() << llendl; + + // Add the participant model to the session's children list addParticipant(participant); adjustParticipant(avatar_id); diff --git a/indra/newview/skins/default/xui/en/menu_conversation_log_gear.xml b/indra/newview/skins/default/xui/en/menu_conversation_log_gear.xml index b8d0eef956..8796b87955 100644 --- a/indra/newview/skins/default/xui/en/menu_conversation_log_gear.xml +++ b/indra/newview/skins/default/xui/en/menu_conversation_log_gear.xml @@ -57,20 +57,28 @@ parameter="can_offer_teleport"/> </menu_item_call> <menu_item_separator /> - <menu_item_check - label="Add friend/Remove friend" + <menu_item_call + label="Add Friend" layout="topleft" - name="Friend_add_remove"> - <menu_item_check.on_click + name="add_friend"> + <on_click function="Calllog.Action" - parameter="add_rem_friend" /> - <menu_item_check.on_check + parameter="add_friend"/> + <on_visible + function="Calllog.Check" + parameter="is_not_friend" /> + </menu_item_call> + <menu_item_call + label="Remove Friend" + layout="topleft" + name="remove_friend"> + <on_click + function="Calllog.Action" + parameter="remove_friend"/> + <on_visible function="Calllog.Check" parameter="is_friend" /> - <menu_item_check.on_enable - function="Calllog.Enable" - parameter="add_rem_friend" /> - </menu_item_check> + </menu_item_call> <menu_item_call label="Invite to group..." layout="topleft" diff --git a/indra/newview/skins/default/xui/en/menu_conversation_log_view.xml b/indra/newview/skins/default/xui/en/menu_conversation_log_view.xml index 4ab8cb4f7d..ce65b23971 100644 --- a/indra/newview/skins/default/xui/en/menu_conversation_log_view.xml +++ b/indra/newview/skins/default/xui/en/menu_conversation_log_view.xml @@ -34,4 +34,12 @@ function="CallLog.Check" parameter="sort_friends_on_top" /> </menu_item_check> + <menu_item_separator /> + <menu_item_call + label="View Nearby chat history..." + name="view_nearby_chat_history"> + <on_click + function="CallLog.Action" + parameter="view_nearby_chat_history" /> + </menu_item_call> </toggleable_menu> diff --git a/indra/newview/skins/default/xui/en/menu_participant_view.xml b/indra/newview/skins/default/xui/en/menu_participant_view.xml index 6401b0e3b7..df2700c94c 100644 --- a/indra/newview/skins/default/xui/en/menu_participant_view.xml +++ b/indra/newview/skins/default/xui/en/menu_participant_view.xml @@ -2,6 +2,13 @@ <toggleable_menu layout="topleft" name="participant_manu_view"> + <menu_item_call + label="Chat preferences..." + name="chat_preferences"> + <on_click + function="IMFloaterContainer.Action" + parameter="chat_preferences" /> + </menu_item_call> <menu_item_check label="Open conversation log" name="Conversation" |