From 22ab8d5662590a2150d6c4ba6472c201f5914181 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint <Friedemann.Kleint@nokia.com> Date: Thu, 8 Oct 2009 17:23:27 +0200 Subject: [PATCH] Debugger: Do configuration error checking early on. Add a configuration checking method to the Debugger manager, depending on toolchain, wire it to the engines. Check that in the debugger run controls. Add a convenience method to ICore that shows a warning message with a "Settings" button, pointing the user to a configuration error on a settings page. Remove leftovers of the dumper parser. Acked-by: con <qtc-committer@nokia.com> --- src/plugins/coreplugin/coreimpl.cpp | 11 ++ src/plugins/coreplugin/coreimpl.h | 5 + src/plugins/coreplugin/icore.cpp | 16 +- src/plugins/coreplugin/icore.h | 6 + src/plugins/coreplugin/mainwindow.cpp | 26 +++ src/plugins/coreplugin/mainwindow.h | 6 + src/plugins/debugger/debuggerdialogs.cpp | 24 --- src/plugins/debugger/debuggerdialogs.h | 8 - src/plugins/debugger/debuggermanager.cpp | 52 +++++- src/plugins/debugger/debuggermanager.h | 5 + src/plugins/debugger/debuggerrunner.cpp | 15 +- src/plugins/debugger/gdb/gdbengine.cpp | 21 ++- src/plugins/debugger/gdb/gdbengine.h | 2 + src/plugins/debugger/gdb/trkoptions.cpp | 20 ++ src/plugins/debugger/gdb/trkoptions.h | 2 + src/plugins/debugger/idebuggerengine.h | 1 + src/plugins/debugger/watchutils.cpp | 173 ------------------ .../qt-s60/s60devicerunconfiguration.cpp | 41 ++++- .../qt-s60/s60devicerunconfiguration.h | 13 +- 19 files changed, 225 insertions(+), 222 deletions(-) diff --git a/src/plugins/coreplugin/coreimpl.cpp b/src/plugins/coreplugin/coreimpl.cpp index 81db34a2ac8..1cfe46f00fe 100644 --- a/src/plugins/coreplugin/coreimpl.cpp +++ b/src/plugins/coreplugin/coreimpl.cpp @@ -69,6 +69,17 @@ bool CoreImpl::showOptionsDialog(const QString &group, const QString &page, QWid return m_mainwindow->showOptionsDialog(group, page, parent); } +bool CoreImpl::showWarningWithOptions(const QString &title, const QString &text, + const QString &details, + const QString &settingsCategory, + const QString &settingsId, + QWidget *parent) +{ + return m_mainwindow->showWarningWithOptions(title, text, + details, settingsCategory, + settingsId, parent); +} + ActionManager *CoreImpl::actionManager() const { return m_mainwindow->actionManager(); diff --git a/src/plugins/coreplugin/coreimpl.h b/src/plugins/coreplugin/coreimpl.h index ca2410d8d08..d591f3efb6f 100644 --- a/src/plugins/coreplugin/coreimpl.h +++ b/src/plugins/coreplugin/coreimpl.h @@ -50,6 +50,11 @@ public: bool showOptionsDialog(const QString &group = QString(), const QString &page = QString(), QWidget *parent = 0); + bool showWarningWithOptions(const QString &title, const QString &text, + const QString &details = QString(), + const QString &settingsCategory = QString(), + const QString &settingsId = QString(), + QWidget *parent = 0); ActionManager *actionManager() const; FileManager *fileManager() const ; diff --git a/src/plugins/coreplugin/icore.cpp b/src/plugins/coreplugin/icore.cpp index 39938d78894..531319a5adc 100644 --- a/src/plugins/coreplugin/icore.cpp +++ b/src/plugins/coreplugin/icore.cpp @@ -68,7 +68,7 @@ */ /*! - \fn void ICore::showOptionsDialog(const QString &group = QString(), + \fn bool ICore::showOptionsDialog(const QString &group = QString(), const QString &page = QString()) \brief Opens the application options/preferences dialog with preselected \a page in a specified \a group. @@ -76,6 +76,20 @@ The arguments refer to the string IDs of the corresponding IOptionsPage. */ +/*! + \fn bool ICore::showWarningWithOptions(const QString &title, const QString &text, + const QString &details = QString(), + const QString &settingsCategory = QString(), + const QString &settingsId = QString(), + QWidget *parent = 0); + + \brief Show a warning message with a button that opens a settings page. + + Should be used to display configuration errors and point users to the setting. + Returns true if the settings dialog was accepted. +*/ + + /*! \fn ActionManager *ICore::actionManager() const \brief Returns the application's action manager. diff --git a/src/plugins/coreplugin/icore.h b/src/plugins/coreplugin/icore.h index 8d0d913992e..eab9b9abf0f 100644 --- a/src/plugins/coreplugin/icore.h +++ b/src/plugins/coreplugin/icore.h @@ -75,6 +75,12 @@ public: const QString &page = QString(), QWidget *parent = 0) = 0; + virtual bool showWarningWithOptions(const QString &title, const QString &text, + const QString &details = QString(), + const QString &settingsCategory = QString(), + const QString &settingsId = QString(), + QWidget *parent = 0) = 0; + virtual ActionManager *actionManager() const = 0; virtual FileManager *fileManager() const = 0; virtual UniqueIDManager *uniqueIDManager() const = 0; diff --git a/src/plugins/coreplugin/mainwindow.cpp b/src/plugins/coreplugin/mainwindow.cpp index a8434f6fdfb..282b2bf6815 100644 --- a/src/plugins/coreplugin/mainwindow.cpp +++ b/src/plugins/coreplugin/mainwindow.cpp @@ -87,6 +87,7 @@ #include <QtGui/QWizard> #include <QtGui/QPrinter> #include <QtGui/QToolButton> +#include <QtGui/QMessageBox> /* #ifdef Q_OS_UNIX @@ -1262,3 +1263,28 @@ void MainWindow::setFullScreen(bool on) } } +// Display a warning with an additional button to open +// the debugger settings dialog if settingsId is nonempty. + +bool MainWindow::showWarningWithOptions(const QString &title, + const QString &text, + const QString &details, + const QString &settingsCategory, + const QString &settingsId, + QWidget *parent) +{ + if (parent == 0) + parent = this; + QMessageBox msgBox(QMessageBox::Warning, title, text, + QMessageBox::Ok, parent); + if (details.isEmpty()) + msgBox.setDetailedText(details); + QAbstractButton *settingsButton = 0; + if (!settingsId.isEmpty() || !settingsCategory.isEmpty()) + settingsButton = msgBox.addButton(tr("Settings..."), QMessageBox::AcceptRole); + msgBox.exec(); + if (settingsButton && msgBox.clickedButton() == settingsButton) { + return showOptionsDialog(settingsCategory, settingsId); + } + return false; +} diff --git a/src/plugins/coreplugin/mainwindow.h b/src/plugins/coreplugin/mainwindow.h index a85a51dddab..7b8510c5e0f 100644 --- a/src/plugins/coreplugin/mainwindow.h +++ b/src/plugins/coreplugin/mainwindow.h @@ -138,6 +138,12 @@ public slots: const QString &page = QString(), QWidget *parent = 0); + bool showWarningWithOptions(const QString &title, const QString &text, + const QString &details = QString(), + const QString &settingsCategory = QString(), + const QString &settingsId = QString(), + QWidget *parent = 0); + protected: virtual void changeEvent(QEvent *e); virtual void closeEvent(QCloseEvent *event); diff --git a/src/plugins/debugger/debuggerdialogs.cpp b/src/plugins/debugger/debuggerdialogs.cpp index ffd63b90bca..204be588455 100644 --- a/src/plugins/debugger/debuggerdialogs.cpp +++ b/src/plugins/debugger/debuggerdialogs.cpp @@ -51,7 +51,6 @@ #include <QtGui/QPushButton> #include <QtGui/QProxyModel> #include <QtGui/QSortFilterProxyModel> -#include <QtGui/QMessageBox> namespace Debugger { namespace Internal { @@ -519,28 +518,5 @@ bool AddressDialog::isValid() const return ok; } -int warningWithSettings(const QString &title, - const QString &text, - const QString &details, - const QString &settingsId, - QWidget *parent) -{ - QMessageBox msgBox(QMessageBox::Warning, title, text, - QMessageBox::Ok, parent); - if (details.isEmpty()) - msgBox.setDetailedText(details); - QAbstractButton *settingsButton = 0; - if (!settingsId.isEmpty()) - settingsButton = msgBox.addButton(QCoreApplication::translate("Debugger::MessageBox", "Settings..."), - QMessageBox::AcceptRole); - const int dialogCode = msgBox.exec(); - if (settingsButton && msgBox.clickedButton() == settingsButton) { - Core::ICore::instance()->showOptionsDialog(QLatin1String(Debugger::Constants::DEBUGGER_SETTINGS_CATEGORY), - settingsId); - return 2; - } - return dialogCode; -} - } // namespace Internal } // namespace Debugger diff --git a/src/plugins/debugger/debuggerdialogs.h b/src/plugins/debugger/debuggerdialogs.h index d89916edf62..a70fe106b15 100644 --- a/src/plugins/debugger/debuggerdialogs.h +++ b/src/plugins/debugger/debuggerdialogs.h @@ -62,14 +62,6 @@ struct ProcData QString state; }; -// Display a warning with an additional button to open -// the debugger settings dialog if settingsId is nonempty. -int warningWithSettings(const QString &title, - const QString &text, - const QString &details = QString(), - const QString &settingsId = QString(), - QWidget *parent = 0); - class AttachCoreDialog : public QDialog { Q_OBJECT diff --git a/src/plugins/debugger/debuggermanager.cpp b/src/plugins/debugger/debuggermanager.cpp index 8a3a1245813..3b60855518a 100644 --- a/src/plugins/debugger/debuggermanager.cpp +++ b/src/plugins/debugger/debuggermanager.cpp @@ -925,11 +925,8 @@ static IDebuggerEngine *determineDebuggerEngine(const QString &executable, // We need the CDB debugger in order to be able to debug VS // executables - if (!winEngine) { - *errorMessage = DebuggerManager::tr("Debugging VS executables is currently not enabled."); - *settingsIdHint = QLatin1String("Cdb"); + if (!DebuggerManager::instance()->checkDebugConfiguration(ProjectExplorer::ToolChain::MSVC, errorMessage, 0 , settingsIdHint)) return 0; - } return winEngine; #endif } @@ -991,7 +988,9 @@ void DebuggerManager::startNewDebugger(const DebuggerStartParametersPtr &sp) // Create Message box with possibility to go to settings const QString msg = tr("Cannot debug '%1' (tool chain: '%2'): %3"). arg(d->m_startParameters->executable, toolChainName, errorMessage); - warningWithSettings(tr("Warning"), msg, QString(), settingsIdHint); + Core::ICore::instance()->showWarningWithOptions(tr("Warning"), msg, QString(), + QLatin1String(DEBUGGER_SETTINGS_CATEGORY), + settingsIdHint); return; } @@ -1713,6 +1712,49 @@ bool DebuggerManager::debuggerActionsEnabled() const return false; } +bool DebuggerManager::checkDebugConfiguration(int toolChain, + QString *errorMessage, + QString *settingsCategory /* = 0 */, + QString *settingsPage /* = 0 */) const +{ + errorMessage->clear(); + if (settingsCategory) + settingsCategory->clear(); + if (settingsPage) + settingsPage->clear(); + bool success = true; + switch(toolChain) { + case ProjectExplorer::ToolChain::GCC: + case ProjectExplorer::ToolChain::LinuxICC: + case ProjectExplorer::ToolChain::MinGW: + case ProjectExplorer::ToolChain::WINCE: // S60 + case ProjectExplorer::ToolChain::WINSCW: + case ProjectExplorer::ToolChain::GCCE: + case ProjectExplorer::ToolChain::RVCT_ARMV5: + case ProjectExplorer::ToolChain::RVCT_ARMV6: + if (gdbEngine) { + success = gdbEngine->checkConfiguration(toolChain, errorMessage, settingsPage); + } else { + success = false; + *errorMessage = msgEngineNotAvailable("Gdb"); + } + break; + case ProjectExplorer::ToolChain::MSVC: + if (winEngine) { + success = winEngine->checkConfiguration(toolChain, errorMessage, settingsPage); + } else { + success = false; + *errorMessage = msgEngineNotAvailable("Cdb"); + if (settingsPage) + *settingsPage = QLatin1String("Cdb"); + } + break; + } + if (!success && settingsCategory && settingsPage && !settingsPage->isEmpty()) + *settingsCategory = QLatin1String(DEBUGGER_SETTINGS_CATEGORY); + return success; +} + QDebug operator<<(QDebug d, DebuggerState state) { return d << stateName(state) << '(' << int(state) << ')'; diff --git a/src/plugins/debugger/debuggermanager.h b/src/plugins/debugger/debuggermanager.h index 71b9be64408..30806390ca0 100644 --- a/src/plugins/debugger/debuggermanager.h +++ b/src/plugins/debugger/debuggermanager.h @@ -173,6 +173,11 @@ public: bool debuggerActionsEnabled() const; + bool checkDebugConfiguration(int toolChain, + QString *errorMessage, + QString *settingsCategory = 0, + QString *settingsPage = 0) const; + static DebuggerManager *instance(); public slots: diff --git a/src/plugins/debugger/debuggerrunner.cpp b/src/plugins/debugger/debuggerrunner.cpp index dc622cf2e35..17e11a1e095 100644 --- a/src/plugins/debugger/debuggerrunner.cpp +++ b/src/plugins/debugger/debuggerrunner.cpp @@ -36,6 +36,7 @@ #include <projectexplorer/projectexplorerconstants.h> #include <utils/qtcassert.h> +#include <coreplugin/icore.h> #include <QtCore/QDebug> #include <QtCore/QDir> @@ -174,7 +175,19 @@ DebuggerRunControl::DebuggerRunControl(DebuggerManager *manager, void DebuggerRunControl::start() { m_running = true; - m_manager->startNewDebugger(m_startParameters); + QString errorMessage; + QString settingsCategory; + QString settingsPage; + if (m_manager->checkDebugConfiguration(startParameters()->toolChainType, &errorMessage, + &settingsCategory, &settingsPage)) { + m_manager->startNewDebugger(m_startParameters); + } else { + error(this, errorMessage); + emit finished(); + Core::ICore::instance()->showWarningWithOptions(tr("Debugger"), errorMessage, + QString(), + settingsCategory, settingsPage); + } } void DebuggerRunControl::slotAddToOutputWindowInline(const QString &data) diff --git a/src/plugins/debugger/gdb/gdbengine.cpp b/src/plugins/debugger/gdb/gdbengine.cpp index 21fcd23af55..d2e3db5c9cd 100644 --- a/src/plugins/debugger/gdb/gdbengine.cpp +++ b/src/plugins/debugger/gdb/gdbengine.cpp @@ -1409,6 +1409,24 @@ int GdbEngine::currentFrame() const return manager()->stackHandler()->currentIndex(); } +bool GdbEngine::checkConfiguration(int toolChain, QString *errorMessage, QString *settingsPage) const +{ + switch (toolChain) { + case ProjectExplorer::ToolChain::WINSCW: // S60 + case ProjectExplorer::ToolChain::GCCE: + case ProjectExplorer::ToolChain::RVCT_ARMV5: + case ProjectExplorer::ToolChain::RVCT_ARMV6: + if (!m_trkOptions->check(errorMessage)) { + if (settingsPage) + *settingsPage = TrkOptionsPage::settingsId(); + return false; + } + default: + break; + } + return true; +} + AbstractGdbAdapter *GdbEngine::createAdapter(const DebuggerStartParametersPtr &sp) { switch (sp->toolChainType) { @@ -3983,7 +4001,8 @@ void GdbEngine::handleAdapterStartFailed(const QString &msg, const QString &sett { setState(AdapterStartFailed); debugMessage(_("ADAPTER START FAILED")); - warningWithSettings(tr("Adapter start failed"), msg, QString(), settingsIdHint); + Core::ICore::instance()->showWarningWithOptions(tr("Adapter start failed"), msg, QString(), + QLatin1String(Debugger::Constants::DEBUGGER_SETTINGS_CATEGORY), settingsIdHint); shutdown(); } diff --git a/src/plugins/debugger/gdb/gdbengine.h b/src/plugins/debugger/gdb/gdbengine.h index e4a3c652b03..3df5bc46fa4 100644 --- a/src/plugins/debugger/gdb/gdbengine.h +++ b/src/plugins/debugger/gdb/gdbengine.h @@ -151,6 +151,8 @@ private: Q_SLOT void setAutoDerefPointers(const QVariant &on); virtual bool isGdbEngine() const { return true; } + virtual bool checkConfiguration(int toolChain, QString *errorMessage, QString *settingsPage= 0) const; + // // Own stuff // diff --git a/src/plugins/debugger/gdb/trkoptions.cpp b/src/plugins/debugger/gdb/trkoptions.cpp index 4975d619852..0c364a300df 100644 --- a/src/plugins/debugger/gdb/trkoptions.cpp +++ b/src/plugins/debugger/gdb/trkoptions.cpp @@ -28,9 +28,11 @@ **************************************************************************/ #include "trkoptions.h" +#include <utils/synchronousprocess.h> #include <QtCore/QSettings> #include <QtCore/QFileInfo> +#include <QtCore/QCoreApplication> #ifdef Q_OS_WIN # define SERIALPORT_ROOT "COM" @@ -104,6 +106,24 @@ void TrkOptions::toSettings(QSettings *s) const s->endGroup(); } +bool TrkOptions::check(QString *errorMessage) const +{ + if (gdb.isEmpty()) { + *errorMessage = QCoreApplication::translate("TrkOptions", "No Symbian gdb executable specified."); + return false; + } + const QString expanded = Utils::SynchronousProcess::locateBinary(gdb); + if (expanded.isEmpty()) { + *errorMessage = QCoreApplication::translate("TrkOptions", "The Symbian gdb executable '%1' could not be found in the search path.").arg(gdb); + return false; + } + if (!cygwin.isEmpty() && !QFileInfo(cygwin).isDir()) { + *errorMessage = QCoreApplication::translate("TrkOptions", "The Cygwin directory '%1' does not exist.").arg(cygwin); + return false; + } + return true; +} + bool TrkOptions::equals(const TrkOptions &o) const { return mode == o.mode diff --git a/src/plugins/debugger/gdb/trkoptions.h b/src/plugins/debugger/gdb/trkoptions.h index 9e50796ea7c..c6f8cac0e8a 100644 --- a/src/plugins/debugger/gdb/trkoptions.h +++ b/src/plugins/debugger/gdb/trkoptions.h @@ -54,6 +54,8 @@ struct TrkOptions void toSettings(QSettings *s) const; bool equals(const TrkOptions &o) const; + bool check(QString *errorMessage) const; + // Lists of choices for the devices static QStringList serialPorts(); static QStringList blueToothDevices(); diff --git a/src/plugins/debugger/idebuggerengine.h b/src/plugins/debugger/idebuggerengine.h index c4d7202152d..b1110bda67a 100644 --- a/src/plugins/debugger/idebuggerengine.h +++ b/src/plugins/debugger/idebuggerengine.h @@ -117,6 +117,7 @@ public: virtual void addOptionPages(QList<Core::IOptionsPage*> *) const {} virtual bool isGdbEngine() const { return false; } + virtual bool checkConfiguration(int /* toolChain */, QString * /* errorMessage */, QString * /* settingsPage */ = 0) const { return true; } protected: void showStatusMessage(const QString &msg, int timeout = -1); diff --git a/src/plugins/debugger/watchutils.cpp b/src/plugins/debugger/watchutils.cpp index a494c0d7000..576f29811e5 100644 --- a/src/plugins/debugger/watchutils.cpp +++ b/src/plugins/debugger/watchutils.cpp @@ -695,179 +695,6 @@ void QtDumperHelper::parseQueryTypes(const QStringList &l, Debugger debugger) } } -/* A parse for dumper output: - * "iname="local.sl",addr="0x0012BA84",value="<3 items>",valuedisabled="true", - * numchild="3",childtype="QString",childnumchild="0",children=[{name="0",value="<binhex>", - * valueencoded="2"},{name="1",value="dAB3AG8A",valueencoded="2"},{name="2", - * value="dABoAHIAZQBlAA==",valueencoded="2"}]" - * Default implementation can be used for debugging purposes. */ - -class DumperParser -{ -public: - explicit DumperParser(const char *s) : m_s(s) {} - bool run(); - virtual ~DumperParser() {} - -protected: - // handle 'key="value"' - virtual bool handleKeyword(const char *k, int size); - virtual bool handleListStart(); - virtual bool handleListEnd(); - virtual bool handleHashStart(); - virtual bool handleHashEnd(); - virtual bool handleValue(const char *k, int size); - -private: - bool parseHash(int level, const char *&pos); - bool parseValue(int level, const char *&pos); - bool parseStringValue(const char *&ptr, int &size, const char *&pos) const; - - const char *m_s; -}; - -// get a string value with pos at the opening double quote -bool DumperParser::parseStringValue(const char *&ptr, int &size, const char *&pos) const -{ - pos++; - const char *endValuePtr = strchr(pos, '"'); - if (!endValuePtr) - return false; - size = endValuePtr - pos; - ptr = pos; - pos = endValuePtr + 1; - return true; -} - -bool DumperParser::run() -{ - const char *ptr = m_s; - const bool rc = parseHash(0, ptr); - if (debug > 1) - qDebug() << Q_FUNC_INFO << '\n' << m_s << rc; - return rc; -} - -// Parse a non-empty hash with pos at the first keyword. -// Curly braces are present at level 0 only. -// '{a="X", b="X"}' -bool DumperParser::parseHash(int level, const char *&pos) -{ - while (true) { - switch (*pos) { - case '\0': // EOS is acceptable at level 0 only - return level == 0; - case '}': - pos++; - return true; - default: - break; - } - const char *equalsPtr = strchr(pos, '='); - if (!equalsPtr) - return false; - const int keywordLen = equalsPtr - pos; - if (!handleKeyword(pos, keywordLen)) - return false; - pos = equalsPtr + 1; - if (!*pos) - return false; - if (!parseValue(level + 1, pos)) - return false; - if (*pos == ',') - pos++; - } - return false; -} - -bool DumperParser::parseValue(int level, const char *&pos) -{ - // Simple string literal - switch (*pos) { - case '"': { - const char *valuePtr; - int valueSize; - return parseStringValue(valuePtr, valueSize, pos) && handleValue(valuePtr, valueSize); - } - // A List. Note that it has a trailing comma '["a",]' - case '[': { - if (!handleListStart()) - return false; - pos++; - while (true) { - switch (*pos) { - case ']': - pos++; - return handleListEnd(); - case '\0': - return false; - default: - break; - } - if (!parseValue(level + 1, pos)) - return false; - if (*pos == ',') - pos++; - } - } - return false; - // A hash '{a="b",b="c"}' - case '{': { - if (!handleHashStart()) - return false; - pos++; - if (!parseHash(level + 1, pos)) - return false; - return handleHashEnd(); - } - return false; - } - return false; -} - -bool DumperParser::handleKeyword(const char *k, int size) -{ - if (debug > 1) - qDebug() << Q_FUNC_INFO << '\n' << QByteArray(k, size); - return true; -} - -bool DumperParser::handleListStart() -{ - if (debug > 1) - qDebug() << Q_FUNC_INFO; - return true; -} - -bool DumperParser::handleListEnd() -{ - if (debug > 1) - qDebug() << Q_FUNC_INFO; - return true; -} - -bool DumperParser::handleHashStart() -{ - if (debug > 1) - qDebug() << Q_FUNC_INFO; - return true; -} - -bool DumperParser::handleHashEnd() -{ - if (debug > 1) - qDebug() << Q_FUNC_INFO; - - return true; -} - -bool DumperParser::handleValue(const char *k, int size) -{ - if (debug > 1) - qDebug() << Q_FUNC_INFO << '\n' << QByteArray(k, size); - return true; -} - static inline QString qClassName(const QString &qtNamespace, const char *className) { if (qtNamespace.isEmpty()) diff --git a/src/plugins/qt4projectmanager/qt-s60/s60devicerunconfiguration.cpp b/src/plugins/qt4projectmanager/qt-s60/s60devicerunconfiguration.cpp index 3ac0d4b39cf..4dde9723ded 100644 --- a/src/plugins/qt4projectmanager/qt-s60/s60devicerunconfiguration.cpp +++ b/src/plugins/qt4projectmanager/qt-s60/s60devicerunconfiguration.cpp @@ -558,8 +558,22 @@ void S60DeviceRunControlBase::start() emit addToOutputWindow(this, tr("Creating %1.sisx ...").arg(QDir::toNativeSeparators(m_baseFileName))); emit addToOutputWindow(this, tr("Executable file: %1").arg(m_executableFileName)); - if (!createPackageFileFromTemplate()) + QString errorMessage; + QString settingsCategory; + QString settingsPage; + if (!checkConfiguration(&errorMessage, &settingsCategory, &settingsPage)) { + error(this, errorMessage); + emit finished(); + Core::ICore::instance()->showWarningWithOptions(tr("S60 Debugger"), errorMessage, QString(), + settingsCategory, settingsPage); + return; + } + + if (!createPackageFileFromTemplate(&errorMessage)) { + error(this, errorMessage); + emit finished(); return; + } m_makesis->setWorkingDirectory(m_workingDirectory); emit addToOutputWindow(this, tr("%1 %2").arg(QDir::toNativeSeparators(m_makesisTool), m_packageFile)); m_makesis->start(m_makesisTool, QStringList(m_packageFile), QIODevice::ReadOnly); @@ -592,12 +606,11 @@ void S60DeviceRunControlBase::readStandardOutput() emit addToOutputWindowInline(this, QString::fromLocal8Bit(data.constData(), data.length())); } -bool S60DeviceRunControlBase::createPackageFileFromTemplate() +bool S60DeviceRunControlBase::createPackageFileFromTemplate(QString *errorMessage) { QFile packageTemplate(m_packageTemplateFile); if (!packageTemplate.open(QIODevice::ReadOnly)) { - error(this, tr("Could not read template package file '%1'").arg(QDir::toNativeSeparators(m_packageTemplateFile))); - emit finished(); + *errorMessage = tr("Could not read template package file '%1'").arg(QDir::toNativeSeparators(m_packageTemplateFile)); return false; } QString contents = packageTemplate.readAll(); @@ -606,8 +619,7 @@ bool S60DeviceRunControlBase::createPackageFileFromTemplate() contents.replace(QLatin1String("$(TARGET)"), m_symbianTarget); QFile packageFile(m_packageFilePath); if (!packageFile.open(QIODevice::WriteOnly)) { - error(this, tr("Could not write package file '%1'").arg(QDir::toNativeSeparators(m_packageFilePath))); - emit finished(); + *errorMessage = tr("Could not write package file '%1'").arg(QDir::toNativeSeparators(m_packageFilePath)); return false; } packageFile.write(contents.toLocal8Bit()); @@ -749,6 +761,13 @@ void S60DeviceRunControlBase::printApplicationOutput(const QString &output) emit addToOutputWindowInline(this, output); } +bool S60DeviceRunControlBase::checkConfiguration(QString * /* errorMessage */, + QString * /* settingsCategory */, + QString * /* settingsPage */) const +{ + return true; +} + // =============== S60DeviceRunControl S60DeviceRunControl::S60DeviceRunControl(const QSharedPointer<ProjectExplorer::RunConfiguration> &runConfiguration) : S60DeviceRunControlBase(runConfiguration) @@ -849,3 +868,13 @@ void S60DeviceDebugRunControl::debuggingFinished() emit addToOutputWindow(this, tr("Debugging finished.")); emit finished(); } + +bool S60DeviceDebugRunControl::checkConfiguration(QString *errorMessage, + QString *settingsCategory, + QString *settingsPage) const +{ + return Debugger::DebuggerManager::instance()->checkDebugConfiguration(m_startParams->toolChainType, + errorMessage, + settingsCategory, + settingsPage); +} diff --git a/src/plugins/qt4projectmanager/qt-s60/s60devicerunconfiguration.h b/src/plugins/qt4projectmanager/qt-s60/s60devicerunconfiguration.h index 5c117d11b14..aa8ce4db869 100644 --- a/src/plugins/qt4projectmanager/qt-s60/s60devicerunconfiguration.h +++ b/src/plugins/qt4projectmanager/qt-s60/s60devicerunconfiguration.h @@ -166,6 +166,10 @@ protected: virtual void handleLauncherFinished() = 0; void processFailed(const QString &program, QProcess::ProcessError errorCode); + virtual bool checkConfiguration(QString *errorMessage, + QString *settingsCategory, + QString *settingsPage) const; + protected slots: void printApplicationOutput(const QString &output); @@ -185,8 +189,8 @@ private slots: void printInstallFailed(const QString &filename, const QString &errorMessage); void launcherFinished(); -private: - bool createPackageFileFromTemplate(); +private: + bool createPackageFileFromTemplate(QString *errorMessage); QString m_serialPortName; QString m_serialPortFriendlyName; @@ -240,9 +244,12 @@ public: virtual void stop(); -protected: +protected: virtual void initLauncher(const QString &executable, trk::Launcher *); virtual void handleLauncherFinished(); + virtual bool checkConfiguration(QString *errorMessage, + QString *settingsCategory, + QString *settingsPage) const; private slots: void debuggingFinished(); -- GitLab