Commit a8133e08 authored by Leandro Melo's avatar Leandro Melo
Browse files

Merge branch 'master' of scm.dev.nokia.troll.no:creator/mainline

parents dc993fff a931a680
......@@ -42,7 +42,7 @@ struct CheckableMessageBoxPrivate;
/* A messagebox suitable for questions with a
* "Do not ask me again" checkbox. Emulates the QMessageBox API with
* static conveniences. */
* static conveniences. The message label can open external URLs. */
class QTCREATOR_UTILS_EXPORT CheckableMessageBox : public QDialog
{
......
......@@ -2,14 +2,6 @@
<ui version="4.0">
<class>Utils::CheckableMessageBox</class>
<widget class="QDialog" name="Utils::CheckableMessageBox">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>195</width>
<height>107</height>
</rect>
</property>
<property name="windowTitle">
<string>Dialog</string>
</property>
......@@ -19,7 +11,14 @@
<item>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QLabel" name="pixmapLabel"/>
<widget class="QLabel" name="pixmapLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
<item>
<spacer name="pixmapSpacer">
......@@ -41,8 +40,23 @@
</item>
<item>
<widget class="QLabel" name="messageLabel">
<property name="minimumSize">
<size>
<width>300</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>TextLabel</string>
<string notr="true">dummyText</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
<property name="openExternalLinks">
<bool>true</bool>
</property>
<property name="textInteractionFlags">
<set>Qt::LinksAccessibleByKeyboard|Qt::LinksAccessibleByMouse</set>
</property>
</widget>
</item>
......@@ -66,7 +80,7 @@
<item>
<widget class="QCheckBox" name="checkBox">
<property name="text">
<string>CheckBox</string>
<string notr="true">CheckBox</string>
</property>
</widget>
</item>
......
......@@ -39,6 +39,7 @@
#include "cdboptionspage.h"
#include "cdboptions.h"
#include "cdbexceptionutils.h"
#include "cdbsymbolpathlisteditor.h"
#include "debuggeragents.h"
#include "debuggeruiswitcher.h"
#include "debuggermainwindow.h"
......@@ -59,6 +60,7 @@
#include <utils/fancymainwindow.h>
#include <texteditor/itexteditor.h>
#include <utils/savedaction.h>
#include <utils/checkablemessagebox.h>
#include <QtCore/QDebug>
#include <QtCore/QTimer>
......@@ -347,11 +349,48 @@ void CdbDebugEnginePrivate::checkVersion()
}
}
void CdbDebugEngine::startupChecks()
{
// Check symbol server unless the user has an external/internal setup
if (!qgetenv("_NT_SYMBOL_PATH").isEmpty()
|| CdbOptions::indexOfSymbolServerPath(m_d->m_options->symbolPaths) != -1)
return;
// Prompt to use Symbol server unless the user checked "No nagging".
Core::ICore *core = Core::ICore::instance();
const QString nagSymbolServerKey = CdbOptions::settingsGroup() + QLatin1String("/NoPromptSymbolServer");
bool noFurtherNagging = core->settings()->value(nagSymbolServerKey, false).toBool();
if (noFurtherNagging)
return;
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></br>"
"</body></html>").arg(symServUrl);
const QDialogButtonBox::StandardButton answer =
Utils::CheckableMessageBox::question(core->mainWindow(), tr("Symbol Server"), msg,
tr("Do not ask again"), &noFurtherNagging);
core->settings()->setValue(nagSymbolServerKey, noFurtherNagging);
if (answer == QDialogButtonBox::No)
return;
// Prompt for path and add it. Synchronize QSetting and debugger.
const QString cacheDir = CdbSymbolPathListEditor::promptCacheDirectory(core->mainWindow());
if (cacheDir.isEmpty())
return;
m_d->m_options->symbolPaths.push_back(CdbOptions::symbolServerPath(cacheDir));
m_d->m_options->toSettings(core->settings());
syncDebuggerPaths();
}
void CdbDebugEngine::startDebugger(const QSharedPointer<DebuggerStartParameters> &sp)
{
if (debugCDBExecution)
qDebug() << "startDebugger" << *sp;
CdbCore::BreakPoint::clearNormalizeFileNameCache();
startupChecks();
setState(AdapterStarting, Q_FUNC_INFO, __LINE__);
m_d->checkVersion();
if (m_d->m_hDebuggeeProcess) {
......
......@@ -112,6 +112,7 @@ private slots:
void warning(const QString &w);
private:
void startupChecks();
void setState(DebuggerState state, const char *func, int line);
inline bool startAttachDebugger(qint64 pid, DebuggerStartMode sm, QString *errorMessage);
void processTerminated(unsigned long exitCode);
......
......@@ -50,6 +50,11 @@ CdbOptions::CdbOptions() :
{
}
QString CdbOptions::settingsGroup()
{
return QLatin1String(settingsGroupC);
}
void CdbOptions::clear()
{
enabled = false;
......@@ -99,5 +104,37 @@ unsigned CdbOptions::compare(const CdbOptions &rhs) const
return rc;
}
static const char symbolServerPrefixC[] = "symsrv*symsrv.dll*";
static const char symbolServerPostfixC[] = "*http://msdl.microsoft.com/download/symbols";
QString CdbOptions::symbolServerPath(const QString &cacheDir)
{
QString s = QLatin1String(symbolServerPrefixC);
s += QDir::toNativeSeparators(cacheDir);
s += QLatin1String(symbolServerPostfixC);
return s;
}
bool CdbOptions::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));
}
return true;
}
int CdbOptions::indexOfSymbolServerPath(const QStringList &paths, QString *cacheDir /* = 0 */)
{
const int count = paths.size();
for (int i = 0; i < count; i++)
if (CdbOptions::isSymbolServerPath(paths.at(i), cacheDir))
return i;
return -1;
}
} // namespace Internal
} // namespace Debugger
......@@ -54,6 +54,14 @@ public:
SymbolOptionsChanged = 0x4 };
unsigned compare(const CdbOptions &s) const;
// Format a symbol server specification with a cache directory
static QString symbolServerPath(const QString &cacheDir);
// Check whether the path is a symbol server specification and return the cache directory
static bool isSymbolServerPath(const QString &symbolPath, QString *cacheDir = 0);
static int indexOfSymbolServerPath(const QStringList &symbolPaths, QString *cacheDir = 0);
static QString settingsGroup();
bool enabled;
QString path;
QStringList symbolPaths;
......
......@@ -28,13 +28,83 @@
**************************************************************************/
#include "cdbsymbolpathlisteditor.h"
#include "cdboptions.h"
#include <utils/pathchooser.h>
#include <QtCore/QDir>
#include <QtCore/QDebug>
#include <QtGui/QFileDialog>
#include <QtGui/QAction>
#include <QtGui/QDialogButtonBox>
#include <QtGui/QVBoxLayout>
#include <QtGui/QFormLayout>
#include <QtGui/QMessageBox>
namespace Debugger {
namespace Internal {
CacheDirectoryDialog::CacheDirectoryDialog(QWidget *parent) :
QDialog(parent), m_chooser(new Utils::PathChooser),
m_buttonBox(new QDialogButtonBox(QDialogButtonBox::Ok|QDialogButtonBox::Cancel))
{
setWindowTitle(tr("Select Local Cache Folder"));
setModal(true);
setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
QFormLayout *formLayout = new QFormLayout;
m_chooser->setExpectedKind(Utils::PathChooser::Directory);
m_chooser->setMinimumWidth(400);
formLayout->addRow(tr("Path:"), m_chooser);
QVBoxLayout *mainLayout = new QVBoxLayout;
mainLayout->addLayout(formLayout);
mainLayout->addWidget(m_buttonBox);
setLayout(mainLayout);
connect(m_buttonBox, SIGNAL(accepted()), this, SLOT(accept()));
connect(m_buttonBox, SIGNAL(rejected()), this, SLOT(reject()));
}
void CacheDirectoryDialog::setPath(const QString &p)
{
m_chooser->setPath(p);
}
QString CacheDirectoryDialog::path() const
{
return m_chooser->path();
}
void CacheDirectoryDialog::accept()
{
// Ensure path exists
QString cache = path();
if (cache.isEmpty())
return;
QFileInfo fi(cache);
// Folder exists - all happy.
if (fi.isDir()) {
QDialog::accept();
return;
}
// Does a file of the same name exist?
if (fi.exists()) {
QMessageBox::warning(this, tr("Already Exists"),
tr("A file named '%1' already exists.").arg(cache));
return;
}
// Create
QDir root(QDir::root());
if (!root.mkpath(cache)) {
QMessageBox::warning(this, tr("Cannot Create"),
tr("The folder '%1' could not be created.").arg(cache));
return;
}
QDialog::accept();
}
CdbSymbolPathListEditor::CdbSymbolPathListEditor(QWidget *parent) :
Utils::PathListEditor(parent)
{
......@@ -44,15 +114,20 @@ CdbSymbolPathListEditor::CdbSymbolPathListEditor(QWidget *parent) :
"Requires specifying a local cache directory."));
}
QString CdbSymbolPathListEditor::promptCacheDirectory(QWidget *parent)
{
CacheDirectoryDialog dialog(parent);
dialog.setPath(QDir::tempPath() + QDir::separator() + QLatin1String("symbolcache"));
if (dialog.exec() != QDialog::Accepted)
return QString();
return dialog.path();
}
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);
}
const QString cacheDir = promptCacheDirectory(this);
if (!cacheDir.isEmpty())
insertPathAtCursor(CdbOptions::symbolServerPath(cacheDir));
}
} // namespace Internal
......
......@@ -32,15 +32,49 @@
#include <utils/pathlisteditor.h>
#include <QtGui/QDialog>
namespace Utils {
class PathChooser;
}
QT_BEGIN_NAMESPACE
class QDialogButtonBox;
QT_END_NAMESPACE
namespace Debugger {
namespace Internal {
// Internal helper dialog prompting for a cache directory
// using a PathChooser.
// Note that QFileDialog does not offer a way of suggesting
// a non-existent folder, which is in turn automatically
// created. This is done here (suggest $TEMP\symbolcache
// regardless of its existence).
class CacheDirectoryDialog : public QDialog {
Q_OBJECT
public:
explicit CacheDirectoryDialog(QWidget *parent = 0);
void setPath(const QString &p);
QString path() const;
virtual void accept();
private:
Utils::PathChooser *m_chooser;
QDialogButtonBox *m_buttonBox;
};
class CdbSymbolPathListEditor : public Utils::PathListEditor
{
Q_OBJECT
public:
explicit CdbSymbolPathListEditor(QWidget *parent = 0);
static QString promptCacheDirectory(QWidget *parent);
private slots:
void addSymbolServer();
};
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment