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