File indexing completed on 2024-05-12 16:01:59

0001 /* This file is part of the KDE project
0002    SPDX-FileCopyrightText: 1998, 1999, 2000 Torben Weis <weis@kde.org>
0003    SPDX-FileCopyrightText: 2004 David Faure <faure@kde.org>
0004 
0005    SPDX-License-Identifier: LGPL-2.0-or-later
0006 */
0007 
0008 #include "KoDocumentInfo.h"
0009 
0010 #include "KisDocument.h"
0011 #include "KoXmlNS.h"
0012 #include <KoResourcePaths.h>
0013 #include <QDateTime>
0014 #include <KoStoreDevice.h>
0015 #include <QDomDocument>
0016 #include <QDir>
0017 
0018 #include <kconfig.h>
0019 #include <kconfiggroup.h>
0020 #include <klocalizedstring.h>
0021 #include <kuser.h>
0022 #include <kemailsettings.h>
0023 
0024 #include <KritaVersionWrapper.h>
0025 
0026 
0027 KoDocumentInfo::KoDocumentInfo(QObject *parent) : QObject(parent)
0028 {
0029     m_aboutTags << "title" << "description" << "subject" << "abstract"
0030     << "keyword" << "initial-creator" << "editing-cycles" << "editing-time"
0031     << "date" << "creation-date" << "language" << "license";
0032 
0033     m_authorTags << "creator" << "creator-first-name" << "creator-last-name" << "initial" << "author-title" << "position" << "company";
0034     m_contactTags << "email" << "telephone" << "telephone-work" << "fax" << "country" << "postal-code" << "city" << "street";
0035     setAboutInfo("editing-cycles", "0");
0036     setAboutInfo("time-elapsed", "0");
0037     setAboutInfo("initial-creator", i18n("Unknown"));
0038     setAboutInfo("creation-date", QDateTime::currentDateTime()
0039                  .toString(Qt::ISODate));
0040 }
0041 
0042 KoDocumentInfo::KoDocumentInfo(const KoDocumentInfo &rhs, QObject *parent)
0043     : QObject(parent),
0044       m_aboutTags(rhs.m_aboutTags),
0045       m_authorTags(rhs.m_authorTags),
0046       m_contact(rhs.m_contact),
0047       m_authorInfo(rhs.m_authorInfo),
0048       m_authorInfoOverride(rhs.m_authorInfoOverride),
0049       m_aboutInfo(rhs.m_aboutInfo),
0050       m_generator(rhs.m_generator)
0051 {
0052 }
0053 
0054 KoDocumentInfo::~KoDocumentInfo()
0055 {
0056 }
0057 
0058 bool KoDocumentInfo::load(const QDomDocument &doc)
0059 {
0060     m_authorInfo.clear();
0061 
0062     if (!loadAboutInfo(doc.documentElement()))
0063         return false;
0064 
0065     if (!loadAuthorInfo(doc.documentElement()))
0066         return false;
0067 
0068     return true;
0069 }
0070 
0071 
0072 QDomDocument KoDocumentInfo::save(QDomDocument &doc)
0073 {
0074     updateParametersAndBumpNumCycles();
0075 
0076     QDomElement s = saveAboutInfo(doc);
0077     if (!s.isNull())
0078         doc.documentElement().appendChild(s);
0079 
0080     s = saveAuthorInfo(doc);
0081     if (!s.isNull())
0082         doc.documentElement().appendChild(s);
0083 
0084 
0085     if (doc.documentElement().isNull())
0086         return QDomDocument();
0087 
0088     return doc;
0089 }
0090 
0091 void KoDocumentInfo::setAuthorInfo(const QString &info, const QString &data)
0092 {
0093     if (!m_authorTags.contains(info) && !m_contactTags.contains(info) && !info.contains("contact-mode-")) {
0094         return;
0095     }
0096 
0097     m_authorInfoOverride.insert(info, data);
0098 }
0099 
0100 void KoDocumentInfo::setActiveAuthorInfo(const QString &info, const QString &data)
0101 {
0102     if (!m_authorTags.contains(info) && !m_contactTags.contains(info) && !info.contains("contact-mode-")) {
0103         return;
0104     }
0105     if (m_contactTags.contains(info)) {
0106         m_contact.insert(data, info);
0107     } else {
0108         m_authorInfo.insert(info, data);
0109     }
0110     emit infoUpdated(info, data);
0111 }
0112 
0113 QString KoDocumentInfo::authorInfo(const QString &info) const
0114 {
0115     if (!m_authorTags.contains(info)  && !m_contactTags.contains(info) && !info.contains("contact-mode-"))
0116         return QString();
0117 
0118     return m_authorInfo[ info ];
0119 }
0120 
0121 QStringList KoDocumentInfo::authorContactInfo() const
0122 {
0123     return m_contact.keys();
0124 }
0125 
0126 void KoDocumentInfo::setAboutInfo(const QString &info, const QString &data)
0127 {
0128     if (!m_aboutTags.contains(info))
0129         return;
0130 
0131     m_aboutInfo.insert(info, data);
0132     emit infoUpdated(info, data);
0133 }
0134 
0135 QString KoDocumentInfo::aboutInfo(const QString &info) const
0136 {
0137     if (!m_aboutTags.contains(info)) {
0138         return QString();
0139     }
0140 
0141     return m_aboutInfo[info];
0142 }
0143 
0144 
0145 bool KoDocumentInfo::loadAuthorInfo(const QDomElement &e)
0146 {
0147     m_contact.clear();
0148     QDomNode n = e.namedItem("author").firstChild();
0149     for (; !n.isNull(); n = n.nextSibling()) {
0150         QDomElement e = n.toElement();
0151         if (e.isNull())
0152             continue;
0153 
0154         if (e.tagName() == "full-name") {
0155             setActiveAuthorInfo("creator", e.text().trimmed());
0156         } else if (e.tagName() == "contact") {
0157             m_contact.insert(e.text(), e.attribute("type"));
0158         } else {
0159             setActiveAuthorInfo(e.tagName(), e.text().trimmed());
0160         }
0161     }
0162 
0163     return true;
0164 }
0165 
0166 QDomElement KoDocumentInfo::saveAuthorInfo(QDomDocument &doc)
0167 {
0168     QDomElement e = doc.createElement("author");
0169     QDomElement t;
0170 
0171     Q_FOREACH (const QString &tag, m_authorTags) {
0172         if (tag == "creator")
0173             t = doc.createElement("full-name");
0174         else
0175             t = doc.createElement(tag);
0176 
0177         e.appendChild(t);
0178         t.appendChild(doc.createTextNode(authorInfo(tag)));
0179     }
0180     for (int i=0; i<m_contact.keys().size(); i++) {
0181         t = doc.createElement("contact");
0182         e.appendChild(t);
0183         QString key = m_contact.keys().at(i);
0184         t.setAttribute("type", m_contact[key]);
0185         t.appendChild(doc.createTextNode(key));
0186     }
0187 
0188     return e;
0189 }
0190 
0191 
0192 bool KoDocumentInfo::loadAboutInfo(const QDomElement &e)
0193 {
0194     QDomNode n = e.namedItem("about").firstChild();
0195     QDomElement tmp;
0196     for (; !n.isNull(); n = n.nextSibling()) {
0197         tmp = n.toElement();
0198         if (tmp.isNull())
0199             continue;
0200 
0201         if (tmp.tagName() == "abstract")
0202             setAboutInfo("abstract", tmp.text());
0203 
0204         setAboutInfo(tmp.tagName(), tmp.text());
0205     }
0206 
0207     return true;
0208 }
0209 
0210 QDomElement KoDocumentInfo::saveAboutInfo(QDomDocument &doc)
0211 {
0212     QDomElement e = doc.createElement("about");
0213     QDomElement t;
0214 
0215     Q_FOREACH (const QString &tag, m_aboutTags) {
0216         if (tag == "abstract") {
0217             t = doc.createElement("abstract");
0218             e.appendChild(t);
0219             t.appendChild(doc.createCDATASection(aboutInfo(tag)));
0220         } else {
0221             t = doc.createElement(tag);
0222             e.appendChild(t);
0223             t.appendChild(doc.createTextNode(aboutInfo(tag)));
0224         }
0225     }
0226 
0227     return e;
0228 }
0229 
0230 void KoDocumentInfo::updateParametersAndBumpNumCycles()
0231 {
0232     KisDocument *doc = dynamic_cast< KisDocument *>(parent());
0233     if (doc && doc->isAutosaving()) {
0234         return;
0235     }
0236 
0237     setAboutInfo("editing-cycles", QString::number(aboutInfo("editing-cycles").toInt() + 1));
0238     setAboutInfo("date", QDateTime::currentDateTime().toString(Qt::ISODate));
0239 
0240     updateParameters();
0241 }
0242 
0243 void KoDocumentInfo::updateParameters()
0244 {
0245     KisDocument *doc = dynamic_cast< KisDocument *>(parent());
0246     if (doc && (!doc->isModified())) {
0247         return;
0248     }
0249 
0250     KConfig config("kritarc");
0251     config.reparseConfiguration();
0252     KConfigGroup appAuthorGroup(&config, "Author");
0253     QString profile = appAuthorGroup.readEntry("active-profile", "");
0254 
0255     QString authorInfo = KoResourcePaths::getAppDataLocation() + "/authorinfo/";
0256     QDir dir(authorInfo);
0257     QStringList filters = QStringList() << "*.authorinfo";
0258 
0259     //Anon case
0260     setActiveAuthorInfo("creator", QString());
0261     setActiveAuthorInfo("initial", "");
0262     setActiveAuthorInfo("author-title", "");
0263     setActiveAuthorInfo("position", "");
0264     setActiveAuthorInfo("company", "");
0265     if (dir.entryList(filters).contains(profile+".authorinfo")) {
0266         QFile file(dir.absoluteFilePath(profile+".authorinfo"));
0267         if (file.exists()) {
0268             file.open(QFile::ReadOnly);
0269             QByteArray ba = file.readAll();
0270             file.close();
0271             QDomDocument doc = QDomDocument();
0272             doc.setContent(ba);
0273             QDomElement root = doc.firstChildElement();
0274 
0275             QDomElement el = root.firstChildElement("nickname");
0276             if (!el.isNull()) {
0277                 setActiveAuthorInfo("creator", el.text());
0278             }
0279             el = root.firstChildElement("givenname");
0280             if (!el.isNull()) {
0281                 setActiveAuthorInfo("creator-first-name", el.text());
0282             }
0283             el = root.firstChildElement("middlename");
0284             if (!el.isNull()) {
0285                 setActiveAuthorInfo("initial", el.text());
0286             }
0287             el = root.firstChildElement("familyname");
0288             if (!el.isNull()) {
0289                setActiveAuthorInfo("creator-last-name", el.text());
0290             }
0291             el = root.firstChildElement("title");
0292             if (!el.isNull()) {
0293                 setActiveAuthorInfo("author-title", el.text());
0294             }
0295             el = root.firstChildElement("position");
0296             if (!el.isNull()) {
0297                 setActiveAuthorInfo("position", el.text());
0298             }
0299             el = root.firstChildElement("company");
0300             if (!el.isNull()) {
0301                 setActiveAuthorInfo("company", el.text());
0302             }
0303 
0304             m_contact.clear();
0305             el = root.firstChildElement("contact");
0306             while (!el.isNull()) {
0307                 m_contact.insert(el.text(), el.attribute("type"));
0308                 el = el.nextSiblingElement("contact");
0309             }
0310         }
0311     }
0312 
0313     //allow author info set programmatically to override info from author profile
0314     Q_FOREACH (const QString &tag, m_authorTags) {
0315         if (m_authorInfoOverride.contains(tag)) {
0316             setActiveAuthorInfo(tag, m_authorInfoOverride.value(tag));
0317         }
0318     }
0319 }
0320 
0321 void KoDocumentInfo::resetMetaData()
0322 {
0323     setAboutInfo("editing-cycles", QString::number(0));
0324     setAboutInfo("initial-creator", authorInfo("creator"));
0325     setAboutInfo("creation-date", QDateTime::currentDateTime().toString(Qt::ISODate));
0326     setAboutInfo("editing-time", QString::number(0));
0327 }
0328 
0329 QString KoDocumentInfo::originalGenerator() const
0330 {
0331     return m_generator;
0332 }
0333 
0334 void KoDocumentInfo::setOriginalGenerator(const QString &generator)
0335 {
0336     m_generator = generator;
0337 }