--- a/homescreenapp/hsdomainmodel/src/hswidgetcomponentregistry.cpp Mon May 03 12:24:59 2010 +0300
+++ b/homescreenapp/hsdomainmodel/src/hswidgetcomponentregistry.cpp Fri May 14 15:43:04 2010 +0300
@@ -17,22 +17,45 @@
#include "hswidgetcomponentregistry.h"
#include "hswidgetcomponent.h"
+#include "hsdomainmodeldatastructures.h"
+#include "hswidgetcomponentdescriptor.h"
+#include "hsapp_defs.h"
+#include "caservice.h"
+#include "caquery.h"
+#include "caentry.h"
+#include "cadefs.h"
+#include "canotifier.h"
+#include "hsscene.h"
+
#include <QSignalMapper>
-QScopedPointer<HsWidgetComponentRegistry> HsWidgetComponentRegistry::mInstance(0);
+#include <QDir>
+#include <QCoreApplication>
+
+#include <HbMainWindow>
/*!
+ \class HsWidgetComponentRegistry
+ \ingroup group_hsdomainmodel
+ \brief Homescreen widget component registry.
+*/
+HsWidgetComponentRegistry *HsWidgetComponentRegistry::mInstance = 0;
+
+
+/*!
+ Singleton.
*/
HsWidgetComponentRegistry* HsWidgetComponentRegistry::instance()
{
if (!mInstance) {
- mInstance.reset(new HsWidgetComponentRegistry);
+ mInstance = new HsWidgetComponentRegistry;
+ mInstance->setParent(HsScene::mainWindow());
}
- return mInstance.data();
+ return mInstance;
}
/*!
-
+ Destructor
*/
HsWidgetComponentRegistry::~HsWidgetComponentRegistry()
{
@@ -40,7 +63,7 @@
}
/*!
-
+ Returns component object of the given \a uri.
*/
HsWidgetComponent *HsWidgetComponentRegistry::component(const QString &uri)
{
@@ -50,27 +73,134 @@
QScopedPointer<HsWidgetComponent> c(new HsWidgetComponent(uri));
mRegistry.insert(uri, c.data());
- connect(c.data(), SIGNAL(aboutToUninstall()), mSignalMapper.data(),
- SLOT(map()));
- mSignalMapper->setMapping(c.data(),uri);
- return c.take();
+ return c.take();
+}
+
+/*!
+ Requests widget component to emit 'aboutToInstall' signal to free widget resources when uninstalling the widget.
+*/
+void HsWidgetComponentRegistry::uninstallComponent(const HsWidgetComponentDescriptor &componentDescriptor)
+{
+ HsWidgetComponent *component = mRegistry.value(componentDescriptor.uri);
+ if (component) {
+ component->emitAboutToUninstall();
+ }
+
+}
+
+/*!
+ Constructor
+*/
+HsWidgetComponentRegistry::HsWidgetComponentRegistry(QObject *parent)
+ : QObject(parent)
+{
+ qRegisterMetaType<HsWidgetComponentDescriptor>("HsWidgetComponentDescriptor");
+
+ CaQuery query;
+ query.setEntryTypeNames(QStringList(widgetTypeName()));
+ CaNotifierFilter filter(query);
+ CaNotifier *notifier = CaService::instance()->createNotifier(filter);
+ notifier->setParent(this);
+ connect(notifier,
+ SIGNAL(entryChanged(CaEntry,ChangeType)),
+ SLOT(onEntryChanged(CaEntry,ChangeType)),Qt::QueuedConnection);
+}
+
+/*!
+ Called when entry is added to content service.
+*/
+void HsWidgetComponentRegistry::handleEntryAdded(const CaEntry &entry, const QString &uri)
+{
+ /* Unfortunately we don't know why the entry was added. It might be because widget
+ * was missing and is available again (media attached) or it's installed on device
+ */
+ registerService(entry,uri);
+ HsWidgetComponent *component = mRegistry.value(uri);
+ if (component) {
+ component->emitAvailable();
+ }
+
}
/*!
-
+ Called when entry is removed from content service.
*/
-HsWidgetComponentRegistry::HsWidgetComponentRegistry(QObject *parent)
- : QObject(parent),mSignalMapper(new QSignalMapper())
+void HsWidgetComponentRegistry::handleEntryRemoved(const CaEntry &entry, const QString &uri)
{
- connect(mSignalMapper.data(),SIGNAL(mapped(QString)),SLOT(onAboutToUninstall(QString)));
+ HsWidgetComponent *component = mRegistry.value(uri);
+
+ if (entry.flags() & MissingEntryFlag) {
+ if (component) {
+ component->emitUnavailable();
+ }
+ } else {
+ // uninstalled
+ QString rootPath = entry.attribute(widgetPathAttributeName());
+ mServiceManager.removeService(uri);
+ QCoreApplication::removeLibraryPath(rootPath);
+ if (component) {
+ // for now support versions without uinstaller
+ component->emitAboutToUninstall();
+ component->emitUninstalled();
+ mRegistry.take(uri)->deleteLater();
+ }
+ }
+}
+
+/*!
+ Called when entry is updated in content service.
+*/
+void HsWidgetComponentRegistry::handleEntryUpdated(const CaEntry &entry, const QString &uri)
+{
+ /* Unfortunately we don't know why the entry was updated. It might be update of a widget
+ * component thus we need to register it into service fw
+ */
+
+ registerService(entry,uri,true);
+ HsWidgetComponent *component = mRegistry.value(uri);
+ if (component) {
+ component->emitUpdated();
+ }
}
/*!
-
+ Registers widget to qt service framework and adds widget path to application's library path.
*/
-void HsWidgetComponentRegistry::onAboutToUninstall(const QString &uri)
+void HsWidgetComponentRegistry::registerService(const CaEntry &entry, const QString& uri, bool reset)
{
- if (mRegistry.contains(uri)) {
- mRegistry.take(uri)->deleteLater();
+ QString path = entry.attribute(widgetPathAttributeName());
+ QString serviceXml = entry.attribute("widget:servicexml");
+ if (!path.isEmpty() && !serviceXml.isEmpty()) {
+ QString service = QDir::toNativeSeparators(path + "/" + serviceXml);
+ // if it already exists, it's not added
+ if (reset) {
+ mServiceManager.removeService(uri);
+ }
+ QCoreApplication::addLibraryPath(path);
+ mServiceManager.addService(service);
+ }
+}
+
+/*!
+ Slot to handle entry changes in content service.
+*/
+void HsWidgetComponentRegistry::onEntryChanged(const CaEntry &entry, ChangeType changeType)
+{
+ QString uri = entry.attribute(widgetUriAttributeName());
+ switch (changeType) {
+ case AddChangeType:
+ handleEntryAdded(entry,uri);
+ break;
+
+ case RemoveChangeType:
+ handleEntryRemoved(entry,uri);
+ break;
+
+ case UpdateChangeType:
+ handleEntryUpdated(entry,uri);
+ break;
+
+ default: break;
}
}
+