summaryrefslogtreecommitdiffstats
path: root/tools/tdefile-plugins/ooo
diff options
context:
space:
mode:
Diffstat (limited to 'tools/tdefile-plugins/ooo')
-rw-r--r--tools/tdefile-plugins/ooo/Makefile.am22
-rw-r--r--tools/tdefile-plugins/ooo/tdefile_ooo.cpp588
-rw-r--r--tools/tdefile-plugins/ooo/tdefile_ooo.desktop57
-rw-r--r--tools/tdefile-plugins/ooo/tdefile_ooo.h78
4 files changed, 745 insertions, 0 deletions
diff --git a/tools/tdefile-plugins/ooo/Makefile.am b/tools/tdefile-plugins/ooo/Makefile.am
new file mode 100644
index 00000000..8aa7d404
--- /dev/null
+++ b/tools/tdefile-plugins/ooo/Makefile.am
@@ -0,0 +1,22 @@
+## Makefile.am for OpenOffice.org file meta info plugin
+
+# set the include path for X, qt and KDE
+INCLUDES = $(KOFFICE_INCLUDES) $(all_includes)
+
+# these are the headers for your project
+noinst_HEADERS = tdefile_ooo.h
+
+kde_module_LTLIBRARIES = tdefile_ooo.la
+
+tdefile_ooo_la_SOURCES = tdefile_ooo.cpp
+tdefile_ooo_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN) -ltdecore -ltdeui $(LIB_QT) -lkjs -ltdefx -lkio -ltdeparts
+tdefile_ooo_la_LIBADD = $(KOFFICE_LIBS)
+
+# let automoc handle all of the meta source files (moc)
+METASOURCES = AUTO
+
+services_DATA = tdefile_ooo.desktop
+servicesdir = $(kde_servicesdir)
+
+messages:
+ $(XGETTEXT) *.cpp -o $(podir)/tdefile_ooo.pot
diff --git a/tools/tdefile-plugins/ooo/tdefile_ooo.cpp b/tools/tdefile-plugins/ooo/tdefile_ooo.cpp
new file mode 100644
index 00000000..358bc876
--- /dev/null
+++ b/tools/tdefile-plugins/ooo/tdefile_ooo.cpp
@@ -0,0 +1,588 @@
+/* This file is part of the KDE project
+ * Copyright (C) 2003 Pierre Souchay <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+/**
+ * CHANGES
+ * v1.7 to 1.9
+ * Added the editing duration analysis.
+ * v1.6 to 1.7
+ * Changed the incorrect meta:date to dc:date
+ * Now parse date instead of simply print the ISO date
+ * Fixes bug with keywords, now properly handled
+ * Changed the deprecated upload method to the new one.
+ * v1.5 to 1.6
+ * Correction for bug 68112: http://bugs.kde.org/show_bug.cgi?id=68112
+ * OOo 1.1 does not support garbages in zip files. We now recreate the zip
+ * file from scratch. It is slower, but we don't have the choice :(
+ * v1.1 to v1.2
+ * Added support for KFileMimeTypeInfo::Hints (Name, Author, Description)
+ * Added some Advanced Attributes and Statistics according to DTD of OOo
+ * No more duplicated strings of same contents to facilitate changes
+ */
+
+#include <config.h>
+#include "tdefile_ooo.h"
+
+#include <klocale.h>
+#include <kgenericfactory.h>
+#include <KoStore.h>
+#include <KoStoreDevice.h>
+#include <kzip.h>
+#include <ktempfile.h>
+#include <tqptrstack.h>
+
+#include <tqdom.h>
+#include <tqfile.h>
+#include <tqdatetime.h>
+#include <tqvalidator.h>
+#include <kdebug.h>
+#include <tdeio/netaccess.h>
+
+typedef KGenericFactory<KOfficePlugin> KOfficeFactory;
+
+K_EXPORT_COMPONENT_FACTORY(tdefile_ooo, KOfficeFactory( "tdefile_ooo" ))
+
+static const char * const mimetypes[] =
+{ "application/vnd.sun.xml.calc", "application/vnd.sun.xml.calc.template",
+ "application/vnd.sun.xml.draw", "application/vnd.sun.xml.draw.template",
+ "application/vnd.sun.xml.impress","application/vnd.sun.xml.impress.template",
+ "application/vnd.sun.xml.writer", "application/vnd.sun.xml.writer.global",
+ "application/vnd.sun.xml.writer.math",
+ "application/vnd.sun.xml.writer.template",
+ "application/vnd.oasis.opendocument.chart",
+ "application/vnd.oasis.opendocument.formula",
+ "application/vnd.oasis.opendocument.graphics",
+ "application/vnd.oasis.opendocument.graphics-template",
+ "application/vnd.oasis.opendocument.presentation",
+ "application/vnd.oasis.opendocument.presentation-template",
+ "application/vnd.oasis.opendocument.spreadsheet",
+ "application/vnd.oasis.opendocument.spreadsheet-template",
+ "application/vnd.oasis.opendocument.text",
+ "application/vnd.oasis.opendocument.text-template",
+ 0};
+
+static const char * const Advanced[] =
+ {
+ "meta:printed-by" , I18N_NOOP("Printed By"),
+ "meta:print-date" , I18N_NOOP("Print Date"),
+ "dc:date" , I18N_NOOP("Date"),
+ "meta:creation-date" , I18N_NOOP("Creation Date"),
+ "meta:initial-creator", I18N_NOOP("Creator"),
+ "meta:generator" , I18N_NOOP("Generator"),
+ "meta:editing-cycles" , I18N_NOOP("Editing Cycles"),
+ "meta:editing-duration" , I18N_NOOP("Editing Duration"),
+ 0};
+
+static const char * dclanguage = "dc:language";
+
+static const char * const Information[] =
+ {"dc:title" , I18N_NOOP("Title") ,
+ "dc:creator" , I18N_NOOP("Author") ,
+ "dc:description", I18N_NOOP("Description"),
+ "dc:subject" , I18N_NOOP("Subject") ,
+ dclanguage , I18N_NOOP("Language") ,
+ 0};
+
+static const char * const Statistics[] =
+ {"meta:draw-count" , I18N_NOOP("Draws"),
+ "meta:table-count" , I18N_NOOP("Tables"),
+ "meta:image-count" , I18N_NOOP("Images"),
+ "meta:object-count" , I18N_NOOP("Objects"),
+ "meta:ole-object-count", I18N_NOOP("OLE Objects"),
+ "meta:page-count" , I18N_NOOP("Pages"),
+ "meta:paragraph-count" , I18N_NOOP("Paragraphs"),
+ "meta:word-count" , I18N_NOOP("Words"),
+ "meta:cell-count" , I18N_NOOP("Cells"),
+ "meta:character-count" , I18N_NOOP("Characters"),
+ "meta:row-count" , I18N_NOOP("Rows"),
+ 0};
+
+static const char * metakeywords = "meta:keywords";
+static const char * metakeyword = "meta:keyword" ;
+static const char * DocumentInfo = "DocumentInfo" ;
+static const char * UserDefined = "UserDefined" ;
+static const char * DocAdvanced = "Advanced" ;
+static const char * DocStatistics = "Statistics" ;
+static const char * metadocstat = "meta:document-statistic";
+static const char * metaname = "meta:name" ;
+static const char * metauserdef = "meta:user-defined";
+static const char * metafile = "meta.xml" ;
+KOfficePlugin::KOfficePlugin(TQObject *parent, const char *name,
+ const TQStringList &args)
+
+ : KFilePlugin(parent, name, args)
+{
+ int i = 0;
+ while (mimetypes[i])
+ makeMimeTypeInfo( mimetypes[i++] );
+}
+
+void KOfficePlugin::makeMimeTypeInfo(const TQString& mimeType)
+{
+ KFileMimeTypeInfo* info = addMimeTypeInfo( mimeType );
+
+ userdefined = addGroupInfo(info, UserDefined, i18n("User Defined"));
+ addVariableInfo(userdefined, TQVariant::String,
+ KFileMimeTypeInfo::Addable |
+ KFileMimeTypeInfo::Removable |
+ KFileMimeTypeInfo::Modifiable);
+
+ KFileMimeTypeInfo::GroupInfo* group = 0L;
+ group = addGroupInfo(info, DocumentInfo, i18n("Document Information"));
+ KFileMimeTypeInfo::ItemInfo* item;
+ int i = 0;
+ for (i = 0; Information[i]; i+=2){
+ item = addItemInfo(group, Information[i], i18n(Information[i+1]),
+ TQVariant::String);
+ setAttributes(item, KFileMimeTypeInfo::Modifiable);
+ switch (i){
+ case 0:
+ setHint(item, KFileMimeTypeInfo::Name);
+ break;
+ case 1:
+ setHint(item, KFileMimeTypeInfo::Author);
+ break;
+ case 2:
+ setHint(item, KFileMimeTypeInfo::Description);
+ default:;
+ }
+ }
+
+ item = addItemInfo(group, metakeyword, i18n("Keywords"),
+ TQVariant::String);
+ setHint(item, KFileMimeTypeInfo::Description);
+ setAttributes(item, KFileMimeTypeInfo::Modifiable);
+
+ group = addGroupInfo(info, DocAdvanced, i18n("Document Advanced"));
+ for (i = 0; Advanced[i]; i+=2){
+ // I should add the isDate property instead of testing the index, but it works well, who cares ? :-)
+ TQVariant::Type typ = TQVariant::String;
+ if (i > 1 && i < 8)
+ typ = TQVariant::DateTime;
+ if (i == 14)
+ typ = TQVariant::String;
+ item = addItemInfo(group, Advanced[i], i18n(Advanced[i+1]), typ);
+ setHint(item, KFileMimeTypeInfo::Description);
+ }
+
+ group = addGroupInfo(info, DocStatistics, i18n("Document Statistics"));
+ for (i = 0; Statistics[i]; i+=2){
+ item = addItemInfo(group, Statistics[i], i18n(Statistics[i+1]),
+ TQVariant::Int);
+ setHint(item, KFileMimeTypeInfo::Length);
+ }
+}
+
+/**
+ * Gets a number in the string and update the position next character which
+ * is not a number
+ * @param str The string to check
+ * @param the position to start to, updated to the next character NAN
+ * @return the number parsed, 0 if number was not valid
+ */
+int getNumber(TQString &str, int * pos){
+ int k = *pos;
+ for (int len = str.length() ;
+ str.at(k).isNumber() && k < len ;
+ k++);
+ bool result = false;
+ int num = str.mid( *pos, k-(*pos)).toInt(&result);
+ *pos = k;
+ if (!result)
+ return 0;
+ return num;
+}
+
+void KOfficePlugin::getEditingTime(KFileMetaInfoGroup group1,
+ const char * labelid, TQString & txt){
+ TQString t;
+ int days = 0;
+ int hours = 0;
+ int minutes = 0;
+ int seconds = 0;
+ if (txt.at(0) != 'P'){
+ kdDebug(7034) << labelid << "=" << txt <<
+ " does not seems to be a valid duration" << endl;
+ return;
+ }
+ int pos = 1;
+ if (txt.at(pos).isNumber()){
+ days = getNumber(txt, &pos);
+ if (txt.at(pos++)!='D'){
+ days=0;
+ kdDebug(7034) << labelid <<
+ " First arg was not a day in " << txt << endl;
+ }
+ }
+ if (txt.at(pos)!= 'T'){
+ kdDebug(7034) << labelid << "=" << txt <<
+ " does not seems to contain time information" << endl;
+ return;
+ }
+ pos++;
+ int len = txt.length();
+ while (pos < len){
+ int res = getNumber(txt, &pos);
+ if (pos >= len)
+ return;
+ switch (txt.at(pos).latin1()) {
+ case 'H':
+ hours = res;
+ break;
+ case 'M':
+ minutes = res;
+ break;
+ case 'S':
+ seconds = res;
+ break;
+ default:
+ kdDebug(7034) << "Unknown unit at pos " << pos << " while parsing " <<
+ labelid << "="<< txt << endl;
+ }
+ pos++;
+ }
+ hours += days * 24;
+ appendItem(group1, labelid,
+ i18n("%1:%2.%3").arg(hours).arg(minutes, 2).arg(seconds,2 ));
+}
+
+void KOfficePlugin::getDateTime(KFileMetaInfoGroup group1,
+ const char * labelid, TQString & txt)
+{
+ TQDateTime dt = TQDateTime::fromString( txt, Qt::ISODate);
+ appendItem( group1, labelid, dt);
+}
+
+bool KOfficePlugin::readInfo( KFileMetaInfo& info, uint /*what*/)
+{
+ if ( info.path().isEmpty() ) // remote file
+ return false;
+
+ KFileMetaInfoGroup group = appendGroup(info, DocumentInfo);
+ TQDomDocument doc = getMetaDocument(info.path());
+ if (doc.isNull())
+ return false;
+ TQDomElement base = getBaseNode(doc).toElement();
+ if (base.isNull())
+ return false;
+ for (int i = 0; Information[i]; i+=2)
+ appendItem(group, Information[i],
+ stringFromNode(base, Information[i]));
+ // Special case for keyword
+ TQDomNodeList keywordList = base.elementsByTagName( metakeyword );
+ TQString allKeywords;
+ for (uint i = 0; i < keywordList.length(); i++){
+ TQDomNode node = keywordList.item(i);
+ if (node.isElement()){
+ if (i>0)
+ allKeywords += ", ";
+ allKeywords += node.toElement().text();
+ }
+ }
+ appendItem(group, metakeyword,
+ allKeywords);
+
+ KFileMetaInfoGroup group1 = appendGroup(info, DocAdvanced);
+ for (int i = 0; Advanced[i]; i+=2){
+ TQString txt = stringFromNode(base, Advanced[i]);
+ if (!txt.isEmpty()){
+ // A silly way to do it...
+ switch (i){
+ case 2:
+ case 4:
+ case 6:
+ getDateTime(group1, Advanced[i], txt);
+ break;
+ case 14:
+ getEditingTime(group1, Advanced[i], txt);
+ break;
+ default:
+ appendItem(group1, Advanced[i], txt);}
+ }
+ }
+
+ TQDomNode dstat = base.namedItem(metadocstat);
+
+ KFileMetaInfoGroup group2 = appendGroup(info, DocStatistics);
+ if (!dstat.isNull() && dstat.isElement()){
+ TQDomElement dinfo = dstat.toElement();
+ for (int i = 0; Statistics[i]; i+=2)
+ addAttributeInfo(dinfo, group2, Statistics[i] );
+ }
+
+
+ TQDomNodeList userList = base.elementsByTagName( metauserdef );
+
+ KFileMetaInfoGroup groupuser = appendGroup(info, UserDefined);
+
+ for (uint i = 0; i < userList.length(); i++){
+ TQDomNode node = userList.item(i);
+ if (node.isElement()){
+ appendItem(groupuser,
+ node.toElement().attribute(metaname,
+ TQString("User %1").arg(i)),
+ node.toElement().text());
+ }
+ }
+ return true;
+}
+
+TQString KOfficePlugin::stringFromNode(const TQDomNode &node, const TQString &name)
+{
+ TQString value = node.namedItem(name).toElement().text();
+ return value.isEmpty() ? TQString() : value;
+}
+
+void KOfficePlugin::addAttributeInfo(const TQDomElement & elem, KFileMetaInfoGroup & group, const TQString &attributeName)
+{
+ if (!elem.hasAttribute(attributeName)){
+ return;
+ }
+ TQString m_attribute = elem.attribute(attributeName, "0");
+ if (m_attribute == "0")
+ return;
+ appendItem(group, attributeName, m_attribute);
+}
+
+bool KOfficePlugin::writeTextNode(TQDomDocument & doc,
+ TQDomNode & parentNode,
+ const TQString &nodeName,
+ const TQString &value) const
+{
+ if (parentNode.toElement().isNull()){
+ kdDebug(7034) << "Parent node is Null or not an Element, cannot write node "
+ << nodeName << endl;
+ return false;
+ }
+
+ // If the node does not exist, we create it...
+ if (parentNode.namedItem(nodeName).isNull())
+ TQDomNode ex = parentNode.appendChild(doc.createElement(nodeName));
+
+ // Now, we are sure we have a node
+ TQDomElement nodeA = parentNode.namedItem(nodeName).toElement();
+
+ // Ooops... existing node were not of the good type...
+ if (nodeA.isNull()){
+ kdDebug(7034) << "Wrong type of node " << nodeName << ", should be Element"
+ << endl;
+ return false;
+ }
+
+ TQDomText txtNode = doc.createTextNode(value);
+
+ // If the node has already Text Child, we replace it.
+ if (nodeA.firstChild().isNull())
+ nodeA.appendChild(txtNode);
+ else
+ nodeA.replaceChild( txtNode, nodeA.firstChild());
+ return true;
+}
+
+bool KOfficePlugin::writeInfo( const KFileMetaInfo& info) const
+{
+ bool no_errors = true;
+ TQDomDocument doc = getMetaDocument(info.path());
+ TQDomElement base = getBaseNode(doc).toElement();
+ if (base.isNull())
+ return false;
+ for (int i = 0; Information[i]; i+=2)
+ no_errors = no_errors &&
+ writeTextNode(doc, base, Information[i],
+ info[DocumentInfo][Information[i]].value().toString());
+ // If we need a meta:keywords container, we create it.
+ if (base.namedItem(metakeywords).isNull())
+ base.appendChild(doc.createElement(metakeywords));
+ TQDomNode metaKeyNode = base.namedItem(metakeywords);
+
+ TQDomNodeList childs = doc.elementsByTagName(metakeyword);
+ for (int i = childs.length(); i >= 0; --i){
+ metaKeyNode.removeChild( childs.item(i) );
+ }
+ TQStringList keywordList = TQStringList::split(",", info[DocumentInfo][metakeyword].value().toString().stripWhiteSpace(), false);
+ for ( TQStringList::Iterator it = keywordList.begin(); it != keywordList.end(); ++it ) {
+ TQDomElement elem = doc.createElement(metakeyword);
+ metaKeyNode.appendChild(elem);
+ elem.appendChild(doc.createTextNode((*it).stripWhiteSpace()));
+ }
+
+ // Now, we store the user-defined data
+ TQDomNodeList theElements = base.elementsByTagName(metauserdef);
+ for (uint i = 0; i < theElements.length(); i++)
+ {
+ TQDomElement el = theElements.item(i).toElement();
+ if (el.isNull()){
+ kdDebug(7034) << metauserdef << " is not an Element" << endl;
+ no_errors = false;
+ }
+
+ TQString s = info[UserDefined][el.attribute(metaname)].value().toString();
+ if (s != el.text()){
+ TQDomText txt = doc.createTextNode(s);
+ if (!el.firstChild().isNull())
+ el.replaceChild(txt, el.firstChild());
+ else
+ el.appendChild(txt);
+ }
+ }
+
+ if (!no_errors){
+ kdDebug(7034) << "Errors were found while building " << metafile
+ << " for file " << info.path() << endl;
+ // It is safer to avoid to manipulate meta.xml if errors, we abort.
+ return false;
+ }
+ writeMetaData(info.path(), doc);
+ return true;
+}
+
+/**
+ * This function recreate a zip in dest with all files from src
+ * except meta.xml
+ */
+bool copyZipToZip( const KZip * src, KZip * dest)
+{
+ KArchiveDirectory * src_dir;
+ KArchiveFile * input_file;
+ TQPtrStack<KArchiveDirectory> src_dirStack ;
+ TQStringList dirEntries;
+ TQStringList curDirName;
+ TQStringList::Iterator it;
+ KArchiveEntry* curEntry;
+ TQString filename = TQString();
+
+ src_dirStack.push ( src->directory() );
+
+ do {
+ src_dir = src_dirStack.pop();
+ curDirName.append(src_dir->name());
+ dirEntries = src_dir->entries();
+
+ /* We now iterate over all entries and create entries in dest */
+ for ( it = dirEntries.begin(); it != dirEntries.end(); ++it ) {
+ if ( *it == metafile )
+ continue;
+ curEntry = src_dir->entry( *it );
+
+ if (curEntry->isFile()) {
+ input_file = dynamic_cast<KArchiveFile*>( curEntry );
+ TQByteArray b = input_file->data();
+ if (curDirName.isEmpty() || src_dir->name()=="/"){
+ filename = *it;
+ } else {
+ filename = curDirName.join("/") + "/" + *it;
+ }
+ dest->writeFile(filename , TQString(), TQString(), b.count(), b.data() );
+ } else
+ if (curEntry->isDirectory()) {
+ src_dirStack.push( dynamic_cast<KArchiveDirectory*>( curEntry ) );
+ }
+ else {
+ kdDebug(7034) << *it << " is a unknown type. Aborting." << endl;
+ return false;
+ }
+ }
+ curDirName.pop_back();
+ } while ( ! src_dirStack.isEmpty() );
+ return true;
+}
+
+bool KOfficePlugin::writeMetaData(const TQString & path,
+ const TQDomDocument &doc) const
+{
+ KTempFile tmp_file;
+ tmp_file.setAutoDelete(true);
+ KZip * m_zip = new KZip(tmp_file.name());
+ KZip * current= new KZip(path);
+ /* To correct problem with OOo 1.1, we have to recreate the file from scratch */
+ if (!m_zip->open(IO_WriteOnly) || !current->open(IO_ReadOnly) )
+ return false;
+ TQCString text = doc.toCString();
+ m_zip->setCompression(KZip::DeflateCompression);
+ if (!copyZipToZip(current, m_zip))
+ return false;
+ m_zip->writeFile(metafile, TQString(), TQString(),text.length(),
+ text);
+ delete current;
+ delete m_zip;
+ // NULL as third parameter is not good, but I don't know the Window ID
+ // That is only to avoid the deprecated warning at compile time
+ if (!TDEIO::NetAccess::upload( tmp_file.name(), KURL(path), NULL)){
+ kdDebug(7034) << "Error while saving " << tmp_file.name() << " as " << path << endl;
+ return false;
+ }
+ return true;
+}
+
+
+TQIODevice* KOfficePlugin::getData(KArchive &m_zip, int fileMode) const
+{
+
+ if ( !m_zip.open(fileMode) || !m_zip.directory())
+ return 0;
+
+ const KArchiveEntry* entry = m_zip.directory()->entry( metafile );
+ if (!entry || entry->isDirectory())
+ return 0;
+
+ const KZipFileEntry* f = static_cast<const KZipFileEntry *>(entry);
+ if (!f)
+ return 0;
+ return f->device();
+}
+
+TQDomDocument KOfficePlugin::getMetaDocument(const TQString &path) const
+{
+ TQDomDocument doc;
+ KZip m_zip(path);
+ TQIODevice * io = getData(m_zip, IO_ReadOnly);
+ if (!io || !io->isReadable())
+ return doc;
+ TQString errorMsg;
+ int errorLine, errorColumn;
+ if ( !doc.setContent( io, &errorMsg, &errorLine, &errorColumn ) ){
+ kdDebug(7034) << "Error " << errorMsg.latin1()
+ << "while getting XML content at line "
+ << errorLine << ", column "<< errorColumn << endl;
+ delete io;
+ return doc;
+ }
+ delete io;
+ return doc;
+}
+
+TQDomNode KOfficePlugin::getBaseNode(const TQDomDocument &doc) const
+{
+ return
+ doc.namedItem("office:document-meta").namedItem("office:meta");
+}
+
+TQValidator * KOfficePlugin::createValidator(const TQString &, /* mimetype */
+ const TQString & , /* group */
+ const TQString &key,
+ TQObject * parent,
+ const char * name ) const
+{
+ if (key == dclanguage)
+ return new TQRegExpValidator(TQRegExp("[a-zA-Z-]{1,5}"),
+ parent, name);
+ return 0;
+}
+
+#include "tdefile_ooo.moc"
diff --git a/tools/tdefile-plugins/ooo/tdefile_ooo.desktop b/tools/tdefile-plugins/ooo/tdefile_ooo.desktop
new file mode 100644
index 00000000..94866b74
--- /dev/null
+++ b/tools/tdefile-plugins/ooo/tdefile_ooo.desktop
@@ -0,0 +1,57 @@
+[Desktop Entry]
+Type=Service
+Name=OpenOffice.org Info
+Name[bg]=Информация за OpenOffice.org
+Name[br]=Titouriñ diwar-benn OpenOffice.org
+Name[ca]=Informació OpenOffice.org
+Name[cs]=OpenOffice.org info
+Name[cy]=Gwybodaeth OpenOffice.org
+Name[el]=Πληροφορίες OpenOffice.org
+Name[eo]=OpenOffice.org informo
+Name[es]=Información de OpenOffice.org
+Name[et]=OpenOffice.org-i info
+Name[eu]=OpenOffice.org-en informazioa
+Name[fa]=اطلاعات OpenOffice.org
+Name[fi]=OpenOffice.org-tiedot
+Name[fr]=Informations sur OpenOffice.org
+Name[fy]=OpenOffice.org ynfo
+Name[ga]=Eolas faoi OpenOffice.org
+Name[gl]=Información de OpenOffice.org
+Name[he]=מידע OpenOffice.org
+Name[hi]=स्टारआफिस.ऑर्ग जानकारी
+Name[hu]=OpenOffice.org-információ
+Name[is]=OpenOffice.org upplýsingar
+Name[it]=Informazioni OpenOffice.org
+Name[ja]=OpenOffice.org 情報
+Name[km]=ព័ត៌មាន​ OpenOffice.org
+Name[lt]=OpenOffice.org informacija
+Name[lv]=OpenOffice.org informācija
+Name[ms]=Maklumat OpenOffice.org
+Name[nb]=OpenOffice.org-info
+Name[nds]=OpenOffice.org-Info
+Name[ne]=ओपनअफिस डट अर्ग इन्फो
+Name[nl]=OpenOffice.org Informatie
+Name[nn]=OpenOffice.org-info
+Name[pa]=OpenOffice.org ਜਾਣਕਾਰੀ
+Name[pl]=Informacje o OpenOffice.org
+Name[pt]=Informação do OpenOffice.org
+Name[pt_BR]=Informações do OpenOffice.org
+Name[ru]=Информация OpenOffice.org
+Name[se]=OpenOffice.org-dieđut
+Name[sk]=Informácie o OpenOffice.org
+Name[sl]=Informacije o OpenOffice.org
+Name[sr]=Информације OpenOffice.org-а
+Name[sr@Latn]=Informacije OpenOffice.org-a
+Name[sv]=Information om OpenOffice.org
+Name[tg]=OpenOffice.org Ахборот
+Name[uk]=Інформація про OpenOffice.org
+Name[uz]=OpenOffice.org maʼlumot
+Name[uz@cyrillic]=OpenOffice.org маълумот
+Name[wa]=Informåcion OpenOffice.org
+Name[zh_CN]=OpenOffice.org 信息
+Name[zh_TW]=OpenOffice.org 資訊
+ServiceTypes=KFilePlugin
+X-TDE-Library=tdefile_ooo
+MimeType=application/vnd.sun.xml.calc;application/vnd.sun.xml.calc.template;application/vnd.sun.xml.draw;application/vnd.sun.xml.draw.template;application/vnd.sun.xml.impress;application/vnd.sun.xml.impress.template;application/vnd.sun.xml.writer;application/vnd.sun.xml.writer.global;application/vnd.sun.xml.writer.math;application/vnd.sun.xml.writer.template;application/vnd.oasis.opendocument.chart;application/vnd.oasis.opendocument.formula;application/vnd.oasis.opendocument.graphics;application/vnd.oasis.opendocument.graphics-template;application/vnd.oasis.opendocument.image;application/vnd.oasis.opendocument.presentation;application/vnd.oasis.opendocument.presentation-template;application/vnd.oasis.opendocument.spreadsheet;application/vnd.oasis.opendocument.spreadsheet-template;application/vnd.oasis.opendocument.text;application/vnd.oasis.opendocument.text-template
+PreferredGroups=DocumentInfo
+PreferredItems=Author,Title,Abstract
diff --git a/tools/tdefile-plugins/ooo/tdefile_ooo.h b/tools/tdefile-plugins/ooo/tdefile_ooo.h
new file mode 100644
index 00000000..9cb9f12a
--- /dev/null
+++ b/tools/tdefile-plugins/ooo/tdefile_ooo.h
@@ -0,0 +1,78 @@
+/* This file is part of the KDE project
+ * Copyright (C) 2003 Pierre Souchay <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef __KFILE_OOO_H__
+#define __KFILE_OOO_H__
+
+#include <tdefilemetainfo.h>
+#include <tqiodevice.h>
+#include <tqdom.h>
+#include <karchive.h>
+class TQStringList;
+class TQDomNode;
+class TQDomElement;
+
+class KOfficePlugin: public KFilePlugin
+{
+ Q_OBJECT
+
+
+public:
+ /**
+ * Constructor */
+ KOfficePlugin( TQObject *parent, const char *name, const TQStringList& args );
+ /**
+ * Read informations from files and store info in KFileMetaInfo.
+ * We currently only parse meta.xml in OOo files.
+ * @param info informations to modify about current file
+ * @param what What kind of parsing is needed ?
+ */
+ virtual bool readInfo( KFileMetaInfo& info, uint what);
+ /**
+ * Write modified informations in meta.xml
+ * @param info Informations modified
+ */
+ virtual bool writeInfo( const KFileMetaInfo& info) const;
+ /**
+ * We need a validator, for the langage
+ */
+ virtual TQValidator* createValidator( const TQString& mimetype,
+ const TQString &group,
+ const TQString &key,
+ TQObject* parent,
+ const char* name) const;
+private:
+ bool writeTextNode(TQDomDocument & doc,
+ TQDomNode & parentNode,
+ const TQString &nodeName,
+ const TQString &value) const;
+ KFileMimeTypeInfo::GroupInfo* userdefined;
+ void addAttributeInfo(const TQDomElement & elem, KFileMetaInfoGroup & group,
+ const TQString &attributeName);
+ TQIODevice* getData(KArchive &m_zip, int fileMode) const;
+ bool writeMetaData(const TQString & path, const TQDomDocument &doc) const;
+ TQDomDocument getMetaDocument(const TQString &path) const;
+ TQDomNode getBaseNode(const TQDomDocument &doc) const;
+ void makeMimeTypeInfo(const TQString& mimeType);
+ TQString stringFromNode(const TQDomNode &node, const TQString &name);
+ void getEditingTime(KFileMetaInfoGroup group1, const char *, TQString & txt);
+ void getDateTime(KFileMetaInfoGroup group1, const char *, TQString & txt);
+};
+
+#endif