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