diff --git a/src/apps/debugger/user_interface/gui/team_window/BreakpointListView.cpp b/src/apps/debugger/user_interface/gui/team_window/BreakpointListView.cpp index b1698c8f41..8c6ba03cc8 100644 --- a/src/apps/debugger/user_interface/gui/team_window/BreakpointListView.cpp +++ b/src/apps/debugger/user_interface/gui/team_window/BreakpointListView.cpp @@ -1,6 +1,6 @@ /* * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de. - * Copyright 2011, Rene Gollent, rene@gollent.com. + * Copyright 2011-2013, Rene Gollent, rene@gollent.com. * Distributed under the terms of the MIT License. */ @@ -11,12 +11,16 @@ #include +#include + #include #include +#include "Architecture.h" #include "FunctionID.h" #include "GuiSettingsUtils.h" #include "LocatableFile.h" +#include "MessageCodes.h" #include "table/TableColumns.h" #include "TargetAddressTableColumn.h" #include "Team.h" @@ -24,6 +28,73 @@ #include "Watchpoint.h" +// #pragma mark - BreakpointProxy + + +BreakpointProxy::BreakpointProxy(UserBreakpoint* breakpoint, + Watchpoint* watchpoint) + : + fBreakpoint(breakpoint), + fWatchpoint(watchpoint) +{ + if (fBreakpoint != NULL) + fBreakpoint->AcquireReference(); + + if (fWatchpoint != NULL) + fWatchpoint->AcquireReference(); +} + + +BreakpointProxy::~BreakpointProxy() +{ + if (fBreakpoint != NULL) + fBreakpoint->ReleaseReference(); + + if (fWatchpoint != NULL) + fWatchpoint->ReleaseReference(); +} + + +breakpoint_proxy_type +BreakpointProxy::Type() const +{ + return fBreakpoint != NULL ? BREAKPOINT_PROXY_TYPE_BREAKPOINT + : BREAKPOINT_PROXY_TYPE_WATCHPOINT; +} + + +// #pragma mark - ListInputFilter + + +class BreakpointListView::ListInputFilter : public BMessageFilter { +public: + ListInputFilter(BView* view) + : + BMessageFilter(B_ANY_DELIVERY, B_ANY_SOURCE, B_KEY_DOWN), + fTargetView(view) + { + } + + ~ListInputFilter() + { + } + + filter_result Filter(BMessage* message, BHandler** target) + { + const char* bytes; + if (message->FindString("bytes", &bytes) == B_OK + && bytes[0] == B_DELETE) { + BMessenger(fTargetView).SendMessage(MSG_CLEAR_BREAKPOINT); + } + + return B_DISPATCH_MESSAGE; + } + +private: + BView* fTargetView; +}; + + // #pragma mark - BreakpointsTableModel @@ -34,25 +105,23 @@ public: fTeam(team) { UpdateBreakpoint(NULL); - UpdateWatchpoint(NULL); } ~BreakpointsTableModel() { fTeam = NULL; UpdateBreakpoint(NULL); - UpdateWatchpoint(NULL); } - bool UpdateBreakpoint(UserBreakpoint* changedBreakpoint) + bool UpdateBreakpoint(BreakpointProxy* proxy) { if (fTeam == NULL) { for (int32 i = 0; - UserBreakpoint* breakpoint = fBreakpoints.ItemAt(i); + BreakpointProxy* proxy = fBreakpointProxies.ItemAt(i); i++) { - breakpoint->ReleaseReference(); + proxy->ReleaseReference(); } - fBreakpoints.MakeEmpty(); + fBreakpointProxies.MakeEmpty(); return true; } @@ -61,132 +130,126 @@ public: UserBreakpointList::ConstIterator it = fTeam->UserBreakpoints().GetIterator(); + int32 watchpointIndex = 0; UserBreakpoint* newBreakpoint = it.Next(); + Watchpoint* newWatchpoint = fTeam->WatchpointAt(watchpointIndex); int32 index = 0; + bool remove; // remove no longer existing breakpoints - while (UserBreakpoint* oldBreakpoint = fBreakpoints.ItemAt(index)) { - if (oldBreakpoint == newBreakpoint) { - if (oldBreakpoint == changedBreakpoint) - NotifyRowsChanged(index, 1); - index++; - newBreakpoint = it.Next(); - } else { + while (BreakpointProxy* oldProxy = fBreakpointProxies.ItemAt(index)) { + remove = false; + switch (oldProxy->Type()) { + case BREAKPOINT_PROXY_TYPE_BREAKPOINT: + { + UserBreakpoint* breakpoint = oldProxy->GetBreakpoint(); + if (breakpoint == newBreakpoint) { + if (breakpoint == proxy->GetBreakpoint()) + NotifyRowsChanged(index, 1); + ++index; + newBreakpoint = it.Next(); + } else + remove = true; + } + break; + + case BREAKPOINT_PROXY_TYPE_WATCHPOINT: + { + Watchpoint* watchpoint = oldProxy->GetWatchpoint(); + if (watchpoint == newWatchpoint) { + if (watchpoint == proxy->GetWatchpoint()) + NotifyRowsChanged(index, 1); + ++watchpointIndex; + ++index; + newWatchpoint = fTeam->WatchpointAt(watchpointIndex); + } else + remove = true; + } + break; + } + + if (remove) { // TODO: Not particularly efficient! - fBreakpoints.RemoveItemAt(index); - oldBreakpoint->ReleaseReference(); + fBreakpointProxies.RemoveItemAt(index); + oldProxy->ReleaseReference(); NotifyRowsRemoved(index, 1); } } // add new breakpoints - int32 countBefore = fBreakpoints.CountItems(); + int32 countBefore = fBreakpointProxies.CountItems(); + BreakpointProxy* newProxy = NULL; + BReference proxyReference; while (newBreakpoint != NULL) { - if (!fBreakpoints.AddItem(newBreakpoint)) + newProxy = new(std::nothrow) BreakpointProxy(newBreakpoint, NULL); + if (newProxy == NULL) return false; - newBreakpoint->AcquireReference(); + proxyReference.SetTo(newProxy, true); + if (!fBreakpointProxies.AddItem(newProxy)) + return false; + + proxyReference.Detach(); newBreakpoint = it.Next(); } - int32 count = fBreakpoints.CountItems(); + // add new watchpoints + while (newWatchpoint != NULL) { + newProxy = new(std::nothrow) BreakpointProxy(NULL, newWatchpoint); + if (newProxy == NULL) + return false; + + proxyReference.SetTo(newProxy, true); + if (!fBreakpointProxies.AddItem(newProxy)) + return false; + + proxyReference.Detach(); + newWatchpoint = fTeam->WatchpointAt(++watchpointIndex); + } + + + int32 count = fBreakpointProxies.CountItems(); if (count > countBefore) NotifyRowsAdded(countBefore, count - countBefore); return true; } - bool UpdateWatchpoint(Watchpoint* changedWatchpoint) - { - if (fTeam == NULL) { - for (int32 i = 0; - Watchpoint* watchpoint = fWatchpoints.ItemAt(i); - i++) { - watchpoint->ReleaseReference(); - } - fWatchpoints.MakeEmpty(); - - return true; - } - - AutoLocker locker(fTeam); - - int32 breakpointCount = fBreakpoints.CountItems(); - int32 index = 0; - int32 teamIndex = 0; - Watchpoint* newWatchpoint = fTeam->WatchpointAt(teamIndex); - // remove no longer existing breakpoints - while (Watchpoint* oldWatchpoint = fWatchpoints.ItemAt(index)) { - if (oldWatchpoint == newWatchpoint) { - if (oldWatchpoint == changedWatchpoint) - NotifyRowsChanged(index + breakpointCount, 1); - index++; - teamIndex++; - newWatchpoint = fTeam->WatchpointAt(teamIndex); - } else { - // TODO: Not particularly efficient! - fWatchpoints.RemoveItemAt(index); - oldWatchpoint->ReleaseReference(); - NotifyRowsRemoved(index + breakpointCount, 1); - } - } - - // add new breakpoints - int32 countBefore = fWatchpoints.CountItems(); - while (newWatchpoint != NULL) { - if (!fWatchpoints.AddItem(newWatchpoint)) - return false; - - newWatchpoint->AcquireReference(); - teamIndex++; - newWatchpoint = fTeam->WatchpointAt(teamIndex); - } - - int32 count = fWatchpoints.CountItems(); - if (count > countBefore) - NotifyRowsAdded(countBefore + breakpointCount, count - countBefore); - - return true; - } - virtual int32 CountColumns() const { - return 5; + return 3; } virtual int32 CountRows() const { - return fBreakpoints.CountItems() + fWatchpoints.CountItems(); + return fBreakpointProxies.CountItems(); } virtual bool GetValueAt(int32 rowIndex, int32 columnIndex, BVariant& value) { - int32 breakpointCount = fBreakpoints.CountItems(); - if (rowIndex < breakpointCount) - return _GetBreakpointValueAt(rowIndex, columnIndex, value); + BreakpointProxy* proxy = fBreakpointProxies.ItemAt(rowIndex); + if (proxy == NULL) + return false; - return _GetWatchpointValueAt(rowIndex - breakpointCount, columnIndex, - value); + if (proxy->Type() == BREAKPOINT_PROXY_TYPE_BREAKPOINT) { + return _GetBreakpointValueAt(proxy->GetBreakpoint(), rowIndex, + columnIndex, value); + } + + return _GetWatchpointValueAt(proxy->GetWatchpoint(), rowIndex, + columnIndex, value); } - UserBreakpoint* BreakpointAt(int32 index) const + BreakpointProxy* BreakpointProxyAt(int32 index) const { - return fBreakpoints.ItemAt(index); - } - - Watchpoint* WatchpointAt(int32 index) const - { - return fWatchpoints.ItemAt(index - fBreakpoints.CountItems()); + return fBreakpointProxies.ItemAt(index); } private: - bool _GetBreakpointValueAt(int32 rowIndex, int32 columnIndex, - BVariant &value) + bool _GetBreakpointValueAt(UserBreakpoint* breakpoint, int32 rowIndex, + int32 columnIndex, BVariant &value) { - UserBreakpoint* breakpoint = fBreakpoints.ItemAt(rowIndex); - if (breakpoint == NULL) - return false; const UserBreakpointLocation& location = breakpoint->Location(); switch (columnIndex) { @@ -198,62 +261,75 @@ private: B_VARIANT_DONT_COPY_DATA); return true; case 2: - if (LocatableFile* sourceFile = location.SourceFile()) { - value.SetTo(sourceFile->Name(), B_VARIANT_DONT_COPY_DATA); - return true; - } - return false; - case 3: - if (location.SourceFile() != NULL) { - value.SetTo(location.GetSourceLocation().Line() + 1); - return true; - } - return false; - case 4: - if (location.SourceFile() == NULL) { + { + LocatableFile* sourceFile = location.SourceFile(); + if (sourceFile != NULL) { + BString data; + data.SetToFormat("%s:%" B_PRId32, sourceFile->Name(), + location.GetSourceLocation().Line() + 1); + value.SetTo(data); + } else { AutoLocker teamLocker(fTeam); if (UserBreakpointInstance* instance = breakpoint->InstanceAt(0)) { value.SetTo(instance->Address()); - return true; } } - return false; + return true; + } default: return false; } } - bool _GetWatchpointValueAt(int32 rowIndex, int32 columnIndex, - BVariant& value) + bool _GetWatchpointValueAt(Watchpoint* watchpoint, int32 rowIndex, + int32 columnIndex, BVariant &value) { - Watchpoint* watchpoint = fWatchpoints.ItemAt(rowIndex); - if (watchpoint == NULL) - return false; - switch (columnIndex) { case 0: value.SetTo((int32)watchpoint->IsEnabled()); return true; case 1: - value.SetTo("Watchpoint"); + { + BString data; + data.SetToFormat("%s at 0x%" B_PRIx64 " (%" B_PRId32 " bytes)", + _WatchpointTypeToString(watchpoint->Type()), + watchpoint->Address(), watchpoint->Length()); + value.SetTo(data); return true; + } case 2: + { return false; - case 3: - return false; - case 4: - value.SetTo(watchpoint->Address()); - return true; + } default: return false; } } + const char* _WatchpointTypeToString(uint32 type) const + { + switch (type) { + case WATCHPOINT_CAPABILITY_FLAG_READ: + { + return "read"; + } + case WATCHPOINT_CAPABILITY_FLAG_WRITE: + { + return "write"; + } + case WATCHPOINT_CAPABILITY_FLAG_READ_WRITE: + { + return "read/write"; + } + default: + return NULL; + } + } + private: Team* fTeam; - BObjectList fBreakpoints; - BObjectList fWatchpoints; + BreakpointProxyList fBreakpointProxies; }; @@ -264,7 +340,6 @@ BreakpointListView::BreakpointListView(Team* team, Listener* listener) : BGroupView(B_VERTICAL), fTeam(team), - fBreakpoint(NULL), fBreakpointsTable(NULL), fBreakpointsTableModel(NULL), fListener(listener) @@ -280,12 +355,12 @@ BreakpointListView::~BreakpointListView() /*static*/ BreakpointListView* -BreakpointListView::Create(Team* team, Listener* listener) +BreakpointListView::Create(Team* team, Listener* listener, BView* filterTarget) { BreakpointListView* self = new BreakpointListView(team, listener); try { - self->_Init(); + self->_Init(filterTarget); } catch (...) { delete self; throw; @@ -302,46 +377,19 @@ BreakpointListView::UnsetListener() } -void -BreakpointListView::SetBreakpoint(UserBreakpoint* breakpoint, - Watchpoint* watchpoint) -{ - if (breakpoint == fBreakpoint) - return; - - if (fBreakpoint != NULL) - fBreakpoint->ReleaseReference(); - - fBreakpoint = breakpoint; - - if (fBreakpoint != NULL) { - fBreakpoint->AcquireReference(); - - for (int32 i = 0; - UserBreakpoint* other = fBreakpointsTableModel->BreakpointAt(i); - i++) { - if (fBreakpoint == other) { - fBreakpointsTable->SelectRow(i, false); - return; - } - } - } - - fBreakpointsTable->DeselectAllRows(); -} - - void BreakpointListView::UserBreakpointChanged(UserBreakpoint* breakpoint) { - fBreakpointsTableModel->UpdateBreakpoint(breakpoint); + BreakpointProxy proxy(breakpoint, NULL); + fBreakpointsTableModel->UpdateBreakpoint(&proxy); } void BreakpointListView::WatchpointChanged(Watchpoint* watchpoint) { - fBreakpointsTableModel->UpdateWatchpoint(watchpoint); + BreakpointProxy proxy(NULL, watchpoint); + fBreakpointsTableModel->UpdateBreakpoint(&proxy); } @@ -378,20 +426,22 @@ BreakpointListView::TableSelectionChanged(Table* table) return; TableSelectionModel* selectionModel = table->SelectionModel(); - UserBreakpoint* breakpoint = fBreakpointsTableModel->BreakpointAt( - selectionModel->RowAt(0)); - if (breakpoint != NULL) - fListener->BreakpointSelectionChanged(breakpoint); - else { - Watchpoint* watchpoint = fBreakpointsTableModel->WatchpointAt( - selectionModel->RowAt(0)); - fListener->WatchpointSelectionChanged(watchpoint); + BreakpointProxyList proxyList; + for (int32 i = 0; i < selectionModel->CountRows(); i++) { + BreakpointProxy* proxy = fBreakpointsTableModel->BreakpointProxyAt( + selectionModel->RowAt(i)); + if (proxy == NULL) + continue; + if (!proxyList.AddItem(proxy)) + return; } + + fListener->BreakpointSelectionChanged(proxyList); } void -BreakpointListView::_Init() +BreakpointListView::_Init(BView* filterTarget) { fBreakpointsTable = new Table("breakpoints list", 0, B_FANCY_BORDER); AddChild(fBreakpointsTable->ToView()); @@ -399,17 +449,15 @@ BreakpointListView::_Init() // columns fBreakpointsTable->AddColumn(new BoolStringTableColumn(0, "State", 70, 20, 1000, "Enabled", "Disabled")); - fBreakpointsTable->AddColumn(new StringTableColumn(1, "Function", 250, 40, + fBreakpointsTable->AddColumn(new StringTableColumn(1, "Location", 250, 40, 1000, B_TRUNCATE_END, B_ALIGN_LEFT)); - fBreakpointsTable->AddColumn(new StringTableColumn(2, "File", 250, 40, - 1000, B_TRUNCATE_END, B_ALIGN_LEFT)); - fBreakpointsTable->AddColumn(new Int32TableColumn(3, "Line", 60, 20, - 1000, B_TRUNCATE_END, B_ALIGN_RIGHT)); - fBreakpointsTable->AddColumn(new TargetAddressTableColumn(4, "Address", 100, - 20, 1000, B_TRUNCATE_END, B_ALIGN_RIGHT)); + fBreakpointsTable->AddColumn(new StringTableColumn(2, "File:Line/Address", + 250, 40, 1000, B_TRUNCATE_END, B_ALIGN_LEFT)); - fBreakpointsTable->SetSelectionMode(B_SINGLE_SELECTION_LIST); + fBreakpointsTable->SetSelectionMode(B_MULTIPLE_SELECTION_LIST); fBreakpointsTable->AddTableListener(this); + fBreakpointsTable->AddFilter(new ListInputFilter(filterTarget)); + fBreakpointsTableModel = new BreakpointsTableModel(fTeam); fBreakpointsTable->SetTableModel(fBreakpointsTableModel); diff --git a/src/apps/debugger/user_interface/gui/team_window/BreakpointListView.h b/src/apps/debugger/user_interface/gui/team_window/BreakpointListView.h index 317ca5be71..9045148abc 100644 --- a/src/apps/debugger/user_interface/gui/team_window/BreakpointListView.h +++ b/src/apps/debugger/user_interface/gui/team_window/BreakpointListView.h @@ -1,5 +1,6 @@ /* * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de. + * Copyright 2013, Rene Gollent, rene@gollent.com. * Distributed under the terms of the MIT License. */ #ifndef BREAKPOINT_LIST_VIEW_H @@ -16,6 +17,31 @@ class UserBreakpoint; class Watchpoint; +enum breakpoint_proxy_type { + BREAKPOINT_PROXY_TYPE_BREAKPOINT = 0, + BREAKPOINT_PROXY_TYPE_WATCHPOINT = 1 +}; + + +class BreakpointProxy : public BReferenceable { +public: + BreakpointProxy(UserBreakpoint* breakpoint, + Watchpoint* watchpoint); + ~BreakpointProxy(); + + breakpoint_proxy_type Type() const; + + UserBreakpoint* GetBreakpoint() const { return fBreakpoint; } + Watchpoint* GetWatchpoint() const { return fWatchpoint; } + +private: + UserBreakpoint* fBreakpoint; + Watchpoint* fWatchpoint; +}; + +typedef BObjectList BreakpointProxyList; + + class BreakpointListView : public BGroupView, private TableListener { public: class Listener; @@ -25,14 +51,12 @@ public: Listener* listener); ~BreakpointListView(); - static BreakpointListView* Create(Team* team, Listener* listener); + static BreakpointListView* Create(Team* team, Listener* listener, + BView* filterTarget); // throws void UnsetListener(); - void SetBreakpoint(UserBreakpoint* breakpoint, - Watchpoint* watchpoint); - void UserBreakpointChanged( UserBreakpoint* breakpoint); void WatchpointChanged( @@ -43,17 +67,16 @@ public: private: class BreakpointsTableModel; + class ListInputFilter; private: // TableListener virtual void TableSelectionChanged(Table* table); - void _Init(); + void _Init(BView* filterTarget); private: Team* fTeam; - UserBreakpoint* fBreakpoint; - Watchpoint* fWatchpoint; Table* fBreakpointsTable; BreakpointsTableModel* fBreakpointsTableModel; Listener* fListener; @@ -65,10 +88,7 @@ public: virtual ~Listener(); virtual void BreakpointSelectionChanged( - UserBreakpoint* breakpoint) = 0; - - virtual void WatchpointSelectionChanged( - Watchpoint* watchpoint) = 0; + BreakpointProxyList& breakpoints) = 0; }; diff --git a/src/apps/debugger/user_interface/gui/team_window/BreakpointsView.cpp b/src/apps/debugger/user_interface/gui/team_window/BreakpointsView.cpp index 7095cdd183..e798b3a20b 100644 --- a/src/apps/debugger/user_interface/gui/team_window/BreakpointsView.cpp +++ b/src/apps/debugger/user_interface/gui/team_window/BreakpointsView.cpp @@ -1,6 +1,6 @@ /* * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de. - * Copyright 2011, Rene Gollent, rene@gollent.com. + * Copyright 2011-2013, Rene Gollent, rene@gollent.com. * Distributed under the terms of the MIT License. */ @@ -27,8 +27,6 @@ BreakpointsView::BreakpointsView(Team* team, Listener* listener) : BGroupView(B_HORIZONTAL, 4.0f), fTeam(team), - fBreakpoint(NULL), - fWatchpoint(NULL), fListView(NULL), fToggleBreakpointButton(NULL), fRemoveBreakpointButton(NULL), @@ -68,32 +66,6 @@ BreakpointsView::UnsetListener() } -void -BreakpointsView::SetBreakpoint(UserBreakpoint* breakpoint, Watchpoint* watchpoint) -{ - if (breakpoint == fBreakpoint && watchpoint == fWatchpoint) - return; - - if (fWatchpoint != NULL) - fWatchpoint->ReleaseReference(); - - if (fBreakpoint != NULL) - fBreakpoint->ReleaseReference(); - - fWatchpoint = watchpoint; - fBreakpoint = breakpoint; - - if (fBreakpoint != NULL) - fBreakpoint->AcquireReference(); - else if (fWatchpoint != NULL) - fWatchpoint->AcquireReference(); - - fListView->SetBreakpoint(breakpoint, watchpoint); - - _UpdateButtons(); -} - - void BreakpointsView::UserBreakpointChanged(UserBreakpoint* breakpoint) { @@ -117,35 +89,9 @@ BreakpointsView::MessageReceived(BMessage* message) { switch (message->what) { case MSG_ENABLE_BREAKPOINT: - if (fListener != NULL) { - if (fBreakpoint != NULL) { - fListener->SetBreakpointEnabledRequested(fBreakpoint, - true); - } else if (fWatchpoint != NULL) { - fListener->SetWatchpointEnabledRequested(fWatchpoint, - true); - } - } - break; case MSG_DISABLE_BREAKPOINT: - if (fListener != NULL) { - if (fBreakpoint != NULL) { - fListener->SetBreakpointEnabledRequested(fBreakpoint, - false); - } else if (fWatchpoint != NULL) { - fListener->SetWatchpointEnabledRequested(fWatchpoint, - false); - } - } - break; case MSG_CLEAR_BREAKPOINT: - if (fListener != NULL) { - if (fBreakpoint != NULL) { - fListener->ClearBreakpointRequested(fBreakpoint); - } else if (fWatchpoint != NULL) { - fListener->ClearWatchpointRequested(fWatchpoint); - } - } + _HandleBreakpointAction(message->what); break; default: BGroupView::MessageReceived(message); @@ -187,18 +133,12 @@ BreakpointsView::SaveSettings(BMessage& settings) void -BreakpointsView::BreakpointSelectionChanged(UserBreakpoint* breakpoint) +BreakpointsView::BreakpointSelectionChanged(BreakpointProxyList& proxies) { if (fListener != NULL) - fListener->BreakpointSelectionChanged(breakpoint); -} + fListener->BreakpointSelectionChanged(proxies); - -void -BreakpointsView::WatchpointSelectionChanged(Watchpoint* watchpoint) -{ - if (fListener != NULL) - fListener->WatchpointSelectionChanged(watchpoint); + _SetSelection(proxies); } @@ -206,7 +146,7 @@ void BreakpointsView::_Init() { BLayoutBuilder::Group<>(this, B_HORIZONTAL, 0.0f) - .Add(fListView = BreakpointListView::Create(fTeam, this)) + .Add(fListView = BreakpointListView::Create(fTeam, this, this)) .AddGroup(B_VERTICAL, B_USE_SMALL_SPACING) .SetInsets(B_USE_SMALL_SPACING) .Add(fToggleBreakpointButton = new BButton("Toggle")) @@ -226,19 +166,44 @@ BreakpointsView::_UpdateButtons() { AutoLocker teamLocker(fTeam); - bool enabled = false; + bool hasEnabled = false; + bool hasDisabled = false; bool valid = false; - if (fBreakpoint != NULL && fBreakpoint->IsValid()) { - valid = true; - enabled = fBreakpoint->IsEnabled(); - } else if (fWatchpoint != NULL) { - valid = true; - enabled = fWatchpoint->IsEnabled(); + 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) { - if (enabled) { + // 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)); @@ -258,6 +223,56 @@ BreakpointsView::_UpdateButtons() } +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 diff --git a/src/apps/debugger/user_interface/gui/team_window/BreakpointsView.h b/src/apps/debugger/user_interface/gui/team_window/BreakpointsView.h index 02bef310b6..374b89674c 100644 --- a/src/apps/debugger/user_interface/gui/team_window/BreakpointsView.h +++ b/src/apps/debugger/user_interface/gui/team_window/BreakpointsView.h @@ -28,9 +28,6 @@ public: void UnsetListener(); - void SetBreakpoint(UserBreakpoint* breakpoint, - Watchpoint* watchpoint); - void UserBreakpointChanged( UserBreakpoint* breakpoint); void WatchpointChanged( @@ -45,19 +42,18 @@ public: private: // BreakpointListView::Listener virtual void BreakpointSelectionChanged( - UserBreakpoint* breakpoint); - virtual void WatchpointSelectionChanged( - Watchpoint* watchpoint); + BreakpointProxyList& proxies); void _Init(); void _UpdateButtons(); + void _SetSelection(BreakpointProxyList& proxies); + void _HandleBreakpointAction(uint32 action); private: Team* fTeam; - UserBreakpoint* fBreakpoint; - Watchpoint* fWatchpoint; BreakpointListView* fListView; + BreakpointProxyList fSelectedBreakpoints; BButton* fToggleBreakpointButton; BButton* fRemoveBreakpointButton; Listener* fListener; @@ -70,15 +66,13 @@ public: virtual ~Listener(); virtual void BreakpointSelectionChanged( - UserBreakpoint* breakpoint) = 0; + BreakpointProxyList& proxies) = 0; virtual void SetBreakpointEnabledRequested( UserBreakpoint* breakpoint, bool enabled) = 0; virtual void ClearBreakpointRequested( UserBreakpoint* breakpoint) = 0; - virtual void WatchpointSelectionChanged( - Watchpoint* Watchpoint) = 0; virtual void SetWatchpointEnabledRequested( Watchpoint* breakpoint, bool enabled) = 0; diff --git a/src/apps/debugger/user_interface/gui/team_window/TeamWindow.cpp b/src/apps/debugger/user_interface/gui/team_window/TeamWindow.cpp index e7f52a7055..5d0fea6183 100644 --- a/src/apps/debugger/user_interface/gui/team_window/TeamWindow.cpp +++ b/src/apps/debugger/user_interface/gui/team_window/TeamWindow.cpp @@ -610,9 +610,17 @@ TeamWindow::FunctionSelectionChanged(FunctionInstance* function) void -TeamWindow::BreakpointSelectionChanged(UserBreakpoint* breakpoint) +TeamWindow::BreakpointSelectionChanged(BreakpointProxyList &proxies) { - _SetActiveBreakpoint(breakpoint); + if (proxies.CountItems() == 0 && fActiveBreakpoint != NULL) { + fActiveBreakpoint->ReleaseReference(); + fActiveBreakpoint = NULL; + } else if (proxies.CountItems() == 1) { + BreakpointProxy* proxy = proxies.ItemAt(0); + if (proxy->Type() == BREAKPOINT_PROXY_TYPE_BREAKPOINT) + _SetActiveBreakpoint(proxy->GetBreakpoint()); + } + // if more than one item is selected, do nothing. } @@ -653,13 +661,6 @@ TeamWindow::ThreadActionRequested(::Thread* thread, uint32 action, } -void -TeamWindow::WatchpointSelectionChanged(Watchpoint* watchpoint) -{ - fBreakpointsView->SetBreakpoint(NULL, watchpoint); -} - - void TeamWindow::SetWatchpointEnabledRequested(Watchpoint* watchpoint, bool enabled) @@ -1041,8 +1042,6 @@ TeamWindow::_SetActiveBreakpoint(UserBreakpoint* breakpoint) // automatically, if the active function remains the same) _ScrollToActiveFunction(); } - - fBreakpointsView->SetBreakpoint(fActiveBreakpoint, NULL); } diff --git a/src/apps/debugger/user_interface/gui/team_window/TeamWindow.h b/src/apps/debugger/user_interface/gui/team_window/TeamWindow.h index 4abf4d8a05..810d975105 100644 --- a/src/apps/debugger/user_interface/gui/team_window/TeamWindow.h +++ b/src/apps/debugger/user_interface/gui/team_window/TeamWindow.h @@ -88,15 +88,13 @@ private: // BreakpointsView::Listener virtual void BreakpointSelectionChanged( - UserBreakpoint* breakpoint); + BreakpointProxyList& proxies); virtual void SetBreakpointEnabledRequested( UserBreakpoint* breakpoint, bool enabled); virtual void ClearBreakpointRequested( UserBreakpoint* breakpoint); - virtual void WatchpointSelectionChanged( - Watchpoint* Watchpoint); virtual void SetWatchpointEnabledRequested( Watchpoint* breakpoint, bool enabled);