#include "breakhandler.h"
#include "debuggeractions.h"
-#include "debuggermanager.h"
+#include "debuggerengine.h"
+#include "debuggerplugin.h"
+#include "debuggerstringutils.h"
+#include "threadshandler.h"
+#include "stackhandler.h"
#include "stackframe.h"
#include <texteditor/basetextmark.h>
#include <utils/qtcassert.h>
+#include <QtCore/QByteArray>
#include <QtCore/QDebug>
#include <QtCore/QTextStream>
#include <QtCore/QFileInfo>
-using namespace Debugger;
-using namespace Debugger::Internal;
-
//////////////////////////////////////////////////////////////////
//
// Compare file names case insensitively on Windows.
static inline bool fileNameMatch(const QString &f1, const QString &f2)
{
- return f1.compare(f2,
#ifdef Q_OS_WIN
- Qt::CaseInsensitive
+ return f1.compare(f2, Qt::CaseInsensitive) == 0;
#else
- Qt::CaseSensitive
+ return f1 == f2;
#endif
- ) == 0;
}
namespace Debugger {
namespace Internal {
+static DebuggerPlugin *plugin() { return DebuggerPlugin::instance(); }
+
// The red blob on the left side in the cpp editor.
class BreakpointMarker : public TextEditor::BaseTextMark
{
QIcon icon() const
{
- const BreakHandler *handler = DebuggerManager::instance()->breakHandler();
+ const BreakHandler *handler = m_data->handler();
if (!m_enabled)
return handler->disabledBreakpointIcon();
return m_pending ? handler->pendingBreakPointIcon() : handler->breakpointIcon();
return;
BreakHandler *handler = m_data->handler();
- handler->removeBreakpoint(handler->indexOf(m_data));
- handler->saveBreakpoints();
+ handler->removeBreakpoint(m_data);
+ //handler->saveBreakpoints();
handler->updateMarkers();
}
}
// Ignore updates to the "real" line number while the debugger is
// 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?
if (m_data->bpNumber.trimmed().isEmpty()) {
m_data->lineNumber = QByteArray::number(lineNumber);
bool m_enabled;
};
-} // namespace Internal
-} // namespace Debugger
-
-
//////////////////////////////////////////////////////////////////
//
//
//////////////////////////////////////////////////////////////////
-BreakpointData::BreakpointData(BreakHandler *handler)
+BreakpointData::BreakpointData()
{
- //qDebug() << "CREATE BREAKPOINTDATA" << this;
- m_handler = handler;
+ m_handler = 0;
enabled = true;
pending = true;
+ type = BreakpointType;
marker = 0;
m_markerLineNumber = 0;
bpMultiple = false;
-//#if defined(Q_OS_MAC)
-// // full names do not work on Mac/MI
+ bpEnabled = true;
useFullPath = false;
-//#else
-// //where = m_manager->shortName(data->fileName);
-// useFullPath = true;
-//#endif
+}
+
+BreakpointData *BreakpointData::clone() const
+{
+ BreakpointData *data = new BreakpointData();
+ data->m_handler = m_handler;
+ data->m_markerFileName = m_markerFileName;
+ data->m_markerLineNumber = m_markerLineNumber;
+ data->enabled = enabled;
+ data->type = type;
+ data->fileName = fileName;
+ data->condition = condition;
+ data->ignoreCount = ignoreCount;
+ data->lineNumber = lineNumber;
+ data->address = address;
+ data->threadSpec = threadSpec;
+ data->funcName = funcName;
+ data->useFullPath = useFullPath;
+ return data;
}
BreakpointData::~BreakpointData()
{
removeMarker();
- //qDebug() << "DESTROY BREAKPOINTDATA" << this;
}
void BreakpointData::removeMarker()
<< "</td><td>" << m_markerLineNumber << "</td></tr>"
<< "<tr><td>" << BreakHandler::tr("Breakpoint Number:")
<< "</td><td>" << bpNumber << "</td></tr>"
- << "<tr><td>" << BreakHandler::tr("Breakpoint Address:")
- << "</td><td>" << bpAddress << "</td></tr>"
+ << "<tr><td>" << BreakHandler::tr("Breakpoint Type:")
+ << "</td><td>"
+ << (type == BreakpointType ? BreakHandler::tr("Breakpoint")
+ : type == WatchpointType ? BreakHandler::tr("Watchpoint")
+ : BreakHandler::tr("Unknown breakpoint type"))
+ << "</td></tr>"
<< "</table><br><hr><table>"
<< "<tr><th>" << BreakHandler::tr("Property")
<< "</th><th>" << BreakHandler::tr("Requested")
<< "</td><td>" << funcName << "</td><td>" << bpFuncName << "</td></tr>"
<< "<tr><td>" << BreakHandler::tr("Line Number:")
<< "</td><td>" << lineNumber << "</td><td>" << bpLineNumber << "</td></tr>"
+ << "<tr><td>" << BreakHandler::tr("Breakpoint Address:")
+ << "</td><td>" << address << "</td><td>" << bpAddress << "</td></tr>"
<< "<tr><td>" << BreakHandler::tr("Corrected Line Number:")
<< "</td><td>-</td><td>" << bpCorrectedLineNumber << "</td></tr>"
<< "<tr><td>" << BreakHandler::tr("Condition:")
<< "</td><td>" << condition << "</td><td>" << bpCondition << "</td></tr>"
<< "<tr><td>" << BreakHandler::tr("Ignore Count:")
<< "</td><td>" << ignoreCount << "</td><td>" << bpIgnoreCount << "</td></tr>"
+ << "<tr><td>" << BreakHandler::tr("Thread Specification:")
+ << "</td><td>" << threadSpec << "</td><td>" << bpThreadSpec << "</td></tr>"
<< "</table></body></html>";
return rc;
}
{
QString rc;
QTextStream str(&rc);
- str << BreakHandler::tr("Marker File:") << m_markerFileName << ' '
- << BreakHandler::tr("Marker Line:") << m_markerLineNumber << ' '
- << BreakHandler::tr("Breakpoint Number:") << bpNumber << ' '
- << BreakHandler::tr("Breakpoint Address:") << bpAddress << '\n'
- << BreakHandler::tr("File Name:")
+ str << BreakHandler::tr("Marker File:") << ' ' << m_markerFileName << '\n'
+ << BreakHandler::tr("Marker Line:") << ' ' << m_markerLineNumber << '\n'
+ << BreakHandler::tr("Breakpoint Number:") << ' ' << bpNumber << '\n'
+ << BreakHandler::tr("Breakpoint Type:") << ' '
+ << (type == BreakpointType ? BreakHandler::tr("Breakpoint")
+ : type == WatchpointType ? BreakHandler::tr("Watchpoint")
+ : BreakHandler::tr("Unknown breakpoint type")) << '\n'
+ << BreakHandler::tr("File Name:") << ' '
<< fileName << " -- " << bpFileName << '\n'
- << BreakHandler::tr("Function Name:")
+ << BreakHandler::tr("Function Name:") << ' '
<< funcName << " -- " << bpFuncName << '\n'
- << BreakHandler::tr("Line Number:")
+ << BreakHandler::tr("Line Number:") << ' '
<< lineNumber << " -- " << bpLineNumber << '\n'
- << BreakHandler::tr("Condition:")
+ << BreakHandler::tr("Breakpoint Address:") << ' '
+ << address << " -- " << bpAddress << '\n'
+ << BreakHandler::tr("Condition:") << ' '
<< condition << " -- " << bpCondition << '\n'
- << BreakHandler::tr("Ignore Count:")
- << ignoreCount << " -- " << bpIgnoreCount << '\n';
+ << BreakHandler::tr("Ignore Count:") << ' '
+ << ignoreCount << " -- " << bpIgnoreCount << '\n'
+ << BreakHandler::tr("Thread Specification:") << ' '
+ << threadSpec << " -- " << bpThreadSpec << '\n';
return rc;
}
&& fileNameMatch(fileName_, m_markerFileName);
}
+bool BreakpointData::isSimilarTo(const BreakpointData *needle) const
+{
+ //qDebug() << "COMPARING " << toString() << " WITH " << needle->toString();
+
+ // Clear hit.
+ if (bpNumber == needle->bpNumber
+ && !bpNumber.isEmpty()
+ && bpNumber.toInt() != 0)
+ return true;
+
+ // Clear miss.
+ if (type != needle->type)
+ return false;
+
+ // We have numbers, but they are different.
+ if (!bpNumber.isEmpty() && !needle->bpNumber.isEmpty()
+ && !bpNumber.startsWith(needle->bpNumber)
+ && !needle->bpNumber.startsWith(bpNumber))
+ return false;
+
+ // At least at a position we were looking for.
+ // FIXME: breaks multiple breakpoints at the same location
+ if (!fileName.isEmpty()
+ && fileNameMatch(fileName, needle->fileName)
+ && lineNumber == needle->lineNumber)
+ return true;
+
+ // At least at a position we were looking for.
+ // FIXME: breaks multiple breakpoints at the same location
+ if (!fileName.isEmpty()
+ && fileNameMatch(fileName, needle->bpFileName)
+ && lineNumber == needle->bpLineNumber)
+ return true;
+
+ return false;
+}
+
bool BreakpointData::conditionsMatch() const
{
// Some versions of gdb "beautify" the passed condition.
//
//////////////////////////////////////////////////////////////////
-BreakHandler::BreakHandler(DebuggerManager *manager, QObject *parent) :
- QAbstractTableModel(parent),
- m_breakpointIcon(QLatin1String(":/debugger/images/breakpoint_16.png")),
- m_disabledBreakpointIcon(QLatin1String(":/debugger/images/breakpoint_disabled_16.png")),
- m_pendingBreakPointIcon(QLatin1String(":/debugger/images/breakpoint_pending_16.png")),
- m_manager(manager)
+BreakHandler::BreakHandler(DebuggerEngine *engine)
+ : m_breakpointIcon(_(":/debugger/images/breakpoint_16.png")),
+ m_disabledBreakpointIcon(_(":/debugger/images/breakpoint_disabled_16.png")),
+ m_pendingBreakPointIcon(_(":/debugger/images/breakpoint_pending_16.png")),
+ m_watchpointIcon(_(":/debugger/images/watchpoint.png")),
+ m_engine(engine),
+ m_lastFound(0),
+ m_lastFoundQueried(false)
{
+ QTC_ASSERT(m_engine, /**/);
}
BreakHandler::~BreakHandler()
int BreakHandler::columnCount(const QModelIndex &parent) const
{
- return parent.isValid() ? 0 : 7;
+ return parent.isValid() ? 0 : 8;
}
int BreakHandler::rowCount(const QModelIndex &parent) const
m_inserted.clear();
}
-int BreakHandler::findBreakpoint(const BreakpointData &needle) const
+BreakpointData *BreakHandler::findSimilarBreakpoint(const BreakpointData *needle) const
{
// Search a breakpoint we might refer to.
for (int index = 0; index != size(); ++index) {
- const BreakpointData *data = at(index);
- // Clear hit.
- if (data->bpNumber == needle.bpNumber)
- return index;
- // At least at a position we were looking for.
- // FIXME: breaks multiple breakpoints at the same location
- if (fileNameMatch(data->fileName, needle.bpFileName)
- && data->lineNumber == needle.bpLineNumber)
- return index;
+ BreakpointData *data = m_bp[index];
+ if (data->isSimilarTo(needle))
+ return data;
}
- return -1;
-}
-
-int BreakHandler::findBreakpoint(const QString &fileName, int lineNumber) const
-{
- if (lineNumber <= 0) {
- QByteArray address = fileName.toLatin1();
- for (int index = 0; index != size(); ++index)
- if (at(index)->bpAddress == address)
- return index;
- } else {
- for (int index = 0; index != size(); ++index)
- if (at(index)->isLocatedAt(fileName, lineNumber))
- return index;
- }
- return -1;
+ return 0;
}
-BreakpointData *BreakHandler::findBreakpoint(int bpNumber) const
+BreakpointData *BreakHandler::findBreakpointByNumber(int bpNumber) const
{
if (!size())
return 0;
return 0;
}
+int BreakHandler::findWatchPointIndexByAddress(const QByteArray &a) const
+{
+ for (int index = size() - 1; index >= 0; --index) {
+ BreakpointData *bd = at(index);
+ if (bd->type == BreakpointData::WatchpointType && bd->address == a)
+ return index;
+ }
+ return -1;
+}
+
+bool BreakHandler::watchPointAt(quint64 address) const
+{
+ const QByteArray addressBA = QByteArray("0x") + QByteArray::number(address, 16);
+ return findWatchPointIndexByAddress(addressBA) != -1;
+}
+
void BreakHandler::saveBreakpoints()
{
+ //qDebug() << "SAVING BREAKPOINTS...";
+ QTC_ASSERT(plugin(), return);
QList<QVariant> list;
for (int index = 0; index != size(); ++index) {
const BreakpointData *data = at(index);
QMap<QString, QVariant> map;
+ // Do not persist Watchpoints.
+ //if (data->type == BreakpointData::WatchpointType)
+ // continue;
+ if (data->type != BreakpointData::BreakpointType)
+ map.insert(_("type"), data->type);
if (!data->fileName.isEmpty())
- map.insert(QLatin1String("filename"), data->fileName);
+ map.insert(_("filename"), data->fileName);
if (!data->lineNumber.isEmpty())
- map.insert(QLatin1String("linenumber"), data->lineNumber);
+ map.insert(_("linenumber"), data->lineNumber);
if (!data->funcName.isEmpty())
- map.insert(QLatin1String("funcname"), data->funcName);
+ map.insert(_("funcname"), data->funcName);
+ if (!data->address.isEmpty())
+ map.insert(_("address"), data->address);
if (!data->condition.isEmpty())
- map.insert(QLatin1String("condition"), data->condition);
+ map.insert(_("condition"), data->condition);
if (!data->ignoreCount.isEmpty())
- map.insert(QLatin1String("ignorecount"), data->ignoreCount);
+ map.insert(_("ignorecount"), data->ignoreCount);
+ if (!data->threadSpec.isEmpty())
+ map.insert(_("threadspec"), data->threadSpec);
if (!data->enabled)
- map.insert(QLatin1String("disabled"), QLatin1String("1"));
+ map.insert(_("disabled"), _("1"));
if (data->useFullPath)
- map.insert(QLatin1String("usefullpath"), QLatin1String("1"));
+ map.insert(_("usefullpath"), _("1"));
list.append(map);
}
- m_manager->setSessionValue("Breakpoints", list);
+ plugin()->setSessionValue("Breakpoints", list);
+ //qDebug() << "SAVED BREAKPOINTS" << this << list.size();
}
void BreakHandler::loadBreakpoints()
{
- QVariant value = m_manager->sessionValue("Breakpoints");
+ QTC_ASSERT(plugin(), return);
+ //qDebug() << "LOADING BREAKPOINTS...";
+ QVariant value = plugin()->sessionValue("Breakpoints");
QList<QVariant> list = value.toList();
clear();
foreach (const QVariant &var, list) {
const QMap<QString, QVariant> map = var.toMap();
- BreakpointData *data = new BreakpointData(this);
- QVariant v = map.value(QLatin1String("filename"));
+ BreakpointData *data = new BreakpointData;
+ QVariant v = map.value(_("filename"));
if (v.isValid())
data->fileName = v.toString();
- v = map.value(QLatin1String("linenumber"));
+ v = map.value(_("linenumber"));
if (v.isValid())
data->lineNumber = v.toString().toLatin1();
- v = map.value(QLatin1String("condition"));
+ v = map.value(_("condition"));
if (v.isValid())
data->condition = v.toString().toLatin1();
- v = map.value(QLatin1String("ignorecount"));
+ v = map.value(_("address"));
+ if (v.isValid())
+ data->address = v.toString().toLatin1();
+ v = map.value(_("ignorecount"));
if (v.isValid())
data->ignoreCount = v.toString().toLatin1();
- v = map.value(QLatin1String("funcname"));
+ v = map.value(_("threadspec"));
+ if (v.isValid())
+ data->threadSpec = v.toString().toLatin1();
+ v = map.value(_("funcname"));
if (v.isValid())
data->funcName = v.toString();
- v = map.value(QLatin1String("disabled"));
+ v = map.value(_("disabled"));
if (v.isValid())
data->enabled = !v.toInt();
- v = map.value(QLatin1String("usefullpath"));
+ v = map.value(_("usefullpath"));
if (v.isValid())
data->useFullPath = bool(v.toInt());
+ v = map.value(_("type"));
+ if (v.isValid())
+ data->type = BreakpointData::Type(v.toInt());
data->setMarkerFileName(data->fileName);
data->setMarkerLineNumber(data->lineNumber.toInt());
append(data);
}
-}
-
-void BreakHandler::resetBreakpoints()
-{
- for (int index = size(); --index >= 0;) {
- BreakpointData *data = at(index);
- data->pending = true;
- data->bpMultiple = false;
- data->bpEnabled = true;
- data->bpNumber.clear();
- data->bpFuncName.clear();
- data->bpFileName.clear();
- data->bpLineNumber.clear();
- data->bpCorrectedLineNumber.clear();
- data->bpCondition.clear();
- data->bpIgnoreCount.clear();
- data->bpAddress.clear();
- // Keep marker data if it was primary.
- if (data->markerFileName() != data->fileName)
- data->setMarkerFileName(QString());
- if (data->markerLineNumber() != data->lineNumber.toInt())
- data->setMarkerLineNumber(0);
- }
- m_enabled.clear();
- m_disabled.clear();
- m_removed.clear();
- m_inserted.clear();
+ //qDebug() << "LOADED BREAKPOINTS" << this << list.size();
}
void BreakHandler::updateMarkers()
if (orientation == Qt::Horizontal && role == Qt::DisplayRole) {
static QString headers[] = {
tr("Number"), tr("Function"), tr("File"), tr("Line"),
- tr("Condition"), tr("Ignore"), tr("Address")
+ tr("Condition"), tr("Ignore"), tr("Threads"), tr("Address")
};
return headers[section];
}
{
static const QString empty = QString(QLatin1Char('-'));
- QTC_ASSERT(mi.isValid(), return QVariant());
+ switch (role) {
+ case CurrentThreadIdRole:
+ QTC_ASSERT(m_engine, return QVariant());
+ return m_engine->threadsHandler()->currentThreadId();
+
+ case EngineActionsEnabledRole:
+ QTC_ASSERT(m_engine, return QVariant());
+ return m_engine->debuggerActionsEnabled();
+
+ case EngineCapabilitiesRole:
+ QTC_ASSERT(m_engine, return QVariant());
+ return m_engine->debuggerCapabilities();
+
+ default:
+ break;
+ }
+ QTC_ASSERT(mi.isValid(), return QVariant());
if (mi.row() >= size())
return QVariant();
const BreakpointData *data = at(mi.row());
+
+ if (role == BreakpointUseFullPathRole)
+ return data->useFullPath;
+
+ if (role == BreakpointFileNameRole)
+ return data->fileName;
+
+ if (role == BreakpointEnabledRole)
+ return data->enabled;
+
+ if (role == BreakpointFunctionNameRole)
+ return data->funcName;
+
switch (mi.column()) {
case 0:
if (role == Qt::DisplayRole) {
const QString str = data->bpNumber;
return str.isEmpty() ? empty : str;
}
- if (role == Qt::UserRole)
- return data->enabled;
if (role == Qt::DecorationRole) {
+ if (data->type == BreakpointData::WatchpointType)
+ return m_watchpointIcon;
if (!data->enabled)
return m_disabledBreakpointIcon;
return data->pending ? m_pendingBreakPointIcon : m_breakpointIcon;
str = "/.../" + str;
return str;
}
- if (role == Qt::UserRole)
- return data->useFullPath;
break;
case 3:
if (role == Qt::DisplayRole) {
const QString str = data->pending ? data->lineNumber : data->bpLineNumber;
return str.isEmpty() ? empty : str;
}
+ if (role == Qt::UserRole + 1)
+ return data->lineNumber;
break;
case 4:
if (role == Qt::DisplayRole)
return data->pending ? data->condition : data->bpCondition;
if (role == Qt::ToolTipRole)
return tr("Breakpoint will only be hit if this condition is met.");
+ if (role == Qt::UserRole + 1)
+ return data->condition;
break;
case 5:
if (role == Qt::DisplayRole)
return data->pending ? data->ignoreCount : data->bpIgnoreCount;
if (role == Qt::ToolTipRole)
return tr("Breakpoint will only be hit after being ignored so many times.");
+ if (role == Qt::UserRole + 1)
+ return data->ignoreCount;
+ break;
case 6:
- if (role == Qt::DisplayRole)
+ if (role == Qt::DisplayRole) {
+ if (data->pending)
+ return !data->threadSpec.isEmpty() ? data->threadSpec : tr("(all)");
+ else
+ return !data->bpThreadSpec.isEmpty() ? data->bpThreadSpec : tr("(all)");
+ }
+ if (role == Qt::ToolTipRole)
+ return tr("Breakpoint will only be hit in the specified thread(s).");
+ if (role == Qt::UserRole + 1)
+ return data->threadSpec;
+ break;
+ case 7:
+ if (role == Qt::DisplayRole) {
+ if (data->type == BreakpointData::WatchpointType)
+ return data->address;
return data->bpAddress;
+ }
break;
}
if (role == Qt::ToolTipRole)
return QVariant();
}
-Qt::ItemFlags BreakHandler::flags(const QModelIndex &mi) const
+Qt::ItemFlags BreakHandler::flags(const QModelIndex &index) const
{
- //switch (mi.column()) {
- //case 0:
- // return Qt::ItemIsUserCheckable | Qt::ItemIsEnabled;
- //default:
- return QAbstractTableModel::flags(mi);
- //}
+// switch (index.column()) {
+// //case 0:
+// // return Qt::ItemIsUserCheckable | Qt::ItemIsEnabled;
+// default:
+ return QAbstractTableModel::flags(index);
+// }
}
-bool BreakHandler::setData(const QModelIndex &mi, const QVariant &value, int role)
+bool BreakHandler::setData(const QModelIndex &index, const QVariant &value, int role)
{
- if (role != Qt::EditRole)
- return false;
+ switch (role) {
+ case RequestActivateBreakpointRole: {
+ const BreakpointData *data = at(value.toInt());
+ QTC_ASSERT(data, return false);
+ m_engine->gotoLocation(data->markerFileName(),
+ data->markerLineNumber(), false);
+ return true;
+ }
- BreakpointData *data = at(mi.row());
- switch (mi.column()) {
- case 0: {
+ case RequestRemoveBreakpointByIndexRole: {
+ BreakpointData *data = at(value.toInt());
+ QTC_ASSERT(data, return false);
+ removeBreakpoint(data);
+ return true;
+ }
+
+ case RequestSynchronizeBreakpointsRole:
+ QTC_ASSERT(m_engine, return false);
+ m_engine->attemptBreakpointSynchronization();
+ return true;
+
+ case RequestBreakByFunctionRole:
+ QTC_ASSERT(m_engine, return false);
+ m_engine->breakByFunction(value.toString());
+ return true;
+
+ case RequestBreakByFunctionMainRole:
+ QTC_ASSERT(m_engine, return false);
+ m_engine->breakByFunctionMain();
+ return true;
+ }
+
+ BreakpointData *data = at(index.row());
+
+ switch (role) {
+ case BreakpointEnabledRole:
if (data->enabled != value.toBool()) {
toggleBreakpointEnabled(data);
- dataChanged(mi, mi);
+ layoutChanged();
}
return true;
- }
- case 2: {
+
+ case BreakpointUseFullPathRole:
if (data->useFullPath != value.toBool()) {
data->useFullPath = value.toBool();
- dataChanged(mi, mi);
+ layoutChanged();
}
return true;
- }
- case 4: {
+
+ /*
QString val = value.toString();
- if (val != data->condition) {
- data->condition = val.toLatin1();
- dataChanged(mi, mi);
+ if (data->funcName != val) {
+ data->funcName = val;
+ layoutChanged();
}
return true;
- }
- case 5: {
+
QString val = value.toString();
- if (val != data->ignoreCount) {
- data->ignoreCount = val.toLatin1();
- dataChanged(mi, mi);
+ if (data->fileName != val) {
+ data->fileName = val;
+ layoutChanged();
+ }
+ return true;
+
+ QByteArray val = value.toString().toLatin1();
+ if (data->lineNumber != val) {
+ data->lineNumber = val;
+ layoutChanged();
+ }
+ return true;
+ */
+ case BreakpointConditionRole: {
+ QByteArray val = value.toString().toLatin1();
+ if (val != data->condition) {
+ data->condition = val;
+ layoutChanged();
+ }
+ }
+ return true;
+
+ case BreakpointIgnoreCountRole: {
+ QByteArray val = value.toString().toLatin1();
+ if (val != data->ignoreCount) {
+ data->ignoreCount = val;
+ layoutChanged();
+ }
+ }
+ return true;
+
+ case BreakpointThreadSpecRole: {
+ QByteArray val = value.toString().toLatin1();
+ if (val != data->threadSpec) {
+ data->threadSpec = val;
+ layoutChanged();
+ }
}
return true;
- }
- default: {
- return false;
- }
}
+ return false;
}
void BreakHandler::append(BreakpointData *data)
{
+ data->m_handler = this;
m_bp.append(data);
m_inserted.append(data);
}
-QList<BreakpointData *> BreakHandler::insertedBreakpoints() const
+Breakpoints BreakHandler::insertedBreakpoints() const
{
return m_inserted;
}
m_inserted.removeAll(d);
}
-QList<BreakpointData *> BreakHandler::takeRemovedBreakpoints()
+Breakpoints BreakHandler::takeRemovedBreakpoints()
{
- QList<BreakpointData *> result = m_removed;
+ Breakpoints result = m_removed;
m_removed.clear();
return result;
}
-QList<BreakpointData *> BreakHandler::takeEnabledBreakpoints()
+Breakpoints BreakHandler::takeEnabledBreakpoints()
{
- QList<BreakpointData *> result = m_enabled;
+ Breakpoints result = m_enabled;
m_enabled.clear();
return result;
}
-QList<BreakpointData *> BreakHandler::takeDisabledBreakpoints()
+Breakpoints BreakHandler::takeDisabledBreakpoints()
{
- QList<BreakpointData *> result = m_disabled;
+ Breakpoints result = m_disabled;
m_disabled.clear();
return result;
}
return;
removeBreakpointHelper(index);
emit layoutChanged();
- saveBreakpoints();
+}
+
+void BreakHandler::removeBreakpoint(BreakpointData *data)
+{
+ removeBreakpointHelper(m_bp.indexOf(data));
+ emit layoutChanged();
}
void BreakHandler::toggleBreakpointEnabled(BreakpointData *data)
m_enabled.removeAll(data);
m_disabled.append(data);
}
- saveBreakpoints();
updateMarkers();
}
{
append(data);
emit layoutChanged();
- saveBreakpoints();
+ saveBreakpoints(); // FIXME: remove?
updateMarkers();
}
for (int index = size(); --index >= 0;)
removeBreakpointHelper(index);
emit layoutChanged();
- saveBreakpoints();
updateMarkers();
}
-void BreakHandler::setAllPending()
+BreakpointData *BreakHandler::findBreakpoint(const QString &fileName, int lineNumber)
{
- loadBreakpoints();
- for (int index = size(); --index >= 0;)
- at(index)->pending = true;
- saveBreakpoints();
- updateMarkers();
+ foreach (BreakpointData *data, m_bp)
+ if (data->isLocatedAt(fileName, lineNumber))
+ return data;
+ return 0;
+}
+
+void BreakHandler::toggleBreakpoint(const QString &fileName, int lineNumber)
+{
+ BreakpointData *data = findBreakpoint(fileName, lineNumber);
+ if (data) {
+ removeBreakpoint(data);
+ } else {
+ data = new BreakpointData;
+ data->fileName = fileName;
+ data->lineNumber = QByteArray::number(lineNumber);
+ data->pending = true;
+ data->setMarkerFileName(fileName);
+ data->setMarkerLineNumber(lineNumber);
+ appendBreakpoint(data);
+ m_engine->attemptBreakpointSynchronization();
+ }
+}
+
+void BreakHandler::toggleBreakpointEnabled(const QString &fileName, int lineNumber)
+{
+ BreakpointData *data = findBreakpoint(fileName, lineNumber);
+ QTC_ASSERT(data, return);
+ data->enabled = !data->enabled;
+ data->updateMarker();
+ m_engine->attemptBreakpointSynchronization();
}
void BreakHandler::saveSessionData()
{
+ QTC_ASSERT(m_engine->isSessionEngine(), return);
saveBreakpoints();
- updateMarkers();
}
void BreakHandler::loadSessionData()
{
- //resetBreakpoints();
+ QTC_ASSERT(m_engine->isSessionEngine(), return);
loadBreakpoints();
updateMarkers();
}
&& data->ignoreCount.isEmpty())
return;
}
- BreakpointData *data = new BreakpointData(this);
+ BreakpointData *data = new BreakpointData;
data->funcName = functionName;
append(data);
- saveBreakpoints();
+ //saveBreakpoints();
updateMarkers();
}
+void BreakHandler::initializeFromTemplate(BreakHandler *other)
+{
+ //qDebug() << "COPYING BREAKPOINTS INTO NEW SESSION";
+ QTC_ASSERT(m_bp.isEmpty(), /**/);
+ foreach (BreakpointData *data, other->m_bp) {
+ append(data->clone());
+ data->removeMarker();
+ }
+ updateMarkers();
+}
+
+void BreakHandler::storeToTemplate(BreakHandler *other)
+{
+ other->removeAllBreakpoints();
+ foreach (BreakpointData *data, m_bp)
+ other->append(data->clone());
+ removeAllBreakpoints();
+ other->updateMarkers();
+ other->saveSessionData();
+}
+
+} // namespace Internal
+} // namespace Debugger
+
#include "breakhandler.moc"