summaryrefslogtreecommitdiff
path: root/indra/newview/llsidepanelinventory.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview/llsidepanelinventory.cpp')
-rwxr-xr-x[-rw-r--r--]indra/newview/llsidepanelinventory.cpp421
1 files changed, 376 insertions, 45 deletions
diff --git a/indra/newview/llsidepanelinventory.cpp b/indra/newview/llsidepanelinventory.cpp
index 31ea542743..0e23e2ad10 100644..100755
--- a/indra/newview/llsidepanelinventory.cpp
+++ b/indra/newview/llsidepanelinventory.cpp
@@ -29,40 +29,135 @@
#include "llagent.h"
#include "llappearancemgr.h"
+#include "llappviewer.h"
#include "llavataractions.h"
#include "llbutton.h"
+#include "lldate.h"
#include "llfirstuse.h"
+#include "llfloatersidepanelcontainer.h"
+#include "llfoldertype.h"
+#include "llfolderview.h"
+#include "llhttpclient.h"
#include "llinventorybridge.h"
#include "llinventoryfunctions.h"
+#include "llinventorymodel.h"
+#include "llinventorymodelbackgroundfetch.h"
+#include "llinventoryobserver.h"
#include "llinventorypanel.h"
+#include "lllayoutstack.h"
#include "lloutfitobserver.h"
#include "llpanelmaininventory.h"
+#include "llpanelmarketplaceinbox.h"
+#include "llselectmgr.h"
#include "llsidepaneliteminfo.h"
#include "llsidepaneltaskinfo.h"
+#include "llstring.h"
#include "lltabcontainer.h"
-#include "llselectmgr.h"
+#include "lltextbox.h"
+#include "lltrans.h"
+#include "llviewermedia.h"
+#include "llviewernetwork.h"
#include "llweb.h"
-static LLRegisterPanelClassWrapper<LLSidepanelInventory> t_inventory("sidepanel_inventory");
+static LLPanelInjector<LLSidepanelInventory> t_inventory("sidepanel_inventory");
-LLSidepanelInventory::LLSidepanelInventory()
- : LLPanel(),
- mItemPanel(NULL),
- mPanelMainInventory(NULL)
+//
+// Constants
+//
+
+// No longer want the inbox panel to auto-expand since it creates issues with the "new" tag time stamp
+#define AUTO_EXPAND_INBOX 0
+
+static const char * const INBOX_BUTTON_NAME = "inbox_btn";
+static const char * const INBOX_LAYOUT_PANEL_NAME = "inbox_layout_panel";
+static const char * const INVENTORY_LAYOUT_STACK_NAME = "inventory_layout_stack";
+static const char * const MARKETPLACE_INBOX_PANEL = "marketplace_inbox";
+
+//
+// Helpers
+//
+class LLInboxAddedObserver : public LLInventoryCategoryAddedObserver
{
+public:
+ LLInboxAddedObserver(LLSidepanelInventory * sidepanelInventory)
+ : LLInventoryCategoryAddedObserver()
+ , mSidepanelInventory(sidepanelInventory)
+ {
+ }
+
+ void done()
+ {
+ for (cat_vec_t::iterator it = mAddedCategories.begin(); it != mAddedCategories.end(); ++it)
+ {
+ LLViewerInventoryCategory* added_category = *it;
+
+ LLFolderType::EType added_category_type = added_category->getPreferredType();
+
+ switch (added_category_type)
+ {
+ case LLFolderType::FT_INBOX:
+ mSidepanelInventory->enableInbox(true);
+ mSidepanelInventory->observeInboxModifications(added_category->getUUID());
+ break;
+ default:
+ break;
+ }
+ }
+ }
+
+private:
+ LLSidepanelInventory * mSidepanelInventory;
+};
+//
+// Implementation
+//
+
+LLSidepanelInventory::LLSidepanelInventory()
+ : LLPanel()
+ , mItemPanel(NULL)
+ , mPanelMainInventory(NULL)
+ , mInboxEnabled(false)
+ , mCategoriesObserver(NULL)
+ , mInboxAddedObserver(NULL)
+{
//buildFromFile( "panel_inventory.xml"); // Called from LLRegisterPanelClass::defaultPanelClassBuilder()
}
LLSidepanelInventory::~LLSidepanelInventory()
{
+ LLLayoutPanel* inbox_layout_panel = getChild<LLLayoutPanel>(INBOX_LAYOUT_PANEL_NAME);
+
+ // Save the InventoryMainPanelHeight in settings per account
+ gSavedPerAccountSettings.setS32("InventoryInboxHeight", inbox_layout_panel->getTargetDim());
+
+ if (mCategoriesObserver && gInventory.containsObserver(mCategoriesObserver))
+ {
+ gInventory.removeObserver(mCategoriesObserver);
+ }
+ delete mCategoriesObserver;
+
+ if (mInboxAddedObserver && gInventory.containsObserver(mInboxAddedObserver))
+ {
+ gInventory.removeObserver(mInboxAddedObserver);
+ }
+ delete mInboxAddedObserver;
+}
+
+void handleInventoryDisplayInboxChanged()
+{
+ LLSidepanelInventory* sidepanel_inventory = LLFloaterSidePanelContainer::getPanel<LLSidepanelInventory>("inventory");
+ if (sidepanel_inventory)
+ {
+ sidepanel_inventory->enableInbox(gSavedSettings.getBOOL("InventoryDisplayInbox"));
+ }
}
BOOL LLSidepanelInventory::postBuild()
{
// UI elements from inventory panel
{
- mInventoryPanel = getChild<LLPanel>("sidepanel__inventory_panel");
+ mInventoryPanel = getChild<LLPanel>("sidepanel_inventory_panel");
mInfoBtn = mInventoryPanel->getChild<LLButton>("info_btn");
mInfoBtn->setClickedCallback(boost::bind(&LLSidepanelInventory::onInfoButtonClicked, this));
@@ -85,7 +180,7 @@ BOOL LLSidepanelInventory::postBuild()
mOverflowBtn = mInventoryPanel->getChild<LLButton>("overflow_btn");
mOverflowBtn->setClickedCallback(boost::bind(&LLSidepanelInventory::onOverflowButtonClicked, this));
- mPanelMainInventory = mInventoryPanel->findChild<LLPanelMainInventory>("panel_main_inventory");
+ mPanelMainInventory = mInventoryPanel->getChild<LLPanelMainInventory>("panel_main_inventory");
mPanelMainInventory->setSelectCallback(boost::bind(&LLSidepanelInventory::onSelectionChange, this, _1, _2));
LLTabContainer* tabs = mPanelMainInventory->getChild<LLTabContainer>("inventory filter tabs");
tabs->setCommitCallback(boost::bind(&LLSidepanelInventory::updateVerbs, this));
@@ -103,7 +198,7 @@ BOOL LLSidepanelInventory::postBuild()
// UI elements from item panel
{
- mItemPanel = findChild<LLSidepanelItemInfo>("sidepanel__item_panel");
+ mItemPanel = getChild<LLSidepanelItemInfo>("sidepanel__item_panel");
LLButton* back_btn = mItemPanel->getChild<LLButton>("back_btn");
back_btn->setClickedCallback(boost::bind(&LLSidepanelInventory::onBackButtonClicked, this));
@@ -119,12 +214,203 @@ BOOL LLSidepanelInventory::postBuild()
}
}
+ // Received items inbox setup
+ {
+ LLLayoutStack* inv_stack = getChild<LLLayoutStack>(INVENTORY_LAYOUT_STACK_NAME);
+
+ // Set up button states and callbacks
+ LLButton * inbox_button = getChild<LLButton>(INBOX_BUTTON_NAME);
+
+ inbox_button->setCommitCallback(boost::bind(&LLSidepanelInventory::onToggleInboxBtn, this));
+
+ // Get the previous inbox state from "InventoryInboxToggleState" setting.
+ bool is_inbox_collapsed = !inbox_button->getToggleState();
+
+ // Restore the collapsed inbox panel state
+ LLLayoutPanel* inbox_panel = getChild<LLLayoutPanel>(INBOX_LAYOUT_PANEL_NAME);
+ inv_stack->collapsePanel(inbox_panel, is_inbox_collapsed);
+ if (!is_inbox_collapsed)
+ {
+ inbox_panel->setTargetDim(gSavedPerAccountSettings.getS32("InventoryInboxHeight"));
+ }
+
+ // Set the inbox visible based on debug settings (final setting comes from http request below)
+ enableInbox(gSavedSettings.getBOOL("InventoryDisplayInbox"));
+
+ // Trigger callback for after login so we can setup to track inbox changes after initial inventory load
+ LLAppViewer::instance()->setOnLoginCompletedCallback(boost::bind(&LLSidepanelInventory::updateInbox, this));
+ }
+
+ gSavedSettings.getControl("InventoryDisplayInbox")->getCommitSignal()->connect(boost::bind(&handleInventoryDisplayInboxChanged));
+
+ // Update the verbs buttons state.
+ updateVerbs();
+
return TRUE;
}
+void LLSidepanelInventory::updateInbox()
+{
+ //
+ // Track inbox folder changes
+ //
+ const LLUUID inbox_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_INBOX, true);
+
+ // Set up observer to listen for creation of inbox if it doesn't exist
+ if (inbox_id.isNull())
+ {
+ observeInboxCreation();
+ }
+ // Set up observer for inbox changes, if we have an inbox already
+ else
+ {
+ // Consolidate Received items
+ // We shouldn't have to do that but with a client/server system relying on a "well known folder" convention,
+ // things can get messy and conventions broken. This call puts everything back together in its right place.
+ gInventory.consolidateForType(inbox_id, LLFolderType::FT_INBOX);
+
+ // Enable the display of the inbox if it exists
+ enableInbox(true);
+
+ observeInboxModifications(inbox_id);
+ }
+}
+
+void LLSidepanelInventory::observeInboxCreation()
+{
+ //
+ // Set up observer to track inbox folder creation
+ //
+
+ if (mInboxAddedObserver == NULL)
+ {
+ mInboxAddedObserver = new LLInboxAddedObserver(this);
+
+ gInventory.addObserver(mInboxAddedObserver);
+ }
+}
+
+void LLSidepanelInventory::observeInboxModifications(const LLUUID& inboxID)
+{
+ //
+ // Silently do nothing if we already have an inbox inventory panel set up
+ // (this can happen multiple times on the initial session that creates the inbox)
+ //
+
+ if (mInventoryPanelInbox.get() != NULL)
+ {
+ return;
+ }
+
+ //
+ // Track inbox folder changes
+ //
+
+ if (inboxID.isNull())
+ {
+ LL_WARNS() << "Attempting to track modifications to non-existent inbox" << LL_ENDL;
+ return;
+ }
+
+ if (mCategoriesObserver == NULL)
+ {
+ mCategoriesObserver = new LLInventoryCategoriesObserver();
+ gInventory.addObserver(mCategoriesObserver);
+ }
+
+ mCategoriesObserver->addCategory(inboxID, boost::bind(&LLSidepanelInventory::onInboxChanged, this, inboxID));
+
+ //
+ // Trigger a load for the entire contents of the Inbox
+ //
+
+ LLInventoryModelBackgroundFetch::instance().start(inboxID);
+
+ //
+ // Set up the inbox inventory view
+ //
+
+ LLPanelMarketplaceInbox * inbox = getChild<LLPanelMarketplaceInbox>(MARKETPLACE_INBOX_PANEL);
+ LLInventoryPanel* inventory_panel = inbox->setupInventoryPanel();
+ mInventoryPanelInbox = inventory_panel->getInventoryPanelHandle();
+}
+
+void LLSidepanelInventory::enableInbox(bool enabled)
+{
+ mInboxEnabled = enabled;
+
+ LLLayoutPanel * inbox_layout_panel = getChild<LLLayoutPanel>(INBOX_LAYOUT_PANEL_NAME);
+ inbox_layout_panel->setVisible(enabled);
+}
+
+void LLSidepanelInventory::openInbox()
+{
+ if (mInboxEnabled)
+ {
+ getChild<LLButton>(INBOX_BUTTON_NAME)->setToggleState(true);
+ onToggleInboxBtn();
+ }
+}
+
+void LLSidepanelInventory::onInboxChanged(const LLUUID& inbox_id)
+{
+ // Trigger a load of the entire inbox so we always know the contents and their creation dates for sorting
+ LLInventoryModelBackgroundFetch::instance().start(inbox_id);
+
+#if AUTO_EXPAND_INBOX
+ // Expand the inbox since we have fresh items
+ if (mInboxEnabled)
+ {
+ getChild<LLButton>(INBOX_BUTTON_NAME)->setToggleState(true);
+ onToggleInboxBtn();
+ }
+#endif
+}
+
+void LLSidepanelInventory::onToggleInboxBtn()
+{
+ LLButton* inboxButton = getChild<LLButton>(INBOX_BUTTON_NAME);
+ LLLayoutPanel* inboxPanel = getChild<LLLayoutPanel>(INBOX_LAYOUT_PANEL_NAME);
+ LLLayoutStack* inv_stack = getChild<LLLayoutStack>(INVENTORY_LAYOUT_STACK_NAME);
+
+ const bool inbox_expanded = inboxButton->getToggleState();
+
+ // Expand/collapse the indicated panel
+ inv_stack->collapsePanel(inboxPanel, !inbox_expanded);
+
+ if (inbox_expanded)
+ {
+ inboxPanel->setTargetDim(gSavedPerAccountSettings.getS32("InventoryInboxHeight"));
+ if (inboxPanel->isInVisibleChain())
+ {
+ gSavedPerAccountSettings.setU32("LastInventoryInboxActivity", time_corrected());
+ }
+}
+ else
+ {
+ gSavedPerAccountSettings.setS32("InventoryInboxHeight", inboxPanel->getTargetDim());
+ }
+
+}
+
void LLSidepanelInventory::onOpen(const LLSD& key)
{
LLFirstUse::newInventory(false);
+ mPanelMainInventory->setFocusFilterEditor();
+#if AUTO_EXPAND_INBOX
+ // Expand the inbox if we have fresh items
+ LLPanelMarketplaceInbox * inbox = findChild<LLPanelMarketplaceInbox>(MARKETPLACE_INBOX_PANEL);
+ if (inbox && (inbox->getFreshItemCount() > 0))
+ {
+ getChild<LLButton>(INBOX_BUTTON_NAME)->setToggleState(true);
+ onToggleInboxBtn();
+ }
+#else
+ if (mInboxEnabled && getChild<LLButton>(INBOX_BUTTON_NAME)->getToggleState())
+ {
+ gSavedPerAccountSettings.setU32("LastInventoryInboxActivity", time_corrected());
+ }
+#endif
if(key.size() == 0)
return;
@@ -161,7 +447,7 @@ void LLSidepanelInventory::onInfoButtonClicked()
void LLSidepanelInventory::onShareButtonClicked()
{
- LLAvatarActions::shareWithAvatars();
+ LLAvatarActions::shareWithAvatars(this);
}
void LLSidepanelInventory::onShopButtonClicked()
@@ -171,26 +457,27 @@ void LLSidepanelInventory::onShopButtonClicked()
void LLSidepanelInventory::performActionOnSelection(const std::string &action)
{
- LLPanelMainInventory *panel_main_inventory = mInventoryPanel->findChild<LLPanelMainInventory>("panel_main_inventory");
- LLFolderViewItem* current_item = panel_main_inventory->getActivePanel()->getRootFolder()->getCurSelectedItem();
+ LLFolderViewItem* current_item = mPanelMainInventory->getActivePanel()->getRootFolder()->getCurSelectedItem();
if (!current_item)
{
- return;
+ if (mInventoryPanelInbox.get() && mInventoryPanelInbox.get()->getRootFolder())
+ {
+ current_item = mInventoryPanelInbox.get()->getRootFolder()->getCurSelectedItem();
+ }
+
+ if (!current_item)
+ {
+ return;
+ }
}
- current_item->getListener()->performAction(panel_main_inventory->getActivePanel()->getModel(), action);
+
+ static_cast<LLFolderViewModelItemInventory*>(current_item->getViewModelItem())->performAction(mPanelMainInventory->getActivePanel()->getModel(), action);
}
void LLSidepanelInventory::onWearButtonClicked()
{
- LLPanelMainInventory *panel_main_inventory = mInventoryPanel->findChild<LLPanelMainInventory>("panel_main_inventory");
- if (!panel_main_inventory)
- {
- llassert(panel_main_inventory != NULL);
- return;
- }
-
// Get selected items set.
- const std::set<LLUUID> selected_uuids_set = panel_main_inventory->getActivePanel()->getRootFolder()->getSelectionList();
+ const std::set<LLUUID> selected_uuids_set = LLAvatarActions::getInventorySelectedUUIDs();
if (selected_uuids_set.empty()) return; // nothing selected
// Convert the set to a vector.
@@ -326,34 +613,28 @@ void LLSidepanelInventory::updateVerbs()
bool LLSidepanelInventory::canShare()
{
- LLPanelMainInventory* panel_main_inventory =
- mInventoryPanel->findChild<LLPanelMainInventory>("panel_main_inventory");
+ LLInventoryPanel* inbox = mInventoryPanelInbox.get();
- if (!panel_main_inventory)
+ // Avoid flicker in the Recent tab while inventory is being loaded.
+ if ( (!inbox || !inbox->getRootFolder() || inbox->getRootFolder()->getSelectionList().empty())
+ && (mPanelMainInventory && !mPanelMainInventory->getActivePanel()->getRootFolder()->hasVisibleChildren()) )
{
- llwarns << "Failed to get the main inventory panel" << llendl;
return false;
}
- LLInventoryPanel* active_panel = panel_main_inventory->getActivePanel();
- // Avoid flicker in the Recent tab while inventory is being loaded.
- if (!active_panel->getRootFolder()->hasVisibleChildren()) return false;
-
- return LLAvatarActions::canShareSelectedItems(active_panel);
+ return ( (mPanelMainInventory ? LLAvatarActions::canShareSelectedItems(mPanelMainInventory->getActivePanel()) : false)
+ || (inbox ? LLAvatarActions::canShareSelectedItems(inbox) : false) );
}
+
bool LLSidepanelInventory::canWearSelected()
{
- LLPanelMainInventory* panel_main_inventory =
- mInventoryPanel->findChild<LLPanelMainInventory>("panel_main_inventory");
- if (!panel_main_inventory)
- {
- llassert(panel_main_inventory != NULL);
+ std::set<LLUUID> selected_uuids = LLAvatarActions::getInventorySelectedUUIDs();
+
+ if (selected_uuids.empty())
return false;
- }
- std::set<LLUUID> selected_uuids = panel_main_inventory->getActivePanel()->getRootFolder()->getSelectionList();
for (std::set<LLUUID>::const_iterator it = selected_uuids.begin();
it != selected_uuids.end();
++it)
@@ -366,22 +647,40 @@ bool LLSidepanelInventory::canWearSelected()
LLInventoryItem *LLSidepanelInventory::getSelectedItem()
{
- LLPanelMainInventory *panel_main_inventory = mInventoryPanel->findChild<LLPanelMainInventory>("panel_main_inventory");
- LLFolderViewItem* current_item = panel_main_inventory->getActivePanel()->getRootFolder()->getCurSelectedItem();
+ LLFolderViewItem* current_item = mPanelMainInventory->getActivePanel()->getRootFolder()->getCurSelectedItem();
+
if (!current_item)
{
- return NULL;
+ if (mInventoryPanelInbox.get() && mInventoryPanelInbox.get()->getRootFolder())
+ {
+ current_item = mInventoryPanelInbox.get()->getRootFolder()->getCurSelectedItem();
+ }
+
+ if (!current_item)
+ {
+ return NULL;
+ }
}
- const LLUUID &item_id = current_item->getListener()->getUUID();
+ const LLUUID &item_id = static_cast<LLFolderViewModelItemInventory*>(current_item->getViewModelItem())->getUUID();
LLInventoryItem *item = gInventory.getItem(item_id);
return item;
}
U32 LLSidepanelInventory::getSelectedCount()
{
- LLPanelMainInventory *panel_main_inventory = mInventoryPanel->findChild<LLPanelMainInventory>("panel_main_inventory");
- std::set<LLUUID> selection_list = panel_main_inventory->getActivePanel()->getRootFolder()->getSelectionList();
- return selection_list.size();
+ int count = 0;
+
+ std::set<LLFolderViewItem*> selection_list = mPanelMainInventory->getActivePanel()->getRootFolder()->getSelectionList();
+ count += selection_list.size();
+
+ if ((count == 0) && mInboxEnabled && mInventoryPanelInbox.get() && mInventoryPanelInbox.get()->getRootFolder())
+ {
+ selection_list = mInventoryPanelInbox.get()->getRootFolder()->getSelectionList();
+
+ count += selection_list.size();
+ }
+
+ return count;
}
LLInventoryPanel *LLSidepanelInventory::getActivePanel()
@@ -401,3 +700,35 @@ BOOL LLSidepanelInventory::isMainInventoryPanelActive() const
{
return mInventoryPanel->getVisible();
}
+
+void LLSidepanelInventory::clearSelections(bool clearMain, bool clearInbox)
+{
+ if (clearMain)
+ {
+ LLInventoryPanel * inv_panel = getActivePanel();
+
+ if (inv_panel)
+ {
+ inv_panel->getRootFolder()->clearSelection();
+ }
+ }
+
+ if (clearInbox && mInboxEnabled && mInventoryPanelInbox.get())
+ {
+ mInventoryPanelInbox.get()->getRootFolder()->clearSelection();
+ }
+
+ updateVerbs();
+}
+
+std::set<LLFolderViewItem*> LLSidepanelInventory::getInboxSelectionList()
+{
+ std::set<LLFolderViewItem*> inventory_selected_uuids;
+
+ if (mInboxEnabled && mInventoryPanelInbox.get() && mInventoryPanelInbox.get()->getRootFolder())
+ {
+ inventory_selected_uuids = mInventoryPanelInbox.get()->getRootFolder()->getSelectionList();
+ }
+
+ return inventory_selected_uuids;
+}