summaryrefslogtreecommitdiff
path: root/indra/newview
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/newview
parent8adca4583ec95ac063f79990ac092998f24415b8 (diff)
parentb34e3a1b40fd72b4c4cdc1553c3f5934e9e9cef5 (diff)
Pull merge from richard/viewer-chui
Diffstat (limited to 'indra/newview')
-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
38 files changed, 1124 insertions, 401 deletions
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>