debugger: make BreakpointData and BreakpointResult proper value types

This commit is contained in:
hjk
2010-11-15 14:12:05 +01:00
parent 8d59cff401
commit 956b54289e
6 changed files with 219 additions and 226 deletions

View File

@@ -78,7 +78,7 @@ bool BreakHandler::hasPendingBreakpoints() const
{ {
ConstIterator it = m_storage.constBegin(), et = m_storage.constEnd(); ConstIterator it = m_storage.constBegin(), et = m_storage.constEnd();
for ( ; it != et; ++it) for ( ; it != et; ++it)
if (it->data->isPending()) if (it->isPending())
return true; return true;
return false; return false;
} }
@@ -92,30 +92,30 @@ static inline bool fileNameMatch(const QString &f1, const QString &f2)
#endif #endif
} }
static bool isSimilarTo(const BreakpointData *data, const BreakpointResponse &needle) static bool isSimilarTo(const BreakpointData &data, const BreakpointResponse &needle)
{ {
// Clear hit. // Clear hit.
// Clear miss. // Clear miss.
if (needle.bpType != UnknownType && data->type() != UnknownType if (needle.bpType != UnknownType && data.type() != UnknownType
&& data->type() != needle.bpType) && data.type() != needle.bpType)
return false; return false;
// Clear hit. // Clear hit.
if (data->address() && data->address() == needle.bpAddress) if (data.address() && data.address() == needle.bpAddress)
return true; return true;
// At least at a position we were looking for. // At least at a position we were looking for.
// FIXME: breaks multiple breakpoints at the same location // FIXME: breaks multiple breakpoints at the same location
if (!data->fileName().isEmpty() if (!data.fileName().isEmpty()
&& fileNameMatch(data->fileName(), needle.bpFileName) && fileNameMatch(data.fileName(), needle.bpFileName)
&& data->lineNumber() == needle.bpLineNumber) && data.lineNumber() == needle.bpLineNumber)
return true; return true;
// At least at a position we were looking for. // At least at a position we were looking for.
// FIXME: breaks multiple breakpoints at the same location // FIXME: breaks multiple breakpoints at the same location
if (!data->fileName().isEmpty() if (!data.fileName().isEmpty()
&& fileNameMatch(data->fileName(), needle.bpFileName) && fileNameMatch(data.fileName(), needle.bpFileName)
&& data->lineNumber() == needle.bpLineNumber) && data.lineNumber() == needle.bpLineNumber)
return true; return true;
return false; return false;
@@ -127,10 +127,10 @@ BreakpointId BreakHandler::findSimilarBreakpoint(const BreakpointResponse &needl
ConstIterator it = m_storage.constBegin(), et = m_storage.constEnd(); ConstIterator it = m_storage.constBegin(), et = m_storage.constEnd();
for ( ; it != et; ++it) { for ( ; it != et; ++it) {
const BreakpointId id = it.key(); const BreakpointId id = it.key();
const BreakpointData *data = it->data; const BreakpointData &data = it->data;
const BreakpointResponse *response = it->response; const BreakpointResponse &response = it->response;
qDebug() << "COMPARING " << data->toString() << " WITH " << needle.toString(); qDebug() << "COMPARING " << data.toString() << " WITH " << needle.toString();
if (response->bpNumber && response->bpNumber == needle.bpNumber) if (response.bpNumber && response.bpNumber == needle.bpNumber)
return id; return id;
if (isSimilarTo(data, needle)) if (isSimilarTo(data, needle))
@@ -143,7 +143,7 @@ BreakpointId BreakHandler::findBreakpointByNumber(int bpNumber) const
{ {
ConstIterator it = m_storage.constBegin(), et = m_storage.constEnd(); ConstIterator it = m_storage.constBegin(), et = m_storage.constEnd();
for ( ; it != et; ++it) for ( ; it != et; ++it)
if (it->response->bpNumber == bpNumber) if (it->response.bpNumber == bpNumber)
return it.key(); return it.key();
return BreakpointId(-1); return BreakpointId(-1);
} }
@@ -152,7 +152,7 @@ BreakpointId BreakHandler::findBreakpointByFunction(const QString &functionName)
{ {
ConstIterator it = m_storage.constBegin(), et = m_storage.constEnd(); ConstIterator it = m_storage.constBegin(), et = m_storage.constEnd();
for ( ; it != et; ++it) for ( ; it != et; ++it)
if (it->data->functionName() == functionName) if (it->data.functionName() == functionName)
return it.key(); return it.key();
return BreakpointId(-1); return BreakpointId(-1);
} }
@@ -161,7 +161,7 @@ BreakpointId BreakHandler::findBreakpointByAddress(quint64 address) const
{ {
ConstIterator it = m_storage.constBegin(), et = m_storage.constEnd(); ConstIterator it = m_storage.constBegin(), et = m_storage.constEnd();
for ( ; it != et; ++it) for ( ; it != et; ++it)
if (it->data->address() == address) if (it->data.address() == address)
return it.key(); return it.key();
return BreakpointId(-1); return BreakpointId(-1);
} }
@@ -171,33 +171,34 @@ BreakpointId BreakHandler::findBreakpointByFileAndLine(const QString &fileName,
{ {
ConstIterator it = m_storage.constBegin(), et = m_storage.constEnd(); ConstIterator it = m_storage.constBegin(), et = m_storage.constEnd();
for ( ; it != et; ++it) for ( ; it != et; ++it)
if (it->data->isLocatedAt(fileName, lineNumber, useMarkerPosition)) if (it->data.isLocatedAt(fileName, lineNumber, useMarkerPosition))
return it.key(); return it.key();
return BreakpointId(-1); return BreakpointId(-1);
} }
BreakpointData *BreakHandler::breakpointById(BreakpointId id) const BreakpointData *BreakHandler::breakpointById(BreakpointId id)
{ {
return m_storage.value(id).data; Iterator it = m_storage.find(id);
QTC_ASSERT(it != m_storage.end(), return 0);
return &it->data;
} }
BreakpointId BreakHandler::findWatchpointByAddress(quint64 address) const BreakpointId BreakHandler::findWatchpointByAddress(quint64 address) const
{ {
ConstIterator it = m_storage.constBegin(), et = m_storage.constEnd(); ConstIterator it = m_storage.constBegin(), et = m_storage.constEnd();
for ( ; it != et; ++it) for ( ; it != et; ++it)
if (it->data->isWatchpoint() && it->data->address() == address) if (it->data.isWatchpoint() && it->data.address() == address)
return it.key(); return it.key();
return BreakpointId(-1); return BreakpointId(-1);
} }
void BreakHandler::setWatchpointByAddress(quint64 address) void BreakHandler::setWatchpointByAddress(quint64 address)
{ {
const int id = findWatchpointByAddress(address); const int id = findWatchpointByAddress(address);
if (id == -1) { if (id == -1) {
BreakpointData *data = new BreakpointData; BreakpointData data;
data->setType(Watchpoint); data.setType(Watchpoint);
data->setAddress(address); data.setAddress(address);
appendBreakpoint(data); appendBreakpoint(data);
scheduleSynchronization(); scheduleSynchronization();
} else { } else {
@@ -218,30 +219,30 @@ void BreakHandler::saveBreakpoints()
QList<QVariant> list; QList<QVariant> list;
ConstIterator it = m_storage.constBegin(), et = m_storage.constEnd(); ConstIterator it = m_storage.constBegin(), et = m_storage.constEnd();
for ( ; it != et; ++it) { for ( ; it != et; ++it) {
const BreakpointData *data = it->data; const BreakpointData &data = it->data;
QMap<QString, QVariant> map; QMap<QString, QVariant> map;
// Do not persist Watchpoints. // Do not persist Watchpoints.
//if (data->isWatchpoint()) //if (data.isWatchpoint())
// continue; // continue;
if (data->type() != BreakpointByFileAndLine) if (data.type() != BreakpointByFileAndLine)
map.insert(_("type"), data->type()); map.insert(_("type"), data.type());
if (!data->fileName().isEmpty()) if (!data.fileName().isEmpty())
map.insert(_("filename"), data->fileName()); map.insert(_("filename"), data.fileName());
if (data->lineNumber()) if (data.lineNumber())
map.insert(_("linenumber"), data->lineNumber()); map.insert(_("linenumber"), data.lineNumber());
if (!data->functionName().isEmpty()) if (!data.functionName().isEmpty())
map.insert(_("funcname"), data->functionName()); map.insert(_("funcname"), data.functionName());
if (data->address()) if (data.address())
map.insert(_("address"), data->address()); map.insert(_("address"), data.address());
if (!data->condition().isEmpty()) if (!data.condition().isEmpty())
map.insert(_("condition"), data->condition()); map.insert(_("condition"), data.condition());
if (data->ignoreCount()) if (data.ignoreCount())
map.insert(_("ignorecount"), data->ignoreCount()); map.insert(_("ignorecount"), data.ignoreCount());
if (!data->threadSpec().isEmpty()) if (!data.threadSpec().isEmpty())
map.insert(_("threadspec"), data->threadSpec()); map.insert(_("threadspec"), data.threadSpec());
if (!data->isEnabled()) if (!data.isEnabled())
map.insert(_("disabled"), _("1")); map.insert(_("disabled"), _("1"));
if (data->useFullPath()) if (data.useFullPath())
map.insert(_("usefullpath"), _("1")); map.insert(_("usefullpath"), _("1"));
list.append(map); list.append(map);
} }
@@ -258,39 +259,39 @@ void BreakHandler::loadBreakpoints()
//clear(); //clear();
foreach (const QVariant &var, list) { foreach (const QVariant &var, list) {
const QMap<QString, QVariant> map = var.toMap(); const QMap<QString, QVariant> map = var.toMap();
BreakpointData *data = new BreakpointData; BreakpointData data;
QVariant v = map.value(_("filename")); QVariant v = map.value(_("filename"));
if (v.isValid()) if (v.isValid())
data->setFileName(v.toString()); data.setFileName(v.toString());
v = map.value(_("linenumber")); v = map.value(_("linenumber"));
if (v.isValid()) if (v.isValid())
data->setLineNumber(v.toString().toInt()); data.setLineNumber(v.toString().toInt());
v = map.value(_("condition")); v = map.value(_("condition"));
if (v.isValid()) if (v.isValid())
data->setCondition(v.toString().toLatin1()); data.setCondition(v.toString().toLatin1());
v = map.value(_("address")); v = map.value(_("address"));
if (v.isValid()) if (v.isValid())
data->setAddress(v.toString().toULongLong()); data.setAddress(v.toString().toULongLong());
v = map.value(_("ignorecount")); v = map.value(_("ignorecount"));
if (v.isValid()) if (v.isValid())
data->setIgnoreCount(v.toString().toInt()); data.setIgnoreCount(v.toString().toInt());
v = map.value(_("threadspec")); v = map.value(_("threadspec"));
if (v.isValid()) if (v.isValid())
data->setThreadSpec(v.toString().toLatin1()); data.setThreadSpec(v.toString().toLatin1());
v = map.value(_("funcname")); v = map.value(_("funcname"));
if (v.isValid()) if (v.isValid())
data->setFunctionName(v.toString()); data.setFunctionName(v.toString());
v = map.value(_("disabled")); v = map.value(_("disabled"));
if (v.isValid()) if (v.isValid())
data->setEnabled(!v.toInt()); data.setEnabled(!v.toInt());
v = map.value(_("usefullpath")); v = map.value(_("usefullpath"));
if (v.isValid()) if (v.isValid())
data->setUseFullPath(bool(v.toInt())); data.setUseFullPath(bool(v.toInt()));
v = map.value(_("type")); v = map.value(_("type"));
if (v.isValid()) if (v.isValid())
data->setType(BreakpointType(v.toInt())); data.setType(BreakpointType(v.toInt()));
data->setMarkerFileName(data->fileName()); data.setMarkerFileName(data.fileName());
data->setMarkerLineNumber(data->lineNumber()); data.setMarkerLineNumber(data.lineNumber());
appendBreakpoint(data); appendBreakpoint(data);
} }
//qDebug() << "LOADED BREAKPOINTS" << this << list.size(); //qDebug() << "LOADED BREAKPOINTS" << this << list.size();
@@ -306,18 +307,18 @@ void BreakHandler::updateMarkers()
void BreakHandler::updateMarker(BreakpointId id) void BreakHandler::updateMarker(BreakpointId id)
{ {
Iterator it = m_storage.find(id); Iterator it = m_storage.find(id);
BreakpointData *data = it->data; QTC_ASSERT(it != m_storage.end(), return);
QTC_ASSERT(data, return); const BreakpointData &data = it->data;
BreakpointMarker *marker = it->marker; BreakpointMarker *marker = it->marker;
if (marker && (data->m_markerFileName != marker->fileName() if (marker && (data.m_markerFileName != marker->fileName()
|| data->m_markerLineNumber != marker->lineNumber())) { || data.m_markerLineNumber != marker->lineNumber())) {
removeMarker(id); removeMarker(id);
marker = 0; marker = 0;
} }
if (!marker && !data->m_markerFileName.isEmpty() && data->m_markerLineNumber > 0) { if (!marker && !data.m_markerFileName.isEmpty() && data.m_markerLineNumber > 0) {
marker = new BreakpointMarker(id, data->m_markerFileName, data->m_markerLineNumber); marker = new BreakpointMarker(id, data.m_markerFileName, data.m_markerLineNumber);
it->marker = marker; it->marker = marker;
} }
} }
@@ -357,44 +358,45 @@ QVariant BreakHandler::data(const QModelIndex &mi, int role) const
{ {
static const QString empty = QString(QLatin1Char('-')); static const QString empty = QString(QLatin1Char('-'));
QTC_ASSERT(mi.isValid(), return QVariant()); if (!mi.isValid())
return QVariant();
BreakpointId id = findBreakpointByIndex(mi); BreakpointId id = findBreakpointByIndex(mi);
ConstIterator it = m_storage.find(id); ConstIterator it = m_storage.find(id);
BreakpointData *data = it->data; QTC_ASSERT(it != m_storage.end(), return QVariant());
QTC_ASSERT(data, return QVariant()); const BreakpointData &data = it->data;
BreakpointResponse *response = it->response; const BreakpointResponse &response = it->response;
QTC_ASSERT(response, return QVariant());
switch (mi.column()) { switch (mi.column()) {
case 0: case 0:
if (role == Qt::DisplayRole) { if (role == Qt::DisplayRole) {
return QString("%1 - %2").arg(id).arg(response->bpNumber); return QString("%1 - %2").arg(id).arg(response.bpNumber);
} }
if (role == Qt::DecorationRole) { if (role == Qt::DecorationRole) {
if (data->isWatchpoint()) if (data.isWatchpoint())
return m_watchpointIcon; return m_watchpointIcon;
if (!data->isEnabled()) if (!data.isEnabled())
return m_disabledBreakpointIcon; return m_disabledBreakpointIcon;
return data->isPending() ? m_pendingBreakPointIcon : m_breakpointIcon; return it->isPending() ? m_pendingBreakPointIcon : m_breakpointIcon;
} }
break; break;
case 1: case 1:
if (role == Qt::DisplayRole) { if (role == Qt::DisplayRole) {
const QString str = data->isPending() const QString str = it->isPending()
? data->functionName() : response->bpFuncName; ? data.functionName() : response.bpFuncName;
return str.isEmpty() ? empty : str; return str.isEmpty() ? empty : str;
} }
break; break;
case 2: case 2:
if (role == Qt::DisplayRole) { if (role == Qt::DisplayRole) {
QString str = data->isPending() QString str = it->isPending()
? data->fileName() : response->bpFileName; ? data.fileName() : response.bpFileName;
str = QFileInfo(str).fileName(); str = QFileInfo(str).fileName();
// FIXME: better? // FIXME: better?
//if (data->bpMultiple && str.isEmpty() && !data->markerFileName.isEmpty()) //if (data.bpMultiple && str.isEmpty() && !data.markerFileName.isEmpty())
// str = data->markerFileName; // str = data.markerFileName;
str = str.isEmpty() ? empty : str; str = str.isEmpty() ? empty : str;
if (data->useFullPath()) if (data.useFullPath())
str = QDir::toNativeSeparators(QLatin1String("/.../") + str); str = QDir::toNativeSeparators(QLatin1String("/.../") + str);
return str; return str;
} }
@@ -402,57 +404,57 @@ QVariant BreakHandler::data(const QModelIndex &mi, int role) const
case 3: case 3:
if (role == Qt::DisplayRole) { if (role == Qt::DisplayRole) {
// FIXME: better? // FIXME: better?
//if (data->bpMultiple && str.isEmpty() && !data->markerFileName.isEmpty()) //if (data.bpMultiple && str.isEmpty() && !data.markerFileName.isEmpty())
// str = data->markerLineNumber; // str = data.markerLineNumber;
const int nr = data->isPending() const int nr = it->isPending()
? data->lineNumber() : response->bpLineNumber; ? data.lineNumber() : response.bpLineNumber;
return nr ? QString::number(nr) : empty; return nr ? QString::number(nr) : empty;
} }
if (role == Qt::UserRole + 1) if (role == Qt::UserRole + 1)
return data->lineNumber(); return data.lineNumber();
break; break;
case 4: case 4:
if (role == Qt::DisplayRole) if (role == Qt::DisplayRole)
return data->isPending() ? data->condition() : response->bpCondition; return it->isPending() ? data.condition() : response.bpCondition;
if (role == Qt::ToolTipRole) if (role == Qt::ToolTipRole)
return tr("Breakpoint will only be hit if this condition is met."); return tr("Breakpoint will only be hit if this condition is met.");
if (role == Qt::UserRole + 1) if (role == Qt::UserRole + 1)
return data->condition(); return data.condition();
break; break;
case 5: case 5:
if (role == Qt::DisplayRole) { if (role == Qt::DisplayRole) {
const int ignoreCount = const int ignoreCount =
data->isPending() ? data->ignoreCount() : response->bpIgnoreCount; it->isPending() ? data.ignoreCount() : response.bpIgnoreCount;
return ignoreCount ? QVariant(ignoreCount) : QVariant(QString()); return ignoreCount ? QVariant(ignoreCount) : QVariant(QString());
} }
if (role == Qt::ToolTipRole) if (role == Qt::ToolTipRole)
return tr("Breakpoint will only be hit after being ignored so many times."); return tr("Breakpoint will only be hit after being ignored so many times.");
if (role == Qt::UserRole + 1) if (role == Qt::UserRole + 1)
return data->ignoreCount(); return data.ignoreCount();
break; break;
case 6: case 6:
if (role == Qt::DisplayRole) { if (role == Qt::DisplayRole) {
if (data->isPending()) if (it->isPending())
return !data->threadSpec().isEmpty() ? data->threadSpec() : tr("(all)"); return !data.threadSpec().isEmpty() ? data.threadSpec() : tr("(all)");
else else
return !response->bpThreadSpec.isEmpty() ? response->bpThreadSpec : tr("(all)"); return !response.bpThreadSpec.isEmpty() ? response.bpThreadSpec : tr("(all)");
} }
if (role == Qt::ToolTipRole) if (role == Qt::ToolTipRole)
return tr("Breakpoint will only be hit in the specified thread(s)."); return tr("Breakpoint will only be hit in the specified thread(s).");
if (role == Qt::UserRole + 1) if (role == Qt::UserRole + 1)
return data->threadSpec(); return data.threadSpec();
break; break;
case 7: case 7:
if (role == Qt::DisplayRole) { if (role == Qt::DisplayRole) {
QString displayValue; QString displayValue;
const quint64 address = const quint64 address =
data->isWatchpoint() ? data->address() : response->bpAddress; data.isWatchpoint() ? data.address() : response.bpAddress;
if (address) if (address)
displayValue += QString::fromAscii("0x%1").arg(address, 0, 16); displayValue += QString::fromAscii("0x%1").arg(address, 0, 16);
if (!response->bpState.isEmpty()) { if (!response.bpState.isEmpty()) {
if (!displayValue.isEmpty()) if (!displayValue.isEmpty())
displayValue += QLatin1Char(' '); displayValue += QLatin1Char(' ');
displayValue += QString::fromAscii(response->bpState); displayValue += QString::fromAscii(response.bpState);
} }
return displayValue; return displayValue;
} }
@@ -460,7 +462,7 @@ QVariant BreakHandler::data(const QModelIndex &mi, int role) const
} }
if (role == Qt::ToolTipRole) if (role == Qt::ToolTipRole)
return debuggerCore()->boolSetting(UseToolTipsInBreakpointsView) return debuggerCore()->boolSetting(UseToolTipsInBreakpointsView)
? data->toToolTip() : QVariant(); ? data.toToolTip() : QVariant();
return QVariant(); return QVariant();
} }
@@ -468,17 +470,17 @@ QVariant BreakHandler::data(const QModelIndex &mi, int role) const
#define GETTER(type, getter) \ #define GETTER(type, getter) \
type BreakHandler::getter(BreakpointId id) const \ type BreakHandler::getter(BreakpointId id) const \
{ \ { \
BreakpointData *data = m_storage.value(id).data; \ ConstIterator it = m_storage.find(id); \
QTC_ASSERT(data, return type()); \ QTC_ASSERT(it != m_storage.end(), return type()); \
return data->getter(); \ return it->data.getter(); \
} }
#define SETTER(type, setter) \ #define SETTER(type, setter) \
void BreakHandler::setter(BreakpointId id, const type &value) \ void BreakHandler::setter(BreakpointId id, const type &value) \
{ \ { \
BreakpointData *data = m_storage.value(id).data; \ Iterator it = m_storage.find(id); \
QTC_ASSERT(data, return); \ QTC_ASSERT(it != m_storage.end(), return); \
if (data->setter(value)) \ if (it->data.setter(value)) \
scheduleSynchronization(); \ scheduleSynchronization(); \
} }
@@ -494,28 +496,42 @@ PROPERTY(QString, functionName, setFunctionName)
PROPERTY(int, markerLineNumber, setMarkerLineNumber) PROPERTY(int, markerLineNumber, setMarkerLineNumber)
PROPERTY(bool, isEnabled, setEnabled) PROPERTY(bool, isEnabled, setEnabled)
PROPERTY(BreakpointType, type, setType) PROPERTY(BreakpointType, type, setType)
PROPERTY(BreakpointState, state, setState)
PROPERTY(QByteArray, threadSpec, setThreadSpec) PROPERTY(QByteArray, threadSpec, setThreadSpec)
PROPERTY(QByteArray, condition, setCondition) PROPERTY(QByteArray, condition, setCondition)
PROPERTY(int, lineNumber, setLineNumber) PROPERTY(int, lineNumber, setLineNumber)
PROPERTY(quint64, address, setAddress) PROPERTY(quint64, address, setAddress)
PROPERTY(int, ignoreCount, setIgnoreCount) PROPERTY(int, ignoreCount, setIgnoreCount)
BreakpointState BreakHandler::state(BreakpointId id) const
{
ConstIterator it = m_storage.find(id);
QTC_ASSERT(it != m_storage.end(), return BreakpointDead);
return it->state;
}
void BreakHandler::setState(BreakpointId id, BreakpointState state)
{
Iterator it = m_storage.find(id);
QTC_ASSERT(it != m_storage.end(), return);
it->state = state;
updateMarker(id);
}
DebuggerEngine *BreakHandler::engine(BreakpointId id) const DebuggerEngine *BreakHandler::engine(BreakpointId id) const
{ {
BreakpointData *data = m_storage.value(id).data; ConstIterator it = m_storage.find(id);
QTC_ASSERT(data, return 0); QTC_ASSERT(it != m_storage.end(), return 0);
return data->engine(); return it->engine;
} }
void BreakHandler::setEngine(BreakpointId id, DebuggerEngine *value) void BreakHandler::setEngine(BreakpointId id, DebuggerEngine *value)
{ {
BreakpointData *data = m_storage.value(id).data; Iterator it = m_storage.find(id);
QTC_ASSERT(data, return); QTC_ASSERT(it != m_storage.end(), return);
QTC_ASSERT(data->state() == BreakpointNew, /**/); QTC_ASSERT(it->state == BreakpointNew, /**/);
QTC_ASSERT(!data->engine(), return); QTC_ASSERT(!it->engine, return);
data->setEngine(value); it->engine = value;
data->setState(BreakpointInsertRequested); it->state = BreakpointInsertRequested;
updateMarker(id); updateMarker(id);
scheduleSynchronization(); scheduleSynchronization();
} }
@@ -524,7 +540,7 @@ void BreakHandler::ackCondition(BreakpointId id)
{ {
Iterator it = m_storage.find(id); Iterator it = m_storage.find(id);
QTC_ASSERT(it != m_storage.end(), return); QTC_ASSERT(it != m_storage.end(), return);
it->response->bpCondition = it->data->condition(); it->response.bpCondition = it->data.condition();
updateMarker(id); updateMarker(id);
} }
@@ -532,7 +548,7 @@ void BreakHandler::ackIgnoreCount(BreakpointId id)
{ {
Iterator it = m_storage.find(id); Iterator it = m_storage.find(id);
QTC_ASSERT(it != m_storage.end(), return); QTC_ASSERT(it != m_storage.end(), return);
it->response->bpIgnoreCount = it->data->ignoreCount(); it->response.bpIgnoreCount = it->data.ignoreCount();
updateMarker(id); updateMarker(id);
} }
@@ -548,21 +564,22 @@ Qt::ItemFlags BreakHandler::flags(const QModelIndex &index) const
void BreakHandler::removeBreakpoint(BreakpointId id) void BreakHandler::removeBreakpoint(BreakpointId id)
{ {
BreakpointData *data = m_storage.value(id).data; Iterator it = m_storage.find(id);
if (data->state() == BreakpointInserted) { QTC_ASSERT(it != m_storage.end(), return);
if (it->state == BreakpointInserted) {
qDebug() << "MARK AS CHANGED: " << id; qDebug() << "MARK AS CHANGED: " << id;
data->m_state = BreakpointRemoveRequested; it->state = BreakpointRemoveRequested;
QTC_ASSERT(data->engine(), return); QTC_ASSERT(it->engine, return);
debuggerCore()->synchronizeBreakpoints(); debuggerCore()->synchronizeBreakpoints();
} else if (data->state() == BreakpointNew) { } else if (it->state == BreakpointNew) {
data->m_state = BreakpointDead; it->state = BreakpointDead;
cleanupBreakpoint(id); cleanupBreakpoint(id);
} else { } else {
qDebug() << "CANNOT REMOVE IN STATE " << data->state(); qDebug() << "CANNOT REMOVE IN STATE " << it->state;
} }
} }
void BreakHandler::appendBreakpoint(BreakpointData *data) void BreakHandler::appendBreakpoint(const BreakpointData &data)
{ {
// Ok to be not thread-safe. The order does not matter and only the gui // Ok to be not thread-safe. The order does not matter and only the gui
// produces authoritative ids. // produces authoritative ids.
@@ -571,7 +588,6 @@ void BreakHandler::appendBreakpoint(BreakpointData *data)
BreakpointId id(++currentId); BreakpointId id(++currentId);
BreakpointItem item; BreakpointItem item;
item.data = data; item.data = data;
item.response = new BreakpointResponse;
m_storage.insert(id, item); m_storage.insert(id, item);
scheduleSynchronization(); scheduleSynchronization();
} }
@@ -592,15 +608,15 @@ void BreakHandler::toggleBreakpoint(const QString &fileName, int lineNumber,
if (id != BreakpointId(-1)) { if (id != BreakpointId(-1)) {
removeBreakpoint(id); removeBreakpoint(id);
} else { } else {
BreakpointData *data = new BreakpointData; BreakpointData data;
if (address) { if (address) {
data->setAddress(address); data.setAddress(address);
} else { } else {
data->setFileName(fileName); data.setFileName(fileName);
data->setLineNumber(lineNumber); data.setLineNumber(lineNumber);
} }
data->setMarkerFileName(fileName); data.setMarkerFileName(fileName);
data->setMarkerLineNumber(lineNumber); data.setMarkerLineNumber(lineNumber);
appendBreakpoint(data); appendBreakpoint(data);
} }
debuggerCore()->synchronizeBreakpoints(); debuggerCore()->synchronizeBreakpoints();
@@ -623,16 +639,15 @@ void BreakHandler::breakByFunction(const QString &functionName)
// combinations of multiple conditions and ignore counts, though. // combinations of multiple conditions and ignore counts, though.
ConstIterator it = m_storage.constBegin(), et = m_storage.constEnd(); ConstIterator it = m_storage.constBegin(), et = m_storage.constEnd();
for ( ; it != et; ++it) { for ( ; it != et; ++it) {
const BreakpointData *data = it->data; const BreakpointData &data = it->data;
QTC_ASSERT(data, break); if (data.functionName() == functionName
if (data->functionName() == functionName && data.condition().isEmpty()
&& data->condition().isEmpty() && data.ignoreCount() == 0)
&& data->ignoreCount() == 0)
return; return;
} }
BreakpointData *data = new BreakpointData; BreakpointData data;
data->setType(BreakpointByFunction); data.setType(BreakpointByFunction);
data->setFunctionName(functionName); data.setFunctionName(functionName);
appendBreakpoint(data); appendBreakpoint(data);
} }
@@ -640,11 +655,11 @@ QIcon BreakHandler::icon(BreakpointId id) const
{ {
//if (!m_handler->isActive()) //if (!m_handler->isActive())
// return m_handler->emptyIcon(); // return m_handler->emptyIcon();
const BreakpointData *data = m_storage.value(id).data; ConstIterator it = m_storage.find(id);
QTC_ASSERT(data, return pendingBreakPointIcon()); QTC_ASSERT(it != m_storage.end(), return pendingBreakPointIcon());
//if (!isActive()) //if (!isActive())
// return emptyIcon(); // return emptyIcon();
switch (data->state()) { switch (it->state) {
case BreakpointInserted: case BreakpointInserted:
return breakpointIcon(); return breakpointIcon();
default: default:
@@ -675,23 +690,23 @@ void BreakHandler::gotoLocation(BreakpointId id) const
ConstIterator it = m_storage.find(id); ConstIterator it = m_storage.find(id);
QTC_ASSERT(it != m_storage.end(), return); QTC_ASSERT(it != m_storage.end(), return);
debuggerCore()->gotoLocation( debuggerCore()->gotoLocation(
it->data->fileName(), it->data->lineNumber(), false); it->data.fileName(), it->data.lineNumber(), false);
} }
void BreakHandler::updateLineNumberFromMarker(BreakpointId id, int lineNumber) void BreakHandler::updateLineNumberFromMarker(BreakpointId id, int lineNumber)
{ {
Iterator it = m_storage.find(id); Iterator it = m_storage.find(id);
QTC_ASSERT(it != m_storage.end(), return); QTC_ASSERT(it != m_storage.end(), return);
//if (data->markerLineNumber == lineNumber) //if (data.markerLineNumber == lineNumber)
// return; // return;
if (it->data->markerLineNumber() != lineNumber) { if (it->data.markerLineNumber() != lineNumber) {
it->data->setMarkerLineNumber(lineNumber); it->data.setMarkerLineNumber(lineNumber);
// FIXME: Should we tell gdb about the change? // FIXME: Should we tell gdb about the change?
// Ignore it for now, as we would require re-compilation // Ignore it for now, as we would require re-compilation
// and debugger re-start anyway. // and debugger re-start anyway.
//if (0 && data->bpLineNumber) { //if (0 && data.bpLineNumber) {
// if (!data->bpNumber.trimmed().isEmpty()) { // if (!data.bpNumber.trimmed().isEmpty()) {
// data->pending = true; // data.pending = true;
// } // }
//} //}
} }
@@ -699,8 +714,8 @@ void BreakHandler::updateLineNumberFromMarker(BreakpointId id, int lineNumber)
// running, as this can be triggered by moving the breakpoint to // running, as this can be triggered by moving the breakpoint to
// the next line that generated code. // the next line that generated code.
// FIXME: Do we need yet another data member? // FIXME: Do we need yet another data member?
if (it->response->bpNumber == 0) { if (it->response.bpNumber == 0) {
it->data->setLineNumber(lineNumber); it->data.setLineNumber(lineNumber);
updateMarker(id); updateMarker(id);
} }
} }
@@ -724,21 +739,21 @@ BreakpointIds BreakHandler::engineBreakpointIds(DebuggerEngine *engine) const
BreakpointIds ids; BreakpointIds ids;
ConstIterator it = m_storage.constBegin(), et = m_storage.constEnd(); ConstIterator it = m_storage.constBegin(), et = m_storage.constEnd();
for ( ; it != et; ++it) for ( ; it != et; ++it)
if (it->data->engine() == engine) if (it->engine == engine)
ids.append(it.key()); ids.append(it.key());
return ids; return ids;
} }
void BreakHandler::notifyBreakpointInsertOk(BreakpointId id) void BreakHandler::notifyBreakpointInsertOk(BreakpointId id)
{ {
QTC_ASSERT(breakHandler()->state(id)== BreakpointInsertProceeding, /**/); QTC_ASSERT(state(id)== BreakpointInsertProceeding, /**/);
breakHandler()->setState(id, BreakpointInserted); setState(id, BreakpointInserted);
} }
void BreakHandler::notifyBreakpointInsertFailed(BreakpointId id) void BreakHandler::notifyBreakpointInsertFailed(BreakpointId id)
{ {
QTC_ASSERT(breakHandler()->state(id)== BreakpointInsertProceeding, /**/); QTC_ASSERT(state(id)== BreakpointInsertProceeding, /**/);
breakHandler()->setState(id, BreakpointDead); setState(id, BreakpointDead);
} }
void BreakHandler::notifyBreakpointRemoveOk(BreakpointId id) void BreakHandler::notifyBreakpointRemoveOk(BreakpointId id)
@@ -772,12 +787,11 @@ void BreakHandler::notifyBreakpointReleased(BreakpointId id)
//QTC_ASSERT(state(id) == BreakpointChangeProceeding, /**/); //QTC_ASSERT(state(id) == BreakpointChangeProceeding, /**/);
Iterator it = m_storage.find(id); Iterator it = m_storage.find(id);
QTC_ASSERT(it != m_storage.end(), return); QTC_ASSERT(it != m_storage.end(), return);
it->data->setState(BreakpointNew); it->state = BreakpointNew;
it->data->setEngine(0); it->engine = 0;
it->response = BreakpointResponse();
delete it->marker; delete it->marker;
it->marker = 0; it->marker = 0;
delete it->response;
it->response = new BreakpointResponse();
updateMarker(id); updateMarker(id);
} }
@@ -792,15 +806,14 @@ BreakpointResponse BreakHandler::response(BreakpointId id) const
{ {
ConstIterator it = m_storage.find(id); ConstIterator it = m_storage.find(id);
QTC_ASSERT(it != m_storage.end(), return BreakpointResponse()); QTC_ASSERT(it != m_storage.end(), return BreakpointResponse());
return *it->response; return it->response;
} }
void BreakHandler::setResponse(BreakpointId id, const BreakpointResponse &data) void BreakHandler::setResponse(BreakpointId id, const BreakpointResponse &data)
{ {
Iterator it = m_storage.find(id); Iterator it = m_storage.find(id);
QTC_ASSERT(it != m_storage.end(), return); QTC_ASSERT(it != m_storage.end(), return);
delete it->response; it->response = BreakpointResponse(data);
it->response = new BreakpointResponse(data);
updateMarker(id); updateMarker(id);
} }
#if 0 #if 0
@@ -825,10 +838,6 @@ void BreakHandler::notifyBreakpointAdjusted(BreakpointId id)
void BreakHandler::BreakpointItem::destroy() void BreakHandler::BreakpointItem::destroy()
{ {
delete data;
data = 0;
delete response;
response = 0;
delete marker; delete marker;
marker = 0; marker = 0;
} }

View File

@@ -61,10 +61,12 @@ public:
QAbstractItemModel *model() { return this; } QAbstractItemModel *model() { return this; }
// The only way to add a new breakpoint.
void appendBreakpoint(const BreakpointData &data);
BreakpointIds allBreakpointIds() const; BreakpointIds allBreakpointIds() const;
BreakpointIds engineBreakpointIds(DebuggerEngine *engine) const; BreakpointIds engineBreakpointIds(DebuggerEngine *engine) const;
BreakpointIds unclaimedBreakpointIds() const; BreakpointIds unclaimedBreakpointIds() const;
BreakpointData *breakpointById(BreakpointId id) const;
int size() const { return m_storage.size(); } int size() const { return m_storage.size(); }
bool hasPendingBreakpoints() const; bool hasPendingBreakpoints() const;
@@ -107,13 +109,13 @@ public:
PROPERTY(QByteArray, condition, setCondition) PROPERTY(QByteArray, condition, setCondition)
PROPERTY(int, ignoreCount, setIgnoreCount) PROPERTY(int, ignoreCount, setIgnoreCount)
PROPERTY(QByteArray, threadSpec, setThreadSpec) PROPERTY(QByteArray, threadSpec, setThreadSpec)
PROPERTY(BreakpointState, state, setState)
PROPERTY(QString, fileName, setFileName) PROPERTY(QString, fileName, setFileName)
PROPERTY(QString, functionName, setFunctionName) PROPERTY(QString, functionName, setFunctionName)
PROPERTY(BreakpointType, type, setType); PROPERTY(BreakpointType, type, setType);
PROPERTY(quint64, address, setAddress); PROPERTY(quint64, address, setAddress);
PROPERTY(int, lineNumber, setLineNumber); PROPERTY(int, lineNumber, setLineNumber);
#undef PROPERTY #undef PROPERTY
BreakpointState state(BreakpointId id) const;
bool isEnabled(BreakpointId id) const; bool isEnabled(BreakpointId id) const;
void setEnabled(BreakpointId id, const bool &on); void setEnabled(BreakpointId id, const bool &on);
void updateEnabled(BreakpointId id, const bool &on); void updateEnabled(BreakpointId id, const bool &on);
@@ -137,12 +139,16 @@ public:
void notifyBreakpointRemoveFailed(BreakpointId id); void notifyBreakpointRemoveFailed(BreakpointId id);
void notifyBreakpointReleased(BreakpointId id); void notifyBreakpointReleased(BreakpointId id);
// This takes ownership. public:
void appendBreakpoint(BreakpointData *data); // FIXME: Make private.
void setState(BreakpointId id, BreakpointState state);
private: private:
friend class BreakpointMarker; friend class BreakpointMarker;
friend class BreakWindow; // FIXME: remove.
BreakpointData *breakpointById(BreakpointId id);
// QAbstractItemModel // QAbstractItemModel
int columnCount(const QModelIndex &parent) const; int columnCount(const QModelIndex &parent) const;
int rowCount(const QModelIndex &parent) const; int rowCount(const QModelIndex &parent) const;
@@ -164,10 +170,15 @@ private:
struct BreakpointItem struct BreakpointItem
{ {
BreakpointItem() : data(0), response(0), marker(0) {} BreakpointItem() : state(BreakpointNew), engine(0), marker(0) {}
void destroy(); void destroy();
BreakpointData *data; bool isPending() const { return state == BreakpointPending
BreakpointResponse *response; || state == BreakpointNew; }
BreakpointData data;
BreakpointState state; // Current state of breakpoint.
DebuggerEngine *engine; // Engine currently handling the breakpoint.
BreakpointResponse response;
BreakpointMarker *marker; BreakpointMarker *marker;
}; };
typedef QHash<BreakpointId, BreakpointItem> BreakpointStorage; typedef QHash<BreakpointId, BreakpointItem> BreakpointStorage;

View File

@@ -50,12 +50,10 @@ namespace Internal {
const char *BreakpointData::throwFunction = "throw"; const char *BreakpointData::throwFunction = "throw";
const char *BreakpointData::catchFunction = "catch"; const char *BreakpointData::catchFunction = "catch";
BreakpointData::BreakpointData() BreakpointData::BreakpointData(BreakpointType type)
{ {
m_state = BreakpointNew; m_type = type;
m_engine = 0;
m_enabled = true; m_enabled = true;
m_type = BreakpointByFileAndLine;
m_ignoreCount = 0; m_ignoreCount = 0;
m_lineNumber = 0; m_lineNumber = 0;
m_address = 0; m_address = 0;
@@ -91,7 +89,7 @@ bool BreakpointData::setFileName(const QString &file)
bool BreakpointData::setEnabled(bool on) bool BreakpointData::setEnabled(bool on)
{ SETIT(m_enabled, on); } { SETIT(m_enabled, on); }
bool BreakpointData::setIgnoreCount(bool count) bool BreakpointData::setIgnoreCount(int count)
{ SETIT(m_ignoreCount, count); } { SETIT(m_ignoreCount, count); }
bool BreakpointData::setFunctionName(const QString &name) bool BreakpointData::setFunctionName(const QString &name)
@@ -112,12 +110,6 @@ bool BreakpointData::setType(BreakpointType type)
bool BreakpointData::setCondition(const QByteArray &cond) bool BreakpointData::setCondition(const QByteArray &cond)
{ SETIT(m_condition, cond); } { SETIT(m_condition, cond); }
bool BreakpointData::setState(BreakpointState state)
{ SETIT(m_state, state); }
bool BreakpointData::setEngine(DebuggerEngine *engine)
{ SETIT(m_engine, engine); }
#undef SETIT #undef SETIT
@@ -156,10 +148,10 @@ QString BreakpointData::toToolTip() const
str << "<html><body><table>" str << "<html><body><table>"
//<< "<tr><td>" << tr("Id:") //<< "<tr><td>" << tr("Id:")
//<< "</td><td>" << m_id << "</td></tr>" //<< "</td><td>" << m_id << "</td></tr>"
<< "<tr><td>" << tr("State:") //<< "<tr><td>" << tr("State:")
<< "</td><td>" << m_state << "</td></tr>" //<< "</td><td>" << m_state << "</td></tr>"
<< "<tr><td>" << tr("Engine:") //<< "<tr><td>" << tr("Engine:")
<< "</td><td>" << m_engine << "</td></tr>" //<< "</td><td>" << m_engine << "</td></tr>"
<< "<tr><td>" << tr("Marker File:") << "<tr><td>" << tr("Marker File:")
<< "</td><td>" << QDir::toNativeSeparators(m_markerFileName) << "</td></tr>" << "</td><td>" << QDir::toNativeSeparators(m_markerFileName) << "</td></tr>"
<< "<tr><td>" << tr("Marker Line:") << "<tr><td>" << tr("Marker Line:")

View File

@@ -30,10 +30,10 @@
#ifndef DEBUGGER_BREAKPOINT_H #ifndef DEBUGGER_BREAKPOINT_H
#define DEBUGGER_BREAKPOINT_H #define DEBUGGER_BREAKPOINT_H
#include <QtCore/QMetaType>
#include <QtCore/QList>
#include <QtCore/QString>
#include <QtCore/QCoreApplication> #include <QtCore/QCoreApplication>
#include <QtCore/QList>
#include <QtCore/QMetaType>
#include <QtCore/QString>
namespace Debugger { namespace Debugger {
@@ -62,6 +62,8 @@ enum BreakpointType
BreakpointByFileAndLine, BreakpointByFileAndLine,
BreakpointByFunction, BreakpointByFunction,
BreakpointByAddress, BreakpointByAddress,
//BreakpointAtThrow, // FIXME: actually use this
//BreakpointAtCatch, // FIXME: actually use this
Watchpoint, Watchpoint,
}; };
@@ -82,21 +84,14 @@ enum BreakpointState
class BreakpointData class BreakpointData
{ {
private: private:
// Intentionally unimplemented. BreakpointData objects are supposed
// to be added to the BreakHandler soon after construction.
BreakpointData(const BreakpointData &);
void operator=(const BreakpointData &);
friend class BreakHandler; // This should be the only class manipulating data. friend class BreakHandler; // This should be the only class manipulating data.
friend class BreakWindow; // FIXME: Remove. friend class BreakWindow; // FIXME: Remove.
friend class BreakpointDialog; // FIXME: Remove. friend class BreakpointDialog; // FIXME: Remove.
friend QDataStream &operator>>(QDataStream& stream, BreakpointData &data); friend QDataStream &operator>>(QDataStream& stream, BreakpointData &data);
public: public:
BreakpointData(); explicit BreakpointData(BreakpointType = UnknownType);
bool isPending() const { return m_state == BreakpointPending
|| m_state == BreakpointNew; }
BreakpointType type() const { return m_type; } BreakpointType type() const { return m_type; }
quint64 address() const { return m_address; } quint64 address() const { return m_address; }
bool useFullPath() const { return m_useFullPath; } bool useFullPath() const { return m_useFullPath; }
@@ -106,7 +101,6 @@ public:
bool isLocatedAt(const QString &fileName, int lineNumber, bool isLocatedAt(const QString &fileName, int lineNumber,
bool useMarkerPosition) const; bool useMarkerPosition) const;
bool conditionsMatch(const QString &other) const; bool conditionsMatch(const QString &other) const;
BreakpointState state() const { return m_state; }
QString functionName() const { return m_functionName; } QString functionName() const { return m_functionName; }
QString markerFileName() const { return m_markerFileName; } QString markerFileName() const { return m_markerFileName; }
QString fileName() const { return m_fileName; } QString fileName() const { return m_fileName; }
@@ -116,7 +110,6 @@ public:
bool isEnabled() const { return m_enabled; } bool isEnabled() const { return m_enabled; }
QByteArray threadSpec() const { return m_threadSpec; } QByteArray threadSpec() const { return m_threadSpec; }
QByteArray condition() const { return m_condition; } QByteArray condition() const { return m_condition; }
DebuggerEngine *engine() const { return m_engine; }
bool isWatchpoint() const { return m_type == Watchpoint; } bool isWatchpoint() const { return m_type == Watchpoint; }
bool isBreakpoint() const { return m_type != Watchpoint; } // Enough for now. bool isBreakpoint() const { return m_type != Watchpoint; } // Enough for now.
@@ -131,21 +124,17 @@ private:
bool setMarkerLineNumber(int line); bool setMarkerLineNumber(int line);
bool setFileName(const QString &file); bool setFileName(const QString &file);
bool setEnabled(bool on); bool setEnabled(bool on);
bool setIgnoreCount(bool count); bool setIgnoreCount(int count);
bool setFunctionName(const QString &name); bool setFunctionName(const QString &name);
bool setLineNumber(int line); bool setLineNumber(int line);
bool setAddress(quint64 address); bool setAddress(quint64 address);
bool setThreadSpec(const QByteArray &spec); bool setThreadSpec(const QByteArray &spec);
bool setType(BreakpointType type); bool setType(BreakpointType type);
bool setCondition(const QByteArray &cond); bool setCondition(const QByteArray &cond);
bool setState(BreakpointState state);
bool setEngine(DebuggerEngine *engine);
private: private:
DebuggerEngine *m_engine;
BreakpointType m_type; // Type of breakpoint.
BreakpointState m_state; // Current state of breakpoint.
// This "user requested information" will get stored in the session. // This "user requested information" will get stored in the session.
BreakpointType m_type; // Type of breakpoint.
bool m_enabled; // Should we talk to the debugger engine? bool m_enabled; // Should we talk to the debugger engine?
bool m_useFullPath; // Should we use the full path when setting the bp? bool m_useFullPath; // Should we use the full path when setting the bp?
QString m_fileName; // Short name of source file. QString m_fileName; // Short name of source file.

View File

@@ -363,14 +363,13 @@ void BreakWindow::contextMenuEvent(QContextMenuEvent *ev)
else if (act == addBreakpointAction) else if (act == addBreakpointAction)
addBreakpoint(); addBreakpoint();
else if (act == breakAtThrowAction) { else if (act == breakAtThrowAction) {
// FIXME: Use the proper breakpoint type instead. BreakpointData data;
BreakpointData *data = new BreakpointData; data.setFunctionName(BreakpointData::throwFunction);
data->setFunctionName(BreakpointData::throwFunction);
handler->appendBreakpoint(data); handler->appendBreakpoint(data);
} else if (act == breakAtCatchAction) { } else if (act == breakAtCatchAction) {
// FIXME: Use the proper breakpoint type instead. // FIXME: Use the proper breakpoint type instead.
BreakpointData *data = new BreakpointData; BreakpointData data;
data->setFunctionName(BreakpointData::catchFunction); data.setFunctionName(BreakpointData::catchFunction);
handler->appendBreakpoint(data); handler->appendBreakpoint(data);
} }
} }
@@ -396,25 +395,18 @@ void BreakWindow::deleteBreakpoints(const QModelIndexList &list)
handler->removeBreakpoint(handler->findBreakpointByIndex(index)); handler->removeBreakpoint(handler->findBreakpointByIndex(index));
} }
static bool editBreakpointInternal(BreakpointData *data, QWidget *parent) void BreakWindow::editBreakpoint(BreakpointId id, QWidget *parent)
{ {
BreakpointDialog dialog(parent); BreakpointDialog dialog(parent);
return dialog.showDialog(data); dialog.showDialog(breakHandler()->breakpointById(id));
}
bool BreakWindow::editBreakpoint(BreakpointId id, QWidget *parent)
{
BreakpointDialog dialog(parent);
return dialog.showDialog(breakHandler()->breakpointById(id));
} }
void BreakWindow::addBreakpoint() void BreakWindow::addBreakpoint()
{ {
BreakpointData *data = new BreakpointData(); BreakpointData data;
if (editBreakpointInternal(data, this)) BreakpointDialog dialog(this);
if (dialog.showDialog(&data))
breakHandler()->appendBreakpoint(data); breakHandler()->appendBreakpoint(data);
else
delete data;
} }
void BreakWindow::editBreakpoints(const QModelIndexList &list) void BreakWindow::editBreakpoints(const QModelIndexList &list)

View File

@@ -45,7 +45,7 @@ public:
explicit BreakWindow(QWidget *parent = 0); explicit BreakWindow(QWidget *parent = 0);
~BreakWindow(); ~BreakWindow();
static bool editBreakpoint(BreakpointId id, QWidget *parent = 0); static void editBreakpoint(BreakpointId id, QWidget *parent);
private slots: private slots:
void resizeColumnsToContents(); void resizeColumnsToContents();