xref: /haiku/src/apps/debugger/user_interface/gui/teams_window/TeamsWindow.cpp (revision 385ee03ba83b7a40d315e17b03031b3ca37820c0)
1 /*
2  * Copyright 2009-2010, Philippe Houdoin, phoudoin@haiku-os.org. All rights reserved.
3  * Copyright 2013-2016, Rene Gollent, rene@gollent.com.
4  * Distributed under the terms of the MIT License.
5  */
6 #include "TeamsWindow.h"
7 
8 
9 #include <new>
10 
11 #include <stdio.h>
12 #include <string.h>
13 #include <stdarg.h>
14 
15 #include <Application.h>
16 #include <Button.h>
17 #include <File.h>
18 #include <FilePanel.h>
19 #include <FindDirectory.h>
20 #include <LayoutBuilder.h>
21 #include <ListView.h>
22 #include <Path.h>
23 #include <Screen.h>
24 #include <ScrollView.h>
25 
26 #include "MessageCodes.h"
27 #include "SettingsManager.h"
28 #include "TargetHostInterface.h"
29 #include "TargetHostInterfaceRoster.h"
30 #include "TeamsListView.h"
31 
32 
33 enum {
34 	MSG_TEAM_SELECTION_CHANGED = 'tesc',
35 	MSG_CHOSE_CORE_FILE = 'chcf'
36 };
37 
38 
39 TeamsWindow::TeamsWindow(SettingsManager* settingsManager)
40 	:
41 	BWindow(BRect(100, 100, 500, 250), "Teams", B_DOCUMENT_WINDOW,
42 		B_ASYNCHRONOUS_CONTROLS),
43 	fTargetHostInterface(NULL),
44 	fTeamsListView(NULL),
45 	fAttachTeamButton(NULL),
46 	fCreateTeamButton(NULL),
47 	fLoadCoreButton(NULL),
48 	fCoreSelectionPanel(NULL),
49 	fSettingsManager(settingsManager)
50 {
51 	team_info info;
52 	get_team_info(B_CURRENT_TEAM, &info);
53 	fCurrentTeam = info.team;
54 }
55 
56 
57 TeamsWindow::~TeamsWindow()
58 {
59 }
60 
61 
62 /*static*/ TeamsWindow*
63 TeamsWindow::Create(SettingsManager* settingsManager)
64 {
65 	TeamsWindow* self = new TeamsWindow(settingsManager);
66 
67 	try {
68 		self->_Init();
69 	} catch (...) {
70 		delete self;
71 		throw;
72 	}
73 
74 	return self;
75 }
76 
77 
78 void
79 TeamsWindow::Zoom(BPoint, float, float)
80 {
81 	BSize preferredSize = fTeamsListView->PreferredSize();
82 	ResizeBy(preferredSize.Width() - Bounds().Width(),
83 		0.0);
84 
85 	// if the new size would extend us past the screen border,
86 	// move sufficiently to the left to bring us back within the bounds
87 	// + a bit of extra margin so we're not flush against the edge.
88 	BScreen screen;
89 	float offset = screen.Frame().right - Frame().right;
90 	if (offset < 0)
91 		MoveBy(offset - 5.0, 0.0);
92 }
93 
94 
95 void
96 TeamsWindow::MessageReceived(BMessage* message)
97 {
98 	switch (message->what) {
99 		case MSG_DEBUG_THIS_TEAM:
100 		{
101 			TeamRow* row = dynamic_cast<TeamRow*>(
102 				fTeamsListView->CurrentSelection());
103 			if (row != NULL) {
104 				BMessage message(MSG_DEBUG_THIS_TEAM);
105 				message.AddInt32("team", row->TeamID());
106 				message.AddPointer("interface", fTargetHostInterface);
107 				be_app_messenger.SendMessage(&message);
108 			}
109 			break;
110 		}
111 
112 		case MSG_TEAM_SELECTION_CHANGED:
113 		{
114 			TeamRow* row = dynamic_cast<TeamRow*>(
115 				fTeamsListView->CurrentSelection());
116 			bool enabled = false;
117 			if (row != NULL) {
118 				team_id id = row->TeamID();
119 				if (id != fCurrentTeam && id != B_SYSTEM_TEAM)
120 					enabled = true;
121 			}
122 
123 			fAttachTeamButton->SetEnabled(enabled);
124 			break;
125 		}
126 
127 		case MSG_SHOW_START_TEAM_WINDOW:
128 		{
129 			BMessage startMessage(*message);
130 			startMessage.AddPointer("interface", fTargetHostInterface);
131 			be_app_messenger.SendMessage(&startMessage);
132 			break;
133 		}
134 
135 		case MSG_CHOSE_CORE_FILE:
136 		case B_CANCEL:
137 		{
138 			delete fCoreSelectionPanel;
139 			fCoreSelectionPanel = NULL;
140 			if (message->what == B_CANCEL)
141 				break;
142 
143 			entry_ref ref;
144 			if (message->FindRef("refs", &ref) != B_OK)
145 				break;
146 
147 			BMessage coreMessage(MSG_LOAD_CORE_TEAM);
148 			coreMessage.AddPointer("interface", fTargetHostInterface);
149 			coreMessage.AddRef("core", &ref);
150 			be_app_messenger.SendMessage(&coreMessage);
151 			break;
152 		}
153 
154 		case MSG_LOAD_CORE_TEAM:
155 		{
156 			try {
157 				BMessenger messenger(this);
158 				fCoreSelectionPanel = new BFilePanel(B_OPEN_PANEL, &messenger,
159 					NULL, 0, false, new BMessage(MSG_CHOSE_CORE_FILE));
160 				fCoreSelectionPanel->Show();
161 			} catch (...) {
162 				delete fCoreSelectionPanel;
163 				fCoreSelectionPanel = NULL;
164 			}
165 			break;
166 		}
167 
168 		default:
169 			BWindow::MessageReceived(message);
170 			break;
171 	}
172 }
173 
174 
175 bool
176 TeamsWindow::QuitRequested()
177 {
178 	_SaveSettings();
179 
180 	be_app_messenger.SendMessage(MSG_TEAMS_WINDOW_CLOSED);
181 	return true;
182 }
183 
184 
185 // #pragma mark --
186 
187 
188 void
189 TeamsWindow::_Init()
190 {
191 	BMessage settings;
192 	_LoadSettings(settings);
193 
194 	fTargetHostInterface = TargetHostInterfaceRoster::Default()
195 		->ActiveInterfaceAt(0);
196 
197 	BRect frame;
198 	if (settings.FindRect("teams window frame", &frame) == B_OK) {
199 		MoveTo(frame.LeftTop());
200 		ResizeTo(frame.Width(), frame.Height());
201 	}
202 
203 	BLayoutBuilder::Group<>(this, B_VERTICAL)
204 		.Add(fTeamsListView = new TeamsListView("TeamsList", fCurrentTeam,
205 			fTargetHostInterface))
206 		.SetInsets(1.0f, 1.0f, 1.0f, 5.0f)
207 		.AddGroup(B_HORIZONTAL)
208 			.SetInsets(B_USE_DEFAULT_SPACING)
209 			.Add(fAttachTeamButton = new BButton("Attach", new BMessage(
210 						MSG_DEBUG_THIS_TEAM)))
211 			.AddGlue()
212 			.Add(fCreateTeamButton = new BButton("Start new team"
213 					B_UTF8_ELLIPSIS, new BMessage(MSG_SHOW_START_TEAM_WINDOW)))
214 			.Add(fLoadCoreButton = new BButton("Load core" B_UTF8_ELLIPSIS,
215 					new BMessage(MSG_LOAD_CORE_TEAM)))
216 			.End()
217 		.End();
218 
219 	fTeamsListView->SetInvocationMessage(new BMessage(MSG_DEBUG_THIS_TEAM));
220 	fTeamsListView->SetSelectionMessage(new BMessage(
221 			MSG_TEAM_SELECTION_CHANGED));
222 
223 	fAttachTeamButton->SetEnabled(false);
224 	fCreateTeamButton->SetTarget(this);
225 	fLoadCoreButton->SetTarget(this);
226 }
227 
228 
229 status_t
230 TeamsWindow::_OpenSettings(BFile& file, uint32 mode)
231 {
232 	BPath path;
233 	if (find_directory(B_USER_SETTINGS_DIRECTORY, &path) != B_OK)
234 		return B_ERROR;
235 
236 	path.Append("Debugger settings");
237 
238 	return file.SetTo(path.Path(), mode);
239 }
240 
241 
242 status_t
243 TeamsWindow::_LoadSettings(BMessage& settings)
244 {
245 	BFile file;
246 	status_t status = _OpenSettings(file, B_READ_ONLY);
247 	if (status < B_OK)
248 		return status;
249 
250 	return settings.Unflatten(&file);
251 }
252 
253 
254 status_t
255 TeamsWindow::_SaveSettings()
256 {
257 	BFile file;
258 	status_t status = _OpenSettings(file,
259 		B_WRITE_ONLY | B_CREATE_FILE | B_ERASE_FILE);
260 
261 	if (status < B_OK)
262 		return status;
263 
264 	BMessage settings('hdbg');
265 	status = settings.AddRect("teams window frame", Frame());
266 	if (status != B_OK)
267 		return status;
268 
269 	if (status == B_OK)
270 		status = settings.Flatten(&file);
271 
272 	return status;
273 }
274