diff options
author | Oz Linden <oz@lindenlab.com> | 2012-03-30 15:56:38 -0400 |
---|---|---|
committer | Oz Linden <oz@lindenlab.com> | 2012-03-30 15:56:38 -0400 |
commit | 74d199c1dd10660f72293c84888af412764f1da8 (patch) | |
tree | 0b4c4137abde8283c5a85da08f19de1aea335c2a /indra/newview | |
parent | 3c3ee709677a0c60420eae84a55a7b61113b4949 (diff) | |
parent | 6e4e971fd27826f90c1728c7fd17242083e230fc (diff) |
merge changes for vmrg-233
Diffstat (limited to 'indra/newview')
95 files changed, 1120 insertions, 405 deletions
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 ¤t_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"/> |