diff --git a/src/plugins/debugger/gdb/gdb.pri b/src/plugins/debugger/gdb/gdb.pri index c10997f27ea3f65b41d39a1699f72eef76dd0ebc..a83f0a5a16a45781e1f8632259cac49e3124622c 100644 --- a/src/plugins/debugger/gdb/gdb.pri +++ b/src/plugins/debugger/gdb/gdb.pri @@ -6,14 +6,20 @@ HEADERS += \ $$PWD/gdbengine.h \ $$PWD/gdboptionspage.h \ $$PWD/trkgdbadapter.h \ - #$$PWD/gdboptionspage.h \ + $$PWD/trkoptions.h \ + $$PWD/trkoptionswidget.h \ + $$PWD/trkoptionspage.h SOURCES += \ $$PWD/gdbmi.cpp \ $$PWD/gdbengine.cpp \ $$PWD/gdboptionspage.cpp \ - $$PWD/trkgdbadapter.cpp + $$PWD/trkgdbadapter.cpp \ + $$PWD/trkoptions.cpp \ + $$PWD/trkoptionswidget.cpp \ + $$PWD/trkoptionspage.cpp -FORMS += $$PWD/gdboptionspage.ui +FORMS += $$PWD/gdboptionspage.ui \ +$$PWD/trkoptionswidget.ui RESOURCES += $$PWD/gdb.qrc diff --git a/src/plugins/debugger/gdb/gdbengine.cpp b/src/plugins/debugger/gdb/gdbengine.cpp index 07d5524505a222e9943553d9a668348556761b0d..faa860a1467347db717391317eaf7b445bb562bd 100644 --- a/src/plugins/debugger/gdb/gdbengine.cpp +++ b/src/plugins/debugger/gdb/gdbengine.cpp @@ -31,6 +31,8 @@ #include "gdbengine.h" #include "gdboptionspage.h" +#include "trkoptions.h" +#include "trkoptionspage.h" #include "trkgdbadapter.h" #include "watchutils.h" @@ -4313,9 +4315,11 @@ IDebuggerEngine *createGdbEngine(DebuggerManager *parent, IDebuggerEngine *createSymbianEngine(DebuggerManager *parent, QList<Core::IOptionsPage*> *opts) { - Q_UNUSED(opts); - //opts->push_back(new GdbOptionsPage); - TrkGdbAdapter *adapter = new TrkGdbAdapter; + QSharedPointer<TrkOptions> options(new TrkOptions); + options->fromSettings(Core::ICore::instance()->settings()); + + opts->push_back(new TrkOptionsPage(options)); + TrkGdbAdapter *adapter = new TrkGdbAdapter(options); GdbEngine *engine = new GdbEngine(parent, adapter); QObject::connect(adapter, SIGNAL(output(QString)), parent, SLOT(showDebuggerOutput(QString))); diff --git a/src/plugins/debugger/gdb/trkgdbadapter.cpp b/src/plugins/debugger/gdb/trkgdbadapter.cpp index b892167d27513199da943ba2ce55cbadda50f483..59126ed60c9b1267f1f4ef7ddd5c14123c4574f9 100644 --- a/src/plugins/debugger/gdb/trkgdbadapter.cpp +++ b/src/plugins/debugger/gdb/trkgdbadapter.cpp @@ -28,6 +28,7 @@ **************************************************************************/ #include "trkgdbadapter.h" +#include "trkoptions.h" #ifndef STANDALONE_RUNNER #include "gdbengine.h" #endif @@ -36,6 +37,9 @@ # include <unistd.h> #endif +#include <QtCore/QTimer> +#include <QtCore/QDir> + #define TrkCB(s) TrkCallback(this, &TrkGdbAdapter::s) @@ -71,21 +75,21 @@ static QByteArray dumpRegister(int n, uint value) namespace Debugger { namespace Internal { -TrkGdbAdapter::TrkGdbAdapter() +TrkGdbAdapter::TrkGdbAdapter(const TrkOptionsPtr &options) : + m_options(options), + m_running(false), + m_gdbAckMode(true), + m_verbose(2), + m_bufferedMemoryRead(true), + m_waitCount(0) { - m_running = false; - m_gdbAckMode = true; - m_verbose = 2; - m_serialFrame = false; - m_bufferedMemoryRead = true; - m_rfcommDevice = "/dev/rfcomm0"; #ifdef Q_OS_WIN - int userId = 0; + const DWORD portOffset = GetCurrentProcessId() % 100; #else - uid_t userId = getuid(); + const uid_t portOffset = getuid(); #endif - m_gdbServerName = QString("127.0.0.1:%1").arg(2222 + userId); + m_gdbServerName = QString::fromLatin1("127.0.0.1:%1").arg(2222 + portOffset); connect(&m_gdbProc, SIGNAL(readyReadStandardError()), this, SIGNAL(readyReadStandardError())); connect(&m_gdbProc, SIGNAL(readyReadStandardOutput()), @@ -103,18 +107,18 @@ TrkGdbAdapter::TrkGdbAdapter() this, SLOT(handleRfcommReadyReadStandardError())); connect(&m_rfcommProc, SIGNAL(readyReadStandardOutput()), this, SLOT(handleRfcommReadyReadStandardOutput())); - connect(&m_gdbProc, SIGNAL(error(QProcess::ProcessError)), + connect(&m_rfcommProc, SIGNAL(error(QProcess::ProcessError)), this, SLOT(handleRfcommError(QProcess::ProcessError))); - connect(&m_gdbProc, SIGNAL(finished(int, QProcess::ExitStatus)), + connect(&m_rfcommProc, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(handleRfcommFinished(int, QProcess::ExitStatus))); - connect(&m_gdbProc, SIGNAL(started()), + connect(&m_rfcommProc, SIGNAL(started()), this, SLOT(handleRfcommStarted())); - connect(&m_gdbProc, SIGNAL(stateChanged(QProcess::ProcessState)), + connect(&m_rfcommProc, SIGNAL(stateChanged(QProcess::ProcessState)), this, SLOT(handleRfcommStateChanged(QProcess::ProcessState))); if (m_verbose > 1) m_trkDevice.setVerbose(true); - m_trkDevice.setSerialFrame(m_serialFrame); + m_trkDevice.setSerialFrame(m_options->mode != TrkOptions::BlueTooth); connect(&m_trkDevice, SIGNAL(logMessage(QString)), this, SLOT(trkLogMessage(QString))); @@ -126,6 +130,25 @@ TrkGdbAdapter::~TrkGdbAdapter() logMessage("Shutting down.\n"); } +QString TrkGdbAdapter::overrideTrkDevice() const +{ + return m_overrideTrkDevice; +} + +void TrkGdbAdapter::setOverrideTrkDevice(const QString &d) +{ + m_overrideTrkDevice = d; +} + +QString TrkGdbAdapter::effectiveTrkDevice() const +{ + if (!m_overrideTrkDevice.isEmpty()) + return m_overrideTrkDevice; + if (m_options->mode == TrkOptions::BlueTooth) + return m_options->blueToothDevice; + return m_options->serialPort; +} + void TrkGdbAdapter::trkLogMessage(const QString &msg) { logMessage("TRK " + msg); @@ -196,9 +219,16 @@ QByteArray TrkGdbAdapter::trkStepRangeMessage(byte option) void TrkGdbAdapter::startInferior() { QString errorMessage; - if (!m_trkDevice.open(m_rfcommDevice, &errorMessage)) { - emit output("LOOPING"); - QTimer::singleShot(1000, this, SLOT(startInferior())); + const QString device = effectiveTrkDevice(); + if (!m_trkDevice.open(device, &errorMessage)) { + emit output(QString::fromLatin1("Waiting on %1 (%2)").arg(device, errorMessage)); + // Do not loop forever + if (m_waitCount++ < (m_options->mode == TrkOptions::BlueTooth ? 60 : 5)) { + QTimer::singleShot(1000, this, SLOT(startInferior())); + } else { + emit output(QString::fromLatin1("Failed to connect to %1 after %2 attempts").arg(device).arg(m_waitCount)); + emit finished(-44, QProcess::CrashExit); + } return; } @@ -1283,14 +1313,21 @@ void TrkGdbAdapter::handleGdbStateChanged(QProcess::ProcessState newState) void TrkGdbAdapter::run() { - emit output("### Starting TrkGdbAdapter"); - m_rfcommProc.start("rfcomm -r listen " + m_rfcommDevice + " 1"); - m_rfcommProc.waitForStarted(); - - if (m_rfcommProc.state() != QProcess::Running) { - emit finished(-44, QProcess::CrashExit); - return; + emit output(QLatin1String("### Starting TrkGdbAdapter")); + if (m_options->mode == TrkOptions::BlueTooth) { + const QString device = effectiveTrkDevice(); + const QString blueToothListener = QLatin1String("rfcomm"); + emit output(QString::fromLatin1("### Starting BlueTooth listener %1 on %2").arg(blueToothListener, device)); + m_rfcommProc.start(blueToothListener + QLatin1String(" -r listen ") + m_options->blueToothDevice + QLatin1String(" 1")); + m_rfcommProc.waitForStarted(); + if (m_rfcommProc.state() != QProcess::Running) { + const QString msg = QString::fromLocal8Bit(m_rfcommProc.readAllStandardError()); + emit output(QString::fromLatin1("Failed to start BlueTooth listener %1 on %2: %3\n%4").arg(blueToothListener, device, m_rfcommProc.errorString(), msg)); + emit finished(-44, QProcess::CrashExit); + return; + } } + m_waitCount = 0; connect(&m_trkDevice, SIGNAL(messageReceived(trk::TrkResult)), this, SLOT(handleTrkResult(trk::TrkResult))); @@ -1300,6 +1337,29 @@ void TrkGdbAdapter::run() startInferior(); } +#ifdef Q_OS_WIN + +// Prepend environment of the Symbian Gdb by Cygwin '/bin' +static void setGdbCygwinEnvironment(const QString &cygwin, QProcess *process) +{ + if (cygwin.isEmpty() || !QFileInfo(cygwin).isDir()) + return; + const QString cygwinBinPath = QDir::toNativeSeparators(cygwin) + QLatin1String("\\bin"); + QStringList env = process->environment(); + if (env.isEmpty()) + env = QProcess::systemEnvironment(); + const QRegExp pathPattern(QLatin1String("^PATH=.*")); + const int index = env.indexOf(pathPattern); + if (index == -1) + return; + QString pathValue = env.at(index).mid(5); + if (pathValue.startsWith(cygwinBinPath)) + return; + env[index] = QLatin1String("PATH=") + cygwinBinPath + QLatin1Char(';'); + process->setEnvironment(env); +} +#endif + void TrkGdbAdapter::startGdb() { if (!m_gdbServer.listen(QHostAddress(gdbServerIP()), gdbServerPort())) { @@ -1316,11 +1376,15 @@ void TrkGdbAdapter::startGdb() this, SLOT(handleGdbConnection())); logMessage("STARTING GDB"); + emit output(QString::fromLatin1("### Starting gdb %1").arg(m_options->gdb)); QStringList gdbArgs; - gdbArgs.append("--nx"); // Do not read .gdbinit file - gdbArgs.append("-i"); - gdbArgs.append("mi"); - m_gdbProc.start(QDir::currentPath() + "/cs-gdb", gdbArgs); + gdbArgs.append(QLatin1String("--nx")); // Do not read .gdbinit file + gdbArgs.append(QLatin1String("-i")); + gdbArgs.append(QLatin1String("mi")); +#ifdef Q_OS_WIN + setGdbCygwinEnvironment(m_options->cygwin, &m_gdbProc); +#endif + m_gdbProc.start(m_options->gdb, gdbArgs); } void TrkGdbAdapter::sendGdbMessage(const QString &msg, GdbCallback callback, @@ -1379,12 +1443,15 @@ void TrkGdbAdapter::start(const QString &program, const QStringList &args, QIODevice::OpenMode mode) { Q_UNUSED(mode); + Q_UNUSED(program); + Q_UNUSED(args); run(); } void TrkGdbAdapter::kill() { - m_rfcommProc.kill(); + if (m_options->mode == TrkOptions::BlueTooth && m_rfcommProc.state() == QProcess::Running) + m_rfcommProc.kill(); m_gdbProc.kill(); } @@ -1402,7 +1469,7 @@ bool TrkGdbAdapter::waitForFinished(int msecs) m_rfcommProc.terminate(); m_rfcommProc.waitForFinished(); QProcess proc; - proc.start("rfcomm release " + m_rfcommDevice.toLatin1()); + proc.start("rfcomm release " + m_options->blueToothDevice); proc.waitForFinished(); return m_gdbProc.waitForFinished(msecs); } diff --git a/src/plugins/debugger/gdb/trkgdbadapter.h b/src/plugins/debugger/gdb/trkgdbadapter.h index 828e8bc9537a676d2ff8eb4eeb41c89e3eca05f3..db5b5413c7cd16924e8ca33a196dd227168d6a48 100644 --- a/src/plugins/debugger/gdb/trkgdbadapter.h +++ b/src/plugins/debugger/gdb/trkgdbadapter.h @@ -34,34 +34,22 @@ #include "trkdevice.h" #include "abstractgdbadapter.h" -#include <QtCore/QDebug> -#include <QtCore/QDir> -#include <QtCore/QFile> #include <QtCore/QHash> #include <QtCore/QPointer> +#include <QtCore/QSharedPointer> #include <QtCore/QProcess> #include <QtCore/QQueue> #include <QtCore/QString> #include <QtCore/QStringList> -#include <QtCore/QTextStream> -#include <QtCore/QTimer> - -#include <QtGui/QAction> -#include <QtGui/QApplication> -#include <QtGui/QMainWindow> -#include <QtGui/QKeyEvent> -#include <QtGui/QTextBlock> -#include <QtGui/QTextEdit> -#include <QtGui/QToolBar> #include <QtNetwork/QTcpServer> #include <QtNetwork/QTcpSocket> -#include <QtNetwork/QLocalServer> -#include <QtNetwork/QLocalSocket> namespace Debugger { namespace Internal { +struct TrkOptions; + struct GdbResult { QByteArray data; @@ -81,18 +69,22 @@ public: typedef trk::TrkResult TrkResult; typedef trk::Callback<const TrkResult &> TrkCallback; typedef trk::Callback<const GdbResult &> GdbCallback; + typedef QSharedPointer<TrkOptions> TrkOptionsPtr; - TrkGdbAdapter(); + explicit TrkGdbAdapter(const TrkOptionsPtr &options); ~TrkGdbAdapter(); void setGdbServerName(const QString &name); QString gdbServerName() const { return m_gdbServerName; } QString gdbServerIP() const; uint gdbServerPort() const; void setVerbose(int verbose) { m_verbose = verbose; } - void setSerialFrame(bool b) { m_serialFrame = b; } void setBufferedMemoryRead(bool b) { m_bufferedMemoryRead = b; } trk::Session &session() { return m_session; } + // Set a device (from the project) to override the settings. + QString overrideTrkDevice() const; + void setOverrideTrkDevice(const QString &); + public slots: void startInferior(); void run(); @@ -108,7 +100,9 @@ private slots: private: friend class RunnerGui; - QString m_rfcommDevice; // /dev/rfcomm0 + const TrkOptionsPtr m_options; + QString m_overrideTrkDevice; + QString m_gdbServerName; // 127.0.0.1:(2222+uid) QProcess m_gdbProc; @@ -237,13 +231,15 @@ public: Q_SLOT void handleRfcommStarted(); Q_SLOT void handleRfcommStateChanged(QProcess::ProcessState newState); + QString effectiveTrkDevice() const; + // Debuggee state Q_SLOT void executeCommand(const QString &msg); trk::Session m_session; // global-ish data (process id, target information) trk::Snapshot m_snapshot; // local-ish data (memory and registers) int m_verbose; - bool m_serialFrame; bool m_bufferedMemoryRead; + int m_waitCount; }; } // namespace Internal diff --git a/src/plugins/debugger/gdb/trkoptions.cpp b/src/plugins/debugger/gdb/trkoptions.cpp new file mode 100644 index 0000000000000000000000000000000000000000..4975d619852f25016ad210d859283389e34dcd0b --- /dev/null +++ b/src/plugins/debugger/gdb/trkoptions.cpp @@ -0,0 +1,133 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** Commercial Usage +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** GNU Lesser General Public License Usage +** +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** +**************************************************************************/ + +#include "trkoptions.h" + +#include <QtCore/QSettings> +#include <QtCore/QFileInfo> + +#ifdef Q_OS_WIN +# define SERIALPORT_ROOT "COM" +enum { firstSerialPort = 1, lastSerialPort = 12 }; +enum { modeDefault = Debugger::Internal::TrkOptions::Serial }; +static const char *serialPortDefaultC = SERIALPORT_ROOT"1"; +static const char *gdbDefaultC = "symgdb"; +#else +# define SERIALPORT_ROOT "/dev/ttyS" +enum { firstSerialPort = 0, lastSerialPort = 3 }; +enum { modeDefault = Debugger::Internal::TrkOptions::BlueTooth }; +static const char *serialPortDefaultC = SERIALPORT_ROOT"0"; +static const char *gdbDefaultC = "symgdb"; +#endif + +static const char *settingsGroupC = "S60Debugger"; +static const char *serialPortKeyC = "Port"; +static const char *modeKeyC = "Mode"; +static const char *blueToothDeviceKeyC = "BlueToothDevice"; +static const char *blueToothDeviceDefaultC = "/dev/rfcomm0"; +static const char *gdbKeyC = "gdb"; +static const char *cygwinKeyC = "Cygwin"; + +static inline QString cygwinDefault() +{ +#ifdef Q_OS_WIN + // Some smartness to check for Cygwin + static bool firstTime = true; + static QString rc = QLatin1String("C:/cygwin"); + if (firstTime) { + if (!QFileInfo(rc).isDir()) + rc.clear(); + firstTime = false; + } + return rc; +#else + return QString(); +#endif +} + +namespace Debugger { +namespace Internal { + +TrkOptions::TrkOptions() : + mode(modeDefault), + serialPort(QLatin1String(serialPortDefaultC)), + blueToothDevice(QLatin1String(blueToothDeviceDefaultC)), + gdb(QLatin1String(gdbDefaultC)), + cygwin(cygwinDefault()) +{ +} + +void TrkOptions::fromSettings(const QSettings *s) +{ + const QString keyRoot = QLatin1String(settingsGroupC) + QLatin1Char('/'); + mode = s->value(keyRoot + QLatin1String(modeKeyC), modeDefault).toInt(); + serialPort = s->value(keyRoot + QLatin1String(serialPortKeyC), QLatin1String(serialPortDefaultC)).toString(); + gdb = s->value(keyRoot + QLatin1String(gdbKeyC),QLatin1String(gdbDefaultC)).toString(); + cygwin = s->value(keyRoot + QLatin1String(cygwinKeyC), cygwinDefault()).toString(); + blueToothDevice = s->value(keyRoot + QLatin1String(blueToothDeviceKeyC), QLatin1String(blueToothDeviceDefaultC)).toString(); +} + +void TrkOptions::toSettings(QSettings *s) const +{ + s->beginGroup(QLatin1String(settingsGroupC)); + s->setValue(QLatin1String(modeKeyC), mode); + s->setValue(QLatin1String(serialPortKeyC), serialPort); + s->setValue(QLatin1String(blueToothDeviceKeyC), blueToothDevice); + s->setValue(QLatin1String(gdbKeyC), gdb); + s->setValue(QLatin1String(cygwinKeyC), cygwin); + s->endGroup(); +} + +bool TrkOptions::equals(const TrkOptions &o) const +{ + return mode == o.mode + && serialPort == o.serialPort + && blueToothDevice == o.blueToothDevice + && gdb == o.gdb + && cygwin == o.cygwin; +} + +QStringList TrkOptions::serialPorts() +{ + QStringList rc; + const QString root = QLatin1String(SERIALPORT_ROOT); + for (int p = firstSerialPort; p != lastSerialPort; p++) + rc.push_back(root + QString::number(p)); + return rc; +} + +QStringList TrkOptions::blueToothDevices() +{ + QStringList rc; + rc.push_back(QLatin1String(blueToothDeviceDefaultC)); + return rc; +} + +} // namespace Internal +} // namespace Debugger diff --git a/src/plugins/debugger/gdb/trkoptions.h b/src/plugins/debugger/gdb/trkoptions.h new file mode 100644 index 0000000000000000000000000000000000000000..cacf1a93cbea8d051d9b4966d8eda102450bbece --- /dev/null +++ b/src/plugins/debugger/gdb/trkoptions.h @@ -0,0 +1,74 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** Commercial Usage +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** GNU Lesser General Public License Usage +** +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** +**************************************************************************/ + +#ifndef TRKOPTIONS_H +#define TRKOPTIONS_H + +#include <QtCore/QStringList> + +QT_BEGIN_NAMESPACE +class QSettings; +QT_END_NAMESPACE + +namespace Debugger { +namespace Internal { + +/* Parameter to be used for debugging S60 via TRK. + * GDB is a Symbian-ARM Gdb. It is Cygwin-built on Windows; the cygwin + * location 'x/bin' will prepended to the execution path. + * Communication happens either via BlueTooth (Linux only) or + * serial ports. */ + +struct TrkOptions +{ + enum Mode { Serial, BlueTooth }; + + TrkOptions(); + void fromSettings(const QSettings *s); + void toSettings(QSettings *s) const; + bool equals(const TrkOptions &o) const; + + // Lists of choices for the devices + static QStringList serialPorts(); + static QStringList blueToothDevices(); + + int mode; + QString serialPort; + QString blueToothDevice; + QString gdb; + QString cygwin; // ignored on Linux +}; + +inline bool operator==(const TrkOptions &o1, const TrkOptions &o2) { return o1.equals(o2); } +inline bool operator!=(const TrkOptions &o1, const TrkOptions &o2) { return !o1.equals(o2); } + +} // namespace Internal +} // namespace Debugger + +#endif // TRKOPTIONS_H diff --git a/src/plugins/debugger/gdb/trkoptionspage.cpp b/src/plugins/debugger/gdb/trkoptionspage.cpp new file mode 100644 index 0000000000000000000000000000000000000000..2962e3c2ceb467e772764db2549bb1bb6afc4c96 --- /dev/null +++ b/src/plugins/debugger/gdb/trkoptionspage.cpp @@ -0,0 +1,98 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** Commercial Usage +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** GNU Lesser General Public License Usage +** +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** +**************************************************************************/ + +#include "trkoptionspage.h" +#include "trkoptionswidget.h" +#include "trkoptions.h" +#include "debuggerconstants.h" + +#include <coreplugin/icore.h> + +#include <QtCore/QCoreApplication> +#include <QtCore/QSettings> + +namespace Debugger { +namespace Internal { + +const char * const TRK_SETTINGS_ID = QT_TRANSLATE_NOOP("Debugger::Internal::TrkOptionsPage", "S60 / Trk"); + +TrkOptionsPage::TrkOptionsPage(const TrkOptionsPtr &options) : + m_options(options) +{ +} + +TrkOptionsPage::~TrkOptionsPage() +{ +} + +QString TrkOptionsPage::settingsId() +{ + return QLatin1String(TRK_SETTINGS_ID); +} + +QString TrkOptionsPage::trName() const +{ + return tr(TRK_SETTINGS_ID); +} + +QString TrkOptionsPage::category() const +{ + return QLatin1String(Debugger::Constants::DEBUGGER_SETTINGS_CATEGORY); +} + +QString TrkOptionsPage::trCategory() const +{ + return QCoreApplication::translate("Debugger", Debugger::Constants::DEBUGGER_SETTINGS_CATEGORY); +} + +QWidget *TrkOptionsPage::createPage(QWidget *parent) +{ + if (!m_widget) + m_widget = new TrkOptionsWidget(parent); + m_widget->setTrkOptions(*m_options); + return m_widget; +} + +void TrkOptionsPage::apply() +{ + if (!m_widget) + return; + const TrkOptions newOptions = m_widget->trkOptions(); + if (newOptions == *m_options) + return; + *m_options = newOptions; + m_options->toSettings(Core::ICore::instance()->settings()); +} + +void TrkOptionsPage::finish() +{ +} + +} // namespace Internal +} // namespace Designer diff --git a/src/plugins/debugger/gdb/trkoptionspage.h b/src/plugins/debugger/gdb/trkoptionspage.h new file mode 100644 index 0000000000000000000000000000000000000000..1d33ab954f5cd1f19c651488261e66f38f5b6b39 --- /dev/null +++ b/src/plugins/debugger/gdb/trkoptionspage.h @@ -0,0 +1,72 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** Commercial Usage +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** GNU Lesser General Public License Usage +** +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** +**************************************************************************/ + +#ifndef TRKOPTIONSPAGE_H +#define TRKOPTIONSPAGE_H + +#include <QtGui/QWidget> +#include <QtCore/QSharedPointer> +#include <QtCore/QPointer> + +#include <coreplugin/dialogs/ioptionspage.h> + +namespace Debugger { +namespace Internal { + +class TrkOptionsWidget; +struct TrkOptions; + +class TrkOptionsPage : public Core::IOptionsPage +{ + Q_OBJECT + Q_DISABLE_COPY(TrkOptionsPage) +public: + typedef QSharedPointer<TrkOptions> TrkOptionsPtr; + + TrkOptionsPage(const TrkOptionsPtr &options); + virtual ~TrkOptionsPage(); + + virtual QString id() const { return settingsId(); } + virtual QString trName() const; + virtual QString category() const; + virtual QString trCategory() const; + + virtual QWidget *createPage(QWidget *parent); + virtual void apply(); + virtual void finish(); + + static QString settingsId(); +private: + const TrkOptionsPtr m_options; + QPointer<TrkOptionsWidget> m_widget; +}; + +} // namespace Internal +} // namespace Designer +#endif // TRKOPTIONSPAGE_H diff --git a/src/plugins/debugger/gdb/trkoptionswidget.cpp b/src/plugins/debugger/gdb/trkoptionswidget.cpp new file mode 100644 index 0000000000000000000000000000000000000000..34b5afb4f3c0b00ad2eefef59b896333125477c1 --- /dev/null +++ b/src/plugins/debugger/gdb/trkoptionswidget.cpp @@ -0,0 +1,98 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** Commercial Usage +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** GNU Lesser General Public License Usage +** +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** +**************************************************************************/ + +#include "trkoptionswidget.h" +#include "trkoptions.h" +#include "debuggerconstants.h" +#include "ui_trkoptionswidget.h" + +namespace Debugger { +namespace Internal { + +TrkOptionsWidget::TrkOptionsWidget(QWidget *parent) : + QWidget(parent), + ui(new Ui::TrkOptionsWidget) +{ + ui->setupUi(this); + ui->gdbChooser->setExpectedKind(Core::Utils::PathChooser::Command); + ui->cygwinChooser->setExpectedKind(Core::Utils::PathChooser::Directory); + ui->blueToothComboBox->addItems(TrkOptions::blueToothDevices()); + ui->serialComboBox->addItems(TrkOptions::serialPorts()); + connect(ui->commComboBox, SIGNAL(currentIndexChanged(int)), ui->commStackedWidget, SLOT(setCurrentIndex(int))); + // No bluetooth on Windows yet... +#ifdef Q_OS_WIN + ui->commComboBox->setEnabled(false); +#else + ui->cygwinChooser->setVisible(false); + ui->cygwinLabel->setVisible(false); +#endif +} + +TrkOptionsWidget::~TrkOptionsWidget() +{ + delete ui; +} + +void TrkOptionsWidget::changeEvent(QEvent *e) +{ + QWidget::changeEvent(e); + switch (e->type()) { + case QEvent::LanguageChange: + ui->retranslateUi(this); + break; + default: + break; + } +} + +void TrkOptionsWidget::setTrkOptions(const TrkOptions &o) +{ + ui->commComboBox->setCurrentIndex(o.mode); + ui->commStackedWidget->setCurrentIndex(o.mode); + const int serialPortIndex = qMax(0, ui->serialComboBox->findText(o.serialPort)); + ui->serialComboBox->setCurrentIndex(serialPortIndex); + ui->gdbChooser->setPath(o.gdb); + ui->cygwinChooser->setPath(o.cygwin); + const int blueToothIndex = qMax(0, ui->blueToothComboBox->findText(o.blueToothDevice)); + ui->blueToothComboBox->setCurrentIndex(blueToothIndex); +} + +TrkOptions TrkOptionsWidget::trkOptions() const +{ + TrkOptions rc; + rc.mode = ui->commComboBox->currentIndex(); + rc.gdb = ui->gdbChooser->path(); + rc.cygwin = ui->cygwinChooser->path(); + rc.blueToothDevice = ui->blueToothComboBox->currentText(); + rc.serialPort = ui->serialComboBox->currentText(); + return rc; +} + +} // namespace Internal +} // namespace Designer diff --git a/src/plugins/debugger/gdb/trkoptionswidget.h b/src/plugins/debugger/gdb/trkoptionswidget.h new file mode 100644 index 0000000000000000000000000000000000000000..25ca593dbb1f55e8241369b83ae046844c193e4a --- /dev/null +++ b/src/plugins/debugger/gdb/trkoptionswidget.h @@ -0,0 +1,62 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** Commercial Usage +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** GNU Lesser General Public License Usage +** +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** +**************************************************************************/ + +#ifndef TRKOPTIONSWIDGET_H +#define TRKOPTIONSWIDGET_H + +#include <QtGui/QWidget> + +namespace Debugger { +namespace Internal { + +struct TrkOptions; + +namespace Ui { + class TrkOptionsWidget; +} + +class TrkOptionsWidget : public QWidget { + Q_OBJECT +public: + TrkOptionsWidget(QWidget *parent = 0); + ~TrkOptionsWidget(); + + void setTrkOptions(const TrkOptions &); + TrkOptions trkOptions() const; + +protected: + void changeEvent(QEvent *e); + +private: + Ui::TrkOptionsWidget *ui; +}; + +} // namespace Internal +} // namespace Designer +#endif // TRKOPTIONSWIDGET_H diff --git a/src/plugins/debugger/gdb/trkoptionswidget.ui b/src/plugins/debugger/gdb/trkoptionswidget.ui new file mode 100644 index 0000000000000000000000000000000000000000..a1c699438d17e271576331ad489bb2d8c8b96d0e --- /dev/null +++ b/src/plugins/debugger/gdb/trkoptionswidget.ui @@ -0,0 +1,149 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>Debugger::Internal::TrkOptionsWidget</class> + <widget class="QWidget" name="Debugger::Internal::TrkOptionsWidget"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>400</width> + <height>300</height> + </rect> + </property> + <property name="windowTitle"> + <string>Form</string> + </property> + <layout class="QVBoxLayout" name="verticalLayout_2"> + <item> + <widget class="QGroupBox" name="gdbGroupBox"> + <property name="title"> + <string>Gdb</string> + </property> + <layout class="QFormLayout" name="formLayout"> + <item row="0" column="0"> + <widget class="QLabel" name="gdbLabel"> + <property name="text"> + <string>Symbian ARM gdb location:</string> + </property> + </widget> + </item> + <item row="0" column="1"> + <widget class="Core::Utils::PathChooser" name="gdbChooser" native="true"/> + </item> + <item row="1" column="0"> + <widget class="QLabel" name="cygwinLabel"> + <property name="text"> + <string>Cygwin location:</string> + </property> + </widget> + </item> + <item row="1" column="1"> + <widget class="Core::Utils::PathChooser" name="cygwinChooser" native="true"/> + </item> + </layout> + </widget> + </item> + <item> + <widget class="QGroupBox" name="commGroupBox"> + <property name="title"> + <string>Communication</string> + </property> + <layout class="QHBoxLayout" name="horizontalLayout"> + <item> + <layout class="QVBoxLayout" name="verticalLayout"> + <item> + <widget class="QComboBox" name="commComboBox"> + <item> + <property name="text"> + <string>Serial Port</string> + </property> + </item> + <item> + <property name="text"> + <string>Bluetooth</string> + </property> + </item> + </widget> + </item> + <item> + <widget class="QStackedWidget" name="commStackedWidget"> + <property name="currentIndex"> + <number>1</number> + </property> + <widget class="QWidget" name="serialPage"> + <layout class="QFormLayout" name="formLayout_2"> + <item row="0" column="0"> + <widget class="QLabel" name="serialLabel"> + <property name="text"> + <string>Port:</string> + </property> + </widget> + </item> + <item row="0" column="1"> + <widget class="QComboBox" name="serialComboBox"/> + </item> + </layout> + </widget> + <widget class="QWidget" name="blueToothPage"> + <layout class="QFormLayout" name="formLayout_3"> + <property name="fieldGrowthPolicy"> + <enum>QFormLayout::ExpandingFieldsGrow</enum> + </property> + <item row="0" column="1"> + <widget class="QComboBox" name="blueToothComboBox"/> + </item> + <item row="0" column="0"> + <widget class="QLabel" name="blueToothLabel"> + <property name="text"> + <string>Device:</string> + </property> + </widget> + </item> + </layout> + </widget> + </widget> + </item> + </layout> + </item> + <item> + <spacer name="commHorizontalSpacer"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>182</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + </layout> + </widget> + </item> + <item> + <spacer name="verticalSpacer"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>40</height> + </size> + </property> + </spacer> + </item> + </layout> + </widget> + <customwidgets> + <customwidget> + <class>Core::Utils::PathChooser</class> + <extends>QWidget</extends> + <header location="global">utils/pathchooser.h</header> + <container>1</container> + </customwidget> + </customwidgets> + <resources/> + <connections/> +</ui> diff --git a/tests/manual/trk/runner.cpp b/tests/manual/trk/runner.cpp index 77b0d6a02d7a6c8a05e353130ef5dcc57b55fac8..25ff2d46847e31343b0fb5ca8986ff0ad3557f51 100755 --- a/tests/manual/trk/runner.cpp +++ b/tests/manual/trk/runner.cpp @@ -28,6 +28,7 @@ **************************************************************************/ #include "trkgdbadapter.h" +#include "trkoptions.h" #include <QtCore/QDebug> @@ -38,6 +39,9 @@ #include <QtGui/QTextBlock> #include <QtGui/QTextEdit> #include <QtGui/QToolBar> +#include <QtCore/QSharedPointer> +#include <QtCore/QTimer> +#include <QtCore/QDir> /////////////////////////////////////////////////////////////////////// // @@ -224,7 +228,9 @@ void RunnerGui::started() int main(int argc, char *argv[]) { QApplication app(argc, argv); - TrkGdbAdapter adapter; + QSharedPointer<TrkOptions> options(new TrkOptions); + options->gdb = QDir::currentPath() + QLatin1String("/cs-gdb"); + TrkGdbAdapter adapter(options); adapter.setVerbose(2); RunnerGui gui(&adapter); gui.show(); diff --git a/tests/manual/trk/runner.pro b/tests/manual/trk/runner.pro index 6a409f6e6a772f2d26ae06e5d0d4b089dddce361..91a27d01c021c8de6d09d575927dbf08ff4ce57e 100644 --- a/tests/manual/trk/runner.pro +++ b/tests/manual/trk/runner.pro @@ -15,8 +15,10 @@ win32:CONFIG+=console HEADERS += \ $$DEBUGGERHOME/abstractgdbadapter.h \ + $$DEBUGGERHOME/trkoptions.h \ $$DEBUGGERHOME/trkgdbadapter.h \ SOURCES += \ $$DEBUGGERHOME/trkgdbadapter.cpp \ + $$DEBUGGERHOME/trkoptions.cpp \ $$PWD/runner.cpp \