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