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