diff --git a/src/plugins/qt4projectmanager/qt-s60/qt-s60.pri b/src/plugins/qt4projectmanager/qt-s60/qt-s60.pri new file mode 100644 index 0000000000000000000000000000000000000000..2d2d68a3cc2cd9a0eeab5a05d74b55c9c8bc12f8 --- /dev/null +++ b/src/plugins/qt4projectmanager/qt-s60/qt-s60.pri @@ -0,0 +1,15 @@ +SUPPORT_QT_S60 = $$(QTCREATOR_WITH_S60) +!isEmpty(SUPPORT_QT_S60) { + message("Adding experimental support for Qt/S60 applications.") + DEFINES += QTCREATOR_WITH_S60 + + SOURCES += $$PWD/s60devices.cpp \ + $$PWD/s60devicespreferencepane.cpp \ + $$PWD/s60manager.cpp + + HEADERS += $$PWD/s60devices.h \ + $$PWD/s60devicespreferencepane.h \ + $$PWD/s60manager.h + + FORMS += $$PWD/s60devicespreferencepane.ui +} diff --git a/src/plugins/qt4projectmanager/qt-s60/s60devices.cpp b/src/plugins/qt4projectmanager/qt-s60/s60devices.cpp new file mode 100644 index 0000000000000000000000000000000000000000..fb785b1ea66440189800e665e3ea45b3b85c7bdb --- /dev/null +++ b/src/plugins/qt4projectmanager/qt-s60/s60devices.cpp @@ -0,0 +1,139 @@ +#include "s60devices.h" + +#include <QtCore/QSettings> +#include <QtCore/QXmlStreamReader> +#include <QtCore/QFile> +#include <QtCore/QDir> + +namespace { + const char * const SYMBIAN_SDKS_KEY = "HKEY_LOCAL_MACHINE\\Software\\Symbian\\EPOC SDKs"; + const char * const SYMBIAN_PATH_KEY = "CommonPath"; + const char * const SYMBIAN_DEVICES_FILE = "devices.xml"; + const char * const DEVICES_LIST = "devices"; + const char * const DEVICE = "device"; + const char * const DEVICE_ID = "id"; + const char * const DEVICE_NAME = "name"; + const char * const DEVICE_DEFAULT = "default"; + const char * const DEVICE_EPOCROOT = "epocroot"; + const char * const DEVICE_TOOLSROOT = "toolsroot"; +} + +using namespace Qt4ProjectManager::Internal; + +S60Devices::S60Devices(QObject *parent) + : QObject(parent) +{ +} + +bool S60Devices::read() +{ + m_devices.clear(); + m_errorString = QString(); + // 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(); + if (devicesXmlPath.isEmpty()) { + m_errorString = "Could not find installed SDKs in registry."; + return false; + } + + devicesXmlPath += QLatin1String("/") + QLatin1String(SYMBIAN_DEVICES_FILE); + QFile devicesFile(devicesXmlPath); + if (!devicesFile.open(QIODevice::ReadOnly)) { + m_errorString = QString("Could not read devices file at %1.").arg(devicesXmlPath); + return false; + } + QXmlStreamReader xml(&devicesFile); + while (!xml.atEnd()) { + xml.readNext(); + if (xml.isStartElement() && xml.name() == DEVICES_LIST) { + if (xml.attributes().value("version") == "1.0") { + // Look for correct device + while (!(xml.isEndElement() && xml.name() == DEVICES_LIST) && !xml.atEnd()) { + xml.readNext(); + if (xml.isStartElement() && xml.name() == DEVICE) { + Device device; + device.id = xml.attributes().value(DEVICE_ID).toString(); + device.name = xml.attributes().value(DEVICE_NAME).toString(); + if (xml.attributes().value(DEVICE_DEFAULT).toString() == "yes") + device.isDefault = true; + else + device.isDefault = false; + while (!(xml.isEndElement() && xml.name() == DEVICE) && !xml.atEnd()) { + xml.readNext(); + if (xml.isStartElement() && xml.name() == DEVICE_EPOCROOT) { + device.epocRoot = xml.readElementText(); + } else if (xml.isStartElement() && xml.name() == DEVICE_TOOLSROOT) { + device.toolsRoot = xml.readElementText(); + } + } + m_devices.append(device); + } + } + } else { + xml.raiseError("Invalid 'devices' element version."); + } + } + } + devicesFile.close(); + if (xml.hasError()) { + m_errorString = xml.errorString(); + return false; + } + + return true; +} + +bool S60Devices::detectQtForDevices() +{ + for (int i = 0; i < m_devices.size(); ++i) { + QFile qtDll(QString("%1/epoc32/release/winscw/udeb/QtCore.dll").arg(m_devices[i].epocRoot)); + if (!qtDll.exists() || !qtDll.open(QIODevice::ReadOnly)) { + m_devices[i].qt = QString(); + continue; + } + const QString indicator = "\\src\\corelib\\kernel\\qobject.h"; + int indicatorlength = indicator.length(); + QByteArray buffer; + QByteArray previousBuffer; + int index = -1; + while (!qtDll.atEnd()) { + buffer = qtDll.read(10000); + index = buffer.indexOf(indicator.toLatin1()); + if (index >= 0) + break; + if (!qtDll.atEnd()) + qtDll.seek(qtDll.pos()-indicatorlength); + previousBuffer = buffer; + } + int lastIndex = index; + while (index >= 0 && buffer.at(index)) --index; + if (index < 0) { // this is untested + } else { + index += 2; // the 0 and another byte for some reason + m_devices[i].qt = QDir::toNativeSeparators(buffer.mid(index, lastIndex-index)); + } + qtDll.close(); + } + return true; +} + +QString S60Devices::errorString() const +{ + return m_errorString; +} + +QList<S60Devices::Device> S60Devices::devices() const +{ + return m_devices; +} + +S60Devices::Device S60Devices::deviceForRoot(const QString &epocRoot) const +{ + foreach (const S60Devices::Device &i, m_devices) { + if (i.epocRoot == epocRoot) { + return i; + } + } + return Device(); +} diff --git a/src/plugins/qt4projectmanager/qt-s60/s60devices.h b/src/plugins/qt4projectmanager/qt-s60/s60devices.h new file mode 100644 index 0000000000000000000000000000000000000000..0d6644b00cd62d87b1ce54829877bacbf5aad506 --- /dev/null +++ b/src/plugins/qt4projectmanager/qt-s60/s60devices.h @@ -0,0 +1,38 @@ +#ifndef S60DEVICES_H +#define S60DEVICES_H + +#include <QtCore/QObject> +#include <QtCore/QString> +#include <QtCore/QList> + +namespace Qt4ProjectManager { +namespace Internal { + +class S60Devices : public QObject +{ + Q_OBJECT +public: + struct Device { + QString id; + QString name; + bool isDefault; + QString epocRoot; + QString toolsRoot; + QString qt; + }; + + S60Devices(QObject *parent = 0); + bool read(); + QString errorString() const; + QList<Device> devices() const; + bool detectQtForDevices(); + Device deviceForRoot(const QString &epocRoot) const; +private: + QString m_errorString; + QList<Device> m_devices; +}; + +} // namespace Internal +} // namespace Qt4ProjectManager + +#endif // S60DEVICES_H diff --git a/src/plugins/qt4projectmanager/qt-s60/s60devicespreferencepane.cpp b/src/plugins/qt4projectmanager/qt-s60/s60devicespreferencepane.cpp new file mode 100644 index 0000000000000000000000000000000000000000..94bd526e76e113e290be549506f3b2b739b4752d --- /dev/null +++ b/src/plugins/qt4projectmanager/qt-s60/s60devicespreferencepane.cpp @@ -0,0 +1,89 @@ +#include "s60devicespreferencepane.h" +#include "ui_s60devicespreferencepane.h" + +#include <qt4projectmanager/qt4projectmanagerconstants.h> + +#include <QtDebug> + +using namespace Qt4ProjectManager; +using namespace Qt4ProjectManager::Internal; + +S60DevicesWidget::S60DevicesWidget(QWidget *parent, S60Devices *devices) : + QWidget(parent), + m_ui(new Ui::S60DevicesPreferencePane), + m_devices(devices) +{ + m_ui->setupUi(this); + connect(m_ui->refreshButton, SIGNAL(clicked()), this, SLOT(updateDevices())); + updateDevicesList(); +} + +S60DevicesWidget::~S60DevicesWidget() +{ + delete m_ui; +} + +void S60DevicesWidget::updateDevices() +{ + m_devices->read(); + Q_ASSERT(m_devices->detectQtForDevices()); + updateDevicesList(); +} + +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))); + } +} + +S60DevicesPreferencePane::S60DevicesPreferencePane(S60Devices *devices, QObject *parent) + : Core::IOptionsPage(parent), + m_widget(0), + m_devices(devices) +{ + m_devices->read(); +} + +S60DevicesPreferencePane::~S60DevicesPreferencePane() +{ +} + +QString S60DevicesPreferencePane::id() const +{ + return QLatin1String("S60 SDKs"); +} + +QString S60DevicesPreferencePane::trName() const +{ + return tr("S60 SDKs"); +} + +QString S60DevicesPreferencePane::category() const +{ + return Constants::QT_CATEGORY; +} + +QString S60DevicesPreferencePane::trCategory() const +{ + return tr(Constants::QT_CATEGORY); +} + +QWidget *S60DevicesPreferencePane::createPage(QWidget *parent) +{ + if (m_widget) + delete m_widget; + m_widget = new S60DevicesWidget(parent, m_devices); + return m_widget; +} + +void S60DevicesPreferencePane::apply() +{ +} + +void S60DevicesPreferencePane::finish() +{ +} diff --git a/src/plugins/qt4projectmanager/qt-s60/s60devicespreferencepane.h b/src/plugins/qt4projectmanager/qt-s60/s60devicespreferencepane.h new file mode 100644 index 0000000000000000000000000000000000000000..37e4a5f444636620ec25f3ec863a83f5e74cb5e0 --- /dev/null +++ b/src/plugins/qt4projectmanager/qt-s60/s60devicespreferencepane.h @@ -0,0 +1,57 @@ +#ifndef S60DEVICESPREFERENCEPANE_H +#define S60DEVICESPREFERENCEPANE_H + +#include "s60devices.h" + +#include <coreplugin/dialogs/ioptionspage.h> + +#include <QtCore/QPointer> +#include <QtGui/QWidget> + +namespace Qt4ProjectManager { +namespace Internal { + +namespace Ui { + class S60DevicesPreferencePane; +} + +class S60DevicesWidget : public QWidget +{ + Q_OBJECT +public: + S60DevicesWidget(QWidget *parent, S60Devices *devices); + ~S60DevicesWidget(); + +private slots: + void updateDevices(); + +private: + void updateDevicesList(); + Ui::S60DevicesPreferencePane *m_ui; + S60Devices *m_devices; +}; + +class S60DevicesPreferencePane : public Core::IOptionsPage { + Q_OBJECT +public: + S60DevicesPreferencePane(S60Devices *devices, QObject *parent = 0); + ~S60DevicesPreferencePane(); + + QString id() const; + QString trName() const; + QString category() const; + QString trCategory() const; + + QWidget *createPage(QWidget *parent); + void apply(); + void finish(); + +private: + QPointer<S60DevicesWidget> m_widget; + S60Devices *m_devices; +}; + +} // namespace Internal +} // namespace Qt4ProjectManager + +#endif // S60DEVICESPREFERENCEPANE_H diff --git a/src/plugins/qt4projectmanager/qt-s60/s60devicespreferencepane.ui b/src/plugins/qt4projectmanager/qt-s60/s60devicespreferencepane.ui new file mode 100644 index 0000000000000000000000000000000000000000..f739161007a9eb764e703670f63b39053f911f44 --- /dev/null +++ b/src/plugins/qt4projectmanager/qt-s60/s60devicespreferencepane.ui @@ -0,0 +1,81 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>Qt4ProjectManager::Internal::S60DevicesPreferencePane</class> + <widget class="QWidget" name="Qt4ProjectManager::Internal::S60DevicesPreferencePane"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>400</width> + <height>300</height> + </rect> + </property> + <property name="windowTitle"> + <string>Form</string> + </property> + <layout class="QVBoxLayout" name="verticalLayout"> + <item> + <widget class="QLabel" name="label"> + <property name="text"> + <string>Installed S60 SDKs:</string> + </property> + </widget> + </item> + <item> + <widget class="QTreeWidget" name="list"> + <property name="indentation"> + <number>0</number> + </property> + <property name="rootIsDecorated"> + <bool>false</bool> + </property> + <property name="uniformRowHeights"> + <bool>true</bool> + </property> + <property name="columnCount"> + <number>2</number> + </property> + <attribute name="headerCascadingSectionResizes"> + <bool>true</bool> + </attribute> + <column> + <property name="text"> + <string>SDK Location</string> + </property> + </column> + <column> + <property name="text"> + <string>Qt Location</string> + </property> + </column> + </widget> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout"> + <item> + <spacer name="horizontalSpacer"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QPushButton" name="refreshButton"> + <property name="text"> + <string>Refresh</string> + </property> + </widget> + </item> + </layout> + </item> + </layout> + </widget> + <resources/> + <connections/> +</ui> diff --git a/src/plugins/qt4projectmanager/qt-s60/s60manager.cpp b/src/plugins/qt4projectmanager/qt-s60/s60manager.cpp new file mode 100644 index 0000000000000000000000000000000000000000..7ecf320fa2bd65dfb74e01f68681bc0c1cb5ee30 --- /dev/null +++ b/src/plugins/qt4projectmanager/qt-s60/s60manager.cpp @@ -0,0 +1,53 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Qt Software Information (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 qt-sales@nokia.com. +** +**************************************************************************/ + +#include "s60manager.h" + +#include "s60devices.h" +#include "s60devicespreferencepane.h" + +#include <extensionsystem/pluginmanager.h> + +using namespace Qt4ProjectManager::Internal; + +S60Manager::S60Manager(QObject *parent) + : QObject(parent), + m_devices(new S60Devices(this)), + m_devicesPreferencePane(new S60DevicesPreferencePane(m_devices, this)) +{ + m_devices->detectQtForDevices(); + ExtensionSystem::PluginManager::instance() + ->addObject(m_devicesPreferencePane); +} + +S60Manager::~S60Manager() +{ + ExtensionSystem::PluginManager::instance() + ->removeObject(m_devicesPreferencePane); +} diff --git a/src/plugins/qt4projectmanager/qt-s60/s60manager.h b/src/plugins/qt4projectmanager/qt-s60/s60manager.h new file mode 100644 index 0000000000000000000000000000000000000000..265d57f034e8b89554f55b9db8d0e31ca08a312f --- /dev/null +++ b/src/plugins/qt4projectmanager/qt-s60/s60manager.h @@ -0,0 +1,60 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Qt Software Information (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 qt-sales@nokia.com. +** +**************************************************************************/ + +#ifndef S60MANAGER_H +#define S60MANAGER_H + +#include <extensionsystem/iplugin.h> + +#include <QtCore/QObject> + +namespace Qt4ProjectManager { +namespace Internal { + +class S60Devices; +class S60DevicesPreferencePane; + +class S60Manager : public QObject +{ + Q_OBJECT +public: + S60Manager(QObject *parent = 0); + ~S60Manager(); + + S60Devices *devices() const { return m_devices; } + +private: + S60Devices *m_devices; + S60DevicesPreferencePane *m_devicesPreferencePane; +}; + +#endif // S60MANAGER_H + +} // namespace Internal +} // namespace Qt4ProjectManager diff --git a/src/plugins/qt4projectmanager/qt4projectmanager.pro b/src/plugins/qt4projectmanager/qt4projectmanager.pro index 8be3a9e61377ec85d35822e19139a0f3fd6999fe..3b2341749d71c5a3af60654bd2fd38e8feee4a07 100644 --- a/src/plugins/qt4projectmanager/qt4projectmanager.pro +++ b/src/plugins/qt4projectmanager/qt4projectmanager.pro @@ -3,7 +3,8 @@ TARGET = Qt4ProjectManager QT += network include(../../qtcreatorplugin.pri) include(qt4projectmanager_dependencies.pri) -HEADERS = qt4projectmanagerplugin.h \ + +HEADERS += qt4projectmanagerplugin.h \ qt4projectmanager.h \ qt4project.h \ qt4nodes.h \ @@ -39,7 +40,7 @@ HEADERS = qt4projectmanagerplugin.h \ qtoptionspage.h \ qtuicodemodelsupport.h \ externaleditors.h -SOURCES = qt4projectmanagerplugin.cpp \ +SOURCES += qt4projectmanagerplugin.cpp \ qt4projectmanager.cpp \ qt4project.cpp \ qt4nodes.cpp \ @@ -73,14 +74,17 @@ SOURCES = qt4projectmanagerplugin.cpp \ qtoptionspage.cpp \ qtuicodemodelsupport.cpp \ externaleditors.cpp -FORMS = makestep.ui \ +FORMS += makestep.ui \ qmakestep.ui \ qt4projectconfigwidget.ui \ embeddedpropertiespage.ui \ qtversionmanager.ui \ showbuildlog.ui -RESOURCES = qt4projectmanager.qrc \ +RESOURCES += qt4projectmanager.qrc \ wizards/wizards.qrc + include(../../shared/proparser/proparser.pri) +include(qt-s60/qt-s60.pri) + DEFINES += QT_NO_CAST_TO_ASCII OTHER_FILES += Qt4ProjectManager.pluginspec diff --git a/src/plugins/qt4projectmanager/qt4projectmanagerplugin.cpp b/src/plugins/qt4projectmanager/qt4projectmanagerplugin.cpp index 5e27b68fc8ef7777e71cff107aa9bdc9a64d4f0f..6dd5fbd90fcad8ac3008d933861947ed1b0775aa 100644 --- a/src/plugins/qt4projectmanager/qt4projectmanagerplugin.cpp +++ b/src/plugins/qt4projectmanager/qt4projectmanagerplugin.cpp @@ -44,6 +44,10 @@ #include "qtoptionspage.h" #include "externaleditors.h" +#ifdef QTCREATOR_WITH_S60 +#include "qt-s60/s60manager.h" +#endif + #include <coreplugin/icore.h> #include <extensionsystem/pluginmanager.h> #include <projectexplorer/buildmanager.h> @@ -138,6 +142,10 @@ bool Qt4ProjectManagerPlugin::initialize(const QStringList &arguments, QString * #endif addAutoReleasedObject(new LinguistExternalEditor); +#ifdef QTCREATOR_WITH_S60 + addAutoReleasedObject(new S60Manager); +#endif + // TODO reenable //m_embeddedPropertiesPage = new EmbeddedPropertiesPage; //addObject(m_embeddedPropertiesPage);