kexi

xmlhandler.cpp

00001 /***************************************************************************
00002  * This file is part of the KDE project
00003  * copyright (C) 2005 by Sebastian Sauer (mail@dipe.org)
00004  * copyright (C) 2006 by Bernd Steindorff (bernd@itii.de)
00005  *
00006  * This program is free software; you can redistribute it and/or
00007  * modify it under the terms of the GNU Library General Public
00008  * License as published by the Free Software Foundation; either
00009  * version 2 of the License, or (at your option) any later version.
00010  * This program is distributed in the hope that it will be useful,
00011  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013  * Library General Public License for more details.
00014  * You should have received a copy of the GNU Library General Public License
00015  * along with this program; see the file COPYING.  If not, write to
00016  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00017  * Boston, MA 02110-1301, USA.
00018  ***************************************************************************/
00019 
00020 #include "xmlhandler.h"
00021 #include "macro.h"
00022 #include "macroitem.h"
00023 #include "action.h"
00024 
00025 #include <qdom.h>
00026 #include <kdebug.h>
00027 
00028 using namespace KoMacro;
00029 
00030 namespace KoMacro {
00031 
00036     class XMLHandler::Private
00037     {
00038         public:
00039 
00044             Macro* const macro;
00045 
00052             Private(Macro* const macro)
00053                 : macro(macro)
00054             {
00055             }
00056     };
00057 
00058 }
00059 
00060 XMLHandler::XMLHandler(Macro* const macro)
00061     : d( new Private(macro) )
00062 {
00063 }
00064 
00065 XMLHandler::~XMLHandler()
00066 {
00067     delete d;
00068 }
00069 
00070 bool XMLHandler::parseXML(const QDomElement& element)
00071 {
00072     // Remove old items. We should clear first.
00073     d->macro->clearItems();
00074 
00075     // We expect a <macro> element. Do we really need to be such strict or
00076     // would it be more wise to trust the application in that case?
00077     if(element.tagName() != "macro") {
00078         kdDebug() << QString("XMLHandler::parseXML() Invalid tagname \"%1\"").arg(element.tagName()) << endl;
00079         return false;
00080     }
00081     
00082     // To be flexible with the xml-scheme, we need a version-number for xml.
00083     // If there is more than one version, parsing should update old macro-data, so that it
00084     // could write out in the newer version in toXML().
00085     if( element.attribute("xmlversion") != "1"){
00086         kdDebug() << QString("XMLHandler::parseXML() Invalid xml-version \"%1\"").arg(element.attribute("xmlversion")) << endl;
00087         return false;
00088     }
00089 
00090     // Do we need to load the macro's name?
00091     // d->macro->setName(element.attribute("name"));
00092 
00093     // Iterate through the child nodes the passed QDomElement has and
00094     // build the MacroItem elements.
00095     for(QDomNode itemnode = element.firstChild(); ! itemnode.isNull(); itemnode = itemnode.nextSibling()) {
00096         // The tagname should be "item"
00097         if(itemnode.nodeName() == "item") {
00098             // The node is an element.
00099             const QDomElement itemelem = itemnode.toElement();
00100 
00101             // Create a new MacroItem
00102             KSharedPtr<MacroItem> item = new MacroItem();
00103 
00104             // Add the new item to our Macro.
00105             d->macro->addItem( item );
00106 
00107             // Each MacroItem may point to an Action instance. We
00108             // try to determinate this action now and if it's defined
00109             // and available, we set it.
00110             KSharedPtr<Action> action = Manager::self()->action( itemelem.attribute("action") );
00111             if(action.data()) {
00112                 item->setAction(action);
00113             }
00114 
00115             // Set the comment
00116             item->setComment( itemelem.attribute("comment") );
00117 
00118             // Iterate through the children this item has and try
00119             // to fill the list of variables our new MacroItem has.
00120             for(QDomNode childnode = itemnode.firstChild(); ! childnode.isNull(); childnode = childnode.nextSibling()) {
00121                 // The tagname should be "variable"
00122                 if(childnode.nodeName() == "variable") {
00123                     // The node is an element.
00124                     const QDomElement childelem = childnode.toElement();
00125 
00126                     // The name the variable has.
00127                     const QString name = childelem.attribute("name");
00128                     // The value the variable has.
00129                     const QString value = childelem.text();
00130 
00131                     // Store the new variable in our macroitem.
00132                     item->addVariable(name, value);
00133                 }
00134             }
00135         }
00136     }
00137 
00138     // Job was done successfully.
00139     return true;
00140 }
00141 
00142 QDomElement XMLHandler::toXML()
00143 {
00144     // The QDomDocument provides us the functionality to create new QDomElement instances.
00145     QDomDocument document;
00146 
00147     // Create the Macro-QDomElement. This element will be returned.
00148     QDomElement macroelem = document.createElement("macro");
00149 
00150     // Set the Macro-XML-Version, it should be the newest Version.
00151     macroelem.setAttribute("xmlversion","1");
00152 
00153     // Do we need to store the macro's name? Normaly the application
00154     // could/should take care of it cause we don't know how the app
00155     // may store the XML and cause we don't like to introduce
00156     // redundancy at this point.
00157     //macroelem.setAttribute("name",d->macro->name());
00158 
00159     // The list of MacroItem-children a Macro provides.
00160     QValueList<KSharedPtr<MacroItem > > items = d->macro->items();
00161 
00162     // Create an iterator...
00163     QValueList<KSharedPtr<MacroItem > >::ConstIterator it(items.constBegin()), end(items.constEnd());
00164     // ...and iterate over the list of children the Macro provides.
00165     for(;it != end; ++it) {
00166         // We are iterating over MacroItem instances.
00167         KSharedPtr<MacroItem> item = *it;
00168 
00169         // Flag to determinate if we really need to remember this item what
00170         // is only the case if comment or action is defined.
00171         bool append = false;
00172 
00173         // Each MacroItem will have an own node.
00174         QDomElement itemelem = document.createElement("item");
00175 
00176         // Each MacroItem could point to an Action provided by the Manager.
00177         const KSharedPtr<Action> action = item->action();
00178         if( action ) {
00179             append = true;
00180 
00181             // Remember the name of the action.
00182             itemelem.setAttribute("action", action->name());
00183 
00184             // Each MacroItem could have a list of variables. We
00185             // iterate through that list and build a element
00186             // for each single variable.
00187             QMap<QString, KSharedPtr<Variable > > varmap = item->variables();
00188 
00189             for(QMap<QString, KSharedPtr<Variable > >::ConstIterator vit = varmap.constBegin(); vit != varmap.constEnd(); ++vit) {
00190                 const KSharedPtr<Variable> v = vit.data();
00191                 if(! v.data()) {
00192                     // skip if the variable is NULL.
00193                     continue;
00194                 }
00195                 // Create an own element for the variable. The tagname will be
00196                 // the name of the variable.
00197                 QDomElement varelement = document.createElement("variable");
00198 
00199                 // Remember the name the value has.
00200                 varelement.setAttribute("name", vit.key()); 
00201 
00202                 // Remember the value as textnode.
00203                 varelement.appendChild(document.createTextNode(v->toString()));
00204 
00205                 // Add the new variable-element to our MacroItem.
00206                 itemelem.appendChild(varelement);
00207             }
00208         }
00209 
00210         // Each MacroItem could have an optional comment.
00211         const QString comment = item->comment();
00212         if(! comment.isEmpty()) {
00213             append = true;
00214             itemelem.setAttribute("comment", item->comment());
00215         }
00216 
00217         // Check if we really need to remember the item.
00218         if(append) {
00219             macroelem.appendChild(itemelem);
00220         }
00221 
00222     }
00223 
00224     // Job done. Return the macro's element.
00225     return macroelem;
00226 }
KDE Home | KDE Accessibility Home | Description of Access Keys