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