File indexing completed on 2025-02-16 05:22:20
0001 /*************************************************************************** 0002 odfplugin.cpp - description 0003 ------------------- 0004 begin : Wed June 20th 2018 0005 copyright : (C) 2018 by Friedrich W. H. Kossebau 0006 email : kossebau@kde.org 0007 ***************************************************************************/ 0008 0009 /*************************************************************************** 0010 * * 0011 * This program is free software; you can redistribute it and/or modify * 0012 * it under the terms of the GNU General Public License as published by * 0013 * the Free Software Foundation; either version 2 of the License, or * 0014 * (at your option) any later version. * 0015 * * 0016 ***************************************************************************/ 0017 0018 #include "odfplugin.h" 0019 0020 #include "batchrenamer.h" 0021 #include "tokenhelpdialog.h" 0022 // KF 0023 #include <KZip> 0024 // Qt 0025 #include <QDomDocument> 0026 #include <QDebug> 0027 0028 namespace { 0029 inline QString dcNS() { return QStringLiteral("http://purl.org/dc/elements/1.1/"); } 0030 inline QString metaNS() { return QStringLiteral("urn:oasis:names:tc:opendocument:xmlns:meta:1.0"); } 0031 inline QString officeNS() { return QStringLiteral("urn:oasis:names:tc:opendocument:xmlns:office:1.0"); } 0032 0033 QString createHelpString(const QString &tokenId, const QString &description) 0034 { 0035 return QLatin1Char('[') + tokenId + QLatin1Char(']') + TokenHelpDialog::getTokenSeparator() + description; 0036 } 0037 0038 QDomElement namedItemNS(const QDomNode &node, const QString &nsURI, const QString &localName) 0039 { 0040 for (auto n = node.firstChildElement(); !n.isNull(); n = n.nextSiblingElement()) { 0041 if (n.localName() == localName && n.namespaceURI() == nsURI) { 0042 return n; 0043 } 0044 } 0045 0046 return QDomElement(); 0047 } 0048 } 0049 0050 0051 OdfPlugin::OdfPlugin(PluginLoader *loader) 0052 : FilePlugin(loader) 0053 , m_creatorToken("odfCreator") 0054 , m_keywordsToken("odfKeywords") 0055 , m_subjectToken("odfSubject") 0056 , m_titleToken("odfTitle") 0057 , m_generatorToken("odfGenerator") 0058 , m_languageToken("odfLanguage") 0059 , m_pageCountToken("odfPageCount") 0060 , m_wordCountToken("odfWordCount") 0061 { 0062 m_name = i18n("OpenDocument Format (ODT, ODS, ODP) Plugin"); 0063 m_comment = i18n("<qt>This plugin supports reading metadata from " 0064 "files in an OpenDocument format.</qt>"); 0065 0066 // there is no generic ODF icon, so use the text one for now 0067 m_icon = "application-vnd.oasis.opendocument.text"; 0068 0069 addSupportedToken(m_creatorToken); 0070 addSupportedToken(m_keywordsToken); 0071 addSupportedToken(m_subjectToken); 0072 addSupportedToken(m_titleToken); 0073 addSupportedToken(m_generatorToken); 0074 addSupportedToken(m_languageToken); 0075 addSupportedToken(m_pageCountToken); 0076 addSupportedToken(m_wordCountToken); 0077 0078 m_help = QStringList { 0079 createHelpString(m_creatorToken, i18n("Creator of the ODF file")), 0080 createHelpString(m_keywordsToken, i18n("Keywords of the ODF file")), 0081 createHelpString(m_subjectToken, i18n("Subject of the ODF file")), 0082 createHelpString(m_titleToken, i18n("Title of the ODF file")), 0083 createHelpString(m_generatorToken, i18n("Generator of the ODF file")), 0084 createHelpString(m_languageToken, i18n("Language of the ODF file")), 0085 createHelpString(m_pageCountToken, i18n("Number of pages in the ODF file")), 0086 createHelpString(m_wordCountToken, i18n("Number of words in the ODF file")), 0087 }; 0088 0089 // prepare for case-insensitive comparison 0090 m_creatorToken = m_creatorToken.toLower(); 0091 m_keywordsToken = m_keywordsToken.toLower(); 0092 m_subjectToken = m_subjectToken.toLower(); 0093 m_titleToken = m_titleToken.toLower(); 0094 m_generatorToken = m_generatorToken.toLower(); 0095 m_languageToken = m_languageToken.toLower(); 0096 m_pageCountToken = m_pageCountToken.toLower(); 0097 m_wordCountToken = m_wordCountToken.toLower(); 0098 } 0099 0100 0101 QString OdfPlugin::processFile(BatchRenamer *b, int index, const QString &filenameOrToken, EPluginType) 0102 { 0103 const QString token = filenameOrToken.toLower(); 0104 0105 if (!supports(token)) { 0106 return QString(""); 0107 } 0108 0109 const QString filename = (*b->files())[index].srcUrl().path(); 0110 KZip zip(filename); 0111 if (!zip.open(QIODevice::ReadOnly)) { 0112 return QString(""); 0113 } 0114 0115 const KArchiveDirectory* directory = zip.directory(); 0116 if (!directory) { 0117 return QString(""); 0118 } 0119 0120 // we need a meta xml file in the archive! 0121 const auto metaXml = directory->entry(QStringLiteral("meta.xml")); 0122 if (!metaXml || !metaXml->isFile()) { 0123 return QString(""); 0124 } 0125 0126 QDomDocument metaDataDocument(QStringLiteral("metaData")); 0127 bool success = metaDataDocument.setContent(static_cast<const KArchiveFile*>(metaXml)->data(), true); 0128 if (!success) { 0129 return QString(""); 0130 } 0131 0132 // parse metadata .. 0133 QDomElement meta = namedItemNS(namedItemNS(metaDataDocument, 0134 officeNS(), QStringLiteral("document-meta")), 0135 officeNS(), QStringLiteral("meta")); 0136 0137 // Dublin Core 0138 if (token == m_subjectToken) { 0139 return namedItemNS(meta, dcNS(), QStringLiteral("subject")).text(); 0140 } 0141 if (token == m_titleToken) { 0142 return namedItemNS(meta, dcNS(), QStringLiteral("title")).text(); 0143 } 0144 if (token == m_creatorToken) { 0145 return namedItemNS(meta, dcNS(), QStringLiteral("creator")).text(); 0146 } 0147 if (token == m_languageToken) { 0148 return namedItemNS(meta, dcNS(), QStringLiteral("language")).text(); 0149 } 0150 0151 // Meta Properties 0152 if (token == m_keywordsToken) { 0153 return namedItemNS(meta, metaNS(), QStringLiteral("keyword")).text(); 0154 } 0155 if (token == m_generatorToken) { 0156 return namedItemNS(meta, metaNS(), QStringLiteral("generator")).text(); 0157 } 0158 0159 const QString attributeName = 0160 (token == m_pageCountToken) ? QStringLiteral("page-count") : 0161 (token == m_wordCountToken) ? QStringLiteral("word-count") : 0162 /* else */ QString(); 0163 0164 if (!attributeName.isEmpty()) { 0165 return namedItemNS(meta, metaNS(), QStringLiteral("document-statistic")).attributeNS(metaNS(), attributeName); 0166 } 0167 0168 return QString(""); 0169 } 0170 0171 const QStringList & OdfPlugin::help() const 0172 { 0173 return m_help; 0174 }