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.cpp836
1 files changed, 502 insertions, 334 deletions
diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp
index cb009ef1ee..385a2569a5 100644
--- a/indra/newview/llinventorybridge.cpp
+++ b/indra/newview/llinventorybridge.cpp
@@ -41,7 +41,6 @@
#include "llfloateropenobject.h"
#include "llfloaterreg.h"
#include "llfloatermarketplacelistings.h"
-#include "llfloateroutfitphotopreview.h"
#include "llfloatersidepanelcontainer.h"
#include "llsidepanelinventory.h"
#include "llfloaterworldmap.h"
@@ -90,30 +89,14 @@
void copy_slurl_to_clipboard_callback_inv(const std::string& slurl);
-typedef std::pair<LLUUID, LLUUID> two_uuids_t;
-typedef std::list<two_uuids_t> two_uuids_list_t;
-
const F32 SOUND_GAIN = 1.0f;
const F32 FOLDER_LOADING_MESSAGE_DELAY = 0.5f; // Seconds to wait before showing the LOADING... text in folder views
-struct LLMoveInv
-{
- LLUUID mObjectID;
- LLUUID mCategoryID;
- two_uuids_list_t mMoveList;
- void (*mCallback)(S32, void*);
- void* mUserData;
-};
-
using namespace LLOldEvents;
// Function declarations
-bool move_task_inventory_callback(const LLSD& notification, const LLSD& response, boost::shared_ptr<LLMoveInv>);
bool confirm_attachment_rez(const LLSD& notification, const LLSD& response);
void teleport_via_landmark(const LLUUID& asset_id);
-static BOOL can_move_to_outfit(LLInventoryItem* inv_item, BOOL move_is_into_current_outfit);
-static bool can_move_to_my_outfits(LLInventoryModel* model, LLInventoryCategory* inv_cat, U32 wear_limit);
-static BOOL can_move_to_landmarks(LLInventoryItem* inv_item);
static bool check_category(LLInventoryModel* model,
const LLUUID& cat_id,
LLInventoryPanel* active_panel,
@@ -139,6 +122,12 @@ bool isMarketplaceSendAction(const std::string& action)
return ("send_to_marketplace" == action);
}
+bool isPanelActive(const std::string& panel_name)
+{
+ LLInventoryPanel *active_panel = LLInventoryPanel::getActiveInventoryPanel(FALSE);
+ return (active_panel && (active_panel->getName() == panel_name));
+}
+
// Used by LLFolderBridge as callback for directory fetching recursion
class LLRightClickInventoryFetchDescendentsObserver : public LLInventoryFetchDescendentsObserver
{
@@ -174,6 +163,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 |
// +=================================================+
@@ -213,54 +261,17 @@ const std::string& LLInvFVBridge::getDisplayName() const
std::string LLInvFVBridge::getSearchableDescription() const
{
- const LLInventoryModel* model = getInventoryModel();
- if (model)
- {
- const LLInventoryItem *item = model->getItem(mUUID);
- if(item)
- {
- std::string desc = item->getDescription();
- LLStringUtil::toUpper(desc);
- return desc;
- }
- }
- return LLStringUtil::null;
+ return get_searchable_description(getInventoryModel(), mUUID);
}
std::string LLInvFVBridge::getSearchableCreatorName() const
{
- const LLInventoryModel* model = getInventoryModel();
- if (model)
- {
- const LLInventoryItem *item = model->getItem(mUUID);
- if(item)
- {
- LLAvatarName av_name;
- if (LLAvatarNameCache::get(item->getCreatorUUID(), &av_name))
- {
- std::string username = av_name.getUserName();
- LLStringUtil::toUpper(username);
- return username;
- }
- }
- }
- return LLStringUtil::null;
+ return get_searchable_creator_name(getInventoryModel(), mUUID);
}
std::string LLInvFVBridge::getSearchableUUIDString() const
{
- const LLInventoryModel* model = getInventoryModel();
- if (model)
- {
- const LLViewerInventoryItem *item = model->getItem(mUUID);
- if(item && (item->getIsFullPerm() || gAgent.isGodlikeWithoutAdminMenuFakery()))
- {
- std::string uuid = item->getAssetUUID().asString();
- LLStringUtil::toUpper(uuid);
- return uuid;
- }
- }
- return LLStringUtil::null;
+ return get_searchable_UUID(getInventoryModel(), mUUID);
}
// Folders have full perms
@@ -328,7 +339,7 @@ BOOL LLInvFVBridge::cutToClipboard()
const LLInventoryObject* obj = gInventory.getObject(mUUID);
if (obj && isItemMovable() && isItemRemovable())
{
- const LLUUID &marketplacelistings_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS, false);
+ const LLUUID &marketplacelistings_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS);
const BOOL cut_from_marketplacelistings = gInventory.isObjectDescendentOf(mUUID, marketplacelistings_id);
if (cut_from_marketplacelistings && (LLMarketplaceData::instance().isInActiveFolder(mUUID) ||
@@ -408,6 +419,32 @@ void LLInvFVBridge::showProperties()
}
}
+void LLInvFVBridge::navigateToFolder(bool new_window, bool change_mode)
+{
+ if(new_window)
+ {
+ mInventoryPanel.get()->openSingleViewInventory(mUUID);
+ }
+ else
+ {
+ if(change_mode)
+ {
+ LLInventoryPanel::setSFViewAndOpenFolder(mInventoryPanel.get(), mUUID);
+ }
+ else
+ {
+ LLInventorySingleFolderPanel* panel = dynamic_cast<LLInventorySingleFolderPanel*>(mInventoryPanel.get());
+ if (!panel || !getInventoryModel() || mUUID.isNull())
+ {
+ return;
+ }
+
+ panel->changeFolderRoot(mUUID);
+ }
+
+ }
+}
+
void LLInvFVBridge::removeBatch(std::vector<LLFolderViewModelItem*>& batch)
{
// Deactivate gestures when moving them into Trash
@@ -801,6 +838,7 @@ void LLInvFVBridge::getClipboardEntries(bool show_asset_id,
menuentry_vec_t &disabled_items, U32 flags)
{
const LLInventoryObject *obj = getInventoryObject();
+ bool single_folder_root = (mRoot == NULL);
if (obj)
{
@@ -812,7 +850,7 @@ void LLInvFVBridge::getClipboardEntries(bool show_asset_id,
disabled_items.push_back(std::string("Copy"));
}
- if (isAgentInventory())
+ if (isAgentInventory() && !single_folder_root)
{
items.push_back(std::string("New folder from selected"));
items.push_back(std::string("Subfolder Separator"));
@@ -846,7 +884,7 @@ void LLInvFVBridge::getClipboardEntries(bool show_asset_id,
items.push_back(std::string("Find Links"));
}
- if (!isInboxFolder())
+ if (!isInboxFolder() && !single_folder_root)
{
items.push_back(std::string("Rename"));
if (!isItemRenameable() || ((flags & FIRST_SELECTED_ITEM) == 0))
@@ -854,14 +892,20 @@ void LLInvFVBridge::getClipboardEntries(bool show_asset_id,
disabled_items.push_back(std::string("Rename"));
}
}
-
+
+ items.push_back(std::string("thumbnail"));
+ if (isLibraryItem())
+ {
+ disabled_items.push_back(std::string("thumbnail"));
+ }
+
+ LLViewerInventoryItem *inv_item = gInventory.getItem(mUUID);
if (show_asset_id)
{
items.push_back(std::string("Copy Asset UUID"));
bool is_asset_knowable = false;
- LLViewerInventoryItem* inv_item = gInventory.getItem(mUUID);
if (inv_item)
{
is_asset_knowable = LLAssetType::lookupIsAssetIDKnowable(inv_item->getType());
@@ -874,6 +918,8 @@ void LLInvFVBridge::getClipboardEntries(bool show_asset_id,
}
}
+ if(!single_folder_root)
+ {
items.push_back(std::string("Cut"));
if (!isItemMovable() || !isItemRemovable())
{
@@ -895,6 +941,7 @@ void LLInvFVBridge::getClipboardEntries(bool show_asset_id,
}
}
}
+ }
}
}
@@ -920,16 +967,12 @@ void LLInvFVBridge::getClipboardEntries(bool show_asset_id,
items.push_back(std::string("Paste Separator"));
- addDeleteContextMenuOptions(items, disabled_items);
-
- // If multiple items are selected, disable properties (if it exists).
- if ((flags & FIRST_SELECTED_ITEM) == 0)
- {
- disabled_items.push_back(std::string("Properties"));
- }
+ if(!single_folder_root)
+ {
+ addDeleteContextMenuOptions(items, disabled_items);
+ }
- LLInventoryPanel *active_panel = LLInventoryPanel::getActiveInventoryPanel(FALSE);
- if (active_panel && (active_panel->getName() != "All Items"))
+ if (!isPanelActive("All Items") && !isPanelActive("comb_single_folder_inv"))
{
items.push_back(std::string("Show in Main Panel"));
}
@@ -1020,7 +1063,7 @@ void LLInvFVBridge::addDeleteContextMenuOptions(menuentry_vec_t &items,
items.push_back(std::string("Delete"));
- if (!isItemRemovable())
+ if (!isItemRemovable() || isPanelActive("Favorite Items"))
{
disabled_items.push_back(std::string("Delete"));
}
@@ -1251,6 +1294,16 @@ BOOL LLInvFVBridge::isLinkedObjectInTrash() const
return FALSE;
}
+bool LLInvFVBridge::isItemInOutfits() const
+{
+ const LLInventoryModel* model = getInventoryModel();
+ if(!model) return false;
+
+ const LLUUID my_outfits_cat = gInventory.findCategoryUUIDForType(LLFolderType::FT_MY_OUTFITS);
+
+ return isCOFFolder() || (my_outfits_cat == mUUID) || model->isObjectDescendentOf(mUUID, my_outfits_cat);
+}
+
BOOL LLInvFVBridge::isLinkedObjectMissing() const
{
const LLInventoryObject *obj = getInventoryObject();
@@ -1281,7 +1334,7 @@ BOOL LLInvFVBridge::isCOFFolder() const
// *TODO : Suppress isInboxFolder() once Merchant Outbox is fully deprecated
BOOL LLInvFVBridge::isInboxFolder() const
{
- const LLUUID inbox_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_INBOX, false);
+ const LLUUID inbox_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_INBOX);
if (inbox_id.isNull())
{
@@ -1293,7 +1346,7 @@ BOOL LLInvFVBridge::isInboxFolder() const
BOOL LLInvFVBridge::isMarketplaceListingsFolder() const
{
- const LLUUID folder_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS, false);
+ const LLUUID folder_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS);
if (folder_id.isNull())
{
@@ -1593,7 +1646,7 @@ bool LLInvFVBridge::canListOnMarketplaceNow() const
{
std::string error_msg;
LLInventoryModel* model = getInventoryModel();
- const LLUUID &marketplacelistings_id = model->findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS, false);
+ const LLUUID &marketplacelistings_id = model->findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS);
if (marketplacelistings_id.notNull())
{
LLViewerInventoryCategory * master_folder = model->getCategory(marketplacelistings_id);
@@ -1692,6 +1745,12 @@ void LLItemBridge::performAction(LLInventoryModel* model, std::string action)
restoreItem();
return;
}
+ else if ("thumbnail" == action)
+ {
+ LLSD data(mUUID);
+ LLFloaterReg::showInstance("change_item_thumbnail", data);
+ return;
+ }
else if ("copy_uuid" == action)
{
// Single item only
@@ -1746,7 +1805,7 @@ void LLItemBridge::performAction(LLInventoryModel* model, std::string action)
{
LLInventoryItem* itemp = model->getItem(mUUID);
if (!itemp) return;
- const LLUUID &marketplacelistings_id = model->findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS, false);
+ const LLUUID &marketplacelistings_id = model->findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS);
// Note: For a single item, if it's not a copy, then it's a move
move_item_to_marketplacelistings(itemp, marketplacelistings_id, ("copy_to_marketplace_listings" == action));
}
@@ -1960,9 +2019,9 @@ std::string LLItemBridge::getLabelSuffix() const
{
// String table is loaded before login screen and inventory items are
// loaded after login, so LLTrans should be ready.
- static std::string NO_COPY = LLTrans::getString("no_copy");
- static std::string NO_MOD = LLTrans::getString("no_modify");
- static std::string NO_XFER = LLTrans::getString("no_transfer");
+ static std::string NO_COPY = LLTrans::getString("no_copy_lbl");
+ static std::string NO_MOD = LLTrans::getString("no_modify_lbl");
+ static std::string NO_XFER = LLTrans::getString("no_transfer_lbl");
static std::string LINK = LLTrans::getString("link");
static std::string BROKEN_LINK = LLTrans::getString("broken_link");
std::string suffix;
@@ -1983,17 +2042,20 @@ std::string LLItemBridge::getLabelSuffix() const
BOOL copy = item->getPermissions().allowCopyBy(gAgent.getID());
if (!copy)
{
+ suffix += " ";
suffix += NO_COPY;
}
BOOL mod = item->getPermissions().allowModifyBy(gAgent.getID());
if (!mod)
{
- suffix += NO_MOD;
+ suffix += suffix.empty() ? " " : ",";
+ suffix += NO_MOD;
}
BOOL xfer = item->getPermissions().allowOperationBy(PERM_TRANSFER,
gAgent.getID());
if (!xfer)
{
+ suffix += suffix.empty() ? " " : ",";
suffix += NO_XFER;
}
}
@@ -2162,6 +2224,21 @@ LLViewerInventoryItem* LLItemBridge::getItem() const
return item;
}
+const LLUUID& LLItemBridge::getThumbnailUUID() const
+{
+ LLViewerInventoryItem* item = NULL;
+ LLInventoryModel* model = getInventoryModel();
+ if(model)
+ {
+ item = (LLViewerInventoryItem*)model->getItem(mUUID);
+ }
+ if (item)
+ {
+ return item->getThumbnailUUID();
+ }
+ return LLUUID::null;
+}
+
BOOL LLItemBridge::isItemPermissive() const
{
LLViewerInventoryItem* item = getItem();
@@ -2244,12 +2321,33 @@ void LLFolderBridge::buildDisplayName() const
std::string LLFolderBridge::getLabelSuffix() const
{
- if (mIsLoading && mTimeSinceRequestStart.getElapsedTimeF32() >= FOLDER_LOADING_MESSAGE_DELAY)
+ 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;
@@ -2273,6 +2371,16 @@ LLFontGL::StyleFlags LLFolderBridge::getLabelStyle() const
return LLFontGL::NORMAL;
}
+const LLUUID& LLFolderBridge::getThumbnailUUID() const
+{
+ LLViewerInventoryCategory* cat = getCategory();
+ if (cat)
+ {
+ return cat->getThumbnailUUID();
+ }
+ return LLUUID::null;
+}
+
void LLFolderBridge::update()
{
// we know we have children but haven't fetched them (doesn't obey filter)
@@ -2483,7 +2591,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();
@@ -2500,8 +2609,8 @@ BOOL LLFolderBridge::dragCategoryIntoFolder(LLInventoryCategory* inv_cat,
if (!filter) return false;
const LLUUID &cat_id = inv_cat->getUUID();
- const LLUUID &current_outfit_id = model->findCategoryUUIDForType(LLFolderType::FT_CURRENT_OUTFIT, false);
- const LLUUID &marketplacelistings_id = model->findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS, false);
+ const LLUUID &current_outfit_id = model->findCategoryUUIDForType(LLFolderType::FT_CURRENT_OUTFIT);
+ const LLUUID &marketplacelistings_id = model->findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS);
const LLUUID from_folder_uuid = inv_cat->getParentUUID();
const BOOL move_is_into_current_outfit = (mUUID == current_outfit_id);
@@ -2519,10 +2628,10 @@ BOOL LLFolderBridge::dragCategoryIntoFolder(LLInventoryCategory* inv_cat,
if (is_agent_inventory)
{
- const LLUUID &trash_id = model->findCategoryUUIDForType(LLFolderType::FT_TRASH, false);
- const LLUUID &landmarks_id = model->findCategoryUUIDForType(LLFolderType::FT_LANDMARK, false);
- const LLUUID &my_outifts_id = model->findCategoryUUIDForType(LLFolderType::FT_MY_OUTFITS, false);
- const LLUUID &lost_and_found_id = model->findCategoryUUIDForType(LLFolderType::FT_LOST_AND_FOUND, false);
+ const LLUUID &trash_id = model->findCategoryUUIDForType(LLFolderType::FT_TRASH);
+ const LLUUID &landmarks_id = model->findCategoryUUIDForType(LLFolderType::FT_LANDMARK);
+ const LLUUID &my_outifts_id = model->findCategoryUUIDForType(LLFolderType::FT_MY_OUTFITS);
+ const LLUUID &lost_and_found_id = model->findCategoryUUIDForType(LLFolderType::FT_LOST_AND_FOUND);
const BOOL move_is_into_trash = (mUUID == trash_id) || model->isObjectDescendentOf(mUUID, trash_id);
const BOOL move_is_into_my_outfits = (mUUID == my_outifts_id) || model->isObjectDescendentOf(mUUID, my_outifts_id);
@@ -2788,7 +2897,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 &&
@@ -2798,14 +2907,16 @@ 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
{
- if (model->isObjectDescendentOf(cat_id, model->findCategoryUUIDForType(LLFolderType::FT_INBOX, false)))
+ if (model->isObjectDescendentOf(cat_id, model->findCategoryUUIDForType(LLFolderType::FT_INBOX)))
{
set_dad_inbox_object(cat_id);
}
@@ -2817,6 +2928,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)
{
@@ -2835,14 +2947,20 @@ BOOL LLFolderBridge::dragCategoryIntoFolder(LLInventoryCategory* inv_cat,
LLUUID version_folder_id = LLMarketplaceData::instance().getActiveFolder(from_folder_uuid);
if (version_folder_id.notNull())
{
- LLViewerInventoryCategory* cat = gInventory.getCategory(version_folder_id);
- if (!validate_marketplacelistings(cat,NULL))
+ LLMarketplaceValidator::getInstance()->validateMarketplaceListings(
+ version_folder_id,
+ [version_folder_id](bool result)
{
- LLMarketplaceData::instance().activateListing(version_folder_id,false);
+ if (!result)
+ {
+ LLMarketplaceData::instance().activateListing(version_folder_id, false);
+ }
}
+ );
}
// 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());
}
}
}
@@ -2856,7 +2974,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)
@@ -2927,7 +3060,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)
{
@@ -3230,6 +3363,12 @@ void LLFolderBridge::performAction(LLInventoryModel* model, std::string action)
return;
}
+ else if ("thumbnail" == action)
+ {
+ LLSD data(mUUID);
+ LLFloaterReg::showInstance("change_item_thumbnail", data);
+ return;
+ }
else if ("paste" == action)
{
pasteFromClipboard();
@@ -3299,18 +3438,26 @@ void LLFolderBridge::performAction(LLInventoryModel* model, std::string action)
if (depth_nesting_in_marketplace(mUUID) == 1)
{
LLUUID version_folder_id = LLMarketplaceData::instance().getVersionFolder(mUUID);
- LLViewerInventoryCategory* cat = gInventory.getCategory(version_folder_id);
mMessage = "";
- if (!validate_marketplacelistings(cat,boost::bind(&LLFolderBridge::gatherMessage, this, _1, _2, _3)))
- {
- LLSD subs;
- subs["[ERROR_CODE]"] = mMessage;
- LLNotificationsUtil::add("MerchantListingFailed", subs);
- }
- else
+
+ LLMarketplaceValidator::getInstance()->validateMarketplaceListings(
+ version_folder_id,
+ [this](bool result)
{
- LLMarketplaceData::instance().activateListing(mUUID,true);
- }
+ // todo: might need to ensure bridge/mUUID exists or this will cause crashes
+ if (!result)
+ {
+ LLSD subs;
+ subs["[ERROR_CODE]"] = mMessage;
+ LLNotificationsUtil::add("MerchantListingFailed", subs);
+ }
+ else
+ {
+ LLMarketplaceData::instance().activateListing(mUUID, true);
+ }
+ },
+ boost::bind(&LLFolderBridge::gatherMessage, this, _1, _2, _3)
+ );
}
return;
}
@@ -3318,18 +3465,27 @@ void LLFolderBridge::performAction(LLInventoryModel* model, std::string action)
{
if (depth_nesting_in_marketplace(mUUID) == 2)
{
- LLInventoryCategory* category = gInventory.getCategory(mUUID);
mMessage = "";
- if (!validate_marketplacelistings(category,boost::bind(&LLFolderBridge::gatherMessage, this, _1, _2, _3),false,2))
- {
- LLSD subs;
- subs["[ERROR_CODE]"] = mMessage;
- LLNotificationsUtil::add("MerchantFolderActivationFailed", subs);
- }
- else
+
+ LLMarketplaceValidator::getInstance()->validateMarketplaceListings(
+ mUUID,
+ [this](bool result)
{
- LLMarketplaceData::instance().setVersionFolder(category->getParentUUID(), mUUID);
- }
+ if (!result)
+ {
+ LLSD subs;
+ subs["[ERROR_CODE]"] = mMessage;
+ LLNotificationsUtil::add("MerchantFolderActivationFailed", subs);
+ }
+ else
+ {
+ LLInventoryCategory* category = gInventory.getCategory(mUUID);
+ LLMarketplaceData::instance().setVersionFolder(category->getParentUUID(), mUUID);
+ }
+ },
+ boost::bind(&LLFolderBridge::gatherMessage, this, _1, _2, _3),
+ false,
+ 2);
}
return;
}
@@ -3352,29 +3508,44 @@ void LLFolderBridge::performAction(LLInventoryModel* model, std::string action)
}
else if ("marketplace_create_listing" == action)
{
- LLViewerInventoryCategory* cat = gInventory.getCategory(mUUID);
mMessage = "";
- bool validates = validate_marketplacelistings(cat,boost::bind(&LLFolderBridge::gatherMessage, this, _1, _2, _3),false);
- if (!validates)
+
+ // first run vithout fix_hierarchy, second run with fix_hierarchy
+ LLMarketplaceValidator::getInstance()->validateMarketplaceListings(
+ mUUID,
+ [this](bool result)
{
- mMessage = "";
- validates = validate_marketplacelistings(cat,boost::bind(&LLFolderBridge::gatherMessage, this, _1, _2, _3),true);
- if (validates)
+ if (!result)
+ {
+ mMessage = "";
+
+ LLMarketplaceValidator::getInstance()->validateMarketplaceListings(
+ mUUID,
+ [this](bool result)
+ {
+ if (result)
+ {
+ LLNotificationsUtil::add("MerchantForceValidateListing");
+ LLMarketplaceData::instance().createListing(mUUID);
+ }
+ else
+ {
+ LLSD subs;
+ subs["[ERROR_CODE]"] = mMessage;
+ LLNotificationsUtil::add("MerchantListingFailed", subs);
+ }
+ },
+ boost::bind(&LLFolderBridge::gatherMessage, this, _1, _2, _3),
+ true);
+ }
+ else
{
- LLNotificationsUtil::add("MerchantForceValidateListing");
+ LLMarketplaceData::instance().createListing(mUUID);
}
- }
+ },
+ boost::bind(&LLFolderBridge::gatherMessage, this, _1, _2, _3),
+ false);
- if (!validates)
- {
- LLSD subs;
- subs["[ERROR_CODE]"] = mMessage;
- LLNotificationsUtil::add("MerchantListingFailed", subs);
- }
- else
- {
- LLMarketplaceData::instance().createListing(mUUID);
- }
return;
}
else if ("marketplace_disassociate_listing" == action)
@@ -3418,7 +3589,7 @@ void LLFolderBridge::performAction(LLInventoryModel* model, std::string action)
{
LLInventoryCategory * cat = gInventory.getCategory(mUUID);
if (!cat) return;
- const LLUUID &marketplacelistings_id = model->findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS, false);
+ const LLUUID &marketplacelistings_id = model->findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS);
move_folder_to_marketplacelistings(cat, marketplacelistings_id, ("move_to_marketplace_listings" != action), (("copy_or_move_to_marketplace_listings" == action)));
}
}
@@ -3668,7 +3839,7 @@ void LLFolderBridge::pasteFromClipboard()
LLInventoryModel* model = getInventoryModel();
if (model && isClipboardPasteable())
{
- const LLUUID &marketplacelistings_id = model->findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS, false);
+ const LLUUID &marketplacelistings_id = model->findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS);
const BOOL paste_into_marketplacelistings = model->isObjectDescendentOf(mUUID, marketplacelistings_id);
BOOL cut_from_marketplacelistings = FALSE;
@@ -3729,11 +3900,11 @@ void LLFolderBridge::perform_pasteFromClipboard()
LLInventoryModel* model = getInventoryModel();
if (model && isClipboardPasteable())
{
- const LLUUID &current_outfit_id = model->findCategoryUUIDForType(LLFolderType::FT_CURRENT_OUTFIT, false);
- const LLUUID &marketplacelistings_id = model->findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS, false);
- const LLUUID &favorites_id = model->findCategoryUUIDForType(LLFolderType::FT_FAVORITE, false);
- const LLUUID &my_outifts_id = model->findCategoryUUIDForType(LLFolderType::FT_MY_OUTFITS, false);
- const LLUUID &lost_and_found_id = model->findCategoryUUIDForType(LLFolderType::FT_LOST_AND_FOUND, false);
+ const LLUUID &current_outfit_id = model->findCategoryUUIDForType(LLFolderType::FT_CURRENT_OUTFIT);
+ const LLUUID &marketplacelistings_id = model->findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS);
+ const LLUUID &favorites_id = model->findCategoryUUIDForType(LLFolderType::FT_FAVORITE);
+ const LLUUID &my_outifts_id = model->findCategoryUUIDForType(LLFolderType::FT_MY_OUTFITS);
+ const LLUUID &lost_and_found_id = model->findCategoryUUIDForType(LLFolderType::FT_LOST_AND_FOUND);
const BOOL move_is_into_current_outfit = (mUUID == current_outfit_id);
const BOOL move_is_into_my_outfits = (mUUID == my_outifts_id) || model->isObjectDescendentOf(mUUID, my_outifts_id);
@@ -3744,6 +3915,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)
@@ -3819,7 +3997,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())
{
@@ -3827,7 +4005,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
{
@@ -3843,7 +4021,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
{
@@ -3862,11 +4040,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);
}
}
}
@@ -3894,6 +4073,7 @@ void LLFolderBridge::perform_pasteFromClipboard()
//changeCategoryParent() implicity calls dirtyFilter
changeCategoryParent(model, vicat, parent_id, FALSE);
}
+ if (cb) cb->fire(item_id);
}
}
else
@@ -3915,6 +4095,7 @@ void LLFolderBridge::perform_pasteFromClipboard()
//changeItemParent() implicity calls dirtyFilter
changeItemParent(model, viitem, parent_id, FALSE);
}
+ if (cb) cb->fire(item_id);
}
}
}
@@ -3935,6 +4116,7 @@ void LLFolderBridge::perform_pasteFromClipboard()
{
copy_inventory_category(model, vicat, parent_id);
}
+ if (cb) cb->fire(item_id);
}
}
else
@@ -3950,11 +4132,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
{
@@ -3964,7 +4148,7 @@ void LLFolderBridge::perform_pasteFromClipboard()
item->getUUID(),
parent_id,
std::string(),
- LLPointer<LLInventoryCallback>(NULL));
+ cb);
}
}
}
@@ -3981,9 +4165,9 @@ void LLFolderBridge::pasteLinkFromClipboard()
LLInventoryModel* model = getInventoryModel();
if(model)
{
- const LLUUID &current_outfit_id = model->findCategoryUUIDForType(LLFolderType::FT_CURRENT_OUTFIT, false);
- const LLUUID &marketplacelistings_id = model->findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS, false);
- const LLUUID &my_outifts_id = model->findCategoryUUIDForType(LLFolderType::FT_MY_OUTFITS, false);
+ const LLUUID &current_outfit_id = model->findCategoryUUIDForType(LLFolderType::FT_CURRENT_OUTFIT);
+ const LLUUID &marketplacelistings_id = model->findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS);
+ const LLUUID &my_outifts_id = model->findCategoryUUIDForType(LLFolderType::FT_MY_OUTFITS);
const BOOL move_is_into_current_outfit = (mUUID == current_outfit_id);
const BOOL move_is_into_my_outfits = (mUUID == my_outifts_id) || model->isObjectDescendentOf(mUUID, my_outifts_id);
@@ -4000,6 +4184,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)
@@ -4010,12 +4202,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
@@ -4053,8 +4245,8 @@ void LLFolderBridge::buildContextMenuOptions(U32 flags, menuentry_vec_t& items
const LLUUID &trash_id = model->findCategoryUUIDForType(LLFolderType::FT_TRASH);
const LLUUID &lost_and_found_id = model->findCategoryUUIDForType(LLFolderType::FT_LOST_AND_FOUND);
const LLUUID &favorites = model->findCategoryUUIDForType(LLFolderType::FT_FAVORITE);
- const LLUUID &marketplace_listings_id = model->findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS, false);
- const LLUUID &outfits_id = model->findCategoryUUIDForType(LLFolderType::FT_MY_OUTFITS, false);
+ const LLUUID &marketplace_listings_id = model->findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS);
+ const LLUUID &outfits_id = model->findCategoryUUIDForType(LLFolderType::FT_MY_OUTFITS);
if (outfits_id == mUUID)
{
@@ -4076,12 +4268,6 @@ void LLFolderBridge::buildContextMenuOptions(U32 flags, menuentry_vec_t& items
}
disabled_items.push_back(std::string("New Folder"));
- disabled_items.push_back(std::string("New Script"));
- disabled_items.push_back(std::string("New Note"));
- disabled_items.push_back(std::string("New Settings"));
- disabled_items.push_back(std::string("New Gesture"));
- disabled_items.push_back(std::string("New Clothes"));
- disabled_items.push_back(std::string("New Body Parts"));
disabled_items.push_back(std::string("upload_def"));
}
if (favorites == mUUID)
@@ -4104,11 +4290,6 @@ void LLFolderBridge::buildContextMenuOptions(U32 flags, menuentry_vec_t& items
if (getPreferredType() == LLFolderType::FT_MARKETPLACE_STOCK)
{
disabled_items.push_back(std::string("New Folder"));
- disabled_items.push_back(std::string("New Script"));
- disabled_items.push_back(std::string("New Note"));
- disabled_items.push_back(std::string("New Gesture"));
- disabled_items.push_back(std::string("New Clothes"));
- disabled_items.push_back(std::string("New Body Parts"));
disabled_items.push_back(std::string("upload_def"));
}
if (marketplace_listings_id == mUUID)
@@ -4118,14 +4299,14 @@ void LLFolderBridge::buildContextMenuOptions(U32 flags, menuentry_vec_t& items
disabled_items.push_back(std::string("Cut"));
disabled_items.push_back(std::string("Delete"));
}
+
+ if (isPanelActive("Favorite Items"))
+ {
+ disabled_items.push_back(std::string("Delete"));
+ }
if(trash_id == mUUID)
{
- bool is_recent_panel = false;
- LLInventoryPanel *active_panel = LLInventoryPanel::getActiveInventoryPanel(FALSE);
- if (active_panel && (active_panel->getName() == "Recent Items"))
- {
- is_recent_panel = true;
- }
+ bool is_recent_panel = isPanelActive("Recent Items");
// This is the trash.
items.push_back(std::string("Empty Trash"));
@@ -4144,6 +4325,8 @@ void LLFolderBridge::buildContextMenuOptions(U32 flags, menuentry_vec_t& items
{
disabled_items.push_back(std::string("Empty Trash"));
}
+
+ items.push_back(std::string("thumbnail"));
}
else if(isItemInTrash())
{
@@ -4168,19 +4351,7 @@ void LLFolderBridge::buildContextMenuOptions(U32 flags, menuentry_vec_t& items
}
if (!isMarketplaceListingsFolder())
{
- items.push_back(std::string("New Script"));
- items.push_back(std::string("New Note"));
- items.push_back(std::string("New Gesture"));
- items.push_back(std::string("New Clothes"));
- items.push_back(std::string("New Body Parts"));
- items.push_back(std::string("New Settings"));
items.push_back(std::string("upload_def"));
-
- if (!LLEnvironment::instance().isInventoryEnabled())
- {
- disabled_items.push_back("New Settings");
- }
-
}
}
getClipboardEntries(false, items, disabled_items, flags);
@@ -4191,6 +4362,7 @@ void LLFolderBridge::buildContextMenuOptions(U32 flags, menuentry_vec_t& items
if (cat && (cat->getPreferredType() == LLFolderType::FT_OUTFIT))
{
items.push_back(std::string("Rename"));
+ items.push_back(std::string("thumbnail"));
addDeleteContextMenuOptions(items, disabled_items);
// EXT-4030: disallow deletion of currently worn outfit
@@ -4205,6 +4377,7 @@ void LLFolderBridge::buildContextMenuOptions(U32 flags, menuentry_vec_t& items
if (model->findCategoryUUIDForType(LLFolderType::FT_CURRENT_OUTFIT) == mUUID)
{
items.push_back(std::string("Copy outfit list to clipboard"));
+ addOpenFolderMenuOptions(flags, items);
}
//Added by aura to force inventory pull on right-click to display folder options correctly. 07-17-06
@@ -4311,9 +4484,12 @@ void LLFolderBridge::buildContextMenuFolderOptions(U32 flags, menuentry_vec_t&
if(!category) return;
const LLUUID trash_id = model->findCategoryUUIDForType(LLFolderType::FT_TRASH);
- if (trash_id == mUUID) return;
- if (isItemInTrash()) return;
-
+ if ((trash_id == mUUID) || isItemInTrash())
+ {
+ addOpenFolderMenuOptions(flags, items);
+ return;
+ }
+
if (!isItemRemovable())
{
disabled_items.push_back(std::string("Delete"));
@@ -4326,7 +4502,7 @@ void LLFolderBridge::buildContextMenuFolderOptions(U32 flags, menuentry_vec_t&
const bool is_agent_inventory = isAgentInventory();
// Only enable calling-card related options for non-system folders.
- if (!is_system_folder && is_agent_inventory)
+ if (!is_system_folder && is_agent_inventory && (mRoot != NULL))
{
LLIsType is_callingcard(LLAssetType::AT_CALLINGCARD);
if (mCallingCards || checkFolderForContentsOfType(model, is_callingcard))
@@ -4346,6 +4522,14 @@ void LLFolderBridge::buildContextMenuFolderOptions(U32 flags, menuentry_vec_t&
disabled_items.push_back(std::string("New folder from selected"));
}
+ //skip the rest options in single-folder mode
+ if (mRoot == NULL)
+ {
+ return;
+ }
+
+ addOpenFolderMenuOptions(flags, items);
+
#ifndef LL_RELEASE_FOR_DOWNLOAD
if (LLFolderType::lookupIsProtectedType(type) && is_agent_inventory)
{
@@ -4371,26 +4555,29 @@ void LLFolderBridge::buildContextMenuFolderOptions(U32 flags, menuentry_vec_t&
if (type != LLFolderType::FT_OUTFIT)
{
items.push_back(std::string("Add To Outfit"));
+ if (!LLAppearanceMgr::instance().getCanAddToCOF(mUUID))
+ {
+ disabled_items.push_back(std::string("Add To Outfit"));
+ }
}
items.push_back(std::string("Replace Outfit"));
+ if (!LLAppearanceMgr::instance().getCanReplaceCOF(mUUID))
+ {
+ disabled_items.push_back(std::string("Replace Outfit"));
+ }
}
if (is_agent_inventory)
{
items.push_back(std::string("Folder Wearables Separator"));
+ // Note: If user tries to unwear "My Inventory", it's going to deactivate everything including gestures
+ // Might be safer to disable this for "My Inventory"
items.push_back(std::string("Remove From Outfit"));
- if (!LLAppearanceMgr::getCanRemoveFromCOF(mUUID))
- {
- disabled_items.push_back(std::string("Remove From Outfit"));
- }
- }
- if (!LLAppearanceMgr::instance().getCanReplaceCOF(mUUID))
- {
- disabled_items.push_back(std::string("Replace Outfit"));
- }
- if (!LLAppearanceMgr::instance().getCanAddToCOF(mUUID))
- {
- disabled_items.push_back(std::string("Add To Outfit"));
+ if (type != LLFolderType::FT_ROOT_INVENTORY // Unless COF is empty, whih shouldn't be, warrantied to have worn items
+ && !LLAppearanceMgr::getCanRemoveFromCOF(mUUID)) // expensive from root!
+ {
+ disabled_items.push_back(std::string("Remove From Outfit"));
+ }
}
items.push_back(std::string("Outfit Separator"));
@@ -4423,6 +4610,20 @@ void LLFolderBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
menu.arrangeAndClear();
}
+void LLFolderBridge::addOpenFolderMenuOptions(U32 flags, menuentry_vec_t& items)
+{
+ if ((flags & ITEM_IN_MULTI_SELECTION) == 0)
+ {
+ items.push_back(std::string("open_in_new_window"));
+ items.push_back(std::string("Open Folder Separator"));
+ items.push_back(std::string("Copy Separator"));
+ if(isPanelActive("comb_single_folder_inv"))
+ {
+ items.push_back(std::string("open_in_current_window"));
+ }
+ }
+}
+
bool LLFolderBridge::hasChildren() const
{
LLInventoryModel* model = getInventoryModel();
@@ -4439,6 +4640,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)
@@ -4456,7 +4669,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.
@@ -4467,12 +4680,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:
@@ -4482,7 +4695,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:
@@ -4492,6 +4705,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;
}
@@ -4790,138 +5008,56 @@ 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;
}
-// Returns true if the item can be moved to Current Outfit or any outfit folder.
-static BOOL can_move_to_outfit(LLInventoryItem* inv_item, BOOL move_is_into_current_outfit)
+void drop_to_favorites_cb(const LLUUID& id, LLPointer<LLInventoryCallback> cb1, LLPointer<LLInventoryCallback> cb2)
{
- LLInventoryType::EType inv_type = inv_item->getInventoryType();
- if ((inv_type != LLInventoryType::IT_WEARABLE) &&
- (inv_type != LLInventoryType::IT_GESTURE) &&
- (inv_type != LLInventoryType::IT_ATTACHMENT) &&
- (inv_type != LLInventoryType::IT_OBJECT) &&
- (inv_type != LLInventoryType::IT_SNAPSHOT) &&
- (inv_type != LLInventoryType::IT_TEXTURE))
- {
- return FALSE;
- }
-
- U32 flags = inv_item->getFlags();
- if(flags & LLInventoryItemFlags::II_FLAGS_OBJECT_HAS_MULTIPLE_ITEMS)
- {
- return FALSE;
- }
-
- if((inv_type == LLInventoryType::IT_TEXTURE) || (inv_type == LLInventoryType::IT_SNAPSHOT))
- {
- return !move_is_into_current_outfit;
- }
-
- if (move_is_into_current_outfit && get_is_item_worn(inv_item->getUUID()))
- {
- return FALSE;
- }
-
- return TRUE;
-}
-
-// Returns true if folder's content can be moved to Current Outfit or any outfit folder.
-static bool can_move_to_my_outfits(LLInventoryModel* model, LLInventoryCategory* inv_cat, U32 wear_limit)
-{
- LLInventoryModel::cat_array_t *cats;
- LLInventoryModel::item_array_t *items;
- model->getDirectDescendentsOf(inv_cat->getUUID(), cats, items);
-
- if (items->size() > wear_limit)
- {
- return false;
- }
-
- if (items->size() == 0)
- {
- // Nothing to move(create)
- return false;
- }
-
- if (cats->size() > 0)
- {
- // We do not allow subfolders in outfits of "My Outfits" yet
- return false;
- }
-
- LLInventoryModel::item_array_t::iterator iter = items->begin();
- LLInventoryModel::item_array_t::iterator end = items->end();
-
- while (iter != end)
- {
- LLViewerInventoryItem *item = *iter;
- if (!can_move_to_outfit(item, false))
- {
- return false;
- }
- iter++;
- }
-
- return true;
-}
-
-// Returns TRUE if item is a landmark or a link to a landmark
-// and can be moved to Favorites or Landmarks folder.
-static BOOL can_move_to_landmarks(LLInventoryItem* inv_item)
-{
- // Need to get the linked item to know its type because LLInventoryItem::getType()
- // returns actual type AT_LINK for links, not the asset type of a linked item.
- if (LLAssetType::AT_LINK == inv_item->getType())
- {
- LLInventoryItem* linked_item = gInventory.getItem(inv_item->getLinkedUUID());
- if (linked_item)
- {
- return LLAssetType::AT_LANDMARK == linked_item->getType();
- }
- }
-
- return LLAssetType::AT_LANDMARK == inv_item->getType();
+ cb1->fire(id);
+ cb2->fire(id);
}
-void LLFolderBridge::dropToFavorites(LLInventoryItem* inv_item)
+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))
{
- const LLUUID &my_outifts_id = getInventoryModel()->findCategoryUUIDForType(LLFolderType::FT_MY_OUTFITS, false);
+ const LLUUID &my_outifts_id = getInventoryModel()->findCategoryUUIDForType(LLFolderType::FT_MY_OUTFITS);
if(mUUID != my_outifts_id)
{
- LLFloaterOutfitPhotoPreview* photo_preview = LLFloaterReg::showTypedInstance<LLFloaterOutfitPhotoPreview>("outfit_photo_preview", inv_item->getUUID());
- if(photo_preview)
- {
- photo_preview->setOutfitID(mUUID);
- }
+ // Legacy: prior to thumbnails images in outfits were used for outfit gallery.
+ LLNotificationsUtil::add("ThumbnailOutfitPhoto");
}
return;
}
@@ -4938,21 +5074,22 @@ 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(),
- func);
+ func,
+ 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;
@@ -4983,7 +5120,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);
}
}
@@ -5016,7 +5152,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();
@@ -5030,11 +5167,11 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item,
LLInventoryFilter* filter = getInventoryFilter();
if (!filter) return false;
- const LLUUID &current_outfit_id = model->findCategoryUUIDForType(LLFolderType::FT_CURRENT_OUTFIT, false);
- const LLUUID &favorites_id = model->findCategoryUUIDForType(LLFolderType::FT_FAVORITE, false);
- const LLUUID &landmarks_id = model->findCategoryUUIDForType(LLFolderType::FT_LANDMARK, false);
- const LLUUID &marketplacelistings_id = model->findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS, false);
- const LLUUID &my_outifts_id = model->findCategoryUUIDForType(LLFolderType::FT_MY_OUTFITS, false);
+ const LLUUID &current_outfit_id = model->findCategoryUUIDForType(LLFolderType::FT_CURRENT_OUTFIT);
+ const LLUUID &favorites_id = model->findCategoryUUIDForType(LLFolderType::FT_FAVORITE);
+ const LLUUID &landmarks_id = model->findCategoryUUIDForType(LLFolderType::FT_LANDMARK);
+ const LLUUID &marketplacelistings_id = model->findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS);
+ const LLUUID &my_outifts_id = model->findCategoryUUIDForType(LLFolderType::FT_MY_OUTFITS);
const LLUUID from_folder_uuid = inv_item->getParentUUID();
const BOOL move_is_into_current_outfit = (mUUID == current_outfit_id);
@@ -5054,7 +5191,7 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item,
LLViewerObject* object = NULL;
if(LLToolDragAndDrop::SOURCE_AGENT == source)
{
- const LLUUID &trash_id = model->findCategoryUUIDForType(LLFolderType::FT_TRASH, false);
+ const LLUUID &trash_id = model->findCategoryUUIDForType(LLFolderType::FT_TRASH);
const BOOL move_is_into_trash = (mUUID == trash_id) || model->isObjectDescendentOf(mUUID, trash_id);
const BOOL move_is_outof_current_outfit = LLAppearanceMgr::instance().getIsInCOF(inv_item->getUUID());
@@ -5196,26 +5333,27 @@ 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)
else
{
// set up observer to select item once drag and drop from inbox is complete
- if (gInventory.isObjectDescendentOf(inv_item->getUUID(), gInventory.findCategoryUUIDForType(LLFolderType::FT_INBOX, false)))
+ if (gInventory.isObjectDescendentOf(inv_item->getUUID(), gInventory.findCategoryUUIDForType(LLFolderType::FT_INBOX)))
{
set_dad_inbox_object(inv_item->getUUID());
}
@@ -5225,6 +5363,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)
@@ -5233,11 +5372,15 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item,
LLUUID version_folder_id = LLMarketplaceData::instance().getActiveFolder(from_folder_uuid);
if (version_folder_id.notNull())
{
- LLViewerInventoryCategory* cat = gInventory.getCategory(version_folder_id);
- if (!validate_marketplacelistings(cat,NULL))
+ LLMarketplaceValidator::getInstance()->validateMarketplaceListings(
+ version_folder_id,
+ [version_folder_id](bool result)
{
- LLMarketplaceData::instance().activateListing(version_folder_id,false);
- }
+ if (!result)
+ {
+ LLMarketplaceData::instance().activateListing(version_folder_id, false);
+ }
+ });
}
}
@@ -5305,11 +5448,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)
{
@@ -5401,13 +5549,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
{
@@ -5417,7 +5565,7 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item,
inv_item->getUUID(),
mUUID,
std::string(),
- LLPointer<LLInventoryCallback>(NULL));
+ cb);
}
}
}
@@ -5972,7 +6120,7 @@ std::string LLCallingCardBridge::getLabelSuffix() const
LLViewerInventoryItem* item = getItem();
if( item && LLAvatarTracker::instance().isBuddyOnline(item->getCreatorUUID()) )
{
- return LLItemBridge::getLabelSuffix() + " (online)";
+ return LLItemBridge::getLabelSuffix() + " online";
}
else
{
@@ -7555,16 +7703,26 @@ class LLObjectBridgeAction: public LLInvFVBridgeAction
public:
virtual void doIt()
{
- /*
- LLFloaterReg::showInstance("properties", mUUID);
- */
- LLInvFVBridgeAction::doIt();
+ attachOrDetach();
}
virtual ~LLObjectBridgeAction(){}
protected:
LLObjectBridgeAction(const LLUUID& id,LLInventoryModel* model) : LLInvFVBridgeAction(id,model) {}
+ void attachOrDetach();
};
+void LLObjectBridgeAction::attachOrDetach()
+{
+ if (get_is_item_worn(mUUID))
+ {
+ LLAppearanceMgr::instance().removeItemFromAvatar(mUUID);
+ }
+ else
+ {
+ LLAppearanceMgr::instance().wearItemOnAvatar(mUUID, true, false); // Don't replace if adding.
+ }
+}
+
class LLLSLTextBridgeAction: public LLInvFVBridgeAction
{
friend class LLInvFVBridgeAction;
@@ -7623,7 +7781,17 @@ void LLWearableBridgeAction::wearOnAvatar()
LLViewerInventoryItem* item = getItem();
if(item)
{
- LLAppearanceMgr::instance().wearItemOnAvatar(item->getUUID(), true, true);
+ if (get_is_item_worn(mUUID))
+ {
+ if(item->getType() != LLAssetType::AT_BODYPART)
+ {
+ LLAppearanceMgr::instance().removeItemFromAvatar(item->getUUID());
+ }
+ }
+ else
+ {
+ LLAppearanceMgr::instance().wearItemOnAvatar(item->getUUID(), true, true);
+ }
}
}