diff options
Diffstat (limited to 'indra/newview')
114 files changed, 4236 insertions, 4486 deletions
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 126b6c0a11..7c30d8eba8 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -233,6 +233,7 @@ set(viewer_SOURCE_FILES llfloaterbuyland.cpp llfloatercamera.cpp llfloatercamerapresets.cpp + llfloaterchangeitemthumbnail.cpp llfloaterchatvoicevolume.cpp llfloaterclassified.cpp llfloatercolorpicker.cpp @@ -269,6 +270,7 @@ set(viewer_SOURCE_FILES llfloaterimsession.cpp llfloaterimcontainer.cpp llfloaterinspect.cpp + llfloaterinventorysettings.cpp llfloaterjoystick.cpp llfloaterlagmeter.cpp llfloaterland.cpp @@ -289,7 +291,7 @@ set(viewer_SOURCE_FILES llfloateroutfitphotopreview.cpp llfloaterobjectweights.cpp llfloateropenobject.cpp - llfloatersimpleoutfitsnapshot.cpp + llfloatersimplesnapshot.cpp llfloaterpathfindingcharacters.cpp llfloaterpathfindingconsole.cpp llfloaterpathfindinglinksets.cpp @@ -302,7 +304,6 @@ set(viewer_SOURCE_FILES llfloaterpreferenceviewadvanced.cpp llfloaterpreviewtrash.cpp llfloaterprofiletexture.cpp - llfloaterproperties.cpp llfloaterregiondebugconsole.cpp llfloaterregioninfo.cpp llfloaterreporter.cpp @@ -604,6 +605,7 @@ set(viewer_SOURCE_FILES lltextureinfodetails.cpp lltexturestats.cpp lltextureview.cpp + llthumbnailctrl.cpp lltoast.cpp lltoastalertpanel.cpp lltoastgroupnotifypanel.cpp @@ -872,6 +874,7 @@ set(viewer_HEADER_FILES llfloaterbuycurrencyhtml.h llfloaterbuyland.h llfloatercamerapresets.h + llfloaterchangeitemthumbnail.h llfloatercamera.h llfloaterchatvoicevolume.h llfloaterclassified.h @@ -912,6 +915,7 @@ set(viewer_HEADER_FILES llfloaterimsession.h llfloaterimcontainer.h llfloaterinspect.h + llfloaterinventorysettings.h llfloaterjoystick.h llfloaterlagmeter.h llfloaterland.h @@ -932,7 +936,7 @@ set(viewer_HEADER_FILES llfloateroutfitphotopreview.h llfloaterobjectweights.h llfloateropenobject.h - llfloatersimpleoutfitsnapshot.h + llfloatersimplesnapshot.h llfloaterpathfindingcharacters.h llfloaterpathfindingconsole.h llfloaterpathfindinglinksets.h @@ -945,7 +949,6 @@ set(viewer_HEADER_FILES llfloaterpreferenceviewadvanced.h llfloaterpreviewtrash.h llfloaterprofiletexture.h - llfloaterproperties.h llfloaterregiondebugconsole.h llfloaterregioninfo.h llfloaterreporter.h @@ -1236,6 +1239,7 @@ set(viewer_HEADER_FILES lltextureinfodetails.h lltexturestats.h lltextureview.h + llthumbnailctrl.h lltoast.h lltoastalertpanel.h lltoastgroupnotifypanel.h diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 411f77e6a7..23521351ca 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -16898,5 +16898,38 @@ <key>Value</key> <integer>0</integer> </map> + <key>FindOriginalOpenWindow</key> + <map> + <key>Comment</key> + <string>Sets the action for 'Find original' and 'Show in Inventory' (0 - shows item in main Inventory, 1 - opens a new single-folder window)</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>0</integer> + </map> +<key>MultiModeDoubleClickFolder</key> +<map> + <key>Comment</key> + <string>Sets the action for Double-click on folder in multi-folder view (0 - expands and collapses folder, 1 - opens a new window, 2 – stays in current floater but switches to SFV)</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>U32</string> + <key>Value</key> + <integer>0</integer> +</map> +<key>SingleModeDoubleClickOpenWindow</key> +<map> + <key>Comment</key> + <string>Sets the action for Double-click on folder in single-folder view (0 - stays in current window, 1 - opens a new window)</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>0</integer> +</map> </map> </llsd> diff --git a/indra/newview/llaisapi.cpp b/indra/newview/llaisapi.cpp index 005259bcb8..d2c59cfaba 100644 --- a/indra/newview/llaisapi.cpp +++ b/indra/newview/llaisapi.cpp @@ -100,7 +100,7 @@ void AISAPI::CreateInventory(const LLUUID& parentId, const LLSD& newInventory, c tid.generate(); std::string url = cap + std::string("/category/") + parentId.asString() + "?tid=" + tid.asString(); - LL_DEBUGS("Inventory") << "url: " << url << LL_ENDL; + LL_DEBUGS("Inventory") << "url: " << url << " parentID " << parentId << " newInventory " << newInventory << LL_ENDL; // I may be suffering from golden hammer here, but the first part of this bind // is actually a static cast for &HttpCoroutineAdapter::postAndSuspend so that @@ -124,7 +124,7 @@ void AISAPI::CreateInventory(const LLUUID& parentId, const LLSD& newInventory, c (&LLCoreHttpUtil::HttpCoroutineAdapter::postAndSuspend), _1, _2, _3, _4, _5, _6); LLCoprocedureManager::CoProcedure_t proc(boost::bind(&AISAPI::InvokeAISCommandCoro, - _1, postFn, url, parentId, newInventory, callback, COPYINVENTORY)); + _1, postFn, url, parentId, newInventory, callback, CREATEINVENTORY)); EnqueueAISCommand("CreateInventory", proc); } @@ -478,6 +478,7 @@ void AISAPI::InvokeAISCommandCoro(LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t ht LL_WARNS("Inventory") << ll_pretty_print_sd(result) << LL_ENDL; } + LL_DEBUGS("Inventory") << result << LL_ENDL; gInventory.onAISUpdateReceived("AISCommand", result); if (callback && !callback.empty()) @@ -487,9 +488,32 @@ void AISAPI::InvokeAISCommandCoro(LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t ht if (result.has("category_id") && (type == COPYLIBRARYCATEGORY)) { id = result["category_id"]; + callback(id); } + if (type == CREATEINVENTORY) + { + if (result.has("_created_categories")) + { + LLSD& cats = result["_created_categories"]; + LLSD::array_const_iterator cat_iter; + for (cat_iter = cats.beginArray(); cat_iter != cats.endArray(); ++cat_iter) + { + LLUUID cat_id = *cat_iter; + callback(cat_id); + } + } + if (result.has("_created_items")) + { + LLSD& items = result["_created_items"]; + LLSD::array_const_iterator item_iter; + for (item_iter = items.beginArray(); item_iter != items.endArray(); ++item_iter) + { + LLUUID item_id = *item_iter; + callback(item_id); + } + } + } - callback(id); } } diff --git a/indra/newview/llaisapi.h b/indra/newview/llaisapi.h index 856f3fc180..6e9cc19baa 100644 --- a/indra/newview/llaisapi.h +++ b/indra/newview/llaisapi.h @@ -61,7 +61,8 @@ private: PURGEDESCENDENTS, UPDATECATEGORY, UPDATEITEM, - COPYLIBRARYCATEGORY + COPYLIBRARYCATEGORY, + CREATEINVENTORY } COMMAND_TYPE; static const std::string INVENTORY_CAP_NAME; diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp index 3c93a9df7e..d8e239822e 100644 --- a/indra/newview/llappearancemgr.cpp +++ b/indra/newview/llappearancemgr.cpp @@ -1701,6 +1701,8 @@ void LLAppearanceMgr::shallowCopyCategory(const LLUUID& src_id, const LLUUID& ds { parent_id = gInventory.getRootFolderID(); } + // USES UDP PATH + // D567 needs to carry over thumbnail info LLUUID subfolder_id = gInventory.createNewCategory( parent_id, LLFolderType::FT_NONE, src_cat->getName()); @@ -2725,7 +2727,9 @@ void LLAppearanceMgr::wearCategoryFinal(LLUUID& cat_id, bool copy_items, bool ap { pid = gInventory.getRootFolderID(); } - + + // UDP PATH + // D567 needs to carry over thumbnail info if present LLUUID new_cat_id = gInventory.createNewCategory( pid, LLFolderType::FT_NONE, @@ -3981,12 +3985,15 @@ void LLAppearanceMgr::makeNewOutfitLinks(const std::string& new_folder_name, boo // First, make a folder in the My Outfits directory. const LLUUID parent_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MY_OUTFITS); + // D567 replace with coros if (AISAPI::isAvailable()) { // cap-based category creation was buggy until recently. use // existence of AIS as an indicator the fix is present. Does // not actually use AIS to create the category. inventory_func_type func = boost::bind(&LLAppearanceMgr::onOutfitFolderCreated,this,_1,show_panel); + + // D567 copy thumbnail info from source folder gInventory.createNewCategory( parent_id, LLFolderType::FT_OUTFIT, @@ -3994,7 +4001,9 @@ void LLAppearanceMgr::makeNewOutfitLinks(const std::string& new_folder_name, boo func); } else - { + { + // UDP PATH, should remove + // D567 copy thumbnail info from source folder LLUUID folder_id = gInventory.createNewCategory( parent_id, LLFolderType::FT_OUTFIT, diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index c9f5f62c41..0f419d8243 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -213,7 +213,7 @@ #include "llcommandlineparser.h" #include "llfloatermemleak.h" #include "llfloaterreg.h" -#include "llfloatersimpleoutfitsnapshot.h" +#include "llfloatersimplesnapshot.h" #include "llfloatersnapshot.h" #include "llsidepanelinventory.h" #include "llatmosphere.h" @@ -1525,7 +1525,7 @@ bool LLAppViewer::doFrame() LL_PROFILE_ZONE_NAMED_CATEGORY_APP( "df Snapshot" ) pingMainloopTimeout("Main:Snapshot"); LLFloaterSnapshot::update(); // take snapshots - LLFloaterSimpleOutfitSnapshot::update(); + LLFloaterSimpleSnapshot::update(); gGLActive = FALSE; } } @@ -3200,15 +3200,16 @@ LLSD LLAppViewer::getViewerInfo() const // LLFloaterAbout. LLSD info; auto& versionInfo(LLVersionInfo::instance()); - info["VIEWER_VERSION"] = LLSDArray(versionInfo.getMajor())(versionInfo.getMinor())(versionInfo.getPatch())(versionInfo.getBuild()); + info["VIEWER_VERSION"] = llsd::array(versionInfo.getMajor(), versionInfo.getMinor(), + versionInfo.getPatch(), versionInfo.getBuild()); info["VIEWER_VERSION_STR"] = versionInfo.getVersion(); info["CHANNEL"] = versionInfo.getChannel(); - info["ADDRESS_SIZE"] = ADDRESS_SIZE; - std::string build_config = versionInfo.getBuildConfig(); - if (build_config != "Release") - { - info["BUILD_CONFIG"] = build_config; - } + info["ADDRESS_SIZE"] = ADDRESS_SIZE; + std::string build_config = versionInfo.getBuildConfig(); + if (build_config != "Release") + { + info["BUILD_CONFIG"] = build_config; + } // return a URL to the release notes for this viewer, such as: // https://releasenotes.secondlife.com/viewer/2.1.0.123456.html diff --git a/indra/newview/llconversationmodel.h b/indra/newview/llconversationmodel.h index 7c6980a7e6..22d2d60905 100644 --- a/indra/newview/llconversationmodel.h +++ b/indra/newview/llconversationmodel.h @@ -111,6 +111,7 @@ public: virtual void previewItem( void ); virtual void selectItem(void) { } virtual void showProperties(void); + virtual void navigateToFolder(bool new_window = false, bool change_mode = false) {} // Methods used in sorting (see LLConversationSort::operator()) EConversationType const getType() const { return mConvType; } diff --git a/indra/newview/llfloaterchangeitemthumbnail.cpp b/indra/newview/llfloaterchangeitemthumbnail.cpp new file mode 100644 index 0000000000..626265fd4b --- /dev/null +++ b/indra/newview/llfloaterchangeitemthumbnail.cpp @@ -0,0 +1,604 @@ +/** + * @file llfloaterchangeitemthumbnail.cpp + * @brief LLFloaterChangeItemThumbnail class implementation + * + * $LicenseInfo:firstyear=2023&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2023, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" + +#include "llfloaterchangeitemthumbnail.h" + +#include "llbutton.h" +#include "llclipboard.h" +#include "lliconctrl.h" +#include "llinventoryfunctions.h" +#include "llinventoryicon.h" +#include "llinventorymodel.h" +#include "llinventoryobserver.h" +#include "llfloaterreg.h" +#include "llfloatersimplesnapshot.h" +#include "lllineeditor.h" +#include "llnotificationsutil.h" +#include "lltextbox.h" +#include "lltexturectrl.h" +#include "llthumbnailctrl.h" +#include "llviewerfoldertype.h" +#include "llviewermenufile.h" +#include "llviewerobjectlist.h" +#include "llwindow.h" + + +class LLThumbnailImagePicker : public LLFilePickerThread +{ +public: + LLThumbnailImagePicker(const LLUUID &item_id); + LLThumbnailImagePicker(const LLUUID &item_id, const LLUUID &task_id); + ~LLThumbnailImagePicker(); + void notify(const std::vector<std::string>& filenames) override; + +private: + LLUUID mInventoryId; + LLUUID mTaskId; +}; + +LLThumbnailImagePicker::LLThumbnailImagePicker(const LLUUID &item_id) + : LLFilePickerThread(LLFilePicker::FFLOAD_IMAGE) + , mInventoryId(item_id) +{ +} + +LLThumbnailImagePicker::LLThumbnailImagePicker(const LLUUID &item_id, const LLUUID &task_id) + : LLFilePickerThread(LLFilePicker::FFLOAD_IMAGE) + , mInventoryId(item_id) + , mTaskId(task_id) +{ +} + +LLThumbnailImagePicker::~LLThumbnailImagePicker() +{ +} + +void LLThumbnailImagePicker::notify(const std::vector<std::string>& filenames) +{ + if (filenames.empty()) + { + return; + } + std::string file_path = filenames[0]; + if (file_path.empty()) + { + return; + } + + LLFloaterSimpleSnapshot::uploadThumbnail(file_path, mInventoryId, mTaskId); +} + +LLFloaterChangeItemThumbnail::LLFloaterChangeItemThumbnail(const LLSD& key) + : LLFloater(key) + , mObserverInitialized(false) + , mTooltipState(TOOLTIP_NONE) +{ +} + +LLFloaterChangeItemThumbnail::~LLFloaterChangeItemThumbnail() +{ + gInventory.removeObserver(this); + removeVOInventoryListener(); +} + +BOOL LLFloaterChangeItemThumbnail::postBuild() +{ + mItemNameText = getChild<LLUICtrl>("item_name"); + mItemTypeIcon = getChild<LLIconCtrl>("item_type_icon"); + mThumbnailCtrl = getChild<LLThumbnailCtrl>("item_thumbnail"); + mToolTipTextBox = getChild<LLTextBox>("tooltip_text"); + + LLSD tooltip_text; + mToolTipTextBox->setValue(tooltip_text); + + LLButton *upload_local = getChild<LLButton>("upload_local"); + upload_local->setClickedCallback(onUploadLocal, (void*)this); + upload_local->setMouseEnterCallback(boost::bind(&LLFloaterChangeItemThumbnail::onButtonMouseEnter, this, _1, _2, TOOLTIP_UPLOAD_LOCAL)); + upload_local->setMouseLeaveCallback(boost::bind(&LLFloaterChangeItemThumbnail::onButtonMouseLeave, this, _1, _2, TOOLTIP_UPLOAD_LOCAL)); + + LLButton *upload_snapshot = getChild<LLButton>("upload_snapshot"); + upload_snapshot->setClickedCallback(onUploadSnapshot, (void*)this); + upload_snapshot->setMouseEnterCallback(boost::bind(&LLFloaterChangeItemThumbnail::onButtonMouseEnter, this, _1, _2, TOOLTIP_UPLOAD_SNAPSHOT)); + upload_snapshot->setMouseLeaveCallback(boost::bind(&LLFloaterChangeItemThumbnail::onButtonMouseLeave, this, _1, _2, TOOLTIP_UPLOAD_SNAPSHOT)); + + LLButton *use_texture = getChild<LLButton>("use_texture"); + use_texture->setClickedCallback(onUseTexture, (void*)this); + use_texture->setMouseEnterCallback(boost::bind(&LLFloaterChangeItemThumbnail::onButtonMouseEnter, this, _1, _2, TOOLTIP_USE_TEXTURE)); + use_texture->setMouseLeaveCallback(boost::bind(&LLFloaterChangeItemThumbnail::onButtonMouseLeave, this, _1, _2, TOOLTIP_USE_TEXTURE)); + + mCopyToClipboardBtn = getChild<LLButton>("copy_to_clipboard"); + mCopyToClipboardBtn->setClickedCallback(onCopyToClipboard, (void*)this); + mCopyToClipboardBtn->setMouseEnterCallback(boost::bind(&LLFloaterChangeItemThumbnail::onButtonMouseEnter, this, _1, _2, TOOLTIP_COPY_TO_CLIPBOARD)); + mCopyToClipboardBtn->setMouseLeaveCallback(boost::bind(&LLFloaterChangeItemThumbnail::onButtonMouseLeave, this, _1, _2, TOOLTIP_COPY_TO_CLIPBOARD)); + + mPasteFromClipboardBtn = getChild<LLButton>("paste_from_clipboard"); + mPasteFromClipboardBtn->setClickedCallback(onPasteFromClipboard, (void*)this); + mPasteFromClipboardBtn->setMouseEnterCallback(boost::bind(&LLFloaterChangeItemThumbnail::onButtonMouseEnter, this, _1, _2, TOOLTIP_COPY_FROM_CLIPBOARD)); + mPasteFromClipboardBtn->setMouseLeaveCallback(boost::bind(&LLFloaterChangeItemThumbnail::onButtonMouseLeave, this, _1, _2, TOOLTIP_COPY_FROM_CLIPBOARD)); + + mRemoveImageBtn = getChild<LLButton>("remove_image"); + mRemoveImageBtn->setClickedCallback(onRemove, (void*)this); + mRemoveImageBtn->setMouseEnterCallback(boost::bind(&LLFloaterChangeItemThumbnail::onButtonMouseEnter, this, _1, _2, TOOLTIP_REMOVE)); + mRemoveImageBtn->setMouseLeaveCallback(boost::bind(&LLFloaterChangeItemThumbnail::onButtonMouseLeave, this, _1, _2, TOOLTIP_REMOVE)); + + return LLFloater::postBuild(); +} + +void LLFloaterChangeItemThumbnail::onOpen(const LLSD& key) +{ + if (!key.has("item_id") && !key.isUUID()) + { + closeFloater(); + } + + if (key.isUUID()) + { + mItemId = key.asUUID(); + } + else + { + mItemId = key["item_id"].asUUID(); + mTaskId = key["task_id"].asUUID(); + } + + refreshFromInventory(); +} + +void LLFloaterChangeItemThumbnail::changed(U32 mask) +{ + //LLInventoryObserver + + if (mTaskId.notNull() || mItemId.isNull()) + { + // Task inventory or not set up yet + return; + } + + const std::set<LLUUID>& mChangedItemIDs = gInventory.getChangedIDs(); + std::set<LLUUID>::const_iterator it; + + for (it = mChangedItemIDs.begin(); it != mChangedItemIDs.end(); it++) + { + // set dirty for 'item profile panel' only if changed item is the item for which 'item profile panel' is shown (STORM-288) + if (*it == mItemId) + { + // if there's a change we're interested in. + if ((mask & (LLInventoryObserver::LABEL | LLInventoryObserver::INTERNAL | LLInventoryObserver::REMOVE)) != 0) + { + refreshFromInventory(); + } + } + } +} + +void LLFloaterChangeItemThumbnail::inventoryChanged(LLViewerObject* object, + LLInventoryObject::object_list_t* inventory, + S32 serial_num, + void* user_data) +{ + //LLVOInventoryListener + refreshFromInventory(); +} + +LLInventoryObject* LLFloaterChangeItemThumbnail::getInventoryObject() +{ + LLInventoryObject* obj = NULL; + if (mTaskId.isNull()) + { + // it is in agent inventory + if (!mObserverInitialized) + { + gInventory.addObserver(this); + mObserverInitialized = true; + } + + obj = gInventory.getObject(mItemId); + } + else + { + LLViewerObject* object = gObjectList.findObject(mTaskId); + if (object) + { + if (!mObserverInitialized) + { + registerVOInventoryListener(object, NULL); + mObserverInitialized = false; + } + + obj = object->getInventoryObject(mItemId); + } + } + return obj; +} + +void LLFloaterChangeItemThumbnail::refreshFromInventory() +{ + LLInventoryObject* obj = getInventoryObject(); + if (!obj) + { + closeFloater(); + } + + if (obj) + { + const LLUUID trash_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_TRASH); + bool in_trash = (obj->getUUID() == trash_id) || gInventory.isObjectDescendentOf(obj->getUUID(), trash_id); + if (in_trash) + { + // Close properties when moving to trash + // Aren't supposed to view properties from trash + closeFloater(); + } + else + { + refreshFromObject(obj); + } + } + else + { + closeFloater(); + } +} + +class LLIsOutfitTextureType : public LLInventoryCollectFunctor +{ +public: + LLIsOutfitTextureType() {} + virtual ~LLIsOutfitTextureType() {} + virtual bool operator()(LLInventoryCategory* cat, + LLInventoryItem* item); +}; + +bool LLIsOutfitTextureType::operator()(LLInventoryCategory* cat, LLInventoryItem* item) +{ + return item && (item->getType() == LLAssetType::AT_TEXTURE); +} + +void LLFloaterChangeItemThumbnail::refreshFromObject(LLInventoryObject* obj) +{ + LLUIImagePtr icon_img; + LLUUID thumbnail_id = obj->getThumbnailUUID(); + + LLViewerInventoryItem* item = dynamic_cast<LLViewerInventoryItem*>(obj); + if (item) + { + // This floater probably shouldn't be be possible to open + // for imcomplete items + llassert(item->isFinished()); + + icon_img = LLInventoryIcon::getIcon(item->getType(), item->getInventoryType(), item->getFlags(), FALSE); + mRemoveImageBtn->setEnabled(thumbnail_id.notNull() && ((item->getActualType() != LLAssetType::AT_TEXTURE) || (item->getAssetUUID() != thumbnail_id))); + } + else + { + LLViewerInventoryCategory* cat = dynamic_cast<LLViewerInventoryCategory*>(obj); + + if (cat) + { + icon_img = LLUI::getUIImage(LLViewerFolderType::lookupIconName(cat->getPreferredType(), true)); + + if (thumbnail_id.isNull() && (cat->getPreferredType() == LLFolderType::FT_OUTFIT)) + { + // Legacy support, check if there is an image inside + + LLInventoryModel::cat_array_t cats; + LLInventoryModel::item_array_t items; + // Not LLIsOfAssetType, because we allow links + LLIsOutfitTextureType f; + gInventory.getDirectDescendentsOf(mItemId, cats, items, f); + + if (1 == items.size()) + { + LLViewerInventoryItem* item = items.front(); + if (item && item->getIsLinkType()) + { + item = item->getLinkedItem(); + } + if (item) + { + LL_INFOS() << "Setting image from outfit as a thumbnail" << LL_ENDL; + thumbnail_id = item->getAssetUUID(); + + if (validateAsset(thumbnail_id)) + { + // per SL-19188, set this image as a thumbnail + cat->setThumbnailUUID(thumbnail_id); + // todo: needs to trigger send/update once server support is done + } + } + } + } + + mRemoveImageBtn->setEnabled(thumbnail_id.notNull()); + } + } + mItemTypeIcon->setImage(icon_img); + mItemNameText->setValue(obj->getName()); + + mThumbnailCtrl->setValue(thumbnail_id); + + mCopyToClipboardBtn->setEnabled(thumbnail_id.notNull()); + + // todo: some elements might not support setting thumbnails + // since they already have them +} + +void LLFloaterChangeItemThumbnail::onUploadLocal(void *userdata) +{ + LLFloaterChangeItemThumbnail *self = (LLFloaterChangeItemThumbnail*)userdata; + + (new LLThumbnailImagePicker(self->mItemId, self->mTaskId))->getFile(); + + LLFloater* floaterp = self->mPickerHandle.get(); + if (floaterp) + { + floaterp->closeFloater(); + } + floaterp = self->mSnapshotHandle.get(); + if (floaterp) + { + floaterp->closeFloater(); + } +} + +void LLFloaterChangeItemThumbnail::onUploadSnapshot(void *userdata) +{ + LLFloaterChangeItemThumbnail *self = (LLFloaterChangeItemThumbnail*)userdata; + + LLFloater* floaterp = self->mSnapshotHandle.get(); + // Show the dialog + if (floaterp) + { + floaterp->openFloater(); + } + else + { + LLSD key; + key["item_id"] = self->mItemId; + key["task_id"] = self->mTaskId; + LLFloaterSimpleSnapshot* snapshot_floater = (LLFloaterSimpleSnapshot*)LLFloaterReg::showInstance("simple_snapshot", key, true); + if (snapshot_floater) + { + self->addDependentFloater(snapshot_floater); + self->mSnapshotHandle = snapshot_floater->getHandle(); + snapshot_floater->setOwner(self); + } + } + + floaterp = self->mPickerHandle.get(); + if (floaterp) + { + floaterp->closeFloater(); + } +} + +void LLFloaterChangeItemThumbnail::onUseTexture(void *userdata) +{ + LLFloaterChangeItemThumbnail *self = (LLFloaterChangeItemThumbnail*)userdata; + LLInventoryObject* obj = self->getInventoryObject(); + if (obj) + { + self->showTexturePicker(obj->getThumbnailUUID()); + } + + LLFloater* floaterp = self->mSnapshotHandle.get(); + if (floaterp) + { + floaterp->closeFloater(); + } +} + +void LLFloaterChangeItemThumbnail::onCopyToClipboard(void *userdata) +{ + LLFloaterChangeItemThumbnail *self = (LLFloaterChangeItemThumbnail*)userdata; + LLInventoryObject* obj = self->getInventoryObject(); + if (obj) + { + LLClipboard::instance().addToClipboard(obj->getThumbnailUUID()); + } +} + +void LLFloaterChangeItemThumbnail::onPasteFromClipboard(void *userdata) +{ + LLFloaterChangeItemThumbnail *self = (LLFloaterChangeItemThumbnail*)userdata; + std::vector<LLUUID> objects; + LLClipboard::instance().pasteFromClipboard(objects); + if (objects.size() > 0) + { + LLInventoryObject* obj = self->getInventoryObject(); + if (obj) + { + LLUUID asset_id = objects[0]; + if (validateAsset(asset_id)) + { + obj->setThumbnailUUID(asset_id); + // todo: need to trigger send/update once server support is done + } + else + { + LLNotificationsUtil::add("ThumbnailDimantionsLimit"); + } + } + } +} + +void LLFloaterChangeItemThumbnail::onRemove(void *userdata) +{ + LLFloaterChangeItemThumbnail *self = (LLFloaterChangeItemThumbnail*)userdata; + + LLSD payload; + payload["item_id"] = self->mItemId; + payload["object_id"] = self->mTaskId; + LLNotificationsUtil::add("DeleteThumbnail", LLSD(), payload, boost::bind(&LLFloaterChangeItemThumbnail::onRemovalConfirmation, _1, _2, self->getHandle())); +} + +// static +void LLFloaterChangeItemThumbnail::onRemovalConfirmation(const LLSD& notification, const LLSD& response, LLHandle<LLFloater> handle) +{ + S32 option = LLNotificationsUtil::getSelectedOption(notification, response); + if (option == 0 && !handle.isDead() && !handle.get()->isDead()) + { + LLFloaterChangeItemThumbnail* self = (LLFloaterChangeItemThumbnail*)handle.get(); + + LLInventoryObject* obj = self->getInventoryObject(); + if (obj) + { + obj->setThumbnailUUID(LLUUID::null); + // todo: need to trigger send/update once server support is done + } + } +} + +bool LLFloaterChangeItemThumbnail::validateAsset(const LLUUID &asset_id) +{ + LLPointer<LLViewerFetchedTexture> texturep = LLViewerTextureManager::getFetchedTexture(asset_id); + + if (!texturep) + { + return false; + } + + if (texturep->getFullWidth() != texturep->getFullHeight()) + { + return false; + } + + if (texturep->getFullWidth() > LLFloaterSimpleSnapshot::THUMBNAIL_SNAPSHOT_DIM_MAX + || texturep->getFullHeight() > LLFloaterSimpleSnapshot::THUMBNAIL_SNAPSHOT_DIM_MAX) + { + return false; + } + + if (texturep->getFullWidth() < LLFloaterSimpleSnapshot::THUMBNAIL_SNAPSHOT_DIM_MIN + || texturep->getFullHeight() < LLFloaterSimpleSnapshot::THUMBNAIL_SNAPSHOT_DIM_MIN) + { + return false; + } + return true; +} + +void LLFloaterChangeItemThumbnail::showTexturePicker(const LLUUID &thumbnail_id) +{ + // show hourglass cursor when loading inventory window + getWindow()->setCursor(UI_CURSOR_WAIT); + + LLFloater* floaterp = mPickerHandle.get(); + // Show the dialog + if (floaterp) + { + floaterp->openFloater(); + } + else + { + floaterp = new LLFloaterTexturePicker( + this, + thumbnail_id, + thumbnail_id, + thumbnail_id, + FALSE, + TRUE, + "SELECT PHOTO", + PERM_NONE, + PERM_NONE, + PERM_NONE, + FALSE, + NULL); + + mPickerHandle = floaterp->getHandle(); + + LLFloaterTexturePicker* texture_floaterp = dynamic_cast<LLFloaterTexturePicker*>(floaterp); + if (texture_floaterp) + { + //texture_floaterp->setTextureSelectedCallback(); + //texture_floaterp->setOnUpdateImageStatsCallback(); + texture_floaterp->setOnFloaterCommitCallback([this](LLTextureCtrl::ETexturePickOp op, LLUUID id) + { + if (op == LLTextureCtrl::TEXTURE_SELECT) + { + onTexturePickerCommit(id); + } + } + ); + + texture_floaterp->setLocalTextureEnabled(FALSE); + texture_floaterp->setBakeTextureEnabled(FALSE); + texture_floaterp->setCanApplyImmediately(false); + texture_floaterp->setCanApply(false, true); + + addDependentFloater(texture_floaterp); + } + + floaterp->openFloater(); + } + floaterp->setFocus(TRUE); +} + +void LLFloaterChangeItemThumbnail::onTexturePickerCommit(LLUUID id) +{ + LLFloaterTexturePicker* floaterp = (LLFloaterTexturePicker*)mPickerHandle.get(); + LLInventoryObject* obj = getInventoryObject(); + + if (obj && floaterp) + { + LLUUID asset_id = floaterp->getAssetID(); + if (validateAsset(asset_id)) + { + obj->setThumbnailUUID(asset_id); + // todo: need to trigger send/update once server support is done + } + else + { + LLNotificationsUtil::add("ThumbnailDimantionsLimit"); + } + } +} + +void LLFloaterChangeItemThumbnail::onButtonMouseEnter(LLUICtrl* button, const LLSD& param, EToolTipState state) +{ + mTooltipState = state; + + std::string tooltip_text; + std::string tooltip_name = "tooltip_" + button->getName(); + if (hasString(tooltip_name)) + { + tooltip_text = getString(tooltip_name); + } + + mToolTipTextBox->setValue(tooltip_text); +} + +void LLFloaterChangeItemThumbnail::onButtonMouseLeave(LLUICtrl* button, const LLSD& param, EToolTipState state) +{ + if (mTooltipState == state) + { + mTooltipState = TOOLTIP_NONE; + LLSD tooltip_text; + mToolTipTextBox->setValue(tooltip_text); + } +} + diff --git a/indra/newview/llfloaterchangeitemthumbnail.h b/indra/newview/llfloaterchangeitemthumbnail.h new file mode 100644 index 0000000000..bc85e4be0b --- /dev/null +++ b/indra/newview/llfloaterchangeitemthumbnail.h @@ -0,0 +1,105 @@ +/** + * @file llfloaterchangeitemthumbnail.h + * @brief LLFloaterChangeItemThumbnail class definition + * + * $LicenseInfo:firstyear=2023&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2023, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#ifndef LL_LLFLOATERCHANGEITEMTHUMBNAIL_H +#define LL_LLFLOATERCHANGEITEMTHUMBNAIL_H + +#include "llfloater.h" +#include "llinventoryobserver.h" +#include "llvoinventorylistener.h" + +class LLButton; +class LLIconCtrl; +class LLTextBox; +class LLThumbnailCtrl; +class LLUICtrl; +class LLViewerInventoryItem; + +class LLFloaterChangeItemThumbnail : public LLFloater, public LLInventoryObserver, public LLVOInventoryListener +{ +public: + LLFloaterChangeItemThumbnail(const LLSD& key); + ~LLFloaterChangeItemThumbnail(); + + BOOL postBuild() override; + void onOpen(const LLSD& key) override; + + void changed(U32 mask) override; + void inventoryChanged(LLViewerObject* object, + LLInventoryObject::object_list_t* inventory, + S32 serial_num, + void* user_data) override; + +private: + + LLInventoryObject* getInventoryObject(); + void refreshFromInventory(); + void refreshFromObject(LLInventoryObject* obj); + + static void onUploadLocal(void*); + static void onUploadSnapshot(void*); + static void onUseTexture(void*); + static void onCopyToClipboard(void*); + static void onPasteFromClipboard(void*); + static void onRemove(void*); + static void onRemovalConfirmation(const LLSD& notification, const LLSD& response, LLHandle<LLFloater> handle); + + static bool validateAsset(const LLUUID &asset_id); + + void showTexturePicker(const LLUUID &thumbnail_id); + void onTexturePickerCommit(LLUUID id); + + enum EToolTipState + { + TOOLTIP_NONE, + TOOLTIP_UPLOAD_LOCAL, + TOOLTIP_UPLOAD_SNAPSHOT, + TOOLTIP_USE_TEXTURE, + TOOLTIP_COPY_TO_CLIPBOARD, + TOOLTIP_COPY_FROM_CLIPBOARD, + TOOLTIP_REMOVE, + }; + + void onButtonMouseEnter(LLUICtrl* button, const LLSD& param, EToolTipState state); + void onButtonMouseLeave(LLUICtrl* button, const LLSD& param, EToolTipState state); + + bool mObserverInitialized; + EToolTipState mTooltipState; + LLUUID mItemId; + LLUUID mTaskId; + + LLIconCtrl *mItemTypeIcon; + LLUICtrl *mItemNameText; + LLThumbnailCtrl *mThumbnailCtrl; + LLTextBox *mToolTipTextBox; + LLButton *mCopyToClipboardBtn; + LLButton *mPasteFromClipboardBtn; + LLButton *mRemoveImageBtn; + + LLHandle<LLFloater> mPickerHandle; + LLHandle<LLFloater> mSnapshotHandle; +}; +#endif // LL_LLFLOATERCHANGEITEMTHUMBNAIL_H diff --git a/indra/newview/llfloaterinventorysettings.cpp b/indra/newview/llfloaterinventorysettings.cpp new file mode 100644 index 0000000000..29d6e90a33 --- /dev/null +++ b/indra/newview/llfloaterinventorysettings.cpp @@ -0,0 +1,44 @@ +/** + * @file llfloaterinventorysettings.cpp + * @brief LLFloaterInventorySettings class implementation + * + * $LicenseInfo:firstyear=2023&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2023, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" + +#include "llfloaterinventorysettings.h" + +LLFloaterInventorySettings::LLFloaterInventorySettings(const LLSD& key) + : LLFloater(key) +{ +} + +LLFloaterInventorySettings::~LLFloaterInventorySettings() +{} + +BOOL LLFloaterInventorySettings::postBuild() +{ + getChild<LLButton>("ok_btn")->setCommitCallback(boost::bind(&LLFloater::closeFloater, this, false)); + return TRUE; +} + diff --git a/indra/newview/llfloaterinventorysettings.h b/indra/newview/llfloaterinventorysettings.h new file mode 100644 index 0000000000..50304276c7 --- /dev/null +++ b/indra/newview/llfloaterinventorysettings.h @@ -0,0 +1,45 @@ +/** + * @file llfloaterinventorysettings.h + * @brief LLFloaterInventorySettings class definition + * + * $LicenseInfo:firstyear=2023&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2023, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#ifndef LL_LLFLOATERINVENTORYSETTINGS_H +#define LL_LLFLOATERINVENTORYSETTINGS_H + +#include "llfloater.h" + +class LLFloaterInventorySettings + : public LLFloater +{ + friend class LLFloaterReg; + +public: + virtual BOOL postBuild(); + +private: + LLFloaterInventorySettings(const LLSD& key); + ~LLFloaterInventorySettings(); +}; + +#endif diff --git a/indra/newview/llfloaterlandholdings.cpp b/indra/newview/llfloaterlandholdings.cpp index 8633fe4e5e..a3222d622f 100644 --- a/indra/newview/llfloaterlandholdings.cpp +++ b/indra/newview/llfloaterlandholdings.cpp @@ -39,6 +39,7 @@ #include "llfloaterworldmap.h" #include "llproductinforequest.h" #include "llscrolllistctrl.h" +#include "llsdutil.h" #include "llstatusbar.h" #include "lltextbox.h" #include "llscrolllistctrl.h" @@ -79,24 +80,25 @@ BOOL LLFloaterLandHoldings::postBuild() for(S32 i = 0; i < count; ++i) { LLUUID id(gAgent.mGroups.at(i).mID); - - LLSD element; - element["id"] = id; - element["columns"][0]["column"] = "group"; - element["columns"][0]["value"] = gAgent.mGroups.at(i).mName; - element["columns"][0]["font"] = "SANSSERIF"; - LLUIString areastr = getString("area_string"); areastr.setArg("[AREA]", llformat("%d", gAgent.mGroups.at(i).mContribution)); - element["columns"][1]["column"] = "area"; - element["columns"][1]["value"] = areastr; - element["columns"][1]["font"] = "SANSSERIF"; - grant_list->addElement(element); + grant_list->addElement( + llsd::map( + "id", id, + "columns", llsd::array( + llsd::map( + "column", "group", + "value", gAgent.mGroups.at(i).mName, + "font", "SANSSERIF"), + llsd::map( + "column", "area", + "value", areastr, + "font", "SANSSERIF")))); } - + center(); - + return TRUE; } @@ -108,8 +110,8 @@ LLFloaterLandHoldings::~LLFloaterLandHoldings() void LLFloaterLandHoldings::onOpen(const LLSD& key) { - LLScrollListCtrl *list = getChild<LLScrollListCtrl>("parcel list"); - list->clearRows(); + LLScrollListCtrl *list = getChild<LLScrollListCtrl>("parcel list"); + list->clearRows(); // query_id null is known to be us const LLUUID& query_id = LLUUID::null; diff --git a/indra/newview/llfloatermarketplacelistings.cpp b/indra/newview/llfloatermarketplacelistings.cpp index e755e9924c..58bd4bc82b 100644 --- a/indra/newview/llfloatermarketplacelistings.cpp +++ b/indra/newview/llfloatermarketplacelistings.cpp @@ -41,8 +41,11 @@ #include "llnotificationmanager.h" #include "llnotificationsutil.h" #include "llsidepaneliteminfo.h" +#include "llsidepaneltaskinfo.h" +#include "lltabcontainer.h" #include "lltextbox.h" #include "lltrans.h" +#include "llviewerwindow.h" ///---------------------------------------------------------------------------- /// LLPanelMarketplaceListings @@ -954,18 +957,44 @@ LLFloaterItemProperties::~LLFloaterItemProperties() BOOL LLFloaterItemProperties::postBuild() { - // On the standalone properties floater, we have no need for a back button... - LLSidepanelItemInfo* panel = getChild<LLSidepanelItemInfo>("item_panel"); - LLButton* back_btn = panel->getChild<LLButton>("back_btn"); - back_btn->setVisible(FALSE); - return LLFloater::postBuild(); } void LLFloaterItemProperties::onOpen(const LLSD& key) { // Tell the panel which item it needs to visualize - LLSidepanelItemInfo* panel = getChild<LLSidepanelItemInfo>("item_panel"); - panel->setItemID(key["id"].asUUID()); + LLPanel* panel = findChild<LLPanel>("sidepanel"); + + LLSidepanelItemInfo* item_panel = dynamic_cast<LLSidepanelItemInfo*>(panel); + if (item_panel) + { + item_panel->setItemID(key["id"].asUUID()); + if (key.has("object")) + { + item_panel->setObjectID(key["object"].asUUID()); + } + item_panel->setParentFloater(this); + } + + LLSidepanelTaskInfo* task_panel = dynamic_cast<LLSidepanelTaskInfo*>(panel); + if (task_panel) + { + task_panel->setObjectSelection(LLSelectMgr::getInstance()->getSelection()); + } } +LLMultiItemProperties::LLMultiItemProperties(const LLSD& key) + : LLMultiFloater(LLSD()) +{ + // start with a small rect in the top-left corner ; will get resized + LLRect rect; + rect.setLeftTopAndSize(0, gViewerWindow->getWindowHeightScaled(), 350, 350); + setRect(rect); + LLFloater* last_floater = LLFloaterReg::getLastFloaterInGroup(key.asString()); + if (last_floater) + { + stackWith(*last_floater); + } + setTitle(LLTrans::getString("MultiPropertiesTitle")); + buildTabContainer(); +} diff --git a/indra/newview/llfloatermarketplacelistings.h b/indra/newview/llfloatermarketplacelistings.h index ffc098e28a..77e855fd2a 100644 --- a/indra/newview/llfloatermarketplacelistings.h +++ b/indra/newview/llfloatermarketplacelistings.h @@ -33,6 +33,7 @@ #include "llinventorypanel.h" #include "llnotificationptr.h" #include "llmodaldialog.h" +#include "llmultifloater.h" #include "lltexteditor.h" class LLInventoryCategoriesObserver; @@ -223,4 +224,10 @@ public: private: }; +class LLMultiItemProperties : public LLMultiFloater +{ +public: + LLMultiItemProperties(const LLSD& key); +}; + #endif // LL_LLFLOATERMARKETPLACELISTINGS_H diff --git a/indra/newview/llfloateropenobject.cpp b/indra/newview/llfloateropenobject.cpp index a682064dad..12ad6dcd33 100644 --- a/indra/newview/llfloateropenobject.cpp +++ b/indra/newview/llfloateropenobject.cpp @@ -164,6 +164,7 @@ void LLFloaterOpenObject::moveToInventory(bool wear, bool replace) } inventory_func_type func = boost::bind(LLFloaterOpenObject::callbackCreateInventoryCategory,_1,object_id,wear,replace); + // D567 copy thumbnail info LLUUID category_id = gInventory.createNewCategory(parent_category_id, LLFolderType::FT_NONE, name, @@ -171,6 +172,7 @@ void LLFloaterOpenObject::moveToInventory(bool wear, bool replace) //If we get a null category ID, we are using a capability in createNewCategory and we will //handle the following in the callbackCreateInventoryCategory routine. + // D567 review if ( category_id.notNull() ) { LLCatAndWear* data = new LLCatAndWear; diff --git a/indra/newview/llfloaterproperties.cpp b/indra/newview/llfloaterproperties.cpp deleted file mode 100644 index 64ad40f419..0000000000 --- a/indra/newview/llfloaterproperties.cpp +++ /dev/null @@ -1,891 +0,0 @@ -/** - * @file llfloaterproperties.cpp - * @brief A floater which shows an inventory item's properties. - * - * $LicenseInfo:firstyear=2002&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA - * $/LicenseInfo$ - */ - -#include "llviewerprecompiledheaders.h" -#include "llfloaterproperties.h" - -#include <algorithm> -#include <functional> -#include "llcachename.h" -#include "llavatarnamecache.h" -#include "lldbstrings.h" -#include "llfloaterreg.h" - -#include "llagent.h" -#include "llbutton.h" -#include "llcheckboxctrl.h" -#include "llcombobox.h" -#include "llavataractions.h" -#include "llinventorydefines.h" -#include "llinventoryobserver.h" -#include "llinventorymodel.h" -#include "lllineeditor.h" -//#include "llspinctrl.h" -#include "llradiogroup.h" -#include "llresmgr.h" -#include "roles_constants.h" -#include "llselectmgr.h" -#include "lltextbox.h" -#include "lltrans.h" -#include "lluiconstants.h" -#include "llviewerinventory.h" -#include "llviewerobjectlist.h" -#include "llviewerregion.h" -#include "llviewercontrol.h" -#include "llviewerwindow.h" -#include "llgroupactions.h" - -#include "lluictrlfactory.h" - - -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// Class LLPropertiesObserver -// -// helper class to watch the inventory. -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -// Ugh. This can't be a singleton because it needs to remove itself -// from the inventory observer list when destroyed, which could -// happen after gInventory has already been destroyed if a singleton. -// Instead, do our own ref counting and create / destroy it as needed -class LLPropertiesObserver : public LLInventoryObserver -{ -public: - LLPropertiesObserver(LLFloaterProperties* floater) - : mFloater(floater) - { - gInventory.addObserver(this); - } - virtual ~LLPropertiesObserver() - { - gInventory.removeObserver(this); - } - virtual void changed(U32 mask); -private: - LLFloaterProperties* mFloater; // Not a handle because LLFloaterProperties is managing LLPropertiesObserver -}; - -void LLPropertiesObserver::changed(U32 mask) -{ - // if there's a change we're interested in. - if((mask & (LLInventoryObserver::LABEL | LLInventoryObserver::INTERNAL | LLInventoryObserver::REMOVE)) != 0) - { - mFloater->dirty(); - } -} - - - -///---------------------------------------------------------------------------- -/// Class LLFloaterProperties -///---------------------------------------------------------------------------- - -// Default constructor -LLFloaterProperties::LLFloaterProperties(const LLUUID& item_id) - : LLFloater(mItemID), - mItemID(item_id), - mDirty(TRUE) -{ - mPropertiesObserver = new LLPropertiesObserver(this); -} - -// Destroys the object -LLFloaterProperties::~LLFloaterProperties() -{ - delete mPropertiesObserver; - mPropertiesObserver = NULL; -} - -// virtual -BOOL LLFloaterProperties::postBuild() -{ - // build the UI - // item name & description - getChild<LLLineEditor>("LabelItemName")->setPrevalidate(&LLTextValidate::validateASCIIPrintableNoPipe); - getChild<LLUICtrl>("LabelItemName")->setCommitCallback(boost::bind(&LLFloaterProperties::onCommitName,this)); - getChild<LLLineEditor>("LabelItemDesc")->setPrevalidate(&LLTextValidate::validateASCIIPrintableNoPipe); - getChild<LLUICtrl>("LabelItemDesc")->setCommitCallback(boost::bind(&LLFloaterProperties:: onCommitDescription, this)); - // Creator information - getChild<LLUICtrl>("BtnCreator")->setCommitCallback(boost::bind(&LLFloaterProperties::onClickCreator,this)); - // owner information - getChild<LLUICtrl>("BtnOwner")->setCommitCallback(boost::bind(&LLFloaterProperties::onClickOwner,this)); - // acquired date - // owner permissions - // Permissions debug text - // group permissions - getChild<LLUICtrl>("CheckShareWithGroup")->setCommitCallback(boost::bind(&LLFloaterProperties::onCommitPermissions, this)); - // everyone permissions - getChild<LLUICtrl>("CheckEveryoneCopy")->setCommitCallback(boost::bind(&LLFloaterProperties::onCommitPermissions, this)); - // next owner permissions - getChild<LLUICtrl>("CheckNextOwnerModify")->setCommitCallback(boost::bind(&LLFloaterProperties::onCommitPermissions, this)); - getChild<LLUICtrl>("CheckNextOwnerCopy")->setCommitCallback(boost::bind(&LLFloaterProperties::onCommitPermissions, this)); - getChild<LLUICtrl>("CheckNextOwnerTransfer")->setCommitCallback(boost::bind(&LLFloaterProperties::onCommitPermissions, this)); - // Mark for sale or not, and sale info - getChild<LLUICtrl>("CheckPurchase")->setCommitCallback(boost::bind(&LLFloaterProperties::onCommitSaleInfo, this)); - getChild<LLUICtrl>("ComboBoxSaleType")->setCommitCallback(boost::bind(&LLFloaterProperties::onCommitSaleType, this)); - // "Price" label for edit - getChild<LLUICtrl>("Edit Cost")->setCommitCallback(boost::bind(&LLFloaterProperties::onCommitSaleInfo, this)); - // The UI has been built, now fill in all the values - refresh(); - - return TRUE; -} - -// virtual -void LLFloaterProperties::onOpen(const LLSD& key) -{ - refresh(); -} - -void LLFloaterProperties::refresh() -{ - LLInventoryItem* item = findItem(); - if(item) - { - refreshFromItem(item); - } - else - { - //RN: it is possible that the container object is in the middle of an inventory refresh - // causing findItem() to fail, so just temporarily disable everything - - mDirty = TRUE; - - const char* enableNames[]={ - "LabelItemName", - "LabelItemDesc", - "LabelCreatorName", - "BtnCreator", - "LabelOwnerName", - "BtnOwner", - "CheckOwnerModify", - "CheckOwnerCopy", - "CheckOwnerTransfer", - "CheckShareWithGroup", - "CheckEveryoneCopy", - "CheckNextOwnerModify", - "CheckNextOwnerCopy", - "CheckNextOwnerTransfer", - "CheckPurchase", - "ComboBoxSaleType", - "Edit Cost" - }; - for(size_t t=0; t<LL_ARRAY_SIZE(enableNames); ++t) - { - getChildView(enableNames[t])->setEnabled(false); - } - const char* hideNames[]={ - "BaseMaskDebug", - "OwnerMaskDebug", - "GroupMaskDebug", - "EveryoneMaskDebug", - "NextMaskDebug" - }; - for(size_t t=0; t<LL_ARRAY_SIZE(hideNames); ++t) - { - getChildView(hideNames[t])->setVisible(false); - } - } -} - -void LLFloaterProperties::draw() -{ - if (mDirty) - { - // RN: clear dirty first because refresh can set dirty to TRUE - mDirty = FALSE; - refresh(); - } - - LLFloater::draw(); -} - -void LLFloaterProperties::refreshFromItem(LLInventoryItem* item) -{ - //////////////////////// - // PERMISSIONS LOOKUP // - //////////////////////// - - // do not enable the UI for incomplete items. - LLViewerInventoryItem* i = (LLViewerInventoryItem*)item; - BOOL is_complete = i->isFinished(); - const BOOL cannot_restrict_permissions = LLInventoryType::cannotRestrictPermissions(i->getInventoryType()); - const BOOL is_calling_card = (i->getInventoryType() == LLInventoryType::IT_CALLINGCARD); - const LLPermissions& perm = item->getPermissions(); - const BOOL can_agent_manipulate = gAgent.allowOperation(PERM_OWNER, perm, - GP_OBJECT_MANIPULATE); - const BOOL can_agent_sell = gAgent.allowOperation(PERM_OWNER, perm, - GP_OBJECT_SET_SALE) && - !cannot_restrict_permissions; - const BOOL is_link = i->getIsLinkType(); - - // You need permission to modify the object to modify an inventory - // item in it. - LLViewerObject* object = NULL; - if(!mObjectID.isNull()) object = gObjectList.findObject(mObjectID); - BOOL is_obj_modify = TRUE; - if(object) - { - is_obj_modify = object->permOwnerModify(); - } - - ////////////////////// - // ITEM NAME & DESC // - ////////////////////// - BOOL is_modifiable = gAgent.allowOperation(PERM_MODIFY, perm, - GP_OBJECT_MANIPULATE) - && is_obj_modify && is_complete; - - getChildView("LabelItemNameTitle")->setEnabled(TRUE); - getChildView("LabelItemName")->setEnabled(is_modifiable && !is_calling_card); // for now, don't allow rename of calling cards - getChild<LLUICtrl>("LabelItemName")->setValue(item->getName()); - getChildView("LabelItemDescTitle")->setEnabled(TRUE); - getChildView("LabelItemDesc")->setEnabled(is_modifiable); - getChildView("IconLocked")->setVisible(!is_modifiable); - getChild<LLUICtrl>("LabelItemDesc")->setValue(item->getDescription()); - - ////////////////// - // CREATOR NAME // - ////////////////// - if(!gCacheName) return; - if(!gAgent.getRegion()) return; - - if (item->getCreatorUUID().notNull()) - { - LLAvatarName av_name; - LLAvatarNameCache::get(item->getCreatorUUID(), &av_name); - getChildView("BtnCreator")->setEnabled(TRUE); - getChildView("LabelCreatorTitle")->setEnabled(TRUE); - getChildView("LabelCreatorName")->setEnabled(TRUE); - getChild<LLUICtrl>("LabelCreatorName")->setValue(av_name.getUserName()); - } - else - { - getChildView("BtnCreator")->setEnabled(FALSE); - getChildView("LabelCreatorTitle")->setEnabled(FALSE); - getChildView("LabelCreatorName")->setEnabled(FALSE); - getChild<LLUICtrl>("LabelCreatorName")->setValue(getString("unknown")); - } - - //////////////// - // OWNER NAME // - //////////////// - if(perm.isOwned()) - { - std::string name; - if (perm.isGroupOwned()) - { - gCacheName->getGroupName(perm.getGroup(), name); - } - else - { - LLAvatarName av_name; - LLAvatarNameCache::get(perm.getOwner(), &av_name); - name = av_name.getUserName(); - } - getChildView("BtnOwner")->setEnabled(TRUE); - getChildView("LabelOwnerTitle")->setEnabled(TRUE); - getChildView("LabelOwnerName")->setEnabled(TRUE); - getChild<LLUICtrl>("LabelOwnerName")->setValue(name); - } - else - { - getChildView("BtnOwner")->setEnabled(FALSE); - getChildView("LabelOwnerTitle")->setEnabled(FALSE); - getChildView("LabelOwnerName")->setEnabled(FALSE); - getChild<LLUICtrl>("LabelOwnerName")->setValue(getString("public")); - } - - ////////////////// - // ACQUIRE DATE // - ////////////////// - - time_t time_utc = item->getCreationDate(); - if (0 == time_utc) - { - getChild<LLUICtrl>("LabelAcquiredDate")->setValue(getString("unknown")); - } - else - { - std::string timeStr = getString("acquiredDate"); - LLSD substitution; - substitution["datetime"] = (S32) time_utc; - LLStringUtil::format (timeStr, substitution); - getChild<LLUICtrl>("LabelAcquiredDate")->setValue(timeStr); - } - - /////////////////////// - // OWNER PERMISSIONS // - /////////////////////// - if(can_agent_manipulate) - { - getChild<LLUICtrl>("OwnerLabel")->setValue(getString("you_can")); - } - else - { - getChild<LLUICtrl>("OwnerLabel")->setValue(getString("owner_can")); - } - - U32 base_mask = perm.getMaskBase(); - U32 owner_mask = perm.getMaskOwner(); - U32 group_mask = perm.getMaskGroup(); - U32 everyone_mask = perm.getMaskEveryone(); - U32 next_owner_mask = perm.getMaskNextOwner(); - - getChildView("OwnerLabel")->setEnabled(TRUE); - getChildView("CheckOwnerModify")->setEnabled(FALSE); - getChild<LLUICtrl>("CheckOwnerModify")->setValue(LLSD((BOOL)(owner_mask & PERM_MODIFY))); - getChildView("CheckOwnerCopy")->setEnabled(FALSE); - getChild<LLUICtrl>("CheckOwnerCopy")->setValue(LLSD((BOOL)(owner_mask & PERM_COPY))); - getChildView("CheckOwnerTransfer")->setEnabled(FALSE); - getChild<LLUICtrl>("CheckOwnerTransfer")->setValue(LLSD((BOOL)(owner_mask & PERM_TRANSFER))); - - /////////////////////// - // DEBUG PERMISSIONS // - /////////////////////// - - if( gSavedSettings.getBOOL("DebugPermissions") ) - { - BOOL slam_perm = FALSE; - BOOL overwrite_group = FALSE; - BOOL overwrite_everyone = FALSE; - - if (item->getType() == LLAssetType::AT_OBJECT) - { - U32 flags = item->getFlags(); - slam_perm = flags & LLInventoryItemFlags::II_FLAGS_OBJECT_SLAM_PERM; - overwrite_everyone = flags & LLInventoryItemFlags::II_FLAGS_OBJECT_PERM_OVERWRITE_EVERYONE; - overwrite_group = flags & LLInventoryItemFlags::II_FLAGS_OBJECT_PERM_OVERWRITE_GROUP; - } - - std::string perm_string; - - perm_string = "B: "; - perm_string += mask_to_string(base_mask); - getChild<LLUICtrl>("BaseMaskDebug")->setValue(perm_string); - getChildView("BaseMaskDebug")->setVisible(TRUE); - - perm_string = "O: "; - perm_string += mask_to_string(owner_mask); - getChild<LLUICtrl>("OwnerMaskDebug")->setValue(perm_string); - getChildView("OwnerMaskDebug")->setVisible(TRUE); - - perm_string = "G"; - perm_string += overwrite_group ? "*: " : ": "; - perm_string += mask_to_string(group_mask); - getChild<LLUICtrl>("GroupMaskDebug")->setValue(perm_string); - getChildView("GroupMaskDebug")->setVisible(TRUE); - - perm_string = "E"; - perm_string += overwrite_everyone ? "*: " : ": "; - perm_string += mask_to_string(everyone_mask); - getChild<LLUICtrl>("EveryoneMaskDebug")->setValue(perm_string); - getChildView("EveryoneMaskDebug")->setVisible(TRUE); - - perm_string = "N"; - perm_string += slam_perm ? "*: " : ": "; - perm_string += mask_to_string(next_owner_mask); - getChild<LLUICtrl>("NextMaskDebug")->setValue(perm_string); - getChildView("NextMaskDebug")->setVisible(TRUE); - } - else - { - getChildView("BaseMaskDebug")->setVisible(FALSE); - getChildView("OwnerMaskDebug")->setVisible(FALSE); - getChildView("GroupMaskDebug")->setVisible(FALSE); - getChildView("EveryoneMaskDebug")->setVisible(FALSE); - getChildView("NextMaskDebug")->setVisible(FALSE); - } - - ///////////// - // SHARING // - ///////////// - - // Check for ability to change values. - if (is_link || cannot_restrict_permissions) - { - getChildView("CheckShareWithGroup")->setEnabled(FALSE); - getChildView("CheckEveryoneCopy")->setEnabled(FALSE); - } - else if (is_obj_modify && can_agent_manipulate) - { - getChildView("CheckShareWithGroup")->setEnabled(TRUE); - getChildView("CheckEveryoneCopy")->setEnabled((owner_mask & PERM_COPY) && (owner_mask & PERM_TRANSFER)); - } - else - { - getChildView("CheckShareWithGroup")->setEnabled(FALSE); - getChildView("CheckEveryoneCopy")->setEnabled(FALSE); - } - - // Set values. - BOOL is_group_copy = (group_mask & PERM_COPY) ? TRUE : FALSE; - BOOL is_group_modify = (group_mask & PERM_MODIFY) ? TRUE : FALSE; - BOOL is_group_move = (group_mask & PERM_MOVE) ? TRUE : FALSE; - - if (is_group_copy && is_group_modify && is_group_move) - { - getChild<LLUICtrl>("CheckShareWithGroup")->setValue(LLSD((BOOL)TRUE)); - - LLCheckBoxCtrl* ctl = getChild<LLCheckBoxCtrl>("CheckShareWithGroup"); - if(ctl) - { - ctl->setTentative(FALSE); - } - } - else if (!is_group_copy && !is_group_modify && !is_group_move) - { - getChild<LLUICtrl>("CheckShareWithGroup")->setValue(LLSD((BOOL)FALSE)); - LLCheckBoxCtrl* ctl = getChild<LLCheckBoxCtrl>("CheckShareWithGroup"); - if(ctl) - { - ctl->setTentative(FALSE); - } - } - else - { - LLCheckBoxCtrl* ctl = getChild<LLCheckBoxCtrl>("CheckShareWithGroup"); - if(ctl) - { - ctl->setTentative(TRUE); - ctl->set(TRUE); - } - } - - getChild<LLUICtrl>("CheckEveryoneCopy")->setValue(LLSD((BOOL)(everyone_mask & PERM_COPY))); - - /////////////// - // SALE INFO // - /////////////// - - const LLSaleInfo& sale_info = item->getSaleInfo(); - BOOL is_for_sale = sale_info.isForSale(); - LLComboBox* combo_sale_type = getChild<LLComboBox>("ComboBoxSaleType"); - LLUICtrl* edit_cost = getChild<LLUICtrl>("Edit Cost"); - - // Check for ability to change values. - if (is_obj_modify && can_agent_sell - && gAgent.allowOperation(PERM_TRANSFER, perm, GP_OBJECT_MANIPULATE)) - { - getChildView("CheckPurchase")->setEnabled(is_complete); - - getChildView("NextOwnerLabel")->setEnabled(TRUE); - getChildView("CheckNextOwnerModify")->setEnabled((base_mask & PERM_MODIFY) && !cannot_restrict_permissions); - getChildView("CheckNextOwnerCopy")->setEnabled((base_mask & PERM_COPY) && !cannot_restrict_permissions); - getChildView("CheckNextOwnerTransfer")->setEnabled((next_owner_mask & PERM_COPY) && !cannot_restrict_permissions); - - combo_sale_type->setEnabled(is_complete && is_for_sale); - edit_cost->setEnabled(is_complete && is_for_sale); - } - else - { - getChildView("CheckPurchase")->setEnabled(FALSE); - - getChildView("NextOwnerLabel")->setEnabled(FALSE); - getChildView("CheckNextOwnerModify")->setEnabled(FALSE); - getChildView("CheckNextOwnerCopy")->setEnabled(FALSE); - getChildView("CheckNextOwnerTransfer")->setEnabled(FALSE); - - combo_sale_type->setEnabled(FALSE); - edit_cost->setEnabled(FALSE); - } - - // Set values. - getChild<LLUICtrl>("CheckPurchase")->setValue(is_for_sale); - getChild<LLUICtrl>("CheckNextOwnerModify")->setValue(LLSD(BOOL(next_owner_mask & PERM_MODIFY))); - getChild<LLUICtrl>("CheckNextOwnerCopy")->setValue(LLSD(BOOL(next_owner_mask & PERM_COPY))); - getChild<LLUICtrl>("CheckNextOwnerTransfer")->setValue(LLSD(BOOL(next_owner_mask & PERM_TRANSFER))); - - if (is_for_sale) - { - S32 numerical_price; - numerical_price = sale_info.getSalePrice(); - edit_cost->setValue(llformat("%d",numerical_price)); - combo_sale_type->setValue(sale_info.getSaleType()); - } - else - { - edit_cost->setValue(llformat("%d",0)); - combo_sale_type->setValue(LLSaleInfo::FS_COPY); - } -} - -void LLFloaterProperties::onClickCreator() -{ - LLInventoryItem* item = findItem(); - if(!item) return; - if(!item->getCreatorUUID().isNull()) - { - LLAvatarActions::showProfile(item->getCreatorUUID()); - } -} - -// static -void LLFloaterProperties::onClickOwner() -{ - LLInventoryItem* item = findItem(); - if(!item) return; - if(item->getPermissions().isGroupOwned()) - { - LLGroupActions::show(item->getPermissions().getGroup()); - } - else - { - LLAvatarActions::showProfile(item->getPermissions().getOwner()); - } -} - -// static -void LLFloaterProperties::onCommitName() -{ - //LL_INFOS() << "LLFloaterProperties::onCommitName()" << LL_ENDL; - LLViewerInventoryItem* item = (LLViewerInventoryItem*)findItem(); - if(!item) - { - return; - } - LLLineEditor* labelItemName = getChild<LLLineEditor>("LabelItemName"); - - if(labelItemName&& - (item->getName() != labelItemName->getText()) && - (gAgent.allowOperation(PERM_MODIFY, item->getPermissions(), GP_OBJECT_MANIPULATE)) ) - { - LLPointer<LLViewerInventoryItem> new_item = new LLViewerInventoryItem(item); - new_item->rename(labelItemName->getText()); - if(mObjectID.isNull()) - { - new_item->updateServer(FALSE); - gInventory.updateItem(new_item); - gInventory.notifyObservers(); - } - else - { - LLViewerObject* object = gObjectList.findObject(mObjectID); - if(object) - { - object->updateInventory( - new_item, - TASK_INVENTORY_ITEM_KEY, - false); - } - } - } -} - -void LLFloaterProperties::onCommitDescription() -{ - //LL_INFOS() << "LLFloaterProperties::onCommitDescription()" << LL_ENDL; - LLViewerInventoryItem* item = (LLViewerInventoryItem*)findItem(); - if(!item) return; - - LLLineEditor* labelItemDesc = getChild<LLLineEditor>("LabelItemDesc"); - if(!labelItemDesc) - { - return; - } - if((item->getDescription() != labelItemDesc->getText()) && - (gAgent.allowOperation(PERM_MODIFY, item->getPermissions(), GP_OBJECT_MANIPULATE))) - { - LLPointer<LLViewerInventoryItem> new_item = new LLViewerInventoryItem(item); - - new_item->setDescription(labelItemDesc->getText()); - if(mObjectID.isNull()) - { - new_item->updateServer(FALSE); - gInventory.updateItem(new_item); - gInventory.notifyObservers(); - } - else - { - LLViewerObject* object = gObjectList.findObject(mObjectID); - if(object) - { - object->updateInventory( - new_item, - TASK_INVENTORY_ITEM_KEY, - false); - } - } - } -} - -// static -void LLFloaterProperties::onCommitPermissions() -{ - //LL_INFOS() << "LLFloaterProperties::onCommitPermissions()" << LL_ENDL; - LLViewerInventoryItem* item = (LLViewerInventoryItem*)findItem(); - if(!item) return; - LLPermissions perm(item->getPermissions()); - - - LLCheckBoxCtrl* CheckShareWithGroup = getChild<LLCheckBoxCtrl>("CheckShareWithGroup"); - - if(CheckShareWithGroup) - { - perm.setGroupBits(gAgent.getID(), gAgent.getGroupID(), - CheckShareWithGroup->get(), - PERM_MODIFY | PERM_MOVE | PERM_COPY); - } - LLCheckBoxCtrl* CheckEveryoneCopy = getChild<LLCheckBoxCtrl>("CheckEveryoneCopy"); - if(CheckEveryoneCopy) - { - perm.setEveryoneBits(gAgent.getID(), gAgent.getGroupID(), - CheckEveryoneCopy->get(), PERM_COPY); - } - - LLCheckBoxCtrl* CheckNextOwnerModify = getChild<LLCheckBoxCtrl>("CheckNextOwnerModify"); - if(CheckNextOwnerModify) - { - perm.setNextOwnerBits(gAgent.getID(), gAgent.getGroupID(), - CheckNextOwnerModify->get(), PERM_MODIFY); - } - LLCheckBoxCtrl* CheckNextOwnerCopy = getChild<LLCheckBoxCtrl>("CheckNextOwnerCopy"); - if(CheckNextOwnerCopy) - { - perm.setNextOwnerBits(gAgent.getID(), gAgent.getGroupID(), - CheckNextOwnerCopy->get(), PERM_COPY); - } - LLCheckBoxCtrl* CheckNextOwnerTransfer = getChild<LLCheckBoxCtrl>("CheckNextOwnerTransfer"); - if(CheckNextOwnerTransfer) - { - perm.setNextOwnerBits(gAgent.getID(), gAgent.getGroupID(), - CheckNextOwnerTransfer->get(), PERM_TRANSFER); - } - if(perm != item->getPermissions() - && item->isFinished()) - { - LLPointer<LLViewerInventoryItem> new_item = new LLViewerInventoryItem(item); - new_item->setPermissions(perm); - U32 flags = new_item->getFlags(); - // If next owner permissions have changed (and this is an object) - // then set the slam permissions flag so that they are applied on rez. - if((perm.getMaskNextOwner()!=item->getPermissions().getMaskNextOwner()) - && (item->getType() == LLAssetType::AT_OBJECT)) - { - flags |= LLInventoryItemFlags::II_FLAGS_OBJECT_SLAM_PERM; - } - // If everyone permissions have changed (and this is an object) - // then set the overwrite everyone permissions flag so they - // are applied on rez. - if ((perm.getMaskEveryone()!=item->getPermissions().getMaskEveryone()) - && (item->getType() == LLAssetType::AT_OBJECT)) - { - flags |= LLInventoryItemFlags::II_FLAGS_OBJECT_PERM_OVERWRITE_EVERYONE; - } - // If group permissions have changed (and this is an object) - // then set the overwrite group permissions flag so they - // are applied on rez. - if ((perm.getMaskGroup()!=item->getPermissions().getMaskGroup()) - && (item->getType() == LLAssetType::AT_OBJECT)) - { - flags |= LLInventoryItemFlags::II_FLAGS_OBJECT_PERM_OVERWRITE_GROUP; - } - new_item->setFlags(flags); - if(mObjectID.isNull()) - { - new_item->updateServer(FALSE); - gInventory.updateItem(new_item); - gInventory.notifyObservers(); - } - else - { - LLViewerObject* object = gObjectList.findObject(mObjectID); - if(object) - { - object->updateInventory( - new_item, - TASK_INVENTORY_ITEM_KEY, - false); - } - } - } - else - { - // need to make sure we don't just follow the click - refresh(); - } -} - -// static -void LLFloaterProperties::onCommitSaleInfo() -{ - //LL_INFOS() << "LLFloaterProperties::onCommitSaleInfo()" << LL_ENDL; - updateSaleInfo(); -} - -// static -void LLFloaterProperties::onCommitSaleType() -{ - //LL_INFOS() << "LLFloaterProperties::onCommitSaleType()" << LL_ENDL; - updateSaleInfo(); -} - -void LLFloaterProperties::updateSaleInfo() -{ - LLViewerInventoryItem* item = (LLViewerInventoryItem*)findItem(); - if(!item) return; - LLSaleInfo sale_info(item->getSaleInfo()); - if(!gAgent.allowOperation(PERM_TRANSFER, item->getPermissions(), GP_OBJECT_SET_SALE)) - { - getChild<LLUICtrl>("CheckPurchase")->setValue(LLSD((BOOL)FALSE)); - } - - if((BOOL)getChild<LLUICtrl>("CheckPurchase")->getValue()) - { - // turn on sale info - LLSaleInfo::EForSale sale_type = LLSaleInfo::FS_COPY; - - LLComboBox* combo_sale_type = getChild<LLComboBox>("ComboBoxSaleType"); - if (combo_sale_type) - { - sale_type = static_cast<LLSaleInfo::EForSale>(combo_sale_type->getValue().asInteger()); - } - - if (sale_type == LLSaleInfo::FS_COPY - && !gAgent.allowOperation(PERM_COPY, item->getPermissions(), - GP_OBJECT_SET_SALE)) - { - sale_type = LLSaleInfo::FS_ORIGINAL; - } - - - - S32 price = -1; - price = getChild<LLUICtrl>("Edit Cost")->getValue().asInteger();; - - // Invalid data - turn off the sale - if (price < 0) - { - sale_type = LLSaleInfo::FS_NOT; - price = 0; - } - - sale_info.setSaleType(sale_type); - sale_info.setSalePrice(price); - } - else - { - sale_info.setSaleType(LLSaleInfo::FS_NOT); - } - if(sale_info != item->getSaleInfo() - && item->isFinished()) - { - LLPointer<LLViewerInventoryItem> new_item = new LLViewerInventoryItem(item); - - // Force an update on the sale price at rez - if (item->getType() == LLAssetType::AT_OBJECT) - { - U32 flags = new_item->getFlags(); - flags |= LLInventoryItemFlags::II_FLAGS_OBJECT_SLAM_SALE; - new_item->setFlags(flags); - } - - new_item->setSaleInfo(sale_info); - if(mObjectID.isNull()) - { - // This is in the agent's inventory. - new_item->updateServer(FALSE); - gInventory.updateItem(new_item); - gInventory.notifyObservers(); - } - else - { - // This is in an object's contents. - LLViewerObject* object = gObjectList.findObject(mObjectID); - if(object) - { - object->updateInventory( - new_item, - TASK_INVENTORY_ITEM_KEY, - false); - } - } - } - else - { - // need to make sure we don't just follow the click - refresh(); - } -} - -LLInventoryItem* LLFloaterProperties::findItem() const -{ - LLInventoryItem* item = NULL; - if(mObjectID.isNull()) - { - // it is in agent inventory - item = gInventory.getItem(mItemID); - } - else - { - LLViewerObject* object = gObjectList.findObject(mObjectID); - if(object) - { - item = (LLInventoryItem*)object->getInventoryObject(mItemID); - } - } - return item; -} - -//static -void LLFloaterProperties::dirtyAll() -{ - LLFloaterReg::const_instance_list_t& inst_list = LLFloaterReg::getFloaterList("properties"); - for (LLFloaterReg::const_instance_list_t::const_iterator iter = inst_list.begin(); - iter != inst_list.end(); ++iter) - { - LLFloaterProperties* floater = dynamic_cast<LLFloaterProperties*>(*iter); - llassert(floater); // else cast failed - wrong type D: - if (floater) - { - floater->dirty(); - } - } -} - -///---------------------------------------------------------------------------- -/// LLMultiProperties -///---------------------------------------------------------------------------- - -LLMultiProperties::LLMultiProperties() - : LLMultiFloater(LLSD()) -{ - // start with a small rect in the top-left corner ; will get resized - LLRect rect; - rect.setLeftTopAndSize(0, gViewerWindow->getWindowHeightScaled(), 20, 20); - setRect(rect); - LLFloater* last_floater = LLFloaterReg::getLastFloaterInGroup("properties"); - if (last_floater) - { - stackWith(*last_floater); - } - setTitle(LLTrans::getString("MultiPropertiesTitle")); - buildTabContainer(); -} - -///---------------------------------------------------------------------------- -/// Local function definitions -///---------------------------------------------------------------------------- diff --git a/indra/newview/llfloaterproperties.h b/indra/newview/llfloaterproperties.h deleted file mode 100644 index aa3fcec337..0000000000 --- a/indra/newview/llfloaterproperties.h +++ /dev/null @@ -1,98 +0,0 @@ -/** - * @file llfloaterproperties.h - * @brief A floater which shows an inventory item's properties. - * - * $LicenseInfo:firstyear=2002&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA - * $/LicenseInfo$ - */ - -#ifndef LL_LLFLOATERPROPERTIES_H -#define LL_LLFLOATERPROPERTIES_H - -#include <map> -#include "llmultifloater.h" -#include "lliconctrl.h" - -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// Class LLFloaterProperties -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -class LLButton; -class LLCheckBoxCtrl; -class LLInventoryItem; -class LLLineEditor; -class LLRadioGroup; -class LLTextBox; - -class LLPropertiesObserver; - -class LLFloaterProperties : public LLFloater -{ -public: - LLFloaterProperties(const LLUUID& item_id); - /*virtual*/ ~LLFloaterProperties(); - - /*virtual*/ BOOL postBuild(); - /*virtual*/ void onOpen(const LLSD& key); - void setObjectID(const LLUUID& object_id) { mObjectID = object_id; } - - void dirty() { mDirty = TRUE; } - void refresh(); - - static void dirtyAll(); - -protected: - // ui callbacks - void onClickCreator(); - void onClickOwner(); - void onCommitName(); - void onCommitDescription(); - void onCommitPermissions(); - void onCommitSaleInfo(); - void onCommitSaleType(); - void updateSaleInfo(); - - LLInventoryItem* findItem() const; - - void refreshFromItem(LLInventoryItem* item); - virtual void draw(); - -protected: - // The item id of the inventory item in question. - LLUUID mItemID; - - // mObjectID will have a value if it is associated with a task in - // the world, and will be == LLUUID::null if it's in the agent - // inventory. - LLUUID mObjectID; - - BOOL mDirty; - - LLPropertiesObserver* mPropertiesObserver; -}; - -class LLMultiProperties : public LLMultiFloater -{ -public: - LLMultiProperties(); -}; - -#endif // LL_LLFLOATERPROPERTIES_H diff --git a/indra/newview/llfloatersimpleoutfitsnapshot.cpp b/indra/newview/llfloatersimpleoutfitsnapshot.cpp deleted file mode 100644 index bab2efbbd5..0000000000 --- a/indra/newview/llfloatersimpleoutfitsnapshot.cpp +++ /dev/null @@ -1,333 +0,0 @@ -/** -* @file llfloatersimpleoutfitsnapshot.cpp -* @brief Snapshot preview window for saving as an outfit thumbnail in visual outfit gallery -* -* $LicenseInfo:firstyear=2022&license=viewerlgpl$ -* Second Life Viewer Source Code -* Copyright (C) 2022, Linden Research, Inc. -* -* This library is free software; you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation; -* version 2.1 of the License only. -* -* This library is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -* Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General Public -* License along with this library; if not, write to the Free Software -* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -* -* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA -* $/LicenseInfo$ -*/ - -#include "llviewerprecompiledheaders.h" - -#include "llfloatersimpleoutfitsnapshot.h" - -#include "llfloaterreg.h" -#include "llimagefiltersmanager.h" -#include "llstatusbar.h" // can_afford_transaction() -#include "llnotificationsutil.h" -#include "llagentbenefits.h" -#include "llviewercontrol.h" - -LLSimpleOutfitSnapshotFloaterView* gSimpleOutfitSnapshotFloaterView = NULL; - -const S32 OUTFIT_SNAPSHOT_WIDTH = 256; -const S32 OUTFIT_SNAPSHOT_HEIGHT = 256; - -static LLDefaultChildRegistry::Register<LLSimpleOutfitSnapshotFloaterView> r("simple_snapshot_outfit_floater_view"); - -///---------------------------------------------------------------------------- -/// Class LLFloaterSimpleOutfitSnapshot::Impl -///---------------------------------------------------------------------------- - -LLSnapshotModel::ESnapshotFormat LLFloaterSimpleOutfitSnapshot::Impl::getImageFormat(LLFloaterSnapshotBase* floater) -{ - return LLSnapshotModel::SNAPSHOT_FORMAT_PNG; -} - -LLSnapshotModel::ESnapshotLayerType LLFloaterSimpleOutfitSnapshot::Impl::getLayerType(LLFloaterSnapshotBase* floater) -{ - return LLSnapshotModel::SNAPSHOT_TYPE_COLOR; -} - -void LLFloaterSimpleOutfitSnapshot::Impl::updateControls(LLFloaterSnapshotBase* floater) -{ - LLSnapshotLivePreview* previewp = getPreviewView(); - updateResolution(floater); - if (previewp) - { - previewp->setSnapshotType(LLSnapshotModel::ESnapshotType::SNAPSHOT_TEXTURE); - previewp->setSnapshotFormat(LLSnapshotModel::ESnapshotFormat::SNAPSHOT_FORMAT_PNG); - previewp->setSnapshotBufferType(LLSnapshotModel::ESnapshotLayerType::SNAPSHOT_TYPE_COLOR); - } -} - -std::string LLFloaterSimpleOutfitSnapshot::Impl::getSnapshotPanelPrefix() -{ - return "panel_outfit_snapshot_"; -} - -void LLFloaterSimpleOutfitSnapshot::Impl::updateResolution(void* data) -{ - LLFloaterSimpleOutfitSnapshot *view = (LLFloaterSimpleOutfitSnapshot *)data; - - if (!view) - { - llassert(view); - return; - } - - S32 width = OUTFIT_SNAPSHOT_WIDTH; - S32 height = OUTFIT_SNAPSHOT_HEIGHT; - - LLSnapshotLivePreview* previewp = getPreviewView(); - if (previewp) - { - S32 original_width = 0, original_height = 0; - previewp->getSize(original_width, original_height); - - if (gSavedSettings.getBOOL("RenderHUDInSnapshot")) - { //clamp snapshot resolution to window size when showing UI HUD in snapshot - width = llmin(width, gViewerWindow->getWindowWidthRaw()); - height = llmin(height, gViewerWindow->getWindowHeightRaw()); - } - - llassert(width > 0 && height > 0); - - previewp->setSize(width, height); - - if (original_width != width || original_height != height) - { - // hide old preview as the aspect ratio could be wrong - checkAutoSnapshot(previewp, FALSE); - previewp->updateSnapshot(TRUE); - } - } -} - -void LLFloaterSimpleOutfitSnapshot::Impl::setStatus(EStatus status, bool ok, const std::string& msg) -{ - switch (status) - { - case STATUS_READY: - mFloater->setCtrlsEnabled(true); - break; - case STATUS_WORKING: - mFloater->setCtrlsEnabled(false); - break; - case STATUS_FINISHED: - mFloater->setCtrlsEnabled(true); - break; - } - - mStatus = status; -} - -///----------------------------------------------------------------re------------ -/// Class LLFloaterSimpleOutfitSnapshot -///---------------------------------------------------------------------------- - -LLFloaterSimpleOutfitSnapshot::LLFloaterSimpleOutfitSnapshot(const LLSD& key) - : LLFloaterSnapshotBase(key), - mOutfitGallery(NULL) -{ - impl = new Impl(this); -} - -LLFloaterSimpleOutfitSnapshot::~LLFloaterSimpleOutfitSnapshot() -{ -} - -BOOL LLFloaterSimpleOutfitSnapshot::postBuild() -{ - getChild<LLUICtrl>("save_btn")->setLabelArg("[UPLOAD_COST]", std::to_string(LLAgentBenefitsMgr::current().getTextureUploadCost())); - - childSetAction("new_snapshot_btn", ImplBase::onClickNewSnapshot, this); - childSetAction("save_btn", boost::bind(&LLFloaterSimpleOutfitSnapshot::onSend, this)); - childSetAction("cancel_btn", boost::bind(&LLFloaterSimpleOutfitSnapshot::onCancel, this)); - - mThumbnailPlaceholder = getChild<LLUICtrl>("thumbnail_placeholder"); - - // create preview window - LLRect full_screen_rect = getRootView()->getRect(); - LLSnapshotLivePreview::Params p; - p.rect(full_screen_rect); - LLSnapshotLivePreview* previewp = new LLSnapshotLivePreview(p); - LLView* parent_view = gSnapshotFloaterView->getParent(); - - parent_view->removeChild(gSnapshotFloaterView); - // make sure preview is below snapshot floater - parent_view->addChild(previewp); - parent_view->addChild(gSnapshotFloaterView); - - //move snapshot floater to special purpose snapshotfloaterview - gFloaterView->removeChild(this); - gSnapshotFloaterView->addChild(this); - - impl->mPreviewHandle = previewp->getHandle(); - previewp->setContainer(this); - impl->updateControls(this); - impl->setAdvanced(true); - impl->setSkipReshaping(true); - - previewp->mKeepAspectRatio = FALSE; - previewp->setThumbnailPlaceholderRect(getThumbnailPlaceholderRect()); - previewp->setAllowRenderUI(false); - - return TRUE; -} -const S32 PREVIEW_OFFSET_X = 12; -const S32 PREVIEW_OFFSET_Y = 70; - -void LLFloaterSimpleOutfitSnapshot::draw() -{ - LLSnapshotLivePreview* previewp = getPreviewView(); - - if (previewp && (previewp->isSnapshotActive() || previewp->getThumbnailLock())) - { - // don't render snapshot window in snapshot, even if "show ui" is turned on - return; - } - - LLFloater::draw(); - - if (previewp && !isMinimized() && mThumbnailPlaceholder->getVisible()) - { - if(previewp->getThumbnailImage()) - { - bool working = impl->getStatus() == ImplBase::STATUS_WORKING; - const LLRect& thumbnail_rect = getThumbnailPlaceholderRect(); - const S32 thumbnail_w = previewp->getThumbnailWidth(); - const S32 thumbnail_h = previewp->getThumbnailHeight(); - - S32 offset_x = PREVIEW_OFFSET_X; - S32 offset_y = PREVIEW_OFFSET_Y; - - gGL.matrixMode(LLRender::MM_MODELVIEW); - // Apply floater transparency to the texture unless the floater is focused. - F32 alpha = getTransparencyType() == TT_ACTIVE ? 1.0f : getCurrentTransparency(); - LLColor4 color = working ? LLColor4::grey4 : LLColor4::white; - gl_draw_scaled_image(offset_x, offset_y, - thumbnail_w, thumbnail_h, - previewp->getThumbnailImage(), color % alpha); -#if LL_DARWIN - std::string alpha_color = getTransparencyType() == TT_ACTIVE ? "OutfitSnapshotMacMask" : "OutfitSnapshotMacMask2"; -#else - std::string alpha_color = getTransparencyType() == TT_ACTIVE ? "FloaterFocusBackgroundColor" : "DkGray"; -#endif - - previewp->drawPreviewRect(offset_x, offset_y, LLUIColorTable::instance().getColor(alpha_color)); - - gGL.pushUIMatrix(); - LLUI::translate((F32) thumbnail_rect.mLeft, (F32) thumbnail_rect.mBottom); - mThumbnailPlaceholder->draw(); - gGL.popUIMatrix(); - } - } - impl->updateLayout(this); -} - -void LLFloaterSimpleOutfitSnapshot::onOpen(const LLSD& key) -{ - LLSnapshotLivePreview* preview = getPreviewView(); - if (preview) - { - preview->updateSnapshot(TRUE); - } - focusFirstItem(FALSE); - gSnapshotFloaterView->setEnabled(TRUE); - gSnapshotFloaterView->setVisible(TRUE); - gSnapshotFloaterView->adjustToFitScreen(this, FALSE); - - impl->updateControls(this); - impl->setStatus(ImplBase::STATUS_READY); -} - -void LLFloaterSimpleOutfitSnapshot::onCancel() -{ - closeFloater(); -} - -void LLFloaterSimpleOutfitSnapshot::onSend() -{ - S32 expected_upload_cost = LLAgentBenefitsMgr::current().getTextureUploadCost(); - if (can_afford_transaction(expected_upload_cost)) - { - saveTexture(); - postSave(); - } - else - { - LLSD args; - args["COST"] = llformat("%d", expected_upload_cost); - LLNotificationsUtil::add("ErrorPhotoCannotAfford", args); - inventorySaveFailed(); - } -} - -void LLFloaterSimpleOutfitSnapshot::postSave() -{ - impl->setStatus(ImplBase::STATUS_WORKING); -} - -// static -void LLFloaterSimpleOutfitSnapshot::update() -{ - LLFloaterSimpleOutfitSnapshot* inst = findInstance(); - if (inst != NULL) - { - inst->impl->updateLivePreview(); - } -} - - -// static -LLFloaterSimpleOutfitSnapshot* LLFloaterSimpleOutfitSnapshot::findInstance() -{ - return LLFloaterReg::findTypedInstance<LLFloaterSimpleOutfitSnapshot>("simple_outfit_snapshot"); -} - -// static -LLFloaterSimpleOutfitSnapshot* LLFloaterSimpleOutfitSnapshot::getInstance() -{ - return LLFloaterReg::getTypedInstance<LLFloaterSimpleOutfitSnapshot>("simple_outfit_snapshot"); -} - -void LLFloaterSimpleOutfitSnapshot::saveTexture() -{ - LLSnapshotLivePreview* previewp = getPreviewView(); - if (!previewp) - { - llassert(previewp != NULL); - return; - } - - if (mOutfitGallery) - { - mOutfitGallery->onBeforeOutfitSnapshotSave(); - } - previewp->saveTexture(TRUE, getOutfitID().asString()); - if (mOutfitGallery) - { - mOutfitGallery->onAfterOutfitSnapshotSave(); - } - closeFloater(); -} - -///---------------------------------------------------------------------------- -/// Class LLSimpleOutfitSnapshotFloaterView -///---------------------------------------------------------------------------- - -LLSimpleOutfitSnapshotFloaterView::LLSimpleOutfitSnapshotFloaterView(const Params& p) : LLFloaterView(p) -{ -} - -LLSimpleOutfitSnapshotFloaterView::~LLSimpleOutfitSnapshotFloaterView() -{ -} diff --git a/indra/newview/llfloatersimplesnapshot.cpp b/indra/newview/llfloatersimplesnapshot.cpp new file mode 100644 index 0000000000..83f4f1ace9 --- /dev/null +++ b/indra/newview/llfloatersimplesnapshot.cpp @@ -0,0 +1,468 @@ +/** +* @file llfloatersimplesnapshot.cpp +* @brief Snapshot preview window for saving as a thumbnail +* +* $LicenseInfo:firstyear=2022&license=viewerlgpl$ +* Second Life Viewer Source Code +* Copyright (C) 2022, Linden Research, Inc. +* +* This library is free software; you can redistribute it and/or +* modify it under the terms of the GNU Lesser General Public +* License as published by the Free Software Foundation; +* version 2.1 of the License only. +* +* This library is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public +* License along with this library; if not, write to the Free Software +* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +* +* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA +* $/LicenseInfo$ +*/ + +#include "llviewerprecompiledheaders.h" + +#include "llfloatersimplesnapshot.h" + +#include "llfloaterreg.h" +#include "llimagefiltersmanager.h" +#include "llinventorymodel.h" +#include "llstatusbar.h" // can_afford_transaction() +#include "llnotificationsutil.h" +#include "llagent.h" +#include "llagentbenefits.h" +#include "llviewercontrol.h" +#include "llviewertexturelist.h" + + + +LLSimpleSnapshotFloaterView* gSimpleSnapshotFloaterView = NULL; + +const S32 LLFloaterSimpleSnapshot::THUMBNAIL_SNAPSHOT_DIM_MAX = 256; +const S32 LLFloaterSimpleSnapshot::THUMBNAIL_SNAPSHOT_DIM_MIN = 64; + +// Thumbnail posting coro + +static const std::string THUMBNAIL_ITEM_UPLOAD_CAP = "InventoryItemThumbnailUpload"; +static const std::string THUMBNAIL_CATEGORY_UPLOAD_CAP = "InventoryCategoryThumbnailUpload"; + +void post_thumbnail_image_coro(std::string cap_url, std::string path_to_image, LLSD first_data) +{ + LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID); + LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t + httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("post_profile_image_coro", httpPolicy)); + LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest); + LLCore::HttpHeaders::ptr_t httpHeaders; + + LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions); + httpOpts->setFollowRedirects(true); + + LLSD result = httpAdapter->postAndSuspend(httpRequest, cap_url, first_data, httpOpts, httpHeaders); + + LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS]; + LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults); + + if (!status) + { + // todo: notification? + LL_WARNS("AvatarProperties") << "Failed to get uploader cap " << status.toString() << LL_ENDL; + return; + } + if (!result.has("uploader")) + { + // todo: notification? + LL_WARNS("AvatarProperties") << "Failed to get uploader cap, response contains no data." << LL_ENDL; + return; + } + std::string uploader_cap = result["uploader"].asString(); + if (uploader_cap.empty()) + { + LL_WARNS("AvatarProperties") << "Failed to get uploader cap, cap invalid." << LL_ENDL; + return; + } + + // Upload the image + + LLCore::HttpRequest::ptr_t uploaderhttpRequest(new LLCore::HttpRequest); + LLCore::HttpHeaders::ptr_t uploaderhttpHeaders(new LLCore::HttpHeaders); + LLCore::HttpOptions::ptr_t uploaderhttpOpts(new LLCore::HttpOptions); + S64 length; + + { + llifstream instream(path_to_image.c_str(), std::iostream::binary | std::iostream::ate); + if (!instream.is_open()) + { + LL_WARNS("AvatarProperties") << "Failed to open file " << path_to_image << LL_ENDL; + return; + } + length = instream.tellg(); + } + + uploaderhttpHeaders->append(HTTP_OUT_HEADER_CONTENT_TYPE, "application/jp2"); // optional + uploaderhttpHeaders->append(HTTP_OUT_HEADER_CONTENT_LENGTH, llformat("%d", length)); // required! + uploaderhttpOpts->setFollowRedirects(true); + + result = httpAdapter->postFileAndSuspend(uploaderhttpRequest, uploader_cap, path_to_image, uploaderhttpOpts, uploaderhttpHeaders); + + httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS]; + status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults); + + LL_DEBUGS("Thumbnail") << result << LL_ENDL; + + if (!status) + { + LL_WARNS("Thumbnail") << "Failed to upload image " << status.toString() << LL_ENDL; + return; + } + + if (result["state"].asString() != "complete") + { + if (result.has("message")) + { + LL_WARNS("Thumbnail") << "Failed to upload image, state " << result["state"] << " message: " << result["message"] << LL_ENDL; + } + else + { + LL_WARNS("Thumbnail") << "Failed to upload image " << result << LL_ENDL; + } + return; + } + + // todo: issue an inventory udpate? + //return result["new_asset"].asUUID(); +} + +///---------------------------------------------------------------------------- +/// Class LLFloaterSimpleSnapshot::Impl +///---------------------------------------------------------------------------- + +LLSnapshotModel::ESnapshotFormat LLFloaterSimpleSnapshot::Impl::getImageFormat(LLFloaterSnapshotBase* floater) +{ + return LLSnapshotModel::SNAPSHOT_FORMAT_PNG; +} + +LLSnapshotModel::ESnapshotLayerType LLFloaterSimpleSnapshot::Impl::getLayerType(LLFloaterSnapshotBase* floater) +{ + return LLSnapshotModel::SNAPSHOT_TYPE_COLOR; +} + +void LLFloaterSimpleSnapshot::Impl::updateControls(LLFloaterSnapshotBase* floater) +{ + LLSnapshotLivePreview* previewp = getPreviewView(); + updateResolution(floater); + if (previewp) + { + previewp->setSnapshotType(LLSnapshotModel::ESnapshotType::SNAPSHOT_TEXTURE); + previewp->setSnapshotFormat(LLSnapshotModel::ESnapshotFormat::SNAPSHOT_FORMAT_PNG); + previewp->setSnapshotBufferType(LLSnapshotModel::ESnapshotLayerType::SNAPSHOT_TYPE_COLOR); + } +} + +std::string LLFloaterSimpleSnapshot::Impl::getSnapshotPanelPrefix() +{ + return "panel_outfit_snapshot_"; +} + +void LLFloaterSimpleSnapshot::Impl::updateResolution(void* data) +{ + LLFloaterSimpleSnapshot *view = (LLFloaterSimpleSnapshot *)data; + + if (!view) + { + llassert(view); + return; + } + + S32 width = THUMBNAIL_SNAPSHOT_DIM_MAX; + S32 height = THUMBNAIL_SNAPSHOT_DIM_MAX; + + LLSnapshotLivePreview* previewp = getPreviewView(); + if (previewp) + { + S32 original_width = 0, original_height = 0; + previewp->getSize(original_width, original_height); + + if (gSavedSettings.getBOOL("RenderHUDInSnapshot")) + { //clamp snapshot resolution to window size when showing UI HUD in snapshot + width = llmin(width, gViewerWindow->getWindowWidthRaw()); + height = llmin(height, gViewerWindow->getWindowHeightRaw()); + } + + llassert(width > 0 && height > 0); + + previewp->setSize(width, height); + + if (original_width != width || original_height != height) + { + // hide old preview as the aspect ratio could be wrong + checkAutoSnapshot(previewp, FALSE); + previewp->updateSnapshot(TRUE); + } + } +} + +void LLFloaterSimpleSnapshot::Impl::setStatus(EStatus status, bool ok, const std::string& msg) +{ + switch (status) + { + case STATUS_READY: + mFloater->setCtrlsEnabled(true); + break; + case STATUS_WORKING: + mFloater->setCtrlsEnabled(false); + break; + case STATUS_FINISHED: + mFloater->setCtrlsEnabled(true); + break; + } + + mStatus = status; +} + +///----------------------------------------------------------------re------------ +/// Class LLFloaterSimpleSnapshot +///---------------------------------------------------------------------------- + +LLFloaterSimpleSnapshot::LLFloaterSimpleSnapshot(const LLSD& key) + : LLFloaterSnapshotBase(key) + , mOwner(NULL) + , mContextConeOpacity(0.f) +{ + impl = new Impl(this); +} + +LLFloaterSimpleSnapshot::~LLFloaterSimpleSnapshot() +{ +} + +BOOL LLFloaterSimpleSnapshot::postBuild() +{ + childSetAction("new_snapshot_btn", ImplBase::onClickNewSnapshot, this); + childSetAction("save_btn", boost::bind(&LLFloaterSimpleSnapshot::onSend, this)); + childSetAction("cancel_btn", boost::bind(&LLFloaterSimpleSnapshot::onCancel, this)); + + mThumbnailPlaceholder = getChild<LLUICtrl>("thumbnail_placeholder"); + + // create preview window + LLRect full_screen_rect = getRootView()->getRect(); + LLSnapshotLivePreview::Params p; + p.rect(full_screen_rect); + LLSnapshotLivePreview* previewp = new LLSnapshotLivePreview(p); + + // Do not move LLFloaterSimpleSnapshot floater into gSnapshotFloaterView + // since it can be a dependednt floater and does not draw UI + + impl->mPreviewHandle = previewp->getHandle(); + previewp->setContainer(this); + impl->updateControls(this); + impl->setAdvanced(true); + impl->setSkipReshaping(true); + + previewp->mKeepAspectRatio = FALSE; + previewp->setThumbnailPlaceholderRect(getThumbnailPlaceholderRect()); + previewp->setAllowRenderUI(false); + previewp->setThumbnailSubsampled(TRUE); + + return TRUE; +} + +const S32 PREVIEW_OFFSET_Y = 70; + +void LLFloaterSimpleSnapshot::draw() +{ + if (mOwner) + { + static LLCachedControl<F32> max_opacity(gSavedSettings, "PickerContextOpacity", 0.4f); + drawConeToOwner(mContextConeOpacity, max_opacity, mOwner); + } + + LLSnapshotLivePreview* previewp = getPreviewView(); + + if (previewp && (previewp->isSnapshotActive() || previewp->getThumbnailLock())) + { + // don't render snapshot window in snapshot, even if "show ui" is turned on + return; + } + + LLFloater::draw(); + + if (previewp && !isMinimized() && mThumbnailPlaceholder->getVisible()) + { + if(previewp->getThumbnailImage()) + { + bool working = impl->getStatus() == ImplBase::STATUS_WORKING; + const S32 thumbnail_w = previewp->getThumbnailWidth(); + const S32 thumbnail_h = previewp->getThumbnailHeight(); + + LLRect local_rect = getLocalRect(); + S32 offset_x = (local_rect.getWidth() - thumbnail_w) / 2; + S32 offset_y = PREVIEW_OFFSET_Y; + + gGL.matrixMode(LLRender::MM_MODELVIEW); + // Apply floater transparency to the texture unless the floater is focused. + F32 alpha = getTransparencyType() == TT_ACTIVE ? 1.0f : getCurrentTransparency(); + LLColor4 color = working ? LLColor4::grey4 : LLColor4::white; + gl_draw_scaled_image(offset_x, offset_y, + thumbnail_w, thumbnail_h, + previewp->getThumbnailImage(), color % alpha); + } + } + impl->updateLayout(this); +} + +void LLFloaterSimpleSnapshot::onOpen(const LLSD& key) +{ + LLSnapshotLivePreview* preview = getPreviewView(); + if (preview) + { + preview->updateSnapshot(TRUE); + } + focusFirstItem(FALSE); + gSnapshotFloaterView->setEnabled(TRUE); + gSnapshotFloaterView->setVisible(TRUE); + gSnapshotFloaterView->adjustToFitScreen(this, FALSE); + + impl->updateControls(this); + impl->setStatus(ImplBase::STATUS_READY); + + mInventoryId = key["item_id"].asUUID(); + mTaskId = key["task_id"].asUUID(); +} + +void LLFloaterSimpleSnapshot::onCancel() +{ + closeFloater(); +} + +void LLFloaterSimpleSnapshot::onSend() +{ + LLSnapshotLivePreview* previewp = getPreviewView(); + + std::string temp_file = gDirUtilp->getTempFilename(); + if (previewp->createUploadFile(temp_file, THUMBNAIL_SNAPSHOT_DIM_MAX, THUMBNAIL_SNAPSHOT_DIM_MIN)) + { + uploadImageUploadFile(temp_file, mInventoryId, mTaskId); + } + else + { + LLSD notif_args; + notif_args["REASON"] = LLImage::getLastError().c_str(); + LLNotificationsUtil::add("CannotUploadTexture", notif_args); + } +} + +void LLFloaterSimpleSnapshot::postSave() +{ + impl->setStatus(ImplBase::STATUS_WORKING); +} + +// static +void LLFloaterSimpleSnapshot::uploadThumbnail(const std::string &file_path, const LLUUID &inventory_id, const LLUUID &task_id) +{ + // generate a temp texture file for coroutine + std::string temp_file = gDirUtilp->getTempFilename(); + U32 codec = LLImageBase::getCodecFromExtension(gDirUtilp->getExtension(file_path)); + if (!LLViewerTextureList::createUploadFile(file_path, temp_file, codec, THUMBNAIL_SNAPSHOT_DIM_MAX, THUMBNAIL_SNAPSHOT_DIM_MIN)) + { + LLSD notif_args; + notif_args["REASON"] = LLImage::getLastError().c_str(); + LLNotificationsUtil::add("CannotUploadTexture", notif_args); + LL_WARNS("Thumbnail") << "Failed to upload thumbnail for " << inventory_id << " " << task_id << ", reason: " << notif_args["REASON"].asString() << LL_ENDL; + return; + } + uploadImageUploadFile(temp_file, inventory_id, task_id); +} + +// static +void LLFloaterSimpleSnapshot::uploadImageUploadFile(const std::string &temp_file, const LLUUID &inventory_id, const LLUUID &task_id) +{ + std::string cap_name; + LLSD data; + + if (task_id.notNull()) + { + cap_name = THUMBNAIL_ITEM_UPLOAD_CAP; + data["item_id"] = inventory_id; + data["task_id"] = task_id; + } + else if (gInventory.getCategory(inventory_id)) + { + cap_name = THUMBNAIL_CATEGORY_UPLOAD_CAP; + data["category_id"] = inventory_id; + } + else + { + cap_name = THUMBNAIL_ITEM_UPLOAD_CAP; + data["item_id"] = inventory_id; + } + + std::string cap_url = gAgent.getRegionCapability(cap_name); + if (cap_url.empty()) + { + LLSD args; + args["CAPABILITY"] = cap_url; + LLNotificationsUtil::add("RegionCapabilityRequestError", args); + LL_WARNS("Thumbnail") << "Failed to upload profile image for item " << inventory_id << " " << task_id << ", no cap found" << LL_ENDL; + return; + } + + LLCoros::instance().launch("postAgentUserImageCoro", + boost::bind(post_thumbnail_image_coro, cap_url, temp_file, data)); +} + +void LLFloaterSimpleSnapshot::update() +{ + // initializes snapshots when needed + LLFloaterReg::const_instance_list_t& inst_list = LLFloaterReg::getFloaterList("simple_snapshot"); + for (LLFloaterReg::const_instance_list_t::const_iterator iter = inst_list.begin(); + iter != inst_list.end(); ++iter) + { + LLFloaterSimpleSnapshot* floater = dynamic_cast<LLFloaterSimpleSnapshot*>(*iter); + if (floater) + { + floater->impl->updateLivePreview(); + } + } +} + + +// static +LLFloaterSimpleSnapshot* LLFloaterSimpleSnapshot::findInstance(const LLSD &key) +{ + return LLFloaterReg::findTypedInstance<LLFloaterSimpleSnapshot>("simple_snapshot", key); +} + +// static +LLFloaterSimpleSnapshot* LLFloaterSimpleSnapshot::getInstance(const LLSD &key) +{ + return LLFloaterReg::getTypedInstance<LLFloaterSimpleSnapshot>("simple_snapshot", key); +} + +void LLFloaterSimpleSnapshot::saveTexture() +{ + LLSnapshotLivePreview* previewp = getPreviewView(); + if (!previewp) + { + llassert(previewp != NULL); + return; + } + + previewp->saveTexture(TRUE, getInventoryId().asString()); + closeFloater(); +} + +///---------------------------------------------------------------------------- +/// Class LLSimpleOutfitSnapshotFloaterView +///---------------------------------------------------------------------------- + +LLSimpleSnapshotFloaterView::LLSimpleSnapshotFloaterView(const Params& p) : LLFloaterView(p) +{ +} + +LLSimpleSnapshotFloaterView::~LLSimpleSnapshotFloaterView() +{ +} diff --git a/indra/newview/llfloatersimpleoutfitsnapshot.h b/indra/newview/llfloatersimplesnapshot.h index cc9a6c5d1e..a2bf2946d4 100644 --- a/indra/newview/llfloatersimpleoutfitsnapshot.h +++ b/indra/newview/llfloatersimplesnapshot.h @@ -1,6 +1,6 @@ /** -* @file llfloatersimpleoutfitsnapshot.h -* @brief Snapshot preview window for saving as an outfit thumbnail in visual outfit gallery +* @file llfloatersimplesnapshot.h +* @brief Snapshot preview window for saving as a thumbnail * * $LicenseInfo:firstyear=2022&license=viewerlgpl$ * Second Life Viewer Source Code @@ -24,26 +24,25 @@ * $/LicenseInfo$ */ -#ifndef LL_LLFLOATERSIMPLEOUTFITSNAPSHOT_H -#define LL_LLFLOATERSIMPLEOUTFITSNAPSHOT_H +#ifndef LL_LLFLOATERSIMPLESNAPSHOT_H +#define LL_LLFLOATERSIMPLESNAPSHOT_H #include "llfloater.h" #include "llfloatersnapshot.h" -#include "lloutfitgallery.h" #include "llsnapshotlivepreview.h" ///---------------------------------------------------------------------------- -/// Class LLFloaterSimpleOutfitSnapshot +/// Class LLFloaterSimpleSnapshot ///---------------------------------------------------------------------------- -class LLFloaterSimpleOutfitSnapshot : public LLFloaterSnapshotBase +class LLFloaterSimpleSnapshot : public LLFloaterSnapshotBase { - LOG_CLASS(LLFloaterSimpleOutfitSnapshot); + LOG_CLASS(LLFloaterSimpleSnapshot); public: - LLFloaterSimpleOutfitSnapshot(const LLSD& key); - ~LLFloaterSimpleOutfitSnapshot(); + LLFloaterSimpleSnapshot(const LLSD& key); + ~LLFloaterSimpleSnapshot(); BOOL postBuild(); void onOpen(const LLSD& key); @@ -51,36 +50,47 @@ public: static void update(); - static LLFloaterSimpleOutfitSnapshot* getInstance(); - static LLFloaterSimpleOutfitSnapshot* findInstance(); + static LLFloaterSimpleSnapshot* getInstance(const LLSD &key); + static LLFloaterSimpleSnapshot* findInstance(const LLSD &key); void saveTexture(); const LLRect& getThumbnailPlaceholderRect() { return mThumbnailPlaceholder->getRect(); } - void setOutfitID(LLUUID id) { mOutfitID = id; } - LLUUID getOutfitID() { return mOutfitID; } - void setGallery(LLOutfitGallery* gallery) { mOutfitGallery = gallery; } + void setInventoryId(const LLUUID &inventory_id) { mInventoryId = inventory_id; } + LLUUID getInventoryId() { return mInventoryId; } + void setTaskId(const LLUUID &task_id) { mTaskId = task_id; } + void setOwner(LLView *owner_view) { mOwner = owner_view; } void postSave(); + static void uploadThumbnail(const std::string &file_path, const LLUUID &inventory_id, const LLUUID &task_id); class Impl; friend class Impl; + static const S32 THUMBNAIL_SNAPSHOT_DIM_MAX; + static const S32 THUMBNAIL_SNAPSHOT_DIM_MIN; + private: void onSend(); void onCancel(); - LLUUID mOutfitID; - LLOutfitGallery* mOutfitGallery; + // uploads upload-ready file + static void uploadImageUploadFile(const std::string &temp_file, const LLUUID &inventory_id, const LLUUID &task_id); + + LLUUID mInventoryId; + LLUUID mTaskId; + + LLView* mOwner; + F32 mContextConeOpacity; }; ///---------------------------------------------------------------------------- -/// Class LLFloaterSimpleOutfitSnapshot::Impl +/// Class LLFloaterSimpleSnapshot::Impl ///---------------------------------------------------------------------------- -class LLFloaterSimpleOutfitSnapshot::Impl : public LLFloaterSnapshotBase::ImplBase +class LLFloaterSimpleSnapshot::Impl : public LLFloaterSnapshotBase::ImplBase { - LOG_CLASS(LLFloaterSimpleOutfitSnapshot::Impl); + LOG_CLASS(LLFloaterSimpleSnapshot::Impl); public: Impl(LLFloaterSnapshotBase* floater) : LLFloaterSnapshotBase::ImplBase(floater) @@ -108,7 +118,7 @@ private: /// Class LLSimpleOutfitSnapshotFloaterView ///---------------------------------------------------------------------------- -class LLSimpleOutfitSnapshotFloaterView : public LLFloaterView +class LLSimpleSnapshotFloaterView : public LLFloaterView { public: struct Params @@ -117,13 +127,13 @@ public: }; protected: - LLSimpleOutfitSnapshotFloaterView(const Params& p); + LLSimpleSnapshotFloaterView(const Params& p); friend class LLUICtrlFactory; public: - virtual ~LLSimpleOutfitSnapshotFloaterView(); + virtual ~LLSimpleSnapshotFloaterView(); }; -extern LLSimpleOutfitSnapshotFloaterView* gSimpleOutfitSnapshotFloaterView; +extern LLSimpleSnapshotFloaterView* gSimpleOutfitSnapshotFloaterView; -#endif // LL_LLFLOATERSIMPLEOUTFITSNAPSHOT_H +#endif // LL_LLFLOATERSIMPLESNAPSHOT_H diff --git a/indra/newview/llfolderviewmodelinventory.h b/indra/newview/llfolderviewmodelinventory.h index de28091c32..1649b2eed7 100644 --- a/indra/newview/llfolderviewmodelinventory.h +++ b/indra/newview/llfolderviewmodelinventory.h @@ -39,12 +39,14 @@ class LLFolderViewModelItemInventory public: LLFolderViewModelItemInventory(class LLFolderViewModelInventory& root_view_model); virtual const LLUUID& getUUID() const = 0; + virtual const LLUUID& getThumbnailUUID() const = 0; virtual time_t getCreationDate() const = 0; // UTC seconds virtual void setCreationDate(time_t creation_date_utc) = 0; virtual PermissionMask getPermissionMask() const = 0; virtual LLFolderType::EType getPreferredType() const = 0; virtual void showProperties(void) = 0; virtual BOOL isItemInTrash( void) const { return FALSE; } // TODO: make into pure virtual. + virtual bool isItemInOutfits() const { return false; } virtual BOOL isAgentInventory() const { return FALSE; } virtual BOOL isUpToDate() const = 0; virtual void addChild(LLFolderViewModelItem* child); diff --git a/indra/newview/llinspectobject.cpp b/indra/newview/llinspectobject.cpp index 5329f10612..c52d0be213 100644 --- a/indra/newview/llinspectobject.cpp +++ b/indra/newview/llinspectobject.cpp @@ -662,9 +662,7 @@ void LLInspectObject::onClickOpen() void LLInspectObject::onClickMoreInfo() { - LLSD key; - key["task"] = "task"; - LLFloaterSidePanelContainer::showPanel("inventory", key); + LLFloaterReg::showInstance("task_properties"); closeFloater(); } diff --git a/indra/newview/llinspecttexture.cpp b/indra/newview/llinspecttexture.cpp index cd288e9603..2e8273d6cf 100644 --- a/indra/newview/llinspecttexture.cpp +++ b/indra/newview/llinspecttexture.cpp @@ -75,11 +75,11 @@ void LLInspectTexture::onOpen(const LLSD& sdData) // Start fade animation LLInspect::onOpen(sdData); - bool fIsAsset = sdData.has("asset_id"); + bool fIsAsset = sdData.has("thumbnail_id"); bool fIsInventory = sdData.has("item_id"); // Skip if we're being asked to display the same thing - const LLUUID idAsset = (fIsAsset) ? sdData["asset_id"].asUUID() : LLUUID::null; + const LLUUID idAsset = (fIsAsset) ? sdData["thumbnail_id"].asUUID() : LLUUID::null; const LLUUID idItem = (fIsInventory) ? sdData["item_id"].asUUID() : LLUUID::null; if ( (getVisible()) && ( ((fIsAsset) && (idAsset == mAssetId)) || ((fIsInventory) && (idItem == mItemId)) ) ) { @@ -134,33 +134,64 @@ BOOL LLInspectTexture::postBuild() // Helper functions // +class LLIsTextureType : public LLInventoryCollectFunctor +{ +public: + LLIsTextureType() {} + virtual ~LLIsTextureType() {} + virtual bool operator()(LLInventoryCategory* cat, + LLInventoryItem* item); +}; + +bool LLIsTextureType::operator()(LLInventoryCategory* cat, LLInventoryItem* item) +{ + return item && (item->getType() == LLAssetType::AT_TEXTURE); +} + LLToolTip* LLInspectTextureUtil::createInventoryToolTip(LLToolTip::Params p) { - const LLSD& sdTooltip = p.create_params; + const LLSD& sdTooltip = p.create_params; + + if (sdTooltip.has("thumbnail_id") && sdTooltip["thumbnail_id"].asUUID().notNull()) + { + // go straight for thumbnail regardless of type + return LLUICtrlFactory::create<LLTextureToolTip>(p); + } LLInventoryType::EType eInvType = (sdTooltip.has("inv_type")) ? (LLInventoryType::EType)sdTooltip["inv_type"].asInteger() : LLInventoryType::IT_NONE; switch (eInvType) { - case LLInventoryType::IT_SNAPSHOT: - case LLInventoryType::IT_TEXTURE: - return LLUICtrlFactory::create<LLTextureToolTip>(p); case LLInventoryType::IT_CATEGORY: { if (sdTooltip.has("item_id")) { const LLUUID idCategory = sdTooltip["item_id"].asUUID(); - - LLInventoryModel::cat_array_t cats; - LLInventoryModel::item_array_t items; - LLIsOfAssetType f(LLAssetType::AT_TEXTURE); - gInventory.getDirectDescendentsOf(idCategory, cats, items, f); - - // Exactly one texture found => show the texture tooltip - if (1 == items.size()) - { - p.create_params.getValue()["asset_id"] = items.front()->getAssetUUID(); - return LLUICtrlFactory::create<LLTextureToolTip>(p); - } + LLViewerInventoryCategory* cat = gInventory.getCategory(idCategory); + if (cat && cat->getPreferredType() == LLFolderType::FT_OUTFIT) + { + LLInventoryModel::cat_array_t cats; + LLInventoryModel::item_array_t items; + // Not LLIsOfAssetType, because we allow links + LLIsTextureType f; + gInventory.getDirectDescendentsOf(idCategory, cats, items, f); + + // Exactly one texture found => show the texture tooltip + if (1 == items.size()) + { + LLViewerInventoryItem* item = items.front(); + if (item && item->getIsLinkType()) + { + item = item->getLinkedItem(); + } + if (item) + { + // Note: LLFloaterChangeItemThumbnail will attempt to write this + // into folder's thumbnail id when opened + p.create_params.getValue()["thumbnail_id"] = item->getAssetUUID(); + return LLUICtrlFactory::create<LLTextureToolTip>(p); + } + } + } } // No or more than one texture found => show default tooltip @@ -277,23 +308,27 @@ LLTextureToolTip::~LLTextureToolTip() void LLTextureToolTip::initFromParams(const LLToolTip::Params& p) { - LLToolTip::initFromParams(p); - - // Create and add the preview control - LLView::Params p_preview; - p_preview.name = "texture_preview"; - LLRect rctPreview; - rctPreview.setOriginAndSize(mPadding, mTextBox->getRect().mTop, mPreviewSize, mPreviewSize); - p_preview.rect = rctPreview; - mPreviewView = LLUICtrlFactory::create<LLTexturePreviewView>(p_preview); - addChild(mPreviewView); - - // Parse the control params - const LLSD& sdTextureParams = p.create_params; - if (sdTextureParams.has("asset_id")) - mPreviewView->setImageFromAssetId(sdTextureParams["asset_id"].asUUID()); - else if (sdTextureParams.has("item_id")) - mPreviewView->setImageFromItemId(sdTextureParams["item_id"].asUUID()); + LLToolTip::initFromParams(p); + + // Create and add the preview control + LLView::Params p_preview; + p_preview.name = "texture_preview"; + LLRect rctPreview; + rctPreview.setOriginAndSize(mPadding, mTextBox->getRect().mTop, mPreviewSize, mPreviewSize); + p_preview.rect = rctPreview; + mPreviewView = LLUICtrlFactory::create<LLTexturePreviewView>(p_preview); + addChild(mPreviewView); + + // Parse the control params + const LLSD& sdTextureParams = p.create_params; + if (sdTextureParams.has("thumbnail_id")) + { + mPreviewView->setImageFromAssetId(sdTextureParams["thumbnail_id"].asUUID()); + } + else if (sdTextureParams.has("item_id")) + { + mPreviewView->setImageFromItemId(sdTextureParams["item_id"].asUUID()); + } snapToChildren(); } diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index db347f7096..5f1db0895c 100644 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -138,6 +138,12 @@ bool isMarketplaceSendAction(const std::string& action) return ("send_to_marketplace" == action); } +bool isPanelActive(const std::string& panel_name) +{ + LLInventoryPanel *active_panel = LLInventoryPanel::getActiveInventoryPanel(FALSE); + return (active_panel && (active_panel->getName() == panel_name)); +} + // Used by LLFolderBridge as callback for directory fetching recursion class LLRightClickInventoryFetchDescendentsObserver : public LLInventoryFetchDescendentsObserver { @@ -407,6 +413,32 @@ void LLInvFVBridge::showProperties() } } +void LLInvFVBridge::navigateToFolder(bool new_window, bool change_mode) +{ + if(new_window) + { + mInventoryPanel.get()->openSingleViewInventory(mUUID); + } + else + { + if(change_mode) + { + LLInventoryPanel::setSFViewAndOpenFolder(mInventoryPanel.get(), mUUID); + } + else + { + LLInventorySingleFolderPanel* panel = dynamic_cast<LLInventorySingleFolderPanel*>(mInventoryPanel.get()); + if (!panel || !getInventoryModel() || mUUID.isNull()) + { + return; + } + + panel->changeFolderRoot(mUUID); + } + + } +} + void LLInvFVBridge::removeBatch(std::vector<LLFolderViewModelItem*>& batch) { // Deactivate gestures when moving them into Trash @@ -853,6 +885,13 @@ void LLInvFVBridge::getClipboardEntries(bool show_asset_id, disabled_items.push_back(std::string("Rename")); } } + + LLViewerInventoryItem* inv_item = gInventory.getItem(mUUID); + items.push_back(std::string("thumbnail")); + if (inv_item && !inv_item->getPermissions().allowOperationBy(PERM_MODIFY, gAgent.getID())) + { + disabled_items.push_back(std::string("thumbnail")); + } if (show_asset_id) { @@ -860,7 +899,6 @@ void LLInvFVBridge::getClipboardEntries(bool show_asset_id, bool is_asset_knowable = false; - LLViewerInventoryItem* inv_item = gInventory.getItem(mUUID); if (inv_item) { is_asset_knowable = LLAssetType::lookupIsAssetIDKnowable(inv_item->getType()); @@ -921,14 +959,7 @@ void LLInvFVBridge::getClipboardEntries(bool show_asset_id, addDeleteContextMenuOptions(items, disabled_items); - // If multiple items are selected, disable properties (if it exists). - if ((flags & FIRST_SELECTED_ITEM) == 0) - { - disabled_items.push_back(std::string("Properties")); - } - - LLInventoryPanel *active_panel = LLInventoryPanel::getActiveInventoryPanel(FALSE); - if (active_panel && (active_panel->getName() != "All Items")) + if (!isPanelActive("All Items") && !isPanelActive("single_folder_inv")) { items.push_back(std::string("Show in Main Panel")); } @@ -1019,7 +1050,7 @@ void LLInvFVBridge::addDeleteContextMenuOptions(menuentry_vec_t &items, items.push_back(std::string("Delete")); - if (!isItemRemovable()) + if (!isItemRemovable() || isPanelActive("Favorite Items")) { disabled_items.push_back(std::string("Delete")); } @@ -1250,6 +1281,16 @@ BOOL LLInvFVBridge::isLinkedObjectInTrash() const return FALSE; } +bool LLInvFVBridge::isItemInOutfits() const +{ + const LLInventoryModel* model = getInventoryModel(); + if(!model) return false; + + const LLUUID my_outfits_cat = gInventory.findCategoryUUIDForType(LLFolderType::FT_MY_OUTFITS, false); + + return isCOFFolder() || (my_outfits_cat == mUUID) || model->isObjectDescendentOf(mUUID, my_outfits_cat); +} + BOOL LLInvFVBridge::isLinkedObjectMissing() const { const LLInventoryObject *obj = getInventoryObject(); @@ -1691,6 +1732,12 @@ void LLItemBridge::performAction(LLInventoryModel* model, std::string action) restoreItem(); return; } + else if ("thumbnail" == action) + { + LLSD data(mUUID); + LLFloaterReg::showInstance("change_item_thumbnail", data); + return; + } else if ("copy_uuid" == action) { // Single item only @@ -1959,9 +2006,9 @@ std::string LLItemBridge::getLabelSuffix() const { // String table is loaded before login screen and inventory items are // loaded after login, so LLTrans should be ready. - static std::string NO_COPY = LLTrans::getString("no_copy"); - static std::string NO_MOD = LLTrans::getString("no_modify"); - static std::string NO_XFER = LLTrans::getString("no_transfer"); + static std::string NO_COPY = LLTrans::getString("no_copy_lbl"); + static std::string NO_MOD = LLTrans::getString("no_modify_lbl"); + static std::string NO_XFER = LLTrans::getString("no_transfer_lbl"); static std::string LINK = LLTrans::getString("link"); static std::string BROKEN_LINK = LLTrans::getString("broken_link"); std::string suffix; @@ -1982,17 +2029,20 @@ std::string LLItemBridge::getLabelSuffix() const BOOL copy = item->getPermissions().allowCopyBy(gAgent.getID()); if (!copy) { + suffix += " "; suffix += NO_COPY; } BOOL mod = item->getPermissions().allowModifyBy(gAgent.getID()); if (!mod) { - suffix += NO_MOD; + suffix += suffix.empty() ? " " : ","; + suffix += NO_MOD; } BOOL xfer = item->getPermissions().allowOperationBy(PERM_TRANSFER, gAgent.getID()); if (!xfer) { + suffix += suffix.empty() ? " " : ","; suffix += NO_XFER; } } @@ -2161,6 +2211,21 @@ LLViewerInventoryItem* LLItemBridge::getItem() const return item; } +const LLUUID& LLItemBridge::getThumbnailUUID() const +{ + LLViewerInventoryItem* item = NULL; + LLInventoryModel* model = getInventoryModel(); + if(model) + { + item = (LLViewerInventoryItem*)model->getItem(mUUID); + } + if (item) + { + return item->getThumbnailUUID(); + } + return LLUUID::null; +} + BOOL LLItemBridge::isItemPermissive() const { LLViewerInventoryItem* item = getItem(); @@ -3231,6 +3296,12 @@ void LLFolderBridge::performAction(LLInventoryModel* model, std::string action) return; } + else if ("thumbnail" == action) + { + LLSD data(mUUID); + LLFloaterReg::showInstance("change_item_thumbnail", data); + return; + } else if ("paste" == action) { pasteFromClipboard(); @@ -4077,12 +4148,6 @@ void LLFolderBridge::buildContextMenuOptions(U32 flags, menuentry_vec_t& items } disabled_items.push_back(std::string("New Folder")); - disabled_items.push_back(std::string("New Script")); - disabled_items.push_back(std::string("New Note")); - disabled_items.push_back(std::string("New Settings")); - disabled_items.push_back(std::string("New Gesture")); - disabled_items.push_back(std::string("New Clothes")); - disabled_items.push_back(std::string("New Body Parts")); disabled_items.push_back(std::string("upload_def")); } if (favorites == mUUID) @@ -4105,11 +4170,6 @@ void LLFolderBridge::buildContextMenuOptions(U32 flags, menuentry_vec_t& items if (getPreferredType() == LLFolderType::FT_MARKETPLACE_STOCK) { disabled_items.push_back(std::string("New Folder")); - disabled_items.push_back(std::string("New Script")); - disabled_items.push_back(std::string("New Note")); - disabled_items.push_back(std::string("New Gesture")); - disabled_items.push_back(std::string("New Clothes")); - disabled_items.push_back(std::string("New Body Parts")); disabled_items.push_back(std::string("upload_def")); } if (marketplace_listings_id == mUUID) @@ -4119,14 +4179,14 @@ void LLFolderBridge::buildContextMenuOptions(U32 flags, menuentry_vec_t& items disabled_items.push_back(std::string("Cut")); disabled_items.push_back(std::string("Delete")); } + + if (isPanelActive("Favorite Items")) + { + disabled_items.push_back(std::string("Delete")); + } if(trash_id == mUUID) { - bool is_recent_panel = false; - LLInventoryPanel *active_panel = LLInventoryPanel::getActiveInventoryPanel(FALSE); - if (active_panel && (active_panel->getName() == "Recent Items")) - { - is_recent_panel = true; - } + bool is_recent_panel = isPanelActive("Recent Items"); // This is the trash. items.push_back(std::string("Empty Trash")); @@ -4169,19 +4229,7 @@ void LLFolderBridge::buildContextMenuOptions(U32 flags, menuentry_vec_t& items } if (!isMarketplaceListingsFolder()) { - items.push_back(std::string("New Script")); - items.push_back(std::string("New Note")); - items.push_back(std::string("New Gesture")); - items.push_back(std::string("New Clothes")); - items.push_back(std::string("New Body Parts")); - items.push_back(std::string("New Settings")); items.push_back(std::string("upload_def")); - - if (!LLEnvironment::instance().isInventoryEnabled()) - { - disabled_items.push_back("New Settings"); - } - } } getClipboardEntries(false, items, disabled_items, flags); @@ -4347,6 +4395,17 @@ void LLFolderBridge::buildContextMenuFolderOptions(U32 flags, menuentry_vec_t& disabled_items.push_back(std::string("New folder from selected")); } + + if ((flags & ITEM_IN_MULTI_SELECTION) == 0) + { + items.push_back(std::string("open_in_new_window")); + items.push_back(std::string("Open Folder Separator")); + if(isPanelActive("single_folder_inv")) + { + items.push_back(std::string("open_in_current_window")); + } + } + #ifndef LL_RELEASE_FOR_DOWNLOAD if (LLFolderType::lookupIsProtectedType(type) && is_agent_inventory) { @@ -5975,7 +6034,7 @@ std::string LLCallingCardBridge::getLabelSuffix() const LLViewerInventoryItem* item = getItem(); if( item && LLAvatarTracker::instance().isBuddyOnline(item->getCreatorUUID()) ) { - return LLItemBridge::getLabelSuffix() + " (online)"; + return LLItemBridge::getLabelSuffix() + " online"; } else { @@ -7558,9 +7617,6 @@ class LLObjectBridgeAction: public LLInvFVBridgeAction public: virtual void doIt() { - /* - LLFloaterReg::showInstance("properties", mUUID); - */ LLInvFVBridgeAction::doIt(); } virtual ~LLObjectBridgeAction(){} diff --git a/indra/newview/llinventorybridge.h b/indra/newview/llinventorybridge.h index bdffecf1c6..958d284854 100644 --- a/indra/newview/llinventorybridge.h +++ b/indra/newview/llinventorybridge.h @@ -28,7 +28,6 @@ #define LL_LLINVENTORYBRIDGE_H #include "llcallingcard.h" -#include "llfloaterproperties.h" #include "llfolderviewmodel.h" #include "llinventorymodel.h" #include "llinventoryobserver.h" @@ -84,6 +83,7 @@ public: // LLInvFVBridge functionality //-------------------------------------------------------------------- virtual const LLUUID& getUUID() const { return mUUID; } + virtual const LLUUID& getThumbnailUUID() const { return LLUUID::null; } virtual void clearDisplayName() { mDisplayName.clear(); } virtual void restoreItem() {} virtual void restoreToWorld() {} @@ -107,6 +107,7 @@ public: virtual std::string getLabelSuffix() const { return LLStringUtil::null; } virtual void openItem() {} virtual void closeItem() {} + virtual void navigateToFolder(bool new_window = false, bool change_mode = false); virtual void showProperties(); virtual BOOL isItemRenameable() const { return TRUE; } virtual BOOL isMultiPreviewAllowed() { return TRUE; } @@ -114,6 +115,7 @@ public: virtual BOOL isItemRemovable() const; virtual BOOL isItemMovable() const; virtual BOOL isItemInTrash() const; + virtual bool isItemInOutfits() const; virtual BOOL isLink() const; virtual BOOL isLibraryItem() const; //virtual BOOL removeItem() = 0; @@ -251,6 +253,7 @@ public: virtual LLUIImagePtr getIconOverlay() const; LLViewerInventoryItem* getItem() const; + virtual const LLUUID& getThumbnailUUID() const; protected: BOOL confirmRemoveItem(const LLSD& notification, const LLSD& response); diff --git a/indra/newview/llinventoryfilter.cpp b/indra/newview/llinventoryfilter.cpp index e3a6b2dc85..d6110b3cd5 100644 --- a/indra/newview/llinventoryfilter.cpp +++ b/indra/newview/llinventoryfilter.cpp @@ -81,7 +81,8 @@ LLInventoryFilter::LLInventoryFilter(const Params& p) mCurrentGeneration(0), mFirstRequiredGeneration(0), mFirstSuccessGeneration(0), - mSearchType(SEARCHTYPE_NAME) + mSearchType(SEARCHTYPE_NAME), + mSingleFolderMode(false) { // copy mFilterOps into mDefaultFilterOps markDefault(); @@ -595,6 +596,9 @@ bool LLInventoryFilter::checkAgainstSearchVisibility(const LLFolderViewModelItem if (is_link && ((mFilterOps.mSearchVisibility & VISIBILITY_LINKS) == 0)) return FALSE; + if (listener->isItemInOutfits() && ((mFilterOps.mSearchVisibility & VISIBILITY_OUTFITS) == 0)) + return FALSE; + if (listener->isItemInTrash() && ((mFilterOps.mSearchVisibility & VISIBILITY_TRASH) == 0)) return FALSE; @@ -791,6 +795,24 @@ void LLInventoryFilter::toggleSearchVisibilityLinks() } } +void LLInventoryFilter::toggleSearchVisibilityOutfits() +{ + bool hide_outfits = mFilterOps.mSearchVisibility & VISIBILITY_OUTFITS; + if (hide_outfits) + { + mFilterOps.mSearchVisibility &= ~VISIBILITY_OUTFITS; + } + else + { + mFilterOps.mSearchVisibility |= VISIBILITY_OUTFITS; + } + + if (hasFilterString()) + { + setModified(hide_outfits ? FILTER_MORE_RESTRICTIVE : FILTER_LESS_RESTRICTIVE); + } +} + void LLInventoryFilter::toggleSearchVisibilityTrash() { bool hide_trash = mFilterOps.mSearchVisibility & VISIBILITY_TRASH; @@ -1605,7 +1627,7 @@ bool LLInventoryFilter::areDateLimitsSet() bool LLInventoryFilter::showAllResults() const { - return hasFilterString(); + return hasFilterString() && !mSingleFolderMode; } diff --git a/indra/newview/llinventoryfilter.h b/indra/newview/llinventoryfilter.h index 384de3e889..e127ef03ab 100644 --- a/indra/newview/llinventoryfilter.h +++ b/indra/newview/llinventoryfilter.h @@ -104,7 +104,8 @@ public: VISIBILITY_NONE = 0, VISIBILITY_TRASH = 0x1 << 0, VISIBILITY_LIBRARY = 0x1 << 1, - VISIBILITY_LINKS = 0x1 << 2 + VISIBILITY_LINKS = 0x1 << 2, + VISIBILITY_OUTFITS = 0x1 << 3 }; struct FilterOps @@ -228,6 +229,7 @@ public: void toggleSearchVisibilityLinks(); void toggleSearchVisibilityTrash(); + void toggleSearchVisibilityOutfits(); void toggleSearchVisibilityLibrary(); void setSearchVisibilityTypes(U32 types); void setSearchVisibilityTypes(const Params& params); @@ -237,6 +239,8 @@ public: const std::string& getFilterSubStringOrig() const { return mFilterSubStringOrig; } bool hasFilterString() const; + void setSingleFolderMode(bool is_single_folder) { mSingleFolderMode = is_single_folder; } + void setFilterPermissions(PermissionMask perms); PermissionMask getFilterPermissions() const; @@ -359,6 +363,8 @@ private: std::vector<std::string> mFilterTokens; std::string mExactToken; + + bool mSingleFolderMode; }; #endif diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp index af1c93f383..15916ffaba 100644 --- a/indra/newview/llinventoryfunctions.cpp +++ b/indra/newview/llinventoryfunctions.cpp @@ -49,6 +49,7 @@ #include "llclipboard.h" #include "lldirpicker.h" #include "lldonotdisturbnotificationstorage.h" +#include "llfloatermarketplacelistings.h" #include "llfloatersidepanelcontainer.h" #include "llfocusmgr.h" #include "llfolderview.h" @@ -403,6 +404,7 @@ void copy_inventory_category(LLInventoryModel* model, bool move_no_copy_items ) { // Create the initial folder + // D567 needs to handle new fields inventory_func_type func = boost::bind(©_inventory_category_content, _1, model, cat, root_copy_id, move_no_copy_items); gInventory.createNewCategory(parent_id, LLFolderType::FT_NONE, cat->getName(), func); } @@ -764,18 +766,37 @@ BOOL get_is_category_renameable(const LLInventoryModel* model, const LLUUID& id) void show_task_item_profile(const LLUUID& item_uuid, const LLUUID& object_id) { - LLFloaterSidePanelContainer::showPanel("inventory", LLSD().with("id", item_uuid).with("object", object_id)); + LLSD params; + params["id"] = item_uuid; + params["object"] = object_id; + + LLFloaterReg::showInstance("item_properties", params); } void show_item_profile(const LLUUID& item_uuid) { LLUUID linked_uuid = gInventory.getLinkedItemID(item_uuid); - LLFloaterSidePanelContainer::showPanel("inventory", LLSD().with("id", linked_uuid)); + LLFloaterReg::showInstance("item_properties", LLSD().with("id", linked_uuid)); } void show_item_original(const LLUUID& item_uuid) { - LLFloater* floater_inventory = LLFloaterReg::getInstance("inventory"); + static LLUICachedControl<bool> find_original_new_floater("FindOriginalOpenWindow", false); + + //show in a new single-folder window + if(find_original_new_floater) + { + const LLUUID& linked_item_uuid = gInventory.getLinkedItemID(item_uuid); + const LLInventoryObject *obj = gInventory.getObject(linked_item_uuid); + if (obj && obj->getParentUUID().notNull()) + { + LLPanelMainInventory::newFolderWindow(obj->getParentUUID(), linked_item_uuid); + } + } + //show in main Inventory + else + { + LLFloater* floater_inventory = LLFloaterReg::getInstance("inventory"); if (!floater_inventory) { LL_WARNS() << "Could not find My Inventory floater" << LL_ENDL; @@ -787,6 +808,10 @@ void show_item_original(const LLUUID& item_uuid) LLPanelMainInventory* main_inventory = sidepanel_inventory->getMainInventoryPanel(); if (main_inventory) { + if(main_inventory->isSingleFolderMode()) + { + main_inventory->onViewModeClick(); + } main_inventory->resetFilters(); } reset_inventory_filter(); @@ -814,6 +839,7 @@ void show_item_original(const LLUUID& item_uuid) } } } + } } @@ -2556,7 +2582,7 @@ void LLInventoryAction::doToSelected(LLInventoryModel* model, LLFolderView* root LLMultiPreview* multi_previewp = NULL; - LLMultiProperties* multi_propertiesp = NULL; + LLMultiItemProperties* multi_itempropertiesp = nullptr; if (("task_open" == action || "open" == action) && selected_items.size() > 1) { @@ -2590,10 +2616,9 @@ void LLInventoryAction::doToSelected(LLInventoryModel* model, LLFolderView* root } else if (("task_properties" == action || "properties" == action) && selected_items.size() > 1) { - multi_propertiesp = new LLMultiProperties(); - gFloaterView->addChild(multi_propertiesp); - - LLFloater::setFloaterHost(multi_propertiesp); + multi_itempropertiesp = new LLMultiItemProperties("item_properties"); + gFloaterView->addChild(multi_itempropertiesp); + LLFloater::setFloaterHost(multi_itempropertiesp); } std::set<LLUUID> selected_uuid_set = LLAvatarActions::getInventorySelectedUUIDs(); @@ -2766,9 +2791,9 @@ void LLInventoryAction::doToSelected(LLInventoryModel* model, LLFolderView* root { multi_previewp->openFloater(LLSD()); } - else if (multi_propertiesp) + else if (multi_itempropertiesp) { - multi_propertiesp->openFloater(LLSD()); + multi_itempropertiesp->openFloater(LLSD()); } } diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp index afd44db771..7e500a56c3 100644 --- a/indra/newview/llinventorymodel.cpp +++ b/indra/newview/llinventorymodel.cpp @@ -689,24 +689,25 @@ const LLUUID LLInventoryModel::findLibraryCategoryUUIDForType(LLFolderType::ETyp // updateCategory() with a newly generated UUID category, but this // version will take care of details like what the name should be // based on preferred type. Returns the UUID of the new category. +// +// On failure, returns a null UUID. +// FIXME: callers do not check for or handle a null results currently. LLUUID LLInventoryModel::createNewCategory(const LLUUID& parent_id, LLFolderType::EType preferred_type, const std::string& pname, inventory_func_type callback) { - LLUUID id; + LLUUID id; // Initially null. if (!isInventoryUsable()) { LL_WARNS(LOG_INV) << "Inventory is not usable; can't create requested category of type " << preferred_type << LL_ENDL; - // FIXME failing but still returning an id? return id; } if(LLFolderType::lookup(preferred_type) == LLFolderType::badLookup()) { LL_DEBUGS(LOG_INV) << "Attempt to create undefined category." << LL_ENDL; - // FIXME failing but still returning an id? return id; } @@ -718,17 +719,29 @@ LLUUID LLInventoryModel::createNewCategory(const LLUUID& parent_id, LL_WARNS(LOG_INV) << "Creating new system folder, type " << preferred_type << LL_ENDL; } - id.generate(); std::string name = pname; - if(!pname.empty()) - { - name.assign(pname); - } - else + if (pname.empty()) { name.assign(LLViewerFolderType::lookupNewCategoryName(preferred_type)); } +#ifdef USE_AIS_FOR_NC + // D567 currently this doesn't really work due to limitations in + // AIS3, also violates the common caller assumption that we can + // assign the id and return immediately. + if (callback) + { + // D567 note that we no longer assign the UUID in the viewer, so various workflows need to change. + LLSD new_inventory = LLSD::emptyMap(); + new_inventory["categories"] = LLSD::emptyArray(); + LLViewerInventoryCategory cat(LLUUID::null, parent_id, preferred_type, name, gAgent.getID()); + LLSD cat_sd = cat.asLLSD(); + new_inventory["categories"].append(cat_sd); + AISAPI::CreateInventory(parent_id, new_inventory, callback); + + return LLUUID::null; + } +#else LLViewerRegion* viewer_region = gAgent.getRegion(); std::string url; if ( viewer_region ) @@ -738,6 +751,7 @@ LLUUID LLInventoryModel::createNewCategory(const LLUUID& parent_id, { //Let's use the new capability. + id.generate(); LLSD request, body; body["folder_id"] = id; body["parent_id"] = parent_id; @@ -753,17 +767,22 @@ LLUUID LLInventoryModel::createNewCategory(const LLUUID& parent_id, return LLUUID::null; } +#endif + if (!gMessageSystem) { return LLUUID::null; } - // FIXME this UDP code path needs to be removed. Requires + // D567 FIXME this UDP code path needs to be removed. Requires // reworking many of the callers to use callbacks rather than // assuming instant success. // Add the category to the internal representation + LL_WARNS() << "D567 need to remove this usage" << LL_ENDL; + + id.generate(); LLPointer<LLViewerInventoryCategory> cat = new LLViewerInventoryCategory(id, parent_id, preferred_type, name, gAgent.getID()); cat->setVersion(LLViewerInventoryCategory::VERSION_INITIAL - 1); // accountForUpdate() will icrease version by 1 diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp index d1477e489b..82f791a171 100644 --- a/indra/newview/llinventorypanel.cpp +++ b/indra/newview/llinventorypanel.cpp @@ -167,7 +167,7 @@ LLInventoryPanel::LLInventoryPanel(const LLInventoryPanel::Params& p) : if (!sColorSetInitialized) { - sDefaultColor = LLUIColorTable::instance().getColor("MenuItemEnabledColor", DEFAULT_WHITE); + sDefaultColor = LLUIColorTable::instance().getColor("InventoryItemColor", DEFAULT_WHITE); sDefaultHighlightColor = LLUIColorTable::instance().getColor("MenuItemHighlightFgColor", DEFAULT_WHITE); sLibraryColor = LLUIColorTable::instance().getColor("InventoryItemLibraryColor", DEFAULT_WHITE); sLinkColor = LLUIColorTable::instance().getColor("InventoryItemLinkColor", DEFAULT_WHITE); @@ -183,6 +183,7 @@ LLInventoryPanel::LLInventoryPanel(const LLInventoryPanel::Params& p) : mCommitCallbackRegistrar.add("Inventory.BeginIMSession", boost::bind(&LLInventoryPanel::beginIMSession, this)); mCommitCallbackRegistrar.add("Inventory.Share", boost::bind(&LLAvatarActions::shareWithAvatars, this)); mCommitCallbackRegistrar.add("Inventory.FileUploadLocation", boost::bind(&LLInventoryPanel::fileUploadLocation, this, _2)); + mCommitCallbackRegistrar.add("Inventory.OpenNewFolderWindow", boost::bind(&LLInventoryPanel::openSingleViewInventory, this, LLUUID())); } LLFolderView * LLInventoryPanel::createFolderRoot(LLUUID root_id ) @@ -1290,16 +1291,17 @@ BOOL LLInventoryPanel::handleToolTip(S32 x, S32 y, MASK mask) { if (const LLFolderViewModelItemInventory* vm_item_p = static_cast<const LLFolderViewModelItemInventory*>(hover_item_p->getViewModelItem())) { - // Copy/pasted from LLView::handleToolTip() - F32 nTimeout = LLToolTipMgr::instance().toolTipVisible() - ? LLUI::getInstance()->mSettingGroups["config"]->getF32("ToolTipFastDelay") - : LLUI::getInstance()->mSettingGroups["config"]->getF32("ToolTipDelay"); + LLSD params; + params["inv_type"] = vm_item_p->getInventoryType(); + params["thumbnail_id"] = vm_item_p->getThumbnailUUID(); + params["item_id"] = vm_item_p->getUUID(); + LLToolTipMgr::instance().show(LLToolTip::Params() .message(hover_item_p->getToolTip()) .sticky_rect(hover_item_p->calcScreenRect()) - .delay_time(nTimeout) + .delay_time(LLView::getTooltipTimeout()) .create_callback(boost::bind(&LLInspectTextureUtil::createInventoryToolTip, _1)) - .create_params(LLSD().with("inv_type", vm_item_p->getInventoryType()).with("item_id", vm_item_p->getUUID()))); + .create_params(params)); return TRUE; } } @@ -1642,6 +1644,11 @@ void LLInventoryPanel::fileUploadLocation(const LLSD& userdata) } } +void LLInventoryPanel::openSingleViewInventory(LLUUID folder_id) +{ + LLPanelMainInventory::newFolderWindow(folder_id.isNull() ? LLFolderBridge::sSelf.get()->getUUID() : folder_id); +} + void LLInventoryPanel::purgeSelectedItems() { if (!mFolderRoot.get()) return; @@ -1824,6 +1831,24 @@ void LLInventoryPanel::openInventoryPanelAndSetSelection(BOOL auto_open, const L } } +void LLInventoryPanel::setSFViewAndOpenFolder(const LLInventoryPanel* panel, const LLUUID& folder_id) +{ + + LLFloaterReg::const_instance_list_t& inst_list = LLFloaterReg::getFloaterList("inventory"); + for (LLFloaterReg::const_instance_list_t::const_iterator iter = inst_list.begin(); iter != inst_list.end(); ++iter) + { + LLFloaterSidePanelContainer* inventory_floater = dynamic_cast<LLFloaterSidePanelContainer*>(*iter); + LLSidepanelInventory* sidepanel_inventory = inventory_floater->findChild<LLSidepanelInventory>("main_panel"); + + LLPanelMainInventory* main_inventory = sidepanel_inventory->getMainInventoryPanel(); + if (main_inventory && panel->hasAncestor(main_inventory) && !main_inventory->isSingleFolderMode()) + { + main_inventory->onViewModeClick(); + main_inventory->setSingleFolderViewRoot(folder_id, false); + } + } +} + void LLInventoryPanel::addHideFolderType(LLFolderType::EType folder_type) { getFilter().setFilterCategoryTypes(getFilter().getFilterCategoryTypes() & ~(1ULL << folder_type)); @@ -2032,6 +2057,138 @@ LLInventoryRecentItemsPanel::LLInventoryRecentItemsPanel( const Params& params) mInvFVBridgeBuilder = &RECENT_ITEMS_BUILDER; } +static LLDefaultChildRegistry::Register<LLInventorySingleFolderPanel> t_single_folder_inventory_panel("single_folder_inventory_panel"); + +LLInventorySingleFolderPanel::LLInventorySingleFolderPanel(const Params& params) + : LLInventoryPanel(params) +{ + getFilter().setSingleFolderMode(true); + getFilter().setEmptyLookupMessage("InventorySingleFolderNoMatches"); + getFilter().setDefaultEmptyLookupMessage("InventorySingleFolderEmpty"); + + mCommitCallbackRegistrar.add("Inventory.OpenSelectedFolder", boost::bind(&LLInventorySingleFolderPanel::openInCurrentWindow, this, _2)); +} + +LLInventorySingleFolderPanel::~LLInventorySingleFolderPanel() +{ +} + +void LLInventorySingleFolderPanel::setSelectCallback(const boost::function<void(const std::deque<LLFolderViewItem*>& items, BOOL user_action)>& cb) +{ + if (mFolderRoot.get()) + { + mFolderRoot.get()->setSelectCallback(cb); + mSelectionCallback = cb; + } +} + +void LLInventorySingleFolderPanel::initFromParams(const Params& p) +{ + Params fav_params(p); + fav_params.start_folder.id = gInventory.getRootFolderID(); + LLInventoryPanel::initFromParams(p); + changeFolderRoot(gInventory.getRootFolderID()); +} + +void LLInventorySingleFolderPanel::openInCurrentWindow(const LLSD& userdata) +{ + changeFolderRoot(LLFolderBridge::sSelf.get()->getUUID()); +} + +void LLInventorySingleFolderPanel::changeFolderRoot(const LLUUID& new_id) +{ + if(mFolderID.notNull()) + { + mBackwardFolders.push_back(mFolderID); + } + mFolderID = new_id; + updateSingleFolderRoot(); +} + +void LLInventorySingleFolderPanel::onForwardFolder() +{ + if(!mForwardFolders.empty() && (mFolderID != mForwardFolders.back())) + { + mBackwardFolders.push_back(mFolderID); + mFolderID = mForwardFolders.back(); + mForwardFolders.pop_back(); + updateSingleFolderRoot(); + } +} + +void LLInventorySingleFolderPanel::onBackwardFolder() +{ + if(!mBackwardFolders.empty() && (mFolderID != mBackwardFolders.back())) + { + mForwardFolders.push_back(mFolderID); + mFolderID = mBackwardFolders.back(); + mBackwardFolders.pop_back(); + updateSingleFolderRoot(); + } +} + +void LLInventorySingleFolderPanel::clearNavigationHistory() +{ + mForwardFolders.clear(); + mBackwardFolders.clear(); +} + +boost::signals2::connection LLInventorySingleFolderPanel::setRootChangedCallback(root_changed_callback_t cb) +{ + return mRootChangedSignal.connect(cb); +} + +void LLInventorySingleFolderPanel::updateSingleFolderRoot() +{ + if (mFolderID != getRootFolderID()) + { + mRootChangedSignal(); + + LLUUID root_id = mFolderID; + if (mFolderRoot.get()) + { + removeItemID(getRootFolderID()); + mFolderRoot.get()->destroyView(); + } + + mCommitCallbackRegistrar.pushScope(); + { + LLFolderView* folder_view = createFolderRoot(root_id); + folder_view->setChildrenInited(false); + mFolderRoot = folder_view->getHandle(); + + addItemID(root_id, mFolderRoot.get()); + + LLRect scroller_view_rect = getRect(); + scroller_view_rect.translate(-scroller_view_rect.mLeft, -scroller_view_rect.mBottom); + LLScrollContainer::Params scroller_params(mParams.scroll()); + scroller_params.rect(scroller_view_rect); + + if (mScroller) + { + removeChild(mScroller); + delete mScroller; + mScroller = NULL; + } + mScroller = LLUICtrlFactory::create<LLFolderViewScrollContainer>(scroller_params); + addChild(mScroller); + mScroller->addChild(mFolderRoot.get()); + mFolderRoot.get()->setScrollContainer(mScroller); + mFolderRoot.get()->setFollowsAll(); + mFolderRoot.get()->addChild(mFolderRoot.get()->mStatusTextBox); + + if (!mSelectionCallback.empty()) + { + mFolderRoot.get()->setSelectCallback(mSelectionCallback); + } + } + mCommitCallbackRegistrar.popScope(); + mFolderRoot.get()->setCallbackRegistrar(&mCommitCallbackRegistrar); + + buildNewViews(mFolderID); + } +} + /************************************************************************/ /* Asset Pre-Filtered Inventory Panel related class */ /************************************************************************/ diff --git a/indra/newview/llinventorypanel.h b/indra/newview/llinventorypanel.h index 0932482ad7..e9eaaa232d 100644 --- a/indra/newview/llinventorypanel.h +++ b/indra/newview/llinventorypanel.h @@ -222,6 +222,7 @@ public: void doCreate(const LLSD& userdata); bool beginIMSession(); void fileUploadLocation(const LLSD& userdata); + void openSingleViewInventory(LLUUID folder_id = LLUUID()); void purgeSelectedItems(); bool attachObject(const LLSD& userdata); static void idle(void* user_data); @@ -245,7 +246,7 @@ public: BOOL main_panel = FALSE, BOOL take_keyboard_focus = TAKE_FOCUS_YES, BOOL reset_filter = FALSE); - + static void setSFViewAndOpenFolder(const LLInventoryPanel* panel, const LLUUID& folder_id); void addItemID(const LLUUID& id, LLFolderViewItem* itemp); void removeItemID(const LLUUID& id); LLFolderViewItem* getItemByID(const LLUUID& id); @@ -263,6 +264,8 @@ public: void callbackPurgeSelectedItems(const LLSD& notification, const LLSD& response); + void changeFolderRoot(const LLUUID& new_id) {}; + protected: void openStartFolderOrMyInventory(); // open the first level of inventory void onItemsCompletion(); // called when selected items are complete @@ -382,6 +385,44 @@ private: std::deque<LLUUID> mBuildViewsQueue; }; + +class LLInventorySingleFolderPanel : public LLInventoryPanel +{ +public: + struct Params : public LLInitParam::Block<Params, LLInventoryPanel::Params> + {}; + + void initFromParams(const Params& p); + bool isSelectionRemovable() { return false; } + //void setSelectCallback(const boost::function<void(const std::deque<LLFolderViewItem*>& items, BOOL user_action)>& cb); + + void openInCurrentWindow(const LLSD& userdata); + void changeFolderRoot(const LLUUID& new_id); + void onForwardFolder(); + void onBackwardFolder(); + void clearNavigationHistory(); + LLUUID getSingleFolderRoot() { return mFolderID; } + + void setSelectCallback(const boost::function<void (const std::deque<LLFolderViewItem*>& items, BOOL user_action)>& cb); + + typedef boost::function<void()> root_changed_callback_t; + boost::signals2::connection setRootChangedCallback(root_changed_callback_t cb); + +protected: + LLInventorySingleFolderPanel(const Params& params); + ~LLInventorySingleFolderPanel(); + void updateSingleFolderRoot(); + + boost::function<void(const std::deque<LLFolderViewItem*>& items, BOOL user_action)> mSelectionCallback; + friend class LLUICtrlFactory; + + LLUUID mFolderID; + std::list<LLUUID> mBackwardFolders; + std::list<LLUUID> mForwardFolders; + + boost::signals2::signal<void()> mRootChangedSignal; +}; + /************************************************************************/ /* Asset Pre-Filtered Inventory Panel related class */ /* Exchanges filter's flexibility for speed of generation and */ diff --git a/indra/newview/lloutfitgallery.cpp b/indra/newview/lloutfitgallery.cpp index 602b7412a4..6ef8080d8c 100644 --- a/indra/newview/lloutfitgallery.cpp +++ b/indra/newview/lloutfitgallery.cpp @@ -36,12 +36,11 @@ #include "llaccordionctrltab.h" #include "llappearancemgr.h" -#include "llagentbenefits.h" #include "llerror.h" #include "llfilepicker.h" #include "llfloaterperms.h" #include "llfloaterreg.h" -#include "llfloatersimpleoutfitsnapshot.h" +#include "llfloatersimplesnapshot.h" #include "llimagedimensionsinfo.h" #include "llinventoryfunctions.h" #include "llinventorymodel.h" @@ -125,7 +124,6 @@ void LLOutfitGallery::onOpen(const LLSD& info) LLOutfitListBase::onOpen(info); if (!mGalleryCreated) { - loadPhotos(); uuid_vec_t cats; getCurrentCategories(cats); int n = cats.size(); @@ -837,50 +835,20 @@ LLContextMenu* LLOutfitGalleryContextMenu::createMenu() registrar.add("Outfit.Rename", boost::bind(renameOutfit, selected_id)); registrar.add("Outfit.Delete", boost::bind(&LLOutfitGalleryContextMenu::onRemoveOutfit, this, selected_id)); registrar.add("Outfit.Create", boost::bind(&LLOutfitGalleryContextMenu::onCreate, this, _2)); - registrar.add("Outfit.UploadPhoto", boost::bind(&LLOutfitGalleryContextMenu::onUploadPhoto, this, selected_id)); - registrar.add("Outfit.SelectPhoto", boost::bind(&LLOutfitGalleryContextMenu::onSelectPhoto, this, selected_id)); - registrar.add("Outfit.TakeSnapshot", boost::bind(&LLOutfitGalleryContextMenu::onTakeSnapshot, this, selected_id)); - registrar.add("Outfit.RemovePhoto", boost::bind(&LLOutfitGalleryContextMenu::onRemovePhoto, this, selected_id)); + registrar.add("Outfit.Thumbnail", boost::bind(&LLOutfitGalleryContextMenu::onThumbnail, this, selected_id)); enable_registrar.add("Outfit.OnEnable", boost::bind(&LLOutfitGalleryContextMenu::onEnable, this, _2)); enable_registrar.add("Outfit.OnVisible", boost::bind(&LLOutfitGalleryContextMenu::onVisible, this, _2)); return createFromFile("menu_gallery_outfit_tab.xml"); } -void LLOutfitGalleryContextMenu::onUploadPhoto(const LLUUID& outfit_cat_id) +void LLOutfitGalleryContextMenu::onThumbnail(const LLUUID& outfit_cat_id) { LLOutfitGallery* gallery = dynamic_cast<LLOutfitGallery*>(mOutfitList); if (gallery && outfit_cat_id.notNull()) { - gallery->uploadPhoto(outfit_cat_id); - } -} - -void LLOutfitGalleryContextMenu::onSelectPhoto(const LLUUID& outfit_cat_id) -{ - LLOutfitGallery* gallery = dynamic_cast<LLOutfitGallery*>(mOutfitList); - if (gallery && outfit_cat_id.notNull()) - { - gallery->onSelectPhoto(outfit_cat_id); - } -} - -void LLOutfitGalleryContextMenu::onRemovePhoto(const LLUUID& outfit_cat_id) -{ - LLOutfitGallery* gallery = dynamic_cast<LLOutfitGallery*>(mOutfitList); - if (gallery && outfit_cat_id.notNull()) - { - gallery->checkRemovePhoto(outfit_cat_id); - gallery->refreshOutfit(outfit_cat_id); - } -} - -void LLOutfitGalleryContextMenu::onTakeSnapshot(const LLUUID& outfit_cat_id) -{ - LLOutfitGallery* gallery = dynamic_cast<LLOutfitGallery*>(mOutfitList); - if (gallery && outfit_cat_id.notNull()) - { - gallery->onTakeSnapshot(outfit_cat_id); + LLSD data(outfit_cat_id); + LLFloaterReg::showInstance("change_item_thumbnail", data); } } @@ -919,16 +887,6 @@ bool LLOutfitGalleryContextMenu::onEnable(LLSD::String param) bool LLOutfitGalleryContextMenu::onVisible(LLSD::String param) { - mMenuHandle.get()->getChild<LLUICtrl>("upload_photo")->setLabelArg("[UPLOAD_COST]", std::to_string(LLAgentBenefitsMgr::current().getTextureUploadCost())); - if ("remove_photo" == param) - { - LLOutfitGallery* gallery = dynamic_cast<LLOutfitGallery*>(mOutfitList); - LLUUID selected_id = mUUIDs.front(); - if (gallery && selected_id.notNull()) - { - return !gallery->hasDefaultImage(selected_id); - } - } return LLOutfitContextMenu::onVisible(param); } @@ -943,56 +901,12 @@ void LLOutfitGalleryGearMenu::onUpdateItemsVisibility() bool have_selection = getSelectedOutfitID().notNull(); mMenu->setItemVisible("expand", FALSE); mMenu->setItemVisible("collapse", FALSE); - mMenu->setItemVisible("upload_photo", have_selection); - mMenu->setItemVisible("select_photo", have_selection); - mMenu->setItemVisible("take_snapshot", have_selection); - mMenu->setItemVisible("remove_photo", !hasDefaultImage()); + mMenu->setItemVisible("thumbnail", have_selection); mMenu->setItemVisible("sepatator3", TRUE); mMenu->setItemVisible("sort_folders_by_name", TRUE); LLOutfitListGearMenuBase::onUpdateItemsVisibility(); } -void LLOutfitGalleryGearMenu::onUploadFoto() -{ - LLUUID selected_outfit_id = getSelectedOutfitID(); - LLOutfitGallery* gallery = dynamic_cast<LLOutfitGallery*>(mOutfitList); - if (gallery && selected_outfit_id.notNull()) - { - gallery->uploadPhoto(selected_outfit_id); - } -} - -void LLOutfitGalleryGearMenu::onSelectPhoto() -{ - LLOutfitGallery* gallery = dynamic_cast<LLOutfitGallery*>(mOutfitList); - LLUUID selected_outfit_id = getSelectedOutfitID(); - if (gallery && !selected_outfit_id.isNull()) - { - gallery->onSelectPhoto(selected_outfit_id); - } -} - -void LLOutfitGalleryGearMenu::onRemovePhoto() -{ - LLOutfitGallery* gallery = dynamic_cast<LLOutfitGallery*>(mOutfitList); - LLUUID selected_outfit_id = getSelectedOutfitID(); - if (gallery && !selected_outfit_id.isNull()) - { - gallery->checkRemovePhoto(selected_outfit_id); - gallery->refreshOutfit(selected_outfit_id); - } -} - -void LLOutfitGalleryGearMenu::onTakeSnapshot() -{ - LLOutfitGallery* gallery = dynamic_cast<LLOutfitGallery*>(mOutfitList); - LLUUID selected_outfit_id = getSelectedOutfitID(); - if (gallery && !selected_outfit_id.isNull()) - { - gallery->onTakeSnapshot(selected_outfit_id); - } -} - void LLOutfitGalleryGearMenu::onChangeSortOrder() { bool sort_by_name = !gSavedSettings.getBOOL("OutfitGallerySortByName"); @@ -1019,236 +933,89 @@ void LLOutfitGallery::onTextureSelectionChanged(LLInventoryItem* itemp) { } -void LLOutfitGallery::loadPhotos() -{ - //Iterate over inventory - mSnapshotFolderID = gInventory.findUserDefinedCategoryUUIDForType(LLFolderType::FT_TEXTURE); - LLViewerInventoryCategory* textures_category = gInventory.getCategory(mSnapshotFolderID); - if (!textures_category) - return; - if (mTexturesObserver == NULL) - { - mTexturesObserver = new LLInventoryCategoriesObserver(); - gInventory.addObserver(mTexturesObserver); - } - - // Start observing changes in "Textures" category. - mTexturesObserver->addCategory(mSnapshotFolderID, - boost::bind(&LLOutfitGallery::refreshTextures, this, mSnapshotFolderID)); - - textures_category->fetch(); -} - -void LLOutfitGallery::updateSnapshotFolderObserver() -{ - if(mSnapshotFolderID != gInventory.findUserDefinedCategoryUUIDForType(LLFolderType::FT_TEXTURE)) - { - if (gInventory.containsObserver(mTexturesObserver)) - { - gInventory.removeObserver(mTexturesObserver); - } - delete mTexturesObserver; - mTexturesObserver = NULL; - loadPhotos(); - } -} - void LLOutfitGallery::refreshOutfit(const LLUUID& category_id) { LLViewerInventoryCategory* category = gInventory.getCategory(category_id); if (category) { bool photo_loaded = false; - LLInventoryModel::cat_array_t sub_cat_array; - LLInventoryModel::item_array_t outfit_item_array; - // Collect all sub-categories of a given category. - gInventory.collectDescendents( - category->getUUID(), - sub_cat_array, - outfit_item_array, - LLInventoryModel::EXCLUDE_TRASH); - BOOST_FOREACH(LLViewerInventoryItem* outfit_item, outfit_item_array) + LLUUID asset_id = category->getThumbnailUUID(); + if (asset_id.isNull()) { - LLViewerInventoryItem* linked_item = outfit_item->getLinkedItem(); - LLUUID asset_id, inv_id; - std::string item_name; - if (linked_item != NULL) + LLInventoryModel::cat_array_t sub_cat_array; + LLInventoryModel::item_array_t outfit_item_array; + // Collect all sub-categories of a given category. + gInventory.collectDescendents( + category->getUUID(), + sub_cat_array, + outfit_item_array, + LLInventoryModel::EXCLUDE_TRASH); + BOOST_FOREACH(LLViewerInventoryItem* outfit_item, outfit_item_array) { - if (linked_item->getActualType() == LLAssetType::AT_TEXTURE) + LLViewerInventoryItem* linked_item = outfit_item->getLinkedItem(); + LLUUID asset_id, inv_id; + std::string item_name; + if (linked_item != NULL) { - asset_id = linked_item->getAssetUUID(); - inv_id = linked_item->getUUID(); - item_name = linked_item->getName(); + if (linked_item->getActualType() == LLAssetType::AT_TEXTURE) + { + asset_id = linked_item->getAssetUUID(); + inv_id = linked_item->getUUID(); + item_name = linked_item->getName(); + } } - } - else if (outfit_item->getActualType() == LLAssetType::AT_TEXTURE) - { - asset_id = outfit_item->getAssetUUID(); - inv_id = outfit_item->getUUID(); - item_name = outfit_item->getName(); - } - if (asset_id.notNull()) - { - photo_loaded |= mOutfitMap[category_id]->setImageAssetId(asset_id); - // Rename links - if (!mOutfitRenamePending.isNull() && mOutfitRenamePending.asString() == item_name) + else if (outfit_item->getActualType() == LLAssetType::AT_TEXTURE) + { + asset_id = outfit_item->getAssetUUID(); + inv_id = outfit_item->getUUID(); + item_name = outfit_item->getName(); + } + if (category->getThumbnailUUID().notNull()) + { + asset_id = category->getThumbnailUUID(); + } + if (asset_id.notNull()) { - LLViewerInventoryCategory *outfit_cat = gInventory.getCategory(mOutfitRenamePending); - LLStringUtil::format_map_t photo_string_args; - photo_string_args["OUTFIT_NAME"] = outfit_cat->getName(); - std::string new_name = getString("outfit_photo_string", photo_string_args); - LLSD updates; - updates["name"] = new_name; - update_inventory_item(inv_id, updates, NULL); - mOutfitRenamePending.setNull(); - LLFloater* appearance_floater = LLFloaterReg::getInstance("appearance"); - if (appearance_floater) + photo_loaded |= mOutfitMap[category_id]->setImageAssetId(asset_id); + // Rename links + if (!mOutfitRenamePending.isNull() && mOutfitRenamePending.asString() == item_name) + { + LLViewerInventoryCategory *outfit_cat = gInventory.getCategory(mOutfitRenamePending); + LLStringUtil::format_map_t photo_string_args; + photo_string_args["OUTFIT_NAME"] = outfit_cat->getName(); + std::string new_name = getString("outfit_photo_string", photo_string_args); + LLSD updates; + updates["name"] = new_name; + update_inventory_item(inv_id, updates, NULL); + mOutfitRenamePending.setNull(); + LLFloater* appearance_floater = LLFloaterReg::getInstance("appearance"); + if (appearance_floater) + { + appearance_floater->setFocus(TRUE); + } + } + if (item_name == LLAppearanceMgr::sExpectedTextureName) { - appearance_floater->setFocus(TRUE); + // Images with "appropriate" name take priority + break; } } - if (item_name == LLAppearanceMgr::sExpectedTextureName) + if (!photo_loaded) { - // Images with "appropriate" name take priority - break; + mOutfitMap[category_id]->setDefaultImage(); } } - if (!photo_loaded) - { - mOutfitMap[category_id]->setDefaultImage(); - } - } - } - - if (mGalleryCreated && !LLApp::isExiting()) - { - reArrangeRows(); - } -} - -// Refresh linked textures from "textures" uploads folder -void LLOutfitGallery::refreshTextures(const LLUUID& category_id) -{ - LLInventoryModel::cat_array_t cat_array; - LLInventoryModel::item_array_t item_array; - - // Collect all sub-categories of a given category. - LLIsType is_texture(LLAssetType::AT_TEXTURE); - gInventory.collectDescendentsIf( - category_id, - cat_array, - item_array, - LLInventoryModel::EXCLUDE_TRASH, - is_texture); - - //Find texture which contain pending outfit ID string in name - LLViewerInventoryItem* photo_upload_item = NULL; - BOOST_FOREACH(LLViewerInventoryItem* item, item_array) - { - std::string name = item->getName(); - if (!mOutfitLinkPending.isNull() && name == mOutfitLinkPending.asString()) - { - photo_upload_item = item; - break; - } - } - - if (photo_upload_item != NULL) - { - LLUUID photo_item_id = photo_upload_item->getUUID(); - LLInventoryObject* upload_object = gInventory.getObject(photo_item_id); - if (!upload_object) - { - LL_WARNS() << "LLOutfitGallery::refreshTextures added_object is null!" << LL_ENDL; } else { - linkPhotoToOutfit(photo_item_id, mOutfitLinkPending); - mOutfitRenamePending = mOutfitLinkPending; - mOutfitLinkPending.setNull(); + mOutfitMap[category_id]->setImageAssetId(asset_id); } } -} - -void LLOutfitGallery::uploadPhoto(LLUUID outfit_id) -{ - outfit_map_t::iterator outfit_it = mOutfitMap.find(outfit_id); - if (outfit_it == mOutfitMap.end() || outfit_it->first.isNull()) - { - return; - } - (new LLFilePickerReplyThread(boost::bind(&LLOutfitGallery::uploadOutfitImage, this, _1, outfit_id), LLFilePicker::FFLOAD_IMAGE, false))->getFile(); -} - -void LLOutfitGallery::uploadOutfitImage(const std::vector<std::string>& filenames, LLUUID outfit_id) -{ - std::string filename = filenames[0]; - LLLocalBitmap* unit = new LLLocalBitmap(filename); - if (unit->getValid()) + + if (mGalleryCreated && !LLApp::isExiting()) { - std::string exten = gDirUtilp->getExtension(filename); - U32 codec = LLImageBase::getCodecFromExtension(exten); - - LLImageDimensionsInfo image_info; - std::string image_load_error; - if (!image_info.load(filename, codec)) - { - image_load_error = image_info.getLastError(); - } - - S32 max_width = MAX_OUTFIT_PHOTO_WIDTH; - S32 max_height = MAX_OUTFIT_PHOTO_HEIGHT; - - if ((image_info.getWidth() > max_width) || (image_info.getHeight() > max_height)) - { - LLStringUtil::format_map_t args; - args["WIDTH"] = llformat("%d", max_width); - args["HEIGHT"] = llformat("%d", max_height); - - image_load_error = LLTrans::getString("outfit_photo_load_dimensions_error", args); - } - - if (!image_load_error.empty()) - { - LLSD subst; - subst["REASON"] = image_load_error; - LLNotificationsUtil::add("OutfitPhotoLoadError", subst); - return; - } - - S32 expected_upload_cost = LLAgentBenefitsMgr::current().getTextureUploadCost(); - void *nruserdata = NULL; - nruserdata = (void *)&outfit_id; - - LLViewerInventoryCategory *outfit_cat = gInventory.getCategory(outfit_id); - if (!outfit_cat) return; - updateSnapshotFolderObserver(); - checkRemovePhoto(outfit_id); - std::string upload_pending_name = outfit_id.asString(); - std::string upload_pending_desc = ""; - upload_new_resource(filename, // file - upload_pending_name, - upload_pending_desc, - 0, LLFolderType::FT_NONE, LLInventoryType::IT_NONE, - LLFloaterPerms::getNextOwnerPerms("Uploads"), - LLFloaterPerms::getGroupPerms("Uploads"), - LLFloaterPerms::getEveryonePerms("Uploads"), - upload_pending_name, LLAssetStorage::LLStoreAssetCallback(), expected_upload_cost, nruserdata, false); - mOutfitLinkPending = outfit_id; + reArrangeRows(); } - delete unit; -} - -void LLOutfitGallery::linkPhotoToOutfit(LLUUID photo_id, LLUUID outfit_id) -{ - LLPointer<LLInventoryCallback> cb = new LLUpdateGalleryOnPhotoLinked(); - link_inventory_object(outfit_id, photo_id, cb); -} - -bool LLOutfitGallery::checkRemovePhoto(LLUUID outfit_id) -{ - LLAppearanceMgr::instance().removeOutfitPhoto(outfit_id); - return true; } void LLUpdateGalleryOnPhotoLinked::fire(const LLUUID& inv_item_id) @@ -1270,151 +1037,3 @@ LLUUID LLOutfitGallery::getDefaultPhoto() return LLUUID(); } -void LLOutfitGallery::onTexturePickerCommit(LLTextureCtrl::ETexturePickOp op, LLUUID id) -{ - LLUUID selected_outfit_id = getSelectedOutfitUUID(); - - if (selected_outfit_id.isNull()) - { - return; - } - - LLFloaterTexturePicker* floaterp = (LLFloaterTexturePicker*)mFloaterHandle.get(); - - if (floaterp && op == LLTextureCtrl::TEXTURE_SELECT) - { - LLUUID image_item_id; - if (id.notNull()) - { - image_item_id = id; - } - else - { - image_item_id = floaterp->findItemID(floaterp->getAssetID(), FALSE, TRUE); - if (image_item_id.isNull()) - { - LL_WARNS() << "id or image_item_id is NULL!" << LL_ENDL; - return; - } - } - - std::string image_load_error; - S32 max_width = MAX_OUTFIT_PHOTO_WIDTH; - S32 max_height = MAX_OUTFIT_PHOTO_HEIGHT; - if (mTextureSelected.isNull() || - mTextureSelected->getFullWidth() == 0 || - mTextureSelected->getFullHeight() == 0) - { - image_load_error = LLTrans::getString("outfit_photo_verify_dimensions_error"); - LL_WARNS() << "Cannot verify selected texture dimensions" << LL_ENDL; - return; - } - S32 width = mTextureSelected->getFullWidth(); - S32 height = mTextureSelected->getFullHeight(); - if ((width > max_width) || (height > max_height)) - { - LLStringUtil::format_map_t args; - args["WIDTH"] = llformat("%d", max_width); - args["HEIGHT"] = llformat("%d", max_height); - - image_load_error = LLTrans::getString("outfit_photo_select_dimensions_error", args); - } - - if (!image_load_error.empty()) - { - LLSD subst; - subst["REASON"] = image_load_error; - LLNotificationsUtil::add("OutfitPhotoLoadError", subst); - return; - } - - checkRemovePhoto(selected_outfit_id); - linkPhotoToOutfit(image_item_id, selected_outfit_id); - } -} - -void LLOutfitGallery::onSelectPhoto(LLUUID selected_outfit_id) -{ - if (selected_outfit_id.notNull()) - { - - // show hourglass cursor when loading inventory window - // because inventory construction is slooow - getWindow()->setCursor(UI_CURSOR_WAIT); - LLFloater* floaterp = mFloaterHandle.get(); - - // Show the dialog - if (floaterp) - { - floaterp->openFloater(); - } - else - { - floaterp = new LLFloaterTexturePicker( - this, - getPhotoAssetId(selected_outfit_id), - getPhotoAssetId(selected_outfit_id), - getPhotoAssetId(selected_outfit_id), - FALSE, - TRUE, - "SELECT PHOTO", - PERM_NONE, - PERM_NONE, - PERM_NONE, - FALSE, - NULL); - - mFloaterHandle = floaterp->getHandle(); - mTextureSelected = NULL; - - LLFloaterTexturePicker* texture_floaterp = dynamic_cast<LLFloaterTexturePicker*>(floaterp); - if (texture_floaterp) - { - texture_floaterp->setTextureSelectedCallback(boost::bind(&LLOutfitGallery::onTextureSelectionChanged, this, _1)); - texture_floaterp->setOnFloaterCommitCallback(boost::bind(&LLOutfitGallery::onTexturePickerCommit, this, _1, _2)); - texture_floaterp->setOnUpdateImageStatsCallback(boost::bind(&LLOutfitGallery::onTexturePickerUpdateImageStats, this, _1)); - texture_floaterp->setLocalTextureEnabled(FALSE); - texture_floaterp->setBakeTextureEnabled(FALSE); - texture_floaterp->setCanApply(false, true); - } - - floaterp->openFloater(); - } - floaterp->setFocus(TRUE); - } -} - -void LLOutfitGallery::onTakeSnapshot(LLUUID selected_outfit_id) -{ - LLFloaterReg::toggleInstanceOrBringToFront("simple_outfit_snapshot"); - LLFloaterSimpleOutfitSnapshot* snapshot_floater = LLFloaterSimpleOutfitSnapshot::getInstance(); - if (snapshot_floater) - { - snapshot_floater->setOutfitID(selected_outfit_id); - snapshot_floater->getInstance()->setGallery(this); - } -} - -void LLOutfitGallery::onBeforeOutfitSnapshotSave() -{ - LLUUID selected_outfit_id = getSelectedOutfitUUID(); - if (!selected_outfit_id.isNull()) - { - checkRemovePhoto(selected_outfit_id); - updateSnapshotFolderObserver(); - } -} - -void LLOutfitGallery::onAfterOutfitSnapshotSave() -{ - LLUUID selected_outfit_id = getSelectedOutfitUUID(); - if (!selected_outfit_id.isNull()) - { - mOutfitLinkPending = selected_outfit_id; - } -} - -void LLOutfitGallery::onTexturePickerUpdateImageStats(LLPointer<LLViewerTexture> texture) -{ - mTextureSelected = texture; -} diff --git a/indra/newview/lloutfitgallery.h b/indra/newview/lloutfitgallery.h index ce5c090134..210e436b96 100644 --- a/indra/newview/lloutfitgallery.h +++ b/indra/newview/lloutfitgallery.h @@ -33,7 +33,6 @@ #include "lllayoutstack.h" #include "lloutfitslist.h" #include "llpanelappearancetab.h" -#include "lltexturectrl.h" #include "llviewertexture.h" #include <vector> @@ -106,14 +105,8 @@ public: void updateMessageVisibility(); bool hasDefaultImage(const LLUUID& outfit_cat_id); - void refreshTextures(const LLUUID& category_id); void refreshOutfit(const LLUUID& category_id); - void onTexturePickerCommit(LLTextureCtrl::ETexturePickOp op, LLUUID id); - void onTexturePickerUpdateImageStats(LLPointer<LLViewerTexture> texture); - void onBeforeOutfitSnapshotSave(); - void onAfterOutfitSnapshotSave(); - protected: /*virtual*/ void onHighlightBaseOutfit(LLUUID base_id, LLUUID prev_id); /*virtual*/ void onSetSelectedOutfitByUUID(const LLUUID& outfit_uuid); @@ -127,14 +120,10 @@ protected: void applyFilter(LLOutfitGalleryItem* item, const std::string& filter_substring); private: - void loadPhotos(); void uploadPhoto(LLUUID outfit_id); void uploadOutfitImage(const std::vector<std::string>& filenames, LLUUID outfit_id); - void updateSnapshotFolderObserver(); LLUUID getPhotoAssetId(const LLUUID& outfit_id); LLUUID getDefaultPhoto(); - void linkPhotoToOutfit(LLUUID outfit_id, LLUUID photo_id); - bool checkRemovePhoto(LLUUID outfit_id); void addToGallery(LLOutfitGalleryItem* item); void removeFromGalleryLast(LLOutfitGalleryItem* item); void removeFromGalleryMiddle(LLOutfitGalleryItem* item); @@ -190,8 +179,6 @@ private: LLListContextMenu* mOutfitGalleryMenu; - LLHandle<LLFloater> mFloaterHandle; - typedef std::map<LLUUID, LLOutfitGalleryItem*> outfit_map_t; typedef outfit_map_t::value_type outfit_map_value_t; outfit_map_t mOutfitMap; @@ -215,10 +202,7 @@ protected: /* virtual */ LLContextMenu* createMenu(); bool onEnable(LLSD::String param); bool onVisible(LLSD::String param); - void onUploadPhoto(const LLUUID& outfit_cat_id); - void onSelectPhoto(const LLUUID& outfit_cat_id); - void onRemovePhoto(const LLUUID& outfit_cat_id); - void onTakeSnapshot(const LLUUID& outfit_cat_id); + void onThumbnail(const LLUUID& outfit_cat_id); void onCreate(const LLSD& data); void onRemoveOutfit(const LLUUID& outfit_cat_id); void onOutfitsRemovalConfirmation(const LLSD& notification, const LLSD& response, const LLUUID& outfit_cat_id); @@ -236,10 +220,6 @@ public: protected: /*virtual*/ void onUpdateItemsVisibility(); private: - /*virtual*/ void onUploadFoto(); - /*virtual*/ void onSelectPhoto(); - /*virtual*/ void onTakeSnapshot(); - /*virtual*/ void onRemovePhoto(); /*virtual*/ void onChangeSortOrder(); bool hasDefaultImage(); diff --git a/indra/newview/lloutfitslist.cpp b/indra/newview/lloutfitslist.cpp index 4171fd8822..fe15d21e36 100644 --- a/indra/newview/lloutfitslist.cpp +++ b/indra/newview/lloutfitslist.cpp @@ -35,7 +35,7 @@ #include "llaccordionctrltab.h" #include "llagentwearables.h" #include "llappearancemgr.h" -#include "llagentbenefits.h" +#include "llfloaterreg.h" #include "llfloatersidepanelcontainer.h" #include "llinventoryfunctions.h" #include "llinventorymodel.h" @@ -1112,10 +1112,7 @@ LLOutfitListGearMenuBase::LLOutfitListGearMenuBase(LLOutfitListBase* olist) registrar.add("Gear.WearAdd", boost::bind(&LLOutfitListGearMenuBase::onAdd, this)); - registrar.add("Gear.UploadPhoto", boost::bind(&LLOutfitListGearMenuBase::onUploadFoto, this)); - registrar.add("Gear.SelectPhoto", boost::bind(&LLOutfitListGearMenuBase::onSelectPhoto, this)); - registrar.add("Gear.TakeSnapshot", boost::bind(&LLOutfitListGearMenuBase::onTakeSnapshot, this)); - registrar.add("Gear.RemovePhoto", boost::bind(&LLOutfitListGearMenuBase::onRemovePhoto, this)); + registrar.add("Gear.Thumbnail", boost::bind(&LLOutfitListGearMenuBase::onThumbnail, this)); registrar.add("Gear.SortByName", boost::bind(&LLOutfitListGearMenuBase::onChangeSortOrder, this)); enable_registrar.add("Gear.OnEnable", boost::bind(&LLOutfitListGearMenuBase::onEnable, this, _2)); @@ -1232,7 +1229,6 @@ bool LLOutfitListGearMenuBase::onEnable(LLSD::String param) bool LLOutfitListGearMenuBase::onVisible(LLSD::String param) { - getMenu()->getChild<LLUICtrl>("upload_photo")->setLabelArg("[UPLOAD_COST]", std::to_string(LLAgentBenefitsMgr::current().getTextureUploadCost())); const LLUUID& selected_outfit_id = getSelectedOutfitID(); if (selected_outfit_id.isNull()) // no selection or invalid outfit selected { @@ -1251,24 +1247,11 @@ bool LLOutfitListGearMenuBase::onVisible(LLSD::String param) return true; } -void LLOutfitListGearMenuBase::onUploadFoto() +void LLOutfitListGearMenuBase::onThumbnail() { - -} - -void LLOutfitListGearMenuBase::onSelectPhoto() -{ - -} - -void LLOutfitListGearMenuBase::onTakeSnapshot() -{ - -} - -void LLOutfitListGearMenuBase::onRemovePhoto() -{ - + const LLUUID& selected_outfit_id = getSelectedOutfitID(); + LLSD data(selected_outfit_id); + LLFloaterReg::showInstance("change_item_thumbnail", data); } void LLOutfitListGearMenuBase::onChangeSortOrder() @@ -1288,10 +1271,7 @@ void LLOutfitListGearMenu::onUpdateItemsVisibility() if (!mMenu) return; mMenu->setItemVisible("expand", TRUE); mMenu->setItemVisible("collapse", TRUE); - mMenu->setItemVisible("upload_photo", FALSE); - mMenu->setItemVisible("select_photo", FALSE); - mMenu->setItemVisible("take_snapshot", FALSE); - mMenu->setItemVisible("remove_photo", FALSE); + mMenu->setItemVisible("thumbnail", FALSE); // Never visible? mMenu->setItemVisible("sepatator3", FALSE); mMenu->setItemVisible("sort_folders_by_name", FALSE); LLOutfitListGearMenuBase::onUpdateItemsVisibility(); diff --git a/indra/newview/lloutfitslist.h b/indra/newview/lloutfitslist.h index 81be8de94f..66b3165169 100644 --- a/indra/newview/lloutfitslist.h +++ b/indra/newview/lloutfitslist.h @@ -163,10 +163,7 @@ public: protected: virtual void onUpdateItemsVisibility(); - virtual void onUploadFoto(); - virtual void onSelectPhoto(); - virtual void onTakeSnapshot(); - virtual void onRemovePhoto(); + virtual void onThumbnail(); virtual void onChangeSortOrder(); const LLUUID& getSelectedOutfitID(); diff --git a/indra/newview/llpanelmaininventory.cpp b/indra/newview/llpanelmaininventory.cpp index 81acb1c8b4..9bfea7fe2b 100644 --- a/indra/newview/llpanelmaininventory.cpp +++ b/indra/newview/llpanelmaininventory.cpp @@ -38,7 +38,6 @@ #include "llinventorybridge.h" #include "llinventoryfunctions.h" #include "llinventorymodelbackgroundfetch.h" -#include "llinventorypanel.h" #include "llfiltereditor.h" #include "llfloatersidepanelcontainer.h" #include "llfloaterreg.h" @@ -113,7 +112,10 @@ LLPanelMainInventory::LLPanelMainInventory(const LLPanel::Params& p) mMenuGearDefault(NULL), mMenuVisibility(NULL), mMenuAddHandle(), - mNeedUploadCost(true) + mNeedUploadCost(true), + mMenuViewDefault(NULL), + mSingleFolderMode(false), + mFolderRootChangedConnection() { // Menu Callbacks (non contex menus) mCommitCallbackRegistrar.add("Inventory.DoToSelected", boost::bind(&LLPanelMainInventory::doToSelected, this, _2)); @@ -237,6 +239,11 @@ BOOL LLPanelMainInventory::postBuild() mGearMenuButton = getChild<LLMenuButton>("options_gear_btn"); mVisibilityMenuButton = getChild<LLMenuButton>("options_visibility_btn"); + mViewMenuButton = getChild<LLMenuButton>("view_btn"); + + mSingleFolderPanelInventory = getChild<LLInventorySingleFolderPanel>("single_folder_inv"); + mFolderRootChangedConnection = mSingleFolderPanelInventory->setRootChangedCallback(boost::bind(&LLPanelMainInventory::updateTitle, this)); + mSingleFolderPanelInventory->setSelectCallback(boost::bind(&LLPanelMainInventory::onSelectionChange, this, mSingleFolderPanelInventory, _1, _2)); initListCommandsHandlers(); @@ -308,12 +315,17 @@ LLPanelMainInventory::~LLPanelMainInventory( void ) gInventory.removeObserver(this); delete mSavedFolderState; - auto menu = mMenuAddHandle.get(); - if(menu) - { - menu->die(); - mMenuAddHandle.markDead(); - } + auto menu = mMenuAddHandle.get(); + if(menu) + { + menu->die(); + mMenuAddHandle.markDead(); + } + + if (mFolderRootChangedConnection.connected()) + { + mFolderRootChangedConnection.disconnect(); + } } LLInventoryPanel* LLPanelMainInventory::getAllItemsPanel() @@ -381,10 +393,17 @@ void LLPanelMainInventory::closeAllFolders() getPanel()->getRootFolder()->closeAllFolders(); } +S32 get_instance_num() +{ + static S32 instance_num = 0; + instance_num = (instance_num + 1) % S32_MAX; + + return instance_num; +} + void LLPanelMainInventory::newWindow() { - static S32 instance_num = 0; - instance_num = (instance_num + 1) % S32_MAX; + S32 instance_num = get_instance_num(); if (!gAgentCamera.cameraMouselook()) { @@ -392,10 +411,49 @@ void LLPanelMainInventory::newWindow() } } +void LLPanelMainInventory::newFolderWindow(LLUUID folder_id, LLUUID item_to_select) +{ + S32 instance_num = get_instance_num(); + + LLFloaterSidePanelContainer* inventory_container = LLFloaterReg::showTypedInstance<LLFloaterSidePanelContainer>("inventory", LLSD(instance_num)); + if(inventory_container) + { + LLSidepanelInventory* sidepanel_inventory = dynamic_cast<LLSidepanelInventory*>(inventory_container->findChild<LLPanel>("main_panel", true)); + if (sidepanel_inventory) + { + LLPanelMainInventory* main_inventory = sidepanel_inventory->getMainInventoryPanel(); + if (main_inventory) + { + main_inventory->onViewModeClick(); + if(folder_id.notNull()) + { + main_inventory->setSingleFolderViewRoot(folder_id); + if(item_to_select.notNull()) + { + sidepanel_inventory->getActivePanel()->setSelection(item_to_select, TAKE_FOCUS_YES); + } + } + } + } + } +} + void LLPanelMainInventory::doCreate(const LLSD& userdata) { reset_inventory_filter(); - menu_create_inventory_item(getPanel(), NULL, userdata); + if(mSingleFolderMode) + { + LLFolderViewItem* current_folder = getActivePanel()->getRootFolder(); + if (current_folder) + { + LLFolderBridge* bridge = (LLFolderBridge*)current_folder->getViewModelItem(); + menu_create_inventory_item(getPanel(), bridge, userdata); + } + } + else + { + menu_create_inventory_item(getPanel(), NULL, userdata); + } } void LLPanelMainInventory::resetFilters() @@ -525,7 +583,7 @@ void LLPanelMainInventory::onClearSearch() } // re-open folders that were initially open in case filter was active - if (mActivePanel && (mFilterSubString.size() || initially_active)) + if (mActivePanel && (mFilterSubString.size() || initially_active) && !mSingleFolderMode) { mSavedFolderState->setApply(TRUE); mActivePanel->getRootFolder()->applyFunctorRecursively(*mSavedFolderState); @@ -535,7 +593,7 @@ void LLPanelMainInventory::onClearSearch() } mFilterSubString = ""; - LLSidepanelInventory * sidepanel_inventory = LLFloaterSidePanelContainer::getPanel<LLSidepanelInventory>("inventory"); + LLSidepanelInventory * sidepanel_inventory = getParentSidepanelInventory(); if (sidepanel_inventory) { LLPanelMarketplaceInbox* inbox_panel = sidepanel_inventory->getChild<LLPanelMarketplaceInbox>("marketplace_inbox"); @@ -576,7 +634,7 @@ void LLPanelMainInventory::onFilterEdit(const std::string& search_string ) // set new filter string setFilterSubString(mFilterSubString); - LLSidepanelInventory * sidepanel_inventory = LLFloaterSidePanelContainer::getPanel<LLSidepanelInventory>("inventory"); + LLSidepanelInventory * sidepanel_inventory = getParentSidepanelInventory(); if (sidepanel_inventory) { LLPanelMarketplaceInbox* inbox_panel = sidepanel_inventory->getChild<LLPanelMarketplaceInbox>("marketplace_inbox"); @@ -1170,26 +1228,25 @@ void LLFloaterInventoryFinder::selectNoTypes(void* user_data) void LLPanelMainInventory::initListCommandsHandlers() { - childSetAction("trash_btn", boost::bind(&LLPanelMainInventory::onTrashButtonClick, this)); childSetAction("add_btn", boost::bind(&LLPanelMainInventory::onAddButtonClick, this)); - - mTrashButton = getChild<LLDragAndDropButton>("trash_btn"); - mTrashButton->setDragAndDropHandler(boost::bind(&LLPanelMainInventory::handleDragAndDropToTrash, this - , _4 // BOOL drop - , _5 // EDragAndDropType cargo_type - , _7 // EAcceptance* accept - )); + childSetAction("view_mode_btn", boost::bind(&LLPanelMainInventory::onViewModeClick, this)); + childSetAction("up_btn", boost::bind(&LLPanelMainInventory::onUpFolderClicked, this)); + childSetAction("back_btn", boost::bind(&LLPanelMainInventory::onBackFolderClicked, this)); + childSetAction("forward_btn", boost::bind(&LLPanelMainInventory::onForwardFolderClicked, this)); mCommitCallbackRegistrar.add("Inventory.GearDefault.Custom.Action", boost::bind(&LLPanelMainInventory::onCustomAction, this, _2)); mEnableCallbackRegistrar.add("Inventory.GearDefault.Check", boost::bind(&LLPanelMainInventory::isActionChecked, this, _2)); mEnableCallbackRegistrar.add("Inventory.GearDefault.Enable", boost::bind(&LLPanelMainInventory::isActionEnabled, this, _2)); + mEnableCallbackRegistrar.add("Inventory.GearDefault.Visible", boost::bind(&LLPanelMainInventory::isActionVisible, this, _2)); mMenuGearDefault = LLUICtrlFactory::getInstance()->createFromFile<LLToggleableMenu>("menu_inventory_gear_default.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); mGearMenuButton->setMenu(mMenuGearDefault, LLMenuButton::MP_TOP_LEFT, true); + mMenuViewDefault = LLUICtrlFactory::getInstance()->createFromFile<LLToggleableMenu>("menu_inventory_view_default.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); + mViewMenuButton->setMenu(mMenuViewDefault); LLMenuGL* menu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_inventory_add.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); mMenuAddHandle = menu->getHandle(); mMenuVisibility = LLUICtrlFactory::getInstance()->createFromFile<LLToggleableMenu>("menu_inventory_search_visibility.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); - mVisibilityMenuButton->setMenu(mMenuVisibility, LLMenuButton::MP_BOTTOM_LEFT, true); + mVisibilityMenuButton->setMenu(mMenuVisibility, LLMenuButton::MP_BOTTOM_LEFT, true); // Update the trash button when selected item(s) get worn or taken off. LLOutfitObserver::instance().addCOFChangedCallback(boost::bind(&LLPanelMainInventory::updateListCommands, this)); @@ -1197,9 +1254,6 @@ void LLPanelMainInventory::initListCommandsHandlers() void LLPanelMainInventory::updateListCommands() { - bool trash_enabled = isActionEnabled("delete"); - - mTrashButton->setEnabled(trash_enabled); } void LLPanelMainInventory::onAddButtonClick() @@ -1218,6 +1272,64 @@ void LLPanelMainInventory::onAddButtonClick() } } +void LLPanelMainInventory::onViewModeClick() +{ + mSingleFolderMode = !mSingleFolderMode; + + getChild<LLPanel>("default_inventory_panel")->setVisible(!mSingleFolderMode); + getChild<LLPanel>("single_folder_inventory")->setVisible(mSingleFolderMode); + getChild<LLLayoutPanel>("nav_buttons")->setVisible(mSingleFolderMode); + getChild<LLButton>("view_mode_btn")->setImageOverlay(mSingleFolderMode ? getString("default_mode_btn") : getString("single_folder_mode_btn")); + + mActivePanel = mSingleFolderMode ? getChild<LLInventoryPanel>("single_folder_inv") : (LLInventoryPanel*)getChild<LLTabContainer>("inventory filter tabs")->getCurrentPanel(); + updateTitle(); + + LLSidepanelInventory* sidepanel_inventory = getParentSidepanelInventory(); + if (sidepanel_inventory) + { + if(mSingleFolderMode) + { + sidepanel_inventory->hideInbox(); + } + else + { + sidepanel_inventory->toggleInbox(); + } + } + +} + +void LLPanelMainInventory::onUpFolderClicked() +{ + const LLViewerInventoryCategory* cat = gInventory.getCategory(mSingleFolderPanelInventory->getSingleFolderRoot()); + if (cat) + { + if (cat->getParentUUID().notNull()) + { + mSingleFolderPanelInventory->changeFolderRoot(cat->getParentUUID()); + } + } +} + +void LLPanelMainInventory::onBackFolderClicked() +{ + mSingleFolderPanelInventory->onBackwardFolder(); +} + +void LLPanelMainInventory::onForwardFolderClicked() +{ + mSingleFolderPanelInventory->onForwardFolder(); +} + +void LLPanelMainInventory::setSingleFolderViewRoot(const LLUUID& folder_id, bool clear_nav_history) +{ + mSingleFolderPanelInventory->changeFolderRoot(folder_id); + if(clear_nav_history) + { + mSingleFolderPanelInventory->clearNavigationHistory(); + } +} + void LLPanelMainInventory::showActionMenu(LLMenuGL* menu, std::string spawning_view_name) { if (menu) @@ -1233,11 +1345,6 @@ void LLPanelMainInventory::showActionMenu(LLMenuGL* menu, std::string spawning_v } } -void LLPanelMainInventory::onTrashButtonClick() -{ - onClipboardAction("delete"); -} - void LLPanelMainInventory::onClipboardAction(const LLSD& userdata) { std::string command_name = userdata.asString(); @@ -1266,6 +1373,7 @@ void LLPanelMainInventory::onCustomAction(const LLSD& userdata) return; const std::string command_name = userdata.asString(); + if (command_name == "new_window") { newWindow(); @@ -1381,6 +1489,11 @@ void LLPanelMainInventory::onCustomAction(const LLSD& userdata) LLFloaterReg::showInstance("linkreplace", params); } + if (command_name == "toggle_search_outfits") + { + mActivePanel->getFilter().toggleSearchVisibilityOutfits(); + } + if (command_name == "toggle_search_trash") { mActivePanel->getFilter().toggleSearchVisibilityTrash(); @@ -1516,6 +1629,21 @@ BOOL LLPanelMainInventory::isActionEnabled(const LLSD& userdata) return TRUE; } +bool LLPanelMainInventory::isActionVisible(const LLSD& userdata) +{ + const std::string param_str = userdata.asString(); + if (param_str == "single_folder_view") + { + return mSingleFolderMode; + } + if (param_str == "multi_folder_view") + { + return !mSingleFolderMode; + } + + return true; +} + BOOL LLPanelMainInventory::isActionChecked(const LLSD& userdata) { U32 sort_order_mask = getActivePanel()->getSortOrder(); @@ -1540,6 +1668,11 @@ BOOL LLPanelMainInventory::isActionChecked(const LLSD& userdata) return sort_order_mask & LLInventoryFilter::SO_SYSTEM_FOLDERS_TO_TOP; } + if (command_name == "toggle_search_outfits") + { + return (mActivePanel->getFilter().getSearchVisibilityTypes() & LLInventoryFilter::VISIBILITY_OUTFITS) != 0; + } + if (command_name == "toggle_search_trash") { return (mActivePanel->getFilter().getSearchVisibilityTypes() & LLInventoryFilter::VISIBILITY_TRASH) != 0; @@ -1555,21 +1688,20 @@ BOOL LLPanelMainInventory::isActionChecked(const LLSD& userdata) return (mActivePanel->getFilter().getSearchVisibilityTypes() & LLInventoryFilter::VISIBILITY_LINKS) != 0; } - return FALSE; -} - -bool LLPanelMainInventory::handleDragAndDropToTrash(BOOL drop, EDragAndDropType cargo_type, EAcceptance* accept) -{ - *accept = ACCEPT_NO; - - const bool is_enabled = isActionEnabled("delete"); - if (is_enabled) *accept = ACCEPT_YES_MULTI; + if (command_name == "list_view") + { + return true; + } + if (command_name == "gallery_view") + { + return false; + } + if (command_name == "combination_view") + { + return false; + } - if (is_enabled && drop) - { - onClipboardAction("delete"); - } - return true; + return FALSE; } void LLPanelMainInventory::setUploadCostIfNeeded() @@ -1592,5 +1724,34 @@ bool LLPanelMainInventory::hasSettingsInventory() return LLEnvironment::instance().isInventoryEnabled(); } +void LLPanelMainInventory::updateTitle() +{ + LLFloater* inventory_floater = gFloaterView->getParentFloater(this); + if(inventory_floater) + { + if(mSingleFolderMode) + { + const LLViewerInventoryCategory* cat = gInventory.getCategory(mSingleFolderPanelInventory->getSingleFolderRoot()); + if (cat) + { + inventory_floater->setTitle(cat->getName()); + } + } + else + { + inventory_floater->setTitle(getString("inventory_title")); + } + } +} + +LLSidepanelInventory* LLPanelMainInventory::getParentSidepanelInventory() +{ + LLFloaterSidePanelContainer* inventory_container = dynamic_cast<LLFloaterSidePanelContainer*>(gFloaterView->getParentFloater(this)); + if(inventory_container) + { + return dynamic_cast<LLSidepanelInventory*>(inventory_container->findChild<LLPanel>("main_panel", true)); + } + return NULL; +} // List Commands // //////////////////////////////////////////////////////////////////////////////// diff --git a/indra/newview/llpanelmaininventory.h b/indra/newview/llpanelmaininventory.h index 257bce930c..6382f44bc9 100644 --- a/indra/newview/llpanelmaininventory.h +++ b/indra/newview/llpanelmaininventory.h @@ -30,6 +30,7 @@ #include "llpanel.h" #include "llinventoryobserver.h" +#include "llinventorypanel.h" #include "lldndbutton.h" #include "llfolderview.h" @@ -43,6 +44,7 @@ class LLTabContainer; class LLFloaterInventoryFinder; class LLMenuButton; class LLMenuGL; +class LLSidepanelInventory; class LLToggleableMenu; class LLFloater; @@ -92,10 +94,17 @@ public: void setFocusFilterEditor(); static void newWindow(); + static void newFolderWindow(LLUUID folder_id = LLUUID(), LLUUID item_to_select = LLUUID()); void toggleFindOptions(); void resetFilters(); + void onViewModeClick(); + void onUpFolderClicked(); + void onBackFolderClicked(); + void onForwardFolderClicked(); + void setSingleFolderViewRoot(const LLUUID& folder_id, bool clear_nav_history = true); + bool isSingleFolderMode() { return mSingleFolderMode; } protected: // @@ -130,6 +139,8 @@ protected: void onSelectSearchType(); void updateSearchTypeCombo(); + LLSidepanelInventory* getParentSidepanelInventory(); + private: LLFloaterInventoryFinder* getFinder(); @@ -149,7 +160,10 @@ private: std::string mCategoryCountString; LLComboBox* mSearchTypeCombo; + bool mSingleFolderMode; + LLInventorySingleFolderPanel* mSingleFolderPanelInventory; + boost::signals2::connection mFolderRootChangedConnection; ////////////////////////////////////////////////////////////////////////////////// // List Commands // @@ -158,22 +172,23 @@ protected: void updateListCommands(); void onAddButtonClick(); void showActionMenu(LLMenuGL* menu, std::string spawning_view_name); - void onTrashButtonClick(); void onClipboardAction(const LLSD& userdata); BOOL isActionEnabled(const LLSD& command_name); BOOL isActionChecked(const LLSD& userdata); void onCustomAction(const LLSD& command_name); - bool handleDragAndDropToTrash(BOOL drop, EDragAndDropType cargo_type, EAcceptance* accept); + bool isActionVisible(const LLSD& userdata); static bool hasSettingsInventory(); + void updateTitle(); /** * Set upload cost in "Upload" sub menu. */ void setUploadCostIfNeeded(); private: - LLDragAndDropButton* mTrashButton; LLToggleableMenu* mMenuGearDefault; + LLToggleableMenu* mMenuViewDefault; LLToggleableMenu* mMenuVisibility; LLMenuButton* mGearMenuButton; + LLMenuButton* mViewMenuButton; LLMenuButton* mVisibilityMenuButton; LLHandle<LLView> mMenuAddHandle; diff --git a/indra/newview/llpanelmarketplaceinbox.cpp b/indra/newview/llpanelmarketplaceinbox.cpp index 8a86f4f63d..3638ee14fc 100644 --- a/indra/newview/llpanelmarketplaceinbox.cpp +++ b/indra/newview/llpanelmarketplaceinbox.cpp @@ -75,9 +75,6 @@ BOOL LLPanelMarketplaceInbox::postBuild() void LLPanelMarketplaceInbox::onSelectionChange() { - LLSidepanelInventory* sidepanel_inventory = LLFloaterSidePanelContainer::getPanel<LLSidepanelInventory>("inventory"); - - sidepanel_inventory->updateVerbs(); } diff --git a/indra/newview/llpanelobjectinventory.cpp b/indra/newview/llpanelobjectinventory.cpp index bd40c9dd2b..1348996136 100644 --- a/indra/newview/llpanelobjectinventory.cpp +++ b/indra/newview/llpanelobjectinventory.cpp @@ -116,6 +116,7 @@ public: virtual PermissionMask getPermissionMask() const { return PERM_NONE; } /*virtual*/ LLFolderType::EType getPreferredType() const { return LLFolderType::FT_NONE; } virtual const LLUUID& getUUID() const { return mUUID; } + virtual const LLUUID& getThumbnailUUID() const { return LLUUID::null;} virtual time_t getCreationDate() const; virtual void setCreationDate(time_t creation_date_utc); @@ -124,6 +125,7 @@ public: virtual BOOL canOpenItem() const { return FALSE; } virtual void closeItem() {} virtual void selectItem() {} + virtual void navigateToFolder(bool new_window = false, bool change_mode = false) {} virtual BOOL isItemRenameable() const; virtual BOOL renameItem(const std::string& new_name); virtual BOOL isItemMovable() const; @@ -1397,21 +1399,6 @@ void LLPanelObjectInventory::inventoryChanged(LLViewerObject* object, { mInventoryNeedsUpdate = TRUE; } - - // refresh any properties floaters that are hanging around. - if(inventory) - { - for (LLInventoryObject::object_list_t::const_iterator iter = inventory->begin(); - iter != inventory->end(); ) - { - LLInventoryObject* item = *iter++; - LLFloaterProperties* floater = LLFloaterReg::findTypedInstance<LLFloaterProperties>("properties", item->getUUID()); - if(floater) - { - floater->refresh(); - } - } - } } void LLPanelObjectInventory::updateInventory() diff --git a/indra/newview/llpanelprofile.cpp b/indra/newview/llpanelprofile.cpp index 708ff26ced..078c1370ee 100644 --- a/indra/newview/llpanelprofile.cpp +++ b/indra/newview/llpanelprofile.cpp @@ -71,6 +71,7 @@ #include "llpanelblockedlist.h" #include "llpanelprofileclassifieds.h" #include "llpanelprofilepicks.h" +#include "llthumbnailctrl.h" #include "lltrans.h" #include "llviewercontrol.h" #include "llviewermenu.h" //is_agent_mappable @@ -365,7 +366,7 @@ LLUUID post_profile_image(std::string cap_url, const LLSD &first_data, std::stri httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS]; status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults); - LL_WARNS("AvatarProperties") << result << LL_ENDL; + LL_DEBUGS("AvatarProperties") << result << LL_ENDL; if (!status) { @@ -908,7 +909,7 @@ BOOL LLPanelProfileSecondLife::postBuild() { mGroupList = getChild<LLGroupList>("group_list"); mShowInSearchCombo = getChild<LLComboBox>("show_in_search"); - mSecondLifePic = getChild<LLIconCtrl>("2nd_life_pic"); + mSecondLifePic = getChild<LLThumbnailCtrl>("2nd_life_pic"); mSecondLifePicLayout = getChild<LLPanel>("image_panel"); mDescriptionEdit = getChild<LLTextEditor>("sl_description_edit"); mAgentActionMenuButton = getChild<LLMenuButton>("agent_actions_menu"); @@ -1437,7 +1438,6 @@ void LLPanelProfileSecondLife::setLoaded() } - class LLProfileImagePicker : public LLFilePickerThread { public: @@ -1484,15 +1484,20 @@ void LLProfileImagePicker::notify(const std::vector<std::string>& filenames) const S32 MAX_DIM = 256; if (!LLViewerTextureList::createUploadFile(file_path, temp_file, codec, MAX_DIM)) { - //todo: image not supported notification - LL_WARNS("AvatarProperties") << "Failed to upload profile image of type " << (S32)PROFILE_IMAGE_SL << ", failed to open image" << LL_ENDL; + LLSD notif_args; + notif_args["REASON"] = LLImage::getLastError().c_str(); + LLNotificationsUtil::add("CannotUploadTexture", notif_args); + LL_WARNS("AvatarProperties") << "Failed to upload profile image of type " << (S32)mType << ", " << notif_args["REASON"].asString() << LL_ENDL; return; } std::string cap_url = gAgent.getRegionCapability(PROFILE_IMAGE_UPLOAD_CAP); if (cap_url.empty()) { - LL_WARNS("AvatarProperties") << "Failed to upload profile image of type " << (S32)PROFILE_IMAGE_SL << ", no cap found" << LL_ENDL; + LLSD args; + args["CAPABILITY"] = PROFILE_IMAGE_UPLOAD_CAP; + LLNotificationsUtil::add("RegionCapabilityRequestError", args); + LL_WARNS("AvatarProperties") << "Failed to upload profile image of type " << (S32)mType << ", no cap found" << LL_ENDL; return; } @@ -2133,7 +2138,7 @@ LLPanelProfileFirstLife::~LLPanelProfileFirstLife() BOOL LLPanelProfileFirstLife::postBuild() { mDescriptionEdit = getChild<LLTextEditor>("fl_description_edit"); - mPicture = getChild<LLIconCtrl>("real_world_pic"); + mPicture = getChild<LLThumbnailCtrl>("real_world_pic"); mUploadPhoto = getChild<LLButton>("fl_upload_image"); mChangePhoto = getChild<LLButton>("fl_change_image"); diff --git a/indra/newview/llpanelprofile.h b/indra/newview/llpanelprofile.h index d32bb943bd..11632a10ae 100644 --- a/indra/newview/llpanelprofile.h +++ b/indra/newview/llpanelprofile.h @@ -58,6 +58,7 @@ class LLTextBase; class LLMenuButton; class LLLineEditor; class LLTextEditor; +class LLThumbnailCtrl; class LLPanelProfileClassifieds; class LLPanelProfilePicks; class LLViewerFetchedTexture; @@ -192,7 +193,7 @@ private: LLGroupList* mGroupList; LLComboBox* mShowInSearchCombo; - LLIconCtrl* mSecondLifePic; + LLThumbnailCtrl* mSecondLifePic; LLPanel* mSecondLifePicLayout; LLTextEditor* mDescriptionEdit; LLMenuButton* mAgentActionMenuButton; @@ -301,7 +302,7 @@ protected: void onDiscardDescriptionChanges(); LLTextEditor* mDescriptionEdit; - LLIconCtrl* mPicture; + LLThumbnailCtrl* mPicture; LLButton* mUploadPhoto; LLButton* mChangePhoto; LLButton* mRemovePhoto; diff --git a/indra/newview/llpathfindingnavmesh.cpp b/indra/newview/llpathfindingnavmesh.cpp index 0287c07f96..c297cac771 100644 --- a/indra/newview/llpathfindingnavmesh.cpp +++ b/indra/newview/llpathfindingnavmesh.cpp @@ -143,7 +143,7 @@ void LLPathfindingNavMesh::handleNavMeshResult(const LLSD &pContent, U32 pNavMes unsigned int binSize = value.size(); std::string newStr(reinterpret_cast<const char *>(&value[0]), binSize); std::istringstream streamdecomp( newStr ); - unsigned int decompBinSize = 0; + size_t decompBinSize = 0; bool valid = false; U8* pUncompressedNavMeshContainer = unzip_llsdNavMesh( valid, decompBinSize, streamdecomp, binSize ) ; if ( !valid ) diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp index 86f7d2bf25..17daff3676 100644 --- a/indra/newview/llselectmgr.cpp +++ b/indra/newview/llselectmgr.cpp @@ -57,7 +57,6 @@ #include "llviewerwindow.h" #include "lldrawable.h" #include "llfloaterinspect.h" -#include "llfloaterproperties.h" #include "llfloaterreporter.h" #include "llfloaterreg.h" #include "llfloatertools.h" @@ -6850,8 +6849,6 @@ void dialog_refresh_all() gMenuAttachmentOther->arrange(); } - LLFloaterProperties::dirtyAll(); - LLFloaterInspect* inspect_instance = LLFloaterReg::getTypedInstance<LLFloaterInspect>("inspect"); if(inspect_instance) { diff --git a/indra/newview/llsettingsvo.cpp b/indra/newview/llsettingsvo.cpp index 707b602fc6..b1eed81476 100644 --- a/indra/newview/llsettingsvo.cpp +++ b/indra/newview/llsettingsvo.cpp @@ -568,11 +568,11 @@ void LLSettingsVOSky::convertAtmosphericsToLegacy(LLSD& legacy, LLSD& settings) legacy[SETTING_BLUE_DENSITY] = ensure_array_4(legacyhaze[SETTING_BLUE_DENSITY], 1.0); legacy[SETTING_BLUE_HORIZON] = ensure_array_4(legacyhaze[SETTING_BLUE_HORIZON], 1.0); - legacy[SETTING_DENSITY_MULTIPLIER] = LLSDArray(legacyhaze[SETTING_DENSITY_MULTIPLIER].asReal())(0.0f)(0.0f)(1.0f); - legacy[SETTING_DISTANCE_MULTIPLIER] = LLSDArray(legacyhaze[SETTING_DISTANCE_MULTIPLIER].asReal())(0.0f)(0.0f)(1.0f); + legacy[SETTING_DENSITY_MULTIPLIER] = llsd::array(legacyhaze[SETTING_DENSITY_MULTIPLIER].asReal(), 0.0f, 0.0f, 1.0f); + legacy[SETTING_DISTANCE_MULTIPLIER] = llsd::array(legacyhaze[SETTING_DISTANCE_MULTIPLIER].asReal(), 0.0f, 0.0f, 1.0f); - legacy[SETTING_HAZE_DENSITY] = LLSDArray(legacyhaze[SETTING_HAZE_DENSITY])(0.0f)(0.0f)(1.0f); - legacy[SETTING_HAZE_HORIZON] = LLSDArray(legacyhaze[SETTING_HAZE_HORIZON])(0.0f)(0.0f)(1.0f); + legacy[SETTING_HAZE_DENSITY] = llsd::array(legacyhaze[SETTING_HAZE_DENSITY], 0.0f, 0.0f, 1.0f); + legacy[SETTING_HAZE_HORIZON] = llsd::array(legacyhaze[SETTING_HAZE_HORIZON], 0.0f, 0.0f, 1.0f); } } @@ -586,15 +586,15 @@ LLSD LLSettingsVOSky::convertToLegacy(const LLSettingsSky::ptr_t &psky, bool isA legacy[SETTING_CLOUD_COLOR] = ensure_array_4(settings[SETTING_CLOUD_COLOR], 1.0); legacy[SETTING_CLOUD_POS_DENSITY1] = ensure_array_4(settings[SETTING_CLOUD_POS_DENSITY1], 1.0); legacy[SETTING_CLOUD_POS_DENSITY2] = ensure_array_4(settings[SETTING_CLOUD_POS_DENSITY2], 1.0); - legacy[SETTING_CLOUD_SCALE] = LLSDArray(settings[SETTING_CLOUD_SCALE])(LLSD::Real(0.0))(LLSD::Real(0.0))(LLSD::Real(1.0)); + legacy[SETTING_CLOUD_SCALE] = llsd::array(settings[SETTING_CLOUD_SCALE], LLSD::Real(0.0), LLSD::Real(0.0), LLSD::Real(1.0)); legacy[SETTING_CLOUD_SCROLL_RATE] = settings[SETTING_CLOUD_SCROLL_RATE]; - legacy[SETTING_LEGACY_ENABLE_CLOUD_SCROLL] = LLSDArray(LLSD::Boolean(!is_approx_zero(settings[SETTING_CLOUD_SCROLL_RATE][0].asReal()))) - (LLSD::Boolean(!is_approx_zero(settings[SETTING_CLOUD_SCROLL_RATE][1].asReal()))); - legacy[SETTING_CLOUD_SHADOW] = LLSDArray(settings[SETTING_CLOUD_SHADOW].asReal())(0.0f)(0.0f)(1.0f); - legacy[SETTING_GAMMA] = LLSDArray(settings[SETTING_GAMMA])(0.0f)(0.0f)(1.0f); + legacy[SETTING_LEGACY_ENABLE_CLOUD_SCROLL] = llsd::array(LLSD::Boolean(!is_approx_zero(settings[SETTING_CLOUD_SCROLL_RATE][0].asReal())), + LLSD::Boolean(!is_approx_zero(settings[SETTING_CLOUD_SCROLL_RATE][1].asReal()))); + legacy[SETTING_CLOUD_SHADOW] = llsd::array(settings[SETTING_CLOUD_SHADOW].asReal(), 0.0f, 0.0f, 1.0f); + legacy[SETTING_GAMMA] = llsd::array(settings[SETTING_GAMMA], 0.0f, 0.0f, 1.0f); legacy[SETTING_GLOW] = ensure_array_4(settings[SETTING_GLOW], 1.0); legacy[SETTING_LIGHT_NORMAL] = ensure_array_4(psky->getLightDirection().getValue(), 0.0f); - legacy[SETTING_MAX_Y] = LLSDArray(settings[SETTING_MAX_Y])(0.0f)(0.0f)(1.0f); + legacy[SETTING_MAX_Y] = llsd::array(settings[SETTING_MAX_Y], 0.0f, 0.0f, 1.0f); legacy[SETTING_STAR_BRIGHTNESS] = settings[SETTING_STAR_BRIGHTNESS].asReal() / 250.0f; // convert from 0-500 -> 0-2 ala pre-FS-compat changes legacy[SETTING_SUNLIGHT_COLOR] = ensure_array_4(settings[SETTING_SUNLIGHT_COLOR], 1.0f); @@ -1062,7 +1062,7 @@ LLSettingsDay::ptr_t LLSettingsVODay::buildFromLegacyPreset(const std::string &n newsettings[SETTING_NAME] = name; - LLSD watertrack = LLSDArray( + LLSD watertrack = llsd::array( LLSDMap(SETTING_KEYKFRAME, LLSD::Real(0.0f)) (SETTING_KEYNAME, "water:Default")); @@ -1077,7 +1077,7 @@ LLSettingsDay::ptr_t LLSettingsVODay::buildFromLegacyPreset(const std::string &n skytrack.append(entry); } - newsettings[SETTING_TRACKS] = LLSDArray(watertrack)(skytrack); + newsettings[SETTING_TRACKS] = llsd::array(watertrack, skytrack); LLSD frames(LLSD::emptyMap()); @@ -1165,7 +1165,7 @@ LLSettingsDay::ptr_t LLSettingsVODay::buildFromLegacyMessage(const LLUUID ®io watersettings[SETTING_NAME] = watername; frames[watername] = watersettings; - LLSD watertrack = LLSDArray( + LLSD watertrack = llsd::array( LLSDMap(SETTING_KEYKFRAME, LLSD::Real(0.0f)) (SETTING_KEYNAME, watername)); @@ -1179,7 +1179,7 @@ LLSettingsDay::ptr_t LLSettingsVODay::buildFromLegacyMessage(const LLUUID ®io LLSD newsettings = LLSDMap ( SETTING_NAME, "Region (legacy)" ) - ( SETTING_TRACKS, LLSDArray(watertrack)(skytrack)) + ( SETTING_TRACKS, llsd::array(watertrack, skytrack)) ( SETTING_FRAMES, frames ) ( SETTING_TYPE, "daycycle" ); @@ -1360,7 +1360,7 @@ LLSD LLSettingsVODay::convertToLegacy(const LLSettingsVODay::ptr_t &pday) skys[name.str()] = std::static_pointer_cast<LLSettingsSky>((*it).second); F32 frame = ((tracksky.size() == 1) && (it == tracksky.begin())) ? -1.0f : (*it).first; - llsdcycle.append( LLSDArray(LLSD::Real(frame))(name.str()) ); + llsdcycle.append( llsd::array(LLSD::Real(frame), name.str()) ); } LLSD llsdskylist(LLSD::emptyMap()); @@ -1373,7 +1373,7 @@ LLSD LLSettingsVODay::convertToLegacy(const LLSettingsVODay::ptr_t &pday) llsdskylist[(*its).first] = llsdsky; } - return LLSDArray(LLSD::emptyMap())(llsdcycle)(llsdskylist)(llsdwater); + return llsd::array(LLSD::emptyMap(), llsdcycle, llsdskylist, llsdwater); } LLSettingsSkyPtr_t LLSettingsVODay::getDefaultSky() const diff --git a/indra/newview/llsidepanelinventory.cpp b/indra/newview/llsidepanelinventory.cpp index a5dcdc41ed..3a0302e531 100644 --- a/indra/newview/llsidepanelinventory.cpp +++ b/indra/newview/llsidepanelinventory.cpp @@ -115,21 +115,19 @@ private: LLSidepanelInventory::LLSidepanelInventory() : LLPanel() - , mItemPanel(NULL) , mPanelMainInventory(NULL) , mInboxEnabled(false) , mCategoriesObserver(NULL) , mInboxAddedObserver(NULL) + , mInboxLayoutPanel(NULL) { //buildFromFile( "panel_inventory.xml"); // Called from LLRegisterPanelClass::defaultPanelClassBuilder() } 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()); + gSavedPerAccountSettings.setS32("InventoryInboxHeight", mInboxLayoutPanel->getTargetDim()); if (mCategoriesObserver && gInventory.containsObserver(mCategoriesObserver)) { @@ -158,29 +156,11 @@ BOOL LLSidepanelInventory::postBuild() // UI elements from inventory panel { mInventoryPanel = getChild<LLPanel>("sidepanel_inventory_panel"); - - mInfoBtn = mInventoryPanel->getChild<LLButton>("info_btn"); - mInfoBtn->setClickedCallback(boost::bind(&LLSidepanelInventory::onInfoButtonClicked, this)); - - mShareBtn = mInventoryPanel->getChild<LLButton>("share_btn"); - mShareBtn->setClickedCallback(boost::bind(&LLSidepanelInventory::onShareButtonClicked, this)); - - mShopBtn = mInventoryPanel->getChild<LLButton>("shop_btn"); - mShopBtn->setClickedCallback(boost::bind(&LLSidepanelInventory::onShopButtonClicked, this)); - - mWearBtn = mInventoryPanel->getChild<LLButton>("wear_btn"); - mWearBtn->setClickedCallback(boost::bind(&LLSidepanelInventory::onWearButtonClicked, this)); - - mPlayBtn = mInventoryPanel->getChild<LLButton>("play_btn"); - mPlayBtn->setClickedCallback(boost::bind(&LLSidepanelInventory::onPlayButtonClicked, this)); - - mTeleportBtn = mInventoryPanel->getChild<LLButton>("teleport_btn"); - mTeleportBtn->setClickedCallback(boost::bind(&LLSidepanelInventory::onTeleportButtonClicked, this)); mPanelMainInventory = mInventoryPanel->getChild<LLPanelMainInventory>("panel_main_inventory"); mPanelMainInventory->setSelectCallback(boost::bind(&LLSidepanelInventory::onSelectionChange, this, _1, _2)); - LLTabContainer* tabs = mPanelMainInventory->getChild<LLTabContainer>("inventory filter tabs"); - tabs->setCommitCallback(boost::bind(&LLSidepanelInventory::updateVerbs, this)); + //LLTabContainer* tabs = mPanelMainInventory->getChild<LLTabContainer>("inventory filter tabs"); + //tabs->setCommitCallback(boost::bind(&LLSidepanelInventory::updateVerbs, this)); /* EXT-4846 : "Can we suppress the "Landmarks" and "My Favorites" folder since they have their own Task Panel?" @@ -190,25 +170,7 @@ BOOL LLSidepanelInventory::postBuild() my_inventory_panel->addHideFolderType(LLFolderType::FT_FAVORITE); */ - LLOutfitObserver::instance().addCOFChangedCallback(boost::bind(&LLSidepanelInventory::updateVerbs, this)); - } - - // UI elements from item panel - { - mItemPanel = getChild<LLSidepanelItemInfo>("sidepanel__item_panel"); - - LLButton* back_btn = mItemPanel->getChild<LLButton>("back_btn"); - back_btn->setClickedCallback(boost::bind(&LLSidepanelInventory::onBackButtonClicked, this)); - } - - // UI elements from task panel - { - mTaskPanel = findChild<LLSidepanelTaskInfo>("sidepanel__task_panel"); - if (mTaskPanel) - { - LLButton* back_btn = mTaskPanel->getChild<LLButton>("back_btn"); - back_btn->setClickedCallback(boost::bind(&LLSidepanelInventory::onBackButtonClicked, this)); - } + //LLOutfitObserver::instance().addCOFChangedCallback(boost::bind(&LLSidepanelInventory::updateVerbs, this)); } // Received items inbox setup @@ -224,11 +186,11 @@ BOOL LLSidepanelInventory::postBuild() bool is_inbox_collapsed = !inbox_button->getToggleState(); // Restore the collapsed inbox panel state - LLLayoutPanel* inbox_panel = getChild<LLLayoutPanel>(INBOX_LAYOUT_PANEL_NAME); - inv_stack->collapsePanel(inbox_panel, is_inbox_collapsed); + mInboxLayoutPanel = getChild<LLLayoutPanel>(INBOX_LAYOUT_PANEL_NAME); + inv_stack->collapsePanel(mInboxLayoutPanel, is_inbox_collapsed); if (!is_inbox_collapsed) { - inbox_panel->setTargetDim(gSavedPerAccountSettings.getS32("InventoryInboxHeight")); + mInboxLayoutPanel->setTargetDim(gSavedPerAccountSettings.getS32("InventoryInboxHeight")); } // Set the inbox visible based on debug settings (final setting comes from http request below) @@ -240,9 +202,6 @@ BOOL LLSidepanelInventory::postBuild() gSavedSettings.getControl("InventoryDisplayInbox")->getCommitSignal()->connect(boost::bind(&handleInventoryDisplayInboxChanged)); - // Update the verbs buttons state. - updateVerbs(); - return TRUE; } @@ -336,8 +295,20 @@ void LLSidepanelInventory::enableInbox(bool enabled) { mInboxEnabled = enabled; - LLLayoutPanel * inbox_layout_panel = getChild<LLLayoutPanel>(INBOX_LAYOUT_PANEL_NAME); - inbox_layout_panel->setVisible(enabled); + if(!enabled || !mPanelMainInventory->isSingleFolderMode()) + { + toggleInbox(); + } +} + +void LLSidepanelInventory::hideInbox() +{ + mInboxLayoutPanel->setVisible(false); +} + +void LLSidepanelInventory::toggleInbox() +{ + mInboxLayoutPanel->setVisible(mInboxEnabled); } void LLSidepanelInventory::openInbox() @@ -367,25 +338,24 @@ void LLSidepanelInventory::onInboxChanged(const LLUUID& inbox_id) void LLSidepanelInventory::onToggleInboxBtn() { LLButton* inboxButton = getChild<LLButton>(INBOX_BUTTON_NAME); - LLLayoutPanel* inboxPanel = getChild<LLLayoutPanel>(INBOX_LAYOUT_PANEL_NAME); LLLayoutStack* inv_stack = getChild<LLLayoutStack>(INVENTORY_LAYOUT_STACK_NAME); const bool inbox_expanded = inboxButton->getToggleState(); // Expand/collapse the indicated panel - inv_stack->collapsePanel(inboxPanel, !inbox_expanded); + inv_stack->collapsePanel(mInboxLayoutPanel, !inbox_expanded); if (inbox_expanded) { - inboxPanel->setTargetDim(gSavedPerAccountSettings.getS32("InventoryInboxHeight")); - if (inboxPanel->isInVisibleChain()) + mInboxLayoutPanel->setTargetDim(gSavedPerAccountSettings.getS32("InventoryInboxHeight")); + if (mInboxLayoutPanel->isInVisibleChain()) { gSavedPerAccountSettings.setU32("LastInventoryInboxActivity", time_corrected()); } } else { - gSavedPerAccountSettings.setS32("InventoryInboxHeight", inboxPanel->getTargetDim()); + gSavedPerAccountSettings.setS32("InventoryInboxHeight", mInboxLayoutPanel->getTargetDim()); } } @@ -408,48 +378,6 @@ void LLSidepanelInventory::onOpen(const LLSD& key) gSavedPerAccountSettings.setU32("LastInventoryInboxActivity", time_corrected()); } #endif - - if(key.size() == 0) - return; - - mItemPanel->reset(); - - if (key.has("id")) - { - mItemPanel->setItemID(key["id"].asUUID()); - if (key.has("object")) - { - mItemPanel->setObjectID(key["object"].asUUID()); - } - showItemInfoPanel(); - } - if (key.has("task")) - { - if (mTaskPanel) - mTaskPanel->setObjectSelection(LLSelectMgr::getInstance()->getSelection()); - showTaskInfoPanel(); - } -} - -void LLSidepanelInventory::onInfoButtonClicked() -{ - LLInventoryItem *item = getSelectedItem(); - if (item) - { - mItemPanel->reset(); - mItemPanel->setItemID(item->getUUID()); - showItemInfoPanel(); - } -} - -void LLSidepanelInventory::onShareButtonClicked() -{ - LLAvatarActions::shareWithAvatars(this); -} - -void LLSidepanelInventory::onShopButtonClicked() -{ - LLWeb::loadURL(gSavedSettings.getString("MarketplaceURL")); } void LLSidepanelInventory::performActionOnSelection(const std::string &action) @@ -471,47 +399,6 @@ void LLSidepanelInventory::performActionOnSelection(const std::string &action) static_cast<LLFolderViewModelItemInventory*>(current_item->getViewModelItem())->performAction(mPanelMainInventory->getActivePanel()->getModel(), action); } -void LLSidepanelInventory::onWearButtonClicked() -{ - // Get selected items set. - const std::set<LLUUID> selected_uuids_set = LLAvatarActions::getInventorySelectedUUIDs(); - if (selected_uuids_set.empty()) return; // nothing selected - - // Convert the set to a vector. - uuid_vec_t selected_uuids_vec; - for (std::set<LLUUID>::const_iterator it = selected_uuids_set.begin(); it != selected_uuids_set.end(); ++it) - { - selected_uuids_vec.push_back(*it); - } - - // Wear all selected items. - wear_multiple(selected_uuids_vec, true); -} - -void LLSidepanelInventory::onPlayButtonClicked() -{ - const LLInventoryItem *item = getSelectedItem(); - if (!item) - { - return; - } - - switch(item->getInventoryType()) - { - case LLInventoryType::IT_GESTURE: - performActionOnSelection("play"); - break; - default: - performActionOnSelection("open"); - break; - } -} - -void LLSidepanelInventory::onTeleportButtonClicked() -{ - performActionOnSelection("teleport"); -} - void LLSidepanelInventory::onBackButtonClicked() { showInventoryPanel(); @@ -519,102 +406,12 @@ void LLSidepanelInventory::onBackButtonClicked() void LLSidepanelInventory::onSelectionChange(const std::deque<LLFolderViewItem*> &items, BOOL user_action) { - updateVerbs(); -} - -void LLSidepanelInventory::showItemInfoPanel() -{ - mItemPanel->setVisible(TRUE); - if (mTaskPanel) - mTaskPanel->setVisible(FALSE); - mInventoryPanel->setVisible(FALSE); - - mItemPanel->dirty(); - mItemPanel->setIsEditing(FALSE); -} - -void LLSidepanelInventory::showTaskInfoPanel() -{ - mItemPanel->setVisible(FALSE); - mInventoryPanel->setVisible(FALSE); - if (mTaskPanel) - { - mTaskPanel->setVisible(TRUE); - mTaskPanel->dirty(); - mTaskPanel->setIsEditing(FALSE); - } } void LLSidepanelInventory::showInventoryPanel() { - mItemPanel->setVisible(FALSE); - if (mTaskPanel) - mTaskPanel->setVisible(FALSE); mInventoryPanel->setVisible(TRUE); - updateVerbs(); -} - -void LLSidepanelInventory::updateVerbs() -{ - mInfoBtn->setEnabled(FALSE); - mShareBtn->setEnabled(FALSE); - - mWearBtn->setVisible(FALSE); - mWearBtn->setEnabled(FALSE); - mPlayBtn->setVisible(FALSE); - mPlayBtn->setEnabled(FALSE); - mPlayBtn->setToolTip(std::string("")); - mTeleportBtn->setVisible(FALSE); - mTeleportBtn->setEnabled(FALSE); - mShopBtn->setVisible(TRUE); - - mShareBtn->setEnabled(canShare()); - - const LLInventoryItem *item = getSelectedItem(); - if (!item) - return; - - bool is_single_selection = getSelectedCount() == 1; - - mInfoBtn->setEnabled(is_single_selection); - - switch(item->getInventoryType()) - { - case LLInventoryType::IT_WEARABLE: - case LLInventoryType::IT_OBJECT: - case LLInventoryType::IT_ATTACHMENT: - mWearBtn->setVisible(TRUE); - mWearBtn->setEnabled(canWearSelected()); - mShopBtn->setVisible(FALSE); - break; - case LLInventoryType::IT_SOUND: - mPlayBtn->setVisible(TRUE); - mPlayBtn->setEnabled(TRUE); - mPlayBtn->setToolTip(LLTrans::getString("InventoryPlaySoundTooltip")); - mShopBtn->setVisible(FALSE); - break; - case LLInventoryType::IT_GESTURE: - mPlayBtn->setVisible(TRUE); - mPlayBtn->setEnabled(TRUE); - mPlayBtn->setToolTip(LLTrans::getString("InventoryPlayGestureTooltip")); - mShopBtn->setVisible(FALSE); - break; - case LLInventoryType::IT_ANIMATION: - mPlayBtn->setVisible(TRUE); - mPlayBtn->setEnabled(TRUE); - mPlayBtn->setEnabled(TRUE); - mPlayBtn->setToolTip(LLTrans::getString("InventoryPlayAnimationTooltip")); - mShopBtn->setVisible(FALSE); - break; - case LLInventoryType::IT_LANDMARK: - mTeleportBtn->setVisible(TRUE); - mTeleportBtn->setEnabled(TRUE); - mShopBtn->setVisible(FALSE); - break; - default: - break; - } } bool LLSidepanelInventory::canShare() @@ -741,8 +538,6 @@ void LLSidepanelInventory::clearSelections(bool clearMain, bool clearInbox) { mInventoryPanelInbox.get()->getRootFolder()->clearSelection(); } - - updateVerbs(); } std::set<LLFolderViewItem*> LLSidepanelInventory::getInboxSelectionList() diff --git a/indra/newview/llsidepanelinventory.h b/indra/newview/llsidepanelinventory.h index a3cd20a2c6..3a252a87c6 100644 --- a/indra/newview/llsidepanelinventory.h +++ b/indra/newview/llsidepanelinventory.h @@ -66,8 +66,6 @@ public: void clearSelections(bool clearMain, bool clearInbox); std::set<LLFolderViewItem*> getInboxSelectionList(); - void showItemInfoPanel(); - void showTaskInfoPanel(); void showInventoryPanel(); // checks can share selected item(s) @@ -76,13 +74,13 @@ public: void onToggleInboxBtn(); void enableInbox(bool enabled); + void toggleInbox(); + void hideInbox(); void openInbox(); bool isInboxEnabled() const { return mInboxEnabled; } - void updateVerbs(); - static void cleanup(); protected: @@ -103,27 +101,14 @@ protected: private: LLPanel* mInventoryPanel; // Main inventory view LLHandle<LLInventoryPanel> mInventoryPanelInbox; - LLSidepanelItemInfo* mItemPanel; // Individual item view - LLSidepanelTaskInfo* mTaskPanel; // Individual in-world object view LLPanelMainInventory* mPanelMainInventory; + LLLayoutPanel* mInboxLayoutPanel; + protected: - void onInfoButtonClicked(); - void onShareButtonClicked(); - void onShopButtonClicked(); - void onWearButtonClicked(); - void onPlayButtonClicked(); - void onTeleportButtonClicked(); void onBackButtonClicked(); private: - LLButton* mInfoBtn; - LLButton* mShareBtn; - LLButton* mWearBtn; - LLButton* mPlayBtn; - LLButton* mTeleportBtn; - LLButton* mShopBtn; - bool mInboxEnabled; LLInventoryCategoriesObserver* mCategoriesObserver; diff --git a/indra/newview/llsidepaneliteminfo.cpp b/indra/newview/llsidepaneliteminfo.cpp index b23e24a222..312dee8c93 100644 --- a/indra/newview/llsidepaneliteminfo.cpp +++ b/indra/newview/llsidepaneliteminfo.cpp @@ -31,16 +31,23 @@ #include "llagent.h" #include "llavataractions.h" +#include "llavatarnamecache.h" #include "llbutton.h" +#include "llcallbacklist.h" #include "llcombobox.h" +#include "llfloater.h" #include "llfloaterreg.h" #include "llgroupactions.h" +#include "llgroupmgr.h" +#include "lliconctrl.h" #include "llinventorydefines.h" +#include "llinventoryicon.h" #include "llinventorymodel.h" #include "llinventoryobserver.h" #include "lllineeditor.h" #include "llradiogroup.h" #include "llslurl.h" +#include "lltexteditor.h" #include "llviewercontrol.h" #include "llviewerinventory.h" #include "llviewerobjectlist.h" @@ -73,49 +80,6 @@ private: }; //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// Class LLItemPropertiesObserver -// -// Helper class to watch for changes to the item. -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -class LLItemPropertiesObserver : public LLInventoryObserver -{ -public: - LLItemPropertiesObserver(LLSidepanelItemInfo* floater) - : mFloater(floater) - { - gInventory.addObserver(this); - } - virtual ~LLItemPropertiesObserver() - { - gInventory.removeObserver(this); - } - virtual void changed(U32 mask); -private: - LLSidepanelItemInfo* mFloater; // Not a handle because LLSidepanelItemInfo is managing LLItemPropertiesObserver -}; - -void LLItemPropertiesObserver::changed(U32 mask) -{ - const std::set<LLUUID>& mChangedItemIDs = gInventory.getChangedIDs(); - std::set<LLUUID>::const_iterator it; - - const LLUUID& item_id = mFloater->getItemID(); - - for (it = mChangedItemIDs.begin(); it != mChangedItemIDs.end(); it++) - { - // set dirty for 'item profile panel' only if changed item is the item for which 'item profile panel' is shown (STORM-288) - if (*it == item_id) - { - // if there's a change we're interested in. - if((mask & (LLInventoryObserver::LABEL | LLInventoryObserver::INTERNAL | LLInventoryObserver::REMOVE)) != 0) - { - mFloater->dirty(); - } - } - } -} - -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Class LLObjectInventoryObserver // // Helper class to watch for changes in an object inventory. @@ -158,36 +122,47 @@ static LLPanelInjector<LLSidepanelItemInfo> t_item_info("sidepanel_item_info"); // Default constructor LLSidepanelItemInfo::LLSidepanelItemInfo(const LLPanel::Params& p) - : LLSidepanelInventorySubpanel(p) + : LLPanel(p) , mItemID(LLUUID::null) , mObjectInventoryObserver(NULL) , mUpdatePendingId(-1) + , mIsDirty(false) /*Not ready*/ + , mParentFloater(NULL) { - mPropertiesObserver = new LLItemPropertiesObserver(this); + gInventory.addObserver(this); + gIdleCallbacks.addFunction(&LLSidepanelItemInfo::onIdle, (void*)this); } // Destroys the object LLSidepanelItemInfo::~LLSidepanelItemInfo() { - delete mPropertiesObserver; - mPropertiesObserver = NULL; + gInventory.removeObserver(this); + gIdleCallbacks.deleteFunction(&LLSidepanelItemInfo::onIdle, (void*)this); stopObjectInventoryObserver(); + + if (mOwnerCacheConnection.connected()) + { + mOwnerCacheConnection.disconnect(); + } + if (mCreatorCacheConnection.connected()) + { + mCreatorCacheConnection.disconnect(); + } } // virtual BOOL LLSidepanelItemInfo::postBuild() { - LLSidepanelInventorySubpanel::postBuild(); - + mLabelOwnerName = getChild<LLTextBox>("LabelOwnerName"); + mLabelCreatorName = getChild<LLTextBox>("LabelCreatorName"); + mItemTypeIcon = getChild<LLIconCtrl>("item_type_icon"); + getChild<LLLineEditor>("LabelItemName")->setPrevalidate(&LLTextValidate::validateASCIIPrintableNoPipe); getChild<LLUICtrl>("LabelItemName")->setCommitCallback(boost::bind(&LLSidepanelItemInfo::onCommitName,this)); - getChild<LLLineEditor>("LabelItemDesc")->setPrevalidate(&LLTextValidate::validateASCIIPrintableNoPipe); getChild<LLUICtrl>("LabelItemDesc")->setCommitCallback(boost::bind(&LLSidepanelItemInfo:: onCommitDescription, this)); - // Creator information - getChild<LLUICtrl>("BtnCreator")->setCommitCallback(boost::bind(&LLSidepanelItemInfo::onClickCreator,this)); - // owner information - getChild<LLUICtrl>("BtnOwner")->setCommitCallback(boost::bind(&LLSidepanelItemInfo::onClickOwner,this)); + // Thumnail edition + getChild<LLUICtrl>("change_thumbnail_btn")->setCommitCallback(boost::bind(&LLSidepanelItemInfo::onEditThumbnail, this)); // acquired date // owner permissions // Permissions debug text @@ -226,6 +201,12 @@ void LLSidepanelItemInfo::setItemID(const LLUUID& item_id) mItemID = item_id; mUpdatePendingId = -1; } + dirty(); +} + +void LLSidepanelItemInfo::setParentFloater(LLFloater* parent) +{ + mParentFloater = parent; } const LLUUID& LLSidepanelItemInfo::getObjectID() const @@ -249,12 +230,11 @@ void LLSidepanelItemInfo::onUpdateCallback(const LLUUID& item_id, S32 received_u void LLSidepanelItemInfo::reset() { - LLSidepanelInventorySubpanel::reset(); - mObjectID = LLUUID::null; mItemID = LLUUID::null; stopObjectInventoryObserver(); + dirty(); } void LLSidepanelItemInfo::refresh() @@ -262,60 +242,26 @@ void LLSidepanelItemInfo::refresh() LLViewerInventoryItem* item = findItem(); if(item) { - refreshFromItem(item); - updateVerbs(); + const LLUUID trash_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_TRASH); + bool in_trash = (item->getUUID() == trash_id) || gInventory.isObjectDescendentOf(item->getUUID(), trash_id); + if (in_trash && mParentFloater) + { + // Close properties when moving to trash + // Aren't supposed to view properties from trash + mParentFloater->closeFloater(); + } + else + { + refreshFromItem(item); + } return; } - else - { - if (getIsEditing()) - { - setIsEditing(FALSE); - } - } - - if (!getIsEditing()) - { - const std::string no_item_names[]={ - "LabelItemName", - "LabelItemDesc", - "LabelCreatorName", - "LabelOwnerName" - }; - - for(size_t t=0; t<LL_ARRAY_SIZE(no_item_names); ++t) - { - getChildView(no_item_names[t])->setEnabled(false); - } - - setPropertiesFieldsEnabled(false); - - const std::string hide_names[]={ - "BaseMaskDebug", - "OwnerMaskDebug", - "GroupMaskDebug", - "EveryoneMaskDebug", - "NextMaskDebug" - }; - for(size_t t=0; t<LL_ARRAY_SIZE(hide_names); ++t) - { - getChildView(hide_names[t])->setVisible(false); - } - } - - if (!item) - { - const std::string no_edit_mode_names[]={ - "BtnCreator", - "BtnOwner", - }; - for(size_t t=0; t<LL_ARRAY_SIZE(no_edit_mode_names); ++t) - { - getChildView(no_edit_mode_names[t])->setEnabled(false); - } - } - - updateVerbs(); + + if (mParentFloater) + { + // if we failed to get item, it likely no longer exists + mParentFloater->closeFloater(); + } } void LLSidepanelItemInfo::refreshFromItem(LLViewerInventoryItem* item) @@ -385,8 +331,22 @@ void LLSidepanelItemInfo::refreshFromItem(LLViewerInventoryItem* item) getChild<LLUICtrl>("LabelItemName")->setValue(item->getName()); getChildView("LabelItemDescTitle")->setEnabled(TRUE); getChildView("LabelItemDesc")->setEnabled(is_modifiable); - getChildView("IconLocked")->setVisible(!is_modifiable); getChild<LLUICtrl>("LabelItemDesc")->setValue(item->getDescription()); + getChild<LLUICtrl>("item_thumbnail")->setValue(item->getThumbnailUUID()); + + LLUIImagePtr icon_img = LLInventoryIcon::getIcon(item->getType(), item->getInventoryType(), item->getFlags(), FALSE); + mItemTypeIcon->setImage(icon_img); + + // Style for creator and owner links + LLStyle::Params style_params; + LLColor4 link_color = LLUIColorTable::instance().getColor("HTMLLinkColor"); + style_params.color = link_color; + style_params.readonly_color = link_color; + style_params.is_link = true; // link will be added later + const LLFontGL* fontp = mLabelCreatorName->getFont(); + style_params.font.name = LLFontGL::nameFromFont(fontp); + style_params.font.size = LLFontGL::sizeFromFont(fontp); + style_params.font.style = "UNDERLINE"; ////////////////// // CREATOR NAME // @@ -397,19 +357,34 @@ void LLSidepanelItemInfo::refreshFromItem(LLViewerInventoryItem* item) if (item->getCreatorUUID().notNull()) { LLUUID creator_id = item->getCreatorUUID(); - std::string name = - LLSLURL("agent", creator_id, "completename").getSLURLString(); - getChildView("BtnCreator")->setEnabled(TRUE); + std::string slurl = + LLSLURL("agent", creator_id, "inspect").getSLURLString(); + + style_params.link_href = slurl; + + LLAvatarName av_name; + if (LLAvatarNameCache::get(creator_id, &av_name)) + { + updateCreatorName(creator_id, av_name, style_params); + } + else + { + if (mCreatorCacheConnection.connected()) + { + mCreatorCacheConnection.disconnect(); + } + mLabelCreatorName->setText(LLTrans::getString("None")); + mCreatorCacheConnection = LLAvatarNameCache::get(creator_id, boost::bind(&LLSidepanelItemInfo::updateCreatorName, this, _1, _2, style_params)); + } + getChildView("LabelCreatorTitle")->setEnabled(TRUE); - getChildView("LabelCreatorName")->setEnabled(FALSE); - getChild<LLUICtrl>("LabelCreatorName")->setValue(name); + mLabelCreatorName->setEnabled(TRUE); } else { - getChildView("BtnCreator")->setEnabled(FALSE); getChildView("LabelCreatorTitle")->setEnabled(FALSE); - getChildView("LabelCreatorName")->setEnabled(FALSE); - getChild<LLUICtrl>("LabelCreatorName")->setValue(getString("unknown_multiple")); + mLabelCreatorName->setEnabled(FALSE); + mLabelCreatorName->setValue(getString("unknown_multiple")); } //////////////// @@ -417,27 +392,56 @@ void LLSidepanelItemInfo::refreshFromItem(LLViewerInventoryItem* item) //////////////// if(perm.isOwned()) { - std::string name; + std::string slurl; if (perm.isGroupOwned()) { - gCacheName->getGroupName(perm.getGroup(), name); + LLGroupMgrGroupData* group_data = LLGroupMgr::getInstance()->getGroupData(perm.getGroup()); + + slurl = LLSLURL("group", perm.getGroup(), "inspect").getSLURLString(); + style_params.link_href = slurl; + if (group_data && group_data->isGroupPropertiesDataComplete()) + { + mLabelOwnerName->setText(group_data->mName, style_params); + } + else + { + // Triggers refresh + LLGroupMgr::getInstance()->sendGroupPropertiesRequest(perm.getGroup()); + + std::string name; + gCacheName->getGroupName(perm.getGroup(), name); + mLabelOwnerName->setText(name, style_params); + } } else { LLUUID owner_id = perm.getOwner(); - name = LLSLURL("agent", owner_id, "completename").getSLURLString(); + slurl = LLSLURL("agent", owner_id, "inspect").getSLURLString(); + + style_params.link_href = slurl; + LLAvatarName av_name; + if (LLAvatarNameCache::get(owner_id, &av_name)) + { + updateOwnerName(owner_id, av_name, style_params); + } + else + { + if (mOwnerCacheConnection.connected()) + { + mOwnerCacheConnection.disconnect(); + } + mLabelOwnerName->setText(LLTrans::getString("None")); + mOwnerCacheConnection = LLAvatarNameCache::get(owner_id, boost::bind(&LLSidepanelItemInfo::updateOwnerName, this, _1, _2, style_params)); + } } - getChildView("BtnOwner")->setEnabled(TRUE); getChildView("LabelOwnerTitle")->setEnabled(TRUE); - getChildView("LabelOwnerName")->setEnabled(FALSE); - getChild<LLUICtrl>("LabelOwnerName")->setValue(name); + mLabelOwnerName->setEnabled(TRUE); } else { - getChildView("BtnOwner")->setEnabled(FALSE); getChildView("LabelOwnerTitle")->setEnabled(FALSE); - getChildView("LabelOwnerName")->setEnabled(FALSE); - getChild<LLUICtrl>("LabelOwnerName")->setValue(getString("public")); + mLabelOwnerName->setEnabled(FALSE); + mLabelOwnerName->setValue(getString("public")); } //////////// @@ -548,6 +552,8 @@ void LLSidepanelItemInfo::refreshFromItem(LLViewerInventoryItem* item) if( gSavedSettings.getBOOL("DebugPermissions") ) { + childSetVisible("layout_debug_permissions", true); + BOOL slam_perm = FALSE; BOOL overwrite_group = FALSE; BOOL overwrite_everyone = FALSE; @@ -565,38 +571,29 @@ void LLSidepanelItemInfo::refreshFromItem(LLViewerInventoryItem* item) perm_string = "B: "; perm_string += mask_to_string(base_mask); getChild<LLUICtrl>("BaseMaskDebug")->setValue(perm_string); - getChildView("BaseMaskDebug")->setVisible(TRUE); perm_string = "O: "; perm_string += mask_to_string(owner_mask); getChild<LLUICtrl>("OwnerMaskDebug")->setValue(perm_string); - getChildView("OwnerMaskDebug")->setVisible(TRUE); perm_string = "G"; perm_string += overwrite_group ? "*: " : ": "; perm_string += mask_to_string(group_mask); getChild<LLUICtrl>("GroupMaskDebug")->setValue(perm_string); - getChildView("GroupMaskDebug")->setVisible(TRUE); perm_string = "E"; perm_string += overwrite_everyone ? "*: " : ": "; perm_string += mask_to_string(everyone_mask); getChild<LLUICtrl>("EveryoneMaskDebug")->setValue(perm_string); - getChildView("EveryoneMaskDebug")->setVisible(TRUE); perm_string = "N"; perm_string += slam_perm ? "*: " : ": "; perm_string += mask_to_string(next_owner_mask); getChild<LLUICtrl>("NextMaskDebug")->setValue(perm_string); - getChildView("NextMaskDebug")->setVisible(TRUE); } else { - getChildView("BaseMaskDebug")->setVisible(FALSE); - getChildView("OwnerMaskDebug")->setVisible(FALSE); - getChildView("GroupMaskDebug")->setVisible(FALSE); - getChildView("EveryoneMaskDebug")->setVisible(FALSE); - getChildView("NextMaskDebug")->setVisible(FALSE); + childSetVisible("layout_debug_permissions", false); } ///////////// @@ -731,6 +728,68 @@ void LLSidepanelItemInfo::refreshFromItem(LLViewerInventoryItem* item) } } +void LLSidepanelItemInfo::updateCreatorName(const LLUUID& creator_id, const LLAvatarName& creator_name, const LLStyle::Params& style_params) +{ + if (mCreatorCacheConnection.connected()) + { + mCreatorCacheConnection.disconnect(); + } + std::string name = creator_name.getCompleteName(); + mLabelCreatorName->setText(name, style_params); +} + +void LLSidepanelItemInfo::updateOwnerName(const LLUUID& owner_id, const LLAvatarName& owner_name, const LLStyle::Params& style_params) +{ + if (mOwnerCacheConnection.connected()) + { + mOwnerCacheConnection.disconnect(); + } + std::string name = owner_name.getCompleteName(); + mLabelOwnerName->setText(name, style_params); +} + +void LLSidepanelItemInfo::changed(U32 mask) +{ + const LLUUID& item_id = getItemID(); + if (getObjectID().notNull() || item_id.isNull()) + { + // Task inventory or not set up yet + return; + } + + const std::set<LLUUID>& mChangedItemIDs = gInventory.getChangedIDs(); + std::set<LLUUID>::const_iterator it; + + for (it = mChangedItemIDs.begin(); it != mChangedItemIDs.end(); it++) + { + // set dirty for 'item profile panel' only if changed item is the item for which 'item profile panel' is shown (STORM-288) + if (*it == item_id) + { + // if there's a change we're interested in. + if((mask & (LLInventoryObserver::LABEL | LLInventoryObserver::INTERNAL | LLInventoryObserver::REMOVE)) != 0) + { + dirty(); + } + } + } +} + +void LLSidepanelItemInfo::dirty() +{ + mIsDirty = true; +} + +// static +void LLSidepanelItemInfo::onIdle( void* user_data ) +{ + LLSidepanelItemInfo* self = reinterpret_cast<LLSidepanelItemInfo*>(user_data); + + if( self->mIsDirty ) + { + self->refresh(); + self->mIsDirty = false; + } +} void LLSidepanelItemInfo::setAssociatedExperience( LLHandle<LLSidepanelItemInfo> hInfo, const LLSD& experience ) { @@ -853,7 +912,7 @@ void LLSidepanelItemInfo::onCommitDescription() LLViewerInventoryItem* item = findItem(); if(!item) return; - LLLineEditor* labelItemDesc = getChild<LLLineEditor>("LabelItemDesc"); + LLTextEditor* labelItemDesc = getChild<LLTextEditor>("LabelItemDesc"); if(!labelItemDesc) { return; @@ -966,7 +1025,14 @@ void LLSidepanelItemInfo::updatePermissions() } } -// static +void LLSidepanelItemInfo::onEditThumbnail() +{ + LLSD data; + data["task_id"] = mObjectID; + data["item_id"] = mItemID; + LLFloaterReg::showInstance("change_item_thumbnail", data); +} + void LLSidepanelItemInfo::onCommitSaleInfo(LLUICtrl* ctrl) { if (ctrl) diff --git a/indra/newview/llsidepaneliteminfo.h b/indra/newview/llsidepaneliteminfo.h index 5f29254182..ba1d5c263a 100644 --- a/indra/newview/llsidepaneliteminfo.h +++ b/indra/newview/llsidepaneliteminfo.h @@ -27,42 +27,55 @@ #ifndef LL_LLSIDEPANELITEMINFO_H #define LL_LLSIDEPANELITEMINFO_H -#include "llsidepanelinventorysubpanel.h" +#include "llinventoryobserver.h" +#include "llpanel.h" +#include "llstyle.h" //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Class LLSidepanelItemInfo // Object properties for inventory side panel. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +class LLAvatarName; class LLButton; +class LLFloater; +class LLIconCtrl; class LLViewerInventoryItem; class LLItemPropertiesObserver; class LLObjectInventoryObserver; class LLViewerObject; class LLPermissions; +class LLTextBox; -class LLSidepanelItemInfo : public LLSidepanelInventorySubpanel +class LLSidepanelItemInfo : public LLPanel, public LLInventoryObserver { public: LLSidepanelItemInfo(const LLPanel::Params& p = getDefaultParams()); virtual ~LLSidepanelItemInfo(); - /*virtual*/ BOOL postBuild(); + /*virtual*/ BOOL postBuild() override; /*virtual*/ void reset(); void setObjectID(const LLUUID& object_id); void setItemID(const LLUUID& item_id); - void setEditMode(BOOL edit); + void setParentFloater(LLFloater* parent); // For simplicity const LLUUID& getObjectID() const; const LLUUID& getItemID() const; // if received update and item id (from callback) matches internal ones, update UI void onUpdateCallback(const LLUUID& item_id, S32 received_update_id); + + void changed(U32 mask) override; + void dirty(); + + static void onIdle( void* user_data ); + void updateOwnerName(const LLUUID& owner_id, const LLAvatarName& owner_name, const LLStyle::Params& style_params); + void updateCreatorName(const LLUUID& creator_id, const LLAvatarName& creator_name, const LLStyle::Params& style_params); protected: - /*virtual*/ void refresh(); - /*virtual*/ void save(); + void refresh() override; + void save(); LLViewerInventoryItem* findItem() const; LLViewerObject* findObject() const; @@ -75,14 +88,22 @@ private: void startObjectInventoryObserver(); void stopObjectInventoryObserver(); void setPropertiesFieldsEnabled(bool enabled); + + boost::signals2::connection mOwnerCacheConnection; + boost::signals2::connection mCreatorCacheConnection; LLUUID mItemID; // inventory UUID for the inventory item. LLUUID mObjectID; // in-world task UUID, or null if in agent inventory. - LLItemPropertiesObserver* mPropertiesObserver; // for syncing changes to item LLObjectInventoryObserver* mObjectInventoryObserver; // for syncing changes to items inside an object // We can send multiple properties updates simultaneously, make sure only last response counts and there won't be a race condition. S32 mUpdatePendingId; + bool mIsDirty; // item properties need to be updated + LLFloater* mParentFloater; + + LLTextBox* mLabelOwnerName; + LLTextBox* mLabelCreatorName; + LLIconCtrl* mItemTypeIcon; // // UI Elements @@ -94,6 +115,7 @@ protected: void onCommitDescription(); void onCommitPermissions(LLUICtrl* ctrl); void updatePermissions(); + void onEditThumbnail(); void onCommitSaleInfo(LLUICtrl* ctrl); void updateSaleInfo(); void onCommitChanges(LLPointer<LLViewerInventoryItem> item); diff --git a/indra/newview/llsidepaneltaskinfo.cpp b/indra/newview/llsidepaneltaskinfo.cpp index 7fa06f51e3..5e363fc9b1 100644 --- a/indra/newview/llsidepaneltaskinfo.cpp +++ b/indra/newview/llsidepaneltaskinfo.cpp @@ -42,6 +42,7 @@ #include "llresmgr.h" #include "lltextbox.h" #include "llbutton.h" +#include "llcallbacklist.h" #include "llcheckboxctrl.h" #include "llviewerobject.h" #include "llselectmgr.h" @@ -78,6 +79,7 @@ LLSidepanelTaskInfo::LLSidepanelTaskInfo() { setMouseOpaque(FALSE); LLSelectMgr::instance().mUpdateSignal.connect(boost::bind(&LLSidepanelTaskInfo::refreshAll, this)); + gIdleCallbacks.addFunction(&LLSidepanelTaskInfo::onIdle, (void*)this); } @@ -85,13 +87,12 @@ LLSidepanelTaskInfo::~LLSidepanelTaskInfo() { if (sActivePanel == this) sActivePanel = NULL; + gIdleCallbacks.deleteFunction(&LLSidepanelTaskInfo::onIdle, (void*)this); } // virtual BOOL LLSidepanelTaskInfo::postBuild() { - LLSidepanelInventorySubpanel::postBuild(); - mOpenBtn = getChild<LLButton>("open_btn"); mOpenBtn->setClickedCallback(boost::bind(&LLSidepanelTaskInfo::onOpenButtonClicked, this)); mPayBtn = getChild<LLButton>("pay_btn"); @@ -253,6 +254,8 @@ void LLSidepanelTaskInfo::disablePermissions() void LLSidepanelTaskInfo::refresh() { + mIsDirty = false; + LLButton* btn_deed_to_group = mDeedBtn; if (btn_deed_to_group) { @@ -864,33 +867,6 @@ void LLSidepanelTaskInfo::refresh() getChildView("label click action")->setEnabled(is_perm_modify && is_nonpermanent_enforced && all_volume); getChildView("clickaction")->setEnabled(is_perm_modify && is_nonpermanent_enforced && all_volume); - if (!getIsEditing()) - { - const std::string no_item_names[] = - { - "Object Name", - "Object Description", - "button set group", - "checkbox share with group", - "button deed", - "checkbox allow everyone move", - "checkbox allow everyone copy", - "checkbox for sale", - "sale type", - "Edit Cost", - "checkbox next owner can modify", - "checkbox next owner can copy", - "checkbox next owner can transfer", - "clickaction", - "search_check", - "perm_modify", - "Group Name", - }; - for (size_t t=0; t<LL_ARRAY_SIZE(no_item_names); ++t) - { - getChildView(no_item_names[t])->setEnabled( FALSE); - } - } updateVerbs(); } @@ -1202,16 +1178,6 @@ void LLSidepanelTaskInfo::onCommitIncludeInSearch(LLUICtrl* ctrl, void* data) // virtual void LLSidepanelTaskInfo::updateVerbs() { - LLSidepanelInventorySubpanel::updateVerbs(); - - /* - mOpenBtn->setVisible(!getIsEditing()); - mPayBtn->setVisible(!getIsEditing()); - mBuyBtn->setVisible(!getIsEditing()); - //const LLViewerObject *obj = getFirstSelectedObject(); - //mEditBtn->setEnabled(obj && obj->permModify()); - */ - LLSafeHandle<LLObjectSelection> object_selection = LLSelectMgr::getInstance()->getSelection(); const BOOL any_selected = (object_selection->getNumNodes() > 0); @@ -1296,6 +1262,23 @@ LLSidepanelTaskInfo* LLSidepanelTaskInfo::getActivePanel() return sActivePanel; } +void LLSidepanelTaskInfo::dirty() +{ + mIsDirty = true; +} + +// static +void LLSidepanelTaskInfo::onIdle( void* user_data ) +{ + LLSidepanelTaskInfo* self = reinterpret_cast<LLSidepanelTaskInfo*>(user_data); + + if( self->mIsDirty ) + { + self->refresh(); + self->mIsDirty = false; + } +} + LLViewerObject* LLSidepanelTaskInfo::getObject() { if (!mObject->isDead()) diff --git a/indra/newview/llsidepaneltaskinfo.h b/indra/newview/llsidepaneltaskinfo.h index dc259cb22d..fbecf6f79f 100644 --- a/indra/newview/llsidepaneltaskinfo.h +++ b/indra/newview/llsidepaneltaskinfo.h @@ -27,8 +27,8 @@ #ifndef LL_LLSIDEPANELTASKINFO_H #define LL_LLSIDEPANELTASKINFO_H -#include "llsidepanelinventorysubpanel.h" #include "lluuid.h" +#include "llpanel.h" #include "llselectmgr.h" //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -43,14 +43,14 @@ class LLNameBox; class LLViewerObject; class LLTextBase; -class LLSidepanelTaskInfo : public LLSidepanelInventorySubpanel +class LLSidepanelTaskInfo : public LLPanel { public: LLSidepanelTaskInfo(); virtual ~LLSidepanelTaskInfo(); - /*virtual*/ BOOL postBuild(); - /*virtual*/ void onVisibilityChange ( BOOL new_visibility ); + BOOL postBuild() override; + void onVisibilityChange ( BOOL new_visibility ) override; void setObjectSelection(LLObjectSelectionHandle selection); @@ -58,10 +58,12 @@ public: LLViewerObject* getFirstSelectedObject(); static LLSidepanelTaskInfo *getActivePanel(); + void dirty(); + static void onIdle( void* user_data ); protected: - /*virtual*/ void refresh(); // refresh all labels as needed - /*virtual*/ void save(); - /*virtual*/ void updateVerbs(); + void refresh() override; // refresh all labels as needed + void save(); + void updateVerbs(); void refreshAll(); // ignore current keyboard focus and update all fields @@ -103,6 +105,8 @@ private: LLUUID mCreatorID; LLUUID mOwnerID; LLUUID mLastOwnerID; + + bool mIsDirty; protected: void onOpenButtonClicked(); diff --git a/indra/newview/llsnapshotlivepreview.cpp b/indra/newview/llsnapshotlivepreview.cpp index ed7e18fadc..37ebcd1266 100644 --- a/indra/newview/llsnapshotlivepreview.cpp +++ b/indra/newview/llsnapshotlivepreview.cpp @@ -51,6 +51,7 @@ #include "llviewercontrol.h" #include "llviewermenufile.h" // upload_new_resource() #include "llviewerstats.h" +#include "llviewertexturelist.h" #include "llwindow.h" #include "llworld.h" #include <boost/filesystem.hpp> @@ -873,6 +874,41 @@ LLPointer<LLImageRaw> LLSnapshotLivePreview::getEncodedImage() return mPreviewImageEncoded; } +bool LLSnapshotLivePreview::createUploadFile(const std::string &out_filename, const S32 max_image_dimentions, const S32 min_image_dimentions) +{ + // make a copy, since convertToUploadFile modifies raw image + LLPointer<LLImageRaw> raw_image = new LLImageRaw( + mPreviewImage->getData(), + mPreviewImage->getWidth(), + mPreviewImage->getHeight(), + mPreviewImage->getComponents()); + + LLPointer<LLImageJ2C> compressedImage = LLViewerTextureList::convertToUploadFile(raw_image, max_image_dimentions); + if (compressedImage->getWidth() < min_image_dimentions || compressedImage->getHeight() < min_image_dimentions) + { + std::string reason = llformat("Images below %d x %d pixels are not allowed. Actual size: %d x %dpx", + min_image_dimentions, + min_image_dimentions, + compressedImage->getWidth(), + compressedImage->getHeight()); + compressedImage->setLastError(reason); + return FALSE; + } + if (compressedImage.isNull()) + { + compressedImage->setLastError("Couldn't convert the image to jpeg2000."); + LL_INFOS() << "Couldn't convert to j2c, file : " << out_filename << LL_ENDL; + return false; + } + if (!compressedImage->save(out_filename)) + { + compressedImage->setLastError("Couldn't create the jpeg2000 image for upload."); + LL_INFOS() << "Couldn't create output file : " << out_filename << LL_ENDL; + return false; + } + return true; +} + // We actually estimate the data size so that we do not require actual compression when showing the preview // Note : whenever formatted image is computed, mDataSize will be updated to reflect the true size void LLSnapshotLivePreview::estimateDataSize() diff --git a/indra/newview/llsnapshotlivepreview.h b/indra/newview/llsnapshotlivepreview.h index 1f81307976..6e38a957b4 100644 --- a/indra/newview/llsnapshotlivepreview.h +++ b/indra/newview/llsnapshotlivepreview.h @@ -106,6 +106,7 @@ public: LLPointer<LLImageFormatted> getFormattedImage(); LLPointer<LLImageRaw> getEncodedImage(); + bool createUploadFile(const std::string &out_file, const S32 max_image_dimentions, const S32 min_image_dimentions); /// Sets size of preview thumbnail image and the surrounding rect. void setThumbnailPlaceholderRect(const LLRect& rect) {mThumbnailPlaceholderRect = rect; } diff --git a/indra/newview/lltexturecache.cpp b/indra/newview/lltexturecache.cpp index af89b4b53b..5c6f7254f2 100644 --- a/indra/newview/lltexturecache.cpp +++ b/indra/newview/lltexturecache.cpp @@ -859,12 +859,12 @@ LLTextureCache::~LLTextureCache() ////////////////////////////////////////////////////////////////////////////// //virtual -S32 LLTextureCache::update(F32 max_time_ms) +size_t LLTextureCache::update(F32 max_time_ms) { static LLFrameTimer timer ; static const F32 MAX_TIME_INTERVAL = 300.f ; //seconds. - S32 res; + size_t res; res = LLWorkerThread::update(max_time_ms); mListMutex.lock(); diff --git a/indra/newview/lltexturecache.h b/indra/newview/lltexturecache.h index e1c752b58e..b6ace467c7 100644 --- a/indra/newview/lltexturecache.h +++ b/indra/newview/lltexturecache.h @@ -113,7 +113,7 @@ public: LLTextureCache(bool threaded); ~LLTextureCache(); - /*virtual*/ S32 update(F32 max_time_ms); + /*virtual*/ size_t update(F32 max_time_ms); void purgeCache(ELLPath location, bool remove_dir = true); void setReadOnly(BOOL read_only) ; diff --git a/indra/newview/lltexturefetch.cpp b/indra/newview/lltexturefetch.cpp index a7dcb1a9bb..6f6ca2be9b 100644 --- a/indra/newview/lltexturefetch.cpp +++ b/indra/newview/lltexturefetch.cpp @@ -2879,9 +2879,9 @@ bool LLTextureFetch::updateRequestPriority(const LLUUID& id, F32 priority) // Threads: T* //virtual -S32 LLTextureFetch::getPending() +size_t LLTextureFetch::getPending() { - S32 res; + size_t res; lockData(); // +Ct { LLMutexLock lock(&mQueueMutex); // +Mfq @@ -2956,7 +2956,7 @@ void LLTextureFetch::commonUpdate() // Threads: Tmain //virtual -S32 LLTextureFetch::update(F32 max_time_ms) +size_t LLTextureFetch::update(F32 max_time_ms) { static LLCachedControl<F32> band_width(gSavedSettings,"ThrottleBandwidthKBPS", 3000.0); @@ -2970,7 +2970,7 @@ S32 LLTextureFetch::update(F32 max_time_ms) mNetworkQueueMutex.unlock(); // -Mfnq } - S32 res = LLWorkerThread::update(max_time_ms); + size_t res = LLWorkerThread::update(max_time_ms); if (!mThreaded) { diff --git a/indra/newview/lltexturefetch.h b/indra/newview/lltexturefetch.h index d087db275b..611a7d6419 100644 --- a/indra/newview/lltexturefetch.h +++ b/indra/newview/lltexturefetch.h @@ -65,7 +65,7 @@ public: class TFRequest; // Threads: Tmain - /*virtual*/ S32 update(F32 max_time_ms); + /*virtual*/ size_t update(F32 max_time_ms); // called in the main thread after the TextureCacheThread shuts down. // Threads: Tmain @@ -131,7 +131,7 @@ public: U32 getTotalNumHTTPRequests(); // Threads: T* - S32 getPending(); + size_t getPending(); // Threads: T* void lockQueue() { mQueueMutex.lock(); } diff --git a/indra/newview/llthumbnailctrl.cpp b/indra/newview/llthumbnailctrl.cpp new file mode 100644 index 0000000000..1b054b4c27 --- /dev/null +++ b/indra/newview/llthumbnailctrl.cpp @@ -0,0 +1,231 @@ +/** + * @file llthumbnailctrl.cpp + * @brief LLThumbnailCtrl base class + * + * $LicenseInfo:firstyear=2023&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2023, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" + +#include "llthumbnailctrl.h" + +#include "linden_common.h" +#include "llagent.h" +#include "lluictrlfactory.h" +#include "lluuid.h" +#include "lltrans.h" +#include "llviewborder.h" +#include "llviewertexture.h" +#include "llviewertexturelist.h" +#include "llwindow.h" + +static LLDefaultChildRegistry::Register<LLThumbnailCtrl> r("thumbnail"); + +LLThumbnailCtrl::Params::Params() +: border("border") +, border_color("border_color") +, fallback_image("fallback_image") +, image_name("image_name") +, border_visible("show_visible", false) +, interactable("interactable", false) +, show_loading("show_loading", true) +{} + +LLThumbnailCtrl::LLThumbnailCtrl(const LLThumbnailCtrl::Params& p) +: LLUICtrl(p) +, mBorderColor(p.border_color()) +, mBorderVisible(p.border_visible()) +, mFallbackImagep(p.fallback_image) +, mInteractable(p.interactable()) +, mShowLoadingPlaceholder(p.show_loading()) +, mPriority(LLGLTexture::BOOST_PREVIEW) +{ + mLoadingPlaceholderString = LLTrans::getString("texture_loading"); + + LLRect border_rect = getLocalRect(); + LLViewBorder::Params vbparams(p.border); + vbparams.name("border"); + vbparams.rect(border_rect); + mBorder = LLUICtrlFactory::create<LLViewBorder> (vbparams); + addChild(mBorder); + + if (p.image_name.isProvided()) + { + setValue(p.image_name()); + } +} + +LLThumbnailCtrl::~LLThumbnailCtrl() +{ + mTexturep = nullptr; + mImagep = nullptr; + mFallbackImagep = nullptr; +} + + +void LLThumbnailCtrl::draw() +{ + LLRect draw_rect = getLocalRect(); + + if (mBorderVisible) + { + mBorder->setKeyboardFocusHighlight(hasFocus()); + + gl_rect_2d( draw_rect, mBorderColor.get(), FALSE ); + draw_rect.stretch( -1 ); + } + + // If we're in a focused floater, don't apply the floater's alpha to the texture. + const F32 alpha = getTransparencyType() == TT_ACTIVE ? 1.0f : getCurrentTransparency(); + if( mTexturep ) + { + if( mTexturep->getComponents() == 4 ) + { + gl_rect_2d_checkerboard( draw_rect, alpha ); + } + + gl_draw_scaled_image( draw_rect.mLeft, draw_rect.mBottom, draw_rect.getWidth(), draw_rect.getHeight(), mTexturep, UI_VERTEX_COLOR % alpha); + + mTexturep->setKnownDrawSize(draw_rect.getWidth(), draw_rect.getHeight()); + } + else if( mImagep.notNull() ) + { + mImagep->draw(draw_rect, UI_VERTEX_COLOR % alpha ); + } + else if (mFallbackImagep.notNull()) + { + if (draw_rect.getWidth() > mFallbackImagep->getWidth() + && draw_rect.getHeight() > mFallbackImagep->getHeight()) + { + S32 img_width = mFallbackImagep->getWidth(); + S32 img_height = mFallbackImagep->getHeight(); + S32 rect_width = draw_rect.getWidth(); + S32 rect_height = draw_rect.getHeight(); + + LLRect fallback_rect; + fallback_rect.mLeft = draw_rect.mLeft + (rect_width - img_width) / 2; + fallback_rect.mRight = fallback_rect.mLeft + img_width; + fallback_rect.mBottom = draw_rect.mBottom + (rect_height - img_height) / 2; + fallback_rect.mTop = fallback_rect.mBottom + img_height; + + mFallbackImagep->draw(fallback_rect, UI_VERTEX_COLOR % alpha); + } + else + { + mFallbackImagep->draw(draw_rect, UI_VERTEX_COLOR % alpha); + } + } + else + { + gl_rect_2d( draw_rect, LLColor4::grey % alpha, TRUE ); + + // Draw X + gl_draw_x( draw_rect, LLColor4::black ); + } + + // Show "Loading..." string on the top left corner while this texture is loading. + // Using the discard level, do not show the string if the texture is almost but not + // fully loaded. + if (mTexturep.notNull() + && mShowLoadingPlaceholder + && !mTexturep->isFullyLoaded()) + { + U32 v_offset = 25; + LLFontGL* font = LLFontGL::getFontSansSerif(); + + // Don't show as loaded if the texture is almost fully loaded (i.e. discard1) unless god + if ((mTexturep->getDiscardLevel() > 1) || gAgent.isGodlike()) + { + font->renderUTF8( + mLoadingPlaceholderString, + 0, + llfloor(draw_rect.mLeft+3), + llfloor(draw_rect.mTop-v_offset), + LLColor4::white, + LLFontGL::LEFT, + LLFontGL::BASELINE, + LLFontGL::DROP_SHADOW); + } + } + + LLUICtrl::draw(); +} + +// virtual +// value might be a string or a UUID +void LLThumbnailCtrl::setValue(const LLSD& value) +{ + LLSD tvalue(value); + if (value.isString() && LLUUID::validate(value.asString())) + { + //RN: support UUIDs masquerading as strings + tvalue = LLSD(LLUUID(value.asString())); + } + + LLUICtrl::setValue(tvalue); + + mImageAssetID = LLUUID::null; + mTexturep = nullptr; + mImagep = nullptr; + + if (tvalue.isUUID()) + { + mImageAssetID = tvalue.asUUID(); + if (mImageAssetID.notNull()) + { + // Should it support baked textures? + mTexturep = LLViewerTextureManager::getFetchedTexture(mImageAssetID, FTT_DEFAULT, MIPMAP_YES, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE); + + mTexturep->setBoostLevel(mPriority); + mTexturep->forceToSaveRawImage(0); + + S32 desired_draw_width = mTexturep->getWidth(); + S32 desired_draw_height = mTexturep->getHeight(); + + mTexturep->setKnownDrawSize(desired_draw_width, desired_draw_height); + } + } + else if (tvalue.isString()) + { + mImagep = LLUI::getUIImage(tvalue.asString(), LLGLTexture::BOOST_UI); + if (mImagep) + { + LLViewerFetchedTexture* texture = dynamic_cast<LLViewerFetchedTexture*>(mImagep->getImage().get()); + if(texture) + { + mImageAssetID = texture->getID(); + } + } + } +} + +BOOL LLThumbnailCtrl::handleHover(S32 x, S32 y, MASK mask) +{ + if (mInteractable && getEnabled()) + { + getWindow()->setCursor(UI_CURSOR_HAND); + return TRUE; + } + return LLUICtrl::handleHover(x, y, mask); +} + + diff --git a/indra/newview/llthumbnailctrl.h b/indra/newview/llthumbnailctrl.h new file mode 100644 index 0000000000..dc21046841 --- /dev/null +++ b/indra/newview/llthumbnailctrl.h @@ -0,0 +1,87 @@ +/** + * @file llthumbnailctrl.h + * @brief LLThumbnailCtrl base class + * + * $LicenseInfo:firstyear=2023&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2023 Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#ifndef LL_LLTHUMBNAILCTRL_H +#define LL_LLTHUMBNAILCTRL_H + +#include "llui.h" +#include "lluictrl.h" +#include "llviewborder.h" // for params + +class LLUICtrlFactory; +class LLUUID; +class LLViewerFetchedTexture; + +// +// Classes +// + +// +class LLThumbnailCtrl +: public LLUICtrl +{ +public: + struct Params : public LLInitParam::Block<Params, LLUICtrl::Params> + { + Optional<LLViewBorder::Params> border; + Optional<LLUIColor> border_color; + Optional<std::string> image_name; + Optional<LLUIImage*> fallback_image; + Optional<bool> border_visible; + Optional<bool> interactable; + Optional<bool> show_loading; + + Params(); + }; +protected: + LLThumbnailCtrl(const Params&); + friend class LLUICtrlFactory; + +public: + virtual ~LLThumbnailCtrl(); + + virtual void draw() override; + + virtual void setValue(const LLSD& value ) override; + + virtual BOOL handleHover(S32 x, S32 y, MASK mask) override; + +private: + S32 mPriority; + bool mBorderVisible; + bool mInteractable; + bool mShowLoadingPlaceholder; + std::string mLoadingPlaceholderString; + LLUUID mImageAssetID; + LLViewBorder* mBorder; + LLUIColor mBorderColor; + + LLPointer<LLViewerFetchedTexture> mTexturep; + LLPointer<LLUIImage> mImagep; + LLPointer<LLUIImage> mFallbackImagep; +}; + +#endif diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp index 469df37f8e..581c6779ab 100644 --- a/indra/newview/llviewerfloaterreg.cpp +++ b/indra/newview/llviewerfloaterreg.cpp @@ -56,6 +56,7 @@ #include "llfloaterbvhpreview.h" #include "llfloatercamera.h" #include "llfloatercamerapresets.h" +#include "llfloaterchangeitemthumbnail.h" #include "llfloaterchatvoicevolume.h" #include "llfloaterclassified.h" #include "llfloaterconversationlog.h" @@ -84,6 +85,7 @@ #include "llfloaterimagepreview.h" #include "llfloaterimsession.h" #include "llfloaterinspect.h" +#include "llfloaterinventorysettings.h" #include "llfloaterjoystick.h" #include "llfloaterlagmeter.h" #include "llfloaterland.h" @@ -103,7 +105,7 @@ #include "llfloaterobjectweights.h" #include "llfloateropenobject.h" #include "llfloateroutfitphotopreview.h" -#include "llfloatersimpleoutfitsnapshot.h" +#include "llfloatersimplesnapshot.h" #include "llfloaterpathfindingcharacters.h" #include "llfloaterpathfindingconsole.h" #include "llfloaterpathfindinglinksets.h" @@ -114,7 +116,6 @@ #include "llfloaterpreferenceviewadvanced.h" #include "llfloaterpreviewtrash.h" #include "llfloaterprofile.h" -#include "llfloaterproperties.h" #include "llfloaterregiondebugconsole.h" #include "llfloaterregioninfo.h" #include "llfloaterregionrestarting.h" @@ -328,6 +329,7 @@ void LLViewerFloaterReg::registerFloaters() LLFloaterReg::add("camera", "floater_camera.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterCamera>); LLFloaterReg::add("camera_presets", "floater_camera_presets.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterCameraPresets>); LLFloaterReg::add("chat_voice", "floater_voice_chat_volume.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterChatVoiceVolume>); + LLFloaterReg::add("change_item_thumbnail", "floater_change_item_thumbnail.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterChangeItemThumbnail>); LLFloaterReg::add("nearby_chat", "floater_im_session.xml", (LLFloaterBuildFunc)&LLFloaterIMNearbyChat::buildFloater); LLFloaterReg::add("classified", "floater_classified.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterClassified>); LLFloaterReg::add("compile_queue", "floater_script_queue.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterCompileQueue>); @@ -371,6 +373,8 @@ void LLViewerFloaterReg::registerFloaters() LLFloaterReg::add("inventory", "floater_my_inventory.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSidePanelContainer>); LLFloaterReg::add("inspect", "floater_inspect.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterInspect>); LLFloaterReg::add("item_properties", "floater_item_properties.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterItemProperties>); + LLFloaterReg::add("task_properties", "floater_task_properties.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterItemProperties>); + LLFloaterReg::add("inventory_settings", "floater_inventory_settings.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterInventorySettings>); LLInspectAvatarUtil::registerFloater(); LLInspectGroupUtil::registerFloater(); LLInspectObjectUtil::registerFloater(); @@ -434,7 +438,6 @@ void LLViewerFloaterReg::registerFloaters() LLFloaterReg::add("preview_sound", "floater_preview_sound.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLPreviewSound>, "preview"); LLFloaterReg::add("preview_texture", "floater_preview_texture.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLPreviewTexture>, "preview"); LLFloaterReg::add("preview_trash", "floater_preview_trash.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterPreviewTrash>); - LLFloaterReg::add("properties", "floater_inventory_item_properties.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterProperties>); LLFloaterReg::add("publish_classified", "floater_publish_classified.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLPublishClassifiedFloater>); LLFloaterReg::add("save_pref_preset", "floater_save_pref_preset.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSavePrefPreset>); LLFloaterReg::add("save_camera_preset", "floater_save_camera_preset.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSaveCameraPreset>); @@ -468,7 +471,7 @@ void LLViewerFloaterReg::registerFloaters() LLFloaterReg::add("scene_load_stats", "floater_scene_load_stats.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSceneLoadStats>); LLFloaterReg::add("stop_queue", "floater_script_queue.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterNotRunQueue>); LLFloaterReg::add("snapshot", "floater_snapshot.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSnapshot>); - LLFloaterReg::add("simple_outfit_snapshot", "floater_simple_outfit_snapshot.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSimpleOutfitSnapshot>); + LLFloaterReg::add("simple_snapshot", "floater_simple_snapshot.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSimpleSnapshot>); LLFloaterReg::add("search", "floater_search.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSearch>); LLFloaterReg::add("profile", "floater_profile.xml",(LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterProfile>); LLFloaterReg::add("guidebook", "floater_how_to.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterHowTo>); diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index a0223a5dbb..015a887e9f 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -3042,9 +3042,7 @@ void handle_object_inspect() LLViewerObject* selected_objectp = selection->getFirstRootObject(); if (selected_objectp) { - LLSD key; - key["task"] = "task"; - LLFloaterSidePanelContainer::showPanel("inventory", key); + LLFloaterReg::showInstance("task_properties"); } /* diff --git a/indra/newview/llviewermenufile.cpp b/indra/newview/llviewermenufile.cpp index fdf1d04c09..6c07c28d81 100644 --- a/indra/newview/llviewermenufile.cpp +++ b/indra/newview/llviewermenufile.cpp @@ -38,7 +38,7 @@ #include "llfloatermap.h" #include "llfloatermodelpreview.h" #include "llfloatersnapshot.h" -#include "llfloatersimpleoutfitsnapshot.h" +#include "llfloatersimplesnapshot.h" #include "llimage.h" #include "llimagebmp.h" #include "llimagepng.h" @@ -664,9 +664,7 @@ class LLFileEnableCloseAllWindows : public view_listener_t bool handleEvent(const LLSD& userdata) { LLFloaterSnapshot* floater_snapshot = LLFloaterSnapshot::findInstance(); - LLFloaterSimpleOutfitSnapshot* floater_outfit_snapshot = LLFloaterSimpleOutfitSnapshot::findInstance(); - bool is_floaters_snapshot_opened = (floater_snapshot && floater_snapshot->isInVisibleChain()) - || (floater_outfit_snapshot && floater_outfit_snapshot->isInVisibleChain()); + bool is_floaters_snapshot_opened = (floater_snapshot && floater_snapshot->isInVisibleChain()); bool open_children = gFloaterView->allChildrenClosed() && !is_floaters_snapshot_opened; return !open_children && !LLNotificationsUI::LLToast::isAlertToastShown(); } @@ -681,9 +679,6 @@ class LLFileCloseAllWindows : public view_listener_t LLFloaterSnapshot* floater_snapshot = LLFloaterSnapshot::findInstance(); if (floater_snapshot) floater_snapshot->closeFloater(app_quitting); - LLFloaterSimpleOutfitSnapshot* floater_outfit_snapshot = LLFloaterSimpleOutfitSnapshot::findInstance(); - if (floater_outfit_snapshot) - floater_outfit_snapshot->closeFloater(app_quitting); if (gMenuHolder) gMenuHolder->hideMenus(); return true; } diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index d97ed61e11..5266db5b38 100644 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -6284,7 +6284,7 @@ bool handle_lure_callback(const LLSD& notification, const LLSD& response) // More than OFFER_RECIPIENT_LIMIT targets will overload the message // producing an llerror. LLSD args; - args["OFFERS"] = notification["payload"]["ids"].size(); + args["OFFERS"] = LLSD::Integer(notification["payload"]["ids"].size()); args["LIMIT"] = static_cast<int>(OFFER_RECIPIENT_LIMIT); LLNotificationsUtil::add("TooManyTeleportOffers", args); return false; diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index f47f0b4572..011bea71a4 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -63,7 +63,6 @@ #include "llcontrolavatar.h" #include "lldrawable.h" #include "llface.h" -#include "llfloaterproperties.h" #include "llfloatertools.h" #include "llfollowcam.h" #include "llhudtext.h" @@ -3474,9 +3473,6 @@ void LLViewerObject::doInventoryCallback() void LLViewerObject::removeInventory(const LLUUID& item_id) { - // close any associated floater properties - LLFloaterReg::hideInstance("properties", item_id); - LLMessageSystem* msg = gMessageSystem; msg->newMessageFast(_PREHASH_RemoveTaskInventory); msg->nextBlockFast(_PREHASH_AgentData); diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp index ad7321ca4b..e5d703a6ee 100755 --- a/indra/newview/llviewerregion.cpp +++ b/indra/newview/llviewerregion.cpp @@ -3024,6 +3024,8 @@ void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames) capabilityNames.append("InterestList"); + capabilityNames.append("InventoryCategoryThumbnailUpload"); + capabilityNames.append("InventoryItemThumbnailUpload"); capabilityNames.append("GetDisplayNames"); capabilityNames.append("GetExperiences"); capabilityNames.append("AgentExperiences"); diff --git a/indra/newview/llviewertexteditor.cpp b/indra/newview/llviewertexteditor.cpp index fe68024b98..5ff84558cf 100644 --- a/indra/newview/llviewertexteditor.cpp +++ b/indra/newview/llviewertexteditor.cpp @@ -246,12 +246,17 @@ public: } virtual BOOL handleToolTip(S32 x, S32 y, MASK mask ) { - if (LLAssetType::AT_TEXTURE == mItem->getType()) + if (mItem->getThumbnailUUID().notNull()) { + LLSD params; + params["inv_type"] = mItem->getInventoryType(); + params["thumbnail_id"] = mItem->getThumbnailUUID(); + params["asset_id"] = mItem->getAssetUUID(); + LLToolTipMgr::instance().show(LLToolTip::Params() .message(mToolTip) .create_callback(boost::bind(&LLInspectTextureUtil::createInventoryToolTip, _1)) - .create_params(LLSD().with("inv_type", mItem->getInventoryType()).with("asset_id", mItem->getAssetUUID()))); + .create_params(params)); return TRUE; } diff --git a/indra/newview/llviewertexturelist.cpp b/indra/newview/llviewertexturelist.cpp index 93ae1670c8..901747ce57 100644 --- a/indra/newview/llviewertexturelist.cpp +++ b/indra/newview/llviewertexturelist.cpp @@ -1286,7 +1286,8 @@ void LLViewerTextureList::decodeAllImages(F32 max_time) BOOL LLViewerTextureList::createUploadFile(const std::string& filename, const std::string& out_filename, const U8 codec, - const S32 max_image_dimentions) + const S32 max_image_dimentions, + const S32 min_image_dimentions) { LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; // Load the image @@ -1314,6 +1315,16 @@ BOOL LLViewerTextureList::createUploadFile(const std::string& filename, image->setLastError("Image files with less than 3 or more than 4 components are not supported."); return FALSE; } + if (image->getWidth() < min_image_dimentions || image->getHeight() < min_image_dimentions) + { + std::string reason = llformat("Images below %d x %d pixels are not allowed. Actual size: %d x %dpx", + min_image_dimentions, + min_image_dimentions, + image->getWidth(), + image->getHeight()); + image->setLastError(reason); + return FALSE; + } // Convert to j2c (JPEG2000) and save the file locally LLPointer<LLImageJ2C> compressedImage = convertToUploadFile(raw_image, max_image_dimentions); if (compressedImage.isNull()) diff --git a/indra/newview/llviewertexturelist.h b/indra/newview/llviewertexturelist.h index 0018e78d45..eac26ab0eb 100644 --- a/indra/newview/llviewertexturelist.h +++ b/indra/newview/llviewertexturelist.h @@ -95,7 +95,8 @@ public: static BOOL createUploadFile(const std::string& filename, const std::string& out_filename, const U8 codec, - const S32 max_image_dimentions = LLViewerFetchedTexture::MAX_IMAGE_SIZE_DEFAULT); + const S32 max_image_dimentions = LLViewerFetchedTexture::MAX_IMAGE_SIZE_DEFAULT, + const S32 min_image_dimentions = 0); static LLPointer<LLImageJ2C> convertToUploadFile(LLPointer<LLImageRaw> raw_image, const S32 max_image_dimentions = LLViewerFetchedTexture::MAX_IMAGE_SIZE_DEFAULT); static void processImageNotInDatabase( LLMessageSystem *msg, void **user_data ); diff --git a/indra/newview/skins/default/colors.xml b/indra/newview/skins/default/colors.xml index 8bb3feaeb0..87ccccbff0 100644 --- a/indra/newview/skins/default/colors.xml +++ b/indra/newview/skins/default/colors.xml @@ -407,7 +407,7 @@ value="0.43 0.06 0.06 1" /> <color name="HTMLLinkColor" - reference="EmphasisColor" /> + value="0.3 0.82 1 1" /> <color name="HealthTextColor" reference="White" /> diff --git a/indra/newview/skins/default/textures/icons/copy_clipboard.png b/indra/newview/skins/default/textures/icons/copy_clipboard.png Binary files differnew file mode 100644 index 0000000000..bb1ceff1ce --- /dev/null +++ b/indra/newview/skins/default/textures/icons/copy_clipboard.png diff --git a/indra/newview/skins/default/textures/icons/delete_icon.png b/indra/newview/skins/default/textures/icons/delete_icon.png Binary files differnew file mode 100644 index 0000000000..37ce374653 --- /dev/null +++ b/indra/newview/skins/default/textures/icons/delete_icon.png diff --git a/indra/newview/skins/default/textures/icons/file_upload.png b/indra/newview/skins/default/textures/icons/file_upload.png Binary files differnew file mode 100644 index 0000000000..58f2757136 --- /dev/null +++ b/indra/newview/skins/default/textures/icons/file_upload.png diff --git a/indra/newview/skins/default/textures/icons/multi_folder_mode.png b/indra/newview/skins/default/textures/icons/multi_folder_mode.png Binary files differnew file mode 100644 index 0000000000..8cda3efc36 --- /dev/null +++ b/indra/newview/skins/default/textures/icons/multi_folder_mode.png diff --git a/indra/newview/skins/default/textures/icons/paste_clipboard.png b/indra/newview/skins/default/textures/icons/paste_clipboard.png Binary files differnew file mode 100644 index 0000000000..e1589ab098 --- /dev/null +++ b/indra/newview/skins/default/textures/icons/paste_clipboard.png diff --git a/indra/newview/skins/default/textures/icons/single_folder_back.png b/indra/newview/skins/default/textures/icons/single_folder_back.png Binary files differnew file mode 100644 index 0000000000..b614e9ef9b --- /dev/null +++ b/indra/newview/skins/default/textures/icons/single_folder_back.png diff --git a/indra/newview/skins/default/textures/icons/single_folder_forward.png b/indra/newview/skins/default/textures/icons/single_folder_forward.png Binary files differnew file mode 100644 index 0000000000..c7bee3522d --- /dev/null +++ b/indra/newview/skins/default/textures/icons/single_folder_forward.png diff --git a/indra/newview/skins/default/textures/icons/single_folder_mode.png b/indra/newview/skins/default/textures/icons/single_folder_mode.png Binary files differnew file mode 100644 index 0000000000..f70b754123 --- /dev/null +++ b/indra/newview/skins/default/textures/icons/single_folder_mode.png diff --git a/indra/newview/skins/default/textures/icons/single_folder_up.png b/indra/newview/skins/default/textures/icons/single_folder_up.png Binary files differnew file mode 100644 index 0000000000..651b2b1af1 --- /dev/null +++ b/indra/newview/skins/default/textures/icons/single_folder_up.png diff --git a/indra/newview/skins/default/textures/icons/snapshot_icon.png b/indra/newview/skins/default/textures/icons/snapshot_icon.png Binary files differnew file mode 100644 index 0000000000..41d524678f --- /dev/null +++ b/indra/newview/skins/default/textures/icons/snapshot_icon.png diff --git a/indra/newview/skins/default/textures/icons/texture_icon.png b/indra/newview/skins/default/textures/icons/texture_icon.png Binary files differnew file mode 100644 index 0000000000..278760a5b0 --- /dev/null +++ b/indra/newview/skins/default/textures/icons/texture_icon.png diff --git a/indra/newview/skins/default/textures/icons/thumbnail_fallback_icon.png b/indra/newview/skins/default/textures/icons/thumbnail_fallback_icon.png Binary files differnew file mode 100644 index 0000000000..8d5ca624af --- /dev/null +++ b/indra/newview/skins/default/textures/icons/thumbnail_fallback_icon.png diff --git a/indra/newview/skins/default/textures/textures.xml b/indra/newview/skins/default/textures/textures.xml index 1f2c0867c4..424fc851fd 100644 --- a/indra/newview/skins/default/textures/textures.xml +++ b/indra/newview/skins/default/textures/textures.xml @@ -252,10 +252,16 @@ with the same filename but different name <texture name="Icon_Close_Foreground" file_name="windows/Icon_Close_Foreground.png" preload="true" /> <texture name="Icon_Close_Press" file_name="windows/Icon_Close_Press.png" preload="true" /> <texture name="Icon_Close_Toast" file_name="windows/Icon_Close_Toast.png" preload="true" /> + + <texture name="Icon_Copy" file_name="icons/copy_clipboard.png" preload="true" /> + + <texture name="Icon_Delete" file_name="icons/delete_icon.png" preload="true" /> <texture name="Icon_Dock_Foreground" file_name="windows/Icon_Dock_Foreground.png" preload="true" /> <texture name="Icon_Dock_Press" file_name="windows/Icon_Dock_Press.png" preload="true" /> + <texture name="Icon_File_Upload" file_name="icons/file_upload.png" preload="true" /> + <texture name="Icon_For_Sale" file_name="icons/Icon_For_Sale.png" preload="false" /> <texture name="Icon_Gear_Background" file_name="windows/Icon_Gear_Background.png" preload="false" /> @@ -268,10 +274,16 @@ with the same filename but different name <texture name="Icon_Minimize_Foreground" file_name="windows/Icon_Minimize_Foreground.png" preload="true" /> <texture name="Icon_Minimize_Press" file_name="windows/Icon_Minimize_Press.png" preload="true" /> + + <texture name="Icon_Paste" file_name="icons/paste_clipboard.png" preload="true" /> <texture name="Icon_Restore_Foreground" file_name="windows/Icon_Restore_Foreground.png" preload="false" /> <texture name="Icon_Restore_Press" file_name="windows/Icon_Restore_Press.png" preload="false" /> + <texture name="Icon_Snapshot" file_name="icons/snapshot_icon.png" preload="true" /> + + <texture name="Icon_Use_Texture" file_name="icons/texture_icon.png" preload="true" /> + <texture name="Info" file_name="icons/Info.png" preload="false" /> <texture name="Info_Small" file_name="icons/Info_Small.png" preload="false" /> <texture name="Info_Off" file_name="navbar/Info_Off.png" preload="false" /> @@ -678,6 +690,7 @@ with the same filename but different name <texture name="TextField_Active" file_name="widgets/TextField_Active.png" preload="true" scale.left="9" scale.top="12" scale.right="248" scale.bottom="12" /> <texture name="TextField_Search_Highlight" file_name="widgets/TextField_Search_Highlight.png" preload="true" scale.left="9" scale.top="12" scale.right="248" scale.bottom="12" /> + <texture name="Thumbnail_Fallback" file_name="icons/thumbnail_fallback_icon.png" preload="true" /> <texture name="Toast_CloseBtn" file_name="windows/Toast_CloseBtn.png" preload="true" /> <texture name="Toast_Background" file_name="windows/Toast_Background.png" preload="true" @@ -874,4 +887,10 @@ with the same filename but different name <texture name="System_Notification" file_name="icons/SL_Logo.png" preload="true"/> <texture name="Icon_Attachment_Small" file_name="icons/Icon_Attachment_Small.png" preload="true"/> <texture name="Icon_Attachment_Large" file_name="icons/Icon_Attachment_Large.png" preload="true"/> + + <texture name="Single_Folder_Mode" file_name="icons/single_folder_mode.png" preload="true"/> + <texture name="Multi_Folder_Mode" file_name="icons/multi_folder_mode.png" preload="true"/> + <texture name="Single_Folder_Back" file_name="icons/single_folder_back.png" preload="true"/> + <texture name="Single_Folder_Forward" file_name="icons/single_folder_forward.png" preload="true"/> + <texture name="Single_Folder_Up" file_name="icons/single_folder_up.png" preload="true"/> </textures> diff --git a/indra/newview/skins/default/xui/da/floater_inventory_item_properties.xml b/indra/newview/skins/default/xui/da/floater_inventory_item_properties.xml deleted file mode 100644 index 59dcc87140..0000000000 --- a/indra/newview/skins/default/xui/da/floater_inventory_item_properties.xml +++ /dev/null @@ -1,67 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="item properties" title="OPLYSNINGER OM BEHOLDNINGSGENSTAND"> - <floater.string name="unknown"> - (ukendt) - </floater.string> - <floater.string name="public"> - (offentlig) - </floater.string> - <floater.string name="you_can"> - Du kan: - </floater.string> - <floater.string name="owner_can"> - Ejer kan: - </floater.string> - <floater.string name="acquiredDate"> - [wkday,datetime,local] [mth,datetime,local] [day,datetime,local] [hour,datetime,local]:[min,datetime,local]:[second,datetime,local] [year,datetime,local] - </floater.string> - <text name="LabelItemNameTitle"> - Navn: - </text> - <text name="LabelItemDescTitle"> - Beskrivelse: - </text> - <text name="LabelCreatorTitle"> - Skaber: - </text> - <button label="Profil..." label_selected="" name="BtnCreator"/> - <text name="LabelOwnerTitle"> - Ejer: - </text> - <button label="Profil..." label_selected="" name="BtnOwner"/> - <text name="LabelAcquiredTitle"> - Erhvervet: - </text> - <text name="LabelAcquiredDate"> - Wed May 24 12:50:46 2006 - </text> - <text name="OwnerLabel"> - Dig: - </text> - <check_box label="Redigér" name="CheckOwnerModify"/> - <check_box label="Kopiere" name="CheckOwnerCopy"/> - <check_box label="Sælg" name="CheckOwnerTransfer"/> - <text name="AnyoneLabel"> - Enhver: - </text> - <check_box label="Kopiér" name="CheckEveryoneCopy"/> - <text name="GroupLabel"> - Gruppe: - </text> - <check_box label="Del" name="CheckShareWithGroup"/> - <text name="NextOwnerLabel"> - Næste ejer: - </text> - <check_box label="Redigér" name="CheckNextOwnerModify"/> - <check_box label="Kopiere" name="CheckNextOwnerCopy"/> - <check_box label="Sælg" name="CheckNextOwnerTransfer"/> - <check_box label="Til salg" name="CheckPurchase"/> - <combo_box name="combobox sale copy"> - <combo_box.item label="Kopiér" name="Copy"/> - <combo_box.item label="Original" name="Original"/> - </combo_box> - <spinner label="Pris:" name="Edit Cost"/> - <text name="CurrencySymbol"> - L$ - </text> -</floater> diff --git a/indra/newview/skins/default/xui/de/floater_inventory_item_properties.xml b/indra/newview/skins/default/xui/de/floater_inventory_item_properties.xml deleted file mode 100644 index 92c038057f..0000000000 --- a/indra/newview/skins/default/xui/de/floater_inventory_item_properties.xml +++ /dev/null @@ -1,36 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="item properties" title="EIGENSCHAFTEN: INVENTAROBJEKT"> - <floater.string name="unknown">(unbekannt)</floater.string> - <floater.string name="public">(öffentlich)</floater.string> - <floater.string name="you_can">Sie können:</floater.string> - <floater.string name="owner_can">Eigentümer kann:</floater.string> - <floater.string name="acquiredDate">[wkday,datetime,local] [mth,datetime,local] [day,datetime,local] [hour,datetime,local]:[min,datetime,local]:[second,datetime,local] [year,datetime,local]</floater.string> - <text name="LabelItemNameTitle">Name:</text> - <text name="LabelItemDescTitle">Beschreibung:</text> - <text name="LabelCreatorTitle">Ersteller:</text> - <button label="Profil..." label_selected="" name="BtnCreator"/> - <text name="LabelOwnerTitle">Eigentümer:</text> - <button label="Profil..." label_selected="" name="BtnOwner"/> - <text name="LabelAcquiredTitle">Erworben:</text> - <text name="LabelAcquiredDate">Mittwoch, 24. Mai 2006, 12:50:46</text> - <text name="OwnerLabel">Sie:</text> - <check_box label="Bearbeiten" name="CheckOwnerModify"/> - <check_box label="Kopieren" left_delta="85" name="CheckOwnerCopy"/> - <check_box label="Wiederverkaufen" name="CheckOwnerTransfer"/> - <text name="AnyoneLabel">Jeder:</text> - <check_box label="Kopieren" name="CheckEveryoneCopy"/> - <text name="GroupLabel">Gruppe:</text> - <check_box label="Teilen" name="CheckShareWithGroup"/> - <text name="NextOwnerLabel" width="150">Nächster Eigentümer:</text> - <check_box label="Bearbeiten" name="CheckNextOwnerModify"/> - <check_box label="Kopieren" left_delta="55" name="CheckNextOwnerCopy"/> - <check_box label="Wiederverkaufen" name="CheckNextOwnerTransfer"/> - <check_box label="Zum Verkauf" name="CheckPurchase"/> - <combo_box name="ComboBoxSaleType"> - <combo_box.item label="Kopie" name="Copy"/> - <combo_box.item label="Inhalt" name="Contents"/> - <combo_box.item label="Original" name="Original"/> - </combo_box> - <spinner label="Preis:" name="Edit Cost"/> - <text name="CurrencySymbol">L$</text> -</floater> diff --git a/indra/newview/skins/default/xui/en/floater_change_item_thumbnail.xml b/indra/newview/skins/default/xui/en/floater_change_item_thumbnail.xml new file mode 100644 index 0000000000..f3f8ee0daa --- /dev/null +++ b/indra/newview/skins/default/xui/en/floater_change_item_thumbnail.xml @@ -0,0 +1,157 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<floater + can_resize="false" + height="366" + layout="topleft" + name="change_item_thumbnail" + help_topic="change_item_thumbnail" + title="CHANGE ITEM IMAGE" + width="319"> + + <floater.string + name="tooltip_upload_local"> + Upload from computer + </floater.string> + <floater.string + name="tooltip_upload_snapshot"> + Use snapshot tool + </floater.string> + <floater.string + name="tooltip_use_texture"> + Choose texture + </floater.string> + <floater.string + name="tooltip_copy_to_clipboard"> + Copy to clipboard + </floater.string> + <floater.string + name="tooltip_paste_from_clipboard"> + Paste from clipboard + </floater.string> + <floater.string + name="tooltip_remove_image"> + Remove image + </floater.string> + + <icon + follows="top|left" + height="16" + image_name="Inv_Object" + layout="topleft" + left="10" + mouse_opaque="true" + name="item_type_icon" + top="4" + width="16" /> + <text + name="item_name" + font="SansSerif" + max_length_bytes="127" + use_ellipses="true" + follows="left|top|right" + layout="topleft" + height="19" + top_delta="1" + left_pad="3" + width="286"/> + + <thumbnail + name="item_thumbnail" + fallback_image="Thumbnail_Fallback" + follows="top|left" + layout="topleft" + left="32" + top_pad="9" + height="256" + width="256" + /> + + <button + follows="right|bottom" + layout="topleft" + image_hover_unselected="Toolbar_Middle_Over" + image_overlay="Icon_File_Upload" + image_selected="Toolbar_Middle_Selected" + image_unselected="Toolbar_Middle_Off" + name="upload_local" + left="38" + top_pad="9" + height="32" + width="32" /> + <button + follows="right|bottom" + layout="topleft" + image_hover_unselected="Toolbar_Middle_Over" + image_overlay="Icon_Snapshot" + image_selected="Toolbar_Middle_Selected" + image_unselected="Toolbar_Middle_Off" + name="upload_snapshot" + left_pad="10" + top_delta="0" + height="32" + width="32" /> + <button + follows="right|bottom" + layout="topleft" + image_hover_unselected="Toolbar_Middle_Over" + image_overlay="Icon_Use_Texture" + image_selected="Toolbar_Middle_Selected" + image_unselected="Toolbar_Middle_Off" + name="use_texture" + left_pad="10" + top_delta="0" + height="32" + width="32" /> + <button + follows="right|bottom" + layout="topleft" + image_hover_unselected="Toolbar_Middle_Over" + image_overlay="Icon_Copy" + image_selected="Toolbar_Middle_Selected" + image_unselected="Toolbar_Middle_Off" + name="copy_to_clipboard" + left_pad="10" + top_delta="0" + height="32" + width="32" /> + <button + follows="right|bottom" + layout="topleft" + image_hover_unselected="Toolbar_Middle_Over" + image_overlay="Icon_Paste" + image_selected="Toolbar_Middle_Selected" + image_unselected="Toolbar_Middle_Off" + name="paste_from_clipboard" + left_pad="10" + top_delta="0" + height="32" + width="32" /> + <button + follows="right|bottom" + layout="topleft" + image_hover_unselected="Toolbar_Middle_Over" + image_overlay="Icon_Delete" + image_selected="Toolbar_Middle_Selected" + image_unselected="Toolbar_Middle_Off" + name="remove_image" + left_pad="10" + top_delta="0" + height="32" + width="32" /> + + <text + type="string" + halign="center" + length="1" + follows="left|top" + height="17" + layout="topleft" + left="5" + right="-5" + name="tooltip_text" + top_pad="12" + width="78"> + tooltip + </text> + +</floater> diff --git a/indra/newview/skins/default/xui/en/floater_inventory_item_properties.xml b/indra/newview/skins/default/xui/en/floater_inventory_item_properties.xml deleted file mode 100644 index 45e16c59ae..0000000000 --- a/indra/newview/skins/default/xui/en/floater_inventory_item_properties.xml +++ /dev/null @@ -1,422 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes" ?> -<floater - legacy_header_height="18" - height="340" - layout="topleft" - name="item properties" - help_topic="item_properties" - save_rect="true" - title="INVENTORY ITEM PROPERTIES" - width="350"> - <floater.string - name="unknown"> - (unknown) - </floater.string> - <floater.string - name="public"> - (public) - </floater.string> - <floater.string - name="you_can"> - You can: - </floater.string> - <floater.string - name="owner_can"> - Owner can: - </floater.string> - <floater.string - name="acquiredDate"> - [wkday,datetime,local] [mth,datetime,local] [day,datetime,local] [hour,datetime,local]:[min,datetime,local]:[second,datetime,local] [year,datetime,local] - </floater.string> - <icon - follows="top|right" - height="18" - image_name="Lock" - layout="topleft" - left="276" - mouse_opaque="true" - name="IconLocked" - top="4" - width="18" /> - <text - type="string" - length="1" - follows="left|top" - height="10" - layout="topleft" - left="10" - name="LabelItemNameTitle" - top="25" - width="78"> - Name: - </text> - <line_editor - border_style="line" - border_thickness="1" - follows="left|top|right" - height="16" - layout="topleft" - left_delta="78" - max_length_bytes="63" - name="LabelItemName" - top_delta="0" - width="252" /> - <text - type="string" - length="1" - follows="left|top" - height="10" - layout="topleft" - left="10" - name="LabelItemDescTitle" - top="45" - width="78"> - Description: - </text> - <line_editor - border_style="line" - border_thickness="1" - follows="left|top|right" - height="16" - layout="topleft" - left_delta="78" - max_length_bytes="127" - name="LabelItemDesc" - top_delta="0" - width="252" /> - <text - type="string" - length="1" - follows="left|top" - height="16" - layout="topleft" - left="10" - name="LabelCreatorTitle" - top="65" - width="78"> - Creator: - </text> - <text - type="string" - length="1" - follows="left|top" - height="16" - layout="topleft" - left_delta="78" - name="LabelCreatorName" - top_delta="0" - translate="false" - use_ellipses="true" - width="170"> - TestString PleaseIgnore - </text> - <button - follows="top|right" - height="16" - label="Profile..." - layout="topleft" - left_delta="174" - name="BtnCreator" - top_delta="0" - width="78" /> - <text - type="string" - length="1" - follows="left|top" - height="16" - layout="topleft" - left="10" - name="LabelOwnerTitle" - top="85" - width="78"> - Owner: - </text> - <text - type="string" - length="1" - follows="left|top" - height="16" - layout="topleft" - left_delta="78" - name="LabelOwnerName" - top_delta="0" - translate="false" - use_ellipses="true" - width="170"> - TestString PleaseIgnore - </text> - <button - follows="top|right" - height="16" - label="Profile..." - layout="topleft" - left_delta="174" - name="BtnOwner" - top_delta="0" - width="78" /> - <text - type="string" - length="1" - follows="left|top" - height="16" - layout="topleft" - left="10" - name="LabelAcquiredTitle" - top="105" - width="78"> - Acquired: - </text> - <text - type="string" - length="1" - follows="left|top" - height="16" - layout="topleft" - left_delta="78" - name="LabelAcquiredDate" - top_delta="0" - width="252"> - Wed May 24 12:50:46 2006 - </text> - <text - type="string" - length="1" - follows="left|top" - height="10" - layout="topleft" - left="10" - name="OwnerLabel" - top="125" - width="78"> - You: - </text> - <check_box - height="16" - label="Edit" - layout="topleft" - left_pad="5" - name="CheckOwnerModify" - top_delta="0" - width="78" /> - <check_box - height="16" - label="Copy" - layout="topleft" - left_delta="0" - name="CheckOwnerCopy" - top_pad="5" - width="88" /> - <check_box - height="16" - label="Resell" - layout="topleft" - left_delta="0" - name="CheckOwnerTransfer" - top_pad="5" - width="106" /> - <text - type="string" - length="1" - follows="left|top" - height="10" - layout="topleft" - left="10" - name="AnyoneLabel" - top_pad="5" - width="78"> - Anyone: - </text> - <check_box - height="16" - label="Copy" - layout="topleft" - left_pad="5" - name="CheckEveryoneCopy" - top_delta="0" - width="130" /> - <text - type="string" - length="1" - follows="left|top" - height="10" - layout="topleft" - left="10" - name="GroupLabel" - top_pad="5" - width="78"> - Group: - </text> - <check_box - height="16" - label="Share" - layout="topleft" - left_pad="5" - name="CheckShareWithGroup" - top_delta="5" - width="106" /> - <text - type="string" - length="1" - follows="left|top" - height="25" - layout="topleft" - left="10" - name="NextOwnerLabel" - top_pad="5" - width="78" - word_wrap="true"> - Next owner: - </text> - <check_box - height="16" - label="Edit" - layout="topleft" - left_pad="5" - name="CheckNextOwnerModify" - top_delta="0" - width="78" /> - <check_box - height="16" - label="Copy" - layout="topleft" - left_delta="0" - name="CheckNextOwnerCopy" - top_pad="5" - width="88" /> - <check_box - height="16" - label="Resell" - layout="topleft" - left_delta="0" - name="CheckNextOwnerTransfer" - top_pad="5" - width="106" /> - <check_box - height="16" - label="For Sale" - layout="topleft" - left="10" - name="CheckPurchase" - top_pad="5" - width="78" /> - <combo_box - height="19" - left_pad="5" - layout="topleft" - follows="left|top" - name="ComboBoxSaleType" - width="110"> - <combo_box.item - name="Copy" - label="Copy" - value="2" /> - <combo_box.item - name="Contents" - label="Contents" - value="3" /> - <combo_box.item - name="Original" - label="Original" - value="1" /> - </combo_box> - <spinner - follows="left|top" - decimal_digits="0" - increment="1" - control_name="Edit Cost" - name="Edit Cost" - label="Price:" - label_width="100" - left="10" - width="192" - min_val="1" - height="19" - max_val="999999999" - top_pad="5"/> - <text - type="string" - length="1" - height="15" - follows="left|top" - layout="topleft" - left_delta="82" - name="CurrencySymbol" - top_delta="1" - width="18"> - L$ - </text> - - <!--line_editor - border_style="line" - border_thickness="1" - follows="left|top|right" - height="16" - layout="topleft" - left_pad="5" - max_length_bytes="25" - name="EditPrice" - top_delta="0" - width="242" /--> - - <!--text - type="string" - length="1" - follows="left|top" - height="10" - layout="topleft" - left="10" - name="BaseMaskDebug" - top="155" - width="330"> - B: - </text> - <text - type="string" - length="1" - follows="left|top" - height="10" - layout="topleft" - left_delta="60" - name="OwnerMaskDebug" - top_delta="0" - width="270"> - O: - </text> - <text - type="string" - length="1" - follows="left|top" - height="10" - layout="topleft" - left_delta="60" - name="GroupMaskDebug" - top_delta="0" - width="210"> - G: - </text> - <text - type="string" - length="1" - follows="left|top" - height="10" - layout="topleft" - left_delta="60" - name="EveryoneMaskDebug" - top_delta="0" - width="150"> - E: - </text> - <text - type="string" - length="1" - follows="left|top" - height="10" - layout="topleft" - left_delta="60" - name="NextMaskDebug" - top_delta="0" - width="90"> - N: - </text--> - -</floater> diff --git a/indra/newview/skins/default/xui/en/floater_inventory_settings.xml b/indra/newview/skins/default/xui/en/floater_inventory_settings.xml new file mode 100644 index 0000000000..bfac79ac46 --- /dev/null +++ b/indra/newview/skins/default/xui/en/floater_inventory_settings.xml @@ -0,0 +1,179 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<floater + can_close="true" + can_minimize="true" + can_resize="false" + save_rect="true" + height="370" + width="370" + name="inventory_settings" + title="INVENTORY SETTINGS"> + <icon + follows="top|left" + height="18" + image_name="Multi_Folder_Mode" + layout="topleft" + left="18" + mouse_opaque="true" + name="multi_folder_icon" + top="25" + width="18" /> + <text + type="string" + length="1" + follows="left|top|right" + height="13" + layout="topleft" + left_pad="12" + top_delta="2" + name="multi_folder_txt" + font="SansSerifMedium" + text_color="White" + width="300"> + Double-click on folder in multi-folder view: + </text> + <radio_group + control_name="MultiModeDoubleClickFolder" + follows="left|top" + top_pad="8" + layout="topleft" + font="SansSerifMedium" + left="60" + width="300" + height="70" + name="multi_double_click_setting"> + <radio_item + height="20" + label="Expands & collapses folder" + label_text.text_color="White" + follows="left|top" + layout="topleft" + name="0" + width="200"/> + <radio_item + height="20" + follows="left|top" + label="Opens a new window" + label_text.text_color="White" + layout="topleft" + left_delta="0" + name="1" + top_pad ="5" + width="200" /> + <radio_item + height="20" + follows="left|top" + label="Switch view" + label_text.text_color="White" + layout="topleft" + left_delta="0" + name="2" + top_pad ="5" + width="200" /> + </radio_group> + <icon + follows="top|left" + height="18" + image_name="Single_Folder_Mode" + layout="topleft" + left="18" + mouse_opaque="true" + name="single_folder_icon" + top_pad="30" + width="18" /> + <text + type="string" + length="1" + follows="left|top|right" + height="13" + layout="topleft" + left_pad="12" + top_delta="2" + name="single_folder_txt" + font="SansSerifMedium" + text_color="White" + width="300"> + Double-click on folder in single-folder view: + </text> + <radio_group + control_name="SingleModeDoubleClickOpenWindow" + follows="left|top" + top_pad="8" + layout="topleft" + font="SansSerifMedium" + left="60" + width="300" + height="45" + name="single_double_click_setting"> + <radio_item + height="20" + label="Stays in current window" + label_text.text_color="White" + follows="left|top" + layout="topleft" + name="false" + width="200"/> + <radio_item + height="20" + follows="left|top" + label="Opens a new window" + label_text.text_color="White" + layout="topleft" + left_delta="0" + name="true" + top_pad ="5" + width="200" /> + </radio_group> + <text + type="string" + length="1" + follows="left|top|right" + height="13" + layout="topleft" + left="48" + name="find_original_txt" + font="SansSerifMedium" + text_color="White" + top_pad="30" + width="300"> + Clicking on "Show in inventory" or "Find original" + </text> + <radio_group + control_name="FindOriginalOpenWindow" + follows="left|top" + top_pad="8" + layout="topleft" + font="SansSerifMedium" + left="60" + width="300" + height="45" + name="find_original_settings"> + <radio_item + height="20" + label="Shows item in main inventory window" + label_text.text_color="White" + follows="left|top" + layout="topleft" + name="false" + width="200"/> + <radio_item + height="20" + follows="left|top" + label="Opens a new single-folder window" + label_text.text_color="White" + layout="topleft" + left_delta="0" + name="true" + top_pad ="5" + width="200" /> + </radio_group> + <button + height="20" + label="OK" + layout="topleft" + left="140" + bottom="-20" + name="ok_btn" + label_color="White" + width="90" /> +</floater> diff --git a/indra/newview/skins/default/xui/en/floater_item_properties.xml b/indra/newview/skins/default/xui/en/floater_item_properties.xml index 0fc54a9c8b..336bb902ca 100644 --- a/indra/newview/skins/default/xui/en/floater_item_properties.xml +++ b/indra/newview/skins/default/xui/en/floater_item_properties.xml @@ -13,7 +13,7 @@ left="0" class="sidepanel_item_info" filename="sidepanel_item_info.xml" - name="item_panel" + name="sidepanel" top="20" label="" height="570" 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 f182d27da8..1b4f323d04 100644 --- a/indra/newview/skins/default/xui/en/floater_my_inventory.xml +++ b/indra/newview/skins/default/xui/en/floater_my_inventory.xml @@ -5,14 +5,14 @@ can_resize="true" height="570" help_topic="sidebar_inventory" - min_width="333" + min_width="363" min_height="590" name="floater_my_inventory" save_rect="true" save_visibility="true" reuse_instance="true" title="INVENTORY" - width="333" > + width="363" > <panel class="sidepanel_inventory" name="main_panel" diff --git a/indra/newview/skins/default/xui/en/floater_simple_outfit_snapshot.xml b/indra/newview/skins/default/xui/en/floater_simple_snapshot.xml index 5ece7b85d5..484ad159d1 100644 --- a/indra/newview/skins/default/xui/en/floater_simple_outfit_snapshot.xml +++ b/indra/newview/skins/default/xui/en/floater_simple_snapshot.xml @@ -2,17 +2,17 @@ <floater positioning="cascading" legacy_header_height="18" - can_minimize="true" + can_minimize="false" can_resize="false" can_close="true" height="305" layout="topleft" - name="simple_outfit_snapshot" - single_instance="true" + name="simple_snapshot" + single_instance="false" help_topic="snapshot" save_rect="true" save_visibility="false" - title="OUTFIT SNAPSHOT" + title="ITEM SNAPSHOT" width="351"> <ui_ctrl layout="topleft" @@ -36,7 +36,7 @@ height="22" layout="topleft" left_pad="10" - label="Save (L$[UPLOAD_COST])" + label="Save" name="save_btn" width="90" /> <button diff --git a/indra/newview/skins/default/xui/en/floater_snapshot.xml b/indra/newview/skins/default/xui/en/floater_snapshot.xml index f441e3cbd7..fcd24d83bb 100644 --- a/indra/newview/skins/default/xui/en/floater_snapshot.xml +++ b/indra/newview/skins/default/xui/en/floater_snapshot.xml @@ -440,7 +440,7 @@ length="1" halign="right" name="360_label" - text_color="0.3 0.82 1 1" + text_color="HTMLLinkColor" top_delta="0" type="string" width="115"> diff --git a/indra/newview/skins/default/xui/en/floater_task_properties.xml b/indra/newview/skins/default/xui/en/floater_task_properties.xml new file mode 100644 index 0000000000..4b5c207577 --- /dev/null +++ b/indra/newview/skins/default/xui/en/floater_task_properties.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<floater + legacy_header_height="18" + height="570" + layout="topleft" + name="Task Properties" + help_topic="item+properties" + title="ITEM PROPERTIES" + single_instance="true" + width="330"> + <panel + follows="all" + layout="topleft" + left="0" + class="sidepanel_task_info" + filename="sidepanel_task_info.xml" + name="sidepanel" + top="20" + label="" + height="550" + visible="true" + width="330"> + </panel> +</floater> diff --git a/indra/newview/skins/default/xui/en/menu_gallery_outfit_tab.xml b/indra/newview/skins/default/xui/en/menu_gallery_outfit_tab.xml index 99ca910062..0ca505dd5d 100755 --- a/indra/newview/skins/default/xui/en/menu_gallery_outfit_tab.xml +++ b/indra/newview/skins/default/xui/en/menu_gallery_outfit_tab.xml @@ -42,35 +42,11 @@ parameter="take_off" /> </menu_item_call> <menu_item_call - label="Upload Photo (L$[UPLOAD_COST])" - layout="topleft" - name="upload_photo"> - <on_click - function="Outfit.UploadPhoto" /> - </menu_item_call> - <menu_item_call - label="Select Photo" - layout="topleft" - name="select_photo"> + label="Image..." + layout="topleft" + name="thumbnail"> <on_click - function="Outfit.SelectPhoto" /> - </menu_item_call> - <menu_item_call - label="Take a Snapshot" - layout="topleft" - name="take_snapshot"> - <on_click - function="Outfit.TakeSnapshot" /> - </menu_item_call> - <menu_item_call - label="Remove Photo" - layout="topleft" - name="remove_photo"> - <on_click - function="Outfit.RemovePhoto" /> - <on_visible - function="Outfit.OnVisible" - parameter="remove_photo" /> + function="Outfit.Thumbnail" /> </menu_item_call> <menu_item_separator name="sepatator1" /> <menu diff --git a/indra/newview/skins/default/xui/en/menu_inventory.xml b/indra/newview/skins/default/xui/en/menu_inventory.xml index aa3d0ae071..8374e63219 100644 --- a/indra/newview/skins/default/xui/en/menu_inventory.xml +++ b/indra/newview/skins/default/xui/en/menu_inventory.xml @@ -159,248 +159,6 @@ function="Inventory.DoCreate" parameter="outfit" /> </menu_item_call> - <menu_item_call - label="New Script" - layout="topleft" - name="New Script"> - <menu_item_call.on_click - function="Inventory.DoCreate" - parameter="lsl" /> - </menu_item_call> - <menu_item_call - label="New Notecard" - layout="topleft" - name="New Note"> - <menu_item_call.on_click - function="Inventory.DoCreate" - parameter="notecard" /> - </menu_item_call> - <menu_item_call - label="New Gesture" - layout="topleft" - name="New Gesture"> - <menu_item_call.on_click - function="Inventory.DoCreate" - parameter="gesture" /> - </menu_item_call> - <menu - label="New Clothes" - layout="topleft" - name="New Clothes"> - <menu_item_call - label="New Shirt" - layout="topleft" - name="New Shirt"> - <menu_item_call.on_click - function="Inventory.DoCreate" - parameter="shirt" /> - </menu_item_call> - <menu_item_call - label="New Pants" - layout="topleft" - name="New Pants"> - <menu_item_call.on_click - function="Inventory.DoCreate" - parameter="pants" /> - </menu_item_call> - <menu_item_call - label="New Shoes" - layout="topleft" - name="New Shoes"> - <menu_item_call.on_click - function="Inventory.DoCreate" - parameter="shoes" /> - </menu_item_call> - <menu_item_call - label="New Socks" - layout="topleft" - name="New Socks"> - <menu_item_call.on_click - function="Inventory.DoCreate" - parameter="socks" /> - </menu_item_call> - <menu_item_call - label="New Jacket" - layout="topleft" - name="New Jacket"> - <menu_item_call.on_click - function="Inventory.DoCreate" - parameter="jacket" /> - </menu_item_call> - <menu_item_call - label="New Skirt" - layout="topleft" - name="New Skirt"> - <menu_item_call.on_click - function="Inventory.DoCreate" - parameter="skirt" /> - </menu_item_call> - <menu_item_call - label="New Gloves" - layout="topleft" - name="New Gloves"> - <menu_item_call.on_click - function="Inventory.DoCreate" - parameter="gloves" /> - </menu_item_call> - <menu_item_call - label="New Undershirt" - layout="topleft" - name="New Undershirt"> - <menu_item_call.on_click - function="Inventory.DoCreate" - parameter="undershirt" /> - </menu_item_call> - <menu_item_call - label="New Underpants" - layout="topleft" - name="New Underpants"> - <menu_item_call.on_click - function="Inventory.DoCreate" - parameter="underpants" /> - </menu_item_call> - <menu_item_call - label="New Alpha Mask" - layout="topleft" - name="New Alpha Mask"> - <menu_item_call.on_click - function="Inventory.DoCreate" - parameter="alpha" /> - </menu_item_call> - <menu_item_call - label="New Tattoo" - layout="topleft" - name="New Tattoo"> - <menu_item_call.on_click - function="Inventory.DoCreate" - parameter="tattoo" /> - </menu_item_call> - <menu_item_call - label="New Universal" - layout="topleft" - name="New Universal"> - <menu_item_call.on_click - function="Inventory.DoCreate" - parameter="universal" /> - </menu_item_call> - <menu_item_call - label="New Physics" - layout="topleft" - name="New Physics"> - <menu_item_call.on_click - function="Inventory.DoCreate" - parameter="physics" /> - </menu_item_call> - </menu> - <menu - label="New Body Parts" - layout="topleft" - name="New Body Parts"> - <menu_item_call - label="New Shape" - layout="topleft" - name="New Shape"> - <menu_item_call.on_click - function="Inventory.DoCreate" - parameter="shape" /> - </menu_item_call> - <menu_item_call - label="New Skin" - layout="topleft" - name="New Skin"> - <menu_item_call.on_click - function="Inventory.DoCreate" - parameter="skin" /> - </menu_item_call> - <menu_item_call - label="New Hair" - layout="topleft" - name="New Hair"> - <menu_item_call.on_click - function="Inventory.DoCreate" - parameter="hair" /> - </menu_item_call> - <menu_item_call - label="New Eyes" - layout="topleft" - name="New Eyes"> - <menu_item_call.on_click - function="Inventory.DoCreate" - parameter="eyes" /> - </menu_item_call> - </menu> - <menu - label="New Settings" - layout="topleft" - name="New Settings"> - <menu_item_call - label="New Sky" - layout="topleft" - name="New Sky"> - <menu_item_call.on_click - function="Inventory.DoCreate" - parameter="sky"/> - <menu_item_call.on_enable - function="Inventory.EnvironmentEnabled" /> - </menu_item_call> - <menu_item_call - label="New Water" - layout="topleft" - name="New Water"> - <menu_item_call.on_click - function="Inventory.DoCreate" - parameter="water"/> - <menu_item_call.on_enable - function="Inventory.EnvironmentEnabled" /> - </menu_item_call> - <menu_item_call - label="New Day Cycle" - layout="topleft" - name="New Day Cycle"> - <menu_item_call.on_click - function="Inventory.DoCreate" - parameter="daycycle"/> - <menu_item_call.on_enable - function="Inventory.EnvironmentEnabled" /> - </menu_item_call> - </menu> - <menu - label="Use as default for" - layout="topleft" - name="upload_def"> - <menu_item_call - label="Image uploads" - layout="topleft" - name="Image uploads"> - <menu_item_call.on_click - function="Inventory.FileUploadLocation" - parameter="texture" /> - </menu_item_call> - <menu_item_call - label="Sound uploads" - layout="topleft" - name="Sound uploads"> - <menu_item_call.on_click - function="Inventory.FileUploadLocation" - parameter="sound" /> - </menu_item_call> - <menu_item_call - label="Animation uploads" - layout="topleft" - name="Animation uploads"> - <menu_item_call.on_click - function="Inventory.FileUploadLocation" - parameter="animation" /> - </menu_item_call> - <menu_item_call - label="Model uploads" - layout="topleft" - name="Model uploads"> - <menu_item_call.on_click - function="Inventory.FileUploadLocation" - parameter="model" /> - </menu_item_call> - </menu> <menu label="Change Type" layout="topleft" @@ -597,12 +355,12 @@ parameter="properties" /> </menu_item_call> <menu_item_call - label="Rename" + label="Image..." layout="topleft" - name="Rename"> + name="thumbnail"> <menu_item_call.on_click function="Inventory.DoToSelected" - parameter="rename" /> + parameter="thumbnail" /> </menu_item_call> <menu_item_call label="Copy Asset UUID" @@ -624,6 +382,31 @@ layout="topleft" name="Copy Separator" /> <menu_item_call + label="Open" + layout="topleft" + name="open_in_current_window"> + <menu_item_call.on_click + function="Inventory.OpenSelectedFolder"/> + </menu_item_call> + <menu_item_call + label="Open in new window" + layout="topleft" + name="open_in_new_window"> + <menu_item_call.on_click + function="Inventory.OpenNewFolderWindow"/> + </menu_item_call> + <menu_item_separator + layout="topleft" + name="Open Folder Separator" /> + <menu_item_call + label="Rename" + layout="topleft" + name="Rename"> + <menu_item_call.on_click + function="Inventory.DoToSelected" + parameter="rename" /> + </menu_item_call> + <menu_item_call label="Cut" layout="topleft" name="Cut"> @@ -931,6 +714,43 @@ function="Inventory.DoToSelected" parameter="ungroup_folder_items" /> </menu_item_call> + <menu + label="Use as default for" + layout="topleft" + name="upload_def"> + <menu_item_call + label="Image uploads" + layout="topleft" + name="Image uploads"> + <menu_item_call.on_click + function="Inventory.FileUploadLocation" + parameter="texture" /> + </menu_item_call> + <menu_item_call + label="Sound uploads" + layout="topleft" + name="Sound uploads"> + <menu_item_call.on_click + function="Inventory.FileUploadLocation" + parameter="sound" /> + </menu_item_call> + <menu_item_call + label="Animation uploads" + layout="topleft" + name="Animation uploads"> + <menu_item_call.on_click + function="Inventory.FileUploadLocation" + parameter="animation" /> + </menu_item_call> + <menu_item_call + label="Model uploads" + layout="topleft" + name="Model uploads"> + <menu_item_call.on_click + function="Inventory.FileUploadLocation" + parameter="model" /> + </menu_item_call> + </menu> <menu_item_separator layout="topleft" name="Marketplace Separator" /> diff --git a/indra/newview/skins/default/xui/en/menu_inventory_gear_default.xml b/indra/newview/skins/default/xui/en/menu_inventory_gear_default.xml index 3eacdbc781..d2bd33a44c 100644 --- a/indra/newview/skins/default/xui/en/menu_inventory_gear_default.xml +++ b/indra/newview/skins/default/xui/en/menu_inventory_gear_default.xml @@ -15,52 +15,17 @@ function="Inventory.GearDefault.Custom.Action" parameter="new_window" /> </menu_item_call> - <menu_item_separator - layout="topleft" /> - <menu_item_check - label="Sort by Name" - layout="topleft" - name="sort_by_name"> - <on_click - function="Inventory.GearDefault.Custom.Action" - parameter="sort_by_name" /> - <on_check - function="Inventory.GearDefault.Check" - parameter="sort_by_name" /> - </menu_item_check> - <menu_item_check - label="Sort by Most Recent" - layout="topleft" - name="sort_by_recent"> - <on_click - function="Inventory.GearDefault.Custom.Action" - parameter="sort_by_recent" /> - <on_check - function="Inventory.GearDefault.Check" - parameter="sort_by_recent" /> - </menu_item_check> - <menu_item_check - label="Sort Folders Always by Name" - layout="topleft" - name="sort_folders_by_name"> - <on_click - function="Inventory.GearDefault.Custom.Action" - parameter="sort_folders_by_name" /> - <on_check - function="Inventory.GearDefault.Check" - parameter="sort_folders_by_name" /> - </menu_item_check> - <menu_item_check - label="Sort System Folders to Top" + <menu_item_call + label="Close All Folders" layout="topleft" - name="sort_system_folders_to_top"> + name="close_folders"> <on_click function="Inventory.GearDefault.Custom.Action" - parameter="sort_system_folders_to_top" /> - <on_check - function="Inventory.GearDefault.Check" - parameter="sort_system_folders_to_top" /> - </menu_item_check> + parameter="close_folders" /> + <on_visible + function="Inventory.GearDefault.Visible" + parameter="multi_folder_view" /> + </menu_item_call> <menu_item_separator layout="topleft" /> <menu_item_call @@ -79,29 +44,6 @@ function="Inventory.GearDefault.Custom.Action" parameter="reset_filters" /> </menu_item_call> - <menu_item_call - label="Close All Folders" - layout="topleft" - name="close_folders"> - <on_click - function="Inventory.GearDefault.Custom.Action" - parameter="close_folders" /> - </menu_item_call> - <menu_item_separator - layout="topleft" /> - <menu_item_call - label="Empty Lost and Found" - layout="topleft" - name="empty_lostnfound"> - <on_click - function="Inventory.GearDefault.Custom.Action" - parameter="empty_lostnfound" /> - <on_enable - function="Inventory.GearDefault.Enable" - parameter="empty_lostnfound" /> - </menu_item_call> - <menu_item_separator - layout="topleft" /> <menu_item_call label="Save Texture As" layout="topleft" @@ -154,9 +96,25 @@ function="Inventory.GearDefault.Custom.Action" parameter="replace_links" /> </menu_item_call> - <menu_item_separator - layout="topleft" /> - + <menu_item_separator> + <menu_item_separator.on_visible + function="Inventory.GearDefault.Visible" + parameter="multi_folder_view" /> + </menu_item_separator> + <menu_item_call + label="Empty Lost and Found" + layout="topleft" + name="empty_lostnfound"> + <on_click + function="Inventory.GearDefault.Custom.Action" + parameter="empty_lostnfound" /> + <on_enable + function="Inventory.GearDefault.Enable" + parameter="empty_lostnfound" /> + <on_visible + function="Inventory.GearDefault.Visible" + parameter="multi_folder_view" /> + </menu_item_call> <menu_item_call label="Empty Trash" layout="topleft" @@ -167,5 +125,8 @@ <on_enable function="Inventory.GearDefault.Enable" parameter="empty_trash" /> + <on_visible + function="Inventory.GearDefault.Visible" + parameter="multi_folder_view" /> </menu_item_call> </toggleable_menu> diff --git a/indra/newview/skins/default/xui/en/menu_inventory_search_visibility.xml b/indra/newview/skins/default/xui/en/menu_inventory_search_visibility.xml index 46193f4a7a..8e34f52f3a 100644 --- a/indra/newview/skins/default/xui/en/menu_inventory_search_visibility.xml +++ b/indra/newview/skins/default/xui/en/menu_inventory_search_visibility.xml @@ -7,6 +7,17 @@ name="menu_search_visibility" visible="false"> <menu_item_check + label="Search outfit folders" + layout="topleft" + name="search_outfits"> + <on_click + function="Inventory.GearDefault.Custom.Action" + parameter="toggle_search_outfits" /> + <on_check + function="Inventory.GearDefault.Check" + parameter="toggle_search_outfits" /> + </menu_item_check> + <menu_item_check label="Search Trash" layout="topleft" name="search_trash"> diff --git a/indra/newview/skins/default/xui/en/menu_inventory_view_default.xml b/indra/newview/skins/default/xui/en/menu_inventory_view_default.xml new file mode 100644 index 0000000000..c7f9822e41 --- /dev/null +++ b/indra/newview/skins/default/xui/en/menu_inventory_view_default.xml @@ -0,0 +1,114 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<toggleable_menu + bottom="806" + layout="topleft" + left="0" + mouse_opaque="false" + name="menu_view_default" + visible="false"> + <menu_item_check + label="Sort by Name" + layout="topleft" + name="sort_by_name"> + <on_click + function="Inventory.GearDefault.Custom.Action" + parameter="sort_by_name" /> + <on_check + function="Inventory.GearDefault.Check" + parameter="sort_by_name" /> + </menu_item_check> + <menu_item_check + label="Sort by Most Recent" + layout="topleft" + name="sort_by_recent"> + <on_click + function="Inventory.GearDefault.Custom.Action" + parameter="sort_by_recent" /> + <on_check + function="Inventory.GearDefault.Check" + parameter="sort_by_recent" /> + </menu_item_check> + <menu_item_check + label="Sort Folders Always by Name" + layout="topleft" + name="sort_folders_by_name"> + <on_click + function="Inventory.GearDefault.Custom.Action" + parameter="sort_folders_by_name" /> + <on_check + function="Inventory.GearDefault.Check" + parameter="sort_folders_by_name" /> + </menu_item_check> + <menu_item_check + label="Sort System Folders to Top" + layout="topleft" + name="sort_system_folders_to_top"> + <on_click + function="Inventory.GearDefault.Custom.Action" + parameter="sort_system_folders_to_top" /> + <on_check + function="Inventory.GearDefault.Check" + parameter="sort_system_folders_to_top" /> + <on_visible + function="Inventory.GearDefault.Visible" + parameter="multi_folder_view" /> + </menu_item_check> + <menu_item_separator> + <menu_item_separator.on_visible + function="Inventory.GearDefault.Visible" + parameter="single_folder_view" /> + </menu_item_separator> + <menu_item_check + label="List view" + layout="topleft" + name="list_view"> + <on_click + function="Inventory.GearDefault.Custom.Action" + parameter="list_view" /> + <on_check + function="Inventory.GearDefault.Check" + parameter="list_view" /> + <on_visible + function="Inventory.GearDefault.Visible" + parameter="single_folder_view" /> + </menu_item_check> + <menu_item_check + label="Gallery view" + layout="topleft" + name="gallery_view"> + <on_click + function="Inventory.GearDefault.Custom.Action" + parameter="gallery_view" /> + <on_check + function="Inventory.GearDefault.Check" + parameter="gallery_view" /> + <on_visible + function="Inventory.GearDefault.Visible" + parameter="single_folder_view" /> + </menu_item_check> + <menu_item_check + label="Combination view" + layout="topleft" + name="combination_view"> + <on_click + function="Inventory.GearDefault.Custom.Action" + parameter="combination_view" /> + <on_check + function="Inventory.GearDefault.Check" + parameter="combination_view" /> + <on_visible + function="Inventory.GearDefault.Visible" + parameter="single_folder_view" /> + </menu_item_check> + <menu_item_separator/> + <menu_item_check + label="Inventory settings..." + name="inv_settings"> + <menu_item_check.on_check + function="Floater.Visible" + parameter="inventory_settings" /> + <menu_item_check.on_click + function="Floater.Toggle" + parameter="inventory_settings" /> + </menu_item_check> +</toggleable_menu> diff --git a/indra/newview/skins/default/xui/en/menu_outfit_gear.xml b/indra/newview/skins/default/xui/en/menu_outfit_gear.xml index 32d9d28434..e216962d12 100644 --- a/indra/newview/skins/default/xui/en/menu_outfit_gear.xml +++ b/indra/newview/skins/default/xui/en/menu_outfit_gear.xml @@ -40,32 +40,11 @@ parameter="take_off" /> </menu_item_call> <menu_item_call - label="Upload Photo (L$[UPLOAD_COST])" + label="Image..." layout="topleft" - name="upload_photo"> + name="thumbnail"> <on_click - function="Gear.UploadPhoto" /> - </menu_item_call> - <menu_item_call - label="Select Photo" - layout="topleft" - name="select_photo"> - <on_click - function="Gear.SelectPhoto" /> - </menu_item_call> - <menu_item_call - label="Take a Snapshot" - layout="topleft" - name="take_snapshot"> - <on_click - function="Gear.TakeSnapshot" /> - </menu_item_call> - <menu_item_call - label="Remove Photo" - layout="topleft" - name="remove_photo"> - <on_click - function="Gear.RemovePhoto" /> + function="Gear.Thumbnail" /> </menu_item_call> <menu_item_separator name="sepatator1" /> <!-- copied (with minor modifications) from menu_inventory_add.xml --> diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml index d1a99133f0..d2d3cb4523 100644 --- a/indra/newview/skins/default/xui/en/notifications.xml +++ b/indra/newview/skins/default/xui/en/notifications.xml @@ -6094,7 +6094,32 @@ Are you sure you want to delete them? notext="Cancel" yestext="OK"/> </notification> - + + <notification + icon="alertmodal.tga" + name="DeleteThumbnail" + type="alertmodal"> + <unique/> + Delete the image for this item? There is no undo. + <tag>confirm</tag> + <usetemplate + ignoretext="Don't show me this again" + name="okcancelignore" + notext="Cancel" + yestext="Delete"/> + </notification> + + <notification + icon="alertmodal.tga" + name="ThumbnailDimantionsLimit" + type="alertmodal"> + <unique/> + Only square images from 64 to 256 pixels per side are allowed. + <usetemplate + name="okbutton" + yestext="OK"/> + </notification> + <notification icon="alertmodal.tga" name="ConfirmUnlink" diff --git a/indra/newview/skins/default/xui/en/panel_main_inventory.xml b/indra/newview/skins/default/xui/en/panel_main_inventory.xml index 2ff58035ed..5f6859622d 100644 --- a/indra/newview/skins/default/xui/en/panel_main_inventory.xml +++ b/indra/newview/skins/default/xui/en/panel_main_inventory.xml @@ -7,7 +7,7 @@ min_height="300" min_width="240" name="main inventory panel" - width="330"> + width="355"> <panel.string name="Itemcount"> </panel.string> @@ -23,6 +23,9 @@ name="ItemcountUnknown"> Fetched [ITEM_COUNT] Items and [CATEGORY_COUNT] Folders [FILTER] </panel.string> + <panel.string name="inventory_title">INVENTORY</panel.string> + <panel.string name="default_mode_btn">Multi_Folder_Mode</panel.string> + <panel.string name="single_folder_mode_btn">Single_Folder_Mode</panel.string> <text type="string" length="1" @@ -38,196 +41,261 @@ width="300"> Items: </text> - <combo_box - height="23" - layout="topleft" - left="10" - top="18" - name="search_type" - follows="top|left" - width="88"> - <item - label="Name" - name="Name" - value="search_by_name"/> - <item - label="Creator" - name="Creator" - value="search_by_creator"/> - <item - label="Description" - name="Description" - value="search_by_description"/> - <item - label="UUID" - name="UUID" - value="search_by_UUID"/> - </combo_box> - <menu_button - follows="top|left" - tool_tip="Show search visibility options" - height="23" - image_overlay="Inv_Toolbar_SearchVisibility" - layout="topleft" - left_pad="3" - name="options_visibility_btn" - width="31" /> - <filter_editor - text_pad_left="10" + <layout_stack follows="left|top|right" - height="23" - label="Enter search text" - layout="topleft" - left_pad="3" - max_length_chars="300" - highlight_text_field="true" - name="inventory search editor" - width="177" /> - <tab_container + height="25" + animate="false" + top_pad="10" + left="2" + orientation="horizontal"> + <layout_panel + border="false" + bevel_style="in" + user_resize="false" + auto_resize="false" + height="25" + width="65" + name="nav_buttons" + visible="false"> + <button + follows="top|left" + height="23" + image_selected="Single_Folder_Back" + image_pressed="Single_Folder_Back" + image_unselected="Single_Folder_Back" + scale_image="false" + layout="topleft" + left="3" + top="2" + name="back_btn" + tool_tip="Back" + width="20" /> + <button + follows="top|left" + height="23" + image_selected="Single_Folder_Forward" + image_pressed="Single_Folder_Forward" + image_unselected="Single_Folder_Forward" + scale_image="false" + layout="topleft" + left_pad="1" + name="forward_btn" + tool_tip="Forward" + width="20" /> + <button + follows="top|left" + height="23" + image_selected="Single_Folder_Up" + image_pressed="Single_Folder_Up" + image_unselected="Single_Folder_Up" + scale_image="false" + layout="topleft" + left_pad="1" + name="up_btn" + tool_tip="Go up one level" + width="20" /> + </layout_panel> + <layout_panel + border="false" + bevel_style="in" + user_resize="false" + height="25" + width="375" + visible="true"> + <combo_box + height="23" + layout="topleft" + left="2" + top="0" + name="search_type" + tool_tip="Search by" + follows="top|left" + width="67"> + <item + label="Name" + name="Name" + value="search_by_name"/> + <item + label="Creator" + name="Creator" + value="search_by_creator"/> + <item + label="Description" + name="Description" + value="search_by_description"/> + <item + label="UUID" + name="UUID" + value="search_by_UUID"/> + </combo_box> + <menu_button + follows="top|left" + tool_tip="Search visibility options" + height="23" + image_overlay="Inv_Toolbar_SearchVisibility" + layout="topleft" + left_pad="1" + name="options_visibility_btn" + width="31" /> + <filter_editor + text_pad_left="10" + follows="left|top|right" + height="23" + label="Enter search text" + layout="topleft" + left_pad="1" + max_length_chars="300" + highlight_text_field="true" + name="inventory search editor" + width="150" /> + <menu_button + follows="top|right" + tool_tip="Actions" + height="23" + image_hover_unselected="Toolbar_Middle_Over" + image_overlay="OptionsMenu_Off" + image_selected="Toolbar_Middle_Selected" + image_unselected="Toolbar_Middle_Off" + layout="topleft" + left_pad="1" + name="options_gear_btn" + width="31" /> + <menu_button + follows="top|right" + tool_tip="View & sort options" + height="23" + image_hover_unselected="Toolbar_Middle_Over" + image_overlay="Conv_toolbar_sort" + image_selected="Toolbar_Middle_Selected" + image_unselected="Toolbar_Middle_Off" + layout="topleft" + left_pad="1" + name="view_btn" + width="31" /> + <button + follows="top|right" + height="23" + image_hover_unselected="Toolbar_Middle_Over" + image_overlay="AddItem_Off" + image_selected="Toolbar_Middle_Selected" + image_unselected="Toolbar_Middle_Off" + layout="topleft" + left_pad="1" + name="add_btn" + tool_tip="Create new item" + width="31" /> + <button + follows="top|right" + tool_tip="Switch between views" + height="23" + image_hover_unselected="Toolbar_Middle_Over" + image_overlay="Single_Folder_Mode" + image_selected="Toolbar_Middle_Selected" + image_unselected="Toolbar_Middle_Off" + layout="topleft" + left_pad="1" + name="view_mode_btn" + width="31" /> + </layout_panel> + </layout_stack> + <panel follows="all" halign="center" - height="339" + height="372" layout="topleft" left="7" - name="inventory filter tabs" - tab_height="30" - tab_position="top" - tab_min_width="100" + name="default_inventory_panel" top_pad="10" width="312"> - <inventory_panel - bg_opaque_color="DkGray2" - bg_alpha_color="DkGray2" - background_visible="true" - border="false" - bevel_style="none" - follows="all" - height="338" - label="MY INVENTORY" - help_topic="my_inventory_tab" - layout="topleft" - left="0" - name="All Items" - sort_order_setting="InventorySortOrder" - show_item_link_overlays="true" - top="16" - width="288" /> - <recent_inventory_panel - bg_opaque_color="DkGray2" - bg_alpha_color="DkGray2" - background_visible="true" - border="false" - bevel_style="none" + <tab_container + follows="all" + halign="center" + height="372" + layout="topleft" + left="0" + name="inventory filter tabs" + tab_height="30" + tab_position="top" + tab_min_width="100" + top="0" + width="312"> + <inventory_panel + bg_opaque_color="DkGray2" + bg_alpha_color="DkGray2" + background_visible="true" + border="false" + bevel_style="none" + follows="all" + height="338" + label="MY INVENTORY" + help_topic="my_inventory_tab" + layout="topleft" + left="0" + name="All Items" + sort_order_setting="InventorySortOrder" + show_item_link_overlays="true" + top="16" + width="288" /> + <recent_inventory_panel + bg_opaque_color="DkGray2" + bg_alpha_color="DkGray2" + background_visible="true" + border="false" + bevel_style="none" + follows="all" + height="338" + label="RECENT" + help_topic="recent_inventory_tab" + layout="topleft" + left_delta="0" + name="Recent Items" + show_item_link_overlays="true" + width="290" /> + <inventory_panel + name="Worn Items" + label="WORN" + show_empty_message="false" + follows="all" + layout="topleft" + width="290" + bg_opaque_color="DkGray2" + bg_alpha_color="DkGray2" + background_visible="true" + border="false" + bevel_style="none" + scroll.reserve_scroll_corner="false"> + </inventory_panel> + </tab_container> + </panel> + <panel follows="all" - height="338" - label="RECENT" - help_topic="recent_inventory_tab" + halign="center" + height="372" layout="topleft" - left_delta="0" - name="Recent Items" - show_item_link_overlays="true" - width="290" /> - <inventory_panel - name="Worn Items" - label="WORN" - show_empty_message="false" - follows="all" - layout="topleft" - width="290" - bg_opaque_color="DkGray2" - bg_alpha_color="DkGray2" - background_visible="true" - border="false" - bevel_style="none" - scroll.reserve_scroll_corner="false"> - </inventory_panel> - </tab_container> - <layout_stack - animate="false" - border_size="0" - follows="left|right|bottom" - height="25" - layout="topleft" - orientation="horizontal" - top_pad="0" - left="10" - name="bottom_panel" - width="307"> - <layout_panel - auto_resize="false" - height="25" - layout="topleft" - name="options_gear_btn_panel" - width="32"> - <menu_button - follows="bottom|left" - tool_tip="Show additional options" - height="25" - image_hover_unselected="Toolbar_Left_Over" - image_overlay="OptionsMenu_Off" - image_selected="Toolbar_Left_Selected" - image_unselected="Toolbar_Left_Off" - layout="topleft" - left="0" - name="options_gear_btn" - top="0" - width="31" /> - </layout_panel> - <layout_panel - auto_resize="false" - height="25" - layout="topleft" - name="add_btn_panel" - width="32"> - <button - follows="bottom|left" - height="25" - image_hover_unselected="Toolbar_Middle_Over" - image_overlay="AddItem_Off" - image_selected="Toolbar_Middle_Selected" - image_unselected="Toolbar_Middle_Off" - layout="topleft" - left="0" - name="add_btn" - tool_tip="Add new item" - top="0" - width="31" /> - </layout_panel> - <layout_panel - auto_resize="true" - height="25" - layout="topleft" - name="dummy_panel" - width="212"> - <icon - follows="bottom|left|right" - height="25" - image_name="Toolbar_Middle_Off" - layout="topleft" - left="0" - top="0" - name="dummy_icon" - width="211" /> - </layout_panel> - <layout_panel - auto_resize="false" - height="25" + left="7" + name="single_folder_inventory" + top_delta="0" + visible="false" + width="312"> + <single_folder_inventory_panel + name="single_folder_inv" + follows="all" + left="0" + top="0" + top_pad="5" + height="372" + width="312" layout="topleft" - name="trash_btn_panel" - width="31"> - <dnd_button - follows="bottom|left" - height="25" - image_hover_unselected="Toolbar_Right_Over" - image_overlay="TrashItem_Off" - image_selected="Toolbar_Right_Selected" - image_unselected="Toolbar_Right_Off" - left="0" - layout="topleft" - name="trash_btn" - tool_tip="Remove selected item" - top="0" - width="31"/> - </layout_panel> - </layout_stack> + bg_opaque_color="DkGray2" + bg_alpha_color="DkGray2" + background_visible="true" + border="false" + bevel_style="none" + scroll.reserve_scroll_corner="false"> + <item folder_indentation="0"/> + <folder + single_folder_mode="true" + folder_indentation="0"/> + </single_folder_inventory_panel> + </panel> </panel> diff --git a/indra/newview/skins/default/xui/en/panel_profile_firstlife.xml b/indra/newview/skins/default/xui/en/panel_profile_firstlife.xml index ca1e405a62..f899f83ad4 100644 --- a/indra/newview/skins/default/xui/en/panel_profile_firstlife.xml +++ b/indra/newview/skins/default/xui/en/panel_profile_firstlife.xml @@ -19,7 +19,7 @@ layout="topleft" visible="false" /> - <icon + <thumbnail name="real_world_pic" image_name="Generic_Person_Large" follows="top|left" diff --git a/indra/newview/skins/default/xui/en/panel_profile_secondlife.xml b/indra/newview/skins/default/xui/en/panel_profile_secondlife.xml index 777b37d666..ebedbf20c7 100644 --- a/indra/newview/skins/default/xui/en/panel_profile_secondlife.xml +++ b/indra/newview/skins/default/xui/en/panel_profile_secondlife.xml @@ -48,7 +48,7 @@ Account: [ACCTTYPE] auto_resize="false" user_resize="false"> - <icon + <thumbnail name="2nd_life_pic" image_name="Generic_Person_Large" layout="topleft" diff --git a/indra/newview/skins/default/xui/en/sidepanel_inventory.xml b/indra/newview/skins/default/xui/en/sidepanel_inventory.xml index 9995523e61..a4b7f48c5e 100644 --- a/indra/newview/skins/default/xui/en/sidepanel_inventory.xml +++ b/indra/newview/skins/default/xui/en/sidepanel_inventory.xml @@ -7,7 +7,7 @@ min_height="350" min_width="240" name="objects panel" - width="333"> + width="358"> <panel follows="all" layout="topleft" @@ -18,7 +18,7 @@ height="570" visible="true" default_tab_group="1" - width="330"> + width="395"> <layout_stack follows="left|right|top|bottom" layout="topleft" @@ -27,15 +27,15 @@ tab_group="1" orientation="vertical" name="inventory_layout_stack" - height="535" - width="330"> + height="565" + width="395"> <layout_panel name="main_inventory_layout_panel" layout="topleft" auto_resize="true" user_resize="true" min_dim="150" - width="330" + width="395" follows="bottom|left|right" height="300"> <panel @@ -48,10 +48,10 @@ top="0" label="" height="300" - width="330" /> + width="395" /> </layout_panel> <layout_panel - width="330" + width="355" layout="topleft" auto_resize="false" user_resize="true" @@ -133,142 +133,5 @@ Purchases from the marketplace will be delivered here. </panel> </layout_panel> </layout_stack> - <panel follows="bottom|left|right" - height="30" - layout="topleft" - name="button_panel" - left="9" - top_pad="7" - width="308"> - <layout_stack follows="bottom|left|right" - height="23" - layout="topleft" - mouse_opaque="false" - name="button_panel_ls" - left="0" - orientation="horizontal" - top="0" - width="308"> - <layout_panel follows="bottom|left|right" - height="23" - layout="bottomleft" - left="0" - mouse_opaque="false" - name="info_btn_lp" - auto_resize="true" - width="101"> - <button enabled="true" - follows="bottom|left|right" - height="23" - label="Profile" - layout="topleft" - left="1" - name="info_btn" - tool_tip="Show object profile" - top="0" - width="100" /> - </layout_panel> - <layout_panel - follows="bottom|left|right" - height="23" - layout="bottomleft" - left_pad="1" - mouse_opaque="false" - name="share_btn_lp" - auto_resize="true" - width="100"> - <button - enabled="true" - follows="bottom|left|right" - height="23" - label="Share" - layout="topleft" - left="1" - name="share_btn" - tool_tip="Share an inventory item" - top="0" - width="99" /> - </layout_panel> - <layout_panel - follows="bottom|left|right" - height="23" - layout="bottomleft" - left_pad="1" - mouse_opaque="false" - name="shop_btn_lp" - auto_resize="true" - width="100"> - <button - enabled="true" - follows="bottom|left|right" - height="23" - label="Shop" - layout="topleft" - left="1" - name="shop_btn" - tool_tip="Open Marketplace webpage" - top="0" - width="99" /> - <button - enabled="false" - follows="bottom|left|right" - height="23" - label="Wear" - layout="topleft" - left="1" - name="wear_btn" - tool_tip="Wear seleceted outfit" - top="0" - width="99" /> - <button - enabled="false" - follows="bottom|left|right" - height="23" - label="Play" - layout="topleft" - name="play_btn" - left="1" - top="0" - width="99" /> - <button - enabled="false" - follows="bottom|left|right" - height="23" - label="Teleport" - layout="topleft" - left="1" - name="teleport_btn" - tool_tip="Teleport to the selected area" - top="0" - width="99" /> - </layout_panel> - </layout_stack> - </panel> - </panel> - <panel - follows="all" - layout="topleft" - left="0" - class="sidepanel_item_info" - filename="sidepanel_item_info.xml" - name="sidepanel__item_panel" - top="0" - label="" - height="570" - visible="false" - width="330"> - </panel> - <panel - follows="all" - layout="topleft" - left="0" - class="sidepanel_task_info" - filename="sidepanel_task_info.xml" - name="sidepanel__task_panel" - top="0" - label="" - height="570" - visible="false" - width="330"> </panel> </panel> diff --git a/indra/newview/skins/default/xui/en/sidepanel_item_info.xml b/indra/newview/skins/default/xui/en/sidepanel_item_info.xml index 9a68479d05..ad521cb1af 100644 --- a/indra/newview/skins/default/xui/en/sidepanel_item_info.xml +++ b/indra/newview/skins/default/xui/en/sidepanel_item_info.xml @@ -43,214 +43,126 @@ name="origin_inworld"> (Inworld) </panel.string> - <icon - follows="top|right" - height="18" - image_name="Lock" - layout="topleft" - right="-15" - mouse_opaque="true" - name="IconLocked" - top="8" - width="18" /> - <button - follows="top|left" - height="24" - image_hover_unselected="BackButton_Over" - image_pressed="BackButton_Press" - image_unselected="BackButton_Off" - layout="topleft" - left="12" - name="back_btn" - tab_stop="false" - top="2" - width="30" - use_draw_context_alpha="false" /> - <text - follows="top|left|right" - font="SansSerifHugeBold" - height="26" - layout="topleft" - left_pad="3" - name="title" - text_color="LtGray" - top="2" - use_ellipses="true" - value="Item Profile" - width="275" /> - <text - follows="top|left|right" - height="13" - layout="topleft" - left="45" - name="origin" - text_color="LtGray_50" - use_ellipses="true" - value="(Inventory)" - width="275" /> - <scroll_container - color="DkGray2" - follows="all" - layout="topleft" - left="9" - name="item_profile_scroll" - opaque="true" - height="493" - width="313" - top="45"> - <panel - follows="left|top|right" - height="390" - help_topic="" - label="" + +<layout_stack + animate="false" + name="main_stack" + layout="topleft" + follows="all" + orientation="vertical" + left="0" + top="0" + right="-1" + bottom="-1"> + <layout_panel + auto_resize="false" + name="layout_item_name" layout="topleft" - left="0" - name="item_profile" - top="0" - width="295"> - <text - type="string" - length="1" - follows="left|top" - height="10" + follows="all" + height="25"> + <icon + follows="top|left" + height="16" + image_name="Inv_Object" layout="topleft" left="5" - name="LabelItemNameTitle" - top="10" - width="78"> - Name: - </text> + mouse_opaque="true" + name="item_type_icon" + top="3" + width="16" /> <line_editor border_style="line" border_thickness="1" follows="left|top|right" - height="20" layout="topleft" - left_delta="78" + left_pad="5" + top="1" + right="-5" + height="20" max_length_bytes="63" name="LabelItemName" - top_delta="0" - width="210" tool_tip="The name is limited to 63 characters. Longer prim names are cut short. Names can only consist of printable characters found in the ASCII-7 (non-extended) character set, with the exception of the vertical bar/pipe '|'." /> - <text - type="string" - length="1" - follows="left|top" - height="10" + </layout_panel> + + <layout_panel + auto_resize="false" + name="layout_item_details" + layout="topleft" + follows="all" + height="133"> + + <thumbnail + name="item_thumbnail" + fallback_image="Thumbnail_Fallback" + follows="top|left" layout="topleft" left="5" - name="LabelItemDescTitle" - top_pad="10" - width="78"> - Description: - </text> - <line_editor - border_style="line" - border_thickness="1" - follows="left|top|right" - height="23" - layout="topleft" - left_delta="78" - max_length_bytes="127" - name="LabelItemDesc" - top_delta="-5" - width="210" - tool_tip="When people have 'Hover Tips on All Objects' selected in the viewer's settings, they'll see the object description pop-up for any object under their mouse pointer. The prim description is limited to 127 bytes any string longer then that will be truncated." /> + top="2" + height="128" + width="128" + /> + <text type="string" length="1" follows="left|top" - height="23" + height="16" layout="topleft" - left="5" - name="LabelCreatorTitle" - top_pad="10" + left_pad="5" + name="LabelOwnerTitle" + top="0" width="78"> - Creator: + Owner: </text> - <avatar_icon - follows="top|left" - height="20" - default_icon_name="Generic_Person" - layout="topleft" - left_pad="0" - top_delta="-6" - mouse_opaque="true" - width="20" /> <text type="string" - follows="left|right|top" font="SansSerifSmall" - height="15" + follows="left|right|top" layout="topleft" - left_pad="5" - name="LabelCreatorName" - top_delta="6" + height="15" + width="187" + left_delta="0" + top_pad="0" + name="LabelOwnerName" use_ellipses="true" - width="165"> + translate="false"> +TestString PleaseIgnore </text> - <button - follows="top|right" - height="16" - image_selected="Inspector_I" - image_unselected="Inspector_I" - layout="topleft" - right="-5" - name="BtnCreator" - top_delta="-6" - width="16" /> <text type="string" length="1" follows="left|top" - height="23" + height="16" layout="topleft" - left="5" - name="LabelOwnerTitle" - top_pad="10" + left_delta="0" + name="LabelCreatorTitle" + top_pad="7" width="78"> - Owner: + Creator: </text> - <avatar_icon - follows="top|left" - height="20" - default_icon_name="Generic_Person" - layout="topleft" - left_pad="0" - top_delta="-6" - mouse_opaque="true" - width="20" /> <text type="string" - follows="left|right|top" font="SansSerifSmall" - height="15" + follows="left|right|top" layout="topleft" - left_pad="5" - name="LabelOwnerName" - top_delta="6" + left_delta="0" + top_pad="0" + width="187" + height="15" + name="LabelCreatorName" use_ellipses="true" - width="165"> + translate="false"> +TestString PleaseIgnore </text> - <button - follows="top|right" - height="16" - image_selected="Inspector_I" - image_unselected="Inspector_I" - layout="topleft" - right="-5" - name="BtnOwner" - top_delta="-3" - width="16" /> <text type="string" length="1" follows="left|top" - height="23" + height="16" layout="topleft" - left="5" + left_delta="0" name="LabelAcquiredTitle" - top_pad="10" + top_pad="7" width="78"> Acquired: </text> @@ -258,171 +170,247 @@ type="string" length="1" follows="left|top|right" - height="23" + height="18" layout="topleft" - left_delta="78" + left_delta="0" name="LabelAcquiredDate" - top_delta="0" - width="210"> + top_pad="0" + width="187"> + 00/00/00 </text> - <text - type="string" - length="1" + <button follows="left|top" - height="10" + height="21" + label="Image..." layout="topleft" - left="5" - name="LabelItemExperienceTitle" + left_delta="0" + name="change_thumbnail_btn" top_pad="0" - width="78" - visible="true"> - Experience: - </text> + width="120" /> + </layout_panel> + + <layout_panel + auto_resize="false" + name="layout_item_description" + layout="topleft" + follows="all" + height="84"> <text type="string" length="1" - follows="left|top|right" + follows="left|top" height="10" layout="topleft" - left_delta="78" - name="LabelItemExperience" - top_delta="0" - width="210" - visible="true" - /> - <panel - border="false" - follows="left|top|right" + left="5" + name="LabelItemDescTitle" + top="0" + width="78"> + Description: + </text> + <text_editor + text_type="ascii_printable_no_pipe" + commit_on_focus_lost="true" + border_style="line" + border_thickness="1" + word_wrap="true" + use_ellipses="false" + follows="all" layout="topleft" - mouse_opaque="false" - name="perms_inv" - left="0" - top_pad="25" - height="155" - width="313"> - <text - type="string" - length="1" - left="10" - top_pad="13" - text_color="EmphasisColor" - height="15" - follows="left|top|right" - layout="topleft" - name="perm_modify" - width="200"> - You can: - </text> - <check_box - height="18" - label="Modify" - layout="topleft" - left="20" - name="CheckOwnerModify" - top_pad="0" - width="90" /> - <check_box - height="18" - label="Copy" - layout="topleft" - left_pad="0" - name="CheckOwnerCopy" - width="90" /> - <check_box - height="18" - label="Transfer" - layout="topleft" - left_pad="0" - name="CheckOwnerTransfer" - width="106" /> - <text - type="string" - length="1" - follows="left|top" - height="16" - layout="topleft" - left="10" - name="AnyoneLabel" - top_pad="8" - width="100"> - Anyone: - </text> - <check_box - height="18" - label="Copy" - layout="topleft" - left_pad="0" - name="CheckEveryoneCopy" - tool_tip="Anyone can take a copy of the object . Object and all of its contents must be copy and transfer permissive." - top_delta="-2" - width="150" /> + left="5" + top_pad="5" + right="-5" + height="46" + max_length="127" + name="LabelItemDesc" + tool_tip="When people have 'Hover Tips on All Objects' selected in the viewer's settings, they'll see the object description pop-up for any object under their mouse pointer. The prim description is limited to 127 bytes any string longer then that will be truncated." /> + <text type="string" length="1" follows="left|top" - height="16" + height="10" layout="topleft" - left="10" - name="GroupLabel" - top_pad="8" - width="100"> - Group: + left="5" + name="LabelItemExperienceTitle" + top_pad="7" + width="78" + visible="true"> + Experience: </text> - <check_box - height="18" - label="Share" - layout="topleft" - left_pad="0" - top_delta="-2" - name="CheckShareWithGroup" - tool_tip="Allow all members of the set group to share your modify permissions for this object. You must Deed to enable role restrictions." - width="150" /> <text type="string" length="1" - follows="left|top" - height="16" - layout="topleft" - left="10" - name="NextOwnerLabel" - top_pad="8" - width="200" - word_wrap="true"> - Next owner: - </text> - <check_box - height="18" - label="Modify" - layout="topleft" - left="20" - top_pad="0" - name="CheckNextOwnerModify" - tool_tip="Next owner can edit properties like item name or scale of this object." - width="90" /> - <check_box - height="18" - label="Copy" - layout="topleft" - left_pad="0" - name="CheckNextOwnerCopy" - tool_tip="Next owner can make unlimited copies of this object. Copies maintain creator information, and can never be more permissive than the item being copied." - width="90" /> - <check_box - height="18" - label="Transfer" + follows="left|top|right" + height="10" layout="topleft" - left_pad="0" - name="CheckNextOwnerTransfer" - tool_tip="Next owner can give away or resell this object." - width="106" /> - </panel> + left_delta="78" + name="LabelItemExperience" + top_delta="0" + width="210" + visible="true" + /> + </layout_panel> + + <layout_panel + auto_resize="false" + name="layout_item_permissions_sale" + layout="topleft" + follows="all" + height="235"> + + <view_border + bevel_style="none" + height="0" + layout="topleft" + left="5" + right="-5" + name="cost_text_border" + top="1"/> + + <text + type="string" + length="1" + left="10" + top_pad="7" + height="15" + follows="left|top" + layout="topleft" + name="perm_modify" + width="200"> + Permissions + </text> + + <text + type="string" + length="1" + left="10" + top_pad="5" + height="15" + follows="left|top" + layout="topleft" + name="perm_modify" + width="200"> + You can: + </text> + <check_box + height="18" + label="Modify" + layout="topleft" + left="20" + name="CheckOwnerModify" + top_pad="0" + width="90" /> + <check_box + height="18" + label="Copy" + layout="topleft" + left_pad="0" + name="CheckOwnerCopy" + width="90" /> + <check_box + height="18" + label="Transfer" + layout="topleft" + left_pad="0" + name="CheckOwnerTransfer" + width="106" /> + <text + type="string" + length="1" + follows="left|top" + height="16" + layout="topleft" + left="10" + name="AnyoneLabel" + top_pad="8" + width="100"> + Anyone: + </text> + <check_box + height="18" + label="Copy" + layout="topleft" + left_pad="0" + name="CheckEveryoneCopy" + tool_tip="Anyone can take a copy of the object . Object and all of its contents must be copy and transfer permissive." + top_delta="-2" + width="150" /> + <text + type="string" + length="1" + follows="left|top" + height="16" + layout="topleft" + left="10" + name="GroupLabel" + top_pad="8" + width="100"> + Group: + </text> + <check_box + height="18" + label="Share" + layout="topleft" + left_pad="0" + top_delta="-2" + name="CheckShareWithGroup" + tool_tip="Allow all members of the set group to share your modify permissions for this object. You must Deed to enable role restrictions." + width="150" /> + <text + type="string" + length="1" + follows="left|top" + height="16" + layout="topleft" + left="10" + name="NextOwnerLabel" + top_pad="8" + width="200" + word_wrap="true"> + Next owner: + </text> + <check_box + height="18" + label="Modify" + layout="topleft" + left="20" + top_pad="0" + name="CheckNextOwnerModify" + tool_tip="Next owner can edit properties like item name or scale of this object." + width="90" /> + <check_box + height="18" + label="Copy" + layout="topleft" + left_pad="0" + name="CheckNextOwnerCopy" + tool_tip="Next owner can make unlimited copies of this object. Copies maintain creator information, and can never be more permissive than the item being copied." + width="90" /> + <check_box + height="18" + label="Transfer" + layout="topleft" + left_pad="0" + name="CheckNextOwnerTransfer" + tool_tip="Next owner can give away or resell this object." + width="106" /> + + <view_border + bevel_style="none" + height="0" + layout="topleft" + left="5" + right="-5" + name="cost_text_border" + top_pad="9"/> + <check_box height="18" label="For Sale" layout="topleft" left="20" name="CheckPurchase" - top_pad="20" + top_pad="15" width="100" tool_tip="Lets people buy this object, its content or it copy inworld for specified price." /> <combo_box @@ -461,24 +449,80 @@ max_val="999999999" top_pad="10" tool_tip="Object cost." /> - </panel> + + </layout_panel> - </scroll_container> - <panel - height="30" - layout="topleft" - name="button_panel" - left="5" - top_pad="0" - width="313" - follows="top|right|left"> - <button - follows="top|right" - height="23" - label="Cancel" - layout="topleft" - name="cancel_btn" - right="-1" - width="100" /> - </panel> + <layout_panel + auto_resize="false" + name="layout_debug_permissions" + layout="topleft" + follows="all" + height="30"> + <text + type="string" + length="1" + follows="left|top" + height="10" + layout="topleft" + left="10" + name="BaseMaskDebug" + text_color="White" + top="2" + width="130"> + B: + </text> + <text + type="string" + length="1" + follows="left|top" + height="10" + layout="topleft" + left_delta="60" + name="OwnerMaskDebug" + text_color="White" + top_delta="0" + width="270"> + O: + </text> + <text + type="string" + length="1" + follows="left|top" + height="10" + layout="topleft" + left_delta="60" + name="GroupMaskDebug" + text_color="White" + top_delta="0" + width="210"> + G: + </text> + <text + type="string" + length="1" + follows="left|top" + height="10" + layout="topleft" + left_delta="60" + name="EveryoneMaskDebug" + text_color="White" + top_delta="0" + width="150"> + E: + </text> + <text + type="string" + length="1" + follows="left|top" + height="10" + layout="topleft" + left_delta="60" + name="NextMaskDebug" + text_color="White" + top_delta="0" + width="90"> + N: + </text> + </layout_panel> + </layout_stack> </panel> diff --git a/indra/newview/skins/default/xui/en/sidepanel_task_info.xml b/indra/newview/skins/default/xui/en/sidepanel_task_info.xml index 1c9d750aa6..ddabbbe4cf 100644 --- a/indra/newview/skins/default/xui/en/sidepanel_task_info.xml +++ b/indra/newview/skins/default/xui/en/sidepanel_task_info.xml @@ -62,25 +62,12 @@ name="Sale Mixed"> Mixed Sale </panel.string> - <button - follows="top|left" - height="24" - image_hover_unselected="BackButton_Over" - image_pressed="BackButton_Press" - image_unselected="BackButton_Off" - layout="topleft" - left="8" - name="back_btn" - tab_stop="false" - top="0" - width="30" - use_draw_context_alpha="false" /> - <text + <text follows="top|left|right" font="SansSerifHuge" height="26" layout="topleft" - left_pad="10" + left="48" name="title" text_color="LtGray" top="0" @@ -181,7 +168,6 @@ translate="false" use_ellipses="true" width="225"> - TestString PleaseIgnore </text> <text type="string" diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml index 42a10e8c56..39fcc35580 100644 --- a/indra/newview/skins/default/xui/en/strings.xml +++ b/indra/newview/skins/default/xui/en/strings.xml @@ -2306,6 +2306,8 @@ For AI Character: Get the closest navigable point to the point provided. <string name="FavoritesNoMatchingItems">To add a place to your favorites, click the star to the right of the location name, then save the landmark to "Favorites bar".</string> <string name="MarketplaceNoListing">You have no listings yet.</string> <string name="MarketplaceNoMatchingItems">No items found. Check the spelling of your search string and try again.</string> + <string name="InventorySingleFolderEmpty">Folder is empty.</string> + <string name="InventorySingleFolderNoMatches">No matches.</string> <string name="InventoryNoTexture">You do not have a copy of this texture in your inventory</string> <string name="InventoryInboxNoItems">Your Marketplace purchases will appear here. You may then drag them into your inventory to use them.</string> <string name="MarketplaceURL">https://marketplace.[MARKETPLACE_DOMAIN_NAME]/</string> @@ -2395,8 +2397,11 @@ If you continue to receive this message, please contact Second Life support for <string name="no_modify" value=" (no modify)" /> <string name="no_copy" value=" (no copy)" /> <string name="worn" value=" (worn)" /> - <string name="link" value=" (link)" /> - <string name="broken_link" value=" (broken_link)" /> + <string name="link" value=" link" /> + <string name="broken_link" value=" broken_link" /> + <string name="no_transfer_lbl" value=" no transfer" /> + <string name="no_modify_lbl" value=" no modify" /> + <string name="no_copy_lbl" value=" no copy" /> <string name="LoadingContents">Loading contents...</string> <string name="NoContents">No contents</string> <string name="WornOnAttachmentPoint" value=" (worn on [ATTACHMENT_POINT])" /> diff --git a/indra/newview/skins/default/xui/es/floater_inventory_item_properties.xml b/indra/newview/skins/default/xui/es/floater_inventory_item_properties.xml deleted file mode 100644 index a8a3ad08f8..0000000000 --- a/indra/newview/skins/default/xui/es/floater_inventory_item_properties.xml +++ /dev/null @@ -1,36 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="item properties" title="PROPIEDADES DEL ÍTEM DEL INVENTARIO"> - <floater.string name="unknown">(desconocido)</floater.string> - <floater.string name="public">(público)</floater.string> - <floater.string name="you_can">Usted puede:</floater.string> - <floater.string name="owner_can">El propietario puede:</floater.string> - <floater.string name="acquiredDate">[wkday,datetime,local][day,datetime,local] [mth,datetime,local] [year,datetime,local][hour,datetime,local]:[min,datetime,local]:[second,datetime,local]</floater.string> - <text name="LabelItemNameTitle">Nombre:</text> - <text name="LabelItemDescTitle">Descripción:</text> - <text name="LabelCreatorTitle">Creador:</text> - <button label="Perfil..." label_selected="" name="BtnCreator"/> - <text name="LabelOwnerTitle">Propietario:</text> - <button label="Perfil..." label_selected="" name="BtnOwner"/> - <text name="LabelAcquiredTitle">Adquirido:</text> - <text name="LabelAcquiredDate">May Mié 24 12:50:46 2006</text> - <text name="OwnerLabel">Tú:</text> - <check_box label="Editar" name="CheckOwnerModify"/> - <check_box label="Copiarlo" left_delta="88" name="CheckOwnerCopy"/> - <check_box label="Revender" name="CheckOwnerTransfer"/> - <text name="AnyoneLabel">Cualquiera:</text> - <check_box label="Copiar" name="CheckEveryoneCopy"/> - <text name="GroupLabel">Grupo:</text> - <check_box label="Compartir" name="CheckShareWithGroup"/> - <text name="NextOwnerLabel" width="230">Próximo propietario:</text> - <check_box label="Editar" name="CheckNextOwnerModify"/> - <check_box label="Copiarlo" left_delta="88" name="CheckNextOwnerCopy"/> - <check_box label="Revender" name="CheckNextOwnerTransfer"/> - <check_box label="En venta" name="CheckPurchase"/> - <combo_box name="ComboBoxSaleType"> - <combo_box.item label="Copiar" name="Copy"/> - <combo_box.item label="Contenidos" name="Contents"/> - <combo_box.item label="Original" name="Original"/> - </combo_box> - <spinner label="Precio:" name="Edit Cost"/> - <text name="CurrencySymbol">L$</text> -</floater> diff --git a/indra/newview/skins/default/xui/fr/floater_inventory_item_properties.xml b/indra/newview/skins/default/xui/fr/floater_inventory_item_properties.xml deleted file mode 100644 index 1d4e7c818f..0000000000 --- a/indra/newview/skins/default/xui/fr/floater_inventory_item_properties.xml +++ /dev/null @@ -1,36 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="item properties" title="PROPRIÉTÉS DES ARTICLES DE L'INVENTAIRE"> - <floater.string name="unknown">(inconnu)</floater.string> - <floater.string name="public">(public)</floater.string> - <floater.string name="you_can">Vous pouvez :</floater.string> - <floater.string name="owner_can">Le propriétaire peut :</floater.string> - <floater.string name="acquiredDate">[wkday,datetime,local] [mth,datetime,local] [day,datetime,local] [hour,datetime,local]:[min,datetime,local]:[second,datetime,local] [year,datetime,local]</floater.string> - <text name="LabelItemNameTitle">Nom :</text> - <text name="LabelItemDescTitle">Description :</text> - <text name="LabelCreatorTitle">Créateur :</text> - <button label="Profil..." label_selected="" name="BtnCreator"/> - <text name="LabelOwnerTitle">Propriétaire :</text> - <button label="Profil..." label_selected="" name="BtnOwner"/> - <text name="LabelAcquiredTitle">Acquis :</text> - <text name="LabelAcquiredDate">Wed May 24 12:50:46 2006</text> - <text name="OwnerLabel">Vous :</text> - <check_box label="Modifier" name="CheckOwnerModify"/> - <check_box label="Copier" name="CheckOwnerCopy"/> - <check_box label="Revendre" name="CheckOwnerTransfer"/> - <text name="AnyoneLabel" width="80">N'importe qui :</text> - <check_box label="Copier" name="CheckEveryoneCopy"/> - <text name="GroupLabel" width="80">Groupe :</text> - <check_box label="Partager" name="CheckShareWithGroup"/> - <text name="NextOwnerLabel" width="192">Le prochain propriétaire :</text> - <check_box label="Modifier" name="CheckNextOwnerModify"/> - <check_box label="Copier" name="CheckNextOwnerCopy"/> - <check_box label="Revendre" name="CheckNextOwnerTransfer"/> - <check_box label="À vendre" name="CheckPurchase"/> - <combo_box name="ComboBoxSaleType"> - <combo_box.item label="Copier" name="Copy"/> - <combo_box.item label="Contenu" name="Contents"/> - <combo_box.item label="Original" name="Original"/> - </combo_box> - <spinner label="Prix :" name="Edit Cost"/> - <text name="CurrencySymbol">L$</text> -</floater> diff --git a/indra/newview/skins/default/xui/it/floater_inventory_item_properties.xml b/indra/newview/skins/default/xui/it/floater_inventory_item_properties.xml deleted file mode 100644 index 8cf680b3f0..0000000000 --- a/indra/newview/skins/default/xui/it/floater_inventory_item_properties.xml +++ /dev/null @@ -1,36 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="item properties" title="CARATTERISTICHE DELL'ARTICOLO IN INVENTARIO"> - <floater.string name="unknown">(sconosciuto)</floater.string> - <floater.string name="public">(pubblico)</floater.string> - <floater.string name="you_can">Tu puoi:</floater.string> - <floater.string name="owner_can">Il proprietario può:</floater.string> - <floater.string name="acquiredDate">[wkday,datetime,local] [mth,datetime,local] [day,datetime,local] [hour,datetime,local]:[min,datetime,local]:[second,datetime,local] [year,datetime,local]</floater.string> - <text name="LabelItemNameTitle">Nome:</text> - <text name="LabelItemDescTitle">Descrizione:</text> - <text name="LabelCreatorTitle">Creatore:</text> - <button label="Profilo..." label_selected="" name="BtnCreator"/> - <text name="LabelOwnerTitle">proprietario:</text> - <button label="Profilo..." label_selected="" name="BtnOwner"/> - <text name="LabelAcquiredTitle">Acquisito:</text> - <text name="LabelAcquiredDate">Wed May 24 12:50:46 2006</text> - <text name="OwnerLabel">Tu:</text> - <check_box label="Modifica" name="CheckOwnerModify"/> - <check_box label="Copiare" left_delta="88" name="CheckOwnerCopy"/> - <check_box label="Rivendi" name="CheckOwnerTransfer"/> - <text name="AnyoneLabel">Chiunque:</text> - <check_box label="Copia" name="CheckEveryoneCopy"/> - <text name="GroupLabel">Gruppo:</text> - <check_box label="Condividi" name="CheckShareWithGroup"/> - <text name="NextOwnerLabel" width="230">Proprietario successivo:</text> - <check_box label="Modifica" name="CheckNextOwnerModify"/> - <check_box label="Copiare" left_delta="88" name="CheckNextOwnerCopy"/> - <check_box label="Rivendi" name="CheckNextOwnerTransfer"/> - <check_box label="In vendita" name="CheckPurchase"/> - <combo_box name="ComboBoxSaleType"> - <combo_box.item label="Copia" name="Copy"/> - <combo_box.item label="Contenuti" name="Contents"/> - <combo_box.item label="Originale" name="Original"/> - </combo_box> - <spinner label="Prezzo:" name="Edit Cost"/> - <text name="CurrencySymbol">L$</text> -</floater> diff --git a/indra/newview/skins/default/xui/ja/floater_inventory_item_properties.xml b/indra/newview/skins/default/xui/ja/floater_inventory_item_properties.xml deleted file mode 100644 index 8d3a655a06..0000000000 --- a/indra/newview/skins/default/xui/ja/floater_inventory_item_properties.xml +++ /dev/null @@ -1,36 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="item properties" title="インベントリアイテムのプロパティ"> - <floater.string name="unknown">(不明)</floater.string> - <floater.string name="public">(公共)</floater.string> - <floater.string name="you_can">できること:</floater.string> - <floater.string name="owner_can">オーナーは次のことができます:</floater.string> - <floater.string name="acquiredDate">[year,datetime,local] [mth,datetime,local] [day,datetime,local] [wkday,datetime,local] [hour,datetime,local]:[min,datetime,local]:[second,datetime,local]</floater.string> - <text name="LabelItemNameTitle">名前:</text> - <text name="LabelItemDescTitle">説明:</text> - <text name="LabelCreatorTitle">クリエーター</text> - <button label="プロフィール..." label_selected="" name="BtnCreator"/> - <text name="LabelOwnerTitle">オーナー:</text> - <button label="プロフィール..." label_selected="" name="BtnOwner"/> - <text name="LabelAcquiredTitle">入手日時:</text> - <text name="LabelAcquiredDate">2006年5月24日水曜日12:50:46</text> - <text name="OwnerLabel">あなた:</text> - <check_box label="編集" name="CheckOwnerModify"/> - <check_box label="コピー" name="CheckOwnerCopy"/> - <check_box label="再販・プレゼント" name="CheckOwnerTransfer"/> - <text name="AnyoneLabel">全員:</text> - <check_box label="コピー" name="CheckEveryoneCopy"/> - <text name="GroupLabel">グループ:</text> - <check_box label="共有" name="CheckShareWithGroup"/> - <text name="NextOwnerLabel" width="158">次の所有者:</text> - <check_box label="編集" name="CheckNextOwnerModify"/> - <check_box label="コピー" name="CheckNextOwnerCopy"/> - <check_box label="再販・プレゼント" name="CheckNextOwnerTransfer"/> - <check_box label="売り出し中" name="CheckPurchase"/> - <combo_box name="ComboBoxSaleType"> - <combo_box.item label="コピー" name="Copy"/> - <combo_box.item label="コンテンツ" name="Contents"/> - <combo_box.item label="オリジナル" name="Original"/> - </combo_box> - <spinner label="価格:" name="Edit Cost"/> - <text name="CurrencySymbol">L$</text> -</floater> diff --git a/indra/newview/skins/default/xui/pl/floater_inventory_item_properties.xml b/indra/newview/skins/default/xui/pl/floater_inventory_item_properties.xml deleted file mode 100644 index d2844e117f..0000000000 --- a/indra/newview/skins/default/xui/pl/floater_inventory_item_properties.xml +++ /dev/null @@ -1,59 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes" ?> -<floater name="item properties" title="WŁAŚCIWOŚCI OBIEKTÓW W SZAFIE"> - <floater.string name="unknown"> - (nieznany) - </floater.string> - <floater.string name="public"> - (publiczny) - </floater.string> - <floater.string name="you_can"> - Ty możesz: - </floater.string> - <floater.string name="owner_can"> - Właściciel może: - </floater.string> - <text name="LabelItemNameTitle"> - Nazwa: - </text> - <text name="LabelItemDescTitle"> - Opis: - </text> - <text name="LabelCreatorTitle"> - Twórca: - </text> - <button label="Profil..." name="BtnCreator" /> - <text name="LabelOwnerTitle"> - Właściciel: - </text> - <button label="Profil..." name="BtnOwner" /> - <text name="LabelAcquiredTitle"> - Nabyte: - </text> - <text name="OwnerLabel"> - Ty: - </text> - <check_box label="Modyfikacja" name="CheckOwnerModify" /> - <check_box label="Kopiowanie" name="CheckOwnerCopy" /> - <check_box label="Transferowanie" name="CheckOwnerTransfer" /> - <text name="AnyoneLabel"> - Każdy: - </text> - <check_box label="Kopiowanie" name="CheckEveryoneCopy" /> - <text name="GroupLabel"> - Grupa: - </text> - <check_box label="Udostępnij" name="CheckShareWithGroup" /> - <text name="NextOwnerLabel"> - Nast. właściciel: - </text> - <check_box label="Modyfikacja" name="CheckNextOwnerModify" /> - <check_box label="Kopiowanie" name="CheckNextOwnerCopy" /> - <check_box label="Transferowanie" name="CheckNextOwnerTransfer" /> - <check_box label="Sprzedaż" name="CheckPurchase" /> - <combo_box name="ComboBoxSaleType"> - <combo_box.item label="Kopia" name="Copy" /> - <combo_box.item label="Zawartość" name="Contents" /> - <combo_box.item label="Oryginał" name="Original" /> - </combo_box> - <spinner name="Edit Cost" label="Cena:" /> -</floater> diff --git a/indra/newview/skins/default/xui/pt/floater_inventory_item_properties.xml b/indra/newview/skins/default/xui/pt/floater_inventory_item_properties.xml deleted file mode 100644 index 5f04c08531..0000000000 --- a/indra/newview/skins/default/xui/pt/floater_inventory_item_properties.xml +++ /dev/null @@ -1,36 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="item properties" title="PROPRIEDADES DE ITEM NO INVENTÁRIO"> - <floater.string name="unknown">(desconhecido)</floater.string> - <floater.string name="public">(público)</floater.string> - <floater.string name="you_can">Você pode:</floater.string> - <floater.string name="owner_can">Proprietário pode :</floater.string> - <floater.string name="acquiredDate">[wkday,datetime,local] [mth,datetime,local] [day,datetime,local] [hour,datetime,local]:[min,datetime,local]:[second,datetime,local] [year,datetime,local]</floater.string> - <text name="LabelItemNameTitle">Nome:</text> - <text name="LabelItemDescTitle">Descrição:</text> - <text name="LabelCreatorTitle">Criador:</text> - <button label="Perfil..." label_selected="" name="BtnCreator"/> - <text name="LabelOwnerTitle">Dono:</text> - <button label="Perfil..." label_selected="" name="BtnOwner"/> - <text name="LabelAcquiredTitle">Adquirido:</text> - <text name="LabelAcquiredDate">Qua Mai 24 12:50:46 2006</text> - <text name="OwnerLabel">Você:</text> - <check_box label="Editar" name="CheckOwnerModify"/> - <check_box label="Copiar" name="CheckOwnerCopy"/> - <check_box label="Revender" name="CheckOwnerTransfer"/> - <text name="AnyoneLabel">Todos:</text> - <check_box label="Cortar" name="CheckEveryoneCopy"/> - <text name="GroupLabel">Grupo:</text> - <check_box label="Compartilhar" name="CheckShareWithGroup"/> - <text name="NextOwnerLabel" width="230">Próximo proprietário:</text> - <check_box label="Editar" name="CheckNextOwnerModify"/> - <check_box label="Copiar" name="CheckNextOwnerCopy"/> - <check_box label="Revender" name="CheckNextOwnerTransfer"/> - <check_box label="À venda" name="CheckPurchase"/> - <combo_box name="ComboBoxSaleType"> - <combo_box.item label="Cortar" name="Copy"/> - <combo_box.item label="Conteúdo" name="Contents"/> - <combo_box.item label="Original" name="Original"/> - </combo_box> - <spinner label="Preço:" name="Edit Cost"/> - <text name="CurrencySymbol">L$</text> -</floater> diff --git a/indra/newview/skins/default/xui/ru/floater_inventory_item_properties.xml b/indra/newview/skins/default/xui/ru/floater_inventory_item_properties.xml deleted file mode 100644 index c988825756..0000000000 --- a/indra/newview/skins/default/xui/ru/floater_inventory_item_properties.xml +++ /dev/null @@ -1,36 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="item properties" title="СВОЙСТВА ПРЕДМЕТА"> - <floater.string name="unknown">(неизвестно)</floater.string> - <floater.string name="public">(публичное)</floater.string> - <floater.string name="you_can">Вы можете:</floater.string> - <floater.string name="owner_can">Владелец может:</floater.string> - <floater.string name="acquiredDate">[wkday,datetime,local], [day,datetime,local] [mth,datetime,local] [year,datetime,local] [hour,datetime,local]:[min,datetime,local]:[second,datetime,local]</floater.string> - <text name="LabelItemNameTitle">Название:</text> - <text name="LabelItemDescTitle">Описание:</text> - <text name="LabelCreatorTitle">Создатель:</text> - <button label="Профиль…" name="BtnCreator"/> - <text name="LabelOwnerTitle">Владелец:</text> - <button label="Профиль…" name="BtnOwner"/> - <text name="LabelAcquiredTitle">Приобретено:</text> - <text name="LabelAcquiredDate">Ср 24 Май 12:50:46 2006</text> - <text name="OwnerLabel">Вы:</text> - <check_box label="Изменить" name="CheckOwnerModify"/> - <check_box label="Копировать" name="CheckOwnerCopy"/> - <check_box label="Перепродать" name="CheckOwnerTransfer"/> - <text name="AnyoneLabel">Все:</text> - <check_box label="Копировать" name="CheckEveryoneCopy"/> - <text name="GroupLabel">Группа:</text> - <check_box label="Поделиться" name="CheckShareWithGroup"/> - <text name="NextOwnerLabel">Следующий владелец:</text> - <check_box label="Изменить" name="CheckNextOwnerModify"/> - <check_box label="Копировать" name="CheckNextOwnerCopy"/> - <check_box label="Перепродать" name="CheckNextOwnerTransfer"/> - <check_box label="Для продажи" name="CheckPurchase"/> - <combo_box name="ComboBoxSaleType"> - <combo_box.item label="Копировать" name="Copy"/> - <combo_box.item label="Содержимое" name="Contents"/> - <combo_box.item label="Оригинал" name="Original"/> - </combo_box> - <spinner label="Цена:" name="Edit Cost"/> - <text name="CurrencySymbol">L$</text> -</floater> diff --git a/indra/newview/skins/default/xui/tr/floater_inventory_item_properties.xml b/indra/newview/skins/default/xui/tr/floater_inventory_item_properties.xml deleted file mode 100644 index c6a5515c6e..0000000000 --- a/indra/newview/skins/default/xui/tr/floater_inventory_item_properties.xml +++ /dev/null @@ -1,36 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="item properties" title="ENVANTER ÖGESİ ÖZELLİKLERİ"> - <floater.string name="unknown">(bilinmiyor)</floater.string> - <floater.string name="public">(kamuya açık)</floater.string> - <floater.string name="you_can">Şunu yapabilirsiniz:</floater.string> - <floater.string name="owner_can">Sahip şunu yapabilir:</floater.string> - <floater.string name="acquiredDate">[wkday,datetime,local] [mth,datetime,local] [day,datetime,local] [hour,datetime,local]:[min,datetime,local]:[second,datetime,local] [year,datetime,local]</floater.string> - <text name="LabelItemNameTitle">Ad:</text> - <text name="LabelItemDescTitle">Açıklama:</text> - <text name="LabelCreatorTitle">Oluşturan:</text> - <button label="Profil..." name="BtnCreator"/> - <text name="LabelOwnerTitle">Sahip:</text> - <button label="Profil..." name="BtnOwner"/> - <text name="LabelAcquiredTitle">Alınan:</text> - <text name="LabelAcquiredDate">24 Mayıs Çarş 12:50:46 2006</text> - <text name="OwnerLabel">Siz:</text> - <check_box label="Düzenle" name="CheckOwnerModify"/> - <check_box label="Kopyala" name="CheckOwnerCopy"/> - <check_box label="Tekrar Sat" name="CheckOwnerTransfer"/> - <text name="AnyoneLabel">Herkes:</text> - <check_box label="Kopyala" name="CheckEveryoneCopy"/> - <text name="GroupLabel">Grup:</text> - <check_box label="Paylaş" name="CheckShareWithGroup"/> - <text name="NextOwnerLabel">Sonraki sahip:</text> - <check_box label="Düzenle" name="CheckNextOwnerModify"/> - <check_box label="Kopyala" name="CheckNextOwnerCopy"/> - <check_box label="Tekrar Sat" name="CheckNextOwnerTransfer"/> - <check_box label="Satılık" name="CheckPurchase"/> - <combo_box name="ComboBoxSaleType"> - <combo_box.item label="Kopyala" name="Copy"/> - <combo_box.item label="İçerik" name="Contents"/> - <combo_box.item label="Orijinal" name="Original"/> - </combo_box> - <spinner label="Fiyat:" name="Edit Cost"/> - <text name="CurrencySymbol">L$</text> -</floater> diff --git a/indra/newview/skins/default/xui/zh/floater_inventory_item_properties.xml b/indra/newview/skins/default/xui/zh/floater_inventory_item_properties.xml deleted file mode 100644 index 4f17b96579..0000000000 --- a/indra/newview/skins/default/xui/zh/floater_inventory_item_properties.xml +++ /dev/null @@ -1,36 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="item properties" title="收納區物品屬性"> - <floater.string name="unknown">(未知)</floater.string> - <floater.string name="public">(公開)</floater.string> - <floater.string name="you_can">你可以:</floater.string> - <floater.string name="owner_can">所有人可以:</floater.string> - <floater.string name="acquiredDate">[wkday,datetime,local] [mth,datetime,local] [day,datetime,local] [hour,datetime,local]:[min,datetime,local]:[second,datetime,local] [year,datetime,local]</floater.string> - <text name="LabelItemNameTitle">名稱:</text> - <text name="LabelItemDescTitle">描述:</text> - <text name="LabelCreatorTitle">創造者:</text> - <button label="檔案..." name="BtnCreator"/> - <text name="LabelOwnerTitle">所有人:</text> - <button label="檔案..." name="BtnOwner"/> - <text name="LabelAcquiredTitle">取得於:</text> - <text name="LabelAcquiredDate">Wed May 24 12:50:46 2006</text> - <text name="OwnerLabel">你:</text> - <check_box label="編輯" name="CheckOwnerModify"/> - <check_box label="恚庨" name="CheckOwnerCopy"/> - <check_box label="轉售" name="CheckOwnerTransfer"/> - <text name="AnyoneLabel">任何人:</text> - <check_box label="恚庨" name="CheckEveryoneCopy"/> - <text name="GroupLabel">群組:</text> - <check_box label="分享" name="CheckShareWithGroup"/> - <text name="NextOwnerLabel">下一個所有人:</text> - <check_box label="編輯" name="CheckNextOwnerModify"/> - <check_box label="恚庨" name="CheckNextOwnerCopy"/> - <check_box label="轉售" name="CheckNextOwnerTransfer"/> - <check_box label="出售" name="CheckPurchase"/> - <combo_box name="ComboBoxSaleType"> - <combo_box.item label="複製" name="Copy"/> - <combo_box.item label="內容" name="Contents"/> - <combo_box.item label="原件" name="Original"/> - </combo_box> - <spinner label="價格:" name="Edit Cost"/> - <text name="CurrencySymbol">L$</text> -</floater> |