diff --git a/src/plugins/qt4projectmanager/qt-s60/s60devicerunconfiguration.cpp b/src/plugins/qt4projectmanager/qt-s60/s60devicerunconfiguration.cpp index 079928f14bb0ab439a1631afa5b085a16b120d46..d60ac111ab155e83d14ef1b810d47d779077af6c 100644 --- a/src/plugins/qt4projectmanager/qt-s60/s60devicerunconfiguration.cpp +++ b/src/plugins/qt4projectmanager/qt-s60/s60devicerunconfiguration.cpp @@ -114,7 +114,7 @@ S60DeviceRunConfiguration::S60DeviceRunConfiguration(Project *project, const QSt m_serialPortName(QLatin1String("COM5")), m_communicationType(SerialPortCommunication), #else - m_serialPortName(QLatin1String(SerialDeviceLister::linuxBlueToothDeviceRootC) + QLatin1Char('0')), + m_serialPortName(QLatin1String(SymbianDeviceManager::linuxBlueToothDeviceRootC) + QLatin1Char('0')), m_communicationType(BlueToothCommunication), #endif m_signingMode(SignSelf) @@ -498,7 +498,7 @@ S60DeviceRunControlBase::S60DeviceRunControlBase(RunConfiguration *runConfigurat QTC_ASSERT(s60runConfig, return); m_toolChain = s60runConfig->toolChainType(); m_serialPortName = s60runConfig->serialPortName(); - m_serialPortFriendlyName = S60Manager::instance()->serialDeviceLister()->friendlyNameForPort(m_serialPortName); + m_serialPortFriendlyName = SymbianDeviceManager::instance()->friendlyNameForPort(m_serialPortName); m_communicationType = s60runConfig->communicationType(); m_targetName = s60runConfig->targetName(); m_baseFileName = s60runConfig->basePackageFilePath(); diff --git a/src/plugins/qt4projectmanager/qt-s60/s60devicerunconfigurationwidget.cpp b/src/plugins/qt4projectmanager/qt-s60/s60devicerunconfigurationwidget.cpp index f578eb88ad01440225689e0cb7bff59e31f46cba..a64d1dd5535c92bf1b65b3dee9c23d1e85445eab 100644 --- a/src/plugins/qt4projectmanager/qt-s60/s60devicerunconfigurationwidget.cpp +++ b/src/plugins/qt4projectmanager/qt-s60/s60devicerunconfigurationwidget.cpp @@ -56,7 +56,7 @@ #include <QtGui/QMainWindow> #include <QtGui/QMessageBox> -Q_DECLARE_METATYPE(Qt4ProjectManager::Internal::CommunicationDevice) +Q_DECLARE_METATYPE(Qt4ProjectManager::Internal::SymbianDevice) namespace Qt4ProjectManager { namespace Internal { @@ -100,7 +100,7 @@ S60DeviceRunConfigurationWidget::S60DeviceRunConfigurationWidget( formLayout->addRow(tr("Install File:"), m_sisxFileLabel); updateSerialDevices(); - connect(S60Manager::instance()->serialDeviceLister(), SIGNAL(updated()), + connect(SymbianDeviceManager::instance(), SIGNAL(updated()), this, SLOT(updateSerialDevices())); // Serial devices control connect(m_serialPortsCombo, SIGNAL(activated(int)), this, SLOT(setSerialPort(int))); @@ -180,12 +180,12 @@ void S60DeviceRunConfigurationWidget::updateSerialDevices() m_serialPortsCombo->clear(); clearDeviceInfo(); const QString previousRunConfigurationPortName = m_runConfiguration->serialPortName(); - const QList<CommunicationDevice> devices = S60Manager::instance()->serialDeviceLister()->communicationDevices(); + const QList<SymbianDevice> devices = SymbianDeviceManager::instance()->devices(); int newIndex = -1; 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) + const SymbianDevice &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. @@ -197,23 +197,23 @@ void S60DeviceRunConfigurationWidget::updateSerialDevices() m_runConfiguration->setSerialPortName(QString()); } else { m_deviceInfoButton->setEnabled(true); - const QString newPortName = device(newIndex).portName; + const QString newPortName = device(newIndex).portName(); if (newPortName != previousRunConfigurationPortName) m_runConfiguration->setSerialPortName(newPortName); } } -CommunicationDevice S60DeviceRunConfigurationWidget::device(int i) const +SymbianDevice S60DeviceRunConfigurationWidget::device(int i) const { if (i >= 0) { const QVariant data = m_serialPortsCombo->itemData(i); - if (qVariantCanConvert<Qt4ProjectManager::Internal::CommunicationDevice>(data)) - return qVariantValue<Qt4ProjectManager::Internal::CommunicationDevice>(data); + if (qVariantCanConvert<Qt4ProjectManager::Internal::SymbianDevice>(data)) + return qVariantValue<Qt4ProjectManager::Internal::SymbianDevice>(data); } - return CommunicationDevice(SerialPortCommunication); + return SymbianDevice(); } -CommunicationDevice S60DeviceRunConfigurationWidget::currentDevice() const +SymbianDevice S60DeviceRunConfigurationWidget::currentDevice() const { return device(m_serialPortsCombo->currentIndex()); } @@ -242,9 +242,9 @@ void S60DeviceRunConfigurationWidget::updateTargetInformation() void S60DeviceRunConfigurationWidget::setSerialPort(int index) { - const CommunicationDevice d = device(index); - m_runConfiguration->setSerialPortName(d.portName); - m_runConfiguration->setCommunicationType(d.type); + const SymbianDevice d = device(index); + m_runConfiguration->setSerialPortName(d.portName()); + m_runConfiguration->setCommunicationType(d.type()); m_deviceInfoButton->setEnabled(index >= 0); clearDeviceInfo(); } @@ -323,15 +323,15 @@ void S60DeviceRunConfigurationWidget::updateDeviceInfo() // go asynchronous afterwards to pop up launch trk box if a timeout occurs. m_infoLauncher = new trk::Launcher(trk::Launcher::ActionPingOnly, QSharedPointer<trk::TrkDevice>(), this); connect(m_infoLauncher, SIGNAL(stateChanged(int)), this, SLOT(slotLauncherStateChanged(int))); - const CommunicationDevice commDev = currentDevice(); - m_infoLauncher->setSerialFrame(commDev.type == SerialPortCommunication); - m_infoLauncher->setTrkServerName(commDev.portName); + const SymbianDevice commDev = currentDevice(); + m_infoLauncher->setSerialFrame(commDev.type() == SerialPortCommunication); + m_infoLauncher->setTrkServerName(commDev.portName()); // Prompt user QString message; const trk::PromptStartCommunicationResult src = S60RunConfigBluetoothStarter::startCommunication(m_infoLauncher->trkDevice(), - commDev.portName, - commDev.type, this, + commDev.portName(), + commDev.type(), this, &message); switch (src) { case trk::PromptStartCommunicationConnected: diff --git a/src/plugins/qt4projectmanager/qt-s60/s60devicerunconfigurationwidget.h b/src/plugins/qt4projectmanager/qt-s60/s60devicerunconfigurationwidget.h index 6d32f8af0fab15e1a49ababb50dd19b92b2b5f31..191f837ae31f334c0e71ef5de1484f31d9898690 100644 --- a/src/plugins/qt4projectmanager/qt-s60/s60devicerunconfigurationwidget.h +++ b/src/plugins/qt4projectmanager/qt-s60/s60devicerunconfigurationwidget.h @@ -52,7 +52,7 @@ namespace trk { namespace Qt4ProjectManager { namespace Internal { -struct CommunicationDevice; +class SymbianDevice; class S60DeviceRunConfiguration; /* Configuration widget for S60 devices on serial ports that are @@ -81,8 +81,8 @@ private slots: void slotWaitingForTrkClosed(); private: - inline CommunicationDevice device(int i) const; - inline CommunicationDevice currentDevice() const; + inline SymbianDevice device(int i) const; + inline SymbianDevice currentDevice() const; void setDeviceInfoLabel(const QString &message, bool isError = false); diff --git a/src/plugins/qt4projectmanager/qt-s60/s60manager.cpp b/src/plugins/qt4projectmanager/qt-s60/s60manager.cpp index e4bc1eed2ac9035af20d9c86a22d63c0f91ee083..b1d67c3209c9287fe87d4b68e111fde61779615d 100644 --- a/src/plugins/qt4projectmanager/qt-s60/s60manager.cpp +++ b/src/plugins/qt4projectmanager/qt-s60/s60manager.cpp @@ -98,8 +98,7 @@ S60Manager *S60Manager::instance() { return m_instance; } S60Manager::S60Manager(QObject *parent) : QObject(parent), - m_devices(new S60Devices(this)), - m_serialDeviceLister(new SerialDeviceLister(this)) + m_devices(new S60Devices(this)) { m_instance = this; #ifdef QTCREATOR_WITH_S60 @@ -127,7 +126,7 @@ S60Manager::S60Manager(QObject *parent) connect(m_devices, SIGNAL(qtVersionsChanged()), this, SLOT(updateQtVersions())); connect(Core::ICore::instance()->mainWindow(), SIGNAL(deviceChange()), - m_serialDeviceLister, SLOT(update())); + SymbianDeviceManager::instance(), SLOT(update())); } S60Manager::~S60Manager() diff --git a/src/plugins/qt4projectmanager/qt-s60/s60manager.h b/src/plugins/qt4projectmanager/qt-s60/s60manager.h index 1633b1bb9c9aabbb7b0591467c63cb1bca260bde..c807534f595e4eb397d52e4dc46f6170a14f616c 100644 --- a/src/plugins/qt4projectmanager/qt-s60/s60manager.h +++ b/src/plugins/qt4projectmanager/qt-s60/s60manager.h @@ -42,8 +42,6 @@ class ToolChain; namespace Qt4ProjectManager { namespace Internal { -class SerialDeviceLister; - class S60Manager : public QObject { Q_OBJECT @@ -62,8 +60,6 @@ public: S60Devices::Device deviceForQtVersion(const Qt4ProjectManager::QtVersion *version) const; QString deviceIdFromDetectionSource(const QString &autoDetectionSource) const; - SerialDeviceLister *serialDeviceLister() const { return m_serialDeviceLister; } - private slots: void updateQtVersions(); @@ -74,7 +70,6 @@ private: S60Devices *m_devices; QObjectList m_pluginObjects; - SerialDeviceLister *m_serialDeviceLister; }; } // namespace Internal diff --git a/src/plugins/qt4projectmanager/qt-s60/serialdevicelister.cpp b/src/plugins/qt4projectmanager/qt-s60/serialdevicelister.cpp index bcfac48f4a0afe417bec7d37db17273a6d851351..495aa5366e90fa14683958a1955127ca15e10037 100644 --- a/src/plugins/qt4projectmanager/qt-s60/serialdevicelister.cpp +++ b/src/plugins/qt4projectmanager/qt-s60/serialdevicelister.cpp @@ -32,103 +32,290 @@ #include <QtCore/QSettings> #include <QtCore/QStringList> #include <QtCore/QFileInfo> -#include <QtGui/QApplication> -#include <QtGui/QWidget> -#include <QtDebug> +#include <QtCore/QtDebug> +#include <QtCore/QTextStream> +#include <QtCore/QSharedData> +#include <QtCore/QScopedPointer> -using namespace Qt4ProjectManager::Internal; +namespace Qt4ProjectManager { +namespace Internal { -namespace { - const char * const REGKEY_CURRENT_CONTROL_SET = "HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet"; - const char * const USBSER = "Services/usbser/Enum"; +enum { debug = 0 }; + +static const char REGKEY_CURRENT_CONTROL_SET[] = "HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet"; +static const char USBSER[] = "Services/usbser/Enum"; + +const char *SymbianDeviceManager::linuxBlueToothDeviceRootC = "/dev/rfcomm"; + +// ------------- SymbianDevice +class SymbianDeviceData : public QSharedData { +public: + SymbianDeviceData() : type(SerialPortCommunication) {} + + QString portName; + QString friendlyName; + QString deviceDesc; + QString manufacturer; + DeviceCommunicationType type; +}; + +SymbianDevice::SymbianDevice(SymbianDeviceData *data) : + m_data(data) +{ + +} + +SymbianDevice::SymbianDevice() : + m_data(new SymbianDeviceData) +{ +} +SymbianDevice::SymbianDevice(const SymbianDevice &rhs) : + m_data(rhs.m_data) +{ +} + +SymbianDevice &SymbianDevice::operator=(const SymbianDevice &rhs) +{ + if (this != &rhs) + m_data = rhs.m_data; + return *this; +} + +SymbianDevice::~SymbianDevice() +{ +} + +QString SymbianDevice::portName() const +{ + return m_data->portName; +} + +QString SymbianDevice::friendlyName() const +{ + return m_data->friendlyName; +} + +QString SymbianDevice::deviceDesc() const +{ + return m_data->deviceDesc; +} + +QString SymbianDevice::manufacturer() const +{ + return m_data->manufacturer; +} + +DeviceCommunicationType SymbianDevice::type() const +{ + return m_data->type; } -const char *SerialDeviceLister::linuxBlueToothDeviceRootC = "/dev/rfcomm"; +bool SymbianDevice::isNull() const +{ + return !m_data->portName.isEmpty(); +} -CommunicationDevice::CommunicationDevice(DeviceCommunicationType t, - const QString &p, - const QString &f) : - portName(p), - friendlyName(f), - type(t) +QString SymbianDevice::toString() const { + QString rc; + QTextStream str(&rc); + format(str); + return rc; } -SerialDeviceLister::SerialDeviceLister(QObject *parent) - : QObject(parent), - m_initialized(false) +void SymbianDevice::format(QTextStream &str) const { + str << (m_data->type == BlueToothCommunication ? "Bluetooth: " : "Serial: ") + << m_data->portName; + if (!m_data->friendlyName.isEmpty()) { + str << " (" << m_data->friendlyName; + if (!m_data->deviceDesc.isEmpty()) + str << " / " << m_data->deviceDesc; + str << ')'; + } + if (!m_data->manufacturer.isEmpty()) + str << " [" << m_data->manufacturer << ']'; +} +// Compare by port and friendly name +int SymbianDevice::compare(const SymbianDevice &rhs) const +{ + if (const int prc = m_data->portName.compare(rhs.m_data->portName)) + return prc; + if (const int frc = m_data->friendlyName.compare(rhs.m_data->friendlyName)) + return frc; + return 0; +} + +QDebug operator<<(QDebug d, const SymbianDevice &cd) +{ + d.nospace() << cd.toString(); + return d; +} + +// ------------- SymbianDeviceManagerPrivate +struct SymbianDeviceManagerPrivate { + SymbianDeviceManagerPrivate() : m_initialized(false) {} + + bool m_initialized; + SymbianDeviceManager::SymbianDeviceList m_devices; +}; + +SymbianDeviceManager::SymbianDeviceManager(QObject *parent) : + QObject(parent), + d(new SymbianDeviceManagerPrivate) +{ +} + +SymbianDeviceManager::~SymbianDeviceManager() +{ + delete d; } -SerialDeviceLister::~SerialDeviceLister() +SymbianDeviceManager::SymbianDeviceList SymbianDeviceManager::devices() const { + if (!d->m_initialized) + const_cast<SymbianDeviceManager*>(this)->update(false); + return d->m_devices; } -QList<CommunicationDevice> SerialDeviceLister::communicationDevices() const +QString SymbianDeviceManager::toString() const { - if (!m_initialized) { - updateSilently(); - m_initialized = true; + QString rc; + QTextStream str(&rc); + const int count = d->m_devices.size(); + for (int i = 0; i < count; i++) { + str << '#' << i << ' '; + d->m_devices.at(i).format(str); + str << '\n'; } - return m_devices2; + return rc; } -QString SerialDeviceLister::friendlyNameForPort(const QString &port) const +QString SymbianDeviceManager::friendlyNameForPort(const QString &port) const { - foreach (const CommunicationDevice &device, m_devices2) { - if (device.portName == port) - return device.friendlyName; + foreach (const SymbianDevice &device, d->m_devices) { + if (device.portName() == port) + return device.friendlyName(); } return QString(); } -void SerialDeviceLister::update() +void SymbianDeviceManager::update() { - updateSilently(); - emit updated(); + update(true); } -void SerialDeviceLister::updateSilently() const +void SymbianDeviceManager::update(bool emitSignals) { - m_devices2 = serialPorts() + blueToothDevices(); + typedef SymbianDeviceList::iterator SymbianDeviceListIterator; + + if (debug) + qDebug(">SerialDeviceLister::update(%d)\n%s", int(emitSignals), + qPrintable(toString())); + + d->m_initialized = true; + // Get ordered new list + SymbianDeviceList newDevices = serialPorts() + blueToothDevices(); + if (newDevices.size() > 1) + qStableSort(newDevices.begin(), newDevices.end()); + if (d->m_devices == newDevices) // Happy, nothing changed. + return; + // Merge the lists and emit the respective added/removed signals, assuming + // no one can plug a different device on the same port at the speed of lightning + if (!d->m_devices.isEmpty()) { + // Find deleted devices + for (SymbianDeviceListIterator oldIt = d->m_devices.begin(); oldIt != d->m_devices.end(); ) { + if (newDevices.contains(*oldIt)) { + ++oldIt; + } else { + const SymbianDevice toBeDeleted = *oldIt; + oldIt = d->m_devices.erase(oldIt); + if (emitSignals) + emit deviceRemoved(toBeDeleted); + } + } + } + if (!newDevices.isEmpty()) { + // Find new devices and insert in order + foreach(const SymbianDevice &newDevice, newDevices) { + if (!d->m_devices.contains(newDevice)) { + d->m_devices.append(newDevice); + if (emitSignals) + emit deviceAdded(newDevice); + } + } + if (d->m_devices.size() > 1) + qStableSort(d->m_devices.begin(), d->m_devices.end()); + } + if (emitSignals) + emit updated(); + + if (debug) + qDebug("<SerialDeviceLister::update\n%s\n", qPrintable(toString())); } -QList<CommunicationDevice> SerialDeviceLister::serialPorts() const +SymbianDeviceManager::SymbianDeviceList SymbianDeviceManager::serialPorts() const { - QList<CommunicationDevice> rc; -#ifdef Q_OS_WIN32 - QSettings registry(REGKEY_CURRENT_CONTROL_SET, QSettings::NativeFormat); - const int count = registry.value(QString::fromLatin1("%1/Count").arg(USBSER)).toInt(); + SymbianDeviceList rc; +#ifdef Q_OS_WIN + const QSettings registry(REGKEY_CURRENT_CONTROL_SET, QSettings::NativeFormat); + const QString usbSerialRootKey = QLatin1String(USBSER) + QLatin1Char('/'); + const int count = registry.value(usbSerialRootKey + QLatin1String("Count")).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('\\', '/'); - 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(); - rc.append(device); + QString driver = registry.value(usbSerialRootKey + QString::number(i)).toString(); + if (driver.contains(QLatin1String("JAVACOMM"))) { + driver.replace(QLatin1Char('\\'), QLatin1Char('/')); + const QString driverRootKey = QLatin1String("Enum/") + driver + QLatin1Char('/'); + if (debug > 1) + qDebug() << "SerialDeviceLister::serialPorts(): Checking " << i << count + << REGKEY_CURRENT_CONTROL_SET << usbSerialRootKey << driverRootKey; + QScopedPointer<SymbianDeviceData> device(new SymbianDeviceData); + device->type = SerialPortCommunication; + device->friendlyName = registry.value(driverRootKey + QLatin1String("FriendlyName")).toString(); + device->portName = registry.value(driverRootKey + QLatin1String("Device Parameters/PortName")).toString(); + device->deviceDesc = registry.value(driverRootKey + QLatin1String("DeviceDesc")).toString(); + device->manufacturer = registry.value(driverRootKey + QLatin1String("Mfg")).toString(); + rc.append(SymbianDevice(device.take())); } } #endif return rc; } -QList<CommunicationDevice> SerialDeviceLister::blueToothDevices() const +SymbianDeviceManager::SymbianDeviceList SymbianDeviceManager::blueToothDevices() const { - QList<CommunicationDevice> rc; + SymbianDeviceList 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); + QScopedPointer<SymbianDeviceData> device(new SymbianDeviceData); + device->type = BlueToothCommunication; + device->portName = prefix + QString::number(d); + if (d == 0 || QFileInfo(device->portName).exists()) { + device->friendlyName = friendlyFormat.arg(device->portName); + rc.push_back(SymbianDevice(device.take())); } } #endif return rc; } + +Q_GLOBAL_STATIC(SymbianDeviceManager, symbianDeviceManager) + +SymbianDeviceManager *SymbianDeviceManager::instance() +{ + return symbianDeviceManager(); +} + +QDebug operator<<(QDebug d, const SymbianDeviceManager &sdm) +{ + d.nospace() << sdm.toString(); + return d; +} + +} // namespace Internal +} // namespace Qt4ProjectManager diff --git a/src/plugins/qt4projectmanager/qt-s60/serialdevicelister.h b/src/plugins/qt4projectmanager/qt-s60/serialdevicelister.h index b1fb65507ce79d55661badefcc2b0e9ebd8430a8..6abcf045c334383bbfe672edaf19fdffffa6fdcb 100644 --- a/src/plugins/qt4projectmanager/qt-s60/serialdevicelister.h +++ b/src/plugins/qt4projectmanager/qt-s60/serialdevicelister.h @@ -31,34 +31,81 @@ #define SERIALDEVICELISTER_H #include <QtCore/QObject> +#include <QtCore/QExplicitlySharedDataPointer> + +QT_BEGIN_NAMESPACE +class QDebug; +class QTextStream; +QT_END_NAMESPACE namespace Qt4ProjectManager { namespace Internal { +struct SymbianDeviceManagerPrivate; +class SymbianDeviceData; + 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; +// SymbianDevice, explicitly shared. +class SymbianDevice { + explicit SymbianDevice(SymbianDeviceData *data); + friend class SymbianDeviceManager; +public: + SymbianDevice(); + SymbianDevice(const SymbianDevice &rhs); + SymbianDevice &operator=(const SymbianDevice &rhs); + ~SymbianDevice(); + int compare(const SymbianDevice &rhs) const; + + DeviceCommunicationType type() const; + bool isNull() const; + QString portName() const; + QString friendlyName() const; + + // Windows only. + QString deviceDesc() const; + QString manufacturer() const; + + void format(QTextStream &str) const; + QString toString() const; + +private: + QExplicitlySharedDataPointer<SymbianDeviceData> m_data; }; -class SerialDeviceLister : public QObject +QDebug operator<<(QDebug d, const SymbianDevice &); + +inline bool operator==(const SymbianDevice &d1, const SymbianDevice &d2) + { return d1.compare(d2) == 0; } +inline bool operator!=(const SymbianDevice &d1, const SymbianDevice &d2) + { return d1.compare(d2) != 0; } +inline bool operator<(const SymbianDevice &d1, const SymbianDevice &d2) + { return d1.compare(d2) < 0; } + +/* SymbianDeviceManager: Singleton that maintains a list of Symbian devices. + * and emits change signals. + * On Windows, the update slot must be connected to a signal + * emitted from an event handler listening for WM_DEVICECHANGE. */ +class SymbianDeviceManager : public QObject { Q_OBJECT public: + typedef QList<SymbianDevice> SymbianDeviceList; + static const char *linuxBlueToothDeviceRootC; - explicit SerialDeviceLister(QObject *parent = 0); - ~SerialDeviceLister(); + // Do not use this constructor, it is just public for Q_GLOBAL_STATIC + explicit SymbianDeviceManager(QObject *parent = 0); + virtual ~SymbianDeviceManager(); + + // Singleton access. + static SymbianDeviceManager *instance(); - QList<CommunicationDevice> communicationDevices() const; + SymbianDeviceList devices() const; + QString toString() const; QString friendlyNameForPort(const QString &port) const; @@ -66,17 +113,20 @@ public slots: void update(); signals: + void deviceRemoved(const SymbianDevice &d); + void deviceAdded(const SymbianDevice &d); void updated(); private: - void updateSilently() const; - QList<CommunicationDevice> serialPorts() const; - QList<CommunicationDevice> blueToothDevices() const; + void update(bool emitSignals); + SymbianDeviceList serialPorts() const; + SymbianDeviceList blueToothDevices() const; - mutable bool m_initialized; - mutable QList<CommunicationDevice> m_devices2; + SymbianDeviceManagerPrivate *d; }; +QDebug operator<<(QDebug d, const SymbianDeviceManager &); + } // Internal } // Qt4ProjectManager