Debugger: Further work on memory leak hunting.
[haiku.git] / src / apps / debugger / user_interface / gui / team_window / BreakpointsView.cpp
blobd061ac04d997304be5c94d6cb59931f750993b04
1 /*
2 * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
3 * Copyright 2011-2016, Rene Gollent, rene@gollent.com.
4 * Distributed under the terms of the MIT License.
5 */
8 #include "BreakpointsView.h"
10 #include <new>
12 #include <Button.h>
13 #include <CheckBox.h>
14 #include <LayoutBuilder.h>
16 #include <AutoLocker.h>
17 #include <ObjectList.h>
19 #include "AppMessageCodes.h"
20 #include "MessageCodes.h"
21 #include "Team.h"
22 #include "UserBreakpoint.h"
25 // #pragma mark - BreakpointsView
28 BreakpointsView::BreakpointsView(Team* team, Listener* listener)
30 BGroupView(B_HORIZONTAL, 4.0f),
31 fTeam(team),
32 fListView(NULL),
33 fToggleBreakpointButton(NULL),
34 fEditBreakpointButton(NULL),
35 fRemoveBreakpointButton(NULL),
36 fListener(listener)
38 SetName("Breakpoints");
42 BreakpointsView::~BreakpointsView()
44 if (fListView != NULL)
45 fListView->UnsetListener();
49 /*static*/ BreakpointsView*
50 BreakpointsView::Create(Team* team, Listener* listener)
52 BreakpointsView* self = new BreakpointsView(team, listener);
54 try {
55 self->_Init();
56 } catch (...) {
57 delete self;
58 throw;
61 return self;
65 void
66 BreakpointsView::UnsetListener()
68 fListener = NULL;
72 void
73 BreakpointsView::UserBreakpointChanged(UserBreakpoint* breakpoint)
75 fListView->UserBreakpointChanged(breakpoint);
77 _UpdateButtons();
81 void
82 BreakpointsView::WatchpointChanged(Watchpoint* watchpoint)
84 fListView->WatchpointChanged(watchpoint);
86 _UpdateButtons();
90 void
91 BreakpointsView::MessageReceived(BMessage* message)
93 switch (message->what) {
94 case MSG_ENABLE_BREAKPOINT:
95 case MSG_DISABLE_BREAKPOINT:
96 case MSG_CLEAR_BREAKPOINT:
97 _HandleBreakpointAction(message->what);
98 break;
100 case MSG_SHOW_BREAKPOINT_EDIT_WINDOW:
101 message->AddPointer("breakpoint",
102 fSelectedBreakpoints.ItemAt(0)->GetBreakpoint());
103 Window()->PostMessage(message);
104 break;
106 default:
107 BGroupView::MessageReceived(message);
108 break;
113 void
114 BreakpointsView::AttachedToWindow()
116 fEditBreakpointButton->SetTarget(this);
117 fToggleBreakpointButton->SetTarget(this);
118 fRemoveBreakpointButton->SetTarget(this);
122 void
123 BreakpointsView::LoadSettings(const BMessage& settings)
125 BMessage breakpointListSettings;
126 if (settings.FindMessage("breakpointList", &breakpointListSettings)
127 == B_OK)
128 fListView->LoadSettings(breakpointListSettings);
132 status_t
133 BreakpointsView::SaveSettings(BMessage& settings)
135 BMessage breakpointListSettings;
136 if (fListView->SaveSettings(breakpointListSettings) != B_OK)
137 return B_NO_MEMORY;
139 if (settings.AddMessage("breakpointList", &breakpointListSettings) != B_OK)
140 return B_NO_MEMORY;
142 return B_OK;
146 void
147 BreakpointsView::BreakpointSelectionChanged(BreakpointProxyList& proxies)
149 if (fListener != NULL)
150 fListener->BreakpointSelectionChanged(proxies);
152 _SetSelection(proxies);
156 void
157 BreakpointsView::_Init()
159 BLayoutBuilder::Group<>(this, B_VERTICAL, 0.0f)
160 .Add(fListView = BreakpointListView::Create(fTeam, this, this))
161 .AddGroup(B_HORIZONTAL, B_USE_SMALL_SPACING)
162 .SetInsets(B_USE_SMALL_SPACING)
163 .AddGlue()
164 .Add(fRemoveBreakpointButton = new BButton("Remove"))
165 .Add(fEditBreakpointButton = new BButton("Edit" B_UTF8_ELLIPSIS))
166 .Add(fToggleBreakpointButton = new BButton("Toggle"))
167 .End();
169 fToggleBreakpointButton->SetMessage(new BMessage(MSG_ENABLE_BREAKPOINT));
170 fRemoveBreakpointButton->SetMessage(new BMessage(MSG_CLEAR_BREAKPOINT));
171 fEditBreakpointButton->SetMessage(
172 new BMessage(MSG_SHOW_BREAKPOINT_EDIT_WINDOW));
174 _UpdateButtons();
178 void
179 BreakpointsView::_UpdateButtons()
181 AutoLocker<Team> teamLocker(fTeam);
183 bool hasEnabled = false;
184 bool hasDisabled = false;
185 bool valid = false;
187 for (int32 i = 0; i < fSelectedBreakpoints.CountItems(); i++) {
188 BreakpointProxy* proxy = fSelectedBreakpoints.ItemAt(i);
189 switch (proxy->Type()) {
190 case BREAKPOINT_PROXY_TYPE_BREAKPOINT:
192 UserBreakpoint* breakpoint = proxy->GetBreakpoint();
193 if (breakpoint->IsValid()) {
194 valid = true;
195 if (breakpoint->IsEnabled())
196 hasEnabled = true;
197 else
198 hasDisabled = true;
201 break;
203 case BREAKPOINT_PROXY_TYPE_WATCHPOINT:
205 Watchpoint* watchpoint = proxy->GetWatchpoint();
206 valid = true;
207 if (watchpoint->IsEnabled())
208 hasEnabled = true;
209 else
210 hasDisabled = true;
211 break;
213 default:
214 break;
218 if (valid) {
219 // only allow condition editing if we have a single
220 // actual breakpoint selected.
221 // TODO: allow using this to modify watchpoints as
222 // well.
223 if (fSelectedBreakpoints.CountItems() == 1
224 && fSelectedBreakpoints.ItemAt(0)->Type()
225 == BREAKPOINT_PROXY_TYPE_BREAKPOINT) {
226 fEditBreakpointButton->SetEnabled(true);
227 } else
228 fEditBreakpointButton->SetEnabled(false);
230 // if we have at least one disabled breakpoint in the
231 // selection, we leave the button as an Enable button
232 if (hasEnabled && !hasDisabled) {
233 fToggleBreakpointButton->SetLabel("Disable");
234 fToggleBreakpointButton->SetMessage(
235 new BMessage(MSG_DISABLE_BREAKPOINT));
236 } else {
237 fToggleBreakpointButton->SetLabel("Enable");
238 fToggleBreakpointButton->SetMessage(
239 new BMessage(MSG_ENABLE_BREAKPOINT));
242 fToggleBreakpointButton->SetEnabled(true);
243 fRemoveBreakpointButton->SetEnabled(true);
244 } else {
245 fToggleBreakpointButton->SetLabel("Enable");
246 fToggleBreakpointButton->SetEnabled(false);
247 fEditBreakpointButton->SetEnabled(false);
248 fRemoveBreakpointButton->SetEnabled(false);
253 void
254 BreakpointsView::_SetSelection(BreakpointProxyList& proxies)
256 for (int32 i = 0; i < fSelectedBreakpoints.CountItems(); i++)
257 fSelectedBreakpoints.ItemAt(i)->ReleaseReference();
259 fSelectedBreakpoints.MakeEmpty();
261 for (int32 i = 0; i < proxies.CountItems(); i++) {
262 BreakpointProxy* proxy = proxies.ItemAt(i);
263 if (!fSelectedBreakpoints.AddItem(proxy))
264 return;
265 proxy->AcquireReference();
268 _UpdateButtons();
272 void
273 BreakpointsView::_HandleBreakpointAction(uint32 action)
275 if (fListener == NULL)
276 return;
278 for (int32 i = 0; i < fSelectedBreakpoints.CountItems(); i++) {
279 BreakpointProxy* proxy = fSelectedBreakpoints.ItemAt(i);
280 if (proxy->Type() == BREAKPOINT_PROXY_TYPE_BREAKPOINT) {
281 UserBreakpoint* breakpoint = proxy->GetBreakpoint();
282 if (action == MSG_ENABLE_BREAKPOINT && !breakpoint->IsEnabled())
283 fListener->SetBreakpointEnabledRequested(breakpoint, true);
284 else if (action == MSG_DISABLE_BREAKPOINT
285 && breakpoint->IsEnabled()) {
286 fListener->SetBreakpointEnabledRequested(breakpoint, false);
287 } else if (action == MSG_CLEAR_BREAKPOINT)
288 fListener->ClearBreakpointRequested(breakpoint);
289 } else {
290 Watchpoint* watchpoint = proxy->GetWatchpoint();
291 if (action == MSG_ENABLE_BREAKPOINT && !watchpoint->IsEnabled())
292 fListener->SetWatchpointEnabledRequested(watchpoint, true);
293 else if (action == MSG_DISABLE_BREAKPOINT
294 && watchpoint->IsEnabled()) {
295 fListener->SetWatchpointEnabledRequested(watchpoint, false);
296 } else if (action == MSG_CLEAR_BREAKPOINT)
297 fListener->ClearWatchpointRequested(watchpoint);
303 // #pragma mark - Listener
306 BreakpointsView::Listener::~Listener()