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 BTextWidget* ActiveTextWidget() { return fActiveTextWidget; }; 418 void SetActiveTextWidget(BTextWidget* w) { fActiveTextWidget = w; }; 419 420 protected: 421 // view setup 422 virtual void SetUpDefaultColumnsIfNeeded(); 423 424 virtual EntryListBase* InitDirentIterator(const entry_ref*); 425 // sets up an entry iterator for _add_poses_ 426 // overriden by QueryPoseView, etc. to provide different iteration 427 virtual void ReturnDirentIterator(EntryListBase* iterator); 428 // returns the entry iterator after _add_poses_ is done 429 430 void Cleanup(bool doAll = false); 431 // clean up poses 432 void NewFolder(const BMessage*); 433 // create a new folder, optionally specify a location 434 435 void NewFileFromTemplate(const BMessage*); 436 // create a new file based on a template, optionally specify 437 // a location 438 439 void ShowContextMenu(BPoint); 440 441 // scripting handlers 442 virtual bool HandleScriptingMessage(BMessage* message); 443 bool SetProperty(BMessage* message, BMessage* specifier, int32 form, 444 const char* property, BMessage* reply); 445 bool GetProperty(BMessage*, int32, const char*, BMessage*); 446 bool CreateProperty(BMessage* message, BMessage* specifier, int32, 447 const char*, BMessage* reply); 448 bool ExecuteProperty(BMessage* specifier, int32, const char*, 449 BMessage* reply); 450 bool CountProperty(BMessage*, int32, const char*, BMessage*); 451 bool DeleteProperty(BMessage*, int32, const char*, BMessage*); 452 453 void ClearPoses(); 454 // remove all the current poses from the view 455 456 // pose info read/write calls 457 void ReadPoseInfo(Model*, PoseInfo*); 458 ExtendedPoseInfo* ReadExtendedPoseInfo(Model*); 459 460 void _CheckPoseSortOrder(PoseList* list, BPose*, int32 index); 461 462 // pose creation 463 BPose* EntryCreated(const node_ref*, const node_ref*, const char*, 464 int32* index = 0); 465 466 void AddPoseToList(PoseList* list, bool visibleList, 467 bool insertionSort, BPose* pose, BRect&viewBounds, 468 float& listViewScrollBy, bool forceDraw, int32* indexPtr = NULL); 469 BPose* CreatePose(Model*, PoseInfo*, bool insertionSort = true, 470 int32* index = 0, BRect* boundsPointer = 0, bool forceDraw = true); 471 virtual void CreatePoses(Model**models, PoseInfo* poseInfoArray, 472 int32 count, BPose** resultingPoses, bool insertionSort = true, 473 int32* lastPoseIndexPointer = 0, BRect* boundsPointer = 0, 474 bool forceDraw = false); 475 virtual bool ShouldShowPose(const Model*, const PoseInfo*); 476 // filter, subclasses override to control which poses show up 477 // subclasses should always call inherited 478 void CreateVolumePose(BVolume*, bool watchIndividually); 479 480 void CreateTrashPose(); 481 482 virtual bool AddPosesThreadValid(const entry_ref*) const; 483 // verifies whether or not the current set of AddPoses threads 484 // are valid and allowed to be adding poses -- returns false 485 // in the case where the directory has been switched while 486 // populating the view 487 488 virtual void AddPoses(Model* model = NULL); 489 // if <model> is zero, PoseView has other means of iterating 490 // through all the entries thaat it adds 491 492 virtual void AddRootPoses(bool watchIndividually, bool mountShared); 493 // watchIndividually is used when placing a volume pose onto 494 // the Desktop where unlike in the Root window it will not be 495 // watched by the folder representing root. If set, each volume 496 // will therefore be watched individually 497 virtual void RemoveRootPoses(); 498 virtual void AddTrashPoses(); 499 500 virtual bool DeletePose(const node_ref*, BPose* pose = NULL, 501 int32 index = 0); 502 virtual void DeleteSymLinkPoseTarget(const node_ref* itemNode, 503 BPose* pose, int32 index); 504 // the pose itself wasn't deleted but it's target node was - the 505 // pose must be a symlink 506 static void PoseHandleDeviceUnmounted(BPose* pose, Model* model, 507 int32 index, BPoseView* poseView, dev_t device); 508 static void RemoveNonBootDesktopModels(BPose*, Model* model, int32, 509 BPoseView* poseView, dev_t); 510 511 // pose placement 512 void CheckAutoPlacedPoses(); 513 // find poses that need placing and place them in a new spot 514 void PlacePose(BPose*, BRect&); 515 // find a new place for a pose, starting at fHintLocation 516 // and place it 517 bool IsValidLocation(const BPose* pose); 518 bool IsValidLocation(const BRect& rect); 519 status_t GetDeskbarFrame(BRect* frame); 520 bool SlotOccupied(BRect poseRect, BRect viewBounds) const; 521 void NextSlot(BPose*, BRect&poseRect, BRect viewBounds); 522 void TrySettingPoseLocation(BNode* node, BPoint point); 523 BPoint PinToGrid(BPoint, BPoint grid, BPoint offset) const; 524 525 // zombie pose handling 526 Model* FindZombie(const node_ref*, int32* index = 0); 527 BPose* ConvertZombieToPose(Model* zombie, int32 index); 528 529 // pose handling 530 BRect CalcPoseRect(const BPose*, int32 index, 531 bool firstColumnOnly = false) const; 532 BRect CalcPoseRectIcon(const BPose*) const; 533 BRect CalcPoseRectList(const BPose*, int32 index, 534 bool firstColumnOnly = false) const; 535 void DrawPose(BPose*, int32 index, bool fullDraw = true); 536 void DrawViewCommon(const BRect&updateRect); 537 538 // pose list handling 539 int32 BSearchList(PoseList* poseList, const BPose*, int32* index, 540 int32 oldIndex); 541 void InsertPoseAfter(BPose* pose, int32* index, int32 orientation, 542 BRect* invalidRect); 543 // does a CopyBits to scroll poses making room for a new pose, 544 // returns rectangle that needs invalidating 545 void CloseGapInList(BRect* invalidRect); 546 int32 FirstIndexAtOrBelow(int32 y, bool constrainIndex = true) const; 547 void AddToVSList(BPose*); 548 int32 RemoveFromVSList(const BPose*); 549 BPose* FindNearbyPose(char arrow, int32* index); 550 BPose* FindBestMatch(int32* index); 551 BPose* FindNextMatch(int32* index, bool reverse = false); 552 553 // node monitoring calls 554 virtual void StartWatching(); 555 virtual void StopWatching(); 556 557 status_t WatchNewNode(const node_ref* item); 558 // the above would ideally be the only call of these three and 559 // it would be a virtual, overriding the specific watch mask in 560 // query pose view, etc. however we need to call WatchNewNode 561 // from inside AddPosesTask while the window is unlocked - we 562 // have to use the static and a cached messenger and masks. 563 static status_t WatchNewNode(const node_ref*, uint32, BMessenger); 564 virtual uint32 WatchNewNodeMask(); 565 // override to change different watch modes for query pose 566 // view, etc. 567 568 // drag&drop handling 569 static bool EachItemInDraggedSelection(const BMessage* message, 570 bool (*)(BPose*, BPoseView*, void*), BPoseView* poseView, 571 void* = NULL); 572 // iterates through each pose in current selectiond in the source 573 // window of the current drag message; locks the window 574 // add const version 575 BRect GetDragRect(int32 clickedPoseIndex); 576 BBitmap* MakeDragBitmap(BRect dragRect, BPoint clickedPoint, 577 int32 clickedPoseIndex, BPoint&offset); 578 static bool FindDragNDropAction(const BMessage* dragMessage, 579 bool&canCopy, bool&canMove, bool&canLink, bool&canErase); 580 581 static bool CanTrashForeignDrag(const Model*); 582 static bool CanCopyOrMoveForeignDrag(const Model*, const BMessage*); 583 static bool DragSelectionContains(const BPose* target, 584 const BMessage* dragMessage); 585 static status_t CreateClippingFile(BPoseView* poseView, BFile&result, 586 char* resultingName, BDirectory* directory, BMessage* message, 587 const char* fallbackName, bool setLocation = false, 588 BPoint dropPoint = BPoint(0, 0)); 589 590 // opening files, lanunching 591 void OpenSelectionCommon(BPose*, int32*, bool); 592 // used by OpenSelection and OpenSelectionUsing 593 static void LaunchAppWithSelection(Model*, const BMessage*, 594 bool checkTypes = true); 595 596 // node monitoring calls 597 virtual bool EntryMoved(const BMessage*); 598 virtual bool AttributeChanged(const BMessage*); 599 virtual bool NoticeMetaMimeChanged(const BMessage*); 600 virtual void MetaMimeChanged(const char*, const char*); 601 602 // click handling 603 bool WasDoubleClick(const BPose*, BPoint point, int32 buttons); 604 bool WasClickInPath(const BPose*, int32 index, 605 BPoint mouseLocation) const; 606 607 // selection 608 void SelectPosesListMode(BRect, BList**); 609 void SelectPosesIconMode(BRect, BList**); 610 void AddRemoveSelectionRange(BPoint where, bool extendSelection, 611 BPose* pose); 612 613 void _BeginSelectionRect(const BPoint& point, bool extendSelection); 614 void _UpdateSelectionRect(const BPoint& point); 615 void _EndSelectionRect(); 616 617 // view drawing 618 void SynchronousUpdate(BRect, bool clip = false); 619 620 // scrolling 621 void HandleAutoScroll(); 622 bool CheckAutoScroll(BPoint mouseLoc, bool shouldScroll); 623 624 // view extent handling 625 void RecalcExtent(); 626 void AddToExtent(const BRect&); 627 void ClearExtent(); 628 void RemoveFromExtent(const BRect&); 629 630 virtual void EditQueries(); 631 632 void HandleAttrMenuItemSelected(BMessage*); 633 void TryUpdatingBrokenLinks(); 634 // ran a little after a volume gets mounted 635 636 void MapToNewIconMode(BPose*, BPoint oldGrid, BPoint oldOffset); 637 void ResetOrigin(); 638 void PinPointToValidRange(BPoint&); 639 // used to ensure pose locations make sense after getting them 640 // in pose info from attributes, etc. 641 642 void FinishPendingScroll(float&listViewScrollBy, BRect bounds); 643 // utility call for CreatePoses 644 645 // background AddPoses task calls 646 static status_t AddPosesTask(void*); 647 virtual void AddPosesCompleted(); 648 bool IsValidAddPosesThread(thread_id) const; 649 650 // typeahead filtering 651 void EnsurePoseUnselected(BPose* pose); 652 void RemoveFilteredPose(BPose* pose, int32 index); 653 void FilterChanged(); 654 void UpdateAfterFilterChange(); 655 bool FilterPose(BPose* pose); 656 void StartFiltering(); 657 void StopFiltering(); 658 void ClearFilter(); 659 PoseList* CurrentPoseList() const; 660 661 // misc 662 BList* GetDropPointList(BPoint dropPoint, BPoint startPoint, 663 const PoseList*, bool sourceInListMode, bool dropOnGrid) const; 664 void SendSelectionAsRefs(uint32 what, bool onlyQueries = false); 665 void MoveListToTrash(BObjectList<entry_ref>*, bool selectNext, 666 bool deleteDirectly); 667 void Delete(BObjectList<entry_ref>*, bool selectNext, bool askUser); 668 void Delete(const entry_ref&ref, bool selectNext, bool askUser); 669 void RestoreItemsFromTrash(BObjectList<entry_ref>*, bool selectNext); 670 671 void WatchParentOf(const entry_ref*); 672 void StopWatchingParentsOf(const entry_ref*); 673 674 void ExcludeTrashFromSelection(); 675 676 private: 677 void DrawOpenAnimation(BRect); 678 679 void MoveSelectionOrEntryToTrash(const entry_ref* ref, bool selectNext); 680 void _ResetStartOffset(); 681 682 protected: 683 struct node_ref_key { 684 node_ref_key() {} 685 node_ref_key(const node_ref& value) : value(value) {} 686 687 uint32 GetHashCode() const 688 { 689 return (uint32)value.device ^ (uint32)value.node; 690 } 691 692 node_ref_key operator=(const node_ref_key& other) 693 { 694 value = other.value; 695 return *this; 696 } 697 698 bool operator==(const node_ref_key& other) const 699 { 700 return (value == other.value); 701 } 702 703 bool operator!=(const node_ref_key& other) const 704 { 705 return (value != other.value); 706 } 707 708 node_ref value; 709 }; 710 711 protected: 712 TScrollBar* fHScrollBar; 713 BScrollBar* fVScrollBar; 714 Model* fModel; 715 BPose* fActivePose; 716 BRect fExtent; 717 // the following should probably be just member lists, not pointers 718 PoseList* fPoseList; 719 PoseList* fFilteredPoseList; 720 PoseList* fVSPoseList; 721 PoseList* fSelectionList; 722 HashSet<node_ref_key> fInsertedNodes; 723 BObjectList<BString> fMimeTypesInSelectionCache; 724 // used for mime string based icon highliting during a drag 725 BObjectList<Model>* fZombieList; 726 PendingNodeMonitorCache pendingNodeMonitorCache; 727 BObjectList<BColumn>* fColumnList; 728 BObjectList<BString>* fMimeTypeList; 729 BObjectList<Model>* fBrokenLinks; 730 bool fMimeTypeListIsDirty; 731 BViewState* fViewState; 732 bool fStateNeedsSaving; 733 BCountView* fCountView; 734 float fListElemHeight; 735 float fIconPoseHeight; 736 BPose* fDropTarget; 737 BPose* fAlreadySelectedDropTarget; 738 BLooper* fSelectionHandler; 739 BPoint fLastClickPoint; 740 int32 fLastClickButtons; 741 const BPose* fLastClickedPose; 742 BPoint fLastLeftTop; 743 BRect fLastExtent; 744 BTitleView* fTitleView; 745 BRefFilter* fRefFilter; 746 BPoint fGrid; 747 BPoint fOffset; 748 BPoint fHintLocation; 749 float fAutoScrollInc; 750 int32 fAutoScrollState; 751 std::set<thread_id> fAddPosesThreads; 752 bool fWidgetTextOutline; 753 const BPose* fSelectionPivotPose; 754 const BPose* fRealPivotPose; 755 BMessageRunner* fKeyRunner; 756 bool fTrackRightMouseUp; 757 bool fTrackMouseUp; 758 759 struct SelectionRectInfo { 760 SelectionRectInfo() 761 : 762 isDragging(false), 763 selection(NULL) 764 { 765 } 766 767 bool isDragging; 768 BRect rect; 769 BRect lastRect; 770 BPoint startPoint; 771 BPoint lastPoint; 772 BList* selection; 773 }; 774 SelectionRectInfo fSelectionRectInfo; 775 776 bool fSelectionVisible : 1; 777 bool fMultipleSelection : 1; 778 bool fDragEnabled : 1; 779 bool fDropEnabled : 1; 780 bool fSelectionRectEnabled : 1; 781 bool fAlwaysAutoPlace : 1; 782 bool fAllowPoseEditing : 1; 783 bool fSelectionChangedHook : 1; 784 // get rid of this 785 bool fSavePoseLocations : 1; 786 bool fShowHideSelection : 1; 787 bool fOkToMapIcons : 1; 788 bool fEnsurePosesVisible : 1; 789 bool fShouldAutoScroll : 1; 790 bool fIsDesktopWindow : 1; 791 bool fIsWatchingDateFormatChange : 1; 792 bool fHasPosesInClipboard : 1; 793 bool fCursorCheck : 1; 794 bool fFiltering : 1; 795 796 BObjectList<BString> fFilterStrings; 797 int32 fLastFilterStringCount; 798 int32 fLastFilterStringLength; 799 800 BRect fStartFrame; 801 802 static float sFontHeight; 803 static font_height sFontInfo; 804 static BString sMatchString; 805 // used for typeahead - should be replaced by a typeahead state 806 807 bigtime_t fLastKeyTime; 808 bigtime_t fLastDeskbarFrameCheckTime; 809 BRect fDeskbarFrame; 810 811 static OffscreenBitmap* sOffscreen; 812 813 BTextWidget* fTextWidgetToCheck; 814 BTextWidget* fActiveTextWidget; 815 816 typedef BView _inherited; 817 }; 818 819 820 class TScrollBar : public BScrollBar { 821 public: 822 TScrollBar(const char*, BView*, float, float); 823 void SetTitleView(BView*); 824 825 // BScrollBar overrides 826 virtual void ValueChanged(float); 827 828 private: 829 BView* fTitleView; 830 831 typedef BScrollBar _inherited; 832 }; 833 834 835 class TPoseViewFilter : public BMessageFilter { 836 public: 837 TPoseViewFilter(BPoseView* pose); 838 ~TPoseViewFilter(); 839 840 filter_result Filter(BMessage*, BHandler**); 841 842 private: 843 filter_result ObjectDropFilter(BMessage*, BHandler**); 844 845 BPoseView* fPoseView; 846 }; 847 848 849 extern bool 850 ClearViewOriginOne(const char* name, uint32 type, off_t size, void* data, 851 void* params); 852 853 854 // inlines follow 855 856 857 inline BContainerWindow* 858 BPoseView::ContainerWindow() const 859 { 860 return dynamic_cast<BContainerWindow*>(Window()); 861 } 862 863 864 inline Model* 865 BPoseView::TargetModel() const 866 { 867 return fModel; 868 } 869 870 871 inline float 872 BPoseView::ListElemHeight() const 873 { 874 return fListElemHeight; 875 } 876 877 878 inline float 879 BPoseView::IconPoseHeight() const 880 { 881 return fIconPoseHeight; 882 } 883 884 885 inline uint32 886 BPoseView::IconSizeInt() const 887 { 888 return fViewState->IconSize(); 889 } 890 891 892 inline icon_size 893 BPoseView::IconSize() const 894 { 895 return (icon_size)fViewState->IconSize(); 896 } 897 898 899 inline PoseList* 900 BPoseView::SelectionList() const 901 { 902 return fSelectionList; 903 } 904 905 906 inline BObjectList<BString>* 907 BPoseView::MimeTypesInSelection() 908 { 909 return &fMimeTypesInSelectionCache; 910 } 911 912 913 inline BScrollBar* 914 BPoseView::HScrollBar() const 915 { 916 return fHScrollBar; 917 } 918 919 920 inline BScrollBar* 921 BPoseView::VScrollBar() const 922 { 923 return fVScrollBar; 924 } 925 926 927 inline BCountView* 928 BPoseView::CountView() const 929 { 930 return fCountView; 931 } 932 933 934 inline BTitleView* 935 BPoseView::TitleView() const 936 { 937 return fTitleView; 938 } 939 940 941 inline bool 942 BPoseView::StateNeedsSaving() 943 { 944 return fStateNeedsSaving || fViewState->StateNeedsSaving(); 945 } 946 947 948 inline uint32 949 BPoseView::ViewMode() const 950 { 951 return fViewState->ViewMode(); 952 } 953 954 955 inline font_height 956 BPoseView::FontInfo() const 957 { 958 return sFontInfo; 959 } 960 961 962 inline float 963 BPoseView::FontHeight() const 964 { 965 return sFontHeight; 966 } 967 968 969 inline BPose* 970 BPoseView::ActivePose() const 971 { 972 return fActivePose; 973 } 974 975 976 inline void 977 BPoseView::DisableSaveLocation() 978 { 979 fSavePoseLocations = false; 980 } 981 982 983 inline bool 984 BPoseView::IsFilePanel() const 985 { 986 return false; 987 } 988 989 990 inline bool 991 BPoseView::IsDesktopWindow() const 992 { 993 return fIsDesktopWindow; 994 } 995 996 997 inline bool 998 BPoseView::IsDesktopView() const 999 { 1000 return false; 1001 } 1002 1003 1004 inline uint32 1005 BPoseView::PrimarySort() const 1006 { 1007 return fViewState->PrimarySort(); 1008 } 1009 1010 1011 inline uint32 1012 BPoseView::PrimarySortType() const 1013 { 1014 return fViewState->PrimarySortType(); 1015 } 1016 1017 1018 inline uint32 1019 BPoseView::SecondarySort() const 1020 { 1021 return fViewState->SecondarySort(); 1022 } 1023 1024 1025 inline uint32 1026 BPoseView::SecondarySortType() const 1027 { 1028 return fViewState->SecondarySortType(); 1029 } 1030 1031 1032 inline bool 1033 BPoseView::ReverseSort() const 1034 { 1035 return fViewState->ReverseSort(); 1036 } 1037 1038 1039 inline void 1040 BPoseView::SetShowHideSelection(bool on) 1041 { 1042 fShowHideSelection = on; 1043 } 1044 1045 1046 inline void 1047 BPoseView::SetIconMapping(bool on) 1048 { 1049 fOkToMapIcons = on; 1050 } 1051 1052 1053 inline void 1054 BPoseView::AddToExtent(const BRect&rect) 1055 { 1056 fExtent = fExtent | rect; 1057 } 1058 1059 1060 inline void 1061 BPoseView::ClearExtent() 1062 { 1063 fExtent.Set(INT32_MAX, INT32_MAX, INT32_MIN, INT32_MIN); 1064 } 1065 1066 1067 inline int32 1068 BPoseView::CountColumns() const 1069 { 1070 return fColumnList->CountItems(); 1071 } 1072 1073 1074 inline float 1075 BPoseView::StartOffset() const 1076 { 1077 return kListOffset + ListIconSize() + kMiniIconSeparator + 1; 1078 } 1079 1080 1081 inline int32 1082 BPoseView::IndexOfColumn(const BColumn* column) const 1083 { 1084 return fColumnList->IndexOf(const_cast<BColumn*>(column)); 1085 } 1086 1087 1088 inline int32 1089 BPoseView::IndexOfPose(const BPose* pose) const 1090 { 1091 return CurrentPoseList()->IndexOf(pose); 1092 } 1093 1094 1095 inline BPose* 1096 BPoseView::PoseAtIndex(int32 index) const 1097 { 1098 return CurrentPoseList()->ItemAt(index); 1099 } 1100 1101 1102 inline BColumn* 1103 BPoseView::ColumnAt(int32 index) const 1104 { 1105 return fColumnList->ItemAt(index); 1106 } 1107 1108 1109 inline BColumn* 1110 BPoseView::FirstColumn() const 1111 { 1112 return fColumnList->FirstItem(); 1113 } 1114 1115 1116 inline BColumn* 1117 BPoseView::LastColumn() const 1118 { 1119 return fColumnList->LastItem(); 1120 } 1121 1122 1123 inline int32 1124 BPoseView::CountItems() const 1125 { 1126 return CurrentPoseList()->CountItems(); 1127 } 1128 1129 1130 inline void 1131 BPoseView::SetMultipleSelection(bool state) 1132 { 1133 fMultipleSelection = state; 1134 } 1135 1136 1137 inline void 1138 BPoseView::SetSelectionChangedHook(bool state) 1139 { 1140 fSelectionChangedHook = state; 1141 } 1142 1143 1144 inline void 1145 BPoseView::SetAutoScroll(bool state) 1146 { 1147 fShouldAutoScroll = state; 1148 } 1149 1150 1151 inline void 1152 BPoseView::SetPoseEditing(bool state) 1153 { 1154 fAllowPoseEditing = state; 1155 } 1156 1157 1158 inline void 1159 BPoseView::SetDragEnabled(bool state) 1160 { 1161 fDragEnabled = state; 1162 } 1163 1164 1165 inline void 1166 BPoseView::SetDropEnabled(bool state) 1167 { 1168 fDropEnabled = state; 1169 } 1170 1171 1172 inline void 1173 BPoseView::SetSelectionRectEnabled(bool state) 1174 { 1175 fSelectionRectEnabled = state; 1176 } 1177 1178 1179 inline void 1180 BPoseView::SetAlwaysAutoPlace(bool state) 1181 { 1182 fAlwaysAutoPlace = state; 1183 } 1184 1185 1186 inline void 1187 BPoseView::SetEnsurePosesVisible(bool state) 1188 { 1189 fEnsurePosesVisible = state; 1190 } 1191 1192 1193 inline void 1194 BPoseView::SetSelectionHandler(BLooper* looper) 1195 { 1196 fSelectionHandler = looper; 1197 } 1198 1199 1200 inline void 1201 TScrollBar::SetTitleView(BView* view) 1202 { 1203 fTitleView = view; 1204 } 1205 1206 1207 inline void 1208 BPoseView::SetRefFilter(BRefFilter* filter) 1209 { 1210 fRefFilter = filter; 1211 if (filter != NULL) 1212 FilterChanged(); 1213 } 1214 1215 1216 inline BRefFilter* 1217 BPoseView::RefFilter() const 1218 { 1219 return fRefFilter; 1220 } 1221 1222 1223 inline BPose* 1224 BPoseView::FindPose(const Model* model, int32* index) const 1225 { 1226 return CurrentPoseList()->FindPose(model, index); 1227 } 1228 1229 1230 inline BPose* 1231 BPoseView::FindPose(const node_ref* node, int32* index) const 1232 { 1233 return CurrentPoseList()->FindPose(node, index); 1234 } 1235 1236 1237 inline BPose* 1238 BPoseView::FindPose(const entry_ref* entry, int32* index) const 1239 { 1240 return CurrentPoseList()->FindPose(entry, index); 1241 } 1242 1243 1244 inline bool 1245 BPoseView::HasPosesInClipboard() 1246 { 1247 return fHasPosesInClipboard; 1248 } 1249 1250 1251 inline void 1252 BPoseView::SetHasPosesInClipboard(bool hasPoses) 1253 { 1254 fHasPosesInClipboard = hasPoses; 1255 } 1256 1257 1258 inline PoseList* 1259 BPoseView::CurrentPoseList() const 1260 { 1261 return fFiltering ? fFilteredPoseList : fPoseList; 1262 } 1263 1264 1265 template<class Param1> 1266 void 1267 EachTextWidget(BPose* pose, BPoseView* poseView, 1268 void (*func)(BTextWidget*, BPose*, BPoseView*, BColumn*, Param1), Param1 p1) 1269 { 1270 for (int32 index = 0; ;index++) { 1271 BColumn* column = poseView->ColumnAt(index); 1272 if (column == NULL) 1273 break; 1274 1275 BTextWidget* widget = pose->WidgetFor(column->AttrHash()); 1276 if (widget != NULL) 1277 (func)(widget, pose, poseView, column, p1); 1278 } 1279 } 1280 1281 1282 template<class Param1, class Param2> 1283 void 1284 EachTextWidget(BPose* pose, BPoseView* poseView, 1285 void (*func)(BTextWidget*, BPose*, BPoseView*, BColumn*, 1286 Param1, Param2), Param1 p1, Param2 p2) 1287 { 1288 for (int32 index = 0; ;index++) { 1289 BColumn* column = poseView->ColumnAt(index); 1290 if (column == NULL) 1291 break; 1292 1293 BTextWidget* widget = pose->WidgetFor(column->AttrHash()); 1294 if (widget != NULL) 1295 (func)(widget, pose, poseView, column, p1, p2); 1296 } 1297 } 1298 1299 1300 template<class Result, class Param1, class Param2> 1301 Result 1302 WhileEachTextWidget(BPose* pose, BPoseView* poseView, 1303 Result (*func)(BTextWidget*, BPose*, BPoseView*, BColumn*, 1304 Param1, Param2), Param1 p1, Param2 p2) 1305 { 1306 for (int32 index = 0; ;index++) { 1307 BColumn* column = poseView->ColumnAt(index); 1308 if (column == NULL) 1309 break; 1310 1311 BTextWidget* widget = pose->WidgetFor(column->AttrHash()); 1312 if (widget != NULL) { 1313 Result result = (func)(widget, pose, poseView, column, p1, p2); 1314 if (result != 0) 1315 return result; 1316 } 1317 } 1318 1319 return 0; 1320 } 1321 1322 1323 } // namespace BPrivate 1324 1325 using namespace BPrivate; 1326 1327 1328 #endif // _POSE_VIEW_H 1329