--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hbcore/effects/hbeffectcontroller.cpp Mon Apr 19 14:02:13 2010 +0300
@@ -0,0 +1,283 @@
+/****************************************************************************
+**
+** Copyright (C) 2008-2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (developer.feedback@nokia.com)
+**
+** This file is part of the HbCore module of the UI Extensions for Mobile.
+**
+** 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.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at developer.feedback@nokia.com.
+**
+****************************************************************************/
+
+#include "hbeffectcontroller_p.h"
+#include "hbeffectfxmldata_p.h"
+#include "hbeffectxmlparser_p.h"
+#include "hbeffectdef_p.h"
+#include "hbeffecttheme_p.h"
+#include "hbinstance.h"
+#include "hbiconloader_p.h"
+#include "hbtheme.h"
+#include "hbtheme_p.h"
+#include "hbthemeclient_p.h"
+#include <QBuffer>
+#include <QDir>
+#include <QFile>
+#include <QDebug>
+
+/*
+ \class HbEffectController hbeffectcontroller.h
+ \brief HbEffectController is used to read and store effects data.
+*/
+
+/*
+ Constructs a HbEffectController.
+*/
+HbEffectController::HbEffectController()
+ : mParser(0),
+ mShared(false),
+ mSharingSet(false)
+{
+}
+
+/*
+ Destructor.
+*/
+HbEffectController::~HbEffectController()
+{
+ delete mParser;
+}
+
+HbEffectFxmlData HbEffectController::fetchFxmlData(
+ const QString &componentType,
+ QGraphicsItem *component,
+ const QString &effectEvent,
+ bool shared ) const
+{
+ Q_UNUSED(shared); // not yet needed since we have a list of added items in local process
+ int componentTypeMatchIndex = -1;
+
+ // Find the definition for the component
+ for (int i = 0; i < mEffectEntries.count(); ++i) {
+ const HbEffectInfo &info = mEffectEntries.at(i);
+ // If found a definition matching the graphics item, return that.
+ if (info.item() // not null
+ && info.item() == component // matches the component
+ && info.inUse() // the effect is in use (not removed)
+ && info.effectEvent() == effectEvent) // matches the event
+ {
+ // sharing support - if it's shared get the FxML data from server and return the object
+ // with parsed FxML data
+ if( info.shared() ) {
+ HbEffectFxmlData *dataFromSrv = HbThemeClient::global()->getSharedEffect(info.mDefFileFullPath);
+ if(dataFromSrv) {
+ return *dataFromSrv;
+ }
+ } else {
+ return info.effectData();
+ }
+ }
+ // If found a definition matching the component type, mark index
+ // The whole list is still scanned for a match for the graphics item. This is
+ // needed to be able to override components effects for one graphics item.
+ else if (!info.componentType().isEmpty() && info.componentType() == componentType &&
+ info.inUse() && info.effectEvent() == effectEvent) {
+ componentTypeMatchIndex = i;
+ }
+ }
+ if (componentTypeMatchIndex >= 0) {
+ const HbEffectInfo &info = mEffectEntries.at(componentTypeMatchIndex);
+ if ( info.shared() ) {
+ HbEffectFxmlData *dataFromSrv =
+ HbThemeClient::global()->getSharedEffect(info.mDefFileFullPath);
+ if(dataFromSrv) {
+ return *dataFromSrv;
+ }
+ } else {
+ return mEffectEntries.at(componentTypeMatchIndex).effectData();
+ }
+ }
+ return HbEffectFxmlData();
+}
+
+bool HbEffectController::addFXML(const QString &componentType, const QString &filePath, const QString &effectEvent,
+ bool shared)
+{
+ return addEffectDefinitionFile(componentType, 0, filePath, effectEvent, shared);
+}
+
+bool HbEffectController::addFXML(QGraphicsItem *item, const QString &filePath, const QString &effectEvent,
+ bool shared)
+{
+ return addEffectDefinitionFile(QString(), item, filePath, effectEvent, shared);
+}
+
+void HbEffectController::removeFXML(const QString &componentType, const QString &filePath, const QString &effectEvent)
+{
+ QString fullPath = expandFileName(filePath);
+ for (int i = mEffectEntries.count() - 1; i >= 0; i--) {
+ const HbEffectInfo &info = mEffectEntries[i];
+ if (info.componentType() == componentType &&
+ info.xmlFileFullPath() == fullPath &&
+ info.effectEvent() == effectEvent)
+ {
+ // Remove the definition for the given component type
+ mEffectEntries.removeAt(i);
+ }
+ }
+}
+
+void HbEffectController::removeFXML(QGraphicsItem *item, const QString &filePath, const QString &effectEvent)
+{
+ QString fullPath = expandFileName(filePath);
+ for (int i = mEffectEntries.count() - 1; i >= 0; i--) {
+ const HbEffectInfo &info = mEffectEntries[i];
+ if (info.item() == item &&
+ info.xmlFileFullPath() == fullPath &&
+ info.effectEvent() == effectEvent)
+ {
+ // Remove the definition for the given item
+ mEffectEntries.removeAt(i);
+ }
+ }
+}
+
+void HbEffectController::removeFXML(QGraphicsItem *item)
+{
+ for (int i = mEffectEntries.count() - 1; i >= 0; i--) {
+ const HbEffectInfo &info = mEffectEntries[i];
+ if (info.item() == item) {
+ // Remove the definition for the given item
+ mEffectEntries.removeAt(i);
+ }
+ }
+}
+
+QList<HbEffectInfo> HbEffectController::effectEntries() const
+{
+ return mEffectEntries;
+}
+void HbEffectController::setSharing(bool enabled)
+{
+ mShared = enabled;
+ mSharingSet = true;
+}
+
+void HbEffectController::unsetSharing()
+{
+ mSharingSet = false;
+}
+
+QString HbEffectController::expandFileName(const QString &fn, bool *fromTheme, bool *shared)
+{
+ // Sharing not supported if the file is in Qt resource.
+ if (fn.startsWith(":/") && shared && *shared) {
+ *shared = false;
+ return fn;
+ } else {
+ // Try the theme, will return the same name if not found in the theme.
+ bool temp;
+ return HbEffectTheme::global()->getEffectXml(fn, fromTheme ? *fromTheme : temp);
+ }
+}
+
+bool HbEffectController::addEffectDefinitionFile(
+ const QString &componentType, QGraphicsItem *item,
+ const QString &fileName, const QString &effectEvent, bool shared)
+{
+ if (mSharingSet) {
+ shared = mShared;
+ }
+ // If client is not connected due to any reason, any kind of sharing is not possible
+ if ( !HbThemeClient::global()->clientConnected() ) {
+ shared = mShared = mSharingSet = false;
+ }
+ bool fromTheme = false;
+ QString filePath = expandFileName(fileName, &fromTheme, &shared);
+
+ // Check if there's already a definition parsed for given componentType or item
+ int indexForSetInUseWhenFail = -1;
+ for (int i = 0, ie = mEffectEntries.count(); i != ie; ++i) {
+ // non-const reference needed here to modify the actual data item
+ HbEffectInfo &info = mEffectEntries[i];
+
+ if ((item && info.item() == item)
+ || (!componentType.isEmpty() && info.componentType() == componentType))
+ {
+ if (info.effectEvent() == effectEvent) {
+ if (info.xmlFileFullPath() == filePath) {
+ // parsed already, just set in use
+ info.mInUse = true;
+ return true;
+ } else {
+ // New definition replaces this one, so mark this 'not used'.
+ info.mInUse = false;
+ // We may need to set the in-use flag back to true if file
+ // access fails, so store the index.
+ indexForSetInUseWhenFail = i;
+ }
+ }
+ }
+ }
+
+ if ( shared ) {
+ if (!HbThemeClient::global()->addSharedEffect(filePath)) {
+ // Themeserver failed, try to parse locally.
+ shared = false;
+ }
+ }
+
+ if (!mParser && !shared) {
+ mParser = new HbEffectXmlParser;
+ }
+
+ HbEffectInfo effectEntry;
+ effectEntry.mComponentType = componentType;
+ effectEntry.mItem = item;
+ effectEntry.mInUse = true;
+ effectEntry.mFromTheme = fromTheme;
+ effectEntry.mDefFileFullPath = filePath;
+ effectEntry.mEffectEvent = effectEvent;
+ effectEntry.mShared = shared;
+
+ if (!shared) {
+ HbEffectFxmlData fxmlData;
+ QFile file(filePath);
+ if (!file.open(QFile::ReadOnly | QFile::Text)) {
+ qWarning("HbEffect: Opening of %s failed", qPrintable(filePath));
+ if (indexForSetInUseWhenFail >= 0) {
+ mEffectEntries[indexForSetInUseWhenFail].mInUse = true;
+ }
+ return false;
+ }
+ mParser->read(&file, &fxmlData);
+ file.close();
+
+ if (mParser->error() != QXmlStreamReader::NoError) {
+ qWarning() << "HbEffect: Parsing of file" << qPrintable(filePath) << "failed:"
+ << mParser->errorString();
+ if (indexForSetInUseWhenFail >= 0) {
+ mEffectEntries[indexForSetInUseWhenFail].mInUse = true;
+ }
+ return false;
+ }
+
+ effectEntry.setEffectData(fxmlData);
+ }
+
+ mEffectEntries.append(effectEntry);
+ return true;
+}