SL-19379 WIP add basic context menu
parent
11b2f138ce
commit
e5b8b799cc
|
|
@ -381,6 +381,7 @@ set(viewer_SOURCE_FILES
|
|||
llinventoryfilter.cpp
|
||||
llinventoryfunctions.cpp
|
||||
llinventorygallery.cpp
|
||||
llinventorygallerymenu.cpp
|
||||
llinventoryicon.cpp
|
||||
llinventoryitemslist.cpp
|
||||
llinventorylistitem.cpp
|
||||
|
|
@ -1025,6 +1026,7 @@ set(viewer_HEADER_FILES
|
|||
llinventoryfilter.h
|
||||
llinventoryfunctions.h
|
||||
llinventorygallery.h
|
||||
llinventorygallerymenu.h
|
||||
llinventoryicon.h
|
||||
llinventoryitemslist.h
|
||||
llinventorylistitem.h
|
||||
|
|
|
|||
|
|
@ -730,6 +730,37 @@ namespace action_give_inventory
|
|||
/**
|
||||
* Checks My Inventory visibility.
|
||||
*/
|
||||
static bool is_give_inventory_acceptable_ids(const std::set<LLUUID> inventory_selected_uuids)
|
||||
{
|
||||
if (inventory_selected_uuids.empty()) return false; // nothing selected
|
||||
|
||||
bool acceptable = false;
|
||||
std::set<LLUUID>::const_iterator it = inventory_selected_uuids.begin();
|
||||
const std::set<LLUUID>::const_iterator it_end = inventory_selected_uuids.end();
|
||||
for (; it != it_end; ++it)
|
||||
{
|
||||
LLViewerInventoryCategory* inv_cat = gInventory.getCategory(*it);
|
||||
// any category can be offered.
|
||||
if (inv_cat)
|
||||
{
|
||||
acceptable = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
LLViewerInventoryItem* inv_item = gInventory.getItem(*it);
|
||||
// check if inventory item can be given
|
||||
if (LLGiveInventory::isInventoryGiveAcceptable(inv_item))
|
||||
{
|
||||
acceptable = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
// there are neither item nor category in inventory
|
||||
acceptable = false;
|
||||
break;
|
||||
}
|
||||
return acceptable;
|
||||
}
|
||||
|
||||
static bool is_give_inventory_acceptable(LLInventoryPanel* panel = NULL)
|
||||
{
|
||||
|
|
@ -737,32 +768,7 @@ namespace action_give_inventory
|
|||
const std::set<LLUUID> inventory_selected_uuids = LLAvatarActions::getInventorySelectedUUIDs(panel);
|
||||
if (inventory_selected_uuids.empty()) return false; // nothing selected
|
||||
|
||||
bool acceptable = false;
|
||||
std::set<LLUUID>::const_iterator it = inventory_selected_uuids.begin();
|
||||
const std::set<LLUUID>::const_iterator it_end = inventory_selected_uuids.end();
|
||||
for (; it != it_end; ++it)
|
||||
{
|
||||
LLViewerInventoryCategory* inv_cat = gInventory.getCategory(*it);
|
||||
// any category can be offered.
|
||||
if (inv_cat)
|
||||
{
|
||||
acceptable = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
LLViewerInventoryItem* inv_item = gInventory.getItem(*it);
|
||||
// check if inventory item can be given
|
||||
if (LLGiveInventory::isInventoryGiveAcceptable(inv_item))
|
||||
{
|
||||
acceptable = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
// there are neither item nor category in inventory
|
||||
acceptable = false;
|
||||
break;
|
||||
}
|
||||
return acceptable;
|
||||
return is_give_inventory_acceptable_ids(inventory_selected_uuids);
|
||||
}
|
||||
|
||||
static void build_items_string(const std::set<LLUUID>& inventory_selected_uuids , std::string& items_string)
|
||||
|
|
@ -890,46 +896,58 @@ namespace action_give_inventory
|
|||
* @param avatar_names - avatar names request to be sent.
|
||||
* @param avatar_uuids - avatar names request to be sent.
|
||||
*/
|
||||
static void give_inventory(const uuid_vec_t& avatar_uuids, const std::vector<LLAvatarName> avatar_names, LLInventoryPanel* panel = NULL)
|
||||
{
|
||||
llassert(avatar_names.size() == avatar_uuids.size());
|
||||
|
||||
const std::set<LLUUID> inventory_selected_uuids = LLAvatarActions::getInventorySelectedUUIDs(panel);
|
||||
if (inventory_selected_uuids.empty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
static void give_inventory_ids(const uuid_vec_t& avatar_uuids, const std::vector<LLAvatarName> avatar_names, const uuid_set_t inventory_selected_uuids)
|
||||
{
|
||||
llassert(avatar_names.size() == avatar_uuids.size());
|
||||
|
||||
std::string residents;
|
||||
LLAvatarActions::buildResidentsString(avatar_names, residents, true);
|
||||
if (inventory_selected_uuids.empty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
std::string items;
|
||||
build_items_string(inventory_selected_uuids, items);
|
||||
std::string residents;
|
||||
LLAvatarActions::buildResidentsString(avatar_names, residents, true);
|
||||
|
||||
int folders_count = 0;
|
||||
std::set<LLUUID>::const_iterator it = inventory_selected_uuids.begin();
|
||||
std::string items;
|
||||
build_items_string(inventory_selected_uuids, items);
|
||||
|
||||
//traverse through selected inventory items and count folders among them
|
||||
for ( ; it != inventory_selected_uuids.end() && folders_count <=1 ; ++it)
|
||||
{
|
||||
LLViewerInventoryCategory* inv_cat = gInventory.getCategory(*it);
|
||||
if (NULL != inv_cat)
|
||||
{
|
||||
folders_count++;
|
||||
}
|
||||
}
|
||||
int folders_count = 0;
|
||||
std::set<LLUUID>::const_iterator it = inventory_selected_uuids.begin();
|
||||
|
||||
// EXP-1599
|
||||
// In case of sharing multiple folders, make the confirmation
|
||||
// dialog contain a warning that only one folder can be shared at a time.
|
||||
std::string notification = (folders_count > 1) ? "ShareFolderConfirmation" : "ShareItemsConfirmation";
|
||||
LLSD substitutions;
|
||||
substitutions["RESIDENTS"] = residents;
|
||||
substitutions["ITEMS"] = items;
|
||||
LLShareInfo::instance().mAvatarNames = avatar_names;
|
||||
LLShareInfo::instance().mAvatarUuids = avatar_uuids;
|
||||
LLNotificationsUtil::add(notification, substitutions, LLSD(), boost::bind(&give_inventory_cb, _1, _2, inventory_selected_uuids));
|
||||
}
|
||||
//traverse through selected inventory items and count folders among them
|
||||
for ( ; it != inventory_selected_uuids.end() && folders_count <=1 ; ++it)
|
||||
{
|
||||
LLViewerInventoryCategory* inv_cat = gInventory.getCategory(*it);
|
||||
if (NULL != inv_cat)
|
||||
{
|
||||
folders_count++;
|
||||
}
|
||||
}
|
||||
|
||||
// EXP-1599
|
||||
// In case of sharing multiple folders, make the confirmation
|
||||
// dialog contain a warning that only one folder can be shared at a time.
|
||||
std::string notification = (folders_count > 1) ? "ShareFolderConfirmation" : "ShareItemsConfirmation";
|
||||
LLSD substitutions;
|
||||
substitutions["RESIDENTS"] = residents;
|
||||
substitutions["ITEMS"] = items;
|
||||
LLShareInfo::instance().mAvatarNames = avatar_names;
|
||||
LLShareInfo::instance().mAvatarUuids = avatar_uuids;
|
||||
LLNotificationsUtil::add(notification, substitutions, LLSD(), boost::bind(&give_inventory_cb, _1, _2, inventory_selected_uuids));
|
||||
}
|
||||
|
||||
static void give_inventory(const uuid_vec_t& avatar_uuids, const std::vector<LLAvatarName> avatar_names, LLInventoryPanel* panel = NULL)
|
||||
{
|
||||
llassert(avatar_names.size() == avatar_uuids.size());
|
||||
|
||||
const std::set<LLUUID> inventory_selected_uuids = LLAvatarActions::getInventorySelectedUUIDs(panel);
|
||||
if (inventory_selected_uuids.empty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
give_inventory_ids(avatar_uuids, avatar_names, inventory_selected_uuids);
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
|
|
@ -1037,6 +1055,28 @@ void LLAvatarActions::shareWithAvatars(LLView * panel)
|
|||
LLNotificationsUtil::add("ShareNotification");
|
||||
}
|
||||
|
||||
//static
|
||||
void LLAvatarActions::shareWithAvatars(const uuid_set_t inventory_selected_uuids, LLFloater* root_floater)
|
||||
{
|
||||
using namespace action_give_inventory;
|
||||
|
||||
LLFloaterAvatarPicker* picker =
|
||||
LLFloaterAvatarPicker::show(boost::bind(give_inventory_ids, _1, _2, inventory_selected_uuids), TRUE, FALSE, FALSE, root_floater->getName());
|
||||
if (!picker)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
picker->setOkBtnEnableCb(boost::bind(is_give_inventory_acceptable_ids, inventory_selected_uuids));
|
||||
picker->openFriendsTab();
|
||||
|
||||
if (root_floater)
|
||||
{
|
||||
root_floater->addDependentFloater(picker);
|
||||
}
|
||||
LLNotificationsUtil::add("ShareNotification");
|
||||
}
|
||||
|
||||
// static
|
||||
bool LLAvatarActions::canShareSelectedItems(LLInventoryPanel* inv_panel /* = NULL*/)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -133,6 +133,7 @@ public:
|
|||
* Share items with the picked avatars.
|
||||
*/
|
||||
static void shareWithAvatars(LLView * panel);
|
||||
static void shareWithAvatars(const uuid_set_t inventory_selected_uuids, LLFloater* root_floater);
|
||||
|
||||
/**
|
||||
* Block/unblock the avatar by id.
|
||||
|
|
|
|||
|
|
@ -2125,6 +2125,45 @@ std::string get_localized_folder_name(LLUUID cat_uuid)
|
|||
|
||||
return localized_root_name;
|
||||
}
|
||||
|
||||
void new_folder_window(const LLUUID& folder_id)
|
||||
{
|
||||
LLPanelMainInventory::newFolderWindow(folder_id);
|
||||
}
|
||||
|
||||
void ungroup_folder_items(const LLUUID& folder_id)
|
||||
{
|
||||
LLInventoryCategory* inv_cat = gInventory.getCategory(folder_id);
|
||||
if (!inv_cat || LLFolderType::lookupIsProtectedType(inv_cat->getPreferredType()))
|
||||
{
|
||||
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();
|
||||
}
|
||||
///----------------------------------------------------------------------------
|
||||
/// LLMarketplaceValidator implementations
|
||||
///----------------------------------------------------------------------------
|
||||
|
|
@ -2977,36 +3016,7 @@ void LLInventoryAction::doToSelected(LLInventoryModel* model, LLFolderView* root
|
|||
{
|
||||
if (selected_uuid_set.size() == 1)
|
||||
{
|
||||
LLInventoryCategory* inv_cat = gInventory.getCategory(*ids.begin());
|
||||
if (!inv_cat || LLFolderType::lookupIsProtectedType(inv_cat->getPreferredType()))
|
||||
{
|
||||
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();
|
||||
ungroup_folder_items(*ids.begin());
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
|
|||
|
|
@ -101,6 +101,8 @@ bool can_move_to_outfit(LLInventoryItem* inv_item, BOOL move_is_into_current_out
|
|||
bool can_move_to_landmarks(LLInventoryItem* inv_item);
|
||||
bool can_move_to_my_outfits(LLInventoryModel* model, LLInventoryCategory* inv_cat, U32 wear_limit);
|
||||
std::string get_localized_folder_name(LLUUID cat_uuid);
|
||||
void new_folder_window(const LLUUID& folder_id);
|
||||
void ungroup_folder_items(const LLUUID& folder_id);
|
||||
|
||||
/** Miscellaneous global functions
|
||||
** **
|
||||
|
|
|
|||
|
|
@ -27,8 +27,8 @@
|
|||
#include "llviewerprecompiledheaders.h"
|
||||
|
||||
#include "llinventorygallery.h"
|
||||
#include "llinventorygallerymenu.h"
|
||||
|
||||
#include "llaccordionctrltab.h"
|
||||
#include "llcommonutils.h"
|
||||
#include "lliconctrl.h"
|
||||
#include "llinventorybridge.h"
|
||||
|
|
@ -115,12 +115,14 @@ BOOL LLInventoryGallery::postBuild()
|
|||
LLPanel::Params params = LLPanel::getDefaultParams();
|
||||
mGalleryPanel = LLUICtrlFactory::create<LLPanel>(params);
|
||||
mMessageTextBox = getChild<LLTextBox>("empty_txt");
|
||||
|
||||
mInventoryGalleryMenu = new LLInventoryGalleryContextMenu(this);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
LLInventoryGallery::~LLInventoryGallery()
|
||||
{
|
||||
delete mInventoryGalleryMenu;
|
||||
|
||||
while (!mUnusedRowPanels.empty())
|
||||
{
|
||||
LLPanel* panelp = mUnusedRowPanels.back();
|
||||
|
|
@ -600,7 +602,7 @@ void LLInventoryGallery::updateAddedItem(LLUUID item_id)
|
|||
|
||||
LLInventoryGalleryItem* item = buildGalleryItem(name, item_id, obj->getType(), thumbnail_id, obj->getIsLinkType());
|
||||
mItemMap.insert(LLInventoryGallery::gallery_item_map_t::value_type(item_id, item));
|
||||
|
||||
item->setRightMouseDownCallback(boost::bind(&LLInventoryGallery::showContextMenu, this, _1, _2, _3, item_id));
|
||||
item->setFocusReceivedCallback(boost::bind(&LLInventoryGallery::onChangeItemSelection, this, item_id));
|
||||
if (mGalleryCreated)
|
||||
{
|
||||
|
|
@ -671,6 +673,16 @@ void LLInventoryGallery::updateItemThumbnail(LLUUID item_id)
|
|||
}
|
||||
}
|
||||
|
||||
void LLInventoryGallery::showContextMenu(LLUICtrl* ctrl, S32 x, S32 y, const LLUUID& item_id)
|
||||
{
|
||||
if (mInventoryGalleryMenu && item_id.notNull())
|
||||
{
|
||||
uuid_vec_t selected_uuids;
|
||||
selected_uuids.push_back(item_id);
|
||||
mInventoryGalleryMenu->show(ctrl, selected_uuids, x, y);
|
||||
}
|
||||
}
|
||||
|
||||
void LLInventoryGallery::onChangeItemSelection(const LLUUID& category_id)
|
||||
{
|
||||
if (mSelectedItemID == category_id)
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@
|
|||
#ifndef LL_LLINVENTORYGALLERY_H
|
||||
#define LL_LLINVENTORYGALLERY_H
|
||||
|
||||
#include "lllistcontextmenu.h"
|
||||
#include "llpanel.h"
|
||||
#include "llinventorymodel.h"
|
||||
|
||||
|
|
@ -35,6 +36,8 @@ class LLInventoryGalleryItem;
|
|||
class LLScrollContainer;
|
||||
class LLTextBox;
|
||||
|
||||
class LLInventoryGalleryContextMenu;
|
||||
|
||||
class LLInventoryGallery : public LLPanel
|
||||
{
|
||||
public:
|
||||
|
|
@ -108,6 +111,7 @@ public:
|
|||
protected:
|
||||
|
||||
void onChangeItemSelection(const LLUUID& category_id);
|
||||
void showContextMenu(LLUICtrl* ctrl, S32 x, S32 y, const LLUUID& item_id);
|
||||
|
||||
void applyFilter(LLInventoryGalleryItem* item, const std::string& filter_substring);
|
||||
|
||||
|
|
@ -171,6 +175,7 @@ private:
|
|||
int mRowPanWidthFactor;
|
||||
int mGalleryWidthFactor;
|
||||
|
||||
LLInventoryGalleryContextMenu* mInventoryGalleryMenu;
|
||||
std::string mFilterSubString;
|
||||
|
||||
typedef std::map<LLUUID, LLInventoryGalleryItem*> gallery_item_map_t;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,616 @@
|
|||
/**
|
||||
* @file llinventorygallerymenu.cpp
|
||||
*
|
||||
* $LicenseInfo:firstyear=2023&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2023, 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 "llinventorygallery.h"
|
||||
#include "llinventorygallerymenu.h"
|
||||
|
||||
#include "llagent.h"
|
||||
#include "llappearancemgr.h"
|
||||
#include "llavataractions.h"
|
||||
#include "llclipboard.h"
|
||||
#include "llfloaterreg.h"
|
||||
#include "llgiveinventory.h"
|
||||
#include "llinventorybridge.h"
|
||||
#include "llinventoryfunctions.h"
|
||||
#include "llinventorymodel.h"
|
||||
#include "llmarketplacefunctions.h"
|
||||
#include "llmenugl.h"
|
||||
#include "llnotificationsutil.h"
|
||||
#include "llviewerfoldertype.h"
|
||||
#include "llviewerwindow.h"
|
||||
|
||||
LLContextMenu* LLInventoryGalleryContextMenu::createMenu()
|
||||
{
|
||||
LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
|
||||
//LLUICtrl::EnableCallbackRegistry::ScopedRegistrar enable_registrar;
|
||||
LLUUID selected_id = mUUIDs.front();
|
||||
|
||||
registrar.add("Inventory.DoToSelected", boost::bind(&LLInventoryGalleryContextMenu::doToSelected, this, _2, selected_id));
|
||||
registrar.add("Inventory.FileUploadLocation", boost::bind(&LLInventoryGalleryContextMenu::fileUploadLocation, this, _2, selected_id));
|
||||
registrar.add("Inventory.EmptyTrash", boost::bind(&LLInventoryModel::emptyFolderType, &gInventory, "ConfirmEmptyTrash", LLFolderType::FT_TRASH));
|
||||
registrar.add("Inventory.EmptyLostAndFound", boost::bind(&LLInventoryModel::emptyFolderType, &gInventory, "ConfirmEmptyLostAndFound", LLFolderType::FT_LOST_AND_FOUND));
|
||||
|
||||
std::set<LLUUID> uuids{selected_id};
|
||||
registrar.add("Inventory.Share", boost::bind(&LLAvatarActions::shareWithAvatars, uuids, gFloaterView->getParentFloater(mGallery)));
|
||||
|
||||
LLContextMenu* menu = createFromFile("menu_gallery_inventory.xml");
|
||||
|
||||
updateMenuItemsVisibility(menu);
|
||||
|
||||
return menu;
|
||||
}
|
||||
|
||||
void LLInventoryGalleryContextMenu::doToSelected(const LLSD& userdata, const LLUUID& selected_id)
|
||||
{
|
||||
std::string action = userdata.asString();
|
||||
LLInventoryObject* obj = gInventory.getObject(selected_id);
|
||||
if(!obj) return;
|
||||
|
||||
bool is_folder = (obj->getType() == LLAssetType::AT_CATEGORY);
|
||||
|
||||
if ("open_selected_folder" == action)
|
||||
{
|
||||
mGallery->setRootFolder(selected_id);
|
||||
}
|
||||
else if ("open_in_new_window" == action)
|
||||
{
|
||||
new_folder_window(selected_id);
|
||||
}
|
||||
else if ("properties" == action)
|
||||
{
|
||||
show_item_profile(selected_id);
|
||||
}
|
||||
else if ("restore" == action)
|
||||
{
|
||||
LLViewerInventoryCategory* cat = gInventory.getCategory(selected_id);
|
||||
if(cat)
|
||||
{
|
||||
const LLUUID new_parent = gInventory.findCategoryUUIDForType(LLFolderType::assetTypeToFolderType(cat->getType()));
|
||||
// do not restamp children on restore
|
||||
gInventory.changeCategoryParent(cat, new_parent, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
LLViewerInventoryItem* item = gInventory.getItem(selected_id);
|
||||
if(item)
|
||||
{
|
||||
bool is_snapshot = (item->getInventoryType() == LLInventoryType::IT_SNAPSHOT);
|
||||
|
||||
const LLUUID new_parent = gInventory.findCategoryUUIDForType(is_snapshot? LLFolderType::FT_SNAPSHOT_CATEGORY : LLFolderType::assetTypeToFolderType(item->getType()));
|
||||
// do not restamp children on restore
|
||||
gInventory.changeItemParent(item, new_parent, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ("copy_uuid" == action)
|
||||
{
|
||||
LLViewerInventoryItem* item = gInventory.getItem(selected_id);
|
||||
if(item)
|
||||
{
|
||||
LLUUID asset_id = item->getProtectedAssetUUID();
|
||||
std::string buffer;
|
||||
asset_id.toString(buffer);
|
||||
|
||||
gViewerWindow->getWindow()->copyTextToClipboard(utf8str_to_wstring(buffer));
|
||||
}
|
||||
}
|
||||
else if ("purge" == action)
|
||||
{
|
||||
remove_inventory_object(selected_id, NULL);
|
||||
}
|
||||
else if ("goto" == action)
|
||||
{
|
||||
show_item_original(selected_id);
|
||||
}
|
||||
else if ("thumbnail" == action)
|
||||
{
|
||||
LLSD data(selected_id);
|
||||
LLFloaterReg::showInstance("change_item_thumbnail", data);
|
||||
}
|
||||
else if ("cut" == action)
|
||||
{
|
||||
bool allow = false;
|
||||
if(is_folder)
|
||||
{
|
||||
allow = get_is_category_removable(&gInventory, selected_id);
|
||||
}
|
||||
else
|
||||
{
|
||||
allow = get_is_item_removable(&gInventory, selected_id);
|
||||
}
|
||||
if(allow)
|
||||
{
|
||||
LLClipboard::instance().setCutMode(true);
|
||||
LLClipboard::instance().addToClipboard(selected_id);
|
||||
}
|
||||
}
|
||||
else if ("paste" == action)
|
||||
{
|
||||
{
|
||||
const LLUUID &marketplacelistings_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS);
|
||||
if(gInventory.isObjectDescendentOf(selected_id, marketplacelistings_id))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
bool is_cut_mode = (LLClipboard::instance().isCutMode());
|
||||
{
|
||||
std::vector<LLUUID> objects;
|
||||
LLClipboard::instance().pasteFromClipboard(objects);
|
||||
for (std::vector<LLUUID>::const_iterator iter = objects.begin(); iter != objects.end(); ++iter)
|
||||
{
|
||||
const LLUUID& item_id = (*iter);
|
||||
if(gInventory.isObjectDescendentOf(item_id, marketplacelistings_id) && (LLMarketplaceData::instance().isInActiveFolder(item_id) ||
|
||||
LLMarketplaceData::instance().isListedAndActive(item_id)))
|
||||
{
|
||||
return;
|
||||
}
|
||||
LLViewerInventoryCategory* cat = gInventory.getCategory(item_id);
|
||||
if (cat)
|
||||
{
|
||||
if(is_cut_mode)
|
||||
{
|
||||
gInventory.changeCategoryParent(cat, selected_id, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
copy_inventory_category(&gInventory, cat, selected_id);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LLViewerInventoryItem* item = gInventory.getItem(item_id);
|
||||
if (item)
|
||||
{
|
||||
if(is_cut_mode)
|
||||
{
|
||||
gInventory.changeItemParent(item, selected_id, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (item->getIsLinkType())
|
||||
{
|
||||
link_inventory_object(selected_id, item_id,
|
||||
LLPointer<LLInventoryCallback>(NULL));
|
||||
}
|
||||
else
|
||||
{
|
||||
copy_inventory_item(
|
||||
gAgent.getID(),
|
||||
item->getPermissions().getOwner(),
|
||||
item->getUUID(),
|
||||
selected_id,
|
||||
std::string(),
|
||||
LLPointer<LLInventoryCallback>(NULL));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
LLClipboard::instance().setCutMode(false);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
else if ("delete" == action)
|
||||
{
|
||||
if (is_folder)
|
||||
{
|
||||
if(get_is_category_removable(&gInventory, selected_id))
|
||||
{
|
||||
gInventory.removeCategory(selected_id);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(get_is_item_removable(&gInventory, selected_id))
|
||||
{
|
||||
gInventory.removeItem(selected_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ("copy" == action)
|
||||
{
|
||||
if(is_folder)
|
||||
{
|
||||
LLClipboard::instance().reset();
|
||||
LLClipboard::instance().addToClipboard(selected_id);
|
||||
}
|
||||
else
|
||||
{
|
||||
LLViewerInventoryItem* inv_item = gInventory.getItem(selected_id);
|
||||
if (inv_item && inv_item->getPermissions().allowOperationBy(PERM_COPY, gAgent.getID()) && !get_is_item_worn(selected_id))
|
||||
{
|
||||
LLClipboard::instance().reset();
|
||||
LLClipboard::instance().addToClipboard(selected_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ("paste_as_link" == action)
|
||||
{
|
||||
link_inventory_object(selected_id, obj, LLPointer<LLInventoryCallback>(NULL));
|
||||
}
|
||||
else if ("rename" == action)
|
||||
{
|
||||
LLSD args;
|
||||
args["NAME"] = obj->getName();
|
||||
|
||||
LLSD payload;
|
||||
payload["id"] = selected_id;
|
||||
|
||||
LLNotificationsUtil::add("RenameItem", args, payload, boost::bind(onRename, _1, _2));
|
||||
}
|
||||
else if ("open" == action || "open_original" == action)
|
||||
{
|
||||
LLViewerInventoryItem* item = gInventory.getItem(selected_id);
|
||||
if (item)
|
||||
{
|
||||
LLInvFVBridgeAction::doAction(item->getType(), selected_id , &gInventory);
|
||||
}
|
||||
}
|
||||
else if ("ungroup_folder_items" == action)
|
||||
{
|
||||
ungroup_folder_items(selected_id);
|
||||
}
|
||||
}
|
||||
|
||||
void LLInventoryGalleryContextMenu::onRename(const LLSD& notification, const LLSD& response)
|
||||
{
|
||||
S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
|
||||
if (option != 0) return; // canceled
|
||||
|
||||
std::string new_name = response["new_name"].asString();
|
||||
LLStringUtil::trim(new_name);
|
||||
if (!new_name.empty())
|
||||
{
|
||||
LLUUID id = notification["payload"]["id"].asUUID();
|
||||
|
||||
LLViewerInventoryCategory* cat = gInventory.getCategory(id);
|
||||
if(cat && (cat->getName() != new_name))
|
||||
{
|
||||
LLSD updates;
|
||||
updates["name"] = new_name;
|
||||
update_inventory_category(cat->getUUID(),updates, NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
LLViewerInventoryItem* item = gInventory.getItem(id);
|
||||
if(item && (item->getName() != new_name))
|
||||
{
|
||||
LLSD updates;
|
||||
updates["name"] = new_name;
|
||||
update_inventory_item(item->getUUID(),updates, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LLInventoryGalleryContextMenu::fileUploadLocation(const LLSD& userdata, const LLUUID& selected_id)
|
||||
{
|
||||
const std::string param = userdata.asString();
|
||||
if (param == "model")
|
||||
{
|
||||
gSavedPerAccountSettings.setString("ModelUploadFolder", selected_id.asString());
|
||||
}
|
||||
else if (param == "texture")
|
||||
{
|
||||
gSavedPerAccountSettings.setString("TextureUploadFolder", selected_id.asString());
|
||||
}
|
||||
else if (param == "sound")
|
||||
{
|
||||
gSavedPerAccountSettings.setString("SoundUploadFolder", selected_id.asString());
|
||||
}
|
||||
else if (param == "animation")
|
||||
{
|
||||
gSavedPerAccountSettings.setString("AnimationUploadFolder", selected_id.asString());
|
||||
}
|
||||
}
|
||||
|
||||
bool can_share_item(LLUUID item_id)
|
||||
{
|
||||
bool can_share = false;
|
||||
|
||||
if (gInventory.isObjectDescendentOf(item_id, gInventory.getRootFolderID()))
|
||||
{
|
||||
const LLViewerInventoryItem *item = gInventory.getItem(item_id);
|
||||
if (item)
|
||||
{
|
||||
if (LLInventoryCollectFunctor::itemTransferCommonlyAllowed(item))
|
||||
{
|
||||
can_share = LLGiveInventory::isInventoryGiveAcceptable(item);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
can_share = (gInventory.getCategory(item_id) != NULL);
|
||||
}
|
||||
|
||||
const LLUUID trash_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_TRASH);
|
||||
if ((item_id == trash_id) || gInventory.isObjectDescendentOf(item_id, trash_id))
|
||||
{
|
||||
can_share = false;
|
||||
}
|
||||
}
|
||||
|
||||
return can_share;
|
||||
}
|
||||
|
||||
bool is_inbox_folder(LLUUID item_id)
|
||||
{
|
||||
const LLUUID inbox_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_INBOX);
|
||||
|
||||
if (inbox_id.isNull())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return gInventory.isObjectDescendentOf(item_id, inbox_id);
|
||||
}
|
||||
|
||||
void LLInventoryGalleryContextMenu::updateMenuItemsVisibility(LLContextMenu* menu)
|
||||
{
|
||||
LLUUID selected_id = mUUIDs.front();
|
||||
LLInventoryObject* obj = gInventory.getObject(selected_id);
|
||||
if (!obj)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
std::vector<std::string> items;
|
||||
std::vector<std::string> disabled_items;
|
||||
|
||||
bool is_agent_inventory = gInventory.isObjectDescendentOf(selected_id, gInventory.getRootFolderID());
|
||||
bool is_link = obj->getIsLinkType();
|
||||
bool is_folder = (obj->getType() == LLAssetType::AT_CATEGORY);
|
||||
bool is_cof = LLAppearanceMgr::instance().getIsInCOF(selected_id);
|
||||
bool is_inbox = is_inbox_folder(selected_id);
|
||||
bool is_trash = (selected_id == gInventory.findCategoryUUIDForType(LLFolderType::FT_TRASH));
|
||||
bool is_in_trash = gInventory.isObjectDescendentOf(selected_id, gInventory.findCategoryUUIDForType(LLFolderType::FT_TRASH));
|
||||
bool is_lost_and_found = (selected_id == gInventory.findCategoryUUIDForType(LLFolderType::FT_LOST_AND_FOUND));
|
||||
bool is_outfits= (selected_id == gInventory.findCategoryUUIDForType(LLFolderType::FT_MY_OUTFITS));
|
||||
//bool is_favorites= (selected_id == gInventory.findCategoryUUIDForType(LLFolderType::FT_FAVORITE));
|
||||
|
||||
bool is_system_folder = false;
|
||||
LLFolderType::EType folder_type(LLFolderType::FT_NONE);
|
||||
bool has_children = false;
|
||||
bool is_full_perm_item = false;
|
||||
bool is_copyable = false;
|
||||
LLViewerInventoryItem* selected_item = gInventory.getItem(selected_id);
|
||||
|
||||
if(is_folder)
|
||||
{
|
||||
LLInventoryCategory* category = gInventory.getCategory(selected_id);
|
||||
if (category)
|
||||
{
|
||||
folder_type = category->getPreferredType();
|
||||
is_system_folder = LLFolderType::lookupIsProtectedType(folder_type);
|
||||
has_children = (gInventory.categoryHasChildren(selected_id) != LLInventoryModel::CHILDREN_NO);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (selected_item)
|
||||
{
|
||||
is_full_perm_item = selected_item->getIsFullPerm();
|
||||
is_copyable = selected_item->getPermissions().allowCopyBy(gAgent.getID());
|
||||
}
|
||||
}
|
||||
|
||||
if(!is_link)
|
||||
{
|
||||
items.push_back(std::string("thumbnail"));
|
||||
LLViewerInventoryItem* inv_item = gInventory.getItem(selected_id);
|
||||
if (inv_item && !inv_item->getPermissions().allowOperationBy(PERM_MODIFY, gAgent.getID()))
|
||||
{
|
||||
disabled_items.push_back(std::string("thumbnail"));
|
||||
}
|
||||
}
|
||||
|
||||
if (is_folder)
|
||||
{
|
||||
items.push_back(std::string("Copy Separator"));
|
||||
|
||||
items.push_back(std::string("open_in_current_window"));
|
||||
items.push_back(std::string("open_in_new_window"));
|
||||
items.push_back(std::string("Open Folder Separator"));
|
||||
}
|
||||
|
||||
if(is_trash)
|
||||
{
|
||||
items.push_back(std::string("Empty Trash"));
|
||||
|
||||
LLInventoryModel::cat_array_t* cat_array;
|
||||
LLInventoryModel::item_array_t* item_array;
|
||||
gInventory.getDirectDescendentsOf(selected_id, cat_array, item_array);
|
||||
if (0 == cat_array->size() && 0 == item_array->size())
|
||||
{
|
||||
disabled_items.push_back(std::string("Empty Trash"));
|
||||
}
|
||||
}
|
||||
else if(is_in_trash)
|
||||
{
|
||||
if (is_link)
|
||||
{
|
||||
items.push_back(std::string("Find Original"));
|
||||
if (LLAssetType::lookupIsLinkType(obj->getType()))
|
||||
{
|
||||
disabled_items.push_back(std::string("Find Original"));
|
||||
}
|
||||
}
|
||||
items.push_back(std::string("Purge Item"));
|
||||
if (!get_is_category_removable(&gInventory, selected_id))
|
||||
{
|
||||
disabled_items.push_back(std::string("Purge Item"));
|
||||
}
|
||||
items.push_back(std::string("Restore Item"));
|
||||
}
|
||||
else
|
||||
{
|
||||
if(can_share_item(selected_id))
|
||||
{
|
||||
items.push_back(std::string("Share"));
|
||||
}
|
||||
if (is_folder && is_agent_inventory)
|
||||
{
|
||||
if (!is_cof && (folder_type != LLFolderType::FT_OUTFIT) && !is_outfits && !is_inbox_folder(selected_id))
|
||||
{
|
||||
if (!gInventory.isObjectDescendentOf(selected_id, gInventory.findCategoryUUIDForType(LLFolderType::FT_CALLINGCARD)))
|
||||
{
|
||||
items.push_back(std::string("New Folder"));
|
||||
}
|
||||
items.push_back(std::string("upload_def"));
|
||||
}
|
||||
|
||||
if(is_outfits)
|
||||
{
|
||||
items.push_back(std::string("New Outfit"));
|
||||
}
|
||||
|
||||
items.push_back(std::string("Subfolder Separator"));
|
||||
if (!is_system_folder)
|
||||
{
|
||||
if(has_children && (folder_type != LLFolderType::FT_OUTFIT))
|
||||
{
|
||||
items.push_back(std::string("Ungroup folder items"));
|
||||
}
|
||||
items.push_back(std::string("Cut"));
|
||||
items.push_back(std::string("Delete"));
|
||||
if(!get_is_category_removable(&gInventory, selected_id))
|
||||
{
|
||||
disabled_items.push_back(std::string("Delete"));
|
||||
disabled_items.push_back(std::string("Cut"));
|
||||
}
|
||||
if(!is_inbox)
|
||||
{
|
||||
items.push_back(std::string("Rename"));
|
||||
}
|
||||
}
|
||||
if (LLClipboard::instance().hasContents() && is_agent_inventory && !is_cof && !is_inbox_folder(selected_id))
|
||||
{
|
||||
items.push_back(std::string("Paste"));
|
||||
|
||||
static LLCachedControl<bool> inventory_linking(gSavedSettings, "InventoryLinking", true);
|
||||
if (inventory_linking)
|
||||
{
|
||||
items.push_back(std::string("Paste As Link"));
|
||||
}
|
||||
}
|
||||
if(!is_system_folder)
|
||||
{
|
||||
items.push_back(std::string("Copy"));
|
||||
}
|
||||
}
|
||||
else if(!is_folder)
|
||||
{
|
||||
items.push_back(std::string("Properties"));
|
||||
items.push_back(std::string("Copy Asset UUID"));
|
||||
items.push_back(std::string("Copy Separator"));
|
||||
|
||||
bool is_asset_knowable = is_asset_knowable = LLAssetType::lookupIsAssetIDKnowable(obj->getType());
|
||||
if ( !is_asset_knowable // disable menu item for Inventory items with unknown asset. EXT-5308
|
||||
|| (! ( is_full_perm_item || gAgent.isGodlike())))
|
||||
{
|
||||
disabled_items.push_back(std::string("Copy Asset UUID"));
|
||||
}
|
||||
if(is_agent_inventory)
|
||||
{
|
||||
items.push_back(std::string("Cut"));
|
||||
if (!is_link || !is_cof || !get_is_item_worn(selected_id))
|
||||
{
|
||||
items.push_back(std::string("Delete"));
|
||||
}
|
||||
if(!get_is_item_removable(&gInventory, selected_id))
|
||||
{
|
||||
disabled_items.push_back(std::string("Delete"));
|
||||
disabled_items.push_back(std::string("Cut"));
|
||||
}
|
||||
|
||||
if (selected_item && (selected_item->getInventoryType() != LLInventoryType::IT_CALLINGCARD) && !is_inbox && selected_item->getPermissions().allowOperationBy(PERM_MODIFY, gAgent.getID()))
|
||||
{
|
||||
items.push_back(std::string("Rename"));
|
||||
}
|
||||
}
|
||||
items.push_back(std::string("Copy"));
|
||||
if (!is_copyable)
|
||||
{
|
||||
disabled_items.push_back(std::string("Copy"));
|
||||
}
|
||||
}
|
||||
if((obj->getType() == LLAssetType::AT_SETTINGS)
|
||||
|| ((obj->getType() <= LLAssetType::AT_GESTURE)
|
||||
&& obj->getType() != LLAssetType::AT_OBJECT
|
||||
&& obj->getType() != LLAssetType::AT_CLOTHING
|
||||
&& obj->getType() != LLAssetType::AT_CATEGORY
|
||||
&& obj->getType() != LLAssetType::AT_BODYPART))
|
||||
{
|
||||
bool can_open = !LLAssetType::lookupIsLinkType(obj->getType());
|
||||
|
||||
if (can_open)
|
||||
{
|
||||
if (is_link)
|
||||
items.push_back(std::string("Open Original"));
|
||||
else
|
||||
items.push_back(std::string("Open"));
|
||||
}
|
||||
else
|
||||
{
|
||||
disabled_items.push_back(std::string("Open"));
|
||||
disabled_items.push_back(std::string("Open Original"));
|
||||
}
|
||||
}
|
||||
else if(LLAssetType::AT_LANDMARK == obj->getType())
|
||||
{
|
||||
items.push_back(std::string("Landmark Open"));
|
||||
}
|
||||
if (is_link)
|
||||
{
|
||||
items.push_back(std::string("Find Original"));
|
||||
if (LLAssetType::lookupIsLinkType(obj->getType()))
|
||||
{
|
||||
disabled_items.push_back(std::string("Find Original"));
|
||||
}
|
||||
}
|
||||
if (is_lost_and_found)
|
||||
{
|
||||
items.push_back(std::string("Empty Lost And Found"));
|
||||
|
||||
LLInventoryModel::cat_array_t* cat_array;
|
||||
LLInventoryModel::item_array_t* item_array;
|
||||
gInventory.getDirectDescendentsOf(selected_id, cat_array, item_array);
|
||||
// Enable Empty menu item only when there is something to act upon.
|
||||
if (0 == cat_array->size() && 0 == item_array->size())
|
||||
{
|
||||
disabled_items.push_back(std::string("Empty Lost And Found"));
|
||||
}
|
||||
|
||||
disabled_items.push_back(std::string("New Folder"));
|
||||
disabled_items.push_back(std::string("upload_def"));
|
||||
}
|
||||
}
|
||||
|
||||
hide_context_entries(*menu, items, disabled_items);
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
/**
|
||||
* @file llinventorygallerymenu.h
|
||||
*
|
||||
* $LicenseInfo:firstyear=2023&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2023, 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_LLINVENTORYGALLERYMENU_H
|
||||
#define LL_LLINVENTORYGALLERYMENU_H
|
||||
|
||||
#include "lllistcontextmenu.h"
|
||||
|
||||
class LLInventoryGalleryContextMenu : public LLListContextMenu
|
||||
{
|
||||
public:
|
||||
LLInventoryGalleryContextMenu(LLInventoryGallery* gallery)
|
||||
: LLListContextMenu(),
|
||||
mGallery(gallery){}
|
||||
/*virtual*/ LLContextMenu* createMenu();
|
||||
|
||||
protected:
|
||||
//virtual void buildContextMenu(class LLMenuGL& menu, U32 flags);
|
||||
void updateMenuItemsVisibility(LLContextMenu* menu);
|
||||
|
||||
void doToSelected(const LLSD& userdata, const LLUUID& selected_id);
|
||||
void fileUploadLocation(const LLSD& userdata, const LLUUID& selected_id);
|
||||
|
||||
static void onRename(const LLSD& notification, const LLSD& response);
|
||||
|
||||
private:
|
||||
bool enableContextMenuItem(const LLSD& userdata);
|
||||
bool checkContextMenuItem(const LLSD& userdata);
|
||||
|
||||
LLInventoryGallery* mGallery;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,531 @@
|
|||
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
|
||||
<context_menu
|
||||
layout="topleft"
|
||||
name="Gallery">
|
||||
<menu_item_call
|
||||
label="Share"
|
||||
layout="topleft"
|
||||
name="Share">
|
||||
<menu_item_call.on_click
|
||||
function="Inventory.Share" />
|
||||
</menu_item_call>
|
||||
<menu_item_call
|
||||
label="Empty Trash"
|
||||
layout="topleft"
|
||||
name="Empty Trash">
|
||||
<menu_item_call.on_click
|
||||
function="Inventory.EmptyTrash"/>
|
||||
</menu_item_call>
|
||||
<menu_item_call
|
||||
label="Empty Lost And Found"
|
||||
layout="topleft"
|
||||
name="Empty Lost And Found">
|
||||
<menu_item_call.on_click
|
||||
function="Inventory.EmptyLostAndFound"/>
|
||||
</menu_item_call>
|
||||
<menu_item_call
|
||||
label="New Folder"
|
||||
layout="topleft"
|
||||
name="New Folder">
|
||||
<menu_item_call.on_click
|
||||
function="Inventory.DoCreate"
|
||||
parameter="category" />
|
||||
</menu_item_call>
|
||||
<menu_item_call
|
||||
label="New Outfit"
|
||||
layout="topleft"
|
||||
name="New Outfit">
|
||||
<menu_item_call.on_click
|
||||
function="Inventory.DoCreate"
|
||||
parameter="outfit" />
|
||||
</menu_item_call>
|
||||
<menu_item_call
|
||||
label="Teleport"
|
||||
layout="topleft"
|
||||
name="Landmark Open">
|
||||
<menu_item_call.on_click
|
||||
function="Inventory.DoToSelected"
|
||||
parameter="open" />
|
||||
</menu_item_call>
|
||||
<menu_item_separator
|
||||
layout="topleft"
|
||||
name="Folder Wearables Separator" />
|
||||
<menu_item_call
|
||||
label="Replace Current Outfit"
|
||||
layout="topleft"
|
||||
name="Replace Outfit">
|
||||
<menu_item_call.on_click
|
||||
function="Inventory.DoToSelected"
|
||||
parameter="replaceoutfit" />
|
||||
</menu_item_call>
|
||||
<menu_item_call
|
||||
label="Add To Current Outfit"
|
||||
layout="topleft"
|
||||
name="Add To Outfit">
|
||||
<menu_item_call.on_click
|
||||
function="Inventory.DoToSelected"
|
||||
parameter="addtooutfit" />
|
||||
</menu_item_call>
|
||||
<menu_item_call
|
||||
label="Remove From Current Outfit"
|
||||
layout="topleft"
|
||||
name="Remove From Outfit">
|
||||
<menu_item_call.on_click
|
||||
function="Inventory.DoToSelected"
|
||||
parameter="removefromoutfit" />
|
||||
</menu_item_call>
|
||||
<menu_item_call
|
||||
label="Copy outfit list to clipboard"
|
||||
layout="topleft"
|
||||
name="Copy outfit list to clipboard">
|
||||
<menu_item_call.on_click
|
||||
function="Inventory.DoToSelected"
|
||||
parameter="copyoutfittoclipboard" />
|
||||
</menu_item_call>
|
||||
<menu_item_separator
|
||||
layout="topleft"
|
||||
name="Outfit Separator" />
|
||||
<menu_item_call
|
||||
label="Find Original"
|
||||
layout="topleft"
|
||||
name="Find Original">
|
||||
<menu_item_call.on_click
|
||||
function="Inventory.DoToSelected"
|
||||
parameter="goto" />
|
||||
</menu_item_call>
|
||||
<menu_item_call
|
||||
label="Purge Item"
|
||||
layout="topleft"
|
||||
name="Purge Item">
|
||||
<menu_item_call.on_click
|
||||
function="Inventory.DoToSelected"
|
||||
parameter="purge"/>
|
||||
</menu_item_call>
|
||||
<menu_item_call
|
||||
label="Restore Item"
|
||||
layout="topleft"
|
||||
name="Restore Item">
|
||||
<menu_item_call.on_click
|
||||
function="Inventory.DoToSelected"
|
||||
parameter="restore" />
|
||||
</menu_item_call>
|
||||
<menu_item_call
|
||||
label="Open"
|
||||
layout="topleft"
|
||||
name="Open">
|
||||
<menu_item_call.on_click
|
||||
function="Inventory.DoToSelected"
|
||||
parameter="open" />
|
||||
</menu_item_call>
|
||||
<menu_item_call
|
||||
label="Open Original"
|
||||
layout="topleft"
|
||||
name="Open Original">
|
||||
<menu_item_call.on_click
|
||||
function="Inventory.DoToSelected"
|
||||
parameter="open_original" />
|
||||
</menu_item_call>
|
||||
<menu_item_call
|
||||
label="Properties"
|
||||
layout="topleft"
|
||||
name="Properties">
|
||||
<menu_item_call.on_click
|
||||
function="Inventory.DoToSelected"
|
||||
parameter="properties" />
|
||||
</menu_item_call>
|
||||
<menu_item_call
|
||||
label="Image..."
|
||||
layout="topleft"
|
||||
name="thumbnail">
|
||||
<menu_item_call.on_click
|
||||
function="Inventory.DoToSelected"
|
||||
parameter="thumbnail" />
|
||||
</menu_item_call>
|
||||
<menu_item_call
|
||||
label="Copy Asset UUID"
|
||||
layout="topleft"
|
||||
name="Copy Asset UUID">
|
||||
<menu_item_call.on_click
|
||||
function="Inventory.DoToSelected"
|
||||
parameter="copy_uuid" />
|
||||
</menu_item_call>
|
||||
<menu_item_separator
|
||||
layout="topleft"
|
||||
name="Copy Separator" />
|
||||
<menu_item_call
|
||||
label="Open"
|
||||
layout="topleft"
|
||||
name="open_in_current_window">
|
||||
<menu_item_call.on_click
|
||||
function="Inventory.DoToSelected"
|
||||
parameter="open_selected_folder" />
|
||||
</menu_item_call>
|
||||
<menu_item_call
|
||||
label="Open in new window"
|
||||
layout="topleft"
|
||||
name="open_in_new_window">
|
||||
<menu_item_call.on_click
|
||||
function="Inventory.DoToSelected"
|
||||
parameter="open_in_new_window" />
|
||||
</menu_item_call>
|
||||
<menu_item_separator
|
||||
layout="topleft"
|
||||
name="Open Folder Separator" />
|
||||
<menu_item_call
|
||||
label="Rename"
|
||||
layout="topleft"
|
||||
name="Rename">
|
||||
<menu_item_call.on_click
|
||||
function="Inventory.DoToSelected"
|
||||
parameter="rename" />
|
||||
</menu_item_call>
|
||||
<menu_item_call
|
||||
label="Cut"
|
||||
layout="topleft"
|
||||
name="Cut">
|
||||
<menu_item_call.on_click
|
||||
function="Inventory.DoToSelected"
|
||||
parameter="cut" />
|
||||
</menu_item_call>
|
||||
<menu_item_call
|
||||
label="Copy"
|
||||
layout="topleft"
|
||||
name="Copy">
|
||||
<menu_item_call.on_click
|
||||
function="Inventory.DoToSelected"
|
||||
parameter="copy" />
|
||||
</menu_item_call>
|
||||
<menu_item_call
|
||||
label="Paste"
|
||||
layout="topleft"
|
||||
name="Paste">
|
||||
<menu_item_call.on_click
|
||||
function="Inventory.DoToSelected"
|
||||
parameter="paste" />
|
||||
</menu_item_call>
|
||||
<menu_item_call
|
||||
label="Paste As Link"
|
||||
layout="topleft"
|
||||
name="Paste As Link">
|
||||
<menu_item_call.on_click
|
||||
function="Inventory.DoToSelected"
|
||||
parameter="paste_link" />
|
||||
</menu_item_call>
|
||||
<menu_item_call
|
||||
label="Replace Links"
|
||||
layout="topleft"
|
||||
name="Replace Links">
|
||||
<menu_item_call.on_click
|
||||
function="Inventory.DoToSelected"
|
||||
parameter="replace_links" />
|
||||
</menu_item_call>
|
||||
<menu_item_separator
|
||||
layout="topleft"
|
||||
name="Paste Separator" />
|
||||
<menu_item_call
|
||||
label="Delete"
|
||||
layout="topleft"
|
||||
name="Delete">
|
||||
<menu_item_call.on_click
|
||||
function="Inventory.DoToSelected"
|
||||
parameter="delete" />
|
||||
</menu_item_call>
|
||||
<menu_item_call
|
||||
label="Delete System Folder"
|
||||
layout="topleft"
|
||||
name="Delete System Folder">
|
||||
<menu_item_call.on_click
|
||||
function="Inventory.DoToSelected"
|
||||
parameter="delete_system_folder" />
|
||||
</menu_item_call>
|
||||
<menu_item_separator
|
||||
layout="topleft" />
|
||||
<menu_item_separator
|
||||
layout="topleft" />
|
||||
<menu_item_call
|
||||
label="Play"
|
||||
layout="topleft"
|
||||
name="Sound Play">
|
||||
<menu_item_call.on_click
|
||||
function="Inventory.DoToSelected"
|
||||
parameter="sound_play" />
|
||||
</menu_item_call>
|
||||
<menu_item_separator
|
||||
layout="topleft"
|
||||
name="Landmark Separator" />
|
||||
<menu_item_call
|
||||
label="Copy SLurl"
|
||||
layout="topleft"
|
||||
name="url_copy">
|
||||
<menu_item_call.on_click
|
||||
function="Inventory.DoToSelected"
|
||||
parameter="copy_slurl" />
|
||||
</menu_item_call>
|
||||
<menu_item_call
|
||||
label="About Landmark"
|
||||
layout="topleft"
|
||||
name="About Landmark">
|
||||
<menu_item_call.on_click
|
||||
function="Inventory.DoToSelected"
|
||||
parameter="about" />
|
||||
</menu_item_call>
|
||||
<menu_item_call
|
||||
label="Show on Map"
|
||||
layout="topleft"
|
||||
name="show_on_map">
|
||||
<menu_item_call.on_click
|
||||
function="Inventory.DoToSelected"
|
||||
parameter="show_on_map" />
|
||||
</menu_item_call>
|
||||
<menu_item_separator
|
||||
layout="topleft"
|
||||
name="Animation Separator" />
|
||||
<menu_item_call
|
||||
label="Play Inworld"
|
||||
layout="topleft"
|
||||
name="Animation Play">
|
||||
<menu_item_call.on_click
|
||||
function="Inventory.DoToSelected"
|
||||
parameter="playworld" />
|
||||
</menu_item_call>
|
||||
<menu_item_call
|
||||
label="Play Locally"
|
||||
layout="topleft"
|
||||
name="Animation Audition">
|
||||
<menu_item_call.on_click
|
||||
function="Inventory.DoToSelected"
|
||||
parameter="playlocal" />
|
||||
</menu_item_call>
|
||||
<menu_item_separator
|
||||
layout="topleft"
|
||||
name="Send Instant Message Separator" />
|
||||
<menu_item_call
|
||||
label="Send Instant Message"
|
||||
layout="topleft"
|
||||
name="Send Instant Message">
|
||||
<menu_item_call.on_click
|
||||
function="Inventory.DoToSelected"
|
||||
parameter="begin_im" />
|
||||
</menu_item_call>
|
||||
<menu_item_call
|
||||
label="Offer Teleport..."
|
||||
layout="topleft"
|
||||
name="Offer Teleport...">
|
||||
<menu_item_call.on_click
|
||||
function="Inventory.DoToSelected"
|
||||
parameter="lure" />
|
||||
</menu_item_call>
|
||||
<menu_item_call
|
||||
label="Request Teleport..."
|
||||
layout="topleft"
|
||||
name="Request Teleport...">
|
||||
<menu_item_call.on_click
|
||||
function="Inventory.DoToSelected"
|
||||
parameter="request_lure" />
|
||||
</menu_item_call>
|
||||
<menu_item_call
|
||||
label="Start Conference Chat"
|
||||
layout="topleft"
|
||||
name="Conference Chat">
|
||||
<menu_item_call.on_click
|
||||
function="Inventory.BeginIMSession"
|
||||
parameter="selected" />
|
||||
</menu_item_call>
|
||||
<menu_item_separator
|
||||
layout="topleft"
|
||||
name="Gesture Separator" />
|
||||
<menu_item_call
|
||||
label="Activate"
|
||||
layout="topleft"
|
||||
name="Activate">
|
||||
<menu_item_call.on_click
|
||||
function="Inventory.DoToSelected"
|
||||
parameter="activate" />
|
||||
</menu_item_call>
|
||||
<menu_item_call
|
||||
label="Deactivate"
|
||||
layout="topleft"
|
||||
name="Deactivate">
|
||||
<menu_item_call.on_click
|
||||
function="Inventory.DoToSelected"
|
||||
parameter="deactivate" />
|
||||
</menu_item_call>
|
||||
<menu_item_separator
|
||||
layout="topleft"
|
||||
name="Texture Separator" />
|
||||
<menu_item_call
|
||||
label="Save As"
|
||||
layout="topleft"
|
||||
name="Save As">
|
||||
<menu_item_call.on_click
|
||||
function="Inventory.DoToSelected"
|
||||
parameter="save_as" />
|
||||
</menu_item_call>
|
||||
<menu_item_call
|
||||
label="Save Selected As"
|
||||
layout="topleft"
|
||||
name="Save Selected As">
|
||||
<menu_item_call.on_click
|
||||
function="Inventory.DoToSelected"
|
||||
parameter="save_selected_as" />
|
||||
</menu_item_call>
|
||||
<menu_item_separator
|
||||
layout="topleft"
|
||||
name="Wearable And Object Separator"/>
|
||||
<menu_item_call
|
||||
label="Wear"
|
||||
layout="topleft"
|
||||
name="Wearable And Object Wear">
|
||||
<menu_item_call.on_click
|
||||
function="Inventory.DoToSelected"
|
||||
parameter="wear" />
|
||||
</menu_item_call>
|
||||
<menu
|
||||
label="Attach To"
|
||||
layout="topleft"
|
||||
name="Attach To" />
|
||||
<menu
|
||||
label="Attach To HUD"
|
||||
layout="topleft"
|
||||
name="Attach To HUD" />
|
||||
<menu_item_call
|
||||
label="Touch"
|
||||
layout="topleft"
|
||||
name="Attachment Touch">
|
||||
<menu_item_call.on_click
|
||||
function="Inventory.DoToSelected"
|
||||
parameter="touch" />
|
||||
</menu_item_call>
|
||||
<menu_item_call
|
||||
label="Edit"
|
||||
layout="topleft"
|
||||
name="Wearable Edit">
|
||||
<menu_item_call.on_click
|
||||
function="Inventory.DoToSelected"
|
||||
parameter="edit" />
|
||||
</menu_item_call>
|
||||
<menu_item_call
|
||||
label="Add"
|
||||
layout="topleft"
|
||||
name="Wearable Add">
|
||||
<menu_item_call.on_click
|
||||
function="Inventory.DoToSelected"
|
||||
parameter="wear_add" />
|
||||
</menu_item_call>
|
||||
<menu_item_call
|
||||
label="Detach From Yourself"
|
||||
layout="topleft"
|
||||
name="Detach From Yourself">
|
||||
<menu_item_call.on_click
|
||||
function="Inventory.DoToSelected"
|
||||
parameter="detach" />
|
||||
</menu_item_call>
|
||||
<menu_item_call
|
||||
label="Take Off"
|
||||
layout="topleft"
|
||||
name="Take Off">
|
||||
<menu_item_call.on_click
|
||||
function="Inventory.DoToSelected"
|
||||
parameter="take_off" />
|
||||
</menu_item_call>
|
||||
<menu_item_separator
|
||||
layout="topleft"
|
||||
name="Settings Separator" />
|
||||
<menu_item_call
|
||||
name="Settings Apply Local"
|
||||
layout="topleft"
|
||||
label="Apply Only To Myself">
|
||||
<menu_item_call.on_click
|
||||
function="Inventory.DoToSelected"
|
||||
parameter="apply_settings_local" />
|
||||
</menu_item_call>
|
||||
<menu_item_call
|
||||
name="Settings Apply Parcel"
|
||||
layout="topleft"
|
||||
label="Apply To Parcel">
|
||||
<menu_item_call.on_click
|
||||
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
|
||||
label="Use as default for"
|
||||
layout="topleft"
|
||||
name="upload_def">
|
||||
<menu_item_call
|
||||
label="Image uploads"
|
||||
layout="topleft"
|
||||
name="Image uploads">
|
||||
<menu_item_call.on_click
|
||||
function="Inventory.FileUploadLocation"
|
||||
parameter="texture" />
|
||||
</menu_item_call>
|
||||
<menu_item_call
|
||||
label="Sound uploads"
|
||||
layout="topleft"
|
||||
name="Sound uploads">
|
||||
<menu_item_call.on_click
|
||||
function="Inventory.FileUploadLocation"
|
||||
parameter="sound" />
|
||||
</menu_item_call>
|
||||
<menu_item_call
|
||||
label="Animation uploads"
|
||||
layout="topleft"
|
||||
name="Animation uploads">
|
||||
<menu_item_call.on_click
|
||||
function="Inventory.FileUploadLocation"
|
||||
parameter="animation" />
|
||||
</menu_item_call>
|
||||
<menu_item_call
|
||||
label="Model uploads"
|
||||
layout="topleft"
|
||||
name="Model uploads">
|
||||
<menu_item_call.on_click
|
||||
function="Inventory.FileUploadLocation"
|
||||
parameter="model" />
|
||||
</menu_item_call>
|
||||
</menu>
|
||||
<menu_item_separator
|
||||
layout="topleft"
|
||||
name="Marketplace Separator" />
|
||||
<menu_item_call
|
||||
label="Copy to Marketplace Listings"
|
||||
layout="topleft"
|
||||
name="Marketplace Copy">
|
||||
<menu_item_call.on_click
|
||||
function="Inventory.DoToSelected"
|
||||
parameter="copy_to_marketplace_listings" />
|
||||
</menu_item_call>
|
||||
<menu_item_call
|
||||
label="Move to Marketplace Listings"
|
||||
layout="topleft"
|
||||
name="Marketplace Move">
|
||||
<menu_item_call.on_click
|
||||
function="Inventory.DoToSelected"
|
||||
parameter="move_to_marketplace_listings" />
|
||||
</menu_item_call>
|
||||
<menu_item_call
|
||||
label="--no options--"
|
||||
layout="topleft"
|
||||
name="--no options--" />
|
||||
<menu_item_separator
|
||||
layout="topleft" />
|
||||
</context_menu>
|
||||
|
|
@ -3247,6 +3247,29 @@ See https://wiki.secondlife.com/wiki/Adding_Spelling_Dictionaries
|
|||
</form>
|
||||
</notification>
|
||||
|
||||
<notification
|
||||
icon="alertmodal.tga"
|
||||
label="Rename Selected Item"
|
||||
name="RenameItem"
|
||||
type="alertmodal">
|
||||
Choose a new name for [NAME]
|
||||
<tag>confirm</tag>
|
||||
<form name="form">
|
||||
<input name="new_name" type="text" width="300">
|
||||
[NAME]
|
||||
</input>
|
||||
<button
|
||||
default="true"
|
||||
index="0"
|
||||
name="OK"
|
||||
text="OK"/>
|
||||
<button
|
||||
index="1"
|
||||
name="Cancel"
|
||||
text="Cancel"/>
|
||||
</form>
|
||||
</notification>
|
||||
|
||||
<notification
|
||||
icon="alertmodal.tga"
|
||||
name="RemoveFromFriends"
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@
|
|||
</text>
|
||||
<scroll_container
|
||||
follows="all"
|
||||
height="400"
|
||||
height="390"
|
||||
layout="topleft"
|
||||
left="4"
|
||||
top="0"
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@
|
|||
left="0"
|
||||
top="129"
|
||||
height="25"
|
||||
width="148"
|
||||
width="130"
|
||||
name="text_bg_panel">
|
||||
<text
|
||||
read_only="true"
|
||||
|
|
@ -65,7 +65,7 @@
|
|||
name="item_name"
|
||||
parse_urls="false"
|
||||
top="2"
|
||||
width="150"
|
||||
width="130"
|
||||
use_ellipses="true">
|
||||
Item name, folder name.
|
||||
</text>
|
||||
|
|
|
|||
Loading…
Reference in New Issue