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