Warning, file /office/calligra/libs/odf/KoDocumentInfo.cpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

0001 /* This file is part of the KDE project
0002    Copyright (C) 1998, 1999, 2000 Torben Weis <weis@kde.org>
0003    Copyright (C) 2004 David Faure <faure@kde.org>
0004 
0005    This library is free software; you can redistribute it and/or
0006    modify it under the terms of the GNU Library General Public
0007    License as published by the Free Software Foundation; either
0008    version 2 of the License, or (at your option) any later version.
0009 
0010    This library is distributed in the hope that it will be useful,
0011    but WITHOUT ANY WARRANTY; without even the implied warranty of
0012    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0013    Library General Public License for more details.
0014 
0015    You should have received a copy of the GNU Library General Public License
0016    along with this library; see the file COPYING.LIB.  If not, write to
0017    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
0018  * Boston, MA 02110-1301, USA.
0019 */
0020 
0021 #include "KoDocumentInfo.h"
0022 
0023 #include "KoDocumentBase.h"
0024 #include "KoOdfWriteStore.h"
0025 #include "KoXmlNS.h"
0026 
0027 #include <QDateTime>
0028 #include <KoStoreDevice.h>
0029 #include <KoXmlWriter.h>
0030 
0031 #include <kconfig.h>
0032 #include <kconfiggroup.h>
0033 #include <OdfDebug.h>
0034 #include <klocalizedstring.h>
0035 #include <kuser.h>
0036 #include <kemailsettings.h>
0037 
0038 #include <CalligraVersionWrapper.h>
0039 
0040 
0041 KoDocumentInfo::KoDocumentInfo(QObject *parent) : QObject(parent)
0042 {
0043     m_aboutTags << "title" << "description" << "subject" << "comments"
0044     << "keyword" << "initial-creator" << "editing-cycles"
0045     << "date" << "creation-date" << "language";
0046 
0047     m_authorTags << "creator" << "initial" << "author-title"
0048     << "email" << "telephone" << "telephone-work"
0049     << "fax" << "country" << "postal-code" << "city"
0050     << "street" << "position" << "company";
0051 
0052     setAboutInfo("editing-cycles", "0");
0053     setAboutInfo("initial-creator", i18n("Unknown"));
0054     setAboutInfo("creation-date", QDateTime::currentDateTime()
0055                  .toString(Qt::ISODate));
0056 }
0057 
0058 KoDocumentInfo::~KoDocumentInfo()
0059 {
0060 }
0061 
0062 bool KoDocumentInfo::load(const KoXmlDocument &doc)
0063 {
0064     m_authorInfo.clear();
0065 
0066     if (!loadAboutInfo(doc.documentElement()))
0067         return false;
0068 
0069     if (!loadAuthorInfo(doc.documentElement()))
0070         return false;
0071 
0072     return true;
0073 }
0074 
0075 bool KoDocumentInfo::loadOasis(const KoXmlDocument &metaDoc)
0076 {
0077     m_authorInfo.clear();
0078 
0079     KoXmlNode t = KoXml::namedItemNS(metaDoc, KoXmlNS::office, "document-meta");
0080     KoXmlNode office = KoXml::namedItemNS(t, KoXmlNS::office, "meta");
0081 
0082     if (office.isNull())
0083         return false;
0084 
0085     if (!loadOasisAboutInfo(office))
0086         return false;
0087 
0088     if (!loadOasisAuthorInfo(office))
0089         return false;
0090 
0091     return true;
0092 }
0093 
0094 QDomDocument KoDocumentInfo::save(QDomDocument &doc)
0095 {
0096     updateParametersAndBumpNumCycles();
0097 
0098     QDomElement s = saveAboutInfo(doc);
0099     if (!s.isNull())
0100         doc.documentElement().appendChild(s);
0101 
0102     s = saveAuthorInfo(doc);
0103     if (!s.isNull())
0104         doc.documentElement().appendChild(s);
0105 
0106 
0107     if (doc.documentElement().isNull())
0108         return QDomDocument();
0109 
0110     return doc;
0111 }
0112 
0113 bool KoDocumentInfo::saveOasis(KoStore *store)
0114 {
0115     updateParametersAndBumpNumCycles();
0116 
0117     KoStoreDevice dev(store);
0118     KoXmlWriter* xmlWriter = KoOdfWriteStore::createOasisXmlWriter(&dev,
0119                              "office:document-meta");
0120     xmlWriter->startElement("office:meta");
0121 
0122     xmlWriter->startElement("meta:generator");
0123     xmlWriter->addTextNode(QString("Calligra/%1")
0124                            .arg(CalligraVersionWrapper::versionString()));
0125     xmlWriter->endElement();
0126 
0127     if (!saveOasisAboutInfo(*xmlWriter))
0128         return false;
0129     if (!saveOasisAuthorInfo(*xmlWriter))
0130         return false;
0131 
0132     xmlWriter->endElement();
0133     xmlWriter->endElement(); // root element
0134     xmlWriter->endDocument();
0135     delete xmlWriter;
0136     return true;
0137 }
0138 
0139 void KoDocumentInfo::setAuthorInfo(const QString &info, const QString &data)
0140 {
0141     if (!m_authorTags.contains(info)) {
0142         return;
0143     }
0144 
0145     m_authorInfoOverride.insert(info, data);
0146 }
0147 
0148 void KoDocumentInfo::setActiveAuthorInfo(const QString &info, const QString &data)
0149 {
0150     if (!m_authorTags.contains(info)) {
0151         return;
0152     }
0153 
0154     if (data.isEmpty()) {
0155         m_authorInfo.remove(info);
0156     } else {
0157         m_authorInfo.insert(info, data);
0158     }
0159     emit infoUpdated(info, data);
0160 }
0161 
0162 QString KoDocumentInfo::authorInfo(const QString &info) const
0163 {
0164     if (!m_authorTags.contains(info))
0165         return QString();
0166 
0167     return m_authorInfo[ info ];
0168 }
0169 
0170 void KoDocumentInfo::setAboutInfo(const QString &info, const QString &data)
0171 {
0172     if (!m_aboutTags.contains(info))
0173         return;
0174 
0175     m_aboutInfo.insert(info, data);
0176     emit infoUpdated(info, data);
0177 }
0178 
0179 QString KoDocumentInfo::aboutInfo(const QString &info) const
0180 {
0181     if (!m_aboutTags.contains(info)) {
0182         return QString();
0183     }
0184 
0185     return m_aboutInfo[info];
0186 }
0187 
0188 bool KoDocumentInfo::saveOasisAuthorInfo(KoXmlWriter &xmlWriter)
0189 {
0190     foreach(const QString & tag, m_authorTags) {
0191         if (!authorInfo(tag).isEmpty() && tag == "creator") {
0192             xmlWriter.startElement("dc:creator");
0193             xmlWriter.addTextNode(authorInfo("creator"));
0194             xmlWriter.endElement();
0195         } else if (!authorInfo(tag).isEmpty()) {
0196             xmlWriter.startElement("meta:user-defined");
0197             xmlWriter.addAttribute("meta:name", tag);
0198             xmlWriter.addTextNode(authorInfo(tag));
0199             xmlWriter.endElement();
0200         }
0201     }
0202 
0203     return true;
0204 }
0205 
0206 bool KoDocumentInfo::loadOasisAuthorInfo(const KoXmlNode &metaDoc)
0207 {
0208     KoXmlElement e = KoXml::namedItemNS(metaDoc, KoXmlNS::dc, "creator");
0209     if (!e.isNull() && !e.text().isEmpty())
0210         setActiveAuthorInfo("creator", e.text());
0211 
0212     KoXmlNode n = metaDoc.firstChild();
0213     for (; !n.isNull(); n = n.nextSibling()) {
0214         if (!n.isElement())
0215             continue;
0216 
0217         KoXmlElement e = n.toElement();
0218         if (!(e.namespaceURI() == KoXmlNS::meta &&
0219                 e.localName() == "user-defined" && !e.text().isEmpty()))
0220             continue;
0221 
0222         QString name = e.attributeNS(KoXmlNS::meta, "name", QString());
0223         setActiveAuthorInfo(name, e.text());
0224     }
0225 
0226     return true;
0227 }
0228 
0229 bool KoDocumentInfo::loadAuthorInfo(const KoXmlElement &e)
0230 {
0231     KoXmlNode n = e.namedItem("author").firstChild();
0232     for (; !n.isNull(); n = n.nextSibling()) {
0233         KoXmlElement e = n.toElement();
0234         if (e.isNull())
0235             continue;
0236 
0237         if (e.tagName() == "full-name")
0238             setActiveAuthorInfo("creator", e.text().trimmed());
0239         else
0240             setActiveAuthorInfo(e.tagName(), e.text().trimmed());
0241     }
0242 
0243     return true;
0244 }
0245 
0246 QDomElement KoDocumentInfo::saveAuthorInfo(QDomDocument &doc)
0247 {
0248     QDomElement e = doc.createElement("author");
0249     QDomElement t;
0250 
0251     foreach(const QString &tag, m_authorTags) {
0252         if (tag == "creator")
0253             t = doc.createElement("full-name");
0254         else
0255             t = doc.createElement(tag);
0256 
0257         e.appendChild(t);
0258         t.appendChild(doc.createTextNode(authorInfo(tag)));
0259     }
0260 
0261     return e;
0262 }
0263 
0264 bool KoDocumentInfo::saveOasisAboutInfo(KoXmlWriter &xmlWriter)
0265 {
0266     foreach(const QString &tag, m_aboutTags) {
0267         if (!aboutInfo(tag).isEmpty() || tag == "title") {
0268             if (tag == "keyword") {
0269                 foreach(const QString & tmp, aboutInfo("keyword").split(m_keywordSeparator)) {
0270                     xmlWriter.startElement("meta:keyword");
0271                     xmlWriter.addTextNode(tmp);
0272                     xmlWriter.endElement();
0273                 }
0274             } else if (tag == "title" || tag == "description" || tag == "subject" ||
0275                        tag == "date" || tag == "language") {
0276                 QByteArray elementName(QString("dc:" + tag).toLatin1());
0277                 xmlWriter.startElement(elementName.constData());
0278                 xmlWriter.addTextNode(aboutInfo(tag));
0279                 xmlWriter.endElement();
0280             } else {
0281                 QByteArray elementName(QString("meta:" + tag).toLatin1());
0282                 xmlWriter.startElement(elementName.constData());
0283                 xmlWriter.addTextNode(aboutInfo(tag));
0284                 xmlWriter.endElement();
0285             }
0286         }
0287     }
0288 
0289     return true;
0290 }
0291 
0292 bool KoDocumentInfo::loadOasisAboutInfo(const KoXmlNode &metaDoc)
0293 {
0294     QStringList keywords;
0295     KoXmlElement e;
0296     forEachElement(e, metaDoc) {
0297         QString tag(e.localName());
0298         if (! m_aboutTags.contains(tag) && tag != "generator") {
0299             continue;
0300         }
0301 
0302         //debugOdf<<"localName="<<e.localName();
0303         if (tag == "keyword") {
0304             if (!e.text().isEmpty())
0305                 keywords << e.text().trimmed();
0306         } else if (tag == "description") {
0307             //this is the odf way but add meta:comment if is already loaded
0308             KoXmlElement e  = KoXml::namedItemNS(metaDoc, KoXmlNS::dc, tag);
0309             if (!e.isNull() && !e.text().isEmpty())
0310                 setAboutInfo("description", aboutInfo("description") + e.text().trimmed());
0311         } else if (tag == "comments") {
0312             //this was the old way so add it to dc:description
0313             KoXmlElement e  = KoXml::namedItemNS(metaDoc, KoXmlNS::meta, tag);
0314             if (!e.isNull() && !e.text().isEmpty())
0315                 setAboutInfo("description", aboutInfo("description") + e.text().trimmed());
0316         } else if (tag == "title"|| tag == "subject"
0317                    || tag == "date" || tag == "language") {
0318             KoXmlElement e  = KoXml::namedItemNS(metaDoc, KoXmlNS::dc, tag);
0319             if (!e.isNull() && !e.text().isEmpty())
0320                 setAboutInfo(tag, e.text().trimmed());
0321         } else if (tag == "generator") {
0322             setOriginalGenerator(e.text().trimmed());
0323         } else {
0324             KoXmlElement e  = KoXml::namedItemNS(metaDoc, KoXmlNS::meta, tag);
0325             if (!e.isNull() && !e.text().isEmpty())
0326                 setAboutInfo(tag, e.text().trimmed());
0327         }
0328     }
0329 
0330     if (keywords.count() > 0) {
0331         setAboutInfo("keyword", keywords.join(m_keywordSeparator));
0332     }
0333 
0334     return true;
0335 }
0336 
0337 bool KoDocumentInfo::loadAboutInfo(const KoXmlElement &e)
0338 {
0339     KoXmlNode n = e.namedItem("about").firstChild();
0340     KoXmlElement tmp;
0341     for (; !n.isNull(); n = n.nextSibling()) {
0342         tmp = n.toElement();
0343         if (tmp.isNull())
0344             continue;
0345 
0346         if (tmp.tagName() == "abstract")
0347             setAboutInfo("comments", tmp.text());
0348 
0349         setAboutInfo(tmp.tagName(), tmp.text());
0350     }
0351 
0352     return true;
0353 }
0354 
0355 QDomElement KoDocumentInfo::saveAboutInfo(QDomDocument &doc)
0356 {
0357     QDomElement e = doc.createElement("about");
0358     QDomElement t;
0359 
0360     foreach(const QString &tag, m_aboutTags) {
0361         if (tag == "comments") {
0362             t = doc.createElement("abstract");
0363             e.appendChild(t);
0364             t.appendChild(doc.createCDATASection(aboutInfo(tag)));
0365         } else {
0366             t = doc.createElement(tag);
0367             e.appendChild(t);
0368             t.appendChild(doc.createTextNode(aboutInfo(tag)));
0369         }
0370     }
0371 
0372     return e;
0373 }
0374 
0375 void KoDocumentInfo::updateParametersAndBumpNumCycles()
0376 {
0377     KoDocumentBase *doc = dynamic_cast< KoDocumentBase *>(parent());
0378     if (doc && doc->isAutosaving()) {
0379         return;
0380     }
0381 
0382     setAboutInfo("editing-cycles", QString::number(aboutInfo("editing-cycles").toInt() + 1));
0383     setAboutInfo("date", QDateTime::currentDateTime().toString(Qt::ISODate));
0384 
0385     updateParameters();
0386 }
0387 
0388 void KoDocumentInfo::updateParameters()
0389 {
0390     KoDocumentBase *doc = dynamic_cast< KoDocumentBase *>(parent());
0391     if (doc && (!doc->isModified() && !doc->isEmpty())) {
0392         return;
0393     }
0394 
0395     KConfig config("calligrarc");
0396     config.reparseConfiguration();
0397     KConfigGroup authorGroup(&config, "Author");
0398     QStringList profiles = authorGroup.readEntry("profile-names", QStringList());
0399 
0400     config.reparseConfiguration();
0401     KConfigGroup appAuthorGroup(&config, "Author");
0402     QString profile = appAuthorGroup.readEntry("active-profile", "");
0403 
0404     if (profiles.contains(profile)) {
0405         KConfigGroup cgs(&authorGroup, "Author-" + profile);
0406         setActiveAuthorInfo("creator", cgs.readEntry("creator"));
0407         setActiveAuthorInfo("initial", cgs.readEntry("initial"));
0408         setActiveAuthorInfo("author-title", cgs.readEntry("author-title"));
0409         setActiveAuthorInfo("email", cgs.readEntry("email"));
0410         setActiveAuthorInfo("telephone", cgs.readEntry("telephone"));
0411         setActiveAuthorInfo("telephone-work", cgs.readEntry("telephone-work"));
0412         setActiveAuthorInfo("fax", cgs.readEntry("fax"));
0413         setActiveAuthorInfo("country",cgs.readEntry("country"));
0414         setActiveAuthorInfo("postal-code",cgs.readEntry("postal-code"));
0415         setActiveAuthorInfo("city", cgs.readEntry("city"));
0416         setActiveAuthorInfo("street", cgs.readEntry("street"));
0417         setActiveAuthorInfo("position", cgs.readEntry("position"));
0418         setActiveAuthorInfo("company", cgs.readEntry("company"));
0419     } else {
0420         if (profile == "anonymous") {
0421             setActiveAuthorInfo("creator", QString());
0422             setActiveAuthorInfo("telephone", QString());
0423             setActiveAuthorInfo("telephone-work", QString());
0424             setActiveAuthorInfo("email", QString());
0425         } else {
0426             KUser user(KUser::UseRealUserID);
0427             setActiveAuthorInfo("creator", user.property(KUser::FullName).toString());
0428             setActiveAuthorInfo("telephone-work", user.property(KUser::WorkPhone).toString());
0429             setActiveAuthorInfo("telephone", user.property(KUser::HomePhone).toString());
0430             KEMailSettings eMailSettings;
0431             setActiveAuthorInfo("email", eMailSettings.getSetting(KEMailSettings::EmailAddress));
0432         }
0433         setActiveAuthorInfo("initial", "");
0434         setActiveAuthorInfo("author-title", "");
0435         setActiveAuthorInfo("fax", "");
0436         setActiveAuthorInfo("country", "");
0437         setActiveAuthorInfo("postal-code", "");
0438         setActiveAuthorInfo("city", "");
0439         setActiveAuthorInfo("street", "");
0440         setActiveAuthorInfo("position", "");
0441         setActiveAuthorInfo("company", "");
0442     }
0443 
0444     //alllow author info set programatically to override info from author profile
0445     foreach(const QString &tag, m_authorTags) {
0446         if (m_authorInfoOverride.contains(tag)) {
0447             setActiveAuthorInfo(tag, m_authorInfoOverride.value(tag));
0448         }
0449     }
0450 }
0451 
0452 void KoDocumentInfo::resetMetaData()
0453 {
0454     setAboutInfo("editing-cycles", QString::number(0));
0455     setAboutInfo("initial-creator", authorInfo("creator"));
0456     setAboutInfo("creation-date", QDateTime::currentDateTime().toString(Qt::ISODate));
0457 }
0458 
0459 QString KoDocumentInfo::originalGenerator() const
0460 {
0461     return m_generator;
0462 }
0463 
0464 void KoDocumentInfo::setOriginalGenerator(const QString &generator)
0465 {
0466     m_generator = generator;
0467 }