summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.hgignore1
-rw-r--r--.hgtags4
-rw-r--r--autobuild.xml12
-rw-r--r--indra/cmake/VisualLeakDetector.cmake15
-rw-r--r--indra/cmake/WebKitLibPlugin.cmake7
-rw-r--r--indra/edit-me-to-trigger-new-build.txt0
-rw-r--r--indra/llmath/llcoord.h23
-rw-r--r--indra/llui/llclipboard.cpp136
-rw-r--r--indra/llui/llclipboard.h72
-rw-r--r--indra/llui/llfloater.cpp271
-rw-r--r--indra/llui/llfloater.h32
-rw-r--r--indra/llui/llfloaterreg.cpp41
-rw-r--r--indra/llui/llfloaterreg.h4
-rw-r--r--indra/llui/lllayoutstack.cpp73
-rw-r--r--indra/llui/lllayoutstack.h2
-rw-r--r--indra/llui/lllineeditor.cpp19
-rw-r--r--indra/llui/llscrollcontainer.cpp15
-rw-r--r--indra/llui/llscrollcontainer.h6
-rw-r--r--indra/llui/llscrolllistctrl.cpp2
-rw-r--r--indra/llui/lltexteditor.cpp20
-rw-r--r--indra/llui/llview.cpp225
-rw-r--r--indra/llui/llview.h2
-rw-r--r--indra/llwindow/llwindow.cpp23
-rw-r--r--indra/llwindow/llwindow.h2
-rw-r--r--indra/llwindow/llwindowheadless.h1
-rw-r--r--indra/llwindow/llwindowmacosx.cpp25
-rw-r--r--indra/llwindow/llwindowmacosx.h1
-rw-r--r--indra/llwindow/llwindowsdl.cpp19
-rw-r--r--indra/llwindow/llwindowsdl.h1
-rw-r--r--indra/llwindow/llwindowwin32.cpp49
-rw-r--r--indra/llwindow/llwindowwin32.h1
-rw-r--r--indra/newview/CMakeLists.txt3
-rw-r--r--indra/newview/app_settings/settings.xml72
-rw-r--r--indra/newview/app_settings/settings_per_account.xml22
-rw-r--r--indra/newview/llappviewerwin32.cpp12
-rwxr-xr-xindra/newview/llavataractions.cpp5
-rw-r--r--indra/newview/llfavoritesbar.cpp12
-rw-r--r--indra/newview/llfloaterbuycontents.cpp4
-rw-r--r--indra/newview/llfloatergesture.cpp27
-rw-r--r--indra/newview/llfloatergodtools.cpp6
-rw-r--r--indra/newview/llfloaterland.cpp14
-rw-r--r--indra/newview/llfloaterregioninfo.cpp30
-rw-r--r--indra/newview/llfloaterregioninfo.h3
-rw-r--r--indra/newview/llfloaterreporter.cpp6
-rw-r--r--indra/newview/llfloatersellland.cpp6
-rw-r--r--indra/newview/llfloatervoiceeffect.cpp4
-rw-r--r--indra/newview/llfloaterwebcontent.cpp4
-rw-r--r--indra/newview/llfolderview.cpp136
-rw-r--r--indra/newview/llfolderview.h59
-rw-r--r--indra/newview/llfoldervieweventlistener.h2
-rw-r--r--indra/newview/llfolderviewitem.cpp45
-rw-r--r--indra/newview/llfolderviewitem.h3
-rw-r--r--indra/newview/llinventorybridge.cpp382
-rw-r--r--indra/newview/llinventorybridge.h6
-rw-r--r--indra/newview/llinventoryfilter.cpp89
-rw-r--r--indra/newview/llinventoryfilter.h2
-rw-r--r--indra/newview/llinventoryfunctions.cpp85
-rw-r--r--indra/newview/llinventoryfunctions.h4
-rw-r--r--indra/newview/llinventorymodel.cpp115
-rw-r--r--indra/newview/llinventorypanel.cpp15
-rw-r--r--indra/newview/llinventorypanel.h1
-rw-r--r--indra/newview/llpanelgroupinvite.cpp12
-rw-r--r--indra/newview/llpanellandmarks.cpp5
-rw-r--r--indra/newview/llpanelmaininventory.cpp4
-rw-r--r--indra/newview/llpanelobjectinventory.cpp7
-rw-r--r--indra/newview/llpanelteleporthistory.cpp2
-rw-r--r--indra/newview/llpaneltopinfobar.cpp2
-rw-r--r--indra/newview/llpanelwearing.cpp2
-rw-r--r--indra/newview/llsidepanelinventory.cpp26
-rw-r--r--indra/newview/lltoolbarview.cpp14
-rw-r--r--indra/newview/lltoolbarview.h3
-rw-r--r--indra/newview/lltooldraganddrop.cpp3
-rw-r--r--indra/newview/llurllineeditorctrl.cpp2
-rw-r--r--indra/newview/llviewermenu.cpp47
-rwxr-xr-xindra/newview/llviewermessage.cpp2
-rwxr-xr-xindra/newview/llviewerwindow.cpp24
-rw-r--r--indra/newview/llvoavatar.cpp10
-rw-r--r--indra/newview/skins/default/xui/de/panel_status_bar.xml2
-rw-r--r--indra/newview/skins/default/xui/en/floater_about.xml2
-rw-r--r--indra/newview/skins/default/xui/en/floater_about_land.xml2
-rw-r--r--indra/newview/skins/default/xui/en/floater_avatar.xml4
-rw-r--r--indra/newview/skins/default/xui/en/floater_avatar_picker.xml2
-rw-r--r--indra/newview/skins/default/xui/en/floater_camera.xml7
-rw-r--r--indra/newview/skins/default/xui/en/floater_chat_bar.xml6
-rw-r--r--indra/newview/skins/default/xui/en/floater_critical.xml2
-rw-r--r--indra/newview/skins/default/xui/en/floater_destinations.xml2
-rw-r--r--indra/newview/skins/default/xui/en/floater_gesture.xml2
-rw-r--r--indra/newview/skins/default/xui/en/floater_help_browser.xml2
-rw-r--r--indra/newview/skins/default/xui/en/floater_joystick.xml50
-rw-r--r--indra/newview/skins/default/xui/en/floater_land_holdings.xml2
-rw-r--r--indra/newview/skins/default/xui/en/floater_map.xml2
-rw-r--r--indra/newview/skins/default/xui/en/floater_merchant_outbox.xml4
-rw-r--r--indra/newview/skins/default/xui/en/floater_moveview.xml6
-rw-r--r--indra/newview/skins/default/xui/en/floater_my_appearance.xml2
-rw-r--r--indra/newview/skins/default/xui/en/floater_my_inventory.xml2
-rw-r--r--indra/newview/skins/default/xui/en/floater_people.xml2
-rw-r--r--indra/newview/skins/default/xui/en/floater_picks.xml2
-rw-r--r--indra/newview/skins/default/xui/en/floater_places.xml2
-rw-r--r--indra/newview/skins/default/xui/en/floater_preferences.xml2
-rw-r--r--indra/newview/skins/default/xui/en/floater_search.xml2
-rw-r--r--indra/newview/skins/default/xui/en/floater_snapshot.xml2
-rw-r--r--indra/newview/skins/default/xui/en/floater_test_text_editor.xml1
-rw-r--r--indra/newview/skins/default/xui/en/floater_test_widgets.xml2
-rw-r--r--indra/newview/skins/default/xui/en/floater_tools.xml3
-rw-r--r--indra/newview/skins/default/xui/en/floater_toybox.xml2
-rw-r--r--indra/newview/skins/default/xui/en/floater_voice_controls.xml2
-rw-r--r--indra/newview/skins/default/xui/en/floater_voice_effect.xml9
-rw-r--r--indra/newview/skins/default/xui/en/floater_world_map.xml2
-rw-r--r--indra/newview/skins/default/xui/en/menu_inventory.xml8
-rw-r--r--indra/newview/skins/default/xui/en/menu_viewer.xml13
-rw-r--r--indra/newview/skins/default/xui/en/panel_chat_item.xml1
-rw-r--r--indra/newview/skins/default/xui/en/panel_postcard_settings.xml1
-rw-r--r--indra/newview/skins/default/xui/en/panel_snapshot_inventory.xml1
-rw-r--r--indra/newview/skins/default/xui/en/panel_snapshot_local.xml1
-rw-r--r--indra/newview/skins/default/xui/en/panel_snapshot_profile.xml1
-rw-r--r--indra/newview/skins/default/xui/en/panel_status_bar.xml4
-rw-r--r--indra/newview/skins/default/xui/en/panel_toast.xml1
-rw-r--r--indra/newview/skins/default/xui/en/sidepanel_inventory.xml5
-rw-r--r--indra/newview/skins/default/xui/en/widgets/floater.xml2
-rw-r--r--indra/newview/skins/default/xui/es/panel_status_bar.xml2
-rw-r--r--indra/newview/skins/default/xui/fr/panel_status_bar.xml2
-rw-r--r--indra/newview/skins/default/xui/it/panel_status_bar.xml2
-rw-r--r--indra/newview/skins/default/xui/ja/panel_status_bar.xml2
-rw-r--r--indra/newview/skins/default/xui/pt/panel_status_bar.xml2
-rw-r--r--indra/newview/skins/default/xui/ru/panel_status_bar.xml2
-rw-r--r--indra/newview/skins/default/xui/tr/panel_status_bar.xml2
126 files changed, 1821 insertions, 808 deletions
diff --git a/.hgignore b/.hgignore
index 403b73df6d..bc3020eee4 100644
--- a/.hgignore
+++ b/.hgignore
@@ -67,3 +67,4 @@ glob:indra/newview/filters.xml
glob:indra/newview/avatar_icons_cache.txt
glob:indra/newview/avatar_lad.log
glob:*.diff
+*.rej
diff --git a/.hgtags b/.hgtags
index 1ae758e8ea..3dcd15b9d3 100644
--- a/.hgtags
+++ b/.hgtags
@@ -271,6 +271,10 @@ e9c82fca5ae6fb8a8af29012d78fb194a29323f3 3.2.9-beta1
a01ef9bed28627f4ca543fbc1d70c79cc297a90f DRTVWR-118_3.2.9-beta2
a01ef9bed28627f4ca543fbc1d70c79cc297a90f 3.2.9-beta2
987425b1acf4752379b2e1eb20944b4b35d67a85 3.2.8-beta2
+d5f263687f43f278107363365938f0a214920a4b DRTVWR-119
+d5f263687f43f278107363365938f0a214920a4b 3.3.0-beta1
+5e8d2662f38a66eca6c591295f5880d47afc73f7 viewer-release-candidate
+5e8d2662f38a66eca6c591295f5880d47afc73f7 3.3.0-release
d5f263687f43f278107363365938f0a214920a4b 3.3.0-start
dffd0457ee0745de65bf95f0642a5c9e46b8e2f0 viewer-beta-candidate
d5f263687f43f278107363365938f0a214920a4b DRTVWR-119
diff --git a/autobuild.xml b/autobuild.xml
index 9914be6867..0e4b81324a 100644
--- a/autobuild.xml
+++ b/autobuild.xml
@@ -1206,9 +1206,9 @@
<key>archive</key>
<map>
<key>hash</key>
- <string>26aa7c367ffadd573f61a6a96f820f80</string>
+ <string>4a98d727561cd1f4ac5ee02907411df1</string>
<key>url</key>
- <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-llqtwebkit/rev/245988/arch/Darwin/installer/llqtwebkit-4.7.1-darwin-20111201.tar.bz2</string>
+ <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-llqtwebkit/rev/250147/arch/Darwin/installer/llqtwebkit-4.7.1-darwin-20120228.tar.bz2</string>
</map>
<key>name</key>
<string>darwin</string>
@@ -1218,9 +1218,9 @@
<key>archive</key>
<map>
<key>hash</key>
- <string>c05a33ee8b6f253b5a744596dfc3707d</string>
+ <string>f50e5f0cc880c55b3f0f7e67dc8f7221</string>
<key>url</key>
- <string>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/llqtwebkit-linux-qt4.6-20101013.tar.bz2</string>
+ <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-llqtwebkit/rev/250147/arch/Linux/installer/llqtwebkit-4.7.1-linux-20120228.tar.bz2</string>
</map>
<key>name</key>
<string>linux</string>
@@ -1230,9 +1230,9 @@
<key>archive</key>
<map>
<key>hash</key>
- <string>270db8568a0c4bab266d98e1a820aec4</string>
+ <string>5e3cd6af397e853a963a6de40d440ff4</string>
<key>url</key>
- <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-llqtwebkit/rev/245988/arch/CYGWIN/installer/llqtwebkit-4.7.1-windows-20111201.tar.bz2</string>
+ <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-llqtwebkit/rev/250147/arch/CYGWIN/installer/llqtwebkit-4.7.1-windows-20120228.tar.bz2</string>
</map>
<key>name</key>
<string>windows</string>
diff --git a/indra/cmake/VisualLeakDetector.cmake b/indra/cmake/VisualLeakDetector.cmake
new file mode 100644
index 0000000000..d3ba554e46
--- /dev/null
+++ b/indra/cmake/VisualLeakDetector.cmake
@@ -0,0 +1,15 @@
+# -*- cmake -*-
+
+if (VIEWER)
+
+ set(INCLUDE_VLD_CMAKE OFF CACHE BOOL "Build the Windows viewer with Visual Leak Detector turned on or off")
+
+ if (INCLUDE_VLD_CMAKE)
+
+ if (WINDOWS)
+ add_definitions(-DINCLUDE_VLD=1)
+ endif (WINDOWS)
+
+ endif (INCLUDE_VLD_CMAKE)
+
+endif (VIEWER)
diff --git a/indra/cmake/WebKitLibPlugin.cmake b/indra/cmake/WebKitLibPlugin.cmake
index 91b49e75d7..d9df78bfc8 100644
--- a/indra/cmake/WebKitLibPlugin.cmake
+++ b/indra/cmake/WebKitLibPlugin.cmake
@@ -70,9 +70,10 @@ elseif (LINUX)
QtNetwork
QtGui
QtCore
- qgif
- qjpeg
- jpeg
+ jscore
+# qgif
+# qjpeg
+# jpeg
fontconfig
X11
Xrender
diff --git a/indra/edit-me-to-trigger-new-build.txt b/indra/edit-me-to-trigger-new-build.txt
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/indra/edit-me-to-trigger-new-build.txt
diff --git a/indra/llmath/llcoord.h b/indra/llmath/llcoord.h
index 1f617e649e..9b76268afd 100644
--- a/indra/llmath/llcoord.h
+++ b/indra/llmath/llcoord.h
@@ -26,6 +26,15 @@
#ifndef LL_LLCOORD_H
#define LL_LLCOORD_H
+template<typename> class LLCoord;
+struct LL_COORD_TYPE_GL;
+struct LL_COORD_TYPE_WINDOW;
+struct LL_COORD_TYPE_SCREEN;
+
+typedef LLCoord<LL_COORD_TYPE_GL> LLCoordGL;
+typedef LLCoord<LL_COORD_TYPE_WINDOW> LLCoordWindow;
+typedef LLCoord<LL_COORD_TYPE_SCREEN> LLCoordScreen;
+
struct LLCoordCommon
{
LLCoordCommon(S32 x, S32 y) : mX(x), mY(y) {}
@@ -45,7 +54,7 @@ public:
LLCoord(): mX(0), mY(0)
{}
- LLCoord(S32 x, S32 y): mX(x), mY(y)
+ LLCoord(typename COORD_FRAME::value_t x, typename COORD_FRAME::value_t y): mX(x), mY(y)
{}
LLCoord(const LLCoordCommon& other)
@@ -58,10 +67,12 @@ public:
return COORD_FRAME::convertToCommon();
}
- void set(S32 x, S32 y) { mX = x; mY = y;}
+ void set(typename COORD_FRAME::value_t x, typename COORD_FRAME::value_t y) { mX = x; mY = y;}
bool operator==(const self_t& other) const { return mX == other.mX && mY == other.mY; }
bool operator!=(const self_t& other) const { return !(*this == other); }
+ static const self_t& getTypedCoords(const COORD_FRAME& self) { return static_cast<const self_t&>(self); }
+ static self_t& getTypedCoords(COORD_FRAME& self) { return static_cast<self_t&>(self); }
};
struct LL_COORD_TYPE_GL
@@ -70,13 +81,13 @@ struct LL_COORD_TYPE_GL
LLCoordCommon convertToCommon() const
{
- const LLCoord<LL_COORD_TYPE_GL>& self = static_cast<const LLCoord<LL_COORD_TYPE_GL>&>(*this);
+ const LLCoordGL& self = LLCoordGL::getTypedCoords(*this);
return LLCoordCommon(self.mX, self.mY);
}
void convertFromCommon(const LLCoordCommon& from)
{
- LLCoord<LL_COORD_TYPE_GL>& self = static_cast<LLCoord<LL_COORD_TYPE_GL>&>(*this);
+ LLCoordGL& self = LLCoordGL::getTypedCoords(*this);
self.mX = from.mX;
self.mY = from.mY;
}
@@ -98,8 +109,4 @@ struct LL_COORD_TYPE_SCREEN
void convertFromCommon(const LLCoordCommon& from);
};
-typedef LLCoord<LL_COORD_TYPE_GL> LLCoordGL;
-typedef LLCoord<LL_COORD_TYPE_WINDOW> LLCoordWindow;
-typedef LLCoord<LL_COORD_TYPE_SCREEN> LLCoordScreen;
-
#endif
diff --git a/indra/llui/llclipboard.cpp b/indra/llui/llclipboard.cpp
index 6910b962a1..14173fdbb0 100644
--- a/indra/llui/llclipboard.cpp
+++ b/indra/llui/llclipboard.cpp
@@ -34,109 +34,113 @@
#include "llview.h"
#include "llwindow.h"
-// Global singleton
-LLClipboard gClipboard;
-
-
-LLClipboard::LLClipboard()
+LLClipboard::LLClipboard() :
+ mGeneration(0)
{
- mSourceItem = NULL;
+ reset();
}
-
LLClipboard::~LLClipboard()
{
+ reset();
}
-
-void LLClipboard::copyFromSubstring(const LLWString &src, S32 pos, S32 len, const LLUUID& source_id )
+void LLClipboard::reset()
{
- mSourceID = source_id;
- mString = src.substr(pos, len);
- LLView::getWindow()->copyTextToClipboard( mString );
+ // Increment the clipboard count
+ mGeneration++;
+ // Clear the clipboard
+ mObjects.clear();
+ mCutMode = false;
+ mString = LLWString();
}
-void LLClipboard::copyFromString(const LLWString &src, const LLUUID& source_id )
+// Copy the input uuid to the LL clipboard
+bool LLClipboard::copyToClipboard(const LLUUID& src, const LLAssetType::EType type)
{
- mSourceID = source_id;
- mString = src;
- LLView::getWindow()->copyTextToClipboard( mString );
+ reset();
+ return addToClipboard(src, type);
}
-const LLWString& LLClipboard::getPasteWString( LLUUID* source_id )
+// Add the input uuid to the LL clipboard
+// Convert the uuid to string and concatenate that string to the system clipboard if legit
+bool LLClipboard::addToClipboard(const LLUUID& src, const LLAssetType::EType type)
{
- if( mSourceID.notNull() )
+ bool res = false;
+ if (src.notNull())
{
- LLWString temp_string;
- LLView::getWindow()->pasteTextFromClipboard(temp_string);
-
- if( temp_string != mString )
+ res = true;
+ if (LLAssetType::lookupIsAssetIDKnowable(type))
{
- mSourceID.setNull();
- mString = temp_string;
+ LLWString source = utf8str_to_wstring(src.asString());
+ res = addToClipboard(source, 0, source.size());
+ }
+ if (res)
+ {
+ mObjects.push_back(src);
+ mGeneration++;
}
}
- else
- {
- LLView::getWindow()->pasteTextFromClipboard(mString);
- }
+ return res;
+}
- if( source_id )
+bool LLClipboard::pasteFromClipboard(std::vector<LLUUID>& inv_objects) const
+{
+ bool res = false;
+ S32 count = mObjects.size();
+ if (count > 0)
{
- *source_id = mSourceID;
+ res = true;
+ inv_objects.clear();
+ for (S32 i = 0; i < count; i++)
+ {
+ inv_objects.push_back(mObjects[i]);
+ }
}
-
- return mString;
+ return res;
}
+// Returns true if the LL Clipboard has pasteable items in it
+bool LLClipboard::hasContents() const
+{
+ return (mObjects.size() > 0);
+}
-BOOL LLClipboard::canPasteString() const
+// Returns true if the input uuid is in the list of clipboard objects
+bool LLClipboard::isOnClipboard(const LLUUID& object) const
{
- return LLView::getWindow()->isClipboardTextAvailable();
+ std::vector<LLUUID>::const_iterator iter = std::find(mObjects.begin(), mObjects.end(), object);
+ return (iter != mObjects.end());
}
+// Copy the input string to the LL and the system clipboard
+bool LLClipboard::copyToClipboard(const LLWString &src, S32 pos, S32 len, bool use_primary)
+{
+ return addToClipboard(src, pos, len, use_primary);
+}
-void LLClipboard::copyFromPrimarySubstring(const LLWString &src, S32 pos, S32 len, const LLUUID& source_id )
+// Concatenate the input string to the LL and the system clipboard
+bool LLClipboard::addToClipboard(const LLWString &src, S32 pos, S32 len, bool use_primary)
{
- mSourceID = source_id;
mString = src.substr(pos, len);
- LLView::getWindow()->copyTextToPrimary( mString );
+ return (use_primary ? LLView::getWindow()->copyTextToPrimary(mString) : LLView::getWindow()->copyTextToClipboard(mString));
}
-
-const LLWString& LLClipboard::getPastePrimaryWString( LLUUID* source_id )
+// Copy the System clipboard to the output string.
+// Manage the LL Clipboard / System clipboard consistency
+bool LLClipboard::pasteFromClipboard(LLWString &dst, bool use_primary)
{
- if( mSourceID.notNull() )
- {
- LLWString temp_string;
- LLView::getWindow()->pasteTextFromPrimary(temp_string);
-
- if( temp_string != mString )
- {
- mSourceID.setNull();
- mString = temp_string;
- }
- }
- else
- {
- LLView::getWindow()->pasteTextFromPrimary(mString);
- }
-
- if( source_id )
+ bool res = (use_primary ? LLView::getWindow()->pasteTextFromPrimary(dst) : LLView::getWindow()->pasteTextFromClipboard(dst));
+ if (res)
{
- *source_id = mSourceID;
+ mString = dst;
}
-
- return mString;
+ return res;
}
-
-BOOL LLClipboard::canPastePrimaryString() const
+// Return true if there's something on the System clipboard
+bool LLClipboard::isTextAvailable(bool use_primary) const
{
- return LLView::getWindow()->isPrimaryTextAvailable();
+ return (use_primary ? LLView::getWindow()->isPrimaryTextAvailable() : LLView::getWindow()->isClipboardTextAvailable());
}
-void LLClipboard::setSourceObject(const LLUUID& source_id, LLAssetType::EType type)
-{
- mSourceItem = new LLInventoryObject (source_id, LLUUID::null, type, "");
-}
diff --git a/indra/llui/llclipboard.h b/indra/llui/llclipboard.h
index 9371b94284..fd2e7610df 100644
--- a/indra/llui/llclipboard.h
+++ b/indra/llui/llclipboard.h
@@ -27,46 +27,68 @@
#ifndef LL_LLCLIPBOARD_H
#define LL_LLCLIPBOARD_H
+#include <boost/function.hpp>
#include "llstring.h"
#include "lluuid.h"
#include "stdenums.h"
+#include "llsingleton.h"
+#include "llassettype.h"
#include "llinventory.h"
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// Class LLClipboard
+//
+// This class is used to cut/copy/paste text strings and inventory items around
+// the world. Use LLClipboard::instance().method() to use its methods.
+// Note that the text and UUIDs are loosely coupled only. There are few cases
+// where the viewer does offer a serialized version of the UUID on the clipboard.
+// In those case, the text is overridden when copying/cutting the item.
+// In all other cases, the text and the UUIDs are very much independent.
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-class LLClipboard
+class LLClipboard : public LLSingleton<LLClipboard>
{
public:
LLClipboard();
~LLClipboard();
+
+ // Clears the clipboard
+ void reset();
+ // Returns the state of the clipboard so client can know if it has been modified (comparing with tracked state)
+ int getGeneration() const { return mGeneration; }
- /* We support two flavors of clipboard. The default is the explicitly
- copy-and-pasted clipboard. The second is the so-called 'primary' clipboard
- which is implicitly copied upon selection on platforms which expect this
- (i.e. X11/Linux). */
-
- void copyFromSubstring(const LLWString &copy_from, S32 pos, S32 len, const LLUUID& source_id = LLUUID::null );
- void copyFromString(const LLWString &copy_from, const LLUUID& source_id = LLUUID::null );
- BOOL canPasteString() const;
- const LLWString& getPasteWString(LLUUID* source_id = NULL);
+ // Text strings management:
+ // ------------------------
+ // We support two flavors of text clipboards. The default is the explicitly
+ // copy-and-pasted clipboard. The second is the so-called 'primary' clipboard
+ // which is implicitly copied upon selection on platforms which expect this
+ // (i.e. X11/Linux, Mac).
+ bool copyToClipboard(const LLWString& src, S32 pos, S32 len, bool use_primary = false);
+ bool addToClipboard(const LLWString& src, S32 pos, S32 len, bool use_primary = false);
+ bool pasteFromClipboard(LLWString& dst, bool use_primary = false);
+ bool isTextAvailable(bool use_primary = false) const;
+
+ // Object list management:
+ // -----------------------
+ // Clears and adds one single object to the clipboard
+ bool copyToClipboard(const LLUUID& src, const LLAssetType::EType type = LLAssetType::AT_NONE);
+ // Adds one object to the current list of objects on the clipboard
+ bool addToClipboard(const LLUUID& src, const LLAssetType::EType type = LLAssetType::AT_NONE);
+ // Gets a copy of the objects on the clipboard
+ bool pasteFromClipboard(std::vector<LLUUID>& inventory_objects) const;
+
+ bool hasContents() const; // True if the clipboard has pasteable objects
+ bool isOnClipboard(const LLUUID& object) const; // True if the input object uuid is on the clipboard
- void copyFromPrimarySubstring(const LLWString &copy_from, S32 pos, S32 len, const LLUUID& source_id = LLUUID::null );
- BOOL canPastePrimaryString() const;
- const LLWString& getPastePrimaryWString(LLUUID* source_id = NULL);
+ bool isCutMode() const { return mCutMode; }
+ void setCutMode(bool mode) { mCutMode = mode; mGeneration++; }
- // Support clipboard for object known only by their uuid and asset type
- void setSourceObject(const LLUUID& source_id, LLAssetType::EType type);
- const LLInventoryObject* getSourceObject() { return mSourceItem; }
-
private:
- LLUUID mSourceID;
- LLWString mString;
- LLInventoryObject* mSourceItem;
+ std::vector<LLUUID> mObjects; // Objects on the clipboard. Can be empty while mString contains something licit (e.g. text from chat)
+ LLWString mString; // The text string. If mObjects is not empty, this string is reflecting them (UUIDs for the moment) if the asset type is knowable.
+ bool mCutMode; // This is a convenience flag for the viewer.
+ int mGeneration; // Incremented when the clipboard changes so that interested parties can check for changes on the clipboard.
};
-
-// Global singleton
-extern LLClipboard gClipboard;
-
-
#endif // LL_LLCLIPBOARD_H
diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp
index 22b20969fc..a8a3a1f906 100644
--- a/indra/llui/llfloater.cpp
+++ b/indra/llui/llfloater.cpp
@@ -68,10 +68,10 @@ namespace LLInitParam
{
void TypeValues<LLFloaterEnums::EOpenPositioning>::declareValues()
{
- declare("none", LLFloaterEnums::OPEN_POSITIONING_NONE);
- declare("cascading", LLFloaterEnums::OPEN_POSITIONING_CASCADING);
- declare("centered", LLFloaterEnums::OPEN_POSITIONING_CENTERED);
- declare("specified", LLFloaterEnums::OPEN_POSITIONING_SPECIFIED);
+ declare("relative", LLFloaterEnums::POSITIONING_RELATIVE);
+ declare("cascading", LLFloaterEnums::POSITIONING_CASCADING);
+ declare("centered", LLFloaterEnums::POSITIONING_CENTERED);
+ declare("specified", LLFloaterEnums::POSITIONING_SPECIFIED);
}
}
@@ -177,9 +177,7 @@ LLFloater::Params::Params()
save_visibility("save_visibility", false),
can_dock("can_dock", false),
show_title("show_title", true),
- open_positioning("open_positioning", LLFloaterEnums::OPEN_POSITIONING_NONE),
- specified_left("specified_left"),
- specified_bottom("specified_bottom"),
+ positioning("positioning", LLFloaterEnums::POSITIONING_RELATIVE),
header_height("header_height", 0),
legacy_header_height("legacy_header_height", 0),
close_image("close_image"),
@@ -249,9 +247,7 @@ LLFloater::LLFloater(const LLSD& key, const LLFloater::Params& p)
mCanClose(p.can_close),
mDragOnLeft(p.can_drag_on_left),
mResizable(p.can_resize),
- mOpenPositioning(p.open_positioning),
- mSpecifiedLeft(p.specified_left),
- mSpecifiedBottom(p.specified_bottom),
+ mPositioning(p.positioning),
mMinWidth(p.min_width),
mMinHeight(p.min_height),
mHeaderHeight(p.header_height),
@@ -547,10 +543,18 @@ LLFloater::~LLFloater()
void LLFloater::storeRectControl()
{
- if( mRectControl.size() > 1 )
+ if (!mRectControl.empty())
{
getControlGroup()->setRect( mRectControl, getRect() );
}
+ if (!mPosXControl.empty() && mPositioning == LLFloaterEnums::POSITIONING_RELATIVE)
+ {
+ getControlGroup()->setF32( mPosXControl, mPosition.mX );
+ }
+ if (!mPosYControl.empty() && mPositioning == LLFloaterEnums::POSITIONING_RELATIVE)
+ {
+ getControlGroup()->setF32( mPosYControl, mPosition.mY );
+ }
}
void LLFloater::storeVisibilityControl()
@@ -569,23 +573,6 @@ void LLFloater::storeDockStateControl()
}
}
-LLRect LLFloater::getSavedRect() const
-{
- LLRect rect;
-
- if (mRectControl.size() > 1)
- {
- rect = getControlGroup()->getRect(mRectControl);
- }
-
- return rect;
-}
-
-bool LLFloater::hasSavedRect() const
-{
- return !getSavedRect().isEmpty();
-}
-
// static
std::string LLFloater::getControlName(const std::string& name, const LLSD& key)
{
@@ -863,7 +850,7 @@ void LLFloater::applyControlsAndPosition(LLFloater* other)
{
if (!applyRectControl())
{
- applyPositioning(other);
+ applyPositioning(other, true);
}
}
}
@@ -872,29 +859,68 @@ bool LLFloater::applyRectControl()
{
bool saved_rect = false;
+ LLRect screen_rect = calcScreenRect();
+ mPosition = LLCoordGL(screen_rect.getCenterX(), screen_rect.getCenterY()).convert();
+
LLFloater* last_in_group = LLFloaterReg::getLastFloaterInGroup(mInstanceName);
if (last_in_group && last_in_group != this)
{
// other floaters in our group, position ourselves relative to them and don't save the rect
mRectControl.clear();
- mOpenPositioning = LLFloaterEnums::OPEN_POSITIONING_CASCADE_GROUP;
+ mPositioning = LLFloaterEnums::POSITIONING_CASCADE_GROUP;
}
- else if (mRectControl.size() > 1)
+ else
{
- // If we have a saved rect, use it
- const LLRect& rect = getControlGroup()->getRect(mRectControl);
- saved_rect = rect.notEmpty();
- if (saved_rect)
+ bool rect_specified = false;
+ if (!mRectControl.empty())
{
- setOrigin(rect.mLeft, rect.mBottom);
-
- if (mResizable)
+ // If we have a saved rect, use it
+ const LLRect& rect = getControlGroup()->getRect(mRectControl);
+ if (rect.notEmpty()) saved_rect = true;
+ if (saved_rect)
{
- reshape(llmax(mMinWidth, rect.getWidth()), llmax(mMinHeight, rect.getHeight()));
+ setOrigin(rect.mLeft, rect.mBottom);
+
+ if (mResizable)
+ {
+ reshape(llmax(mMinWidth, rect.getWidth()), llmax(mMinHeight, rect.getHeight()));
+ }
+ mPositioning = LLFloaterEnums::POSITIONING_RELATIVE;
+ LLRect screen_rect = calcScreenRect();
+ mPosition = LLCoordGL(screen_rect.getCenterX(), screen_rect.getCenterY()).convert();
+ rect_specified = true;
}
}
+
+ LLControlVariablePtr x_control = getControlGroup()->getControl(mPosXControl);
+ LLControlVariablePtr y_control = getControlGroup()->getControl(mPosYControl);
+ if (x_control.notNull()
+ && y_control.notNull()
+ && !x_control->isDefault()
+ && !y_control->isDefault())
+ {
+ mPosition.mX = x_control->getValue().asReal();
+ mPosition.mY = y_control->getValue().asReal();
+ mPositioning = LLFloaterEnums::POSITIONING_RELATIVE;
+ applyRelativePosition();
+
+ saved_rect = true;
+ }
+
+ // remember updated position
+ if (rect_specified)
+ {
+ storeRectControl();
+ }
+ }
+
+ if (saved_rect)
+ {
+ // propagate any derived positioning data back to settings file
+ storeRectControl();
}
+
return saved_rect;
}
@@ -911,50 +937,56 @@ bool LLFloater::applyDockState()
return docked;
}
-void LLFloater::applyPositioning(LLFloater* other)
+void LLFloater::applyPositioning(LLFloater* other, bool on_open)
{
// Otherwise position according to the positioning code
- switch (mOpenPositioning)
+ switch (mPositioning)
{
- case LLFloaterEnums::OPEN_POSITIONING_CENTERED:
+ case LLFloaterEnums::POSITIONING_CENTERED:
center();
break;
- case LLFloaterEnums::OPEN_POSITIONING_SPECIFIED:
- {
- // Translate relative to snap rect
- setOrigin(mSpecifiedLeft, mSpecifiedBottom);
- const LLRect& snap_rect = gFloaterView->getSnapRect();
- translate(snap_rect.mLeft, snap_rect.mBottom);
- translateIntoRect(snap_rect);
- }
+ case LLFloaterEnums::POSITIONING_SPECIFIED:
break;
- case LLFloaterEnums::OPEN_POSITIONING_CASCADE_GROUP:
- case LLFloaterEnums::OPEN_POSITIONING_CASCADING:
- if (other != NULL && other != this)
+ case LLFloaterEnums::POSITIONING_CASCADING:
+ if (!on_open)
{
- stackWith(*other);
+ applyRelativePosition();
}
- else
+ // fall through
+ case LLFloaterEnums::POSITIONING_CASCADE_GROUP:
+ if (on_open)
{
- static const U32 CASCADING_FLOATER_HOFFSET = 0;
- static const U32 CASCADING_FLOATER_VOFFSET = 0;
+ if (other != NULL && other != this)
+ {
+ stackWith(*other);
+ }
+ else
+ {
+ static const U32 CASCADING_FLOATER_HOFFSET = 0;
+ static const U32 CASCADING_FLOATER_VOFFSET = 0;
- const LLRect& snap_rect = gFloaterView->getSnapRect();
+ const LLRect& snap_rect = gFloaterView->getSnapRect();
- const S32 horizontal_offset = CASCADING_FLOATER_HOFFSET;
- const S32 vertical_offset = snap_rect.getHeight() - CASCADING_FLOATER_VOFFSET;
+ const S32 horizontal_offset = CASCADING_FLOATER_HOFFSET;
+ const S32 vertical_offset = snap_rect.getHeight() - CASCADING_FLOATER_VOFFSET;
- S32 rect_height = getRect().getHeight();
- setOrigin(horizontal_offset, vertical_offset - rect_height);
+ S32 rect_height = getRect().getHeight();
+ setOrigin(horizontal_offset, vertical_offset - rect_height);
- translate(snap_rect.mLeft, snap_rect.mBottom);
- translateIntoRect(snap_rect);
+ translate(snap_rect.mLeft, snap_rect.mBottom);
+ }
+ setFollows(FOLLOWS_TOP | FOLLOWS_LEFT);
}
break;
- case LLFloaterEnums::OPEN_POSITIONING_NONE:
+ case LLFloaterEnums::POSITIONING_RELATIVE:
+ {
+ applyRelativePosition();
+
+ break;
+ }
default:
// Do nothing
break;
@@ -1072,7 +1104,9 @@ void LLFloater::handleReshape(const LLRect& new_rect, bool by_user)
if (by_user && !isMinimized())
{
storeRectControl();
- mOpenPositioning = LLFloaterEnums::OPEN_POSITIONING_NONE;
+ mPositioning = LLFloaterEnums::POSITIONING_RELATIVE;
+ LLRect screen_rect = calcScreenRect();
+ mPosition = LLCoordGL(screen_rect.getCenterX(), screen_rect.getCenterY()).convert();
}
// if not minimized, adjust all snapped dependents to new shape
@@ -1250,6 +1284,7 @@ void LLFloater::setMinimized(BOOL minimize)
// Reshape *after* setting mMinimized
reshape( mExpandedRect.getWidth(), mExpandedRect.getHeight(), TRUE );
+ applyPositioning(NULL, false);
}
make_ui_sound("UISndWindowClose");
@@ -1590,7 +1625,7 @@ void LLFloater::setDocked(bool docked, bool pop_on_undock)
if (mDocked)
{
setMinimized(FALSE);
- mOpenPositioning = LLFloaterEnums::OPEN_POSITIONING_NONE;
+ mPositioning = LLFloaterEnums::POSITIONING_RELATIVE;
}
updateTitleButtons();
@@ -1624,7 +1659,7 @@ void LLFloater::onClickTearOff(LLFloater* self)
self->openFloater(self->getKey());
// only force position for floaters that don't have that data saved
- if (self->mRectControl.size() <= 1)
+ if (self->mRectControl.empty())
{
new_rect.setLeftTopAndSize(host_floater->getRect().mLeft + 5, host_floater->getRect().mTop - floater_header_size - 5, self->getRect().getWidth(), self->getRect().getHeight());
self->setRect(new_rect);
@@ -2164,19 +2199,14 @@ LLFloaterView::LLFloaterView (const Params& p)
mSnapOffsetBottom(0),
mSnapOffsetRight(0)
{
+ mSnapView = getHandle();
}
// By default, adjust vertical.
void LLFloaterView::reshape(S32 width, S32 height, BOOL called_from_parent)
{
- S32 old_right = mLastSnapRect.mRight;
- S32 old_top = mLastSnapRect.mTop;
-
LLView::reshape(width, height, called_from_parent);
- S32 new_right = getSnapRect().mRight;
- S32 new_top = getSnapRect().mTop;
-
mLastSnapRect = getSnapRect();
for ( child_list_const_iter_t child_it = getChildList()->begin(); child_it != getChildList()->end(); ++child_it)
@@ -2189,35 +2219,39 @@ void LLFloaterView::reshape(S32 width, S32 height, BOOL called_from_parent)
continue;
}
- if (!floaterp->isMinimized())
+ if (!floaterp->isMinimized() && floaterp->getCanDrag())
{
- LLRect r = floaterp->getRect();
+ LLRect old_rect = floaterp->getRect();
+ floaterp->applyPositioning(NULL, false);
+ LLRect new_rect = floaterp->getRect();
- // Compute absolute distance from each edge of screen
- S32 left_offset = llabs(r.mLeft - 0);
- S32 right_offset = llabs(old_right - r.mRight);
+ //LLRect r = floaterp->getRect();
- S32 top_offset = llabs(old_top - r.mTop);
- S32 bottom_offset = llabs(r.mBottom - 0);
+ //// Compute absolute distance from each edge of screen
+ //S32 left_offset = llabs(r.mLeft - 0);
+ //S32 right_offset = llabs(old_right - r.mRight);
- S32 translate_x = 0;
- S32 translate_y = 0;
+ //S32 top_offset = llabs(old_top - r.mTop);
+ //S32 bottom_offset = llabs(r.mBottom - 0);
- if (left_offset > right_offset)
- {
- translate_x = new_right - old_right;
- }
+ S32 translate_x = new_rect.mLeft - old_rect.mLeft;
+ S32 translate_y = new_rect.mBottom - old_rect.mBottom;
- if (top_offset < bottom_offset)
- {
- translate_y = new_top - old_top;
- }
+ //if (left_offset > right_offset)
+ //{
+ // translate_x = new_right - old_right;
+ //}
+
+ //if (top_offset < bottom_offset)
+ //{
+ // translate_y = new_top - old_top;
+ //}
// don't reposition immovable floaters
- if (floaterp->getCanDrag())
- {
- floaterp->translate(translate_x, translate_y);
- }
+ //if (floaterp->getCanDrag())
+ //{
+ // floaterp->translate(translate_x, translate_y);
+ //}
BOOST_FOREACH(LLHandle<LLFloater> dependent_floater, floaterp->mDependents)
{
if (dependent_floater.get())
@@ -2913,9 +2947,11 @@ void LLFloater::setInstanceName(const std::string& name)
std::string ctrl_name = getControlName(mInstanceName, mKey);
// save_rect and save_visibility only apply to registered floaters
- if (!mRectControl.empty())
+ if (mSaveRect)
{
mRectControl = LLFloaterReg::declareRectControl(ctrl_name);
+ mPosXControl = LLFloaterReg::declarePosXControl(ctrl_name);
+ mPosYControl = LLFloaterReg::declarePosYControl(ctrl_name);
}
if (!mVisibilityControl.empty())
{
@@ -2972,7 +3008,10 @@ void LLFloater::initFromParams(const LLFloater::Params& p)
LLPanel::initFromParams(p);
// override any follows flags
- setFollows(FOLLOWS_NONE);
+ if (mPositioning != LLFloaterEnums::POSITIONING_SPECIFIED)
+ {
+ setFollows(FOLLOWS_NONE);
+ }
mTitle = p.title;
mShortTitle = p.short_title;
@@ -2991,14 +3030,9 @@ void LLFloater::initFromParams(const LLFloater::Params& p)
mSingleInstance = p.single_instance;
mReuseInstance = p.reuse_instance.isProvided() ? p.reuse_instance : p.single_instance;
- mOpenPositioning = p.open_positioning;
- mSpecifiedLeft = p.specified_left;
- mSpecifiedBottom = p.specified_bottom;
+ mPositioning = p.positioning;
- if (p.save_rect && mRectControl.empty())
- {
- mRectControl = "t"; // flag to build mRectControl name once mInstanceName is set
- }
+ mSaveRect = p.save_rect;
if (p.save_visibility)
{
mVisibilityControl = "t"; // flag to build mVisibilityControl name once mInstanceName is set
@@ -3113,7 +3147,7 @@ bool LLFloater::initFloaterXML(LLXMLNodePtr node, LLView *parent, const std::str
params.rect.left.set(0);
}
params.from_xui = true;
- applyXUILayout(params, parent);
+ applyXUILayout(params, parent, parent == gFloaterView ? gFloaterView->getSnapRect() : parent->getLocalRect());
initFromParams(params);
initFloater(params);
@@ -3272,8 +3306,24 @@ void LLFloater::stackWith(LLFloater& other)
next_rect.setLeftTopAndSize(next_rect.mLeft, next_rect.mTop, getRect().getWidth(), getRect().getHeight());
setShape(next_rect);
+
+ other.mPositioning = LLFloaterEnums::POSITIONING_CASCADE_GROUP;
+ other.setFollows(FOLLOWS_LEFT | FOLLOWS_TOP);
}
+void LLFloater::applyRelativePosition()
+{
+ LLRect snap_rect = gFloaterView->getSnapRect();
+ LLRect floater_view_screen_rect = gFloaterView->calcScreenRect();
+ snap_rect.translate(floater_view_screen_rect.mLeft, floater_view_screen_rect.mBottom);
+ LLRect floater_screen_rect = calcScreenRect();
+
+ LLCoordGL new_center = mPosition.convert();
+ LLCoordGL cur_center(floater_screen_rect.getCenterX(), floater_screen_rect.getCenterY());
+ translate(new_center.mX - cur_center.mX, new_center.mY - cur_center.mY);
+}
+
+
LLCoordFloater::LLCoordFloater(F32 x, F32 y, LLFloater& floater)
: coord_t((S32)x, (S32)y)
{
@@ -3306,9 +3356,12 @@ bool LLCoordFloater::operator==(const LLCoordFloater& other) const
LLCoordCommon LL_COORD_FLOATER::convertToCommon() const
{
- const LLCoordFloater& self = static_cast<const LLCoordFloater&>(*this);
+ const LLCoordFloater& self = static_cast<const LLCoordFloater&>(LLCoordFloater::getTypedCoords(*this));
LLRect snap_rect = gFloaterView->getSnapRect();
+ LLRect floater_view_screen_rect = gFloaterView->calcScreenRect();
+ snap_rect.translate(floater_view_screen_rect.mLeft, floater_view_screen_rect.mBottom);
+
LLFloater* floaterp = mFloater.get();
S32 floater_width = floaterp ? floaterp->getRect().getWidth() : 0;
S32 floater_height = floaterp ? floaterp->getRect().getHeight() : 0;
@@ -3348,8 +3401,12 @@ LLCoordCommon LL_COORD_FLOATER::convertToCommon() const
void LL_COORD_FLOATER::convertFromCommon(const LLCoordCommon& from)
{
- LLCoordFloater& self = static_cast<LLCoordFloater&>(*this);
+ LLCoordFloater& self = static_cast<LLCoordFloater&>(LLCoordFloater::getTypedCoords(*this));
LLRect snap_rect = gFloaterView->getSnapRect();
+ LLRect floater_view_screen_rect = gFloaterView->calcScreenRect();
+ snap_rect.translate(floater_view_screen_rect.mLeft, floater_view_screen_rect.mBottom);
+
+
LLFloater* floaterp = mFloater.get();
S32 floater_width = floaterp ? floaterp->getRect().getWidth() : 0;
S32 floater_height = floaterp ? floaterp->getRect().getHeight() : 0;
diff --git a/indra/llui/llfloater.h b/indra/llui/llfloater.h
index a7cc9ae961..64d6dcea04 100644
--- a/indra/llui/llfloater.h
+++ b/indra/llui/llfloater.h
@@ -64,12 +64,12 @@ namespace LLFloaterEnums
{
enum EOpenPositioning
{
- OPEN_POSITIONING_NONE,
- OPEN_POSITIONING_CASCADING,
- OPEN_POSITIONING_CASCADE_GROUP,
- OPEN_POSITIONING_CENTERED,
- OPEN_POSITIONING_SPECIFIED,
- OPEN_POSITIONING_COUNT
+ POSITIONING_RELATIVE,
+ POSITIONING_CASCADING,
+ POSITIONING_CASCADE_GROUP,
+ POSITIONING_CENTERED,
+ POSITIONING_SPECIFIED,
+ POSITIONING_COUNT
};
}
@@ -163,10 +163,7 @@ public:
can_dock,
show_title;
- Optional<LLFloaterEnums::EOpenPositioning> open_positioning;
- Optional<S32> specified_left;
- Optional<S32> specified_bottom;
-
+ Optional<LLFloaterEnums::EOpenPositioning> positioning;
Optional<S32> header_height,
legacy_header_height; // HACK see initFromXML()
@@ -272,8 +269,6 @@ public:
BOOL isResizable() const { return mResizable; }
void setResizeLimits( S32 min_width, S32 min_height );
void getResizeLimits( S32* min_width, S32* min_height ) { *min_width = mMinWidth; *min_height = mMinHeight; }
- LLRect getSavedRect() const;
- bool hasSavedRect() const;
static std::string getControlName(const std::string& name, const LLSD& key);
static LLControlGroup* getControlGroup();
@@ -355,7 +350,7 @@ public:
void enableResizeCtrls(bool enable, bool width = true, bool height = true);
- bool isPositioning(LLFloaterEnums::EOpenPositioning p) const { return (p == mOpenPositioning); }
+ bool isPositioning(LLFloaterEnums::EOpenPositioning p) const { return (p == mPositioning); }
protected:
void applyControlsAndPosition(LLFloater* other);
@@ -363,7 +358,9 @@ protected:
virtual bool applyRectControl();
bool applyDockState();
- void applyPositioning(LLFloater* other);
+ void applyPositioning(LLFloater* other, bool on_open);
+ void applyRelativePosition();
+
void storeRectControl();
void storeVisibilityControl();
void storeDockStateControl();
@@ -427,7 +424,10 @@ public:
commit_signal_t* mMinimizeSignal;
protected:
+ bool mSaveRect;
std::string mRectControl;
+ std::string mPosXControl;
+ std::string mPosYControl;
std::string mVisibilityControl;
std::string mDocStateControl;
LLSD mKey; // Key used for retrieving instances; set (for now) by LLFLoaterReg
@@ -453,9 +453,7 @@ private:
BOOL mDragOnLeft;
BOOL mResizable;
- LLFloaterEnums::EOpenPositioning mOpenPositioning;
- S32 mSpecifiedLeft;
- S32 mSpecifiedBottom;
+ LLFloaterEnums::EOpenPositioning mPositioning;
LLCoordFloater mPosition;
S32 mMinWidth;
diff --git a/indra/llui/llfloaterreg.cpp b/indra/llui/llfloaterreg.cpp
index e144b68f5e..9115eb7174 100644
--- a/indra/llui/llfloaterreg.cpp
+++ b/indra/llui/llfloaterreg.cpp
@@ -96,7 +96,9 @@ LLFloater* LLFloaterReg::getLastFloaterCascading()
{
LLFloater* inst = *iter;
- if (inst->getVisible() && inst->isPositioning(LLFloaterEnums::OPEN_POSITIONING_CASCADING))
+ if (inst->getVisible()
+ && (inst->isPositioning(LLFloaterEnums::POSITIONING_CASCADING)
+ || inst->isPositioning(LLFloaterEnums::POSITIONING_CASCADE_GROUP)))
{
if (candidate_rect.mTop > inst->getRect().mTop)
{
@@ -358,9 +360,7 @@ void LLFloaterReg::restoreVisibleInstances()
//static
std::string LLFloaterReg::getRectControlName(const std::string& name)
{
- std::string res = std::string("floater_rect_") + name;
- LLStringUtil::replaceChar( res, ' ', '_' );
- return res;
+ return std::string("floater_rect_") + getBaseControlName(name);
}
//static
@@ -368,19 +368,48 @@ std::string LLFloaterReg::declareRectControl(const std::string& name)
{
std::string controlname = getRectControlName(name);
LLFloater::getControlGroup()->declareRect(controlname, LLRect(),
- llformat("Window Position and Size for %s", name.c_str()),
+ llformat("Window Size for %s", name.c_str()),
TRUE);
return controlname;
}
+std::string LLFloaterReg::declarePosXControl(const std::string& name)
+{
+ std::string controlname = std::string("floater_pos_") + getBaseControlName(name) + "_x";
+ LLFloater::getControlGroup()->declareF32(controlname,
+ 10.f,
+ llformat("Window X Position for %s", name.c_str()),
+ TRUE);
+ return controlname;
+}
+
+std::string LLFloaterReg::declarePosYControl(const std::string& name)
+{
+ std::string controlname = std::string("floater_pos_") + getBaseControlName(name) + "_y";
+ LLFloater::getControlGroup()->declareF32(controlname,
+ 10.f,
+ llformat("Window Y Position for %s", name.c_str()),
+ TRUE);
+
+ return controlname;
+}
+
+
//static
std::string LLFloaterReg::getVisibilityControlName(const std::string& name)
{
- std::string res = std::string("floater_vis_") + name;
+ return std::string("floater_vis_") + getBaseControlName(name);
+}
+
+//static
+std::string LLFloaterReg::getBaseControlName(const std::string& name)
+{
+ std::string res(name);
LLStringUtil::replaceChar( res, ' ', '_' );
return res;
}
+
//static
std::string LLFloaterReg::declareVisibilityControl(const std::string& name)
{
diff --git a/indra/llui/llfloaterreg.h b/indra/llui/llfloaterreg.h
index 534cf8b40a..a1e1f8a988 100644
--- a/indra/llui/llfloaterreg.h
+++ b/indra/llui/llfloaterreg.h
@@ -115,9 +115,11 @@ public:
// Control Variables
static std::string getRectControlName(const std::string& name);
static std::string declareRectControl(const std::string& name);
+ static std::string declarePosXControl(const std::string& name);
+ static std::string declarePosYControl(const std::string& name);
static std::string getVisibilityControlName(const std::string& name);
static std::string declareVisibilityControl(const std::string& name);
-
+ static std::string getBaseControlName(const std::string& name);
static std::string declareDockStateControl(const std::string& name);
static std::string getDockStateControlName(const std::string& name);
diff --git a/indra/llui/lllayoutstack.cpp b/indra/llui/lllayoutstack.cpp
index ae262f794e..4c730286da 100644
--- a/indra/llui/lllayoutstack.cpp
+++ b/indra/llui/lllayoutstack.cpp
@@ -113,7 +113,26 @@ S32 LLLayoutPanel::getLayoutDim() const
? getRect().getWidth()
: getRect().getHeight()));
}
-
+
+S32 LLLayoutPanel::getTargetDim() const
+{
+ return mTargetDim;
+}
+
+void LLLayoutPanel::setTargetDim(S32 value)
+{
+ LLRect new_rect(getRect());
+ if (mOrientation == LLLayoutStack::HORIZONTAL)
+ {
+ new_rect.mRight = new_rect.mLeft + value;
+ }
+ else
+ {
+ new_rect.mTop = new_rect.mBottom + value;
+ }
+ setShape(new_rect, true);
+}
+
S32 LLLayoutPanel::getVisibleDim() const
{
F32 min_dim = getRelevantMinDim();
@@ -172,12 +191,15 @@ void LLLayoutPanel::handleReshape(const LLRect& new_rect, bool by_user)
LLLayoutStack* stackp = dynamic_cast<LLLayoutStack*>(getParent());
if (stackp)
{
- stackp->mNeedsLayout = true;
if (by_user)
- {
- // tell layout stack to account for new shape
+ { // tell layout stack to account for new shape
+
+ // make sure that panels have already been auto resized
+ stackp->updateLayout();
+ // now apply requested size to panel
stackp->updatePanelRect(this, new_rect);
}
+ stackp->mNeedsLayout = true;
}
LLPanel::handleReshape(new_rect, by_user);
}
@@ -241,7 +263,6 @@ void LLLayoutStack::draw()
drawChild(panelp, 0, 0, !clip_rect.isEmpty());
}
}
- mAnimatedThisFrame = false;
}
void LLLayoutStack::removeChild(LLView* view)
@@ -310,7 +331,7 @@ void LLLayoutStack::updateLayout()
if (!mNeedsLayout) return;
- bool animation_in_progress = animatePanels();
+ bool continue_animating = animatePanels();
F32 total_visible_fraction = 0.f;
S32 space_to_distribute = (mOrientation == HORIZONTAL)
? getRect().getWidth()
@@ -415,7 +436,7 @@ void LLLayoutStack::updateLayout()
// clear animation flag at end, since panel resizes will set it
// and leave it set if there is any animation in progress
- mNeedsLayout = animation_in_progress;
+ mNeedsLayout = continue_animating;
} // end LLLayoutStack::updateLayout
LLLayoutPanel* LLLayoutStack::findEmbeddedPanel(LLPanel* panelp) const
@@ -488,6 +509,7 @@ void LLLayoutStack::updateClass()
for (instance_iter it = beginInstances(); it != endInstances(); ++it)
{
it->updateLayout();
+ it->mAnimatedThisFrame = false;
}
}
@@ -557,7 +579,7 @@ void LLLayoutStack::normalizeFractionalSizes()
bool LLLayoutStack::animatePanels()
{
- bool animation_in_progress = false;
+ bool continue_animating = false;
//
// animate visibility
@@ -577,14 +599,15 @@ bool LLLayoutStack::animatePanels()
}
}
- animation_in_progress = true;
+ mAnimatedThisFrame = true;
+ continue_animating = true;
}
else
{
if (panelp->mVisibleAmt != 1.f)
{
panelp->mVisibleAmt = 1.f;
- animation_in_progress = true;
+ mAnimatedThisFrame = true;
}
}
}
@@ -601,14 +624,15 @@ bool LLLayoutStack::animatePanels()
}
}
- animation_in_progress = true;
+ continue_animating = true;
+ mAnimatedThisFrame = true;
}
else
{
if (panelp->mVisibleAmt != 0.f)
{
panelp->mVisibleAmt = 0.f;
- animation_in_progress = true;
+ mAnimatedThisFrame = true;
}
}
}
@@ -616,22 +640,31 @@ bool LLLayoutStack::animatePanels()
F32 collapse_state = panelp->mCollapsed ? 1.f : 0.f;
if (panelp->mCollapseAmt != collapse_state)
{
- if (!mAnimatedThisFrame)
+ if (mAnimate)
{
- panelp->mCollapseAmt = lerp(panelp->mCollapseAmt, collapse_state, LLCriticalDamp::getInterpolant(mCloseTimeConstant));
- }
- animation_in_progress = true;
+ if (!mAnimatedThisFrame)
+ {
+ panelp->mCollapseAmt = lerp(panelp->mCollapseAmt, collapse_state, LLCriticalDamp::getInterpolant(mCloseTimeConstant));
+ }
- if (llabs(panelp->mCollapseAmt - collapse_state) < 0.001f)
+ if (llabs(panelp->mCollapseAmt - collapse_state) < 0.001f)
+ {
+ panelp->mCollapseAmt = collapse_state;
+ }
+
+ mAnimatedThisFrame = true;
+ continue_animating = true;
+ }
+ else
{
panelp->mCollapseAmt = collapse_state;
+ mAnimatedThisFrame = true;
}
}
}
- mAnimatedThisFrame = true;
-
- return animation_in_progress;
+ if (mAnimatedThisFrame) mNeedsLayout = true;
+ return continue_animating;
}
void LLLayoutStack::updatePanelRect( LLLayoutPanel* resized_panel, const LLRect& new_rect )
diff --git a/indra/llui/lllayoutstack.h b/indra/llui/lllayoutstack.h
index d32caec5f9..648cd5fdce 100644
--- a/indra/llui/lllayoutstack.h
+++ b/indra/llui/lllayoutstack.h
@@ -155,6 +155,8 @@ public:
void setVisible(BOOL visible);
S32 getLayoutDim() const;
+ S32 getTargetDim() const;
+ void setTargetDim(S32 value);
S32 getMinDim() const { return llmax(0, mMinDim); }
void setMinDim(S32 value) { mMinDim = value; }
diff --git a/indra/llui/lllineeditor.cpp b/indra/llui/lllineeditor.cpp
index 7e84814c51..d0fbf4b913 100644
--- a/indra/llui/lllineeditor.cpp
+++ b/indra/llui/lllineeditor.cpp
@@ -1047,7 +1047,7 @@ void LLLineEditor::cut()
// Prepare for possible rollback
LLLineEditorRollback rollback( this );
- gClipboard.copyFromSubstring( mText.getWString(), left_pos, length );
+ LLClipboard::instance().copyToClipboard( mText.getWString(), left_pos, length );
deleteSelection();
// Validate new string and rollback the if needed.
@@ -1078,13 +1078,13 @@ void LLLineEditor::copy()
{
S32 left_pos = llmin( mSelectionStart, mSelectionEnd );
S32 length = llabs( mSelectionStart - mSelectionEnd );
- gClipboard.copyFromSubstring( mText.getWString(), left_pos, length );
+ LLClipboard::instance().copyToClipboard( mText.getWString(), left_pos, length );
}
}
BOOL LLLineEditor::canPaste() const
{
- return !mReadOnly && gClipboard.canPasteString();
+ return !mReadOnly && LLClipboard::instance().isTextAvailable();
}
void LLLineEditor::paste()
@@ -1115,14 +1115,7 @@ void LLLineEditor::pasteHelper(bool is_primary)
if (can_paste_it)
{
LLWString paste;
- if (is_primary)
- {
- paste = gClipboard.getPastePrimaryWString();
- }
- else
- {
- paste = gClipboard.getPasteWString();
- }
+ LLClipboard::instance().pasteFromClipboard(paste, is_primary);
if (!paste.empty())
{
@@ -1209,13 +1202,13 @@ void LLLineEditor::copyPrimary()
{
S32 left_pos = llmin( mSelectionStart, mSelectionEnd );
S32 length = llabs( mSelectionStart - mSelectionEnd );
- gClipboard.copyFromPrimarySubstring( mText.getWString(), left_pos, length );
+ LLClipboard::instance().copyToClipboard( mText.getWString(), left_pos, length, true);
}
}
BOOL LLLineEditor::canPastePrimary() const
{
- return !mReadOnly && gClipboard.canPastePrimaryString();
+ return !mReadOnly && LLClipboard::instance().isTextAvailable(true);
}
void LLLineEditor::updatePrimary()
diff --git a/indra/llui/llscrollcontainer.cpp b/indra/llui/llscrollcontainer.cpp
index 20bed050ad..9b7e30bb04 100644
--- a/indra/llui/llscrollcontainer.cpp
+++ b/indra/llui/llscrollcontainer.cpp
@@ -389,10 +389,17 @@ void LLScrollContainer::calcVisibleSize( S32 *visible_width, S32 *visible_height
{
*show_h_scrollbar = TRUE;
*visible_height -= scrollbar_size;
- // Note: Do *not* recompute *show_v_scrollbar here because with
- // the (- scrollbar_size) we just did we will always add a vertical scrollbar
- // even if the height of the items is actually less than the visible size.
- // Fear not though: there's enough calcVisibleSize() calls to add a vertical slider later.
+
+ // The view inside the scroll container should not be extended
+ // to container's full height to ensure the correct computation
+ // of *show_v_scrollbar after subtracting horizontal scrollbar_size.
+
+ // Must retest now that visible_height has changed
+ if( !*show_v_scrollbar && ((doc_height - *visible_height) > 1) )
+ {
+ *show_v_scrollbar = TRUE;
+ *visible_width -= scrollbar_size;
+ }
}
}
}
diff --git a/indra/llui/llscrollcontainer.h b/indra/llui/llscrollcontainer.h
index 3aa79cc255..d87c95b3d7 100644
--- a/indra/llui/llscrollcontainer.h
+++ b/indra/llui/llscrollcontainer.h
@@ -91,7 +91,7 @@ public:
void setReserveScrollCorner( BOOL b ) { mReserveScrollCorner = b; }
LLRect getVisibleContentRect();
LLRect getContentWindowRect();
- const LLRect& getScrolledViewRect() const { return mScrolledView ? mScrolledView->getRect() : LLRect::null; }
+ virtual const LLRect getScrolledViewRect() const { return mScrolledView ? mScrolledView->getRect() : LLRect::null; }
void pageUp(S32 overlap = 0);
void pageDown(S32 overlap = 0);
void goToTop();
@@ -116,6 +116,9 @@ public:
bool autoScroll(S32 x, S32 y);
+protected:
+ LLView* mScrolledView;
+
private:
// internal scrollbar handlers
virtual void scrollHorizontal( S32 new_pos );
@@ -124,7 +127,6 @@ private:
void calcVisibleSize( S32 *visible_width, S32 *visible_height, BOOL* show_h_scrollbar, BOOL* show_v_scrollbar ) const;
LLScrollbar* mScrollbar[SCROLLBAR_COUNT];
- LLView* mScrolledView;
S32 mSize;
BOOL mIsOpaque;
LLUIColor mBackgroundColor;
diff --git a/indra/llui/llscrolllistctrl.cpp b/indra/llui/llscrolllistctrl.cpp
index 466fac33ea..b3e1b63db5 100644
--- a/indra/llui/llscrolllistctrl.cpp
+++ b/indra/llui/llscrolllistctrl.cpp
@@ -2504,7 +2504,7 @@ void LLScrollListCtrl::copy()
{
buffer += (*itor)->getContentsCSV() + "\n";
}
- gClipboard.copyFromSubstring(utf8str_to_wstring(buffer), 0, buffer.length());
+ LLClipboard::instance().copyToClipboard(utf8str_to_wstring(buffer), 0, buffer.length());
}
// virtual
diff --git a/indra/llui/lltexteditor.cpp b/indra/llui/lltexteditor.cpp
index 3409b6817d..9720dded6c 100644
--- a/indra/llui/lltexteditor.cpp
+++ b/indra/llui/lltexteditor.cpp
@@ -1332,7 +1332,7 @@ void LLTextEditor::cut()
}
S32 left_pos = llmin( mSelectionStart, mSelectionEnd );
S32 length = llabs( mSelectionStart - mSelectionEnd );
- gClipboard.copyFromSubstring( getWText(), left_pos, length, mSourceID );
+ LLClipboard::instance().copyToClipboard( getWText(), left_pos, length);
deleteSelection( FALSE );
onKeyStroke();
@@ -1352,12 +1352,12 @@ void LLTextEditor::copy()
}
S32 left_pos = llmin( mSelectionStart, mSelectionEnd );
S32 length = llabs( mSelectionStart - mSelectionEnd );
- gClipboard.copyFromSubstring(getWText(), left_pos, length, mSourceID);
+ LLClipboard::instance().copyToClipboard(getWText(), left_pos, length);
}
BOOL LLTextEditor::canPaste() const
{
- return !mReadOnly && gClipboard.canPasteString();
+ return !mReadOnly && LLClipboard::instance().isTextAvailable();
}
// paste from clipboard
@@ -1393,16 +1393,8 @@ void LLTextEditor::pasteHelper(bool is_primary)
return;
}
- LLUUID source_id;
LLWString paste;
- if (is_primary)
- {
- paste = gClipboard.getPastePrimaryWString(&source_id);
- }
- else
- {
- paste = gClipboard.getPasteWString(&source_id);
- }
+ LLClipboard::instance().pasteFromClipboard(paste, is_primary);
if (paste.empty())
{
@@ -1475,12 +1467,12 @@ void LLTextEditor::copyPrimary()
}
S32 left_pos = llmin( mSelectionStart, mSelectionEnd );
S32 length = llabs( mSelectionStart - mSelectionEnd );
- gClipboard.copyFromPrimarySubstring(getWText(), left_pos, length, mSourceID);
+ LLClipboard::instance().copyToClipboard(getWText(), left_pos, length, true);
}
BOOL LLTextEditor::canPastePrimary() const
{
- return !mReadOnly && gClipboard.canPastePrimaryString();
+ return !mReadOnly && LLClipboard::instance().isTextAvailable(true);
}
void LLTextEditor::updatePrimary()
diff --git a/indra/llui/llview.cpp b/indra/llui/llview.cpp
index 421166dcd4..54843227b7 100644
--- a/indra/llui/llview.cpp
+++ b/indra/llui/llview.cpp
@@ -1835,7 +1835,10 @@ const LLCtrlQuery & LLView::getFocusRootsQuery()
void LLView::setShape(const LLRect& new_rect, bool by_user)
{
- handleReshape(new_rect, by_user);
+ if (new_rect != getRect())
+ {
+ handleReshape(new_rect, by_user);
+ }
}
void LLView::handleReshape(const LLRect& new_rect, bool by_user)
@@ -2225,145 +2228,163 @@ static bool get_last_child_rect(LLView* parent, LLRect *rect)
}
//static
-void LLView::applyXUILayout(LLView::Params& p, LLView* parent)
+void LLView::applyXUILayout(LLView::Params& p, LLView* parent, LLRect layout_rect)
{
+ if (!parent) return;
+
const S32 VPAD = 4;
const S32 MIN_WIDGET_HEIGHT = 10;
// *NOTE: This will confuse export of floater/panel coordinates unless
// the default is also "topleft". JC
- if (p.layout().empty() && parent)
+ if (p.layout().empty())
{
p.layout = parent->getLayout();
}
- if (parent)
+ if (layout_rect.isEmpty())
{
- LLRect parent_rect = parent->getLocalRect();
- // overwrite uninitialized rect params, using context
- LLRect default_rect = parent->getLocalRect();
+ layout_rect = parent->getLocalRect();
+ }
- bool layout_topleft = (p.layout() == "topleft");
+ // overwrite uninitialized rect params, using context
+ LLRect default_rect = parent->getLocalRect();
- // convert negative or centered coordinates to parent relative values
- // Note: some of this logic matches the logic in TypedParam<LLRect>::setValueFromBlock()
- if (p.rect.left.isProvided() && p.rect.left < 0) p.rect.left = p.rect.left + parent_rect.getWidth();
- if (p.rect.right.isProvided() && p.rect.right < 0) p.rect.right = p.rect.right + parent_rect.getWidth();
- if (p.rect.bottom.isProvided() && p.rect.bottom < 0) p.rect.bottom = p.rect.bottom + parent_rect.getHeight();
- if (p.rect.top.isProvided() && p.rect.top < 0) p.rect.top = p.rect.top + parent_rect.getHeight();
+ bool layout_topleft = (p.layout() == "topleft");
+ // convert negative or centered coordinates to parent relative values
+ // Note: some of this logic matches the logic in TypedParam<LLRect>::setValueFromBlock()
+ if (p.rect.left.isProvided())
+ {
+ p.rect.left = p.rect.left + ((p.rect.left >= 0) ? layout_rect.mLeft : layout_rect.mRight);
+ }
+ if (p.rect.right.isProvided())
+ {
+ p.rect.right = p.rect.right + ((p.rect.right >= 0) ? layout_rect.mLeft : layout_rect.mRight);
+ }
+ if (p.rect.bottom.isProvided())
+ {
+ p.rect.bottom = p.rect.bottom + ((p.rect.bottom >= 0) ? layout_rect.mBottom : layout_rect.mTop);
if (layout_topleft)
{
//invert top to bottom
- if (p.rect.top.isProvided()) p.rect.top = parent_rect.getHeight() - p.rect.top;
- if (p.rect.bottom.isProvided()) p.rect.bottom = parent_rect.getHeight() - p.rect.bottom;
+ p.rect.bottom = layout_rect.mBottom + layout_rect.mTop - p.rect.bottom;
}
-
- // DEPRECATE: automatically fall back to height of MIN_WIDGET_HEIGHT pixels
- if (!p.rect.height.isProvided() && !p.rect.top.isProvided() && p.rect.height == 0)
+ }
+ if (p.rect.top.isProvided())
+ {
+ p.rect.top = p.rect.top + ((p.rect.top >= 0) ? layout_rect.mBottom : layout_rect.mTop);
+ if (layout_topleft)
{
- p.rect.height = MIN_WIDGET_HEIGHT;
+ //invert top to bottom
+ p.rect.top = layout_rect.mBottom + layout_rect.mTop - p.rect.top;
}
+ }
+
+ // DEPRECATE: automatically fall back to height of MIN_WIDGET_HEIGHT pixels
+ if (!p.rect.height.isProvided() && !p.rect.top.isProvided() && p.rect.height == 0)
+ {
+ p.rect.height = MIN_WIDGET_HEIGHT;
+ }
- default_rect.translate(0, default_rect.getHeight());
+ default_rect.translate(0, default_rect.getHeight());
- // If there was a recently constructed child, use its rectangle
- get_last_child_rect(parent, &default_rect);
+ // If there was a recently constructed child, use its rectangle
+ get_last_child_rect(parent, &default_rect);
- if (layout_topleft)
+ if (layout_topleft)
+ {
+ // Invert the sense of bottom_delta for topleft layout
+ if (p.bottom_delta.isProvided())
{
- // Invert the sense of bottom_delta for topleft layout
- if (p.bottom_delta.isProvided())
- {
- p.bottom_delta = -p.bottom_delta;
- }
- else if (p.top_pad.isProvided())
- {
- p.bottom_delta = -(p.rect.height + p.top_pad);
- }
- else if (p.top_delta.isProvided())
- {
- p.bottom_delta =
- -(p.top_delta + p.rect.height - default_rect.getHeight());
- }
- else if (!p.left_delta.isProvided()
- && !p.left_pad.isProvided())
- {
- // set default position is just below last rect
- p.bottom_delta.set(-(p.rect.height + VPAD), false);
- }
- else
- {
- p.bottom_delta.set(0, false);
- }
-
- // default to same left edge
- if (!p.left_delta.isProvided())
- {
- p.left_delta.set(0, false);
- }
- if (p.left_pad.isProvided())
- {
- // left_pad is based on prior widget's right edge
- p.left_delta.set(p.left_pad + default_rect.getWidth(), false);
- }
-
- default_rect.translate(p.left_delta, p.bottom_delta);
+ p.bottom_delta = -p.bottom_delta;
}
- else
- {
- // set default position is just below last rect
- if (!p.bottom_delta.isProvided())
- {
- p.bottom_delta.set(-(p.rect.height + VPAD), false);
- }
- if (!p.left_delta.isProvided())
- {
- p.left_delta.set(0, false);
- }
- default_rect.translate(p.left_delta, p.bottom_delta);
+ else if (p.top_pad.isProvided())
+ {
+ p.bottom_delta = -(p.rect.height + p.top_pad);
}
-
- // this handles case where *both* x and x_delta are provided
- // ignore x in favor of default x + x_delta
- if (p.bottom_delta.isProvided()) p.rect.bottom.set(0, false);
- if (p.left_delta.isProvided()) p.rect.left.set(0, false);
-
- // selectively apply rectangle defaults, making sure that
- // params are not flagged as having been "provided"
- // as rect params are overconstrained and rely on provided flags
- if (!p.rect.left.isProvided())
+ else if (p.top_delta.isProvided())
{
- p.rect.left.set(default_rect.mLeft, false);
- //HACK: get around the fact that setting a rect param component value won't invalidate the existing rect object value
- p.rect.paramChanged(p.rect.left, true);
+ p.bottom_delta =
+ -(p.top_delta + p.rect.height - default_rect.getHeight());
}
- if (!p.rect.bottom.isProvided())
+ else if (!p.left_delta.isProvided()
+ && !p.left_pad.isProvided())
{
- p.rect.bottom.set(default_rect.mBottom, false);
- p.rect.paramChanged(p.rect.bottom, true);
+ // set default position is just below last rect
+ p.bottom_delta.set(-(p.rect.height + VPAD), false);
}
- if (!p.rect.top.isProvided())
+ else
{
- p.rect.top.set(default_rect.mTop, false);
- p.rect.paramChanged(p.rect.top, true);
+ p.bottom_delta.set(0, false);
}
- if (!p.rect.right.isProvided())
+
+ // default to same left edge
+ if (!p.left_delta.isProvided())
{
- p.rect.right.set(default_rect.mRight, false);
- p.rect.paramChanged(p.rect.right, true);
-
+ p.left_delta.set(0, false);
}
- if (!p.rect.width.isProvided())
+ if (p.left_pad.isProvided())
{
- p.rect.width.set(default_rect.getWidth(), false);
- p.rect.paramChanged(p.rect.width, true);
+ // left_pad is based on prior widget's right edge
+ p.left_delta.set(p.left_pad + default_rect.getWidth(), false);
}
- if (!p.rect.height.isProvided())
+
+ default_rect.translate(p.left_delta, p.bottom_delta);
+ }
+ else
+ {
+ // set default position is just below last rect
+ if (!p.bottom_delta.isProvided())
{
- p.rect.height.set(default_rect.getHeight(), false);
- p.rect.paramChanged(p.rect.height, true);
+ p.bottom_delta.set(-(p.rect.height + VPAD), false);
}
+ if (!p.left_delta.isProvided())
+ {
+ p.left_delta.set(0, false);
+ }
+ default_rect.translate(p.left_delta, p.bottom_delta);
+ }
+
+ // this handles case where *both* x and x_delta are provided
+ // ignore x in favor of default x + x_delta
+ if (p.bottom_delta.isProvided()) p.rect.bottom.set(0, false);
+ if (p.left_delta.isProvided()) p.rect.left.set(0, false);
+
+ // selectively apply rectangle defaults, making sure that
+ // params are not flagged as having been "provided"
+ // as rect params are overconstrained and rely on provided flags
+ if (!p.rect.left.isProvided())
+ {
+ p.rect.left.set(default_rect.mLeft, false);
+ //HACK: get around the fact that setting a rect param component value won't invalidate the existing rect object value
+ p.rect.paramChanged(p.rect.left, true);
+ }
+ if (!p.rect.bottom.isProvided())
+ {
+ p.rect.bottom.set(default_rect.mBottom, false);
+ p.rect.paramChanged(p.rect.bottom, true);
+ }
+ if (!p.rect.top.isProvided())
+ {
+ p.rect.top.set(default_rect.mTop, false);
+ p.rect.paramChanged(p.rect.top, true);
+ }
+ if (!p.rect.right.isProvided())
+ {
+ p.rect.right.set(default_rect.mRight, false);
+ p.rect.paramChanged(p.rect.right, true);
+
+ }
+ if (!p.rect.width.isProvided())
+ {
+ p.rect.width.set(default_rect.getWidth(), false);
+ p.rect.paramChanged(p.rect.width, true);
+ }
+ if (!p.rect.height.isProvided())
+ {
+ p.rect.height.set(default_rect.getHeight(), false);
+ p.rect.paramChanged(p.rect.height, true);
}
}
diff --git a/indra/llui/llview.h b/indra/llui/llview.h
index fd19309a56..1c35349510 100644
--- a/indra/llui/llview.h
+++ b/indra/llui/llview.h
@@ -505,7 +505,7 @@ public:
// Set up params after XML load before calling new(),
// usually to adjust layout.
- static void applyXUILayout(Params& p, LLView* parent);
+ static void applyXUILayout(Params& p, LLView* parent, LLRect layout_rect = LLRect());
// For re-export of floaters and panels, convert the coordinate system
// to be top-left based.
diff --git a/indra/llwindow/llwindow.cpp b/indra/llwindow/llwindow.cpp
index 6834b34387..5b7424acbb 100644
--- a/indra/llwindow/llwindow.cpp
+++ b/indra/llwindow/llwindow.cpp
@@ -192,6 +192,21 @@ BOOL LLWindow::setSize(LLCoordScreen size)
return setSizeImpl(size);
}
+BOOL LLWindow::setSize(LLCoordWindow size)
+{
+ //HACK: we are inconsistently using minimum window dimensions
+ // in this case, we are constraining the inner "client" rect and other times
+ // we constrain the outer "window" rect
+ // There doesn't seem to be a good way to do this consistently without a bunch of platform
+ // specific code
+ if (!getMaximized())
+ {
+ size.mX = llmax(size.mX, mMinWindowWidth);
+ size.mY = llmax(size.mY, mMinWindowHeight);
+ }
+ return setSizeImpl(size);
+}
+
// virtual
void LLWindow::setMinSize(U32 min_width, U32 min_height, bool enforce_immediately)
@@ -440,7 +455,7 @@ BOOL LLWindowManager::isWindowValid(LLWindow *window)
//coordinate conversion utility funcs that forward to llwindow
LLCoordCommon LL_COORD_TYPE_WINDOW::convertToCommon() const
{
- const LLCoordWindow& self = static_cast<const LLCoordWindow&>(*this);
+ const LLCoordWindow& self = LLCoordWindow::getTypedCoords(*this);
LLWindow* windowp = &(*LLWindow::beginInstances());
LLCoordGL out;
@@ -450,7 +465,7 @@ LLCoordCommon LL_COORD_TYPE_WINDOW::convertToCommon() const
void LL_COORD_TYPE_WINDOW::convertFromCommon(const LLCoordCommon& from)
{
- LLCoordWindow& self = static_cast<LLCoordWindow&>(*this);
+ LLCoordWindow& self = LLCoordWindow::getTypedCoords(*this);
LLWindow* windowp = &(*LLWindow::beginInstances());
LLCoordGL from_gl(from);
@@ -459,7 +474,7 @@ void LL_COORD_TYPE_WINDOW::convertFromCommon(const LLCoordCommon& from)
LLCoordCommon LL_COORD_TYPE_SCREEN::convertToCommon() const
{
- const LLCoordScreen& self = static_cast<const LLCoordScreen&>(*this);
+ const LLCoordScreen& self = LLCoordScreen::getTypedCoords(*this);
LLWindow* windowp = &(*LLWindow::beginInstances());
LLCoordGL out;
@@ -469,7 +484,7 @@ LLCoordCommon LL_COORD_TYPE_SCREEN::convertToCommon() const
void LL_COORD_TYPE_SCREEN::convertFromCommon(const LLCoordCommon& from)
{
- LLCoordScreen& self = static_cast<LLCoordScreen&>(*this);
+ LLCoordScreen& self = LLCoordScreen::getTypedCoords(*this);
LLWindow* windowp = &(*LLWindow::beginInstances());
LLCoordGL from_gl(from);
diff --git a/indra/llwindow/llwindow.h b/indra/llwindow/llwindow.h
index d2971581d2..4da87f4e06 100644
--- a/indra/llwindow/llwindow.h
+++ b/indra/llwindow/llwindow.h
@@ -73,6 +73,7 @@ public:
virtual BOOL getSize(LLCoordWindow *size) = 0;
virtual BOOL setPosition(LLCoordScreen position) = 0;
BOOL setSize(LLCoordScreen size);
+ BOOL setSize(LLCoordWindow size);
virtual void setMinSize(U32 min_width, U32 min_height, bool enforce_immediately = true);
virtual BOOL switchContext(BOOL fullscreen, const LLCoordScreen &size, BOOL disable_vsync, const LLCoordScreen * const posp = NULL) = 0;
virtual BOOL setCursorPosition(LLCoordWindow position) = 0;
@@ -172,6 +173,7 @@ protected:
virtual BOOL canDelete();
virtual BOOL setSizeImpl(LLCoordScreen size) = 0;
+ virtual BOOL setSizeImpl(LLCoordWindow size) = 0;
protected:
LLWindowCallbacks* mCallbacks;
diff --git a/indra/llwindow/llwindowheadless.h b/indra/llwindow/llwindowheadless.h
index d4a778cb85..1f767f4c97 100644
--- a/indra/llwindow/llwindowheadless.h
+++ b/indra/llwindow/llwindowheadless.h
@@ -47,6 +47,7 @@ public:
/*virtual*/ BOOL getSize(LLCoordWindow *size) {return FALSE;};
/*virtual*/ BOOL setPosition(LLCoordScreen position) {return FALSE;};
/*virtual*/ BOOL setSizeImpl(LLCoordScreen size) {return FALSE;};
+ /*virtual*/ BOOL setSizeImpl(LLCoordWindow size) {return FALSE;};
/*virtual*/ BOOL switchContext(BOOL fullscreen, const LLCoordScreen &size, BOOL disable_vsync, const LLCoordScreen * const posp = NULL) {return FALSE;};
/*virtual*/ BOOL setCursorPosition(LLCoordWindow position) {return FALSE;};
/*virtual*/ BOOL getCursorPosition(LLCoordWindow *position) {return FALSE;};
diff --git a/indra/llwindow/llwindowmacosx.cpp b/indra/llwindow/llwindowmacosx.cpp
index c952f8bbcf..32bb84cba5 100644
--- a/indra/llwindow/llwindowmacosx.cpp
+++ b/indra/llwindow/llwindowmacosx.cpp
@@ -1266,6 +1266,31 @@ BOOL LLWindowMacOSX::setSizeImpl(const LLCoordScreen size)
return TRUE;
}
+BOOL LLWindowMacOSX::setSizeImpl(const LLCoordWindow size)
+{
+ Rect client_rect;
+ if (mWindow)
+ {
+ OSStatus err = GetWindowBounds(mWindow, kWindowContentRgn, &client_rect);
+ if (err == noErr)
+ {
+ client_rect.right = client_rect.left + size.mX;
+ client_rect.bottom = client_rect.top + size.mY;
+ err = SetWindowBounds(mWindow, kWindowContentRgn, &client_rect);
+ }
+ if (err == noErr)
+ {
+ return TRUE;
+ }
+ else
+ {
+ llinfos << "Error setting size" << err << llendl;
+ return FALSE;
+ }
+ }
+ return FALSE;
+}
+
void LLWindowMacOSX::swapBuffers()
{
aglSwapBuffers(mContext);
diff --git a/indra/llwindow/llwindowmacosx.h b/indra/llwindow/llwindowmacosx.h
index 073f294b54..52ba8b3bf3 100644
--- a/indra/llwindow/llwindowmacosx.h
+++ b/indra/llwindow/llwindowmacosx.h
@@ -59,6 +59,7 @@ public:
/*virtual*/ BOOL getSize(LLCoordWindow *size);
/*virtual*/ BOOL setPosition(LLCoordScreen position);
/*virtual*/ BOOL setSizeImpl(LLCoordScreen size);
+ /*virtual*/ BOOL setSizeImpl(LLCoordWindow size);
/*virtual*/ BOOL switchContext(BOOL fullscreen, const LLCoordScreen &size, BOOL disable_vsync, const LLCoordScreen * const posp = NULL);
/*virtual*/ BOOL setCursorPosition(LLCoordWindow position);
/*virtual*/ BOOL getCursorPosition(LLCoordWindow *position);
diff --git a/indra/llwindow/llwindowsdl.cpp b/indra/llwindow/llwindowsdl.cpp
index 5f5baceef8..3d33af9d9b 100644
--- a/indra/llwindow/llwindowsdl.cpp
+++ b/indra/llwindow/llwindowsdl.cpp
@@ -981,6 +981,25 @@ BOOL LLWindowSDL::setSizeImpl(const LLCoordScreen size)
return FALSE;
}
+BOOL LLWindowSDL::setSizeImpl(const LLCoordWindow size)
+{
+ if(mWindow)
+ {
+ // Push a resize event onto SDL's queue - we'll handle it
+ // when it comes out again.
+ SDL_Event event;
+ event.type = SDL_VIDEORESIZE;
+ event.resize.w = size.mX;
+ event.resize.h = size.mY;
+ SDL_PushEvent(&event); // copied into queue
+
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+
void LLWindowSDL::swapBuffers()
{
if (mWindow)
diff --git a/indra/llwindow/llwindowsdl.h b/indra/llwindow/llwindowsdl.h
index 59719e4046..4e2a269ea3 100644
--- a/indra/llwindow/llwindowsdl.h
+++ b/indra/llwindow/llwindowsdl.h
@@ -64,6 +64,7 @@ public:
/*virtual*/ BOOL getSize(LLCoordWindow *size);
/*virtual*/ BOOL setPosition(LLCoordScreen position);
/*virtual*/ BOOL setSizeImpl(LLCoordScreen size);
+ /*virtual*/ BOOL setSizeImpl(LLCoordWindow size);
/*virtual*/ BOOL switchContext(BOOL fullscreen, const LLCoordScreen &size, BOOL disable_vsync, const LLCoordScreen * const posp = NULL);
/*virtual*/ BOOL setCursorPosition(LLCoordWindow position);
/*virtual*/ BOOL getCursorPosition(LLCoordWindow *position);
diff --git a/indra/llwindow/llwindowwin32.cpp b/indra/llwindow/llwindowwin32.cpp
index ebc3203f14..bc85acbf45 100644
--- a/indra/llwindow/llwindowwin32.cpp
+++ b/indra/llwindow/llwindowwin32.cpp
@@ -872,10 +872,30 @@ BOOL LLWindowWin32::setSizeImpl(const LLCoordScreen size)
return FALSE;
}
+ WINDOWPLACEMENT placement;
+ placement.length = sizeof(WINDOWPLACEMENT);
+
+ if (!GetWindowPlacement(mWindowHandle, &placement)) return FALSE;
+
+ placement.showCmd = SW_RESTORE;
+
+ if (!SetWindowPlacement(mWindowHandle, &placement)) return FALSE;
+
moveWindow(position, size);
return TRUE;
}
+BOOL LLWindowWin32::setSizeImpl(const LLCoordWindow size)
+{
+ RECT window_rect = {0, 0, size.mX, size.mY };
+ DWORD dw_ex_style = WS_EX_APPWINDOW | WS_EX_WINDOWEDGE;
+ DWORD dw_style = WS_OVERLAPPEDWINDOW;
+
+ AdjustWindowRectEx(&window_rect, dw_style, FALSE, dw_ex_style);
+
+ return setSizeImpl(LLCoordScreen(window_rect.right - window_rect.left, window_rect.bottom - window_rect.top));
+}
+
// changing fullscreen resolution
BOOL LLWindowWin32::switchContext(BOOL fullscreen, const LLCoordScreen &size, BOOL disable_vsync, const LLCoordScreen * const posp)
{
@@ -886,12 +906,12 @@ BOOL LLWindowWin32::switchContext(BOOL fullscreen, const LLCoordScreen &size, BO
DWORD current_refresh;
DWORD dw_ex_style;
DWORD dw_style;
- RECT window_rect;
+ RECT window_rect = {0, 0, 0, 0};
S32 width = size.mX;
S32 height = size.mY;
BOOL auto_show = FALSE;
- if (mhRC)
+ if (mhRC)
{
auto_show = TRUE;
resetDisplayResolution();
@@ -986,7 +1006,8 @@ BOOL LLWindowWin32::switchContext(BOOL fullscreen, const LLCoordScreen &size, BO
dw_ex_style = WS_EX_APPWINDOW;
dw_style = WS_POPUP;
- // Move window borders out not to cover window contents
+ // Move window borders out not to cover window contents.
+ // This converts client rect to window rect, i.e. expands it by the window border size.
AdjustWindowRectEx(&window_rect, dw_style, FALSE, dw_ex_style);
}
// If it failed, we don't want to run fullscreen
@@ -1014,6 +1035,7 @@ BOOL LLWindowWin32::switchContext(BOOL fullscreen, const LLCoordScreen &size, BO
dw_style = WS_OVERLAPPEDWINDOW;
}
+
// don't post quit messages when destroying old windows
mPostQuit = FALSE;
@@ -1798,6 +1820,10 @@ static LLFastTimer::DeclareTimer FTM_MOUSEHANDLER("Handle Mouse");
LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_param, LPARAM l_param)
{
+ // Ignore clicks not originated in the client area, i.e. mouse-up events not preceded with a WM_LBUTTONDOWN.
+ // This helps prevent avatar walking after maximizing the window by double-clicking the title bar.
+ static bool sHandleLeftMouseUp = true;
+
LLWindowWin32 *window_imp = (LLWindowWin32 *)GetWindowLong(h_wnd, GWL_USERDATA);
@@ -2144,10 +2170,20 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_
window_imp->handleUnicodeUTF16((U16)w_param, gKeyboard->currentMask(FALSE));
return 0;
+ case WM_NCLBUTTONDOWN:
+ {
+ window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_NCLBUTTONDOWN");
+ // A click in a non-client area, e.g. title bar or window border.
+ sHandleLeftMouseUp = false;
+ }
+ break;
+
case WM_LBUTTONDOWN:
{
window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_LBUTTONDOWN");
LLFastTimer t2(FTM_MOUSEHANDLER);
+ sHandleLeftMouseUp = true;
+
if (LLWinImm::isAvailable() && window_imp->mPreeditor)
{
window_imp->interruptLanguageTextInput();
@@ -2212,6 +2248,13 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_
{
window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_LBUTTONUP");
LLFastTimer t2(FTM_MOUSEHANDLER);
+
+ if (!sHandleLeftMouseUp)
+ {
+ sHandleLeftMouseUp = true;
+ break;
+ }
+
//if (gDebugClicks)
//{
// LL_INFOS("Window") << "WndProc left button up" << LL_ENDL;
diff --git a/indra/llwindow/llwindowwin32.h b/indra/llwindow/llwindowwin32.h
index b3602be8b7..54c9ac4d4d 100644
--- a/indra/llwindow/llwindowwin32.h
+++ b/indra/llwindow/llwindowwin32.h
@@ -58,6 +58,7 @@ public:
/*virtual*/ BOOL getSize(LLCoordWindow *size);
/*virtual*/ BOOL setPosition(LLCoordScreen position);
/*virtual*/ BOOL setSizeImpl(LLCoordScreen size);
+ /*virtual*/ BOOL setSizeImpl(LLCoordWindow size);
/*virtual*/ BOOL switchContext(BOOL fullscreen, const LLCoordScreen &size, BOOL disable_vsync, const LLCoordScreen * const posp = NULL);
/*virtual*/ BOOL setCursorPosition(LLCoordWindow position);
/*virtual*/ BOOL getCursorPosition(LLCoordWindow *position);
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index 3c9bde34b7..64fa35543d 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -41,6 +41,7 @@ include(UnixInstall)
include(LLKDU)
include(ViewerMiscLibs)
include(LLLogin)
+include(VisualLeakDetector)
include(GLOD)
include(CMakeCopyIfDifferent)
@@ -287,7 +288,6 @@ set(viewer_SOURCE_FILES
llinspectremoteobject.cpp
llinspecttoast.cpp
llinventorybridge.cpp
- llinventoryclipboard.cpp
llinventoryfilter.cpp
llinventoryfunctions.cpp
llinventoryicon.cpp
@@ -842,7 +842,6 @@ set(viewer_HEADER_FILES
llinspectremoteobject.h
llinspecttoast.h
llinventorybridge.h
- llinventoryclipboard.h
llinventoryfilter.h
llinventoryfunctions.h
llinventoryicon.h
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index ee8c15752b..15da381e2f 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -621,6 +621,28 @@
<key>Value</key>
<string>http://lecs-viewer-web-components.s3.amazonaws.com/v3.0/[GRID_LOWERCASE]/avatars.html</string>
</map>
+ <key>AvatarRotateThresholdSlow</key>
+ <map>
+ <key>Comment</key>
+ <string>Angle between avatar facing and camera facing at which avatar turns to face same direction as camera, when moving slowly (degrees)</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>F32</string>
+ <key>Value</key>
+ <integer>60</integer>
+ </map>
+ <key>AvatarRotateThresholdFast</key>
+ <map>
+ <key>Comment</key>
+ <string>Angle between avatar facing and camera facing at which avatar turns to face same direction as camera, when moving fast (degrees)</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>F32</string>
+ <key>Value</key>
+ <integer>2</integer>
+ </map>
<key>AvatarBakedTextureUploadTimeout</key>
<map>
<key>Comment</key>
@@ -4282,17 +4304,6 @@
<key>Value</key>
<integer>0</integer>
</map>
- <key>InventoryInboxToggleState</key>
- <map>
- <key>Comment</key>
- <string>Stores the open/closed state of inventory Received items panel</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>0</integer>
- </map>
<key>InventoryLinking</key>
<map>
<key>Comment</key>
@@ -9619,18 +9630,29 @@
<key>Value</key>
<integer>1</integer>
</map>
- <key>ShowConsoleWindow</key>
- <map>
- <key>Comment</key>
- <string>Show log in separate OS window</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>0</integer>
- </map>
- <key>NavBarShowCoordinates</key>
+ <key>ShowConsoleWindow</key>
+ <map>
+ <key>Comment</key>
+ <string>Show log in separate OS window</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
+ <key>EnableVisualLeakDetector</key>
+ <map>
+ <key>Comment</key>
+ <string>EnableVisualLeakDetector</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
+ <key>NavBarShowCoordinates</key>
<map>
<key>Comment</key>
<string>Show coordinates in navigation bar</string>
@@ -12766,7 +12788,7 @@
<key>WindowX</key>
<map>
<key>Comment</key>
- <string>X coordinate of lower left corner of SL viewer window, relative to primary display (pixels)</string>
+ <string>X coordinate of upper left corner of SL viewer window, relative to upper left corner of primary display (pixels)</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
@@ -12777,7 +12799,7 @@
<key>WindowY</key>
<map>
<key>Comment</key>
- <string>Y coordinate of lower left corner of SL viewer window, relative to primary display (pixels)</string>
+ <string>Y coordinate of upper left corner of SL viewer window, relative to upper left corner of primary display (pixels)</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
diff --git a/indra/newview/app_settings/settings_per_account.xml b/indra/newview/app_settings/settings_per_account.xml
index 8cdd8ed838..143126b334 100644
--- a/indra/newview/app_settings/settings_per_account.xml
+++ b/indra/newview/app_settings/settings_per_account.xml
@@ -33,6 +33,28 @@
<key>Value</key>
<string />
</map>
+ <key>InventoryInboxHeight</key>
+ <map>
+ <key>Comment</key>
+ <string>Inventory inbox panel height in Inventory floater.</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>S32</string>
+ <key>Value</key>
+ <integer>200</integer>
+ </map>
+ <key>InventoryInboxToggleState</key>
+ <map>
+ <key>Comment</key>
+ <string>Stores the open/closed state of inventory Received Items panel.</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
<key>DisplayDestinationsOnInitialRun</key>
<map>
<key>Comment</key>
diff --git a/indra/newview/llappviewerwin32.cpp b/indra/newview/llappviewerwin32.cpp
index 6931b55c4c..bad60a9757 100644
--- a/indra/newview/llappviewerwin32.cpp
+++ b/indra/newview/llappviewerwin32.cpp
@@ -26,6 +26,10 @@
#include "llviewerprecompiledheaders.h"
+#ifdef INCLUDE_VLD
+#include "vld.h"
+#endif
+
#include "llappviewerwin32.h"
#include "llmemtype.h"
@@ -105,6 +109,14 @@ int APIENTRY WINMAIN(HINSTANCE hInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
+#ifdef INCLUDE_VLD
+ // only works for debug builds (hard coded into vld.h)
+ #ifdef _DEBUG
+ // start with Visual Leak Detector turned off
+ VLDGlobalDisable();
+ #endif // _DEBUG
+#endif // INCLUDE_VLD
+
LLMemType mt1(LLMemType::MTYPE_STARTUP);
const S32 MAX_HEAPS = 255;
diff --git a/indra/newview/llavataractions.cpp b/indra/newview/llavataractions.cpp
index 9a7cdcfa21..f618af9536 100755
--- a/indra/newview/llavataractions.cpp
+++ b/indra/newview/llavataractions.cpp
@@ -738,6 +738,11 @@ void LLAvatarActions::shareWithAvatars()
LLFloaterAvatarPicker* picker =
LLFloaterAvatarPicker::show(boost::bind(give_inventory, _1, _2), TRUE, FALSE);
+ if (!picker)
+ {
+ return;
+ }
+
picker->setOkBtnEnableCb(boost::bind(is_give_inventory_acceptable));
picker->openFriendsTab();
LLNotificationsUtil::add("ShareNotification");
diff --git a/indra/newview/llfavoritesbar.cpp b/indra/newview/llfavoritesbar.cpp
index f4b6dc2c81..575b613ccf 100644
--- a/indra/newview/llfavoritesbar.cpp
+++ b/indra/newview/llfavoritesbar.cpp
@@ -39,7 +39,7 @@
#include "llagent.h"
#include "llclipboard.h"
-#include "llinventoryclipboard.h"
+#include "llclipboard.h"
#include "llinventorybridge.h"
#include "llinventoryfunctions.h"
#include "llfloatersidepanelcontainer.h"
@@ -1118,7 +1118,7 @@ BOOL LLFavoritesBarCtrl::handleRightMouseDown(S32 x, S32 y, MASK mask)
}
void copy_slurl_to_clipboard_cb(std::string& slurl)
{
- gClipboard.copyFromString(utf8str_to_wstring(slurl));
+ LLClipboard::instance().copyToClipboard(utf8str_to_wstring(slurl),0,slurl.size());
LLSD args;
args["SLURL"] = slurl;
@@ -1187,7 +1187,7 @@ void LLFavoritesBarCtrl::doToSelected(const LLSD& userdata)
}
else if (action == "copy")
{
- LLInventoryClipboard::instance().store(mSelectedItemID);
+ LLClipboard::instance().copyToClipboard(mSelectedItemID, LLAssetType::AT_LANDMARK);
}
else if (action == "paste")
{
@@ -1211,13 +1211,13 @@ void LLFavoritesBarCtrl::doToSelected(const LLSD& userdata)
BOOL LLFavoritesBarCtrl::isClipboardPasteable() const
{
- if (!LLInventoryClipboard::instance().hasContents())
+ if (!LLClipboard::instance().hasContents())
{
return FALSE;
}
LLDynamicArray<LLUUID> objects;
- LLInventoryClipboard::instance().retrieve(objects);
+ LLClipboard::instance().pasteFromClipboard(objects);
S32 count = objects.count();
for(S32 i = 0; i < count; i++)
{
@@ -1246,7 +1246,7 @@ void LLFavoritesBarCtrl::pastFromClipboard() const
{
LLInventoryItem* item = NULL;
LLDynamicArray<LLUUID> objects;
- LLInventoryClipboard::instance().retrieve(objects);
+ LLClipboard::instance().pasteFromClipboard(objects);
S32 count = objects.count();
LLUUID parent_id(mFavoriteFolderId);
for(S32 i = 0; i < count; i++)
diff --git a/indra/newview/llfloaterbuycontents.cpp b/indra/newview/llfloaterbuycontents.cpp
index a7388d21a3..bca4b5e447 100644
--- a/indra/newview/llfloaterbuycontents.cpp
+++ b/indra/newview/llfloaterbuycontents.cpp
@@ -210,7 +210,9 @@ void LLFloaterBuyContents::inventoryChanged(LLViewerObject* obj,
LLSD row;
BOOL item_is_multi = FALSE;
- if ( inv_item->getFlags() & LLInventoryItemFlags::II_FLAGS_LANDMARK_VISITED )
+ if ((inv_item->getFlags() & LLInventoryItemFlags::II_FLAGS_LANDMARK_VISITED
+ || inv_item->getFlags() & LLInventoryItemFlags::II_FLAGS_OBJECT_HAS_MULTIPLE_ITEMS)
+ && !(inv_item->getFlags() & LLInventoryItemFlags::II_FLAGS_WEARABLES_MASK))
{
item_is_multi = TRUE;
}
diff --git a/indra/newview/llfloatergesture.cpp b/indra/newview/llfloatergesture.cpp
index d495f20a9a..56051ff684 100644
--- a/indra/newview/llfloatergesture.cpp
+++ b/indra/newview/llfloatergesture.cpp
@@ -32,7 +32,7 @@
#include "llinventorybridge.h"
#include "llinventoryfunctions.h"
#include "llinventorymodel.h"
-#include "llinventoryclipboard.h"
+#include "llclipboard.h"
#include "llagent.h"
#include "llappearancemgr.h"
@@ -90,6 +90,12 @@ public:
if(mFloater)
{
mFloater->addGesture(inv_item,NULL,mFloater->getChild<LLScrollListCtrl>("gesture_list"));
+
+ // EXP-1909 (Pasted gesture displayed twice)
+ // The problem is that addGesture is called here for the second time for the same item (which is copied)
+ // First time addGesture is called from LLFloaterGestureObserver::changed(), which is a callback for inventory
+ // change. So we need to refresh the gesture list to avoid duplicates.
+ mFloater->refreshAll();
}
}
};
@@ -391,11 +397,11 @@ bool LLFloaterGesture::isActionEnabled(const LLSD& command)
std::string command_name = command.asString();
if("paste" == command_name)
{
- if(!LLInventoryClipboard::instance().hasContents())
+ if(!LLClipboard::instance().hasContents())
return false;
LLDynamicArray<LLUUID> ids;
- LLInventoryClipboard::instance().retrieve(ids);
+ LLClipboard::instance().pasteFromClipboard(ids);
for(LLDynamicArray<LLUUID>::iterator it = ids.begin(); it != ids.end(); it++)
{
LLInventoryItem* item = gInventory.getItem(*it);
@@ -490,27 +496,26 @@ void LLFloaterGesture::onActivateBtnClick()
void LLFloaterGesture::onCopyPasteAction(const LLSD& command)
{
std::string command_name = command.asString();
- // since we select this comman inventory item had already arrived .
+ // Since we select this command, the inventory items must have already arrived
if("copy_gesture" == command_name)
{
uuid_vec_t ids;
getSelectedIds(ids);
- // make sure that clopboard is empty
- LLInventoryClipboard::instance().reset();
+ // Make sure the clipboard is empty
+ LLClipboard::instance().reset();
for(uuid_vec_t::iterator it = ids.begin(); it != ids.end(); it++)
{
LLInventoryItem* item = gInventory.getItem(*it);
if(item && item->getInventoryType() == LLInventoryType::IT_GESTURE)
{
- LLInventoryClipboard::instance().add(item->getUUID());
+ LLClipboard::instance().addToClipboard(item->getUUID(),LLAssetType::AT_GESTURE);
}
}
}
else if ("paste" == command_name)
{
- LLInventoryClipboard& clipbord = LLInventoryClipboard::instance();
LLDynamicArray<LLUUID> ids;
- clipbord.retrieve(ids);
+ LLClipboard::instance().pasteFromClipboard(ids);
if(ids.empty() || !gInventory.isCategoryComplete(mGestureFolderID))
return;
LLInventoryCategory* gesture_dir = gInventory.getCategory(mGestureFolderID);
@@ -530,11 +535,11 @@ void LLFloaterGesture::onCopyPasteAction(const LLSD& command)
gesture_dir->getUUID(), getString("copy_name", string_args), cb);
}
}
- clipbord.reset();
+ LLClipboard::instance().reset();
}
else if ("copy_uuid" == command_name)
{
- gClipboard.copyFromString(utf8str_to_wstring(mGestureList->getCurrentID().asString()), mGestureList->getCurrentID());
+ LLClipboard::instance().copyToClipboard(mGestureList->getCurrentID(),LLAssetType::AT_GESTURE);
}
}
diff --git a/indra/newview/llfloatergodtools.cpp b/indra/newview/llfloatergodtools.cpp
index a34e0353ec..fb905eae11 100644
--- a/indra/newview/llfloatergodtools.cpp
+++ b/indra/newview/llfloatergodtools.cpp
@@ -1123,8 +1123,12 @@ bool LLPanelObjectTools::callbackSimWideDeletes( const LLSD& notification, const
void LLPanelObjectTools::onClickSet()
{
+ LLFloaterAvatarPicker* picker = LLFloaterAvatarPicker::show(boost::bind(&LLPanelObjectTools::callbackAvatarID, this, _1,_2));
// grandparent is a floater, which can have a dependent
- gFloaterView->getParentFloater(this)->addDependentFloater(LLFloaterAvatarPicker::show(boost::bind(&LLPanelObjectTools::callbackAvatarID, this, _1,_2)));
+ if (picker)
+ {
+ gFloaterView->getParentFloater(this)->addDependentFloater(picker);
+ }
}
void LLPanelObjectTools::onClickSetBySelection(void* data)
diff --git a/indra/newview/llfloaterland.cpp b/indra/newview/llfloaterland.cpp
index 95da8ff948..ee18c95b34 100644
--- a/indra/newview/llfloaterland.cpp
+++ b/indra/newview/llfloaterland.cpp
@@ -2739,7 +2739,12 @@ void LLPanelLandAccess::onCommitAny(LLUICtrl *ctrl, void *userdata)
void LLPanelLandAccess::onClickAddAccess()
{
- gFloaterView->getParentFloater(this)->addDependentFloater(LLFloaterAvatarPicker::show(boost::bind(&LLPanelLandAccess::callbackAvatarCBAccess, this, _1)) );
+ LLFloaterAvatarPicker* picker = LLFloaterAvatarPicker::show(
+ boost::bind(&LLPanelLandAccess::callbackAvatarCBAccess, this, _1));
+ if (picker)
+ {
+ gFloaterView->getParentFloater(this)->addDependentFloater(picker);
+ }
}
void LLPanelLandAccess::callbackAvatarCBAccess(const uuid_vec_t& ids)
@@ -2783,7 +2788,12 @@ void LLPanelLandAccess::onClickRemoveAccess(void* data)
// static
void LLPanelLandAccess::onClickAddBanned()
{
- gFloaterView->getParentFloater(this)->addDependentFloater(LLFloaterAvatarPicker::show(boost::bind(&LLPanelLandAccess::callbackAvatarCBBanned, this, _1)));
+ LLFloaterAvatarPicker* picker = LLFloaterAvatarPicker::show(
+ boost::bind(&LLPanelLandAccess::callbackAvatarCBBanned, this, _1));
+ if (picker)
+ {
+ gFloaterView->getParentFloater(this)->addDependentFloater(picker);
+ }
}
// static
diff --git a/indra/newview/llfloaterregioninfo.cpp b/indra/newview/llfloaterregioninfo.cpp
index 676059779c..17850ff35d 100644
--- a/indra/newview/llfloaterregioninfo.cpp
+++ b/indra/newview/llfloaterregioninfo.cpp
@@ -650,7 +650,10 @@ void LLPanelRegionGeneralInfo::onClickKick()
// in order to set up floater dependency
LLFloater* parent_floater = gFloaterView->getParentFloater(this);
LLFloater* child_floater = LLFloaterAvatarPicker::show(boost::bind(&LLPanelRegionGeneralInfo::onKickCommit, this, _1), FALSE, TRUE);
- parent_floater->addDependentFloater(child_floater);
+ if (child_floater)
+ {
+ parent_floater->addDependentFloater(child_floater);
+ }
}
void LLPanelRegionGeneralInfo::onKickCommit(const uuid_vec_t& ids)
@@ -1470,7 +1473,10 @@ void LLPanelEstateInfo::onClickKickUser()
// in order to set up floater dependency
LLFloater* parent_floater = gFloaterView->getParentFloater(this);
LLFloater* child_floater = LLFloaterAvatarPicker::show(boost::bind(&LLPanelEstateInfo::onKickUserCommit, this, _1), FALSE, TRUE);
- parent_floater->addDependentFloater(child_floater);
+ if (child_floater)
+ {
+ parent_floater->addDependentFloater(child_floater);
+ }
}
void LLPanelEstateInfo::onKickUserCommit(const uuid_vec_t& ids)
@@ -1891,6 +1897,26 @@ void LLPanelEstateInfo::sendEstateAccessDelta(U32 flags, const LLUUID& agent_or_
gAgent.sendReliableMessage();
}
+// static
+void LLPanelEstateInfo::updateEstateOwnerName(const std::string& name)
+{
+ LLPanelEstateInfo* panelp = LLFloaterRegionInfo::getPanelEstate();
+ if (panelp)
+ {
+ panelp->setOwnerName(name);
+ }
+}
+
+// static
+void LLPanelEstateInfo::updateEstateName(const std::string& name)
+{
+ LLPanelEstateInfo* panelp = LLFloaterRegionInfo::getPanelEstate();
+ if (panelp)
+ {
+ panelp->getChildRef<LLTextBox>("estate_name").setText(name);
+ }
+}
+
void LLPanelEstateInfo::updateControls(LLViewerRegion* region)
{
BOOL god = gAgent.isGodlike();
diff --git a/indra/newview/llfloaterregioninfo.h b/indra/newview/llfloaterregioninfo.h
index ae45949b4a..e36ef4604b 100644
--- a/indra/newview/llfloaterregioninfo.h
+++ b/indra/newview/llfloaterregioninfo.h
@@ -294,6 +294,9 @@ public:
void updateControls(LLViewerRegion* region);
+ static void updateEstateName(const std::string& name);
+ static void updateEstateOwnerName(const std::string& name);
+
virtual bool refreshFromRegion(LLViewerRegion* region);
virtual bool estateUpdate(LLMessageSystem* msg);
diff --git a/indra/newview/llfloaterreporter.cpp b/indra/newview/llfloaterreporter.cpp
index c08848b1ea..3ec1e372eb 100644
--- a/indra/newview/llfloaterreporter.cpp
+++ b/indra/newview/llfloaterreporter.cpp
@@ -285,7 +285,11 @@ void LLFloaterReporter::getObjectInfo(const LLUUID& object_id)
void LLFloaterReporter::onClickSelectAbuser()
{
- gFloaterView->getParentFloater(this)->addDependentFloater(LLFloaterAvatarPicker::show(boost::bind(&LLFloaterReporter::callbackAvatarID, this, _1, _2), FALSE, TRUE ));
+ LLFloaterAvatarPicker* picker = LLFloaterAvatarPicker::show(boost::bind(&LLFloaterReporter::callbackAvatarID, this, _1, _2), FALSE, TRUE );
+ if (picker)
+ {
+ gFloaterView->getParentFloater(this)->addDependentFloater(picker);
+ }
}
void LLFloaterReporter::callbackAvatarID(const uuid_vec_t& ids, const std::vector<LLAvatarName> names)
diff --git a/indra/newview/llfloatersellland.cpp b/indra/newview/llfloatersellland.cpp
index 3434841d09..64c0dfa023 100644
--- a/indra/newview/llfloatersellland.cpp
+++ b/indra/newview/llfloatersellland.cpp
@@ -392,8 +392,12 @@ void LLFloaterSellLandUI::onChangeValue(LLUICtrl *ctrl, void *userdata)
void LLFloaterSellLandUI::doSelectAgent()
{
+ LLFloaterAvatarPicker* picker = LLFloaterAvatarPicker::show(boost::bind(&LLFloaterSellLandUI::callbackAvatarPick, this, _1, _2), FALSE, TRUE);
// grandparent is a floater, in order to set up dependency
- addDependentFloater(LLFloaterAvatarPicker::show(boost::bind(&LLFloaterSellLandUI::callbackAvatarPick, this, _1, _2), FALSE, TRUE));
+ if (picker)
+ {
+ addDependentFloater(picker);
+ }
}
void LLFloaterSellLandUI::callbackAvatarPick(const uuid_vec_t& ids, const std::vector<LLAvatarName> names)
diff --git a/indra/newview/llfloatervoiceeffect.cpp b/indra/newview/llfloatervoiceeffect.cpp
index 030fed0575..227720bee3 100644
--- a/indra/newview/llfloatervoiceeffect.cpp
+++ b/indra/newview/llfloatervoiceeffect.cpp
@@ -145,7 +145,9 @@ void LLFloaterVoiceEffect::refreshEffectList()
for (voice_effect_list_t::const_iterator it = template_list.begin(); it != template_list.end(); ++it)
{
const LLUUID& effect_id = it->second;
- std::string effect_name = getString("effect_" + it->first); // will throw an error if the effect is not listed in the XML
+
+ std::string localized_effect = "effect_" + it->first;
+ std::string effect_name = hasString(localized_effect) ? getString(localized_effect) : it->first; // XML contains localized effects names
LLSD effect_properties = effect_interface->getVoiceEffectProperties(effect_id);
diff --git a/indra/newview/llfloaterwebcontent.cpp b/indra/newview/llfloaterwebcontent.cpp
index 3b5c3663fb..3fe2518de6 100644
--- a/indra/newview/llfloaterwebcontent.cpp
+++ b/indra/newview/llfloaterwebcontent.cpp
@@ -169,7 +169,7 @@ void LLFloaterWebContent::geometryChanged(const std::string &uuid, S32 x, S32 y,
void LLFloaterWebContent::geometryChanged(S32 x, S32 y, S32 width, S32 height)
{
// Make sure the layout of the browser control is updated, so this calculation is correct.
- LLLayoutStack::updateClass();
+ getChild<LLLayoutStack>("stack1")->updateLayout();
// TODO: need to adjust size and constrain position to make sure floaters aren't moved outside the window view, etc.
LLCoordWindow window_size;
@@ -258,7 +258,7 @@ void LLFloaterWebContent::open_media(const Params& p)
if (!p.preferred_media_size().isEmpty())
{
- LLLayoutStack::updateClass();
+ getChild<LLLayoutStack>("stack1")->updateLayout();
LLRect browser_rect = mWebBrowser->calcScreenRect();
LLCoordWindow window_size;
getWindow()->getSize(&window_size);
diff --git a/indra/newview/llfolderview.cpp b/indra/newview/llfolderview.cpp
index 86001e4146..bad0d8cd8f 100644
--- a/indra/newview/llfolderview.cpp
+++ b/indra/newview/llfolderview.cpp
@@ -30,7 +30,7 @@
#include "llcallbacklist.h"
#include "llinventorybridge.h"
-#include "llinventoryclipboard.h" // *TODO: remove this once hack below gone.
+#include "llclipboard.h" // *TODO: remove this once hack below gone.
#include "llinventoryfilter.h"
#include "llinventoryfunctions.h"
#include "llinventorymodelbackgroundfetch.h"
@@ -165,6 +165,33 @@ void LLCloseAllFoldersFunctor::doItem(LLFolderViewItem* item)
{ }
///----------------------------------------------------------------------------
+/// Class LLFolderViewScrollContainer
+///----------------------------------------------------------------------------
+
+// virtual
+const LLRect LLFolderViewScrollContainer::getScrolledViewRect() const
+{
+ LLRect rect = LLRect::null;
+ if (mScrolledView)
+ {
+ LLFolderView* folder_view = dynamic_cast<LLFolderView*>(mScrolledView);
+ if (folder_view)
+ {
+ S32 height = folder_view->mRunningHeight;
+
+ rect = mScrolledView->getRect();
+ rect.setLeftTopAndSize(rect.mLeft, rect.mTop, rect.getWidth(), height);
+ }
+ }
+
+ return rect;
+}
+
+LLFolderViewScrollContainer::LLFolderViewScrollContainer(const LLScrollContainer::Params& p)
+: LLScrollContainer(p)
+{}
+
+///----------------------------------------------------------------------------
/// Class LLFolderView
///----------------------------------------------------------------------------
LLFolderView::Params::Params()
@@ -429,8 +456,8 @@ S32 LLFolderView::arrange( S32* unused_width, S32* unused_height, S32 filter_gen
}
else
{
- folderp->setVisible(show_folder_state == LLInventoryFilter::SHOW_ALL_FOLDERS || // always show folders?
- (folderp->getFiltered(filter_generation) || folderp->hasFilteredDescendants(filter_generation))); // passed filter or has descendants that passed filter
+ folderp->setVisible((show_folder_state == LLInventoryFilter::SHOW_ALL_FOLDERS || // always show folders?
+ (folderp->getFiltered(filter_generation) || folderp->hasFilteredDescendants(filter_generation))));
}
if (folderp->getVisible())
@@ -535,6 +562,7 @@ void LLFolderView::reshape(S32 width, S32 height, BOOL called_from_parent)
{
width = scroll_rect.getWidth();
}
+
LLView::reshape(width, height, called_from_parent);
mReshapeSignal(mSelectedItems, FALSE);
}
@@ -769,7 +797,7 @@ void LLFolderView::sanitizeSelection()
// if nothing selected after prior constraints...
if (mSelectedItems.empty())
{
- // ...select first available parent of original selection, or "My Inventory" otherwise
+ // ...select first available parent of original selection
LLFolderViewItem* new_selection = NULL;
if (original_selected_item)
{
@@ -943,6 +971,9 @@ void LLFolderView::draw()
// We should call this method to also notify parent about required rect.
// See EXT-7564, EXT-7047.
arrangeFromRoot();
+ LLUI::popMatrix();
+ LLUI::pushMatrix();
+ LLUI::translate((F32)getRect().mLeft, (F32)getRect().mBottom);
}
}
@@ -1014,6 +1045,36 @@ bool isDescendantOfASelectedItem(LLFolderViewItem* item, const std::vector<LLFol
return false;
}
+// static
+void LLFolderView::removeCutItems()
+{
+ // There's no item in "cut" mode on the clipboard -> exit
+ if (!LLClipboard::instance().isCutMode())
+ return;
+
+ // Get the list of clipboard item uuids and iterate through them
+ LLDynamicArray<LLUUID> objects;
+ LLClipboard::instance().pasteFromClipboard(objects);
+ for (LLDynamicArray<LLUUID>::const_iterator iter = objects.begin();
+ iter != objects.end();
+ ++iter)
+ {
+ const LLUUID& item_id = (*iter);
+ LLInventoryObject *obj = gInventory.getObject(item_id);
+ if (obj)
+ {
+ if (LLAssetType::AT_CATEGORY == obj->getType())
+ {
+ remove_category(&gInventory, item_id);
+ }
+ else
+ {
+ remove_item(&gInventory, item_id);
+ }
+ }
+ }
+}
+
void LLFolderView::onItemsRemovalConfirmation(const LLSD& notification, const LLSD& response)
{
S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
@@ -1293,7 +1354,7 @@ BOOL LLFolderView::canCopy() const
void LLFolderView::copy()
{
// *NOTE: total hack to clear the inventory clipboard
- LLInventoryClipboard::instance().reset();
+ LLClipboard::instance().reset();
S32 count = mSelectedItems.size();
if(getVisible() && getEnabled() && (count > 0))
{
@@ -1334,7 +1395,7 @@ BOOL LLFolderView::canCut() const
void LLFolderView::cut()
{
// clear the inventory clipboard
- LLInventoryClipboard::instance().reset();
+ LLClipboard::instance().reset();
S32 count = mSelectedItems.size();
if(getVisible() && getEnabled() && (count > 0))
{
@@ -1348,6 +1409,7 @@ void LLFolderView::cut()
listener->cutToClipboard();
}
}
+ LLFolderView::removeCutItems();
}
mSearchString.clear();
}
@@ -1961,19 +2023,13 @@ void LLFolderView::deleteAllChildren()
void LLFolderView::scrollToShowSelection()
{
- // If items are filtered while background fetch is in progress
- // scrollbar resets to the first filtered item. See EXT-3981.
- // However we allow scrolling for folder views with mAutoSelectOverride
- // (used in Places SP) as an exception because the selection in them
- // is not reset during items filtering. See STORM-133.
- if ( (!LLInventoryModelBackgroundFetch::instance().folderFetchActive() || mAutoSelectOverride)
- && mSelectedItems.size() )
+ if ( mSelectedItems.size() )
{
mNeedsScroll = TRUE;
}
}
-// If the parent is scroll containter, scroll it to make the selection
+// If the parent is scroll container, scroll it to make the selection
// is maximally visible.
void LLFolderView::scrollToShowItem(LLFolderViewItem* item, const LLRect& constraint_rect)
{
@@ -2108,10 +2164,10 @@ bool LLFolderView::doToSelected(LLInventoryModel* model, const LLSD& userdata)
removeSelectedItems();
return true;
}
-
- if ("copy" == action)
- {
- LLInventoryClipboard::instance().reset();
+ if (("copy" == action) || ("cut" == action))
+ {
+ // Clear the clipboard before we start adding things on it
+ LLClipboard::instance().reset();
}
static const std::string change_folder_string = "change_folder_type_";
@@ -2192,46 +2248,56 @@ void LLFolderView::doIdle()
arrangeAll();
}
+ if (mFilter->isModified() && mFilter->isNotDefault())
+ {
+ mNeedsAutoSelect = TRUE;
+ }
mFilter->clearModified();
- BOOL filter_modified_and_active = mCompletedFilterGeneration < mFilter->getCurrentGeneration() &&
- mFilter->isNotDefault();
- mNeedsAutoSelect = filter_modified_and_active &&
- !(gFocusMgr.childHasKeyboardFocus(this) || gFocusMgr.getMouseCapture());
- // filter to determine visiblity before arranging
+ // filter to determine visibility before arranging
filterFromRoot();
// automatically show matching items, and select first one if we had a selection
- // do this every frame until user puts keyboard focus into the inventory window
- // signaling the end of the automatic update
- // only do this when mNeedsFilter is set, meaning filtered items have
- // potentially changed
if (mNeedsAutoSelect)
{
LLFastTimer t3(FTM_AUTO_SELECT);
// select new item only if a filtered item not currently selected
LLFolderViewItem* selected_itemp = mSelectedItems.empty() ? NULL : mSelectedItems.back();
- if ((selected_itemp && !selected_itemp->getFiltered()) && !mAutoSelectOverride)
+ if (!mAutoSelectOverride && (!selected_itemp || !selected_itemp->potentiallyFiltered()))
{
- // select first filtered item
- LLSelectFirstFilteredItem filter;
- applyFunctorRecursively(filter);
+ // these are named variables to get around gcc not binding non-const references to rvalues
+ // and functor application is inherently non-const to allow for stateful functors
+ LLSelectFirstFilteredItem functor;
+ applyFunctorRecursively(functor);
}
// Open filtered folders for folder views with mAutoSelectOverride=TRUE.
// Used by LLPlacesFolderView.
if (mAutoSelectOverride && !mFilter->getFilterSubString().empty())
{
- LLOpenFilteredFolders filter;
- applyFunctorRecursively(filter);
+ // these are named variables to get around gcc not binding non-const references to rvalues
+ // and functor application is inherently non-const to allow for stateful functors
+ LLOpenFilteredFolders functor;
+ applyFunctorRecursively(functor);
}
scrollToShowSelection();
}
+ BOOL filter_finished = mCompletedFilterGeneration >= mFilter->getCurrentGeneration()
+ && !LLInventoryModelBackgroundFetch::instance().folderFetchActive();
+ if (filter_finished
+ || gFocusMgr.childHasKeyboardFocus(inventory_panel)
+ || gFocusMgr.childHasMouseCapture(inventory_panel))
+ {
+ // finishing the filter process, giving focus to the folder view, or dragging the scrollbar all stop the auto select process
+ mNeedsAutoSelect = FALSE;
+ }
+
+
// during filtering process, try to pin selected item's location on screen
// this will happen when searching your inventory and when new items arrive
- if (filter_modified_and_active)
+ if (!filter_finished)
{
// calculate rectangle to pin item to at start of animated rearrange
if (!mPinningSelectedItem && !mSelectedItems.empty())
@@ -2297,7 +2363,7 @@ void LLFolderView::doIdle()
{
scrollToShowItem(mSelectedItems.back(), constraint_rect);
// continue scrolling until animated layout change is done
- if (!filter_modified_and_active
+ if (filter_finished
&& (!needsArrange() || !is_visible))
{
mNeedsScroll = FALSE;
diff --git a/indra/newview/llfolderview.h b/indra/newview/llfolderview.h
index 1d018b5e6a..da8bb15f8e 100644
--- a/indra/newview/llfolderview.h
+++ b/indra/newview/llfolderview.h
@@ -44,6 +44,7 @@
#include "lldepthstack.h"
#include "lleditmenuhandler.h"
#include "llfontgl.h"
+#include "llscrollcontainer.h"
#include "lltooldraganddrop.h"
#include "llviewertexture.h"
@@ -54,15 +55,33 @@ class LLInventoryModel;
class LLPanel;
class LLLineEditor;
class LLMenuGL;
-class LLScrollContainer;
class LLUICtrl;
class LLTextBox;
+/**
+ * Class LLFolderViewScrollContainer
+ *
+ * A scroll container which provides the information about the height
+ * of currently displayed folder view contents.
+ * Used for updating vertical scroll bar visibility in inventory panel.
+ * See LLScrollContainer::calcVisibleSize().
+ */
+class LLFolderViewScrollContainer : public LLScrollContainer
+{
+public:
+ /*virtual*/ ~LLFolderViewScrollContainer() {};
+ /*virtual*/ const LLRect getScrolledViewRect() const;
+
+protected:
+ LLFolderViewScrollContainer(const LLScrollContainer::Params& p);
+ friend class LLUICtrlFactory;
+};
+
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Class LLFolderView
//
-// Th LLFolderView represents the root level folder view object. It
-// manages the screen region of the folder view.
+// The LLFolderView represents the root level folder view object.
+// It manages the screen region of the folder view.
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
class LLFolderView : public LLFolderViewFolder, public LLEditMenuHandler
@@ -81,6 +100,9 @@ public:
Params();
};
+
+ friend class LLFolderViewScrollContainer;
+
LLFolderView(const Params&);
virtual ~LLFolderView( void );
@@ -88,7 +110,7 @@ public:
virtual LLFolderView* getRoot() { return this; }
- // FolderViews default to sort by name. This will change that,
+ // FolderViews default to sort by name. This will change that,
// and resort the items if necessary.
void setSortOrder(U32 order);
void setFilterPermMask(PermissionMask filter_perm_mask);
@@ -117,20 +139,20 @@ public:
virtual void setOpenArrangeRecursively(BOOL openitem, ERecurseType recurse);
virtual BOOL addFolder( LLFolderViewFolder* folder);
- // Finds width and height of this object and it's children. Also
- // makes sure that this view and it's children are the right size.
+ // Find width and height of this object and its children. Also
+ // makes sure that this view and its children are the right size.
virtual S32 arrange( S32* width, S32* height, S32 filter_generation );
void arrangeAll() { mArrangeGeneration++; }
S32 getArrangeGeneration() { return mArrangeGeneration; }
- // applies filters to control visibility of inventory items
+ // Apply filters to control visibility of inventory items
virtual void filter( LLInventoryFilter& filter);
- // get the last selected item
+ // Get the last selected item
virtual LLFolderViewItem* getCurSelectedItem( void );
- // Record the selected item and pass it down the hierachy.
+ // Record the selected item and pass it down the hierarchy.
virtual BOOL setSelection(LLFolderViewItem* selection, BOOL openitem,
BOOL take_keyboard_focus);
@@ -140,13 +162,13 @@ public:
// Called once a frame to update the selection if mSelectThisID has been set
void updateSelection();
- // This method is used to toggle the selection of an item. Walks
- // children, and keeps track of selected objects.
+ // This method is used to toggle the selection of an item.
+ // Walks children and keeps track of selected objects.
virtual BOOL changeSelection(LLFolderViewItem* selection, BOOL selected);
virtual std::set<LLUUID> getSelectionList() const;
- // make sure if ancestor is selected, descendents are not
+ // Make sure if ancestor is selected, descendents are not
void sanitizeSelection();
void clearSelection();
void addToSelectionList(LLFolderViewItem* item);
@@ -157,21 +179,22 @@ public:
void setDraggingOverItem(LLFolderViewItem* item) { mDraggingOverItem = item; }
LLFolderViewItem* getDraggingOverItem() { return mDraggingOverItem; }
- // deletion functionality
+ // Deletion functionality
void removeSelectedItems();
+ static void removeCutItems();
- // open the selected item.
+ // Open the selected item
void openSelectedItems( void );
void propertiesSelectedItems( void );
- // change the folder type
+ // Change the folder type
void changeType(LLInventoryModel *model, LLFolderType::EType new_folder_type);
void autoOpenItem(LLFolderViewFolder* item);
void closeAutoOpenedFolders();
BOOL autoOpenTest(LLFolderViewFolder* item);
- // copy & paste
+ // Copy & paste
virtual void copy();
virtual BOOL canCopy() const;
@@ -184,7 +207,7 @@ public:
virtual void doDelete();
virtual BOOL canDoDelete() const;
- // public rename functionality - can only start the process
+ // Public rename functionality - can only start the process
void startRenamingSelectedItem( void );
// These functions were used when there was only one folderview,
@@ -325,7 +348,7 @@ protected:
/**
* Is used to determine if we need to cut text In LLFolderViewItem to avoid horizontal scroll.
- * NOTE: For now it uses only to cut LLFolderViewItem::mLabel text to be used for Landmarks in Places Panel.
+ * NOTE: For now it's used only to cut LLFolderViewItem::mLabel text for Landmarks in Places Panel.
*/
bool mUseEllipses; // See EXT-719
diff --git a/indra/newview/llfoldervieweventlistener.h b/indra/newview/llfoldervieweventlistener.h
index aee31ca033..06682dcbf1 100644
--- a/indra/newview/llfoldervieweventlistener.h
+++ b/indra/newview/llfoldervieweventlistener.h
@@ -75,7 +75,7 @@ public:
virtual void move( LLFolderViewEventListener* parent_listener ) = 0;
virtual BOOL isItemCopyable() const = 0;
virtual BOOL copyToClipboard() const = 0;
- virtual void cutToClipboard() = 0;
+ virtual BOOL cutToClipboard() const = 0;
virtual BOOL isClipboardPasteable() const = 0;
virtual void pasteFromClipboard() = 0;
virtual void pasteLinkFromClipboard() = 0;
diff --git a/indra/newview/llfolderviewitem.cpp b/indra/newview/llfolderviewitem.cpp
index afad27b4e0..d2b4866987 100644
--- a/indra/newview/llfolderviewitem.cpp
+++ b/indra/newview/llfolderviewitem.cpp
@@ -40,6 +40,7 @@
#include "llviewerwindow.h" // Argh, only for setCursor()
// linden library includes
+#include "llclipboard.h"
#include "llfocusmgr.h" // gFocusMgr
#include "lltrans.h"
@@ -220,6 +221,11 @@ BOOL LLFolderViewItem::potentiallyVisible()
{
// we haven't been checked against min required filter
// or we have and we passed
+ return potentiallyFiltered();
+}
+
+BOOL LLFolderViewItem::potentiallyFiltered()
+{
return getLastFilterGeneration() < getRoot()->getFilter()->getMinRequiredGeneration() || getFiltered();
}
@@ -1002,7 +1008,7 @@ void LLFolderViewItem::draw()
LLColor4 color = (mIsSelected && filled) ? sHighlightFgColor : sFgColor;
if (highlight_link) color = sLinkColor;
if (in_library) color = sLibraryColor;
-
+
F32 right_x = 0;
F32 y = (F32)getRect().getHeight() - font->getLineHeight() - (F32)TEXT_PAD - (F32)TOP_PAD;
F32 text_left = (F32)(ARROW_SIZE + TEXT_PAD + ICON_WIDTH + ICON_PAD + mIndentation);
@@ -1158,7 +1164,37 @@ S32 LLFolderViewFolder::arrange( S32* width, S32* height, S32 filter_generation)
mNeedsSort = false;
}
- mHasVisibleChildren = hasFilteredDescendants(filter_generation);
+ // evaluate mHasVisibleChildren
+ mHasVisibleChildren = false;
+ if (hasFilteredDescendants(filter_generation))
+ {
+ // We have to verify that there's at least one child that's not filtered out
+ bool found = false;
+ // Try the items first
+ for (items_t::iterator iit = mItems.begin(); iit != mItems.end(); ++iit)
+ {
+ LLFolderViewItem* itemp = (*iit);
+ found = (itemp->getFiltered(filter_generation));
+ if (found)
+ break;
+ }
+ if (!found)
+ {
+ // If no item found, try the folders
+ for (folders_t::iterator fit = mFolders.begin(); fit != mFolders.end(); ++fit)
+ {
+ LLFolderViewFolder* folderp = (*fit);
+ found = ( folderp->getListener()
+ && (folderp->getFiltered(filter_generation)
+ || (folderp->getFilteredFolder(filter_generation)
+ && folderp->hasFilteredDescendants(filter_generation))));
+ if (found)
+ break;
+ }
+ }
+
+ mHasVisibleChildren = found;
+ }
// calculate height as a single item (without any children), and reshapes rectangle to match
LLFolderViewItem::arrange( width, height, filter_generation );
@@ -1311,7 +1347,7 @@ void LLFolderViewFolder::requestSort()
void LLFolderViewFolder::setCompletedFilterGeneration(S32 generation, BOOL recurse_up)
{
- mMostFilteredDescendantGeneration = llmin(mMostFilteredDescendantGeneration, generation);
+ //mMostFilteredDescendantGeneration = llmin(mMostFilteredDescendantGeneration, generation);
mCompletedFilterGeneration = generation;
// only aggregate up if we are a lower (older) value
if (recurse_up
@@ -1345,7 +1381,8 @@ void LLFolderViewFolder::filter( LLInventoryFilter& filter)
&& !mPassedFilter) // and did not pass the filter
{
// go ahead and flag this folder as done
- mLastFilterGeneration = filter_generation;
+ mLastFilterGeneration = filter_generation;
+ mStringMatchOffset = std::string::npos;
}
else // filter self only on first pass through
{
diff --git a/indra/newview/llfolderviewitem.h b/indra/newview/llfolderviewitem.h
index 4e8dc2da16..3c7592046a 100644
--- a/indra/newview/llfolderviewitem.h
+++ b/indra/newview/llfolderviewitem.h
@@ -304,7 +304,8 @@ public:
BOOL isDescendantOf( const LLFolderViewFolder* potential_ancestor );
S32 getIndentation() { return mIndentation; }
- virtual BOOL potentiallyVisible(); // do we know for a fact that this item has been filtered out?
+ virtual BOOL potentiallyVisible(); // do we know for a fact that this item won't be displayed?
+ virtual BOOL potentiallyFiltered(); // do we know for a fact that this item has been filtered out?
virtual BOOL getFiltered();
virtual BOOL getFiltered(S32 filter_generation);
diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp
index 2de2b17373..1f948abfae 100644
--- a/indra/newview/llinventorybridge.cpp
+++ b/indra/newview/llinventorybridge.cpp
@@ -47,7 +47,7 @@
#include "llgiveinventory.h"
#include "llimfloater.h"
#include "llimview.h"
-#include "llinventoryclipboard.h"
+#include "llclipboard.h"
#include "llinventorydefines.h"
#include "llinventoryfunctions.h"
#include "llinventorymodel.h"
@@ -143,6 +143,42 @@ bool isMarketplaceSendAction(const std::string& action)
return ("send_to_marketplace" == action);
}
+// Used by LLFolderBridge as callback for directory fetching recursion
+class LLRightClickInventoryFetchDescendentsObserver : public LLInventoryFetchDescendentsObserver
+{
+public:
+ LLRightClickInventoryFetchDescendentsObserver(const uuid_vec_t& ids) : LLInventoryFetchDescendentsObserver(ids) {}
+ ~LLRightClickInventoryFetchDescendentsObserver() {}
+ virtual void execute(bool clear_observer = false);
+ virtual void done()
+ {
+ execute(true);
+ }
+};
+
+// Used by LLFolderBridge as callback for directory content items fetching
+class LLRightClickInventoryFetchObserver : public LLInventoryFetchItemsObserver
+{
+public:
+ LLRightClickInventoryFetchObserver(const uuid_vec_t& ids) : LLInventoryFetchItemsObserver(ids) { };
+ ~LLRightClickInventoryFetchObserver() {}
+ void execute(bool clear_observer = false)
+ {
+ if (clear_observer)
+ {
+ dec_busy_count();
+ gInventory.removeObserver(this);
+ delete this;
+ }
+ // we've downloaded all the items, so repaint the dialog
+ LLFolderBridge::staticFolderOptionsMenu();
+ }
+ virtual void done()
+ {
+ execute(true);
+ }
+};
+
// +=================================================+
// | LLInvFVBridge |
// +=================================================+
@@ -215,13 +251,27 @@ BOOL LLInvFVBridge::isLink() const
/**
* @brief Adds this item into clipboard storage
*/
-void LLInvFVBridge::cutToClipboard()
+BOOL LLInvFVBridge::cutToClipboard() const
+{
+ const LLInventoryObject* obj = gInventory.getObject(mUUID);
+ if (obj && isItemMovable() && isItemRemovable())
+ {
+ LLClipboard::instance().setCutMode(true);
+ return LLClipboard::instance().addToClipboard(mUUID);
+ }
+ return FALSE;
+}
+
+BOOL LLInvFVBridge::copyToClipboard() const
{
- if(isItemMovable())
+ const LLInventoryObject* obj = gInventory.getObject(mUUID);
+ if (obj && isItemCopyable())
{
- LLInventoryClipboard::instance().cut(mUUID);
+ return LLClipboard::instance().addToClipboard(mUUID);
}
+ return FALSE;
}
+
// *TODO: make sure this does the right thing
void LLInvFVBridge::showProperties()
{
@@ -396,6 +446,11 @@ void LLInvFVBridge::removeBatchNoCheck(LLDynamicArray<LLFolderViewEventListener*
for(; it != end; ++it)
{
gInventory.moveObject((*it), trash_id);
+ LLViewerInventoryItem* item = gInventory.getItem(*it);
+ if (item)
+ {
+ model->updateItem(item);
+ }
}
// notify inventory observers.
@@ -404,7 +459,8 @@ void LLInvFVBridge::removeBatchNoCheck(LLDynamicArray<LLFolderViewEventListener*
BOOL LLInvFVBridge::isClipboardPasteable() const
{
- if (!LLInventoryClipboard::instance().hasContents() || !isAgentInventory())
+ // Return FALSE on degenerated cases: empty clipboard, no inventory, no agent
+ if (!LLClipboard::instance().hasContents() || !isAgentInventory())
{
return FALSE;
}
@@ -414,37 +470,42 @@ BOOL LLInvFVBridge::isClipboardPasteable() const
return FALSE;
}
- const LLUUID &agent_id = gAgent.getID();
+ // In cut mode, whatever is on the clipboard is always pastable
+ if (LLClipboard::instance().isCutMode())
+ {
+ return TRUE;
+ }
+ // In normal mode, we need to check each element of the clipboard to know if we can paste or not
LLDynamicArray<LLUUID> objects;
- LLInventoryClipboard::instance().retrieve(objects);
+ LLClipboard::instance().pasteFromClipboard(objects);
S32 count = objects.count();
for(S32 i = 0; i < count; i++)
{
const LLUUID &item_id = objects.get(i);
- // Can't paste folders
+ // Folders are pastable if all items in there are copyable
const LLInventoryCategory *cat = model->getCategory(item_id);
if (cat)
{
+ LLFolderBridge cat_br(mInventoryPanel.get(), mRoot, item_id);
+ if (!cat_br.isItemCopyable())
return FALSE;
+ // Skip to the next item in the clipboard
+ continue;
}
- const LLInventoryItem *item = model->getItem(item_id);
- if (item)
- {
- if (!item->getPermissions().allowCopyBy(agent_id))
- {
+ // Each item must be copyable to be pastable
+ LLItemBridge item_br(mInventoryPanel.get(), mRoot, item_id);
+ if (!item_br.isItemCopyable())
return FALSE;
}
- }
- }
return TRUE;
}
BOOL LLInvFVBridge::isClipboardPasteableAsLink() const
{
- if (!LLInventoryClipboard::instance().hasContents() || !isAgentInventory())
+ if (!LLClipboard::instance().hasContents() || !isAgentInventory())
{
return FALSE;
}
@@ -455,7 +516,7 @@ BOOL LLInvFVBridge::isClipboardPasteableAsLink() const
}
LLDynamicArray<LLUUID> objects;
- LLInventoryClipboard::instance().retrieve(objects);
+ LLClipboard::instance().pasteFromClipboard(objects);
S32 count = objects.count();
for(S32 i = 0; i < count; i++)
{
@@ -606,6 +667,12 @@ void LLInvFVBridge::getClipboardEntries(bool show_asset_id,
disabled_items.push_back(std::string("Copy"));
}
+ items.push_back(std::string("Cut"));
+ if (!isItemMovable() || !isItemRemovable())
+ {
+ disabled_items.push_back(std::string("Cut"));
+ }
+
if (canListOnMarketplace())
{
items.push_back(std::string("Marketplace Separator"));
@@ -1285,6 +1352,12 @@ void LLItemBridge::performAction(LLInventoryModel* model, std::string action)
gViewerWindow->getWindow()->copyTextToClipboard(utf8str_to_wstring(buffer));
return;
}
+ else if ("cut" == action)
+ {
+ cutToClipboard();
+ LLFolderView::removeCutItems();
+ return;
+ }
else if ("copy" == action)
{
copyToClipboard();
@@ -1292,7 +1365,6 @@ void LLItemBridge::performAction(LLInventoryModel* model, std::string action)
}
else if ("paste" == action)
{
- // Single item only
LLInventoryItem* itemp = model->getItem(mUUID);
if (!itemp) return;
@@ -1667,16 +1739,6 @@ BOOL LLItemBridge::isItemCopyable() const
return FALSE;
}
-BOOL LLItemBridge::copyToClipboard() const
-{
- if(isItemCopyable())
- {
- LLInventoryClipboard::instance().add(mUUID);
- return TRUE;
- }
- return FALSE;
-}
-
LLViewerInventoryItem* LLItemBridge::getItem() const
{
LLViewerInventoryItem* item = NULL;
@@ -1710,16 +1772,20 @@ BOOL LLFolderBridge::isItemMovable() const
LLInventoryObject* obj = getInventoryObject();
if(obj)
{
- return (!LLFolderType::lookupIsProtectedType(((LLInventoryCategory*)obj)->getPreferredType()));
+ // If it's a protected type folder, we can't move it
+ if (LLFolderType::lookupIsProtectedType(((LLInventoryCategory*)obj)->getPreferredType()))
+ return FALSE;
+ return TRUE;
}
return FALSE;
}
void LLFolderBridge::selectItem()
{
+ // Have no fear: the first thing start() does is to test if everything for that folder has been fetched...
+ LLInventoryModelBackgroundFetch::instance().start(getUUID(), true);
}
-
// Iterate through a folder's children to determine if
// all the children are removable.
class LLIsItemRemovable : public LLFolderViewFunctor
@@ -1775,19 +1841,35 @@ BOOL LLFolderBridge::isUpToDate() const
BOOL LLFolderBridge::isItemCopyable() const
{
- // Can copy folders to paste-as-link, but not for straight paste.
- return gSavedSettings.getBOOL("InventoryLinking");
+ // Folders are copyable if items in them are, recursively, copyable.
+
+ // Get the content of the folder
+ LLInventoryModel::cat_array_t* cat_array;
+ LLInventoryModel::item_array_t* item_array;
+ gInventory.getDirectDescendentsOf(mUUID,cat_array,item_array);
+
+ // Check the items
+ LLInventoryModel::item_array_t item_array_copy = *item_array;
+ for (LLInventoryModel::item_array_t::iterator iter = item_array_copy.begin(); iter != item_array_copy.end(); iter++)
+ {
+ LLInventoryItem* item = *iter;
+ LLItemBridge item_br(mInventoryPanel.get(), mRoot, item->getUUID());
+ if (!item_br.isItemCopyable())
+ return FALSE;
}
-BOOL LLFolderBridge::copyToClipboard() const
+ // Check the folders
+ LLInventoryModel::cat_array_t cat_array_copy = *cat_array;
+ for (LLInventoryModel::cat_array_t::iterator iter = cat_array_copy.begin(); iter != cat_array_copy.end(); iter++)
{
- if(isItemCopyable())
- {
- LLInventoryClipboard::instance().add(mUUID);
+ LLViewerInventoryCategory* category = *iter;
+ LLFolderBridge cat_br(mInventoryPanel.get(), mRoot, category->getUUID());
+ if (!cat_br.isItemCopyable())
+ return FALSE;
+ }
+
return TRUE;
}
- return FALSE;
-}
BOOL LLFolderBridge::isClipboardPasteable() const
{
@@ -1804,7 +1886,7 @@ BOOL LLFolderBridge::isClipboardPasteable() const
}
LLDynamicArray<LLUUID> objects;
- LLInventoryClipboard::instance().retrieve(objects);
+ LLClipboard::instance().pasteFromClipboard(objects);
const LLViewerInventoryCategory *current_cat = getCategory();
// Search for the direct descendent of current Friends subfolder among all pasted items,
@@ -1842,7 +1924,7 @@ BOOL LLFolderBridge::isClipboardPasteableAsLink() const
const BOOL is_in_friend_folder = LLFriendCardsManager::instance().isCategoryInFriendFolder( current_cat );
const LLUUID &current_cat_id = current_cat->getUUID();
LLDynamicArray<LLUUID> objects;
- LLInventoryClipboard::instance().retrieve(objects);
+ LLClipboard::instance().pasteFromClipboard(objects);
S32 count = objects.count();
for(S32 i = 0; i < count; i++)
{
@@ -2432,121 +2514,114 @@ BOOL move_inv_category_world_to_agent(const LLUUID& object_id,
return accept;
}
-//Used by LLFolderBridge as callback for directory recursion.
-class LLRightClickInventoryFetchObserver : public LLInventoryFetchItemsObserver
-{
-public:
- LLRightClickInventoryFetchObserver(const uuid_vec_t& ids) :
- LLInventoryFetchItemsObserver(ids),
- mCopyItems(false)
- { };
- LLRightClickInventoryFetchObserver(const uuid_vec_t& ids,
- const LLUUID& cat_id,
- bool copy_items) :
- LLInventoryFetchItemsObserver(ids),
- mCatID(cat_id),
- mCopyItems(copy_items)
- { };
- virtual void done()
- {
- // we've downloaded all the items, so repaint the dialog
- LLFolderBridge::staticFolderOptionsMenu();
-
- gInventory.removeObserver(this);
- delete this;
- }
-
-protected:
- LLUUID mCatID;
- bool mCopyItems;
-
-};
-
-//Used by LLFolderBridge as callback for directory recursion.
-class LLRightClickInventoryFetchDescendentsObserver : public LLInventoryFetchDescendentsObserver
-{
-public:
- LLRightClickInventoryFetchDescendentsObserver(const uuid_vec_t& ids,
- bool copy_items) :
- LLInventoryFetchDescendentsObserver(ids),
- mCopyItems(copy_items)
- {}
- ~LLRightClickInventoryFetchDescendentsObserver() {}
- virtual void done();
-protected:
- bool mCopyItems;
-};
-
-void LLRightClickInventoryFetchDescendentsObserver::done()
+void LLRightClickInventoryFetchDescendentsObserver::execute(bool clear_observer)
{
- // Avoid passing a NULL-ref as mCompleteFolders.front() down to
- // gInventory.collectDescendents()
+ // Bail out immediately if no descendents
if( mComplete.empty() )
{
llwarns << "LLRightClickInventoryFetchDescendentsObserver::done with empty mCompleteFolders" << llendl;
+ if (clear_observer)
+ {
dec_busy_count();
gInventory.removeObserver(this);
delete this;
+ }
return;
}
- // What we do here is get the complete information on the items in
- // the library, and set up an observer that will wait for that to
- // happen.
- LLInventoryModel::cat_array_t cat_array;
- LLInventoryModel::item_array_t item_array;
- gInventory.collectDescendents(mComplete.front(),
- cat_array,
- item_array,
- LLInventoryModel::EXCLUDE_TRASH);
- S32 count = item_array.count();
-#if 0 // HACK/TODO: Why?
- // This early causes a giant menu to get produced, and doesn't seem to be needed.
- if(!count)
- {
- llwarns << "Nothing fetched in category " << mCompleteFolders.front()
- << llendl;
+ // Copy the list of complete fetched folders while "this" is still valid
+ uuid_vec_t completed_folder = mComplete;
+
+ // Clean up, and remove this as an observer now since recursive calls
+ // could notify observers and throw us into an infinite loop.
+ if (clear_observer)
+ {
dec_busy_count();
gInventory.removeObserver(this);
delete this;
- return;
}
-#endif
- uuid_vec_t ids;
- for(S32 i = 0; i < count; ++i)
+ for (uuid_vec_t::iterator current_folder = completed_folder.begin(); current_folder != completed_folder.end(); ++current_folder)
{
- ids.push_back(item_array.get(i)->getUUID());
- }
+ // Get the information on the fetched folder items and subfolders and fetch those
+ LLInventoryModel::cat_array_t* cat_array;
+ LLInventoryModel::item_array_t* item_array;
+ gInventory.getDirectDescendentsOf(*current_folder, cat_array, item_array);
- LLRightClickInventoryFetchObserver* outfit = new LLRightClickInventoryFetchObserver(ids, mComplete.front(), mCopyItems);
+ S32 item_count = item_array->count();
+ S32 cat_count = cat_array->count();
+
+ // Move to next if current folder empty
+ if ((item_count == 0) && (cat_count == 0))
+ {
+ continue;
+ }
- // clean up, and remove this as an observer since the call to the
- // outfit could notify observers and throw us into an infinite
- // loop.
- dec_busy_count();
- gInventory.removeObserver(this);
- delete this;
+ uuid_vec_t ids;
+ LLRightClickInventoryFetchObserver* outfit = NULL;
+ LLRightClickInventoryFetchDescendentsObserver* categories = NULL;
- // increment busy count and either tell the inventory to check &
- // call done, or add this object to the inventory for observation.
- inc_busy_count();
+ // Fetch the items
+ if (item_count)
+ {
+ for (S32 i = 0; i < item_count; ++i)
+ {
+ ids.push_back(item_array->get(i)->getUUID());
+ }
+ outfit = new LLRightClickInventoryFetchObserver(ids);
+ }
+ // Fetch the subfolders
+ if (cat_count)
+ {
+ for (S32 i = 0; i < cat_count; ++i)
+ {
+ ids.push_back(cat_array->get(i)->getUUID());
+ }
+ categories = new LLRightClickInventoryFetchDescendentsObserver(ids);
+ }
- // do the fetch
+ // Perform the item fetch
+ if (outfit)
+ {
outfit->startFetch();
- outfit->done(); //Not interested in waiting and this will be right 99% of the time.
+ outfit->execute(); // Not interested in waiting and this will be right 99% of the time.
+ delete outfit;
//Uncomment the following code for laggy Inventory UI.
-/* if(outfit->isFinished())
+ /*
+ if (outfit->isFinished())
{
// everything is already here - call done.
- outfit->done();
+ outfit->execute();
+ delete outfit;
}
else
{
- // it's all on it's way - add an observer, and the inventory
+ // it's all on its way - add an observer, and the inventory
// will call done for us when everything is here.
+ inc_busy_count();
gInventory.addObserver(outfit);
- }*/
+ }
+ */
+ }
+ // Perform the subfolders fetch : this is where we truly recurse down the folder hierarchy
+ if (categories)
+ {
+ categories->startFetch();
+ if (categories->isFinished())
+ {
+ // everything is already here - call done.
+ categories->execute();
+ delete categories;
+ }
+ else
+ {
+ // it's all on its way - add an observer, and the inventory
+ // will call done for us when everything is here.
+ inc_busy_count();
+ gInventory.addObserver(categories);
+ }
+ }
+ }
}
@@ -2665,6 +2740,12 @@ void LLFolderBridge::performAction(LLInventoryModel* model, std::string action)
modifyOutfit(TRUE);
return;
}
+ else if ("cut" == action)
+ {
+ cutToClipboard();
+ LLFolderView::removeCutItems();
+ return;
+ }
else if ("copy" == action)
{
copyToClipboard();
@@ -2886,7 +2967,7 @@ void LLFolderBridge::pasteFromClipboard()
const BOOL move_is_into_outbox = model->isObjectDescendentOf(mUUID, outbox_id);
LLDynamicArray<LLUUID> objects;
- LLInventoryClipboard::instance().retrieve(objects);
+ LLClipboard::instance().pasteFromClipboard(objects);
if (move_is_into_outbox)
{
@@ -2936,7 +3017,8 @@ void LLFolderBridge::pasteFromClipboard()
const LLUUID& item_id = (*iter);
LLInventoryItem *item = model->getItem(item_id);
- if (item)
+ LLInventoryObject *obj = model->getObject(item_id);
+ if (obj)
{
if (move_is_into_current_outfit || move_is_into_outfit)
{
@@ -2945,10 +3027,21 @@ void LLFolderBridge::pasteFromClipboard()
dropToOutfit(item, move_is_into_current_outfit);
}
}
- else if(LLInventoryClipboard::instance().isCutMode())
+ else if (LLClipboard::instance().isCutMode())
+ {
+ // Do a move to "paste" a "cut"
+ // move_inventory_item() is not enough, as we have to update inventory locally too
+ if (LLAssetType::AT_CATEGORY == obj->getType())
+ {
+ LLViewerInventoryCategory* vicat = (LLViewerInventoryCategory *) model->getCategory(item_id);
+ llassert(vicat);
+ if (vicat)
+ {
+ changeCategoryParent(model, vicat, parent_id, FALSE);
+ }
+ }
+ else
{
- // move_inventory_item() is not enough,
- //we have to update inventory locally too
LLViewerInventoryItem* viitem = dynamic_cast<LLViewerInventoryItem*>(item);
llassert(viitem);
if (viitem)
@@ -2956,6 +3049,19 @@ void LLFolderBridge::pasteFromClipboard()
changeItemParent(model, viitem, parent_id, FALSE);
}
}
+ }
+ else
+ {
+ // Do a "copy" to "paste" a regular copy clipboard
+ if (LLAssetType::AT_CATEGORY == obj->getType())
+ {
+ LLViewerInventoryCategory* vicat = (LLViewerInventoryCategory *) model->getCategory(item_id);
+ llassert(vicat);
+ if (vicat)
+ {
+ copy_inventory_category(model, vicat, parent_id);
+ }
+ }
else
{
copy_inventory_item(
@@ -2969,6 +3075,9 @@ void LLFolderBridge::pasteFromClipboard()
}
}
}
+ // Change mode to paste for next paste
+ LLClipboard::instance().setCutMode(false);
+ }
}
void LLFolderBridge::pasteLinkFromClipboard()
@@ -2992,7 +3101,7 @@ void LLFolderBridge::pasteLinkFromClipboard()
const LLUUID parent_id(mUUID);
LLDynamicArray<LLUUID> objects;
- LLInventoryClipboard::instance().retrieve(objects);
+ LLClipboard::instance().pasteFromClipboard(objects);
for (LLDynamicArray<LLUUID>::const_iterator iter = objects.begin();
iter != objects.end();
++iter)
@@ -3030,6 +3139,8 @@ void LLFolderBridge::pasteLinkFromClipboard()
LLPointer<LLInventoryCallback>(NULL));
}
}
+ // Change mode to paste for next paste
+ LLClipboard::instance().setCutMode(false);
}
}
@@ -3287,16 +3398,19 @@ void LLFolderBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
folders.push_back(category->getUUID());
sSelf = getHandle();
- LLRightClickInventoryFetchDescendentsObserver* fetch = new LLRightClickInventoryFetchDescendentsObserver(folders, FALSE);
+ LLRightClickInventoryFetchDescendentsObserver* fetch = new LLRightClickInventoryFetchDescendentsObserver(folders);
fetch->startFetch();
- inc_busy_count();
if (fetch->isFinished())
{
+ // Do not call execute() or done() here as if the folder is here, there's likely no point drilling down
+ // This saves lots of time as buildContextMenu() is called a lot
+ delete fetch;
buildContextMenuFolderOptions(flags);
}
else
{
// it's all on its way - add an observer, and the inventory will call done for us when everything is here.
+ inc_busy_count();
gInventory.addObserver(fetch);
}
}
diff --git a/indra/newview/llinventorybridge.h b/indra/newview/llinventorybridge.h
index 3b4f845f54..dc9e88d54d 100644
--- a/indra/newview/llinventorybridge.h
+++ b/indra/newview/llinventorybridge.h
@@ -106,8 +106,8 @@ public:
virtual void removeBatch(LLDynamicArray<LLFolderViewEventListener*>& batch);
virtual void move(LLFolderViewEventListener* new_parent_bridge) {}
virtual BOOL isItemCopyable() const { return FALSE; }
- virtual BOOL copyToClipboard() const { return FALSE; }
- virtual void cutToClipboard();
+ virtual BOOL copyToClipboard() const;
+ virtual BOOL cutToClipboard() const;
virtual BOOL isClipboardPasteable() const;
virtual BOOL isClipboardPasteableAsLink() const;
virtual void pasteFromClipboard() {}
@@ -212,7 +212,6 @@ public:
virtual BOOL renameItem(const std::string& new_name);
virtual BOOL removeItem();
virtual BOOL isItemCopyable() const;
- virtual BOOL copyToClipboard() const;
virtual BOOL hasChildren() const { return FALSE; }
virtual BOOL isUpToDate() const { return TRUE; }
@@ -275,7 +274,6 @@ public:
virtual BOOL isItemCopyable() const;
virtual BOOL isClipboardPasteable() const;
virtual BOOL isClipboardPasteableAsLink() const;
- virtual BOOL copyToClipboard() const;
static void createWearable(LLFolderBridge* bridge, LLWearableType::EType type);
diff --git a/indra/newview/llinventoryfilter.cpp b/indra/newview/llinventoryfilter.cpp
index 5496c273f2..4d0af94f9f 100644
--- a/indra/newview/llinventoryfilter.cpp
+++ b/indra/newview/llinventoryfilter.cpp
@@ -39,8 +39,11 @@
#include "llviewerfoldertype.h"
// linden library includes
+#include "llclipboard.h"
#include "lltrans.h"
+LLFastTimer::DeclareTimer FT_FILTER_CLIPBOARD("Filter Clipboard");
+
LLInventoryFilter::FilterOps::FilterOps() :
mFilterObjectTypes(0xffffffffffffffffULL),
mFilterCategoryTypes(0xffffffffffffffffULL),
@@ -88,11 +91,15 @@ LLInventoryFilter::~LLInventoryFilter()
BOOL LLInventoryFilter::check(const LLFolderViewItem* item)
{
- // If it's a folder and we're showing all folders, return TRUE automatically.
+ // Clipboard cut items are *always* filtered so we need this value upfront
+ const LLFolderViewEventListener* listener = item->getListener();
+ const BOOL passed_clipboard = (listener ? checkAgainstClipboard(listener->getUUID()) : TRUE);
+
+ // If it's a folder and we're showing all folders, return automatically.
const BOOL is_folder = (dynamic_cast<const LLFolderViewFolder*>(item) != NULL);
if (is_folder && (mFilterOps.mShowFolderState == LLInventoryFilter::SHOW_ALL_FOLDERS))
{
- return TRUE;
+ return passed_clipboard;
}
mSubStringMatchOffset = mFilterSubString.size() ? item->getSearchableLabel().find(mFilterSubString) : std::string::npos;
@@ -103,6 +110,7 @@ BOOL LLInventoryFilter::check(const LLFolderViewItem* item)
const BOOL passed = (passed_filtertype &&
passed_permissions &&
passed_filterlink &&
+ passed_clipboard &&
(mFilterSubString.size() == 0 || mSubStringMatchOffset != std::string::npos));
return passed;
@@ -114,8 +122,10 @@ bool LLInventoryFilter::check(const LLInventoryItem* item)
const bool passed_filtertype = checkAgainstFilterType(item);
const bool passed_permissions = checkAgainstPermissions(item);
+ const BOOL passed_clipboard = checkAgainstClipboard(item->getUUID());
const bool passed = (passed_filtertype &&
passed_permissions &&
+ passed_clipboard &&
(mFilterSubString.size() == 0 || mSubStringMatchOffset != std::string::npos));
return passed;
@@ -145,12 +155,15 @@ bool LLInventoryFilter::checkFolder(const LLFolderViewFolder* folder) const
bool LLInventoryFilter::checkFolder(const LLUUID& folder_id) const
{
+ // Always check against the clipboard
+ const BOOL passed_clipboard = checkAgainstClipboard(folder_id);
+
// we're showing all folders, overriding filter
if (mFilterOps.mShowFolderState == LLInventoryFilter::SHOW_ALL_FOLDERS)
{
- return true;
+ return passed_clipboard;
}
-
+
if (mFilterOps.mFilterTypes & FILTERTYPE_CATEGORY)
{
// Can only filter categories for items in your inventory
@@ -163,7 +176,7 @@ bool LLInventoryFilter::checkFolder(const LLUUID& folder_id) const
return false;
}
- return true;
+ return passed_clipboard;
}
BOOL LLInventoryFilter::checkAgainstFilterType(const LLFolderViewItem* item) const
@@ -255,7 +268,7 @@ BOOL LLInventoryFilter::checkAgainstFilterType(const LLFolderViewItem* item) con
}
}
}
-
+
return TRUE;
}
@@ -309,6 +322,31 @@ bool LLInventoryFilter::checkAgainstFilterType(const LLInventoryItem* item) cons
return true;
}
+// Items and folders that are on the clipboard or, recursively, in a folder which
+// is on the clipboard must be filtered out if the clipboard is in the "cut" mode.
+bool LLInventoryFilter::checkAgainstClipboard(const LLUUID& object_id) const
+{
+ if (LLClipboard::instance().isCutMode())
+ {
+ LLFastTimer ft(FT_FILTER_CLIPBOARD);
+ LLUUID current_id = object_id;
+ LLInventoryObject *current_object = gInventory.getObject(object_id);
+ while (current_id.notNull() && current_object)
+ {
+ if (LLClipboard::instance().isOnClipboard(current_id))
+ {
+ return false;
+ }
+ current_id = current_object->getParentUUID();
+ if (current_id.notNull())
+ {
+ current_object = gInventory.getObject(current_id);
+ }
+ }
+ }
+ return true;
+}
+
BOOL LLInventoryFilter::checkAgainstPermissions(const LLFolderViewItem* item) const
{
const LLFolderViewEventListener* listener = item->getListener();
@@ -364,6 +402,11 @@ std::string::size_type LLInventoryFilter::getStringMatchOffset() const
return mSubStringMatchOffset;
}
+BOOL LLInventoryFilter::isDefault() const
+{
+ return !isNotDefault();
+}
+
// has user modified default filter params?
BOOL LLInventoryFilter::isNotDefault() const
{
@@ -379,7 +422,7 @@ BOOL LLInventoryFilter::isNotDefault() const
not_default |= (mFilterOps.mMinDate != mDefaultFilterOps.mMinDate);
not_default |= (mFilterOps.mMaxDate != mDefaultFilterOps.mMaxDate);
not_default |= (mFilterOps.mHoursAgo != mDefaultFilterOps.mHoursAgo);
-
+
return not_default;
}
@@ -558,8 +601,14 @@ void LLInventoryFilter::setDateRange(time_t min_date, time_t max_date)
setModified();
}
- areDateLimitsSet() ? mFilterOps.mFilterTypes |= FILTERTYPE_DATE
- : mFilterOps.mFilterTypes &= ~FILTERTYPE_DATE;
+ if (areDateLimitsSet())
+ {
+ mFilterOps.mFilterTypes |= FILTERTYPE_DATE;
+ }
+ else
+ {
+ mFilterOps.mFilterTypes &= ~FILTERTYPE_DATE;
+ }
}
void LLInventoryFilter::setDateRangeLastLogoff(BOOL sl)
@@ -575,8 +624,14 @@ void LLInventoryFilter::setDateRangeLastLogoff(BOOL sl)
setModified();
}
- areDateLimitsSet() ? mFilterOps.mFilterTypes |= FILTERTYPE_DATE
- : mFilterOps.mFilterTypes &= ~FILTERTYPE_DATE;
+ if (areDateLimitsSet())
+ {
+ mFilterOps.mFilterTypes |= FILTERTYPE_DATE;
+ }
+ else
+ {
+ mFilterOps.mFilterTypes &= ~FILTERTYPE_DATE;
+ }
}
BOOL LLInventoryFilter::isSinceLogoff() const
@@ -622,8 +677,14 @@ void LLInventoryFilter::setHoursAgo(U32 hours)
}
}
- areDateLimitsSet() ? mFilterOps.mFilterTypes |= FILTERTYPE_DATE
- : mFilterOps.mFilterTypes &= ~FILTERTYPE_DATE;
+ if (areDateLimitsSet())
+ {
+ mFilterOps.mFilterTypes |= FILTERTYPE_DATE;
+ }
+ else
+ {
+ mFilterOps.mFilterTypes &= ~FILTERTYPE_DATE;
+ }
}
void LLInventoryFilter::setFilterLinks(U64 filter_links)
@@ -947,7 +1008,7 @@ void LLInventoryFilter::fromLLSD(LLSD& data)
{
if(data.has("filter_types"))
{
- setFilterObjectTypes((U32)data["filter_types"].asInteger());
+ setFilterObjectTypes((U64)data["filter_types"].asInteger());
}
if(data.has("min_date") && data.has("max_date"))
diff --git a/indra/newview/llinventoryfilter.h b/indra/newview/llinventoryfilter.h
index 6be2acfaa3..9e600c036f 100644
--- a/indra/newview/llinventoryfilter.h
+++ b/indra/newview/llinventoryfilter.h
@@ -124,6 +124,7 @@ public:
BOOL checkAgainstPermissions(const LLFolderViewItem* item) const;
bool checkAgainstPermissions(const LLInventoryItem* item) const;
BOOL checkAgainstFilterLinks(const LLFolderViewItem* item) const;
+ bool checkAgainstClipboard(const LLUUID& object_id) const;
std::string::size_type getStringMatchOffset() const;
@@ -162,6 +163,7 @@ public:
// +-------------------------------------------------------------------+
// + Default
// +-------------------------------------------------------------------+
+ BOOL isDefault() const;
BOOL isNotDefault() const;
void markDefault();
void resetDefault();
diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp
index dd92188e9d..f74a239fd3 100644
--- a/indra/newview/llinventoryfunctions.cpp
+++ b/indra/newview/llinventoryfunctions.cpp
@@ -54,7 +54,6 @@
#include "lliconctrl.h"
#include "llimview.h"
#include "llinventorybridge.h"
-#include "llinventoryclipboard.h"
#include "llinventorymodel.h"
#include "llinventorypanel.h"
#include "lllineeditor.h"
@@ -161,6 +160,31 @@ void change_category_parent(LLInventoryModel* model,
model->notifyObservers();
}
+// Move the item to the trash. Works for folders and objects.
+// Caution: This method assumes that the item is removable!
+void remove_item(LLInventoryModel* model, const LLUUID& id)
+{
+ LLViewerInventoryItem* item = model->getItem(id);
+ if (!item)
+ return;
+
+ if (item->getType() == LLAssetType::AT_CATEGORY)
+ {
+ // Call the general helper function to delete a folder
+ remove_category(model, id);
+ }
+ else
+ {
+ // Get the trash UUID
+ LLUUID trash_id = model->findCategoryUUIDForType(LLFolderType::FT_TRASH, false);
+ if (trash_id.notNull())
+ {
+ // Finally, move the item to the trash
+ change_item_parent(model, item, trash_id, true);
+ }
+ }
+}
+
void remove_category(LLInventoryModel* model, const LLUUID& cat_id)
{
if (!model || !get_is_category_removable(model, cat_id))
@@ -214,6 +238,49 @@ void rename_category(LLInventoryModel* model, const LLUUID& cat_id, const std::s
model->notifyObservers();
}
+void copy_inventory_category(LLInventoryModel* model,
+ LLViewerInventoryCategory* cat,
+ const LLUUID& parent_id,
+ const LLUUID& root_copy_id)
+{
+ // Create the initial folder
+ LLUUID new_cat_uuid = gInventory.createNewCategory(parent_id, LLFolderType::FT_NONE, cat->getName());
+ model->notifyObservers();
+
+ // We need to exclude the initial root of the copy to avoid recursively copying the copy, etc...
+ LLUUID root_id = (root_copy_id.isNull() ? new_cat_uuid : root_copy_id);
+
+ // Get the content of the folder
+ LLInventoryModel::cat_array_t* cat_array;
+ LLInventoryModel::item_array_t* item_array;
+ gInventory.getDirectDescendentsOf(cat->getUUID(),cat_array,item_array);
+
+ // Copy all the items
+ LLInventoryModel::item_array_t item_array_copy = *item_array;
+ for (LLInventoryModel::item_array_t::iterator iter = item_array_copy.begin(); iter != item_array_copy.end(); iter++)
+ {
+ LLInventoryItem* item = *iter;
+ copy_inventory_item(
+ gAgent.getID(),
+ item->getPermissions().getOwner(),
+ item->getUUID(),
+ new_cat_uuid,
+ std::string(),
+ LLPointer<LLInventoryCallback>(NULL));
+ }
+
+ // Copy all the folders
+ LLInventoryModel::cat_array_t cat_array_copy = *cat_array;
+ for (LLInventoryModel::cat_array_t::iterator iter = cat_array_copy.begin(); iter != cat_array_copy.end(); iter++)
+ {
+ LLViewerInventoryCategory* category = *iter;
+ if (category->getUUID() != root_id)
+ {
+ copy_inventory_category(model, category, new_cat_uuid, root_id);
+ }
+ }
+}
+
class LLInventoryCollectAllItems : public LLInventoryCollectFunctor
{
public:
@@ -992,20 +1059,24 @@ void LLSaveFolderState::setApply(BOOL apply)
void LLSaveFolderState::doFolder(LLFolderViewFolder* folder)
{
LLMemType mt(LLMemType::MTYPE_INVENTORY_DO_FOLDER);
+ LLInvFVBridge* bridge = (LLInvFVBridge*)folder->getListener();
+ if(!bridge) return;
+
if(mApply)
{
// we're applying the open state
- LLInvFVBridge* bridge = (LLInvFVBridge*)folder->getListener();
- if(!bridge) return;
LLUUID id(bridge->getUUID());
if(mOpenFolders.find(id) != mOpenFolders.end())
{
- folder->setOpen(TRUE);
+ if (!folder->isOpen())
+ {
+ folder->setOpen(TRUE);
+ }
}
else
{
// keep selected filter in its current state, this is less jarring to user
- if (!folder->isSelected())
+ if (!folder->isSelected() && folder->isOpen())
{
folder->setOpen(FALSE);
}
@@ -1016,8 +1087,6 @@ void LLSaveFolderState::doFolder(LLFolderViewFolder* folder)
// we're recording state at this point
if(folder->isOpen())
{
- LLInvFVBridge* bridge = (LLInvFVBridge*)folder->getListener();
- if(!bridge) return;
mOpenFolders.insert(bridge->getUUID());
}
}
@@ -1053,7 +1122,6 @@ void LLSelectFirstFilteredItem::doItem(LLFolderViewItem *item)
{
item->getParentFolder()->setOpenArrangeRecursively(TRUE, LLFolderViewFolder::RECURSE_UP);
}
- item->getRoot()->scrollToShowSelection();
mItemSelected = TRUE;
}
}
@@ -1067,7 +1135,6 @@ void LLSelectFirstFilteredItem::doFolder(LLFolderViewFolder* folder)
{
folder->getParentFolder()->setOpenArrangeRecursively(TRUE, LLFolderViewFolder::RECURSE_UP);
}
- folder->getRoot()->scrollToShowSelection();
mItemSelected = TRUE;
}
}
diff --git a/indra/newview/llinventoryfunctions.h b/indra/newview/llinventoryfunctions.h
index ce2b89b22e..b3d9f4b966 100644
--- a/indra/newview/llinventoryfunctions.h
+++ b/indra/newview/llinventoryfunctions.h
@@ -62,6 +62,8 @@ void change_item_parent(LLInventoryModel* model,
const LLUUID& new_parent_id,
BOOL restamp);
+void remove_item(LLInventoryModel* model, const LLUUID& id);
+
void change_category_parent(LLInventoryModel* model,
LLViewerInventoryCategory* cat,
const LLUUID& new_parent_id,
@@ -71,6 +73,8 @@ void remove_category(LLInventoryModel* model, const LLUUID& cat_id);
void rename_category(LLInventoryModel* model, const LLUUID& cat_id, const std::string& new_name);
+void copy_inventory_category(LLInventoryModel* model, LLViewerInventoryCategory* cat, const LLUUID& parent_id, const LLUUID& root_copy_id = LLUUID::null);
+
// Generates a string containing the path to the item specified by item_id.
void append_path(const LLUUID& id, std::string& path);
diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp
index a71b699fdd..0eba8bd0f1 100644
--- a/indra/newview/llinventorymodel.cpp
+++ b/indra/newview/llinventorymodel.cpp
@@ -30,6 +30,7 @@
#include "llagent.h"
#include "llagentwearables.h"
#include "llappearancemgr.h"
+#include "llclipboard.h"
#include "llinventorypanel.h"
#include "llinventorybridge.h"
#include "llinventoryfunctions.h"
@@ -1110,50 +1111,82 @@ void LLInventoryModel::purgeDescendentsOf(const LLUUID& id)
return;
}
LLPointer<LLViewerInventoryCategory> cat = getCategory(id);
- if(cat.notNull())
- {
- // do the cache accounting
- llinfos << "LLInventoryModel::purgeDescendentsOf " << cat->getName()
- << llendl;
- S32 descendents = cat->getDescendentCount();
- if(descendents > 0)
- {
- LLCategoryUpdate up(id, -descendents);
- accountForUpdate(up);
+ if (cat.notNull())
+ {
+ if (LLClipboard::instance().hasContents() && LLClipboard::instance().isCutMode())
+ {
+ // Something on the clipboard is in "cut mode" and needs to be preserved
+ llinfos << "LLInventoryModel::purgeDescendentsOf " << cat->getName()
+ << " iterate and purge non hidden items" << llendl;
+ cat_array_t* categories;
+ item_array_t* items;
+ // Get the list of direct descendants in tha categoy passed as argument
+ getDirectDescendentsOf(id, categories, items);
+ std::vector<LLUUID> list_uuids;
+ // Make a unique list with all the UUIDs of the direct descendants (items and categories are not treated differently)
+ // Note: we need to do that shallow copy as purging things will invalidate the categories or items lists
+ for (cat_array_t::const_iterator it = categories->begin(); it != categories->end(); ++it)
+ {
+ list_uuids.push_back((*it)->getUUID());
+ }
+ for (item_array_t::const_iterator it = items->begin(); it != items->end(); ++it)
+ {
+ list_uuids.push_back((*it)->getUUID());
+ }
+ // Iterate through the list and only purge the UUIDs that are not on the clipboard
+ for (std::vector<LLUUID>::const_iterator it = list_uuids.begin(); it != list_uuids.end(); ++it)
+ {
+ if (!LLClipboard::instance().isOnClipboard(*it))
+ {
+ purgeObject(*it);
+ }
+ }
}
+ else
+ {
+ // Fast purge
+ // do the cache accounting
+ llinfos << "LLInventoryModel::purgeDescendentsOf " << cat->getName()
+ << llendl;
+ S32 descendents = cat->getDescendentCount();
+ if(descendents > 0)
+ {
+ LLCategoryUpdate up(id, -descendents);
+ accountForUpdate(up);
+ }
- // we know that descendent count is 0, aide since the
- // accounting may actually not do an update, we should force
- // it here.
- cat->setDescendentCount(0);
+ // we know that descendent count is 0, however since the
+ // accounting may actually not do an update, we should force
+ // it here.
+ cat->setDescendentCount(0);
+
+ // send it upstream
+ LLMessageSystem* msg = gMessageSystem;
+ msg->newMessage("PurgeInventoryDescendents");
+ msg->nextBlock("AgentData");
+ msg->addUUID("AgentID", gAgent.getID());
+ msg->addUUID("SessionID", gAgent.getSessionID());
+ msg->nextBlock("InventoryData");
+ msg->addUUID("FolderID", id);
+ gAgent.sendReliableMessage();
- // send it upstream
- LLMessageSystem* msg = gMessageSystem;
- msg->newMessage("PurgeInventoryDescendents");
- msg->nextBlock("AgentData");
- msg->addUUID("AgentID", gAgent.getID());
- msg->addUUID("SessionID", gAgent.getSessionID());
- msg->nextBlock("InventoryData");
- msg->addUUID("FolderID", id);
- gAgent.sendReliableMessage();
-
- // unceremoniously remove anything we have locally stored.
- cat_array_t categories;
- item_array_t items;
- collectDescendents(id,
- categories,
- items,
- INCLUDE_TRASH);
- S32 count = items.count();
- S32 i;
- for(i = 0; i < count; ++i)
- {
- deleteObject(items.get(i)->getUUID());
- }
- count = categories.count();
- for(i = 0; i < count; ++i)
- {
- deleteObject(categories.get(i)->getUUID());
+ // unceremoniously remove anything we have locally stored.
+ cat_array_t categories;
+ item_array_t items;
+ collectDescendents(id,
+ categories,
+ items,
+ INCLUDE_TRASH);
+ S32 count = items.count();
+ for(S32 i = 0; i < count; ++i)
+ {
+ deleteObject(items.get(i)->getUUID());
+ }
+ count = categories.count();
+ for(S32 i = 0; i < count; ++i)
+ {
+ deleteObject(categories.get(i)->getUUID());
+ }
}
}
}
diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp
index 01a8ecfb5d..71dd963f28 100644
--- a/indra/newview/llinventorypanel.cpp
+++ b/indra/newview/llinventorypanel.cpp
@@ -33,6 +33,7 @@
#include "llagentwearables.h"
#include "llappearancemgr.h"
#include "llavataractions.h"
+#include "llclipboard.h"
#include "llfloaterinventory.h"
#include "llfloaterreg.h"
#include "llfloatersidepanelcontainer.h"
@@ -206,10 +207,11 @@ void LLInventoryPanel::initFromParams(const LLInventoryPanel::Params& params)
scroller_view_rect.translate(-scroller_view_rect.mLeft, -scroller_view_rect.mBottom);
LLScrollContainer::Params scroller_params(params.scroll());
scroller_params.rect(scroller_view_rect);
- mScroller = LLUICtrlFactory::create<LLScrollContainer>(scroller_params);
+ mScroller = LLUICtrlFactory::create<LLFolderViewScrollContainer>(scroller_params);
addChild(mScroller);
mScroller->addChild(mFolderRoot);
mFolderRoot->setScrollContainer(mScroller);
+ mFolderRoot->setFollowsAll();
mFolderRoot->addChild(mFolderRoot->mStatusTextBox);
}
@@ -247,6 +249,9 @@ void LLInventoryPanel::initFromParams(const LLInventoryPanel::Params& params)
getFilter()->setFilterEmptySystemFolders();
}
+ // keep track of the clipboard state so that we avoid filtering too much
+ mClipboardState = LLClipboard::instance().getGeneration();
+
// Initialize base class params.
LLPanel::initFromParams(params);
}
@@ -277,6 +282,14 @@ void LLInventoryPanel::draw()
{
// Select the desired item (in case it wasn't loaded when the selection was requested)
mFolderRoot->updateSelection();
+
+ // Nudge the filter if the clipboard state changed
+ if (mClipboardState != LLClipboard::instance().getGeneration())
+ {
+ mClipboardState = LLClipboard::instance().getGeneration();
+ getFilter()->setModified(LLClipboard::instance().isCutMode() ? LLInventoryFilter::FILTER_MORE_RESTRICTIVE : LLInventoryFilter::FILTER_LESS_RESTRICTIVE);
+ }
+
LLPanel::draw();
}
diff --git a/indra/newview/llinventorypanel.h b/indra/newview/llinventorypanel.h
index 7d805f6862..6db59afb9b 100644
--- a/indra/newview/llinventorypanel.h
+++ b/indra/newview/llinventorypanel.h
@@ -222,6 +222,7 @@ public:
private:
std::string mSortOrderSetting;
+ int mClipboardState;
//--------------------------------------------------------------------
// Hidden folders
diff --git a/indra/newview/llpanelgroupinvite.cpp b/indra/newview/llpanelgroupinvite.cpp
index ca48e8561b..7a15d93181 100644
--- a/indra/newview/llpanelgroupinvite.cpp
+++ b/indra/newview/llpanelgroupinvite.cpp
@@ -289,12 +289,12 @@ void LLPanelGroupInvite::impl::callbackClickAdd(void* userdata)
//Soon the avatar picker will be embedded into this panel
//instead of being it's own separate floater. But that is next week.
//This will do for now. -jwolk May 10, 2006
- LLFloater* parentp;
-
- parentp = gFloaterView->getParentFloater(panelp);
- parentp->addDependentFloater(LLFloaterAvatarPicker::show(boost::bind(impl::callbackAddUsers, _1,
- panelp->mImplementation),
- TRUE));
+ LLFloaterAvatarPicker* picker = LLFloaterAvatarPicker::show(
+ boost::bind(impl::callbackAddUsers, _1, panelp->mImplementation), TRUE);
+ if (picker)
+ {
+ gFloaterView->getParentFloater(panelp)->addDependentFloater(picker);
+ }
}
}
diff --git a/indra/newview/llpanellandmarks.cpp b/indra/newview/llpanellandmarks.cpp
index c7454e85a9..68a3b6d1cd 100644
--- a/indra/newview/llpanellandmarks.cpp
+++ b/indra/newview/llpanellandmarks.cpp
@@ -1149,7 +1149,7 @@ Rules:
- cut/rename/delete in any other accordions
- paste - only in Favorites, Landmarks accordions
3. For Folders we can: perform any action in Landmarks accordion, except Received folder
- 4. We can not paste folders from Clipboard (processed by LLFolderView::canPaste())
+ 4. We can paste folders from Clipboard (processed by LLFolderView::canPaste())
5. Check LLFolderView/Inventory Bridges rules
*/
bool LLLandmarksPanel::canItemBeModified(const std::string& command_name, LLFolderViewItem* item) const
@@ -1206,8 +1206,7 @@ bool LLLandmarksPanel::canItemBeModified(const std::string& command_name, LLFold
if ("cut" == command_name)
{
- // "Cut" disabled for folders. See EXT-8697.
- can_be_modified = root_folder->canCut() && listenerp->getInventoryType() != LLInventoryType::IT_CATEGORY;
+ can_be_modified = root_folder->canCut();
}
else if ("rename" == command_name)
{
diff --git a/indra/newview/llpanelmaininventory.cpp b/indra/newview/llpanelmaininventory.cpp
index c3c62920d3..c11597f532 100644
--- a/indra/newview/llpanelmaininventory.cpp
+++ b/indra/newview/llpanelmaininventory.cpp
@@ -375,7 +375,7 @@ void LLPanelMainInventory::onClearSearch()
if (mActivePanel)
{
mActivePanel->setFilterSubString(LLStringUtil::null);
- mActivePanel->setFilterTypes(0xffffffff);
+ mActivePanel->setFilterTypes(0xffffffffffffffffULL);
mActivePanel->setFilterLinks(LLInventoryFilter::FILTERLINK_INCLUDE_LINKS);
}
@@ -726,7 +726,7 @@ void LLFloaterInventoryFinder::updateElementsFromFilter()
void LLFloaterInventoryFinder::draw()
{
LLMemType mt(LLMemType::MTYPE_INVENTORY_DRAW);
- U32 filter = 0xffffffff;
+ U64 filter = 0xffffffffffffffffULL;
BOOL filtered_by_all_types = TRUE;
if (!getChild<LLUICtrl>("check_animation")->getValue())
diff --git a/indra/newview/llpanelobjectinventory.cpp b/indra/newview/llpanelobjectinventory.cpp
index 98ea680504..1ca24f3031 100644
--- a/indra/newview/llpanelobjectinventory.cpp
+++ b/indra/newview/llpanelobjectinventory.cpp
@@ -124,7 +124,7 @@ public:
virtual void move(LLFolderViewEventListener* parent_listener);
virtual BOOL isItemCopyable() const;
virtual BOOL copyToClipboard() const;
- virtual void cutToClipboard();
+ virtual BOOL cutToClipboard() const;
virtual BOOL isClipboardPasteable() const;
virtual void pasteFromClipboard();
virtual void pasteLinkFromClipboard();
@@ -524,8 +524,9 @@ BOOL LLTaskInvFVBridge::copyToClipboard() const
return FALSE;
}
-void LLTaskInvFVBridge::cutToClipboard()
+BOOL LLTaskInvFVBridge::cutToClipboard() const
{
+ return FALSE;
}
BOOL LLTaskInvFVBridge::isClipboardPasteable() const
@@ -1568,7 +1569,7 @@ void LLPanelObjectInventory::reset()
scroll_p.rect(scroller_rect);
scroll_p.tab_stop(true);
scroll_p.follows.flags(FOLLOWS_ALL);
- mScroller = LLUICtrlFactory::create<LLScrollContainer>(scroll_p);
+ mScroller = LLUICtrlFactory::create<LLFolderViewScrollContainer>(scroll_p);
addChild(mScroller);
mScroller->addChild(mFolders);
diff --git a/indra/newview/llpanelteleporthistory.cpp b/indra/newview/llpanelteleporthistory.cpp
index 1f1cccad85..c63d89fc98 100644
--- a/indra/newview/llpanelteleporthistory.cpp
+++ b/indra/newview/llpanelteleporthistory.cpp
@@ -358,7 +358,7 @@ void LLTeleportHistoryPanel::ContextMenu::onInfo()
//static
void LLTeleportHistoryPanel::ContextMenu::gotSLURLCallback(const std::string& slurl)
{
- gClipboard.copyFromString(utf8str_to_wstring(slurl));
+ LLClipboard::instance().copyToClipboard(utf8str_to_wstring(slurl),0,slurl.size());
}
void LLTeleportHistoryPanel::ContextMenu::onCopyToClipboard()
diff --git a/indra/newview/llpaneltopinfobar.cpp b/indra/newview/llpaneltopinfobar.cpp
index eb4c7572d4..280cc11179 100644
--- a/indra/newview/llpaneltopinfobar.cpp
+++ b/indra/newview/llpaneltopinfobar.cpp
@@ -467,7 +467,7 @@ void LLPanelTopInfoBar::onContextMenuItemClicked(const LLSD::String& item)
LLAgentUI::buildSLURL(slurl, false);
LLUIString location_str(slurl.getSLURLString());
- gClipboard.copyFromString(location_str);
+ LLClipboard::instance().copyToClipboard(location_str,0,location_str.length());
}
}
diff --git a/indra/newview/llpanelwearing.cpp b/indra/newview/llpanelwearing.cpp
index e2801c09bd..3b9934d4be 100644
--- a/indra/newview/llpanelwearing.cpp
+++ b/indra/newview/llpanelwearing.cpp
@@ -302,6 +302,6 @@ void LLPanelWearing::copyToClipboard()
}
}
- gClipboard.copyFromString(utf8str_to_wstring(text));
+ LLClipboard::instance().copyToClipboard(utf8str_to_wstring(text),0,text.size());
}
// EOF
diff --git a/indra/newview/llsidepanelinventory.cpp b/indra/newview/llsidepanelinventory.cpp
index c8b67cc9ec..4f9ab318a5 100644
--- a/indra/newview/llsidepanelinventory.cpp
+++ b/indra/newview/llsidepanelinventory.cpp
@@ -78,7 +78,6 @@ static const char * const MARKETPLACE_INBOX_PANEL = "marketplace_inbox";
//
// Helpers
//
-
class LLInboxAddedObserver : public LLInventoryCategoryAddedObserver
{
public:
@@ -130,6 +129,11 @@ LLSidepanelInventory::LLSidepanelInventory()
LLSidepanelInventory::~LLSidepanelInventory()
{
+ LLLayoutPanel* inbox_layout_panel = getChild<LLLayoutPanel>(INBOX_LAYOUT_PANEL_NAME);
+
+ // Save the InventoryMainPanelHeight in settings per account
+ gSavedPerAccountSettings.setS32("InventoryInboxHeight", inbox_layout_panel->getTargetDim());
+
if (mCategoriesObserver && gInventory.containsObserver(mCategoriesObserver))
{
gInventory.removeObserver(mCategoriesObserver);
@@ -226,7 +230,12 @@ BOOL LLSidepanelInventory::postBuild()
bool is_inbox_collapsed = !inbox_button->getToggleState();
// Restore the collapsed inbox panel state
- inv_stack->collapsePanel(getChild<LLLayoutPanel>(INBOX_LAYOUT_PANEL_NAME), is_inbox_collapsed);
+ LLLayoutPanel* inbox_panel = getChild<LLLayoutPanel>(INBOX_LAYOUT_PANEL_NAME);
+ inv_stack->collapsePanel(inbox_panel, is_inbox_collapsed);
+ if (!is_inbox_collapsed)
+ {
+ inbox_panel->setTargetDim(gSavedPerAccountSettings.getS32("InventoryInboxHeight"));
+ }
// Set the inbox visible based on debug settings (final setting comes from http request below)
enableInbox(gSavedSettings.getBOOL("InventoryDisplayInbox"));
@@ -370,10 +379,19 @@ void LLSidepanelInventory::onToggleInboxBtn()
// Expand/collapse the indicated panel
inv_stack->collapsePanel(inboxPanel, !inbox_expanded);
- if (inbox_expanded && inboxPanel->isInVisibleChain())
+ if (inbox_expanded)
{
- gSavedPerAccountSettings.setU32("LastInventoryInboxActivity", time_corrected());
+ inboxPanel->setTargetDim(gSavedPerAccountSettings.getS32("InventoryInboxHeight"));
+ if (inboxPanel->isInVisibleChain())
+ {
+ gSavedPerAccountSettings.setU32("LastInventoryInboxActivity", time_corrected());
+ }
}
+ else
+ {
+ gSavedPerAccountSettings.setS32("InventoryInboxHeight", inboxPanel->getTargetDim());
+ }
+
}
void LLSidepanelInventory::onOpen(const LLSD& key)
diff --git a/indra/newview/lltoolbarview.cpp b/indra/newview/lltoolbarview.cpp
index eccb2cf2f1..81ad96f39e 100644
--- a/indra/newview/lltoolbarview.cpp
+++ b/indra/newview/lltoolbarview.cpp
@@ -75,6 +75,7 @@ LLToolBarView::LLToolBarView(const LLToolBarView::Params& p)
mDragStarted(false),
mShowToolbars(true),
mDragToolbarButton(NULL),
+ mDragItem(NULL),
mToolbarsLoaded(false)
{
for (S32 i = 0; i < TOOLBAR_COUNT; i++)
@@ -579,7 +580,6 @@ BOOL LLToolBarView::handleDragTool( S32 x, S32 y, const LLUUID& uuid, LLAssetTyp
uuid_vec_t cargo_ids;
types.push_back(DAD_WIDGET);
cargo_ids.push_back(uuid);
- gClipboard.setSourceObject(uuid,LLAssetType::AT_WIDGET);
LLToolDragAndDrop::ESource src = LLToolDragAndDrop::SOURCE_VIEWER;
LLUUID srcID;
LLToolDragAndDrop::getInstance()->beginMultiDrag(types, cargo_ids, src, srcID);
@@ -662,6 +662,18 @@ void LLToolBarView::resetDragTool(LLToolBarButton* toolbarButton)
gToolBarView->mDragToolbarButton = toolbarButton;
}
+// Provide a handle on a free standing inventory item containing references to the tool.
+// This might be used by Drag and Drop to move around references to tool items.
+LLInventoryObject* LLToolBarView::getDragItem()
+{
+ if (mDragToolbarButton)
+ {
+ LLUUID item_uuid = mDragToolbarButton->getCommandId().uuid();
+ mDragItem = new LLInventoryObject (item_uuid, LLUUID::null, LLAssetType::AT_WIDGET, "");
+ }
+ return mDragItem;
+}
+
void LLToolBarView::setToolBarsVisible(bool visible)
{
mShowToolbars = visible;
diff --git a/indra/newview/lltoolbarview.h b/indra/newview/lltoolbarview.h
index be66bcae36..9c4194ebed 100644
--- a/indra/newview/lltoolbarview.h
+++ b/indra/newview/lltoolbarview.h
@@ -31,6 +31,7 @@
#include "lluictrl.h"
#include "lltoolbar.h"
#include "llcommandmanager.h"
+#include "llinventory.h"
class LLUICtrlFactory;
@@ -106,6 +107,7 @@ public:
static BOOL handleDragTool(S32 x, S32 y, const LLUUID& uuid, LLAssetType::EType type);
static BOOL handleDropTool(void* cargo_data, S32 x, S32 y, LLToolBar* toolbar);
static void resetDragTool(LLToolBarButton* toolbarButton);
+ LLInventoryObject* getDragItem();
bool isModified() const;
@@ -129,6 +131,7 @@ private:
bool mDragStarted;
LLToolBarButton* mDragToolbarButton;
+ LLInventoryObject* mDragItem;
bool mShowToolbars;
};
diff --git a/indra/newview/lltooldraganddrop.cpp b/indra/newview/lltooldraganddrop.cpp
index c7ab934f9e..4f4eef0f3d 100644
--- a/indra/newview/lltooldraganddrop.cpp
+++ b/indra/newview/lltooldraganddrop.cpp
@@ -48,6 +48,7 @@
#include "llpreviewnotecard.h"
#include "llrootview.h"
#include "llselectmgr.h"
+#include "lltoolbarview.h"
#include "lltoolmgr.h"
#include "lltooltip.h"
#include "lltrans.h"
@@ -2528,7 +2529,7 @@ LLInventoryObject* LLToolDragAndDrop::locateInventory(
}
else if(mSource == SOURCE_VIEWER)
{
- item = (LLViewerInventoryItem*)gClipboard.getSourceObject();
+ item = (LLViewerInventoryItem*)gToolBarView->getDragItem();
}
if(item) return item;
if(cat) return cat;
diff --git a/indra/newview/llurllineeditorctrl.cpp b/indra/newview/llurllineeditorctrl.cpp
index 56b5bbf942..cad5769042 100644
--- a/indra/newview/llurllineeditorctrl.cpp
+++ b/indra/newview/llurllineeditorctrl.cpp
@@ -89,5 +89,5 @@ void LLURLLineEditor::copyEscapedURLToClipboard()
else // human-readable location
text_to_copy = utf8str_to_wstring(unescaped_text);
- gClipboard.copyFromString( text_to_copy );
+ LLClipboard::instance().copyToClipboard(text_to_copy, 0, text_to_copy.size());
}
diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp
index 12aed8f448..37cf916423 100644
--- a/indra/newview/llviewermenu.cpp
+++ b/indra/newview/llviewermenu.cpp
@@ -25,6 +25,11 @@
*/
#include "llviewerprecompiledheaders.h"
+
+#ifdef INCLUDE_VLD
+#include "vld.h"
+#endif
+
#include "llviewermenu.h"
// linden library includes
@@ -214,7 +219,7 @@ void near_sit_down_point(BOOL success, void *);
void velocity_interpolate( void* );
-
+void handle_visual_leak_detector_toggle(void*);
void handle_rebake_textures(void*);
BOOL check_admin_override(void*);
void handle_admin_override_toggle(void*);
@@ -2018,6 +2023,15 @@ class LLAdvancedToggleViewAdminOptions : public view_listener_t
}
};
+class LLAdvancedToggleVisualLeakDetector : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ handle_visual_leak_detector_toggle(NULL);
+ return true;
+ }
+};
+
class LLAdvancedCheckViewAdminOptions : public view_listener_t
{
bool handleEvent(const LLSD& userdata)
@@ -3444,6 +3458,35 @@ void handle_admin_override_toggle(void*)
show_debug_menus();
}
+void handle_visual_leak_detector_toggle(void*)
+{
+ static bool vld_enabled = false;
+
+ if ( vld_enabled )
+ {
+#ifdef INCLUDE_VLD
+ // only works for debug builds (hard coded into vld.h)
+#ifdef _DEBUG
+ // start with Visual Leak Detector turned off
+ VLDDisable();
+#endif // _DEBUG
+#endif // INCLUDE_VLD
+ vld_enabled = false;
+ }
+ else
+ {
+#ifdef INCLUDE_VLD
+ // only works for debug builds (hard coded into vld.h)
+ #ifdef _DEBUG
+ // start with Visual Leak Detector turned off
+ VLDEnable();
+ #endif // _DEBUG
+#endif // INCLUDE_VLD
+
+ vld_enabled = true;
+ };
+}
+
void handle_god_mode(void*)
{
gAgent.requestEnterGodMode();
@@ -8237,6 +8280,8 @@ void initialize_menus()
view_listener_t::addMenu(new LLAdvancedEnableViewAdminOptions(), "Advanced.EnableViewAdminOptions");
view_listener_t::addMenu(new LLAdvancedToggleViewAdminOptions(), "Advanced.ToggleViewAdminOptions");
view_listener_t::addMenu(new LLAdvancedCheckViewAdminOptions(), "Advanced.CheckViewAdminOptions");
+ view_listener_t::addMenu(new LLAdvancedToggleVisualLeakDetector(), "Advanced.ToggleVisualLeakDetector");
+
view_listener_t::addMenu(new LLAdvancedRequestAdminStatus(), "Advanced.RequestAdminStatus");
view_listener_t::addMenu(new LLAdvancedLeaveAdminStatus(), "Advanced.LeaveAdminStatus");
diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp
index 2917fee62e..b7319fcef0 100755
--- a/indra/newview/llviewermessage.cpp
+++ b/indra/newview/llviewermessage.cpp
@@ -6845,12 +6845,14 @@ void process_covenant_reply(LLMessageSystem* msg, void**)
LLPanelEstateCovenant::updateEstateName(estate_name);
LLPanelLandCovenant::updateEstateName(estate_name);
+ LLPanelEstateInfo::updateEstateName(estate_name);
LLFloaterBuyLand::updateEstateName(estate_name);
std::string owner_name =
LLSLURL("agent", estate_owner_id, "inspect").getSLURLString();
LLPanelEstateCovenant::updateEstateOwnerName(owner_name);
LLPanelLandCovenant::updateEstateOwnerName(owner_name);
+ LLPanelEstateInfo::updateEstateOwnerName(owner_name);
LLFloaterBuyLand::updateEstateOwnerName(owner_name);
LLPanelPlaceProfile* panel = LLFloaterSidePanelContainer::getPanel<LLPanelPlaceProfile>("places", "panel_place_profile");
diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index 589714c25c..ecd76f5495 100755
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -610,7 +610,7 @@ public:
addText(xpos, ypos, llformat("%d/%d Mesh HTTP Requests/Retries", LLMeshRepository::sHTTPRequestCount,
LLMeshRepository::sHTTPRetryCount));
ypos += y_inc;
-
+
addText(xpos, ypos, llformat("%d/%d Mesh LOD Pending/Processing", LLMeshRepository::sLODPending, LLMeshRepository::sLODProcessing));
ypos += y_inc;
@@ -1969,12 +1969,12 @@ void LLViewerWindow::shutdownViews()
gMorphView->setVisible(FALSE);
}
llinfos << "Global views cleaned." << llendl ;
-
+
// DEV-40930: Clear sModalStack. Otherwise, any LLModalDialog left open
// will crump with LL_ERRS.
LLModalDialog::shutdownModals();
llinfos << "LLModalDialog shut down." << llendl;
-
+
// destroy the nav bar, not currently part of gViewerWindow
// *TODO: Make LLNavigationBar part of gViewerWindow
if (LLNavigationBar::instanceExists())
@@ -1982,17 +1982,17 @@ void LLViewerWindow::shutdownViews()
delete LLNavigationBar::getInstance();
}
llinfos << "LLNavigationBar destroyed." << llendl ;
-
+
// destroy menus after instantiating navbar above, as it needs
// access to gMenuHolder
cleanup_menus();
llinfos << "menus destroyed." << llendl ;
-
+
// Delete all child views.
delete mRootView;
mRootView = NULL;
llinfos << "RootView deleted." << llendl ;
-
+
// Automatically deleted as children of mRootView. Fix the globals.
gStatusBar = NULL;
gIMMgr = NULL;
@@ -2161,13 +2161,19 @@ void LLViewerWindow::reshape(S32 width, S32 height)
// tell the OS specific window code about min window size
mWindow->setMinSize(min_window_width, min_window_height);
+ LLCoordScreen window_rect;
+ if (mWindow->getSize(&window_rect))
+ {
// Only save size if not maximized
- gSavedSettings.setU32("WindowWidth", mWindowRectRaw.getWidth());
- gSavedSettings.setU32("WindowHeight", mWindowRectRaw.getHeight());
+ gSavedSettings.setU32("WindowWidth", window_rect.mX);
+ gSavedSettings.setU32("WindowHeight", window_rect.mY);
+ }
}
LLViewerStats::getInstance()->setStat(LLViewerStats::ST_WINDOW_WIDTH, (F64)width);
LLViewerStats::getInstance()->setStat(LLViewerStats::ST_WINDOW_HEIGHT, (F64)height);
+
+ LLLayoutStack::updateClass();
}
}
@@ -4100,7 +4106,7 @@ void LLViewerWindow::movieSize(S32 new_width, S32 new_height)
gViewerWindow->getWindow()->getSize(&size);
if ( size != new_size )
{
- gViewerWindow->getWindow()->setSize(new_size.convert());
+ gViewerWindow->getWindow()->setSize(new_size);
}
}
diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp
index bc7f5a9744..a3a40de5eb 100644
--- a/indra/newview/llvoavatar.cpp
+++ b/indra/newview/llvoavatar.cpp
@@ -149,10 +149,6 @@ const F32 PELVIS_LAG_WALKING = 0.4f; // ...while walking
const F32 PELVIS_LAG_MOUSELOOK = 0.15f;
const F32 MOUSELOOK_PELVIS_FOLLOW_FACTOR = 0.5f;
const F32 PELVIS_LAG_WHEN_FOLLOW_CAM_IS_ON = 0.0001f; // not zero! - something gets divided by this!
-
-const F32 PELVIS_ROT_THRESHOLD_SLOW = 60.0f; // amount of deviation allowed between
-const F32 PELVIS_ROT_THRESHOLD_FAST = 2.0f; // the pelvis and the view direction
- // when moving fast & slow
const F32 TORSO_NOISE_AMOUNT = 1.0f; // Amount of deviation from up-axis, in degrees
const F32 TORSO_NOISE_SPEED = 0.2f; // Time scale factor on torso noise.
@@ -3652,7 +3648,11 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent)
BOOL self_in_mouselook = isSelf() && gAgentCamera.cameraMouselook();
LLVector3 pelvisDir( mRoot.getWorldMatrix().getFwdRow4().mV );
- F32 pelvis_rot_threshold = clamp_rescale(speed, 0.1f, 1.0f, PELVIS_ROT_THRESHOLD_SLOW, PELVIS_ROT_THRESHOLD_FAST);
+
+ static LLCachedControl<F32> s_pelvis_rot_threshold_slow(gSavedSettings, "AvatarRotateThresholdSlow");
+ static LLCachedControl<F32> s_pelvis_rot_threshold_fast(gSavedSettings, "AvatarRotateThresholdFast");
+
+ F32 pelvis_rot_threshold = clamp_rescale(speed, 0.1f, 1.0f, s_pelvis_rot_threshold_slow, s_pelvis_rot_threshold_fast);
if (self_in_mouselook)
{
diff --git a/indra/newview/skins/default/xui/de/panel_status_bar.xml b/indra/newview/skins/default/xui/de/panel_status_bar.xml
index 2493d60df6..14ace0ac3a 100644
--- a/indra/newview/skins/default/xui/de/panel_status_bar.xml
+++ b/indra/newview/skins/default/xui/de/panel_status_bar.xml
@@ -15,7 +15,7 @@
<panel.string name="buycurrencylabel">
[AMT] L$
</panel.string>
- <panel name="balance_bg">
+ <panel left="-415" name="balance_bg" width="205">
<text name="balance" tool_tip="Klicken, um L$-Guthaben zu aktualisieren" value="20 L$"/>
<button label="L$ kaufen" name="buyL" tool_tip="Hier klicken, um mehr L$ zu kaufen"/>
<button label="Einkaufen" name="goShop" tool_tip="Second Life-Marktplatz öffnen" width="85"/>
diff --git a/indra/newview/skins/default/xui/en/floater_about.xml b/indra/newview/skins/default/xui/en/floater_about.xml
index c7e9ec781d..060d889003 100644
--- a/indra/newview/skins/default/xui/en/floater_about.xml
+++ b/indra/newview/skins/default/xui/en/floater_about.xml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<floater
- open_positioning="centered"
+ positioning="centered"
legacy_header_height="18"
height="440"
layout="topleft"
diff --git a/indra/newview/skins/default/xui/en/floater_about_land.xml b/indra/newview/skins/default/xui/en/floater_about_land.xml
index 3a6c2678c1..fb123ec4d1 100644
--- a/indra/newview/skins/default/xui/en/floater_about_land.xml
+++ b/indra/newview/skins/default/xui/en/floater_about_land.xml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<floater
- open_positioning="cascading"
+ positioning="cascading"
can_tear_off="false"
height="420"
layout="topleft"
diff --git a/indra/newview/skins/default/xui/en/floater_avatar.xml b/indra/newview/skins/default/xui/en/floater_avatar.xml
index 82c3403008..cd5cca02bd 100644
--- a/indra/newview/skins/default/xui/en/floater_avatar.xml
+++ b/indra/newview/skins/default/xui/en/floater_avatar.xml
@@ -1,13 +1,13 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<floater
- open_positioning="cascading"
+ positioning="cascading"
ignore_ui_scale="false"
legacy_header_height="225"
can_minimize="true"
can_close="true"
can_resize="true"
min_height="230"
- min_width="450"
+ min_width="515"
height="230"
layout="topleft"
name="Avatar"
diff --git a/indra/newview/skins/default/xui/en/floater_avatar_picker.xml b/indra/newview/skins/default/xui/en/floater_avatar_picker.xml
index cbbbeb6094..1a55dc2e2c 100644
--- a/indra/newview/skins/default/xui/en/floater_avatar_picker.xml
+++ b/indra/newview/skins/default/xui/en/floater_avatar_picker.xml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<floater
- open_positioning="cascading"
+ positioning="cascading"
legacy_header_height="18"
can_resize="true"
height="350"
diff --git a/indra/newview/skins/default/xui/en/floater_camera.xml b/indra/newview/skins/default/xui/en/floater_camera.xml
index 4673c6def5..22bc488a92 100644
--- a/indra/newview/skins/default/xui/en/floater_camera.xml
+++ b/indra/newview/skins/default/xui/en/floater_camera.xml
@@ -1,8 +1,9 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<floater
- open_positioning="specified"
- specified_left="458"
- specified_bottom="80"
+ positioning="specified"
+ left="458"
+ bottom="-80"
+ follows="left|bottom"
legacy_header_height="18"
can_minimize="true"
can_close="true"
diff --git a/indra/newview/skins/default/xui/en/floater_chat_bar.xml b/indra/newview/skins/default/xui/en/floater_chat_bar.xml
index 63992462b3..688a01ce7b 100644
--- a/indra/newview/skins/default/xui/en/floater_chat_bar.xml
+++ b/indra/newview/skins/default/xui/en/floater_chat_bar.xml
@@ -1,8 +1,8 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<floater
- open_positioning="specified"
- specified_left="10"
- specified_bottom="10"
+ positioning="specified"
+ left="10"
+ bottom="-10"
height="60"
layout="topleft"
legacy_header_height="25"
diff --git a/indra/newview/skins/default/xui/en/floater_critical.xml b/indra/newview/skins/default/xui/en/floater_critical.xml
index 13b15bf724..143bcb4430 100644
--- a/indra/newview/skins/default/xui/en/floater_critical.xml
+++ b/indra/newview/skins/default/xui/en/floater_critical.xml
@@ -6,7 +6,7 @@
height="500"
layout="topleft"
name="modal container"
- open_positioning="centered"
+ positioning="centered"
width="600">
<button
height="20"
diff --git a/indra/newview/skins/default/xui/en/floater_destinations.xml b/indra/newview/skins/default/xui/en/floater_destinations.xml
index 373114a1eb..39aa8e07bb 100644
--- a/indra/newview/skins/default/xui/en/floater_destinations.xml
+++ b/indra/newview/skins/default/xui/en/floater_destinations.xml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<floater
- open_positioning="cascading"
+ positioning="cascading"
ignore_ui_scale="false"
legacy_header_height="225"
can_minimize="true"
diff --git a/indra/newview/skins/default/xui/en/floater_gesture.xml b/indra/newview/skins/default/xui/en/floater_gesture.xml
index b96a94a849..200e9b9537 100644
--- a/indra/newview/skins/default/xui/en/floater_gesture.xml
+++ b/indra/newview/skins/default/xui/en/floater_gesture.xml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<floater
- open_positioning="cascading"
+ positioning="cascading"
save_rect="true"
legacy_header_height="18"
can_resize="true"
diff --git a/indra/newview/skins/default/xui/en/floater_help_browser.xml b/indra/newview/skins/default/xui/en/floater_help_browser.xml
index cd075abc41..c06cb63f8a 100644
--- a/indra/newview/skins/default/xui/en/floater_help_browser.xml
+++ b/indra/newview/skins/default/xui/en/floater_help_browser.xml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<floater
- open_positioning="cascading"
+ positioning="cascading"
legacy_header_height="18"
can_resize="true"
height="600"
diff --git a/indra/newview/skins/default/xui/en/floater_joystick.xml b/indra/newview/skins/default/xui/en/floater_joystick.xml
index 6e1bb8fcd0..59f6a9434c 100644
--- a/indra/newview/skins/default/xui/en/floater_joystick.xml
+++ b/indra/newview/skins/default/xui/en/floater_joystick.xml
@@ -13,6 +13,7 @@
</floater.string>
<check_box
bottom="38"
+ height="10"
control_name="JoystickEnabled"
halign="left"
label="Enable Joystick:"
@@ -28,6 +29,7 @@
width="380" />
<spinner
bottom="48"
+ height="10"
control_name="JoystickAxis1"
decimal_digits="0"
increment="1"
@@ -41,6 +43,7 @@
width="140" />
<spinner
bottom="48"
+ height="10"
control_name="JoystickAxis2"
decimal_digits="0"
increment="1"
@@ -54,6 +57,7 @@
width="140" />
<spinner
bottom="48"
+ height="10"
control_name="JoystickAxis0"
decimal_digits="0"
increment="1"
@@ -67,6 +71,7 @@
width="140" />
<spinner
bottom="68"
+ height="10"
control_name="JoystickAxis4"
decimal_digits="0"
increment="1"
@@ -80,6 +85,7 @@
width="140" />
<spinner
bottom="68"
+ height="10"
control_name="JoystickAxis5"
decimal_digits="0"
increment="1"
@@ -93,6 +99,7 @@
width="140" />
<spinner
bottom="68"
+ height="10"
control_name="JoystickAxis3"
decimal_digits="0"
increment="1"
@@ -106,6 +113,7 @@
width="140" />
<spinner
bottom="88"
+ height="10"
control_name="JoystickAxis6"
decimal_digits="0"
increment="1"
@@ -119,6 +127,7 @@
width="140" />
<check_box
bottom_delta="18"
+ height="10"
control_name="ZoomDirect"
label="Direct Zoom"
layout="topleft"
@@ -127,6 +136,7 @@
width="60" />
<check_box
bottom_delta="0"
+ height="10"
control_name="Cursor3D"
label="3D Cursor"
layout="topleft"
@@ -135,6 +145,7 @@
width="60" />
<check_box
bottom_delta="0"
+ height="10"
control_name="AutoLeveling"
label="Auto Level"
layout="topleft"
@@ -157,6 +168,7 @@
</text>
<check_box
bottom="127"
+ height="10"
control_name="JoystickAvatarEnabled"
halign="center"
label="Avatar"
@@ -166,6 +178,7 @@
width="60" />
<check_box
bottom="127"
+ height="10"
control_name="JoystickBuildEnabled"
halign="center"
label="Build"
@@ -175,6 +188,7 @@
width="60" />
<check_box
bottom="127"
+ height="10"
control_name="JoystickFlycamEnabled"
halign="center"
label="Flycam"
@@ -257,6 +271,7 @@
</text>
<spinner
bottom="144"
+ height="10"
control_name="AvatarAxisScale1"
decimal_digits="2"
label_width="0"
@@ -268,6 +283,7 @@
width="56" />
<spinner
bottom="144"
+ height="10"
control_name="BuildAxisScale1"
decimal_digits="2"
label_width="0"
@@ -279,6 +295,7 @@
width="56" />
<spinner
bottom="144"
+ height="10"
control_name="FlycamAxisScale1"
decimal_digits="2"
label_width="0"
@@ -301,6 +318,7 @@
</text>
<spinner
bottom="164"
+ height="10"
control_name="AvatarAxisScale2"
decimal_digits="2"
label_width="0"
@@ -312,6 +330,7 @@
width="56" />
<spinner
bottom="164"
+ height="10"
control_name="BuildAxisScale2"
decimal_digits="2"
label_width="0"
@@ -323,6 +342,7 @@
width="56" />
<spinner
bottom="164"
+ height="10"
control_name="FlycamAxisScale2"
decimal_digits="2"
label_width="0"
@@ -345,6 +365,7 @@
</text>
<spinner
bottom="184"
+ height="10"
control_name="AvatarAxisScale0"
decimal_digits="2"
label_width="0"
@@ -356,6 +377,7 @@
width="56" />
<spinner
bottom="184"
+ height="10"
control_name="BuildAxisScale0"
decimal_digits="2"
label_width="0"
@@ -367,6 +389,7 @@
width="56" />
<spinner
bottom="184"
+ height="10"
control_name="FlycamAxisScale0"
decimal_digits="2"
label_width="0"
@@ -389,6 +412,7 @@
</text>
<spinner
bottom="204"
+ height="10"
control_name="AvatarAxisScale4"
decimal_digits="2"
label_width="0"
@@ -400,6 +424,7 @@
width="56" />
<spinner
bottom="204"
+ height="10"
control_name="BuildAxisScale4"
decimal_digits="2"
label_width="0"
@@ -411,6 +436,7 @@
width="56" />
<spinner
bottom="204"
+ height="10"
control_name="FlycamAxisScale4"
decimal_digits="2"
label_width="0"
@@ -433,6 +459,7 @@
</text>
<spinner
bottom="224"
+ height="10"
control_name="AvatarAxisScale5"
decimal_digits="2"
label_width="0"
@@ -444,6 +471,7 @@
width="56" />
<spinner
bottom="224"
+ height="10"
control_name="BuildAxisScale5"
decimal_digits="2"
label_width="0"
@@ -455,6 +483,7 @@
width="56" />
<spinner
bottom="224"
+ height="10"
control_name="FlycamAxisScale5"
decimal_digits="2"
label_width="0"
@@ -477,6 +506,7 @@
</text>
<spinner
bottom="244"
+ height="10"
control_name="BuildAxisScale3"
decimal_digits="2"
label_width="0"
@@ -488,6 +518,7 @@
width="56" />
<spinner
bottom="244"
+ height="10"
control_name="FlycamAxisScale3"
decimal_digits="2"
label_width="0"
@@ -510,6 +541,7 @@
</text>
<spinner
bottom="274"
+ height="10"
control_name="AvatarAxisDeadZone1"
decimal_digits="2"
increment="0.01"
@@ -520,6 +552,7 @@
width="56" />
<spinner
bottom="274"
+ height="10"
control_name="BuildAxisDeadZone1"
decimal_digits="2"
increment="0.01"
@@ -530,6 +563,7 @@
width="56" />
<spinner
bottom="274"
+ height="10"
control_name="FlycamAxisDeadZone1"
decimal_digits="2"
increment="0.01"
@@ -551,6 +585,7 @@
</text>
<spinner
bottom="294"
+ height="10"
control_name="AvatarAxisDeadZone2"
decimal_digits="2"
increment="0.01"
@@ -561,6 +596,7 @@
width="56" />
<spinner
bottom="294"
+ height="10"
control_name="BuildAxisDeadZone2"
decimal_digits="2"
increment="0.01"
@@ -571,6 +607,7 @@
width="56" />
<spinner
bottom="294"
+ height="10"
control_name="FlycamAxisDeadZone2"
decimal_digits="2"
increment="0.01"
@@ -592,6 +629,7 @@
</text>
<spinner
bottom="314"
+ height="10"
control_name="AvatarAxisDeadZone0"
decimal_digits="2"
increment="0.01"
@@ -602,6 +640,7 @@
width="56" />
<spinner
bottom="314"
+ height="10"
control_name="BuildAxisDeadZone0"
decimal_digits="2"
increment="0.01"
@@ -612,6 +651,7 @@
width="56" />
<spinner
bottom="314"
+ height="10"
control_name="FlycamAxisDeadZone0"
decimal_digits="2"
increment="0.01"
@@ -633,6 +673,7 @@
</text>
<spinner
bottom="334"
+ height="10"
control_name="AvatarAxisDeadZone4"
decimal_digits="2"
increment="0.01"
@@ -643,6 +684,7 @@
width="56" />
<spinner
bottom="334"
+ height="10"
control_name="BuildAxisDeadZone4"
decimal_digits="2"
increment="0.01"
@@ -653,6 +695,7 @@
width="56" />
<spinner
bottom="334"
+ height="10"
control_name="FlycamAxisDeadZone4"
decimal_digits="2"
increment="0.01"
@@ -674,6 +717,7 @@
</text>
<spinner
bottom="354"
+ height="10"
control_name="AvatarAxisDeadZone5"
decimal_digits="2"
increment="0.01"
@@ -684,6 +728,7 @@
width="56" />
<spinner
bottom="354"
+ height="10"
control_name="BuildAxisDeadZone5"
decimal_digits="2"
increment="0.01"
@@ -694,6 +739,7 @@
width="56" />
<spinner
bottom="354"
+ height="10"
control_name="FlycamAxisDeadZone5"
decimal_digits="2"
increment="0.01"
@@ -715,6 +761,7 @@
</text>
<spinner
bottom="374"
+ height="10"
control_name="BuildAxisDeadZone3"
decimal_digits="2"
increment="0.01"
@@ -725,6 +772,7 @@
width="56" />
<spinner
bottom="374"
+ height="10"
control_name="FlycamAxisDeadZone3"
decimal_digits="2"
increment="0.01"
@@ -802,6 +850,7 @@
</text>
<spinner
bottom="430"
+ height="10"
control_name="FlycamAxisScale6"
decimal_digits="2"
label_width="0"
@@ -824,6 +873,7 @@
</text>
<spinner
bottom="450"
+ height="10"
control_name="FlycamAxisDeadZone6"
decimal_digits="2"
increment="0.01"
diff --git a/indra/newview/skins/default/xui/en/floater_land_holdings.xml b/indra/newview/skins/default/xui/en/floater_land_holdings.xml
index 3737294ebe..390ec9ab7d 100644
--- a/indra/newview/skins/default/xui/en/floater_land_holdings.xml
+++ b/indra/newview/skins/default/xui/en/floater_land_holdings.xml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<floater
- open_positioning="centered"
+ positioning="centered"
legacy_header_height="18"
height="430"
layout="topleft"
diff --git a/indra/newview/skins/default/xui/en/floater_map.xml b/indra/newview/skins/default/xui/en/floater_map.xml
index 3eeebcf120..b8893e11d9 100644
--- a/indra/newview/skins/default/xui/en/floater_map.xml
+++ b/indra/newview/skins/default/xui/en/floater_map.xml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<floater
- open_positioning="cascading"
+ positioning="cascading"
can_minimize="true"
can_resize="true"
chrome="true"
diff --git a/indra/newview/skins/default/xui/en/floater_merchant_outbox.xml b/indra/newview/skins/default/xui/en/floater_merchant_outbox.xml
index 3d33d19de5..72d2281435 100644
--- a/indra/newview/skins/default/xui/en/floater_merchant_outbox.xml
+++ b/indra/newview/skins/default/xui/en/floater_merchant_outbox.xml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<floater
- open_positioning="cascading"
+ positioning="cascading"
can_close="true"
can_resize="true"
height="440"
@@ -115,7 +115,7 @@
wrap="true"
halign="left"
valign="center"
- font="SansSerif"/>
+ font="SansSerif" />
<button
label="Send to Marketplace"
tool_tip="Push to my Marketplace Storefront"
diff --git a/indra/newview/skins/default/xui/en/floater_moveview.xml b/indra/newview/skins/default/xui/en/floater_moveview.xml
index 065dab0413..4e7ee7913f 100644
--- a/indra/newview/skins/default/xui/en/floater_moveview.xml
+++ b/indra/newview/skins/default/xui/en/floater_moveview.xml
@@ -1,8 +1,8 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<floater
- open_positioning="specified"
- specified_left="320"
- specified_bottom="80"
+ positioning="specified"
+ left="320"
+ bottom="-80"
legacy_header_height="18"
can_dock="false"
can_minimize="true"
diff --git a/indra/newview/skins/default/xui/en/floater_my_appearance.xml b/indra/newview/skins/default/xui/en/floater_my_appearance.xml
index 1c4b25a7b0..fdea7a821a 100644
--- a/indra/newview/skins/default/xui/en/floater_my_appearance.xml
+++ b/indra/newview/skins/default/xui/en/floater_my_appearance.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<floater
- open_positioning="cascading"
+ positioning="cascading"
legacy_header_height="18"
can_resize="true"
height="588"
diff --git a/indra/newview/skins/default/xui/en/floater_my_inventory.xml b/indra/newview/skins/default/xui/en/floater_my_inventory.xml
index cd0b59dc51..184f296255 100644
--- a/indra/newview/skins/default/xui/en/floater_my_inventory.xml
+++ b/indra/newview/skins/default/xui/en/floater_my_inventory.xml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<floater
- open_positioning="cascading"
+ positioning="cascading"
can_close="true"
can_resize="true"
height="570"
diff --git a/indra/newview/skins/default/xui/en/floater_people.xml b/indra/newview/skins/default/xui/en/floater_people.xml
index d6d8431150..08d0b00a83 100644
--- a/indra/newview/skins/default/xui/en/floater_people.xml
+++ b/indra/newview/skins/default/xui/en/floater_people.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<floater
- open_positioning="cascading"
+ positioning="cascading"
can_close="true"
can_resize="true"
height="570"
diff --git a/indra/newview/skins/default/xui/en/floater_picks.xml b/indra/newview/skins/default/xui/en/floater_picks.xml
index 7882116662..984894b016 100644
--- a/indra/newview/skins/default/xui/en/floater_picks.xml
+++ b/indra/newview/skins/default/xui/en/floater_picks.xml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<floater
- open_positioning="cascading"
+ positioning="cascading"
can_close="true"
can_resize="true"
height="572"
diff --git a/indra/newview/skins/default/xui/en/floater_places.xml b/indra/newview/skins/default/xui/en/floater_places.xml
index ccceac0a7b..b241e265a9 100644
--- a/indra/newview/skins/default/xui/en/floater_places.xml
+++ b/indra/newview/skins/default/xui/en/floater_places.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<floater
- open_positioning="cascading"
+ positioning="cascading"
legacy_header_height="18"
can_resize="true"
height="588"
diff --git a/indra/newview/skins/default/xui/en/floater_preferences.xml b/indra/newview/skins/default/xui/en/floater_preferences.xml
index b2662331b0..bd6faf4ed8 100644
--- a/indra/newview/skins/default/xui/en/floater_preferences.xml
+++ b/indra/newview/skins/default/xui/en/floater_preferences.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<floater
legacy_header_height="18"
- open_positioning="centered"
+ positioning="centered"
default_tab_group="1"
height="460"
layout="topleft"
diff --git a/indra/newview/skins/default/xui/en/floater_search.xml b/indra/newview/skins/default/xui/en/floater_search.xml
index dd818e2e06..c3e7028dc5 100644
--- a/indra/newview/skins/default/xui/en/floater_search.xml
+++ b/indra/newview/skins/default/xui/en/floater_search.xml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<floater
- open_positioning="cascading"
+ positioning="cascading"
legacy_header_height="18"
can_resize="true"
height="775"
diff --git a/indra/newview/skins/default/xui/en/floater_snapshot.xml b/indra/newview/skins/default/xui/en/floater_snapshot.xml
index 0c38283d59..49d64767cc 100644
--- a/indra/newview/skins/default/xui/en/floater_snapshot.xml
+++ b/indra/newview/skins/default/xui/en/floater_snapshot.xml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<floater
- open_positioning="cascading"
+ positioning="cascading"
legacy_header_height="18"
can_minimize="true"
can_close="true"
diff --git a/indra/newview/skins/default/xui/en/floater_test_text_editor.xml b/indra/newview/skins/default/xui/en/floater_test_text_editor.xml
index 548e24efba..e1fefc3631 100644
--- a/indra/newview/skins/default/xui/en/floater_test_text_editor.xml
+++ b/indra/newview/skins/default/xui/en/floater_test_text_editor.xml
@@ -3,6 +3,7 @@
legacy_header_height="18"
can_resize="true"
height="600"
+ single_instance="false"
layout="topleft"
name="floater_test_text_editor"
translate="false"
diff --git a/indra/newview/skins/default/xui/en/floater_test_widgets.xml b/indra/newview/skins/default/xui/en/floater_test_widgets.xml
index 13c850c86c..10854f5a49 100644
--- a/indra/newview/skins/default/xui/en/floater_test_widgets.xml
+++ b/indra/newview/skins/default/xui/en/floater_test_widgets.xml
@@ -115,6 +115,7 @@
</flyout_button>
<check_box
bottom_delta="35"
+ height="10"
label="Checkbox"
layout="topleft"
tool_tip="checkbox"
@@ -275,6 +276,7 @@
<!-- "spinner" is a numerical input widget with an up and down arrow to
change the value. -->
<spinner
+ height="10"
bottom_delta="35"
follows="top|left"
label="Spinner"
diff --git a/indra/newview/skins/default/xui/en/floater_tools.xml b/indra/newview/skins/default/xui/en/floater_tools.xml
index 2d63c94fe1..e37740d20c 100644
--- a/indra/newview/skins/default/xui/en/floater_tools.xml
+++ b/indra/newview/skins/default/xui/en/floater_tools.xml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<floater
- open_positioning="cascading"
+ positioning="cascading"
legacy_header_height="18"
height="580"
layout="topleft"
@@ -1206,6 +1206,7 @@ even though the user gets a free copy.
label="Modify"
layout="topleft"
left="10"
+ height="10"
name="checkbox next owner can modify"
width="85" />
<check_box
diff --git a/indra/newview/skins/default/xui/en/floater_toybox.xml b/indra/newview/skins/default/xui/en/floater_toybox.xml
index fcaae9d172..d8211c24a7 100644
--- a/indra/newview/skins/default/xui/en/floater_toybox.xml
+++ b/indra/newview/skins/default/xui/en/floater_toybox.xml
@@ -10,7 +10,7 @@
layout="topleft"
legacy_header_height="18"
name="Toybox"
- open_positioning="centered"
+ positioning="centered"
save_rect="true"
single_instance="true"
title="TOOLBAR BUTTONS"
diff --git a/indra/newview/skins/default/xui/en/floater_voice_controls.xml b/indra/newview/skins/default/xui/en/floater_voice_controls.xml
index d99b29f324..dce2720cf8 100644
--- a/indra/newview/skins/default/xui/en/floater_voice_controls.xml
+++ b/indra/newview/skins/default/xui/en/floater_voice_controls.xml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<floater
- open_positioning="cascading"
+ positioning="cascading"
can_resize="true"
can_minimize="true"
can_close="true"
diff --git a/indra/newview/skins/default/xui/en/floater_voice_effect.xml b/indra/newview/skins/default/xui/en/floater_voice_effect.xml
index 77fb21e27c..35cb2670d0 100644
--- a/indra/newview/skins/default/xui/en/floater_voice_effect.xml
+++ b/indra/newview/skins/default/xui/en/floater_voice_effect.xml
@@ -36,15 +36,20 @@
<string name="effect_Cyber">Cyber</string>
<string name="effect_DeepBot">DeepBot</string>
<string name="effect_Demon">Demon</string>
+ <string name="effect_Female Elf">Female Elf</string>
<string name="effect_Flirty">Flirty</string>
<string name="effect_Foxy">Foxy</string>
- <string name="effect_Halloween_2010_Bonus">Halloween_2010_Bonus</string>
+ <string name="effect_Halloween 2010 Bonus">Halloween_2010_Bonus</string>
<string name="effect_Helium">Helium</string>
<string name="effect_Husky">Husky</string>
+ <string name="effect_Husky Whisper">Husky Whisper</string>
<string name="effect_Intercom">Intercom</string>
+ <string name="effect_Julia">Julia</string>
+ <string name="effect_Lo Lilt">Lo Lilt</string>
<string name="effect_Macho">Macho</string>
<string name="effect_Micro">Micro</string>
<string name="effect_Mini">Mini</string>
+ <string name="effect_Model">Model</string>
<string name="effect_Nano">Nano</string>
<string name="effect_Nightmare">Nightmare</string>
<string name="effect_PopBot">PopBot</string>
@@ -52,10 +57,12 @@
<string name="effect_Radio">Radio</string>
<string name="effect_Robot">Robot</string>
<string name="effect_Roxanne">Roxanne</string>
+ <string name="effect_Rumble">Rumble</string>
<string name="effect_Sabrina">Sabrina</string>
<string name="effect_Samantha">Samantha</string>
<string name="effect_Sexy">Sexy</string>
<string name="effect_Shorty">Shorty</string>
+ <string name="effect_Smaller">Smaller</string>
<string name="effect_Sneaky">Sneaky</string>
<string name="effect_Stallion">Stallion</string>
<string name="effect_Sultry">Sultry</string>
diff --git a/indra/newview/skins/default/xui/en/floater_world_map.xml b/indra/newview/skins/default/xui/en/floater_world_map.xml
index 56d79f62c7..83407069d2 100644
--- a/indra/newview/skins/default/xui/en/floater_world_map.xml
+++ b/indra/newview/skins/default/xui/en/floater_world_map.xml
@@ -2,7 +2,7 @@
<floater
legacy_header_height="18"
can_resize="true"
- open_positioning="centered"
+ positioning="centered"
height="600"
layout="topleft"
min_height="520"
diff --git a/indra/newview/skins/default/xui/en/menu_inventory.xml b/indra/newview/skins/default/xui/en/menu_inventory.xml
index ef4a1bc061..b13bf5b508 100644
--- a/indra/newview/skins/default/xui/en/menu_inventory.xml
+++ b/indra/newview/skins/default/xui/en/menu_inventory.xml
@@ -453,6 +453,14 @@
layout="topleft"
name="Copy Separator" />
<menu_item_call
+ label="Cut"
+ layout="topleft"
+ name="Cut">
+ <menu_item_call.on_click
+ function="Inventory.DoToSelected"
+ parameter="cut" />
+ </menu_item_call>
+ <menu_item_call
label="Copy"
layout="topleft"
name="Copy">
diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml
index 1d11abcf73..5ba566b175 100644
--- a/indra/newview/skins/default/xui/en/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/en/menu_viewer.xml
@@ -3268,6 +3268,14 @@
<menu_item_call.on_click
function="Advanced.CompressImage" />
</menu_item_call>
+
+ <menu_item_call
+ label="Enable Visual Leak Detector"
+ name="Enable Visual Leak Detector">
+ <menu_item_call.on_click
+ function="Advanced.ToggleVisualLeakDetector" />
+ </menu_item_call>
+
<menu_item_check
label="Output Debug Minidump"
name="Output Debug Minidump">
@@ -3294,6 +3302,7 @@
name="Set Logging Level"
tear_off="true">
<menu_item_check
+ name="Debug"
label="Debug">
<menu_item_check.on_check
function="Develop.CheckLoggingLevel"
@@ -3303,6 +3312,7 @@
parameter="0" />
</menu_item_check>
<menu_item_check
+ name="Info"
label="Info">
<menu_item_check.on_check
function="Develop.CheckLoggingLevel"
@@ -3312,6 +3322,7 @@
parameter="1" />
</menu_item_check>
<menu_item_check
+ name="Warning"
label="Warning">
<menu_item_check.on_check
function="Develop.CheckLoggingLevel"
@@ -3321,6 +3332,7 @@
parameter="2" />
</menu_item_check>
<menu_item_check
+ name="Error"
label="Error">
<menu_item_check.on_check
function="Develop.CheckLoggingLevel"
@@ -3330,6 +3342,7 @@
parameter="3" />
</menu_item_check>
<menu_item_check
+ name="None"
label="None">
<menu_item_check.on_check
function="Develop.CheckLoggingLevel"
diff --git a/indra/newview/skins/default/xui/en/panel_chat_item.xml b/indra/newview/skins/default/xui/en/panel_chat_item.xml
index 1b97de2b05..1ef99649e6 100644
--- a/indra/newview/skins/default/xui/en/panel_chat_item.xml
+++ b/indra/newview/skins/default/xui/en/panel_chat_item.xml
@@ -18,6 +18,7 @@
<text_chat
top="3"
left="30"
+ right="-10"
height="120"
text_color="white"
word_wrap="true"
diff --git a/indra/newview/skins/default/xui/en/panel_postcard_settings.xml b/indra/newview/skins/default/xui/en/panel_postcard_settings.xml
index e9427a2388..3f67a48b14 100644
--- a/indra/newview/skins/default/xui/en/panel_postcard_settings.xml
+++ b/indra/newview/skins/default/xui/en/panel_postcard_settings.xml
@@ -85,6 +85,7 @@
top_delta="0"
width="95" />
<check_box
+ height="10"
bottom_delta="20"
follows="left|top"
label="Constrain proportions"
diff --git a/indra/newview/skins/default/xui/en/panel_snapshot_inventory.xml b/indra/newview/skins/default/xui/en/panel_snapshot_inventory.xml
index 9057ebb65e..71d808fa4b 100644
--- a/indra/newview/skins/default/xui/en/panel_snapshot_inventory.xml
+++ b/indra/newview/skins/default/xui/en/panel_snapshot_inventory.xml
@@ -114,6 +114,7 @@
width="95" />
<check_box
bottom_delta="20"
+ height="10"
follows="left|top"
label="Constrain proportions"
layout="topleft"
diff --git a/indra/newview/skins/default/xui/en/panel_snapshot_local.xml b/indra/newview/skins/default/xui/en/panel_snapshot_local.xml
index b966358f18..781ab17403 100644
--- a/indra/newview/skins/default/xui/en/panel_snapshot_local.xml
+++ b/indra/newview/skins/default/xui/en/panel_snapshot_local.xml
@@ -132,6 +132,7 @@
width="95" />
<check_box
bottom_delta="20"
+ height="10"
follows="left|top"
label="Constrain proportions"
layout="topleft"
diff --git a/indra/newview/skins/default/xui/en/panel_snapshot_profile.xml b/indra/newview/skins/default/xui/en/panel_snapshot_profile.xml
index 5bd383b81e..0dd357aa1a 100644
--- a/indra/newview/skins/default/xui/en/panel_snapshot_profile.xml
+++ b/indra/newview/skins/default/xui/en/panel_snapshot_profile.xml
@@ -119,6 +119,7 @@
top_delta="0"
width="95" />
<check_box
+ height="10"
bottom_delta="20"
label="Constrain proportions"
layout="topleft"
diff --git a/indra/newview/skins/default/xui/en/panel_status_bar.xml b/indra/newview/skins/default/xui/en/panel_status_bar.xml
index 22c1139cdb..3aa34439f1 100644
--- a/indra/newview/skins/default/xui/en/panel_status_bar.xml
+++ b/indra/newview/skins/default/xui/en/panel_status_bar.xml
@@ -35,8 +35,8 @@
</panel.string>
<panel
height="18"
- left="-370"
- width="160"
+ left="-395"
+ width="185"
top="1"
follows="right|top"
name="balance_bg">
diff --git a/indra/newview/skins/default/xui/en/panel_toast.xml b/indra/newview/skins/default/xui/en/panel_toast.xml
index 0b5aff54ca..37a904bca8 100644
--- a/indra/newview/skins/default/xui/en/panel_toast.xml
+++ b/indra/newview/skins/default/xui/en/panel_toast.xml
@@ -10,7 +10,6 @@
-->
<floater
- open_positioning="none"
legacy_header_height="0"
header_height="0"
name="toast"
diff --git a/indra/newview/skins/default/xui/en/sidepanel_inventory.xml b/indra/newview/skins/default/xui/en/sidepanel_inventory.xml
index ee790e8dd4..6ecb57b41d 100644
--- a/indra/newview/skins/default/xui/en/sidepanel_inventory.xml
+++ b/indra/newview/skins/default/xui/en/sidepanel_inventory.xml
@@ -48,10 +48,10 @@
height="300"
width="330" />
</layout_panel>
- <layout_panel
+ <layout_panel
width="330"
layout="topleft"
- auto_resize="true"
+ auto_resize="false"
user_resize="true"
follows="left|right|top"
name="inbox_layout_panel"
@@ -105,6 +105,7 @@
[NUM] new
</text>
<panel
+ name="inbox_inventory_placeholder_panel"
follows="all"
left="10"
bottom="235"
diff --git a/indra/newview/skins/default/xui/en/widgets/floater.xml b/indra/newview/skins/default/xui/en/widgets/floater.xml
index adbb183317..97a5ae7d4e 100644
--- a/indra/newview/skins/default/xui/en/widgets/floater.xml
+++ b/indra/newview/skins/default/xui/en/widgets/floater.xml
@@ -2,7 +2,7 @@
<!-- See also settings.xml UIFloater* settings for configuration -->
<floater
name="floater"
- open_positioning="none"
+ positioning="none"
layout="topleft"
bg_opaque_color="FloaterFocusBackgroundColor"
bg_alpha_color="FloaterDefaultBackgroundColor"
diff --git a/indra/newview/skins/default/xui/es/panel_status_bar.xml b/indra/newview/skins/default/xui/es/panel_status_bar.xml
index 79b2c32b23..7eead3bc18 100644
--- a/indra/newview/skins/default/xui/es/panel_status_bar.xml
+++ b/indra/newview/skins/default/xui/es/panel_status_bar.xml
@@ -15,7 +15,7 @@
<panel.string name="buycurrencylabel">
[AMT] L$
</panel.string>
- <panel name="balance_bg">
+ <panel left="-410" name="balance_bg" width="200">
<text name="balance" tool_tip="Haz clic para actualizar tu saldo en L$" value="20 L$"/>
<button label="Comprar L$" name="buyL" tool_tip="Pulsa para comprar más L$"/>
<button label="Comprar" name="goShop" tool_tip="Abrir el mercado de Second Life" width="80"/>
diff --git a/indra/newview/skins/default/xui/fr/panel_status_bar.xml b/indra/newview/skins/default/xui/fr/panel_status_bar.xml
index c0d59a3182..ba36a7d299 100644
--- a/indra/newview/skins/default/xui/fr/panel_status_bar.xml
+++ b/indra/newview/skins/default/xui/fr/panel_status_bar.xml
@@ -15,7 +15,7 @@
<panel.string name="buycurrencylabel">
[AMT] L$
</panel.string>
- <panel name="balance_bg">
+ <panel left="-405" name="balance_bg" width="195">
<text name="balance" tool_tip="Cliquer sur ce bouton pour actualiser votre solde en L$." value="20 L$"/>
<button label="Acheter L$" name="buyL" tool_tip="Cliquer pour acheter plus de L$."/>
<button label="Achats" name="goShop" tool_tip="Ouvrir la Place du marché Second Life." width="75"/>
diff --git a/indra/newview/skins/default/xui/it/panel_status_bar.xml b/indra/newview/skins/default/xui/it/panel_status_bar.xml
index 4abc90113f..0aaf89d8c8 100644
--- a/indra/newview/skins/default/xui/it/panel_status_bar.xml
+++ b/indra/newview/skins/default/xui/it/panel_status_bar.xml
@@ -15,7 +15,7 @@
<panel.string name="buycurrencylabel">
L$ [AMT]
</panel.string>
- <panel name="balance_bg">
+ <panel left="-405" name="balance_bg" width="195">
<text name="balance" tool_tip="Clicca per aggiornare il tuo saldo in L$" value="L$ 20"/>
<button label="Acquista L$" name="buyL" tool_tip="Clicca per acquistare più L$"/>
<button label="Acquisti" name="goShop" tool_tip="Apri Mercato Second Life" width="75"/>
diff --git a/indra/newview/skins/default/xui/ja/panel_status_bar.xml b/indra/newview/skins/default/xui/ja/panel_status_bar.xml
index 4fb876f690..f09643d562 100644
--- a/indra/newview/skins/default/xui/ja/panel_status_bar.xml
+++ b/indra/newview/skins/default/xui/ja/panel_status_bar.xml
@@ -15,7 +15,7 @@
<panel.string name="buycurrencylabel">
L$ [AMT]
</panel.string>
- <panel name="balance_bg">
+ <panel left="-370" name="balance_bg" width="160">
<text name="balance" tool_tip="クリックして L$ 残高を更新" value="L$20"/>
<button label="L$ の購入" name="buyL" tool_tip="クリックして L$ を購入します"/>
<button label="店" name="goShop" tool_tip="Second Life マーケットプレイスを開く" width="40"/>
diff --git a/indra/newview/skins/default/xui/pt/panel_status_bar.xml b/indra/newview/skins/default/xui/pt/panel_status_bar.xml
index 22853f0643..cb9a6eb757 100644
--- a/indra/newview/skins/default/xui/pt/panel_status_bar.xml
+++ b/indra/newview/skins/default/xui/pt/panel_status_bar.xml
@@ -15,7 +15,7 @@
<panel.string name="buycurrencylabel">
L$ [AMT]
</panel.string>
- <panel name="balance_bg">
+ <panel left="-410" name="balance_bg" width="200">
<text name="balance" tool_tip="Atualizar saldo de L$" value="L$20"/>
<button label="Comprar L$" name="buyL" tool_tip="Comprar mais L$"/>
<button label="Comprar" name="goShop" tool_tip="Abrir Mercado do Second Life" width="80"/>
diff --git a/indra/newview/skins/default/xui/ru/panel_status_bar.xml b/indra/newview/skins/default/xui/ru/panel_status_bar.xml
index babe5811ac..9c84ff1fd8 100644
--- a/indra/newview/skins/default/xui/ru/panel_status_bar.xml
+++ b/indra/newview/skins/default/xui/ru/panel_status_bar.xml
@@ -15,7 +15,7 @@
<panel.string name="buycurrencylabel">
L$ [AMT]
</panel.string>
- <panel name="balance_bg">
+ <panel left="-450" name="balance_bg" width="240">
<text name="balance" tool_tip="Щелкните для обновления вашего баланса L$" value="L$20"/>
<button label="Купить L$" name="buyL" tool_tip="Щелкните для покупки L$"/>
<button label="Торговый центр" name="goShop" tool_tip="Открыть торговый центр Second Life" width="121"/>
diff --git a/indra/newview/skins/default/xui/tr/panel_status_bar.xml b/indra/newview/skins/default/xui/tr/panel_status_bar.xml
index 81c304a5d8..178cbda4a2 100644
--- a/indra/newview/skins/default/xui/tr/panel_status_bar.xml
+++ b/indra/newview/skins/default/xui/tr/panel_status_bar.xml
@@ -15,7 +15,7 @@
<panel.string name="buycurrencylabel">
L$ [AMT]
</panel.string>
- <panel name="balance_bg">
+ <panel left="-425" name="balance_bg" width="215">
<text name="balance" tool_tip="L$ bakiyenizi yenilemek için buraya tıklayın" value="L$20"/>
<button label="L$ Satın Al" name="buyL" tool_tip="Daha fazla L$ satın almak için tıklayın"/>
<button label="Alışveriş yap" name="goShop" tool_tip="Second Life Pazaryeri Aç" width="95"/>