diff options
Diffstat (limited to 'indra/newview/llsidepanelinventory.cpp')
-rwxr-xr-x[-rw-r--r--] | indra/newview/llsidepanelinventory.cpp | 421 |
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; +} |