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