diff options
Diffstat (limited to 'indra/newview/llinventorybridge.cpp')
-rw-r--r-- | indra/newview/llinventorybridge.cpp | 227 |
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); } } } |