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