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 bool fTrackMouseUp; 749 750 struct SelectionRectInfo { 751 SelectionRectInfo() 752 : 753 isDragging(false), 754 selection(NULL) 755 { 756 } 757 758 bool isDragging; 759 BRect rect; 760 BRect lastRect; 761 BPoint startPoint; 762 BPoint lastPoint; 763 BList* selection; 764 }; 765 SelectionRectInfo fSelectionRectInfo; 766 767 bool fSelectionVisible : 1; 768 bool fMultipleSelection : 1; 769 bool fDragEnabled : 1; 770 bool fDropEnabled : 1; 771 bool fSelectionRectEnabled : 1; 772 bool fAlwaysAutoPlace : 1; 773 bool fAllowPoseEditing : 1; 774 bool fSelectionChangedHook : 1; 775 // get rid of this 776 bool fSavePoseLocations : 1; 777 bool fShowHideSelection : 1; 778 bool fOkToMapIcons : 1; 779 bool fEnsurePosesVisible : 1; 780 bool fShouldAutoScroll : 1; 781 bool fIsDesktopWindow : 1; 782 bool fIsWatchingDateFormatChange : 1; 783 bool fHasPosesInClipboard : 1; 784 bool fCursorCheck : 1; 785 bool fFiltering : 1; 786 787 BObjectList<BString> fFilterStrings; 788 int32 fLastFilterStringCount; 789 int32 fLastFilterStringLength; 790 791 BRect fStartFrame; 792 793 static float sFontHeight; 794 static font_height sFontInfo; 795 static BFont sCurrentFont; 796 static BString sMatchString; 797 // used for typeahead - should be replaced by a typeahead state 798 799 bigtime_t fLastKeyTime; 800 bigtime_t fLastDeskbarFrameCheckTime; 801 BRect fDeskbarFrame; 802 803 static OffscreenBitmap* sOffscreen; 804 805 BTextWidget* fTextWidgetToCheck; 806 807 typedef BView _inherited; 808 }; 809 810 811 class TScrollBar : public BScrollBar { 812 public: 813 TScrollBar(const char*, BView*, float, float); 814 void SetTitleView(BView*); 815 816 // BScrollBar overrides 817 virtual void ValueChanged(float); 818 819 private: 820 BView* fTitleView; 821 822 typedef BScrollBar _inherited; 823 }; 824 825 826 class TPoseViewFilter : public BMessageFilter { 827 public: 828 TPoseViewFilter(BPoseView* pose); 829 ~TPoseViewFilter(); 830 831 filter_result Filter(BMessage*, BHandler**); 832 833 private: 834 filter_result ObjectDropFilter(BMessage*, BHandler**); 835 836 BPoseView* fPoseView; 837 }; 838 839 840 extern bool 841 ClearViewOriginOne(const char* name, uint32 type, off_t size, void* data, 842 void* params); 843 844 845 // inlines follow 846 847 848 inline BContainerWindow* 849 BPoseView::ContainerWindow() const 850 { 851 return dynamic_cast<BContainerWindow*>(Window()); 852 } 853 854 855 inline Model* 856 BPoseView::TargetModel() const 857 { 858 return fModel; 859 } 860 861 862 inline float 863 BPoseView::ListElemHeight() const 864 { 865 return fListElemHeight; 866 } 867 868 869 inline float 870 BPoseView::IconPoseHeight() const 871 { 872 return fIconPoseHeight; 873 } 874 875 876 inline uint32 877 BPoseView::IconSizeInt() const 878 { 879 return fViewState->IconSize(); 880 } 881 882 883 inline icon_size 884 BPoseView::IconSize() const 885 { 886 return (icon_size)fViewState->IconSize(); 887 } 888 889 890 inline PoseList* 891 BPoseView::SelectionList() const 892 { 893 return fSelectionList; 894 } 895 896 897 inline BObjectList<BString>* 898 BPoseView::MimeTypesInSelection() 899 { 900 return &fMimeTypesInSelectionCache; 901 } 902 903 904 inline BScrollBar* 905 BPoseView::HScrollBar() const 906 { 907 return fHScrollBar; 908 } 909 910 911 inline BScrollBar* 912 BPoseView::VScrollBar() const 913 { 914 return fVScrollBar; 915 } 916 917 918 inline BCountView* 919 BPoseView::CountView() const 920 { 921 return fCountView; 922 } 923 924 925 inline BTitleView* 926 BPoseView::TitleView() const 927 { 928 return fTitleView; 929 } 930 931 932 inline bool 933 BPoseView::StateNeedsSaving() 934 { 935 return fStateNeedsSaving || fViewState->StateNeedsSaving(); 936 } 937 938 939 inline uint32 940 BPoseView::ViewMode() const 941 { 942 return fViewState->ViewMode(); 943 } 944 945 946 inline font_height 947 BPoseView::FontInfo() const 948 { 949 return sFontInfo; 950 } 951 952 953 inline float 954 BPoseView::FontHeight() const 955 { 956 return sFontHeight; 957 } 958 959 960 inline BPose* 961 BPoseView::ActivePose() const 962 { 963 return fActivePose; 964 } 965 966 967 inline void 968 BPoseView::DisableSaveLocation() 969 { 970 fSavePoseLocations = false; 971 } 972 973 974 inline bool 975 BPoseView::IsFilePanel() const 976 { 977 return false; 978 } 979 980 981 inline bool 982 BPoseView::IsDesktopWindow() const 983 { 984 return fIsDesktopWindow; 985 } 986 987 988 inline bool 989 BPoseView::IsDesktopView() const 990 { 991 return false; 992 } 993 994 995 inline uint32 996 BPoseView::PrimarySort() const 997 { 998 return fViewState->PrimarySort(); 999 } 1000 1001 1002 inline uint32 1003 BPoseView::PrimarySortType() const 1004 { 1005 return fViewState->PrimarySortType(); 1006 } 1007 1008 1009 inline uint32 1010 BPoseView::SecondarySort() const 1011 { 1012 return fViewState->SecondarySort(); 1013 } 1014 1015 1016 inline uint32 1017 BPoseView::SecondarySortType() const 1018 { 1019 return fViewState->SecondarySortType(); 1020 } 1021 1022 1023 inline bool 1024 BPoseView::ReverseSort() const 1025 { 1026 return fViewState->ReverseSort(); 1027 } 1028 1029 1030 inline void 1031 BPoseView::SetShowHideSelection(bool on) 1032 { 1033 fShowHideSelection = on; 1034 } 1035 1036 1037 inline void 1038 BPoseView::SetIconMapping(bool on) 1039 { 1040 fOkToMapIcons = on; 1041 } 1042 1043 1044 inline void 1045 BPoseView::AddToExtent(const BRect&rect) 1046 { 1047 fExtent = fExtent | rect; 1048 } 1049 1050 1051 inline void 1052 BPoseView::ClearExtent() 1053 { 1054 fExtent.Set(INT32_MAX, INT32_MAX, INT32_MIN, INT32_MIN); 1055 } 1056 1057 1058 inline int32 1059 BPoseView::CountColumns() const 1060 { 1061 return fColumnList->CountItems(); 1062 } 1063 1064 1065 inline float 1066 BPoseView::StartOffset() const 1067 { 1068 return kListOffset + ListIconSize() + kMiniIconSeparator + 1; 1069 } 1070 1071 1072 inline int32 1073 BPoseView::IndexOfColumn(const BColumn* column) const 1074 { 1075 return fColumnList->IndexOf(const_cast<BColumn*>(column)); 1076 } 1077 1078 1079 inline int32 1080 BPoseView::IndexOfPose(const BPose* pose) const 1081 { 1082 return CurrentPoseList()->IndexOf(pose); 1083 } 1084 1085 1086 inline BPose* 1087 BPoseView::PoseAtIndex(int32 index) const 1088 { 1089 return CurrentPoseList()->ItemAt(index); 1090 } 1091 1092 1093 inline BColumn* 1094 BPoseView::ColumnAt(int32 index) const 1095 { 1096 return fColumnList->ItemAt(index); 1097 } 1098 1099 1100 inline BColumn* 1101 BPoseView::FirstColumn() const 1102 { 1103 return fColumnList->FirstItem(); 1104 } 1105 1106 1107 inline BColumn* 1108 BPoseView::LastColumn() const 1109 { 1110 return fColumnList->LastItem(); 1111 } 1112 1113 1114 inline int32 1115 BPoseView::CountItems() const 1116 { 1117 return CurrentPoseList()->CountItems(); 1118 } 1119 1120 1121 inline void 1122 BPoseView::SetMultipleSelection(bool state) 1123 { 1124 fMultipleSelection = state; 1125 } 1126 1127 1128 inline void 1129 BPoseView::SetSelectionChangedHook(bool state) 1130 { 1131 fSelectionChangedHook = state; 1132 } 1133 1134 1135 inline void 1136 BPoseView::SetAutoScroll(bool state) 1137 { 1138 fShouldAutoScroll = state; 1139 } 1140 1141 1142 inline void 1143 BPoseView::SetPoseEditing(bool state) 1144 { 1145 fAllowPoseEditing = state; 1146 } 1147 1148 1149 inline void 1150 BPoseView::SetDragEnabled(bool state) 1151 { 1152 fDragEnabled = state; 1153 } 1154 1155 1156 inline void 1157 BPoseView::SetDropEnabled(bool state) 1158 { 1159 fDropEnabled = state; 1160 } 1161 1162 1163 inline void 1164 BPoseView::SetSelectionRectEnabled(bool state) 1165 { 1166 fSelectionRectEnabled = state; 1167 } 1168 1169 1170 inline void 1171 BPoseView::SetAlwaysAutoPlace(bool state) 1172 { 1173 fAlwaysAutoPlace = state; 1174 } 1175 1176 1177 inline void 1178 BPoseView::SetEnsurePosesVisible(bool state) 1179 { 1180 fEnsurePosesVisible = state; 1181 } 1182 1183 1184 inline void 1185 BPoseView::SetSelectionHandler(BLooper* looper) 1186 { 1187 fSelectionHandler = looper; 1188 } 1189 1190 1191 inline void 1192 TScrollBar::SetTitleView(BView* view) 1193 { 1194 fTitleView = view; 1195 } 1196 1197 1198 inline void 1199 BPoseView::SetRefFilter(BRefFilter* filter) 1200 { 1201 fRefFilter = filter; 1202 if (filter != NULL) 1203 FilterChanged(); 1204 } 1205 1206 1207 inline BRefFilter* 1208 BPoseView::RefFilter() const 1209 { 1210 return fRefFilter; 1211 } 1212 1213 1214 inline BPose* 1215 BPoseView::FindPose(const Model* model, int32* index) const 1216 { 1217 return CurrentPoseList()->FindPose(model, index); 1218 } 1219 1220 1221 inline BPose* 1222 BPoseView::FindPose(const node_ref* node, int32* index) const 1223 { 1224 return CurrentPoseList()->FindPose(node, index); 1225 } 1226 1227 1228 inline BPose* 1229 BPoseView::FindPose(const entry_ref* entry, int32* index) const 1230 { 1231 return CurrentPoseList()->FindPose(entry, index); 1232 } 1233 1234 1235 inline bool 1236 BPoseView::HasPosesInClipboard() 1237 { 1238 return fHasPosesInClipboard; 1239 } 1240 1241 1242 inline void 1243 BPoseView::SetHasPosesInClipboard(bool hasPoses) 1244 { 1245 fHasPosesInClipboard = hasPoses; 1246 } 1247 1248 1249 inline PoseList* 1250 BPoseView::CurrentPoseList() const 1251 { 1252 return fFiltering ? fFilteredPoseList : fPoseList; 1253 } 1254 1255 1256 template<class Param1> 1257 void 1258 EachTextWidget(BPose* pose, BPoseView* poseView, 1259 void (*func)(BTextWidget*, BPose*, BPoseView*, BColumn*, Param1), Param1 p1) 1260 { 1261 for (int32 index = 0; ;index++) { 1262 BColumn* column = poseView->ColumnAt(index); 1263 if (column == NULL) 1264 break; 1265 1266 BTextWidget* widget = pose->WidgetFor(column->AttrHash()); 1267 if (widget != NULL) 1268 (func)(widget, pose, poseView, column, p1); 1269 } 1270 } 1271 1272 1273 template<class Param1, class Param2> 1274 void 1275 EachTextWidget(BPose* pose, BPoseView* poseView, 1276 void (*func)(BTextWidget*, BPose*, BPoseView*, BColumn*, 1277 Param1, Param2), Param1 p1, Param2 p2) 1278 { 1279 for (int32 index = 0; ;index++) { 1280 BColumn* column = poseView->ColumnAt(index); 1281 if (column == NULL) 1282 break; 1283 1284 BTextWidget* widget = pose->WidgetFor(column->AttrHash()); 1285 if (widget != NULL) 1286 (func)(widget, pose, poseView, column, p1, p2); 1287 } 1288 } 1289 1290 1291 template<class Result, class Param1, class Param2> 1292 Result 1293 WhileEachTextWidget(BPose* pose, BPoseView* poseView, 1294 Result (*func)(BTextWidget*, BPose*, BPoseView*, BColumn*, 1295 Param1, Param2), Param1 p1, Param2 p2) 1296 { 1297 for (int32 index = 0; ;index++) { 1298 BColumn* column = poseView->ColumnAt(index); 1299 if (column == NULL) 1300 break; 1301 1302 BTextWidget* widget = pose->WidgetFor(column->AttrHash()); 1303 if (widget != NULL) { 1304 Result result = (func)(widget, pose, poseView, column, p1, p2); 1305 if (result != 0) 1306 return result; 1307 } 1308 } 1309 1310 return 0; 1311 } 1312 1313 1314 } // namespace BPrivate 1315 1316 using namespace BPrivate; 1317 1318 1319 #endif // _POSE_VIEW_H 1320