src/hbcore/effects/hbeffectxmlparser.cpp
changeset 0 16d8024aca5e
child 5 627c4a0fd0e7
equal deleted inserted replaced
-1:000000000000 0:16d8024aca5e
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2008-2010 Nokia Corporation and/or its subsidiary(-ies).
       
     4 ** All rights reserved.
       
     5 ** Contact: Nokia Corporation (developer.feedback@nokia.com)
       
     6 **
       
     7 ** This file is part of the HbCore module of the UI Extensions for Mobile.
       
     8 **
       
     9 ** GNU Lesser General Public License Usage
       
    10 ** This file may be used under the terms of the GNU Lesser General Public
       
    11 ** License version 2.1 as published by the Free Software Foundation and
       
    12 ** appearing in the file LICENSE.LGPL included in the packaging of this file.
       
    13 ** Please review the following information to ensure the GNU Lesser General
       
    14 ** Public License version 2.1 requirements will be met:
       
    15 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
       
    16 **
       
    17 ** In addition, as a special exception, Nokia gives you certain additional
       
    18 ** rights.  These rights are described in the Nokia Qt LGPL Exception
       
    19 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
       
    20 **
       
    21 ** If you have questions regarding the use of this file, please contact
       
    22 ** Nokia at developer.feedback@nokia.com.
       
    23 **
       
    24 ****************************************************************************/
       
    25 
       
    26 #include "hbeffectxmlparser_p.h"
       
    27 #include "hbeffectdef_p.h"
       
    28 #include <QString>
       
    29 #include <QStringList>
       
    30 #include <QXmlStreamAttribute>
       
    31 
       
    32 /*
       
    33   \class HbEffectXmlParser
       
    34 
       
    35   \brief The HbEffectXmlParser class is responsible of parsing
       
    36   xml file containing event effect definitions.
       
    37   The startwidth, startheight, endwidth and endheight correspond to startx, starty, endx and endy respectively.
       
    38 
       
    39   \warning This class is a part of internal library implementation and may
       
    40   be removed from the public API!
       
    41 
       
    42   \internal
       
    43 */
       
    44 
       
    45 /*
       
    46   Constructor.
       
    47 */
       
    48 HbEffectXmlParser::HbEffectXmlParser()
       
    49     :mFxmlData(0)
       
    50 {
       
    51 }
       
    52 
       
    53 /*
       
    54   Destructor.
       
    55 */
       
    56 HbEffectXmlParser::~HbEffectXmlParser()
       
    57 {
       
    58 }
       
    59 
       
    60 /*
       
    61   Parses fxml document from the specified io device.
       
    62 */
       
    63 bool HbEffectXmlParser::read(QIODevice *device, HbEffectFxmlData *dst)
       
    64 {
       
    65     setDevice(device);
       
    66     mFxmlData = dst;
       
    67 
       
    68     while (!atEnd()) {
       
    69         readNext();
       
    70         if (isStartElement()) {
       
    71             if (name() == FXML_LAYERS) {
       
    72                 readVisuals();
       
    73             } else {
       
    74                 qWarning("HbEffectXmlParser: Document element is invalid (not <layers>");
       
    75                 raiseError("HbEffectXmlParser::read The document is not an valid effect definitions document.");
       
    76             }
       
    77         }        
       
    78     }
       
    79 
       
    80     if (error()) {
       
    81         qWarning("HbEffectXmlParser: failed with %d (%s)", error(), qPrintable(errorString()));
       
    82     }
       
    83 
       
    84     return !error();
       
    85 }
       
    86 
       
    87 /*
       
    88   Handles unknown elements.
       
    89 */
       
    90 void HbEffectXmlParser::readUnknownElement()
       
    91 {
       
    92     Q_ASSERT(isStartElement());
       
    93 
       
    94     while (!atEnd()) {
       
    95         readNext();
       
    96 
       
    97         if (isEndElement()) {
       
    98             break;
       
    99         }
       
   100 
       
   101         if (isStartElement()) {
       
   102             readUnknownElement();
       
   103         }
       
   104     }
       
   105 }
       
   106 
       
   107 void HbEffectXmlParser::readBlendingElement()
       
   108 {
       
   109     Q_ASSERT(isStartElement());
       
   110 
       
   111     while (!atEnd()) {
       
   112         readNext();
       
   113 
       
   114         // If there is no value in the blending element, bail out.
       
   115         if (isEndElement()) {
       
   116             break;
       
   117         }
       
   118 
       
   119         if (isCharacters()) {
       
   120             // Store current blending value
       
   121             mCurrentBlending = text().toString().trimmed();
       
   122             // Blending value was read, find end tag and return.
       
   123             while (!atEnd()) {
       
   124                 readNext();
       
   125 
       
   126                 if (isEndElement()) {
       
   127                     break;
       
   128                 }
       
   129             }
       
   130             break;
       
   131         }
       
   132     }
       
   133 }
       
   134 
       
   135 // FXML support
       
   136 void HbEffectXmlParser::readVisuals()
       
   137 {
       
   138     Q_ASSERT(isStartElement() && name() == FXML_LAYERS);
       
   139 
       
   140     while (!atEnd()) {
       
   141         readNext();
       
   142 
       
   143         if (isEndElement()) {
       
   144             if (name() == FXML_LAYERS)
       
   145                 break;
       
   146         }
       
   147 
       
   148         if (isStartElement()) {
       
   149             if (name() == FXML_VISUAL) {
       
   150                 readVisualData();
       
   151             }
       
   152 
       
   153             else if (name() == FXML_LAYERGROUP) {
       
   154                 // Not needed
       
   155             }
       
   156             else if (name() == FXML_BLENDING) {
       
   157                 readBlendingElement();
       
   158             }
       
   159             else if (name() == FXML_COMMENT) {
       
   160                 // Comments are skipped
       
   161             }
       
   162             else if (name() == FXML_FILTER) {
       
   163 #ifdef HB_FILTER_EFFECTS
       
   164                 readFilterData();
       
   165 #endif
       
   166             }
       
   167 
       
   168             else {
       
   169                 readUnknownElement();
       
   170             }
       
   171         }
       
   172     }
       
   173 }
       
   174 
       
   175 void HbEffectXmlParser::readVisualData()
       
   176 {
       
   177     // Read all 'param' tags inside the 'visual' tags and append them in the fxml animation list
       
   178 
       
   179     while (!atEnd()) {
       
   180         readNext();
       
   181 
       
   182         if (isEndElement() && name() == FXML_VISUAL) {
       
   183             break;
       
   184         }
       
   185 
       
   186         if (isStartElement()) {
       
   187             if (name() == FXML_PARAM) {
       
   188                 mFxmlData->appendParamData(readParamData());
       
   189             }
       
   190             else if (name() == FXML_FILTER) {
       
   191 #ifdef HB_FILTER_EFFECTS
       
   192                 readFilterData();
       
   193 #endif
       
   194             }
       
   195             else {
       
   196                 readUnknownElement();
       
   197             }
       
   198         }
       
   199     }
       
   200 }
       
   201 /**
       
   202 * Reads all 'param' tags inside the 'filter' tag and creates a filter data structure,
       
   203 * which is then appended to the fxmlData.
       
   204 */
       
   205 void HbEffectXmlParser::readFilterData()
       
   206 {
       
   207 #ifdef HB_FILTER_EFFECTS
       
   208     // Create filter data structure
       
   209     HbEffectFxmlFilterData filterData(mFxmlData->memoryType());
       
   210 
       
   211     // Parse filter type
       
   212     QXmlStreamAttributes attrs = attributes();
       
   213 
       
   214     foreach (const QXmlStreamAttribute &attr, attrs) {
       
   215         // "type" = ...
       
   216         if (attr.name().toString() == FXML_PARAM_TYPE) {
       
   217             filterData.setType(attr.value().toString());
       
   218             break;
       
   219         }
       
   220         // Other attributes are skipped atm
       
   221     }
       
   222 
       
   223     while (!atEnd()) {
       
   224         readNext();
       
   225 
       
   226         if (isEndElement() && name() == FXML_FILTER) {
       
   227             break;
       
   228         }
       
   229 
       
   230         if (isStartElement()) {
       
   231             if (name() == FXML_PARAM) {
       
   232                 filterData.appendParamData(readParamData());
       
   233             } else {
       
   234                 readUnknownElement();
       
   235             }
       
   236         }
       
   237     }
       
   238 
       
   239     // Add blending data in the filter data
       
   240     filterData.setBlending(mCurrentBlending);
       
   241 
       
   242     // Append filter data in the list
       
   243     mFxmlData->appendFilterData(filterData);
       
   244 
       
   245 #endif
       
   246 }
       
   247 
       
   248 // This parses information inside one <param> field.
       
   249 // E.g. "scale_x", "scale_y", "scale_origin_x"
       
   250 // 
       
   251 HbEffectFxmlParamData HbEffectXmlParser::readParamData()
       
   252 {
       
   253     Q_ASSERT(isStartElement() && name() == FXML_PARAM);
       
   254     
       
   255     HbEffectFxmlParamData param(mFxmlData->memoryType());
       
   256     HbKeyFrame kf(mFxmlData->memoryType());
       
   257 
       
   258     QXmlStreamAttributes attrs = attributes();
       
   259 
       
   260     // Populate the PARAM attributes
       
   261     foreach (const QXmlStreamAttribute &attr, attrs) {
       
   262         // "name" = ...
       
   263         if (attr.name().toString() == FXML_PARAM_NAME) {
       
   264             param.setName(attr.value().toString());
       
   265         }
       
   266         // "type" = ...
       
   267         else if (attr.name().toString() == FXML_PARAM_TYPE) {
       
   268             // Nothing to do here atm...
       
   269         }
       
   270         // Insert other elements to param data, e.g. "ref" is stored here
       
   271         else {
       
   272             param.setAttribute(attr.name().toString(), attr.value().toString());
       
   273         }
       
   274     }
       
   275 
       
   276     while (!atEnd()) {
       
   277         readNext();
       
   278 
       
   279         if (isEndElement() && name() == FXML_PARAM) {
       
   280             break;
       
   281         }
       
   282 
       
   283         // Elements inside params
       
   284         if (isStartElement()) {
       
   285             // <duration> tag
       
   286             if (name() == FXML_DURATION) {
       
   287                 param.setDuration(readElementText());
       
   288             }
       
   289             // <style> tag
       
   290             else if (name() == FXML_STYLE) {
       
   291                 param.setAttribute(FXML_STYLE, readElementText());
       
   292             }
       
   293             // <marker> tag
       
   294             else if (name() == FXML_MARKER) {
       
   295                 QXmlStreamAttributes attrs = attributes();
       
   296                 
       
   297                 enum {
       
   298                     Undefined = 0,
       
   299                     Start,
       
   300                     End
       
   301                 } loopType = Undefined;
       
   302 
       
   303                 // Fetch "type" attribute from <marker> tag
       
   304                 foreach (const QXmlStreamAttribute &attr, attrs) {
       
   305                     if (attr.name().toString() == FXML_PARAM_TYPE) {
       
   306                         QString s = attr.value().toString();
       
   307                         if (s == FXML_LOOP_START) {
       
   308                             loopType = Start;
       
   309                         } else if (s == FXML_LOOP_END) {
       
   310                             loopType = End;
       
   311                         }
       
   312                         break;
       
   313                     }
       
   314                 }
       
   315 
       
   316                 if (loopType != Undefined) {
       
   317                     // Fetch "at" attribute from <marker> tag
       
   318                     foreach (const QXmlStreamAttribute &attr, attrs) {
       
   319                         if (attr.name().toString() == FXML_PARAM_AT) {
       
   320                             QString s = attr.value().toString();
       
   321                             bool ok = false;
       
   322                             float f = s.toFloat(&ok);
       
   323                             if (ok) {
       
   324                                 if (loopType == Start) {
       
   325                                     param.setLoopStart(f);
       
   326                                 } else if (loopType == End) {
       
   327                                     param.setLoopEnd(f);
       
   328                                 }
       
   329                             }
       
   330                         }
       
   331                         break;
       
   332                     }
       
   333                 }
       
   334 
       
   335                 // Advance until end element
       
   336                 while (!atEnd()) {
       
   337                     if (readNext() == QXmlStreamReader::EndElement) {
       
   338                         break;
       
   339                     }
       
   340                 }
       
   341             }
       
   342 
       
   343             // <keyframe> tag
       
   344             else if (name() == FXML_KEYFRAME) {
       
   345                 QXmlStreamAttributes attrs = attributes();
       
   346                 
       
   347                 bool ok = false;
       
   348 
       
   349                 // Fetch "at" attribute from <keyframe> tag
       
   350                 foreach (const QXmlStreamAttribute &attr, attrs) {
       
   351                     if (attr.name().toString() == FXML_PARAM_AT) {
       
   352                         QString s = attr.value().toString();
       
   353                         kf.pos = s.toFloat(&ok);
       
   354                         break;
       
   355                     }
       
   356                 }
       
   357 
       
   358                 // Fetch value of the <keyframe> tag
       
   359                 QString s = readElementText();
       
   360                 if (ok) {
       
   361                     // Color value cannot be stored in float so store it as a string
       
   362                     if (param.name() == "color") {
       
   363                         kf.stringValue = s;
       
   364                     } else {
       
   365                         kf.val = s.toFloat(&ok);
       
   366                     }
       
   367                 }
       
   368 
       
   369                 // Append keyframe to the param data if values were ok.
       
   370                 // Verify also here that the position is between 0.0 and 1.0.
       
   371                 if (ok && kf.pos >= 0.0 && kf.pos <= 1.0) {
       
   372                     param.append(kf);
       
   373                 }
       
   374             }
       
   375             //<start> element
       
   376             else if(name() == FXML_KEYWORD_START) {
       
   377 
       
   378                 QXmlStreamAttributes attrs = attributes();
       
   379                 foreach (const QXmlStreamAttribute &attr, attrs) {
       
   380                     if( attr.name() == FXML_PARAM_REF ) {
       
   381                         param.setStartRef(attr.value().toString());
       
   382                     }
       
   383                 }
       
   384                 param.setAttribute(FXML_KEYWORD_START, readElementText());
       
   385             }
       
   386             //<end> element
       
   387             else if(name() == FXML_KEYWORD_END) {                
       
   388                 QXmlStreamAttributes attrs = attributes();
       
   389                 foreach (const QXmlStreamAttribute &attr, attrs) {
       
   390                     if( attr.name() == FXML_PARAM_REF ) {
       
   391                         param.setEndRef(attr.value().toString());
       
   392                     }
       
   393                 }
       
   394                 param.setAttribute(FXML_KEYWORD_END, readElementText());
       
   395             }
       
   396             else {
       
   397                 readUnknownElement();
       
   398             }
       
   399         }
       
   400         // Value of the param
       
   401         else if (isCharacters()) {
       
   402             param.setValue(text().toString().trimmed());
       
   403         }
       
   404     }
       
   405 
       
   406     return param;
       
   407 }
       
   408 
       
   409 // End of File