From 1f4dfd08c20446f15e17a1f91242846d38bb065c Mon Sep 17 00:00:00 2001 From: Ansariel Date: Tue, 9 Jan 2018 14:33:55 +0100 Subject: [PATCH 01/31] Set correct lib version --- autobuild.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/autobuild.xml b/autobuild.xml index 3015184439..b7cc327cea 100644 --- a/autobuild.xml +++ b/autobuild.xml @@ -644,7 +644,7 @@ version - 1.10.00 + 1.10.02 fmodex From 5c1c3604b6d6745ff702f536314ff8ab1ec8e7a6 Mon Sep 17 00:00:00 2001 From: Ansariel Date: Tue, 9 Jan 2018 23:15:13 +0100 Subject: [PATCH 02/31] Somehow this got mangled up... --- indra/llaudio/llaudioengine_fmodstudio.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/indra/llaudio/llaudioengine_fmodstudio.cpp b/indra/llaudio/llaudioengine_fmodstudio.cpp index 9d7b0509ac..e55485bb02 100644 --- a/indra/llaudio/llaudioengine_fmodstudio.cpp +++ b/indra/llaudio/llaudioengine_fmodstudio.cpp @@ -126,9 +126,8 @@ bool LLAudioEngine_FMODSTUDIO::init(const S32 num_channels, void* userdata) break; } - // In this case, all sounds, PLUS wind and stream will be software. - result = mSystem->setSoftwareChannels(num_channels + 2); - Check_FMOD_Error(result,"FMOD::System::setSoftwareChannels"); + result = mSystem->setAdvancedSettings(&adv_settings); + Check_FMOD_Error(result, "FMOD::System::setAdvancedSettings"); U32 fmod_flags = FMOD_INIT_NORMAL | FMOD_INIT_3D_RIGHTHANDED | FMOD_INIT_THREAD_UNSAFE; if(mEnableProfiler) @@ -239,6 +238,11 @@ bool LLAudioEngine_FMODSTUDIO::init(const S32 num_channels, void* userdata) LL_INFOS("AppInit") << "LLAudioEngine_FMODSTUDIO::init() FMOD Studio initialized correctly" << LL_ENDL; + FMOD_ADVANCEDSETTINGS adv_settings_dump = { }; + mSystem->getAdvancedSettings(&adv_settings_dump); + + LL_INFOS("AppInit") << "LLAudioEngine_FMODSTUDIO::init(): resampler=" << adv_settings.resamplerMethod << " bytes" << LL_ENDL; + int r_numbuffers, r_samplerate, r_channels; unsigned int r_bufferlength; mSystem->getDSPBufferSize(&r_bufferlength, &r_numbuffers); From 2e3d7676f57b96a4f3bb891ed211725b68c85103 Mon Sep 17 00:00:00 2001 From: Liny Date: Tue, 9 Jan 2018 20:06:48 -0800 Subject: [PATCH 03/31] Add fmod studio for linux --- autobuild.xml | 4 ++-- indra/cmake/Copy3rdPartyLibs.cmake | 4 ++-- indra/newview/viewer_manifest.py | 22 +++++++++++++++++++--- package_override_gcc.ini | 3 +++ 4 files changed, 26 insertions(+), 7 deletions(-) diff --git a/autobuild.xml b/autobuild.xml index b7cc327cea..ac30b5752b 100644 --- a/autobuild.xml +++ b/autobuild.xml @@ -619,11 +619,11 @@ archive hash - 1331456a3df95294eaf44fab990f62cd + eccdcb4a1e96bb829284d01255f4f913 hash_algorithm md5 url - file:///opt/firestorm/fmodstudio-1.10.02-linux-.tar.bz2 + file:///opt/firestorm/fmodstudio-1.10.02-linux-201801091647.tar.bz2 name linux diff --git a/indra/cmake/Copy3rdPartyLibs.cmake b/indra/cmake/Copy3rdPartyLibs.cmake index ee2d333121..78e8b92a9e 100644 --- a/indra/cmake/Copy3rdPartyLibs.cmake +++ b/indra/cmake/Copy3rdPartyLibs.cmake @@ -278,8 +278,8 @@ elseif(LINUX) set(debug_files ${debug_files} "libfmodL.so") set(release_files ${release_files} "libfmod.so") else( NOT ND_BUILD64BIT_ARCH ) - set(debug_files ${debug_files} "libfmodL64.so") - set(release_files ${release_files} "libfmod64.so") + set(debug_files ${debug_files} "libfmodL.so") + set(release_files ${release_files} "libfmod.so") endif( NOT ND_BUILD64BIT_ARCH ) endif (FMODSTUDIO) diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py index ac829705ca..4c1c223229 100755 --- a/indra/newview/viewer_manifest.py +++ b/indra/newview/viewer_manifest.py @@ -1665,6 +1665,15 @@ class Linux_i686_Manifest(LinuxManifest): print "Skipping libfmodex.so - not found" pass + try: + self.path("libfmod-*.so") + self.path("libfmod.so") + self.path("libfmod.so*") + pass + except: + print "Skipping libfmodstudio.so - not found" + pass + self.end_prefix("lib") # Vivox runtimes @@ -1701,14 +1710,21 @@ class Linux_x86_64_Manifest(LinuxManifest): try: self.path("libfmodex64-*.so") self.path("libfmodex64.so") - self.path("libfmod64.so") - self.path("libfmod.so") - self.path("libfmod.so*") + self.path("libfmodex64.so*") pass except: print "Skipping libfmodex.so - not found" pass + try: + self.path("libfmod-*.so") + self.path("libfmod.so") + self.path("libfmod.so*") + pass + except: + print "Skipping libfmod.so - not found" + pass + self.end_prefix("lib") self.prefix(src="../packages/lib/release/x64", dst="lib") diff --git a/package_override_gcc.ini b/package_override_gcc.ini index fcaf1a5d21..c84b012dfa 100644 --- a/package_override_gcc.ini +++ b/package_override_gcc.ini @@ -1,6 +1,9 @@ [firestorm] linux = build_directory|build-linux-x86_64 +[fmodstudio] +linux = file:///opt/firestorm/fmodstudio-1.10.02-linux-x64-201801091648.tar.bz2|8787b777a49d41ccbb3cbd6c4a1d768d + [gstreamer] linux = http://downloads.phoenixviewer.com/gstreamer-0.10.6.201505150224-r5-linux-x64-201505150224-r5.tar.bz2|22d197890dd99756250912f396cb1abb From 50d1556d3b765f06842e7faaee3e6d9c89c3ce92 Mon Sep 17 00:00:00 2001 From: Ansariel Date: Wed, 10 Jan 2018 23:07:02 +0100 Subject: [PATCH 04/31] FIRE-20809: Improve HUD management --- indra/newview/CMakeLists.txt | 2 + indra/newview/app_settings/commands.xml | 10 + indra/newview/app_settings/settings.xml | 11 + .../app_settings/settings_per_account.xml | 11 +- indra/newview/fsfloaterwearablefavorites.cpp | 376 ++++++++++++++++++ indra/newview/fsfloaterwearablefavorites.h | 110 +++++ indra/newview/llinventorybridge.cpp | 12 +- indra/newview/llinventoryfunctions.cpp | 10 + indra/newview/llinventorymodel.cpp | 13 +- indra/newview/llviewerfloaterreg.cpp | 2 + indra/newview/llwearableitemslist.cpp | 9 +- .../skins/default/textures/textures.xml | 1 + .../toolbar_icons/wearable_favorites.png | Bin 0 -> 536 bytes .../xui/de/floater_fs_wearable_favorites.xml | 14 + .../xui/de/menu_fs_wearable_favorites.xml | 6 + .../skins/default/xui/de/menu_viewer.xml | 1 + .../newview/skins/default/xui/de/strings.xml | 6 + .../xui/en/floater_fs_wearable_favorites.xml | 92 +++++ .../xui/en/menu_fs_wearable_favorites.xml | 33 ++ .../skins/default/xui/en/menu_viewer.xml | 11 + .../newview/skins/default/xui/en/strings.xml | 2 + 21 files changed, 725 insertions(+), 7 deletions(-) create mode 100644 indra/newview/fsfloaterwearablefavorites.cpp create mode 100644 indra/newview/fsfloaterwearablefavorites.h create mode 100644 indra/newview/skins/default/textures/toolbar_icons/wearable_favorites.png create mode 100644 indra/newview/skins/default/xui/de/floater_fs_wearable_favorites.xml create mode 100644 indra/newview/skins/default/xui/de/menu_fs_wearable_favorites.xml create mode 100644 indra/newview/skins/default/xui/en/floater_fs_wearable_favorites.xml create mode 100644 indra/newview/skins/default/xui/en/menu_fs_wearable_favorites.xml diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 44fd5e6328..293235a629 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -166,6 +166,7 @@ set(viewer_SOURCE_FILES fsfloatervoicecontrols.cpp fsfloatervolumecontrols.cpp fsfloatervramusage.cpp + fsfloaterwearablefavorites.cpp fskeywords.cpp fslightshare.cpp fslslbridge.cpp @@ -914,6 +915,7 @@ set(viewer_HEADER_FILES fsfloatervoicecontrols.h fsfloatervolumecontrols.h fsfloatervramusage.h + fsfloaterwearablefavorites.h fsgridhandler.h fskeywords.h fslightshare.h diff --git a/indra/newview/app_settings/commands.xml b/indra/newview/app_settings/commands.xml index 64f2a4b2ba..b28baa26d7 100644 --- a/indra/newview/app_settings/commands.xml +++ b/indra/newview/app_settings/commands.xml @@ -598,4 +598,14 @@ is_running_function="Floater.IsOpen" is_running_parameters="fs_group_titles" /> + diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 8aaf19b270..deef3fbb9a 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -24522,6 +24522,17 @@ Change of this parameter will affect the layout of buttons in notification toast Value 1 + FSWearableFavoritesSortOrder + + Comment + The sort order for the wearable favorites item list + Persist + 1 + Type + U32 + Value + 3 + diff --git a/indra/newview/app_settings/settings_per_account.xml b/indra/newview/app_settings/settings_per_account.xml index 5dfe0e32c5..c725635830 100644 --- a/indra/newview/app_settings/settings_per_account.xml +++ b/indra/newview/app_settings/settings_per_account.xml @@ -734,7 +734,16 @@ Value 1 - + ProtectWearableFavoritesFolders + + Comment + Keep the Wearable Favorites folder in Inventory safe from manual changes. + Type + Boolean + Value + 1 + + FSKeywordOn Comment diff --git a/indra/newview/fsfloaterwearablefavorites.cpp b/indra/newview/fsfloaterwearablefavorites.cpp new file mode 100644 index 0000000000..74d01fb93a --- /dev/null +++ b/indra/newview/fsfloaterwearablefavorites.cpp @@ -0,0 +1,376 @@ +/** + * @file fsfloaterwearablefavorites.cpp + * @brief Class for the favorite wearables floater + * + * $LicenseInfo:firstyear=2018&license=viewerlgpl$ + * Phoenix Firestorm Viewer Source Code + * Copyright (c) 2018 Ansariel Hiller @ Second Life + * + * 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 + * + * The Phoenix Firestorm Project, Inc., 1831 Oakwood Drive, Fairmont, Minnesota 56031-3225 USA + * http://www.firestormviewer.org + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" + +#include "fsfloaterwearablefavorites.h" +#include "fscommon.h" +#include "llappearancemgr.h" +#include "llbutton.h" +#include "llfiltereditor.h" +#include "llinventoryfunctions.h" +#include "llinventoryobserver.h" +#include "llmenugl.h" +#include "llmenubutton.h" +#include "lltoggleablemenu.h" +#include "llviewercontrol.h" // for gSavedSettings +#include "llviewermenu.h" // for gMenuHolder +#include "rlvactions.h" +#include "rlvlocks.h" + +#define FS_WEARABLE_FAVORITES_FOLDER "#Wearable Favorites" + +static LLDefaultChildRegistry::Register r("fs_wearable_favorites_items_list"); + +FSWearableFavoritesItemsList::FSWearableFavoritesItemsList(const Params& p) +: LLWearableItemsList(p) +{ +} + +BOOL FSWearableFavoritesItemsList::handleDragAndDrop(S32 x, S32 y, MASK mask, + BOOL drop, + EDragAndDropType cargo_type, + void* cargo_data, + EAcceptance* accept, + std::string& tooltip_msg) +{ + // Scroll folder view if needed. Never accepts a drag or drop. + *accept = ACCEPT_NO; + autoScroll(x, y); + + if (cargo_type == DAD_BODYPART || cargo_type == DAD_CLOTHING || cargo_type == DAD_OBJECT) + { + if (drop) + { + LLInventoryItem* item = (LLInventoryItem*)cargo_data; + if (!mDADSignal.empty()) + { + mDADSignal(item->getUUID()); + } + } + else + { + *accept = ACCEPT_YES_SINGLE; + } + } + + return TRUE; +} + +LLUUID FSFloaterWearableFavorites::sFolderID = LLUUID(); + +FSFloaterWearableFavorites::FSFloaterWearableFavorites(const LLSD& key) + : LLFloater(key), + mItemsList(NULL), + mInitialized(false), + mDADCallbackConnection() +{ + mCategoriesObserver = new LLInventoryCategoriesObserver(); +} + +FSFloaterWearableFavorites::~FSFloaterWearableFavorites() +{ + if (gInventory.containsObserver(mCategoriesObserver)) + { + gInventory.removeObserver(mCategoriesObserver); + } + delete mCategoriesObserver; + + if (mDADCallbackConnection.connected()) + { + mDADCallbackConnection.disconnect(); + } + + if (mOptionsMenuHandle.get()) + { + mOptionsMenuHandle.get()->die(); + } +} + +//virtual +BOOL FSFloaterWearableFavorites::postBuild() +{ + mItemsList = getChild("favorites_list"); + mItemsList->setNoFilteredItemsMsg(getString("search_no_items")); + mItemsList->setDoubleClickCallback(boost::bind(&FSFloaterWearableFavorites::onDoubleClick, this)); + + mRemoveItemBtn = getChild("remove_btn"); + mRemoveItemBtn->setCommitCallback(boost::bind(&FSFloaterWearableFavorites::handleRemove, this)); + + mFilterEditor = getChild("wearable_filter_input"); + mFilterEditor->setCommitCallback(boost::bind(&FSFloaterWearableFavorites::onFilterEdit, this, _2)); + + // Create menus. + LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar; + LLUICtrl::EnableCallbackRegistry::ScopedRegistrar enable_registrar; + + registrar.add("FavWearables.Action", boost::bind(&FSFloaterWearableFavorites::onOptionsMenuItemClicked, this, _2)); + enable_registrar.add("FavWearables.CheckAction", boost::bind(&FSFloaterWearableFavorites::onOptionsMenuItemChecked, this, _2)); + + mOptionsButton = getChild("options_btn"); + + LLToggleableMenu* options_menu = LLUICtrlFactory::getInstance()->createFromFile("menu_fs_wearable_favorites.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); + if (options_menu) + { + mOptionsMenuHandle = options_menu->getHandle(); + mOptionsButton->setMenu(options_menu, LLMenuButton::MP_BOTTOM_LEFT); + } + + return TRUE; +} + +//virtual +void FSFloaterWearableFavorites::onOpen(const LLSD& /*info*/) +{ + if (!mInitialized) + { + if (!gInventory.isInventoryUsable()) + { + return; + } + + initCategory(); + + LLViewerInventoryCategory* category = gInventory.getCategory(sFolderID); + if (!category) + { + return; + } + + const LLUUID cof = gInventory.findCategoryUUIDForType(LLFolderType::FT_CURRENT_OUTFIT); + LLViewerInventoryCategory* category_cof = gInventory.getCategory(cof); + if (!category_cof) + { + return; + } + + gInventory.addObserver(mCategoriesObserver); + mCategoriesObserver->addCategory(sFolderID, boost::bind(&FSFloaterWearableFavorites::updateList, this, sFolderID)); + mCategoriesObserver->addCategory(cof, boost::bind(&FSFloaterWearableFavorites::updateList, this, sFolderID)); + category->fetch(); + + mItemsList->setSortOrder((LLWearableItemsList::ESortOrder)gSavedSettings.getU32("FSWearableFavoritesSortOrder")); + updateList(sFolderID); + mItemsList->setDADCallback(boost::bind(&FSFloaterWearableFavorites::onItemDAD, this, _1)); + + mInitialized = true; + } +} + +//virtual +void FSFloaterWearableFavorites::draw() +{ + LLFloater::draw(); + + mRemoveItemBtn->setEnabled(mItemsList->numSelected() > 0); +} + +//virtual +BOOL FSFloaterWearableFavorites::handleKeyHere(KEY key, MASK mask) +{ + if (FSCommon::isFilterEditorKeyCombo(key, mask)) + { + mFilterEditor->setFocus(TRUE); + return TRUE; + } + + return LLFloater::handleKeyHere(key, mask); +} + +void FSFloaterWearableFavorites::initCategory() +{ + LLUUID fs_favs_id; + + LLUUID fs_root_cat_id = gInventory.findCategoryByName(ROOT_FIRESTORM_FOLDER); + if (!fs_root_cat_id.isNull()) + { + LLInventoryModel::item_array_t* items; + LLInventoryModel::cat_array_t* cats; + gInventory.getDirectDescendentsOf(fs_root_cat_id, cats, items); + if (cats) + { + for (LLInventoryModel::cat_array_t::iterator it = cats->begin(); it != cats->end(); ++it) + { + if ((*it)->getName() == FS_WEARABLE_FAVORITES_FOLDER) + { + fs_favs_id = (*it)->getUUID(); + break; + } + } + } + } + else + { + fs_root_cat_id = gInventory.createNewCategory(gInventory.getRootFolderID(), LLFolderType::FT_NONE, ROOT_FIRESTORM_FOLDER); + } + + if (fs_favs_id.isNull()) + { + fs_favs_id = gInventory.createNewCategory(fs_root_cat_id, LLFolderType::FT_NONE, FS_WEARABLE_FAVORITES_FOLDER); + } + + sFolderID = fs_favs_id; +} + +//static +LLUUID FSFloaterWearableFavorites::getFavoritesFolder() +{ + if (sFolderID.notNull()) + { + return sFolderID; + } + + LLUUID fs_root_cat_id = gInventory.findCategoryByName(ROOT_FIRESTORM_FOLDER); + if (!fs_root_cat_id.isNull()) + { + LLInventoryModel::item_array_t* items; + LLInventoryModel::cat_array_t* cats; + gInventory.getDirectDescendentsOf(fs_root_cat_id, cats, items); + if (cats) + { + for (LLInventoryModel::cat_array_t::iterator it = cats->begin(); it != cats->end(); ++it) + { + if ((*it)->getName() == FS_WEARABLE_FAVORITES_FOLDER) + { + sFolderID = (*it)->getUUID(); + break; + } + } + } + } + + return sFolderID; +} + +void FSFloaterWearableFavorites::updateList(const LLUUID& folder_id) +{ + mItemsList->updateList(folder_id); + + if (gInventory.isCategoryComplete(folder_id)) + { + mItemsList->setNoItemsCommentText(getString("empty_list")); // Have to reset it here because LLWearableItemsList::updateList might override it + } +} + +void FSFloaterWearableFavorites::onItemDAD(const LLUUID& item_id) +{ + link_inventory_object(sFolderID, item_id, LLPointer(NULL)); +} + +void FSFloaterWearableFavorites::handleRemove() +{ + uuid_vec_t selected_item_ids; + mItemsList->getSelectedUUIDs(selected_item_ids); + + for (uuid_vec_t::iterator it = selected_item_ids.begin(); it != selected_item_ids.end(); ++it) + { + remove_inventory_item(*it, LLPointer(NULL)); + } +} + +void FSFloaterWearableFavorites::onFilterEdit(const std::string& search_string) +{ + mItemsList->setFilterSubString(search_string); + mItemsList->setNoItemsCommentText(getString("empty_list")); +} + +void FSFloaterWearableFavorites::onOptionsMenuItemClicked(const LLSD& userdata) +{ + const std::string action = userdata.asString(); + + if (action == "sort_by_name") + { + mItemsList->setSortOrder(LLWearableItemsList::E_SORT_BY_NAME); + gSavedSettings.setU32("FSWearableFavoritesSortOrder", LLWearableItemsList::E_SORT_BY_NAME); + } + else if (action == "sort_by_most_recent") + { + mItemsList->setSortOrder(LLWearableItemsList::E_SORT_BY_MOST_RECENT); + gSavedSettings.setU32("FSWearableFavoritesSortOrder", LLWearableItemsList::E_SORT_BY_MOST_RECENT); + } + else if (action == "sort_by_type_name") + { + mItemsList->setSortOrder(LLWearableItemsList::E_SORT_BY_TYPE_NAME); + gSavedSettings.setU32("FSWearableFavoritesSortOrder", LLWearableItemsList::E_SORT_BY_TYPE_NAME); + } +} + +bool FSFloaterWearableFavorites::onOptionsMenuItemChecked(const LLSD& userdata) +{ + const std::string action = userdata.asString(); + + if (action == "sort_by_name") + { + return mItemsList->getSortOrder() == LLWearableItemsList::E_SORT_BY_NAME; + } + else if (action == "sort_by_most_recent") + { + return mItemsList->getSortOrder() == LLWearableItemsList::E_SORT_BY_MOST_RECENT; + } + else if (action == "sort_by_type_name") + { + return mItemsList->getSortOrder() == LLWearableItemsList::E_SORT_BY_TYPE_NAME; + } + + return false; +} + +void FSFloaterWearableFavorites::onDoubleClick() +{ + LLUUID selected_item_id = mItemsList->getSelectedUUID(); + if (selected_item_id.notNull()) + { + uuid_vec_t ids; + ids.push_back(selected_item_id); + LLViewerInventoryItem* item = gInventory.getItem(selected_item_id); + + if (get_is_item_worn(selected_item_id)) + { + if ((item->getType() == LLAssetType::AT_CLOTHING && (!RlvActions::isRlvEnabled() || gRlvWearableLocks.canRemove(item))) || + (item->getType() == LLAssetType::AT_OBJECT) && (!RlvActions::isRlvEnabled() || gRlvAttachmentLocks.canDetach(item))) + { + LLAppearanceMgr::instance().removeItemsFromAvatar(ids); + } + } + else + { + if (item->getType() == LLAssetType::AT_BODYPART && (!RlvActions::isRlvEnabled() || (gRlvWearableLocks.canWear(item) & RLV_WEAR_REPLACE) == RLV_WEAR_REPLACE)) + { + wear_multiple(ids, true); + } + else if (item->getType() == LLAssetType::AT_CLOTHING && LLAppearanceMgr::instance().canAddWearables(ids) && (!RlvActions::isRlvEnabled() || (gRlvWearableLocks.canWear(item) & RLV_WEAR_ADD) == RLV_WEAR_ADD)) + { + wear_multiple(ids, false); + } + else if (item->getType() == LLAssetType::AT_OBJECT && LLAppearanceMgr::instance().canAddWearables(ids) && (!RlvActions::isRlvEnabled() || (gRlvAttachmentLocks.canAttach(item) & RLV_WEAR_ADD) == RLV_WEAR_ADD)) + { + wear_multiple(ids, false); + } + } + } +} + diff --git a/indra/newview/fsfloaterwearablefavorites.h b/indra/newview/fsfloaterwearablefavorites.h new file mode 100644 index 0000000000..40d6d41a22 --- /dev/null +++ b/indra/newview/fsfloaterwearablefavorites.h @@ -0,0 +1,110 @@ +/** + * @file fsfloaterwearablefavorites.h + * @brief Class for the favorite wearables floater + * + * $LicenseInfo:firstyear=2018&license=viewerlgpl$ + * Phoenix Firestorm Viewer Source Code + * Copyright (c) 2018 Ansariel Hiller @ Second Life + * + * 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 + * + * The Phoenix Firestorm Project, Inc., 1831 Oakwood Drive, Fairmont, Minnesota 56031-3225 USA + * http://www.firestormviewer.org + * $/LicenseInfo$ + */ + +#ifndef FS_FLOATERWEARABLEFAVORITES_H +#define FS_FLOATERWEARABLEFAVORITES_H + +#include "llfloater.h" +#include "llwearableitemslist.h" + +class LLButton; +class LLFilterEditor; +class LLMenuButton; +class LLInventoryCategoriesObserver; + +class FSWearableFavoritesItemsList : public LLWearableItemsList +{ +public: + struct Params : public LLInitParam::Block + { + Params() + {} + }; + + virtual ~FSWearableFavoritesItemsList() {} + + /* virtual */ BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, + EDragAndDropType cargo_type, + void* cargo_data, + EAcceptance* accept, + std::string& tooltip_msg); + + typedef boost::signals2::signal item_dad_callback_t; + boost::signals2::connection setDADCallback(const item_dad_callback_t::slot_type& cb) + { + return mDADSignal.connect(cb); + } + +protected: + friend class LLUICtrlFactory; + FSWearableFavoritesItemsList(const Params&); + + item_dad_callback_t mDADSignal; +}; + +class FSFloaterWearableFavorites : public LLFloater +{ +public: + FSFloaterWearableFavorites(const LLSD& key); + virtual ~FSFloaterWearableFavorites(); + + /*virtual*/ BOOL postBuild(); + /*virtual*/ void onOpen(const LLSD& info); + /*virtual*/ void draw(); + /*virtual*/ BOOL handleKeyHere(KEY key, MASK mask); + /*virtual*/ bool hasAccelerators() const { return true; } + + static LLUUID getFavoritesFolder(); + +private: + void initCategory(); + void updateList(const LLUUID& folder_id); + + void onItemDAD(const LLUUID& item_id); + void handleRemove(); + void onFilterEdit(const std::string& search_string); + void onDoubleClick(); + + void onOptionsMenuItemClicked(const LLSD& userdata); + bool onOptionsMenuItemChecked(const LLSD& userdata); + + bool mInitialized; + + boost::signals2::connection mDADCallbackConnection; + + LLInventoryCategoriesObserver* mCategoriesObserver; + + FSWearableFavoritesItemsList* mItemsList; + LLButton* mRemoveItemBtn; + LLFilterEditor* mFilterEditor; + LLMenuButton* mOptionsButton; + LLHandle mOptionsMenuHandle; + + static LLUUID sFolderID; +}; + +#endif // FS_FLOATERWEARABLEFAVORITES_H diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index 1b626a62c2..4be1780b27 100644 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -99,6 +99,7 @@ #endif // #include "fsfloaterplacedetails.h" +#include "fsfloaterwearablefavorites.h" #include "llviewerattachmenu.h" #include "llresmgr.h" @@ -1374,6 +1375,13 @@ BOOL LLInvFVBridge::isProtectedFolder(bool ignore_setting /*= false*/) const return TRUE; } + if ((mUUID == FSFloaterWearableFavorites::getFavoritesFolder() + || model->isObjectDescendentOf(mUUID, FSFloaterWearableFavorites::getFavoritesFolder())) + && gSavedPerAccountSettings.getBOOL("ProtectWearableFavoritesFolders")) + { + return TRUE; + } + return FALSE; } // @@ -5653,9 +5661,11 @@ bool LLFolderBridge::isProtected() const { static LLCachedControl protectAOFolders(gSavedPerAccountSettings, "ProtectAOFolders"); static LLCachedControl protectBridgeFolder(gSavedPerAccountSettings, "ProtectBridgeFolder"); + static LLCachedControl WearableFavoritesprotectBridgeFolder(gSavedPerAccountSettings, "ProtectWearableFavoritesFolders"); return ((mUUID == AOEngine::instance().getAOFolder() && protectAOFolders) || - (mUUID == FSLSLBridge::instance().getBridgeFolder() && protectBridgeFolder)); + (mUUID == FSLSLBridge::instance().getBridgeFolder() && protectBridgeFolder) || + (mUUID == FSFloaterWearableFavorites::getFavoritesFolder() && WearableFavoritesprotectBridgeFolder)); } // diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp index 9f4b948324..c0d305c281 100644 --- a/indra/newview/llinventoryfunctions.cpp +++ b/indra/newview/llinventoryfunctions.cpp @@ -94,6 +94,7 @@ // Firestorm includes #include "aoengine.h" +#include "fsfloaterwearablefavorites.h" #include "fslslbridge.h" BOOL LLInventoryState::sWearNewClothing = FALSE; @@ -640,6 +641,9 @@ BOOL get_is_item_removable(const LLInventoryModel* model, const LLUUID& id) || (model->isObjectDescendentOf(id, FSLSLBridge::instance().getBridgeFolder()) && gSavedPerAccountSettings.getBOOL("ProtectBridgeFolder")) + || + (model->isObjectDescendentOf(id, FSFloaterWearableFavorites::getFavoritesFolder()) + && gSavedPerAccountSettings.getBOOL("ProtectWearableFavoritesFolders")) ) { return FALSE; @@ -707,6 +711,9 @@ BOOL get_is_category_removable(const LLInventoryModel* model, const LLUUID& id) || ((id == FSLSLBridge::instance().getBridgeFolder() || model->isObjectDescendentOf(id, FSLSLBridge::instance().getBridgeFolder())) && gSavedPerAccountSettings.getBOOL("ProtectBridgeFolder")) + || + ((id == FSFloaterWearableFavorites::getFavoritesFolder() || model->isObjectDescendentOf(id, FSFloaterWearableFavorites::getFavoritesFolder())) + && gSavedPerAccountSettings.getBOOL("ProtectWearableFavoritesFolders")) ) { return FALSE; @@ -762,6 +769,9 @@ BOOL get_is_category_renameable(const LLInventoryModel* model, const LLUUID& id) || ((id == FSLSLBridge::instance().getBridgeFolder() || model->isObjectDescendentOf(id, FSLSLBridge::instance().getBridgeFolder())) && gSavedPerAccountSettings.getBOOL("ProtectBridgeFolder")) + || + ((id == FSFloaterWearableFavorites::getFavoritesFolder() || model->isObjectDescendentOf(id, FSFloaterWearableFavorites::getFavoritesFolder())) + && gSavedPerAccountSettings.getBOOL("ProtectWearableFavoritesFolders")) ) { return FALSE; diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp index bd1e2cd88b..4edb583d8a 100644 --- a/indra/newview/llinventorymodel.cpp +++ b/indra/newview/llinventorymodel.cpp @@ -64,11 +64,11 @@ #include "rlvhandler.h" #include "rlvlocks.h" // [/RLVa:KB] -//-TT Patch: ReplaceWornItemsOnly +// Patch: ReplaceWornItemsOnly #include "llviewerobjectlist.h" #include "llviewerobject.h" #include "llgesturemgr.h" -//-TT +// //#define DIFF_INVENTORY_FILES #ifdef DIFF_INVENTORY_FILES @@ -76,6 +76,7 @@ #endif #include "aoengine.h" +#include "fsfloaterwearablefavorites.h" #include "fslslbridge.h" #ifdef OPENSIM #include "llviewernetwork.h" @@ -1310,7 +1311,9 @@ void LLInventoryModel::changeItemParent(LLViewerInventoryItem* item, if ((isObjectDescendentOf(item->getUUID(), AOEngine::instance().getAOFolder()) && gSavedPerAccountSettings.getBOOL("ProtectAOFolders")) || (isObjectDescendentOf(item->getUUID(), FSLSLBridge::instance().getBridgeFolder()) - && gSavedPerAccountSettings.getBOOL("ProtectBridgeFolder"))) + && gSavedPerAccountSettings.getBOOL("ProtectBridgeFolder")) || + (isObjectDescendentOf(item->getUUID(), FSFloaterWearableFavorites::getFavoritesFolder()) + && gSavedPerAccountSettings.getBOOL("ProtectWearableFavoritesFolders"))) { LL_INFOS("Inventory") << "Cannot move item because it is descendent of a protected folder" << LL_ENDL; return; @@ -1352,7 +1355,9 @@ void LLInventoryModel::changeCategoryParent(LLViewerInventoryCategory* cat, if ((isObjectDescendentOf(cat->getUUID(), AOEngine::instance().getAOFolder()) && gSavedPerAccountSettings.getBOOL("ProtectAOFolders")) || (isObjectDescendentOf(cat->getUUID(), FSLSLBridge::instance().getBridgeFolder()) - && gSavedPerAccountSettings.getBOOL("ProtectBridgeFolder"))) + && gSavedPerAccountSettings.getBOOL("ProtectBridgeFolder")) || + (isObjectDescendentOf(cat->getUUID(), FSFloaterWearableFavorites::getFavoritesFolder()) + && gSavedPerAccountSettings.getBOOL("ProtectWearableFavoritesFolders"))) { LL_INFOS("Inventory") << "Cannot move category because it is descendent of a protected folder" << LL_ENDL; return; diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp index 7da87f08a4..89625cf36c 100644 --- a/indra/newview/llviewerfloaterreg.cpp +++ b/indra/newview/llviewerfloaterreg.cpp @@ -194,6 +194,7 @@ #include "fsfloatervoicecontrols.h" #include "fsfloatervolumecontrols.h" #include "fsfloatervramusage.h" +#include "fsfloaterwearablefavorites.h" #include "fsmoneytracker.h" #include "fspanelclassified.h" #include "lggbeamcolormapfloater.h" @@ -466,6 +467,7 @@ void LLViewerFloaterReg::registerFloaters() LLFloaterReg::add("fs_teleporthistory", "floater_fs_teleporthistory.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); LLFloaterReg::add("fs_voice_controls", "floater_fs_voice_controls.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); LLFloaterReg::add("fs_volume_controls", "floater_fs_volume_controls.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); + LLFloaterReg::add("fs_wearable_favorites", "floater_fs_wearable_favorites.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); LLFloaterReg::add("imcontacts", "floater_fs_contacts.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); LLFloaterReg::add("lgg_beamcolormap", "floater_beamcolor.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); LLFloaterReg::add("lgg_beamshape", "floater_beamshape.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); diff --git a/indra/newview/llwearableitemslist.cpp b/indra/newview/llwearableitemslist.cpp index 09bb908b0b..d74bd33e25 100644 --- a/indra/newview/llwearableitemslist.cpp +++ b/indra/newview/llwearableitemslist.cpp @@ -950,7 +950,14 @@ void LLWearableItemsList::ContextMenu::updateItemsVisibility(LLContextMenu* menu // [/RLVa:KB] } // for - bool standalone = mParent ? mParent->isStandalone() : false; + // Standalone check doesn't make sense here as the context + // menu is only shown if standalone is true. If not, this + // method isn't called at all and it is assumed you provide + // your own right-click handler (LLWearableItemsList::ContextMenu + // is only used in LLWearableItemsList::onRightClick handler + // method which in return is only set as event handler if + // standalone is true). + bool standalone = /*mParent ? mParent->isStandalone() :*/ false; bool wear_add_visible = mask & (MASK_CLOTHING|MASK_ATTACHMENT) && n_worn == 0 && can_be_worn && (n_already_worn != 0 || mask & MASK_ATTACHMENT); // *TODO: eliminate multiple traversals over the menu items diff --git a/indra/newview/skins/default/textures/textures.xml b/indra/newview/skins/default/textures/textures.xml index b1091b1626..15fdb5b2fd 100644 --- a/indra/newview/skins/default/textures/textures.xml +++ b/indra/newview/skins/default/textures/textures.xml @@ -793,6 +793,7 @@ with the same filename but different name + diff --git a/indra/newview/skins/default/textures/toolbar_icons/wearable_favorites.png b/indra/newview/skins/default/textures/toolbar_icons/wearable_favorites.png new file mode 100644 index 0000000000000000000000000000000000000000..5e73f9a046a0eb572efc50374a6e5ea69dd555e8 GIT binary patch literal 536 zcmV+z0_XjSP)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D02y>eSaefwW^{L9 za%BK;VQFr3E^cLXAT%y8E-^XO*0N*(00D?eL_t(IPpy+XP6AOBhKbQc5(^6(ODj7I zd)QNFrUvq;y6z9b~Z3!7@9_-VOp(LYKfOMbm-}$-)=OU&CX<>M5s5LUax1g zddjL#9UXf5>_$qYBuTQrSS$+i-$gta49qIzsiQ+L|LbT3OC&gwy%GLoGBNsE7Gm<$ zGhN!_9F%b(UUdgXcaYu*mY952w|eIwHRW}Y*Yf*WBTv9j7Wb*6lfQnDI26x + + + Kleidung oder Objekt hier hinziehen, um zur Liste hinzuzufügen. + + + Keine treffenden Objekte gefunden. + + + + +