diff --git a/src/plugins/debugger/gdb/s60debuggerbluetoothstarter.cpp b/src/plugins/debugger/gdb/s60debuggerbluetoothstarter.cpp index 8dcfa4b9042a9a3d0cb5d417943a354d9279ee42..ad2869aac5812ea9a87bcefb197299f47a26e948 100644 --- a/src/plugins/debugger/gdb/s60debuggerbluetoothstarter.cpp +++ b/src/plugins/debugger/gdb/s60debuggerbluetoothstarter.cpp @@ -30,6 +30,7 @@ #include "s60debuggerbluetoothstarter.h" #include "bluetoothlistener.h" #include "debuggermanager.h" +#include "trkoptions.h" namespace Debugger { namespace Internal { @@ -48,5 +49,24 @@ trk::BluetoothListener *S60DebuggerBluetoothStarter::createListener() return rc; } +trk::PromptStartCommunicationResult +S60DebuggerBluetoothStarter::startCommunication(const TrkDevicePtr &trkDevice, + const QString &device, + int communicationType, + QWidget *msgBoxParent, + QString *errorMessage) +{ + // Bluetooth? + if (communicationType == TrkOptions::BlueTooth) { + S60DebuggerBluetoothStarter bluetoothStarter(trkDevice); + bluetoothStarter.setDevice(device); + return trk::promptStartBluetooth(bluetoothStarter, msgBoxParent, errorMessage); + } + // Serial + BaseCommunicationStarter serialStarter(trkDevice); + serialStarter.setDevice(device); + return trk::promptStartSerial(serialStarter, msgBoxParent, errorMessage); +} + } // namespace Internal } // namespace Debugger diff --git a/src/plugins/debugger/gdb/s60debuggerbluetoothstarter.h b/src/plugins/debugger/gdb/s60debuggerbluetoothstarter.h index 226e00072ac4af1403bf411162cf70a28df2d537..234afa2c2c9c731917befdb53737bcc512678d1e 100644 --- a/src/plugins/debugger/gdb/s60debuggerbluetoothstarter.h +++ b/src/plugins/debugger/gdb/s60debuggerbluetoothstarter.h @@ -31,6 +31,7 @@ #define S60DEBUGGERBLUETOOTHSTARTER_H #include "communicationstarter.h" +#include "bluetoothlistener_gui.h" namespace Debugger { namespace Internal { @@ -38,15 +39,24 @@ namespace Internal { /* S60DebuggerBluetoothStarter: Creates a listener in 'Listen' mode * parented on the Debugger manager which outputs to the debugger window. * Note: This is a "last resort" starter, normally, the run configuration - * should have already started a listener. */ + * should have already started a listener. + * Provides a static convenience to prompt for both connection types. */ class S60DebuggerBluetoothStarter : public trk::AbstractBluetoothStarter -{ +{ public: - explicit S60DebuggerBluetoothStarter(const TrkDevicePtr& trkDevice, QObject *parent = 0); + static trk::PromptStartCommunicationResult + startCommunication(const TrkDevicePtr &trkDevice, + const QString &device, + int communicationType, + QWidget *msgBoxParent, + QString *errorMessage); -protected: +protected: virtual trk::BluetoothListener *createListener(); + +private: + explicit S60DebuggerBluetoothStarter(const TrkDevicePtr& trkDevice, QObject *parent = 0); }; } // namespace Internal diff --git a/src/plugins/debugger/gdb/trkgdbadapter.cpp b/src/plugins/debugger/gdb/trkgdbadapter.cpp index e954396c30aeb00ad7860778c229eecf570e332b..bf23a09eab59024e29b17094bca9a6fcdafbc692 100644 --- a/src/plugins/debugger/gdb/trkgdbadapter.cpp +++ b/src/plugins/debugger/gdb/trkgdbadapter.cpp @@ -1512,30 +1512,22 @@ void TrkGdbAdapter::startAdapter() debugMessage(_("TRYING TO START ADAPTER")); logMessage(QLatin1String("### Starting TrkGdbAdapter")); m_trkDevice->setSerialFrame(effectiveTrkDeviceType() != TrkOptions::BlueTooth); - // Prompt the user for a bluetooth connection - const QString device = effectiveTrkDevice(); - QString message; - if (effectiveTrkDeviceType() == TrkOptions::BlueTooth) { - S60DebuggerBluetoothStarter starter(m_trkDevice); - starter.setDevice(device); - const trk::StartBluetoothGuiResult src = trk::startBluetoothGui(starter, 0, &message); - switch (src) { - case trk::BluetoothGuiConnected: - break; - case trk::BluetoothGuiCanceled: - emit adapterStartFailed(message, QString()); - return; - case trk::BluetoothGuiError: - emit adapterStartFailed(message, TrkOptionsPage::settingsId()); - return; - }; - } else { - if (!m_trkDevice->isOpen() && !m_trkDevice->open(device, &message)) { - message = tr("Failed to connect to %1: %2\nCheck whether TRK is running.").arg(device).arg(message); - logMessage(message); - emit adapterStartFailed(message, TrkOptionsPage::settingsId()); - return; - } + // Prompt the user to start communication + QString message; + const trk::PromptStartCommunicationResult src = + S60DebuggerBluetoothStarter::startCommunication(m_trkDevice, + effectiveTrkDevice(), + effectiveTrkDeviceType(), + 0, &message); + switch (src) { + case trk::PromptStartCommunicationConnected: + break; + case trk::PromptStartCommunicationCanceled: + emit adapterStartFailed(message, QString()); + return; + case trk::PromptStartCommunicationError: + emit adapterStartFailed(message, TrkOptionsPage::settingsId()); + return; } QTC_ASSERT(m_gdbServer == 0, delete m_gdbServer); diff --git a/src/plugins/debugger/gdb/trkoptions.h b/src/plugins/debugger/gdb/trkoptions.h index f4a288fe0743d902d641867db7fe4c34d8ebc89e..470b66ab52f8c56d5514879db68b90a4f6fd6bcb 100644 --- a/src/plugins/debugger/gdb/trkoptions.h +++ b/src/plugins/debugger/gdb/trkoptions.h @@ -46,6 +46,7 @@ namespace Internal { struct TrkOptions { + // Matches the communication enumeration from the S60 devices listener. enum Mode { Serial, BlueTooth }; TrkOptions(); diff --git a/src/plugins/qt4projectmanager/qt-s60/s60devicerunconfiguration.cpp b/src/plugins/qt4projectmanager/qt-s60/s60devicerunconfiguration.cpp index d547c3b6d83d77568d2764459da2766ec9479b3d..0804a9fe258c781192fad92b8158d293befc92f0 100644 --- a/src/plugins/qt4projectmanager/qt-s60/s60devicerunconfiguration.cpp +++ b/src/plugins/qt4projectmanager/qt-s60/s60devicerunconfiguration.cpp @@ -582,21 +582,24 @@ void S60DeviceRunControlBase::signsisProcessFinished() initLauncher(runFileName, m_launcher); emit addToOutputWindow(this, tr("Package: %1\nDeploying application to '%2'...").arg(lsFile(copySrc), m_serialPortFriendlyName)); QString errorMessage; - // Prompt the user to start up the Blue tooth connection - if (m_communicationType == BlueToothCommunication) { - S60RunConfigBluetoothStarter starter(m_launcher->trkDevice()); - switch (trk::startBluetoothGui(starter, 0, &errorMessage)) { - case trk::BluetoothGuiConnected: - break; - case trk::BluetoothGuiCanceled: - case trk::BluetoothGuiError: - delete m_launcher; - m_launcher = 0; - error(this, errorMessage); - emit finished(); - return; - }; - } + // Prompt the user to start up the Blue tooth connection + const trk::PromptStartCommunicationResult src = + S60RunConfigBluetoothStarter::startCommunication(m_launcher->trkDevice(), + m_serialPortName, + m_communicationType, 0, + &errorMessage); + switch (src) { + case trk::PromptStartCommunicationConnected: + break; + case trk::PromptStartCommunicationCanceled: + case trk::PromptStartCommunicationError: + delete m_launcher; + m_launcher = 0; + error(this, errorMessage); + emit finished(); + return; + }; + if (!m_launcher->startServer(&errorMessage)) { delete m_launcher; m_launcher = 0; diff --git a/src/plugins/qt4projectmanager/qt-s60/s60devicerunconfigurationwidget.cpp b/src/plugins/qt4projectmanager/qt-s60/s60devicerunconfigurationwidget.cpp index 0b1554b1bae58ab3191eb1ee110c454751ae3613..46ebf4f0443c8d4ed549304377b8ead268f2eaae 100644 --- a/src/plugins/qt4projectmanager/qt-s60/s60devicerunconfigurationwidget.cpp +++ b/src/plugins/qt4projectmanager/qt-s60/s60devicerunconfigurationwidget.cpp @@ -302,22 +302,22 @@ bool S60DeviceRunConfigurationWidget::getDeviceInfo(QString *message) const CommunicationDevice commDev = currentDevice(); launcher->setSerialFrame(commDev.type == SerialPortCommunication); launcher->setTrkServerName(commDev.portName); - // Prompt the user to start - if (commDev.type == BlueToothCommunication) { - S60RunConfigBluetoothStarter starter(launcher->trkDevice()); - starter.setDevice(launcher->trkServerName()); - const trk::StartBluetoothGuiResult src = trk::startBluetoothGui(starter, this, message); - switch (src) { - case trk::BluetoothGuiConnected: - break; - case trk::BluetoothGuiCanceled: - launcher->deleteLater(); - return true; - case trk::BluetoothGuiError: - launcher->deleteLater(); - return false; - }; - } + // Prompt user + const trk::PromptStartCommunicationResult src = + S60RunConfigBluetoothStarter::startCommunication(launcher->trkDevice(), + commDev.portName, + commDev.type, this, + message); + switch (src) { + case trk::PromptStartCommunicationConnected: + break; + case trk::PromptStartCommunicationCanceled: + launcher->deleteLater(); + return true; + case trk::PromptStartCommunicationError: + launcher->deleteLater(); + return false; + }; if (!launcher->startServer(message)) { launcher->deleteLater(); return false; diff --git a/src/plugins/qt4projectmanager/qt-s60/s60runconfigbluetoothstarter.cpp b/src/plugins/qt4projectmanager/qt-s60/s60runconfigbluetoothstarter.cpp index 1481dcacbc9d755e803a511a0a208a3e4f7c5cec..b12aa0f1d292196e81e9f31e5362ee4877537cb7 100644 --- a/src/plugins/qt4projectmanager/qt-s60/s60runconfigbluetoothstarter.cpp +++ b/src/plugins/qt4projectmanager/qt-s60/s60runconfigbluetoothstarter.cpp @@ -29,6 +29,7 @@ #include "s60runconfigbluetoothstarter.h" #include "bluetoothlistener.h" +#include "serialdevicelister.h" #include <coreplugin/icore.h> #include <coreplugin/messagemanager.h> @@ -49,5 +50,25 @@ trk::BluetoothListener *S60RunConfigBluetoothStarter::createListener() connect(rc, SIGNAL(message(QString)), core->messageManager(), SLOT(printToOutputPane(QString))); return rc; } + +trk::PromptStartCommunicationResult +S60RunConfigBluetoothStarter::startCommunication(const TrkDevicePtr &trkDevice, + const QString &device, + int communicationType, + QWidget *msgBoxParent, + QString *errorMessage) +{ + // Bluetooth? + if (communicationType == BlueToothCommunication) { + S60RunConfigBluetoothStarter bluetoothStarter(trkDevice); + bluetoothStarter.setDevice(device); + return trk::promptStartBluetooth(bluetoothStarter, msgBoxParent, errorMessage); + } + // Serial + BaseCommunicationStarter serialStarter(trkDevice); + serialStarter.setDevice(device); + return trk::promptStartSerial(serialStarter, msgBoxParent, errorMessage); +} + } // namespace Internal } // namespace Qt4ProjectManager diff --git a/src/plugins/qt4projectmanager/qt-s60/s60runconfigbluetoothstarter.h b/src/plugins/qt4projectmanager/qt-s60/s60runconfigbluetoothstarter.h index 0da8817b323dc445c18eebdbc1c93adb1a7cd415..70ea0123f5d44ca5772a9e1d42dd03a31663c6c9 100644 --- a/src/plugins/qt4projectmanager/qt-s60/s60runconfigbluetoothstarter.h +++ b/src/plugins/qt4projectmanager/qt-s60/s60runconfigbluetoothstarter.h @@ -31,20 +31,34 @@ #define S60RUNCONFIGBLUETOOTHSTARTER_H #include "communicationstarter.h" +#include "bluetoothlistener_gui.h" namespace Qt4ProjectManager { namespace Internal { /* S60RunConfigBluetoothStarter: Creates a listener in 'Listen' mode - * parented on the Qt Creator core which outputs to the message manager. */ + * parented on the Qt Creator core which outputs to the message manager. + * Provides a static convenience to prompt for both connection types. */ class S60RunConfigBluetoothStarter : public trk::AbstractBluetoothStarter { public: - explicit S60RunConfigBluetoothStarter(const TrkDevicePtr& trkDevice, QObject *parent = 0); + typedef trk::AbstractBluetoothStarter::TrkDevicePtr TrkDevicePtr; + + // Convenience function to start communication depending on type, + // passing on the right messages. + static trk::PromptStartCommunicationResult + startCommunication(const TrkDevicePtr &trkDevice, + const QString &device, + int communicationType, + QWidget *msgBoxParent, + QString *errorMessage); protected: virtual trk::BluetoothListener *createListener(); + +private: + explicit S60RunConfigBluetoothStarter(const TrkDevicePtr& trkDevice, QObject *parent = 0); }; } // namespace Internal diff --git a/src/shared/trk/bluetoothlistener_gui.cpp b/src/shared/trk/bluetoothlistener_gui.cpp index ee21c82a7c5c6b2850bef35954b33fac682e969e..edcb40a9a52564706ab5df041f415a0f83fdda32 100644 --- a/src/shared/trk/bluetoothlistener_gui.cpp +++ b/src/shared/trk/bluetoothlistener_gui.cpp @@ -38,38 +38,62 @@ namespace trk { -StartBluetoothGuiResult - startBluetoothGui(AbstractBluetoothStarter &starter, - QWidget *msgBoxParent, - QString *errorMessage) +PromptStartCommunicationResult + promptStartCommunication(BaseCommunicationStarter &starter, + const QString &msgBoxTitle, + const QString &msgBoxText, + QWidget *msgBoxParent, + QString *errorMessage) { errorMessage->clear(); + // Initial connection attempt. switch (starter.start()) { - case AbstractBluetoothStarter::Started: + case BaseCommunicationStarter::Started: break; - case AbstractBluetoothStarter::ConnectionSucceeded: - return BluetoothGuiConnected; - case AbstractBluetoothStarter::StartError: + case BaseCommunicationStarter::ConnectionSucceeded: + return PromptStartCommunicationConnected; + case BaseCommunicationStarter::StartError: *errorMessage = starter.errorString(); - return BluetoothGuiError; + return PromptStartCommunicationError; } - // Run the starter with the event loop of a message box, close it - // with the finished signals. - const QString title = QCoreApplication::translate("trk::startBluetoothGui", "Waiting for Bluetooth Connection"); - const QString message = QCoreApplication::translate("trk::startBluetoothGui", "Connecting to %1...").arg(starter.device()); - QMessageBox messageBox(QMessageBox::Information, title, message, QMessageBox::Cancel, msgBoxParent); + // Run the starter with the event loop of a message box, have the box + // closed by the signals of the starter. + QMessageBox messageBox(QMessageBox::Information, msgBoxTitle, msgBoxText, QMessageBox::Cancel, msgBoxParent); QObject::connect(&starter, SIGNAL(connected()), &messageBox, SLOT(close())); QObject::connect(&starter, SIGNAL(timeout()), &messageBox, SLOT(close())); - messageBox.exec(); - // Only starter.state() is reliable here. - if (starter.state() == AbstractBluetoothStarter::Running) { - *errorMessage = QCoreApplication::translate("trk::startBluetoothGui", "Connection on %1 canceled.").arg(starter.device()); - return BluetoothGuiCanceled; - } - if (starter.state() != AbstractBluetoothStarter::Connected) { + messageBox.exec(); + // Only starter.state() is reliable here to obtain the state. + switch (starter.state()) { + case AbstractBluetoothStarter::Running: + *errorMessage = QCoreApplication::translate("trk::promptStartCommunication", "Connection on %1 canceled.").arg(starter.device()); + return PromptStartCommunicationCanceled; + case AbstractBluetoothStarter::TimedOut: *errorMessage = starter.errorString(); - return BluetoothGuiError; + return PromptStartCommunicationError; + case AbstractBluetoothStarter::Connected: + break; } - return BluetoothGuiConnected; + return PromptStartCommunicationConnected; +} + +PromptStartCommunicationResult + promptStartSerial(BaseCommunicationStarter &starter, + QWidget *msgBoxParent, + QString *errorMessage) +{ + const QString title = QCoreApplication::translate("trk::promptStartCommunication", "Waiting for TRK"); + const QString message = QCoreApplication::translate("trk::promptStartCommunication", "Waiting for TRK to start on %1...").arg(starter.device()); + return promptStartCommunication(starter, title, message, msgBoxParent, errorMessage); } + +PromptStartCommunicationResult + promptStartBluetooth(BaseCommunicationStarter &starter, + QWidget *msgBoxParent, + QString *errorMessage) +{ + const QString title = QCoreApplication::translate("trk::promptStartCommunication", "Waiting for Bluetooth Connection"); + const QString message = QCoreApplication::translate("trk::promptStartCommunication", "Connecting to %1...").arg(starter.device()); + return promptStartCommunication(starter, title, message, msgBoxParent, errorMessage); +} + } // namespace trk diff --git a/src/shared/trk/bluetoothlistener_gui.h b/src/shared/trk/bluetoothlistener_gui.h index 2a7c57e291ae53ec7d3bdf53fcac0e4b4cb60d26..83cce425ea35ce6e4cae1463ef22ce16c78630ca 100644 --- a/src/shared/trk/bluetoothlistener_gui.h +++ b/src/shared/trk/bluetoothlistener_gui.h @@ -37,22 +37,39 @@ class QWidget; QT_END_NAMESPACE namespace trk { - class AbstractBluetoothStarter; +class BaseCommunicationStarter; - /* startBluetoothGui(): Prompt the user to start a Bluetooth - * connection with a message box he can cancel. Pass in - * the starter with device and parameters set up. */ +/* promptStartCommunication(): Convenience functions that + * prompt the user to start a communication (launching or + * connecting TRK) using a modal message box in which they can cancel. + * Pass in the starter with device and parameters set up. */ - enum StartBluetoothGuiResult { - BluetoothGuiConnected, - BluetoothGuiCanceled, - BluetoothGuiError - }; +enum PromptStartCommunicationResult { + PromptStartCommunicationConnected, + PromptStartCommunicationCanceled, + PromptStartCommunicationError +}; - StartBluetoothGuiResult - startBluetoothGui(AbstractBluetoothStarter &starter, +PromptStartCommunicationResult + promptStartCommunication(BaseCommunicationStarter &starter, + const QString &msgBoxTitle, + const QString &msgBoxText, + QWidget *msgBoxParent, + QString *errorMessage); + +// Convenience to start a serial connection (messages prompting +// to launch Trk). +PromptStartCommunicationResult + promptStartSerial(BaseCommunicationStarter &starter, QWidget *msgBoxParent, QString *errorMessage); + +// Convenience to start blue tooth connection (messages +// prompting to connect). +PromptStartCommunicationResult + promptStartBluetooth(BaseCommunicationStarter &starter, + QWidget *msgBoxParent, + QString *errorMessage); } // namespace trk #endif // BLUETOOTHLISTENER_GUI_H diff --git a/src/shared/trk/communicationstarter.cpp b/src/shared/trk/communicationstarter.cpp index 58a954cd26be473bbb535d1654f7e59fcf57efab..b425db2506280b3a22293d2a7e7b04171103d42d 100644 --- a/src/shared/trk/communicationstarter.cpp +++ b/src/shared/trk/communicationstarter.cpp @@ -35,11 +35,12 @@ #include <QtCore/QEventLoop> namespace trk { + // --------------- AbstractBluetoothStarter -struct AbstractBluetoothStarterPrivate { - explicit AbstractBluetoothStarterPrivate(const AbstractBluetoothStarter::TrkDevicePtr &d); +struct BaseCommunicationStarterPrivate { + explicit BaseCommunicationStarterPrivate(const BaseCommunicationStarter::TrkDevicePtr &d); - const AbstractBluetoothStarter::TrkDevicePtr trkDevice; + const BaseCommunicationStarter::TrkDevicePtr trkDevice; BluetoothListener *listener; QTimer *timer; int intervalMS; @@ -47,11 +48,10 @@ struct AbstractBluetoothStarterPrivate { int n; QString device; QString errorString; - AbstractBluetoothStarter::State state; + BaseCommunicationStarter::State state; }; -AbstractBluetoothStarterPrivate::AbstractBluetoothStarterPrivate(const AbstractBluetoothStarter::TrkDevicePtr &d) : - +BaseCommunicationStarterPrivate::BaseCommunicationStarterPrivate(const BaseCommunicationStarter::TrkDevicePtr &d) : trkDevice(d), listener(0), timer(0), @@ -59,32 +59,38 @@ AbstractBluetoothStarterPrivate::AbstractBluetoothStarterPrivate(const AbstractB attempts(-1), n(0), device(QLatin1String("/dev/rfcomm0")), - state(AbstractBluetoothStarter::TimedOut) + state(BaseCommunicationStarter::TimedOut) { } -AbstractBluetoothStarter::AbstractBluetoothStarter(const TrkDevicePtr &trkDevice, QObject *parent) : +BaseCommunicationStarter::BaseCommunicationStarter(const TrkDevicePtr &trkDevice, QObject *parent) : QObject(parent), - d(new AbstractBluetoothStarterPrivate(trkDevice)) + d(new BaseCommunicationStarterPrivate(trkDevice)) { } -AbstractBluetoothStarter::~AbstractBluetoothStarter() +BaseCommunicationStarter::~BaseCommunicationStarter() { stopTimer(); delete d; } -void AbstractBluetoothStarter::stopTimer() +void BaseCommunicationStarter::stopTimer() { if (d->timer && d->timer->isActive()) d->timer->stop(); } -AbstractBluetoothStarter::StartResult AbstractBluetoothStarter::start() +bool BaseCommunicationStarter::initializeStartupResources(QString *errorMessage) +{ + errorMessage->clear(); + return true; +} + +BaseCommunicationStarter::StartResult BaseCommunicationStarter::start() { if (state() == Running) { - d->errorString = QLatin1String("Internal error, attempt to re-start AbstractBluetoothStarter.\n"); + d->errorString = QLatin1String("Internal error, attempt to re-start BaseCommunicationStarter.\n"); return StartError; } // Before we instantiate timers, and such, try to open the device, @@ -92,10 +98,9 @@ AbstractBluetoothStarter::StartResult AbstractBluetoothStarter::start() // 'Watch' mode if (d->trkDevice->open(d->device , &(d->errorString))) return ConnectionSucceeded; - // Fire up the listener + // Pull up resources for next attempt d->n = 0; - d->listener = createListener(); - if (!d->listener->start(d->device, &(d->errorString))) + if (!initializeStartupResources(&(d->errorString))) return StartError; // Start timer if (!d->timer) { @@ -109,49 +114,49 @@ AbstractBluetoothStarter::StartResult AbstractBluetoothStarter::start() return Started; } -AbstractBluetoothStarter::State AbstractBluetoothStarter::state() const +BaseCommunicationStarter::State BaseCommunicationStarter::state() const { return d->state; } -int AbstractBluetoothStarter::intervalMS() const +int BaseCommunicationStarter::intervalMS() const { return d->intervalMS; } -void AbstractBluetoothStarter::setIntervalMS(int i) +void BaseCommunicationStarter::setIntervalMS(int i) { d->intervalMS = i; if (d->timer) d->timer->setInterval(i); } -int AbstractBluetoothStarter::attempts() const +int BaseCommunicationStarter::attempts() const { return d->attempts; } -void AbstractBluetoothStarter::setAttempts(int a) +void BaseCommunicationStarter::setAttempts(int a) { d->attempts = a; } -QString AbstractBluetoothStarter::device() const +QString BaseCommunicationStarter::device() const { return d->device; } -void AbstractBluetoothStarter::setDevice(const QString &dv) +void BaseCommunicationStarter::setDevice(const QString &dv) { d->device = dv; } -QString AbstractBluetoothStarter::errorString() const +QString BaseCommunicationStarter::errorString() const { return d->errorString; } -void AbstractBluetoothStarter::slotTimer() +void BaseCommunicationStarter::slotTimer() { ++d->n; // Check for timeout @@ -166,17 +171,32 @@ void AbstractBluetoothStarter::slotTimer() if (d->trkDevice->open(d->device , &(d->errorString))) { stopTimer(); const QString msg = tr("%1: Connection attempt %2 succeeded.").arg(d->device).arg(d->n); - d->listener->emitMessage(msg); + emit message(msg); d->state = Connected; emit connected(); } else { const QString msg = tr("%1: Connection attempt %2 failed: %3 (retrying)...") .arg(d->device).arg(d->n).arg(d->errorString); - d->listener->emitMessage(msg); + emit message(msg); } } } +// --------------- AbstractBluetoothStarter + +AbstractBluetoothStarter::AbstractBluetoothStarter(const TrkDevicePtr &trkDevice, QObject *parent) : + BaseCommunicationStarter(trkDevice, parent) +{ +} + +bool AbstractBluetoothStarter::initializeStartupResources(QString *errorMessage) +{ + // Create the listener and forward messages to it. + BluetoothListener *listener = createListener(); + connect(this, SIGNAL(message(QString)), listener, SLOT(emitMessage(QString))); + return listener->start(device(), errorMessage); +} + // -------- ConsoleBluetoothStarter ConsoleBluetoothStarter::ConsoleBluetoothStarter(const TrkDevicePtr &trkDevice, QObject *listenerParent, diff --git a/src/shared/trk/communicationstarter.h b/src/shared/trk/communicationstarter.h index e90578dc1717989610e86fcd6e94fef8b3fffa07..7b89e2472ed0a6c0583e7348362821a822075389 100644 --- a/src/shared/trk/communicationstarter.h +++ b/src/shared/trk/communicationstarter.h @@ -36,25 +36,28 @@ namespace trk { class TrkDevice; class BluetoothListener; -struct AbstractBluetoothStarterPrivate; - -/* AbstractBluetoothStarter: Repeatedly tries to open a trk device - * until a connection succeeds, allowing to do something else in the - * foreground (local event loop or asynchronous operation). - * Note that in case a Listener is already running in watch mode, it might - * also happen that connection succeeds immediately. - * Implementations must provide a factory function that creates and sets up the - * listener (mode, message connection, etc). */ - -class AbstractBluetoothStarter : public QObject { +struct BaseCommunicationStarterPrivate; + +/* BaseCommunicationStarter: A QObject that repeatedly tries to open a + * trk device until a connection succeeds or a timeout occurs (emitting + * signals), allowing to do something else in the foreground (local event loop + * [say QMessageBox] or some asynchronous operation). If the initial + * connection attempt in start() fails, the + * virtual initializeStartupResources() is called to initialize resources + * required to pull up the communication (namely Bluetooth listeners). + * The base class can be used as is to prompt the user to launch TRK for a serial + * communication as this requires no further resource setup. */ + +class BaseCommunicationStarter : public QObject { Q_OBJECT - Q_DISABLE_COPY(AbstractBluetoothStarter) + Q_DISABLE_COPY(BaseCommunicationStarter) public: - typedef QSharedPointer<TrkDevice> TrkDevicePtr; + typedef QSharedPointer<TrkDevice> TrkDevicePtr; enum State { Running, Connected, TimedOut }; - virtual ~AbstractBluetoothStarter(); + explicit BaseCommunicationStarter(const TrkDevicePtr& trkDevice, QObject *parent = 0); + virtual ~BaseCommunicationStarter(); int intervalMS() const; void setIntervalMS(int i); @@ -80,19 +83,40 @@ public: signals: void connected(); void timeout(); + void message(const QString &); private slots: void slotTimer(); protected: - explicit AbstractBluetoothStarter(const TrkDevicePtr& trkDevice, QObject *parent = 0); - // Overwrite to create and parametrize the listener. - virtual BluetoothListener *createListener() = 0; + virtual bool initializeStartupResources(QString *errorMessage); private: inline void stopTimer(); - AbstractBluetoothStarterPrivate *d; + BaseCommunicationStarterPrivate *d; +}; + +/* AbstractBluetoothStarter: Repeatedly tries to open a trk Bluetooth + * device. Note that in case a Listener is already running mode, the + * connection will succeed immediately. + * initializeStartupResources() is implemented to fire up the listener. + * Introduces a new virtual createListener() that derived classes must + * implement as a factory function that creates and sets up the + * listener (mode, message connection, etc). */ + +class AbstractBluetoothStarter : public BaseCommunicationStarter { + Q_OBJECT + Q_DISABLE_COPY(AbstractBluetoothStarter) +public: + +protected: + explicit AbstractBluetoothStarter(const TrkDevicePtr& trkDevice, QObject *parent = 0); + + // Implemented to fire up the listener. + virtual bool initializeStartupResources(QString *errorMessage); + // New virtual: Overwrite to create and parametrize the listener. + virtual BluetoothListener *createListener() = 0; }; /* ConsoleBluetoothStarter: Convenience class for console processes. Creates a @@ -102,12 +126,11 @@ class ConsoleBluetoothStarter : public AbstractBluetoothStarter { Q_OBJECT Q_DISABLE_COPY(ConsoleBluetoothStarter) public: - - static bool startBluetooth(const TrkDevicePtr& trkDevice, - QObject *listenerParent, - const QString &device, - int attempts, - QString *errorMessage); + static bool startBluetooth(const TrkDevicePtr& trkDevice, + QObject *listenerParent, + const QString &device, + int attempts, + QString *errorMessage); protected: virtual BluetoothListener *createListener(); diff --git a/src/shared/trk/trk.pri b/src/shared/trk/trk.pri index 5b0e067b15840566822e3e38ac546ae3086e2498..2ce17c0a6c68980811b893171e4c73022a21d603 100644 --- a/src/shared/trk/trk.pri +++ b/src/shared/trk/trk.pri @@ -14,6 +14,7 @@ SOURCES += $$PWD/trkutils.cpp \ $$PWD/bluetoothlistener.cpp \ $$PWD/communicationstarter.cpp +# Tests/trklauncher is a console application contains(QT, gui) { HEADERS += $$PWD/bluetoothlistener_gui.h SOURCES += $$PWD/bluetoothlistener_gui.cpp