xref: /haiku/src/kits/tracker/PoseView.h (revision b65adbdfbc322bb7d86d74049389c688e9962f15)
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 	void SetListElemHeight();
228 
229 	void SetIconPoseHeight();
230 	float IconPoseHeight() const;
231 	uint32 IconSizeInt() const;
232 	icon_size IconSize() const;
233 
234 	BRect Extent() const;
235 	void GetLayoutInfo(uint32 viewMode, BPoint* grid,
236 		BPoint* offset) const;
237 
238 	int32 CountItems() const;
239 	void UpdateCount();
240 
241 	rgb_color DeskTextColor() const;
242 	rgb_color DeskTextBackColor() const;
243 
244 	bool WidgetTextOutline() const;
245 	void SetWidgetTextOutline(bool);
246 		// used to not erase when we have a background image and
247 		// invalidate instead
248 
249 	void ScrollView(int32 type);
250 
251 	// column handling
252 	void ColumnRedraw(BRect updateRect);
253 	bool AddColumn(BColumn*, const BColumn* after = NULL);
254 	bool RemoveColumn(BColumn* column, bool runAlert);
255 	void MoveColumnTo(BColumn* src, BColumn* dest);
256 	bool ResizeColumnToWidest(BColumn* column);
257 	BPoint ResizeColumn(BColumn*, float, float* lastLineDrawPos = NULL,
258 		void (*drawLineFunc)(BPoseView*, BPoint, BPoint) = 0,
259 		void (*undrawLineFunc)(BPoseView*, BPoint, BPoint) = 0);
260 		// returns the bottom right of the last pose drawn or
261 		// the bottom right of bounds
262 
263 	BColumn* ColumnAt(int32 index) const;
264 	BColumn* ColumnFor(uint32 attribute_hash) const;
265 	BColumn* FirstColumn() const;
266 	BColumn* LastColumn() const;
267 	int32 IndexOfColumn(const BColumn*) const;
268 	int32 CountColumns() const;
269 
270 	// Where to start the first column
271 	float StartOffset() const;
272 
273 	// pose access
274 	int32 IndexOfPose(const BPose*) const;
275 	BPose* PoseAtIndex(int32 index) const;
276 
277 	BPose* FindPose(BPoint where, int32* index = NULL) const;
278 		// return pose at location h, v (search list starting from
279 		// bottom so drawing and hit detection reflect the same pose
280 		// ordering)
281 	BPose* FindPose(const Model*, int32* index = NULL) const;
282 	BPose* FindPose(const node_ref*, int32* index = NULL) const;
283 	BPose* FindPose(const entry_ref*, int32* index = NULL) const;
284 	BPose* FindPose(const entry_ref*, int32 specifierForm,
285 		int32* index) const;
286 		// special form of FindPose used for scripting,
287 		// <specifierForm> may ask for previous or next pose
288 	BPose* DeepFindPose(const node_ref* node, int32* index = NULL) const;
289 		// same as FindPose, node can be a target of the actual
290 		// pose if the pose is a symlink
291 	BPose* FirstVisiblePose(int32* _index = NULL) const;
292 	BPose* LastVisiblePose(int32* _index = NULL) const;
293 
294 	void OpenInfoWindows();
295 	void SetDefaultPrinter();
296 
297 	void IdentifySelection(bool force = false);
298 	void UnmountSelectedVolumes();
299 	virtual void OpenParent();
300 
301 	virtual void OpenSelection(BPose* clicked_pose = NULL,
302 		int32* index = NULL);
303 	void OpenSelectionUsing(BPose* clicked_pose = NULL,
304 		int32* index = NULL);
305 		// launches the open with window
306 	virtual void MoveSelectionTo(BPoint, BPoint, BContainerWindow*);
307 	void DuplicateSelection(BPoint* dropStart = NULL,
308 		BPoint* dropEnd = NULL);
309 
310 	// Move to trash calls try to select the next pose in the view
311 	// when they are dones
312 	virtual void MoveSelectionToTrash(bool selectNext = true);
313 	virtual void DeleteSelection(bool selectNext = true,
314 		bool askUser = true);
315 	virtual void MoveEntryToTrash(const entry_ref*,
316 		bool selectNext = true);
317 
318 	void RestoreSelectionFromTrash(bool selectNext = true);
319 
320 	// selection
321 	PoseList* SelectionList() const;
322 	void SelectAll();
323 	void InvertSelection();
324 	int32 SelectMatchingEntries(const BMessage*);
325 	void ShowSelectionWindow();
326 	void ClearSelection();
327 	void ShowSelection(bool);
328 	void AddRemovePoseFromSelection(BPose* pose, int32 index,
329 		bool select);
330 
331 	BLooper* SelectionHandler();
332 	void SetSelectionHandler(BLooper*);
333 
334 	BObjectList<BString>*MimeTypesInSelection();
335 
336 	// pose selection
337 	void SelectPose(BPose*, int32 index, bool scrollIntoView = true);
338 	void AddPoseToSelection(BPose*, int32 index,
339 		bool scrollIntoView = true);
340 	void RemovePoseFromSelection(BPose*);
341 	void SelectPoseAtLocation(BPoint);
342 	void SelectPoses(int32 start, int32 end);
343 	void MoveOrChangePoseSelection(int32 to);
344 
345 	// pose handling
346 	void ScrollIntoView(BPose* pose, int32 index);
347 	void ScrollIntoView(BRect poseRect);
348 	void SetActivePose(BPose*);
349 	BPose* ActivePose() const;
350 	void CommitActivePose(bool saveChanges = true);
351 	static bool PoseVisible(const Model*, const PoseInfo*);
352 	bool FrameForPose(BPose* targetPose, bool convert, BRect* poseRect);
353 	bool CreateSymlinkPoseTarget(Model* symlink);
354 		// used to complete a symlink pose; returns true if
355 		// target symlink should not be shown
356 	void ResetPosePlacementHint();
357 	void PlaceFolder(const entry_ref*, const BMessage*);
358 
359 	// clipboard handling for poses
360 	inline bool HasPosesInClipboard();
361 	inline void SetHasPosesInClipboard(bool hasPoses);
362 	void SetPosesClipboardMode(uint32 clipboardMode);
363 	void UpdatePosesClipboardModeFromClipboard(
364 		BMessage* clipboardReport = NULL);
365 
366 	// filtering
367 	void SetRefFilter(BRefFilter*);
368 	BRefFilter* RefFilter() const;
369 
370 	// access for mime types represented in the pose view
371 	void AddMimeType(const char* mimeType);
372 	const char* MimeTypeAt(int32 index);
373 	int32 CountMimeTypes();
374 	void RefreshMimeTypeList();
375 
376 	// drag&drop handling
377 	virtual bool HandleMessageDropped(BMessage*);
378 	static bool HandleDropCommon(BMessage* dragMessage, Model* target,
379 		BPose*, BView* view, BPoint dropPoint);
380 		// used by pose views and info windows
381 	static bool CanHandleDragSelection(const Model* target,
382 		const BMessage* dragMessage, bool ignoreTypes);
383 	virtual void DragSelectedPoses(const BPose* clickedPose, BPoint);
384 
385 	void MoveSelectionInto(Model* destFolder, BContainerWindow* srcWindow,
386 		bool forceCopy, bool forceMove = false, bool createLink = false,
387 		bool relativeLink = false);
388 	static void MoveSelectionInto(Model* destFolder,
389 		BContainerWindow* srcWindow, BContainerWindow* destWindow,
390 		uint32 buttons, BPoint loc, bool forceCopy,
391 		bool forceMove = false, bool createLink = false,
392 		bool relativeLink = false, BPoint clickPoint = BPoint(0, 0),
393 		bool pinToGrid = false);
394 
395 	bool UpdateDropTarget(BPoint, const BMessage*,
396 		bool trackingContextMenu);
397 		// return true if drop target changed
398 	void HiliteDropTarget(bool hiliteState);
399 
400 	void DragStop();
401 		// throw away cached up structures
402 
403 	static bool MenuTrackingHook(BMenu* menu, void* castToThis);
404 		// hook for spring loaded nav-menus
405 
406 	// scripting
407 	virtual BHandler* ResolveSpecifier(BMessage* message, int32 index,
408 		BMessage* specifier, int32 form, const char* property);
409 	virtual status_t GetSupportedSuites(BMessage*);
410 
411 	// string width calls that use local width caches, faster than using
412 	// the general purpose BView::StringWidth
413 	float StringWidth(const char*) const;
414 	float StringWidth(const char*, int32) const;
415 		// deliberately hide the BView StringWidth here - this makes it
416 		// easy to have the right StringWidth picked up by
417 		// template instantiation, as used by WidgetAttributeText
418 
419 	// show/hide barberpole while a background task is filling
420 	// up the view, etc.
421 	void ShowBarberPole();
422 	void HideBarberPole();
423 
424 	bool fShowSelectionWhenInactive;
425 	bool fTransparentSelection;
426 	bool fIsDrawingSelectionRect;
427 
428 	bool IsWatchingDateFormatChange();
429 	void StartWatchDateFormatChange();
430 	void StopWatchDateFormatChange();
431 
432 	// type ahead filtering
433 	bool IsFiltering() const;
434 
435 	void UpdateDateColumns(BMessage*);
436 	virtual void AdaptToVolumeChange(BMessage*);
437 	virtual void AdaptToDesktopIntegrationChange(BMessage*);
438 
439 	void SetTextWidgetToCheck(BTextWidget*, BTextWidget* = NULL);
440 
441 protected:
442 	// view setup
443 	virtual void SetUpDefaultColumnsIfNeeded();
444 
445 	virtual EntryListBase* InitDirentIterator(const entry_ref*);
446 		// sets up an entry iterator for _add_poses_
447 		// overriden by QueryPoseView, etc. to provide different iteration
448 	virtual void ReturnDirentIterator(EntryListBase* iterator);
449 		// returns the entry iterator after _add_poses_ is done
450 
451 	void Cleanup(bool doAll = false);
452 		// clean up poses
453 	void NewFolder(const BMessage*);
454 		// create a new folder, optionally specify a location
455 
456 	void NewFileFromTemplate(const BMessage*);
457 		// create a new file based on a template, optionally specify
458 		// a location
459 
460 	void ShowContextMenu(BPoint);
461 
462 	// scripting handlers
463 	virtual bool HandleScriptingMessage(BMessage* message);
464 	bool SetProperty(BMessage* message, BMessage* specifier, int32 form,
465 		const char* property, BMessage* reply);
466 	bool GetProperty(BMessage*, int32, const char*, BMessage*);
467 	bool CreateProperty(BMessage* message, BMessage* specifier, int32,
468 		const char*, BMessage* reply);
469 	bool ExecuteProperty(BMessage* specifier, int32, const char*,
470 		BMessage* reply);
471 	bool CountProperty(BMessage*, int32, const char*, BMessage*);
472 	bool DeleteProperty(BMessage*, int32, const char*, BMessage*);
473 
474 	void ClearPoses();
475 		// remove all the current poses from the view
476 
477 	// pose info read/write calls
478 	void ReadPoseInfo(Model*, PoseInfo*);
479 	ExtendedPoseInfo* ReadExtendedPoseInfo(Model*);
480 
481 	void _CheckPoseSortOrder(PoseList* list, BPose*, int32 index);
482 
483 	// pose creation
484 	BPose* EntryCreated(const node_ref*, const node_ref*, const char*,
485 		int32* index = 0);
486 
487 	void AddPoseToList(PoseList* list, bool visibleList,
488 		bool insertionSort, BPose* pose, BRect&viewBounds,
489 		float& listViewScrollBy, bool forceDraw, int32* indexPtr = NULL);
490 	BPose* CreatePose(Model*, PoseInfo*, bool insertionSort = true,
491 		int32* index = 0, BRect* boundsPointer = 0, bool forceDraw = true);
492 	virtual void CreatePoses(Model**models, PoseInfo* poseInfoArray,
493 		int32 count, BPose** resultingPoses, bool insertionSort = true,
494 		int32* lastPoseIndexPointer = 0, BRect* boundsPointer = 0,
495 		bool forceDraw = false);
496 	virtual bool ShouldShowPose(const Model*, const PoseInfo*);
497 		// filter, subclasses override to control which poses show up
498 		// subclasses should always call inherited
499 	void CreateVolumePose(BVolume*, bool watchIndividually);
500 
501 	void CreateTrashPose();
502 
503 	virtual bool AddPosesThreadValid(const entry_ref*) const;
504 		// verifies whether or not the current set of AddPoses threads
505 		// are valid and allowed to be adding poses -- returns false
506 		// in the case where the directory has been switched while
507 		// populating the view
508 
509 	virtual void AddPoses(Model* model = NULL);
510 		// if <model> is zero, PoseView has other means of iterating
511 		// through all the entries thaat it adds
512 
513 	virtual void AddRootPoses(bool watchIndividually, bool mountShared);
514 		// watchIndividually is used when placing a volume pose onto
515 		// the Desktop where unlike in the Root window it will not be
516 		// watched by the folder representing root. If set, each volume
517 		// will therefore be watched individually
518 	virtual void RemoveRootPoses();
519 	virtual void AddTrashPoses();
520 
521 	virtual bool DeletePose(const node_ref*, BPose* pose = NULL,
522 		int32 index = 0);
523 	virtual void DeleteSymLinkPoseTarget(const node_ref* itemNode,
524 		BPose* pose, int32 index);
525 		// the pose itself wasn't deleted but it's target node was - the
526 		// pose must be a symlink
527 	static void PoseHandleDeviceUnmounted(BPose* pose, Model* model,
528 		int32 index, BPoseView* poseView, dev_t device);
529 	static void RemoveNonBootDesktopModels(BPose*, Model* model, int32,
530 		BPoseView* poseView, dev_t);
531 
532 	// pose placement
533 	void CheckAutoPlacedPoses();
534 		// find poses that need placing and place them in a new spot
535 	void PlacePose(BPose*, BRect&);
536 		// find a new place for a pose, starting at fHintLocation
537 		// and place it
538 	bool IsValidLocation(const BPose* pose);
539 	bool IsValidLocation(const BRect& rect);
540 	status_t GetDeskbarFrame(BRect* frame);
541 	bool SlotOccupied(BRect poseRect, BRect viewBounds) const;
542 	void NextSlot(BPose*, BRect&poseRect, BRect viewBounds);
543 	void TrySettingPoseLocation(BNode* node, BPoint point);
544 	BPoint PinToGrid(BPoint, BPoint grid, BPoint offset) const;
545 
546 	// zombie pose handling
547 	Model* FindZombie(const node_ref*, int32* index = 0);
548 	BPose* ConvertZombieToPose(Model* zombie, int32 index);
549 
550 	// pose handling
551 	BRect CalcPoseRect(const BPose*, int32 index,
552 		bool firstColumnOnly = false) const;
553 	BRect CalcPoseRectIcon(const BPose*) const;
554 	BRect CalcPoseRectList(const BPose*, int32 index,
555 		bool firstColumnOnly = false) const;
556 	void DrawPose(BPose*, int32 index, bool fullDraw = true);
557 	void DrawViewCommon(const BRect&updateRect);
558 
559 	// pose list handling
560 	int32 BSearchList(PoseList* poseList, const BPose*, int32* index,
561 		int32 oldIndex);
562 	void InsertPoseAfter(BPose* pose, int32* index, int32 orientation,
563 		BRect* invalidRect);
564 		// does a CopyBits to scroll poses making room for a new pose,
565 		// returns rectangle that needs invalidating
566 	void CloseGapInList(BRect* invalidRect);
567 	int32 FirstIndexAtOrBelow(int32 y, bool constrainIndex = true) const;
568 	void AddToVSList(BPose*);
569 	int32 RemoveFromVSList(const BPose*);
570 	BPose* FindNearbyPose(char arrow, int32* index);
571 	BPose* FindBestMatch(int32* index);
572 	BPose* FindNextMatch(int32* index, bool reverse = false);
573 
574 	// node monitoring calls
575 	virtual void StartWatching();
576 	virtual void StopWatching();
577 
578 	status_t WatchNewNode(const node_ref* item);
579 		// the above would ideally be the only call of these three and
580 		// it would be a virtual, overriding the specific watch mask in
581 		// query pose view, etc. however we need to call WatchNewNode
582 		// from inside AddPosesTask while the window is unlocked - we
583 		// have to use the static and a cached messenger and masks.
584 	static status_t WatchNewNode(const node_ref*, uint32, BMessenger);
585 	virtual uint32 WatchNewNodeMask();
586 		// override to change different watch modes for query pose
587 		// view, etc.
588 
589 	// drag&drop handling
590 	static bool EachItemInDraggedSelection(const BMessage* message,
591 		bool (*)(BPose*, BPoseView*, void*), BPoseView* poseView,
592 		void* = NULL);
593 		// iterates through each pose in current selectiond in the source
594 		// window of the current drag message; locks the window
595 		// add const version
596 	BRect GetDragRect(int32 clickedPoseIndex);
597 	BBitmap* MakeDragBitmap(BRect dragRect, BPoint clickedPoint,
598 		int32 clickedPoseIndex, BPoint&offset);
599 	static bool FindDragNDropAction(const BMessage* dragMessage,
600 		bool&canCopy, bool&canMove, bool&canLink, bool&canErase);
601 
602 	static bool CanTrashForeignDrag(const Model*);
603 	static bool CanCopyOrMoveForeignDrag(const Model*, const BMessage*);
604 	static bool DragSelectionContains(const BPose* target,
605 		const BMessage* dragMessage);
606 	static status_t CreateClippingFile(BPoseView* poseView, BFile&result,
607 		char* resultingName, BDirectory* directory, BMessage* message,
608 		const char* fallbackName, bool setLocation = false,
609 		BPoint dropPoint = BPoint(0, 0));
610 
611 	// opening files, lanunching
612 	void OpenSelectionCommon(BPose*, int32*, bool);
613 		// used by OpenSelection and OpenSelectionUsing
614 	static void LaunchAppWithSelection(Model*, const BMessage*,
615 		bool checkTypes = true);
616 
617 	// node monitoring calls
618 	virtual bool EntryMoved(const BMessage*);
619 	virtual bool AttributeChanged(const BMessage*);
620 	virtual bool NoticeMetaMimeChanged(const BMessage*);
621 	virtual void MetaMimeChanged(const char*, const char*);
622 
623 	// click handling
624 	bool WasDoubleClick(const BPose*, BPoint point, int32 buttons);
625 	bool WasClickInPath(const BPose*, int32 index,
626 		BPoint mouseLocation) const;
627 
628 	// selection
629 	void SelectPosesListMode(BRect, BList**);
630 	void SelectPosesIconMode(BRect, BList**);
631 	void AddRemoveSelectionRange(BPoint where, bool extendSelection,
632 		BPose* pose);
633 
634 	void _BeginSelectionRect(const BPoint& point, bool extendSelection);
635 	void _UpdateSelectionRect(const BPoint& point);
636 	void _EndSelectionRect();
637 
638 	// view drawing
639 	void SynchronousUpdate(BRect, bool clip = false);
640 
641 	// scrolling
642 	void HandleAutoScroll();
643 	bool CheckAutoScroll(BPoint mouseLoc, bool shouldScroll);
644 
645 	// view extent handling
646 	void RecalcExtent();
647 	void AddToExtent(const BRect&);
648 	void ClearExtent();
649 	void RemoveFromExtent(const BRect&);
650 
651 	virtual void EditQueries();
652 
653 	void HandleAttrMenuItemSelected(BMessage*);
654 	void TryUpdatingBrokenLinks();
655 		// ran a little after a volume gets mounted
656 
657 	void MapToNewIconMode(BPose*, BPoint oldGrid, BPoint oldOffset);
658 	void ResetOrigin();
659 	void PinPointToValidRange(BPoint&);
660 		// used to ensure pose locations make sense after getting them
661 		// in pose info from attributes, etc.
662 
663 	void FinishPendingScroll(float&listViewScrollBy, BRect bounds);
664 		// utility call for CreatePoses
665 
666 	// background AddPoses task calls
667 	static status_t AddPosesTask(void*);
668 	virtual void AddPosesCompleted();
669 	bool IsValidAddPosesThread(thread_id) const;
670 
671 	// typeahead filtering
672 	void EnsurePoseUnselected(BPose* pose);
673 	void RemoveFilteredPose(BPose* pose, int32 index);
674 	void FilterChanged();
675 	void UpdateAfterFilterChange();
676 	bool FilterPose(BPose* pose);
677 	void StartFiltering();
678 	void StopFiltering();
679 	void ClearFilter();
680 	PoseList* CurrentPoseList() const;
681 
682 	// misc
683 	BList* GetDropPointList(BPoint dropPoint, BPoint startPoint,
684 		const PoseList*, bool sourceInListMode, bool dropOnGrid) const;
685 	void SendSelectionAsRefs(uint32 what, bool onlyQueries = false);
686 	void MoveListToTrash(BObjectList<entry_ref>*, bool selectNext,
687 		bool deleteDirectly);
688 	void Delete(BObjectList<entry_ref>*, bool selectNext, bool askUser);
689 	void Delete(const entry_ref&ref, bool selectNext, bool askUser);
690 	void RestoreItemsFromTrash(BObjectList<entry_ref>*, bool selectNext);
691 
692 	void WatchParentOf(const entry_ref*);
693 	void StopWatchingParentsOf(const entry_ref*);
694 
695 	void ExcludeTrashFromSelection();
696 
697 private:
698 	void DrawOpenAnimation(BRect);
699 
700 	void MoveSelectionOrEntryToTrash(const entry_ref* ref, bool selectNext);
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 void
869 BPoseView::SetListElemHeight()
870 {
871 	float extra = 0;
872 	if (IconSize() > B_MINI_ICON)
873 		extra = kLargeIconSeparator;
874 
875 	fListElemHeight = std::max((float)IconSize() + extra,
876 		ceilf(sFontHeight) < 20 ? 20 : ceilf(sFontHeight * 1.1f));
877 }
878 
879 
880 inline float
881 BPoseView::IconPoseHeight() const
882 {
883 	return fIconPoseHeight;
884 }
885 
886 
887 inline uint32
888 BPoseView::IconSizeInt() const
889 {
890 	return fViewState->IconSize();
891 }
892 
893 
894 inline icon_size
895 BPoseView::IconSize() const
896 {
897 	return (icon_size)fViewState->IconSize();
898 }
899 
900 
901 inline PoseList*
902 BPoseView::SelectionList() const
903 {
904 	return fSelectionList;
905 }
906 
907 
908 inline BObjectList<BString>*
909 BPoseView::MimeTypesInSelection()
910 {
911 	return &fMimeTypesInSelectionCache;
912 }
913 
914 
915 inline BScrollBar*
916 BPoseView::HScrollBar() const
917 {
918 	return fHScrollBar;
919 }
920 
921 
922 inline BScrollBar*
923 BPoseView::VScrollBar() const
924 {
925 	return fVScrollBar;
926 }
927 
928 
929 inline BCountView*
930 BPoseView::CountView() const
931 {
932 	return fCountView;
933 }
934 
935 
936 inline BTitleView*
937 BPoseView::TitleView() const
938 {
939 	return fTitleView;
940 }
941 
942 
943 inline bool
944 BPoseView::StateNeedsSaving()
945 {
946 	return fStateNeedsSaving || fViewState->StateNeedsSaving();
947 }
948 
949 
950 inline uint32
951 BPoseView::ViewMode() const
952 {
953 	return fViewState->ViewMode();
954 }
955 
956 
957 inline font_height
958 BPoseView::FontInfo() const
959 {
960 	return sFontInfo;
961 }
962 
963 
964 inline float
965 BPoseView::FontHeight() const
966 {
967 	return sFontHeight;
968 }
969 
970 
971 inline BPose*
972 BPoseView::ActivePose() const
973 {
974 	return fActivePose;
975 }
976 
977 
978 inline void
979 BPoseView::DisableSaveLocation()
980 {
981 	fSavePoseLocations = false;
982 }
983 
984 
985 inline bool
986 BPoseView::IsFilePanel() const
987 {
988 	return false;
989 }
990 
991 
992 inline bool
993 BPoseView::IsDesktopWindow() const
994 {
995 	return fIsDesktopWindow;
996 }
997 
998 
999 inline bool
1000 BPoseView::IsDesktopView() const
1001 {
1002 	return false;
1003 }
1004 
1005 
1006 inline uint32
1007 BPoseView::PrimarySort() const
1008 {
1009 	return fViewState->PrimarySort();
1010 }
1011 
1012 
1013 inline uint32
1014 BPoseView::PrimarySortType() const
1015 {
1016 	return fViewState->PrimarySortType();
1017 }
1018 
1019 
1020 inline uint32
1021 BPoseView::SecondarySort() const
1022 {
1023 	return fViewState->SecondarySort();
1024 }
1025 
1026 
1027 inline uint32
1028 BPoseView::SecondarySortType() const
1029 {
1030 	return fViewState->SecondarySortType();
1031 }
1032 
1033 
1034 inline bool
1035 BPoseView::ReverseSort() const
1036 {
1037 	return fViewState->ReverseSort();
1038 }
1039 
1040 
1041 inline void
1042 BPoseView::SetShowHideSelection(bool on)
1043 {
1044 	fShowHideSelection = on;
1045 }
1046 
1047 
1048 inline void
1049 BPoseView::SetIconMapping(bool on)
1050 {
1051 	fOkToMapIcons = on;
1052 }
1053 
1054 
1055 inline void
1056 BPoseView::AddToExtent(const BRect&rect)
1057 {
1058 	fExtent = fExtent | rect;
1059 }
1060 
1061 
1062 inline void
1063 BPoseView::ClearExtent()
1064 {
1065 	fExtent.Set(INT32_MAX, INT32_MAX, INT32_MIN, INT32_MIN);
1066 }
1067 
1068 
1069 inline int32
1070 BPoseView::CountColumns() const
1071 {
1072 	return fColumnList->CountItems();
1073 }
1074 
1075 
1076 inline float
1077 BPoseView::StartOffset() const
1078 {
1079 	return kListOffset + IconSizeInt() + kMiniIconSeparator + 1;
1080 }
1081 
1082 
1083 inline int32
1084 BPoseView::IndexOfColumn(const BColumn* column) const
1085 {
1086 	return fColumnList->IndexOf(const_cast<BColumn*>(column));
1087 }
1088 
1089 
1090 inline int32
1091 BPoseView::IndexOfPose(const BPose* pose) const
1092 {
1093 	return CurrentPoseList()->IndexOf(pose);
1094 }
1095 
1096 
1097 inline BPose*
1098 BPoseView::PoseAtIndex(int32 index) const
1099 {
1100 	return CurrentPoseList()->ItemAt(index);
1101 }
1102 
1103 
1104 inline BColumn*
1105 BPoseView::ColumnAt(int32 index) const
1106 {
1107 	return fColumnList->ItemAt(index);
1108 }
1109 
1110 
1111 inline BColumn*
1112 BPoseView::FirstColumn() const
1113 {
1114 	return fColumnList->FirstItem();
1115 }
1116 
1117 
1118 inline BColumn*
1119 BPoseView::LastColumn() const
1120 {
1121 	return fColumnList->LastItem();
1122 }
1123 
1124 
1125 inline int32
1126 BPoseView::CountItems() const
1127 {
1128 	return CurrentPoseList()->CountItems();
1129 }
1130 
1131 
1132 inline void
1133 BPoseView::SetMultipleSelection(bool state)
1134 {
1135 	fMultipleSelection = state;
1136 }
1137 
1138 
1139 inline void
1140 BPoseView::SetSelectionChangedHook(bool state)
1141 {
1142 	fSelectionChangedHook = state;
1143 }
1144 
1145 
1146 inline void
1147 BPoseView::SetAutoScroll(bool state)
1148 {
1149 	fShouldAutoScroll = state;
1150 }
1151 
1152 
1153 inline void
1154 BPoseView::SetPoseEditing(bool state)
1155 {
1156 	fAllowPoseEditing = state;
1157 }
1158 
1159 
1160 inline void
1161 BPoseView::SetDragEnabled(bool state)
1162 {
1163 	fDragEnabled = state;
1164 }
1165 
1166 
1167 inline void
1168 BPoseView::SetDropEnabled(bool state)
1169 {
1170 	fDropEnabled = state;
1171 }
1172 
1173 
1174 inline void
1175 BPoseView::SetSelectionRectEnabled(bool state)
1176 {
1177 	fSelectionRectEnabled = state;
1178 }
1179 
1180 
1181 inline void
1182 BPoseView::SetAlwaysAutoPlace(bool state)
1183 {
1184 	fAlwaysAutoPlace = state;
1185 }
1186 
1187 
1188 inline void
1189 BPoseView::SetEnsurePosesVisible(bool state)
1190 {
1191 	fEnsurePosesVisible = state;
1192 }
1193 
1194 
1195 inline void
1196 BPoseView::SetSelectionHandler(BLooper* looper)
1197 {
1198 	fSelectionHandler = looper;
1199 }
1200 
1201 
1202 inline void
1203 TScrollBar::SetTitleView(BView* view)
1204 {
1205 	fTitleView = view;
1206 }
1207 
1208 
1209 inline void
1210 BPoseView::SetRefFilter(BRefFilter* filter)
1211 {
1212 	fRefFilter = filter;
1213 	if (filter != NULL)
1214 		FilterChanged();
1215 }
1216 
1217 
1218 inline BRefFilter*
1219 BPoseView::RefFilter() const
1220 {
1221 	return fRefFilter;
1222 }
1223 
1224 
1225 inline BPose*
1226 BPoseView::FindPose(const Model* model, int32* index) const
1227 {
1228 	return CurrentPoseList()->FindPose(model, index);
1229 }
1230 
1231 
1232 inline BPose*
1233 BPoseView::FindPose(const node_ref* node, int32* index) const
1234 {
1235 	return CurrentPoseList()->FindPose(node, index);
1236 }
1237 
1238 
1239 inline BPose*
1240 BPoseView::FindPose(const entry_ref* entry, int32* index) const
1241 {
1242 	return CurrentPoseList()->FindPose(entry, index);
1243 }
1244 
1245 
1246 inline bool
1247 BPoseView::HasPosesInClipboard()
1248 {
1249 	return fHasPosesInClipboard;
1250 }
1251 
1252 
1253 inline void
1254 BPoseView::SetHasPosesInClipboard(bool hasPoses)
1255 {
1256 	fHasPosesInClipboard = hasPoses;
1257 }
1258 
1259 
1260 inline PoseList*
1261 BPoseView::CurrentPoseList() const
1262 {
1263 	return fFiltering ? fFilteredPoseList : fPoseList;
1264 }
1265 
1266 
1267 template<class Param1>
1268 void
1269 EachTextWidget(BPose* pose, BPoseView* poseView,
1270 	void (*func)(BTextWidget*, BPose*, BPoseView*, BColumn*, Param1), Param1 p1)
1271 {
1272 	for (int32 index = 0; ;index++) {
1273 		BColumn* column = poseView->ColumnAt(index);
1274 		if (column == NULL)
1275 			break;
1276 
1277 		BTextWidget* widget = pose->WidgetFor(column->AttrHash());
1278 		if (widget != NULL)
1279 			(func)(widget, pose, poseView, column, p1);
1280 	}
1281 }
1282 
1283 
1284 template<class Param1, class Param2>
1285 void
1286 EachTextWidget(BPose* pose, BPoseView* poseView,
1287 	void (*func)(BTextWidget*, BPose*, BPoseView*, BColumn*,
1288 	Param1, Param2), Param1 p1, Param2 p2)
1289 {
1290 	for (int32 index = 0; ;index++) {
1291 		BColumn* column = poseView->ColumnAt(index);
1292 		if (column == NULL)
1293 			break;
1294 
1295 		BTextWidget* widget = pose->WidgetFor(column->AttrHash());
1296 		if (widget != NULL)
1297 			(func)(widget, pose, poseView, column, p1, p2);
1298 	}
1299 }
1300 
1301 
1302 template<class Result, class Param1, class Param2>
1303 Result
1304 WhileEachTextWidget(BPose* pose, BPoseView* poseView,
1305 	Result (*func)(BTextWidget*, BPose*, BPoseView*, BColumn*,
1306 	Param1, Param2), Param1 p1, Param2 p2)
1307 {
1308 	for (int32 index = 0; ;index++) {
1309 		BColumn* column = poseView->ColumnAt(index);
1310 		if (column == NULL)
1311 			break;
1312 
1313 		BTextWidget* widget = pose->WidgetFor(column->AttrHash());
1314 		if (widget != NULL) {
1315 			Result result = (func)(widget, pose, poseView, column, p1, p2);
1316 			if (result != 0)
1317 				return result;
1318 		}
1319 	}
1320 
1321 	return 0;
1322 }
1323 
1324 
1325 } // namespace BPrivate
1326 
1327 using namespace BPrivate;
1328 
1329 
1330 #endif	// _POSE_VIEW_H
1331