Inventory cut support!
Also fixes a bunch of comments, implementation based off of v-d. Added isOnClipboard and setCutMode functions to LLInventoryClipboard, in part from v-d's LLClipboard. LLInventoryFilter has a few rearrangements of code; only real change is now it has checkAgainstClipboard and uses it to filter out cut items. There is a massive retabbed block in llinventorymodel.cpp, view without space changes. Implements removeObject. Note: We are not afflicted by MAINT-1197: Fix inventory deselection/reselection when cutting items
This commit is contained in:
@@ -429,7 +429,7 @@ void LLFolderView::setOpenArrangeRecursively(BOOL openitem, ERecurseType recurse
|
||||
|
||||
static LLFastTimer::DeclareTimer FTM_ARRANGE("Arrange");
|
||||
|
||||
// This view grows and shinks to enclose all of its children items and folders.
|
||||
// This view grows and shrinks to enclose all of its children items and folders.
|
||||
S32 LLFolderView::arrange( S32* unused_width, S32* unused_height, S32 filter_generation )
|
||||
{
|
||||
if(!mScrollContainer)
|
||||
@@ -1049,6 +1049,24 @@ bool isDescendantOfASelectedItem(LLFolderViewItem* item, const std::vector<LLFol
|
||||
return false;
|
||||
}
|
||||
|
||||
// static
|
||||
void LLFolderView::removeCutItems()
|
||||
{
|
||||
// There's no item in "cut" mode on the clipboard -> exit
|
||||
if (!LLInventoryClipboard::instance().isCutMode())
|
||||
return;
|
||||
|
||||
// Get the list of clipboard item uuids and iterate through them
|
||||
LLDynamicArray<LLUUID> objects;
|
||||
LLInventoryClipboard::instance().retrieve(objects);
|
||||
for (LLDynamicArray<LLUUID>::const_iterator iter = objects.begin();
|
||||
iter != objects.end();
|
||||
++iter)
|
||||
{
|
||||
gInventory.removeObject(*iter);
|
||||
}
|
||||
}
|
||||
|
||||
void LLFolderView::removeSelectedItems( void )
|
||||
{
|
||||
if(getVisible() && getEnabled())
|
||||
@@ -1385,6 +1403,7 @@ void LLFolderView::cut()
|
||||
listener->cutToClipboard();
|
||||
}
|
||||
}
|
||||
LLFolderView::removeCutItems();
|
||||
}
|
||||
mSearchString.clear();
|
||||
}
|
||||
@@ -2015,7 +2034,7 @@ void LLFolderView::scrollToShowSelection()
|
||||
}
|
||||
}
|
||||
|
||||
// If the parent is scroll containter, scroll it to make the selection
|
||||
// If the parent is scroll container, scroll it to make the selection
|
||||
// is maximally visible.
|
||||
void LLFolderView::scrollToShowItem(LLFolderViewItem* item, const LLRect& constraint_rect)
|
||||
{
|
||||
@@ -2165,7 +2184,7 @@ void LLFolderView::doIdle()
|
||||
mNeedsAutoSelect = filter_modified_and_active &&
|
||||
!(gFocusMgr.childHasKeyboardFocus(this) || gFocusMgr.getMouseCapture());
|
||||
|
||||
// filter to determine visiblity before arranging
|
||||
// filter to determine visibility before arranging
|
||||
filterFromRoot();
|
||||
|
||||
// automatically show matching items, and select first one
|
||||
|
||||
@@ -67,8 +67,8 @@ class LLTextBox;
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// Class LLFolderView
|
||||
//
|
||||
// Th LLFolderView represents the root level folder view object. It
|
||||
// manages the screen region of the folder view.
|
||||
// The LLFolderView represents the root level folder view object.
|
||||
// It manages the screen region of the folder view.
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
class LLFolderView : public LLFolderViewFolder, public LLEditMenuHandler
|
||||
@@ -160,6 +160,7 @@ public:
|
||||
|
||||
// Deletion functionality
|
||||
void removeSelectedItems();
|
||||
static void removeCutItems();
|
||||
|
||||
// Open the selected item
|
||||
void openSelectedItems( void );
|
||||
@@ -320,7 +321,7 @@ protected:
|
||||
|
||||
/**
|
||||
* Is used to determine if we need to cut text In LLFolderViewItem to avoid horizontal scroll.
|
||||
* NOTE: For now it uses only to cut LLFolderViewItem::mLabel text to be used for Landmarks in Places Panel.
|
||||
* NOTE: For now it's used only to cut LLFolderViewItem::mLabel text for Landmarks in Places Panel.
|
||||
*/
|
||||
bool mUseEllipses; // See EXT-719
|
||||
|
||||
|
||||
@@ -124,7 +124,7 @@ bool doToSelected(LLFolderView* folder, std::string action)
|
||||
return true;
|
||||
}
|
||||
|
||||
if ("copy" == action)
|
||||
if ("copy" == action || "cut" == action)
|
||||
{
|
||||
LLInventoryClipboard::instance().reset();
|
||||
}
|
||||
|
||||
@@ -319,7 +319,6 @@ BOOL LLInvFVBridge::isLink() const
|
||||
/**
|
||||
* @brief Adds this item into clipboard storage
|
||||
*/
|
||||
//Unused.
|
||||
void LLInvFVBridge::cutToClipboard()
|
||||
{
|
||||
if(isItemMovable())
|
||||
@@ -568,6 +567,7 @@ void LLInvFVBridge::removeBatchNoCheck(LLDynamicArray<LLFolderViewEventListener*
|
||||
|
||||
BOOL LLInvFVBridge::isClipboardPasteable() const
|
||||
{
|
||||
// Return FALSE on degenerated cases: empty clipboard, no inventory, no agent
|
||||
if (!LLInventoryClipboard::instance().hasContents() || !isAgentInventory())
|
||||
{
|
||||
return FALSE;
|
||||
@@ -578,6 +578,13 @@ BOOL LLInvFVBridge::isClipboardPasteable() const
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// In cut mode, whatever is on the clipboard is always pastable
|
||||
if (LLInventoryClipboard::instance().isCutMode())
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// In normal mode, we need to check each element of the clipboard to know if we can paste or not
|
||||
LLInventoryPanel* panel = dynamic_cast<LLInventoryPanel*>(mInventoryPanel.get());
|
||||
LLDynamicArray<LLUUID> objects;
|
||||
LLInventoryClipboard::instance().retrieve(objects);
|
||||
@@ -772,6 +779,12 @@ void LLInvFVBridge::getClipboardEntries(bool show_asset_id,
|
||||
disabled_items.push_back(std::string("Copy"));
|
||||
}
|
||||
|
||||
items.push_back(std::string("Cut"));
|
||||
if (!isItemMovable() || !isItemRemovable())
|
||||
{
|
||||
disabled_items.push_back(std::string("Cut"));
|
||||
}
|
||||
|
||||
if (canListOnMarketplace())
|
||||
{
|
||||
items.push_back(std::string("Marketplace Separator"));
|
||||
@@ -1434,6 +1447,12 @@ void LLItemBridge::performAction(LLInventoryModel* model, std::string action)
|
||||
gViewerWindow->getWindow()->copyTextToClipboard(utf8str_to_wstring(buffer));
|
||||
return;
|
||||
}
|
||||
else if ("cut" == action)
|
||||
{
|
||||
cutToClipboard();
|
||||
LLFolderView::removeCutItems();
|
||||
return;
|
||||
}
|
||||
else if ("copy" == action)
|
||||
{
|
||||
copyToClipboard();
|
||||
@@ -1441,7 +1460,6 @@ void LLItemBridge::performAction(LLInventoryModel* model, std::string action)
|
||||
}
|
||||
else if ("paste" == action)
|
||||
{
|
||||
// Single item only
|
||||
LLInventoryItem* itemp = model->getItem(mUUID);
|
||||
if (!itemp) return;
|
||||
|
||||
@@ -2826,6 +2844,12 @@ void LLFolderBridge::performAction(LLInventoryModel* model, std::string action)
|
||||
modifyOutfit(TRUE);
|
||||
return;
|
||||
}
|
||||
else if ("cut" == action)
|
||||
{
|
||||
cutToClipboard();
|
||||
LLFolderView::removeCutItems();
|
||||
return;
|
||||
}
|
||||
else if ("copy" == action)
|
||||
{
|
||||
copyToClipboard();
|
||||
@@ -3099,6 +3123,7 @@ void LLFolderBridge::pasteFromClipboard()
|
||||
++iter)
|
||||
{
|
||||
const LLUUID& item_id = (*iter);
|
||||
|
||||
LLInventoryItem *item = model->getItem(item_id);
|
||||
LLInventoryObject *obj = model->getObject(item_id);
|
||||
if (obj)
|
||||
@@ -3158,6 +3183,8 @@ void LLFolderBridge::pasteFromClipboard()
|
||||
}
|
||||
}
|
||||
}
|
||||
// Change mode to copy for next paste
|
||||
LLInventoryClipboard::instance().setCutMode(false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3220,6 +3247,7 @@ void LLFolderBridge::pasteLinkFromClipboard()
|
||||
LLPointer<LLInventoryCallback>(NULL));
|
||||
}
|
||||
}
|
||||
//Singu Note: Don't setCutMode(false) here, we can link now but real paste later.
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -104,6 +104,12 @@ BOOL LLInventoryClipboard::hasContents() const
|
||||
return (mObjects.count() > 0);
|
||||
}
|
||||
|
||||
// returns true if the input uuid is in the list of clipboard objects.
|
||||
bool LLInventoryClipboard::isOnClipboard(const LLUUID& object) const
|
||||
{
|
||||
std::vector<LLUUID>::const_iterator iter = std::find(mObjects.begin(), mObjects.end(), object);
|
||||
return (iter != mObjects.end());
|
||||
}
|
||||
|
||||
///----------------------------------------------------------------------------
|
||||
/// Local function definitions
|
||||
|
||||
@@ -64,7 +64,11 @@ public:
|
||||
|
||||
// returns true if the clipboard has something pasteable in it.
|
||||
BOOL hasContents() const;
|
||||
// returns true if the input object uuid is on the clipboard
|
||||
bool isOnClipboard(const LLUUID& object) const;
|
||||
|
||||
bool isCutMode() const { return mCutMode; }
|
||||
void setCutMode(bool mode) { mCutMode = mode; }
|
||||
|
||||
protected:
|
||||
static LLInventoryClipboard sInstance;
|
||||
|
||||
@@ -39,6 +39,7 @@
|
||||
#include "llviewerfoldertype.h"
|
||||
#include "llagentwearables.h"
|
||||
#include "llvoavatarself.h"
|
||||
#include "llinventoryclipboard.h"
|
||||
|
||||
// linden library includes
|
||||
#include "lltrans.h"
|
||||
@@ -88,18 +89,20 @@ LLInventoryFilter::~LLInventoryFilter()
|
||||
{
|
||||
}
|
||||
|
||||
BOOL LLInventoryFilter::check(LLFolderViewItem* item)
|
||||
BOOL LLInventoryFilter::check(LLFolderViewItem* item)
|
||||
{
|
||||
// If it's a folder and we're showing all folders, return TRUE automatically.
|
||||
// Clipboard cut items are *always* filtered so we need this value upfront
|
||||
const LLFolderViewEventListener* listener = item->getListener();
|
||||
const LLUUID item_id = listener ? listener->getUUID() : LLUUID::null;
|
||||
const bool passed_clipboard = item_id.notNull() ? checkAgainstClipboard(item_id) : true;
|
||||
|
||||
// If it's a folder and we're showing all folders, return automatically.
|
||||
const BOOL is_folder = (dynamic_cast<const LLFolderViewFolder*>(item) != NULL);
|
||||
if (is_folder && (mFilterOps.mShowFolderState == LLInventoryFilter::SHOW_ALL_FOLDERS))
|
||||
{
|
||||
return TRUE;
|
||||
return passed_clipboard;
|
||||
}
|
||||
|
||||
const LLFolderViewEventListener* listener = item->getListener();
|
||||
const LLUUID item_id = listener ? listener->getUUID() : LLUUID::null;
|
||||
|
||||
mSubStringMatchOffset = mFilterSubString.size() ? item->getSearchableLabel().find(mFilterSubString) : std::string::npos;
|
||||
|
||||
const BOOL passed_filtertype = checkAgainstFilterType(item);
|
||||
@@ -109,23 +112,41 @@ BOOL LLInventoryFilter::check(LLFolderViewItem* item)
|
||||
const BOOL passed = (passed_filtertype &&
|
||||
passed_permissions &&
|
||||
passed_filterlink &&
|
||||
passed_clipboard &&
|
||||
passed_wearable &&
|
||||
(mFilterSubString.size() == 0 || mSubStringMatchOffset != std::string::npos));
|
||||
|
||||
return passed;
|
||||
}
|
||||
|
||||
bool LLInventoryFilter::checkFolder(const LLFolderViewFolder* folder)
|
||||
bool LLInventoryFilter::checkFolder(const LLFolderViewFolder* folder) const
|
||||
{
|
||||
// we're showing all folders, overriding filter
|
||||
if (mFilterOps.mShowFolderState == LLInventoryFilter::SHOW_ALL_FOLDERS)
|
||||
if (!folder)
|
||||
{
|
||||
return true;
|
||||
llwarns << "The filter can not be checked on an invalid folder." << llendl;
|
||||
llassert(false); // crash in development builds
|
||||
return false;
|
||||
}
|
||||
|
||||
const LLFolderViewEventListener* listener = folder->getListener();
|
||||
if (!listener)
|
||||
{
|
||||
llwarns << "Folder view event listener not found." << llendl;
|
||||
llassert(false); // crash in development builds
|
||||
return false;
|
||||
}
|
||||
|
||||
const LLUUID folder_id = listener->getUUID();
|
||||
|
||||
// Always check against the clipboard
|
||||
const BOOL passed_clipboard = checkAgainstClipboard(folder_id);
|
||||
|
||||
// we're showing all folders, overriding filter
|
||||
if (mFilterOps.mShowFolderState == LLInventoryFilter::SHOW_ALL_FOLDERS)
|
||||
{
|
||||
return passed_clipboard;
|
||||
}
|
||||
|
||||
if (mFilterOps.mFilterTypes & FILTERTYPE_CATEGORY)
|
||||
{
|
||||
// Can only filter categories for items in your inventory
|
||||
@@ -138,7 +159,7 @@ bool LLInventoryFilter::checkFolder(const LLFolderViewFolder* folder)
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
return passed_clipboard;
|
||||
}
|
||||
|
||||
BOOL LLInventoryFilter::checkAgainstFilterType(const LLFolderViewItem* item) const
|
||||
@@ -234,6 +255,30 @@ BOOL LLInventoryFilter::checkAgainstFilterType(const LLFolderViewItem* item) con
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// Items and folders that are on the clipboard or, recursively, in a folder which
|
||||
// is on the clipboard must be filtered out if the clipboard is in the "cut" mode.
|
||||
bool LLInventoryFilter::checkAgainstClipboard(const LLUUID& object_id) const
|
||||
{
|
||||
if (LLInventoryClipboard::instance().isCutMode())
|
||||
{
|
||||
LLUUID current_id = object_id;
|
||||
LLInventoryObject *current_object = gInventory.getObject(object_id);
|
||||
while (current_id.notNull() && current_object)
|
||||
{
|
||||
if (LLInventoryClipboard::instance().isOnClipboard(current_id))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
current_id = current_object->getParentUUID();
|
||||
if (current_id.notNull())
|
||||
{
|
||||
current_object = gInventory.getObject(current_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
BOOL LLInventoryFilter::checkAgainstPermissions(const LLFolderViewItem* item) const
|
||||
{
|
||||
const LLFolderViewEventListener* listener = item->getListener();
|
||||
|
||||
@@ -118,10 +118,11 @@ public:
|
||||
// + Execution And Results
|
||||
// +-------------------------------------------------------------------+
|
||||
BOOL check(LLFolderViewItem* item);
|
||||
bool checkFolder(const LLFolderViewFolder* folder);
|
||||
bool checkFolder(const LLFolderViewFolder* folder) const;
|
||||
BOOL checkAgainstFilterType(const LLFolderViewItem* item) const;
|
||||
BOOL checkAgainstPermissions(const LLFolderViewItem* item) const;
|
||||
BOOL checkAgainstFilterLinks(const LLFolderViewItem* item) const;
|
||||
bool checkAgainstClipboard(const LLUUID& object_id) const;
|
||||
|
||||
std::string::size_type getStringMatchOffset() const;
|
||||
|
||||
@@ -171,9 +172,9 @@ public:
|
||||
S32 getMinRequiredGeneration() const;
|
||||
S32 getMustPassGeneration() const;
|
||||
|
||||
|
||||
|
||||
|
||||
// +-------------------------------------------------------------------+
|
||||
// + Conversion
|
||||
// +-------------------------------------------------------------------+
|
||||
void toLLSD(LLSD& data) const;
|
||||
void fromLLSD(LLSD& data);
|
||||
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
#include "llagent.h"
|
||||
#include "llagentwearables.h"
|
||||
#include "llappearancemgr.h"
|
||||
#include "llinventoryclipboard.h"
|
||||
#include "llinventorypanel.h"
|
||||
#include "llinventorybridge.h"
|
||||
#include "llinventoryfunctions.h"
|
||||
@@ -1249,47 +1250,80 @@ void LLInventoryModel::purgeDescendentsOf(const LLUUID& id)
|
||||
LLPointer<LLViewerInventoryCategory> cat = getCategory(id);
|
||||
if(cat.notNull())
|
||||
{
|
||||
// do the cache accounting
|
||||
llinfos << "LLInventoryModel::purgeDescendentsOf " << cat->getName()
|
||||
<< llendl;
|
||||
S32 descendents = cat->getDescendentCount();
|
||||
if(descendents > 0)
|
||||
if (LLInventoryClipboard::instance().hasContents() && LLInventoryClipboard::instance().isCutMode())
|
||||
{
|
||||
LLCategoryUpdate up(id, -descendents);
|
||||
accountForUpdate(up);
|
||||
// Something on the clipboard is in "cut mode" and needs to be preserved
|
||||
llinfos << "LLInventoryModel::purgeDescendentsOf " << cat->getName()
|
||||
<< " iterate and purge non hidden items" << llendl;
|
||||
cat_array_t* categories;
|
||||
item_array_t* items;
|
||||
// Get the list of direct descendants in tha categoy passed as argument
|
||||
getDirectDescendentsOf(id, categories, items);
|
||||
std::vector<LLUUID> list_uuids;
|
||||
// Make a unique list with all the UUIDs of the direct descendants (items and categories are not treated differently)
|
||||
// Note: we need to do that shallow copy as purging things will invalidate the categories or items lists
|
||||
for (cat_array_t::const_iterator it = categories->begin(); it != categories->end(); ++it)
|
||||
{
|
||||
list_uuids.push_back((*it)->getUUID());
|
||||
}
|
||||
for (item_array_t::const_iterator it = items->begin(); it != items->end(); ++it)
|
||||
{
|
||||
list_uuids.push_back((*it)->getUUID());
|
||||
}
|
||||
// Iterate through the list and only purge the UUIDs that are not on the clipboard
|
||||
for (std::vector<LLUUID>::const_iterator it = list_uuids.begin(); it != list_uuids.end(); ++it)
|
||||
{
|
||||
if (!LLInventoryClipboard::instance().isOnClipboard(*it))
|
||||
{
|
||||
purgeObject(*it);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// we know that descendent count is 0, aide since the
|
||||
// accounting may actually not do an update, we should force
|
||||
// it here.
|
||||
cat->setDescendentCount(0);
|
||||
|
||||
// send it upstream
|
||||
LLMessageSystem* msg = gMessageSystem;
|
||||
msg->newMessage("PurgeInventoryDescendents");
|
||||
msg->nextBlock("AgentData");
|
||||
msg->addUUID("AgentID", gAgent.getID());
|
||||
msg->addUUID("SessionID", gAgent.getSessionID());
|
||||
msg->nextBlock("InventoryData");
|
||||
msg->addUUID("FolderID", id);
|
||||
gAgent.sendReliableMessage();
|
||||
|
||||
// unceremoniously remove anything we have locally stored.
|
||||
cat_array_t categories;
|
||||
item_array_t items;
|
||||
collectDescendents(id,
|
||||
categories,
|
||||
items,
|
||||
INCLUDE_TRASH);
|
||||
S32 count = items.count();
|
||||
for(S32 i = 0; i < count; ++i)
|
||||
else
|
||||
{
|
||||
deleteObject(items.get(i)->getUUID());
|
||||
}
|
||||
count = categories.count();
|
||||
for(S32 i = 0; i < count; ++i)
|
||||
{
|
||||
deleteObject(categories.get(i)->getUUID());
|
||||
// Fast purge
|
||||
// do the cache accounting
|
||||
llinfos << "LLInventoryModel::purgeDescendentsOf " << cat->getName()
|
||||
<< llendl;
|
||||
S32 descendents = cat->getDescendentCount();
|
||||
if(descendents > 0)
|
||||
{
|
||||
LLCategoryUpdate up(id, -descendents);
|
||||
accountForUpdate(up);
|
||||
}
|
||||
|
||||
// we know that descendent count is 0, however since the
|
||||
// accounting may actually not do an update, we should force
|
||||
// it here.
|
||||
cat->setDescendentCount(0);
|
||||
|
||||
// send it upstream
|
||||
LLMessageSystem* msg = gMessageSystem;
|
||||
msg->newMessage("PurgeInventoryDescendents");
|
||||
msg->nextBlock("AgentData");
|
||||
msg->addUUID("AgentID", gAgent.getID());
|
||||
msg->addUUID("SessionID", gAgent.getSessionID());
|
||||
msg->nextBlock("InventoryData");
|
||||
msg->addUUID("FolderID", id);
|
||||
gAgent.sendReliableMessage();
|
||||
|
||||
// unceremoniously remove anything we have locally stored.
|
||||
cat_array_t categories;
|
||||
item_array_t items;
|
||||
collectDescendents(id,
|
||||
categories,
|
||||
items,
|
||||
INCLUDE_TRASH);
|
||||
S32 count = items.count();
|
||||
for(S32 i = 0; i < count; ++i)
|
||||
{
|
||||
deleteObject(items.get(i)->getUUID());
|
||||
}
|
||||
count = categories.count();
|
||||
for(S32 i = 0; i < count; ++i)
|
||||
{
|
||||
deleteObject(categories.get(i)->getUUID());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2908,7 +2942,7 @@ void LLInventoryModel::processBulkUpdateInventory(LLMessageSystem* msg, void**)
|
||||
{
|
||||
LLPointer<LLViewerInventoryCategory> tfolder = new LLViewerInventoryCategory(gAgent.getID());
|
||||
tfolder->unpackMessage(msg, _PREHASH_FolderData, i);
|
||||
//llinfos << "unpaked folder '" << tfolder->getName() << "' ("
|
||||
//llinfos << "unpacked folder '" << tfolder->getName() << "' ("
|
||||
// << tfolder->getUUID() << ") in " << tfolder->getParentUUID()
|
||||
// << llendl;
|
||||
if(tfolder->getUUID().notNull())
|
||||
@@ -2964,7 +2998,7 @@ void LLInventoryModel::processBulkUpdateInventory(LLMessageSystem* msg, void**)
|
||||
{
|
||||
LLPointer<LLViewerInventoryItem> titem = new LLViewerInventoryItem;
|
||||
titem->unpackMessage(msg, _PREHASH_ItemData, i);
|
||||
//llinfos << "unpaked item '" << titem->getName() << "' in "
|
||||
//llinfos << "unpacked item '" << titem->getName() << "' in "
|
||||
// << titem->getParentUUID() << llendl;
|
||||
U32 callback_id;
|
||||
msg->getU32Fast(_PREHASH_ItemData, _PREHASH_CallbackID, callback_id);
|
||||
@@ -3261,6 +3295,30 @@ void LLInventoryModel::removeCategory(const LLUUID& category_id)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LLInventoryModel::removeObject(const LLUUID& object_id)
|
||||
{
|
||||
LLInventoryObject* obj = getObject(object_id);
|
||||
if (dynamic_cast<LLViewerInventoryItem*>(obj))
|
||||
{
|
||||
removeItem(object_id);
|
||||
}
|
||||
else if (dynamic_cast<LLViewerInventoryCategory*>(obj))
|
||||
{
|
||||
removeCategory(object_id);
|
||||
}
|
||||
else if (obj)
|
||||
{
|
||||
LL_WARNS("Inventory") << "object ID " << object_id
|
||||
<< " is an object of unrecognized class "
|
||||
<< typeid(*obj).name() << LL_ENDL;
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_WARNS("Inventory") << "object ID " << object_id << " not found" << LL_ENDL;
|
||||
}
|
||||
}
|
||||
|
||||
const LLUUID &LLInventoryModel::getRootFolderID() const
|
||||
{
|
||||
return mRootFolderID;
|
||||
|
||||
@@ -186,6 +186,10 @@
|
||||
<on_click filter="" function="Inventory.DoToSelected" userdata="acquire_asset_id" />
|
||||
</menu_item_call>
|
||||
<menu_item_separator name="Copy Separator" />
|
||||
<menu_item_call bottom_delta="-18" height="18" label="Cut" left="0" mouse_opaque="true"
|
||||
name="Cut" width="128">
|
||||
<on_click filter="" function="Inventory.DoToSelected" userdata="cut" />
|
||||
</menu_item_call>
|
||||
<menu_item_call bottom_delta="-18" height="18" label="Copy" left="0" mouse_opaque="true"
|
||||
name="Copy" width="128">
|
||||
<on_click filter="" function="Inventory.DoToSelected" userdata="copy" />
|
||||
|
||||
Reference in New Issue
Block a user