summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLeyla Farazha <leyla@lindenlab.com>2011-07-29 17:01:24 -0700
committerLeyla Farazha <leyla@lindenlab.com>2011-07-29 17:01:24 -0700
commited02d0c1fccbfd25ed54f6be5b051736834d2e27 (patch)
tree94090f29d253a7aa9a5ceed6d850e7e6df1b4e40
parent0b9327df241e1a5a4693c690810ce8c330e196ad (diff)
EXP-843 Enable drag and drop to and from the outbox, with conditional warnings based on permissions
EXP-1034 Add confirmation dialog for moving no-copy items to outbox
-rw-r--r--indra/newview/llinventorybridge.cpp158
-rw-r--r--indra/newview/llinventorybridge.h4
-rw-r--r--indra/newview/llpanelmarketplaceoutbox.cpp27
-rw-r--r--indra/newview/llpanelmarketplaceoutbox.h6
-rw-r--r--indra/newview/skins/default/xui/en/notifications.xml16
5 files changed, 204 insertions, 7 deletions
diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp
index ff328fd071..8eacb5a719 100644
--- a/indra/newview/llinventorybridge.cpp
+++ b/indra/newview/llinventorybridge.cpp
@@ -573,7 +573,7 @@ void LLInvFVBridge::getClipboardEntries(bool show_asset_id,
}
// Don't allow items to be pasted directly into the COF or the inbox
- if (!isCOFFolder() && !isInboxFolder())
+ if (!isCOFFolder() && !isInboxFolder() && !isOutboxFolder())
{
items.push_back(std::string("Paste"));
}
@@ -794,6 +794,20 @@ BOOL LLInvFVBridge::isInboxFolder() const
return gInventory.isObjectDescendentOf(mUUID, inbox_id);
}
+
+BOOL LLInvFVBridge::isOutboxFolder() const
+{
+ const LLUUID outbox_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_OUTBOX, false, false);
+
+ if (outbox_id.isNull())
+ {
+ return FALSE;
+ }
+
+ return gInventory.isObjectDescendentOf(mUUID, outbox_id);
+}
+
+
BOOL LLInvFVBridge::isItemPermissive() const
{
return FALSE;
@@ -1648,6 +1662,55 @@ BOOL LLFolderBridge::isClipboardPasteableAsLink() const
}
+static BOOL can_move_to_outbox(LLInventoryItem* inv_item)
+{
+ return inv_item->getPermissions().allowOperationBy(PERM_TRANSFER, gAgent.getID());
+}
+
+
+void LLFolderBridge::dropFolderToOutbox(LLInventoryCategory* inv_cat)
+{
+ LLUUID dest_folder_id = gInventory.createNewCategory(mUUID, LLFolderType::FT_NONE, inv_cat->getName());
+
+ LLInventoryModel::cat_array_t* cat_array;
+ LLInventoryModel::item_array_t* item_array;
+ gInventory.getDirectDescendentsOf(inv_cat->getUUID(),cat_array,item_array);
+
+ for (LLInventoryModel::item_array_t::iterator iter = item_array->begin(); iter != item_array->end(); iter++)
+ {
+ LLInventoryItem* item = *iter;
+ if (item->getPermissions().allowOperationBy(PERM_COPY, gAgent.getID(), gAgent.getGroupID()))
+ {
+ //LLPointer<LLInventoryCallback> cb = new OutboxMoveCallback();
+ copy_inventory_item(
+ gAgent.getID(),
+ item->getPermissions().getOwner(),
+ item->getUUID(),
+ dest_folder_id,
+ item->getName(),
+ LLPointer<LLInventoryCallback>(NULL));
+
+ }
+ else
+ {
+ LLSD args;
+ args["ITEM_NAME"] = item->getName();
+ LLSD payload;
+ payload["item_id"] = item->getUUID();
+ payload["dest_folder_id"] = dest_folder_id;
+ LLNotificationsUtil::add("ConfirmNoCopyToOutbox", args, payload, boost::bind(&LLFolderBridge::moveToOutbox, this, _1, _2));
+ }
+
+ }
+ /*
+ // we need to also drill down recursively
+ for (LLInventoryModel::cat_array_t::iterator iter = cat_array->begin(); iter != cat_array->end(); iter++)
+ {
+ LLViewerInventoryCategory* category = gInventory.getCategory(dest_folder_id);
+ }
+ */
+}
+
BOOL LLFolderBridge::dragCategoryIntoFolder(LLInventoryCategory* inv_cat,
BOOL drop)
{
@@ -1674,10 +1737,12 @@ BOOL LLFolderBridge::dragCategoryIntoFolder(LLInventoryCategory* inv_cat,
const LLUUID &cat_id = inv_cat->getUUID();
const LLUUID &trash_id = model->findCategoryUUIDForType(LLFolderType::FT_TRASH, false);
const LLUUID &landmarks_id = model->findCategoryUUIDForType(LLFolderType::FT_LANDMARK, false);
-
+ const LLUUID &outbox_id = model->findCategoryUUIDForType(LLFolderType::FT_OUTBOX, false);
+
const BOOL move_is_into_trash = (mUUID == trash_id) || model->isObjectDescendentOf(mUUID, trash_id);
const BOOL move_is_into_outfit = getCategory() && (getCategory()->getPreferredType() == LLFolderType::FT_OUTFIT);
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);
//--------------------------------------------------------------------------------
// Determine if folder can be moved.
@@ -1730,6 +1795,18 @@ BOOL LLFolderBridge::dragCategoryIntoFolder(LLInventoryCategory* inv_cat,
}
}
}
+ if (move_is_into_outbox)
+ {
+ for (S32 i=0; i < descendent_items.count(); ++i)
+ {
+ LLInventoryItem* item = descendent_items[i];
+ if (!can_move_to_outbox(item))
+ {
+ is_movable = FALSE;
+ break;
+ }
+ }
+ }
//
//--------------------------------------------------------------------------------
@@ -1797,6 +1874,10 @@ BOOL LLFolderBridge::dragCategoryIntoFolder(LLInventoryCategory* inv_cat,
#endif
}
}
+ if (move_is_into_outbox)
+ {
+ dropFolderToOutbox(inv_cat);
+ }
else
{
if (gInventory.isObjectDescendentOf(inv_cat->getUUID(), gInventory.findCategoryUUIDForType(LLFolderType::FT_INBOX, false, false)))
@@ -2635,7 +2716,7 @@ void LLFolderBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
// Not sure what the right thing is to do here.
if (!isCOFFolder() && cat && (cat->getPreferredType() != LLFolderType::FT_OUTFIT))
{
- if (!isInboxFolder()) // don't allow creation in inbox
+ if (!isInboxFolder() && !isOutboxFolder()) // don't allow creation in inbox
{
// Do not allow to create 2-level subfolder in the Calling Card/Friends folder. EXT-694.
if (!LLFriendCardsManager::instance().isCategoryInFriendFolder(cat))
@@ -3003,6 +3084,67 @@ static BOOL can_move_to_landmarks(LLInventoryItem* inv_item)
return LLAssetType::AT_LANDMARK == inv_item->getType();
}
+void LLFolderBridge::dropToOutbox(LLInventoryItem* inv_item)
+{
+ if (inv_item->getPermissions().allowOperationBy(PERM_COPY, gAgent.getID(), gAgent.getGroupID()))
+ {
+ LLUUID dest_folder_id = mUUID;
+
+ // when moving item directly into outbox create folder with that name
+ if (mUUID == gInventory.findCategoryUUIDForType(LLFolderType::FT_OUTBOX, false))
+ {
+ dest_folder_id = gInventory.createNewCategory(mUUID, LLFolderType::FT_NONE, inv_item->getName());
+ }
+
+ copy_inventory_item(
+ gAgent.getID(),
+ inv_item->getPermissions().getOwner(),
+ inv_item->getUUID(),
+ dest_folder_id,
+ inv_item->getName(),
+ LLPointer<LLInventoryCallback>(NULL));
+
+ }
+ else
+ {
+ LLSD args;
+ args["ITEM_NAME"] = inv_item->getName();
+ LLSD payload;
+ payload["item_id"] = inv_item->getUUID();
+ payload["dest_folder_id"] = mUUID;
+ LLNotificationsUtil::add("ConfirmNoCopyToOutbox", args, payload, boost::bind(&LLFolderBridge::moveToOutbox, this, _1, _2));
+ }
+}
+
+
+void LLFolderBridge::moveToOutbox(const LLSD& notification, const LLSD& response)
+{
+ S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
+ if (option != 0) return; // canceled
+
+
+ LLInventoryModel* model = getInventoryModel();
+ LLViewerInventoryItem * viitem = gInventory.getItem(notification["payload"]["item_id"].asUUID());
+ LLUUID dest_folder_id = notification["payload"]["dest_folder_id"].asUUID();
+
+ if (viitem)
+ {
+
+ // when moving item directly into outbox create folder with that name
+ if (dest_folder_id == gInventory.findCategoryUUIDForType(LLFolderType::FT_OUTBOX, false))
+ {
+ dest_folder_id = gInventory.createNewCategory(mUUID, LLFolderType::FT_NONE, viitem->getName());
+ }
+
+ LLInvFVBridge::changeItemParent(
+ model,
+ viitem,
+ dest_folder_id,
+ false);
+ }
+
+}
+
void LLFolderBridge::dropToFavorites(LLInventoryItem* inv_item)
{
// use callback to rearrange favorite landmarks after adding
@@ -3060,11 +3202,13 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item,
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 &outbox_id = model->findCategoryUUIDForType(LLFolderType::FT_OUTBOX, false);
const BOOL move_is_into_current_outfit = (mUUID == current_outfit_id);
const BOOL move_is_into_favorites = (mUUID == favorites_id);
const BOOL move_is_into_outfit = (getCategory() && getCategory()->getPreferredType()==LLFolderType::FT_OUTFIT);
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); //(mUUID == outbox_id);
LLToolDragAndDrop::ESource source = LLToolDragAndDrop::getInstance()->getSource();
BOOL accept = FALSE;
@@ -3130,6 +3274,10 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item,
{
accept = can_move_to_landmarks(inv_item);
}
+ else if (move_is_into_outbox)
+ {
+ accept = can_move_to_outbox(inv_item);
+ }
if(accept && drop)
{
@@ -3180,6 +3328,10 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item,
{
dropToOutfit(inv_item, move_is_into_current_outfit);
}
+ else if (move_is_into_outbox)
+ {
+ dropToOutbox(inv_item);
+ }
// NORMAL or TRASH folder
// (move the item, restamp if into trash)
else
diff --git a/indra/newview/llinventorybridge.h b/indra/newview/llinventorybridge.h
index 15629c0c75..262f4ffdcf 100644
--- a/indra/newview/llinventorybridge.h
+++ b/indra/newview/llinventorybridge.h
@@ -140,6 +140,7 @@ protected:
BOOL isAgentInventory() const; // false if lost or in the inventory library
BOOL isCOFFolder() const; // true if COF or descendent of
BOOL isInboxFolder() const; // true if COF or descendent of marketplace inbox
+ BOOL isOutboxFolder() const; // true if COF or descendent of marketplace inbox
virtual BOOL isItemPermissive() const;
static void changeItemParent(LLInventoryModel* model,
LLViewerInventoryItem* item,
@@ -299,6 +300,9 @@ protected:
void dropToFavorites(LLInventoryItem* inv_item);
void dropToOutfit(LLInventoryItem* inv_item, BOOL move_is_into_current_outfit);
+ void dropToOutbox(LLInventoryItem* inv_item);
+ void moveToOutbox(const LLSD& notification, const LLSD& response);
+ void dropFolderToOutbox(LLInventoryCategory* inv_cat);
//--------------------------------------------------------------------
// Messy hacks for handling folder options
diff --git a/indra/newview/llpanelmarketplaceoutbox.cpp b/indra/newview/llpanelmarketplaceoutbox.cpp
index 74d0de3b30..9e1b28f168 100644
--- a/indra/newview/llpanelmarketplaceoutbox.cpp
+++ b/indra/newview/llpanelmarketplaceoutbox.cpp
@@ -38,7 +38,7 @@
#include "llsidepanelinventory.h"
#include "llsidetray.h"
#include "lltimer.h"
-
+#include "llfolderview.h"
static LLRegisterPanelClassWrapper<LLPanelMarketplaceOutbox> t_panel_marketplace_outbox("panel_marketplace_outbox");
@@ -136,6 +136,27 @@ void LLPanelMarketplaceOutbox::setupInventoryPanel()
outbox_inventory_placeholder->setVisible(FALSE);
}
+BOOL LLPanelMarketplaceOutbox::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
+ EDragAndDropType cargo_type,
+ void* cargo_data,
+ EAcceptance* accept,
+ std::string& tooltip_msg)
+{
+ BOOL handled = LLPanel::handleDragAndDrop(x, y, mask, drop, cargo_type, cargo_data, accept, tooltip_msg);
+
+ if (!handled && mInventoryPanel->getRootFolder())
+ {
+ handled = mInventoryPanel->getRootFolder()->handleDragAndDropFromChild(mask,drop,cargo_type,cargo_data,accept,tooltip_msg);
+ }
+
+ if (handled && mInventoryPanel->getRootFolder())
+ {
+ mInventoryPanel->getRootFolder()->setDragAndDropThisFrame();
+ }
+
+ return handled;
+}
+
bool LLPanelMarketplaceOutbox::isOutboxEmpty() const
{
// TODO: Check for contents of outbox
@@ -170,9 +191,9 @@ void timeDelay(LLCoros::self& self, LLPanelMarketplaceOutbox* outboxPanel)
}
void LLPanelMarketplaceOutbox::onSyncButtonClicked()
-{
+{
// TODO: Actually trigger sync to marketplace
-
+
mSyncInProgress = true;
updateSyncButtonStatus();
diff --git a/indra/newview/llpanelmarketplaceoutbox.h b/indra/newview/llpanelmarketplaceoutbox.h
index 1b502127ef..d5671edad6 100644
--- a/indra/newview/llpanelmarketplaceoutbox.h
+++ b/indra/newview/llpanelmarketplaceoutbox.h
@@ -61,6 +61,12 @@ public:
void onSyncComplete();
+ /*virtual*/ BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
+ EDragAndDropType cargo_type,
+ void* cargo_data,
+ EAcceptance* accept,
+ std::string& tooltip_msg);
+
protected:
void onSyncButtonClicked();
void updateSyncButtonStatus();
diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml
index 1bc377126e..5c600265c2 100644
--- a/indra/newview/skins/default/xui/en/notifications.xml
+++ b/indra/newview/skins/default/xui/en/notifications.xml
@@ -199,7 +199,21 @@ Save changes to current clothing/body part?
yestext="Save"/>
</notification>
- <notification
+ <notification
+ icon="alertmodal.tga"
+ name="ConfirmNoCopyToOutbox"
+ type="alertmodal">
+ You don't have permission to copy this item to the Marketplace Outbox. Are you sure you want to move the following item?
+ [ITEM_NAME]
+ <usetemplate
+ name="okcancelbuttons"
+ notext="No"
+ yestext="Yes"/>
+ </notification>
+
+
+
+ <notification
icon="alertmodal.tga"
name="CompileQueueSaveText"
type="alertmodal">