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