/** * @file llinventorypanel.h * @brief LLInventoryPanel * class definition * * $LicenseInfo:firstyear=2001&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$ */ #ifndef LL_LLINVENTORYPANEL_H #define LL_LLINVENTORYPANEL_H #include "llassetstorage.h" #include "llfolderviewitem.h" #include "llfolderviewmodelinventory.h" #include "llfloater.h" #include "llinventory.h" #include "llinventoryfilter.h" #include "llinventorymodel.h" #include "llscrollcontainer.h" #include "lluictrlfactory.h" #include class LLInvFVBridge; class LLInventoryFolderViewModelBuilder; class LLInvPanelComplObserver; class LLFolderViewModelInventory; class LLFolderViewGroupedItemBridge; namespace LLInitParam { template<> struct TypeValues : public TypeValuesHelper { static void declareValues(); }; } class LLInventoryPanel : public LLPanel { //-------------------------------------------------------------------- // Data //-------------------------------------------------------------------- public: struct Filter : public LLInitParam::Block { Optional sort_order; Optional types; Optional search_string; Filter() : sort_order("sort_order"), types("types", 0xffffffff), search_string("search_string") {} }; struct StartFolder : public LLInitParam::ChoiceBlock { Alternative name; Alternative id; Alternative type; StartFolder() : name("name"), id("id"), type("type") {} }; struct Params : public LLInitParam::Block { Optional sort_order_setting; Optional inventory; Optional allow_multi_select; Optional allow_drag; Optional show_item_link_overlays; Optional filter; Optional start_folder; Optional use_label_suffix; Optional show_empty_message; Optional suppress_folder_menu; Optional show_root_folder; Optional allow_drop_on_root; Optional use_marketplace_folders; Optional scroll; Optional accepts_drag_and_drop; Optional folder_view; Optional folder; Optional item; Optional open_first_folder; // All item and folder views will be initialized on init if true (default) // Will initialize on visibility change otherwise. Optional preinitialize_views; Params() : sort_order_setting("sort_order_setting"), inventory("", &gInventory), allow_multi_select("allow_multi_select", true), allow_drag("allow_drag", true), show_item_link_overlays("show_item_link_overlays", false), suppress_folder_menu("suppress_folder_menu", false), filter("filter"), start_folder("start_folder"), use_label_suffix("use_label_suffix", true), show_empty_message("show_empty_message", true), show_root_folder("show_root_folder", false), allow_drop_on_root("allow_drop_on_root", true), use_marketplace_folders("use_marketplace_folders", false), open_first_folder("open_first_folder", true), scroll("scroll"), accepts_drag_and_drop("accepts_drag_and_drop"), folder_view("folder_view"), folder("folder"), item("item"), preinitialize_views("preinitialize_views", true) {} }; struct InventoryState : public LLInitParam::Block { Mandatory filter; Mandatory sort; }; //-------------------------------------------------------------------- // Initialization //-------------------------------------------------------------------- protected: LLInventoryPanel(const Params&); void initFromParams(const Params&); friend class LLUICtrlFactory; public: virtual ~LLInventoryPanel(); public: typedef std::set selected_items_t; LLInventoryModel* getModel() { return mInventory; } LLFolderViewModelInventory& getRootViewModel() { return mInventoryViewModel; } // LLView methods /*virtual*/ void onVisibilityChange(bool new_visibility) override; void draw() override; /*virtual*/ bool handleKeyHere( KEY key, MASK mask ) override; bool handleHover(S32 x, S32 y, MASK mask) override; /*virtual*/ bool handleDragAndDrop(S32 x, S32 y, MASK mask, bool drop, EDragAndDropType cargo_type, void* cargo_data, EAcceptance* accept, std::string& tooltip_msg) override; bool handleToolTip(S32 x, S32 y, MASK mask) override; // LLUICtrl methods /*virtual*/ void onFocusLost() override; /*virtual*/ void onFocusReceived() override; void onFolderOpening(const LLUUID &id); // LLBadgeHolder methods bool addBadge(LLBadge * badge) override; // Call this method to set the selection. void openAllFolders(); void setSelection(const LLUUID& obj_id, bool take_keyboard_focus); void setSelectCallback(const boost::function& items, bool user_action)>& cb); void clearSelection(); selected_items_t getSelectedItems() const; bool isSelectionRemovable(); LLInventoryFilter& getFilter(); const LLInventoryFilter& getFilter() const; void setFilterTypes(U64 filter, LLInventoryFilter::EFilterType = LLInventoryFilter::FILTERTYPE_OBJECT); void setFilterWorn(); U32 getFilterObjectTypes() const; void setFilterPermMask(PermissionMask filter_perm_mask); U32 getFilterPermMask() const; void setFilterWearableTypes(U64 filter); void setFilterSettingsTypes(U64 filter); void setFilterSubString(const std::string& string); const std::string getFilterSubString(); void setSinceLogoff(bool sl); void setHoursAgo(U32 hours); void setDateSearchDirection(U32 direction); bool getSinceLogoff(); void setFilterLinks(U64 filter_links); void setSearchType(LLInventoryFilter::ESearchType type); LLInventoryFilter::ESearchType getSearchType(); void setShowFolderState(LLInventoryFilter::EFolderShow show); LLInventoryFilter::EFolderShow getShowFolderState(); // This method is called when something has changed about the inventory. void modelChanged(U32 mask); LLFolderView* getRootFolder() { return mFolderRoot.get(); } LLUUID getRootFolderID(); LLScrollContainer* getScrollableContainer() { return mScroller; } bool getAllowDropOnRoot() { return mParams.allow_drop_on_root; } bool areViewsInitialized() { return mViewsInitialized == VIEWS_INITIALIZED && mFolderRoot.get() && !mFolderRoot.get()->needsArrange(); } void onSelectionChange(const std::deque &items, bool user_action); LLHandle getInventoryPanelHandle() const { return getDerivedHandle(); } // Callbacks void doToSelected(const LLSD& userdata); void doCreate(const LLSD& userdata); bool beginIMSession(); void fileUploadLocation(const LLSD& userdata); void openSingleViewInventory(LLUUID folder_id = LLUUID()); void purgeSelectedItems(); bool attachObject(const LLSD& userdata); static void idle(void* user_data); void updateFolderLabel(const LLUUID& folder_id); // DEBUG ONLY: static void dumpSelectionInformation(void* user_data); void openSelected(); void unSelectAll(); static void onIdle(void* user_data); // Find whichever inventory panel is active / on top. // "Auto_open" determines if we open an inventory panel if none are open. static LLInventoryPanel *getActiveInventoryPanel(bool auto_open = true); static void openInventoryPanelAndSetSelection(bool auto_open, const LLUUID& obj_id, bool use_main_panel = false, bool take_keyboard_focus = true, bool reset_filter = false); static void setSFViewAndOpenFolder(const LLInventoryPanel* panel, const LLUUID& folder_id); void addItemID(const LLUUID& id, LLFolderViewItem* itemp); void removeItemID(const LLUUID& id); LLFolderViewItem* getItemByID(const LLUUID& id); LLFolderViewFolder* getFolderByID(const LLUUID& id); void setSelectionByID(const LLUUID& obj_id, bool take_keyboard_focus); void updateSelection(); void setSuppressOpenItemAction(bool supress_open_item) { mSuppressOpenItemAction = supress_open_item; } LLFolderViewModelInventory* getFolderViewModel() { return &mInventoryViewModel; } const LLFolderViewModelInventory* getFolderViewModel() const { return &mInventoryViewModel; } // Clean up stuff when the folder root gets deleted void clearFolderRoot(); static void callbackPurgeSelectedItems(const LLSD& notification, const LLSD& response, const std::vector inventory_selected); void changeFolderRoot(const LLUUID& new_id) {}; void initFolderRoot(); void initializeViewBuilding(); protected: void openStartFolderOrMyInventory(); // open the first level of inventory void onItemsCompletion(); // called when selected items are complete LLUUID mSelectThisID; LLInventoryModel* mInventory; LLInventoryObserver* mInventoryObserver; LLInvPanelComplObserver* mCompletionObserver; bool mFocusSelection; bool mAcceptsDragAndDrop; bool mAllowMultiSelect; bool mAllowDrag; bool mShowItemLinkOverlays; // Shows link graphic over inventory item icons bool mShowEmptyMessage; bool mSuppressFolderMenu; bool mSuppressOpenItemAction; LLHandle mFolderRoot; LLScrollContainer* mScroller; LLUUID mPreviousSelectedFolder; LLFolderViewModelInventory mInventoryViewModel; LLPointer mGroupedItemBridge; Params mParams; // stored copy of parameter block std::map mItemMap; /** * Pointer to LLInventoryFolderViewModelBuilder. * * It is set in LLInventoryPanel's constructor and can be overridden in derived classes with * another implementation. * Take into account it will not be deleted by LLInventoryPanel itself. */ const LLInventoryFolderViewModelBuilder* mInvFVBridgeBuilder; bool mBuildChildrenViews; // build root and children bool mRootInited; //-------------------------------------------------------------------- // Sorting //-------------------------------------------------------------------- public: static const std::string DEFAULT_SORT_ORDER; static const std::string RECENTITEMS_SORT_ORDER; static const std::string INHERIT_SORT_ORDER; void setSortOrder(U32 order); U32 getSortOrder() const; private: std::string mSortOrderSetting; int mClipboardState; //-------------------------------------------------------------------- // Hidden folders //-------------------------------------------------------------------- public: void addHideFolderType(LLFolderType::EType folder_type); protected: // Builds the UI. Call this once the inventory is usable. void initializeViews(F64 max_time); // Specific inventory colors static bool sColorSetInitialized; static LLUIColor sDefaultColor; static LLUIColor sDefaultHighlightColor; static LLUIColor sLibraryColor; static LLUIColor sLinkColor; enum EBuildModes { BUILD_NO_LIMIT, BUILD_TIMELIMIT, // requires mBuildViewsEndTime BUILD_ONE_FOLDER, BUILD_NO_CHILDREN, }; // All buildNewViews() use BUILD_TIMELIMIT by default // and expect time limit mBuildViewsEndTime to be set LLFolderViewItem* buildNewViews(const LLUUID& id); LLFolderViewItem* buildNewViews(const LLUUID& id, LLInventoryObject const* objectp); LLFolderViewItem* buildNewViews(const LLUUID& id, LLInventoryObject const* objectp, LLFolderViewItem *target_view, const EBuildModes &mode = BUILD_TIMELIMIT); // if certain types are not allowed, no reason to create views virtual bool typedViewsFilter(const LLUUID& id, LLInventoryObject const* objectp) { return true; } virtual void itemChanged(const LLUUID& item_id, U32 mask, const LLInventoryObject* model_item); bool getIsHiddenFolderType(LLFolderType::EType folder_type) const; virtual LLFolderView * createFolderRoot(LLUUID root_id ); virtual LLFolderViewFolder* createFolderViewFolder(LLInvFVBridge * bridge, bool allow_drop); virtual LLFolderViewItem* createFolderViewItem(LLInvFVBridge * bridge); boost::function& items, bool user_action)> mSelectionCallback; private: // buildViewsTree does not include some checks and is meant // for recursive use, use buildNewViews() for first call LLFolderViewItem* buildViewsTree(const LLUUID& id, const LLUUID& parent_id, LLInventoryObject const* objectp, LLFolderViewItem *target_view, LLFolderViewFolder *parent_folder_view, const EBuildModes &mode, S32 depth = -1); typedef enum e_views_initialization_state { VIEWS_UNINITIALIZED = 0, VIEWS_INITIALIZING, VIEWS_BUILDING, // Root folder exists VIEWS_INITIALIZED, } EViewsInitializationState; bool mBuildViewsOnInit; EViewsInitializationState mViewsInitialized; // Whether views have been generated F64 mBuildViewsEndTime; // Stop building views past this timestamp std::deque mBuildViewsQueue; }; class LLInventorySingleFolderPanel : public LLInventoryPanel { public: struct Params : public LLInitParam::Block {}; void initFromParams(const Params& p); void onFocusReceived() override; bool isSelectionRemovable() { return false; } void initFolderRoot(const LLUUID& start_folder_id = LLUUID::null); void changeFolderRoot(const LLUUID& new_id); void onForwardFolder(); void onBackwardFolder(); void clearNavigationHistory(); LLUUID getSingleFolderRoot() { return mFolderID; } void doCreate(const LLSD& userdata); void doToSelected(const LLSD& userdata); void doShare(); bool isBackwardAvailable() const; bool isForwardAvailable() const; bool hasVisibleItems() const; void setNavBackwardList(std::list backward_list) { mBackwardFolders = backward_list; } void setNavForwardList(std::list forward_list) { mForwardFolders = forward_list; } std::list getNavBackwardList() { return mBackwardFolders; } std::list getNavForwardList() { return mForwardFolders; } typedef boost::function root_changed_callback_t; boost::signals2::connection setRootChangedCallback(root_changed_callback_t cb); protected: LLInventorySingleFolderPanel(const Params& params); ~LLInventorySingleFolderPanel(); void updateSingleFolderRoot(); friend class LLUICtrlFactory; LLUUID mFolderID; std::list mBackwardFolders; std::list mForwardFolders; boost::signals2::signal mRootChangedSignal; }; /************************************************************************/ /* Asset Pre-Filtered Inventory Panel related class */ /* Exchanges filter's flexibility for speed of generation and */ /* improved performance */ /************************************************************************/ class LLAssetFilteredInventoryPanel : public LLInventoryPanel { public: struct Params : public LLInitParam::Block { Mandatory filter_asset_types; Params() : filter_asset_types("filter_asset_types") {} }; void initFromParams(const Params& p); protected: LLAssetFilteredInventoryPanel(const Params& p); friend class LLUICtrlFactory; public: ~LLAssetFilteredInventoryPanel() {} /*virtual*/ bool handleDragAndDrop(S32 x, S32 y, MASK mask, bool drop, EDragAndDropType cargo_type, void* cargo_data, EAcceptance* accept, std::string& tooltip_msg) override; protected: /*virtual*/ bool typedViewsFilter(const LLUUID& id, LLInventoryObject const* objectp) override; /*virtual*/ void itemChanged(const LLUUID& item_id, U32 mask, const LLInventoryObject* model_item) override; private: bool mAssetTypes[LLAssetType::AT_COUNT]; bool mDragTypes[EDragAndDropType::DAD_COUNT]; }; #endif // LL_LLINVENTORYPANEL_H