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