summaryrefslogtreecommitdiff
path: root/indra/newview/llsyswellwindow.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview/llsyswellwindow.cpp')
-rwxr-xr-x[-rw-r--r--]indra/newview/llsyswellwindow.cpp734
1 files changed, 391 insertions, 343 deletions
diff --git a/indra/newview/llsyswellwindow.cpp b/indra/newview/llsyswellwindow.cpp
index 6714fe908f..8babb874f8 100644..100755
--- a/indra/newview/llsyswellwindow.cpp
+++ b/indra/newview/llsyswellwindow.cpp
@@ -1,61 +1,52 @@
/**
* @file llsyswellwindow.cpp
* @brief // TODO
- * $LicenseInfo:firstyear=2000&license=viewergpl$
- *
- * Copyright (c) 2000-2009, Linden Research, Inc.
- *
+ * $LicenseInfo:firstyear=2000&license=viewerlgpl$
* Second Life Viewer Source Code
- * The source code in this file ("Source Code") is provided by Linden Lab
- * to you under the terms of the GNU General Public License, version 2.0
- * ("GPL"), unless you have obtained a separate licensing agreement
- * ("Other License"), formally executed by you and Linden Lab. Terms of
- * the GPL can be found in doc/GPL-license.txt in this distribution, or
- * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ * 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.
*
- * There are special exceptions to the terms and conditions of the GPL as
- * it is applied to this Source Code. View the full text of the exception
- * in the file doc/FLOSS-exception.txt in this software distribution, or
- * online at
- * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ * 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.
*
- * By copying, modifying or distributing this software, you acknowledge
- * that you have read and understood your obligations described above,
- * and agree to abide by those obligations.
+ * 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
*
- * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
- * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
- * COMPLETENESS OR PERFORMANCE.
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
-
#include "llviewerprecompiledheaders.h" // must be first include
-
-#include "llflatlistview.h"
-
#include "llsyswellwindow.h"
-#include "llbottomtray.h"
-#include "llviewercontrol.h"
-#include "llviewerwindow.h"
-
#include "llchiclet.h"
-#include "lltoastpanel.h"
+#include "llchicletbar.h"
+#include "llflatlistview.h"
+#include "llfloaterreg.h"
#include "llnotificationmanager.h"
-
+#include "llnotificationsutil.h"
+#include "llscriptfloater.h"
+#include "llspeakers.h"
+#include "lltoastpanel.h"
//---------------------------------------------------------------------------------
-LLSysWellWindow::LLSysWellWindow(const LLSD& key) : LLDockableFloater(NULL, key),
+LLSysWellWindow::LLSysWellWindow(const LLSD& key) : LLTransientDockableFloater(NULL, true, key),
mChannel(NULL),
mMessageList(NULL),
- mSeparator(NULL)
-{
- LLIMMgr::getInstance()->addSessionObserver(this);
- LLIMChiclet::sFindChicletsSignal.connect(boost::bind(&LLSysWellWindow::findIMChiclet, this, _1));
+ mSysWellChiclet(NULL),
+ NOTIFICATION_WELL_ANCHOR_NAME("notification_well_panel"),
+ IM_WELL_ANCHOR_NAME("im_well_panel"),
+ mIsReshapedByUser(false)
- mTypedItemsCount[IT_NOTIFICATION] = 0;
- mTypedItemsCount[IT_INSTANT_MESSAGE] = 0;
+{
+ setOverlapsScreenChannel(true);
}
//---------------------------------------------------------------------------------
@@ -63,106 +54,44 @@ BOOL LLSysWellWindow::postBuild()
{
mMessageList = getChild<LLFlatListView>("notification_list");
- // init connections to the list's update events
- connectListUpdaterToSignal("notify");
- connectListUpdaterToSignal("groupnotify");
-
// get a corresponding channel
initChannel();
- LLPanel::Params params;
- mSeparator = LLUICtrlFactory::create<LLPanel>(params);
- LLUICtrlFactory::instance().buildPanel(mSeparator, "panel_separator.xml");
-
- LLRect rc = mSeparator->getRect();
- rc.setOriginAndSize(0, 0, mMessageList->getItemsRect().getWidth(), rc.getHeight());
- mSeparator->setRect(rc);
- mSeparator->setFollows(FOLLOWS_LEFT | FOLLOWS_RIGHT | FOLLOWS_TOP);
- mSeparator->setVisible(FALSE);
-
- mMessageList->addItem(mSeparator);
-
- return LLDockableFloater::postBuild();
+ return LLTransientDockableFloater::postBuild();
}
//---------------------------------------------------------------------------------
void LLSysWellWindow::setMinimized(BOOL minimize)
{
- // we don't show empty Message Well window
- if (!minimize)
- {
- setVisible(!isWindowEmpty());
- }
-
- LLDockableFloater::setMinimized(minimize);
-}
-
-//---------------------------------------------------------------------------------
-void LLSysWellWindow::connectListUpdaterToSignal(std::string notification_type)
-{
- LLNotificationsUI::LLNotificationManager* manager = LLNotificationsUI::LLNotificationManager::getInstance();
- LLNotificationsUI::LLEventHandler* n_handler = manager->getHandlerForNotification(notification_type);
- if(n_handler)
- {
- n_handler->setNotificationIDCallback(boost::bind(&LLSysWellWindow::removeItemByID, this, _1));
- }
- else
- {
- llwarns << "LLSysWellWindow::connectListUpdaterToSignal() - could not get a handler for '" << notification_type <<"' type of notifications" << llendl;
- }
+ LLTransientDockableFloater::setMinimized(minimize);
}
//---------------------------------------------------------------------------------
-void LLSysWellWindow::onChicletClick()
+void LLSysWellWindow::handleReshape(const LLRect& rect, bool by_user)
{
- // 1 - remove StartUp toast and channel if present
- if(!LLNotificationsUI::LLScreenChannel::getStartUpToastShown())
- {
- LLNotificationsUI::LLChannelManager::getInstance()->onStartUpToastClose();
- }
-
- // 2 - toggle instance of SysWell's chiclet-window
- toggleWindow();
+ mIsReshapedByUser |= by_user; // mark floater that it is reshaped by user
+ LLTransientDockableFloater::handleReshape(rect, by_user);
}
//---------------------------------------------------------------------------------
-LLSysWellWindow::~LLSysWellWindow()
+void LLSysWellWindow::onStartUpToastClick(S32 x, S32 y, MASK mask)
{
- LLIMMgr::getInstance()->removeSessionObserver(this);
+ // just set floater visible. Screen channels will be cleared.
+ setVisible(TRUE);
}
-//---------------------------------------------------------------------------------
-void LLSysWellWindow::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))
+void LLSysWellWindow::setSysWellChiclet(LLSysWellChiclet* chiclet)
+{
+ mSysWellChiclet = chiclet;
+ if(NULL != mSysWellChiclet)
{
- handleItemAdded(IT_NOTIFICATION);
-
- reshapeWindow();
-
- new_item->setOnItemCloseCallback(boost::bind(&LLSysWellWindow::onItemClose, this, _1));
- new_item->setOnItemClickCallback(boost::bind(&LLSysWellWindow::onItemClick, this, _1));
- }
- else
- {
- llwarns << "Unable to add Notification into the list, notification ID: " << p.notification_id
- << ", title: " << p.title
- << llendl;
-
- new_item->die();
+ mSysWellChiclet->updateWidget(isWindowEmpty());
}
}
//---------------------------------------------------------------------------------
-void LLSysWellWindow::clear()
+LLSysWellWindow::~LLSysWellWindow()
{
- mMessageList->clear();
}
//---------------------------------------------------------------------------------
@@ -170,13 +99,16 @@ void LLSysWellWindow::removeItemByID(const LLUUID& id)
{
if(mMessageList->removeItemByValue(id))
{
- handleItemRemoved(IT_NOTIFICATION);
+ if (NULL != mSysWellChiclet)
+ {
+ mSysWellChiclet->updateWidget(isWindowEmpty());
+ }
reshapeWindow();
}
else
{
- llwarns << "Unable to remove notification from the list, ID: " << id
- << llendl;
+ LL_WARNS() << "Unable to remove notification from the list, ID: " << id
+ << LL_ENDL;
}
// hide chiclet window if there are no items left
@@ -186,117 +118,61 @@ void LLSysWellWindow::removeItemByID(const LLUUID& id)
}
}
-//---------------------------------------------------------------------------------
-void LLSysWellWindow::onItemClick(LLSysWellItem* item)
+ LLPanel * LLSysWellWindow::findItemByID(const LLUUID& id)
{
- LLUUID id = item->getID();
- if(mChannel)
- mChannel->loadStoredToastByNotificationIDToChannel(id);
+ return mMessageList->getItemByValue(id);
}
//---------------------------------------------------------------------------------
-void LLSysWellWindow::onItemClose(LLSysWellItem* item)
-{
- LLUUID id = item->getID();
- removeItemByID(id);
- if(mChannel)
- mChannel->killToastByNotificationID(id);
-}
-
-//--------------------------------------------------------------------------
-void LLSysWellWindow::onStoreToast(LLPanel* info_panel, LLUUID id)
-{
- LLSysWellItem::Params p;
- p.notification_id = id;
- p.title = static_cast<LLToastPanel*>(info_panel)->getTitle();
- addItem(p);
-}
-
//---------------------------------------------------------------------------------
void LLSysWellWindow::initChannel()
{
LLNotificationsUI::LLScreenChannelBase* channel = LLNotificationsUI::LLChannelManager::getInstance()->findChannelByID(
LLUUID(gSavedSettings.getString("NotificationChannelUUID")));
mChannel = dynamic_cast<LLNotificationsUI::LLScreenChannel*>(channel);
- if(mChannel)
- {
- mChannel->setOnStoreToastCallback(boost::bind(&LLSysWellWindow::onStoreToast, this, _1, _2));
- }
- else
- {
- llwarns << "LLSysWellWindow::initChannel() - could not get a requested screen channel" << llendl;
- }
-}
-
-//---------------------------------------------------------------------------------
-void LLSysWellWindow::getAllowedRect(LLRect& rect)
-{
- rect = gViewerWindow->getWorldViewRect();
-}
-
-//---------------------------------------------------------------------------------
-void LLSysWellWindow::toggleWindow()
-{
- if (getDockControl() == NULL)
- {
- setDockControl(new LLDockControl(
- LLBottomTray::getInstance()->getSysWell(), this,
- getDockTongue(), LLDockControl::TOP, boost::bind(&LLSysWellWindow::getAllowedRect, this, _1)));
- }
-
- if(!getVisible() || isMinimized())
- {
- if(isWindowEmpty())
- {
- return;
- }
-
- setVisible(TRUE);
- }
- else if (isDocked())
+ if(NULL == mChannel)
{
- setVisible(FALSE);
+ LL_WARNS() << "LLSysWellWindow::initChannel() - could not get a requested screen channel" << LL_ENDL;
}
- //set window in foreground
- setFocus(getVisible());
}
//---------------------------------------------------------------------------------
void LLSysWellWindow::setVisible(BOOL visible)
{
- if(visible)
- {
- if (LLBottomTray::instanceExists())
- {
- LLBottomTray::getInstance()->getSysWell()->setToggleState(TRUE);
- }
- }
- else
+ if (visible)
{
- if (LLBottomTray::instanceExists())
+ if (NULL == getDockControl() && getDockTongue().notNull())
{
- LLBottomTray::getInstance()->getSysWell()->setToggleState(FALSE);
+ setDockControl(new LLDockControl(
+ LLChicletBar::getInstance()->getChild<LLView>(getAnchorViewName()), this,
+ getDockTongue(), LLDockControl::BOTTOM));
}
}
- LLDockableFloater::setVisible(visible);
+ // do not show empty window
+ if (NULL == mMessageList || isWindowEmpty()) visible = FALSE;
+
+ LLTransientDockableFloater::setVisible(visible);
// update notification channel state
+ initChannel(); // make sure the channel still exists
if(mChannel)
{
mChannel->updateShowToastsState();
+ mChannel->redrawToasts();
}
}
//---------------------------------------------------------------------------------
void LLSysWellWindow::setDocked(bool docked, bool pop_on_undock)
{
- LLDockableFloater::setDocked(docked, pop_on_undock);
+ LLTransientDockableFloater::setDocked(docked, pop_on_undock);
// update notification channel state
if(mChannel)
{
mChannel->updateShowToastsState();
+ mChannel->redrawToasts();
}
}
@@ -307,20 +183,24 @@ void LLSysWellWindow::reshapeWindow()
// it includes height from floater top to list top and from floater bottom and list bottom
static S32 parent_list_delta_height = getRect().getHeight() - mMessageList->getRect().getHeight();
- S32 notif_list_height = mMessageList->getItemsRect().getHeight() + 2 * mMessageList->getBorderWidth();
+ if (!mIsReshapedByUser) // Don't reshape Well window, if it ever was reshaped by user. See EXT-5715.
+ {
+ S32 notif_list_height = mMessageList->getItemsRect().getHeight() + 2 * mMessageList->getBorderWidth();
- LLRect curRect = getRect();
+ LLRect curRect = getRect();
- S32 new_window_height = notif_list_height + parent_list_delta_height;
+ S32 new_window_height = notif_list_height + parent_list_delta_height;
- if (new_window_height > MAX_WINDOW_HEIGHT)
- {
- new_window_height = MAX_WINDOW_HEIGHT;
+ if (new_window_height > MAX_WINDOW_HEIGHT)
+ {
+ new_window_height = MAX_WINDOW_HEIGHT;
+ }
+ S32 newWidth = curRect.getWidth() < MIN_WINDOW_WIDTH ? MIN_WINDOW_WIDTH : curRect.getWidth();
+
+ curRect.setLeftTopAndSize(curRect.mLeft, curRect.mTop, newWidth, new_window_height);
+ reshape(curRect.getWidth(), curRect.getHeight(), TRUE);
+ setRect(curRect);
}
- S32 newY = curRect.mTop + new_window_height - curRect.getHeight();
- curRect.setLeftTopAndSize(curRect.mLeft, newY, MIN_WINDOW_WIDTH, new_window_height);
- reshape(curRect.getWidth(), curRect.getHeight(), TRUE);
- setRect(curRect);
// update notification channel state
// update on a window reshape is important only when a window is visible and docked
@@ -331,224 +211,392 @@ void LLSysWellWindow::reshapeWindow()
}
//---------------------------------------------------------------------------------
-LLChiclet* LLSysWellWindow::findIMChiclet(const LLUUID& sessionId)
+bool LLSysWellWindow::isWindowEmpty()
{
- LLChiclet* res = NULL;
- RowPanel* panel = mMessageList->getTypedItemByValue<RowPanel>(sessionId);
- if (panel != NULL)
- {
- res = panel->mChiclet;
- }
+ return mMessageList->size() == 0;
+}
- return res;
+/************************************************************************/
+/* ObjectRowPanel implementation */
+/************************************************************************/
+
+LLIMWellWindow::ObjectRowPanel::ObjectRowPanel(const LLUUID& notification_id, bool new_message/* = false*/)
+ : LLPanel()
+ , mChiclet(NULL)
+{
+ buildFromFile( "panel_active_object_row.xml");
+
+ initChiclet(notification_id);
+
+ LLTextBox* obj_name = getChild<LLTextBox>("object_name");
+ obj_name->setValue(LLScriptFloaterManager::getObjectName(notification_id));
+
+ mCloseBtn = getChild<LLButton>("hide_btn");
+ mCloseBtn->setCommitCallback(boost::bind(&LLIMWellWindow::ObjectRowPanel::onClosePanel, this));
}
//---------------------------------------------------------------------------------
-void LLSysWellWindow::addIMRow(const LLUUID& sessionId, S32 chicletCounter,
- const std::string& name, const LLUUID& otherParticipantId)
+LLIMWellWindow::ObjectRowPanel::~ObjectRowPanel()
{
- RowPanel* item = new RowPanel(this, sessionId, chicletCounter, name, otherParticipantId);
- if (mMessageList->insertItemAfter(mSeparator, item, sessionId))
- {
- handleItemAdded(IT_INSTANT_MESSAGE);
- }
- else
- {
- llwarns << "Unable to add IM Row into the list, sessionID: " << sessionId
- << ", name: " << name
- << ", other participant ID: " << otherParticipantId
- << llendl;
-
- item->die();
- }
}
//---------------------------------------------------------------------------------
-void LLSysWellWindow::delIMRow(const LLUUID& sessionId)
+void LLIMWellWindow::ObjectRowPanel::onClosePanel()
{
- if (mMessageList->removeItemByValue(sessionId))
- {
- handleItemRemoved(IT_INSTANT_MESSAGE);
- }
- else
+ LLScriptFloaterManager::getInstance()->removeNotification(mChiclet->getSessionId());
+}
+
+void LLIMWellWindow::ObjectRowPanel::initChiclet(const LLUUID& notification_id, bool new_message/* = false*/)
+{
+ // Choose which of the pre-created chiclets to use.
+ switch(LLScriptFloaterManager::getObjectType(notification_id))
{
- llwarns << "Unable to remove IM Row from the list, sessionID: " << sessionId
- << llendl;
+ case LLScriptFloaterManager::OBJ_GIVE_INVENTORY:
+ mChiclet = getChild<LLInvOfferChiclet>("inv_offer_chiclet");
+ break;
+ default:
+ mChiclet = getChild<LLScriptChiclet>("object_chiclet");
+ break;
}
- // remove all toasts that belong to this session from a screen
- if(mChannel)
- mChannel->removeToastsBySessionID(sessionId);
+ mChiclet->setVisible(true);
+ mChiclet->setSessionId(notification_id);
+}
- // hide chiclet window if there are no items left
- if(isWindowEmpty())
- {
- setVisible(FALSE);
- }
+//---------------------------------------------------------------------------------
+void LLIMWellWindow::ObjectRowPanel::onMouseEnter(S32 x, S32 y, MASK mask)
+{
+ setTransparentColor(LLUIColorTable::instance().getColor("SysWellItemSelected"));
}
//---------------------------------------------------------------------------------
-bool LLSysWellWindow::isWindowEmpty()
+void LLIMWellWindow::ObjectRowPanel::onMouseLeave(S32 x, S32 y, MASK mask)
{
- // keep in mind, mSeparator is always in the list
- return mMessageList->size() == 1;
+ setTransparentColor(LLUIColorTable::instance().getColor("SysWellItemUnselected"));
}
//---------------------------------------------------------------------------------
-//virtual
-void LLSysWellWindow::sessionAdded(const LLUUID& session_id,
- const std::string& name, const LLUUID& other_participant_id)
+// virtual
+BOOL LLIMWellWindow::ObjectRowPanel::handleMouseDown(S32 x, S32 y, MASK mask)
{
- //*TODO get rid of get_session_value, session_id's are unique, cause performance degradation with lots chiclets (IB)
- if (mMessageList->getItemByValue(session_id) == NULL)
+ // Pass the mouse down event to the chiclet (EXT-596).
+ if (!mChiclet->pointInView(x, y) && !mCloseBtn->getRect().pointInRect(x, y)) // prevent double call of LLIMChiclet::onMouseDown()
{
- S32 chicletCounter = LLIMModel::getInstance()->getNumUnread(session_id);
- if (chicletCounter > -1)
- {
- addIMRow(session_id, chicletCounter, name, other_participant_id);
- reshapeWindow();
- }
+ mChiclet->onMouseDown();
+ return TRUE;
}
+
+ return LLPanel::handleMouseDown(x, y, mask);
}
-//---------------------------------------------------------------------------------
-//virtual
-void LLSysWellWindow::sessionRemoved(const LLUUID& sessionId)
+// virtual
+BOOL LLIMWellWindow::ObjectRowPanel::handleRightMouseDown(S32 x, S32 y, MASK mask)
{
- delIMRow(sessionId);
- reshapeWindow();
- LLBottomTray::getInstance()->getSysWell()->updateUreadIMNotifications();
+ return mChiclet->handleRightMouseDown(x, y, mask);
+}
+
+/************************************************************************/
+/* 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));
+}
+
+// static
+LLNotificationWellWindow* LLNotificationWellWindow::getInstance(const LLSD& key /*= LLSD()*/)
+{
+ return LLFloaterReg::getTypedInstance<LLNotificationWellWindow>("notification_well_window", key);
+}
+
+// virtual
+BOOL LLNotificationWellWindow::postBuild()
+{
+ BOOL rv = LLSysWellWindow::postBuild();
+ setTitle(getString("title_notification_well_window"));
+ return rv;
}
-void LLSysWellWindow::sessionIDUpdated(const LLUUID& old_session_id, const LLUUID& new_session_id)
+// virtual
+void LLNotificationWellWindow::setVisible(BOOL visible)
{
- //for outgoing ad-hoc and group im sessions only
- LLChiclet* chiclet = findIMChiclet(old_session_id);
- if (chiclet)
+ if (visible)
{
- chiclet->setSessionId(new_session_id);
- mMessageList->updateValue(old_session_id, new_session_id);
+ // when Notification channel is cleared, storable toasts will be added into the list.
+ clearScreenChannels();
}
+
+ LLSysWellWindow::setVisible(visible);
}
-void LLSysWellWindow::handleItemAdded(EItemType added_item_type)
+//---------------------------------------------------------------------------------
+void LLNotificationWellWindow::addItem(LLSysWellItem::Params p)
{
- bool should_be_shown = ++mTypedItemsCount[added_item_type] == 1 && anotherTypeExists(added_item_type);
+ LLSD value = p.notification_id;
+ // do not add clones
+ if( mMessageList->getItemByValue(value))
+ return;
- if (should_be_shown && !mSeparator->getVisible())
+ LLSysWellItem* new_item = new LLSysWellItem(p);
+ if (mMessageList->addItem(new_item, value, ADD_TOP))
+ {
+ mSysWellChiclet->updateWidget(isWindowEmpty());
+ reshapeWindow();
+ new_item->setOnItemCloseCallback(boost::bind(&LLNotificationWellWindow::onItemClose, this, _1));
+ new_item->setOnItemClickCallback(boost::bind(&LLNotificationWellWindow::onItemClick, this, _1));
+ }
+ else
{
- mSeparator->setVisible(TRUE);
+ LL_WARNS() << "Unable to add Notification into the list, notification ID: " << p.notification_id
+ << ", title: " << p.title
+ << LL_ENDL;
- // refresh list to recalculate mSeparator position
- mMessageList->reshape(mMessageList->getRect().getWidth(), mMessageList->getRect().getHeight());
+ new_item->die();
}
}
-void LLSysWellWindow::handleItemRemoved(EItemType removed_item_type)
+void LLNotificationWellWindow::closeAll()
{
- bool should_be_hidden = --mTypedItemsCount[removed_item_type] == 0;
-
- if (should_be_hidden && mSeparator->getVisible())
+ // Need to clear notification channel, to add storable toasts into the list.
+ clearScreenChannels();
+ std::vector<LLPanel*> items;
+ mMessageList->getItems(items);
+ for (std::vector<LLPanel*>::iterator
+ iter = items.begin(),
+ iter_end = items.end();
+ iter != iter_end; ++iter)
{
- mSeparator->setVisible(FALSE);
+ LLSysWellItem* sys_well_item = dynamic_cast<LLSysWellItem*>(*iter);
+ if (sys_well_item)
+ onItemClose(sys_well_item);
+ }
+}
- // refresh list to recalculate mSeparator position
- mMessageList->reshape(mMessageList->getRect().getWidth(), mMessageList->getRect().getHeight());
+//////////////////////////////////////////////////////////////////////////
+// PRIVATE METHODS
+void LLNotificationWellWindow::initChannel()
+{
+ LLSysWellWindow::initChannel();
+ if(mChannel)
+ {
+ mChannel->addOnStoreToastCallback(boost::bind(&LLNotificationWellWindow::onStoreToast, this, _1, _2));
}
}
-bool LLSysWellWindow::anotherTypeExists(EItemType item_type)
+void LLNotificationWellWindow::clearScreenChannels()
{
- bool exists = false;
- switch(item_type)
+ // 1 - remove StartUp toast and channel if present
+ if(!LLNotificationsUI::LLScreenChannel::getStartUpToastShown())
{
- case IT_INSTANT_MESSAGE:
- if (mTypedItemsCount[IT_NOTIFICATION] > 0)
- {
- exists = true;
- }
- break;
- case IT_NOTIFICATION:
- if (mTypedItemsCount[IT_INSTANT_MESSAGE] > 0)
- {
- exists = true;
- }
- break;
+ LLNotificationsUI::LLChannelManager::getInstance()->onStartUpToastClose();
+ }
+
+ // 2 - remove toasts in Notification channel
+ if(mChannel)
+ {
+ mChannel->removeAndStoreAllStorableToasts();
}
- return exists;
}
-//---------------------------------------------------------------------------------
-LLSysWellWindow::RowPanel::RowPanel(const LLSysWellWindow* parent, const LLUUID& sessionId,
- S32 chicletCounter, const std::string& name, const LLUUID& otherParticipantId) :
- LLPanel(LLPanel::Params()), mChiclet(NULL), mParent(parent)
+void LLNotificationWellWindow::onStoreToast(LLPanel* info_panel, LLUUID id)
{
- LLUICtrlFactory::getInstance()->buildPanel(this, "panel_activeim_row.xml", NULL);
+ LLSysWellItem::Params p;
+ p.notification_id = id;
+ p.title = static_cast<LLToastPanel*>(info_panel)->getTitle();
+ addItem(p);
+}
- // Choose which of the pre-created chiclets (IM/group) to use.
- // The other one gets hidden.
+void LLNotificationWellWindow::onItemClick(LLSysWellItem* item)
+{
+ LLUUID id = item->getID();
+ LLFloaterReg::showInstance("inspect_toast", id);
+}
- LLIMChiclet::EType im_chiclet_type = LLIMChiclet::getIMSessionType(sessionId);
- switch (im_chiclet_type)
+void LLNotificationWellWindow::onItemClose(LLSysWellItem* item)
+{
+ LLUUID id = item->getID();
+
+ if(mChannel)
{
- case LLIMChiclet::TYPE_GROUP:
- case LLIMChiclet::TYPE_AD_HOC:
- mChiclet = getChild<LLIMChiclet>("group_chiclet");
- childSetVisible("p2p_chiclet", false);
- break;
- case LLIMChiclet::TYPE_UNKNOWN: // assign mChiclet a non-null value anyway
- case LLIMChiclet::TYPE_IM:
- mChiclet = getChild<LLIMChiclet>("p2p_chiclet");
- childSetVisible("group_chiclet", false);
- break;
+ // 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());
+}
- // Initialize chiclet.
- mChiclet->setCounter(chicletCounter);
- mChiclet->setSessionId(sessionId);
- mChiclet->setIMSessionName(name);
- mChiclet->setOtherParticipantId(otherParticipantId);
+/************************************************************************/
+/* LLIMWellWindow implementation */
+/************************************************************************/
- LLTextBox* contactName = getChild<LLTextBox>("contact_name");
- contactName->setValue(name);
+//////////////////////////////////////////////////////////////////////////
+// PUBLIC METHODS
+LLIMWellWindow::LLIMWellWindow(const LLSD& key)
+: LLSysWellWindow(key)
+{
+}
- mCloseBtn = getChild<LLButton>("hide_btn");
- mCloseBtn->setCommitCallback(boost::bind(&LLSysWellWindow::RowPanel::onClosePanel, this));
+LLIMWellWindow::~LLIMWellWindow()
+{
}
-//---------------------------------------------------------------------------------
-LLSysWellWindow::RowPanel::~RowPanel()
+// static
+LLIMWellWindow* LLIMWellWindow::getInstance(const LLSD& key /*= LLSD()*/)
{
+ return LLFloaterReg::getTypedInstance<LLIMWellWindow>("im_well_window", key);
}
-//---------------------------------------------------------------------------------
-void LLSysWellWindow::RowPanel::onClosePanel()
+
+// static
+LLIMWellWindow* LLIMWellWindow::findInstance(const LLSD& key /*= LLSD()*/)
{
- gIMMgr->removeSession(mChiclet->getSessionId());
- // This row panel will be removed from the list in LLSysWellWindow::sessionRemoved().
+ return LLFloaterReg::findTypedInstance<LLIMWellWindow>("im_well_window", key);
}
-//---------------------------------------------------------------------------------
-void LLSysWellWindow::RowPanel::onMouseEnter(S32 x, S32 y, MASK mask)
+BOOL LLIMWellWindow::postBuild()
{
- setTransparentColor(LLUIColorTable::instance().getColor("SysWellItemSelected"));
+ BOOL rv = LLSysWellWindow::postBuild();
+ setTitle(getString("title_im_well_window"));
+
+ LLIMChiclet::sFindChicletsSignal.connect(boost::bind(&LLIMWellWindow::findObjectChiclet, this, _1));
+
+ return rv;
}
-//---------------------------------------------------------------------------------
-void LLSysWellWindow::RowPanel::onMouseLeave(S32 x, S32 y, MASK mask)
+LLChiclet* LLIMWellWindow::findObjectChiclet(const LLUUID& notification_id)
{
- setTransparentColor(LLUIColorTable::instance().getColor("SysWellItemUnselected"));
+ if (!mMessageList) return NULL;
+
+ LLChiclet* res = NULL;
+ ObjectRowPanel* panel = mMessageList->getTypedItemByValue<ObjectRowPanel>(notification_id);
+ if (panel != NULL)
+ {
+ res = panel->mChiclet;
+ }
+
+ return res;
}
-//---------------------------------------------------------------------------------
-// virtual
-BOOL LLSysWellWindow::RowPanel::handleMouseDown(S32 x, S32 y, MASK mask)
+//////////////////////////////////////////////////////////////////////////
+// PRIVATE METHODS
+
+void LLIMWellWindow::addObjectRow(const LLUUID& notification_id, bool new_message/* = false*/)
{
- // Pass the mouse down event to the chiclet (EXT-596).
- if (!mChiclet->pointInView(x, y) && !mCloseBtn->getRect().pointInRect(x, y)) // prevent double call of LLIMChiclet::onMouseDown()
- mChiclet->onMouseDown();
+ if (mMessageList->getItemByValue(notification_id) == NULL)
+ {
+ ObjectRowPanel* item = new ObjectRowPanel(notification_id, new_message);
+ if (!mMessageList->addItem(item, notification_id))
+ {
+ LL_WARNS() << "Unable to add Object Row into the list, notificationID: " << notification_id << LL_ENDL;
+ item->die();
+ }
+ reshapeWindow();
+ }
+}
- return LLPanel::handleMouseDown(x, y, mask);
+void LLIMWellWindow::removeObjectRow(const LLUUID& notification_id)
+{
+ if (!mMessageList->removeItemByValue(notification_id))
+ {
+ LL_WARNS() << "Unable to remove Object Row from the list, notificationID: " << notification_id << LL_ENDL;
+ }
+
+ reshapeWindow();
+ // hide chiclet window if there are no items left
+ if(isWindowEmpty())
+ {
+ setVisible(FALSE);
+ }
+}
+
+void LLIMWellWindow::closeAll()
+{
+ // Generate an ignorable alert dialog if there is an active voice IM sesion
+ bool need_confirmation = false;
+ const LLIMModel& im_model = LLIMModel::instance();
+ std::vector<LLSD> values;
+ mMessageList->getValues(values);
+ for (std::vector<LLSD>::iterator
+ iter = values.begin(),
+ iter_end = values.end();
+ iter != iter_end; ++iter)
+ {
+ LLIMSpeakerMgr* speaker_mgr = im_model.getSpeakerManager(*iter);
+ if (speaker_mgr && speaker_mgr->isVoiceActive())
+ {
+ need_confirmation = true;
+ break;
+ }
+ }
+ if ( need_confirmation )
+ {
+ //Bring up a confirmation dialog
+ LLNotificationsUtil::add
+ ("ConfirmCloseAll", LLSD(), LLSD(),
+ boost::bind(&LLIMWellWindow::confirmCloseAll, this, _1, _2));
+ }
+ else
+ {
+ closeAllImpl();
+ }
+}
+
+void LLIMWellWindow::closeAllImpl()
+{
+ std::vector<LLSD> values;
+ mMessageList->getValues(values);
+
+ for (std::vector<LLSD>::iterator
+ iter = values.begin(),
+ iter_end = values.end();
+ iter != iter_end; ++iter)
+ {
+ LLPanel* panel = mMessageList->getItemByValue(*iter);
+
+ ObjectRowPanel* obj_panel = dynamic_cast <ObjectRowPanel*> (panel);
+ if (obj_panel)
+ {
+ LLScriptFloaterManager::instance().removeNotification(*iter);
+ }
+ }
}
-// EOF
+bool LLIMWellWindow::confirmCloseAll(const LLSD& notification, const LLSD& response)
+{
+ S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
+ switch(option)
+ {
+ case 0:
+ {
+ closeAllImpl();
+ return true;
+ }
+ default:
+ break;
+ }
+ return false;
+}
+
+