xref: /haiku/src/kits/tracker/PoseView.h (revision 922e7ba1f3228e6f28db69b0ded8f86eb32dea17)
1 /*
2 Open Tracker License
3 
4 Terms and Conditions
5 
6 Copyright (c) 1991-2000, Be Incorporated. All rights reserved.
7 
8 Permission is hereby granted, free of charge, to any person obtaining a copy of
9 this software and associated documentation files (the "Software"), to deal in
10 the Software without restriction, including without limitation the rights to
11 use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
12 of the Software, and to permit persons to whom the Software is furnished to do
13 so, subject to the following conditions:
14 
15 The above copyright notice and this permission notice applies to all licensees
16 and shall be included in all copies or substantial portions of the Software.
17 
18 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF TITLE, MERCHANTABILITY,
20 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21 BE INCORPORATED BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
22 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF, OR IN CONNECTION
23 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 
25 Except as contained in this notice, the name of Be Incorporated shall not be
26 used in advertising or otherwise to promote the sale, use or other dealings in
27 this Software without prior written authorization from Be Incorporated.
28 
29 Tracker(TM), Be(R), BeOS(R), and BeIA(TM) are trademarks or registered trademarks
30 of Be Incorporated in the United States and other countries. Other brand product
31 names are registered trademarks or trademarks of their respective holders.
32 All rights reserved.
33 */
34 
35 //
36 //	BPoseView is a container for poses, handling all of the interaction, drawing,
37 //	etc. The three different view modes are handled here.
38 //
39 //	this is by far the fattest Tracker class and over time will undergo a lot of
40 //	trimming
41 
42 #ifndef	_POSE_VIEW_H
43 #define _POSE_VIEW_H
44 
45 #include "AttributeStream.h"
46 #include "ContainerWindow.h"
47 #include "Model.h"
48 #include "PendingNodeMonitorCache.h"
49 #include "PoseList.h"
50 #include "TitleView.h"
51 #include "Utilities.h"
52 #include "ViewState.h"
53 
54 #include <Directory.h>
55 #include <FilePanel.h>
56 #include <MessageRunner.h>
57 #include <String.h>
58 #include <ScrollBar.h>
59 #include <View.h>
60 #include <hash_set>
61 #include <set>
62 
63 
64 class BRefFilter;
65 class BList;
66 
67 #if __GNUC__ > 2
68 namespace __gnu_cxx {
69 template<>
70 struct hash<node_ref>
71 #else
72 template<>
73 struct std::hash<node_ref>
74 #endif
75 {
76 	size_t operator()(node_ref ref) const {
77 		return ref.node;
78 	}
79 };
80 #if __GNUC__ > 2
81 } // namespace __gnu_cxx
82 typedef __gnu_cxx::hash_set<node_ref, __gnu_cxx::hash<node_ref> > NodeSet;
83 #else
84 typedef std::hash_set<node_ref, std::hash<node_ref> > NodeSet;
85 #endif
86 
87 
88 namespace BPrivate {
89 
90 class BCountView;
91 class BContainerWindow;
92 class BHScrollBar;
93 class EntryListBase;
94 
95 
96 const int32 kSmallStep = 10;
97 const int32 kListOffset = 20;
98 
99 const uint32 kMiniIconMode = 'Tmic';
100 const uint32 kIconMode = 'Ticn';
101 const uint32 kListMode = 'Tlst';
102 
103 const uint32 kCheckTypeahead = 'Tcty';
104 
105 class BPoseView : public BView {
106 	public:
107 		BPoseView(Model *, BRect, uint32 viewMode, uint32 resizeMask = B_FOLLOW_ALL);
108 		virtual ~BPoseView();
109 
110 		// setup, teardown
111 		virtual void Init(AttributeStreamNode *);
112 		virtual void Init(const BMessage &);
113 		void InitCommon();
114 		virtual	void DetachedFromWindow();
115 
116 		// Returns true if for instance, node ref is a remote desktop directory and
117 		// this is a desktop pose view.
118 		virtual bool Represents(const node_ref *) const;
119 		virtual bool Represents(const entry_ref *) const;
120 
121 		BContainerWindow *ContainerWindow() const;
122 		const char *ViewStateAttributeName() const;
123 		const char *ForeignViewStateAttributeName() const;
124 		Model *TargetModel() const;
125 
126 		virtual bool IsFilePanel() const;
127 		bool IsDesktopWindow() const;
128 		virtual bool IsDesktopView() const;
129 
130 		// state saving/restoring
131 		virtual	void SaveState(AttributeStreamNode *node);
132 		virtual void RestoreState(AttributeStreamNode *);
133 		virtual void RestoreColumnState(AttributeStreamNode *);
134 		void AddColumnList(BObjectList<BColumn> *list);
135 		virtual void SaveColumnState(AttributeStreamNode *);
136 		virtual void SavePoseLocations(BRect *frameIfDesktop = NULL);
137 		void DisableSaveLocation();
138 
139 		virtual	void SaveState(BMessage &) const;
140 		virtual void RestoreState(const BMessage &);
141 		virtual void RestoreColumnState(const BMessage &);
142 		virtual void SaveColumnState(BMessage &) const;
143 
144 		bool StateNeedsSaving();
145 
146 		// switch between mini icon mode, icon mode and list mode
147 		virtual void SetViewMode(uint32 mode);
148 		uint32 ViewMode() const;
149 
150 		// re-use the pose view for a new directory
151 	 	virtual void SwitchDir(const entry_ref *,
152 	 		AttributeStreamNode *node = NULL);
153 
154 		// in the rare cases where a pose view needs to be explicitly refreshed
155 		// (for instance in a query window with a dynamic date query), this is
156 		// used
157 		virtual void Refresh();
158 
159 		// callbacks
160 		virtual	void MessageReceived(BMessage *);
161 		virtual	void AttachedToWindow();
162 		virtual void WindowActivated(bool);
163 		virtual void MakeFocus(bool = true);
164 		virtual	void Draw(BRect update_rect);
165 		virtual	void DrawAfterChildren(BRect update_rect);
166 		virtual void MouseMoved(BPoint, uint32, const BMessage *);
167 		virtual	void MouseDown(BPoint where);
168 		virtual	void MouseUp(BPoint where);
169 		virtual	void MouseDragged(const BMessage *);
170 		virtual	void MouseLongDown(const BMessage *);
171 		virtual void MouseIdle(const BMessage *);
172 		virtual	void KeyDown(const char *, int32);
173 		virtual void Pulse();
174 		virtual void MoveBy(float, float);
175 		virtual void ScrollTo(BPoint point);
176 
177 		// misc. mode setters
178 		void SetMultipleSelection(bool);
179 		void SetDragEnabled(bool);
180 		void SetDropEnabled(bool);
181 		void SetSelectionRectEnabled(bool);
182 		void SetAlwaysAutoPlace(bool);
183 		void SetSelectionChangedHook(bool);
184 		void SetShowHideSelection(bool);
185 		void SetEnsurePosesVisible(bool);
186 		void SetIconMapping(bool);
187 		void SetAutoScroll(bool);
188 		void SetPoseEditing(bool);
189 
190 		void UpdateIcon(BPose *pose);
191 
192 		// file change notification handler
193 		virtual bool FSNotification(const BMessage *);
194 
195 		// scrollbars
196 		virtual void UpdateScrollRange();
197 		virtual	void SetScrollBarsTo(BPoint);
198 		virtual void AddScrollBars();
199 		BHScrollBar* HScrollBar() const;
200 		BScrollBar* VScrollBar() const ;
201 		BCountView* CountView() const;
202 		void DisableScrollBars();
203 		void EnableScrollBars();
204 
205 		// sorting
206 		virtual void SortPoses();
207 		void SetPrimarySort(uint32 attrHash);
208 		void SetSecondarySort(uint32 attrHash);
209 		void SetReverseSort(bool reverse);
210 		uint32 PrimarySort() const;
211 		uint32 PrimarySortType() const;
212 		uint32 SecondarySort() const;
213 		uint32 SecondarySortType() const;
214 		bool ReverseSort() const;
215 		void CheckPoseSortOrder(BPose *, int32 index);
216 		void CheckPoseVisibility(BRect * = NULL);
217 			// make sure pose fits the screen and/or window bounds if needed
218 
219 		// view metrics
220 		font_height	FontInfo() const;
221 			// returns height, descent, etc.
222 		float FontHeight() const;
223 		float ListElemHeight() const;
224 
225 		void SetIconPoseHeight();
226 		float IconPoseHeight() const;
227 		uint32 IconSizeInt() const;
228 		icon_size IconSize() const;
229 
230 		BRect Extent() const;
231 		void GetLayoutInfo(uint32 viewMode, BPoint *grid, BPoint *offset) const;
232 
233 		int32 CountItems() const;
234 		void UpdateCount();
235 
236 		rgb_color DeskTextColor() const;
237 		rgb_color DeskTextBackColor() const;
238 
239 		bool WidgetTextOutline() const;
240 		void SetWidgetTextOutline(bool);
241 			// used to not erase when we have a background image and
242 			// invalidate instead
243 
244 		// column handling
245 		void ColumnRedraw(BRect updateRect);
246 		bool AddColumn(BColumn *, const BColumn *after = NULL);
247 		bool RemoveColumn(BColumn *column, bool runAlert);
248 		void MoveColumnTo(BColumn *src, BColumn *dest);
249 		bool ResizeColumnToWidest(BColumn *column);
250 		BPoint ResizeColumn(BColumn *, float, float *lastLineDrawPos = NULL,
251 			void (*drawLineFunc)(BPoseView *, BPoint, BPoint) = 0,
252 			void (*undrawLineFunc)(BPoseView *, BPoint, BPoint) = 0);
253 			// returns the bottom right of the last pose drawn or bottom right of
254 			// bounds
255 
256 		BColumn *ColumnAt(int32 index) const;
257 		BColumn *ColumnFor(uint32 attribute_hash) const;
258 		BColumn *FirstColumn() const;
259 		BColumn *LastColumn() const;
260 		int32 IndexOfColumn(const BColumn *) const;
261 		int32 CountColumns() const;
262 
263 		// pose access
264 		int32 IndexOfPose(const BPose *) const;
265 		BPose *PoseAtIndex(int32 index) const;
266 
267 		BPose *FindPose(BPoint where, int32 *index = NULL) const;
268 			// return pose at location h, v (search list starting from bottom so
269 			// drawing and hit detection reflect the same pose ordering)
270 		BPose *FindPose(const Model *, int32 *index = NULL) const;
271 		BPose *FindPose(const node_ref *, int32 *index = NULL) const;
272 		BPose *FindPose(const entry_ref *, int32 *index = NULL) const;
273 		BPose *FindPose(const entry_ref *, int32 specifierForm, int32 *index) const;
274 			// special form of FindPose used for scripting, <specifierForm> may
275 			// ask for previous or next pose
276 		BPose *DeepFindPose(const node_ref *node, int32 *index = NULL) const;
277 			// same as FindPose, node can be a target of the actual
278 			// pose if the pose is a symlink
279 
280 		void OpenInfoWindows();
281 		void SetDefaultPrinter();
282 
283 		void IdentifySelection();
284 		void UnmountSelectedVolumes();
285 		virtual void OpenParent();
286 
287 		virtual void OpenSelection(BPose *clicked_pose = NULL, int32 *index = NULL);
288 		void OpenSelectionUsing(BPose *clicked_pose = NULL, int32 *index = NULL);
289 			// launches the open with window
290 		virtual void MoveSelectionTo(BPoint, BPoint, BContainerWindow *);
291 		void DuplicateSelection(BPoint *dropStart = NULL, BPoint *dropEnd = NULL);
292 
293 		// Move to trash calls try to select the next pose in the view when they
294 		// are dones
295 		virtual void MoveSelectionToTrash(bool selectNext = true);
296 		virtual void DeleteSelection(bool selectNext = true, bool askUser = true);
297 		virtual void MoveEntryToTrash(const entry_ref *, bool selectNext = true);
298 
299 		void RestoreSelectionFromTrash(bool selectNext = true);
300 
301 		// selection
302 		PoseList *SelectionList() const;
303 		void SelectAll();
304 		void InvertSelection();
305 		int32 SelectMatchingEntries(const BMessage *);
306 		void ShowSelectionWindow();
307 		void ClearSelection();
308 		void ShowSelection(bool);
309 		void AddRemovePoseFromSelection(BPose *pose, int32 index, bool select);
310 
311 		BLooper *SelectionHandler();
312 		void SetSelectionHandler(BLooper *);
313 
314 		BObjectList<BString> *MimeTypesInSelection();
315 
316 		// pose selection
317 		void SelectPose(BPose *, int32 index, bool scrollIntoView = true);
318 		void AddPoseToSelection(BPose *, int32 index,
319 			bool scrollIntoView = true);
320 		void RemovePoseFromSelection(BPose *);
321 		void SelectPoseAtLocation(BPoint);
322 		void SelectPoses(int32 start, int32 end);
323 
324 		// pose handling
325 		void ScrollIntoView(BPose *pose, int32 index);
326 		void ScrollIntoView(BRect poseRect);
327 		void SetActivePose(BPose *);
328 		BPose *ActivePose() const;
329 		void CommitActivePose(bool saveChanges = true);
330 		static bool PoseVisible(const Model *, const PoseInfo *);
331 		bool FrameForPose(BPose *targetpose, bool convert, BRect *poseRect);
332 		bool CreateSymlinkPoseTarget(Model *symlink);
333 			// used to complete a symlink pose; returns true if
334 			// target symlink should not be shown
335 		void ResetPosePlacementHint();
336 		void PlaceFolder(const entry_ref *, const BMessage *);
337 
338 		// clipboard handling for poses
339 		inline bool HasPosesInClipboard();
340 		inline void SetHasPosesInClipboard(bool hasPoses);
341 		void SetPosesClipboardMode(uint32 clipboardMode);
342 		void UpdatePosesClipboardModeFromClipboard(BMessage *clipboardReport = NULL);
343 
344 		// filtering
345 		void SetRefFilter(BRefFilter *);
346 		BRefFilter *RefFilter() const;
347 
348 		// access for mime types represented in the pose view
349 		void AddMimeType(const char* mimeType);
350 		const char *MimeTypeAt(int32 index);
351 		int32 CountMimeTypes();
352 	 	void RefreshMimeTypeList();
353 
354 		// drag&drop handling
355 		virtual bool HandleMessageDropped(BMessage *);
356 		static bool HandleDropCommon(BMessage *dragMessage, Model *target, BPose *,
357 			BView *view, BPoint dropPt);
358 			// used by pose views and info windows
359 		static bool CanHandleDragSelection(const Model *target,
360 			const BMessage *dragMessage, bool ignoreTypes);
361 		virtual	void DragSelectedPoses(const BPose *clickedPose, BPoint);
362 
363 		void MoveSelectionInto(Model *destFolder, BContainerWindow *srcWindow,
364 			bool forceCopy, bool forceMove = false, bool createLink = false, bool relativeLink = false);
365 		static void MoveSelectionInto(Model *destFolder, BContainerWindow *srcWindow,
366 			BContainerWindow *destWindow, uint32 buttons, BPoint loc,
367 			bool forceCopy, bool forceMove = false, bool createLink = false, bool relativeLink = false,
368 			BPoint clickPt = BPoint(0, 0), bool pinToGrid = false);
369 
370 		bool UpdateDropTarget(BPoint, const BMessage *, bool trackingContextMenu);
371 			// return true if drop target changed
372 		void HiliteDropTarget(bool hiliteState);
373 
374 		void DragStop();
375 			// throw away cached up structures
376 
377 		static bool MenuTrackingHook(BMenu *menu, void *castToThis);
378 			// hook for spring loaded nav-menus
379 
380 		// scripting
381 		virtual BHandler *ResolveSpecifier(BMessage	*message, int32 index,
382 			BMessage *specifier, int32 form, const char	*property);
383 		virtual status_t GetSupportedSuites(BMessage *);
384 
385 		// string width calls that use local width caches, faster than using
386 		// the general purpose BView::StringWidth
387 		float StringWidth(const char *) const;
388 		float StringWidth(const char *, int32) const;
389 			// deliberately hide the BView StringWidth here - this makes it
390 			// easy to have the right StringWidth picked up by
391 			// template instantiation, as used by WidgetAttributeText
392 
393 		// show/hide barberpole while a background task is filling up the view, etc.
394 		void ShowBarberPole();
395 		void HideBarberPole();
396 
397 		bool fShowSelectionWhenInactive;
398 		bool fTransparentSelection;
399 		bool fIsDrawingSelectionRect;
400 
401 		bool IsWatchingDateFormatChange();
402 		void StartWatchDateFormatChange();
403 		void StopWatchDateFormatChange();
404 
405 		void UpdateDateColumns(BMessage *);
406 		virtual void AdaptToVolumeChange(BMessage *);
407 		virtual void AdaptToDesktopIntegrationChange(BMessage *);
408 
409 	protected:
410 		// view setup
411 		virtual void SetUpDefaultColumnsIfNeeded();
412 
413 		virtual EntryListBase *InitDirentIterator(const entry_ref *);
414 			// sets up an entry iterator for _add_poses_
415 			// overriden by QueryPoseView, etc. to provide different iteration
416 
417 		void Cleanup(bool doAll = false);
418 			// clean up poses
419 		void NewFolder(const BMessage *);
420 			// create a new folder, optionally specify a location
421 
422 		void NewFileFromTemplate(const BMessage *);
423 			// create a new file based on a template, optionally specify a location
424 
425 		void ShowContextMenu(BPoint);
426 
427 		// scripting handlers
428 		virtual bool HandleScriptingMessage(BMessage *message);
429 		bool SetProperty(BMessage *message, BMessage *specifier, int32 form,
430 			const char *property, BMessage *reply);
431 		bool GetProperty(BMessage *, int32, const char *, BMessage *);
432 		bool CreateProperty(BMessage *message, BMessage *specifier, int32,
433 			const char *, BMessage *reply);
434 		bool ExecuteProperty(BMessage *specifier, int32, const char *, BMessage *reply);
435 		bool CountProperty(BMessage *, int32, const char *, BMessage *);
436 		bool DeleteProperty(BMessage *, int32, const char *, BMessage *);
437 
438 		void ClearPoses();
439 			// remove all the current poses from the view
440 
441 		// pose info read/write calls
442 		void ReadPoseInfo(Model *, PoseInfo *);
443 		ExtendedPoseInfo *ReadExtendedPoseInfo(Model *);
444 
445 		void _CheckPoseSortOrder(PoseList *list, BPose *, int32 index);
446 
447 		// pose creation
448 		BPose *EntryCreated(const node_ref *, const node_ref *, const char *, int32 *index = 0);
449 
450 		void AddPoseToList(PoseList *list, bool visibleList, bool insertionSort,
451 			BPose *pose, BRect &viewBounds, float &listViewScrollBy,
452 			bool forceDraw, int32 *indexPtr = NULL);
453 		BPose *CreatePose(Model *, PoseInfo *, bool insertionSort = true,
454 			int32 *index = 0, BRect *boundsPtr = 0, bool forceDraw = true);
455 		virtual void CreatePoses(Model **models, PoseInfo *poseInfoArray, int32 count,
456 			BPose **resultingPoses, bool insertionSort = true, int32 *lastPoseIndexPtr = 0,
457 			BRect *boundsPtr = 0, bool forceDraw = false);
458 		virtual bool ShouldShowPose(const Model *, const PoseInfo *);
459 			// filter, subclasses override to control which poses show up
460 			// subclasses should always call inherited
461 		void CreateVolumePose(BVolume *, bool watchIndividually);
462 
463 		void CreateTrashPose();
464 
465 		virtual bool AddPosesThreadValid(const entry_ref *) const;
466 			// verifies whether or not the current set of AddPoses threads
467 			// are valid and allowed to be adding poses -- returns false
468 			// in the case where the directory has been switched while populating
469 			// the view
470 
471 		virtual void AddPoses(Model *model = NULL);
472 			// if <model> is zero, PoseView has other means of iterating through all
473 			// the entries thaat it adds
474 
475 		virtual void AddRootPoses(bool watchIndividually, bool mountShared);
476 			// watchIndividually is used when placing a volume pose onto the Desktop
477 			// where unlike in the Root window it will not be watched by the folder
478 			// representing root. If set, each volume will therefore be watched
479 			// individually
480 		virtual void RemoveRootPoses();
481 		virtual void AddTrashPoses();
482 
483 		virtual bool DeletePose(const node_ref *, BPose *pose = NULL, int32 index = 0);
484 		virtual void DeleteSymLinkPoseTarget(const node_ref *itemNode, BPose *pose,
485 			int32 index);
486 			// the pose itself wasn't deleted but it's target node was - the
487 			// pose must be a symlink
488 		static void PoseHandleDeviceUnmounted(BPose *pose, Model *model, int32 index,
489 			BPoseView *poseView, dev_t device);
490 		static void RemoveNonBootDesktopModels(BPose *, Model *model, int32,
491 			BPoseView *poseView, dev_t);
492 
493 		// pose placement
494 		void CheckAutoPlacedPoses();
495 			// find poses that need placing and place them in a new spot
496 		void PlacePose(BPose *, BRect &);
497 			// find a new place for a pose, starting at fHintLocation and place it
498 		bool IsValidLocation(const BPose *pose);
499 		bool IsValidLocation(const BRect& rect);
500 		status_t GetDeskbarFrame(BRect* frame);
501 		bool SlotOccupied(BRect poseRect, BRect viewBounds) const;
502 		void NextSlot(BPose *, BRect &poseRect, BRect viewBounds);
503 		void TrySettingPoseLocation(BNode *node, BPoint point);
504 		BPoint PinToGrid(BPoint, BPoint grid, BPoint offset) const;
505 
506 		// zombie pose handling
507 		Model *FindZombie(const node_ref *, int32 *index = 0);
508 		BPose *ConvertZombieToPose(Model *zombie, int32 index);
509 
510 		// pose handling
511 		BRect CalcPoseRect(const BPose *, int32 index,
512 			bool firstColumnOnly = false) const;
513 		BRect CalcPoseRectIcon(const BPose *) const;
514 		BRect CalcPoseRectList(const BPose *, int32 index,
515 			bool firstColumnOnly = false) const;
516 		void DrawPose(BPose *, int32 index, bool fullDraw = true);
517 		void DrawViewCommon(const BRect &updateRect);
518 
519 		// pose list handling
520 		int32 BSearchList(PoseList *poseList, const BPose *, int32 *index);
521 		void InsertPoseAfter(BPose *pose, int32 *index, int32 orientation,
522 			BRect *invalidRect);
523 			// does a CopyBits to scroll poses making room for a new pose,
524 			// returns rectangle that needs invalidating
525 		void CloseGapInList(BRect *invalidRect);
526 		int32 FirstIndexAtOrBelow(int32 y, bool constrainIndex = true) const;
527 		void AddToVSList(BPose *);
528 		int32 RemoveFromVSList(const BPose *);
529 		BPose *FindNearbyPose(char arrow, int32 *index);
530 		BPose *FindBestMatch(int32 *index);
531 		BPose *FindNextMatch(int32 *index, bool reverse = false);
532 
533 		// node monitoring calls
534 		virtual void StartWatching();
535 		virtual void StopWatching();
536 
537 		status_t WatchNewNode(const node_ref *item);
538 			// the above would ideally be the only call of these three and it would
539 			// be a virtual, overriding the specific watch mask in query pose view, etc.
540 			// however we need to call WatchNewNode from inside AddPosesTask while
541 			// the window is unlocked - we have to use the static and a cached
542 			// messenger and masks.
543 		static status_t WatchNewNode(const node_ref *, uint32, BMessenger);
544 		virtual uint32 WatchNewNodeMask();
545 			// override to change different watch modes for query pose view, etc.
546 
547 		// drag&drop handling
548 		static bool EachItemInDraggedSelection(const BMessage *message,
549 			bool (*)(BPose *, BPoseView *, void *), BPoseView *poseView,
550 			void * = NULL);
551 			// iterates through each pose in current selectiond in the source
552 			// window of the current drag message; locks the window
553 			// add const version
554 		BRect GetDragRect(int32 clickedPoseIndex);
555 		BBitmap *MakeDragBitmap(BRect dragRect, BPoint clickedPoint, int32 clickedPoseIndex, BPoint &offset);
556 		static bool FindDragNDropAction(const BMessage *dragMessage, bool &canCopy,
557 			bool &canMove, bool &canLink, bool &canErase);
558 
559 		static bool CanTrashForeignDrag(const Model *);
560 		static bool CanCopyOrMoveForeignDrag(const Model *, const BMessage *);
561 		static bool DragSelectionContains(const BPose *target, const BMessage *dragMessage);
562 		static status_t CreateClippingFile(BPoseView *poseView, BFile &result,
563 			char *resultingName, BDirectory *dir, BMessage *message, const char *fallbackName,
564 			bool setLocation = false, BPoint dropPoint = BPoint(0, 0));
565 
566 		// opening files, lanunching
567 		void OpenSelectionCommon(BPose *, int32 *, bool);
568 			// used by OpenSelection and OpenSelectionUsing
569 		static void LaunchAppWithSelection(Model *, const BMessage *, bool checkTypes = true);
570 
571 		// node monitoring calls
572 		virtual bool EntryMoved(const BMessage *);
573 		virtual bool AttributeChanged(const BMessage *);
574 		virtual bool NoticeMetaMimeChanged(const BMessage *);
575 		virtual void MetaMimeChanged(const char *, const char *);
576 
577 		// click handling
578 		bool WasDoubleClick(const BPose *, BPoint);
579 		bool WasClickInPath(const BPose *, int32 index, BPoint) const;
580 
581 		// selection
582 		void SelectPosesListMode(BRect, BList **);
583 		void SelectPosesIconMode(BRect, BList **);
584 		void AddRemoveSelectionRange(BPoint where, bool extendSelection, BPose *);
585 
586 		void _BeginSelectionRect(const BPoint& point, bool extendSelection);
587 		void _UpdateSelectionRect(const BPoint& point);
588 		void _EndSelectionRect();
589 
590 		// view drawing
591 		void SynchronousUpdate(BRect, bool clip = false);
592 
593 		// scrolling
594 		void HandleAutoScroll();
595 		bool CheckAutoScroll(BPoint mouseLoc, bool shouldScroll, bool selectionScrolling = false);
596 
597 		// view extent handling
598 		void RecalcExtent();
599 		void AddToExtent(const BRect &);
600 		void ClearExtent();
601 		void RemoveFromExtent(const BRect &);
602 
603 		virtual void EditQueries();
604 		virtual void AddCountView();
605 
606 		void HandleAttrMenuItemSelected(BMessage *);
607 		void TryUpdatingBrokenLinks();
608 			// ran a little after a volume gets mounted
609 
610 		void MapToNewIconMode(BPose *, BPoint oldGrid, BPoint oldOffset);
611 		void ResetOrigin();
612 		void PinPointToValidRange(BPoint &);
613 			// used to ensure pose locations make sense after getting them
614 			// in pose info from attributes, etc.
615 
616 		void FinishPendingScroll(float &listViewScrollBy, BRect bounds);
617 			// utility call for CreatePoses
618 
619 		// background AddPoses task calls
620 		static status_t AddPosesTask(void *);
621 		virtual void AddPosesCompleted();
622 		bool IsValidAddPosesThread(thread_id) const;
623 
624 		// typeahead filtering
625 		void EnsurePoseUnselected(BPose *pose);
626 		void RemoveFilteredPose(BPose *pose, int32 index);
627 		void FilterChanged();
628 		void UpdateAfterFilterChange();
629 		bool FilterPose(BPose *pose);
630 		void StartFiltering();
631 		void StopFiltering();
632 		void ClearFilter();
633 		PoseList *CurrentPoseList() const;
634 
635 		// misc
636 		BList *GetDropPointList(BPoint dropPoint, BPoint startPoint, const PoseList *,
637 			bool sourceInListMode, bool dropOnGrid) const;
638 		void SendSelectionAsRefs(uint32 what, bool onlyQueries = false);
639 		void MoveListToTrash(BObjectList<entry_ref> *, bool selectNext, bool deleteDirectly);
640 		void Delete(BObjectList<entry_ref> *, bool selectNext, bool askUser);
641 		void Delete(const entry_ref &ref, bool selectNext, bool askUser);
642 		void RestoreItemsFromTrash(BObjectList<entry_ref> *, bool selectNext);
643 
644 	private:
645 		void DrawOpenAnimation(BRect);
646 
647 		void MoveSelectionOrEntryToTrash(const entry_ref *ref, bool selectNext);
648 
649 	protected:
650 		BHScrollBar *fHScrollBar;
651 		BScrollBar *fVScrollBar;
652 		Model *fModel;
653 		BPose *fActivePose;
654 		BRect fExtent;
655 		// the following should probably be just member lists, not pointers
656 		PoseList *fPoseList;
657 		PoseList *fFilteredPoseList;
658 		PoseList *fVSPoseList;
659 		PoseList *fSelectionList;
660 		NodeSet fInsertedNodes;
661 		BObjectList<BString> fMimeTypesInSelectionCache;
662 			// used for mime string based icon highliting during a drag
663 		BObjectList<Model> *fZombieList;
664 		PendingNodeMonitorCache pendingNodeMonitorCache;
665 		BObjectList<BColumn> *fColumnList;
666 		BObjectList<BString> *fMimeTypeList;
667 	  	bool fMimeTypeListIsDirty;
668 		BViewState *fViewState;
669 		bool fStateNeedsSaving;
670 		BCountView *fCountView;
671 		float fListElemHeight;
672 		float fIconPoseHeight;
673 		BPose *fDropTarget;
674 		BPose *fAlreadySelectedDropTarget;
675 		BLooper *fSelectionHandler;
676 		BPoint fLastClickPt;
677 		bigtime_t fLastClickTime;
678 		const BPose *fLastClickedPose;
679 		BPoint fLastLeftTop;
680 		BRect fLastExtent;
681 		BTitleView *fTitleView;
682 		BRefFilter *fRefFilter;
683 		BPoint fGrid;
684 		BPoint fOffset;
685 		BPoint fHintLocation;
686 		float fAutoScrollInc;
687 		int32 fAutoScrollState;
688 		std::set<thread_id> fAddPosesThreads;
689 		bool fWidgetTextOutline;
690 		const BPose *fSelectionPivotPose;
691 		const BPose *fRealPivotPose;
692 		BMessageRunner *fKeyRunner;
693 		bool fTrackRightMouseUp;
694 
695 		struct SelectionRectInfo {
696 					SelectionRectInfo()
697 						:	isDragging(false), selection(NULL) {};
698 			bool	isDragging;
699 			BRect	rect;
700 			BRect	lastRect;
701 			BPoint	startPoint;
702 			BPoint	lastPoint;
703 			BList*	selection;
704 		};
705 		SelectionRectInfo fSelectionRectInfo;
706 
707 		bool fSelectionVisible : 1;
708 		bool fMultipleSelection : 1;
709 		bool fDragEnabled : 1;
710 		bool fDropEnabled : 1;
711 		bool fSelectionRectEnabled : 1;
712 		bool fAlwaysAutoPlace : 1;
713 		bool fAllowPoseEditing : 1;
714 		bool fSelectionChangedHook : 1;	// get rid of this
715 		bool fSavePoseLocations : 1;
716 		bool fShowHideSelection : 1;
717 		bool fOkToMapIcons : 1;
718 		bool fEnsurePosesVisible : 1;
719 		bool fShouldAutoScroll : 1;
720 		bool fIsDesktopWindow : 1;
721 		bool fIsWatchingDateFormatChange : 1;
722 		bool fHasPosesInClipboard : 1;
723 		bool fCursorCheck : 1;
724 		bool fFiltering : 1;
725 
726 		BObjectList<BString> fFilterStrings;
727 		int32 fLastFilterStringCount;
728 		int32 fLastFilterStringLength;
729 
730 		BRect fStartFrame;
731 
732 		static float sFontHeight;
733 		static font_height sFontInfo;
734 		static BFont sCurrentFont;
735 		static BString sMatchString;
736 			// used for typeahead - should be replaced by a typeahead state
737 
738 		bigtime_t fLastKeyTime;
739 		bigtime_t fLastDeskbarFrameCheckTime;
740 		BRect fDeskbarFrame;
741 
742 		static OffscreenBitmap *sOffscreen;
743 
744 		typedef BView _inherited;
745 };
746 
747 
748 class BHScrollBar : public BScrollBar {
749 	public:
750 		BHScrollBar(BRect, const char *, BView *);
751 		void SetTitleView(BView *);
752 
753 		// BScrollBar overrides
754 		virtual	void ValueChanged(float);
755 
756 	private:
757 		BView *fTitleView;
758 
759 		typedef BScrollBar _inherited;
760 };
761 
762 
763 class TPoseViewFilter : public BMessageFilter {
764 	public:
765 		TPoseViewFilter(BPoseView *pose);
766 		~TPoseViewFilter();
767 
768 		filter_result Filter(BMessage *, BHandler **);
769 
770 	private:
771 		filter_result ObjectDropFilter(BMessage *, BHandler **);
772 
773 		BPoseView *fPoseView;
774 };
775 
776 
777 extern bool
778 ClearViewOriginOne(const char *name, uint32 type, off_t size, void *data, void *params);
779 
780 // inlines follow
781 
782 inline BContainerWindow *
783 BPoseView::ContainerWindow() const
784 {
785 	return dynamic_cast<BContainerWindow *>(Window());
786 }
787 
788 inline Model *
789 BPoseView::TargetModel() const
790 {
791 	return fModel;
792 }
793 
794 inline float
795 BPoseView::ListElemHeight() const
796 {
797 	return fListElemHeight;
798 }
799 
800 inline float
801 BPoseView::IconPoseHeight() const
802 {
803 	return fIconPoseHeight;
804 }
805 
806 inline uint32
807 BPoseView::IconSizeInt() const
808 {
809 	return fViewState->IconSize();
810 }
811 
812 inline icon_size
813 BPoseView::IconSize() const
814 {
815 	return (icon_size)fViewState->IconSize();
816 }
817 
818 inline PoseList *
819 BPoseView::SelectionList() const
820 {
821 	return fSelectionList;
822 }
823 
824 inline BObjectList<BString> *
825 BPoseView::MimeTypesInSelection()
826 {
827 	return &fMimeTypesInSelectionCache;
828 }
829 
830 inline BHScrollBar*
831 BPoseView::HScrollBar() const
832 {
833 	return fHScrollBar;
834 }
835 
836 inline BScrollBar*
837 BPoseView::VScrollBar() const
838 {
839 	return fVScrollBar;
840 }
841 
842 inline BCountView*
843 BPoseView::CountView() const
844 {
845 	return fCountView;
846 }
847 
848 inline bool
849 BPoseView::StateNeedsSaving()
850 {
851 	return fStateNeedsSaving || fViewState->StateNeedsSaving();
852 }
853 
854 inline uint32
855 BPoseView::ViewMode() const
856 {
857 	return fViewState->ViewMode();
858 }
859 
860 inline font_height
861 BPoseView::FontInfo() const
862 {
863 	return sFontInfo;
864 }
865 
866 inline float
867 BPoseView::FontHeight() const
868 {
869 	return sFontHeight;
870 }
871 
872 inline BPose *
873 BPoseView::ActivePose() const
874 {
875 	return fActivePose;
876 }
877 
878 inline void
879 BPoseView::DisableSaveLocation()
880 {
881 	fSavePoseLocations = false;
882 }
883 
884 inline bool
885 BPoseView::IsFilePanel() const
886 {
887 	return false;
888 }
889 
890 inline bool
891 BPoseView::IsDesktopWindow() const
892 {
893 	return fIsDesktopWindow;
894 }
895 
896 inline bool
897 BPoseView::IsDesktopView() const
898 {
899 	return false;
900 }
901 
902 inline uint32
903 BPoseView::PrimarySort() const
904 {
905 	return fViewState->PrimarySort();
906 }
907 
908 inline uint32
909 BPoseView::PrimarySortType() const
910 {
911 	return fViewState->PrimarySortType();
912 }
913 
914 inline uint32
915 BPoseView::SecondarySort() const
916 {
917 	return fViewState->SecondarySort();
918 }
919 
920 inline uint32
921 BPoseView::SecondarySortType() const
922 {
923 	return fViewState->SecondarySortType();
924 }
925 
926 inline bool
927 BPoseView::ReverseSort() const
928 {
929 	return fViewState->ReverseSort();
930 }
931 
932 inline void
933 BPoseView::SetShowHideSelection(bool on)
934 {
935 	fShowHideSelection = on;
936 }
937 
938 inline void
939 BPoseView::SetIconMapping(bool on)
940 {
941 	fOkToMapIcons = on;
942 }
943 
944 inline void
945 BPoseView::AddToExtent(const BRect &rect)
946 {
947 	fExtent = fExtent | rect;
948 }
949 
950 inline void
951 BPoseView::ClearExtent()
952 {
953 	fExtent.Set(LONG_MAX, LONG_MAX, LONG_MIN, LONG_MIN);
954 }
955 
956 inline int32
957 BPoseView::CountColumns() const
958 {
959 	return fColumnList->CountItems();
960 }
961 
962 inline int32
963 BPoseView::IndexOfColumn(const BColumn* column) const
964 {
965 	return fColumnList->IndexOf(const_cast<BColumn *>(column));
966 }
967 
968 inline int32
969 BPoseView::IndexOfPose(const BPose *pose) const
970 {
971 	return CurrentPoseList()->IndexOf(pose);
972 }
973 
974 inline BPose *
975 BPoseView::PoseAtIndex(int32 index) const
976 {
977 	return CurrentPoseList()->ItemAt(index);
978 }
979 
980 inline BColumn *
981 BPoseView::ColumnAt(int32 index) const
982 {
983 	return fColumnList->ItemAt(index);
984 }
985 
986 inline BColumn *
987 BPoseView::FirstColumn() const
988 {
989 	return fColumnList->FirstItem();
990 }
991 
992 inline BColumn *
993 BPoseView::LastColumn() const
994 {
995 	return fColumnList->LastItem();
996 }
997 
998 inline int32
999 BPoseView::CountItems() const
1000 {
1001 	return CurrentPoseList()->CountItems();
1002 }
1003 
1004 
1005 inline void
1006 BPoseView::SetMultipleSelection(bool state)
1007 {
1008 	fMultipleSelection = state;
1009 }
1010 
1011 inline void
1012 BPoseView::SetSelectionChangedHook(bool state)
1013 {
1014 	fSelectionChangedHook = state;
1015 }
1016 
1017 inline void
1018 BPoseView::SetAutoScroll(bool state)
1019 {
1020 	fShouldAutoScroll = state;
1021 }
1022 
1023 inline void
1024 BPoseView::SetPoseEditing(bool state)
1025 {
1026 	fAllowPoseEditing = state;
1027 }
1028 
1029 inline void
1030 BPoseView::SetDragEnabled(bool state)
1031 {
1032 	fDragEnabled = state;
1033 }
1034 
1035 inline void
1036 BPoseView::SetDropEnabled(bool state)
1037 {
1038 	fDropEnabled = state;
1039 }
1040 
1041 inline void
1042 BPoseView::SetSelectionRectEnabled(bool state)
1043 {
1044 	fSelectionRectEnabled = state;
1045 }
1046 
1047 inline void
1048 BPoseView::SetAlwaysAutoPlace(bool state)
1049 {
1050 	fAlwaysAutoPlace = state;
1051 }
1052 
1053 inline void
1054 BPoseView::SetEnsurePosesVisible(bool state)
1055 {
1056 	fEnsurePosesVisible = state;
1057 }
1058 
1059 inline void
1060 BPoseView::SetSelectionHandler(BLooper *looper)
1061 {
1062 	fSelectionHandler = looper;
1063 }
1064 
1065 inline void
1066 BPoseView::SetRefFilter(BRefFilter *filter)
1067 {
1068 	fRefFilter = filter;
1069 }
1070 
1071 inline BRefFilter *
1072 BPoseView::RefFilter() const
1073 {
1074 	return fRefFilter;
1075 }
1076 
1077 inline void
1078 BHScrollBar::SetTitleView(BView *view)
1079 {
1080 	fTitleView = view;
1081 }
1082 
1083 inline BPose *
1084 BPoseView::FindPose(const Model *model, int32 *index) const
1085 {
1086 	return CurrentPoseList()->FindPose(model, index);
1087 }
1088 
1089 inline BPose *
1090 BPoseView::FindPose(const node_ref *node, int32 *index) const
1091 {
1092 	return CurrentPoseList()->FindPose(node, index);
1093 }
1094 
1095 inline BPose *
1096 BPoseView::FindPose(const entry_ref *entry, int32 *index) const
1097 {
1098 	return CurrentPoseList()->FindPose(entry, index);
1099 }
1100 
1101 
1102 inline bool
1103 BPoseView::HasPosesInClipboard()
1104 {
1105 	return fHasPosesInClipboard;
1106 }
1107 
1108 
1109 inline void
1110 BPoseView::SetHasPosesInClipboard(bool hasPoses)
1111 {
1112 	fHasPosesInClipboard = hasPoses;
1113 }
1114 
1115 
1116 inline PoseList *
1117 BPoseView::CurrentPoseList() const
1118 {
1119 	return fFiltering ? fFilteredPoseList : fPoseList;
1120 }
1121 
1122 
1123 template<class Param1>
1124 void
1125 EachTextWidget(BPose *pose, BPoseView *poseView,
1126 	void (*func)(BTextWidget *, BPose *, BPoseView *, BColumn *, Param1), Param1 p1)
1127 {
1128 	for (int32 index = 0; ;index++) {
1129 		BColumn *column = poseView->ColumnAt(index);
1130 		if (!column)
1131 			break;
1132 
1133 		BTextWidget *widget = pose->WidgetFor(column->AttrHash());
1134 		if (widget)
1135 			(func)(widget, pose, poseView, column, p1);
1136 	}
1137 }
1138 
1139 
1140 template<class Param1, class Param2>
1141 void
1142 EachTextWidget(BPose *pose, BPoseView *poseView,
1143 	void (*func)(BTextWidget *, BPose *, BPoseView *, BColumn *,
1144 	Param1, Param2), Param1 p1, Param2 p2)
1145 {
1146 	for (int32 index = 0; ;index++) {
1147 		BColumn *column = poseView->ColumnAt(index);
1148 		if (!column)
1149 			break;
1150 
1151 		BTextWidget *widget = pose->WidgetFor(column->AttrHash());
1152 		if (widget)
1153 			(func)(widget, pose, poseView, column, p1, p2);
1154 	}
1155 }
1156 
1157 
1158 template<class Result, class Param1, class Param2>
1159 Result
1160 WhileEachTextWidget(BPose *pose, BPoseView *poseView,
1161 	Result (*func)(BTextWidget *, BPose *, BPoseView *, BColumn *,
1162 	Param1, Param2), Param1 p1, Param2 p2)
1163 {
1164 	for (int32 index = 0; ;index++) {
1165 		BColumn *column = poseView->ColumnAt(index);
1166 		if (!column)
1167 			break;
1168 
1169 		BTextWidget *widget = pose->WidgetFor(column->AttrHash());
1170 		if (widget) {
1171 			Result result = (func)(widget, pose, poseView, column, p1, p2);
1172 			if (result)
1173 				return result;
1174 		}
1175 	}
1176 	return 0;
1177 }
1178 
1179 
1180 } // namespace BPrivate
1181 
1182 using namespace BPrivate;
1183 
1184 #endif	/* _POSE_VIEW_H */
1185