1 /* 2 * Copyright 2000, Georges-Edouard Berenger. All rights reserved. 3 * Distributed under the terms of the MIT License. 4 */ 5 6 7 #include "QuitMenu.h" 8 #include "IconMenuItem.h" 9 #include "ProcessController.h" 10 11 #include <Roster.h> 12 #include <Window.h> 13 #include <stdio.h> 14 15 16 class QuitMenuItem : public IconMenuItem { 17 public: 18 QuitMenuItem(team_id team, BBitmap* icon, const char* title, 19 BMessage* m, bool purge = false); 20 team_id Team() { return fTeam; } 21 22 private: 23 team_id fTeam; 24 }; 25 26 27 QuitMenuItem::QuitMenuItem(team_id team, BBitmap* icon, const char* title, 28 BMessage* m, bool purge) 29 : 30 IconMenuItem(icon, title, m, true, purge), fTeam(team) 31 { 32 } 33 34 35 // #pragma mark - 36 37 38 QuitMenu::QuitMenu(const char* title, info_pack* infos, int infosCount) 39 : BMenu(title), 40 fInfos(infos), 41 fInfosCount(infosCount), 42 fMe(NULL) 43 { 44 SetTargetForItems(gPCView); 45 } 46 47 48 void 49 QuitMenu::AttachedToWindow() 50 { 51 if (!fMe) 52 fMe = new BMessenger(this); 53 54 be_roster->StartWatching(*fMe, B_REQUEST_LAUNCHED | B_REQUEST_QUIT); 55 BList apps; 56 team_id tmid; 57 be_roster->GetAppList(&apps); 58 for (int t = CountItems() - 1; t >= 0; t--) { 59 QuitMenuItem* item = (QuitMenuItem*)ItemAt(t); 60 bool found = false; 61 for (int a = 0; !found && (tmid = (team_id)(addr_t)apps.ItemAt(a)) != 0; a++) 62 if (item->Team() == tmid) 63 found = true; 64 if (!found) 65 RemoveItem(t); 66 } 67 for (int a = 0; (tmid = (team_id)(addr_t) apps.ItemAt(a)) != 0; a++) { 68 AddTeam(tmid); 69 } 70 71 BMenu::AttachedToWindow(); 72 } 73 74 75 void 76 QuitMenu::DetachedFromWindow() 77 { 78 BMenu::DetachedFromWindow(); 79 be_roster->StopWatching(*fMe); 80 delete fMe; 81 fMe = NULL; 82 } 83 84 85 void 86 QuitMenu::AddTeam(team_id tmid) 87 { 88 int t = 0; 89 QuitMenuItem* item; 90 while ((item = (QuitMenuItem*) ItemAt(t++)) != NULL) { 91 if (item->Team() == tmid) 92 return; 93 } 94 95 t = 0; 96 while (t < fInfosCount && tmid != fInfos[t].team_info.team) { 97 t++; 98 } 99 100 BMessage* message = new BMessage ('QtTm'); 101 message->AddInt32 ("team", tmid); 102 item = NULL; 103 if (t < fInfosCount) 104 item = new QuitMenuItem(tmid, fInfos[t].team_icon, fInfos[t].team_name, 105 message); 106 else { 107 info_pack infos; 108 if (get_team_info(tmid, &infos.team_info) == B_OK 109 && get_team_name_and_icon(infos, true)) 110 item = new QuitMenuItem(tmid, infos.team_icon, infos.team_name, 111 message, true); 112 } 113 if (item) { 114 item->SetTarget(gPCView); 115 AddItem(item); 116 } else 117 delete message; 118 } 119 120 121 void 122 QuitMenu::MessageReceived(BMessage *msg) 123 { 124 switch (msg->what) { 125 case B_SOME_APP_LAUNCHED: 126 { 127 int32 tmid; 128 if (msg->FindInt32("be:team", &tmid) == B_OK) 129 AddTeam(tmid); 130 break; 131 } 132 case B_SOME_APP_QUIT: 133 { 134 int32 tmid; 135 if (msg->FindInt32("be:team", &tmid) == B_OK) { 136 QuitMenuItem* item; 137 int t = 0; 138 while ((item = (QuitMenuItem*) ItemAt(t++)) != NULL) { 139 if (item->Team() == tmid) { 140 delete RemoveItem(--t); 141 return; 142 } 143 } 144 } 145 break; 146 } 147 148 default: 149 BMenu::MessageReceived(msg); 150 } 151 } 152