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