Files
qt-creator/src/plugins/debugger/breakwindow.cpp

694 lines
24 KiB
C++
Raw Normal View History

/**************************************************************************
2008-12-02 12:01:29 +01:00
**
** This file is part of Qt Creator
**
2011-01-11 16:28:15 +01:00
** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
2008-12-02 12:01:29 +01:00
**
** Contact: Nokia Corporation (qt-info@nokia.com)
2008-12-02 12:01:29 +01:00
**
2010-12-17 16:01:08 +01:00
** No Commercial Usage
**
2010-12-17 16:01:08 +01:00
** This file contains pre-release code and may not be distributed.
** You may use this file in accordance with the terms and conditions
** contained in the Technology Preview License Agreement accompanying
** this package.
**
** GNU Lesser General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
2010-12-17 16:01:08 +01:00
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
2008-12-02 12:01:29 +01:00
**
**************************************************************************/
2008-12-02 15:08:31 +01:00
2008-12-02 12:01:29 +01:00
#include "breakwindow.h"
#include "breakhandler.h"
2008-12-02 12:01:29 +01:00
#include "debuggeractions.h"
#include "debuggercore.h"
#include "ui_breakpoint.h"
2008-12-02 12:01:29 +01:00
#include "ui_breakcondition.h"
#include <utils/pathchooser.h>
#include <utils/qtcassert.h>
#include <utils/savedaction.h>
#include <QtCore/QDebug>
#include <QtGui/QAction>
#include <QtGui/QIntValidator>
#include <QtGui/QKeyEvent>
#include <QtGui/QMenu>
2008-12-02 12:01:29 +01:00
namespace Debugger {
namespace Internal {
2008-12-02 12:01:29 +01:00
///////////////////////////////////////////////////////////////////////
//
// BreakpointDialog: Show a dialog for editing breakpoints. Shows controls
// for the file-and-line, function and address parameters depending on the
// breakpoint type. The controls not applicable to the current type
// (say function name for file-and-line) are disabled and cleared out.
// However,the values are saved and restored once the respective mode
// is again choosen, which is done using m_savedParameters and
// setters/getters taking the parts mask enumeration parameter.
//
///////////////////////////////////////////////////////////////////////
class BreakpointDialog : public QDialog
{
Q_OBJECT
public:
explicit BreakpointDialog(QWidget *parent);
2010-11-16 10:50:11 +01:00
bool showDialog(BreakpointParameters *data);
2010-11-25 14:47:56 +01:00
void setParameters(const BreakpointParameters &data);
BreakpointParameters parameters() const;
public slots:
void typeChanged(int index);
private:
2010-11-25 14:47:56 +01:00
enum DialogPart {
FileAndLinePart = 0x1,
FunctionPart = 0x2,
AddressPart = 0x4,
ConditionPart = 0x8,
ModulePart = 0x10,
AllParts = FileAndLinePart|FunctionPart|AddressPart|ConditionPart|ModulePart
2010-11-25 14:47:56 +01:00
};
void setPartsEnabled(unsigned partsMask);
void clearOtherParts(unsigned partsMask);
2010-11-25 14:47:56 +01:00
void getParts(unsigned partsMask, BreakpointParameters *data) const;
void setParts(unsigned partsMask, const BreakpointParameters &data);
void setType(BreakpointType type);
BreakpointType type() const;
Ui::BreakpointDialog m_ui;
BreakpointParameters m_savedParameters;
BreakpointType m_previousType;
bool m_firstTypeChange;
};
2010-11-25 14:47:56 +01:00
BreakpointDialog::BreakpointDialog(QWidget *parent)
: QDialog(parent), m_previousType(UnknownType), m_firstTypeChange(true)
{
setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
2010-11-25 14:47:56 +01:00
// Match BreakpointType (omitting unknown type).
m_ui.setupUi(this);
QStringList types;
types << tr("File and Line Number") << tr("Function Name") << tr("Address")
<< tr("throw") << tr("catch") << tr("Function \"main()\"")
<< tr("Address (Watchpoint)");
QTC_ASSERT(types.size() == Watchpoint, return; )
m_ui.comboBoxType->addItems(types);
m_ui.pathChooserFileName->setExpectedKind(Utils::PathChooser::File);
connect(m_ui.comboBoxType, SIGNAL(activated(int)), SLOT(typeChanged(int)));
const QString moduleToolTip =
tr("Specifying the module (base name of the library or executable)\n"
"for function or file type breakpoints can significantly speed up\n"
"debugger start-up times (CDB, LLDB).");
m_ui.labelModule->setToolTip(moduleToolTip);
m_ui.lineEditModule->setToolTip(moduleToolTip);
const QString commandToolTip =
tr("Debugger command to be executed when the breakpoint is hit.\n"
"gdb allows for specifying a sequence of commands separated by the delimiter '\\n'.");
m_ui.lineEditCommand->setToolTip(commandToolTip);
m_ui.labelCommand->setToolTip(commandToolTip);
m_ui.spinBoxIgnoreCount->setMinimum(0);
m_ui.spinBoxIgnoreCount->setMaximum(2147483647);
}
void BreakpointDialog::setType(BreakpointType type)
{
2010-11-25 14:47:56 +01:00
const int comboIndex = type - 1; // Skip UnknownType.
if (comboIndex != m_ui.comboBoxType->currentIndex() || m_firstTypeChange) {
m_ui.comboBoxType->setCurrentIndex(comboIndex);
typeChanged(comboIndex);
m_firstTypeChange = false;
}
}
BreakpointType BreakpointDialog::type() const
{
2010-11-25 14:47:56 +01:00
const int type = m_ui.comboBoxType->currentIndex() + 1; // Skip unknown type.
return static_cast<BreakpointType>(type);
}
2010-11-25 14:47:56 +01:00
void BreakpointDialog::setParameters(const BreakpointParameters &data)
{
2010-11-25 14:47:56 +01:00
m_savedParameters = data;
setType(data.type);
setParts(AllParts, data);
}
BreakpointParameters BreakpointDialog::parameters() const
{
2010-11-25 14:47:56 +01:00
BreakpointParameters data(type());
getParts(AllParts, &data);
return data;
}
void BreakpointDialog::setPartsEnabled(unsigned partsMask)
{
m_ui.labelFileName->setEnabled(partsMask & FileAndLinePart);
m_ui.pathChooserFileName->setEnabled(partsMask & FileAndLinePart);
m_ui.labelLineNumber->setEnabled(partsMask & FileAndLinePart);
m_ui.lineEditLineNumber->setEnabled(partsMask & FileAndLinePart);
m_ui.labelUseFullPath->setEnabled(partsMask & FileAndLinePart);
m_ui.checkBoxUseFullPath->setEnabled(partsMask & FileAndLinePart);
m_ui.labelFunction->setEnabled(partsMask & FunctionPart);
m_ui.lineEditFunction->setEnabled(partsMask & FunctionPart);
m_ui.labelAddress->setEnabled(partsMask & AddressPart);
m_ui.lineEditAddress->setEnabled(partsMask & AddressPart);
m_ui.labelCondition->setEnabled(partsMask & ConditionPart);
m_ui.labelIgnoreCount->setEnabled(partsMask & ConditionPart);
m_ui.labelThreadSpec->setEnabled(partsMask & ConditionPart);
m_ui.lineEditCondition->setEnabled(partsMask & ConditionPart);
m_ui.spinBoxIgnoreCount->setEnabled(partsMask & ConditionPart);
m_ui.lineEditThreadSpec->setEnabled(partsMask & ConditionPart);
m_ui.labelModule->setEnabled(partsMask & ModulePart);
m_ui.lineEditModule->setEnabled(partsMask & ModulePart);
}
void BreakpointDialog::clearOtherParts(unsigned partsMask)
{
const unsigned inversedPartsMask = ~partsMask;
if (inversedPartsMask & FileAndLinePart) {
m_ui.pathChooserFileName->setPath(QString());
m_ui.lineEditLineNumber->clear();
m_ui.checkBoxUseFullPath->setChecked(false);
}
if (inversedPartsMask & FunctionPart)
m_ui.lineEditFunction->clear();
if (inversedPartsMask & AddressPart)
m_ui.lineEditAddress->clear();
if (inversedPartsMask & ConditionPart) {
m_ui.lineEditCondition->clear();
m_ui.spinBoxIgnoreCount->clear();
m_ui.lineEditThreadSpec->clear();
}
if (inversedPartsMask & ModulePart)
m_ui.lineEditModule->clear();
}
2010-11-25 14:47:56 +01:00
void BreakpointDialog::getParts(unsigned partsMask, BreakpointParameters *data) const
{
data->enabled = m_ui.checkBoxEnabled->isChecked();
data->tracepoint = m_ui.checkBoxTracepoint->isChecked();
data->command = m_ui.lineEditCommand->text().trimmed();
if (partsMask & FileAndLinePart) {
2010-11-25 14:47:56 +01:00
data->lineNumber = m_ui.lineEditLineNumber->text().toInt();
data->useFullPath = m_ui.checkBoxUseFullPath->isChecked();
data->fileName = m_ui.pathChooserFileName->path();
}
if (partsMask & FunctionPart)
2010-11-25 14:47:56 +01:00
data->functionName = m_ui.lineEditFunction->text();
if (partsMask & AddressPart)
2010-11-25 14:47:56 +01:00
data->address = m_ui.lineEditAddress->text().toULongLong(0, 0);
if (partsMask & ConditionPart) {
data->condition = m_ui.lineEditCondition->text().toUtf8();
data->ignoreCount = m_ui.spinBoxIgnoreCount->text().toInt();
data->threadSpec =
BreakHandler::threadSpecFromDisplay(m_ui.lineEditThreadSpec->text());
}
if (partsMask & ModulePart)
data->module = m_ui.lineEditModule->text();
}
2010-11-25 14:47:56 +01:00
void BreakpointDialog::setParts(unsigned mask, const BreakpointParameters &data)
{
m_ui.checkBoxEnabled->setChecked(data.enabled);
m_ui.checkBoxUseFullPath->setChecked(data.useFullPath);
m_ui.lineEditCommand->setText(data.command);
if (mask & FileAndLinePart) {
2010-11-25 14:47:56 +01:00
m_ui.pathChooserFileName->setPath(data.fileName);
m_ui.lineEditLineNumber->setText(QString::number(data.lineNumber));
m_ui.checkBoxTracepoint->setChecked(data.tracepoint);
}
if (mask & FunctionPart)
2010-11-25 14:47:56 +01:00
m_ui.lineEditFunction->setText(data.functionName);
if (mask & AddressPart) {
2010-11-25 14:47:56 +01:00
if (data.address) {
m_ui.lineEditAddress->setText(
QString::fromAscii("0x%1").arg(data.address, 0, 16));
} else {
m_ui.lineEditAddress->clear();
}
}
if (mask & ConditionPart) {
m_ui.lineEditCondition->setText(QString::fromUtf8(data.condition));
m_ui.spinBoxIgnoreCount->setValue(data.ignoreCount);
m_ui.lineEditThreadSpec->
setText(BreakHandler::displayFromThreadSpec(data.threadSpec));
}
if (mask & ModulePart)
m_ui.lineEditModule->setText(data.module);
}
void BreakpointDialog::typeChanged(int)
{
BreakpointType previousType = m_previousType;
const BreakpointType newType = type();
m_previousType = newType;
2010-11-25 14:47:56 +01:00
// Save current state.
switch(previousType) {
case UnknownType:
break;
case BreakpointByFileAndLine:
getParts(FileAndLinePart|ModulePart|ConditionPart, &m_savedParameters);
break;
case BreakpointByFunction:
getParts(FunctionPart|ModulePart|ConditionPart, &m_savedParameters);
break;
case BreakpointAtThrow:
case BreakpointAtCatch:
case BreakpointAtMain:
break;
case BreakpointByAddress:
case Watchpoint:
getParts(AddressPart|ConditionPart, &m_savedParameters);
break;
}
2010-11-25 14:47:56 +01:00
// Enable and set up new state from saved values.
switch (newType) {
case UnknownType:
break;
case BreakpointByFileAndLine:
setParts(FileAndLinePart|ConditionPart|ModulePart, m_savedParameters);
setPartsEnabled(FileAndLinePart|ConditionPart|ModulePart);
clearOtherParts(FileAndLinePart|ConditionPart|ModulePart);
break;
case BreakpointByFunction:
setParts(FunctionPart|ConditionPart|ModulePart, m_savedParameters);
setPartsEnabled(FunctionPart|ConditionPart|ModulePart);
clearOtherParts(FunctionPart|ConditionPart|ModulePart);
break;
case BreakpointAtThrow:
case BreakpointAtCatch:
clearOtherParts(ConditionPart|ModulePart);
setPartsEnabled(ConditionPart);
break;
case BreakpointAtMain:
m_ui.lineEditFunction->setText(QLatin1String("main")); // Just for display
clearOtherParts(0);
setPartsEnabled(0);
break;
case BreakpointByAddress:
case Watchpoint:
setParts(AddressPart|ConditionPart, m_savedParameters);
setPartsEnabled(AddressPart|ConditionPart);
clearOtherParts(AddressPart|ConditionPart);
break;
}
}
2010-11-16 10:50:11 +01:00
bool BreakpointDialog::showDialog(BreakpointParameters *data)
{
2010-11-16 10:50:11 +01:00
setParameters(*data);
if (exec() != QDialog::Accepted)
return false;
// Check if changed.
const BreakpointParameters newParameters = parameters();
2010-11-16 10:50:11 +01:00
if (data->equals(newParameters))
return false;
2010-11-16 10:50:11 +01:00
*data = newParameters;
return true;
}
// Dialog allowing changing properties of multiple breakpoints at a time.
class MultiBreakPointsDialog : public QDialog {
Q_OBJECT
public:
explicit MultiBreakPointsDialog(QWidget *parent = 0);
QString condition() const { return m_ui.lineEditCondition->text(); }
int ignoreCount() const { return m_ui.spinBoxIgnoreCount->value(); }
int threadSpec() const
{ return BreakHandler::threadSpecFromDisplay(m_ui.lineEditThreadSpec->text()); }
void setCondition(const QString &c) { m_ui.lineEditCondition->setText(c); }
void setIgnoreCount(int i) { m_ui.spinBoxIgnoreCount->setValue(i); }
void setThreadSpec(int t)
{ return m_ui.lineEditThreadSpec->setText(BreakHandler::displayFromThreadSpec(t)); }
private:
Ui::BreakCondition m_ui;
};
MultiBreakPointsDialog::MultiBreakPointsDialog(QWidget *parent) :
QDialog(parent)
{
setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
m_ui.setupUi(this);
setWindowTitle(tr("Edit Breakpoint Properties"));
m_ui.spinBoxIgnoreCount->setMinimum(0);
m_ui.spinBoxIgnoreCount->setMaximum(2147483647);
}
///////////////////////////////////////////////////////////////////////
//
// BreakWindow
//
///////////////////////////////////////////////////////////////////////
BreakWindow::BreakWindow(QWidget *parent)
: QTreeView(parent)
2008-12-02 12:01:29 +01:00
{
m_alwaysResizeColumnsToContents = false;
QAction *act = debuggerCore()->action(UseAlternatingRowColors);
setFrameStyle(QFrame::NoFrame);
setAttribute(Qt::WA_MacShowFocusRect, false);
2008-12-02 12:01:29 +01:00
setWindowTitle(tr("Breakpoints"));
setWindowIcon(QIcon(QLatin1String(":/debugger/images/debugger_breakpoints.png")));
setAlternatingRowColors(act->isChecked());
2008-12-02 12:01:29 +01:00
setRootIsDecorated(false);
setIconSize(QSize(10, 10));
setSelectionMode(QAbstractItemView::ExtendedSelection);
2008-12-02 12:01:29 +01:00
connect(this, SIGNAL(activated(QModelIndex)),
SLOT(rowActivated(QModelIndex)));
connect(act, SIGNAL(toggled(bool)),
SLOT(setAlternatingRowColorsHelper(bool)));
2010-11-25 14:47:56 +01:00
connect(debuggerCore()->action(UseAddressInBreakpointsView),
SIGNAL(toggled(bool)),
SLOT(showAddressColumn(bool)));
}
void BreakWindow::showAddressColumn(bool on)
{
setColumnHidden(7, !on);
2008-12-02 12:01:29 +01:00
}
void BreakWindow::keyPressEvent(QKeyEvent *ev)
2008-12-02 12:01:29 +01:00
{
if (ev->key() == Qt::Key_Delete) {
QItemSelectionModel *sm = selectionModel();
QTC_ASSERT(sm, return);
QModelIndexList si = sm->selectedIndexes();
if (si.isEmpty())
si.append(currentIndex());
const BreakpointIds ids = breakHandler()->findBreakpointsByIndex(si);
int row = qMin(model()->rowCount() - ids.size() - 1, currentIndex().row());
deleteBreakpoints(ids);
setCurrentIndex(si.at(0).sibling(row, 0));
}
QTreeView::keyPressEvent(ev);
2008-12-02 12:01:29 +01:00
}
void BreakWindow::resizeEvent(QResizeEvent *ev)
2008-12-02 12:01:29 +01:00
{
QTreeView::resizeEvent(ev);
2008-12-02 12:01:29 +01:00
}
void BreakWindow::mouseDoubleClickEvent(QMouseEvent *ev)
{
QModelIndex indexUnderMouse = indexAt(ev->pos());
if (indexUnderMouse.isValid() && indexUnderMouse.column() >= 4) {
BreakpointId id = breakHandler()->findBreakpointByIndex(indexUnderMouse);
editBreakpoints(BreakpointIds() << id);
}
QTreeView::mouseDoubleClickEvent(ev);
}
void BreakWindow::setModel(QAbstractItemModel *model)
{
QTreeView::setModel(model);
resizeColumnToContents(0); // Number
resizeColumnToContents(3); // Line
resizeColumnToContents(6); // Ignore count
}
2008-12-02 12:01:29 +01:00
void BreakWindow::contextMenuEvent(QContextMenuEvent *ev)
{
QMenu menu;
QItemSelectionModel *sm = selectionModel();
QTC_ASSERT(sm, return);
QModelIndexList selectedIndices = sm->selectedIndexes();
QModelIndex indexUnderMouse = indexAt(ev->pos());
if (selectedIndices.isEmpty() && indexUnderMouse.isValid())
selectedIndices.append(indexUnderMouse);
BreakHandler *handler = breakHandler();
BreakpointIds selectedIds = handler->findBreakpointsByIndex(selectedIndices);
const int rowCount = model()->rowCount();
const unsigned engineCapabilities = BreakOnThrowAndCatchCapability;
2010-11-25 14:47:56 +01:00
// FIXME BP: model()->data(QModelIndex(), EngineCapabilitiesRole).toUInt();
QAction *deleteAction = new QAction(tr("Delete Breakpoint"), &menu);
deleteAction->setEnabled(!selectedIds.isEmpty());
QAction *deleteAllAction = new QAction(tr("Delete All Breakpoints"), &menu);
deleteAllAction->setEnabled(model()->rowCount() > 0);
// Delete by file: Find indices of breakpoints of the same file.
QAction *deleteByFileAction = 0;
BreakpointIds breakpointsInFile;
if (indexUnderMouse.isValid()) {
const QModelIndex index = indexUnderMouse.sibling(indexUnderMouse.row(), 2);
const QString file = index.data().toString();
if (!file.isEmpty()) {
for (int i = 0; i < rowCount; i++)
if (index.data().toString() == file)
breakpointsInFile.append(handler->findBreakpointByIndex(index));
if (breakpointsInFile.size() > 1) {
deleteByFileAction =
new QAction(tr("Delete Breakpoints of \"%1\"").arg(file), &menu);
deleteByFileAction->setEnabled(true);
}
}
}
if (!deleteByFileAction) {
deleteByFileAction = new QAction(tr("Delete Breakpoints of File"), &menu);
deleteByFileAction->setEnabled(false);
}
QAction *adjustColumnAction =
new QAction(tr("Adjust Column Widths to Contents"), &menu);
QAction *alwaysAdjustAction =
new QAction(tr("Always Adjust Column Widths to Contents"), &menu);
alwaysAdjustAction->setCheckable(true);
alwaysAdjustAction->setChecked(m_alwaysResizeColumnsToContents);
QAction *editBreakpointAction =
new QAction(tr("Edit Breakpoint..."), &menu);
editBreakpointAction->setEnabled(!selectedIds.isEmpty());
int threadId = 0;
// FIXME BP: m_engine->threadsHandler()->currentThreadId();
QString associateTitle = threadId == -1
? tr("Associate Breakpoint With All Threads")
: tr("Associate Breakpoint With Thread %1").arg(threadId);
QAction *associateBreakpointAction = new QAction(associateTitle, &menu);
associateBreakpointAction->setEnabled(!selectedIds.isEmpty());
QAction *synchronizeAction =
new QAction(tr("Synchronize Breakpoints"), &menu);
synchronizeAction->setEnabled(debuggerCore()->hasSnapshots());
bool enabled = selectedIds.isEmpty() || handler->isEnabled(selectedIds.at(0));
const QString str5 = selectedIds.size() > 1
? enabled
? tr("Disable Selected Breakpoints")
: tr("Enable Selected Breakpoints")
: enabled
? tr("Disable Breakpoint")
: tr("Enable Breakpoint");
QAction *toggleEnabledAction = new QAction(str5, &menu);
toggleEnabledAction->setEnabled(!selectedIds.isEmpty());
QAction *addBreakpointAction =
new QAction(tr("Add Breakpoint..."), this);
QAction *breakAtThrowAction =
new QAction(tr("Set Breakpoint at \"throw\""), this);
QAction *breakAtCatchAction =
new QAction(tr("Set Breakpoint at \"catch\""), this);
menu.addAction(addBreakpointAction);
menu.addAction(deleteAction);
menu.addAction(editBreakpointAction);
menu.addAction(associateBreakpointAction);
menu.addAction(toggleEnabledAction);
menu.addSeparator();
menu.addAction(deleteAllAction);
//menu.addAction(deleteByFileAction);
menu.addSeparator();
menu.addAction(synchronizeAction);
if (engineCapabilities & BreakOnThrowAndCatchCapability) {
menu.addSeparator();
menu.addAction(breakAtThrowAction);
menu.addAction(breakAtCatchAction);
}
menu.addSeparator();
menu.addAction(debuggerCore()->action(UseToolTipsInBreakpointsView));
menu.addAction(debuggerCore()->action(UseAddressInBreakpointsView));
menu.addAction(adjustColumnAction);
menu.addAction(alwaysAdjustAction);
menu.addSeparator();
menu.addAction(debuggerCore()->action(SettingsDialog));
2008-12-02 12:01:29 +01:00
QAction *act = menu.exec(ev->globalPos());
if (act == deleteAction)
deleteBreakpoints(selectedIds);
else if (act == deleteAllAction)
deleteBreakpoints(handler->allBreakpointIds());
else if (act == deleteByFileAction)
deleteBreakpoints(breakpointsInFile);
else if (act == adjustColumnAction)
2008-12-02 12:01:29 +01:00
resizeColumnsToContents();
else if (act == alwaysAdjustAction)
2008-12-02 12:01:29 +01:00
setAlwaysResizeColumnsToContents(!m_alwaysResizeColumnsToContents);
else if (act == editBreakpointAction)
editBreakpoints(selectedIds);
else if (act == associateBreakpointAction)
associateBreakpoint(selectedIds, threadId);
else if (act == synchronizeAction)
; //synchronizeBreakpoints();
else if (act == toggleEnabledAction)
setBreakpointsEnabled(selectedIds, !enabled);
else if (act == addBreakpointAction)
addBreakpoint();
2010-11-16 10:50:11 +01:00
else if (act == breakAtThrowAction)
handler->appendBreakpoint(BreakpointParameters(BreakpointAtThrow));
else if (act == breakAtCatchAction)
handler->appendBreakpoint(BreakpointParameters(BreakpointAtCatch));
}
void BreakWindow::setBreakpointsEnabled(const BreakpointIds &ids, bool enabled)
{
BreakHandler *handler = breakHandler();
foreach (const BreakpointId id, ids)
handler->setEnabled(id, enabled);
}
void BreakWindow::deleteBreakpoints(const BreakpointIds &ids)
{
BreakHandler *handler = breakHandler();
foreach (const BreakpointId id, ids)
handler->removeBreakpoint(id);
}
void BreakWindow::editBreakpoint(BreakpointId id, QWidget *parent)
{
BreakpointDialog dialog(parent);
BreakpointParameters data = breakHandler()->breakpointData(id);
2010-11-16 10:50:11 +01:00
if (dialog.showDialog(&data))
breakHandler()->setBreakpointData(id, data);
}
void BreakWindow::addBreakpoint()
{
2010-11-16 10:50:11 +01:00
BreakpointParameters data(BreakpointByFileAndLine);
BreakpointDialog dialog(this);
dialog.setWindowTitle(tr("Add Breakpoint"));
if (dialog.showDialog(&data))
breakHandler()->appendBreakpoint(data);
}
void BreakWindow::editBreakpoints(const BreakpointIds &ids)
2008-12-02 12:01:29 +01:00
{
QTC_ASSERT(!ids.isEmpty(), return);
const BreakpointId id = ids.at(0);
if (ids.size() == 1) {
editBreakpoint(id, this);
return;
}
// This allows to change properties of multiple breakpoints at a time.
MultiBreakPointsDialog dialog;
BreakHandler *handler = breakHandler();
const QString oldCondition = QString::fromLatin1(handler->condition(id));
dialog.setCondition(oldCondition);
const int oldIgnoreCount = handler->ignoreCount(id);
dialog.setIgnoreCount(oldIgnoreCount);
const int oldThreadSpec = handler->threadSpec(id);
dialog.setThreadSpec(oldThreadSpec);
2008-12-02 12:01:29 +01:00
if (dialog.exec() == QDialog::Rejected)
2008-12-02 12:01:29 +01:00
return;
const QString newCondition = dialog.condition();
const int newIgnoreCount = dialog.ignoreCount();
const int newThreadSpec = dialog.threadSpec();
if (newCondition == oldCondition && newIgnoreCount == oldIgnoreCount
&& newThreadSpec == oldThreadSpec)
return;
foreach (const BreakpointId id, ids) {
handler->setCondition(id, newCondition.toLatin1());
handler->setIgnoreCount(id, newIgnoreCount);
handler->setThreadSpec(id, newThreadSpec);
}
2008-12-02 12:01:29 +01:00
}
void BreakWindow::associateBreakpoint(const BreakpointIds &ids, int threadId)
{
BreakHandler *handler = breakHandler();
foreach (const BreakpointId id, ids)
handler->setThreadSpec(id, threadId);
}
2008-12-02 12:01:29 +01:00
void BreakWindow::resizeColumnsToContents()
{
for (int i = model()->columnCount(); --i >= 0; )
resizeColumnToContents(i);
2008-12-02 12:01:29 +01:00
}
void BreakWindow::setAlwaysResizeColumnsToContents(bool on)
{
m_alwaysResizeColumnsToContents = on;
QHeaderView::ResizeMode mode = on
2008-12-02 12:01:29 +01:00
? QHeaderView::ResizeToContents : QHeaderView::Interactive;
for (int i = model()->columnCount(); --i >= 0; )
header()->setResizeMode(i, mode);
2008-12-02 12:01:29 +01:00
}
void BreakWindow::rowActivated(const QModelIndex &index)
{
breakHandler()->gotoLocation(breakHandler()->findBreakpointByIndex(index));
}
} // namespace Internal
} // namespace Debugger
#include "breakwindow.moc"