summaryrefslogtreecommitdiffstats
path: root/filters/kspread/opencalc
diff options
context:
space:
mode:
authortpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2010-01-20 01:29:50 +0000
committertpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2010-01-20 01:29:50 +0000
commit8362bf63dea22bbf6736609b0f49c152f975eb63 (patch)
tree0eea3928e39e50fae91d4e68b21b1e6cbae25604 /filters/kspread/opencalc
downloadkoffice-8362bf63dea22bbf6736609b0f49c152f975eb63.tar.gz
koffice-8362bf63dea22bbf6736609b0f49c152f975eb63.zip
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
Diffstat (limited to 'filters/kspread/opencalc')
-rw-r--r--filters/kspread/opencalc/Makefile.am21
-rw-r--r--filters/kspread/opencalc/kspread_opencalc_export.desktop59
-rw-r--r--filters/kspread/opencalc/kspread_opencalc_import.desktop62
-rw-r--r--filters/kspread/opencalc/opencalcexport.cc1329
-rw-r--r--filters/kspread/opencalc/opencalcexport.h89
-rw-r--r--filters/kspread/opencalc/opencalcimport.cc2826
-rw-r--r--filters/kspread/opencalc/opencalcimport.h119
-rw-r--r--filters/kspread/opencalc/opencalcstyleexport.cc546
-rw-r--r--filters/kspread/opencalc/opencalcstyleexport.h167
-rw-r--r--filters/kspread/opencalc/status.html208
10 files changed, 5426 insertions, 0 deletions
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 <faure@kde.org>
+ Copyright (C) 2000 Norbert Andres <nandres@web.de>
+ Copyright (C) 2005 Laurent Montel <montel@kde.org>
+
+ 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 <float.h>
+#include <math.h>
+
+#include <opencalcexport.h>
+
+#include <qdatetime.h>
+#include <qdom.h>
+#include <qfile.h>
+#include <qregexp.h>
+#include <qvaluelist.h>
+
+#include <kdebug.h>
+#include <kmessagebox.h>
+#include <kmdcodec.h>
+#include <kgenericfactory.h>
+#include <klocale.h>
+
+#include <KoDocumentInfo.h>
+#include <KoFilterChain.h>
+#include <KoGlobal.h>
+
+#include <kspread_aboutdata.h>
+#include <kspread_cell.h>
+#include <kspread_doc.h>
+#include <kspread_format.h>
+#include <kspread_map.h>
+#include <kspread_view.h>
+#include <kspread_canvas.h>
+#include <kspread_sheet.h>
+#include <kspread_sheetprint.h>
+#include <kspread_style.h>
+#include <kspread_style_manager.h>
+#include <kspread_util.h>
+
+using namespace KSpread;
+
+typedef QValueList<Reference> AreaList;
+
+class OpenCalcExportFactory : KGenericFactory<OpenCalcExport, KoFilter>
+{
+public:
+ OpenCalcExportFactory(void) : KGenericFactory<OpenCalcExport, KoFilter> ("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<const KSpread::Doc *>( 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<const Doc *>(document);
+
+ if ( ksdoc->mimeType() != "application/x-kspread" )
+ {
+ kdWarning(30518) << "Invalid document mimetype " << ksdoc->mimeType() << endl;
+ return KoFilter::NotImplemented;
+ }
+
+ m_locale = static_cast<Doc*>(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<KoDocumentInfoAbout *>( docInfo->page( "about" ) );
+ KoDocumentInfoAuthor * authorPage = static_cast<KoDocumentInfoAuthor*>( 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:
+ <meta:creation-date>2003-01-08T23:57:31</meta:creation-date>
+ <dc:language>en-US</dc:language>
+ <meta:editing-cycles>2</meta:editing-cycles>
+ <meta:editing-duration>PT38S</meta:editing-duration>
+ <meta:user-defined meta:name="Info 3"/>
+ <meta:user-defined meta:name="Info 4"/>
+ */
+
+ 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<View*>( 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<Sheet> 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<Sheet> 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 : "<<range<<endl;
+ tabElem.setAttribute( "table:print-ranges", range );
+ }
+
+
+ tabElem.setAttribute( "table:name", name );
+
+ maxRowCols( sheet, maxCols, maxRows );
+
+ exportSheet( doc, tabElem, sheet, maxCols, maxRows );
+
+ body.appendChild( tabElem );
+ }
+
+ KoDocument * document = m_chain->inputDocument();
+ Doc * kspreadDoc = static_cast<Doc *>( 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<Doc *>(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<Sheet> 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<Sheet> 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 == "<page>" )
+ {
+ addText( text, doc, parent );
+
+ QDomElement page = doc.createElement( "text:page-number" );
+ page.appendChild( doc.createTextNode( "1" ) );
+ parent.appendChild( page );
+ }
+ else if ( var == "<pages>" )
+ {
+ addText( text, doc, parent );
+
+ QDomElement page = doc.createElement( "text:page-count" );
+ page.appendChild( doc.createTextNode( "99" ) );
+ parent.appendChild( page );
+ }
+ else if ( var == "<date>" )
+ {
+ 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 == "<time>" )
+ {
+ addText( text, doc, parent );
+
+ QDomElement t = doc.createElement( "text:time" );
+ t.appendChild( doc.createTextNode( QTime::currentTime().toString() ) );
+ parent.appendChild( t );
+ }
+ else if ( var == "<file>" ) // filepath + name
+ {
+ addText( text, doc, parent );
+
+ QDomElement t = doc.createElement( "text:file-name" );
+ t.setAttribute( "text:display", "full" );
+ t.appendChild( doc.createTextNode( "???" ) );
+ parent.appendChild( t );
+ }
+ else if ( var == "<name>" ) // filename
+ {
+ addText( text, doc, parent );
+
+ QDomElement t = doc.createElement( "text:title" );
+ t.appendChild( doc.createTextNode( "???" ) );
+ parent.appendChild( t );
+ }
+ else if ( var == "<author>" )
+ {
+ KoDocumentInfo * docInfo = ksdoc->documentInfo();
+ KoDocumentInfoAuthor * authorPage = static_cast<KoDocumentInfoAuthor*>( docInfo->page( "author" ) );
+
+ text += authorPage->fullName();
+
+ addText( text, doc, parent );
+ }
+ else if ( var == "<email>" )
+ {
+ KoDocumentInfo * docInfo = ksdoc->documentInfo();
+ KoDocumentInfoAuthor * authorPage = static_cast<KoDocumentInfoAuthor*>( docInfo->page( "author" ) );
+
+ text += authorPage->email();
+
+ addText( text, doc, parent );
+ }
+ else if ( var == "<org>" )
+ {
+ KoDocumentInfo * docInfo = ksdoc->documentInfo();
+ KoDocumentInfoAuthor * authorPage = static_cast<KoDocumentInfoAuthor*>( docInfo->page( "author" ) );
+
+ text += authorPage->company();
+
+ addText( text, doc, parent );
+ }
+ else if ( var == "<sheet>" )
+ {
+ addText( text, doc, parent );
+
+ QDomElement s = doc.createElement( "text:sheet-name" );
+ s.appendChild( doc.createTextNode( "???" ) );
+ parent.appendChild( s );
+ }
+ else
+ {
+ // no known variable:
+ text += var;
+ addText( text, doc, parent );
+ }
+
+ text = "";
+ var = "";
+ }
+ }
+ else
+ {
+ text += part[i];
+ }
+ ++i;
+ }
+ if ( !text.isEmpty() || !var.isEmpty() )
+ {
+ //we don't have var at the end =>store it
+ addText( text+var, doc, parent );
+ }
+}
+
+QString OpenCalcExport::convertFormula( QString const & formula ) const
+{
+ QChar decimalSymbol( '.' );
+ if ( m_locale )
+ {
+ const QString decimal ( m_locale->decimalSymbol() );
+ if ( !decimal.isEmpty() )
+ {
+ decimalSymbol = decimal.at( 0 );
+ }
+ }
+
+ QString s;
+ QRegExp exp("(\\$?)([a-zA-Z]+)(\\$?)([0-9]+)");
+ int n = exp.search( formula, 0 );
+ kdDebug(30518) << "Exp: " << formula << ", n: " << n << ", Length: " << formula.length()
+ << ", Matched length: " << exp.matchedLength() << endl;
+
+ bool inQuote1 = false;
+ bool inQuote2 = false;
+ int i = 0;
+ int l = (int) formula.length();
+ if ( l <= 0 )
+ return formula;
+ while ( i < l )
+ {
+ if ( ( n != -1 ) && ( n < i ) )
+ {
+ n = exp.search( formula, i );
+ kdDebug(30518) << "Exp: " << formula.right( l - i ) << ", n: " << n << endl;
+ }
+ if ( formula[i] == '"' )
+ {
+ inQuote1 = !inQuote1;
+ s += formula[i];
+ ++i;
+ continue;
+ }
+ if ( formula[i] == '\'' )
+ {
+ // named area
+ inQuote2 = !inQuote2;
+ ++i;
+ continue;
+ }
+ if ( inQuote1 || inQuote2 )
+ {
+ s += formula[i];
+ ++i;
+ continue;
+ }
+ if ( ( formula[i] == '=' ) && ( formula[i + 1] == '=' ) )
+ {
+ s += '=';
+ ++i;++i;
+ continue;
+ }
+ if ( formula[i] == '!' )
+ {
+ insertBracket( s );
+ s += '.';
+ ++i;
+ continue;
+ }
+ else if ( formula[i] == decimalSymbol )
+ {
+ s += '.'; // decimal point
+ ++i;
+ continue;
+ }
+ if ( n == i )
+ {
+ int ml = exp.matchedLength();
+ if ( formula[ i + ml ] == '!' )
+ {
+ kdDebug(30518) << "No cell ref but sheet name" << endl;
+ s += formula[i];
+ ++i;
+ continue;
+ }
+ if ( ( i > 0 ) && ( formula[i - 1] != '!' ) )
+ s += "[.";
+ for ( int j = 0; j < ml; ++j )
+ {
+ s += formula[i];
+ ++i;
+ }
+ s += ']';
+ continue;
+ }
+
+ s += formula[i];
+ ++i;
+ }
+
+ return s;
+}
+
+bool OpenCalcExport::writeMetaFile( KoStore * store, uint filesWritten )
+{
+ store->enterDirectory( "META-INF" );
+ if ( !store->open( "manifest.xml" ) )
+ return false;
+
+ QDomImplementation impl;
+ QDomDocumentType type( impl.createDocumentType( "manifest:manifest", "-//OpenOffice.org//DTD Manifest 1.0//EN", "Manifest.dtd" ) );
+
+ QDomDocument meta( type );
+ meta.appendChild( meta.createProcessingInstruction( "xml","version=\"1.0\" encoding=\"UTF-8\"" ) );
+
+ QDomElement content = meta.createElement( "manifest:manifest" );
+ content.setAttribute( "xmlns:manifest", "http://openoffice.org/2001/manifest" );
+
+ QDomElement entry = meta.createElement( "manifest:file-entry" );
+ entry.setAttribute( "manifest:media-type", "application/vnd.sun.xml.calc" );
+ entry.setAttribute( "manifest:full-path", "/" );
+ content.appendChild( entry );
+
+ entry = meta.createElement( "manifest:file-entry" );
+ content.appendChild( entry );
+
+ if ( filesWritten & contentXML )
+ {
+ entry = meta.createElement( "manifest:file-entry" );
+ entry.setAttribute( "manifest:media-type", "text/xml" );
+ entry.setAttribute( "manifest:full-path", "content.xml" );
+ content.appendChild( entry );
+ }
+
+ if ( filesWritten & stylesXML )
+ {
+ entry = meta.createElement( "manifest:file-entry" );
+ entry.setAttribute( "manifest:media-type", "text/xml" );
+ entry.setAttribute( "manifest:full-path", "styles.xml" );
+ content.appendChild( entry );
+ }
+
+ if ( filesWritten & metaXML )
+ {
+ entry = meta.createElement( "manifest:file-entry" );
+ entry.setAttribute( "manifest:media-type", "text/xml" );
+ entry.setAttribute( "manifest:full-path", "meta.xml" );
+ content.appendChild( entry );
+ }
+
+ if ( filesWritten & settingsXML )
+ {
+ entry = meta.createElement( "manifest:file-entry" );
+ entry.setAttribute( "manifest:media-type", "text/xml" );
+ entry.setAttribute( "manifest:full-path", "settings.xml" );
+ content.appendChild( entry );
+ }
+
+ meta.appendChild( content );
+
+ QCString doc( meta.toCString() );
+ kdDebug(30518) << "Manifest: " << doc << endl;
+
+ store->write( doc, doc.length() );
+
+ if ( !store->close() )
+ return false;
+
+ return true;
+}
+
+#include <opencalcexport.moc>
diff --git a/filters/kspread/opencalc/opencalcexport.h b/filters/kspread/opencalc/opencalcexport.h
new file mode 100644
index 000000000..6a265fce5
--- /dev/null
+++ b/filters/kspread/opencalc/opencalcexport.h
@@ -0,0 +1,89 @@
+/* This file is part of the KDE project
+ Copyright (C) 2000 - 2003 David Faure <faure@kde.org>
+ Copyright (C) 2003 Norbert Andres <nandres@web.de>
+
+ 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.
+*/
+
+#ifndef OPENCALCEXPORT_H
+#define OPENCALCEXPORT_H
+
+#include "opencalcstyleexport.h"
+
+#include <KoFilter.h>
+#include <qptrlist.h>
+
+class QDomDocument;
+class QDomElement;
+class KLocale;
+class KoStore;
+
+namespace KSpread
+{
+class Doc;
+class Sheet;
+}
+
+class OpenCalcExport : public KoFilter
+{
+ Q_OBJECT
+
+ public:
+ OpenCalcExport( KoFilter * parent, const char * name, const QStringList & );
+ virtual ~OpenCalcExport() {}
+
+ virtual KoFilter::ConversionStatus convert( const QCString & from,
+ const QCString & to );
+
+ private:
+ enum files { metaXML = 0x01, contentXML = 0x02, stylesXML = 0x04, settingsXML = 0x08 };
+ OpenCalcStyles m_styles;
+
+ bool writeFile( const KSpread::Doc * ksdoc );
+
+ bool exportDocInfo( KoStore * store, const KSpread::Doc * ksdoc );
+ bool exportStyles ( KoStore * store, const KSpread::Doc * ksdoc );
+ bool exportContent( KoStore * store, const KSpread::Doc * ksdoc );
+ bool exportSettings( KoStore * store, const KSpread::Doc * ksdoc );
+
+ bool exportBody( QDomDocument & doc, QDomElement & content, const KSpread::Doc * ksdoc );
+ void exportSheet( QDomDocument & doc, QDomElement & tabElem,
+ const KSpread::Sheet * sheet, int maxCols, int maxRows );
+ void exportCells( QDomDocument & doc, QDomElement & rowElem,
+ const KSpread::Sheet * sheet, int row, int maxCols );
+ void exportDefaultCellStyle( QDomDocument & doc, QDomElement & officeStyles );
+ void exportPageAutoStyles( QDomDocument & doc, QDomElement & autoStyles,
+ const KSpread::Doc * ksdoc );
+ void exportMasterStyles( QDomDocument & doc, QDomElement & masterStyles,
+ const KSpread::Doc *ksdoc );
+
+ bool writeMetaFile( KoStore * store, uint filesWritten );
+
+ void maxRowCols( const KSpread::Sheet * sheet,
+ int & maxCols, int & maxRows );
+ void convertPart( QString const & part, QDomDocument & doc,
+ QDomElement & parent, const KSpread::Doc * ksdoc );
+ void addText( QString const & text, QDomDocument & doc,
+ QDomElement & parent );
+
+ void createDefaultStyles();
+ QString convertFormula( QString const & formula ) const;
+private:
+ /// Pointer to the KSpread locale
+ KLocale* m_locale;
+};
+
+#endif
diff --git a/filters/kspread/opencalc/opencalcimport.cc b/filters/kspread/opencalc/opencalcimport.cc
new file mode 100644
index 000000000..8330519f1
--- /dev/null
+++ b/filters/kspread/opencalc/opencalcimport.cc
@@ -0,0 +1,2826 @@
+/* This file is part of the KDE project
+ Copyright (C) 2002 Norbert Andres <nandres@web.de>
+ Copyright (C) 2004 - 2005 Laurent Montel <montel@kde.org>
+
+ 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 <float.h>
+#include <math.h>
+
+#include <qcolor.h>
+#include <qfile.h>
+#include <qfont.h>
+#include <qpen.h>
+#include <qxml.h>
+
+#include "opencalcimport.h"
+
+#include <kdebug.h>
+#include <KoDocumentInfo.h>
+#include <kgenericfactory.h>
+#include <kmessagebox.h>
+#include <kmdcodec.h>
+#include <KoFilterChain.h>
+#include <KoGlobal.h>
+#include <KoUnit.h>
+#include <KoStyleStack.h>
+#include <KoDom.h>
+#include <ooutils.h>
+
+#include <kspread_cell.h>
+#include <kspread_condition.h>
+#include <kspread_doc.h>
+#include <kspread_global.h>
+#include <kspread_map.h>
+#include <kspread_sheet.h>
+#include <kspread_sheetprint.h>
+#include <kspread_style.h>
+#include <kspread_style_manager.h>
+#include <kspread_util.h>
+#include <kspread_value.h>
+
+#define SECSPERDAY (24 * 60 * 60)
+
+using namespace KSpread;
+
+class OpenCalcImportFactory : KGenericFactory<OpenCalcImport, KoFilter>
+{
+public:
+ OpenCalcImportFactory(void) : KGenericFactory<OpenCalcImport, KoFilter> ("kspreadopencalcimport")
+ {}
+protected:
+ virtual void setupTranslations( void )
+ {
+ KGlobal::locale()->insertCatalogue( "kofficefilters" );
+ }
+};
+
+K_EXPORT_COMPONENT_FACTORY( libopencalcimport, OpenCalcImportFactory() )
+
+OpenCalcImport::OpenCalcPoint::OpenCalcPoint( QString const & str )
+ : isRange( false )
+{
+ bool inQuote = false;
+
+ int l = str.length();
+ int colonPos = -1;
+ QString range;
+
+ // replace '.' with '!'
+ for ( int i = 0; i < l; ++i )
+ {
+ if ( str[i] == '$' )
+ continue;
+ if ( str[i] == '\'' )
+ {
+ inQuote = !inQuote;
+ }
+ else if ( str[i] == '.' )
+ {
+ if ( !inQuote )
+ {
+ if ( i != 0 && i != (colonPos + 1) ) // no empty table names
+ range += '!';
+ }
+ else
+ range += '.';
+ }
+ else if ( str[i] == ':' )
+ {
+ if ( !inQuote )
+ {
+ isRange = true;
+ colonPos = i;
+ }
+ range += ':';
+ }
+ else
+ range += str[i];
+ }
+
+ translation = range;
+
+ if ( isRange )
+ {
+ KSpread::Range newRange( range );
+ table = newRange.sheetName();
+ topLeft = newRange.range().topLeft();
+ botRight = newRange.range().bottomRight();
+ }
+ else
+ {
+ Point newPoint( range );
+ table = newPoint.sheetName();
+ topLeft = newPoint.pos();
+ botRight = newPoint.pos();
+ }
+}
+
+
+OpenCalcImport::OpenCalcImport( KoFilter *, const char *, const QStringList & )
+ : KoFilter(),
+ m_styles( 17, true ),
+ m_defaultStyles( 17, true ),
+ m_formats( 17, true )
+{
+ m_styles.setAutoDelete( true );
+ m_defaultStyles.setAutoDelete( true );
+ m_formats.setAutoDelete( true );
+}
+
+OpenCalcImport::~OpenCalcImport()
+{
+}
+
+double timeToNum( int h, int m, int s )
+{
+ int secs = h * 3600 + m * 60 + s;
+ return (double) secs / (double) SECSPERDAY;
+}
+
+bool OpenCalcImport::readRowFormat( QDomElement & rowNode, QDomElement * rowStyle,
+ Sheet * table, int & row, int & number,
+ bool isLast )
+{
+ if ( rowNode.isNull() )
+ return false;
+
+ QDomNode node;
+ if ( rowStyle )
+ {
+ node = rowStyle->firstChild();
+ kdDebug(30518) << "RowStyle: " << rowStyle << ", " << rowStyle->tagName() << endl;
+ }
+
+ double height = -1.0;
+ bool insertPageBreak = false;
+ Format layout( table, table->doc()->styleManager()->defaultStyle() );
+
+ while( !node.isNull() )
+ {
+ QDomElement property = node.toElement();
+
+ kdDebug(30518) << "Row: Child exists: " << property.tagName() << endl;
+ if ( !property.isNull() && property.localName() == "properties" && property.namespaceURI() == ooNS::style )
+ {
+ if ( property.hasAttributeNS( ooNS::style, "row-height" ) )
+ {
+ height = KoUnit::parseValue( property.attributeNS( ooNS::style, "row-height", QString::null ) , -1 );
+ }
+
+ if ( property.hasAttributeNS( ooNS::fo, "break-before" ) )
+ {
+ if ( property.attributeNS( ooNS::fo, "break-before", QString::null ) == "page" )
+ {
+ insertPageBreak = true;
+ }
+ }
+
+ loadStyleProperties( &layout, property );
+ }
+
+ node = node.nextSibling();
+ }
+
+ if ( rowNode.hasAttributeNS( ooNS::table, "number-rows-repeated" ) )
+ {
+ bool ok = true;
+ int n = rowNode.attributeNS( ooNS::table, "number-rows-repeated", QString::null ).toInt( &ok );
+ if ( ok )
+ number = n;
+ kdDebug(30518) << "Row repeated: " << number << endl;
+ }
+
+ if ( isLast )
+ {
+ if ( number > 30 )
+ number = 30;
+ }
+ else
+ {
+ if ( number > 256 )
+ number = 256;
+ }
+
+ for ( int i = 0; i < number; ++i )
+ {
+ RowFormat * rowL = table->nonDefaultRowFormat( row );
+ rowL->copy( layout );
+
+ if ( height != -1 )
+ {
+ kdDebug(30518) << "Setting row height to " << height << endl;
+ rowL->setHeight( int( height ) );
+ }
+
+ // if ( insertPageBreak ) TODO:
+ // rowL->setPageBreak( true )
+
+ // kdDebug(30518) << "Added RowFormat: " << row << endl;
+ ++row;
+ }
+
+ return true;
+}
+
+QString OpenCalcImport::translatePar( QString & par ) const
+{
+ OpenCalcPoint point( par );
+ kdDebug(30518) << " Parameter: " << par << ", Translation: " << point.translation << endl;
+
+ return point.translation;
+}
+
+void OpenCalcImport::checkForNamedAreas( QString & formula ) const
+{
+ int l = formula.length();
+ int i = 0;
+ QString word;
+ int start = 0;
+ while ( i < l )
+ {
+ if ( formula[i].isLetterOrNumber() )
+ {
+ word += formula[i];
+ ++i;
+ continue;
+ }
+ if ( word.length() > 0 )
+ {
+ if ( m_namedAreas.find( word ) != m_namedAreas.end() )
+ {
+ formula = formula.replace( start, word.length(), "'" + word + "'" );
+ l = formula.length();
+ ++i;
+ kdDebug(30518) << "Formula: " << formula << ", L: " << l << ", i: " << i + 1 <<endl;
+ }
+ }
+
+ ++i;
+ word = "";
+ start = i;
+ }
+ if ( word.length() > 0 )
+ {
+ if ( m_namedAreas.find( word ) != m_namedAreas.end() )
+ {
+ formula = formula.replace( start, word.length(), "'" + word + "'" );
+ l = formula.length();
+ ++i;
+ kdDebug(30518) << "Formula: " << formula << ", L: " << l << ", i: " << i + 1 <<endl;
+ }
+ }
+}
+
+void OpenCalcImport::convertFormula( QString & text, QString const & f ) const
+{
+ kdDebug(30518) << "Parsing formula: " << f << endl;
+
+ QString formula;
+ QString parameter;
+
+ int l = f.length();
+ int p = 0;
+
+ while ( p < l )
+ {
+ if ( f[p] == '(' || f[p] == '[' )
+ {
+ break;
+ }
+
+ formula += f[p];
+ ++p;
+ }
+
+ if ( parameter.isEmpty() )
+ {
+ checkForNamedAreas( formula );
+ }
+
+ kdDebug(30518) << "Formula: " << formula << ", Parameter: " << parameter << ", P: " << p << endl;
+
+
+ // replace formula names here
+ if ( formula == "=MULTIPLE.OPERATIONS" )
+ formula = "=MULTIPLEOPERATIONS";
+
+ QString par;
+ bool isPar = false;
+ bool inQuote = false;
+
+ while ( p < l )
+ {
+ if ( f[p] == '"' )
+ {
+ inQuote = !inQuote;
+ parameter += '"';
+ }
+ else if ( f[p] == '[' )
+ {
+ if ( !inQuote )
+ isPar = true;
+ else
+ parameter += '[';
+ }
+ else if ( f[p] == ']' )
+ {
+ if ( inQuote )
+ {
+ parameter += ']';
+ continue;
+ }
+
+ isPar = false;
+ parameter += translatePar( par );
+ par = "";
+ }
+ else if ( isPar )
+ {
+ par += f[p];
+ }
+ else if ( f[p] == '=' ) // TODO: check if StarCalc has a '==' sometimes
+ {
+ if ( inQuote )
+ parameter += '=';
+ else
+ parameter += "==";
+ }
+ else if ( f[p] == ')' )
+ {
+ if ( !inQuote )
+ parameter += ")";
+ }
+ else
+ parameter += f[p];
+
+ ++p;
+ if ( p == l )
+ checkForNamedAreas( parameter );
+ }
+
+ text = formula + parameter;
+ kdDebug(30518) << "New formula: " << text << endl;
+}
+
+bool OpenCalcImport::readCells( QDomElement & rowNode, Sheet * table, int row, int & columns )
+{
+ bool ok = true;
+ int spanC = 1;
+ int spanR = 1;
+ //Cell* defCell = table->defaultCell();
+
+ QDomNode cellNode = KoDom::namedItemNS( rowNode, ooNS::table, "table-cell" );
+
+ while ( !cellNode.isNull() )
+ {
+ spanR = 1; spanC = 1;
+
+ QDomElement e = cellNode.toElement();
+ if ( e.isNull() )
+ {
+ ++columns;
+
+ cellNode = cellNode.nextSibling();
+ continue;
+ }
+
+ Cell* cell = 0;
+
+ kdDebug(30518) << " Cell: " << columns << ", " << row << endl;
+
+ // ="3" table:number-rows-spanned="1"
+ if ( e.hasAttributeNS( ooNS::table, "number-columns-spanned" ) )
+ {
+ int span = e.attributeNS( ooNS::table, "number-columns-spanned", QString::null ).toInt( &ok );
+ if ( ok )
+ spanC = span;
+ }
+ if ( e.hasAttributeNS( ooNS::table, "number-rows-spanned" ) )
+ {
+ int span = e.attributeNS( ooNS::table, "number-rows-spanned", QString::null ).toInt( &ok );
+ if ( ok )
+ spanR = span;
+ }
+
+ QString text;
+ QDomElement textP = KoDom::namedItemNS( e, ooNS::text, "p" );
+ if ( !textP.isNull() )
+ {
+ QDomElement subText = textP.firstChild().toElement(); // ## wrong
+ if ( !subText.isNull() )
+ {
+ // something in <text:p>, e.g. links
+ text = subText.text();
+
+ if ( subText.hasAttributeNS( ooNS::xlink, "href" ) )
+ {
+ QString link = subText.attributeNS( ooNS::xlink, "href", QString::null );
+ if ( link[0]=='#' )
+ link=link.remove( 0, 1 );
+ if ( !cell )
+ cell = table->nonDefaultCell( columns, row );
+ cell->setLink( link );
+ }
+ }
+ else
+ text = textP.text(); // our text, could contain formating for value or result of formula
+ }
+ QDomElement annotation = KoDom::namedItemNS( e, ooNS::office, "annotation" );
+ if ( !annotation.isNull() )
+ {
+ QString comment;
+ QDomNode node = annotation.firstChild();
+ while( !node.isNull() )
+ {
+ QDomElement commentElement = node.toElement();
+ if( !commentElement.isNull() )
+ if ( commentElement.localName() == "p" && e.namespaceURI()==ooNS::text)
+ {
+ if( !comment.isEmpty() ) comment.append( '\n' );
+ comment.append( commentElement.text() );
+ }
+
+ node = node.nextSibling();
+ }
+
+ if( !comment.isEmpty() )
+ {
+ if ( !cell )
+ cell = table->nonDefaultCell( columns, row );
+ kdDebug(30518)<<" columns :"<<columns<<" row :"<<row<<endl;
+ cell->format()->setComment( comment );
+ }
+ }
+
+ kdDebug(30518) << "Contains: " << text << endl;
+ bool isFormula = false;
+
+ if ( e.hasAttributeNS( ooNS::table, "style-name" ) )
+ {
+ if ( !cell )
+ cell = table->nonDefaultCell( columns, row );
+
+ QString psName( "Default" );
+ if ( e.hasAttributeNS( ooNS::style, "parent-style-name" ) )
+ psName = e.attributeNS( ooNS::style, "parent-style-name", QString::null );
+
+ kdDebug(30518) << "Default style: " << psName << endl;
+ Format * layout = m_defaultStyles[psName];
+
+ if ( layout )
+ cell->format()->copy( *layout );
+
+ QDomElement * st = 0;
+ if ( e.hasAttributeNS( ooNS::table, "style-name" ) )
+ {
+ kdDebug(30518) << "Style: " << e.attributeNS( ooNS::table, "style-name", QString::null ) << endl;
+ st = m_styles[ e.attributeNS( ooNS::table, "style-name", QString::null ) ];
+ }
+ if ( st )
+ {
+ kdDebug(30518) << "Style: adapting " << endl;
+ QDomNode node = st->firstChild();
+ bool foundValidation = false;
+ while( !node.isNull() )
+ {
+ QDomElement property = node.toElement();
+ if ( !property.isNull() )
+ {
+ kdDebug(30518)<<"property.tagName() :"<<property.tagName()<<endl;
+ if ( property.localName()=="map" && property.namespaceURI() == ooNS::style && !foundValidation)
+ {
+ loadCondition( cell, property );
+ foundValidation = true;
+ }
+ if ( property.localName() == "properties" && property.namespaceURI() == ooNS::style )
+ {
+ loadStyleProperties( cell->format(), property );
+ if ( cell->format()->getAngle( columns, row ) != 0 )
+ {
+ QFontMetrics fm( cell->format()->textFont( columns, row ) );
+ int tmpAngle = cell->format()->getAngle( columns, row );
+ int textHeight = static_cast<int>( cos( tmpAngle * M_PI / 180 )
+ * ( fm.ascent() + fm.descent() )
+ + abs ( ( int )( fm.width( cell->strOutText() )
+ * sin( tmpAngle * M_PI / 180 ) ) ) );
+ /*
+ int textWidth = static_cast<int>( abs ( ( int ) ( sin( tmpAngle * M_PI / 180 )
+ * ( fm.ascent() + fm.descent() ) ) )
+ + fm.width( cell->strOutText() )
+ * cos( tmpAngle * M_PI / 180 ) );
+ */
+ kdDebug(30518) << "Rotation: height: " << textHeight << endl;
+
+ RowFormat * l = table->rowFormat( row );
+ if ( l->height() < textHeight )
+ {
+ if ( l->isDefault() )
+ l = table->nonDefaultRowFormat( row );
+
+ l->setHeight( textHeight + 2 );
+ }
+ }
+ }
+ }
+ node = node.nextSibling();
+ }
+ }
+ }
+ else
+ {
+ if ( !cell )
+ cell = table->nonDefaultCell( columns, row );
+
+ QString psName( "Default" );
+ kdDebug(30518) << "Default style: " << psName << endl;
+ Format * layout = m_defaultStyles[psName];
+
+ if ( layout )
+ cell->format()->copy( *layout );
+ }
+ if ( e.hasAttributeNS( ooNS::table, "formula" ) )
+ {
+ isFormula = true;
+ QString formula;
+ convertFormula( formula, e.attributeNS( ooNS::table, "formula", QString::null ) );
+
+ if ( !cell )
+ cell = table->nonDefaultCell( columns, row );
+ cell->setCellText( formula );
+ }
+ if ( e.hasAttributeNS( ooNS::table, "validation-name" ) )
+ {
+ kdDebug(30518)<<" Celle has a validation :"<<e.attributeNS( ooNS::table, "validation-name", QString::null )<<endl;
+ loadOasisValidation( cell->getValidity(), e.attributeNS( ooNS::table, "validation-name", QString::null ) );
+ }
+ if ( e.hasAttributeNS( ooNS::table, "value-type" ) )
+ {
+ if ( !cell )
+ cell = table->nonDefaultCell( columns, row );
+
+ cell->setCellText( text );
+
+ QString value = e.attributeNS( ooNS::table, "value", QString::null );
+ QString type = e.attributeNS( ooNS::table, "value-type", QString::null );
+
+ kdDebug(30518) << "Value: " << value << ", type: " << type << endl;
+
+ bool ok = false;
+ double dv = 0.0;
+
+ if ( ( type == "float" ) || ( type == "currency" ) )
+ {
+ dv = value.toDouble( &ok );
+ if ( ok )
+ {
+ if ( !isFormula )
+ cell->setValue( dv );
+
+ if ( type == "currency" )
+ {
+ cell->format()->setCurrency( 1, e.attributeNS( ooNS::table, "currency", QString::null ) );
+ cell->format()->setFormatType( Money_format );
+ }
+ }
+ }
+ else
+ if ( type == "percentage" )
+ {
+ dv = value.toDouble( &ok );
+ if ( ok )
+ {
+ if ( !isFormula )
+ cell->setValue( dv );
+ //TODO fixme
+ //cell->setFactor( 100 );
+ // TODO: replace with custom...
+ cell->format()->setFormatType( Percentage_format );
+ }
+ }
+ else if ( type == "boolean" )
+ {
+ if ( value.isEmpty() )
+ value = e.attributeNS( ooNS::table, "boolean-value", QString::null );
+
+ kdDebug(30518) << "Type: boolean" << endl;
+ if ( value == "true" )
+ cell->setValue( true );
+ else
+ cell->setValue( false );
+ ok = true;
+ cell->format()->setFormatType( Custom_format );
+ }
+ else if ( type == "date" )
+ {
+ if ( value.isEmpty() )
+ value = e.attributeNS( ooNS::table, "date-value", QString::null );
+ kdDebug(30518) << "Type: date, value: " << value << endl;
+
+ // "1980-10-15"
+ int year=0, month=0, day=0;
+ ok = false;
+
+ int p1 = value.find( '-' );
+ if ( p1 > 0 )
+ year = value.left( p1 ).toInt( &ok );
+
+ kdDebug(30518) << "year: " << value.left( p1 ) << endl;
+
+ int p2 = value.find( '-', ++p1 );
+
+ if ( ok )
+ month = value.mid( p1, p2 - p1 ).toInt( &ok );
+
+ kdDebug(30518) << "month: " << value.mid( p1, p2 - p1 ) << endl;
+
+ if ( ok )
+ day = value.right( value.length() - p2 - 1 ).toInt( &ok );
+
+ kdDebug(30518) << "day: " << value.right( value.length() - p2 ) << endl;
+
+ if ( ok )
+ {
+ QDateTime dt( QDate( year, month, day ) );
+ // KSpreadValue kval( dt );
+ // cell->setValue( kval );
+ cell->setValue( QDate( year, month, day ) );
+ kdDebug(30518) << "Set QDate: " << year << " - " << month << " - " << day << endl;
+ }
+ }
+ else if ( type == "time" )
+ {
+ if ( value.isEmpty() )
+ value = e.attributeNS( ooNS::table, "time-value", QString::null );
+
+ kdDebug(30518) << "Type: time: " << value << endl;
+ // "PT15H10M12S"
+ int hours=0, minutes=0, seconds=0;
+ int l = value.length();
+ QString num;
+
+ for ( int i = 0; i < l; ++i )
+ {
+ if ( value[i].isNumber() )
+ {
+ num += value[i];
+ continue;
+ }
+ else if ( value[i] == 'H' )
+ hours = num.toInt( &ok );
+ else if ( value[i] == 'M' )
+ minutes = num.toInt( &ok );
+ else if ( value[i] == 'S' )
+ seconds = num.toInt( &ok );
+ else
+ continue;
+
+ kdDebug(30518) << "Num: " << num << endl;
+
+ num = "";
+ if ( !ok )
+ break;
+ }
+
+ kdDebug(30518) << "Hours: " << hours << ", " << minutes << ", " << seconds << endl;
+
+ if ( ok )
+ {
+ // KSpreadValue kval( timeToNum( hours, minutes, seconds ) );
+ // cell->setValue( kval );
+ cell->setValue( QTime( hours % 24, minutes, seconds ) );
+ cell->format()->setFormatType( Custom_format );
+ }
+ }
+
+
+ if ( !ok ) // just in case we couldn't set the value directly
+ cell->setCellText( text );
+ }
+ else if ( !text.isEmpty() )
+ {
+ if ( !cell )
+ cell = table->nonDefaultCell( columns, row );
+ cell->setCellText( text );
+ }
+
+ if ( spanR > 1 || spanC > 1 )
+ {
+ if ( !cell )
+ cell = table->nonDefaultCell( columns, row );
+ cell->mergeCells( columns, row, spanC - 1, spanR - 1 );
+ }
+
+ cellNode = cellNode.nextSibling();
+
+ if ( e.hasAttributeNS( ooNS::table, "number-columns-repeated" ) )
+ {
+ // copy cell from left
+ bool ok = false;
+ int number = e.attributeNS( ooNS::table, "number-columns-repeated", QString::null ).toInt( &ok );
+ Cell* cellDest = 0;
+
+ // don't repeat more than 10 if it is the last cell and empty
+ if ( !ok || cellNode.isNull() )
+ {
+ if ( number > 10 )
+ number = 10;
+ }
+
+ for ( int i = 1; i < number; ++i )
+ {
+ ++columns;
+
+ if ( cell )
+ {
+ cellDest = table->nonDefaultCell( columns, row );
+ cellDest->copyAll( cell );
+ }
+ }
+ }
+
+ ++columns;
+ }
+
+ return true;
+}
+
+
+void OpenCalcImport::loadCondition( Cell*cell,const QDomElement &property )
+{
+ kdDebug(30518)<<"void OpenCalcImport::loadCondition( Cell*cell,const QDomElement &property )*******\n";
+ loadOasisCondition( cell, property );
+}
+
+void OpenCalcImport::loadOasisCondition(Cell*cell,const QDomElement &property )
+{
+ QDomElement elementItem( property );
+ StyleManager * manager = cell->sheet()->doc()->styleManager();
+
+ QValueList<Conditional> cond;
+ while ( !elementItem.isNull() )
+ {
+ kdDebug(30518)<<"elementItem.tagName() :"<<elementItem.tagName()<<endl;
+
+ if ( elementItem.localName()== "map" && property.namespaceURI() == ooNS::style )
+ {
+ bool ok = true;
+ kdDebug(30518)<<"elementItem.attribute(style:condition ) :"<<elementItem.attributeNS( ooNS::style, "condition", QString::null )<<endl;
+ Conditional newCondition;
+ loadOasisConditionValue( elementItem.attributeNS( ooNS::style, "condition", QString::null ), newCondition );
+ if ( elementItem.hasAttributeNS( ooNS::style, "apply-style-name" ) )
+ {
+ kdDebug(30518)<<"elementItem.attribute( style:apply-style-name ) :"<<elementItem.attributeNS( ooNS::style, "apply-style-name", QString::null )<<endl;
+ newCondition.styleName = new QString( elementItem.attributeNS( ooNS::style, "apply-style-name", QString::null ) );
+ newCondition.style = manager->style( *newCondition.styleName );
+ if ( !newCondition.style )
+ ok = false;
+ else
+ ok = true;
+ }
+
+ if ( ok )
+ cond.append( newCondition );
+ else
+ kdDebug(30518) << "Error loading condition " << elementItem.nodeName()<< endl;
+ }
+ elementItem = elementItem.nextSibling().toElement();
+ }
+ if ( !cond.isEmpty() )
+ cell->setConditionList( cond );
+}
+
+void OpenCalcImport::loadOasisConditionValue( const QString &styleCondition, Conditional &newCondition )
+{
+ QString val( styleCondition );
+ if ( val.contains( "cell-content()" ) )
+ {
+ val = val.remove( "cell-content()" );
+ loadOasisCondition( val,newCondition );
+ }
+ //GetFunction ::= cell-content-is-between(Value, Value) | cell-content-is-not-between(Value, Value)
+ //for the moment we support just int/double value, not text/date/time :(
+ if ( val.contains( "cell-content-is-between(" ) )
+ {
+ val = val.remove( "cell-content-is-between(" );
+ val = val.remove( ")" );
+ QStringList listVal = QStringList::split( "," , val );
+ loadOasisValidationValue( listVal, newCondition );
+ newCondition.cond = Conditional::Between;
+ }
+ if ( val.contains( "cell-content-is-not-between(" ) )
+ {
+ val = val.remove( "cell-content-is-not-between(" );
+ val = val.remove( ")" );
+ QStringList listVal = QStringList::split( ",", val );
+ loadOasisValidationValue( listVal,newCondition );
+ newCondition.cond = Conditional::Different;
+ }
+
+}
+
+
+void OpenCalcImport::loadOasisCondition( QString &valExpression, Conditional &newCondition )
+{
+ QString value;
+ if (valExpression.find( "<=" )==0 )
+ {
+ value = valExpression.remove( 0,2 );
+ newCondition.cond = Conditional::InferiorEqual;
+ }
+ else if (valExpression.find( ">=" )==0 )
+ {
+ value = valExpression.remove( 0,2 );
+ newCondition.cond = Conditional::SuperiorEqual;
+ }
+ else if (valExpression.find( "!=" )==0 )
+ {
+ //add Differentto attribute
+ value = valExpression.remove( 0,2 );
+ newCondition.cond = Conditional::DifferentTo;
+ }
+ else if ( valExpression.find( "<" )==0 )
+ {
+ value = valExpression.remove( 0,1 );
+ newCondition.cond = Conditional::Inferior;
+ }
+ else if(valExpression.find( ">" )==0 )
+ {
+ value = valExpression.remove( 0,1 );
+ newCondition.cond = Conditional::Superior;
+ }
+ else if (valExpression.find( "=" )==0 )
+ {
+ value = valExpression.remove( 0,1 );
+ newCondition.cond = Conditional::Equal;
+ }
+ else
+ kdDebug(30518)<<" I don't know how to parse it :"<<valExpression<<endl;
+ kdDebug(30518)<<" value :"<<value<<endl;
+ bool ok = false;
+ newCondition.val1 = value.toDouble(&ok);
+ if ( !ok )
+ {
+ newCondition.val1 = value.toInt(&ok);
+ if ( !ok )
+ {
+ newCondition.strVal1 = new QString( value );
+ kdDebug(30518)<<" Try to parse this value :"<<value<<endl;
+ }
+
+ }
+}
+
+
+void OpenCalcImport::loadOasisValidationValue( const QStringList &listVal, Conditional &newCondition )
+{
+ bool ok = false;
+ kdDebug(30518)<<" listVal[0] :"<<listVal[0]<<" listVal[1] :"<<listVal[1]<<endl;
+
+ newCondition.val1 = listVal[0].toDouble(&ok);
+ if ( !ok )
+ {
+ newCondition.val1 = listVal[0].toInt(&ok);
+ if ( !ok )
+ {
+ newCondition.strVal1 = new QString( listVal[0] );
+ kdDebug(30518)<<" Try to parse this value :"<<listVal[0]<<endl;
+ }
+ }
+ ok=false;
+ newCondition.val2 = listVal[1].toDouble(&ok);
+ if ( !ok )
+ {
+ newCondition.val2 = listVal[1].toInt(&ok);
+ if ( !ok )
+ {
+ newCondition.strVal2 = new QString( listVal[1] );
+ kdDebug(30518)<<" Try to parse this value :"<<listVal[1]<<endl;
+ }
+ }
+}
+
+
+bool OpenCalcImport::readRowsAndCells( QDomElement & content, Sheet * table )
+{
+ kdDebug(30518) << endl << "Reading in rows " << endl;
+
+ int i = 1;
+ int row = 1;
+ int columns = 1;
+ int backupRow = 1;
+ QDomElement * rowStyle = 0;
+ //Cell* cell = 0;
+ //Cell* cellDest = 0;
+ //Cell* defCell = table->defaultCell();
+ QDomNode rowNode = KoDom::namedItemNS( content, ooNS::table, "table-row" );
+
+ while ( !rowNode.isNull() )
+ {
+ bool collapsed = false;
+
+ int number = 1;
+ QDomElement r = rowNode.toElement();
+
+ if ( r.isNull() )
+ return false;
+
+ if ( r.hasAttributeNS( ooNS::table, "style-name" ) )
+ {
+ QString style = r.attributeNS( ooNS::table, "style-name", QString::null );
+ rowStyle = m_styles[ style ];
+ kdDebug(30518) << "Row style: " << style << endl;
+ }
+
+ collapsed = ( r.attributeNS( ooNS::table, "visibility", QString::null ) == "collapse" );
+
+ backupRow = row;
+
+ rowNode = rowNode.nextSibling();
+
+ if ( !readRowFormat( r, rowStyle, table, row, number, rowNode.isNull() ) ) // updates "row"
+ return false;
+
+ if ( !readCells( r, table, backupRow, columns ) )
+ return false;
+
+ RowFormat * srcLayout = table->nonDefaultRowFormat( backupRow );
+ RowFormat * layout = 0;
+
+ if ( collapsed )
+ srcLayout->setHide( true );
+
+ for ( i = 1; i < number; ++i )
+ {
+ layout = table->nonDefaultRowFormat( backupRow + i );
+
+ layout->copy( *srcLayout );
+
+ /*
+ * TODO: Test: do we need to copy the cells, too?
+ * if so we will probably also need to copy them for repeated col layouts.
+ for ( j = 1; j <= columns; ++j )
+ {
+ Cell* cell = table->cellAt( j, backupRow );
+
+ kdDebug(30518) << "Cell: " << cell << "DefCell: " << defCell << endl;
+ if ( cell && (cell != defCell) )
+ {
+ cellDest = table->nonDefaultCell( j, backupRow + i );
+ cellDest->copyAll( cell );
+ }
+ }
+ */
+ }
+
+ rowStyle = 0;
+ columns = 1;
+ }
+
+ kdDebug(30518) << "Reading in rows done" << endl << endl;
+
+ return true;
+}
+
+bool OpenCalcImport::readColLayouts( QDomElement & content, Sheet * table )
+{
+ kdDebug(30518) << endl << "Reading in columns..." << endl;
+
+ QDomNode colLayout = KoDom::namedItemNS( content, ooNS::table, "table-column" );
+ int column = 1;
+
+ while ( !colLayout.isNull() )
+ {
+ if ( colLayout.nodeName() != "table:table-column" )
+ return true; // all cols read in.
+
+ QDomElement e = colLayout.toElement();
+
+ if ( e.isNull() )
+ return false; // error, that's it...
+
+ kdDebug(30518) << "New column: " << column << endl;
+
+ int number = 1;
+ double width = -1.0;
+ bool collapsed = ( e.attributeNS( ooNS::table, "visibility", QString::null ) == "collapse" );
+ bool insertPageBreak = false;
+ Format styleLayout( table, table->doc()->styleManager()->defaultStyle() );
+
+ kdDebug(30518) << "Check table:number-columns-repeated" << endl;
+ if ( e.hasAttributeNS( ooNS::table, "number-columns-repeated" ) )
+ {
+ bool ok = true;
+ number = e.attributeNS( ooNS::table, "number-columns-repeated", QString::null ).toInt( &ok );
+ if ( !ok )
+ number = 1;
+
+ kdDebug(30518) << "Repeated: " << number << endl;
+ }
+
+ kdDebug(30518) << "Checking table:default-cell-style-name" << endl;
+ if ( e.hasAttributeNS( ooNS::table, "default-cell-style-name" ) )
+ {
+ QString n( e.attributeNS( ooNS::table, "default-cell-style-name", QString::null ) );
+ kdDebug(30518) << "Has attribute default-cell-style-name: " << n << endl;
+ Format * defaultStyle = m_defaultStyles[ n ];
+ if ( !defaultStyle )
+ {
+ QString name = e.attributeNS( ooNS::table, "default-cell-style-name", QString::null );
+ QDomElement * st = m_styles[ name ];
+
+ kdDebug(30518) << "Default cell style: " << name << endl;
+
+ if ( st && !st->isNull() )
+ {
+ Format * layout = new Format( 0, m_doc->styleManager()->defaultStyle() );
+
+ readInStyle( layout, *st );
+
+ m_defaultStyles.insert( name, layout );
+ kdDebug(30518) << "Insert default cell style: " << name << endl;
+
+ defaultStyle = layout;
+ }
+ }
+
+ if ( defaultStyle )
+ {
+ // kdDebug(30518) << "Copying default style, Font: " << defaultStyle->font().toString() << endl;
+ styleLayout.copy( *defaultStyle );
+ }
+ }
+
+ QDomElement * colStyle = 0;
+ if ( e.hasAttributeNS( ooNS::table, "style-name" ) )
+ {
+ QString style = e.attributeNS( ooNS::table, "style-name", QString::null );
+ colStyle = m_styles[ style ];
+
+ kdDebug(30518) << "Col Style: " << style << endl;
+ }
+
+ QDomNode node;
+
+ if ( colStyle )
+ node = colStyle->firstChild();
+
+ while( !node.isNull() )
+ {
+ QDomElement property = node.toElement();
+ if ( !property.isNull() && property.localName() == "properties" && property.namespaceURI() == ooNS::style )
+ {
+ if ( property.hasAttributeNS( ooNS::style, "column-width" ) )
+ {
+ QString sWidth = property.attributeNS( ooNS::style, "column-width", QString::null );
+ width = KoUnit::parseValue( property.attributeNS( ooNS::style, "column-width", QString::null ), width );
+ kdDebug(30518) << "Col Width: " << sWidth << endl;
+ }
+
+ if ( property.hasAttributeNS( ooNS::fo, "break-before" ) )
+ {
+ if ( property.attributeNS( ooNS::fo, "break-before", QString::null ) == "page" )
+ {
+ insertPageBreak = true;
+ }
+ }
+
+ loadStyleProperties( &styleLayout, property );
+ }
+
+ node = node.nextSibling();
+ }
+
+ colLayout = colLayout.nextSibling();
+
+ if ( colLayout.isNull() && ( number > 30 ) )
+ number = 30;
+
+ for ( int i = 0; i < number; ++i )
+ {
+ kdDebug(30518) << "Inserting colLayout: " << column << endl;
+
+ ColumnFormat * col = new ColumnFormat( table, column );
+ col->copy( styleLayout );
+ if ( width != -1.0 )
+ col->setWidth( int( width ) );
+
+ // if ( insertPageBreak )
+ // col->setPageBreak( true )
+
+ if ( collapsed )
+ col->setHide( true );
+
+ table->insertColumnFormat( col );
+ ++column;
+ }
+ }
+
+ return true;
+}
+
+void replaceMacro( QString & text, QString const & old, QString const & newS )
+{
+ int n = text.find( old );
+ if ( n != -1 )
+ text = text.replace( n, old.length(), newS );
+}
+
+QString getPart( QDomNode const & part )
+{
+ QString result;
+ QDomElement e = KoDom::namedItemNS( part, ooNS::text, "p" );
+ while ( !e.isNull() )
+ {
+ QString text = e.text();
+ kdDebug(30518) << "PART: " << text << endl;
+
+ QDomElement macro = KoDom::namedItemNS( e, ooNS::text, "time" );
+ if ( !macro.isNull() )
+ replaceMacro( text, macro.text(), "<time>" );
+
+ macro = KoDom::namedItemNS( e, ooNS::text, "date" );
+ if ( !macro.isNull() )
+ replaceMacro( text, macro.text(), "<date>" );
+
+ macro = KoDom::namedItemNS( e, ooNS::text, "page-number" );
+ if ( !macro.isNull() )
+ replaceMacro( text, macro.text(), "<page>" );
+
+ macro = KoDom::namedItemNS( e, ooNS::text, "page-count" );
+ if ( !macro.isNull() )
+ replaceMacro( text, macro.text(), "<pages>" );
+
+ macro = KoDom::namedItemNS( e, ooNS::text, "sheet-name" );
+ if ( !macro.isNull() )
+ replaceMacro( text, macro.text(), "<sheet>" );
+
+ macro = KoDom::namedItemNS( e, ooNS::text, "title" );
+ if ( !macro.isNull() )
+ replaceMacro( text, macro.text(), "<name>" );
+
+ macro = KoDom::namedItemNS( e, ooNS::text, "file-name" );
+ if ( !macro.isNull() )
+ replaceMacro( text, macro.text(), "<file>" );
+
+ if ( !result.isEmpty() )
+ result += '\n';
+ result += text;
+ e = e.nextSibling().toElement();
+ }
+
+ return result;
+}
+
+void OpenCalcImport::loadTableMasterStyle( Sheet * table,
+ QString const & stylename )
+{
+ kdDebug(30518) << "Loading table master style: " << stylename << endl;
+
+ QDomElement * style = m_styles[ stylename ];
+
+ if ( !style )
+ {
+ kdDebug(30518) << "Master style not found! " << endl;
+ return;
+ }
+
+ QDomNode header = KoDom::namedItemNS( *style, ooNS::style, "header" );
+ kdDebug(30518) << "Style header " << endl;
+
+ QString hleft, hmiddle, hright;
+ QString fleft, fmiddle, fright;
+
+ if ( !header.isNull() )
+ {
+ kdDebug(30518) << "Header exists" << endl;
+ QDomNode part = KoDom::namedItemNS( header, ooNS::style, "region-left" );
+ if ( !part.isNull() )
+ {
+ hleft = getPart( part );
+ kdDebug(30518) << "Header left: " << hleft << endl;
+ }
+ else
+ kdDebug(30518) << "Style:region:left doesn't exist!" << endl;
+ part = KoDom::namedItemNS( header, ooNS::style, "region-center" );
+ if ( !part.isNull() )
+ {
+ hmiddle = getPart( part );
+ kdDebug(30518) << "Header middle: " << hmiddle << endl;
+ }
+ part = KoDom::namedItemNS( header, ooNS::style, "region-right" );
+ if ( !part.isNull() )
+ {
+ hright = getPart( part );
+ kdDebug(30518) << "Header right: " << hright << endl;
+ }
+ }
+
+ QDomNode footer = KoDom::namedItemNS( *style, ooNS::style, "footer" );
+
+ if ( !footer.isNull() )
+ {
+ QDomNode part = KoDom::namedItemNS( footer, ooNS::style, "region-left" );
+ if ( !part.isNull() )
+ {
+ fleft = getPart( part );
+ kdDebug(30518) << "Footer left: " << fleft << endl;
+ }
+ part = KoDom::namedItemNS( footer, ooNS::style, "region-center" );
+ if ( !part.isNull() )
+ {
+ fmiddle = getPart( part );
+ kdDebug(30518) << "Footer middle: " << fmiddle << endl;
+ }
+ part = KoDom::namedItemNS( footer, ooNS::style, "region-right" );
+ if ( !part.isNull() )
+ {
+ fright = getPart( part );
+ kdDebug(30518) << "Footer right: " << fright << endl;
+ }
+ }
+
+ table->print()->setHeadFootLine( hleft, hmiddle, hright,
+ fleft, fmiddle, fright );
+ if ( style->hasAttributeNS( ooNS::style, "page-master-name" ) )
+ {
+ QString masterPageLayoutStyleName=style->attributeNS( ooNS::style, "page-master-name", QString::null );
+ kdDebug(30518)<<"masterPageLayoutStyleName :"<<masterPageLayoutStyleName<<endl;
+ QDomElement *masterLayoutStyle = m_styles[masterPageLayoutStyleName];
+ kdDebug(30518)<<"masterLayoutStyle :"<<masterLayoutStyle<<endl;
+ if ( !masterLayoutStyle )
+ return;
+ KoStyleStack styleStack( ooNS::style, ooNS::fo );
+ styleStack.push( *masterLayoutStyle );
+ loadOasisMasterLayoutPage( table, styleStack );
+ }
+}
+
+void OpenCalcImport::loadOasisMasterLayoutPage( Sheet * table,KoStyleStack &styleStack )
+{
+ float left = 0.0;
+ float right = 0.0;
+ float top = 0.0;
+ float bottom = 0.0;
+ float width = 0.0;
+ float height = 0.0;
+ QString orientation = "Portrait";
+ QString format;
+
+ // Laurent : Why we stored layout information as Millimeter ?!!!!!
+ // kspread used point for all other attribute
+ // I don't understand :(
+ if ( styleStack.hasAttributeNS( ooNS::fo, "page-width" ) )
+ {
+ width = KoUnit::toMM(KoUnit::parseValue( styleStack.attributeNS( ooNS::fo, "page-width" ) ) );
+ }
+ if ( styleStack.hasAttributeNS( ooNS::fo, "page-height" ) )
+ {
+ height = KoUnit::toMM( KoUnit::parseValue( styleStack.attributeNS( ooNS::fo, "page-height" ) ) );
+ }
+ if ( styleStack.hasAttributeNS( ooNS::fo, "margin-top" ) )
+ {
+ top = KoUnit::toMM(KoUnit::parseValue( styleStack.attributeNS( ooNS::fo, "margin-top" ) ) );
+ }
+ if ( styleStack.hasAttributeNS( ooNS::fo, "margin-bottom" ) )
+ {
+ bottom = KoUnit::toMM(KoUnit::parseValue( styleStack.attributeNS( ooNS::fo, "margin-bottom" ) ) );
+ }
+ if ( styleStack.hasAttributeNS( ooNS::fo, "margin-left" ) )
+ {
+ left = KoUnit::toMM(KoUnit::parseValue( styleStack.attributeNS( ooNS::fo, "margin-left" ) ) );
+ }
+ if ( styleStack.hasAttributeNS( ooNS::fo, "margin-right" ) )
+ {
+ right = KoUnit::toMM(KoUnit::parseValue( styleStack.attributeNS( ooNS::fo, "margin-right" ) ) );
+ }
+ if ( styleStack.hasAttributeNS( ooNS::style, "writing-mode" ) )
+ {
+ kdDebug(30518)<<"styleStack.hasAttribute( style:writing-mode ) :"<<styleStack.hasAttributeNS( ooNS::style, "writing-mode" )<<endl;
+ }
+ if ( styleStack.hasAttributeNS( ooNS::style, "print-orientation" ) )
+ {
+ orientation = ( styleStack.attributeNS( ooNS::style, "print-orientation" )=="landscape" ) ? "Landscape" : "Portrait" ;
+ }
+ if ( styleStack.hasAttributeNS( ooNS::style, "num-format" ) )
+ {
+ kdDebug(30518)<<" num-format :"<<styleStack.attributeNS( ooNS::style, "num-format" )<<endl;
+ //todo fixme
+ }
+ if ( styleStack.hasAttributeNS( ooNS::fo, "background-color" ) )
+ {
+ //todo
+ kdDebug(30518)<<" fo:background-color :"<<styleStack.attributeNS( ooNS::fo, "background-color" )<<endl;
+ }
+ if ( styleStack.hasAttributeNS( ooNS::style, "print" ) )
+ {
+ //todo parsing
+ QString str = styleStack.attributeNS( ooNS::style, "print" );
+ kdDebug(30518)<<" style:print :"<<str<<endl;
+
+ if (str.contains( "headers" ) )
+ {
+ //todo implement it into kspread
+ }
+ if ( str.contains( "grid" ) )
+ {
+ table->print()->setPrintGrid( true );
+ }
+ if ( str.contains( "annotations" ) )
+ {
+ //todo it's not implemented
+ }
+ if ( str.contains( "objects" ) )
+ {
+ //todo it's not implemented
+ }
+ if ( str.contains( "charts" ) )
+ {
+ //todo it's not implemented
+ }
+ if ( str.contains( "drawings" ) )
+ {
+ //todo it's not implemented
+ }
+ if ( str.contains( "formulas" ) )
+ {
+ table->setShowFormula(true);
+ }
+ if ( str.contains( "zero-values" ) )
+ {
+ //todo it's not implemented
+ }
+ }
+ if ( styleStack.hasAttributeNS( ooNS::style, "table-centering" ) )
+ {
+ QString str = styleStack.attributeNS( ooNS::style, "table-centering" );
+ //not implemented into kspread
+ kdDebug(30518)<<" styleStack.attribute( style:table-centering ) :"<<str<<endl;
+#if 0
+ if ( str == "horizontal" )
+ {
+ }
+ else if ( str == "vertical" )
+ {
+ }
+ else if ( str == "both" )
+ {
+ }
+ else if ( str == "none" )
+ {
+ }
+ else
+ kdDebug(30518)<<" table-centering unknown :"<<str<<endl;
+#endif
+ }
+ format = QString( "%1x%2" ).arg( width ).arg( height );
+ kdDebug(30518)<<" format : "<<format<<endl;
+ table->print()->setPaperLayout( left, top, right, bottom, format, orientation );
+
+ kdDebug(30518)<<" left margin :"<<left<<" right :"<<right<<" top :"<<top<<" bottom :"<<bottom<<endl;
+//<style:properties fo:page-width="21.8cm" fo:page-height="28.801cm" fo:margin-top="2cm" fo:margin-bottom="2.799cm" fo:margin-left="1.3cm" fo:margin-right="1.3cm" style:writing-mode="lr-tb"/>
+// QString format = paper.attribute( "format" );
+// QString orientation = paper.attribute( "orientation" );
+// m_pPrint->setPaperLayout( left, top, right, bottom, format, orientation );
+// }
+}
+
+
+bool OpenCalcImport::parseBody( int numOfTables )
+{
+ QDomElement content = m_content.documentElement();
+ QDomNode body = KoDom::namedItemNS( content, ooNS::office, "body" );
+
+ if ( body.isNull() )
+ return false;
+
+ loadOasisAreaName( body.toElement() );
+ loadOasisCellValidation( body.toElement() );
+
+ Sheet * table;
+ QDomNode sheet = KoDom::namedItemNS( body, ooNS::table, "table" );
+
+ kdDebug()<<" sheet :"<<sheet.isNull()<<endl;
+ if ( sheet.isNull() )
+ return false;
+
+ while ( !sheet.isNull() )
+ {
+ QDomElement t = sheet.toElement();
+ if ( t.isNull() )
+ {
+ sheet = sheet.nextSibling();
+ continue;
+ }
+ if ( t.nodeName() != "table:table" )
+ {
+ sheet = sheet.nextSibling();
+ continue;
+ }
+
+ table = m_doc->map()->addNewSheet();
+
+ table->setSheetName( t.attributeNS( ooNS::table, "name", QString::null ), true, false );
+ kdDebug()<<" table->name()"<<table->name()<<endl;
+ sheet = sheet.nextSibling();
+ }
+
+ sheet = body.firstChild();
+
+ int step = (int) ( 80 / numOfTables );
+ int progress = 15;
+
+ Format::setGlobalColWidth( MM_TO_POINT( 22.7 ) );
+ Format::setGlobalRowHeight( MM_TO_POINT( 4.3 ) );
+ kdDebug(30518) << "Global Height: " << MM_TO_POINT( 4.3 ) << ", Global width: " << MM_TO_POINT( 22.7) << endl;
+
+ while ( !sheet.isNull() )
+ {
+ QDomElement t = sheet.toElement();
+ if ( t.isNull() )
+ {
+ KMessageBox::sorry( 0, i18n( "The file seems to be corrupt. Skipping a table." ) );
+ sheet = sheet.nextSibling();
+ continue;
+ }
+ if ( t.nodeName() != "table:table" )
+ {
+ sheet = sheet.nextSibling();
+ continue;
+ }
+
+ table = m_doc->map()->findSheet( t.attributeNS( ooNS::table, "name", QString::null ) );
+ if ( !table )
+ {
+ KMessageBox::sorry( 0, i18n( "Skipping a table." ) );
+ sheet = sheet.nextSibling();
+ continue;
+ }
+
+ Format * defaultStyle = m_defaultStyles[ "Default" ];
+ if ( defaultStyle )
+ {
+ Cell* defaultCell = table->defaultCell();
+ kdDebug(30518) << "Copy default style to default cell" << endl;
+ defaultCell->format()->copy( *defaultStyle );
+ }
+ table->setDefaultHeight( MM_TO_POINT( 4.3 ) );
+ table->setDefaultWidth( MM_TO_POINT( 22.7 ) );
+
+ kdDebug(30518) << "Added table: " << t.attributeNS( ooNS::table, "name", QString::null ) << endl;
+
+ if ( t.hasAttributeNS( ooNS::table, "style-name" ) )
+ {
+ QString style = t.attributeNS( ooNS::table, "style-name", QString::null );
+ QDomElement * tableStyle = m_styles[ style ];
+
+ QDomNode node;
+
+ if ( tableStyle )
+ node = tableStyle->firstChild();
+
+ while( !node.isNull() )
+ {
+ QDomElement property = node.toElement();
+ if ( property.localName() == "properties" && property.namespaceURI() == ooNS::style )
+ {
+ if ( property.hasAttributeNS( ooNS::table, "display" ) )
+ {
+ bool visible = (property.attributeNS( ooNS::table, "display", QString::null ) == "true" ? true : false );
+ table->hideSheet( !visible );
+ kdDebug(30518) << "Table: " << table->tableName() << ", hidden: " << !visible << endl;
+ }
+ }
+
+ node = node.nextSibling();
+ }
+
+ if ( tableStyle && tableStyle->hasAttributeNS( ooNS::style, "master-page-name" ) )
+ {
+ QString stylename = "pm" + tableStyle->attributeNS( ooNS::style, "master-page-name", QString::null );
+
+ loadTableMasterStyle( table, stylename );
+
+ }
+ }
+ if ( t.hasAttributeNS( ooNS::table, "print-ranges" ) )
+ {
+ // e.g.: Sheet4.A1:Sheet4.E28
+ QString range = t.attributeNS( ooNS::table, "print-ranges", QString::null );
+ OpenCalcPoint point( range );
+
+ kdDebug(30518) << "Print range: " << point.translation << endl;
+ KSpread::Range p( point.translation );
+
+ kdDebug(30518) << "Print table: " << p.sheetName() << endl;
+
+ if ( table->sheetName() == p.sheetName() )
+ table->print()->setPrintRange( p.range() );
+ }
+
+ if ( !readColLayouts( t, table ) )
+ return false;
+
+ if ( !readRowsAndCells( t, table ) )
+ return false;
+
+ if ( t.hasAttributeNS( ooNS::table, "protected" ) )
+ {
+ QCString passwd( "" );
+ if ( t.hasAttributeNS( ooNS::table, "protection-key" ) )
+ {
+ QString p = t.attributeNS( ooNS::table, "protection-key", QString::null );
+ QCString str( p.latin1() );
+ kdDebug(30518) << "Decoding password: " << str << endl;
+ passwd = KCodecs::base64Decode( str );
+ }
+ kdDebug(30518) << "Password hash: '" << passwd << "'" << endl;
+ table->setProtected( passwd );
+ }
+
+ progress += step;
+ emit sigProgress( progress );
+ sheet = sheet.nextSibling();
+ }
+
+ QDomElement b = body.toElement();
+ if ( b.hasAttributeNS( ooNS::table, "structure-protected" ) )
+ {
+ QCString passwd( "" );
+ if ( b.hasAttributeNS( ooNS::table, "protection-key" ) )
+ {
+ QString p = b.attributeNS( ooNS::table, "protection-key", QString::null );
+ QCString str( p.latin1() );
+ kdDebug(30518) << "Decoding password: " << str << endl;
+ passwd = KCodecs::base64Decode( str );
+ }
+ kdDebug(30518) << "Password hash: '" << passwd << "'" << endl;
+
+ m_doc->map()->setProtected( passwd );
+ }
+
+ emit sigProgress( 98 );
+
+ return true;
+}
+
+void OpenCalcImport::insertStyles( QDomElement const & element )
+{
+ if ( element.isNull() )
+ return;
+
+ QDomElement e;
+ forEachElement( e, element )
+ {
+ if ( e.isNull() || !e.hasAttributeNS( ooNS::style, "name" ) )
+ {
+ continue;
+ }
+
+ QString name = e.attributeNS( ooNS::style, "name", QString::null );
+ kdDebug(30518) << "Style: '" << name << "' loaded " << endl;
+ m_styles.insert( name, new QDomElement( e ) );
+ }
+}
+
+
+void OpenCalcImport::loadOasisAreaName( const QDomElement&body )
+{
+ QDomNode namedAreas = KoDom::namedItemNS( body, ooNS::table, "named-expressions" );
+ if ( !namedAreas.isNull() )
+ {
+ QDomElement e;
+ forEachElement( e, namedAreas )
+ {
+ if ( e.isNull() || !e.hasAttributeNS( ooNS::table, "name" ) || !e.hasAttributeNS( ooNS::table, "cell-range-address" ) )
+ {
+ kdDebug(30518) << "Reading in named area failed" << endl;
+ continue;
+ }
+
+ // TODO: what is: table:base-cell-address
+ QString name = e.attributeNS( ooNS::table, "name", QString::null );
+ QString areaPoint = e.attributeNS( ooNS::table, "cell-range-address", QString::null );
+
+ m_namedAreas.append( name );
+ kdDebug(30518) << "Reading in named area, name: " << name << ", area: " << areaPoint << endl;
+
+ OpenCalcPoint point( areaPoint );
+ kdDebug(30518) << "Area: " << point.translation << endl;
+
+ QString range( point.translation );
+
+ if ( point.translation.find( ':' ) == -1 )
+ {
+ Point p( point.translation );
+
+ int n = range.find( '!' );
+ if ( n > 0 )
+ range = range + ":" + range.right( range.length() - n - 1);
+
+ kdDebug(30518) << "=> Area: " << range << endl;
+ }
+
+ KSpread::Range p( range );
+
+ m_doc->addAreaName( p.range(), name, p.sheetName() );
+ kdDebug(30518) << "Area range: " << p.sheetName() << endl;
+ }
+ }
+}
+
+void OpenCalcImport::loadOasisCellValidation( const QDomElement&body )
+{
+ QDomNode validation = KoDom::namedItemNS( body, ooNS::table, "content-validations" );
+ if ( !validation.isNull() )
+ {
+ QDomElement element;
+ forEachElement( element, validation )
+ {
+ if ( element.localName() == "content-validation" ) {
+ m_validationList.insert( element.attributeNS( ooNS::table, "name", QString::null ), element);
+ kdDebug(30518)<<" validation found :"<<element.attributeNS( ooNS::table, "name", QString::null )<<endl;
+ }
+ else {
+ kdDebug(30518)<<" Tag not recognize :"<<element.tagName()<<endl;
+ }
+ }
+ }
+}
+
+
+QString * OpenCalcImport::loadFormat( QDomElement * element,
+ FormatType & formatType,
+ QString name )
+{
+ if ( !element )
+ return 0;
+
+ int i;
+ bool ok;
+
+ QString * format = 0;
+ QDomElement e = element->firstChild( ).toElement();
+ int precision = 0;
+ int leadingZ = 1;
+ bool thousandsSep = false;
+ bool negRed = false;
+
+ if ( element->localName() == "time-style" )
+ formatType = Custom_format;
+ else if ( element->localName() == "date-style" )
+ formatType = Custom_format;
+ else if ( element->localName() == "percentage-style" )
+ formatType = Custom_format;
+ else if ( element->localName() == "number-style" )
+ formatType = Custom_format;
+ else if ( element->localName() == "currency-style" )
+ formatType = Custom_format;
+ else if ( element->localName() == "boolean-style" )
+ formatType = Custom_format;
+
+ if ( !e.isNull() )
+ format = new QString();
+
+ // TODO (element):
+ // number:automatic-order="true"
+ // number:truncate-on-overflow="false"
+ // style:volatile="true"
+
+ while ( !e.isNull() )
+ {
+ if ( e.localName() == "properties" && e.namespaceURI() == ooNS::style )
+ {
+ if ( e.hasAttributeNS( ooNS::fo, "color" ) )
+ negRed = true; // we only support red...
+ }
+ else if ( e.localName() == "text" && e.namespaceURI()==ooNS::number)
+ {
+ if ( negRed && ( e.text() == "-" ) )
+ ;
+ else
+ format->append( e.text() );
+ }
+ else if ( e.localName() == "currency-symbol" && e.namespaceURI()==ooNS::number)
+ {
+ QString sym( e.text() );
+ kdDebug(30518) << "Currency: " << sym << endl;
+ format->append( sym );
+ // number:language="de" number:country="DE">€</number:currency-symbol>
+ }
+ else if ( e.localName() == "day-of-week" && e.namespaceURI()==ooNS::number)
+ {
+ if ( e.hasAttributeNS( ooNS::number, "style" ) )
+ {
+ if ( e.attributeNS( ooNS::number, "style", QString::null ) == "long" )
+ format->append( "dddd" );
+ else
+ format->append( "ddd" );
+ }
+ else
+ format->append( "ddd" );
+ }
+ else if ( e.localName() == "day" && e.namespaceURI()==ooNS::number)
+ {
+ if ( e.hasAttributeNS( ooNS::number, "style" ) )
+ {
+ if ( e.attributeNS( ooNS::number, "style", QString::null ) == "long" )
+ format->append( "dd" );
+ else
+ format->append( "d" );
+ }
+ else
+ format->append( "d" );
+ }
+ else if ( e.localName() == "month" && e.namespaceURI()==ooNS::number)
+ {
+ if ( e.hasAttributeNS( ooNS::number, "textual" ) )
+ {
+ if ( e.attributeNS( ooNS::number, "textual", QString::null ) == "true" )
+ format->append( "mm" );
+ }
+
+ if ( e.hasAttributeNS( ooNS::number, "style" ) )
+ {
+ if ( e.attributeNS( ooNS::number, "style", QString::null ) == "long" )
+ format->append( "mm" );
+ else
+ format->append( "m" );
+ }
+ else
+ format->append( "m" );
+ }
+ else if ( e.localName() == "year" && e.namespaceURI()==ooNS::number)
+ {
+ if ( e.hasAttributeNS( ooNS::number, "style" ) )
+ {
+ if ( e.attributeNS( ooNS::number, "style", QString::null ) == "long" )
+ format->append( "yyyy" );
+ else
+ format->append( "yy" );
+ }
+ else
+ format->append( "yy" );
+ }
+ else if ( e.localName() == "hours" && e.namespaceURI()==ooNS::number)
+ {
+ if ( e.hasAttributeNS( ooNS::number, "style" ) )
+ {
+ if ( e.attributeNS( ooNS::number, "style", QString::null ) == "long" )
+ format->append( "hh" );
+ else
+ format->append( "h" );
+ }
+ else
+ format->append( "h" );
+ }
+ else if ( e.localName() == "minutes" && e.namespaceURI()==ooNS::number)
+ {
+ if ( e.hasAttributeNS( ooNS::number, "style" ) )
+ {
+ if ( e.attributeNS( ooNS::number, "style", QString::null ) == "long" )
+ format->append( "mm" );
+ else
+ format->append( "m" );
+ }
+ else
+ format->append( "m" );
+ }
+ else if ( e.localName() == "seconds" && e.namespaceURI()==ooNS::number)
+ {
+ if ( e.hasAttributeNS( ooNS::number, "style" ) )
+ {
+ if ( e.attributeNS( ooNS::number, "style", QString::null ) == "long" )
+ format->append( "ss" );
+ else
+ format->append( "s" );
+ }
+ else
+ format->append( "s" );
+ }
+ else if ( e.localName() == "am-pm" && e.namespaceURI()==ooNS::number)
+ {
+ format->append( "AM/PM" );
+ }
+ else if ( e.localName() == "number" && e.namespaceURI()==ooNS::number)
+ {
+ // TODO: number:grouping="true"
+
+ if ( e.hasAttributeNS( ooNS::number, "decimal-places" ) )
+ {
+ int d = e.attributeNS( ooNS::number, "decimal-places", QString::null ).toInt( &ok );
+ if ( ok )
+ precision = d;
+ }
+
+ if ( e.hasAttributeNS( ooNS::number, "min-integer-digits" ) )
+ {
+ int d = e.attributeNS( ooNS::number, "min-integer-digits", QString::null ).toInt( &ok );
+ if ( ok )
+ leadingZ = d;
+ }
+
+ if ( thousandsSep && leadingZ <= 3 )
+ {
+ format->append( "#," );
+ for ( i = leadingZ; i <= 3; ++i )
+ format->append( '#' );
+ }
+
+ for ( i = 1; i <= leadingZ; ++i )
+ {
+ format->append( '0' );
+ if ( ( i % 3 == 0 ) && thousandsSep )
+ format->append( ',' );
+ }
+
+ format->append( '.' );
+ for ( i = 0; i < precision; ++i )
+ format->append( '0' );
+ }
+ else if ( e.localName() == "scientific-number" && e.namespaceURI()==ooNS::number)
+ {
+ int exp = 2;
+
+ if ( e.hasAttributeNS( ooNS::number, "decimal-places" ) )
+ {
+ int d = e.attributeNS( ooNS::number, "decimal-places", QString::null ).toInt( &ok );
+ if ( ok )
+ precision = d;
+ }
+
+ if ( e.hasAttributeNS( ooNS::number, "min-integer-digits" ) )
+ {
+ int d = e.attributeNS( ooNS::number, "min-integer-digits", QString::null ).toInt( &ok );
+ if ( ok )
+ leadingZ = d;
+ }
+
+ if ( e.hasAttributeNS( ooNS::number, "min-exponent-digits" ) )
+ {
+ int d = e.attributeNS( ooNS::number, "min-exponent-digits", QString::null ).toInt( &ok );
+ if ( ok )
+ exp = d;
+ if ( exp <= 0 )
+ exp = 1;
+ }
+
+ if ( thousandsSep && leadingZ <= 3 )
+ {
+ format->append( "#," );
+ for ( i = leadingZ; i <= 3; ++i )
+ format->append( '#' );
+ }
+
+ for ( i = 1; i <= leadingZ; ++i )
+ {
+ format->append( '0' );
+ if ( ( i % 3 == 0 ) && thousandsSep )
+ format->append( ',' );
+ }
+
+ format->append( '.' );
+ for ( i = 0; i < precision; ++i )
+ format->append( '0' );
+
+ format->append( "E+" );
+ for ( i = 0; i < exp; ++i )
+ format->append( '0' );
+
+ formatType = Custom_format;
+ }
+ else if ( e.localName() == "fraction" && e.namespaceURI()==ooNS::number)
+ {
+ int integer = 0;
+ int numerator = 1;
+ int denominator = 1;
+
+ if ( e.hasAttributeNS( ooNS::number, "min-integer-digits" ) )
+ {
+ int d = e.attributeNS( ooNS::number, "min-integer-digits", QString::null ).toInt( &ok );
+ if ( ok )
+ integer = d;
+ }
+ if ( e.hasAttributeNS( ooNS::number, "min-numerator-digits" ) )
+ {
+ int d = e.attributeNS( ooNS::number, "min-numerator-digits", QString::null ).toInt( &ok );
+ if ( ok )
+ numerator = d;
+ }
+ if ( e.hasAttributeNS( ooNS::number, "min-denominator-digits" ) )
+ {
+ int d = e.attributeNS( ooNS::number, "min-denominator-digits", QString::null ).toInt( &ok );
+ if ( ok )
+ denominator = d;
+ }
+
+ for ( i = 0; i <= integer; ++i )
+ format->append( '#' );
+
+ format->append( ' ' );
+
+ for ( i = 0; i <= numerator; ++i )
+ format->append( '?' );
+
+ format->append( '/' );
+
+ for ( i = 0; i <= denominator; ++i )
+ format->append( '?' );
+ }
+ // Not needed:
+ // <style:map style:condition="value()&gt;=0" style:apply-style-name="N106P0"/>
+ // we handle painting negative numbers in red differently
+
+ e = e.nextSibling().toElement();
+ }
+
+ if ( negRed )
+ {
+ QString f( *format );
+ format->append( ";[Red]" );
+ format->append( f );
+ }
+
+ kdDebug(30518) << "*** New FormatString: " << *format << endl << endl;
+
+ m_formats.insert( name, format );
+
+ return format;
+}
+
+void OpenCalcImport::loadFontStyle( Format * layout, QDomElement const * font ) const
+{
+ if ( !font || !layout )
+ return;
+
+ kdDebug(30518) << "Copy font style from the layout " << font->tagName() << ", " << font->nodeName() << endl;
+
+ if ( font->hasAttributeNS( ooNS::fo, "font-family" ) )
+ layout->setTextFontFamily( font->attributeNS( ooNS::fo, "font-family", QString::null ) );
+ if ( font->hasAttributeNS( ooNS::fo, "color" ) )
+ layout->setTextColor( QColor( font->attributeNS( ooNS::fo, "color", QString::null ) ) );
+ if ( font->hasAttributeNS( ooNS::fo, "font-size" ) )
+ layout->setTextFontSize( int( KoUnit::parseValue( font->attributeNS( ooNS::fo, "font-size", QString::null ), 10 ) ) );
+ else
+ layout->setTextFontSize( 10 );
+ if ( font->hasAttributeNS( ooNS::fo, "font-style" ) )
+ {
+ kdDebug(30518) << "italic" << endl;
+ layout->setTextFontItalic( true ); // only thing we support
+ }
+ if ( font->hasAttributeNS( ooNS::fo, "font-weight" ) )
+ layout->setTextFontBold( true ); // only thing we support
+ if ( font->hasAttributeNS( ooNS::fo, "text-underline" ) || font->hasAttributeNS( ooNS::style, "text-underline" ) )
+ layout->setTextFontUnderline( true ); // only thing we support
+ if ( font->hasAttributeNS( ooNS::style, "text-crossing-out" ) )
+ layout->setTextFontStrike( true ); // only thing we support
+ if ( font->hasAttributeNS( ooNS::style, "font-pitch" ) )
+ {
+ // TODO: possible values: fixed, variable
+ }
+ // TODO:
+ // text-underline-color
+}
+
+void OpenCalcImport::loadBorder( Format * layout, QString const & borderDef, bPos pos ) const
+{
+ if ( borderDef == "none" )
+ return;
+
+ int p = borderDef.find( ' ' );
+ if ( p < 0 )
+ return;
+
+ QPen pen;
+ QString w = borderDef.left( p );
+ pen.setWidth( (int) KoUnit::parseValue( w ) );
+
+
+ ++p;
+ int p2 = borderDef.find( ' ', p );
+ QString s = borderDef.mid( p, p2 - p );
+
+ kdDebug(30518) << "Borderstyle: " << s << endl;
+
+ if ( s == "solid" || s == "double" )
+ pen.setStyle( Qt::SolidLine );
+ else
+ {
+#if 0
+ // TODO: not supported by oocalc
+ pen.setStyle( Qt::DashLine );
+ pen.setStyle( Qt::DotLine );
+ pen.setStyle( Qt::DashDotLine );
+ pen.setStyle( Qt::DashDotDotLine );
+#endif
+ pen.setStyle( Qt::SolidLine ); //default.
+ }
+
+ ++p2;
+ p = borderDef.find( ' ', p2 );
+ if ( p == -1 )
+ p = borderDef.length();
+
+ pen.setColor( QColor( borderDef.right( p - p2 ) ) );
+
+ if ( pos == Left )
+ layout->setLeftBorderPen( pen );
+ else if ( pos == Top )
+ layout->setTopBorderPen( pen );
+ else if ( pos == Right )
+ layout->setRightBorderPen( pen );
+ else if ( pos == Bottom )
+ layout->setBottomBorderPen( pen );
+ else if ( pos == Border )
+ {
+ layout->setLeftBorderPen( pen );
+ layout->setTopBorderPen( pen );
+ layout->setRightBorderPen( pen );
+ layout->setBottomBorderPen( pen );
+ }
+ // TODO Diagonals not supported by oocalc
+}
+
+void OpenCalcImport::loadStyleProperties( Format * layout, QDomElement const & property ) const
+{
+ kdDebug(30518) << "*** Loading style properties *****" << endl;
+
+ if ( property.hasAttributeNS( ooNS::style, "decimal-places" ) )
+ {
+ bool ok = false;
+ int p = property.attributeNS( ooNS::style, "decimal-places", QString::null ).toInt( &ok );
+ if (ok )
+ layout->setPrecision( p );
+ }
+
+ if ( property.hasAttributeNS( ooNS::style, "font-name" ) )
+ {
+ QDomElement * font = m_styles[ property.attributeNS( ooNS::style, "font-name", QString::null ) ];
+ loadFontStyle( layout, font ); // generell font style
+ }
+
+ loadFontStyle( layout, &property ); // specific font style
+
+ // TODO:
+ // diagonal: fall + goup
+ // fo:direction="ltr"
+ // style:text-align-source ("fix")
+ // style:shadow
+ // style:text-outline
+ // indents from right, top, bottom
+ // style:condition="cell-content()=15"
+ // => style:apply-style-name="Result" style:base-cell-address="Sheet6.A5"/>
+
+ if ( property.hasAttributeNS( ooNS::style, "rotation-angle" ) )
+ {
+ bool ok = false;
+ int a = property.attributeNS( ooNS::style, "rotation-angle", QString::null ).toInt( &ok );
+ if ( ok )
+ layout->setAngle( -a + 1 );
+ }
+
+ if ( property.hasAttributeNS( ooNS::fo, "direction" ) )
+ {
+ layout->setVerticalText( true );
+ }
+ if ( property.hasAttributeNS( ooNS::fo, "text-align" ) )
+ {
+ QString s = property.attributeNS( ooNS::fo, "text-align", QString::null );
+ if ( s == "center" )
+ layout->setAlign( Format::Center );
+ else if ( s == "end" )
+ layout->setAlign( Format::Right );
+ else if ( s == "start" )
+ layout->setAlign( Format::Left );
+ else if ( s == "justify" ) // TODO in KSpread!
+ layout->setAlign( Format::Center );
+ }
+ if ( property.hasAttributeNS( ooNS::fo, "margin-left" ) )
+ {
+ kdDebug(30518)<<"margin-left :"<<KoUnit::parseValue( property.attributeNS( ooNS::fo, "margin-left", QString::null ),0.0 )<<endl;
+ layout->setIndent( KoUnit::parseValue( property.attributeNS( ooNS::fo, "margin-left", QString::null ),0.0 ) );
+ }
+ if ( property.hasAttributeNS( ooNS::fo, "background-color" ) )
+ layout->setBgColor( QColor( property.attributeNS( ooNS::fo, "background-color", QString::null ) ) );
+
+ if ( property.hasAttributeNS( ooNS::style, "print-content" ) )
+ {
+ if ( property.attributeNS( ooNS::style, "print-content", QString::null ) == "false" )
+ layout->setDontPrintText( false );
+ }
+ if ( property.hasAttributeNS( ooNS::style, "cell-protect" ) )
+ {
+ QString prot( property.attributeNS( ooNS::style, "cell-protect", QString::null ) );
+ if ( prot == "none" )
+ {
+ layout->setNotProtected( true );
+ layout->setHideFormula( false );
+ layout->setHideAll( false );
+ }
+ else if ( prot == "formula-hidden" )
+ {
+ layout->setNotProtected( true );
+ layout->setHideFormula( true );
+ layout->setHideAll( false );
+ }
+ else if ( prot == "protected formula-hidden" )
+ {
+ layout->setNotProtected( false );
+ layout->setHideFormula( true );
+ layout->setHideAll( false );
+ }
+ else if ( prot == "hidden-and-protected" )
+ {
+ layout->setNotProtected( false );
+ layout->setHideFormula( false );
+ layout->setHideAll( true );
+ }
+ else if ( prot == "protected" )
+ {
+ layout->setNotProtected( false );
+ layout->setHideFormula( false );
+ layout->setHideAll( false );
+ }
+ kdDebug(30518) << "Cell " << prot << endl;
+ }
+
+ if ( property.hasAttributeNS( ooNS::fo, "padding-left" ) )
+ layout->setIndent( KoUnit::parseValue(property.attributeNS( ooNS::fo, "padding-left", QString::null ) ) );
+
+ if ( property.hasAttributeNS( ooNS::fo, "vertical-align" ) )
+ {
+ QString s = property.attributeNS( ooNS::fo, "vertical-align", QString::null );
+ if ( s == "middle" )
+ layout->setAlignY( Format::Middle );
+ else if ( s == "bottom" )
+ layout->setAlignY( Format::Bottom );
+ else
+ layout->setAlignY( Format::Top );
+ }
+ else
+ layout->setAlignY( Format::Bottom );
+
+ if ( property.hasAttributeNS( ooNS::fo, "wrap-option" ) )
+ {
+ layout->setMultiRow( true );
+
+ /* we do not support anything else yet
+ QString s = property.attributeNS( ooNS::fo, "wrap-option", QString::null );
+ if ( s == "wrap" )
+ layout->setMultiRow( true );
+ */
+ }
+
+ if ( property.hasAttributeNS( ooNS::fo, "border-bottom" ) )
+ {
+ loadBorder( layout, property.attributeNS( ooNS::fo, "border-bottom", QString::null ), Bottom );
+ // TODO: style:border-line-width-bottom if double!
+ }
+
+ if ( property.hasAttributeNS( ooNS::fo, "border-right" ) )
+ {
+ loadBorder( layout, property.attributeNS( ooNS::fo, "border-right", QString::null ), Right );
+ // TODO: style:border-line-width-right
+ }
+
+ if ( property.hasAttributeNS( ooNS::fo, "border-top" ) )
+ {
+ loadBorder( layout, property.attributeNS( ooNS::fo, "border-top", QString::null ), Top );
+ // TODO: style:border-line-width-top
+ }
+
+ if ( property.hasAttributeNS( ooNS::fo, "border-left" ) )
+ {
+ loadBorder( layout, property.attributeNS( ooNS::fo, "border-left", QString::null ), Left );
+ // TODO: style:border-line-width-left
+ }
+
+ if ( property.hasAttributeNS( ooNS::fo, "border" ) )
+ {
+ loadBorder( layout, property.attributeNS( ooNS::fo, "border", QString::null ), Border );
+ // TODO: style:border-line-width-left
+ }
+}
+
+void OpenCalcImport::readInStyle( Format * layout, QDomElement const & style )
+{
+ kdDebug(30518) << "** Reading Style: " << style.tagName() << "; " << style.attributeNS( ooNS::style, "name", QString::null) << endl;
+ if ( style.localName() == "style" && style.namespaceURI()==ooNS::style)
+ {
+ if ( style.hasAttributeNS( ooNS::style, "parent-style-name" ) )
+ {
+ Format * cp
+ = m_defaultStyles.find( style.attributeNS( ooNS::style, "parent-style-name", QString::null ) );
+ kdDebug(30518) << "Copying layout from " << style.attributeNS( ooNS::style, "parent-style-name", QString::null ) << endl;
+
+ if ( cp != 0 )
+ layout->copy( *cp );
+ }
+ else if ( style.hasAttributeNS( ooNS::style, "family") )
+ {
+ QString name = style.attribute( "style-family" ) + "default";
+ Format * cp = m_defaultStyles.find( name );
+
+ kdDebug(30518) << "Copying layout from " << name << ", " << !cp << endl;
+
+ if ( cp != 0 )
+ layout->copy( *cp );
+ }
+
+ if ( style.hasAttributeNS( ooNS::style, "data-style-name" ) )
+ {
+ QString * format = m_formats[ style.attributeNS( ooNS::style, "data-style-name", QString::null ) ];
+ FormatType formatType;
+
+ if ( !format )
+ {
+ // load and convert it
+ QString name( style.attributeNS( ooNS::style, "data-style-name", QString::null ) );
+ format = loadFormat( m_styles[ name ], formatType, name );
+ }
+
+ if ( format )
+ {
+ layout->setFormatString( *format );
+ layout->setFormatType( formatType );
+ }
+
+ // <number:currency-symbol number:language="de" number:country="DE">€</number:currency-symbol>
+ }
+ }
+
+ QDomElement property;
+ forEachElement( property, style )
+ {
+ if ( property.localName() == "properties" && property.namespaceURI() == ooNS::style )
+ loadStyleProperties( layout, property );
+
+ kdDebug(30518) << layout->textFontFamily( 0, 0 ) << endl;
+ }
+}
+
+bool OpenCalcImport::createStyleMap( QDomDocument const & styles )
+{
+ QDomElement content = styles.documentElement();
+ QDomNode docStyles = KoDom::namedItemNS( content, ooNS::office, "document-styles" );
+
+ if ( content.hasAttributeNS( ooNS::office, "version" ) )
+ {
+ bool ok = true;
+ double d = content.attributeNS( ooNS::office, "version", QString::null ).toDouble( &ok );
+
+ if ( ok )
+ {
+ kdDebug(30518) << "OpenCalc version: " << d << endl;
+ if ( d > 1.0 )
+ {
+ QString message( i18n("This document was created with OpenOffice.org version '%1'. This filter was written for version 1.0. Reading this file could cause strange behavior, crashes or incorrect display of the data. Do you want to continue converting the document?") );
+ message.arg( content.attributeNS( ooNS::office, "version", QString::null ) );
+ if ( KMessageBox::warningYesNo( 0, message, i18n( "Unsupported document version" ) ) == KMessageBox::No )
+ return false;
+ }
+ }
+ }
+
+ QDomNode fontStyles = KoDom::namedItemNS( content, ooNS::office, "font-decls" );
+
+ if ( !fontStyles.isNull() )
+ {
+ kdDebug(30518) << "Starting reading in font-decl..." << endl;
+
+ insertStyles( fontStyles.toElement() );
+ }
+ else
+ kdDebug(30518) << "No items found" << endl;
+
+ kdDebug(30518) << "Starting reading in auto:styles" << endl;
+
+ QDomNode autoStyles = KoDom::namedItemNS( content, ooNS::office, "automatic-styles" );
+ if ( !autoStyles.isNull() )
+ insertStyles( autoStyles.toElement() );
+ else
+ kdDebug(30518) << "No items found" << endl;
+
+
+ kdDebug(30518) << "Reading in master styles" << endl;
+
+ QDomNode masterStyles = KoDom::namedItemNS( content, ooNS::office, "master-styles" );
+
+ if ( masterStyles.isNull() )
+ {
+ kdDebug(30518) << "Nothing found " << endl;
+ }
+
+ QDomElement master = KoDom::namedItemNS( masterStyles, ooNS::style, "master-page");
+ if ( !master.isNull() )
+ {
+ QString name( "pm" );
+ name += master.attributeNS( ooNS::style, "name", QString::null );
+ kdDebug(30518) << "Master style: '" << name << "' loaded " << endl;
+ m_styles.insert( name, new QDomElement( master ) );
+
+ master = master.nextSibling().toElement();
+ }
+
+
+ kdDebug(30518) << "Starting reading in office:styles" << endl;
+
+ QDomNode fixedStyles = KoDom::namedItemNS( content, ooNS::office, "styles" );
+
+ kdDebug(30518) << "Reading in default styles" << endl;
+
+ QDomNode def = KoDom::namedItemNS( fixedStyles, ooNS::style, "default-style" );
+ kdDebug()<<" def !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! :"<<def.isNull()<<endl;
+ while ( !def.isNull() )
+ {
+ QDomElement e = def.toElement();
+ kdDebug(30518) << "Style found " << e.nodeName() << ", tag: " << e.tagName() << endl;
+
+ if ( e.nodeName() != "style:default-style" )
+ {
+ def = def.nextSibling();
+ continue;
+ }
+
+ if ( !e.isNull() )
+ {
+ Format * layout = new Format( 0, m_doc->styleManager()->defaultStyle() );
+
+ readInStyle( layout, e );
+ kdDebug(30518) << "Default style " << e.attributeNS( ooNS::style, "family", QString::null ) << "default" << " loaded " << endl;
+
+ m_defaultStyles.insert( e.attributeNS( ooNS::style, "family", QString::null ) + "default", layout );
+ // QFont font = layout->font();
+ // kdDebug(30518) << "Font: " << font.family() << ", " << font.toString() << endl;
+ }
+
+ def = def.nextSibling();
+ }
+
+ QDomElement defs = KoDom::namedItemNS( fixedStyles, ooNS::style, "style" );
+ while ( !defs.isNull() )
+ {
+ if ( defs.nodeName() != "style:style" )
+ break; // done
+
+ if ( !defs.hasAttributeNS( ooNS::style, "name" ) )
+ {
+ // ups...
+ defs = defs.nextSibling().toElement();
+ continue;
+ }
+
+ Format * layout = new Format( 0, m_doc->styleManager()->defaultStyle() );
+ readInStyle( layout, defs );
+ kdDebug(30518) << "Default style " << defs.attributeNS( ooNS::style, "name", QString::null ) << " loaded " << endl;
+
+ m_defaultStyles.insert( defs.attributeNS( ooNS::style, "name", QString::null ), layout );
+ // kdDebug(30518) << "Font: " << layout->font().family() << ", " << layout->font().toString() << endl;
+
+ defs = defs.nextSibling().toElement();
+ }
+
+ if ( !fixedStyles.isNull() )
+ insertStyles( fixedStyles.toElement() );
+
+ kdDebug(30518) << "Starting reading in automatic styles" << endl;
+
+ content = m_content.documentElement();
+ autoStyles = KoDom::namedItemNS( content, ooNS::office, "automatic-styles" );
+
+ if ( !autoStyles.isNull() )
+ insertStyles( autoStyles.toElement() );
+
+ fontStyles = KoDom::namedItemNS( content, ooNS::office, "font-decls" );
+
+ if ( !fontStyles.isNull() )
+ {
+ kdDebug(30518) << "Starting reading in special font decl" << endl;
+
+ insertStyles( fontStyles.toElement() );
+ }
+
+ kdDebug(30518) << "Styles read in." << endl;
+
+ return true;
+}
+
+void OpenCalcImport::loadOasisValidation( Validity* val, const QString& validationName )
+{
+ kdDebug(30518)<<"validationName:"<<validationName<<endl;
+ QDomElement element = m_validationList[validationName];
+ if ( element.hasAttributeNS( ooNS::table, "condition" ) )
+ {
+ QString valExpression = element.attributeNS( ooNS::table, "condition", QString::null );
+ kdDebug(30518)<<" element.attribute( table:condition ) "<<valExpression<<endl;
+ //Condition ::= ExtendedTrueCondition | TrueFunction 'and' TrueCondition
+ //TrueFunction ::= cell-content-is-whole-number() | cell-content-is-decimal-number() | cell-content-is-date() | cell-content-is-time()
+ //ExtendedTrueCondition ::= ExtendedGetFunction | cell-content-text-length() Operator Value
+ //TrueCondition ::= GetFunction | cell-content() Operator Value
+ //GetFunction ::= cell-content-is-between(Value, Value) | cell-content-is-not-between(Value, Value)
+ //ExtendedGetFunction ::= cell-content-text-length-is-between(Value, Value) | cell-content-text-length-is-not-between(Value, Value)
+ //Operator ::= '<' | '>' | '<=' | '>=' | '=' | '!='
+ //Value ::= NumberValue | String | Formula
+ //A Formula is a formula without an equals (=) sign at the beginning. See section 8.1.3 for more information.
+ //A String comprises one or more characters surrounded by quotation marks.
+ //A NumberValue is a whole or decimal number. It must not contain comma separators for numbers of 1000 or greater.
+
+ //ExtendedTrueCondition
+ if ( valExpression.contains( "cell-content-text-length()" ) )
+ {
+ //"cell-content-text-length()>45"
+ valExpression = valExpression.remove("cell-content-text-length()" );
+ kdDebug(30518)<<" valExpression = :"<<valExpression<<endl;
+ val->m_restriction = Restriction::TextLength;
+
+ loadOasisValidationCondition( val, valExpression );
+ }
+ //cell-content-text-length-is-between(Value, Value) | cell-content-text-length-is-not-between(Value, Value)
+ else if ( valExpression.contains( "cell-content-text-length-is-between" ) )
+ {
+ val->m_restriction = Restriction::TextLength;
+ val->m_cond = Conditional::Between;
+ valExpression = valExpression.remove( "cell-content-text-length-is-between(" );
+ kdDebug(30518)<<" valExpression :"<<valExpression<<endl;
+ valExpression = valExpression.remove( ")" );
+ QStringList listVal = QStringList::split( ",", valExpression );
+ loadOasisValidationValue( val, listVal );
+ }
+ else if ( valExpression.contains( "cell-content-text-length-is-not-between" ) )
+ {
+ val->m_restriction = Restriction::TextLength;
+ val->m_cond = Conditional::Different;
+ valExpression = valExpression.remove( "cell-content-text-length-is-not-between(" );
+ kdDebug(30518)<<" valExpression :"<<valExpression<<endl;
+ valExpression = valExpression.remove( ")" );
+ kdDebug(30518)<<" valExpression :"<<valExpression<<endl;
+ QStringList listVal = QStringList::split( ",", valExpression );
+ loadOasisValidationValue( val, listVal );
+
+ }
+ //TrueFunction ::= cell-content-is-whole-number() | cell-content-is-decimal-number() | cell-content-is-date() | cell-content-is-time()
+ else
+ {
+ if (valExpression.contains( "cell-content-is-whole-number()" ) )
+ {
+ val->m_restriction = Restriction::Number;
+ valExpression = valExpression.remove( "cell-content-is-whole-number() and " );
+ }
+ else if (valExpression.contains( "cell-content-is-decimal-number()" ) )
+ {
+ val->m_restriction = Restriction::Integer;
+ valExpression = valExpression.remove( "cell-content-is-decimal-number() and " );
+ }
+ else if (valExpression.contains( "cell-content-is-date()" ) )
+ {
+ val->m_restriction = Restriction::Date;
+ valExpression = valExpression.remove( "cell-content-is-date() and " );
+ }
+ else if (valExpression.contains( "cell-content-is-time()" ) )
+ {
+ val->m_restriction = Restriction::Time;
+ valExpression = valExpression.remove( "cell-content-is-time() and " );
+ }
+ kdDebug(30518)<<"valExpression :"<<valExpression<<endl;
+
+ if ( valExpression.contains( "cell-content()" ) )
+ {
+ valExpression = valExpression.remove( "cell-content()" );
+ loadOasisValidationCondition( val, valExpression );
+ }
+ //GetFunction ::= cell-content-is-between(Value, Value) | cell-content-is-not-between(Value, Value)
+ //for the moment we support just int/double value, not text/date/time :(
+ if ( valExpression.contains( "cell-content-is-between(" ) )
+ {
+ valExpression = valExpression.remove( "cell-content-is-between(" );
+ valExpression = valExpression.remove( ")" );
+ QStringList listVal = QStringList::split( "," , valExpression );
+ loadOasisValidationValue( val, listVal );
+
+ val->m_cond = Conditional::Between;
+ }
+ if ( valExpression.contains( "cell-content-is-not-between(" ) )
+ {
+ valExpression = valExpression.remove( "cell-content-is-not-between(" );
+ valExpression = valExpression.remove( ")" );
+ QStringList listVal = QStringList::split( ",", valExpression );
+ loadOasisValidationValue( val, listVal );
+ val->m_cond = Conditional::Different;
+ }
+ }
+ }
+ if ( element.hasAttributeNS( ooNS::table, "allow-empty-cell" ) )
+ {
+ val->allowEmptyCell = ( ( element.attributeNS( ooNS::table, "allow-empty-cell", QString::null )=="true" ) ? true : false );
+
+ }
+ if ( element.hasAttributeNS( ooNS::table, "base-cell-address" ) )
+ {
+ //todo what is it ?
+ }
+
+ QDomElement help = KoDom::namedItemNS( element, ooNS::table, "help-message" );
+ if ( !help.isNull() )
+ {
+ if ( help.hasAttributeNS( ooNS::table, "title" ) )
+ val->titleInfo = help.attributeNS( ooNS::table, "title", QString::null );
+ if ( help.hasAttributeNS( ooNS::table, "display" ) )
+ val->displayValidationInformation = ( ( help.attributeNS( ooNS::table, "display", QString::null )=="true" ) ? true : false );
+ QDomElement attrText = KoDom::namedItemNS( help, ooNS::text, "p" );
+ if ( !attrText.isNull() )
+ val->messageInfo = attrText.text();
+ }
+
+ QDomElement error = KoDom::namedItemNS( element, ooNS::table, "error-message" );
+ if ( !error.isNull() )
+ {
+ if ( error.hasAttributeNS( ooNS::table, "title" ) )
+ val->title = error.attributeNS( ooNS::table, "title", QString::null );
+ if ( error.hasAttributeNS( ooNS::table, "message-type" ) )
+ {
+ QString str = error.attributeNS( ooNS::table, "message-type", QString::null );
+ if ( str == "warning" )
+ val->m_action = Action::Warning;
+ else if ( str == "information" )
+ val->m_action = Action::Information;
+ else if ( str == "stop" )
+ val->m_action = Action::Stop;
+ else
+ kdDebug(30518)<<"validation : message type unknown :"<<str<<endl;
+ }
+
+ if ( error.hasAttributeNS( ooNS::table, "display" ) )
+ {
+ kdDebug(30518)<<" display message :"<<error.attributeNS( ooNS::table, "display", QString::null )<<endl;
+ val->displayMessage = (error.attributeNS( ooNS::table, "display", QString::null )=="true");
+ }
+ QDomElement attrText = KoDom::namedItemNS( error, ooNS::text, "p" );
+ if ( !attrText.isNull() )
+ val->message = attrText.text();
+ }
+}
+
+void OpenCalcImport::loadOasisValidationValue( Validity* val, const QStringList &listVal )
+{
+ bool ok = false;
+ kdDebug(30518)<<" listVal[0] :"<<listVal[0]<<" listVal[1] :"<<listVal[1]<<endl;
+
+ if ( val->m_restriction == Restriction::Date )
+ {
+ val->dateMin = QDate::fromString( listVal[0] );
+ val->dateMax = QDate::fromString( listVal[1] );
+ }
+ else if ( val->m_restriction == Restriction::Time )
+ {
+ val->timeMin = QTime::fromString( listVal[0] );
+ val->timeMax = QTime::fromString( listVal[1] );
+ }
+ else
+ {
+ val->valMin = listVal[0].toDouble(&ok);
+ if ( !ok )
+ {
+ val->valMin = listVal[0].toInt(&ok);
+ if ( !ok )
+ kdDebug(30518)<<" Try to parse this value :"<<listVal[0]<<endl;
+
+#if 0
+ if ( !ok )
+ val->valMin = listVal[0];
+#endif
+ }
+ ok=false;
+ val->valMax = listVal[1].toDouble(&ok);
+ if ( !ok )
+ {
+ val->valMax = listVal[1].toInt(&ok);
+ if ( !ok )
+ kdDebug(30518)<<" Try to parse this value :"<<listVal[1]<<endl;
+
+#if 0
+ if ( !ok )
+ val->valMax = listVal[1];
+#endif
+ }
+ }
+}
+
+
+void OpenCalcImport::loadOasisValidationCondition( Validity* val,QString &valExpression )
+{
+ QString value;
+ if (valExpression.contains( "<=" ) )
+ {
+ value = valExpression.remove( "<=" );
+ val->m_cond = Conditional::InferiorEqual;
+ }
+ else if (valExpression.contains( ">=" ) )
+ {
+ value = valExpression.remove( ">=" );
+ val->m_cond = Conditional::SuperiorEqual;
+ }
+ else if (valExpression.contains( "!=" ) )
+ {
+ //add Differentto attribute
+ value = valExpression.remove( "!=" );
+ val->m_cond = Conditional::DifferentTo;
+ }
+ else if ( valExpression.contains( "<" ) )
+ {
+ value = valExpression.remove( "<" );
+ val->m_cond = Conditional::Inferior;
+ }
+ else if(valExpression.contains( ">" ) )
+ {
+ value = valExpression.remove( ">" );
+ val->m_cond = Conditional::Superior;
+ }
+ else if (valExpression.contains( "=" ) )
+ {
+ value = valExpression.remove( "=" );
+ val->m_cond = Conditional::Equal;
+ }
+ else
+ kdDebug(30518)<<" I don't know how to parse it :"<<valExpression<<endl;
+ kdDebug(30518)<<" value :"<<value<<endl;
+ if ( val->m_restriction == Restriction::Date )
+ {
+ val->dateMin = QDate::fromString( value );
+ }
+ else if ( val->m_restriction == Restriction::Date )
+ {
+ val->timeMin = QTime::fromString( value );
+ }
+ else
+ {
+ bool ok = false;
+ val->valMin = value.toDouble(&ok);
+ if ( !ok )
+ {
+ val->valMin = value.toInt(&ok);
+ if ( !ok )
+ kdDebug(30518)<<" Try to parse this value :"<<value<<endl;
+
+#if 0
+ if ( !ok )
+ val->valMin = value;
+#endif
+ }
+ }
+}
+
+
+int OpenCalcImport::readMetaData()
+{
+ int result = 5;
+ KoDocumentInfo * docInfo = m_doc->documentInfo();
+ KoDocumentInfoAbout * aboutPage = static_cast<KoDocumentInfoAbout *>(docInfo->page( "about" ));
+ KoDocumentInfoAuthor * authorPage = static_cast<KoDocumentInfoAuthor*>(docInfo->page( "author" ));
+
+ QDomNode meta = KoDom::namedItemNS( m_meta, ooNS::office, "document-meta" );
+ QDomNode office = KoDom::namedItemNS( meta, ooNS::office, "meta" );
+
+ if ( office.isNull() )
+ return 2;
+
+ QDomElement e = KoDom::namedItemNS( office, ooNS::dc, "creator" );
+ if ( !e.isNull() && !e.text().isEmpty() )
+ authorPage->setFullName( e.text() );
+
+ e = KoDom::namedItemNS( office, ooNS::dc, "title" );
+ if ( !e.isNull() && !e.text().isEmpty() )
+ aboutPage->setTitle( e.text() );
+
+ e = KoDom::namedItemNS( office, ooNS::dc, "description" );
+ if ( !e.isNull() && !e.text().isEmpty() )
+ aboutPage->setAbstract( e.text() );
+
+ e = KoDom::namedItemNS( office, ooNS::dc, "subject" );
+ if ( !e.isNull() && !e.text().isEmpty() )
+ aboutPage->setSubject( e.text() );
+
+ e= KoDom::namedItemNS( office, ooNS::meta, "keywords" );
+ if ( !e.isNull() )
+ {
+ e = KoDom::namedItemNS( e, ooNS::meta, "keyword" );
+ if ( !e.isNull() && !e.text().isEmpty() )
+ aboutPage->setKeywords( e.text() );
+ }
+
+ e = KoDom::namedItemNS( office, ooNS::meta, "document-statistic" );
+ if ( !e.isNull() && e.hasAttributeNS( ooNS::meta, "table-count" ) )
+ {
+ bool ok = false;
+ result = e.attributeNS( ooNS::meta, "table-count", QString::null ).toInt( &ok );
+ if ( !ok )
+ result = 5;
+ }
+
+ m_meta.clear(); // not needed anymore
+
+ return result;
+}
+
+KoFilter::ConversionStatus OpenCalcImport::convert( QCString const & from, QCString const & to )
+{
+ kdDebug(30518) << "Entering OpenCalc Import filter: " << from << " - " << to << endl;
+
+ KoDocument * document = m_chain->outputDocument();
+ if ( !document )
+ return KoFilter::StupidError;
+
+ if ( !::qt_cast<const KSpread::Doc *>( document ) ) // it's safer that way :)
+ {
+ kdWarning(30518) << "document isn't a KSpread::Doc but a " << document->className() << endl;
+ return KoFilter::NotImplemented;
+ }
+
+ if ( ( from != "application/vnd.sun.xml.calc" && from != "application/vnd.sun.xml.calc.template") || to != "application/x-kspread" )
+ {
+ kdWarning(30518) << "Invalid mimetypes " << from << " " << to << endl;
+ return KoFilter::NotImplemented;
+ }
+
+ m_doc = ( Doc * ) document;
+
+ if ( m_doc->mimeType() != "application/x-kspread" )
+ {
+ kdWarning(30518) << "Invalid document mimetype " << m_doc->mimeType() << endl;
+ return KoFilter::NotImplemented;
+ }
+
+ kdDebug(30518) << "Opening file " << endl;
+
+ KoFilter::ConversionStatus preStatus = openFile();
+
+ if ( preStatus != KoFilter::OK )
+ return preStatus;
+
+ emit sigProgress( 13 );
+ int tables = readMetaData();
+
+ emit sigProgress( 15 );
+
+ if ( !parseBody( tables ) )
+ return KoFilter::StupidError;
+
+ emit sigProgress( 100 );
+ return KoFilter::OK;
+}
+
+KoFilter::ConversionStatus OpenCalcImport::openFile()
+{
+ KoStore * store = KoStore::createStore( m_chain->inputFile(), KoStore::Read);
+
+ kdDebug(30518) << "Store created" << endl;
+
+ if ( !store )
+ {
+ kdWarning(30518) << "Couldn't open the requested file." << endl;
+ return KoFilter::FileNotFound;
+ }
+
+ kdDebug(30518) << "Trying to open content.xml" << endl;
+ QString messageError;
+ loadAndParse( m_content, "content.xml", store);
+ kdDebug(30518) << "Opened" << endl;
+
+ QDomDocument styles;
+ kdDebug(30518) << "file content.xml loaded " << endl;
+
+ loadAndParse( styles, "styles.xml", store);
+
+ loadAndParse( m_meta, "meta.xml", store);
+ loadAndParse( m_settings, "settings.xml", store);
+
+ delete store;
+
+ emit sigProgress( 10 );
+
+ if ( !createStyleMap( styles ) )
+ return KoFilter::UserCancelled;
+
+ return KoFilter::OK;
+}
+
+KoFilter::ConversionStatus OpenCalcImport::loadAndParse( QDomDocument& doc, const QString& fileName,KoStore *m_store )
+{
+ return OoUtils::loadAndParse( fileName, doc, m_store);
+}
+
+#include "opencalcimport.moc"
+
diff --git a/filters/kspread/opencalc/opencalcimport.h b/filters/kspread/opencalc/opencalcimport.h
new file mode 100644
index 000000000..57379796a
--- /dev/null
+++ b/filters/kspread/opencalc/opencalcimport.h
@@ -0,0 +1,119 @@
+/* This file is part of the KDE project
+ Copyright (C) 2002 Norbert Andres <nandres@web.de>
+ Copyright (C) 2004 Montel Laurent <montel@kde.org>
+
+ 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.
+*/
+
+#ifndef OpenCalc_IMPORT_H__
+#define OpenCalc_IMPORT_H__
+
+#include <KoFilter.h>
+#include "kspread_format.h"
+
+#include <qdict.h>
+#include <qdom.h>
+
+class KoStyleStack;
+class KoStore;
+
+namespace KSpread
+{
+class Cell;
+class Conditional;
+class Doc;
+class Sheet;
+class Validity;
+}
+
+class OpenCalcImport : public KoFilter
+{
+ Q_OBJECT
+ public:
+ OpenCalcImport( KoFilter * parent, const char * name, const QStringList & );
+ virtual ~OpenCalcImport();
+
+ virtual KoFilter::ConversionStatus convert( QCString const & from, QCString const & to );
+
+
+ private:
+
+ class OpenCalcPoint
+ {
+ public:
+ OpenCalcPoint( QString const & str );
+
+ QString table;
+ QString translation;
+ QPoint topLeft;
+ QPoint botRight;
+ bool isRange;
+ };
+
+ enum bPos { Left, Top, Right, Bottom, Fall, GoUp, Border };
+
+ KSpread::Doc * m_doc;
+ KSpread::Format * m_defaultLayout;
+
+ QDomDocument m_content;
+ QDomDocument m_meta;
+ QDomDocument m_settings;
+
+ QDict<QDomElement> m_styles;
+ QDict<KSpread::Format> m_defaultStyles;
+ QDict<QString> m_formats;
+ QMap<QString,QDomElement> m_validationList;
+
+ QStringList m_namedAreas;
+
+ int readMetaData();
+ bool parseBody( int numOfTables );
+ void insertStyles( QDomElement const & element );
+ bool createStyleMap( QDomDocument const & styles );
+ bool readRowFormat( QDomElement & rowNode, QDomElement * rowStyle,
+ KSpread::Sheet * table, int & row, int & number, bool last );
+ bool readColLayouts( QDomElement & content, KSpread::Sheet * table );
+ bool readRowsAndCells( QDomElement & content, KSpread::Sheet * table );
+ bool readCells( QDomElement & rowNode, KSpread::Sheet * table, int row, int & columns );
+ void convertFormula( QString & text, QString const & f ) const;
+ void loadFontStyle( KSpread::Format * layout, QDomElement const * font ) const;
+ void readInStyle( KSpread::Format * layout, QDomElement const & style );
+ void loadStyleProperties( KSpread::Format * layout, QDomElement const & property ) const;
+ void loadBorder( KSpread::Format * layout, QString const & borderDef, bPos pos ) const;
+ void loadTableMasterStyle( KSpread::Sheet * table, QString const & stylename );
+ QString * loadFormat( QDomElement * element,
+ KSpread::FormatType & formatType,
+ QString name );
+ void checkForNamedAreas( QString & formula ) const;
+ void loadOasisCellValidation( const QDomElement&body );
+ void loadOasisValidation( KSpread::Validity* val, const QString& validationName );
+ void loadOasisValidationCondition( KSpread::Validity* val,QString &valExpression );
+ void loadOasisAreaName( const QDomElement&body );
+ void loadOasisMasterLayoutPage( KSpread::Sheet * table,KoStyleStack &styleStack );
+ void loadOasisValidationValue( KSpread::Validity* val, const QStringList &listVal );
+ QString translatePar( QString & par ) const;
+ void loadCondition( KSpread::Cell*cell,const QDomElement &property );
+ void loadOasisCondition(KSpread::Cell*cell,const QDomElement &property );
+ void loadOasisConditionValue( const QString &styleCondition, KSpread::Conditional &newCondition );
+ void loadOasisCondition( QString &valExpression, KSpread::Conditional &newCondition );
+ void loadOasisValidationValue( const QStringList &listVal, KSpread::Conditional &newCondition );
+ KoFilter::ConversionStatus loadAndParse( QDomDocument& doc, const QString& fileName,KoStore *m_store );
+
+ KoFilter::ConversionStatus openFile();
+};
+
+#endif // OpenCalc_IMPORT_H__
+
diff --git a/filters/kspread/opencalc/opencalcstyleexport.cc b/filters/kspread/opencalc/opencalcstyleexport.cc
new file mode 100644
index 000000000..34d574beb
--- /dev/null
+++ b/filters/kspread/opencalc/opencalcstyleexport.cc
@@ -0,0 +1,546 @@
+/* This file is part of the KDE project
+ Copyright (C) 2003 Norbert Andres <nandres@web.de>
+
+ 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 <opencalcstyleexport.h>
+
+#include <KoGlobal.h>
+
+#include <kspread_cell.h>
+#include <kspread_doc.h>
+#include <kspread_format.h>
+#include <kspread_sheet.h>
+#include <kspread_style.h>
+#include <kspread_style_manager.h>
+
+#include <qdom.h>
+
+using namespace KSpread;
+
+OpenCalcStyles::OpenCalcStyles()
+{
+ m_cellStyles.setAutoDelete( true );
+ m_columnStyles.setAutoDelete( true );
+ m_numberStyles.setAutoDelete( true );
+ m_rowStyles.setAutoDelete( true );
+ m_sheetStyles.setAutoDelete( true );
+
+ m_fontList.setAutoDelete( true );
+}
+
+OpenCalcStyles::~OpenCalcStyles()
+{
+}
+
+void OpenCalcStyles::writeStyles( QDomDocument & doc, QDomElement & autoStyles )
+{
+ addColumnStyles( doc, autoStyles );
+ addRowStyles( doc, autoStyles );
+ addSheetStyles( doc, autoStyles );
+ addNumberStyles( doc, autoStyles );
+ addCellStyles( doc, autoStyles );
+}
+
+void OpenCalcStyles::writeFontDecl( QDomDocument & doc, QDomElement & fontDecls )
+{
+ QFont * f = m_fontList.first();
+ while ( f )
+ {
+ QDomElement fontDecl = doc.createElement( "style:font-decl" );
+
+ fontDecl.setAttribute( "style:name", f->family() );
+ fontDecl.setAttribute( "fo:font-family", f->family() );
+ fontDecl.setAttribute( "style:font-pitch", ( f->fixedPitch() ? "fixed" : "variable" ) );
+
+ // missing:
+ // style:font-charset="x-symbol" style:font-family-generic="swiss"
+ // style:font-style-name= "Bold/Standard/Regular"
+
+ fontDecls.appendChild( fontDecl );
+
+ f = m_fontList.next();
+ }
+}
+
+void OpenCalcStyles::addFont( QFont const & font, bool def )
+{
+ if ( def )
+ m_defaultFont = font;
+
+ QFont * f = m_fontList.first();
+ while ( f )
+ {
+ if ( f->family() == font.family() )
+ return;
+
+ f = m_fontList.next();
+ }
+
+ f = new QFont( font );
+ m_fontList.append( f );
+}
+
+QString OpenCalcStyles::cellStyle( CellStyle const & cs )
+{
+ CellStyle * t = m_cellStyles.first();
+ while ( t )
+ {
+ if ( CellStyle::isEqual( t, cs ) )
+ return t->name;
+
+ t = m_cellStyles.next();
+ }
+
+ t = new CellStyle();
+ t->copyData( cs );
+
+ m_cellStyles.append( t );
+
+ t->name = QString( "ce%1" ).arg( m_cellStyles.count() );
+
+ return t->name;
+}
+
+QString OpenCalcStyles::columnStyle( ColumnStyle const & cs )
+{
+ ColumnStyle * t = m_columnStyles.first();
+ while ( t )
+ {
+ if ( ColumnStyle::isEqual( t, cs ) )
+ return t->name;
+
+ t = m_columnStyles.next();
+ }
+
+ t = new ColumnStyle();
+ t->copyData( cs );
+
+ m_columnStyles.append( t );
+
+ t->name = QString( "co%1" ).arg( m_columnStyles.count() );
+
+ return t->name;
+}
+
+QString OpenCalcStyles::numberStyle( NumberStyle const & )
+{
+ return "";
+}
+
+QString OpenCalcStyles::rowStyle( RowStyle const & rs )
+{
+ RowStyle * t = m_rowStyles.first();
+ while ( t )
+ {
+ if ( RowStyle::isEqual( t, rs ) )
+ return t->name;
+
+ t = m_rowStyles.next();
+ }
+
+ t = new RowStyle();
+ t->copyData( rs );
+
+ m_rowStyles.append( t );
+
+ t->name = QString( "ro%1" ).arg( m_rowStyles.count() );
+
+ return t->name;
+}
+
+QString OpenCalcStyles::sheetStyle( SheetStyle const & ts )
+{
+ SheetStyle * t = m_sheetStyles.first();
+ while ( t )
+ {
+ if ( SheetStyle::isEqual( t, ts ) )
+ return t->name;
+
+ t = m_sheetStyles.next();
+ }
+
+ t = new SheetStyle();
+ t->copyData( ts );
+
+ m_sheetStyles.append( t );
+
+ t->name = QString( "ta%1" ).arg( m_sheetStyles.count() );
+
+ return t->name;
+}
+
+QString convertPenToString( QPen const & pen )
+{
+ QString s( QString( "%1cm solid " ).arg( pen.width() * 0.035 ) );
+ s += pen.color().name();
+
+ return s;
+}
+
+void OpenCalcStyles::addCellStyles( QDomDocument & doc, QDomElement & autoStyles )
+{
+ CellStyle * t = m_cellStyles.first();
+ while ( t )
+ {
+ QDomElement ts = doc.createElement( "style:style" );
+ ts.setAttribute( "style:name", t->name );
+ ts.setAttribute( "style:family", "table-cell" );
+ ts.setAttribute( "style:parent-style-name", "Default" );
+ if ( t->numberStyle.length() > 0 )
+ ts.setAttribute( "style:data-style-name", t->numberStyle );
+
+ QDomElement prop = doc.createElement( "style:properties" );
+
+ if ( t->font.family() != m_defaultFont.family() )
+ prop.setAttribute( "style:font-name", t->font.family() );
+
+ if ( t->font.bold() != m_defaultFont.bold() )
+ prop.setAttribute( "fo:font-weight", ( t->font.bold() ? "bold" : "light" ) );
+
+ prop.setAttribute( "fo:font-size", QString( "%1pt" ).arg( t->font.pointSize() ) );
+
+ if ( t->font.underline() != m_defaultFont.underline() )
+ {
+ prop.setAttribute( "style:text-underline", ( t->font.underline() ? "single" : "none" ) );
+ if ( t->font.underline() )
+ prop.setAttribute( "style:text-underline-color", "font-color" );
+ }
+
+ if ( t->font.italic() != m_defaultFont.italic() )
+ prop.setAttribute( "fo:font-style", ( t->font.italic() ? "italic" : "none" ) );
+
+ if ( t->font.strikeOut() != m_defaultFont.strikeOut() )
+ prop.setAttribute( "style:text-crossing-out", ( t->font.strikeOut() ? "single-line" : "none" ) );
+
+ if ( t->color.name() != "#000000" )
+ prop.setAttribute( "fo:color", t->color.name() );
+
+ if ( t->bgColor.name() != "#ffffff" )
+ prop.setAttribute( "fo:background-color", t->bgColor.name() );
+
+ if ( t->alignX != Format::Undefined )
+ {
+ QString value;
+ if ( t->alignX == Format::Center )
+ value = "center";
+ else if ( t->alignX == Format::Right )
+ value = "end";
+ else if ( t->alignX == Format::Left )
+ value = "start";
+ prop.setAttribute( "fo:text-align", value );
+ }
+
+ if ( t->alignY != Format::Bottom ) // default in OpenCalc
+ prop.setAttribute( "fo:vertical-align", ( t->alignY == Format::Middle ? "middle" : "top" ) );
+
+ if ( t->indent > 0.0 )
+ {
+ prop.setAttribute( "fo:margin-left", QString( "%1pt" ).arg( t->indent ) );
+ if ( t->alignX == Format::Undefined )
+ prop.setAttribute( "fo:text-align", "start" );
+ }
+
+ if ( t->wrap )
+ prop.setAttribute( "fo:wrap-option", "wrap" );
+
+ if ( t->vertical )
+ {
+ prop.setAttribute( "fo:direction", "ttb" );
+ prop.setAttribute( "style:rotation-angle", "0" );
+ }
+
+ if ( t->angle != 0 )
+ prop.setAttribute( "style:rotation-angle", QString::number( t->angle ) );
+
+ if ( !t->print )
+ prop.setAttribute( "style:print-content", "false" );
+
+ if ( t->hideAll )
+ prop.setAttribute( "style:cell-protect", "hidden-and-protected" );
+ else
+ if ( t->notProtected && !t->hideFormula )
+ prop.setAttribute( "style:cell-protect", "none" );
+ else
+ if ( t->notProtected && t->hideFormula )
+ prop.setAttribute( "style:cell-protect", "formula-hidden" );
+ else if ( t->hideFormula )
+ prop.setAttribute( "style:cell-protect", "protected formula-hidden" );
+ else if ( !t->notProtected )
+ prop.setAttribute( "style:cell-protect", "protected" );
+
+
+ if ( ( t->left == t->right ) && ( t->left == t->top ) && ( t->left == t->bottom ) )
+ {
+ if ( ( t->left.width() != 0 ) && ( t->left.style() != Qt::NoPen ) )
+ prop.setAttribute( "fo:border", convertPenToString( t->left ) );
+ }
+ else
+ {
+ if ( ( t->left.width() != 0 ) && ( t->left.style() != Qt::NoPen ) )
+ prop.setAttribute( "fo:border-left", convertPenToString( t->left ) );
+
+ if ( ( t->right.width() != 0 ) && ( t->right.style() != Qt::NoPen ) )
+ prop.setAttribute( "fo:border-right", convertPenToString( t->right ) );
+
+ if ( ( t->top.width() != 0 ) && ( t->top.style() != Qt::NoPen ) )
+ prop.setAttribute( "fo:border-top", convertPenToString( t->top ) );
+
+ if ( ( t->bottom.width() != 0 ) && ( t->bottom.style() != Qt::NoPen ) )
+ prop.setAttribute( "fo:border-bottom", convertPenToString( t->bottom ) );
+ }
+
+ ts.appendChild( prop );
+ autoStyles.appendChild( ts );
+
+ t = m_cellStyles.next();
+ }
+}
+
+void OpenCalcStyles::addColumnStyles( QDomDocument & doc, QDomElement & autoStyles )
+{
+ ColumnStyle * t = m_columnStyles.first();
+ while ( t )
+ {
+ QDomElement ts = doc.createElement( "style:style" );
+ ts.setAttribute( "style:name", t->name );
+ ts.setAttribute( "style:family", "table-column" );
+
+ QDomElement prop = doc.createElement( "style:properties" );
+ if ( t->breakB != ::Style::none )
+ prop.setAttribute( "fo:break-before", ( t->breakB == ::Style::automatic ? "auto" : "page" ) );
+ prop.setAttribute( "style:column-width", QString( "%1cm" ).arg( t->size ) );
+
+ ts.appendChild( prop );
+ autoStyles.appendChild( ts );
+
+ t = m_columnStyles.next();
+ }
+}
+
+void OpenCalcStyles::addNumberStyles( QDomDocument & /*doc*/, QDomElement & /*autoStyles*/ )
+{
+}
+
+void OpenCalcStyles::addRowStyles( QDomDocument & doc, QDomElement & autoStyles )
+{
+ RowStyle * t = m_rowStyles.first();
+ while ( t )
+ {
+ QDomElement ts = doc.createElement( "style:style" );
+ ts.setAttribute( "style:name", t->name );
+ ts.setAttribute( "style:family", "table-row" );
+
+ QDomElement prop = doc.createElement( "style:properties" );
+ prop.setAttribute( "style:row-height", QString( "%1cm" ).arg( t->size ) );
+ if ( t->breakB != ::Style::none )
+ prop.setAttribute( "fo:break-before", ( t->breakB == ::Style::automatic ? "auto" : "page" ) );
+
+ ts.appendChild( prop );
+ autoStyles.appendChild( ts );
+
+ t = m_rowStyles.next();
+ }
+}
+
+void OpenCalcStyles::addSheetStyles( QDomDocument & doc, QDomElement & autoStyles )
+{
+ SheetStyle * t = m_sheetStyles.first();
+ while ( t )
+ {
+ QDomElement ts = doc.createElement( "style:style" );
+ ts.setAttribute( "style:name", t->name );
+ ts.setAttribute( "style:family", "table" );
+ ts.setAttribute( "style:master-page-name", "Default" );
+
+ QDomElement prop = doc.createElement( "style:properties" );
+ prop.setAttribute( "table:display", ( t->visible ? "true" : "false" ) );
+
+ ts.appendChild( prop );
+ autoStyles.appendChild( ts );
+
+ t = m_sheetStyles.next();
+ }
+}
+
+bool SheetStyle::isEqual( SheetStyle const * const t1, SheetStyle const & t2 )
+{
+ if ( t1->visible == t2.visible )
+ return true;
+
+ return false;
+}
+
+CellStyle::CellStyle()
+ : color( Qt::black ),
+ bgColor( Qt::white ),
+ indent( -1.0 ),
+ wrap( false ),
+ vertical( false ),
+ angle( 0 ),
+ print( true ),
+ left ( Qt::black, 0, Qt::NoPen ),
+ right( Qt::black, 0, Qt::NoPen ),
+ top ( Qt::black, 0, Qt::NoPen ),
+ bottom( Qt::black, 0, Qt::NoPen ),
+ hideAll( false ),
+ hideFormula( false ),
+ notProtected ( false ),
+ alignX( Format::Undefined ),
+ alignY( Format::Middle )
+{
+}
+
+void CellStyle::copyData( CellStyle const & ts )
+{
+ font = ts.font;
+ numberStyle = ts.numberStyle;
+ color = ts.color;
+ bgColor = ts.bgColor;
+ indent = ts.indent;
+ wrap = ts.wrap;
+ vertical = ts.vertical;
+ angle = ts.angle;
+ print = ts.print;
+ left = ts.left;
+ right = ts.right;
+ top = ts.top;
+ bottom = ts.bottom;
+ hideAll = ts.hideAll;
+ hideFormula = ts.hideFormula;
+ notProtected = ts.notProtected;
+ alignX = ts.alignX;
+ alignY = ts.alignY;
+}
+
+bool CellStyle::isEqual( CellStyle const * const t1, CellStyle const & t2 )
+{
+ if ( ( t1->font == t2.font ) && ( t1->numberStyle == t2.numberStyle )
+ && ( t1->color == t2.color ) && ( t1->bgColor == t2.bgColor )
+ && ( t1->alignX == t2.alignX ) && ( t1->alignY == t2.alignY )
+ && ( t1->indent == t2.indent ) && ( t1->wrap == t2.wrap )
+ && ( t1->vertical == t2.vertical ) && ( t1->angle == t2.angle )
+ && ( t1->print == t2.print ) && ( t1->left == t2.left )
+ && ( t1->right == t2.right ) && ( t1->top == t2.top )
+ && ( t1->bottom == t2.bottom ) && ( t1->hideAll == t2.hideAll )
+ && ( t1->hideFormula == t2.hideFormula ) && ( t1->notProtected == t2.notProtected )
+ )
+ return true;
+
+ return false;
+}
+
+// all except the number style
+void CellStyle::loadData( CellStyle & cs, Cell const * const cell )
+{
+ int col = cell->column();
+ int row = cell->row();
+
+ Format * f = new Format( 0, cell->sheet()->doc()->styleManager()->defaultStyle() );
+
+ QFont font = cell->format()->textFont( col, row );
+ if ( font != f->font() )
+ cs.font = font;
+
+ QColor color = cell->format()->textColor( col, row );
+ if ( color != f->textColor( col, row ) )
+ cs.color = color;
+
+ QColor bgColor = cell->bgColor( col, row );
+ if ( bgColor != f->bgColor( col, row ) )
+ cs.bgColor = bgColor;
+
+ if ( cell->format()->hasProperty( Format::PAlign ) || !cell->format()->hasNoFallBackProperties( Format::PAlign ) )
+ cs.alignX = cell->format()->align( col, row );
+
+ if ( cell->format()->hasProperty( Format::PAlignY ) || !cell->format()->hasNoFallBackProperties( Format::PAlignY ) )
+ cs.alignY = cell->format()->alignY( col, row );
+
+ if ( cell->format()->hasProperty( Format::PIndent ) || !cell->format()->hasNoFallBackProperties( Format::PIndent ) )
+ cs.indent = cell->format()->getIndent( col, row );
+
+ if ( cell->format()->hasProperty( Format::PAngle ) || !cell->format()->hasNoFallBackProperties( Format::PAngle ) )
+ cs.angle = -cell->format()->getAngle( col, row );
+
+ if ( cell->format()->hasProperty( Format::PMultiRow ) || !cell->format()->hasNoFallBackProperties( Format::PMultiRow ) )
+ cs.wrap = cell->format()->multiRow( col, row );
+
+ if ( cell->format()->hasProperty( Format::PVerticalText )
+ || !cell->format()->hasNoFallBackProperties( Format::PVerticalText ) )
+ cs.vertical = cell->format()->verticalText( col, row );
+
+ if ( cell->format()->hasProperty( Format::PDontPrintText )
+ || !cell->format()->hasNoFallBackProperties( Format::PDontPrintText ) )
+ cs.print = !cell->format()->getDontprintText( col, row );
+
+ if ( cell->format()->hasProperty( Format::PLeftBorder ) || !cell->format()->hasNoFallBackProperties( Format::PLeftBorder ) )
+ cs.left = cell->leftBorderPen( col, row );
+
+ if ( cell->format()->hasProperty( Format::PRightBorder ) || !cell->format()->hasNoFallBackProperties( Format::PRightBorder ) )
+ cs.right = cell->rightBorderPen( col, row );
+
+ if ( cell->format()->hasProperty( Format::PTopBorder ) || !cell->format()->hasNoFallBackProperties( Format::PTopBorder ) )
+ cs.top = cell->topBorderPen( col, row );
+
+ if ( cell->format()->hasProperty( Format::PBottomBorder ) || !cell->format()->hasNoFallBackProperties( Format::PBottomBorder ) )
+ cs.bottom = cell->bottomBorderPen( col, row );
+
+ if ( cell->format()->hasProperty( Format::PNotProtected ) || !cell->format()->hasNoFallBackProperties( Format::PNotProtected ) )
+ cs.notProtected = cell->format()->notProtected( col, row );
+
+ if ( cell->format()->hasProperty( Format::PHideAll ) || !cell->format()->hasNoFallBackProperties( Format::PHideAll ) )
+ cs.hideAll = cell->format()->isHideAll( col, row );
+
+ if ( cell->format()->hasProperty( Format::PHideFormula ) || !cell->format()->hasNoFallBackProperties( Format::PHideFormula ) )
+ cs.hideFormula = cell->format()->isHideFormula( col, row );
+}
+
+bool NumberStyle::isEqual( NumberStyle const * const t1, NumberStyle const & t2 )
+{
+ if ( ( t1->type == t2.type ) && ( t1->pattern == t2.pattern ) )
+ return true;
+
+ return false;
+}
+
+void ColumnStyle::copyData( ColumnStyle const & cs )
+{
+ breakB = cs.breakB;
+ size = cs.size;
+}
+
+bool ColumnStyle::isEqual( ColumnStyle const * const c1, ColumnStyle const & c2 )
+{
+ if ( ( c1->breakB == c2.breakB ) && ( c1->size == c2.size ) )
+ return true;
+
+ return false;
+}
+
+void RowStyle::copyData( RowStyle const & cs )
+{
+ breakB = cs.breakB;
+ size = cs.size;
+}
+
+bool RowStyle::isEqual( RowStyle const * const c1, RowStyle const & c2 )
+{
+ if ( ( c1->breakB == c2.breakB ) && ( c1->size == c2.size ) )
+ return true;
+
+ return false;
+}
diff --git a/filters/kspread/opencalc/opencalcstyleexport.h b/filters/kspread/opencalc/opencalcstyleexport.h
new file mode 100644
index 000000000..2321b5290
--- /dev/null
+++ b/filters/kspread/opencalc/opencalcstyleexport.h
@@ -0,0 +1,167 @@
+/* This file is part of the KDE project
+ Copyright (C) 2003 Norbert Andres <nandres@web.de>
+
+ 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.
+*/
+
+
+#ifndef OPENCALCSTYLEEXPORT_H
+#define OPENCALCSTYLEEXPORT_H
+
+#include "kspread_format.h"
+
+#include <qcolor.h>
+#include <qfont.h>
+#include <qptrlist.h>
+#include <qstring.h>
+
+namespace KSpread
+{
+ class Cell;
+}
+
+class QDomDocument;
+class QDomElement;
+
+typedef enum T1 { Boolean, Date, Number, Percentage, Time } NumberType;
+
+class Style
+{
+ public:
+ enum breakBefore { none, automatic, page };
+
+ Style() : breakB( none ), size( 0.0 ) {}
+
+ QString name;
+ uint breakB;
+ double size;
+};
+
+class SheetStyle
+{
+ public:
+ SheetStyle() : visible( true ) {}
+
+ void copyData( SheetStyle const & ts ) { visible = ts.visible; }
+ static bool isEqual( SheetStyle const * const t1, SheetStyle const & t2 );
+
+ QString name;
+ bool visible;
+};
+
+class NumberStyle
+{
+ public:
+ NumberStyle() {}
+
+ void copyData( NumberStyle const & ts ) { type = ts.type; }
+ static bool isEqual( NumberStyle const * const t1, NumberStyle const & t2 );
+
+ QString name;
+
+ NumberType type;
+ QString pattern;
+};
+
+class CellStyle
+{
+ public:
+ CellStyle();
+
+ void copyData( CellStyle const & ts );
+ static bool isEqual( CellStyle const * const t1, CellStyle const & t2 );
+
+ // all except the number style
+ static void loadData( CellStyle & cs, KSpread::Cell const * const cell );
+
+ QString name;
+
+ QFont font;
+ QString numberStyle;
+ QColor color;
+ QColor bgColor;
+ double indent;
+ bool wrap;
+ bool vertical;
+ int angle;
+ bool print;
+ QPen left;
+ QPen right;
+ QPen top;
+ QPen bottom;
+ bool hideAll;
+ bool hideFormula;
+ bool notProtected;
+
+ KSpread::Format::Align alignX;
+ KSpread::Format::AlignY alignY;
+};
+
+class ColumnStyle : public Style
+{
+ public:
+ ColumnStyle() : Style() {}
+
+ void copyData( ColumnStyle const & cs );
+ static bool isEqual( ColumnStyle const * const c1, ColumnStyle const & c2 );
+};
+
+class RowStyle : public Style
+{
+ public:
+ RowStyle() : Style() {}
+
+ void copyData( RowStyle const & cs );
+ static bool isEqual( RowStyle const * const c1, RowStyle const & c2 );
+};
+
+class OpenCalcStyles
+{
+ public:
+ OpenCalcStyles();
+ ~OpenCalcStyles();
+
+ void writeStyles ( QDomDocument & doc, QDomElement & autoStyles );
+ void writeFontDecl( QDomDocument & doc, QDomElement & content );
+
+ void addFont( QFont const & font, bool def = false );
+
+ QString cellStyle( CellStyle const & cs );
+ QString columnStyle( ColumnStyle const & cs );
+ QString numberStyle( NumberStyle const & ns );
+ QString rowStyle( RowStyle const & rs );
+ QString sheetStyle( SheetStyle const & ts );
+
+ private:
+ QPtrList<CellStyle> m_cellStyles;
+ QPtrList<ColumnStyle> m_columnStyles;
+ QPtrList<NumberStyle> m_numberStyles;
+ QPtrList<RowStyle> m_rowStyles;
+ QPtrList<SheetStyle> m_sheetStyles;
+ QPtrList<QFont> m_fontList;
+
+ QFont m_defaultFont;
+
+ void addCellStyles( QDomDocument & doc, QDomElement & autoStyles );
+ void addColumnStyles( QDomDocument & doc, QDomElement & autoStyles );
+ void addNumberStyles( QDomDocument & doc, QDomElement & autoStyles );
+ void addRowStyles( QDomDocument & doc, QDomElement & autoStyles );
+ void addSheetStyles( QDomDocument & doc, QDomElement & autoStyles );
+};
+
+
+
+#endif
diff --git a/filters/kspread/opencalc/status.html b/filters/kspread/opencalc/status.html
new file mode 100644
index 000000000..b23f6ae90
--- /dev/null
+++ b/filters/kspread/opencalc/status.html
@@ -0,0 +1,208 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <title>KOffice filters status: OpenOffice.org Calc filter</title>
+</head>
+<body text="#000000" bgcolor="#FFFFFF" link="#000099" vlink="#666666" alink="#666666">
+<a NAME="START"></a>
+<center>
+<h1>
+KOffice filters status:&nbsp;&nbsp; OpenOffice.org Calc</h1></center>
+
+<hr NOSHADE SIZE=2 WIDTH="70%"><b><font size="-1"><a href="#import">Import</a>
+| <a href="#export">Export</a></font></b>
+<br>&nbsp;
+<br>&nbsp;
+<br>
+<br>
+<center>
+<p><a NAME="import"></a></center>
+<b><font size="-1"><a href="#START">Up</a></font></b>
+<center><table BORDER=0 CELLSPACING=0 WIDTH="100%" BGCOLOR="#000000" >
+<tr>
+<td>
+<table BORDER=0 CELLPADDING=2 WIDTH="100%" BGCOLOR="#FFFFFF" >
+<tr BGCOLOR="#DDFFDD">
+<td COLSPAN="2">
+<center><b><i><font size="+1">Import OpenOffice.org Calc for Kspread</font></i></b></center>
+</td>
+</tr>
+
+<tr BGCOLOR="#EEEEFF">
+<td VALIGN=TOP NOWRAP WIDTH="1%"><b><font size="+1">Last update</font></b></td>
+
+<td>April 22, 2004</td>
+</tr>
+
+<tr BGCOLOR="#CCCCFF">
+<td VALIGN=TOP><b><font size="+1">Features</font></b></td>
+ <td>
+ Loading tables, hidden tables, print ranges<br>
+ Named areas<br>
+ hidden columns<br>
+ hidden rows<br>
+ Comments<br>
+ Formulas<br>
+ Links (e-mail, files, web)<br>
+ cell content<br>
+ Datatypes: float, percentage, (date), times, booleans (miss some kspread support) <br>
+ Formating: indents, bold, italic, alignments, colors...<br>
+ Borders, background colors<br>
+ column width, row width<br>
+ column layouts, row layouts<br>
+ page layout (size, border)<br>
+ OpenCalc style import, default style<br>
+ format string translating (not supported by KSpread yet, but this filter produces these strings => needs enhancements in KSpread)<br>
+ header, footer (including macros)<br>
+ protected maps, tables, unprotected cells, hidden cells, hidden formulas<br>
+ validation<br>
+ not printed cells
+ </td>
+</tr>
+
+<tr BGCOLOR="#EEEEFF">
+<td VALIGN=TOP><b><font size="+1">Todo</font></b></td>
+<td>
+ Page breaks (for Columns &amp; Rows)(not supported by KSpread)<br>
+ leading zeros (not supported by KSpread)<br>
+ embedded objects (Charts!)<br>
+ conditional cell attributes<br>
+ real format string usage(KSpread feature not implemented yet - as soon as it exists this filter will benefit automatically)
+ check Table names in "'", like 'This is my name'<br>
+ Settings<br>
+</td>
+</tr>
+
+<tr BGCOLOR="#CCCCFF">
+<td VALIGN=TOP><b><font size="+1">History</font></b></td>
+
+<td>
+ Sep 26, 2002 - Initial Revision<br>
+</td>
+</tr>
+
+<tr BGCOLOR="#EEEEFF">
+<td VALIGN=TOP><b><font size="+1">Authors</font></b></td>
+<td>
+ <a href="mailto:nandres@web.de">Norbert Andres</a>
+</td>
+</tr>
+
+<tr BGCOLOR="#CCCCFF">
+<td VALIGN=TOP><b><font size="+1">Links</font></b></td>
+<td><a href="http://xml.openoffice.org">OpenOffice.org XML Web Site</a></td>
+</tr>
+
+<tr BGCOLOR="#EEEEFF">
+<td VALIGN=TOP><b><font size="+1">Progress report&nbsp;</font></b></td>
+<td></td>
+</tr>
+</table>
+</td>
+</tr>
+</table></center>
+<b><font size="-1"><a href="#START">Up</a></font></b>
+<br>&nbsp;
+<p>
+<hr NOSHADE SIZE=1>
+<br>&nbsp;
+<br>&nbsp;
+<br>
+<br>
+<center>
+<p><a NAME="export"></a></center>
+<b><font size="-1"><a href="#START">Up</a></font></b>
+<center><table BORDER=0 CELLSPACING=0 WIDTH="100%" BGCOLOR="#000000" >
+<tr>
+<td>
+<table BORDER=0 CELLPADDING=2 WIDTH="100%" BGCOLOR="#FFFFFF" >
+<tr BGCOLOR="#FFDDDD">
+<td COLSPAN="2">
+<center><b><i><font size="+1">Export Kspread to OpenOffice.org Calc</font></i></b></center>
+</td>
+</tr>
+
+<tr BGCOLOR="#EEEEFF">
+<td VALIGN=TOP NOWRAP WIDTH="1%"><b><font size="+1">Last update</font></b></td>
+
+<td>Octo 20, 2004</td>
+</tr>
+
+<tr BGCOLOR="#CCCCFF">
+<td VALIGN=TOP><b><font size="+1">Features</font></b></td>
+<td>
+ Saves sheets (supported: hidden sheets, names)<br>
+ Saves columns and row (supported: widths/heights, page breaks, hidden)<br>
+ Saves cell contents (including formula conversion)<br>
+ Document information<br>
+ Page sizes, header and footer (including variable converting)<br>
+ Font (sizes, attributes, color)<br>
+ Background color<br>
+ Text alignment, angle, vertical text, text wrap and indents<br>
+ Merged Cells<br>
+ DontPrint flag<br>
+ Comments<br>
+ Named Areas<br>
+ Cell borders<br>
+ Link<br>
+ protected maps, tables, unprotected cells, hidden cells, hidden formulas<br>
+ not printed cells<br>
+ Print ranges<br>
+ Export document settings (active table, cursor position)<br>
+ Settings<br>
+ Validation<br>
+</td>
+</tr>
+
+<tr BGCOLOR="#EEEEFF">
+<td VALIGN=TOP><b><font size="+1">Todo</font></b></td>
+<td>
+ Number formats (needs some new features in KSpread)<br>
+ Embedded objects (charts,...)<br>
+ Conditions<br>
+</td>
+</tr>
+
+<tr BGCOLOR="#CCCCFF">
+<td VALIGN=TOP><b><font size="+1">History</font></b></td>
+
+<td>
+ Jan 12, 2003 - Initial Revision<br>
+ Jan 18, 2003 - page layout, header, footer<br>
+ Jan 19, 2003 - Added support for fonts, text color, background color, formula
+conversion<br>
+ Jan 19, 2003 - text alignment, indents, comments, NoPrint, Merged Cells<br>
+ Jan 19, 2003 - angle, vertical text, text wrap<br>
+ Jan 19, 2003 - named area, hidden columns and rows<br>
+ Jan 20, 2003 - cell borders<br>
+ Jan 29, 2003 - protected stuff<br>
+ Mar 13, 2005 - link<br>
+</tr>
+
+<tr BGCOLOR="#EEEEFF">
+<td VALIGN=TOP><b><font size="+1">Authors</font></b></td>
+
+<td>
+ <a href="mailto:nandres@web.de">Norbert Andres</a>
+</td>
+</tr>
+
+<tr BGCOLOR="#CCCCFF">
+<td VALIGN=TOP><b><font size="+1">Links</font></b></td>
+
+<td><a href="http://xml.openoffice.org">OpenOffice.org XML Web Site</a></td>
+</tr>
+
+<tr BGCOLOR="#EEEEFF">
+<td VALIGN=TOP><b><font size="+1">Progress report</font></b></td>
+<td></td>
+</tr>
+</table>
+</td>
+</tr>
+</table></center>
+<b><font size="-1"><a href="#START">Up</a></font></b>
+
+</body>
+</html>