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