diff options
Diffstat (limited to 'indra/newview')
7 files changed, 383 insertions, 181 deletions
diff --git a/indra/newview/llfloaterbulkythumbs.cpp b/indra/newview/llfloaterbulkythumbs.cpp index 9ffb71b394..02adf90acf 100644 --- a/indra/newview/llfloaterbulkythumbs.cpp +++ b/indra/newview/llfloaterbulkythumbs.cpp @@ -70,6 +70,10 @@ BOOL LLFloaterBulkyThumbs::postBuild() mWriteThumbnailsBtn->setCommitCallback(boost::bind(&LLFloaterBulkyThumbs::onWriteThumbnails, this)); mWriteThumbnailsBtn->setEnabled(false); + mDisplayThumbnaillessItemsBtn = getChild<LLUICtrl>("display_thumbless_items"); + mDisplayThumbnaillessItemsBtn->setCommitCallback(boost::bind(&LLFloaterBulkyThumbs::onDisplayThumbnaillessItems, this)); + mDisplayThumbnaillessItemsBtn->setEnabled(true); + return true; } @@ -96,6 +100,18 @@ void LLFloaterBulkyThumbs::recordInventoryItemEntry(LLViewerInventoryItem* item) { // dupe - do not save } + + if (item->getThumbnailUUID() == LLUUID::null) + { + mOutputLog->appendText( + STRINGIZE( + "ITEM " << mItemNamesIDs.size() << "> " << + name << + " has no thumbnail" << + //id.asString() << + std::endl + ), false); + } } void LLFloaterBulkyThumbs::onPasteItems() @@ -139,6 +155,13 @@ void LLFloaterBulkyThumbs::onPasteItems() LLInventoryModel::EXCLUDE_TRASH, is_bodypart); + LLIsType is_clothing(LLAssetType::AT_CLOTHING); + gInventory.collectDescendentsIf(cat->getUUID(), + cat_array, + item_array, + LLInventoryModel::EXCLUDE_TRASH, + is_clothing); + for (size_t i = 0; i < item_array.size(); i++) { LLViewerInventoryItem* item = item_array.at(i); @@ -150,7 +173,7 @@ void LLFloaterBulkyThumbs::onPasteItems() if (item) { const LLAssetType::EType item_type = item->getType(); - if (item_type == LLAssetType::AT_OBJECT || item_type == LLAssetType::AT_BODYPART) + if (item_type == LLAssetType::AT_OBJECT || item_type == LLAssetType::AT_BODYPART || item_type == LLAssetType::AT_CLOTHING) { recordInventoryItemEntry(item); } @@ -388,3 +411,33 @@ void LLFloaterBulkyThumbs::onWriteThumbnails() } mOutputLog->setCursorAndScrollToEnd(); } + +void LLFloaterBulkyThumbs::onDisplayThumbnaillessItems() +{ + //std::map<std::string, LLUUID>::iterator item_iter = mItemNamesIDs.begin(); + //size_t index = 1; + + //mOutputLog->appendText("======= Items with no thumbnail =======", false); + + //while (item_iter != mItemNamesIDs.end()) + //{ + // std::string item_name = (*item_iter).first; + + // //mOutputLog->appendText( + // // STRINGIZE( + // // "MATCHING ITEM (" << index++ << "/" << mItemNamesIDs.size() << ") " << item_name << "> " + // // ), false); + + // std::map<std::string, LLUUID>::iterator texture_iter = mTextureNamesIDs.find(item_name); + // if (texture_iter == mTextureNamesIDs.end()) + // { + // mOutputLog->appendText( + // STRINGIZE( + // "MISSING:" << + + // std::endl + // ), false); + + // } + //} +} diff --git a/indra/newview/llfloaterbulkythumbs.h b/indra/newview/llfloaterbulkythumbs.h index 75657002b3..10133553a6 100644 --- a/indra/newview/llfloaterbulkythumbs.h +++ b/indra/newview/llfloaterbulkythumbs.h @@ -57,6 +57,9 @@ class LLFloaterBulkyThumbs: LLUICtrl* mWriteThumbnailsBtn; void onWriteThumbnails(); + LLUICtrl* mDisplayThumbnaillessItemsBtn; + void onDisplayThumbnaillessItems(); + void recordInventoryItemEntry(LLViewerInventoryItem* item); void recordTextureItemEntry(LLViewerInventoryItem* item); diff --git a/indra/newview/llfloaterinventorythumbnailshelper.cpp b/indra/newview/llfloaterinventorythumbnailshelper.cpp index 9697fc3d51..15e1c88572 100644 --- a/indra/newview/llfloaterinventorythumbnailshelper.cpp +++ b/indra/newview/llfloaterinventorythumbnailshelper.cpp @@ -3,6 +3,9 @@ * @author Callum Prentice * @brief LLFloaterInventoryThumbnailsHelper class implementation * + * Usage instructions and some brief notes can be found in Confluence here: + * https://lindenlab.atlassian.net/wiki/spaces/~174746736/pages/2928672843/Inventory+Thumbnail+Helper+Tool + * * $LicenseInfo:firstyear=2008&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. @@ -25,23 +28,20 @@ * $/LicenseInfo$ */ -/** - * Floater that appears when buying an object, giving a preview - * of its contents and their permissions. - */ - #include "llviewerprecompiledheaders.h" -#include "llfloaterinventorythumbnailshelper.h" -#include "lluictrlfactory.h" +#include "llaisapi.h" #include "llclipboard.h" -#include "llinventorymodel.h" #include "llinventoryfunctions.h" -#include "lltexteditor.h" +#include "llinventorymodel.h" +#include "llnotifications.h" +#include "llnotificationsutil.h" #include "llscrolllistctrl.h" -#include "llmediactrl.h" +#include "lltexteditor.h" +#include "lluictrlfactory.h" #include "lluuid.h" -#include "llaisapi.h" + +#include "llfloaterinventorythumbnailshelper.h" LLFloaterInventoryThumbnailsHelper::LLFloaterInventoryThumbnailsHelper(const LLSD& key) : LLFloater("floater_inventory_thumbnails_helper") @@ -54,66 +54,53 @@ LLFloaterInventoryThumbnailsHelper::~LLFloaterInventoryThumbnailsHelper() BOOL LLFloaterInventoryThumbnailsHelper::postBuild() { - mPasteItemsBtn = getChild<LLUICtrl>("paste_items_btn"); - mPasteItemsBtn->setCommitCallback(boost::bind(&LLFloaterInventoryThumbnailsHelper::onPasteItems, this)); - - mPasteTexturesBtn = getChild<LLUICtrl>("paste_textures_btn"); - mPasteTexturesBtn->setCommitCallback(boost::bind(&LLFloaterInventoryThumbnailsHelper::onPasteTextures, this)); + mInventoryThumbnailsList = getChild<LLScrollListCtrl>("inventory_thumbnails_list"); + mInventoryThumbnailsList->setAllowMultipleSelection(true); mOutputLog = getChild<LLTextEditor>("output_log"); mOutputLog->setMaxTextLength(0xffff * 0x10); - //mMergeItemsTexturesBtn = getChild<LLUICtrl>("merge_items_textures"); - //mMergeItemsTexturesBtn->setCommitCallback(boost::bind(&LLFloaterInventoryThumbnailsHelper::onMergeItemsTextures, this)); - //mMergeItemsTexturesBtn->setEnabled(false); + mPasteItemsBtn = getChild<LLUICtrl>("paste_items_btn"); + mPasteItemsBtn->setCommitCallback(boost::bind(&LLFloaterInventoryThumbnailsHelper::onPasteItems, this)); + mPasteItemsBtn->setEnabled(true); - mInventoryThumbnailsList = getChild<LLScrollListCtrl>("inventory_thumbnails_list"); - mInventoryThumbnailsList->setAllowMultipleSelection(true); - mInventoryThumbnailsList->deleteAllItems(); + mPasteTexturesBtn = getChild<LLUICtrl>("paste_textures_btn"); + mPasteTexturesBtn->setCommitCallback(boost::bind(&LLFloaterInventoryThumbnailsHelper::onPasteTextures, this)); + mPasteTexturesBtn->setEnabled(true); mWriteThumbnailsBtn = getChild<LLUICtrl>("write_thumbnails_btn"); mWriteThumbnailsBtn->setCommitCallback(boost::bind(&LLFloaterInventoryThumbnailsHelper::onWriteThumbnails, this)); mWriteThumbnailsBtn->setEnabled(false); + mLogMissingThumbnailsBtn = getChild<LLUICtrl>("log_missing_thumbnails_btn"); + mLogMissingThumbnailsBtn->setCommitCallback(boost::bind(&LLFloaterInventoryThumbnailsHelper::onLogMissingThumbnails, this)); + mLogMissingThumbnailsBtn->setEnabled(false); + + mClearThumbnailsBtn = getChild<LLUICtrl>("clear_thumbnails_btn"); + mClearThumbnailsBtn->setCommitCallback(boost::bind(&LLFloaterInventoryThumbnailsHelper::onClearThumbnails, this)); + mClearThumbnailsBtn->setEnabled(false); + return true; } +// Records an entry in the pasted items - saves it to a map and writes it to the log +// window for later confirmation/validation - since it uses a map, duplicates (based on +// the name) are discarded void LLFloaterInventoryThumbnailsHelper::recordInventoryItemEntry(LLViewerInventoryItem* item) { const std::string name = item->getName(); - std::map<std::string, LLUUID>::iterator iter = mItemNamesIDs.find(name); - if (iter == mItemNamesIDs.end()) + std::map<std::string, LLViewerInventoryItem*>::iterator iter = mItemNamesItems.find(name); + if (iter == mItemNamesItems.end()) { - LLUUID id = item->getUUID(); - mItemNamesIDs.insert({name, id}); + mItemNamesItems.insert({name, item}); - mOutputLog->appendText( + writeToLog( STRINGIZE( - "ITEM " << mItemNamesIDs.size() << "> " << + "ITEM " << mItemNamesItems.size() << "> " << name << - //" | " << - //id.asString() << std::endl ), false); - - // TODO: use this ID to get name of texture and display that - const LLUUID current_thumbnail_id = item->getThumbnailUUID(); - - std::string texture_display = std::string("Not Present"); - if (!current_thumbnail_id.isNull()) - { - texture_display = current_thumbnail_id.asString(); - } - - LLSD row; - row["columns"][0]["column"] = "name"; - row["columns"][0]["type"] = "text"; - row["columns"][0]["value"] = name; - row["columns"][1]["column"] = "texture"; - row["columns"][1]["type"] = "text"; - row["columns"][1]["value"] = texture_display; - mInventoryThumbnailsList->addElement(row); } else { @@ -121,6 +108,10 @@ void LLFloaterInventoryThumbnailsHelper::recordInventoryItemEntry(LLViewerInvent } } +// Called when the user has copied items from their inventory and selects the Paste Items button +// in the UI - iterates over items and folders and saves details of each one. +// The first use of this tool is for updating NUX items and as such, only looks for OBJECTS, +// CLOTHING and BODYPARTS - later versions of this tool should make that selection editable. void LLFloaterInventoryThumbnailsHelper::onPasteItems() { if (!LLClipboard::instance().hasContents()) @@ -128,7 +119,7 @@ void LLFloaterInventoryThumbnailsHelper::onPasteItems() return; } - mOutputLog->appendText( + writeToLog( STRINGIZE( "\n==== Pasting items from inventory ====" << std::endl @@ -142,6 +133,7 @@ void LLFloaterInventoryThumbnailsHelper::onPasteItems() { const LLUUID& entry = objects.at(i); + // Check for a folder const LLInventoryCategory* cat = gInventory.getCategory(entry); if (cat) { @@ -162,6 +154,13 @@ void LLFloaterInventoryThumbnailsHelper::onPasteItems() LLInventoryModel::EXCLUDE_TRASH, is_bodypart); + LLIsType is_clothing(LLAssetType::AT_CLOTHING); + gInventory.collectDescendentsIf(cat->getUUID(), + cat_array, + item_array, + LLInventoryModel::EXCLUDE_TRASH, + is_clothing); + for (size_t i = 0; i < item_array.size(); i++) { LLViewerInventoryItem* item = item_array.at(i); @@ -169,20 +168,28 @@ void LLFloaterInventoryThumbnailsHelper::onPasteItems() } } + // Check for an item LLViewerInventoryItem* item = gInventory.getItem(entry); if (item) { const LLAssetType::EType item_type = item->getType(); - if (item_type == LLAssetType::AT_OBJECT || item_type == LLAssetType::AT_BODYPART) + if (item_type == LLAssetType::AT_OBJECT || item_type == LLAssetType::AT_BODYPART || item_type == LLAssetType::AT_CLOTHING) { recordInventoryItemEntry(item); } } } - mOutputLog->setCursorAndScrollToEnd(); + // update the main list view based on what we found + updateDisplayList(); + + // update the buttons enabled state based on what we found/saved + updateButtonStates(); } +// Records a entry in the pasted textures - saves it to a map and writes it to the log +// window for later confirmation/validation - since it uses a map, duplicates (based on +// the name) are discarded void LLFloaterInventoryThumbnailsHelper::recordTextureItemEntry(LLViewerInventoryItem* item) { const std::string name = item->getName(); @@ -193,7 +200,7 @@ void LLFloaterInventoryThumbnailsHelper::recordTextureItemEntry(LLViewerInventor LLUUID id = item->getAssetUUID(); mTextureNamesIDs.insert({name, id}); - mOutputLog->appendText( + writeToLog( STRINGIZE( "TEXTURE " << mTextureNamesIDs.size() << "> " << name << @@ -208,6 +215,8 @@ void LLFloaterInventoryThumbnailsHelper::recordTextureItemEntry(LLViewerInventor } } +// Called when the user has copied textures from their inventory and selects the Paste Textures +// button in the UI - iterates over textures and folders and saves details of each one. void LLFloaterInventoryThumbnailsHelper::onPasteTextures() { if (!LLClipboard::instance().hasContents()) @@ -215,7 +224,7 @@ void LLFloaterInventoryThumbnailsHelper::onPasteTextures() return; } - mOutputLog->appendText( + writeToLog( STRINGIZE( "\n==== Pasting textures from inventory ====" << std::endl @@ -260,105 +269,65 @@ void LLFloaterInventoryThumbnailsHelper::onPasteTextures() } } - mOutputLog->setCursorAndScrollToEnd(); + // update the main list view based on what we found + updateDisplayList(); - populateThumbnailNames(); + // update the buttons enabled state based on what we found/saved + updateButtonStates(); } - -void LLFloaterInventoryThumbnailsHelper::populateThumbnailNames() +// Updates the main list of entries in the UI based on what is in the maps/storage +void LLFloaterInventoryThumbnailsHelper::updateDisplayList() { - std::map<std::string, LLUUID>::iterator item_iter = mItemNamesIDs.begin(); + mInventoryThumbnailsList->deleteAllItems(); - while (item_iter != mItemNamesIDs.end()) + std::map<std::string, LLViewerInventoryItem*>::iterator item_iter = mItemNamesItems.begin(); + while (item_iter != mItemNamesItems.end()) { std::string item_name = (*item_iter).first; - std::map<std::string, LLUUID>::iterator texture_iter = mTextureNamesIDs.find(item_name); - if (texture_iter != mTextureNamesIDs.end()) + std::string existing_texture_name = std::string(); + LLUUID existing_thumbnail_id = (*item_iter).second->getThumbnailUUID(); + if (existing_thumbnail_id != LLUUID::null) { - const bool case_sensitive = true; - LLScrollListItem* entry = mInventoryThumbnailsList->getItemByLabel(item_name, case_sensitive); - - const std::string texture_name = (*texture_iter).first; - entry->getColumn(1)->setValue(LLSD(texture_name)); + existing_texture_name = existing_thumbnail_id.asString(); + } + else + { + existing_texture_name = "none"; } - ++item_iter; - } -} - -void LLFloaterInventoryThumbnailsHelper::mergeItemsTextures() -{ - mOutputLog->appendText( - STRINGIZE( - "\n==== Matching items and textures for " << - mItemNamesIDs.size() << - " entries ====" << - std::endl - ), false); - - std::map<std::string, LLUUID>::iterator item_iter = mItemNamesIDs.begin(); - size_t index = 1; - - while (item_iter != mItemNamesIDs.end()) - { - std::string item_name = (*item_iter).first; - - mOutputLog->appendText( - STRINGIZE( - "MATCHING ITEM (" << index++ << "/" << mItemNamesIDs.size() << ") " << item_name << "> " - ), false); - + std::string new_texture_name = std::string(); std::map<std::string, LLUUID>::iterator texture_iter = mTextureNamesIDs.find(item_name); if (texture_iter != mTextureNamesIDs.end()) { - mOutputLog->appendText( - STRINGIZE( - "MATCHED" << - std::endl - ), false); - - mNameItemIDTextureId.insert({item_name, {(*item_iter).second, (*texture_iter).second}}); + new_texture_name = (*texture_iter).first; } else { - mOutputLog->appendText( - STRINGIZE( - "NO MATCH FOUND" << - std::endl - ), false); + new_texture_name = "missing"; } - ++item_iter; - } + LLSD row; + row["columns"][EListColumnNum::NAME]["column"] = "item_name"; + row["columns"][EListColumnNum::NAME]["type"] = "text"; + row["columns"][EListColumnNum::NAME]["value"] = item_name; + row["columns"][EListColumnNum::NAME]["font"]["name"] = "Monospace"; - mOutputLog->appendText( - STRINGIZE( - "==== Matched list of items and textures has " << - mNameItemIDTextureId.size() << - " entries ====" << - std::endl - ), true); - - //std::map<std::string, std::pair< LLUUID, LLUUID>>::iterator iter = mNameItemIDTextureId.begin(); - //while (iter != mNameItemIDTextureId.end()) - //{ - // std::string output_line = (*iter).first; - // output_line += "\n"; - // output_line += "item ID: "; - // output_line += ((*iter).second).first.asString(); - // output_line += "\n"; - // output_line += "thumbnail texture ID: "; - // output_line += ((*iter).second).second.asString(); - // output_line += "\n"; - // mOutputLog->appendText(output_line, true); - - // ++iter; - //} - mOutputLog->setCursorAndScrollToEnd(); + row["columns"][EListColumnNum::EXISTING_TEXTURE]["column"] = "existing_texture"; + row["columns"][EListColumnNum::EXISTING_TEXTURE]["type"] = "text"; + row["columns"][EListColumnNum::EXISTING_TEXTURE]["font"]["name"] = "Monospace"; + row["columns"][EListColumnNum::EXISTING_TEXTURE]["value"] = existing_texture_name; + + row["columns"][EListColumnNum::NEW_TEXTURE]["column"] = "new_texture"; + row["columns"][EListColumnNum::NEW_TEXTURE]["type"] = "text"; + row["columns"][EListColumnNum::NEW_TEXTURE]["font"]["name"] = "Monospace"; + row["columns"][EListColumnNum::NEW_TEXTURE]["value"] = new_texture_name; + + mInventoryThumbnailsList->addElement(row); - mWriteThumbnailsBtn->setEnabled(true); + ++item_iter; + } } #if 1 @@ -373,6 +342,9 @@ void inventoryThumbnailsHelperCb(LLPointer<LLInventoryCallback> cb, LLUUID id) } #endif +// Makes calls to the AIS v3 API to record the local changes made to the thumbnails. +// If this is not called, the operations (e.g. set thumbnail or clear thumbnail) +// appear to work but do not push the changes back to the inventory (local cache view only) bool writeInventoryThumbnailID(LLUUID item_id, LLUUID thumbnail_asset_id) { if (AISAPI::isAvailable()) @@ -395,40 +367,164 @@ bool writeInventoryThumbnailID(LLUUID item_id, LLUUID thumbnail_asset_id) } } +// Called when the Write Thumbanils button is pushed. Iterates over the name/item and +// name/.texture maps and where it finds a common name, extracts what is needed and +// writes the thumbnail accordingly. void LLFloaterInventoryThumbnailsHelper::onWriteThumbnails() { - mOutputLog->appendText( - STRINGIZE( - "\n==== Writing thumbnails for " << - mNameItemIDTextureId.size() << - " entries ====" << - std::endl - ), false); + std::map<std::string, LLViewerInventoryItem*>::iterator item_iter = mItemNamesItems.begin(); + while (item_iter != mItemNamesItems.end()) + { + std::string item_name = (*item_iter).first; + + std::map<std::string, LLUUID>::iterator texture_iter = mTextureNamesIDs.find(item_name); + if (texture_iter != mTextureNamesIDs.end()) + { + LLUUID item_id = (*item_iter).second->getUUID(); + + LLUUID thumbnail_asset_id = (*texture_iter).second; - std::map<std::string, std::pair< LLUUID, LLUUID>>::iterator iter = mNameItemIDTextureId.begin(); - size_t index = 1; + writeToLog( + STRINGIZE( + "WRITING THUMB " << + (*item_iter).first << + "\n" << + "item ID: " << + item_id << + "\n" << + "thumbnail texture ID: " << + thumbnail_asset_id << + "\n" + ), true); + + + (*item_iter).second->setThumbnailUUID(thumbnail_asset_id); + + // This additional step (notifying AIS API) is required + // to make the changes persist outside of the local cache + writeInventoryThumbnailID(item_id, thumbnail_asset_id); + } - while (iter != mNameItemIDTextureId.end()) + ++item_iter; + } + + updateDisplayList(); +} + +// Called when the Log Items with Missing Thumbnails is selected. This merely writes +// a list of all the items for which the thumbnail ID is Null. Typical use case is to +// copy from the log window, pasted to Slack to illustrate which items are missing +// a thumbnail +void LLFloaterInventoryThumbnailsHelper::onLogMissingThumbnails() +{ + std::map<std::string, LLViewerInventoryItem*>::iterator item_iter = mItemNamesItems.begin(); + while (item_iter != mItemNamesItems.end()) { - mOutputLog->appendText( - STRINGIZE( - "WRITING THUMB (" << index++ << "/" << mNameItemIDTextureId.size() << ")> " << - (*iter).first << - "\n" << - "item ID: " << - ((*iter).second).first.asString() << - "\n" << - "thumbnail texture ID: " << - ((*iter).second).second.asString() << - "\n" - ), true); - - LLUUID item_id = ((*iter).second).first; - LLUUID thumbnail_asset_id = ((*iter).second).second; - - writeInventoryThumbnailID(item_id, thumbnail_asset_id); - - ++iter; + LLUUID thumbnail_id = (*item_iter).second->getThumbnailUUID(); + + if (thumbnail_id == LLUUID::null) + { + writeToLog( + STRINGIZE( + "Missing thumbnail: " << + (*item_iter).first << + std::endl + ), true); + } + + ++item_iter; + } +} + +// Called when the Clear Thumbnail button is selected. Code to perform the clear (really +// just writing a NULL UUID into the thumbnail field) is behind an "Are you Sure?" dialog +// since it cannot be undone and potentinally, you could remove the thumbnails from your +// whole inventory this way. +void LLFloaterInventoryThumbnailsHelper::onClearThumbnails() +{ + // create and show confirmation (Yes/No) textbox since this is a destructive operation + LLNotificationsUtil::add("ClearInventoryThumbnailsWarning", LLSD(), LLSD(), + [&](const LLSD & notif, const LLSD & resp) + { + S32 opt = LLNotificationsUtil::getSelectedOption(notif, resp); + if (opt == 0) + { + std::map<std::string, LLViewerInventoryItem*>::iterator item_iter = mItemNamesItems.begin(); + while (item_iter != mItemNamesItems.end()) + { + (*item_iter).second->setThumbnailUUID(LLUUID::null); + + // This additional step (notifying AIS API) is required + // to make the changes persist outside of the local cache + const LLUUID item_id = (*item_iter).second->getUUID(); + writeInventoryThumbnailID(item_id, LLUUID::null); + + ++item_iter; + } + + updateDisplayList(); + } + else + { + LL_INFOS() << "Clearing on thumbnails was canceled" << LL_ENDL; + } + }); +} + +// Update the endabled state of some of the UI buttons based on what has +// been recorded so far. For example, if there are no valid item/texture pairs, +// then the Write Thumbnails button is not enabled. +void LLFloaterInventoryThumbnailsHelper::updateButtonStates() +{ + size_t found_count = 0; + + std::map<std::string, LLViewerInventoryItem*>::iterator item_iter = mItemNamesItems.begin(); + while (item_iter != mItemNamesItems.end()) + { + std::string item_name = (*item_iter).first; + + std::map<std::string, LLUUID>::iterator texture_iter = mTextureNamesIDs.find(item_name); + if (texture_iter != mTextureNamesIDs.end()) + { + found_count++; + } + + ++item_iter; + } + + // the "Write Thumbnails" button is only enabled when there is at least one + // item with a matching texture ready to be written to the thumbnail field + if (found_count > 0) + { + mWriteThumbnailsBtn->setEnabled(true); } + else + { + mWriteThumbnailsBtn->setEnabled(false); + } + + // The "Log Missing Items" and "Clear Thumbnails" buttons are only enabled + // when there is at least 1 item that was pasted from inventory (doesn't need + // to have a matching texture for these operations) + if (mItemNamesItems.size() > 0) + { + mLogMissingThumbnailsBtn->setEnabled(true); + mClearThumbnailsBtn->setEnabled(true); + } + else + { + mLogMissingThumbnailsBtn->setEnabled(false); + mClearThumbnailsBtn->setEnabled(false); + } +} + +// Helper function for writing a line to the log window. Currently the only additional +// feature is that it scrolls to the bottom each time a line is written but it +// is envisaged that other common actions will be added here eventually - E.G. write eavh +// line to the Second Life log too for example. +void LLFloaterInventoryThumbnailsHelper::writeToLog(std::string logline, bool prepend_newline) +{ + mOutputLog->appendText(logline, prepend_newline); + mOutputLog->setCursorAndScrollToEnd(); } diff --git a/indra/newview/llfloaterinventorythumbnailshelper.h b/indra/newview/llfloaterinventorythumbnailshelper.h index ec83d5b7e0..b42a85d1a5 100644 --- a/indra/newview/llfloaterinventorythumbnailshelper.h +++ b/indra/newview/llfloaterinventorythumbnailshelper.h @@ -1,7 +1,7 @@ /** * @file llfloaterinventorythumbnailshelper.h * @author Callum Prentice - * @brief Helper floater for bulk processing of inventory thumbnails + * @brief Helper floater for bulk processing of inventory thumbnails tool * * $LicenseInfo:firstyear=2008&license=viewerlgpl$ * Second Life Viewer Source Code @@ -31,7 +31,6 @@ #include "llfloater.h" class LLTextEditor; class LLScrollListCtrl; -class LLMediaCtrl; class LLViewerInventoryItem; class LLUUID; @@ -46,27 +45,38 @@ class LLFloaterInventoryThumbnailsHelper: LLScrollListCtrl* mInventoryThumbnailsList; + LLTextEditor* mOutputLog; + LLUICtrl* mPasteItemsBtn; void onPasteItems(); LLUICtrl* mPasteTexturesBtn; void onPasteTextures(); - LLTextEditor* mOutputLog; - - void mergeItemsTextures(); - LLUICtrl* mWriteThumbnailsBtn; void onWriteThumbnails(); + LLUICtrl* mLogMissingThumbnailsBtn; + void onLogMissingThumbnails(); + + LLUICtrl* mClearThumbnailsBtn; + void onClearThumbnails(); + void recordInventoryItemEntry(LLViewerInventoryItem* item); void recordTextureItemEntry(LLViewerInventoryItem* item); - void populateThumbnailNames(); + void updateButtonStates(); + void updateDisplayList(); + void writeToLog(std::string logline, bool prepend_newline); - std::map<std::string, LLUUID> mItemNamesIDs; + std::map<std::string, LLViewerInventoryItem*> mItemNamesItems; std::map<std::string, LLUUID> mTextureNamesIDs; - std::map<std::string, std::pair< LLUUID, LLUUID>> mNameItemIDTextureId; + enum EListColumnNum + { + NAME = 0, + EXISTING_TEXTURE = 1, + NEW_TEXTURE = 2 + }; }; #endif // LL_LLFLOATERINVENTORYTHUMBNAILSHELPER_H diff --git a/indra/newview/skins/default/xui/en/floater_bulky_thumbs.xml b/indra/newview/skins/default/xui/en/floater_bulky_thumbs.xml index e94717f947..d23fd1247f 100644 --- a/indra/newview/skins/default/xui/en/floater_bulky_thumbs.xml +++ b/indra/newview/skins/default/xui/en/floater_bulky_thumbs.xml @@ -44,14 +44,23 @@ left="10" name="merge_items_textures" bottom="8" - width="200" /> + width="100" /> <button follows="left|bottom" height="20" label="Write Thumbnails" layout="bottomleft" - left="250" + left="150" name="write_items_thumbnails" bottom="8" - width="200" /> + width="100" /> + <button + follows="left|bottom" + height="20" + label="Missing Thumbnails" + layout="bottomleft" + left="250" + name="display_thumbless_items" + bottom="8" + width="100" /> </floater>
\ No newline at end of file diff --git a/indra/newview/skins/default/xui/en/floater_inventory_thumbnails_helper.xml b/indra/newview/skins/default/xui/en/floater_inventory_thumbnails_helper.xml index 512bce2475..aa3500bac2 100644 --- a/indra/newview/skins/default/xui/en/floater_inventory_thumbnails_helper.xml +++ b/indra/newview/skins/default/xui/en/floater_inventory_thumbnails_helper.xml @@ -9,7 +9,7 @@ name="contents" help_topic="contents" title="Inventory Thumbnails Helper" - width="500"> + width="800"> <scroll_list top="20" height="350" @@ -23,14 +23,20 @@ right="-8" tool_tip="Paste items from your inventory"> <scroll_list.columns + dynamic_width="true" label="Inventory Item" - name="name" - relative_width="0.40" /> + name="item_name" + relative_width="0.4" /> + <scroll_list.columns + dynamic_width="true" + label="Existing Texture" + name="existing_texture" + relative_width="0.3" /> <scroll_list.columns dynamic_width="true" - label="Texture Name" - name="texture" - relative_width="0.6" /> + label="New Texture" + name="new_texture" + relative_width="0.3" /> </scroll_list> <text_editor top="375" @@ -73,10 +79,21 @@ <button follows="left|bottom" height="20" - label="List items with no thumb" + label="Log items with no thumbnail" layout="bottomleft" right="-10" - name="list_items_no_thumb_btn" + name="log_missing_thumbnails_btn" bottom="60" width="235" /> + <button + follows="left|bottom" + height="20" + label="Clear thumbnails from pasted items" + layout="bottomleft" + right="-10" + name="clear_thumbnails_btn" + top_delta="26" + width="235" /> + + </floater>
\ No newline at end of file diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml index ef720e65e3..45020163ef 100644 --- a/indra/newview/skins/default/xui/en/notifications.xml +++ b/indra/newview/skins/default/xui/en/notifications.xml @@ -12074,4 +12074,18 @@ Would you like to save them first? yestext="Yes"/> </notification> + <notification + icon="alertmodal.tga" + name="ClearInventoryThumbnailsWarning" + type="alertmodal"> + You are about to remove thumbnail images from the inventory items in the list. This change cannot be undone. + + Would you like to proceed? + <tag>confirm</tag> + <usetemplate + name="okcancelbuttons" + notext="No" + yestext="Yes"/> + </notification> + </notifications> |