xref: /haiku/src/kits/tracker/PoseView.h (revision 746cac055adc6ac3308c7bc2d29040fb95689cc9)
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 WidgetTextOutline() const;
211 		void SetWidgetTextOutline(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 		void AddMimeType(const char* mimeType);
319 		const char *MimeTypeAt(int32 index);
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 		status_t GetDeskbarFrame(BRect* frame);
460 		bool SlotOccupied(BRect poseRect, BRect viewBounds) const;
461 		void NextSlot(BPose *, BRect &poseRect, BRect viewBounds);
462 		void TrySettingPoseLocation(BNode *node, BPoint point);
463 		BPoint PinToGrid(BPoint, BPoint grid, BPoint offset) const;
464 
465 		// zombie pose handling
466 		Model *FindZombie(const node_ref *, int32 *index = 0);
467 		BPose *ConvertZombieToPose(Model *zombie, int32 index);
468 
469 		// pose handling
470 		BRect CalcPoseRect(BPose *, int32 index, bool minimal = false) const;
471 		void DrawPose(BPose *, int32 index, bool fullDraw = true);
472 		void DrawViewCommon(BRect, bool recalculateText = false);
473 
474 		// pose list handling
475 		int32 BSearchList(const BPose *, int32 *index);
476 		void InsertPoseAfter(BPose *pose, int32 *index, int32 orientation,
477 			BRect *invalidRect);
478 			// does a CopyBits to scroll poses making room for a new pose,
479 			// returns rectangle that needs invalidating
480 		void CloseGapInList(BRect *invalidRect);
481 		int32 FirstIndexAtOrBelow(int32 y, bool constrainIndex = true) const;
482 		void AddToVSList(BPose *);
483 		int32 RemoveFromVSList(const BPose *);
484 		BPose *FindNearbyPose(char arrow, int32 *index);
485 		BPose *FindBestMatch(int32 *index);
486 		BPose *FindNextMatch(int32 *index, bool reverse = false);
487 
488 		// node monitoring calls
489 		virtual void StartWatching();
490 		virtual void StopWatching();
491 
492 		status_t WatchNewNode(const node_ref *item);
493 			// the above would ideally be the only call of these three and it would
494 			// be a virtual, overriding the specific watch mask in query pose view, etc.
495 			// however we need to call WatchNewNode from inside AddPosesTask while
496 			// the window is unlocked - we have to use the static and a cached
497 			// messenger and masks.
498 		static status_t WatchNewNode(const node_ref *, uint32, BMessenger);
499 		virtual uint32 WatchNewNodeMask();
500 			// override to change different watch modes for query pose view, etc.
501 
502 		// drag&drop handling
503 		static bool EachItemInDraggedSelection(const BMessage *message,
504 			bool (*)(BPose *, BPoseView *, void *), BPoseView *poseView,
505 			void * = NULL);
506 			// iterates through each pose in current selectiond in the source
507 			// window of the current drag message; locks the window
508 			// add const version
509 		BRect GetDragRect(int32 clickedPoseIndex);
510 		BBitmap *MakeDragBitmap(BRect dragRect, BPoint clickedPoint, int32 clickedPoseIndex, BPoint &offset);
511 		static bool FindDragNDropAction(const BMessage *dragMessage, bool &canCopy,
512 			bool &canMove, bool &canLink, bool &canErase);
513 
514 		static bool CanTrashForeignDrag(const Model *);
515 		static bool CanCopyOrMoveForeignDrag(const Model *, const BMessage *);
516 		static bool DragSelectionContains(const BPose *target, const BMessage *dragMessage);
517 		static status_t CreateClippingFile(BPoseView *poseView, BFile &result,
518 			char *resultingName, BDirectory *dir, BMessage *message, const char *fallbackName,
519 			bool setLocation = false, BPoint dropPoint = BPoint(0, 0));
520 
521 		// opening files, lanunching
522 		void OpenSelectionCommon(BPose *, int32 *, bool);
523 			// used by OpenSelection and OpenSelectionUsing
524 		static void LaunchAppWithSelection(Model *, const BMessage *, bool checkTypes = true);
525 
526 		// node monitoring calls
527 		virtual bool EntryMoved(const BMessage *);
528 		virtual bool AttributeChanged(const BMessage *);
529 		virtual bool NoticeMetaMimeChanged(const BMessage *);
530 		virtual void MetaMimeChanged(const char *, const char *);
531 
532 		// click handling
533 		bool WasDoubleClick(const BPose *, BPoint);
534 		bool WasClickInPath(const BPose *, int32 index, BPoint) const;
535 		int32 WaitForMouseUpOrDrag(BPoint start);
536 
537 		// selection
538 		void SelectPosesListMode(BRect, BList **);
539 		void SelectPosesIconMode(BRect, BList **);
540 		void AddRemoveSelectionRange(BPoint where, bool extendSelection, BPose *);
541 
542 		// view drawing
543 		void SynchronousUpdate(BRect, bool clip = false);
544 
545 		// scrolling
546 		void HandleAutoScroll();
547 		bool CheckAutoScroll(BPoint mouseLoc, bool shouldScroll, bool selectionScrolling = false);
548 
549 		// view extent handling
550 		void RecalcExtent();
551 		void AddToExtent(const BRect &);
552 		void ClearExtent();
553 		void RemoveFromExtent(const BRect &);
554 
555 		virtual void EditQueries();
556 		virtual void AddCountView();
557 
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 		BPose *fAlreadySelectedDropTarget;
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 fWidgetTextOutline;
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 sFontHeight;
657 		static font_height sFontInfo;
658 		static BFont sCurrentFont;
659 		static bigtime_t sLastKeyTime;
660 		static char sMatchString[B_FILE_NAME_LENGTH];
661 			// used for typeahead - should be replaced by a typeahead state
662 
663 		bigtime_t fLastDeskbarFrameCheckTime;
664 		BRect fDeskbarFrame;
665 
666 		// TODO: Get rid of this.
667 		static _BWidthBuffer_ *sWidthBuffer;
668 
669 		static OffscreenBitmap *sOffscreen;
670 
671 		typedef BView _inherited;
672 };
673 
674 
675 class BHScrollBar : public BScrollBar {
676 	public:
677 		BHScrollBar(BRect, const char *, BView *);
678 		void SetTitleView(BView *);
679 
680 		// BScrollBar overrides
681 		virtual	void ValueChanged(float);
682 
683 	private:
684 		BView *fTitleView;
685 
686 		typedef BScrollBar _inherited;
687 };
688 
689 
690 class TPoseViewFilter : public BMessageFilter {
691 	public:
692 		TPoseViewFilter(BPoseView *pose);
693 		~TPoseViewFilter();
694 
695 		filter_result Filter(BMessage *, BHandler **);
696 
697 	private:
698 		filter_result ObjectDropFilter(BMessage *, BHandler **);
699 
700 		BPoseView *fPoseView;
701 };
702 
703 
704 extern bool
705 ClearViewOriginOne(const char *name, uint32 type, off_t size, void *data, void *params);
706 
707 // inlines follow
708 
709 inline BContainerWindow *
710 BPoseView::ContainerWindow() const
711 {
712 	return dynamic_cast<BContainerWindow *>(Window());
713 }
714 
715 inline Model *
716 BPoseView::TargetModel() const
717 {
718 	return fModel;
719 }
720 
721 inline float
722 BPoseView::ListElemHeight() const
723 {
724 	return fListElemHeight;
725 }
726 
727 inline float
728 BPoseView::IconPoseHeight() const
729 {
730 	return fIconPoseHeight;
731 }
732 
733 inline uint32
734 BPoseView::IconSizeInt() const
735 {
736 	return fViewState->IconSize();
737 }
738 
739 inline icon_size
740 BPoseView::IconSize() const
741 {
742 	return (icon_size)fViewState->IconSize();
743 }
744 
745 inline PoseList *
746 BPoseView::SelectionList() const
747 {
748 	return fSelectionList;
749 }
750 
751 inline BObjectList<BString> *
752 BPoseView::MimeTypesInSelection()
753 {
754 	return &fMimeTypesInSelectionCache;
755 }
756 
757 inline BHScrollBar*
758 BPoseView::HScrollBar() const
759 {
760 	return fHScrollBar;
761 }
762 
763 inline BScrollBar*
764 BPoseView::VScrollBar() const
765 {
766 	return fVScrollBar;
767 }
768 
769 inline bool
770 BPoseView::StateNeedsSaving()
771 {
772 	return fStateNeedsSaving || fViewState->StateNeedsSaving();
773 }
774 
775 inline uint32
776 BPoseView::ViewMode() const
777 {
778 	return fViewState->ViewMode();
779 }
780 
781 inline font_height
782 BPoseView::FontInfo() const
783 {
784 	return sFontInfo;
785 }
786 
787 inline float
788 BPoseView::FontHeight() const
789 {
790 	return sFontHeight;
791 }
792 
793 inline BPose *
794 BPoseView::ActivePose() const
795 {
796 	return fActivePose;
797 }
798 
799 inline void
800 BPoseView::DisableSaveLocation()
801 {
802 	fSavePoseLocations = false;
803 }
804 
805 inline bool
806 BPoseView::IsFilePanel() const
807 {
808 	return false;
809 }
810 
811 inline bool
812 BPoseView::IsDesktopWindow() const
813 {
814 	return fIsDesktopWindow;
815 }
816 
817 inline bool
818 BPoseView::IsDesktopView() const
819 {
820 	return false;
821 }
822 
823 inline uint32
824 BPoseView::PrimarySort() const
825 {
826 	return fViewState->PrimarySort();
827 }
828 
829 inline uint32
830 BPoseView::PrimarySortType() const
831 {
832 	return fViewState->PrimarySortType();
833 }
834 
835 inline uint32
836 BPoseView::SecondarySort() const
837 {
838 	return fViewState->SecondarySort();
839 }
840 
841 inline uint32
842 BPoseView::SecondarySortType() const
843 {
844 	return fViewState->SecondarySortType();
845 }
846 
847 inline bool
848 BPoseView::ReverseSort() const
849 {
850 	return fViewState->ReverseSort();
851 }
852 
853 inline void
854 BPoseView::SetShowHideSelection(bool on)
855 {
856 	fShowHideSelection = on;
857 }
858 
859 inline void
860 BPoseView::SetIconMapping(bool on)
861 {
862 	fOkToMapIcons = on;
863 }
864 
865 inline void
866 BPoseView::AddToExtent(const BRect &rect)
867 {
868 	fExtent = fExtent | rect;
869 }
870 
871 inline void
872 BPoseView::ClearExtent()
873 {
874 	fExtent.Set(LONG_MAX, LONG_MAX, LONG_MIN, LONG_MIN);
875 }
876 
877 inline int32
878 BPoseView::CountColumns() const
879 {
880 	return fColumnList->CountItems();
881 }
882 
883 inline int32
884 BPoseView::IndexOfColumn(const BColumn* column) const
885 {
886 	return fColumnList->IndexOf(const_cast<BColumn *>(column));
887 }
888 
889 inline int32
890 BPoseView::IndexOfPose(const BPose *pose) const
891 {
892 	return fPoseList->IndexOf(pose);
893 }
894 
895 inline BPose *
896 BPoseView::PoseAtIndex(int32 index) const
897 {
898 	return fPoseList->ItemAt(index);
899 }
900 
901 inline BColumn *
902 BPoseView::ColumnAt(int32 index) const
903 {
904 	return fColumnList->ItemAt(index);
905 }
906 
907 inline BColumn *
908 BPoseView::FirstColumn() const
909 {
910 	return fColumnList->FirstItem();
911 }
912 
913 inline BColumn *
914 BPoseView::LastColumn() const
915 {
916 	return fColumnList->LastItem();
917 }
918 
919 inline int32
920 BPoseView::CountItems() const
921 {
922 	return fPoseList->CountItems();
923 }
924 
925 inline void
926 BPoseView::SetMultipleSelection(bool state)
927 {
928 	fMultipleSelection = state;
929 }
930 
931 inline void
932 BPoseView::SetSelectionChangedHook(bool state)
933 {
934 	fSelectionChangedHook = state;
935 }
936 
937 inline void
938 BPoseView::SetAutoScroll(bool state)
939 {
940 	fShouldAutoScroll = state;
941 }
942 
943 inline void
944 BPoseView::SetPoseEditing(bool state)
945 {
946 	fAllowPoseEditing = state;
947 }
948 
949 inline void
950 BPoseView::SetDragEnabled(bool state)
951 {
952 	fDragEnabled = state;
953 }
954 
955 inline void
956 BPoseView::SetDropEnabled(bool state)
957 {
958 	fDropEnabled = state;
959 }
960 
961 inline void
962 BPoseView::SetSelectionRectEnabled(bool state)
963 {
964 	fSelectionRectEnabled = state;
965 }
966 
967 inline void
968 BPoseView::SetAlwaysAutoPlace(bool state)
969 {
970 	fAlwaysAutoPlace = state;
971 }
972 
973 inline void
974 BPoseView::SetEnsurePosesVisible(bool state)
975 {
976 	fEnsurePosesVisible = state;
977 }
978 
979 inline void
980 BPoseView::SetSelectionHandler(BLooper *looper)
981 {
982 	fSelectionHandler = looper;
983 }
984 
985 inline void
986 BPoseView::SetRefFilter(BRefFilter *filter)
987 {
988 	fRefFilter = filter;
989 }
990 
991 inline BRefFilter *
992 BPoseView::RefFilter() const
993 {
994 	return fRefFilter;
995 }
996 
997 inline void
998 BHScrollBar::SetTitleView(BView *view)
999 {
1000 	fTitleView = view;
1001 }
1002 
1003 inline BPose *
1004 BPoseView::FindPose(const Model *model, int32 *index) const
1005 {
1006 	return fPoseList->FindPose(model, index);
1007 }
1008 
1009 inline BPose *
1010 BPoseView::FindPose(const node_ref *node, int32 *index) const
1011 {
1012 	return fPoseList->FindPose(node, index);
1013 }
1014 
1015 inline BPose *
1016 BPoseView::FindPose(const entry_ref *entry, int32 *index) const
1017 {
1018 	return fPoseList->FindPose(entry, index);
1019 }
1020 
1021 
1022 inline bool
1023 BPoseView::HasPosesInClipboard()
1024 {
1025 	return fHasPosesInClipboard;
1026 }
1027 
1028 
1029 inline void
1030 BPoseView::SetHasPosesInClipboard(bool hasPoses)
1031 {
1032 	fHasPosesInClipboard = hasPoses;
1033 }
1034 
1035 
1036 template<class Param1>
1037 void
1038 EachTextWidget(BPose *pose, BPoseView *poseView,
1039 	void (*func)(BTextWidget *, BPose *, BPoseView *, BColumn *, Param1), Param1 p1)
1040 {
1041 	for (int32 index = 0; ;index++) {
1042 		BColumn *column = poseView->ColumnAt(index);
1043 		if (!column)
1044 			break;
1045 
1046 		BTextWidget *widget = pose->WidgetFor(column->AttrHash());
1047 		if (widget)
1048 			(func)(widget, pose, poseView, column, p1);
1049 	}
1050 }
1051 
1052 
1053 template<class Param1, class Param2>
1054 void
1055 EachTextWidget(BPose *pose, BPoseView *poseView,
1056 	void (*func)(BTextWidget *, BPose *, BPoseView *, BColumn *,
1057 	Param1, Param2), Param1 p1, Param2 p2)
1058 {
1059 	for (int32 index = 0; ;index++) {
1060 		BColumn *column = poseView->ColumnAt(index);
1061 		if (!column)
1062 			break;
1063 
1064 		BTextWidget *widget = pose->WidgetFor(column->AttrHash());
1065 		if (widget)
1066 			(func)(widget, pose, poseView, column, p1, p2);
1067 	}
1068 }
1069 
1070 
1071 template<class Result, class Param1, class Param2>
1072 Result
1073 WhileEachTextWidget(BPose *pose, BPoseView *poseView,
1074 	Result (*func)(BTextWidget *, BPose *, BPoseView *, BColumn *,
1075 	Param1, Param2), Param1 p1, Param2 p2)
1076 {
1077 	for (int32 index = 0; ;index++) {
1078 		BColumn *column = poseView->ColumnAt(index);
1079 		if (!column)
1080 			break;
1081 
1082 		BTextWidget *widget = pose->WidgetFor(column->AttrHash());
1083 		if (widget) {
1084 			Result result = (func)(widget, pose, poseView, column, p1, p2);
1085 			if (result)
1086 				return result;
1087 		}
1088 	}
1089 	return 0;
1090 }
1091 
1092 
1093 } // namespace BPrivate
1094 
1095 using namespace BPrivate;
1096 
1097 #endif	/* _POSE_VIEW_H */
1098