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 <stdlib.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 "icons.h" 55 #include "tracker_private.h" 56 #include "BarApp.h" 57 #include "BarView.h" 58 #include "BarWindow.h" 59 #include "DeskBarUtils.h" 60 #include "FSUtils.h" 61 #include "PublicCommands.h" 62 #include "ResourceSet.h" 63 #include "Switcher.h" 64 #include "TeamMenu.h" 65 #include "WindowMenuItem.h" 66 67 68 // private Be API 69 extern void __set_window_decor(int32 theme); 70 71 BLocker TBarApp::sSubscriberLock; 72 BList TBarApp::sBarTeamInfoList; 73 BList TBarApp::sSubscribers; 74 75 76 const uint32 kShowBeMenu = 'BeMn'; 77 const uint32 kShowTeamMenu = 'TmMn'; 78 79 const BRect kIconSize(0.0f, 0.0f, 15.0f, 15.0f); 80 81 #if __HAIKU__ 82 static const color_space kIconFormat = B_RGBA32; 83 #else 84 static const color_space kIconFormat = B_CMAP8; 85 #endif 86 87 88 89 int 90 main() 91 { 92 TBarApp app; 93 app.Run(); 94 95 return B_OK; 96 } 97 98 99 TBarApp::TBarApp() 100 : BApplication(kDeskbarSignature), 101 fSettingsFile(NULL), 102 fPreferencesWindow(NULL) 103 { 104 InitSettings(); 105 InitIconPreloader(); 106 107 #ifdef __HAIKU__ 108 be_roster->StartWatching(this); 109 #endif 110 111 sBarTeamInfoList.MakeEmpty(); 112 113 BList teamList; 114 int32 numTeams; 115 be_roster->GetAppList(&teamList); 116 numTeams = teamList.CountItems(); 117 for (int32 i = 0; i < numTeams; i++) { 118 app_info appInfo; 119 team_id tID = (team_id)teamList.ItemAt(i); 120 if (be_roster->GetRunningAppInfo(tID, &appInfo) == B_OK) { 121 AddTeam(appInfo.team, appInfo.flags, appInfo.signature, 122 &appInfo.ref); 123 } 124 } 125 126 sSubscribers.MakeEmpty(); 127 128 fSwitcherMessenger = BMessenger(new TSwitchManager(fSettings.switcherLoc)); 129 130 fBarWindow = new TBarWindow(); 131 fBarWindow->Show(); 132 133 // this messenger now targets the barview instead of the 134 // statusview so that all additions to the tray 135 // follow the same path 136 fStatusViewMessenger = BMessenger(fBarWindow->FindView("BarView")); 137 } 138 139 140 TBarApp::~TBarApp() 141 { 142 #ifdef __HAIKU__ 143 be_roster->StopWatching(this); 144 #endif 145 146 int32 teamCount = sBarTeamInfoList.CountItems(); 147 for (int32 i = 0; i < teamCount; i++) { 148 BarTeamInfo *barInfo = (BarTeamInfo *)sBarTeamInfoList.ItemAt(i); 149 delete barInfo; 150 } 151 152 int32 subsCount = sSubscribers.CountItems(); 153 for (int32 i = 0; i < subsCount; i++) { 154 BMessenger *messenger = static_cast<BMessenger *>(sSubscribers.ItemAt(i)); 155 delete messenger; 156 } 157 SaveSettings(); 158 delete fSettingsFile; 159 } 160 161 162 bool 163 TBarApp::QuitRequested() 164 { 165 // don't allow user quitting 166 if (CurrentMessage() && CurrentMessage()->FindBool("shortcut")) { 167 // but allow quitting to hide fPreferencesWindow 168 int32 index = 0; 169 BWindow* window = NULL; 170 while ((window = WindowAt(index++)) != NULL) { 171 if (window == fPreferencesWindow) { 172 if (fPreferencesWindow->Lock()) { 173 if (fPreferencesWindow->IsActive()) 174 fPreferencesWindow->PostMessage(B_QUIT_REQUESTED); 175 fPreferencesWindow->Unlock(); 176 } 177 break; 178 } 179 } 180 return false; 181 } 182 183 // system quitting, call inherited to notify all loopers 184 fBarWindow->SaveSettings(); 185 BApplication::QuitRequested(); 186 return true; 187 } 188 189 190 void 191 TBarApp::SaveSettings() 192 { 193 if (fSettingsFile->InitCheck() == B_OK) { 194 fSettingsFile->Seek(0, SEEK_SET); 195 fSettingsFile->Write(&fSettings.vertical, sizeof(bool)); 196 fSettingsFile->Write(&fSettings.left, sizeof(bool)); 197 fSettingsFile->Write(&fSettings.top, sizeof(bool)); 198 fSettingsFile->Write(&fSettings.ampmMode, sizeof(bool)); 199 fSettingsFile->Write(&fSettings.state, sizeof(uint32)); 200 fSettingsFile->Write(&fSettings.width, sizeof(float)); 201 fSettingsFile->Write(&fSettings.showTime, sizeof(bool)); 202 fSettingsFile->Write(&fSettings.switcherLoc, sizeof(BPoint)); 203 fSettingsFile->Write(&fSettings.recentAppsCount, sizeof(int32)); 204 fSettingsFile->Write(&fSettings.recentDocsCount, sizeof(int32)); 205 fSettingsFile->Write(&fSettings.timeShowSeconds, sizeof(bool)); 206 fSettingsFile->Write(&fSettings.timeShowMil, sizeof(bool)); 207 fSettingsFile->Write(&fSettings.recentFoldersCount, sizeof(int32)); 208 fSettingsFile->Write(&fSettings.timeShowEuro, sizeof(bool)); 209 fSettingsFile->Write(&fSettings.alwaysOnTop, sizeof(bool)); 210 fSettingsFile->Write(&fSettings.timeFullDate, sizeof(bool)); 211 fSettingsFile->Write(&fSettings.trackerAlwaysFirst, sizeof(bool)); 212 fSettingsFile->Write(&fSettings.sortRunningApps, sizeof(bool)); 213 fSettingsFile->Write(&fSettings.superExpando, sizeof(bool)); 214 fSettingsFile->Write(&fSettings.expandNewTeams, sizeof(bool)); 215 fSettingsFile->Write(&fSettings.autoRaise, sizeof(bool)); 216 } 217 } 218 219 220 void 221 TBarApp::InitSettings() 222 { 223 desk_settings settings; 224 settings.vertical = true; 225 settings.left = false; 226 settings.top = true; 227 settings.ampmMode = true; 228 settings.showTime = true; 229 settings.state = kExpandoState; 230 settings.width = 0; 231 settings.switcherLoc = BPoint(5000, 5000); 232 settings.recentAppsCount = 10; 233 settings.recentDocsCount = 10; 234 settings.timeShowSeconds = false; 235 settings.timeShowMil = false; 236 settings.recentFoldersCount = 10; 237 settings.timeShowEuro = false; 238 settings.alwaysOnTop = false; 239 settings.timeFullDate = false; 240 settings.trackerAlwaysFirst = false; 241 settings.sortRunningApps = false; 242 settings.superExpando = false; 243 settings.expandNewTeams = false; 244 settings.autoRaise = false; 245 246 BPath dirPath; 247 const char *settingsFileName = "Deskbar_settings"; 248 249 find_directory(B_USER_DESKBAR_DIRECTORY, &dirPath, true); 250 // just make it 251 252 if (find_directory (B_USER_SETTINGS_DIRECTORY, &dirPath, true) == B_OK) { 253 BPath filePath = dirPath; 254 filePath.Append(settingsFileName); 255 fSettingsFile = new BFile(filePath.Path(), O_RDWR); 256 if (fSettingsFile->InitCheck() != B_OK) { 257 BDirectory theDir(dirPath.Path()); 258 if (theDir.InitCheck() == B_OK) 259 theDir.CreateFile(settingsFileName, fSettingsFile); 260 } 261 262 if (fSettingsFile->InitCheck() == B_OK) { 263 off_t size = 0; 264 fSettingsFile->GetSize(&size); 265 266 if (size >= kValidSettingsSize1) { 267 fSettingsFile->Seek(0, SEEK_SET); 268 fSettingsFile->Read(&settings.vertical, sizeof(bool)); 269 fSettingsFile->Read(&settings.left, sizeof(bool)); 270 fSettingsFile->Read(&settings.top, sizeof(bool)); 271 fSettingsFile->Read(&settings.ampmMode, sizeof(bool)); 272 fSettingsFile->Read(&settings.state, sizeof(uint32)); 273 fSettingsFile->Read(&settings.width, sizeof(float)); 274 fSettingsFile->Read(&settings.showTime, sizeof(bool)); 275 } 276 if (size >= kValidSettingsSize2) 277 fSettingsFile->Read(&settings.switcherLoc, sizeof(BPoint)); 278 if (size >= kValidSettingsSize3) { 279 fSettingsFile->Read(&settings.recentAppsCount, sizeof(int32)); 280 fSettingsFile->Read(&settings.recentDocsCount, sizeof(int32)); 281 } 282 if (size >= kValidSettingsSize4) { 283 fSettingsFile->Read(&settings.timeShowSeconds, sizeof(bool)); 284 fSettingsFile->Read(&settings.timeShowMil, sizeof(bool)); 285 } 286 if (size >= kValidSettingsSize5) 287 fSettingsFile->Read(&settings.recentFoldersCount, sizeof(int32)); 288 if (size >= kValidSettingsSize6) { 289 fSettingsFile->Read(&settings.timeShowEuro, sizeof(bool)); 290 fSettingsFile->Read(&settings.alwaysOnTop, sizeof(bool)); 291 } 292 if (size >= kValidSettingsSize7) 293 fSettingsFile->Read(&settings.timeFullDate, sizeof(bool)); 294 if (size >= kValidSettingsSize8) { 295 fSettingsFile->Read(&settings.trackerAlwaysFirst, sizeof(bool)); 296 fSettingsFile->Read(&settings.sortRunningApps, sizeof(bool)); 297 } 298 if (size >= kValidSettingsSize9) { 299 fSettingsFile->Read(&settings.superExpando, sizeof(bool)); 300 fSettingsFile->Read(&settings.expandNewTeams, sizeof(bool)); 301 } 302 if (size >= kValidSettingsSize10) 303 fSettingsFile->Read(&settings.autoRaise, sizeof(bool)); 304 } 305 } 306 307 fSettings = settings; 308 } 309 310 311 void 312 TBarApp::MessageReceived(BMessage *message) 313 { 314 int32 count; 315 switch (message->what) { 316 case 'gloc': 317 case 'sloc': 318 case 'gexp': 319 case 'sexp': 320 case 'info': 321 case 'exst': 322 case 'cwnt': 323 case 'icon': 324 case 'remv': 325 case 'adon': 326 // pass any BDeskbar originating messages on to the window 327 fBarWindow->PostMessage(message); 328 break; 329 330 case kConfigShow: 331 ShowPreferencesWindow(); 332 break; 333 334 case kShowBeMenu: 335 if (fBarWindow->Lock()) { 336 fBarWindow->ShowBeMenu(); 337 fBarWindow->Unlock(); 338 } 339 break; 340 341 case kShowTeamMenu: 342 if (fBarWindow->Lock()) { 343 fBarWindow->ShowTeamMenu(); 344 fBarWindow->Unlock(); 345 } 346 break; 347 348 case kUpdateRecentCounts: 349 if (message->FindInt32("applications", &count) == B_OK) 350 fSettings.recentAppsCount = count; 351 if (message->FindInt32("folders", &count) == B_OK) 352 fSettings.recentFoldersCount = count; 353 if (message->FindInt32("documents", &count) == B_OK) 354 fSettings.recentDocsCount = count; 355 break; 356 357 case kConfigClose: 358 fPreferencesWindow = NULL; 359 break; 360 361 case B_SOME_APP_LAUNCHED: 362 { 363 team_id team = -1; 364 message->FindInt32("be:team", &team); 365 366 uint32 flags = 0; 367 message->FindInt32("be:flags", (long *)&flags); 368 369 const char *sig = NULL; 370 message->FindString("be:signature", &sig); 371 372 entry_ref ref; 373 message->FindRef("be:ref", &ref); 374 375 AddTeam(team, flags, sig, &ref); 376 break; 377 } 378 379 case B_SOME_APP_QUIT: 380 { 381 team_id team = -1; 382 message->FindInt32("be:team", &team); 383 RemoveTeam(team); 384 break; 385 } 386 387 case B_ARCHIVED_OBJECT: 388 // TODO: what's this??? 389 message->AddString("special", "Alex Osadzinski"); 390 fStatusViewMessenger.SendMessage(message); 391 break; 392 393 case msg_Be: 394 __set_window_decor(0); 395 break; 396 397 case msg_Win95: 398 __set_window_decor(2); 399 break; 400 401 case msg_Amiga: 402 __set_window_decor(1); 403 break; 404 405 case msg_Mac: 406 __set_window_decor(3); 407 break; 408 409 case msg_ToggleDraggers: 410 if (BDragger::AreDraggersDrawn()) 411 BDragger::HideAllDraggers(); 412 else 413 BDragger::ShowAllDraggers(); 414 break; 415 416 case msg_AlwaysTop: 417 fSettings.alwaysOnTop = !fSettings.alwaysOnTop; 418 419 fBarWindow->SetFeel(fSettings.alwaysOnTop ? 420 B_FLOATING_ALL_WINDOW_FEEL : B_NORMAL_WINDOW_FEEL); 421 break; 422 423 case msg_AutoRaise: 424 { 425 fSettings.autoRaise = !fSettings.autoRaise; 426 427 TBarView *barView = static_cast<TBarApp *>(be_app)->BarView(); 428 fBarWindow->Lock(); 429 barView->UpdateAutoRaise(); 430 fBarWindow->Unlock(); 431 break; 432 } 433 434 case msg_trackerFirst: 435 { 436 fSettings.trackerAlwaysFirst = !fSettings.trackerAlwaysFirst; 437 438 TBarView *barView = static_cast<TBarApp *>(be_app)->BarView(); 439 fBarWindow->Lock(); 440 barView->UpdatePlacement(); 441 fBarWindow->Unlock(); 442 break; 443 } 444 445 case msg_sortRunningApps: 446 { 447 fSettings.sortRunningApps = !fSettings.sortRunningApps; 448 449 TBarView *barView = static_cast<TBarApp *>(be_app)->BarView(); 450 fBarWindow->Lock(); 451 barView->UpdatePlacement(); 452 fBarWindow->Unlock(); 453 break; 454 } 455 456 case msg_Unsubscribe: 457 { 458 BMessenger messenger; 459 if (message->FindMessenger("messenger", &messenger) == B_OK) 460 Unsubscribe(messenger); 461 break; 462 } 463 464 case msg_superExpando: 465 { 466 fSettings.superExpando = !fSettings.superExpando; 467 468 TBarView *barView = static_cast<TBarApp *>(be_app)->BarView(); 469 fBarWindow->Lock(); 470 barView->UpdatePlacement(); 471 fBarWindow->Unlock(); 472 break; 473 } 474 475 case msg_expandNewTeams: 476 { 477 fSettings.expandNewTeams = !fSettings.expandNewTeams; 478 479 TBarView *barView = static_cast<TBarApp *>(be_app)->BarView(); 480 fBarWindow->Lock(); 481 barView->UpdatePlacement(); 482 fBarWindow->Unlock(); 483 break; 484 } 485 486 case 'TASK': 487 fSwitcherMessenger.SendMessage(message); 488 break; 489 490 #if __HAIKU__ 491 case CMD_SUSPEND_SYSTEM: 492 break; 493 494 case CMD_REBOOT_SYSTEM: 495 case CMD_SHUTDOWN_SYSTEM: 496 { 497 bool reboot = (message->what == CMD_REBOOT_SYSTEM); 498 bool confirm; 499 message->FindBool("confirm", &confirm); 500 501 BRoster roster; 502 BRoster::Private rosterPrivate(roster); 503 status_t error = rosterPrivate.ShutDown(reboot, confirm, false); 504 if (error != B_OK) 505 fprintf(stderr, "Shutdown failed: %s\n", strerror(error)); 506 507 break; 508 } 509 #endif // __HAIKU__ 510 511 // in case Tracker is not running 512 513 case kShowSplash: 514 #ifdef B_BEOS_VERSION_5 515 run_be_about(); 516 #endif 517 break; 518 519 default: 520 BApplication::MessageReceived(message); 521 break; 522 } 523 } 524 525 526 /** In case Tracker is not running, the TBeMenu will use us as a target. 527 * We'll make sure the user won't be completely confused and take over 528 * Tracker's duties until it's back. 529 */ 530 531 void 532 TBarApp::RefsReceived(BMessage *refs) 533 { 534 entry_ref ref; 535 for (int32 i = 0; refs->FindRef("refs", i, &ref) == B_OK; i++) { 536 BMessage refsReceived(B_REFS_RECEIVED); 537 refsReceived.AddRef("refs", &ref); 538 539 BEntry entry(&ref); 540 if (!entry.IsDirectory()) 541 TrackerLaunch(&refsReceived, true); 542 } 543 } 544 545 546 void 547 TBarApp::Subscribe(const BMessenger &subscriber, BList *list) 548 { 549 // called when ExpandoMenuBar, TeamMenu or Switcher are built/rebuilt 550 list->MakeEmpty(); 551 552 BAutolock autolock(sSubscriberLock); 553 if (!autolock.IsLocked()) 554 return; 555 556 int32 numTeams = sBarTeamInfoList.CountItems(); 557 for (int32 i = 0; i < numTeams; i++) { 558 BarTeamInfo *barInfo = (BarTeamInfo *)sBarTeamInfoList.ItemAt(i); 559 BarTeamInfo *newBarInfo = new (std::nothrow) BarTeamInfo(*barInfo); 560 if (newBarInfo != NULL) 561 list->AddItem(newBarInfo); 562 } 563 564 int32 subsCount = sSubscribers.CountItems(); 565 for (int32 i = 0; i < subsCount; i++) { 566 BMessenger *messenger = (BMessenger *)sSubscribers.ItemAt(i); 567 if (*messenger == subscriber) 568 return; 569 } 570 571 sSubscribers.AddItem(new BMessenger(subscriber)); 572 } 573 574 575 void 576 TBarApp::Unsubscribe(const BMessenger &subscriber) 577 { 578 BAutolock autolock(sSubscriberLock); 579 if (!autolock.IsLocked()) 580 return; 581 582 int32 count = sSubscribers.CountItems(); 583 for (int32 i = 0; i < count; i++) { 584 BMessenger *messenger = (BMessenger *)sSubscribers.ItemAt(i); 585 if (*messenger == subscriber) { 586 sSubscribers.RemoveItem(i); 587 delete messenger; 588 break; 589 } 590 } 591 } 592 593 594 void 595 TBarApp::AddTeam(team_id team, uint32 flags, const char *sig, entry_ref *ref) 596 { 597 BAutolock autolock(sSubscriberLock); 598 if (!autolock.IsLocked()) 599 return; 600 601 // have we already seen this team, is this another instance of 602 // a known app? 603 BarTeamInfo *multiLaunchTeam = NULL; 604 int32 teamCount = sBarTeamInfoList.CountItems(); 605 for (int32 i = 0; i < teamCount; i++) { 606 BarTeamInfo *barInfo = (BarTeamInfo *)sBarTeamInfoList.ItemAt(i); 607 if (barInfo->teams->HasItem((void *)team)) 608 return; 609 if (strcasecmp(barInfo->sig, sig) == 0) 610 multiLaunchTeam = barInfo; 611 } 612 613 if (multiLaunchTeam != NULL) { 614 multiLaunchTeam->teams->AddItem((void *)team); 615 616 int32 subsCount = sSubscribers.CountItems(); 617 if (subsCount > 0) { 618 BMessage message(msg_AddTeam); 619 message.AddInt32("team", team); 620 message.AddString("sig", multiLaunchTeam->sig); 621 622 for (int32 i = 0; i < subsCount; i++) 623 ((BMessenger *)sSubscribers.ItemAt(i))->SendMessage(&message); 624 } 625 return; 626 } 627 628 BFile file(ref, B_READ_ONLY); 629 BAppFileInfo appMime(&file); 630 631 BarTeamInfo *barInfo = new BarTeamInfo(new BList(), flags, strdup(sig), 632 new BBitmap(kIconSize, kIconFormat), strdup(ref->name)); 633 634 barInfo->teams->AddItem((void *)team); 635 if (appMime.GetIcon(barInfo->icon, B_MINI_ICON) != B_OK) 636 appMime.GetTrackerIcon(barInfo->icon, B_MINI_ICON); 637 638 sBarTeamInfoList.AddItem(barInfo); 639 640 int32 subsCount = sSubscribers.CountItems(); 641 if (subsCount > 0) { 642 for (int32 i = 0; i < subsCount; i++) { 643 BMessenger *messenger = (BMessenger *)sSubscribers.ItemAt(i); 644 BMessage message(B_SOME_APP_LAUNCHED); 645 646 BList *tList = new BList(*(barInfo->teams)); 647 message.AddPointer("teams", tList); 648 649 BBitmap *icon = new BBitmap(barInfo->icon); 650 ASSERT(icon); 651 652 message.AddPointer("icon", icon); 653 654 message.AddInt32("flags", static_cast<int32>(barInfo->flags)); 655 message.AddString("name", barInfo->name); 656 message.AddString("sig", barInfo->sig); 657 658 messenger->SendMessage(&message); 659 } 660 } 661 } 662 663 664 void 665 TBarApp::RemoveTeam(team_id team) 666 { 667 BAutolock autolock(sSubscriberLock); 668 if (!autolock.IsLocked()) 669 return; 670 671 int32 teamCount = sBarTeamInfoList.CountItems(); 672 for (int32 i = 0; i < teamCount; i++) { 673 BarTeamInfo *barInfo = (BarTeamInfo *)sBarTeamInfoList.ItemAt(i); 674 if (barInfo->teams->HasItem((void *)team)) { 675 int32 subsCount = sSubscribers.CountItems(); 676 if (subsCount > 0) { 677 BMessage message((barInfo->teams->CountItems() == 1) ? 678 B_SOME_APP_QUIT : msg_RemoveTeam); 679 680 message.AddInt32("team", team); 681 for (int32 i = 0; i < subsCount; i++) { 682 BMessenger *messenger = (BMessenger *)sSubscribers.ItemAt(i); 683 messenger->SendMessage(&message); 684 } 685 } 686 687 barInfo->teams->RemoveItem((void *)team); 688 if (barInfo->teams->CountItems() < 1) { 689 delete (BarTeamInfo *)sBarTeamInfoList.RemoveItem(i); 690 return; 691 } 692 } 693 } 694 } 695 696 697 void 698 TBarApp::ShowPreferencesWindow() 699 { 700 if (fPreferencesWindow) 701 fPreferencesWindow->Activate(); 702 else { 703 fPreferencesWindow = new PreferencesWindow(BRect(0, 0, 320, 240)); 704 fPreferencesWindow->Show(); 705 } 706 } 707 708 709 // #pragma mark - 710 711 712 BarTeamInfo::BarTeamInfo(BList *teams, uint32 flags, char *sig, BBitmap *icon, char *name) 713 : teams(teams), 714 flags(flags), 715 sig(sig), 716 icon(icon), 717 name(name) 718 { 719 } 720 721 722 BarTeamInfo::BarTeamInfo(const BarTeamInfo &info) 723 : teams(new BList(*info.teams)), 724 flags(info.flags), 725 sig(strdup(info.sig)), 726 icon(new BBitmap(*info.icon)), 727 name(strdup(info.name)) 728 { 729 } 730 731 732 BarTeamInfo::~BarTeamInfo() 733 { 734 delete teams; 735 free(sig); 736 delete icon; 737 free(name); 738 } 739 740 741