diff options
Diffstat (limited to 'indra/llui/llnotifications.h')
-rw-r--r-- | indra/llui/llnotifications.h | 227 |
1 files changed, 176 insertions, 51 deletions
diff --git a/indra/llui/llnotifications.h b/indra/llui/llnotifications.h index 5c8d146e0c..2cc8803f10 100644 --- a/indra/llui/llnotifications.h +++ b/indra/llui/llnotifications.h @@ -3,31 +3,25 @@ * @brief Non-UI manager and support for keeping a prioritized list of notifications * @author Q (with assistance from Richard and Coco) * -* $LicenseInfo:firstyear=2008&license=viewergpl$ -* -* Copyright (c) 2008-2009, Linden Research, Inc. -* +* $LicenseInfo:firstyear=2008&license=viewerlgpl$ * Second Life Viewer Source Code -* The source code in this file ("Source Code") is provided by Linden Lab -* to you under the terms of the GNU General Public License, version 2.0 -* ("GPL"), unless you have obtained a separate licensing agreement -* ("Other License"), formally executed by you and Linden Lab. Terms of -* the GPL can be found in doc/GPL-license.txt in this distribution, or -* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 +* Copyright (C) 2010, Linden Research, Inc. +* +* This library is free software; you can redistribute it and/or +* modify it under the terms of the GNU Lesser General Public +* License as published by the Free Software Foundation; +* version 2.1 of the License only. * -* There are special exceptions to the terms and conditions of the GPL as -* it is applied to this Source Code. View the full text of the exception -* in the file doc/FLOSS-exception.txt in this software distribution, or -* online at -* http://secondlifegrid.net/programs/open_source/licensing/flossexception +* This library is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* Lesser General Public License for more details. * -* By copying, modifying or distributing this software, you acknowledge -* that you have read and understood your obligations described above, -* and agree to abide by those obligations. +* You should have received a copy of the GNU Lesser General Public +* License along with this library; if not, write to the Free Software +* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * -* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO -* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, -* COMPLETENESS OR PERFORMANCE. +* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -100,11 +94,11 @@ // and we need this to manage the notification callbacks #include "llevents.h" #include "llfunctorregistry.h" -#include "llui.h" -#include "llmemory.h" - -class LLNotification; -typedef boost::shared_ptr<LLNotification> LLNotificationPtr; +#include "llpointer.h" +#include "llinitparam.h" +#include "llnotificationslistener.h" +#include "llnotificationptr.h" +#include "llcachename.h" typedef enum e_notification_priority @@ -116,8 +110,23 @@ typedef enum e_notification_priority NOTIFICATION_PRIORITY_CRITICAL } ENotificationPriority; +class LLNotificationResponderInterface +{ +public: + LLNotificationResponderInterface(){}; + virtual ~LLNotificationResponderInterface(){}; + + virtual void handleRespond(const LLSD& notification, const LLSD& response) = 0; + + virtual LLSD asLLSD() = 0; + + virtual void fromLLSD(const LLSD& params) = 0; +}; + typedef boost::function<void (const LLSD&, const LLSD&)> LLNotificationResponder; +typedef boost::shared_ptr<LLNotificationResponderInterface> LLNotificationResponderPtr; + typedef LLFunctorRegistry<LLNotificationResponder> LLNotificationFunctorRegistry; typedef LLFunctorRegistration<LLNotificationResponder> LLNotificationFunctorRegistration; @@ -158,7 +167,8 @@ public: LLNotificationForm(); LLNotificationForm(const LLSD& sd); - LLNotificationForm(const std::string& name, const LLXMLNodePtr xml_node); + LLNotificationForm(const std::string& name, + const LLPointer<class LLXMLNode> xml_node); LLSD asLLSD() const; @@ -294,17 +304,20 @@ public: Optional<LLSD> payload; Optional<ENotificationPriority> priority; Optional<LLSD> form_elements; - Optional<LLDate> timestamp; + Optional<LLDate> time_stamp; Optional<LLNotificationContext*> context; + Optional<void*> responder; struct Functor : public LLInitParam::Choice<Functor> { - Option<std::string> name; - Option<LLNotificationFunctorRegistry::ResponseFunctor> function; + Alternative<std::string> name; + Alternative<LLNotificationFunctorRegistry::ResponseFunctor> function; + Alternative<LLNotificationResponderPtr> responder; Functor() : name("functor_name"), - function("functor") + function("functor"), + responder("responder") {} }; Optional<Functor> functor; @@ -312,22 +325,30 @@ public: Params() : name("name"), priority("priority", NOTIFICATION_PRIORITY_UNSPECIFIED), - timestamp("time_stamp") + time_stamp("time_stamp"), + payload("payload"), + form_elements("form_elements") { - timestamp = LLDate::now(); + time_stamp = LLDate::now(); + responder = NULL; } Params(const std::string& _name) - : name("name"), - priority("priority", NOTIFICATION_PRIORITY_UNSPECIFIED), - timestamp("time_stamp") + : name("name"), + priority("priority", NOTIFICATION_PRIORITY_UNSPECIFIED), + time_stamp("time_stamp"), + payload("payload"), + form_elements("form_elements") { functor.name = _name; name = _name; - timestamp = LLDate::now(); + time_stamp = LLDate::now(); + responder = NULL; } }; + LLNotificationResponderPtr getResponderPtr() { return mResponder; } + private: LLUUID mId; @@ -337,13 +358,17 @@ private: LLDate mExpiresAt; bool mCancelled; bool mRespondedTo; // once the notification has been responded to, this becomes true + LLSD mResponse; bool mIgnored; ENotificationPriority mPriority; LLNotificationFormPtr mForm; - + void* mResponderObj; // TODO - refactor/remove this field + bool mIsReusable; + LLNotificationResponderPtr mResponder; + // a reference to the template LLNotificationTemplatePtr mTemplatep; - + /* We want to be able to store and reload notifications so that they can survive a shutdown/restart of the client. So we can't simply pass in callbacks; @@ -367,12 +392,10 @@ private: // this is just for making it easy to look things up in a set organized by UUID -- DON'T USE IT // for anything real! - LLNotification(LLUUID uuid) : mId(uuid) {} + LLNotification(LLUUID uuid) : mId(uuid), mCancelled(false), mRespondedTo(false), mIgnored(false), mPriority(NOTIFICATION_PRIORITY_UNSPECIFIED), mTemporaryResponder(false) {} void cancel(); - bool payloadContainsAll(const std::vector<std::string>& required_fields) const; - public: // constructor from a saved notification @@ -380,6 +403,10 @@ public: void setResponseFunctor(std::string const &responseFunctorName); + void setResponseFunctor(const LLNotificationFunctorRegistry::ResponseFunctor& cb); + + void setResponseFunctor(const LLNotificationResponderPtr& responder); + typedef enum e_response_template_type { WITHOUT_DEFAULT_BUTTON, @@ -419,6 +446,10 @@ public: void respond(const LLSD& sd); + void* getResponder() { return mResponderObj; } + + void setResponder(void* responder) { mResponderObj = responder; } + void setIgnored(bool ignore); bool isCancelled() const @@ -431,6 +462,8 @@ public: return mRespondedTo; } + const LLSD& getResponse() { return mResponse; } + bool isIgnored() const { return mIgnored; @@ -440,7 +473,12 @@ public: { return mTemplatep->mName; } - + + bool isPersistent() const + { + return mTemplatep->mPersist; + } + const LLUUID& id() const { return mId; @@ -500,6 +538,10 @@ public: { return mId; } + + bool isReusable() { return mIsReusable; } + + void setReusable(bool reusable) { mIsReusable = reusable; } // comparing two notifications normally means comparing them by UUID (so we can look them // up quickly this way) @@ -617,7 +659,7 @@ namespace LLNotificationComparators struct orderBy { typedef boost::function<T (LLNotificationPtr)> field_t; - orderBy(field_t field, EDirection = ORDER_INCREASING) : mField(field) {} + orderBy(field_t field, EDirection direction = ORDER_INCREASING) : mField(field), mDirection(direction) {} bool operator()(LLNotificationPtr lhs, LLNotificationPtr rhs) { if (mDirection == ORDER_DECREASING) @@ -689,6 +731,14 @@ public: this, _1)); } + template <typename LISTENER> + LLBoundListener connectAtFrontChanged(const LISTENER& slot) + { + return LLEventDetail::visit_and_connect(slot, + boost::bind(&LLNotificationChannelBase::connectAtFrontChangedImpl, + this, + _1)); + } template <typename LISTENER> LLBoundListener connectPassedFilter(const LISTENER& slot) { @@ -714,6 +764,7 @@ public: protected: LLBoundListener connectChangedImpl(const LLEventListener& slot); + LLBoundListener connectAtFrontChangedImpl(const LLEventListener& slot); LLBoundListener connectPassedFilterImpl(const LLEventListener& slot); LLBoundListener connectFailedFilterImpl(const LLEventListener& slot); @@ -798,9 +849,19 @@ private: LLNotificationComparator mComparator; }; - +// An interface class to provide a clean linker seam to the LLNotifications class. +// Extend this interface as needed for your use of LLNotifications. +class LLNotificationsInterface +{ +public: + virtual LLNotificationPtr add(const std::string& name, + const LLSD& substitutions, + const LLSD& payload, + LLNotificationFunctorRegistry::ResponseFunctor functor) = 0; +}; class LLNotifications : + public LLNotificationsInterface, public LLSingleton<LLNotifications>, public LLNotificationChannelBase { @@ -811,20 +872,21 @@ public: // load notification descriptions from file; // OK to call more than once because it will reload bool loadTemplates(); - LLXMLNodePtr checkForXMLTemplate(LLXMLNodePtr item); + LLPointer<class LLXMLNode> checkForXMLTemplate(LLPointer<class LLXMLNode> item); // Add a simple notification (from XUI) void addFromCallback(const LLSD& name); - // we provide a collection of simple add notification functions so that it's reasonable to create notifications in one line + // *NOTE: To add simple notifications, #include "llnotificationsutil.h" + // and use LLNotificationsUtil::add("MyNote") or add("MyNote", args) LLNotificationPtr add(const std::string& name, - const LLSD& substitutions = LLSD(), - const LLSD& payload = LLSD()); + const LLSD& substitutions, + const LLSD& payload); LLNotificationPtr add(const std::string& name, const LLSD& substitutions, const LLSD& payload, const std::string& functor_name); - LLNotificationPtr add(const std::string& name, + /* virtual */ LLNotificationPtr add(const std::string& name, const LLSD& substitutions, const LLSD& payload, LLNotificationFunctorRegistry::ResponseFunctor functor); @@ -870,6 +932,9 @@ public: std::string getGlobalString(const std::string& key) const; + void setIgnoreAllNotifications(bool ignore); + bool getIgnoreAllNotifications(); + private: // we're a singleton, so we don't have a public constructor LLNotifications(); @@ -891,15 +956,75 @@ private: std::string mFileName; - typedef std::map<std::string, LLXMLNodePtr> XMLTemplateMap; + typedef std::map<std::string, LLPointer<class LLXMLNode> > XMLTemplateMap; XMLTemplateMap mXmlTemplates; LLNotificationMap mUniqueNotifications; typedef std::map<std::string, std::string> GlobalStringMap; GlobalStringMap mGlobalStrings; + + bool mIgnoreAllNotifications; + + boost::scoped_ptr<LLNotificationsListener> mListener; }; +/** + * Abstract class for postponed notifications. + * Provides possibility to add notification after specified by id avatar or group will be + * received from cache name. The object of this type automatically well be deleted + * by cleanup method after respond will be received from cache name. + * + * To add custom postponed notification to the notification system client should: + * 1 create class derived from LLPostponedNotification; + * 2 call LLPostponedNotification::add method; + */ +class LLPostponedNotification +{ +public: + /** + * Performs hooking cache name callback which will add notification to notifications system. + * Type of added notification should be specified by template parameter T + * and non-private derived from LLPostponedNotification class, + * otherwise compilation error will occur. + */ + template<class T> + static void add(const LLNotification::Params& params, + const LLUUID& id, bool is_group) + { + // upcast T to the base type to restrict T derivation from LLPostponedNotification + LLPostponedNotification* thiz = new T(); + + thiz->mParams = params; + + gCacheName->get(id, is_group, boost::bind( + &LLPostponedNotification::onCachedNameReceived, thiz, _1, _2, + _3, _4)); + } + +private: + void onCachedNameReceived(const LLUUID& id, const std::string& first, + const std::string& last, bool is_group); + + void cleanup() + { + delete this; + } + +protected: + LLPostponedNotification() {} + virtual ~LLPostponedNotification() {} + + /** + * Abstract method provides possibility to modify notification parameters and + * will be called after cache name retrieve information about avatar or group + * and before notification will be added to the notification system. + */ + virtual void modifyNotificationParams() = 0; + + LLNotification::Params mParams; + std::string mName; +}; #endif//LL_LLNOTIFICATIONS_H |