summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDavid Schulz <david.schulz@digia.com>2013-04-30 07:25:42 -0700
committerDavid Schulz <david.schulz@digia.com>2013-05-15 14:02:17 +0200
commit70336e30809b972f564c6cc57b012b2fbaad9ab8 (patch)
treeb9ca32ed3b766a888255ec408e695f66790882db /src
parent1bf0343acc5d59f34a7b56d27b17459df9c97838 (diff)
downloadqt-creator-70336e30809b972f564c6cc57b012b2fbaad9ab8.tar.gz
Debugger: Add CDB symbol cache option.
Change-Id: I9c4ec9bbcc0216271d6e4d10e9f6e925d3569cea Reviewed-by: Friedemann Kleint <Friedemann.Kleint@digia.com>
Diffstat (limited to 'src')
-rw-r--r--src/plugins/debugger/cdb/cdbengine.cpp4
-rw-r--r--src/plugins/debugger/cdb/cdboptionspage.cpp101
-rw-r--r--src/plugins/debugger/cdb/cdboptionspage.h29
-rw-r--r--src/plugins/debugger/cdb/cdboptionspagewidget.ui129
-rw-r--r--src/plugins/debugger/debugger.qbs3
-rw-r--r--src/plugins/debugger/shared/cdbsymbolpathlisteditor.cpp152
-rw-r--r--src/plugins/debugger/shared/cdbsymbolpathlisteditor.h26
-rw-r--r--src/plugins/debugger/shared/shared.pri9
-rw-r--r--src/plugins/debugger/shared/symbolpathsdialog.cpp104
-rw-r--r--src/plugins/debugger/shared/symbolpathsdialog.h70
-rw-r--r--src/plugins/debugger/shared/symbolpathsdialog.ui152
11 files changed, 526 insertions, 253 deletions
diff --git a/src/plugins/debugger/cdb/cdbengine.cpp b/src/plugins/debugger/cdb/cdbengine.cpp
index 671e101df7..df81a1cc88 100644
--- a/src/plugins/debugger/cdb/cdbengine.cpp
+++ b/src/plugins/debugger/cdb/cdbengine.cpp
@@ -582,8 +582,8 @@ void CdbEngine::setupEngine()
{
if (debug)
qDebug(">setupEngine");
- // Nag to add symbol server
- if (CdbSymbolPathListEditor::promptToAddSymbolServer(CdbOptions::settingsGroup(),
+ // Nag to add symbol server and cache
+ if (CdbSymbolPathListEditor::promptToAddSymbolPaths(CdbOptions::settingsGroup(),
&(m_options->symbolPaths)))
m_options->toSettings(Core::ICore::settings());
diff --git a/src/plugins/debugger/cdb/cdboptionspage.cpp b/src/plugins/debugger/cdb/cdboptionspage.cpp
index 96875bf5aa..d98040f3e8 100644
--- a/src/plugins/debugger/cdb/cdboptionspage.cpp
+++ b/src/plugins/debugger/cdb/cdboptionspage.cpp
@@ -154,48 +154,11 @@ QStringList CdbBreakEventWidget::breakEvents() const
return rc;
}
-CdbPathDialog::CdbPathDialog(QWidget *parent, Mode mode)
- : QDialog(parent)
- , m_pathListEditor(0)
-{
- setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
- setMinimumWidth(700);
-
- switch (mode) {
- case SymbolPaths:
- setWindowTitle(tr("CDB Symbol Paths"));
- m_pathListEditor = new CdbSymbolPathListEditor(this);
- break;
- case SourcePaths:
- setWindowTitle(tr("CDB Source Paths"));
- m_pathListEditor = new Utils::PathListEditor(this);
- break;
- }
-
- QVBoxLayout *layout = new QVBoxLayout(this);
- QGroupBox *groupBox = new QGroupBox(this);
- (new QVBoxLayout(groupBox))->addWidget(m_pathListEditor);
- layout->addWidget(groupBox);
- QDialogButtonBox *buttonBox =
- new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel,
- Qt::Horizontal, this);
- connect(buttonBox, SIGNAL(accepted()), this, SLOT(accept()));
- connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject()));
- layout->addWidget(buttonBox);
-}
-
-QStringList CdbPathDialog::paths() const
-{
- return m_pathListEditor->pathList();
-}
-
-void CdbPathDialog::setPaths(const QStringList &paths)
-{
- m_pathListEditor->setPathList(paths);
-}
-
-CdbOptionsPageWidget::CdbOptionsPageWidget(QWidget *parent) :
- QWidget(parent), m_breakEventWidget(new CdbBreakEventWidget)
+CdbOptionsPageWidget::CdbOptionsPageWidget(QWidget *parent)
+ : QWidget(parent)
+ , m_breakEventWidget(new CdbBreakEventWidget)
+ , m_symbolPathListEditor(new CdbSymbolPathListEditor)
+ , m_sourcePathListEditor(new Utils::PathListEditor)
{
m_ui.setupUi(this);
// Squeeze the groupbox layouts vertically to
@@ -206,8 +169,6 @@ CdbOptionsPageWidget::CdbOptionsPageWidget(QWidget *parent) :
const QMargins margins(margin, margin / 3, margin, margin / 3);
m_ui.startupFormLayout->setContentsMargins(margins);
- m_ui.pathGroupBox->layout()->setContentsMargins(margins);
- m_ui.breakpointLayout->setContentsMargins(margins);
QVBoxLayout *eventLayout = new QVBoxLayout;
eventLayout->setContentsMargins(margins);
@@ -219,33 +180,15 @@ CdbOptionsPageWidget::CdbOptionsPageWidget(QWidget *parent) :
m_ui.breakCrtDbgReportCheckBox
->setToolTip(CommonOptionsPage::msgSetBreakpointAtFunctionToolTip(CdbOptions::crtDbgReport, hint));
- connect(m_ui.symbolPathButton, SIGNAL(clicked()), this, SLOT(showSymbolPathDialog()));
- connect(m_ui.sourcePathButton, SIGNAL(clicked()), this, SLOT(showSourcePathDialog()));
-}
-
-void CdbOptionsPageWidget::setSymbolPaths(const QStringList &s)
-{
- m_symbolPaths = s;
- const QString summary =
- tr("Symbol paths: %1").arg(m_symbolPaths.isEmpty() ?
- tr("<none>") : QString::number(m_symbolPaths.size()));
- m_ui.symbolPathLabel->setText(summary);
-}
-
-void CdbOptionsPageWidget::setSourcePaths(const QStringList &s)
-{
- m_sourcePaths = s;
- const QString summary =
- tr("Source paths: %1").arg(m_sourcePaths.isEmpty() ?
- tr("<none>") : QString::number(m_sourcePaths.size()));
- m_ui.sourcePathLabel->setText(summary);
+ m_ui.symbolPathsGroupBox->layout()->addWidget(m_symbolPathListEditor);
+ m_ui.sourcePathsGroupBox->layout()->addWidget(m_sourcePathListEditor);
}
void CdbOptionsPageWidget::setOptions(CdbOptions &o)
{
m_ui.additionalArgumentsLineEdit->setText(o.additionalArguments);
- setSymbolPaths(o.symbolPaths);
- setSourcePaths(o.sourcePaths);
+ m_symbolPathListEditor->setPathList(o.symbolPaths);
+ m_sourcePathListEditor->setPathList(o.sourcePaths);
m_ui.ignoreFirstChanceAccessViolationCheckBox->setChecked(o.ignoreFirstChanceAccessViolation);
m_breakEventWidget->setBreakEvents(o.breakEvents);
m_ui.consoleCheckBox->setChecked(o.cdbConsole);
@@ -257,8 +200,8 @@ CdbOptions CdbOptionsPageWidget::options() const
{
CdbOptions rc;
rc.additionalArguments = m_ui.additionalArgumentsLineEdit->text().trimmed();
- rc.symbolPaths = m_symbolPaths;
- rc.sourcePaths = m_sourcePaths;
+ rc.symbolPaths = m_symbolPathListEditor->pathList();
+ rc.sourcePaths = m_sourcePathListEditor->pathList();
rc.ignoreFirstChanceAccessViolation = m_ui.ignoreFirstChanceAccessViolationCheckBox->isChecked();
rc.breakEvents = m_breakEventWidget->breakEvents();
rc.cdbConsole = m_ui.consoleCheckBox->isChecked();
@@ -268,22 +211,6 @@ CdbOptions CdbOptionsPageWidget::options() const
return rc;
}
-void CdbOptionsPageWidget::showSymbolPathDialog()
-{
- CdbPathDialog pathDialog(this, CdbPathDialog::SymbolPaths);
- pathDialog.setPaths(m_symbolPaths);
- if (pathDialog.exec() == QDialog::Accepted)
- setSymbolPaths(pathDialog.paths());
-}
-
-void CdbOptionsPageWidget::showSourcePathDialog()
-{
- CdbPathDialog pathDialog(this, CdbPathDialog::SourcePaths);
- pathDialog.setPaths(m_sourcePaths);
- if (pathDialog.exec() == QDialog::Accepted)
- setSourcePaths(pathDialog.paths());
-}
-
static QString stripColon(QString s)
{
const int lastColon = s.lastIndexOf(QLatin1Char(':'));
@@ -297,10 +224,8 @@ QString CdbOptionsPageWidget::searchKeywords() const
QString rc;
QTextStream(&rc)
<< stripColon(m_ui.additionalArgumentsLabel->text()) << ' '
- << stripColon(m_ui.breakFunctionGroupBox->title()) << ' '
- << m_ui.breakpointsGroupBox->title() << ' '
- << stripColon(m_ui.symbolPathLabel->text()) << ' '
- << stripColon(m_ui.sourcePathLabel->text());
+ << m_ui.symbolPathsGroupBox->title() << ' '
+ << m_ui.sourcePathsGroupBox->title();
rc.remove(QLatin1Char('&'));
return rc;
}
diff --git a/src/plugins/debugger/cdb/cdboptionspage.h b/src/plugins/debugger/cdb/cdboptionspage.h
index 01dcad7d34..0d3d0c7e9b 100644
--- a/src/plugins/debugger/cdb/cdboptionspage.h
+++ b/src/plugins/debugger/cdb/cdboptionspage.h
@@ -72,24 +72,6 @@ private:
QList<QLineEdit*> m_lineEdits;
};
-class CdbPathDialog : public QDialog
-{
- Q_OBJECT
-public:
- enum Mode {
- SymbolPaths,
- SourcePaths
- };
-
- explicit CdbPathDialog(QWidget *parent, Mode mode);
-
- QStringList paths() const;
- void setPaths(const QStringList &paths);
-
-private:
- Utils::PathListEditor *m_pathListEditor;
-};
-
class CdbOptionsPageWidget : public QWidget
{
Q_OBJECT
@@ -102,20 +84,13 @@ public:
QString searchKeywords() const;
-private slots:
- void showSymbolPathDialog();
- void showSourcePathDialog();
-
private:
- void setSymbolPaths(const QStringList &);
- void setSourcePaths(const QStringList &);
-
inline QString path() const;
Ui::CdbOptionsPageWidget m_ui;
CdbBreakEventWidget *m_breakEventWidget;
- QStringList m_symbolPaths;
- QStringList m_sourcePaths;
+ CdbSymbolPathListEditor *m_symbolPathListEditor;
+ Utils::PathListEditor *m_sourcePathListEditor;
};
class CdbOptionsPage : public Core::IOptionsPage
diff --git a/src/plugins/debugger/cdb/cdboptionspagewidget.ui b/src/plugins/debugger/cdb/cdboptionspagewidget.ui
index 647449105f..6df830facc 100644
--- a/src/plugins/debugger/cdb/cdboptionspagewidget.ui
+++ b/src/plugins/debugger/cdb/cdboptionspagewidget.ui
@@ -54,80 +54,6 @@
</layout>
</widget>
</item>
- <item row="0" column="1">
- <widget class="QGroupBox" name="pathGroupBox">
- <property name="title">
- <string>Paths</string>
- </property>
- <layout class="QGridLayout" name="gridLayout">
- <item row="0" column="0">
- <widget class="QLabel" name="symbolPathLabel">
- <property name="sizePolicy">
- <sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- </widget>
- </item>
- <item row="0" column="1">
- <widget class="QPushButton" name="symbolPathButton">
- <property name="text">
- <string>Edit...</string>
- </property>
- </widget>
- </item>
- <item row="1" column="0">
- <widget class="QLabel" name="sourcePathLabel">
- <property name="sizePolicy">
- <sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- </widget>
- </item>
- <item row="1" column="1">
- <widget class="QPushButton" name="sourcePathButton">
- <property name="text">
- <string>Edit...</string>
- </property>
- </widget>
- </item>
- </layout>
- </widget>
- </item>
- <item row="1" column="0">
- <widget class="QGroupBox" name="breakpointsGroupBox">
- <property name="title">
- <string>Breakpoints</string>
- </property>
- <layout class="QVBoxLayout" name="breakpointLayout">
- <item>
- <widget class="QCheckBox" name="breakpointCorrectionCheckBox">
- <property name="toolTip">
- <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Attempt to correct the location of a breakpoint based on file and line number should it be in a comment or in a line for which no code is generated. The correction is based on the code model.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
- </property>
- <property name="text">
- <string>Correct breakpoint location</string>
- </property>
- </widget>
- </item>
- </layout>
- </widget>
- </item>
- <item row="1" column="1">
- <widget class="QGroupBox" name="breakFunctionGroupBox">
- <property name="title">
- <string>Break on functions:</string>
- </property>
- <layout class="QVBoxLayout" name="verticalLayout_2">
- <item>
- <widget class="QCheckBox" name="breakCrtDbgReportCheckBox"/>
- </item>
- </layout>
- </widget>
- </item>
<item row="2" column="0" colspan="2">
<widget class="QGroupBox" name="eventGroupBox">
<property name="title">
@@ -135,22 +61,55 @@
</property>
</widget>
</item>
+ <item row="0" column="1">
+ <layout class="QVBoxLayout" name="verticalLayout_4">
+ <item>
+ <widget class="QGroupBox" name="variousGroupBox">
+ <property name="title">
+ <string>Various</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout_3">
+ <item>
+ <widget class="QCheckBox" name="ignoreFirstChanceAccessViolationCheckBox">
+ <property name="text">
+ <string>Ignore first chance access violations</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="breakCrtDbgReportCheckBox"/>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="breakpointCorrectionCheckBox">
+ <property name="toolTip">
+ <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Attempt to correct the location of a breakpoint based on file and line number should it be in a comment or in a line for which no code is generated. The correction is based on the code model.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
+ </property>
+ <property name="text">
+ <string>Correct breakpoint location</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ </layout>
+ </item>
</layout>
</item>
<item>
- <widget class="QGroupBox" name="variousGroupBox">
+ <widget class="QGroupBox" name="symbolPathsGroupBox">
<property name="title">
- <string>Various</string>
+ <string>Symbol Paths</string>
</property>
- <layout class="QVBoxLayout" name="verticalLayout_3">
- <item>
- <widget class="QCheckBox" name="ignoreFirstChanceAccessViolationCheckBox">
- <property name="text">
- <string>Ignore first chance access violations</string>
- </property>
- </widget>
- </item>
- </layout>
+ <layout class="QGridLayout" name="gridLayout_3"/>
+ </widget>
+ </item>
+ <item>
+ <widget class="QGroupBox" name="sourcePathsGroupBox">
+ <property name="title">
+ <string>Source Paths</string>
+ </property>
+ <layout class="QGridLayout" name="gridLayout_4"/>
</widget>
</item>
<item>
diff --git a/src/plugins/debugger/debugger.qbs b/src/plugins/debugger/debugger.qbs
index ce88d079c3..77cedce2d9 100644
--- a/src/plugins/debugger/debugger.qbs
+++ b/src/plugins/debugger/debugger.qbs
@@ -263,6 +263,9 @@ QtcPlugin {
"shared/hostutils.h",
"shared/peutils.cpp",
"shared/peutils.h",
+ "shared/symbolpathsdialog.ui",
+ "shared/symbolpathsdialog.cpp",
+ "shared/symbolpathsdialog.h",
]
Group {
diff --git a/src/plugins/debugger/shared/cdbsymbolpathlisteditor.cpp b/src/plugins/debugger/shared/cdbsymbolpathlisteditor.cpp
index 9d957a6ce9..eda4ba18f5 100644
--- a/src/plugins/debugger/shared/cdbsymbolpathlisteditor.cpp
+++ b/src/plugins/debugger/shared/cdbsymbolpathlisteditor.cpp
@@ -34,10 +34,14 @@
#include <utils/pathchooser.h>
#include <utils/checkablemessagebox.h>
+#include <symbolpathsdialog.h>
+
+#include <QCheckBox>
#include <QDir>
#include <QDebug>
#include <QAction>
#include <QFormLayout>
+#include <QLabel>
namespace Debugger {
namespace Internal {
@@ -77,10 +81,13 @@ QString CacheDirectoryDialog::path() const
void CacheDirectoryDialog::accept()
{
- // Ensure path exists
QString cache = path();
- if (cache.isEmpty())
+ // if cache is empty a default is used by the cdb
+ if (cache.isEmpty()) {
+ QDialog::accept();
return;
+ }
+ // Ensure path exists
QFileInfo fi(cache);
// Folder exists - all happy.
if (fi.isDir()) {
@@ -105,8 +112,9 @@ void CacheDirectoryDialog::accept()
// ---------------- CdbSymbolPathListEditor
-const char *CdbSymbolPathListEditor::symbolServerPrefixC = "symsrv*symsrv.dll*";
-const char *CdbSymbolPathListEditor::symbolServerPostfixC = "*http://msdl.microsoft.com/download/symbols";
+const char *CdbSymbolPathListEditor::symbolServerPrefixC = "srv*";
+const char *CdbSymbolPathListEditor::symbolServerPostfixC = "http://msdl.microsoft.com/download/symbols";
+const char *CdbSymbolPathListEditor::symbolCachePrefixC = "cache*";
CdbSymbolPathListEditor::CdbSymbolPathListEditor(QWidget *parent) :
Utils::PathListEditor(parent)
@@ -115,86 +123,146 @@ CdbSymbolPathListEditor::CdbSymbolPathListEditor(QWidget *parent) :
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."));
+ action = insertAction(lastAddActionIndex() + 1, tr("Symbol Cache..."), this, SLOT(addSymbolCache()));
+ action->setToolTip(tr("Uses a directory to cache symbols used by the debugger."));
}
-QString CdbSymbolPathListEditor::promptCacheDirectory(QWidget *parent)
+bool CdbSymbolPathListEditor::promptCacheDirectory(QWidget *parent, QString *cacheDirectory)
{
CacheDirectoryDialog dialog(parent);
dialog.setPath(QDir::tempPath() + QDir::separator() + QLatin1String("symbolcache"));
if (dialog.exec() != QDialog::Accepted)
- return QString();
- return dialog.path();
+ return false;
+ *cacheDirectory = dialog.path();
+ return true;
}
void CdbSymbolPathListEditor::addSymbolServer()
{
- const QString cacheDir = promptCacheDirectory(this);
- if (!cacheDir.isEmpty())
- insertPathAtCursor(CdbSymbolPathListEditor::symbolServerPath(cacheDir));
+ addSymbolPath(SymbolServerPath);
}
-QString CdbSymbolPathListEditor::symbolServerPath(const QString &cacheDir)
+void CdbSymbolPathListEditor::addSymbolCache()
{
+ addSymbolPath(SymbolCachePath);
+}
+
+void CdbSymbolPathListEditor::addSymbolPath(CdbSymbolPathListEditor::SymbolPathMode mode)
+{
+ QString cacheDir;
+ if (promptCacheDirectory(this, &cacheDir))
+ insertPathAtCursor(CdbSymbolPathListEditor::symbolPath(cacheDir, mode));
+}
+
+QString CdbSymbolPathListEditor::symbolPath(const QString &cacheDir,
+ CdbSymbolPathListEditor::SymbolPathMode mode)
+{
+ if (mode == SymbolCachePath)
+ return QLatin1String(symbolCachePrefixC) + QDir::toNativeSeparators(cacheDir);
QString s = QLatin1String(symbolServerPrefixC);
- s += QDir::toNativeSeparators(cacheDir);
+ if (!cacheDir.isEmpty())
+ s += QDir::toNativeSeparators(cacheDir) + QLatin1String("*");
s += QLatin1String(symbolServerPostfixC);
return s;
}
bool CdbSymbolPathListEditor::isSymbolServerPath(const QString &path, QString *cacheDir /* = 0 */)
{
- // Split apart symbol server post/prefixes
if (!path.startsWith(QLatin1String(symbolServerPrefixC)) || !path.endsWith(QLatin1String(symbolServerPostfixC)))
return false;
if (cacheDir) {
- const unsigned prefixLength = qstrlen(symbolServerPrefixC);
- *cacheDir = path.mid(prefixLength, path.size() - prefixLength - qstrlen(symbolServerPostfixC));
+ static const unsigned prefixLength = qstrlen(symbolServerPrefixC);
+ static const unsigned postfixLength = qstrlen(symbolServerPostfixC);
+ if (path.length() == prefixLength + postfixLength)
+ return true;
+ // Split apart symbol server post/prefixes
+ *cacheDir = path.mid(prefixLength, path.size() - prefixLength - qstrlen(symbolServerPostfixC) + 1);
}
return true;
}
-int CdbSymbolPathListEditor::indexOfSymbolServerPath(const QStringList &paths, QString *cacheDir /* = 0 */)
+bool CdbSymbolPathListEditor::isSymbolCachePath(const QString &path, QString *cacheDir)
+{
+ if (!path.startsWith(QLatin1String(symbolCachePrefixC)))
+ return false;
+ if (cacheDir) {
+ static const unsigned prefixLength = qstrlen(symbolCachePrefixC);
+ // Split apart symbol cach prefixes
+ *cacheDir = path.mid(prefixLength);
+ }
+ return true;
+}
+
+int CdbSymbolPathListEditor::indexOfSymbolPath(const QStringList &paths,
+ CdbSymbolPathListEditor::SymbolPathMode mode,
+ QString *cacheDir /* = 0 */)
{
const int count = paths.size();
- for (int i = 0; i < count; i++)
- if (CdbSymbolPathListEditor::isSymbolServerPath(paths.at(i), cacheDir))
- return i;
+ for (int i = 0; i < count; i++) {
+ if (mode == SymbolServerPath
+ ? CdbSymbolPathListEditor::isSymbolServerPath(paths.at(i), cacheDir)
+ : CdbSymbolPathListEditor::isSymbolCachePath(paths.at(i), cacheDir)) {
+ return i;
+ }
+ }
return -1;
}
-bool CdbSymbolPathListEditor::promptToAddSymbolServer(const QString &settingsGroup, QStringList *symbolPaths)
+bool CdbSymbolPathListEditor::promptToAddSymbolPaths(const QString &settingsGroup,
+ QStringList *symbolPaths)
{
- // Check symbol server unless the user has an external/internal setup
+ const int indexOfSymbolServer =
+ CdbSymbolPathListEditor::indexOfSymbolPath(*symbolPaths, SymbolServerPath);
+ const int indexOfSymbolCache =
+ CdbSymbolPathListEditor::indexOfSymbolPath(*symbolPaths, SymbolCachePath);
+
if (!qgetenv("_NT_SYMBOL_PATH").isEmpty()
- || CdbSymbolPathListEditor::indexOfSymbolServerPath(*symbolPaths) != -1)
+ || (indexOfSymbolServer != -1 && indexOfSymbolCache != -1))
return false;
- // Prompt to use Symbol server unless the user checked "No nagging".
- const QString nagSymbolServerKey = settingsGroup + QLatin1String("/NoPromptSymbolServer");
+
+ const QString nagSymbolServerKey = settingsGroup + QLatin1String("/NoPromptSymbolCache");
bool noFurtherNagging = Core::ICore::settings()->value(nagSymbolServerKey, false).toBool();
if (noFurtherNagging)
return false;
- const QString symServUrl = QLatin1String("http://support.microsoft.com/kb/311503");
- const QString msg = tr("<html><head/><body><p>The debugger is not configured to use the public "
- "<a href=\"%1\">Microsoft Symbol Server</a>. This is recommended "
- "for retrieval of the symbols of the operating system libraries.</p>"
- "<p><i>Note:</i> A fast internet connection is required for this to work smoothly. Also, a delay "
- "might occur when connecting for the first time.</p>"
- "<p>Would you like to set it up?</p>"
- "</body></html>").arg(symServUrl);
- const QDialogButtonBox::StandardButton answer =
- Utils::CheckableMessageBox::question(Core::ICore::mainWindow(), tr("Symbol Server"), msg,
- tr("Do not ask again"), &noFurtherNagging);
+ QString path;
+ if (indexOfSymbolServer != -1)
+ path = symbolPaths->at(indexOfSymbolServer);
+ if (path.isEmpty() && indexOfSymbolCache != -1)
+ path = symbolPaths->at(indexOfSymbolCache);
+ if (path.isEmpty())
+ path = QDir::tempPath() + QDir::separator() + QLatin1String("symbolcache");
+
+ bool useSymbolServer = true;
+ bool useSymbolCache = true;
+ bool addSymbolPaths = SymbolPathsDialog::useCommonSymbolPaths(useSymbolCache,
+ useSymbolServer,
+ path, noFurtherNagging);
Core::ICore::settings()->setValue(nagSymbolServerKey, noFurtherNagging);
- if (answer == QDialogButtonBox::No)
- return false;
- // Prompt for path and add it. Synchronize QSetting and debugger.
- const QString cacheDir = CdbSymbolPathListEditor::promptCacheDirectory(Core::ICore::mainWindow());
- if (cacheDir.isEmpty())
+ if (!addSymbolPaths)
return false;
- symbolPaths->push_back(CdbSymbolPathListEditor::symbolServerPath(cacheDir));
- return true;
+ // remove old entries
+ if (indexOfSymbolServer > indexOfSymbolCache) {
+ symbolPaths->removeAt(indexOfSymbolServer);
+ if (indexOfSymbolCache != -1)
+ symbolPaths->removeAt(indexOfSymbolCache);
+ } else if (indexOfSymbolCache > indexOfSymbolServer) {
+ symbolPaths->removeAt(indexOfSymbolCache);
+ if (indexOfSymbolServer != -1)
+ symbolPaths->removeAt(indexOfSymbolServer);
+ }
+
+ if (useSymbolCache) {
+ symbolPaths->push_back(CdbSymbolPathListEditor::symbolPath(path, SymbolCachePath));
+ if (useSymbolServer)
+ symbolPaths->push_back(CdbSymbolPathListEditor::symbolPath(QString(), SymbolServerPath));
+ return true;
+ } else if (useSymbolServer) {
+ symbolPaths->push_back(CdbSymbolPathListEditor::symbolPath(path, SymbolServerPath));
+ return true;
+ }
+ return false;
}
} // namespace Internal
diff --git a/src/plugins/debugger/shared/cdbsymbolpathlisteditor.h b/src/plugins/debugger/shared/cdbsymbolpathlisteditor.h
index d5b0509b67..949b8ef9e5 100644
--- a/src/plugins/debugger/shared/cdbsymbolpathlisteditor.h
+++ b/src/plugins/debugger/shared/cdbsymbolpathlisteditor.h
@@ -52,7 +52,7 @@ namespace Internal {
// created. This is done here (suggest $TEMP\symbolcache
// regardless of its existence).
-class CacheDirectoryDialog : public QDialog {
+class CacheDirectoryDialog : public QDialog {
Q_OBJECT
public:
explicit CacheDirectoryDialog(QWidget *parent = 0);
@@ -71,26 +71,38 @@ class CdbSymbolPathListEditor : public Utils::PathListEditor
{
Q_OBJECT
public:
+ enum SymbolPathMode{
+ SymbolServerPath,
+ SymbolCachePath
+ };
+
explicit CdbSymbolPathListEditor(QWidget *parent = 0);
- static QString promptCacheDirectory(QWidget *parent);
+ static bool promptCacheDirectory(QWidget *parent, QString *cacheDirectory);
// Pre- and Postfix used to build a symbol server path specification
static const char *symbolServerPrefixC;
static const char *symbolServerPostfixC;
+ static const char *symbolCachePrefixC;
- // Format a symbol server specification with a local cache directory
- static QString symbolServerPath(const QString &cacheDir);
+ // Format a symbol path specification
+ static QString symbolPath(const QString &cacheDir, SymbolPathMode mode);
// Check for a symbol server path and extract local cache directory
static bool isSymbolServerPath(const QString &path, QString *cacheDir = 0);
+ // Check for a symbol cache path and extract local cache directory
+ static bool isSymbolCachePath(const QString &path, QString *cacheDir = 0);
// Check for symbol server in list of paths.
- static int indexOfSymbolServerPath(const QStringList &paths, QString *cacheDir = 0);
+ static int indexOfSymbolPath(const QStringList &paths, SymbolPathMode mode, QString *cacheDir = 0);
+
+ // Nag user to add a symbol cache and server to the path list on debugger startup.
+ static bool promptToAddSymbolPaths(const QString &settingsGroup, QStringList *symbolPaths);
- // Nag user to add a symbol server to the path list on debugger startup.
- static bool promptToAddSymbolServer(const QString &settingsGroup, QStringList *symbolPaths);
+private:
+ void addSymbolPath(SymbolPathMode mode);
private slots:
void addSymbolServer();
+ void addSymbolCache();
};
} // namespace Internal
diff --git a/src/plugins/debugger/shared/shared.pri b/src/plugins/debugger/shared/shared.pri
index 5a214b2524..a0021f598b 100644
--- a/src/plugins/debugger/shared/shared.pri
+++ b/src/plugins/debugger/shared/shared.pri
@@ -1,12 +1,14 @@
SOURCES += $$PWD/backtrace.cpp \
$$PWD/cdbsymbolpathlisteditor.cpp \
$$PWD/hostutils.cpp \
- $$PWD/peutils.cpp
+ $$PWD/peutils.cpp \
+ shared/symbolpathsdialog.cpp
HEADERS += $$PWD/backtrace.h \
$$PWD/cdbsymbolpathlisteditor.h \
$$PWD/hostutils.h \
- $$PWD/peutils.h
+ $$PWD/peutils.h \
+ shared/symbolpathsdialog.h
INCLUDEPATH += $$PWD
@@ -14,3 +16,6 @@ win32-msvc* {
# For the Privilege manipulation functions in sharedlibraryinjector.cpp.
LIBS += -ladvapi32
}
+
+FORMS += \
+ shared/symbolpathsdialog.ui
diff --git a/src/plugins/debugger/shared/symbolpathsdialog.cpp b/src/plugins/debugger/shared/symbolpathsdialog.cpp
new file mode 100644
index 0000000000..8d42050962
--- /dev/null
+++ b/src/plugins/debugger/shared/symbolpathsdialog.cpp
@@ -0,0 +1,104 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** 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.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+#include "symbolpathsdialog.h"
+#include "ui_symbolpathsdialog.h"
+#include "QMessageBox"
+
+using namespace Debugger;
+using namespace Internal;
+
+SymbolPathsDialog::SymbolPathsDialog(QWidget *parent) :
+ QDialog(parent),
+ ui(new Ui::SymbolPathsDialog)
+{
+ ui->setupUi(this);
+ ui->pixmapLabel->setPixmap(QMessageBox::standardIcon(QMessageBox::Question));
+}
+
+SymbolPathsDialog::~SymbolPathsDialog()
+{
+ delete ui;
+}
+
+bool SymbolPathsDialog::useSymbolCache() const
+{
+ return ui->useLocalSymbolCache->isChecked();
+}
+
+bool SymbolPathsDialog::useSymbolServer() const
+{
+ return ui->useSymbolServer->isChecked();
+}
+
+QString SymbolPathsDialog::path() const
+{
+ return ui->pathChooser->path();
+}
+
+bool SymbolPathsDialog::doNotAskAgain() const
+{
+ return ui->doNotAskAgain->isChecked();
+}
+
+void SymbolPathsDialog::setUseSymbolCache(bool useSymbolCache)
+{
+ ui->useLocalSymbolCache->setChecked(useSymbolCache);
+}
+
+void SymbolPathsDialog::setUseSymbolServer(bool useSymbolServer)
+{
+ ui->useSymbolServer->setChecked(useSymbolServer);
+}
+
+void SymbolPathsDialog::setPath(const QString &path)
+{
+ ui->pathChooser->setPath(path);
+}
+
+void SymbolPathsDialog::setDoNotAskAgain(bool doNotAskAgain) const
+{
+ ui->doNotAskAgain->setChecked(doNotAskAgain);
+}
+
+bool SymbolPathsDialog::useCommonSymbolPaths(bool &useSymbolCache, bool &useSymbolServer,
+ QString &path, bool &doNotAskAgain)
+{
+ SymbolPathsDialog dialog;
+ dialog.setUseSymbolCache(useSymbolCache);
+ dialog.setUseSymbolServer(useSymbolServer);
+ dialog.setPath(path);
+ dialog.setDoNotAskAgain(doNotAskAgain);
+ int ret = dialog.exec();
+ useSymbolCache = dialog.useSymbolCache();
+ useSymbolServer = dialog.useSymbolServer();
+ path = dialog.path();
+ doNotAskAgain = dialog.doNotAskAgain();
+ return ret == QDialog::Accepted;
+}
diff --git a/src/plugins/debugger/shared/symbolpathsdialog.h b/src/plugins/debugger/shared/symbolpathsdialog.h
new file mode 100644
index 0000000000..2a34627a76
--- /dev/null
+++ b/src/plugins/debugger/shared/symbolpathsdialog.h
@@ -0,0 +1,70 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** 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.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+#ifndef SYMBOLPATHSDIALOG_H
+#define SYMBOLPATHSDIALOG_H
+
+#include <QDialog>
+#include <QString>
+
+namespace Debugger {
+namespace Internal {
+
+namespace Ui {
+class SymbolPathsDialog;
+}
+
+class SymbolPathsDialog : public QDialog
+{
+ Q_OBJECT
+
+public:
+ explicit SymbolPathsDialog(QWidget *parent = 0);
+ ~SymbolPathsDialog();
+
+ bool useSymbolCache() const;
+ bool useSymbolServer() const;
+ QString path() const;
+ bool doNotAskAgain() const;
+
+ void setUseSymbolCache(bool useSymbolCache);
+ void setUseSymbolServer(bool useSymbolServer);
+ void setPath(const QString &path);
+ void setDoNotAskAgain(bool doNotAskAgain) const;
+
+ static bool useCommonSymbolPaths(bool &useSymbolCache, bool &useSymbolServer, QString &path, bool &doNotAskAgain);
+
+private:
+ Ui::SymbolPathsDialog *ui;
+};
+
+} // namespace Internal
+} // namespace Debugger
+
+#endif // SYMBOLPATHSDIALOG_H
diff --git a/src/plugins/debugger/shared/symbolpathsdialog.ui b/src/plugins/debugger/shared/symbolpathsdialog.ui
new file mode 100644
index 0000000000..4059bb31ac
--- /dev/null
+++ b/src/plugins/debugger/shared/symbolpathsdialog.ui
@@ -0,0 +1,152 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>Debugger::Internal::SymbolPathsDialog</class>
+ <widget class="QDialog" name="Debugger::Internal::SymbolPathsDialog">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>537</width>
+ <height>245</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Dialog</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <item>
+ <widget class="QLabel" name="pixmapLabel">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Minimum" vsizetype="Minimum">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignHCenter|Qt::AlignTop</set>
+ </property>
+ <property name="margin">
+ <number>5</number>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="msgLabel">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;
+&lt;p&gt;The debugger is not configured to use the public Microsoft Symbol Server.&lt;br&gt;This is recommended for retrieval of the symbols of the operating system libraries.&lt;/p&gt;
+&lt;p&gt;&lt;span style=&quot; font-style:italic;&quot;&gt;Note:&lt;/span&gt; It is recommended, that if you use the Microsoft Symbol Server, to also use a local symbol cache.&lt;br&gt;Also, a fast internet connection is required for this to work smoothly,&lt;br&gt;and a delay might occur when connecting for the first time, when caching the symbols for the first time.&lt;/p&gt;
+&lt;p&gt;Would you like to set it up?&lt;/p&gt;
+&lt;/body&gt;&lt;/html&gt;</string>
+ </property>
+ <property name="textFormat">
+ <enum>Qt::RichText</enum>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="useLocalSymbolCache">
+ <property name="text">
+ <string>Use Local Symbol Cache</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="useSymbolServer">
+ <property name="text">
+ <string>Use Microsoft Symbol Server</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="Utils::PathChooser" name="pathChooser" native="true"/>
+ </item>
+ <item>
+ <widget class="Line" name="line">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="doNotAskAgain">
+ <property name="text">
+ <string>Do not ask again</string>
+ </property>
+ <property name="tristate">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QDialogButtonBox" name="buttonBox">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="standardButtons">
+ <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <customwidgets>
+ <customwidget>
+ <class>Utils::PathChooser</class>
+ <extends>QWidget</extends>
+ <header>utils/pathchooser.h</header>
+ <container>1</container>
+ </customwidget>
+ </customwidgets>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>accepted()</signal>
+ <receiver>Debugger::Internal::SymbolPathsDialog</receiver>
+ <slot>accept()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>248</x>
+ <y>254</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>157</x>
+ <y>274</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>rejected()</signal>
+ <receiver>Debugger::Internal::SymbolPathsDialog</receiver>
+ <slot>reject()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>316</x>
+ <y>260</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>286</x>
+ <y>274</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>