xref: /haiku/src/kits/tracker/PoseView.h (revision 9760dcae2038d47442f4658c2575844c6cf92c40)
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 MouseMoved(BPoint, uint32, const BMessage *);
165 		virtual	void Draw(BRect update_rect);
166 		virtual	void DrawAfterChildren(BRect update_rect);
167 		virtual	void MouseDown(BPoint where);
168 		virtual	void KeyDown(const char *, int32);
169 		virtual void Pulse();
170 		virtual void MoveBy(float, float);
171 		virtual void ScrollTo(BPoint point);
172 
173 		// misc. mode setters
174 		void SetMultipleSelection(bool);
175 		void SetDragEnabled(bool);
176 		void SetDropEnabled(bool);
177 		void SetSelectionRectEnabled(bool);
178 		void SetAlwaysAutoPlace(bool);
179 		void SetSelectionChangedHook(bool);
180 		void SetShowHideSelection(bool);
181 		void SetEnsurePosesVisible(bool);
182 		void SetIconMapping(bool);
183 		void SetAutoScroll(bool);
184 		void SetPoseEditing(bool);
185 
186 		void UpdateIcon(BPose *pose);
187 
188 		// file change notification handler
189 		virtual bool FSNotification(const BMessage *);
190 
191 		// scrollbars
192 		virtual void UpdateScrollRange();
193 		virtual	void SetScrollBarsTo(BPoint);
194 		virtual void AddScrollBars();
195 		BHScrollBar* HScrollBar() const;
196 		BScrollBar* VScrollBar() const ;
197 		BCountView* CountView() const;
198 		void DisableScrollBars();
199 		void EnableScrollBars();
200 
201 		// sorting
202 		virtual void SortPoses();
203 		void SetPrimarySort(uint32 attrHash);
204 		void SetSecondarySort(uint32 attrHash);
205 		void SetReverseSort(bool reverse);
206 		uint32 PrimarySort() const;
207 		uint32 PrimarySortType() const;
208 		uint32 SecondarySort() const;
209 		uint32 SecondarySortType() const;
210 		bool ReverseSort() const;
211 		void CheckPoseSortOrder(BPose *, int32 index);
212 		void CheckPoseVisibility(BRect * = NULL);
213 			// make sure pose fits the screen and/or window bounds if needed
214 
215 		// view metrics
216 		font_height	FontInfo() const;
217 			// returns height, descent, etc.
218 		float FontHeight() const;
219 		float ListElemHeight() const;
220 
221 		void SetIconPoseHeight();
222 		float IconPoseHeight() const;
223 		uint32 IconSizeInt() const;
224 		icon_size IconSize() const;
225 
226 		BRect Extent() const;
227 		void GetLayoutInfo(uint32 viewMode, BPoint *grid, BPoint *offset) const;
228 
229 		int32 CountItems() const;
230 		void UpdateCount();
231 
232 		rgb_color DeskTextColor() const;
233 		rgb_color DeskTextBackColor() const;
234 
235 		bool WidgetTextOutline() const;
236 		void SetWidgetTextOutline(bool);
237 			// used to not erase when we have a background image and
238 			// invalidate instead
239 
240 		// column handling
241 		void ColumnRedraw(BRect updateRect);
242 		bool AddColumn(BColumn *, const BColumn *after = NULL);
243 		bool RemoveColumn(BColumn *column, bool runAlert);
244 		void MoveColumnTo(BColumn *src, BColumn *dest);
245 		bool ResizeColumnToWidest(BColumn *column);
246 		BPoint ResizeColumn(BColumn *, float, float *lastLineDrawPos = NULL,
247 			void (*drawLineFunc)(BPoseView *, BPoint, BPoint) = 0,
248 			void (*undrawLineFunc)(BPoseView *, BPoint, BPoint) = 0);
249 			// returns the bottom right of the last pose drawn or bottom right of
250 			// bounds
251 
252 		BColumn *ColumnAt(int32 index) const;
253 		BColumn *ColumnFor(uint32 attribute_hash) const;
254 		BColumn *FirstColumn() const;
255 		BColumn *LastColumn() const;
256 		int32 IndexOfColumn(const BColumn *) const;
257 		int32 CountColumns() const;
258 
259 		// pose access
260 		int32 IndexOfPose(const BPose *) const;
261 		BPose *PoseAtIndex(int32 index) const;
262 
263 		BPose *FindPose(BPoint where, int32 *index = NULL) const;
264 			// return pose at location h, v (search list starting from bottom so
265 			// drawing and hit detection reflect the same pose ordering)
266 		BPose *FindPose(const Model *, int32 *index = NULL) const;
267 		BPose *FindPose(const node_ref *, int32 *index = NULL) const;
268 		BPose *FindPose(const entry_ref *, int32 *index = NULL) const;
269 		BPose *FindPose(const entry_ref *, int32 specifierForm, int32 *index) const;
270 			// special form of FindPose used for scripting, <specifierForm> may
271 			// ask for previous or next pose
272 		BPose *DeepFindPose(const node_ref *node, int32 *index = NULL) const;
273 			// same as FindPose, node can be a target of the actual
274 			// pose if the pose is a symlink
275 
276 		void OpenInfoWindows();
277 		void SetDefaultPrinter();
278 
279 		void IdentifySelection();
280 		void UnmountSelectedVolumes();
281 		virtual void OpenParent();
282 
283 		virtual void OpenSelection(BPose *clicked_pose = NULL, int32 *index = NULL);
284 		void OpenSelectionUsing(BPose *clicked_pose = NULL, int32 *index = NULL);
285 			// launches the open with window
286 		virtual void MoveSelectionTo(BPoint, BPoint, BContainerWindow *);
287 		void DuplicateSelection(BPoint *dropStart = NULL, BPoint *dropEnd = NULL);
288 
289 		// Move to trash calls try to select the next pose in the view when they
290 		// are dones
291 		virtual void MoveSelectionToTrash(bool selectNext = true);
292 		virtual void DeleteSelection(bool selectNext = true, bool askUser = true);
293 		virtual void MoveEntryToTrash(const entry_ref *, bool selectNext = true);
294 
295 		void RestoreSelectionFromTrash(bool selectNext = true);
296 
297 		// selection
298 		PoseList *SelectionList() const;
299 		void SelectAll();
300 		void InvertSelection();
301 		int32 SelectMatchingEntries(const BMessage *);
302 		void ShowSelectionWindow();
303 		void ClearSelection();
304 		void ShowSelection(bool);
305 		void AddRemovePoseFromSelection(BPose *pose, int32 index, bool select);
306 
307 		BLooper *SelectionHandler();
308 		void SetSelectionHandler(BLooper *);
309 
310 		BObjectList<BString> *MimeTypesInSelection();
311 
312 		// pose selection
313 		void SelectPose(BPose *, int32 index, bool scrollIntoView = true);
314 		void AddPoseToSelection(BPose *, int32 index,
315 			bool scrollIntoView = true);
316 		void RemovePoseFromSelection(BPose *);
317 		void SelectPoseAtLocation(BPoint);
318 		void SelectPoses(int32 start, int32 end);
319 
320 		// pose handling
321 		void ScrollIntoView(BPose *pose, int32 index);
322 		void ScrollIntoView(BRect poseRect);
323 		void SetActivePose(BPose *);
324 		BPose *ActivePose() const;
325 		void CommitActivePose(bool saveChanges = true);
326 		static bool PoseVisible(const Model *, const PoseInfo *, bool inFilePanel);bool FrameForPose(BPose *targetpose, bool convert, BRect *poseRect);
327 		bool CreateSymlinkPoseTarget(Model *symlink);
328 			// used to complete a symlink pose; returns true if
329 			// target symlink should not be shown
330 		void ResetPosePlacementHint();
331 		void PlaceFolder(const entry_ref *, const BMessage *);
332 
333 		// clipboard handling for poses
334 		inline bool HasPosesInClipboard();
335 		inline void SetHasPosesInClipboard(bool hasPoses);
336 		void SetPosesClipboardMode(uint32 clipboardMode);
337 		void UpdatePosesClipboardModeFromClipboard(BMessage *clipboardReport = NULL);
338 
339 		// filtering
340 		void SetRefFilter(BRefFilter *);
341 		BRefFilter *RefFilter() const;
342 
343 		// access for mime types represented in the pose view
344 		void AddMimeType(const char* mimeType);
345 		const char *MimeTypeAt(int32 index);
346 		int32 CountMimeTypes();
347 	 	void RefreshMimeTypeList();
348 
349 		// drag&drop handling
350 		virtual bool HandleMessageDropped(BMessage *);
351 		static bool HandleDropCommon(BMessage *dragMessage, Model *target, BPose *,
352 			BView *view, BPoint dropPt);
353 			// used by pose views and info windows
354 		static bool CanHandleDragSelection(const Model *target,
355 			const BMessage *dragMessage, bool ignoreTypes);
356 		virtual	void DragSelectedPoses(const BPose *clickedPose, BPoint);
357 		virtual	void DragSelectionRect(BPoint, bool extendSelection);
358 
359 		void MoveSelectionInto(Model *destFolder, BContainerWindow *srcWindow,
360 			bool forceCopy, bool forceMove = false, bool createLink = false, bool relativeLink = false);
361 		static void MoveSelectionInto(Model *destFolder, BContainerWindow *srcWindow,
362 			BContainerWindow *destWindow, uint32 buttons, BPoint loc,
363 			bool forceCopy, bool forceMove = false, bool createLink = false, bool relativeLink = false,
364 			BPoint clickPt = BPoint(0, 0), bool pinToGrid = false);
365 
366 		bool UpdateDropTarget(BPoint, const BMessage *, bool trackingContextMenu);
367 			// return true if drop target changed
368 		void HiliteDropTarget(bool hiliteState);
369 
370 		void DragStop();
371 			// throw away cached up structures
372 
373 		static bool MenuTrackingHook(BMenu *menu, void *castToThis);
374 			// hook for spring loaded nav-menus
375 
376 		// scripting
377 		virtual BHandler *ResolveSpecifier(BMessage	*message, int32 index,
378 			BMessage *specifier, int32 form, const char	*property);
379 		virtual status_t GetSupportedSuites(BMessage *);
380 
381 		// string width calls that use local width caches, faster than using
382 		// the general purpose BView::StringWidth
383 		float StringWidth(const char *) const;
384 		float StringWidth(const char *, int32) const;
385 			// deliberately hide the BView StringWidth here - this makes it
386 			// easy to have the right StringWidth picked up by
387 			// template instantiation, as used by WidgetAttributeText
388 
389 		// show/hide barberpole while a background task is filling up the view, etc.
390 		void ShowBarberPole();
391 		void HideBarberPole();
392 
393 		bool fShowSelectionWhenInactive;
394 		bool fTransparentSelection;
395 		bool fIsDrawingSelectionRect;
396 
397 		bool IsWatchingDateFormatChange();
398 		void StartWatchDateFormatChange();
399 		void StopWatchDateFormatChange();
400 
401 		void UpdateDateColumns(BMessage *);
402 		virtual void AdaptToVolumeChange(BMessage *);
403 		virtual void AdaptToDesktopIntegrationChange(BMessage *);
404 
405 	protected:
406 		// view setup
407 		virtual void SetUpDefaultColumnsIfNeeded();
408 
409 		virtual EntryListBase *InitDirentIterator(const entry_ref *);
410 			// sets up an entry iterator for _add_poses_
411 			// overriden by QueryPoseView, etc. to provide different iteration
412 
413 		void Cleanup(bool doAll = false);
414 			// clean up poses
415 		void NewFolder(const BMessage *);
416 			// create a new folder, optionally specify a location
417 
418 		void NewFileFromTemplate(const BMessage *);
419 			// create a new file based on a template, optionally specify a location
420 
421 		void ShowContextMenu(BPoint);
422 
423 		// scripting handlers
424 		virtual bool HandleScriptingMessage(BMessage *message);
425 		bool SetProperty(BMessage *message, BMessage *specifier, int32 form,
426 			const char *property, BMessage *reply);
427 		bool GetProperty(BMessage *, int32, const char *, BMessage *);
428 		bool CreateProperty(BMessage *message, BMessage *specifier, int32,
429 			const char *, BMessage *reply);
430 		bool ExecuteProperty(BMessage *specifier, int32, const char *, BMessage *reply);
431 		bool CountProperty(BMessage *, int32, const char *, BMessage *);
432 		bool DeleteProperty(BMessage *, int32, const char *, BMessage *);
433 
434 		void ClearPoses();
435 			// remove all the current poses from the view
436 
437 		// pose info read/write calls
438 		void ReadPoseInfo(Model *, PoseInfo *);
439 		ExtendedPoseInfo *ReadExtendedPoseInfo(Model *);
440 
441 		// pose creation
442 		BPose *EntryCreated(const node_ref *, const node_ref *, const char *, int32 *index = 0);
443 
444 		BPose *CreatePose(Model *, PoseInfo *, bool insertionSort = true,
445 			int32 *index = 0, BRect *boundsPtr = 0, bool forceDraw = true);
446 		virtual void CreatePoses(Model **models, PoseInfo *poseInfoArray, int32 count,
447 			BPose **resultingPoses, bool insertionSort = true, int32 *lastPoseIndexPtr = 0,
448 			BRect *boundsPtr = 0, bool forceDraw = false);
449 		virtual bool ShouldShowPose(const Model *, const PoseInfo *);
450 			// filter, subclasses override to control which poses show up
451 			// subclasses should always call inherited
452 		void CreateVolumePose(BVolume *, bool watchIndividually);
453 
454 		virtual bool AddPosesThreadValid(const entry_ref *) const;
455 			// verifies whether or not the current set of AddPoses threads
456 			// are valid and allowed to be adding poses -- returns false
457 			// in the case where the directory has been switched while populating
458 			// the view
459 
460 		virtual void AddPoses(Model *model = NULL);
461 			// if <model> is zero, PoseView has other means of iterating through all
462 			// the entries thaat it adds
463 
464 		virtual void AddRootPoses(bool watchIndividually, bool mountShared);
465 			// watchIndividually is used when placing a volume pose onto the Desktop
466 			// where unlike in the Root window it will not be watched by the folder
467 			// representing root. If set, each volume will therefore be watched
468 			// individually
469 		virtual void RemoveRootPoses();
470 		virtual void AddTrashPoses();
471 
472 		virtual bool DeletePose(const node_ref *, BPose *pose = NULL, int32 index = 0);
473 		virtual void DeleteSymLinkPoseTarget(const node_ref *itemNode, BPose *pose,
474 			int32 index);
475 			// the pose itself wasn't deleted but it's target node was - the
476 			// pose must be a symlink
477 		static void PoseHandleDeviceUnmounted(BPose *pose, Model *model, int32 index,
478 			BPoseView *poseView, dev_t device);
479 		static void RemoveNonBootDesktopModels(BPose *, Model *model, int32,
480 			BPoseView *poseView, dev_t);
481 
482 		// pose placement
483 		void CheckAutoPlacedPoses();
484 			// find poses that need placing and place them in a new spot
485 		void PlacePose(BPose *, BRect &);
486 			// find a new place for a pose, starting at fHintLocation and place it
487 		bool IsValidLocation(const BPose *pose);
488 		bool IsValidLocation(const BRect& rect);
489 		status_t GetDeskbarFrame(BRect* frame);
490 		bool SlotOccupied(BRect poseRect, BRect viewBounds) const;
491 		void NextSlot(BPose *, BRect &poseRect, BRect viewBounds);
492 		void TrySettingPoseLocation(BNode *node, BPoint point);
493 		BPoint PinToGrid(BPoint, BPoint grid, BPoint offset) const;
494 
495 		// zombie pose handling
496 		Model *FindZombie(const node_ref *, int32 *index = 0);
497 		BPose *ConvertZombieToPose(Model *zombie, int32 index);
498 
499 		// pose handling
500 		BRect CalcPoseRect(const BPose *, int32 index,
501 			bool firstColumnOnly = false) const;
502 		BRect CalcPoseRectIcon(const BPose *) const;
503 		BRect CalcPoseRectList(const BPose *, int32 index,
504 			bool firstColumnOnly = false) const;
505 		void DrawPose(BPose *, int32 index, bool fullDraw = true);
506 		void DrawViewCommon(const BRect &updateRect);
507 
508 		// pose list handling
509 		int32 BSearchList(const BPose *, int32 *index);
510 		void InsertPoseAfter(BPose *pose, int32 *index, int32 orientation,
511 			BRect *invalidRect);
512 			// does a CopyBits to scroll poses making room for a new pose,
513 			// returns rectangle that needs invalidating
514 		void CloseGapInList(BRect *invalidRect);
515 		int32 FirstIndexAtOrBelow(int32 y, bool constrainIndex = true) const;
516 		void AddToVSList(BPose *);
517 		int32 RemoveFromVSList(const BPose *);
518 		BPose *FindNearbyPose(char arrow, int32 *index);
519 		BPose *FindBestMatch(int32 *index);
520 		BPose *FindNextMatch(int32 *index, bool reverse = false);
521 
522 		// node monitoring calls
523 		virtual void StartWatching();
524 		virtual void StopWatching();
525 
526 		status_t WatchNewNode(const node_ref *item);
527 			// the above would ideally be the only call of these three and it would
528 			// be a virtual, overriding the specific watch mask in query pose view, etc.
529 			// however we need to call WatchNewNode from inside AddPosesTask while
530 			// the window is unlocked - we have to use the static and a cached
531 			// messenger and masks.
532 		static status_t WatchNewNode(const node_ref *, uint32, BMessenger);
533 		virtual uint32 WatchNewNodeMask();
534 			// override to change different watch modes for query pose view, etc.
535 
536 		// drag&drop handling
537 		static bool EachItemInDraggedSelection(const BMessage *message,
538 			bool (*)(BPose *, BPoseView *, void *), BPoseView *poseView,
539 			void * = NULL);
540 			// iterates through each pose in current selectiond in the source
541 			// window of the current drag message; locks the window
542 			// add const version
543 		BRect GetDragRect(int32 clickedPoseIndex);
544 		BBitmap *MakeDragBitmap(BRect dragRect, BPoint clickedPoint, int32 clickedPoseIndex, BPoint &offset);
545 		static bool FindDragNDropAction(const BMessage *dragMessage, bool &canCopy,
546 			bool &canMove, bool &canLink, bool &canErase);
547 
548 		static bool CanTrashForeignDrag(const Model *);
549 		static bool CanCopyOrMoveForeignDrag(const Model *, const BMessage *);
550 		static bool DragSelectionContains(const BPose *target, const BMessage *dragMessage);
551 		static status_t CreateClippingFile(BPoseView *poseView, BFile &result,
552 			char *resultingName, BDirectory *dir, BMessage *message, const char *fallbackName,
553 			bool setLocation = false, BPoint dropPoint = BPoint(0, 0));
554 
555 		// opening files, lanunching
556 		void OpenSelectionCommon(BPose *, int32 *, bool);
557 			// used by OpenSelection and OpenSelectionUsing
558 		static void LaunchAppWithSelection(Model *, const BMessage *, bool checkTypes = true);
559 
560 		// node monitoring calls
561 		virtual bool EntryMoved(const BMessage *);
562 		virtual bool AttributeChanged(const BMessage *);
563 		virtual bool NoticeMetaMimeChanged(const BMessage *);
564 		virtual void MetaMimeChanged(const char *, const char *);
565 
566 		// click handling
567 		bool WasDoubleClick(const BPose *, BPoint);
568 		bool WasClickInPath(const BPose *, int32 index, BPoint) const;
569 		int32 WaitForMouseUpOrDrag(BPoint start);
570 
571 		// selection
572 		void SelectPosesListMode(BRect, BList **);
573 		void SelectPosesIconMode(BRect, BList **);
574 		void AddRemoveSelectionRange(BPoint where, bool extendSelection, BPose *);
575 
576 		// view drawing
577 		void SynchronousUpdate(BRect, bool clip = false);
578 
579 		// scrolling
580 		void HandleAutoScroll();
581 		bool CheckAutoScroll(BPoint mouseLoc, bool shouldScroll, bool selectionScrolling = false);
582 
583 		// view extent handling
584 		void RecalcExtent();
585 		void AddToExtent(const BRect &);
586 		void ClearExtent();
587 		void RemoveFromExtent(const BRect &);
588 
589 		virtual void EditQueries();
590 		virtual void AddCountView();
591 
592 		void HandleAttrMenuItemSelected(BMessage *);
593 		void TryUpdatingBrokenLinks();
594 			// ran a little after a volume gets mounted
595 
596 		void MapToNewIconMode(BPose *, BPoint oldGrid, BPoint oldOffset);
597 		void ResetOrigin();
598 		void PinPointToValidRange(BPoint &);
599 			// used to ensure pose locations make sense after getting them
600 			// in pose info from attributes, etc.
601 
602 		void FinishPendingScroll(float &listViewScrollBy, BRect bounds);
603 			// utility call for CreatePoses
604 
605 		// background AddPoses task calls
606 		static status_t AddPosesTask(void *);
607 		virtual void AddPosesCompleted();
608 		bool IsValidAddPosesThread(thread_id) const;
609 
610 		// misc
611 		BList *GetDropPointList(BPoint dropPoint, BPoint startPoint, const PoseList *,
612 			bool sourceInListMode, bool dropOnGrid) const;
613 		void SendSelectionAsRefs(uint32 what, bool onlyQueries = false);
614 		void MoveListToTrash(BObjectList<entry_ref> *, bool selectNext, bool deleteDirectly);
615 		void Delete(BObjectList<entry_ref> *, bool selectNext, bool askUser);
616 		void Delete(const entry_ref &ref, bool selectNext, bool askUser);
617 		void RestoreItemsFromTrash(BObjectList<entry_ref> *, bool selectNext);
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