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