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