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 "IconMenuItem.h" 54323b6546SOliver Tappe #include "MountMenu.h" 55323b6546SOliver Tappe #include "IconMenuItem.h" 56323b6546SOliver Tappe #include "MountMenu.h" 57323b6546SOliver Tappe #include "PublicCommands.h" 58323b6546SOliver Tappe #include "RecentItems.h" 59323b6546SOliver Tappe #include "StatusView.h" 60323b6546SOliver Tappe #include "tracker_private.h" 61323b6546SOliver Tappe 62546208a5SOliver Tappe #undef B_TRANSLATION_CONTEXT 63546208a5SOliver Tappe #define B_TRANSLATION_CONTEXT "DeskbarMenu" 64323b6546SOliver Tappe 65323b6546SOliver Tappe #define ROSTER_SIG "application/x-vnd.Be-ROST" 66323b6546SOliver Tappe 67323b6546SOliver Tappe #ifdef MOUNT_MENU_IN_DESKBAR 68323b6546SOliver Tappe 69323b6546SOliver Tappe class DeskbarMountMenu : public BPrivate::MountMenu { 70323b6546SOliver Tappe public: 71323b6546SOliver Tappe DeskbarMountMenu(const char* name); 72323b6546SOliver Tappe virtual bool AddDynamicItem(add_state s); 73323b6546SOliver Tappe }; 74323b6546SOliver Tappe 75323b6546SOliver Tappe #endif 76323b6546SOliver Tappe 77323b6546SOliver Tappe // #define SHOW_RECENT_FIND_ITEMS 78323b6546SOliver Tappe 79323b6546SOliver Tappe namespace BPrivate { 80323b6546SOliver Tappe BMenu* TrackerBuildRecentFindItemsMenu(const char*); 81323b6546SOliver Tappe } 82323b6546SOliver Tappe 83323b6546SOliver Tappe 84323b6546SOliver Tappe using namespace BPrivate; 85323b6546SOliver Tappe 86323b6546SOliver Tappe 87323b6546SOliver Tappe // #pragma mark - 88323b6546SOliver Tappe 89323b6546SOliver Tappe 90323b6546SOliver Tappe TDeskbarMenu::TDeskbarMenu(TBarView* barView) 91323b6546SOliver Tappe : BNavMenu("DeskbarMenu", B_REFS_RECEIVED, DefaultTarget()), 92323b6546SOliver Tappe fAddState(kStart), 93323b6546SOliver Tappe fBarView(barView) 94323b6546SOliver Tappe { 95323b6546SOliver Tappe } 96323b6546SOliver Tappe 97323b6546SOliver Tappe 98323b6546SOliver Tappe void 99323b6546SOliver Tappe TDeskbarMenu::AttachedToWindow() 100323b6546SOliver Tappe { 101323b6546SOliver Tappe if (fBarView && fBarView->LockLooper()) { 102323b6546SOliver Tappe if (fBarView->Dragging()) { 103323b6546SOliver Tappe SetTypesList(fBarView->CachedTypesList()); 104323b6546SOliver Tappe SetTarget(BMessenger(fBarView)); 105323b6546SOliver Tappe SetTrackingHookDeep(this, fBarView->MenuTrackingHook, 106323b6546SOliver Tappe fBarView->GetTrackingHookData()); 107323b6546SOliver Tappe fBarView->DragStart(); 108323b6546SOliver Tappe } else { 109323b6546SOliver Tappe SetTypesList(NULL); 110323b6546SOliver Tappe SetTarget(DefaultTarget()); 111323b6546SOliver Tappe SetTrackingHookDeep(this, NULL, NULL); 112323b6546SOliver Tappe } 113323b6546SOliver Tappe 114323b6546SOliver Tappe fBarView->UnlockLooper(); 115323b6546SOliver Tappe } 116323b6546SOliver Tappe 117323b6546SOliver Tappe BNavMenu::AttachedToWindow(); 118323b6546SOliver Tappe } 119323b6546SOliver Tappe 120323b6546SOliver Tappe 121323b6546SOliver Tappe void 122323b6546SOliver Tappe TDeskbarMenu::DetachedFromWindow() 123323b6546SOliver Tappe { 124323b6546SOliver Tappe if (fBarView) { 125323b6546SOliver Tappe BLooper* looper = fBarView->Looper(); 126323b6546SOliver Tappe if (looper && looper->Lock()) { 127323b6546SOliver Tappe fBarView->DragStop(); 128323b6546SOliver Tappe looper->Unlock(); 129323b6546SOliver Tappe } 130323b6546SOliver Tappe } 131323b6546SOliver Tappe 132323b6546SOliver Tappe // don't call BNavMenu::DetachedFromWindow 133323b6546SOliver Tappe // it sets the TypesList to NULL 134323b6546SOliver Tappe BMenu::DetachedFromWindow(); 135323b6546SOliver Tappe } 136323b6546SOliver Tappe 137323b6546SOliver Tappe 138323b6546SOliver Tappe bool 139323b6546SOliver Tappe TDeskbarMenu::StartBuildingItemList() 140323b6546SOliver Tappe { 141323b6546SOliver Tappe RemoveItems(0, CountItems(), true); 142323b6546SOliver Tappe fAddState = kStart; 143323b6546SOliver Tappe return BNavMenu::StartBuildingItemList(); 144323b6546SOliver Tappe } 145323b6546SOliver Tappe 146323b6546SOliver Tappe 147323b6546SOliver Tappe void 148323b6546SOliver Tappe TDeskbarMenu::DoneBuildingItemList() 149323b6546SOliver Tappe { 150323b6546SOliver Tappe if (fItemList->CountItems() <= 0) { 151323b6546SOliver Tappe BMenuItem* item 152323b6546SOliver Tappe = new BMenuItem(B_TRANSLATE("<Deskbar folder is empty>"), 0); 153323b6546SOliver Tappe item->SetEnabled(false); 154323b6546SOliver Tappe AddItem(item); 155323b6546SOliver Tappe } else 156323b6546SOliver Tappe BNavMenu::DoneBuildingItemList(); 157323b6546SOliver Tappe } 158323b6546SOliver Tappe 159323b6546SOliver Tappe 160323b6546SOliver Tappe bool 161323b6546SOliver Tappe TDeskbarMenu::AddNextItem() 162323b6546SOliver Tappe { 163323b6546SOliver Tappe if (fAddState == kStart) 164323b6546SOliver Tappe return AddStandardDeskbarMenuItems(); 165323b6546SOliver Tappe 166323b6546SOliver Tappe TrackingHookData* data = fBarView->GetTrackingHookData(); 167323b6546SOliver Tappe if (fAddState == kAddingRecents) { 168323b6546SOliver Tappe static const char* recentTitle[] = { 169323b6546SOliver Tappe B_TRANSLATE_MARK("Recent documents"), 170323b6546SOliver Tappe B_TRANSLATE_MARK("Recent folders"), 171323b6546SOliver Tappe B_TRANSLATE_MARK("Recent applications")}; 172323b6546SOliver Tappe const int recentType[] = {kRecentDocuments, kRecentFolders, 173323b6546SOliver Tappe kRecentApplications}; 174323b6546SOliver Tappe const int recentTypes = 3; 175323b6546SOliver Tappe TRecentsMenu* recentItem[recentTypes]; 176323b6546SOliver Tappe 177323b6546SOliver Tappe bool enabled = false; 178323b6546SOliver Tappe 179323b6546SOliver Tappe for (int i = 0; i < recentTypes; i++) { 180323b6546SOliver Tappe recentItem[i] 181323b6546SOliver Tappe = new TRecentsMenu(B_TRANSLATE_NOCOLLECT(recentTitle[i]), 182323b6546SOliver Tappe fBarView, recentType[i]); 183323b6546SOliver Tappe 184323b6546SOliver Tappe if (recentItem[i]) 185323b6546SOliver Tappe enabled |= recentItem[i]->RecentsEnabled(); 186323b6546SOliver Tappe } 187323b6546SOliver Tappe if (enabled) { 188323b6546SOliver Tappe AddSeparatorItem(); 189323b6546SOliver Tappe 190323b6546SOliver Tappe for (int i = 0; i < recentTypes; i++) { 191323b6546SOliver Tappe if (!recentItem[i]) 192323b6546SOliver Tappe continue; 193323b6546SOliver Tappe 194323b6546SOliver Tappe if (recentItem[i]->RecentsEnabled()) { 195323b6546SOliver Tappe recentItem[i]->SetTypesList(TypesList()); 196323b6546SOliver Tappe recentItem[i]->SetTarget(Target()); 197323b6546SOliver Tappe AddItem(recentItem[i]); 198323b6546SOliver Tappe } 199323b6546SOliver Tappe 200323b6546SOliver Tappe if (data && fBarView && fBarView->Dragging()) { 201323b6546SOliver Tappe recentItem[i]->InitTrackingHook(data->fTrackingHook, 202323b6546SOliver Tappe &data->fTarget, data->fDragMessage); 203323b6546SOliver Tappe } 204323b6546SOliver Tappe } 205323b6546SOliver Tappe } 206323b6546SOliver Tappe 207323b6546SOliver Tappe AddSeparatorItem(); 208323b6546SOliver Tappe fAddState = kAddingDeskbarMenu; 209323b6546SOliver Tappe return true; 210323b6546SOliver Tappe } 211323b6546SOliver Tappe 212323b6546SOliver Tappe if (fAddState == kAddingDeskbarMenu) { 213323b6546SOliver Tappe // keep reentering and adding items 214323b6546SOliver Tappe // until this returns false 215323b6546SOliver Tappe bool done = BNavMenu::AddNextItem(); 216323b6546SOliver Tappe BMenuItem* item = ItemAt(CountItems() - 1); 217323b6546SOliver Tappe if (item) { 218323b6546SOliver Tappe BNavMenu* menu = dynamic_cast<BNavMenu*>(item->Menu()); 219323b6546SOliver Tappe if (menu) { 220323b6546SOliver Tappe if (data && fBarView->Dragging()) { 221323b6546SOliver Tappe menu->InitTrackingHook(data->fTrackingHook, 222323b6546SOliver Tappe &data->fTarget, data->fDragMessage); 223323b6546SOliver Tappe } else 224323b6546SOliver Tappe menu->InitTrackingHook(0, NULL, NULL); 225323b6546SOliver Tappe } 226323b6546SOliver Tappe } 227323b6546SOliver Tappe 228323b6546SOliver Tappe if (!done) 229323b6546SOliver Tappe fAddState = kDone; 230323b6546SOliver Tappe return done; 231323b6546SOliver Tappe } 232323b6546SOliver Tappe 233323b6546SOliver Tappe return false; 234323b6546SOliver Tappe } 235323b6546SOliver Tappe 236323b6546SOliver Tappe 237323b6546SOliver Tappe bool 238323b6546SOliver Tappe TDeskbarMenu::AddStandardDeskbarMenuItems() 239323b6546SOliver Tappe { 240323b6546SOliver Tappe bool dragging = false; 241323b6546SOliver Tappe if (fBarView) 242323b6546SOliver Tappe dragging = fBarView->Dragging(); 243323b6546SOliver Tappe 244323b6546SOliver Tappe BMenuItem* item; 245323b6546SOliver Tappe BRoster roster; 246323b6546SOliver Tappe if (!roster.IsRunning(kTrackerSignature)) { 247323b6546SOliver Tappe item = new BMenuItem(B_TRANSLATE("Restart Tracker"), 248323b6546SOliver Tappe new BMessage(kRestartTracker)); 249323b6546SOliver Tappe AddItem(item); 250323b6546SOliver Tappe AddSeparatorItem(); 251323b6546SOliver Tappe } 252323b6546SOliver Tappe 253323b6546SOliver Tappe // One of them is used if HAIKU_DISTRO_COMPATIBILITY_OFFICIAL, and the other if 254323b6546SOliver Tappe // not. However, we want both of them to end up in the catalog, so we have to 255323b6546SOliver Tappe // make them visible to collectcatkeys in either case. 256028ad031SAdrien Destugues - PulkoMandy B_TRANSLATE_MARK_VOID("About Haiku") 257028ad031SAdrien Destugues - PulkoMandy B_TRANSLATE_MARK_VOID("About this system") 258323b6546SOliver Tappe 259323b6546SOliver Tappe item = new BMenuItem( 260323b6546SOliver Tappe #ifdef HAIKU_DISTRO_COMPATIBILITY_OFFICIAL 261028ad031SAdrien Destugues - PulkoMandy B_TRANSLATE_NOCOLLECT("About Haiku") 262323b6546SOliver Tappe #else 263028ad031SAdrien Destugues - PulkoMandy B_TRANSLATE_NOCOLLECT("About this system") 264323b6546SOliver Tappe #endif 265323b6546SOliver Tappe , new BMessage(kShowSplash)); 266323b6546SOliver Tappe item->SetEnabled(!dragging); 267323b6546SOliver Tappe AddItem(item); 268323b6546SOliver Tappe 269323b6546SOliver Tappe static const char* kFindMenuItemStr 270323b6546SOliver Tappe = B_TRANSLATE_MARK("Find" B_UTF8_ELLIPSIS); 271323b6546SOliver Tappe 272323b6546SOliver Tappe #ifdef SHOW_RECENT_FIND_ITEMS 273323b6546SOliver Tappe item = new BMenuItem( 274323b6546SOliver Tappe TrackerBuildRecentFindItemsMenu(kFindMenuItemStr), 275323b6546SOliver Tappe new BMessage(kFindButton)); 276323b6546SOliver Tappe #else 277323b6546SOliver Tappe item = new BMenuItem(B_TRANSLATE_NOCOLLECT(kFindMenuItemStr), 278323b6546SOliver Tappe new BMessage(kFindButton)); 279323b6546SOliver Tappe #endif 280323b6546SOliver Tappe item->SetEnabled(!dragging); 281323b6546SOliver Tappe AddItem(item); 282323b6546SOliver Tappe 283323b6546SOliver Tappe item = new BMenuItem(B_TRANSLATE("Show replicants"), 284323b6546SOliver Tappe new BMessage(kToggleDraggers)); 285323b6546SOliver Tappe item->SetEnabled(!dragging); 286323b6546SOliver Tappe item->SetMarked(BDragger::AreDraggersDrawn()); 287323b6546SOliver Tappe AddItem(item); 288323b6546SOliver Tappe 289323b6546SOliver Tappe static const char* kMountMenuStr = B_TRANSLATE_MARK("Mount"); 290323b6546SOliver Tappe 291323b6546SOliver Tappe #ifdef MOUNT_MENU_IN_DESKBAR 292323b6546SOliver Tappe DeskbarMountMenu* mountMenu = new DeskbarMountMenu( 293323b6546SOliver Tappe B_TRANSLATE_NOCOLLECT(kMountMenuStr)); 294323b6546SOliver Tappe mountMenu->SetEnabled(!dragging); 295323b6546SOliver Tappe AddItem(mountMenu); 296323b6546SOliver Tappe #endif 297323b6546SOliver Tappe 298323b6546SOliver Tappe item = new BMenuItem(B_TRANSLATE("Deskbar preferences" B_UTF8_ELLIPSIS), 299323b6546SOliver Tappe new BMessage(kConfigShow)); 300323b6546SOliver Tappe item->SetTarget(be_app); 301323b6546SOliver Tappe AddItem(item); 302323b6546SOliver Tappe 303323b6546SOliver Tappe AddSeparatorItem(); 304323b6546SOliver Tappe 305323b6546SOliver Tappe BMenu* shutdownMenu = new BMenu(B_TRANSLATE("Shutdown" B_UTF8_ELLIPSIS)); 306323b6546SOliver Tappe 307323b6546SOliver Tappe item = new BMenuItem(B_TRANSLATE("Restart system"), 308323b6546SOliver Tappe new BMessage(kRebootSystem)); 309323b6546SOliver Tappe item->SetEnabled(!dragging); 310323b6546SOliver Tappe shutdownMenu->AddItem(item); 311323b6546SOliver Tappe 312028ad031SAdrien Destugues - PulkoMandy B_TRANSLATE_MARK_VOID("Suspend"); 313323b6546SOliver Tappe 314323b6546SOliver Tappe #ifdef APM_SUPPORT 315323b6546SOliver Tappe if (_kapm_control_(APM_CHECK_ENABLED) == B_OK) { 316028ad031SAdrien Destugues - PulkoMandy item = new BMenuItem(B_TRANSLATE_NOCOLLECT("Suspend"), 317323b6546SOliver Tappe new BMessage(kSuspendSystem)); 318323b6546SOliver Tappe item->SetEnabled(!dragging); 319323b6546SOliver Tappe shutdownMenu->AddItem(item); 320323b6546SOliver Tappe } 321323b6546SOliver Tappe #endif 322323b6546SOliver Tappe 323323b6546SOliver Tappe item = new BMenuItem(B_TRANSLATE("Power off"), 324323b6546SOliver Tappe new BMessage(kShutdownSystem)); 325323b6546SOliver Tappe item->SetEnabled(!dragging); 326323b6546SOliver Tappe shutdownMenu->AddItem(item); 327323b6546SOliver Tappe shutdownMenu->SetFont(be_plain_font); 328323b6546SOliver Tappe 329323b6546SOliver Tappe shutdownMenu->SetTargetForItems(be_app); 330323b6546SOliver Tappe BMessage* message = new BMessage(kShutdownSystem); 331323b6546SOliver Tappe message->AddBool("confirm", true); 332323b6546SOliver Tappe AddItem(new BMenuItem(shutdownMenu, message)); 333323b6546SOliver Tappe 334323b6546SOliver Tappe fAddState = kAddingRecents; 335323b6546SOliver Tappe 336323b6546SOliver Tappe return true; 337323b6546SOliver Tappe } 338323b6546SOliver Tappe 339323b6546SOliver Tappe 340323b6546SOliver Tappe void 341323b6546SOliver Tappe TDeskbarMenu::ClearMenuBuildingState() 342323b6546SOliver Tappe { 343323b6546SOliver Tappe fAddState = kDone; 344323b6546SOliver Tappe fMenuBuilt = false; 345323b6546SOliver Tappe // force the menu to get rebuilt each time 346323b6546SOliver Tappe BNavMenu::ClearMenuBuildingState(); 347323b6546SOliver Tappe } 348323b6546SOliver Tappe 349323b6546SOliver Tappe 350323b6546SOliver Tappe void 351323b6546SOliver Tappe TDeskbarMenu::ResetTargets() 352323b6546SOliver Tappe { 353323b6546SOliver Tappe // This method does not recurse into submenus 354323b6546SOliver Tappe // and does not affect menu items in submenus. 355323b6546SOliver Tappe // (e.g. "Restart System" and "Power Off") 356323b6546SOliver Tappe 357323b6546SOliver Tappe BNavMenu::ResetTargets(); 358323b6546SOliver Tappe 359323b6546SOliver Tappe // if we are dragging, set the target to whatever was set 360323b6546SOliver Tappe // else set it to the default (Tracker) 361323b6546SOliver Tappe if (!fBarView->Dragging()) 362323b6546SOliver Tappe SetTarget(DefaultTarget()); 363323b6546SOliver Tappe 364323b6546SOliver Tappe // now set the target for the menuitems to the currently 365323b6546SOliver Tappe // set target, which may or may not be tracker 366323b6546SOliver Tappe SetTargetForItems(Target()); 367323b6546SOliver Tappe 368323b6546SOliver Tappe for (int32 i = 0; ; i++) { 369323b6546SOliver Tappe BMenuItem* item = ItemAt(i); 370323b6546SOliver Tappe if (item == NULL) 371323b6546SOliver Tappe break; 372323b6546SOliver Tappe 373323b6546SOliver Tappe if (item->Message()) { 374323b6546SOliver Tappe switch (item->Message()->what) { 375323b6546SOliver Tappe case kFindButton: 376323b6546SOliver Tappe item->SetTarget(BMessenger(kTrackerSignature)); 377323b6546SOliver Tappe break; 378323b6546SOliver Tappe 379323b6546SOliver Tappe case kShowSplash: 380323b6546SOliver Tappe case kToggleDraggers: 381323b6546SOliver Tappe case kConfigShow: 382*cb422386SJohn Scipione case kConfigQuit: 383323b6546SOliver Tappe case kAlwaysTop: 384573f748cSJohn Scipione case kExpandNewTeams: 385573f748cSJohn Scipione case kHideLabels: 386573f748cSJohn Scipione case kResizeTeamIcons: 387573f748cSJohn Scipione case kSortRunningApps: 388573f748cSJohn Scipione case kTrackerFirst: 389323b6546SOliver Tappe case kRebootSystem: 390323b6546SOliver Tappe case kSuspendSystem: 391323b6546SOliver Tappe case kShutdownSystem: 392573f748cSJohn Scipione case kShowHideTime: 3933cf2d117SJohn Scipione case kShowSeconds: 3943cf2d117SJohn Scipione case kShowDayOfWeek: 39531c0024dSJohn Scipione case kShowTimeZone: 39631c0024dSJohn Scipione case kGetClockSettings: 39731c0024dSJohn Scipione item->SetTarget(be_app); 398573f748cSJohn Scipione break; 399323b6546SOliver Tappe } 400323b6546SOliver Tappe } 401323b6546SOliver Tappe } 402323b6546SOliver Tappe } 403323b6546SOliver Tappe 404323b6546SOliver Tappe 405323b6546SOliver Tappe BPoint 406323b6546SOliver Tappe TDeskbarMenu::ScreenLocation() 407323b6546SOliver Tappe { 408323b6546SOliver Tappe bool vertical = fBarView->Vertical(); 409323b6546SOliver Tappe int32 expando = (fBarView->State() == kExpandoState); 410323b6546SOliver Tappe BPoint point; 411323b6546SOliver Tappe 412323b6546SOliver Tappe BRect rect = Supermenu()->Bounds(); 413323b6546SOliver Tappe Supermenu()->ConvertToScreen(&rect); 414323b6546SOliver Tappe 415323b6546SOliver Tappe if (expando && vertical && fBarView->Left()) { 416323b6546SOliver Tappe PRINT(("Left\n")); 417323b6546SOliver Tappe point = rect.RightTop() + BPoint(0, 3); 418323b6546SOliver Tappe } else if (expando && vertical && !fBarView->Left()) { 419323b6546SOliver Tappe PRINT(("Right\n")); 420323b6546SOliver Tappe point = rect.LeftTop() - BPoint(Bounds().Width(), 0) + BPoint(0, 3); 421323b6546SOliver Tappe } else 422323b6546SOliver Tappe point = BMenu::ScreenLocation(); 423323b6546SOliver Tappe 424323b6546SOliver Tappe return point; 425323b6546SOliver Tappe } 426323b6546SOliver Tappe 427323b6546SOliver Tappe 428323b6546SOliver Tappe /*static*/ 429323b6546SOliver Tappe BMessenger 430323b6546SOliver Tappe TDeskbarMenu::DefaultTarget() 431323b6546SOliver Tappe { 432323b6546SOliver Tappe // if Tracker is not available we target the BarApp 433323b6546SOliver Tappe BMessenger target(kTrackerSignature); 434323b6546SOliver Tappe if (target.IsValid()) 435323b6546SOliver Tappe return target; 436323b6546SOliver Tappe 437323b6546SOliver Tappe return BMessenger(be_app); 438323b6546SOliver Tappe } 439323b6546SOliver Tappe 440323b6546SOliver Tappe 441323b6546SOliver Tappe // #pragma mark - 442323b6546SOliver Tappe 443323b6546SOliver Tappe 444323b6546SOliver Tappe TRecentsMenu::TRecentsMenu(const char* name, TBarView* bar, int32 which, 445323b6546SOliver Tappe const char* signature, entry_ref* appRef) 446323b6546SOliver Tappe : BNavMenu(name, B_REFS_RECEIVED, TDeskbarMenu::DefaultTarget()), 447323b6546SOliver Tappe fWhich(which), 448323b6546SOliver Tappe fAppRef(NULL), 449323b6546SOliver Tappe fSignature(NULL), 450323b6546SOliver Tappe fRecentsCount(0), 451323b6546SOliver Tappe fRecentsEnabled(false), 452323b6546SOliver Tappe fItemIndex(0), 453323b6546SOliver Tappe fBarView(bar) 454323b6546SOliver Tappe { 455323b6546SOliver Tappe TBarApp* app = dynamic_cast<TBarApp*>(be_app); 456323b6546SOliver Tappe if (app == NULL) 457323b6546SOliver Tappe return; 458323b6546SOliver Tappe 459323b6546SOliver Tappe switch (which) { 460323b6546SOliver Tappe case kRecentDocuments: 461323b6546SOliver Tappe fRecentsCount = app->Settings()->recentDocsCount; 462323b6546SOliver Tappe fRecentsEnabled = app->Settings()->recentDocsEnabled; 463323b6546SOliver Tappe break; 464323b6546SOliver Tappe case kRecentApplications: 465323b6546SOliver Tappe fRecentsCount = app->Settings()->recentAppsCount; 466323b6546SOliver Tappe fRecentsEnabled = app->Settings()->recentAppsEnabled; 467323b6546SOliver Tappe break; 468323b6546SOliver Tappe case kRecentAppDocuments: 469323b6546SOliver Tappe fRecentsCount = app->Settings()->recentDocsCount; 470323b6546SOliver Tappe fRecentsEnabled = app->Settings()->recentDocsEnabled; 471323b6546SOliver Tappe if (signature != NULL) 472323b6546SOliver Tappe fSignature = strdup(signature); 473323b6546SOliver Tappe if (appRef != NULL) 474323b6546SOliver Tappe fAppRef = new entry_ref(*appRef); 475323b6546SOliver Tappe break; 476323b6546SOliver Tappe case kRecentFolders: 477323b6546SOliver Tappe fRecentsCount = app->Settings()->recentFoldersCount; 478323b6546SOliver Tappe fRecentsEnabled = app->Settings()->recentFoldersEnabled; 479323b6546SOliver Tappe break; 480323b6546SOliver Tappe } 481323b6546SOliver Tappe } 482323b6546SOliver Tappe 483323b6546SOliver Tappe 484323b6546SOliver Tappe TRecentsMenu::~TRecentsMenu() 485323b6546SOliver Tappe { 486323b6546SOliver Tappe delete fAppRef; 487323b6546SOliver Tappe free(fSignature); 488323b6546SOliver Tappe } 489323b6546SOliver Tappe 490323b6546SOliver Tappe 491323b6546SOliver Tappe void 492323b6546SOliver Tappe TRecentsMenu::DetachedFromWindow() 493323b6546SOliver Tappe { 494323b6546SOliver Tappe // BNavMenu::DetachedFromWindow sets the TypesList to NULL 495323b6546SOliver Tappe BMenu::DetachedFromWindow(); 496323b6546SOliver Tappe } 497323b6546SOliver Tappe 498323b6546SOliver Tappe 499323b6546SOliver Tappe bool 500323b6546SOliver Tappe TRecentsMenu::StartBuildingItemList() 501323b6546SOliver Tappe { 502323b6546SOliver Tappe RemoveItems(0, CountItems(), true); 503323b6546SOliver Tappe 504323b6546SOliver Tappe // !! note: don't call inherited from here 505323b6546SOliver Tappe // the navref is not set for this menu 506323b6546SOliver Tappe // but it still needs to be a draggable navmenu 507323b6546SOliver Tappe // simply return true so that AddNextItem is called 508323b6546SOliver Tappe // 509323b6546SOliver Tappe // return BNavMenu::StartBuildingItemList(); 510323b6546SOliver Tappe return true; 511323b6546SOliver Tappe } 512323b6546SOliver Tappe 513323b6546SOliver Tappe 514323b6546SOliver Tappe bool 515323b6546SOliver Tappe TRecentsMenu::AddNextItem() 516323b6546SOliver Tappe { 517323b6546SOliver Tappe if (fRecentsCount > 0 && fRecentsEnabled && AddRecents(fRecentsCount)) 518323b6546SOliver Tappe return true; 519323b6546SOliver Tappe 520323b6546SOliver Tappe fItemIndex = 0; 521323b6546SOliver Tappe return false; 522323b6546SOliver Tappe } 523323b6546SOliver Tappe 524323b6546SOliver Tappe 525323b6546SOliver Tappe bool 526323b6546SOliver Tappe TRecentsMenu::AddRecents(int32 count) 527323b6546SOliver Tappe { 528323b6546SOliver Tappe if (fItemIndex == 0) { 529323b6546SOliver Tappe fRecentList.MakeEmpty(); 530323b6546SOliver Tappe BRoster roster; 531323b6546SOliver Tappe 532323b6546SOliver Tappe switch (fWhich) { 533323b6546SOliver Tappe case kRecentDocuments: 534323b6546SOliver Tappe roster.GetRecentDocuments(&fRecentList, count); 535323b6546SOliver Tappe break; 536323b6546SOliver Tappe case kRecentApplications: 537323b6546SOliver Tappe roster.GetRecentApps(&fRecentList, count); 538323b6546SOliver Tappe break; 539323b6546SOliver Tappe case kRecentAppDocuments: 540323b6546SOliver Tappe roster.GetRecentDocuments(&fRecentList, count, NULL, 541323b6546SOliver Tappe fSignature); 542323b6546SOliver Tappe break; 543323b6546SOliver Tappe case kRecentFolders: 544323b6546SOliver Tappe roster.GetRecentFolders(&fRecentList, count); 545323b6546SOliver Tappe break; 546323b6546SOliver Tappe default: 547323b6546SOliver Tappe return false; 548323b6546SOliver Tappe } 549323b6546SOliver Tappe } 550323b6546SOliver Tappe 551323b6546SOliver Tappe for (;;) { 552323b6546SOliver Tappe entry_ref ref; 553323b6546SOliver Tappe if (fRecentList.FindRef("refs", fItemIndex++, &ref) != B_OK) 554323b6546SOliver Tappe break; 555323b6546SOliver Tappe 556323b6546SOliver Tappe if (ref.name && strlen(ref.name) > 0) { 557323b6546SOliver Tappe Model model(&ref, true); 558323b6546SOliver Tappe 559323b6546SOliver Tappe if (fWhich != kRecentApplications) { 560323b6546SOliver Tappe BMessage* message = new BMessage(B_REFS_RECEIVED); 561323b6546SOliver Tappe if (fWhich == kRecentAppDocuments) { 562323b6546SOliver Tappe // add application as handler 563323b6546SOliver Tappe message->AddRef("handler", fAppRef); 564323b6546SOliver Tappe } 565323b6546SOliver Tappe 566323b6546SOliver Tappe ModelMenuItem* item = BNavMenu::NewModelItem(&model, 567323b6546SOliver Tappe message, Target(), false, NULL, TypesList()); 568323b6546SOliver Tappe 569323b6546SOliver Tappe if (item) 570323b6546SOliver Tappe AddItem(item); 571323b6546SOliver Tappe } else { 572323b6546SOliver Tappe // The application items expand to a list of recent documents 573323b6546SOliver Tappe // for that application - so they must be handled extra 574323b6546SOliver Tappe BFile file(&ref, B_READ_ONLY); 575323b6546SOliver Tappe char signature[B_MIME_TYPE_LENGTH]; 576323b6546SOliver Tappe 577323b6546SOliver Tappe BAppFileInfo appInfo(&file); 578323b6546SOliver Tappe if (appInfo.InitCheck() != B_OK 579323b6546SOliver Tappe || appInfo.GetSignature(signature) != B_OK) 580323b6546SOliver Tappe continue; 581323b6546SOliver Tappe 582323b6546SOliver Tappe ModelMenuItem* item = NULL; 583323b6546SOliver Tappe BMessage doc; 584323b6546SOliver Tappe be_roster->GetRecentDocuments(&doc, 1, NULL, signature); 585323b6546SOliver Tappe // ToDo: check if the documents do exist at all to 586323b6546SOliver Tappe // avoid the creation of the submenu. 587323b6546SOliver Tappe 588323b6546SOliver Tappe if (doc.CountNames(B_REF_TYPE) > 0) { 589323b6546SOliver Tappe // create recents menu that will contain the recent docs of 590323b6546SOliver Tappe // this app 591323b6546SOliver Tappe TRecentsMenu* docs = new TRecentsMenu(model.Name(), 592323b6546SOliver Tappe fBarView, kRecentAppDocuments, signature, &ref); 593323b6546SOliver Tappe docs->SetTypesList(TypesList()); 594323b6546SOliver Tappe docs->SetTarget(Target()); 595323b6546SOliver Tappe 596323b6546SOliver Tappe item = new ModelMenuItem(&model, docs); 597323b6546SOliver Tappe } else 598323b6546SOliver Tappe item = new ModelMenuItem(&model, model.Name(), NULL); 599323b6546SOliver Tappe 600323b6546SOliver Tappe if (item) { 601323b6546SOliver Tappe // add refs-message so that the recent app can be launched 602323b6546SOliver Tappe BMessage* msg = new BMessage(B_REFS_RECEIVED); 603323b6546SOliver Tappe msg->AddRef("refs", &ref); 604323b6546SOliver Tappe item->SetMessage(msg); 605323b6546SOliver Tappe item->SetTarget(Target()); 606323b6546SOliver Tappe 607323b6546SOliver Tappe AddItem(item); 608323b6546SOliver Tappe } 609323b6546SOliver Tappe } 610323b6546SOliver Tappe 611323b6546SOliver Tappe // return true so that we know to reenter this list 612323b6546SOliver Tappe return true; 613323b6546SOliver Tappe } 614323b6546SOliver Tappe } 615323b6546SOliver Tappe 616323b6546SOliver Tappe // return false if we are done with this list 617323b6546SOliver Tappe return false; 618323b6546SOliver Tappe } 619323b6546SOliver Tappe 620323b6546SOliver Tappe 621323b6546SOliver Tappe void 622323b6546SOliver Tappe TRecentsMenu::DoneBuildingItemList() 623323b6546SOliver Tappe { 624323b6546SOliver Tappe // !! note: don't call inherited here 625323b6546SOliver Tappe // the object list is not built 626323b6546SOliver Tappe // and this list does not need to be sorted 627323b6546SOliver Tappe // BNavMenu::DoneBuildingItemList(); 628323b6546SOliver Tappe 629323b6546SOliver Tappe if (CountItems() > 0) 630323b6546SOliver Tappe SetTargetForItems(Target()); 631323b6546SOliver Tappe } 632323b6546SOliver Tappe 633323b6546SOliver Tappe 634323b6546SOliver Tappe void 635323b6546SOliver Tappe TRecentsMenu::ClearMenuBuildingState() 636323b6546SOliver Tappe { 637323b6546SOliver Tappe fMenuBuilt = false; 638323b6546SOliver Tappe BNavMenu::ClearMenuBuildingState(); 639323b6546SOliver Tappe } 640323b6546SOliver Tappe 641323b6546SOliver Tappe 642323b6546SOliver Tappe void 643323b6546SOliver Tappe TRecentsMenu::ResetTargets() 644323b6546SOliver Tappe { 645323b6546SOliver Tappe BNavMenu::ResetTargets(); 646323b6546SOliver Tappe 647323b6546SOliver Tappe // if we are dragging, set the target to whatever was set 648323b6546SOliver Tappe // else set it to the default (Tracker) 649323b6546SOliver Tappe if (!fBarView->Dragging()) 650323b6546SOliver Tappe SetTarget(TDeskbarMenu::DefaultTarget()); 651323b6546SOliver Tappe 652323b6546SOliver Tappe // now set the target for the menuitems to the currently 653323b6546SOliver Tappe // set target, which may or may not be tracker 654323b6546SOliver Tappe SetTargetForItems(Target()); 655323b6546SOliver Tappe } 656323b6546SOliver Tappe 657323b6546SOliver Tappe 658323b6546SOliver Tappe //***************************************************************************** 659323b6546SOliver Tappe // #pragma mark - 660323b6546SOliver Tappe 661323b6546SOliver Tappe 662323b6546SOliver Tappe #ifdef MOUNT_MENU_IN_DESKBAR 663323b6546SOliver Tappe 664323b6546SOliver Tappe DeskbarMountMenu::DeskbarMountMenu(const char* name) 665323b6546SOliver Tappe : BPrivate::MountMenu(name) 666323b6546SOliver Tappe { 667323b6546SOliver Tappe SetFont(be_plain_font); 668323b6546SOliver Tappe } 669323b6546SOliver Tappe 670323b6546SOliver Tappe 671323b6546SOliver Tappe bool 672323b6546SOliver Tappe DeskbarMountMenu::AddDynamicItem(add_state s) 673323b6546SOliver Tappe { 674323b6546SOliver Tappe BPrivate::MountMenu::AddDynamicItem(s); 675323b6546SOliver Tappe 676323b6546SOliver Tappe SetTargetForItems(BMessenger(kTrackerSignature)); 677323b6546SOliver Tappe 678323b6546SOliver Tappe return false; 679323b6546SOliver Tappe } 680323b6546SOliver Tappe 681323b6546SOliver Tappe #endif 682