xref: /haiku/src/kits/tracker/PoseView.h (revision 4a55cc230cf7566cadcbb23b1928eefff8aea9a2)
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 SetShowHideSelection(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 	rgb_color DeskTextColor() const;
217 	rgb_color DeskTextBackColor() 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,
289 		bool askUser = true);
290 	virtual void MoveEntryToTrash(const entry_ref*,
291 		bool selectNext = true);
292 
293 	void RestoreSelectionFromTrash(bool selectNext = true);
294 
295 	// selection
296 	PoseList* SelectionList() const;
297 	void SelectAll();
298 	void InvertSelection();
299 	int32 SelectMatchingEntries(const BMessage*);
300 	void ShowSelectionWindow();
301 	void ClearSelection();
302 	void ShowSelection(bool);
303 	void AddRemovePoseFromSelection(BPose* pose, int32 index,
304 		bool select);
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 fShowHideSelection : 1;
791 	bool fOkToMapIcons : 1;
792 	bool fEnsurePosesVisible : 1;
793 	bool fShouldAutoScroll : 1;
794 	bool fIsDesktopWindow : 1;
795 	bool fIsWatchingDateFormatChange : 1;
796 	bool fHasPosesInClipboard : 1;
797 	bool fCursorCheck : 1;
798 	bool fFiltering : 1;
799 
800 	BObjectList<BString> fFilterStrings;
801 	int32 fLastFilterStringCount;
802 	int32 fLastFilterStringLength;
803 
804 	BRect fStartFrame;
805 
806 	static float sFontHeight;
807 	static font_height sFontInfo;
808 	static BString sMatchString;
809 		// used for typeahead - should be replaced by a typeahead state
810 
811 	bigtime_t fLastKeyTime;
812 	bigtime_t fLastDeskbarFrameCheckTime;
813 	BRect fDeskbarFrame;
814 
815 	static OffscreenBitmap* sOffscreen;
816 
817 	BTextWidget* fTextWidgetToCheck;
818 	BTextWidget* fActiveTextWidget;
819 
820 private:
821 	mutable uint32 fCachedIconSizeFrom;
822 	mutable BSize fCachedIconSize;
823 
824 	typedef BView _inherited;
825 };
826 
827 
828 class TScrollBar : public BScrollBar {
829 public:
830 	TScrollBar(const char*, BView*, float, float);
831 	void SetTitleView(BView*);
832 
833 	// BScrollBar overrides
834 	virtual	void ValueChanged(float);
835 
836 private:
837 	BView* fTitleView;
838 
839 	typedef BScrollBar _inherited;
840 };
841 
842 
843 class TPoseViewFilter : public BMessageFilter {
844 public:
845 	TPoseViewFilter(BPoseView* pose);
846 	~TPoseViewFilter();
847 
848 	filter_result Filter(BMessage*, BHandler**);
849 
850 private:
851 	filter_result ObjectDropFilter(BMessage*, BHandler**);
852 
853 	BPoseView* fPoseView;
854 };
855 
856 
857 extern bool
858 ClearViewOriginOne(const char* name, uint32 type, off_t size, void* data,
859 	void* params);
860 
861 
862 // inlines follow
863 
864 
865 inline BContainerWindow*
866 BPoseView::ContainerWindow() const
867 {
868 	return dynamic_cast<BContainerWindow*>(Window());
869 }
870 
871 
872 inline Model*
873 BPoseView::TargetModel() const
874 {
875 	return fModel;
876 }
877 
878 
879 inline float
880 BPoseView::ListElemHeight() const
881 {
882 	return fListElemHeight;
883 }
884 
885 
886 inline float
887 BPoseView::ListOffset() const
888 {
889 	return fListOffset;
890 }
891 
892 
893 inline float
894 BPoseView::IconPoseHeight() const
895 {
896 	return fIconPoseHeight;
897 }
898 
899 
900 inline uint32
901 BPoseView::UnscaledIconSizeInt() const
902 {
903 	return fViewState->IconSize();
904 }
905 
906 
907 inline uint32
908 BPoseView::IconSizeInt() const
909 {
910 	return IconSize().IntegerWidth() + 1;
911 }
912 
913 
914 inline PoseList*
915 BPoseView::SelectionList() const
916 {
917 	return fSelectionList;
918 }
919 
920 
921 inline BObjectList<BString>*
922 BPoseView::MimeTypesInSelection()
923 {
924 	return &fMimeTypesInSelectionCache;
925 }
926 
927 
928 inline BScrollBar*
929 BPoseView::HScrollBar() const
930 {
931 	return fHScrollBar;
932 }
933 
934 
935 inline BScrollBar*
936 BPoseView::VScrollBar() const
937 {
938 	return fVScrollBar;
939 }
940 
941 
942 inline BCountView*
943 BPoseView::CountView() const
944 {
945 	return fCountView;
946 }
947 
948 
949 inline BTitleView*
950 BPoseView::TitleView() const
951 {
952 	return fTitleView;
953 }
954 
955 
956 inline bool
957 BPoseView::StateNeedsSaving()
958 {
959 	return fStateNeedsSaving || fViewState->StateNeedsSaving();
960 }
961 
962 
963 inline uint32
964 BPoseView::ViewMode() const
965 {
966 	return fViewState->ViewMode();
967 }
968 
969 
970 inline font_height
971 BPoseView::FontInfo() const
972 {
973 	return sFontInfo;
974 }
975 
976 
977 inline float
978 BPoseView::FontHeight() const
979 {
980 	return sFontHeight;
981 }
982 
983 
984 inline BPose*
985 BPoseView::ActivePose() const
986 {
987 	return fActivePose;
988 }
989 
990 
991 inline void
992 BPoseView::DisableSaveLocation()
993 {
994 	fSavePoseLocations = false;
995 }
996 
997 
998 inline bool
999 BPoseView::IsFilePanel() const
1000 {
1001 	return false;
1002 }
1003 
1004 
1005 inline bool
1006 BPoseView::IsDesktopWindow() const
1007 {
1008 	return fIsDesktopWindow;
1009 }
1010 
1011 
1012 inline bool
1013 BPoseView::IsDesktopView() const
1014 {
1015 	return false;
1016 }
1017 
1018 
1019 inline uint32
1020 BPoseView::PrimarySort() const
1021 {
1022 	return fViewState->PrimarySort();
1023 }
1024 
1025 
1026 inline uint32
1027 BPoseView::PrimarySortType() const
1028 {
1029 	return fViewState->PrimarySortType();
1030 }
1031 
1032 
1033 inline uint32
1034 BPoseView::SecondarySort() const
1035 {
1036 	return fViewState->SecondarySort();
1037 }
1038 
1039 
1040 inline uint32
1041 BPoseView::SecondarySortType() const
1042 {
1043 	return fViewState->SecondarySortType();
1044 }
1045 
1046 
1047 inline bool
1048 BPoseView::ReverseSort() const
1049 {
1050 	return fViewState->ReverseSort();
1051 }
1052 
1053 
1054 inline void
1055 BPoseView::SetShowHideSelection(bool on)
1056 {
1057 	fShowHideSelection = on;
1058 }
1059 
1060 
1061 inline void
1062 BPoseView::SetIconMapping(bool on)
1063 {
1064 	fOkToMapIcons = on;
1065 }
1066 
1067 
1068 inline void
1069 BPoseView::AddToExtent(const BRect&rect)
1070 {
1071 	fExtent = fExtent | rect;
1072 }
1073 
1074 
1075 inline void
1076 BPoseView::ClearExtent()
1077 {
1078 	fExtent.Set(INT32_MAX, INT32_MAX, INT32_MIN, INT32_MIN);
1079 }
1080 
1081 
1082 inline int32
1083 BPoseView::CountColumns() const
1084 {
1085 	return fColumnList->CountItems();
1086 }
1087 
1088 
1089 inline float
1090 BPoseView::StartOffset() const
1091 {
1092 	return fListOffset + ListIconSize() + kMiniIconSeparator + 1;
1093 }
1094 
1095 
1096 inline int32
1097 BPoseView::IndexOfColumn(const BColumn* column) const
1098 {
1099 	return fColumnList->IndexOf(const_cast<BColumn*>(column));
1100 }
1101 
1102 
1103 inline int32
1104 BPoseView::IndexOfPose(const BPose* pose) const
1105 {
1106 	return CurrentPoseList()->IndexOf(pose);
1107 }
1108 
1109 
1110 inline BPose*
1111 BPoseView::PoseAtIndex(int32 index) const
1112 {
1113 	return CurrentPoseList()->ItemAt(index);
1114 }
1115 
1116 
1117 inline BColumn*
1118 BPoseView::ColumnAt(int32 index) const
1119 {
1120 	return fColumnList->ItemAt(index);
1121 }
1122 
1123 
1124 inline BColumn*
1125 BPoseView::FirstColumn() const
1126 {
1127 	return fColumnList->FirstItem();
1128 }
1129 
1130 
1131 inline BColumn*
1132 BPoseView::LastColumn() const
1133 {
1134 	return fColumnList->LastItem();
1135 }
1136 
1137 
1138 inline int32
1139 BPoseView::CountItems() const
1140 {
1141 	return CurrentPoseList()->CountItems();
1142 }
1143 
1144 
1145 inline void
1146 BPoseView::SetMultipleSelection(bool state)
1147 {
1148 	fMultipleSelection = state;
1149 }
1150 
1151 
1152 inline void
1153 BPoseView::SetSelectionChangedHook(bool state)
1154 {
1155 	fSelectionChangedHook = state;
1156 }
1157 
1158 
1159 inline void
1160 BPoseView::SetAutoScroll(bool state)
1161 {
1162 	fShouldAutoScroll = state;
1163 }
1164 
1165 
1166 inline void
1167 BPoseView::SetPoseEditing(bool state)
1168 {
1169 	fAllowPoseEditing = state;
1170 }
1171 
1172 
1173 inline void
1174 BPoseView::SetDragEnabled(bool state)
1175 {
1176 	fDragEnabled = state;
1177 }
1178 
1179 
1180 inline void
1181 BPoseView::SetDropEnabled(bool state)
1182 {
1183 	fDropEnabled = state;
1184 }
1185 
1186 
1187 inline void
1188 BPoseView::SetSelectionRectEnabled(bool state)
1189 {
1190 	fSelectionRectEnabled = state;
1191 }
1192 
1193 
1194 inline void
1195 BPoseView::SetAlwaysAutoPlace(bool state)
1196 {
1197 	fAlwaysAutoPlace = state;
1198 }
1199 
1200 
1201 inline void
1202 BPoseView::SetEnsurePosesVisible(bool state)
1203 {
1204 	fEnsurePosesVisible = state;
1205 }
1206 
1207 
1208 inline void
1209 BPoseView::SetSelectionHandler(BLooper* looper)
1210 {
1211 	fSelectionHandler = looper;
1212 }
1213 
1214 
1215 inline void
1216 TScrollBar::SetTitleView(BView* view)
1217 {
1218 	fTitleView = view;
1219 }
1220 
1221 
1222 inline void
1223 BPoseView::SetRefFilter(BRefFilter* filter)
1224 {
1225 	fRefFilter = filter;
1226 	if (filter != NULL)
1227 		FilterChanged();
1228 }
1229 
1230 
1231 inline BRefFilter*
1232 BPoseView::RefFilter() const
1233 {
1234 	return fRefFilter;
1235 }
1236 
1237 
1238 inline BPose*
1239 BPoseView::FindPose(const Model* model, int32* index) const
1240 {
1241 	return CurrentPoseList()->FindPose(model, index);
1242 }
1243 
1244 
1245 inline BPose*
1246 BPoseView::FindPose(const node_ref* node, int32* index) const
1247 {
1248 	return CurrentPoseList()->FindPose(node, index);
1249 }
1250 
1251 
1252 inline BPose*
1253 BPoseView::FindPose(const entry_ref* entry, int32* index) const
1254 {
1255 	return CurrentPoseList()->FindPose(entry, index);
1256 }
1257 
1258 
1259 inline bool
1260 BPoseView::HasPosesInClipboard()
1261 {
1262 	return fHasPosesInClipboard;
1263 }
1264 
1265 
1266 inline void
1267 BPoseView::SetHasPosesInClipboard(bool hasPoses)
1268 {
1269 	fHasPosesInClipboard = hasPoses;
1270 }
1271 
1272 
1273 inline PoseList*
1274 BPoseView::CurrentPoseList() const
1275 {
1276 	return fFiltering ? fFilteredPoseList : fPoseList;
1277 }
1278 
1279 
1280 template<class Param1>
1281 void
1282 EachTextWidget(BPose* pose, BPoseView* poseView,
1283 	void (*func)(BTextWidget*, BPose*, BPoseView*, BColumn*, Param1), Param1 p1)
1284 {
1285 	for (int32 index = 0; ;index++) {
1286 		BColumn* column = poseView->ColumnAt(index);
1287 		if (column == NULL)
1288 			break;
1289 
1290 		BTextWidget* widget = pose->WidgetFor(column->AttrHash());
1291 		if (widget != NULL)
1292 			(func)(widget, pose, poseView, column, p1);
1293 	}
1294 }
1295 
1296 
1297 template<class Param1, class Param2>
1298 void
1299 EachTextWidget(BPose* pose, BPoseView* poseView,
1300 	void (*func)(BTextWidget*, BPose*, BPoseView*, BColumn*,
1301 	Param1, Param2), Param1 p1, Param2 p2)
1302 {
1303 	for (int32 index = 0; ;index++) {
1304 		BColumn* column = poseView->ColumnAt(index);
1305 		if (column == NULL)
1306 			break;
1307 
1308 		BTextWidget* widget = pose->WidgetFor(column->AttrHash());
1309 		if (widget != NULL)
1310 			(func)(widget, pose, poseView, column, p1, p2);
1311 	}
1312 }
1313 
1314 
1315 template<class Result, class Param1, class Param2>
1316 Result
1317 WhileEachTextWidget(BPose* pose, BPoseView* poseView,
1318 	Result (*func)(BTextWidget*, BPose*, BPoseView*, BColumn*,
1319 	Param1, Param2), Param1 p1, Param2 p2)
1320 {
1321 	for (int32 index = 0; ;index++) {
1322 		BColumn* column = poseView->ColumnAt(index);
1323 		if (column == NULL)
1324 			break;
1325 
1326 		BTextWidget* widget = pose->WidgetFor(column->AttrHash());
1327 		if (widget != NULL) {
1328 			Result result = (func)(widget, pose, poseView, column, p1, p2);
1329 			if (result != 0)
1330 				return result;
1331 		}
1332 	}
1333 
1334 	return 0;
1335 }
1336 
1337 
1338 } // namespace BPrivate
1339 
1340 using namespace BPrivate;
1341 
1342 
1343 #endif	// _POSE_VIEW_H
1344