xref: /haiku/src/kits/tracker/PoseView.h (revision 9a6a20d4689307142a7ed26a1437ba47e244e73f)
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 IsDesktopWindow() 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 	void UnmountSelectedVolumes();
274 	virtual void OpenParent();
275 
276 	virtual void OpenSelection(BPose* clicked_pose = NULL,
277 		int32* index = NULL);
278 	void OpenSelectionUsing(BPose* clicked_pose = NULL,
279 		int32* index = NULL);
280 		// launches the open with window
281 	virtual void MoveSelectionTo(BPoint, BPoint, BContainerWindow*);
282 	void DuplicateSelection(BPoint* dropStart = NULL,
283 		BPoint* dropEnd = NULL);
284 
285 	// Move to trash calls try to select the next pose in the view
286 	// when they are dones
287 	virtual void MoveSelectionToTrash(bool selectNext = true);
288 	virtual void DeleteSelection(bool selectNext = true, bool confirm = true);
289 	virtual void MoveEntryToTrash(const entry_ref*,
290 		bool selectNext = true);
291 
292 	void RestoreSelectionFromTrash(bool selectNext = true);
293 
294 	// selection
295 	PoseList* SelectionList() const;
296 	void SelectAll();
297 	void InvertSelection();
298 	int32 SelectMatchingEntries(const BMessage*);
299 	void ShowSelectionWindow();
300 	void ClearSelection();
301 	void ShowSelection(bool);
302 	void AddRemovePoseFromSelection(BPose* pose, int32 index,
303 		bool select);
304 	int32 CountSelected() const;
305 	bool SelectedVolumeIsReadOnly() const;
306 	bool TargetVolumeIsReadOnly() const;
307 	bool CanEditName() const;
308 	bool CanMoveToTrashOrDuplicate() const;
309 
310 	void SetSelectionHandler(BLooper* looper);
311 
312 	BObjectList<BString>*MimeTypesInSelection();
313 
314 	// pose selection
315 	void SelectPose(BPose*, int32 index, bool scrollIntoView = true);
316 	void AddPoseToSelection(BPose*, int32 index,
317 		bool scrollIntoView = true);
318 	void RemovePoseFromSelection(BPose*);
319 	void SelectPoseAtLocation(BPoint);
320 	void SelectPoses(int32 start, int32 end);
321 	void MoveOrChangePoseSelection(int32 to);
322 
323 	// pose handling
324 	void ScrollIntoView(BPose* pose, int32 index);
325 	void ScrollIntoView(BRect poseRect);
326 	void SetActivePose(BPose*);
327 	BPose* ActivePose() const;
328 	void CommitActivePose(bool saveChanges = true);
329 	static bool PoseVisible(const Model*, const PoseInfo*);
330 	bool FrameForPose(BPose* targetPose, bool convert, BRect* poseRect);
331 	bool CreateSymlinkPoseTarget(Model* symlink);
332 		// used to complete a symlink pose; returns true if
333 		// target symlink should not be shown
334 	void ResetPosePlacementHint();
335 	void PlaceFolder(const entry_ref*, const BMessage*);
336 
337 	// clipboard handling for poses
338 	inline bool HasPosesInClipboard();
339 	inline void SetHasPosesInClipboard(bool hasPoses);
340 	void SetPosesClipboardMode(uint32 clipboardMode);
341 	void UpdatePosesClipboardModeFromClipboard(
342 		BMessage* clipboardReport = NULL);
343 
344 	// filtering
345 	void SetRefFilter(BRefFilter*);
346 	BRefFilter* RefFilter() const;
347 
348 	// access for mime types represented in the pose view
349 	void AddMimeType(const char* mimeType);
350 	const char* MimeTypeAt(int32 index);
351 	int32 CountMimeTypes();
352 	void RefreshMimeTypeList();
353 
354 	// drag&drop handling
355 	virtual bool HandleMessageDropped(BMessage*);
356 	static bool HandleDropCommon(BMessage* dragMessage, Model* target,
357 		BPose*, BView* view, BPoint dropPoint);
358 		// used by pose views and info windows
359 	static bool CanHandleDragSelection(const Model* target,
360 		const BMessage* dragMessage, bool ignoreTypes);
361 	virtual void DragSelectedPoses(const BPose* clickedPose, BPoint);
362 
363 	void MoveSelectionInto(Model* destFolder, BContainerWindow* srcWindow,
364 		bool forceCopy, bool forceMove = false, bool createLink = false,
365 		bool relativeLink = false);
366 	static void MoveSelectionInto(Model* destFolder,
367 		BContainerWindow* srcWindow, BContainerWindow* destWindow,
368 		uint32 buttons, BPoint loc, bool forceCopy,
369 		bool forceMove = false, bool createLink = false,
370 		bool relativeLink = false, BPoint clickPoint = BPoint(0, 0),
371 		bool pinToGrid = false);
372 
373 	bool UpdateDropTarget(BPoint, const BMessage*,
374 		bool trackingContextMenu);
375 		// return true if drop target changed
376 	void HiliteDropTarget(bool hiliteState);
377 
378 	void DragStop();
379 		// throw away cached up structures
380 
381 	static bool MenuTrackingHook(BMenu* menu, void* castToThis);
382 		// hook for spring loaded nav-menus
383 
384 	// scripting
385 	virtual BHandler* ResolveSpecifier(BMessage* message, int32 index,
386 		BMessage* specifier, int32 form, const char* property);
387 	virtual status_t GetSupportedSuites(BMessage*);
388 
389 	// string width calls that use local width caches, faster than using
390 	// the general purpose BView::StringWidth
391 	float StringWidth(const char*) const;
392 	float StringWidth(const char*, int32) const;
393 		// deliberately hide the BView StringWidth here - this makes it
394 		// easy to have the right StringWidth picked up by
395 		// template instantiation, as used by WidgetAttributeText
396 
397 	// show/hide barberpole while a background task is filling
398 	// up the view, etc.
399 	void ShowBarberPole();
400 	void HideBarberPole();
401 
402 	bool fShowSelectionWhenInactive;
403 	bool fIsDrawingSelectionRect;
404 
405 	bool IsWatchingDateFormatChange();
406 	void StartWatchDateFormatChange();
407 	void StopWatchDateFormatChange();
408 
409 	// type ahead filtering
410 	bool IsFiltering() const;
411 
412 	void UpdateDateColumns(BMessage*);
413 	virtual void AdaptToVolumeChange(BMessage*);
414 	virtual void AdaptToDesktopIntegrationChange(BMessage*);
415 
416 	void SetTextWidgetToCheck(BTextWidget*, BTextWidget* = NULL);
417 
418 	BTextWidget* ActiveTextWidget() { return fActiveTextWidget; };
419 	void SetActiveTextWidget(BTextWidget* w) { fActiveTextWidget = w; };
420 
421 protected:
422 	// view setup
423 	virtual void SetupDefaultColumnsIfNeeded();
424 
425 	virtual EntryListBase* InitDirentIterator(const entry_ref*);
426 		// sets up an entry iterator for _add_poses_
427 		// overriden by QueryPoseView, etc. to provide different iteration
428 	virtual void ReturnDirentIterator(EntryListBase* iterator);
429 		// returns the entry iterator after _add_poses_ is done
430 
431 	void Cleanup(bool doAll = false);
432 		// clean up poses
433 	void NewFolder(const BMessage*);
434 		// create a new folder, optionally specify a location
435 
436 	void NewFileFromTemplate(const BMessage*);
437 		// create a new file based on a template, optionally specify
438 		// a location
439 
440 	void ShowContextMenu(BPoint);
441 
442 	// scripting handlers
443 	virtual bool HandleScriptingMessage(BMessage* message);
444 	bool SetProperty(BMessage* message, BMessage* specifier, int32 form,
445 		const char* property, BMessage* reply);
446 	bool GetProperty(BMessage*, int32, const char*, BMessage*);
447 	bool CreateProperty(BMessage* message, BMessage* specifier, int32,
448 		const char*, BMessage* reply);
449 	bool ExecuteProperty(BMessage* specifier, int32, const char*,
450 		BMessage* reply);
451 	bool CountProperty(BMessage*, int32, const char*, BMessage*);
452 	bool DeleteProperty(BMessage*, int32, const char*, BMessage*);
453 
454 	void ClearPoses();
455 		// remove all the current poses from the view
456 
457 	// pose info read/write calls
458 	void ReadPoseInfo(Model*, PoseInfo*);
459 	ExtendedPoseInfo* ReadExtendedPoseInfo(Model*);
460 
461 	void _CheckPoseSortOrder(PoseList* list, BPose*, int32 index);
462 
463 	// pose creation
464 	BPose* EntryCreated(const node_ref*, const node_ref*, const char*,
465 		int32* index = 0);
466 
467 	void AddPoseToList(PoseList* list, bool visibleList,
468 		bool insertionSort, BPose* pose, BRect&viewBounds,
469 		float& listViewScrollBy, bool forceDraw, int32* indexPtr = NULL);
470 	BPose* CreatePose(Model*, PoseInfo*, bool insertionSort = true,
471 		int32* index = 0, BRect* boundsPointer = 0, bool forceDraw = true);
472 	virtual void CreatePoses(Model**models, PoseInfo* poseInfoArray,
473 		int32 count, BPose** resultingPoses, bool insertionSort = true,
474 		int32* lastPoseIndexPointer = 0, BRect* boundsPointer = 0,
475 		bool forceDraw = false);
476 	virtual bool ShouldShowPose(const Model*, const PoseInfo*);
477 		// filter, subclasses override to control which poses show up
478 		// subclasses should always call inherited
479 	void CreateVolumePose(BVolume*, bool watchIndividually);
480 
481 	void CreateTrashPose();
482 
483 	virtual bool AddPosesThreadValid(const entry_ref*) const;
484 		// verifies whether or not the current set of AddPoses threads
485 		// are valid and allowed to be adding poses -- returns false
486 		// in the case where the directory has been switched while
487 		// populating the view
488 
489 	virtual void AddPoses(Model* model = NULL);
490 		// if <model> is zero, PoseView has other means of iterating
491 		// through all the entries thaat it adds
492 
493 	virtual void AddRootPoses(bool watchIndividually, bool mountShared);
494 		// watchIndividually is used when placing a volume pose onto
495 		// the Desktop where unlike in the Root window it will not be
496 		// watched by the folder representing root. If set, each volume
497 		// will therefore be watched individually
498 	virtual void RemoveRootPoses();
499 	virtual void AddTrashPoses();
500 
501 	virtual bool DeletePose(const node_ref*, BPose* pose = NULL,
502 		int32 index = 0);
503 	virtual void DeleteSymLinkPoseTarget(const node_ref* itemNode,
504 		BPose* pose, int32 index);
505 		// the pose itself wasn't deleted but it's target node was - the
506 		// pose must be a symlink
507 	static void PoseHandleDeviceUnmounted(BPose* pose, Model* model,
508 		int32 index, BPoseView* poseView, dev_t device);
509 	static void RemoveNonBootDesktopModels(BPose*, Model* model, int32,
510 		BPoseView* poseView, dev_t);
511 
512 	// pose placement
513 	void CheckAutoPlacedPoses();
514 		// find poses that need placing and place them in a new spot
515 	void PlacePose(BPose*, BRect&);
516 		// find a new place for a pose, starting at fHintLocation
517 		// and place it
518 	bool IsValidLocation(const BPose* pose);
519 	bool IsValidLocation(const BRect& rect);
520 	status_t GetDeskbarFrame(BRect* frame);
521 	bool SlotOccupied(BRect poseRect, BRect viewBounds) const;
522 	void NextSlot(BPose*, BRect&poseRect, BRect viewBounds);
523 	void TrySettingPoseLocation(BNode* node, BPoint point);
524 	BPoint PinToGrid(BPoint, BPoint grid, BPoint offset) const;
525 
526 	// zombie pose handling
527 	Model* FindZombie(const node_ref*, int32* index = 0);
528 	BPose* ConvertZombieToPose(Model* zombie, int32 index);
529 
530 	// pose handling
531 	BRect CalcPoseRect(const BPose*, int32 index,
532 		bool firstColumnOnly = false) const;
533 	BRect CalcPoseRectIcon(const BPose*) const;
534 	BRect CalcPoseRectList(const BPose*, int32 index,
535 		bool firstColumnOnly = false) const;
536 	void DrawPose(BPose*, int32 index, bool fullDraw = true);
537 	void DrawViewCommon(const BRect&updateRect);
538 
539 	// pose list handling
540 	int32 BSearchList(PoseList* poseList, const BPose*, int32* index,
541 		int32 oldIndex);
542 	void InsertPoseAfter(BPose* pose, int32* index, int32 orientation,
543 		BRect* invalidRect);
544 		// does a CopyBits to scroll poses making room for a new pose,
545 		// returns rectangle that needs invalidating
546 	void CloseGapInList(BRect* invalidRect);
547 	int32 FirstIndexAtOrBelow(int32 y, bool constrainIndex = true) const;
548 	void AddToVSList(BPose*);
549 	int32 RemoveFromVSList(const BPose*);
550 	BPose* FindNearbyPose(char arrow, int32* index);
551 	BPose* FindBestMatch(int32* index);
552 	BPose* FindNextMatch(int32* index, bool reverse = false);
553 
554 	// node monitoring calls
555 	virtual void StartWatching();
556 	virtual void StopWatching();
557 
558 	status_t WatchNewNode(const node_ref* item);
559 		// the above would ideally be the only call of these three and
560 		// it would be a virtual, overriding the specific watch mask in
561 		// query pose view, etc. however we need to call WatchNewNode
562 		// from inside AddPosesTask while the window is unlocked - we
563 		// have to use the static and a cached messenger and masks.
564 	static status_t WatchNewNode(const node_ref*, uint32, BMessenger);
565 	virtual uint32 WatchNewNodeMask();
566 		// override to change different watch modes for query pose
567 		// view, etc.
568 
569 	// drag&drop handling
570 	static bool EachItemInDraggedSelection(const BMessage* message,
571 		bool (*)(BPose*, BPoseView*, void*), BPoseView* poseView,
572 		void* = NULL);
573 		// iterates through each pose in current selectiond in the source
574 		// window of the current drag message; locks the window
575 		// add const version
576 	BRect GetDragRect(int32 clickedPoseIndex);
577 	BBitmap* MakeDragBitmap(BRect dragRect, BPoint clickedPoint,
578 		int32 clickedPoseIndex, BPoint&offset);
579 	static bool FindDragNDropAction(const BMessage* dragMessage,
580 		bool&canCopy, bool&canMove, bool&canLink, bool&canErase);
581 
582 	static bool CanTrashForeignDrag(const Model*);
583 	static bool CanCopyOrMoveForeignDrag(const Model*, const BMessage*);
584 	static bool DragSelectionContains(const BPose* target,
585 		const BMessage* dragMessage);
586 	static status_t CreateClippingFile(BPoseView* poseView, BFile&result,
587 		char* resultingName, BDirectory* directory, BMessage* message,
588 		const char* fallbackName, bool setLocation = false,
589 		BPoint dropPoint = BPoint(0, 0));
590 
591 	// opening files, lanunching
592 	void OpenSelectionCommon(BPose*, int32*, bool);
593 		// used by OpenSelection and OpenSelectionUsing
594 	static void LaunchAppWithSelection(Model*, const BMessage*,
595 		bool checkTypes = true);
596 
597 	// node monitoring calls
598 	virtual bool EntryMoved(const BMessage*);
599 	virtual bool AttributeChanged(const BMessage*);
600 	virtual bool NoticeMetaMimeChanged(const BMessage*);
601 	virtual void MetaMimeChanged(const char*, const char*);
602 
603 	// click handling
604 	bool WasDoubleClick(const BPose*, BPoint point, int32 buttons);
605 	bool WasClickInPath(const BPose*, int32 index,
606 		BPoint mouseLocation) const;
607 
608 	// selection
609 	void SelectPoses(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 confirm);
668 	void Delete(const entry_ref&ref, bool selectNext, bool confirm);
669 	void RestoreItemsFromTrash(BObjectList<entry_ref>*, bool selectNext);
670 	void DoDelete();
671 	void DoMoveToTrash();
672 
673 	void WatchParentOf(const entry_ref*);
674 	void StopWatchingParentsOf(const entry_ref*);
675 
676 	void ExcludeTrashFromSelection();
677 
678 private:
679 	void DrawOpenAnimation(BRect);
680 	void ApplyBackgroundColor();
681 
682 	void MoveSelectionOrEntryToTrash(const entry_ref* ref, bool selectNext);
683 
684 protected:
685 	struct node_ref_key {
686 		node_ref_key() {}
687 		node_ref_key(const node_ref& value) : value(value) {}
688 
689 		uint32 GetHashCode() const
690 		{
691 			return (uint32)value.device ^ (uint32)value.node;
692 		}
693 
694 		node_ref_key operator=(const node_ref_key& other)
695 		{
696 			value = other.value;
697 			return *this;
698 		}
699 
700 		bool operator==(const node_ref_key& other) const
701 		{
702 			return (value == other.value);
703 		}
704 
705 		bool operator!=(const node_ref_key& other) const
706 		{
707 			return (value != other.value);
708 		}
709 
710 		node_ref	value;
711 	};
712 
713 protected:
714 	BViewState* fViewState;
715 	bool fStateNeedsSaving;
716 
717 	bool fSavePoseLocations : 1;
718 	bool fMultipleSelection : 1;
719 	bool fDragEnabled : 1;
720 	bool fDropEnabled : 1;
721 
722 	BLooper* fSelectionHandler;
723 
724 	std::set<thread_id> fAddPosesThreads;
725 	PoseList* fPoseList;
726 
727 	PendingNodeMonitorCache pendingNodeMonitorCache;
728 
729 private:
730 	TScrollBar* fHScrollBar;
731 	BScrollBar* fVScrollBar;
732 	Model* fModel;
733 	BPose* fActivePose;
734 	BRect fExtent;
735 	// the following should probably be just member lists, not pointers
736 	PoseList* fFilteredPoseList;
737 	PoseList* fVSPoseList;
738 	PoseList* fSelectionList;
739 	HashSet<node_ref_key> fInsertedNodes;
740 	BObjectList<BString> fMimeTypesInSelectionCache;
741 		// used for mime string based icon highliting during a drag
742 	BObjectList<Model>* fZombieList;
743 	BObjectList<BColumn>* fColumnList;
744 	BObjectList<BString>* fMimeTypeList;
745 	BObjectList<Model>* fBrokenLinks;
746 	bool fMimeTypeListIsDirty;
747 	BCountView* fCountView;
748 	float fListElemHeight;
749 	float fListOffset;
750 	float fIconPoseHeight;
751 	BPose* fDropTarget;
752 	BPose* fAlreadySelectedDropTarget;
753 	BPoint fLastClickPoint;
754 	int32 fLastClickButtons;
755 	const BPose* fLastClickedPose;
756 	BPoint fLastLeftTop;
757 	BRect fLastExtent;
758 	BTitleView* fTitleView;
759 	BRefFilter* fRefFilter;
760 	BPoint fGrid;
761 	BPoint fOffset;
762 	BPoint fHintLocation;
763 	float fAutoScrollInc;
764 	int32 fAutoScrollState;
765 	bool fWidgetTextOutline;
766 	const BPose* fSelectionPivotPose;
767 	const BPose* fRealPivotPose;
768 	BMessageRunner* fKeyRunner;
769 	bool fTrackRightMouseUp;
770 	bool fTrackMouseUp;
771 
772 	struct SelectionRectInfo {
773 		SelectionRectInfo()
774 			:
775 			isDragging(false),
776 			selection(NULL)
777 		{
778 		}
779 
780 		bool isDragging;
781 		BRect rect;
782 		BRect lastRect;
783 		BPoint startPoint;
784 		BPoint lastPoint;
785 		BList* selection;
786 	};
787 	SelectionRectInfo fSelectionRectInfo;
788 
789 	bool fSelectionVisible : 1;
790 	bool fSelectionRectEnabled : 1;
791 	bool fTransparentSelection : 1;
792 	bool fAlwaysAutoPlace : 1;
793 	bool fAllowPoseEditing : 1;
794 	bool fSelectionChangedHook : 1;
795 		// get rid of this
796 	bool fOkToMapIcons : 1;
797 	bool fEnsurePosesVisible : 1;
798 	bool fShouldAutoScroll : 1;
799 	bool fIsDesktopWindow : 1;
800 	bool fIsWatchingDateFormatChange : 1;
801 	bool fHasPosesInClipboard : 1;
802 	bool fCursorCheck : 1;
803 	bool fFiltering : 1;
804 
805 	BObjectList<BString> fFilterStrings;
806 	int32 fLastFilterStringCount;
807 	int32 fLastFilterStringLength;
808 
809 	BRect fStartFrame;
810 
811 	static float sFontHeight;
812 	static font_height sFontInfo;
813 	static BString sMatchString;
814 		// used for typeahead - should be replaced by a typeahead state
815 
816 	bigtime_t fLastKeyTime;
817 	bigtime_t fLastDeskbarFrameCheckTime;
818 	BRect fDeskbarFrame;
819 
820 	static OffscreenBitmap* sOffscreen;
821 
822 	BTextWidget* fTextWidgetToCheck;
823 	BTextWidget* fActiveTextWidget;
824 
825 private:
826 	mutable uint32 fCachedIconSizeFrom;
827 	mutable BSize fCachedIconSize;
828 
829 	typedef BView _inherited;
830 };
831 
832 
833 class TScrollBar : public BScrollBar {
834 public:
835 	TScrollBar(const char*, BView*, float, float);
836 	void SetTitleView(BView*);
837 
838 	// BScrollBar overrides
839 	virtual	void ValueChanged(float);
840 
841 private:
842 	BView* fTitleView;
843 
844 	typedef BScrollBar _inherited;
845 };
846 
847 
848 class TPoseViewFilter : public BMessageFilter {
849 public:
850 	TPoseViewFilter(BPoseView* pose);
851 	~TPoseViewFilter();
852 
853 	filter_result Filter(BMessage*, BHandler**);
854 
855 private:
856 	filter_result ObjectDropFilter(BMessage*, BHandler**);
857 
858 	BPoseView* fPoseView;
859 };
860 
861 
862 extern bool
863 ClearViewOriginOne(const char* name, uint32 type, off_t size, void* data,
864 	void* params);
865 
866 
867 // inlines follow
868 
869 
870 inline BContainerWindow*
871 BPoseView::ContainerWindow() const
872 {
873 	return dynamic_cast<BContainerWindow*>(Window());
874 }
875 
876 
877 inline Model*
878 BPoseView::TargetModel() const
879 {
880 	return fModel;
881 }
882 
883 
884 inline float
885 BPoseView::ListElemHeight() const
886 {
887 	return fListElemHeight;
888 }
889 
890 
891 inline float
892 BPoseView::ListOffset() const
893 {
894 	return fListOffset;
895 }
896 
897 
898 inline float
899 BPoseView::IconPoseHeight() const
900 {
901 	return fIconPoseHeight;
902 }
903 
904 
905 inline uint32
906 BPoseView::UnscaledIconSizeInt() const
907 {
908 	return fViewState->IconSize();
909 }
910 
911 
912 inline uint32
913 BPoseView::IconSizeInt() const
914 {
915 	return IconSize().IntegerWidth() + 1;
916 }
917 
918 
919 inline PoseList*
920 BPoseView::SelectionList() const
921 {
922 	return fSelectionList;
923 }
924 
925 inline int32
926 BPoseView::CountSelected() const
927 {
928 	return fSelectionList->CountItems();
929 }
930 
931 inline BObjectList<BString>*
932 BPoseView::MimeTypesInSelection()
933 {
934 	return &fMimeTypesInSelectionCache;
935 }
936 
937 
938 inline BScrollBar*
939 BPoseView::HScrollBar() const
940 {
941 	return fHScrollBar;
942 }
943 
944 
945 inline BScrollBar*
946 BPoseView::VScrollBar() const
947 {
948 	return fVScrollBar;
949 }
950 
951 
952 inline BCountView*
953 BPoseView::CountView() const
954 {
955 	return fCountView;
956 }
957 
958 
959 inline BTitleView*
960 BPoseView::TitleView() const
961 {
962 	return fTitleView;
963 }
964 
965 
966 inline bool
967 BPoseView::StateNeedsSaving()
968 {
969 	return fStateNeedsSaving || fViewState->StateNeedsSaving();
970 }
971 
972 
973 inline uint32
974 BPoseView::ViewMode() const
975 {
976 	return fViewState->ViewMode();
977 }
978 
979 
980 inline font_height
981 BPoseView::FontInfo() const
982 {
983 	return sFontInfo;
984 }
985 
986 
987 inline float
988 BPoseView::FontHeight() const
989 {
990 	return sFontHeight;
991 }
992 
993 
994 inline BPose*
995 BPoseView::ActivePose() const
996 {
997 	return fActivePose;
998 }
999 
1000 
1001 inline void
1002 BPoseView::DisableSaveLocation()
1003 {
1004 	fSavePoseLocations = false;
1005 }
1006 
1007 
1008 inline bool
1009 BPoseView::IsFilePanel() const
1010 {
1011 	return false;
1012 }
1013 
1014 
1015 inline bool
1016 BPoseView::IsDesktopWindow() const
1017 {
1018 	return fIsDesktopWindow;
1019 }
1020 
1021 
1022 inline bool
1023 BPoseView::IsDesktopView() const
1024 {
1025 	return false;
1026 }
1027 
1028 
1029 inline uint32
1030 BPoseView::PrimarySort() const
1031 {
1032 	return fViewState->PrimarySort();
1033 }
1034 
1035 
1036 inline uint32
1037 BPoseView::PrimarySortType() const
1038 {
1039 	return fViewState->PrimarySortType();
1040 }
1041 
1042 
1043 inline uint32
1044 BPoseView::SecondarySort() const
1045 {
1046 	return fViewState->SecondarySort();
1047 }
1048 
1049 
1050 inline uint32
1051 BPoseView::SecondarySortType() const
1052 {
1053 	return fViewState->SecondarySortType();
1054 }
1055 
1056 
1057 inline bool
1058 BPoseView::ReverseSort() const
1059 {
1060 	return fViewState->ReverseSort();
1061 }
1062 
1063 
1064 inline void
1065 BPoseView::SetIconMapping(bool on)
1066 {
1067 	fOkToMapIcons = on;
1068 }
1069 
1070 
1071 inline void
1072 BPoseView::AddToExtent(const BRect&rect)
1073 {
1074 	fExtent = fExtent | rect;
1075 }
1076 
1077 
1078 inline void
1079 BPoseView::ClearExtent()
1080 {
1081 	fExtent.Set(INT32_MAX, INT32_MAX, INT32_MIN, INT32_MIN);
1082 }
1083 
1084 
1085 inline int32
1086 BPoseView::CountColumns() const
1087 {
1088 	return fColumnList->CountItems();
1089 }
1090 
1091 
1092 inline float
1093 BPoseView::StartOffset() const
1094 {
1095 	return fListOffset + ListIconSize() + kMiniIconSeparator + 1;
1096 }
1097 
1098 
1099 inline int32
1100 BPoseView::IndexOfColumn(const BColumn* column) const
1101 {
1102 	return fColumnList->IndexOf(const_cast<BColumn*>(column));
1103 }
1104 
1105 
1106 inline int32
1107 BPoseView::IndexOfPose(const BPose* pose) const
1108 {
1109 	return CurrentPoseList()->IndexOf(pose);
1110 }
1111 
1112 
1113 inline BPose*
1114 BPoseView::PoseAtIndex(int32 index) const
1115 {
1116 	return CurrentPoseList()->ItemAt(index);
1117 }
1118 
1119 
1120 inline BColumn*
1121 BPoseView::ColumnAt(int32 index) const
1122 {
1123 	return fColumnList->ItemAt(index);
1124 }
1125 
1126 
1127 inline BColumn*
1128 BPoseView::FirstColumn() const
1129 {
1130 	return fColumnList->FirstItem();
1131 }
1132 
1133 
1134 inline BColumn*
1135 BPoseView::LastColumn() const
1136 {
1137 	return fColumnList->LastItem();
1138 }
1139 
1140 
1141 inline int32
1142 BPoseView::CountItems() const
1143 {
1144 	return CurrentPoseList()->CountItems();
1145 }
1146 
1147 
1148 inline void
1149 BPoseView::SetMultipleSelection(bool state)
1150 {
1151 	fMultipleSelection = state;
1152 }
1153 
1154 
1155 inline void
1156 BPoseView::SetSelectionChangedHook(bool state)
1157 {
1158 	fSelectionChangedHook = state;
1159 }
1160 
1161 
1162 inline void
1163 BPoseView::SetAutoScroll(bool state)
1164 {
1165 	fShouldAutoScroll = state;
1166 }
1167 
1168 
1169 inline void
1170 BPoseView::SetPoseEditing(bool state)
1171 {
1172 	fAllowPoseEditing = state;
1173 }
1174 
1175 
1176 inline void
1177 BPoseView::SetDragEnabled(bool state)
1178 {
1179 	fDragEnabled = state;
1180 }
1181 
1182 
1183 inline void
1184 BPoseView::SetDropEnabled(bool state)
1185 {
1186 	fDropEnabled = state;
1187 }
1188 
1189 
1190 inline void
1191 BPoseView::SetSelectionRectEnabled(bool state)
1192 {
1193 	fSelectionRectEnabled = state;
1194 }
1195 
1196 
1197 inline void
1198 BPoseView::SetAlwaysAutoPlace(bool state)
1199 {
1200 	fAlwaysAutoPlace = state;
1201 }
1202 
1203 
1204 inline void
1205 BPoseView::SetEnsurePosesVisible(bool state)
1206 {
1207 	fEnsurePosesVisible = state;
1208 }
1209 
1210 
1211 inline void
1212 BPoseView::SetSelectionHandler(BLooper* looper)
1213 {
1214 	fSelectionHandler = looper;
1215 }
1216 
1217 
1218 inline void
1219 TScrollBar::SetTitleView(BView* view)
1220 {
1221 	fTitleView = view;
1222 }
1223 
1224 
1225 inline void
1226 BPoseView::SetRefFilter(BRefFilter* filter)
1227 {
1228 	fRefFilter = filter;
1229 	if (filter != NULL)
1230 		FilterChanged();
1231 }
1232 
1233 
1234 inline BRefFilter*
1235 BPoseView::RefFilter() const
1236 {
1237 	return fRefFilter;
1238 }
1239 
1240 
1241 inline BPose*
1242 BPoseView::FindPose(const Model* model, int32* index) const
1243 {
1244 	return CurrentPoseList()->FindPose(model, index);
1245 }
1246 
1247 
1248 inline BPose*
1249 BPoseView::FindPose(const node_ref* node, int32* index) const
1250 {
1251 	return CurrentPoseList()->FindPose(node, index);
1252 }
1253 
1254 
1255 inline BPose*
1256 BPoseView::FindPose(const entry_ref* entry, int32* index) const
1257 {
1258 	return CurrentPoseList()->FindPose(entry, index);
1259 }
1260 
1261 
1262 inline bool
1263 BPoseView::HasPosesInClipboard()
1264 {
1265 	return fHasPosesInClipboard;
1266 }
1267 
1268 
1269 inline void
1270 BPoseView::SetHasPosesInClipboard(bool hasPoses)
1271 {
1272 	fHasPosesInClipboard = hasPoses;
1273 }
1274 
1275 
1276 inline PoseList*
1277 BPoseView::CurrentPoseList() const
1278 {
1279 	return fFiltering ? fFilteredPoseList : fPoseList;
1280 }
1281 
1282 
1283 template<class Param1>
1284 void
1285 EachTextWidget(BPose* pose, BPoseView* poseView,
1286 	void (*func)(BTextWidget*, BPose*, BPoseView*, BColumn*, Param1), Param1 p1)
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);
1296 	}
1297 }
1298 
1299 
1300 template<class Param1, class Param2>
1301 void
1302 EachTextWidget(BPose* pose, BPoseView* poseView,
1303 	void (*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 			(func)(widget, pose, poseView, column, p1, p2);
1314 	}
1315 }
1316 
1317 
1318 template<class Result, class Param1, class Param2>
1319 Result
1320 WhileEachTextWidget(BPose* pose, BPoseView* poseView,
1321 	Result (*func)(BTextWidget*, BPose*, BPoseView*, BColumn*,
1322 	Param1, Param2), Param1 p1, Param2 p2)
1323 {
1324 	for (int32 index = 0; ;index++) {
1325 		BColumn* column = poseView->ColumnAt(index);
1326 		if (column == NULL)
1327 			break;
1328 
1329 		BTextWidget* widget = pose->WidgetFor(column->AttrHash());
1330 		if (widget != NULL) {
1331 			Result result = (func)(widget, pose, poseView, column, p1, p2);
1332 			if (result != 0)
1333 				return result;
1334 		}
1335 	}
1336 
1337 	return 0;
1338 }
1339 
1340 
1341 } // namespace BPrivate
1342 
1343 using namespace BPrivate;
1344 
1345 
1346 #endif	// _POSE_VIEW_H
1347