File indexing completed on 2024-05-26 16:15:58

0001 /* This file is part of the KDE project
0002  * Copyright (C) 2007 Thomas Zander <zander@kde.org>
0003  * Copyright (C) 2008, 2011 Sebastian Sauer <mail@dipe.org>
0004  * Copyright (C) 2011 Robert Mathias Marmorstein <robert@narnia.homeunix.com>
0005  *
0006  * This library is free software; you can redistribute it and/or
0007  * modify it under the terms of the GNU Library General Public
0008  * License as published by the Free Software Foundation; either
0009  * version 2 of the License, or (at your option) any later version.
0010  *
0011  * This library is distributed in the hope that it will be useful,
0012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
0013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0014  * Library General Public License for more details.
0015  *
0016  * You should have received a copy of the GNU Library General Public License
0017  * along with this library; see the file COPYING.LIB.  If not, write to
0018  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
0019  * Boston, MA 02110-1301, USA.
0020  */
0021 #include "KoVariableManager.h"
0022 
0023 #include "KoInlineTextObjectManager.h"
0024 #include "KoNamedVariable.h"
0025 #include <KoXmlNS.h>
0026 #include <KoXmlReader.h>
0027 #include <KoXmlWriter.h>
0028 
0029 class KoVariableManagerPrivate
0030 {
0031 public:
0032     KoVariableManagerPrivate()
0033             : lastId(KoInlineObject::VariableManagerStart) { }
0034     KoInlineTextObjectManager *inlineObjectManager;
0035     QHash<QString, int> variableMapping;
0036     QHash<int, QString> userTypes;
0037     QStringList variableNames;
0038     QStringList userVariableNames;
0039     int lastId;
0040 };
0041 
0042 KoVariableManager::KoVariableManager(KoInlineTextObjectManager *inlineObjectManager)
0043         : d(new KoVariableManagerPrivate)
0044 {
0045     d->inlineObjectManager = inlineObjectManager;
0046 }
0047 
0048 KoVariableManager::~KoVariableManager()
0049 {
0050     delete d;
0051 }
0052 
0053 void KoVariableManager::setValue(const QString &name, const QString &value, const QString &type)
0054 {
0055     int key;
0056     // we store the mapping from name to key
0057     if (d->variableMapping.contains(name)) {
0058         key = d->variableMapping.value(name);
0059     } else {
0060         key = d->lastId++;
0061         d->variableMapping.insert(name, key);
0062         if (type.isEmpty()) {
0063             Q_ASSERT(!d->variableNames.contains(name));
0064             d->variableNames.append(name);
0065         } else {
0066             Q_ASSERT(!d->userVariableNames.contains(name));
0067             d->userVariableNames.append(name);
0068         }
0069     }
0070     if (!type.isEmpty()) {
0071         d->userTypes.insert(key, type);
0072     }
0073     // the variable manager stores the actual value of the variable.
0074     d->inlineObjectManager->setProperty(static_cast<KoInlineObject::Property>(key), value);
0075     emit valueChanged();
0076 }
0077 
0078 QString KoVariableManager::value(const QString &name) const
0079 {
0080     int key = d->variableMapping.value(name);
0081     if (key == 0) {
0082         return QString();
0083     }
0084     return d->inlineObjectManager->stringProperty(static_cast<KoInlineObject::Property>(key));
0085 }
0086 
0087 QString KoVariableManager::userType(const QString &name) const
0088 {
0089     int key = d->variableMapping.value(name);
0090     if (key == 0) {
0091         return QString();
0092     }
0093     QHash<int, QString>::const_iterator it = d->userTypes.constFind(key);
0094     if (it == d->userTypes.constEnd()) {
0095         return QString();
0096     }
0097     return it.value();
0098 }
0099 
0100 void KoVariableManager::remove(const QString &name)
0101 {
0102     int key = d->variableMapping.value(name);
0103     if (key == 0) {
0104         return;
0105     }
0106     d->variableMapping.remove(name);
0107     d->userTypes.remove(key);
0108     d->variableNames.removeOne(name);
0109     d->userVariableNames.removeOne(name);
0110     d->inlineObjectManager->removeProperty(static_cast<KoInlineObject::Property>(key));
0111 }
0112 
0113 KoVariable *KoVariableManager::createVariable(const QString &name) const
0114 {
0115     int key = d->variableMapping.value(name);
0116     if (key == 0) {
0117         return 0;
0118     }
0119     return new KoNamedVariable(static_cast<KoInlineObject::Property>(key), name);
0120 }
0121 
0122 QList<QString> KoVariableManager::variables() const
0123 {
0124     return d->variableNames;
0125 }
0126 
0127 QList<QString> KoVariableManager::userVariables() const
0128 {
0129     return d->userVariableNames;
0130 }
0131 
0132 #include "TextDebug.h"
0133 
0134 void KoVariableManager::loadOdf(const KoXmlElement &bodyElement)
0135 {
0136     KoXmlElement element = KoXml::namedItemNS(bodyElement, KoXmlNS::text, "user-field-decls", KoXmlTextContentPrelude);
0137     if (element.isNull())
0138         return;
0139     KoXmlElement e;
0140     forEachElement(e, element) {
0141         if (e.namespaceURI() != KoXmlNS::text || e.localName() != "user-field-decl")
0142             continue;
0143         const QString name = e.attributeNS(KoXmlNS::text, "name");
0144         QString type = e.attributeNS(KoXmlNS::office, "value-type");
0145         QString value;
0146         if (type == "string") {
0147             if (e.hasAttributeNS(KoXmlNS::office, "string-value"))
0148                 value = e.attributeNS(KoXmlNS::office, "string-value");
0149             else // if the string-value is not present then the content defines the value
0150                 value = e.toText().data();
0151         } else if (type == "boolean") {
0152             value = e.attributeNS(KoXmlNS::office, "boolean-value");
0153         } else if (type == "currency") {
0154             value = e.attributeNS(KoXmlNS::office, "currency");
0155         } else if (type == "date") {
0156             value = e.attributeNS(KoXmlNS::office, "date-value");
0157         } else if (type == "float") {
0158             value = e.attributeNS(KoXmlNS::office, "value");
0159         } else if (type == "percentage") {
0160             value = e.attributeNS(KoXmlNS::office, "value");
0161         } else if (type == "time") {
0162             value = e.attributeNS(KoXmlNS::office, "time-value");
0163         } else if (type == "void") {
0164             value = e.attributeNS(KoXmlNS::office, "value");
0165         } else if (e.hasAttributeNS(KoXmlNS::text, "formula")) {
0166             type = "formula";
0167             value = e.attributeNS(KoXmlNS::text, "formula");
0168         } else {
0169             warnText << "Unknown user-field-decl value-type=" << type;
0170             continue;
0171         }
0172         setValue(name, value, type);
0173     }
0174 }
0175 
0176 void KoVariableManager::saveOdf(KoXmlWriter *bodyWriter)
0177 {
0178     if (userVariables().isEmpty()) {
0179         return;
0180     }
0181     bodyWriter->startElement("text:user-field-decls");
0182     foreach (const QString &name, userVariables()) {
0183         bodyWriter->startElement("text:user-field-decl");
0184         bodyWriter->addAttribute("text:name", name);
0185         QByteArray tag;
0186         QString type = userType(name);
0187         if (type == "formula") {
0188             tag = "text:formula";
0189         } else {
0190             if (type == "string") {
0191                 tag = "office:string-value";
0192             } else if (type == "boolean") {
0193                 tag = "office:boolean-value";
0194             } else if (type == "currency") {
0195                 tag = "office:boolean-value";
0196             } else if (type == "date") {
0197                 tag = "office:date-value";
0198             } else if (type == "float") {
0199                 tag = "office:value";
0200             } else if (type == "percentage") {
0201                 tag = "office:value";
0202             } else if (type == "time") {
0203                 tag = "office:time-value";
0204             } else if (type == "void") {
0205                 tag = "office:value";
0206             } else {
0207                 tag = "office:string-value";
0208                 type = "string";
0209             }
0210             bodyWriter->addAttribute("office:value-type", type);
0211         }
0212         bodyWriter->addAttribute(tag, value(name));
0213         bodyWriter->endElement();
0214     }
0215     bodyWriter->endElement();
0216 }