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