lib

KoOasisStyles.cpp

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