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