/** * @file llfolderview.h * @brief Definition of the folder view collection of classes. * * $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$ */ /** * * The folder view collection of classes provides an interface for * making a 'folder view' similar to the way the a single pane file * folder interface works. * */ #ifndef LL_LLFOLDERVIEW_H #define LL_LLFOLDERVIEW_H #include "llfolderviewitem.h" // because LLFolderView is-a LLFolderViewFolder #include "lluictrl.h" #include "v4color.h" #include "lldepthstack.h" #include "lleditmenuhandler.h" #include "llfontgl.h" #include "llscrollcontainer.h" class LLFolderViewModelInterface; class LLFolderViewGroupedItemModel; class LLFolderViewFolder; class LLFolderViewItem; class LLFolderViewFilter; class LLPanel; class LLLineEditor; class LLMenuGL; class LLUICtrl; class LLTextBox; /** * Class LLFolderViewScrollContainer * * A scroll container which provides the information about the height * of currently displayed folder view contents. * Used for updating vertical scroll bar visibility in inventory panel. * See LLScrollContainer::calcVisibleSize(). */ class LLFolderViewScrollContainer : public LLScrollContainer { public: /*virtual*/ ~LLFolderViewScrollContainer() {}; /*virtual*/ const LLRect getScrolledViewRect() const; protected: LLFolderViewScrollContainer(const LLScrollContainer::Params& p); friend class LLUICtrlFactory; }; //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Class LLFolderView // // The LLFolderView represents the root level folder view object. // It manages the screen region of the folder view. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ class LLFolderView : public LLFolderViewFolder, public LLEditMenuHandler { public: struct Params : public LLInitParam::Block<Params, LLFolderViewFolder::Params> { Mandatory<LLPanel*> parent_panel; Optional<std::string> title; Optional<bool> use_label_suffix, allow_multiselect, allow_drag, show_empty_message, use_ellipses, show_item_link_overlays, suppress_folder_menu; Mandatory<LLFolderViewModelInterface*> view_model; Optional<LLFolderViewGroupedItemModel*> grouped_item_model; Mandatory<std::string> options_menu; Params(); }; friend class LLFolderViewScrollContainer; typedef folder_view_item_deque selected_items_t; LLFolderView(const Params&); virtual ~LLFolderView( void ); virtual bool canFocusChildren() const; virtual const LLFolderView* getRoot() const { return this; } virtual LLFolderView* getRoot() { return this; } LLFolderViewModelInterface* getFolderViewModel() { return mViewModel; } const LLFolderViewModelInterface* getFolderViewModel() const { return mViewModel; } LLFolderViewGroupedItemModel* getFolderViewGroupedItemModel() { return mGroupedItemModel; } const LLFolderViewGroupedItemModel* getFolderViewGroupedItemModel() const { return mGroupedItemModel; } typedef boost::signals2::signal<void (const std::deque<LLFolderViewItem*>& items, bool user_action)> signal_t; void setSelectCallback(const signal_t::slot_type& cb) { mSelectSignal.connect(cb); } void setReshapeCallback(const signal_t::slot_type& cb) { mReshapeSignal.connect(cb); } bool getAllowMultiSelect() { return mAllowMultiSelect; } bool getAllowDrag() { return mAllowDrag; } void setSingleFolderMode(bool is_single_mode) { mSingleFolderMode = is_single_mode; } bool isSingleFolderMode() { return mSingleFolderMode; } // Close all folders in the view void closeAllFolders(); void openTopLevelFolders(); virtual void addFolder( LLFolderViewFolder* folder); // Find width and height of this object and its children. Also // makes sure that this view and its children are the right size. virtual S32 arrange( S32* width, S32* height ); virtual S32 getItemHeight() const; void arrangeAll() { mArrangeGeneration++; } S32 getArrangeGeneration() { return mArrangeGeneration; } // applies filters to control visibility of items virtual void filter( LLFolderViewFilter& filter); void clearHoveredItem() { setHoveredItem(nullptr); } LLFolderViewItem* getHoveredItem() const; void setHoveredItem(LLFolderViewItem* itemp); // Get the last selected item virtual LLFolderViewItem* getCurSelectedItem( void ); selected_items_t& getSelectedItems( void ); // Record the selected item and pass it down the hierarchy. virtual bool setSelection(LLFolderViewItem* selection, bool openitem, bool take_keyboard_focus = true); // This method is used to toggle the selection of an item. Walks // children, and keeps track of selected objects. virtual bool changeSelection(LLFolderViewItem* selection, bool selected); virtual std::set<LLFolderViewItem*> getSelectionList() const; // Make sure if ancestor is selected, descendants are not void sanitizeSelection(); virtual void clearSelection(); void addToSelectionList(LLFolderViewItem* item); void removeFromSelectionList(LLFolderViewItem* item); bool startDrag(); void setDragAndDropThisFrame() { mDragAndDropThisFrame = true; } void setDraggingOverItem(LLFolderViewItem* item) { mDraggingOverItem = item; } LLFolderViewItem* getDraggingOverItem() { return mDraggingOverItem; } // Deletion functionality void removeSelectedItems(); void autoOpenItem(LLFolderViewFolder* item); void closeAutoOpenedFolders(); bool autoOpenTest(LLFolderViewFolder* item); bool isOpen() const { return true; } // root folder always open // Copy & paste virtual bool canCopy() const; virtual void copy(); virtual bool canCut() const; virtual void cut(); virtual bool canPaste() const; virtual void paste(); LLFolderViewItem* getNextUnselectedItem(); // Public rename functionality - can only start the process void startRenamingSelectedItem( void ); // LLView functionality ///*virtual*/ bool handleKey( KEY key, MASK mask, bool called_from_parent ); /*virtual*/ bool handleKeyHere( KEY key, MASK mask ); /*virtual*/ bool handleUnicodeCharHere(llwchar uni_char); /*virtual*/ bool handleMouseDown( S32 x, S32 y, MASK mask ); /*virtual*/ bool handleDoubleClick( S32 x, S32 y, MASK mask ); /*virtual*/ bool handleRightMouseDown( S32 x, S32 y, MASK mask ); /*virtual*/ bool handleHover( S32 x, S32 y, MASK mask ); /*virtual*/ bool handleDragAndDrop(S32 x, S32 y, MASK mask, bool drop, EDragAndDropType cargo_type, void* cargo_data, EAcceptance* accept, std::string& tooltip_msg); /*virtual*/ void reshape(S32 width, S32 height, bool called_from_parent = true); /*virtual*/ void onMouseLeave(S32 x, S32 y, MASK mask) { setShowSelectionContext(false); } virtual void draw(); virtual void deleteAllChildren(); void stopAutoScollining() {mNeedsScroll = false;} void scrollToShowSelection(); void scrollToShowItem(LLFolderViewItem* item, const LLRect& constraint_rect); void setScrollContainer( LLScrollContainer* parent ) { mScrollContainer = parent; } LLRect getVisibleRect(); bool search(LLFolderViewItem* first_item, const std::string &search_string, bool backward); void setShowSelectionContext(bool show) { mShowSelectionContext = show; } bool getShowSelectionContext(); void setShowSingleSelection(bool show); bool getShowSingleSelection() { return mShowSingleSelection; } F32 getSelectionFadeElapsedTime() { return mMultiSelectionFadeTimer.getElapsedTimeF32(); } bool getUseEllipses() { return mUseEllipses; } S32 getSelectedCount() { return (S32)mSelectedItems.size(); } void update(); // needs to be called periodically (e.g. once per frame) bool needsAutoSelect() { return mNeedsAutoSelect && !mAutoSelectOverride; } bool needsAutoRename() { return mNeedsAutoRename; } void setNeedsAutoRename(bool val) { mNeedsAutoRename = val; } void setPinningSelectedItem(bool val) { mPinningSelectedItem = val; } void setAutoSelectOverride(bool val) { mAutoSelectOverride = val; } bool showItemLinkOverlays() { return mShowItemLinkOverlays; } void setCallbackRegistrar(LLUICtrl::CommitCallbackRegistry::ScopedRegistrar* registrar) { mCallbackRegistrar = registrar; } void setEnableRegistrar(LLUICtrl::EnableCallbackRegistry::ScopedRegistrar* registrar) { mEnableRegistrar = registrar; } void setForceArrange(bool force) { mForceArrange = force; } LLPanel* getParentPanel() { return mParentPanel.get(); } // DEBUG only void dumpSelectionInformation(); virtual S32 notify(const LLSD& info) ; void setShowEmptyMessage(bool show_msg) { mShowEmptyMessage = show_msg; } bool useLabelSuffix() { return mUseLabelSuffix; } virtual void updateMenu(); void finishRenamingItem( void ); // Note: We may eventually have to move that method up the hierarchy to LLFolderViewItem. LLHandle<LLFolderView> getHandle() const { return getDerivedHandle<LLFolderView>(); } private: void updateMenuOptions(LLMenuGL* menu); void updateRenamerPosition(); protected: LLScrollContainer* mScrollContainer; // NULL if this is not a child of a scroll container. void commitRename( const LLSD& data ); void onRenamerLost(); void closeRenamer( void ); bool isFolderSelected(); bool selectFirstItem(); bool selectLastItem(); bool addNoOptions(LLMenuGL* menu) const; protected: LLHandle<LLView> mPopupMenuHandle; std::string mMenuFileName; LLHandle<LLView> mHoveredItem; selected_items_t mSelectedItems; bool mKeyboardSelection, mAllowMultiSelect, mAllowDrag, mShowEmptyMessage, mShowFolderHierarchy, mNeedsScroll, mPinningSelectedItem, mNeedsAutoSelect, mAutoSelectOverride, mNeedsAutoRename, mUseLabelSuffix, mDragAndDropThisFrame, mShowItemLinkOverlays, mShowSelectionContext, mShowSingleSelection, mSuppressFolderMenu, mSingleFolderMode; // Renaming variables and methods LLFolderViewItem* mRenameItem; // The item currently being renamed LLLineEditor* mRenamer; LLRect mScrollConstraintRect; LLDepthStack<LLFolderViewFolder> mAutoOpenItems; LLFolderViewFolder* mAutoOpenCandidate; LLFrameTimer mAutoOpenTimer; LLFrameTimer mSearchTimer; std::string mSearchString; LLFrameTimer mMultiSelectionFadeTimer; S32 mArrangeGeneration; signal_t mSelectSignal; signal_t mReshapeSignal; S32 mSignalSelectCallback; S32 mMinWidth; LLHandle<LLPanel> mParentPanel; LLFolderViewModelInterface* mViewModel; LLFolderViewGroupedItemModel* mGroupedItemModel; /** * Is used to determine if we need to cut text In LLFolderViewItem to avoid horizontal scroll. * NOTE: For now it's used only to cut LLFolderViewItem::mLabel text for Landmarks in Places Panel. */ bool mUseEllipses; // See EXT-719 /** * Contains item under mouse pointer while dragging */ LLFolderViewItem* mDraggingOverItem; // See EXT-719 LLUICtrl::CommitCallbackRegistry::ScopedRegistrar* mCallbackRegistrar; LLUICtrl::EnableCallbackRegistry::ScopedRegistrar* mEnableRegistrar; boost::signals2::connection mRenamerTopLostSignalConnection; bool mForceArrange; public: static F32 sAutoOpenTime; LLTextBox* mStatusTextBox; }; //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Class LLFolderViewFunctor // // Simple abstract base class for applying a functor to folders and // items in a folder view hierarchy. This is suboptimal for algorithms // that only work folders or only work on items, but I'll worry about // that later when it's determined to be too slow. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ class LLFolderViewFunctor { public: virtual ~LLFolderViewFunctor() {} virtual void doFolder(LLFolderViewFolder* folder) = 0; virtual void doItem(LLFolderViewItem* item) = 0; }; //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Class LLSelectFirstFilteredItem // // This will select the first *item* found in the hierarchy. If no item can be // selected, the first matching folder will. // Since doFolder() is done first but we prioritize item selection, we let the // first filtered folder set the selection and raise a folder flag. // The selection might be overridden by the first filtered item in doItem() // which checks an item flag. Since doFolder() checks the item flag too, the first // item will still be selected if items were to be done first and folders second. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ class LLSelectFirstFilteredItem : public LLFolderViewFunctor { public: LLSelectFirstFilteredItem() : mItemSelected(false), mFolderSelected(false) {} virtual ~LLSelectFirstFilteredItem() {} virtual void doFolder(LLFolderViewFolder* folder); virtual void doItem(LLFolderViewItem* item); bool wasItemSelected() { return mItemSelected || mFolderSelected; } protected: bool mItemSelected; bool mFolderSelected; }; class LLOpenFilteredFolders : public LLFolderViewFunctor { public: LLOpenFilteredFolders() {} virtual ~LLOpenFilteredFolders() {} virtual void doFolder(LLFolderViewFolder* folder); virtual void doItem(LLFolderViewItem* item); }; class LLSaveFolderState : public LLFolderViewFunctor { public: LLSaveFolderState() : mApply(false) {} virtual ~LLSaveFolderState() {} virtual void doFolder(LLFolderViewFolder* folder); virtual void doItem(LLFolderViewItem* item) {} void setApply(bool apply); void clearOpenFolders() { mOpenFolders.clear(); } protected: std::set<LLUUID> mOpenFolders; bool mApply; }; class LLOpenFoldersWithSelection : public LLFolderViewFunctor { public: LLOpenFoldersWithSelection() {} virtual ~LLOpenFoldersWithSelection() {} virtual void doFolder(LLFolderViewFolder* folder); virtual void doItem(LLFolderViewItem* item); }; class LLAllDescendentsPassedFilter : public LLFolderViewFunctor { public: LLAllDescendentsPassedFilter() : mAllDescendentsPassedFilter(true) {} /*virtual*/ ~LLAllDescendentsPassedFilter() {} /*virtual*/ void doFolder(LLFolderViewFolder* folder); /*virtual*/ void doItem(LLFolderViewItem* item); bool allDescendentsPassedFilter() const { return mAllDescendentsPassedFilter; } protected: bool mAllDescendentsPassedFilter; }; // Flags for buildContextMenu() const U32 SUPPRESS_OPEN_ITEM = 0x1; const U32 FIRST_SELECTED_ITEM = 0x2; const U32 ITEM_IN_MULTI_SELECTION = 0x4; #endif // LL_LLFOLDERVIEW_H