summaryrefslogtreecommitdiff
path: root/indra/newview/llinventorygallery.cpp
diff options
context:
space:
mode:
authorAndrey Kleshchev <andreykproductengine@lindenlab.com>2023-06-08 22:50:12 +0300
committerAndrey Kleshchev <andreykproductengine@lindenlab.com>2023-06-08 22:50:19 +0300
commit53fc42fe032c2aef453f420645b0e46dea4c23db (patch)
treea548f26e4b4d540a249a44dd324e783ae45395d3 /indra/newview/llinventorygallery.cpp
parent29f52ad1a7c4f0d023c4b6a7dd0d43ea105e8fdb (diff)
SL-19832 Inventory gallery should support CTRL+X, C and V
Diffstat (limited to 'indra/newview/llinventorygallery.cpp')
-rw-r--r--indra/newview/llinventorygallery.cpp235
1 files changed, 234 insertions, 1 deletions
diff --git a/indra/newview/llinventorygallery.cpp b/indra/newview/llinventorygallery.cpp
index 63a706a9d6..eff43e33ca 100644
--- a/indra/newview/llinventorygallery.cpp
+++ b/indra/newview/llinventorygallery.cpp
@@ -29,6 +29,7 @@
#include "llinventorygallery.h"
#include "llinventorygallerymenu.h"
+#include "llclipboard.h"
#include "llcommonutils.h"
#include "lliconctrl.h"
#include "llinventorybridge.h"
@@ -133,6 +134,11 @@ BOOL LLInventoryGallery::postBuild()
LLInventoryGallery::~LLInventoryGallery()
{
+ if (gEditMenuHandler == this)
+ {
+ gEditMenuHandler = NULL;
+ }
+
delete mInventoryGalleryMenu;
delete mRootGalleryMenu;
delete mFilter;
@@ -1009,6 +1015,7 @@ void LLInventoryGallery::moveUp()
LLUUID item_id = item->getUUID();
changeItemSelection(item_id, true);
item->setFocus(TRUE);
+ claimEditHandler();
}
}
}
@@ -1031,6 +1038,7 @@ void LLInventoryGallery::moveDown()
LLUUID item_id = item->getUUID();
changeItemSelection(item_id, true);
item->setFocus(TRUE);
+ claimEditHandler();
}
}
}
@@ -1056,6 +1064,7 @@ void LLInventoryGallery::moveLeft()
LLUUID item_id = item->getUUID();
changeItemSelection(item_id, true);
item->setFocus(TRUE);
+ claimEditHandler();
}
}
}
@@ -1079,6 +1088,7 @@ void LLInventoryGallery::moveRight()
LLUUID item_id = item->getUUID();
changeItemSelection(item_id, true);
item->setFocus(TRUE);
+ claimEditHandler();
}
}
}
@@ -1154,6 +1164,227 @@ LLInventoryGalleryItem* LLInventoryGallery::getSelectedItem()
return mItemMap[mSelectedItemID];
}
+void LLInventoryGallery::copy()
+{
+ LLClipboard::instance().reset();
+ if (getVisible() && getEnabled() && mSelectedItemID.notNull())
+ {
+ LLClipboard::instance().addToClipboard(mSelectedItemID);
+ }
+ mFilterSubString.clear();
+}
+
+BOOL LLInventoryGallery::canCopy() const
+{
+ if (!getVisible() || !getEnabled() || mSelectedItemID.isNull())
+ {
+ return FALSE;
+ }
+
+ if (!isItemCopyable(mSelectedItemID))
+ {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+void LLInventoryGallery::cut()
+{
+ // clear the inventory clipboard
+ LLClipboard::instance().reset();
+ if (getVisible() && getEnabled() && mSelectedItemID.notNull())
+ {
+ // todo: fade out selected item
+ LLClipboard::instance().setCutMode(true);
+ LLClipboard::instance().addToClipboard(mSelectedItemID);
+ }
+ mFilterSubString.clear();
+}
+
+BOOL LLInventoryGallery::canCut() const
+{
+ if (!getVisible() || !getEnabled() || mSelectedItemID.isNull())
+ {
+ return FALSE;
+ }
+
+ LLViewerInventoryCategory* cat = gInventory.getCategory(mSelectedItemID);
+ if (cat)
+ {
+ if (!get_is_category_removable(&gInventory, mSelectedItemID))
+ {
+ return FALSE;
+ }
+ }
+ else if (!get_is_item_removable(&gInventory, mSelectedItemID))
+ {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+void LLInventoryGallery::paste()
+{
+ const LLUUID& marketplacelistings_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS);
+ if (gInventory.isObjectDescendentOf(mSelectedItemID, marketplacelistings_id))
+ {
+ return;
+ }
+
+ LLInventoryObject* obj = gInventory.getObject(mSelectedItemID);
+ bool is_folder = obj && (obj->getType() == LLAssetType::AT_CATEGORY);
+ LLUUID dest = is_folder ? mSelectedItemID : mFolderID;
+ 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, dest, false);
+ }
+ else
+ {
+ copy_inventory_category(&gInventory, cat, dest);
+ }
+ }
+ else
+ {
+ LLViewerInventoryItem* item = gInventory.getItem(item_id);
+ if (item)
+ {
+ if (is_cut_mode)
+ {
+ gInventory.changeItemParent(item, dest, false);
+ }
+ else
+ {
+ if (item->getIsLinkType())
+ {
+ link_inventory_object(dest, item_id,
+ LLPointer<LLInventoryCallback>(NULL));
+ }
+ else
+ {
+ copy_inventory_item(
+ gAgent.getID(),
+ item->getPermissions().getOwner(),
+ item->getUUID(),
+ dest,
+ std::string(),
+ LLPointer<LLInventoryCallback>(NULL));
+ }
+ }
+ }
+ }
+ }
+ // todo: scroll to item on arrival
+ LLClipboard::instance().setCutMode(false);
+}
+
+BOOL LLInventoryGallery::canPaste() const
+{
+ // Return FALSE on degenerated cases: empty clipboard, no inventory, no agent
+ if (!LLClipboard::instance().hasContents())
+ {
+ return FALSE;
+ }
+
+ // In cut mode, whatever is on the clipboard is always pastable
+ if (LLClipboard::instance().isCutMode())
+ {
+ return TRUE;
+ }
+
+ // In normal mode, we need to check each element of the clipboard to know if we can paste or not
+ std::vector<LLUUID> objects;
+ LLClipboard::instance().pasteFromClipboard(objects);
+ S32 count = objects.size();
+ for (S32 i = 0; i < count; i++)
+ {
+ const LLUUID& item_id = objects.at(i);
+
+ // Each item must be copyable to be pastable
+ if (!isItemCopyable(item_id))
+ {
+ return FALSE;
+ }
+ }
+ return TRUE;
+}
+
+void LLInventoryGallery::claimEditHandler()
+{
+ gEditMenuHandler = this;
+}
+
+bool LLInventoryGallery::isItemCopyable(const LLUUID & item_id)
+{
+ const LLInventoryCategory* cat = gInventory.getCategory(item_id);
+ if (cat)
+ {
+ // Folders are copyable if items in them are, recursively, copyable.
+ // Get the content of the folder
+ LLInventoryModel::cat_array_t* cat_array;
+ LLInventoryModel::item_array_t* item_array;
+ gInventory.getDirectDescendentsOf(item_id, cat_array, item_array);
+
+ // Check the items
+ LLInventoryModel::item_array_t item_array_copy = *item_array;
+ for (LLInventoryModel::item_array_t::iterator iter = item_array_copy.begin(); iter != item_array_copy.end(); iter++)
+ {
+ LLInventoryItem* item = *iter;
+ if (!isItemCopyable(item->getUUID()))
+ {
+ return false;
+ }
+ }
+
+ // Check the folders
+ LLInventoryModel::cat_array_t cat_array_copy = *cat_array;
+ for (LLInventoryModel::cat_array_t::iterator iter = cat_array_copy.begin(); iter != cat_array_copy.end(); iter++)
+ {
+ LLViewerInventoryCategory* category = *iter;
+ if (!isItemCopyable(category->getUUID()))
+ {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ LLViewerInventoryItem* item = gInventory.getItem(item_id);
+ if (item)
+ {
+ // Can't copy worn objects.
+ // Worn objects are tied to their inworld conterparts
+ // Copy of modified worn object will return object with obsolete asset and inventory
+ if (get_is_item_worn(item_id))
+ {
+ return false;
+ }
+
+ static LLCachedControl<bool> inventory_linking(gSavedSettings, "InventoryLinking", true);
+ return (item->getIsLinkType() && inventory_linking)
+ || item->getPermissions().allowCopyBy(gAgent.getID());
+ }
+
+ return false;
+}
+
void LLInventoryGallery::updateMessageVisibility()
{
@@ -1666,6 +1897,7 @@ void LLInventoryGalleryItem::setSelected(bool value)
BOOL LLInventoryGalleryItem::handleMouseDown(S32 x, S32 y, MASK mask)
{
setFocus(TRUE);
+ mGallery->claimEditHandler();
gFocusMgr.setMouseCapture(this);
S32 screen_x;
@@ -1678,6 +1910,8 @@ BOOL LLInventoryGalleryItem::handleMouseDown(S32 x, S32 y, MASK mask)
BOOL LLInventoryGalleryItem::handleRightMouseDown(S32 x, S32 y, MASK mask)
{
setFocus(TRUE);
+ mGallery->claimEditHandler();
+
return LLUICtrl::handleRightMouseDown(x, y, mask);
}
@@ -1763,7 +1997,6 @@ BOOL LLInventoryGalleryItem::handleKeyHere(KEY key, MASK mask)
BOOL handled = FALSE;
switch (key)
{
-
case KEY_LEFT:
mGallery->moveLeft();
handled = true;