xref: /haiku/src/kits/tracker/PoseView.h (revision 776c58b2b56d8bcf33638a2ecb6c697f95a1cbf3)
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);
612 		bool WasClickInPath(const BPose*, int32 index, BPoint) const;
613 
614 		// selection
615 		void SelectPosesListMode(BRect, BList**);
616 		void SelectPosesIconMode(BRect, BList**);
617 		void AddRemoveSelectionRange(BPoint where, bool extendSelection,
618 			BPose*);
619 
620 		void _BeginSelectionRect(const BPoint& point, bool extendSelection);
621 		void _UpdateSelectionRect(const BPoint& point);
622 		void _EndSelectionRect();
623 
624 		// view drawing
625 		void SynchronousUpdate(BRect, bool clip = false);
626 
627 		// scrolling
628 		void HandleAutoScroll();
629 		bool CheckAutoScroll(BPoint mouseLoc, bool shouldScroll);
630 
631 		// view extent handling
632 		void RecalcExtent();
633 		void AddToExtent(const BRect&);
634 		void ClearExtent();
635 		void RemoveFromExtent(const BRect&);
636 
637 		virtual void EditQueries();
638 		virtual void AddCountView();
639 
640 		void HandleAttrMenuItemSelected(BMessage*);
641 		void TryUpdatingBrokenLinks();
642 			// ran a little after a volume gets mounted
643 
644 		void MapToNewIconMode(BPose*, BPoint oldGrid, BPoint oldOffset);
645 		void ResetOrigin();
646 		void PinPointToValidRange(BPoint&);
647 			// used to ensure pose locations make sense after getting them
648 			// in pose info from attributes, etc.
649 
650 		void FinishPendingScroll(float&listViewScrollBy, BRect bounds);
651 			// utility call for CreatePoses
652 
653 		// background AddPoses task calls
654 		static status_t AddPosesTask(void*);
655 		virtual void AddPosesCompleted();
656 		bool IsValidAddPosesThread(thread_id) const;
657 
658 		// typeahead filtering
659 		void EnsurePoseUnselected(BPose* pose);
660 		void RemoveFilteredPose(BPose* pose, int32 index);
661 		void FilterChanged();
662 		void UpdateAfterFilterChange();
663 		bool FilterPose(BPose* pose);
664 		void StartFiltering();
665 		void StopFiltering();
666 		void ClearFilter();
667 		PoseList* CurrentPoseList() const;
668 
669 		// misc
670 		BList* GetDropPointList(BPoint dropPoint, BPoint startPoint,
671 			const PoseList*, bool sourceInListMode, bool dropOnGrid) const;
672 		void SendSelectionAsRefs(uint32 what, bool onlyQueries = false);
673 		void MoveListToTrash(BObjectList<entry_ref>*, bool selectNext,
674 			bool deleteDirectly);
675 		void Delete(BObjectList<entry_ref>*, bool selectNext, bool askUser);
676 		void Delete(const entry_ref&ref, bool selectNext, bool askUser);
677 		void RestoreItemsFromTrash(BObjectList<entry_ref>*, bool selectNext);
678 
679 		void WatchParentOf(const entry_ref*);
680 		void StopWatchingParentsOf(const entry_ref*);
681 
682 	private:
683 		void DrawOpenAnimation(BRect);
684 
685 		void MoveSelectionOrEntryToTrash(const entry_ref* ref, bool selectNext);
686 
687 	protected:
688 		BHScrollBar* fHScrollBar;
689 		BScrollBar* fVScrollBar;
690 		Model* fModel;
691 		BPose* fActivePose;
692 		BRect fExtent;
693 		// the following should probably be just member lists, not pointers
694 		PoseList* fPoseList;
695 		PoseList* fFilteredPoseList;
696 		PoseList* fVSPoseList;
697 		PoseList* fSelectionList;
698 		NodeSet fInsertedNodes;
699 		BObjectList<BString> fMimeTypesInSelectionCache;
700 			// used for mime string based icon highliting during a drag
701 		BObjectList<Model>* fZombieList;
702 		PendingNodeMonitorCache pendingNodeMonitorCache;
703 		BObjectList<BColumn>* fColumnList;
704 		BObjectList<BString>* fMimeTypeList;
705 		BObjectList<Model>* fBrokenLinks;
706 	  	bool fMimeTypeListIsDirty;
707 		BViewState* fViewState;
708 		bool fStateNeedsSaving;
709 		BCountView* fCountView;
710 		float fListElemHeight;
711 		float fIconPoseHeight;
712 		BPose* fDropTarget;
713 		BPose* fAlreadySelectedDropTarget;
714 		BLooper* fSelectionHandler;
715 		BPoint fLastClickPt;
716 		const BPose* fLastClickedPose;
717 		BPoint fLastLeftTop;
718 		BRect fLastExtent;
719 		BTitleView* fTitleView;
720 		BRefFilter* fRefFilter;
721 		BPoint fGrid;
722 		BPoint fOffset;
723 		BPoint fHintLocation;
724 		float fAutoScrollInc;
725 		int32 fAutoScrollState;
726 		std::set<thread_id> fAddPosesThreads;
727 		bool fWidgetTextOutline;
728 		const BPose* fSelectionPivotPose;
729 		const BPose* fRealPivotPose;
730 		BMessageRunner* fKeyRunner;
731 		bool fTrackRightMouseUp;
732 
733 		struct SelectionRectInfo {
734 					SelectionRectInfo()
735 						:	isDragging(false), selection(NULL) {};
736 			bool	isDragging;
737 			BRect	rect;
738 			BRect	lastRect;
739 			BPoint	startPoint;
740 			BPoint	lastPoint;
741 			BList*	selection;
742 		};
743 		SelectionRectInfo fSelectionRectInfo;
744 
745 		bool fSelectionVisible : 1;
746 		bool fMultipleSelection : 1;
747 		bool fDragEnabled : 1;
748 		bool fDropEnabled : 1;
749 		bool fSelectionRectEnabled : 1;
750 		bool fAlwaysAutoPlace : 1;
751 		bool fAllowPoseEditing : 1;
752 		bool fSelectionChangedHook : 1;	// get rid of this
753 		bool fSavePoseLocations : 1;
754 		bool fShowHideSelection : 1;
755 		bool fOkToMapIcons : 1;
756 		bool fEnsurePosesVisible : 1;
757 		bool fShouldAutoScroll : 1;
758 		bool fIsDesktopWindow : 1;
759 		bool fIsWatchingDateFormatChange : 1;
760 		bool fHasPosesInClipboard : 1;
761 		bool fCursorCheck : 1;
762 		bool fFiltering : 1;
763 
764 		BObjectList<BString> fFilterStrings;
765 		int32 fLastFilterStringCount;
766 		int32 fLastFilterStringLength;
767 
768 		BRect fStartFrame;
769 
770 		static float sFontHeight;
771 		static font_height sFontInfo;
772 		static BFont sCurrentFont;
773 		static BString sMatchString;
774 			// used for typeahead - should be replaced by a typeahead state
775 
776 		bigtime_t fLastKeyTime;
777 		bigtime_t fLastDeskbarFrameCheckTime;
778 		BRect fDeskbarFrame;
779 
780 		static OffscreenBitmap* sOffscreen;
781 
782 		BTextWidget* fTextWidgetToCheck;
783 
784 		typedef BView _inherited;
785 };
786 
787 
788 class BHScrollBar : public BScrollBar {
789 	public:
790 		BHScrollBar(BRect, const char*, BView*);
791 		void SetTitleView(BView*);
792 
793 		// BScrollBar overrides
794 		virtual	void ValueChanged(float);
795 
796 	private:
797 		BView* fTitleView;
798 
799 		typedef BScrollBar _inherited;
800 };
801 
802 
803 class TPoseViewFilter : public BMessageFilter {
804 	public:
805 		TPoseViewFilter(BPoseView* pose);
806 		~TPoseViewFilter();
807 
808 		filter_result Filter(BMessage*, BHandler**);
809 
810 	private:
811 		filter_result ObjectDropFilter(BMessage*, BHandler**);
812 
813 		BPoseView* fPoseView;
814 };
815 
816 
817 extern bool
818 ClearViewOriginOne(const char* name, uint32 type, off_t size, void* data,
819 	void* params);
820 
821 
822 // inlines follow
823 
824 
825 inline BContainerWindow*
826 BPoseView::ContainerWindow() const
827 {
828 	return dynamic_cast<BContainerWindow*>(Window());
829 }
830 
831 
832 inline Model*
833 BPoseView::TargetModel() const
834 {
835 	return fModel;
836 }
837 
838 
839 inline float
840 BPoseView::ListElemHeight() const
841 {
842 	return fListElemHeight;
843 }
844 
845 
846 inline float
847 BPoseView::IconPoseHeight() const
848 {
849 	return fIconPoseHeight;
850 }
851 
852 
853 inline uint32
854 BPoseView::IconSizeInt() const
855 {
856 	return fViewState->IconSize();
857 }
858 
859 
860 inline icon_size
861 BPoseView::IconSize() const
862 {
863 	return (icon_size)fViewState->IconSize();
864 }
865 
866 
867 inline PoseList*
868 BPoseView::SelectionList() const
869 {
870 	return fSelectionList;
871 }
872 
873 
874 inline BObjectList<BString>*
875 BPoseView::MimeTypesInSelection()
876 {
877 	return&fMimeTypesInSelectionCache;
878 }
879 
880 
881 inline BHScrollBar*
882 BPoseView::HScrollBar() const
883 {
884 	return fHScrollBar;
885 }
886 
887 
888 inline BScrollBar*
889 BPoseView::VScrollBar() const
890 {
891 	return fVScrollBar;
892 }
893 
894 
895 inline BCountView*
896 BPoseView::CountView() const
897 {
898 	return fCountView;
899 }
900 
901 
902 inline bool
903 BPoseView::StateNeedsSaving()
904 {
905 	return fStateNeedsSaving || fViewState->StateNeedsSaving();
906 }
907 
908 
909 inline uint32
910 BPoseView::ViewMode() const
911 {
912 	return fViewState->ViewMode();
913 }
914 
915 
916 inline font_height
917 BPoseView::FontInfo() const
918 {
919 	return sFontInfo;
920 }
921 
922 
923 inline float
924 BPoseView::FontHeight() const
925 {
926 	return sFontHeight;
927 }
928 
929 
930 inline BPose*
931 BPoseView::ActivePose() const
932 {
933 	return fActivePose;
934 }
935 
936 
937 inline void
938 BPoseView::DisableSaveLocation()
939 {
940 	fSavePoseLocations = false;
941 }
942 
943 
944 inline bool
945 BPoseView::IsFilePanel() const
946 {
947 	return false;
948 }
949 
950 
951 inline bool
952 BPoseView::IsDesktopWindow() const
953 {
954 	return fIsDesktopWindow;
955 }
956 
957 
958 inline bool
959 BPoseView::IsDesktopView() const
960 {
961 	return false;
962 }
963 
964 
965 inline uint32
966 BPoseView::PrimarySort() const
967 {
968 	return fViewState->PrimarySort();
969 }
970 
971 
972 inline uint32
973 BPoseView::PrimarySortType() const
974 {
975 	return fViewState->PrimarySortType();
976 }
977 
978 
979 inline uint32
980 BPoseView::SecondarySort() const
981 {
982 	return fViewState->SecondarySort();
983 }
984 
985 
986 inline uint32
987 BPoseView::SecondarySortType() const
988 {
989 	return fViewState->SecondarySortType();
990 }
991 
992 
993 inline bool
994 BPoseView::ReverseSort() const
995 {
996 	return fViewState->ReverseSort();
997 }
998 
999 
1000 inline void
1001 BPoseView::SetShowHideSelection(bool on)
1002 {
1003 	fShowHideSelection = on;
1004 }
1005 
1006 
1007 inline void
1008 BPoseView::SetIconMapping(bool on)
1009 {
1010 	fOkToMapIcons = on;
1011 }
1012 
1013 
1014 inline void
1015 BPoseView::AddToExtent(const BRect&rect)
1016 {
1017 	fExtent = fExtent | rect;
1018 }
1019 
1020 
1021 inline void
1022 BPoseView::ClearExtent()
1023 {
1024 	fExtent.Set(INT32_MAX, INT32_MAX, INT32_MIN, INT32_MIN);
1025 }
1026 
1027 
1028 inline int32
1029 BPoseView::CountColumns() const
1030 {
1031 	return fColumnList->CountItems();
1032 }
1033 
1034 
1035 inline int32
1036 BPoseView::IndexOfColumn(const BColumn* column) const
1037 {
1038 	return fColumnList->IndexOf(const_cast<BColumn*>(column));
1039 }
1040 
1041 
1042 inline int32
1043 BPoseView::IndexOfPose(const BPose* pose) const
1044 {
1045 	return CurrentPoseList()->IndexOf(pose);
1046 }
1047 
1048 
1049 inline BPose*
1050 BPoseView::PoseAtIndex(int32 index) const
1051 {
1052 	return CurrentPoseList()->ItemAt(index);
1053 }
1054 
1055 
1056 inline BColumn*
1057 BPoseView::ColumnAt(int32 index) const
1058 {
1059 	return fColumnList->ItemAt(index);
1060 }
1061 
1062 
1063 inline BColumn*
1064 BPoseView::FirstColumn() const
1065 {
1066 	return fColumnList->FirstItem();
1067 }
1068 
1069 
1070 inline BColumn*
1071 BPoseView::LastColumn() const
1072 {
1073 	return fColumnList->LastItem();
1074 }
1075 
1076 
1077 inline int32
1078 BPoseView::CountItems() const
1079 {
1080 	return CurrentPoseList()->CountItems();
1081 }
1082 
1083 
1084 inline void
1085 BPoseView::SetMultipleSelection(bool state)
1086 {
1087 	fMultipleSelection = state;
1088 }
1089 
1090 
1091 inline void
1092 BPoseView::SetSelectionChangedHook(bool state)
1093 {
1094 	fSelectionChangedHook = state;
1095 }
1096 
1097 
1098 inline void
1099 BPoseView::SetAutoScroll(bool state)
1100 {
1101 	fShouldAutoScroll = state;
1102 }
1103 
1104 
1105 inline void
1106 BPoseView::SetPoseEditing(bool state)
1107 {
1108 	fAllowPoseEditing = state;
1109 }
1110 
1111 
1112 inline void
1113 BPoseView::SetDragEnabled(bool state)
1114 {
1115 	fDragEnabled = state;
1116 }
1117 
1118 
1119 inline void
1120 BPoseView::SetDropEnabled(bool state)
1121 {
1122 	fDropEnabled = state;
1123 }
1124 
1125 
1126 inline void
1127 BPoseView::SetSelectionRectEnabled(bool state)
1128 {
1129 	fSelectionRectEnabled = state;
1130 }
1131 
1132 
1133 inline void
1134 BPoseView::SetAlwaysAutoPlace(bool state)
1135 {
1136 	fAlwaysAutoPlace = state;
1137 }
1138 
1139 
1140 inline void
1141 BPoseView::SetEnsurePosesVisible(bool state)
1142 {
1143 	fEnsurePosesVisible = state;
1144 }
1145 
1146 
1147 inline void
1148 BPoseView::SetSelectionHandler(BLooper* looper)
1149 {
1150 	fSelectionHandler = looper;
1151 }
1152 
1153 
1154 inline void
1155 BPoseView::SetRefFilter(BRefFilter* filter)
1156 {
1157 	fRefFilter = filter;
1158 	if (filter != NULL)
1159 		FilterChanged();
1160 }
1161 
1162 
1163 inline BRefFilter*
1164 BPoseView::RefFilter() const
1165 {
1166 	return fRefFilter;
1167 }
1168 
1169 
1170 inline void
1171 BHScrollBar::SetTitleView(BView* view)
1172 {
1173 	fTitleView = view;
1174 }
1175 
1176 
1177 inline BPose*
1178 BPoseView::FindPose(const Model* model, int32* index) const
1179 {
1180 	return CurrentPoseList()->FindPose(model, index);
1181 }
1182 
1183 
1184 inline BPose*
1185 BPoseView::FindPose(const node_ref* node, int32* index) const
1186 {
1187 	return CurrentPoseList()->FindPose(node, index);
1188 }
1189 
1190 
1191 inline BPose*
1192 BPoseView::FindPose(const entry_ref* entry, int32* index) const
1193 {
1194 	return CurrentPoseList()->FindPose(entry, index);
1195 }
1196 
1197 
1198 inline bool
1199 BPoseView::HasPosesInClipboard()
1200 {
1201 	return fHasPosesInClipboard;
1202 }
1203 
1204 
1205 inline void
1206 BPoseView::SetHasPosesInClipboard(bool hasPoses)
1207 {
1208 	fHasPosesInClipboard = hasPoses;
1209 }
1210 
1211 
1212 inline PoseList*
1213 BPoseView::CurrentPoseList() const
1214 {
1215 	return fFiltering ? fFilteredPoseList : fPoseList;
1216 }
1217 
1218 
1219 template<class Param1>
1220 void
1221 EachTextWidget(BPose* pose, BPoseView* poseView,
1222 	void (*func)(BTextWidget*, BPose*, BPoseView*, BColumn*, Param1), Param1 p1)
1223 {
1224 	for (int32 index = 0; ;index++) {
1225 		BColumn* column = poseView->ColumnAt(index);
1226 		if (!column)
1227 			break;
1228 
1229 		BTextWidget* widget = pose->WidgetFor(column->AttrHash());
1230 		if (widget)
1231 			(func)(widget, pose, poseView, column, p1);
1232 	}
1233 }
1234 
1235 
1236 template<class Param1, class Param2>
1237 void
1238 EachTextWidget(BPose* pose, BPoseView* poseView,
1239 	void (*func)(BTextWidget*, BPose*, BPoseView*, BColumn*,
1240 	Param1, Param2), Param1 p1, Param2 p2)
1241 {
1242 	for (int32 index = 0; ;index++) {
1243 		BColumn* column = poseView->ColumnAt(index);
1244 		if (!column)
1245 			break;
1246 
1247 		BTextWidget* widget = pose->WidgetFor(column->AttrHash());
1248 		if (widget)
1249 			(func)(widget, pose, poseView, column, p1, p2);
1250 	}
1251 }
1252 
1253 
1254 template<class Result, class Param1, class Param2>
1255 Result
1256 WhileEachTextWidget(BPose* pose, BPoseView* poseView,
1257 	Result (*func)(BTextWidget*, BPose*, BPoseView*, BColumn*,
1258 	Param1, Param2), Param1 p1, Param2 p2)
1259 {
1260 	for (int32 index = 0; ;index++) {
1261 		BColumn* column = poseView->ColumnAt(index);
1262 		if (!column)
1263 			break;
1264 
1265 		BTextWidget* widget = pose->WidgetFor(column->AttrHash());
1266 		if (widget) {
1267 			Result result = (func)(widget, pose, poseView, column, p1, p2);
1268 			if (result)
1269 				return result;
1270 		}
1271 	}
1272 	return 0;
1273 }
1274 
1275 
1276 } // namespace BPrivate
1277 
1278 using namespace BPrivate;
1279 
1280 #endif	// _POSE_VIEW_H
1281