From 036e2207000257d57b5b5c7e3fe585c3edcff28c Mon Sep 17 00:00:00 2001 From: con <qtc-committer@nokia.com> Date: Fri, 31 Jul 2009 16:49:26 +0200 Subject: [PATCH] Find out when devices get connected / disconnected. And adapt the device selection list. --- src/plugins/coreplugin/coreplugin.pro | 12 ++-- .../coreplugin/eventfilteringmainwindow.cpp | 53 ++++++++++++++++ .../coreplugin/eventfilteringmainwindow.h | 62 +++++++++++++++++++ src/plugins/coreplugin/mainwindow.cpp | 3 +- src/plugins/coreplugin/mainwindow.h | 5 +- .../qt4projectmanager/qt-s60/qt-s60-todo.txt | 5 +- .../qt4projectmanager/qt-s60/qt-s60.pri | 1 + .../qt-s60/s60devicerunconfiguration.cpp | 29 +++++---- .../qt-s60/s60devicerunconfiguration.h | 1 + .../qt4projectmanager/qt-s60/s60manager.cpp | 8 ++- .../qt4projectmanager/qt-s60/s60manager.h | 4 ++ .../qt-s60/serialdevicelister.cpp | 51 +++++++++++++-- .../qt-s60/serialdevicelister.h | 28 ++++++++- 13 files changed, 233 insertions(+), 29 deletions(-) create mode 100644 src/plugins/coreplugin/eventfilteringmainwindow.cpp create mode 100644 src/plugins/coreplugin/eventfilteringmainwindow.h diff --git a/src/plugins/coreplugin/coreplugin.pro b/src/plugins/coreplugin/coreplugin.pro index 8bdc845c48f..f92509e61dc 100644 --- a/src/plugins/coreplugin/coreplugin.pro +++ b/src/plugins/coreplugin/coreplugin.pro @@ -77,7 +77,8 @@ SOURCES += mainwindow.cpp \ editormanager/ieditor.cpp \ dialogs/ioptionspage.cpp \ dialogs/iwizard.cpp \ - settingsdatabase.cpp + settingsdatabase.cpp \ + eventfilteringmainwindow.cpp HEADERS += mainwindow.h \ editmode.h \ tabpositionindicator.h \ @@ -154,21 +155,20 @@ HEADERS += mainwindow.h \ sidebar.h \ fileiconprovider.h \ mimedatabase.h \ - settingsdatabase.h + settingsdatabase.h \ + eventfilteringmainwindow.h FORMS += dialogs/newdialog.ui \ dialogs/settingsdialog.ui \ dialogs/shortcutsettings.ui \ dialogs/saveitemsdialog.ui \ dialogs/openwithdialog.ui \ editormanager/openeditorsview.ui \ - generalsettings.ui + generalsettings.ui RESOURCES += core.qrc \ fancyactionbar.qrc - -unix:!macx { +unix:!macx { images.files = images/qtcreator_logo_*.png images.path = /share/pixmaps INSTALLS += images } - OTHER_FILES += Core.pluginspec diff --git a/src/plugins/coreplugin/eventfilteringmainwindow.cpp b/src/plugins/coreplugin/eventfilteringmainwindow.cpp new file mode 100644 index 00000000000..54a890deda6 --- /dev/null +++ b/src/plugins/coreplugin/eventfilteringmainwindow.cpp @@ -0,0 +1,53 @@ +/************************************************************************** +** +** 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://www.qtsoftware.com/contact. +** +**************************************************************************/ + +#include "eventfilteringmainwindow.h" + +#ifdef Q_OS_WIN +#include <windows.h> +#endif + +#include <QtDebug> + +using namespace Core::Internal; + +EventFilteringMainWindow::EventFilteringMainWindow() +{ +} + +#ifdef Q_OS_WIN +bool EventFilteringMainWindow::winEvent(MSG *msg, long *result) +{ + if (msg->message == WM_DEVICECHANGE) { + emit deviceChange(); + *result = TRUE; + } + return false; +} +#endif diff --git a/src/plugins/coreplugin/eventfilteringmainwindow.h b/src/plugins/coreplugin/eventfilteringmainwindow.h new file mode 100644 index 00000000000..fdaceb444b6 --- /dev/null +++ b/src/plugins/coreplugin/eventfilteringmainwindow.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://www.qtsoftware.com/contact. +** +**************************************************************************/ + +#ifndef EVENTFILTERINGMAINWINDOW_H +#define EVENTFILTERINGMAINWINDOW_H + +#include <QtGui/QMainWindow> + +namespace Core { +namespace Internal { + +/*! + * This class only exists because we can't include windows.h in mainwindow.cpp + * because windows defines an IContext... + */ + +class EventFilteringMainWindow : public QMainWindow +{ + Q_OBJECT +public: + EventFilteringMainWindow(); + +#ifdef Q_OS_WIN +protected: + bool winEvent(MSG *message, long *result); +#endif + +signals: + void deviceChange(); + +}; + +} // Internal +} // Core + +#endif // EVENTFILTERINGMAINWINDOW_H diff --git a/src/plugins/coreplugin/mainwindow.cpp b/src/plugins/coreplugin/mainwindow.cpp index 2d11cefe95d..dafa9e5a15a 100644 --- a/src/plugins/coreplugin/mainwindow.cpp +++ b/src/plugins/coreplugin/mainwindow.cpp @@ -106,7 +106,7 @@ static const char *uriListMimeFormatC = "text/uri-list"; enum { debugMainWindow = 0 }; MainWindow::MainWindow() : - QMainWindow(), + EventFilteringMainWindow(), m_coreImpl(new CoreImpl(this)), m_uniqueIDManager(new UniqueIDManager()), m_globalContext(QList<int>() << Constants::C_GLOBAL_ID), @@ -1254,3 +1254,4 @@ void MainWindow::setFullScreen(bool on) //statusBar()->show(); } } + diff --git a/src/plugins/coreplugin/mainwindow.h b/src/plugins/coreplugin/mainwindow.h index c0aa8494a70..8409f8bceb5 100644 --- a/src/plugins/coreplugin/mainwindow.h +++ b/src/plugins/coreplugin/mainwindow.h @@ -32,7 +32,8 @@ #include "core_global.h" -#include <QtGui/QMainWindow> +#include "eventfilteringmainwindow.h" + #include <QtCore/QMap> #include <QtCore/QList> #include <QtCore/QSet> @@ -79,7 +80,7 @@ class ShortcutSettings; class ViewManager; class VersionDialog; -class CORE_EXPORT MainWindow : public QMainWindow +class CORE_EXPORT MainWindow : public EventFilteringMainWindow { Q_OBJECT diff --git a/src/plugins/qt4projectmanager/qt-s60/qt-s60-todo.txt b/src/plugins/qt4projectmanager/qt-s60/qt-s60-todo.txt index 93836090436..5dc2e55543f 100644 --- a/src/plugins/qt4projectmanager/qt-s60/qt-s60-todo.txt +++ b/src/plugins/qt4projectmanager/qt-s60/qt-s60-todo.txt @@ -18,6 +18,8 @@ * should the default make target be defined by the project instead of tool chain, or perhaps by the QtVersion dependent on a tool chain? + * seems that the make for building for device doesn't return useful exit code, + so a run is started even if the build has errors * Run Configurations * handling of active run config getting disabled not optimal yet @@ -28,8 +30,7 @@ * Run on device * passphrase for signing * time stamp of copied sisx is ridiculous - * maybe don't copy the sisx all the time - * don't hardcode com port + * don't copy the sisx all the time * don't hardcode copy destination * Add compile output parser winscw at least diff --git a/src/plugins/qt4projectmanager/qt-s60/qt-s60.pri b/src/plugins/qt4projectmanager/qt-s60/qt-s60.pri index bfc53ae98e1..b367a21a9f7 100644 --- a/src/plugins/qt4projectmanager/qt-s60/qt-s60.pri +++ b/src/plugins/qt4projectmanager/qt-s60/qt-s60.pri @@ -22,4 +22,5 @@ SUPPORT_QT_S60 = $$(QTCREATOR_WITH_S60) OTHER_FILES += $$PWD/qt-s60-todo.txt include($$PWD/../../../../tests/manual/trk/trklauncher.pri) || error("could not include trklauncher.pri") + # LIBS += -lUser32 -lSetupApi } diff --git a/src/plugins/qt4projectmanager/qt-s60/s60devicerunconfiguration.cpp b/src/plugins/qt4projectmanager/qt-s60/s60devicerunconfiguration.cpp index 71ef6338383..2396789d824 100644 --- a/src/plugins/qt4projectmanager/qt-s60/s60devicerunconfiguration.cpp +++ b/src/plugins/qt4projectmanager/qt-s60/s60devicerunconfiguration.cpp @@ -265,18 +265,9 @@ S60DeviceRunConfigurationWidget::S60DeviceRunConfigurationWidget(S60DeviceRunCon m_sisxFileLabel = new QLabel(m_runConfiguration->basePackageFilePath() + ".sisx"); formLayout->addRow(tr("Install File:"), m_sisxFileLabel); - QString runConfigurationPortName = m_runConfiguration->serialPortName(); - QList<SerialDeviceLister::SerialDevice> serialDevices = SerialDeviceLister().serialDevices(); m_serialPorts = new QComboBox; - for (int i = 0; i < serialDevices.size(); ++i) { - const SerialDeviceLister::SerialDevice &device = serialDevices.at(i); - m_serialPorts->addItem(device.friendlyName, device.portName); - if (device.portName == runConfigurationPortName) - m_serialPorts->setCurrentIndex(i); - } - QString selectedPortName = m_serialPorts->itemData(m_serialPorts->currentIndex()).toString(); - if (m_serialPorts->count() > 0 && runConfigurationPortName != selectedPortName) - m_runConfiguration->setSerialPortName(selectedPortName); + updateSerialDevices(); + connect(S60Manager::instance()->serialDeviceLister(), SIGNAL(updated()), this, SLOT(updateSerialDevices())); connect(m_serialPorts, SIGNAL(activated(int)), this, SLOT(setSerialPort(int))); formLayout->addRow(tr("Device on Serial Port:"), m_serialPorts); @@ -331,6 +322,22 @@ S60DeviceRunConfigurationWidget::S60DeviceRunConfigurationWidget(S60DeviceRunCon connect(keyPath, SIGNAL(changed(QString)), this, SLOT(keyPathChanged(QString))); } +void S60DeviceRunConfigurationWidget::updateSerialDevices() +{ + m_serialPorts->clear(); + QString runConfigurationPortName = m_runConfiguration->serialPortName(); + QList<SerialDeviceLister::SerialDevice> serialDevices = S60Manager::instance()->serialDeviceLister()->serialDevices(); + for (int i = 0; i < serialDevices.size(); ++i) { + const SerialDeviceLister::SerialDevice &device = serialDevices.at(i); + m_serialPorts->addItem(device.friendlyName, device.portName); + if (device.portName == runConfigurationPortName) + m_serialPorts->setCurrentIndex(i); + } + QString selectedPortName = m_serialPorts->itemData(m_serialPorts->currentIndex()).toString(); + if (m_serialPorts->count() > 0 && runConfigurationPortName != selectedPortName) + m_runConfiguration->setSerialPortName(selectedPortName); +} + void S60DeviceRunConfigurationWidget::nameEdited(const QString &text) { m_runConfiguration->setName(text); diff --git a/src/plugins/qt4projectmanager/qt-s60/s60devicerunconfiguration.h b/src/plugins/qt4projectmanager/qt-s60/s60devicerunconfiguration.h index 3e4d7572a08..17ff66dbf21 100644 --- a/src/plugins/qt4projectmanager/qt-s60/s60devicerunconfiguration.h +++ b/src/plugins/qt4projectmanager/qt-s60/s60devicerunconfiguration.h @@ -101,6 +101,7 @@ public: private slots: void nameEdited(const QString &text); void updateTargetInformation(); + void updateSerialDevices(); void setSerialPort(int index); void selfSignToggled(bool toggle); void customSignatureToggled(bool toggle); diff --git a/src/plugins/qt4projectmanager/qt-s60/s60manager.cpp b/src/plugins/qt4projectmanager/qt-s60/s60manager.cpp index 2f5f3e3bec9..18cc1a4a0dc 100644 --- a/src/plugins/qt4projectmanager/qt-s60/s60manager.cpp +++ b/src/plugins/qt4projectmanager/qt-s60/s60manager.cpp @@ -36,8 +36,11 @@ #include "s60emulatorrunconfiguration.h" #include "s60Devicerunconfiguration.h" +#include <coreplugin/icore.h> #include <extensionsystem/pluginmanager.h> +#include <QtGui/QMainWindow> + using namespace Qt4ProjectManager::Internal; S60Manager *S60Manager::m_instance = 0; @@ -55,7 +58,8 @@ S60Manager::S60Manager(QObject *parent) m_s60EmulatorRunConfigurationFactory(new S60EmulatorRunConfigurationFactory(this)), m_s60EmulatorRunConfigurationRunner(new S60EmulatorRunConfigurationRunner(this)), m_s60DeviceRunConfigurationFactory(new S60DeviceRunConfigurationFactory(this)), - m_s60DeviceRunConfigurationRunner(new S60DeviceRunConfigurationRunner(this)) + m_s60DeviceRunConfigurationRunner(new S60DeviceRunConfigurationRunner(this)), + m_serialDeviceLister(new SerialDeviceLister(this)) { m_instance = this; m_devices->detectQtForDevices(); @@ -72,6 +76,8 @@ S60Manager::S60Manager(QObject *parent) updateQtVersions(); connect(m_devices, SIGNAL(qtVersionsChanged()), this, SLOT(updateQtVersions())); + connect(Core::ICore::instance()->mainWindow(), SIGNAL(deviceChange()), + m_serialDeviceLister, SLOT(update())); } S60Manager::~S60Manager() diff --git a/src/plugins/qt4projectmanager/qt-s60/s60manager.h b/src/plugins/qt4projectmanager/qt-s60/s60manager.h index 95925e8119a..23ce072c07d 100644 --- a/src/plugins/qt4projectmanager/qt-s60/s60manager.h +++ b/src/plugins/qt4projectmanager/qt-s60/s60manager.h @@ -31,6 +31,7 @@ #define S60MANAGER_H #include "qtversionmanager.h" +#include "serialdevicelister.h" #include <extensionsystem/iplugin.h> #include <projectexplorer/toolchain.h> @@ -61,6 +62,8 @@ public: S60Devices *devices() const { return m_devices; } QString deviceIdFromDetectionSource(const QString &autoDetectionSource) const; + SerialDeviceLister *serialDeviceLister() const { return m_serialDeviceLister; } + private slots: void updateQtVersions(); @@ -72,6 +75,7 @@ private: S60EmulatorRunConfigurationRunner *m_s60EmulatorRunConfigurationRunner; S60DeviceRunConfigurationFactory *m_s60DeviceRunConfigurationFactory; S60DeviceRunConfigurationRunner *m_s60DeviceRunConfigurationRunner; + SerialDeviceLister *m_serialDeviceLister; }; } // namespace Internal diff --git a/src/plugins/qt4projectmanager/qt-s60/serialdevicelister.cpp b/src/plugins/qt4projectmanager/qt-s60/serialdevicelister.cpp index 948b7241e09..7b7b0263ef5 100644 --- a/src/plugins/qt4projectmanager/qt-s60/serialdevicelister.cpp +++ b/src/plugins/qt4projectmanager/qt-s60/serialdevicelister.cpp @@ -31,6 +31,8 @@ #include <QtCore/QSettings> #include <QtCore/QStringList> +#include <QtGui/QApplication> +#include <QtGui/QWidget> #include <QtDebug> using namespace Qt4ProjectManager::Internal; @@ -40,13 +42,54 @@ namespace { const char * const USBSER = "Services/usbser/Enum"; } -SerialDeviceLister::SerialDeviceLister() +//#ifdef Q_OS_WIN +//GUID WceusbshGUID = { 0x25dbce51, 0x6c8f, 0x4a72, +// 0x8a,0x6d,0xb5,0x4c,0x2b,0x4f,0xc8,0x35 }; +//#endif + +SerialDeviceLister::SerialDeviceLister(QObject *parent) + : QObject(parent), + m_initialized(false) +// , m_devNotifyHandle(0) +{ +//#ifdef Q_OS_WIN +// // register for events +// DEV_BROADCAST_DEVICEINTERFACE NotificationFilter; +// ZeroMemory( &NotificationFilter, sizeof(NotificationFilter) ); +// NotificationFilter.dbcc_size = sizeof(DEV_BROADCAST_DEVICEINTERFACE); +// NotificationFilter.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE; +// NotificationFilter.dbcc_classguid = WceusbshGUID; +// m_devNotifyHandle = RegisterDeviceNotification(QApplication::topLevelWidgets().at(0)->winId(), &NotificationFilter, DEVICE_NOTIFY_WINDOW_HANDLE); +//#endif +} + +SerialDeviceLister::~SerialDeviceLister() { +//#ifdef Q_OS_WIN +// if (m_devNotifyHandle) +// UnregisterDeviceNotification(m_devNotifyHandle); +//#endif } QList<SerialDeviceLister::SerialDevice> SerialDeviceLister::serialDevices() const { - QList<SerialDeviceLister::SerialDevice> devices; + if (!m_initialized) { + updateSilently(); + m_initialized = true; + } + return m_devices; +} + +void SerialDeviceLister::update() +{ + updateSilently(); + emit updated(); +} + +void SerialDeviceLister::updateSilently() const +{ + m_devices.clear(); +#ifdef Q_OS_WIN32 QSettings registry(REGKEY_CURRENT_CONTROL_SET, QSettings::NativeFormat); int count = registry.value(QString::fromLatin1("%1/Count").arg(USBSER)).toInt(); for (int i = 0; i < count; ++i) { @@ -56,8 +99,8 @@ QList<SerialDeviceLister::SerialDevice> SerialDeviceLister::serialDevices() cons SerialDeviceLister::SerialDevice device; 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(); - devices.append(device); + m_devices.append(device); } } - return devices; +#endif } diff --git a/src/plugins/qt4projectmanager/qt-s60/serialdevicelister.h b/src/plugins/qt4projectmanager/qt-s60/serialdevicelister.h index c314dd19758..099023ed928 100644 --- a/src/plugins/qt4projectmanager/qt-s60/serialdevicelister.h +++ b/src/plugins/qt4projectmanager/qt-s60/serialdevicelister.h @@ -30,9 +30,15 @@ #ifndef SERIALDEVICELISTER_H #define SERIALDEVICELISTER_H +#include <QtCore/QAbstractEventDispatcher> +#include <QtCore/QList> #include <QtCore/QObject> #include <QtCore/QString> -#include <QtCore/QList> + +//#ifdef Q_OS_WIN32 +//#include <windows.h> +//#include <dbt.h> +//#endif namespace Qt4ProjectManager { namespace Internal { @@ -47,8 +53,26 @@ public: QString friendlyName; }; - SerialDeviceLister(); + SerialDeviceLister(QObject *parent = 0); + ~SerialDeviceLister(); QList<SerialDevice> serialDevices() const; + +public slots: + void update(); + +signals: + void updated(); + +private: + void updateSilently() const; + + mutable bool m_initialized; + mutable QList<SerialDevice> m_devices; + +//#ifdef Q_OS_WIN +//private: +// HDEVNOTIFY m_devNotifyHandle; +//#endif }; } // Internal -- GitLab