SL-17665 Add operation to create a subfolder from selected items in Inventory
parent
0fbfa6e884
commit
ed9dbabb5e
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
** **
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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" />
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
Loading…
Reference in New Issue