forked from qt-creator/qt-creator
Added Cdb Debugger path options (including symbol server).
Made pathlisteditor use a toolbutton menu as it looks too much of a "button desert" otherwise.
This commit is contained in:
@@ -32,16 +32,19 @@
|
|||||||
#include <QtGui/QVBoxLayout>
|
#include <QtGui/QVBoxLayout>
|
||||||
#include <QtGui/QHBoxLayout>
|
#include <QtGui/QHBoxLayout>
|
||||||
#include <QtGui/QPlainTextEdit>
|
#include <QtGui/QPlainTextEdit>
|
||||||
#include <QtGui/QPushButton>
|
|
||||||
#include <QtGui/QToolButton>
|
#include <QtGui/QToolButton>
|
||||||
#include <QtGui/QSpacerItem>
|
#include <QtGui/QSpacerItem>
|
||||||
#include <QtGui/QFileDialog>
|
#include <QtGui/QFileDialog>
|
||||||
#include <QtGui/QTextCursor>
|
#include <QtGui/QTextCursor>
|
||||||
#include <QtGui/QTextBlock>
|
#include <QtGui/QTextBlock>
|
||||||
|
#include <QtGui/QMenu>
|
||||||
|
#include <QtGui/QAction>
|
||||||
|
|
||||||
#include <QtCore/QSignalMapper>
|
#include <QtCore/QSignalMapper>
|
||||||
#include <QtCore/QMimeData>
|
#include <QtCore/QMimeData>
|
||||||
#include <QtCore/QSharedPointer>
|
#include <QtCore/QSharedPointer>
|
||||||
|
#include <QtCore/QDir>
|
||||||
|
#include <QtCore/QDebug>
|
||||||
|
|
||||||
namespace Core {
|
namespace Core {
|
||||||
namespace Utils {
|
namespace Utils {
|
||||||
@@ -86,6 +89,8 @@ struct PathListEditorPrivate {
|
|||||||
|
|
||||||
QHBoxLayout *layout;
|
QHBoxLayout *layout;
|
||||||
QVBoxLayout *buttonLayout;
|
QVBoxLayout *buttonLayout;
|
||||||
|
QToolButton *toolButton;
|
||||||
|
QMenu *buttonMenu;
|
||||||
QPlainTextEdit *edit;
|
QPlainTextEdit *edit;
|
||||||
QSignalMapper *envVarMapper;
|
QSignalMapper *envVarMapper;
|
||||||
QString fileDialogTitle;
|
QString fileDialogTitle;
|
||||||
@@ -94,12 +99,16 @@ struct PathListEditorPrivate {
|
|||||||
PathListEditorPrivate::PathListEditorPrivate() :
|
PathListEditorPrivate::PathListEditorPrivate() :
|
||||||
layout(new QHBoxLayout),
|
layout(new QHBoxLayout),
|
||||||
buttonLayout(new QVBoxLayout),
|
buttonLayout(new QVBoxLayout),
|
||||||
|
toolButton(new QToolButton),
|
||||||
|
buttonMenu(new QMenu),
|
||||||
edit(new PathListPlainTextEdit),
|
edit(new PathListPlainTextEdit),
|
||||||
envVarMapper(0)
|
envVarMapper(0)
|
||||||
{
|
{
|
||||||
|
layout->setMargin(0);
|
||||||
layout->addWidget(edit);
|
layout->addWidget(edit);
|
||||||
layout->addLayout(buttonLayout);
|
buttonLayout->addWidget(toolButton);
|
||||||
buttonLayout->addItem(new QSpacerItem(0, 0, QSizePolicy::Ignored, QSizePolicy::MinimumExpanding));
|
buttonLayout->addItem(new QSpacerItem(0, 0, QSizePolicy::Ignored, QSizePolicy::MinimumExpanding));
|
||||||
|
layout->addLayout(buttonLayout);
|
||||||
}
|
}
|
||||||
|
|
||||||
PathListEditor::PathListEditor(QWidget *parent) :
|
PathListEditor::PathListEditor(QWidget *parent) :
|
||||||
@@ -107,9 +116,14 @@ PathListEditor::PathListEditor(QWidget *parent) :
|
|||||||
m_d(new PathListEditorPrivate)
|
m_d(new PathListEditorPrivate)
|
||||||
{
|
{
|
||||||
setLayout(m_d->layout);
|
setLayout(m_d->layout);
|
||||||
addButton(tr("Add..."), this, SLOT(slotAdd()));
|
m_d->toolButton->setPopupMode(QToolButton::MenuButtonPopup);
|
||||||
addButton(tr("Delete"), this, SLOT(deletePathAtCursor()));
|
m_d->toolButton->setText(tr("Insert..."));
|
||||||
addButton(tr("Clear"), this, SLOT(clear()));
|
m_d->toolButton->setMenu(m_d->buttonMenu);
|
||||||
|
connect(m_d->toolButton, SIGNAL(clicked()), this, SLOT(slotInsert()));
|
||||||
|
|
||||||
|
addAction(tr("Add..."), this, SLOT(slotAdd()));
|
||||||
|
addAction(tr("Delete line"), this, SLOT(deletePathAtCursor()));
|
||||||
|
addAction(tr("Clear"), this, SLOT(clear()));
|
||||||
}
|
}
|
||||||
|
|
||||||
PathListEditor::~PathListEditor()
|
PathListEditor::~PathListEditor()
|
||||||
@@ -117,26 +131,43 @@ PathListEditor::~PathListEditor()
|
|||||||
delete m_d;
|
delete m_d;
|
||||||
}
|
}
|
||||||
|
|
||||||
QAbstractButton *PathListEditor::addButton(const QString &text, QObject * receiver, const char *slotFunc)
|
static inline QAction *createAction(QObject *parent, const QString &text, QObject * receiver, const char *slotFunc)
|
||||||
{
|
{
|
||||||
// before Spacer item
|
QAction *rc = new QAction(text, parent);
|
||||||
return insertButton(m_d->buttonLayout->count() - 1, text, receiver, slotFunc);
|
QObject::connect(rc, SIGNAL(triggered()), receiver, slotFunc);
|
||||||
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
QAbstractButton *PathListEditor::insertButton(int index, const QString &text, QObject * receiver, const char *slotFunc)
|
QAction *PathListEditor::addAction(const QString &text, QObject * receiver, const char *slotFunc)
|
||||||
{
|
{
|
||||||
#ifdef Q_OS_MAC
|
QAction *rc = createAction(this, text, receiver, slotFunc);
|
||||||
typedef QPushButton Button;
|
m_d->buttonMenu->addAction(rc);
|
||||||
#else
|
|
||||||
typedef QToolButton Button;
|
|
||||||
#endif
|
|
||||||
Button *rc = new Button;
|
|
||||||
rc->setText(text);
|
|
||||||
connect(rc, SIGNAL(clicked()), receiver, slotFunc);
|
|
||||||
m_d->buttonLayout->insertWidget(index, rc);
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QAction *PathListEditor::insertAction(int index /* -1 */, const QString &text, QObject * receiver, const char *slotFunc)
|
||||||
|
{
|
||||||
|
// Find the 'before' action
|
||||||
|
QAction *beforeAction = 0;
|
||||||
|
if (index >= 0) {
|
||||||
|
const QList<QAction*> actions = m_d->buttonMenu->actions();
|
||||||
|
if (index < actions.size())
|
||||||
|
beforeAction = actions.at(index);
|
||||||
|
}
|
||||||
|
QAction *rc = createAction(this, text, receiver, slotFunc);
|
||||||
|
if (beforeAction) {
|
||||||
|
m_d->buttonMenu->insertAction(beforeAction, rc);
|
||||||
|
} else {
|
||||||
|
m_d->buttonMenu->addAction(rc);
|
||||||
|
}
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PathListEditor::lastAddActionIndex()
|
||||||
|
{
|
||||||
|
return 0; // Insert/Add
|
||||||
|
}
|
||||||
|
|
||||||
QString PathListEditor::pathListString() const
|
QString PathListEditor::pathListString() const
|
||||||
{
|
{
|
||||||
return pathList().join(separator());
|
return pathList().join(separator());
|
||||||
@@ -193,7 +224,14 @@ void PathListEditor::slotAdd()
|
|||||||
{
|
{
|
||||||
const QString dir = QFileDialog::getExistingDirectory(this, m_d->fileDialogTitle);
|
const QString dir = QFileDialog::getExistingDirectory(this, m_d->fileDialogTitle);
|
||||||
if (!dir.isEmpty())
|
if (!dir.isEmpty())
|
||||||
insertPathAtCursor(dir);
|
appendPath(QDir::toNativeSeparators(dir));
|
||||||
|
}
|
||||||
|
|
||||||
|
void PathListEditor::slotInsert()
|
||||||
|
{
|
||||||
|
const QString dir = QFileDialog::getExistingDirectory(this, m_d->fileDialogTitle);
|
||||||
|
if (!dir.isEmpty())
|
||||||
|
insertPathAtCursor(QDir::toNativeSeparators(dir));
|
||||||
}
|
}
|
||||||
|
|
||||||
QChar PathListEditor::separator()
|
QChar PathListEditor::separator()
|
||||||
@@ -207,15 +245,16 @@ QChar PathListEditor::separator()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Add a button "Import from 'Path'"
|
// Add a button "Import from 'Path'"
|
||||||
void PathListEditor::addEnvVariableImportButton(const QString &var)
|
void PathListEditor::addEnvVariableImportAction(const QString &var)
|
||||||
{
|
{
|
||||||
if (!m_d->envVarMapper) {
|
if (!m_d->envVarMapper) {
|
||||||
m_d->envVarMapper = new QSignalMapper(this);
|
m_d->envVarMapper = new QSignalMapper(this);
|
||||||
connect(m_d->envVarMapper, SIGNAL(mapped(QString)), this, SLOT(setPathListFromEnvVariable(QString)));
|
connect(m_d->envVarMapper, SIGNAL(mapped(QString)), this, SLOT(setPathListFromEnvVariable(QString)));
|
||||||
}
|
}
|
||||||
|
|
||||||
QAbstractButton *b = addButton(tr("From \"%1\"").arg(var), m_d->envVarMapper, SLOT(map()));
|
QAction *a = insertAction(lastAddActionIndex() + 1,
|
||||||
m_d->envVarMapper->setMapping(b, var);
|
tr("From \"%1\"").arg(var), m_d->envVarMapper, SLOT(map()));
|
||||||
|
m_d->envVarMapper->setMapping(a, var);
|
||||||
}
|
}
|
||||||
|
|
||||||
QString PathListEditor::text() const
|
QString PathListEditor::text() const
|
||||||
@@ -247,14 +286,25 @@ void PathListEditor::insertPathAtCursor(const QString &path)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PathListEditor::appendPath(const QString &path)
|
||||||
|
{
|
||||||
|
QString paths = text().trimmed();
|
||||||
|
if (!paths.isEmpty())
|
||||||
|
paths += QLatin1Char('\n');
|
||||||
|
paths += path;
|
||||||
|
setText(paths);
|
||||||
|
}
|
||||||
|
|
||||||
void PathListEditor::deletePathAtCursor()
|
void PathListEditor::deletePathAtCursor()
|
||||||
{
|
{
|
||||||
// Delete current line
|
// Delete current line
|
||||||
QTextCursor cursor = m_d->edit->textCursor();
|
QTextCursor cursor = m_d->edit->textCursor();
|
||||||
if (cursor.block().isValid()) {
|
if (cursor.block().isValid()) {
|
||||||
cursor.select(QTextCursor::BlockUnderCursor);
|
|
||||||
cursor.removeSelectedText();
|
|
||||||
cursor.movePosition(QTextCursor::StartOfLine, QTextCursor::MoveAnchor);
|
cursor.movePosition(QTextCursor::StartOfLine, QTextCursor::MoveAnchor);
|
||||||
|
// Select down or until end of [last] line
|
||||||
|
if (!cursor.movePosition(QTextCursor::Down, QTextCursor::KeepAnchor))
|
||||||
|
cursor.movePosition(QTextCursor::EndOfLine, QTextCursor::KeepAnchor);
|
||||||
|
cursor.removeSelectedText();
|
||||||
m_d->edit->setTextCursor(cursor);
|
m_d->edit->setTextCursor(cursor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,7 +36,7 @@
|
|||||||
#include <QtCore/QStringList>
|
#include <QtCore/QStringList>
|
||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
class QAbstractButton;
|
class QAction;
|
||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
namespace Core {
|
namespace Core {
|
||||||
@@ -72,8 +72,8 @@ public:
|
|||||||
|
|
||||||
static QChar separator();
|
static QChar separator();
|
||||||
|
|
||||||
// Add a convenience button "Import from 'Path'" (environment variable)
|
// Add a convenience action "Import from 'Path'" (environment variable)
|
||||||
void addEnvVariableImportButton(const QString &var);
|
void addEnvVariableImportAction(const QString &var);
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void clear();
|
void clear();
|
||||||
@@ -83,17 +83,22 @@ public slots:
|
|||||||
void setFileDialogTitle(const QString &l);
|
void setFileDialogTitle(const QString &l);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
QAbstractButton *insertButton(int index /* -1 */, const QString &text, QObject * receiver, const char *slotFunc);
|
// Index after which to insert further "Add" actions
|
||||||
QAbstractButton *addButton(const QString &text, QObject * receiver, const char *slotFunc);
|
static int lastAddActionIndex();
|
||||||
|
QAction *insertAction(int index /* -1 */, const QString &text, QObject * receiver, const char *slotFunc);
|
||||||
|
QAction *addAction(const QString &text, QObject * receiver, const char *slotFunc);
|
||||||
|
|
||||||
QString text() const;
|
QString text() const;
|
||||||
void setText(const QString &);
|
void setText(const QString &);
|
||||||
|
|
||||||
protected slots:
|
protected slots:
|
||||||
void insertPathAtCursor(const QString &);
|
void insertPathAtCursor(const QString &);
|
||||||
void deletePathAtCursor();
|
void deletePathAtCursor();
|
||||||
|
void appendPath(const QString &);
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void slotAdd();
|
void slotAdd();
|
||||||
|
void slotInsert();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
PathListEditorPrivate *m_d;
|
PathListEditorPrivate *m_d;
|
||||||
|
|||||||
@@ -40,7 +40,8 @@ HEADERS += \
|
|||||||
$$PWD/cdbassembler.h \
|
$$PWD/cdbassembler.h \
|
||||||
$$PWD/cdboptions.h \
|
$$PWD/cdboptions.h \
|
||||||
$$PWD/cdboptionspage.h \
|
$$PWD/cdboptionspage.h \
|
||||||
$$PWD/cdbdumperhelper.h
|
$$PWD/cdbdumperhelper.h \
|
||||||
|
$$PWD/cdbsymbolpathlisteditor.h
|
||||||
|
|
||||||
SOURCES += \
|
SOURCES += \
|
||||||
$$PWD/cdbdebugengine.cpp \
|
$$PWD/cdbdebugengine.cpp \
|
||||||
@@ -54,7 +55,8 @@ SOURCES += \
|
|||||||
$$PWD/cdbassembler.cpp \
|
$$PWD/cdbassembler.cpp \
|
||||||
$$PWD/cdboptions.cpp \
|
$$PWD/cdboptions.cpp \
|
||||||
$$PWD/cdboptionspage.cpp \
|
$$PWD/cdboptionspage.cpp \
|
||||||
$$PWD/cdbdumperhelper.cpp
|
$$PWD/cdbdumperhelper.cpp \
|
||||||
|
$$PWD/cdbsymbolpathlisteditor.cpp
|
||||||
|
|
||||||
FORMS += $$PWD/cdboptionspagewidget.ui
|
FORMS += $$PWD/cdboptionspagewidget.ui
|
||||||
|
|
||||||
|
|||||||
@@ -347,8 +347,10 @@ IDebuggerEngine *CdbDebugEngine::create(DebuggerManager *parent,
|
|||||||
QString *errorMessage)
|
QString *errorMessage)
|
||||||
{
|
{
|
||||||
CdbDebugEngine *rc = new CdbDebugEngine(parent, options);
|
CdbDebugEngine *rc = new CdbDebugEngine(parent, options);
|
||||||
if (rc->m_d->init(errorMessage))
|
if (rc->m_d->init(errorMessage)) {
|
||||||
|
rc->syncDebuggerPaths();
|
||||||
return rc;
|
return rc;
|
||||||
|
}
|
||||||
delete rc;
|
delete rc;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -452,6 +454,7 @@ void CdbDebugEnginePrivate::clearDisplay()
|
|||||||
bool CdbDebugEngine::startDebugger()
|
bool CdbDebugEngine::startDebugger()
|
||||||
{
|
{
|
||||||
m_d->clearDisplay();
|
m_d->clearDisplay();
|
||||||
|
|
||||||
const DebuggerStartMode mode = m_d->m_debuggerManager->startMode();
|
const DebuggerStartMode mode = m_d->m_debuggerManager->startMode();
|
||||||
// Figure out dumper. @TODO: same in gdb...
|
// Figure out dumper. @TODO: same in gdb...
|
||||||
const QString dumperLibName = QDir::toNativeSeparators(m_d->m_debuggerManagerAccess->qtDumperLibraryName());
|
const QString dumperLibName = QDir::toNativeSeparators(m_d->m_debuggerManagerAccess->qtDumperLibraryName());
|
||||||
@@ -1489,6 +1492,59 @@ void CdbDebugEngine::reloadSourceFiles()
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QStringList CdbDebugEnginePrivate::sourcePaths() const
|
||||||
|
{
|
||||||
|
WCHAR wszBuf[MAX_PATH];
|
||||||
|
if (SUCCEEDED(m_cif.debugSymbols->GetSourcePathWide(wszBuf, MAX_PATH, 0)))
|
||||||
|
return QString::fromUtf16(wszBuf).split(QLatin1Char(';'));
|
||||||
|
return QStringList();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CdbDebugEngine::syncDebuggerPaths()
|
||||||
|
{
|
||||||
|
if (debugCDB)
|
||||||
|
qDebug() << Q_FUNC_INFO << m_d->m_options->symbolPaths << m_d->m_options->sourcePaths;
|
||||||
|
QString errorMessage;
|
||||||
|
if (!m_d->setSourcePaths(m_d->m_options->sourcePaths, &errorMessage)
|
||||||
|
|| !m_d->setSymbolPaths(m_d->m_options->symbolPaths, &errorMessage)) {
|
||||||
|
errorMessage = QString::fromLatin1("Unable to set the debugger paths: %1").arg(errorMessage);
|
||||||
|
qWarning("%s\n", qPrintable(errorMessage));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline QString pathString(const QStringList &s)
|
||||||
|
{ return s.join(QString(QLatin1Char(';'))); }
|
||||||
|
|
||||||
|
bool CdbDebugEnginePrivate::setSourcePaths(const QStringList &s, QString *errorMessage)
|
||||||
|
{
|
||||||
|
const HRESULT hr = m_cif.debugSymbols->SetSourcePathWide(pathString(s).utf16());
|
||||||
|
if (FAILED(hr)) {
|
||||||
|
if (errorMessage)
|
||||||
|
*errorMessage = msgComFailed("SetSourcePathWide", hr);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
QStringList CdbDebugEnginePrivate::symbolPaths() const
|
||||||
|
{
|
||||||
|
WCHAR wszBuf[MAX_PATH];
|
||||||
|
if (SUCCEEDED(m_cif.debugSymbols->GetSymbolPathWide(wszBuf, MAX_PATH, 0)))
|
||||||
|
return QString::fromUtf16(wszBuf).split(QLatin1Char(';'));
|
||||||
|
return QStringList();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CdbDebugEnginePrivate::setSymbolPaths(const QStringList &s, QString *errorMessage)
|
||||||
|
{
|
||||||
|
const HRESULT hr = m_cif.debugSymbols->SetSymbolPathWide(pathString(s).utf16());
|
||||||
|
if (FAILED(hr)) {
|
||||||
|
if (errorMessage)
|
||||||
|
*errorMessage = msgComFailed("SetSymbolPathWide", hr);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
} // namespace Debugger
|
} // namespace Debugger
|
||||||
|
|
||||||
@@ -1512,5 +1568,6 @@ Debugger::Internal::IDebuggerEngine *createWinEngine(Debugger::Internal::Debugge
|
|||||||
optionsPage->setFailureMessage(errorMessage);
|
optionsPage->setFailureMessage(errorMessage);
|
||||||
qWarning("%s", qPrintable(errorMessage));
|
qWarning("%s", qPrintable(errorMessage));
|
||||||
}
|
}
|
||||||
|
QObject::connect(optionsPage, SIGNAL(debuggerPathsChanged()), engine, SLOT(syncDebuggerPaths()));
|
||||||
return engine;
|
return engine;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -96,6 +96,9 @@ public:
|
|||||||
virtual void reloadSourceFiles();
|
virtual void reloadSourceFiles();
|
||||||
virtual void reloadFullStack() {}
|
virtual void reloadFullStack() {}
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void syncDebuggerPaths();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void timerEvent(QTimerEvent*);
|
void timerEvent(QTimerEvent*);
|
||||||
|
|
||||||
|
|||||||
@@ -135,6 +135,12 @@ struct CdbDebugEnginePrivate
|
|||||||
static bool executeDebuggerCommand(CIDebugControl *ctrl, const QString &command, QString *errorMessage);
|
static bool executeDebuggerCommand(CIDebugControl *ctrl, const QString &command, QString *errorMessage);
|
||||||
static bool evaluateExpression(CIDebugControl *ctrl, const QString &expression, DEBUG_VALUE *v, QString *errorMessage);
|
static bool evaluateExpression(CIDebugControl *ctrl, const QString &expression, DEBUG_VALUE *v, QString *errorMessage);
|
||||||
|
|
||||||
|
QStringList sourcePaths() const;
|
||||||
|
bool setSourcePaths(const QStringList &s, QString *errorMessage);
|
||||||
|
|
||||||
|
QStringList symbolPaths() const;
|
||||||
|
bool setSymbolPaths(const QStringList &s, QString *errorMessage);
|
||||||
|
|
||||||
const QSharedPointer<CdbOptions> m_options;
|
const QSharedPointer<CdbOptions> m_options;
|
||||||
HANDLE m_hDebuggeeProcess;
|
HANDLE m_hDebuggeeProcess;
|
||||||
HANDLE m_hDebuggeeThread;
|
HANDLE m_hDebuggeeThread;
|
||||||
|
|||||||
@@ -34,8 +34,10 @@
|
|||||||
#include <QtCore/QFileInfo>
|
#include <QtCore/QFileInfo>
|
||||||
|
|
||||||
static const char *settingsGroupC = "CDB";
|
static const char *settingsGroupC = "CDB";
|
||||||
static const char *enabledKeyC = "enabled";
|
static const char *enabledKeyC = "Enabled";
|
||||||
static const char *pathKeyC = "path";
|
static const char *pathKeyC = "Path";
|
||||||
|
static const char *symbolPathsKeyC = "SymbolPaths";
|
||||||
|
static const char *sourcePathsKeyC = "SourcePaths";
|
||||||
|
|
||||||
namespace Debugger {
|
namespace Debugger {
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
@@ -65,6 +67,8 @@ void CdbOptions::fromSettings(const QSettings *s)
|
|||||||
}
|
}
|
||||||
enabled = s->value(enabledKey, false).toBool();
|
enabled = s->value(enabledKey, false).toBool();
|
||||||
path = s->value(keyRoot + QLatin1String(pathKeyC), QString()).toString();
|
path = s->value(keyRoot + QLatin1String(pathKeyC), QString()).toString();
|
||||||
|
symbolPaths = s->value(keyRoot + QLatin1String(symbolPathsKeyC), QStringList()).toStringList();
|
||||||
|
sourcePaths = s->value(keyRoot + QLatin1String(sourcePathsKeyC), QStringList()).toStringList();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CdbOptions::toSettings(QSettings *s) const
|
void CdbOptions::toSettings(QSettings *s) const
|
||||||
@@ -72,6 +76,8 @@ void CdbOptions::toSettings(QSettings *s) const
|
|||||||
s->beginGroup(QLatin1String(settingsGroupC));
|
s->beginGroup(QLatin1String(settingsGroupC));
|
||||||
s->setValue(QLatin1String(enabledKeyC), enabled);
|
s->setValue(QLatin1String(enabledKeyC), enabled);
|
||||||
s->setValue(QLatin1String(pathKeyC), path);
|
s->setValue(QLatin1String(pathKeyC), path);
|
||||||
|
s->setValue(QLatin1String(symbolPathsKeyC), symbolPaths);
|
||||||
|
s->setValue(QLatin1String(sourcePathsKeyC), sourcePaths);
|
||||||
s->endGroup();
|
s->endGroup();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -105,9 +111,14 @@ bool CdbOptions::autoDetectPath(QString *outPath)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CdbOptions::equals(const CdbOptions &rhs) const
|
unsigned CdbOptions::compare(const CdbOptions &rhs) const
|
||||||
{
|
{
|
||||||
return enabled == rhs.enabled && path == rhs.path;
|
unsigned rc = 0;
|
||||||
|
if (enabled != rhs.enabled || path != rhs.path)
|
||||||
|
rc |= InitializationOptionsChanged;
|
||||||
|
if (symbolPaths != rhs.symbolPaths || sourcePaths != rhs.sourcePaths)
|
||||||
|
rc |= DebuggerPathsChanged;
|
||||||
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
|
|||||||
@@ -30,7 +30,7 @@
|
|||||||
#ifndef CDBSETTINGS_H
|
#ifndef CDBSETTINGS_H
|
||||||
#define CDBSETTINGS_H
|
#define CDBSETTINGS_H
|
||||||
|
|
||||||
#include <QtCore/QString>
|
#include <QtCore/QStringList>
|
||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
class QSettings;
|
class QSettings;
|
||||||
@@ -48,19 +48,23 @@ public:
|
|||||||
void fromSettings(const QSettings *s);
|
void fromSettings(const QSettings *s);
|
||||||
void toSettings(QSettings *s) const;
|
void toSettings(QSettings *s) const;
|
||||||
|
|
||||||
bool equals(const CdbOptions &s) const;
|
// A set of flags for comparison function.
|
||||||
|
enum ChangeFlags { InitializationOptionsChanged = 0x1, DebuggerPathsChanged = 0x2 };
|
||||||
|
unsigned compare(const CdbOptions &s) const;
|
||||||
|
|
||||||
// Locate the debugging tools
|
// Locate the debugging tools
|
||||||
static bool autoDetectPath(QString *path);
|
static bool autoDetectPath(QString *path);
|
||||||
|
|
||||||
bool enabled;
|
bool enabled;
|
||||||
QString path;
|
QString path;
|
||||||
|
QStringList symbolPaths;
|
||||||
|
QStringList sourcePaths;
|
||||||
};
|
};
|
||||||
|
|
||||||
inline bool operator==(const CdbOptions &s1, const CdbOptions &s2)
|
inline bool operator==(const CdbOptions &s1, const CdbOptions &s2)
|
||||||
{ return s1.equals(s2); }
|
{ return s1.compare(s2) == 0u; }
|
||||||
inline bool operator!=(const CdbOptions &s1, const CdbOptions &s2)
|
inline bool operator!=(const CdbOptions &s1, const CdbOptions &s2)
|
||||||
{ return !s1.equals(s2); }
|
{ return s1.compare(s2) != 0u; }
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
} // namespace Debugger
|
} // namespace Debugger
|
||||||
|
|||||||
@@ -53,6 +53,8 @@ void CdbOptionsPageWidget::setOptions(CdbOptions &o)
|
|||||||
{
|
{
|
||||||
m_ui.pathChooser->setPath(o.path);
|
m_ui.pathChooser->setPath(o.path);
|
||||||
m_ui.cdbOptionsGroupBox->setChecked(o.enabled);
|
m_ui.cdbOptionsGroupBox->setChecked(o.enabled);
|
||||||
|
m_ui.symbolPathListEditor->setPathList(o.symbolPaths);
|
||||||
|
m_ui.sourcePathListEditor->setPathList(o.sourcePaths);
|
||||||
}
|
}
|
||||||
|
|
||||||
CdbOptions CdbOptionsPageWidget::options() const
|
CdbOptions CdbOptionsPageWidget::options() const
|
||||||
@@ -60,6 +62,8 @@ CdbOptions CdbOptionsPageWidget::options() const
|
|||||||
CdbOptions rc;
|
CdbOptions rc;
|
||||||
rc.path = m_ui.pathChooser->path();
|
rc.path = m_ui.pathChooser->path();
|
||||||
rc.enabled = m_ui.cdbOptionsGroupBox->isChecked();
|
rc.enabled = m_ui.cdbOptionsGroupBox->isChecked();
|
||||||
|
rc.symbolPaths = m_ui.symbolPathListEditor->pathList();
|
||||||
|
rc.sourcePaths = m_ui.sourcePathListEditor->pathList();
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -121,9 +125,11 @@ void CdbOptionsPage::apply()
|
|||||||
if (!m_widget)
|
if (!m_widget)
|
||||||
return;
|
return;
|
||||||
const CdbOptions newOptions = m_widget->options();
|
const CdbOptions newOptions = m_widget->options();
|
||||||
if (newOptions != *m_options) {
|
if (const unsigned changedMask = m_options->compare(newOptions)) {
|
||||||
*m_options = newOptions;
|
*m_options = newOptions;
|
||||||
m_options->toSettings(Core::ICore::instance()->settings());
|
m_options->toSettings(Core::ICore::instance()->settings());
|
||||||
|
if (changedMask & CdbOptions::DebuggerPathsChanged)
|
||||||
|
emit debuggerPathsChanged();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -83,6 +83,9 @@ public:
|
|||||||
// Load failure messages can be displayed here
|
// Load failure messages can be displayed here
|
||||||
void setFailureMessage(const QString &msg) { m_failureMessage = msg; }
|
void setFailureMessage(const QString &msg) { m_failureMessage = msg; }
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void debuggerPathsChanged();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const QSharedPointer<CdbOptions> m_options;
|
const QSharedPointer<CdbOptions> m_options;
|
||||||
QPointer<CdbOptionsPageWidget> m_widget;
|
QPointer<CdbOptionsPageWidget> m_widget;
|
||||||
|
|||||||
@@ -6,8 +6,8 @@
|
|||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>369</width>
|
<width>522</width>
|
||||||
<height>281</height>
|
<height>512</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="windowTitle">
|
<property name="windowTitle">
|
||||||
@@ -48,7 +48,7 @@
|
|||||||
</property>
|
</property>
|
||||||
<property name="sizeHint" stdset="0">
|
<property name="sizeHint" stdset="0">
|
||||||
<size>
|
<size>
|
||||||
<width>40</width>
|
<width>0</width>
|
||||||
<height>20</height>
|
<height>20</height>
|
||||||
</size>
|
</size>
|
||||||
</property>
|
</property>
|
||||||
@@ -56,6 +56,38 @@
|
|||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QGroupBox" name="pathGroupBox">
|
||||||
|
<property name="title">
|
||||||
|
<string>Debugger Paths</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QFormLayout" name="formLayout_2">
|
||||||
|
<property name="fieldGrowthPolicy">
|
||||||
|
<enum>QFormLayout::AllNonFixedFieldsGrow</enum>
|
||||||
|
</property>
|
||||||
|
<item row="0" column="0">
|
||||||
|
<widget class="QLabel" name="symbolPathLabel">
|
||||||
|
<property name="text">
|
||||||
|
<string>Symbol paths:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="1">
|
||||||
|
<widget class="Debugger::Internal::CdbSymbolPathListEditor" name="symbolPathListEditor" native="true"/>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="0">
|
||||||
|
<widget class="QLabel" name="sourcePathLabel">
|
||||||
|
<property name="text">
|
||||||
|
<string>Source paths:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="1">
|
||||||
|
<widget class="Core::Utils::PathListEditor" name="sourcePathListEditor" native="true"/>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<spacer name="verticalSpacer">
|
<spacer name="verticalSpacer">
|
||||||
<property name="orientation">
|
<property name="orientation">
|
||||||
@@ -64,7 +96,7 @@
|
|||||||
<property name="sizeHint" stdset="0">
|
<property name="sizeHint" stdset="0">
|
||||||
<size>
|
<size>
|
||||||
<width>20</width>
|
<width>20</width>
|
||||||
<height>223</height>
|
<height>203</height>
|
||||||
</size>
|
</size>
|
||||||
</property>
|
</property>
|
||||||
</spacer>
|
</spacer>
|
||||||
@@ -91,6 +123,18 @@
|
|||||||
<header location="global">utils/pathchooser.h</header>
|
<header location="global">utils/pathchooser.h</header>
|
||||||
<container>1</container>
|
<container>1</container>
|
||||||
</customwidget>
|
</customwidget>
|
||||||
|
<customwidget>
|
||||||
|
<class>Core::Utils::PathListEditor</class>
|
||||||
|
<extends>QWidget</extends>
|
||||||
|
<header location="global">utils/pathlisteditor.h</header>
|
||||||
|
<container>1</container>
|
||||||
|
</customwidget>
|
||||||
|
<customwidget>
|
||||||
|
<class>Debugger::Internal::CdbSymbolPathListEditor</class>
|
||||||
|
<extends>QWidget</extends>
|
||||||
|
<header>cdbsymbolpathlisteditor.h</header>
|
||||||
|
<container>1</container>
|
||||||
|
</customwidget>
|
||||||
</customwidgets>
|
</customwidgets>
|
||||||
<resources/>
|
<resources/>
|
||||||
<connections/>
|
<connections/>
|
||||||
|
|||||||
59
src/plugins/debugger/cdb/cdbsymbolpathlisteditor.cpp
Normal file
59
src/plugins/debugger/cdb/cdbsymbolpathlisteditor.cpp
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
/**************************************************************************
|
||||||
|
**
|
||||||
|
** This file is part of Qt Creator
|
||||||
|
**
|
||||||
|
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
|
||||||
|
**
|
||||||
|
** Contact: Qt Software Information (qt-info@nokia.com)
|
||||||
|
**
|
||||||
|
** Commercial Usage
|
||||||
|
**
|
||||||
|
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||||
|
** accordance with the Qt Commercial License Agreement provided with the
|
||||||
|
** Software or, alternatively, in accordance with the terms contained in
|
||||||
|
** a written agreement between you and Nokia.
|
||||||
|
**
|
||||||
|
** 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.
|
||||||
|
**
|
||||||
|
** If you are unsure which license is appropriate for your use, please
|
||||||
|
** contact the sales department at qt-sales@nokia.com.
|
||||||
|
**
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
#include "cdbsymbolpathlisteditor.h"
|
||||||
|
|
||||||
|
#include <QtGui/QFileDialog>
|
||||||
|
#include <QtGui/QAction>
|
||||||
|
|
||||||
|
namespace Debugger {
|
||||||
|
namespace Internal {
|
||||||
|
|
||||||
|
CdbSymbolPathListEditor::CdbSymbolPathListEditor(QWidget *parent) :
|
||||||
|
Core::Utils::PathListEditor(parent)
|
||||||
|
{
|
||||||
|
//! Add Microsoft Symbol server connection
|
||||||
|
QAction *action = insertAction(lastAddActionIndex() + 1, tr("Symbol Server..."), this, SLOT(addSymbolServer()));
|
||||||
|
action->setToolTip(tr("Adds the Microsoft symbol server providing symbols for operating system libraries."
|
||||||
|
"Requires specifying a local cache directory."));
|
||||||
|
}
|
||||||
|
|
||||||
|
void CdbSymbolPathListEditor::addSymbolServer()
|
||||||
|
{
|
||||||
|
const QString title = tr("Pick a local cache directory");
|
||||||
|
const QString cacheDir = QFileDialog::getExistingDirectory(this, title);
|
||||||
|
if (!cacheDir.isEmpty()) {
|
||||||
|
const QString path = QString::fromLatin1("symsrv*symsrv.dll*%1*http://msdl.microsoft.com/download/symbols").
|
||||||
|
arg(QDir::toNativeSeparators(cacheDir));
|
||||||
|
insertPathAtCursor(path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Internal
|
||||||
|
} // namespace Debugger
|
||||||
51
src/plugins/debugger/cdb/cdbsymbolpathlisteditor.h
Normal file
51
src/plugins/debugger/cdb/cdbsymbolpathlisteditor.h
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
/**************************************************************************
|
||||||
|
**
|
||||||
|
** This file is part of Qt Creator
|
||||||
|
**
|
||||||
|
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
|
||||||
|
**
|
||||||
|
** Contact: Qt Software Information (qt-info@nokia.com)
|
||||||
|
**
|
||||||
|
** Commercial Usage
|
||||||
|
**
|
||||||
|
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||||
|
** accordance with the Qt Commercial License Agreement provided with the
|
||||||
|
** Software or, alternatively, in accordance with the terms contained in
|
||||||
|
** a written agreement between you and Nokia.
|
||||||
|
**
|
||||||
|
** 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.
|
||||||
|
**
|
||||||
|
** If you are unsure which license is appropriate for your use, please
|
||||||
|
** contact the sales department at qt-sales@nokia.com.
|
||||||
|
**
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
#ifndef SYMBOLPATHLISTEDITOR_H
|
||||||
|
#define SYMBOLPATHLISTEDITOR_H
|
||||||
|
|
||||||
|
#include <utils/pathlisteditor.h>
|
||||||
|
|
||||||
|
namespace Debugger {
|
||||||
|
namespace Internal {
|
||||||
|
|
||||||
|
class CdbSymbolPathListEditor : public Core::Utils::PathListEditor
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit CdbSymbolPathListEditor(QWidget *parent = 0);
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void addSymbolServer();
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace Internal
|
||||||
|
} // namespace Debugger
|
||||||
|
|
||||||
|
#endif // SYMBOLPATHLISTEDITOR_H
|
||||||
Reference in New Issue
Block a user