diff options
| author | Ansariel <ansariel.hiller@phoenixviewer.com> | 2024-05-22 21:25:21 +0200 |
|---|---|---|
| committer | Andrey Lihatskiy <alihatskiy@productengine.com> | 2024-05-22 22:40:26 +0300 |
| commit | e2e37cced861b98de8c1a7c9c0d3a50d2d90e433 (patch) | |
| tree | 1bb897489ce524986f6196201c10ac0d8861aa5f /indra/newview/llsidepanelinventory.cpp | |
| parent | 069ea06848f766466f1a281144c82a0f2bd79f3a (diff) | |
Fix line endlings
Diffstat (limited to 'indra/newview/llsidepanelinventory.cpp')
| -rw-r--r-- | indra/newview/llsidepanelinventory.cpp | 1190 |
1 files changed, 595 insertions, 595 deletions
diff --git a/indra/newview/llsidepanelinventory.cpp b/indra/newview/llsidepanelinventory.cpp index 021cdd7945..c07d4b7e56 100644 --- a/indra/newview/llsidepanelinventory.cpp +++ b/indra/newview/llsidepanelinventory.cpp @@ -1,595 +1,595 @@ -/**
- * @file LLSidepanelInventory.cpp
- * @brief Side Bar "Inventory" panel
- *
- * $LicenseInfo:firstyear=2009&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-#include "llviewerprecompiledheaders.h"
-#include "llsidepanelinventory.h"
-
-#include "llagent.h"
-#include "llappearancemgr.h"
-#include "llappviewer.h"
-#include "llavataractions.h"
-#include "llbutton.h"
-#include "lldate.h"
-#include "llfirstuse.h"
-#include "llfloaterreg.h"
-#include "llfloatersidepanelcontainer.h"
-#include "llfoldertype.h"
-#include "llfolderview.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 "lltextbox.h"
-#include "lltrans.h"
-#include "llviewermedia.h"
-#include "llviewernetwork.h"
-#include "llweb.h"
-
-static LLPanelInjector<LLSidepanelInventory> t_inventory("sidepanel_inventory");
-
-//
-// 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";
-
-static bool sLoginCompleted = false;
-
-//
-// 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()
- , mPanelMainInventory(NULL)
- , mInboxEnabled(false)
- , mCategoriesObserver(NULL)
- , mInboxAddedObserver(NULL)
- , mInboxLayoutPanel(NULL)
-{
- //buildFromFile( "panel_inventory.xml"); // Called from LLRegisterPanelClass::defaultPanelClassBuilder()
-}
-
-LLSidepanelInventory::~LLSidepanelInventory()
-{
- // Save the InventoryMainPanelHeight in settings per account
- gSavedPerAccountSettings.setS32("InventoryInboxHeight", mInboxLayoutPanel->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");
-
- 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));
-
- /*
- EXT-4846 : "Can we suppress the "Landmarks" and "My Favorites" folder since they have their own Task Panel?"
- Deferring this until 2.1.
- LLInventoryPanel *my_inventory_panel = mPanelMainInventory->getChild<LLInventoryPanel>("All Items");
- my_inventory_panel->addHideFolderType(LLFolderType::FT_LANDMARK);
- my_inventory_panel->addHideFolderType(LLFolderType::FT_FAVORITE);
- */
-
- //LLOutfitObserver::instance().addCOFChangedCallback(boost::bind(&LLSidepanelInventory::updateVerbs, this));
- }
-
- // 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));
-
- // For main Inventory floater: Get the previous inbox state from "InventoryInboxToggleState" setting.
- // For additional Inventory floaters: Collapsed state is default.
- bool is_inbox_collapsed = !inbox_button->getToggleState() || sLoginCompleted;
-
- // Restore the collapsed inbox panel state
- mInboxLayoutPanel = getChild<LLLayoutPanel>(INBOX_LAYOUT_PANEL_NAME);
- inv_stack->collapsePanel(mInboxLayoutPanel, is_inbox_collapsed);
- if (!is_inbox_collapsed)
- {
- mInboxLayoutPanel->setTargetDim(gSavedPerAccountSettings.getS32("InventoryInboxHeight"));
- }
-
- if (sLoginCompleted)
- {
- //save the state of Inbox panel only for main Inventory floater
- inbox_button->removeControlVariable();
- inbox_button->setToggleState(false);
- updateInbox();
- }
- else
- {
- // 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));
-
- LLFloater *floater = dynamic_cast<LLFloater*>(getParent());
- if (floater && floater->getKey().isUndefined() && !sLoginCompleted)
- {
- // Prefill inventory for primary inventory floater
- // Other floaters should fill on visibility change
- //
- // see get_instance_num();
- // Primary inventory floater will have undefined key
- initInventoryViews();
- }
-
- return true;
-}
-
-void LLSidepanelInventory::updateInbox()
-{
- sLoginCompleted = true;
- //
- // Track inbox folder changes
- //
- const LLUUID inbox_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_INBOX);
-
- // 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;
-
- if(!enabled || !mPanelMainInventory->isSingleFolderMode())
- {
- toggleInbox();
- }
-}
-
-void LLSidepanelInventory::hideInbox()
-{
- mInboxLayoutPanel->setVisible(false);
-}
-
-void LLSidepanelInventory::toggleInbox()
-{
- mInboxLayoutPanel->setVisible(mInboxEnabled);
-}
-
-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);
- LLLayoutStack* inv_stack = getChild<LLLayoutStack>(INVENTORY_LAYOUT_STACK_NAME);
-
- const bool inbox_expanded = inboxButton->getToggleState();
-
- // Expand/collapse the indicated panel
- inv_stack->collapsePanel(mInboxLayoutPanel, !inbox_expanded);
-
- if (inbox_expanded)
- {
- mInboxLayoutPanel->setTargetDim(gSavedPerAccountSettings.getS32("InventoryInboxHeight"));
- if (mInboxLayoutPanel->isInVisibleChain())
- {
- gSavedPerAccountSettings.setU32("LastInventoryInboxActivity", time_corrected());
- }
-}
- else
- {
- gSavedPerAccountSettings.setS32("InventoryInboxHeight", mInboxLayoutPanel->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
-
- gAgent.showLatestFeatureNotification("inventory");
-}
-
-void LLSidepanelInventory::performActionOnSelection(const std::string &action)
-{
- LLFolderViewItem* current_item = mPanelMainInventory->getActivePanel()->getRootFolder()->getCurSelectedItem();
- if (!current_item)
- {
- if (mInventoryPanelInbox.get() && mInventoryPanelInbox.get()->getRootFolder())
- {
- current_item = mInventoryPanelInbox.get()->getRootFolder()->getCurSelectedItem();
- }
-
- if (!current_item)
- {
- return;
- }
- }
-
- static_cast<LLFolderViewModelItemInventory*>(current_item->getViewModelItem())->performAction(mPanelMainInventory->getActivePanel()->getModel(), action);
-}
-
-void LLSidepanelInventory::onBackButtonClicked()
-{
- showInventoryPanel();
-}
-
-void LLSidepanelInventory::onSelectionChange(const std::deque<LLFolderViewItem*> &items, bool user_action)
-{
-
-}
-
-void LLSidepanelInventory::showInventoryPanel()
-{
- mInventoryPanel->setVisible(true);
-}
-
-void LLSidepanelInventory::initInventoryViews()
-{
- mPanelMainInventory->initInventoryViews();
-}
-
-bool LLSidepanelInventory::canShare()
-{
- LLInventoryPanel* inbox = mInventoryPanelInbox.get();
-
- // Avoid flicker in the Recent tab while inventory is being loaded.
- if ( (!inbox || !inbox->getRootFolder() || inbox->getRootFolder()->getSelectionList().empty())
- && (mPanelMainInventory && !mPanelMainInventory->getActivePanel()->getRootFolder()->hasVisibleChildren()) )
- {
- return false;
- }
-
- return ( (mPanelMainInventory ? LLAvatarActions::canShareSelectedItems(mPanelMainInventory->getActivePanel()) : false)
- || (inbox ? LLAvatarActions::canShareSelectedItems(inbox) : false) );
-}
-
-
-bool LLSidepanelInventory::canWearSelected()
-{
-
- std::set<LLUUID> selected_uuids = LLAvatarActions::getInventorySelectedUUIDs();
-
- if (selected_uuids.empty())
- return false;
-
- for (std::set<LLUUID>::const_iterator it = selected_uuids.begin();
- it != selected_uuids.end();
- ++it)
- {
- if (!get_can_item_be_worn(*it)) return false;
- }
-
- return true;
-}
-
-LLInventoryItem *LLSidepanelInventory::getSelectedItem()
-{
- LLFolderView* root = mPanelMainInventory->getActivePanel()->getRootFolder();
- if (!root)
- {
- return NULL;
- }
- LLFolderViewItem* current_item = root->getCurSelectedItem();
-
- if (!current_item)
- {
- if (mInventoryPanelInbox.get() && mInventoryPanelInbox.get()->getRootFolder())
- {
- current_item = mInventoryPanelInbox.get()->getRootFolder()->getCurSelectedItem();
- }
-
- if (!current_item)
- {
- return NULL;
- }
- }
- const LLUUID &item_id = static_cast<LLFolderViewModelItemInventory*>(current_item->getViewModelItem())->getUUID();
- LLInventoryItem *item = gInventory.getItem(item_id);
- return item;
-}
-
-U32 LLSidepanelInventory::getSelectedCount()
-{
- 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()
-{
- if (!getVisible())
- {
- return NULL;
- }
- if (mInventoryPanel->getVisible())
- {
- return mPanelMainInventory->getActivePanel();
- }
- return NULL;
-}
-
-void LLSidepanelInventory::selectAllItemsPanel()
-{
- if (!getVisible())
- {
- return;
- }
- if (mInventoryPanel->getVisible())
- {
- mPanelMainInventory->selectAllItemsPanel();
- }
-
-}
-
-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.isDead())
- {
- mInventoryPanelInbox.get()->getRootFolder()->clearSelection();
- }
-}
-
-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;
-}
-
-void LLSidepanelInventory::cleanup()
-{
- LLFloaterReg::const_instance_list_t& inst_list = LLFloaterReg::getFloaterList("inventory");
- for (LLFloaterReg::const_instance_list_t::const_iterator iter = inst_list.begin(); iter != inst_list.end();)
- {
- LLFloaterSidePanelContainer* iv = dynamic_cast<LLFloaterSidePanelContainer*>(*iter++);
- if (iv)
- {
- iv->cleanup();
- }
- }
-}
+/** + * @file LLSidepanelInventory.cpp + * @brief Side Bar "Inventory" panel + * + * $LicenseInfo:firstyear=2009&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" +#include "llsidepanelinventory.h" + +#include "llagent.h" +#include "llappearancemgr.h" +#include "llappviewer.h" +#include "llavataractions.h" +#include "llbutton.h" +#include "lldate.h" +#include "llfirstuse.h" +#include "llfloaterreg.h" +#include "llfloatersidepanelcontainer.h" +#include "llfoldertype.h" +#include "llfolderview.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 "lltextbox.h" +#include "lltrans.h" +#include "llviewermedia.h" +#include "llviewernetwork.h" +#include "llweb.h" + +static LLPanelInjector<LLSidepanelInventory> t_inventory("sidepanel_inventory"); + +// +// 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"; + +static bool sLoginCompleted = false; + +// +// 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() + , mPanelMainInventory(NULL) + , mInboxEnabled(false) + , mCategoriesObserver(NULL) + , mInboxAddedObserver(NULL) + , mInboxLayoutPanel(NULL) +{ + //buildFromFile( "panel_inventory.xml"); // Called from LLRegisterPanelClass::defaultPanelClassBuilder() +} + +LLSidepanelInventory::~LLSidepanelInventory() +{ + // Save the InventoryMainPanelHeight in settings per account + gSavedPerAccountSettings.setS32("InventoryInboxHeight", mInboxLayoutPanel->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"); + + 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)); + + /* + EXT-4846 : "Can we suppress the "Landmarks" and "My Favorites" folder since they have their own Task Panel?" + Deferring this until 2.1. + LLInventoryPanel *my_inventory_panel = mPanelMainInventory->getChild<LLInventoryPanel>("All Items"); + my_inventory_panel->addHideFolderType(LLFolderType::FT_LANDMARK); + my_inventory_panel->addHideFolderType(LLFolderType::FT_FAVORITE); + */ + + //LLOutfitObserver::instance().addCOFChangedCallback(boost::bind(&LLSidepanelInventory::updateVerbs, this)); + } + + // 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)); + + // For main Inventory floater: Get the previous inbox state from "InventoryInboxToggleState" setting. + // For additional Inventory floaters: Collapsed state is default. + bool is_inbox_collapsed = !inbox_button->getToggleState() || sLoginCompleted; + + // Restore the collapsed inbox panel state + mInboxLayoutPanel = getChild<LLLayoutPanel>(INBOX_LAYOUT_PANEL_NAME); + inv_stack->collapsePanel(mInboxLayoutPanel, is_inbox_collapsed); + if (!is_inbox_collapsed) + { + mInboxLayoutPanel->setTargetDim(gSavedPerAccountSettings.getS32("InventoryInboxHeight")); + } + + if (sLoginCompleted) + { + //save the state of Inbox panel only for main Inventory floater + inbox_button->removeControlVariable(); + inbox_button->setToggleState(false); + updateInbox(); + } + else + { + // 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)); + + LLFloater *floater = dynamic_cast<LLFloater*>(getParent()); + if (floater && floater->getKey().isUndefined() && !sLoginCompleted) + { + // Prefill inventory for primary inventory floater + // Other floaters should fill on visibility change + // + // see get_instance_num(); + // Primary inventory floater will have undefined key + initInventoryViews(); + } + + return true; +} + +void LLSidepanelInventory::updateInbox() +{ + sLoginCompleted = true; + // + // Track inbox folder changes + // + const LLUUID inbox_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_INBOX); + + // 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; + + if(!enabled || !mPanelMainInventory->isSingleFolderMode()) + { + toggleInbox(); + } +} + +void LLSidepanelInventory::hideInbox() +{ + mInboxLayoutPanel->setVisible(false); +} + +void LLSidepanelInventory::toggleInbox() +{ + mInboxLayoutPanel->setVisible(mInboxEnabled); +} + +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); + LLLayoutStack* inv_stack = getChild<LLLayoutStack>(INVENTORY_LAYOUT_STACK_NAME); + + const bool inbox_expanded = inboxButton->getToggleState(); + + // Expand/collapse the indicated panel + inv_stack->collapsePanel(mInboxLayoutPanel, !inbox_expanded); + + if (inbox_expanded) + { + mInboxLayoutPanel->setTargetDim(gSavedPerAccountSettings.getS32("InventoryInboxHeight")); + if (mInboxLayoutPanel->isInVisibleChain()) + { + gSavedPerAccountSettings.setU32("LastInventoryInboxActivity", time_corrected()); + } +} + else + { + gSavedPerAccountSettings.setS32("InventoryInboxHeight", mInboxLayoutPanel->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 + + gAgent.showLatestFeatureNotification("inventory"); +} + +void LLSidepanelInventory::performActionOnSelection(const std::string &action) +{ + LLFolderViewItem* current_item = mPanelMainInventory->getActivePanel()->getRootFolder()->getCurSelectedItem(); + if (!current_item) + { + if (mInventoryPanelInbox.get() && mInventoryPanelInbox.get()->getRootFolder()) + { + current_item = mInventoryPanelInbox.get()->getRootFolder()->getCurSelectedItem(); + } + + if (!current_item) + { + return; + } + } + + static_cast<LLFolderViewModelItemInventory*>(current_item->getViewModelItem())->performAction(mPanelMainInventory->getActivePanel()->getModel(), action); +} + +void LLSidepanelInventory::onBackButtonClicked() +{ + showInventoryPanel(); +} + +void LLSidepanelInventory::onSelectionChange(const std::deque<LLFolderViewItem*> &items, bool user_action) +{ + +} + +void LLSidepanelInventory::showInventoryPanel() +{ + mInventoryPanel->setVisible(true); +} + +void LLSidepanelInventory::initInventoryViews() +{ + mPanelMainInventory->initInventoryViews(); +} + +bool LLSidepanelInventory::canShare() +{ + LLInventoryPanel* inbox = mInventoryPanelInbox.get(); + + // Avoid flicker in the Recent tab while inventory is being loaded. + if ( (!inbox || !inbox->getRootFolder() || inbox->getRootFolder()->getSelectionList().empty()) + && (mPanelMainInventory && !mPanelMainInventory->getActivePanel()->getRootFolder()->hasVisibleChildren()) ) + { + return false; + } + + return ( (mPanelMainInventory ? LLAvatarActions::canShareSelectedItems(mPanelMainInventory->getActivePanel()) : false) + || (inbox ? LLAvatarActions::canShareSelectedItems(inbox) : false) ); +} + + +bool LLSidepanelInventory::canWearSelected() +{ + + std::set<LLUUID> selected_uuids = LLAvatarActions::getInventorySelectedUUIDs(); + + if (selected_uuids.empty()) + return false; + + for (std::set<LLUUID>::const_iterator it = selected_uuids.begin(); + it != selected_uuids.end(); + ++it) + { + if (!get_can_item_be_worn(*it)) return false; + } + + return true; +} + +LLInventoryItem *LLSidepanelInventory::getSelectedItem() +{ + LLFolderView* root = mPanelMainInventory->getActivePanel()->getRootFolder(); + if (!root) + { + return NULL; + } + LLFolderViewItem* current_item = root->getCurSelectedItem(); + + if (!current_item) + { + if (mInventoryPanelInbox.get() && mInventoryPanelInbox.get()->getRootFolder()) + { + current_item = mInventoryPanelInbox.get()->getRootFolder()->getCurSelectedItem(); + } + + if (!current_item) + { + return NULL; + } + } + const LLUUID &item_id = static_cast<LLFolderViewModelItemInventory*>(current_item->getViewModelItem())->getUUID(); + LLInventoryItem *item = gInventory.getItem(item_id); + return item; +} + +U32 LLSidepanelInventory::getSelectedCount() +{ + 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() +{ + if (!getVisible()) + { + return NULL; + } + if (mInventoryPanel->getVisible()) + { + return mPanelMainInventory->getActivePanel(); + } + return NULL; +} + +void LLSidepanelInventory::selectAllItemsPanel() +{ + if (!getVisible()) + { + return; + } + if (mInventoryPanel->getVisible()) + { + mPanelMainInventory->selectAllItemsPanel(); + } + +} + +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.isDead()) + { + mInventoryPanelInbox.get()->getRootFolder()->clearSelection(); + } +} + +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; +} + +void LLSidepanelInventory::cleanup() +{ + LLFloaterReg::const_instance_list_t& inst_list = LLFloaterReg::getFloaterList("inventory"); + for (LLFloaterReg::const_instance_list_t::const_iterator iter = inst_list.begin(); iter != inst_list.end();) + { + LLFloaterSidePanelContainer* iv = dynamic_cast<LLFloaterSidePanelContainer*>(*iter++); + if (iv) + { + iv->cleanup(); + } + } +} |
