diff options
author | David Schulz <david.schulz@digia.com> | 2013-04-30 07:25:42 -0700 |
---|---|---|
committer | David Schulz <david.schulz@digia.com> | 2013-05-15 14:02:17 +0200 |
commit | 70336e30809b972f564c6cc57b012b2fbaad9ab8 (patch) | |
tree | b9ca32ed3b766a888255ec408e695f66790882db /src | |
parent | 1bf0343acc5d59f34a7b56d27b17459df9c97838 (diff) | |
download | qt-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.cpp | 4 | ||||
-rw-r--r-- | src/plugins/debugger/cdb/cdboptionspage.cpp | 101 | ||||
-rw-r--r-- | src/plugins/debugger/cdb/cdboptionspage.h | 29 | ||||
-rw-r--r-- | src/plugins/debugger/cdb/cdboptionspagewidget.ui | 129 | ||||
-rw-r--r-- | src/plugins/debugger/debugger.qbs | 3 | ||||
-rw-r--r-- | src/plugins/debugger/shared/cdbsymbolpathlisteditor.cpp | 152 | ||||
-rw-r--r-- | src/plugins/debugger/shared/cdbsymbolpathlisteditor.h | 26 | ||||
-rw-r--r-- | src/plugins/debugger/shared/shared.pri | 9 | ||||
-rw-r--r-- | src/plugins/debugger/shared/symbolpathsdialog.cpp | 104 | ||||
-rw-r--r-- | src/plugins/debugger/shared/symbolpathsdialog.h | 70 | ||||
-rw-r--r-- | src/plugins/debugger/shared/symbolpathsdialog.ui | 152 |
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><html><head/><body><p>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.</p></body></html></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><html><head/><body><p>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.</p></body></html></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><html><head/><body> +<p>The debugger is not configured to use the public Microsoft Symbol Server.<br>This is recommended for retrieval of the symbols of the operating system libraries.</p> +<p><span style=" font-style:italic;">Note:</span> It is recommended, that if you use the Microsoft Symbol Server, to also use a local symbol cache.<br>Also, a fast internet connection is required for this to work smoothly,<br>and a delay might occur when connecting for the first time, when caching the symbols for the first time.</p> +<p>Would you like to set it up?</p> +</body></html></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> |