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 Model *TargetModel() const; 123 124 virtual bool IsFilePanel() const; 125 bool IsDesktopWindow() const; 126 virtual bool IsDesktopView() const; 127 128 // state saving/restoring 129 virtual void SaveState(AttributeStreamNode *node); 130 virtual void RestoreState(AttributeStreamNode *); 131 virtual void RestoreColumnState(AttributeStreamNode *); 132 void AddColumnList(BObjectList<BColumn> *list); 133 virtual void SaveColumnState(AttributeStreamNode *); 134 virtual void SavePoseLocations(BRect *frameIfDesktop = NULL); 135 void DisableSaveLocation(); 136 137 virtual void SaveState(BMessage &) const; 138 virtual void RestoreState(const BMessage &); 139 virtual void RestoreColumnState(const BMessage &); 140 virtual void SaveColumnState(BMessage &) const; 141 142 bool StateNeedsSaving(); 143 144 // switch between mini icon mode, icon mode and list mode 145 virtual void SetViewMode(uint32 mode); 146 uint32 ViewMode() const; 147 148 // re-use the pose view for a new directory 149 virtual void SwitchDir(const entry_ref *, 150 AttributeStreamNode *node = NULL); 151 152 // in the rare cases where a pose view needs to be explicitly refreshed 153 // (for instance in a query window with a dynamic date query), this is 154 // used 155 virtual void Refresh(); 156 157 // callbacks 158 virtual void MessageReceived(BMessage *); 159 virtual void AttachedToWindow(); 160 virtual void WindowActivated(bool); 161 virtual void MakeFocus(bool = true); 162 virtual void MouseMoved(BPoint, uint32, const BMessage *); 163 virtual void Draw(BRect update_rect); 164 virtual void DrawAfterChildren(BRect update_rect); 165 virtual void MouseDown(BPoint where); 166 virtual void KeyDown(const char *, int32); 167 virtual void Pulse(); 168 virtual void MoveBy(float, float); 169 virtual void ScrollTo(BPoint point); 170 171 // misc. mode setters 172 void SetMultipleSelection(bool); 173 void SetDragEnabled(bool); 174 void SetDropEnabled(bool); 175 void SetSelectionRectEnabled(bool); 176 void SetAlwaysAutoPlace(bool); 177 void SetSelectionChangedHook(bool); 178 void SetShowHideSelection(bool); 179 void SetEnsurePosesVisible(bool); 180 void SetIconMapping(bool); 181 void SetAutoScroll(bool); 182 void SetPoseEditing(bool); 183 184 void UpdateIcon(BPose *pose); 185 186 // file change notification handler 187 virtual bool FSNotification(const BMessage *); 188 189 // scrollbars 190 virtual void UpdateScrollRange(); 191 virtual void SetScrollBarsTo(BPoint); 192 virtual void AddScrollBars(); 193 BHScrollBar* HScrollBar() const; 194 BScrollBar* VScrollBar() const ; 195 BCountView* CountView() const; 196 void DisableScrollBars(); 197 void EnableScrollBars(); 198 199 // sorting 200 virtual void SortPoses(); 201 void SetPrimarySort(uint32 attrHash); 202 void SetSecondarySort(uint32 attrHash); 203 void SetReverseSort(bool reverse); 204 uint32 PrimarySort() const; 205 uint32 PrimarySortType() const; 206 uint32 SecondarySort() const; 207 uint32 SecondarySortType() const; 208 bool ReverseSort() const; 209 void CheckPoseSortOrder(BPose *, int32 index); 210 void CheckPoseVisibility(BRect * = NULL); 211 // make sure pose fits the screen and/or window bounds if needed 212 213 // view metrics 214 font_height FontInfo() const; 215 // returns height, descent, etc. 216 float FontHeight() const; 217 float ListElemHeight() const; 218 219 void SetIconPoseHeight(); 220 float IconPoseHeight() const; 221 uint32 IconSizeInt() const; 222 icon_size IconSize() const; 223 224 BRect Extent() const; 225 void GetLayoutInfo(uint32 viewMode, BPoint *grid, BPoint *offset) const; 226 227 int32 CountItems() const; 228 void UpdateCount(); 229 230 rgb_color DeskTextColor() const; 231 rgb_color DeskTextBackColor() const; 232 233 bool WidgetTextOutline() const; 234 void SetWidgetTextOutline(bool); 235 // used to not erase when we have a background image and 236 // invalidate instead 237 238 // column handling 239 void ColumnRedraw(BRect updateRect); 240 bool AddColumn(BColumn *, const BColumn *after = NULL); 241 bool RemoveColumn(BColumn *column, bool runAlert); 242 void MoveColumnTo(BColumn *src, BColumn *dest); 243 bool ResizeColumnToWidest(BColumn *column); 244 BPoint ResizeColumn(BColumn *, float, float *lastLineDrawPos = NULL, 245 void (*drawLineFunc)(BPoseView *, BPoint, BPoint) = 0, 246 void (*undrawLineFunc)(BPoseView *, BPoint, BPoint) = 0); 247 // returns the bottom right of the last pose drawn or bottom right of 248 // bounds 249 250 BColumn *ColumnAt(int32 index) const; 251 BColumn *ColumnFor(uint32 attribute_hash) const; 252 BColumn *FirstColumn() const; 253 BColumn *LastColumn() const; 254 int32 IndexOfColumn(const BColumn *) const; 255 int32 CountColumns() const; 256 257 // pose access 258 int32 IndexOfPose(const BPose *) const; 259 BPose *PoseAtIndex(int32 index) const; 260 261 BPose *FindPose(BPoint where, int32 *index = NULL) const; 262 // return pose at location h, v (search list starting from bottom so 263 // drawing and hit detection reflect the same pose ordering) 264 BPose *FindPose(const Model *, int32 *index = NULL) const; 265 BPose *FindPose(const node_ref *, int32 *index = NULL) const; 266 BPose *FindPose(const entry_ref *, int32 *index = NULL) const; 267 BPose *FindPose(const entry_ref *, int32 specifierForm, int32 *index) const; 268 // special form of FindPose used for scripting, <specifierForm> may 269 // ask for previous or next pose 270 BPose *DeepFindPose(const node_ref *node, int32 *index = NULL) const; 271 // same as FindPose, node can be a target of the actual 272 // pose if the pose is a symlink 273 274 void OpenInfoWindows(); 275 void SetDefaultPrinter(); 276 277 void IdentifySelection(); 278 void UnmountSelectedVolumes(); 279 virtual void OpenParent(); 280 281 virtual void OpenSelection(BPose *clicked_pose = NULL, int32 *index = NULL); 282 void OpenSelectionUsing(BPose *clicked_pose = NULL, int32 *index = NULL); 283 // launches the open with window 284 virtual void MoveSelectionTo(BPoint, BPoint, BContainerWindow *); 285 void DuplicateSelection(BPoint *dropStart = NULL, BPoint *dropEnd = NULL); 286 287 // Move to trash calls try to select the next pose in the view when they 288 // are dones 289 virtual void MoveSelectionToTrash(bool selectNext = true); 290 virtual void DeleteSelection(bool selectNext = true, bool askUser = true); 291 virtual void MoveEntryToTrash(const entry_ref *, bool selectNext = true); 292 293 void RestoreSelectionFromTrash(bool selectNext = true); 294 295 // selection 296 PoseList *SelectionList() const; 297 void SelectAll(); 298 void InvertSelection(); 299 int32 SelectMatchingEntries(const BMessage *); 300 void ShowSelectionWindow(); 301 void ClearSelection(); 302 void ShowSelection(bool); 303 void AddRemovePoseFromSelection(BPose *pose, int32 index, bool select); 304 305 BLooper *SelectionHandler(); 306 void SetSelectionHandler(BLooper *); 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 318 // pose handling 319 void ScrollIntoView(BPose *pose, int32 index); 320 void ScrollIntoView(BRect poseRect); 321 void SetActivePose(BPose *); 322 BPose *ActivePose() const; 323 void CommitActivePose(bool saveChanges = true); 324 static bool PoseVisible(const Model *, const PoseInfo *, bool inFilePanel); 325 bool FrameForPose(BPose *targetpose, bool convert, BRect *poseRect); 326 bool CreateSymlinkPoseTarget(Model *symlink); 327 // used to complete a symlink pose; returns true if 328 // target symlink should not be shown 329 void ResetPosePlacementHint(); 330 void PlaceFolder(const entry_ref *, const BMessage *); 331 332 // clipboard handling for poses 333 inline bool HasPosesInClipboard(); 334 inline void SetHasPosesInClipboard(bool hasPoses); 335 void SetPosesClipboardMode(uint32 clipboardMode); 336 void UpdatePosesClipboardModeFromClipboard(BMessage *clipboardReport = NULL); 337 338 // filtering 339 void SetRefFilter(BRefFilter *); 340 BRefFilter *RefFilter() const; 341 342 // access for mime types represented in the pose view 343 void AddMimeType(const char* mimeType); 344 const char *MimeTypeAt(int32 index); 345 int32 CountMimeTypes(); 346 void RefreshMimeTypeList(); 347 348 // drag&drop handling 349 virtual bool HandleMessageDropped(BMessage *); 350 static bool HandleDropCommon(BMessage *dragMessage, Model *target, BPose *, 351 BView *view, BPoint dropPt); 352 // used by pose views and info windows 353 static bool CanHandleDragSelection(const Model *target, 354 const BMessage *dragMessage, bool ignoreTypes); 355 virtual void DragSelectedPoses(const BPose *clickedPose, BPoint); 356 virtual void DragSelectionRect(BPoint, bool extendSelection); 357 358 void MoveSelectionInto(Model *destFolder, BContainerWindow *srcWindow, 359 bool forceCopy, bool forceMove = false, bool createLink = false, bool relativeLink = false); 360 static void MoveSelectionInto(Model *destFolder, BContainerWindow *srcWindow, 361 BContainerWindow *destWindow, uint32 buttons, BPoint loc, 362 bool forceCopy, bool forceMove = false, bool createLink = false, bool relativeLink = false, 363 BPoint clickPt = BPoint(0, 0), bool pinToGrid = false); 364 365 bool UpdateDropTarget(BPoint, const BMessage *, bool trackingContextMenu); 366 // return true if drop target changed 367 void HiliteDropTarget(bool hiliteState); 368 369 void DragStop(); 370 // throw away cached up structures 371 372 static bool MenuTrackingHook(BMenu *menu, void *castToThis); 373 // hook for spring loaded nav-menus 374 375 // scripting 376 virtual BHandler *ResolveSpecifier(BMessage *message, int32 index, 377 BMessage *specifier, int32 form, const char *property); 378 virtual status_t GetSupportedSuites(BMessage *); 379 380 // string width calls that use local width caches, faster than using 381 // the general purpose BView::StringWidth 382 float StringWidth(const char *) const; 383 float StringWidth(const char *, int32) const; 384 // deliberately hide the BView StringWidth here - this makes it 385 // easy to have the right StringWidth picked up by 386 // template instantiation, as used by WidgetAttributeText 387 388 // show/hide barberpole while a background task is filling up the view, etc. 389 void ShowBarberPole(); 390 void HideBarberPole(); 391 392 bool fShowSelectionWhenInactive; 393 bool fTransparentSelection; 394 bool fIsDrawingSelectionRect; 395 396 bool IsWatchingDateFormatChange(); 397 void StartWatchDateFormatChange(); 398 void StopWatchDateFormatChange(); 399 400 void UpdateDateColumns(BMessage *); 401 virtual void AdaptToVolumeChange(BMessage *); 402 virtual void AdaptToDesktopIntegrationChange(BMessage *); 403 404 protected: 405 // view setup 406 virtual void SetUpDefaultColumnsIfNeeded(); 407 408 virtual EntryListBase *InitDirentIterator(const entry_ref *); 409 // sets up an entry iterator for _add_poses_ 410 // overriden by QueryPoseView, etc. to provide different iteration 411 412 void Cleanup(bool doAll = false); 413 // clean up poses 414 void NewFolder(const BMessage *); 415 // create a new folder, optionally specify a location 416 417 void NewFileFromTemplate(const BMessage *); 418 // create a new file based on a template, optionally specify a location 419 420 void ShowContextMenu(BPoint); 421 422 // scripting handlers 423 virtual bool HandleScriptingMessage(BMessage *message); 424 bool SetProperty(BMessage *message, BMessage *specifier, int32 form, 425 const char *property, BMessage *reply); 426 bool GetProperty(BMessage *, int32, const char *, BMessage *); 427 bool CreateProperty(BMessage *message, BMessage *specifier, int32, 428 const char *, BMessage *reply); 429 bool ExecuteProperty(BMessage *specifier, int32, const char *, BMessage *reply); 430 bool CountProperty(BMessage *, int32, const char *, BMessage *); 431 bool DeleteProperty(BMessage *, int32, const char *, BMessage *); 432 433 void ClearPoses(); 434 // remove all the current poses from the view 435 436 // pose info read/write calls 437 void ReadPoseInfo(Model *, PoseInfo *); 438 ExtendedPoseInfo *ReadExtendedPoseInfo(Model *); 439 440 // pose creation 441 BPose *EntryCreated(const node_ref *, const node_ref *, const char *, int32 *index = 0); 442 443 BPose *CreatePose(Model *, PoseInfo *, bool insertionSort = true, 444 int32 *index = 0, BRect *boundsPtr = 0, bool forceDraw = true); 445 virtual void CreatePoses(Model **models, PoseInfo *poseInfoArray, int32 count, 446 BPose **resultingPoses, bool insertionSort = true, int32 *lastPoseIndexPtr = 0, 447 BRect *boundsPtr = 0, bool forceDraw = false); 448 virtual bool ShouldShowPose(const Model *, const PoseInfo *); 449 // filter, subclasses override to control which poses show up 450 // subclasses should always call inherited 451 void CreateVolumePose(BVolume *, bool watchIndividually); 452 453 virtual bool AddPosesThreadValid(const entry_ref *) const; 454 // verifies whether or not the current set of AddPoses threads 455 // are valid and allowed to be adding poses -- returns false 456 // in the case where the directory has been switched while populating 457 // the view 458 459 virtual void AddPoses(Model *model = NULL); 460 // if <model> is zero, PoseView has other means of iterating through all 461 // the entries that it adds 462 virtual void AddRootPoses(bool watchIndividually, bool mountShared); 463 // watchIndividually is used when placing a volume pose onto the Desktop 464 // where unlike in the Root window it will not be watched by the folder 465 // representing root. If set, each volume will therefore be watched 466 // individually 467 virtual void RemoveRootPoses(); 468 virtual void AddTrashPoses(); 469 470 virtual bool DeletePose(const node_ref *, BPose *pose = NULL, int32 index = 0); 471 virtual void DeleteSymLinkPoseTarget(const node_ref *itemNode, BPose *pose, 472 int32 index); 473 // the pose itself wasn't deleted but it's target node was - the 474 // pose must be a symlink 475 static void PoseHandleDeviceUnmounted(BPose *pose, Model *model, int32 index, 476 BPoseView *poseView, dev_t device); 477 static void RemoveNonBootDesktopModels(BPose *, Model *model, int32, 478 BPoseView *poseView, dev_t); 479 480 // pose placement 481 void CheckAutoPlacedPoses(); 482 // find poses that need placing and place them in a new spot 483 void PlacePose(BPose *, BRect &); 484 // find a new place for a pose, starting at fHintLocation and place it 485 bool IsValidLocation(const BPose *pose); 486 bool IsValidLocation(const BRect& rect); 487 status_t GetDeskbarFrame(BRect* frame); 488 bool SlotOccupied(BRect poseRect, BRect viewBounds) const; 489 void NextSlot(BPose *, BRect &poseRect, BRect viewBounds); 490 void TrySettingPoseLocation(BNode *node, BPoint point); 491 BPoint PinToGrid(BPoint, BPoint grid, BPoint offset) const; 492 493 // zombie pose handling 494 Model *FindZombie(const node_ref *, int32 *index = 0); 495 BPose *ConvertZombieToPose(Model *zombie, int32 index); 496 497 // pose handling 498 BRect CalcPoseRect(const BPose *, int32 index, 499 bool firstColumnOnly = false) const; 500 BRect CalcPoseRectIcon(const BPose *) const; 501 BRect CalcPoseRectList(const BPose *, int32 index, 502 bool firstColumnOnly = false) const; 503 void DrawPose(BPose *, int32 index, bool fullDraw = true); 504 void DrawViewCommon(const BRect &updateRect); 505 506 // pose list handling 507 int32 BSearchList(const BPose *, int32 *index); 508 void InsertPoseAfter(BPose *pose, int32 *index, int32 orientation, 509 BRect *invalidRect); 510 // does a CopyBits to scroll poses making room for a new pose, 511 // returns rectangle that needs invalidating 512 void CloseGapInList(BRect *invalidRect); 513 int32 FirstIndexAtOrBelow(int32 y, bool constrainIndex = true) const; 514 void AddToVSList(BPose *); 515 int32 RemoveFromVSList(const BPose *); 516 BPose *FindNearbyPose(char arrow, int32 *index); 517 BPose *FindBestMatch(int32 *index); 518 BPose *FindNextMatch(int32 *index, bool reverse = false); 519 520 // node monitoring calls 521 virtual void StartWatching(); 522 virtual void StopWatching(); 523 524 status_t WatchNewNode(const node_ref *item); 525 // the above would ideally be the only call of these three and it would 526 // be a virtual, overriding the specific watch mask in query pose view, etc. 527 // however we need to call WatchNewNode from inside AddPosesTask while 528 // the window is unlocked - we have to use the static and a cached 529 // messenger and masks. 530 static status_t WatchNewNode(const node_ref *, uint32, BMessenger); 531 virtual uint32 WatchNewNodeMask(); 532 // override to change different watch modes for query pose view, etc. 533 534 // drag&drop handling 535 static bool EachItemInDraggedSelection(const BMessage *message, 536 bool (*)(BPose *, BPoseView *, void *), BPoseView *poseView, 537 void * = NULL); 538 // iterates through each pose in current selectiond in the source 539 // window of the current drag message; locks the window 540 // add const version 541 BRect GetDragRect(int32 clickedPoseIndex); 542 BBitmap *MakeDragBitmap(BRect dragRect, BPoint clickedPoint, int32 clickedPoseIndex, BPoint &offset); 543 static bool FindDragNDropAction(const BMessage *dragMessage, bool &canCopy, 544 bool &canMove, bool &canLink, bool &canErase); 545 546 static bool CanTrashForeignDrag(const Model *); 547 static bool CanCopyOrMoveForeignDrag(const Model *, const BMessage *); 548 static bool DragSelectionContains(const BPose *target, const BMessage *dragMessage); 549 static status_t CreateClippingFile(BPoseView *poseView, BFile &result, 550 char *resultingName, BDirectory *dir, BMessage *message, const char *fallbackName, 551 bool setLocation = false, BPoint dropPoint = BPoint(0, 0)); 552 553 // opening files, lanunching 554 void OpenSelectionCommon(BPose *, int32 *, bool); 555 // used by OpenSelection and OpenSelectionUsing 556 static void LaunchAppWithSelection(Model *, const BMessage *, bool checkTypes = true); 557 558 // node monitoring calls 559 virtual bool EntryMoved(const BMessage *); 560 virtual bool AttributeChanged(const BMessage *); 561 virtual bool NoticeMetaMimeChanged(const BMessage *); 562 virtual void MetaMimeChanged(const char *, const char *); 563 564 // click handling 565 bool WasDoubleClick(const BPose *, BPoint); 566 bool WasClickInPath(const BPose *, int32 index, BPoint) const; 567 int32 WaitForMouseUpOrDrag(BPoint start); 568 569 // selection 570 void SelectPosesListMode(BRect, BList **); 571 void SelectPosesIconMode(BRect, BList **); 572 void AddRemoveSelectionRange(BPoint where, bool extendSelection, BPose *); 573 574 // view drawing 575 void SynchronousUpdate(BRect, bool clip = false); 576 577 // scrolling 578 void HandleAutoScroll(); 579 bool CheckAutoScroll(BPoint mouseLoc, bool shouldScroll, bool selectionScrolling = false); 580 581 // view extent handling 582 void RecalcExtent(); 583 void AddToExtent(const BRect &); 584 void ClearExtent(); 585 void RemoveFromExtent(const BRect &); 586 587 virtual void EditQueries(); 588 virtual void AddCountView(); 589 590 void HandleAttrMenuItemSelected(BMessage *); 591 void TryUpdatingBrokenLinks(); 592 // ran a little after a volume gets mounted 593 594 void MapToNewIconMode(BPose *, BPoint oldGrid, BPoint oldOffset); 595 void ResetOrigin(); 596 void PinPointToValidRange(BPoint &); 597 // used to ensure pose locations make sense after getting them 598 // in pose info from attributes, etc. 599 600 void FinishPendingScroll(float &listViewScrollBy, BRect bounds); 601 // utility call for CreatePoses 602 603 // background AddPoses task calls 604 static status_t AddPosesTask(void *); 605 virtual void AddPosesCompleted(); 606 bool IsValidAddPosesThread(thread_id) const; 607 608 // misc 609 BList *GetDropPointList(BPoint dropPoint, BPoint startPoint, const PoseList *, 610 bool sourceInListMode, bool dropOnGrid) const; 611 void SendSelectionAsRefs(uint32 what, bool onlyQueries = false); 612 void MoveListToTrash(BObjectList<entry_ref> *, bool selectNext, bool deleteDirectly); 613 void Delete(BObjectList<entry_ref> *, bool selectNext, bool askUser); 614 void Delete(const entry_ref &ref, bool selectNext, bool askUser); 615 void RestoreItemsFromTrash(BObjectList<entry_ref> *, bool selectNext); 616 617 static bool ShouldIntegrateDesktop(const BVolume &volume); 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