diff options
author | Alan Alpert <alan.alpert@nokia.com> | 2012-04-26 19:32:48 +1000 |
---|---|---|
committer | Qt by Nokia <qt-info@nokia.com> | 2012-06-19 06:39:41 +0200 |
commit | ffc209f6e365e7a32cb3c7b5d09f72c54f47d2a2 (patch) | |
tree | b57f9eac92bdf43bf3bba852bd0b52c495e495be /src/imports/serviceframework/qdeclarativeserviceold.cpp | |
parent | b04b5a3f5b7696c3d23cefaae23359fb9efcd315 (diff) |
Adds new asynchronous friendly types.
The old types will probably be deprecated at some point, but they're
still provided so that users have time to switch.
Change-Id: I0f3068e77d4252e777a2771950fc665f0d509bb7
Reviewed-by: Andrew Stanley-Jones <andrew.stanley-jones@nokia.com>
Diffstat (limited to 'src/imports/serviceframework/qdeclarativeserviceold.cpp')
-rw-r--r-- | src/imports/serviceframework/qdeclarativeserviceold.cpp | 636 |
1 files changed, 636 insertions, 0 deletions
diff --git a/src/imports/serviceframework/qdeclarativeserviceold.cpp b/src/imports/serviceframework/qdeclarativeserviceold.cpp new file mode 100644 index 00000000..d36477ea --- /dev/null +++ b/src/imports/serviceframework/qdeclarativeserviceold.cpp @@ -0,0 +1,636 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the QtSystems module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qdeclarativeserviceold_p.h" + +#include <QQmlEngine> +#include <QQmlInfo> + +QT_BEGIN_NAMESPACE + +/*! + \qmlclass Service QDeclarativeService + + \brief The Service element holds an instance of a service object. + \inherits QObject + + \ingroup qml-serviceframework + + The Service element is part of the Qt ServiceFramework API and + provides a client instance of the service object. This element is a simplified + reflection of the QServiceInterfaceDescriptor class that allows the specification of + the Service::interfaceName to locate the default service implemented at this interface. + + \sa ServiceList +*/ +QDeclarativeService::QDeclarativeService() + : m_serviceInstance(0), m_componentComplete(false) +{ + m_serviceManager = new QServiceManager(); +} + +QDeclarativeService::~QDeclarativeService() +{ + delete m_serviceInstance; +} + +/*! + \qmlproperty bool Service::valid read-only + + This property holds whether a default service was found at the + interface name and corresponds to QServiceInterfaceDescriptor::isValid(). +*/ +bool QDeclarativeService::isValid() const +{ + return m_descriptor.isValid(); +} + +void QDeclarativeService::setInterfaceDesc(const QServiceInterfaceDescriptor &desc) +{ + if (desc == m_descriptor) + return; + + m_descriptor = desc; + + if (m_serviceInstance) + delete m_serviceInstance; + setServiceObject(0); +} + +QServiceInterfaceDescriptor QDeclarativeService::interfaceDesc() const +{ + return m_descriptor; +} + +/*! + \qmlproperty QString Service::interfaceName + + This property holds the interface name of the service that + corresponds to QServiceInterfaceDescriptor::interfaceName(). +*/ +void QDeclarativeService::setInterfaceName(const QString &interface) +{ + m_interface = interface; + updateDescriptor(); +} + +QString QDeclarativeService::interfaceName() const +{ + if (isValid()) + return m_descriptor.interfaceName(); + else + return "No Interface"; +} + +/*! + \qmlproperty QString Service::serviceName + + This property holds the service name of the service that + corresponds to QServiceInterfaceDescriptor::serviceName(). +*/ +QString QDeclarativeService::serviceName() const +{ + if (isValid()) + return m_descriptor.serviceName(); + else + return "No Service"; +} + +void QDeclarativeService::setServiceName(const QString &service) +{ + m_service = service; +} + +/*! + \qmlproperty int Service::majorVersion + + This property holds the major version number of the service that + corresponds to QServiceInterfaceDescriptor::majorVersion(). +*/ +int QDeclarativeService::majorVersion() const +{ + if (isValid()) + return m_descriptor.majorVersion(); + else + return 0; +} + +void QDeclarativeService::setMajorVersion(int version) +{ + m_major = version; + updateDescriptor(); +} + +/*! + \qmlproperty int Service::minorVersion + + This property holds the minor version number of the service that + corresponds to QServiceInterfaceDescriptor::minorVersion(). +*/ +int QDeclarativeService::minorVersion() const +{ + if (isValid()) + return m_descriptor.minorVersion(); + else + return 0; +} + +void QDeclarativeService::setMinorVersion(int version) +{ + m_minor = version; + updateDescriptor(); +} + +/*! + \qmlproperty QObject* Service::serviceObject + + This property holds an instance of the service object which + can be used to make metaobject calls to the service. This + corresponds to QServiceManager::loadInterface(). +*/ +QObject* QDeclarativeService::serviceObject() +{ + if (m_serviceInstance) { + return m_serviceInstance; + } + + if (isValid()) { + QObject *object = m_serviceManager->loadInterface(m_descriptor); + setServiceObject(object); + if (!m_serviceInstance) { + emit error(QLatin1String("Failed to create object")); + return m_serviceInstance; + } + emit serviceObjectChanged(); + connect(m_serviceInstance, SIGNAL(errorUnrecoverableIPCFault(QService::UnrecoverableIPCError)), + this, SLOT(IPCFault(QService::UnrecoverableIPCError))); + m_error.clear(); + return m_serviceInstance; + } else { + return 0; + } +} + +/*! + \qmlproperty QString Service::error + + This property holds the last error the was received, if any + + */ + +QString QDeclarativeService::lastError() const +{ + return m_error; +} + +void QDeclarativeService::IPCFault(QService::UnrecoverableIPCError errorValue) +{ + switch (errorValue) { + default: + case QService::ErrorUnknown: + m_error = QLatin1String("IPC Error: Unkown Error"); + break; + case QService::ErrorServiceNoLongerAvailable: + m_error = QLatin1String("IPC Error: Service no longer available"); + break; + case QService::ErrorOutofMemory: + m_error = QLatin1String("IPC Error: Out of memory"); + break; + case QService::ErrorPermissionDenied: + m_error = QLatin1String("IPC Error: Permission Denied"); + break; + case QService::ErrorInvalidArguments: + m_error = QLatin1String("IPC Error: Invalid Arguments"); + break; + } + emit error(m_error); + m_serviceInstance->deleteLater(); + setServiceObject(0); +} + +void QDeclarativeService::updateDescriptor() +{ + if (!m_componentComplete) + return; + + if (m_interface.isEmpty()) + return; + + QServiceInterfaceDescriptor new_desc; + + if (m_minor == 0 && m_major == 0 && m_service.isEmpty()){ + new_desc = m_serviceManager->interfaceDefault(m_interface); + } + else { + QServiceFilter filter; + if (!m_service.isEmpty()) + filter.setServiceName(m_service); + + + if (m_minor != 0 || m_major != 0) { + const QString version = QString::number(m_major) + "." + QString::number(m_minor); + filter.setInterface(m_interface, version); + } + + QList<QServiceInterfaceDescriptor> list = m_serviceManager->findInterfaces(filter); + if (!list.isEmpty()) + new_desc = list.takeFirst(); + } + + if (new_desc != m_descriptor) { + m_descriptor = new_desc; + if (m_serviceInstance) + emit serviceObjectChanged(); + } + + if (!isValid()) { + qWarning() << "WARNING: No service found for interface name: " << m_interface << m_service << m_major << m_minor; + } +} + +void QDeclarativeService::setServiceObject(QObject *object) +{ + if (m_serviceInstance != object) { + m_serviceInstance = object; + emit serviceObjectChanged(); + } +} + +void QDeclarativeService::classBegin() +{ + +} + +void QDeclarativeService::componentComplete() +{ + m_componentComplete = true; + updateDescriptor(); +} + +bool QDeclarativeService::operator ==(const QServiceInterfaceDescriptor& other ) const +{ + if ( m_descriptor == other) + return true; + + return false; +} + +/*! + \qmlclass ServiceList QDeclarativeServiceList + + \brief The ServiceList element holds a list of \l Service elements. + \inherits QObject + + \ingroup qml-serviceframework + + The ServiceList element is part of the Qt ServiceFramework API and + provides a list of \l Service elements at the interface ServiceList::interfaceName with + minimum version match ServiceList::minVersion properties. This list can be used to + select the desired service and instantiate a service object for access via the QMetaObject. + + This element is a simplified reflection of the QServiceFilter class that provides a list + of simplified QServiceInterfaceDescriptors. Similarly, if the ServiceList::serviceName + and ServiceList::versionMatch are not provided they will respectively default to an empty + string with a minimum verison match. + + \sa Service +*/ +QDeclarativeServiceList::QDeclarativeServiceList() + : m_service(QString()), + m_interface(), + m_major(1), + m_minor(1), + m_match(QDeclarativeServiceList::Minimum), + m_componentComplete(false) +{ + serviceManager = new QServiceManager(this); +} + +QDeclarativeServiceList::~QDeclarativeServiceList() +{ + while (m_services.count()) + delete m_services.takeFirst(); +} +/*! + \qmlproperty QString ServiceList::serviceName + + This property holds the interface name of the services that + corresponds to setting QServiceFilter::setService(). +*/ +void QDeclarativeServiceList::setServiceName(const QString &service) +{ + m_service = service; + updateFilterResults(); + if (m_componentComplete) + emit serviceNameChanged(); +} + +QString QDeclarativeServiceList::serviceName() const +{ + return m_service; +} + +/*! + \qmlproperty QString ServiceList::interfaceName + + This property holds the interface name of the services that + corresponds to setting QServiceFilter::setInterface(). +*/ +void QDeclarativeServiceList::setInterfaceName(const QString &interface) +{ + m_interface = interface; + updateFilterResults(); + if (m_componentComplete) + emit interfaceNameChanged(); +} + +QString QDeclarativeServiceList::interfaceName() const +{ + return m_interface; +} + +/*! + \qmlproperty int ServiceList::majorVersion + + This property holds the major version number of the service filter that + corresponds to QServiceFilter::majorVersion(). +*/ +void QDeclarativeServiceList::setMajorVersion(int major) +{ + m_major = major; + updateFilterResults(); + if (m_componentComplete) + emit majorVersionChanged(); +} + +int QDeclarativeServiceList::majorVersion() const +{ + return m_major; +} + +/*! + \qmlproperty int ServiceList::minorVersion + + This property holds the minor version number of the service filter that + corresponds to QServiceFilter::minorVersion(). +*/ +void QDeclarativeServiceList::setMinorVersion(int minor) +{ + m_minor = minor; + updateFilterResults(); + if (m_componentComplete) + emit minorVersionChanged(); +} + +int QDeclarativeServiceList::minorVersion() const +{ + return m_minor; +} + +/*! + \qmlproperty int ServiceList::monitorServiceRegistrations + + This property controls the behaviour of the list when new services are + registered or deregistered. Setting this property to true means the list + will be automatically updated when a service is added or removed. Caution, + your service object will be deleted if the service is unregistered, even if + the service is still running. +*/ + +void QDeclarativeServiceList::setMonitorServiceRegistrations(bool updates) +{ + if (updates == false) { + disconnect(this, SLOT(servicesAddedRemoved())); + } + else { + connect(serviceManager, SIGNAL(serviceAdded(QString,QService::Scope)), + this, SLOT(servicesAddedRemoved())); + connect(serviceManager, SIGNAL(serviceRemoved(QString,QService::Scope)), + this, SLOT(servicesAddedRemoved())); + } + + if (m_dynamicUpdates != updates) + emit monitorServiceRegistrationsChanged(); + + m_dynamicUpdates = updates; +} + +void QDeclarativeServiceList::servicesAddedRemoved() +{ + // invoke in another event loop run + QMetaObject::invokeMethod(this, "updateServiceList", Qt::QueuedConnection); +} + +bool QDeclarativeServiceList::monitorServiceRegistrations() const +{ + return m_dynamicUpdates; +} + +/*! + \qmlproperty enumeration ServiceList::versionMatch + + This property holds the version match rule of the service filter that + corresponds to QServiceFilter::versionMatchRule(). Within QML the values + ServiceList.Exact and ServiceList.Minimum correspond to + QServiceFilter::ExactVersionMatch and QServiceFilter::MinimumVersionMatch + respectively. +*/ +void QDeclarativeServiceList::setVersionMatch(MatchRule match) +{ + m_match = match; + updateFilterResults(); + if (m_componentComplete) + emit versionMatchChanged(); +} + +QDeclarativeServiceList::MatchRule QDeclarativeServiceList::versionMatch() const +{ + return m_match; +} + + +void QDeclarativeServiceList::updateServiceList() +{ + if (!m_componentComplete) + return; + + const QString version = QString::number(m_major) + "." + QString::number(m_minor); + + QServiceFilter filter; + + if (!m_service.isEmpty()) + filter.setServiceName(m_service); + + if (m_match == QDeclarativeServiceList::Exact) + filter.setInterface(m_interface, version, QServiceFilter::ExactVersionMatch); + else if (!m_interface.isEmpty()) + filter.setInterface(m_interface, version); + + const QList<QServiceInterfaceDescriptor> newlist = serviceManager->findInterfaces(filter); + + QSet<QServiceInterfaceDescriptor> currentServices = QSet<QServiceInterfaceDescriptor>::fromList(m_currentList); + QSet<QServiceInterfaceDescriptor> newServices = QSet<QServiceInterfaceDescriptor>::fromList(newlist); + + if (currentServices == newServices) { + return; + } + + const QSet<QServiceInterfaceDescriptor> addServices = newServices.subtract(currentServices); + const QSet<QServiceInterfaceDescriptor> delServices = currentServices.subtract( + QSet<QServiceInterfaceDescriptor>::fromList(newlist)); + + foreach (const QServiceInterfaceDescriptor &desc, delServices) { + foreach (QDeclarativeService *service, m_services) { + if (*service == desc) { + m_services.removeOne(service); + delete service; + } + } + m_currentList.removeOne(desc); + } + + foreach (const QServiceInterfaceDescriptor &desc, addServices) { + QDeclarativeService *service = new QDeclarativeService(); + service->setInterfaceDesc(desc); + m_services.append(service); + m_currentList.append(desc); + } + + emit resultsChanged(); +} + +void QDeclarativeServiceList::updateFilterResults() +{ + if (!m_componentComplete) + return; + + const QString version = QString::number(m_major) + "." + QString::number(m_minor); + + QServiceFilter filter; + + if (!m_service.isEmpty()) + filter.setServiceName(m_service); + + if (m_match == QDeclarativeServiceList::Exact) + filter.setInterface(m_interface, version, QServiceFilter::ExactVersionMatch); + else if (!m_interface.isEmpty()) + filter.setInterface(m_interface, version); + + QList<QServiceInterfaceDescriptor> list = serviceManager->findInterfaces(filter); + + if (list == m_currentList) { + return; + } + + m_currentList = list; + + while (m_services.count()) //for now we refresh the entire list + delete m_services.takeFirst(); + + for (int i = 0; i < list.size(); i++) { + QDeclarativeService *service = new QDeclarativeService(); + service->setInterfaceDesc(list.at(i)); + m_services.append(service); + } + + emit resultsChanged(); +} + +/*! + \qmlproperty QQmlListProperty ServiceList::services + + This property holds the list of \l Service elements that match + the Service::interfaceName and minimum Service::versionNumber properties. +*/ +QQmlListProperty<QDeclarativeService> QDeclarativeServiceList::services() +{ + return QQmlListProperty<QDeclarativeService>(this, + 0, + s_append, + s_count, + s_at, + s_clear); +} + +void QDeclarativeServiceList::classBegin() +{ +} + +void QDeclarativeServiceList::componentComplete() +{ + if (!m_componentComplete) { + m_componentComplete = true; + updateFilterResults(); + } +} + +void QDeclarativeServiceList::listUpdated() +{ + if (m_componentComplete) + emit resultsChanged(); +} + +void QDeclarativeServiceList::s_append(QQmlListProperty<QDeclarativeService> *prop, QDeclarativeService *service) +{ + QDeclarativeServiceList* list = static_cast<QDeclarativeServiceList*>(prop->object); + list->m_services.append(service); + list->listUpdated(); +} +int QDeclarativeServiceList::s_count(QQmlListProperty<QDeclarativeService> *prop) +{ + return static_cast<QDeclarativeServiceList*>(prop->object)->m_services.count(); +} + +QDeclarativeService* QDeclarativeServiceList::s_at(QQmlListProperty<QDeclarativeService> *prop, int index) +{ + return static_cast<QDeclarativeServiceList*>(prop->object)->m_services[index]; +} + +void QDeclarativeServiceList::s_clear(QQmlListProperty<QDeclarativeService> *prop) +{ + QDeclarativeServiceList* list = static_cast<QDeclarativeServiceList*>(prop->object); + qDeleteAll(list->m_services); + list->m_services.clear(); + list->listUpdated(); +} +#include "moc_qdeclarativeserviceold_p.cpp" + +QT_END_NAMESPACE |