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