diff options
author | Merov Linden <merov@lindenlab.com> | 2012-12-19 11:04:24 -0800 |
---|---|---|
committer | Merov Linden <merov@lindenlab.com> | 2012-12-19 11:04:24 -0800 |
commit | e32f110b9a17928285dc9e39953abce9eecf9742 (patch) | |
tree | 1be90f51b3117efd4b4d938a5692095244c1c5cd /indra | |
parent | 8adca4583ec95ac063f79990ac092998f24415b8 (diff) | |
parent | b34e3a1b40fd72b4c4cdc1553c3f5934e9e9cef5 (diff) |
Pull merge from richard/viewer-chui
Diffstat (limited to 'indra')
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 > 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> |