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