Warning, file /office/calligra/libs/kross/KoScriptingOdf.h was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001 /*************************************************************************** 0002 * KoScriptingOdf.h 0003 * This file is part of the KDE project 0004 * copyright (C) 2007 Sebastian Sauer <mail@dipe.org> 0005 * 0006 * This program 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 program 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 program; see the file COPYING. If not, write to 0018 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 0019 * Boston, MA 02110-1301, USA. 0020 ***************************************************************************/ 0021 0022 #ifndef KOSCRIPTINGODF_H 0023 #define KOSCRIPTINGODF_H 0024 0025 #include <QPair> 0026 #include <KoXmlReader.h> 0027 #include <KoDocument.h> 0028 0029 class KoScriptingOdfStore; 0030 class KoPartAdaptor; 0031 0032 /** 0033 * The KoScriptingOdfReader provides functionality to read content 0034 * from a KoStore. 0035 * 0036 * The following python samples does open the content.xml file and 0037 * reads all text:p elements from it; 0038 * \code 0039 * import Kross, Words 0040 * Words.document().openUrl("/home/kde4/testDoc.odt") 0041 * reader = Words.store().open("META-INF/manifest.xml") 0042 * reader = store.open("content.xml") 0043 * def onElement(): 0044 * if reader.name() != "text:p": 0045 * raise "This should never happen cause of the filter" 0046 * print "%s %s" % (reader.level(),reader.attributeNames()) 0047 * reader.connect("onElement()", onElement) 0048 * reader.setNameFilter("text:p") 0049 * reader.start() 0050 * \endcode 0051 */ 0052 class KoScriptingOdfReader : public QObject 0053 { 0054 Q_OBJECT 0055 public: 0056 /** Constructor. */ 0057 explicit KoScriptingOdfReader(KoScriptingOdfStore *store, const KoXmlDocument &doc); 0058 /** Destructor. */ 0059 ~KoScriptingOdfReader() override; 0060 /** Return the KoScriptingOdfStore instance this reader belongs to. */ 0061 KoScriptingOdfStore *store() const; 0062 /** Return the KoXmlDocument instance this reader operates on. */ 0063 KoXmlDocument doc() const; 0064 /** Return the current element. */ 0065 KoXmlElement currentElement() const; 0066 0067 public Q_SLOTS: 0068 0069 /** 0070 * Return the element tag-name filter that will be applied on reading. 0071 */ 0072 QString nameFilter() const; 0073 0074 /** 0075 * Set the element tag-name filter that will be applied on reading. 0076 * 0077 * This python sample demonstrates usage of the setNameFilter()-method; 0078 * \code 0079 * # Only handle text:p elements. 0080 * reader.setNameFilter("text:p") 0081 * 0082 * # Use a regular expression for the tag-name. 0083 * reader.setNameFilter(".*:p", True) 0084 * \endcode 0085 */ 0086 void setNameFilter(const QString &name = QString(), bool regularExpression = false); 0087 0088 //QString levelFilter() const; 0089 //void setLevelFilter(const QString &name = QString()) const; 0090 0091 /** 0092 * Start the reading. 0093 * 0094 * This will fire up the whole reading process. We walk through 0095 * all elements and emit the onElement() signal or other signals 0096 * for each element we are interested in. 0097 */ 0098 void start(); 0099 0100 /** 0101 * Return the tag-name of the current element. This could be 0102 * e.g. "office:text", "style:style" or "text:p". 0103 */ 0104 QString name() const; 0105 0106 /** 0107 * The namespace of the element. For example "office:document-content". 0108 */ 0109 QString namespaceURI() const; 0110 0111 //QString prefix() const { return m_currentElement.prefix(); } 0112 //QString localName() const { return m_currentElement.localName(); } 0113 0114 /** 0115 * The level the element is on. Elements may nested and the level is 0116 * a number that defines how much elements are around this element. 0117 * The root-element has a level of 0, direct children of the 0118 * root-element have a level of 1, there children of 2, etc. 0119 */ 0120 int level() const; 0121 #ifndef KOXML_USE_QDOM 0122 /** 0123 * Return a list of attribute-names the element has. This could be 0124 * for example "text:style-name". 0125 */ 0126 QStringList attributeNames(); 0127 #endif 0128 0129 /** 0130 * Return the value of the attribute with the name \p name . 0131 */ 0132 QString attribute(const QString &name, const QString &defaultValue = QString()) const; 0133 0134 /** 0135 * Return the value of the attribute with the name \p name that is within 0136 * the namespace \p namespaceURI . 0137 */ 0138 QString attributeNS(const QString &namespaceURI, const QString &localName, const QString &defaultValue = QString()) const; 0139 0140 /** 0141 * Returns true if the current element has an attribute with name \p name. 0142 */ 0143 bool hasAttribute(const QString &name) const; 0144 0145 /** 0146 * Returns true if the current element has an attribute with name \p name that 0147 * is within the namespace \p namespaceURI . 0148 */ 0149 bool hasAttributeNS(const QString &namespaceURI, const QString &localName) const; 0150 0151 /** 0152 * Returns true if the current element is invalid. 0153 */ 0154 bool isNull() const; 0155 0156 /** 0157 * Return true if the current element is an element. 0158 */ 0159 bool isElement() const; 0160 0161 //bool isText() const; 0162 //bool isCDATASection() const { return m_currentElement.isCDATASection(); } 0163 //bool isDocument() const { return m_currentElement.isDocument(); } 0164 //QString toText() const { return m_currentElement.toText().data(); } 0165 //KoXmlCDATASection toCDATASection() const; 0166 0167 /** 0168 * Return true if the current element has child nodes. Please note, that 0169 * text-nodes are not counted as children by this method. Fetch any text 0170 * by using the text() method which will return an empty string if there 0171 * is actually no text. 0172 */ 0173 bool hasChildren() const; 0174 0175 /** 0176 * Return the content of the element as string. 0177 */ 0178 QString text() const; 0179 0180 Q_SIGNALS: 0181 0182 /** 0183 * This signal got emitted after start() was called for each 0184 * element we read. 0185 */ 0186 void onElement(); 0187 0188 protected: 0189 /** Emit the onElement signal above. */ 0190 void emitOnElement(); 0191 /** Set the current element. */ 0192 void setCurrentElement(const KoXmlElement &elem); 0193 /** Set the level. */ 0194 void setLevel(int level); 0195 /** Element-handler. */ 0196 virtual void handleElement(KoXmlElement &elem, int level = 0); 0197 0198 private: 0199 KoScriptingOdfStore *m_store; 0200 KoXmlDocument m_doc; 0201 KoXmlElement m_currentElement; 0202 int m_level; 0203 QString m_filter; 0204 QRegExp m_filterRegExp; 0205 }; 0206 0207 /** 0208 * The KoScriptingOdfManifestReader class handles reading ODF META-INF/manifest.xml files. 0209 * 0210 * The following python sample script does use the Words scripting module to load a 0211 * ISO OpenDocument Text file and print the content of the manifest-file to stdout; 0212 * \code 0213 * import Kross, Words 0214 * Words.document().openUrl("/home/kde4/testDoc.odt") 0215 * reader = Words.store().open("META-INF/manifest.xml") 0216 * if not reader: 0217 * raise "Failed to read the mainfest" 0218 * for i in range( reader.count() ): 0219 * print "%s %s" % (reader.type(i),reader.path(i)) 0220 * \endcode 0221 */ 0222 class KoScriptingOdfManifestReader : public KoScriptingOdfReader 0223 { 0224 Q_OBJECT 0225 public: 0226 /** Constructor. */ 0227 KoScriptingOdfManifestReader(KoScriptingOdfStore *store, const KoXmlDocument &doc); 0228 /** Destructor. */ 0229 ~KoScriptingOdfManifestReader() override {} 0230 0231 public Q_SLOTS: 0232 /** Returns the number of file-entries the manifest has. */ 0233 int count() const { 0234 return m_entries.count(); 0235 } 0236 /** Returns the type of the file-entry. This could be for example 0237 something like "text/xml" or "application/vnd.oasis.opendocument.text" */ 0238 QString type(int index) { 0239 return m_entries.value(index).first; 0240 } 0241 /** Return the path of the file-entry. This could be for example 0242 something like "/", "content.xml" or "styles.xml". */ 0243 QString path(int index) { 0244 return m_entries.value(index).second; 0245 } 0246 /** 0247 * Return a list of paths for the defined type. If not type is defined 0248 * just all paths are returned. 0249 * 0250 * Python sample that does use the paths-method; 0251 * \code 0252 * # Following may print ['/','content.xml','styles.xml'] 0253 * print reader.paths() 0254 * 0255 * # Following may print ['content.xml','styles.xml'] 0256 * print reader.paths("text/xml") 0257 * \endcode 0258 */ 0259 QStringList paths(const QString &type = QString()) const; 0260 private: 0261 QList<QPair<QString,QString> > m_entries; 0262 }; 0263 0264 /** 0265 * The KoScriptingOdfManifestReader class handles reading ODF styles.xml files. 0266 */ 0267 class KoScriptingOdfStylesReader : public KoScriptingOdfReader 0268 { 0269 Q_OBJECT 0270 public: 0271 /** Constructor. */ 0272 KoScriptingOdfStylesReader(KoScriptingOdfStore *store, const KoXmlDocument &doc); 0273 /** Destructor. */ 0274 ~KoScriptingOdfStylesReader() override {} 0275 public Q_SLOTS: 0276 //QString style(const QString &styleName); 0277 }; 0278 0279 /** 0280 * The KoScriptingOdfManifestReader class handles reading ODF content.xml files. 0281 */ 0282 class KoScriptingOdfContentReader : public KoScriptingOdfReader 0283 { 0284 Q_OBJECT 0285 public: 0286 /** Constructor. */ 0287 KoScriptingOdfContentReader(KoScriptingOdfStore *store, const KoXmlDocument &doc); 0288 /** Destructor. */ 0289 ~KoScriptingOdfContentReader() override {} 0290 public Q_SLOTS: 0291 //QStringList headers(const QString &filter); 0292 //QStringList lists(const QString &filter); 0293 //QStringList images(const QString &filter); 0294 //QStringList tables(const QString &filter); 0295 }; 0296 0297 /** 0298 * The KoScriptingOdfStore class provides access to the KoStore functionality. 0299 * 0300 * The following python sample does use Words do read a ODT document and then 0301 * flushes the DOM tree to stdout. 0302 * \code 0303 * import Kross 0304 * Words = Kross.module("words") 0305 * 0306 * # Get the Words KoApplicationAdaptor instance. 0307 * docAdaptor = Words.document() 0308 * # Open an ISO OpenDocument Text File. 0309 * docAdaptor.openUrl("/home/kde4/testDoc.odt") 0310 * 0311 * # Get a KoStore instance. 0312 * store = Words.store() 0313 * # Open the content.xml file within the KoStore. 0314 * reader = store.open("content.xml") 0315 * if not reader: 0316 * raise "Failed to read file from the store" 0317 * 0318 * # This function got called for each element 0319 * def onElement(name, level): 0320 * print "ELEMENT name=%s level=%s" % (name, level) 0321 * # Connect our callback function with the reader. 0322 * reader.connect("onElement(QString,int)", onElement) 0323 * 0324 * # Start the reading. 0325 * reader.start() 0326 * \endcode 0327 */ 0328 class KoScriptingOdfStore : public QObject 0329 { 0330 Q_OBJECT 0331 public: 0332 /** Constructor. */ 0333 explicit KoScriptingOdfStore(QObject *parent, KoDocument *doc); 0334 /** Destructor. */ 0335 ~KoScriptingOdfStore() override; 0336 0337 //KoStore* readStore() const; 0338 //QIODevice* readDevice() const; 0339 0340 public Q_SLOTS: 0341 0342 /** 0343 * Returns true if there exists a file with the defined name 0344 * \p fileName in the store else false is returned. 0345 * 0346 * The following python sample does use the hasFile-method; 0347 * \code 0348 * if not store.hasFile("content.xml"): 0349 * raise "No content.xml file within the store." 0350 * if not store.hasFile("tar:/META-INF/manifest.xml"): 0351 * raise "No manifest.xml file within the store." 0352 * \endcode 0353 */ 0354 bool hasFile(const QString &fileName); 0355 0356 /** 0357 * Returns true if the store is already opened else false 0358 * got returned. The store does allow to open and deal 0359 * with maximal one file the same time. 0360 */ 0361 bool isOpen() const; 0362 0363 /** 0364 * Open the file with the defined name \p fileName and 0365 * return a \a KoScriptingOdfReader object if the file 0366 * was open successful else NULL (aka no object) got 0367 * returned. 0368 * 0369 * If the store is already opened, it got closed before 0370 * we try to open the new file. This means, that all 0371 * previous \a KoScriptingOdfReader instances are 0372 * invalid and that only the last one returned by using 0373 * the open-method is valid till closed. 0374 * 0375 * The following python sample does use the open-method; 0376 * \code 0377 * # Fetch a reader for the styles.xml file. 0378 * stylesReader = store.open("styles.xml") 0379 * if not stylesReader: 0380 * raise "Failed to read styles" 0381 * 0382 * # Now fetch a reader for the manifest. Please note, 0383 * # that stylesReader.close() is implicit done here. 0384 * manifestReader = store.open("META-INF/manifest.xml") 0385 * if not manifestReader: 0386 * raise "Failed to read mainfest" 0387 * \endcode 0388 */ 0389 QObject* open(const QString &fileName); 0390 0391 /** 0392 * Closes the store if it's opened. If the store was not opened 0393 * or got closed successful true is returned. 0394 */ 0395 bool close(); 0396 0397 /** 0398 * Extract the content of the file named \p fileName and return 0399 * it as an array of bytes. 0400 */ 0401 QByteArray extract(const QString &fileName); 0402 0403 /** 0404 * Extract the content of the file named \p fileName to the defined 0405 * target-file \p toFileName and return true on success. 0406 */ 0407 bool extractToFile(const QString &fileName, const QString &toFileName); 0408 0409 //QStringList directories(); 0410 //bool hasDirectory(const QString &directoryName); 0411 //QString currentDirectory(); 0412 //bool changeDirectory(const QString &directoryName); 0413 0414 /** 0415 * Returns the document the store is the backend for. 0416 */ 0417 QObject *document() const; 0418 0419 /** 0420 * Set the document the store is the backend for. This could 0421 * be a \a KoPartAdaptor or a \a KoDocument object. 0422 */ 0423 bool setDocument(QObject *document); 0424 0425 //void setFilter(const QString &filter) {} 0426 //void start() {} 0427 0428 Q_SIGNALS: 0429 0430 //void onElement(); 0431 //void onHeader(); 0432 //void onParagraph(); 0433 0434 private: 0435 KoStore *getReadStore(); 0436 QByteArray getByteArray(); 0437 QByteArray getMimeType() const; 0438 0439 QPointer<KoDocument> m_document; 0440 QPointer<KoPartAdaptor> m_documentAdaptor; 0441 0442 KoStore *m_readStore; 0443 QIODevice *m_readDevice; 0444 KoScriptingOdfReader *m_reader; 0445 QByteArray m_byteArray; 0446 }; 0447 0448 0449 0450 #endif