diff options
author | Yuri Chebotarev ychebotarev@productengine.com <Yuri Chebotarev ychebotarev@productengine.com> | 2009-10-27 11:33:09 +0200 |
---|---|---|
committer | Yuri Chebotarev ychebotarev@productengine.com <Yuri Chebotarev ychebotarev@productengine.com> | 2009-10-27 11:33:09 +0200 |
commit | c377a4b6f42acba8dfe259086985ca9342bb7864 (patch) | |
tree | f7c16a5d7c781eee99afbfcb618c163cd7ef75e3 /indra | |
parent | 62c8f55e3e49f55bc76dbcaba797ca02b3072c3f (diff) | |
parent | d0d208fbf6e156c73b83b780a73f4613769a381d (diff) |
merge
--HG--
branch : product-engine
Diffstat (limited to 'indra')
23 files changed, 406 insertions, 98 deletions
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index eb045349c2..b113a35ea1 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -7731,6 +7731,39 @@ <key>Value</key> <integer>1</integer> </map> + <key>FriendsListShowIcons</key> + <map> + <key>Comment</key> + <string>Show/hide online and all friends icons in the friend list</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>1</integer> + </map> + <key>NearbyListShowIcons</key> + <map> + <key>Comment</key> + <string>Show/hide people icons in nearby list</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>1</integer> + </map> + <key>RecentListShowIcons</key> + <map> + <key>Comment</key> + <string>Show/hide people icons in recent list</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>1</integer> + </map> <key>FriendsSortOrder</key> <map> <key>Comment</key> diff --git a/indra/newview/llavatarlist.cpp b/indra/newview/llavatarlist.cpp index 3a07c6e5ef..1d07caee53 100644 --- a/indra/newview/llavatarlist.cpp +++ b/indra/newview/llavatarlist.cpp @@ -38,6 +38,7 @@ #include "llcallingcard.h" // for LLAvatarTracker #include "llcachename.h" #include "llvoiceclient.h" +#include "llviewercontrol.h" // for gSavedSettings static LLDefaultChildRegistry::Register<LLAvatarList> r("avatar_list"); @@ -45,6 +46,21 @@ static LLDefaultChildRegistry::Register<LLAvatarList> r("avatar_list"); // Used to limit time spent for avatar list update per frame. static const unsigned ADD_LIMIT = 50; +void LLAvatarList::toggleIcons() +{ + // Save the new value for new items to use. + mShowIcons = !mShowIcons; + gSavedSettings.setBOOL(mIconParamName, mShowIcons); + + // Show/hide icons for all existing items. + std::vector<LLPanel*> items; + getItems(items); + for( std::vector<LLPanel*>::const_iterator it = items.begin(); it != items.end(); it++) + { + static_cast<LLAvatarListItem*>(*it)->setAvatarIconVisible(mShowIcons); + } +} + static bool findInsensitive(std::string haystack, const std::string& needle_upper) { LLStringUtil::toUpper(haystack); @@ -73,6 +89,12 @@ LLAvatarList::LLAvatarList(const Params& p) setComparator(&NAME_COMPARATOR); } +void LLAvatarList::setShowIcons(std::string param_name) +{ + mIconParamName= param_name; + mShowIcons = gSavedSettings.getBOOL(mIconParamName); +} + // virtual void LLAvatarList::draw() { @@ -202,6 +224,7 @@ void LLAvatarList::addNewItem(const LLUUID& id, const std::string& name, BOOL is item->setContextMenu(mContextMenu); item->childSetVisible("info_btn", false); + item->setAvatarIconVisible(mShowIcons); addItem(item, id, pos); } diff --git a/indra/newview/llavatarlist.h b/indra/newview/llavatarlist.h index a83a72b26c..f60f1f00f3 100644 --- a/indra/newview/llavatarlist.h +++ b/indra/newview/llavatarlist.h @@ -70,7 +70,11 @@ public: void setContextMenu(LLAvatarListItem::ContextMenu* menu) { mContextMenu = menu; } + void toggleIcons(); void sortByName(); + void setShowIcons(std::string param_name); + bool getIconsVisible() const { return mShowIcons; } + const std::string getIconParamName() const{return mIconParamName;} virtual BOOL handleRightMouseDown(S32 x, S32 y, MASK mask); protected: @@ -86,7 +90,9 @@ private: bool mIgnoreOnlineStatus; bool mDirty; + bool mShowIcons; + std::string mIconParamName; std::string mNameFilter; uuid_vector_t mIDs; diff --git a/indra/newview/llavatarlistitem.cpp b/indra/newview/llavatarlistitem.cpp index ebc79aae48..4ecb9537ba 100644 --- a/indra/newview/llavatarlistitem.cpp +++ b/indra/newview/llavatarlistitem.cpp @@ -42,6 +42,7 @@ #include "llavatariconctrl.h" #include "llbutton.h" +S32 LLAvatarListItem::sIconWidth = 0; LLAvatarListItem::LLAvatarListItem() : LLPanel(), @@ -55,6 +56,12 @@ LLAvatarListItem::LLAvatarListItem() mOnlineStatus(E_UNKNOWN) { LLUICtrlFactory::getInstance()->buildPanel(this, "panel_avatar_list_item.xml"); + // Remember avatar icon width including its padding from the name text box, + // so that we can hide and show the icon again later. + if (!sIconWidth) + { + sIconWidth = mAvatarName->getRect().mLeft - mAvatarIcon->getRect().mLeft; + } } LLAvatarListItem::~LLAvatarListItem() @@ -188,6 +195,21 @@ void LLAvatarListItem::setAvatarId(const LLUUID& id, bool ignore_status_changes) gCacheName->get(id, FALSE, boost::bind(&LLAvatarListItem::onNameCache, this, _2, _3)); } +void LLAvatarListItem::setAvatarIconVisible(bool visible) +{ + // Already done? Then do nothing. + if (mAvatarIcon->getVisible() == (BOOL)visible) + return; + + // Show/hide avatar icon. + mAvatarIcon->setVisible(visible); + + // Move the avatar name horizontally by icon size + its distance from the avatar name. + LLRect name_rect = mAvatarName->getRect(); + name_rect.mLeft += visible ? sIconWidth : -sIconWidth; + mAvatarName->setRect(name_rect); +} + void LLAvatarListItem::onInfoBtnClick() { LLFloaterReg::showInstance("inspect_avatar", LLSD().insert("avatar_id", mAvatarId)); diff --git a/indra/newview/llavatarlistitem.h b/indra/newview/llavatarlistitem.h index b9cfed4b7b..a8d3919217 100644 --- a/indra/newview/llavatarlistitem.h +++ b/indra/newview/llavatarlistitem.h @@ -64,6 +64,7 @@ public: void setOnline(bool online); void setName(const std::string& name); void setAvatarId(const LLUUID& id, bool ignore_status_changes = false); + void setAvatarIconVisible(bool visible); const LLUUID& getAvatarId() const; const std::string getAvatarName() const; @@ -87,7 +88,7 @@ private: void onNameCache(const std::string& first_name, const std::string& last_name); - LLAvatarIconCtrl*mAvatarIcon; + LLAvatarIconCtrl* mAvatarIcon; LLTextBox* mAvatarName; LLTextBox* mStatus; @@ -98,6 +99,7 @@ private: LLUUID mAvatarId; EOnlineStatus mOnlineStatus; + static S32 sIconWidth; // icon width + padding }; #endif //LL_LLAVATARLISTITEM_H diff --git a/indra/newview/llchannelmanager.cpp b/indra/newview/llchannelmanager.cpp index 77f941eef0..6427422572 100644 --- a/indra/newview/llchannelmanager.cpp +++ b/indra/newview/llchannelmanager.cpp @@ -40,6 +40,8 @@ #include "llbottomtray.h" #include "llviewerwindow.h" #include "llrootview.h" +#include "llsyswellwindow.h" +#include "llfloaterreg.h" #include <algorithm> @@ -128,7 +130,7 @@ void LLChannelManager::onLoginCompleted() S32 channel_right_bound = gViewerWindow->getWorldViewRect().mRight - gSavedSettings.getS32("NotificationChannelRightMargin"); S32 channel_width = gSavedSettings.getS32("NotifyBoxWidth"); mStartUpChannel->init(channel_right_bound - channel_width, channel_right_bound); - mStartUpChannel->setShowToasts(true); + mStartUpChannel->setMouseDownCallback(boost::bind(&LLSysWellWindow::onStartUpToastClick, LLFloaterReg::getTypedInstance<LLSysWellWindow>("syswell_window"), _2, _3, _4)); mStartUpChannel->setCommitCallback(boost::bind(&LLChannelManager::onStartUpToastClose, this)); mStartUpChannel->createStartUpToast(away_notifications, gSavedSettings.getS32("StartUpToastLifeTime")); diff --git a/indra/newview/llimfloater.cpp b/indra/newview/llimfloater.cpp index d0d176766d..91e383eb14 100644 --- a/indra/newview/llimfloater.cpp +++ b/indra/newview/llimfloater.cpp @@ -61,7 +61,14 @@ LLIMFloater::LLIMFloater(const LLUUID& session_id) mLastMessageIndex(-1), mDialog(IM_NOTHING_SPECIAL), mChatHistory(NULL), - mInputEditor(NULL), + mInputEditor(NULL), + mSavedTitle(), + mTypingStart(), + mShouldSendTypingState(false), + mMeTyping(false), + mOtherTyping(false), + mTypingTimer(), + mTypingTimeoutTimer(), mPositioned(false), mSessionInitialized(false) { @@ -95,6 +102,7 @@ void LLIMFloater::onFocusReceived() // virtual void LLIMFloater::onClose(bool app_quitting) { + setTyping(false); gIMMgr->leaveSession(mSessionID); } @@ -141,6 +149,7 @@ void LLIMFloater::onSendMsg( LLUICtrl* ctrl, void* userdata ) { LLIMFloater* self = (LLIMFloater*) userdata; self->sendMsg(); + self->setTyping(false); } void LLIMFloater::sendMsg() @@ -228,12 +237,27 @@ BOOL LLIMFloater::postBuild() LLLogChat::loadHistory(getTitle(), &chatFromLogFile, (void *)this); } + mTypingStart = LLTrans::getString("IM_typing_start_string"); + //*TODO if session is not initialized yet, add some sort of a warning message like "starting session...blablabla" //see LLFloaterIMPanel for how it is done (IB) return LLDockableFloater::postBuild(); } +// virtual +void LLIMFloater::draw() +{ + if ( mMeTyping ) + { + // Time out if user hasn't typed for a while. + if ( mTypingTimeoutTimer.getElapsedTimeF32() > LLAgent::TYPING_TIMEOUT_SECS ) + { + setTyping(false); + } + } + LLFloater::draw(); +} // static @@ -402,7 +426,8 @@ void LLIMFloater::sessionInitReplyReceived(const LLUUID& im_session_id) void LLIMFloater::updateMessages() { - std::list<LLSD> messages = LLIMModel::instance().getMessages(mSessionID, mLastMessageIndex+1); + std::list<LLSD> messages; + LLIMModel::instance().getMessages(mSessionID, messages, mLastMessageIndex+1); std::string agent_name; gCacheName->getFullName(gAgentID, agent_name); @@ -454,7 +479,7 @@ void LLIMFloater::onInputEditorFocusReceived( LLFocusableElement* caller, void* void LLIMFloater::onInputEditorFocusLost(LLFocusableElement* caller, void* userdata) { LLIMFloater* self = (LLIMFloater*) userdata; - self->setTyping(FALSE); + self->setTyping(false); } // static @@ -464,19 +489,118 @@ void LLIMFloater::onInputEditorKeystroke(LLLineEditor* caller, void* userdata) std::string text = self->mInputEditor->getText(); if (!text.empty()) { - self->setTyping(TRUE); + self->setTyping(true); } else { // Deleting all text counts as stopping typing. - self->setTyping(FALSE); + self->setTyping(false); + } +} + +void LLIMFloater::setTyping(bool typing) +{ + if ( typing ) + { + // Started or proceeded typing, reset the typing timeout timer + mTypingTimeoutTimer.reset(); + } + + if ( mMeTyping != typing ) + { + // Typing state is changed + mMeTyping = typing; + // So, should send current state + mShouldSendTypingState = true; + // In case typing is started, send state after some delay + mTypingTimer.reset(); + } + + // Don't want to send typing indicators to multiple people, potentially too + // much network traffic. Only send in person-to-person IMs. + if ( mShouldSendTypingState && mDialog == IM_NOTHING_SPECIAL ) + { + if ( mMeTyping ) + { + if ( mTypingTimer.getElapsedTimeF32() > 1.f ) + { + // Still typing, send 'start typing' notification + LLIMModel::instance().sendTypingState(mSessionID, mOtherParticipantUUID, TRUE); + mShouldSendTypingState = false; + } + } + else + { + // Send 'stop typing' notification immediately + LLIMModel::instance().sendTypingState(mSessionID, mOtherParticipantUUID, FALSE); + mShouldSendTypingState = false; + } + } + + LLIMSpeakerMgr* speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(mSessionID); + if (speaker_mgr) + speaker_mgr->setSpeakerTyping(gAgent.getID(), FALSE); + +} + +void LLIMFloater::processIMTyping(const LLIMInfo* im_info, BOOL typing) +{ + if ( typing ) + { + // other user started typing + addTypingIndicator(im_info); + } + else + { + // other user stopped typing + removeTypingIndicator(im_info); } } +void LLIMFloater::addTypingIndicator(const LLIMInfo* im_info) +{ + // We may have lost a "stop-typing" packet, don't add it twice + if ( im_info && !mOtherTyping ) + { + mOtherTyping = true; -//just a stub for now -void LLIMFloater::setTyping(BOOL typing) + // Create typing is started title string + LLUIString typing_start(mTypingStart); + typing_start.setArg("[NAME]", im_info->mName); + + // Save and set new title + mSavedTitle = getTitle(); + setTitle (typing_start); + + // Update speaker + LLIMSpeakerMgr* speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(mSessionID); + if ( speaker_mgr ) + { + speaker_mgr->setSpeakerTyping(im_info->mFromID, TRUE); + } + } +} + +void LLIMFloater::removeTypingIndicator(const LLIMInfo* im_info) { + if ( mOtherTyping ) + { + mOtherTyping = false; + + // Revert the title to saved one + setTitle(mSavedTitle); + + if ( im_info ) + { + // Update speaker + LLIMSpeakerMgr* speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(mSessionID); + if ( speaker_mgr ) + { + speaker_mgr->setSpeakerTyping(im_info->mFromID, FALSE); + } + } + + } } void LLIMFloater::chatFromLogFile(LLLogChat::ELogLineType type, std::string line, void* userdata) diff --git a/indra/newview/llimfloater.h b/indra/newview/llimfloater.h index 99810b6d6d..3559e14c89 100644 --- a/indra/newview/llimfloater.h +++ b/indra/newview/llimfloater.h @@ -55,6 +55,8 @@ public: // LLView overrides /*virtual*/ BOOL postBuild(); /*virtual*/ void setVisible(BOOL visible); + // Check typing timeout timer. + /*virtual*/ void draw(); // LLFloater overrides /*virtual*/ void onClose(bool app_quitting); @@ -85,6 +87,7 @@ public: void setPositioned(bool b) { mPositioned = b; }; void onVisibilityChange(const LLSD& new_visibility); + void processIMTyping(const LLIMInfo* im_info, BOOL typing); private: // process focus events to set a currently active session @@ -94,7 +97,7 @@ private: static void onInputEditorFocusReceived( LLFocusableElement* caller, void* userdata ); static void onInputEditorFocusLost(LLFocusableElement* caller, void* userdata); static void onInputEditorKeystroke(LLLineEditor* caller, void* userdata); - void setTyping(BOOL typing); + void setTyping(bool typing); void onSlide(); static void* createPanelIMControl(void* userdata); static void* createPanelGroupControl(void* userdata); @@ -103,6 +106,11 @@ private: static void chatFromLogFile(LLLogChat::ELogLineType type, std::string line, void* userdata); + // Add the "User is typing..." indicator. + void addTypingIndicator(const LLIMInfo* im_info); + + // Remove the "User is typing..." indicator. + void removeTypingIndicator(const LLIMInfo* im_info = NULL); LLPanelChatControlPanel* mControlPanel; LLUUID mSessionID; @@ -114,6 +122,14 @@ private: LLLineEditor* mInputEditor; bool mPositioned; + std::string mSavedTitle; + LLUIString mTypingStart; + bool mMeTyping; + bool mOtherTyping; + bool mShouldSendTypingState; + LLFrameTimer mTypingTimer; + LLFrameTimer mTypingTimeoutTimer; + bool mSessionInitialized; LLSD mQueuedMsgsForInit; }; diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp index fa7e1170be..59cd9cec86 100644 --- a/indra/newview/llimview.cpp +++ b/indra/newview/llimview.cpp @@ -272,7 +272,8 @@ void LLIMModel::testMessages() } -bool LLIMModel::newSession(LLUUID session_id, std::string name, EInstantMessage type, LLUUID other_participant_id, const std::vector<LLUUID>& ids) +bool LLIMModel::newSession(const LLUUID& session_id, const std::string& name, const EInstantMessage& type, + const LLUUID& other_participant_id, const std::vector<LLUUID>& ids) { if (is_in_map(sSessionsMap, session_id)) { @@ -289,7 +290,7 @@ bool LLIMModel::newSession(LLUUID session_id, std::string name, EInstantMessage } -bool LLIMModel::clearSession(LLUUID session_id) +bool LLIMModel::clearSession(const LLUUID& session_id) { if (sSessionsMap.find(session_id) == sSessionsMap.end()) return false; delete (sSessionsMap[session_id]); @@ -297,16 +298,13 @@ bool LLIMModel::clearSession(LLUUID session_id) return true; } -//*TODO remake it, instead of returing the list pass it as as parameter (IB) -std::list<LLSD> LLIMModel::getMessages(LLUUID session_id, int start_index) +void LLIMModel::getMessages(const LLUUID& session_id, std::list<LLSD>& messages, int start_index) { - std::list<LLSD> return_list; - LLIMSession* session = findIMSession(session_id); if (!session) { llwarns << "session " << session_id << "does not exist " << llendl; - return return_list; + return; } int i = session->mMsgs.size() - start_index; @@ -317,7 +315,7 @@ std::list<LLSD> LLIMModel::getMessages(LLUUID session_id, int start_index) { LLSD msg; msg = *iter; - return_list.push_back(*iter); + messages.push_back(*iter); i--; } @@ -327,14 +325,9 @@ std::list<LLSD> LLIMModel::getMessages(LLUUID session_id, int start_index) arg["session_id"] = session_id; arg["num_unread"] = 0; mNoUnreadMsgsSignal(arg); - - // TODO: in the future is there a more efficient way to return these - //of course there is - return as parameter (IB) - return return_list; - } -bool LLIMModel::addToHistory(LLUUID session_id, std::string from, LLUUID from_id, std::string utf8_text) { +bool LLIMModel::addToHistory(const LLUUID& session_id, const std::string& from, const LLUUID& from_id, const std::string& utf8_text) { LLIMSession* session = findIMSession(session_id); @@ -383,8 +376,8 @@ bool LLIMModel::logToFile(const LLUUID& session_id, const std::string& from, con return false; } -//*TODO add const qualifier and pass by references (IB) -bool LLIMModel::addMessage(LLUUID session_id, std::string from, LLUUID from_id, std::string utf8_text, bool log2file /* = true */) { +bool LLIMModel::addMessage(const LLUUID& session_id, const std::string& from, const LLUUID& from_id, + const std::string& utf8_text, bool log2file /* = true */) { LLIMSession* session = findIMSession(session_id); if (!session) @@ -506,7 +499,7 @@ void LLIMModel::sendTypingState(LLUUID session_id, LLUUID other_participant_id, gAgent.sendReliableMessage(); } -void LLIMModel::sendLeaveSession(LLUUID session_id, LLUUID other_participant_id) +void LLIMModel::sendLeaveSession(const LLUUID& session_id, const LLUUID& other_participant_id) { if(session_id.notNull()) { @@ -1265,7 +1258,8 @@ void LLIMMgr::addMessage( fixed_session_name = session_name; } - if (!LLIMModel::getInstance()->findIMSession(new_session_id)) + bool new_session = !hasSession(session_id); + if (new_session) { LLIMModel::getInstance()->newSession(session_id, fixed_session_name, dialog, other_participant_id); } @@ -1284,15 +1278,16 @@ void LLIMMgr::addMessage( // create IM window as necessary if(!floater) { - - floater = createFloater( new_session_id, other_participant_id, fixed_session_name, dialog, FALSE); + } + if (new_session) + { // When we get a new IM, and if you are a god, display a bit // of information about the source. This is to help liaisons // when answering questions. @@ -1302,7 +1297,7 @@ void LLIMMgr::addMessage( std::ostringstream bonus_info; bonus_info << LLTrans::getString("***")+ " "+ LLTrans::getString("IMParentEstate") + ":" + " " << parent_estate_id - << ((parent_estate_id == 1) ? "," + LLTrans::getString("IMMainland") : "") + << ((parent_estate_id == 1) ? "," + LLTrans::getString("IMMainland") : "") << ((parent_estate_id == 5) ? "," + LLTrans::getString ("IMTeen") : ""); // once we have web-services (or something) which returns @@ -1405,10 +1400,7 @@ S32 LLIMMgr::getNumberOfUnreadIM() S32 num = 0; for(it = LLIMModel::sSessionsMap.begin(); it != LLIMModel::sSessionsMap.end(); ++it) { - if((*it).first != mBeingRemovedSessionID) - { - num += (*it).second->mNumUnread; - } + num += (*it).second->mNumUnread; } return num; @@ -1517,41 +1509,25 @@ bool LLIMMgr::leaveSession(const LLUUID& session_id) return true; } -// This removes the panel referenced by the uuid, and then restores -// internal consistency. The internal pointer is not deleted? Did you mean -// a pointer to the corresponding LLIMSession? Session data is cleared now. -// Put a copy of UUID to avoid problem when passed reference becames invalid -// if it has been come from the object removed in observer. -void LLIMMgr::removeSession(LLUUID session_id) +// Removes data associated with a particular session specified by session_id +void LLIMMgr::removeSession(const LLUUID& session_id) { - if (mBeingRemovedSessionID == session_id) - { - return; - } + llassert_always(hasSession(session_id)); + //*TODO remove this floater thing when Communicate Floater is being deleted (IB) LLFloaterIMPanel* floater = findFloaterBySession(session_id); if(floater) { mFloaters.erase(floater->getHandle()); LLFloaterChatterBox::getInstance()->removeFloater(floater); - //mTabContainer->removeTabPanel(floater); - - clearPendingInvitation(session_id); - clearPendingAgentListUpdates(session_id); } - // for some purposes storing ID of a sessios that is being removed - mBeingRemovedSessionID = session_id; - notifyObserverSessionRemoved(session_id); + clearPendingInvitation(session_id); + clearPendingAgentListUpdates(session_id); - //if we don't clear session data on removing the session - //we can't use LLBottomTray as observer of session creation/delettion and - //creating chiclets only on session created even, we need to handle chiclets creation - //the same way as LLFloaterIMPanels were managed. LLIMModel::getInstance()->clearSession(session_id); - // now this session is completely removed - mBeingRemovedSessionID.setNull(); + notifyObserverSessionRemoved(session_id); } void LLIMMgr::inviteToSession( @@ -1991,6 +1967,12 @@ void LLIMMgr::processIMTypingCore(const LLIMInfo* im_info, BOOL typing) { floater->processIMTyping(im_info, typing); } + + LLIMFloater* im_floater = LLIMFloater::findInstance(session_id); + if ( im_floater ) + { + im_floater->processIMTyping(im_info, typing); + } } class LLViewerChatterBoxSessionStartReply : public LLHTTPNode diff --git a/indra/newview/llimview.h b/indra/newview/llimview.h index 6991017e8f..e3d0a50557 100644 --- a/indra/newview/llimview.h +++ b/indra/newview/llimview.h @@ -104,18 +104,35 @@ public: boost::signals2::connection addNewMsgCallback( session_callback_t cb ) { return mNewMsgSignal.connect(cb); } boost::signals2::connection addNoUnreadMsgsCallback( session_callback_t cb ) { return mNoUnreadMsgsSignal.connect(cb); } - bool newSession(LLUUID session_id, std::string name, EInstantMessage type, LLUUID other_participant_id, + /** + * Create new session object in a model + */ + bool newSession(const LLUUID& session_id, const std::string& name, const EInstantMessage& type, const LLUUID& other_participant_id, const std::vector<LLUUID>& ids = std::vector<LLUUID>()); - bool clearSession(LLUUID session_id); - std::list<LLSD> getMessages(LLUUID session_id, int start_index = 0); - bool addMessage(LLUUID session_id, std::string from, LLUUID other_participant_id, std::string utf8_text, bool log2file = true); - bool addToHistory(LLUUID session_id, std::string from, LLUUID from_id, std::string utf8_text); + /** + * Remove all session data associated with a session specified by session_id + */ + bool clearSession(const LLUUID& session_id); - bool logToFile(const LLUUID& session_id, const std::string& from, const std::string& utf8_text); + /** + * Populate supplied std::list with messages starting from index specified by start_index + */ + void getMessages(const LLUUID& session_id, std::list<LLSD>& messages, int start_index = 0); - //used to get the name of the session, for use as the title - //currently just the other avatar name + /** + * Add a message to an IM Model - the message is saved in a message store associated with a session specified by session_id + * and also saved into a file if log2file is specified. + * It sends new message signal for each added message. + */ + bool addMessage(const LLUUID& session_id, const std::string& from, const LLUUID& other_participant_id, const std::string& utf8_text, bool log2file = true); + + /** + * Get a session's name. + * For a P2P chat - it's an avatar's name, + * For a group chat - it's a group's name + * For an ad-hoc chat - is received from the server and is in a from of "<Avatar's name> conference" + */ const std::string& getName(const LLUUID& session_id) const; /** @@ -150,7 +167,7 @@ public: */ LLIMSpeakerMgr* getSpeakerManager(const LLUUID& session_id) const; - static void sendLeaveSession(LLUUID session_id, LLUUID other_participant_id); + static void sendLeaveSession(const LLUUID& session_id, const LLUUID& other_participant_id); static bool sendStartSession(const LLUUID& temp_session_id, const LLUUID& other_participant_id, const std::vector<LLUUID>& ids, EInstantMessage dialog); static void sendTypingState(LLUUID session_id, LLUUID other_participant_id, BOOL typing); @@ -158,6 +175,19 @@ public: const LLUUID& other_participant_id, EInstantMessage dialog); void testMessages(); + +private: + + /** + * Add message to a list of message associated with session specified by session_id + */ + bool addToHistory(const LLUUID& session_id, const std::string& from, const LLUUID& from_id, const std::string& utf8_text); + + /** + * Save an IM message into a file + */ + //*TODO should also save uuid of a sender + bool logToFile(const LLUUID& session_id, const std::string& from, const std::string& utf8_text); }; class LLIMSessionObserver @@ -297,10 +327,11 @@ public: bool endCall(const LLUUID& session_id); private: - // This removes the panel referenced by the uuid, and then - // restores internal consistency. The internal pointer is not - // deleted. - void removeSession(LLUUID session_id); + + /** + * Remove data associated with a particular session specified by session_id + */ + void removeSession(const LLUUID& session_id); // create a panel and update internal representation for // consistency. Returns the pointer, caller (the class instance @@ -341,9 +372,6 @@ private: LLSD mPendingInvitations; LLSD mPendingAgentListUpdates; - // ID of a session that is being removed: observers are already told - // that this session is being removed, but it is still present in the sessions' map - LLUUID mBeingRemovedSessionID; }; class LLIncomingCallDialog : public LLModalDialog diff --git a/indra/newview/llnearbychatbar.cpp b/indra/newview/llnearbychatbar.cpp index 5fa97926a5..217007fb15 100644 --- a/indra/newview/llnearbychatbar.cpp +++ b/indra/newview/llnearbychatbar.cpp @@ -45,6 +45,7 @@ #include "llviewerstats.h" #include "llcommandhandler.h" #include "llviewercontrol.h" +#include "llnavigationbar.h" S32 LLNearbyChatBar::sLastSpecialChatChannel = 0; @@ -177,6 +178,31 @@ void LLGestureComboBox::draw() LLComboBox::draw(); } +//virtual +void LLGestureComboBox::showList() +{ + LLComboBox::showList(); + + // Calculating amount of space between the navigation bar and gestures combo + LLNavigationBar* nb = LLNavigationBar::getInstance(); + S32 x, nb_bottom; + nb->localPointToScreen(0, 0, &x, &nb_bottom); + + S32 list_bottom; + mList->localPointToScreen(0, 0, &x, &list_bottom); + + S32 max_height = nb_bottom - list_bottom; + + LLRect rect = mList->getRect(); + // List overlapped navigation bar, downsize it + if (rect.getHeight() > max_height) + { + rect.setOriginAndSize(rect.mLeft, rect.mBottom, rect.getWidth(), max_height); + mList->setRect(rect); + mList->reshape(rect.getWidth(), rect.getHeight()); + } +} + LLNearbyChatBar::LLNearbyChatBar() : LLPanel() , mChatBox(NULL) diff --git a/indra/newview/llnearbychatbar.h b/indra/newview/llnearbychatbar.h index b902ff86cc..d495a10193 100644 --- a/indra/newview/llnearbychatbar.h +++ b/indra/newview/llnearbychatbar.h @@ -62,6 +62,9 @@ public: virtual void changed() { refreshGestures(); } protected: + + virtual void showList(); + LLFrameTimer mGestureLabelTimer; std::vector<LLMultiGesture*> mGestures; std::string mLabel; diff --git a/indra/newview/llpanelpeople.cpp b/indra/newview/llpanelpeople.cpp index 61d66873ea..4580eeb336 100644 --- a/indra/newview/llpanelpeople.cpp +++ b/indra/newview/llpanelpeople.cpp @@ -413,13 +413,17 @@ BOOL LLPanelPeople::postBuild() mOnlineFriendList = getChild<LLPanel>(FRIENDS_TAB_NAME)->getChild<LLAvatarList>("avatars_online"); mAllFriendList = getChild<LLPanel>(FRIENDS_TAB_NAME)->getChild<LLAvatarList>("avatars_all"); mOnlineFriendList->setNoItemsCommentText(getString("no_friends_online")); + mOnlineFriendList->setShowIcons("FriendsListShowIcons"); mAllFriendList->setNoItemsCommentText(getString("no_friends")); + mAllFriendList->setShowIcons("FriendsListShowIcons"); mNearbyList = getChild<LLPanel>(NEARBY_TAB_NAME)->getChild<LLAvatarList>("avatar_list"); mNearbyList->setNoItemsCommentText(getString("no_one_near")); + mNearbyList->setShowIcons("NearbyListShowIcons"); mRecentList = getChild<LLPanel>(RECENT_TAB_NAME)->getChild<LLAvatarList>("avatar_list"); mRecentList->setNoItemsCommentText(getString("no_people")); + mRecentList->setShowIcons("RecentListShowIcons"); mGroupList = getChild<LLGroupList>("group_list"); mGroupList->setNoItemsCommentText(getString("no_groups")); @@ -611,6 +615,10 @@ void LLPanelPeople::updateButtons() bool recent_tab_active = (cur_tab == RECENT_TAB_NAME); LLUUID selected_id; + std::vector<LLUUID> selected_uuids; + getCurrentItemIDs(selected_uuids); + bool item_selected = (selected_uuids.size() == 1); + buttonSetVisible("group_info_btn", group_tab_active); buttonSetVisible("chat_btn", group_tab_active); buttonSetVisible("add_friend_btn", nearby_tab_active || recent_tab_active); @@ -621,7 +629,6 @@ void LLPanelPeople::updateButtons() if (group_tab_active) { - bool item_selected = mGroupList->getSelectedItem() != NULL; bool cur_group_active = true; if (item_selected) @@ -629,7 +636,7 @@ void LLPanelPeople::updateButtons() selected_id = mGroupList->getSelectedUUID(); cur_group_active = (gAgent.getGroupID() == selected_id); } - + LLPanel* groups_panel = mTabContainer->getCurrentPanel(); groups_panel->childSetEnabled("activate_btn", item_selected && !cur_group_active); // "none" or a non-active group selected groups_panel->childSetEnabled("plus_btn", item_selected); @@ -640,18 +647,18 @@ void LLPanelPeople::updateButtons() bool is_friend = true; // Check whether selected avatar is our friend. - if ((selected_id = getCurrentItemID()).notNull()) + if (item_selected) { + selected_id = selected_uuids.front(); is_friend = LLAvatarTracker::instance().getBuddyInfo(selected_id) != NULL; } childSetEnabled("add_friend_btn", !is_friend); } - bool item_selected = selected_id.notNull(); buttonSetEnabled("teleport_btn", friends_tab_active && item_selected); buttonSetEnabled("view_profile_btn", item_selected); - buttonSetEnabled("im_btn", item_selected); + buttonSetEnabled("im_btn", (selected_uuids.size() >= 1)); // allow starting the friends conference for multiple selection buttonSetEnabled("call_btn", item_selected && false); // not implemented yet buttonSetEnabled("share_btn", item_selected && false); // not implemented yet buttonSetEnabled("group_info_btn", item_selected); @@ -877,7 +884,17 @@ void LLPanelPeople::onAddFriendWizButtonClicked() void LLPanelPeople::onDeleteFriendButtonClicked() { - LLAvatarActions::removeFriendDialog(getCurrentItemID()); + std::vector<LLUUID> selected_uuids; + getCurrentItemIDs(selected_uuids); + + if (selected_uuids.size() == 1) + { + LLAvatarActions::removeFriendDialog( selected_uuids.front() ); + } + else if (selected_uuids.size() > 1) + { + LLAvatarActions::removeFriendsDialog( selected_uuids ); + } } void LLPanelPeople::onGroupInfoButtonClicked() @@ -963,6 +980,8 @@ void LLPanelPeople::onFriendsViewSortMenuItemClicked(const LLSD& userdata) } else if (chosen_item == "view_icons") { + mAllFriendList->toggleIcons(); + mOnlineFriendList->toggleIcons(); } else if (chosen_item == "organize_offline") { @@ -992,6 +1011,7 @@ void LLPanelPeople::onNearbyViewSortMenuItemClicked(const LLSD& userdata) } else if (chosen_item == "view_icons") { + mNearbyList->toggleIcons(); } else if (chosen_item == "sort_distance") { @@ -1011,7 +1031,7 @@ void LLPanelPeople::onRecentViewSortMenuItemClicked(const LLSD& userdata) } else if (chosen_item == "view_icons") { - // *TODO: implement showing/hiding icons + mRecentList->toggleIcons(); } } diff --git a/indra/newview/llparticipantlist.cpp b/indra/newview/llparticipantlist.cpp index 25e773e8b8..534c69a2a3 100644 --- a/indra/newview/llparticipantlist.cpp +++ b/indra/newview/llparticipantlist.cpp @@ -87,7 +87,7 @@ bool LLParticipantList::SpeakerAddListener::handleEvent(LLPointer<LLOldEvents::L bool LLParticipantList::SpeakerRemoveListener::handleEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata) { LLAvatarList::uuid_vector_t& group_members = mAvatarList->getIDs(); - group_members.erase(std::find(group_members.begin(), group_members.end(), event->getValue().asUUID())); + group_members.erase(std::find(group_members.begin(), group_members.end(), event->getValue().asUUID()), group_members.end()); mAvatarList->setDirty(); return true; } diff --git a/indra/newview/llscreenchannel.cpp b/indra/newview/llscreenchannel.cpp index 1683d113a9..383e540394 100644 --- a/indra/newview/llscreenchannel.cpp +++ b/indra/newview/llscreenchannel.cpp @@ -519,6 +519,7 @@ void LLScreenChannel::createStartUpToast(S32 notif_num, F32 timer) LLRect toast_rect; LLToast::Params p; p.lifetime_secs = timer; + p.enable_hide_btn = false; mStartUpToastPanel = new LLToast(p); if(!mStartUpToastPanel) diff --git a/indra/newview/llsyswellwindow.cpp b/indra/newview/llsyswellwindow.cpp index 86290e6695..93a931dc78 100644 --- a/indra/newview/llsyswellwindow.cpp +++ b/indra/newview/llsyswellwindow.cpp @@ -113,6 +113,12 @@ void LLSysWellWindow::connectListUpdaterToSignal(std::string notification_type) } //--------------------------------------------------------------------------------- +void LLSysWellWindow::onStartUpToastClick(S32 x, S32 y, MASK mask) +{ + onChicletClick(); +} + +//--------------------------------------------------------------------------------- void LLSysWellWindow::onChicletClick() { // 1 - remove StartUp toast and channel if present diff --git a/indra/newview/llsyswellwindow.h b/indra/newview/llsyswellwindow.h index fa6a1abea4..cbc5f7358f 100644 --- a/indra/newview/llsyswellwindow.h +++ b/indra/newview/llsyswellwindow.h @@ -76,6 +76,7 @@ public: void onItemClose(LLSysWellItem* item); void onStoreToast(LLPanel* info_panel, LLUUID id); void onChicletClick(); + void onStartUpToastClick(S32 x, S32 y, MASK mask); // size constants for the window and for its elements static const S32 MAX_WINDOW_HEIGHT = 200; diff --git a/indra/newview/llviewerinventory.cpp b/indra/newview/llviewerinventory.cpp index 57a4117d5d..366e5602bd 100644 --- a/indra/newview/llviewerinventory.cpp +++ b/indra/newview/llviewerinventory.cpp @@ -42,7 +42,6 @@ #include "llconsole.h" #include "llinventorymodel.h" #include "llnotify.h" -#include "llimview.h" #include "llgesturemgr.h" #include "llinventorybridge.h" diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index c659e58e47..f3c1cf191a 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -142,7 +142,6 @@ #include "llstatview.h" #include "llsurface.h" #include "llsurfacepatch.h" -#include "llimview.h" #include "lltexlayer.h" #include "lltextbox.h" #include "lltexturecache.h" diff --git a/indra/newview/skins/default/xui/en/menu_people_friends_view_sort.xml b/indra/newview/skins/default/xui/en/menu_people_friends_view_sort.xml index cc17e9dd4b..eedb4383bb 100644 --- a/indra/newview/skins/default/xui/en/menu_people_friends_view_sort.xml +++ b/indra/newview/skins/default/xui/en/menu_people_friends_view_sort.xml @@ -23,9 +23,14 @@ parameter="sort_status" /> </menu_item_check> <menu_item_separator layout="topleft" /> - <menu_item_call name="view_icons" label="View People Icons"> - <menu_item_call.on_click function="People.Friends.ViewSort.Action" userdata="view_icons" /> - </menu_item_call> + <menu_item_check name="view_icons" label="View People Icons"> + <menu_item_check.on_click + function="People.Friends.ViewSort.Action" + parameter="view_icons" /> + <menu_item_check.on_check + function="CheckControl" + parameter="FriendsListShowIcons" /> + </menu_item_check> <menu_item_call name="organize_offline" label="Organize Offline Friends"> <menu_item_call.on_click function="People.Friends.ViewSort.Action" userdata="organize_offline" /> </menu_item_call> diff --git a/indra/newview/skins/default/xui/en/menu_people_nearby_view_sort.xml b/indra/newview/skins/default/xui/en/menu_people_nearby_view_sort.xml index f91a961388..c002cd078f 100644 --- a/indra/newview/skins/default/xui/en/menu_people_nearby_view_sort.xml +++ b/indra/newview/skins/default/xui/en/menu_people_nearby_view_sort.xml @@ -12,9 +12,14 @@ <menu_item_call.on_click function="People.Nearby.ViewSort.Action" userdata="sort_distance" /> </menu_item_call> <menu_item_separator layout="topleft" /> - <menu_item_call name="view_icons" label="View People Icons"> - <menu_item_call.on_click function="People.Nearby.ViewSort.Action" userdata="view_icons" /> - </menu_item_call> + <menu_item_check name="view_icons" label="View People Icons"> + <menu_item_check.on_click + function="People.Nearby.ViewSort.Action" + parameter="view_icons" /> + <menu_item_check.on_check + function="CheckControl" + parameter="NearbyListShowIcons" /> + </menu_item_check> <menu_item_separator layout="topleft" /> <menu_item_call name="show_blocked_list" label="Show Blocked Residents & Objects"> <menu_item_call.on_click function="SideTray.ShowPanel" userdata="panel_block_list_sidetray" /> diff --git a/indra/newview/skins/default/xui/en/menu_people_recent_view_sort.xml b/indra/newview/skins/default/xui/en/menu_people_recent_view_sort.xml index d09871cff3..cfd6dc78b6 100644 --- a/indra/newview/skins/default/xui/en/menu_people_recent_view_sort.xml +++ b/indra/newview/skins/default/xui/en/menu_people_recent_view_sort.xml @@ -23,9 +23,14 @@ parameter="sort_name" /> </menu_item_check> <menu_item_separator layout="topleft" /> - <menu_item_call name="view_icons" label="View People Icons"> - <menu_item_call.on_click function="People.Recent.ViewSort.Action" userdata="view_icons" /> - </menu_item_call> + <menu_item_check name="view_icons" label="View People Icons"> + <menu_item_check.on_click + function="People.Recent.ViewSort.Action" + parameter="view_icons" /> + <menu_item_check.on_check + function="CheckControl" + parameter="RecentListShowIcons" /> + </menu_item_check> <menu_item_separator layout="topleft" /> <menu_item_call name="show_blocked_list" label="Show Blocked Residents & Objects"> <menu_item_call.on_click function="SideTray.ShowPanel" userdata="panel_block_list_sidetray" /> diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml index 4c19b22ac5..7efda2b882 100644 --- a/indra/newview/skins/default/xui/en/strings.xml +++ b/indra/newview/skins/default/xui/en/strings.xml @@ -264,10 +264,6 @@ <string name="TrackYourCamera">Track your camera</string> <string name="ControlYourCamera">Control your camera</string> - <!-- IM --> - <string name="IM_logging_string">-- Instant message logging enabled --</string> - <string name="Unnamed">(Unnamed)</string> - <!-- Sim Access labels --> <string name="SIM_ACCESS_PG">PG</string> <string name="SIM_ACCESS_MATURE">Mature</string> @@ -2884,7 +2880,11 @@ If you continue to receive this message, contact the [SUPPORT_SITE]. Failed to start viewer </string> - <!-- IM system messages --> + <!-- IM system messages --> + <string name="IM_logging_string">-- Instant message logging enabled --</string> + <string name="IM_typing_start_string">[NAME] is typing...</string> + <string name="Unnamed">(Unnamed)</string> + <string name="ringing-im"> Joining Voice Chat... </string> |