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