F:/KPlato/koffice/libs/kofficecore/KoOasisStyles.cpp

Aller à la documentation de ce fichier.
00001 /* This file is part of the KDE project
00002    Copyright (C) 2004-2006 David Faure <faure@kde.org>
00003 
00004    This library is free software; you can redistribute it and/or
00005    modify it under the terms of the GNU Library General Public
00006    License version 2 as published by the Free Software Foundation.
00007 
00008    This library is distributed in the hope that it will be useful,
00009    but WITHOUT ANY WARRANTY; without even the implied warranty of
00010    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00011    Library General Public License for more details.
00012 
00013    You should have received a copy of the GNU Library General Public License
00014    along with this library; see the file COPYING.LIB.  If not, write to
00015    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00016  * Boston, MA 02110-1301, USA.
00017 */
00018 
00019 #include "KoOasisStyles.h"
00020 #include <KoXmlReader.h>
00021 #include <KoXmlWriter.h>
00022 #include <kdebug.h>
00023 #include "KoDom.h"
00024 #include "KoXmlNS.h"
00025 #include "KoGenStyles.h"
00026 #include <QBuffer>
00027 #include <kglobal.h>
00028 #include <klocale.h>
00029 #include <QBrush>
00030 #include <KoStyleStack.h>
00031 
00032 class KoOasisStyles::Private
00033 {
00034 public:
00035     // The key of the map is the family
00036     QMap<QString, Q3Dict<KoXmlElement> > m_styles;
00037     QMap<QString, Q3Dict<KoXmlElement> > m_stylesAutoStyles;
00038 };
00039 
00040 KoOasisStyles::KoOasisStyles()
00041     : d( new Private )
00042 {
00043     m_defaultStyle.setAutoDelete( true );
00044     m_masterPages.setAutoDelete( true );
00045     m_listStyles.setAutoDelete( true );
00046     m_drawStyles.setAutoDelete( true );
00047 }
00048 
00049 KoOasisStyles::~KoOasisStyles()
00050 {
00051     delete d;
00052 }
00053 
00054 void KoOasisStyles::createStyleMap( const KoXmlDocument& doc, bool stylesDotXml )
00055 {
00056    const KoXmlElement docElement  = doc.documentElement();
00057     // We used to have the office:version check here, but better let the apps do that
00058     KoXmlElement fontStyles = KoDom::namedItemNS( docElement, KoXmlNS::office, "font-decls" );
00059 
00060     if ( !fontStyles.isNull() ) {
00061         //kDebug(30003) << "Starting reading in font-decl..." << endl;
00062         insertStyles( fontStyles, false );
00063     }// else
00064     //   kDebug(30003) << "No items found" << endl;
00065 
00066     //kDebug(30003) << "Starting reading in office:automatic-styles. stylesDotXml=" << stylesDotXml << endl;
00067 
00068     KoXmlElement autoStyles = KoDom::namedItemNS( docElement, KoXmlNS::office, "automatic-styles" );
00069     if ( !autoStyles.isNull() ) {
00070         insertStyles( autoStyles, stylesDotXml );
00071     }// else
00072     //    kDebug(30003) << "No items found" << endl;
00073 
00074 
00075     //kDebug(30003) << "Reading in master styles" << endl;
00076 
00077     KoXmlNode masterStyles = KoDom::namedItemNS( docElement, KoXmlNS::office, "master-styles" );
00078 
00079     if ( !masterStyles.isNull() ) {
00080         KoXmlElement master;
00081         forEachElement( master, masterStyles )
00082         {
00083             if ( master.localName() == "master-page" &&
00084                  master.namespaceURI() == KoXmlNS::style ) {
00085                 const QString name = master.attributeNS( KoXmlNS::style, "name", QString::null );
00086                 kDebug(30003) << "Master style: '" << name << "' loaded " << endl;
00087                 m_masterPages.insert( name, new KoXmlElement( master ) );
00088             } else
00089                 // OASIS docu mentions style:handout-master and draw:layer-set here
00090                 kWarning(30003) << "Unknown tag " << master.tagName() << " in office:master-styles" << endl;
00091         }
00092     }
00093 
00094 
00095     kDebug(30003) << "Starting reading in office:styles" << endl;
00096 
00097     const KoXmlElement officeStyle = KoDom::namedItemNS( docElement, KoXmlNS::office, "styles" );
00098 
00099     if ( !officeStyle.isNull() ) {
00100         m_officeStyle = officeStyle;
00101         insertOfficeStyles( m_officeStyle );
00102 
00103     }
00104 
00105     //kDebug(30003) << "Styles read in." << endl;
00106 }
00107 
00108 Q3ValueVector<KoXmlElement> KoOasisStyles::userStyles() const
00109 {
00110     Q3ValueVector<KoXmlElement> vec;
00111     // Collect user styles
00112     unsigned int i = 0;
00113     KoXmlElement e;
00114     forEachElement( e, m_officeStyle )
00115     {
00116         if ( e.localName() == "style" &&
00117              e.namespaceURI() == KoXmlNS::style )
00118         {
00119             vec.resize( i+1 );
00120             vec[i++] = e;
00121         }
00122     }
00123     return vec;
00124 }
00125 
00126 const Q3Dict<KoXmlElement>& KoOasisStyles::styles(const QString& family) const
00127 {
00128     // hmm this can create an empty item in the map, but otherwise we couldn't
00129     // return a const reference.
00130     return d->m_styles[family];
00131 }
00132 
00133 void KoOasisStyles::insertOfficeStyles( const KoXmlElement& styles )
00134 {
00135     KoXmlElement e;
00136     forEachElement( e, styles )
00137     {
00138         const QString localName = e.localName();
00139         const QString ns = e.namespaceURI();
00140         if ( ( ns == KoXmlNS::svg && (
00141                    localName == "linearGradient"
00142                    || localName == "radialGradient" ) )
00143              || ( ns == KoXmlNS::draw && (
00144                       localName == "gradient"
00145                       || localName == "hatch"
00146                       || localName == "fill-image"
00147                       || localName == "marker"
00148                       || localName == "stroke-dash"
00149                       || localName == "opacity" ) )
00150              )
00151         {
00152             const QString name = e.attributeNS( KoXmlNS::draw, "name", QString::null );
00153             Q_ASSERT( !name.isEmpty() );
00154             KoXmlElement* ep = new KoXmlElement( e );
00155             m_drawStyles.insert( name, ep );
00156         }
00157         else
00158             insertStyle( e, false );
00159     }
00160 }
00161 
00162 
00163 void KoOasisStyles::insertStyles( const KoXmlElement& styles, bool styleAutoStyles )
00164 {
00165     //kDebug(30003) << "Inserting styles from " << styles.tagName() << endl;
00166     KoXmlElement e;
00167     forEachElement( e, styles )
00168         insertStyle( e, styleAutoStyles );
00169 }
00170 
00171 void KoOasisStyles::insertStyle( const KoXmlElement& e, bool styleAutoStyles )
00172 {
00173     const QString localName = e.localName();
00174     const QString ns = e.namespaceURI();
00175 
00176     const QString name = e.attributeNS( KoXmlNS::style, "name", QString::null );
00177     if ( ns == KoXmlNS::style && localName == "style" ) {
00178         const QString family = e.attributeNS( KoXmlNS::style, "family", QString::null );
00179 
00180         if ( styleAutoStyles ) {
00181             Q3Dict<KoXmlElement>& dict = d->m_stylesAutoStyles[ family ];
00182             dict.setAutoDelete( true );
00183             if ( dict.find( name ) != 0 )
00184                 kDebug(30003) << "Auto-style: '" << name << "' already exists" << endl;
00185             dict.insert( name, new KoXmlElement( e ) );
00186             //kDebug(30003) << "Style: '" << name << "' loaded as a style auto style" << endl;
00187         } else {
00188             Q3Dict<KoXmlElement>& dict = d->m_styles[ family ];
00189             dict.setAutoDelete( true );
00190 
00191             if ( dict.find( name ) != 0 )
00192                 kDebug(30003) << "Style: '" << name << "' already exists" << endl;
00193             dict.insert( name, new KoXmlElement( e ) );
00194             //kDebug(30003) << "Style: '" << name << "' loaded " << endl;
00195         }
00196     } else if ( ns == KoXmlNS::style && (
00197                 localName == "page-layout"
00198              || localName == "font-decl"
00199              || localName == "presentation-page-layout" ) )
00200     {
00201         if ( m_styles.find( name ) != 0 )
00202             kDebug(30003) << "Style: '" << name << "' already exists" << endl;
00203         m_styles.insert( name, new KoXmlElement( e ) );
00204     } else if ( localName == "default-style" && ns == KoXmlNS::style ) {
00205         const QString family = e.attributeNS( KoXmlNS::style, "family", QString::null );
00206         if ( !family.isEmpty() )
00207             m_defaultStyle.insert( family, new KoXmlElement( e ) );
00208     } else if ( localName == "list-style" && ns == KoXmlNS::text ) {
00209         m_listStyles.insert( name, new KoXmlElement( e ) );
00210         //kDebug(30003) << "List style: '" << name << "' loaded " << endl;
00211     } else if ( ns == KoXmlNS::number && (
00212                    localName == "number-style"
00213                 || localName == "currency-style"
00214                 || localName == "percentage-style"
00215                 || localName == "boolean-style"
00216                 || localName == "text-style"
00217                 || localName == "date-style"
00218                 || localName == "time-style" ) ) {
00219         importDataStyle( e );
00220     }
00221     // The rest (text:*-configuration and text:outline-style) is to be done by the apps.
00222 }
00223 
00224 // OO spec 2.5.4. p68. Conversion to Qt format: see qdate.html
00225 // OpenCalcImport::loadFormat has similar code, but slower, intermixed with other stuff,
00226 // lacking long-textual forms.
00227 void KoOasisStyles::importDataStyle( const KoXmlElement& parent )
00228 {
00229     NumericStyleFormat dataStyle;
00230 
00231     const QString localName = parent.localName();
00232     if (localName == "number-style")
00233       dataStyle.type = NumericStyleFormat::Number;
00234     else if (localName == "currency-style")
00235       dataStyle.type = NumericStyleFormat::Currency;
00236     else if (localName == "percentage-style")
00237       dataStyle.type = NumericStyleFormat::Percentage;
00238     else if (localName == "boolean-style")
00239       dataStyle.type = NumericStyleFormat::Boolean;
00240     else if (localName == "text-style")
00241       dataStyle.type = NumericStyleFormat::Text;
00242     else if (localName == "date-style")
00243       dataStyle.type = NumericStyleFormat::Date;
00244     else if (localName == "time-style")
00245       dataStyle.type = NumericStyleFormat::Time;
00246 
00247     QString format;
00248     int precision = -1;
00249     int leadingZ  = 1;
00250 #warning Nothing changes thousandsSep - dead constant
00251     bool thousandsSep = false;
00252     //todo negred
00253     //bool negRed = false;
00254     bool ok = false;
00255     int i = 0;
00256     KoXmlElement e;
00257     QString prefix;
00258     QString suffix;
00259     forEachElement( e, parent )
00260     {
00261         if ( e.namespaceURI() != KoXmlNS::number )
00262             continue;
00263         QString localName = e.localName();
00264         const QString numberStyle = e.attributeNS( KoXmlNS::number, "style", QString::null );
00265         const bool shortForm = numberStyle == "short" || numberStyle.isEmpty();
00266         if ( localName == "day" ) {
00267             format += shortForm ? "d" : "dd";
00268         } else if ( localName == "day-of-week" ) {
00269             format += shortForm ? "ddd" : "dddd";
00270         } else if ( localName == "month" ) {
00271             if ( e.attributeNS( KoXmlNS::number, "possessive-form", QString::null ) == "true" ) {
00272                 format += shortForm ? "PPP" : "PPPP";
00273             }
00274             // TODO the spec has a strange mention of number:format-source
00275             else if ( e.attributeNS( KoXmlNS::number, "textual", QString::null ) == "true" ) {
00276                 format += shortForm ? "MMM" : "MMMM";
00277             } else { // month number
00278                 format += shortForm ? "M" : "MM";
00279             }
00280         } else if ( localName == "year" ) {
00281             format += shortForm ? "yy" : "yyyy";
00282         } else if ( localName == "era" ) {
00283             //TODO I don't know what is it... (define into oo spec)
00284         } else if ( localName == "week-of-year" || localName == "quarter") {
00285             // ### not supported in Qt
00286         } else if ( localName == "hours" ) {
00287             format += shortForm ? "h" : "hh";
00288         } else if ( localName == "minutes" ) {
00289             format += shortForm ? "m" : "mm";
00290         } else if ( localName == "seconds" ) {
00291             format += shortForm ? "s" : "ss";
00292         } else if ( localName == "am-pm" ) {
00293             format += "ap";
00294         } else if ( localName == "text" ) { // literal
00295             format += e.text();
00296         } else if ( localName == "suffix" ) {
00297             suffix = e.text();
00298             kDebug(30003)<<" suffix :"<<suffix<<endl;
00299         } else if ( localName == "prefix" ) {
00300             prefix = e.text();
00301             kDebug(30003)<<" prefix :"<<prefix<<endl;
00302         } else if ( localName == "currency-symbol" ) {
00303             dataStyle.currencySymbol = e.text();
00304             kDebug(30003)<<" currency-symbol: "<<dataStyle.currencySymbol<<endl;
00305             format += e.text();
00306             //TODO
00307             // number:language="de" number:country="DE">€</number:currency-symbol>
00308             // Stefan: localization of the symbol?
00309         } else if ( localName == "number" ) {
00310             // TODO: number:grouping="true"
00311             if ( e.hasAttributeNS( KoXmlNS::number, "decimal-places" ) )
00312             {
00313                 int d = e.attributeNS( KoXmlNS::number, "decimal-places", QString::null ).toInt( &ok );
00314                 if ( ok )
00315                     precision = d;
00316             }
00317             if ( e.hasAttributeNS( KoXmlNS::number, "min-integer-digits" ) )
00318             {
00319                 int d = e.attributeNS( KoXmlNS::number, "min-integer-digits", QString::null ).toInt( &ok );
00320                 if ( ok )
00321                     leadingZ = d;
00322             }
00323             if ( thousandsSep && leadingZ <= 3 )
00324             {
00325                 format += "#,";
00326                 for ( i = leadingZ; i <= 3; ++i )
00327                     format += '#';
00328             }
00329             for ( i = 1; i <= leadingZ; ++i )
00330             {
00331                 format +=  '0';
00332                 if ( ( i % 3 == 0 ) && thousandsSep )
00333                     format =+ ',' ;
00334             }
00335             if (precision > -1)
00336             {
00337                 format += '.';
00338                 for ( i = 0; i < precision; ++i )
00339                     format += '0';
00340             }
00341         }
00342         else if ( localName == "scientific-number" ) {
00343             if (dataStyle.type == NumericStyleFormat::Number)
00344                 dataStyle.type = NumericStyleFormat::Scientific;
00345             int exp = 2;
00346 
00347             if ( e.hasAttributeNS( KoXmlNS::number, "decimal-places" ) )
00348             {
00349                 int d = e.attributeNS( KoXmlNS::number, "decimal-places", QString::null ).toInt( &ok );
00350                 if ( ok )
00351                     precision = d;
00352             }
00353 
00354             if ( e.hasAttributeNS( KoXmlNS::number, "min-integer-digits" ) )
00355             {
00356                 int d = e.attributeNS( KoXmlNS::number, "min-integer-digits", QString::null ).toInt( &ok );
00357                 if ( ok )
00358                     leadingZ = d;
00359             }
00360 
00361             if ( e.hasAttributeNS( KoXmlNS::number, "min-exponent-digits" ) )
00362             {
00363                 int d = e.attributeNS( KoXmlNS::number, "min-exponent-digits", QString::null ).toInt( &ok );
00364                 if ( ok )
00365                     exp = d;
00366                 if ( exp <= 0 )
00367                     exp = 1;
00368             }
00369 
00370             if ( thousandsSep && leadingZ <= 3 )
00371             {
00372                 format += "#,";
00373                 for ( i = leadingZ; i <= 3; ++i )
00374                     format += '#';
00375             }
00376 
00377             for ( i = 1; i <= leadingZ; ++i )
00378             {
00379                 format+='0';
00380                 if ( ( i % 3 == 0 ) && thousandsSep )
00381                     format+=',';
00382             }
00383 
00384             if (precision > -1)
00385             {
00386                 format += '.';
00387                 for ( i = 0; i < precision; ++i )
00388                     format += '0';
00389             }
00390 
00391             format+="E+";
00392             for ( i = 0; i < exp; ++i )
00393                 format+='0';
00394         } else if ( localName == "fraction" ) {
00395                 if (dataStyle.type == NumericStyleFormat::Number)
00396                     dataStyle.type = NumericStyleFormat::Fraction;
00397                 int integer = 0;
00398                 int numerator = 1;
00399                 int denominator = 1;
00400                 int denominatorValue=0;
00401                 if ( e.hasAttributeNS( KoXmlNS::number, "min-integer-digits" ) )
00402                 {
00403                     int d = e.attributeNS( KoXmlNS::number, "min-integer-digits", QString::null ).toInt( &ok );
00404                     if ( ok )
00405                         integer = d;
00406                 }
00407                 if ( e.hasAttributeNS( KoXmlNS::number, "min-numerator-digits" ) )
00408                 {
00409                     int d = e.attributeNS( KoXmlNS::number, "min-numerator-digits", QString::null ).toInt( &ok );
00410                     if ( ok )
00411                         numerator = d;
00412                 }
00413                 if ( e.hasAttributeNS( KoXmlNS::number, "min-denominator-digits" ) )
00414                 {
00415                     int d = e.attributeNS( KoXmlNS::number, "min-denominator-digits", QString::null ).toInt( &ok );
00416                     if ( ok )
00417                         denominator = d;
00418                 }
00419                 if ( e.hasAttributeNS( KoXmlNS::number, "denominator-value" ) )
00420                 {
00421                     int d = e.attributeNS( KoXmlNS::number, "denominator-value", QString::null ).toInt( &ok );
00422                     if ( ok )
00423                         denominatorValue = d;
00424                 }
00425 
00426                 for ( i = 0; i < integer; ++i )
00427                     format+='#';
00428 
00429                 format+=' ';
00430 
00431                 for ( i = 0; i < numerator; ++i )
00432                     format+='?';
00433 
00434                 format+='/';
00435 
00436                 if ( denominatorValue != 0 )
00437                     format+=QString::number( denominatorValue );
00438                 else
00439                 {
00440                     for ( i = 0; i < denominator; ++i )
00441                         format+='?';
00442                 }
00443             }
00444         // Not needed:
00445         //  <style:map style:condition="value()&gt;=0" style:apply-style-name="N106P0"/>
00446         // we handle painting negative numbers in red differently
00447 
00448     }
00449 
00450     const QString styleName = parent.attributeNS( KoXmlNS::style, "name", QString::null );
00451     kDebug(30003) << "data style: " << styleName << " qt format=" << format << endl;
00452     if ( !prefix.isEmpty() )
00453     {
00454         kDebug(30003)<<" format.left( prefix.length() ) :"<<format.left( prefix.length() )<<" prefix :"<<prefix<<endl;
00455         if ( format.left( prefix.length() )==prefix )
00456         {
00457             format = format.right( format.length()-prefix.length() );
00458         }
00459         else
00460             prefix.clear();
00461     }
00462     if ( !suffix.isEmpty() )
00463     {
00464         kDebug(30003)<<"format.right( suffix.length() ) :"<<format.right( suffix.length() )<<" suffix :"<<suffix<<endl;
00465         if ( format.right( suffix.length() )==suffix )
00466         {
00467             format = format.left( format.length()-suffix.length() );
00468         }
00469         else
00470             suffix.clear();
00471     }
00472 
00473     dataStyle.formatStr=format;
00474     dataStyle.prefix=prefix;
00475     dataStyle.suffix=suffix;
00476     dataStyle.precision = precision;
00477     kDebug(30003)<<" finish insert format :"<<format<<" prefix :"<<prefix<<" suffix :"<<suffix<<endl;
00478     m_dataFormats.insert( styleName, dataStyle );
00479 }
00480 
00481 #define addTextNumber( text, elementWriter ) { \
00482         if ( !text.isEmpty() ) \
00483         { \
00484             elementWriter.startElement( "number:text" ); \
00485             elementWriter.addTextNode( text ); \
00486             elementWriter.endElement(); \
00487             text=""; \
00488         } \
00489 }
00490 
00491 void KoOasisStyles::parseOasisTimeKlocale(KoXmlWriter &elementWriter, QString & format, QString & text )
00492 {
00493     kDebug(30003)<<"parseOasisTimeKlocale(KoXmlWriter &elementWriter, QString & format, QString & text ) :"<<format<<endl;
00494     do
00495     {
00496         if ( !saveOasisKlocaleTimeFormat( elementWriter, format, text ) )
00497         {
00498             text += format[0];
00499             format = format.remove( 0, 1 );
00500         }
00501     }
00502     while ( format.length() > 0 );
00503     addTextNumber( text, elementWriter );
00504 }
00505 
00506 bool KoOasisStyles::saveOasisKlocaleTimeFormat( KoXmlWriter &elementWriter, QString & format, QString & text )
00507 {
00508     bool changed = false;
00509     if ( format.startsWith( "%H" ) ) //hh
00510     {
00511         //hour in 24h
00512         addTextNumber( text, elementWriter );
00513 
00514         elementWriter.startElement( "number:hours" );
00515         elementWriter.addAttribute( "number:style", "long" );
00516         elementWriter.endElement();
00517         format = format.remove( 0, 2 );
00518         changed = true;
00519     }
00520     else if ( format.startsWith( "%k" ) )//h
00521     {
00522         addTextNumber( text, elementWriter );
00523 
00524         elementWriter.startElement( "number:hours" );
00525         elementWriter.addAttribute( "number:style", "short" );
00526         elementWriter.endElement();
00527         format = format.remove( 0, 2 );
00528         changed = true;
00529     }
00530     else if ( format.startsWith( "%I" ) )// ?????
00531     {
00532         //TODO hour in 12h
00533         changed = true;
00534     }
00535     else if ( format.startsWith( "%l" ) )
00536     {
00537         //TODO hour in 12h with 1 digit
00538         changed = true;
00539     }
00540     else if ( format.startsWith( "%M" ) )// mm
00541     {
00542         addTextNumber( text, elementWriter );
00543 
00544         elementWriter.startElement( "number:minutes" );
00545         elementWriter.addAttribute( "number:style", "long" );
00546         elementWriter.endElement();
00547         format = format.remove( 0, 2 );
00548         changed = true;
00549 
00550     }
00551     else if ( format.startsWith( "%S" ) ) //ss
00552     {
00553         addTextNumber( text, elementWriter );
00554 
00555         elementWriter.startElement( "number:seconds" );
00556         elementWriter.addAttribute( "number:style", "long" );
00557         elementWriter.endElement();
00558         format = format.remove( 0, 2 );
00559         changed = true;
00560     }
00561     else if ( format.startsWith( "%p" ) )
00562     {
00563         //TODO am or pm
00564         addTextNumber( text, elementWriter );
00565 
00566         elementWriter.startElement( "number:am-pm" );
00567         elementWriter.endElement();
00568         format = format.remove( 0, 2 );
00569         changed = true;
00570     }
00571     return changed;
00572 }
00573 
00574 
00575 bool KoOasisStyles::saveOasisTimeFormat( KoXmlWriter &elementWriter, QString & format, QString & text, bool &antislash )
00576 {
00577     bool changed = false;
00578     //we can also add time to date.
00579     if ( antislash )
00580     {
00581         text+=format[0];
00582         format = format.remove( 0, 1 );
00583         antislash = false;
00584         changed = true;
00585     }
00586     else if ( format.startsWith( "hh" ) )
00587     {
00588         addTextNumber( text, elementWriter );
00589 
00590         elementWriter.startElement( "number:hours" );
00591         elementWriter.addAttribute( "number:style", "long" );
00592         elementWriter.endElement();
00593         format = format.remove( 0, 2 );
00594         changed = true;
00595     }
00596     else if ( format.startsWith( "h" ) )
00597     {
00598         addTextNumber( text, elementWriter );
00599 
00600         elementWriter.startElement( "number:hours" );
00601         elementWriter.addAttribute( "number:style", "short" );
00602         elementWriter.endElement();
00603         format = format.remove( 0, 1 );
00604         changed = true;
00605     }
00606     else if ( format.startsWith( "mm" ) )
00607     {
00608         addTextNumber( text, elementWriter );
00609 
00610         elementWriter.startElement( "number:minutes" );
00611         elementWriter.addAttribute( "number:style", "long" );
00612         elementWriter.endElement();
00613         format = format.remove( 0, 2 );
00614         changed = true;
00615     }
00616     else if ( format.startsWith( "m" ) )
00617     {
00618         addTextNumber( text, elementWriter );
00619 
00620         elementWriter.startElement( "number:minutes" );
00621         elementWriter.addAttribute( "number:style", "short" );
00622         elementWriter.endElement();
00623         format = format.remove( 0, 1 );
00624         changed = true;
00625     }
00626     else if ( format.startsWith( "ss" ) )
00627     {
00628         addTextNumber( text, elementWriter );
00629 
00630         elementWriter.startElement( "number:seconds" );
00631         elementWriter.addAttribute( "number:style", "long" );
00632         elementWriter.endElement();
00633         format = format.remove( 0, 2 );
00634         changed = true;
00635     }
00636     else if ( format.startsWith( "s" ) )
00637     {
00638         addTextNumber( text, elementWriter );
00639 
00640         elementWriter.startElement( "number:seconds" );
00641         elementWriter.addAttribute( "number:style", "short" );
00642         elementWriter.endElement();
00643         format = format.remove( 0, 1 );
00644         changed = true;
00645     }
00646     else if ( format.startsWith( "ap" ) )
00647     {
00648         addTextNumber( text, elementWriter );
00649 
00650         elementWriter.startElement( "number:am-pm" );
00651         elementWriter.endElement();
00652         format = format.remove( 0, 2 );
00653         changed = true;
00654     }
00655     return changed;
00656 }
00657 
00658 QString KoOasisStyles::saveOasisTimeStyle( KoGenStyles &mainStyles, const QString & _format, bool klocaleFormat,
00659                                            const QString & _prefix, const QString & _suffix )
00660 {
00661     kDebug(30003)<<"QString KoOasisStyles::saveOasisTimeStyle( KoGenStyles &mainStyles, const QString & _format ) :"<<_format<<endl;
00662     QString format( _format );
00663     KoGenStyle currentStyle( KoGenStyle::STYLE_NUMERIC_TIME );
00664     QBuffer buffer;
00665     buffer.open( QIODevice::WriteOnly );
00666     KoXmlWriter elementWriter( &buffer );  // TODO pass indentation level
00667     QString text;
00668     if ( klocaleFormat )
00669     {
00670         parseOasisTimeKlocale( elementWriter, format, text );
00671     }
00672     else
00673     {
00674         bool antislash = false;
00675         do
00676         {
00677             if ( !saveOasisTimeFormat( elementWriter, format, text, antislash ) )
00678             {
00679                 QString elem( format[0] );
00680                 format = format.remove( 0, 1 );
00681                 if ( elem == "\\" )
00682                 {
00683                      antislash = true;
00684                 }
00685                 else
00686                 {
00687                     text += elem;
00688                     antislash = false;
00689                 }
00690             }
00691         }
00692         while ( format.length() > 0 );
00693         addTextNumber( text, elementWriter );
00694     }
00695     QString elementContents = QString::fromUtf8( buffer.buffer(), buffer.buffer().size() );
00696     currentStyle.addChildElement( "number", elementContents );
00697     return mainStyles.lookup( currentStyle, "N" );
00698 }
00699 
00700 //convert klocale string to good format
00701 void KoOasisStyles::parseOasisDateKlocale(KoXmlWriter &elementWriter, QString & format, QString & text )
00702 {
00703     kDebug(30003)<<"KoOasisStyles::parseOasisDateKlocale(KoXmlWriter &elementWriter, QString & format, QString & text ) :"<<format<<endl;
00704     do
00705     {
00706         if ( format.startsWith( "%Y" ) )
00707         {
00708             addTextNumber( text, elementWriter );
00709             elementWriter.startElement( "number:year" );
00710             elementWriter.addAttribute( "number:style", "long" );
00711             elementWriter.endElement();
00712             format = format.remove( 0, 2 );
00713         }
00714         else if ( format.startsWith( "%y" ) )
00715         {
00716 
00717             addTextNumber( text, elementWriter );
00718 
00719             elementWriter.startElement( "number:year" );
00720             elementWriter.addAttribute( "number:style", "short" );
00721             elementWriter.endElement();
00722             format = format.remove( 0, 2 );
00723         }
00724         else if ( format.startsWith( "%n" ) )
00725         {
00726             addTextNumber( text, elementWriter );
00727             elementWriter.startElement( "number:month" );
00728             elementWriter.addAttribute( "number:style", "short" );
00729             elementWriter.addAttribute( "number:textual", "false");
00730             elementWriter.endElement();
00731             format = format.remove( 0, 2 );
00732         }
00733         else if ( format.startsWith( "%m" ) )
00734         {
00735             addTextNumber( text, elementWriter );
00736             elementWriter.startElement( "number:month" );
00737             elementWriter.addAttribute( "number:style", "long" );
00738             elementWriter.addAttribute( "number:textual", "false"); //not necessary remove it
00739             elementWriter.endElement();
00740             format = format.remove( 0, 2 );
00741         }
00742         else if ( format.startsWith( "%e" ) )
00743         {
00744             addTextNumber( text, elementWriter );
00745 
00746             elementWriter.startElement( "number:day" );
00747             elementWriter.addAttribute( "number:style", "short" );
00748             elementWriter.endElement();
00749             format = format.remove( 0, 2 );
00750         }
00751         else if ( format.startsWith( "%d" ) )
00752         {
00753             addTextNumber( text, elementWriter );
00754 
00755             elementWriter.startElement( "number:day" );
00756             elementWriter.addAttribute( "number:style", "long" );
00757             elementWriter.endElement();
00758             format = format.remove( 0, 2 );
00759         }
00760         else if ( format.startsWith( "%b" ) )
00761         {
00762             addTextNumber( text, elementWriter );
00763             elementWriter.startElement( "number:month" );
00764             elementWriter.addAttribute( "number:style", "short" );
00765             elementWriter.addAttribute( "number:textual", "true");
00766             elementWriter.endElement();
00767             format = format.remove( 0, 2 );
00768         }
00769         else if ( format.startsWith( "%B" ) )
00770         {
00771             addTextNumber( text, elementWriter );
00772             elementWriter.startElement( "number:month" );
00773             elementWriter.addAttribute( "number:style", "long" );
00774             elementWriter.addAttribute( "number:textual", "true");
00775             elementWriter.endElement();
00776             format = format.remove( 0, 2 );
00777         }
00778         else if ( format.startsWith( "%a" ) )
00779         {
00780             addTextNumber( text, elementWriter );
00781             elementWriter.startElement( "number:day-of-week" );
00782             elementWriter.addAttribute( "number:style", "short" );
00783             elementWriter.endElement();
00784 
00785             format = format.remove( 0, 2 );
00786         }
00787         else if ( format.startsWith( "%A" ) )
00788         {
00789             addTextNumber( text, elementWriter );
00790             elementWriter.startElement( "number:day-of-week" );
00791             elementWriter.addAttribute( "number:style", "long" );
00792             elementWriter.endElement();
00793             format = format.remove( 0, 2 );
00794         }
00795         else
00796         {
00797             if ( !saveOasisKlocaleTimeFormat( elementWriter, format, text ) )
00798             {
00799                 text += format[0];
00800                 format = format.remove( 0, 1 );
00801             }
00802         }
00803     }
00804     while ( format.length() > 0 );
00805     addTextNumber( text, elementWriter );
00806 }
00807 
00808 QString KoOasisStyles::saveOasisDateStyle( KoGenStyles &mainStyles, const QString & _format, bool klocaleFormat,
00809                                            const QString & _prefix, const QString & _suffix )
00810 {
00811     kDebug(30003)<<"QString KoOasisStyles::saveOasisDateStyle( KoGenStyles &mainStyles, const QString & _format ) :"<<_format<<endl;
00812     QString format( _format );
00813 
00814     // Not supported into Qt: "era" "week-of-year" "quarter"
00815 
00816     KoGenStyle currentStyle( KoGenStyle::STYLE_NUMERIC_DATE );
00817     QBuffer buffer;
00818     buffer.open( QIODevice::WriteOnly );
00819     KoXmlWriter elementWriter( &buffer );  // TODO pass indentation level
00820     QString text;
00821     if ( klocaleFormat )
00822     {
00823         parseOasisDateKlocale( elementWriter, format, text );
00824     }
00825     else
00826     {
00827         bool antislash = false;
00828         do
00829         {
00830             if ( antislash )
00831             {
00832                 text+=format[0];
00833                 format = format.remove( 0, 1 );
00834             }
00835             //TODO implement loading ! What is it ?
00836             else if ( format.startsWith( "MMMMM" ) )
00837             {
00838                 addTextNumber( text, elementWriter );
00839                 elementWriter.startElement( "number:month" );
00840                 elementWriter.addAttribute( "number:textual", "true");
00841                 elementWriter.endElement();
00842                 format = format.remove( 0, 5 );
00843             }
00844             else if ( format.startsWith( "MMMM" ) )
00845             {
00846                 addTextNumber( text, elementWriter );
00847                 elementWriter.startElement( "number:month" );
00848                 elementWriter.addAttribute( "number:style", "long" );
00849                 elementWriter.addAttribute( "number:textual", "true");
00850                 elementWriter.endElement();
00851                 format = format.remove( 0, 4 );
00852             }
00853             else if ( format.startsWith( "MMM" ) )
00854             {
00855                 addTextNumber( text, elementWriter );
00856                 elementWriter.startElement( "number:month" );
00857                 elementWriter.addAttribute( "number:style", "short" );
00858                 elementWriter.addAttribute( "number:textual", "true");
00859                 elementWriter.endElement();
00860                 format = format.remove( 0, 3 );
00861             }
00862             else if ( format.startsWith( "MM" ) )
00863             {
00864                 addTextNumber( text, elementWriter );
00865                 elementWriter.startElement( "number:month" );
00866                 elementWriter.addAttribute( "number:style", "long" );
00867                 elementWriter.addAttribute( "number:textual", "false"); //not necessary remove it
00868                 elementWriter.endElement();
00869                 format = format.remove( 0, 2 );
00870             }
00871             else if ( format.startsWith( "M" ) )
00872             {
00873                 addTextNumber( text, elementWriter );
00874                 elementWriter.startElement( "number:month" );
00875                 elementWriter.addAttribute( "number:style", "short" );
00876                 elementWriter.addAttribute( "number:textual", "false");
00877                 elementWriter.endElement();
00878                 format = format.remove( 0, 1 );
00879             }
00880             else if ( format.startsWith( "PPPP" ) )
00881             {
00882                 addTextNumber( text, elementWriter );
00883                 //<number:month number:possessive-form="true" number:textual="true" number:style="long"/>
00884                 elementWriter.startElement( "number:month" );
00885                 elementWriter.addAttribute( "number:style", "short" );
00886                 elementWriter.addAttribute( "number:textual", "false");
00887                 elementWriter.addAttribute( "number:possessive-form", "true" );
00888                 elementWriter.endElement();
00889                 format = format.remove( 0, 4 );
00890             }
00891             else if ( format.startsWith( "PPP" ) )
00892             {
00893                 addTextNumber( text, elementWriter );
00894                 //<number:month number:possessive-form="true" number:textual="true" number:style="short"/>
00895                 elementWriter.startElement( "number:month" );
00896                 elementWriter.addAttribute( "number:possessive-form", "true" );
00897 
00898                 elementWriter.addAttribute( "number:style", "short" );
00899                 elementWriter.addAttribute( "number:textual", "false");
00900                 elementWriter.endElement();
00901                 format = format.remove( 0, 3 );
00902             }
00903             else if ( format.startsWith( "dddd" ) )
00904             {
00905                 addTextNumber( text, elementWriter );
00906 
00907                 elementWriter.startElement( "number:day-of-week" );
00908                 elementWriter.addAttribute( "number:style", "long" );
00909                 elementWriter.endElement();
00910                 format = format.remove( 0, 4 );
00911             }
00912             else if ( format.startsWith( "ddd" ) )
00913             {
00914                 addTextNumber( text, elementWriter );
00915 
00916                 elementWriter.startElement( "number:day-of-week" );
00917                 elementWriter.addAttribute( "number:style", "short" );
00918                 elementWriter.endElement();
00919                 format = format.remove( 0, 3 );
00920             }
00921             else if ( format.startsWith( "dd" ) )
00922             {
00923                 addTextNumber( text, elementWriter );
00924 
00925                 elementWriter.startElement( "number:day" );
00926                 elementWriter.addAttribute( "number:style", "long" );
00927                 elementWriter.endElement();
00928                 format = format.remove( 0, 2 );
00929             }
00930             else if ( format.startsWith( "d" ) )
00931             {
00932                 addTextNumber( text, elementWriter );
00933 
00934                 elementWriter.startElement( "number:day" );
00935                 elementWriter.addAttribute( "number:style", "short" );
00936                 elementWriter.endElement();
00937                 format = format.remove( 0, 1 );
00938             }
00939             else if ( format.startsWith( "yyyy" ) )
00940             {
00941                 addTextNumber( text, elementWriter );
00942 
00943                 elementWriter.startElement( "number:year" );
00944                 elementWriter.addAttribute( "number:style", "long" );
00945                 elementWriter.endElement();
00946                 format = format.remove( 0, 4 );
00947             }
00948             else if ( format.startsWith( "yy" ) )
00949             {
00950                 addTextNumber( text, elementWriter );
00951 
00952                 elementWriter.startElement( "number:year" );
00953                 elementWriter.addAttribute( "number:style", "short" );
00954                 elementWriter.endElement();
00955                 format = format.remove( 0, 2 );
00956             }
00957             else
00958             {
00959                 if ( !saveOasisTimeFormat( elementWriter, format, text,antislash ) )
00960                 {
00961                     QString elem( format[0] );
00962                     format = format.remove( 0, 1 );
00963                     if ( elem == "\\" )
00964                     {
00965                         antislash = true;
00966                     }
00967                     else
00968                     {
00969                         text += elem;
00970                         antislash = false;
00971                     }
00972                 }
00973             }
00974         }
00975         while ( format.length() > 0 );
00976         addTextNumber( text, elementWriter );
00977     }
00978 
00979     QString elementContents = QString::fromUtf8( buffer.buffer(), buffer.buffer().size() );
00980     currentStyle.addChildElement( "number", elementContents );
00981     return mainStyles.lookup( currentStyle, "N" );
00982 }
00983 
00984 
00985 QString KoOasisStyles::saveOasisFractionStyle( KoGenStyles &mainStyles, const QString & _format,
00986                                                const QString &_prefix, const QString &_suffix )
00987 {
00988     kDebug(30003)<<"QString saveOasisFractionStyle( KoGenStyles &mainStyles, const QString & _format ) :"<<_format<<endl;
00989     QString format( _format );
00990 
00991     KoGenStyle currentStyle( KoGenStyle::STYLE_NUMERIC_FRACTION );
00992     QBuffer buffer;
00993     buffer.open( QIODevice::WriteOnly );
00994     KoXmlWriter elementWriter( &buffer );  // TODO pass indentation level
00995     QString text;
00996     int integer = 0;
00997     int numerator = 0;
00998     int denominator = 0;
00999     int denominatorValue = 0;
01000     bool beforeSlash = true;
01001     do
01002     {
01003         if ( format[0]=='#' )
01004             integer++;
01005         else if ( format[0]=='/' )
01006             beforeSlash = false;
01007         else if ( format[0]=='?' )
01008         {
01009             if ( beforeSlash )
01010                 numerator++;
01011             else
01012                 denominator++;
01013         }
01014         else
01015         {
01016             bool ok;
01017             int value = format.toInt( &ok );
01018             if ( ok )
01019             {
01020                 denominatorValue=value;
01021                 break;
01022             }
01023         }
01024         format.remove( 0,1 );
01025     }
01026     while ( format.length() > 0 );
01027 
01028     text= _prefix;
01029     addTextNumber(text, elementWriter );
01030 
01031     elementWriter.startElement( "number:fraction" );
01032     elementWriter.addAttribute( "number:min-integer-digits", integer );
01033     elementWriter.addAttribute( "number:min-numerator-digits",numerator );
01034     elementWriter.addAttribute( "number:min-denominator-digits",denominator );
01035     if ( denominatorValue != 0 )
01036         elementWriter.addAttribute( "number:denominator-value",denominatorValue );
01037     elementWriter.endElement();
01038 
01039     addKofficeNumericStyleExtension( elementWriter, _suffix, _prefix );
01040 
01041     text=_suffix;
01042     addTextNumber(text, elementWriter );
01043 
01044     QString elementContents = QString::fromUtf8( buffer.buffer(), buffer.buffer().size() );
01045     currentStyle.addChildElement( "number", elementContents );
01046     return mainStyles.lookup( currentStyle, "N" );
01047 }
01048 
01049 
01050 QString KoOasisStyles::saveOasisNumberStyle( KoGenStyles &mainStyles, const QString & _format,
01051                                              const QString &_prefix, const QString &_suffix )
01052 {
01053     kDebug(30003)<<"QString saveOasisNumberStyle( KoGenStyles &mainStyles, const QString & _format ) :"<<_format<<endl;
01054     QString format( _format );
01055 
01056     KoGenStyle currentStyle( KoGenStyle::STYLE_NUMERIC_NUMBER );
01057     QBuffer buffer;
01058     buffer.open( QIODevice::WriteOnly );
01059     KoXmlWriter elementWriter( &buffer );  // TODO pass indentation level
01060     QString text;
01061     int decimalplaces = 0;
01062     int integerdigits = 0;
01063     bool beforeSeparator = true;
01064     do
01065     {
01066         if ( format[0]=='.' || format[0]==',' )
01067             beforeSeparator = false;
01068         else if ( format[0]=='0' && beforeSeparator )
01069             integerdigits++;
01070         else if ( format[0]=='0' && !beforeSeparator )
01071             decimalplaces++;
01072         else
01073             kDebug(30003)<<" error format 0 \n";
01074         format.remove( 0,1 );
01075     }
01076     while ( format.length() > 0 );
01077     text= _prefix ;
01078     addTextNumber(text, elementWriter );
01079     elementWriter.startElement( "number:number" );
01080     kDebug(30003)<<" decimalplaces :"<<decimalplaces<<" integerdigits :"<<integerdigits<<endl;
01081     if (!beforeSeparator)
01082         elementWriter.addAttribute( "number:decimal-places", decimalplaces );
01083     elementWriter.addAttribute( "number:min-integer-digits", integerdigits );
01084     elementWriter.endElement();
01085 
01086     text =_suffix ;
01087     addTextNumber(text, elementWriter );
01088     addKofficeNumericStyleExtension( elementWriter, _suffix,_prefix );
01089 
01090     QString elementContents = QString::fromUtf8( buffer.buffer(), buffer.buffer().size() );
01091     currentStyle.addChildElement( "number", elementContents );
01092     return mainStyles.lookup( currentStyle, "N" );
01093 }
01094 
01095 QString KoOasisStyles::saveOasisPercentageStyle( KoGenStyles &mainStyles, const QString & _format,
01096                                                  const QString &_prefix, const QString &_suffix )
01097 {
01098     //<number:percentage-style style:name="N11">
01099     //<number:number number:decimal-places="2" number:min-integer-digits="1"/>
01100     //<number:text>%</number:text>
01101     //</number:percentage-style>
01102 
01103     kDebug(30003)<<"QString saveOasisPercentageStyle( KoGenStyles &mainStyles, const QString & _format ) :"<<_format<<endl;
01104     QString format( _format );
01105 
01106     KoGenStyle currentStyle( KoGenStyle::STYLE_NUMERIC_PERCENTAGE );
01107     QBuffer buffer;
01108     buffer.open( QIODevice::WriteOnly );
01109     KoXmlWriter elementWriter( &buffer );  // TODO pass indentation level
01110     QString text;
01111     int decimalplaces = 0;
01112     int integerdigits = 0;
01113     bool beforeSeparator = true;
01114     do
01115     {
01116         if ( format[0]=='.' || format[0]==',' )
01117             beforeSeparator = false;
01118         else if ( format[0]=='0' && beforeSeparator )
01119             integerdigits++;
01120         else if ( format[0]=='0' && !beforeSeparator )
01121             decimalplaces++;
01122         else
01123             kDebug(30003)<<" error format 0 \n";
01124         format.remove( 0,1 );
01125     }
01126     while ( format.length() > 0 );
01127     text= _prefix ;
01128     addTextNumber(text, elementWriter );
01129     elementWriter.startElement( "number:number" );
01130     if (!beforeSeparator)
01131         elementWriter.addAttribute( "number:decimal-places", decimalplaces );
01132     elementWriter.addAttribute( "number:min-integer-digits", integerdigits );
01133     elementWriter.endElement();
01134 
01135     addTextNumber(QString( "%" ), elementWriter );
01136 
01137     text =_suffix ;
01138     addTextNumber(text, elementWriter );
01139     addKofficeNumericStyleExtension( elementWriter, _suffix,_prefix );
01140 
01141     QString elementContents = QString::fromUtf8( buffer.buffer(), buffer.buffer().size() );
01142     currentStyle.addChildElement( "number", elementContents );
01143     return mainStyles.lookup( currentStyle, "N" );
01144 
01145 }
01146 
01147 QString KoOasisStyles::saveOasisScientificStyle( KoGenStyles &mainStyles, const QString & _format,
01148                                                  const QString &_prefix, const QString &_suffix )
01149 {
01150     //<number:number-style style:name="N60">
01151     //<number:scientific-number number:decimal-places="2" number:min-integer-digits="1" number:min-exponent-digits="3"/>
01152     //</number:number-style>
01153 
01154     //example 000,000e+0000
01155     kDebug(30003)<<"QString saveOasisScientificStyle( KoGenStyles &mainStyles, const QString & _format ) :"<<_format<<endl;
01156     QString format( _format );
01157 
01158     KoGenStyle currentStyle( KoGenStyle::STYLE_NUMERIC_SCIENTIFIC );
01159     QBuffer buffer;
01160     buffer.open( QIODevice::WriteOnly );
01161     int decimalplace = 0;
01162     int integerdigits = 0;
01163     int exponentdigits = 0;
01164     KoXmlWriter elementWriter( &buffer );  // TODO pass indentation level
01165     QString text;
01166     bool beforeSeparator = true;
01167     bool exponential = false;
01168     bool positive = true;
01169     do
01170     {
01171         if ( !exponential )
01172         {
01173             if ( format[0]=='0' && beforeSeparator )
01174                 integerdigits++;
01175             else if ( format[0]==',' || format[0]=='.' )
01176                 beforeSeparator = false;
01177             else if (  format[0]=='0' && !beforeSeparator )
01178                 decimalplace++;
01179             else if ( format[0].toLower()=='e' )
01180             {
01181                 format.remove( 0, 1 );
01182                 if ( format[0]=='+' )
01183                     positive = true;
01184                 else if ( format[0]=='-' )
01185                     positive = false;
01186                 else
01187                     kDebug(30003)<<"Error into scientific number\n";
01188                 exponential = true;
01189             }
01190         }
01191         else
01192         {
01193             if ( format[0]=='0' && positive )
01194                 exponentdigits++;
01195             else if ( format[0]=='0' && !positive )
01196                 exponentdigits--;
01197             else
01198                 kDebug(30003)<<" error into scientific number exponential value\n";
01199         }
01200         format.remove( 0,1 );
01201     }
01202     while ( format.length() > 0 );
01203     text =  _prefix ;
01204     addTextNumber(text, elementWriter );
01205 
01206     elementWriter.startElement( "number:scientific-number" );
01207     kDebug(30003)<<" decimalplace :"<<decimalplace<<" integerdigits :"<<integerdigits<<" exponentdigits :"<<exponentdigits<<endl;
01208     if (!beforeSeparator)
01209         elementWriter.addAttribute( "number:decimal-places", decimalplace );
01210     elementWriter.addAttribute( "number:min-integer-digits",integerdigits );
01211     elementWriter.addAttribute( "number:min-exponent-digits",exponentdigits );
01212     elementWriter.endElement();
01213 
01214     text = _suffix;
01215     addTextNumber(text, elementWriter );
01216     addKofficeNumericStyleExtension( elementWriter, _suffix,_prefix );
01217 
01218     QString elementContents = QString::fromUtf8( buffer.buffer(), buffer.buffer().size() );
01219     currentStyle.addChildElement( "number", elementContents );
01220     return mainStyles.lookup( currentStyle, "N" );
01221 }
01222 
01223 QString KoOasisStyles::saveOasisCurrencyStyle( KoGenStyles &mainStyles,
01224                                                const QString & _format, const QString &symbol,
01225                                                const QString &_prefix, const QString &_suffix )
01226 {
01227 
01228     //<number:currency-style style:name="N107P0" style:volatile="true">
01229     //<number:number number:decimal-places="2" number:min-integer-digits="1" number:grouping="true"/>
01230     //<number:text> </number:text>
01231     //<number:currency-symbol>VEB</number:currency-symbol>
01232     //</number:currency-style>
01233 
01234     kDebug(30003)<<"QString saveOasisCurrencyStyle( KoGenStyles &mainStyles, const QString & _format ) :"<<_format<<endl;
01235     QString format( _format );
01236 
01237     KoGenStyle currentStyle( KoGenStyle::STYLE_NUMERIC_CURRENCY );
01238     QBuffer buffer;
01239     buffer.open( QIODevice::WriteOnly );
01240     KoXmlWriter elementWriter( &buffer );  // TODO pass indentation level
01241     QString text;
01242     int decimalplaces = 0;
01243     int integerdigits = 0;
01244     bool beforeSeparator = true;
01245     do
01246     {
01247         if ( format[0]=='.' || format[0]==',' )
01248             beforeSeparator = false;
01249         else if ( format[0]=='0' && beforeSeparator )
01250             integerdigits++;
01251         else if ( format[0]=='0' && !beforeSeparator )
01252             decimalplaces++;
01253         else
01254             kDebug(30003)<<" error format 0 \n";
01255         format.remove( 0,1 );
01256     }
01257     while ( format.length() > 0 );
01258 
01259     text =  _prefix ;
01260     addTextNumber(text, elementWriter );
01261 
01262     elementWriter.startElement( "number:number" );
01263     kDebug(30003)<<" decimalplaces :"<<decimalplaces<<" integerdigits :"<<integerdigits<<endl;
01264     if (!beforeSeparator)
01265       elementWriter.addAttribute( "number:decimal-places", decimalplaces );
01266     elementWriter.addAttribute( "number:min-integer-digits", integerdigits );
01267     elementWriter.endElement();
01268 
01269     text =  _suffix ;
01270     addTextNumber(text, elementWriter );
01271     addKofficeNumericStyleExtension( elementWriter, _suffix,_prefix );
01272 
01273     elementWriter.startElement( "number:currency-symbol" );
01274     kDebug(30003)<<" currency-symbol: "<<symbol<<endl;
01275     elementWriter.addTextNode( symbol.toUtf8() );
01276     elementWriter.endElement();
01277 
01278     QString elementContents = QString::fromUtf8( buffer.buffer(), buffer.buffer().size() );
01279     currentStyle.addChildElement( "number", elementContents );
01280     return mainStyles.lookup( currentStyle, "N" );
01281 }
01282 
01283 QString KoOasisStyles::saveOasisTextStyle( KoGenStyles &mainStyles, const QString & _format, const QString &_prefix, const QString &_suffix )
01284 {
01285 
01286     //<number:text-style style:name="N100">
01287     //<number:text-content/>
01289 
01290     kDebug(30003)<<"QString saveOasisTextStyle( KoGenStyles &mainStyles, const QString & _format ) :"<<_format<<endl;
01291     QString format( _format );
01292 
01293     KoGenStyle currentStyle( KoGenStyle::STYLE_NUMERIC_TEXT );
01294     QBuffer buffer;
01295     buffer.open( QIODevice::WriteOnly );
01296     KoXmlWriter elementWriter( &buffer );  // TODO pass indentation level
01297     QString text;
01298     do
01299     {
01300         format.remove( 0,1 );
01301     }
01302     while ( format.length() > 0 );
01303     text =  _prefix ;
01304     addTextNumber(text, elementWriter );
01305 
01306     elementWriter.startElement( "number:text-style" );
01307 
01308     text =  _suffix ;
01309     addTextNumber(text, elementWriter );
01310     addKofficeNumericStyleExtension( elementWriter, _suffix,_prefix );
01311     elementWriter.endElement();
01312 
01313     QString elementContents = QString::fromUtf8( buffer.buffer(), buffer.buffer().size() );
01314     currentStyle.addChildElement( "number", elementContents );
01315     return mainStyles.lookup( currentStyle, "N" );
01316 }
01317 
01318 //This is an extension of numeric style. For the moment we used namespace of 
01319 //oasis format for specific koffice extension. Change it for the future.
01320 void KoOasisStyles::addKofficeNumericStyleExtension( KoXmlWriter & elementWriter, const QString &_suffix, const QString &_prefix )
01321  {
01322      if ( !_suffix.isEmpty() )
01323      {
01324          elementWriter.startElement( "number:suffix" );
01325          elementWriter.addTextNode( _suffix );
01326          elementWriter.endElement();
01327      }
01328      if ( !_prefix.isEmpty() )
01329      {
01330          elementWriter.startElement( "number:prefix" );
01331          elementWriter.addTextNode( _prefix );
01332          elementWriter.endElement();
01333      }
01334 }
01335 
01336 void KoOasisStyles::saveOasisFillStyle( KoGenStyle &styleFill, KoGenStyles& mainStyles, const QBrush & brush )
01337 {
01338     if ( brush.style() == Qt::SolidPattern )
01339     {
01340         styleFill.addProperty( "draw:fill","solid" );
01341         styleFill.addProperty( "draw:fill-color", brush.color().name() );
01342     }
01343     else if ( brush.style() == Qt::Dense1Pattern )
01344     {
01345         styleFill.addProperty( "draw:transparency", "94%" );
01346         styleFill.addProperty( "draw:fill","solid" );
01347         styleFill.addProperty( "draw:fill-color", brush.color().name() );
01348     }
01349     else if ( brush.style() == Qt::Dense2Pattern )
01350     {
01351         styleFill.addProperty( "draw:transparency", "88%" );
01352         styleFill.addProperty( "draw:fill","solid" );
01353         styleFill.addProperty( "draw:fill-color", brush.color().name() );
01354     }
01355     else if ( brush.style() == Qt::Dense3Pattern )
01356     {
01357         styleFill.addProperty( "draw:transparency", "63%" );
01358         styleFill.addProperty( "draw:fill","solid" );
01359         styleFill.addProperty( "draw:fill-color", brush.color().name() );
01360     }
01361     else if ( brush.style() == Qt::Dense4Pattern )
01362     {
01363         styleFill.addProperty( "draw:transparency", "50%" );
01364         styleFill.addProperty( "draw:fill","solid" );
01365         styleFill.addProperty( "draw:fill-color", brush.color().name() );
01366     }
01367     else if ( brush.style() == Qt::Dense5Pattern )
01368     {
01369         styleFill.addProperty( "draw:transparency", "37%" );
01370         styleFill.addProperty( "draw:fill","solid" );
01371         styleFill.addProperty( "draw:fill-color", brush.color().name() );
01372     }
01373     else if ( brush.style() == Qt::Dense6Pattern )
01374     {
01375         styleFill.addProperty( "draw:transparency", "12%" );
01376         styleFill.addProperty( "draw:fill","solid" );
01377         styleFill.addProperty( "draw:fill-color", brush.color().name() );
01378     }
01379     else if ( brush.style() == Qt::Dense7Pattern )
01380     {
01381         styleFill.addProperty( "draw:transparency", "6%" );
01382         styleFill.addProperty( "draw:fill","solid" );
01383         styleFill.addProperty( "draw:fill-color", brush.color().name() );
01384     }
01385     else //otherstyle
01386     {
01387         styleFill.addProperty( "draw:fill","hatch" );
01388         styleFill.addProperty( "draw:fill-hatch-name", saveOasisHatchStyle( mainStyles,brush ) );
01389     }
01390 
01391 }
01392 
01393 QString KoOasisStyles::saveOasisHatchStyle( KoGenStyles& mainStyles, const QBrush &brush )
01394 {
01395     KoGenStyle hatchStyle( KoGenStyle::STYLE_HATCH /*no family name*/);
01396     hatchStyle.addAttribute( "draw:color", brush.color().name() );
01397     //hatchStyle.addAttribute( "draw:distance", m_distance ); not implemented into kpresenter
01398     switch( brush.style() )
01399     {
01400     case Qt::HorPattern:
01401         hatchStyle.addAttribute( "draw:style", "single" );
01402         hatchStyle.addAttribute( "draw:rotation", 0);
01403         break;
01404     case Qt::BDiagPattern:
01405         hatchStyle.addAttribute( "draw:style", "single" );
01406         hatchStyle.addAttribute( "draw:rotation", 450);
01407         break;
01408     case Qt::VerPattern:
01409         hatchStyle.addAttribute( "draw:style", "single" );
01410         hatchStyle.addAttribute( "draw:rotation", 900);
01411         break;
01412     case Qt::FDiagPattern:
01413         hatchStyle.addAttribute( "draw:style", "single" );
01414         hatchStyle.addAttribute( "draw:rotation", 1350);
01415         break;
01416     case Qt::CrossPattern:
01417         hatchStyle.addAttribute( "draw:style", "double" );
01418         hatchStyle.addAttribute( "draw:rotation", 0);
01419         break;
01420     case Qt::DiagCrossPattern:
01421         hatchStyle.addAttribute( "draw:style", "double" );
01422         hatchStyle.addAttribute( "draw:rotation", 450);
01423         break;
01424     default:
01425         break;
01426     }
01427 
01428     return mainStyles.lookup( hatchStyle, "hatch" );
01429 }
01430 
01431 QBrush KoOasisStyles::loadOasisFillStyle( const KoStyleStack &styleStack, const QString & fill, const KoOasisStyles & oasisStyles )
01432 {
01433     QBrush tmpBrush;
01434     if ( fill == "solid" )
01435     {
01436         tmpBrush.setStyle(static_cast<Qt::BrushStyle>( 1 ) );
01437         if ( styleStack.hasAttributeNS( KoXmlNS::draw, "fill-color" ) )
01438             tmpBrush.setColor(styleStack.attributeNS( KoXmlNS::draw, "fill-color" ) );
01439         if ( styleStack.hasAttributeNS( KoXmlNS::draw, "transparency" ) )
01440         {
01441             QString transparency = styleStack.attributeNS( KoXmlNS::draw, "transparency" );
01442             if ( transparency == "94%" )
01443             {
01444                 tmpBrush.setStyle(Qt::Dense1Pattern);
01445             }
01446             else if ( transparency == "88%" )
01447             {
01448                 tmpBrush.setStyle(Qt::Dense2Pattern);
01449             }
01450             else if ( transparency == "63%" )
01451             {
01452                 tmpBrush.setStyle(Qt::Dense3Pattern);
01453 
01454             }
01455             else if ( transparency == "50%" )
01456             {
01457                 tmpBrush.setStyle(Qt::Dense4Pattern);
01458 
01459             }
01460             else if ( transparency == "37%" )
01461             {
01462                 tmpBrush.setStyle(Qt::Dense5Pattern);
01463 
01464             }
01465             else if ( transparency == "12%" )
01466             {
01467                 tmpBrush.setStyle(Qt::Dense6Pattern);
01468 
01469             }
01470             else if ( transparency == "6%" )
01471             {
01472                 tmpBrush.setStyle(Qt::Dense7Pattern);
01473 
01474             }
01475             else
01476                 kDebug(30003)<<" transparency is not defined into kpresenter :"<<transparency<<endl;
01477         }
01478     }
01479     else if ( fill == "hatch" )
01480     {
01481         QString style = styleStack.attributeNS( KoXmlNS::draw, "fill-hatch-name" );
01482         kDebug(30003)<<" hatch style is  : "<<style<<endl;
01483 
01484         //type not defined by default
01485         //try to use style.
01486         KoXmlElement* draw = oasisStyles.drawStyles()[style];
01487         if ( draw)
01488         {
01489             kDebug(30003)<<"We have a style\n";
01490             int angle = 0;
01491             if( draw->hasAttributeNS( KoXmlNS::draw, "rotation" ))
01492             {
01493                 angle = (draw->attributeNS( KoXmlNS::draw, "rotation", QString::null ).toInt())/10;
01494                 kDebug(30003)<<"angle :"<<angle<<endl;
01495             }
01496             if(draw->hasAttributeNS( KoXmlNS::draw, "color" ) )
01497             {
01498                 //kDebug(30003)<<" draw:color :"<<draw->attributeNS( KoXmlNS::draw, "color", QString::null )<<endl;
01499                 tmpBrush.setColor(draw->attributeNS( KoXmlNS::draw, "color", QString::null ) );
01500             }
01501             if( draw->hasAttributeNS( KoXmlNS::draw, "distance" ))
01502             {
01503                 //todo implemente it into kpresenter
01504             }
01505             if( draw->hasAttributeNS( KoXmlNS::draw, "display-name"))
01506             {
01507                 //todo implement it into kpresenter
01508             }
01509             if( draw->hasAttributeNS( KoXmlNS::draw, "style" ))
01510             {
01511                 //todo implemente it into kpresenter
01512                 QString styleHash = draw->attributeNS( KoXmlNS::draw, "style", QString::null );
01513                 if( styleHash == "single")
01514                 {
01515                     switch( angle )
01516                     {
01517                     case 0:
01518                     case 180:
01519                         tmpBrush.setStyle(Qt::HorPattern );
01520                         break;
01521                     case 45:
01522                     case 225:
01523                         tmpBrush.setStyle(Qt::BDiagPattern );
01524                         break;
01525                     case 90:
01526                     case 270:
01527                         tmpBrush.setStyle(Qt::VerPattern );
01528                         break;
01529                     case 135:
01530                     case 315:
01531                         tmpBrush.setStyle(Qt::FDiagPattern );
01532                         break;
01533                     default:
01534                         //todo fixme when we will have a kopaint
01535                         kDebug(30003)<<" draw:rotation 'angle' : "<<angle<<endl;
01536                         break;
01537                     }
01538                 }
01539                 else if( styleHash == "double")
01540                 {
01541                     switch( angle )
01542                     {
01543                     case 0:
01544                     case 180:
01545                     case 90:
01546                     case 270:
01547                         tmpBrush.setStyle(Qt::CrossPattern );
01548                         break;
01549                     case 45:
01550                     case 135:
01551                     case 225:
01552                     case 315:
01553                         tmpBrush.setStyle(Qt::DiagCrossPattern );
01554                         break;
01555                     default:
01556                         //todo fixme when we will have a kopaint
01557                         kDebug(30003)<<" draw:rotation 'angle' : "<<angle<<endl;
01558                         break;
01559                     }
01560 
01561                 }
01562                 else if( styleHash == "triple")
01563                 {
01564                     kDebug(30003)<<" it is not implemented :( \n";
01565                 }
01566             }
01567         }
01568     }
01569     return tmpBrush;
01570 }
01571 
01572 const KoXmlElement* KoOasisStyles::defaultStyle( const QString& family ) const
01573 {
01574     return m_defaultStyle[family];
01575 }
01576 
01577 const KoXmlElement* KoOasisStyles::findStyle( const QString& name ) const
01578 {
01579     return m_styles[ name ];
01580 }
01581 
01582 const KoXmlElement* KoOasisStyles::findStyle( const QString& styleName, const QString& family ) const
01583 {
01584     const KoXmlElement* style = d->m_styles[ family ][ styleName ];
01585     if ( style && !family.isEmpty() ) {
01586         const QString styleFamily = style->attributeNS( KoXmlNS::style, "family", QString::null );
01587         if ( styleFamily != family ) {
01588             kWarning() << "KoOasisStyles: was looking for style " << styleName
01589                         << " in family " << family << " but got " << styleFamily << endl;
01590         }
01591     }
01592     return style;
01593 }
01594 
01595 const KoXmlElement* KoOasisStyles::findStyleAutoStyle( const QString& styleName, const QString& family ) const
01596 {
01597     const KoXmlElement* style = d->m_stylesAutoStyles[ family ][ styleName ];
01598     if ( style ) {
01599         const QString styleFamily = style->attributeNS( KoXmlNS::style, "family", QString::null );
01600         if ( styleFamily != family ) {
01601             kWarning() << "KoOasisStyles: was looking for style " << styleName
01602                         << " in family " << family << " but got " << styleFamily << endl;
01603         }
01604     }
01605     return style;
01606 }

Généré le Wed Nov 22 23:41:03 2006 pour KPlato par  doxygen 1.5.1-p1