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