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