- Introduce class BreakpointProxy which acts as a container for
either a breakpoint or a watchpoint. BreakpointsTableModel now stores
a single list of these rather than separate Breakpoint/Watchpoint lists.
- Switch BreakpointListView to allow multiple selection mode, and
consequently change selection/listener interfaces to use a list of
BreakpointProxy objects. Adjust implementors accordingly.
- Rework breakpoint list columns to better mesh with a unified display
of breakpoint and watchpoint information.
- Add an input filter to handle removing breakpoints when the delete
key is pressed.
This commit is contained in:
Rene Gollent 2013-05-19 21:34:33 -04:00
parent 74875a2e90
commit 6b308faf1e
6 changed files with 356 additions and 282 deletions

View File

@ -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 <new>
#include <MessageFilter.h>
#include <AutoLocker.h>
#include <ObjectList.h>
#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<BreakpointProxy> 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<Team> 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<Team> 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<UserBreakpoint> fBreakpoints;
BObjectList<Watchpoint> 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);

View File

@ -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<BreakpointProxy> 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;
};

View File

@ -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<Team> 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

View File

@ -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;

View File

@ -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);
}

View File

@ -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);