summaryrefslogtreecommitdiff
path: root/indra
diff options
context:
space:
mode:
Diffstat (limited to 'indra')
-rw-r--r--indra/llinventory/llinventory.h2
-rw-r--r--indra/llrender/llfontregistry.cpp2
-rw-r--r--indra/llui/CMakeLists.txt4
-rw-r--r--indra/llui/llbutton.cpp19
-rw-r--r--indra/llui/lldockablefloater.cpp86
-rw-r--r--indra/llui/lldockablefloater.h65
-rw-r--r--indra/llui/lldockcontrol.cpp126
-rw-r--r--indra/llui/lldockcontrol.h81
-rw-r--r--indra/llui/llscrolllistctrl.cpp35
-rw-r--r--indra/llui/llscrolllistctrl.h10
-rw-r--r--indra/llui/lltextbox.cpp5
-rw-r--r--indra/llui/lltexteditor.cpp7
-rw-r--r--indra/llui/llview.cpp4
-rw-r--r--indra/llui/llview.h2
-rw-r--r--indra/newview/CMakeLists.txt8
-rw-r--r--indra/newview/app_settings/settings.xml17
-rw-r--r--indra/newview/llagent.cpp1
-rw-r--r--indra/newview/llavatarlist.cpp3
-rw-r--r--indra/newview/llbottomtray.cpp54
-rw-r--r--indra/newview/llbottomtray.h13
-rw-r--r--indra/newview/llchiclet.cpp6
-rw-r--r--indra/newview/llchiclet.h1
-rw-r--r--indra/newview/llfavoritesbar.cpp349
-rw-r--r--indra/newview/llfavoritesbar.h49
-rw-r--r--indra/newview/llfloaterchat.cpp4
-rw-r--r--indra/newview/llfloaterpreference.cpp6
-rw-r--r--indra/newview/llfriendcard.cpp13
-rw-r--r--indra/newview/llfriendcard.h5
-rw-r--r--indra/newview/llinventorybridge.cpp10
-rw-r--r--indra/newview/lllocationhistory.cpp78
-rw-r--r--indra/newview/lllocationhistory.h77
-rw-r--r--indra/newview/lllocationinputctrl.cpp72
-rw-r--r--indra/newview/lllocationinputctrl.h2
-rw-r--r--indra/newview/llnavigationbar.cpp204
-rw-r--r--indra/newview/llnavigationbar.h15
-rw-r--r--indra/newview/llpanelavatar.cpp4
-rw-r--r--indra/newview/llpanelavatar.h2
-rw-r--r--indra/newview/llpanelblockedlist.cpp279
-rw-r--r--indra/newview/llpanelblockedlist.h115
-rw-r--r--indra/newview/llpanelpeople.cpp3
-rw-r--r--indra/newview/llpanelpicks.cpp100
-rw-r--r--indra/newview/llpanelpicks.h5
-rw-r--r--indra/newview/llpanelplaceinfo.cpp262
-rw-r--r--indra/newview/llpanelplaceinfo.h30
-rw-r--r--indra/newview/llpanelplaces.cpp11
-rw-r--r--indra/newview/llpanelteleporthistory.cpp26
-rw-r--r--indra/newview/llpanelteleporthistory.h4
-rw-r--r--indra/newview/llscreenchannel.cpp9
-rw-r--r--indra/newview/llsearchcombobox.cpp250
-rw-r--r--indra/newview/llsearchcombobox.h108
-rw-r--r--indra/newview/llsearchhistory.cpp154
-rw-r--r--indra/newview/llsearchhistory.h138
-rw-r--r--indra/newview/llsidetray.cpp7
-rw-r--r--indra/newview/llstartup.cpp4
-rw-r--r--indra/newview/llsyswellwindow.cpp57
-rw-r--r--indra/newview/llsyswellwindow.h8
-rw-r--r--indra/newview/llteleporthistorystorage.cpp98
-rw-r--r--indra/newview/llteleporthistorystorage.h35
-rw-r--r--indra/newview/lltoast.h4
-rw-r--r--indra/newview/lltoastgroupnotifypanel.cpp61
-rw-r--r--indra/newview/lltoastgroupnotifypanel.h2
-rw-r--r--indra/newview/lltoastimpanel.cpp28
-rw-r--r--indra/newview/lltoastimpanel.h5
-rw-r--r--indra/newview/lltoastpanel.cpp31
-rw-r--r--indra/newview/lltoastpanel.h2
-rw-r--r--indra/newview/lltoolbar.cpp11
-rw-r--r--indra/newview/llviewerfloaterreg.cpp5
-rw-r--r--indra/newview/llviewerinventory.cpp100
-rw-r--r--indra/newview/llviewerinventory.h7
-rw-r--r--indra/newview/llviewermenu.cpp4
-rw-r--r--indra/newview/llviewermessage.cpp10
-rw-r--r--indra/newview/llviewerwindow.cpp13
-rw-r--r--indra/newview/skins/default/textures/textures.xml1
-rw-r--r--indra/newview/skins/default/xui/en/menu_people_friends_view_sort.xml4
-rw-r--r--indra/newview/skins/default/xui/en/menu_people_nearby_view_sort.xml4
-rw-r--r--indra/newview/skins/default/xui/en/menu_people_recent_view_sort.xml4
-rw-r--r--indra/newview/skins/default/xui/en/panel_block_list_sidetray.xml84
-rw-r--r--indra/newview/skins/default/xui/en/panel_bottomtray.xml2
-rw-r--r--indra/newview/skins/default/xui/en/panel_edit_profile.xml38
-rw-r--r--indra/newview/skins/default/xui/en/panel_group_notify.xml80
-rw-r--r--indra/newview/skins/default/xui/en/panel_instant_message.xml6
-rw-r--r--indra/newview/skins/default/xui/en/panel_navigation_bar.xml13
-rw-r--r--indra/newview/skins/default/xui/en/panel_pick_list_item.xml20
-rw-r--r--indra/newview/skins/default/xui/en/panel_side_tray.xml7
-rw-r--r--indra/newview/skins/default/xui/en/widgets/accordion_tab.xml6
-rw-r--r--indra/newview/skins/default/xui/en/widgets/list.xml1
-rw-r--r--indra/newview/skins/default/xui/en/widgets/location_input.xml2
-rw-r--r--indra/newview/skins/default/xui/en/widgets/search_combo_box.xml26
88 files changed, 3184 insertions, 541 deletions
diff --git a/indra/llinventory/llinventory.h b/indra/llinventory/llinventory.h
index 2b4d8ed831..64af6c94f5 100644
--- a/indra/llinventory/llinventory.h
+++ b/indra/llinventory/llinventory.h
@@ -100,7 +100,7 @@ public:
BOOL getIsLinkType() const;
// mutators - will not call updateServer();
void setUUID(const LLUUID& new_uuid);
- void rename(const std::string& new_name);
+ virtual void rename(const std::string& new_name);
void setParent(const LLUUID& new_parent);
void setType(LLAssetType::EType type);
diff --git a/indra/llrender/llfontregistry.cpp b/indra/llrender/llfontregistry.cpp
index 99f364a589..45573cd817 100644
--- a/indra/llrender/llfontregistry.cpp
+++ b/indra/llrender/llfontregistry.cpp
@@ -105,7 +105,7 @@ bool removeSubString(std::string& str, const std::string& substr)
size_t pos = str.find(substr);
if (pos != string::npos)
{
- str.erase(pos);
+ str.erase(pos, substr.size());
return true;
}
return false;
diff --git a/indra/llui/CMakeLists.txt b/indra/llui/CMakeLists.txt
index 790f2d5729..95d693cdc4 100644
--- a/indra/llui/CMakeLists.txt
+++ b/indra/llui/CMakeLists.txt
@@ -34,6 +34,8 @@ set(llui_SOURCE_FILES
llconsole.cpp
llcontainerview.cpp
llctrlselectioninterface.cpp
+ lldockablefloater.cpp
+ lldockcontrol.cpp
lldraghandle.cpp
lleditmenuhandler.cpp
llf32uictrl.cpp
@@ -113,6 +115,8 @@ set(llui_HEADER_FILES
llcontainerview.h
llctrlselectioninterface.h
lldraghandle.h
+ lldockablefloater.h
+ lldockcontrol.h
lleditmenuhandler.h
llf32uictrl.h
llfiltereditor.h
diff --git a/indra/llui/llbutton.cpp b/indra/llui/llbutton.cpp
index 98e8c9a988..bf58e19949 100644
--- a/indra/llui/llbutton.cpp
+++ b/indra/llui/llbutton.cpp
@@ -355,11 +355,19 @@ BOOL LLButton::handleMouseDown(S32 x, S32 y, MASK mask)
setFocus(TRUE);
}
+ /*
+ * ATTENTION! This call fires another mouse down callback.
+ * If you wish to remove this call emit that signal directly
+ * by calling LLUICtrl::mMouseDownSignal(x, y, mask);
+ */
+ LLUICtrl::handleMouseDown(x, y, mask);
+
mMouseDownSignal(this, LLSD());
mMouseDownTimer.start();
mMouseDownFrame = (S32) LLFrameTimer::getFrameCount();
mMouseHeldDownCount = 0;
+
if (getSoundFlags() & MOUSE_DOWN)
{
@@ -378,6 +386,13 @@ BOOL LLButton::handleMouseUp(S32 x, S32 y, MASK mask)
// Always release the mouse
gFocusMgr.setMouseCapture( NULL );
+ /*
+ * ATTENTION! This call fires another mouse up callback.
+ * If you wish to remove this call emit that signal directly
+ * by calling LLUICtrl::mMouseUpSignal(x, y, mask);
+ */
+ LLUICtrl::handleMouseUp(x, y, mask);
+
// Regardless of where mouseup occurs, handle callback
mMouseUpSignal(this, LLSD());
@@ -460,12 +475,16 @@ BOOL LLButton::handleRightMouseUp(S32 x, S32 y, MASK mask)
void LLButton::onMouseEnter(S32 x, S32 y, MASK mask)
{
+ LLUICtrl::onMouseEnter(x, y, mask);
+
if (isInEnabledChain())
mNeedsHighlight = TRUE;
}
void LLButton::onMouseLeave(S32 x, S32 y, MASK mask)
{
+ LLUICtrl::onMouseLeave(x, y, mask);
+
mNeedsHighlight = FALSE;
}
diff --git a/indra/llui/lldockablefloater.cpp b/indra/llui/lldockablefloater.cpp
new file mode 100644
index 0000000000..d0789d6502
--- /dev/null
+++ b/indra/llui/lldockablefloater.cpp
@@ -0,0 +1,86 @@
+/**
+ * @file lldockablefloater.cpp
+ * @brief Creates a panel of a specific kind for a toast
+ *
+ * $LicenseInfo:firstyear=2000&license=viewergpl$
+ *
+ * Copyright (c) 2000-2009, Linden Research, Inc.
+ *
+ * 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
+ *
+ * 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
+ *
+ * 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.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#include "linden_common.h"
+
+#include "lldockablefloater.h"
+
+LLDockableFloater::LLDockableFloater(LLDockControl* dockControl,
+ const LLSD& key, const Params& params) :
+ LLFloater(key, params), mDockControl(dockControl)
+{
+}
+
+LLDockableFloater::~LLDockableFloater()
+{
+}
+
+BOOL LLDockableFloater::postBuild()
+{
+ mDockTongue = LLUI::getUIImage("windows/Flyout_Pointer.png");
+ LLFloater::setDocked(true);
+ return LLView::postBuild();
+}
+
+void LLDockableFloater::setDocked(bool docked, bool pop_on_undock)
+{
+ if (docked)
+ {
+ mDockControl.get()->on();
+ }
+ else
+ {
+ mDockControl.get()->off();
+ }
+ LLFloater::setDocked(docked, pop_on_undock);
+}
+
+void LLDockableFloater::draw()
+{
+ mDockControl.get()->repositionDockable();
+ mDockControl.get()->drawToungue();
+ LLFloater::draw();
+}
+
+void LLDockableFloater::setDockControl(LLDockControl* dockControl)
+{
+ mDockControl.reset(dockControl);
+}
+const LLUIImagePtr& LLDockableFloater::getDockTongue()
+{
+ return mDockTongue;
+}
+
+LLDockControl* LLDockableFloater::getDockControl()
+{
+ return mDockControl.get();
+}
diff --git a/indra/llui/lldockablefloater.h b/indra/llui/lldockablefloater.h
new file mode 100644
index 0000000000..5ece78a925
--- /dev/null
+++ b/indra/llui/lldockablefloater.h
@@ -0,0 +1,65 @@
+/**
+ * @file lldockablefloater.h
+ * @brief Creates a panel of a specific kind for a toast.
+ *
+ * $LicenseInfo:firstyear=2003&license=viewergpl$
+ *
+ * Copyright (c) 2003-2009, Linden Research, Inc.
+ *
+ * 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
+ *
+ * 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
+ *
+ * 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.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_DOCKABLEFLOATER_H
+#define LL_DOCKABLEFLOATER_H
+
+#include "llerror.h"
+#include "llfloater.h"
+#include "lldockcontrol.h"
+
+/**
+ * Represents floater that can dock.
+ * In case impossibility deriving from LLDockableFloater use LLDockControl.
+ */
+class LLDockableFloater : public LLFloater
+{
+public:
+ LOG_CLASS(LLDockableFloater);
+ LLDockableFloater(LLDockControl* dockControl, const LLSD& key, const Params& params = getDefaultParams());
+ virtual ~LLDockableFloater();
+
+ /* virtula */BOOL postBuild();
+ /* virtual */void setDocked(bool docked, bool pop_on_undock = true);
+ /* virtual */void draw();
+
+protected:
+ void setDockControl(LLDockControl* dockControl);
+ LLDockControl* getDockControl();
+ const LLUIImagePtr& getDockTongue();
+
+private:
+ std::auto_ptr<LLDockControl> mDockControl;
+ LLUIImagePtr mDockTongue;
+};
+
+#endif /* LL_DOCKABLEFLOATER_H */
diff --git a/indra/llui/lldockcontrol.cpp b/indra/llui/lldockcontrol.cpp
new file mode 100644
index 0000000000..bec7f04cc0
--- /dev/null
+++ b/indra/llui/lldockcontrol.cpp
@@ -0,0 +1,126 @@
+/**
+ * @file lldockcontrol.cpp
+ * @brief Creates a panel of a specific kind for a toast
+ *
+ * $LicenseInfo:firstyear=2000&license=viewergpl$
+ *
+ * Copyright (c) 2000-2009, Linden Research, Inc.
+ *
+ * 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
+ *
+ * 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
+ *
+ * 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.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#include "linden_common.h"
+
+#include "lldockcontrol.h"
+
+LLDockControl::LLDockControl(LLView* dockWidget, LLFloater* dockableFloater,
+ const LLUIImagePtr& dockTongue, DocAt dockAt, bool enabled) :
+ mDockWidget(dockWidget), mDockableFloater(dockableFloater), mDockTongue(
+ dockTongue)
+{
+ mDockAt = dockAt;
+ if (enabled)
+ {
+ on();
+ }
+ else
+ {
+ off();
+ }
+}
+
+LLDockControl::~LLDockControl()
+{
+}
+
+void LLDockControl::repositionDockable()
+{
+ if (mEnabled)
+ {
+ calculateDockablePosition();
+ }
+}
+
+void LLDockControl::calculateDockablePosition()
+{
+ LLRect dockRect = mDockWidget->calcScreenRect();
+ if (mPrevDockRect != dockRect || mRecalculateDocablePosition)
+ {
+ LLRect dockableRect = mDockableFloater->calcScreenRect();
+ LLRect rootRect = mDockableFloater->getRootView()->getRect();
+
+ S32 x = 0;
+ S32 y = 0;
+ switch (mDockAt)
+ {
+ case TOP:
+ x = dockRect.getCenterX() - dockableRect.getWidth() / 2;
+ y = dockRect.mTop + mDockTongue->getHeight()
+ + dockableRect.getHeight();
+ if (x < rootRect.mLeft)
+ {
+ x = rootRect.mLeft;
+ }
+ if (x + dockableRect.getWidth() > rootRect.mRight)
+ {
+ x = rootRect.mRight - dockableRect.getWidth();
+ }
+ mDockTongueX = dockRect.getCenterX() - mDockTongue->getWidth() / 2;
+ mDockTongueY = dockRect.mTop;
+ break;
+ }
+ dockableRect.setLeftTopAndSize(x, y, dockableRect.getWidth(),
+ dockableRect.getHeight());
+ LLRect localDocableParentRect;
+ mDockableFloater->getParent()->screenRectToLocal(dockableRect,
+ &localDocableParentRect);
+ mDockableFloater->setRect(localDocableParentRect);
+
+ mDockableFloater->screenPointToLocal(mDockTongueX, mDockTongueY,
+ &mDockTongueX, &mDockTongueY);
+ mPrevDockRect = dockRect;
+ mRecalculateDocablePosition = false;
+ }
+}
+
+void LLDockControl::on()
+{
+ mDockableFloater->setCanDrag(false);
+ mEnabled = true;
+ mRecalculateDocablePosition = true;
+}
+
+void LLDockControl::off()
+{
+ mDockableFloater->setCanDrag(true);
+ mEnabled = false;
+}
+
+void LLDockControl::drawToungue()
+{
+ if (mEnabled)
+ {
+ mDockTongue->draw(mDockTongueX, mDockTongueY);
+ }
+}
diff --git a/indra/llui/lldockcontrol.h b/indra/llui/lldockcontrol.h
new file mode 100644
index 0000000000..0e1f4c8e64
--- /dev/null
+++ b/indra/llui/lldockcontrol.h
@@ -0,0 +1,81 @@
+/**
+ * @file lldockcontrol.h
+ * @brief Creates a panel of a specific kind for a toast.
+ *
+ * $LicenseInfo:firstyear=2003&license=viewergpl$
+ *
+ * Copyright (c) 2003-2009, Linden Research, Inc.
+ *
+ * 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
+ *
+ * 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
+ *
+ * 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.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_DOCKCONTROL_H
+#define LL_DOCKCONTROL_H
+
+#include "llerror.h"
+#include "llview.h"
+#include "llfloater.h"
+#include "lluiimage.h"
+
+/**
+ * Provides services for docking of specified floater.
+ * This class should be used in case impossibility deriving from LLDockableFloater.
+ */
+class LLDockControl
+{
+public:
+ enum DocAt
+ {
+ TOP
+ };
+
+public:
+ LOG_CLASS(LLDockControl);
+ LLDockControl(LLView* dockWidget, LLFloater* dockableFloater,
+ const LLUIImagePtr& dockTongue, DocAt dockAt,
+ bool enabled);
+ virtual ~LLDockControl();
+
+public:
+ void on();
+ void off();
+ void setDock(LLView* dockWidget)
+ { mDockWidget = dockWidget;};
+ void repositionDockable();
+ void drawToungue();
+protected:
+ virtual void calculateDockablePosition();
+private:
+ bool mEnabled;
+ bool mRecalculateDocablePosition;
+ DocAt mDockAt;
+ LLView* mDockWidget;
+ LLRect mPrevDockRect;
+ LLFloater* mDockableFloater;
+ LLUIImagePtr mDockTongue;
+ S32 mDockTongueX;
+ S32 mDockTongueY;
+};
+
+#endif /* LL_DOCKCONTROL_H */
diff --git a/indra/llui/llscrolllistctrl.cpp b/indra/llui/llscrolllistctrl.cpp
index b9a253aac8..36a3b007b6 100644
--- a/indra/llui/llscrolllistctrl.cpp
+++ b/indra/llui/llscrolllistctrl.cpp
@@ -123,6 +123,7 @@ LLScrollListCtrl::Params::Params()
sort_ascending("sort_ascending", true),
commit_on_keyboard_movement("commit_on_keyboard_movement", true),
heading_height("heading_height"),
+ page_lines("page_lines", 0),
background_visible("background_visible"),
draw_stripes("draw_stripes"),
column_padding("column_padding"),
@@ -145,7 +146,7 @@ LLScrollListCtrl::LLScrollListCtrl(const LLScrollListCtrl::Params& p)
: LLUICtrl(p),
mLineHeight(0),
mScrollLines(0),
- mPageLines(0),
+ mPageLines(p.page_lines),
mMaxSelectable(0),
mAllowKeyboardMovement(TRUE),
mCommitOnKeyboardMovement(p.commit_on_keyboard_movement),
@@ -196,8 +197,6 @@ LLScrollListCtrl::LLScrollListCtrl(const LLScrollListCtrl::Params& p)
updateLineHeight();
- mPageLines = mLineHeight? (mItemListRect.getHeight()) / mLineHeight : 0;
-
// Init the scrollbar
static LLUICachedControl<S32> scrollbar_size ("UIScrollbarSize", 0);
@@ -214,7 +213,7 @@ LLScrollListCtrl::LLScrollListCtrl(const LLScrollListCtrl::Params& p)
sbparams.orientation(LLScrollbar::VERTICAL);
sbparams.doc_size(getItemCount());
sbparams.doc_pos(mScrollLines);
- sbparams.page_size(mPageLines);
+ sbparams.page_size( mPageLines ? mPageLines : getItemCount() );
sbparams.change_callback(boost::bind(&LLScrollListCtrl::onScrollChange, this, _1, _2));
sbparams.follows.flags(FOLLOWS_RIGHT | FOLLOWS_TOP | FOLLOWS_BOTTOM);
sbparams.visible(false);
@@ -469,8 +468,12 @@ void LLScrollListCtrl::updateLayout()
getChildView("comment_text")->setShape(mItemListRect);
// how many lines of content in a single "page"
- mPageLines = mLineHeight? mItemListRect.getHeight() / mLineHeight : 0;
- BOOL scrollbar_visible = getItemCount() > mPageLines;
+ S32 page_lines = mLineHeight? mItemListRect.getHeight() / mLineHeight : getItemCount();
+ //if mPageLines is NOT provided display all item
+ if(mPageLines)
+ page_lines = mPageLines;
+
+ BOOL scrollbar_visible = mLineHeight * getItemCount() > mItemListRect.getHeight();
if (scrollbar_visible)
{
// provide space on the right for scrollbar
@@ -479,7 +482,7 @@ void LLScrollListCtrl::updateLayout()
mScrollbar->setOrigin(getRect().getWidth() - mBorderThickness - scrollbar_size, mItemListRect.mBottom);
mScrollbar->reshape(scrollbar_size, mItemListRect.getHeight() + (mDisplayColumnHeaders ? mHeadingHeight : 0));
- mScrollbar->setPageSize( mPageLines );
+ mScrollbar->setPageSize(page_lines);
mScrollbar->setDocSize( getItemCount() );
mScrollbar->setVisible(scrollbar_visible);
@@ -491,6 +494,9 @@ void LLScrollListCtrl::updateLayout()
void LLScrollListCtrl::fitContents(S32 max_width, S32 max_height)
{
S32 height = llmin( getRequiredRect().getHeight(), max_height );
+ if(mPageLines)
+ height = llmin( mPageLines * mLineHeight + (mDisplayColumnHeaders ? mHeadingHeight : 0), height );
+
S32 width = getRect().getWidth();
reshape( width, height );
@@ -721,6 +727,12 @@ void LLScrollListCtrl::setHeadingHeight(S32 heading_height)
updateLayout();
}
+void LLScrollListCtrl::setPageLines(S32 new_page_lines)
+{
+ mPageLines = new_page_lines;
+
+ updateLayout();
+}
BOOL LLScrollListCtrl::selectFirstItem()
{
@@ -1367,7 +1379,7 @@ void LLScrollListCtrl::drawItems()
S32 y = mItemListRect.mTop - mLineHeight;
// allow for partial line at bottom
- S32 num_page_lines = mPageLines + 1;
+ S32 num_page_lines = (mPageLines)? mPageLines : getItemCount() + 1;
LLRect item_rect;
@@ -1856,7 +1868,7 @@ LLScrollListItem* LLScrollListCtrl::hitItem( S32 x, S32 y )
mLineHeight );
// allow for partial line at bottom
- S32 num_page_lines = mPageLines + 1;
+ S32 num_page_lines = (mPageLines)? mPageLines : getItemCount() + 1;
S32 line = 0;
item_list::iterator iter;
@@ -2421,7 +2433,8 @@ void LLScrollListCtrl::scrollToShowSelected()
}
S32 lowest = mScrollLines;
- S32 highest = mScrollLines + mPageLines;
+ S32 page_lines = (mPageLines)? mPageLines : getItemCount();
+ S32 highest = mScrollLines + page_lines;
if (index < lowest)
{
@@ -2430,7 +2443,7 @@ void LLScrollListCtrl::scrollToShowSelected()
}
else if (highest <= index)
{
- setScrollPos(index - mPageLines + 1);
+ setScrollPos(index - page_lines + 1);
}
}
diff --git a/indra/llui/llscrolllistctrl.h b/indra/llui/llscrolllistctrl.h
index 7a7e5be0be..5c18f85160 100644
--- a/indra/llui/llscrolllistctrl.h
+++ b/indra/llui/llscrolllistctrl.h
@@ -87,6 +87,7 @@ public:
// layout
Optional<S32> column_padding,
+ page_lines,
heading_height;
// sort and search behavior
@@ -314,6 +315,11 @@ public:
S32 getMaxContentWidth() { return mMaxContentWidth; }
void setHeadingHeight(S32 heading_height);
+ /**
+ * Sets max visible lines without scroolbar, if this value equals to 0,
+ * then display all items.
+ */
+ void setPageLines(S32 page_lines );
void setCollapseEmptyColumns(BOOL collapse);
LLScrollListItem* hitItem(S32 x,S32 y);
@@ -368,11 +374,13 @@ protected:
typedef std::deque<LLScrollListItem *> item_list;
item_list& getItemList() { return mItemList; }
+ void updateLineHeight();
+
private:
void selectPrevItem(BOOL extend_selection);
void selectNextItem(BOOL extend_selection);
void drawItems();
- void updateLineHeight();
+
void updateLineHeightInsert(LLScrollListItem* item);
void reportInvalidInput();
BOOL isRepeatedChars(const LLWString& string) const;
diff --git a/indra/llui/lltextbox.cpp b/indra/llui/lltextbox.cpp
index 7a92bfb74c..30bf182deb 100644
--- a/indra/llui/lltextbox.cpp
+++ b/indra/llui/lltextbox.cpp
@@ -481,7 +481,10 @@ void LLTextBox::drawText( S32 x, S32 y, const LLWString &text, const LLColor4& c
mShadowType,
line_length, getRect().getWidth(), NULL, mUseEllipses );
cur_pos += line_length + 1;
- y -= llfloor(mDefaultFont->getLineHeight()) + mLineSpacing;
+ S32 line_height = llfloor(mDefaultFont->getLineHeight()) + mLineSpacing;
+ y -= line_height;
+ if(y < line_height)
+ break;
}
}
}
diff --git a/indra/llui/lltexteditor.cpp b/indra/llui/lltexteditor.cpp
index 296ccea0e4..51c259ff53 100644
--- a/indra/llui/lltexteditor.cpp
+++ b/indra/llui/lltexteditor.cpp
@@ -3412,11 +3412,8 @@ void LLTextEditor::endOfDoc()
// Sets the scrollbar from the cursor position
void LLTextEditor::updateScrollFromCursor()
{
- if (mReadOnly)
- {
- // no cursor in read only mode
- return;
- }
+ // Update scroll position even in read-only mode (when there's no cursor displayed)
+ // because startOfDoc()/endOfDoc() modify cursor position. See EXT-736.
if (!mScrollNeeded)
{
diff --git a/indra/llui/llview.cpp b/indra/llui/llview.cpp
index 83d45f0dfa..55d94b325f 100644
--- a/indra/llui/llview.cpp
+++ b/indra/llui/llview.cpp
@@ -2741,11 +2741,11 @@ void LLView::notifyParent(const LLSD& info)
if(parent)
parent->notifyParent(info);
}
-void LLView::notifyChilds(const LLSD& info)
+void LLView::notifyChildren(const LLSD& info)
{
for ( child_list_iter_t child_it = mChildList.begin(); child_it != mChildList.end(); ++child_it)
{
- (*child_it)->notifyChilds(info);
+ (*child_it)->notifyChildren(info);
}
}
diff --git a/indra/llui/llview.h b/indra/llui/llview.h
index 87298b5292..1d48378081 100644
--- a/indra/llui/llview.h
+++ b/indra/llui/llview.h
@@ -550,7 +550,7 @@ public:
virtual void handleReshape(const LLRect& rect, bool by_user);
virtual void notifyParent(const LLSD& info);
- virtual void notifyChilds(const LLSD& info);
+ virtual void notifyChildren(const LLSD& info);
protected:
void drawDebugRect();
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index 05459cfcac..f4194ed511 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -180,7 +180,6 @@ set(viewer_SOURCE_FILES
llfloaterlandholdings.cpp
llfloatermap.cpp
llfloatermemleak.cpp
- llfloatermute.cpp
llfloaternamedesc.cpp
llfloaternotificationsconsole.cpp
llfloateropenobject.cpp
@@ -286,6 +285,7 @@ set(viewer_SOURCE_FILES
llpanelavatar.cpp
llpanelavatarrow.cpp
llpanelavatartag.cpp
+ llpanelblockedlist.cpp
llpanelclassified.cpp
llpanelcontents.cpp
llpaneldirbrowser.cpp
@@ -348,6 +348,8 @@ set(viewer_SOURCE_FILES
llremoteparcelrequest.cpp
llsavedsettingsglue.cpp
llscreenchannel.cpp
+ llsearchcombobox.cpp
+ llsearchhistory.cpp
llselectmgr.cpp
llsidetray.cpp
llsidetraypanelcontainer.cpp
@@ -634,7 +636,6 @@ set(viewer_HEADER_FILES
llfloaterlandholdings.h
llfloatermap.h
llfloatermemleak.h
- llfloatermute.h
llfloaternamedesc.h
llfloaternotificationsconsole.h
llfloateropenobject.h
@@ -738,6 +739,7 @@ set(viewer_HEADER_FILES
llpanelavatar.h
llpanelavatarrow.h
llpanelavatartag.h
+ llpanelblockedlist.h
llpanelclassified.h
llpanelcontents.h
llpaneldirbrowser.h
@@ -802,6 +804,8 @@ set(viewer_HEADER_FILES
llrootview.h
llscreenchannel.h
llsavedsettingsglue.h
+ llsearchcombobox.h
+ llsearchhistory.h
llselectmgr.h
llsidetray.h
llsidetraypanelcontainer.h
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index e88bc5a91f..32b1443157 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -6866,10 +6866,10 @@
<key>Value</key>
<integer>0</integer>
</map>
- <key>ShowPGSearchAll</key>
+ <key>ShowCameraAndMoveControls</key>
<map>
<key>Comment</key>
- <string>Show/Hide Navigation Bar Favorites Panel</string>
+ <string>Show/Hide Camera and Move controls in the bottom tray</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
@@ -6880,7 +6880,7 @@
<key>ShowNavbarFavoritesPanel</key>
<map>
<key>Comment</key>
- <string>Show/Hide Navigation Bar Navigation Panel</string>
+ <string>Show/Hide Navigation Bar Favorites Panel</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
@@ -6891,6 +6891,17 @@
<key>ShowNavbarNavigationPanel</key>
<map>
<key>Comment</key>
+ <string>Show/Hide Navigation Bar Navigation Panel</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>1</integer>
+ </map>
+ <key>ShowPGSearchAll</key>
+ <map>
+ <key>Comment</key>
<string>Display results of search All that are flagged as PG</string>
<key>Persist</key>
<integer>1</integer>
diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp
index e1747930b0..08681db6cb 100644
--- a/indra/newview/llagent.cpp
+++ b/indra/newview/llagent.cpp
@@ -47,7 +47,6 @@
#include "llfloaterdirectory.h"
#include "llfloaterland.h"
-#include "llfloatermute.h"
#include "llfloatersnapshot.h"
#include "llfloatertools.h"
#include "llfloaterworldmap.h"
diff --git a/indra/newview/llavatarlist.cpp b/indra/newview/llavatarlist.cpp
index e0322e26b9..a121d327f7 100644
--- a/indra/newview/llavatarlist.cpp
+++ b/indra/newview/llavatarlist.cpp
@@ -223,12 +223,13 @@ BOOL LLAvatarList::update(const std::vector<LLUUID>& all_buddies, const std::str
#endif
setScrollPos(pos);
+ updateLineHeight();
LLRect rect = getRequiredRect();
LLSD params;
params["action"] = "size_changes";
params["width"] = rect.getWidth();
- params["height"] = rect.getHeight();
+ params["height"] = llmax(rect.getHeight(),20) + 5;
getParent()->notifyParent(params);
diff --git a/indra/newview/llbottomtray.cpp b/indra/newview/llbottomtray.cpp
index fe13d4f652..861f23abb7 100644
--- a/indra/newview/llbottomtray.cpp
+++ b/indra/newview/llbottomtray.cpp
@@ -60,7 +60,6 @@ LLBottomTray::LLBottomTray(const LLSD&)
mSysWell = getChild<LLNotificationChiclet>("sys_well");
mSysWell->setNotificationChicletWindow(LLFloaterReg::getInstance("syswell_window"));
- LLFloaterReg::getTypedInstance<LLSysWellWindow>("syswell_window")->setSysWell(mSysWell);
mChicletPanel->setChicletClickedCallback(boost::bind(&LLBottomTray::onChicletClick,this,_1));
@@ -80,8 +79,16 @@ LLBottomTray::LLBottomTray(const LLSD&)
BOOL LLBottomTray::postBuild()
{
+ mCommitCallbackRegistrar.add("ShowCamMoveCtrls.Action", boost::bind(&LLBottomTray::onShowCamMoveCtrlsContextMenuItemClicked, this, _2));
+ mEnableCallbackRegistrar.add("ShowCamMoveCtrls.EnableMenuItem", boost::bind(&LLBottomTray::onShowCamMoveCtrlsContextMenuItemEnabled, this, _2));
+
+ mShowCamMoveCtrlsContextMenu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_hide_camera_move_controls.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
+ gMenuHolder->addChild(mShowCamMoveCtrlsContextMenu);
+
mNearbyChatBar = getChild<LLNearbyChatBar>("chat_bar");
mToolbarStack = getChild<LLLayoutStack>("toolbar_stack");
+ mMovementPanel = getChild<LLPanel>("movement_panel");
+ mCamPanel = getChild<LLPanel>("cam_panel");
return TRUE;
}
@@ -205,8 +212,9 @@ void LLBottomTray::setVisible(BOOL visible)
child_it != mToolbarStack->getChildList()->end(); child_it++)
{
LLView* viewp = *child_it;
+ std::string name = viewp->getName();
- if ("chat_bar" == viewp->getName())
+ if ("chat_bar" == name || "movement_panel" == name || "cam_panel" == name)
continue;
else
{
@@ -216,3 +224,45 @@ void LLBottomTray::setVisible(BOOL visible)
}
}
+BOOL LLBottomTray::handleRightMouseDown(S32 x, S32 y, MASK mask)
+{
+ if (mShowCamMoveCtrlsContextMenu)
+ {
+ mShowCamMoveCtrlsContextMenu->buildDrawLabels();
+ mShowCamMoveCtrlsContextMenu->updateParent(LLMenuGL::sMenuContainer);
+ LLMenuGL::showPopup(this, mShowCamMoveCtrlsContextMenu, x, y);
+ }
+
+ return TRUE;
+}
+
+bool LLBottomTray::onShowCamMoveCtrlsContextMenuItemEnabled(const LLSD& userdata)
+{
+ std::string item = userdata.asString();
+
+ if (item == "show_camera_move_controls")
+ {
+ return gSavedSettings.getBOOL("ShowCameraAndMoveControls");
+ }
+
+ return FALSE;
+}
+
+void LLBottomTray::onShowCamMoveCtrlsContextMenuItemClicked(const LLSD& userdata)
+{
+ std::string item = userdata.asString();
+
+ if (item == "show_camera_move_controls")
+ {
+ BOOL state = !gSavedSettings.getBOOL("ShowCameraAndMoveControls");
+
+ showCameraAndMoveControls(state);
+ gSavedSettings.setBOOL("ShowCameraAndMoveControls", state);
+ }
+}
+
+void LLBottomTray::showCameraAndMoveControls(BOOL visible)
+{
+ mCamPanel->setVisible(visible);
+ mMovementPanel->setVisible(visible);
+}
diff --git a/indra/newview/llbottomtray.h b/indra/newview/llbottomtray.h
index a8fe65a9d3..c3c840ede0 100644
--- a/indra/newview/llbottomtray.h
+++ b/indra/newview/llbottomtray.h
@@ -33,6 +33,8 @@
#ifndef LL_LLBOTTOMPANEL_H
#define LL_LLBOTTOMPANEL_H
+#include <llmenugl.h>
+
#include "llpanel.h"
#include "llimview.h"
@@ -68,6 +70,10 @@ public:
virtual void onFocusLost();
virtual void setVisible(BOOL visible);
+ virtual BOOL handleRightMouseDown(S32 x, S32 y, MASK mask);
+
+ void showCameraAndMoveControls(BOOL visible);
+
private:
protected:
@@ -76,6 +82,9 @@ protected:
void onChicletClick(LLUICtrl* ctrl);
+ bool onShowCamMoveCtrlsContextMenuItemEnabled(const LLSD& userdata);
+ void onShowCamMoveCtrlsContextMenuItemClicked(const LLSD& userdata);
+
static void* createNearbyChatBar(void* userdata);
/**
@@ -88,7 +97,9 @@ protected:
LLTalkButton* mTalkBtn;
LLNearbyChatBar* mNearbyChatBar;
LLLayoutStack* mToolbarStack;
-
+ LLMenuGL* mShowCamMoveCtrlsContextMenu;
+ LLPanel* mMovementPanel;
+ LLPanel* mCamPanel;
};
#endif // LL_LLBOTTOMPANEL_H
diff --git a/indra/newview/llchiclet.cpp b/indra/newview/llchiclet.cpp
index 1109d8174f..808fcde312 100644
--- a/indra/newview/llchiclet.cpp
+++ b/indra/newview/llchiclet.cpp
@@ -117,6 +117,10 @@ boost::signals2::connection LLNotificationChiclet::setClickCallback(
return mButton->setClickedCallback(cb);
}
+void LLNotificationChiclet::setToggleState(BOOL toggled) {
+ mButton->setToggleState(toggled);
+}
+
void LLNotificationChiclet::updateUreadIMNotifications()
{
mUreadIMNotifications = gIMMgr->getNumberOfUnreadIM();
@@ -235,6 +239,7 @@ LLIMP2PChiclet::Params::Params()
avatar_icon.name("avatar_icon");
avatar_icon.rect(LLRect(0, 25, 25, 0));
+ avatar_icon.mouse_opaque(false);
unread_notifications.name("unread");
unread_notifications.rect(LLRect(25, 25, 45, 0));
@@ -242,6 +247,7 @@ LLIMP2PChiclet::Params::Params()
unread_notifications.font_halign(LLFontGL::HCENTER);
unread_notifications.v_pad(5);
unread_notifications.text_color(LLColor4::white);
+ unread_notifications.mouse_opaque(false);
speaker.name("speaker");
speaker.rect(LLRect(45, 25, 65, 0));
diff --git a/indra/newview/llchiclet.h b/indra/newview/llchiclet.h
index ba202515a8..f96dfb69ec 100644
--- a/indra/newview/llchiclet.h
+++ b/indra/newview/llchiclet.h
@@ -537,6 +537,7 @@ public:
void incUreadSystemNotifications() { setCounter(++mUreadSystemNotifications + mUreadIMNotifications); }
void decUreadSystemNotifications() { setCounter(--mUreadSystemNotifications + mUreadIMNotifications); }
void updateUreadIMNotifications();
+ void setToggleState(BOOL toggled);
protected:
LLNotificationChiclet(const Params& p);
diff --git a/indra/newview/llfavoritesbar.cpp b/indra/newview/llfavoritesbar.cpp
index 7ad60232c7..a7f0a8ff9a 100644
--- a/indra/newview/llfavoritesbar.cpp
+++ b/indra/newview/llfavoritesbar.cpp
@@ -55,6 +55,7 @@
#include "llviewerinventory.h"
#include "llviewermenu.h"
#include "llviewermenu.h"
+#include "lltooldraganddrop.h"
static LLDefaultChildRegistry::Register<LLFavoritesBarCtrl> r("favorites_bar");
@@ -73,6 +74,7 @@ public:
, mLoaded(false) {}
void setLandmarkID(const LLUUID& id) { mLandmarkID = id; }
+ const LLUUID& getLandmarkId() const { return mLandmarkID; }
const std::string& getSLURL()
{
@@ -130,8 +132,21 @@ public:
msg = mUrlGetter.getSLURL();
return TRUE;
}
+
+ /*virtual*/ BOOL handleHover(S32 x, S32 y, MASK mask)
+ {
+ LLFavoritesBarCtrl* fb = dynamic_cast<LLFavoritesBarCtrl*>(getParent());
+
+ if (fb)
+ {
+ fb->handleHover(x, y, mask);
+ }
+
+ return LLButton::handleHover(x, y, mask);
+ }
void setLandmarkID(const LLUUID& id){ mUrlGetter.setLandmarkID(id); }
+ const LLUUID& getLandmarkId() const { return mUrlGetter.getLandmarkId(); }
protected:
LLFavoriteLandmarkButton(const LLButton::Params& p) : LLButton(p) {}
@@ -141,6 +156,33 @@ private:
LLSLURLGetter mUrlGetter;
};
+class LLFavoritesToggleableMenu : public LLToggleableMenu
+{
+public:
+ virtual BOOL handleHover(S32 x, S32 y, MASK mask)
+ {
+ if (fb)
+ {
+ fb->handleHover(x, y, mask);
+ }
+
+ return LLToggleableMenu::handleHover(x, y, mask);
+ }
+
+ void initFavoritesBarPointer(LLFavoritesBarCtrl* fb) { this->fb = fb; }
+
+protected:
+ LLFavoritesToggleableMenu(const LLToggleableMenu::Params& p):
+ LLToggleableMenu(p)
+ {
+ }
+
+ friend class LLUICtrlFactory;
+
+private:
+ LLFavoritesBarCtrl* fb;
+};
+
/**
* This class is needed to override LLMenuItemCallGL default handleToolTip function and
* show SLURL as button tooltip.
@@ -164,6 +206,18 @@ public:
void setLandmarkID(const LLUUID& id){ mUrlGetter.setLandmarkID(id); }
+ virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask)
+ {
+ mMouseDownSignal(this, x, y, mask);
+ return LLMenuItemCallGL::handleMouseDown(x, y, mask);
+ }
+
+ virtual BOOL handleMouseUp(S32 x, S32 y, MASK mask)
+ {
+ mMouseUpSignal(this, x, y, mask);
+ return LLMenuItemCallGL::handleMouseUp(x, y, mask);
+ }
+
protected:
LLFavoriteLandmarkMenuItem(const LLMenuItemCallGL::Params& p) : LLMenuItemCallGL(p) {}
@@ -181,6 +235,14 @@ struct LLFavoritesSort
// TODO - made it customizible using gSavedSettings
bool operator()(const LLViewerInventoryItem* const& a, const LLViewerInventoryItem* const& b)
{
+ S32 sortField1 = a->getSortField();
+ S32 sortField2 = b->getSortField();
+
+ if (!(sortField1 < 0 && sortField2 < 0))
+ {
+ return sortField2 > sortField1;
+ }
+
time_t first_create = a->getCreationDate();
time_t second_create = b->getCreationDate();
if (first_create == second_create)
@@ -239,29 +301,34 @@ BOOL LLFavoritesBarCtrl::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
case DAD_LANDMARK:
{
// Copy the item into the favorites folder (if it's not already there).
- LLInventoryItem *item = (LLInventoryItem *)cargo_data;
- LLUUID favorites_id = gInventory.findCategoryUUIDForType(LLAssetType::AT_FAVORITE);
- if (item->getParentUUID() == favorites_id)
+ LLInventoryItem *item = (LLInventoryItem *)cargo_data;
+
+ // check if we are dragging an existing item from the favorites bar
+ if (item && mDragItemId == item->getUUID())
{
- llwarns << "Attemt to copy a favorite item into the same folder." << llendl;
- break;
+ *accept = ACCEPT_YES_SINGLE;
+
+ if (drop)
+ {
+ handleExistingFavoriteDragAndDrop(x, y);
+ }
}
+ else
+ {
+ LLUUID favorites_id = gInventory.findCategoryUUIDForType(LLAssetType::AT_FAVORITE);
+ if (item->getParentUUID() == favorites_id)
+ {
+ llwarns << "Attemt to copy a favorite item into the same folder." << llendl;
+ break;
+ }
- *accept = ACCEPT_YES_COPY_SINGLE;
+ *accept = ACCEPT_YES_COPY_SINGLE;
- if (drop)
- {
- copy_inventory_item(
- gAgent.getID(),
- item->getPermissions().getOwner(),
- item->getUUID(),
- favorites_id,
- std::string(),
- LLPointer<LLInventoryCallback>(NULL));
-
- llinfos << "Copied inventory item #" << item->getUUID() << " to favorites." << llendl;
+ if (drop)
+ {
+ handleNewFavoriteDragAndDrop(item, favorites_id, x, y);
+ }
}
-
}
break;
default:
@@ -271,6 +338,61 @@ BOOL LLFavoritesBarCtrl::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
return TRUE;
}
+void LLFavoritesBarCtrl::handleExistingFavoriteDragAndDrop(S32 x, S32 y)
+{
+ LLFavoriteLandmarkButton* dest = dynamic_cast<LLFavoriteLandmarkButton*>(findChildByLocalCoords(x, y));
+
+ if (dest)
+ {
+ updateItemsOrder(mItems, mDragItemId, dest->getLandmarkId());
+ }
+ else
+ {
+ mItems.push_back(gInventory.getItem(mDragItemId));
+ }
+
+ saveItemsOrder(mItems);
+
+ LLFavoritesToggleableMenu* menu = (LLFavoritesToggleableMenu*) mPopupMenuHandle.get();
+
+ if (menu && menu->getVisible())
+ {
+ menu->setVisible(FALSE);
+ showDropDownMenu();
+ }
+
+ mDragItemId = LLUUID::null;
+ getWindow()->setCursor(UI_CURSOR_ARROW);
+}
+
+void LLFavoritesBarCtrl::handleNewFavoriteDragAndDrop(LLInventoryItem *item, const LLUUID& favorites_id, S32 x, S32 y)
+{
+ LLFavoriteLandmarkButton* dest = dynamic_cast<LLFavoriteLandmarkButton*>(findChildByLocalCoords(x, y));
+
+ if (dest)
+ {
+ insertBeforeItem(mItems, dest->getLandmarkId(), item->getUUID());
+ }
+ else
+ {
+ mItems.push_back(gInventory.getItem(item->getUUID()));
+ }
+
+ saveItemsOrder(mItems);
+
+ copy_inventory_item(
+ gAgent.getID(),
+ item->getPermissions().getOwner(),
+ item->getUUID(),
+ favorites_id,
+ std::string(),
+ LLPointer<LLInventoryCallback>(NULL));
+
+ getWindow()->setCursor(UI_CURSOR_ARROW);
+
+ llinfos << "Copied inventory item #" << item->getUUID() << " to favorites." << llendl;
+}
+
//virtual
void LLFavoritesBarCtrl::changed(U32 mask)
{
@@ -311,9 +433,9 @@ LLXMLNodePtr LLFavoritesBarCtrl::getButtonXMLNode()
void LLFavoritesBarCtrl::updateButtons(U32 bar_width)
{
- LLInventoryModel::item_array_t items;
+ mItems.clear();
- if (!collectFavoriteItems(items))
+ if (!collectFavoriteItems(mItems))
{
return;
}
@@ -331,7 +453,7 @@ void LLFavoritesBarCtrl::updateButtons(U32 bar_width)
const S32 buttonVGap = 2;
- S32 count = items.count();
+ S32 count = mItems.count();
const S32 buttonHPad = LLUI::sSettingGroups["config"]->getS32("ButtonHPad");
const S32 chevron_button_width = mFont->getWidth(">>") + buttonHPad * 2;
@@ -369,7 +491,7 @@ void LLFavoritesBarCtrl::updateButtons(U32 bar_width)
S32 i;
for (i = 0; i < mFirstDropDownItem; ++i)
{
- if (mItemNamesCache.get(i) != items.get(i)->getName())
+ if (mItemNamesCache.get(i) != mItems.get(i)->getName())
{
break;
}
@@ -387,7 +509,7 @@ void LLFavoritesBarCtrl::updateButtons(U32 bar_width)
mItemNamesCache.clear();
for (S32 i = 0; i < mFirstDropDownItem; i++)
{
- mItemNamesCache.put(items.get(i)->getName());
+ mItemNamesCache.put(mItems.get(i)->getName());
}
// Rebuild the buttons only
@@ -404,7 +526,7 @@ void LLFavoritesBarCtrl::updateButtons(U32 bar_width)
}
}
- createButtons(items, buttonXMLNode, buttonWidth, buttonHGap);
+ createButtons(mItems, buttonXMLNode, buttonWidth, buttonHGap);
}
// Chevron button
@@ -467,9 +589,9 @@ void LLFavoritesBarCtrl::createButtons(const LLInventoryModel::item_array_t &ite
{
S32 curr_x = buttonHGap;
// Adding buttons
- for(S32 i = mFirstDropDownItem -1; i >= 0; i--)
+ for(S32 i = mFirstDropDownItem -1, j = 0; i >= 0; i--)
{
- LLInventoryItem* item = items.get(i);
+ LLViewerInventoryItem* item = items.get(j++);
LLFavoriteLandmarkButton* fav_btn = LLUICtrlFactory::defaultBuilder<LLFavoriteLandmarkButton>(buttonXMLNode, this, NULL);
if (NULL == fav_btn)
@@ -488,6 +610,10 @@ void LLFavoritesBarCtrl::createButtons(const LLInventoryModel::item_array_t &ite
fav_btn->setToolTip(item->getName());
fav_btn->setCommitCallback(boost::bind(&LLFavoritesBarCtrl::onButtonClick, this, item->getUUID()));
fav_btn->setRightMouseDownCallback(boost::bind(&LLFavoritesBarCtrl::onButtonRightClick, this, item->getUUID(), _1, _2, _3,_4 ));
+
+ fav_btn->LLUICtrl::setMouseDownCallback(boost::bind(&LLFavoritesBarCtrl::onButtonMouseDown, this, item->getUUID(), _1, _2, _3, _4));
+ fav_btn->LLUICtrl::setMouseUpCallback(boost::bind(&LLFavoritesBarCtrl::onButtonMouseUp, this, item->getUUID(), _1, _2, _3, _4));
+
sendChildToBack(fav_btn);
curr_x += buttonWidth + buttonHGap;
@@ -521,6 +647,15 @@ BOOL LLFavoritesBarCtrl::collectFavoriteItems(LLInventoryModel::item_array_t &it
std::sort(items.begin(), items.end(), LLFavoritesSort());
+ if (needToSaveItemsOrder(items))
+ {
+ S32 sortField = 0;
+ for (LLInventoryModel::item_array_t::iterator i = items.begin(); i != items.end(); ++i)
+ {
+ (*i)->setSortField(++sortField);
+ }
+ }
+
return TRUE;
}
@@ -528,7 +663,7 @@ void LLFavoritesBarCtrl::showDropDownMenu()
{
if (mPopupMenuHandle.isDead())
{
- LLToggleableMenu::Params menu_p;
+ LLFavoritesToggleableMenu::Params menu_p;
menu_p.name("favorites menu");
menu_p.can_tear_off(false);
menu_p.visible(false);
@@ -536,26 +671,26 @@ void LLFavoritesBarCtrl::showDropDownMenu()
menu_p.max_scrollable_items = 10;
menu_p.preferred_width = DROP_DOWN_MENU_WIDTH;
- LLToggleableMenu* menu = LLUICtrlFactory::create<LLToggleableMenu>(menu_p);
-
+ LLFavoritesToggleableMenu* menu = LLUICtrlFactory::create<LLFavoritesToggleableMenu>(menu_p);
+ menu->initFavoritesBarPointer(this);
mPopupMenuHandle = menu->getHandle();
}
- LLToggleableMenu* menu = (LLToggleableMenu*)mPopupMenuHandle.get();
+ LLFavoritesToggleableMenu* menu = (LLFavoritesToggleableMenu*)mPopupMenuHandle.get();
if(menu)
{
if (!menu->toggleVisibility())
return;
- LLInventoryModel::item_array_t items;
+ mItems.clear();
- if (!collectFavoriteItems(items))
+ if (!collectFavoriteItems(mItems))
{
return;
}
- S32 count = items.count();
+ S32 count = mItems.count();
// Check it there are changed items, since last call
if (mItemNamesCache.size() == count)
@@ -563,7 +698,7 @@ void LLFavoritesBarCtrl::showDropDownMenu()
S32 i;
for (i = mFirstDropDownItem; i < count; i++)
{
- if (mItemNamesCache.get(i) != items.get(i)->getName())
+ if (mItemNamesCache.get(i) != mItems.get(i)->getName())
{
break;
}
@@ -587,7 +722,7 @@ void LLFavoritesBarCtrl::showDropDownMenu()
{
for (S32 i = mFirstDropDownItem; i < count; i++)
{
- mItemNamesCache.put(items.get(i)->getName());
+ mItemNamesCache.put(mItems.get(i)->getName());
}
}
@@ -598,17 +733,18 @@ void LLFavoritesBarCtrl::showDropDownMenu()
for(S32 i = mFirstDropDownItem; i < count; i++)
{
- LLInventoryItem* item = items.get(i);
+ LLViewerInventoryItem* item = mItems.get(i);
const std::string& item_name = item->getName();
- LLMenuItemCallGL::Params item_params;
+ LLFavoriteLandmarkMenuItem::Params item_params;
item_params.name(item_name);
item_params.label(item_name);
item_params.on_click.function(boost::bind(&LLFavoritesBarCtrl::onButtonClick, this, item->getUUID()));
LLFavoriteLandmarkMenuItem *menu_item = LLUICtrlFactory::create<LLFavoriteLandmarkMenuItem>(item_params);
menu_item->setRightMouseDownCallback(boost::bind(&LLFavoritesBarCtrl::onButtonRightClick, this,item->getUUID(),_1,_2,_3,_4));
- menu_item->setLandmarkID(item->getUUID());
+ menu_item->LLUICtrl::setMouseDownCallback(boost::bind(&LLFavoritesBarCtrl::onButtonMouseDown, this, item->getUUID(), _1, _2, _3, _4));
+ menu_item->LLUICtrl::setMouseUpCallback(boost::bind(&LLFavoritesBarCtrl::onButtonMouseUp, this, item->getUUID(), _1, _2, _3, _4));
// Check whether item name wider than menu
if (menu_item->getNominalWidth() > max_width)
@@ -644,13 +780,6 @@ void LLFavoritesBarCtrl::showDropDownMenu()
void LLFavoritesBarCtrl::onButtonClick(LLUUID item_id)
{
- LLInventoryModel::item_array_t items;
-
- if (!collectFavoriteItems(items))
- {
- return;
- }
-
// We only have one Inventory, gInventory. Some day this should be better abstracted.
LLInvFVBridgeAction::doAction(item_id,&gInventory);
}
@@ -797,5 +926,135 @@ void LLFavoritesBarCtrl::pastFromClipboard() const
}
}
+void LLFavoritesBarCtrl::onButtonMouseDown(LLUUID id, LLUICtrl* ctrl, S32 x, S32 y, MASK mask)
+{
+ mDragItemId = id;
+ mStartDrag = TRUE;
+
+ S32 screenX, screenY;
+ localPointToScreen(x, y, &screenX, &screenY);
+
+ LLToolDragAndDrop::getInstance()->setDragStart(screenX, screenY);
+}
+
+void LLFavoritesBarCtrl::onButtonMouseUp(LLUUID id, LLUICtrl* ctrl, S32 x, S32 y, MASK mask)
+{
+ mDragItemId = LLUUID::null;
+}
+
+BOOL LLFavoritesBarCtrl::handleHover(S32 x, S32 y, MASK mask)
+{
+ if (mDragItemId != LLUUID::null && mStartDrag)
+ {
+ S32 screenX, screenY;
+ localPointToScreen(x, y, &screenX, &screenY);
+
+ if(LLToolDragAndDrop::getInstance()->isOverThreshold(screenX, screenY))
+ {
+ LLToolDragAndDrop::getInstance()->beginDrag(
+ DAD_LANDMARK, mDragItemId,
+ LLToolDragAndDrop::SOURCE_LIBRARY);
+
+ mStartDrag = FALSE;
+
+ return LLToolDragAndDrop::getInstance()->handleHover(x, y, mask);
+ }
+ }
+
+ return TRUE;
+}
+
+LLUICtrl* LLFavoritesBarCtrl::findChildByLocalCoords(S32 x, S32 y)
+{
+ LLUICtrl* ctrl = 0;
+ S32 screenX, screenY;
+ const child_list_t* list = getChildList();
+
+ localPointToScreen(x, y, &screenX, &screenY);
+
+ // look for a child which contains the point (screenX, screenY) in it's rectangle
+ for (child_list_const_iter_t i = list->begin(); i != list->end(); ++i)
+ {
+ LLRect rect;
+ localRectToScreen((*i)->getRect(), &rect);
+
+ if (rect.pointInRect(screenX, screenY))
+ {
+ ctrl = dynamic_cast<LLUICtrl*>(*i);
+ break;
+ }
+ }
+
+ return ctrl;
+}
+
+BOOL LLFavoritesBarCtrl::needToSaveItemsOrder(const LLInventoryModel::item_array_t& items)
+{
+ BOOL result = FALSE;
+
+ // if there is an item without sort order field set, we need to save items order
+ for (LLInventoryModel::item_array_t::const_iterator i = items.begin(); i != items.end(); ++i)
+ {
+ if ((*i)->getSortField() < 0)
+ {
+ result = TRUE;
+ break;
+ }
+ }
+
+ return result;
+}
+
+void LLFavoritesBarCtrl::saveItemsOrder(LLInventoryModel::item_array_t& items)
+{
+ int sortField = 0;
+
+ // current order is saved by setting incremental values (1, 2, 3, ...) for the sort field
+ for (LLInventoryModel::item_array_t::iterator i = items.begin(); i != items.end(); ++i)
+ {
+ LLViewerInventoryItem* item = *i;
+
+ item->setSortField(++sortField);
+ item->setComplete(TRUE);
+ item->updateServer(FALSE);
+
+ gInventory.updateItem(item);
+ }
+
+ gInventory.notifyObservers();
+}
+
+LLInventoryModel::item_array_t::iterator LLFavoritesBarCtrl::findItemByUUID(LLInventoryModel::item_array_t& items, const LLUUID& id)
+{
+ LLInventoryModel::item_array_t::iterator result = items.end();
+
+ for (LLInventoryModel::item_array_t::iterator i = items.begin(); i != items.end(); ++i)
+ {
+ if ((*i)->getUUID() == id)
+ {
+ result = i;
+ break;
+ }
+ }
+
+ return result;
+}
+
+void LLFavoritesBarCtrl::updateItemsOrder(LLInventoryModel::item_array_t& items, const LLUUID& srcItemId, const LLUUID& destItemId)
+{
+ LLViewerInventoryItem* srcItem = gInventory.getItem(srcItemId);
+ LLViewerInventoryItem* destItem = gInventory.getItem(destItemId);
+
+ items.erase(findItemByUUID(items, srcItem->getUUID()));
+ items.insert(findItemByUUID(items, destItem->getUUID()), srcItem);
+}
+
+void LLFavoritesBarCtrl::insertBeforeItem(LLInventoryModel::item_array_t& items, const LLUUID& beforeItemId, const LLUUID& insertedItemId)
+{
+ LLViewerInventoryItem* beforeItem = gInventory.getItem(beforeItemId);
+ LLViewerInventoryItem* insertedItem = gInventory.getItem(insertedItemId);
+
+ items.insert(findItemByUUID(items, beforeItem->getUUID()), insertedItem);
+}
// EOF
diff --git a/indra/newview/llfavoritesbar.h b/indra/newview/llfavoritesbar.h
index 824b396add..4cd92d1a58 100644
--- a/indra/newview/llfavoritesbar.h
+++ b/indra/newview/llfavoritesbar.h
@@ -60,6 +60,8 @@ public:
EAcceptance* accept,
std::string& tooltip_msg);
+ /*virtual*/ BOOL handleHover(S32 x, S32 y, MASK mask);
+
// LLInventoryObserver observer trigger
virtual void changed(U32 mask);
virtual void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE);
@@ -73,10 +75,12 @@ protected:
void onButtonClick(LLUUID id);
void onButtonRightClick(LLUUID id,LLView* button,S32 x,S32 y,MASK mask);
+ void onButtonMouseDown(LLUUID id, LLUICtrl* button, S32 x, S32 y, MASK mask);
+ void onButtonMouseUp(LLUUID id, LLUICtrl* button, S32 x, S32 y, MASK mask);
+
void doToSelected(const LLSD& userdata);
BOOL isClipboardPasteable() const;
void pastFromClipboard() const;
-
void showDropDownMenu();
@@ -94,8 +98,49 @@ protected:
LLRect mChevronRect;
std::string mChevronButtonToolTip;
+
+private:
+ /*
+ * Helper function to make code more readable. It handles all drag and drop
+ * operations of the existing favorites items on the favorites bar.
+ */
+ void handleExistingFavoriteDragAndDrop(S32 x, S32 y);
+
+ /*
+ * Helper function to make code more readable. It handles all drag and drop
+ * operations of the new landmark to the favorites bar.
+ */
+ void handleNewFavoriteDragAndDrop(LLInventoryItem *item, const LLUUID& favorites_id, S32 x, S32 y);
+
+ // finds a control under the specified LOCAL point
+ LLUICtrl* findChildByLocalCoords(S32 x, S32 y);
+
+ // checks if the current order of the favorites items must be saved
+ BOOL needToSaveItemsOrder(const LLInventoryModel::item_array_t& items);
+
+ // saves current order of the favorites items
+ void saveItemsOrder(LLInventoryModel::item_array_t& items);
+
+ /*
+ * changes favorites items order by insertion of the item identified by srcItemId
+ * BEFORE the item identified by destItemId. both items must exist in items array.
+ */
+ void updateItemsOrder(LLInventoryModel::item_array_t& items, const LLUUID& srcItemId, const LLUUID& destItemId);
+
+ /*
+ * inserts an item identified by insertedItemId BEFORE an item identified by beforeItemId.
+ * this function assumes that an item identified by insertedItemId doesn't exist in items array.
+ */
+ void insertBeforeItem(LLInventoryModel::item_array_t& items, const LLUUID& beforeItemId, const LLUUID& insertedItemId);
+
+ // finds an item by it's UUID in the items array
+ LLInventoryModel::item_array_t::iterator findItemByUUID(LLInventoryModel::item_array_t& items, const LLUUID& id);
+
+ BOOL mSkipUpdate;
+ BOOL mStartDrag;
+ LLUUID mDragItemId;
+ LLInventoryModel::item_array_t mItems;
};
#endif // LL_LLFAVORITESBARCTRL_H
-
diff --git a/indra/newview/llfloaterchat.cpp b/indra/newview/llfloaterchat.cpp
index 0dee3a1e83..14fb93df61 100644
--- a/indra/newview/llfloaterchat.cpp
+++ b/indra/newview/llfloaterchat.cpp
@@ -47,7 +47,6 @@
#include "llconsole.h"
#include "llfloateractivespeakers.h"
#include "llfloaterchatterbox.h"
-#include "llfloatermute.h"
#include "llfloaterreg.h"
#include "llfloaterscriptdebug.h"
#include "llkeyboard.h"
@@ -56,6 +55,7 @@
//#include "llresizehandle.h"
#include "llchatbar.h"
#include "llrecentpeople.h"
+#include "llpanelblockedlist.h"
#include "llstatusbar.h"
#include "llviewertexteditor.h"
#include "llviewergesture.h" // for triggering gestures
@@ -280,7 +280,7 @@ void LLFloaterChat::onClickMute(void *data)
LLMute mute(id);
mute.setFromDisplayName(name);
LLMuteList::getInstance()->add(mute);
- LLFloaterReg::showInstance("mute");
+ LLPanelBlockedList::showPanelAndSelect(mute.mID);
}
//static
diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp
index c47c7b073c..d389cf06ec 100644
--- a/indra/newview/llfloaterpreference.cpp
+++ b/indra/newview/llfloaterpreference.cpp
@@ -61,6 +61,7 @@
#include "llnavigationbar.h"
#include "llpanellogin.h"
#include "llradiogroup.h"
+#include "llsearchcombobox.h"
#include "llsky.h"
#include "llscrolllistctrl.h"
#include "llscrolllistitem.h"
@@ -214,6 +215,11 @@ bool callback_clear_browser_cache(const LLSD& notification, const LLSD& response
// flag client texture cache for clearing next time the client runs
gSavedSettings.setBOOL("PurgeCacheOnNextStartup", TRUE);
LLNotifications::instance().add("CacheWillClear");
+
+ LLSearchHistory::getInstance()->clearHistory();
+ LLSearchHistory::getInstance()->save();
+ LLSearchComboBox* search_ctrl = LLNavigationBar::getInstance()->getChild<LLSearchComboBox>("search_combo_box");
+ search_ctrl->clearHistory();
}
return false;
diff --git a/indra/newview/llfriendcard.cpp b/indra/newview/llfriendcard.cpp
index bef5f094e3..97b7f3e9ad 100644
--- a/indra/newview/llfriendcard.cpp
+++ b/indra/newview/llfriendcard.cpp
@@ -173,6 +173,15 @@ bool LLFriendCardsManager::isCategoryInFriendFolder(const LLViewerInventoryCateg
return TRUE == gInventory.isObjectDescendentOf(cat->getUUID(), findFriendFolderUUIDImpl());
}
+bool LLFriendCardsManager::isAnyFriendCategory(const LLUUID& catID) const
+{
+ const LLUUID& friendFolderID = findFriendFolderUUIDImpl();
+ if (catID == friendFolderID)
+ return true;
+
+ return TRUE == gInventory.isObjectDescendentOf(catID, friendFolderID);
+}
+
void LLFriendCardsManager::syncFriendsFolder()
{
//lets create "Friends" and "Friends/All" in the Inventory "Calling Cards" if they are absent
@@ -305,10 +314,12 @@ void LLFriendCardsManager::findMatchedFriendCards(const LLUUID& avatarID, LLInve
LLInventoryModel::cat_array_t cats;
LLUUID friendFolderUUID = findFriendFolderUUIDImpl();
- LLParticularBuddyCollector matchFunctor(avatarID);
LLViewerInventoryCategory* friendFolder = gInventory.getCategory(friendFolderUUID);
+ if (NULL == friendFolder)
+ return;
+ LLParticularBuddyCollector matchFunctor(avatarID);
LLInventoryModel::cat_array_t subFolders;
subFolders.push_back(friendFolder);
diff --git a/indra/newview/llfriendcard.h b/indra/newview/llfriendcard.h
index 18a6d0ab69..aa391ce2c1 100644
--- a/indra/newview/llfriendcard.h
+++ b/indra/newview/llfriendcard.h
@@ -77,6 +77,11 @@ public:
bool isCategoryInFriendFolder(const LLViewerInventoryCategory* cat) const;
/**
+ * Checks is the specified category is a Friend folder or any its subfolder
+ */
+ bool isAnyFriendCategory(const LLUUID& catID) const;
+
+ /**
* Synchronizes content of the Calling Card/Friends/All Global Inventory folder with Agent's Friend List
*/
void syncFriendsFolder();
diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp
index 789e628b67..adc73111e0 100644
--- a/indra/newview/llinventorybridge.cpp
+++ b/indra/newview/llinventorybridge.cpp
@@ -2420,8 +2420,14 @@ BOOL LLFolderBridge::dragOrDrop(MASK mask, BOOL drop,
drop);
break;
case DAD_CATEGORY:
- accept = dragCategoryIntoFolder((LLInventoryCategory*)cargo_data,
- drop);
+ if (LLFriendCardsManager::instance().isAnyFriendCategory(mUUID))
+ {
+ accept = FALSE;
+ }
+ else
+ {
+ accept = dragCategoryIntoFolder((LLInventoryCategory*)cargo_data, drop);
+ }
break;
default:
break;
diff --git a/indra/newview/lllocationhistory.cpp b/indra/newview/lllocationhistory.cpp
index c83cde9d83..d910dbf718 100644
--- a/indra/newview/lllocationhistory.cpp
+++ b/indra/newview/lllocationhistory.cpp
@@ -37,59 +37,41 @@
#include <iomanip> // for std::setw()
#include "llui.h"
-
-const char LLLocationHistory::delimiter = '\t';
+#include "llsd.h"
+#include "llsdserialize.h"
LLLocationHistory::LLLocationHistory() :
mFilename("typed_locations.txt")
{
}
-void LLLocationHistory::addItem(const std::string & item, const std::string & tooltip) {
+void LLLocationHistory::addItem(const LLLocationHistoryItem& item) {
static LLUICachedControl<S32> max_items("LocationHistoryMaxSize", 100);
// check if this item doesn't duplicate any existing one
- std::vector<std::string>::iterator item_iter = std::find_if(mItems.begin(), mItems.end(),
- boost::bind(&LLLocationHistory::equalByRegionParcel,this,_1,item));
+ location_list_t::iterator item_iter = std::find(mItems.begin(), mItems.end(),item);
if(item_iter != mItems.end()){
- /*replace duplicate.
- * If an item's region and item's parcel are equal.
- */
- mToolTips.erase(*item_iter);
mItems.erase(item_iter);
-
}
mItems.push_back(item);
- mToolTips[item] = tooltip;
-
+
// If the vector size exceeds the maximum, purge the oldest items.
if ((S32)mItems.size() > max_items) {
- for(std::vector<std::string>::iterator i = mItems.begin(); i != mItems.end()-max_items; ++i) {
- mToolTips.erase(*i);
- mItems.erase(i);
+ for(location_list_t::iterator i = mItems.begin(); i != mItems.end()-max_items; ++i) {
+ mItems.erase(i);
}
}
}
-/**
- * check if the history item is equal.
- * @return true - if region name and parcel is equal.
+/*
+ * @brief Try to find item in history.
+ * If item has been founded, it will be places into end of history.
+ * @return true - item has founded
*/
-bool LLLocationHistory::equalByRegionParcel(const std::string& item, const std::string& newItem){
-
-
- S32 itemIndex = item.find('(');
- S32 newItemIndex = newItem.find('(');
-
- std::string region_parcel = item.substr(0,itemIndex);
- std::string new_region_parcel = newItem.substr(0,newItemIndex);
-
- return region_parcel == new_region_parcel;
-}
-bool LLLocationHistory::touchItem(const std::string & item) {
+bool LLLocationHistory::touchItem(const LLLocationHistoryItem& item) {
bool result = false;
- std::vector<std::string>::iterator item_iter = std::find(mItems.begin(), mItems.end(), item);
+ location_list_t::iterator item_iter = std::find(mItems.begin(), mItems.end(), item);
// the last used item should be the first in the history
if (item_iter != mItems.end()) {
@@ -104,13 +86,6 @@ bool LLLocationHistory::touchItem(const std::string & item) {
void LLLocationHistory::removeItems()
{
mItems.clear();
- mToolTips.clear();
-}
-
-std::string LLLocationHistory::getToolTip(const std::string & item) const {
- std::map<std::string, std::string>::const_iterator i = mToolTips.find(item);
-
- return i != mToolTips.end() ? i->second : "";
}
bool LLLocationHistory::getMatchingItems(std::string substring, location_list_t& result) const
@@ -123,7 +98,7 @@ bool LLLocationHistory::getMatchingItems(std::string substring, location_list_t&
for (location_list_t::const_iterator it = mItems.begin(); it != mItems.end(); ++it)
{
- std::string haystack = *it;
+ std::string haystack = it->getLocation();
LLStringUtil::toLower(haystack);
if (haystack.find(needle) != std::string::npos)
@@ -139,7 +114,7 @@ void LLLocationHistory::dump() const
int i = 0;
for (location_list_t::const_iterator it = mItems.begin(); it != mItems.end(); ++it, ++i)
{
- llinfos << "#" << std::setw(2) << std::setfill('0') << i << ": " << *it << llendl;
+ llinfos << "#" << std::setw(2) << std::setfill('0') << i << ": " << it->getLocation() << llendl;
}
}
@@ -158,11 +133,7 @@ void LLLocationHistory::save() const
for (location_list_t::const_iterator it = mItems.begin(); it != mItems.end(); ++it)
{
- std::string tooltip = getToolTip(*it);
- if(!tooltip.empty())
- {
- file << (*it) << delimiter << tooltip << std::endl;
- }
+ file << LLSDOStreamer<LLSDNotationFormatter>((*it).toLLSD()) << std::endl;
}
file.close();
@@ -186,16 +157,17 @@ void LLLocationHistory::load()
// add each line in the file to the list
std::string line;
-
+ LLPointer<LLSDParser> parser = new LLSDNotationParser();
while (std::getline(file, line)) {
- size_t dp = line.find(delimiter);
-
- if (dp != std::string::npos) {
- const std::string reg_name = line.substr(0, dp);
- const std::string tooltip = line.substr(dp + 1, std::string::npos);
-
- addItem(reg_name, tooltip);
+ LLSD s_item;
+ std::istringstream iss(line);
+ if (parser->parse(iss, s_item, line.length()) == LLSDParser::PARSE_FAILURE)
+ {
+ llinfos<< "Parsing saved teleport history failed" << llendl;
+ break;
}
+
+ mItems.push_back(s_item);
}
file.close();
diff --git a/indra/newview/lllocationhistory.h b/indra/newview/lllocationhistory.h
index 060a6b2fe8..5f9976f87a 100644
--- a/indra/newview/lllocationhistory.h
+++ b/indra/newview/lllocationhistory.h
@@ -40,21 +40,84 @@
#include <map>
#include <boost/function.hpp>
+class LLSD;
+
+enum ELocationType {
+ TYPED_REGION_SURL//region name or surl
+ ,LANDMARK // name of landmark
+ ,TELEPORT_HISTORY
+ };
+class LLLocationHistoryItem {
+
+public:
+ LLLocationHistoryItem(){}
+ LLLocationHistoryItem(std::string typed_location,
+ LLVector3d global_position, std::string tooltip,ELocationType type ):
+ mLocation(typed_location),
+ mGlobalPos(global_position),
+ mToolTip(tooltip),
+ mType(type)
+ {}
+ LLLocationHistoryItem(const LLLocationHistoryItem& item):
+ mGlobalPos(item.mGlobalPos),
+ mToolTip(item.mToolTip),
+ mLocation(item.mLocation),
+ mType(item.mType)
+ {}
+ LLLocationHistoryItem(const LLSD& data):
+ mLocation(data["location"]),
+ mGlobalPos(data["global_pos"]),
+ mToolTip(data["tooltip"]),
+ mType(ELocationType(data["item_type"].asInteger()))
+ {}
+
+ bool operator==(const LLLocationHistoryItem& item)
+ {
+ // do not compare mGlobalPos,
+ // because of a rounding off , the history can contain duplicates
+ return mLocation == item.mLocation && (mType == item.mType);
+ }
+ bool operator!=(const LLLocationHistoryItem& item)
+ {
+ return ! (*this == item);
+ }
+ LLSD toLLSD() const
+ {
+ LLSD val;
+ val["location"]= mLocation;
+ val["global_pos"] = mGlobalPos.getValue();
+ val["tooltip"] = mToolTip;
+ val["item_type"] = mType;
+ return val;
+ }
+ const std::string& getLocation() const { return mLocation; };
+ const std::string& getToolTip() const { return mToolTip; };
+ //static bool equalByRegionParcel(const LLLocationHistoryItem& item1, const LLLocationHistoryItem& item2);
+ static bool equalByLocation(const LLLocationHistoryItem& item1, const std::string& item_location)
+ {
+ return item1.getLocation() == item_location;
+ }
+
+ LLVector3d mGlobalPos; // global position
+ std::string mToolTip;// SURL
+ std::string mLocation;// typed_location
+ ELocationType mType;
+};
+
class LLLocationHistory: public LLSingleton<LLLocationHistory>
{
LOG_CLASS(LLLocationHistory);
public:
- typedef std::vector<std::string> location_list_t;
+ typedef std::vector<LLLocationHistoryItem> location_list_t;
typedef boost::function<void()> loaded_callback_t;
typedef boost::signals2::signal<void()> loaded_signal_t;
LLLocationHistory();
- void addItem(const std::string & item, const std::string & tooltip);
- bool touchItem(const std::string & item);
+ void addItem(const LLLocationHistoryItem& item);
+ bool touchItem(const LLLocationHistoryItem& item);
void removeItems();
- std::string getToolTip(const std::string & item) const;
size_t getItemCount() const { return mItems.size(); }
const location_list_t& getItems() const { return mItems; }
bool getMatchingItems(std::string substring, location_list_t& result) const;
@@ -65,10 +128,8 @@ public:
void dump() const;
private:
- bool equalByRegionParcel(const std::string& item, const std::string& item_to_add);
- const static char delimiter;
- std::vector<std::string> mItems;
- std::map<std::string, std::string> mToolTips;
+
+ location_list_t mItems;
std::string mFilename; /// File to store the history to.
loaded_signal_t mLoadedSignal;
};
diff --git a/indra/newview/lllocationinputctrl.cpp b/indra/newview/lllocationinputctrl.cpp
index a8ec826e88..f54a614f62 100644
--- a/indra/newview/lllocationinputctrl.cpp
+++ b/indra/newview/lllocationinputctrl.cpp
@@ -48,6 +48,7 @@
#include "lllandmarkactions.h"
#include "lllandmarklist.h"
#include "lllocationhistory.h"
+#include "llteleporthistory.h"
#include "llsidetray.h"
#include "llslurl.h"
#include "lltrans.h"
@@ -295,11 +296,19 @@ BOOL LLLocationInputCtrl::handleToolTip(S32 x, S32 y, std::string& msg, LLRect*
if (LLUICtrl::handleToolTip(x, y, msg, sticky_rect_screen) && !msg.empty())
{
if (mList->getRect().pointInRect(x, y)) {
- LLLocationHistory* lh = LLLocationHistory::getInstance();
- const std::string tooltip = lh->getToolTip(msg);
-
- if (!tooltip.empty()) {
- msg = tooltip;
+ S32 loc_x, loc_y;
+ //x,y - contain coordinates related to the location input control, but without taking the expanded list into account
+ //So we have to convert it again into local coordinates of mList
+ localPointToOtherView(x,y,&loc_x,&loc_y,mList);
+
+ LLScrollListItem* item = mList->hitItem(loc_x,loc_y);
+ if (item)
+ {
+ LLSD value = item->getValue();
+ if (value.has("tooltip"))
+ {
+ msg = value["tooltip"].asString();
+ }
}
}
@@ -448,18 +457,58 @@ void LLLocationInputCtrl::onLocationPrearrange(const LLSD& data)
rebuildLocationHistory(filter);
//Let's add landmarks to the top of the list if any
- if( filter.size() !=0 )
+ if(!filter.empty() )
{
LLInventoryModel::item_array_t landmark_items = LLLandmarkActions::fetchLandmarksByName(filter, TRUE);
for(U32 i=0; i < landmark_items.size(); i++)
{
- mList->addSimpleElement(landmark_items[i]->getName(), ADD_TOP);
+ LLSD value;
+ //TODO:: DO we need tooltip for Landmark??
+
+ value["item_type"] = LANDMARK;
+ value["AssetUUID"] = landmark_items[i]->getAssetUUID();
+ add(landmark_items[i]->getName(), value);
+
+ }
+ //Let's add teleport history items
+ LLTeleportHistory* th = LLTeleportHistory::getInstance();
+ LLTeleportHistory::slurl_list_t th_items = th->getItems();
+
+ std::set<std::string> new_item_titles;// duplicate control
+ LLTeleportHistory::slurl_list_t::iterator result = std::find_if(
+ th_items.begin(), th_items.end(), boost::bind(
+ &LLLocationInputCtrl::findTeleportItemsByTitle, this,
+ _1, filter));
+
+ while (result != th_items.end())
+ {
+ //mTitile format - region_name[, parcel_name]
+ //mFullTitile format - region_name[, parcel_name] (local_x,local_y, local_z)
+ if (new_item_titles.insert(result->mFullTitle).second)
+ {
+ LLSD value;
+ value["item_type"] = TELEPORT_HISTORY;
+ value["global_pos"] = result->mGlobalPos.getValue();
+ std::string region_name = result->mTitle.substr(0, result->mTitle.find(','));
+ //TODO*: add Surl to teleportitem or parse region name from title
+ value["tooltip"] = LLSLURL::buildSLURLfromPosGlobal(region_name,
+ result->mGlobalPos, false);
+ add(result->getTitle(), value);
+ }
+ result = std::find_if(result + 1, th_items.end(), boost::bind(
+ &LLLocationInputCtrl::findTeleportItemsByTitle, this,
+ _1, filter));
}
}
+ sortByName();
+
mList->mouseOverHighlightNthItem(-1); // Clear highlight on the last selected item.
}
-
+bool LLLocationInputCtrl::findTeleportItemsByTitle(const LLTeleportHistoryItem& item, const std::string& filter)
+{
+ return item.mTitle.find(filter) != std::string::npos;
+}
void LLLocationInputCtrl::onTextEditorRightClicked(S32 x, S32 y, MASK mask)
{
if (mLocationContextMenu)
@@ -519,7 +568,12 @@ void LLLocationInputCtrl::rebuildLocationHistory(std::string filter)
removeall();
for (LLLocationHistory::location_list_t::const_reverse_iterator it = itemsp->rbegin(); it != itemsp->rend(); it++)
{
- add(*it);
+ LLSD value;
+ value["tooltip"] = it->getToolTip();
+ //location history can contain only typed locations
+ value["item_type"] = TYPED_REGION_SURL;
+ value["global_pos"] = it->mGlobalPos.getValue();
+ add(it->getLocation(), value);
}
}
diff --git a/indra/newview/lllocationinputctrl.h b/indra/newview/lllocationinputctrl.h
index d967df8257..3c43e1a321 100644
--- a/indra/newview/lllocationinputctrl.h
+++ b/indra/newview/lllocationinputctrl.h
@@ -41,6 +41,7 @@ class LLLandmark;
class LLAddLandmarkObserver;
class LLRemoveLandmarkObserver;
class LLMenuGL;
+class LLTeleportHistoryItem;
/**
* Location input control.
@@ -103,6 +104,7 @@ private:
void refresh();
void refreshLocation();
void rebuildLocationHistory(std::string filter = "");
+ bool findTeleportItemsByTitle(const LLTeleportHistoryItem& item, const std::string& filter);
void setText(const LLStringExplicit& text);
void updateAddLandmarkButton();
void updateContextMenu();
diff --git a/indra/newview/llnavigationbar.cpp b/indra/newview/llnavigationbar.cpp
index 28e9c93779..c283b3a05f 100644
--- a/indra/newview/llnavigationbar.cpp
+++ b/indra/newview/llnavigationbar.cpp
@@ -45,7 +45,7 @@
#include "lllocationhistory.h"
#include "lllocationinputctrl.h"
#include "llteleporthistory.h"
-#include "llsearcheditor.h"
+#include "llsearchcombobox.h"
#include "llsidetray.h"
#include "llslurl.h"
#include "llurlsimstring.h"
@@ -82,7 +82,6 @@ public:
Mandatory<EType> item_type;
Params() {}
- Params(EType type, std::string title);
};
/*virtual*/ void draw();
@@ -104,24 +103,21 @@ private:
const std::string LLTeleportHistoryMenuItem::ICON_IMG_BACKWARD("teleport_history_backward.tga");
const std::string LLTeleportHistoryMenuItem::ICON_IMG_FORWARD("teleport_history_forward.tga");
-LLTeleportHistoryMenuItem::Params::Params(EType type, std::string title)
-{
- item_type(type);
- font.name("SANSSERIF");
-
- if (type == TYPE_CURRENT)
- font.style("BOLD");
- else
- title = " " + title;
-
- name(title);
- label(title);
-}
-
LLTeleportHistoryMenuItem::LLTeleportHistoryMenuItem(const Params& p)
: LLMenuItemCallGL(p),
mArrowIcon(NULL)
{
+ // Set appearance depending on the item type.
+ if (p.item_type == TYPE_CURRENT)
+ {
+ setFont(LLFontGL::getFontSansSerifBold());
+ }
+ else
+ {
+ setFont(LLFontGL::getFontSansSerif());
+ setLabel(std::string(" ") + std::string(p.label));
+ }
+
LLIconCtrl::Params icon_params;
icon_params.name("icon");
icon_params.rect(LLRect(0, ICON_HEIGHT, ICON_WIDTH, 0));
@@ -183,14 +179,11 @@ LLNavigationBar::LLNavigationBar()
mBtnForward(NULL),
mBtnHome(NULL),
mCmbLocation(NULL),
- mLeSearch(NULL),
+ mSearchComboBox(NULL),
mPurgeTPHistoryItems(false)
{
setIsChrome(TRUE);
- mParcelMgrConnection = LLViewerParcelMgr::getInstance()->setTeleportFinishedCallback(
- boost::bind(&LLNavigationBar::onTeleportFinished, this, _1));
-
LLUICtrlFactory::getInstance()->buildPanel(this, "panel_navigation_bar.xml");
// set a listener function for LoginComplete event
@@ -202,8 +195,10 @@ LLNavigationBar::LLNavigationBar()
LLNavigationBar::~LLNavigationBar()
{
- mParcelMgrConnection.disconnect();
+ mTeleportFinishConnection.disconnect();
sInstance = 0;
+
+ LLSearchHistory::getInstance()->save();
}
BOOL LLNavigationBar::postBuild()
@@ -213,10 +208,12 @@ BOOL LLNavigationBar::postBuild()
mBtnHome = getChild<LLButton>("home_btn");
mCmbLocation= getChild<LLLocationInputCtrl>("location_combo");
- mLeSearch = getChild<LLSearchEditor>("search_input");
+ mSearchComboBox = getChild<LLSearchComboBox>("search_combo_box");
+
+ fillSearchComboBox();
if (!mBtnBack || !mBtnForward || !mBtnHome ||
- !mCmbLocation || !mLeSearch)
+ !mCmbLocation || !mSearchComboBox)
{
llwarns << "Malformed navigation bar" << llendl;
return FALSE;
@@ -234,7 +231,7 @@ BOOL LLNavigationBar::postBuild()
mCmbLocation->setSelectionCallback(boost::bind(&LLNavigationBar::onLocationSelection, this));
- mLeSearch->setCommitCallback(boost::bind(&LLNavigationBar::onSearchCommit, this));
+ mSearchComboBox->setCommitCallback(boost::bind(&LLNavigationBar::onSearchCommit, this));
mDefaultNbRect = getRect();
mDefaultFpRect = getChild<LLFavoritesBarCtrl>("favorite")->getRect();
@@ -246,6 +243,25 @@ BOOL LLNavigationBar::postBuild()
return TRUE;
}
+void LLNavigationBar::fillSearchComboBox()
+{
+ if(!mSearchComboBox)
+ {
+ return;
+ }
+
+ LLSearchHistory::getInstance()->load();
+
+ LLSearchHistory::search_history_list_t search_list =
+ LLSearchHistory::getInstance()->getSearchHistoryList();
+ LLSearchHistory::search_history_list_t::const_iterator it = search_list.begin();
+ for( ; search_list.end() != it; ++it)
+ {
+ LLSearchHistory::LLSearchHistoryItem item = *it;
+ mSearchComboBox->add(item.search_query);
+ }
+}
+
void LLNavigationBar::draw()
{
if(mPurgeTPHistoryItems)
@@ -280,7 +296,12 @@ void LLNavigationBar::onHomeButtonClicked()
void LLNavigationBar::onSearchCommit()
{
- invokeSearch(mLeSearch->getValue().asString());
+ std::string search_query = mSearchComboBox->getValue().asString();
+ if(!search_query.empty())
+ {
+ LLSearchHistory::getInstance()->addEntry(search_query);
+ invokeSearch(mSearchComboBox->getValue().asString());
+ }
}
void LLNavigationBar::onTeleportHistoryMenuItemClicked(const LLSD& userdata)
@@ -299,69 +320,107 @@ void LLNavigationBar::onLocationSelection()
if (typed_location.empty())
return;
+ LLSD value = mCmbLocation->getSelectedValue();
+
+ if(value.has("item_type"))
+ {
+
+ switch(value["item_type"].asInteger())
+ {
+ case LANDMARK:
+
+ if(value.has("AssetUUID"))
+ {
+
+ gAgent.teleportViaLandmark( LLUUID(value["AssetUUID"].asString()));
+ return;
+ }
+ else
+ {
+ LLInventoryModel::item_array_t landmark_items =
+ LLLandmarkActions::fetchLandmarksByName(typed_location,
+ FALSE);
+ if (!landmark_items.empty())
+ {
+ gAgent.teleportViaLandmark( landmark_items[0]->getAssetUUID());
+ return;
+ }
+ }
+ break;
+
+ case TELEPORT_HISTORY:
+ //in case of teleport item was selected, teleport by position too.
+ case TYPED_REGION_SURL:
+ if(value.has("global_pos"))
+ {
+ gAgent.teleportViaLocation(LLVector3d(value["global_pos"]));
+ return;
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+ //Let's parse surl or region name
+
std::string region_name;
LLVector3 local_coords(128, 128, 0);
S32 x = 0, y = 0, z = 0;
-
// Is the typed location a SLURL?
if (LLSLURL::isSLURL(typed_location))
{
// Yes. Extract region name and local coordinates from it.
if (LLURLSimString::parse(LLSLURL::stripProtocol(typed_location), &region_name, &x, &y, &z))
- local_coords.set(x, y, z);
+ local_coords.set(x, y, z);
else
return;
- }
- else
+ }else
{
- //If it is not slurl let's look for landmarks
- LLInventoryModel::item_array_t landmark_items = LLLandmarkActions::fetchLandmarksByName(typed_location, FALSE);
- if ( !landmark_items.empty() )
- {
- gAgent.teleportViaLandmark(landmark_items[0]->getAssetUUID());
- return;
- }
- //No landmark match, check if it is a region name
- region_name = parseLocation(typed_location, &x, &y, &z);
- if (region_name != typed_location)
- local_coords.set(x, y, z);
-
- // Treat it as region name.
- // region_name = typed_location;
+ // assume that an user has typed the {region name} or possible {region_name, parcel}
+ region_name = typed_location.substr(0,typed_location.find(','));
}
-
+
// Resolve the region name to its global coordinates.
// If resolution succeeds we'll teleport.
LLWorldMap::url_callback_t cb = boost::bind(
&LLNavigationBar::onRegionNameResponse, this,
typed_location, region_name, local_coords, _1, _2, _3, _4);
+ // connect the callback each time, when user enter new location to get real location of agent after teleport
+ mTeleportFinishConnection = LLViewerParcelMgr::getInstance()->
+ setTeleportFinishedCallback(boost::bind(&LLNavigationBar::onTeleportFinished, this, _1,typed_location));
+
LLWorldMap::getInstance()->sendNamedRegionRequest(region_name, cb, std::string("unused"), false);
}
-void LLNavigationBar::onTeleportFinished(const LLVector3d& global_agent_pos)
+void LLNavigationBar::onTeleportFinished(const LLVector3d& global_agent_pos, const std::string& typed_location)
{
// Location is valid. Add it to the typed locations history.
LLLocationHistory* lh = LLLocationHistory::getInstance();
+ //TODO*: do we need convert surl into readable format?
std::string location;
/*NOTE:
* We can't use gAgent.getPositionAgent() in case of local teleport to build location.
* At this moment gAgent.getPositionAgent() contains previous coordinates.
* according to EXT-65 agent position is being reseted on each frame.
*/
- LLAgentUI::buildLocationString(location, LLAgentUI::LOCATION_FORMAT_WITHOUT_SIM,
- gAgent.getPosAgentFromGlobal(global_agent_pos));
+ LLAgentUI::buildLocationString(location, LLAgentUI::LOCATION_FORMAT_WITHOUT_SIM,
+ gAgent.getPosAgentFromGlobal(global_agent_pos));
+ std::string tooltip (LLSLURL::buildSLURLfromPosGlobal(gAgent.getRegion()->getName(), global_agent_pos, false));
+ LLLocationHistoryItem item (location,
+ global_agent_pos, tooltip,TYPED_REGION_SURL);// we can add into history only TYPED location
//Touch it, if it is at list already, add new location otherwise
- if ( !lh->touchItem(location) ) {
- std::string tooltip = LLSLURL::buildSLURLfromPosGlobal(
- gAgent.getRegion()->getName(), global_agent_pos, false);
-
- lh->addItem(location, tooltip);
+ if ( !lh->touchItem(item) ) {
+ lh->addItem(item);
}
- llinfos << "Saving after on teleport finish" << llendl;
- lh->save();
+ lh->save();
+
+ if(mTeleportFinishConnection.connected())
+ mTeleportFinishConnection.disconnect();
+
}
void LLNavigationBar::onTeleportHistoryChanged()
@@ -411,7 +470,9 @@ void LLNavigationBar::rebuildTeleportHistoryMenu()
else
type = LLTeleportHistoryMenuItem::TYPE_CURRENT;
- LLTeleportHistoryMenuItem::Params item_params(type, hist_items[i].getTitle());
+ LLTeleportHistoryMenuItem::Params item_params;
+ item_params.label = item_params.name = hist_items[i].getTitle();
+ item_params.item_type = type;
item_params.on_click.function(boost::bind(&LLNavigationBar::onTeleportHistoryMenuItemClicked, this, i));
LLTeleportHistoryMenuItem* new_itemp = LLUICtrlFactory::create<LLTeleportHistoryMenuItem>(item_params);
//new_itemp->setFont()
@@ -435,8 +496,8 @@ void LLNavigationBar::onRegionNameResponse(
// Teleport to the location.
LLVector3d region_pos = from_region_handle(region_handle);
LLVector3d global_pos = region_pos + (LLVector3d) local_coords;
-
- llinfos << "Teleporting to: " << global_pos << llendl;
+
+ llinfos << "Teleporting to: " << LLSLURL::buildSLURLfromPosGlobal(region_name, global_pos, false) << llendl;
gAgent.teleportViaLocation(global_pos);
}
@@ -474,35 +535,6 @@ void LLNavigationBar::invokeSearch(std::string search_text)
LLFloaterReg::showInstance("search", LLSD().insert("panel", "all").insert("id", LLSD(search_text)));
}
-std::string LLNavigationBar::parseLocation(const std::string & location, S32* x, S32* y, S32* z) {
- /*
- * This regular expression extracts numbers from the following string
- * construct: "(num1, num2, num3)", where num1, num2 and num3 are decimal
- * numbers. Leading and trailing spaces are also caught by the expression.
- */
- const boost::regex re("\\s*\\((\\d+),\\s*(\\d+),\\s*(\\d+)\\)\\s*");
-
- boost::smatch m;
- if (boost::regex_search(location, m, re)) {
- // string representations of parsed by regex++ numbers
- std::string xstr(m[1].first, m[1].second);
- std::string ystr(m[2].first, m[2].second);
- std::string zstr(m[3].first, m[3].second);
-
- *x = atoi(xstr.c_str());
- *y = atoi(ystr.c_str());
- *z = atoi(zstr.c_str());
- //erase commas in coordinates
- std::string region_parcel = boost::regex_replace(location, re, "");
- // cut region name
- return region_parcel.substr(0, region_parcel.find_first_of(','));
- }
-
- *x = *y = *z = 0;
-
- return location;
-}
-
void LLNavigationBar::clearHistoryCache()
{
mCmbLocation->removeall();
diff --git a/indra/newview/llnavigationbar.h b/indra/newview/llnavigationbar.h
index 6932847854..8a65cd24fa 100644
--- a/indra/newview/llnavigationbar.h
+++ b/indra/newview/llnavigationbar.h
@@ -41,6 +41,7 @@ class LLButton;
class LLLocationInputCtrl;
class LLMenuGL;
class LLSearchEditor;
+class LLSearchComboBox;
/**
* Web browser-like navigation bar.
@@ -69,12 +70,6 @@ private:
void rebuildTeleportHistoryMenu();
void showTeleportHistoryMenu();
void invokeSearch(std::string search_text);
-
- /**
- * Get region name and local coordinates from typed location
- */
- static std::string parseLocation(const std::string & location, S32* x, S32* y, S32* z);
-
// callbacks
void onTeleportHistoryMenuItemClicked(const LLSD& userdata);
void onTeleportHistoryChanged();
@@ -86,7 +81,7 @@ private:
void onLocationSelection();
void onLocationPrearrange(const LLSD& data);
void onSearchCommit();
- void onTeleportFinished(const LLVector3d& global_agent_pos);
+ void onTeleportFinished(const LLVector3d& global_agent_pos, const std::string& typed_location);
void onRegionNameResponse(
std::string typed_location,
std::string region_name,
@@ -94,17 +89,19 @@ private:
U64 region_handle, const std::string& url,
const LLUUID& snapshot_id, bool teleport);
+ void fillSearchComboBox();
+
static LLNavigationBar *sInstance;
LLMenuGL* mTeleportHistoryMenu;
LLButton* mBtnBack;
LLButton* mBtnForward;
LLButton* mBtnHome;
- LLSearchEditor* mLeSearch;
+ LLSearchComboBox* mSearchComboBox;
LLLocationInputCtrl* mCmbLocation;
LLRect mDefaultNbRect;
LLRect mDefaultFpRect;
- boost::signals2::connection mParcelMgrConnection;
+ boost::signals2::connection mTeleportFinishConnection;
bool mPurgeTPHistoryItems;
};
diff --git a/indra/newview/llpanelavatar.cpp b/indra/newview/llpanelavatar.cpp
index b2d606ab4d..fd3519bf4b 100644
--- a/indra/newview/llpanelavatar.cpp
+++ b/indra/newview/llpanelavatar.cpp
@@ -372,7 +372,6 @@ void LLPanelAvatarProfile::resetControls()
childSetVisible("status_me_panel", false);
childSetVisible("profile_me_buttons_panel", false);
childSetVisible("account_actions_panel", false);
- childSetVisible("partner_edit_link", false);
}
void LLPanelAvatarProfile::resetData()
@@ -539,7 +538,7 @@ void LLPanelAvatarProfile::fillAccountStatus(const LLAvatarData* avatar_data)
childSetValue("acc_status_text", caption_text);
}
-void LLPanelAvatarProfile::onUrlTextboxClicked(std::string url)
+void LLPanelAvatarProfile::onUrlTextboxClicked(const std::string& url)
{
LLWeb::loadURL(url);
}
@@ -675,4 +674,3 @@ void LLPanelAvatarMeProfile::onStatusMessageChanged()
{
updateData();
}
-
diff --git a/indra/newview/llpanelavatar.h b/indra/newview/llpanelavatar.h
index 4ee4cb6e87..1ed5fa4357 100644
--- a/indra/newview/llpanelavatar.h
+++ b/indra/newview/llpanelavatar.h
@@ -166,7 +166,7 @@ protected:
*/
virtual void fillAccountStatus(const LLAvatarData* avatar_data);
- void onUrlTextboxClicked(std::string url);
+ void onUrlTextboxClicked(const std::string& url);
void onHomepageTextboxClicked();
void onAddFriendButtonClick();
void onIMButtonClick();
diff --git a/indra/newview/llpanelblockedlist.cpp b/indra/newview/llpanelblockedlist.cpp
new file mode 100644
index 0000000000..60d0f07285
--- /dev/null
+++ b/indra/newview/llpanelblockedlist.cpp
@@ -0,0 +1,279 @@
+/**
+ * @file llpanelblockedlist.cpp
+ * @brief Container for blocked Residents & Objects list
+ *
+ * $LicenseInfo:firstyear=2001&license=viewergpl$
+ *
+ * Copyright (c) 2001-2009, Linden Research, Inc.
+ *
+ * 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
+ *
+ * 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
+ *
+ * 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.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llfloater.h"
+#include "llfloaterreg.h"
+#include "llscrolllistctrl.h"
+
+#include "llpanelblockedlist.h"
+
+// project include
+#include "llfloateravatarpicker.h"
+#include "llsidetray.h"
+#include "llsidetraypanelcontainer.h"
+
+static LLRegisterPanelClassWrapper<LLPanelBlockedList> t_panel_blocked_list("panel_block_list_sidetray");
+
+//
+// Constants
+//
+const std::string BLOCKED_PARAM_NAME = "blocked_to_select";
+
+//-----------------------------------------------------------------------------
+// LLPanelBlockedList()
+//-----------------------------------------------------------------------------
+
+LLPanelBlockedList::LLPanelBlockedList()
+: LLPanel()
+{
+ mCommitCallbackRegistrar.add("Block.ClickPick", boost::bind(&LLPanelBlockedList::onPickBtnClick, this));
+ mCommitCallbackRegistrar.add("Block.ClickBlockByName", boost::bind(&LLPanelBlockedList::onBlockByNameClick, this));
+ mCommitCallbackRegistrar.add("Block.ClickRemove", boost::bind(&LLPanelBlockedList::onRemoveBtnClick, this));
+}
+
+LLPanelBlockedList::~LLPanelBlockedList()
+{
+ LLMuteList::getInstance()->removeObserver(this);
+}
+
+BOOL LLPanelBlockedList::postBuild()
+{
+ mBlockedList = getChild<LLScrollListCtrl>("blocked");
+ mBlockedList->setCommitOnSelectionChange(TRUE);
+
+ childSetCommitCallback("back", boost::bind(&LLPanelBlockedList::onBackBtnClick, this), NULL);
+
+ LLMuteList::getInstance()->addObserver(this);
+
+ refreshBlockedList();
+
+ return LLPanel::postBuild();
+}
+
+void LLPanelBlockedList::draw()
+{
+ updateButtons();
+ LLPanel::draw();
+}
+
+void LLPanelBlockedList::onOpen(const LLSD& key)
+{
+ if (key.has(BLOCKED_PARAM_NAME) && key[BLOCKED_PARAM_NAME].asUUID().notNull())
+ {
+ selectBlocked(key[BLOCKED_PARAM_NAME].asUUID());
+ }
+}
+
+void LLPanelBlockedList::selectBlocked(const LLUUID& mute_id)
+{
+ mBlockedList->selectByID(mute_id);
+}
+
+void LLPanelBlockedList::showPanelAndSelect(const LLUUID& idToSelect)
+{
+ LLSideTray::getInstance()->showPanel("panel_block_list_sidetray", LLSD().insert(BLOCKED_PARAM_NAME, idToSelect));
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+// Private Section
+//////////////////////////////////////////////////////////////////////////
+void LLPanelBlockedList::refreshBlockedList()
+{
+ mBlockedList->deleteAllItems();
+
+ std::vector<LLMute> mutes = LLMuteList::getInstance()->getMutes();
+ std::vector<LLMute>::iterator it;
+ for (it = mutes.begin(); it != mutes.end(); ++it)
+ {
+ std::string display_name = it->getDisplayName();
+ mBlockedList->addStringUUIDItem(display_name, it->mID, ADD_BOTTOM, TRUE);
+ }
+}
+
+void LLPanelBlockedList::updateButtons()
+{
+ bool hasSelected = NULL != mBlockedList->getFirstSelected();
+ childSetEnabled("Unblock", hasSelected);
+}
+
+
+
+void LLPanelBlockedList::onBackBtnClick()
+{
+ LLSideTrayPanelContainer* parent = dynamic_cast<LLSideTrayPanelContainer*>(getParent());
+ if(parent)
+ {
+ parent->openPreviousPanel();
+ }
+}
+
+void LLPanelBlockedList::onRemoveBtnClick()
+{
+ std::string name = mBlockedList->getSelectedItemLabel();
+ LLUUID id = mBlockedList->getStringUUIDSelectedItem();
+ LLMute mute(id);
+ mute.setFromDisplayName(name);
+ // now mute.mName has the suffix trimmed off
+
+ S32 last_selected = mBlockedList->getFirstSelectedIndex();
+ if (LLMuteList::getInstance()->remove(mute))
+ {
+ // Above removals may rebuild this dialog.
+
+ if (last_selected == mBlockedList->getItemCount())
+ {
+ // we were on the last item, so select the last item again
+ mBlockedList->selectNthItem(last_selected - 1);
+ }
+ else
+ {
+ // else select the item after the last item previously selected
+ mBlockedList->selectNthItem(last_selected);
+ }
+ }
+}
+
+void LLPanelBlockedList::onPickBtnClick()
+{
+ const BOOL allow_multiple = FALSE;
+ const BOOL close_on_select = TRUE;
+ /*LLFloaterAvatarPicker* picker = */LLFloaterAvatarPicker::show(callbackBlockPicked, this, allow_multiple, close_on_select);
+
+ // *TODO: mantipov: should LLFloaterAvatarPicker be closed when panel is closed?
+ // old Floater dependency is not enable in panel
+ // addDependentFloater(picker);
+}
+
+void LLPanelBlockedList::onBlockByNameClick()
+{
+ LLFloaterGetBlockedObjectName::show(&LLPanelBlockedList::callbackBlockByName);
+}
+
+//static
+void LLPanelBlockedList::callbackBlockPicked(const std::vector<std::string>& names, const std::vector<LLUUID>& ids, void* user_data)
+{
+ if (names.empty() || ids.empty()) return;
+ LLMute mute(ids[0], names[0], LLMute::AGENT);
+ LLMuteList::getInstance()->add(mute);
+ showPanelAndSelect(mute.mID);
+}
+
+//static
+void LLPanelBlockedList::callbackBlockByName(const std::string& text)
+{
+ if (text.empty()) return;
+
+ LLMute mute(LLUUID::null, text, LLMute::BY_NAME);
+ BOOL success = LLMuteList::getInstance()->add(mute);
+ if (!success)
+ {
+ LLNotifications::instance().add("MuteByNameFailed");
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+// LLFloaterGetBlockedObjectName
+//////////////////////////////////////////////////////////////////////////
+
+// Constructor/Destructor
+LLFloaterGetBlockedObjectName::LLFloaterGetBlockedObjectName(const LLSD& key)
+: LLFloater(key)
+, mGetObjectNameCallback(NULL)
+{
+}
+
+// Destroys the object
+LLFloaterGetBlockedObjectName::~LLFloaterGetBlockedObjectName()
+{
+ gFocusMgr.releaseFocusIfNeeded( this );
+}
+
+BOOL LLFloaterGetBlockedObjectName::postBuild()
+{
+ getChild<LLButton>("OK")-> setCommitCallback(boost::bind(&LLFloaterGetBlockedObjectName::applyBlocking, this));
+ getChild<LLButton>("Cancel")-> setCommitCallback(boost::bind(&LLFloaterGetBlockedObjectName::cancelBlocking, this));
+ center();
+
+ return LLFloater::postBuild();
+}
+
+BOOL LLFloaterGetBlockedObjectName::handleKeyHere(KEY key, MASK mask)
+{
+ if (key == KEY_RETURN && mask == MASK_NONE)
+ {
+ applyBlocking();
+ return TRUE;
+ }
+ else if (key == KEY_ESCAPE && mask == MASK_NONE)
+ {
+ cancelBlocking();
+ return TRUE;
+ }
+
+ return LLFloater::handleKeyHere(key, mask);
+}
+
+// static
+LLFloaterGetBlockedObjectName* LLFloaterGetBlockedObjectName::show(get_object_name_callback_t callback)
+{
+ LLFloaterGetBlockedObjectName* floater = LLFloaterReg::showTypedInstance<LLFloaterGetBlockedObjectName>("mute_object_by_name");
+
+ floater->mGetObjectNameCallback = callback;
+
+ // *TODO: mantipov: should LLFloaterGetBlockedObjectName be closed when panel is closed?
+ // old Floater dependency is not enable in panel
+ // addDependentFloater(floater);
+
+ return floater;
+}
+
+//////////////////////////////////////////////////////////////////////////
+// Private Section
+void LLFloaterGetBlockedObjectName::applyBlocking()
+{
+ if (mGetObjectNameCallback)
+ {
+ const std::string& text = childGetValue("object_name").asString();
+ mGetObjectNameCallback(text);
+ }
+ closeFloater();
+}
+
+void LLFloaterGetBlockedObjectName::cancelBlocking()
+{
+ closeFloater();
+}
+
+//EOF
diff --git a/indra/newview/llpanelblockedlist.h b/indra/newview/llpanelblockedlist.h
new file mode 100644
index 0000000000..52b74a184b
--- /dev/null
+++ b/indra/newview/llpanelblockedlist.h
@@ -0,0 +1,115 @@
+/**
+ * @file llpanelblockedlist.h
+ * @brief Container for blocked Residents & Objects list
+ *
+ * $LicenseInfo:firstyear=2002&license=viewergpl$
+ *
+ * Copyright (c) 2002-2009, Linden Research, Inc.
+ *
+ * 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
+ *
+ * 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
+ *
+ * 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.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLPANELBLOCKEDLIST_H
+#define LL_LLPANELBLOCKEDLIST_H
+
+#include "llpanel.h"
+#include "llmutelist.h"
+// #include <vector>
+
+// class LLButton;
+// class LLLineEditor;
+// class LLMessageSystem;
+// class LLUUID;
+ class LLScrollListCtrl;
+
+class LLPanelBlockedList
+ : public LLPanel, public LLMuteListObserver
+{
+public:
+ LLPanelBlockedList();
+ ~LLPanelBlockedList();
+
+ virtual BOOL postBuild();
+ virtual void draw();
+ virtual void onOpen(const LLSD& key);
+
+ void selectBlocked(const LLUUID& id);
+
+ /**
+ * Shows current Panel in side tray and select passed blocked item.
+ *
+ * @param idToSelect - LLUUID of blocked Resident or Object to be selected.
+ * If it is LLUUID::null, nothing will be selected.
+ */
+ static void showPanelAndSelect(const LLUUID& idToSelect);
+
+ // LLMuteListObserver callback interface implementation.
+ /* virtual */ void onChange() { refreshBlockedList();}
+
+private:
+ void refreshBlockedList();
+ void updateButtons();
+
+ // UI callbacks
+ void onBackBtnClick();
+ void onRemoveBtnClick();
+ void onPickBtnClick();
+ void onBlockByNameClick();
+
+ static void callbackBlockPicked(const std::vector<std::string>& names, const std::vector<LLUUID>& ids, void* user_data);
+ static void callbackBlockByName(const std::string& text);
+
+private:
+ LLScrollListCtrl* mBlockedList;
+};
+
+//-----------------------------------------------------------------------------
+// LLFloaterGetBlockedObjectName()
+//-----------------------------------------------------------------------------
+// Class for handling mute object by name floater.
+class LLFloaterGetBlockedObjectName : public LLFloater
+{
+ friend class LLFloaterReg;
+public:
+ typedef boost::function<void (const std::string&)> get_object_name_callback_t;
+
+ virtual BOOL postBuild();
+
+ virtual BOOL handleKeyHere(KEY key, MASK mask);
+
+ static LLFloaterGetBlockedObjectName* show(get_object_name_callback_t callback);
+
+private:
+ LLFloaterGetBlockedObjectName(const LLSD& key);
+ virtual ~LLFloaterGetBlockedObjectName();
+
+ // UI Callbacks
+ void applyBlocking();
+ void cancelBlocking();
+
+ get_object_name_callback_t mGetObjectNameCallback;
+};
+
+
+#endif // LL_LLPANELBLOCKEDLIST_H
diff --git a/indra/newview/llpanelpeople.cpp b/indra/newview/llpanelpeople.cpp
index 34d5ef8f86..42aa21c13e 100644
--- a/indra/newview/llpanelpeople.cpp
+++ b/indra/newview/llpanelpeople.cpp
@@ -43,12 +43,12 @@
// newview
#include "llagent.h"
+#include "llavataractions.h"
#include "llavatarlist.h"
#include "llcallingcard.h" // for LLAvatarTracker
#include "llfloateravatarpicker.h"
//#include "llfloaterminiinspector.h"
#include "llfriendcard.h"
-#include "llavataractions.h"
#include "llgroupactions.h"
#include "llgrouplist.h"
#include "llrecentpeople.h"
@@ -976,7 +976,6 @@ void LLPanelPeople::onRecentViewSortMenuItemClicked(const LLSD& userdata)
}
}
-
void LLPanelPeople::onCallButtonClicked()
{
// *TODO: not implemented yet
diff --git a/indra/newview/llpanelpicks.cpp b/indra/newview/llpanelpicks.cpp
index bd6ca4746c..c34038c672 100644
--- a/indra/newview/llpanelpicks.cpp
+++ b/indra/newview/llpanelpicks.cpp
@@ -54,6 +54,11 @@ static const std::string XML_BTN_INFO = "info_btn";
static const std::string XML_BTN_TELEPORT = "teleport_btn";
static const std::string XML_BTN_SHOW_ON_MAP = "show_on_map_btn";
+static const std::string PICK_ID("pick_id");
+static const std::string PICK_CREATOR_ID("pick_creator_id");
+static const std::string PICK_NAME("pick_name");
+
+
static LLRegisterPanelClassWrapper<LLPanelPicks> t_panel_picks("panel_picks");
//-----------------------------------------------------------------------------
@@ -97,19 +102,8 @@ void LLPanelPicks::processProperties(void* data, EAvatarProcessorType type)
gCacheName->getName(getAvatarId(),name,second_name);
childSetTextArg("pick_title", "[NAME]",name);
- // to restore selection of the same item later
- LLUUID pick_id_selected(LLUUID::null);
- if (getSelectedPickItem()) pick_id_selected = getSelectedPickItem()->getPickId();
-
mPicksList->clear();
- //*TODO move it somewhere else?
- childSetEnabled(XML_BTN_NEW, false);
- childSetEnabled(XML_BTN_DELETE, false);
- childSetEnabled(XML_BTN_INFO, false);
- childSetEnabled(XML_BTN_TELEPORT,!avatar_picks->picks_list.empty());
- childSetEnabled(XML_BTN_SHOW_ON_MAP,!avatar_picks->picks_list.empty());
-
LLAvatarPicks::picks_list_t::const_iterator it = avatar_picks->picks_list.begin();
for(; avatar_picks->picks_list.end() != it; ++it)
{
@@ -124,12 +118,18 @@ void LLPanelPicks::processProperties(void* data, EAvatarProcessorType type)
LLAvatarPropertiesProcessor::instance().addObserver(getAvatarId(), picture);
picture->update();
- mPicksList->addItem(picture);
- if (pick_id_selected != LLUUID::null &&
- pick_id == pick_id_selected) mPicksList->toggleSelection(picture);
+
+ LLSD pick_value = LLSD();
+ pick_value.insert(PICK_ID, pick_id);
+ pick_value.insert(PICK_NAME, pick_name);
+ pick_value.insert(PICK_CREATOR_ID, getAvatarId());
+
+ mPicksList->addItem(picture, pick_value);
picture->setDoubleClickCallback(boost::bind(&LLPanelPicks::onDoubleClickItem, this, _1));
picture->setRightMouseDownCallback(boost::bind(&LLPanelPicks::onRightMouseDownItem, this, _1, _2, _3, _4));
+ picture->setRightMouseUpCallback(boost::bind(&LLPanelPicks::updateButtons, this));
+ picture->setMouseUpCallback(boost::bind(&LLPanelPicks::updateButtons, this));
}
LLAvatarPropertiesProcessor::getInstance()->removeObserver(getAvatarId(),this);
@@ -140,10 +140,10 @@ void LLPanelPicks::processProperties(void* data, EAvatarProcessorType type)
LLPickItem* LLPanelPicks::getSelectedPickItem()
{
- std::list<LLPanel*> selected_items = mPicksList->getSelectedItems();
+ LLPanel* selected_item = mPicksList->getSelectedItem();
+ if (!selected_item) return NULL;
- if (selected_items.empty()) return NULL;
- return dynamic_cast<LLPickItem*>(selected_items.front());
+ return dynamic_cast<LLPickItem*>(selected_item);
}
BOOL LLPanelPicks::postBuild()
@@ -193,6 +193,10 @@ void LLPanelPicks::onOpen(const LLSD& key)
{
childSetVisible("pick_title", !self);
childSetVisible("pick_title_agent", self);
+
+ mPopupMenu->setItemVisible("pick_delete", TRUE);
+ mPopupMenu->setItemVisible("pick_edit", TRUE);
+ mPopupMenu->setItemVisible("pick_separator", TRUE);
}
LLPanelProfileTab::onOpen(key);
@@ -201,11 +205,11 @@ void LLPanelPicks::onOpen(const LLSD& key)
//static
void LLPanelPicks::onClickDelete()
{
- LLPickItem* pick_item = getSelectedPickItem();
- if (!pick_item) return;
+ LLSD pick_value = mPicksList->getSelectedValue();
+ if (pick_value.isUndefined()) return;
LLSD args;
- args["PICK"] = pick_item->getPickName();
+ args["PICK"] = pick_value[PICK_NAME];
LLNotifications::instance().add("DeleteAvatarPick", args, LLSD(), boost::bind(&LLPanelPicks::callbackDelete, this, _1, _2));
}
@@ -213,12 +217,12 @@ bool LLPanelPicks::callbackDelete(const LLSD& notification, const LLSD& response
{
S32 option = LLNotification::getSelectedOption(notification, response);
- LLPickItem* pick_item = getSelectedPickItem();
+ LLSD pick_value = mPicksList->getSelectedValue();
if (0 == option)
{
- LLAvatarPropertiesProcessor::instance().sendPickDelete(pick_item->getPickId());
- mPicksList->removeItem(pick_item);
+ LLAvatarPropertiesProcessor::instance().sendPickDelete(pick_value[PICK_ID]);
+ mPicksList->removeItemByValue(pick_value);
}
updateButtons();
return false;
@@ -265,32 +269,30 @@ void LLPanelPicks::onRightMouseDownItem(LLUICtrl* item, S32 x, S32 y, MASK mask)
void LLPanelPicks::onDoubleClickItem(LLUICtrl* item)
{
- LLPickItem* pick_item = dynamic_cast<LLPickItem*>(item);
- if (!pick_item) return;
+ LLSD pick_value = mPicksList->getSelectedValue();
+ if (pick_value.isUndefined()) return;
+
LLSD args;
- args["PICK"] = pick_item->getPickName();
+ args["PICK"] = pick_value[PICK_NAME];
LLNotifications::instance().add("TeleportToPick", args, LLSD(), boost::bind(&LLPanelPicks::callbackTeleport, this, _1, _2));
}
void LLPanelPicks::updateButtons()
{
int picks_num = mPicksList->size();
- childSetEnabled(XML_BTN_INFO, picks_num > 0);
+ bool has_selected = mPicksList->numSelected();
+
+ childSetEnabled(XML_BTN_INFO, has_selected);
if (getAvatarId() == gAgentID)
{
childSetEnabled(XML_BTN_NEW, picks_num < MAX_AVATAR_PICKS);
- childSetEnabled(XML_BTN_DELETE, picks_num > 0);
-
- //*TODO move somewhere this calls
- // we'd better set them up earlier when a panel was being constructed
- mPopupMenu->setItemVisible("pick_delete", TRUE);
- mPopupMenu->setItemVisible("pick_edit", TRUE);
- mPopupMenu->setItemVisible("pick_separator", TRUE);
+ childSetEnabled(XML_BTN_DELETE, has_selected);
}
- //*TODO update buttons like Show on Map, Teleport etc.
-
+ childSetEnabled(XML_BTN_INFO, has_selected);
+ childSetEnabled(XML_BTN_TELEPORT, has_selected);
+ childSetEnabled(XML_BTN_SHOW_ON_MAP, has_selected);
}
void LLPanelPicks::setProfilePanel(LLPanelProfile* profile_panel)
@@ -318,12 +320,12 @@ void LLPanelPicks::onClickNew()
void LLPanelPicks::onClickInfo()
{
- LLPickItem* pick = getSelectedPickItem();
- if (!pick) return;
+ LLSD selected_value = mPicksList->getSelectedValue();
+ if (selected_value.isUndefined()) return;
buildPickPanel();
mPickPanel->reset();
- mPickPanel->init(pick->getCreatorId(), pick->getPickId());
+ mPickPanel->init(selected_value[PICK_CREATOR_ID], selected_value[PICK_ID]);
getProfilePanel()->togglePanel(mPickPanel);
}
@@ -335,12 +337,12 @@ void LLPanelPicks::onClickBack()
void LLPanelPicks::onClickMenuEdit()
{
//*TODO, refactor - most of that is similar to onClickInfo
- LLPickItem* pick = getSelectedPickItem();
- if (!pick) return;
+ LLSD selected_value = mPicksList->getSelectedValue();
+ if (selected_value.isUndefined()) return;
buildPickPanel();
mPickPanel->reset();
- mPickPanel->init(pick->getCreatorId(), pick->getPickId());
+ mPickPanel->init(selected_value[PICK_CREATOR_ID], selected_value[PICK_ID]);
mPickPanel->setEditMode(TRUE);
getProfilePanel()->togglePanel(mPickPanel);
}
@@ -470,3 +472,17 @@ void LLPanelPicks::onClose()
getProfilePanel()->togglePanel(mPickPanel);
}
}
+
+BOOL LLPickItem::postBuild()
+{
+ setMouseEnterCallback(boost::bind(&LLPanelPick::childSetVisible, this, "hovered_icon", true));
+ setMouseLeaveCallback(boost::bind(&LLPanelPick::childSetVisible, this, "hovered_icon", false));
+ return TRUE;
+}
+
+void LLPickItem::setValue(const LLSD& value)
+{
+ if (!value.isMap()) return;;
+ if (!value.has("selected")) return;
+ childSetVisible("selected_icon", value["selected"]);
+}
diff --git a/indra/newview/llpanelpicks.h b/indra/newview/llpanelpicks.h
index 5860354902..97e8e607c8 100644
--- a/indra/newview/llpanelpicks.h
+++ b/indra/newview/llpanelpicks.h
@@ -152,6 +152,11 @@ public:
~LLPickItem();
+ /*virtual*/ BOOL postBuild();
+
+ /** setting on/off background icon to indicate selected state */
+ /*virtual*/ void setValue(const LLSD& value);
+
protected:
LLUUID mPickID;
diff --git a/indra/newview/llpanelplaceinfo.cpp b/indra/newview/llpanelplaceinfo.cpp
index 73e09a36f9..ec1c10d8c9 100644
--- a/indra/newview/llpanelplaceinfo.cpp
+++ b/indra/newview/llpanelplaceinfo.cpp
@@ -49,6 +49,7 @@
#include "lltextbox.h"
#include "llaccordionctrl.h"
+#include "llaccordionctrltab.h"
#include "llagent.h"
#include "llavatarpropertiesprocessor.h"
#include "llfloaterworldmap.h"
@@ -81,6 +82,8 @@ LLPanelPlaceInfo::~LLPanelPlaceInfo()
{
LLRemoteParcelInfoProcessor::getInstance()->removeObserver(mParcelID, this);
}
+
+ LLViewerParcelMgr::getInstance()->removeObserver(this);
}
BOOL LLPanelPlaceInfo::postBuild()
@@ -98,26 +101,16 @@ BOOL LLPanelPlaceInfo::postBuild()
mParcelName = getChild<LLTextBox>("parcel_title");
mDescEditor = getChild<LLTextEditor>("description");
- mMaturityRatingIcon = getChild<LLIconCtrl>("maturity");
mMaturityRatingText = getChild<LLTextBox>("maturity_value");
-
mParcelOwner = getChild<LLTextBox>("owner_value");
-
mLastVisited = getChild<LLTextBox>("last_visited_value");
- mRatingIcon = getChild<LLIconCtrl>("rating_icon");
mRatingText = getChild<LLTextBox>("rating_value");
- mVoiceIcon = getChild<LLIconCtrl>("voice_icon");
mVoiceText = getChild<LLTextBox>("voice_value");
- mFlyIcon = getChild<LLIconCtrl>("fly_icon");
mFlyText = getChild<LLTextBox>("fly_value");
- mPushIcon = getChild<LLIconCtrl>("push_icon");
mPushText = getChild<LLTextBox>("push_value");
- mBuildIcon = getChild<LLIconCtrl>("build_icon");
mBuildText = getChild<LLTextBox>("build_value");
- mScriptsIcon = getChild<LLIconCtrl>("scripts_icon");
mScriptsText = getChild<LLTextBox>("scripts_value");
- mDamageIcon = getChild<LLIconCtrl>("damage_icon");
mDamageText = getChild<LLTextBox>("damage_value");
mRegionNameText = getChild<LLTextBox>("region_name");
@@ -131,6 +124,16 @@ BOOL LLPanelPlaceInfo::postBuild()
mEstateOwnerText = getChild<LLTextBox>("estate_owner");
mCovenantText = getChild<LLTextEditor>("covenant");
+ mSalesPriceText = getChild<LLTextBox>("sales_price");
+ mAreaText = getChild<LLTextBox>("area");
+ mTrafficText = getChild<LLTextBox>("traffic");
+ mPrimitivesText = getChild<LLTextBox>("primitives");
+ mParcelScriptsText = getChild<LLTextBox>("parcel_scripts");
+ mTerraformLimitsText = getChild<LLTextBox>("terraform_limits");
+ mSubdivideText = getChild<LLTextEditor>("subdivide");
+ mResaleText = getChild<LLTextEditor>("resale");
+ mSaleToText = getChild<LLTextBox>("sale_to");
+
mOwner = getChild<LLTextBox>("owner");
mCreator = getChild<LLTextBox>("creator");
mCreated = getChild<LLTextBox>("created");
@@ -253,7 +256,6 @@ void LLPanelPlaceInfo::resetLocation()
mLandmarkID.setNull();
mPosRegion.clearVec();
std::string not_available = getString("not_available");
- mMaturityRatingIcon->setValue(not_available);
mMaturityRatingText->setValue(not_available);
mParcelOwner->setValue(not_available);
mLastVisited->setValue(not_available);
@@ -268,19 +270,12 @@ void LLPanelPlaceInfo::resetLocation()
mSnapshotCtrl->setImageAssetID(LLUUID::null);
mSnapshotCtrl->setFallbackImageName("default_land_picture.j2c");
- mRatingIcon->setValue(not_available);
mRatingText->setText(not_available);
- mVoiceIcon->setValue(not_available);
mVoiceText->setText(not_available);
- mFlyIcon->setValue(not_available);
mFlyText->setText(not_available);
- mPushIcon->setValue(not_available);
mPushText->setText(not_available);
- mBuildIcon->setValue(not_available);
mBuildText->setText(not_available);
- mScriptsIcon->setValue(not_available);
- mScriptsText->setText(not_available);
- mDamageIcon->setValue(not_available);
+ mParcelScriptsText->setText(not_available);
mDamageText->setText(not_available);
mRegionNameText->setValue(not_available);
@@ -293,6 +288,16 @@ void LLPanelPlaceInfo::resetLocation()
mEstateRatingText->setValue(not_available);
mEstateOwnerText->setValue(not_available);
mCovenantText->setValue(not_available);
+
+ mSalesPriceText->setValue(not_available);
+ mAreaText->setValue(not_available);
+ mTrafficText->setValue(not_available);
+ mPrimitivesText->setValue(not_available);
+ mParcelScriptsText->setValue(not_available);
+ mTerraformLimitsText->setValue(not_available);
+ mSubdivideText->setValue(not_available);
+ mResaleText->setValue(not_available);
+ mSaleToText->setValue(not_available);
}
//virtual
@@ -312,7 +317,6 @@ void LLPanelPlaceInfo::setInfoType(INFO_TYPE type)
bool is_info_type_teleport_history = type == TELEPORT_HISTORY;
getChild<LLTextBox>("maturity_label")->setVisible(!is_info_type_agent);
- mMaturityRatingIcon->setVisible(!is_info_type_agent);
mMaturityRatingText->setVisible(!is_info_type_agent);
getChild<LLTextBox>("owner_label")->setVisible(is_info_type_agent);
@@ -326,6 +330,8 @@ void LLPanelPlaceInfo::setInfoType(INFO_TYPE type)
getChild<LLAccordionCtrl>("advanced_info_accordion")->setVisible(is_info_type_agent);
+ LLViewerParcelMgr* parcel_mgr = LLViewerParcelMgr::getInstance();
+
switch(type)
{
case CREATE_LANDMARK:
@@ -333,6 +339,15 @@ void LLPanelPlaceInfo::setInfoType(INFO_TYPE type)
break;
case AGENT:
+ if (parcel_mgr)
+ {
+ // If information is requested for current agent location
+ // start using LLViewerParcelMgr for land selection.
+ parcel_mgr->addObserver(this);
+ parcel_mgr->selectParcelAt(gAgent.getPositionGlobal());
+ }
+
+ // Fall through to PLACE case
case PLACE:
mCurrentTitle = getString("title_place");
@@ -348,14 +363,22 @@ void LLPanelPlaceInfo::setInfoType(INFO_TYPE type)
case TELEPORT_HISTORY:
mCurrentTitle = getString("title_teleport_history");
-
- // *TODO: Add last visited timestamp.
- mLastVisited->setText(getString("unknown"));
break;
}
+ if (type != AGENT && parcel_mgr != NULL)
+ {
+ if (!parcel_mgr->selectionEmpty())
+ {
+ parcel_mgr->deselectUnused();
+ }
+ parcel_mgr->removeObserver(this);
+ }
+
if (type != PLACE)
toggleMediaPanel(FALSE);
+
+ mInfoType = type;
}
BOOL LLPanelPlaceInfo::isMediaPanelVisible()
@@ -432,22 +455,16 @@ void LLPanelPlaceInfo::processParcelInfo(const LLParcelData& parcel_data)
// HACK: Flag 0x2 == adult region,
// Flag 0x1 == mature region, otherwise assume PG
std::string rating = LLViewerRegion::accessToString(SIM_ACCESS_PG);
- std::string rating_icon = "places_rating_pg.tga";
if (parcel_data.flags & 0x2)
{
rating = LLViewerRegion::accessToString(SIM_ACCESS_ADULT);
- rating_icon = "places_rating_adult.tga";
}
else if (parcel_data.flags & 0x1)
{
rating = LLViewerRegion::accessToString(SIM_ACCESS_MATURE);
- rating_icon = "places_rating_mature.tga";
}
- mMaturityRatingIcon->setValue(rating_icon);
mMaturityRatingText->setValue(rating);
-
- mRatingIcon->setValue(rating_icon);
mRatingText->setValue(rating);
//update for_sale banner, here we should use DFQ_FOR_SALE instead of PF_FOR_SALE
@@ -476,7 +493,7 @@ void LLPanelPlaceInfo::processParcelInfo(const LLParcelData& parcel_data)
mRegionName->setText(name);
}
- if (mCurrentTitle != getString("title_landmark"))
+ if (mInfoType == CREATE_LANDMARK)
{
mTitleEditor->setText(parcel_data.name);
mNotesEditor->setText(LLStringUtil::null);
@@ -517,10 +534,10 @@ void LLPanelPlaceInfo::displayParcelInfo(const LLVector3& pos_region,
void LLPanelPlaceInfo::displayAgentParcelInfo()
{
- mPosRegion = gAgent.getPositionAgent();
+ mParcel = LLViewerParcelMgr::getInstance()->getFloatingParcelSelection();
- LLViewerRegion* region = gAgent.getRegion();
- LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
+ LLParcel* parcel = mParcel->getParcel();
+ LLViewerRegion* region = LLViewerParcelMgr::getInstance()->getSelectionRegion();
if (!region || !parcel)
return;
@@ -547,13 +564,6 @@ void LLPanelPlaceInfo::displayAgentParcelInfo()
default:
parcel_data.flags = 0;
}
-
- // Adding "For Sale" flag in remote parcel response format.
- if (parcel->getForSale())
- {
- parcel_data.flags |= DFQ_FOR_SALE;
- }
-
parcel_data.desc = parcel->getDesc();
parcel_data.name = parcel->getName();
parcel_data.sim_name = gAgent.getRegion()->getName();
@@ -563,75 +573,68 @@ void LLPanelPlaceInfo::displayAgentParcelInfo()
parcel_data.global_y = global_pos.mdV[1];
parcel_data.global_z = global_pos.mdV[2];
+ mPosRegion = gAgent.getPositionAgent();
+
processParcelInfo(parcel_data);
+ std::string on = getString("on");
+ std::string off = getString("off");
+
// Processing parcel characteristics
if (parcel->getParcelFlagAllowVoice())
{
- mVoiceIcon->setValue("places_voice_on.tga");
- mVoiceText->setText(getString("on"));
+ mVoiceText->setText(on);
}
else
{
- mVoiceIcon->setValue("places_voice_off.tga");
- mVoiceText->setText(getString("off"));
+ mVoiceText->setText(off);
}
if (!region->getBlockFly() && parcel->getAllowFly())
{
- mFlyIcon->setValue("places_fly_on.tga");
- mFlyText->setText(getString("on"));
+ mFlyText->setText(on);
}
else
{
- mFlyIcon->setValue("places_fly_off.tga");
- mFlyText->setText(getString("off"));
+ mFlyText->setText(off);
}
if (region->getRestrictPushObject() || parcel->getRestrictPushObject())
{
- mPushIcon->setValue("places_push_off.tga");
- mPushText->setText(getString("off"));
+ mPushText->setText(off);
}
else
{
- mPushIcon->setValue("places_push_on.tga");
- mPushText->setText(getString("on"));
+ mPushText->setText(on);
}
if (parcel->getAllowModify())
{
- mBuildIcon->setValue("places_build_on.tga");
- mBuildText->setText(getString("on"));
+ mBuildText->setText(on);
}
else
{
- mBuildIcon->setValue("places_build_off.tga");
- mBuildText->setText(getString("off"));
+ mBuildText->setText(off);
}
if((region->getRegionFlags() & REGION_FLAGS_SKIP_SCRIPTS) ||
(region->getRegionFlags() & REGION_FLAGS_ESTATE_SKIP_SCRIPTS) ||
!parcel->getAllowOtherScripts())
{
- mScriptsIcon->setValue("places_scripts_off.tga");
- mScriptsText->setText(getString("off"));
+ mScriptsText->setText(off);
}
else
{
- mScriptsIcon->setValue("places_scripts_on.tga");
- mScriptsText->setText(getString("on"));
+ mScriptsText->setText(on);
}
if (region->getAllowDamage() || parcel->getAllowDamage())
{
- mDamageIcon->setValue("places_damage_on.tga");
- mDamageText->setText(getString("on"));
+ mDamageText->setText(on);
}
else
{
- mDamageIcon->setValue("places_damage_off.tga");
- mDamageText->setText(getString("off"));
+ mDamageText->setText(off);
}
mRegionNameText->setText(region->getName());
@@ -656,7 +659,8 @@ void LLPanelPlaceInfo::displayAgentParcelInfo()
gCacheName->get(parcel->getGroupID(), TRUE,
boost::bind(&LLPanelPlaceInfo::nameUpdatedCallback, this, mRegionGroupText, _2, _3));
- mParcelOwner->setText(mRegionGroupText->getText());
+ gCacheName->get(parcel->getGroupID(), TRUE,
+ boost::bind(&LLPanelPlaceInfo::nameUpdatedCallback, this, mParcelOwner, _2, _3));
}
else
{
@@ -681,6 +685,98 @@ void LLPanelPlaceInfo::displayAgentParcelInfo()
}
mEstateRatingText->setText(region->getSimAccessString());
+
+ S32 area;
+ S32 claim_price;
+ S32 rent_price;
+ F32 dwell;
+ BOOL for_sale = parcel->getForSale();
+ LLViewerParcelMgr::getInstance()->getDisplayInfo(&area,
+ &claim_price,
+ &rent_price,
+ &for_sale,
+ &dwell);
+
+ if (for_sale)
+ {
+ // Adding "For Sale" flag in remote parcel response format.
+ parcel_data.flags |= DFQ_FOR_SALE;
+
+ const LLUUID& auth_buyer_id = parcel->getAuthorizedBuyerID();
+ if(auth_buyer_id.notNull())
+ {
+ gCacheName->get(auth_buyer_id, TRUE,
+ boost::bind(&LLPanelPlaceInfo::nameUpdatedCallback, this, mSaleToText, _2, _3));
+
+ // Show sales info to a specific person or a group he belongs to.
+ if (auth_buyer_id != gAgent.getID() && !gAgent.isInGroup(auth_buyer_id))
+ {
+ for_sale = FALSE;
+ }
+ }
+ else
+ {
+ mSaleToText->setText(getString("anyone"));
+ }
+
+ const U8* sign = (U8*)getString("price_text").c_str();
+ const U8* sqm = (U8*)getString("area_text").c_str();
+
+ mSalesPriceText->setText(llformat("%s%d ", sign, parcel->getSalePrice()));
+ mAreaText->setText(llformat("%d %s", area, sqm));
+ mTrafficText->setText(llformat("%.0f", dwell));
+
+ // Can't have more than region max tasks, regardless of parcel
+ // object bonus factor.
+ S32 primitives = llmin(llround(parcel->getMaxPrimCapacity() * parcel->getParcelPrimBonus()),
+ (S32)region->getMaxTasks());
+
+ const U8* available = (U8*)getString("available").c_str();
+ const U8* allocated = (U8*)getString("allocated").c_str();
+
+ mPrimitivesText->setText(llformat("%d %s, %d %s", primitives, available, parcel->getPrimCount(), allocated));
+
+ if (parcel->getAllowOtherScripts())
+ {
+ mParcelScriptsText->setText(getString("all_residents_text"));
+ }
+ else if (parcel->getAllowGroupScripts())
+ {
+ mParcelScriptsText->setText(getString("group_text"));
+ }
+ else
+ {
+ mParcelScriptsText->setText(off);
+ }
+
+ mTerraformLimitsText->setText(parcel->getAllowTerraform() ? on : off);
+
+ if (region->getRegionFlags() & REGION_FLAGS_ALLOW_PARCEL_CHANGES)
+ {
+ mSubdivideText->setText(getString("can_change"));
+ }
+ else
+ {
+ mSubdivideText->setText(getString("can_not_change"));
+ }
+ if (region->getRegionFlags() & REGION_FLAGS_BLOCK_LAND_RESELL)
+ {
+ mResaleText->setText(getString("can_not_resell"));
+ }
+ else
+ {
+ mResaleText->setText(getString("can_resell"));
+ }
+ }
+
+ getChild<LLAccordionCtrlTab>("sales_tab")->setVisible(for_sale);
+}
+
+// virtual
+void LLPanelPlaceInfo::changed()
+{
+ resetLocation();
+ displayAgentParcelInfo();
}
void LLPanelPlaceInfo::updateEstateName(const std::string& name)
@@ -698,6 +794,22 @@ void LLPanelPlaceInfo::updateCovenantText(const std::string &text)
mCovenantText->setText(text);
}
+void LLPanelPlaceInfo::updateLastVisitedText(const LLDate &date)
+{
+ if (date.isNull())
+ {
+ mLastVisited->setText(getString("unknown"));
+ }
+ else
+ {
+ std::string timeStr = getString("acquired_date");
+ LLSD substitution;
+ substitution["datetime"] = (S32) date.secondsSinceEpoch();
+ LLStringUtil::format (timeStr, substitution);
+ mLastVisited->setText(timeStr);
+ }
+}
+
void LLPanelPlaceInfo::onCommitTitleOrNote(LANDMARK_INFO_TYPE type)
{
LLInventoryItem* item = gInventory.getItem(mLandmarkID);
@@ -785,6 +897,7 @@ void LLPanelPlaceInfo::createPick(const LLVector3d& global_pos)
LLAvatarPropertiesProcessor::instance().sendDataUpdate(&pick_data, APT_PICK_INFO);
}
+// virtual
void LLPanelPlaceInfo::reshape(S32 width, S32 height, BOOL called_from_parent)
{
if (mMinHeight > 0 && mScrollingPanel != NULL)
@@ -794,3 +907,22 @@ void LLPanelPlaceInfo::reshape(S32 width, S32 height, BOOL called_from_parent)
LLView::reshape(width, height, called_from_parent);
}
+
+// virtual
+void LLPanelPlaceInfo::handleVisibilityChange (BOOL new_visibility)
+{
+ LLPanel::handleVisibilityChange(new_visibility);
+
+ LLViewerParcelMgr* parcel_mgr = LLViewerParcelMgr::getInstance();
+ if (!parcel_mgr)
+ return;
+
+ // Remove land selection when panel hides.
+ if (!new_visibility)
+ {
+ if (!parcel_mgr->selectionEmpty())
+ {
+ parcel_mgr->deselectLand();
+ }
+ }
+}
diff --git a/indra/newview/llpanelplaceinfo.h b/indra/newview/llpanelplaceinfo.h
index 0cdeaab2b7..60f35cd0c1 100644
--- a/indra/newview/llpanelplaceinfo.h
+++ b/indra/newview/llpanelplaceinfo.h
@@ -42,15 +42,17 @@
#include "llpanelmedia.h"
#include "llremoteparcelrequest.h"
+#include "llviewerparcelmgr.h"
class LLButton;
class LLInventoryItem;
class LLLineEditor;
+class LLParcelSelection;
class LLTextBox;
class LLTextEditor;
class LLTextureCtrl;
-class LLPanelPlaceInfo : public LLPanel, LLRemoteParcelInfoObserver
+class LLPanelPlaceInfo : public LLPanel, LLRemoteParcelInfoObserver, LLParcelObserver
{
public:
enum INFO_TYPE
@@ -105,9 +107,13 @@ public:
// without sending a request to the server.
void displayAgentParcelInfo();
+ // Called on parcel selection change by LLViewerParcelMgr.
+ /*virtual*/ void changed();
+
void updateEstateName(const std::string& name);
void updateEstateOwnerName(const std::string& name);
void updateCovenantText(const std::string &text);
+ void updateLastVisitedText(const LLDate &date);
void nameUpdatedCallback(LLTextBox* text,
const std::string& first,
@@ -115,6 +121,7 @@ public:
/*virtual*/ void processParcelInfo(const LLParcelData& parcel_data);
/*virtual*/ void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE);
+ /*virtual*/ void handleVisibilityChange (BOOL new_visibility);
private:
enum LANDMARK_INFO_TYPE
@@ -131,30 +138,23 @@ private:
LLVector3 mPosRegion;
std::string mCurrentTitle;
S32 mMinHeight;
+ INFO_TYPE mInfoType;
LLTextBox* mTitle;
LLTextureCtrl* mSnapshotCtrl;
LLTextBox* mRegionName;
LLTextBox* mParcelName;
LLTextEditor* mDescEditor;
- LLIconCtrl* mMaturityRatingIcon;
LLTextBox* mMaturityRatingText;
LLTextBox* mParcelOwner;
LLTextBox* mLastVisited;
- LLIconCtrl* mRatingIcon;
LLTextBox* mRatingText;
- LLIconCtrl* mVoiceIcon;
LLTextBox* mVoiceText;
- LLIconCtrl* mFlyIcon;
LLTextBox* mFlyText;
- LLIconCtrl* mPushIcon;
LLTextBox* mPushText;
- LLIconCtrl* mBuildIcon;
LLTextBox* mBuildText;
- LLIconCtrl* mScriptsIcon;
LLTextBox* mScriptsText;
- LLIconCtrl* mDamageIcon;
LLTextBox* mDamageText;
LLTextBox* mRegionNameText;
@@ -168,6 +168,16 @@ private:
LLTextBox* mEstateOwnerText;
LLTextEditor* mCovenantText;
+ LLTextBox* mSalesPriceText;
+ LLTextBox* mAreaText;
+ LLTextBox* mTrafficText;
+ LLTextBox* mPrimitivesText;
+ LLTextBox* mParcelScriptsText;
+ LLTextBox* mTerraformLimitsText;
+ LLTextEditor* mSubdivideText;
+ LLTextEditor* mResaleText;
+ LLTextBox* mSaleToText;
+
LLTextBox* mOwner;
LLTextBox* mCreator;
LLTextBox* mCreated;
@@ -176,6 +186,8 @@ private:
LLPanel* mScrollingPanel;
LLPanel* mInfoPanel;
LLMediaPanel* mMediaPanel;
+
+ LLSafeHandle<LLParcelSelection> mParcel;
};
#endif // LL_LLPANELPLACEINFO_H
diff --git a/indra/newview/llpanelplaces.cpp b/indra/newview/llpanelplaces.cpp
index 2aebfdabfa..bc740bd865 100644
--- a/indra/newview/llpanelplaces.cpp
+++ b/indra/newview/llpanelplaces.cpp
@@ -51,6 +51,7 @@
#include "llpanellandmarks.h"
#include "llpanelteleporthistory.h"
#include "llsidetray.h"
+#include "llteleporthistorystorage.h"
#include "lltoggleablemenu.h"
#include "llviewerinventory.h"
#include "llviewermenu.h"
@@ -172,8 +173,7 @@ void LLPanelPlaces::onOpen(const LLSD& key)
if (mPlaceInfoType == AGENT_INFO_TYPE)
{
mPlaceInfo->setInfoType(LLPanelPlaceInfo::AGENT);
- mPlaceInfo->displayAgentParcelInfo();
-
+
mPosGlobal = gAgent.getPositionGlobal();
}
else if (mPlaceInfoType == CREATE_LANDMARK_INFO_TYPE)
@@ -212,14 +212,15 @@ void LLPanelPlaces::onOpen(const LLSD& key)
{
S32 index = key["id"].asInteger();
- const LLTeleportHistory::slurl_list_t& hist_items =
- LLTeleportHistory::getInstance()->getItems();
+ const LLTeleportHistoryStorage::slurl_list_t& hist_items =
+ LLTeleportHistoryStorage::getInstance()->getItems();
mPosGlobal = hist_items[index].mGlobalPos;
mPlaceInfo->setInfoType(LLPanelPlaceInfo::TELEPORT_HISTORY);
+ mPlaceInfo->updateLastVisitedText(hist_items[index].mDate);
mPlaceInfo->displayParcelInfo(get_pos_local_from_global(mPosGlobal),
- hist_items[index].mRegionID,
+ LLUUID(),
mPosGlobal);
}
}
diff --git a/indra/newview/llpanelteleporthistory.cpp b/indra/newview/llpanelteleporthistory.cpp
index 8b378c33e3..df48ee5d08 100644
--- a/indra/newview/llpanelteleporthistory.cpp
+++ b/indra/newview/llpanelteleporthistory.cpp
@@ -37,6 +37,7 @@
#include "llpanelteleporthistory.h"
#include "llsidetray.h"
#include "llworldmap.h"
+#include "llteleporthistorystorage.h"
// Not yet implemented; need to remove buildPanel() from constructor when we switch
//static LLRegisterPanelClassWrapper<LLTeleportHistoryPanel> t_teleport_history("panel_teleport_history");
@@ -56,7 +57,7 @@ LLTeleportHistoryPanel::~LLTeleportHistoryPanel()
BOOL LLTeleportHistoryPanel::postBuild()
{
- mTeleportHistory = LLTeleportHistory::getInstance();
+ mTeleportHistory = LLTeleportHistoryStorage::getInstance();
if (mTeleportHistory)
{
mTeleportHistory->setHistoryChangedCallback(boost::bind(&LLTeleportHistoryPanel::showTeleportHistory, this));
@@ -92,9 +93,7 @@ void LLTeleportHistoryPanel::onShowOnMap()
S32 index = itemp->getColumn(LIST_INDEX)->getValue().asInteger();
- const LLTeleportHistory::slurl_list_t& hist_items = mTeleportHistory->getItems();
-
- LLVector3d global_pos = hist_items[index].mGlobalPos;
+ LLVector3d global_pos = mTeleportHistory->getItems()[index].mGlobalPos;
if (!global_pos.isExactlyZero())
{
@@ -153,7 +152,7 @@ void LLTeleportHistoryPanel::updateVerbs()
if (itemp)
{
index = itemp->getColumn(LIST_INDEX)->getValue().asInteger();
- cur_item = mTeleportHistory->getCurrentItemIndex();
+ cur_item = mTeleportHistory->getItems().size() - 1;
}
mTeleportBtn->setEnabled(index != cur_item);
@@ -162,13 +161,11 @@ void LLTeleportHistoryPanel::updateVerbs()
void LLTeleportHistoryPanel::showTeleportHistory()
{
- const LLTeleportHistory::slurl_list_t& hist_items = mTeleportHistory->getItems();
+ const LLTeleportHistoryStorage::slurl_list_t& hist_items = mTeleportHistory->getItems();
mHistoryItems->deleteAllItems();
- S32 cur_item = mTeleportHistory->getCurrentItemIndex();
-
- for (LLTeleportHistory::slurl_list_t::const_iterator iter = hist_items.begin();
+ for (LLTeleportHistoryStorage::slurl_list_t::const_iterator iter = hist_items.begin();
iter != hist_items.end(); ++iter)
{
std::string landmark_title = (*iter).mTitle;
@@ -181,7 +178,6 @@ void LLTeleportHistoryPanel::showTeleportHistory()
continue;
S32 index = iter - hist_items.begin();
-
LLSD row;
row["id"] = index;
@@ -201,14 +197,12 @@ void LLTeleportHistoryPanel::showTeleportHistory()
index_column["value"] = index;
mHistoryItems->addElement(row, ADD_TOP);
-
- if (cur_item == index)
- {
- LLScrollListItem* itemp = mHistoryItems->getItem(index);
- ((LLScrollListText*)itemp->getColumn(LIST_ITEM_TITLE))->setFontStyle(LLFontGL::BOLD);
- }
}
+ // Consider last item (most recent) as current
+ LLScrollListItem* itemp = mHistoryItems->getItem((S32)hist_items.size() - 1);
+ ((LLScrollListText*)itemp->getColumn(LIST_ITEM_TITLE))->setFontStyle(LLFontGL::BOLD);
+
updateVerbs();
}
diff --git a/indra/newview/llpanelteleporthistory.h b/indra/newview/llpanelteleporthistory.h
index 553385b37e..023b04c3fa 100644
--- a/indra/newview/llpanelteleporthistory.h
+++ b/indra/newview/llpanelteleporthistory.h
@@ -39,6 +39,8 @@
#include "llpanelplacestab.h"
#include "llteleporthistory.h"
+class LLTeleportHistoryStorage;
+
class LLTeleportHistoryPanel : public LLPanelPlacesTab
{
public:
@@ -65,7 +67,7 @@ private:
LIST_INDEX
};
- LLTeleportHistory* mTeleportHistory;
+ LLTeleportHistoryStorage* mTeleportHistory;
LLScrollListCtrl* mHistoryItems;
std::string mFilterSubString;
};
diff --git a/indra/newview/llscreenchannel.cpp b/indra/newview/llscreenchannel.cpp
index 68996673be..1fbe359295 100644
--- a/indra/newview/llscreenchannel.cpp
+++ b/indra/newview/llscreenchannel.cpp
@@ -88,9 +88,12 @@ void LLScreenChannel::reshape(S32 width, S32 height, BOOL called_from_parent)
//--------------------------------------------------------------------------
void LLScreenChannel::addToast(LLToast::Params p)
{
- bool store_toast = !mShowToasts && p.can_be_stored && mCanStoreToasts;
+ bool store_toast = false, show_toast = false;
- if(!mShowToasts && !store_toast)
+ show_toast = mShowToasts || p.force_show;
+ store_toast = !show_toast && p.can_be_stored && mCanStoreToasts;
+
+ if(!show_toast && !store_toast)
{
mOnRejectToast(p);
return;
@@ -106,7 +109,7 @@ void LLScreenChannel::addToast(LLToast::Params p)
new_toast_elem.toast->setOnToastHoverCallback(boost::bind(&LLScreenChannel::onToastHover, this, _1, _2));
}
- if(mShowToasts)
+ if(show_toast)
{
mToastList.push_back(new_toast_elem);
showToasts();
diff --git a/indra/newview/llsearchcombobox.cpp b/indra/newview/llsearchcombobox.cpp
new file mode 100644
index 0000000000..c903f40f3f
--- /dev/null
+++ b/indra/newview/llsearchcombobox.cpp
@@ -0,0 +1,250 @@
+/**
+ * @file llsearchcombobox.cpp
+ * @brief Search Combobox implementation
+ *
+ * $LicenseInfo:firstyear=2009&license=viewergpl$
+ *
+ * Copyright (c) 2009, Linden Research, Inc.
+ *
+ * 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
+ *
+ * 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
+ *
+ * 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.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+#include "llsearchcombobox.h"
+
+#include "llkeyboard.h"
+#include "lluictrlfactory.h"
+
+static LLDefaultChildRegistry::Register<LLSearchComboBox> r1("search_combo_box");
+
+class LLSearchHistoryBuilder
+{
+public:
+ LLSearchHistoryBuilder(LLSearchComboBox* combo_box, const std::string& filter);
+
+ virtual void buildSearchHistory();
+
+ virtual ~LLSearchHistoryBuilder(){}
+
+protected:
+
+ virtual bool filterSearchHistory();
+
+ LLSearchComboBox* mComboBox;
+ std::string mFilter;
+ LLSearchHistory::search_history_list_t mFilteredSearchHistory;
+};
+
+LLSearchComboBox::Params::Params()
+: search_button("search_button")
+, dropdown_button_visible("dropdown_button_visible", false)
+{
+}
+
+LLSearchComboBox::LLSearchComboBox(const Params&p)
+: LLComboBox(p)
+{
+ S32 btn_top = p.search_button.top_pad + p.search_button.rect.height;
+ S32 btn_right = p.search_button.rect.width + p.search_button.left_pad;
+ LLRect search_btn_rect(p.search_button.left_pad, btn_top, btn_right, p.search_button.top_pad);
+
+ LLButton::Params button_params(p.search_button);
+ button_params.name(std::string("search_btn"));
+ button_params.rect(search_btn_rect) ;
+ button_params.follows.flags(FOLLOWS_LEFT|FOLLOWS_TOP);
+ button_params.tab_stop(false);
+ button_params.click_callback.function(boost::bind(&LLSearchComboBox::onSelectionCommit, this));
+ mSearchButton = LLUICtrlFactory::create<LLButton>(button_params);
+ mTextEntry->addChild(mSearchButton);
+
+ setButtonVisible(p.dropdown_button_visible);
+ mTextEntry->setCommitCallback(boost::bind(&LLComboBox::onTextCommit, this, _2));
+ mTextEntry->setKeystrokeCallback(boost::bind(&LLComboBox::onTextEntry, this, _1), NULL);
+ setSelectionCallback(boost::bind(&LLSearchComboBox::onSelectionCommit, this));
+ setPrearrangeCallback(boost::bind(&LLSearchComboBox::onSearchPrearrange, this, _2));
+}
+
+void LLSearchComboBox::rebuildSearchHistory(const std::string& filter)
+{
+ LLSearchHistoryBuilder builder(this, filter);
+ builder.buildSearchHistory();
+}
+
+void LLSearchComboBox::onSearchPrearrange(const LLSD& data)
+{
+ std::string filter = data.asString();
+ rebuildSearchHistory(filter);
+
+ mList->mouseOverHighlightNthItem(-1); // Clear highlight on the last selected item.
+}
+
+void LLSearchComboBox::onTextEntry(LLLineEditor* line_editor)
+{
+ KEY key = gKeyboard->currentKey();
+
+ if (line_editor->getText().empty())
+ {
+ prearrangeList(); // resets filter
+ hideList();
+ }
+ // Typing? (moving cursor should not affect showing the list)
+ else if (key != KEY_LEFT && key != KEY_RIGHT && key != KEY_HOME && key != KEY_END)
+ {
+ prearrangeList(line_editor->getText());
+ if (mList->getItemCount() != 0)
+ {
+ showList();
+ focusTextEntry();
+ }
+ else
+ {
+ // Hide the list if it's empty.
+ hideList();
+ }
+ }
+ LLComboBox::onTextEntry(line_editor);
+}
+
+void LLSearchComboBox::focusTextEntry()
+{
+ // We can't use "mTextEntry->setFocus(TRUE)" instead because
+ // if the "select_on_focus" parameter is true it places the cursor
+ // at the beginning (after selecting text), thus screwing up updateSelection().
+ if (mTextEntry)
+ {
+ gFocusMgr.setKeyboardFocus(mTextEntry);
+ }
+}
+
+void LLSearchComboBox::hideList()
+{
+ LLComboBox::hideList();
+ if (mTextEntry && hasFocus())
+ focusTextEntry();
+}
+
+LLSearchComboBox::~LLSearchComboBox()
+{
+}
+
+void LLSearchComboBox::onSelectionCommit()
+{
+ std::string search_query = getSimple();
+ LLStringUtil::trim(search_query);
+ if(search_query.empty())
+ {
+ mTextEntry->setText(search_query);
+ setControlValue(search_query);
+
+ return;
+ }
+
+ remove(search_query);
+ add(search_query, ADD_TOP);
+ mTextEntry->setText(search_query);
+ setControlValue(search_query);
+
+ LLUICtrl::onCommit();
+}
+
+BOOL LLSearchComboBox::remove(const std::string& name)
+{
+ BOOL found = mList->selectItemByLabel(name, FALSE);
+
+ if (found)
+ {
+ LLScrollListItem* item = mList->getFirstSelected();
+ if (item)
+ {
+ LLComboBox::remove(mList->getItemIndex(item));
+ }
+ }
+
+ return found;
+}
+
+void LLSearchComboBox::clearHistory()
+{
+ removeall();
+ setTextEntry(LLStringUtil::null);
+}
+
+LLSearchHistoryBuilder::LLSearchHistoryBuilder(LLSearchComboBox* combo_box, const std::string& filter)
+: mComboBox(combo_box)
+, mFilter(filter)
+{
+}
+
+bool LLSearchHistoryBuilder::filterSearchHistory()
+{
+ // *TODO: an STL algorithm would look nicer
+ mFilteredSearchHistory.clear();
+
+ std::string filter_copy = mFilter;
+ LLStringUtil::toLower(filter_copy);
+
+ LLSearchHistory::search_history_list_t history =
+ LLSearchHistory::getInstance()->getSearchHistoryList();
+
+ LLSearchHistory::search_history_list_t::const_iterator it = history.begin();
+ for ( ; it != history.end(); ++it)
+ {
+ std::string search_query = (*it).search_query;
+ LLStringUtil::toLower(search_query);
+
+ if (search_query.find(filter_copy) != std::string::npos)
+ mFilteredSearchHistory.push_back(*it);
+ }
+
+ return mFilteredSearchHistory.size();
+}
+
+void LLSearchHistoryBuilder::buildSearchHistory()
+{
+ mFilteredSearchHistory.clear();
+
+ LLSearchHistory::search_history_list_t filtered_items;
+ LLSearchHistory::search_history_list_t* itemsp = NULL;
+ LLSearchHistory* sh = LLSearchHistory::getInstance();
+
+ if (mFilter.empty())
+ {
+ itemsp = &sh->getSearchHistoryList();
+ }
+ else
+ {
+ filterSearchHistory();
+ itemsp = &mFilteredSearchHistory;
+ itemsp->sort();
+ }
+
+ mComboBox->removeall();
+
+ LLSearchHistory::search_history_list_t::const_iterator it = itemsp->begin();
+ for ( ; it != itemsp->end(); it++)
+ {
+ LLSearchHistory::LLSearchHistoryItem item = *it;
+ mComboBox->add(item.search_query);
+ }
+}
diff --git a/indra/newview/llsearchcombobox.h b/indra/newview/llsearchcombobox.h
new file mode 100644
index 0000000000..38f9a5a26b
--- /dev/null
+++ b/indra/newview/llsearchcombobox.h
@@ -0,0 +1,108 @@
+/**
+ * @file llsearchcombobox.h
+ * @brief LLSearchComboBox class definition
+ *
+ * $LicenseInfo:firstyear=2009&license=viewergpl$
+ *
+ * Copyright (c) 2009, Linden Research, Inc.
+ *
+ * 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
+ *
+ * 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
+ *
+ * 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.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLSEARCHCOMBOBOX_H
+#define LL_LLSEARCHCOMBOBOX_H
+
+#include "llcombobox.h"
+#include "llsearchhistory.h"
+
+/**
+ * Search control with text box for search queries and a drop down list
+ * with recent queries. Supports text auto-complete and filtering of drop down list
+ * according to typed text.
+ */
+class LLSearchComboBox : public LLComboBox
+{
+public:
+
+ struct Params : public LLInitParam::Block<Params, LLComboBox::Params>
+ {
+ Optional<LLButton::Params> search_button;
+ Optional<bool> dropdown_button_visible;
+
+ Params();
+ };
+
+ /**
+ * Removes an entry from combo box, case insensitive
+ */
+ BOOL remove(const std::string& name);
+
+ /**
+ * Clears search history
+ */
+ void clearHistory();
+
+ ~LLSearchComboBox();
+
+protected:
+
+ LLSearchComboBox(const Params&p);
+ friend class LLUICtrlFactory;
+
+ /**
+ * Handles typing in text box
+ */
+ void onTextEntry(LLLineEditor* line_editor);
+
+ /**
+ * Hides drop down list and focuses text box
+ */
+ void hideList();
+
+ /**
+ * Rebuilds search history, case insensitive
+ * If filter is an empty string - whole history will be added to combo box
+ * if filter is valid string - only matching entries will be added
+ */
+ virtual void rebuildSearchHistory(const std::string& filter);
+
+ /**
+ * Callback for prearrange event
+ */
+ void onSearchPrearrange(const LLSD& data);
+
+ /**
+ * Callback for text box or combo box commit
+ */
+ void onSelectionCommit();
+
+ /**
+ * Sets focus to text box
+ */
+ void focusTextEntry();
+
+ LLButton* mSearchButton;
+};
+
+#endif //LL_LLSEARCHCOMBOBOX_H
diff --git a/indra/newview/llsearchhistory.cpp b/indra/newview/llsearchhistory.cpp
new file mode 100644
index 0000000000..d45a1efa0e
--- /dev/null
+++ b/indra/newview/llsearchhistory.cpp
@@ -0,0 +1,154 @@
+/**
+ * @file llsearchhistory.cpp
+ * @brief Search history container implementation
+ *
+ * $LicenseInfo:firstyear=2009&license=viewergpl$
+ *
+ * Copyright (c) 2009, Linden Research, Inc.
+ *
+ * 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
+ *
+ * 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
+ *
+ * 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.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+#include "llsearchhistory.h"
+
+#include "llfile.h"
+#include "llsdserialize.h"
+#include "llxmlnode.h"
+
+std::string LLSearchHistory::SEARCH_QUERY = "search_query";
+std::string LLSearchHistory::SEARCH_HISTORY_FILE_NAME = "search_history.txt";
+
+LLSearchHistory::LLSearchHistory()
+{
+
+}
+
+bool LLSearchHistory::load()
+{
+ // build filename for each user
+ std::string resolved_filename = getHistoryFilePath();
+ llifstream file(resolved_filename);
+ if (!file.is_open())
+ {
+ return false;
+ }
+
+ clearHistory();
+
+ // add each line in the file to the list
+ std::string line;
+ LLPointer<LLSDParser> parser = new LLSDNotationParser();
+ while (std::getline(file, line))
+ {
+ LLSD s_item;
+ std::istringstream iss(line);
+ if (parser->parse(iss, s_item, line.length()) == LLSDParser::PARSE_FAILURE)
+ {
+ break;
+ }
+
+ mSearchHistory.push_back(s_item);
+ }
+
+ file.close();
+
+ return true;
+}
+
+bool LLSearchHistory::save()
+{
+ // build filename for each user
+ std::string resolved_filename = getHistoryFilePath();
+ // open a file for writing
+ llofstream file (resolved_filename);
+ if (!file.is_open())
+ {
+ return false;
+ }
+
+ search_history_list_t::const_iterator it = mSearchHistory.begin();
+ for (; mSearchHistory.end() != it; ++it)
+ {
+ file << LLSDOStreamer<LLSDNotationFormatter>((*it).toLLSD()) << std::endl;
+ }
+
+ file.close();
+ return true;
+}
+
+std::string LLSearchHistory::getHistoryFilePath()
+{
+ return gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, SEARCH_HISTORY_FILE_NAME);
+}
+
+void LLSearchHistory::addEntry(const std::string& search_query)
+{
+ if(search_query.empty())
+ {
+ return;
+ }
+
+ search_history_list_t::iterator it =
+ find(mSearchHistory.begin(), mSearchHistory.end(), search_query);
+
+ if(mSearchHistory.end() != it)
+ {
+ mSearchHistory.erase(it);
+ }
+
+ LLSearchHistoryItem item(search_query);
+ mSearchHistory.push_front(item);
+}
+
+bool LLSearchHistory::LLSearchHistoryItem::operator < (const LLSearchHistory::LLSearchHistoryItem& right)
+{
+ S32 result = LLStringUtil::compareInsensitive(search_query, right.search_query);
+
+ return result < 0;
+}
+
+bool LLSearchHistory::LLSearchHistoryItem::operator > (const LLSearchHistory::LLSearchHistoryItem& right)
+{
+ S32 result = LLStringUtil::compareInsensitive(search_query, right.search_query);
+
+ return result > 0;
+}
+
+bool LLSearchHistory::LLSearchHistoryItem::operator==(const LLSearchHistory::LLSearchHistoryItem& right)
+{
+ return 0 == LLStringUtil::compareInsensitive(search_query, right.search_query);
+}
+
+bool LLSearchHistory::LLSearchHistoryItem::operator==(const std::string& right)
+{
+ return 0 == LLStringUtil::compareInsensitive(search_query, right);
+}
+
+LLSD LLSearchHistory::LLSearchHistoryItem::toLLSD() const
+{
+ LLSD ret;
+ ret[SEARCH_QUERY] = search_query;
+ return ret;
+}
diff --git a/indra/newview/llsearchhistory.h b/indra/newview/llsearchhistory.h
new file mode 100644
index 0000000000..253ef21e9e
--- /dev/null
+++ b/indra/newview/llsearchhistory.h
@@ -0,0 +1,138 @@
+/**
+ * @file llsearchhistory.h
+ * @brief Search history container definition
+ *
+ * $LicenseInfo:firstyear=2009&license=viewergpl$
+ *
+ * Copyright (c) 2009, Linden Research, Inc.
+ *
+ * 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
+ *
+ * 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
+ *
+ * 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.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLSEARCHHISTORY_H
+#define LL_LLSEARCHHISTORY_H
+
+#include "llsingleton.h"
+/**
+ * Search history container able to save and load history from file.
+ * History is stored in chronological order, most recent at the beginning.
+ */
+class LLSearchHistory : public LLSingleton<LLSearchHistory>
+{
+public:
+
+ // Forward declaration
+ class LLSearchHistoryItem;
+
+ // Search history container
+ typedef std::list<LLSearchHistoryItem> search_history_list_t;
+
+ /**
+ * Saves search history to file
+ */
+ bool save();
+
+ /**
+ * loads search history from file
+ */
+ bool load();
+
+ /**
+ * Returns search history list
+ */
+ search_history_list_t& getSearchHistoryList() { return mSearchHistory; }
+
+ /**
+ * Deletes all search history queries from list.
+ */
+ void clearHistory() { mSearchHistory.clear(); }
+
+ /**
+ * Adds unique entry to front of search history list, case insensitive
+ * If entry is already in list, it will be deleted and added to front.
+ */
+ void addEntry(const std::string& search_text);
+
+ LLSearchHistory();
+
+ /**
+ * Class for storing data about single search request.
+ */
+ class LLSearchHistoryItem
+ {
+ public:
+
+ LLSearchHistoryItem()
+ {}
+
+ LLSearchHistoryItem(const std::string& query)
+ : search_query(query)
+ {}
+
+ LLSearchHistoryItem(const LLSD& item)
+ {
+ if(item.has(SEARCH_QUERY))
+ search_query = item[SEARCH_QUERY].asString();
+ }
+
+ std::string search_query;
+
+ /**
+ * Allows std::list sorting
+ */
+ bool operator < (const LLSearchHistory::LLSearchHistoryItem& right);
+
+ /**
+ * Allows std::list sorting
+ */
+ bool operator > (const LLSearchHistory::LLSearchHistoryItem& right);
+
+ bool operator==(const LLSearchHistoryItem& right);
+
+ bool operator==(const std::string& right);
+
+ /**
+ * Serializes search history item to LLSD
+ */
+ LLSD toLLSD() const;
+ };
+
+protected:
+
+ /**
+ * Returns path to search history file.
+ */
+ std::string getHistoryFilePath();
+
+ static std::string SEARCH_HISTORY_FILE_NAME;
+ static std::string SEARCH_QUERY;
+
+private:
+
+ search_history_list_t mSearchHistory;
+};
+
+class LLSearchComboBox;
+
+#endif //LL_LLSEARCHHISTORY_H
diff --git a/indra/newview/llsidetray.cpp b/indra/newview/llsidetray.cpp
index afa8e5f072..381e63f020 100644
--- a/indra/newview/llsidetray.cpp
+++ b/indra/newview/llsidetray.cpp
@@ -241,6 +241,13 @@ LLSideTray::LLSideTray(Params& params)
,mMaxBarWidth(params.rect.width)
{
mCollapsed=params.collapsed;
+
+
+ LLUICtrl::CommitCallbackRegistry::Registrar& commit = LLUICtrl::CommitCallbackRegistry::currentRegistrar();
+
+ // register handler function to process data from the xml.
+ // panel_name should be specified via "parameter" attribute.
+ commit.add("SideTray.ShowPanel", boost::bind(&LLSideTray::showPanel, this, _2, LLUUID::null));
}
diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp
index 6c0481feaa..8fb0f201cb 100644
--- a/indra/newview/llstartup.cpp
+++ b/indra/newview/llstartup.cpp
@@ -899,6 +899,10 @@ bool idle_startup()
if (STATE_LOGIN_CLEANUP == LLStartUp::getStartupState())
{
+ // Move the progress view in front of the UI immediately when login is performed
+ // this allows not to see main menu after Alt+Tab was pressed while login. EXT-744.
+ gViewerWindow->moveProgressViewToFront();
+
//reset the values that could have come in from a slurl
if (!gLoginHandler.getWebLoginKey().isNull())
{
diff --git a/indra/newview/llsyswellwindow.cpp b/indra/newview/llsyswellwindow.cpp
index 15d77dbf88..7ddbf0a744 100644
--- a/indra/newview/llsyswellwindow.cpp
+++ b/indra/newview/llsyswellwindow.cpp
@@ -38,9 +38,9 @@
#include "llviewercontrol.h"
#include "llviewerwindow.h"
+#include "llchiclet.h"
//---------------------------------------------------------------------------------
-LLSysWellWindow::LLSysWellWindow(const LLSD& key) : LLFloater(LLSD()),
- mSysWell(NULL),
+LLSysWellWindow::LLSysWellWindow(const LLSD& key) : LLDockableFloater(NULL, key),
mChannel(NULL),
mScrollContainer(NULL),
mNotificationList(NULL)
@@ -57,13 +57,9 @@ BOOL LLSysWellWindow::postBuild()
mNotificationList = getChild<LLScrollingPanelList>("notification_list");
mIMRowList = getChild<LLScrollingPanelList>("im_row_panel_list");
- gViewerWindow->setOnBottomTrayWidthChanged(boost::bind(&LLSysWellWindow::adjustWindowPosition, this)); // *TODO: won't be necessary after docking is realized
mScrollContainer->setBorderVisible(FALSE);
- mDockTongue = LLUI::getUIImage("windows/Flyout_Pointer.png");
-
-
- return TRUE;
+ return LLDockableFloater::postBuild();
}
//---------------------------------------------------------------------------------
@@ -82,7 +78,6 @@ void LLSysWellWindow::addItem(LLSysWellItem::Params p)
LLSysWellItem* new_item = new LLSysWellItem(p);
mNotificationList->addPanel(dynamic_cast<LLScrollingPanel*>(new_item));
reshapeWindow();
- adjustWindowPosition(); // *TODO: won't be necessary after docking is realized
new_item->setOnItemCloseCallback(boost::bind(&LLSysWellWindow::onItemClose, this, _1));
new_item->setOnItemClickCallback(boost::bind(&LLSysWellWindow::onItemClick, this, _1));
@@ -127,10 +122,6 @@ void LLSysWellWindow::removeItemByID(const LLUUID& id)
return;
reshapeWindow();
- adjustWindowPosition(); // *TODO: won't be necessary after docking is realized
-
- // hide chiclet window if there are no items left
- setVisible(!isWindowEmpty());
}
//---------------------------------------------------------------------------------
@@ -148,11 +139,20 @@ void LLSysWellWindow::onItemClose(LLSysWellItem* item)
removeItemByID(id);
if(mChannel)
mChannel->killToastByNotificationID(id);
+
+ // hide chiclet window if there are no items left
+ setVisible(!isWindowEmpty());
}
//---------------------------------------------------------------------------------
void LLSysWellWindow::toggleWindow()
{
+ if (getDockControl() == NULL)
+ {
+ setDockControl(new LLDockControl(
+ LLBottomTray::getInstance()->getSysWell(), this,
+ getDockTongue(), LLDockControl::TOP, isDocked()));
+ }
setVisible(!getVisible());
}
@@ -162,12 +162,20 @@ void LLSysWellWindow::setVisible(BOOL visible)
// on Show adjust position of SysWell chiclet's window
if(visible)
{
+ if (LLBottomTray::instanceExists())
+ {
+ LLBottomTray::getInstance()->getSysWell()->setToggleState(TRUE);
+ }
if(mChannel)
mChannel->removeAndStoreAllVisibleToasts();
-
- adjustWindowPosition(); // *TODO: won't be necessary after docking is realized
}
-
+ else
+ {
+ if (LLBottomTray::instanceExists())
+ {
+ LLBottomTray::getInstance()->getSysWell()->setToggleState(FALSE);
+ }
+ }
if(mChannel)
mChannel->setShowToasts(!visible);
@@ -175,16 +183,6 @@ void LLSysWellWindow::setVisible(BOOL visible)
}
//---------------------------------------------------------------------------------
-void LLSysWellWindow::adjustWindowPosition() // *TODO: won't be necessary after docking is realized
-{
- const S32 WINDOW_MARGIN = 5;
-
- LLRect btm_rect = LLBottomTray::getInstance()->getRect();
- LLRect this_rect = getRect();
- setOrigin(btm_rect.mRight - this_rect.getWidth() - WINDOW_MARGIN, WINDOW_MARGIN);
-}
-
-//---------------------------------------------------------------------------------
void LLSysWellWindow::reshapeWindow()
{
// Get size for scrollbar and floater's header
@@ -272,7 +270,6 @@ void LLSysWellWindow::addIMRow(const LLUUID& sessionId, S32 chicletCounter,
{
mIMRowList->addPanel(new RowPanel(this, sessionId, chicletCounter, name, otherParticipantId));
- adjustWindowPosition(); // *TODO: won't be necessary after docking is realized
}
//---------------------------------------------------------------------------------
@@ -286,14 +283,12 @@ void LLSysWellWindow::delIMRow(const LLUUID& sessionId)
// hide chiclet window if there are no items left
setVisible(!isWindowEmpty());
-
- adjustWindowPosition(); // *TODO: won't be necessary after docking is realized
}
//---------------------------------------------------------------------------------
bool LLSysWellWindow::isWindowEmpty()
{
- if(mIMRowList->getPanelList().size() == 0 && mNotificationList->getPanelList().size() == 0)
+ if(mIMRowList->getPanelList().size() == 0 && LLBottomTray::getInstance()->getSysWell()->getCounter() == 0)
{
return true;
}
@@ -328,7 +323,7 @@ void LLSysWellWindow::sessionRemoved(const LLUUID& sessionId)
{
delIMRow(sessionId);
reshapeWindow();
- mSysWell->updateUreadIMNotifications();
+ LLBottomTray::getInstance()->getSysWell()->updateUreadIMNotifications();
}
//---------------------------------------------------------------------------------
@@ -396,5 +391,3 @@ void LLSysWellWindow::RowPanel::updatePanel(BOOL allow_modify)
}
//---------------------------------------------------------------------------------
-
-
diff --git a/indra/newview/llsyswellwindow.h b/indra/newview/llsyswellwindow.h
index d9fdf77a04..ef0974b428 100644
--- a/indra/newview/llsyswellwindow.h
+++ b/indra/newview/llsyswellwindow.h
@@ -35,7 +35,7 @@
#include "llsyswellitem.h"
-#include "llfloater.h"
+#include "lldockablefloater.h"
#include "llbutton.h"
#include "llscreenchannel.h"
#include "llscrollcontainer.h"
@@ -46,7 +46,7 @@
-class LLSysWellWindow : public LLFloater, LLIMSessionObserver
+class LLSysWellWindow : public LLDockableFloater, LLIMSessionObserver
{
public:
LLSysWellWindow(const LLSD& key);
@@ -58,7 +58,6 @@ public:
// change attributes
void setChannel(LLNotificationsUI::LLScreenChannel* channel) {mChannel = channel;}
- void setSysWell(LLNotificationChiclet* sys_well) {mSysWell = sys_well;}
// Operating with items
void addItem(LLSysWellItem::Params p);
@@ -93,9 +92,6 @@ private:
// pointer to a corresponding channel's instance
LLNotificationsUI::LLScreenChannel* mChannel;
-
- LLNotificationChiclet* mSysWell;
- LLUIImagePtr mDockTongue;
LLPanel* mTwinListPanel;
LLScrollContainer* mScrollContainer;
LLScrollingPanelList* mIMRowList;
diff --git a/indra/newview/llteleporthistorystorage.cpp b/indra/newview/llteleporthistorystorage.cpp
index b31edf1e5d..0bb5a727e0 100644
--- a/indra/newview/llteleporthistorystorage.cpp
+++ b/indra/newview/llteleporthistorystorage.cpp
@@ -37,8 +37,11 @@
#include "llsd.h"
#include "llsdserialize.h"
#include "lldir.h"
+#include "llteleporthistory.h"
+#include "llagent.h"
-static LLTeleportHistoryStorage tpstorage;
+// Max offset for two global positions to consider them as equal
+const F64 MAX_GLOBAL_POS_OFFSET = 5.0f;
LLTeleportHistoryPersistentItem::LLTeleportHistoryPersistentItem(const LLSD& val)
{
@@ -58,15 +61,42 @@ LLSD LLTeleportHistoryPersistentItem::toLLSD() const
return val;
}
+struct LLSortItemsByDate
+{
+ bool operator()(const LLTeleportHistoryPersistentItem& a, const LLTeleportHistoryPersistentItem& b)
+ {
+ return a.mDate < b.mDate;
+ }
+};
+
LLTeleportHistoryStorage::LLTeleportHistoryStorage() :
mFilename("teleport_history.txt")
{
+ LLTeleportHistory *th = LLTeleportHistory::getInstance();
+ if (th)
+ th->setHistoryChangedCallback(boost::bind(&LLTeleportHistoryStorage::onTeleportHistoryChange, this));
+
+ load();
}
LLTeleportHistoryStorage::~LLTeleportHistoryStorage()
{
}
+void LLTeleportHistoryStorage::onTeleportHistoryChange()
+{
+ LLTeleportHistory *th = LLTeleportHistory::getInstance();
+ if (!th)
+ return;
+
+ const LLTeleportHistoryItem &item = th->getItems()[th->getCurrentItemIndex()];
+
+ addItem(item.mTitle, item.mGlobalPos);
+ save();
+
+ mHistoryChangedSignal();
+}
+
void LLTeleportHistoryStorage::purgeItems()
{
mItems.clear();
@@ -74,12 +104,45 @@ void LLTeleportHistoryStorage::purgeItems()
void LLTeleportHistoryStorage::addItem(const std::string title, const LLVector3d& global_pos)
{
- mItems.push_back(LLTeleportHistoryPersistentItem(title, global_pos));
+ addItem(title, global_pos, LLDate::now());
+}
+
+
+bool LLTeleportHistoryStorage::compareByTitleAndGlobalPos(const LLTeleportHistoryPersistentItem& a, const LLTeleportHistoryPersistentItem& b)
+{
+ return a.mTitle == b.mTitle && (a.mGlobalPos - b.mGlobalPos).length() < MAX_GLOBAL_POS_OFFSET;
}
void LLTeleportHistoryStorage::addItem(const std::string title, const LLVector3d& global_pos, const LLDate& date)
{
- mItems.push_back(LLTeleportHistoryPersistentItem(title, global_pos, date));
+
+ LLTeleportHistoryPersistentItem item(title, global_pos, date);
+
+ slurl_list_t::iterator item_iter = std::find_if(mItems.begin(), mItems.end(),
+ boost::bind(&LLTeleportHistoryStorage::compareByTitleAndGlobalPos, this, _1, item));
+
+ // If there is such item already, remove it, since new item is more recent
+ if (item_iter != mItems.end())
+ {
+ mItems.erase(item_iter);
+ }
+
+ mItems.push_back(item);
+
+ // Check whether sorting is needed
+ if (mItems.size() > 1)
+ {
+ item_iter = mItems.end();
+
+ item_iter--;
+ item_iter--;
+
+ // If second to last item is more recent than last, then resort items
+ if (item_iter->mDate > item.mDate)
+ {
+ std::sort(mItems.begin(), mItems.end(), LLSortItemsByDate());
+ }
+ }
}
void LLTeleportHistoryStorage::removeItem(S32 idx)
@@ -145,6 +208,8 @@ void LLTeleportHistoryStorage::load()
}
file.close();
+
+ std::sort(mItems.begin(), mItems.end(), LLSortItemsByDate());
}
void LLTeleportHistoryStorage::dump() const
@@ -162,3 +227,30 @@ void LLTeleportHistoryStorage::dump() const
}
}
+boost::signals2::connection LLTeleportHistoryStorage::setHistoryChangedCallback(history_callback_t cb)
+{
+ return mHistoryChangedSignal.connect(cb);
+}
+
+void LLTeleportHistoryStorage::goToItem(S32 idx)
+
+{
+ // Validate specified index.
+ if (idx < 0 || idx >= (S32)mItems.size())
+ {
+ llwarns << "Invalid teleport history index (" << idx << ") specified" << llendl;
+ dump();
+ return;
+ }
+
+ if (idx == (S32)mItems.size() - 1)
+ {
+ llwarns << "Will not teleport to the same location." << llendl;
+ dump();
+ return;
+ }
+
+ // Attempt to teleport to the requested item.
+ gAgent.teleportViaLocation(mItems[idx].mGlobalPos);
+}
+
diff --git a/indra/newview/llteleporthistorystorage.h b/indra/newview/llteleporthistorystorage.h
index fa836c0326..f67c4e2fb9 100644
--- a/indra/newview/llteleporthistorystorage.h
+++ b/indra/newview/llteleporthistorystorage.h
@@ -78,7 +78,10 @@ class LLTeleportHistoryStorage: public LLSingleton<LLTeleportHistoryStorage>
public:
- typedef std::vector<LLTeleportHistoryPersistentItem> item_list_list_t;
+ typedef std::vector<LLTeleportHistoryPersistentItem> slurl_list_t;
+
+ typedef boost::function<void()> history_callback_t;
+ typedef boost::signals2::signal<void()> history_signal_t;
LLTeleportHistoryStorage();
~LLTeleportHistoryStorage();
@@ -86,7 +89,7 @@ public:
/**
* @return history items.
*/
- const item_list_list_t& getItems() const { return mItems; }
+ const slurl_list_t& getItems() const { return mItems; }
void purgeItems();
void addItem(const std::string title, const LLVector3d& global_pos);
@@ -99,10 +102,34 @@ public:
void dump() const;
+ /**
+ * Set a callback to be called upon history changes.
+ *
+ * Multiple callbacks can be set.
+ */
+ boost::signals2::connection setHistoryChangedCallback(history_callback_t cb);
+
+ /**
+ * Go to specific item in the history.
+ *
+ * The item is specified by its index (starting from 0).
+ */
+ void goToItem(S32 idx);
+
private:
- item_list_list_t mItems;
- std::string mFilename;
+ void onTeleportHistoryChange();
+ bool compareByTitleAndGlobalPos(const LLTeleportHistoryPersistentItem& a, const LLTeleportHistoryPersistentItem& b);
+
+ slurl_list_t mItems;
+ std::string mFilename;
+
+ /**
+ * Signal emitted when the history gets changed.
+ *
+ * Invokes callbacks set with setHistoryChangedCallback().
+ */
+ history_signal_t mHistoryChangedSignal;
};
#endif //LL_LLTELEPORTHISTORYSTORAGE_H
diff --git a/indra/newview/lltoast.h b/indra/newview/lltoast.h
index 969f3fd1cb..05e63a60c5 100644
--- a/indra/newview/lltoast.h
+++ b/indra/newview/lltoast.h
@@ -70,12 +70,16 @@ public:
bool enable_hide_btn;
bool is_modal;
bool is_tip;
+ bool force_show;
+ bool force_store;
Params() : can_fade(true),
can_be_stored(true),
is_modal(false),
is_tip(false),
enable_hide_btn(true),
+ force_show(false),
+ force_store(false),
panel(NULL),
timer_period(gSavedSettings.getS32("NotificationToastTime"))
diff --git a/indra/newview/lltoastgroupnotifypanel.cpp b/indra/newview/lltoastgroupnotifypanel.cpp
index 6f26b4077c..6f373a74bd 100644
--- a/indra/newview/lltoastgroupnotifypanel.cpp
+++ b/indra/newview/lltoastgroupnotifypanel.cpp
@@ -40,7 +40,7 @@
#include "lliconctrl.h"
#include "llnotify.h"
#include "lltextbox.h"
-#include "lltexteditor.h"
+
#include "lluiconstants.h"
#include "llui.h"
#include "llviewercontrol.h"
@@ -53,6 +53,8 @@
#include "llfloaterinventory.h"
#include "llinventorytype.h"
+const S32 LLToastGroupNotifyPanel::DEFAULT_MESSAGE_MAX_LINE_COUNT = 4;
+
LLToastGroupNotifyPanel::LLToastGroupNotifyPanel(LLNotificationPtr& notification)
: LLToastPanel(notification),
mInventoryOffer(NULL)
@@ -65,8 +67,6 @@ LLToastGroupNotifyPanel::LLToastGroupNotifyPanel(LLNotificationPtr& notification
llwarns << "Group notice for unkown group: " << payload["group_id"].asUUID() << llendl;
}
- static const LLUIColor textColor = LLUIColorTable::instance().getColor("GroupNotifyTextColor");
-
//group icon
LLIconCtrl* pGroupIcon = getChild<LLIconCtrl>("group_icon", TRUE);
pGroupIcon->setValue(groupData.mInsigniaID);
@@ -78,23 +78,16 @@ LLToastGroupNotifyPanel::LLToastGroupNotifyPanel(LLNotificationPtr& notification
LLTextBox* pTitleText = getChild<LLTextBox>("title");
pTitleText->setValue(from.str());
- //message body
+ //message subject
const std::string& subject = payload["subject"].asString();
+ //message body
const std::string& message = payload["message"].asString();
- LLTextEditor* pMessageText = getChild<LLTextEditor>("message");
- pMessageText->setValue("");
- pMessageText->setEnabled(FALSE);
- LLStyle::Params date_style;
- date_style.color = textColor;
- date_style.font.name = "SANSSERIF";
-
- LLStyle::Params header_style_params;
- header_style_params.color = textColor;
- header_style_params.font = LLFontGL::getFontSansSerifBig();
- pMessageText->appendStyledText(subject + "\n",false,false,header_style_params);
+ LLTextBox* pSubjectText = getChild<LLTextBox>("subject");
+ pSubjectText->setValue(subject);
+ LLTextBox* pDateTimeText = getChild<LLTextBox>("datetime");
std::string timeStr = "["+LLTrans::getString("UTCTimeWeek")+"],["
+LLTrans::getString("UTCTimeDay")+"] ["
+LLTrans::getString("UTCTimeMth")+"] ["
@@ -108,25 +101,38 @@ LLToastGroupNotifyPanel::LLToastGroupNotifyPanel(LLNotificationPtr& notification
LLSD substitution;
substitution["datetime"] = (S32) notice_date.secondsSinceEpoch();
LLStringUtil::format(timeStr, substitution);
- LLStyle::Params date_style_params;
- date_style_params.color = textColor;
- date_style_params.font = LLFontGL::getFontMonospace();
- pMessageText->appendStyledText(timeStr, false, false, date_style);
- pMessageText->appendColoredText(std::string("\n\n") + message, false,
- false, textColor);
+ pDateTimeText->setValue(timeStr);
+
+ LLTextBox* pMessageText = getChild<LLTextBox>("message");
+
+ //If message is empty let it be invisible and not take place at the panel
+ if(message.size() != 0)
+ {
+ pMessageText->setVisible(TRUE);
+ pMessageText->setValue(message);
+ }
+ else
+ {
+ pMessageText->setVisible(FALSE);
+ }
//attachment
BOOL hasInventory = payload["inventory_offer"].isDefined();
+
+ //attachment text
LLTextBox * pAttachLink = getChild<LLTextBox>("attachment");
+ //attachment icon
+ LLIconCtrl* pAttachIcon = getChild<LLIconCtrl>("attachment_icon", TRUE);
+
+ //If attachment is empty let it be invisible and not take place at the panel
pAttachLink->setVisible(hasInventory);
+ pAttachIcon->setVisible(hasInventory);
if (hasInventory) {
pAttachLink->setValue(payload["inventory_name"]);
mInventoryOffer = new LLOfferInfo(payload["inventory_offer"]);
childSetActionTextbox("attachment", boost::bind(
&LLToastGroupNotifyPanel::onClickAttachment, this));
- //attachment icon
- LLIconCtrl* pAttachIcon = getChild<LLIconCtrl>("attachment_icon", TRUE);
LLUIImagePtr attachIconImg = get_item_icon(mInventoryOffer->mType,
LLInventoryType::IT_TEXTURE,
0, FALSE);
@@ -137,8 +143,15 @@ LLToastGroupNotifyPanel::LLToastGroupNotifyPanel(LLNotificationPtr& notification
LLButton* pOkBtn = getChild<LLButton>("btn_ok");
pOkBtn->setClickedCallback((boost::bind(&LLToastGroupNotifyPanel::onClickOk, this)));
setDefaultBtn(pOkBtn);
-}
+ S32 maxLinesCount;
+ std::istringstream ss( getString("message_max_lines_count") );
+ if (!(ss >> maxLinesCount))
+ {
+ maxLinesCount = DEFAULT_MESSAGE_MAX_LINE_COUNT;
+ }
+ snapToMessageHeight(pMessageText, maxLinesCount);
+}
// virtual
LLToastGroupNotifyPanel::~LLToastGroupNotifyPanel()
diff --git a/indra/newview/lltoastgroupnotifypanel.h b/indra/newview/lltoastgroupnotifypanel.h
index ba98531251..e3d0ef45cb 100644
--- a/indra/newview/lltoastgroupnotifypanel.h
+++ b/indra/newview/lltoastgroupnotifypanel.h
@@ -68,6 +68,8 @@ protected:
private:
static bool isAttachmentOpenable(LLAssetType::EType);
+ static const S32 DEFAULT_MESSAGE_MAX_LINE_COUNT;
+
LLButton* mSaveInventoryBtn;
LLUUID mGroupID;
diff --git a/indra/newview/lltoastimpanel.cpp b/indra/newview/lltoastimpanel.cpp
index e41181c9e1..913e46e05e 100644
--- a/indra/newview/lltoastimpanel.cpp
+++ b/indra/newview/lltoastimpanel.cpp
@@ -34,9 +34,7 @@
#include "lltoastimpanel.h"
#include "llimpanel.h"
-const S32 LLToastIMPanel::MAX_MESSAGE_HEIGHT = 50;
-const S32 LLToastIMPanel::CAPTION_HEIGHT = 30;
-const S32 LLToastIMPanel::TOP_PAD = 5;
+const S32 LLToastIMPanel::DEFAULT_MESSAGE_MAX_LINE_COUNT = 6;
//--------------------------------------------------------------------------
LLToastIMPanel::LLToastIMPanel(LLToastIMPanel::Params &p) : LLToastPanel(p.notification),
@@ -60,7 +58,13 @@ LLToastIMPanel::LLToastIMPanel(LLToastIMPanel::Params &p) : LLToastPanel(p.notif
mReplyBtn->setClickedCallback(boost::bind(&LLToastIMPanel::onClickReplyBtn, this));
- snapToMessageHeight();
+ S32 maxLinesCount;
+ std::istringstream ss( getString("message_max_lines_count") );
+ if (!(ss >> maxLinesCount))
+ {
+ maxLinesCount = DEFAULT_MESSAGE_MAX_LINE_COUNT;
+ }
+ snapToMessageHeight(mMessage, maxLinesCount);
}
//--------------------------------------------------------------------------
@@ -69,22 +73,6 @@ LLToastIMPanel::~LLToastIMPanel()
}
//--------------------------------------------------------------------------
-void LLToastIMPanel::snapToMessageHeight()
-{
- S32 required_text_height = mMessage->getTextPixelHeight();
- S32 text_height = llmin(required_text_height, MAX_MESSAGE_HEIGHT);
- LLRect text_rect = mMessage->getRect();
- LLRect btn_rect = mReplyBtn->getRect();
-
-
- mMessage->reshape( text_rect.getWidth(), text_height, TRUE);
- mMessage->setValue(mMessage->getText());
-
- S32 panel_height = CAPTION_HEIGHT + text_height + btn_rect.getHeight() + TOP_PAD*5;
- reshape( getRect().getWidth(), panel_height, TRUE);
-}
-
-//--------------------------------------------------------------------------
void LLToastIMPanel::onClickReplyBtn()
{
LLIMFloater::toggle(mSessionID);
diff --git a/indra/newview/lltoastimpanel.h b/indra/newview/lltoastimpanel.h
index 7f5d6eca1d..11f489c12f 100644
--- a/indra/newview/lltoastimpanel.h
+++ b/indra/newview/lltoastimpanel.h
@@ -59,12 +59,9 @@ public:
virtual ~LLToastIMPanel();
private:
- static const S32 MAX_MESSAGE_HEIGHT;
- static const S32 CAPTION_HEIGHT;
- static const S32 TOP_PAD;
+ static const S32 DEFAULT_MESSAGE_MAX_LINE_COUNT;
void onClickReplyBtn();
- void snapToMessageHeight();
LLUUID mSessionID;
LLAvatarIconCtrl* mAvatar;
diff --git a/indra/newview/lltoastpanel.cpp b/indra/newview/lltoastpanel.cpp
index 28052a33be..e884d89ce4 100644
--- a/indra/newview/lltoastpanel.cpp
+++ b/indra/newview/lltoastpanel.cpp
@@ -49,5 +49,36 @@ std::string LLToastPanel::getTitle()
return mNotification->getMessage();
}
+//snap to the message height if it is visible
+void LLToastPanel::snapToMessageHeight(LLTextBox* message, S32 maxLineCount)
+{
+ //Add message height if it is visible
+ if (message->getVisible())
+ {
+ S32 heightDelta = 0;
+ S32 maxTextHeight = (S32)(message->getFont()->getLineHeight() * maxLineCount);
+
+ LLRect messageRect = message->getRect();
+ S32 oldTextHeight = messageRect.getHeight();
+
+ //Reshape the toast to give the message max height.
+ //This needed to calculate lines count according to specified text
+ heightDelta = maxTextHeight - oldTextHeight;
+ reshape( getRect().getWidth(), getRect().getHeight() + heightDelta);
+ message->setValue(message->getText());
+
+ //Knowing the height is set to max allowed, getTextPixelHeight returns needed text height
+ //Perhaps we need to pass maxLineCount as parameter to getTextPixelHeight to avoid previous reshape.
+ S32 requiredTextHeight = message->getTextPixelHeight();
+ S32 newTextHeight = llmin(requiredTextHeight, maxTextHeight);
+ //Calculate last delta height deducting previous heightDelta
+ heightDelta = newTextHeight - oldTextHeight - heightDelta;
+
+ //reshape the panel with new height
+ reshape( getRect().getWidth(), getRect().getHeight() + heightDelta);
+ message->setValue(message->getText());
+ }
+
+}
diff --git a/indra/newview/lltoastpanel.h b/indra/newview/lltoastpanel.h
index 2258eca273..bc9888f4b4 100644
--- a/indra/newview/lltoastpanel.h
+++ b/indra/newview/lltoastpanel.h
@@ -34,6 +34,7 @@
#define LL_LLTOASTPANEL_H
#include "llpanel.h"
+#include "lltextbox.h"
#include "llnotifications.h"
#include <string>
@@ -53,6 +54,7 @@ public:
virtual const LLUUID& getID() { return mNotification->id();}
protected:
LLNotificationPtr mNotification;
+ void snapToMessageHeight(LLTextBox* message, S32 maxLineCount);
};
#endif /* LL_TOASTPANEL_H */
diff --git a/indra/newview/lltoolbar.cpp b/indra/newview/lltoolbar.cpp
index acd6856061..c7c9f07504 100644
--- a/indra/newview/lltoolbar.cpp
+++ b/indra/newview/lltoolbar.cpp
@@ -60,6 +60,7 @@
#include "llui.h"
#include "llviewermenu.h"
#include "llfirstuse.h"
+#include "llpanelblockedlist.h"
#include "llscrolllistctrl.h"
#include "llscrolllistitem.h"
#include "llscrolllistcell.h"
@@ -69,7 +70,6 @@
#include "lltoolgrab.h"
#include "llcombobox.h"
#include "llfloaterchat.h"
-#include "llfloatermute.h"
#include "llimpanel.h"
#include "lllayoutstack.h"
@@ -297,11 +297,8 @@ void LLToolBar::updateCommunicateList()
communicate_button->addSeparator(ADD_TOP);
communicate_button->add(getString("Redock Windows"), LLSD("redock"), ADD_TOP);
communicate_button->addSeparator(ADD_TOP);
- LLFloaterMute* mute_instance = LLFloaterReg::getTypedInstance<LLFloaterMute>("mute");
- if(mute_instance)
- {
- communicate_button->add(mute_instance->getShortTitle(), LLSD("mute list"), ADD_TOP);
- }
+ communicate_button->add(getString("Blocked List"), LLSD("mute list"), ADD_TOP);
+
std::set<LLHandle<LLFloater> >::const_iterator floater_handle_it;
if (gIMMgr->getIMFloaterHandles().size() > 0)
@@ -379,7 +376,7 @@ void LLToolBar::onClickCommunicate(LLUICtrl* ctrl, const LLSD& user_data)
}
else if (selected_option.asString() == "mute list")
{
- LLFloaterReg::showInstance("mute");
+ LLPanelBlockedList::showPanelAndSelect(LLUUID::null);
}
else if (selected_option.isUndefined()) // user just clicked the communicate button, treat as toggle
{
diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp
index b85dc30e72..c8f2e03903 100644
--- a/indra/newview/llviewerfloaterreg.cpp
+++ b/indra/newview/llviewerfloaterreg.cpp
@@ -78,7 +78,6 @@
#include "llfloaterlandholdings.h"
#include "llfloatermap.h"
#include "llfloatermemleak.h"
-#include "llfloatermute.h"
#include "llfloaternamedesc.h"
#include "llfloaternotificationsconsole.h"
#include "llfloateropenobject.h"
@@ -110,6 +109,7 @@
#include "llmediaremotectrl.h"
#include "llmoveview.h"
#include "llnearbychat.h"
+#include "llpanelblockedlist.h"
#include "llpreviewanim.h"
#include "llpreviewgesture.h"
#include "llpreviewnotecard.h"
@@ -177,8 +177,7 @@ void LLViewerFloaterReg::registerFloaters()
LLFloaterReg::add("message_critical", "floater_critical.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterTOS>);
LLFloaterReg::add("message_tos", "floater_tos.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterTOS>);
LLFloaterReg::add("moveview", "floater_moveview.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterMove>);
- LLFloaterReg::add("mute", "floater_mute.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterMute>);
- LLFloaterReg::add("mute_object", "floater_mute_object.xml", &LLFloaterMute::buildFloaterMuteObjectUI);
+ LLFloaterReg::add("mute_object_by_name", "floater_mute_object.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterGetBlockedObjectName>);
LLFloaterReg::add("mini_map", "floater_map.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterMap>);
LLFloaterReg::add("syswell_window", "floater_sys_well.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLSysWellWindow>);
diff --git a/indra/newview/llviewerinventory.cpp b/indra/newview/llviewerinventory.cpp
index 95ab40f9bf..ec20af46a1 100644
--- a/indra/newview/llviewerinventory.cpp
+++ b/indra/newview/llviewerinventory.cpp
@@ -120,6 +120,41 @@ LLViewerInventoryItem::~LLViewerInventoryItem()
{
}
+BOOL LLViewerInventoryItem::extractSortFieldAndDisplayName(S32* sortField, std::string* displayName) const
+{
+ using std::string;
+ using std::stringstream;
+
+ const char separator = getSeparator();
+ const string::size_type separatorPos = mName.find(separator, 0);
+
+ BOOL result = FALSE;
+
+ if (separatorPos < string::npos)
+ {
+ if (sortField)
+ {
+ /*
+ * The conversion from string to S32 is made this way instead of old plain
+ * atoi() to ensure portability. If on some other platform S32 will not be
+ * defined to be signed int, this conversion will still work because of
+ * operators overloading, but atoi() may fail.
+ */
+ stringstream ss(mName.substr(0, separatorPos));
+ ss >> *sortField;
+ }
+
+ if (displayName)
+ {
+ *displayName = mName.substr(separatorPos + 1, string::npos);
+ }
+
+ result = TRUE;
+ }
+
+ return result;
+}
+
void LLViewerInventoryItem::copyViewerItem(const LLViewerInventoryItem* other)
{
LLInventoryItem::copyItem(other);
@@ -1102,7 +1137,70 @@ const std::string& LLViewerInventoryItem::getName() const
return linked_category->getName();
}
- return LLInventoryItem::getName();
+ return getDisplayName();
+}
+
+const std::string& LLViewerInventoryItem::getDisplayName() const
+{
+ std::string result;
+ BOOL hasSortField = extractSortFieldAndDisplayName(0, &result);
+
+ return mDisplayName = hasSortField ? result : LLInventoryItem::getName();
+}
+
+S32 LLViewerInventoryItem::getSortField() const
+{
+ S32 result;
+ BOOL hasSortField = extractSortFieldAndDisplayName(&result, 0);
+
+ return hasSortField ? result : -1;
+}
+
+void LLViewerInventoryItem::setSortField(S32 sortField)
+{
+ using std::string;
+
+ std::stringstream ss;
+ ss << sortField;
+
+ string newSortField = ss.str();
+
+ const char separator = getSeparator();
+ const string::size_type separatorPos = mName.find(separator, 0);
+
+ if (separatorPos < string::npos)
+ {
+ // the name of the LLViewerInventoryItem already consists of sort field and display name.
+ mName = newSortField + separator + mName.substr(separatorPos + 1, string::npos);
+ }
+ else
+ {
+ // there is no sort field in the name of LLViewerInventoryItem, we should add it
+ mName = newSortField + separator + mName;
+ }
+}
+
+void LLViewerInventoryItem::rename(const std::string& n)
+{
+ using std::string;
+
+ string new_name(n);
+ LLStringUtil::replaceNonstandardASCII(new_name, ' ');
+ LLStringUtil::replaceChar(new_name, '|', ' ');
+ LLStringUtil::trim(new_name);
+ LLStringUtil::truncate(new_name, DB_INV_ITEM_NAME_STR_LEN);
+
+ const char separator = getSeparator();
+ const string::size_type separatorPos = mName.find(separator, 0);
+
+ if (separatorPos < string::npos)
+ {
+ mName.replace(separatorPos + 1, string::npos, new_name);
+ }
+ else
+ {
+ mName = new_name;
+ }
}
const LLPermissions& LLViewerInventoryItem::getPermissions() const
diff --git a/indra/newview/llviewerinventory.h b/indra/newview/llviewerinventory.h
index 0bfb37f7e8..c4ff30bbfc 100644
--- a/indra/newview/llviewerinventory.h
+++ b/indra/newview/llviewerinventory.h
@@ -55,11 +55,18 @@ public:
protected:
~LLViewerInventoryItem( void ); // ref counted
+ BOOL extractSortFieldAndDisplayName(S32* sortField, std::string* displayName) const;
+ static char getSeparator() { return '@'; }
+ mutable std::string mDisplayName;
public:
virtual LLAssetType::EType getType() const;
virtual const LLUUID& getAssetUUID() const;
virtual const std::string& getName() const;
+ virtual const std::string& getDisplayName() const;
+ virtual S32 getSortField() const;
+ virtual void setSortField(S32 sortField);
+ virtual void rename(const std::string& new_name);
virtual const LLPermissions& getPermissions() const;
virtual const LLUUID& getCreatorUUID() const;
virtual const std::string& getDescription() const;
diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp
index 8a5928f4e9..5536951ce6 100644
--- a/indra/newview/llviewermenu.cpp
+++ b/indra/newview/llviewermenu.cpp
@@ -113,7 +113,6 @@
#include "llfloaterland.h"
#include "llfloaterlandholdings.h"
#include "llfloatermap.h"
-#include "llfloatermute.h"
#include "llfloateropenobject.h"
#include "llfloaterperms.h"
#include "llfloaterpostprocess.h"
@@ -147,6 +146,7 @@
#include "llfloaterinventory.h"
#include "llkeyboard.h"
#include "llpanellogin.h"
+#include "llpanelblockedlist.h"
#include "llmenucommands.h"
#include "llmenugl.h"
#include "llmimetypes.h"
@@ -2896,7 +2896,7 @@ class LLObjectMute : public view_listener_t
else
{
LLMuteList::getInstance()->add(mute);
- LLFloaterReg::showInstance("mute");
+ LLPanelBlockedList::showPanelAndSelect(mute.mID);
}
return true;
diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp
index dfb1c330e5..177c987bc0 100644
--- a/indra/newview/llviewermessage.cpp
+++ b/indra/newview/llviewermessage.cpp
@@ -82,7 +82,6 @@
#include "llfloaterregioninfo.h"
#include "llfloaterlandholdings.h"
#include "llurldispatcher.h"
-#include "llfloatermute.h"
#include "llfloaterpostcard.h"
#include "llfloaterpreference.h"
#include "llfollowcam.h"
@@ -138,6 +137,7 @@
#include "llgroupactions.h"
#include "llagentui.h"
#include "llsidetray.h"
+#include "llpanelblockedlist.h"
#include "llpanelplaceinfo.h"
#include <boost/tokenizer.hpp>
@@ -1001,9 +1001,7 @@ void inventory_offer_mute_callback(const LLUUID& blocked_id,
LLMute mute(blocked_id, from_name, type);
if (LLMuteList::getInstance()->add(mute))
{
- LLFloaterReg::showInstance("mute");
- LLFloaterMute* mute_instance = LLFloaterReg::getTypedInstance<LLFloaterMute>("mute");
- if(mute_instance) mute_instance->selectMute(blocked_id);
+ LLPanelBlockedList::showPanelAndSelect(blocked_id);
}
// purge the message queue of any previously queued inventory offers from the same source.
@@ -5576,7 +5574,7 @@ void process_covenant_reply(LLMessageSystem* msg, void**)
LLPanelLandCovenant::updateEstateName(estate_name);
LLFloaterBuyLand::updateEstateName(estate_name);
- LLPanelPlaceInfo* panel = dynamic_cast<LLPanelPlaceInfo*>(LLSideTray::getInstance()->showPanel("panel_place_info", LLSD()));
+ LLPanelPlaceInfo* panel = LLSideTray::getInstance()->findChild<LLPanelPlaceInfo>("panel_place_info");
if (panel)
{
panel->updateEstateName(estate_name);
@@ -5660,7 +5658,7 @@ void callbackCacheEstateOwnerName(const LLUUID& id,
LLPanelLandCovenant::updateEstateOwnerName(name);
LLFloaterBuyLand::updateEstateOwnerName(name);
- LLPanelPlaceInfo* panel = dynamic_cast<LLPanelPlaceInfo*>(LLSideTray::getInstance()->showPanel("panel_place_info", LLSD()));
+ LLPanelPlaceInfo* panel = LLSideTray::getInstance()->findChild<LLPanelPlaceInfo>("panel_place_info");
if (panel)
{
panel->updateEstateOwnerName(name);
diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index 607c5d9ae8..241c6fd511 100644
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -1596,8 +1596,6 @@ void LLViewerWindow::initWorldUI()
gFloaterView->setRect(floater_view_rect);
gNotifyBoxView->setRect(notify_view_rect);
- // *Note: this is where gFloaterMute used to be initialized.
-
LLWorldMapView::initClass();
// Force gFloaterWorldMap to initialize
@@ -1636,6 +1634,11 @@ void LLViewerWindow::initWorldUI()
navbar->showFavoritesPanel(FALSE);
}
+ if (!gSavedSettings.getBOOL("ShowCameraAndMoveControls"))
+ {
+ LLBottomTray::getInstance()->showCameraAndMoveControls(FALSE);
+ }
+
getRootView()->addChild(gStatusBar);
getRootView()->addChild(navbar);
@@ -1668,6 +1671,9 @@ void LLViewerWindow::initWorldUI()
// put behind everything else in the UI
getRootView()->addChildInBack(gHUDView);
}
+
+ // this allows not to see UI elements created while UI initializing after Alt+Tab was pressed during login. EXT-744.
+ moveProgressViewToFront();
}
// Destroy the UI
@@ -4417,8 +4423,7 @@ void LLViewerWindow::moveProgressViewToFront()
{
if( mProgressView && mRootView )
{
- mRootView->removeChild( mProgressView );
- mRootView->addChild( mProgressView );
+ mRootView->sendChildToFront(mProgressView);
}
}
diff --git a/indra/newview/skins/default/textures/textures.xml b/indra/newview/skins/default/textures/textures.xml
index 0bd5f114ed..e32ea0944e 100644
--- a/indra/newview/skins/default/textures/textures.xml
+++ b/indra/newview/skins/default/textures/textures.xml
@@ -93,6 +93,7 @@
<texture name="Info_Press" file_name="navbar/Info_Press.png" preload="false"/>
<texture name="ListItem_Select" file_name="widgets/ListItem_Select.png" preload="true" />
+ <texture name="ListItem_Over" file_name="widgets/ListItem_Over.png" preload="true" />
<texture name="menu_separator" file_name="navbar/FileMenu_Divider.png" scale.left="4" scale.top="166" scale.right="0" scale.bottom="0" />
diff --git a/indra/newview/skins/default/xui/en/menu_people_friends_view_sort.xml b/indra/newview/skins/default/xui/en/menu_people_friends_view_sort.xml
index bb5a4e51f7..6ef1eb9513 100644
--- a/indra/newview/skins/default/xui/en/menu_people_friends_view_sort.xml
+++ b/indra/newview/skins/default/xui/en/menu_people_friends_view_sort.xml
@@ -15,4 +15,8 @@
<menu_item_call name="organize_offline" label="Organize Offline Friends">
<menu_item_call.on_click function="People.Friends.ViewSort.Action" userdata="organize_offline" />
</menu_item_call>
+ <menu_item_separator layout="topleft" />
+ <menu_item_call name="show_blocked_list" label="Show Blocked Residents &amp; Objects">
+ <menu_item_call.on_click function="SideTray.ShowPanel" parameter="panel_block_list_sidetray" />
+ </menu_item_call>
</menu>
diff --git a/indra/newview/skins/default/xui/en/menu_people_nearby_view_sort.xml b/indra/newview/skins/default/xui/en/menu_people_nearby_view_sort.xml
index 8c2c5e8c9e..2b0f029016 100644
--- a/indra/newview/skins/default/xui/en/menu_people_nearby_view_sort.xml
+++ b/indra/newview/skins/default/xui/en/menu_people_nearby_view_sort.xml
@@ -15,4 +15,8 @@
<menu_item_call name="view_icons" label="View People Icons">
<menu_item_call.on_click function="People.Nearby.ViewSort.Action" userdata="view_icons" />
</menu_item_call>
+ <menu_item_separator layout="topleft" />
+ <menu_item_call name="show_blocked_list" label="Show Blocked Residents &amp; Objects">
+ <menu_item_call.on_click function="SideTray.ShowPanel" userdata="panel_block_list_sidetray" />
+ </menu_item_call>
</menu>
diff --git a/indra/newview/skins/default/xui/en/menu_people_recent_view_sort.xml b/indra/newview/skins/default/xui/en/menu_people_recent_view_sort.xml
index 00cf443cc6..88b0528e53 100644
--- a/indra/newview/skins/default/xui/en/menu_people_recent_view_sort.xml
+++ b/indra/newview/skins/default/xui/en/menu_people_recent_view_sort.xml
@@ -12,4 +12,8 @@
<menu_item_call name="view_icons" label="View People Icons">
<menu_item_call.on_click function="People.Recent.ViewSort.Action" userdata="view_icons" />
</menu_item_call>
+ <menu_item_separator layout="topleft" />
+ <menu_item_call name="show_blocked_list" label="Show Blocked Residents &amp; Objects">
+ <menu_item_call.on_click function="SideTray.ShowPanel" userdata="panel_block_list_sidetray" />
+ </menu_item_call>
</menu>
diff --git a/indra/newview/skins/default/xui/en/panel_block_list_sidetray.xml b/indra/newview/skins/default/xui/en/panel_block_list_sidetray.xml
new file mode 100644
index 0000000000..5c8a8ee208
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_block_list_sidetray.xml
@@ -0,0 +1,84 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel
+ background_visible="true"
+ follows="left|top|right|bottom"
+ height="305"
+ layout="topleft"
+ name="block_list_panel"
+ min_height="350"
+ min_width="240"
+ width="280">
+ <text
+ follows="top|left|right"
+ font="SansSerifHugeBold"
+ height="20"
+ layout="topleft"
+ left="10"
+ name="title_text"
+ text_color="white"
+ top="0"
+ width="250">
+ Blocked List
+ </text>
+ <button
+ follows="top|right"
+ height="25"
+ image_overlay="BackArrow_Off"
+ layout="topleft"
+ name="back"
+ right="-9"
+ tab_stop="false"
+ top="0"
+ width="25"/>
+ <scroll_list
+ follows="left|top|right|bottom"
+ height="200"
+ layout="topleft"
+ left="5"
+ name="blocked"
+ tool_tip="List of currently blocked residents"
+ top="30"
+ width="270" />
+ <button
+ follows="left|bottom"
+ height="20"
+ label="Block Resident..."
+ label_selected="Block Resident..."
+ layout="topleft"
+ left_delta="0"
+ name="Block resident..."
+ tool_tip="Pick a resident to block"
+ top_pad="4"
+ width="210">
+ <button.commit_callback
+ function="Block.ClickPick" />
+ </button>
+ <button
+ follows="left|bottom"
+ height="20"
+ label="Block object by name..."
+ label_selected="Block object by name..."
+ layout="topleft"
+ left_delta="0"
+ name="Block object by name..."
+ top_pad="4"
+ width="210" >
+ <button.commit_callback
+ function="Block.ClickBlockByName" />
+ </button>
+ <button
+ enabled="false"
+ follows="left|bottom"
+ height="20"
+ label="Unblock"
+ label_selected="Unblock"
+ layout="topleft"
+ left_delta="0"
+ name="Unblock"
+ tool_tip="Remove resident or object from blocked list"
+ top_pad="4"
+ width="210" >
+ <button.commit_callback
+ function="Block.ClickRemove" />
+ </button>
+</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_bottomtray.xml b/indra/newview/skins/default/xui/en/panel_bottomtray.xml
index 8fc029bea6..79ca839f28 100644
--- a/indra/newview/skins/default/xui/en/panel_bottomtray.xml
+++ b/indra/newview/skins/default/xui/en/panel_bottomtray.xml
@@ -266,7 +266,7 @@
top="2"
width="48">
<button
- image_selected="bottom_tray_sys_notifications.tga"
+ image_selected="bottom_tray_sys_notifications_selected.tga"
image_unselected="bottom_tray_sys_notifications.tga"/>
<unread_notifications
width="20"
diff --git a/indra/newview/skins/default/xui/en/panel_edit_profile.xml b/indra/newview/skins/default/xui/en/panel_edit_profile.xml
index fa02cdb4b2..0d6d8ba97d 100644
--- a/indra/newview/skins/default/xui/en/panel_edit_profile.xml
+++ b/indra/newview/skins/default/xui/en/panel_edit_profile.xml
@@ -13,10 +13,44 @@
top="10"
width="255">
<string
+ name="CaptionTextAcctInfo">
+ [ACCTTYPE] [PAYMENTINFO] [AGEVERIFICATION]
+ </string>
+ <string
+ name="AcctTypeResident"
+ value="Resident" />
+ <string
+ name="AcctTypeTrial"
+ value="Trial" />
+ <string
+ name="AcctTypeCharterMember"
+ value="Charter Member" />
+ <string
+ name="AcctTypeEmployee"
+ value="Linden Lab Employee" />
+ <string
+ name="PaymentInfoUsed"
+ value="Payment Info Used" />
+ <string
+ name="PaymentInfoOnFile"
+ value="Payment Info On File" />
+ <string
+ name="NoPaymentInfoOnFile"
+ value="No Payment Info On File" />
+ <string
+ name="AgeVerified"
+ value="Age-verified" />
+ <string
+ name="NotAgeVerified"
+ value="Not Age-verified" />
+ <string
name="partner_edit_link_url">
http://www.secondlife.com/account/partners.php?lang=en
</string>
- <scroll_container
+ <string
+ name="no_partner_text"
+ value="None" />
+ <scroll_container
color="DkGray2"
follows="left|top|right|bottom"
height="300"
@@ -38,7 +72,7 @@
background_visible="true"
bg_alpha_color="DkGray2"
follows="left|top|right|bottom"
- height="620"
+ height="750"
layout="topleft"
left="0"
name="data_panel"
diff --git a/indra/newview/skins/default/xui/en/panel_group_notify.xml b/indra/newview/skins/default/xui/en/panel_group_notify.xml
index 8ebf1b69a7..f97daf922f 100644
--- a/indra/newview/skins/default/xui/en/panel_group_notify.xml
+++ b/indra/newview/skins/default/xui/en/panel_group_notify.xml
@@ -1,8 +1,12 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<panel background_visible="true" bevel_style="in" bg_alpha_color="0 0 0 0"
- height="200" label="instant_message" layout="topleft" left="0"
+ height="155" label="instant_message" layout="topleft" left="0"
name="panel_group_notify" top="0" width="350">
- <panel background_visible="true" bevel_style="in" bg_alpha_color="black"
+ <string
+ name="message_max_lines_count">
+ 4
+ </string>
+ <panel follows="top" background_visible="true" bevel_style="in" bg_alpha_color="black"
height="50" label="header" layout="topleft" left="0" name="header"
top="0" width="350">
<icon follows="left|top|right|bottom" height="40" width="40" layout="topleft"
@@ -13,21 +17,61 @@
Sender Name / Group Name
</text>
</panel>
- <text_editor type="string" length="1" bg_readonly_color="0 0 0 0"
- follows="left|top|right|bottom" height="70" hide_scrollbar="true"
- hide_border="true" layout="topleft" top="55" left="25" name="message"
- text_color="GroupNotifyTextColor" text_readonly_color="GroupNotifyTextColor" width="300" word_wrap="true">
- Message
- Body
- </text_editor>
- <icon follows="left|top|right|bottom" height="16" width="16"
- layout="topleft" top="135" left="25" mouse_opaque="true" name="attachment_icon" />
+ <text
+ follows="top"
+ height="20"
+ layout="topleft"
+ left="25"
+ name="subject"
+ text_color="GroupNotifyTextColor"
+ font="SansSerifBig"
+ top="60"
+ use_ellipses="true"
+ value="subject"
+ width="300"
+ word_wrap="true">
+ subject
+ </text>
+ <text
+ follows="top"
+ height="20"
+ layout="topleft"
+ left="25"
+ name="datetime"
+ text_color="GroupNotifyTextColor"
+ font="SansSerif"
+ top="80"
+ use_ellipses="true"
+ value="datetime"
+ width="300"
+ word_wrap="true">
+ datetime
+ </text>
+ <text
+ follows="left|top|bottom|right"
+ height="0"
+ layout="topleft"
+ left="25"
+ name="message"
+ text_color="GroupNotifyTextColor"
+ top="100"
+ use_ellipses="true"
+ value="message"
+ width="300"
+ word_wrap="true"
+ visible="true" >
+ </text>
+ <icon
+ follows="left|bottom|right" height="15" width="15"
+ layout="topleft" bottom="122" left="25" mouse_opaque="true" name="attachment_icon" visible="true"
+ />
<text font="SansSerif" font.style="UNDERLINE" font_shadow="hard"
- type="string" length="1" follows="left|top|right|bottom" layout="topleft"
- left="45" top="135" height="15" width="280" name="attachment"
- text_color="GroupNotifyTextColor">
+ type="string" length="1" follows="left|bottom|right" layout="topleft"
+ left="45" bottom="122" height="15" width="280" name="attachment"
+ text_color="GroupNotifyTextColor" visible="true">
Attachment
- </text>
- <button label="OK" layout="topleft" top="170" left="140" height="20"
- width="70" name="btn_ok" />
-</panel>
+ </text>
+
+ <button label="OK" layout="topleft" bottom="145" left="140" height="20"
+ width="70" name="btn_ok" follows="bottom" />
+</panel> \ No newline at end of file
diff --git a/indra/newview/skins/default/xui/en/panel_instant_message.xml b/indra/newview/skins/default/xui/en/panel_instant_message.xml
index 169fde7b47..ace456918c 100644
--- a/indra/newview/skins/default/xui/en/panel_instant_message.xml
+++ b/indra/newview/skins/default/xui/en/panel_instant_message.xml
@@ -10,6 +10,10 @@
name="im_panel"
top="0"
width="350">
+ <string
+ name="message_max_lines_count">
+ 6
+ </string>
<panel
background_visible="true"
bevel_style="in"
@@ -56,7 +60,7 @@
width="50" />
</panel>
<text
- follows="left|bottom|right"
+ follows="left|top|bottom|right"
height="60"
layout="topleft"
left="10"
diff --git a/indra/newview/skins/default/xui/en/panel_navigation_bar.xml b/indra/newview/skins/default/xui/en/panel_navigation_bar.xml
index dee911a45d..80dca8c0c1 100644
--- a/indra/newview/skins/default/xui/en/panel_navigation_bar.xml
+++ b/indra/newview/skins/default/xui/en/panel_navigation_bar.xml
@@ -107,8 +107,8 @@
<!-- picture_style="true" -->
<!-- top_delta="0" -->
<!-- width="168" /> -->
-
- <search_editor
+
+ <search_combo_box
bevel_style="none"
border_style="line"
border.border_thickness="0"
@@ -118,12 +118,15 @@
height="22"
label="Search"
layout="topleft"
- left_pad="7"
+ right="-10"
mouse_opaque="false"
- name="search_input"
+ name="search_combo_box"
tool_tip="Search"
top_delta="0"
- width="200" />
+ width="200" >
+ <combo_editor
+ label="Search" />
+ </search_combo_box>
</panel>
<favorites_bar
diff --git a/indra/newview/skins/default/xui/en/panel_pick_list_item.xml b/indra/newview/skins/default/xui/en/panel_pick_list_item.xml
index 6f4110067b..4c8c4efbe7 100644
--- a/indra/newview/skins/default/xui/en/panel_pick_list_item.xml
+++ b/indra/newview/skins/default/xui/en/panel_pick_list_item.xml
@@ -8,6 +8,26 @@
name="picture_item"
top="0"
width="275">
+ <icon
+ height="120"
+ image_name="ListItem_Over"
+ left="0"
+ mouse_opaque="false"
+ name="hovered_icon"
+ top="0"
+ scale_image="true"
+ visible="false"
+ width="270"/>
+ <icon
+ height="120"
+ image_name="ListItem_Select"
+ left="0"
+ mouse_opaque="false"
+ name="selected_icon"
+ top="0"
+ scale_image="true"
+ visible="false"
+ width="270"/>
<texture_picker
allow_no_texture="true"
default_image_name="None"
diff --git a/indra/newview/skins/default/xui/en/panel_side_tray.xml b/indra/newview/skins/default/xui/en/panel_side_tray.xml
index e9eac2c9dc..e166675364 100644
--- a/indra/newview/skins/default/xui/en/panel_side_tray.xml
+++ b/indra/newview/skins/default/xui/en/panel_side_tray.xml
@@ -57,6 +57,13 @@
label="Group Info"
border="true"
/>
+ <panel
+ class="panel_block_list_sidetray"
+ name="panel_block_list_sidetray"
+ filename="panel_block_list_sidetray.xml"
+ label="Blocked Residents &amp; Objects"
+ border="true"
+ />
</panel_container>
</sidetray_tab>
diff --git a/indra/newview/skins/default/xui/en/widgets/accordion_tab.xml b/indra/newview/skins/default/xui/en/widgets/accordion_tab.xml
new file mode 100644
index 0000000000..eabacbecb2
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/widgets/accordion_tab.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<accordion_tab
+ header_collapse_img="accordion_collapsed.tga"
+ header_collapse_img_pressed="accordion_collapsed.tga"
+ header_expand_img="accordion_expanded.tga"
+ header_expand_img_pressed="accordion_expanded.tga" />
diff --git a/indra/newview/skins/default/xui/en/widgets/list.xml b/indra/newview/skins/default/xui/en/widgets/list.xml
index 8c264205d5..4a59716464 100644
--- a/indra/newview/skins/default/xui/en/widgets/list.xml
+++ b/indra/newview/skins/default/xui/en/widgets/list.xml
@@ -6,4 +6,5 @@
background_visible="false"
background_opaque="false"
item_pad="5"
+ keep_one_selected="true"
multi_select="false" /> \ No newline at end of file
diff --git a/indra/newview/skins/default/xui/en/widgets/location_input.xml b/indra/newview/skins/default/xui/en/widgets/location_input.xml
index 8f4d0edf95..297a3762f6 100644
--- a/indra/newview/skins/default/xui/en/widgets/location_input.xml
+++ b/indra/newview/skins/default/xui/en/widgets/location_input.xml
@@ -43,7 +43,7 @@
label=""
pad_right="0"
tool_tip="My Location History"/>
- <combo_list bg_writeable_color="MenuDefaultBgColor"/>
+ <combo_list bg_writeable_color="MenuDefaultBgColor" page_lines="10"/>
<combo_editor name="Combo Text Entry"
text_pad_left="20"
select_on_focus="false"
diff --git a/indra/newview/skins/default/xui/en/widgets/search_combo_box.xml b/indra/newview/skins/default/xui/en/widgets/search_combo_box.xml
new file mode 100644
index 0000000000..1d43b25f1d
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/widgets/search_combo_box.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<search_combo_box
+ allow_text_entry="true"
+ list_position="BELOW"
+ show_text_as_tentative="false"
+ dropdown_button_visible="false"
+ background_image="TextField_Search_Off"
+ background_image_disabled="TextField_Search_Disabled"
+ background_image_focused="TextField_Search_Active">
+ <combo_editor
+ select_on_focus="true"
+ text_pad_left="20"
+ background_image="TextField_Search_Off"
+ background_image_disabled="TextField_Search_Disabled"
+ background_image_focused="TextField_Search_Active"/>
+ <combo_list
+ multi_select="false"
+ page_lines="10" />
+ <search_button label=""
+ top_pad="4"
+ left_pad="4"
+ width="13"
+ height="13"
+ image_unselected="Search"
+ image_selected="Search" />
+</search_combo_box> \ No newline at end of file