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 *); 327 bool FrameForPose(BPose *targetpose, bool convert, BRect *poseRect); 328 bool CreateSymlinkPoseTarget(Model *symlink); 329 // used to complete a symlink pose; returns true if 330 // target symlink should not be shown 331 void ResetPosePlacementHint(); 332 void PlaceFolder(const entry_ref *, const BMessage *); 333 334 // clipboard handling for poses 335 inline bool HasPosesInClipboard(); 336 inline void SetHasPosesInClipboard(bool hasPoses); 337 void SetPosesClipboardMode(uint32 clipboardMode); 338 void UpdatePosesClipboardModeFromClipboard(BMessage *clipboardReport = NULL); 339 340 // filtering 341 void SetRefFilter(BRefFilter *); 342 BRefFilter *RefFilter() const; 343 344 // access for mime types represented in the pose view 345 void AddMimeType(const char* mimeType); 346 const char *MimeTypeAt(int32 index); 347 int32 CountMimeTypes(); 348 void RefreshMimeTypeList(); 349 350 // drag&drop handling 351 virtual bool HandleMessageDropped(BMessage *); 352 static bool HandleDropCommon(BMessage *dragMessage, Model *target, BPose *, 353 BView *view, BPoint dropPt); 354 // used by pose views and info windows 355 static bool CanHandleDragSelection(const Model *target, 356 const BMessage *dragMessage, bool ignoreTypes); 357 virtual void DragSelectedPoses(const BPose *clickedPose, BPoint); 358 virtual void DragSelectionRect(BPoint, bool extendSelection); 359 360 void MoveSelectionInto(Model *destFolder, BContainerWindow *srcWindow, 361 bool forceCopy, bool forceMove = false, bool createLink = false, bool relativeLink = false); 362 static void MoveSelectionInto(Model *destFolder, BContainerWindow *srcWindow, 363 BContainerWindow *destWindow, uint32 buttons, BPoint loc, 364 bool forceCopy, bool forceMove = false, bool createLink = false, bool relativeLink = false, 365 BPoint clickPt = BPoint(0, 0), bool pinToGrid = false); 366 367 bool UpdateDropTarget(BPoint, const BMessage *, bool trackingContextMenu); 368 // return true if drop target changed 369 void HiliteDropTarget(bool hiliteState); 370 371 void DragStop(); 372 // throw away cached up structures 373 374 static bool MenuTrackingHook(BMenu *menu, void *castToThis); 375 // hook for spring loaded nav-menus 376 377 // scripting 378 virtual BHandler *ResolveSpecifier(BMessage *message, int32 index, 379 BMessage *specifier, int32 form, const char *property); 380 virtual status_t GetSupportedSuites(BMessage *); 381 382 // string width calls that use local width caches, faster than using 383 // the general purpose BView::StringWidth 384 float StringWidth(const char *) const; 385 float StringWidth(const char *, int32) const; 386 // deliberately hide the BView StringWidth here - this makes it 387 // easy to have the right StringWidth picked up by 388 // template instantiation, as used by WidgetAttributeText 389 390 // show/hide barberpole while a background task is filling up the view, etc. 391 void ShowBarberPole(); 392 void HideBarberPole(); 393 394 bool fShowSelectionWhenInactive; 395 bool fTransparentSelection; 396 bool fIsDrawingSelectionRect; 397 398 bool IsWatchingDateFormatChange(); 399 void StartWatchDateFormatChange(); 400 void StopWatchDateFormatChange(); 401 402 void UpdateDateColumns(BMessage *); 403 virtual void AdaptToVolumeChange(BMessage *); 404 virtual void AdaptToDesktopIntegrationChange(BMessage *); 405 406 protected: 407 // view setup 408 virtual void SetUpDefaultColumnsIfNeeded(); 409 410 virtual EntryListBase *InitDirentIterator(const entry_ref *); 411 // sets up an entry iterator for _add_poses_ 412 // overriden by QueryPoseView, etc. to provide different iteration 413 414 void Cleanup(bool doAll = false); 415 // clean up poses 416 void NewFolder(const BMessage *); 417 // create a new folder, optionally specify a location 418 419 void NewFileFromTemplate(const BMessage *); 420 // create a new file based on a template, optionally specify a location 421 422 void ShowContextMenu(BPoint); 423 424 // scripting handlers 425 virtual bool HandleScriptingMessage(BMessage *message); 426 bool SetProperty(BMessage *message, BMessage *specifier, int32 form, 427 const char *property, BMessage *reply); 428 bool GetProperty(BMessage *, int32, const char *, BMessage *); 429 bool CreateProperty(BMessage *message, BMessage *specifier, int32, 430 const char *, BMessage *reply); 431 bool ExecuteProperty(BMessage *specifier, int32, const char *, BMessage *reply); 432 bool CountProperty(BMessage *, int32, const char *, BMessage *); 433 bool DeleteProperty(BMessage *, int32, const char *, BMessage *); 434 435 void ClearPoses(); 436 // remove all the current poses from the view 437 438 // pose info read/write calls 439 void ReadPoseInfo(Model *, PoseInfo *); 440 ExtendedPoseInfo *ReadExtendedPoseInfo(Model *); 441 442 void _CheckPoseSortOrder(PoseList *list, BPose *, int32 index); 443 444 // pose creation 445 BPose *EntryCreated(const node_ref *, const node_ref *, const char *, int32 *index = 0); 446 447 void AddPoseToList(PoseList *list, bool visibleList, bool insertionSort, 448 BPose *pose, BRect &viewBounds, float &listViewScrollBy, 449 bool forceDraw, int32 *indexPtr = NULL); 450 BPose *CreatePose(Model *, PoseInfo *, bool insertionSort = true, 451 int32 *index = 0, BRect *boundsPtr = 0, bool forceDraw = true); 452 virtual void CreatePoses(Model **models, PoseInfo *poseInfoArray, int32 count, 453 BPose **resultingPoses, bool insertionSort = true, int32 *lastPoseIndexPtr = 0, 454 BRect *boundsPtr = 0, bool forceDraw = false); 455 virtual bool ShouldShowPose(const Model *, const PoseInfo *); 456 // filter, subclasses override to control which poses show up 457 // subclasses should always call inherited 458 void CreateVolumePose(BVolume *, bool watchIndividually); 459 460 void CreateTrashPose(); 461 462 virtual bool AddPosesThreadValid(const entry_ref *) const; 463 // verifies whether or not the current set of AddPoses threads 464 // are valid and allowed to be adding poses -- returns false 465 // in the case where the directory has been switched while populating 466 // the view 467 468 virtual void AddPoses(Model *model = NULL); 469 // if <model> is zero, PoseView has other means of iterating through all 470 // the entries thaat it adds 471 472 virtual void AddRootPoses(bool watchIndividually, bool mountShared); 473 // watchIndividually is used when placing a volume pose onto the Desktop 474 // where unlike in the Root window it will not be watched by the folder 475 // representing root. If set, each volume will therefore be watched 476 // individually 477 virtual void RemoveRootPoses(); 478 virtual void AddTrashPoses(); 479 480 virtual bool DeletePose(const node_ref *, BPose *pose = NULL, int32 index = 0); 481 virtual void DeleteSymLinkPoseTarget(const node_ref *itemNode, BPose *pose, 482 int32 index); 483 // the pose itself wasn't deleted but it's target node was - the 484 // pose must be a symlink 485 static void PoseHandleDeviceUnmounted(BPose *pose, Model *model, int32 index, 486 BPoseView *poseView, dev_t device); 487 static void RemoveNonBootDesktopModels(BPose *, Model *model, int32, 488 BPoseView *poseView, dev_t); 489 490 // pose placement 491 void CheckAutoPlacedPoses(); 492 // find poses that need placing and place them in a new spot 493 void PlacePose(BPose *, BRect &); 494 // find a new place for a pose, starting at fHintLocation and place it 495 bool IsValidLocation(const BPose *pose); 496 bool IsValidLocation(const BRect& rect); 497 status_t GetDeskbarFrame(BRect* frame); 498 bool SlotOccupied(BRect poseRect, BRect viewBounds) const; 499 void NextSlot(BPose *, BRect &poseRect, BRect viewBounds); 500 void TrySettingPoseLocation(BNode *node, BPoint point); 501 BPoint PinToGrid(BPoint, BPoint grid, BPoint offset) const; 502 503 // zombie pose handling 504 Model *FindZombie(const node_ref *, int32 *index = 0); 505 BPose *ConvertZombieToPose(Model *zombie, int32 index); 506 507 // pose handling 508 BRect CalcPoseRect(const BPose *, int32 index, 509 bool firstColumnOnly = false) const; 510 BRect CalcPoseRectIcon(const BPose *) const; 511 BRect CalcPoseRectList(const BPose *, int32 index, 512 bool firstColumnOnly = false) const; 513 void DrawPose(BPose *, int32 index, bool fullDraw = true); 514 void DrawViewCommon(const BRect &updateRect); 515 516 // pose list handling 517 int32 BSearchList(PoseList *poseList, const BPose *, int32 *index); 518 void InsertPoseAfter(BPose *pose, int32 *index, int32 orientation, 519 BRect *invalidRect); 520 // does a CopyBits to scroll poses making room for a new pose, 521 // returns rectangle that needs invalidating 522 void CloseGapInList(BRect *invalidRect); 523 int32 FirstIndexAtOrBelow(int32 y, bool constrainIndex = true) const; 524 void AddToVSList(BPose *); 525 int32 RemoveFromVSList(const BPose *); 526 BPose *FindNearbyPose(char arrow, int32 *index); 527 BPose *FindBestMatch(int32 *index); 528 BPose *FindNextMatch(int32 *index, bool reverse = false); 529 530 // node monitoring calls 531 virtual void StartWatching(); 532 virtual void StopWatching(); 533 534 status_t WatchNewNode(const node_ref *item); 535 // the above would ideally be the only call of these three and it would 536 // be a virtual, overriding the specific watch mask in query pose view, etc. 537 // however we need to call WatchNewNode from inside AddPosesTask while 538 // the window is unlocked - we have to use the static and a cached 539 // messenger and masks. 540 static status_t WatchNewNode(const node_ref *, uint32, BMessenger); 541 virtual uint32 WatchNewNodeMask(); 542 // override to change different watch modes for query pose view, etc. 543 544 // drag&drop handling 545 static bool EachItemInDraggedSelection(const BMessage *message, 546 bool (*)(BPose *, BPoseView *, void *), BPoseView *poseView, 547 void * = NULL); 548 // iterates through each pose in current selectiond in the source 549 // window of the current drag message; locks the window 550 // add const version 551 BRect GetDragRect(int32 clickedPoseIndex); 552 BBitmap *MakeDragBitmap(BRect dragRect, BPoint clickedPoint, int32 clickedPoseIndex, BPoint &offset); 553 static bool FindDragNDropAction(const BMessage *dragMessage, bool &canCopy, 554 bool &canMove, bool &canLink, bool &canErase); 555 556 static bool CanTrashForeignDrag(const Model *); 557 static bool CanCopyOrMoveForeignDrag(const Model *, const BMessage *); 558 static bool DragSelectionContains(const BPose *target, const BMessage *dragMessage); 559 static status_t CreateClippingFile(BPoseView *poseView, BFile &result, 560 char *resultingName, BDirectory *dir, BMessage *message, const char *fallbackName, 561 bool setLocation = false, BPoint dropPoint = BPoint(0, 0)); 562 563 // opening files, lanunching 564 void OpenSelectionCommon(BPose *, int32 *, bool); 565 // used by OpenSelection and OpenSelectionUsing 566 static void LaunchAppWithSelection(Model *, const BMessage *, bool checkTypes = true); 567 568 // node monitoring calls 569 virtual bool EntryMoved(const BMessage *); 570 virtual bool AttributeChanged(const BMessage *); 571 virtual bool NoticeMetaMimeChanged(const BMessage *); 572 virtual void MetaMimeChanged(const char *, const char *); 573 574 // click handling 575 bool WasDoubleClick(const BPose *, BPoint); 576 bool WasClickInPath(const BPose *, int32 index, BPoint) const; 577 int32 WaitForMouseUpOrDrag(BPoint start); 578 579 // selection 580 void SelectPosesListMode(BRect, BList **); 581 void SelectPosesIconMode(BRect, BList **); 582 void AddRemoveSelectionRange(BPoint where, bool extendSelection, BPose *); 583 584 // view drawing 585 void SynchronousUpdate(BRect, bool clip = false); 586 587 // scrolling 588 void HandleAutoScroll(); 589 bool CheckAutoScroll(BPoint mouseLoc, bool shouldScroll, bool selectionScrolling = false); 590 591 // view extent handling 592 void RecalcExtent(); 593 void AddToExtent(const BRect &); 594 void ClearExtent(); 595 void RemoveFromExtent(const BRect &); 596 597 virtual void EditQueries(); 598 virtual void AddCountView(); 599 600 void HandleAttrMenuItemSelected(BMessage *); 601 void TryUpdatingBrokenLinks(); 602 // ran a little after a volume gets mounted 603 604 void MapToNewIconMode(BPose *, BPoint oldGrid, BPoint oldOffset); 605 void ResetOrigin(); 606 void PinPointToValidRange(BPoint &); 607 // used to ensure pose locations make sense after getting them 608 // in pose info from attributes, etc. 609 610 void FinishPendingScroll(float &listViewScrollBy, BRect bounds); 611 // utility call for CreatePoses 612 613 // background AddPoses task calls 614 static status_t AddPosesTask(void *); 615 virtual void AddPosesCompleted(); 616 bool IsValidAddPosesThread(thread_id) const; 617 618 // typeahead filtering 619 void EnsurePoseUnselected(BPose *pose); 620 void RemoveFilteredPose(BPose *pose, int32 index); 621 void FilterChanged(); 622 void UpdateAfterFilterChange(); 623 bool FilterPose(BPose *pose); 624 void StartFiltering(); 625 void StopFiltering(); 626 void ClearFilter(); 627 PoseList *CurrentPoseList() const; 628 629 // misc 630 BList *GetDropPointList(BPoint dropPoint, BPoint startPoint, const PoseList *, 631 bool sourceInListMode, bool dropOnGrid) const; 632 void SendSelectionAsRefs(uint32 what, bool onlyQueries = false); 633 void MoveListToTrash(BObjectList<entry_ref> *, bool selectNext, bool deleteDirectly); 634 void Delete(BObjectList<entry_ref> *, bool selectNext, bool askUser); 635 void Delete(const entry_ref &ref, bool selectNext, bool askUser); 636 void RestoreItemsFromTrash(BObjectList<entry_ref> *, bool selectNext); 637 638 private: 639 void DrawOpenAnimation(BRect); 640 641 void MoveSelectionOrEntryToTrash(const entry_ref *ref, bool selectNext); 642 643 protected: 644 BHScrollBar *fHScrollBar; 645 BScrollBar *fVScrollBar; 646 Model *fModel; 647 BPose *fActivePose; 648 BRect fExtent; 649 // the following should probably be just member lists, not pointers 650 PoseList *fPoseList; 651 PoseList *fFilteredPoseList; 652 PoseList *fVSPoseList; 653 PoseList *fSelectionList; 654 NodeSet fInsertedNodes; 655 BObjectList<BString> fMimeTypesInSelectionCache; 656 // used for mime string based icon highliting during a drag 657 BObjectList<Model> *fZombieList; 658 PendingNodeMonitorCache pendingNodeMonitorCache; 659 BObjectList<BColumn> *fColumnList; 660 BObjectList<BString> *fMimeTypeList; 661 bool fMimeTypeListIsDirty; 662 BViewState *fViewState; 663 bool fStateNeedsSaving; 664 BCountView *fCountView; 665 float fListElemHeight; 666 float fIconPoseHeight; 667 BPose *fDropTarget; 668 BPose *fAlreadySelectedDropTarget; 669 BLooper *fSelectionHandler; 670 BPoint fLastClickPt; 671 bigtime_t fLastClickTime; 672 const BPose *fLastClickedPose; 673 BPoint fLastLeftTop; 674 BRect fLastExtent; 675 BTitleView *fTitleView; 676 BRefFilter *fRefFilter; 677 BPoint fGrid; 678 BPoint fOffset; 679 BPoint fHintLocation; 680 float fAutoScrollInc; 681 int32 fAutoScrollState; 682 std::set<thread_id> fAddPosesThreads; 683 bool fWidgetTextOutline; 684 const BPose *fSelectionPivotPose; 685 const BPose *fRealPivotPose; 686 BMessageRunner *fKeyRunner; 687 688 bool fSelectionVisible : 1; 689 bool fMultipleSelection : 1; 690 bool fDragEnabled : 1; 691 bool fDropEnabled : 1; 692 bool fSelectionRectEnabled : 1; 693 bool fAlwaysAutoPlace : 1; 694 bool fAllowPoseEditing : 1; 695 bool fSelectionChangedHook : 1; // get rid of this 696 bool fSavePoseLocations : 1; 697 bool fShowHideSelection : 1; 698 bool fOkToMapIcons : 1; 699 bool fEnsurePosesVisible : 1; 700 bool fShouldAutoScroll : 1; 701 bool fIsDesktopWindow : 1; 702 bool fIsWatchingDateFormatChange : 1; 703 bool fHasPosesInClipboard : 1; 704 bool fCursorCheck : 1; 705 bool fFiltering : 1; 706 707 BObjectList<BString> fFilterStrings; 708 int32 fLastFilterStringCount; 709 int32 fLastFilterStringLength; 710 711 BRect fStartFrame; 712 BRect fSelectionRect; 713 714 static float sFontHeight; 715 static font_height sFontInfo; 716 static BFont sCurrentFont; 717 static BString sMatchString; 718 // used for typeahead - should be replaced by a typeahead state 719 720 bigtime_t fLastKeyTime; 721 bigtime_t fLastDeskbarFrameCheckTime; 722 BRect fDeskbarFrame; 723 724 static OffscreenBitmap *sOffscreen; 725 726 typedef BView _inherited; 727 }; 728 729 730 class BHScrollBar : public BScrollBar { 731 public: 732 BHScrollBar(BRect, const char *, BView *); 733 void SetTitleView(BView *); 734 735 // BScrollBar overrides 736 virtual void ValueChanged(float); 737 738 private: 739 BView *fTitleView; 740 741 typedef BScrollBar _inherited; 742 }; 743 744 745 class TPoseViewFilter : public BMessageFilter { 746 public: 747 TPoseViewFilter(BPoseView *pose); 748 ~TPoseViewFilter(); 749 750 filter_result Filter(BMessage *, BHandler **); 751 752 private: 753 filter_result ObjectDropFilter(BMessage *, BHandler **); 754 755 BPoseView *fPoseView; 756 }; 757 758 759 extern bool 760 ClearViewOriginOne(const char *name, uint32 type, off_t size, void *data, void *params); 761 762 // inlines follow 763 764 inline BContainerWindow * 765 BPoseView::ContainerWindow() const 766 { 767 return dynamic_cast<BContainerWindow *>(Window()); 768 } 769 770 inline Model * 771 BPoseView::TargetModel() const 772 { 773 return fModel; 774 } 775 776 inline float 777 BPoseView::ListElemHeight() const 778 { 779 return fListElemHeight; 780 } 781 782 inline float 783 BPoseView::IconPoseHeight() const 784 { 785 return fIconPoseHeight; 786 } 787 788 inline uint32 789 BPoseView::IconSizeInt() const 790 { 791 return fViewState->IconSize(); 792 } 793 794 inline icon_size 795 BPoseView::IconSize() const 796 { 797 return (icon_size)fViewState->IconSize(); 798 } 799 800 inline PoseList * 801 BPoseView::SelectionList() const 802 { 803 return fSelectionList; 804 } 805 806 inline BObjectList<BString> * 807 BPoseView::MimeTypesInSelection() 808 { 809 return &fMimeTypesInSelectionCache; 810 } 811 812 inline BHScrollBar* 813 BPoseView::HScrollBar() const 814 { 815 return fHScrollBar; 816 } 817 818 inline BScrollBar* 819 BPoseView::VScrollBar() const 820 { 821 return fVScrollBar; 822 } 823 824 inline BCountView* 825 BPoseView::CountView() const 826 { 827 return fCountView; 828 } 829 830 inline bool 831 BPoseView::StateNeedsSaving() 832 { 833 return fStateNeedsSaving || fViewState->StateNeedsSaving(); 834 } 835 836 inline uint32 837 BPoseView::ViewMode() const 838 { 839 return fViewState->ViewMode(); 840 } 841 842 inline font_height 843 BPoseView::FontInfo() const 844 { 845 return sFontInfo; 846 } 847 848 inline float 849 BPoseView::FontHeight() const 850 { 851 return sFontHeight; 852 } 853 854 inline BPose * 855 BPoseView::ActivePose() const 856 { 857 return fActivePose; 858 } 859 860 inline void 861 BPoseView::DisableSaveLocation() 862 { 863 fSavePoseLocations = false; 864 } 865 866 inline bool 867 BPoseView::IsFilePanel() const 868 { 869 return false; 870 } 871 872 inline bool 873 BPoseView::IsDesktopWindow() const 874 { 875 return fIsDesktopWindow; 876 } 877 878 inline bool 879 BPoseView::IsDesktopView() const 880 { 881 return false; 882 } 883 884 inline uint32 885 BPoseView::PrimarySort() const 886 { 887 return fViewState->PrimarySort(); 888 } 889 890 inline uint32 891 BPoseView::PrimarySortType() const 892 { 893 return fViewState->PrimarySortType(); 894 } 895 896 inline uint32 897 BPoseView::SecondarySort() const 898 { 899 return fViewState->SecondarySort(); 900 } 901 902 inline uint32 903 BPoseView::SecondarySortType() const 904 { 905 return fViewState->SecondarySortType(); 906 } 907 908 inline bool 909 BPoseView::ReverseSort() const 910 { 911 return fViewState->ReverseSort(); 912 } 913 914 inline void 915 BPoseView::SetShowHideSelection(bool on) 916 { 917 fShowHideSelection = on; 918 } 919 920 inline void 921 BPoseView::SetIconMapping(bool on) 922 { 923 fOkToMapIcons = on; 924 } 925 926 inline void 927 BPoseView::AddToExtent(const BRect &rect) 928 { 929 fExtent = fExtent | rect; 930 } 931 932 inline void 933 BPoseView::ClearExtent() 934 { 935 fExtent.Set(LONG_MAX, LONG_MAX, LONG_MIN, LONG_MIN); 936 } 937 938 inline int32 939 BPoseView::CountColumns() const 940 { 941 return fColumnList->CountItems(); 942 } 943 944 inline int32 945 BPoseView::IndexOfColumn(const BColumn* column) const 946 { 947 return fColumnList->IndexOf(const_cast<BColumn *>(column)); 948 } 949 950 inline int32 951 BPoseView::IndexOfPose(const BPose *pose) const 952 { 953 return CurrentPoseList()->IndexOf(pose); 954 } 955 956 inline BPose * 957 BPoseView::PoseAtIndex(int32 index) const 958 { 959 return CurrentPoseList()->ItemAt(index); 960 } 961 962 inline BColumn * 963 BPoseView::ColumnAt(int32 index) const 964 { 965 return fColumnList->ItemAt(index); 966 } 967 968 inline BColumn * 969 BPoseView::FirstColumn() const 970 { 971 return fColumnList->FirstItem(); 972 } 973 974 inline BColumn * 975 BPoseView::LastColumn() const 976 { 977 return fColumnList->LastItem(); 978 } 979 980 inline int32 981 BPoseView::CountItems() const 982 { 983 return CurrentPoseList()->CountItems(); 984 } 985 986 987 inline void 988 BPoseView::SetMultipleSelection(bool state) 989 { 990 fMultipleSelection = state; 991 } 992 993 inline void 994 BPoseView::SetSelectionChangedHook(bool state) 995 { 996 fSelectionChangedHook = state; 997 } 998 999 inline void 1000 BPoseView::SetAutoScroll(bool state) 1001 { 1002 fShouldAutoScroll = state; 1003 } 1004 1005 inline void 1006 BPoseView::SetPoseEditing(bool state) 1007 { 1008 fAllowPoseEditing = state; 1009 } 1010 1011 inline void 1012 BPoseView::SetDragEnabled(bool state) 1013 { 1014 fDragEnabled = state; 1015 } 1016 1017 inline void 1018 BPoseView::SetDropEnabled(bool state) 1019 { 1020 fDropEnabled = state; 1021 } 1022 1023 inline void 1024 BPoseView::SetSelectionRectEnabled(bool state) 1025 { 1026 fSelectionRectEnabled = state; 1027 } 1028 1029 inline void 1030 BPoseView::SetAlwaysAutoPlace(bool state) 1031 { 1032 fAlwaysAutoPlace = state; 1033 } 1034 1035 inline void 1036 BPoseView::SetEnsurePosesVisible(bool state) 1037 { 1038 fEnsurePosesVisible = state; 1039 } 1040 1041 inline void 1042 BPoseView::SetSelectionHandler(BLooper *looper) 1043 { 1044 fSelectionHandler = looper; 1045 } 1046 1047 inline void 1048 BPoseView::SetRefFilter(BRefFilter *filter) 1049 { 1050 fRefFilter = filter; 1051 } 1052 1053 inline BRefFilter * 1054 BPoseView::RefFilter() const 1055 { 1056 return fRefFilter; 1057 } 1058 1059 inline void 1060 BHScrollBar::SetTitleView(BView *view) 1061 { 1062 fTitleView = view; 1063 } 1064 1065 inline BPose * 1066 BPoseView::FindPose(const Model *model, int32 *index) const 1067 { 1068 return CurrentPoseList()->FindPose(model, index); 1069 } 1070 1071 inline BPose * 1072 BPoseView::FindPose(const node_ref *node, int32 *index) const 1073 { 1074 return CurrentPoseList()->FindPose(node, index); 1075 } 1076 1077 inline BPose * 1078 BPoseView::FindPose(const entry_ref *entry, int32 *index) const 1079 { 1080 return CurrentPoseList()->FindPose(entry, index); 1081 } 1082 1083 1084 inline bool 1085 BPoseView::HasPosesInClipboard() 1086 { 1087 return fHasPosesInClipboard; 1088 } 1089 1090 1091 inline void 1092 BPoseView::SetHasPosesInClipboard(bool hasPoses) 1093 { 1094 fHasPosesInClipboard = hasPoses; 1095 } 1096 1097 1098 inline PoseList * 1099 BPoseView::CurrentPoseList() const 1100 { 1101 return fFiltering ? fFilteredPoseList : fPoseList; 1102 } 1103 1104 1105 template<class Param1> 1106 void 1107 EachTextWidget(BPose *pose, BPoseView *poseView, 1108 void (*func)(BTextWidget *, BPose *, BPoseView *, BColumn *, Param1), Param1 p1) 1109 { 1110 for (int32 index = 0; ;index++) { 1111 BColumn *column = poseView->ColumnAt(index); 1112 if (!column) 1113 break; 1114 1115 BTextWidget *widget = pose->WidgetFor(column->AttrHash()); 1116 if (widget) 1117 (func)(widget, pose, poseView, column, p1); 1118 } 1119 } 1120 1121 1122 template<class Param1, class Param2> 1123 void 1124 EachTextWidget(BPose *pose, BPoseView *poseView, 1125 void (*func)(BTextWidget *, BPose *, BPoseView *, BColumn *, 1126 Param1, Param2), Param1 p1, Param2 p2) 1127 { 1128 for (int32 index = 0; ;index++) { 1129 BColumn *column = poseView->ColumnAt(index); 1130 if (!column) 1131 break; 1132 1133 BTextWidget *widget = pose->WidgetFor(column->AttrHash()); 1134 if (widget) 1135 (func)(widget, pose, poseView, column, p1, p2); 1136 } 1137 } 1138 1139 1140 template<class Result, class Param1, class Param2> 1141 Result 1142 WhileEachTextWidget(BPose *pose, BPoseView *poseView, 1143 Result (*func)(BTextWidget *, BPose *, BPoseView *, BColumn *, 1144 Param1, Param2), Param1 p1, Param2 p2) 1145 { 1146 for (int32 index = 0; ;index++) { 1147 BColumn *column = poseView->ColumnAt(index); 1148 if (!column) 1149 break; 1150 1151 BTextWidget *widget = pose->WidgetFor(column->AttrHash()); 1152 if (widget) { 1153 Result result = (func)(widget, pose, poseView, column, p1, p2); 1154 if (result) 1155 return result; 1156 } 1157 } 1158 return 0; 1159 } 1160 1161 1162 } // namespace BPrivate 1163 1164 using namespace BPrivate; 1165 1166 #endif /* _POSE_VIEW_H */ 1167