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