/* * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de. * Copyright 2011-2016, Rene Gollent, rene@gollent.com. * Distributed under the terms of the MIT License. */ #include "BreakpointsView.h" #include #include #include #include #include #include #include "AppMessageCodes.h" #include "MessageCodes.h" #include "Team.h" #include "UserBreakpoint.h" // #pragma mark - BreakpointsView BreakpointsView::BreakpointsView(Team* team, Listener* listener) : BGroupView(B_HORIZONTAL, 4.0f), fTeam(team), fListView(NULL), fToggleBreakpointButton(NULL), fEditBreakpointButton(NULL), fRemoveBreakpointButton(NULL), fListener(listener) { SetName("Breakpoints"); } BreakpointsView::~BreakpointsView() { if (fListView != NULL) fListView->UnsetListener(); } /*static*/ BreakpointsView* BreakpointsView::Create(Team* team, Listener* listener) { BreakpointsView* self = new BreakpointsView(team, listener); try { self->_Init(); } catch (...) { delete self; throw; } return self; } void BreakpointsView::UnsetListener() { fListener = NULL; } void BreakpointsView::UserBreakpointChanged(UserBreakpoint* breakpoint) { fListView->UserBreakpointChanged(breakpoint); _UpdateButtons(); } void BreakpointsView::WatchpointChanged(Watchpoint* watchpoint) { fListView->WatchpointChanged(watchpoint); _UpdateButtons(); } void BreakpointsView::MessageReceived(BMessage* message) { switch (message->what) { case MSG_ENABLE_BREAKPOINT: case MSG_DISABLE_BREAKPOINT: case MSG_CLEAR_BREAKPOINT: _HandleBreakpointAction(message->what); break; case MSG_SHOW_BREAKPOINT_EDIT_WINDOW: message->AddPointer("breakpoint", fSelectedBreakpoints.ItemAt(0)->GetBreakpoint()); Window()->PostMessage(message); break; default: BGroupView::MessageReceived(message); break; } } void BreakpointsView::AttachedToWindow() { fEditBreakpointButton->SetTarget(this); fToggleBreakpointButton->SetTarget(this); fRemoveBreakpointButton->SetTarget(this); } void BreakpointsView::LoadSettings(const BMessage& settings) { BMessage breakpointListSettings; if (settings.FindMessage("breakpointList", &breakpointListSettings) == B_OK) fListView->LoadSettings(breakpointListSettings); } status_t BreakpointsView::SaveSettings(BMessage& settings) { BMessage breakpointListSettings; if (fListView->SaveSettings(breakpointListSettings) != B_OK) return B_NO_MEMORY; if (settings.AddMessage("breakpointList", &breakpointListSettings) != B_OK) return B_NO_MEMORY; return B_OK; } void BreakpointsView::BreakpointSelectionChanged(BreakpointProxyList& proxies) { if (fListener != NULL) fListener->BreakpointSelectionChanged(proxies); _SetSelection(proxies); } void BreakpointsView::_Init() { BLayoutBuilder::Group<>(this, B_VERTICAL, 0.0f) .Add(fListView = BreakpointListView::Create(fTeam, this, this)) .AddGroup(B_HORIZONTAL, B_USE_SMALL_SPACING) .SetInsets(B_USE_SMALL_SPACING) .AddGlue() .Add(fRemoveBreakpointButton = new BButton("Remove")) .Add(fEditBreakpointButton = new BButton("Edit" B_UTF8_ELLIPSIS)) .Add(fToggleBreakpointButton = new BButton("Toggle")) .End(); fToggleBreakpointButton->SetMessage(new BMessage(MSG_ENABLE_BREAKPOINT)); fRemoveBreakpointButton->SetMessage(new BMessage(MSG_CLEAR_BREAKPOINT)); fEditBreakpointButton->SetMessage( new BMessage(MSG_SHOW_BREAKPOINT_EDIT_WINDOW)); _UpdateButtons(); } void BreakpointsView::_UpdateButtons() { AutoLocker teamLocker(fTeam); bool hasEnabled = false; bool hasDisabled = false; bool valid = false; for (int32 i = 0; i < fSelectedBreakpoints.CountItems(); i++) { BreakpointProxy* proxy = fSelectedBreakpoints.ItemAt(i); switch (proxy->Type()) { case BREAKPOINT_PROXY_TYPE_BREAKPOINT: { UserBreakpoint* breakpoint = proxy->GetBreakpoint(); if (breakpoint->IsValid()) { valid = true; if (breakpoint->IsEnabled()) hasEnabled = true; else hasDisabled = true; } break; } case BREAKPOINT_PROXY_TYPE_WATCHPOINT: { Watchpoint* watchpoint = proxy->GetWatchpoint(); valid = true; if (watchpoint->IsEnabled()) hasEnabled = true; else hasDisabled = true; break; } default: break; } } if (valid) { // only allow condition editing if we have a single // actual breakpoint selected. // TODO: allow using this to modify watchpoints as // well. if (fSelectedBreakpoints.CountItems() == 1 && fSelectedBreakpoints.ItemAt(0)->Type() == BREAKPOINT_PROXY_TYPE_BREAKPOINT) { fEditBreakpointButton->SetEnabled(true); } else fEditBreakpointButton->SetEnabled(false); // if we have at least one disabled breakpoint in the // selection, we leave the button as an Enable button if (hasEnabled && !hasDisabled) { fToggleBreakpointButton->SetLabel("Disable"); fToggleBreakpointButton->SetMessage( new BMessage(MSG_DISABLE_BREAKPOINT)); } else { fToggleBreakpointButton->SetLabel("Enable"); fToggleBreakpointButton->SetMessage( new BMessage(MSG_ENABLE_BREAKPOINT)); } fToggleBreakpointButton->SetEnabled(true); fRemoveBreakpointButton->SetEnabled(true); } else { fToggleBreakpointButton->SetLabel("Enable"); fToggleBreakpointButton->SetEnabled(false); fEditBreakpointButton->SetEnabled(false); fRemoveBreakpointButton->SetEnabled(false); } } void BreakpointsView::_SetSelection(BreakpointProxyList& proxies) { for (int32 i = 0; i < fSelectedBreakpoints.CountItems(); i++) fSelectedBreakpoints.ItemAt(i)->ReleaseReference(); fSelectedBreakpoints.MakeEmpty(); for (int32 i = 0; i < proxies.CountItems(); i++) { BreakpointProxy* proxy = proxies.ItemAt(i); if (!fSelectedBreakpoints.AddItem(proxy)) return; proxy->AcquireReference(); } _UpdateButtons(); } void BreakpointsView::_HandleBreakpointAction(uint32 action) { if (fListener == NULL) return; for (int32 i = 0; i < fSelectedBreakpoints.CountItems(); i++) { BreakpointProxy* proxy = fSelectedBreakpoints.ItemAt(i); if (proxy->Type() == BREAKPOINT_PROXY_TYPE_BREAKPOINT) { UserBreakpoint* breakpoint = proxy->GetBreakpoint(); if (action == MSG_ENABLE_BREAKPOINT && !breakpoint->IsEnabled()) fListener->SetBreakpointEnabledRequested(breakpoint, true); else if (action == MSG_DISABLE_BREAKPOINT && breakpoint->IsEnabled()) { fListener->SetBreakpointEnabledRequested(breakpoint, false); } else if (action == MSG_CLEAR_BREAKPOINT) fListener->ClearBreakpointRequested(breakpoint); } else { Watchpoint* watchpoint = proxy->GetWatchpoint(); if (action == MSG_ENABLE_BREAKPOINT && !watchpoint->IsEnabled()) fListener->SetWatchpointEnabledRequested(watchpoint, true); else if (action == MSG_DISABLE_BREAKPOINT && watchpoint->IsEnabled()) { fListener->SetWatchpointEnabledRequested(watchpoint, false); } else if (action == MSG_CLEAR_BREAKPOINT) fListener->ClearWatchpointRequested(watchpoint); } } } // #pragma mark - Listener BreakpointsView::Listener::~Listener() { }