1 /* 2 Open Tracker License 3 4 Terms and Conditions 5 6 Copyright (c) 1991-2000, Be Incorporated. All rights reserved. 7 8 Permission is hereby granted, free of charge, to any person obtaining a copy of 9 this software and associated documentation files (the "Software"), to deal in 10 the Software without restriction, including without limitation the rights to 11 use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 12 of the Software, and to permit persons to whom the Software is furnished to do 13 so, subject to the following conditions: 14 15 The above copyright notice and this permission notice applies to all licensees 16 and shall be included in all copies or substantial portions of the Software. 17 18 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF TITLE, MERCHANTABILITY, 20 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 21 BE INCORPORATED BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 22 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF, OR IN CONNECTION 23 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 25 Except as contained in this notice, the name of Be Incorporated shall not be 26 used in advertising or otherwise to promote the sale, use or other dealings in 27 this Software without prior written authorization from Be Incorporated. 28 29 Tracker(TM), Be(R), BeOS(R), and BeIA(TM) are trademarks or registered trademarks 30 of Be Incorporated in the United States and other countries. Other brand product 31 names are registered trademarks or trademarks of their respective holders. 32 All rights reserved. 33 */ 34 35 #include <Debug.h> 36 #include <malloc.h> 37 #include <string.h> 38 39 #include <AppFileInfo.h> 40 #include <Autolock.h> 41 #include <Bitmap.h> 42 #include <Directory.h> 43 #include <Dragger.h> 44 #include <File.h> 45 #include <FindDirectory.h> 46 #include <Mime.h> 47 #include <Path.h> 48 #include <Roster.h> 49 50 #if __HAIKU__ 51 # include <RosterPrivate.h> 52 #endif 53 54 #include "FavoritesConfig.h" 55 56 #include "icons.h" 57 #include "tracker_private.h" 58 #include "BarApp.h" 59 #include "BarView.h" 60 #include "BarWindow.h" 61 #include "DeskBarUtils.h" 62 #include "FSUtils.h" 63 #include "PublicCommands.h" 64 #include "ResourceSet.h" 65 #include "Switcher.h" 66 #include "TeamMenu.h" 67 #include "WindowMenuItem.h" 68 69 70 // private Be API 71 extern void __set_window_decor(int32 theme); 72 73 BLocker TBarApp::sSubscriberLock; 74 BList TBarApp::sBarTeamInfoList; 75 BList TBarApp::sSubscribers; 76 77 78 const uint32 kShowBeMenu = 'BeMn'; 79 const uint32 kShowTeamMenu = 'TmMn'; 80 81 const BRect kIconSize(0.0f, 0.0f, 15.0f, 15.0f); 82 83 84 int 85 main() 86 { 87 TBarApp app; 88 app.Run(); 89 90 return B_OK; 91 } 92 93 94 TBarApp::TBarApp() 95 : BApplication(kDeskbarSignature), 96 fSettingsFile(NULL), 97 fConfigWindow(NULL) 98 { 99 InitSettings(); 100 InitIconPreloader(); 101 102 #ifdef __HAIKU__ 103 be_roster->StartWatching(this); 104 #endif 105 106 sBarTeamInfoList.MakeEmpty(); 107 108 BList teamList; 109 int32 numTeams; 110 be_roster->GetAppList(&teamList); 111 numTeams = teamList.CountItems(); 112 for (int32 i = 0; i < numTeams; i++) { 113 app_info appInfo; 114 team_id tID = (team_id)teamList.ItemAt(i); 115 if (be_roster->GetRunningAppInfo(tID, &appInfo) == B_OK) { 116 AddTeam(appInfo.team, appInfo.flags, appInfo.signature, 117 &appInfo.ref); 118 } 119 } 120 121 sSubscribers.MakeEmpty(); 122 123 fSwitcherMessenger = BMessenger(new TSwitchManager(fSettings.switcherLoc)); 124 125 fBarWindow = new TBarWindow(); 126 fBarWindow->Show(); 127 128 // this messenger now targets the barview instead of the 129 // statusview so that all additions to the tray 130 // follow the same path 131 fStatusViewMessenger = BMessenger(fBarWindow->FindView("BarView")); 132 } 133 134 135 TBarApp::~TBarApp() 136 { 137 #ifdef __HAIKU__ 138 be_roster->StopWatching(this); 139 #endif 140 141 int32 teamCount = sBarTeamInfoList.CountItems(); 142 for (int32 i = 0; i < teamCount; i++) { 143 BarTeamInfo *barInfo = (BarTeamInfo *)sBarTeamInfoList.ItemAt(i); 144 delete barInfo->teams; 145 free(barInfo->sig); 146 delete barInfo->icon; 147 free(barInfo->name); 148 free(barInfo); 149 } 150 151 int32 subsCount = sSubscribers.CountItems(); 152 for (int32 i = 0; i < subsCount; i++) { 153 BMessenger *messenger = static_cast<BMessenger *>(sSubscribers.ItemAt(i)); 154 delete messenger; 155 } 156 SaveSettings(); 157 delete fSettingsFile; 158 } 159 160 161 bool 162 TBarApp::QuitRequested() 163 { 164 if (CurrentMessage() && CurrentMessage()->FindBool("shortcut")) 165 // don't allow user quitting 166 return false; 167 168 // system quitting, call inherited to notify all loopers 169 fBarWindow->SaveSettings(); 170 BApplication::QuitRequested(); 171 return true; 172 } 173 174 175 void 176 TBarApp::SaveSettings() 177 { 178 if (fSettingsFile->InitCheck() == B_OK) { 179 fSettingsFile->Seek(0, SEEK_SET); 180 fSettingsFile->Write(&fSettings.vertical, sizeof(bool)); 181 fSettingsFile->Write(&fSettings.left, sizeof(bool)); 182 fSettingsFile->Write(&fSettings.top, sizeof(bool)); 183 fSettingsFile->Write(&fSettings.ampmMode, sizeof(bool)); 184 fSettingsFile->Write(&fSettings.state, sizeof(uint32)); 185 fSettingsFile->Write(&fSettings.width, sizeof(float)); 186 fSettingsFile->Write(&fSettings.showTime, sizeof(bool)); 187 fSettingsFile->Write(&fSettings.switcherLoc, sizeof(BPoint)); 188 fSettingsFile->Write(&fSettings.recentAppsCount, sizeof(int32)); 189 fSettingsFile->Write(&fSettings.recentDocsCount, sizeof(int32)); 190 fSettingsFile->Write(&fSettings.timeShowSeconds, sizeof(bool)); 191 fSettingsFile->Write(&fSettings.timeShowMil, sizeof(bool)); 192 fSettingsFile->Write(&fSettings.recentFoldersCount, sizeof(int32)); 193 fSettingsFile->Write(&fSettings.timeShowEuro, sizeof(bool)); 194 fSettingsFile->Write(&fSettings.alwaysOnTop, sizeof(bool)); 195 fSettingsFile->Write(&fSettings.timeFullDate, sizeof(bool)); 196 fSettingsFile->Write(&fSettings.trackerAlwaysFirst, sizeof(bool)); 197 fSettingsFile->Write(&fSettings.sortRunningApps, sizeof(bool)); 198 fSettingsFile->Write(&fSettings.superExpando, sizeof(bool)); 199 fSettingsFile->Write(&fSettings.expandNewTeams, sizeof(bool)); 200 } 201 } 202 203 204 void 205 TBarApp::InitSettings() 206 { 207 desk_settings settings; 208 settings.vertical = true; 209 settings.left = false; 210 settings.top = true; 211 settings.ampmMode = true; 212 settings.showTime = true; 213 settings.state = kExpandoState; 214 settings.width = 0; 215 settings.switcherLoc = BPoint(5000, 5000); 216 settings.recentAppsCount = 10; 217 settings.recentDocsCount = 10; 218 settings.timeShowSeconds = false; 219 settings.timeShowMil = false; 220 settings.recentFoldersCount = 0; // default is hidden 221 settings.timeShowEuro = false; 222 settings.alwaysOnTop = false; 223 settings.timeFullDate = false; 224 settings.trackerAlwaysFirst = false; 225 settings.sortRunningApps = false; 226 settings.superExpando = false; 227 settings.expandNewTeams = false; 228 229 BPath dirPath; 230 const char *settingsFileName = "Deskbar_settings"; 231 232 find_directory(B_USER_DESKBAR_DIRECTORY, &dirPath, true); 233 // just make it 234 235 if (find_directory (B_USER_SETTINGS_DIRECTORY, &dirPath, true) == B_OK) { 236 BPath filePath = dirPath; 237 filePath.Append(settingsFileName); 238 fSettingsFile = new BFile(filePath.Path(), O_RDWR); 239 if (fSettingsFile->InitCheck() != B_OK) { 240 BDirectory theDir(dirPath.Path()); 241 if (theDir.InitCheck() == B_OK) 242 theDir.CreateFile(settingsFileName, fSettingsFile); 243 } 244 245 if (fSettingsFile->InitCheck() == B_OK) { 246 off_t theSize = 0; 247 fSettingsFile->GetSize(&theSize); 248 249 if (theSize >= kValidSettingsSize1) { 250 fSettingsFile->Seek(0, SEEK_SET); 251 fSettingsFile->Read(&settings.vertical, sizeof(bool)); 252 fSettingsFile->Read(&settings.left, sizeof(bool)); 253 fSettingsFile->Read(&settings.top, sizeof(bool)); 254 fSettingsFile->Read(&settings.ampmMode, sizeof(bool)); 255 fSettingsFile->Read(&settings.state, sizeof(uint32)); 256 fSettingsFile->Read(&settings.width, sizeof(float)); 257 fSettingsFile->Read(&settings.showTime, sizeof(bool)); 258 } 259 if (theSize >= kValidSettingsSize2) 260 fSettingsFile->Read(&settings.switcherLoc, sizeof(BPoint)); 261 if (theSize >= kValidSettingsSize3) { 262 fSettingsFile->Read(&settings.recentAppsCount, sizeof(int32)); 263 fSettingsFile->Read(&settings.recentDocsCount, sizeof(int32)); 264 } 265 if (theSize >= kValidSettingsSize4) { 266 fSettingsFile->Read(&settings.timeShowSeconds, sizeof(bool)); 267 fSettingsFile->Read(&settings.timeShowMil, sizeof(bool)); 268 } 269 if (theSize >= kValidSettingsSize5) 270 fSettingsFile->Read(&settings.recentFoldersCount, sizeof(int32)); 271 if (theSize >= kValidSettingsSize6) { 272 fSettingsFile->Read(&settings.timeShowEuro, sizeof(bool)); 273 fSettingsFile->Read(&settings.alwaysOnTop, sizeof(bool)); 274 } 275 if (theSize >= kValidSettingsSize7) 276 fSettingsFile->Read(&settings.timeFullDate, sizeof(bool)); 277 if (theSize >= kValidSettingsSize8) { 278 fSettingsFile->Read(&settings.trackerAlwaysFirst, sizeof(bool)); 279 fSettingsFile->Read(&settings.sortRunningApps, sizeof(bool)); 280 } 281 if (theSize >= kValidSettingsSize9) { 282 fSettingsFile->Read(&settings.superExpando, sizeof(bool)); 283 fSettingsFile->Read(&settings.expandNewTeams, sizeof(bool)); 284 } 285 } 286 } 287 288 fSettings = settings; 289 } 290 291 292 void 293 TBarApp::MessageReceived(BMessage *message) 294 { 295 int32 count; 296 switch (message->what) { 297 case 'gloc': 298 case 'sloc': 299 case 'gexp': 300 case 'sexp': 301 case 'info': 302 case 'exst': 303 case 'cwnt': 304 case 'icon': 305 case 'remv': 306 case 'adon': 307 // pass any BDeskbar originating messages on to the window 308 fBarWindow->PostMessage(message); 309 break; 310 311 case kConfigShow: 312 if (message->FindInt32("count", &count) == B_OK) 313 fSettings.recentDocsCount = count; 314 break; 315 316 case kUpdateAppsCount: 317 if (message->FindInt32("count", &count) == B_OK) 318 fSettings.recentAppsCount = count; 319 break; 320 321 case kShowBeMenu: 322 if (fBarWindow->Lock()) { 323 fBarWindow->ShowBeMenu(); 324 fBarWindow->Unlock(); 325 } 326 break; 327 328 case kShowTeamMenu: 329 if (fBarWindow->Lock()) { 330 fBarWindow->ShowTeamMenu(); 331 fBarWindow->Unlock(); 332 } 333 break; 334 335 case msg_config_db: 336 ShowConfigWindow(); 337 break; 338 339 case kConfigClose: 340 if (message->FindInt32("applications", &count) == B_OK) 341 fSettings.recentAppsCount = count; 342 if (message->FindInt32("folders", &count) == B_OK) 343 fSettings.recentFoldersCount = count; 344 if (message->FindInt32("documents", &count) == B_OK) 345 fSettings.recentDocsCount = count; 346 347 fConfigWindow = NULL; 348 break; 349 350 case B_SOME_APP_LAUNCHED: 351 { 352 team_id team = -1; 353 message->FindInt32("be:team", &team); 354 355 uint32 flags = 0; 356 message->FindInt32("be:flags", (long *)&flags); 357 358 const char *sig = NULL; 359 message->FindString("be:signature", &sig); 360 361 entry_ref ref; 362 message->FindRef("be:ref", &ref); 363 364 AddTeam(team, flags, sig, &ref); 365 break; 366 } 367 368 case B_SOME_APP_QUIT: 369 { 370 team_id team = -1; 371 message->FindInt32("be:team", &team); 372 RemoveTeam(team); 373 break; 374 } 375 376 case B_ARCHIVED_OBJECT: 377 // TODO: what's this??? 378 message->AddString("special", "Alex Osadzinski"); 379 fStatusViewMessenger.SendMessage(message); 380 break; 381 382 case msg_Be: 383 __set_window_decor(0); 384 break; 385 386 case msg_Win95: 387 __set_window_decor(2); 388 break; 389 390 case msg_Amiga: 391 __set_window_decor(1); 392 break; 393 394 case msg_Mac: 395 __set_window_decor(3); 396 break; 397 398 case msg_ToggleDraggers: 399 if (BDragger::AreDraggersDrawn()) 400 BDragger::HideAllDraggers(); 401 else 402 BDragger::ShowAllDraggers(); 403 break; 404 405 case msg_AlwaysTop: 406 fSettings.alwaysOnTop = !fSettings.alwaysOnTop; 407 408 fBarWindow->SetFeel(fSettings.alwaysOnTop ? 409 B_FLOATING_ALL_WINDOW_FEEL : B_NORMAL_WINDOW_FEEL); 410 break; 411 412 case msg_trackerFirst: 413 { 414 fSettings.trackerAlwaysFirst = !fSettings.trackerAlwaysFirst; 415 416 TBarView *barView = static_cast<TBarApp *>(be_app)->BarView(); 417 fBarWindow->Lock(); 418 barView->UpdatePlacement(); 419 fBarWindow->Unlock(); 420 break; 421 } 422 423 case msg_sortRunningApps: 424 { 425 fSettings.sortRunningApps = !fSettings.sortRunningApps; 426 427 TBarView *barView = static_cast<TBarApp *>(be_app)->BarView(); 428 fBarWindow->Lock(); 429 barView->UpdatePlacement(); 430 fBarWindow->Unlock(); 431 break; 432 } 433 434 case msg_Unsubscribe: 435 { 436 BMessenger messenger; 437 if (message->FindMessenger("messenger", &messenger) == B_OK) 438 Unsubscribe(messenger); 439 break; 440 } 441 442 case msg_superExpando: 443 { 444 fSettings.superExpando = !fSettings.superExpando; 445 446 TBarView *barView = static_cast<TBarApp *>(be_app)->BarView(); 447 fBarWindow->Lock(); 448 barView->UpdatePlacement(); 449 fBarWindow->Unlock(); 450 break; 451 } 452 453 case msg_expandNewTeams: 454 { 455 fSettings.expandNewTeams = !fSettings.expandNewTeams; 456 457 TBarView *barView = static_cast<TBarApp *>(be_app)->BarView(); 458 fBarWindow->Lock(); 459 barView->UpdatePlacement(); 460 fBarWindow->Unlock(); 461 break; 462 } 463 464 case 'TASK': 465 fSwitcherMessenger.SendMessage(message); 466 break; 467 468 #if __HAIKU__ 469 case CMD_SUSPEND_SYSTEM: 470 break; 471 472 case CMD_REBOOT_SYSTEM: 473 case CMD_SHUTDOWN_SYSTEM: { 474 bool reboot = (message->what == CMD_REBOOT_SYSTEM); 475 BRoster roster; 476 BRoster::Private rosterPrivate(roster); 477 status_t error = rosterPrivate.ShutDown(reboot, true, false); 478 if (error != B_OK) 479 fprintf(stderr, "Shutdown failed: %s\n", strerror(error)); 480 481 break; 482 } 483 #endif // __HAIKU__ 484 485 // in case Tracker is not running 486 487 case kShowSplash: 488 #ifdef B_BEOS_VERSION_5 489 run_be_about(); 490 #endif 491 break; 492 493 default: 494 BApplication::MessageReceived(message); 495 break; 496 } 497 } 498 499 500 /** In case Tracker is not running, the TBeMenu will use us as a target. 501 * We'll make sure the user won't be completely confused and take over 502 * Tracker's duties until it's back. 503 */ 504 505 void 506 TBarApp::RefsReceived(BMessage *refs) 507 { 508 entry_ref ref; 509 for (int32 i = 0; refs->FindRef("refs", i, &ref) == B_OK; i++) { 510 BMessage refsReceived(B_REFS_RECEIVED); 511 refsReceived.AddRef("refs", &ref); 512 513 BEntry entry(&ref); 514 if (!entry.IsDirectory()) 515 TrackerLaunch(&refsReceived, true); 516 } 517 } 518 519 520 void 521 TBarApp::Subscribe(const BMessenger &subscriber, BList *list) 522 { 523 // called when ExpandoMenuBar, TeamMenu or Switcher are built/rebuilt 524 list->MakeEmpty(); 525 526 BAutolock autolock(sSubscriberLock); 527 if (!autolock.IsLocked()) 528 return; 529 530 int32 numTeams = sBarTeamInfoList.CountItems(); 531 for (int32 i = 0; i < numTeams; i++) { 532 BarTeamInfo *barInfo = (BarTeamInfo *)sBarTeamInfoList.ItemAt(i); 533 BList *tList = new BList(*(barInfo->teams)); 534 BBitmap *icon = new BBitmap(kIconSize, B_COLOR_8_BIT); 535 ASSERT(icon); 536 icon->SetBits(barInfo->icon->Bits(), icon->BitsLength(), 0, B_COLOR_8_BIT); 537 list->AddItem(new BarTeamInfo(tList, barInfo->flags, strdup(barInfo->sig), icon, strdup(barInfo->name))); 538 } 539 540 int32 subsCount = sSubscribers.CountItems(); 541 for (int32 i = 0; i < subsCount; i++) { 542 BMessenger *messenger = (BMessenger *)sSubscribers.ItemAt(i); 543 if (*messenger == subscriber) 544 return; 545 } 546 547 sSubscribers.AddItem(new BMessenger(subscriber)); 548 } 549 550 551 void 552 TBarApp::Unsubscribe(const BMessenger &subscriber) 553 { 554 BAutolock autolock(sSubscriberLock); 555 if (!autolock.IsLocked()) 556 return; 557 558 int32 count = sSubscribers.CountItems(); 559 for (int32 i = 0; i < count; i++) { 560 BMessenger *messenger = (BMessenger *)sSubscribers.ItemAt(i); 561 if (*messenger == subscriber) { 562 sSubscribers.RemoveItem(i); 563 delete (messenger); 564 break; 565 } 566 } 567 } 568 569 570 void 571 TBarApp::AddTeam(team_id team, uint32 flags, const char *sig, entry_ref *ref) 572 { 573 BAutolock autolock(sSubscriberLock); 574 if (!autolock.IsLocked()) 575 return; 576 577 // have we already seen this team, is this another instance of 578 // a known app? 579 BarTeamInfo *multiLaunchTeam = NULL; 580 int32 teamCount = sBarTeamInfoList.CountItems(); 581 for (int32 i = 0; i < teamCount; i++) { 582 BarTeamInfo *barInfo = (BarTeamInfo *)sBarTeamInfoList.ItemAt(i); 583 if (barInfo->teams->HasItem((void *)team)) 584 return; 585 if (strcasecmp(barInfo->sig, sig) == 0) 586 multiLaunchTeam = barInfo; 587 } 588 589 if (multiLaunchTeam != NULL) { 590 multiLaunchTeam->teams->AddItem((void *)team); 591 592 int32 subsCount = sSubscribers.CountItems(); 593 if (subsCount > 0) { 594 BMessage message(msg_AddTeam); 595 message.AddInt32("team", team); 596 message.AddString("sig", multiLaunchTeam->sig); 597 598 for (int32 i = 0; i < subsCount; i++) 599 ((BMessenger *)sSubscribers.ItemAt(i))->SendMessage(&message); 600 } 601 return; 602 } 603 604 BFile file(ref, B_READ_ONLY); 605 BAppFileInfo appMime(&file); 606 607 BarTeamInfo *barInfo = new BarTeamInfo(new BList(), flags, strdup(sig), 608 new BBitmap(kIconSize, B_COLOR_8_BIT), strdup(ref->name)); 609 610 barInfo->teams->AddItem((void *)team); 611 if (appMime.GetIcon(barInfo->icon, B_MINI_ICON) != B_OK) { 612 const BBitmap* generic = AppResSet()->FindBitmap(B_MESSAGE_TYPE, R_GenericAppIcon); 613 if (generic) 614 barInfo->icon->SetBits(generic->Bits(), barInfo->icon->BitsLength(), 615 0, B_COLOR_8_BIT); 616 } 617 618 sBarTeamInfoList.AddItem(barInfo); 619 620 int32 subsCount = sSubscribers.CountItems(); 621 if (subsCount > 0) { 622 for (int32 i = 0; i < subsCount; i++) { 623 BMessenger *messenger = (BMessenger *)sSubscribers.ItemAt(i); 624 BMessage message(B_SOME_APP_LAUNCHED); 625 626 BList *tList = new BList(*(barInfo->teams)); 627 message.AddPointer("teams", tList); 628 629 BBitmap *icon = new BBitmap(kIconSize, B_COLOR_8_BIT); 630 ASSERT(icon); 631 632 icon->SetBits(barInfo->icon->Bits(), icon->BitsLength(), 0, B_COLOR_8_BIT); 633 message.AddPointer("icon", icon); 634 635 message.AddInt32("flags", static_cast<int32>(barInfo->flags)); 636 message.AddString("name", barInfo->name); 637 message.AddString("sig", barInfo->sig); 638 639 messenger->SendMessage(&message); 640 } 641 } 642 } 643 644 645 void 646 TBarApp::RemoveTeam(team_id team) 647 { 648 BAutolock autolock(sSubscriberLock); 649 if (!autolock.IsLocked()) 650 return; 651 652 int32 teamCount = sBarTeamInfoList.CountItems(); 653 for (int32 i = 0; i < teamCount; i++) { 654 BarTeamInfo *barInfo = (BarTeamInfo *)sBarTeamInfoList.ItemAt(i); 655 if (barInfo->teams->HasItem((void *)team)) { 656 int32 subsCount = sSubscribers.CountItems(); 657 if (subsCount > 0) { 658 BMessage message((barInfo->teams->CountItems() == 1) ? 659 B_SOME_APP_QUIT : msg_RemoveTeam); 660 661 message.AddInt32("team", team); 662 for (int32 i = 0; i < subsCount; i++) { 663 BMessenger *messenger = (BMessenger *)sSubscribers.ItemAt(i); 664 messenger->SendMessage(&message); 665 } 666 } 667 668 barInfo->teams->RemoveItem((void *)team); 669 if (barInfo->teams->CountItems() < 1) { 670 delete (BarTeamInfo *)sBarTeamInfoList.RemoveItem(i); 671 return; 672 } 673 } 674 } 675 } 676 677 678 void 679 TBarApp::ShowConfigWindow() 680 { 681 if (fConfigWindow) 682 fConfigWindow->Activate(); 683 else { 684 // always start at top, could be cached and we could start 685 // where we left off. 686 BPath path; 687 find_directory (B_USER_DESKBAR_DIRECTORY, &path); 688 entry_ref startref; 689 get_ref_for_path(path.Path(), &startref); 690 691 fConfigWindow = new TFavoritesConfigWindow(BRect(0, 0, 320, 240), 692 "Configure Be Menu", false, B_ANY_NODE, 693 BMessenger(this), &startref, 694 fSettings.recentAppsCount, fSettings.recentDocsCount, 695 fSettings.recentFoldersCount); 696 } 697 } 698 699 700 // #pragma mark - 701 702 703 BarTeamInfo::BarTeamInfo(BList *teams, uint32 flags, char *sig, BBitmap *icon, char *name) 704 : teams(teams), 705 flags(flags), 706 sig(sig), 707 icon(icon), 708 name(name) 709 { 710 } 711 712 713 BarTeamInfo::~BarTeamInfo() 714 { 715 delete teams; 716 free(sig); 717 delete icon; 718 free(name); 719 } 720 721 722