455 lines
16 KiB
C++
455 lines
16 KiB
C++
/**
|
|
* @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);
|
|
|
|
// [SL:KB] - Patch: Inventory-DragDrop | Checked: 2014-02-04 (Catznip-3.6)
|
|
void setDragStart(S32 screen_x, S32 screen_y);
|
|
bool isOverDragThreshold(S32 screen_x, S32 screen_y);
|
|
// [/SL:KB]
|
|
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 handleScrollWheel(S32 x, S32 y, S32 clicks); // <FS:Ansariel> FIRE-14223: Using mouse scroll while renaming an item moves line editor out of inventory floater
|
|
/*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 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 );
|
|
void updateRenamerPosition();
|
|
|
|
// 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);
|
|
|
|
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;
|
|
// [SL:KB] - Patch: Inventory-DragDrop | Checked: 2014-02-04 (Catznip-3.6)
|
|
S32 mDragStartX;
|
|
S32 mDragStartY;
|
|
// [/SL:KB]
|
|
|
|
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;
|
|
|
|
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
|