OSDN Git Service

S60: Introduce a communications device type.
authorFriedemann Kleint <Friedemann.Kleint@nokia.com>
Thu, 22 Oct 2009 14:42:25 +0000 (16:42 +0200)
committerFriedemann Kleint <Friedemann.Kleint@nokia.com>
Thu, 22 Oct 2009 14:42:25 +0000 (16:42 +0200)
- Introduce a communications device type flag, add stubs for
  Bluetooth to serialdevicelister and pass the device type
  in new struct CommunicationDevice along to run configuration
  and debugger start parameters (overriding the debugger settings).
- Give the s60devices::Device a tooltip in the settings page

14 files changed:
src/plugins/debugger/debuggermanager.cpp
src/plugins/debugger/debuggermanager.h
src/plugins/debugger/gdb/trkgdbadapter.cpp
src/plugins/debugger/gdb/trkgdbadapter.h
src/plugins/qt4projectmanager/qt-s60/s60devicerunconfiguration.cpp
src/plugins/qt4projectmanager/qt-s60/s60devicerunconfiguration.h
src/plugins/qt4projectmanager/qt-s60/s60devicerunconfigurationwidget.cpp
src/plugins/qt4projectmanager/qt-s60/s60devicerunconfigurationwidget.h
src/plugins/qt4projectmanager/qt-s60/s60devices.cpp
src/plugins/qt4projectmanager/qt-s60/s60devices.h
src/plugins/qt4projectmanager/qt-s60/s60devicespreferencepane.cpp
src/plugins/qt4projectmanager/qt-s60/serialdevicelister.cpp
src/plugins/qt4projectmanager/qt-s60/serialdevicelister.h
src/shared/trk/trkdevice.cpp

index 9c21448..51f7d21 100644 (file)
@@ -216,6 +216,7 @@ static const char *stateName(int s)
 DebuggerStartParameters::DebuggerStartParameters()
   : attachPID(-1),
     useTerminal(false),
+    remoteChannelType(-1),
     toolChainType(ProjectExplorer::ToolChain::UNKNOWN),
     startMode(NoStartMode)
 {}
index c82bacb..b2c5bb9 100644 (file)
@@ -113,6 +113,7 @@ public:
     QString crashParameter; // for AttachCrashedExternal
     // for remote debugging
     QString remoteChannel;
+    int remoteChannelType;
     QString remoteArchitecture;
     QString symbolFileName;
     QString serverStartScript;
index c62a31b..de7dfae 100644 (file)
@@ -191,6 +191,7 @@ void Snapshot::insertMemory(const MemoryRange &range, const QByteArray &ba)
 TrkGdbAdapter::TrkGdbAdapter(GdbEngine *engine, const TrkOptionsPtr &options) :
     AbstractGdbAdapter(engine),
     m_options(options),
+    m_overrideTrkDeviceType(-1),
     m_running(false),
     m_gdbAckMode(true),
     m_verbose(2),
@@ -225,7 +226,7 @@ TrkGdbAdapter::TrkGdbAdapter(GdbEngine *engine, const TrkOptionsPtr &options) :
         this, SLOT(handleTrkError(QString)));
 
     m_trkDevice.setVerbose(m_verbose);
-    m_trkDevice.setSerialFrame(m_options->mode != TrkOptions::BlueTooth);
+    m_trkDevice.setSerialFrame(effectiveTrkDeviceType() != TrkOptions::BlueTooth);
 
     connect(&m_trkDevice, SIGNAL(logMessage(QString)),
         this, SLOT(trkLogMessage(QString)));
@@ -237,16 +238,6 @@ 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())
@@ -256,6 +247,13 @@ QString TrkGdbAdapter::effectiveTrkDevice() const
     return m_options->serialPort;
 }
 
+int TrkGdbAdapter::effectiveTrkDeviceType() const
+{
+    if (m_overrideTrkDeviceType >= 0)
+        return m_overrideTrkDeviceType;
+    return m_options->mode;
+}
+
 void TrkGdbAdapter::trkLogMessage(const QString &msg)
 {
     logMessage("TRK " + msg);
@@ -403,7 +401,7 @@ void TrkGdbAdapter::waitForTrkConnect()
                 .arg(QChar("/-\\|"[direction])));
         }
         // Do not loop forever
-        if (m_waitCount++ < (m_options->mode == TrkOptions::BlueTooth ? 60 : 5)) {
+        if (m_waitCount++ < (effectiveTrkDeviceType() == TrkOptions::BlueTooth ? 60 : 5)) {
             QTimer::singleShot(1000, this, SLOT(waitForTrkConnect()));
         } else {
             QString msg = _("Failed to connect to %1 after "
@@ -1519,7 +1517,8 @@ void TrkGdbAdapter::startAdapter()
 {
     // Retrieve parameters
     const DebuggerStartParameters &parameters = startParameters();
-    setOverrideTrkDevice(parameters.remoteChannel);
+    m_overrideTrkDevice = parameters.remoteChannel;
+    m_overrideTrkDeviceType = parameters.remoteChannelType;
     m_remoteExecutable = parameters.executable;
     m_symbolFile = parameters.symbolFileName;
     // FIXME: testing hack, remove!
@@ -1534,7 +1533,8 @@ void TrkGdbAdapter::startAdapter()
     setState(AdapterStarting);
     debugMessage(_("TRYING TO START ADAPTER"));
     logMessage(QLatin1String("### Starting TrkGdbAdapter"));
-    if (m_options->mode == TrkOptions::BlueTooth) {
+    m_trkDevice.setSerialFrame(effectiveTrkDeviceType() != TrkOptions::BlueTooth);
+    if (effectiveTrkDeviceType() == TrkOptions::BlueTooth) {
         const QString device = effectiveTrkDevice();
         const QString blueToothListener = QLatin1String("rfcomm");
         QStringList blueToothListenerArguments;
index 9bc68b4..2f73b7f 100644 (file)
@@ -142,16 +142,13 @@ public:
     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 &);
-
 signals:
     void output(const QString &msg);
 
 private:
     const TrkOptionsPtr m_options;
     QString m_overrideTrkDevice;
+    int m_overrideTrkDeviceType;
 
     QString m_gdbServerName; // 127.0.0.1:(2222+uid)
 
@@ -302,6 +299,7 @@ private:
     Q_SLOT void handleRfcommStateChanged(QProcess::ProcessState newState);
 
     QString effectiveTrkDevice() const;
+    int effectiveTrkDeviceType() const;
 
     // Debuggee state
     trk::Session m_session; // global-ish data (process id, target information)
index dc3fa07..64b1ee1 100644 (file)
@@ -34,6 +34,7 @@
 #include "profilereader.h"
 #include "s60manager.h"
 #include "s60devices.h"
+#include "serialdevicelister.h"
 
 #include <coreplugin/icore.h>
 #include <coreplugin/messagemanager.h>
@@ -59,12 +60,19 @@ static QString lsFile(const QString &f)
     str << fi.size() << ' ' << fi.lastModified().toString(Qt::ISODate) << ' ' << QDir::toNativeSeparators(fi.absoluteFilePath());
     return rc;
 }
+
 // ======== S60DeviceRunConfiguration
 S60DeviceRunConfiguration::S60DeviceRunConfiguration(Project *project, const QString &proFilePath)
     : RunConfiguration(project),
     m_proFilePath(proFilePath),
     m_cachedTargetInformationValid(false),
-    m_serialPortName("COM5"),
+#ifdef Q_OS_WIN
+    m_serialPortName(QLatin1String("COM5")),
+    m_communicationType(SerialPortCommunication),
+#else
+    m_serialPortName(QLatin1String(SerialDeviceLister::linuxBlueToothDeviceRootC) + QLatin1Char('0')),
+    m_communicationType(BlueToothCommunication),
+#endif
     m_signingMode(SignSelf)
 {
     if (!m_proFilePath.isEmpty())
@@ -114,6 +122,7 @@ void S60DeviceRunConfiguration::save(PersistentSettingsWriter &writer) const
     writer.saveValue("CustomSignaturePath", m_customSignaturePath);
     writer.saveValue("CustomKeyPath", m_customKeyPath);
     writer.saveValue("SerialPortName", m_serialPortName);
+    writer.saveValue("CommunicationType", m_communicationType);
     RunConfiguration::save(writer);
 }
 
@@ -126,6 +135,7 @@ void S60DeviceRunConfiguration::restore(const PersistentSettingsReader &reader)
     m_customSignaturePath = reader.restoreValue("CustomSignaturePath").toString();
     m_customKeyPath = reader.restoreValue("CustomKeyPath").toString();
     m_serialPortName = reader.restoreValue("SerialPortName").toString().trimmed();
+    m_communicationType = reader.restoreValue("CommunicationType").toInt();
 }
 
 QString S60DeviceRunConfiguration::serialPortName() const
@@ -138,6 +148,16 @@ void S60DeviceRunConfiguration::setSerialPortName(const QString &name)
     m_serialPortName = name.trimmed();
 }
 
+int S60DeviceRunConfiguration::communicationType() const
+{
+    return m_communicationType;
+}
+
+void S60DeviceRunConfiguration::setCommunicationType(int t)
+{
+    m_communicationType = t;
+}
+
 QString S60DeviceRunConfiguration::targetName() const
 {
     const_cast<S60DeviceRunConfiguration *>(this)->updateTarget();
@@ -393,6 +413,7 @@ S60DeviceRunControlBase::S60DeviceRunControlBase(const QSharedPointer<RunConfigu
 
     m_serialPortName = s60runConfig->serialPortName();
     m_serialPortFriendlyName = S60Manager::instance()->serialDeviceLister()->friendlyNameForPort(m_serialPortName);
+    m_communicationType = s60runConfig->communicationType();
     m_targetName = s60runConfig->targetName();
     m_baseFileName = s60runConfig->basePackageFilePath();
     m_symbianPlatform = s60runConfig->symbianPlatform();
@@ -542,6 +563,7 @@ void S60DeviceRunControlBase::signsisProcessFinished()
 
     //TODO sisx destination and file path user definable
     m_launcher->setTrkServerName(m_serialPortName);
+    m_launcher->setSerialFrame(m_communicationType == SerialPortCommunication);
     const QString copySrc(m_baseFileName + ".sisx");
     const QString copyDst = QString("C:\\Data\\%1.sisx").arg(QFileInfo(m_baseFileName).fileName());
     const QString runFileName = QString("C:\\sys\\bin\\%1.exe").arg(m_targetName);
@@ -689,6 +711,7 @@ S60DeviceDebugRunControl::S60DeviceDebugRunControl(const QSharedPointer<ProjectE
             Qt::QueuedConnection);
 
     m_startParams->remoteChannel = rc->serialPortName();
+    m_startParams->remoteChannelType = rc->communicationType();
     m_startParams->startMode = Debugger::StartInternal;
     m_startParams->toolChainType = rc->toolChainType();
 }
index 41b48a9..1efaca4 100644 (file)
@@ -64,6 +64,10 @@ public:
 
     QString serialPortName() const;
     void setSerialPortName(const QString &name);
+    // See SerialDeviceListener
+    int communicationType() const;
+    void setCommunicationType(int t);
+
     QString targetName() const;
     QString basePackageFilePath() const;
     QString symbianPlatform() const;
@@ -98,7 +102,8 @@ private:
     QString m_packageTemplateFileName;
     bool m_cachedTargetInformationValid;
     QString m_serialPortName;
-    SigningMode m_signingMode;
+    int m_communicationType;
+    SigningMode m_signingMode;    
     QString m_customSignaturePath;
     QString m_customKeyPath;
 };
@@ -163,6 +168,7 @@ private:
 
     QString m_serialPortName;
     QString m_serialPortFriendlyName;
+    int     m_communicationType;
     QString m_targetName;
     QString m_baseFileName;
     QString m_symbianPlatform;
index b0b1b25..c0964e6 100644 (file)
@@ -50,6 +50,8 @@
 #include <QtGui/QApplication>
 #include <QtGui/QSpacerItem>
 
+Q_DECLARE_METATYPE(Qt4ProjectManager::Internal::CommunicationDevice)
+
 namespace Qt4ProjectManager {
 namespace Internal {
 
@@ -167,16 +169,16 @@ void S60DeviceRunConfigurationWidget::updateSerialDevices()
     m_serialPortsCombo->clear();
     clearDeviceInfo();
     const QString previousRunConfigurationPortName = m_runConfiguration->serialPortName();
-    const QList<SerialDeviceLister::SerialDevice> serialDevices = S60Manager::instance()->serialDeviceLister()->serialDevices();
+    const QList<CommunicationDevice> devices = S60Manager::instance()->serialDeviceLister()->communicationDevices();
     int newIndex = -1;
-    for (int i = 0; i < serialDevices.size(); ++i) {
-        const SerialDeviceLister::SerialDevice &device = serialDevices.at(i);
-        m_serialPortsCombo->addItem(device.friendlyName, device.portName);
+    for (int i = 0; i < devices.size(); ++i) {
+        const CommunicationDevice &device = devices.at(i);
+        m_serialPortsCombo->addItem(device.friendlyName, qVariantFromValue(device));
         if (device.portName == previousRunConfigurationPortName)
             newIndex = i;
     }
     // Set new index: prefer to keep old or set to 0, if available.
-    if (newIndex == -1 && !serialDevices.empty())
+    if (newIndex == -1 && !devices.empty())
         newIndex = 0;
     m_serialPortsCombo->setCurrentIndex(newIndex);
     if (newIndex == -1) {
@@ -184,20 +186,25 @@ void S60DeviceRunConfigurationWidget::updateSerialDevices()
         m_runConfiguration->setSerialPortName(QString());
     } else {
         m_deviceInfoButton->setEnabled(true);
-        const QString newPortName = portName(newIndex);
+        const QString newPortName = device(newIndex).portName;
         if (newPortName != previousRunConfigurationPortName)
             m_runConfiguration->setSerialPortName(newPortName);
     }
 }
 
-QString S60DeviceRunConfigurationWidget::portName(int index) const
+CommunicationDevice S60DeviceRunConfigurationWidget::device(int i) const
 {
-    return index >= 0 ? m_serialPortsCombo->itemData(index).toString() : QString();
+    if (i >= 0) {
+        const QVariant data = m_serialPortsCombo->itemData(i);
+        if (qVariantCanConvert<Qt4ProjectManager::Internal::CommunicationDevice>(data))
+            return qVariantValue<Qt4ProjectManager::Internal::CommunicationDevice>(data);
+    }
+    return CommunicationDevice(SerialPortCommunication);
 }
 
-QString S60DeviceRunConfigurationWidget::currentPortName() const
+CommunicationDevice S60DeviceRunConfigurationWidget::currentDevice() const
 {
-    return portName(m_serialPortsCombo->currentIndex());
+    return device(m_serialPortsCombo->currentIndex());
 }
 
 void S60DeviceRunConfigurationWidget::nameEdited(const QString &text)
@@ -212,7 +219,9 @@ void S60DeviceRunConfigurationWidget::updateTargetInformation()
 
 void S60DeviceRunConfigurationWidget::setSerialPort(int index)
 {
-    m_runConfiguration->setSerialPortName(portName(index));
+    const CommunicationDevice d = device(index);
+    m_runConfiguration->setSerialPortName(d.portName);
+    m_runConfiguration->setCommunicationType(d.type);
     m_deviceInfoButton->setEnabled(index >= 0);
     clearDeviceInfo();
     updateSummary();
@@ -252,7 +261,7 @@ void S60DeviceRunConfigurationWidget::updateSummary()
                            tr("<No Device>");
     const QString signature = m_runConfiguration->signingMode() == S60DeviceRunConfiguration::SignCustom ?
                               tr("(custom certificate)") :
-                              tr("(self-signed certificate)");
+                              tr("(self-signed certificate)");    
     m_detailsWidget->setSummaryText(tr("Summary: Run on '%1' %2").arg(device, signature));
 }
 
@@ -284,7 +293,9 @@ bool S60DeviceRunConfigurationWidget::getDeviceInfo(QString *message)
     // Do a launcher run with the ping protocol. Instantiate launcher on heap
     // as not to introduce delays when destructing a device with timeout
     trk::Launcher *launcher = new trk::Launcher(trk::Launcher::ActionPingOnly, this);
-    launcher->setTrkServerName(currentPortName());
+    const CommunicationDevice commDev = currentDevice();
+    launcher->setSerialFrame(commDev.type == SerialPortCommunication);
+    launcher->setTrkServerName(commDev.portName);
     if (!launcher->startServer(message)) {
         launcher->deleteLater();
         return false;
index 65c5d19..1863f5d 100644 (file)
@@ -47,6 +47,7 @@ namespace Utils {
 namespace Qt4ProjectManager {
 namespace Internal {
 
+struct CommunicationDevice;
 class S60DeviceRunConfiguration;
 
 /* Configuration widget for S60 devices on serial ports that are
@@ -73,8 +74,9 @@ private slots:
     void clearDeviceInfo();
 
 private:
-    inline QString currentPortName() const;
-    inline QString portName(int index) const;
+    inline CommunicationDevice device(int i) const;
+    inline CommunicationDevice currentDevice() const;
+
     bool getDeviceInfo(QString *message);
     void setDeviceInfoLabel(const QString &message, bool isError = false);
 
index 08343e5..a9aa6dc 100644 (file)
 
 #include <QtCore/QSettings>
 #include <QtCore/QXmlStreamReader>
+#include <QtCore/QTextStream>
 #include <QtCore/QFile>
 #include <QtCore/QDir>
+#include <QtCore/QCoreApplication>
+#include <QtCore/QDebug>
 
 namespace {
     const char * const SYMBIAN_SDKS_KEY = "HKEY_LOCAL_MACHINE\\Software\\Symbian\\EPOC SDKs";
@@ -47,17 +50,58 @@ namespace {
     const char * const DEVICE_TOOLSROOT = "toolsroot";
 }
 
-using namespace Qt4ProjectManager::Internal;
+namespace Qt4ProjectManager {
+namespace Internal {
+
+S60Devices::Device::Device() :
+    isDefault(false)
+{
+}
+
+QString S60Devices::Device::toHtml() const
+{
+    QString rc;
+    QTextStream str(&rc);
+    str << "<html><body><table>"
+            << "<tr><td><b>" << QCoreApplication::translate("Qt4ProjectManager::Internal::S60Devices::Device", "Id:")
+            << "</b></td><td>" << id << "</td></tr>"
+            << "<tr><td><b>" << QCoreApplication::translate("Qt4ProjectManager::Internal::S60Devices::Device", "Name:")
+            << "</b></td><td>" << name << "</td></tr>"
+            << "<tr><td><b>" << QCoreApplication::translate("Qt4ProjectManager::Internal::S60Devices::Device", "EPOC:")
+            << "</b></td><td>" << epocRoot << "</td></tr>"
+            << "<tr><td><b>" << QCoreApplication::translate("Qt4ProjectManager::Internal::S60Devices::Device", "Tools:")
+            << "</b></td><td>" << toolsRoot << "</td></tr>"
+            << "<tr><td><b>" << QCoreApplication::translate("Qt4ProjectManager::Internal::S60Devices::Device", "Qt:")
+            << "</b></td><td>" << qt << "</td></tr>";
+    return rc;
+}
 
 S60Devices::S60Devices(QObject *parent)
         : QObject(parent)
 {
 }
 
+bool S60Devices::readLinux()
+{
+    m_errorString = QLatin1String("not implemented.");
+    return false;
+}
+
 bool S60Devices::read()
 {
     m_devices.clear();
-    m_errorString = QString();
+    m_errorString.clear();
+#ifdef Q_OS_WIN
+    return readWin();
+#else
+    return readLinux();
+#endif
+}
+
+// Windows EPOC
+
+bool S60Devices::readWin()
+{
     // Check the windows registry via QSettings for devices.xml path
     QSettings settings(SYMBIAN_SDKS_KEY, QSettings::NativeFormat);
     QString devicesXmlPath = settings.value(SYMBIAN_PATH_KEY).toString();
@@ -180,3 +224,22 @@ QString S60Devices::cleanedRootPath(const QString &deviceRoot)
     }
     return path;
 }
+
+QDebug operator<<(QDebug db, const S60Devices::Device &d)
+{
+    QDebug nospace = db.nospace();
+    nospace << "id='" << d.id << "' name='" << d.name << "' default="
+            << d.isDefault << " Epoc='" << d.epocRoot << "' tools='"
+            << d.toolsRoot << "' Qt='" << d.qt << '\'';
+    return db;
+}
+
+QDebug operator<<(QDebug dbg, const S60Devices &d)
+{
+    foreach(const S60Devices::Device &device, d.devices())
+        dbg << device;
+    return dbg;
+}
+
+} // namespace Internal
+} // namespace Qt4ProjectManager
index cb57aac..839fd32 100644 (file)
 #include <QtCore/QString>
 #include <QtCore/QList>
 
+QT_BEGIN_NAMESPACE
+class QDebug;
+QT_END_NAMESPACE
+
 namespace Qt4ProjectManager {
 namespace Internal {
 
@@ -42,6 +46,9 @@ class S60Devices : public QObject
     Q_OBJECT
 public:
     struct Device {
+        Device();
+        QString toHtml() const;
+
         QString id;
         QString name;
         bool isDefault;
@@ -62,10 +69,15 @@ signals:
     void qtVersionsChanged();
 
 private:
+    bool readLinux();
+    bool readWin();
     QString m_errorString;
     QList<Device> m_devices;
 };
 
+QDebug operator<<(QDebug dbg, const S60Devices::Device &d);
+QDebug operator<<(QDebug dbg, const S60Devices &d);
+
 } // namespace Internal
 } // namespace Qt4ProjectManager
 
index f9a4f21..8102391 100644 (file)
@@ -64,8 +64,13 @@ void S60DevicesWidget::updateDevicesList()
     QList<S60Devices::Device> devices = m_devices->devices();
     m_ui->list->clear();
     foreach (const S60Devices::Device &device, devices) {
-        m_ui->list->addTopLevelItem(new QTreeWidgetItem(QStringList() << device.epocRoot
-          << (device.qt.isEmpty()?tr("No Qt installed"):device.qt)));
+        QStringList columns;
+        columns << device.epocRoot << (device.qt.isEmpty()?tr("No Qt installed"):device.qt);
+        QTreeWidgetItem *item = new QTreeWidgetItem(columns);
+        const QString tooltip = device.toHtml();
+        item->setToolTip(0, tooltip);
+        item->setToolTip(1, tooltip);
+        m_ui->list->addTopLevelItem(item);
     }
 }
 
index a1a0b7b..35e2b64 100644 (file)
@@ -31,6 +31,7 @@
 
 #include <QtCore/QSettings>
 #include <QtCore/QStringList>
+#include <QtCore/QFileInfo>
 #include <QtGui/QApplication>
 #include <QtGui/QWidget>
 #include <QtDebug>
@@ -42,6 +43,17 @@ namespace {
     const char * const USBSER = "Services/usbser/Enum";
 }
 
+const char *SerialDeviceLister::linuxBlueToothDeviceRootC = "/dev/rfcomm";
+
+CommunicationDevice::CommunicationDevice(DeviceCommunicationType t,
+                                         const QString &p,
+                                         const QString &f) :
+    portName(p),
+    friendlyName(f),
+    type(t)
+{
+}
+
 SerialDeviceLister::SerialDeviceLister(QObject *parent)
         : QObject(parent),
         m_initialized(false)
@@ -53,18 +65,18 @@ SerialDeviceLister::~SerialDeviceLister()
 {
 }
 
-QList<SerialDeviceLister::SerialDevice> SerialDeviceLister::serialDevices() const
+QList<CommunicationDevice> SerialDeviceLister::communicationDevices() const
 {
     if (!m_initialized) {
         updateSilently();
         m_initialized = true;
     }
-    return m_devices;
+    return m_devices2;
 }
 
 QString SerialDeviceLister::friendlyNameForPort(const QString &port) const
 {
-    foreach (const SerialDevice &device, m_devices) {
+    foreach (const CommunicationDevice &device, m_devices2) {
         if (device.portName == port)
             return device.friendlyName;
     }
@@ -79,19 +91,44 @@ void SerialDeviceLister::update()
 
 void SerialDeviceLister::updateSilently() const
 {
-    m_devices.clear();
+    m_devices2 = serialPorts() + blueToothDevices();
+}
+
+QList<CommunicationDevice> SerialDeviceLister::serialPorts() const
+{
+    QList<CommunicationDevice> rc;
 #ifdef Q_OS_WIN32
     QSettings registry(REGKEY_CURRENT_CONTROL_SET, QSettings::NativeFormat);
-    int count = registry.value(QString::fromLatin1("%1/Count").arg(USBSER)).toInt();
+    const int count = registry.value(QString::fromLatin1("%1/Count").arg(USBSER)).toInt();
     for (int i = 0; i < count; ++i) {
         QString driver = registry.value(QString::fromLatin1("%1/%2").arg(USBSER).arg(i)).toString();
         if (driver.contains("JAVACOMM")) {
             driver.replace('\\', '/');
-            SerialDeviceLister::SerialDevice device;
+            CommunicationDevice device(SerialPortCommunication);
             device.friendlyName = registry.value(QString::fromLatin1("Enum/%1/FriendlyName").arg(driver)).toString();
             device.portName = registry.value(QString::fromLatin1("Enum/%1/Device Parameters/PortName").arg(driver)).toString();
-            m_devices.append(device);
+            rc.append(device);
+        }
+    }
+#endif
+    return rc;
+}
+
+QList<CommunicationDevice> SerialDeviceLister::blueToothDevices() const
+{
+    QList<CommunicationDevice> rc;
+#if defined(Q_OS_UNIX) && !defined(Q_OS_MAC)
+    // Bluetooth devices are created on connection. List the existing ones
+    // or at least the first one.
+    const QString prefix = QLatin1String(linuxBlueToothDeviceRootC);
+    const QString friendlyFormat = QLatin1String("Bluetooth device (%1)");
+    for (int d = 0; d < 4; d++) {
+        CommunicationDevice device(BlueToothCommunication, prefix + QString::number(d));
+        if (d == 0 || QFileInfo(device.portName).exists()) {            
+            device.friendlyName = friendlyFormat.arg(device.portName);
+            rc.push_back(device);
         }
     }
 #endif
+    return rc;
 }
index f2f7184..b1fb655 100644 (file)
 #ifndef SERIALDEVICELISTER_H
 #define SERIALDEVICELISTER_H
 
-#include <QtCore/QAbstractEventDispatcher>
-#include <QtCore/QList>
 #include <QtCore/QObject>
-#include <QtCore/QString>
-
-//#ifdef Q_OS_WIN32
-//#include <windows.h>
-//#include <dbt.h>
-//#endif
 
 namespace Qt4ProjectManager {
 namespace Internal {
 
+enum DeviceCommunicationType {
+    SerialPortCommunication = 0,
+    BlueToothCommunication = 1
+};
+
+struct CommunicationDevice {
+    explicit CommunicationDevice(DeviceCommunicationType type = SerialPortCommunication,
+                                 const QString &portName = QString(),
+                                 const QString &friendlyName = QString());
+    QString portName;
+    QString friendlyName;
+    DeviceCommunicationType type;
+};
+
 class SerialDeviceLister : public QObject
 {
     Q_OBJECT
 public:
+    static const char *linuxBlueToothDeviceRootC;
 
-    struct SerialDevice {
-        QString portName;
-        QString friendlyName;
-    };
-
-    SerialDeviceLister(QObject *parent = 0);
+    explicit SerialDeviceLister(QObject *parent = 0);
     ~SerialDeviceLister();
-    QList<SerialDevice> serialDevices() const;
+
+    QList<CommunicationDevice> communicationDevices() const;
+
     QString friendlyNameForPort(const QString &port) const;
 
 public slots:
@@ -66,9 +70,11 @@ signals:
 
 private:
     void updateSilently() const;
+    QList<CommunicationDevice> serialPorts() const;
+    QList<CommunicationDevice> blueToothDevices() const;
 
     mutable bool m_initialized;
-    mutable QList<SerialDevice> m_devices;
+    mutable QList<CommunicationDevice> m_devices2;
 };
 
 } // Internal
index ef7bc8b..7fb21c0 100644 (file)
@@ -882,7 +882,7 @@ TrkDevice::~TrkDevice()
 bool TrkDevice::open(const QString &port, QString *errorMessage)
 {
     if (d->verbose)
-        qDebug() << "Opening" << port << "is open: " << isOpen();
+        qDebug() << "Opening" << port << "is open: " << isOpen() << " serialFrame=" << serialFrame();
     close();
 #ifdef Q_OS_WIN
     d->deviceContext->device = CreateFile(port.toStdWString().c_str(),