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