diff options
Diffstat (limited to 'indra')
22 files changed, 313 insertions, 179 deletions
diff --git a/indra/llui/llspinctrl.cpp b/indra/llui/llspinctrl.cpp index 934879cdfd..8a728df2e7 100644 --- a/indra/llui/llspinctrl.cpp +++ b/indra/llui/llspinctrl.cpp @@ -52,6 +52,7 @@ LLSpinCtrl::Params::Params() : label_width("label_width"), decimal_digits("decimal_digits"), allow_text_entry("allow_text_entry", true), + allow_digits_only("allow_digits_only", false), label_wrap("label_wrap", false), text_enabled_color("text_enabled_color"), text_disabled_color("text_disabled_color"), @@ -129,6 +130,10 @@ LLSpinCtrl::LLSpinCtrl(const LLSpinCtrl::Params& p) params.follows.flags(FOLLOWS_LEFT | FOLLOWS_BOTTOM); mEditor = LLUICtrlFactory::create<LLLineEditor> (params); mEditor->setFocusReceivedCallback( boost::bind(&LLSpinCtrl::onEditorGainFocus, _1, this )); + if (p.allow_digits_only) + { + mEditor->setPrevalidateInput(LLTextValidate::validateNonNegativeS32NoSpace); + } //RN: this seems to be a BAD IDEA, as it makes the editor behavior different when it has focus // than when it doesn't. Instead, if you always have to double click to select all the text, // it's easier to understand diff --git a/indra/llui/llspinctrl.h b/indra/llui/llspinctrl.h index 87814f838e..e34add879d 100644 --- a/indra/llui/llspinctrl.h +++ b/indra/llui/llspinctrl.h @@ -44,6 +44,7 @@ public: Optional<S32> label_width; Optional<U32> decimal_digits; Optional<bool> allow_text_entry; + Optional<bool> allow_digits_only; Optional<bool> label_wrap; Optional<LLUIColor> text_enabled_color; diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 4dacde4792..08a1a237f5 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -1834,10 +1834,7 @@ bool LLAppViewer::cleanup() LLMuteList::getInstance()->cache(gAgent.getID()); //save call log list - if (gSavedPerAccountSettings.getBOOL("LogInstantMessages")) - { - LLConversationLog::instance().cache(); - } + LLConversationLog::instance().cache(); if (mPurgeOnExit) { diff --git a/indra/newview/llconversationlog.cpp b/indra/newview/llconversationlog.cpp index cc02e18698..27be2bc5ae 100644 --- a/indra/newview/llconversationlog.cpp +++ b/indra/newview/llconversationlog.cpp @@ -37,7 +37,7 @@ struct Conversation_params Conversation_params(time_t time) : mTime(time), mTimestamp(LLConversation::createTimestamp(time)), - mIsConversationPast(true) + mIsVoice(false) {} time_t mTime; @@ -48,7 +48,6 @@ struct Conversation_params LLUUID mSessionID; LLUUID mParticipantID; bool mIsVoice; - bool mIsConversationPast; bool mHasOfflineIMs; }; @@ -65,7 +64,6 @@ LLConversation::LLConversation(const Conversation_params& params) mSessionID(params.mSessionID), mParticipantID(params.mParticipantID), mIsVoice(params.mIsVoice), - mIsConversationPast(params.mIsConversationPast), mHasOfflineIMs(params.mHasOfflineIMs) { setListenIMFloaterOpened(); @@ -80,7 +78,6 @@ LLConversation::LLConversation(const LLIMModel::LLIMSession& session) mSessionID(session.mSessionID), mParticipantID(session.mOtherParticipantID), mIsVoice(session.mStartedAsIMCall), - mIsConversationPast(false), mHasOfflineIMs(session.mHasOfflineMessage) { setListenIMFloaterOpened(); @@ -96,7 +93,6 @@ LLConversation::LLConversation(const LLConversation& conversation) mSessionID = conversation.getSessionID(); mParticipantID = conversation.getParticipantID(); mIsVoice = conversation.isVoice(); - mIsConversationPast = conversation.isConversationPast(); mHasOfflineIMs = conversation.hasOfflineMessages(); setListenIMFloaterOpened(); @@ -107,12 +103,10 @@ LLConversation::~LLConversation() mIMFloaterShowedConnection.disconnect(); } -void LLConversation::setIsVoice(bool is_voice) +void LLConversation::updateTimestamp() { - if (mIsConversationPast) - return; - - mIsVoice = is_voice; + mTime = time_corrected(); + mTimestamp = createTimestamp(mTime); } void LLConversation::onIMFloaterShown(const LLUUID& session_id) @@ -154,14 +148,18 @@ void LLConversation::setListenIMFloaterOpened() LLIMFloater* floater = LLIMFloater::findInstance(mSessionID); bool has_offline_ims = !mIsVoice && mHasOfflineIMs; - bool ims_are_read = LLIMFloater::isVisible(floater) && floater->hasFocus(); + bool offline_ims_visible = LLIMFloater::isVisible(floater) && floater->hasFocus(); // we don't need to listen for im floater with this conversation is opened // if floater is already opened or this conversation doesn't have unread offline messages - if (has_offline_ims && !ims_are_read) + if (has_offline_ims && !offline_ims_visible) { mIMFloaterShowedConnection = LLIMFloater::setIMFloaterShowedCallback(boost::bind(&LLConversation::onIMFloaterShown, this, _1)); } + else + { + mHasOfflineIMs = false; + } } /************************************************************************/ @@ -195,40 +193,107 @@ void LLConversationLogFriendObserver::changed(U32 mask) LLConversationLog::LLConversationLog() { - loadFromFile(getFileName()); - LLControlVariable* ctrl = gSavedPerAccountSettings.getControl("LogInstantMessages").get(); if (ctrl) { - ctrl->getSignal()->connect(boost::bind(&LLConversationLog::observeIMSession, this)); - + ctrl->getSignal()->connect(boost::bind(&LLConversationLog::enableLogging, this, _2)); if (ctrl->getValue().asBoolean()) { - LLIMMgr::instance().addSessionObserver(this); + enableLogging(true); } } - - mFriendObserver = new LLConversationLogFriendObserver; - LLAvatarTracker::instance().addObserver(mFriendObserver); - } -void LLConversationLog::observeIMSession() +void LLConversationLog::enableLogging(bool enable) { - if (gSavedPerAccountSettings.getBOOL("LogInstantMessages")) + if (enable) { + loadFromFile(getFileName()); + LLIMMgr::instance().addSessionObserver(this); + newMessageSignalConnection = LLIMModel::instance().addNewMsgCallback(boost::bind(&LLConversationLog::onNewMessageReceived, this, _1)); + + mFriendObserver = new LLConversationLogFriendObserver; + LLAvatarTracker::instance().addObserver(mFriendObserver); } else { + saveToFile(getFileName()); + LLIMMgr::instance().removeSessionObserver(this); + newMessageSignalConnection.disconnect(); + LLAvatarTracker::instance().removeObserver(mFriendObserver); + mConversations.clear(); } + + notifyObservers(); } -void LLConversationLog::logConversation(const LLConversation& conversation) +void LLConversationLog::logConversation(const LLUUID& session_id) { - mConversations.push_back(conversation); - notifyObservers(); + LLIMModel::LLIMSession* session = LLIMModel::instance().findIMSession(session_id); + LLConversation* conversation = findConversation(session_id); + + if (session && conversation) + { + updateConversationTimestamp(conversation); + } + else if (session && !conversation) + { + createConversation(session_id); + } +} + +void LLConversationLog::createConversation(const LLUUID& session_id) +{ + LLIMModel::LLIMSession* session = LLIMModel::instance().findIMSession(session_id); + + if (session) + { + LLConversation conversation(*session); + mConversations.push_back(conversation); + + if (LLIMModel::LLIMSession::P2P_SESSION == session->mSessionType) + { + LLAvatarNameCache::get(session->mOtherParticipantID, boost::bind(&LLConversationLog::onAvatarNameCache, this, _1, _2, session)); + } + + notifyObservers(); + } +} + +void LLConversationLog::updateConversationName(const LLUUID& session_id, const std::string& name) +{ + LLConversation* conversation = findConversation(session_id); + + if (conversation) + { + conversation->setConverstionName(name); + notifyPrticularConversationObservers(session_id, LLConversationLogObserver::CHANGED_NAME); + } +} + +void LLConversationLog::updateConversationTimestamp(LLConversation* conversation) +{ + if (conversation) + { + conversation->updateTimestamp(); + notifyPrticularConversationObservers(conversation->getSessionID(), LLConversationLogObserver::CHANGED_TIME); + } +} + +LLConversation* LLConversationLog::findConversation(const LLUUID& session_id) +{ + conversations_vec_t::iterator conv_it = mConversations.begin(); + for(; conv_it != mConversations.end(); ++conv_it) + { + if (conv_it->getSessionID() == session_id) + { + return &*conv_it; + } + } + + return NULL; } void LLConversationLog::removeConversation(const LLConversation& conversation) @@ -271,41 +336,17 @@ void LLConversationLog::removeObserver(LLConversationLogObserver* observer) void LLConversationLog::sessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id) { - LLIMModel::LLIMSession* session = LLIMModel::instance().findIMSession(session_id); - if (session) - { - if (LLIMModel::LLIMSession::P2P_SESSION == session->mSessionType) - { - LLAvatarNameCache::get(session->mOtherParticipantID, boost::bind(&LLConversationLog::onAvatarNameCache, this, _1, _2, session)); - } - else - { - LLConversation conversation(*session); - LLConversationLog::instance().logConversation(conversation); - session->mVoiceChannel->setStateChangedCallback(boost::bind(&LLConversationLog::onVoiceChannelConnected, this, _5, _2)); - } - } + logConversation(session_id); } -void LLConversationLog::sessionRemoved(const LLUUID& session_id) +void LLConversationLog::cache() { - conversations_vec_t::reverse_iterator rev_iter = mConversations.rbegin(); - - for (; rev_iter != mConversations.rend(); ++rev_iter) + if (gSavedPerAccountSettings.getBOOL("LogInstantMessages")) { - if (rev_iter->getSessionID() == session_id && !rev_iter->isConversationPast()) - { - rev_iter->setIsPast(true); - return; // return here because only one session with session_id may be active - } + saveToFile(getFileName()); } } -void LLConversationLog::cache() -{ - saveToFile(getFileName()); -} - std::string LLConversationLog::getFileName() { std::string filename = "conversation"; @@ -314,7 +355,7 @@ std::string LLConversationLog::getFileName() bool LLConversationLog::saveToFile(const std::string& filename) { - if(!filename.size()) + if (!filename.size()) { llwarns << "Call log list filename is empty!" << llendl; return false; @@ -442,25 +483,13 @@ void LLConversationLog::notifyPrticularConversationObservers(const LLUUID& sessi } } -void LLConversationLog::onVoiceChannelConnected(const LLUUID& session_id, const LLVoiceChannel::EState& state) +void LLConversationLog::onNewMessageReceived(const LLSD& data) { - conversations_vec_t::reverse_iterator rev_iter = mConversations.rbegin(); - - for (; rev_iter != mConversations.rend(); ++rev_iter) - { - if (rev_iter->getSessionID() == session_id && !rev_iter->isConversationPast() && LLVoiceChannel::STATE_CALL_STARTED == state) - { - rev_iter->setIsVoice(true); - notifyPrticularConversationObservers(session_id, LLConversationLogObserver::VOICE_STATE); - return; // return here because only one session with session_id may be active - } - } + const LLUUID session_id = data["session_id"].asUUID(); + logConversation(session_id); } void LLConversationLog::onAvatarNameCache(const LLUUID& participant_id, const LLAvatarName& av_name, LLIMModel::LLIMSession* session) { - LLConversation conversation(*session); - conversation.setConverstionName(av_name.getCompleteName()); - LLConversationLog::instance().logConversation(conversation); - session->mVoiceChannel->setStateChangedCallback(boost::bind(&LLConversationLog::onVoiceChannelConnected, this, _5, _2)); + updateConversationName(session->mSessionID, av_name.getCompleteName()); } diff --git a/indra/newview/llconversationlog.h b/indra/newview/llconversationlog.h index 16be37d67a..a458e975bb 100644 --- a/indra/newview/llconversationlog.h +++ b/indra/newview/llconversationlog.h @@ -57,16 +57,19 @@ public: const std::string& getTimestamp() const { return mTimestamp; } const time_t& getTime() const { return mTime; } bool isVoice() const { return mIsVoice; } - bool isConversationPast() const { return mIsConversationPast; } bool hasOfflineMessages() const { return mHasOfflineIMs; } void setIsVoice(bool is_voice); - void setIsPast (bool is_past) { mIsConversationPast = is_past; } void setConverstionName(std::string conv_name) { mConversationName = conv_name; } bool isOlderThan(U32 days) const; /* + * updates last interaction time + */ + void updateTimestamp(); + + /* * Resets flag of unread offline message to false when im floater with this conversation is opened. */ void onIMFloaterShown(const LLUUID& session_id); @@ -86,7 +89,7 @@ private: boost::signals2::connection mIMFloaterShowedConnection; - time_t mTime; // start time of conversation + time_t mTime; // last interaction time SessionType mConversationType; std::string mConversationName; std::string mHistoryFileName; @@ -94,8 +97,7 @@ private: LLUUID mParticipantID; bool mIsVoice; bool mHasOfflineIMs; - bool mIsConversationPast; // once session is finished conversation became past forever - std::string mTimestamp; // conversation start time in form of: mm/dd/yyyy hh:mm + std::string mTimestamp; // last interaction time in form of: mm/dd/yyyy hh:mm }; /** @@ -112,32 +114,26 @@ class LLConversationLog : public LLSingleton<LLConversationLog>, LLIMSessionObse friend class LLSingleton<LLConversationLog>; public: - /** - * adds conversation to the conversation list and notifies observers - */ - void logConversation(const LLConversation& conversation); void removeConversation(const LLConversation& conversation); /** * Returns first conversation with matched session_id */ - const LLConversation* getConversation(const LLUUID& session_id); + const LLConversation* getConversation(const LLUUID& session_id); + const std::vector<LLConversation>& getConversations() { return mConversations; } void addObserver(LLConversationLogObserver* observer); void removeObserver(LLConversationLogObserver* observer); - const std::vector<LLConversation>& getConversations() { return mConversations; } - // LLIMSessionObserver triggers virtual void sessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id); - virtual void sessionRemoved(const LLUUID& session_id); + virtual void sessionRemoved(const LLUUID& session_id){} // Stub virtual void sessionVoiceOrIMStarted(const LLUUID& session_id){}; // Stub virtual void sessionIDUpdated(const LLUUID& old_session_id, const LLUUID& new_session_id){}; // Stub void notifyObservers(); - void notifyPrticularConversationObservers(const LLUUID& session_id, U32 mask); - void onVoiceChannelConnected(const LLUUID& session_id, const LLVoiceChannel::EState& state); + void onNewMessageReceived(const LLSD& data); /** * public method which is called on viewer exit to save conversation log @@ -148,7 +144,14 @@ private: LLConversationLog(); - void observeIMSession(); + void enableLogging(bool enable); + + /** + * adds conversation to the conversation list and notifies observers + */ + void logConversation(const LLUUID& session_id); + + void notifyPrticularConversationObservers(const LLUUID& session_id, U32 mask); /** * constructs file name in which conversations log will be saved @@ -161,11 +164,19 @@ private: void onAvatarNameCache(const LLUUID& participant_id, const LLAvatarName& av_name, LLIMModel::LLIMSession* session); + void createConversation(const LLUUID& session_id); + void updateConversationTimestamp(LLConversation* conversation); + void updateConversationName(const LLUUID& session_id, const std::string& name); + + LLConversation* findConversation(const LLUUID& session_id); + typedef std::vector<LLConversation> conversations_vec_t; std::vector<LLConversation> mConversations; std::set<LLConversationLogObserver*> mObservers; LLFriendObserver* mFriendObserver; // Observer of the LLAvatarTracker instance + + boost::signals2::connection newMessageSignalConnection; }; class LLConversationLogObserver @@ -174,7 +185,8 @@ public: enum EConversationChange { - VOICE_STATE = 1 + CHANGED_TIME = 1, // last interaction time changed + CHANGED_NAME = 2 // conversation name changed }; virtual ~LLConversationLogObserver(){} diff --git a/indra/newview/llconversationloglist.cpp b/indra/newview/llconversationloglist.cpp index d39e090c22..429e99f7ad 100644 --- a/indra/newview/llconversationloglist.cpp +++ b/indra/newview/llconversationloglist.cpp @@ -143,22 +143,32 @@ void LLConversationLogList::changed() void LLConversationLogList::changed(const LLUUID& session_id, U32 mask) { - if (mask & LLConversationLogObserver::VOICE_STATE) + LLConversationLogListItem* item = getConversationLogListItem(session_id); + + if (!item) { - std::vector<LLPanel*> panels; - LLFlatListViewEx::getItems(panels); + return; + } - std::vector<LLPanel*>::iterator iter = panels.begin(); + if (mask & LLConversationLogObserver::CHANGED_TIME) + { + item->updateTimestamp(); - for (; iter != panels.end(); ++iter) + // if list is sorted by date and a date of some item has changed, + // than the whole list should be rebuilt + if (E_SORT_BY_DATE == getSortOrder()) { - LLConversationLogListItem* item = dynamic_cast<LLConversationLogListItem*>(*iter); - - if (item && session_id == item->getConversation()->getSessionID() && !item->getConversation()->isConversationPast()) - { - item->initIcons(); - return; - } + mIsDirty = true; + } + } + else if (mask & LLConversationLogObserver::CHANGED_NAME) + { + item->updateName(); + // if list is sorted by name and a name of some item has changed, + // than the whole list should be rebuilt + if (E_SORT_BY_DATE == getSortOrder()) + { + mIsDirty = true; } } } @@ -401,6 +411,29 @@ const LLConversation* LLConversationLogList::getSelectedConversation() return NULL; } +LLConversationLogListItem* LLConversationLogList::getConversationLogListItem(const LLUUID& session_id) +{ + std::vector<LLPanel*> panels; + LLFlatListViewEx::getItems(panels); + std::vector<LLPanel*>::iterator iter = panels.begin(); + + for (; iter != panels.end(); ++iter) + { + LLConversationLogListItem* item = dynamic_cast<LLConversationLogListItem*>(*iter); + if (item && session_id == item->getConversation()->getSessionID()) + { + return item; + } + } + + return NULL; +} + +LLConversationLogList::ESortOrder LLConversationLogList::getSortOrder() +{ + return static_cast<ESortOrder>(gSavedSettings.getU32("CallLogSortOrder")); +} + bool LLConversationLogListItemComparator::compare(const LLPanel* item1, const LLPanel* item2) const { const LLConversationLogListItem* conversation_item1 = dynamic_cast<const LLConversationLogListItem*>(item1); diff --git a/indra/newview/llconversationloglist.h b/indra/newview/llconversationloglist.h index 5e7fc0a9fb..62ec57e09e 100644 --- a/indra/newview/llconversationloglist.h +++ b/indra/newview/llconversationloglist.h @@ -43,6 +43,12 @@ class LLConversationLogList: public LLFlatListViewEx, public LLConversationLogOb { LOG_CLASS(LLConversationLogList); public: + + typedef enum e_sort_oder{ + E_SORT_BY_NAME = 0, + E_SORT_BY_DATE = 1, + } ESortOrder; + struct Params : public LLInitParam::Block<Params, LLFlatListViewEx::Params> { Params(){}; @@ -90,6 +96,9 @@ private: LLIMModel::LLIMSession::SType getSelectedSessionType(); const LLConversationLogListItem* getSelectedConversationPanel(); const LLConversation* getSelectedConversation(); + LLConversationLogListItem* getConversationLogListItem(const LLUUID& session_id); + + ESortOrder getSortOrder(); LLHandle<LLToggleableMenu> mContextMenu; bool mIsDirty; diff --git a/indra/newview/llconversationloglistitem.cpp b/indra/newview/llconversationloglistitem.cpp index dddf216592..fac6130371 100644 --- a/indra/newview/llconversationloglistitem.cpp +++ b/indra/newview/llconversationloglistitem.cpp @@ -117,6 +117,16 @@ void LLConversationLogListItem::initIcons() } } +void LLConversationLogListItem::updateTimestamp() +{ + mConversationDate->setValue(mConversation->getTimestamp()); +} + +void LLConversationLogListItem::updateName() +{ + mConversationName->setValue(mConversation->getConversationName()); +} + void LLConversationLogListItem::onMouseEnter(S32 x, S32 y, MASK mask) { getChildView("hovered_icon")->setVisible(true); diff --git a/indra/newview/llconversationloglistitem.h b/indra/newview/llconversationloglistitem.h index 2aaafa0fba..1bf7a0ed93 100644 --- a/indra/newview/llconversationloglistitem.h +++ b/indra/newview/llconversationloglistitem.h @@ -64,10 +64,16 @@ public: void onDoubleClick(); - void initIcons(); + /** + * updates string value of last interaction time from conversation + */ + void updateTimestamp(); + void updateName(); private: + void initIcons(); + const LLConversation* mConversation; LLTextBox* mConversationName; diff --git a/indra/newview/llconversationmodel.cpp b/indra/newview/llconversationmodel.cpp index 51a37fe856..c36c3cbc65 100644 --- a/indra/newview/llconversationmodel.cpp +++ b/indra/newview/llconversationmodel.cpp @@ -78,14 +78,6 @@ void LLConversationItem::showProperties(void) { } -bool LLConversationSort::operator()(const LLConversationItem* const& a, const LLConversationItem* const& b) const -{ - // We compare only by name for the moment - // *TODO : Implement the sorting by date - S32 compare = LLStringUtil::compareDict(a->getDisplayName(), b->getDisplayName()); - return (compare < 0); -} - // // LLConversationItemSession // @@ -202,12 +194,38 @@ void LLConversationItemParticipant::onAvatarNameCache(const LLAvatarName& av_nam { mName = av_name.mDisplayName; // *TODO : we should also store that one, to be used in the tooltip : av_name.mUsername - // *TODO : we need to request or initiate a list resort mNeedsRefresh = true; + if (mParent) + { + mParent->requestSort(); + } } void LLConversationItemParticipant::dumpDebugData() { llinfos << "Merov debug : participant, uuid = " << mUUID << ", name = " << mName << ", muted = " << mIsMuted << ", moderator = " << mIsModerator << llendl; -} +} + +// +// LLConversationSort +// + +bool LLConversationSort::operator()(const LLConversationItem* const& a, const LLConversationItem* const& b) const +{ + // For the moment, we sort only by name + // *TODO : Implement the sorting by date as well (most recent first) + // *TODO : Check the type of item (session/participants) as order should be different for both (eventually) + S32 compare = LLStringUtil::compareDict(a->getDisplayName(), b->getDisplayName()); + return (compare < 0); +} + +// +// LLConversationViewModel +// + +void LLConversationViewModel::sort(LLFolderViewFolder* folder) +{ + base_t::sort(folder); +} + // EOF diff --git a/indra/newview/llconversationmodel.h b/indra/newview/llconversationmodel.h index e5c727feae..f95db9a9d7 100644 --- a/indra/newview/llconversationmodel.h +++ b/indra/newview/llconversationmodel.h @@ -210,23 +210,14 @@ private: class LLConversationSort { public: - LLConversationSort(U32 order = 0) - : mSortOrder(order), - mByDate(false), - mByName(false) - { - mByDate = (order & LLConversationFilter::SO_DATE); - mByName = (order & LLConversationFilter::SO_NAME); - } + LLConversationSort(U32 order = 0) : mSortOrder(order) { } - bool isByDate() const { return mByDate; } + bool isByDate() const { return (mSortOrder & LLConversationFilter::SO_DATE); } U32 getSortOrder() const { return mSortOrder; } bool operator()(const LLConversationItem* const& a, const LLConversationItem* const& b) const; private: U32 mSortOrder; - bool mByDate; - bool mByName; }; class LLConversationViewModel @@ -235,7 +226,7 @@ class LLConversationViewModel public: typedef LLFolderViewModel<LLConversationSort, LLConversationItem, LLConversationItem, LLConversationFilter> base_t; - void sort(LLFolderViewFolder* folder) { } // *TODO : implement conversation sort + void sort(LLFolderViewFolder* folder); bool contentsReady() { return true; } // *TODO : we need to check that participants names are available somewhat bool startDrag(std::vector<LLFolderViewModelItem*>& items) { return false; } // We do not allow drag of conversation items diff --git a/indra/newview/llfloaterconversationlog.cpp b/indra/newview/llfloaterconversationlog.cpp index 4375ce5726..089aec1905 100644 --- a/indra/newview/llfloaterconversationlog.cpp +++ b/indra/newview/llfloaterconversationlog.cpp @@ -45,11 +45,11 @@ BOOL LLFloaterConversationLog::postBuild() switch (gSavedSettings.getU32("CallLogSortOrder")) { - case E_SORT_BY_NAME: + case LLConversationLogList::E_SORT_BY_NAME: mConversationLogList->sortByName(); break; - case E_SORT_BY_DATE: + case LLConversationLogList::E_SORT_BY_DATE: mConversationLogList->sortByDate(); break; } @@ -63,6 +63,13 @@ BOOL LLFloaterConversationLog::postBuild() getChild<LLFilterEditor>("people_filter_input")->setCommitCallback(boost::bind(&LLFloaterConversationLog::onFilterEdit, this, _2)); + LLControlVariable* ctrl = gSavedPerAccountSettings.getControl("LogInstantMessages").get(); + if (ctrl) + { + ctrl->getSignal()->connect(boost::bind(&LLFloaterConversationLog::onCallLoggingEnabledDisabled, this, _2)); + onCallLoggingEnabledDisabled(ctrl->getValue().asBoolean()); + } + return LLFloater::postBuild(); } @@ -87,12 +94,12 @@ void LLFloaterConversationLog::onCustomAction (const LLSD& userdata) if ("sort_by_name" == command_name) { mConversationLogList->sortByName(); - gSavedSettings.setU32("CallLogSortOrder", E_SORT_BY_NAME); + gSavedSettings.setU32("CallLogSortOrder", LLConversationLogList::E_SORT_BY_NAME); } else if ("sort_by_date" == command_name) { mConversationLogList->sortByDate(); - gSavedSettings.setU32("CallLogSortOrder", E_SORT_BY_DATE); + gSavedSettings.setU32("CallLogSortOrder", LLConversationLogList::E_SORT_BY_DATE); } else if ("sort_friends_on_top" == command_name) { @@ -117,11 +124,11 @@ bool LLFloaterConversationLog::isActionChecked(const LLSD& userdata) if ("sort_by_name" == command_name) { - return sort_order == E_SORT_BY_NAME; + return sort_order == LLConversationLogList::E_SORT_BY_NAME; } else if ("sort_by_date" == command_name) { - return sort_order == E_SORT_BY_DATE; + return sort_order == LLConversationLogList::E_SORT_BY_DATE; } else if ("sort_friends_on_top" == command_name) { @@ -130,3 +137,9 @@ bool LLFloaterConversationLog::isActionChecked(const LLSD& userdata) return false; } + +void LLFloaterConversationLog::onCallLoggingEnabledDisabled(bool enabled) +{ + std::string no_items_msg = enabled ? "" : getString("logging_calls_disabled"); + mConversationLogList->setNoItemsCommentText(no_items_msg); +} diff --git a/indra/newview/llfloaterconversationlog.h b/indra/newview/llfloaterconversationlog.h index 7d788c0290..9e79cbd7d8 100644 --- a/indra/newview/llfloaterconversationlog.h +++ b/indra/newview/llfloaterconversationlog.h @@ -34,11 +34,6 @@ class LLFloaterConversationLog : public LLFloater { public: - typedef enum e_sort_oder{ - E_SORT_BY_NAME = 0, - E_SORT_BY_DATE = 1, - } ESortOrder; - LLFloaterConversationLog(const LLSD& key); virtual ~LLFloaterConversationLog(){}; @@ -54,6 +49,8 @@ private: bool isActionEnabled(const LLSD& userdata); bool isActionChecked(const LLSD& userdata); + void onCallLoggingEnabledDisabled(bool enabled); + LLConversationLogList* mConversationLogList; }; diff --git a/indra/newview/llfloaterconversationpreview.cpp b/indra/newview/llfloaterconversationpreview.cpp index c9d9d7aa3b..88efc39764 100644 --- a/indra/newview/llfloaterconversationpreview.cpp +++ b/indra/newview/llfloaterconversationpreview.cpp @@ -65,9 +65,11 @@ BOOL LLFloaterConversationPreview::postBuild() std::string title = getString("Title", args); setTitle(title); - getChild<LLLineEditor>("description")->setValue(name); + LLSD load_params; + load_params["load_all_history"] = true; + load_params["cut_off_todays_date"] = false; - LLLogChat::loadChatHistory(file, mMessages, true); + LLLogChat::loadChatHistory(file, mMessages, load_params); mCurrentPage = mMessages.size() / mPageSize; mPageSpinner = getChild<LLSpinCtrl>("history_page_spin"); @@ -138,7 +140,7 @@ void LLFloaterConversationPreview::showHistory() void LLFloaterConversationPreview::onMoreHistoryBtnClick() { - mCurrentPage = mPageSpinner->getValueF32(); + mCurrentPage = (int)(mPageSpinner->getValueF32()); if (--mCurrentPage < 0) { return; diff --git a/indra/newview/llimfloatercontainer.cpp b/indra/newview/llimfloatercontainer.cpp index 79009942bf..6aa7a2e054 100644 --- a/indra/newview/llimfloatercontainer.cpp +++ b/indra/newview/llimfloatercontainer.cpp @@ -46,6 +46,7 @@ #include "lltransientfloatermgr.h" #include "llviewercontrol.h" #include "llconversationview.h" +#include "llcallbacklist.h" // // LLIMFloaterContainer @@ -67,6 +68,8 @@ LLIMFloaterContainer::LLIMFloaterContainer(const LLSD& seed) LLIMFloaterContainer::~LLIMFloaterContainer() { + gIdleCallbacks.deleteFunction(idle, this); + mNewMessageConnection.disconnect(); LLTransientFloaterMgr::getInstance()->removeControlView(LLTransientFloaterMgr::IM, this); @@ -118,7 +121,7 @@ BOOL LLIMFloaterContainer::postBuild() mConversationsListPanel = getChild<LLPanel>("conversations_list_panel"); - // CHUI-98 : View Model for conversations + // Create the root model and view for all conversation sessions LLConversationItem* base_item = new LLConversationItem(getRootViewModel()); LLFolderView::Params p(LLUICtrlFactory::getDefaultParams<LLFolderView>()); @@ -171,6 +174,10 @@ BOOL LLIMFloaterContainer::postBuild() gIdleCallbacks.addFunction(idle, (void*)this); mInitialized = true; + + // Add callback: we'll take care of view updates on idle + gIdleCallbacks.addFunction(idle, this); + return TRUE; } @@ -383,6 +390,13 @@ void LLIMFloaterContainer::draw() } } + // CHUI-308 : Hack! We shouldn't have to do that but we have too as long as + // we don't have a scroll container. + // *TODO: Take those 3 lines out once we implement the scroll container. + repositioningWidgets(); + mConversationsRoot->setRect(mConversationsListPanel->getLocalRect()); + mConversationsRoot->setFollowsAll(); + if (mTabContainer->getTabCount() == 0) { // Do not close the container when every conversation is torn off because the user @@ -496,6 +510,13 @@ void LLIMFloaterContainer::updateState(bool collapse, S32 delta_width) setCanResize(is_left_pane_expanded || is_right_pane_expanded); setCanMinimize(is_left_pane_expanded || is_right_pane_expanded); + // force set correct size for the title after show/hide minimize button + LLRect cur_rect = getRect(); + LLRect force_rect = cur_rect; + force_rect.mRight = cur_rect.mRight + 1; + setRect(force_rect); + setRect(cur_rect); + // restore floater's resize limits (prevent collapse when left panel is expanded) if (is_left_pane_expanded && !is_right_pane_expanded) { @@ -625,7 +646,7 @@ void LLIMFloaterContainer::addConversationListItem(const LLUUID& uuid) } if (!item) { - llinfos << "Merov debug : Couldn't create conversation session item : " << display_name << llendl; + llwarns << "Couldn't create conversation session item : " << display_name << llendl; return; } // *TODO: Should we flag LLConversationItemSession with a mIsNearbyChat? @@ -645,7 +666,6 @@ void LLIMFloaterContainer::addConversationListItem(const LLUUID& uuid) // 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); diff --git a/indra/newview/llimfloatercontainer.h b/indra/newview/llimfloatercontainer.h index 427baa03e3..bda1ce0cb1 100644 --- a/indra/newview/llimfloatercontainer.h +++ b/indra/newview/llimfloatercontainer.h @@ -77,6 +77,8 @@ public: void collapseMessagesPane(bool collapse); + // Callbacks + 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); diff --git a/indra/newview/lllogchat.cpp b/indra/newview/lllogchat.cpp index 073f5f00c5..3692658e9e 100644 --- a/indra/newview/lllogchat.cpp +++ b/indra/newview/lllogchat.cpp @@ -387,13 +387,16 @@ void append_to_last_message(std::list<LLSD>& messages, const std::string& line) } // static -void LLLogChat::loadChatHistory(const std::string& file_name, std::list<LLSD>& messages, bool load_all_history/*= false*/) +void LLLogChat::loadChatHistory(const std::string& file_name, std::list<LLSD>& messages, const LLSD& load_params) { if (file_name.empty()) { llwarns << "Session name is Empty!" << llendl; return ; } + + bool load_all_history = load_params.has("load_all_history") ? load_params["load_all_history"].asBoolean() : false; + //LL_INFOS("") << "Loading:" << file_name << LL_ENDL;/* uncomment if you want to verify step, delete on commit */ //LL_INFOS("") << "Current:" << makeLogFileName(file_name) << LL_ENDL;/* uncomment if you want to verify step, delete on commit */ LLFILE* fptr = LLFile::fopen(makeLogFileName(file_name), "r");/*Flawfinder: ignore*/ @@ -449,7 +452,7 @@ void LLLogChat::loadChatHistory(const std::string& file_name, std::list<LLSD>& m else { LLSD item; - if (!LLChatLogParser::parse(line, item)) + if (!LLChatLogParser::parse(line, item, load_params)) { item[IM_TEXT] = line; } @@ -500,10 +503,11 @@ void LLChatLogFormatter::format(const LLSD& im, std::ostream& ostr) const } } -bool LLChatLogParser::parse(std::string& raw, LLSD& im) +bool LLChatLogParser::parse(std::string& raw, LLSD& im, const LLSD& parse_params) { if (!raw.length()) return false; + bool cut_off_todays_date = parse_params.has("cut_off_todays_date") ? parse_params["cut_off_todays_date"].asBoolean() : true; im = LLSD::emptyMap(); //matching a timestamp @@ -518,7 +522,12 @@ bool LLChatLogParser::parse(std::string& raw, LLSD& im) boost::trim(timestamp); timestamp.erase(0, 1); timestamp.erase(timestamp.length()-1, 1); - LLLogChatTimeScanner::instance().checkAndCutOffDate(timestamp); + + if (cut_off_todays_date) + { + LLLogChatTimeScanner::instance().checkAndCutOffDate(timestamp); + } + im[IM_TIME] = timestamp; } else diff --git a/indra/newview/lllogchat.h b/indra/newview/lllogchat.h index 95f83e64e5..d3e9adcc37 100644 --- a/indra/newview/lllogchat.h +++ b/indra/newview/lllogchat.h @@ -55,7 +55,7 @@ public: void (*callback)(ELogLineType, const LLSD&, void*), void* userdata); - static void loadChatHistory(const std::string& file_name, std::list<LLSD>& messages, bool load_all_history = false); + static void loadChatHistory(const std::string& file_name, std::list<LLSD>& messages, const LLSD& load_params = LLSD()); private: static std::string cleanFileName(std::string filename); }; @@ -105,7 +105,7 @@ public: * * @return false if failed to parse mandatory data - message text */ - static bool parse(std::string& raw, LLSD& im); + static bool parse(std::string& raw, LLSD& im, const LLSD& parse_params = LLSD()); protected: LLChatLogParser(); diff --git a/indra/newview/llparticipantlist.cpp b/indra/newview/llparticipantlist.cpp index 2282734109..0d1a37c835 100644 --- a/indra/newview/llparticipantlist.cpp +++ b/indra/newview/llparticipantlist.cpp @@ -675,8 +675,6 @@ void LLParticipantList::addAvatarIDExceptAgent(const LLUUID& avatar_id) // *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); diff --git a/indra/newview/skins/default/xui/en/floater_conversation_log.xml b/indra/newview/skins/default/xui/en/floater_conversation_log.xml index 9cdeb0d788..df78bbccec 100644 --- a/indra/newview/skins/default/xui/en/floater_conversation_log.xml +++ b/indra/newview/skins/default/xui/en/floater_conversation_log.xml @@ -13,6 +13,11 @@ reuse_instance="true" title="CONVERSATION LOG" width="450"> + + <string name="logging_calls_disabled"> + Conversations are not being logged. To log conversations in the future, select "Save IM logs in my computer" under Preferences > Privacy. + </string> + <panel follows="left|top|right" height="27" diff --git a/indra/newview/skins/default/xui/en/floater_conversation_preview.xml b/indra/newview/skins/default/xui/en/floater_conversation_preview.xml index d74c2c252d..0e5af67f68 100644 --- a/indra/newview/skins/default/xui/en/floater_conversation_preview.xml +++ b/indra/newview/skins/default/xui/en/floater_conversation_preview.xml @@ -14,41 +14,17 @@ name="Title"> CONVERSATION: [NAME] </floater.string> - <text - type="string" - length="1" - follows="left|top" - font="SansSerif" - height="19" - layout="topleft" - left="10" - name="desc txt" - top="22" - width="90"> - Description: - </text> - <line_editor - border_style="line" - border_thickness="1" - enabled="false" - follows="left|top|right" - font="SansSerif" - height="22" - layout="topleft" - left_pad="0" - max_length_bytes="127" - name="description" - width="296" /> <chat_history font="SansSerifSmall" follows="all" visible="true" - height="310" + height="330" name="chat_history" notify_unread_msg="false" parse_highlights="true" parse_urls="true" left="5" + top_pad="25" width="390"> </chat_history> <text @@ -63,6 +39,7 @@ width="35"> </text> <spinner + allow_digits_only="true" decimal_digits="0" follows="bottom|right" height="23" diff --git a/indra/newview/skins/default/xui/en/floater_im_container.xml b/indra/newview/skins/default/xui/en/floater_im_container.xml index 1583add857..413e66738d 100644 --- a/indra/newview/skins/default/xui/en/floater_im_container.xml +++ b/indra/newview/skins/default/xui/en/floater_im_container.xml @@ -36,7 +36,7 @@ name="conversations_layout_panel" min_dim="38" width="268" - expanded_min_dim="165"> + expanded_min_dim="120"> <layout_stack animate="false" follows="left|top|right" |