diff options
Diffstat (limited to 'indra/llui/llnotifications.h')
-rw-r--r-- | indra/llui/llnotifications.h | 249 |
1 files changed, 145 insertions, 104 deletions
diff --git a/indra/llui/llnotifications.h b/indra/llui/llnotifications.h index 4ae02b943f..c677dfe298 100644 --- a/indra/llui/llnotifications.h +++ b/indra/llui/llnotifications.h @@ -87,17 +87,16 @@ #include <boost/shared_ptr.hpp> #include <boost/enable_shared_from_this.hpp> #include <boost/type_traits.hpp> +#include <boost/signals2.hpp> -// we want to minimize external dependencies, but this one is important -#include "llsd.h" - -// 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" +#include "llsdparam.h" class LLAvatarName; typedef enum e_notification_priority @@ -164,6 +163,7 @@ public: struct FormElementBase : public LLInitParam::Block<FormElementBase> { Optional<std::string> name; + Optional<bool> enabled; FormElementBase(); }; @@ -233,16 +233,20 @@ public: } EIgnoreType; LLNotificationForm(); + LLNotificationForm(const LLNotificationForm&); LLNotificationForm(const LLSD& sd); LLNotificationForm(const std::string& name, const Params& p); + void fromLLSD(const LLSD& sd); LLSD asLLSD() const; S32 getNumElements() { return mFormData.size(); } LLSD getElement(S32 index) { return mFormData.get(index); } LLSD getElement(const std::string& element_name); - bool hasElement(const std::string& element_name); - void addElement(const std::string& type, const std::string& name, const LLSD& value = LLSD()); + bool hasElement(const std::string& element_name) const; + bool getElementEnabled(const std::string& element_name) const; + void setElementEnabled(const std::string& element_name, bool enabled); + void addElement(const std::string& type, const std::string& name, const LLSD& value = LLSD(), bool enabled = true); void formatElements(const LLSD& substitutions); // appends form elements from another form serialized as LLSD void append(const LLSD& sub_form); @@ -296,19 +300,20 @@ LOG_CLASS(LLNotification); friend class LLNotifications; public: + // parameter object used to instantiate a new notification struct Params : public LLInitParam::Block<Params> { friend class LLNotification; Mandatory<std::string> name; - - // optional - Optional<LLSD> substitutions; - Optional<LLSD> payload; + Optional<LLUUID> id; + Optional<LLSD> substitutions, + form_elements, + payload; Optional<ENotificationPriority, NotificationPriorityValues> priority; - Optional<LLSD> form_elements; - Optional<LLDate> time_stamp; + Optional<LLDate> time_stamp, + expiry; Optional<LLNotificationContext*> context; Optional<void*> responder; @@ -319,7 +324,7 @@ public: Alternative<LLNotificationResponderPtr> responder; Functor() - : name("functor_name"), + : name("responseFunctor"), function("functor"), responder("responder") {} @@ -328,10 +333,13 @@ public: Params() : name("name"), + id("id"), priority("priority", NOTIFICATION_PRIORITY_UNSPECIFIED), - time_stamp("time_stamp"), + time_stamp("time"), payload("payload"), - form_elements("form_elements") + form_elements("form"), + substitutions("substitutions"), + expiry("expiry") { time_stamp = LLDate::now(); responder = NULL; @@ -340,9 +348,11 @@ public: Params(const std::string& _name) : name("name"), priority("priority", NOTIFICATION_PRIORITY_UNSPECIFIED), - time_stamp("time_stamp"), + time_stamp("time"), payload("payload"), - form_elements("form_elements") + form_elements("form"), + substitutions("substitutions"), + expiry("expiry") { functor.name = _name; name = _name; @@ -355,7 +365,7 @@ public: private: - LLUUID mId; + const LLUUID mId; LLSD mPayload; LLSD mSubstitutions; LLDate mTimestamp; @@ -367,7 +377,6 @@ private: ENotificationPriority mPriority; LLNotificationFormPtr mForm; void* mResponderObj; // TODO - refactor/remove this field - bool mIsReusable; LLNotificationResponderPtr mResponder; // a reference to the template @@ -392,18 +401,10 @@ private: void init(const std::string& template_name, const LLSD& form_elements); - LLNotification(const Params& p); - - // 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), mCancelled(false), mRespondedTo(false), mIgnored(false), mPriority(NOTIFICATION_PRIORITY_UNSPECIFIED), mTemporaryResponder(false) {} - void cancel(); public: - - // constructor from a saved notification - LLNotification(const LLSD& sd); + LLNotification(const LLSDParamAdapter<Params>& p); void setResponseFunctor(std::string const &responseFunctorName); @@ -448,6 +449,11 @@ public: // ["responseFunctor"] = name of registered functor that handles responses to notification; LLSD asLLSD(); + const LLNotificationFormPtr getForm(); + void updateForm(const LLNotificationFormPtr& form); + + void repost(); + void respond(const LLSD& sd); void respondWithDefault(); @@ -514,8 +520,20 @@ public: std::string getURL() const; S32 getURLOption() const; S32 getURLOpenExternally() const; + bool canLogToChat() const; + bool canLogToIM() const; + bool canShowToast() const; + bool hasFormElements() const; + + typedef enum e_combine_behavior + { + REPLACE_WITH_NEW, + KEEP_OLD, + CANCEL_OLD + + } ECombineBehavior; - const LLNotificationFormPtr getForm(); + ECombineBehavior getCombineBehavior() const; const LLDate getExpiration() const { @@ -532,10 +550,6 @@ 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) bool operator<(const LLNotification& rhs) const @@ -647,44 +661,18 @@ namespace LLNotificationFilters namespace LLNotificationComparators { - typedef enum e_direction { ORDER_DECREASING, ORDER_INCREASING } EDirection; - - // generic order functor that takes method or member variable reference - template<typename T> - struct orderBy + struct orderByUUID { - typedef boost::function<T (LLNotificationPtr)> field_t; - orderBy(field_t field, EDirection direction = ORDER_INCREASING) : mField(field), mDirection(direction) {} bool operator()(LLNotificationPtr lhs, LLNotificationPtr rhs) { - if (mDirection == ORDER_DECREASING) - { - return mField(lhs) > mField(rhs); - } - else - { - return mField(lhs) < mField(rhs); - } + return lhs->id() < rhs->id(); } - - field_t mField; - EDirection mDirection; - }; - - struct orderByUUID : public orderBy<const LLUUID&> - { - orderByUUID(EDirection direction = ORDER_INCREASING) : orderBy<const LLUUID&>(&LLNotification::id, direction) {} - }; - - struct orderByDate : public orderBy<const LLDate&> - { - orderByDate(EDirection direction = ORDER_INCREASING) : orderBy<const LLDate&>(&LLNotification::getDate, direction) {} }; }; typedef boost::function<bool (LLNotificationPtr)> LLNotificationFilter; typedef boost::function<bool (LLNotificationPtr, LLNotificationPtr)> LLNotificationComparator; -typedef std::set<LLNotificationPtr, LLNotificationComparator> LLNotificationSet; +typedef std::set<LLNotificationPtr, LLNotificationComparators::orderByUUID> LLNotificationSet; typedef std::multimap<std::string, LLNotificationPtr> LLNotificationMap; // ======================================================== @@ -705,12 +693,14 @@ 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: - LLNotificationChannelBase(LLNotificationFilter filter, LLNotificationComparator comp) : - mFilter(filter), mItems(comp) + LLNotificationChannelBase(LLNotificationFilter filter) + : mFilter(filter), + mItems() {} virtual ~LLNotificationChannelBase() {} // you can also connect to a Channel, so you can be notified of @@ -785,59 +775,49 @@ 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. -// -// NOTE: LLNotificationChannel is self-registering. The *correct* way to create one is to -// do something like: -// LLNotificationChannel::buildChannel("name", "parent"...); -// This returns an LLNotificationChannelPtr, which you can store, or -// you can then retrieve the channel by using the registry: -// LLNotifications::instance().getChannel("name")... +// 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; + Multiple<std::string> sources; + }; + + LLNotificationChannel(const Params& p = Params()); + LLNotificationChannel(const std::string& name, const std::string& parent, LLNotificationFilter filter); + 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(); Iterator end(); + size_t size(); - // Channels have a comparator to control sort order; - // the default sorts by arrival date - void setComparator(LLNotificationComparator comparator); - std::string summarize(); - // factory method for constructing these channels; since they're self-registering, - // we want to make sure that you can't use new to make them - static LLNotificationChannelPtr buildChannel(const std::string& name, const std::string& parent, - LLNotificationFilter filter=LLNotificationFilters::includeEverything, - LLNotificationComparator comparator=LLNotificationComparators::orderByUUID()); - -protected: - // 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); - private: std::string mName; std::string mParent; @@ -924,10 +904,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; @@ -966,6 +942,7 @@ private: bool mIgnoreAllNotifications; boost::scoped_ptr<LLNotificationsListener> mListener; + std::vector<LLNotificationChannelPtr> mDefaultChannels; }; /** @@ -996,14 +973,15 @@ public: thiz->mParams = params; // Avoid header file dependency on llcachename.h - lookupName(thiz, id, is_group); + thiz->lookupName(id, is_group); } private: - static void lookupName(LLPostponedNotification* thiz, const LLUUID& id, bool is_group); + void lookupName(const LLUUID& id, bool is_group); // only used for groups void onGroupNameCache(const LLUUID& id, const std::string& full_name, bool is_group); // only used for avatars + void fetchAvatarName(const LLUUID& id); void onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name); // used for both group and avatar names void finalizeName(const std::string& name); @@ -1014,8 +992,19 @@ private: } protected: - LLPostponedNotification() {} - virtual ~LLPostponedNotification() {} + LLPostponedNotification() + : mParams(), + mName(), + mAvatarNameCacheConnection() + {} + + virtual ~LLPostponedNotification() + { + if (mAvatarNameCacheConnection.connected()) + { + mAvatarNameCacheConnection.disconnect(); + } + } /** * Abstract method provides possibility to modify notification parameters and @@ -1026,6 +1015,58 @@ protected: LLNotification::Params mParams; std::string mName; + boost::signals2::connection mAvatarNameCacheConnection; +}; + +// Stores only persistent notifications. +// Class users can use connectChanged() to process persistent notifications +// (see LLNotificationStorage for example). +class LLPersistentNotificationChannel : public LLNotificationChannel +{ + LOG_CLASS(LLPersistentNotificationChannel); +public: + LLPersistentNotificationChannel() + : LLNotificationChannel("Persistent", "Visible", ¬ificationFilter) + { + } + + typedef std::vector<LLNotificationPtr> history_list_t; + history_list_t::iterator beginHistory() { sortHistory(); return mHistory.begin(); } + history_list_t::iterator endHistory() { return mHistory.end(); } + +private: + + struct sortByTime + { + S32 operator ()(const LLNotificationPtr& a, const LLNotificationPtr& b) + { + return a->getDate() < b->getDate(); + } + }; + + void sortHistory() + { + std::sort(mHistory.begin(), mHistory.end(), sortByTime()); + } + + + // The channel gets all persistent notifications except those that have been canceled + static bool notificationFilter(LLNotificationPtr pNotification) + { + bool handle_notification = false; + + handle_notification = pNotification->isPersistent() + && !pNotification->isCancelled(); + + return handle_notification; + } + + void onAdd(LLNotificationPtr p) + { + mHistory.push_back(p); + } + + std::vector<LLNotificationPtr> mHistory; }; #endif//LL_LLNOTIFICATIONS_H |