1*323b6546SOliver Tappe /* 2*323b6546SOliver Tappe Open Tracker License 3*323b6546SOliver Tappe 4*323b6546SOliver Tappe Terms and Conditions 5*323b6546SOliver Tappe 6*323b6546SOliver Tappe Copyright (c) 1991-2000, Be Incorporated. All rights reserved. 7*323b6546SOliver Tappe 8*323b6546SOliver Tappe Permission is hereby granted, free of charge, to any person obtaining a copy of 9*323b6546SOliver Tappe this software and associated documentation files (the "Software"), to deal in 10*323b6546SOliver Tappe the Software without restriction, including without limitation the rights to 11*323b6546SOliver Tappe use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 12*323b6546SOliver Tappe of the Software, and to permit persons to whom the Software is furnished to do 13*323b6546SOliver Tappe so, subject to the following conditions: 14*323b6546SOliver Tappe 15*323b6546SOliver Tappe The above copyright notice and this permission notice applies to all licensees 16*323b6546SOliver Tappe and shall be included in all copies or substantial portions of the Software. 17*323b6546SOliver Tappe 18*323b6546SOliver Tappe THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19*323b6546SOliver Tappe IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF TITLE, MERCHANTABILITY, 20*323b6546SOliver Tappe FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 21*323b6546SOliver Tappe BE INCORPORATED BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 22*323b6546SOliver Tappe AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF, OR IN CONNECTION 23*323b6546SOliver Tappe WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24*323b6546SOliver Tappe 25*323b6546SOliver Tappe Except as contained in this notice, the name of Be Incorporated shall not be 26*323b6546SOliver Tappe used in advertising or otherwise to promote the sale, use or other dealings in 27*323b6546SOliver Tappe this Software without prior written authorization from Be Incorporated. 28*323b6546SOliver Tappe 29*323b6546SOliver Tappe Tracker(TM), Be(R), BeOS(R), and BeIA(TM) are trademarks or registered 30*323b6546SOliver Tappe trademarks of Be Incorporated in the United States and other countries. Other 31*323b6546SOliver Tappe brand product names are registered trademarks or trademarks of their respective 32*323b6546SOliver Tappe holders. 33*323b6546SOliver Tappe All rights reserved. 34*323b6546SOliver Tappe */ 35*323b6546SOliver Tappe 36*323b6546SOliver Tappe #include <Debug.h> 37*323b6546SOliver Tappe #include <Bitmap.h> 38*323b6546SOliver Tappe #include <Catalog.h> 39*323b6546SOliver Tappe #include <Dragger.h> 40*323b6546SOliver Tappe #include <Locale.h> 41*323b6546SOliver Tappe #include <Menu.h> 42*323b6546SOliver Tappe #include <MenuItem.h> 43*323b6546SOliver Tappe #include <Roster.h> 44*323b6546SOliver Tappe 45*323b6546SOliver Tappe #include "DeskbarMenu.h" 46*323b6546SOliver Tappe #include "BarApp.h" 47*323b6546SOliver Tappe #include "BarView.h" 48*323b6546SOliver Tappe #include "DeskbarUtils.h" 49*323b6546SOliver Tappe #include "IconMenuItem.h" 50*323b6546SOliver Tappe #include "MountMenu.h" 51*323b6546SOliver Tappe #include "IconMenuItem.h" 52*323b6546SOliver Tappe #include "MountMenu.h" 53*323b6546SOliver Tappe #include "IconMenuItem.h" 54*323b6546SOliver Tappe #include "MountMenu.h" 55*323b6546SOliver Tappe #include "PublicCommands.h" 56*323b6546SOliver Tappe #include "RecentItems.h" 57*323b6546SOliver Tappe #include "StatusView.h" 58*323b6546SOliver Tappe #include "tracker_private.h" 59*323b6546SOliver Tappe 60*323b6546SOliver Tappe #undef B_TRANSLATE_CONTEXT 61*323b6546SOliver Tappe #define B_TRANSLATE_CONTEXT "DeskbarMenu" 62*323b6546SOliver Tappe 63*323b6546SOliver Tappe #define ROSTER_SIG "application/x-vnd.Be-ROST" 64*323b6546SOliver Tappe 65*323b6546SOliver Tappe #ifdef MOUNT_MENU_IN_DESKBAR 66*323b6546SOliver Tappe 67*323b6546SOliver Tappe class DeskbarMountMenu : public BPrivate::MountMenu { 68*323b6546SOliver Tappe public: 69*323b6546SOliver Tappe DeskbarMountMenu(const char* name); 70*323b6546SOliver Tappe virtual bool AddDynamicItem(add_state s); 71*323b6546SOliver Tappe }; 72*323b6546SOliver Tappe 73*323b6546SOliver Tappe #endif 74*323b6546SOliver Tappe 75*323b6546SOliver Tappe // #define SHOW_RECENT_FIND_ITEMS 76*323b6546SOliver Tappe 77*323b6546SOliver Tappe namespace BPrivate { 78*323b6546SOliver Tappe BMenu* TrackerBuildRecentFindItemsMenu(const char*); 79*323b6546SOliver Tappe } 80*323b6546SOliver Tappe 81*323b6546SOliver Tappe 82*323b6546SOliver Tappe using namespace BPrivate; 83*323b6546SOliver Tappe 84*323b6546SOliver Tappe 85*323b6546SOliver Tappe // #pragma mark - 86*323b6546SOliver Tappe 87*323b6546SOliver Tappe 88*323b6546SOliver Tappe TDeskbarMenu::TDeskbarMenu(TBarView* barView) 89*323b6546SOliver Tappe : BNavMenu("DeskbarMenu", B_REFS_RECEIVED, DefaultTarget()), 90*323b6546SOliver Tappe fAddState(kStart), 91*323b6546SOliver Tappe fBarView(barView) 92*323b6546SOliver Tappe { 93*323b6546SOliver Tappe } 94*323b6546SOliver Tappe 95*323b6546SOliver Tappe 96*323b6546SOliver Tappe void 97*323b6546SOliver Tappe TDeskbarMenu::AttachedToWindow() 98*323b6546SOliver Tappe { 99*323b6546SOliver Tappe if (fBarView && fBarView->LockLooper()) { 100*323b6546SOliver Tappe if (fBarView->Dragging()) { 101*323b6546SOliver Tappe SetTypesList(fBarView->CachedTypesList()); 102*323b6546SOliver Tappe SetTarget(BMessenger(fBarView)); 103*323b6546SOliver Tappe SetTrackingHookDeep(this, fBarView->MenuTrackingHook, 104*323b6546SOliver Tappe fBarView->GetTrackingHookData()); 105*323b6546SOliver Tappe fBarView->DragStart(); 106*323b6546SOliver Tappe } else { 107*323b6546SOliver Tappe SetTypesList(NULL); 108*323b6546SOliver Tappe SetTarget(DefaultTarget()); 109*323b6546SOliver Tappe SetTrackingHookDeep(this, NULL, NULL); 110*323b6546SOliver Tappe } 111*323b6546SOliver Tappe 112*323b6546SOliver Tappe fBarView->UnlockLooper(); 113*323b6546SOliver Tappe } 114*323b6546SOliver Tappe 115*323b6546SOliver Tappe BNavMenu::AttachedToWindow(); 116*323b6546SOliver Tappe } 117*323b6546SOliver Tappe 118*323b6546SOliver Tappe 119*323b6546SOliver Tappe void 120*323b6546SOliver Tappe TDeskbarMenu::DetachedFromWindow() 121*323b6546SOliver Tappe { 122*323b6546SOliver Tappe if (fBarView) { 123*323b6546SOliver Tappe BLooper* looper = fBarView->Looper(); 124*323b6546SOliver Tappe if (looper && looper->Lock()) { 125*323b6546SOliver Tappe fBarView->DragStop(); 126*323b6546SOliver Tappe looper->Unlock(); 127*323b6546SOliver Tappe } 128*323b6546SOliver Tappe } 129*323b6546SOliver Tappe 130*323b6546SOliver Tappe // don't call BNavMenu::DetachedFromWindow 131*323b6546SOliver Tappe // it sets the TypesList to NULL 132*323b6546SOliver Tappe BMenu::DetachedFromWindow(); 133*323b6546SOliver Tappe } 134*323b6546SOliver Tappe 135*323b6546SOliver Tappe 136*323b6546SOliver Tappe bool 137*323b6546SOliver Tappe TDeskbarMenu::StartBuildingItemList() 138*323b6546SOliver Tappe { 139*323b6546SOliver Tappe RemoveItems(0, CountItems(), true); 140*323b6546SOliver Tappe fAddState = kStart; 141*323b6546SOliver Tappe return BNavMenu::StartBuildingItemList(); 142*323b6546SOliver Tappe } 143*323b6546SOliver Tappe 144*323b6546SOliver Tappe 145*323b6546SOliver Tappe void 146*323b6546SOliver Tappe TDeskbarMenu::DoneBuildingItemList() 147*323b6546SOliver Tappe { 148*323b6546SOliver Tappe if (fItemList->CountItems() <= 0) { 149*323b6546SOliver Tappe BMenuItem* item 150*323b6546SOliver Tappe = new BMenuItem(B_TRANSLATE("<Deskbar folder is empty>"), 0); 151*323b6546SOliver Tappe item->SetEnabled(false); 152*323b6546SOliver Tappe AddItem(item); 153*323b6546SOliver Tappe } else 154*323b6546SOliver Tappe BNavMenu::DoneBuildingItemList(); 155*323b6546SOliver Tappe } 156*323b6546SOliver Tappe 157*323b6546SOliver Tappe 158*323b6546SOliver Tappe bool 159*323b6546SOliver Tappe TDeskbarMenu::AddNextItem() 160*323b6546SOliver Tappe { 161*323b6546SOliver Tappe if (fAddState == kStart) 162*323b6546SOliver Tappe return AddStandardDeskbarMenuItems(); 163*323b6546SOliver Tappe 164*323b6546SOliver Tappe TrackingHookData* data = fBarView->GetTrackingHookData(); 165*323b6546SOliver Tappe if (fAddState == kAddingRecents) { 166*323b6546SOliver Tappe static const char* recentTitle[] = { 167*323b6546SOliver Tappe B_TRANSLATE_MARK("Recent documents"), 168*323b6546SOliver Tappe B_TRANSLATE_MARK("Recent folders"), 169*323b6546SOliver Tappe B_TRANSLATE_MARK("Recent applications")}; 170*323b6546SOliver Tappe const int recentType[] = {kRecentDocuments, kRecentFolders, 171*323b6546SOliver Tappe kRecentApplications}; 172*323b6546SOliver Tappe const int recentTypes = 3; 173*323b6546SOliver Tappe TRecentsMenu* recentItem[recentTypes]; 174*323b6546SOliver Tappe 175*323b6546SOliver Tappe bool enabled = false; 176*323b6546SOliver Tappe 177*323b6546SOliver Tappe for (int i = 0; i < recentTypes; i++) { 178*323b6546SOliver Tappe recentItem[i] 179*323b6546SOliver Tappe = new TRecentsMenu(B_TRANSLATE_NOCOLLECT(recentTitle[i]), 180*323b6546SOliver Tappe fBarView, recentType[i]); 181*323b6546SOliver Tappe 182*323b6546SOliver Tappe if (recentItem[i]) 183*323b6546SOliver Tappe enabled |= recentItem[i]->RecentsEnabled(); 184*323b6546SOliver Tappe } 185*323b6546SOliver Tappe if (enabled) { 186*323b6546SOliver Tappe AddSeparatorItem(); 187*323b6546SOliver Tappe 188*323b6546SOliver Tappe for (int i = 0; i < recentTypes; i++) { 189*323b6546SOliver Tappe if (!recentItem[i]) 190*323b6546SOliver Tappe continue; 191*323b6546SOliver Tappe 192*323b6546SOliver Tappe if (recentItem[i]->RecentsEnabled()) { 193*323b6546SOliver Tappe recentItem[i]->SetTypesList(TypesList()); 194*323b6546SOliver Tappe recentItem[i]->SetTarget(Target()); 195*323b6546SOliver Tappe AddItem(recentItem[i]); 196*323b6546SOliver Tappe } 197*323b6546SOliver Tappe 198*323b6546SOliver Tappe if (data && fBarView && fBarView->Dragging()) { 199*323b6546SOliver Tappe recentItem[i]->InitTrackingHook(data->fTrackingHook, 200*323b6546SOliver Tappe &data->fTarget, data->fDragMessage); 201*323b6546SOliver Tappe } 202*323b6546SOliver Tappe } 203*323b6546SOliver Tappe } 204*323b6546SOliver Tappe 205*323b6546SOliver Tappe AddSeparatorItem(); 206*323b6546SOliver Tappe fAddState = kAddingDeskbarMenu; 207*323b6546SOliver Tappe return true; 208*323b6546SOliver Tappe } 209*323b6546SOliver Tappe 210*323b6546SOliver Tappe if (fAddState == kAddingDeskbarMenu) { 211*323b6546SOliver Tappe // keep reentering and adding items 212*323b6546SOliver Tappe // until this returns false 213*323b6546SOliver Tappe bool done = BNavMenu::AddNextItem(); 214*323b6546SOliver Tappe BMenuItem* item = ItemAt(CountItems() - 1); 215*323b6546SOliver Tappe if (item) { 216*323b6546SOliver Tappe BNavMenu* menu = dynamic_cast<BNavMenu*>(item->Menu()); 217*323b6546SOliver Tappe if (menu) { 218*323b6546SOliver Tappe if (data && fBarView->Dragging()) { 219*323b6546SOliver Tappe menu->InitTrackingHook(data->fTrackingHook, 220*323b6546SOliver Tappe &data->fTarget, data->fDragMessage); 221*323b6546SOliver Tappe } else 222*323b6546SOliver Tappe menu->InitTrackingHook(0, NULL, NULL); 223*323b6546SOliver Tappe } 224*323b6546SOliver Tappe } 225*323b6546SOliver Tappe 226*323b6546SOliver Tappe if (!done) 227*323b6546SOliver Tappe fAddState = kDone; 228*323b6546SOliver Tappe return done; 229*323b6546SOliver Tappe } 230*323b6546SOliver Tappe 231*323b6546SOliver Tappe return false; 232*323b6546SOliver Tappe } 233*323b6546SOliver Tappe 234*323b6546SOliver Tappe 235*323b6546SOliver Tappe bool 236*323b6546SOliver Tappe TDeskbarMenu::AddStandardDeskbarMenuItems() 237*323b6546SOliver Tappe { 238*323b6546SOliver Tappe bool dragging = false; 239*323b6546SOliver Tappe if (fBarView) 240*323b6546SOliver Tappe dragging = fBarView->Dragging(); 241*323b6546SOliver Tappe 242*323b6546SOliver Tappe BMenuItem* item; 243*323b6546SOliver Tappe BRoster roster; 244*323b6546SOliver Tappe if (!roster.IsRunning(kTrackerSignature)) { 245*323b6546SOliver Tappe item = new BMenuItem(B_TRANSLATE("Restart Tracker"), 246*323b6546SOliver Tappe new BMessage(kRestartTracker)); 247*323b6546SOliver Tappe AddItem(item); 248*323b6546SOliver Tappe AddSeparatorItem(); 249*323b6546SOliver Tappe } 250*323b6546SOliver Tappe 251*323b6546SOliver Tappe // One of them is used if HAIKU_DISTRO_COMPATIBILITY_OFFICIAL, and the other if 252*323b6546SOliver Tappe // not. However, we want both of them to end up in the catalog, so we have to 253*323b6546SOliver Tappe // make them visible to collectcatkeys in either case. 254*323b6546SOliver Tappe #if defined(B_COLLECTING_CATKEYS)||defined(HAIKU_DISTRO_COMPATIBILITY_OFFICIAL) 255*323b6546SOliver Tappe static const char* kAboutHaikuMenuItemStr = B_TRANSLATE_MARK( 256*323b6546SOliver Tappe "About Haiku"); 257*323b6546SOliver Tappe #endif 258*323b6546SOliver Tappe 259*323b6546SOliver Tappe #if defined(B_COLLECTING_CATKEYS)||!defined(HAIKU_DISTRO_COMPATIBILITY_OFFICIAL) 260*323b6546SOliver Tappe static const char* kAboutThisSystemMenuItemStr = B_TRANSLATE_MARK( 261*323b6546SOliver Tappe "About this system"); 262*323b6546SOliver Tappe #endif 263*323b6546SOliver Tappe 264*323b6546SOliver Tappe item = new BMenuItem( 265*323b6546SOliver Tappe #ifdef HAIKU_DISTRO_COMPATIBILITY_OFFICIAL 266*323b6546SOliver Tappe B_TRANSLATE_NOCOLLECT(kAboutHaikuMenuItemStr) 267*323b6546SOliver Tappe #else 268*323b6546SOliver Tappe B_TRANSLATE_NOCOLLECT(kAboutThisSystemMenuItemStr) 269*323b6546SOliver Tappe #endif 270*323b6546SOliver Tappe , new BMessage(kShowSplash)); 271*323b6546SOliver Tappe item->SetEnabled(!dragging); 272*323b6546SOliver Tappe AddItem(item); 273*323b6546SOliver Tappe 274*323b6546SOliver Tappe static const char* kFindMenuItemStr 275*323b6546SOliver Tappe = B_TRANSLATE_MARK("Find" B_UTF8_ELLIPSIS); 276*323b6546SOliver Tappe 277*323b6546SOliver Tappe #ifdef SHOW_RECENT_FIND_ITEMS 278*323b6546SOliver Tappe item = new BMenuItem( 279*323b6546SOliver Tappe TrackerBuildRecentFindItemsMenu(kFindMenuItemStr), 280*323b6546SOliver Tappe new BMessage(kFindButton)); 281*323b6546SOliver Tappe #else 282*323b6546SOliver Tappe item = new BMenuItem(B_TRANSLATE_NOCOLLECT(kFindMenuItemStr), 283*323b6546SOliver Tappe new BMessage(kFindButton)); 284*323b6546SOliver Tappe #endif 285*323b6546SOliver Tappe item->SetEnabled(!dragging); 286*323b6546SOliver Tappe AddItem(item); 287*323b6546SOliver Tappe 288*323b6546SOliver Tappe item = new BMenuItem(B_TRANSLATE("Show replicants"), 289*323b6546SOliver Tappe new BMessage(kToggleDraggers)); 290*323b6546SOliver Tappe item->SetEnabled(!dragging); 291*323b6546SOliver Tappe item->SetMarked(BDragger::AreDraggersDrawn()); 292*323b6546SOliver Tappe AddItem(item); 293*323b6546SOliver Tappe 294*323b6546SOliver Tappe static const char* kMountMenuStr = B_TRANSLATE_MARK("Mount"); 295*323b6546SOliver Tappe 296*323b6546SOliver Tappe #ifdef MOUNT_MENU_IN_DESKBAR 297*323b6546SOliver Tappe DeskbarMountMenu* mountMenu = new DeskbarMountMenu( 298*323b6546SOliver Tappe B_TRANSLATE_NOCOLLECT(kMountMenuStr)); 299*323b6546SOliver Tappe mountMenu->SetEnabled(!dragging); 300*323b6546SOliver Tappe AddItem(mountMenu); 301*323b6546SOliver Tappe #endif 302*323b6546SOliver Tappe 303*323b6546SOliver Tappe item = new BMenuItem(B_TRANSLATE("Deskbar preferences" B_UTF8_ELLIPSIS), 304*323b6546SOliver Tappe new BMessage(kConfigShow)); 305*323b6546SOliver Tappe item->SetTarget(be_app); 306*323b6546SOliver Tappe AddItem(item); 307*323b6546SOliver Tappe 308*323b6546SOliver Tappe AddSeparatorItem(); 309*323b6546SOliver Tappe 310*323b6546SOliver Tappe BMenu* shutdownMenu = new BMenu(B_TRANSLATE("Shutdown" B_UTF8_ELLIPSIS)); 311*323b6546SOliver Tappe 312*323b6546SOliver Tappe item = new BMenuItem(B_TRANSLATE("Restart system"), 313*323b6546SOliver Tappe new BMessage(kRebootSystem)); 314*323b6546SOliver Tappe item->SetEnabled(!dragging); 315*323b6546SOliver Tappe shutdownMenu->AddItem(item); 316*323b6546SOliver Tappe 317*323b6546SOliver Tappe #if defined(APM_SUPPORT) || defined(B_COLLECTING_CATKEYS) 318*323b6546SOliver Tappe static const char* kSuspendMenuItemStr = B_TRANSLATE_MARK("Suspend"); 319*323b6546SOliver Tappe #endif 320*323b6546SOliver Tappe 321*323b6546SOliver Tappe #ifdef APM_SUPPORT 322*323b6546SOliver Tappe if (_kapm_control_(APM_CHECK_ENABLED) == B_OK) { 323*323b6546SOliver Tappe item = new BMenuItem(B_TRANSLATE_NOCOLLECT(kSuspendMenuItemStr), 324*323b6546SOliver Tappe new BMessage(kSuspendSystem)); 325*323b6546SOliver Tappe item->SetEnabled(!dragging); 326*323b6546SOliver Tappe shutdownMenu->AddItem(item); 327*323b6546SOliver Tappe } 328*323b6546SOliver Tappe #endif 329*323b6546SOliver Tappe 330*323b6546SOliver Tappe item = new BMenuItem(B_TRANSLATE("Power off"), 331*323b6546SOliver Tappe new BMessage(kShutdownSystem)); 332*323b6546SOliver Tappe item->SetEnabled(!dragging); 333*323b6546SOliver Tappe shutdownMenu->AddItem(item); 334*323b6546SOliver Tappe shutdownMenu->SetFont(be_plain_font); 335*323b6546SOliver Tappe 336*323b6546SOliver Tappe shutdownMenu->SetTargetForItems(be_app); 337*323b6546SOliver Tappe BMessage* message = new BMessage(kShutdownSystem); 338*323b6546SOliver Tappe message->AddBool("confirm", true); 339*323b6546SOliver Tappe AddItem(new BMenuItem(shutdownMenu, message)); 340*323b6546SOliver Tappe 341*323b6546SOliver Tappe fAddState = kAddingRecents; 342*323b6546SOliver Tappe 343*323b6546SOliver Tappe return true; 344*323b6546SOliver Tappe } 345*323b6546SOliver Tappe 346*323b6546SOliver Tappe 347*323b6546SOliver Tappe void 348*323b6546SOliver Tappe TDeskbarMenu::ClearMenuBuildingState() 349*323b6546SOliver Tappe { 350*323b6546SOliver Tappe fAddState = kDone; 351*323b6546SOliver Tappe fMenuBuilt = false; 352*323b6546SOliver Tappe // force the menu to get rebuilt each time 353*323b6546SOliver Tappe BNavMenu::ClearMenuBuildingState(); 354*323b6546SOliver Tappe } 355*323b6546SOliver Tappe 356*323b6546SOliver Tappe 357*323b6546SOliver Tappe void 358*323b6546SOliver Tappe TDeskbarMenu::ResetTargets() 359*323b6546SOliver Tappe { 360*323b6546SOliver Tappe // This method does not recurse into submenus 361*323b6546SOliver Tappe // and does not affect menu items in submenus. 362*323b6546SOliver Tappe // (e.g. "Restart System" and "Power Off") 363*323b6546SOliver Tappe 364*323b6546SOliver Tappe BNavMenu::ResetTargets(); 365*323b6546SOliver Tappe 366*323b6546SOliver Tappe // if we are dragging, set the target to whatever was set 367*323b6546SOliver Tappe // else set it to the default (Tracker) 368*323b6546SOliver Tappe if (!fBarView->Dragging()) 369*323b6546SOliver Tappe SetTarget(DefaultTarget()); 370*323b6546SOliver Tappe 371*323b6546SOliver Tappe // now set the target for the menuitems to the currently 372*323b6546SOliver Tappe // set target, which may or may not be tracker 373*323b6546SOliver Tappe SetTargetForItems(Target()); 374*323b6546SOliver Tappe 375*323b6546SOliver Tappe for (int32 i = 0; ; i++) { 376*323b6546SOliver Tappe BMenuItem* item = ItemAt(i); 377*323b6546SOliver Tappe if (item == NULL) 378*323b6546SOliver Tappe break; 379*323b6546SOliver Tappe 380*323b6546SOliver Tappe if (item->Message()) { 381*323b6546SOliver Tappe switch (item->Message()->what) { 382*323b6546SOliver Tappe case kFindButton: 383*323b6546SOliver Tappe item->SetTarget(BMessenger(kTrackerSignature)); 384*323b6546SOliver Tappe break; 385*323b6546SOliver Tappe 386*323b6546SOliver Tappe case kShowSplash: 387*323b6546SOliver Tappe case kToggleDraggers: 388*323b6546SOliver Tappe case kConfigShow: 389*323b6546SOliver Tappe case kAlwaysTop: 390*323b6546SOliver Tappe case kShowSeconds: 391*323b6546SOliver Tappe case kRebootSystem: 392*323b6546SOliver Tappe case kSuspendSystem: 393*323b6546SOliver Tappe case kShutdownSystem: 394*323b6546SOliver Tappe item->SetTarget(be_app); 395*323b6546SOliver Tappe break; 396*323b6546SOliver Tappe } 397*323b6546SOliver Tappe } 398*323b6546SOliver Tappe } 399*323b6546SOliver Tappe } 400*323b6546SOliver Tappe 401*323b6546SOliver Tappe 402*323b6546SOliver Tappe BPoint 403*323b6546SOliver Tappe TDeskbarMenu::ScreenLocation() 404*323b6546SOliver Tappe { 405*323b6546SOliver Tappe bool vertical = fBarView->Vertical(); 406*323b6546SOliver Tappe int32 expando = (fBarView->State() == kExpandoState); 407*323b6546SOliver Tappe BPoint point; 408*323b6546SOliver Tappe 409*323b6546SOliver Tappe BRect rect = Supermenu()->Bounds(); 410*323b6546SOliver Tappe Supermenu()->ConvertToScreen(&rect); 411*323b6546SOliver Tappe 412*323b6546SOliver Tappe if (expando && vertical && fBarView->Left()) { 413*323b6546SOliver Tappe PRINT(("Left\n")); 414*323b6546SOliver Tappe point = rect.RightTop() + BPoint(0, 3); 415*323b6546SOliver Tappe } else if (expando && vertical && !fBarView->Left()) { 416*323b6546SOliver Tappe PRINT(("Right\n")); 417*323b6546SOliver Tappe point = rect.LeftTop() - BPoint(Bounds().Width(), 0) + BPoint(0, 3); 418*323b6546SOliver Tappe } else 419*323b6546SOliver Tappe point = BMenu::ScreenLocation(); 420*323b6546SOliver Tappe 421*323b6546SOliver Tappe return point; 422*323b6546SOliver Tappe } 423*323b6546SOliver Tappe 424*323b6546SOliver Tappe 425*323b6546SOliver Tappe /*static*/ 426*323b6546SOliver Tappe BMessenger 427*323b6546SOliver Tappe TDeskbarMenu::DefaultTarget() 428*323b6546SOliver Tappe { 429*323b6546SOliver Tappe // if Tracker is not available we target the BarApp 430*323b6546SOliver Tappe BMessenger target(kTrackerSignature); 431*323b6546SOliver Tappe if (target.IsValid()) 432*323b6546SOliver Tappe return target; 433*323b6546SOliver Tappe 434*323b6546SOliver Tappe return BMessenger(be_app); 435*323b6546SOliver Tappe } 436*323b6546SOliver Tappe 437*323b6546SOliver Tappe 438*323b6546SOliver Tappe // #pragma mark - 439*323b6546SOliver Tappe 440*323b6546SOliver Tappe 441*323b6546SOliver Tappe TRecentsMenu::TRecentsMenu(const char* name, TBarView* bar, int32 which, 442*323b6546SOliver Tappe const char* signature, entry_ref* appRef) 443*323b6546SOliver Tappe : BNavMenu(name, B_REFS_RECEIVED, TDeskbarMenu::DefaultTarget()), 444*323b6546SOliver Tappe fWhich(which), 445*323b6546SOliver Tappe fAppRef(NULL), 446*323b6546SOliver Tappe fSignature(NULL), 447*323b6546SOliver Tappe fRecentsCount(0), 448*323b6546SOliver Tappe fRecentsEnabled(false), 449*323b6546SOliver Tappe fItemIndex(0), 450*323b6546SOliver Tappe fBarView(bar) 451*323b6546SOliver Tappe { 452*323b6546SOliver Tappe TBarApp* app = dynamic_cast<TBarApp*>(be_app); 453*323b6546SOliver Tappe if (app == NULL) 454*323b6546SOliver Tappe return; 455*323b6546SOliver Tappe 456*323b6546SOliver Tappe switch (which) { 457*323b6546SOliver Tappe case kRecentDocuments: 458*323b6546SOliver Tappe fRecentsCount = app->Settings()->recentDocsCount; 459*323b6546SOliver Tappe fRecentsEnabled = app->Settings()->recentDocsEnabled; 460*323b6546SOliver Tappe break; 461*323b6546SOliver Tappe case kRecentApplications: 462*323b6546SOliver Tappe fRecentsCount = app->Settings()->recentAppsCount; 463*323b6546SOliver Tappe fRecentsEnabled = app->Settings()->recentAppsEnabled; 464*323b6546SOliver Tappe break; 465*323b6546SOliver Tappe case kRecentAppDocuments: 466*323b6546SOliver Tappe fRecentsCount = app->Settings()->recentDocsCount; 467*323b6546SOliver Tappe fRecentsEnabled = app->Settings()->recentDocsEnabled; 468*323b6546SOliver Tappe if (signature != NULL) 469*323b6546SOliver Tappe fSignature = strdup(signature); 470*323b6546SOliver Tappe if (appRef != NULL) 471*323b6546SOliver Tappe fAppRef = new entry_ref(*appRef); 472*323b6546SOliver Tappe break; 473*323b6546SOliver Tappe case kRecentFolders: 474*323b6546SOliver Tappe fRecentsCount = app->Settings()->recentFoldersCount; 475*323b6546SOliver Tappe fRecentsEnabled = app->Settings()->recentFoldersEnabled; 476*323b6546SOliver Tappe break; 477*323b6546SOliver Tappe } 478*323b6546SOliver Tappe } 479*323b6546SOliver Tappe 480*323b6546SOliver Tappe 481*323b6546SOliver Tappe TRecentsMenu::~TRecentsMenu() 482*323b6546SOliver Tappe { 483*323b6546SOliver Tappe delete fAppRef; 484*323b6546SOliver Tappe free(fSignature); 485*323b6546SOliver Tappe } 486*323b6546SOliver Tappe 487*323b6546SOliver Tappe 488*323b6546SOliver Tappe void 489*323b6546SOliver Tappe TRecentsMenu::DetachedFromWindow() 490*323b6546SOliver Tappe { 491*323b6546SOliver Tappe // BNavMenu::DetachedFromWindow sets the TypesList to NULL 492*323b6546SOliver Tappe BMenu::DetachedFromWindow(); 493*323b6546SOliver Tappe } 494*323b6546SOliver Tappe 495*323b6546SOliver Tappe 496*323b6546SOliver Tappe bool 497*323b6546SOliver Tappe TRecentsMenu::StartBuildingItemList() 498*323b6546SOliver Tappe { 499*323b6546SOliver Tappe RemoveItems(0, CountItems(), true); 500*323b6546SOliver Tappe 501*323b6546SOliver Tappe // !! note: don't call inherited from here 502*323b6546SOliver Tappe // the navref is not set for this menu 503*323b6546SOliver Tappe // but it still needs to be a draggable navmenu 504*323b6546SOliver Tappe // simply return true so that AddNextItem is called 505*323b6546SOliver Tappe // 506*323b6546SOliver Tappe // return BNavMenu::StartBuildingItemList(); 507*323b6546SOliver Tappe return true; 508*323b6546SOliver Tappe } 509*323b6546SOliver Tappe 510*323b6546SOliver Tappe 511*323b6546SOliver Tappe bool 512*323b6546SOliver Tappe TRecentsMenu::AddNextItem() 513*323b6546SOliver Tappe { 514*323b6546SOliver Tappe if (fRecentsCount > 0 && fRecentsEnabled && AddRecents(fRecentsCount)) 515*323b6546SOliver Tappe return true; 516*323b6546SOliver Tappe 517*323b6546SOliver Tappe fItemIndex = 0; 518*323b6546SOliver Tappe return false; 519*323b6546SOliver Tappe } 520*323b6546SOliver Tappe 521*323b6546SOliver Tappe 522*323b6546SOliver Tappe bool 523*323b6546SOliver Tappe TRecentsMenu::AddRecents(int32 count) 524*323b6546SOliver Tappe { 525*323b6546SOliver Tappe if (fItemIndex == 0) { 526*323b6546SOliver Tappe fRecentList.MakeEmpty(); 527*323b6546SOliver Tappe BRoster roster; 528*323b6546SOliver Tappe 529*323b6546SOliver Tappe switch (fWhich) { 530*323b6546SOliver Tappe case kRecentDocuments: 531*323b6546SOliver Tappe roster.GetRecentDocuments(&fRecentList, count); 532*323b6546SOliver Tappe break; 533*323b6546SOliver Tappe case kRecentApplications: 534*323b6546SOliver Tappe roster.GetRecentApps(&fRecentList, count); 535*323b6546SOliver Tappe break; 536*323b6546SOliver Tappe case kRecentAppDocuments: 537*323b6546SOliver Tappe roster.GetRecentDocuments(&fRecentList, count, NULL, 538*323b6546SOliver Tappe fSignature); 539*323b6546SOliver Tappe break; 540*323b6546SOliver Tappe case kRecentFolders: 541*323b6546SOliver Tappe roster.GetRecentFolders(&fRecentList, count); 542*323b6546SOliver Tappe break; 543*323b6546SOliver Tappe default: 544*323b6546SOliver Tappe return false; 545*323b6546SOliver Tappe } 546*323b6546SOliver Tappe } 547*323b6546SOliver Tappe 548*323b6546SOliver Tappe for (;;) { 549*323b6546SOliver Tappe entry_ref ref; 550*323b6546SOliver Tappe if (fRecentList.FindRef("refs", fItemIndex++, &ref) != B_OK) 551*323b6546SOliver Tappe break; 552*323b6546SOliver Tappe 553*323b6546SOliver Tappe if (ref.name && strlen(ref.name) > 0) { 554*323b6546SOliver Tappe Model model(&ref, true); 555*323b6546SOliver Tappe 556*323b6546SOliver Tappe if (fWhich != kRecentApplications) { 557*323b6546SOliver Tappe BMessage* message = new BMessage(B_REFS_RECEIVED); 558*323b6546SOliver Tappe if (fWhich == kRecentAppDocuments) { 559*323b6546SOliver Tappe // add application as handler 560*323b6546SOliver Tappe message->AddRef("handler", fAppRef); 561*323b6546SOliver Tappe } 562*323b6546SOliver Tappe 563*323b6546SOliver Tappe ModelMenuItem* item = BNavMenu::NewModelItem(&model, 564*323b6546SOliver Tappe message, Target(), false, NULL, TypesList()); 565*323b6546SOliver Tappe 566*323b6546SOliver Tappe if (item) 567*323b6546SOliver Tappe AddItem(item); 568*323b6546SOliver Tappe } else { 569*323b6546SOliver Tappe // The application items expand to a list of recent documents 570*323b6546SOliver Tappe // for that application - so they must be handled extra 571*323b6546SOliver Tappe BFile file(&ref, B_READ_ONLY); 572*323b6546SOliver Tappe char signature[B_MIME_TYPE_LENGTH]; 573*323b6546SOliver Tappe 574*323b6546SOliver Tappe BAppFileInfo appInfo(&file); 575*323b6546SOliver Tappe if (appInfo.InitCheck() != B_OK 576*323b6546SOliver Tappe || appInfo.GetSignature(signature) != B_OK) 577*323b6546SOliver Tappe continue; 578*323b6546SOliver Tappe 579*323b6546SOliver Tappe ModelMenuItem* item = NULL; 580*323b6546SOliver Tappe BMessage doc; 581*323b6546SOliver Tappe be_roster->GetRecentDocuments(&doc, 1, NULL, signature); 582*323b6546SOliver Tappe // ToDo: check if the documents do exist at all to 583*323b6546SOliver Tappe // avoid the creation of the submenu. 584*323b6546SOliver Tappe 585*323b6546SOliver Tappe if (doc.CountNames(B_REF_TYPE) > 0) { 586*323b6546SOliver Tappe // create recents menu that will contain the recent docs of 587*323b6546SOliver Tappe // this app 588*323b6546SOliver Tappe TRecentsMenu* docs = new TRecentsMenu(model.Name(), 589*323b6546SOliver Tappe fBarView, kRecentAppDocuments, signature, &ref); 590*323b6546SOliver Tappe docs->SetTypesList(TypesList()); 591*323b6546SOliver Tappe docs->SetTarget(Target()); 592*323b6546SOliver Tappe 593*323b6546SOliver Tappe item = new ModelMenuItem(&model, docs); 594*323b6546SOliver Tappe } else 595*323b6546SOliver Tappe item = new ModelMenuItem(&model, model.Name(), NULL); 596*323b6546SOliver Tappe 597*323b6546SOliver Tappe if (item) { 598*323b6546SOliver Tappe // add refs-message so that the recent app can be launched 599*323b6546SOliver Tappe BMessage* msg = new BMessage(B_REFS_RECEIVED); 600*323b6546SOliver Tappe msg->AddRef("refs", &ref); 601*323b6546SOliver Tappe item->SetMessage(msg); 602*323b6546SOliver Tappe item->SetTarget(Target()); 603*323b6546SOliver Tappe 604*323b6546SOliver Tappe AddItem(item); 605*323b6546SOliver Tappe } 606*323b6546SOliver Tappe } 607*323b6546SOliver Tappe 608*323b6546SOliver Tappe // return true so that we know to reenter this list 609*323b6546SOliver Tappe return true; 610*323b6546SOliver Tappe } 611*323b6546SOliver Tappe } 612*323b6546SOliver Tappe 613*323b6546SOliver Tappe // return false if we are done with this list 614*323b6546SOliver Tappe return false; 615*323b6546SOliver Tappe } 616*323b6546SOliver Tappe 617*323b6546SOliver Tappe 618*323b6546SOliver Tappe void 619*323b6546SOliver Tappe TRecentsMenu::DoneBuildingItemList() 620*323b6546SOliver Tappe { 621*323b6546SOliver Tappe // !! note: don't call inherited here 622*323b6546SOliver Tappe // the object list is not built 623*323b6546SOliver Tappe // and this list does not need to be sorted 624*323b6546SOliver Tappe // BNavMenu::DoneBuildingItemList(); 625*323b6546SOliver Tappe 626*323b6546SOliver Tappe if (CountItems() > 0) 627*323b6546SOliver Tappe SetTargetForItems(Target()); 628*323b6546SOliver Tappe } 629*323b6546SOliver Tappe 630*323b6546SOliver Tappe 631*323b6546SOliver Tappe void 632*323b6546SOliver Tappe TRecentsMenu::ClearMenuBuildingState() 633*323b6546SOliver Tappe { 634*323b6546SOliver Tappe fMenuBuilt = false; 635*323b6546SOliver Tappe BNavMenu::ClearMenuBuildingState(); 636*323b6546SOliver Tappe } 637*323b6546SOliver Tappe 638*323b6546SOliver Tappe 639*323b6546SOliver Tappe void 640*323b6546SOliver Tappe TRecentsMenu::ResetTargets() 641*323b6546SOliver Tappe { 642*323b6546SOliver Tappe BNavMenu::ResetTargets(); 643*323b6546SOliver Tappe 644*323b6546SOliver Tappe // if we are dragging, set the target to whatever was set 645*323b6546SOliver Tappe // else set it to the default (Tracker) 646*323b6546SOliver Tappe if (!fBarView->Dragging()) 647*323b6546SOliver Tappe SetTarget(TDeskbarMenu::DefaultTarget()); 648*323b6546SOliver Tappe 649*323b6546SOliver Tappe // now set the target for the menuitems to the currently 650*323b6546SOliver Tappe // set target, which may or may not be tracker 651*323b6546SOliver Tappe SetTargetForItems(Target()); 652*323b6546SOliver Tappe } 653*323b6546SOliver Tappe 654*323b6546SOliver Tappe 655*323b6546SOliver Tappe //***************************************************************************** 656*323b6546SOliver Tappe // #pragma mark - 657*323b6546SOliver Tappe 658*323b6546SOliver Tappe 659*323b6546SOliver Tappe #ifdef MOUNT_MENU_IN_DESKBAR 660*323b6546SOliver Tappe 661*323b6546SOliver Tappe DeskbarMountMenu::DeskbarMountMenu(const char* name) 662*323b6546SOliver Tappe : BPrivate::MountMenu(name) 663*323b6546SOliver Tappe { 664*323b6546SOliver Tappe SetFont(be_plain_font); 665*323b6546SOliver Tappe } 666*323b6546SOliver Tappe 667*323b6546SOliver Tappe 668*323b6546SOliver Tappe bool 669*323b6546SOliver Tappe DeskbarMountMenu::AddDynamicItem(add_state s) 670*323b6546SOliver Tappe { 671*323b6546SOliver Tappe BPrivate::MountMenu::AddDynamicItem(s); 672*323b6546SOliver Tappe 673*323b6546SOliver Tappe SetTargetForItems(BMessenger(kTrackerSignature)); 674*323b6546SOliver Tappe 675*323b6546SOliver Tappe return false; 676*323b6546SOliver Tappe } 677*323b6546SOliver Tappe 678*323b6546SOliver Tappe 679*323b6546SOliver Tappe #endif 680*323b6546SOliver Tappe 681