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
Richard Linden 2012-03-29 23:48:29 -07:00
parent 1ea65f0285
commit 2fa1c42aad
21 changed files with 242 additions and 324 deletions

View File

@ -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;

View File

@ -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

View File

@ -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

View File

@ -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"

View File

@ -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;
};
/**

View File

@ -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);
}

View File

@ -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());
}
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////

View File

@ -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;
};

View File

@ -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));
}

View File

@ -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();
}
//--------------------------------------------------------------------------

View File

@ -87,25 +87,11 @@ 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)
{

View File

@ -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.

View File

@ -111,21 +111,15 @@ 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);
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);
if (im_floater != NULL)
{
res = im_floater->getVisible() == TRUE;
@ -134,19 +128,6 @@ bool LLHandlerUtil::isIMFloaterOpened(const LLNotificationPtr& notification)
return res;
}
static bool is_IM_floater_focused(const LLNotificationPtr& notification)
{
bool res = false;
LLIMFloater* im_floater = find_im_floater(notification);
if (im_floater != NULL)
{
res = im_floater->hasFocus() == TRUE;
}
return res;
}
// static
void LLHandlerUtil::logToIM(const EInstantMessage& session_type,
const std::string& session_name, const std::string& from_name,
@ -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"];
if (from_id.isNull())
{
LLUUID from_id = notification->getPayload()["from_id"];
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);
}

View File

@ -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());
}

View File

@ -61,6 +61,7 @@ public:
private:
boost::shared_ptr<class LLNearbyChatHandler> mChatHandler;
std::vector<LLNotificationChannelPtr> mChannels;
};
}

View File

@ -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);
}
}
@ -173,21 +156,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)
{

View File

@ -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());
}

View File

@ -433,13 +433,19 @@ BOOL LLIMWellWindow::ObjectRowPanel::handleRightMouseDown(S32 x, S32 y, MASK mas
//////////////////////////////////////////////////////////////////////////
// PUBLIC METHODS
LLNotificationWellWindow::LLNotificationWellWindow(const LLSD& key)
: LLSysWellWindow(key)
LLNotificationWellWindow::WellNotificationChannel::WellNotificationChannel(LLNotificationWellWindow* well_window)
: LLNotificationChannel(LLNotificationChannel::Params().name(well_window->getPathname())),
mWellWindow(well_window)
{
// init connections to the list's update events
connectListUpdaterToSignal("Notifications");
connectListUpdaterToSignal("Group Notifications");
connectListUpdaterToSignal("Offer");
connectToChannel("Notifications");
connectToChannel("Group Notifications");
connectToChannel("Offer");
}
LLNotificationWellWindow::LLNotificationWellWindow(const LLSD& key)
: LLSysWellWindow(key)
{
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

View File

@ -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);

View File

@ -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".

View File

@ -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".