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 SetShowHideSelection(bool); 161 void SetEnsurePosesVisible(bool); 162 void SetIconMapping(bool); 163 void SetAutoScroll(bool); 164 void SetPoseEditing(bool); 165 166 void UpdateIcon(BPose* pose); 167 168 // file change notification handler 169 virtual bool FSNotification(const BMessage*); 170 171 // scrollbars 172 virtual void UpdateScrollRange(); 173 virtual void SetScrollBarsTo(BPoint); 174 virtual void AddScrollBars(); 175 BScrollBar* HScrollBar() const; 176 BScrollBar* VScrollBar() const ; 177 BCountView* CountView() const; 178 BTitleView* TitleView() const; 179 void DisableScrollBars(); 180 void EnableScrollBars(); 181 182 // sorting 183 virtual void SortPoses(); 184 void SetPrimarySort(uint32 attrHash); 185 void SetSecondarySort(uint32 attrHash); 186 void SetReverseSort(bool reverse); 187 uint32 PrimarySort() const; 188 uint32 PrimarySortType() const; 189 uint32 SecondarySort() const; 190 uint32 SecondarySortType() const; 191 bool ReverseSort() const; 192 void CheckPoseSortOrder(BPose*, int32 index); 193 void CheckPoseVisibility(BRect* = NULL); 194 // make sure pose fits the screen and/or window bounds if needed 195 196 // view metrics 197 font_height FontInfo() const; 198 // returns height, descent, etc. 199 float FontHeight() const; 200 float ListElemHeight() const; 201 float ListOffset() const; 202 203 void SetIconPoseHeight(); 204 float IconPoseHeight() const; 205 uint32 UnscaledIconSizeInt() const; 206 uint32 IconSizeInt() const; 207 BSize IconSize() const; 208 209 BRect Extent() const; 210 void GetLayoutInfo(uint32 viewMode, BPoint* grid, 211 BPoint* offset) const; 212 213 int32 CountItems() const; 214 void UpdateCount(); 215 216 rgb_color DeskTextColor() const; 217 rgb_color DeskTextBackColor() const; 218 219 bool WidgetTextOutline() const; 220 void SetWidgetTextOutline(bool); 221 // used to not erase when we have a background image and 222 // invalidate instead 223 224 void ScrollView(int32 type); 225 226 // column handling 227 void ColumnRedraw(BRect updateRect); 228 bool AddColumn(BColumn*, const BColumn* after = NULL); 229 bool RemoveColumn(BColumn* column, bool runAlert); 230 void MoveColumnTo(BColumn* src, BColumn* dest); 231 bool ResizeColumnToWidest(BColumn* column); 232 BPoint ResizeColumn(BColumn*, float, float* lastLineDrawPos = NULL, 233 void (*drawLineFunc)(BPoseView*, BPoint, BPoint) = 0, 234 void (*undrawLineFunc)(BPoseView*, BPoint, BPoint) = 0); 235 // returns the bottom right of the last pose drawn or 236 // the bottom right of bounds 237 238 BColumn* ColumnAt(int32 index) const; 239 BColumn* ColumnFor(uint32 attribute_hash) const; 240 BColumn* FirstColumn() const; 241 BColumn* LastColumn() const; 242 int32 IndexOfColumn(const BColumn*) const; 243 int32 CountColumns() const; 244 245 // Where to start the first column 246 float StartOffset() const; 247 248 // pose access 249 int32 IndexOfPose(const BPose*) const; 250 BPose* PoseAtIndex(int32 index) const; 251 252 BPose* FindPose(BPoint where, int32* index = NULL) const; 253 // return pose at location h, v (search list starting from 254 // bottom so drawing and hit detection reflect the same pose 255 // ordering) 256 BPose* FindPose(const Model*, int32* index = NULL) const; 257 BPose* FindPose(const node_ref*, int32* index = NULL) const; 258 BPose* FindPose(const entry_ref*, int32* index = NULL) const; 259 BPose* FindPose(const entry_ref*, int32 specifierForm, 260 int32* index) const; 261 // special form of FindPose used for scripting, 262 // <specifierForm> may ask for previous or next pose 263 BPose* DeepFindPose(const node_ref* node, int32* index = NULL) const; 264 // same as FindPose, node can be a target of the actual 265 // pose if the pose is a symlink 266 BPose* FirstVisiblePose(int32* _index = NULL) const; 267 BPose* LastVisiblePose(int32* _index = NULL) const; 268 269 void OpenInfoWindows(); 270 void SetDefaultPrinter(); 271 272 void IdentifySelection(bool force = false); 273 void UnmountSelectedVolumes(); 274 virtual void OpenParent(); 275 276 virtual void OpenSelection(BPose* clicked_pose = NULL, 277 int32* index = NULL); 278 void OpenSelectionUsing(BPose* clicked_pose = NULL, 279 int32* index = NULL); 280 // launches the open with window 281 virtual void MoveSelectionTo(BPoint, BPoint, BContainerWindow*); 282 void DuplicateSelection(BPoint* dropStart = NULL, 283 BPoint* dropEnd = NULL); 284 285 // Move to trash calls try to select the next pose in the view 286 // when they are dones 287 virtual void MoveSelectionToTrash(bool selectNext = true); 288 virtual void DeleteSelection(bool selectNext = true, 289 bool askUser = true); 290 virtual void MoveEntryToTrash(const entry_ref*, 291 bool selectNext = true); 292 293 void RestoreSelectionFromTrash(bool selectNext = true); 294 295 // selection 296 PoseList* SelectionList() const; 297 void SelectAll(); 298 void InvertSelection(); 299 int32 SelectMatchingEntries(const BMessage*); 300 void ShowSelectionWindow(); 301 void ClearSelection(); 302 void ShowSelection(bool); 303 void AddRemovePoseFromSelection(BPose* pose, int32 index, 304 bool select); 305 306 void SetSelectionHandler(BLooper* looper); 307 308 BObjectList<BString>*MimeTypesInSelection(); 309 310 // pose selection 311 void SelectPose(BPose*, int32 index, bool scrollIntoView = true); 312 void AddPoseToSelection(BPose*, int32 index, 313 bool scrollIntoView = true); 314 void RemovePoseFromSelection(BPose*); 315 void SelectPoseAtLocation(BPoint); 316 void SelectPoses(int32 start, int32 end); 317 void MoveOrChangePoseSelection(int32 to); 318 319 // pose handling 320 void ScrollIntoView(BPose* pose, int32 index); 321 void ScrollIntoView(BRect poseRect); 322 void SetActivePose(BPose*); 323 BPose* ActivePose() const; 324 void CommitActivePose(bool saveChanges = true); 325 static bool PoseVisible(const Model*, const PoseInfo*); 326 bool FrameForPose(BPose* targetPose, bool convert, BRect* poseRect); 327 bool CreateSymlinkPoseTarget(Model* symlink); 328 // used to complete a symlink pose; returns true if 329 // target symlink should not be shown 330 void ResetPosePlacementHint(); 331 void PlaceFolder(const entry_ref*, const BMessage*); 332 333 // clipboard handling for poses 334 inline bool HasPosesInClipboard(); 335 inline void SetHasPosesInClipboard(bool hasPoses); 336 void SetPosesClipboardMode(uint32 clipboardMode); 337 void UpdatePosesClipboardModeFromClipboard( 338 BMessage* clipboardReport = NULL); 339 340 // filtering 341 void SetRefFilter(BRefFilter*); 342 BRefFilter* RefFilter() const; 343 344 // access for mime types represented in the pose view 345 void AddMimeType(const char* mimeType); 346 const char* MimeTypeAt(int32 index); 347 int32 CountMimeTypes(); 348 void RefreshMimeTypeList(); 349 350 // drag&drop handling 351 virtual bool HandleMessageDropped(BMessage*); 352 static bool HandleDropCommon(BMessage* dragMessage, Model* target, 353 BPose*, BView* view, BPoint dropPoint); 354 // used by pose views and info windows 355 static bool CanHandleDragSelection(const Model* target, 356 const BMessage* dragMessage, bool ignoreTypes); 357 virtual void DragSelectedPoses(const BPose* clickedPose, BPoint); 358 359 void MoveSelectionInto(Model* destFolder, BContainerWindow* srcWindow, 360 bool forceCopy, bool forceMove = false, bool createLink = false, 361 bool relativeLink = false); 362 static void MoveSelectionInto(Model* destFolder, 363 BContainerWindow* srcWindow, BContainerWindow* destWindow, 364 uint32 buttons, BPoint loc, bool forceCopy, 365 bool forceMove = false, bool createLink = false, 366 bool relativeLink = false, BPoint clickPoint = BPoint(0, 0), 367 bool pinToGrid = false); 368 369 bool UpdateDropTarget(BPoint, const BMessage*, 370 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 394 // up the view, etc. 395 void ShowBarberPole(); 396 void HideBarberPole(); 397 398 bool fShowSelectionWhenInactive; 399 bool fIsDrawingSelectionRect; 400 401 bool IsWatchingDateFormatChange(); 402 void StartWatchDateFormatChange(); 403 void StopWatchDateFormatChange(); 404 405 // type ahead filtering 406 bool IsFiltering() const; 407 408 void UpdateDateColumns(BMessage*); 409 virtual void AdaptToVolumeChange(BMessage*); 410 virtual void AdaptToDesktopIntegrationChange(BMessage*); 411 412 void SetTextWidgetToCheck(BTextWidget*, BTextWidget* = NULL); 413 414 BTextWidget* ActiveTextWidget() { return fActiveTextWidget; }; 415 void SetActiveTextWidget(BTextWidget* w) { fActiveTextWidget = w; }; 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 678 protected: 679 struct node_ref_key { 680 node_ref_key() {} 681 node_ref_key(const node_ref& value) : value(value) {} 682 683 uint32 GetHashCode() const 684 { 685 return (uint32)value.device ^ (uint32)value.node; 686 } 687 688 node_ref_key operator=(const node_ref_key& other) 689 { 690 value = other.value; 691 return *this; 692 } 693 694 bool operator==(const node_ref_key& other) const 695 { 696 return (value == other.value); 697 } 698 699 bool operator!=(const node_ref_key& other) const 700 { 701 return (value != other.value); 702 } 703 704 node_ref value; 705 }; 706 707 protected: 708 BViewState* fViewState; 709 bool fStateNeedsSaving; 710 711 bool fSavePoseLocations : 1; 712 bool fMultipleSelection : 1; 713 bool fDragEnabled : 1; 714 bool fDropEnabled : 1; 715 716 BLooper* fSelectionHandler; 717 718 std::set<thread_id> fAddPosesThreads; 719 PoseList* fPoseList; 720 721 PendingNodeMonitorCache pendingNodeMonitorCache; 722 723 private: 724 TScrollBar* fHScrollBar; 725 BScrollBar* fVScrollBar; 726 Model* fModel; 727 BPose* fActivePose; 728 BRect fExtent; 729 // the following should probably be just member lists, not pointers 730 PoseList* fFilteredPoseList; 731 PoseList* fVSPoseList; 732 PoseList* fSelectionList; 733 HashSet<node_ref_key> fInsertedNodes; 734 BObjectList<BString> fMimeTypesInSelectionCache; 735 // used for mime string based icon highliting during a drag 736 BObjectList<Model>* fZombieList; 737 BObjectList<BColumn>* fColumnList; 738 BObjectList<BString>* fMimeTypeList; 739 BObjectList<Model>* fBrokenLinks; 740 bool fMimeTypeListIsDirty; 741 BCountView* fCountView; 742 float fListElemHeight; 743 float fListOffset; 744 float fIconPoseHeight; 745 BPose* fDropTarget; 746 BPose* fAlreadySelectedDropTarget; 747 BPoint fLastClickPoint; 748 int32 fLastClickButtons; 749 const BPose* fLastClickedPose; 750 BPoint fLastLeftTop; 751 BRect fLastExtent; 752 BTitleView* fTitleView; 753 BRefFilter* fRefFilter; 754 BPoint fGrid; 755 BPoint fOffset; 756 BPoint fHintLocation; 757 float fAutoScrollInc; 758 int32 fAutoScrollState; 759 bool fWidgetTextOutline; 760 const BPose* fSelectionPivotPose; 761 const BPose* fRealPivotPose; 762 BMessageRunner* fKeyRunner; 763 bool fTrackRightMouseUp; 764 bool fTrackMouseUp; 765 766 struct SelectionRectInfo { 767 SelectionRectInfo() 768 : 769 isDragging(false), 770 selection(NULL) 771 { 772 } 773 774 bool isDragging; 775 BRect rect; 776 BRect lastRect; 777 BPoint startPoint; 778 BPoint lastPoint; 779 BList* selection; 780 }; 781 SelectionRectInfo fSelectionRectInfo; 782 783 bool fSelectionVisible : 1; 784 bool fSelectionRectEnabled : 1; 785 bool fTransparentSelection : 1; 786 bool fAlwaysAutoPlace : 1; 787 bool fAllowPoseEditing : 1; 788 bool fSelectionChangedHook : 1; 789 // get rid of this 790 bool fShowHideSelection : 1; 791 bool fOkToMapIcons : 1; 792 bool fEnsurePosesVisible : 1; 793 bool fShouldAutoScroll : 1; 794 bool fIsDesktopWindow : 1; 795 bool fIsWatchingDateFormatChange : 1; 796 bool fHasPosesInClipboard : 1; 797 bool fCursorCheck : 1; 798 bool fFiltering : 1; 799 800 BObjectList<BString> fFilterStrings; 801 int32 fLastFilterStringCount; 802 int32 fLastFilterStringLength; 803 804 BRect fStartFrame; 805 806 static float sFontHeight; 807 static font_height sFontInfo; 808 static BString sMatchString; 809 // used for typeahead - should be replaced by a typeahead state 810 811 bigtime_t fLastKeyTime; 812 bigtime_t fLastDeskbarFrameCheckTime; 813 BRect fDeskbarFrame; 814 815 static OffscreenBitmap* sOffscreen; 816 817 BTextWidget* fTextWidgetToCheck; 818 BTextWidget* fActiveTextWidget; 819 820 private: 821 mutable uint32 fCachedIconSizeFrom; 822 mutable BSize fCachedIconSize; 823 824 typedef BView _inherited; 825 }; 826 827 828 class TScrollBar : public BScrollBar { 829 public: 830 TScrollBar(const char*, BView*, float, float); 831 void SetTitleView(BView*); 832 833 // BScrollBar overrides 834 virtual void ValueChanged(float); 835 836 private: 837 BView* fTitleView; 838 839 typedef BScrollBar _inherited; 840 }; 841 842 843 class TPoseViewFilter : public BMessageFilter { 844 public: 845 TPoseViewFilter(BPoseView* pose); 846 ~TPoseViewFilter(); 847 848 filter_result Filter(BMessage*, BHandler**); 849 850 private: 851 filter_result ObjectDropFilter(BMessage*, BHandler**); 852 853 BPoseView* fPoseView; 854 }; 855 856 857 extern bool 858 ClearViewOriginOne(const char* name, uint32 type, off_t size, void* data, 859 void* params); 860 861 862 // inlines follow 863 864 865 inline BContainerWindow* 866 BPoseView::ContainerWindow() const 867 { 868 return dynamic_cast<BContainerWindow*>(Window()); 869 } 870 871 872 inline Model* 873 BPoseView::TargetModel() const 874 { 875 return fModel; 876 } 877 878 879 inline float 880 BPoseView::ListElemHeight() const 881 { 882 return fListElemHeight; 883 } 884 885 886 inline float 887 BPoseView::ListOffset() const 888 { 889 return fListOffset; 890 } 891 892 893 inline float 894 BPoseView::IconPoseHeight() const 895 { 896 return fIconPoseHeight; 897 } 898 899 900 inline uint32 901 BPoseView::UnscaledIconSizeInt() const 902 { 903 return fViewState->IconSize(); 904 } 905 906 907 inline uint32 908 BPoseView::IconSizeInt() const 909 { 910 return IconSize().IntegerWidth() + 1; 911 } 912 913 914 inline PoseList* 915 BPoseView::SelectionList() const 916 { 917 return fSelectionList; 918 } 919 920 921 inline BObjectList<BString>* 922 BPoseView::MimeTypesInSelection() 923 { 924 return &fMimeTypesInSelectionCache; 925 } 926 927 928 inline BScrollBar* 929 BPoseView::HScrollBar() const 930 { 931 return fHScrollBar; 932 } 933 934 935 inline BScrollBar* 936 BPoseView::VScrollBar() const 937 { 938 return fVScrollBar; 939 } 940 941 942 inline BCountView* 943 BPoseView::CountView() const 944 { 945 return fCountView; 946 } 947 948 949 inline BTitleView* 950 BPoseView::TitleView() const 951 { 952 return fTitleView; 953 } 954 955 956 inline bool 957 BPoseView::StateNeedsSaving() 958 { 959 return fStateNeedsSaving || fViewState->StateNeedsSaving(); 960 } 961 962 963 inline uint32 964 BPoseView::ViewMode() const 965 { 966 return fViewState->ViewMode(); 967 } 968 969 970 inline font_height 971 BPoseView::FontInfo() const 972 { 973 return sFontInfo; 974 } 975 976 977 inline float 978 BPoseView::FontHeight() const 979 { 980 return sFontHeight; 981 } 982 983 984 inline BPose* 985 BPoseView::ActivePose() const 986 { 987 return fActivePose; 988 } 989 990 991 inline void 992 BPoseView::DisableSaveLocation() 993 { 994 fSavePoseLocations = false; 995 } 996 997 998 inline bool 999 BPoseView::IsFilePanel() const 1000 { 1001 return false; 1002 } 1003 1004 1005 inline bool 1006 BPoseView::IsDesktopWindow() const 1007 { 1008 return fIsDesktopWindow; 1009 } 1010 1011 1012 inline bool 1013 BPoseView::IsDesktopView() const 1014 { 1015 return false; 1016 } 1017 1018 1019 inline uint32 1020 BPoseView::PrimarySort() const 1021 { 1022 return fViewState->PrimarySort(); 1023 } 1024 1025 1026 inline uint32 1027 BPoseView::PrimarySortType() const 1028 { 1029 return fViewState->PrimarySortType(); 1030 } 1031 1032 1033 inline uint32 1034 BPoseView::SecondarySort() const 1035 { 1036 return fViewState->SecondarySort(); 1037 } 1038 1039 1040 inline uint32 1041 BPoseView::SecondarySortType() const 1042 { 1043 return fViewState->SecondarySortType(); 1044 } 1045 1046 1047 inline bool 1048 BPoseView::ReverseSort() const 1049 { 1050 return fViewState->ReverseSort(); 1051 } 1052 1053 1054 inline void 1055 BPoseView::SetShowHideSelection(bool on) 1056 { 1057 fShowHideSelection = on; 1058 } 1059 1060 1061 inline void 1062 BPoseView::SetIconMapping(bool on) 1063 { 1064 fOkToMapIcons = on; 1065 } 1066 1067 1068 inline void 1069 BPoseView::AddToExtent(const BRect&rect) 1070 { 1071 fExtent = fExtent | rect; 1072 } 1073 1074 1075 inline void 1076 BPoseView::ClearExtent() 1077 { 1078 fExtent.Set(INT32_MAX, INT32_MAX, INT32_MIN, INT32_MIN); 1079 } 1080 1081 1082 inline int32 1083 BPoseView::CountColumns() const 1084 { 1085 return fColumnList->CountItems(); 1086 } 1087 1088 1089 inline float 1090 BPoseView::StartOffset() const 1091 { 1092 return fListOffset + ListIconSize() + kMiniIconSeparator + 1; 1093 } 1094 1095 1096 inline int32 1097 BPoseView::IndexOfColumn(const BColumn* column) const 1098 { 1099 return fColumnList->IndexOf(const_cast<BColumn*>(column)); 1100 } 1101 1102 1103 inline int32 1104 BPoseView::IndexOfPose(const BPose* pose) const 1105 { 1106 return CurrentPoseList()->IndexOf(pose); 1107 } 1108 1109 1110 inline BPose* 1111 BPoseView::PoseAtIndex(int32 index) const 1112 { 1113 return CurrentPoseList()->ItemAt(index); 1114 } 1115 1116 1117 inline BColumn* 1118 BPoseView::ColumnAt(int32 index) const 1119 { 1120 return fColumnList->ItemAt(index); 1121 } 1122 1123 1124 inline BColumn* 1125 BPoseView::FirstColumn() const 1126 { 1127 return fColumnList->FirstItem(); 1128 } 1129 1130 1131 inline BColumn* 1132 BPoseView::LastColumn() const 1133 { 1134 return fColumnList->LastItem(); 1135 } 1136 1137 1138 inline int32 1139 BPoseView::CountItems() const 1140 { 1141 return CurrentPoseList()->CountItems(); 1142 } 1143 1144 1145 inline void 1146 BPoseView::SetMultipleSelection(bool state) 1147 { 1148 fMultipleSelection = state; 1149 } 1150 1151 1152 inline void 1153 BPoseView::SetSelectionChangedHook(bool state) 1154 { 1155 fSelectionChangedHook = state; 1156 } 1157 1158 1159 inline void 1160 BPoseView::SetAutoScroll(bool state) 1161 { 1162 fShouldAutoScroll = state; 1163 } 1164 1165 1166 inline void 1167 BPoseView::SetPoseEditing(bool state) 1168 { 1169 fAllowPoseEditing = state; 1170 } 1171 1172 1173 inline void 1174 BPoseView::SetDragEnabled(bool state) 1175 { 1176 fDragEnabled = state; 1177 } 1178 1179 1180 inline void 1181 BPoseView::SetDropEnabled(bool state) 1182 { 1183 fDropEnabled = state; 1184 } 1185 1186 1187 inline void 1188 BPoseView::SetSelectionRectEnabled(bool state) 1189 { 1190 fSelectionRectEnabled = state; 1191 } 1192 1193 1194 inline void 1195 BPoseView::SetAlwaysAutoPlace(bool state) 1196 { 1197 fAlwaysAutoPlace = state; 1198 } 1199 1200 1201 inline void 1202 BPoseView::SetEnsurePosesVisible(bool state) 1203 { 1204 fEnsurePosesVisible = state; 1205 } 1206 1207 1208 inline void 1209 BPoseView::SetSelectionHandler(BLooper* looper) 1210 { 1211 fSelectionHandler = looper; 1212 } 1213 1214 1215 inline void 1216 TScrollBar::SetTitleView(BView* view) 1217 { 1218 fTitleView = view; 1219 } 1220 1221 1222 inline void 1223 BPoseView::SetRefFilter(BRefFilter* filter) 1224 { 1225 fRefFilter = filter; 1226 if (filter != NULL) 1227 FilterChanged(); 1228 } 1229 1230 1231 inline BRefFilter* 1232 BPoseView::RefFilter() const 1233 { 1234 return fRefFilter; 1235 } 1236 1237 1238 inline BPose* 1239 BPoseView::FindPose(const Model* model, int32* index) const 1240 { 1241 return CurrentPoseList()->FindPose(model, index); 1242 } 1243 1244 1245 inline BPose* 1246 BPoseView::FindPose(const node_ref* node, int32* index) const 1247 { 1248 return CurrentPoseList()->FindPose(node, index); 1249 } 1250 1251 1252 inline BPose* 1253 BPoseView::FindPose(const entry_ref* entry, int32* index) const 1254 { 1255 return CurrentPoseList()->FindPose(entry, index); 1256 } 1257 1258 1259 inline bool 1260 BPoseView::HasPosesInClipboard() 1261 { 1262 return fHasPosesInClipboard; 1263 } 1264 1265 1266 inline void 1267 BPoseView::SetHasPosesInClipboard(bool hasPoses) 1268 { 1269 fHasPosesInClipboard = hasPoses; 1270 } 1271 1272 1273 inline PoseList* 1274 BPoseView::CurrentPoseList() const 1275 { 1276 return fFiltering ? fFilteredPoseList : fPoseList; 1277 } 1278 1279 1280 template<class Param1> 1281 void 1282 EachTextWidget(BPose* pose, BPoseView* poseView, 1283 void (*func)(BTextWidget*, BPose*, BPoseView*, BColumn*, Param1), Param1 p1) 1284 { 1285 for (int32 index = 0; ;index++) { 1286 BColumn* column = poseView->ColumnAt(index); 1287 if (column == NULL) 1288 break; 1289 1290 BTextWidget* widget = pose->WidgetFor(column->AttrHash()); 1291 if (widget != NULL) 1292 (func)(widget, pose, poseView, column, p1); 1293 } 1294 } 1295 1296 1297 template<class Param1, class Param2> 1298 void 1299 EachTextWidget(BPose* pose, BPoseView* poseView, 1300 void (*func)(BTextWidget*, BPose*, BPoseView*, BColumn*, 1301 Param1, Param2), Param1 p1, Param2 p2) 1302 { 1303 for (int32 index = 0; ;index++) { 1304 BColumn* column = poseView->ColumnAt(index); 1305 if (column == NULL) 1306 break; 1307 1308 BTextWidget* widget = pose->WidgetFor(column->AttrHash()); 1309 if (widget != NULL) 1310 (func)(widget, pose, poseView, column, p1, p2); 1311 } 1312 } 1313 1314 1315 template<class Result, class Param1, class Param2> 1316 Result 1317 WhileEachTextWidget(BPose* pose, BPoseView* poseView, 1318 Result (*func)(BTextWidget*, BPose*, BPoseView*, BColumn*, 1319 Param1, Param2), Param1 p1, Param2 p2) 1320 { 1321 for (int32 index = 0; ;index++) { 1322 BColumn* column = poseView->ColumnAt(index); 1323 if (column == NULL) 1324 break; 1325 1326 BTextWidget* widget = pose->WidgetFor(column->AttrHash()); 1327 if (widget != NULL) { 1328 Result result = (func)(widget, pose, poseView, column, p1, p2); 1329 if (result != 0) 1330 return result; 1331 } 1332 } 1333 1334 return 0; 1335 } 1336 1337 1338 } // namespace BPrivate 1339 1340 using namespace BPrivate; 1341 1342 1343 #endif // _POSE_VIEW_H 1344