summaryrefslogtreecommitdiff
path: root/indra/newview/llinventorybridge.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview/llinventorybridge.cpp')
-rw-r--r--indra/newview/llinventorybridge.cpp227
1 files changed, 191 insertions, 36 deletions
diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp
index f582207614..73005d6903 100644
--- a/indra/newview/llinventorybridge.cpp
+++ b/indra/newview/llinventorybridge.cpp
@@ -162,6 +162,65 @@ public:
}
};
+class LLPasteIntoFolderCallback: public LLInventoryCallback
+{
+public:
+ LLPasteIntoFolderCallback(LLHandle<LLInventoryPanel>& handle)
+ : mInventoryPanel(handle)
+ {
+ }
+ ~LLPasteIntoFolderCallback()
+ {
+ processItems();
+ }
+
+ void fire(const LLUUID& inv_item)
+ {
+ mChangedIds.push_back(inv_item);
+ }
+
+ void processItems()
+ {
+ LLInventoryPanel* panel = mInventoryPanel.get();
+ bool has_elements = false;
+ for (LLUUID& inv_item : mChangedIds)
+ {
+ LLInventoryItem* item = gInventory.getItem(inv_item);
+ if (item && panel)
+ {
+ LLUUID root_id = panel->getRootFolderID();
+
+ if (inv_item == root_id)
+ {
+ return;
+ }
+
+ LLFolderViewItem* item = panel->getItemByID(inv_item);
+ if (item)
+ {
+ if (!has_elements)
+ {
+ panel->clearSelection();
+ panel->getRootFolder()->clearSelection();
+ panel->getRootFolder()->requestArrange();
+ panel->getRootFolder()->update();
+ has_elements = true;
+ }
+ panel->getRootFolder()->changeSelection(item, TRUE);
+ }
+ }
+ }
+
+ if (has_elements)
+ {
+ panel->getRootFolder()->scrollToShowSelection();
+ }
+ }
+private:
+ LLHandle<LLInventoryPanel> mInventoryPanel;
+ std::vector<LLUUID> mChangedIds;
+};
+
// +=================================================+
// | LLInvFVBridge |
// +=================================================+
@@ -2262,13 +2321,32 @@ void LLFolderBridge::buildDisplayName() const
std::string LLFolderBridge::getLabelSuffix() const
{
static LLCachedControl<F32> folder_loading_message_delay(gSavedSettings, "FolderLoadingMessageWaitTime", 0.5f);
+ static LLCachedControl<bool> xui_debug(gSavedSettings, "DebugShowXUINames", 0);
if (mIsLoading && mTimeSinceRequestStart.getElapsedTimeF32() >= folder_loading_message_delay())
{
return llformat(" ( %s ) ", LLTrans::getString("LoadingData").c_str());
}
std::string suffix = "";
- if(mShowDescendantsCount)
+ if (xui_debug)
+ {
+ LLInventoryModel::cat_array_t* cats;
+ LLInventoryModel::item_array_t* items;
+ gInventory.getDirectDescendentsOf(getUUID(), cats, items);
+
+ LLViewerInventoryCategory* cat = gInventory.getCategory(getUUID());
+ if (cat)
+ {
+ LLStringUtil::format_map_t args;
+ args["[FOLDER_COUNT]"] = llformat("%d", cats->size());
+ args["[ITEMS_COUNT]"] = llformat("%d", items->size());
+ args["[VERSION]"] = llformat("%d", cat->getVersion());
+ args["[VIEWER_DESCENDANT_COUNT]"] = llformat("%d", cats->size() + items->size());
+ args["[SERVER_DESCENDANT_COUNT]"] = llformat("%d", cat->getDescendentCount());
+ suffix = " " + LLTrans::getString("InventoryFolderDebug", args);
+ }
+ }
+ else if(mShowDescendantsCount)
{
LLInventoryModel::cat_array_t cat_array;
LLInventoryModel::item_array_t item_array;
@@ -2512,7 +2590,8 @@ BOOL LLFolderBridge::dragCategoryIntoFolder(LLInventoryCategory* inv_cat,
BOOL drop,
std::string& tooltip_msg,
BOOL is_link,
- BOOL user_confirm)
+ BOOL user_confirm,
+ LLPointer<LLInventoryCallback> cb)
{
LLInventoryModel* model = getInventoryModel();
@@ -2817,7 +2896,7 @@ BOOL LLFolderBridge::dragCategoryIntoFolder(LLInventoryCategory* inv_cat,
{
// Category can contains objects,
// create a new folder and populate it with links to original objects
- dropToMyOutfits(inv_cat);
+ dropToMyOutfits(inv_cat, cb);
}
// if target is current outfit folder we use link
else if (move_is_into_current_outfit &&
@@ -2827,10 +2906,12 @@ BOOL LLFolderBridge::dragCategoryIntoFolder(LLInventoryCategory* inv_cat,
// traverse category and add all contents to currently worn.
BOOL append = true;
LLAppearanceMgr::instance().wearInventoryCategory(inv_cat, false, append);
+ if (cb) cb->fire(inv_cat->getUUID());
}
else if (move_is_into_marketplacelistings)
{
move_folder_to_marketplacelistings(inv_cat, mUUID);
+ if (cb) cb->fire(inv_cat->getUUID());
}
else
{
@@ -2846,6 +2927,7 @@ BOOL LLFolderBridge::dragCategoryIntoFolder(LLInventoryCategory* inv_cat,
(LLViewerInventoryCategory*)inv_cat,
mUUID,
move_is_into_trash);
+ if (cb) cb->fire(inv_cat->getUUID());
}
if (move_is_from_marketplacelistings)
{
@@ -2877,6 +2959,7 @@ BOOL LLFolderBridge::dragCategoryIntoFolder(LLInventoryCategory* inv_cat,
}
// In all cases, update the listing we moved from so suffix are updated
update_marketplace_category(from_folder_uuid);
+ if (cb) cb->fire(inv_cat->getUUID());
}
}
}
@@ -2890,7 +2973,22 @@ BOOL LLFolderBridge::dragCategoryIntoFolder(LLInventoryCategory* inv_cat,
}
else
{
- accept = move_inv_category_world_to_agent(cat_id, mUUID, drop, NULL, NULL, filter);
+ // Todo: fix me. moving from task inventory doesn't have a completion callback,
+ // yet making a copy creates new item id so this doesn't work right
+ std::function<void(S32, void*, const LLMoveInv*)> callback = [cb](S32, void*, const LLMoveInv* move_inv) mutable
+ {
+ two_uuids_list_t::const_iterator move_it;
+ for (move_it = move_inv->mMoveList.begin();
+ move_it != move_inv->mMoveList.end();
+ ++move_it)
+ {
+ if (cb)
+ {
+ cb->fire(move_it->second);
+ }
+ }
+ };
+ accept = move_inv_category_world_to_agent(cat_id, mUUID, drop, callback, NULL, filter);
}
}
else if (LLToolDragAndDrop::SOURCE_LIBRARY == source)
@@ -2961,7 +3059,7 @@ void warn_move_inventory(LLViewerObject* object, boost::shared_ptr<LLMoveInv> mo
BOOL move_inv_category_world_to_agent(const LLUUID& object_id,
const LLUUID& category_id,
BOOL drop,
- void (*callback)(S32, void*),
+ std::function<void(S32, void*, const LLMoveInv*)> callback,
void* user_data,
LLInventoryFilter* filter)
{
@@ -3816,6 +3914,13 @@ void LLFolderBridge::perform_pasteFromClipboard()
std::vector<LLUUID> objects;
LLClipboard::instance().pasteFromClipboard(objects);
+
+ LLPointer<LLInventoryCallback> cb = NULL;
+ LLInventoryPanel* panel = mInventoryPanel.get();
+ if (panel->getRootFolder()->isSingleFolderMode() && panel->getRootFolderID() == mUUID)
+ {
+ cb = new LLPasteIntoFolderCallback(mInventoryPanel);
+ }
LLViewerInventoryCategory * dest_folder = getCategory();
if (move_is_into_marketplacelistings)
@@ -3891,7 +3996,7 @@ void LLFolderBridge::perform_pasteFromClipboard()
{
if (!move_is_into_my_outfits && item && can_move_to_outfit(item, move_is_into_current_outfit))
{
- dropToOutfit(item, move_is_into_current_outfit);
+ dropToOutfit(item, move_is_into_current_outfit, cb);
}
else if (move_is_into_my_outfits && LLAssetType::AT_CATEGORY == obj->getType())
{
@@ -3899,7 +4004,7 @@ void LLFolderBridge::perform_pasteFromClipboard()
U32 max_items_to_wear = gSavedSettings.getU32("WearFolderLimit");
if (cat && can_move_to_my_outfits(model, cat, max_items_to_wear))
{
- dropToMyOutfits(cat);
+ dropToMyOutfits(cat, cb);
}
else
{
@@ -3915,7 +4020,7 @@ void LLFolderBridge::perform_pasteFromClipboard()
{
if (item && can_move_to_outfit(item, move_is_into_current_outfit))
{
- dropToOutfit(item, move_is_into_current_outfit);
+ dropToOutfit(item, move_is_into_current_outfit, cb);
}
else
{
@@ -3934,11 +4039,12 @@ void LLFolderBridge::perform_pasteFromClipboard()
{
//changeItemParent() implicity calls dirtyFilter
changeItemParent(model, viitem, parent_id, FALSE);
+ if (cb) cb->fire(item_id);
}
}
else
{
- dropToFavorites(item);
+ dropToFavorites(item, cb);
}
}
}
@@ -3966,6 +4072,7 @@ void LLFolderBridge::perform_pasteFromClipboard()
//changeCategoryParent() implicity calls dirtyFilter
changeCategoryParent(model, vicat, parent_id, FALSE);
}
+ if (cb) cb->fire(item_id);
}
}
else
@@ -3987,6 +4094,7 @@ void LLFolderBridge::perform_pasteFromClipboard()
//changeItemParent() implicity calls dirtyFilter
changeItemParent(model, viitem, parent_id, FALSE);
}
+ if (cb) cb->fire(item_id);
}
}
}
@@ -4007,6 +4115,7 @@ void LLFolderBridge::perform_pasteFromClipboard()
{
copy_inventory_category(model, vicat, parent_id);
}
+ if (cb) cb->fire(item_id);
}
}
else
@@ -4022,11 +4131,13 @@ void LLFolderBridge::perform_pasteFromClipboard()
// Stop pasting into the marketplace as soon as we get an error
break;
}
+ if (cb) cb->fire(item_id);
}
else if (item->getIsLinkType())
{
- link_inventory_object(parent_id, item_id,
- LLPointer<LLInventoryCallback>(NULL));
+ link_inventory_object(parent_id,
+ item_id,
+ cb);
}
else
{
@@ -4036,7 +4147,7 @@ void LLFolderBridge::perform_pasteFromClipboard()
item->getUUID(),
parent_id,
std::string(),
- LLPointer<LLInventoryCallback>(NULL));
+ cb);
}
}
}
@@ -4072,6 +4183,14 @@ void LLFolderBridge::pasteLinkFromClipboard()
std::vector<LLUUID> objects;
LLClipboard::instance().pasteFromClipboard(objects);
+
+ LLPointer<LLInventoryCallback> cb = NULL;
+ LLInventoryPanel* panel = mInventoryPanel.get();
+ if (panel->getRootFolder()->isSingleFolderMode())
+ {
+ cb = new LLPasteIntoFolderCallback(mInventoryPanel);
+ }
+
for (std::vector<LLUUID>::const_iterator iter = objects.begin();
iter != objects.end();
++iter)
@@ -4082,12 +4201,12 @@ void LLFolderBridge::pasteLinkFromClipboard()
LLInventoryItem *item = model->getItem(object_id);
if (item && can_move_to_outfit(item, move_is_into_current_outfit))
{
- dropToOutfit(item, move_is_into_current_outfit);
+ dropToOutfit(item, move_is_into_current_outfit, cb);
}
}
else if (LLConstPointer<LLInventoryObject> obj = model->getObject(object_id))
{
- link_inventory_object(parent_id, obj, LLPointer<LLInventoryCallback>(NULL));
+ link_inventory_object(parent_id, obj, cb);
}
}
// Change mode to paste for next paste
@@ -4520,6 +4639,18 @@ BOOL LLFolderBridge::dragOrDrop(MASK mask, BOOL drop,
{
LLInventoryItem* inv_item = (LLInventoryItem*)cargo_data;
+ static LLPointer<LLInventoryCallback> drop_cb = NULL;
+ LLInventoryPanel* panel = mInventoryPanel.get();
+ LLToolDragAndDrop* drop_tool = LLToolDragAndDrop::getInstance();
+ if (drop
+ && panel->getRootFolder()->isSingleFolderMode()
+ && panel->getRootFolderID() == mUUID
+ && drop_tool->getCargoIndex() == 0)
+ {
+ drop_cb = new LLPasteIntoFolderCallback(mInventoryPanel);
+ }
+
+
//LL_INFOS() << "LLFolderBridge::dragOrDrop()" << LL_ENDL;
BOOL accept = FALSE;
switch(cargo_type)
@@ -4537,7 +4668,7 @@ BOOL LLFolderBridge::dragOrDrop(MASK mask, BOOL drop,
case DAD_GESTURE:
case DAD_MESH:
case DAD_SETTINGS:
- accept = dragItemIntoFolder(inv_item, drop, tooltip_msg);
+ accept = dragItemIntoFolder(inv_item, drop, tooltip_msg, TRUE, drop_cb);
break;
case DAD_LINK:
// DAD_LINK type might mean one of two asset types: AT_LINK or AT_LINK_FOLDER.
@@ -4548,12 +4679,12 @@ BOOL LLFolderBridge::dragOrDrop(MASK mask, BOOL drop,
LLInventoryCategory* linked_category = gInventory.getCategory(inv_item->getLinkedUUID());
if (linked_category)
{
- accept = dragCategoryIntoFolder((LLInventoryCategory*)linked_category, drop, tooltip_msg, TRUE);
+ accept = dragCategoryIntoFolder((LLInventoryCategory*)linked_category, drop, tooltip_msg, TRUE, TRUE, drop_cb);
}
}
else
{
- accept = dragItemIntoFolder(inv_item, drop, tooltip_msg);
+ accept = dragItemIntoFolder(inv_item, drop, tooltip_msg, TRUE, drop_cb);
}
break;
case DAD_CATEGORY:
@@ -4563,7 +4694,7 @@ BOOL LLFolderBridge::dragOrDrop(MASK mask, BOOL drop,
}
else
{
- accept = dragCategoryIntoFolder((LLInventoryCategory*)cargo_data, drop, tooltip_msg);
+ accept = dragCategoryIntoFolder((LLInventoryCategory*)cargo_data, drop, tooltip_msg, FALSE, TRUE, drop_cb);
}
break;
case DAD_ROOT_CATEGORY:
@@ -4573,6 +4704,11 @@ BOOL LLFolderBridge::dragOrDrop(MASK mask, BOOL drop,
LL_WARNS() << "Unhandled cargo type for drag&drop " << cargo_type << LL_ENDL;
break;
}
+
+ if (!drop || drop_tool->getCargoIndex() + 1 == drop_tool->getCargoCount())
+ {
+ drop_cb = NULL;
+ }
return accept;
}
@@ -4873,36 +5009,48 @@ bool move_task_inventory_callback(const LLSD& notification, const LLSD& response
if (move_inv->mCallback)
{
- move_inv->mCallback(option, move_inv->mUserData);
+ move_inv->mCallback(option, move_inv->mUserData, move_inv.get());
}
move_inv.reset(); //since notification will persist
return false;
}
-void LLFolderBridge::dropToFavorites(LLInventoryItem* inv_item)
+void drop_to_favorites_cb(const LLUUID& id, LLPointer<LLInventoryCallback> cb1, LLPointer<LLInventoryCallback> cb2)
+{
+ cb1->fire(id);
+ cb2->fire(id);
+}
+
+void LLFolderBridge::dropToFavorites(LLInventoryItem* inv_item, LLPointer<LLInventoryCallback> cb)
{
// use callback to rearrange favorite landmarks after adding
// to have new one placed before target (on which it was dropped). See EXT-4312.
- LLPointer<AddFavoriteLandmarkCallback> cb = new AddFavoriteLandmarkCallback();
+ LLPointer<AddFavoriteLandmarkCallback> cb_fav = new AddFavoriteLandmarkCallback();
LLInventoryPanel* panel = mInventoryPanel.get();
LLFolderViewItem* drag_over_item = panel ? panel->getRootFolder()->getDraggingOverItem() : NULL;
LLFolderViewModelItemInventory* view_model = drag_over_item ? static_cast<LLFolderViewModelItemInventory*>(drag_over_item->getViewModelItem()) : NULL;
if (view_model)
{
- cb.get()->setTargetLandmarkId(view_model->getUUID());
+ cb_fav.get()->setTargetLandmarkId(view_model->getUUID());
}
+ LLPointer <LLInventoryCallback> callback = cb_fav;
+ if (cb)
+ {
+ callback = new LLBoostFuncInventoryCallback(boost::bind(drop_to_favorites_cb, _1, cb, cb_fav));
+ }
+
copy_inventory_item(
gAgent.getID(),
inv_item->getPermissions().getOwner(),
inv_item->getUUID(),
mUUID,
std::string(),
- cb);
+ callback);
}
-void LLFolderBridge::dropToOutfit(LLInventoryItem* inv_item, BOOL move_is_into_current_outfit)
+void LLFolderBridge::dropToOutfit(LLInventoryItem* inv_item, BOOL move_is_into_current_outfit, LLPointer<LLInventoryCallback> cb)
{
if((inv_item->getInventoryType() == LLInventoryType::IT_TEXTURE) || (inv_item->getInventoryType() == LLInventoryType::IT_SNAPSHOT))
{
@@ -4927,14 +5075,14 @@ void LLFolderBridge::dropToOutfit(LLInventoryItem* inv_item, BOOL move_is_into_c
}
}
-void LLFolderBridge::dropToMyOutfits(LLInventoryCategory* inv_cat)
+void LLFolderBridge::dropToMyOutfits(LLInventoryCategory* inv_cat, LLPointer<LLInventoryCallback> cb)
{
// make a folder in the My Outfits directory.
const LLUUID dest_id = getInventoryModel()->findCategoryUUIDForType(LLFolderType::FT_MY_OUTFITS);
// Note: creation will take time, so passing folder id to callback is slightly unreliable,
// but so is collecting and passing descendants' ids
- inventory_func_type func = boost::bind(&LLFolderBridge::outfitFolderCreatedCallback, this, inv_cat->getUUID(), _1);
+ inventory_func_type func = boost::bind(&LLFolderBridge::outfitFolderCreatedCallback, this, inv_cat->getUUID(), _1, cb);
gInventory.createNewCategory(dest_id,
LLFolderType::FT_OUTFIT,
inv_cat->getName(),
@@ -4942,7 +5090,7 @@ void LLFolderBridge::dropToMyOutfits(LLInventoryCategory* inv_cat)
inv_cat->getThumbnailUUID());
}
-void LLFolderBridge::outfitFolderCreatedCallback(LLUUID cat_source_id, LLUUID cat_dest_id)
+void LLFolderBridge::outfitFolderCreatedCallback(LLUUID cat_source_id, LLUUID cat_dest_id, LLPointer<LLInventoryCallback> cb)
{
LLInventoryModel::cat_array_t* categories;
LLInventoryModel::item_array_t* items;
@@ -4973,7 +5121,6 @@ void LLFolderBridge::outfitFolderCreatedCallback(LLUUID cat_source_id, LLUUID ca
if (!link_array.empty())
{
- LLPointer<LLInventoryCallback> cb = NULL;
link_inventory_array(cat_dest_id, link_array, cb);
}
}
@@ -5006,7 +5153,8 @@ void LLFolderBridge::callback_dropCategoryIntoFolder(const LLSD& notification, c
BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item,
BOOL drop,
std::string& tooltip_msg,
- BOOL user_confirm)
+ BOOL user_confirm,
+ LLPointer<LLInventoryCallback> cb)
{
LLInventoryModel* model = getInventoryModel();
@@ -5186,19 +5334,20 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item,
// (copy the item)
else if (move_is_into_favorites)
{
- dropToFavorites(inv_item);
+ dropToFavorites(inv_item, cb);
}
// CURRENT OUTFIT or OUTFIT folder
// (link the item)
else if (move_is_into_current_outfit || move_is_into_outfit)
{
- dropToOutfit(inv_item, move_is_into_current_outfit);
+ dropToOutfit(inv_item, move_is_into_current_outfit, cb);
}
// MARKETPLACE LISTINGS folder
// Move the item
else if (move_is_into_marketplacelistings)
{
move_item_to_marketplacelistings(inv_item, mUUID);
+ if (cb) cb->fire(inv_item->getUUID());
}
// NORMAL or TRASH folder
// (move the item, restamp if into trash)
@@ -5215,6 +5364,7 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item,
(LLViewerInventoryItem*)inv_item,
mUUID,
move_is_into_trash);
+ if (cb) cb->fire(inv_item->getUUID());
}
if (move_is_from_marketplacelistings)
@@ -5299,11 +5449,16 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item,
if (accept && drop)
{
+ LLUUID item_id = inv_item->getUUID();
boost::shared_ptr<LLMoveInv> move_inv (new LLMoveInv());
move_inv->mObjectID = inv_item->getParentUUID();
- two_uuids_t item_pair(mUUID, inv_item->getUUID());
+ two_uuids_t item_pair(mUUID, item_id);
move_inv->mMoveList.push_back(item_pair);
- move_inv->mCallback = NULL;
+ if (cb)
+ {
+ move_inv->mCallback = [item_id, cb](S32, void*, const LLMoveInv* move_inv) mutable
+ { cb->fire(item_id); };
+ }
move_inv->mUserData = NULL;
if(is_move)
{
@@ -5395,13 +5550,13 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item,
// (copy the item)
if (move_is_into_favorites)
{
- dropToFavorites(inv_item);
+ dropToFavorites(inv_item, cb);
}
// CURRENT OUTFIT or OUTFIT folder
// (link the item)
else if (move_is_into_current_outfit || move_is_into_outfit)
{
- dropToOutfit(inv_item, move_is_into_current_outfit);
+ dropToOutfit(inv_item, move_is_into_current_outfit, cb);
}
else
{
@@ -5411,7 +5566,7 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item,
inv_item->getUUID(),
mUUID,
std::string(),
- LLPointer<LLInventoryCallback>(NULL));
+ cb);
}
}
}