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
16class 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
27QuitMenuItem::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
38QuitMenu::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
48void
49QuitMenu::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
75void
76QuitMenu::DetachedFromWindow()
77{
78	BMenu::DetachedFromWindow();
79	be_roster->StopWatching(*fMe);
80	delete fMe;
81	fMe = NULL;
82}
83
84
85void
86QuitMenu::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	}
114	if (item) {
115		item->SetTarget(gPCView);
116		AddItem(item);
117	} else
118		delete message;
119}
120
121
122void
123QuitMenu::MessageReceived(BMessage *msg)
124{
125	switch (msg->what) {
126		case B_SOME_APP_LAUNCHED:
127		{
128			int32 tmid;
129			if (msg->FindInt32("be:team", &tmid) == B_OK)
130				AddTeam(tmid);
131			break;
132		}
133		case B_SOME_APP_QUIT:
134		{
135			int32 tmid;
136			if (msg->FindInt32("be:team", &tmid) == B_OK) {
137				QuitMenuItem* item;
138				int t = 0;
139				while ((item = (QuitMenuItem*) ItemAt(t++)) != NULL) {
140					if (item->Team() == tmid) {
141						delete RemoveItem(--t);
142						return;
143					}
144				}
145			}
146			break;
147		}
148
149		default:
150			BMenu::MessageReceived(msg);
151	}
152}
153