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