PageRenderTime 72ms CodeModel.GetById 11ms app.highlight 55ms RepoModel.GetById 2ms app.codeStats 0ms

/indra/newview/llfolderviewitem.h

https://bitbucket.org/lindenlab/viewer-beta/
C++ Header | 574 lines | 307 code | 125 blank | 142 comment | 0 complexity | 9deef7e14e62cd86f08a3cdc817660e4 MD5 | raw file
  1/** 
  2* @file llfolderviewitem.h
  3* @brief Items and folders that can appear in a hierarchical folder view
  4*
  5* $LicenseInfo:firstyear=2001&license=viewerlgpl$
  6* Second Life Viewer Source Code
  7* Copyright (C) 2010, Linden Research, Inc.
  8* 
  9* This library is free software; you can redistribute it and/or
 10* modify it under the terms of the GNU Lesser General Public
 11* License as published by the Free Software Foundation;
 12* version 2.1 of the License only.
 13* 
 14* This library is distributed in the hope that it will be useful,
 15* but WITHOUT ANY WARRANTY; without even the implied warranty of
 16* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 17* Lesser General Public License for more details.
 18* 
 19* You should have received a copy of the GNU Lesser General Public
 20* License along with this library; if not, write to the Free Software
 21* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 22* 
 23* Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
 24* $/LicenseInfo$
 25*/
 26#ifndef LLFOLDERVIEWITEM_H
 27#define LLFOLDERVIEWITEM_H
 28
 29#include "llview.h"
 30#include "lldarray.h"  // *TODO: Eliminate, forward declare
 31#include "lluiimage.h"
 32
 33class LLFontGL;
 34class LLFolderView;
 35class LLFolderViewEventListener;
 36class LLFolderViewFolder;
 37class LLFolderViewFunctor;
 38class LLFolderViewItem;
 39class LLFolderViewListenerFunctor;
 40class LLInventoryFilter;
 41class LLMenuGL;
 42class LLUIImage;
 43class LLViewerInventoryItem;
 44
 45// These are grouping of inventory types.
 46// Order matters when sorting system folders to the top.
 47enum EInventorySortGroup
 48{ 
 49	SG_SYSTEM_FOLDER, 
 50	SG_TRASH_FOLDER, 
 51	SG_NORMAL_FOLDER, 
 52	SG_ITEM 
 53};
 54
 55// *TODO: do we really need one sort object per folder?
 56// can we just have one of these per LLFolderView ?
 57class LLInventorySort
 58{
 59public:
 60	LLInventorySort() 
 61		: mSortOrder(0),
 62		mByDate(false),
 63		mSystemToTop(false),
 64		mFoldersByName(false) { }
 65
 66	// Returns true if order has changed
 67	bool updateSort(U32 order);
 68	U32 getSort() { return mSortOrder; }
 69	bool isByDate() { return mByDate; }
 70
 71	bool operator()(const LLFolderViewItem* const& a, const LLFolderViewItem* const& b);
 72private:
 73	U32  mSortOrder;
 74	bool mByDate;
 75	bool mSystemToTop;
 76	bool mFoldersByName;
 77};
 78
 79//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 80// Class LLFolderViewItem
 81//
 82// An instance of this class represents a single item in a folder view
 83// such as an inventory item or a file.
 84//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 85
 86class LLFolderViewItem : public LLView
 87{
 88public:
 89	static void initClass();
 90	static void cleanupClass();
 91
 92	struct Params : public LLInitParam::Block<Params, LLView::Params>
 93	{
 94		Optional<LLUIImage*>					icon;
 95		Optional<LLUIImage*>					icon_open;  // used for folders
 96		Optional<LLUIImage*>					icon_overlay;  // for links
 97		Optional<LLFolderView*>					root;
 98		Mandatory<LLFolderViewEventListener*>	listener;
 99
100		Optional<LLUIImage*>					folder_arrow_image;
101		Optional<S32>							folder_indentation; // pixels
102		Optional<LLUIImage*>					selection_image;
103		Optional<S32>							item_height; // pixels
104		Optional<S32>							item_top_pad; // pixels
105
106		Optional<S32>							creation_date; //UTC seconds
107
108		Params();
109	};
110
111	// layout constants
112	static const S32 LEFT_PAD = 5;
113	// LEFT_INDENTATION is set via folder_indentation above
114	static const S32 ICON_PAD = 2;
115	static const S32 ICON_WIDTH = 16;
116	static const S32 TEXT_PAD = 1;
117	static const S32 ARROW_SIZE = 12;
118	static const S32 MAX_FOLDER_ITEM_OVERLAP = 2;
119	// animation parameters
120	static const F32 FOLDER_CLOSE_TIME_CONSTANT;
121	static const F32 FOLDER_OPEN_TIME_CONSTANT;
122
123	// Mostly for debugging printout purposes.
124	const std::string& getSearchableLabel() { return mSearchableLabel; }
125	
126	BOOL isLoading() const { return mIsLoading; }
127
128private:
129	BOOL						mIsSelected;
130
131protected:
132	friend class LLUICtrlFactory;
133	friend class LLFolderViewEventListener;
134
135	LLFolderViewItem(const Params& p);
136
137	std::string					mLabel;
138	std::string					mSearchableLabel;
139	S32							mLabelWidth;
140	bool						mLabelWidthDirty;
141	time_t						mCreationDate;
142	LLFolderViewFolder*			mParentFolder;
143	LLFolderViewEventListener*	mListener;
144	BOOL						mIsCurSelection;
145	BOOL						mSelectPending;
146	LLFontGL::StyleFlags		mLabelStyle;
147	std::string					mLabelSuffix;
148	LLUIImagePtr				mIcon;
149	std::string					mStatusText;
150	LLUIImagePtr				mIconOpen;
151	LLUIImagePtr				mIconOverlay;
152	BOOL						mHasVisibleChildren;
153	S32							mIndentation;
154	S32							mItemHeight;
155	BOOL						mPassedFilter;
156	S32							mLastFilterGeneration;
157	std::string::size_type		mStringMatchOffset;
158	F32							mControlLabelRotation;
159	LLFolderView*				mRoot;
160	BOOL						mDragAndDropTarget;
161	BOOL                        mIsLoading;
162	LLTimer                     mTimeSinceRequestStart;
163	bool						mShowLoadStatus;
164	bool						mIsMouseOverTitle;
165
166	// helper function to change the selection from the root.
167	void changeSelectionFromRoot(LLFolderViewItem* selection, BOOL selected);
168
169	// this is an internal method used for adding items to folders. A
170	// no-op at this level, but reimplemented in derived classes.
171	virtual BOOL addItem(LLFolderViewItem*) { return FALSE; }
172	virtual BOOL addFolder(LLFolderViewFolder*) { return FALSE; }
173
174	static LLFontGL* getLabelFontForStyle(U8 style);
175
176	virtual void setCreationDate(time_t creation_date_utc)	{ mCreationDate = creation_date_utc; }
177
178public:
179	BOOL postBuild();
180
181	// This function clears the currently selected item, and records
182	// the specified selected item appropriately for display and use
183	// in the UI. If open is TRUE, then folders are opened up along
184	// the way to the selection.
185	void setSelectionFromRoot(LLFolderViewItem* selection, BOOL openitem,
186		BOOL take_keyboard_focus = TRUE);
187
188	// This function is called when the folder view is dirty. It's
189	// implemented here but called by derived classes when folding the
190	// views.
191	void arrangeFromRoot();
192	void filterFromRoot( void );
193	
194	void arrangeAndSet(BOOL set_selection, BOOL take_keyboard_focus);
195
196	virtual ~LLFolderViewItem( void );
197
198	// addToFolder() returns TRUE if it succeeds. FALSE otherwise
199	enum { ARRANGE = TRUE, DO_NOT_ARRANGE = FALSE };
200	virtual BOOL addToFolder(LLFolderViewFolder* folder, LLFolderView* root);
201
202	virtual EInventorySortGroup getSortGroup() const;
203
204	// Finds width and height of this object and it's children.  Also
205	// makes sure that this view and it's children are the right size.
206	virtual S32 arrange( S32* width, S32* height, S32 filter_generation );
207	virtual S32 getItemHeight();
208
209	// applies filters to control visibility of inventory items
210	virtual void filter( LLInventoryFilter& filter);
211
212	// updates filter serial number and optionally propagated value up to root
213	S32		getLastFilterGeneration() { return mLastFilterGeneration; }
214
215	virtual void	dirtyFilter();
216
217	// If 'selection' is 'this' then note that otherwise ignore.
218	// Returns TRUE if this item ends up being selected.
219	virtual BOOL setSelection(LLFolderViewItem* selection, BOOL openitem, BOOL take_keyboard_focus);
220
221	// This method is used to set the selection state of an item.
222	// If 'selection' is 'this' then note selection.
223	// Returns TRUE if the selection state of this item was changed.
224	virtual BOOL changeSelection(LLFolderViewItem* selection, BOOL selected);
225
226	// this method is used to deselect this element
227	void deselectItem();
228
229	// this method is used to select this element
230	virtual void selectItem();
231
232	// gets multiple-element selection
233	virtual std::set<LLUUID> getSelectionList() const;
234
235	// Returns true is this object and all of its children can be removed (deleted by user)
236	virtual BOOL isRemovable();
237
238	// Returns true is this object and all of its children can be moved
239	virtual BOOL isMovable();
240
241	// destroys this item recursively
242	virtual void destroyView();
243
244	BOOL isSelected() const { return mIsSelected; }
245
246	void setUnselected() { mIsSelected = FALSE; }
247
248	void setIsCurSelection(BOOL select) { mIsCurSelection = select; }
249
250	BOOL getIsCurSelection() { return mIsCurSelection; }
251
252	BOOL hasVisibleChildren() { return mHasVisibleChildren; }
253
254	void setShowLoadStatus(bool status) { mShowLoadStatus = status; }
255
256	// Call through to the viewed object and return true if it can be
257	// removed. Returns true if it's removed.
258	//virtual BOOL removeRecursively(BOOL single_item);
259	BOOL remove();
260
261	// Build an appropriate context menu for the item.	Flags unused.
262	void buildContextMenu(LLMenuGL& menu, U32 flags);
263
264	// This method returns the actual name of the thing being
265	// viewed. This method will ask the viewed object itself.
266	const std::string& getName( void ) const;
267
268	const std::string& getSearchableLabel( void ) const;
269
270	// This method returns the label displayed on the view. This
271	// method was primarily added to allow sorting on the folder
272	// contents possible before the entire view has been constructed.
273	const std::string& getLabel() const { return mLabel; }
274
275	// Used for sorting, like getLabel() above.
276	virtual time_t getCreationDate() const { return mCreationDate; }
277
278	LLFolderViewFolder* getParentFolder( void ) { return mParentFolder; }
279	const LLFolderViewFolder* getParentFolder( void ) const { return mParentFolder; }
280
281	LLFolderViewItem* getNextOpenNode( BOOL include_children = TRUE );
282	LLFolderViewItem* getPreviousOpenNode( BOOL include_children = TRUE );
283
284	const LLFolderViewEventListener* getListener( void ) const { return mListener; }
285	LLFolderViewEventListener* getListener( void ) { return mListener; }
286	
287	// Gets the inventory item if it exists (null otherwise)
288	LLViewerInventoryItem * getInventoryItem(void);
289
290	// just rename the object.
291	void rename(const std::string& new_name);
292
293	// open
294	virtual void openItem( void );
295	virtual void preview(void);
296
297	// Show children (unfortunate that this is called "open")
298	virtual void setOpen(BOOL open = TRUE) {};
299
300	virtual BOOL isOpen() const { return FALSE; }
301
302	virtual LLFolderView*	getRoot();
303	BOOL			isDescendantOf( const LLFolderViewFolder* potential_ancestor );
304	S32				getIndentation() { return mIndentation; }
305
306	virtual BOOL	potentiallyVisible(); // do we know for a fact that this item has been filtered out?
307
308	virtual BOOL	getFiltered();
309	virtual BOOL	getFiltered(S32 filter_generation);
310	virtual void	setFiltered(BOOL filtered, S32 filter_generation);
311
312	// change the icon
313	void setIcon(LLUIImagePtr icon);
314
315	// refresh information from the object being viewed.
316	void refreshFromListener();
317	virtual void refresh();
318
319	virtual void applyListenerFunctorRecursively(LLFolderViewListenerFunctor& functor);
320
321	// LLView functionality
322	virtual BOOL handleRightMouseDown( S32 x, S32 y, MASK mask );
323	virtual BOOL handleMouseDown( S32 x, S32 y, MASK mask );
324	virtual BOOL handleHover( S32 x, S32 y, MASK mask );
325	virtual BOOL handleMouseUp( S32 x, S32 y, MASK mask );
326	virtual BOOL handleDoubleClick( S32 x, S32 y, MASK mask );
327
328	virtual void onMouseLeave(S32 x, S32 y, MASK mask);
329
330	virtual LLView* findChildView(const std::string& name, BOOL recurse) const { return NULL; }
331
332	//	virtual void handleDropped();
333	virtual void draw();
334	virtual BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
335		EDragAndDropType cargo_type,
336		void* cargo_data,
337		EAcceptance* accept,
338		std::string& tooltip_msg);
339
340private:
341	static std::map<U8, LLFontGL*> sFonts; // map of styles to fonts
342};
343
344
345// function used for sorting.
346typedef bool (*sort_order_f)(LLFolderViewItem* a, LLFolderViewItem* b);
347
348
349//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
350// Class LLFolderViewFolder
351//
352// An instance of an LLFolderViewFolder represents a collection of
353// more folders and items. This is used to build the hierarchy of
354// items found in the folder view.
355//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
356
357class LLFolderViewFolder : public LLFolderViewItem
358{
359protected:
360	LLFolderViewFolder( const LLFolderViewItem::Params& );
361	friend class LLUICtrlFactory;
362
363public:
364	typedef enum e_trash
365	{
366		UNKNOWN, TRASH, NOT_TRASH
367	} ETrash;
368
369	typedef std::list<LLFolderViewItem*> items_t;
370	typedef std::list<LLFolderViewFolder*> folders_t;
371
372protected:
373	items_t mItems;
374	folders_t mFolders;
375	LLInventorySort	mSortFunction;
376
377	BOOL		mIsOpen;
378	BOOL		mExpanderHighlighted;
379	F32			mCurHeight;
380	F32			mTargetHeight;
381	F32			mAutoOpenCountdown;
382	time_t		mSubtreeCreationDate;
383	mutable ETrash mAmTrash;
384	S32			mLastArrangeGeneration;
385	S32			mLastCalculatedWidth;
386	S32			mCompletedFilterGeneration;
387	S32			mMostFilteredDescendantGeneration;
388	bool		mNeedsSort;
389	bool		mPassedFolderFilter;
390
391public:
392	typedef enum e_recurse_type
393	{
394		RECURSE_NO,
395		RECURSE_UP,
396		RECURSE_DOWN,
397		RECURSE_UP_DOWN
398	} ERecurseType;
399
400
401	virtual ~LLFolderViewFolder( void );
402
403	virtual BOOL	potentiallyVisible();
404
405	LLFolderViewItem* getNextFromChild( LLFolderViewItem*, BOOL include_children = TRUE );
406	LLFolderViewItem* getPreviousFromChild( LLFolderViewItem*, BOOL include_children = TRUE  );
407
408	// addToFolder() returns TRUE if it succeeds. FALSE otherwise
409	virtual BOOL addToFolder(LLFolderViewFolder* folder, LLFolderView* root);
410
411	// Finds width and height of this object and it's children.  Also
412	// makes sure that this view and it's children are the right size.
413	virtual S32 arrange( S32* width, S32* height, S32 filter_generation );
414
415	BOOL needsArrange();
416	void requestSort();
417
418	// Returns the sort group (system, trash, folder) for this folder.
419	virtual EInventorySortGroup getSortGroup() const;
420
421	virtual void	setCompletedFilterGeneration(S32 generation, BOOL recurse_up);
422	virtual S32		getCompletedFilterGeneration() { return mCompletedFilterGeneration; }
423
424	BOOL hasFilteredDescendants(S32 filter_generation);
425	BOOL hasFilteredDescendants();
426
427	// applies filters to control visibility of inventory items
428	virtual void filter( LLInventoryFilter& filter);
429	virtual void setFiltered(BOOL filtered, S32 filter_generation);
430	virtual BOOL getFiltered();
431	virtual BOOL getFiltered(S32 filter_generation);
432
433	virtual void dirtyFilter();
434	
435	// folder-specific filtering (filter status propagates top down instead of bottom up)
436	void filterFolder(LLInventoryFilter& filter);
437	void setFilteredFolder(bool filtered, S32 filter_generation);
438	bool getFilteredFolder(S32 filter_generation);
439
440	// Passes selection information on to children and record
441	// selection information if necessary.
442	// Returns TRUE if this object (or a child) ends up being selected.
443	// If 'openitem' is TRUE then folders are opened up along the way to the selection.
444	virtual BOOL setSelection(LLFolderViewItem* selection, BOOL openitem, BOOL take_keyboard_focus);
445
446	// This method is used to change the selection of an item.
447	// Recursively traverse all children; if 'selection' is 'this' then change
448	// the select status if necessary.
449	// Returns TRUE if the selection state of this folder, or of a child, was changed.
450	virtual BOOL changeSelection(LLFolderViewItem* selection, BOOL selected);
451
452	// this method is used to group select items
453	void extendSelectionTo(LLFolderViewItem* selection);
454
455	// Returns true is this object and all of its children can be removed.
456	virtual BOOL isRemovable();
457
458	// Returns true is this object and all of its children can be moved
459	virtual BOOL isMovable();
460
461	// destroys this folder, and all children
462	virtual void destroyView();
463
464	// If this folder can be removed, remove all children that can be
465	// removed, return TRUE if this is empty after the operation and
466	// it's viewed folder object can be removed.
467	//virtual BOOL removeRecursively(BOOL single_item);
468	//virtual BOOL remove();
469
470	// remove the specified item (and any children) if
471	// possible. Return TRUE if the item was deleted.
472	BOOL removeItem(LLFolderViewItem* item);
473
474	// simply remove the view (and any children) Don't bother telling
475	// the listeners.
476	void removeView(LLFolderViewItem* item);
477
478	// extractItem() removes the specified item from the folder, but
479	// doesn't delete it.
480	void extractItem( LLFolderViewItem* item );
481
482	// This function is called by a child that needs to be resorted.
483	void resort(LLFolderViewItem* item);
484
485	void setItemSortOrder(U32 ordering);
486	void sortBy(U32);
487	//BOOL (*func)(LLFolderViewItem* a, LLFolderViewItem* b));
488
489	void setAutoOpenCountdown(F32 countdown) { mAutoOpenCountdown = countdown; }
490
491	// folders can be opened. This will usually be called by internal
492	// methods.
493	virtual void toggleOpen();
494
495	// Force a folder open or closed
496	virtual void setOpen(BOOL openitem = TRUE);
497
498	// Called when a child is refreshed.
499	// don't rearrange child folder contents unless explicitly requested
500	virtual void requestArrange(BOOL include_descendants = FALSE);
501
502	// internal method which doesn't update the entire view. This
503	// method was written because the list iterators destroy the state
504	// of other iterations, thus, we can't arrange while iterating
505	// through the children (such as when setting which is selected.
506	virtual void setOpenArrangeRecursively(BOOL openitem, ERecurseType recurse = RECURSE_NO);
507
508	// Get the current state of the folder.
509	virtual BOOL isOpen() const { return mIsOpen; }
510
511	// special case if an object is dropped on the child.
512	BOOL handleDragAndDropFromChild(MASK mask,
513		BOOL drop,
514		EDragAndDropType cargo_type,
515		void* cargo_data,
516		EAcceptance* accept,
517		std::string& tooltip_msg);
518
519	void applyFunctorRecursively(LLFolderViewFunctor& functor);
520	virtual void applyListenerFunctorRecursively(LLFolderViewListenerFunctor& functor);
521
522	// Just apply this functor to the folder's immediate children.
523	void applyFunctorToChildren(LLFolderViewFunctor& functor);
524
525	virtual void openItem( void );
526	virtual BOOL addItem(LLFolderViewItem* item);
527	virtual BOOL addFolder( LLFolderViewFolder* folder);
528
529	// LLView functionality
530	virtual BOOL handleHover(S32 x, S32 y, MASK mask);
531	virtual BOOL handleRightMouseDown( S32 x, S32 y, MASK mask );
532	virtual BOOL handleMouseDown( S32 x, S32 y, MASK mask );
533	virtual BOOL handleDoubleClick( S32 x, S32 y, MASK mask );
534	virtual BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
535		EDragAndDropType cargo_type,
536		void* cargo_data,
537		EAcceptance* accept,
538		std::string& tooltip_msg);
539	BOOL handleDragAndDropToThisFolder(MASK mask, BOOL drop,
540									   EDragAndDropType cargo_type,
541									   void* cargo_data,
542									   EAcceptance* accept,
543									   std::string& tooltip_msg);
544	virtual void draw();
545
546	time_t getCreationDate() const;
547	bool isTrash() const;
548
549	folders_t::const_iterator getFoldersBegin() const { return mFolders.begin(); }
550	folders_t::const_iterator getFoldersEnd() const { return mFolders.end(); }
551	folders_t::size_type getFoldersCount() const { return mFolders.size(); }
552
553	items_t::const_iterator getItemsBegin() const { return mItems.begin(); }
554	items_t::const_iterator getItemsEnd() const { return mItems.end(); }
555	items_t::size_type getItemsCount() const { return mItems.size(); }
556	LLFolderViewFolder* getCommonAncestor(LLFolderViewItem* item_a, LLFolderViewItem* item_b, bool& reverse);
557	void gatherChildRangeExclusive(LLFolderViewItem* start, LLFolderViewItem* end, bool reverse,  std::vector<LLFolderViewItem*>& items);
558};
559
560//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
561// Class LLFolderViewListenerFunctor
562//
563// This simple abstract base class can be used to applied to all
564// listeners in a hierarchy.
565//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
566
567class LLFolderViewListenerFunctor
568{
569public:
570	virtual ~LLFolderViewListenerFunctor() {}
571	virtual void operator()(LLFolderViewEventListener* listener) = 0;
572};
573
574#endif  // LLFOLDERVIEWITEM_H