diff options
author | Richard Linden <none@none> | 2012-03-29 23:48:29 -0700 |
---|---|---|
committer | Richard Linden <none@none> | 2012-03-29 23:48:29 -0700 |
commit | 2fa1c42aadbe2a29e1bcced9a487c0e5abf0602b (patch) | |
tree | 08d9ebd23121654a9cf4e0561b1256de9bc9b608 | |
parent | 1ea65f0285d7022ce20ef84d4e35e3c94bcb3fbd (diff) |
CHUI-51 WIP notifications routig code cleanup
phase 2, removal of extraneous signaling in favor of llnotificationchannels
made notificationchannels work better with overrides and lifetime managed
by creator
21 files changed, 241 insertions, 323 deletions
diff --git a/indra/llcommon/llinstancetracker.h b/indra/llcommon/llinstancetracker.h index 34d841a4e0..11f582372e 100644 --- a/indra/llcommon/llinstancetracker.h +++ b/indra/llcommon/llinstancetracker.h @@ -43,7 +43,7 @@ * semantics: one instance per process, rather than one instance per module as * sometimes happens with data simply declared static. */ -class LL_COMMON_API LLInstanceTrackerBase : public boost::noncopyable +class LL_COMMON_API LLInstanceTrackerBase { protected: /// Get a process-unique void* pointer slot for the specified type_info @@ -209,6 +209,9 @@ protected: virtual const KEY& getKey() const { return mInstanceKey; } private: + LLInstanceTracker( const LLInstanceTracker& ); + const LLInstanceTracker& operator=( const LLInstanceTracker& ); + void add_(KEY key) { mInstanceKey = key; diff --git a/indra/llcommon/llrefcount.h b/indra/llcommon/llrefcount.h index 8eb5d53f3f..32ae15435a 100644 --- a/indra/llcommon/llrefcount.h +++ b/indra/llcommon/llrefcount.h @@ -27,6 +27,7 @@ #define LLREFCOUNT_H #include <boost/noncopyable.hpp> +#include <boost/intrusive_ptr.hpp> #define LL_REF_COUNT_DEBUG 0 #if LL_REF_COUNT_DEBUG @@ -86,4 +87,22 @@ private: #endif }; +/** + * intrusive pointer support + * this allows you to use boost::intrusive_ptr with any LLRefCount-derived type + */ +namespace boost +{ + inline void intrusive_ptr_add_ref(LLRefCount* p) + { + p->ref(); + } + + inline void intrusive_ptr_release(LLRefCount* p) + { + p->unref(); + } +}; + + #endif diff --git a/indra/llcommon/llthread.h b/indra/llcommon/llthread.h index b52e70ab2e..cf39696b4f 100644 --- a/indra/llcommon/llthread.h +++ b/indra/llcommon/llthread.h @@ -30,6 +30,7 @@ #include "llapp.h" #include "llapr.h" #include "apr_thread_cond.h" +#include "boost/intrusive_ptr.hpp" class LLThread; class LLMutex; @@ -266,6 +267,22 @@ private: S32 mRef; }; +/** + * intrusive pointer support for LLThreadSafeRefCount + * this allows you to use boost::intrusive_ptr with any LLThreadSafeRefCount-derived type + */ +namespace boost +{ + inline void intrusive_ptr_add_ref(LLThreadSafeRefCount* p) + { + p->ref(); + } + + inline void intrusive_ptr_release(LLThreadSafeRefCount* p) + { + p->unref(); + } +}; //============================================================================ // Simple responder for self destructing callbacks diff --git a/indra/llui/llnotifications.cpp b/indra/llui/llnotifications.cpp index 038a86d20a..c45899a4bd 100644 --- a/indra/llui/llnotifications.cpp +++ b/indra/llui/llnotifications.cpp @@ -966,7 +966,7 @@ bool LLNotificationChannelBase::updateItem(const LLSD& payload, LLNotificationPt std::string cmd = payload["sigtype"]; LLNotificationSet::iterator foundItem = mItems.find(pNotification); bool wasFound = (foundItem != mItems.end()); - bool passesFilter = mFilter(pNotification); + bool passesFilter = mFilter ? mFilter(pNotification) : true; // first, we offer the result of the filter test to the simple // signals for pass/fail. One of these is guaranteed to be called. @@ -1071,27 +1071,28 @@ bool LLNotificationChannelBase::updateItem(const LLSD& payload, LLNotificationPt return abortProcessing; } +LLNotificationChannel::LLNotificationChannel(const Params& p) +: LLNotificationChannelBase(p.filter(), p.comparator()), + LLInstanceTracker<LLNotificationChannel, std::string>(p.name.isProvided() ? p.name : LLUUID::generateNewID().asString()), + mName(p.name.isProvided() ? p.name : LLUUID::generateNewID().asString()) +{ + BOOST_FOREACH(const std::string& source, p.sources) + { + connectToChannel(source); + } +} + + LLNotificationChannel::LLNotificationChannel(const std::string& name, const std::string& parent, LLNotificationFilter filter, - LLNotificationComparator comparator) : -LLNotificationChannelBase(filter, comparator), -mName(name), -mParent(parent) + LLNotificationComparator comparator) +: LLNotificationChannelBase(filter, comparator), + LLInstanceTracker<LLNotificationChannel, std::string>(name), + mName(name) { - // store myself in the channel map - LLNotifications::instance().addChannel(LLNotificationChannelPtr(this)); // bind to notification broadcast - if (parent.empty()) - { - LLNotifications::instance().connectChanged( - boost::bind(&LLNotificationChannelBase::updateItem, this, _1)); - } - else - { - LLNotificationChannelPtr p = LLNotifications::instance().getChannel(parent); - p->connectChanged(boost::bind(&LLNotificationChannelBase::updateItem, this, _1)); - } + connectToChannel(parent); } @@ -1134,6 +1135,21 @@ std::string LLNotificationChannel::summarize() return s; } +void LLNotificationChannel::connectToChannel( const std::string& channel_name ) +{ + if (channel_name.empty()) + { + LLNotifications::instance().connectChanged( + boost::bind(&LLNotificationChannelBase::updateItem, this, _1)); + } + else + { + LLNotificationChannelPtr p = LLNotifications::instance().getChannel(channel_name); + p->connectChanged(boost::bind(&LLNotificationChannelBase::updateItem, this, _1)); + } +} + + // --- // END OF LLNotificationChannel implementation @@ -1248,21 +1264,9 @@ bool LLNotifications::failedUniquenessTest(const LLSD& payload) return false; } - -void LLNotifications::addChannel(LLNotificationChannelPtr pChan) -{ - mChannels[pChan->getName()] = pChan; -} - LLNotificationChannelPtr LLNotifications::getChannel(const std::string& channelName) { - ChannelMap::iterator p = mChannels.find(channelName); - if(p == mChannels.end()) - { - llerrs << "Did not find channel named " << channelName << llendl; - return LLNotificationChannelPtr(); - } - return p->second; + return LLNotificationChannelPtr(LLNotificationChannel::getInstance(channelName)); } @@ -1278,20 +1282,20 @@ void LLNotifications::createDefaultChannels() { // now construct the various channels AFTER loading the notifications, // because the history channel is going to rewrite the stored notifications file - new LLNotificationChannel("Enabled", "", - !boost::bind(&LLNotifications::getIgnoreAllNotifications, this)); - new LLNotificationChannel("Expiration", "Enabled", - boost::bind(&LLNotifications::expirationFilter, this, _1)); - new LLNotificationChannel("Unexpired", "Enabled", - !boost::bind(&LLNotifications::expirationFilter, this, _1)); // use negated bind - new LLNotificationChannel("Unique", "Unexpired", - boost::bind(&LLNotifications::uniqueFilter, this, _1)); - new LLNotificationChannel("Ignore", "Unique", - filterIgnoredNotifications); - new LLNotificationChannel("VisibilityRules", "Ignore", - boost::bind(&LLNotifications::isVisibleByRules, this, _1)); - new LLNotificationChannel("Visible", "VisibilityRules", - &LLNotificationFilters::includeEverything); + mDefaultChannels.push_back(new LLNotificationChannel("Enabled", "", + !boost::bind(&LLNotifications::getIgnoreAllNotifications, this))); + mDefaultChannels.push_back(new LLNotificationChannel("Expiration", "Enabled", + boost::bind(&LLNotifications::expirationFilter, this, _1))); + mDefaultChannels.push_back(new LLNotificationChannel("Unexpired", "Enabled", + !boost::bind(&LLNotifications::expirationFilter, this, _1))); // use negated bind + mDefaultChannels.push_back(new LLNotificationChannel("Unique", "Unexpired", + boost::bind(&LLNotifications::uniqueFilter, this, _1))); + mDefaultChannels.push_back(new LLNotificationChannel("Ignore", "Unique", + filterIgnoredNotifications)); + mDefaultChannels.push_back(new LLNotificationChannel("VisibilityRules", "Ignore", + boost::bind(&LLNotifications::isVisibleByRules, this, _1))); + mDefaultChannels.push_back(new LLNotificationChannel("Visible", "VisibilityRules", + &LLNotificationFilters::includeEverything)); // create special persistent notification channel // this isn't a leak, don't worry about the empty "new" diff --git a/indra/llui/llnotifications.h b/indra/llui/llnotifications.h index f83365a97d..344108ecbf 100644 --- a/indra/llui/llnotifications.h +++ b/indra/llui/llnotifications.h @@ -94,10 +94,11 @@ // and we need this to manage the notification callbacks #include "llevents.h" #include "llfunctorregistry.h" -#include "llpointer.h" #include "llinitparam.h" #include "llnotificationslistener.h" #include "llnotificationptr.h" +#include "llpointer.h" +#include "llrefcount.h" class LLAvatarName; typedef enum e_notification_priority @@ -707,7 +708,8 @@ typedef std::multimap<std::string, LLNotificationPtr> LLNotificationMap; // all of the built-in tests should attach to the "Visible" channel // class LLNotificationChannelBase : - public LLEventTrackable + public LLEventTrackable, + public LLRefCount { LOG_CLASS(LLNotificationChannelBase); public: @@ -787,26 +789,48 @@ protected: // destroy it, but if it becomes necessary to do so, the shared_ptr model // will ensure that we don't leak resources. class LLNotificationChannel; -typedef boost::shared_ptr<LLNotificationChannel> LLNotificationChannelPtr; +typedef boost::intrusive_ptr<LLNotificationChannel> LLNotificationChannelPtr; // manages a list of notifications // Note that if this is ever copied around, we might find ourselves with multiple copies // of a queue with notifications being added to different nonequivalent copies. So we -// make it inherit from boost::noncopyable, and then create a map of shared_ptr to manage it. +// make it inherit from boost::noncopyable, and then create a map of LLPointer to manage it. // class LLNotificationChannel : boost::noncopyable, - public LLNotificationChannelBase + public LLNotificationChannelBase, + public LLInstanceTracker<LLNotificationChannel, std::string> { LOG_CLASS(LLNotificationChannel); public: + // Notification Channels have a filter, which determines which notifications + // will be added to this channel. + // Channel filters cannot change. + struct Params : public LLInitParam::Block<Params> + { + Mandatory<std::string> name; + Optional<LLNotificationFilter> filter; + Optional<LLNotificationComparator> comparator; + Multiple<std::string> sources; + + Params() + : comparator("", LLNotificationComparators::orderByUUID()) + {} + }; + + LLNotificationChannel(const Params& p = Params()); + + LLNotificationChannel(const std::string& name, const std::string& parent, + LLNotificationFilter filter, LLNotificationComparator comparator=LLNotificationComparators::orderByUUID()); + virtual ~LLNotificationChannel() {} typedef LLNotificationSet::iterator Iterator; std::string getName() const { return mName; } - std::string getParentChannelName() { return mParent; } + void connectToChannel(const std::string& channel_name); + bool isEmpty() const; Iterator begin(); @@ -818,14 +842,6 @@ public: std::string summarize(); - // Notification Channels have a filter, which determines which notifications - // will be added to this channel. - // Channel filters cannot change. - // Channels have a protected constructor so you can't make smart pointers that don't - // come from our internal reference; call NotificationChannel::build(args) - LLNotificationChannel(const std::string& name, const std::string& parent, - LLNotificationFilter filter, LLNotificationComparator comparator=LLNotificationComparators::orderByUUID()); - private: std::string mName; std::string mParent; @@ -912,10 +928,6 @@ public: void createDefaultChannels(); - typedef std::map<std::string, LLNotificationChannelPtr> ChannelMap; - ChannelMap mChannels; - - void addChannel(LLNotificationChannelPtr pChan); LLNotificationChannelPtr getChannel(const std::string& channelName); std::string getGlobalString(const std::string& key) const; @@ -954,6 +966,7 @@ private: bool mIgnoreAllNotifications; boost::scoped_ptr<LLNotificationsListener> mListener; + std::vector<LLNotificationChannelPtr> mDefaultChannels; }; /** diff --git a/indra/llui/llnotificationslistener.cpp b/indra/llui/llnotificationslistener.cpp index 3bbeb3a778..e4e127336b 100644 --- a/indra/llui/llnotificationslistener.cpp +++ b/indra/llui/llnotificationslistener.cpp @@ -121,13 +121,13 @@ void LLNotificationsListener::listChannels(const LLSD& params) const { LLReqID reqID(params); LLSD response(reqID.makeResponse()); - for (LLNotifications::ChannelMap::const_iterator cmi(mNotifications.mChannels.begin()), - cmend(mNotifications.mChannels.end()); + for (LLNotificationChannel::instance_iter cmi(LLNotificationChannel::beginInstances()), + cmend(LLNotificationChannel::endInstances()); cmi != cmend; ++cmi) { LLSD channelInfo; - channelInfo["parent"] = cmi->second->getParentChannelName(); - response[cmi->first] = channelInfo; + //channelInfo["parent"] = cmi->second->getParentChannelName(); + response[cmi->getName()] = channelInfo; } LLEventPumps::instance().obtain(params["reply"]).post(response); } diff --git a/indra/newview/llchiclet.cpp b/indra/newview/llchiclet.cpp index 9f19f8dd1c..67519a3ca6 100644 --- a/indra/newview/llchiclet.cpp +++ b/indra/newview/llchiclet.cpp @@ -335,29 +335,15 @@ void LLIMWellChiclet::messageCountChanged(const LLSD& session_data) /* LLNotificationChiclet implementation */ /************************************************************************/ LLNotificationChiclet::LLNotificationChiclet(const Params& p) -: LLSysWellChiclet(p) -, mUreadSystemNotifications(0) +: LLSysWellChiclet(p), + mUreadSystemNotifications(0) { - // connect counter handlers to the signals - connectCounterUpdatersToSignal("Notify"); - connectCounterUpdatersToSignal("Group Notify"); - connectCounterUpdatersToSignal("Offer"); - + mNotificationChannel.reset(new ChicletNotificationChannel(this)); // ensure that notification well window exists, to synchronously // handle toast add/delete events. LLNotificationWellWindow::getInstance()->setSysWellChiclet(this); } -void LLNotificationChiclet::connectCounterUpdatersToSignal(const std::string& notification_type) -{ - LLNotificationsUI::LLEventHandler* n_handler = dynamic_cast<LLNotificationsUI::LLEventHandler*>(LLNotifications::instance().getChannel(notification_type).get()); - if(n_handler) - { - n_handler->setNewNotificationCallback(boost::bind(&LLNotificationChiclet::incUreadSystemNotifications, this)); - n_handler->setDelNotification(boost::bind(&LLNotificationChiclet::decUreadSystemNotifications, this)); - } -} - void LLNotificationChiclet::onMenuItemClicked(const LLSD& user_data) { std::string action = user_data.asString(); @@ -406,6 +392,12 @@ void LLNotificationChiclet::setCounter(S32 counter) updateWidget(getCounter() == 0); } + +bool LLNotificationChiclet::ChicletNotificationChannel::filterNotification( LLNotificationPtr notify ) +{ + return !(notify->canLogToIM() && notify->hasFormElements()); +} + ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// diff --git a/indra/newview/llchiclet.h b/indra/newview/llchiclet.h index 1f1069dcb4..dd0d47cccd 100644 --- a/indra/newview/llchiclet.h +++ b/indra/newview/llchiclet.h @@ -34,6 +34,7 @@ #include "lloutputmonitorctrl.h" #include "llgroupmgr.h" #include "llimview.h" +#include "llnotifications.h" class LLMenuGL; class LLIMFloater; @@ -911,11 +912,35 @@ protected: class LLNotificationChiclet : public LLSysWellChiclet { + LOG_CLASS(LLNotificationChiclet); + friend class LLUICtrlFactory; public: struct Params : public LLInitParam::Block<Params, LLSysWellChiclet::Params>{}; protected: + struct ChicletNotificationChannel : public LLNotificationChannel + { + ChicletNotificationChannel(LLNotificationChiclet* chiclet) + : LLNotificationChannel(LLNotificationChannel::Params().filter(filterNotification).name(chiclet->getSessionId().asString())), + mChiclet(chiclet) + { + // connect counter handlers to the signals + connectToChannel("IM Notifications"); + connectToChannel("Group Notifications"); + connectToChannel("Offer"); + } + + static bool filterNotification(LLNotificationPtr notify); + // connect counter updaters to the corresponding signals + /*virtual*/ void onAdd(LLNotificationPtr p) { mChiclet->setCounter(++mChiclet->mUreadSystemNotifications); } + /*virtual*/ void onDelete(LLNotificationPtr p) { mChiclet->setCounter(--mChiclet->mUreadSystemNotifications); } + + LLNotificationChiclet* const mChiclet; + }; + + boost::scoped_ptr<ChicletNotificationChannel> mNotificationChannel; + LLNotificationChiclet(const Params& p); /** @@ -933,12 +958,6 @@ protected: */ /*virtual*/ void createMenu(); - // connect counter updaters to the corresponding signals - void connectCounterUpdatersToSignal(const std::string& notification_type); - - // methods for updating a number of unread System notifications - void incUreadSystemNotifications() { setCounter(++mUreadSystemNotifications); } - void decUreadSystemNotifications() { setCounter(--mUreadSystemNotifications); } /*virtual*/ void setCounter(S32 counter); S32 mUreadSystemNotifications; }; diff --git a/indra/newview/llfloaternotificationsconsole.cpp b/indra/newview/llfloaternotificationsconsole.cpp index 90dbabebfb..4f35c325a8 100644 --- a/indra/newview/llfloaternotificationsconsole.cpp +++ b/indra/newview/llfloaternotificationsconsole.cpp @@ -44,21 +44,16 @@ public: BOOL postBuild(); private: - bool update(const LLSD& payload, bool passed_filter); + bool update(const LLSD& payload); static void toggleClick(void* user_data); static void onClickNotification(void* user_data); - static void onClickNotificationReject(void* user_data); LLNotificationChannelPtr mChannelPtr; - LLNotificationChannelPtr mChannelRejectsPtr; }; LLNotificationChannelPanel::LLNotificationChannelPanel(const LLNotificationChannelPanel::Params& p) : LLLayoutPanel(p) { mChannelPtr = LLNotifications::instance().getChannel(p.name); - mChannelRejectsPtr = LLNotificationChannelPtr( - new LLNotificationChannel(p.name() + "rejects", mChannelPtr->getParentChannelName(), - !boost::bind(mChannelPtr->getFilter(), _1))); buildFromFile( "panel_notifications_channel.xml"); } @@ -68,15 +63,11 @@ BOOL LLNotificationChannelPanel::postBuild() header_button->setLabel(mChannelPtr->getName()); header_button->setClickedCallback(toggleClick, this); - mChannelPtr->connectChanged(boost::bind(&LLNotificationChannelPanel::update, this, _1, true)); - mChannelRejectsPtr->connectChanged(boost::bind(&LLNotificationChannelPanel::update, this, _1, false)); + mChannelPtr->connectChanged(boost::bind(&LLNotificationChannelPanel::update, this, _1)); LLScrollListCtrl* scroll = getChild<LLScrollListCtrl>("notifications_list"); scroll->setDoubleClickCallback(onClickNotification, this); scroll->setRect(LLRect( getRect().mLeft, getRect().mTop, getRect().mRight, 0)); - scroll = getChild<LLScrollListCtrl>("notification_rejects_list"); - scroll->setDoubleClickCallback(onClickNotificationReject, this); - scroll->setRect(LLRect( getRect().mLeft, getRect().mTop, getRect().mRight, 0)); return TRUE; } @@ -97,8 +88,6 @@ void LLNotificationChannelPanel::toggleClick(void *user_data) // turn off tab stop for collapsed panel self->getChild<LLScrollListCtrl>("notifications_list")->setTabStop(!header_button->getToggleState()); self->getChild<LLScrollListCtrl>("notifications_list")->setVisible(!header_button->getToggleState()); - self->getChild<LLScrollListCtrl>("notification_rejects_list")->setTabStop(!header_button->getToggleState()); - self->getChild<LLScrollListCtrl>("notification_rejects_list")->setVisible(!header_button->getToggleState()); } /*static*/ @@ -118,24 +107,7 @@ void LLNotificationChannelPanel::onClickNotification(void* user_data) } } -/*static*/ -void LLNotificationChannelPanel::onClickNotificationReject(void* user_data) -{ - LLNotificationChannelPanel* self = (LLNotificationChannelPanel*)user_data; - if (!self) return; - LLScrollListItem* firstselected = self->getChild<LLScrollListCtrl>("notification_rejects_list")->getFirstSelected(); - llassert(firstselected); - if (firstselected) - { - void* data = firstselected->getUserdata(); - if (data) - { - gFloaterView->getParentFloater(self)->addDependentFloater(new LLFloaterNotification((LLNotification*)data), TRUE); - } - } -} - -bool LLNotificationChannelPanel::update(const LLSD& payload, bool passed_filter) +bool LLNotificationChannelPanel::update(const LLSD& payload) { LLNotificationPtr notification = LLNotifications::instance().find(payload["id"].asUUID()); if (notification) @@ -151,9 +123,7 @@ bool LLNotificationChannelPanel::update(const LLSD& payload, bool passed_filter) row["columns"][2]["column"] = "date"; row["columns"][2]["type"] = "date"; - LLScrollListItem* sli = passed_filter ? - getChild<LLScrollListCtrl>("notifications_list")->addElement(row) : - getChild<LLScrollListCtrl>("notification_rejects_list")->addElement(row); + LLScrollListItem* sli = getChild<LLScrollListCtrl>("notifications_list")->addElement(row); sli->setUserdata(&(*notification)); } diff --git a/indra/newview/llimhandler.cpp b/indra/newview/llimhandler.cpp index a92c4fa387..1437d0747c 100644 --- a/indra/newview/llimhandler.cpp +++ b/indra/newview/llimhandler.cpp @@ -95,24 +95,12 @@ bool LLIMHandler::processNotification(const LLNotificationPtr& notification) p.notification = notification; p.panel = im_box; p.can_be_stored = false; - p.on_delete_toast = boost::bind(&LLIMHandler::onDeleteToast, this, _1); LLScreenChannel* channel = dynamic_cast<LLScreenChannel*>(mChannel); if(channel) channel->addToast(p); - // send a signal to the counter manager; - mNewNotificationSignal(); - return false; } -//-------------------------------------------------------------------------- -void LLIMHandler::onDeleteToast(LLToast* toast) -{ - // send a signal to the counter manager - mDelNotificationSignal(); -} - -//-------------------------------------------------------------------------- diff --git a/indra/newview/llnotificationgrouphandler.cpp b/indra/newview/llnotificationgrouphandler.cpp index 2ce51fa094..97e382e42f 100644 --- a/indra/newview/llnotificationgrouphandler.cpp +++ b/indra/newview/llnotificationgrouphandler.cpp @@ -87,26 +87,12 @@ bool LLGroupHandler::processNotification(const LLNotificationPtr& notification) if(channel) channel->addToast(p); - // send a signal to the counter manager - mNewNotificationSignal(); - LLGroupActions::refresh_notices(); return false; } //-------------------------------------------------------------------------- -void LLGroupHandler::onDeleteToast(LLToast* toast) -{ - // send a signal to the counter manager - mDelNotificationSignal(); - - // send a signal to a listener to let him perform some action - // in this case listener is a SysWellWindow and it will remove a corresponding item from its list - mNotificationIDSignal(toast->getNotificationID()); -} - -//-------------------------------------------------------------------------- void LLGroupHandler::onRejectToast(LLUUID& id) { LLNotificationPtr notification = LLNotifications::instance().find(id); diff --git a/indra/newview/llnotificationhandler.h b/indra/newview/llnotificationhandler.h index ff9371f7df..419b8a14b6 100644 --- a/indra/newview/llnotificationhandler.h +++ b/indra/newview/llnotificationhandler.h @@ -67,19 +67,6 @@ class LLEventHandler public: virtual ~LLEventHandler() {}; - // callbacks for counters - typedef boost::function<void (void)> notification_callback_t; - typedef boost::signals2::signal<void (void)> notification_signal_t; - notification_signal_t mNewNotificationSignal; - notification_signal_t mDelNotificationSignal; - boost::signals2::connection setNewNotificationCallback(notification_callback_t cb) { return mNewNotificationSignal.connect(cb); } - boost::signals2::connection setDelNotification(notification_callback_t cb) { return mDelNotificationSignal.connect(cb); } - // callback for notification/toast - typedef boost::function<void (const LLUUID id)> notification_id_callback_t; - typedef boost::signals2::signal<void (const LLUUID id)> notification_id_signal_t; - notification_id_signal_t mNotificationIDSignal; - boost::signals2::connection setNotificationIDCallback(notification_id_callback_t cb) { return mNotificationIDSignal.connect(cb); } - protected: virtual void onDeleteToast(LLToast* toast) {} @@ -143,7 +130,6 @@ public: protected: bool processNotification(const LLNotificationPtr& p); - virtual void onDeleteToast(LLToast* toast); virtual void initChannel(); }; @@ -201,7 +187,6 @@ public: virtual bool processNotification(const LLNotificationPtr& p); protected: - virtual void onDeleteToast(LLToast* toast); virtual void initChannel(); // own handlers @@ -244,7 +229,6 @@ public: virtual bool processNotification(const LLNotificationPtr& p); protected: - virtual void onDeleteToast(LLToast* toast); virtual void initChannel(); // own handlers @@ -313,12 +297,7 @@ public: /** * Writes notification message to IM p2p session. */ - static void logToIMP2P(const LLNotificationPtr& notification); - - /** - * Writes notification message to IM p2p session. - */ - static void logToIMP2P(const LLNotificationPtr& notification, bool to_file_only); + static void logToIMP2P(const LLNotificationPtr& notification, bool to_file_only = false); /** * Writes group notice notification message to IM group session. diff --git a/indra/newview/llnotificationhandlerutil.cpp b/indra/newview/llnotificationhandlerutil.cpp index dca7fda151..3ebf0bcc9e 100644 --- a/indra/newview/llnotificationhandlerutil.cpp +++ b/indra/newview/llnotificationhandlerutil.cpp @@ -111,37 +111,18 @@ void LLSysHandler::removeExclusiveNotifications(const LLNotificationPtr& notif) } } -const static std::string OBJECT_GIVE_ITEM("ObjectGiveItem"); - -static LLIMFloater* find_im_floater(const LLNotificationPtr& notification) -{ - LLUUID from_id = notification->getPayload()["from_id"]; - LLUUID session_id = LLIMMgr::computeSessionID(IM_NOTHING_SPECIAL, from_id); - return LLFloaterReg::findTypedInstance<LLIMFloater>("impanel", session_id); -} - // static bool LLHandlerUtil::isIMFloaterOpened(const LLNotificationPtr& notification) { bool res = false; - LLIMFloater* im_floater = find_im_floater(notification); - if (im_floater != NULL) - { - res = im_floater->getVisible() == TRUE; - } - - return res; -} - -static bool is_IM_floater_focused(const LLNotificationPtr& notification) -{ - bool res = false; + LLUUID from_id = notification->getPayload()["from_id"]; + LLUUID session_id = LLIMMgr::computeSessionID(IM_NOTHING_SPECIAL, from_id); + LLIMFloater* im_floater = LLFloaterReg::findTypedInstance<LLIMFloater>("impanel", session_id); - LLIMFloater* im_floater = find_im_floater(notification); if (im_floater != NULL) { - res = im_floater->hasFocus() == TRUE; + res = im_floater->getVisible() == TRUE; } return res; @@ -208,12 +189,6 @@ void LLHandlerUtil::logToIM(const EInstantMessage& session_type, } } -// static -void LLHandlerUtil::logToIMP2P(const LLNotificationPtr& notification) -{ - logToIMP2P(notification, false); -} - void log_name_callback(const std::string& full_name, const std::string& from_name, const std::string& message, const LLUUID& from_id) @@ -225,25 +200,21 @@ void log_name_callback(const std::string& full_name, const std::string& from_nam // static void LLHandlerUtil::logToIMP2P(const LLNotificationPtr& notification, bool to_file_only) { - // don't create IM p2p session with objects, it's necessary condition to log - //if (notification->getName() != OBJECT_GIVE_ITEM) - { - LLUUID from_id = notification->getPayload()["from_id"]; + LLUUID from_id = notification->getPayload()["from_id"]; - if (from_id.isNull()) - { - llwarns << " from_id for notification " << notification->getName() << " is null " << llendl; - return; - } + if (from_id.isNull()) + { + llwarns << " from_id for notification " << notification->getName() << " is null " << llendl; + return; + } - if(to_file_only) - { - gCacheName->get(from_id, false, boost::bind(&log_name_callback, _2, "", notification->getMessage(), LLUUID())); - } - else - { - gCacheName->get(from_id, false, boost::bind(&log_name_callback, _2, INTERACTIVE_SYSTEM_FROM, notification->getMessage(), from_id)); - } + if(to_file_only) + { + gCacheName->get(from_id, false, boost::bind(&log_name_callback, _2, "", notification->getMessage(), LLUUID())); + } + else + { + gCacheName->get(from_id, false, boost::bind(&log_name_callback, _2, INTERACTIVE_SYSTEM_FROM, notification->getMessage(), from_id)); } } @@ -377,23 +348,20 @@ void LLHandlerUtil::updateVisibleIMFLoaterMesages(const LLNotificationPtr& notif void LLHandlerUtil::decIMMesageCounter(const LLNotificationPtr& notification) { const std::string name = LLHandlerUtil::getSubstitutionName(notification); - LLUUID from_id = notification->getPayload()["from_id"]; - LLUUID session_id = LLIMMgr::computeSessionID(IM_NOTHING_SPECIAL, from_id); + LLUUID from_id = notification->getPayload()["from_id"]; + LLUUID session_id = LLIMMgr::computeSessionID(IM_NOTHING_SPECIAL, from_id); - LLIMModel::LLIMSession * session = LLIMModel::getInstance()->findIMSession( - session_id); + LLIMModel::LLIMSession * session = LLIMModel::getInstance()->findIMSession(session_id); - if (session == NULL) + if (session) { - return; + LLSD arg; + arg["session_id"] = session_id; + session->mNumUnread--; + arg["num_unread"] = session->mNumUnread; + session->mParticipantUnreadMessageCount--; + arg["participant_unread"] = session->mParticipantUnreadMessageCount; + LLIMModel::getInstance()->mNewMsgSignal(arg); } - - LLSD arg; - arg["session_id"] = session_id; - session->mNumUnread--; - arg["num_unread"] = session->mNumUnread; - session->mParticipantUnreadMessageCount--; - arg["participant_unread"] = session->mParticipantUnreadMessageCount; - LLIMModel::getInstance()->mNewMsgSignal(arg); } diff --git a/indra/newview/llnotificationmanager.cpp b/indra/newview/llnotificationmanager.cpp index 394ae2ac21..9beb8afac6 100644 --- a/indra/newview/llnotificationmanager.cpp +++ b/indra/newview/llnotificationmanager.cpp @@ -52,15 +52,16 @@ LLNotificationManager::~LLNotificationManager() //-------------------------------------------------------------------------- void LLNotificationManager::init() { - new LLScriptHandler(); - new LLTipHandler(); - new LLGroupHandler(); - new LLAlertHandler("Alerts", "alert", false); - new LLAlertHandler("AlertModal", "alertmodal", true); - new LLOfferHandler(); - new LLHintHandler(); - new LLBrowserNotification(); - new LLOutboxNotification(); + mChannels.push_back(new LLScriptHandler()); + mChannels.push_back(new LLTipHandler()); + mChannels.push_back(new LLGroupHandler()); + mChannels.push_back(new LLAlertHandler("Alerts", "alert", false)); + mChannels.push_back(new LLAlertHandler("AlertModal", "alertmodal", true)); + mChannels.push_back(new LLOfferHandler()); + mChannels.push_back(new LLHintHandler()); + mChannels.push_back(new LLBrowserNotification()); + mChannels.push_back(new LLOutboxNotification()); + mChannels.push_back(new LLIMHandler()); mChatHandler = boost::shared_ptr<LLNearbyChatHandler>(new LLNearbyChatHandler()); } diff --git a/indra/newview/llnotificationmanager.h b/indra/newview/llnotificationmanager.h index 4d124e1379..c8afdf9e46 100644 --- a/indra/newview/llnotificationmanager.h +++ b/indra/newview/llnotificationmanager.h @@ -61,6 +61,7 @@ public: private: boost::shared_ptr<class LLNearbyChatHandler> mChatHandler; + std::vector<LLNotificationChannelPtr> mChannels; }; } diff --git a/indra/newview/llnotificationofferhandler.cpp b/indra/newview/llnotificationofferhandler.cpp index 8010417d43..051075cff9 100644 --- a/indra/newview/llnotificationofferhandler.cpp +++ b/indra/newview/llnotificationofferhandler.cpp @@ -79,16 +79,17 @@ bool LLOfferHandler::processNotification(const LLNotificationPtr& notification) initChannel(); } - bool add_notif_to_im = notification->canLogToIM() && notification->hasFormElements(); if( notification->getPayload().has("give_inventory_notification") - && !notification->getPayload()["give_inventory_notification"] ) + && notification->getPayload()["give_inventory_notification"].asBoolean() == false) { // This is an original inventory offer, so add a script floater LLScriptFloaterManager::instance().onAddNotification(notification->getID()); } else { + bool add_notif_to_im = notification->canLogToIM() && notification->hasFormElements(); + notification->setReusable(add_notif_to_im); LLUUID session_id; @@ -99,10 +100,6 @@ bool LLOfferHandler::processNotification(const LLNotificationPtr& notification) LLUUID from_id = notification->getPayload()["from_id"]; session_id = LLHandlerUtil::spawnIMSession(name, from_id); - } - - if (add_notif_to_im) - { LLHandlerUtil::addNotifPanelToIM(notification); } @@ -120,33 +117,19 @@ bool LLOfferHandler::processNotification(const LLNotificationPtr& notification) p.notif_id = notification->getID(); p.notification = notification; p.panel = notify_box; - p.on_delete_toast = boost::bind(&LLOfferHandler::onDeleteToast, this, _1); // we not save offer notifications to the syswell floater that should be added to the IM floater p.can_be_stored = !add_notif_to_im; LLScreenChannel* channel = dynamic_cast<LLScreenChannel*>(mChannel); if(channel) channel->addToast(p); - - // if we not add notification to IM - add it to notification well - if (!add_notif_to_im) - { - // send a signal to the counter manager - mNewNotificationSignal(); - } } if (notification->canLogToIM()) { // log only to file if notif panel can be embedded to IM and IM is opened - if (add_notif_to_im && LLHandlerUtil::isIMFloaterOpened(notification)) - { - LLHandlerUtil::logToIMP2P(notification, true); - } - else - { - LLHandlerUtil::logToIMP2P(notification); - } + bool file_only = add_notif_to_im && LLHandlerUtil::isIMFloaterOpened(notification); + LLHandlerUtil::logToIMP2P(notification, file_only); } } @@ -174,21 +157,6 @@ bool LLOfferHandler::processNotification(const LLNotificationPtr& notification) } //-------------------------------------------------------------------------- - -void LLOfferHandler::onDeleteToast(LLToast* toast) -{ - if (!toast->getNotification()->canLogToIM() || !toast->getNotification()->hasFormElements()) - { - // send a signal to the counter manager - mDelNotificationSignal(); - } - - // send a signal to a listener to let him perform some action - // in this case listener is a SysWellWindow and it will remove a corresponding item from its list - mNotificationIDSignal(toast->getNotificationID()); -} - -//-------------------------------------------------------------------------- void LLOfferHandler::onRejectToast(LLUUID& id) { LLNotificationPtr notification = LLNotifications::instance().find(id); diff --git a/indra/newview/llnotificationscripthandler.cpp b/indra/newview/llnotificationscripthandler.cpp index 714f14963c..c74c967722 100644 --- a/indra/newview/llnotificationscripthandler.cpp +++ b/indra/newview/llnotificationscripthandler.cpp @@ -37,10 +37,6 @@ using namespace LLNotificationsUI; -static const std::string SCRIPT_DIALOG ("ScriptDialog"); -static const std::string SCRIPT_DIALOG_GROUP ("ScriptDialogGroup"); -static const std::string SCRIPT_LOAD_URL ("LoadWebPage"); - //-------------------------------------------------------------------------- LLScriptHandler::LLScriptHandler() : LLSysHandler("Notifications", "notify") @@ -87,7 +83,7 @@ bool LLScriptHandler::processNotification(const LLNotificationPtr& notification) LLHandlerUtil::logToIMP2P(notification); } - if(SCRIPT_DIALOG == notification->getName() || SCRIPT_DIALOG_GROUP == notification->getName() || SCRIPT_LOAD_URL == notification->getName()) + if(notification->hasFormElements()) { LLScriptFloaterManager::getInstance()->onAddNotification(notification->getID()); } @@ -106,9 +102,6 @@ bool LLScriptHandler::processNotification(const LLNotificationPtr& notification) { channel->addToast(p); } - - // send a signal to the counter manager - mNewNotificationSignal(); } return false; @@ -117,7 +110,7 @@ bool LLScriptHandler::processNotification(const LLNotificationPtr& notification) void LLScriptHandler::onDelete( LLNotificationPtr notification ) { - if(SCRIPT_DIALOG == notification->getName() || SCRIPT_DIALOG_GROUP == notification->getName() || SCRIPT_LOAD_URL == notification->getName()) + if(notification->hasFormElements()) { LLScriptFloaterManager::getInstance()->onRemoveNotification(notification->getID()); } @@ -132,17 +125,11 @@ void LLScriptHandler::onDelete( LLNotificationPtr notification ) void LLScriptHandler::onDeleteToast(LLToast* toast) { - // send a signal to the counter manager - mDelNotificationSignal(); - // send a signal to a listener to let him perform some action // in this case listener is a SysWellWindow and it will remove a corresponding item from its list - mNotificationIDSignal(toast->getNotificationID()); - LLNotificationPtr notification = LLNotifications::getInstance()->find(toast->getNotificationID()); - if( notification && - (SCRIPT_DIALOG == notification->getName() || SCRIPT_DIALOG_GROUP == notification->getName()) ) + if( notification && notification->hasFormElements()) { LLScriptFloaterManager::getInstance()->onRemoveNotification(notification->getID()); } diff --git a/indra/newview/llsyswellwindow.cpp b/indra/newview/llsyswellwindow.cpp index e8293ebe2b..18e0d9d0d2 100644 --- a/indra/newview/llsyswellwindow.cpp +++ b/indra/newview/llsyswellwindow.cpp @@ -433,13 +433,19 @@ BOOL LLIMWellWindow::ObjectRowPanel::handleRightMouseDown(S32 x, S32 y, MASK mas ////////////////////////////////////////////////////////////////////////// // PUBLIC METHODS +LLNotificationWellWindow::WellNotificationChannel::WellNotificationChannel(LLNotificationWellWindow* well_window) +: LLNotificationChannel(LLNotificationChannel::Params().name(well_window->getPathname())), + mWellWindow(well_window) +{ + connectToChannel("Notifications"); + connectToChannel("Group Notifications"); + connectToChannel("Offer"); +} + LLNotificationWellWindow::LLNotificationWellWindow(const LLSD& key) -: LLSysWellWindow(key) +: LLSysWellWindow(key) { - // init connections to the list's update events - connectListUpdaterToSignal("Notifications"); - connectListUpdaterToSignal("Group Notifications"); - connectListUpdaterToSignal("Offer"); + mNotificationUpdates.reset(new WellNotificationChannel(this)); } // static @@ -546,19 +552,6 @@ void LLNotificationWellWindow::onStoreToast(LLPanel* info_panel, LLUUID id) addItem(p); } -void LLNotificationWellWindow::connectListUpdaterToSignal(std::string notification_type) -{ - LLNotificationsUI::LLEventHandler* n_handler = dynamic_cast<LLNotificationsUI::LLEventHandler*>(LLNotifications::instance().getChannel(notification_type).get()); - if(n_handler) - { - n_handler->setNotificationIDCallback(boost::bind(&LLNotificationWellWindow::removeItemByID, this, _1)); - } - else - { - llwarns << "LLSysWellWindow::connectListUpdaterToSignal() - could not get a handler for '" << notification_type <<"' type of notifications" << llendl; - } -} - void LLNotificationWellWindow::onItemClick(LLSysWellItem* item) { LLUUID id = item->getID(); @@ -573,6 +566,12 @@ void LLNotificationWellWindow::onItemClose(LLSysWellItem* item) mChannel->killToastByNotificationID(id); } +void LLNotificationWellWindow::onAdd( LLNotificationPtr notify ) +{ + removeItemByID(notify->getID()); +} + + /************************************************************************/ @@ -866,4 +865,4 @@ bool LLIMWellWindow::confirmCloseAll(const LLSD& notification, const LLSD& respo return false; } -// EOF + diff --git a/indra/newview/llsyswellwindow.h b/indra/newview/llsyswellwindow.h index 272e9cfcb1..caf30cfd67 100644 --- a/indra/newview/llsyswellwindow.h +++ b/indra/newview/llsyswellwindow.h @@ -34,6 +34,7 @@ #include "llscreenchannel.h" #include "llscrollcontainer.h" #include "llimview.h" +#include "llnotifications.h" #include "boost/shared_ptr.hpp" @@ -111,7 +112,7 @@ public: /*virtual*/ BOOL postBuild(); /*virtual*/ void setVisible(BOOL visible); - + /*virtual*/ void onAdd(LLNotificationPtr notify); // Operating with items void addItem(LLSysWellItem::Params p); @@ -119,6 +120,18 @@ public: void closeAll(); protected: + struct WellNotificationChannel : public LLNotificationChannel + { + WellNotificationChannel(LLNotificationWellWindow*); + void onAdd(LLNotificationPtr notify) + { + mWellWindow->removeItemByID(notify->getID()); + } + + LLNotificationWellWindow* mWellWindow; + }; + + LLNotificationChannelPtr mNotificationUpdates; /*virtual*/ const std::string& getAnchorViewName() { return NOTIFICATION_WELL_ANCHOR_NAME; } private: @@ -126,12 +139,8 @@ private: void initChannel(); void clearScreenChannels(); - void onStoreToast(LLPanel* info_panel, LLUUID id); - // connect counter and list updaters to the corresponding signals - void connectListUpdaterToSignal(std::string notification_type); - // Handlers void onItemClick(LLSysWellItem* item); void onItemClose(LLSysWellItem* item); diff --git a/indra/newview/lltoastgroupnotifypanel.h b/indra/newview/lltoastgroupnotifypanel.h index 3b8b31eac1..dfdc6ae559 100644 --- a/indra/newview/lltoastgroupnotifypanel.h +++ b/indra/newview/lltoastgroupnotifypanel.h @@ -47,9 +47,6 @@ class LLToastGroupNotifyPanel public: void close(); - static bool onNewNotification(const LLSD& notification); - - // Non-transient messages. You can specify non-default button // layouts (like one for script dialogs) by passing various // numbers in for "layout". diff --git a/indra/newview/lltoastscripttextbox.h b/indra/newview/lltoastscripttextbox.h index 8e69d8834d..7d33446248 100644 --- a/indra/newview/lltoastscripttextbox.h +++ b/indra/newview/lltoastscripttextbox.h @@ -39,8 +39,6 @@ class LLToastScriptTextbox public: void close(); - static bool onNewNotification(const LLSD& notification); - // Non-transient messages. You can specify non-default button // layouts (like one for script dialogs) by passing various // numbers in for "layout". |