summaryrefslogtreecommitdiff
path: root/indra/newview/llinventorybridge.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview/llinventorybridge.cpp')
-rwxr-xr-xindra/newview/llinventorybridge.cpp1457
1 files changed, 1068 insertions, 389 deletions
diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp
index 84f88e38ba..605f71f412 100755
--- a/indra/newview/llinventorybridge.cpp
+++ b/indra/newview/llinventorybridge.cpp
@@ -40,6 +40,7 @@
#include "llfavoritesbar.h" // management of favorites folder
#include "llfloateropenobject.h"
#include "llfloaterreg.h"
+#include "llfloatermarketplacelistings.h"
#include "llfloatersidepanelcontainer.h"
#include "llfloaterworldmap.h"
#include "llfolderview.h"
@@ -65,6 +66,7 @@
#include "llsidepanelappearance.h"
#include "lltooldraganddrop.h"
#include "lltrans.h"
+#include "llurlaction.h"
#include "llviewerassettype.h"
#include "llviewerfoldertype.h"
#include "llviewermenu.h"
@@ -80,11 +82,6 @@
void copy_slurl_to_clipboard_callback_inv(const std::string& slurl);
-// Marketplace outbox current disabled
-#define ENABLE_MERCHANT_OUTBOX_CONTEXT_MENU 1
-#define ENABLE_MERCHANT_SEND_TO_MARKETPLACE_CONTEXT_MENU 0
-#define BLOCK_WORN_ITEMS_IN_OUTBOX 1
-
typedef std::pair<LLUUID, LLUUID> two_uuids_t;
typedef std::list<two_uuids_t> two_uuids_list_t;
@@ -206,7 +203,6 @@ const std::string& LLInvFVBridge::getDisplayName() const
{
buildDisplayName();
}
-
return mDisplayName;
}
@@ -270,13 +266,49 @@ BOOL LLInvFVBridge::isLibraryItem() const
/**
* @brief Adds this item into clipboard storage
*/
-BOOL LLInvFVBridge::cutToClipboard() const
+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 BOOL cut_from_marketplacelistings = gInventory.isObjectDescendentOf(mUUID, marketplacelistings_id);
+
+ if (cut_from_marketplacelistings && (LLMarketplaceData::instance().isInActiveFolder(mUUID) ||
+ LLMarketplaceData::instance().isListedAndActive(mUUID)))
+ {
+ // Prompt the user if cutting from a marketplace active listing
+ LLNotificationsUtil::add("ConfirmMerchantActiveChange", LLSD(), LLSD(), boost::bind(&LLInvFVBridge::callback_cutToClipboard, this, _1, _2));
+ }
+ else
+ {
+ // Otherwise just perform the cut
+ return perform_cutToClipboard();
+ }
+ }
+ return FALSE;
+}
+
+// Callback for cutToClipboard if DAMA required...
+BOOL LLInvFVBridge::callback_cutToClipboard(const LLSD& notification, const LLSD& response)
+{
+ S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
+ if (option == 0) // YES
+ {
+ return perform_cutToClipboard();
+ }
+ return FALSE;
+}
+
+BOOL LLInvFVBridge::perform_cutToClipboard()
{
const LLInventoryObject* obj = gInventory.getObject(mUUID);
if (obj && isItemMovable() && isItemRemovable())
{
LLClipboard::instance().setCutMode(true);
- return LLClipboard::instance().addToClipboard(mUUID);
+ BOOL added_to_clipboard = LLClipboard::instance().addToClipboard(mUUID);
+ removeObject(&gInventory, mUUID); // Always perform the remove even if the object couldn't make it to the clipboard
+ return added_to_clipboard;
}
return FALSE;
}
@@ -291,15 +323,22 @@ BOOL LLInvFVBridge::copyToClipboard() const
return FALSE;
}
-// *TODO: make sure this does the right thing
void LLInvFVBridge::showProperties()
{
- show_item_profile(mUUID);
-
- // Disable old properties floater; this is replaced by the sidepanel.
- /*
- LLFloaterReg::showInstance("properties", mUUID);
- */
+ if (isMarketplaceListingsFolder())
+ {
+ LLFloaterReg::showInstance("item_properties", LLSD().with("id",mUUID),TRUE);
+ // Force it to show on top as this floater has a tendency to hide when confirmation dialog shows up
+ LLFloater* floater_properties = LLFloaterReg::findInstance("item_properties", LLSD().with("id",mUUID));
+ if (floater_properties)
+ {
+ floater_properties->setVisibleAndFrontmost();
+ }
+ }
+ else
+ {
+ show_item_profile(mUUID);
+ }
}
void LLInvFVBridge::removeBatch(std::vector<LLFolderViewModelItem*>& batch)
@@ -696,7 +735,7 @@ void LLInvFVBridge::getClipboardEntries(bool show_asset_id,
if (!isInboxFolder())
{
items.push_back(std::string("Rename"));
- if (!isItemRenameable() || (flags & FIRST_SELECTED_ITEM) == 0)
+ if (!isItemRenameable() || ((flags & FIRST_SELECTED_ITEM) == 0))
{
disabled_items.push_back(std::string("Rename"));
}
@@ -734,15 +773,28 @@ void LLInvFVBridge::getClipboardEntries(bool show_asset_id,
disabled_items.push_back(std::string("Cut"));
}
- if (canListOnMarketplace())
+ if (canListOnMarketplace() && !isMarketplaceListingsFolder() && !isInboxFolder())
{
items.push_back(std::string("Marketplace Separator"));
- items.push_back(std::string("Merchant Copy"));
- if (!canListOnMarketplaceNow())
- {
- disabled_items.push_back(std::string("Merchant Copy"));
- }
+ if (gMenuHolder->getChild<LLView>("MerchantOutbox")->getVisible())
+ {
+ items.push_back(std::string("Merchant Copy"));
+ if (!canListOnOutboxNow())
+ {
+ disabled_items.push_back(std::string("Merchant Copy"));
+ }
+ }
+ if (gMenuHolder->getChild<LLView>("MarketplaceListings")->getVisible())
+ {
+ items.push_back(std::string("Marketplace Copy"));
+ items.push_back(std::string("Marketplace Move"));
+ if (!canListOnMarketplaceNow())
+ {
+ disabled_items.push_back(std::string("Marketplace Copy"));
+ disabled_items.push_back(std::string("Marketplace Move"));
+ }
+ }
}
}
}
@@ -901,21 +953,130 @@ void LLInvFVBridge::addOutboxContextMenuOptions(U32 flags,
{
disabled_items.push_back(std::string("Rename"));
}
-
-#if ENABLE_MERCHANT_SEND_TO_MARKETPLACE_CONTEXT_MENU
- if (isOutboxFolderDirectParent())
- {
- items.push_back(std::string("Marketplace Separator"));
- items.push_back(std::string("Marketplace Send"));
-
- if ((flags & FIRST_SELECTED_ITEM) == 0)
- {
- disabled_items.push_back(std::string("Marketplace Send"));
- }
- }
-#endif // ENABLE_MERCHANT_SEND_TO_MARKETPLACE_CONTEXT_MENU
}
+void LLInvFVBridge::addMarketplaceContextMenuOptions(U32 flags,
+ menuentry_vec_t &items,
+ menuentry_vec_t &disabled_items)
+{
+ S32 depth = depth_nesting_in_marketplace(mUUID);
+ if (depth == 1)
+ {
+ // Options available at the Listing Folder level
+ items.push_back(std::string("Marketplace Create Listing"));
+ items.push_back(std::string("Marketplace Associate Listing"));
+ items.push_back(std::string("Marketplace Check Listing"));
+ items.push_back(std::string("Marketplace List"));
+ items.push_back(std::string("Marketplace Unlist"));
+ if (LLMarketplaceData::instance().isUpdating(mUUID,depth) || ((flags & FIRST_SELECTED_ITEM) == 0))
+ {
+ // During SLM update, disable all marketplace related options
+ // Also disable all if multiple selected items
+ disabled_items.push_back(std::string("Marketplace Create Listing"));
+ disabled_items.push_back(std::string("Marketplace Associate Listing"));
+ disabled_items.push_back(std::string("Marketplace Check Listing"));
+ disabled_items.push_back(std::string("Marketplace List"));
+ disabled_items.push_back(std::string("Marketplace Unlist"));
+ }
+ else
+ {
+ if (gSavedSettings.getBOOL("MarketplaceListingsLogging"))
+ {
+ items.push_back(std::string("Marketplace Get Listing"));
+ }
+ if (LLMarketplaceData::instance().isListed(mUUID))
+ {
+ disabled_items.push_back(std::string("Marketplace Create Listing"));
+ disabled_items.push_back(std::string("Marketplace Associate Listing"));
+ if (LLMarketplaceData::instance().getVersionFolder(mUUID).isNull())
+ {
+ disabled_items.push_back(std::string("Marketplace List"));
+ disabled_items.push_back(std::string("Marketplace Unlist"));
+ }
+ else
+ {
+ if (LLMarketplaceData::instance().getActivationState(mUUID))
+ {
+ disabled_items.push_back(std::string("Marketplace List"));
+ }
+ else
+ {
+ disabled_items.push_back(std::string("Marketplace Unlist"));
+ }
+ }
+ }
+ else
+ {
+ disabled_items.push_back(std::string("Marketplace List"));
+ disabled_items.push_back(std::string("Marketplace Unlist"));
+ if (gSavedSettings.getBOOL("MarketplaceListingsLogging"))
+ {
+ disabled_items.push_back(std::string("Marketplace Get Listing"));
+ }
+ }
+ }
+ }
+ if (depth == 2)
+ {
+ // Options available at the Version Folder levels and only for folders
+ LLInventoryCategory* cat = gInventory.getCategory(mUUID);
+ if (cat && LLMarketplaceData::instance().isListed(cat->getParentUUID()))
+ {
+ items.push_back(std::string("Marketplace Activate"));
+ items.push_back(std::string("Marketplace Deactivate"));
+ if (LLMarketplaceData::instance().isUpdating(mUUID,depth) || ((flags & FIRST_SELECTED_ITEM) == 0))
+ {
+ // During SLM update, disable all marketplace related options
+ // Also disable all if multiple selected items
+ disabled_items.push_back(std::string("Marketplace Activate"));
+ disabled_items.push_back(std::string("Marketplace Deactivate"));
+ }
+ else
+ {
+ if (LLMarketplaceData::instance().isVersionFolder(mUUID))
+ {
+ disabled_items.push_back(std::string("Marketplace Activate"));
+ if (LLMarketplaceData::instance().getActivationState(mUUID))
+ {
+ disabled_items.push_back(std::string("Marketplace Deactivate"));
+ }
+ }
+ else
+ {
+ disabled_items.push_back(std::string("Marketplace Deactivate"));
+ }
+ }
+ }
+ }
+
+ items.push_back(std::string("Marketplace Edit Listing"));
+ LLUUID listing_folder_id = nested_parent_id(mUUID,depth);
+ LLUUID version_folder_id = LLMarketplaceData::instance().getVersionFolder(listing_folder_id);
+
+ if (depth >= 2)
+ {
+ // Prevent creation of new folders if the max count has been reached on this version folder (active or not)
+ LLUUID local_version_folder_id = nested_parent_id(mUUID,depth-1);
+ LLInventoryModel::cat_array_t categories;
+ LLInventoryModel::item_array_t items;
+ gInventory.collectDescendents(local_version_folder_id, categories, items, FALSE);
+ if (categories.size() >= gSavedSettings.getU32("InventoryOutboxMaxFolderCount"))
+ {
+ disabled_items.push_back(std::string("New Folder"));
+ }
+ }
+
+ // Options available at all levels on items and categories
+ if (!LLMarketplaceData::instance().isListed(listing_folder_id) || version_folder_id.isNull())
+ {
+ disabled_items.push_back(std::string("Marketplace Edit Listing"));
+ }
+
+ // Separator
+ items.push_back(std::string("Marketplace Listings Separator"));
+}
+
+
// *TODO: remove this
BOOL LLInvFVBridge::startDrag(EDragAndDropType* type, LLUUID* id) const
{
@@ -1018,6 +1179,7 @@ BOOL LLInvFVBridge::isCOFFolder() const
return LLAppearanceMgr::instance().getIsInCOF(mUUID);
}
+// *TODO : Suppress isInboxFolder() once Merchant Outbox is fully deprecated
BOOL LLInvFVBridge::isInboxFolder() const
{
const LLUUID inbox_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_INBOX, false);
@@ -1030,6 +1192,18 @@ BOOL LLInvFVBridge::isInboxFolder() const
return gInventory.isObjectDescendentOf(mUUID, inbox_id);
}
+BOOL LLInvFVBridge::isMarketplaceListingsFolder() const
+{
+ const LLUUID folder_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS, false);
+
+ if (folder_id.isNull())
+ {
+ return FALSE;
+ }
+
+ return gInventory.isObjectDescendentOf(mUUID, folder_id);
+}
+
BOOL LLInvFVBridge::isOutboxFolder() const
{
const LLUUID outbox_id = getOutboxFolder();
@@ -1191,11 +1365,18 @@ LLInvFVBridge* LLInvFVBridge::createBridge(LLAssetType::EType asset_type,
case LLAssetType::AT_CATEGORY:
if (actual_asset_type == LLAssetType::AT_LINK_FOLDER)
{
- // Create a link folder handler instead.
+ // Create a link folder handler instead
new_listener = new LLLinkFolderBridge(inventory, root, uuid);
- break;
}
- new_listener = new LLFolderBridge(inventory, root, uuid);
+ else if (actual_asset_type == LLAssetType::AT_MARKETPLACE_FOLDER)
+ {
+ // Create a marketplace folder handler
+ new_listener = new LLMarketplaceFolderBridge(inventory, root, uuid);
+ }
+ else
+ {
+ new_listener = new LLFolderBridge(inventory, root, uuid);
+ }
break;
case LLAssetType::AT_LINK:
case LLAssetType::AT_LINK_FOLDER:
@@ -1238,6 +1419,22 @@ void LLInvFVBridge::purgeItem(LLInventoryModel *model, const LLUUID &uuid)
}
}
+void LLInvFVBridge::removeObject(LLInventoryModel *model, const LLUUID &uuid)
+{
+ // Keep track of the parent
+ LLInventoryItem* itemp = model->getItem(uuid);
+ LLUUID parent_id = (itemp ? itemp->getParentUUID() : LLUUID::null);
+ // Remove the object
+ model->removeObject(uuid);
+ // Get the parent updated
+ if (parent_id.notNull())
+ {
+ LLViewerInventoryCategory* parent_cat = model->getCategory(parent_id);
+ model->updateCategory(parent_cat);
+ model->notifyObservers();
+ }
+}
+
bool LLInvFVBridge::canShare() const
{
bool can_share = false;
@@ -1268,11 +1465,9 @@ bool LLInvFVBridge::canShare() const
bool LLInvFVBridge::canListOnMarketplace() const
{
-#if ENABLE_MERCHANT_OUTBOX_CONTEXT_MENU
-
LLInventoryModel * model = getInventoryModel();
- const LLViewerInventoryCategory * cat = model->getCategory(mUUID);
+ LLViewerInventoryCategory * cat = model->getCategory(mUUID);
if (cat && LLFolderType::lookupIsProtectedType(cat->getPreferredType()))
{
return false;
@@ -1283,16 +1478,6 @@ bool LLInvFVBridge::canListOnMarketplace() const
return false;
}
- if (getOutboxFolder().isNull())
- {
- return false;
- }
-
- if (isInboxFolder() || isOutboxFolder())
- {
- return false;
- }
-
LLViewerInventoryItem * item = model->getItem(mUUID);
if (item)
{
@@ -1308,16 +1493,11 @@ bool LLInvFVBridge::canListOnMarketplace() const
}
return true;
-
-#else
- return false;
-#endif
}
-bool LLInvFVBridge::canListOnMarketplaceNow() const
+// *TODO : Suppress canListOnOutboxNow() once we deprecate Merchant Outbox completely
+bool LLInvFVBridge::canListOnOutboxNow() const
{
-#if ENABLE_MERCHANT_OUTBOX_CONTEXT_MENU
-
bool can_list = true;
// Do not allow listing while import is in progress
@@ -1363,10 +1543,56 @@ bool LLInvFVBridge::canListOnMarketplaceNow() const
}
return can_list;
+}
-#else
- return false;
-#endif
+bool LLInvFVBridge::canListOnMarketplaceNow() const
+{
+ bool can_list = true;
+
+ const LLInventoryObject* obj = getInventoryObject();
+ can_list &= (obj != NULL);
+
+ if (can_list)
+ {
+ const LLUUID& object_id = obj->getLinkedUUID();
+ can_list = object_id.notNull();
+
+ if (can_list)
+ {
+ LLFolderViewFolder * object_folderp = mInventoryPanel.get() ? mInventoryPanel.get()->getFolderByID(object_id) : NULL;
+ if (object_folderp)
+ {
+ can_list = !static_cast<LLFolderBridge*>(object_folderp->getViewModelItem())->isLoading();
+ }
+ }
+
+ if (can_list)
+ {
+ std::string error_msg;
+ LLInventoryModel* model = getInventoryModel();
+ const LLUUID &marketplacelistings_id = model->findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS, false);
+ if (marketplacelistings_id.notNull())
+ {
+ LLViewerInventoryCategory * master_folder = model->getCategory(marketplacelistings_id);
+ LLInventoryCategory *cat = model->getCategory(mUUID);
+ if (cat)
+ {
+ can_list = can_move_folder_to_marketplace(master_folder, master_folder, cat, error_msg);
+ }
+ else
+ {
+ LLInventoryItem *item = model->getItem(mUUID);
+ can_list = (item ? can_move_item_to_marketplace(master_folder, master_folder, item, error_msg) : false);
+ }
+ }
+ else
+ {
+ can_list = false;
+ }
+ }
+ }
+
+ return can_list;
}
LLToolDragAndDrop::ESource LLInvFVBridge::getDragSource() const
@@ -1458,7 +1684,6 @@ void LLItemBridge::performAction(LLInventoryModel* model, std::string action)
else if ("cut" == action)
{
cutToClipboard();
- gInventory.removeObject(mUUID);
return;
}
else if ("copy" == action)
@@ -1499,6 +1724,14 @@ void LLItemBridge::performAction(LLInventoryModel* model, std::string action)
const LLUUID outbox_id = getInventoryModel()->findCategoryUUIDForType(LLFolderType::FT_OUTBOX, false);
copy_item_to_outbox(itemp, outbox_id, LLUUID::null, LLToolDragAndDrop::getOperationId());
}
+ else if (("move_to_marketplace_listings" == action) || ("copy_to_marketplace_listings" == action) || ("copy_or_move_to_marketplace_listings" == action))
+ {
+ LLInventoryItem* itemp = model->getItem(mUUID);
+ if (!itemp) return;
+ const LLUUID &marketplacelistings_id = model->findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS, false);
+ // 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));
+ }
else if ("copy_slurl" == action)
{
LLViewerInventoryItem* item = static_cast<LLViewerInventoryItem*>(getItem());
@@ -1518,6 +1751,11 @@ void LLItemBridge::performAction(LLInventoryModel* model, std::string action)
{
doActionOnCurSelectedLandmark(boost::bind(&LLItemBridge::doShowOnMap, this, _1));
}
+ else if ("marketplace_edit_listing" == action)
+ {
+ std::string url = LLMarketplaceData::instance().getListingURL(mUUID);
+ LLUrlAction::openURL(url);
+ }
}
void LLItemBridge::doActionOnCurSelectedLandmark(LLLandmarkList::loaded_callback_t cb)
@@ -1983,6 +2221,22 @@ void LLFolderBridge::buildDisplayName() const
}
}
+std::string LLFolderBridge::getLabelSuffix() const
+{
+ static LLCachedControl<F32> folder_loading_message_delay(gSavedSettings, "FolderLoadingMessageWaitTime", 0.5f);
+
+ if (mIsLoading && mTimeSinceRequestStart.getElapsedTimeF32() >= folder_loading_message_delay())
+ {
+ return llformat(" ( %s ) ", LLTrans::getString("LoadingData").c_str());
+ }
+
+ return LLInvFVBridge::getLabelSuffix();
+}
+
+LLFontGL::StyleFlags LLFolderBridge::getLabelStyle() const
+{
+ return LLFontGL::NORMAL;
+}
void LLFolderBridge::update()
{
@@ -2039,6 +2293,11 @@ BOOL LLFolderBridge::isItemRemovable() const
return FALSE;
}
}
+
+ if (isMarketplaceListingsFolder() && LLMarketplaceData::instance().getActivationState(mUUID))
+ {
+ return FALSE;
+ }
return TRUE;
}
@@ -2174,88 +2433,11 @@ BOOL LLFolderBridge::isClipboardPasteableAsLink() const
}
-static BOOL can_move_to_outbox(LLInventoryItem* inv_item, std::string& tooltip_msg)
-{
- // Collapse links directly to items/folders
- LLViewerInventoryItem * viewer_inv_item = (LLViewerInventoryItem *) inv_item;
- LLViewerInventoryItem * linked_item = viewer_inv_item->getLinkedItem();
- if (linked_item != NULL)
- {
- inv_item = linked_item;
- }
-
- bool allow_transfer = inv_item->getPermissions().allowOperationBy(PERM_TRANSFER, gAgent.getID());
- if (!allow_transfer)
- {
- tooltip_msg = LLTrans::getString("TooltipOutboxNoTransfer");
- return false;
- }
-
-#if BLOCK_WORN_ITEMS_IN_OUTBOX
- bool worn = get_is_item_worn(inv_item->getUUID());
- if (worn)
- {
- tooltip_msg = LLTrans::getString("TooltipOutboxWorn");
- return false;
- }
-#endif
-
- bool calling_card = (LLAssetType::AT_CALLINGCARD == inv_item->getType());
- if (calling_card)
- {
- tooltip_msg = LLTrans::getString("TooltipOutboxCallingCard");
- return false;
- }
-
- return true;
-}
-
-
-int get_folder_levels(LLInventoryCategory* inv_cat)
-{
- LLInventoryModel::cat_array_t* cats;
- LLInventoryModel::item_array_t* items;
- gInventory.getDirectDescendentsOf(inv_cat->getUUID(), cats, items);
-
- int max_child_levels = 0;
-
- for (S32 i=0; i < cats->size(); ++i)
- {
- LLInventoryCategory* category = cats->at(i);
- max_child_levels = llmax(max_child_levels, get_folder_levels(category));
- }
-
- return 1 + max_child_levels;
-}
-
-int get_folder_path_length(const LLUUID& ancestor_id, const LLUUID& descendant_id)
-{
- int depth = 0;
-
- if (ancestor_id == descendant_id) return depth;
-
- const LLInventoryCategory* category = gInventory.getCategory(descendant_id);
-
- while(category)
- {
- LLUUID parent_id = category->getParentUUID();
-
- if (parent_id.isNull()) break;
-
- depth++;
-
- if (parent_id == ancestor_id) return depth;
-
- category = gInventory.getCategory(parent_id);
- }
-
- LL_WARNS() << "get_folder_path_length() couldn't trace a path from the descendant to the ancestor" << LL_ENDL;
- return -1;
-}
BOOL LLFolderBridge::dragCategoryIntoFolder(LLInventoryCategory* inv_cat,
BOOL drop,
- std::string& tooltip_msg)
+ std::string& tooltip_msg,
+ BOOL user_confirm)
{
LLInventoryModel* model = getInventoryModel();
@@ -2274,10 +2456,14 @@ BOOL LLFolderBridge::dragCategoryIntoFolder(LLInventoryCategory* inv_cat,
const LLUUID &cat_id = inv_cat->getUUID();
const LLUUID &current_outfit_id = model->findCategoryUUIDForType(LLFolderType::FT_CURRENT_OUTFIT, false);
const LLUUID &outbox_id = model->findCategoryUUIDForType(LLFolderType::FT_OUTBOX, false);
+ const LLUUID &marketplacelistings_id = model->findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS, false);
+ const LLUUID from_folder_uuid = inv_cat->getParentUUID();
const BOOL move_is_into_current_outfit = (mUUID == current_outfit_id);
const BOOL move_is_into_outbox = model->isObjectDescendentOf(mUUID, outbox_id);
const BOOL move_is_from_outbox = model->isObjectDescendentOf(cat_id, outbox_id);
+ const BOOL move_is_into_marketplacelistings = model->isObjectDescendentOf(mUUID, marketplacelistings_id);
+ const BOOL move_is_from_marketplacelistings = model->isObjectDescendentOf(cat_id, marketplacelistings_id);
// check to make sure source is agent inventory, and is represented there.
LLToolDragAndDrop::ESource source = LLToolDragAndDrop::getInstance()->getSource();
@@ -2305,6 +2491,18 @@ BOOL LLFolderBridge::dragCategoryIntoFolder(LLInventoryCategory* inv_cat,
BOOL is_movable = TRUE;
+ if (is_movable && (marketplacelistings_id == cat_id))
+ {
+ is_movable = FALSE;
+ tooltip_msg = LLTrans::getString("TooltipOutboxCannotMoveRoot");
+ }
+ if (is_movable && move_is_from_marketplacelistings && LLMarketplaceData::instance().getActivationState(cat_id))
+ {
+ // If the incoming folder is listed and active (and is therefore either the listing or the version folder),
+ // then moving is *not* allowed
+ is_movable = FALSE;
+ tooltip_msg = LLTrans::getString("TooltipOutboxDragActive");
+ }
if (is_movable && (mUUID == cat_id))
{
is_movable = FALSE;
@@ -2330,6 +2528,12 @@ BOOL LLFolderBridge::dragCategoryIntoFolder(LLInventoryCategory* inv_cat,
is_movable = FALSE;
// tooltip?
}
+ if (is_movable && (getPreferredType() == LLFolderType::FT_MARKETPLACE_STOCK))
+ {
+ // One cannot move a folder into a stock folder
+ is_movable = FALSE;
+ // tooltip?
+ }
LLInventoryModel::cat_array_t descendent_categories;
LLInventoryModel::item_array_t descendent_items;
@@ -2397,93 +2601,13 @@ BOOL LLFolderBridge::dragCategoryIntoFolder(LLInventoryCategory* inv_cat,
}
}
}
- if (is_movable && move_is_into_outbox)
+
+ if (is_movable && (move_is_into_outbox || move_is_into_marketplacelistings))
{
- const int nested_folder_levels = get_folder_path_length(outbox_id, mUUID) + get_folder_levels(inv_cat);
-
- if (nested_folder_levels > gSavedSettings.getU32("InventoryOutboxMaxFolderDepth"))
- {
- tooltip_msg = LLTrans::getString("TooltipOutboxFolderLevels");
- is_movable = FALSE;
- }
- else
- {
- int dragged_folder_count = descendent_categories.size();
- int existing_item_count = 0;
- int existing_folder_count = 0;
-
- const LLViewerInventoryCategory * master_folder = model->getFirstDescendantOf(outbox_id, mUUID);
-
- if (master_folder != NULL)
- {
- if (model->isObjectDescendentOf(cat_id, master_folder->getUUID()))
- {
- // Don't use count because we're already inside the same category anyway
- dragged_folder_count = 0;
- }
- else
- {
- existing_folder_count = 1; // Include the master folder in the count!
-
- // If we're in the drop operation as opposed to the drag without drop, we are doing a
- // single category at a time so don't block based on the total amount of cargo data items
- if (drop)
- {
- dragged_folder_count += 1;
- }
- else
- {
- // NOTE: The cargo id's count is a total of categories AND items but we err on the side of
- // prevention rather than letting too many folders into the hierarchy of the outbox,
- // when we're dragging the item to a new parent
- dragged_folder_count += LLToolDragAndDrop::instance().getCargoCount();
- }
- }
-
- // Tally the total number of categories and items inside the master folder
-
- LLInventoryModel::cat_array_t existing_categories;
- LLInventoryModel::item_array_t existing_items;
-
- model->collectDescendents(master_folder->getUUID(), existing_categories, existing_items, FALSE);
-
- existing_folder_count += existing_categories.size();
- existing_item_count += existing_items.size();
- }
- else
- {
- // Assume a single category is being dragged to the outbox since we evaluate one at a time
- // when not putting them under a parent item.
- dragged_folder_count += 1;
- }
-
- const int nested_folder_count = existing_folder_count + dragged_folder_count;
- const int nested_item_count = existing_item_count + descendent_items.size();
-
- if (nested_folder_count > gSavedSettings.getU32("InventoryOutboxMaxFolderCount"))
- {
- tooltip_msg = LLTrans::getString("TooltipOutboxTooManyFolders");
- is_movable = FALSE;
- }
- else if (nested_item_count > gSavedSettings.getU32("InventoryOutboxMaxItemCount"))
- {
- tooltip_msg = LLTrans::getString("TooltipOutboxTooManyObjects");
- is_movable = FALSE;
- }
-
- if (is_movable == TRUE)
- {
- for (S32 i=0; i < descendent_items.size(); ++i)
- {
- LLInventoryItem* item = descendent_items[i];
- if (!can_move_to_outbox(item, tooltip_msg))
- {
- is_movable = FALSE;
- break;
- }
- }
- }
- }
+ const LLViewerInventoryCategory * master_folder = (move_is_into_outbox ? model->getFirstDescendantOf(outbox_id, mUUID) : model->getFirstDescendantOf(marketplacelistings_id, mUUID));
+ LLViewerInventoryCategory * dest_folder = getCategory();
+ S32 bundle_size = (drop ? 1 : LLToolDragAndDrop::instance().getCargoCount());
+ is_movable = can_move_folder_to_marketplace(master_folder, dest_folder, inv_cat, tooltip_msg, bundle_size);
}
if (is_movable)
@@ -2526,6 +2650,48 @@ BOOL LLFolderBridge::dragCategoryIntoFolder(LLInventoryCategory* inv_cat,
if (accept && drop)
{
+ // Dropping in or out of marketplace needs (sometimes) confirmation
+ if (user_confirm && (move_is_from_marketplacelistings || move_is_into_marketplacelistings))
+ {
+ if (move_is_from_marketplacelistings && (LLMarketplaceData::instance().isInActiveFolder(cat_id) ||
+ LLMarketplaceData::instance().isListedAndActive(cat_id)))
+ {
+ if (LLMarketplaceData::instance().isListed(cat_id) || LLMarketplaceData::instance().isVersionFolder(cat_id))
+ {
+ // Move the active version folder or listing folder itself outside marketplace listings will unlist the listing so ask that question specifically
+ LLNotificationsUtil::add("ConfirmMerchantUnlist", LLSD(), LLSD(), boost::bind(&LLFolderBridge::callback_dropCategoryIntoFolder, this, _1, _2, inv_cat));
+ }
+ else
+ {
+ // Any other case will simply modify but not unlist an active listed listing
+ LLNotificationsUtil::add("ConfirmMerchantActiveChange", LLSD(), LLSD(), boost::bind(&LLFolderBridge::callback_dropCategoryIntoFolder, this, _1, _2, inv_cat));
+ }
+ return true;
+ }
+ if (move_is_from_marketplacelistings && LLMarketplaceData::instance().isVersionFolder(cat_id))
+ {
+ // Moving the version folder from its location will deactivate it. Ask confirmation.
+ LLNotificationsUtil::add("ConfirmMerchantClearVersion", LLSD(), LLSD(), boost::bind(&LLFolderBridge::callback_dropCategoryIntoFolder, this, _1, _2, inv_cat));
+ return true;
+ }
+ if (move_is_into_marketplacelistings && LLMarketplaceData::instance().isInActiveFolder(mUUID))
+ {
+ // Moving something in an active listed listing will modify it. Ask confirmation.
+ LLNotificationsUtil::add("ConfirmMerchantActiveChange", LLSD(), LLSD(), boost::bind(&LLFolderBridge::callback_dropCategoryIntoFolder, this, _1, _2, inv_cat));
+ return true;
+ }
+ if (move_is_from_marketplacelistings && LLMarketplaceData::instance().isListed(cat_id))
+ {
+ // Moving a whole listing folder will result in archival of SLM data. Ask confirmation.
+ LLNotificationsUtil::add("ConfirmListingCutOrDelete", LLSD(), LLSD(), boost::bind(&LLFolderBridge::callback_dropCategoryIntoFolder, this, _1, _2, inv_cat));
+ return true;
+ }
+ if (move_is_into_marketplacelistings && !move_is_from_marketplacelistings)
+ {
+ LLNotificationsUtil::add("ConfirmMerchantMoveInventory", LLSD(), LLSD(), boost::bind(&LLFolderBridge::callback_dropCategoryIntoFolder, this, _1, _2, inv_cat));
+ return true;
+ }
+ }
// Look for any gestures and deactivate them
if (move_is_into_trash)
{
@@ -2551,6 +2717,10 @@ BOOL LLFolderBridge::dragCategoryIntoFolder(LLInventoryCategory* inv_cat,
{
copy_folder_to_outbox(inv_cat, mUUID, cat_id, LLToolDragAndDrop::getOperationId());
}
+ else if (move_is_into_marketplacelistings)
+ {
+ move_folder_to_marketplacelistings(inv_cat, mUUID);
+ }
else
{
if (model->isObjectDescendentOf(cat_id, model->findCategoryUUIDForType(LLFolderType::FT_INBOX, false)))
@@ -2566,11 +2736,38 @@ BOOL LLFolderBridge::dragCategoryIntoFolder(LLInventoryCategory* inv_cat,
mUUID,
move_is_into_trash);
}
+ if (move_is_from_marketplacelistings)
+ {
+ // If we are moving a folder at the listing folder level (i.e. its parent is the marketplace listings folder)
+ if (from_folder_uuid == marketplacelistings_id)
+ {
+ // Clear the folder from the marketplace in case it is a listing folder
+ if (LLMarketplaceData::instance().isListed(cat_id))
+ {
+ LLMarketplaceData::instance().clearListing(cat_id);
+ }
+ }
+ else
+ {
+ // If we move from within an active (listed) listing, checks that it's still valid, if not, unlist
+ 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))
+ {
+ 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);
+ }
+ }
}
}
else if (LLToolDragAndDrop::SOURCE_WORLD == source)
{
- if (move_is_into_outbox)
+ if (move_is_into_outbox || move_is_into_marketplacelistings)
{
tooltip_msg = LLTrans::getString("TooltipOutboxNotInInventory");
accept = FALSE;
@@ -2582,7 +2779,7 @@ BOOL LLFolderBridge::dragCategoryIntoFolder(LLInventoryCategory* inv_cat,
}
else if (LLToolDragAndDrop::SOURCE_LIBRARY == source)
{
- if (move_is_into_outbox)
+ if (move_is_into_outbox || move_is_into_marketplacelistings)
{
tooltip_msg = LLTrans::getString("TooltipOutboxNotInInventory");
accept = FALSE;
@@ -2952,7 +3149,6 @@ void LLFolderBridge::performAction(LLInventoryModel* model, std::string action)
else if ("cut" == action)
{
cutToClipboard();
- gInventory.removeObject(mUUID);
return;
}
else if ("copy" == action)
@@ -2980,6 +3176,120 @@ void LLFolderBridge::performAction(LLInventoryModel* model, std::string action)
restoreItem();
return;
}
+ else if ("marketplace_list" == 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
+ {
+ LLMarketplaceData::instance().activateListing(mUUID,true);
+ }
+ }
+ return;
+ }
+ else if ("marketplace_activate" == 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
+ {
+ LLMarketplaceData::instance().setVersionFolder(category->getParentUUID(), mUUID);
+ }
+ }
+ return;
+ }
+ else if ("marketplace_unlist" == action)
+ {
+ if (depth_nesting_in_marketplace(mUUID) == 1)
+ {
+ LLMarketplaceData::instance().activateListing(mUUID,false,1);
+ }
+ return;
+ }
+ else if ("marketplace_deactivate" == action)
+ {
+ if (depth_nesting_in_marketplace(mUUID) == 2)
+ {
+ LLInventoryCategory* category = gInventory.getCategory(mUUID);
+ LLMarketplaceData::instance().setVersionFolder(category->getParentUUID(), LLUUID::null, 1);
+ }
+ return;
+ }
+ 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)
+ {
+ mMessage = "";
+ validates = validate_marketplacelistings(cat,boost::bind(&LLFolderBridge::gatherMessage, this, _1, _2, _3),true);
+ if (validates)
+ {
+ LLNotificationsUtil::add("MerchantForceValidateListing");
+ }
+ }
+
+ if (!validates)
+ {
+ LLSD subs;
+ subs["[ERROR_CODE]"] = mMessage;
+ LLNotificationsUtil::add("MerchantListingFailed", subs);
+ }
+ else
+ {
+ LLMarketplaceData::instance().createListing(mUUID);
+ }
+ return;
+ }
+ else if ("marketplace_disassociate_listing" == action)
+ {
+ LLMarketplaceData::instance().clearListing(mUUID);
+ return;
+ }
+ else if ("marketplace_get_listing" == action)
+ {
+ // This is used only to exercise the SLM API but won't be shown to end users
+ LLMarketplaceData::instance().getListing(mUUID);
+ return;
+ }
+ else if ("marketplace_associate_listing" == action)
+ {
+ LLFloaterAssociateListing::show(mUUID);
+ return;
+ }
+ else if ("marketplace_check_listing" == action)
+ {
+ LLSD data(mUUID);
+ LLFloaterReg::showInstance("marketplace_validation", data);
+ return;
+ }
+ else if ("marketplace_edit_listing" == action)
+ {
+ std::string url = LLMarketplaceData::instance().getListingURL(mUUID);
+ if (!url.empty())
+ {
+ LLUrlAction::openURL(url);
+ }
+ return;
+ }
#ifndef LL_RELEASE_FOR_DOWNLOAD
else if ("delete_system_folder" == action)
{
@@ -2996,17 +3306,31 @@ void LLFolderBridge::performAction(LLInventoryModel* model, std::string action)
const LLUUID outbox_id = getInventoryModel()->findCategoryUUIDForType(LLFolderType::FT_OUTBOX, false);
copy_folder_to_outbox(cat, outbox_id, cat->getUUID(), LLToolDragAndDrop::getOperationId());
}
-#if ENABLE_MERCHANT_SEND_TO_MARKETPLACE_CONTEXT_MENU
- else if (isMarketplaceSendAction(action))
+ else if (("move_to_marketplace_listings" == action) || ("copy_to_marketplace_listings" == action) || ("copy_or_move_to_marketplace_listings" == action))
{
- LL_INFOS() << "Send to marketplace action!" << LL_ENDL;
-
LLInventoryCategory * cat = gInventory.getCategory(mUUID);
if (!cat) return;
-
- send_to_marketplace(cat);
- }
-#endif // ENABLE_MERCHANT_SEND_TO_MARKETPLACE_CONTEXT_MENU
+ const LLUUID &marketplacelistings_id = model->findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS, false);
+ move_folder_to_marketplacelistings(cat, marketplacelistings_id, ("move_to_marketplace_listings" != action), (("copy_or_move_to_marketplace_listings" == action)));
+ }
+}
+
+void LLFolderBridge::gatherMessage(std::string& message, S32 depth, LLError::ELevel log_level)
+{
+ if (log_level >= LLError::LEVEL_ERROR)
+ {
+ if (!mMessage.empty())
+ {
+ // Currently, we do not gather all messages as it creates very long alerts
+ // Users can get to the whole list of errors on a listing using the "Check for Errors" audit button or "Check listing" right click menu
+ //mMessage += "\n";
+ return;
+ }
+ // Take the leading spaces out...
+ std::string::size_type start = message.find_first_not_of(" ");
+ // Append the message
+ mMessage += message.substr(start, message.length() - start);
+ }
}
void LLFolderBridge::openItem()
@@ -3076,25 +3400,24 @@ LLFolderType::EType LLFolderBridge::getPreferredType() const
// Icons for folders are based on the preferred type
LLUIImagePtr LLFolderBridge::getIcon() const
{
- LLFolderType::EType preferred_type = LLFolderType::FT_NONE;
- LLViewerInventoryCategory* cat = getCategory();
- if(cat)
- {
- preferred_type = cat->getPreferredType();
- }
- return getIcon(preferred_type);
+ return getFolderIcon(FALSE);
}
-// static
-LLUIImagePtr LLFolderBridge::getIcon(LLFolderType::EType preferred_type)
+LLUIImagePtr LLFolderBridge::getIconOpen() const
{
- return LLUI::getUIImage(LLViewerFolderType::lookupIconName(preferred_type, FALSE));
+ return getFolderIcon(TRUE);
}
-LLUIImagePtr LLFolderBridge::getIconOpen() const
+LLUIImagePtr LLFolderBridge::getFolderIcon(BOOL is_open) const
{
- return LLUI::getUIImage(LLViewerFolderType::lookupIconName(getPreferredType(), TRUE));
+ LLFolderType::EType preferred_type = getPreferredType();
+ return LLUI::getUIImage(LLViewerFolderType::lookupIconName(preferred_type, is_open));
+}
+// static : use by LLLinkFolderBridge to get the closed type icons
+LLUIImagePtr LLFolderBridge::getIcon(LLFolderType::EType preferred_type)
+{
+ return LLUI::getUIImage(LLViewerFolderType::lookupIconName(preferred_type, FALSE));
}
LLUIImagePtr LLFolderBridge::getIconOverlay() const
@@ -3106,14 +3429,6 @@ LLUIImagePtr LLFolderBridge::getIconOverlay() const
return NULL;
}
-std::string LLFolderBridge::getLabelSuffix() const
-{
- static LLCachedControl<F32> folder_loading_message_delay(gSavedSettings, "FolderLoadingMessageWaitTime", 0.5f);
- return mIsLoading && mTimeSinceRequestStart.getElapsedTimeF32() >= folder_loading_message_delay()
- ? llformat(" ( %s ) ", LLTrans::getString("LoadingData").c_str())
- : LLStringUtil::null;
-}
-
BOOL LLFolderBridge::renameItem(const std::string& new_name)
{
@@ -3197,10 +3512,42 @@ void LLFolderBridge::updateHierarchyCreationDate(time_t date)
void LLFolderBridge::pasteFromClipboard()
{
LLInventoryModel* model = getInventoryModel();
- if(model && isClipboardPasteable())
+ 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 BOOL paste_into_marketplacelistings = model->isObjectDescendentOf(mUUID, marketplacelistings_id);
+
+ if (paste_into_marketplacelistings && !LLMarketplaceData::instance().isListed(mUUID) && LLMarketplaceData::instance().isInActiveFolder(mUUID))
+ {
+ // Prompt the user if pasting in a marketplace active version listing (note that pasting right under the listing folder root doesn't need a prompt)
+ LLNotificationsUtil::add("ConfirmMerchantActiveChange", LLSD(), LLSD(), boost::bind(&LLFolderBridge::callback_pasteFromClipboard, this, _1, _2));
+ }
+ else
+ {
+ // Otherwise just do the paste
+ perform_pasteFromClipboard();
+ }
+ }
+}
+
+// Callback for pasteFromClipboard if DAMA required...
+void LLFolderBridge::callback_pasteFromClipboard(const LLSD& notification, const LLSD& response)
+{
+ S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
+ if (option == 0) // YES
+ {
+ perform_pasteFromClipboard();
+ }
+}
+
+void LLFolderBridge::perform_pasteFromClipboard()
+{
+ LLInventoryModel* model = getInventoryModel();
+ if (model && isClipboardPasteable())
+ {
+ const LLUUID &current_outfit_id = model->findCategoryUUIDForType(LLFolderType::FT_CURRENT_OUTFIT, false);
const LLUUID &outbox_id = model->findCategoryUUIDForType(LLFolderType::FT_OUTBOX, 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);
@@ -3208,58 +3555,70 @@ void LLFolderBridge::pasteFromClipboard()
const BOOL move_is_into_my_outfits = (mUUID == my_outifts_id) || model->isObjectDescendentOf(mUUID, my_outifts_id);
const BOOL move_is_into_outfit = move_is_into_my_outfits || (getCategory() && getCategory()->getPreferredType()==LLFolderType::FT_OUTFIT);
const BOOL move_is_into_outbox = model->isObjectDescendentOf(mUUID, outbox_id);
+ const BOOL move_is_into_marketplacelistings = model->isObjectDescendentOf(mUUID, marketplacelistings_id);
const BOOL move_is_into_favorites = (mUUID == favorites_id);
std::vector<LLUUID> objects;
LLClipboard::instance().pasteFromClipboard(objects);
-
- if (move_is_into_outbox)
- {
- LLFolderViewItem * outbox_itemp = mInventoryPanel.get()->getItemByID(mUUID);
-
- if (outbox_itemp)
- {
- LLToolDragAndDrop::instance().setCargoCount(objects.size());
-
- BOOL can_list = TRUE;
-
- for (std::vector<LLUUID>::const_iterator iter = objects.begin();
- (iter != objects.end()) && (can_list == TRUE);
- ++iter)
- {
- const LLUUID& item_id = (*iter);
- LLInventoryItem *item = model->getItem(item_id);
-
- if (item)
- {
- MASK mask = 0x0;
- BOOL drop = FALSE;
- EDragAndDropType cargo_type = LLViewerAssetType::lookupDragAndDropType(item->getActualType());
- void * cargo_data = (void *) item;
- std::string tooltip_msg;
-
- can_list = outbox_itemp->getViewModelItem()->dragOrDrop(mask, drop, cargo_type, cargo_data, tooltip_msg);
- }
- }
-
- LLToolDragAndDrop::instance().resetCargoCount();
-
- if (can_list == FALSE)
- {
- // Notify user of failure somehow -- play error sound? modal dialog?
- return;
- }
+
+ LLViewerInventoryCategory * dest_folder = getCategory();
+ if (move_is_into_outbox || move_is_into_marketplacelistings)
+ {
+ std::string error_msg;
+ const LLViewerInventoryCategory * master_folder = (move_is_into_outbox ? model->getFirstDescendantOf(outbox_id, mUUID) : model->getFirstDescendantOf(marketplacelistings_id, mUUID));
+ int index = 0;
+ for (std::vector<LLUUID>::const_iterator iter = objects.begin(); iter != objects.end(); ++iter)
+ {
+ const LLUUID& item_id = (*iter);
+ LLInventoryItem *item = model->getItem(item_id);
+ LLInventoryCategory *cat = model->getCategory(item_id);
+
+ if (item && !can_move_item_to_marketplace(master_folder, dest_folder, item, error_msg, objects.size() - index, true))
+ {
+ break;
+ }
+ if (cat && !can_move_folder_to_marketplace(master_folder, dest_folder, cat, error_msg, objects.size() - index, true, true))
+ {
+ break;
+ }
+ ++index;
}
+ if (!error_msg.empty())
+ {
+ LLSD subs;
+ subs["[ERROR_CODE]"] = error_msg;
+ LLNotificationsUtil::add("MerchantPasteFailed", subs);
+ return;
+ }
}
-
+ else
+ {
+ // Check that all items can be moved into that folder : for the moment, only stock folder mismatch is checked
+ for (std::vector<LLUUID>::const_iterator iter = objects.begin(); iter != objects.end(); ++iter)
+ {
+ const LLUUID& item_id = (*iter);
+ LLInventoryItem *item = model->getItem(item_id);
+ LLInventoryCategory *cat = model->getCategory(item_id);
+
+ if ((item && !dest_folder->acceptItem(item)) || (cat && (dest_folder->getPreferredType() == LLFolderType::FT_MARKETPLACE_STOCK)))
+ {
+ std::string error_msg = LLTrans::getString("TooltipOutboxMixedStock");
+ LLSD subs;
+ subs["[ERROR_CODE]"] = error_msg;
+ LLNotificationsUtil::add("StockPasteFailed", subs);
+ return;
+ }
+ }
+ }
+
const LLUUID parent_id(mUUID);
-
+
for (std::vector<LLUUID>::const_iterator iter = objects.begin();
iter != objects.end();
++iter)
{
const LLUUID& item_id = (*iter);
-
+
LLInventoryItem *item = model->getItem(item_id);
LLInventoryObject *obj = model->getObject(item_id);
if (obj)
@@ -3287,21 +3646,44 @@ void LLFolderBridge::pasteFromClipboard()
LLViewerInventoryCategory* vicat = (LLViewerInventoryCategory *) model->getCategory(item_id);
llassert(vicat);
if (vicat)
- {
- //changeCategoryParent() implicity calls dirtyFilter
- changeCategoryParent(model, vicat, parent_id, FALSE);
+ {
+ // Clear the cut folder from the marketplace if it is a listing folder
+ if (LLMarketplaceData::instance().isListed(item_id))
+ {
+ LLMarketplaceData::instance().clearListing(item_id);
+ }
+ if (move_is_into_marketplacelistings)
+ {
+ move_folder_to_marketplacelistings(vicat, parent_id);
+ }
+ else
+ {
+ //changeCategoryParent() implicity calls dirtyFilter
+ changeCategoryParent(model, vicat, parent_id, FALSE);
+ }
}
}
else
- {
- LLViewerInventoryItem* viitem = dynamic_cast<LLViewerInventoryItem*>(item);
- llassert(viitem);
- if (viitem)
- {
- //changeItemParent() implicity calls dirtyFilter
- changeItemParent(model, viitem, parent_id, FALSE);
- }
- }
+ {
+ LLViewerInventoryItem* viitem = dynamic_cast<LLViewerInventoryItem*>(item);
+ llassert(viitem);
+ if (viitem)
+ {
+ if (move_is_into_marketplacelistings)
+ {
+ if (!move_item_to_marketplacelistings(viitem, parent_id))
+ {
+ // Stop pasting into the marketplace as soon as we get an error
+ break;
+ }
+ }
+ else
+ {
+ //changeItemParent() implicity calls dirtyFilter
+ changeItemParent(model, viitem, parent_id, FALSE);
+ }
+ }
+ }
}
else
{
@@ -3312,22 +3694,45 @@ void LLFolderBridge::pasteFromClipboard()
llassert(vicat);
if (vicat)
{
- copy_inventory_category(model, vicat, parent_id);
+ if (move_is_into_marketplacelistings)
+ {
+ move_folder_to_marketplacelistings(vicat, parent_id, true);
+ }
+ else
+ {
+ copy_inventory_category(model, vicat, parent_id);
+ }
}
}
- else
- {
- copy_inventory_item(
- gAgent.getID(),
- item->getPermissions().getOwner(),
- item->getUUID(),
- parent_id,
- std::string(),
- LLPointer<LLInventoryCallback>(NULL));
- }
- }
- }
- }
+ else
+ {
+ LLViewerInventoryItem* viitem = dynamic_cast<LLViewerInventoryItem*>(item);
+ llassert(viitem);
+ if (viitem)
+ {
+ if (move_is_into_marketplacelistings)
+ {
+ if (!move_item_to_marketplacelistings(viitem, parent_id, true))
+ {
+ // Stop pasting into the marketplace as soon as we get an error
+ break;
+ }
+ }
+ else
+ {
+ copy_inventory_item(
+ gAgent.getID(),
+ item->getPermissions().getOwner(),
+ item->getUUID(),
+ parent_id,
+ std::string(),
+ LLPointer<LLInventoryCallback>(NULL));
+ }
+ }
+ }
+ }
+ }
+ }
// Change mode to paste for next paste
LLClipboard::instance().setCutMode(false);
}
@@ -3340,14 +3745,16 @@ void LLFolderBridge::pasteLinkFromClipboard()
{
const LLUUID &current_outfit_id = model->findCategoryUUIDForType(LLFolderType::FT_CURRENT_OUTFIT, false);
const LLUUID &outbox_id = model->findCategoryUUIDForType(LLFolderType::FT_OUTBOX, 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 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);
const BOOL move_is_into_outfit = move_is_into_my_outfits || (getCategory() && getCategory()->getPreferredType()==LLFolderType::FT_OUTFIT);
const BOOL move_is_into_outbox = model->isObjectDescendentOf(mUUID, outbox_id);
+ const BOOL move_is_into_marketplacelistings = model->isObjectDescendentOf(mUUID, marketplacelistings_id);
- if (move_is_into_outbox)
+ if (move_is_into_outbox || move_is_into_marketplacelistings)
{
// Notify user of failure somehow -- play error sound? modal dialog?
return;
@@ -3407,9 +3814,10 @@ void LLFolderBridge::buildContextMenuOptions(U32 flags, menuentry_vec_t& items
LLInventoryModel* model = getInventoryModel();
llassert(model != NULL);
- 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 &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);
if (lost_and_found_id == mUUID)
{
@@ -3427,6 +3835,35 @@ void LLFolderBridge::buildContextMenuOptions(U32 flags, menuentry_vec_t& items
{
disabled_items.push_back(std::string("New Folder"));
}
+ if (isMarketplaceListingsFolder())
+ {
+ addMarketplaceContextMenuOptions(flags, items, disabled_items);
+ if (LLMarketplaceData::instance().isUpdating(mUUID))
+ {
+ disabled_items.push_back(std::string("New Folder"));
+ disabled_items.push_back(std::string("Rename"));
+ disabled_items.push_back(std::string("Cut"));
+ disabled_items.push_back(std::string("Copy"));
+ disabled_items.push_back(std::string("Paste"));
+ disabled_items.push_back(std::string("Delete"));
+ }
+ }
+ 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"));
+ }
+ if (marketplace_listings_id == mUUID)
+ {
+ disabled_items.push_back(std::string("New Folder"));
+ disabled_items.push_back(std::string("Rename"));
+ disabled_items.push_back(std::string("Cut"));
+ disabled_items.push_back(std::string("Delete"));
+ }
if(trash_id == mUUID)
{
// This is the trash.
@@ -3456,12 +3893,14 @@ void LLFolderBridge::buildContextMenuOptions(U32 flags, menuentry_vec_t& items
{
items.push_back(std::string("New Folder"));
}
-
- 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"));
+ 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"));
+ }
}
getClipboardEntries(false, items, disabled_items, flags);
}
@@ -3495,9 +3934,9 @@ void LLFolderBridge::buildContextMenuOptions(U32 flags, menuentry_vec_t& items
LLIsType is_object( LLAssetType::AT_OBJECT );
LLIsType is_gesture( LLAssetType::AT_GESTURE );
- if (checkFolderForContentsOfType(model, is_wearable) ||
- checkFolderForContentsOfType(model, is_object) ||
- checkFolderForContentsOfType(model, is_gesture) )
+ if (checkFolderForContentsOfType(model, is_wearable) ||
+ checkFolderForContentsOfType(model, is_object) ||
+ checkFolderForContentsOfType(model, is_gesture) )
{
mWearables=TRUE;
}
@@ -3509,7 +3948,7 @@ void LLFolderBridge::buildContextMenuOptions(U32 flags, menuentry_vec_t& items
disabled_items.push_back(std::string("Delete System Folder"));
}
- if (!isOutboxFolder())
+ if (!isOutboxFolder() && !isMarketplaceListingsFolder())
{
items.push_back(std::string("Share"));
if (!canShare())
@@ -3519,7 +3958,7 @@ void LLFolderBridge::buildContextMenuOptions(U32 flags, menuentry_vec_t& items
}
// Add menu items that are dependent on the contents of the folder.
LLViewerInventoryCategory* category = (LLViewerInventoryCategory *) model->getCategory(mUUID);
- if (category)
+ if (category && (marketplace_listings_id != mUUID))
{
uuid_vec_t folders;
folders.push_back(category->getUUID());
@@ -3538,8 +3977,8 @@ void LLFolderBridge::buildContextMenuOptions(U32 flags, menuentry_vec_t& items
{
// it's all on its way - add an observer, and the inventory will call done for us when everything is here.
gInventory.addObserver(fetch);
- }
-}
+ }
+ }
}
void LLFolderBridge::buildContextMenuFolderOptions(U32 flags, menuentry_vec_t& items, menuentry_vec_t& disabled_items)
@@ -3556,6 +3995,12 @@ void LLFolderBridge::buildContextMenuFolderOptions(U32 flags, menuentry_vec_t&
if (isItemInTrash()) return;
if (!isAgentInventory()) return;
if (isOutboxFolder()) return;
+
+ if (!isItemRemovable())
+ {
+ disabled_items.push_back(std::string("Delete"));
+ }
+ if (isMarketplaceListingsFolder()) return;
LLFolderType::EType type = category->getPreferredType();
const bool is_system_folder = LLFolderType::lookupIsProtectedType(type);
@@ -3575,11 +4020,6 @@ void LLFolderBridge::buildContextMenuFolderOptions(U32 flags, menuentry_vec_t&
}
}
- if (!isItemRemovable())
- {
- disabled_items.push_back(std::string("Delete"));
- }
-
#ifndef LL_RELEASE_FOR_DOWNLOAD
if (LLFolderType::lookupIsProtectedType(type))
{
@@ -3868,6 +4308,121 @@ void LLFolderBridge::modifyOutfit(BOOL append)
LLAppearanceMgr::instance().wearInventoryCategory( cat, FALSE, append );
}
+// +=================================================+
+// | LLMarketplaceFolderBridge |
+// +=================================================+
+
+// LLMarketplaceFolderBridge is a specialized LLFolderBridge for use in Marketplace Inventory panels
+LLMarketplaceFolderBridge::LLMarketplaceFolderBridge(LLInventoryPanel* inventory,
+ LLFolderView* root,
+ const LLUUID& uuid) :
+LLFolderBridge(inventory, root, uuid)
+{
+ m_depth = depth_nesting_in_marketplace(mUUID);
+ m_stockCountCache = COMPUTE_STOCK_NOT_EVALUATED;
+}
+
+LLUIImagePtr LLMarketplaceFolderBridge::getIcon() const
+{
+ return getMarketplaceFolderIcon(FALSE);
+}
+
+LLUIImagePtr LLMarketplaceFolderBridge::getIconOpen() const
+{
+ return getMarketplaceFolderIcon(TRUE);
+}
+
+LLUIImagePtr LLMarketplaceFolderBridge::getMarketplaceFolderIcon(BOOL is_open) const
+{
+ LLFolderType::EType preferred_type = getPreferredType();
+ if (!LLMarketplaceData::instance().isUpdating(getUUID()))
+ {
+ // Skip computation (expensive) if we're waiting for updates. Use the old value in that case.
+ m_depth = depth_nesting_in_marketplace(mUUID);
+ }
+ if ((preferred_type == LLFolderType::FT_NONE) && (m_depth == 2))
+ {
+ // We override the type when in the marketplace listings folder and only for version folder
+ preferred_type = LLFolderType::FT_MARKETPLACE_VERSION;
+ }
+ return LLUI::getUIImage(LLViewerFolderType::lookupIconName(preferred_type, is_open));
+}
+
+std::string LLMarketplaceFolderBridge::getLabelSuffix() const
+{
+ static LLCachedControl<F32> folder_loading_message_delay(gSavedSettings, "FolderLoadingMessageWaitTime", 0.5f);
+
+ if (mIsLoading && mTimeSinceRequestStart.getElapsedTimeF32() >= folder_loading_message_delay())
+ {
+ return llformat(" ( %s ) ", LLTrans::getString("LoadingData").c_str());
+ }
+
+ std::string suffix = "";
+ // Listing folder case
+ if (LLMarketplaceData::instance().isListed(getUUID()))
+ {
+ suffix = llformat("%d",LLMarketplaceData::instance().getListingID(getUUID()));
+ if (suffix.empty())
+ {
+ suffix = LLTrans::getString("MarketplaceNoID");
+ }
+ suffix = " (" + suffix + ")";
+ if (LLMarketplaceData::instance().getActivationState(getUUID()))
+ {
+ suffix += " (" + LLTrans::getString("MarketplaceLive") + ")";
+ }
+ }
+ // Version folder case
+ else if (LLMarketplaceData::instance().isVersionFolder(getUUID()))
+ {
+ suffix += " (" + LLTrans::getString("MarketplaceActive") + ")";
+ }
+ // Add stock amount
+ bool updating = LLMarketplaceData::instance().isUpdating(getUUID());
+ if (!updating)
+ {
+ // Skip computation (expensive) if we're waiting for update anyway. Use the old value in that case.
+ m_stockCountCache = compute_stock_count(getUUID());
+ }
+ if (m_stockCountCache == 0)
+ {
+ suffix += " (" + LLTrans::getString("MarketplaceNoStock") + ")";
+ }
+ else if (m_stockCountCache != COMPUTE_STOCK_INFINITE)
+ {
+ if (getPreferredType() == LLFolderType::FT_MARKETPLACE_STOCK)
+ {
+ suffix += " (" + LLTrans::getString("MarketplaceStock");
+ }
+ else
+ {
+ suffix += " (" + LLTrans::getString("MarketplaceMax");
+ }
+ if (m_stockCountCache == COMPUTE_STOCK_NOT_EVALUATED)
+ {
+ suffix += "=" + LLTrans::getString("MarketplaceUpdating") + ")";
+ }
+ else
+ {
+ suffix += "=" + llformat("%d", m_stockCountCache) + ")";
+ }
+ }
+ // Add updating suffix
+ if (updating)
+ {
+ suffix += " (" + LLTrans::getString("MarketplaceUpdating") + ")";
+ }
+ return LLInvFVBridge::getLabelSuffix() + suffix;
+}
+
+LLFontGL::StyleFlags LLMarketplaceFolderBridge::getLabelStyle() const
+{
+ return (LLMarketplaceData::instance().getActivationState(getUUID()) ? LLFontGL::BOLD : LLFontGL::NORMAL);
+}
+
+
+
+
// helper stuff
bool move_task_inventory_callback(const LLSD& notification, const LLSD& response, LLMoveInv* move_inv)
{
@@ -3988,12 +4543,35 @@ void LLFolderBridge::dropToOutfit(LLInventoryItem* inv_item, BOOL move_is_into_c
}
}
+// Callback for drop item if DAMA required...
+void LLFolderBridge::callback_dropItemIntoFolder(const LLSD& notification, const LLSD& response, LLInventoryItem* inv_item)
+{
+ S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
+ if (option == 0) // YES
+ {
+ std::string tooltip_msg;
+ dragItemIntoFolder(inv_item, TRUE, tooltip_msg, FALSE);
+ }
+}
+
+// Callback for drop category if DAMA required...
+void LLFolderBridge::callback_dropCategoryIntoFolder(const LLSD& notification, const LLSD& response, LLInventoryCategory* inv_category)
+{
+ S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
+ if (option == 0) // YES
+ {
+ std::string tooltip_msg;
+ dragCategoryIntoFolder(inv_category, TRUE, tooltip_msg, FALSE);
+ }
+}
+
// This is used both for testing whether an item can be dropped
// into the folder, as well as performing the actual drop, depending
// if drop == TRUE.
BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item,
BOOL drop,
- std::string& tooltip_msg)
+ std::string& tooltip_msg,
+ BOOL user_confirm)
{
LLInventoryModel* model = getInventoryModel();
@@ -4011,7 +4589,9 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item,
const LLUUID &favorites_id = model->findCategoryUUIDForType(LLFolderType::FT_FAVORITE, false);
const LLUUID &landmarks_id = model->findCategoryUUIDForType(LLFolderType::FT_LANDMARK, false);
const LLUUID &outbox_id = model->findCategoryUUIDForType(LLFolderType::FT_OUTBOX, 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 from_folder_uuid = inv_item->getParentUUID();
const BOOL move_is_into_current_outfit = (mUUID == current_outfit_id);
const BOOL move_is_into_favorites = (mUUID == favorites_id);
@@ -4020,6 +4600,8 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item,
const BOOL move_is_into_landmarks = (mUUID == landmarks_id) || model->isObjectDescendentOf(mUUID, landmarks_id);
const BOOL move_is_into_outbox = model->isObjectDescendentOf(mUUID, outbox_id);
const BOOL move_is_from_outbox = model->isObjectDescendentOf(inv_item->getUUID(), outbox_id);
+ const BOOL move_is_into_marketplacelistings = model->isObjectDescendentOf(mUUID, marketplacelistings_id);
+ const BOOL move_is_from_marketplacelistings = model->isObjectDescendentOf(inv_item->getUUID(), marketplacelistings_id);
LLToolDragAndDrop::ESource source = LLToolDragAndDrop::getInstance()->getSource();
BOOL accept = FALSE;
@@ -4073,59 +4655,45 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item,
//--------------------------------------------------------------------------------
// Determine if item can be moved & dropped
- //
+ // Note: if user_confirm is false, we already went through those accept logic test and can skip them
accept = TRUE;
- if (!is_movable)
+ if (user_confirm && !is_movable)
{
accept = FALSE;
}
- else if ((mUUID == inv_item->getParentUUID()) && !move_is_into_favorites)
+ else if (user_confirm && (mUUID == inv_item->getParentUUID()) && !move_is_into_favorites)
{
accept = FALSE;
}
- else if (move_is_into_current_outfit || move_is_into_outfit)
+ else if (user_confirm && (move_is_into_current_outfit || move_is_into_outfit))
{
accept = can_move_to_outfit(inv_item, move_is_into_current_outfit);
}
- else if (move_is_into_favorites || move_is_into_landmarks)
+ else if (user_confirm && (move_is_into_favorites || move_is_into_landmarks))
{
accept = can_move_to_landmarks(inv_item);
}
- else if (move_is_into_outbox)
+ else if (user_confirm && (move_is_into_outbox || move_is_into_marketplacelistings))
{
- accept = can_move_to_outbox(inv_item, tooltip_msg);
-
- if (accept)
- {
- const LLViewerInventoryCategory * master_folder = model->getFirstDescendantOf(outbox_id, mUUID);
-
- int existing_item_count = LLToolDragAndDrop::instance().getCargoCount();
-
- if (master_folder != NULL)
- {
- LLInventoryModel::cat_array_t existing_categories;
- LLInventoryModel::item_array_t existing_items;
-
- gInventory.collectDescendents(master_folder->getUUID(), existing_categories, existing_items, FALSE);
-
- existing_item_count += existing_items.size();
- }
-
- if (existing_item_count > gSavedSettings.getU32("InventoryOutboxMaxItemCount"))
- {
- tooltip_msg = LLTrans::getString("TooltipOutboxTooManyObjects");
- accept = FALSE;
- }
- }
+ const LLViewerInventoryCategory * master_folder = (move_is_into_outbox ? model->getFirstDescendantOf(outbox_id, mUUID) : model->getFirstDescendantOf(marketplacelistings_id, mUUID));
+ LLViewerInventoryCategory * dest_folder = getCategory();
+ accept = can_move_item_to_marketplace(master_folder, dest_folder, inv_item, tooltip_msg, LLToolDragAndDrop::instance().getCargoCount() - LLToolDragAndDrop::instance().getCargoIndex());
}
+ // Check that the folder can accept this item based on folder/item type compatibility (e.g. stock folder compatibility)
+ if (user_confirm && accept)
+ {
+ LLViewerInventoryCategory * dest_folder = getCategory();
+ accept = dest_folder->acceptItem(inv_item);
+ }
+
LLInventoryPanel* active_panel = LLInventoryPanel::getActiveInventoryPanel(FALSE);
// Check whether the item being dragged from active inventory panel
// passes the filter of the destination panel.
- if (accept && active_panel && use_filter)
+ if (user_confirm && accept && active_panel && use_filter)
{
LLFolderViewItem* fv_item = active_panel->getItemByID(inv_item->getUUID());
if (!fv_item) return false;
@@ -4145,9 +4713,25 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item,
// RN: a better solution would be to deselect automatically when an item is moved
// and then select any item that is dropped only in the panel that it is dropped in
if (active_panel && (destination_panel != active_panel))
- {
- active_panel->unSelectAll();
- }
+ {
+ active_panel->unSelectAll();
+ }
+ // Dropping in or out of marketplace needs (sometimes) confirmation
+ if (user_confirm && (move_is_from_marketplacelistings || move_is_into_marketplacelistings))
+ {
+ if ((move_is_from_marketplacelistings && (LLMarketplaceData::instance().isInActiveFolder(inv_item->getUUID())
+ || LLMarketplaceData::instance().isListedAndActive(inv_item->getUUID()))) ||
+ (move_is_into_marketplacelistings && LLMarketplaceData::instance().isInActiveFolder(mUUID)))
+ {
+ LLNotificationsUtil::add("ConfirmMerchantActiveChange", LLSD(), LLSD(), boost::bind(&LLFolderBridge::callback_dropItemIntoFolder, this, _1, _2, inv_item));
+ return true;
+ }
+ if (move_is_into_marketplacelistings && !move_is_from_marketplacelistings)
+ {
+ LLNotificationsUtil::add("ConfirmMerchantMoveInventory", LLSD(), LLSD(), boost::bind(&LLFolderBridge::callback_dropItemIntoFolder, this, _1, _2, inv_item));
+ return true;
+ }
+ }
//--------------------------------------------------------------------------------
// Destination folder logic
@@ -4160,7 +4744,7 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item,
LLFolderViewItem* itemp = destination_panel->getRootFolder()->getDraggingOverItem();
if (itemp)
{
- LLUUID srcItemId = inv_item->getUUID();
+ LLUUID srcItemId = inv_item->getUUID();
LLUUID destItemId = static_cast<LLFolderViewModelItemInventory*>(itemp->getViewModelItem())->getUUID();
LLFavoritesOrderStorage::instance().rearrangeFavoriteLandmarks(srcItemId, destItemId);
}
@@ -4178,6 +4762,8 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item,
{
dropToOutfit(inv_item, move_is_into_current_outfit);
}
+ // MERCHANT OUTBOX folder
+ // Move the item
else if (move_is_into_outbox)
{
if (move_is_from_outbox)
@@ -4189,6 +4775,12 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item,
copy_item_to_outbox(inv_item, mUUID, LLUUID::null, LLToolDragAndDrop::getOperationId());
}
}
+ // MARKETPLACE LISTINGS folder
+ // Move the item
+ else if (move_is_into_marketplacelistings)
+ {
+ move_item_to_marketplacelistings(inv_item, mUUID);
+ }
// NORMAL or TRASH folder
// (move the item, restamp if into trash)
else
@@ -4205,8 +4797,22 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item,
mUUID,
move_is_into_trash);
}
-
- //
+
+ if (move_is_from_marketplacelistings)
+ {
+ // If we move from an active (listed) listing, checks that it's still valid, if not, unlist
+ 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))
+ {
+ LLMarketplaceData::instance().activateListing(version_folder_id,false);
+ }
+ }
+ }
+
+ //
//--------------------------------------------------------------------------------
}
}
@@ -4255,7 +4861,7 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item,
{
accept = FALSE;
}
- else if (move_is_into_outbox)
+ else if (move_is_into_outbox || move_is_into_marketplacelistings)
{
tooltip_msg = LLTrans::getString("TooltipOutboxNotInInventory");
accept = FALSE;
@@ -4293,7 +4899,7 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item,
}
else if(LLToolDragAndDrop::SOURCE_NOTECARD == source)
{
- if (move_is_into_outbox)
+ if (move_is_into_outbox || move_is_into_marketplacelistings)
{
tooltip_msg = LLTrans::getString("TooltipOutboxNotInInventory");
accept = FALSE;
@@ -4327,7 +4933,7 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item,
{
accept = TRUE;
- if (move_is_into_outbox)
+ if (move_is_into_outbox || move_is_into_marketplacelistings)
{
tooltip_msg = LLTrans::getString("TooltipOutboxNotInInventory");
accept = FALSE;
@@ -4500,6 +5106,12 @@ void LLTextureBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
{
addOutboxContextMenuOptions(flags, items, disabled_items);
}
+ else if (isMarketplaceListingsFolder())
+ {
+ addMarketplaceContextMenuOptions(flags, items, disabled_items);
+ items.push_back(std::string("Properties"));
+ getClipboardEntries(false, items, disabled_items, flags);
+ }
else
{
items.push_back(std::string("Share"));
@@ -4567,6 +5179,12 @@ void LLSoundBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
{
addOutboxContextMenuOptions(flags, items, disabled_items);
}
+ else if (isMarketplaceListingsFolder())
+ {
+ addMarketplaceContextMenuOptions(flags, items, disabled_items);
+ items.push_back(std::string("Properties"));
+ getClipboardEntries(false, items, disabled_items, flags);
+ }
else
{
if (isItemInTrash())
@@ -4642,6 +5260,12 @@ void LLLandmarkBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
{
addOutboxContextMenuOptions(flags, items, disabled_items);
}
+ else if (isMarketplaceListingsFolder())
+ {
+ addMarketplaceContextMenuOptions(flags, items, disabled_items);
+ items.push_back(std::string("Properties"));
+ getClipboardEntries(false, items, disabled_items, flags);
+ }
else
{
if(isItemInTrash())
@@ -4934,6 +5558,12 @@ void LLCallingCardBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
{
items.push_back(std::string("Delete"));
}
+ else if (isMarketplaceListingsFolder())
+ {
+ addMarketplaceContextMenuOptions(flags, items, disabled_items);
+ items.push_back(std::string("Properties"));
+ getClipboardEntries(false, items, disabled_items, flags);
+ }
else
{
items.push_back(std::string("Share"));
@@ -5066,6 +5696,25 @@ void LLNotecardBridge::openItem()
}
}
+void LLNotecardBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
+{
+ LL_DEBUGS() << "LLNotecardBridge::buildContextMenu()" << LL_ENDL;
+
+ if (isMarketplaceListingsFolder())
+ {
+ menuentry_vec_t items;
+ menuentry_vec_t disabled_items;
+ addMarketplaceContextMenuOptions(flags, items, disabled_items);
+ items.push_back(std::string("Properties"));
+ getClipboardEntries(false, items, disabled_items, flags);
+ hide_context_entries(menu, items, disabled_items);
+ }
+ else
+ {
+ LLItemBridge::buildContextMenu(menu, flags);
+ }
+}
+
// +=================================================+
// | LLGestureBridge |
// +=================================================+
@@ -5201,6 +5850,12 @@ void LLGestureBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
{
items.push_back(std::string("Delete"));
}
+ else if (isMarketplaceListingsFolder())
+ {
+ addMarketplaceContextMenuOptions(flags, items, disabled_items);
+ items.push_back(std::string("Properties"));
+ getClipboardEntries(false, items, disabled_items, flags);
+ }
else
{
items.push_back(std::string("Share"));
@@ -5255,6 +5910,12 @@ void LLAnimationBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
{
items.push_back(std::string("Delete"));
}
+ else if (isMarketplaceListingsFolder())
+ {
+ addMarketplaceContextMenuOptions(flags, items, disabled_items);
+ items.push_back(std::string("Properties"));
+ getClipboardEntries(false, items, disabled_items, flags);
+ }
else
{
if(isItemInTrash())
@@ -5514,6 +6175,12 @@ void LLObjectBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
{
items.push_back(std::string("Delete"));
}
+ else if (isMarketplaceListingsFolder())
+ {
+ addMarketplaceContextMenuOptions(flags, items, disabled_items);
+ items.push_back(std::string("Properties"));
+ getClipboardEntries(false, items, disabled_items, flags);
+ }
else
{
items.push_back(std::string("Share"));
@@ -5736,6 +6403,12 @@ void LLWearableBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
{
items.push_back(std::string("Delete"));
}
+ else if (isMarketplaceListingsFolder())
+ {
+ addMarketplaceContextMenuOptions(flags, items, disabled_items);
+ items.push_back(std::string("Properties"));
+ getClipboardEntries(false, items, disabled_items, flags);
+ }
else
{ // FWIW, it looks like SUPPRESS_OPEN_ITEM is not set anywhere
BOOL can_open = ((flags & SUPPRESS_OPEN_ITEM) != SUPPRESS_OPEN_ITEM);
@@ -6036,6 +6709,12 @@ void LLMeshBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
{
addOutboxContextMenuOptions(flags, items, disabled_items);
}
+ else if (isMarketplaceListingsFolder())
+ {
+ addMarketplaceContextMenuOptions(flags, items, disabled_items);
+ items.push_back(std::string("Properties"));
+ getClipboardEntries(false, items, disabled_items, flags);
+ }
else
{
items.push_back(std::string("Properties"));