xref: /haiku/src/apps/debugger/user_interface/gui/team_window/BreakpointsView.cpp (revision 579f1dbca962a2a03df54f69fdc6e9423f91f20e)
1 /*
2  * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
3  * Copyright 2011-2013, Rene Gollent, rene@gollent.com.
4  * Distributed under the terms of the MIT License.
5  */
6 
7 
8 #include "BreakpointsView.h"
9 
10 #include <new>
11 
12 #include <Button.h>
13 #include <CheckBox.h>
14 #include <LayoutBuilder.h>
15 
16 #include <AutoLocker.h>
17 #include <ObjectList.h>
18 
19 #include "MessageCodes.h"
20 #include "Team.h"
21 #include "UserBreakpoint.h"
22 
23 
24 // #pragma mark - BreakpointsView
25 
26 
27 BreakpointsView::BreakpointsView(Team* team, Listener* listener)
28 	:
29 	BGroupView(B_HORIZONTAL, 4.0f),
30 	fTeam(team),
31 	fListView(NULL),
32 	fConfigureExceptionsButton(NULL),
33 	fToggleBreakpointButton(NULL),
34 	fRemoveBreakpointButton(NULL),
35 	fListener(listener)
36 {
37 	SetName("Breakpoints");
38 }
39 
40 
41 BreakpointsView::~BreakpointsView()
42 {
43 	if (fListView != NULL)
44 		fListView->UnsetListener();
45 }
46 
47 
48 /*static*/ BreakpointsView*
49 BreakpointsView::Create(Team* team, Listener* listener)
50 {
51 	BreakpointsView* self = new BreakpointsView(team, listener);
52 
53 	try {
54 		self->_Init();
55 	} catch (...) {
56 		delete self;
57 		throw;
58 	}
59 
60 	return self;
61 }
62 
63 
64 void
65 BreakpointsView::UnsetListener()
66 {
67 	fListener = NULL;
68 }
69 
70 
71 void
72 BreakpointsView::UserBreakpointChanged(UserBreakpoint* breakpoint)
73 {
74 	fListView->UserBreakpointChanged(breakpoint);
75 
76 	_UpdateButtons();
77 }
78 
79 
80 void
81 BreakpointsView::WatchpointChanged(Watchpoint* watchpoint)
82 {
83 	fListView->WatchpointChanged(watchpoint);
84 
85 	_UpdateButtons();
86 }
87 
88 
89 void
90 BreakpointsView::MessageReceived(BMessage* message)
91 {
92 	switch (message->what) {
93 		case MSG_ENABLE_BREAKPOINT:
94 		case MSG_DISABLE_BREAKPOINT:
95 		case MSG_CLEAR_BREAKPOINT:
96 			_HandleBreakpointAction(message->what);
97 			break;
98 
99 			BGroupView::MessageReceived(message);
100 			break;
101 	}
102 }
103 
104 
105 void
106 BreakpointsView::AttachedToWindow()
107 {
108 	fConfigureExceptionsButton->SetTarget(Window());
109 	fToggleBreakpointButton->SetTarget(this);
110 	fRemoveBreakpointButton->SetTarget(this);
111 }
112 
113 
114 void
115 BreakpointsView::LoadSettings(const BMessage& settings)
116 {
117 	BMessage breakpointListSettings;
118 	if (settings.FindMessage("breakpointList", &breakpointListSettings)
119 		== B_OK)
120 		fListView->LoadSettings(breakpointListSettings);
121 }
122 
123 
124 status_t
125 BreakpointsView::SaveSettings(BMessage& settings)
126 {
127 	BMessage breakpointListSettings;
128 	if (fListView->SaveSettings(breakpointListSettings) != B_OK)
129 		return B_NO_MEMORY;
130 
131 	if (settings.AddMessage("breakpointList", &breakpointListSettings) != B_OK)
132 		return B_NO_MEMORY;
133 
134 	return B_OK;
135 }
136 
137 
138 void
139 BreakpointsView::BreakpointSelectionChanged(BreakpointProxyList& proxies)
140 {
141 	if (fListener != NULL)
142 		fListener->BreakpointSelectionChanged(proxies);
143 
144 	_SetSelection(proxies);
145 }
146 
147 
148 void
149 BreakpointsView::_Init()
150 {
151 	BLayoutBuilder::Group<>(this, B_VERTICAL, 0.0f)
152 		.Add(fListView = BreakpointListView::Create(fTeam, this, this))
153 		.AddGroup(B_HORIZONTAL, B_USE_SMALL_SPACING)
154 			.SetInsets(B_USE_SMALL_SPACING)
155 			.AddGlue()
156 			.Add(fConfigureExceptionsButton = new BButton(
157 				"Configure break conditions" B_UTF8_ELLIPSIS))
158 			.Add(fRemoveBreakpointButton = new BButton("Remove"))
159 			.Add(fToggleBreakpointButton = new BButton("Toggle"))
160 		.End();
161 
162 	fConfigureExceptionsButton->SetMessage(
163 		new BMessage(MSG_SHOW_BREAK_CONDITION_CONFIG_WINDOW));
164 	fToggleBreakpointButton->SetMessage(new BMessage(MSG_ENABLE_BREAKPOINT));
165 	fRemoveBreakpointButton->SetMessage(new BMessage(MSG_CLEAR_BREAKPOINT));
166 
167 	_UpdateButtons();
168 }
169 
170 
171 void
172 BreakpointsView::_UpdateButtons()
173 {
174 	AutoLocker<Team> teamLocker(fTeam);
175 
176 	bool hasEnabled = false;
177 	bool hasDisabled = false;
178 	bool valid = false;
179 
180 	for (int32 i = 0; i < fSelectedBreakpoints.CountItems(); i++) {
181 		BreakpointProxy* proxy = fSelectedBreakpoints.ItemAt(i);
182 		switch (proxy->Type()) {
183 			case BREAKPOINT_PROXY_TYPE_BREAKPOINT:
184 			{
185 				UserBreakpoint* breakpoint = proxy->GetBreakpoint();
186 				if (breakpoint->IsValid()) {
187 					valid = true;
188 					if (breakpoint->IsEnabled())
189 						hasEnabled = true;
190 					else
191 						hasDisabled = true;
192 				}
193 				break;
194 			}
195 			case BREAKPOINT_PROXY_TYPE_WATCHPOINT:
196 			{
197 				Watchpoint* watchpoint = proxy->GetWatchpoint();
198 				valid = true;
199 				if (watchpoint->IsEnabled())
200 					hasEnabled = true;
201 				else
202 					hasDisabled = true;
203 				break;
204 			}
205 			default:
206 				break;
207 		}
208 	}
209 
210 	if (valid) {
211 		// if we have at least one disabled breakpoint in the
212 		// selection, we leave the button as an Enable button
213 		if (hasEnabled && !hasDisabled) {
214 			fToggleBreakpointButton->SetLabel("Disable");
215 			fToggleBreakpointButton->SetMessage(
216 				new BMessage(MSG_DISABLE_BREAKPOINT));
217 		} else {
218 			fToggleBreakpointButton->SetLabel("Enable");
219 			fToggleBreakpointButton->SetMessage(
220 				new BMessage(MSG_ENABLE_BREAKPOINT));
221 		}
222 
223 		fToggleBreakpointButton->SetEnabled(true);
224 		fRemoveBreakpointButton->SetEnabled(true);
225 	} else {
226 		fToggleBreakpointButton->SetLabel("Enable");
227 		fToggleBreakpointButton->SetEnabled(false);
228 		fRemoveBreakpointButton->SetEnabled(false);
229 	}
230 }
231 
232 
233 void
234 BreakpointsView::_SetSelection(BreakpointProxyList& proxies)
235 {
236 	for (int32 i = 0; i < fSelectedBreakpoints.CountItems(); i++)
237 		fSelectedBreakpoints.ItemAt(i)->ReleaseReference();
238 
239 	fSelectedBreakpoints.MakeEmpty();
240 
241 	for (int32 i = 0; i < proxies.CountItems(); i++) {
242 		BreakpointProxy* proxy = proxies.ItemAt(i);
243 		if (!fSelectedBreakpoints.AddItem(proxy))
244 			return;
245 		proxy->AcquireReference();
246 	}
247 
248 	_UpdateButtons();
249 }
250 
251 
252 void
253 BreakpointsView::_HandleBreakpointAction(uint32 action)
254 {
255 	if (fListener == NULL)
256 		return;
257 
258 	for (int32 i = 0; i < fSelectedBreakpoints.CountItems(); i++) {
259 		BreakpointProxy* proxy = fSelectedBreakpoints.ItemAt(i);
260 		if (proxy->Type() == BREAKPOINT_PROXY_TYPE_BREAKPOINT) {
261 			UserBreakpoint* breakpoint = proxy->GetBreakpoint();
262 			if (action == MSG_ENABLE_BREAKPOINT && !breakpoint->IsEnabled())
263 				fListener->SetBreakpointEnabledRequested(breakpoint, true);
264 			else if (action == MSG_DISABLE_BREAKPOINT
265 				&& breakpoint->IsEnabled()) {
266 				fListener->SetBreakpointEnabledRequested(breakpoint, false);
267 			} else if (action == MSG_CLEAR_BREAKPOINT)
268 				fListener->ClearBreakpointRequested(breakpoint);
269 		} else {
270 			Watchpoint* watchpoint = proxy->GetWatchpoint();
271 			if (action == MSG_ENABLE_BREAKPOINT && !watchpoint->IsEnabled())
272 				fListener->SetWatchpointEnabledRequested(watchpoint, true);
273 			else if (action == MSG_DISABLE_BREAKPOINT
274 				&& watchpoint->IsEnabled()) {
275 				fListener->SetWatchpointEnabledRequested(watchpoint, false);
276 			} else if (action == MSG_CLEAR_BREAKPOINT)
277 				fListener->ClearWatchpointRequested(watchpoint);
278 		}
279 	}
280 }
281 
282 
283 // #pragma mark - Listener
284 
285 
286 BreakpointsView::Listener::~Listener()
287 {
288 }
289