filters

excelimport.cc

00001 /* This file is part of the KDE project
00002    Copyright (C) 2003-2006 Ariya Hidayat <ariya@kde.org>
00003    Copyright (C) 2006 Marijn Kruisselbrink <m.kruisselbrink@student.tue.nl>
00004 
00005    This library is free software; you can redistribute it and/or
00006    modify it under the terms of the GNU Library General Public
00007    License as published by the Free Software Foundation; either
00008    version 2 of the License, or (at your option) any later version.
00009 
00010    This library is distributed in the hope that it will be useful,
00011    but WITHOUT ANY WARRANTY; without even the implied warranty of
00012    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013    Library General Public License for more details.
00014 
00015    You should have received a copy of the GNU Library General Public License
00016    along with this library; see the file COPYING.LIB.  If not, write to
00017    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00018  * Boston, MA 02110-1301, USA.
00019 */
00020 
00021 #include <config.h>
00022 
00023 #ifdef HAVE_UNISTD_H
00024 #include <unistd.h>
00025 #endif
00026 
00027 #include <excelimport.h>
00028 #include <excelimport.moc>
00029 
00030 #include <qbuffer.h>
00031 #include <qcstring.h>
00032 #include <qdatetime.h>
00033 #include <qfile.h>
00034 #include <qstring.h>
00035 #include <qtextstream.h>
00036 
00037 #include <kdebug.h>
00038 #include <KoFilterChain.h>
00039 #include <KoGlobal.h>
00040 #include <KoUnit.h>
00041 #include <kgenericfactory.h>
00042 
00043 #include <KoXmlWriter.h>
00044 #include <KoOasisStore.h>
00045 
00046 #include "swinder.h"
00047 #include <iostream>
00048 
00049 typedef KGenericFactory<ExcelImport, KoFilter> ExcelImportFactory;
00050 K_EXPORT_COMPONENT_FACTORY( libexcelimport, ExcelImportFactory( "kofficefilters" ) )
00051 
00052 
00053 // UString -> QConstString conversion. Use .string() to get the QString.
00054 // Always store the QConstString into a variable first, to avoid a deep copy.
00055 inline QConstString string( const Swinder::UString& str ) {
00056    // Let's hope there's no copying of the QConstString happening...
00057    return QConstString( reinterpret_cast<const QChar*>( str.data() ), str.length() );
00058 }
00059 
00060 using namespace Swinder;
00061 
00062 class ExcelImport::Private
00063 {
00064 public:
00065   QString inputFile;
00066   QString outputFile;
00067 
00068   Workbook *workbook;  
00069 
00070   bool createStyles( KoOasisStore* store );
00071   bool createContent( KoOasisStore* store );
00072   bool createManifest( KoOasisStore* store );
00073   
00074   int sheetFormatIndex;
00075   int columnFormatIndex;
00076   int rowFormatIndex;
00077   int cellFormatIndex;
00078   int valueFormatIndex;
00079   
00080   void processWorkbookForBody( Workbook* workbook, KoXmlWriter* xmlWriter );
00081   void processWorkbookForStyle( Workbook* workbook, KoXmlWriter* xmlWriter );
00082   void processSheetForBody( Sheet* sheet, KoXmlWriter* xmlWriter );
00083   void processSheetForStyle( Sheet* sheet, KoXmlWriter* xmlWriter );
00084   void processColumnForBody( Column* column, int repeat, KoXmlWriter* xmlWriter );
00085   void processColumnForStyle( Column* column, int repeat, KoXmlWriter* xmlWriter );
00086   void processRowForBody( Row* row, int repeat, KoXmlWriter* xmlWriter );
00087   void processRowForStyle( Row* row, int repeat, KoXmlWriter* xmlWriter );
00088   void processCellForBody( Cell* cell, KoXmlWriter* xmlWriter );
00089   void processCellForStyle( Cell* cell, KoXmlWriter* xmlWriter );
00090   void processFormat( Format* format, KoXmlWriter* xmlWriter );
00091   void processValueFormat( QString valueFormat, QString refName, KoXmlWriter* xmlWriter );
00092 };
00093 
00094 
00095 ExcelImport::ExcelImport ( QObject*, const char*, const QStringList& )
00096     : KoFilter()
00097 {
00098   d = new Private;
00099 }
00100 
00101 ExcelImport::~ExcelImport()
00102 {
00103   delete d;
00104 }
00105 
00106 KoFilter::ConversionStatus ExcelImport::convert( const QCString& from, const QCString& to )
00107 {
00108   if ( from != "application/msexcel" )
00109     return KoFilter::NotImplemented; 
00110 
00111   if ( to != "application/vnd.oasis.opendocument.spreadsheet" )     
00112     return KoFilter::NotImplemented;
00113 
00114   d->inputFile = m_chain->inputFile();
00115   d->outputFile = m_chain->outputFile();
00116 
00117   // open inputFile
00118   d->workbook = new Swinder::Workbook;
00119   if( !d->workbook->load( d->inputFile.local8Bit() ) )
00120   {
00121     delete d->workbook;
00122     d->workbook = 0;
00123     return KoFilter::StupidError;
00124   }
00125 
00126   if( d->workbook->isPasswordProtected() )
00127   {
00128     delete d->workbook;
00129     d->workbook = 0;
00130     return KoFilter::PasswordProtected;
00131   }
00132   
00133   // create output store
00134   KoStore* storeout;
00135   storeout = KoStore::createStore( d->outputFile, KoStore::Write, 
00136     "application/vnd.oasis.opendocument.spreadsheet", KoStore::Zip );
00137 
00138   if ( !storeout )
00139   {
00140     kdWarning() << "Couldn't open the requested file." << endl;
00141     delete d->workbook;
00142     return KoFilter::FileNotFound;
00143   }
00144 
00145   // Tell KoStore not to touch the file names
00146   storeout->disallowNameExpansion();
00147   KoOasisStore oasisStore( storeout );
00148 
00149   // store document styles
00150   d->sheetFormatIndex = 1;
00151   d->columnFormatIndex = 1;
00152   d->rowFormatIndex = 1;
00153   d->cellFormatIndex = 1;
00154   d->valueFormatIndex = 1;
00155   if ( !d->createStyles( &oasisStore ) ) 
00156   {
00157     kdWarning() << "Couldn't open the file 'styles.xml'." << endl;
00158     delete d->workbook;
00159     delete storeout;
00160     return KoFilter::CreationError;
00161   }
00162 
00163   // store document content
00164   d->sheetFormatIndex = 1;
00165   d->columnFormatIndex = 1;
00166   d->rowFormatIndex = 1;
00167   d->cellFormatIndex = 1;
00168   d->valueFormatIndex = 1;
00169   if ( !d->createContent( &oasisStore ) )
00170   {
00171     kdWarning() << "Couldn't open the file 'content.xml'." << endl;
00172     delete d->workbook;
00173     delete storeout;
00174     return KoFilter::CreationError;
00175   }
00176 
00177   // store document manifest
00178   if ( !d->createManifest( &oasisStore ) )
00179   {
00180     kdWarning() << "Couldn't open the file 'META-INF/manifest.xml'." << endl;
00181     delete d->workbook;
00182     delete storeout;
00183     return KoFilter::CreationError;
00184   }
00185 
00186   // we are done!
00187   delete d->workbook;
00188   delete storeout;
00189   d->inputFile = QString::null;
00190   d->outputFile = QString::null;
00191   d->workbook = 0;
00192 
00193   return KoFilter::OK;
00194 }
00195 
00196 bool ExcelImport::Private::createContent( KoOasisStore* store )
00197 {
00198   KoXmlWriter* bodyWriter = store->bodyWriter();
00199   KoXmlWriter* contentWriter = store->contentWriter();
00200   if ( !bodyWriter || !contentWriter )
00201     return false;
00202 
00203   // FIXME this is dummy and hardcoded, replace with real font names
00204   contentWriter->startElement( "office:font-face-decls" );
00205   contentWriter->startElement( "style:font-face" );
00206   contentWriter->addAttribute( "style:name", "Arial" );
00207   contentWriter->addAttribute( "svg:font-family", "Arial" );
00208   contentWriter->endElement(); // style:font-face
00209   contentWriter->startElement( "style:font-face" );
00210   contentWriter->addAttribute( "style:name", "Times New Roman" );
00211   contentWriter->addAttribute( "svg:font-family", "&apos;Times New Roman&apos;" );
00212   contentWriter->endElement(); // style:font-face
00213   contentWriter->endElement(); // office:font-face-decls
00214 
00215   // important: reset all indexes  
00216   sheetFormatIndex = 1;
00217   columnFormatIndex = 1;
00218   rowFormatIndex = 1;
00219   cellFormatIndex = 1;
00220   valueFormatIndex = 1;
00221   
00222   // office:automatic-styles
00223   contentWriter->startElement( "office:automatic-styles" );
00224   processWorkbookForStyle( workbook, contentWriter );
00225   contentWriter->endElement(); // office:automatic-style
00226 
00227   // important: reset all indexes  
00228   sheetFormatIndex = 1;
00229   columnFormatIndex = 1;
00230   rowFormatIndex = 1;
00231   cellFormatIndex = 1;
00232   valueFormatIndex = 1;
00233   
00234   // office:body
00235   bodyWriter->startElement( "office:body" );
00236   processWorkbookForBody( workbook, bodyWriter );
00237   bodyWriter->endElement();  // office:body
00238   
00239   return store->closeContentWriter();
00240 }
00241 
00242 bool ExcelImport::Private::createStyles( KoOasisStore* store )
00243 {
00244   if ( !store->store()->open( "styles.xml" ) )
00245     return false;
00246   KoStoreDevice dev( store->store() );
00247   KoXmlWriter* stylesWriter = new KoXmlWriter( &dev );
00248 
00249   // FIXME this is dummy default, replace if necessary
00250   stylesWriter->startDocument( "office:document-styles" );
00251   stylesWriter->startElement( "office:document-styles" );
00252   stylesWriter->addAttribute( "xmlns:office", "urn:oasis:names:tc:opendocument:xmlns:office:1.0" );
00253   stylesWriter->addAttribute( "xmlns:style", "urn:oasis:names:tc:opendocument:xmlns:style:1.0" );
00254   stylesWriter->addAttribute( "xmlns:text", "urn:oasis:names:tc:opendocument:xmlns:text:1.0" );
00255   stylesWriter->addAttribute( "xmlns:table", "urn:oasis:names:tc:opendocument:xmlns:table:1.0" );
00256   stylesWriter->addAttribute( "xmlns:draw", "urn:oasis:names:tc:opendocument:xmlns:drawing:1.0" );
00257   stylesWriter->addAttribute( "xmlns:fo", "urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0" );
00258   stylesWriter->addAttribute( "xmlns:svg","urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0" );
00259   stylesWriter->addAttribute( "office:version","1.0" );
00260   stylesWriter->startElement( "office:styles" );
00261   stylesWriter->startElement( "style:default-style" );
00262   stylesWriter->addAttribute( "style:family", "table-cell" );
00263   stylesWriter->startElement( "style:table-cell-properties" );
00264   stylesWriter->addAttribute( "style:decimal-places", "2" );
00265   stylesWriter->endElement(); // style:table-cell-properties
00266   stylesWriter->startElement( "style:paragraph-properties" );
00267   stylesWriter->addAttribute( "style:tab-stop-distance", "0.5in" );
00268   stylesWriter->endElement(); // style:paragraph-properties
00269   stylesWriter->startElement( "style:text-properties" );
00270   stylesWriter->addAttribute( "style:font-name", "Albany AMT" );
00271   stylesWriter->addAttribute( "fo:language", "en" );
00272   stylesWriter->addAttribute( "fo:country", "US" );
00273   stylesWriter->addAttribute( "style:font-name-asian", "Albany AMT1" );
00274   stylesWriter->addAttribute( "style:country-asian", "none" );
00275   stylesWriter->addAttribute( "style:font-name-complex", "Lucidasans" );
00276   stylesWriter->addAttribute( "style:language-complex", "none" );
00277   stylesWriter->addAttribute( "style:country-complex", "none" );
00278   stylesWriter->endElement(); // style:text-properties
00279   stylesWriter->endElement(); // style:default-style
00280   stylesWriter->startElement( "style:style" );
00281   stylesWriter->addAttribute( "style:name", "Default" );
00282   stylesWriter->addAttribute( "style:family", "table-cell" );
00283   stylesWriter->endElement(); // style:style
00284   stylesWriter->endElement(); // office:styles
00285   
00286   // office:automatic-styles
00287   stylesWriter->startElement( "office:automatic-styles" );
00288   stylesWriter->endElement(); // office:automatic-styles
00289 
00290   stylesWriter->endElement();  // office:document-styles
00291   stylesWriter->endDocument();
00292   
00293   delete stylesWriter;
00294 
00295   return store->store()->close();
00296 }
00297 
00298 bool ExcelImport::Private::createManifest( KoOasisStore* store )
00299 {
00300   KoXmlWriter* manifestWriter = store->manifestWriter( "application/vnd.oasis.opendocument.spreadsheet" );
00301   
00302   manifestWriter->addManifestEntry( "styles.xml", "text/xml" );
00303   manifestWriter->addManifestEntry( "content.xml", "text/xml" );
00304 
00305   return store->closeManifestWriter();
00306 }
00307 
00308 void ExcelImport::Private::processWorkbookForBody( Workbook* workbook, KoXmlWriter* xmlWriter )
00309 {
00310   if( !workbook ) return;
00311   if( !xmlWriter ) return;
00312   
00313   xmlWriter->startElement( "office:spreadsheet" );
00314   
00315   for( unsigned i=0; i < workbook->sheetCount(); i++ )
00316   {
00317     Sheet* sheet = workbook->sheet( i );
00318     processSheetForBody( sheet, xmlWriter );
00319   }
00320   
00321   xmlWriter->endElement();  // office:spreadsheet
00322 }
00323 
00324 void ExcelImport::Private::processWorkbookForStyle( Workbook* workbook, KoXmlWriter* xmlWriter )
00325 {
00326   if( !workbook ) return;
00327   if( !xmlWriter ) return;
00328   
00329   for( unsigned i=0; i < workbook->sheetCount(); i++ )
00330   {
00331     Sheet* sheet = workbook->sheet( i );
00332     processSheetForStyle( sheet, xmlWriter );
00333   }
00334 }
00335 
00336 void ExcelImport::Private::processSheetForBody( Sheet* sheet, KoXmlWriter* xmlWriter )
00337 {
00338   if( !sheet ) return;
00339   if( !xmlWriter ) return;
00340   
00341   xmlWriter->startElement( "table:table" );
00342   
00343   xmlWriter->addAttribute( "table:name", string( sheet->name() ).string() );
00344   xmlWriter->addAttribute( "table:print", "false" );
00345   xmlWriter->addAttribute( "table:protected", "false" );
00346   xmlWriter->addAttribute( "table:style-name", QString("ta%1").arg(sheetFormatIndex));
00347   sheetFormatIndex++;
00348   
00349   unsigned ci = 0;
00350   while( ci <= sheet->maxColumn() )
00351   {
00352     Column* column = sheet->column( ci, false );
00353     if( column )
00354     {
00355       // forward search for columns with same properties
00356       unsigned cj = ci + 1;
00357       while( cj <= sheet->maxColumn() )
00358       {
00359         const Column* nextColumn = sheet->column( cj, false );
00360         if( !nextColumn ) break;
00361         if( column->width() != nextColumn->width() ) break;
00362         if( column->visible() != nextColumn->visible() ) break;
00363         if( column->format() != nextColumn->format() ) break;
00364         cj++;
00365       }
00366       
00367       int repeated = cj - ci;
00368       processColumnForBody( column, repeated, xmlWriter );
00369       ci += repeated;
00370     }
00371     else {
00372       ci++;
00373       xmlWriter->startElement( "table:table-column" );
00374       xmlWriter->endElement();
00375     }
00376   }
00377   
00378   for( unsigned i = 0; i <= sheet->maxRow(); i++ )
00379   {
00380     // FIXME optimized this when operator== in Swinder::Format is implemented
00381     processRowForBody( sheet->row( i, false ), 1, xmlWriter );
00382   }
00383   
00384   xmlWriter->endElement();  // table:table
00385 }
00386 
00387 void ExcelImport::Private::processSheetForStyle( Sheet* sheet, KoXmlWriter* xmlWriter )
00388 {
00389   if( !sheet ) return;
00390   if( !xmlWriter ) return;
00391 
00392   xmlWriter->startElement( "style:style" );
00393   xmlWriter->addAttribute( "style:family", "table" );  
00394   xmlWriter->addAttribute( "style:master-page-name", "Default" );  
00395   xmlWriter->addAttribute( "style:name", QString("ta%1").arg(sheetFormatIndex) );  
00396   sheetFormatIndex++;
00397   
00398   xmlWriter->startElement( "style:table-properties" );
00399   xmlWriter->addAttribute( "table:display", sheet->visible() ? "true" : "false" );
00400   xmlWriter->addAttribute( "table:writing-mode", "lr-tb" );
00401   xmlWriter->endElement();  // style:table-properties
00402   
00403   xmlWriter->endElement();  // style:style
00404 
00405   unsigned ci = 0;
00406   while( ci <= sheet->maxColumn() )
00407   {
00408     Column* column = sheet->column( ci, false );
00409     if( column )
00410     {
00411       // forward search for similar column
00412       unsigned cj = ci + 1;
00413       while( cj <= sheet->maxColumn() )
00414       {
00415         Column* nextColumn = sheet->column( cj, false );
00416         if( !nextColumn ) break;
00417         if( column->width() != nextColumn->width() ) break;
00418         if( column->visible() != nextColumn->visible() ) break;
00419         if( column->format() != nextColumn->format() ) break;
00420         cj++;
00421       }
00422       
00423       int repeated = cj - ci;
00424       processColumnForStyle( column, repeated, xmlWriter );
00425       ci += repeated;
00426     }
00427     else
00428       ci++;
00429   }
00430   
00431   for( unsigned i = 0; i <= sheet->maxRow(); i++ )
00432   {
00433     Row* row = sheet->row( i, false );
00434     // FIXME optimized this when operator== in Swinder::Format is implemented
00435     processRowForStyle( row, 1, xmlWriter );
00436   }
00437 }
00438 
00439 void ExcelImport::Private::processColumnForBody( Column* column, int repeat, KoXmlWriter* xmlWriter )
00440 {
00441   if( !column ) return;
00442   if( !xmlWriter ) return;
00443   
00444   xmlWriter->startElement( "table:table-column" );
00445   xmlWriter->addAttribute( "table:default-style-name", "Default" );  
00446   xmlWriter->addAttribute( "table:visibility", column->visible() ? "visible" : "collapse" );  
00447   if(repeat > 1) xmlWriter->addAttribute( "table:number-columns-repeated", repeat );  
00448   xmlWriter->addAttribute( "table:style-name", QString("co%1").arg(columnFormatIndex) );  
00449   columnFormatIndex++;
00450 
00451   xmlWriter->endElement();  // table:table-column
00452 }
00453 
00454 void ExcelImport::Private::processColumnForStyle( Column* column, int /*repeat*/, KoXmlWriter* xmlWriter )
00455 {
00456   if( !column ) return;
00457   if( !xmlWriter ) return;
00458   
00459   xmlWriter->startElement( "style:style" );
00460   xmlWriter->addAttribute( "style:family", "table-column" );  
00461   xmlWriter->addAttribute( "style:name", QString("co%1").arg(columnFormatIndex) );  
00462   columnFormatIndex++;
00463   
00464   xmlWriter->startElement( "style:table-column-properties" );
00465   xmlWriter->addAttribute( "fo:break-before", "auto" );
00466   xmlWriter->addAttribute( "style:column-width", QString("%1in").arg(column->width()/27) );
00467   xmlWriter->endElement();  // style:table-column-properties
00468   
00469   xmlWriter->endElement();  // style:style
00470 }
00471 
00472 void ExcelImport::Private::processRowForBody( Row* row, int /*repeat*/, KoXmlWriter* xmlWriter )
00473 {
00474   if( !xmlWriter ) return;
00475   if( !row ) {
00476     xmlWriter->startElement( "table:table-row" );
00477     xmlWriter->endElement();
00478     return;
00479   }
00480   if( !row->sheet() ) return;
00481   
00482   // find the column of the rightmost cell (if any)
00483   int lastCol = -1;
00484   for( unsigned i = 0; i <= row->sheet()->maxColumn(); i++ )
00485     if( row->sheet()->cell( i, row->index(), false ) ) lastCol = i;
00486   
00487   xmlWriter->startElement( "table:table-row" );
00488   xmlWriter->addAttribute( "table:visibility", row->visible() ? "visible" : "collapse" );  
00489   xmlWriter->addAttribute( "table:style-name", QString("ro%1").arg(rowFormatIndex) );  
00490   rowFormatIndex++;
00491   
00492   for( int i = 0; i <= lastCol; i++ )
00493   {
00494     Cell* cell = row->sheet()->cell( i, row->index(), false );
00495     if( cell )
00496       processCellForBody( cell, xmlWriter );
00497     else
00498     {
00499       // empty cell
00500       xmlWriter->startElement( "table:table-cell" );
00501       xmlWriter->endElement();
00502     }
00503   }
00504   
00505   xmlWriter->endElement();  // table:table-row
00506 }
00507 
00508 void ExcelImport::Private::processRowForStyle( Row* row, int repeat, KoXmlWriter* xmlWriter )
00509 {
00510   if( !row ) return;
00511   if( !row->sheet() ) return;
00512   if( !xmlWriter ) return;
00513 
00514   // find the column of the rightmost cell (if any)
00515   int lastCol = -1;
00516   for( unsigned i = 0; i <= row->sheet()->maxColumn(); i++ )
00517     if( row->sheet()->cell( i, row->index(), false ) ) lastCol = i;
00518   
00519   xmlWriter->startElement( "style:style" );
00520   xmlWriter->addAttribute( "style:family", "table-row" );  
00521   if(repeat > 1) xmlWriter->addAttribute( "table:number-rows-repeated", repeat );  
00522   xmlWriter->addAttribute( "style:name", QString("ro%1").arg(rowFormatIndex) );  
00523   rowFormatIndex++;
00524   
00525   xmlWriter->startElement( "style:table-row-properties" );
00526   xmlWriter->addAttribute( "fo:break-before", "auto" );
00527   xmlWriter->addAttribute( "style:row-height", QString("%1pt").arg(row->height()) );
00528   xmlWriter->endElement();  // style:table-row-properties
00529   
00530   xmlWriter->endElement();  // style:style
00531 
00532   for( int i = 0; i <= lastCol; i++ )
00533   {
00534     Cell* cell = row->sheet()->cell( i, row->index(), false );
00535     if( cell )
00536       processCellForStyle( cell, xmlWriter );
00537   }
00538 }
00539 
00540 static bool isPercentageFormat( QString valueFormat )
00541 {
00542   if( valueFormat.isEmpty() ) return false;
00543   if( valueFormat.length() < 1 ) return false;
00544   return valueFormat[valueFormat.length()-1] == QChar('%');
00545 }
00546 
00547 static bool isDateFormat( QString valueFormat )
00548 {
00549   QString vfu = valueFormat.upper();
00550   
00551   if( vfu == "M/D/YY" ) return true;
00552   if( vfu == "M/D/YYYY" ) return true;
00553   if( vfu == "MM/DD/YY" ) return true;
00554   if( vfu == "MM/DD/YYYY" ) return true;
00555   if( vfu == "D-MMM-YY" ) return true;
00556   if( vfu == "D\\-MMM\\-YY" ) return true;
00557   if( vfu == "D-MMM-YYYY" ) return true;
00558   if( vfu == "D\\-MMM\\-YYYY" ) return true;
00559   if( vfu == "D-MMM" ) return true;
00560   if( vfu == "D\\-MMM" ) return true;
00561   if( vfu == "D-MM" ) return true;
00562   if( vfu == "D\\-MM" ) return true;
00563   if( vfu == "MMM/DD" ) return true;
00564   if( vfu == "MMM/D" ) return true;
00565   if( vfu == "MM/DD" ) return true;
00566   if( vfu == "MM/D" ) return true;
00567   if( vfu == "MM/DD/YY" ) return true;
00568   if( vfu == "MM/DD/YYYY" ) return true;
00569   if( vfu == "YYYY/MM/D" ) return true;
00570   if( vfu == "YYYY/MM/DD" ) return true;
00571   if( vfu == "YYYY-MM-D" ) return true;
00572   if( vfu == "YYYY\\-MM\\-D" ) return true;
00573   if( vfu == "YYYY-MM-DD" ) return true;
00574   if( vfu == "YYYY\\-MM\\-DD" ) return true;
00575   
00576   return false;
00577 }
00578 
00579 static bool isTimeFormat( QString valueFormat )
00580 {
00581   QString vf = valueFormat;
00582   
00583   if( vf == "h:mm AM/PM" ) return true;
00584   if( vf == "h:mm:ss AM/PM" ) return true;
00585   if( vf == "h:mm" ) return true;
00586   if( vf == "h:mm:ss" ) return true;
00587   if( vf == "[h]:mm:ss" ) return true;
00588   if( vf == "[h]:mm" ) return true;
00589   if( vf == "[mm]:ss" ) return true;
00590   if( vf == "M/D/YY h:mm" ) return true;
00591   if( vf == "[ss]" ) return true;
00592   if( vf == "mm:ss" ) return true;
00593   if( vf == "mm:ss.0" ) return true;
00594   if( vf == "[mm]:ss" ) return true;
00595   if( vf == "[ss]" ) return true;
00596   
00597   return false;
00598 }
00599 
00600 static QString convertDate( double serialNo )
00601 {
00602   // reference is midnight 30 Dec 1899
00603   QDate dd( 1899, 12, 30 );
00604   dd = dd.addDays( (int) serialNo );
00605   return dd.toString( "yyyy-MM-dd" );
00606 }
00607 
00608 static QString convertTime( double serialNo )
00609 {
00610   // reference is midnight 30 Dec 1899
00611   QTime tt;
00612   tt = tt.addMSecs( qRound( (serialNo-(int)serialNo) * 86400 * 1000 ) );
00613   return tt.toString( "PThhHmmMss,zzz0S" );
00614 }  
00615 
00616 void ExcelImport::Private::processCellForBody( Cell* cell, KoXmlWriter* xmlWriter )
00617 {
00618   if( !cell ) return;
00619   if( !xmlWriter ) return;
00620   
00621   xmlWriter->startElement( "table:table-cell" );
00622   xmlWriter->addAttribute( "table:style-name", QString("ce%1").arg(cellFormatIndex) );  
00623   cellFormatIndex++;
00624   
00625   QString formula = string( cell->formula() ).string();
00626   if( !formula.isEmpty() )
00627     xmlWriter->addAttribute( "table:formula", formula.prepend("=") );
00628   
00629   Value value = cell->value();
00630   
00631   if( value.isBoolean() )
00632   {
00633     xmlWriter->addAttribute( "office:value-type", "boolean" );
00634     xmlWriter->addAttribute( "office:boolean-value", value.asBoolean() ? "true" : "false" );
00635   }
00636   else if( value.isFloat() || value.isInteger() )
00637   {
00638     QString valueFormat = string( cell->format().valueFormat() ).string();
00639     
00640     bool handled = false;
00641     
00642     if( isPercentageFormat( valueFormat ) )
00643     {
00644       handled = true;
00645       xmlWriter->addAttribute( "office:value-type", "percentage" );
00646       xmlWriter->addAttribute( "office:value", QString::number( value.asFloat(), 'g', 15 ) );
00647     }
00648     
00649     if( isDateFormat( valueFormat ) )
00650     {
00651       handled = true;
00652       QString dateValue = convertDate( value.asFloat() );
00653       xmlWriter->addAttribute( "office:value-type", "date" );
00654       xmlWriter->addAttribute( "office:date-value", dateValue );
00655     }
00656     
00657     if( isTimeFormat( valueFormat ) )
00658     {
00659       handled = true;
00660       QString timeValue = convertTime( value.asFloat() );
00661       xmlWriter->addAttribute( "office:value-type", "time" );
00662       xmlWriter->addAttribute( "office:time-value", timeValue );
00663     }
00664     
00665     // fallback
00666     if( !handled )
00667     {
00668       xmlWriter->addAttribute( "office:value-type", "float" );
00669       xmlWriter->addAttribute( "office:value", QString::number( value.asFloat(), 'g', 15 ) );
00670     }
00671   }
00672   else if( value.isString() )
00673   {
00674     QString str = string( value.asString() ).string();
00675     xmlWriter->addAttribute( "office:value-type", "string" );
00676     xmlWriter->addAttribute( "office:string-value", str );
00677     xmlWriter->startElement( "text:p" );
00678     xmlWriter->addTextNode( str );
00679     xmlWriter->endElement(); //  text:p 
00680   }
00681   
00682   // TODO: handle formula
00683   
00684   xmlWriter->endElement(); //  table:table-cell 
00685 }
00686 
00687 void ExcelImport::Private::processCellForStyle( Cell* cell, KoXmlWriter* xmlWriter )
00688 {
00689   if( !cell ) return;
00690   if( !xmlWriter ) return;
00691   
00692   // TODO optimize with hash table
00693   Format format = cell->format();
00694   
00695   // handle data format, e.g. number style
00696   QString refName;
00697   QString valueFormat = string( format.valueFormat() ).string();
00698   if( valueFormat != QString("General") )
00699   {
00700     refName = QString("N%1").arg(valueFormatIndex);
00701     valueFormatIndex++; 
00702     processValueFormat( valueFormat, refName, xmlWriter );
00703   }
00704 
00705   // now the real table-cell  
00706   xmlWriter->startElement( "style:style" );
00707   xmlWriter->addAttribute( "style:family", "table-cell" );  
00708   xmlWriter->addAttribute( "style:name", QString("ce%1").arg(cellFormatIndex) );  
00709   cellFormatIndex++;
00710   if( !refName.isEmpty() )
00711     xmlWriter->addAttribute( "style:data-style-name", refName );  
00712   
00713   processFormat( &format, xmlWriter );
00714   
00715   xmlWriter->endElement();  // style:style
00716 
00717 }
00718 
00719 QString convertColor( const Color& color )
00720 {
00721   char buf[8];
00722   sprintf( buf, "#%02x%02x%02x", color.red, color.green, color.blue );
00723   return QString( buf );
00724 }
00725 
00726 QString convertBorder( const Pen& pen )
00727 {
00728   if( pen.style == Pen::NoLine || pen.width == 0 ) return "none";
00729   
00730   QString result = QString::number( pen.width );
00731   result += "pt ";
00732   
00733   switch( pen.style )
00734   {
00735     case Pen::SolidLine: result += "solid "; break;
00736     case Pen::DashLine: result += "dashed "; break;
00737     case Pen::DotLine: result += "dotted "; break;
00738     case Pen::DashDotLine: result += "dot-dash "; break;
00739     case Pen::DashDotDotLine: result += "dot-dot-dash "; break;
00740   }
00741   
00742   return result + convertColor( pen.color );
00743 }
00744 
00745 void ExcelImport::Private::processFormat( Format* format, KoXmlWriter* xmlWriter )
00746 {
00747   if( !format ) return;
00748   if( !xmlWriter ) return;
00749   
00750   FormatFont font = format->font();
00751   FormatAlignment align = format->alignment();
00752   FormatBackground back = format->background();
00753   FormatBorders borders = format->borders();
00754   
00755   if( !font.isNull() )
00756   {
00757     xmlWriter->startElement( "style:text-properties" );
00758     
00759     if( font.bold() ) 
00760       xmlWriter->addAttribute( "fo:font-weight", "bold" );  
00761       
00762     if( font.italic() ) 
00763       xmlWriter->addAttribute( "fo:font-style", "italic" );  
00764       
00765     if( font.underline() )
00766     {
00767       xmlWriter->addAttribute( "style:text-underline-style", "solid" );  
00768       xmlWriter->addAttribute( "style:text-underline-width", "auto" );  
00769       xmlWriter->addAttribute( "style:text-underline-color", "font-color" );  
00770     }
00771     
00772     if( font.strikeout() )
00773       xmlWriter->addAttribute( "style:text-line-through-style", "solid" );  
00774   
00775     if( font.subscript() )
00776       xmlWriter->addAttribute( "style:text-position", "sub" );
00777   
00778     if( font.superscript() )
00779       xmlWriter->addAttribute( "style:text-position", "super" );
00780 
00781     if( !font.fontFamily().isEmpty() )
00782       xmlWriter->addAttribute( "style:font-name", string(font.fontFamily()).string() );
00783       
00784     xmlWriter->addAttribute( "fo:font-size", QString("%1pt").arg(font.fontSize()) );  
00785     
00786     xmlWriter->addAttribute( "fo:color", convertColor( font.color() ) );
00787     
00788     xmlWriter->endElement();  // style:text-properties
00789   }
00790   
00791   xmlWriter->startElement( "style:table-cell-properties" );
00792   if( !align.isNull() )
00793   {
00794     switch( align.alignY() ) {
00795       case Format::Top: xmlWriter->addAttribute( "style:vertical-align", "top" ); break;
00796       case Format::Middle: xmlWriter->addAttribute( "style:vertical-align", "middle" ); break;
00797       case Format::Bottom: xmlWriter->addAttribute( "style:vertical-align", "bottom" ); break;
00798     }
00799     
00800     xmlWriter->addAttribute( "fo:wrap-option", align.wrap() ? "wrap" : "no-wrap" );
00801     //TODO rotation
00802     //TODO stacked letters
00803   }
00804   
00805   if( !borders.isNull() )
00806   {
00807     xmlWriter->addAttribute( "fo:border-left", convertBorder( borders.leftBorder() ) );
00808     xmlWriter->addAttribute( "fo:border-right", convertBorder( borders.rightBorder() ) );
00809     xmlWriter->addAttribute( "fo:border-top", convertBorder( borders.topBorder() ) );
00810     xmlWriter->addAttribute( "fo:border-bottom", convertBorder( borders.bottomBorder() ) );
00811     //TODO diagonal 'borders'
00812   }
00813   
00814   if( !back.isNull() && back.pattern() != FormatBackground::EmptyPattern )
00815   {
00816     Color backColor = back.backgroundColor();
00817     if( back.pattern() == FormatBackground::SolidPattern )
00818       backColor = back.foregroundColor();
00819     
00820     xmlWriter->addAttribute( "fo:background-color", convertColor( backColor ) );
00821     
00822     //TODO patterns
00823   }
00824   xmlWriter->endElement(); // style:table-cell-properties
00825   
00826   xmlWriter->startElement( "style:paragraph-properties" );
00827   if( !align.isNull() )
00828   {
00829     switch( align.alignX() ) {
00830       case Format::Left: xmlWriter->addAttribute( "fo:text-align", "start" ); break;
00831       case Format::Center: xmlWriter->addAttribute( "fo:text-align", "center" ); break;
00832       case Format::Right: xmlWriter->addAttribute( "fo:text-align", "end" ); break;
00833     }
00834     
00835     if( align.indentLevel() != 0 )
00836       xmlWriter->addAttribute( "fo:margin-left", QString::number( align.indentLevel() ) + "0pt" );
00837   }
00838   xmlWriter->endElement(); // style:paragraph-properties
00839 }
00840 
00841 void ExcelImport::Private::processValueFormat( QString valueFormat, QString refName, 
00842 KoXmlWriter* xmlWriter )
00843 {
00844   /*int decimalPlaces = 2;
00845   int leadingZeroes = 1;
00846   int exponentDigits = -1;
00847   bool percentage = false;*/
00848 
00849   // TODO: someday we need a real MS Excel to OpenDocument format paraser
00850   // this just catches the most common format, not covers all possible cases
00851   
00852   if( valueFormat == "0")
00853   {
00854     xmlWriter->startElement( "number:number-style" );
00855     xmlWriter->addAttribute( "style:name", refName ); 
00856     xmlWriter->addAttribute( "style:family", "data-style" ); 
00857     xmlWriter->startElement( "number:number" );
00858     xmlWriter->addAttribute( "number:decimal-places", 0 ); 
00859     xmlWriter->addAttribute( "number:min-integer-digits", 1 ); 
00860     xmlWriter->endElement();  // number:number
00861     xmlWriter->endElement();  // number:number-style
00862   }
00863   else if( valueFormat == "0.0")
00864   {
00865     xmlWriter->startElement( "number:number-style" );
00866     xmlWriter->addAttribute( "style:name", refName ); 
00867     xmlWriter->addAttribute( "style:family", "data-style" ); 
00868     xmlWriter->startElement( "number:number" );
00869     xmlWriter->addAttribute( "number:decimal-places", 1 ); 
00870     xmlWriter->addAttribute( "number:min-integer-digits", 1 ); 
00871     xmlWriter->endElement();  // number:number
00872     xmlWriter->endElement();  // number:number-style
00873   }
00874   else if( valueFormat == "0.00")
00875   {
00876     xmlWriter->startElement( "number:number-style" );
00877     xmlWriter->addAttribute( "style:name", refName ); 
00878     xmlWriter->addAttribute( "style:family", "data-style" ); 
00879     xmlWriter->startElement( "number:number" );
00880     xmlWriter->addAttribute( "number:decimal-places", 2 ); 
00881     xmlWriter->addAttribute( "number:min-integer-digits", 1 ); 
00882     xmlWriter->endElement();  // number:number
00883     xmlWriter->endElement();  // number:number-style
00884   }
00885   else if( valueFormat == "0.000")
00886   {
00887     xmlWriter->startElement( "number:number-style" );
00888     xmlWriter->addAttribute( "style:name", refName ); 
00889     xmlWriter->addAttribute( "style:family", "data-style" ); 
00890     xmlWriter->startElement( "number:number" );
00891     xmlWriter->addAttribute( "number:decimal-places", 3 ); 
00892     xmlWriter->addAttribute( "number:min-integer-digits", 1 ); 
00893     xmlWriter->endElement();  // number:number
00894     xmlWriter->endElement();  // number:number-style
00895   }
00896   else if( valueFormat == "0.0000")
00897   {
00898     xmlWriter->startElement( "number:number-style" );
00899     xmlWriter->addAttribute( "style:name", refName ); 
00900     xmlWriter->addAttribute( "style:family", "data-style" ); 
00901     xmlWriter->startElement( "number:number" );
00902     xmlWriter->addAttribute( "number:decimal-places", 4 ); 
00903     xmlWriter->addAttribute( "number:min-integer-digits", 1 ); 
00904     xmlWriter->endElement();  // number:number
00905     xmlWriter->endElement();  // number:number-style
00906   }
00907   else if( valueFormat == "0.00000")
00908   {
00909     xmlWriter->startElement( "number:number-style" );
00910     xmlWriter->addAttribute( "style:name", refName ); 
00911     xmlWriter->addAttribute( "style:family", "data-style" ); 
00912     xmlWriter->startElement( "number:number" );
00913     xmlWriter->addAttribute( "number:decimal-places", 5 ); 
00914     xmlWriter->addAttribute( "number:min-integer-digits", 1 ); 
00915     xmlWriter->endElement();  // number:number
00916     xmlWriter->endElement();  // number:number-style
00917   }
00918   else if( valueFormat == "0.000000")
00919   {
00920     xmlWriter->startElement( "number:number-style" );
00921     xmlWriter->addAttribute( "style:name", refName ); 
00922     xmlWriter->addAttribute( "style:family", "data-style" ); 
00923     xmlWriter->startElement( "number:number" );
00924     xmlWriter->addAttribute( "number:decimal-places", 6 ); 
00925     xmlWriter->addAttribute( "number:min-integer-digits", 1 ); 
00926     xmlWriter->endElement();  // number:number
00927     xmlWriter->endElement();  // number:number-style
00928   }
00929   else if( valueFormat == "0.0000000")
00930   {
00931     xmlWriter->startElement( "number:number-style" );
00932     xmlWriter->addAttribute( "style:name", refName ); 
00933     xmlWriter->addAttribute( "style:family", "data-style" ); 
00934     xmlWriter->startElement( "number:number" );
00935     xmlWriter->addAttribute( "number:decimal-places", 7 ); 
00936     xmlWriter->addAttribute( "number:min-integer-digits", 1 ); 
00937     xmlWriter->endElement();  // number:number
00938     xmlWriter->endElement();  // number:number-style
00939   }
00940   else if( valueFormat == "0.00000000")
00941   {
00942     xmlWriter->startElement( "number:number-style" );
00943     xmlWriter->addAttribute( "style:name", refName ); 
00944     xmlWriter->addAttribute( "style:family", "data-style" ); 
00945     xmlWriter->startElement( "number:number" );
00946     xmlWriter->addAttribute( "number:decimal-places", 8 ); 
00947     xmlWriter->addAttribute( "number:min-integer-digits", 1 ); 
00948     xmlWriter->endElement();  // number:number
00949     xmlWriter->endElement();  // number:number-style
00950   }
00951   else if( valueFormat == "0.000000000")
00952   {
00953     xmlWriter->startElement( "number:number-style" );
00954     xmlWriter->addAttribute( "style:name", refName ); 
00955     xmlWriter->addAttribute( "style:family", "data-style" ); 
00956     xmlWriter->startElement( "number:number" );
00957     xmlWriter->addAttribute( "number:decimal-places", 9 ); 
00958     xmlWriter->addAttribute( "number:min-integer-digits", 1 ); 
00959     xmlWriter->endElement();  // number:number
00960     xmlWriter->endElement();  // number:number-style
00961   }
00962   else if( valueFormat == "0.0000000000")
00963   {
00964     xmlWriter->startElement( "number:number-style" );
00965     xmlWriter->addAttribute( "style:name", refName ); 
00966     xmlWriter->addAttribute( "style:family", "data-style" ); 
00967     xmlWriter->startElement( "number:number" );
00968     xmlWriter->addAttribute( "number:decimal-places", 10 ); 
00969     xmlWriter->addAttribute( "number:min-integer-digits", 1 ); 
00970     xmlWriter->endElement();  // number:number
00971     xmlWriter->endElement();  // number:number-style
00972   }
00973   else if( valueFormat == "0.00000000000")
00974   {
00975     xmlWriter->startElement( "number:number-style" );
00976     xmlWriter->addAttribute( "style:name", refName ); 
00977     xmlWriter->addAttribute( "style:family", "data-style" ); 
00978     xmlWriter->startElement( "number:number" );
00979     xmlWriter->addAttribute( "number:decimal-places", 11 ); 
00980     xmlWriter->addAttribute( "number:min-integer-digits", 1 ); 
00981     xmlWriter->endElement();  // number:number
00982     xmlWriter->endElement();  // number:number-style
00983   }
00984   else if( valueFormat == "0.000000000000")
00985   {
00986     xmlWriter->startElement( "number:number-style" );
00987     xmlWriter->addAttribute( "style:name", refName ); 
00988     xmlWriter->addAttribute( "style:family", "data-style" ); 
00989     xmlWriter->startElement( "number:number" );
00990     xmlWriter->addAttribute( "number:decimal-places", 12 ); 
00991     xmlWriter->addAttribute( "number:min-integer-digits", 1 ); 
00992     xmlWriter->endElement();  // number:number
00993     xmlWriter->endElement();  // number:number-style
00994   }
00995   else if( valueFormat == "0.0000000000000")
00996   {
00997     xmlWriter->startElement( "number:number-style" );
00998     xmlWriter->addAttribute( "style:name", refName ); 
00999     xmlWriter->addAttribute( "style:family", "data-style" ); 
01000     xmlWriter->startElement( "number:number" );
01001     xmlWriter->addAttribute( "number:decimal-places", 13 ); 
01002     xmlWriter->addAttribute( "number:min-integer-digits", 1 ); 
01003     xmlWriter->endElement();  // number:number
01004     xmlWriter->endElement();  // number:number-style
01005   }
01006   else if( valueFormat == "0.00000000000000")
01007   {
01008     xmlWriter->startElement( "number:number-style" );
01009     xmlWriter->addAttribute( "style:name", refName ); 
01010     xmlWriter->addAttribute( "style:family", "data-style" ); 
01011     xmlWriter->startElement( "number:number" );
01012     xmlWriter->addAttribute( "number:decimal-places", 14 ); 
01013     xmlWriter->addAttribute( "number:min-integer-digits", 1 ); 
01014     xmlWriter->endElement();  // number:number
01015     xmlWriter->endElement();  // number:number-style
01016   }
01017   else if( valueFormat == "0.000000000000000")
01018   {
01019     xmlWriter->startElement( "number:number-style" );
01020     xmlWriter->addAttribute( "style:name", refName ); 
01021     xmlWriter->addAttribute( "style:family", "data-style" ); 
01022     xmlWriter->startElement( "number:number" );
01023     xmlWriter->addAttribute( "number:decimal-places", 15 ); 
01024     xmlWriter->addAttribute( "number:min-integer-digits", 1 ); 
01025     xmlWriter->endElement();  // number:number
01026     xmlWriter->endElement();  // number:number-style
01027   }
01028   else if( valueFormat == "0.0000000000000000")
01029   {
01030     xmlWriter->startElement( "number:number-style" );
01031     xmlWriter->addAttribute( "style:name", refName ); 
01032     xmlWriter->addAttribute( "style:family", "data-style" ); 
01033     xmlWriter->startElement( "number:number" );
01034     xmlWriter->addAttribute( "number:decimal-places", 16 ); 
01035     xmlWriter->addAttribute( "number:min-integer-digits", 1 ); 
01036     xmlWriter->endElement();  // number:number
01037     xmlWriter->endElement();  // number:number-style
01038   }
01039   else if( valueFormat == "0E+00")
01040   {
01041     xmlWriter->startElement( "number:number-style" );
01042     xmlWriter->addAttribute( "style:name", refName ); 
01043     xmlWriter->addAttribute( "style:family", "data-style" ); 
01044     xmlWriter->startElement( "number:scientific-number" );
01045     xmlWriter->addAttribute( "number:decimal-places", 0 ); 
01046     xmlWriter->addAttribute( "number:min-integer-digits", 1 ); 
01047     xmlWriter->addAttribute( "number:min-exponent-digits", 2 ); 
01048     xmlWriter->endElement();  // number:scientific-number
01049     xmlWriter->endElement();  // number:number-style
01050   }
01051   else if( valueFormat == "0.0E+00")
01052   {
01053     xmlWriter->startElement( "number:number-style" );
01054     xmlWriter->addAttribute( "style:name", refName ); 
01055     xmlWriter->addAttribute( "style:family", "data-style" ); 
01056     xmlWriter->startElement( "number:scientific-number" );
01057     xmlWriter->addAttribute( "number:decimal-places", 1 ); 
01058     xmlWriter->addAttribute( "number:min-integer-digits", 1 ); 
01059     xmlWriter->addAttribute( "number:min-exponent-digits", 2 ); 
01060     xmlWriter->endElement();  // number:scientific-number
01061     xmlWriter->endElement();  // number:number-style
01062   }
01063   else if( valueFormat == "0.00E+00")
01064   {
01065     xmlWriter->startElement( "number:number-style" );
01066     xmlWriter->addAttribute( "style:name", refName ); 
01067     xmlWriter->addAttribute( "style:family", "data-style" ); 
01068     xmlWriter->startElement( "number:scientific-number" );
01069     xmlWriter->addAttribute( "number:decimal-places", 2 ); 
01070     xmlWriter->addAttribute( "number:min-integer-digits", 1 ); 
01071     xmlWriter->addAttribute( "number:min-exponent-digits", 2 ); 
01072     xmlWriter->endElement();  // number:scientific-number
01073     xmlWriter->endElement();  // number:number-style
01074   }
01075   else if( valueFormat == "0.000E+00")
01076   {
01077     xmlWriter->startElement( "number:number-style" );
01078     xmlWriter->addAttribute( "style:name", refName ); 
01079     xmlWriter->addAttribute( "style:family", "data-style" ); 
01080     xmlWriter->startElement( "number:scientific-number" );
01081     xmlWriter->addAttribute( "number:decimal-places", 3 ); 
01082     xmlWriter->addAttribute( "number:min-integer-digits", 1 ); 
01083     xmlWriter->addAttribute( "number:min-exponent-digits", 2 ); 
01084     xmlWriter->endElement();  // number:scientific-number
01085     xmlWriter->endElement();  // number:number-style
01086   }
01087   else if( valueFormat == "0.0000E+00")
01088   {
01089     xmlWriter->startElement( "number:number-style" );
01090     xmlWriter->addAttribute( "style:name", refName ); 
01091     xmlWriter->addAttribute( "style:family", "data-style" ); 
01092     xmlWriter->startElement( "number:scientific-number" );
01093     xmlWriter->addAttribute( "number:decimal-places", 4 ); 
01094     xmlWriter->addAttribute( "number:min-integer-digits", 1 ); 
01095     xmlWriter->addAttribute( "number:min-exponent-digits", 2 ); 
01096     xmlWriter->endElement();  // number:scientific-number
01097     xmlWriter->endElement();  // number:number-style
01098   }
01099   else if( valueFormat == "0.00000E+00")
01100   {
01101     xmlWriter->startElement( "number:number-style" );
01102     xmlWriter->addAttribute( "style:name", refName ); 
01103     xmlWriter->addAttribute( "style:family", "data-style" ); 
01104     xmlWriter->startElement( "number:scientific-number" );
01105     xmlWriter->addAttribute( "number:decimal-places", 5 ); 
01106     xmlWriter->addAttribute( "number:min-integer-digits", 1 ); 
01107     xmlWriter->addAttribute( "number:min-exponent-digits", 2 ); 
01108     xmlWriter->endElement();  // number:scientific-number
01109     xmlWriter->endElement();  // number:number-style
01110   }
01111   else if( valueFormat == "0.000000E+00")
01112   {
01113     xmlWriter->startElement( "number:number-style" );
01114     xmlWriter->addAttribute( "style:name", refName ); 
01115     xmlWriter->addAttribute( "style:family", "data-style" ); 
01116     xmlWriter->startElement( "number:scientific-number" );
01117     xmlWriter->addAttribute( "number:decimal-places", 6 ); 
01118     xmlWriter->addAttribute( "number:min-integer-digits", 1 ); 
01119     xmlWriter->addAttribute( "number:min-exponent-digits", 2 ); 
01120     xmlWriter->endElement();  // number:scientific-number
01121     xmlWriter->endElement();  // number:number-style
01122   }
01123   else if( valueFormat == "0.0000000E+00")
01124   {
01125     xmlWriter->startElement( "number:number-style" );
01126     xmlWriter->addAttribute( "style:name", refName ); 
01127     xmlWriter->addAttribute( "style:family", "data-style" ); 
01128     xmlWriter->startElement( "number:scientific-number" );
01129     xmlWriter->addAttribute( "number:decimal-places", 7 ); 
01130     xmlWriter->addAttribute( "number:min-integer-digits", 1 ); 
01131     xmlWriter->addAttribute( "number:min-exponent-digits", 2 ); 
01132     xmlWriter->endElement();  // number:scientific-number
01133     xmlWriter->endElement();  // number:number-style
01134   }
01135   else if( valueFormat == "0.00000000E+00")
01136   {
01137     xmlWriter->startElement( "number:number-style" );
01138     xmlWriter->addAttribute( "style:name", refName ); 
01139     xmlWriter->addAttribute( "style:family", "data-style" ); 
01140     xmlWriter->startElement( "number:scientific-number" );
01141     xmlWriter->addAttribute( "number:decimal-places", 8 ); 
01142     xmlWriter->addAttribute( "number:min-integer-digits", 1 ); 
01143     xmlWriter->addAttribute( "number:min-exponent-digits", 2 ); 
01144     xmlWriter->endElement();  // number:scientific-number
01145     xmlWriter->endElement();  // number:number-style
01146   }
01147   else if( valueFormat == "0.000000000E+00")
01148   {
01149     xmlWriter->startElement( "number:number-style" );
01150     xmlWriter->addAttribute( "style:name", refName ); 
01151     xmlWriter->addAttribute( "style:family", "data-style" ); 
01152     xmlWriter->startElement( "number:scientific-number" );
01153     xmlWriter->addAttribute( "number:decimal-places", 9 ); 
01154     xmlWriter->addAttribute( "number:min-integer-digits", 1 ); 
01155     xmlWriter->addAttribute( "number:min-exponent-digits", 2 ); 
01156     xmlWriter->endElement();  // number:scientific-number
01157     xmlWriter->endElement();  // number:number-style
01158   }
01159   else if( valueFormat == "0.0000000000E+00")
01160   {
01161     xmlWriter->startElement( "number:number-style" );
01162     xmlWriter->addAttribute( "style:name", refName ); 
01163     xmlWriter->addAttribute( "style:family", "data-style" ); 
01164     xmlWriter->startElement( "number:scientific-number" );
01165     xmlWriter->addAttribute( "number:decimal-places", 10 ); 
01166     xmlWriter->addAttribute( "number:min-integer-digits", 1 ); 
01167     xmlWriter->addAttribute( "number:min-exponent-digits", 2 ); 
01168     xmlWriter->endElement();  // number:scientific-number
01169     xmlWriter->endElement();  // number:number-style
01170   }
01171   else if( valueFormat == "0.00000000000E+00")
01172   {
01173     xmlWriter->startElement( "number:number-style" );
01174     xmlWriter->addAttribute( "style:name", refName ); 
01175     xmlWriter->addAttribute( "style:family", "data-style" ); 
01176     xmlWriter->startElement( "number:scientific-number" );
01177     xmlWriter->addAttribute( "number:decimal-places", 11 ); 
01178     xmlWriter->addAttribute( "number:min-integer-digits", 1 ); 
01179     xmlWriter->addAttribute( "number:min-exponent-digits", 2 ); 
01180     xmlWriter->endElement();  // number:scientific-number
01181     xmlWriter->endElement();  // number:number-style
01182   }
01183   else if( valueFormat == "0.000000000000E+00")
01184   {
01185     xmlWriter->startElement( "number:number-style" );
01186     xmlWriter->addAttribute( "style:name", refName ); 
01187     xmlWriter->addAttribute( "style:family", "data-style" ); 
01188     xmlWriter->startElement( "number:scientific-number" );
01189     xmlWriter->addAttribute( "number:decimal-places", 12 ); 
01190     xmlWriter->addAttribute( "number:min-integer-digits", 1 ); 
01191     xmlWriter->addAttribute( "number:min-exponent-digits", 2 ); 
01192     xmlWriter->endElement();  // number:scientific-number
01193     xmlWriter->endElement();  // number:number-style
01194   }
01195   else if( valueFormat == "0.0000000000000E+00")
01196   {
01197     xmlWriter->startElement( "number:number-style" );
01198     xmlWriter->addAttribute( "style:name", refName ); 
01199     xmlWriter->addAttribute( "style:family", "data-style" ); 
01200     xmlWriter->startElement( "number:scientific-number" );
01201     xmlWriter->addAttribute( "number:decimal-places", 13 ); 
01202     xmlWriter->addAttribute( "number:min-integer-digits", 1 ); 
01203     xmlWriter->addAttribute( "number:min-exponent-digits", 2 ); 
01204     xmlWriter->endElement();  // number:scientific-number
01205     xmlWriter->endElement();  // number:number-style
01206   }
01207   else if( valueFormat == "0.00000000000000E+00")
01208   {
01209     xmlWriter->startElement( "number:number-style" );
01210     xmlWriter->addAttribute( "style:name", refName ); 
01211     xmlWriter->addAttribute( "style:family", "data-style" ); 
01212     xmlWriter->startElement( "number:scientific-number" );
01213     xmlWriter->addAttribute( "number:decimal-places", 14 ); 
01214     xmlWriter->addAttribute( "number:min-integer-digits", 1 ); 
01215     xmlWriter->addAttribute( "number:min-exponent-digits", 2 ); 
01216     xmlWriter->endElement();  // number:scientific-number
01217     xmlWriter->endElement();  // number:number-style
01218   }
01219   else if( valueFormat == "0.000000000000000E+00")
01220   {
01221     xmlWriter->startElement( "number:number-style" );
01222     xmlWriter->addAttribute( "style:name", refName ); 
01223     xmlWriter->addAttribute( "style:family", "data-style" ); 
01224     xmlWriter->startElement( "number:scientific-number" );
01225     xmlWriter->addAttribute( "number:decimal-places", 16 ); 
01226     xmlWriter->addAttribute( "number:min-integer-digits", 1 ); 
01227     xmlWriter->addAttribute( "number:min-exponent-digits", 2 ); 
01228     xmlWriter->endElement();  // number:scientific-number
01229     xmlWriter->endElement();  // number:number-style
01230   }
01231   else if( valueFormat == "0.0000000000000000E+00")
01232   {
01233     xmlWriter->startElement( "number:number-style" );
01234     xmlWriter->addAttribute( "style:name", refName ); 
01235     xmlWriter->addAttribute( "style:family", "data-style" ); 
01236     xmlWriter->startElement( "number:scientific-number" );
01237     xmlWriter->addAttribute( "number:decimal-places", 17 ); 
01238     xmlWriter->addAttribute( "number:min-integer-digits", 1 ); 
01239     xmlWriter->addAttribute( "number:min-exponent-digits", 2 ); 
01240     xmlWriter->endElement();  // number:scientific-number
01241     xmlWriter->endElement();  // number:number-style
01242   }
01243   else if( valueFormat == "0%")
01244   {
01245     xmlWriter->startElement( "number:percentage-style" );
01246     xmlWriter->addAttribute( "style:name", refName ); 
01247     xmlWriter->startElement( "number:number" );
01248     xmlWriter->addAttribute( "number:decimal-places", 0 ); 
01249     xmlWriter->addAttribute( "number:min-integer-digits", 1 ); 
01250     xmlWriter->endElement();  // number:number
01251     xmlWriter->startElement( "number:text" );
01252     xmlWriter->addTextNode( "%" );
01253     xmlWriter->endElement();  // number:text
01254     xmlWriter->endElement();  // number:percentage-style
01255   }
01256   else if( valueFormat == "0.0%")
01257   {
01258     xmlWriter->startElement( "number:percentage-style" );
01259     xmlWriter->addAttribute( "style:name", refName ); 
01260     xmlWriter->startElement( "number:number" );
01261     xmlWriter->addAttribute( "number:decimal-places", 1 ); 
01262     xmlWriter->addAttribute( "number:min-integer-digits", 1 ); 
01263     xmlWriter->endElement();  // number:number
01264     xmlWriter->startElement( "number:text" );
01265     xmlWriter->addTextNode( "%" );
01266     xmlWriter->endElement();  // number:text
01267     xmlWriter->endElement();  // number:percentage-style
01268   }
01269   else if( valueFormat == "0.00%")
01270   {
01271     xmlWriter->startElement( "number:percentage-style" );
01272     xmlWriter->addAttribute( "style:name", refName ); 
01273     xmlWriter->startElement( "number:number" );
01274     xmlWriter->addAttribute( "number:decimal-places", 2 ); 
01275     xmlWriter->addAttribute( "number:min-integer-digits", 1 ); 
01276     xmlWriter->endElement();  // number:number
01277     xmlWriter->startElement( "number:text" );
01278     xmlWriter->addTextNode( "%" );
01279     xmlWriter->endElement();  // number:text
01280     xmlWriter->endElement();  // number:percentage-style
01281   }
01282   else if( valueFormat == "0.000%")
01283   {
01284     xmlWriter->startElement( "number:percentage-style" );
01285     xmlWriter->addAttribute( "style:name", refName ); 
01286     xmlWriter->startElement( "number:number" );
01287     xmlWriter->addAttribute( "number:decimal-places", 3 ); 
01288     xmlWriter->addAttribute( "number:min-integer-digits", 1 ); 
01289     xmlWriter->endElement();  // number:number
01290     xmlWriter->startElement( "number:text" );
01291     xmlWriter->addTextNode( "%" );
01292     xmlWriter->endElement();  // number:text
01293     xmlWriter->endElement();  // number:percentage-style
01294   }
01295   else if( valueFormat == "0.0000%")
01296   {
01297     xmlWriter->startElement( "number:percentage-style" );
01298     xmlWriter->addAttribute( "style:name", refName ); 
01299     xmlWriter->startElement( "number:number" );
01300     xmlWriter->addAttribute( "number:decimal-places", 4 ); 
01301     xmlWriter->addAttribute( "number:min-integer-digits", 1 ); 
01302     xmlWriter->endElement();  // number:number
01303     xmlWriter->startElement( "number:text" );
01304     xmlWriter->addTextNode( "%" );
01305     xmlWriter->endElement();  // number:text
01306     xmlWriter->endElement();  // number:percentage-style
01307   }
01308   else if( valueFormat == "0.00000%")
01309   {
01310     xmlWriter->startElement( "number:percentage-style" );
01311     xmlWriter->addAttribute( "style:name", refName ); 
01312     xmlWriter->startElement( "number:number" );
01313     xmlWriter->addAttribute( "number:decimal-places", 5 ); 
01314     xmlWriter->addAttribute( "number:min-integer-digits", 1 ); 
01315     xmlWriter->endElement();  // number:number
01316     xmlWriter->startElement( "number:text" );
01317     xmlWriter->addTextNode( "%" );
01318     xmlWriter->endElement();  // number:text
01319     xmlWriter->endElement();  // number:percentage-style
01320   }
01321   else if( valueFormat == "0.000000%")
01322   {
01323     xmlWriter->startElement( "number:percentage-style" );
01324     xmlWriter->addAttribute( "style:name", refName ); 
01325     xmlWriter->startElement( "number:number" );
01326     xmlWriter->addAttribute( "number:decimal-places", 6 ); 
01327     xmlWriter->addAttribute( "number:min-integer-digits", 1 ); 
01328     xmlWriter->endElement();  // number:number
01329     xmlWriter->startElement( "number:text" );
01330     xmlWriter->addTextNode( "%" );
01331     xmlWriter->endElement();  // number:text
01332     xmlWriter->endElement();  // number:percentage-style
01333   }
01334   else if( valueFormat == "0.0000000%")
01335   {
01336     xmlWriter->startElement( "number:percentage-style" );
01337     xmlWriter->addAttribute( "style:name", refName ); 
01338     xmlWriter->startElement( "number:number" );
01339     xmlWriter->addAttribute( "number:decimal-places", 7 ); 
01340     xmlWriter->addAttribute( "number:min-integer-digits", 1 ); 
01341     xmlWriter->endElement();  // number:number
01342     xmlWriter->startElement( "number:text" );
01343     xmlWriter->addTextNode( "%" );
01344     xmlWriter->endElement();  // number:text
01345     xmlWriter->endElement();  // number:percentage-style
01346   }
01347   else if( valueFormat == "0.00000000%")
01348   {
01349     xmlWriter->startElement( "number:percentage-style" );
01350     xmlWriter->addAttribute( "style:name", refName ); 
01351     xmlWriter->startElement( "number:number" );
01352     xmlWriter->addAttribute( "number:decimal-places", 8 ); 
01353     xmlWriter->addAttribute( "number:min-integer-digits", 1 ); 
01354     xmlWriter->endElement();  // number:number
01355     xmlWriter->startElement( "number:text" );
01356     xmlWriter->addTextNode( "%" );
01357     xmlWriter->endElement();  // number:text
01358     xmlWriter->endElement();  // number:percentage-style
01359   }
01360   else if( valueFormat == "0.000000000%")
01361   {
01362     xmlWriter->startElement( "number:percentage-style" );
01363     xmlWriter->addAttribute( "style:name", refName ); 
01364     xmlWriter->startElement( "number:number" );
01365     xmlWriter->addAttribute( "number:decimal-places", 9 ); 
01366     xmlWriter->addAttribute( "number:min-integer-digits", 1 ); 
01367     xmlWriter->endElement();  // number:number
01368     xmlWriter->startElement( "number:text" );
01369     xmlWriter->addTextNode( "%" );
01370     xmlWriter->endElement();  // number:text
01371     xmlWriter->endElement();  // number:percentage-style
01372   }
01373   else if( valueFormat == "0.0000000000%")
01374   {
01375     xmlWriter->startElement( "number:percentage-style" );
01376     xmlWriter->addAttribute( "style:name", refName ); 
01377     xmlWriter->startElement( "number:number" );
01378     xmlWriter->addAttribute( "number:decimal-places", 10 ); 
01379     xmlWriter->addAttribute( "number:min-integer-digits", 1 ); 
01380     xmlWriter->endElement();  // number:number
01381     xmlWriter->startElement( "number:text" );
01382     xmlWriter->addTextNode( "%" );
01383     xmlWriter->endElement();  // number:text
01384     xmlWriter->endElement();  // number:percentage-style
01385   }
01386   else if( valueFormat == "0.00000000000%")
01387   {
01388     xmlWriter->startElement( "number:percentage-style" );
01389     xmlWriter->addAttribute( "style:name", refName ); 
01390     xmlWriter->startElement( "number:number" );
01391     xmlWriter->addAttribute( "number:decimal-places", 11 ); 
01392     xmlWriter->addAttribute( "number:min-integer-digits", 1 ); 
01393     xmlWriter->endElement();  // number:number
01394     xmlWriter->startElement( "number:text" );
01395     xmlWriter->addTextNode( "%" );
01396     xmlWriter->endElement();  // number:text
01397     xmlWriter->endElement();  // number:percentage-style
01398   }
01399   else if( valueFormat == "0.000000000000%")
01400   {
01401     xmlWriter->startElement( "number:percentage-style" );
01402     xmlWriter->addAttribute( "style:name", refName ); 
01403     xmlWriter->startElement( "number:number" );
01404     xmlWriter->addAttribute( "number:decimal-places", 12 ); 
01405     xmlWriter->addAttribute( "number:min-integer-digits", 1 ); 
01406     xmlWriter->endElement();  // number:number
01407     xmlWriter->startElement( "number:text" );
01408     xmlWriter->addTextNode( "%" );
01409     xmlWriter->endElement();  // number:text
01410     xmlWriter->endElement();  // number:percentage-style
01411   }
01412   else if( valueFormat == "0.0000000000000%")
01413   {
01414     xmlWriter->startElement( "number:percentage-style" );
01415     xmlWriter->addAttribute( "style:name", refName ); 
01416     xmlWriter->startElement( "number:number" );
01417     xmlWriter->addAttribute( "number:decimal-places", 13 ); 
01418     xmlWriter->addAttribute( "number:min-integer-digits", 1 ); 
01419     xmlWriter->endElement();  // number:number
01420     xmlWriter->startElement( "number:text" );
01421     xmlWriter->addTextNode( "%" );
01422     xmlWriter->endElement();  // number:text
01423     xmlWriter->endElement();  // number:percentage-style
01424   }
01425   else if( valueFormat == "0.00000000000000%")
01426   {
01427     xmlWriter->startElement( "number:percentage-style" );
01428     xmlWriter->addAttribute( "style:name", refName ); 
01429     xmlWriter->startElement( "number:number" );
01430     xmlWriter->addAttribute( "number:decimal-places", 14 ); 
01431     xmlWriter->addAttribute( "number:min-integer-digits", 1 ); 
01432     xmlWriter->endElement();  // number:number
01433     xmlWriter->startElement( "number:text" );
01434     xmlWriter->addTextNode( "%" );
01435     xmlWriter->endElement();  // number:text
01436     xmlWriter->endElement();  // number:percentage-style
01437   }
01438   else if( valueFormat == "0.000000000000000%")
01439   {
01440     xmlWriter->startElement( "number:percentage-style" );
01441     xmlWriter->addAttribute( "style:name", refName ); 
01442     xmlWriter->startElement( "number:number" );
01443     xmlWriter->addAttribute( "number:decimal-places", 15 ); 
01444     xmlWriter->addAttribute( "number:min-integer-digits", 1 ); 
01445     xmlWriter->endElement();  // number:number
01446     xmlWriter->startElement( "number:text" );
01447     xmlWriter->addTextNode( "%" );
01448     xmlWriter->endElement();  // number:text
01449     xmlWriter->endElement();  // number:percentage-style
01450   }
01451   else if( valueFormat == "0.0000000000000000%")
01452   {
01453     xmlWriter->startElement( "number:percentage-style" );
01454     xmlWriter->addAttribute( "style:name", refName ); 
01455     xmlWriter->startElement( "number:number" );
01456     xmlWriter->addAttribute( "number:decimal-places", 16 ); 
01457     xmlWriter->addAttribute( "number:min-integer-digits", 1 ); 
01458     xmlWriter->endElement();  // number:number
01459     xmlWriter->startElement( "number:text" );
01460     xmlWriter->addTextNode( "%" );
01461     xmlWriter->endElement();  // number:text
01462     xmlWriter->endElement();  // number:percentage-style
01463   }
01464   else if( valueFormat.lower() == "m/d/yy")
01465   {
01466     xmlWriter->startElement( "number:date-style" );
01467     xmlWriter->addAttribute( "style:name", refName ); 
01468     xmlWriter->addAttribute( "style:family", "data-style" ); 
01469     
01470     xmlWriter->startElement( "number:month" );
01471     xmlWriter->addAttribute( "number:textual", "false" ); 
01472     xmlWriter->addAttribute( "number:style", "short" ); 
01473     xmlWriter->endElement();  // number:month
01474     
01475     xmlWriter->startElement( "number:text");
01476     xmlWriter->addTextNode( "/" );
01477     xmlWriter->endElement();  // number:text
01478     
01479     xmlWriter->startElement( "number:day" );
01480     xmlWriter->addAttribute( "number:style", "short" ); 
01481     xmlWriter->endElement();  // number:day
01482     
01483     xmlWriter->startElement( "number:text");
01484     xmlWriter->addTextNode( "/" );
01485     xmlWriter->endElement();  // number:text
01486     
01487     xmlWriter->startElement( "number:year" );
01488     xmlWriter->addAttribute( "number:style", "short" ); 
01489     xmlWriter->endElement();  // number:year
01490     
01491     xmlWriter->endElement();  // number:date-style
01492   }
01493   else if( valueFormat.lower() == "m/d/yyyy")
01494   {
01495     xmlWriter->startElement( "number:date-style" );
01496     xmlWriter->addAttribute( "style:name", refName ); 
01497     xmlWriter->addAttribute( "style:family", "data-style" ); 
01498     
01499     xmlWriter->startElement( "number:month" );
01500     xmlWriter->addAttribute( "number:textual", "false" ); 
01501     xmlWriter->addAttribute( "number:style", "short" ); 
01502     xmlWriter->endElement();  // number:month
01503     
01504     xmlWriter->startElement( "number:text");
01505     xmlWriter->addTextNode( "/" );
01506     xmlWriter->endElement();  // number:text
01507     
01508     xmlWriter->startElement( "number:day" );
01509     xmlWriter->addAttribute( "number:style", "short" ); 
01510     xmlWriter->endElement();  // number:day
01511     
01512     xmlWriter->startElement( "number:text");
01513     xmlWriter->addTextNode( "/" );
01514     xmlWriter->endElement();  // number:text
01515     
01516     xmlWriter->startElement( "number:year" );
01517     xmlWriter->addAttribute( "number:style", "long" ); 
01518     xmlWriter->endElement();  // number:year
01519     
01520     xmlWriter->endElement();  // number:date-style
01521   }
01522   else if( (valueFormat.lower() == "d-mmm-yy") || (valueFormat.lower() == "d\\-mmm\\-yy") )
01523   {
01524     xmlWriter->startElement( "number:date-style" );
01525     xmlWriter->addAttribute( "style:name", refName ); 
01526     xmlWriter->addAttribute( "style:family", "data-style" ); 
01527     
01528     xmlWriter->startElement( "number:day" );
01529     xmlWriter->addAttribute( "number:style", "short" ); 
01530     xmlWriter->endElement();  // number:day
01531     
01532     xmlWriter->startElement( "number:text");
01533     xmlWriter->addTextNode( "-" );
01534     xmlWriter->endElement();  // number:text
01535     
01536     xmlWriter->startElement( "number:month" );
01537     xmlWriter->addAttribute( "number:textual", "true" ); 
01538     xmlWriter->addAttribute( "number:style", "short" ); 
01539     xmlWriter->endElement();  // number:month
01540     
01541     xmlWriter->startElement( "number:text");
01542     xmlWriter->addTextNode( "-" );
01543     xmlWriter->endElement();  // number:text
01544     
01545     xmlWriter->startElement( "number:year" );
01546     xmlWriter->addAttribute( "number:style", "short" ); 
01547     xmlWriter->endElement();  // number:year
01548     
01549     xmlWriter->endElement();  // number:date-style
01550   }
01551   else if( (valueFormat.lower() == "d-mmm-yyyy") || (valueFormat.lower() == "d\\-mmm\\-yyyy") )
01552   {
01553     xmlWriter->startElement( "number:date-style" );
01554     xmlWriter->addAttribute( "style:name", refName ); 
01555     xmlWriter->addAttribute( "style:family", "data-style" ); 
01556     
01557     xmlWriter->startElement( "number:day" );
01558     xmlWriter->addAttribute( "number:style", "short" ); 
01559     xmlWriter->endElement();  // number:day
01560     
01561     xmlWriter->startElement( "number:text");
01562     xmlWriter->addTextNode( "-" );
01563     xmlWriter->endElement();  // number:text
01564     
01565     xmlWriter->startElement( "number:month" );
01566     xmlWriter->addAttribute( "number:textual", "true" ); 
01567     xmlWriter->addAttribute( "number:style", "short" ); 
01568     xmlWriter->endElement();  // number:month
01569     
01570     xmlWriter->startElement( "number:text");
01571     xmlWriter->addTextNode( "-" );
01572     xmlWriter->endElement();  // number:text
01573     
01574     xmlWriter->startElement( "number:year" );
01575     xmlWriter->addAttribute( "number:style", "long" ); 
01576     xmlWriter->endElement();  // number:year
01577     
01578     xmlWriter->endElement();  // number:date-style
01579   }
01580   else if( (valueFormat.lower() == "d-mmm") || (valueFormat.lower() == "d\\-mmm") )
01581   {
01582     xmlWriter->startElement( "number:date-style" );
01583     xmlWriter->addAttribute( "style:name", refName ); 
01584     xmlWriter->addAttribute( "style:family", "data-style" ); 
01585     
01586     xmlWriter->startElement( "number:day" );
01587     xmlWriter->addAttribute( "number:style", "short" ); 
01588     xmlWriter->endElement();  // number:day
01589     
01590     xmlWriter->startElement( "number:text");
01591     xmlWriter->addTextNode( "-" );
01592     xmlWriter->endElement();  // number:text
01593     
01594     xmlWriter->startElement( "number:month" );
01595     xmlWriter->addAttribute( "number:textual", "true" ); 
01596     xmlWriter->addAttribute( "number:style", "short" ); 
01597     xmlWriter->endElement();  // number:month
01598   
01599     xmlWriter->endElement();  // number:date-style
01600   }
01601   else if( (valueFormat.lower() == "d-mm") || (valueFormat.lower() == "d\\-mm") )
01602   {
01603     xmlWriter->startElement( "number:date-style" );
01604     xmlWriter->addAttribute( "style:name", refName ); 
01605     xmlWriter->addAttribute( "style:family", "data-style" ); 
01606     
01607     xmlWriter->startElement( "number:day" );
01608     xmlWriter->addAttribute( "number:style", "short" ); 
01609     xmlWriter->endElement();  // number:day
01610     
01611     xmlWriter->startElement( "number:text");
01612     xmlWriter->addTextNode( "-" );
01613     xmlWriter->endElement();  // number:text
01614     
01615     xmlWriter->startElement( "number:month" );
01616     xmlWriter->addAttribute( "number:textual", "false" ); 
01617     xmlWriter->addAttribute( "number:style", "long" ); 
01618     xmlWriter->endElement();  // number:month
01619   
01620     xmlWriter->endElement();  // number:date-style
01621   }
01622   else if( valueFormat.lower() == "mmm/d" )
01623   {
01624     xmlWriter->startElement( "number:date-style" );
01625     xmlWriter->addAttribute( "style:name", refName ); 
01626     xmlWriter->addAttribute( "style:family", "data-style" ); 
01627     
01628     xmlWriter->startElement( "number:month" );
01629     xmlWriter->addAttribute( "number:textual", "true" ); 
01630     xmlWriter->addAttribute( "number:style", "short" ); 
01631     xmlWriter->endElement();  // number:month
01632   
01633     xmlWriter->startElement( "number:text");
01634     xmlWriter->addTextNode( "/" );
01635     xmlWriter->endElement();  // number:text
01636     
01637     xmlWriter->startElement( "number:day" );
01638     xmlWriter->addAttribute( "number:style", "short" ); 
01639     xmlWriter->endElement();  // number:day
01640     
01641     xmlWriter->endElement();  // number:date-style
01642   }
01643   else if( valueFormat.lower() == "mmm/dd" )
01644   {
01645     xmlWriter->startElement( "number:date-style" );
01646     xmlWriter->addAttribute( "style:name", refName ); 
01647     xmlWriter->addAttribute( "style:family", "data-style" ); 
01648     
01649     xmlWriter->startElement( "number:month" );
01650     xmlWriter->addAttribute( "number:textual", "true" ); 
01651     xmlWriter->addAttribute( "number:style", "short" ); 
01652     xmlWriter->endElement();  // number:month
01653   
01654     xmlWriter->startElement( "number:text");
01655     xmlWriter->addTextNode( "/" );
01656     xmlWriter->endElement();  // number:text
01657     
01658     xmlWriter->startElement( "number:day" );
01659     xmlWriter->addAttribute( "number:style", "long" ); 
01660     xmlWriter->endElement();  // number:day
01661     
01662     xmlWriter->endElement();  // number:date-style
01663   }
01664   else if( valueFormat.lower() == "mm/d" )
01665   {
01666     xmlWriter->startElement( "number:date-style" );
01667     xmlWriter->addAttribute( "style:name", refName ); 
01668     xmlWriter->addAttribute( "style:family", "data-style" ); 
01669     
01670     xmlWriter->startElement( "number:month" );
01671     xmlWriter->addAttribute( "number:textual", "false" ); 
01672     xmlWriter->addAttribute( "number:style", "long" ); 
01673     xmlWriter->endElement();  // number:month
01674   
01675     xmlWriter->startElement( "number:text");
01676     xmlWriter->addTextNode( "/" );
01677     xmlWriter->endElement();  // number:text
01678     
01679     xmlWriter->startElement( "number:day" );
01680     xmlWriter->addAttribute( "number:style", "short" ); 
01681     xmlWriter->endElement();  // number:day
01682     
01683     xmlWriter->endElement();  // number:date-style
01684   }
01685   else if( valueFormat.lower() == "mm/dd" )
01686   {
01687     xmlWriter->startElement( "number:date-style" );
01688     xmlWriter->addAttribute( "style:name", refName ); 
01689     xmlWriter->addAttribute( "style:family", "data-style" ); 
01690     
01691     xmlWriter->startElement( "number:month" );
01692     xmlWriter->addAttribute( "number:textual", "false" ); 
01693     xmlWriter->addAttribute( "number:style", "long" ); 
01694     xmlWriter->endElement();  // number:month
01695   
01696     xmlWriter->startElement( "number:text");
01697     xmlWriter->addTextNode( "/" );
01698     xmlWriter->endElement();  // number:text
01699     
01700     xmlWriter->startElement( "number:day" );
01701     xmlWriter->addAttribute( "number:style", "long" ); 
01702     xmlWriter->endElement();  // number:day
01703     
01704     xmlWriter->endElement();  // number:date-style
01705   }
01706   else if( valueFormat.lower() == "mm/dd/yy" )
01707   {
01708     xmlWriter->startElement( "number:date-style" );
01709     xmlWriter->addAttribute( "style:name", refName ); 
01710     xmlWriter->addAttribute( "style:family", "data-style" ); 
01711     
01712     xmlWriter->startElement( "number:month" );
01713     xmlWriter->addAttribute( "number:textual", "false" ); 
01714     xmlWriter->addAttribute( "number:style", "long" ); 
01715     xmlWriter->endElement();  // number:month
01716   
01717     xmlWriter->startElement( "number:text");
01718     xmlWriter->addTextNode( "/" );
01719     xmlWriter->endElement();  // number:text
01720     
01721     xmlWriter->startElement( "number:day" );
01722     xmlWriter->addAttribute( "number:style", "long" ); 
01723     xmlWriter->endElement();  // number:day
01724     
01725     xmlWriter->startElement( "number:text");
01726     xmlWriter->addTextNode( "/" );
01727     xmlWriter->endElement();  // number:text
01728     
01729     xmlWriter->startElement( "number:year" );
01730     xmlWriter->addAttribute( "number:style", "short" ); 
01731     xmlWriter->endElement();  // number:year
01732    
01733     xmlWriter->endElement();  // number:date-style
01734   }
01735   else if( valueFormat.lower() == "mm/dd/yyyy" )
01736   {
01737     xmlWriter->startElement( "number:date-style" );
01738     xmlWriter->addAttribute( "style:name", refName ); 
01739     xmlWriter->addAttribute( "style:family", "data-style" ); 
01740     
01741     xmlWriter->startElement( "number:month" );
01742     xmlWriter->addAttribute( "number:textual", "false" ); 
01743     xmlWriter->addAttribute( "number:style", "long" ); 
01744     xmlWriter->endElement();  // number:month
01745   
01746     xmlWriter->startElement( "number:text");
01747     xmlWriter->addTextNode( "/" );
01748     xmlWriter->endElement();  // number:text
01749     
01750     xmlWriter->startElement( "number:day" );
01751     xmlWriter->addAttribute( "number:style", "long" ); 
01752     xmlWriter->endElement();  // number:day
01753     
01754     xmlWriter->startElement( "number:text");
01755     xmlWriter->addTextNode( "/" );
01756     xmlWriter->endElement();  // number:text
01757     
01758     xmlWriter->startElement( "number:year" );
01759     xmlWriter->addAttribute( "number:style", "long" ); 
01760     xmlWriter->endElement();  // number:year
01761    
01762     xmlWriter->endElement();  // number:date-style
01763   }
01764   else if( valueFormat.lower() == "yyyy/mm/dd" )
01765   {
01766     xmlWriter->startElement( "number:date-style" );
01767     xmlWriter->addAttribute( "style:name", refName ); 
01768     xmlWriter->addAttribute( "style:family", "data-style" ); 
01769     
01770     xmlWriter->startElement( "number:year" );
01771     xmlWriter->addAttribute( "number:style", "long" ); 
01772     xmlWriter->endElement();  // number:year
01773    
01774     xmlWriter->startElement( "number:text");
01775     xmlWriter->addTextNode( "/" );
01776     xmlWriter->endElement();  // number:text
01777     
01778     xmlWriter->startElement( "number:month" );
01779     xmlWriter->addAttribute( "number:textual", "false" ); 
01780     xmlWriter->addAttribute( "number:style", "long" ); 
01781     xmlWriter->endElement();  // number:month
01782   
01783     xmlWriter->startElement( "number:text");
01784     xmlWriter->addTextNode( "/" );
01785     xmlWriter->endElement();  // number:text
01786     
01787     xmlWriter->startElement( "number:day" );
01788     xmlWriter->addAttribute( "number:style", "long" ); 
01789     xmlWriter->endElement();  // number:day
01790     
01791     xmlWriter->endElement();  // number:date-style
01792   }
01793   else if( valueFormat.lower() == "yyyy/mm/d" )
01794   {
01795     xmlWriter->startElement( "number:date-style" );
01796     xmlWriter->addAttribute( "style:name", refName ); 
01797     xmlWriter->addAttribute( "style:family", "data-style" ); 
01798     
01799     xmlWriter->startElement( "number:year" );
01800     xmlWriter->addAttribute( "number:style", "long" ); 
01801     xmlWriter->endElement();  // number:year
01802    
01803     xmlWriter->startElement( "number:text");
01804     xmlWriter->addTextNode( "/" );
01805     xmlWriter->endElement();  // number:text
01806     
01807     xmlWriter->startElement( "number:month" );
01808     xmlWriter->addAttribute( "number:textual", "false" ); 
01809     xmlWriter->addAttribute( "number:style", "long" ); 
01810     xmlWriter->endElement();  // number:month
01811   
01812     xmlWriter->startElement( "number:text");
01813     xmlWriter->addTextNode( "/" );
01814     xmlWriter->endElement();  // number:text
01815     
01816     xmlWriter->startElement( "number:day" );
01817     xmlWriter->addAttribute( "number:style", "short" ); 
01818     xmlWriter->endElement();  // number:day
01819     
01820     xmlWriter->endElement();  // number:date-style
01821   }
01822   else if( (valueFormat.lower() == "yyyy-mm-dd") || (valueFormat.lower() == "yyyy\\-mm\\-dd") )
01823   {
01824     xmlWriter->startElement( "number:date-style" );
01825     xmlWriter->addAttribute( "style:name", refName ); 
01826     xmlWriter->addAttribute( "style:family", "data-style" ); 
01827     
01828     xmlWriter->startElement( "number:year" );
01829     xmlWriter->addAttribute( "number:style", "long" ); 
01830     xmlWriter->endElement();  // number:year
01831    
01832     xmlWriter->startElement( "number:text");
01833     xmlWriter->addTextNode( "-" );
01834     xmlWriter->endElement();  // number:text
01835     
01836     xmlWriter->startElement( "number:month" );
01837     xmlWriter->addAttribute( "number:textual", "false" ); 
01838     xmlWriter->addAttribute( "number:style", "long" ); 
01839     xmlWriter->endElement();  // number:month
01840   
01841     xmlWriter->startElement( "number:text");
01842     xmlWriter->addTextNode( "-" );
01843     xmlWriter->endElement();  // number:text
01844     
01845     xmlWriter->startElement( "number:day" );
01846     xmlWriter->addAttribute( "number:style", "long" ); 
01847     xmlWriter->endElement();  // number:day
01848     
01849     xmlWriter->endElement();  // number:date-style
01850   }
01851   else if( (valueFormat.lower() == "yyyy-mm-d") || (valueFormat.lower() == "yyyy\\-mm\\-d") )
01852   {
01853     xmlWriter->startElement( "number:date-style" );
01854     xmlWriter->addAttribute( "style:name", refName ); 
01855     xmlWriter->addAttribute( "style:family", "data-style" ); 
01856     
01857     xmlWriter->startElement( "number:year" );
01858     xmlWriter->addAttribute( "number:style", "long" ); 
01859     xmlWriter->endElement();  // number:year
01860    
01861     xmlWriter->startElement( "number:text");
01862     xmlWriter->addTextNode( "-" );
01863     xmlWriter->endElement();  // number:text
01864     
01865     xmlWriter->startElement( "number:month" );
01866     xmlWriter->addAttribute( "number:textual", "false" ); 
01867     xmlWriter->addAttribute( "number:style", "long" ); 
01868     xmlWriter->endElement();  // number:month
01869   
01870     xmlWriter->startElement( "number:text");
01871     xmlWriter->addTextNode( "-" );
01872     xmlWriter->endElement();  // number:text
01873     
01874     xmlWriter->startElement( "number:day" );
01875     xmlWriter->addAttribute( "number:style", "short" ); 
01876     xmlWriter->endElement();  // number:day
01877     
01878     xmlWriter->endElement();  // number:date-style
01879   }
01880 
01881   else if( valueFormat == "h:mm AM/PM" )
01882   {
01883     xmlWriter->startElement( "number:time-style" );
01884     xmlWriter->addAttribute( "style:name", refName ); 
01885     xmlWriter->addAttribute( "style:family", "data-style" ); 
01886     
01887     xmlWriter->startElement( "number:hours" );
01888     xmlWriter->addAttribute( "number:style", "short" ); 
01889     xmlWriter->endElement();  // number:hour
01890    
01891     xmlWriter->startElement( "number:text");
01892     xmlWriter->addTextNode( ":" );
01893     xmlWriter->endElement();  // number:text
01894     
01895     xmlWriter->startElement( "number:minutes" );
01896     xmlWriter->addAttribute( "number:style", "long" ); 
01897     xmlWriter->endElement();  // number:minutes
01898   
01899     xmlWriter->startElement( "number:text");
01900     xmlWriter->addTextNode( " " );
01901     xmlWriter->endElement();  // number:text
01902     
01903     xmlWriter->startElement( "number:am-pm" );
01904     xmlWriter->endElement();  // number:am-pm
01905     
01906     xmlWriter->endElement();  // number:time-style
01907   }
01908   else if( valueFormat == "h:mm:ss AM/PM" )
01909   {
01910     xmlWriter->startElement( "number:time-style" );
01911     xmlWriter->addAttribute( "style:name", refName ); 
01912     xmlWriter->addAttribute( "style:family", "data-style" ); 
01913     
01914     xmlWriter->startElement( "number:hours" );
01915     xmlWriter->addAttribute( "number:style", "short" ); 
01916     xmlWriter->endElement();  // number:hour
01917    
01918     xmlWriter->startElement( "number:text");
01919     xmlWriter->addTextNode( ":" );
01920     xmlWriter->endElement();  // number:text
01921     
01922     xmlWriter->startElement( "number:minutes" );
01923     xmlWriter->addAttribute( "number:style", "long" ); 
01924     xmlWriter->endElement();  // number:minutes
01925   
01926     xmlWriter->startElement( "number:text");
01927     xmlWriter->addTextNode( ":" );
01928     xmlWriter->endElement();  // number:text
01929     
01930     xmlWriter->startElement( "number:seconds" );
01931     xmlWriter->addAttribute( "number:style", "long" ); 
01932     xmlWriter->endElement();  // number:minutes
01933   
01934     xmlWriter->startElement( "number:text");
01935     xmlWriter->addTextNode( " " );
01936     xmlWriter->endElement();  // number:text
01937     
01938     xmlWriter->startElement( "number:am-pm" );
01939     xmlWriter->endElement();  // number:am-pm
01940     
01941     xmlWriter->endElement();  // number:time-style
01942   }
01943   else if( valueFormat == "h:mm" )
01944   {
01945     xmlWriter->startElement( "number:time-style" );
01946     xmlWriter->addAttribute( "style:name", refName ); 
01947     xmlWriter->addAttribute( "style:family", "data-style" ); 
01948     
01949     xmlWriter->startElement( "number:hours" );
01950     xmlWriter->addAttribute( "number:style", "short" ); 
01951     xmlWriter->endElement();  // number:hour
01952    
01953     xmlWriter->startElement( "number:text");
01954     xmlWriter->addTextNode( ":" );
01955     xmlWriter->endElement();  // number:text
01956     
01957     xmlWriter->startElement( "number:minutes" );
01958     xmlWriter->addAttribute( "number:style", "long" ); 
01959     xmlWriter->endElement();  // number:minutes
01960     
01961     xmlWriter->endElement();  // number:time-style
01962   }
01963   else if( valueFormat == "h:mm:ss" )
01964   {
01965     xmlWriter->startElement( "number:time-style" );
01966     xmlWriter->addAttribute( "style:name", refName ); 
01967     xmlWriter->addAttribute( "style:family", "data-style" ); 
01968     
01969     xmlWriter->startElement( "number:hours" );
01970     xmlWriter->addAttribute( "number:style", "short" ); 
01971     xmlWriter->endElement();  // number:hour
01972    
01973     xmlWriter->startElement( "number:text");
01974     xmlWriter->addTextNode( ":" );
01975     xmlWriter->endElement();  // number:text
01976     
01977     xmlWriter->startElement( "number:minutes" );
01978     xmlWriter->addAttribute( "number:style", "long" ); 
01979     xmlWriter->endElement();  // number:minutes
01980   
01981     xmlWriter->startElement( "number:text");
01982     xmlWriter->addTextNode( ":" );
01983     xmlWriter->endElement();  // number:text
01984     
01985     xmlWriter->startElement( "number:seconds" );
01986     xmlWriter->addAttribute( "number:style", "long" ); 
01987     xmlWriter->endElement();  // number:minutes
01988     
01989     xmlWriter->endElement();  // number:time-style
01990   }
01991   else if( valueFormat == "[h]:mm" )
01992   {
01993     xmlWriter->startElement( "number:time-style" );
01994     xmlWriter->addAttribute( "style:name", refName ); 
01995     xmlWriter->addAttribute( "style:family", "data-style" ); 
01996     xmlWriter->addAttribute( "number:truncate-on-overflow", "false" ); 
01997     
01998     xmlWriter->startElement( "number:hours" );
01999     xmlWriter->addAttribute( "number:style", "short" ); 
02000     xmlWriter->endElement();  // number:hour
02001    
02002     xmlWriter->startElement( "number:text");
02003     xmlWriter->addTextNode( ":" );
02004     xmlWriter->endElement();  // number:text
02005     
02006     xmlWriter->startElement( "number:minutes" );
02007     xmlWriter->addAttribute( "number:style", "long" ); 
02008     xmlWriter->endElement();  // number:minutes
02009     
02010     xmlWriter->endElement();  // number:time-style
02011   }
02012   else if( valueFormat == "[h]:mm:ss" )
02013   {
02014     xmlWriter->startElement( "number:time-style" );
02015     xmlWriter->addAttribute( "style:name", refName ); 
02016     xmlWriter->addAttribute( "style:family", "data-style" ); 
02017     xmlWriter->addAttribute( "number:truncate-on-overflow", "false" ); 
02018     
02019     xmlWriter->startElement( "number:hours" );
02020     xmlWriter->addAttribute( "number:style", "short" ); 
02021     xmlWriter->endElement();  // number:hour
02022    
02023     xmlWriter->startElement( "number:text");
02024     xmlWriter->addTextNode( ":" );
02025     xmlWriter->endElement();  // number:text
02026     
02027     xmlWriter->startElement( "number:minutes" );
02028     xmlWriter->addAttribute( "number:style", "long" ); 
02029     xmlWriter->endElement();  // number:minutes
02030   
02031     xmlWriter->startElement( "number:text");
02032     xmlWriter->addTextNode( ":" );
02033     xmlWriter->endElement();  // number:text
02034     
02035     xmlWriter->startElement( "number:seconds" );
02036     xmlWriter->addAttribute( "number:style", "long" ); 
02037     xmlWriter->endElement();  // number:minutes
02038     
02039     xmlWriter->endElement();  // number:time-style
02040   }
02041   else if( valueFormat == "mm:ss" )
02042   {
02043     xmlWriter->startElement( "number:time-style" );
02044     xmlWriter->addAttribute( "style:name", refName ); 
02045     xmlWriter->addAttribute( "style:family", "data-style" ); 
02046     
02047     xmlWriter->startElement( "number:minutes" );
02048     xmlWriter->addAttribute( "number:style", "long" ); 
02049     xmlWriter->endElement();  // number:minutes
02050   
02051     xmlWriter->startElement( "number:text");
02052     xmlWriter->addTextNode( ":" );
02053     xmlWriter->endElement();  // number:text
02054     
02055     xmlWriter->startElement( "number:seconds" );
02056     xmlWriter->addAttribute( "number:style", "long" ); 
02057     xmlWriter->endElement();  // number:minutes
02058     
02059     xmlWriter->endElement();  // number:time-style
02060   }
02061   else if( valueFormat == "mm:ss.0" )
02062   {
02063     xmlWriter->startElement( "number:time-style" );
02064     xmlWriter->addAttribute( "style:name", refName ); 
02065     xmlWriter->addAttribute( "style:family", "data-style" ); 
02066     
02067     xmlWriter->startElement( "number:minutes" );
02068     xmlWriter->addAttribute( "number:style", "long" ); 
02069     xmlWriter->endElement();  // number:minutes
02070   
02071     xmlWriter->startElement( "number:text");
02072     xmlWriter->addTextNode( ":" );
02073     xmlWriter->endElement();  // number:text
02074     
02075     xmlWriter->startElement( "number:seconds" );
02076     xmlWriter->addAttribute( "number:style", "long" ); 
02077     
02078     xmlWriter->endElement();  // number:minutes
02079     xmlWriter->startElement( "number:text");
02080     xmlWriter->addTextNode( ".0" );
02081     xmlWriter->endElement();  // number:text
02082     
02083     
02084     xmlWriter->endElement();  // number:time-style
02085   }
02086   else if( valueFormat == "[mm]:ss" )
02087   {
02088     xmlWriter->startElement( "number:time-style" );
02089     xmlWriter->addAttribute( "style:name", refName ); 
02090     xmlWriter->addAttribute( "style:family", "data-style" ); 
02091     xmlWriter->addAttribute( "number:truncate-on-overflow", "false" ); 
02092     
02093     xmlWriter->startElement( "number:minutes" );
02094     xmlWriter->addAttribute( "number:style", "long" ); 
02095     xmlWriter->endElement();  // number:minutes
02096   
02097     xmlWriter->startElement( "number:text");
02098     xmlWriter->addTextNode( ":" );
02099     xmlWriter->endElement();  // number:text
02100     
02101     xmlWriter->startElement( "number:seconds" );
02102     xmlWriter->addAttribute( "number:style", "long" ); 
02103     xmlWriter->endElement();  // number:minutes
02104     
02105     xmlWriter->endElement();  // number:time-style
02106   }
02107   else if( valueFormat == "[ss]" )
02108   {
02109     xmlWriter->startElement( "number:time-style" );
02110     xmlWriter->addAttribute( "style:name", refName ); 
02111     xmlWriter->addAttribute( "style:family", "data-style" ); 
02112     xmlWriter->addAttribute( "number:truncate-on-overflow", "false" ); 
02113     
02114     xmlWriter->startElement( "number:seconds" );
02115     xmlWriter->addAttribute( "number:style", "long" ); 
02116     xmlWriter->endElement();  // number:minutes
02117     
02118     xmlWriter->endElement();  // number:time-style
02119   }
02120 
02121 }
KDE Home | KDE Accessibility Home | Description of Access Keys