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