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