summaryrefslogtreecommitdiff
path: root/indra
diff options
context:
space:
mode:
authorMerov Linden <merov@lindenlab.com>2012-12-19 11:04:24 -0800
committerMerov Linden <merov@lindenlab.com>2012-12-19 11:04:24 -0800
commite32f110b9a17928285dc9e39953abce9eecf9742 (patch)
tree1be90f51b3117efd4b4d938a5692095244c1c5cd /indra
parent8adca4583ec95ac063f79990ac092998f24415b8 (diff)
parentb34e3a1b40fd72b4c4cdc1553c3f5934e9e9cef5 (diff)
Pull merge from richard/viewer-chui
Diffstat (limited to 'indra')
-rw-r--r--indra/llui/CMakeLists.txt2
-rw-r--r--indra/llui/llbutton.cpp36
-rwxr-xr-xindra/llui/llfolderviewitem.cpp11
-rw-r--r--indra/llui/llnotifications.cpp5
-rw-r--r--indra/llui/llnotifications.h9
-rw-r--r--indra/llui/llnotificationslistener.cpp354
-rw-r--r--indra/llui/llnotificationslistener.h69
-rw-r--r--indra/llui/llnotificationtemplate.h1
-rwxr-xr-xindra/newview/CMakeLists.txt6
-rw-r--r--indra/newview/llbrowsernotification.cpp5
-rw-r--r--indra/newview/llchannelmanager.cpp4
-rw-r--r--indra/newview/llchatbar.cpp44
-rw-r--r--indra/newview/llcommunicationchannel.cpp73
-rw-r--r--indra/newview/llcommunicationchannel.h59
-rw-r--r--indra/newview/lldonotdisturbnotificationstorage.cpp106
-rw-r--r--indra/newview/lldonotdisturbnotificationstorage.h57
-rw-r--r--indra/newview/llfloaterimcontainer.cpp7
-rw-r--r--indra/newview/llfloaterimsession.cpp38
-rw-r--r--indra/newview/llfloaterimsession.h7
-rw-r--r--indra/newview/llfloaterimsessiontab.cpp83
-rw-r--r--indra/newview/llfloaterimsessiontab.h8
-rw-r--r--indra/newview/llfloateroutbox.cpp17
-rw-r--r--indra/newview/llimhandler.cpp2
-rw-r--r--indra/newview/llimview.cpp49
-rw-r--r--indra/newview/llnotificationalerthandler.cpp28
-rw-r--r--indra/newview/llnotificationgrouphandler.cpp2
-rw-r--r--indra/newview/llnotificationhandler.h142
-rw-r--r--indra/newview/llnotificationhandlerutil.cpp12
-rw-r--r--indra/newview/llnotificationhinthandler.cpp27
-rw-r--r--indra/newview/llnotificationofferhandler.cpp2
-rw-r--r--indra/newview/llnotificationscripthandler.cpp2
-rw-r--r--indra/newview/llnotificationstorage.cpp203
-rw-r--r--indra/newview/llnotificationstorage.h34
-rw-r--r--indra/newview/llnotificationtiphandler.cpp2
-rw-r--r--indra/newview/llpersistentnotificationstorage.cpp210
-rw-r--r--indra/newview/llpersistentnotificationstorage.h63
-rwxr-xr-xindra/newview/llviewermessage.cpp11
-rwxr-xr-xindra/newview/llviewerwindow.cpp30
-rw-r--r--indra/newview/llviewerwindow.h8
-rw-r--r--indra/newview/skins/default/colors.xml3
-rw-r--r--indra/newview/skins/default/xui/en/floater_im_container.xml6
-rw-r--r--indra/newview/skins/default/xui/en/floater_im_session.xml15
-rw-r--r--indra/newview/skins/default/xui/en/menu_im_conversation.xml94
-rw-r--r--indra/newview/skins/default/xui/en/menu_viewer.xml53
-rw-r--r--indra/newview/skins/default/xui/en/notifications.xml1
-rw-r--r--indra/newview/skins/default/xui/en/widgets/toolbar.xml12
46 files changed, 1149 insertions, 863 deletions
diff --git a/indra/llui/CMakeLists.txt b/indra/llui/CMakeLists.txt
index ccc7aa8cec..9c961d67d6 100644
--- a/indra/llui/CMakeLists.txt
+++ b/indra/llui/CMakeLists.txt
@@ -71,7 +71,6 @@ set(llui_SOURCE_FILES
llmultislider.cpp
llmultisliderctrl.cpp
llnotifications.cpp
- llnotificationslistener.cpp
llnotificationsutil.cpp
llpanel.cpp
llprogressbar.cpp
@@ -181,7 +180,6 @@ set(llui_HEADER_FILES
llmultislider.h
llnotificationptr.h
llnotifications.h
- llnotificationslistener.h
llnotificationsutil.h
llnotificationtemplate.h
llnotificationvisibilityrule.h
diff --git a/indra/llui/llbutton.cpp b/indra/llui/llbutton.cpp
index f82cdc64a9..99384439d2 100644
--- a/indra/llui/llbutton.cpp
+++ b/indra/llui/llbutton.cpp
@@ -613,29 +613,11 @@ void LLButton::draw()
static LLCachedControl<bool> sEnableButtonFlashing(*LLUI::sSettingGroups["config"], "EnableButtonFlashing", true);
F32 alpha = mUseDrawContextAlpha ? getDrawContext().mAlpha : getCurrentTransparency();
- bool flash = false;
if (mFlashingTimer)
{
mFlashing = mFlashingTimer->isFlashingInProgress();
- flash = mFlashing && (!sEnableButtonFlashing || mFlashingTimer->isCurrentlyHighlighted());
- }
- else
- {
- if(mFlashing)
- {
- if ( sEnableButtonFlashing)
- {
- F32 elapsed = mFrameTimer.getElapsedTimeF32();
- S32 flash_count = S32(elapsed * mButtonFlashRate * 2.f);
- // flash on or off?
- flash = (flash_count % 2 == 0) || flash_count > S32((F32)mButtonFlashCount * 2.f);
- }
- else
- { // otherwise just highlight button in flash color
- flash = true;
- }
- }
}
+ bool flash = mFlashing && sEnableButtonFlashing;
bool pressed_by_keyboard = FALSE;
if (hasFocus())
@@ -660,7 +642,8 @@ void LLButton::draw()
bool selected = getToggleState();
bool use_glow_effect = FALSE;
- LLColor4 glow_color = LLColor4::white;
+ LLColor4 highlighting_color = LLColor4::white;
+ LLColor4 glow_color;
LLRender::eBlendType glow_type = LLRender::BT_ADD_WITH_ALPHA;
LLUIImage* imagep = NULL;
if (pressed && mDisplayPressedState)
@@ -733,10 +716,15 @@ void LLButton::draw()
LLColor4 flash_color = mFlashBgColor.get();
use_glow_effect = TRUE;
glow_type = LLRender::BT_ALPHA; // blend the glow
- if (mNeedsHighlight) // highlighted AND flashing
- glow_color = (glow_color*0.5f + flash_color*0.5f) % 2.0f; // average between flash and highlight colour, with sum of the opacity
- else
+
+ if (mFlashingTimer->isCurrentlyHighlighted())
+ {
glow_color = flash_color;
+ }
+ else if (mNeedsHighlight)
+ {
+ glow_color = highlighting_color;
+ }
}
}
@@ -785,7 +773,7 @@ void LLButton::draw()
if (use_glow_effect)
{
mCurGlowStrength = lerp(mCurGlowStrength,
- mFlashing ? (flash? 1.0 : 0.0)
+ mFlashing ? (mFlashingTimer->isCurrentlyHighlighted() || mNeedsHighlight? 1.0 : 0.0)
: mHoverGlowStrength,
LLCriticalDamp::getInterpolant(0.05f));
}
diff --git a/indra/llui/llfolderviewitem.cpp b/indra/llui/llfolderviewitem.cpp
index 100904c5a2..1281d6bd66 100755
--- a/indra/llui/llfolderviewitem.cpp
+++ b/indra/llui/llfolderviewitem.cpp
@@ -1493,17 +1493,20 @@ void LLFolderViewFolder::extendSelectionTo(LLFolderViewItem* new_selection)
void LLFolderViewFolder::destroyView()
{
- std::for_each(mItems.begin(), mItems.end(), DeletePointer());
- mItems.clear();
+ while (!mItems.empty())
+ {
+ LLFolderViewItem *itemp = mItems.back();
+ itemp->destroyView(); // LLFolderViewItem::destroyView() removes entry from mItems
+ }
while (!mFolders.empty())
{
LLFolderViewFolder *folderp = mFolders.back();
- folderp->destroyView(); // removes entry from mFolders
+ folderp->destroyView(); // LLFolderVievFolder::destroyView() removes entry from mFolders
}
LLFolderViewItem::destroyView();
- }
+}
// extractItem() removes the specified item from the folder, but
// doesn't delete it.
diff --git a/indra/llui/llnotifications.cpp b/indra/llui/llnotifications.cpp
index fd9bfec203..c9b4399bef 100644
--- a/indra/llui/llnotifications.cpp
+++ b/indra/llui/llnotifications.cpp
@@ -39,7 +39,6 @@
#include "lldir.h"
#include "llsdserialize.h"
#include "lltrans.h"
-#include "llnotificationslistener.h"
#include "llstring.h"
#include "llsdparam.h"
#include "llsdutil.h"
@@ -993,10 +992,12 @@ bool LLNotificationChannelBase::updateItem(const LLSD& payload, LLNotificationPt
bool abortProcessing = false;
if (passesFilter)
{
+ onFilterPass(pNotification);
abortProcessing = mPassedFilter(payload);
}
else
{
+ onFilterFail(pNotification);
abortProcessing = mFailedFilter(payload);
}
@@ -1168,8 +1169,6 @@ LLNotifications::LLNotifications()
mIgnoreAllNotifications(false)
{
LLUICtrl::CommitCallbackRegistry::currentRegistrar().add("Notification.Show", boost::bind(&LLNotifications::addFromCallback, this, _2));
-
- mListener.reset(new LLNotificationsListener(*this));
}
diff --git a/indra/llui/llnotifications.h b/indra/llui/llnotifications.h
index 372b9ce46f..42dee4c3e9 100644
--- a/indra/llui/llnotifications.h
+++ b/indra/llui/llnotifications.h
@@ -92,7 +92,6 @@
#include "llevents.h"
#include "llfunctorregistry.h"
#include "llinitparam.h"
-#include "llnotificationslistener.h"
#include "llnotificationptr.h"
#include "llpointer.h"
#include "llrefcount.h"
@@ -681,7 +680,6 @@ namespace LLNotificationComparators
};
typedef boost::function<bool (LLNotificationPtr)> LLNotificationFilter;
-typedef boost::function<bool (LLNotificationPtr, LLNotificationPtr)> LLNotificationComparator;
typedef std::set<LLNotificationPtr, LLNotificationComparators::orderByUUID> LLNotificationSet;
typedef std::multimap<std::string, LLNotificationPtr> LLNotificationMap;
@@ -776,6 +774,9 @@ protected:
virtual void onDelete(LLNotificationPtr p) {}
virtual void onChange(LLNotificationPtr p) {}
+ virtual void onFilterPass(LLNotificationPtr p) {}
+ virtual void onFilterFail(LLNotificationPtr p) {}
+
bool updateItem(const LLSD& payload, LLNotificationPtr pNotification);
LLNotificationFilter mFilter;
};
@@ -831,7 +832,6 @@ public:
private:
std::string mName;
std::string mParent;
- LLNotificationComparator mComparator;
};
// An interface class to provide a clean linker seam to the LLNotifications class.
@@ -951,7 +951,6 @@ private:
bool mIgnoreAllNotifications;
- boost::scoped_ptr<LLNotificationsListener> mListener;
std::vector<LLNotificationChannelPtr> mDefaultChannels;
};
@@ -1030,7 +1029,7 @@ protected:
// Stores only persistent notifications.
// Class users can use connectChanged() to process persistent notifications
-// (see LLNotificationStorage for example).
+// (see LLPersistentNotificationStorage for example).
class LLPersistentNotificationChannel : public LLNotificationChannel
{
LOG_CLASS(LLPersistentNotificationChannel);
diff --git a/indra/llui/llnotificationslistener.cpp b/indra/llui/llnotificationslistener.cpp
deleted file mode 100644
index e4e127336b..0000000000
--- a/indra/llui/llnotificationslistener.cpp
+++ /dev/null
@@ -1,354 +0,0 @@
-/**
- * @file llnotificationslistener.cpp
- * @author Brad Kittenbrink
- * @date 2009-07-08
- * @brief Implementation for llnotificationslistener.
- *
- * $LicenseInfo:firstyear=2009&license=viewerlgpl$
- * Second Life Viewer Source Code
- * 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.
- *
- * 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.
- *
- * 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
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-#include "linden_common.h"
-#include "llnotificationslistener.h"
-#include "llnotifications.h"
-#include "llnotificationtemplate.h"
-#include "llsd.h"
-#include "llui.h"
-
-LLNotificationsListener::LLNotificationsListener(LLNotifications & notifications) :
- LLEventAPI("LLNotifications",
- "LLNotifications listener to (e.g.) pop up a notification"),
- mNotifications(notifications)
-{
- add("requestAdd",
- "Add a notification with specified [\"name\"], [\"substitutions\"] and [\"payload\"].\n"
- "If optional [\"reply\"] specified, arrange to send user response on that LLEventPump.",
- &LLNotificationsListener::requestAdd);
- add("listChannels",
- "Post to [\"reply\"] a map of info on existing channels",
- &LLNotificationsListener::listChannels,
- LLSD().with("reply", LLSD()));
- add("listChannelNotifications",
- "Post to [\"reply\"] an array of info on notifications in channel [\"channel\"]",
- &LLNotificationsListener::listChannelNotifications,
- LLSD().with("reply", LLSD()).with("channel", LLSD()));
- add("respond",
- "Respond to notification [\"uuid\"] with data in [\"response\"]",
- &LLNotificationsListener::respond,
- LLSD().with("uuid", LLSD()));
- add("cancel",
- "Cancel notification [\"uuid\"]",
- &LLNotificationsListener::cancel,
- LLSD().with("uuid", LLSD()));
- add("ignore",
- "Ignore future notification [\"name\"]\n"
- "(from <notification name= > in notifications.xml)\n"
- "according to boolean [\"ignore\"].\n"
- "If [\"name\"] is omitted or undefined, [un]ignore all future notifications.\n"
- "Note that ignored notifications are not forwarded unless intercepted before\n"
- "the \"Ignore\" channel.",
- &LLNotificationsListener::ignore);
- add("forward",
- "Forward to [\"pump\"] future notifications on channel [\"channel\"]\n"
- "according to boolean [\"forward\"]. When enabled, only types matching\n"
- "[\"types\"] are forwarded, as follows:\n"
- "omitted or undefined: forward all notifications\n"
- "string: forward only the specific named [sig]type\n"
- "array of string: forward any notification matching any named [sig]type.\n"
- "When boolean [\"respond\"] is true, we auto-respond to each forwarded\n"
- "notification.",
- &LLNotificationsListener::forward,
- LLSD().with("channel", LLSD()));
-}
-
-// This is here in the .cpp file so we don't need the definition of class
-// Forwarder in the header file.
-LLNotificationsListener::~LLNotificationsListener()
-{
-}
-
-void LLNotificationsListener::requestAdd(const LLSD& event_data) const
-{
- if(event_data.has("reply"))
- {
- mNotifications.add(event_data["name"],
- event_data["substitutions"],
- event_data["payload"],
- boost::bind(&LLNotificationsListener::NotificationResponder,
- this,
- event_data["reply"].asString(),
- _1, _2
- )
- );
- }
- else
- {
- mNotifications.add(event_data["name"],
- event_data["substitutions"],
- event_data["payload"]);
- }
-}
-
-void LLNotificationsListener::NotificationResponder(const std::string& reply_pump,
- const LLSD& notification,
- const LLSD& response) const
-{
- LLSD reponse_event;
- reponse_event["notification"] = notification;
- reponse_event["response"] = response;
- LLEventPumps::getInstance()->obtain(reply_pump).post(reponse_event);
-}
-
-void LLNotificationsListener::listChannels(const LLSD& params) const
-{
- LLReqID reqID(params);
- LLSD response(reqID.makeResponse());
- for (LLNotificationChannel::instance_iter cmi(LLNotificationChannel::beginInstances()),
- cmend(LLNotificationChannel::endInstances());
- cmi != cmend; ++cmi)
- {
- LLSD channelInfo;
- //channelInfo["parent"] = cmi->second->getParentChannelName();
- response[cmi->getName()] = channelInfo;
- }
- LLEventPumps::instance().obtain(params["reply"]).post(response);
-}
-
-void LLNotificationsListener::listChannelNotifications(const LLSD& params) const
-{
- LLReqID reqID(params);
- LLSD response(reqID.makeResponse());
- LLNotificationChannelPtr channel(mNotifications.getChannel(params["channel"]));
- if (channel)
- {
- LLSD notifications(LLSD::emptyArray());
- for (LLNotificationChannel::Iterator ni(channel->begin()), nend(channel->end());
- ni != nend; ++ni)
- {
- notifications.append(asLLSD(*ni));
- }
- response["notifications"] = notifications;
- }
- LLEventPumps::instance().obtain(params["reply"]).post(response);
-}
-
-void LLNotificationsListener::respond(const LLSD& params) const
-{
- LLNotificationPtr notification(mNotifications.find(params["uuid"]));
- if (notification)
- {
- notification->respond(params["response"]);
- }
-}
-
-void LLNotificationsListener::cancel(const LLSD& params) const
-{
- LLNotificationPtr notification(mNotifications.find(params["uuid"]));
- if (notification)
- {
- mNotifications.cancel(notification);
- }
-}
-
-void LLNotificationsListener::ignore(const LLSD& params) const
-{
- // Calling a method named "ignore", but omitting its "ignore" Boolean
- // argument, should by default cause something to be ignored. Explicitly
- // pass ["ignore"] = false to cancel ignore.
- bool ignore = true;
- if (params.has("ignore"))
- {
- ignore = params["ignore"].asBoolean();
- }
- // This method can be used to affect either a single notification name or
- // all future notifications. The two use substantially different mechanisms.
- if (params["name"].isDefined())
- {
- // ["name"] was passed: ignore just that notification
- LLNotificationTemplatePtr templatep = mNotifications.getTemplate(params["name"]);
- if (templatep)
- {
- templatep->mForm->setIgnored(ignore);
- }
- }
- else
- {
- // no ["name"]: ignore all future notifications
- mNotifications.setIgnoreAllNotifications(ignore);
- }
-}
-
-class LLNotificationsListener::Forwarder: public LLEventTrackable
-{
- LOG_CLASS(LLNotificationsListener::Forwarder);
-public:
- Forwarder(LLNotifications& llnotifications, const std::string& channel):
- mNotifications(llnotifications),
- mRespond(false)
- {
- // Connect to the specified channel on construction. Because
- // LLEventTrackable is a base, we should automatically disconnect when
- // destroyed.
- LLNotificationChannelPtr channelptr(llnotifications.getChannel(channel));
- if (channelptr)
- {
- // Insert our processing as a "passed filter" listener. This way
- // we get to run before all the "changed" listeners, and we get to
- // swipe it (hide it from the other listeners) if desired.
- channelptr->connectPassedFilter(boost::bind(&Forwarder::handle, this, _1));
- }
- }
-
- void setPumpName(const std::string& name) { mPumpName = name; }
- void setTypes(const LLSD& types) { mTypes = types; }
- void setRespond(bool respond) { mRespond = respond; }
-
-private:
- bool handle(const LLSD& notification) const;
- bool matchType(const LLSD& filter, const std::string& type) const;
-
- LLNotifications& mNotifications;
- std::string mPumpName;
- LLSD mTypes;
- bool mRespond;
-};
-
-void LLNotificationsListener::forward(const LLSD& params)
-{
- std::string channel(params["channel"]);
- // First decide whether we're supposed to start forwarding or stop it.
- // Default to true.
- bool forward = true;
- if (params.has("forward"))
- {
- forward = params["forward"].asBoolean();
- }
- if (! forward)
- {
- // This is a request to stop forwarding notifications on the specified
- // channel. The rest of the params don't matter.
- // Because mForwarders contains scoped_ptrs, erasing the map entry
- // DOES delete the heap Forwarder object. Because Forwarder derives
- // from LLEventTrackable, destroying it disconnects it from the
- // channel.
- mForwarders.erase(channel);
- return;
- }
- // From here on, we know we're being asked to start (or modify) forwarding
- // on the specified channel. Find or create an appropriate Forwarder.
- ForwarderMap::iterator
- entry(mForwarders.insert(ForwarderMap::value_type(channel, ForwarderMap::mapped_type())).first);
- if (! entry->second)
- {
- entry->second.reset(new Forwarder(mNotifications, channel));
- }
- // Now, whether this Forwarder is brand-new or not, update it with the new
- // request info.
- Forwarder& fwd(*entry->second);
- fwd.setPumpName(params["pump"]);
- fwd.setTypes(params["types"]);
- fwd.setRespond(params["respond"]);
-}
-
-bool LLNotificationsListener::Forwarder::handle(const LLSD& notification) const
-{
- LL_INFOS("LLNotificationsListener") << "handle(" << notification << ")" << LL_ENDL;
- if (notification["sigtype"].asString() == "delete")
- {
- LL_INFOS("LLNotificationsListener") << "ignoring delete" << LL_ENDL;
- // let other listeners see the "delete" operation
- return false;
- }
- LLNotificationPtr note(mNotifications.find(notification["id"]));
- if (! note)
- {
- LL_INFOS("LLNotificationsListener") << notification["id"] << " not found" << LL_ENDL;
- return false;
- }
- if (! matchType(mTypes, note->getType()))
- {
- LL_INFOS("LLNotificationsListener") << "didn't match types " << mTypes << LL_ENDL;
- // We're not supposed to intercept this particular notification. Let
- // other listeners process it.
- return false;
- }
- LL_INFOS("LLNotificationsListener") << "sending via '" << mPumpName << "'" << LL_ENDL;
- // This is a notification we care about. Forward it through specified
- // LLEventPump.
- LLEventPumps::instance().obtain(mPumpName).post(asLLSD(note));
- // Are we also being asked to auto-respond?
- if (mRespond)
- {
- LL_INFOS("LLNotificationsListener") << "should respond" << LL_ENDL;
- note->respond(LLSD::emptyMap());
- // Did that succeed in removing the notification? Only cancel() if
- // it's still around -- otherwise we get an LL_ERRS crash!
- note = mNotifications.find(notification["id"]);
- if (note)
- {
- LL_INFOS("LLNotificationsListener") << "respond() didn't clear, canceling" << LL_ENDL;
- mNotifications.cancel(note);
- }
- }
- // If we've auto-responded to this notification, then it's going to be
- // deleted. Other listeners would get the change operation, try to look it
- // up and be baffled by lookup failure. So when we auto-respond, suppress
- // this notification: don't pass it to other listeners.
- return mRespond;
-}
-
-bool LLNotificationsListener::Forwarder::matchType(const LLSD& filter, const std::string& type) const
-{
- // Decide whether this notification matches filter:
- // undefined: forward all notifications
- if (filter.isUndefined())
- {
- return true;
- }
- // array of string: forward any notification matching any named type
- if (filter.isArray())
- {
- for (LLSD::array_const_iterator ti(filter.beginArray()), tend(filter.endArray());
- ti != tend; ++ti)
- {
- if (ti->asString() == type)
- {
- return true;
- }
- }
- // Didn't match any entry in the array
- return false;
- }
- // string: forward only the specific named type
- return (filter.asString() == type);
-}
-
-LLSD LLNotificationsListener::asLLSD(LLNotificationPtr note)
-{
- LLSD notificationInfo(note->asLLSD());
- // For some reason the following aren't included in LLNotification::asLLSD().
- notificationInfo["summary"] = note->summarize();
- notificationInfo["id"] = note->id();
- notificationInfo["type"] = note->getType();
- notificationInfo["message"] = note->getMessage();
- notificationInfo["label"] = note->getLabel();
- return notificationInfo;
-}
diff --git a/indra/llui/llnotificationslistener.h b/indra/llui/llnotificationslistener.h
deleted file mode 100644
index f9f7641de6..0000000000
--- a/indra/llui/llnotificationslistener.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/**
- * @file llnotificationslistener.h
- * @author Brad Kittenbrink
- * @date 2009-07-08
- * @brief Wrap subset of LLNotifications API in event API for test scripts.
- *
- * $LicenseInfo:firstyear=2009&license=viewerlgpl$
- * Second Life Viewer Source Code
- * 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.
- *
- * 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.
- *
- * 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
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-#ifndef LL_LLNOTIFICATIONSLISTENER_H
-#define LL_LLNOTIFICATIONSLISTENER_H
-
-#include "lleventapi.h"
-#include "llnotificationptr.h"
-#include <boost/shared_ptr.hpp>
-#include <map>
-#include <string>
-
-class LLNotifications;
-class LLSD;
-
-class LLNotificationsListener : public LLEventAPI
-{
-public:
- LLNotificationsListener(LLNotifications & notifications);
- ~LLNotificationsListener();
-
-private:
- void requestAdd(LLSD const & event_data) const;
-
- void NotificationResponder(const std::string& replypump,
- const LLSD& notification,
- const LLSD& response) const;
-
- void listChannels(const LLSD& params) const;
- void listChannelNotifications(const LLSD& params) const;
- void respond(const LLSD& params) const;
- void cancel(const LLSD& params) const;
- void ignore(const LLSD& params) const;
- void forward(const LLSD& params);
-
- static LLSD asLLSD(LLNotificationPtr);
-
- class Forwarder;
- typedef std::map<std::string, boost::shared_ptr<Forwarder> > ForwarderMap;
- ForwarderMap mForwarders;
- LLNotifications & mNotifications;
-};
-
-#endif // LL_LLNOTIFICATIONSLISTENER_H
diff --git a/indra/llui/llnotificationtemplate.h b/indra/llui/llnotificationtemplate.h
index 906b83a400..18a82190b5 100644
--- a/indra/llui/llnotificationtemplate.h
+++ b/indra/llui/llnotificationtemplate.h
@@ -49,7 +49,6 @@
//#include "llfunctorregistry.h"
//#include "llpointer.h"
#include "llinitparam.h"
-//#include "llnotificationslistener.h"
//#include "llnotificationptr.h"
//#include "llcachename.h"
#include "llnotifications.h"
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index c9176d71fb..d43f9e9988 100755
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -137,6 +137,7 @@ set(viewer_SOURCE_FILES
llcommanddispatcherlistener.cpp
llcommandhandler.cpp
llcommandlineparser.cpp
+ llcommunicationchannel.cpp
llcompilequeue.cpp
llconfirmationmanager.cpp
llconversationlog.cpp
@@ -152,6 +153,7 @@ set(viewer_SOURCE_FILES
lldebugview.cpp
lldelayedgestureerror.cpp
lldirpicker.cpp
+ lldonotdisturbnotificationstorage.cpp
lldndbutton.cpp
lldrawable.cpp
lldrawpool.cpp
@@ -448,6 +450,7 @@ set(viewer_SOURCE_FILES
llpathfindingobject.cpp
llpathfindingobjectlist.cpp
llpathfindingpathtool.cpp
+ llpersistentnotificationstorage.cpp
llphysicsmotion.cpp
llphysicsshapebuilderutil.cpp
llplacesinventorybridge.cpp
@@ -722,6 +725,7 @@ set(viewer_HEADER_FILES
llcommanddispatcherlistener.h
llcommandhandler.h
llcommandlineparser.h
+ llcommunicationchannel.h
llcompilequeue.h
llconfirmationmanager.h
llconversationlog.h
@@ -737,6 +741,7 @@ set(viewer_HEADER_FILES
lldebugview.h
lldelayedgestureerror.h
lldirpicker.h
+ lldonotdisturbnotificationstorage.h
lldndbutton.h
lldrawable.h
lldrawpool.h
@@ -1021,6 +1026,7 @@ set(viewer_HEADER_FILES
llpathfindingobject.h
llpathfindingobjectlist.h
llpathfindingpathtool.h
+ llpersistentnotificationstorage.h
llphysicsmotion.h
llphysicsshapebuilderutil.h
llplacesinventorybridge.h
diff --git a/indra/newview/llbrowsernotification.cpp b/indra/newview/llbrowsernotification.cpp
index 9e608d2c8b..19747757db 100644
--- a/indra/newview/llbrowsernotification.cpp
+++ b/indra/newview/llbrowsernotification.cpp
@@ -35,6 +35,11 @@
using namespace LLNotificationsUI;
+LLBrowserNotification::LLBrowserNotification()
+ : LLSystemNotificationHandler("Browser", "browser")
+{
+}
+
bool LLBrowserNotification::processNotification(const LLNotificationPtr& notification)
{
LLUUID media_id = notification->getPayload()["media_id"].asUUID();
diff --git a/indra/newview/llchannelmanager.cpp b/indra/newview/llchannelmanager.cpp
index 987651fc80..dd2bcc742b 100644
--- a/indra/newview/llchannelmanager.cpp
+++ b/indra/newview/llchannelmanager.cpp
@@ -29,7 +29,8 @@
#include "llchannelmanager.h"
#include "llappviewer.h"
-#include "llnotificationstorage.h"
+#include "lldonotdisturbnotificationstorage.h"
+#include "llpersistentnotificationstorage.h"
#include "llviewercontrol.h"
#include "llviewerwindow.h"
#include "llrootview.h"
@@ -138,6 +139,7 @@ void LLChannelManager::onLoginCompleted()
}
LLPersistentNotificationStorage::getInstance()->loadNotifications();
+ LLDoNotDisturbNotificationStorage::getInstance()->initialize();
}
//--------------------------------------------------------------------------
diff --git a/indra/newview/llchatbar.cpp b/indra/newview/llchatbar.cpp
index 27138e6c06..7d0331757b 100644
--- a/indra/newview/llchatbar.cpp
+++ b/indra/newview/llchatbar.cpp
@@ -669,47 +669,3 @@ void LLChatBar::onCommitGesture(LLUICtrl* ctrl)
mGestureCombo->setFocus(FALSE);
}
}
-
-
-/* Cruft - global gChatHandler declared below has been commented out,
- so this class is never used. See similar code in llfloaterimnearbychatbar.cpp
-class LLChatHandler : public LLCommandHandler
-{
-public:
- // not allowed from outside the app
- LLChatHandler() : LLCommandHandler("chat", UNTRUSTED_BLOCK) { }
-
- // Your code here
- bool handle(const LLSD& tokens, const LLSD& query_map,
- LLMediaCtrl* web)
- {
- bool retval = false;
- // Need at least 2 tokens to have a valid message.
- if (tokens.size() < 2)
- {
- retval = false;
- }
- else
- {
- S32 channel = tokens[0].asInteger();
- // VWR-19499 Restrict function to chat channels greater than 0.
- if ((channel > 0) && (channel < CHAT_CHANNEL_DEBUG))
- {
- retval = true;
- // Say mesg on channel
- std::string mesg = tokens[1].asString();
- send_chat_from_viewer(mesg, CHAT_TYPE_NORMAL, channel);
- }
- else
- {
- retval = false;
- // Tell us this is an unsupported SLurl.
- }
- }
- return retval;
- }
-};
-
-// Creating the object registers with the dispatcher.
-//LLChatHandler gChatHandler;
-cruft */
diff --git a/indra/newview/llcommunicationchannel.cpp b/indra/newview/llcommunicationchannel.cpp
new file mode 100644
index 0000000000..353447e4b6
--- /dev/null
+++ b/indra/newview/llcommunicationchannel.cpp
@@ -0,0 +1,73 @@
+/**
+* @file llcommunicationchannel.cpp
+* @brief Implementation of llcommunicationchannel
+* @author Stinson@lindenlab.com
+*
+* $LicenseInfo:firstyear=2012&license=viewerlgpl$
+* Second Life Viewer Source Code
+* Copyright (C) 2012, 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.
+*
+* 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.
+*
+* 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
+*
+* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+* $/LicenseInfo$
+*/
+
+#include "llviewerprecompiledheaders.h" // must be first include
+
+#include "llcommunicationchannel.h"
+
+#include <string>
+#include <map>
+
+#include "llagent.h"
+#include "lldate.h"
+#include "llnotifications.h"
+
+
+LLCommunicationChannel::LLCommunicationChannel(const std::string& pName, const std::string& pParentName)
+ : LLNotificationChannel(pName, pParentName, filterByDoNotDisturbStatus)
+{
+}
+
+LLCommunicationChannel::~LLCommunicationChannel()
+{
+}
+
+bool LLCommunicationChannel::filterByDoNotDisturbStatus(LLNotificationPtr)
+{
+ return !gAgent.isDoNotDisturb();
+}
+
+LLCommunicationChannel::history_list_t::const_iterator LLCommunicationChannel::beginHistory() const
+{
+ return mHistory.begin();
+}
+
+LLCommunicationChannel::history_list_t::const_iterator LLCommunicationChannel::endHistory() const
+{
+ return mHistory.end();
+}
+
+void LLCommunicationChannel::onFilterFail(LLNotificationPtr pNotificationPtr)
+{
+ std::string notificationType = pNotificationPtr->getType();
+ if ((notificationType == "groupnotify")
+ || (notificationType == "offer")
+ || (notificationType == "notifytoast"))
+ {
+ mHistory.insert(std::make_pair<LLDate, LLNotificationPtr>(pNotificationPtr->getDate(), pNotificationPtr));
+ }
+}
diff --git a/indra/newview/llcommunicationchannel.h b/indra/newview/llcommunicationchannel.h
new file mode 100644
index 0000000000..a4756b8993
--- /dev/null
+++ b/indra/newview/llcommunicationchannel.h
@@ -0,0 +1,59 @@
+/**
+* @file llcommunicationchannel.h
+* @brief Header file for llcommunicationchannel
+* @author Stinson@lindenlab.com
+*
+* $LicenseInfo:firstyear=2012&license=viewerlgpl$
+* Second Life Viewer Source Code
+* Copyright (C) 2012, 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.
+*
+* 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.
+*
+* 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
+*
+* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+* $/LicenseInfo$
+*/
+#ifndef LL_LLCOMMUNICATIONCHANNEL_H
+#define LL_LLCOMMUNICATIONCHANNEL_H
+
+#include <string>
+#include <map>
+
+#include "lldate.h"
+#include "llerror.h"
+#include "llnotifications.h"
+
+class LLCommunicationChannel : public LLNotificationChannel
+{
+ LOG_CLASS(LLCommunicationChannel);
+public:
+ LLCommunicationChannel(const std::string& pName, const std::string& pParentName);
+ virtual ~LLCommunicationChannel();
+
+ static bool filterByDoNotDisturbStatus(LLNotificationPtr);
+
+ typedef std::multimap<LLDate, LLNotificationPtr> history_list_t;
+ history_list_t::const_iterator beginHistory() const;
+ history_list_t::const_iterator endHistory() const;
+
+protected:
+ virtual void onFilterFail(LLNotificationPtr pNotificationPtr);
+
+private:
+
+ history_list_t mHistory;
+};
+
+#endif // LL_LLCOMMUNICATIONCHANNEL_H
+
diff --git a/indra/newview/lldonotdisturbnotificationstorage.cpp b/indra/newview/lldonotdisturbnotificationstorage.cpp
new file mode 100644
index 0000000000..472a0dd9ee
--- /dev/null
+++ b/indra/newview/lldonotdisturbnotificationstorage.cpp
@@ -0,0 +1,106 @@
+/**
+* @file lldonotdisturbnotificationstorage.cpp
+* @brief Implementation of lldonotdisturbnotificationstorage
+* @author Stinson@lindenlab.com
+*
+* $LicenseInfo:firstyear=2012&license=viewerlgpl$
+* Second Life Viewer Source Code
+* Copyright (C) 2012, 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.
+*
+* 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.
+*
+* 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
+*
+* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+* $/LicenseInfo$
+*/
+
+#include "llviewerprecompiledheaders.h"
+
+#include "lldonotdisturbnotificationstorage.h"
+
+#include "llcommunicationchannel.h"
+#include "lldir.h"
+#include "llerror.h"
+#include "llfasttimer_class.h"
+#include "llnotifications.h"
+#include "llnotificationstorage.h"
+#include "llsd.h"
+#include "llsingleton.h"
+
+LLDoNotDisturbNotificationStorage::LLDoNotDisturbNotificationStorage()
+ : LLSingleton<LLDoNotDisturbNotificationStorage>()
+ , LLNotificationStorage(gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, "dnd_notifications.xml"))
+{
+}
+
+LLDoNotDisturbNotificationStorage::~LLDoNotDisturbNotificationStorage()
+{
+}
+
+void LLDoNotDisturbNotificationStorage::initialize()
+{
+ getCommunicationChannel()->connectFailedFilter(boost::bind(&LLDoNotDisturbNotificationStorage::onChannelChanged, this, _1));
+}
+
+static LLFastTimer::DeclareTimer FTM_SAVE_DND_NOTIFICATIONS("Save DND Notifications");
+
+void LLDoNotDisturbNotificationStorage::saveNotifications()
+{
+ LLFastTimer _(FTM_SAVE_DND_NOTIFICATIONS);
+
+ LLNotificationChannelPtr channelPtr = getCommunicationChannel();
+ const LLCommunicationChannel *commChannel = dynamic_cast<LLCommunicationChannel*>(channelPtr.get());
+ llassert(commChannel != NULL);
+
+ LLSD output = LLSD::emptyMap();
+ LLSD& data = output["data"];
+ data = LLSD::emptyArray();
+
+ for (LLCommunicationChannel::history_list_t::const_iterator historyIter = commChannel->beginHistory();
+ historyIter != commChannel->endHistory(); ++historyIter)
+ {
+ LLNotificationPtr notificationPtr = historyIter->second;
+
+ if (!notificationPtr->isRespondedTo() && !notificationPtr->isCancelled() && !notificationPtr->isExpired())
+ {
+ data.append(notificationPtr->asLLSD());
+ }
+ }
+
+ writeNotifications(output);
+}
+
+static LLFastTimer::DeclareTimer FTM_LOAD_DND_NOTIFICATIONS("Load DND Notifications");
+
+void LLDoNotDisturbNotificationStorage::loadNotifications()
+{
+}
+
+LLNotificationChannelPtr LLDoNotDisturbNotificationStorage::getCommunicationChannel() const
+{
+ LLNotificationChannelPtr channelPtr = LLNotifications::getInstance()->getChannel("Communication");
+ llassert(channelPtr);
+ return channelPtr;
+}
+
+
+bool LLDoNotDisturbNotificationStorage::onChannelChanged(const LLSD& pPayload)
+{
+ if (pPayload["sigtype"].asString() != "load")
+ {
+ saveNotifications();
+ }
+
+ return false;
+}
diff --git a/indra/newview/lldonotdisturbnotificationstorage.h b/indra/newview/lldonotdisturbnotificationstorage.h
new file mode 100644
index 0000000000..60bcd89ec3
--- /dev/null
+++ b/indra/newview/lldonotdisturbnotificationstorage.h
@@ -0,0 +1,57 @@
+/**
+* @file lldonotdisturbnotificationstorage.h
+* @brief Header file for lldonotdisturbnotificationstorage
+* @author Stinson@lindenlab.com
+*
+* $LicenseInfo:firstyear=2012&license=viewerlgpl$
+* Second Life Viewer Source Code
+* Copyright (C) 2012, 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.
+*
+* 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.
+*
+* 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
+*
+* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+* $/LicenseInfo$
+*/
+#ifndef LL_LLDONOTDISTURBNOTIFICATIONSTORAGE_H
+#define LL_LLDONOTDISTURBNOTIFICATIONSTORAGE_H
+
+#include "llerror.h"
+#include "llnotifications.h"
+#include "llnotificationstorage.h"
+#include "llsingleton.h"
+
+class LLSD;
+
+class LLDoNotDisturbNotificationStorage : public LLSingleton<LLDoNotDisturbNotificationStorage>, public LLNotificationStorage
+{
+ LOG_CLASS(LLDoNotDisturbNotificationStorage);
+public:
+ LLDoNotDisturbNotificationStorage();
+ ~LLDoNotDisturbNotificationStorage();
+
+ void initialize();
+
+ void saveNotifications();
+ void loadNotifications();
+
+protected:
+
+private:
+ LLNotificationChannelPtr getCommunicationChannel() const;
+ bool onChannelChanged(const LLSD& pPayload);
+};
+
+#endif // LL_LLDONOTDISTURBNOTIFICATIONSTORAGE_H
+
diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp
index ba5ec363d6..390eec84f6 100644
--- a/indra/newview/llfloaterimcontainer.cpp
+++ b/indra/newview/llfloaterimcontainer.cpp
@@ -1412,17 +1412,18 @@ bool LLFloaterIMContainer::removeConversationListItem(const LLUUID& uuid, bool c
// Delete the widget and the associated conversation item
// Note : since the mConversationsItems is also the listener to the widget, deleting
// the widget will also delete its listener
- bool isWidgetSelected = false;
+ bool is_widget_selected = false;
LLFolderViewItem* new_selection = NULL;
LLFolderViewItem* widget = get_ptr_in_map(mConversationsWidgets,uuid);
if (widget)
{
- isWidgetSelected = widget->isSelected();
+ is_widget_selected = widget->isSelected();
new_selection = mConversationsRoot->getNextFromChild(widget);
if(new_selection == NULL)
{
new_selection = mConversationsRoot->getPreviousFromChild(widget);
}
+
widget->destroyView();
}
@@ -1445,7 +1446,7 @@ bool LLFloaterIMContainer::removeConversationListItem(const LLUUID& uuid, bool c
}
}
}
- return isWidgetSelected;
+ return is_widget_selected;
}
LLConversationViewSession* LLFloaterIMContainer::createConversationItemWidget(LLConversationItem* item)
diff --git a/indra/newview/llfloaterimsession.cpp b/indra/newview/llfloaterimsession.cpp
index a0ca7286f1..ff07ddfcbf 100644
--- a/indra/newview/llfloaterimsession.cpp
+++ b/indra/newview/llfloaterimsession.cpp
@@ -73,8 +73,7 @@ LLFloaterIMSession::LLFloaterIMSession(const LLUUID& session_id)
mTypingTimer(),
mTypingTimeoutTimer(),
mPositioned(false),
- mSessionInitialized(false),
- mStartConferenceInSameFloater(false)
+ mSessionInitialized(false)
{
mIsNearbyChat = false;
@@ -83,6 +82,9 @@ LLFloaterIMSession::LLFloaterIMSession(const LLUUID& session_id)
setOverlapsScreenChannel(true);
LLTransientFloaterMgr::getInstance()->addControlView(LLTransientFloaterMgr::IM, this);
+ mEnableCallbackRegistrar.add("Avatar.EnableGearItem", boost::bind(&LLFloaterIMSession::enableGearMenuItem, this, _2));
+ mCommitCallbackRegistrar.add("Avatar.GearDoToSelected", boost::bind(&LLFloaterIMSession::GearDoToSelected, this, _2));
+ mEnableCallbackRegistrar.add("Avatar.CheckGearItem", boost::bind(&LLFloaterIMSession::checkGearMenuItem, this, _2));
setDocked(true);
}
@@ -190,6 +192,36 @@ void LLFloaterIMSession::onSendMsg( LLUICtrl* ctrl, void* userdata )
self->setTyping(false);
}
+bool LLFloaterIMSession::enableGearMenuItem(const LLSD& userdata)
+{
+ std::string command = userdata.asString();
+ uuid_vec_t selected_uuids;
+ selected_uuids.push_back(mOtherParticipantUUID);
+
+ LLFloaterIMContainer* floater_container = LLFloaterIMContainer::getInstance();
+ return floater_container->enableContextMenuItem(command, selected_uuids);
+}
+
+void LLFloaterIMSession::GearDoToSelected(const LLSD& userdata)
+{
+ std::string command = userdata.asString();
+ uuid_vec_t selected_uuids;
+ selected_uuids.push_back(mOtherParticipantUUID);
+
+ LLFloaterIMContainer* floater_container = LLFloaterIMContainer::getInstance();
+ floater_container->doToParticipants(command, selected_uuids);
+}
+
+bool LLFloaterIMSession::checkGearMenuItem(const LLSD& userdata)
+{
+ std::string command = userdata.asString();
+ uuid_vec_t selected_uuids;
+ selected_uuids.push_back(mOtherParticipantUUID);
+
+ LLFloaterIMContainer* floater_container = LLFloaterIMContainer::getInstance();
+ return floater_container->checkContextMenuItem(command, selected_uuids);
+}
+
void LLFloaterIMSession::sendMsgFromInputEditor()
{
if (gAgent.isGodlike()
@@ -429,8 +461,6 @@ void LLFloaterIMSession::addP2PSessionParticipants(const LLSD& notification, con
return;
}
- mStartConferenceInSameFloater = true;
-
LLVoiceChannel* voice_channel = LLIMModel::getInstance()->getVoiceChannel(mSessionID);
// first check whether this is a voice session
diff --git a/indra/newview/llfloaterimsession.h b/indra/newview/llfloaterimsession.h
index 1d8957b1d9..6a2f4b29eb 100644
--- a/indra/newview/llfloaterimsession.h
+++ b/indra/newview/llfloaterimsession.h
@@ -99,6 +99,9 @@ public:
void setPositioned(bool b) { mPositioned = b; };
void onVisibilityChange(const LLSD& new_visibility);
+ bool enableGearMenuItem(const LLSD& userdata);
+ void GearDoToSelected(const LLSD& userdata);
+ bool checkGearMenuItem(const LLSD& userdata);
// Implements LLVoiceClientStatusObserver::onChange() to enable the call
// button when voice is available
@@ -124,8 +127,6 @@ public:
//used as a callback on receiving new IM message
static void sRemoveTypingIndicator(const LLSD& data);
static void onIMChicletCreated(const LLUUID& session_id);
-
- bool getStartConferenceInSameFloater() const { return mStartConferenceInSameFloater; }
const LLUUID& getOtherParticipantUUID() {return mOtherParticipantUUID;}
static boost::signals2::connection setIMFloaterShowedCallback(const floater_showed_signal_t::slot_type& cb);
@@ -185,8 +186,6 @@ private:
bool mSessionInitialized;
LLSD mQueuedMsgsForInit;
- bool mStartConferenceInSameFloater;
-
uuid_vec_t mInvitedParticipants;
// connection to voice channel state change signal
diff --git a/indra/newview/llfloaterimsessiontab.cpp b/indra/newview/llfloaterimsessiontab.cpp
index ea99a1c5bf..7984034ded 100644
--- a/indra/newview/llfloaterimsessiontab.cpp
+++ b/indra/newview/llfloaterimsessiontab.cpp
@@ -177,6 +177,7 @@ void LLFloaterIMSessionTab::addToHost(const LLUUID& session_id)
// LLFloater::mLastHostHandle = floater_container (a "future" host)
conversp->setHost(floater_container);
conversp->setHost(NULL);
+ conversp->forceReshape();
}
// Added floaters share some state (like sort order) with their host
conversp->setSortOrder(floater_container->getSortOrder());
@@ -197,6 +198,8 @@ BOOL LLFloaterIMSessionTab::postBuild()
mTearOffBtn = getChild<LLButton>("tear_off_btn");
mTearOffBtn->setCommitCallback(boost::bind(&LLFloaterIMSessionTab::onTearOffClicked, this));
+ mGearBtn = getChild<LLButton>("gear_btn");
+
mParticipantListPanel = getChild<LLLayoutPanel>("speakers_list_panel");
// Add a scroller for the folder (participant) view
@@ -224,7 +227,8 @@ BOOL LLFloaterIMSessionTab::postBuild()
setOpenPositioning(LLFloaterEnums::POSITIONING_RELATIVE);
- mSaveRect = isTornOff();
+ mSaveRect = isNearbyChat()
+ && !gSavedSettings.getBOOL("NearbyChatIsNotTornOff");
initRectControl();
if (isChatMultiTab())
@@ -239,11 +243,11 @@ BOOL LLFloaterIMSessionTab::postBuild()
// Now ready to build the conversation and participants list
buildConversationViewParticipant();
refreshConversation();
-
+
// Zero expiry time is set only once to allow initial update.
mRefreshTimer->setTimerExpirySec(0);
mRefreshTimer->start();
-
+ initBtns();
return result;
}
@@ -649,6 +653,15 @@ void LLFloaterIMSessionTab::updateHeaderAndToolbar()
showTranslationCheckbox();
}
+
+void LLFloaterIMSessionTab::forceReshape()
+{
+ LLRect floater_rect = getRect();
+ reshape(llmax(floater_rect.getWidth(), this->getMinWidth()),
+ llmax(floater_rect.getHeight(), this->getMinHeight()),
+ true);
+}
+
void LLFloaterIMSessionTab::reshapeChatHistory()
{
@@ -735,19 +748,6 @@ void LLFloaterIMSessionTab::onOpen(const LLSD& key)
}
}
-// virtual
-void LLFloaterIMSessionTab::onClose(bool app_quitting)
-{
- // Always suppress the IM from the conversations list on close if present for any reason
- if (LLFloaterIMSessionTab::isChatMultiTab())
- {
- LLFloaterIMContainer* im_box = LLFloaterIMContainer::findInstance();
- if (im_box)
- {
- im_box->removeConversationListItem(mKey);
- }
- }
-}
void LLFloaterIMSessionTab::onTearOffClicked()
{
@@ -755,7 +755,58 @@ void LLFloaterIMSessionTab::onTearOffClicked()
mSaveRect = isTornOff();
initRectControl();
LLFloater::onClickTearOff(this);
+ if (isTornOff())
+ {
+ forceReshape();
+ }
refreshConversation();
+ updateGearBtn();
+}
+
+void LLFloaterIMSessionTab::updateGearBtn()
+{
+
+ BOOL prevVisibility = mGearBtn->getVisible();
+ mGearBtn->setVisible(checkIfTornOff() && mIsP2PChat);
+
+
+ // Move buttons if Gear button changed visibility
+ if(prevVisibility != mGearBtn->getVisible())
+ {
+ LLRect gear_btn_rect = mGearBtn->getRect();
+ LLRect add_btn_rect = getChild<LLButton>("add_btn")->getRect();
+ LLRect call_btn_rect = getChild<LLButton>("voice_call_btn")->getRect();
+ S32 gap_width = call_btn_rect.mLeft - add_btn_rect.mRight;
+ S32 right_shift = gear_btn_rect.getWidth() + gap_width;
+ if(mGearBtn->getVisible())
+ {
+ // Move buttons to the right to give space for Gear button
+ add_btn_rect.translate(right_shift,0);
+ call_btn_rect.translate(right_shift,0);
+ }
+ else
+ {
+ add_btn_rect.translate(-right_shift,0);
+ call_btn_rect.translate(-right_shift,0);
+ }
+ getChild<LLButton>("add_btn")->setRect(add_btn_rect);
+ getChild<LLButton>("voice_call_btn")->setRect(call_btn_rect);
+ }
+}
+
+void LLFloaterIMSessionTab::initBtns()
+{
+ LLRect gear_btn_rect = mGearBtn->getRect();
+ LLRect add_btn_rect = getChild<LLButton>("add_btn")->getRect();
+ LLRect call_btn_rect = getChild<LLButton>("voice_call_btn")->getRect();
+ S32 gap_width = call_btn_rect.mLeft - add_btn_rect.mRight;
+ S32 right_shift = gear_btn_rect.getWidth() + gap_width;
+
+ add_btn_rect.translate(-right_shift,0);
+ call_btn_rect.translate(-right_shift,0);
+
+ getChild<LLButton>("add_btn")->setRect(add_btn_rect);
+ getChild<LLButton>("voice_call_btn")->setRect(call_btn_rect);
}
// static
diff --git a/indra/newview/llfloaterimsessiontab.h b/indra/newview/llfloaterimsessiontab.h
index cd0bcd481c..0fa99a46be 100644
--- a/indra/newview/llfloaterimsessiontab.h
+++ b/indra/newview/llfloaterimsessiontab.h
@@ -77,7 +77,6 @@ public:
// LLFloater overrides
/*virtual*/ void onOpen(const LLSD& key);
- /*virtual*/ void onClose(bool app_quitting);
/*virtual*/ BOOL postBuild();
/*virtual*/ void draw();
/*virtual*/ void setVisible(BOOL visible);
@@ -92,10 +91,13 @@ public:
void setSortOrder(const LLConversationSort& order);
virtual void onTearOffClicked();
-
+ void updateGearBtn();
+ void initBtns();
virtual void updateMessages() {}
LLConversationItem* getCurSelectedViewModelItem();
+ void forceReshape();
+
protected:
// callback for click on any items of the visual states menu
@@ -157,6 +159,8 @@ protected:
LLButton* mExpandCollapseBtn;
LLButton* mTearOffBtn;
LLButton* mCloseBtn;
+ LLButton* mGearBtn;
+
private:
// Handling selection and contextual menu
diff --git a/indra/newview/llfloateroutbox.cpp b/indra/newview/llfloateroutbox.cpp
index 18ed36d0f3..29a3e6ac3a 100644
--- a/indra/newview/llfloateroutbox.cpp
+++ b/indra/newview/llfloateroutbox.cpp
@@ -49,6 +49,11 @@
/// LLOutboxNotification class
///----------------------------------------------------------------------------
+LLNotificationsUI::LLOutboxNotification::LLOutboxNotification()
+ : LLSystemNotificationHandler("Outbox", "outbox")
+{
+}
+
bool LLNotificationsUI::LLOutboxNotification::processNotification(const LLNotificationPtr& notify)
{
LLFloaterOutbox* outbox_floater = LLFloaterReg::getTypedInstance<LLFloaterOutbox>("outbox");
@@ -60,10 +65,10 @@ bool LLNotificationsUI::LLOutboxNotification::processNotification(const LLNotifi
void LLNotificationsUI::LLOutboxNotification::onDelete(LLNotificationPtr p)
{
- LLNotificationsUI::LLSysHandler * sys_handler = dynamic_cast<LLNotificationsUI::LLSysHandler*>(LLNotifications::instance().getChannel("AlertModal").get());
- if (sys_handler)
+ LLNotificationsUI::LLNotificationHandler * notification_handler = dynamic_cast<LLNotificationsUI::LLNotificationHandler*>(LLNotifications::instance().getChannel("AlertModal").get());
+ if (notification_handler)
{
- sys_handler->onDelete(p);
+ notification_handler->onDelete(p);
}
}
@@ -524,9 +529,9 @@ void LLFloaterOutbox::initializationReportError(U32 status, const LLSD& content)
void LLFloaterOutbox::showNotification(const LLNotificationPtr& notification)
{
- LLNotificationsUI::LLSysHandler * sys_handler = dynamic_cast<LLNotificationsUI::LLSysHandler*>(LLNotifications::instance().getChannel("AlertModal").get());
- llassert(sys_handler);
+ LLNotificationsUI::LLNotificationHandler * notification_handler = dynamic_cast<LLNotificationsUI::LLNotificationHandler*>(LLNotifications::instance().getChannel("AlertModal").get());
+ llassert(notification_handler);
- sys_handler->processNotification(notification);
+ notification_handler->processNotification(notification);
}
diff --git a/indra/newview/llimhandler.cpp b/indra/newview/llimhandler.cpp
index 047472a282..72967eb6c7 100644
--- a/indra/newview/llimhandler.cpp
+++ b/indra/newview/llimhandler.cpp
@@ -38,7 +38,7 @@ using namespace LLNotificationsUI;
//--------------------------------------------------------------------------
LLIMHandler::LLIMHandler()
-: LLSysHandler("IM Notifications", "notifytoast")
+: LLCommunicationNotificationHandler("IM Notifications", "notifytoast")
{
// Getting a Channel for our notifications
mChannel = LLChannelManager::getInstance()->createNotificationChannel()->getHandle();
diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index da3d2e89bf..5b4d5466a1 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -149,7 +149,7 @@ void on_new_message(const LLSD& msg)
}
// do not show notification in "do not disturb" mode or it goes from agent
- if (gAgent.isDoNotDisturb() || gAgent.getID() == participant_id)
+ if (gAgent.getID() == participant_id)
{
return;
}
@@ -160,10 +160,16 @@ void on_new_message(const LLSD& msg)
LLFloaterIMSessionTab* session_floater = LLFloaterIMSessionTab::getConversation(session_id);
//session floater not focused (visible or not)
- bool sessionFloaterNotFocused = session_floater && !session_floater->hasFocus();
+ bool session_floater_not_focused = session_floater && !session_floater->hasFocus();
+ //conv. floater is closed
+ bool conversation_floater_is_closed =
+ !( im_box
+ && im_box->isInVisibleChain()
+ && !im_box->isMinimized());
//conversation floater not focused (visible or not)
- bool conversationFloaterNotFocused = im_box && !im_box->hasFocus();
+ bool conversation_floater_not_focused =
+ conversation_floater_is_closed || !im_box->hasFocus();
if ("toast" == action)
{
@@ -187,12 +193,12 @@ void on_new_message(const LLSD& msg)
}
//User is not focused on conversation containing the message
- if(sessionFloaterNotFocused)
+ if(session_floater_not_focused)
{
im_box->flashConversationItemWidget(session_id, true);
//The conversation floater isn't focused/open
- if(conversationFloaterNotFocused)
+ if(conversation_floater_not_focused)
{
gToolBarView->flashCommand(LLCommandId("chat"), true);
@@ -204,23 +210,29 @@ void on_new_message(const LLSD& msg)
}
}
}
+
else if ("flash" == action)
{
- //User is not focused on conversation containing the message
- if(sessionFloaterNotFocused && conversationFloaterNotFocused)
- {
- gToolBarView->flashCommand(LLCommandId("chat"), true);
- }
- //conversation floater is open but a different conversation is focused
- else if(sessionFloaterNotFocused)
- {
- im_box->flashConversationItemWidget(session_id, true);
- }
+ if (session_floater_not_focused)
+ {
+ //User is not focused on conversation containing the message
+
+ if(conversation_floater_not_focused)
+ {
+ gToolBarView->flashCommand(LLCommandId("chat"), true);
+ }
+ //conversation floater is open but a different conversation is focused
+ else
+ {
+ im_box->flashConversationItemWidget(session_id, true);
+ }
+ }
}
+
else if("openconversations" == action)
{
//User is not focused on conversation containing the message
- if(sessionFloaterNotFocused)
+ if(session_floater_not_focused)
{
//Flash line item
im_box->flashConversationItemWidget(session_id, true);
@@ -2543,7 +2555,7 @@ void LLIMMgr::addMessage(
}
//Play sound for new conversations
- if(gSavedSettings.getBOOL("PlaySoundNewConversation") == TRUE)
+ if (!gAgent.isDoNotDisturb() && (gSavedSettings.getBOOL("PlaySoundNewConversation") == TRUE))
{
make_ui_sound("UISndNewIncomingIMSession");
}
@@ -2699,12 +2711,13 @@ LLUUID LLIMMgr::addSession(
{
LLFloaterIMSession* im_floater = LLFloaterIMSession::findInstance(floater_id);
- if (im_floater && im_floater->getStartConferenceInSameFloater())
+ if (im_floater)
{
// The IM floater should be initialized with a new session_id
// so that it is found by that id when creating a chiclet in LLFloaterIMSession::onIMChicletCreated,
// and a new floater is not created.
im_floater->initIMSession(session_id);
+ im_floater->reloadMessages();
}
}
diff --git a/indra/newview/llnotificationalerthandler.cpp b/indra/newview/llnotificationalerthandler.cpp
index 2bc9cdd3c1..58a9b01a45 100644
--- a/indra/newview/llnotificationalerthandler.cpp
+++ b/indra/newview/llnotificationalerthandler.cpp
@@ -29,6 +29,7 @@
#include "llnotificationhandler.h"
+#include "llagentcamera.h"
#include "llnotifications.h"
#include "llprogressview.h"
#include "lltoastnotifypanel.h"
@@ -41,7 +42,7 @@ using namespace LLNotificationsUI;
//--------------------------------------------------------------------------
LLAlertHandler::LLAlertHandler(const std::string& name, const std::string& notification_type, bool is_modal)
-: LLSysHandler(name, notification_type),
+: LLSystemNotificationHandler(name, notification_type),
mIsModal(is_modal)
{
LLScreenChannelBase::Params p;
@@ -123,3 +124,28 @@ void LLAlertHandler::onChange( LLNotificationPtr notification )
if(channel)
channel->modifyToastByNotificationID(notification->getID(), (LLToastPanel*)alert_dialog);
}
+
+//--------------------------------------------------------------------------
+LLViewerAlertHandler::LLViewerAlertHandler(const std::string& name, const std::string& notification_type)
+ : LLSystemNotificationHandler(name, notification_type)
+{
+}
+
+bool LLViewerAlertHandler::processNotification(const LLNotificationPtr& p)
+{
+ if (gHeadlessClient)
+ {
+ LL_INFOS("LLViewerAlertHandler") << "Alert: " << p->getName() << LL_ENDL;
+ }
+
+ // If we're in mouselook, the mouse is hidden and so the user can't click
+ // the dialog buttons. In that case, change to First Person instead.
+ if( gAgentCamera.cameraMouselook() )
+ {
+ gAgentCamera.changeCameraToDefault();
+ }
+
+ return false;
+}
+
+
diff --git a/indra/newview/llnotificationgrouphandler.cpp b/indra/newview/llnotificationgrouphandler.cpp
index 18cd94e685..8fef102cf8 100644
--- a/indra/newview/llnotificationgrouphandler.cpp
+++ b/indra/newview/llnotificationgrouphandler.cpp
@@ -38,7 +38,7 @@ using namespace LLNotificationsUI;
//--------------------------------------------------------------------------
LLGroupHandler::LLGroupHandler()
-: LLSysHandler("Group Notifications", "groupnotify")
+: LLCommunicationNotificationHandler("Group Notifications", "groupnotify")
{
// Getting a Channel for our notifications
LLScreenChannel* channel = LLChannelManager::getInstance()->createNotificationChannel();
diff --git a/indra/newview/llnotificationhandler.h b/indra/newview/llnotificationhandler.h
index 4bded6ab30..bff4efa9ea 100644
--- a/indra/newview/llnotificationhandler.h
+++ b/indra/newview/llnotificationhandler.h
@@ -27,6 +27,7 @@
#ifndef LL_LLNOTIFICATIONHANDLER_H
#define LL_LLNOTIFICATIONHANDLER_H
+#include <boost/intrusive_ptr.hpp>
#include "llwindow.h"
@@ -86,22 +87,37 @@ protected:
/**
* Handler for system notifications.
*/
-class LLSysHandler : public LLEventHandler, public LLNotificationChannel
+class LLNotificationHandler : public LLEventHandler, public LLNotificationChannel
{
public:
- LLSysHandler(const std::string& name, const std::string& notification_type);
- virtual ~LLSysHandler() {};
+ LLNotificationHandler(const std::string& name, const std::string& notification_type, const std::string& parentName);
+ virtual ~LLNotificationHandler() {};
// base interface functions
- /*virtual*/ void onAdd(LLNotificationPtr p) { processNotification(p); }
- /*virtual*/ void onLoad(LLNotificationPtr p) { processNotification(p); }
- /*virtual*/ void onDelete(LLNotificationPtr p) { if (mChannel.get()) mChannel.get()->removeToastByNotificationID(p->getID());}
+ virtual void onAdd(LLNotificationPtr p) { processNotification(p); }
+ virtual void onChange(LLNotificationPtr p) { processNotification(p); }
+ virtual void onLoad(LLNotificationPtr p) { processNotification(p); }
+ virtual void onDelete(LLNotificationPtr p) { if (mChannel.get()) mChannel.get()->removeToastByNotificationID(p->getID());}
- virtual bool processNotification(const LLNotificationPtr& notify)=0;
+ virtual bool processNotification(const LLNotificationPtr& notify) = 0;
+};
+
+class LLSystemNotificationHandler : public LLNotificationHandler
+{
+public:
+ LLSystemNotificationHandler(const std::string& name, const std::string& notification_type);
+ virtual ~LLSystemNotificationHandler() {};
+};
+
+class LLCommunicationNotificationHandler : public LLNotificationHandler
+{
+public:
+ LLCommunicationNotificationHandler(const std::string& name, const std::string& notification_type);
+ virtual ~LLCommunicationNotificationHandler() {};
};
/**
- * Handler for chat message notifications.
+ * Handler for chat message notifications.
*/
class LLChatHandler : public LLEventHandler
{
@@ -115,67 +131,62 @@ public:
* Handler for IM notifications.
* It manages life time of IMs, group messages.
*/
-class LLIMHandler : public LLSysHandler
+class LLIMHandler : public LLCommunicationNotificationHandler
{
public:
LLIMHandler();
virtual ~LLIMHandler();
+ bool processNotification(const LLNotificationPtr& p);
protected:
- bool processNotification(const LLNotificationPtr& p);
- /*virtual*/ void initChannel();
+ virtual void initChannel();
};
/**
* Handler for system informational notices.
* It manages life time of tip notices.
*/
-class LLTipHandler : public LLSysHandler
+class LLTipHandler : public LLSystemNotificationHandler
{
public:
LLTipHandler();
virtual ~LLTipHandler();
- // base interface functions
- /*virtual*/ void onChange(LLNotificationPtr p) { processNotification(p); }
- /*virtual*/ bool processNotification(const LLNotificationPtr& p);
+ virtual bool processNotification(const LLNotificationPtr& p);
protected:
- /*virtual*/ void initChannel();
+ virtual void initChannel();
};
/**
* Handler for system informational notices.
* It manages life time of script notices.
*/
-class LLScriptHandler : public LLSysHandler
+class LLScriptHandler : public LLSystemNotificationHandler
{
public:
LLScriptHandler();
virtual ~LLScriptHandler();
- /*virtual*/ void onDelete(LLNotificationPtr p);
- // base interface functions
- /*virtual*/ bool processNotification(const LLNotificationPtr& p);
+ virtual void onDelete(LLNotificationPtr p);
+ virtual bool processNotification(const LLNotificationPtr& p);
protected:
- /*virtual*/ void onDeleteToast(LLToast* toast);
- /*virtual*/ void initChannel();
+ virtual void onDeleteToast(LLToast* toast);
+ virtual void initChannel();
};
/**
* Handler for group system notices.
*/
-class LLGroupHandler : public LLSysHandler
+class LLGroupHandler : public LLCommunicationNotificationHandler
{
public:
LLGroupHandler();
virtual ~LLGroupHandler();
- // base interface functions
- /*virtual*/ void onChange(LLNotificationPtr p) { processNotification(p); }
- /*virtual*/ bool processNotification(const LLNotificationPtr& p);
+ virtual bool processNotification(const LLNotificationPtr& p);
protected:
virtual void initChannel();
@@ -184,15 +195,14 @@ protected:
/**
* Handler for alert system notices.
*/
-class LLAlertHandler : public LLSysHandler
+class LLAlertHandler : public LLSystemNotificationHandler
{
public:
LLAlertHandler(const std::string& name, const std::string& notification_type, bool is_modal);
virtual ~LLAlertHandler();
- /*virtual*/ void onChange(LLNotificationPtr p);
- /*virtual*/ void onLoad(LLNotificationPtr p) { processNotification(p); }
- /*virtual*/ bool processNotification(const LLNotificationPtr& p);
+ virtual void onChange(LLNotificationPtr p);
+ virtual bool processNotification(const LLNotificationPtr& p);
protected:
virtual void initChannel();
@@ -200,67 +210,85 @@ protected:
bool mIsModal;
};
+class LLViewerAlertHandler : public LLSystemNotificationHandler
+{
+ LOG_CLASS(LLViewerAlertHandler);
+public:
+ LLViewerAlertHandler(const std::string& name, const std::string& notification_type);
+ virtual ~LLViewerAlertHandler() {};
+
+ virtual void onDelete(LLNotificationPtr p) {};
+ virtual bool processNotification(const LLNotificationPtr& p);
+
+protected:
+ virtual void initChannel() {};
+};
+
/**
* Handler for offers notices.
* It manages life time of offer notices.
*/
-class LLOfferHandler : public LLSysHandler
+class LLOfferHandler : public LLCommunicationNotificationHandler
{
public:
LLOfferHandler();
virtual ~LLOfferHandler();
- // base interface functions
- /*virtual*/ void onChange(LLNotificationPtr p);
- /*virtual*/ void onDelete(LLNotificationPtr notification);
- /*virtual*/ bool processNotification(const LLNotificationPtr& p);
+ virtual void onChange(LLNotificationPtr p);
+ virtual void onDelete(LLNotificationPtr notification);
+ virtual bool processNotification(const LLNotificationPtr& p);
protected:
- /*virtual*/ void initChannel();
+ virtual void initChannel();
};
/**
* Handler for UI hints.
*/
-class LLHintHandler : public LLNotificationChannel
+class LLHintHandler : public LLSystemNotificationHandler
{
public:
- LLHintHandler() : LLNotificationChannel("Hints", "Visible", LLNotificationFilters::filterBy<std::string>(&LLNotification::getType, "hint"))
- {}
+ LLHintHandler();
virtual ~LLHintHandler() {}
- /*virtual*/ void onAdd(LLNotificationPtr p);
- /*virtual*/ void onLoad(LLNotificationPtr p);
- /*virtual*/ void onDelete(LLNotificationPtr p);
+ virtual void onAdd(LLNotificationPtr p);
+ virtual void onLoad(LLNotificationPtr p);
+ virtual void onDelete(LLNotificationPtr p);
+ virtual bool processNotification(const LLNotificationPtr& p);
+
+protected:
+ virtual void initChannel() {};
};
/**
* Handler for browser notifications
*/
-class LLBrowserNotification : public LLNotificationChannel
+class LLBrowserNotification : public LLSystemNotificationHandler
{
public:
- LLBrowserNotification()
- : LLNotificationChannel("Browser", "Visible", LLNotificationFilters::filterBy<std::string>(&LLNotification::getType, "browser"))
- {}
- /*virtual*/ void onAdd(LLNotificationPtr p) { processNotification(p); }
- /*virtual*/ void onChange(LLNotificationPtr p) { processNotification(p); }
- bool processNotification(const LLNotificationPtr& p);
+ LLBrowserNotification();
+ virtual ~LLBrowserNotification() {}
+
+ virtual bool processNotification(const LLNotificationPtr& p);
+
+protected:
+ virtual void initChannel() {};
};
/**
* Handler for outbox notifications
*/
-class LLOutboxNotification : public LLNotificationChannel
+class LLOutboxNotification : public LLSystemNotificationHandler
{
public:
- LLOutboxNotification()
- : LLNotificationChannel("Outbox", "Visible", LLNotificationFilters::filterBy<std::string>(&LLNotification::getType, "outbox"))
- {}
- /*virtual*/ void onAdd(LLNotificationPtr p) { processNotification(p); }
- /*virtual*/ void onChange(LLNotificationPtr p) { }
- /*virtual*/ void onDelete(LLNotificationPtr p);
- bool processNotification(const LLNotificationPtr& p);
+ LLOutboxNotification();
+ virtual ~LLOutboxNotification() {};
+ virtual void onChange(LLNotificationPtr p) { }
+ virtual void onDelete(LLNotificationPtr p);
+ virtual bool processNotification(const LLNotificationPtr& p);
+
+protected:
+ virtual void initChannel() {};
};
class LLHandlerUtil
diff --git a/indra/newview/llnotificationhandlerutil.cpp b/indra/newview/llnotificationhandlerutil.cpp
index 7f1216ff40..f0175d677c 100644
--- a/indra/newview/llnotificationhandlerutil.cpp
+++ b/indra/newview/llnotificationhandlerutil.cpp
@@ -41,8 +41,16 @@
using namespace LLNotificationsUI;
-LLSysHandler::LLSysHandler(const std::string& name, const std::string& notification_type)
-: LLNotificationChannel(name, "Visible", LLNotificationFilters::filterBy<std::string>(&LLNotification::getType, notification_type))
+LLNotificationHandler::LLNotificationHandler(const std::string& name, const std::string& notification_type, const std::string& parentName)
+: LLNotificationChannel(name, parentName, LLNotificationFilters::filterBy<std::string>(&LLNotification::getType, notification_type))
+{}
+
+LLSystemNotificationHandler::LLSystemNotificationHandler(const std::string& name, const std::string& notification_type)
+ : LLNotificationHandler(name, notification_type, "System")
+{}
+
+LLCommunicationNotificationHandler::LLCommunicationNotificationHandler(const std::string& name, const std::string& notification_type)
+ : LLNotificationHandler(name, notification_type, "Communication")
{}
// static
diff --git a/indra/newview/llnotificationhinthandler.cpp b/indra/newview/llnotificationhinthandler.cpp
index 271f418507..f40369a2e0 100644
--- a/indra/newview/llnotificationhinthandler.cpp
+++ b/indra/newview/llnotificationhinthandler.cpp
@@ -33,6 +33,27 @@
using namespace LLNotificationsUI;
-void LLHintHandler::onAdd(LLNotificationPtr p) { LLHints::show(p); }
-void LLHintHandler::onLoad(LLNotificationPtr p) { LLHints::show(p); }
-void LLHintHandler::onDelete(LLNotificationPtr p) { LLHints::hide(p); }
+LLHintHandler::LLHintHandler()
+ : LLSystemNotificationHandler("Hints", "hint")
+{
+}
+
+void LLHintHandler::onAdd(LLNotificationPtr p)
+{
+ LLHints::show(p);
+}
+
+void LLHintHandler::onLoad(LLNotificationPtr p)
+{
+ LLHints::show(p);
+}
+
+void LLHintHandler::onDelete(LLNotificationPtr p)
+{
+ LLHints::hide(p);
+}
+
+bool LLHintHandler::processNotification(const LLNotificationPtr& p)
+{
+ return false;
+}
diff --git a/indra/newview/llnotificationofferhandler.cpp b/indra/newview/llnotificationofferhandler.cpp
index ff5b5e21f7..da38c9063b 100644
--- a/indra/newview/llnotificationofferhandler.cpp
+++ b/indra/newview/llnotificationofferhandler.cpp
@@ -41,7 +41,7 @@ using namespace LLNotificationsUI;
//--------------------------------------------------------------------------
LLOfferHandler::LLOfferHandler()
-: LLSysHandler("Offer", "offer")
+: LLCommunicationNotificationHandler("Offer", "offer")
{
// Getting a Channel for our notifications
LLScreenChannel* channel = LLChannelManager::getInstance()->createNotificationChannel();
diff --git a/indra/newview/llnotificationscripthandler.cpp b/indra/newview/llnotificationscripthandler.cpp
index 290a81f91c..e2d4e9f8ce 100644
--- a/indra/newview/llnotificationscripthandler.cpp
+++ b/indra/newview/llnotificationscripthandler.cpp
@@ -39,7 +39,7 @@ using namespace LLNotificationsUI;
//--------------------------------------------------------------------------
LLScriptHandler::LLScriptHandler()
-: LLSysHandler("Notifications", "notify")
+: LLSystemNotificationHandler("Notifications", "notify")
{
// Getting a Channel for our notifications
LLScreenChannel* channel = LLChannelManager::getInstance()->createNotificationChannel();
diff --git a/indra/newview/llnotificationstorage.cpp b/indra/newview/llnotificationstorage.cpp
index a31b95811e..d25a212059 100644
--- a/indra/newview/llnotificationstorage.cpp
+++ b/indra/newview/llnotificationstorage.cpp
@@ -25,207 +25,68 @@
*/
#include "llviewerprecompiledheaders.h" // must be first include
+
#include "llnotificationstorage.h"
-#include "llxmlnode.h" // for linux compilers
+#include <string>
-#include "llchannelmanager.h"
-#include "llscreenchannel.h"
-#include "llscriptfloater.h"
+#include "llerror.h"
+#include "llfile.h"
+#include "llpointer.h"
+#include "llsd.h"
#include "llsdserialize.h"
-#include "llviewermessage.h"
-
-//////////////////////////////////////////////////////////////////////////
-
-class LLResponderRegistry
-{
-public:
-
- static void registerResponders();
-
- static LLNotificationResponderInterface* createResponder(const std::string& notification_name, const LLSD& params);
-
-private:
-
- template<typename RESPONDER_TYPE>
- static LLNotificationResponderInterface* create(const LLSD& params)
- {
- RESPONDER_TYPE* responder = new RESPONDER_TYPE();
- responder->fromLLSD(params);
- return responder;
- }
-
- typedef boost::function<LLNotificationResponderInterface* (const LLSD& params)> responder_constructor_t;
-
- static void add(const std::string& notification_name, const responder_constructor_t& ctr);
-
-private:
-
- typedef std::map<std::string, responder_constructor_t> build_map_t;
-
- static build_map_t sBuildMap;
-};
-//////////////////////////////////////////////////////////////////////////
-LLPersistentNotificationStorage::LLPersistentNotificationStorage()
+LLNotificationStorage::LLNotificationStorage(std::string pFileName)
+ : mFileName(pFileName)
{
- mFileName = gDirUtilp->getExpandedFilename ( LL_PATH_PER_SL_ACCOUNT, "open_notifications.xml" );
}
-bool LLPersistentNotificationStorage::onPersistentChannelChanged(const LLSD& payload)
+LLNotificationStorage::~LLNotificationStorage()
{
- // we ignore "load" messages, but rewrite the persistence file on any other
- const std::string sigtype = payload["sigtype"].asString();
- if ("load" != sigtype)
- {
- saveNotifications();
- }
- return false;
}
-static LLFastTimer::DeclareTimer FTM_SAVE_NOTIFICATIONS("Save Notifications");
-
-void LLPersistentNotificationStorage::saveNotifications()
+bool LLNotificationStorage::writeNotifications(const LLSD& pNotificationData) const
{
- LLFastTimer _(FTM_SAVE_NOTIFICATIONS);
-
- llofstream notify_file(mFileName.c_str());
- if (!notify_file.is_open())
- {
- llwarns << "Failed to open " << mFileName << llendl;
- return;
- }
- LLSD output;
- LLSD& data = output["data"];
+ llofstream notifyFile(mFileName.c_str());
+ bool didFileOpen = notifyFile.is_open();
- boost::intrusive_ptr<LLPersistentNotificationChannel> history_channel = boost::dynamic_pointer_cast<LLPersistentNotificationChannel>(LLNotifications::instance().getChannel("Persistent"));
- if (!history_channel)
+ if (!didFileOpen)
{
- return;
+ LL_WARNS("LLNotificationStorage") << "Failed to open file '" << mFileName << "'" << LL_ENDL;
}
-
- for ( std::vector<LLNotificationPtr>::iterator it = history_channel->beginHistory(), end_it = history_channel->endHistory();
- it != end_it;
- ++it)
+ else
{
- LLNotificationPtr notification = *it;
-
- // After a notification was placed in Persist channel, it can become
- // responded, expired or canceled - in this case we are should not save it
- if(notification->isRespondedTo() || notification->isCancelled()
- || notification->isExpired())
- {
- continue;
- }
-
- data.append(notification->asLLSD());
+ LLPointer<LLSDFormatter> formatter = new LLSDXMLFormatter();
+ formatter->format(pNotificationData, notifyFile, LLSDFormatter::OPTIONS_PRETTY);
}
- LLPointer<LLSDFormatter> formatter = new LLSDXMLFormatter();
- formatter->format(output, notify_file, LLSDFormatter::OPTIONS_PRETTY);
+ return didFileOpen;
}
-static LLFastTimer::DeclareTimer FTM_LOAD_NOTIFICATIONS("Load Notifications");
-
-void LLPersistentNotificationStorage::loadNotifications()
+bool LLNotificationStorage::readNotifications(LLSD& pNotificationData) const
{
- LLFastTimer _(FTM_LOAD_NOTIFICATIONS);
- LLResponderRegistry::registerResponders();
+ bool didFileRead;
- LLNotifications::instance().getChannel("Persistent")->
- connectChanged(boost::bind(&LLPersistentNotificationStorage::onPersistentChannelChanged, this, _1));
+ pNotificationData.clear();
- llifstream notify_file(mFileName.c_str());
- if (!notify_file.is_open())
+ llifstream notifyFile(mFileName.c_str());
+ didFileRead = notifyFile.is_open();
+ if (!didFileRead)
{
- llwarns << "Failed to open " << mFileName << llendl;
- return;
+ LL_WARNS("LLNotificationStorage") << "Failed to open file '" << mFileName << "'" << LL_ENDL;
}
-
- LLSD input;
- LLPointer<LLSDParser> parser = new LLSDXMLParser();
- if (parser->parse(notify_file, input, LLSDSerialize::SIZE_UNLIMITED) < 0)
+ else
{
- llwarns << "Failed to parse open notifications" << llendl;
- return;
- }
-
- if (input.isUndefined())
- {
- return;
- }
-
- LLSD& data = input["data"];
- if (data.isUndefined())
- {
- return;
- }
-
- using namespace LLNotificationsUI;
- LLScreenChannel* notification_channel = dynamic_cast<LLScreenChannel*>(LLChannelManager::getInstance()->
- findChannelByID(LLUUID(gSavedSettings.getString("NotificationChannelUUID"))));
-
- LLNotifications& instance = LLNotifications::instance();
-
- for (LLSD::array_const_iterator notification_it = data.beginArray();
- notification_it != data.endArray();
- ++notification_it)
- {
- LLSD notification_params = *notification_it;
- LLNotificationPtr notification(new LLNotification(notification_params));
-
- LLNotificationResponderPtr responder(LLResponderRegistry::
- createResponder(notification_params["name"], notification_params["responder"]));
- notification->setResponseFunctor(responder);
-
- instance.add(notification);
-
- // hide script floaters so they don't confuse the user and don't overlap startup toast
- LLScriptFloaterManager::getInstance()->setFloaterVisible(notification->getID(), false);
-
- if(notification_channel)
+ LLPointer<LLSDParser> parser = new LLSDXMLParser();
+ didFileRead = (parser->parse(notifyFile, pNotificationData, LLSDSerialize::SIZE_UNLIMITED) >= 0);
+ if (!didFileRead)
{
- // hide saved toasts so they don't confuse the user
- notification_channel->hideToast(notification->getID());
+ LL_WARNS("LLNotificationStorage") << "Failed to parse open notifications from file '" << mFileName
+ << "'" << LL_ENDL;
}
}
-}
-
-//////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////
-LLResponderRegistry::build_map_t LLResponderRegistry::sBuildMap;
-
-void LLResponderRegistry::registerResponders()
-{
- sBuildMap.clear();
-
- add("ObjectGiveItem", &create<LLOfferInfo>);
- add("UserGiveItem", &create<LLOfferInfo>);
-}
-
-LLNotificationResponderInterface* LLResponderRegistry::createResponder(const std::string& notification_name, const LLSD& params)
-{
- build_map_t::const_iterator it = sBuildMap.find(notification_name);
- if(sBuildMap.end() == it)
- {
- return NULL;
- }
- responder_constructor_t ctr = it->second;
- return ctr(params);
+ return didFileRead;
}
-
-void LLResponderRegistry::add(const std::string& notification_name, const responder_constructor_t& ctr)
-{
- if(sBuildMap.find(notification_name) != sBuildMap.end())
- {
- llwarns << "Responder is already registered : " << notification_name << llendl;
- llassert(!"Responder already registered");
- }
- sBuildMap[notification_name] = ctr;
-}
-
-// EOF
diff --git a/indra/newview/llnotificationstorage.h b/indra/newview/llnotificationstorage.h
index 8635c797c0..ab4da4e73f 100644
--- a/indra/newview/llnotificationstorage.h
+++ b/indra/newview/llnotificationstorage.h
@@ -27,32 +27,24 @@
#ifndef LL_NOTIFICATIONSTORAGE_H
#define LL_NOTIFICATIONSTORAGE_H
-#include "llnotifications.h"
-
-// Class that saves not responded(unread) notifications.
-// Unread notifications are saved in open_notifications.xml in SL account folder
-//
-// Notifications that should be saved(if unread) are marked with persist="true" in notifications.xml
-// Notifications using functor responders are saved automatically (see llviewermessage.cpp
-// lure_callback_reg for example).
-// Notifications using object responders(LLOfferInfo) need additional tuning. Responder object should
-// be a) serializable(implement LLNotificationResponderInterface),
-// b) registered with LLResponderRegistry (found in llnotificationstorage.cpp).
-class LLPersistentNotificationStorage : public LLSingleton<LLPersistentNotificationStorage>
-{
- LOG_CLASS(LLPersistentNotificationStorage);
-public:
+#include <string>
- LLPersistentNotificationStorage();
+#include "llerror.h"
- void saveNotifications();
+class LLSD;
- void loadNotifications();
-
-private:
+class LLNotificationStorage
+{
+ LOG_CLASS(LLNotificationStorage);
+public:
+ LLNotificationStorage(std::string pFileName);
+ ~LLNotificationStorage();
- bool onPersistentChannelChanged(const LLSD& payload);
+protected:
+ bool writeNotifications(const LLSD& pNotificationData) const;
+ bool readNotifications(LLSD& pNotificationData) const;
+private:
std::string mFileName;
};
diff --git a/indra/newview/llnotificationtiphandler.cpp b/indra/newview/llnotificationtiphandler.cpp
index faa67b5ea4..a85335f1ba 100644
--- a/indra/newview/llnotificationtiphandler.cpp
+++ b/indra/newview/llnotificationtiphandler.cpp
@@ -42,7 +42,7 @@ using namespace LLNotificationsUI;
//--------------------------------------------------------------------------
LLTipHandler::LLTipHandler()
-: LLSysHandler("NotificationTips", "notifytip")
+: LLSystemNotificationHandler("NotificationTips", "notifytip")
{
// Getting a Channel for our notifications
LLScreenChannel* channel = LLChannelManager::getInstance()->createNotificationChannel();
diff --git a/indra/newview/llpersistentnotificationstorage.cpp b/indra/newview/llpersistentnotificationstorage.cpp
new file mode 100644
index 0000000000..7aaad64fd7
--- /dev/null
+++ b/indra/newview/llpersistentnotificationstorage.cpp
@@ -0,0 +1,210 @@
+/**
+* @file llpersistentnotificationstorage.cpp
+* @brief Implementation of llpersistentnotificationstorage
+* @author Stinson@lindenlab.com
+*
+* $LicenseInfo:firstyear=2012&license=viewerlgpl$
+* Second Life Viewer Source Code
+* Copyright (C) 2012, 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.
+*
+* 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.
+*
+* 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
+*
+* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+* $/LicenseInfo$
+*/
+
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llpersistentnotificationstorage.h"
+
+#include "llchannelmanager.h"
+#include "llnotificationstorage.h"
+#include "llscreenchannel.h"
+#include "llscriptfloater.h"
+#include "llviewermessage.h"
+
+class LLResponderRegistry
+{
+public:
+
+ static void registerResponders();
+
+ static LLNotificationResponderInterface* createResponder(const std::string& notification_name, const LLSD& params);
+
+protected:
+
+private:
+ template<typename RESPONDER_TYPE>
+ static LLNotificationResponderInterface* create(const LLSD& params)
+ {
+ RESPONDER_TYPE* responder = new RESPONDER_TYPE();
+ responder->fromLLSD(params);
+ return responder;
+ }
+
+ typedef boost::function<LLNotificationResponderInterface* (const LLSD& params)> responder_constructor_t;
+
+ static void add(const std::string& notification_name, const responder_constructor_t& ctr);
+
+ typedef std::map<std::string, responder_constructor_t> build_map_t;
+
+ static build_map_t sBuildMap;
+};
+
+LLPersistentNotificationStorage::LLPersistentNotificationStorage()
+ : LLSingleton<LLPersistentNotificationStorage>()
+ , LLNotificationStorage(gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, "open_notifications.xml"))
+{
+}
+
+LLPersistentNotificationStorage::~LLPersistentNotificationStorage()
+{
+}
+
+static LLFastTimer::DeclareTimer FTM_SAVE_NOTIFICATIONS("Save Notifications");
+
+void LLPersistentNotificationStorage::saveNotifications()
+{
+ LLFastTimer _(FTM_SAVE_NOTIFICATIONS);
+
+ boost::intrusive_ptr<LLPersistentNotificationChannel> history_channel = boost::dynamic_pointer_cast<LLPersistentNotificationChannel>(LLNotifications::instance().getChannel("Persistent"));
+ if (!history_channel)
+ {
+ return;
+ }
+
+ LLSD output = LLSD::emptyMap();
+ LLSD& data = output["data"];
+
+ for ( std::vector<LLNotificationPtr>::iterator it = history_channel->beginHistory(), end_it = history_channel->endHistory();
+ it != end_it;
+ ++it)
+ {
+ LLNotificationPtr notification = *it;
+
+ // After a notification was placed in Persist channel, it can become
+ // responded, expired or canceled - in this case we are should not save it
+ if(notification->isRespondedTo() || notification->isCancelled()
+ || notification->isExpired())
+ {
+ continue;
+ }
+
+ data.append(notification->asLLSD());
+ }
+
+ writeNotifications(output);
+}
+
+static LLFastTimer::DeclareTimer FTM_LOAD_NOTIFICATIONS("Load Notifications");
+
+void LLPersistentNotificationStorage::loadNotifications()
+{
+ LLFastTimer _(FTM_LOAD_NOTIFICATIONS);
+ LLResponderRegistry::registerResponders();
+
+ LLNotifications::instance().getChannel("Persistent")->
+ connectChanged(boost::bind(&LLPersistentNotificationStorage::onPersistentChannelChanged, this, _1));
+
+ LLSD input;
+ if (!readNotifications(input) ||input.isUndefined())
+ {
+ return;
+ }
+
+ LLSD& data = input["data"];
+ if (data.isUndefined())
+ {
+ return;
+ }
+
+ using namespace LLNotificationsUI;
+ LLScreenChannel* notification_channel = dynamic_cast<LLScreenChannel*>(LLChannelManager::getInstance()->
+ findChannelByID(LLUUID(gSavedSettings.getString("NotificationChannelUUID"))));
+
+ LLNotifications& instance = LLNotifications::instance();
+
+ for (LLSD::array_const_iterator notification_it = data.beginArray();
+ notification_it != data.endArray();
+ ++notification_it)
+ {
+ LLSD notification_params = *notification_it;
+ LLNotificationPtr notification(new LLNotification(notification_params));
+
+ LLNotificationResponderPtr responder(LLResponderRegistry::
+ createResponder(notification_params["name"], notification_params["responder"]));
+ notification->setResponseFunctor(responder);
+
+ instance.add(notification);
+
+ // hide script floaters so they don't confuse the user and don't overlap startup toast
+ LLScriptFloaterManager::getInstance()->setFloaterVisible(notification->getID(), false);
+
+ if(notification_channel)
+ {
+ // hide saved toasts so they don't confuse the user
+ notification_channel->hideToast(notification->getID());
+ }
+ }
+}
+
+bool LLPersistentNotificationStorage::onPersistentChannelChanged(const LLSD& payload)
+{
+ // we ignore "load" messages, but rewrite the persistence file on any other
+ const std::string sigtype = payload["sigtype"].asString();
+ if ("load" != sigtype)
+ {
+ saveNotifications();
+ }
+ return false;
+}
+
+//////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////
+
+LLResponderRegistry::build_map_t LLResponderRegistry::sBuildMap;
+
+void LLResponderRegistry::registerResponders()
+{
+ sBuildMap.clear();
+
+ add("ObjectGiveItem", &create<LLOfferInfo>);
+ add("UserGiveItem", &create<LLOfferInfo>);
+}
+
+LLNotificationResponderInterface* LLResponderRegistry::createResponder(const std::string& notification_name, const LLSD& params)
+{
+ build_map_t::const_iterator it = sBuildMap.find(notification_name);
+ if(sBuildMap.end() == it)
+ {
+ return NULL;
+ }
+ responder_constructor_t ctr = it->second;
+ return ctr(params);
+}
+
+void LLResponderRegistry::add(const std::string& notification_name, const responder_constructor_t& ctr)
+{
+ if(sBuildMap.find(notification_name) != sBuildMap.end())
+ {
+ llwarns << "Responder is already registered : " << notification_name << llendl;
+ llassert(!"Responder already registered");
+ }
+ sBuildMap[notification_name] = ctr;
+}
+
+// EOF
diff --git a/indra/newview/llpersistentnotificationstorage.h b/indra/newview/llpersistentnotificationstorage.h
new file mode 100644
index 0000000000..98a825d2c1
--- /dev/null
+++ b/indra/newview/llpersistentnotificationstorage.h
@@ -0,0 +1,63 @@
+/**
+* @file llpersistentnotificationstorage.h
+* @brief Header file for llpersistentnotificationstorage
+* @author Stinson@lindenlab.com
+*
+* $LicenseInfo:firstyear=2012&license=viewerlgpl$
+* Second Life Viewer Source Code
+* Copyright (C) 2012, 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.
+*
+* 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.
+*
+* 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
+*
+* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+* $/LicenseInfo$
+*/
+#ifndef LL_LLPERSISTENTNOTIFICATIONSTORAGE_H
+#define LL_LLPERSISTENTNOTIFICATIONSTORAGE_H
+
+#include "llerror.h"
+#include "llnotificationstorage.h"
+#include "llsingleton.h"
+
+class LLSD;
+
+// Class that saves not responded(unread) notifications.
+// Unread notifications are saved in open_notifications.xml in SL account folder
+//
+// Notifications that should be saved(if unread) are marked with persist="true" in notifications.xml
+// Notifications using functor responders are saved automatically (see llviewermessage.cpp
+// lure_callback_reg for example).
+// Notifications using object responders(LLOfferInfo) need additional tuning. Responder object should
+// be a) serializable(implement LLNotificationResponderInterface),
+// b) registered with LLResponderRegistry (found in llpersistentnotificationstorage.cpp).
+
+class LLPersistentNotificationStorage : public LLSingleton<LLPersistentNotificationStorage>, public LLNotificationStorage
+{
+ LOG_CLASS(LLPersistentNotificationStorage);
+public:
+ LLPersistentNotificationStorage();
+ ~LLPersistentNotificationStorage();
+
+ void saveNotifications();
+ void loadNotifications();
+
+protected:
+
+private:
+ bool onPersistentChannelChanged(const LLSD& payload);
+};
+
+#endif // LL_LLPERSISTENTNOTIFICATIONSTORAGE_H
+
diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp
index 5bb7db5c0d..04dd7c911b 100755
--- a/indra/newview/llviewermessage.cpp
+++ b/indra/newview/llviewermessage.cpp
@@ -3169,17 +3169,16 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
payload["online"] = (offline == IM_ONLINE);
payload["sender"] = msg->getSender().getIPandPort();
- if (is_do_not_disturb)
- {
- send_do_not_disturb_message(msg, from_id);
- LLNotifications::instance().forceResponse(LLNotification::Params("OfferFriendship").payload(payload), 1);
- }
- else if (is_muted)
+ if (is_muted)
{
LLNotifications::instance().forceResponse(LLNotification::Params("OfferFriendship").payload(payload), 1);
}
else
{
+ if (is_do_not_disturb)
+ {
+ send_do_not_disturb_message(msg, from_id);
+ }
args["NAME_SLURL"] = LLSLURL("agent", from_id, "about").getSLURLString();
if(message.empty())
{
diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index 1d7abb7c1c..1c463015e2 100755
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -37,8 +37,10 @@
#include "llagent.h"
#include "llagentcamera.h"
+#include "llcommunicationchannel.h"
#include "llfloaterreg.h"
#include "llmeshrepository.h"
+#include "llnotificationhandler.h"
#include "llpanellogin.h"
#include "llviewerkeyboard.h"
#include "llviewermenu.h"
@@ -127,6 +129,7 @@
#include "llmorphview.h"
#include "llmoveview.h"
#include "llnavigationbar.h"
+#include "llnotificationhandler.h"
#include "llpanelpathfindingrebakenavmesh.h"
#include "llpaneltopinfobar.h"
#include "llpopupview.h"
@@ -1554,11 +1557,11 @@ LLViewerWindow::LLViewerWindow(const Params& p)
mWindowListener.reset(new LLWindowListener(this, boost::lambda::var(gKeyboard)));
mViewerWindowListener.reset(new LLViewerWindowListener(this));
- mAlertsChannel.reset(new LLNotificationChannel("VW_alerts", "Visible", LLNotificationFilters::filterBy<std::string>(&LLNotification::getType, "alert")));
- mModalAlertsChannel.reset(new LLNotificationChannel("VW_alertmodal", "Visible", LLNotificationFilters::filterBy<std::string>(&LLNotification::getType, "alertmodal")));
+ mSystemChannel.reset(new LLNotificationChannel("System", "Visible", LLNotificationFilters::includeEverything));
+ mCommunicationChannel.reset(new LLCommunicationChannel("Communication", "Visible"));
+ mAlertsChannel.reset(new LLNotificationsUI::LLViewerAlertHandler("VW_alerts", "alert"));
+ mModalAlertsChannel.reset(new LLNotificationsUI::LLViewerAlertHandler("VW_alertmodal", "alertmodal"));
- mAlertsChannel->connectChanged(&LLViewerWindow::onAlert);
- mModalAlertsChannel->connectChanged(&LLViewerWindow::onAlert);
bool ignore = gSavedSettings.getBOOL("IgnoreAllNotifications");
LLNotifications::instance().setIgnoreAllNotifications(ignore);
if (ignore)
@@ -5044,25 +5047,6 @@ LLRect LLViewerWindow::getChatConsoleRect()
//----------------------------------------------------------------------------
-//static
-bool LLViewerWindow::onAlert(const LLSD& notify)
-{
- LLNotificationPtr notification = LLNotifications::instance().find(notify["id"].asUUID());
-
- if (gHeadlessClient)
- {
- llinfos << "Alert: " << notification->getName() << llendl;
- }
-
- // If we're in mouselook, the mouse is hidden and so the user can't click
- // the dialog buttons. In that case, change to First Person instead.
- if( gAgentCamera.cameraMouselook() )
- {
- gAgentCamera.changeCameraToDefault();
- }
- return false;
-}
-
void LLViewerWindow::setUIVisibility(bool visible)
{
mUIVisible = visible;
diff --git a/indra/newview/llviewerwindow.h b/indra/newview/llviewerwindow.h
index ee6a7793f8..5a0d9652b8 100644
--- a/indra/newview/llviewerwindow.h
+++ b/indra/newview/llviewerwindow.h
@@ -43,6 +43,7 @@
#include "lltimer.h"
#include "llstat.h"
#include "llmousehandler.h"
+#include "llnotifications.h"
#include "llhandle.h"
#include "llinitparam.h"
@@ -401,7 +402,6 @@ public:
private:
bool shouldShowToolTipFor(LLMouseHandler *mh);
- static bool onAlert(const LLSD& notify);
void switchToolByMask(MASK mask);
void destroyWindow();
@@ -418,8 +418,10 @@ private:
bool mActive;
bool mUIVisible;
- boost::shared_ptr<class LLNotificationChannel> mAlertsChannel,
- mModalAlertsChannel;
+ LLNotificationChannelPtr mSystemChannel;
+ LLNotificationChannelPtr mCommunicationChannel;
+ LLNotificationChannelPtr mAlertsChannel;
+ LLNotificationChannelPtr mModalAlertsChannel;
LLRect mWindowRectRaw; // whole window, including UI
LLRect mWindowRectScaled; // whole window, scaled by UI size
diff --git a/indra/newview/skins/default/colors.xml b/indra/newview/skins/default/colors.xml
index becdbda067..c3df04d0a6 100644
--- a/indra/newview/skins/default/colors.xml
+++ b/indra/newview/skins/default/colors.xml
@@ -11,6 +11,9 @@
<color
name="EmphasisColor_35"
value="0.38 0.694 0.573 0.35" />
+ <color
+ name="BeaconColor"
+ value="1 .67 .2 1" />
<color
name="BeaconColor"
value="1 .67 .2 1" />
diff --git a/indra/newview/skins/default/xui/en/floater_im_container.xml b/indra/newview/skins/default/xui/en/floater_im_container.xml
index 37a3b9ac59..3475c7da33 100644
--- a/indra/newview/skins/default/xui/en/floater_im_container.xml
+++ b/indra/newview/skins/default/xui/en/floater_im_container.xml
@@ -38,7 +38,7 @@
name="conversations_layout_panel"
min_dim="38"
width="225"
- expanded_min_dim="200">
+ expanded_min_dim="156">
<layout_stack
animate="false"
follows="left|top|right"
@@ -108,7 +108,7 @@
image_unselected="Toolbar_Middle_Off"
layout="topleft"
top="5"
- left="5"
+ left="1"
name="expand_collapse_btn"
tool_tip="Collapse/Expand this list"
width="31" />
@@ -128,7 +128,7 @@
auto_resize="true"
user_resize="true"
name="messages_layout_panel"
- expanded_min_dim="225">
+ expanded_min_dim="222">
<panel_container
bottom="-1"
follows="all"
diff --git a/indra/newview/skins/default/xui/en/floater_im_session.xml b/indra/newview/skins/default/xui/en/floater_im_session.xml
index e4b127b7b9..4dbd52d05e 100644
--- a/indra/newview/skins/default/xui/en/floater_im_session.xml
+++ b/indra/newview/skins/default/xui/en/floater_im_session.xml
@@ -79,6 +79,21 @@
tool_tip="View/sort options"
top="5"
width="31" />
+ <menu_button
+ menu_filename="menu_im_conversation.xml"
+ follows="top|left"
+ height="25"
+ image_hover_unselected="Toolbar_Middle_Over"
+ image_overlay="OptionsMenu_Off"
+ image_selected="Toolbar_Middle_Selected"
+ image_unselected="Toolbar_Middle_Off"
+ layout="topleft"
+ top="5"
+ left_pad="4"
+ name="gear_btn"
+ visible="false"
+ tool_tip="Actions on selected person"
+ width="31"/>
<button
enabled="false"
follows="top|left"
diff --git a/indra/newview/skins/default/xui/en/menu_im_conversation.xml b/indra/newview/skins/default/xui/en/menu_im_conversation.xml
new file mode 100644
index 0000000000..8882d0a7d8
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/menu_im_conversation.xml
@@ -0,0 +1,94 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<toggleable_menu
+ layout="topleft"
+ name="Conversation Gear Menu">
+ <menu_item_call
+ label="View Profile"
+ layout="topleft"
+ name="View Profile">
+ <on_click function="Avatar.GearDoToSelected" parameter="view_profile" />
+ <on_enable function="Avatar.EnableGearItem" parameter="can_view_profile" />
+ </menu_item_call>
+ <menu_item_call
+ label="Add Friend"
+ layout="topleft"
+ name="Add Friend">
+ <on_click function="Avatar.GearDoToSelected" parameter="add_friend" />
+ <on_enable function="Avatar.EnableGearItem" parameter="can_add" />
+ </menu_item_call>
+ <menu_item_call
+ label="Remove friend"
+ layout="topleft"
+ name="remove_friend">
+ <on_click function="Avatar.GearDoToSelected" parameter="remove_friend" />
+ <on_enable function="Avatar.EnableGearItem" parameter="can_delete" />
+ </menu_item_call>
+ <menu_item_call
+ label="Offer teleport"
+ layout="topleft"
+ name="offer_teleport">
+ <on_click function="Avatar.GearDoToSelected" parameter="offer_teleport"/>
+ <on_enable function="Avatar.EnableGearItem" parameter="can_offer_teleport"/>
+ </menu_item_call>
+ <menu_item_call
+ label="Invite to group..."
+ layout="topleft"
+ name="invite_to_group">
+ <on_click function="Avatar.GearDoToSelected" parameter="invite_to_group" />
+ <on_enable function="Avatar.EnableGearItem" parameter="can_invite" />
+ </menu_item_call>
+ <menu_item_separator
+ layout="topleft"
+ name="View Icons Separator" />
+ <menu_item_call
+ label="Chat history..."
+ layout="topleft"
+ name="chat_history">
+ <on_click function="Avatar.GearDoToSelected" parameter="chat_history"/>
+ <on_enable function="Avatar.EnableGearItem" parameter="can_chat_history"/>
+ </menu_item_call>
+ <menu_item_separator
+ layout="topleft"/>
+ <menu_item_call
+ label="Map"
+ layout="topleft"
+ name="map">
+ <on_click function="Avatar.GearDoToSelected" parameter="map" />
+ <on_enable function="Avatar.EnableGearItem" parameter="can_show_on_map" />
+ </menu_item_call>
+ <menu_item_call
+ label="Share"
+ layout="topleft"
+ name="Share">
+ <on_click function="Avatar.GearDoToSelected" parameter="share" />
+ <on_enable function="Avatar.EnableGearItem" parameter="can_share" />
+ </menu_item_call>
+ <menu_item_call
+ label="Pay"
+ layout="topleft"
+ name="Pay">
+ <on_click function="Avatar.GearDoToSelected" parameter="pay" />
+ <on_enable function="Avatar.EnableGearItem" parameter="can_pay" />
+ </menu_item_call>
+ <menu_item_separator
+ layout="topleft"/>
+ <menu_item_check
+ label="Block Voice"
+ layout="topleft"
+ name="Block/Unblock">
+ <on_check function="Avatar.CheckGearItem" parameter="is_blocked" />
+ <on_click function="Avatar.GearDoToSelected" parameter="block_unblock" />
+ <on_enable function="Avatar.EnableGearItem" parameter="can_block" />
+ </menu_item_check>
+ <menu_item_check
+ label="Block Text"
+ layout="topleft"
+ name="MuteText">
+ <on_check function="Avatar.CheckGearItem" parameter="is_muted" />
+ <on_click function="Avatar.GearDoToSelected" parameter="mute_unmute" />
+ <on_enable function="Avatar.EnableGearItem" parameter="can_block" />
+ </menu_item_check>
+ <menu_item_separator
+ layout="topleft"/>
+</toggleable_menu>
+
diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml
index 3e7329c0b5..00424e97f6 100644
--- a/indra/newview/skins/default/xui/en/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/en/menu_viewer.xml
@@ -1267,7 +1267,58 @@
function="Floater.Show"
parameter="hud" />
</menu_item_call>-->
-
+ <menu_item_separator/>
+
+ <menu_item_call
+ label="User’s guide"
+ name="User’s guide">
+ <menu_item_call.on_click
+ function="Advanced.WebBrowserTest"
+ parameter="http://community.secondlife.com/t5/English-Knowledge-Base/Second-Life-User-s-Guide/ta-p/1244857"/>
+ </menu_item_call>
+ <menu_item_call
+ label="Knowledge Base"
+ name="Knowledge Base">
+ <menu_item_call.on_click
+ function="Advanced.WebBrowserTest"
+ parameter="http://community.secondlife.com/t5/tkb/communitypage"/>
+ </menu_item_call>
+ <menu_item_call
+ label="Wiki"
+ name="Wiki">
+ <menu_item_call.on_click
+ function="Advanced.WebBrowserTest"
+ parameter="http://wiki.secondlife.com"/>
+ </menu_item_call>
+ <menu_item_call
+ label="Community Forums"
+ name="Community Forums">
+ <menu_item_call.on_click
+ function="Advanced.WebBrowserTest"
+ parameter="http://community.secondlife.com/t5/Forums/ct-p/Forums"/>
+ </menu_item_call>
+ <menu_item_call
+ label="Support portal"
+ name="Support portal">
+ <menu_item_call.on_click
+ function="Advanced.WebBrowserTest"
+ parameter="https://support.secondlife.com/"/>
+ </menu_item_call>
+ <menu_item_separator/>
+ <menu_item_call
+ label="[SECOND_LIFE] News"
+ name="Second Life News">
+ <menu_item_call.on_click
+ function="Advanced.WebBrowserTest"
+ parameter="http://community.secondlife.com/t5/Featured-News/bg-p/blog_feature_news"/>
+ </menu_item_call>
+ <menu_item_call
+ label="[SECOND_LIFE] Blogs"
+ name="Second Life Blogs">
+ <menu_item_call.on_click
+ function="Advanced.WebBrowserTest"
+ parameter="http://community.secondlife.com/t5/Blogs/ct-p/Blogs"/>
+ </menu_item_call>
<menu_item_separator/>
<menu_item_call
diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml
index 94307d2f93..35ce787847 100644
--- a/indra/newview/skins/default/xui/en/notifications.xml
+++ b/indra/newview/skins/default/xui/en/notifications.xml
@@ -3696,7 +3696,6 @@ Do Not Disturb is on. You will not be notified of incoming communications.
- Other residents will receive your Do Not Disturb response (set in Preferences &gt; General).
- Teleportation offers will be declined.
- Voice calls will be rejected.
-- Inventory offers will go to your Trash.
<usetemplate
ignoretext="I change my status to Do Not Disturb mode"
name="okignore"
diff --git a/indra/newview/skins/default/xui/en/widgets/toolbar.xml b/indra/newview/skins/default/xui/en/widgets/toolbar.xml
index 053b213ef4..0ace37a5dc 100644
--- a/indra/newview/skins/default/xui/en/widgets/toolbar.xml
+++ b/indra/newview/skins/default/xui/en/widgets/toolbar.xml
@@ -30,9 +30,9 @@
image_overlay_alignment="left"
use_ellipses="true"
auto_resize="true"
- button_flash_count="3"
- button_flash_rate="0.25"
- flash_color="EmphasisColor"/>
+ button_flash_count="4"
+ button_flash_rate="0.5"
+ flash_color="BeaconColor"/>
<button_icon pad_left="10"
pad_right="10"
image_bottom_pad="10"
@@ -51,7 +51,7 @@
chrome="true"
use_ellipses="true"
auto_resize="true"
- button_flash_count="3"
- button_flash_rate="0.25"
- flash_color="EmphasisColor"/>
+ button_flash_count="4"
+ button_flash_rate="0.5"
+ flash_color="BeaconColor"/>
</toolbar>