From 8362bf63dea22bbf6736609b0f49c152f975eb63 Mon Sep 17 00:00:00 2001 From: tpearson Date: Wed, 20 Jan 2010 01:29:50 +0000 Subject: Added old abandoned KDE3 version of koffice git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/applications/koffice@1077364 283d02a7-25f6-0310-bc7c-ecb5cbfe19da --- filters/kspread/opencalc/Makefile.am | 21 + .../opencalc/kspread_opencalc_export.desktop | 59 + .../opencalc/kspread_opencalc_import.desktop | 62 + filters/kspread/opencalc/opencalcexport.cc | 1329 +++++++++ filters/kspread/opencalc/opencalcexport.h | 89 + filters/kspread/opencalc/opencalcimport.cc | 2826 ++++++++++++++++++++ filters/kspread/opencalc/opencalcimport.h | 119 + filters/kspread/opencalc/opencalcstyleexport.cc | 546 ++++ filters/kspread/opencalc/opencalcstyleexport.h | 167 ++ filters/kspread/opencalc/status.html | 208 ++ 10 files changed, 5426 insertions(+) create mode 100644 filters/kspread/opencalc/Makefile.am create mode 100644 filters/kspread/opencalc/kspread_opencalc_export.desktop create mode 100644 filters/kspread/opencalc/kspread_opencalc_import.desktop create mode 100644 filters/kspread/opencalc/opencalcexport.cc create mode 100644 filters/kspread/opencalc/opencalcexport.h create mode 100644 filters/kspread/opencalc/opencalcimport.cc create mode 100644 filters/kspread/opencalc/opencalcimport.h create mode 100644 filters/kspread/opencalc/opencalcstyleexport.cc create mode 100644 filters/kspread/opencalc/opencalcstyleexport.h create mode 100644 filters/kspread/opencalc/status.html (limited to 'filters/kspread/opencalc') diff --git a/filters/kspread/opencalc/Makefile.am b/filters/kspread/opencalc/Makefile.am new file mode 100644 index 000000000..65741b1d7 --- /dev/null +++ b/filters/kspread/opencalc/Makefile.am @@ -0,0 +1,21 @@ +####### General stuff + +INCLUDES= -I$(srcdir)/../../liboofilter -I$(srcdir) -I$(top_srcdir)/kspread $(KOFFICE_INCLUDES) \ + $(KOTEXT_INCLUDES) $(all_includes) + +####### Files +kde_module_LTLIBRARIES = libopencalcimport.la libopencalcexport.la + +libopencalcexport_la_SOURCES = opencalcexport.cc opencalcstyleexport.cc +libopencalcexport_la_LDFLAGS = $(all_libraries) -module -avoid-version -no-undefined +libopencalcexport_la_LIBADD = ../../../kspread/libkspreadcommon.la ../../liboofilter/liboofilter.la $(KOFFICE_LIBS) + +libopencalcimport_la_SOURCES = opencalcimport.cc +libopencalcimport_la_LDFLAGS = $(all_libraries) -module -avoid-version -no-undefined +libopencalcimport_la_LIBADD = ../../../kspread/libkspreadcommon.la ../../liboofilter/liboofilter.la $(KOFFICE_LIBS) + +METASOURCES = AUTO + +service_DATA = kspread_opencalc_import.desktop kspread_opencalc_export.desktop + +servicedir = $(kde_servicesdir) diff --git a/filters/kspread/opencalc/kspread_opencalc_export.desktop b/filters/kspread/opencalc/kspread_opencalc_export.desktop new file mode 100644 index 000000000..d120960b8 --- /dev/null +++ b/filters/kspread/opencalc/kspread_opencalc_export.desktop @@ -0,0 +1,59 @@ +[Desktop Entry] +Type=Service +Name=OpenOffice.org Calc Export Filter for KSpread +Name[bg]=Филтър за експортиране от KSpread в OpenOffice.org Calc +Name[br]=Sil ezporzh OpenOffice.org Calc evit KSpread +Name[ca]=Filtre d'exportació OpenOffice.org Calc per a KSpread +Name[cs]=OpenOffice.org Calc exportní filtr pro KSpread +Name[cy]=Hidlen Allforio OpenOffice.org Calc ar gyfer KSpread +Name[da]=OpenOffice.rog-Calc eksportfilter for KSpread +Name[de]=KSpread OpenOffice.org Calc-Exportfilter +Name[el]=Φίλτρο εξαγωγής OpenOffice.org Calc για το KSpread +Name[eo]=OpenOffice.org Calc-eksportfiltrilo por KSpread +Name[es]=Filtro de exportación de OpenOffice.org Calc para KSpread +Name[et]=KSpreadi OpenOffice.org Calc'i ekspordifilter +Name[eu]=KSpread-en OpenOffice.org Calc esportaziorako iragazkia +Name[fa]=پالایۀ صادرات OpenOffice.org Calc برای KSpread +Name[fi]=OpenOffice.org Calc -vientisuodin KSpreadille +Name[fr]=Filtre d'exportation OpenOffice.org Calc pour KSpread +Name[fy]=OpenOffice.org Calc Eksportfilter foar KSpread +Name[ga]=Scagaire Easpórtála OpenOffice.org Calc le haghaidh KSpread +Name[gl]=Filtro de Exportación de OpenOffice.org Calc para KSpread +Name[he]=מסנן ייצוא מ־KSpread ל־OpenOffice.org Calc +Name[hi]=के-स्प्रेड के लिए ओपन-ऑफ़िस.ऑर्ग केल्क निर्यात छननी +Name[hr]=OpenOffice.org Calc filtar izvoza za KSpread +Name[hu]=OpenOffice.org Calc exportszűrő a KSpreadhez +Name[is]=OpenOffice.org Calc útflutningssía fyrir KSpread +Name[it]=Filtro di esportazione OpenOffice.org Calc per KSpread +Name[ja]=KSpread OpenOffice.org Calc エクスポートフィルタ +Name[km]=តម្រង​នាំចេញ OpenOffice.org Calc សម្រាប់ KSpread +Name[lt]=OpenOffice.org Calc eksportavimo filtras skirtas KSpread +Name[lv]=OpenOffice.org Calc eksporta filtrs priekš KSpread +Name[ms]=Penapis Eksport OpenOffice.org Calc bagi KSpread +Name[nb]=OpenOffice.org Calc-eksportfilter for KSpread +Name[nds]="OpenOffice.org Calc"-Exportfilter för KSpread +Name[ne]=केडीई स्प्रिेडका लागि OpenOffice.org क्याल्क निर्यात फिल्टर +Name[nl]=OpenOffice.org Calc Exportfilter voor KSpread +Name[nn]=OpenOffice.org Calc-eksportfilter for KSpread +Name[pl]=Filtr eksportu do formatu OpenOffice.org Calc dla KSpread +Name[pt]=Filtro de Exportação de OpenOffice.org Calc para o KSpread +Name[pt_BR]=Filtro de Exportação OpenOffice.org Calc do KSpread +Name[ru]=Фильтр экспорта таблиц KSpread в OpenOffice.org Calc +Name[se]=KSpread:a OpenOffice.org Calc-olggosfievrridansilli +Name[sk]=OpenCalc filter pre export do KSpread +Name[sl]=Izvozni filter OpenOffice.org Calc za KSpread +Name[sr]=KSpread-ов филтер за извоз у OpenOffice.org-ов Calc +Name[sr@Latn]=KSpread-ov filter za izvoz u OpenOffice.org-ov Calc +Name[sv]=OpenOffice.org Calc-exportfilter för Kspread +Name[ta]=கேஸ்பெரெட்டுக்கான OpenOffice.org கால்க் ஏற்றும் அலங்காரம் +Name[tr]=KSpread için OpenOffice.org Calc Aktarma Filtresi +Name[uk]=Фільтр експорту OpenOffice.org Calc для KSpread +Name[uz]=KSpread uchun OpenOffice.org Calc eksport filteri +Name[uz@cyrillic]=KSpread учун OpenOffice.org Calc экспорт филтери +Name[zh_CN]=KSpread 的 OpenOffice.org Calc 导出过滤器 +Name[zh_TW]=KSpread 的 OpenOffice.org Calc 匯出過濾程式 +X-KDE-Export=application/vnd.sun.xml.calc +X-KDE-Import=application/x-kspread +X-KDE-Weight=1 +X-KDE-Library=libopencalcexport +ServiceTypes=KOfficeFilter diff --git a/filters/kspread/opencalc/kspread_opencalc_import.desktop b/filters/kspread/opencalc/kspread_opencalc_import.desktop new file mode 100644 index 000000000..c7dde5ef5 --- /dev/null +++ b/filters/kspread/opencalc/kspread_opencalc_import.desktop @@ -0,0 +1,62 @@ +[Desktop Entry] +Type=Service +Name=OpenOffice.org Calc Import Filter for KSpread +Name[bg]=Филтър за импортиране от OpenOffice.org Calc в KSpread +Name[br]=Sil enporzh OpenOffice.org Calc evit KSpread +Name[ca]=Filtre d'importació OpenOffice.org Calc per a KSpread +Name[cs]=OpenOffice.org Calc importní filtr pro KSpread +Name[cy]=Hidl Mewnforio OpenOffice.org Calc ar gyfer KSpread +Name[da]=OpenOffice.org-Calc importfilter for KSpread +Name[de]=KSpread OpenOffice.org Calc-Importfilter +Name[el]=Φίλτρο εισαγωγής OpenOffice.org Calc για το KSpread +Name[eo]=OpenOffice.org Calc-importfiltrilo por KSpread +Name[es]=Filtro de importación de OpenOffice.org Calc para KSpread +Name[et]=KSpreadi OpenOffice.org Calc'i impordifilter +Name[eu]=KSpread-en OpenOffice.org Calc inportaziorako iragazkia +Name[fa]=پالایۀ واردات OpenOffice.org Calc برای KSpread +Name[fi]=OpenOffice.org Calc -tuontisuodin KSpreadille +Name[fr]=Filtre d'importation OpenOffice.org Calc pour KSpread +Name[fy]=OpenOffice.org Calc Ymportfilter foar KSpread +Name[ga]=Scagaire Iompórtála OpenOffice.org Calc le haghaidh KSpread +Name[gl]=Filtro de Importación de OpenOffice.org Calc para KSpread +Name[he]=מסנן ייבוא מ־OpenOffice.org Calc ל־KSpread +Name[hi]=के-स्प्रेड के लिए ओपन-ऑफ़िस.ऑर्ग केल्क आयात छननी +Name[hr]=OpenOffice.org Calc filtar uvoza za KSpread +Name[hu]=OpenOffice.org importszűrő a KSpreadhez +Name[is]=OpenOffice.org Calc innflutningssía fyrir KSpread +Name[it]=Filtro di importazione OpenOffice.org Calc per KSpread +Name[ja]=KSpread OpenOffice.org Calc インポートフィルタ +Name[km]=តម្រង​នាំចូល OpenOffice.org Calc សម្រាប់ KSpread +Name[lt]=OpenOffice.org Calc importavimo filtras skirtas KSpread +Name[lv]=OpenOffice.org Calc importa filtrs priekš KSpread +Name[ms]=Penapis Import OpenOffice.org Calc bagi KSpread +Name[nb]=OpenOffice.org Calc-importfilter for KSpread +Name[nds]="OpenOffice.org Calc"-Importfilter för KSpread +Name[ne]=केडीई स्प्रिेडका लागि OpenOffice.org क्याल्क आयात फिल्टर +Name[nl]=OpenOffice.org Calc Importfilter voor KSpread +Name[nn]=OpenOffice.org Calc-importfilter for KSpread +Name[pl]=Filtr importu formatu OpenOffice.org dla KSpread +Name[pt]=Filtro de Importação de OpenOffice.org Calc para o KSpread +Name[pt_BR]=Filtro de Importação OpenOffice.org Calc do KSpread +Name[ru]=Фильтр импорта таблиц OpenOffice.org Calc в KSpread +Name[se]=KSpread:a OpenOffice.org Calc-sisafievrridansilli +Name[sk]=OpenCalc filter pre import z KSpread +Name[sl]=Uvozni filter OpenOffice.org Calc za KSpread +Name[sr]=KSpread-ов филтер за увоз из OpenOffice.org-овог Calc-а +Name[sr@Latn]=KSpread-ov filter za uvoz iz OpenOffice.org-ovog Calc-a +Name[sv]=OpenOffice.org Calc-importfilter för Kspread +Name[ta]=கேஸ்பெரெட்டுக்கான OpenOffice.org கால்க் இறக்கும் அலங்காரம் +Name[tr]=KSpread için OpenOffice.org Calc Alma Filtresi +Name[uk]=Фільтр імпорту OpenOffice.org Calc для KSpread +Name[uz]=KSpread uchun OpenOffice.org Calc import filteri +Name[uz@cyrillic]=KSpread учун OpenOffice.org Calc импорт филтери +Name[zh_CN]=KSpread 的 OpenOffice.org Calc 导入过滤器 +Name[zh_TW]=KSpread 的 OpenOffice.org Calc 匯入過濾程式 +X-KDE-Export=application/x-kspread +X-KDE-Import=application/vnd.sun.xml.calc,application/vnd.sun.xml.calc.template +X-KDE-Weight=1 +X-KDE-Library=libopencalcimport +X-KDE-LibraryMajor=1 +X-KDE-LibraryMinor=0 +X-KDE-LibraryDependencies= +ServiceTypes=KOfficeFilter diff --git a/filters/kspread/opencalc/opencalcexport.cc b/filters/kspread/opencalc/opencalcexport.cc new file mode 100644 index 000000000..20915b516 --- /dev/null +++ b/filters/kspread/opencalc/opencalcexport.cc @@ -0,0 +1,1329 @@ +/* This file is part of the KDE project + Copyright (C) 2000 David Faure + Copyright (C) 2000 Norbert Andres + Copyright (C) 2005 Laurent Montel + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#include +#include + +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace KSpread; + +typedef QValueList AreaList; + +class OpenCalcExportFactory : KGenericFactory +{ +public: + OpenCalcExportFactory(void) : KGenericFactory ("kspreadopencalcexport") + {} +protected: + virtual void setupTranslations( void ) + { + KGlobal::locale()->insertCatalogue( "kofficefilters" ); + } +}; + +K_EXPORT_COMPONENT_FACTORY( libopencalcexport, OpenCalcExportFactory() ) + +#define STOPEXPORT \ + do \ + { \ + delete store; \ + return false; \ + } while(0) + +OpenCalcExport::OpenCalcExport( KoFilter *, const char *, const QStringList & ) + : KoFilter(), m_locale( 0 ) +{ +} + +KoFilter::ConversionStatus OpenCalcExport::convert( const QCString & from, + const QCString & to ) +{ + /* later... + KSpreadLeader * leader = new KSpreadLeader( m_chain ); + OpenCalcWorker * worker = new OpenCalcWorker(); + leader->setWorker( worker ); + + KoFilter::ConversionStatus status = leader->convert(); + + delete worker; + delete leader; + + return status; + */ + + KoDocument * document = m_chain->inputDocument(); + + if ( !document ) + return KoFilter::StupidError; + + if ( !::qt_cast( document ) ) + { + kdWarning(30518) << "document isn't a KSpread::Doc but a " + << document->className() << endl; + return KoFilter::NotImplemented; + } + + if ( ( to != "application/vnd.sun.xml.calc") || (from != "application/x-kspread" ) ) + { + kdWarning(30518) << "Invalid mimetypes " << to << " " << from << endl; + return KoFilter::NotImplemented; + } + + const Doc * ksdoc = static_cast(document); + + if ( ksdoc->mimeType() != "application/x-kspread" ) + { + kdWarning(30518) << "Invalid document mimetype " << ksdoc->mimeType() << endl; + return KoFilter::NotImplemented; + } + + m_locale = static_cast(document)->locale(); + if ( !writeFile( ksdoc ) ) + return KoFilter::CreationError; + + emit sigProgress( 100 ); + + return KoFilter::OK; +} + +bool OpenCalcExport::writeFile( const Doc * ksdoc ) +{ + KoStore * store = KoStore::createStore( m_chain->outputFile(), KoStore::Write, "", KoStore::Zip ); + + if ( !store ) + return false; + + uint filesWritten = 0; + + if ( !exportContent( store, ksdoc ) ) + STOPEXPORT; + else + filesWritten |= contentXML; + + // TODO: pass sheet number and cell number + if ( !exportDocInfo( store, ksdoc ) ) + STOPEXPORT; + else + filesWritten |= metaXML; + + if ( !exportStyles( store, ksdoc ) ) + STOPEXPORT; + else + filesWritten |= stylesXML; + + if ( !exportSettings( store, ksdoc ) ) + STOPEXPORT; + else + filesWritten |= settingsXML; + + if ( !writeMetaFile( store, filesWritten ) ) + STOPEXPORT; + + // writes zip file to disc + delete store; + store = 0; + + return true; +} + +bool OpenCalcExport::exportDocInfo( KoStore * store, const Doc* ksdoc ) +{ + if ( !store->open( "meta.xml" ) ) + return false; + + KoDocumentInfo * docInfo = ksdoc->documentInfo(); + KoDocumentInfoAbout * aboutPage = static_cast( docInfo->page( "about" ) ); + KoDocumentInfoAuthor * authorPage = static_cast( docInfo->page( "author" ) ); + + QDomDocument meta; + meta.appendChild( meta.createProcessingInstruction( "xml","version=\"1.0\" encoding=\"UTF-8\"" ) ); + + QDomElement content = meta.createElement( "office:document-meta" ); + content.setAttribute( "xmlns:office", "http://openoffice.org/2000/office"); + content.setAttribute( "xmlns:xlink", "http://www.w3.org/1999/xlink" ); + content.setAttribute( "xmlns:dc", "http://purl.org/dc/elements/1.1/" ); + content.setAttribute( "xmlns:meta", "http://openoffice.org/2000/meta" ); + content.setAttribute( "office:version", "1.0" ); + + QDomNode officeMeta = meta.createElement( "office:meta" ); + + QDomElement data = meta.createElement( "meta:generator" ); + QString app( "KSpread " ); + app += KSpread::version; + data.appendChild( meta.createTextNode( app ) ); + officeMeta.appendChild( data ); + + data = meta.createElement( "meta:initial-creator" ); + data.appendChild( meta.createTextNode( authorPage->fullName() ) ); + officeMeta.appendChild( data ); + + data = meta.createElement( "meta:creator" ); + data.appendChild( meta.createTextNode( authorPage->fullName() ) ); + officeMeta.appendChild( data ); + + data = meta.createElement( "dc:description" ); + data.appendChild( meta.createTextNode( aboutPage->abstract() ) ); + officeMeta.appendChild( data ); + + data = meta.createElement( "meta:keywords" ); + QDomElement dataItem = meta.createElement( "meta:keyword" ); + dataItem.appendChild( meta.createTextNode( aboutPage->keywords() ) ); + data.appendChild( dataItem ); + officeMeta.appendChild( data ); + + data = meta.createElement( "dc:title" ); + data.appendChild( meta.createTextNode( aboutPage->title() ) ); + officeMeta.appendChild( data ); + + data = meta.createElement( "dc:subject" ); + data.appendChild( meta.createTextNode( aboutPage->subject() ) ); + officeMeta.appendChild( data ); + + const QDateTime dt ( QDateTime::currentDateTime() ); + if ( dt.isValid() ) + { + data = meta.createElement( "dc:date" ); + data.appendChild( meta.createTextNode( dt.toString( Qt::ISODate ) ) ); + officeMeta.appendChild( data ); + } + + /* TODO: + 2003-01-08T23:57:31 + en-US + 2 + PT38S + + + */ + + data = meta.createElement( "meta:document-statistic" ); + data.setAttribute( "meta:table-count", QString::number( ksdoc->map()->count() ) ); + // TODO: data.setAttribute( "meta:cell-count", ); + officeMeta.appendChild( data ); + + content.appendChild( officeMeta ); + meta.appendChild( content ); + + QCString doc( meta.toCString() ); + kdDebug(30518) << "Meta: " << doc << endl; + + store->write( doc, doc.length() ); + + if ( !store->close() ) + return false; + + return true; +} + +bool OpenCalcExport::exportSettings( KoStore * store, const Doc * ksdoc ) +{ + if ( !store->open( "settings.xml" ) ) + return false; + + QDomDocument doc; + doc.appendChild( doc.createProcessingInstruction( "xml","version=\"1.0\" encoding=\"UTF-8\"" ) ); + + QDomElement settings = doc.createElement( "office:document-settings" ); + settings.setAttribute( "xmlns:office", "http://openoffice.org/2000/office"); + settings.setAttribute( "xmlns:xlink", "http://www.w3.org/1999/xlink" ); + settings.setAttribute( "xmlns:config", "http://openoffice.org/2001/config" ); + settings.setAttribute( "office:version", "1.0" ); + + QDomElement begin = doc.createElement( "office:settings" ); + + QDomElement configItem = doc.createElement("config:config-item-set" ); + configItem.setAttribute( "config:name", "view-settings" ); + + QDomElement mapIndexed = doc.createElement( "config:config-item-map-indexed" ); + mapIndexed.setAttribute("config:name", "Views" ); + configItem.appendChild( mapIndexed ); + + QDomElement mapItem = doc.createElement("config:config-item-map-entry" ); + + QDomElement attribute = doc.createElement("config:config-item" ); + attribute.setAttribute( "config:name", "ActiveTable" ); + attribute.setAttribute( "config:type", "string" ); + + View * view = static_cast( ksdoc->views().getFirst()); + QString activeTable; + if ( view ) // no view if embedded document + { + Canvas * canvas = view->canvasWidget(); + activeTable = canvas->activeSheet()->sheetName(); + // save current sheet selection before to save marker, otherwise current pos is not saved + view->saveCurrentSheetSelection(); + } + attribute.appendChild( doc.createTextNode( activeTable ) ); + mapItem.appendChild( attribute ); + + QDomElement configmaped = doc.createElement( "config:config-item-map-named" ); + configmaped.setAttribute( "config:name","Tables" ); + + QPtrListIterator it( ksdoc->map()->sheetList() ); + for( ; it.current(); ++it ) + { + QPoint marker; + if ( view ) + { + marker = view->markerFromSheet( *it ); + } + QDomElement tmpItemMapNamed = doc.createElement( "config:config-item-map-entry" ); + tmpItemMapNamed.setAttribute( "config:name", ( *it )->tableName() ); + + QDomElement sheetAttribute = doc.createElement( "config:config-item" ); + sheetAttribute.setAttribute( "config:name", "CursorPositionX" ); + sheetAttribute.setAttribute( "config:type", "int" ); + sheetAttribute.appendChild( doc.createTextNode( QString::number(marker.x() ) ) ); + tmpItemMapNamed.appendChild( sheetAttribute ); + + sheetAttribute = doc.createElement( "config:config-item" ); + sheetAttribute.setAttribute( "config:name", "CursorPositionY" ); + sheetAttribute.setAttribute( "config:type", "int" ); + sheetAttribute.appendChild( doc.createTextNode( QString::number(marker.y() ) ) ); + tmpItemMapNamed.appendChild( sheetAttribute ); + + configmaped.appendChild( tmpItemMapNamed ); + } + mapItem.appendChild( configmaped ); + + + + mapIndexed.appendChild( mapItem ); + + begin.appendChild( configItem ); + + settings.appendChild( begin ); + + doc.appendChild( settings ); + + QCString f( doc.toCString() ); + kdDebug(30518) << "Settings: " << (char const * ) f << endl; + + store->write( f, f.length() ); + + if ( !store->close() ) + return false; + + return true; +} + +bool OpenCalcExport::exportContent( KoStore * store, const Doc * ksdoc ) +{ + if ( !store->open( "content.xml" ) ) + return false; + + createDefaultStyles(); + + QDomDocument doc; + doc.appendChild( doc.createProcessingInstruction( "xml","version=\"1.0\" encoding=\"UTF-8\"" ) ); + + QDomElement content = doc.createElement( "office:document-content" ); + content.setAttribute( "xmlns:office", "http://openoffice.org/2000/office"); + content.setAttribute( "xmlns:style", "http://openoffice.org/2000/style" ); + content.setAttribute( "xmlns:text", "http://openoffice.org/2000/text" ); + content.setAttribute( "xmlns:table", "http://openoffice.org/2000/table" ); + content.setAttribute( "xmlns:draw", "http://openoffice.org/2000/drawing" ); + content.setAttribute( "xmlns:fo", "http://www.w3.org/1999/XSL/Format" ); + content.setAttribute( "xmlns:xlink", "http://www.w3.org/1999/xlink" ); + content.setAttribute( "xmlns:number", "http://openoffice.org/2000/datastyle" ); + content.setAttribute( "xmlns:svg", "http://www.w3.org/2000/svg" ); + content.setAttribute( "xmlns:chart", "http://openoffice.org/2000/chart" ); + content.setAttribute( "xmlns:dr3d", "http://openoffice.org/2000/dr3d" ); + content.setAttribute( "xmlns:math", "http://www.w3.org/1998/Math/MathML" ); + content.setAttribute( "xmlns:form", "http://openoffice.org/2000/form" ); + content.setAttribute( "xmlns:script", "http://openoffice.org/2000/script" ); + content.setAttribute( "office:class", "spreadsheet" ); + content.setAttribute( "office:version", "1.0" ); + + QDomElement data = doc.createElement( "office:script" ); + content.appendChild( data ); + + if ( !exportBody( doc, content, ksdoc ) ) + return false; + + doc.appendChild( content ); + + QCString f( doc.toCString() ); + kdDebug(30518) << "Content: " << (char const * ) f << endl; + + store->write( f, f.length() ); + + if ( !store->close() ) + return false; + + return true; +} + +void exportNamedExpr( QDomDocument & doc, QDomElement & parent, + AreaList const & namedAreas ) +{ + AreaList::const_iterator it = namedAreas.begin(); + AreaList::const_iterator end = namedAreas.end(); + + while ( it != end ) + { + QDomElement namedRange = doc.createElement( "table:named-range" ); + + Reference ref = *it; + + namedRange.setAttribute( "table:name", ref.ref_name ); + namedRange.setAttribute( "table:base-cell-address", convertRefToBase( ref.sheet_name, ref.rect ) ); + namedRange.setAttribute( "table:cell-range-address", convertRefToRange( ref.sheet_name, ref.rect ) ); + + parent.appendChild( namedRange ); + + ++it; + } +} + +bool OpenCalcExport::exportBody( QDomDocument & doc, QDomElement & content, const Doc * ksdoc ) +{ + QDomElement fontDecls = doc.createElement( "office:font-decls" ); + QDomElement autoStyles = doc.createElement( "office:automatic-styles" ); + QDomElement body = doc.createElement( "office:body" ); + + if ( ksdoc->map()->isProtected() ) + { + body.setAttribute( "table:structure-protected", "true" ); + + QCString passwd; + ksdoc->map()->password( passwd ); + if ( passwd.length() > 0 ) + { + QCString str( KCodecs::base64Encode( passwd ) ); + body.setAttribute( "table:protection-key", QString( str.data() ) ); + } + } + + + + QPtrListIterator it( ksdoc->map()->sheetList() ); + + for( it.toFirst(); it.current(); ++it ) + { + SheetStyle ts; + int maxCols = 1; + int maxRows = 1; + Sheet * sheet = it.current(); + + ts.visible = !sheet->isHidden(); + + QDomElement tabElem = doc.createElement( "table:table" ); + tabElem.setAttribute( "table:style-name", m_styles.sheetStyle( ts ) ); + + if ( sheet->isProtected() ) + { + tabElem.setAttribute( "table:protected", "true" ); + + QCString passwd; + sheet->password( passwd ); + if ( passwd.length() > 0 ) + { + QCString str( KCodecs::base64Encode( passwd ) ); + tabElem.setAttribute( "table:protection-key", QString( str.data() ) ); + } + } + + QString name( sheet->tableName() ); + + int n = name.find( ' ' ); + if ( n != -1 ) + { + kdDebug(30518) << "Sheet name converting: " << name << endl; + name[n] == '_'; + kdDebug(30518) << "Sheet name converted: " << name << endl; + } + name = name.replace( ' ', "_" ); + + QRect _printRange = sheet->print()->printRange(); + if ( _printRange != ( QRect( QPoint( 1, 1 ), QPoint( KS_colMax, KS_rowMax ) ) ) ) + { + QString range= convertRangeToRef( name, _printRange ); + //kdDebug(30518)<<" range : "<inputDocument(); + Doc * kspreadDoc = static_cast( document ); + + AreaList namedAreas = kspreadDoc->listArea(); + if ( namedAreas.count() > 0 ) + { + QDomElement namedExpr = doc.createElement( "table:named-expressions" ); + exportNamedExpr( doc, namedExpr, namedAreas ); + + body.appendChild( namedExpr ); + } + + m_styles.writeStyles( doc, autoStyles ); + m_styles.writeFontDecl( doc, fontDecls ); + + content.appendChild( fontDecls ); + content.appendChild( autoStyles ); + content.appendChild( body ); + + return true; +} + +void OpenCalcExport::exportSheet( QDomDocument & doc, QDomElement & tabElem, + const Sheet * sheet, int maxCols, int maxRows ) +{ + kdDebug(30518) << "exportSheet: " << sheet->tableName() << endl; + int i = 1; + + while ( i <= maxCols ) + { + const ColumnFormat * column = sheet->columnFormat( i ); + ColumnStyle cs; + cs.breakB = ::Style::automatic; + cs.size = column->mmWidth() / 10; + bool hide = column->isHide(); + + int j = i + 1; + int repeated = 1; + while ( j <= maxCols ) + { + const ColumnFormat *c = sheet->columnFormat( j ); + ColumnStyle cs1; + cs1.breakB = ::Style::automatic; + cs1.size = c->mmWidth() / 10; + + if ( ColumnStyle::isEqual( &cs, cs1 ) && ( hide == c->isHide() ) ) + ++repeated; + else + break; + ++j; + } + + QDomElement colElem = doc.createElement( "table:table-column" ); + colElem.setAttribute( "table:style-name", m_styles.columnStyle( cs ) ); + colElem.setAttribute( "table:default-cell-style-name", "Default" );//todo fixme create style from cell + if ( hide ) + colElem.setAttribute( "table:visibility", "collapse" ); + + if ( repeated > 1 ) + colElem.setAttribute( "table:number-columns-repeated", QString::number( repeated ) ); + + tabElem.appendChild( colElem ); + i += repeated; + } + + for ( i = 1; i <= maxRows; ++i ) + { + const RowFormat * row = sheet->rowFormat( i ); + RowStyle rs; + rs.breakB = ::Style::automatic; + rs.size = row->mmHeight() / 10; + + QDomElement rowElem = doc.createElement( "table:table-row" ); + rowElem.setAttribute( "table:style-name", m_styles.rowStyle( rs ) ); + if ( row->isHide() ) + rowElem.setAttribute( "table:visibility", "collapse" ); + + exportCells( doc, rowElem, sheet, i, maxCols ); + + tabElem.appendChild( rowElem ); + } +} + +void OpenCalcExport::exportCells( QDomDocument & doc, QDomElement & rowElem, + const Sheet *sheet, int row, int maxCols ) +{ + int i = 1; + while ( i <= maxCols ) + { + int repeated = 1; + bool hasComment = false; + const Cell* cell = sheet->cellAt( i, row ); + QDomElement cellElem; + + if ( !cell->isPartOfMerged() ) + cellElem = doc.createElement( "table:table-cell" ); + else + cellElem = doc.createElement( "table:covered-table-cell" ); + + QFont font; + Value const value( cell->value() ); + if ( !cell->isDefault() ) + { + font = cell->format()->textFont( i, row ); + m_styles.addFont( font ); + + if ( cell->format()->hasProperty( Format::PComment ) ) + hasComment = true; + } + + CellStyle c; + CellStyle::loadData( c, cell ); // TODO: number style + + cellElem.setAttribute( "table:style-name", m_styles.cellStyle( c ) ); + + // group empty cells with the same style + if ( cell->isEmpty() && !hasComment && !cell->isPartOfMerged() && !cell->doesMergeCells() ) + { + int j = i + 1; + while ( j <= maxCols ) + { + const Cell *cell1 = sheet->cellAt( j, row ); + + CellStyle c1; + CellStyle::loadData( c1, cell1 ); // TODO: number style + + if ( cell1->isEmpty() && !cell->format()->hasProperty( Format::PComment ) + && CellStyle::isEqual( &c, c1 ) && !cell->isPartOfMerged() && !cell->doesMergeCells() ) + ++repeated; + else + break; + ++j; + } + if ( repeated > 1 ) + cellElem.setAttribute( "table:number-columns-repeated", QString::number( repeated ) ); + } + + if ( value.isBoolean() ) + { + kdDebug(30518) << "Type: Boolean" << endl; + cellElem.setAttribute( "table:value-type", "boolean" ); + cellElem.setAttribute( "table:boolean-value", ( value.asBoolean() ? "true" : "false" ) ); + } + else if ( value.isNumber() ) + { + kdDebug(30518) << "Type: Number" << endl; + FormatType type = cell->format()->getFormatType( i, row ); + + if ( type == Percentage_format ) + cellElem.setAttribute( "table:value-type", "percentage" ); + else + cellElem.setAttribute( "table:value-type", "float" ); + + cellElem.setAttribute( "table:value", QString::number( value.asFloat() ) ); + } + else + { + kdDebug(30518) << "Type: " << value.type() << endl; + } + + if ( cell->isFormula() ) + { + kdDebug(30518) << "Formula found" << endl; + + QString formula( convertFormula( cell->text() ) ); + cellElem.setAttribute( "table:formula", formula ); + } + else if ( !cell->link().isEmpty() ) + { + QDomElement link = doc.createElement( "text:p" ); + QDomElement linkref = doc.createElement( "text:a" ); + + QString tmp = cell->link(); + if ( localReferenceAnchor( tmp ) ) + linkref.setAttribute( "xlink:href", ( "#"+tmp ) ); + else + linkref.setAttribute( "xlink:href", tmp ); + + linkref.appendChild( doc.createTextNode( cell->text() ) ); + + link.appendChild( linkref ); + cellElem.appendChild( link ); + } + else if ( !cell->isEmpty() ) + { + QDomElement textElem = doc.createElement( "text:p" ); + textElem.appendChild( doc.createTextNode( cell->strOutText() ) ); + + cellElem.appendChild( textElem ); + kdDebug(30518) << "Cell StrOut: " << cell->strOutText() << endl; + } + + if ( cell->doesMergeCells() ) + { + int colSpan = cell->mergedXCells() + 1; + int rowSpan = cell->mergedYCells() + 1; + + if ( colSpan > 1 ) + cellElem.setAttribute( "table:number-columns-spanned", QString::number( colSpan ) ); + + if ( rowSpan > 1 ) + cellElem.setAttribute( "table:number-rows-spanned", QString::number( rowSpan ) ); + } + + if ( hasComment ) + { + QString comment( cell->format()->comment( i, row ) ); + QDomElement annotation = doc.createElement( "office:annotation" ); + QDomElement text = doc.createElement( "text:p" ); + text.appendChild( doc.createTextNode( comment ) ); + + annotation.appendChild( text ); + cellElem.appendChild( annotation ); + } + + rowElem.appendChild( cellElem ); + + i += repeated; + } +} + +void OpenCalcExport::maxRowCols( const Sheet *sheet, + int & maxCols, int & maxRows ) +{ + Cell const * cell = sheet->firstCell(); + + while ( cell ) + { + if ( cell->column() > maxCols ) + maxCols = cell->column(); + + if ( cell->row() > maxRows ) + maxRows = cell->row(); + + cell = cell->nextCell(); + } + + RowFormat const * row = sheet->firstRow(); + + while ( row ) + { + if ( row->row() > maxRows ) + maxRows = row->row(); + + row = row->next(); + } + + ColumnFormat const * col = sheet->firstCol(); + while ( col ) + { + if ( col->column() > maxCols ) + maxCols = col->column(); + + col = col->next(); + } + +} + +bool OpenCalcExport::exportStyles( KoStore * store, const Doc *ksdoc ) +{ + if ( !store->open( "styles.xml" ) ) + return false; + + QDomDocument doc; + doc.appendChild( doc.createProcessingInstruction( "xml","version=\"1.0\" encoding=\"UTF-8\"" ) ); + + QDomElement content = doc.createElement( "office:document-styles" ); + content.setAttribute( "xmlns:office", "http://openoffice.org/2000/office" ); + content.setAttribute( "xmlns:style", "http://openoffice.org/2000/style" ); + content.setAttribute( "xmlns:text", "http://openoffice.org/2000/text" ); + content.setAttribute( "xmlns:table", "http://openoffice.org/2000/table" ); + content.setAttribute( "xmlns:draw", "http://openoffice.org/2000/drawing" ); + content.setAttribute( "xmlns:fo", "http://www.w3.org/1999/XSL/Format" ); + content.setAttribute( "xmlns:xlink", "http://www.w3.org/1999/xlink" ); + content.setAttribute( "xmlns:number", "http://openoffice.org/2000/datastyle" ); + content.setAttribute( "xmlns:svg", "http://www.w3.org/2000/svg" ); + content.setAttribute( "xmlns:chart", "http://openoffice.org/2000/chart" ); + content.setAttribute( "xmlns:dr3d", "http://openoffice.org/2000/dr3d" ); + content.setAttribute( "xmlns:math", "http://www.w3.org/1998/Math/MathML" ); + content.setAttribute( "xmlns:form", "http://openoffice.org/2000/form" ); + content.setAttribute( "xmlns:script", "http://openoffice.org/2000/script" ); + content.setAttribute( "office:version", "1.0" ); + + // order important here! + QDomElement officeStyles = doc.createElement( "office:styles" ); + exportDefaultCellStyle( doc, officeStyles ); + + QDomElement fontDecls = doc.createElement( "office:font-decls" ); + m_styles.writeFontDecl( doc, fontDecls ); + + // TODO: needs in new number/date/time parser... + // exportDefaultNumberStyles( doc, officeStyles ); + + QDomElement defaultStyle = doc.createElement( "style:style" ); + defaultStyle.setAttribute( "style:name", "Default" ); + defaultStyle.setAttribute( "style:family", "table-cell" ); + officeStyles.appendChild( defaultStyle ); + + QDomElement autoStyles = doc.createElement( "office:automatic-styles" ); + exportPageAutoStyles( doc, autoStyles, ksdoc ); + + QDomElement masterStyles = doc.createElement( "office:master-styles" ); + exportMasterStyles( doc, masterStyles, ksdoc ); + + content.appendChild( fontDecls ); + content.appendChild( officeStyles ); + content.appendChild( autoStyles ); + content.appendChild( masterStyles ); + + doc.appendChild( content ); + + QCString f( doc.toCString() ); + kdDebug(30518) << "Content: " << (char const * ) f << endl; + + store->write( f, f.length() ); + + if ( !store->close() ) + return false; + + return true; +} + +void OpenCalcExport::exportDefaultCellStyle( QDomDocument & doc, QDomElement & officeStyles ) +{ + QDomElement defStyle = doc.createElement( "style:default-style" ); + defStyle.setAttribute( "style:family", "table-cell" ); + + KoDocument * document = m_chain->inputDocument(); + Doc * ksdoc = static_cast(document); + + Format * format = new Format( 0, ksdoc->styleManager()->defaultStyle() ); + const KLocale *locale = ksdoc->locale(); + QString language; + QString country; + QString charSet; + + QString l( locale->language() ); + KLocale::splitLocale( l, language, country, charSet ); + QFont font( format->font() ); + m_styles.addFont( font, true ); + + QDomElement style = doc.createElement( "style:properties" ); + style.setAttribute( "style:font-name", font.family() ); + style.setAttribute( "fo:font-size", QString( "%1pt" ).arg( font.pointSize() ) ); + style.setAttribute( "style:decimal-places", QString::number( locale->fracDigits() ) ); + style.setAttribute( "fo:language", language ); + style.setAttribute( "fo:country", country ); + style.setAttribute( "style:font-name-asian", "HG Mincho Light J" ); + style.setAttribute( "style:language-asian", "none" ); + style.setAttribute( "style:country-asian", "none" ); + style.setAttribute( "style:font-name-complex", "Arial Unicode MS" ); + style.setAttribute( "style:language-complex", "none" ); + style.setAttribute( "style:country-complex", "none" ); + style.setAttribute( "style:tab-stop-distance", "1.25cm" ); + + defStyle.appendChild( style ); + officeStyles.appendChild( defStyle ); + delete format; +} + +void OpenCalcExport::createDefaultStyles() +{ + // TODO: default number styles, currency styles,... +} + +void OpenCalcExport::exportPageAutoStyles( QDomDocument & doc, QDomElement & autoStyles, + const Doc *ksdoc ) +{ + QPtrListIterator it( ksdoc->map()->sheetList() ); + const Sheet * sheet = it.toFirst(); + + float width = 20.999; + float height = 29.699; + + if ( sheet ) + { + width = sheet->print()->paperWidth() / 10; + height = sheet->print()->paperHeight() / 10; + } + + QString sWidth = QString( "%1cm" ).arg( width ); + QString sHeight = QString( "%1cm" ).arg( height ); + + QDomElement pageMaster = doc.createElement( "style:page-master" ); + pageMaster.setAttribute( "style:name", "pm1" ); + + QDomElement properties = doc.createElement( "style:properties" ); + properties.setAttribute( "fo:page-width", sWidth ); + properties.setAttribute( "fo:page-height", sHeight ); + properties.setAttribute( "fo:border", "0.002cm solid #000000" ); + properties.setAttribute( "fo:padding", "0cm" ); + properties.setAttribute( "fo:background-color", "transparent" ); + + pageMaster.appendChild( properties ); + + QDomElement header = doc.createElement( "style:header-style" ); + properties = doc.createElement( "style:properties" ); + properties.setAttribute( "fo:min-height", "0.75cm" ); + properties.setAttribute( "fo:margin-left", "0cm" ); + properties.setAttribute( "fo:margin-right", "0cm" ); + properties.setAttribute( "fo:margin-bottom", "0.25cm" ); + + header.appendChild( properties ); + + QDomElement footer = doc.createElement( "style:header-style" ); + properties = doc.createElement( "style:properties" ); + properties.setAttribute( "fo:min-height", "0.75cm" ); + properties.setAttribute( "fo:margin-left", "0cm" ); + properties.setAttribute( "fo:margin-right", "0cm" ); + properties.setAttribute( "fo:margin-bottom", "0.25cm" ); + + footer.appendChild( properties ); + + pageMaster.appendChild( header ); + pageMaster.appendChild( footer ); + + autoStyles.appendChild( pageMaster ); +} + +void OpenCalcExport::exportMasterStyles( QDomDocument & doc, QDomElement & masterStyles, + const Doc * ksdoc ) +{ + QDomElement masterPage = doc.createElement( "style:master-page" ); + masterPage.setAttribute( "style:name", "Default" ); + masterPage.setAttribute( "style:page-master-name", "pm1" ); + + QPtrListIterator it( ksdoc->map()->sheetList() ); + const Sheet * sheet = it.toFirst(); + + QString headerLeft; + QString headerCenter; + QString headerRight; + QString footerLeft; + QString footerCenter; + QString footerRight; + + if ( sheet ) + { + headerLeft = sheet->print()->headLeft(); + headerCenter = sheet->print()->headMid(); + headerRight = sheet->print()->headRight(); + footerLeft = sheet->print()->footLeft(); + footerCenter = sheet->print()->footMid(); + footerRight = sheet->print()->footRight(); + } + + if ( ( headerLeft.length() > 0 ) || ( headerCenter.length() > 0 ) + || ( headerRight.length() > 0 ) ) + { + QDomElement header = doc.createElement( "style:header" ); + QDomElement left = doc.createElement( "style:region-left" ); + QDomElement text = doc.createElement( "text:p" ); + convertPart( headerLeft, doc, text, ksdoc ); + left.appendChild( text ); + + QDomElement center = doc.createElement( "style:region-center" ); + QDomElement text1 = doc.createElement( "text:p" ); + convertPart( headerCenter, doc, text1, ksdoc ); + center.appendChild( text1 ); + + QDomElement right = doc.createElement( "style:region-right" ); + QDomElement text2 = doc.createElement( "text:p" ); + convertPart( headerRight, doc, text2, ksdoc ); + right.appendChild( text2 ); + + header.appendChild( left ); + header.appendChild( center ); + header.appendChild( right ); + + masterPage.appendChild( header ); + } + else + { + QDomElement header = doc.createElement( "style:header" ); + QDomElement text = doc.createElement( "text:p" ); + QDomElement name = doc.createElement( "text:sheet-name" ); + name.appendChild( doc.createTextNode( "???" ) ); + text.appendChild( name ); + header.appendChild( text ); + + masterPage.appendChild( header ); + } + + if ( ( footerLeft.length() > 0 ) || ( footerCenter.length() > 0 ) + || ( footerRight.length() > 0 ) ) + { + QDomElement footer = doc.createElement( "style:footer" ); + QDomElement left = doc.createElement( "style:region-left" ); + QDomElement text = doc.createElement( "text:p" ); + convertPart( footerLeft, doc, text, ksdoc ); + left.appendChild( text ); + + QDomElement center = doc.createElement( "style:region-center" ); + QDomElement text1 = doc.createElement( "text:p" ); + convertPart( footerCenter, doc, text1, ksdoc ); + center.appendChild( text1 ); + + QDomElement right = doc.createElement( "style:region-right" ); + QDomElement text2 = doc.createElement( "text:p" ); + convertPart( footerRight, doc, text2, ksdoc ); + right.appendChild( text2 ); + + footer.appendChild( left ); + footer.appendChild( center ); + footer.appendChild( right ); + + masterPage.appendChild( footer ); + } + else + { + QDomElement footer = doc.createElement( "style:footer" ); + QDomElement text = doc.createElement( "text:p" ); + text.appendChild( doc.createTextNode( i18n( "Page " ) ) ); + QDomElement number = doc.createElement( "text:page-number" ); + number.appendChild( doc.createTextNode( "1" ) ); + text.appendChild( number ); + footer.appendChild( text ); + + masterPage.appendChild( footer ); + } + + masterStyles.appendChild( masterPage ); +} + +void OpenCalcExport::addText( QString const & text, QDomDocument & doc, + QDomElement & parent ) +{ + if (text.length() > 0 ) + parent.appendChild( doc.createTextNode( text ) ); +} + +void OpenCalcExport::convertPart( QString const & part, QDomDocument & doc, + QDomElement & parent, const Doc * ksdoc ) +{ + QString text; + QString var; + + bool inVar = false; + uint i = 0; + uint l = part.length(); + while ( i < l ) + { + if ( inVar || part[i] == '<' ) + { + inVar = true; + var += part[i]; + if ( part[i] == '>' ) + { + inVar = false; + if ( var == "" ) + { + addText( text, doc, parent ); + + QDomElement page = doc.createElement( "text:page-number" ); + page.appendChild( doc.createTextNode( "1" ) ); + parent.appendChild( page ); + } + else if ( var == "" ) + { + addText( text, doc, parent ); + + QDomElement page = doc.createElement( "text:page-count" ); + page.appendChild( doc.createTextNode( "99" ) ); + parent.appendChild( page ); + } + else if ( var == "" ) + { + addText( text, doc, parent ); + + QDomElement t = doc.createElement( "text:date" ); + t.setAttribute( "text:date-value", "0-00-00" ); + // todo: "style:data-style-name", "N2" + t.appendChild( doc.createTextNode( QDate::currentDate().toString() ) ); + parent.appendChild( t ); + } + else if ( var == "