diff options
| -rw-r--r-- | indra/newview/CMakeLists.txt | 2 | ||||
| -rw-r--r-- | indra/newview/llfloaterinventorythumbnailshelper.cpp | 543 | ||||
| -rw-r--r-- | indra/newview/llfloaterinventorythumbnailshelper.h | 82 | ||||
| -rw-r--r-- | indra/newview/llviewerfloaterreg.cpp | 4 | ||||
| -rw-r--r-- | indra/newview/skins/default/xui/en/floater_inventory_thumbnails_helper.xml | 99 | ||||
| -rw-r--r-- | indra/newview/skins/default/xui/en/menu_viewer.xml | 15 | ||||
| -rw-r--r-- | indra/newview/skins/default/xui/en/notifications.xml | 27 | 
7 files changed, 771 insertions, 1 deletions
| diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 2c45e0713c..ecc6a4e661 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -231,6 +231,7 @@ set(viewer_SOURCE_FILES      llfloaterimcontainer.cpp      llfloaterinspect.cpp      llfloaterinventorysettings.cpp +    llfloaterinventorythumbnailshelper.cpp      llfloaterjoystick.cpp      llfloaterlagmeter.cpp      llfloaterland.cpp @@ -880,6 +881,7 @@ set(viewer_HEADER_FILES      llfloaterimcontainer.h      llfloaterinspect.h      llfloaterinventorysettings.h +    llfloaterinventorythumbnailshelper.h      llfloaterjoystick.h      llfloaterlagmeter.h      llfloaterland.h diff --git a/indra/newview/llfloaterinventorythumbnailshelper.cpp b/indra/newview/llfloaterinventorythumbnailshelper.cpp new file mode 100644 index 0000000000..814f88e9b9 --- /dev/null +++ b/indra/newview/llfloaterinventorythumbnailshelper.cpp @@ -0,0 +1,543 @@ +/** + * @file llfloaterinventorythumbnailshelper.cpp + * @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. + * + * 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 "llaisapi.h" +#include "llclipboard.h" +#include "llinventoryfunctions.h" +#include "llinventorymodel.h" +#include "llnotifications.h" +#include "llnotificationsutil.h" +#include "llscrolllistctrl.h" +#include "lltexteditor.h" +#include "lluictrlfactory.h" +#include "lluuid.h" + +#include "llfloaterinventorythumbnailshelper.h" + +LLFloaterInventoryThumbnailsHelper::LLFloaterInventoryThumbnailsHelper(const LLSD& key) +    :   LLFloater("floater_inventory_thumbnails_helper") +{ +} + +LLFloaterInventoryThumbnailsHelper::~LLFloaterInventoryThumbnailsHelper() +{ +} + +BOOL LLFloaterInventoryThumbnailsHelper::postBuild() +{ +    mInventoryThumbnailsList = getChild<LLScrollListCtrl>("inventory_thumbnails_list"); +    mInventoryThumbnailsList->setAllowMultipleSelection(true); + +    mOutputLog = getChild<LLTextEditor>("output_log"); +    mOutputLog->setMaxTextLength(0xffff * 0x10); + +    mPasteItemsBtn = getChild<LLUICtrl>("paste_items_btn"); +    mPasteItemsBtn->setCommitCallback(boost::bind(&LLFloaterInventoryThumbnailsHelper::onPasteItems, this)); +    mPasteItemsBtn->setEnabled(true); + +    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, LLViewerInventoryItem*>::iterator iter = mItemNamesItems.find(name); +    if (iter == mItemNamesItems.end()) +    { +        mItemNamesItems.insert({name, item}); + +        writeToLog( +            STRINGIZE( +                "ITEM " << mItemNamesItems.size() << "> " << +                name << +                std::endl +            ), false); +    } +    else +    { +        // dupe - do not save +    } +} + +// 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()) +    { +        return; +    } + +    writeToLog( +        STRINGIZE( +            "\n==== Pasting items from inventory ====" << +            std::endl +        ), false); + +    std::vector<LLUUID> objects; +    LLClipboard::instance().pasteFromClipboard(objects); +    size_t count = objects.size(); + +    for (size_t i = 0; i < count; i++) +    { +        const LLUUID& entry = objects.at(i); + +        // Check for a folder +        const LLInventoryCategory* cat = gInventory.getCategory(entry); +        if (cat) +        { +            LLInventoryModel::cat_array_t cat_array; +            LLInventoryModel::item_array_t item_array; + +            LLIsType is_object(LLAssetType::AT_OBJECT); +            gInventory.collectDescendentsIf(cat->getUUID(), +                                            cat_array, +                                            item_array, +                                            LLInventoryModel::EXCLUDE_TRASH, +                                            is_object); + +            LLIsType is_bodypart(LLAssetType::AT_BODYPART); +            gInventory.collectDescendentsIf(cat->getUUID(), +                                            cat_array, +                                            item_array, +                                            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); +                recordInventoryItemEntry(item); +            } +        } + +        // 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 || item_type == LLAssetType::AT_CLOTHING) +            { +                recordInventoryItemEntry(item); +            } +        } +    } + +    // 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(); + +    std::map<std::string, LLUUID>::iterator iter = mTextureNamesIDs.find(name); +    if (iter == mTextureNamesIDs.end()) +    { +        LLUUID id = item->getAssetUUID(); +        mTextureNamesIDs.insert({name, id}); + +        writeToLog( +            STRINGIZE( +                "TEXTURE " << mTextureNamesIDs.size() << "> " << +                name << +                //" | " << +                //id.asString() << +                std::endl +            ), false); +    } +    else +    { +        // dupe - do not save +    } +} + +// 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()) +    { +        return; +    } + +    writeToLog( +        STRINGIZE( +            "\n==== Pasting textures from inventory ====" << +            std::endl +        ), false); + +    std::vector<LLUUID> objects; +    LLClipboard::instance().pasteFromClipboard(objects); +    size_t count = objects.size(); + +    for (size_t i = 0; i < count; i++) +    { +        const LLUUID& entry = objects.at(i); + +        const LLInventoryCategory* cat = gInventory.getCategory(entry); +        if (cat) +        { +            LLInventoryModel::cat_array_t cat_array; +            LLInventoryModel::item_array_t item_array; + +            LLIsType is_object(LLAssetType::AT_TEXTURE); +            gInventory.collectDescendentsIf(cat->getUUID(), +                                            cat_array, +                                            item_array, +                                            LLInventoryModel::EXCLUDE_TRASH, +                                            is_object); + +            for (size_t i = 0; i < item_array.size(); i++) +            { +                LLViewerInventoryItem* item = item_array.at(i); +                recordTextureItemEntry(item); +            } +        } + +        LLViewerInventoryItem* item = gInventory.getItem(entry); +        if (item) +        { +            const LLAssetType::EType item_type = item->getType(); +            if (item_type == LLAssetType::AT_TEXTURE) +            { +                recordTextureItemEntry(item); +            } +        } +    } + +    // update the main list view based on what we found +    updateDisplayList(); + +    // update the buttons enabled state based on what we found/saved +    updateButtonStates(); +} + +// Updates the main list of entries in the UI based on what is in the maps/storage +void LLFloaterInventoryThumbnailsHelper::updateDisplayList() +{ +    mInventoryThumbnailsList->deleteAllItems(); + +    std::map<std::string, LLViewerInventoryItem*>::iterator item_iter = mItemNamesItems.begin(); +    while (item_iter != mItemNamesItems.end()) +    { +        std::string item_name = (*item_iter).first; + +        std::string existing_texture_name = std::string(); +        LLUUID existing_thumbnail_id = (*item_iter).second->getThumbnailUUID(); +        if (existing_thumbnail_id != LLUUID::null) +        { +            existing_texture_name = existing_thumbnail_id.asString(); +        } +        else +        { +            existing_texture_name = "none"; +        } + +        std::string new_texture_name = std::string(); +        std::map<std::string, LLUUID>::iterator texture_iter = mTextureNamesIDs.find(item_name); +        if (texture_iter != mTextureNamesIDs.end()) +        { +            new_texture_name = (*texture_iter).first; +        } +        else +        { +            new_texture_name = "missing"; +        } + +        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"; + +        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); + +        ++item_iter; +    } +} + +#if 1 +// *TODO$: LLInventoryCallback should be deprecated to conform to the new boost::bind/coroutine model. +// temp code in transition +void inventoryThumbnailsHelperCb(LLPointer<LLInventoryCallback> cb, LLUUID id) +{ +    if (cb.notNull()) +    { +        cb->fire(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()) +    { + +        LLSD updates; +        updates["thumbnail"] = LLSD().with("asset_id", thumbnail_asset_id.asString()); + +        LLPointer<LLInventoryCallback> cb; + +        AISAPI::completion_t cr = boost::bind(&inventoryThumbnailsHelperCb, cb, _1); +        AISAPI::UpdateItem(item_id, updates, cr); + +        return true; +    } +    else +    { +        LL_WARNS() << "Unable to write inventory thumbnail because the AIS API is not available" << LL_ENDL; +        return false; +    } +} + +// 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() +{ +    // create and show confirmation (Yes/No) textbox since this is a destructive operation +    LLNotificationsUtil::add("WriteInventoryThumbnailsWarning", 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()) +            { +                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; + +                    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); +                } + +                ++item_iter; +            } + +            updateDisplayList(); +        } +        else +        { +            LL_INFOS() << "Writing new thumbnails was canceled" << LL_ENDL; +        } +    }); +} + +// 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()) +    { +        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 new file mode 100644 index 0000000000..b42a85d1a5 --- /dev/null +++ b/indra/newview/llfloaterinventorythumbnailshelper.h @@ -0,0 +1,82 @@ +/** + * @file llfloaterinventorythumbnailshelper.h + * @author Callum Prentice + * @brief Helper floater for bulk processing of inventory thumbnails tool + * + * $LicenseInfo:firstyear=2008&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_LLFLOATERINVENTORYTHUMBNAILSHELPER_H +#define LL_LLFLOATERINVENTORYTHUMBNAILSHELPER_H + +#include "llfloater.h" +class LLTextEditor; +class LLScrollListCtrl; +class LLViewerInventoryItem; +class LLUUID; + +class LLFloaterInventoryThumbnailsHelper: +    public LLFloater +{ +        friend class LLFloaterReg; +    private: +        LLFloaterInventoryThumbnailsHelper(const LLSD& key); +        BOOL postBuild() override; +        ~LLFloaterInventoryThumbnailsHelper(); + +        LLScrollListCtrl* mInventoryThumbnailsList; + +        LLTextEditor* mOutputLog; + +        LLUICtrl* mPasteItemsBtn; +        void onPasteItems(); + +        LLUICtrl* mPasteTexturesBtn; +        void onPasteTextures(); + +        LLUICtrl* mWriteThumbnailsBtn; +        void onWriteThumbnails(); + +        LLUICtrl* mLogMissingThumbnailsBtn; +        void onLogMissingThumbnails(); + +        LLUICtrl* mClearThumbnailsBtn; +        void onClearThumbnails(); + +        void recordInventoryItemEntry(LLViewerInventoryItem* item); +        void recordTextureItemEntry(LLViewerInventoryItem* item); +        void updateButtonStates(); +        void updateDisplayList(); +        void writeToLog(std::string logline, bool prepend_newline); + +        std::map<std::string, LLViewerInventoryItem*> mItemNamesItems; +        std::map<std::string, LLUUID> mTextureNamesIDs; + +        enum EListColumnNum +        { +            NAME = 0, +            EXISTING_TEXTURE = 1, +            NEW_TEXTURE = 2 +        }; +}; + +#endif // LL_LLFLOATERINVENTORYTHUMBNAILSHELPER_H diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp index 15b95d70a9..08029b5446 100644 --- a/indra/newview/llviewerfloaterreg.cpp +++ b/indra/newview/llviewerfloaterreg.cpp @@ -86,6 +86,7 @@  #include "llfloaterimsession.h"  #include "llfloaterinspect.h"  #include "llfloaterinventorysettings.h" +#include "llfloaterinventorythumbnailshelper.h"  #include "llfloaterjoystick.h"  #include "llfloaterlagmeter.h"  #include "llfloaterland.h" @@ -329,7 +330,7 @@ void LLViewerFloaterReg::registerFloaters()  	LLFloaterReg::add("build", "floater_tools.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterTools>);  	LLFloaterReg::add("build_options", "floater_build_options.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterBuildOptions>);  	LLFloaterReg::add("bumps", "floater_bumps.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterBump>); - +      	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>); @@ -376,6 +377,7 @@ void LLViewerFloaterReg::registerFloaters()  	LLFloaterReg::add("incoming_call", "floater_incoming_call.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLIncomingCallDialog>);  	LLFloaterReg::add("inventory", "floater_my_inventory.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSidePanelContainer>);  	LLFloaterReg::add("inspect", "floater_inspect.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterInspect>); +    LLFloaterReg::add("inventory_thumbnails_helper", "floater_inventory_thumbnails_helper.xml", (LLFloaterBuildFunc) &LLFloaterReg::build<LLFloaterInventoryThumbnailsHelper>);  	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>); 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 new file mode 100644 index 0000000000..aa3500bac2 --- /dev/null +++ b/indra/newview/skins/default/xui/en/floater_inventory_thumbnails_helper.xml @@ -0,0 +1,99 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<floater +  legacy_header_height="18" +  can_resize="false" +  height="600" +  layout="topleft" +  min_height="175" +  min_width="500" +  name="contents" +  help_topic="contents" +  title="Inventory Thumbnails Helper" +  width="800"> +    <scroll_list +       top="20" +       height="350" +       draw_stripes="true" +       draw_heading="true" +       follows="all" +       layout="topleft" +       left="8" +       multi_select="true" +       name="inventory_thumbnails_list" +       right="-8" +       tool_tip="Paste items from your inventory"> +        <scroll_list.columns +             dynamic_width="true" +             label="Inventory Item" +             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="New Texture" +             name="new_texture" +             relative_width="0.3" /> +    </scroll_list> +    <text_editor +      top="375" +      height="140" +      follows="all" +      left="8" +      right="-8" +      name="output_log" +      font="Monospace" +      text_color="0.1 0.5 0.1 1.0" +      width="480"> +    </text_editor> +    <button +      follows="left|bottom" +      height="20" +      label="Paste items from Inventory" +      layout="topleft" +      left="10" +      name="paste_items_btn" +      bottom="-60" +      width="235" /> +    <button +      follows="left|bottom" +      height="20" +      label="Paste textures from Inventory" +      layout="topleft" +      left_delta="0" +      name="paste_textures_btn" +      top_delta="26	" +      width="235" /> +    <button +      follows="left|bottom" +      height="20" +      label="Write Thumbnails" +      layout="topleft" +      left_delta="0" +      name="write_thumbnails_btn" +      top_delta="26	" +      width="235" /> +    <button +      follows="left|bottom" +      height="20" +      label="Log items with no thumbnail" +      layout="bottomleft" +      right="-10" +      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/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml index 810d3fddd5..8b6f1b097a 100644 --- a/indra/newview/skins/default/xui/en/menu_viewer.xml +++ b/indra/newview/skins/default/xui/en/menu_viewer.xml @@ -3522,6 +3522,21 @@ function="World.EnvPreset"               function="Advanced.WebContentTest"               parameter="http://duckduckgo.com"/>            </menu_item_call> +            <menu_item_call +             label="Inventory Thumbnails Helper" +             name="Inventory Thumbnails Helper" +				shortcut="control|alt|shift|X"> +                <menu_item_call.on_click +                 function="Floater.Show" +                 parameter="inventory_thumbnails_helper" /> +            </menu_item_call> +            <menu_item_call +           label="FB Connect Test" +           name="FB Connect Test"> +            <menu_item_call.on_click +             function="Advanced.WebContentTest" +             parameter="https://cryptic-ridge-1632.herokuapp.com/"/> +          </menu_item_call>            <menu_item_call               label="Dump SelectMgr"               name="Dump SelectMgr"> diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml index d0c73f0973..9eb9f5c1c8 100644 --- a/indra/newview/skins/default/xui/en/notifications.xml +++ b/indra/newview/skins/default/xui/en/notifications.xml @@ -12115,4 +12115,31 @@ are wearing now.         yestext="Save"/>    </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> + +    <notification +  icon="alertmodal.tga" +  name="WriteInventoryThumbnailsWarning" +  type="alertmodal"> +        You are about to overwrite thumbnail images for some or all of 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> | 
