1323b6546SOliver Tappe /* 2323b6546SOliver Tappe Open Tracker License 3323b6546SOliver Tappe 4323b6546SOliver Tappe Terms and Conditions 5323b6546SOliver Tappe 6323b6546SOliver Tappe Copyright (c) 1991-2000, Be Incorporated. All rights reserved. 7323b6546SOliver Tappe 8323b6546SOliver Tappe Permission is hereby granted, free of charge, to any person obtaining a copy of 9323b6546SOliver Tappe this software and associated documentation files (the "Software"), to deal in 10323b6546SOliver Tappe the Software without restriction, including without limitation the rights to 11323b6546SOliver Tappe use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 12323b6546SOliver Tappe of the Software, and to permit persons to whom the Software is furnished to do 13323b6546SOliver Tappe so, subject to the following conditions: 14323b6546SOliver Tappe 15323b6546SOliver Tappe The above copyright notice and this permission notice applies to all licensees 16323b6546SOliver Tappe and shall be included in all copies or substantial portions of the Software. 17323b6546SOliver Tappe 18323b6546SOliver Tappe THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19323b6546SOliver Tappe IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF TITLE, MERCHANTABILITY, 20323b6546SOliver Tappe FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 21323b6546SOliver Tappe BE INCORPORATED BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 22323b6546SOliver Tappe AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF, OR IN CONNECTION 23323b6546SOliver Tappe WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24323b6546SOliver Tappe 25323b6546SOliver Tappe Except as contained in this notice, the name of Be Incorporated shall not be 26323b6546SOliver Tappe used in advertising or otherwise to promote the sale, use or other dealings in 27323b6546SOliver Tappe this Software without prior written authorization from Be Incorporated. 28323b6546SOliver Tappe 29323b6546SOliver Tappe Tracker(TM), Be(R), BeOS(R), and BeIA(TM) are trademarks or registered 30323b6546SOliver Tappe trademarks of Be Incorporated in the United States and other countries. Other 31323b6546SOliver Tappe brand product names are registered trademarks or trademarks of their respective 32323b6546SOliver Tappe holders. 33323b6546SOliver Tappe All rights reserved. 34323b6546SOliver Tappe */ 35323b6546SOliver Tappe 361cd61330SJohn Scipione 371cd61330SJohn Scipione #include "DeskbarMenu.h" 381cd61330SJohn Scipione 39323b6546SOliver Tappe #include <Debug.h> 40323b6546SOliver Tappe #include <Bitmap.h> 41323b6546SOliver Tappe #include <Catalog.h> 42323b6546SOliver Tappe #include <Dragger.h> 43323b6546SOliver Tappe #include <Locale.h> 44323b6546SOliver Tappe #include <Menu.h> 45323b6546SOliver Tappe #include <MenuItem.h> 46323b6546SOliver Tappe #include <Roster.h> 47323b6546SOliver Tappe 48323b6546SOliver Tappe #include "BarApp.h" 49323b6546SOliver Tappe #include "BarView.h" 50323b6546SOliver Tappe #include "DeskbarUtils.h" 51323b6546SOliver Tappe #include "IconMenuItem.h" 52323b6546SOliver Tappe #include "MountMenu.h" 53323b6546SOliver Tappe #include "RecentItems.h" 54323b6546SOliver Tappe #include "StatusView.h" 55039f5926SJohn Scipione 56323b6546SOliver Tappe #include "tracker_private.h" 57323b6546SOliver Tappe 58546208a5SOliver Tappe #undef B_TRANSLATION_CONTEXT 59546208a5SOliver Tappe #define B_TRANSLATION_CONTEXT "DeskbarMenu" 60323b6546SOliver Tappe 61323b6546SOliver Tappe #define ROSTER_SIG "application/x-vnd.Be-ROST" 62323b6546SOliver Tappe 63323b6546SOliver Tappe #ifdef MOUNT_MENU_IN_DESKBAR 64323b6546SOliver Tappe class DeskbarMountMenu : public BPrivate::MountMenu { 65323b6546SOliver Tappe public: 66323b6546SOliver Tappe DeskbarMountMenu(const char* name); 67323b6546SOliver Tappe virtual bool AddDynamicItem(add_state s); 68323b6546SOliver Tappe }; 69088a9620SJohn Scipione #endif // MOUNT_MENU_IN_DESKBAR 70323b6546SOliver Tappe 71323b6546SOliver Tappe //#define SHOW_RECENT_FIND_ITEMS 72323b6546SOliver Tappe 73323b6546SOliver Tappe namespace BPrivate { 74323b6546SOliver Tappe BMenu* TrackerBuildRecentFindItemsMenu(const char*); 75323b6546SOliver Tappe } 76323b6546SOliver Tappe 77323b6546SOliver Tappe using namespace BPrivate; 78323b6546SOliver Tappe 79323b6546SOliver Tappe 80088a9620SJohn Scipione // #pragma mark - TDeskbarMenu 81323b6546SOliver Tappe 82323b6546SOliver Tappe 83323b6546SOliver Tappe TDeskbarMenu::TDeskbarMenu(TBarView* barView) 84fe624b39SJohn Scipione : 85fe624b39SJohn Scipione BNavMenu("DeskbarMenu", B_REFS_RECEIVED, DefaultTarget()), 86323b6546SOliver Tappe fAddState(kStart), 87323b6546SOliver Tappe fBarView(barView) 88323b6546SOliver Tappe { 89323b6546SOliver Tappe } 90323b6546SOliver Tappe 91323b6546SOliver Tappe 92323b6546SOliver Tappe void 93323b6546SOliver Tappe TDeskbarMenu::AttachedToWindow() 94323b6546SOliver Tappe { 95088a9620SJohn Scipione if (fBarView != NULL && fBarView->LockLooper()) { 96323b6546SOliver Tappe if (fBarView->Dragging()) { 97323b6546SOliver Tappe SetTypesList(fBarView->CachedTypesList()); 98323b6546SOliver Tappe SetTarget(BMessenger(fBarView)); 99323b6546SOliver Tappe SetTrackingHookDeep(this, fBarView->MenuTrackingHook, 100323b6546SOliver Tappe fBarView->GetTrackingHookData()); 101323b6546SOliver Tappe fBarView->DragStart(); 102323b6546SOliver Tappe } else { 103323b6546SOliver Tappe SetTypesList(NULL); 104323b6546SOliver Tappe SetTarget(DefaultTarget()); 105323b6546SOliver Tappe SetTrackingHookDeep(this, NULL, NULL); 106323b6546SOliver Tappe } 107323b6546SOliver Tappe 108323b6546SOliver Tappe fBarView->UnlockLooper(); 109323b6546SOliver Tappe } 110323b6546SOliver Tappe 111323b6546SOliver Tappe BNavMenu::AttachedToWindow(); 112323b6546SOliver Tappe } 113323b6546SOliver Tappe 114323b6546SOliver Tappe 115323b6546SOliver Tappe void 116323b6546SOliver Tappe TDeskbarMenu::DetachedFromWindow() 117323b6546SOliver Tappe { 118088a9620SJohn Scipione if (fBarView != NULL) { 119323b6546SOliver Tappe BLooper* looper = fBarView->Looper(); 120088a9620SJohn Scipione if (looper != NULL && looper->Lock()) { 121323b6546SOliver Tappe fBarView->DragStop(); 122323b6546SOliver Tappe looper->Unlock(); 123323b6546SOliver Tappe } 124323b6546SOliver Tappe } 125323b6546SOliver Tappe 126323b6546SOliver Tappe // don't call BNavMenu::DetachedFromWindow 127323b6546SOliver Tappe // it sets the TypesList to NULL 128323b6546SOliver Tappe BMenu::DetachedFromWindow(); 129323b6546SOliver Tappe } 130323b6546SOliver Tappe 131323b6546SOliver Tappe 132323b6546SOliver Tappe bool 133323b6546SOliver Tappe TDeskbarMenu::StartBuildingItemList() 134323b6546SOliver Tappe { 135323b6546SOliver Tappe RemoveItems(0, CountItems(), true); 136323b6546SOliver Tappe fAddState = kStart; 137323b6546SOliver Tappe return BNavMenu::StartBuildingItemList(); 138323b6546SOliver Tappe } 139323b6546SOliver Tappe 140323b6546SOliver Tappe 141323b6546SOliver Tappe void 142323b6546SOliver Tappe TDeskbarMenu::DoneBuildingItemList() 143323b6546SOliver Tappe { 144323b6546SOliver Tappe if (fItemList->CountItems() <= 0) { 145323b6546SOliver Tappe BMenuItem* item 146323b6546SOliver Tappe = new BMenuItem(B_TRANSLATE("<Deskbar folder is empty>"), 0); 147323b6546SOliver Tappe item->SetEnabled(false); 148323b6546SOliver Tappe AddItem(item); 149323b6546SOliver Tappe } else 150323b6546SOliver Tappe BNavMenu::DoneBuildingItemList(); 151323b6546SOliver Tappe } 152323b6546SOliver Tappe 153323b6546SOliver Tappe 154323b6546SOliver Tappe bool 155323b6546SOliver Tappe TDeskbarMenu::AddNextItem() 156323b6546SOliver Tappe { 157323b6546SOliver Tappe if (fAddState == kStart) 158323b6546SOliver Tappe return AddStandardDeskbarMenuItems(); 159323b6546SOliver Tappe 160323b6546SOliver Tappe TrackingHookData* data = fBarView->GetTrackingHookData(); 161323b6546SOliver Tappe if (fAddState == kAddingRecents) { 162323b6546SOliver Tappe static const char* recentTitle[] = { 163323b6546SOliver Tappe B_TRANSLATE_MARK("Recent documents"), 164323b6546SOliver Tappe B_TRANSLATE_MARK("Recent folders"), 165323b6546SOliver Tappe B_TRANSLATE_MARK("Recent applications")}; 166323b6546SOliver Tappe const int recentType[] = {kRecentDocuments, kRecentFolders, 167323b6546SOliver Tappe kRecentApplications}; 168323b6546SOliver Tappe const int recentTypes = 3; 169323b6546SOliver Tappe TRecentsMenu* recentItem[recentTypes]; 170323b6546SOliver Tappe 171323b6546SOliver Tappe bool enabled = false; 172323b6546SOliver Tappe 173323b6546SOliver Tappe for (int i = 0; i < recentTypes; i++) { 174323b6546SOliver Tappe recentItem[i] 175323b6546SOliver Tappe = new TRecentsMenu(B_TRANSLATE_NOCOLLECT(recentTitle[i]), 176323b6546SOliver Tappe fBarView, recentType[i]); 177323b6546SOliver Tappe 178323b6546SOliver Tappe if (recentItem[i]) 179323b6546SOliver Tappe enabled |= recentItem[i]->RecentsEnabled(); 180323b6546SOliver Tappe } 181323b6546SOliver Tappe if (enabled) { 182323b6546SOliver Tappe AddSeparatorItem(); 183323b6546SOliver Tappe 184323b6546SOliver Tappe for (int i = 0; i < recentTypes; i++) { 185323b6546SOliver Tappe if (!recentItem[i]) 186323b6546SOliver Tappe continue; 187323b6546SOliver Tappe 188323b6546SOliver Tappe if (recentItem[i]->RecentsEnabled()) { 189323b6546SOliver Tappe recentItem[i]->SetTypesList(TypesList()); 190323b6546SOliver Tappe recentItem[i]->SetTarget(Target()); 191323b6546SOliver Tappe AddItem(recentItem[i]); 192323b6546SOliver Tappe } 193323b6546SOliver Tappe 194323b6546SOliver Tappe if (data && fBarView && fBarView->Dragging()) { 195323b6546SOliver Tappe recentItem[i]->InitTrackingHook(data->fTrackingHook, 196323b6546SOliver Tappe &data->fTarget, data->fDragMessage); 197323b6546SOliver Tappe } 198323b6546SOliver Tappe } 19980d8697cSMurai Takashi } else { 20080d8697cSMurai Takashi for (int i = 0; i < recentTypes; i++) 20180d8697cSMurai Takashi delete recentItem[i]; 202323b6546SOliver Tappe } 203323b6546SOliver Tappe 204323b6546SOliver Tappe AddSeparatorItem(); 205323b6546SOliver Tappe fAddState = kAddingDeskbarMenu; 206323b6546SOliver Tappe return true; 207323b6546SOliver Tappe } 208323b6546SOliver Tappe 209323b6546SOliver Tappe if (fAddState == kAddingDeskbarMenu) { 210323b6546SOliver Tappe // keep reentering and adding items 211323b6546SOliver Tappe // until this returns false 212323b6546SOliver Tappe bool done = BNavMenu::AddNextItem(); 213323b6546SOliver Tappe BMenuItem* item = ItemAt(CountItems() - 1); 214323b6546SOliver Tappe if (item) { 215323b6546SOliver Tappe BNavMenu* menu = dynamic_cast<BNavMenu*>(item->Menu()); 216323b6546SOliver Tappe if (menu) { 217323b6546SOliver Tappe if (data && fBarView->Dragging()) { 218323b6546SOliver Tappe menu->InitTrackingHook(data->fTrackingHook, 219323b6546SOliver Tappe &data->fTarget, data->fDragMessage); 220323b6546SOliver Tappe } else 221323b6546SOliver Tappe menu->InitTrackingHook(0, NULL, NULL); 222323b6546SOliver Tappe } 223323b6546SOliver Tappe } 224323b6546SOliver Tappe 225323b6546SOliver Tappe if (!done) 226323b6546SOliver Tappe fAddState = kDone; 227323b6546SOliver Tappe return done; 228323b6546SOliver Tappe } 229323b6546SOliver Tappe 230323b6546SOliver Tappe return false; 231323b6546SOliver Tappe } 232323b6546SOliver Tappe 233323b6546SOliver Tappe 234323b6546SOliver Tappe bool 235323b6546SOliver Tappe TDeskbarMenu::AddStandardDeskbarMenuItems() 236323b6546SOliver Tappe { 237323b6546SOliver Tappe bool dragging = false; 238323b6546SOliver Tappe if (fBarView) 239323b6546SOliver Tappe dragging = fBarView->Dragging(); 240323b6546SOliver Tappe 241323b6546SOliver Tappe BMenuItem* item; 242323b6546SOliver Tappe 243323b6546SOliver Tappe // One of them is used if HAIKU_DISTRO_COMPATIBILITY_OFFICIAL, and the other if 244323b6546SOliver Tappe // not. However, we want both of them to end up in the catalog, so we have to 245323b6546SOliver Tappe // make them visible to collectcatkeys in either case. 246028ad031SAdrien Destugues - PulkoMandy B_TRANSLATE_MARK_VOID("About Haiku") 247028ad031SAdrien Destugues - PulkoMandy B_TRANSLATE_MARK_VOID("About this system") 248323b6546SOliver Tappe 249323b6546SOliver Tappe item = new BMenuItem( 250323b6546SOliver Tappe #ifdef HAIKU_DISTRO_COMPATIBILITY_OFFICIAL 251028ad031SAdrien Destugues - PulkoMandy B_TRANSLATE_NOCOLLECT("About Haiku") 252323b6546SOliver Tappe #else 253028ad031SAdrien Destugues - PulkoMandy B_TRANSLATE_NOCOLLECT("About this system") 254323b6546SOliver Tappe #endif 255323b6546SOliver Tappe , new BMessage(kShowSplash)); 256323b6546SOliver Tappe item->SetEnabled(!dragging); 257323b6546SOliver Tappe AddItem(item); 258323b6546SOliver Tappe 259323b6546SOliver Tappe static const char* kFindMenuItemStr 260323b6546SOliver Tappe = B_TRANSLATE_MARK("Find" B_UTF8_ELLIPSIS); 261323b6546SOliver Tappe 262323b6546SOliver Tappe #ifdef SHOW_RECENT_FIND_ITEMS 263323b6546SOliver Tappe item = new BMenuItem( 264323b6546SOliver Tappe TrackerBuildRecentFindItemsMenu(kFindMenuItemStr), 265323b6546SOliver Tappe new BMessage(kFindButton)); 266323b6546SOliver Tappe #else 267323b6546SOliver Tappe item = new BMenuItem(B_TRANSLATE_NOCOLLECT(kFindMenuItemStr), 268323b6546SOliver Tappe new BMessage(kFindButton)); 269323b6546SOliver Tappe #endif 270323b6546SOliver Tappe item->SetEnabled(!dragging); 271323b6546SOliver Tappe AddItem(item); 272323b6546SOliver Tappe 273323b6546SOliver Tappe item = new BMenuItem(B_TRANSLATE("Show replicants"), 274323b6546SOliver Tappe new BMessage(kToggleDraggers)); 275323b6546SOliver Tappe item->SetEnabled(!dragging); 276323b6546SOliver Tappe item->SetMarked(BDragger::AreDraggersDrawn()); 277323b6546SOliver Tappe AddItem(item); 278323b6546SOliver Tappe 279323b6546SOliver Tappe static const char* kMountMenuStr = B_TRANSLATE_MARK("Mount"); 280323b6546SOliver Tappe 281323b6546SOliver Tappe #ifdef MOUNT_MENU_IN_DESKBAR 282323b6546SOliver Tappe DeskbarMountMenu* mountMenu = new DeskbarMountMenu( 283323b6546SOliver Tappe B_TRANSLATE_NOCOLLECT(kMountMenuStr)); 284323b6546SOliver Tappe mountMenu->SetEnabled(!dragging); 285323b6546SOliver Tappe AddItem(mountMenu); 286323b6546SOliver Tappe #endif 287323b6546SOliver Tappe 288323b6546SOliver Tappe item = new BMenuItem(B_TRANSLATE("Deskbar preferences" B_UTF8_ELLIPSIS), 289323b6546SOliver Tappe new BMessage(kConfigShow)); 290323b6546SOliver Tappe item->SetTarget(be_app); 291323b6546SOliver Tappe AddItem(item); 292323b6546SOliver Tappe 293323b6546SOliver Tappe AddSeparatorItem(); 294323b6546SOliver Tappe 295323b6546SOliver Tappe BMenu* shutdownMenu = new BMenu(B_TRANSLATE("Shutdown" B_UTF8_ELLIPSIS)); 296323b6546SOliver Tappe 297323b6546SOliver Tappe item = new BMenuItem(B_TRANSLATE("Restart system"), 298323b6546SOliver Tappe new BMessage(kRebootSystem)); 299323b6546SOliver Tappe item->SetEnabled(!dragging); 300323b6546SOliver Tappe shutdownMenu->AddItem(item); 301323b6546SOliver Tappe 302028ad031SAdrien Destugues - PulkoMandy B_TRANSLATE_MARK_VOID("Suspend"); 303323b6546SOliver Tappe 304323b6546SOliver Tappe #ifdef APM_SUPPORT 305323b6546SOliver Tappe if (_kapm_control_(APM_CHECK_ENABLED) == B_OK) { 306028ad031SAdrien Destugues - PulkoMandy item = new BMenuItem(B_TRANSLATE_NOCOLLECT("Suspend"), 307323b6546SOliver Tappe new BMessage(kSuspendSystem)); 308323b6546SOliver Tappe item->SetEnabled(!dragging); 309323b6546SOliver Tappe shutdownMenu->AddItem(item); 310323b6546SOliver Tappe } 311323b6546SOliver Tappe #endif 312323b6546SOliver Tappe 313323b6546SOliver Tappe item = new BMenuItem(B_TRANSLATE("Power off"), 314323b6546SOliver Tappe new BMessage(kShutdownSystem)); 315323b6546SOliver Tappe item->SetEnabled(!dragging); 316323b6546SOliver Tappe shutdownMenu->AddItem(item); 317323b6546SOliver Tappe shutdownMenu->SetFont(be_plain_font); 318323b6546SOliver Tappe 319323b6546SOliver Tappe shutdownMenu->SetTargetForItems(be_app); 320323b6546SOliver Tappe BMessage* message = new BMessage(kShutdownSystem); 321323b6546SOliver Tappe message->AddBool("confirm", true); 322323b6546SOliver Tappe AddItem(new BMenuItem(shutdownMenu, message)); 323323b6546SOliver Tappe 324323b6546SOliver Tappe fAddState = kAddingRecents; 325323b6546SOliver Tappe 326323b6546SOliver Tappe return true; 327323b6546SOliver Tappe } 328323b6546SOliver Tappe 329323b6546SOliver Tappe 330323b6546SOliver Tappe void 331323b6546SOliver Tappe TDeskbarMenu::ClearMenuBuildingState() 332323b6546SOliver Tappe { 333323b6546SOliver Tappe fAddState = kDone; 334323b6546SOliver Tappe fMenuBuilt = false; 335323b6546SOliver Tappe // force the menu to get rebuilt each time 336323b6546SOliver Tappe BNavMenu::ClearMenuBuildingState(); 337323b6546SOliver Tappe } 338323b6546SOliver Tappe 339323b6546SOliver Tappe 340323b6546SOliver Tappe void 341323b6546SOliver Tappe TDeskbarMenu::ResetTargets() 342323b6546SOliver Tappe { 343323b6546SOliver Tappe // This method does not recurse into submenus 344323b6546SOliver Tappe // and does not affect menu items in submenus. 345323b6546SOliver Tappe // (e.g. "Restart System" and "Power Off") 346323b6546SOliver Tappe 347323b6546SOliver Tappe BNavMenu::ResetTargets(); 348323b6546SOliver Tappe 349323b6546SOliver Tappe // if we are dragging, set the target to whatever was set 350323b6546SOliver Tappe // else set it to the default (Tracker) 351323b6546SOliver Tappe if (!fBarView->Dragging()) 352323b6546SOliver Tappe SetTarget(DefaultTarget()); 353323b6546SOliver Tappe 354323b6546SOliver Tappe // now set the target for the menuitems to the currently 355323b6546SOliver Tappe // set target, which may or may not be tracker 356323b6546SOliver Tappe SetTargetForItems(Target()); 357323b6546SOliver Tappe 358323b6546SOliver Tappe for (int32 i = 0; ; i++) { 359323b6546SOliver Tappe BMenuItem* item = ItemAt(i); 360323b6546SOliver Tappe if (item == NULL) 361323b6546SOliver Tappe break; 362323b6546SOliver Tappe 363323b6546SOliver Tappe if (item->Message()) { 364323b6546SOliver Tappe switch (item->Message()->what) { 365323b6546SOliver Tappe case kFindButton: 366323b6546SOliver Tappe item->SetTarget(BMessenger(kTrackerSignature)); 367323b6546SOliver Tappe break; 368323b6546SOliver Tappe 369323b6546SOliver Tappe case kShowSplash: 370323b6546SOliver Tappe case kToggleDraggers: 371323b6546SOliver Tappe case kConfigShow: 372cb422386SJohn Scipione case kConfigQuit: 373323b6546SOliver Tappe case kAlwaysTop: 374573f748cSJohn Scipione case kExpandNewTeams: 375573f748cSJohn Scipione case kHideLabels: 376573f748cSJohn Scipione case kResizeTeamIcons: 377573f748cSJohn Scipione case kSortRunningApps: 378573f748cSJohn Scipione case kTrackerFirst: 379323b6546SOliver Tappe case kRebootSystem: 380323b6546SOliver Tappe case kSuspendSystem: 381323b6546SOliver Tappe case kShutdownSystem: 382*c0dc265cSJohn Scipione case kRealignReplicants: 383573f748cSJohn Scipione case kShowHideTime: 3843cf2d117SJohn Scipione case kShowSeconds: 3853cf2d117SJohn Scipione case kShowDayOfWeek: 38631c0024dSJohn Scipione case kShowTimeZone: 38731c0024dSJohn Scipione case kGetClockSettings: 38831c0024dSJohn Scipione item->SetTarget(be_app); 389573f748cSJohn Scipione break; 390323b6546SOliver Tappe } 391323b6546SOliver Tappe } 392323b6546SOliver Tappe } 393323b6546SOliver Tappe } 394323b6546SOliver Tappe 395323b6546SOliver Tappe 396323b6546SOliver Tappe BPoint 397323b6546SOliver Tappe TDeskbarMenu::ScreenLocation() 398323b6546SOliver Tappe { 399323b6546SOliver Tappe bool vertical = fBarView->Vertical(); 400323b6546SOliver Tappe int32 expando = (fBarView->State() == kExpandoState); 401323b6546SOliver Tappe BPoint point; 402323b6546SOliver Tappe 403323b6546SOliver Tappe BRect rect = Supermenu()->Bounds(); 404323b6546SOliver Tappe Supermenu()->ConvertToScreen(&rect); 405323b6546SOliver Tappe 406323b6546SOliver Tappe if (expando && vertical && fBarView->Left()) { 407323b6546SOliver Tappe PRINT(("Left\n")); 408323b6546SOliver Tappe point = rect.RightTop() + BPoint(0, 3); 409323b6546SOliver Tappe } else if (expando && vertical && !fBarView->Left()) { 410323b6546SOliver Tappe PRINT(("Right\n")); 411323b6546SOliver Tappe point = rect.LeftTop() - BPoint(Bounds().Width(), 0) + BPoint(0, 3); 412323b6546SOliver Tappe } else 413323b6546SOliver Tappe point = BMenu::ScreenLocation(); 414323b6546SOliver Tappe 415323b6546SOliver Tappe return point; 416323b6546SOliver Tappe } 417323b6546SOliver Tappe 418323b6546SOliver Tappe 419323b6546SOliver Tappe /*static*/ 420323b6546SOliver Tappe BMessenger 421323b6546SOliver Tappe TDeskbarMenu::DefaultTarget() 422323b6546SOliver Tappe { 423323b6546SOliver Tappe // if Tracker is not available we target the BarApp 424323b6546SOliver Tappe BMessenger target(kTrackerSignature); 425323b6546SOliver Tappe if (target.IsValid()) 426323b6546SOliver Tappe return target; 427323b6546SOliver Tappe 428323b6546SOliver Tappe return BMessenger(be_app); 429323b6546SOliver Tappe } 430323b6546SOliver Tappe 431323b6546SOliver Tappe 432323b6546SOliver Tappe // #pragma mark - 433323b6546SOliver Tappe 434323b6546SOliver Tappe 435323b6546SOliver Tappe TRecentsMenu::TRecentsMenu(const char* name, TBarView* bar, int32 which, 436323b6546SOliver Tappe const char* signature, entry_ref* appRef) 437323b6546SOliver Tappe : BNavMenu(name, B_REFS_RECEIVED, TDeskbarMenu::DefaultTarget()), 438323b6546SOliver Tappe fWhich(which), 439323b6546SOliver Tappe fAppRef(NULL), 440323b6546SOliver Tappe fSignature(NULL), 441323b6546SOliver Tappe fRecentsCount(0), 442323b6546SOliver Tappe fRecentsEnabled(false), 443323b6546SOliver Tappe fItemIndex(0), 444323b6546SOliver Tappe fBarView(bar) 445323b6546SOliver Tappe { 446323b6546SOliver Tappe TBarApp* app = dynamic_cast<TBarApp*>(be_app); 447323b6546SOliver Tappe if (app == NULL) 448323b6546SOliver Tappe return; 449323b6546SOliver Tappe 450323b6546SOliver Tappe switch (which) { 451323b6546SOliver Tappe case kRecentDocuments: 452323b6546SOliver Tappe fRecentsCount = app->Settings()->recentDocsCount; 453323b6546SOliver Tappe fRecentsEnabled = app->Settings()->recentDocsEnabled; 454323b6546SOliver Tappe break; 455323b6546SOliver Tappe case kRecentApplications: 456323b6546SOliver Tappe fRecentsCount = app->Settings()->recentAppsCount; 457323b6546SOliver Tappe fRecentsEnabled = app->Settings()->recentAppsEnabled; 458323b6546SOliver Tappe break; 459323b6546SOliver Tappe case kRecentAppDocuments: 460323b6546SOliver Tappe fRecentsCount = app->Settings()->recentDocsCount; 461323b6546SOliver Tappe fRecentsEnabled = app->Settings()->recentDocsEnabled; 462323b6546SOliver Tappe if (signature != NULL) 463323b6546SOliver Tappe fSignature = strdup(signature); 464323b6546SOliver Tappe if (appRef != NULL) 465323b6546SOliver Tappe fAppRef = new entry_ref(*appRef); 466323b6546SOliver Tappe break; 467323b6546SOliver Tappe case kRecentFolders: 468323b6546SOliver Tappe fRecentsCount = app->Settings()->recentFoldersCount; 469323b6546SOliver Tappe fRecentsEnabled = app->Settings()->recentFoldersEnabled; 470323b6546SOliver Tappe break; 471323b6546SOliver Tappe } 472323b6546SOliver Tappe } 473323b6546SOliver Tappe 474323b6546SOliver Tappe 475323b6546SOliver Tappe TRecentsMenu::~TRecentsMenu() 476323b6546SOliver Tappe { 477323b6546SOliver Tappe delete fAppRef; 478323b6546SOliver Tappe free(fSignature); 479323b6546SOliver Tappe } 480323b6546SOliver Tappe 481323b6546SOliver Tappe 482323b6546SOliver Tappe void 483323b6546SOliver Tappe TRecentsMenu::DetachedFromWindow() 484323b6546SOliver Tappe { 485323b6546SOliver Tappe // BNavMenu::DetachedFromWindow sets the TypesList to NULL 486323b6546SOliver Tappe BMenu::DetachedFromWindow(); 487323b6546SOliver Tappe } 488323b6546SOliver Tappe 489323b6546SOliver Tappe 490323b6546SOliver Tappe bool 491323b6546SOliver Tappe TRecentsMenu::StartBuildingItemList() 492323b6546SOliver Tappe { 493323b6546SOliver Tappe RemoveItems(0, CountItems(), true); 494323b6546SOliver Tappe 495323b6546SOliver Tappe // !! note: don't call inherited from here 496323b6546SOliver Tappe // the navref is not set for this menu 497323b6546SOliver Tappe // but it still needs to be a draggable navmenu 498323b6546SOliver Tappe // simply return true so that AddNextItem is called 499323b6546SOliver Tappe // 500323b6546SOliver Tappe // return BNavMenu::StartBuildingItemList(); 501323b6546SOliver Tappe return true; 502323b6546SOliver Tappe } 503323b6546SOliver Tappe 504323b6546SOliver Tappe 505323b6546SOliver Tappe bool 506323b6546SOliver Tappe TRecentsMenu::AddNextItem() 507323b6546SOliver Tappe { 508323b6546SOliver Tappe if (fRecentsCount > 0 && fRecentsEnabled && AddRecents(fRecentsCount)) 509323b6546SOliver Tappe return true; 510323b6546SOliver Tappe 511323b6546SOliver Tappe fItemIndex = 0; 512323b6546SOliver Tappe return false; 513323b6546SOliver Tappe } 514323b6546SOliver Tappe 515323b6546SOliver Tappe 516323b6546SOliver Tappe bool 517323b6546SOliver Tappe TRecentsMenu::AddRecents(int32 count) 518323b6546SOliver Tappe { 519323b6546SOliver Tappe if (fItemIndex == 0) { 520323b6546SOliver Tappe fRecentList.MakeEmpty(); 521323b6546SOliver Tappe BRoster roster; 522323b6546SOliver Tappe 523323b6546SOliver Tappe switch (fWhich) { 524323b6546SOliver Tappe case kRecentDocuments: 525323b6546SOliver Tappe roster.GetRecentDocuments(&fRecentList, count); 526323b6546SOliver Tappe break; 527323b6546SOliver Tappe case kRecentApplications: 528323b6546SOliver Tappe roster.GetRecentApps(&fRecentList, count); 529323b6546SOliver Tappe break; 530323b6546SOliver Tappe case kRecentAppDocuments: 531323b6546SOliver Tappe roster.GetRecentDocuments(&fRecentList, count, NULL, 532323b6546SOliver Tappe fSignature); 533323b6546SOliver Tappe break; 534323b6546SOliver Tappe case kRecentFolders: 535323b6546SOliver Tappe roster.GetRecentFolders(&fRecentList, count); 536323b6546SOliver Tappe break; 537323b6546SOliver Tappe default: 538323b6546SOliver Tappe return false; 539323b6546SOliver Tappe } 540323b6546SOliver Tappe } 541323b6546SOliver Tappe 542323b6546SOliver Tappe for (;;) { 543323b6546SOliver Tappe entry_ref ref; 544323b6546SOliver Tappe if (fRecentList.FindRef("refs", fItemIndex++, &ref) != B_OK) 545323b6546SOliver Tappe break; 546323b6546SOliver Tappe 547323b6546SOliver Tappe if (ref.name && strlen(ref.name) > 0) { 548323b6546SOliver Tappe Model model(&ref, true); 549323b6546SOliver Tappe 550323b6546SOliver Tappe if (fWhich != kRecentApplications) { 551323b6546SOliver Tappe BMessage* message = new BMessage(B_REFS_RECEIVED); 552323b6546SOliver Tappe if (fWhich == kRecentAppDocuments) { 553323b6546SOliver Tappe // add application as handler 554323b6546SOliver Tappe message->AddRef("handler", fAppRef); 555323b6546SOliver Tappe } 556323b6546SOliver Tappe 557323b6546SOliver Tappe ModelMenuItem* item = BNavMenu::NewModelItem(&model, 558323b6546SOliver Tappe message, Target(), false, NULL, TypesList()); 559323b6546SOliver Tappe 560323b6546SOliver Tappe if (item) 561323b6546SOliver Tappe AddItem(item); 562323b6546SOliver Tappe } else { 563323b6546SOliver Tappe // The application items expand to a list of recent documents 564323b6546SOliver Tappe // for that application - so they must be handled extra 565323b6546SOliver Tappe BFile file(&ref, B_READ_ONLY); 566323b6546SOliver Tappe char signature[B_MIME_TYPE_LENGTH]; 567323b6546SOliver Tappe 568323b6546SOliver Tappe BAppFileInfo appInfo(&file); 569323b6546SOliver Tappe if (appInfo.InitCheck() != B_OK 570323b6546SOliver Tappe || appInfo.GetSignature(signature) != B_OK) 571323b6546SOliver Tappe continue; 572323b6546SOliver Tappe 573323b6546SOliver Tappe ModelMenuItem* item = NULL; 574323b6546SOliver Tappe BMessage doc; 575323b6546SOliver Tappe be_roster->GetRecentDocuments(&doc, 1, NULL, signature); 576323b6546SOliver Tappe // ToDo: check if the documents do exist at all to 577323b6546SOliver Tappe // avoid the creation of the submenu. 578323b6546SOliver Tappe 579323b6546SOliver Tappe if (doc.CountNames(B_REF_TYPE) > 0) { 580323b6546SOliver Tappe // create recents menu that will contain the recent docs of 581323b6546SOliver Tappe // this app 582323b6546SOliver Tappe TRecentsMenu* docs = new TRecentsMenu(model.Name(), 583323b6546SOliver Tappe fBarView, kRecentAppDocuments, signature, &ref); 584323b6546SOliver Tappe docs->SetTypesList(TypesList()); 585323b6546SOliver Tappe docs->SetTarget(Target()); 586323b6546SOliver Tappe 587323b6546SOliver Tappe item = new ModelMenuItem(&model, docs); 588323b6546SOliver Tappe } else 589323b6546SOliver Tappe item = new ModelMenuItem(&model, model.Name(), NULL); 590323b6546SOliver Tappe 591323b6546SOliver Tappe if (item) { 592323b6546SOliver Tappe // add refs-message so that the recent app can be launched 593323b6546SOliver Tappe BMessage* msg = new BMessage(B_REFS_RECEIVED); 594323b6546SOliver Tappe msg->AddRef("refs", &ref); 595323b6546SOliver Tappe item->SetMessage(msg); 596323b6546SOliver Tappe item->SetTarget(Target()); 597323b6546SOliver Tappe 598323b6546SOliver Tappe AddItem(item); 599323b6546SOliver Tappe } 600323b6546SOliver Tappe } 601323b6546SOliver Tappe 602323b6546SOliver Tappe // return true so that we know to reenter this list 603323b6546SOliver Tappe return true; 604323b6546SOliver Tappe } 605323b6546SOliver Tappe } 606323b6546SOliver Tappe 607323b6546SOliver Tappe // return false if we are done with this list 608323b6546SOliver Tappe return false; 609323b6546SOliver Tappe } 610323b6546SOliver Tappe 611323b6546SOliver Tappe 612323b6546SOliver Tappe void 613323b6546SOliver Tappe TRecentsMenu::DoneBuildingItemList() 614323b6546SOliver Tappe { 615323b6546SOliver Tappe // !! note: don't call inherited here 616323b6546SOliver Tappe // the object list is not built 617323b6546SOliver Tappe // and this list does not need to be sorted 618323b6546SOliver Tappe // BNavMenu::DoneBuildingItemList(); 619323b6546SOliver Tappe 620323b6546SOliver Tappe if (CountItems() > 0) 621323b6546SOliver Tappe SetTargetForItems(Target()); 622323b6546SOliver Tappe } 623323b6546SOliver Tappe 624323b6546SOliver Tappe 625323b6546SOliver Tappe void 626323b6546SOliver Tappe TRecentsMenu::ClearMenuBuildingState() 627323b6546SOliver Tappe { 628323b6546SOliver Tappe fMenuBuilt = false; 629323b6546SOliver Tappe BNavMenu::ClearMenuBuildingState(); 630323b6546SOliver Tappe } 631323b6546SOliver Tappe 632323b6546SOliver Tappe 633323b6546SOliver Tappe void 634323b6546SOliver Tappe TRecentsMenu::ResetTargets() 635323b6546SOliver Tappe { 636323b6546SOliver Tappe BNavMenu::ResetTargets(); 637323b6546SOliver Tappe 638323b6546SOliver Tappe // if we are dragging, set the target to whatever was set 639323b6546SOliver Tappe // else set it to the default (Tracker) 640323b6546SOliver Tappe if (!fBarView->Dragging()) 641323b6546SOliver Tappe SetTarget(TDeskbarMenu::DefaultTarget()); 642323b6546SOliver Tappe 643323b6546SOliver Tappe // now set the target for the menuitems to the currently 644323b6546SOliver Tappe // set target, which may or may not be tracker 645323b6546SOliver Tappe SetTargetForItems(Target()); 646323b6546SOliver Tappe } 647323b6546SOliver Tappe 648323b6546SOliver Tappe 649088a9620SJohn Scipione // #pragma mark - DeskbarMountMenu 650323b6546SOliver Tappe 651323b6546SOliver Tappe 652323b6546SOliver Tappe #ifdef MOUNT_MENU_IN_DESKBAR 653323b6546SOliver Tappe DeskbarMountMenu::DeskbarMountMenu(const char* name) 654323b6546SOliver Tappe : BPrivate::MountMenu(name) 655323b6546SOliver Tappe { 656323b6546SOliver Tappe SetFont(be_plain_font); 657323b6546SOliver Tappe } 658323b6546SOliver Tappe 659323b6546SOliver Tappe 660323b6546SOliver Tappe bool 661323b6546SOliver Tappe DeskbarMountMenu::AddDynamicItem(add_state s) 662323b6546SOliver Tappe { 663323b6546SOliver Tappe BPrivate::MountMenu::AddDynamicItem(s); 664323b6546SOliver Tappe 665323b6546SOliver Tappe SetTargetForItems(BMessenger(kTrackerSignature)); 666323b6546SOliver Tappe 667323b6546SOliver Tappe return false; 668323b6546SOliver Tappe } 669088a9620SJohn Scipione #endif // MOUNT_MENU_IN_DESKBAR 670