--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hbcore/effects/hbeffectxmlparser.cpp Mon Apr 19 14:02:13 2010 +0300
@@ -0,0 +1,409 @@
+/****************************************************************************
+**
+** 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 "hbeffectxmlparser_p.h"
+#include "hbeffectdef_p.h"
+#include <QString>
+#include <QStringList>
+#include <QXmlStreamAttribute>
+
+/*
+ \class HbEffectXmlParser
+
+ \brief The HbEffectXmlParser class is responsible of parsing
+ xml file containing event effect definitions.
+ The startwidth, startheight, endwidth and endheight correspond to startx, starty, endx and endy respectively.
+
+ \warning This class is a part of internal library implementation and may
+ be removed from the public API!
+
+ \internal
+*/
+
+/*
+ Constructor.
+*/
+HbEffectXmlParser::HbEffectXmlParser()
+ :mFxmlData(0)
+{
+}
+
+/*
+ Destructor.
+*/
+HbEffectXmlParser::~HbEffectXmlParser()
+{
+}
+
+/*
+ Parses fxml document from the specified io device.
+*/
+bool HbEffectXmlParser::read(QIODevice *device, HbEffectFxmlData *dst)
+{
+ setDevice(device);
+ mFxmlData = dst;
+
+ while (!atEnd()) {
+ readNext();
+ if (isStartElement()) {
+ if (name() == FXML_LAYERS) {
+ readVisuals();
+ } else {
+ qWarning("HbEffectXmlParser: Document element is invalid (not <layers>");
+ raiseError("HbEffectXmlParser::read The document is not an valid effect definitions document.");
+ }
+ }
+ }
+
+ if (error()) {
+ qWarning("HbEffectXmlParser: failed with %d (%s)", error(), qPrintable(errorString()));
+ }
+
+ return !error();
+}
+
+/*
+ Handles unknown elements.
+*/
+void HbEffectXmlParser::readUnknownElement()
+{
+ Q_ASSERT(isStartElement());
+
+ while (!atEnd()) {
+ readNext();
+
+ if (isEndElement()) {
+ break;
+ }
+
+ if (isStartElement()) {
+ readUnknownElement();
+ }
+ }
+}
+
+void HbEffectXmlParser::readBlendingElement()
+{
+ Q_ASSERT(isStartElement());
+
+ while (!atEnd()) {
+ readNext();
+
+ // If there is no value in the blending element, bail out.
+ if (isEndElement()) {
+ break;
+ }
+
+ if (isCharacters()) {
+ // Store current blending value
+ mCurrentBlending = text().toString().trimmed();
+ // Blending value was read, find end tag and return.
+ while (!atEnd()) {
+ readNext();
+
+ if (isEndElement()) {
+ break;
+ }
+ }
+ break;
+ }
+ }
+}
+
+// FXML support
+void HbEffectXmlParser::readVisuals()
+{
+ Q_ASSERT(isStartElement() && name() == FXML_LAYERS);
+
+ while (!atEnd()) {
+ readNext();
+
+ if (isEndElement()) {
+ if (name() == FXML_LAYERS)
+ break;
+ }
+
+ if (isStartElement()) {
+ if (name() == FXML_VISUAL) {
+ readVisualData();
+ }
+
+ else if (name() == FXML_LAYERGROUP) {
+ // Not needed
+ }
+ else if (name() == FXML_BLENDING) {
+ readBlendingElement();
+ }
+ else if (name() == FXML_COMMENT) {
+ // Comments are skipped
+ }
+ else if (name() == FXML_FILTER) {
+#ifdef HB_FILTER_EFFECTS
+ readFilterData();
+#endif
+ }
+
+ else {
+ readUnknownElement();
+ }
+ }
+ }
+}
+
+void HbEffectXmlParser::readVisualData()
+{
+ // Read all 'param' tags inside the 'visual' tags and append them in the fxml animation list
+
+ while (!atEnd()) {
+ readNext();
+
+ if (isEndElement() && name() == FXML_VISUAL) {
+ break;
+ }
+
+ if (isStartElement()) {
+ if (name() == FXML_PARAM) {
+ mFxmlData->appendParamData(readParamData());
+ }
+ else if (name() == FXML_FILTER) {
+#ifdef HB_FILTER_EFFECTS
+ readFilterData();
+#endif
+ }
+ else {
+ readUnknownElement();
+ }
+ }
+ }
+}
+/**
+* Reads all 'param' tags inside the 'filter' tag and creates a filter data structure,
+* which is then appended to the fxmlData.
+*/
+void HbEffectXmlParser::readFilterData()
+{
+#ifdef HB_FILTER_EFFECTS
+ // Create filter data structure
+ HbEffectFxmlFilterData filterData(mFxmlData->memoryType());
+
+ // Parse filter type
+ QXmlStreamAttributes attrs = attributes();
+
+ foreach (const QXmlStreamAttribute &attr, attrs) {
+ // "type" = ...
+ if (attr.name().toString() == FXML_PARAM_TYPE) {
+ filterData.setType(attr.value().toString());
+ break;
+ }
+ // Other attributes are skipped atm
+ }
+
+ while (!atEnd()) {
+ readNext();
+
+ if (isEndElement() && name() == FXML_FILTER) {
+ break;
+ }
+
+ if (isStartElement()) {
+ if (name() == FXML_PARAM) {
+ filterData.appendParamData(readParamData());
+ } else {
+ readUnknownElement();
+ }
+ }
+ }
+
+ // Add blending data in the filter data
+ filterData.setBlending(mCurrentBlending);
+
+ // Append filter data in the list
+ mFxmlData->appendFilterData(filterData);
+
+#endif
+}
+
+// This parses information inside one <param> field.
+// E.g. "scale_x", "scale_y", "scale_origin_x"
+//
+HbEffectFxmlParamData HbEffectXmlParser::readParamData()
+{
+ Q_ASSERT(isStartElement() && name() == FXML_PARAM);
+
+ HbEffectFxmlParamData param(mFxmlData->memoryType());
+ HbKeyFrame kf(mFxmlData->memoryType());
+
+ QXmlStreamAttributes attrs = attributes();
+
+ // Populate the PARAM attributes
+ foreach (const QXmlStreamAttribute &attr, attrs) {
+ // "name" = ...
+ if (attr.name().toString() == FXML_PARAM_NAME) {
+ param.setName(attr.value().toString());
+ }
+ // "type" = ...
+ else if (attr.name().toString() == FXML_PARAM_TYPE) {
+ // Nothing to do here atm...
+ }
+ // Insert other elements to param data, e.g. "ref" is stored here
+ else {
+ param.setAttribute(attr.name().toString(), attr.value().toString());
+ }
+ }
+
+ while (!atEnd()) {
+ readNext();
+
+ if (isEndElement() && name() == FXML_PARAM) {
+ break;
+ }
+
+ // Elements inside params
+ if (isStartElement()) {
+ // <duration> tag
+ if (name() == FXML_DURATION) {
+ param.setDuration(readElementText());
+ }
+ // <style> tag
+ else if (name() == FXML_STYLE) {
+ param.setAttribute(FXML_STYLE, readElementText());
+ }
+ // <marker> tag
+ else if (name() == FXML_MARKER) {
+ QXmlStreamAttributes attrs = attributes();
+
+ enum {
+ Undefined = 0,
+ Start,
+ End
+ } loopType = Undefined;
+
+ // Fetch "type" attribute from <marker> tag
+ foreach (const QXmlStreamAttribute &attr, attrs) {
+ if (attr.name().toString() == FXML_PARAM_TYPE) {
+ QString s = attr.value().toString();
+ if (s == FXML_LOOP_START) {
+ loopType = Start;
+ } else if (s == FXML_LOOP_END) {
+ loopType = End;
+ }
+ break;
+ }
+ }
+
+ if (loopType != Undefined) {
+ // Fetch "at" attribute from <marker> tag
+ foreach (const QXmlStreamAttribute &attr, attrs) {
+ if (attr.name().toString() == FXML_PARAM_AT) {
+ QString s = attr.value().toString();
+ bool ok = false;
+ float f = s.toFloat(&ok);
+ if (ok) {
+ if (loopType == Start) {
+ param.setLoopStart(f);
+ } else if (loopType == End) {
+ param.setLoopEnd(f);
+ }
+ }
+ }
+ break;
+ }
+ }
+
+ // Advance until end element
+ while (!atEnd()) {
+ if (readNext() == QXmlStreamReader::EndElement) {
+ break;
+ }
+ }
+ }
+
+ // <keyframe> tag
+ else if (name() == FXML_KEYFRAME) {
+ QXmlStreamAttributes attrs = attributes();
+
+ bool ok = false;
+
+ // Fetch "at" attribute from <keyframe> tag
+ foreach (const QXmlStreamAttribute &attr, attrs) {
+ if (attr.name().toString() == FXML_PARAM_AT) {
+ QString s = attr.value().toString();
+ kf.pos = s.toFloat(&ok);
+ break;
+ }
+ }
+
+ // Fetch value of the <keyframe> tag
+ QString s = readElementText();
+ if (ok) {
+ // Color value cannot be stored in float so store it as a string
+ if (param.name() == "color") {
+ kf.stringValue = s;
+ } else {
+ kf.val = s.toFloat(&ok);
+ }
+ }
+
+ // Append keyframe to the param data if values were ok.
+ // Verify also here that the position is between 0.0 and 1.0.
+ if (ok && kf.pos >= 0.0 && kf.pos <= 1.0) {
+ param.append(kf);
+ }
+ }
+ //<start> element
+ else if(name() == FXML_KEYWORD_START) {
+
+ QXmlStreamAttributes attrs = attributes();
+ foreach (const QXmlStreamAttribute &attr, attrs) {
+ if( attr.name() == FXML_PARAM_REF ) {
+ param.setStartRef(attr.value().toString());
+ }
+ }
+ param.setAttribute(FXML_KEYWORD_START, readElementText());
+ }
+ //<end> element
+ else if(name() == FXML_KEYWORD_END) {
+ QXmlStreamAttributes attrs = attributes();
+ foreach (const QXmlStreamAttribute &attr, attrs) {
+ if( attr.name() == FXML_PARAM_REF ) {
+ param.setEndRef(attr.value().toString());
+ }
+ }
+ param.setAttribute(FXML_KEYWORD_END, readElementText());
+ }
+ else {
+ readUnknownElement();
+ }
+ }
+ // Value of the param
+ else if (isCharacters()) {
+ param.setValue(text().toString().trimmed());
+ }
+ }
+
+ return param;
+}
+
+// End of File