From d7282efb6fa8bd2cc289f9e3da73afe77e4bc8b3 Mon Sep 17 00:00:00 2001 From: Ansariel Date: Thu, 19 Nov 2015 21:32:47 +0100 Subject: [PATCH] FIRE-17318: Add option to use legacy notification well window (simple list view) --- indra/newview/app_settings/settings.xml | 24 +++ indra/newview/llappviewer.cpp | 3 + indra/newview/llchannelmanager.cpp | 12 +- indra/newview/llchiclet.cpp | 28 ++- indra/newview/llchicletbar.cpp | 12 +- indra/newview/llstartup.cpp | 2 +- indra/newview/llsyswellwindow.cpp | 180 ++++++++++++++++++ indra/newview/llsyswellwindow.h | 59 ++++++ indra/newview/llviewerfloaterreg.cpp | 12 +- .../skins/default/xui/en/floater_sys_well.xml | 4 + .../default/xui/en/panel_preferences_UI.xml | 23 +++ 11 files changed, 352 insertions(+), 7 deletions(-) diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index f1b34cad49..09f5f327a8 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -23712,6 +23712,30 @@ Change of this parameter will affect the layout of buttons in notification toast Value 0 + FSLegacyNotificationWell + + Comment + Enables the legacy notifications and system messages well + Persist + 1 + Type + Boolean + Value + 0 + + FSInternalLegacyNotificationWell + + Comment + Internal state of FSLegacyNotificationWell + Persist + 0 + HideFromEditor + 1 + Type + Boolean + Value + 0 + diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index f518577058..4d3dbd18aa 100755 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -1036,6 +1036,9 @@ bool LLAppViewer::init() settings_map["floater"] = &gSavedSettings; // *TODO: New settings file settings_map["account"] = &gSavedPerAccountSettings; + // Optional legacy notification well + gSavedSettings.setBOOL("FSInternalLegacyNotificationWell", gSavedSettings.getBOOL("FSLegacyNotificationWell")); + LLUI::initClass(settings_map, LLUIImageList::getInstance(), ui_audio_callback, diff --git a/indra/newview/llchannelmanager.cpp b/indra/newview/llchannelmanager.cpp index 5d3c37b4a1..48dac91c6b 100755 --- a/indra/newview/llchannelmanager.cpp +++ b/indra/newview/llchannelmanager.cpp @@ -150,7 +150,17 @@ void LLChannelManager::onLoginCompleted() S32 channel_right_bound = gViewerWindow->getWorldViewRectScaled().mRight - gSavedSettings.getS32("NotificationChannelRightMargin"); S32 channel_width = gSavedSettings.getS32("NotifyBoxWidth"); mStartUpChannel->init(channel_right_bound - channel_width, channel_right_bound); - mStartUpChannel->setMouseDownCallback(boost::bind(&LLFloaterNotificationsTabbed::onStartUpToastClick, LLFloaterNotificationsTabbed::getInstance(), _2, _3, _4)); + // Optional legacy notification well + //mStartUpChannel->setMouseDownCallback(boost::bind(&LLFloaterNotificationsTabbed::onStartUpToastClick, LLFloaterNotificationsTabbed::getInstance(), _2, _3, _4)); + if (!gSavedSettings.getBOOL("FSInternalLegacyNotificationWell")) + { + mStartUpChannel->setMouseDownCallback(boost::bind(&LLFloaterNotificationsTabbed::onStartUpToastClick, LLFloaterNotificationsTabbed::getInstance(), _2, _3, _4)); + } + else + { + mStartUpChannel->setMouseDownCallback(boost::bind(&LLNotificationWellWindow::onStartUpToastClick, LLNotificationWellWindow::getInstance(), _2, _3, _4)); + } + // mStartUpChannel->setCommitCallback(boost::bind(&LLChannelManager::onStartUpToastClose, this)); mStartUpChannel->createStartUpToast(away_notifications, gSavedSettings.getS32("StartUpToastLifeTime")); diff --git a/indra/newview/llchiclet.cpp b/indra/newview/llchiclet.cpp index a5516460f3..33dd9620b1 100755 --- a/indra/newview/llchiclet.cpp +++ b/indra/newview/llchiclet.cpp @@ -313,7 +313,16 @@ LLNotificationChiclet::LLNotificationChiclet(const Params& p) mNotificationChannel.reset(new ChicletNotificationChannel(this)); // ensure that notification well window exists, to synchronously // handle toast add/delete events. - LLFloaterNotificationsTabbed::getInstance()->setSysWellChiclet(this); + // Optional legacy notification well + //LLFloaterNotificationsTabbed::getInstance()->setSysWellChiclet(this); + if (!gSavedSettings.getBOOL("FSInternalLegacyNotificationWell")) + { + LLFloaterNotificationsTabbed::getInstance()->setSysWellChiclet(this); + } + else + { + LLNotificationWellWindow::getInstance()->setSysWellChiclet(this); + } } void LLNotificationChiclet::onMenuItemClicked(const LLSD& user_data) @@ -321,7 +330,16 @@ void LLNotificationChiclet::onMenuItemClicked(const LLSD& user_data) std::string action = user_data.asString(); if("close all" == action) { - LLFloaterNotificationsTabbed::getInstance()->closeAll(); + // Optional legacy notification well + //LLFloaterNotificationsTabbed::getInstance()->closeAll(); + if (!gSavedSettings.getBOOL("FSInternalLegacyNotificationWell")) + { + LLFloaterNotificationsTabbed::getInstance()->closeAll(); + } + else + { + LLNotificationWellWindow::getInstance()->closeAll(); + } // [FS communication UI] - We have our own IM well button again //LLIMWellWindow::getInstance()->closeAll(); } @@ -374,7 +392,11 @@ bool LLNotificationChiclet::ChicletNotificationChannel::filterNotification( LLNo if ( (notification->getName() == "ScriptDialog") // special case for scripts // if there is no toast window for the notification, filter it //|| (!LLNotificationWellWindow::getInstance()->findItemByID(notification->getID())) - || (!LLFloaterNotificationsTabbed::getInstance()->findItemByID(notification->getID(), notification->getName())) + // Optional legacy notification well + //|| (!LLFloaterNotificationsTabbed::getInstance()->findItemByID(notification->getID(), notification->getName())) + || ((!gSavedSettings.getBOOL("FSInternalLegacyNotificationWell") && !LLFloaterNotificationsTabbed::getInstance()->findItemByID(notification->getID(), notification->getName())) + || (gSavedSettings.getBOOL("FSInternalLegacyNotificationWell") && !LLNotificationWellWindow::getInstance()->findItemByID(notification->getID()))) + // ) { displayNotification = false; diff --git a/indra/newview/llchicletbar.cpp b/indra/newview/llchicletbar.cpp index 1e97c6dfa3..f537a947e1 100755 --- a/indra/newview/llchicletbar.cpp +++ b/indra/newview/llchicletbar.cpp @@ -150,7 +150,17 @@ BOOL LLChicletBar::postBuild() // [FS communication UI] showWellButton("im_well", !LLIMWellWindow::getInstance()->isWindowEmpty()); - showWellButton("notification_well", !LLFloaterNotificationsTabbed::getInstance()->isWindowEmpty()); + // Optional legacy notification well + //showWellButton("notification_well", !LLFloaterNotificationsTabbed::getInstance()->isWindowEmpty()); + if (!gSavedSettings.getBOOL("FSInternalLegacyNotificationWell")) + { + showWellButton("notification_well", !LLFloaterNotificationsTabbed::getInstance()->isWindowEmpty()); + } + else + { + showWellButton("notification_well", !LLNotificationWellWindow::getInstance()->isWindowEmpty()); + } + // LLPanelTopInfoBar::instance().setResizeCallback(boost::bind(&LLChicletBar::fitWithTopInfoBar, this)); LLPanelTopInfoBar::instance().setVisibleCallback(boost::bind(&LLChicletBar::fitWithTopInfoBar, this)); diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index d8e6f74227..ff0a923a2d 100755 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -604,7 +604,7 @@ bool idle_startup() gSavedSettings.setString("FSInternalSkinCurrent", gSavedSettings.getString("FSSkinCurrentReadableName")); gSavedSettings.setString("FSInternalSkinCurrentTheme", gSavedSettings.getString("FSSkinCurrentThemeReadableName")); // - + if (LLFeatureManager::getInstance()->isSafe()) { LLNotificationsUtil::add("DisplaySetToSafe"); diff --git a/indra/newview/llsyswellwindow.cpp b/indra/newview/llsyswellwindow.cpp index ad03fa246b..a18b4974e8 100755 --- a/indra/newview/llsyswellwindow.cpp +++ b/indra/newview/llsyswellwindow.cpp @@ -438,6 +438,186 @@ BOOL LLIMWellWindow::ObjectRowPanel::handleRightMouseDown(S32 x, S32 y, MASK mas return mChiclet->handleRightMouseDown(x, y, mask); } +// Optional legacy notification well +/************************************************************************/ +/* LLNotificationWellWindow implementation */ +/************************************************************************/ + +////////////////////////////////////////////////////////////////////////// +// PUBLIC METHODS +LLNotificationWellWindow::WellNotificationChannel::WellNotificationChannel(LLNotificationWellWindow* well_window) +: LLNotificationChannel(LLNotificationChannel::Params().name(well_window->getPathname())), + mWellWindow(well_window) +{ + connectToChannel("Notifications"); + connectToChannel("Group Notifications"); + connectToChannel("Offer"); +} + +LLNotificationWellWindow::LLNotificationWellWindow(const LLSD& key) +: LLSysWellWindow(key) +{ + mNotificationUpdates.reset(new WellNotificationChannel(this)); + mUpdateLocked = false; +} + +// static +LLNotificationWellWindow* LLNotificationWellWindow::getInstance(const LLSD& key /*= LLSD()*/) +{ + return LLFloaterReg::getTypedInstance("notification_well_window", key); +} + +// virtual +BOOL LLNotificationWellWindow::postBuild() +{ + BOOL rv = LLSysWellWindow::postBuild(); + setTitle(getString("title_notification_well_window")); + return rv; +} + +// virtual +void LLNotificationWellWindow::setVisible(BOOL visible) +{ + if (visible) + { + // when Notification channel is cleared, storable toasts will be added into the list. + clearScreenChannels(); + } + + LLSysWellWindow::setVisible(visible); +} + +//--------------------------------------------------------------------------------- +void LLNotificationWellWindow::addItem(LLSysWellItem::Params p) +{ + LLSD value = p.notification_id; + // do not add clones + if( mMessageList->getItemByValue(value)) + return; + + LLSysWellItem* new_item = new LLSysWellItem(p); + if (mMessageList->addItem(new_item, value, ADD_TOP, !mUpdateLocked)) + { + if( !mUpdateLocked ) + { + mSysWellChiclet->updateWidget(isWindowEmpty()); + reshapeWindow(); + } + new_item->setOnItemCloseCallback(boost::bind(&LLNotificationWellWindow::onItemClose, this, _1)); + new_item->setOnItemClickCallback(boost::bind(&LLNotificationWellWindow::onItemClick, this, _1)); + } + else + { + LL_WARNS() << "Unable to add Notification into the list, notification ID: " << p.notification_id + << ", title: " << p.title + << LL_ENDL; + + new_item->die(); + } +} + +void LLNotificationWellWindow::closeAll() +{ + // Need to clear notification channel, to add storable toasts into the list. + clearScreenChannels(); + std::vector items; + mMessageList->getItems(items); + + LLPersistentNotificationStorage::getInstance()->startBulkUpdate(); // + + for (std::vector::iterator + iter = items.begin(), + iter_end = items.end(); + iter != iter_end; ++iter) + { + LLSysWellItem* sys_well_item = dynamic_cast(*iter); + if (sys_well_item) + onItemClose(sys_well_item); + } + + // All done, renable normal mode and save. + LLPersistentNotificationStorage::getInstance()->endBulkUpdate(); + LLPersistentNotificationStorage::getInstance()->saveNotifications(); + // +} + +void LLNotificationWellWindow::unlockWindowUpdate() +{ + mUpdateLocked = false; + mSysWellChiclet->updateWidget(isWindowEmpty()); + + // Let the list rearrange itself. This is normally called during addItem if the window is not locked. + LLSD oNotify; + oNotify["rearrange"] = 1; + mMessageList->notify( oNotify ); + + reshapeWindow(); + +} + +////////////////////////////////////////////////////////////////////////// +// PRIVATE METHODS +void LLNotificationWellWindow::initChannel() +{ + LLSysWellWindow::initChannel(); + if(mChannel) + { + mChannel->addOnStoreToastCallback(boost::bind(&LLNotificationWellWindow::onStoreToast, this, _1, _2)); + } +} + +void LLNotificationWellWindow::clearScreenChannels() +{ + // 1 - remove StartUp toast and channel if present + if(!LLNotificationsUI::LLScreenChannel::getStartUpToastShown()) + { + LLNotificationsUI::LLChannelManager::getInstance()->onStartUpToastClose(); + } + + // 2 - remove toasts in Notification channel + if(mChannel) + { + mChannel->removeAndStoreAllStorableToasts(); + } +} + +void LLNotificationWellWindow::onStoreToast(LLPanel* info_panel, LLUUID id) +{ + LLSysWellItem::Params p; + p.notification_id = id; + p.title = static_cast(info_panel)->getTitle(); + addItem(p); +} + +void LLNotificationWellWindow::onItemClick(LLSysWellItem* item) +{ + LLUUID id = item->getID(); + LLFloaterReg::showInstance("inspect_toast", id); +} + +void LLNotificationWellWindow::onItemClose(LLSysWellItem* item) +{ + LLUUID id = item->getID(); + + if(mChannel) + { + // removeItemByID() is invoked from killToastByNotificationID() and item will removed; + mChannel->killToastByNotificationID(id); + } + else + { + // removeItemByID() should be called one time for each item to remove it from notification well + removeItemByID(id); + } + +} + +void LLNotificationWellWindow::onAdd( LLNotificationPtr notify ) +{ + removeItemByID(notify->getID()); +} +// + /************************************************************************/ /* LLIMWellWindow implementation */ /************************************************************************/ diff --git a/indra/newview/llsyswellwindow.h b/indra/newview/llsyswellwindow.h index ecfdc652c6..1f00b94e65 100755 --- a/indra/newview/llsyswellwindow.h +++ b/indra/newview/llsyswellwindow.h @@ -102,6 +102,65 @@ protected: bool mIsReshapedByUser; }; +// Optional legacy notification well +/** + * Class intended to manage incoming notifications. + * + * It contains a list of notifications that have not been responded to. + */ +class LLNotificationWellWindow : public LLSysWellWindow +{ + bool mUpdateLocked; + +public: + LLNotificationWellWindow(const LLSD& key); + static LLNotificationWellWindow* getInstance(const LLSD& key = LLSD()); + + /*virtual*/ BOOL postBuild(); + /*virtual*/ void setVisible(BOOL visible); + /*virtual*/ void onAdd(LLNotificationPtr notify); + // Operating with items + void addItem(LLSysWellItem::Params p); + + // Closes all notifications and removes them from the Notification Well + void closeAll(); + + void lockWindowUpdate() + { mUpdateLocked = true; } + void unlockWindowUpdate(); + +protected: + struct WellNotificationChannel : public LLNotificationChannel + { + WellNotificationChannel(LLNotificationWellWindow*); + void onDelete(LLNotificationPtr notify) + { + mWellWindow->removeItemByID(notify->getID()); + } + + LLNotificationWellWindow* mWellWindow; + }; + + LLNotificationChannelPtr mNotificationUpdates; + /*virtual*/ const std::string& getAnchorViewName() { return NOTIFICATION_WELL_ANCHOR_NAME; } + +private: + // init Window's channel + void initChannel(); + void clearScreenChannels(); + + void onStoreToast(LLPanel* info_panel, LLUUID id); + + // Handlers + void onItemClick(LLSysWellItem* item); + void onItemClose(LLSysWellItem* item); + + // ID of a toast loaded by user (by clicking notification well item) + LLUUID mLoadedToastId; + +}; +// + /** * Class intended to manage incoming messages in IM chats. * diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp index cb270f99de..6fc8dcb611 100755 --- a/indra/newview/llviewerfloaterreg.cpp +++ b/indra/newview/llviewerfloaterreg.cpp @@ -322,7 +322,17 @@ void LLViewerFloaterReg::registerFloaters() LLFloaterReg::add("notifications_console", "floater_notifications_console.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); - LLFloaterReg::add("notification_well_window", "floater_notifications_tabbed.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); + // Optional legacy notification well + //LLFloaterReg::add("notification_well_window", "floater_notifications_tabbed.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); + if (!gSavedSettings.getBOOL("FSInternalLegacyNotificationWell")) + { + LLFloaterReg::add("notification_well_window", "floater_notifications_tabbed.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); + } + else + { + LLFloaterReg::add("notification_well_window", "floater_sys_well.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); + } + // LLFloaterReg::add("object_weights", "floater_object_weights.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); LLFloaterReg::add("openobject", "floater_openobject.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); diff --git a/indra/newview/skins/default/xui/en/floater_sys_well.xml b/indra/newview/skins/default/xui/en/floater_sys_well.xml index f09e87bffd..1a3ebf41e0 100755 --- a/indra/newview/skins/default/xui/en/floater_sys_well.xml +++ b/indra/newview/skins/default/xui/en/floater_sys_well.xml @@ -23,6 +23,10 @@ name="title_im_well_window"> Conversations + + Notifications + + + + (requires restart) +