diff -r 000000000000 -r 16d8024aca5e src/hbcore/effects/hbeffectcontroller.cpp --- /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 +#include +#include +#include + +/* + \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 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; +}