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:
Friedemann Kleint
2009-05-08 16:56:48 +02:00
parent d971065b36
commit aa8548d37e
13 changed files with 347 additions and 46 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View 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

View 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