summaryrefslogtreecommitdiff
path: root/indra
diff options
context:
space:
mode:
authorMnikolenko Productengine <mnikolenko@productengine.com>2022-07-04 20:25:18 +0300
committerMnikolenko Productengine <mnikolenko@productengine.com>2022-07-04 20:25:18 +0300
commited9dbabb5e6e5f48492dc650ec2fd82317008b6f (patch)
tree825e800a9b8901961eeaf5f5da19f09f9f3daa77 /indra
parent0fbfa6e884e1892b6a7049d669782e3b3704cd2f (diff)
SL-17665 Add operation to create a subfolder from selected items in Inventory
Diffstat (limited to 'indra')
-rw-r--r--indra/newview/llinventorybridge.cpp22
-rw-r--r--indra/newview/llinventoryfunctions.cpp155
-rw-r--r--indra/newview/llinventoryfunctions.h4
-rw-r--r--indra/newview/lltoastalertpanel.cpp2
-rw-r--r--indra/newview/skins/default/xui/en/menu_inventory.xml19
-rw-r--r--indra/newview/skins/default/xui/en/notifications.xml34
6 files changed, 235 insertions, 1 deletions
diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp
index a0de3a2af1..884007d2a6 100644
--- a/indra/newview/llinventorybridge.cpp
+++ b/indra/newview/llinventorybridge.cpp
@@ -792,6 +792,19 @@ void LLInvFVBridge::getClipboardEntries(bool show_asset_id,
disabled_items.push_back(std::string("Copy"));
}
+ if (isAgentInventory())
+ {
+ items.push_back(std::string("New folder from selected"));
+ items.push_back(std::string("Subfolder Separator"));
+ std::set<LLUUID> selected_uuid_set = LLAvatarActions::getInventorySelectedUUIDs();
+ uuid_vec_t ids;
+ std::copy(selected_uuid_set.begin(), selected_uuid_set.end(), std::back_inserter(ids));
+ if (!is_only_items_selected(ids) && !is_only_cats_selected(ids))
+ {
+ disabled_items.push_back(std::string("New folder from selected"));
+ }
+ }
+
if (obj->getIsLinkType())
{
items.push_back(std::string("Find Original"));
@@ -4266,7 +4279,16 @@ void LLFolderBridge::buildContextMenuFolderOptions(U32 flags, menuentry_vec_t&
items.push_back(std::string("Conference Chat Folder"));
items.push_back(std::string("IM All Contacts In Folder"));
}
+
+ if (((flags & ITEM_IN_MULTI_SELECTION) == 0) && hasChildren())
+ {
+ items.push_back(std::string("Ungroup folder items"));
+ }
}
+ else
+ {
+ disabled_items.push_back(std::string("New folder from selected"));
+ }
#ifndef LL_RELEASE_FOR_DOWNLOAD
if (LLFolderType::lookupIsProtectedType(type) && is_agent_inventory)
diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp
index d239b23e83..d8a4340254 100644
--- a/indra/newview/llinventoryfunctions.cpp
+++ b/indra/newview/llinventoryfunctions.cpp
@@ -1868,6 +1868,86 @@ void change_item_parent(const LLUUID& item_id, const LLUUID& new_parent_id)
}
}
+void move_items_to_folder(const LLUUID& new_cat_uuid, const uuid_vec_t& selected_uuids)
+{
+ for (uuid_vec_t::const_iterator it = selected_uuids.begin(); it != selected_uuids.end(); ++it)
+ {
+ LLInventoryItem* inv_item = gInventory.getItem(*it);
+ if (inv_item)
+ {
+ change_item_parent(*it, new_cat_uuid);
+ }
+ else
+ {
+ LLInventoryCategory* inv_cat = gInventory.getCategory(*it);
+ if (inv_cat)
+ {
+ gInventory.changeCategoryParent((LLViewerInventoryCategory*)inv_cat, new_cat_uuid, false);
+ }
+ }
+ }
+
+ LLFloater* floater_inventory = LLFloaterReg::getInstance("inventory");
+ if (!floater_inventory)
+ {
+ LL_WARNS() << "Could not find My Inventory floater" << LL_ENDL;
+ return;
+ }
+ LLSidepanelInventory *sidepanel_inventory = LLFloaterSidePanelContainer::getPanel<LLSidepanelInventory>("inventory");
+ if (sidepanel_inventory)
+ {
+ if (sidepanel_inventory->getActivePanel())
+ {
+ sidepanel_inventory->getActivePanel()->setSelection(new_cat_uuid, TAKE_FOCUS_YES);
+ LLFolderViewItem* fv_folder = sidepanel_inventory->getActivePanel()->getItemByID(new_cat_uuid);
+ if (fv_folder)
+ {
+ fv_folder->setOpen(TRUE);
+ }
+ }
+ }
+}
+
+bool is_only_cats_selected(const uuid_vec_t& selected_uuids)
+{
+ for (uuid_vec_t::const_iterator it = selected_uuids.begin(); it != selected_uuids.end(); ++it)
+ {
+ LLInventoryCategory* inv_cat = gInventory.getCategory(*it);
+ if (!inv_cat)
+ {
+ return false;
+ }
+ }
+ return true;
+}
+
+bool is_only_items_selected(const uuid_vec_t& selected_uuids)
+{
+ for (uuid_vec_t::const_iterator it = selected_uuids.begin(); it != selected_uuids.end(); ++it)
+ {
+ LLViewerInventoryItem* inv_item = gInventory.getItem(*it);
+ if (!inv_item)
+ {
+ return false;
+ }
+ }
+ return true;
+}
+
+
+void move_items_to_new_subfolder(const uuid_vec_t& selected_uuids, const std::string& folder_name)
+{
+ LLInventoryObject* first_item = gInventory.getObject(*selected_uuids.begin());
+ if (!first_item)
+ {
+ return;
+ }
+
+ inventory_func_type func = boost::bind(&move_items_to_folder, _1, selected_uuids);
+ gInventory.createNewCategory(first_item->getParentUUID(), LLFolderType::FT_NONE, folder_name, func);
+
+}
+
///----------------------------------------------------------------------------
/// LLInventoryCollectFunctor implementations
///----------------------------------------------------------------------------
@@ -2522,6 +2602,81 @@ void LLInventoryAction::doToSelected(LLInventoryModel* model, LLFolderView* root
{
(new LLDirPickerThread(boost::bind(&LLInventoryAction::saveMultipleTextures, _1, selected_items, model), std::string()))->getFile();
}
+ else if ("new_folder_from_selected" == action)
+ {
+
+ LLInventoryObject* first_item = gInventory.getObject(*ids.begin());
+ if (!first_item)
+ {
+ return;
+ }
+ const LLUUID& parent_uuid = first_item->getParentUUID();
+ for (uuid_vec_t::const_iterator it = ids.begin(); it != ids.end(); ++it)
+ {
+ LLInventoryObject *item = gInventory.getObject(*it);
+ if (!item || item->getParentUUID() != parent_uuid)
+ {
+ LLNotificationsUtil::add("SameFolderRequired");
+ return;
+ }
+ }
+
+ LLSD args;
+ args["DESC"] = LLTrans::getString("New Folder");
+
+ LLNotificationsUtil::add("CreateSubfolder", args, LLSD(),
+ [ids](const LLSD& notification, const LLSD& response)
+ {
+ S32 opt = LLNotificationsUtil::getSelectedOption(notification, response);
+ if (opt == 0)
+ {
+ std::string settings_name = response["message"].asString();
+
+ LLInventoryObject::correctInventoryName(settings_name);
+ if (settings_name.empty())
+ {
+ settings_name = LLTrans::getString("New Folder");
+ }
+ move_items_to_new_subfolder(ids, settings_name);
+ }
+ });
+ }
+ else if ("ungroup_folder_items" == action)
+ {
+ if (selected_uuid_set.size() == 1)
+ {
+ LLInventoryCategory* inv_cat = gInventory.getCategory(*ids.begin());
+ if (!inv_cat)
+ {
+ return;
+ }
+ const LLUUID &new_cat_uuid = inv_cat->getParentUUID();
+ LLInventoryModel::cat_array_t* cat_array;
+ LLInventoryModel::item_array_t* item_array;
+ gInventory.getDirectDescendentsOf(inv_cat->getUUID(), cat_array, item_array);
+ LLInventoryModel::cat_array_t cats = *cat_array;
+ LLInventoryModel::item_array_t items = *item_array;
+
+ for (LLInventoryModel::cat_array_t::const_iterator cat_iter = cats.begin(); cat_iter != cats.end(); ++cat_iter)
+ {
+ LLViewerInventoryCategory* cat = *cat_iter;
+ if (cat)
+ {
+ gInventory.changeCategoryParent(cat, new_cat_uuid, false);
+ }
+ }
+ for (LLInventoryModel::item_array_t::const_iterator item_iter = items.begin(); item_iter != items.end(); ++item_iter)
+ {
+ LLViewerInventoryItem* item = *item_iter;
+ if(item)
+ {
+ gInventory.changeItemParent(item, new_cat_uuid, false);
+ }
+ }
+ gInventory.removeCategory(inv_cat->getUUID());
+ gInventory.notifyObservers();
+ }
+ }
else
{
std::set<LLFolderViewItem*>::iterator set_iter;
diff --git a/indra/newview/llinventoryfunctions.h b/indra/newview/llinventoryfunctions.h
index 8915bfa1e0..ba9f157e47 100644
--- a/indra/newview/llinventoryfunctions.h
+++ b/indra/newview/llinventoryfunctions.h
@@ -93,6 +93,10 @@ LLUUID nested_parent_id(LLUUID cur_uuid, S32 depth);
S32 compute_stock_count(LLUUID cat_uuid, bool force_count = false);
void change_item_parent(const LLUUID& item_id, const LLUUID& new_parent_id);
+void move_items_to_new_subfolder(const uuid_vec_t& selected_uuids, const std::string& folder_name);
+void move_items_to_folder(const LLUUID& new_cat_uuid, const uuid_vec_t& selected_uuids);
+bool is_only_cats_selected(const uuid_vec_t& selected_uuids);
+bool is_only_items_selected(const uuid_vec_t& selected_uuids);
/** Miscellaneous global functions
** **
diff --git a/indra/newview/lltoastalertpanel.cpp b/indra/newview/lltoastalertpanel.cpp
index 8baad30e8f..692e8d91a9 100644
--- a/indra/newview/lltoastalertpanel.cpp
+++ b/indra/newview/lltoastalertpanel.cpp
@@ -291,7 +291,7 @@ LLToastAlertPanel::LLToastAlertPanel( LLNotificationPtr notification, bool modal
mLineEditor->setText(edit_text_contents);
std::string notif_name = mNotification->getName();
- if (("SaveOutfitAs" == notif_name) || ("SaveSettingAs" == notif_name) || ("CreateLandmarkFolder" == notif_name))
+ if (("SaveOutfitAs" == notif_name) || ("SaveSettingAs" == notif_name) || ("CreateLandmarkFolder" == notif_name) || ("CreateSubfolder" == notif_name))
{
mLineEditor->setPrevalidate(&LLTextValidate::validateASCII);
}
diff --git a/indra/newview/skins/default/xui/en/menu_inventory.xml b/indra/newview/skins/default/xui/en/menu_inventory.xml
index 78ca170813..aa3d0ae071 100644
--- a/indra/newview/skins/default/xui/en/menu_inventory.xml
+++ b/indra/newview/skins/default/xui/en/menu_inventory.xml
@@ -912,6 +912,25 @@
function="Inventory.DoToSelected"
parameter="apply_settings_parcel" />
</menu_item_call>
+ <menu_item_separator
+ layout="topleft"
+ name="Subfolder Separator" />
+ <menu_item_call
+ label="Create folder from selected"
+ layout="topleft"
+ name="New folder from selected">
+ <menu_item_call.on_click
+ function="Inventory.DoToSelected"
+ parameter="new_folder_from_selected" />
+ </menu_item_call>
+ <menu_item_call
+ label="Ungroup folder items"
+ layout="topleft"
+ name="Ungroup folder items">
+ <menu_item_call.on_click
+ function="Inventory.DoToSelected"
+ parameter="ungroup_folder_items" />
+ </menu_item_call>
<menu_item_separator
layout="topleft"
name="Marketplace Separator" />
diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml
index 6a9039b198..0a3826123c 100644
--- a/indra/newview/skins/default/xui/en/notifications.xml
+++ b/indra/newview/skins/default/xui/en/notifications.xml
@@ -11842,4 +11842,38 @@ Unpacking: [UNPACK_TIME]s [USIZE]KB
</form>
</notification>
+ <notification
+ icon="alertmodal.tga"
+ label="Save Outfit"
+ name="CreateSubfolder"
+ type="alertmodal">
+ <unique/>
+ Name the new folder:
+ <tag>confirm</tag>
+ <form name="form">
+ <input name="message" type="text">
+ [DESC]
+ </input>
+ <button
+ default="true"
+ index="0"
+ name="OK"
+ text="OK"/>
+ <button
+ index="1"
+ name="Cancel"
+ text="Cancel"/>
+ </form>
+ </notification>
+ <notification
+ icon="alertmodal.tga"
+ name="SameFolderRequired"
+ type="alert">
+ Selected items must be in the same folder.
+ <tag>fail</tag>
+ <usetemplate
+ name="okbutton"
+ yestext="OK"/>
+ </notification>
+
</notifications>