kspread

kspread_style.cc

00001 /* This file is part of the KDE project
00002    Copyright (C) 2003 Norbert Andres, nandres@web.de
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 as published by the Free Software Foundation; either
00007    version 2 of the License, or (at your option) any later version.
00008 
00009    This library is distributed in the hope that it will be useful,
00010    but WITHOUT ANY WARRANTY; without even the implied warranty of
00011    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012    Library General Public License for more details.
00013 
00014    You should have received a copy of the GNU Library General Public License
00015    along with this library; see the file COPYING.LIB.  If not, write to
00016    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00017  * Boston, MA 02110-1301, USA.
00018 */
00019 
00020 #include <qdom.h>
00021 #include <qbuffer.h>
00022 
00023 #include <kdebug.h>
00024 #include <klocale.h>
00025 
00026 #include <KoGlobal.h>
00027 #include <KoGenStyles.h>
00028 #include <KoOasisStyles.h>
00029 #include <KoStyleStack.h>
00030 #include <KoXmlWriter.h>
00031 #include <KoXmlNS.h>
00032 
00033 #include "kspread_util.h"
00034 #include "kspread_doc.h"
00035 
00036 #include "kspread_style.h"
00037 
00038 using namespace KSpread;
00039 
00040 static uint calculateValue( QPen const & pen )
00041 {
00042   uint n = pen.color().red() + pen.color().green() + pen.color().blue();
00043 
00044   n += 1000 * pen.width();
00045   n += 10000 * (uint) pen.style();
00046 
00047   return n;
00048 }
00049 
00050 Style::Style()
00051   : m_parent( 0 ),
00052     m_type( AUTO ),
00053     m_usageCount( 1 ),
00054     m_featuresSet( 0 ),
00055     m_alignX( Format::Undefined ),
00056     m_alignY( Format::Middle ),
00057     m_floatFormat( Format::OnlyNegSigned ),
00058     m_floatColor( Format::AllBlack ),
00059     m_formatType( Generic_format ),
00060     m_fontFlags( 0 ),
00061     m_bgColor( Qt::white ),
00062     m_backGroundBrush( Qt::red, Qt::NoBrush ),
00063     m_rotateAngle( 0 ),
00064     m_indent( 0.0 ),
00065     m_precision( -1 ),
00066     m_properties( 0 )
00067 {
00068   QFont f( KoGlobal::defaultFont() );
00069   m_fontFamily = f.family();
00070   m_fontSize = f.pointSize();
00071 
00072   QPen pen( Qt::black, 1, Qt::NoPen );
00073 
00074   m_textPen         = pen;
00075   m_leftBorderPen   = pen;
00076   m_topBorderPen    = pen;
00077   m_rightBorderPen  = pen;
00078   m_bottomBorderPen = pen;
00079   m_fallDiagonalPen = pen;
00080   m_goUpDiagonalPen = pen;
00081 
00082   m_leftPenValue    = calculateValue( pen );
00083   m_topPenValue     = calculateValue( pen );
00084   m_rightPenValue   = calculateValue( pen );
00085   m_bottomPenValue  = calculateValue( pen );
00086 
00087   m_currency.type   = 0;
00088 }
00089 
00090 Style::Style( Style * style )
00091   : m_parent( ( style->m_type == BUILTIN || style->m_type == CUSTOM ) ? (CustomStyle *) style : 0 ),
00092     m_type( AUTO ),
00093     m_usageCount( 1 ),
00094     m_featuresSet( ( style->m_type == BUILTIN || style->m_type == CUSTOM ) ? 0 : style->m_featuresSet ),
00095     m_alignX( style->m_alignX ),
00096     m_alignY( style->m_alignY ),
00097     m_floatFormat( style->m_floatFormat ),
00098     m_floatColor( style->m_floatColor ),
00099     m_formatType( style->m_formatType ),
00100     m_fontFamily( style->m_fontFamily ),
00101     m_fontFlags( style->m_fontFlags ),
00102     m_fontSize( style->m_fontSize ),
00103     m_textPen( style->m_textPen ),
00104     m_bgColor( style->m_bgColor ),
00105     m_rightBorderPen( style->m_rightBorderPen ),
00106     m_bottomBorderPen( style->m_bottomBorderPen ),
00107     m_leftBorderPen( style->m_leftBorderPen ),
00108     m_topBorderPen( style->m_topBorderPen ),
00109     m_fallDiagonalPen( style->m_fallDiagonalPen ),
00110     m_goUpDiagonalPen( style->m_goUpDiagonalPen ),
00111     m_backGroundBrush( style->m_backGroundBrush ),
00112     m_rotateAngle( style->m_rotateAngle ),
00113     m_indent( style->m_indent ),
00114     m_strFormat( style->m_strFormat ),
00115     m_precision( style->m_precision ),
00116     m_prefix( style->m_prefix ),
00117     m_postfix( style->m_postfix ),
00118     m_currency( style->m_currency ),
00119     m_properties( style->m_properties )
00120 {
00121 }
00122 
00123 Style::~Style()
00124 {
00125 }
00126 
00127 bool Style::operator == (const Style& style) const
00128 {
00129     //This is prone to error because if someone adds additional
00130     //properties to the style class they will have to remember
00131     //to correct this function - can we do this a better way?
00132   if ( m_featuresSet != style.m_featuresSet )
00133     return false;
00134   if ( m_type != style.m_type )
00135     return false;
00136   // NOTE Stefan: Only compare the values of the set features.
00137   if ( // layout (4)
00138        ( m_featuresSet & SAlignX ) && ( m_alignX != style.m_alignX ) ||
00139        ( m_featuresSet & SAlignY ) && ( m_alignY != style.m_alignY ) ||
00140        ( m_featuresSet & SAngle )  && ( m_rotateAngle != style.m_rotateAngle ) ||
00141        ( m_featuresSet & SIndent ) && ( m_indent != style.m_indent ) ||
00142        // background (2)
00143        ( m_featuresSet & SBackgroundColor ) && ( m_bgColor != style.m_bgColor ) ||
00144        ( m_featuresSet & SBackgroundBrush ) && ( m_backGroundBrush != style.m_backGroundBrush ) ||
00145        // borders (6)
00146        ( m_featuresSet & SRightBorder )  && ( m_rightBorderPen != style.m_rightBorderPen ) ||
00147        ( m_featuresSet & SBottomBorder ) && ( m_bottomBorderPen != style.m_bottomBorderPen ) ||
00148        ( m_featuresSet & SLeftBorder )   && ( m_leftBorderPen != style.m_leftBorderPen ) ||
00149        ( m_featuresSet & STopBorder )    && ( m_topBorderPen != style.m_topBorderPen ) ||
00150        ( m_featuresSet & SFallDiagonal ) && ( m_fallDiagonalPen != style.m_fallDiagonalPen ) ||
00151        ( m_featuresSet & SGoUpDiagonal ) && ( m_goUpDiagonalPen != style.m_goUpDiagonalPen ) ||
00152        // format (7) (SFormatType twice)
00153        ( m_featuresSet & SPrecision )    && ( m_precision != style.m_precision ) ||
00154        ( m_featuresSet & SPrefix )       && ( m_prefix != style.m_prefix ) ||
00155        ( m_featuresSet & SPostfix )      && ( m_postfix != style.m_postfix ) ||
00156        ( m_featuresSet & SFloatFormat )  && ( m_floatFormat != style.m_floatFormat ) ||
00157        ( m_featuresSet & SFloatColor )   && ( m_floatColor != style.m_floatColor ) ||
00158        ( m_featuresSet & SFormatType )   && ( m_formatType != style.m_formatType ) ||
00159        ( m_featuresSet & SFormatType )   && ( m_currency.type != style.m_currency.type ) ||
00160        ( m_featuresSet & SCustomFormat ) && ( m_strFormat != style.m_strFormat ) ||
00161        // font (4)
00162        ( m_featuresSet & SFontFamily ) && ( m_fontFamily != style.m_fontFamily ) ||
00163        ( m_featuresSet & SFontFlag )   && ( m_fontFlags != style.m_fontFlags ) ||
00164        ( m_featuresSet & SFontSize )   && ( m_fontSize != style.m_fontSize ) ||
00165        ( m_featuresSet & STextPen )    && ( m_textPen != style.m_textPen ) )
00166   {
00167     return false;
00168   }
00169   // Properties (7)
00170   const uint differingProperties = m_properties xor style.m_properties;
00171   if ( ( m_featuresSet & SDontPrintText ) && ( differingProperties & PDontPrintText ) ||
00172        ( m_featuresSet & SCustomFormat )  && ( differingProperties & PCustomFormat ) ||
00173        ( m_featuresSet & SNotProtected )  && ( differingProperties & PNotProtected ) ||
00174        ( m_featuresSet & SHideAll )       && ( differingProperties & PHideAll ) ||
00175        ( m_featuresSet & SHideFormula )   && ( differingProperties & PHideFormula ) ||
00176        ( m_featuresSet & SMultiRow )      && ( differingProperties & PMultiRow ) ||
00177        ( m_featuresSet & SVerticalText )  && ( differingProperties & PVerticalText ) )
00178   {
00179     return false;
00180   }
00181   return true;
00182 }
00183 
00184 void Style::loadOasisStyle( KoOasisStyles& oasisStyles, const QDomElement & element )
00185 {
00186   // NOTE Stefan: Don't fill the style stack with the parent styles!
00187   KoStyleStack styleStack;
00188   styleStack.push( element );
00189   styleStack.setTypeProperties( "table-cell" );
00190   loadOasisTableCellProperties( oasisStyles, styleStack );
00191   styleStack.setTypeProperties( "text" );
00192   loadOasisTextProperties( oasisStyles, styleStack );
00193   styleStack.setTypeProperties( "paragraph" );
00194   loadOasisParagraphProperties( oasisStyles, styleStack );
00195 
00196   loadOasisDataStyle( oasisStyles, element );
00197 }
00198 
00199 void Style::loadOasisDataStyle( KoOasisStyles& oasisStyles, const QDomElement& element )
00200 {
00201   QString str;
00202   if ( element.hasAttributeNS( KoXmlNS::style, "data-style-name" ) )
00203   {
00204 //     kdDebug()<<"element.attribute( style:data-style-name ) :"<<element.attributeNS( KoXmlNS::style, "data-style-name", QString::null )<<endl;
00205 //     kdDebug()<< " oasisStyles.dataFormats()[...] :"<< oasisStyles.dataFormats()[element.attributeNS( KoXmlNS::style, "data-style-name" , QString::null)].formatStr<<endl;
00206 //     kdDebug()<< " oasisStyles.dataFormats()[...] prefix :"<< oasisStyles.dataFormats()[element.attributeNS( KoXmlNS::style, "data-style-name" , QString::null)].prefix<<endl;
00207 //     kdDebug()<< " oasisStyles.dataFormats()[...] suffix :"<< oasisStyles.dataFormats()[element.attributeNS( KoXmlNS::style, "data-style-name" , QString::null)].suffix<<endl;
00208 
00209     const QString styleName = element.attributeNS( KoXmlNS::style, "data-style-name", QString::null );
00210     if ( oasisStyles.dataFormats().contains(styleName) )
00211     {
00212       const KoOasisStyles::NumericStyleFormat dataStyle = oasisStyles.dataFormats()[styleName];
00213 
00214       QString tmp = dataStyle.prefix;
00215       if ( !tmp.isEmpty() )
00216       {
00217         m_prefix = tmp;
00218         m_featuresSet |= SPrefix;
00219       }
00220       tmp = dataStyle.suffix;
00221       if ( !tmp.isEmpty() )
00222       {
00223         m_postfix = tmp;
00224         m_featuresSet |= SPostfix;
00225       }
00226       // determine data formatting
00227       switch (dataStyle.type)
00228       {
00229         case KoOasisStyles::NumericStyleFormat::Number:
00230           m_formatType = Number_format;
00231           m_featuresSet |= SFormatType;
00232           break;
00233         case KoOasisStyles::NumericStyleFormat::Scientific:
00234           m_formatType = Scientific_format;
00235           m_featuresSet |= SFormatType;
00236           break;
00237         case KoOasisStyles::NumericStyleFormat::Currency:
00238           kdDebug() << " currency-symbol: " << dataStyle.currencySymbol << endl;
00239           if (!dataStyle.currencySymbol.isEmpty())
00240           {
00241             Currency currency(dataStyle.currencySymbol);
00242             m_currency.type = currency.getIndex();
00243             m_currency.symbol = currency.getDisplayCode();
00244           }
00245           m_formatType = Money_format;
00246           m_featuresSet |= SFormatType;
00247           break;
00248         case KoOasisStyles::NumericStyleFormat::Percentage:
00249           m_formatType = Percentage_format;
00250           m_featuresSet |= SFormatType;
00251           break;
00252         case KoOasisStyles::NumericStyleFormat::Fraction:
00253           // determine format of fractions, dates and times by using the
00254           // formatting string
00255           tmp = dataStyle.formatStr;
00256           if ( !tmp.isEmpty() )
00257           {
00258             m_formatType = Style::fractionType( tmp );
00259             m_featuresSet |= SFormatType;
00260           }
00261           break;
00262         case KoOasisStyles::NumericStyleFormat::Date:
00263           // determine format of fractions, dates and times by using the
00264           // formatting string
00265           tmp = dataStyle.formatStr;
00266           if ( !tmp.isEmpty() )
00267           {
00268             m_formatType = Style::dateType( tmp );
00269             m_featuresSet |= SFormatType;
00270           }
00271           break;
00272         case KoOasisStyles::NumericStyleFormat::Time:
00273           // determine format of fractions, dates and times by using the
00274           // formatting string
00275           tmp = dataStyle.formatStr;
00276           if ( !tmp.isEmpty() )
00277           {
00278             m_formatType = Style::timeType( tmp );
00279             m_featuresSet |= SFormatType;
00280           }
00281           break;
00282         case KoOasisStyles::NumericStyleFormat::Boolean:
00283           m_formatType = Number_format;
00284           m_featuresSet |= SFormatType;
00285           break;
00286         case KoOasisStyles::NumericStyleFormat::Text:
00287           m_formatType = Text_format;
00288           m_featuresSet |= SFormatType;
00289           break;
00290       }
00291 
00292       if (dataStyle.precision > -1)
00293       {
00294         m_precision = dataStyle.precision;
00295         m_featuresSet |= SPrecision;
00296       }
00297     }
00298   }
00299 }
00300 
00301 void Style::loadOasisParagraphProperties( KoOasisStyles& oasisStyles, const KoStyleStack& styleStack )
00302 {
00303   Q_UNUSED( oasisStyles );
00304   kdDebug() << "\t paragraph-properties" << endl;
00305   if ( styleStack.hasAttributeNS( KoXmlNS::fo, "text-align" ) )
00306   {
00307     QString str = styleStack.attributeNS( KoXmlNS::fo, "text-align" );
00308     if ( str == "center" )
00309       m_alignX = Format::Center;
00310     else if ( str == "end" )
00311       m_alignX = Format::Right;
00312     else if ( str == "start" )
00313       m_alignX = Format::Left;
00314     else
00315       m_alignX = Format::Undefined;
00316     m_featuresSet |= SAlignX;
00317     kdDebug() << "\t\t text-align: " << str << endl;
00318   }
00319 }
00320 
00321 void Style::loadOasisTableCellProperties( KoOasisStyles& oasisStyles, const KoStyleStack& styleStack )
00322 {
00323   QString str;
00324   if ( styleStack.hasAttributeNS( KoXmlNS::style, "vertical-align" ) )
00325   {
00326     m_alignY = Format::UndefinedY;
00327 
00328     str = styleStack.attributeNS( KoXmlNS::style, "vertical-align" );
00329     if ( str == "bottom" )
00330       m_alignY = Format::Bottom;
00331     else if ( str =="top" )
00332       m_alignY = Format::Top;
00333     else if ( str =="middle" )
00334       m_alignY = Format::Middle;
00335 
00336     if (m_alignY != Format::UndefinedY) // file's property is invalid
00337       m_featuresSet |= SAlignY;
00338   }
00339   if ( styleStack.hasAttributeNS( KoXmlNS::fo, "background-color" ) )
00340   {
00341     m_bgColor = QColor(  styleStack.attributeNS( KoXmlNS::fo, "background-color" ) );
00342     if ( m_bgColor.isValid() && m_bgColor != Qt::white )
00343       m_featuresSet |= SBackgroundColor;
00344   }
00345 
00346   if ( styleStack.hasAttributeNS( KoXmlNS::fo, "wrap-option" )&&( styleStack.attributeNS( KoXmlNS::fo, "wrap-option" )=="wrap" ) )
00347   {
00348     setProperty( PMultiRow );
00349     m_featuresSet |= SMultiRow;
00350   }
00351   if ( styleStack.hasAttributeNS( KoXmlNS::style, "cell-protect" ) )
00352   {
00353     str = styleStack.attributeNS( KoXmlNS::style, "cell-protect" );
00354     if ( str=="hidden-and-protected" )
00355     {
00356       setProperty( PHideAll );
00357       m_featuresSet |= SHideAll;
00358     }
00359     else if ( str == "protected formula-hidden" )
00360     {
00361       setProperty( PHideFormula );
00362       m_featuresSet |= SHideFormula;
00363     }
00364     else if ( str == "protected" )
00365     {
00366       setProperty( PNotProtected );
00367       m_featuresSet |= SNotProtected;
00368     }
00369     else if ( str =="formula-hidden" )
00370     {
00371             //FIXME !!!!
00372 #if 0
00373             setNotProtected( true );
00374             setHideFormula( true );
00375             setHideAll( false );
00376 #endif
00377     }
00378   }
00379   if ( styleStack.hasAttributeNS( KoXmlNS::style, "print-content" ) && ( styleStack.attributeNS( KoXmlNS::style, "print-content" )=="false" ) )
00380   {
00381     setProperty( PDontPrintText );
00382     m_featuresSet |= SDontPrintText;
00383 
00384   }
00385   if ( styleStack.hasAttributeNS( KoXmlNS::style, "direction" ) && ( styleStack.attributeNS( KoXmlNS::style, "direction" )=="ttb" ) )
00386   {
00387     setProperty( PVerticalText );
00388     m_featuresSet |= SVerticalText;
00389 
00390   }
00391   if ( styleStack.hasAttributeNS( KoXmlNS::style, "rotation-angle" ) )
00392   {
00393     bool ok;
00394     int a = styleStack.attributeNS( KoXmlNS::style, "rotation-angle" ).toInt( &ok );
00395     kdDebug()<<" rotation-angle :"<<a<<endl;
00396     if ( a != 0 )
00397     {
00398       m_rotateAngle= ( -a  );
00399       m_featuresSet |= SAngle;
00400     }
00401   }
00402   if ( styleStack.hasAttributeNS( KoXmlNS::fo, "margin-left" ) )
00403   {
00404         //todo fix me
00405     setIndent( KoUnit::parseValue( styleStack.attributeNS( KoXmlNS::fo, "margin-left" ),0.0 ) );
00406     m_featuresSet |= SIndent;
00407   }
00408   if ( styleStack.hasAttributeNS( KoXmlNS::fo, "border" ) )
00409   {
00410     str=styleStack.attributeNS( KoXmlNS::fo, "border" );
00411     QPen pen = convertOasisStringToPen( str );
00412     m_featuresSet |= SLeftBorder;
00413     m_featuresSet |= SRightBorder;
00414     m_featuresSet |= STopBorder;
00415     m_featuresSet |= SBottomBorder;
00416     m_leftBorderPen = pen;
00417     m_topBorderPen = pen;
00418     m_bottomBorderPen = pen;
00419     m_rightBorderPen = pen;
00420   }
00421   if ( styleStack.hasAttributeNS( KoXmlNS::fo, "border-left" ) )
00422   {
00423     str=styleStack.attributeNS( KoXmlNS::fo, "border-left" );
00424     m_leftBorderPen = convertOasisStringToPen( str );
00425     m_featuresSet |= SLeftBorder;
00426   }
00427   if ( styleStack.hasAttributeNS( KoXmlNS::fo, "border-right" ) )
00428   {
00429     str=styleStack.attributeNS( KoXmlNS::fo, "border-right" );
00430     m_rightBorderPen = convertOasisStringToPen( str );
00431     m_featuresSet |= SRightBorder;
00432   }
00433   if ( styleStack.hasAttributeNS( KoXmlNS::fo, "border-top" ) )
00434   {
00435     str=styleStack.attributeNS( KoXmlNS::fo, "border-top" );
00436     m_topBorderPen = convertOasisStringToPen( str );
00437     m_featuresSet |= STopBorder;
00438   }
00439   if ( styleStack.hasAttributeNS( KoXmlNS::fo, "border-bottom" ) )
00440   {
00441     str=styleStack.attributeNS( KoXmlNS::fo, "border-bottom" );
00442     m_bottomBorderPen = convertOasisStringToPen( str );
00443     m_featuresSet |= SBottomBorder;
00444   }
00445   if (styleStack.hasAttributeNS( KoXmlNS::style, "diagonal-tl-br" ) )
00446   {
00447     str=styleStack.attributeNS( KoXmlNS::style, "diagonal-tl-br" );
00448     m_fallDiagonalPen = convertOasisStringToPen( str );
00449     m_featuresSet |= SFallDiagonal;
00450   }
00451   if (styleStack.hasAttributeNS( KoXmlNS::style, "diagonal-bl-tr" ) )
00452   {
00453     str=styleStack.attributeNS( KoXmlNS::style, "diagonal-bl-tr" );
00454     m_goUpDiagonalPen = convertOasisStringToPen( str );
00455     m_featuresSet |= SGoUpDiagonal;
00456   }
00457 
00458   if ( styleStack.hasAttributeNS( KoXmlNS::draw, "style-name" ) )
00459   {
00460     kdDebug()<<" style name :"<<styleStack.attributeNS( KoXmlNS::draw, "style-name" )<<endl;
00461 
00462     const QDomElement * style = oasisStyles.findStyle( styleStack.attributeNS( KoXmlNS::draw, "style-name" ), "graphic" );
00463     kdDebug()<<" style :"<<style<<endl;
00464     if ( style )
00465     {
00466       KoStyleStack drawStyleStack;
00467       drawStyleStack.push( *style );
00468       drawStyleStack.setTypeProperties( "graphic" );
00469       if ( drawStyleStack.hasAttributeNS( KoXmlNS::draw, "fill" ) )
00470       {
00471         const QString fill = drawStyleStack.attributeNS( KoXmlNS::draw, "fill" );
00472         kdDebug()<<" load object gradient fill type :"<<fill<<endl;
00473 
00474         if ( fill == "solid" || fill == "hatch" )
00475         {
00476           kdDebug()<<" Style ******************************************************\n";
00477           m_backGroundBrush=KoOasisStyles::loadOasisFillStyle( drawStyleStack, fill, oasisStyles );
00478           m_featuresSet |= SBackgroundBrush;
00479         }
00480         else
00481           kdDebug()<<" fill style not supported into kspread : "<<fill<<endl;
00482       }
00483     }
00484   }
00485 }
00486 
00487 void Style::loadOasisTextProperties( KoOasisStyles& oasisStyles, const KoStyleStack& styleStack )
00488 {
00489   Q_UNUSED( oasisStyles );
00490   // fo:font-size="13pt"
00491   // fo:font-style="italic"
00492   // style:text-underline="double"
00493   // style:text-underline-color="font-color"
00494   // fo:font-weight="bold"
00495   kdDebug() << "\t text-properties" << endl;
00496   if ( styleStack.hasAttributeNS( KoXmlNS::fo, "font-family" ) )
00497   {
00498     m_fontFamily = styleStack.attributeNS( KoXmlNS::fo, "font-family" ); // FIXME Stefan: sanity check
00499     m_featuresSet |= SFontFamily;
00500     m_featuresSet |= SFont;
00501     kdDebug() << "\t\t fo:font-family: " << m_fontFamily << endl;
00502   }
00503   if ( styleStack.hasAttributeNS( KoXmlNS::fo, "font-size" ) )
00504   {
00505     m_fontSize = (int) KoUnit::parseValue( styleStack.attributeNS( KoXmlNS::fo, "font-size" ), 10.0 ); // FIXME Stefan: fallback to default
00506     m_featuresSet |= SFontSize;
00507     m_featuresSet |= SFont;
00508     kdDebug() << "\t\t fo:font-size: " << m_fontSize << endl;
00509   }
00510   if ( styleStack.hasAttributeNS( KoXmlNS::fo, "font-style" ) )
00511   {
00512     if ( styleStack.attributeNS( KoXmlNS::fo, "font-style" ) == "italic" ) // "normal", "oblique"
00513     {
00514       m_fontFlags |= FItalic;
00515       m_featuresSet |= SFontFlag;
00516       m_featuresSet |= SFont;
00517       kdDebug() << "\t\t fo:font-style: " << "italic" << endl;
00518     }
00519   }
00520   if ( styleStack.hasAttributeNS( KoXmlNS::fo, "font-weight" ) )
00521   {
00522     if ( styleStack.attributeNS( KoXmlNS::fo, "font-weight" ) == "bold" ) // "normal", "100", "200", ...
00523     {
00524       m_fontFlags |= FBold;
00525       m_featuresSet |= SFontFlag;
00526       m_featuresSet |= SFont;
00527       kdDebug() << "\t\t fo:font-weight: " << "bold" << endl;
00528     }
00529   }
00530   if ( styleStack.hasAttributeNS( KoXmlNS::style, "text-underline-style" ) )
00531   {
00532     if ( styleStack.attributeNS( KoXmlNS::style, "text-underline-style" ) != "none" )
00533     {
00534       m_fontFlags |= FUnderline;
00535       m_featuresSet |= SFontFlag;
00536       m_featuresSet |= SFont;
00537       kdDebug() << "\t\t style:text-underline-style: " << "solid (actually: !none)" << endl;
00538     }
00539   }
00540   if ( styleStack.hasAttributeNS( KoXmlNS::style, "text-underline-width" ) )
00541   {
00542         //TODO
00543   }
00544   if ( styleStack.hasAttributeNS( KoXmlNS::style, "text-underline-color" ) )
00545   {
00546         //TODO
00547   }
00548   if ( styleStack.hasAttributeNS( KoXmlNS::fo, "color" ) )
00549   {
00550     QColor color = QColor( styleStack.attributeNS( KoXmlNS::fo, "color" ) );
00551     if ( color.isValid() )
00552     {
00553       m_featuresSet |= STextPen;
00554       m_textPen = QPen( color );
00555       kdDebug() << "\t\t fo:color: " << color.name() << endl;
00556     }
00557   }
00558   if ( styleStack.hasAttributeNS( KoXmlNS::style, "text-line-through-style" ) )
00559   {
00560     if ( styleStack.attributeNS( KoXmlNS::style, "text-line-through-style" ) != "none"
00561          /*&& styleStack.attributeNS("text-line-through-style")=="solid"*/ )
00562     {
00563       m_fontFlags |= FStrike;
00564       m_featuresSet |= SFontFlag;
00565       m_featuresSet |= SFont;
00566       kdDebug() << "\t\t text-line-through-style: " << "solid (actually: !none)" << endl;
00567     }
00568   }
00569 }
00570 
00571 static QString convertDateFormat( const QString& date )
00572 {
00573   QString result = date;
00574   result.replace( "%Y", "yyyy" );
00575   result.replace( "%y", "yy" );
00576   result.replace( "%n", "M" );
00577   result.replace( "%m", "MM" );
00578   result.replace( "%e", "d" );
00579   result.replace( "%d", "dd" );
00580   result.replace( "%b", "MMM" );
00581   result.replace( "%B", "MMMM" );
00582   result.replace( "%a", "ddd" );
00583   result.replace( "%A", "dddd" );
00584   return result;
00585 }
00586 
00587 FormatType Style::dateType( const QString &_format )
00588 {
00589     const QString dateFormatShort = convertDateFormat( KGlobal::locale()->dateFormatShort() );
00590     const QString dateFormat = convertDateFormat( KGlobal::locale()->dateFormat() );
00591 
00592     if ( _format == "dd-MMM-yy" )
00593         return date_format1;
00594     else if ( _format == "dd-MMM-yyyy" )
00595         return date_format2;
00596     else if ( _format == "d-MM" )
00597         return date_format3;
00598     else if ( _format == "dd-MM" ) //TODO ???????
00599         return date_format4;
00600     else if ( _format == "dd/MM/yy" )
00601         return date_format5;
00602     else if ( _format == "dd/MM/yyyy" )
00603         return date_format6;
00604     else if ( _format == "MMM-yy" )
00605         return date_format7;
00606     else if ( _format == "MMMM-yyyy" )
00607         return date_format9;
00608     else if ( _format == "MMMMM-yy" )
00609         return date_format10;
00610     else if ( _format == "dd/MMM" )
00611         return date_format11;
00612     else if ( _format == "dd/MM" )
00613         return date_format12;
00614     else if ( _format == "dd/MMM/yyyy" )
00615         return date_format13;
00616     else if ( _format == "yyyy/MMM/dd" )
00617         return date_format14;
00618     else if ( _format == "yyyy-MMM-dd" )
00619         return date_format15;
00620     else if ( _format == "yyyy/MM/dd" )
00621         return date_format16;
00622     else if ( _format == "d MMMM yyyy" )
00623         return date_format17;
00624     else if ( _format == "MM/dd/yyyy" )
00625         return date_format18;
00626     else if ( _format == "MM/dd/yy" )
00627         return date_format19;
00628     else if ( _format == "MMM/dd/yy" )
00629         return date_format20;
00630     else if ( _format == "MMM/dd/yyyy" )
00631         return date_format21;
00632     else if ( _format == "MMM-yyyy" )
00633         return date_format22;
00634     else if ( _format == "yyyy" )
00635         return date_format23;
00636     else if ( _format == "yy" )
00637         return date_format24;
00638     else if ( _format == "yyyy/MM/dd" )
00639         return date_format25;
00640     else if ( _format == "yyyy/MMM/dd" )
00641         return date_format26;
00642     else if ( _format == dateFormatShort )
00643         return ShortDate_format;
00644     else if ( _format == dateFormat )
00645         return TextDate_format;
00646     else
00647         return ShortDate_format;
00648 }
00649 
00650 FormatType Style::timeType( const QString &_format )
00651 {
00652     if ( _format == "h:mm AP" )
00653         return Time_format1;
00654     else if ( _format == "h:mm:ss AP" )
00655         return Time_format2;
00656     else if ( _format == "hh \\h mm \\m\\i\\n ss \\s" )
00657         return Time_format3;
00658     else if ( _format == "hh:mm" )
00659         return Time_format4;
00660     else if ( _format == "hh:mm:ss" )
00661         return Time_format5;
00662     else if ( _format == "m:ss" )
00663         return Time_format6;
00664     else if ( _format == "h:mm:ss" )
00665         return Time_format7;
00666     else if ( _format == "h:mm" )
00667         return Time_format8;
00668     else
00669         return Time_format;
00670 }
00671 
00672 FormatType Style::fractionType( const QString &_format )
00673 {
00674     if ( _format == "# ?/2" )
00675         return fraction_half;
00676     else if ( _format =="# ?/4" )
00677         return fraction_quarter;
00678     else if ( _format == "# ?/8" )
00679         return fraction_eighth;
00680     else if ( _format == "# ?/16" )
00681         return fraction_sixteenth;
00682     else if ( _format == "# ?/10" )
00683         return fraction_tenth;
00684     else if ( _format == "# ?/100" )
00685         return fraction_hundredth;
00686     else if ( _format == "# ?/?" )
00687         return fraction_one_digit;
00688     else if ( _format == "# \?\?/\?\?" )
00689         return fraction_two_digits;
00690     else if ( _format == "# \?\?\?/\?\?\?" )
00691         return fraction_three_digits;
00692     else
00693         return fraction_half;
00694 }
00695 
00696 QString Style::saveOasisStyleNumeric( KoGenStyle &style, KoGenStyles &mainStyles,
00697                                       FormatType _style,
00698                                       const QString &_prefix, const QString &_postfix,
00699                                       int _precision, const QString& symbol )
00700 {
00701 //  kdDebug() << k_funcinfo << endl;
00702     QString styleName;
00703     QString valueType;
00704     switch( _style )
00705     {
00706     case Number_format:
00707         styleName = saveOasisStyleNumericNumber( mainStyles, _style, _precision, _prefix, _postfix );
00708         valueType = "float";
00709         break;
00710     case Text_format:
00711         styleName = saveOasisStyleNumericText( mainStyles, _style, _precision, _prefix, _postfix );
00712         valueType = "string";
00713         break;
00714     case Money_format:
00715         styleName = saveOasisStyleNumericMoney( mainStyles, _style,symbol, _precision, _prefix, _postfix );
00716         valueType = "currency";
00717         break;
00718     case Percentage_format:
00719         styleName = saveOasisStyleNumericPercentage( mainStyles, _style, _precision, _prefix, _postfix );
00720         valueType = "percentage";
00721         break;
00722     case Scientific_format:
00723         styleName = saveOasisStyleNumericScientific( mainStyles, _style, _prefix, _postfix, _precision );
00724         valueType = "float";
00725         break;
00726     case ShortDate_format:
00727     case TextDate_format:
00728         styleName = saveOasisStyleNumericDate( mainStyles, _style, _prefix, _postfix );
00729         valueType = "date";
00730         break;
00731     case Time_format:
00732     case SecondeTime_format:
00733     case Time_format1:
00734     case Time_format2:
00735     case Time_format3:
00736     case Time_format4:
00737     case Time_format5:
00738     case Time_format6:
00739     case Time_format7:
00740     case Time_format8:
00741         styleName = saveOasisStyleNumericTime( mainStyles, _style, _prefix, _postfix );
00742         valueType = "time";
00743         break;
00744     case fraction_half:
00745     case fraction_quarter:
00746     case fraction_eighth:
00747     case fraction_sixteenth:
00748     case fraction_tenth:
00749     case fraction_hundredth:
00750     case fraction_one_digit:
00751     case fraction_two_digits:
00752     case fraction_three_digits:
00753         styleName = saveOasisStyleNumericFraction( mainStyles,_style, _prefix, _postfix );
00754         valueType = "float";
00755         break;
00756     case date_format1:
00757     case date_format2:
00758     case date_format3:
00759     case date_format4:
00760     case date_format5:
00761     case date_format6:
00762     case date_format7:
00763     case date_format8:
00764     case date_format9:
00765     case date_format10:
00766     case date_format11:
00767     case date_format12:
00768     case date_format13:
00769     case date_format14:
00770     case date_format15:
00771     case date_format16:
00772     case date_format17:
00773     case date_format18:
00774     case date_format19:
00775     case date_format20:
00776     case date_format21:
00777     case date_format22:
00778     case date_format23:
00779     case date_format24:
00780     case date_format25:
00781     case date_format26:
00782         styleName = saveOasisStyleNumericDate( mainStyles, _style, _prefix, _postfix );
00783         valueType = "date";
00784         break;
00785     case Custom_format:
00786         styleName = saveOasisStyleNumericCustom( mainStyles, _style, _prefix, _postfix );
00787         break;
00788     case Generic_format:
00789     case No_format:
00790       if (_precision > -1 || !_prefix.isEmpty() || !_postfix.isEmpty())
00791       {
00792         styleName = saveOasisStyleNumericNumber( mainStyles, _style, _precision, _prefix, _postfix );
00793         valueType = "float";
00794       }
00795       break;
00796     }
00797     if ( !styleName.isEmpty() )
00798     {
00799       style.addAttribute( "style:data-style-name", styleName );
00800     }
00801     return styleName;
00802 }
00803 
00804 QString Style::saveOasisStyleNumericNumber( KoGenStyles& mainStyles, FormatType /*_style*/, int _precision,
00805                                             const QString &_prefix, const QString &_suffix )
00806 {
00807   QString format;
00808   if ( _precision == -1 )
00809     format="0";
00810   else
00811   {
00812     QString tmp;
00813     for ( int i = 0; i <_precision; i++ )
00814     {
00815       tmp+="0";
00816     }
00817     format = "0."+tmp;
00818   }
00819   return KoOasisStyles::saveOasisNumberStyle( mainStyles, format, _prefix, _suffix );
00820 }
00821 
00822 QString Style::saveOasisStyleNumericText( KoGenStyles& /*mainStyles*/, FormatType /*_style*/, int /*_precision*/,
00823                                           const QString &/*_prefix*/, const QString &/*_suffix*/ )
00824 {
00825     return "";
00826 }
00827 
00828 QString Style::saveOasisStyleNumericMoney( KoGenStyles& mainStyles, FormatType /*_style*/,
00829                                            const QString& symbol, int _precision,
00830                                            const QString &_prefix, const QString &_suffix )
00831 {
00832     QString format;
00833     if ( _precision == -1 )
00834         format="0";
00835     else
00836     {
00837         QString tmp;
00838         for ( int i = 0; i <_precision; i++ )
00839         {
00840             tmp+="0";
00841         }
00842         format = "0."+tmp;
00843     }
00844     return KoOasisStyles::saveOasisCurrencyStyle( mainStyles, format, symbol, _prefix, _suffix );
00845 }
00846 
00847 QString Style::saveOasisStyleNumericPercentage( KoGenStyles&mainStyles, FormatType /*_style*/,
00848                                                 int _precision,
00849                                                 const QString &_prefix, const QString &_suffix )
00850 {
00851     //<number:percentage-style style:name="N106" style:family="data-style">
00852     //<number:number number:decimal-places="6" number:min-integer-digits="1"/>
00853     //<number:text>%</number:text>
00854     //</number:percentage-style>
00855     //TODO add decimal etc.
00856     QString format;
00857     if ( _precision == -1 )
00858         format="0";
00859     else
00860     {
00861         QString tmp;
00862         for ( int i = 0; i <_precision; i++ )
00863         {
00864             tmp+="0";
00865         }
00866         format = "0."+tmp;
00867     }
00868     return KoOasisStyles::saveOasisPercentageStyle( mainStyles, format, _prefix, _suffix );
00869 }
00870 
00871 
00872 QString Style::saveOasisStyleNumericScientific( KoGenStyles&mainStyles, FormatType /*_style*/,
00873                                                 const QString &_prefix, const QString _suffix, int _precision )
00874 {
00875     //<number:number-style style:name="N60" style:family="data-style">
00876     //  <number:scientific-number number:decimal-places="2" number:min-integer-digits="1" number:min-exponent-digits="3"/>
00877     //</number:number-style>
00878     QString format;
00879     if ( _precision == -1 )
00880         format="0E+00";
00881     else
00882     {
00883         QString tmp;
00884         for ( int i = 0; i <_precision; i++ )
00885         {
00886             tmp+="0";
00887         }
00888         format = "0."+tmp+"E+00";
00889     }
00890     return KoOasisStyles::saveOasisScientificStyle( mainStyles, format, _prefix, _suffix );
00891 }
00892 
00893 QString Style::saveOasisStyleNumericDate( KoGenStyles&mainStyles, FormatType _style,
00894                                           const QString &_prefix, const QString &_suffix )
00895 {
00896     QString format;
00897     bool locale = false;
00898     switch( _style )
00899     {
00900         //TODO fixme use locale of kspread and not kglobal
00901     case ShortDate_format:
00902         format = KGlobal::locale()->dateFormatShort();
00903         locale = true;
00904         break;
00905     case TextDate_format:
00906         format = KGlobal::locale()->dateFormat();
00907         locale = true;
00908         break;
00909     case date_format1:
00910         format = "dd-MMM-yy";
00911         break;
00912     case date_format2:
00913         format = "dd-MMM-yyyy";
00914         break;
00915     case date_format3:
00916         format = "dd-M";
00917         break;
00918     case date_format4:
00919         format = "dd-MM";
00920         break;
00921     case date_format5:
00922         format = "dd/MM/yy";
00923         break;
00924     case date_format6:
00925         format = "dd/MM/yyyy";
00926         break;
00927     case date_format7:
00928         format = "MMM-yy";
00929         break;
00930     case date_format8:
00931         format = "MMMM-yy";
00932         break;
00933     case date_format9:
00934         format = "MMMM-yyyy";
00935         break;
00936     case date_format10:
00937         format = "MMMMM-yy";
00938         break;
00939     case date_format11:
00940         format = "dd/MMM";
00941         break;
00942     case date_format12:
00943         format = "dd/MM";
00944         break;
00945     case date_format13:
00946         format = "dd/MMM/yyyy";
00947         break;
00948     case date_format14:
00949         format = "yyyy/MMM/dd";
00950         break;
00951     case date_format15:
00952         format = "yyyy-MMM-dd";
00953         break;
00954     case date_format16:
00955         format = "yyyy/MM/dd";
00956         break;
00957     case date_format17:
00958         format = "d MMMM yyyy";
00959         break;
00960     case date_format18:
00961         format = "MM/dd/yyyy";
00962         break;
00963     case date_format19:
00964         format = "MM/dd/yy";
00965         break;
00966     case date_format20:
00967         format = "MMM/dd/yy";
00968         break;
00969     case date_format21:
00970         format = "MMM/dd/yyyy";
00971         break;
00972     case date_format22:
00973         format = "MMM-yyyy";
00974         break;
00975     case date_format23:
00976         format = "yyyy";
00977         break;
00978     case date_format24:
00979         format = "yy";
00980         break;
00981     case date_format25:
00982         format = "yyyy/MM/dd";
00983         break;
00984     case date_format26:
00985         format = "yyyy/MMM/dd";
00986         break;
00987     default:
00988         kdDebug()<<"this date format is not defined ! :"<<_style<<endl;
00989         break;
00990     }
00991     return KoOasisStyles::saveOasisDateStyle( mainStyles, format, locale, _prefix, _suffix );
00992 }
00993 
00994 QString Style::saveOasisStyleNumericCustom( KoGenStyles& /*mainStyles*/, FormatType /*_style*/,
00995                                             const QString &/*_prefix*/, const QString &/*_suffix*/ )
00996 {
00997     //TODO
00998     //<number:date-style style:name="N50" style:family="data-style" number:automatic-order="true" number:format-source="language">
00999     //<number:month/>
01000     //<number:text>/</number:text>
01001     //<number:day/>
01002     //<number:text>/</number:text>
01003     //<number:year/>
01004     //<number:text> </number:text>
01005     //<number:hours number:style="long"/>
01006     //<number:text>:</number:text>
01007     //<number:minutes number:style="long"/>
01008     // <number:text> </number:text>
01009     //<number:am-pm/>
01010     //</number:date-style>
01011     return "";
01012 }
01013 
01014 QString Style::saveOasisStyleNumericTime( KoGenStyles& mainStyles, FormatType _style,
01015                                           const QString &_prefix, const QString &_suffix )
01016 {
01017     //<number:time-style style:name="N42" style:family="data-style">
01018     //<number:hours number:style="long"/>
01019     //<number:text>:</number:text>
01020     //<number:minutes number:style="long"/>
01021     //<number:text> </number:text>
01022     //<number:am-pm/>
01023     //</number:time-style>
01024 
01025     QString format;
01026     bool locale = false;
01027     //TODO use format
01028     switch( _style )
01029     {
01030     case Time_format: //TODO FIXME
01031         format = "hh:mm:ss";
01032         break;
01033     case SecondeTime_format: //TODO FIXME
01034         format = "hh:mm";
01035         break;
01036     case Time_format1:
01037         format = "h:mm AP";
01038         break;
01039     case Time_format2:
01040         format = "h:mm:ss AP";
01041         break;
01042     case Time_format3: // 9 h 01 min 28 s
01043         format = "hh \\h mm \\m\\i\\n ss \\s";
01044         break;
01045     case Time_format4:
01046         format = "hh:mm";
01047         break;
01048     case Time_format5:
01049         format = "hh:mm:ss";
01050         break;
01051     case Time_format6:
01052         format = "m:ss";
01053         break;
01054     case Time_format7:
01055         format = "h:mm:ss";
01056         break;
01057     case Time_format8:
01058         format = "h:mm";
01059         break;
01060     default:
01061         kdDebug()<<"time format not defined :"<<_style<<endl;
01062         break;
01063     }
01064     return KoOasisStyles::saveOasisTimeStyle( mainStyles, format, locale, _prefix, _suffix );
01065 }
01066 
01067 
01068 QString Style::saveOasisStyleNumericFraction( KoGenStyles &mainStyles, FormatType _style,
01069                                               const QString &_prefix, const QString _suffix )
01070 {
01071     //<number:number-style style:name="N71" style:family="data-style">
01072     //<number:fraction number:min-integer-digits="0" number:min-numerator-digits="2" number:min-denominator-digits="2"/>
01073     //</number:number-style>
01074     QString format;
01075     switch( _style )
01076     {
01077     case fraction_half:
01078         format = "# ?/2";
01079         break;
01080     case fraction_quarter:
01081         format = "# ?/4";
01082         break;
01083     case fraction_eighth:
01084         format = "# ?/8";
01085         break;
01086     case fraction_sixteenth:
01087         format = "# ?/16";
01088         break;
01089     case fraction_tenth:
01090         format = "# ?/10";
01091         break;
01092     case fraction_hundredth:
01093         format = "# ?/100";
01094         break;
01095     case fraction_one_digit:
01096         format = "# ?/?";
01097         break;
01098     case fraction_two_digits:
01099         format = "# \?\?/\?\?";
01100         break;
01101     case fraction_three_digits:
01102         format = "# \?\?\?/\?\?\?";
01103         break;
01104     default:
01105         kdDebug()<<" fraction format not defined :"<<_style<<endl;
01106         break;
01107     }
01108 
01109     return KoOasisStyles::saveOasisFractionStyle( mainStyles, format, _prefix, _suffix );
01110 }
01111 
01112 QString Style::saveOasis( KoGenStyle& style, KoGenStyles& mainStyles )
01113 {
01114   // KSpread::Style is definitly an OASIS auto style,
01115   // but don't overwrite it, if it already exists
01116   if (style.type() == 0)
01117       style = KoGenStyle( Doc::STYLE_CELL_AUTO, "table-cell" );
01118   // doing the real work
01119   saveOasisStyle( style, mainStyles );
01120   return QString::null;
01121 }
01122 
01123 void Style::saveOasisStyle( KoGenStyle &style, KoGenStyles &mainStyles )
01124 {
01125 #ifndef NDEBUG
01126     //if (type() == BUILTIN )
01127     //  kdDebug() << "BUILTIN" << endl;
01128     //else if (type() == CUSTOM )
01129     //  kdDebug() << "CUSTOM" << endl;
01130     //else if (type() == AUTO )
01131     //  kdDebug() << "AUTO" << endl;
01132 #endif
01133 
01134     // don't store parent, if it's the default style
01135     if ( m_parent && (m_parent->type() != BUILTIN || m_parent->name() != "Default") )
01136         // FIXME this is not the OASIS parent style's name. it's its display name!
01137         style.addAttribute( "style:parent-style-name", m_parent->name() );
01138 
01139     if ( featureSet( SAlignX ) && alignX() != Format::Undefined )
01140     {
01141         QString value;
01142         switch( alignX() )
01143         {
01144         case Format::Center:
01145             value = "center";
01146             break;
01147         case Format::Right:
01148             value = "end";
01149             break;
01150         case Format::Left:
01151             value = "start";
01152             break;
01153         case Format::Undefined:
01154             break;
01155         }
01156         if ( !value.isEmpty() )
01157         {
01158             style.addProperty( "style:text-align-source", "fix" ); // table-cell-properties
01159             style.addProperty( "fo:text-align", value, KoGenStyle::ParagraphType );
01160         }
01161     }
01162 
01163     if ( featureSet( SAlignY ) )
01164     {
01165         QString value;
01166         switch( alignY() )
01167         {
01168         case Format::Top:
01169             value = "top";
01170             break;
01171         case Format::Middle:
01172             value = "middle";
01173             break;
01174         case Format::Bottom:
01175             value = "bottom";
01176             break;
01177         case Format::UndefinedY:
01178         default:
01179             break;
01180         }
01181         if (!value.isEmpty()) // sanity
01182             style.addProperty( "style:vertical-align", value );
01183     }
01184 
01185     if ( featureSet( SBackgroundColor ) && m_bgColor != QColor() && m_bgColor.isValid() )
01186         style.addProperty( "fo:background-color", colorName(m_bgColor) );
01187 
01188     if ( featureSet( SMultiRow ) && hasProperty( PMultiRow ) )
01189         style.addProperty( "fo:wrap-option", "wrap" );
01190 
01191     if ( featureSet( SVerticalText ) && hasProperty( PVerticalText ) )
01192     {
01193         style.addProperty( "style:direction", "ttb" );
01194         style.addProperty( "style:rotation-angle", "0" );
01195         style.addProperty( "style:rotation-align", "none" );
01196     }
01197 #if 0
01198     if ( featureSet( SFloatFormat ) )
01199         format.setAttribute( "float", (int) m_floatFormat );
01200 
01201     if ( featureSet( SFloatColor ) )
01202         format.setAttribute( "floatcolor", (int)m_floatColor );
01203 
01204     if ( featureSet( SCustomFormat ) && !strFormat().isEmpty() )
01205         format.setAttribute( "custom", m_strFormat );
01206 
01207     if ( featureSet( SFormatType ) && formatType() == Format::Money )
01208     {
01209         format.setAttribute( "type", (int) m_currency.type );
01210         format.setAttribute( "symbol", m_currency.symbol );
01211     }
01212 #endif
01213     if ( featureSet( SAngle ) && m_rotateAngle != 0 )
01214     {
01215         style.addProperty( "style:rotation-align", "none" );
01216         style.addProperty( "style:rotation-angle", QString::number( -1.0 *m_rotateAngle  ) );
01217     }
01218 
01219     if ( featureSet( SIndent ) && m_indent != 0.0 )
01220     {
01221         style.addPropertyPt("fo:margin-left", m_indent, KoGenStyle::ParagraphType );
01222         //FIXME
01223         //if ( a == Format::Undefined )
01224         //currentCellStyle.addProperty("fo:text-align", "start" );
01225     }
01226 
01227     if ( featureSet( SDontPrintText ) && hasProperty( PDontPrintText ) )
01228         style.addProperty( "style:print-content", "false");
01229 
01230     // protection
01231     bool hideAll = false;
01232     bool hideFormula = false;
01233     bool isNotProtected = false;
01234 
01235     if ( featureSet( SNotProtected ) && hasProperty( PNotProtected ) )
01236         isNotProtected = true;
01237 
01238     if ( featureSet( SHideAll ) && hasProperty( PHideAll ) )
01239         hideAll=true;
01240 
01241     if ( featureSet( SHideFormula ) && hasProperty( PHideFormula ) )
01242         hideFormula = true;
01243 
01244     if ( hideAll )
01245         style.addProperty( "style:cell-protect", "hidden-and-protected" );
01246     else
01247     {
01248         if ( isNotProtected && !hideFormula )
01249             style.addProperty( "style:cell-protect", "none" );
01250         else if ( isNotProtected && hideFormula )
01251             style.addProperty( "style:cell-protect", "formula-hidden" );
01252         else if ( hideFormula )
01253             style.addProperty( "style:cell-protect", "protected formula-hidden" );
01254         else if ( featureSet( SNotProtected ) && !hasProperty( PNotProtected ) )
01255             // write out, only if it is explicity set
01256             style.addProperty( "style:cell-protect", "protected" );
01257     }
01258 
01259     // borders
01260     // NOTE Stefan: QPen api docs:
01261     //              For horizontal and vertical lines a line width of 0 is
01262     //              the same as a line width of 1.
01263     //              A line width of 0 will produce a 1 pixel wide line using
01264     //              a fast algorithm for diagonals. A line width of 1 will
01265     //              also produce a 1 pixel wide line, but uses a slower more
01266     //              accurate algorithm for diagonals.
01267     if ( featureSet( SLeftBorder ) && featureSet( SRightBorder ) &&
01268          featureSet( STopBorder ) && featureSet( SBottomBorder ) &&
01269          ( m_leftBorderPen == m_topBorderPen ) &&
01270          ( m_leftBorderPen == m_rightBorderPen ) &&
01271          ( m_leftBorderPen == m_bottomBorderPen ) )
01272     {
01273       if ( m_leftBorderPen.style() != Qt::NoPen )
01274             style.addProperty("fo:border", convertOasisPenToString( m_leftBorderPen ) );
01275     }
01276     else
01277     {
01278         if ( featureSet( SLeftBorder ) && ( m_leftBorderPen.style() != Qt::NoPen ) )
01279             style.addProperty( "fo:border-left", convertOasisPenToString( m_leftBorderPen ) );
01280 
01281         if ( featureSet( SRightBorder ) && ( m_rightBorderPen.style() != Qt::NoPen ) )
01282             style.addProperty( "fo:border-right", convertOasisPenToString( m_rightBorderPen ) );
01283 
01284         if ( featureSet( STopBorder ) && ( m_topBorderPen.style() != Qt::NoPen ) )
01285             style.addProperty( "fo:border-top", convertOasisPenToString( m_topBorderPen ) );
01286 
01287         if ( featureSet( SBottomBorder ) && ( m_bottomBorderPen.style() != Qt::NoPen ) )
01288             style.addProperty( "fo:border-bottom", convertOasisPenToString( m_bottomBorderPen ) );
01289     }
01290     if ( featureSet( SFallDiagonal ) && ( m_fallDiagonalPen.style() != Qt::NoPen ) )
01291     {
01292         style.addProperty("style:diagonal-tl-br", convertOasisPenToString( m_fallDiagonalPen ) );
01293     }
01294     if ( featureSet( SGoUpDiagonal ) && ( m_goUpDiagonalPen.style() != Qt::NoPen ) )
01295     {
01296         style.addProperty("style:diagonal-bl-tr", convertOasisPenToString(m_goUpDiagonalPen ) );
01297     }
01298 
01299     // font
01300     if ( featureSet( SFontFamily ) ) // !m_fontFamily.isEmpty() == true
01301     {
01302         style.addProperty("fo:font-family", m_fontFamily, KoGenStyle::TextType );
01303     }
01304     if ( featureSet( SFontSize ) ) // m_fontSize != 0
01305     {
01306         style.addPropertyPt("fo:font-size",m_fontSize, KoGenStyle::TextType  );
01307     }
01308 
01309     if ( featureSet( SFontFlag ) && m_fontFlags & (uint) FBold )
01310         style.addProperty("fo:font-weight","bold", KoGenStyle::TextType );
01311 
01312     if ( featureSet( SFontFlag ) && m_fontFlags & (uint) FItalic )
01313         style.addProperty("fo:font-style", "italic", KoGenStyle::TextType );
01314 
01315     if ( featureSet( SFontFlag ) && m_fontFlags & (uint) FUnderline )
01316     {
01317         //style:text-underline-style="solid" style:text-underline-width="auto"
01318         style.addProperty( "style:text-underline-style", "solid", KoGenStyle::TextType );
01319         //copy from oo-129
01320         style.addProperty( "style:text-underline-width", "auto", KoGenStyle::TextType );
01321         style.addProperty( "style:text-underline-color", "font-color", KoGenStyle::TextType );
01322     }
01323 
01324     if ( featureSet( SFontFlag ) && m_fontFlags & (uint) FStrike )
01325         style.addProperty( "style:text-line-through-style", "solid", KoGenStyle::TextType );
01326 
01327     if ( featureSet( STextPen ) && m_textPen.color().isValid() ) // always save; default: m_textPen.style() == Qt::NoPen
01328     {
01329         style.addProperty("fo:color", colorName(m_textPen.color()), KoGenStyle::TextType );
01330     }
01331 
01332     //I don't think there is a reason why the background brush should be saved if it is null,
01333     //but remove the check if it causes problems.  -- Robert Knight <robertknight@gmail.com>
01334     if ( featureSet( SBackgroundBrush ) && (m_backGroundBrush.style() != Qt::NoBrush) )
01335     {
01336         QString tmp = saveOasisBackgroundStyle( mainStyles, m_backGroundBrush );
01337         if ( !tmp.isEmpty() )
01338             style.addProperty("draw:style-name", tmp );
01339     }
01340 
01341     QString _prefix;
01342     QString _postfix;
01343     int _precision = -1;
01344     if ( featureSet( SPrefix ) && !prefix().isEmpty() )
01345         _prefix = m_prefix;
01346     if ( featureSet( SPostfix ) && !postfix().isEmpty() )
01347         _postfix = m_postfix;
01348     if ( featureSet( SPrecision ) && m_precision != -1 )
01349         _precision =  m_precision;
01350 
01351     QString symbol;
01352     if ( featureSet( SFormatType ) && m_formatType == Money_format )
01353     {
01354       symbol = Currency::getCurrencyCode(m_currency.type);
01355     }
01356 
01357     QString numericStyle = saveOasisStyleNumeric( style, mainStyles, m_formatType,
01358                                                   _prefix, _postfix, _precision,
01359                                                   symbol );
01360     if ( !numericStyle.isEmpty() )
01361         style.addAttribute( "style:data-style-name", numericStyle );
01362 }
01363 
01364 QString Style::saveOasisBackgroundStyle( KoGenStyles &mainStyles, const QBrush &brush )
01365 {
01366     KoGenStyle styleobjectauto = KoGenStyle( KoGenStyle::STYLE_GRAPHICAUTO, "graphic" );
01367     KoOasisStyles::saveOasisFillStyle( styleobjectauto, mainStyles, brush );
01368     return mainStyles.lookup( styleobjectauto, "gr" );
01369 }
01370 
01371 void Style::saveXML( QDomDocument & doc, QDomElement & format ) const
01372 {
01373   if ( featureSet( SAlignX ) && alignX() != Format::Undefined )
01374     format.setAttribute( "alignX", (int) m_alignX );
01375 
01376   if ( featureSet( SAlignY ) && alignY() != Format::Middle )
01377     format.setAttribute( "alignY", (int) m_alignY );
01378 
01379   if ( featureSet( SBackgroundColor ) && m_bgColor != QColor() && m_bgColor.isValid() )
01380     format.setAttribute( "bgcolor", m_bgColor.name() );
01381 
01382   if ( featureSet( SMultiRow ) && hasProperty( PMultiRow ) )
01383     format.setAttribute( "multirow", "yes" );
01384 
01385   if ( featureSet( SVerticalText ) && hasProperty( PVerticalText ) )
01386     format.setAttribute( "verticaltext", "yes" );
01387 
01388   if ( featureSet( SPrecision ) )
01389     format.setAttribute( "precision", m_precision );
01390 
01391   if ( featureSet( SPrefix ) && !prefix().isEmpty() )
01392     format.setAttribute( "prefix", m_prefix );
01393 
01394   if ( featureSet( SPostfix ) && !postfix().isEmpty() )
01395     format.setAttribute( "postfix", m_postfix );
01396 
01397   if ( featureSet( SFloatFormat ) )
01398     format.setAttribute( "float", (int) m_floatFormat );
01399 
01400   if ( featureSet( SFloatColor ) )
01401   format.setAttribute( "floatcolor", (int)m_floatColor );
01402 
01403   if ( featureSet( SFormatType ) )
01404     format.setAttribute( "format",(int) m_formatType );
01405 
01406   if ( featureSet( SCustomFormat ) && !strFormat().isEmpty() )
01407     format.setAttribute( "custom", m_strFormat );
01408 
01409   if ( featureSet( SFormatType ) && formatType() == Money_format )
01410   {
01411     format.setAttribute( "type", (int) m_currency.type );
01412     format.setAttribute( "symbol", m_currency.symbol );
01413   }
01414 
01415   if ( featureSet( SAngle ) )
01416     format.setAttribute( "angle", m_rotateAngle );
01417 
01418   if ( featureSet( SIndent ) )
01419     format.setAttribute( "indent", m_indent );
01420 
01421   if ( featureSet( SDontPrintText ) && hasProperty( PDontPrintText ) )
01422     format.setAttribute( "dontprinttext", "yes" );
01423 
01424   if ( featureSet( SNotProtected ) && hasProperty( PNotProtected ) )
01425     format.setAttribute( "noprotection", "yes" );
01426 
01427   if ( featureSet( SHideAll ) && hasProperty( PHideAll ) )
01428     format.setAttribute( "hideall", "yes" );
01429 
01430   if ( featureSet( SHideFormula ) && hasProperty( PHideFormula ) )
01431     format.setAttribute( "hideformula", "yes" );
01432 
01433   if ( featureSet( SFontFamily ) )
01434     format.setAttribute( "font-family", m_fontFamily );
01435   if ( featureSet( SFontSize ) )
01436     format.setAttribute( "font-size", m_fontSize );
01437   if ( featureSet( SFontFlag ) )
01438     format.setAttribute( "font-flags", m_fontFlags );
01439 
01440   //  if ( featureSet( SFont ) )
01441   //    format.appendChild( util_createElement( "font", m_textFont, doc ) );
01442 
01443   if ( featureSet( STextPen ) && m_textPen.color().isValid() )
01444     format.appendChild( util_createElement( "pen", m_textPen, doc ) );
01445 
01446   if ( featureSet( SBackgroundBrush ) )
01447   {
01448     format.setAttribute( "brushcolor", m_backGroundBrush.color().name() );
01449     format.setAttribute( "brushstyle", (int) m_backGroundBrush.style() );
01450   }
01451 
01452   if ( featureSet( SLeftBorder ) )
01453   {
01454     QDomElement left = doc.createElement( "left-border" );
01455     left.appendChild( util_createElement( "pen", m_leftBorderPen, doc ) );
01456     format.appendChild( left );
01457   }
01458 
01459   if ( featureSet( STopBorder ) )
01460   {
01461     QDomElement top = doc.createElement( "top-border" );
01462     top.appendChild( util_createElement( "pen", m_topBorderPen, doc ) );
01463     format.appendChild( top );
01464   }
01465 
01466   if ( featureSet( SRightBorder ) )
01467   {
01468     QDomElement right = doc.createElement( "right-border" );
01469     right.appendChild( util_createElement( "pen", m_rightBorderPen, doc ) );
01470     format.appendChild( right );
01471   }
01472 
01473   if ( featureSet( SBottomBorder ) )
01474   {
01475     QDomElement bottom = doc.createElement( "bottom-border" );
01476     bottom.appendChild( util_createElement( "pen", m_bottomBorderPen, doc ) );
01477     format.appendChild( bottom );
01478   }
01479 
01480   if ( featureSet( SFallDiagonal ) )
01481   {
01482     QDomElement fallDiagonal  = doc.createElement( "fall-diagonal" );
01483     fallDiagonal.appendChild( util_createElement( "pen", m_fallDiagonalPen, doc ) );
01484     format.appendChild( fallDiagonal );
01485   }
01486 
01487   if ( featureSet( SGoUpDiagonal ) )
01488   {
01489     QDomElement goUpDiagonal = doc.createElement( "up-diagonal" );
01490     goUpDiagonal.appendChild( util_createElement( "pen", m_goUpDiagonalPen, doc ) );
01491     format.appendChild( goUpDiagonal );
01492   }
01493 }
01494 
01495 bool Style::loadXML( QDomElement & format )
01496 {
01497   bool ok;
01498   if ( format.hasAttribute( "type" ) )
01499   {
01500     m_type = (StyleType) format.attribute( "type" ).toInt( &ok );
01501     if ( !ok )
01502       return false;
01503   }
01504 
01505   if ( format.hasAttribute( "alignX" ) )
01506   {
01507     Format::Align a = (Format::Align) format.attribute( "alignX" ).toInt( &ok );
01508     if ( !ok )
01509       return false;
01510     if ( (unsigned int) a >= 1 || (unsigned int) a <= 4 )
01511     {
01512       m_alignX = a;
01513       m_featuresSet |= SAlignX;
01514     }
01515   }
01516   if ( format.hasAttribute( "alignY" ) )
01517   {
01518     Format::AlignY a = (Format::AlignY) format.attribute( "alignY" ).toInt( &ok );
01519     if ( !ok )
01520       return false;
01521     if ( (unsigned int) a >= 1 || (unsigned int) a < 4 )
01522     {
01523       m_alignY = a;
01524       m_featuresSet |= SAlignY;
01525     }
01526   }
01527 
01528   if ( format.hasAttribute( "bgcolor" ) )
01529   {
01530     m_bgColor = QColor( format.attribute( "bgcolor" ) );
01531     // FIXME: Is white always correct here?
01532     if ( m_bgColor != Qt::white )
01533     m_featuresSet |= SBackgroundColor;
01534   }
01535 
01536   if ( format.hasAttribute( "multirow" ) )
01537   {
01538     setProperty( PMultiRow );
01539     m_featuresSet |= SMultiRow;
01540   }
01541 
01542   if ( format.hasAttribute( "verticaltext" ) )
01543   {
01544     setProperty( PVerticalText );
01545     m_featuresSet |= SVerticalText;
01546   }
01547 
01548   if ( format.hasAttribute( "precision" ) )
01549   {
01550     int i = format.attribute( "precision" ).toInt( &ok );
01551     if ( i < -1 )
01552     {
01553       kdDebug(36001) << "Value out of range Cell::precision=" << i << endl;
01554       return false;
01555     }
01556     m_precision = i;
01557     m_featuresSet |= SPrecision;
01558   }
01559 
01560   if ( format.hasAttribute( "float" ) )
01561   {
01562     Format::FloatFormat a = (Format::FloatFormat)format.attribute( "float" ).toInt( &ok );
01563     if ( !ok )
01564       return false;
01565     if ( (unsigned int) a >= 1 || (unsigned int) a <= 3 )
01566     {
01567       m_floatFormat = a;
01568       m_featuresSet |= SFloatFormat;
01569     }
01570   }
01571 
01572   if ( format.hasAttribute( "floatcolor" ) )
01573   {
01574     Format::FloatColor a = (Format::FloatColor) format.attribute( "floatcolor" ).toInt( &ok );
01575     if ( !ok ) return false;
01576     if ( (unsigned int) a >= 1 || (unsigned int) a <= 2 )
01577     {
01578       m_floatColor = a;
01579       m_featuresSet |= SFloatColor;
01580     }
01581   }
01582 
01583   if ( format.hasAttribute( "format" ) )
01584   {
01585     int fo = format.attribute( "format" ).toInt( &ok );
01586     if ( ! ok )
01587       return false;
01588     m_formatType = ( FormatType ) fo;
01589     m_featuresSet |= SFormatType;
01590   }
01591   if ( format.hasAttribute( "custom" ) )
01592   {
01593     m_strFormat = format.attribute( "custom" );
01594     m_featuresSet |= SCustomFormat;
01595   }
01596   if ( m_formatType == Money_format )
01597   {
01598     if ( format.hasAttribute( "type" ) )
01599     {
01600       m_currency.type   = format.attribute( "type" ).toInt( &ok );
01601       if (!ok)
01602         m_currency.type = 1;
01603     }
01604     if ( format.hasAttribute( "symbol" ) )
01605     {
01606       m_currency.symbol = format.attribute( "symbol" );
01607     }
01608     m_featuresSet |= SFormatType;
01609   }
01610   if ( format.hasAttribute( "angle" ) )
01611   {
01612     m_rotateAngle = format.attribute( "angle" ).toInt( &ok );
01613     if ( !ok )
01614       return false;
01615     m_featuresSet |= SAngle;
01616   }
01617   if ( format.hasAttribute( "indent" ) )
01618   {
01619     m_indent = format.attribute( "indent" ).toDouble( &ok );
01620     if ( !ok )
01621       return false;
01622     m_featuresSet |= SIndent;
01623   }
01624   if ( format.hasAttribute( "dontprinttext" ) )
01625   {
01626     setProperty( PDontPrintText );
01627     m_featuresSet |= SDontPrintText;
01628   }
01629 
01630   if ( format.hasAttribute( "noprotection" ) )
01631   {
01632     setProperty( PNotProtected );
01633     m_featuresSet |= SNotProtected;
01634   }
01635 
01636   if ( format.hasAttribute( "hideall" ) )
01637   {
01638     setProperty( PHideAll );
01639     m_featuresSet |= SHideAll;
01640   }
01641 
01642   if ( format.hasAttribute( "hideformula" ) )
01643   {
01644     setProperty( PHideFormula );
01645     m_featuresSet |= SHideFormula;
01646   }
01647 
01648   // TODO: remove that...
01649   QDomElement font = format.namedItem( "font" ).toElement();
01650   if ( !font.isNull() )
01651   {
01652     QFont f( util_toFont( font ) );
01653     m_fontFamily = f.family();
01654     m_fontSize = f.pointSize();
01655     if ( f.italic() )
01656       m_fontFlags |= FItalic;
01657     if ( f.bold() )
01658       m_fontFlags |= FBold;
01659     if ( f.underline() )
01660       m_fontFlags |= FUnderline;
01661     if ( f.strikeOut() )
01662       m_fontFlags |= FStrike;
01663 
01664     m_featuresSet |= SFont;
01665     m_featuresSet |= SFontFamily;
01666     m_featuresSet |= SFontFlag;
01667     m_featuresSet |= SFontSize;
01668   }
01669 
01670   if ( format.hasAttribute( "font-family" ) )
01671   {
01672     m_fontFamily = format.attribute( "font-family" );
01673     m_featuresSet |= SFont;
01674     m_featuresSet |= SFontFamily;
01675   }
01676   if ( format.hasAttribute( "font-size" ) )
01677   {
01678     m_fontSize = format.attribute( "font-size" ).toInt( &ok );
01679     if ( !ok )
01680       return false;
01681     m_featuresSet |= SFont;
01682     m_featuresSet |= SFontSize;
01683   }
01684 
01685   if ( format.hasAttribute( "font-flags" ) )
01686   {
01687     m_fontFlags = format.attribute( "font-flags" ).toInt( &ok );
01688     if ( !ok )
01689       return false;
01690     m_featuresSet |= SFont;
01691     m_featuresSet |= SFontFlag;
01692   }
01693 
01694   if ( format.hasAttribute( "brushcolor" ) )
01695   {
01696     m_backGroundBrush.setColor( QColor( format.attribute( "brushcolor" ) ) );
01697     // It is not necessary to set this feature just because the color changes.
01698     // FIXME: Or is it?
01699     //m_featuresSet |= SBackgroundBrush;
01700   }
01701 
01702   if ( format.hasAttribute( "brushstyle" ) )
01703   {
01704     m_backGroundBrush.setStyle( (Qt::BrushStyle) format.attribute( "brushstyle" ).toInt( &ok )  );
01705     if ( !ok )
01706       return false;
01707 
01708     if ( m_backGroundBrush.style() != Qt::NoBrush )
01709     m_featuresSet |= SBackgroundBrush;
01710   }
01711 
01712   QDomElement pen = format.namedItem( "pen" ).toElement();
01713   if ( !pen.isNull() )
01714   {
01715     m_textPen = util_toPen( pen );
01716     if ( m_textPen.style() != Qt::NoPen )
01717     m_featuresSet |= STextPen;
01718   }
01719 
01720   QDomElement left = format.namedItem( "left-border" ).toElement();
01721   if ( !left.isNull() )
01722   {
01723     QDomElement pen = left.namedItem( "pen" ).toElement();
01724     if ( !pen.isNull() )
01725     {
01726       m_leftBorderPen = util_toPen( pen );
01727       if ( m_leftBorderPen.style() != Qt::NoPen )
01728       m_featuresSet |= SLeftBorder;
01729     }
01730   }
01731 
01732   QDomElement top = format.namedItem( "top-border" ).toElement();
01733   if ( !top.isNull() )
01734   {
01735     QDomElement pen = top.namedItem( "pen" ).toElement();
01736     if ( !pen.isNull() )
01737     {
01738       m_topBorderPen = util_toPen( pen );
01739       if ( m_topBorderPen.style() != Qt::NoPen )
01740       m_featuresSet |= STopBorder;
01741     }
01742   }
01743 
01744   QDomElement right = format.namedItem( "right-border" ).toElement();
01745   if ( !right.isNull() )
01746   {
01747     QDomElement pen = right.namedItem( "pen" ).toElement();
01748     if ( !pen.isNull() )
01749     {
01750       m_rightBorderPen = util_toPen( pen );
01751       if ( m_rightBorderPen.style() != Qt::NoPen )
01752       m_featuresSet |= SRightBorder;
01753     }
01754   }
01755 
01756   QDomElement bottom = format.namedItem( "bottom-border" ).toElement();
01757   if ( !bottom.isNull() )
01758   {
01759     QDomElement pen = bottom.namedItem( "pen" ).toElement();
01760     if ( !pen.isNull() )
01761     {
01762       m_bottomBorderPen = util_toPen( pen );
01763       if ( m_bottomBorderPen.style() != Qt::NoPen )
01764       m_featuresSet |= SBottomBorder;
01765     }
01766   }
01767 
01768   QDomElement fallDiagonal = format.namedItem( "fall-diagonal" ).toElement();
01769   if ( !fallDiagonal.isNull() )
01770   {
01771     QDomElement pen = fallDiagonal.namedItem( "pen" ).toElement();
01772     if ( !pen.isNull() )
01773     {
01774       m_fallDiagonalPen = util_toPen( pen );
01775       if ( m_fallDiagonalPen.style() != Qt::NoPen )
01776       m_featuresSet |= SFallDiagonal;
01777     }
01778   }
01779 
01780   QDomElement goUpDiagonal = format.namedItem( "up-diagonal" ).toElement();
01781   if ( !goUpDiagonal.isNull() )
01782   {
01783     QDomElement pen = goUpDiagonal.namedItem( "pen" ).toElement();
01784     if ( !pen.isNull() )
01785     {
01786       m_goUpDiagonalPen = util_toPen( pen );
01787       if ( m_goUpDiagonalPen.style() != Qt::NoPen )
01788       m_featuresSet |= SGoUpDiagonal;
01789     }
01790   }
01791 
01792   if ( format.hasAttribute( "prefix" ) )
01793   {
01794     m_prefix = format.attribute( "prefix" );
01795     m_featuresSet |= SPrefix;
01796   }
01797   if ( format.hasAttribute( "postfix" ) )
01798   {
01799     m_postfix = format.attribute( "postfix" );
01800     m_featuresSet |= SPostfix;
01801   }
01802 
01803   return true;
01804 }
01805 
01806 void Style::setParent( CustomStyle * parent )
01807 {
01808   m_parent = parent;
01809   if ( m_parent )
01810     m_parentName = m_parent->name();
01811 }
01812 
01813 CustomStyle * Style::parent() const
01814 {
01815   return m_parent;
01816 }
01817 
01818 bool Style::release()
01819 {
01820   --m_usageCount;
01821 
01822   if ( m_type == CUSTOM || m_type == BUILTIN )
01823     return false; // never delete builtin styles...
01824 
01825   if ( m_usageCount < 1 )
01826     return true;
01827 
01828   return false;
01829 }
01830 
01831 void Style::addRef()
01832 {
01833   ++m_usageCount;
01834 }
01835 
01836 bool Style::hasProperty( Properties p ) const
01837 {
01838   FlagsSet f;
01839   switch( p )
01840   {
01841    case PDontPrintText:
01842     f = SDontPrintText;
01843     break;
01844    case PCustomFormat:
01845     f = SCustomFormat;
01846     break;
01847    case PNotProtected:
01848     f = SNotProtected;
01849     break;
01850    case PHideAll:
01851     f = SHideAll;
01852     break;
01853    case PHideFormula:
01854     f = SHideFormula;
01855     break;
01856    case PMultiRow:
01857     f = SMultiRow;
01858     break;
01859    case PVerticalText:
01860     f = SVerticalText;
01861     break;
01862    default:
01863     kdWarning() << "Unhandled property" << endl;
01864     return ( m_properties  & (uint) p );
01865   }
01866 
01867   return ( !m_parent || featureSet( f ) ? ( m_properties & (uint) p ) : m_parent->hasProperty( p ) );
01868 }
01869 
01870 bool Style::hasFeature( FlagsSet f, bool withoutParent ) const
01871 {
01872   bool b = ( m_featuresSet & (uint) f );
01873 
01874   // check if feature is defined here or at parent level
01875   if ( m_parent && !withoutParent )
01876     b = ( m_parent->hasFeature( f, withoutParent ) ? true : b );
01877 
01878   return b;
01879 }
01880 
01881 void Style::clearFeature( FlagsSet f )
01882 {
01883   m_featuresSet &= ~(uint)f;
01884 }
01885 
01886 QFont Style::font() const
01887 {
01888   QString family = fontFamily();
01889   int  size      = fontSize();
01890   uint ff        = fontFlags();
01891 
01892   QFont f( family, size );
01893   if ( ff & (uint) FBold )
01894     f.setBold( true );
01895   if ( ff & (uint) FItalic )
01896     f.setItalic( true );
01897   if ( ff & (uint) FUnderline )
01898     f.setUnderline( true );
01899   if ( ff & (uint) FStrike )
01900     f.setStrikeOut( true );
01901 
01902   return f;
01903 }
01904 
01905 QString const & Style::fontFamily() const
01906 {
01907   return ( !m_parent || featureSet( SFontFamily ) ? m_fontFamily : m_parent->fontFamily() );
01908 }
01909 
01910 uint Style::fontFlags() const
01911 {
01912   return ( !m_parent || featureSet( SFontFlag ) ? m_fontFlags : m_parent->fontFlags() );
01913 }
01914 
01915 int Style::fontSize() const
01916 {
01917   return ( !m_parent || featureSet( SFontSize ) ? m_fontSize : m_parent->fontSize() );
01918 }
01919 
01920 QPen const & Style::pen() const
01921 {
01922   return ( !m_parent || featureSet( STextPen ) ? m_textPen : m_parent->pen() );
01923 }
01924 
01925 QColor const & Style::bgColor() const
01926 {
01927   return ( !m_parent || featureSet( SBackgroundColor ) ? m_bgColor : m_parent->bgColor() );
01928 }
01929 
01930 QPen const & Style::rightBorderPen() const
01931 {
01932   return ( !m_parent || featureSet( SRightBorder ) ? m_rightBorderPen : m_parent->rightBorderPen() );
01933 }
01934 
01935 QPen const & Style::bottomBorderPen() const
01936 {
01937   return ( !m_parent || featureSet( SBottomBorder ) ? m_bottomBorderPen : m_parent->bottomBorderPen() );
01938 }
01939 
01940 QPen const & Style::leftBorderPen() const
01941 {
01942   return ( !m_parent || featureSet( SLeftBorder ) ? m_leftBorderPen : m_parent->leftBorderPen() );
01943 }
01944 
01945 QPen const & Style::topBorderPen() const
01946 {
01947   return ( !m_parent || featureSet( STopBorder ) ? m_topBorderPen : m_parent->topBorderPen() );
01948 }
01949 
01950 QPen const & Style::fallDiagonalPen() const
01951 {
01952   return ( !m_parent || featureSet( SFallDiagonal ) ? m_fallDiagonalPen : m_parent->fallDiagonalPen() );
01953 }
01954 
01955 QPen const & Style::goUpDiagonalPen() const
01956 {
01957   return ( !m_parent || featureSet( SGoUpDiagonal ) ? m_goUpDiagonalPen : m_parent->goUpDiagonalPen() );
01958 }
01959 
01960 int Style::precision() const
01961 {
01962   return ( !m_parent || featureSet( SPrecision ) ? m_precision : m_parent->precision() );
01963 }
01964 
01965 int Style::rotateAngle() const
01966 {
01967   return ( !m_parent || featureSet( SAngle ) ? m_rotateAngle : m_parent->rotateAngle() );
01968 }
01969 
01970 double Style::indent() const
01971 {
01972   return ( !m_parent || featureSet( SIndent ) ? m_indent : m_parent->indent() );
01973 }
01974 
01975 QBrush const & Style::backGroundBrush() const
01976 {
01977   return ( !m_parent || featureSet( SBackgroundBrush ) ? m_backGroundBrush : m_parent->backGroundBrush() );
01978 }
01979 
01980 Format::Align Style::alignX() const
01981 {
01982   return ( !m_parent || featureSet( SAlignX ) ? m_alignX : m_parent->alignX() );
01983 }
01984 
01985 Format::AlignY Style::alignY() const
01986 {
01987   return ( !m_parent || featureSet( SAlignY ) ? m_alignY : m_parent->alignY() );
01988 }
01989 
01990 Format::FloatFormat Style::floatFormat() const
01991 {
01992   return ( !m_parent || featureSet( SFloatFormat ) ? m_floatFormat : m_parent->floatFormat() );
01993 }
01994 
01995 Format::FloatColor Style::floatColor() const
01996 {
01997   return ( !m_parent || featureSet( SFloatColor ) ? m_floatColor : m_parent->floatColor() );
01998 }
01999 
02000 FormatType Style::formatType() const
02001 {
02002   return ( !m_parent || featureSet( SFormatType ) ? m_formatType : m_parent->formatType() );
02003 }
02004 
02005 Format::Currency const & Style::currency() const
02006 {
02007   return ( !m_parent || featureSet( SFormatType ) ? m_currency : m_parent->currency() );
02008 }
02009 
02010 QString const & Style::strFormat() const
02011 {
02012   return ( !m_parent || featureSet( SCustomFormat ) ? m_strFormat : m_parent->strFormat() );
02013 }
02014 
02015 QString const & Style::prefix() const
02016 {
02017   return ( !m_parent || featureSet( SPrefix ) ? m_prefix : m_parent->prefix() );
02018 }
02019 
02020 QString const & Style::postfix() const
02021 {
02022   return ( !m_parent || featureSet( SPostfix ) ? m_postfix : m_parent->postfix() );
02023 }
02024 
02025 
02026 
02027 Style * Style::setAlignX( Format::Align alignX )
02028 {
02029   if ( m_type != AUTO || m_usageCount > 1 )
02030   {
02031     Style * style = new Style( this );
02032     style->m_alignX = alignX;
02033     style->m_featuresSet |= SAlignX;
02034     return style;
02035   }
02036 
02037   m_alignX      = alignX;
02038   m_featuresSet |= SAlignX;
02039   return this;
02040 }
02041 
02042 Style * Style::setAlignY( Format::AlignY alignY )
02043 {
02044   if ( m_type != AUTO || m_usageCount > 1 )
02045   {
02046     Style * style = new Style( this );
02047     style->m_alignY = alignY;
02048     style->m_featuresSet |= SAlignY;
02049     return style;
02050   }
02051 
02052   m_alignY = alignY;
02053   m_featuresSet |= SAlignY;
02054   return this;
02055 }
02056 
02057 Style * Style::setFont( QFont const & f )
02058 {
02059   if ( m_type != AUTO || m_usageCount > 1 )
02060   {
02061     Style * style = new Style( this );
02062     if ( style->m_fontFamily != f.family() )
02063     {
02064       style->m_fontFamily = f.family();
02065       style->m_featuresSet |= SFont;
02066       style->m_featuresSet |= SFontFamily;
02067     }
02068     if ( style->m_fontSize != f.pointSize() )
02069     {
02070       style->m_fontSize = f.pointSize();
02071       style->m_featuresSet |= SFont;
02072       style->m_featuresSet |= SFontSize;
02073     }
02074     if ( f.italic() != (m_fontFlags & (uint) FItalic ) )
02075     {
02076       if ( f.italic() )
02077         style->m_fontFlags |= FItalic;
02078       else
02079         style->m_fontFlags &= ~(uint) FItalic;
02080       style->m_featuresSet |= SFont;
02081       style->m_featuresSet |= SFontFlag;
02082     }
02083     if ( f.bold() != (m_fontFlags & (uint) FBold ) )
02084     {
02085       if ( f.bold() )
02086         style->m_fontFlags |= FBold;
02087       else
02088         style->m_fontFlags &= ~(uint) FBold;
02089       style->m_featuresSet |= SFont;
02090       style->m_featuresSet |= SFontFlag;
02091     }
02092     if ( f.underline() != (m_fontFlags & (uint) FUnderline ) )
02093     {
02094       if ( f.underline() )
02095         style->m_fontFlags |= FUnderline;
02096       else
02097         style->m_fontFlags &= ~(uint) FUnderline;
02098       style->m_featuresSet |= SFont;
02099       style->m_featuresSet |= SFontFlag;
02100     }
02101     if ( f.strikeOut() != (m_fontFlags & (uint) FStrike ) )
02102     {
02103       if ( f.strikeOut() )
02104         style->m_fontFlags |= FStrike;
02105       else
02106         style->m_fontFlags &= ~(uint) FStrike;
02107       style->m_featuresSet |= SFont;
02108       style->m_featuresSet |= SFontFlag;
02109     }
02110 
02111     return style;
02112   }
02113 
02114   if ( m_fontFamily != f.family() )
02115   {
02116     m_fontFamily = f.family();
02117     m_featuresSet |= SFont;
02118     m_featuresSet |= SFontFamily;
02119   }
02120   if ( m_fontSize != f.pointSize() )
02121   {
02122     m_fontSize = f.pointSize();
02123     m_featuresSet |= SFont;
02124     m_featuresSet |= SFontSize;
02125   }
02126   if ( f.italic() != (m_fontFlags & (uint) FItalic ) )
02127   {
02128     if ( f.italic() )
02129       m_fontFlags |= FItalic;
02130     else
02131       m_fontFlags &= ~(uint) FItalic;
02132     m_featuresSet |= SFont;
02133     m_featuresSet |= SFontFlag;
02134   }
02135   if ( f.bold() != (m_fontFlags & (uint) FBold ) )
02136   {
02137     if ( f.bold() )
02138       m_fontFlags |= FBold;
02139     else
02140       m_fontFlags &= ~(uint) FBold;
02141     m_featuresSet |= SFont;
02142     m_featuresSet |= SFontFlag;
02143   }
02144   if ( f.underline() != (m_fontFlags & (uint) FUnderline ) )
02145   {
02146     if ( f.underline() )
02147       m_fontFlags |= FUnderline;
02148     else
02149       m_fontFlags &= ~(uint) FUnderline;
02150     m_featuresSet |= SFont;
02151     m_featuresSet |= SFontFlag;
02152   }
02153   if ( f.strikeOut() != (m_fontFlags & (uint) FStrike ) )
02154   {
02155     if ( f.strikeOut() )
02156       m_fontFlags |= FStrike;
02157     else
02158       m_fontFlags &= ~(uint) FStrike;
02159     m_featuresSet |= SFont;
02160     m_featuresSet |= SFontFlag;
02161   }
02162 
02163   return this;
02164 }
02165 
02166 Style * Style::setFontFamily( QString const & fam )
02167 {
02168   if ( m_type != AUTO || m_usageCount > 1 )
02169   {
02170     if ( m_fontFamily != fam )
02171     {
02172       Style * style  = new Style( this );
02173       style->m_fontFamily   = fam;
02174       style->m_featuresSet |= SFontFamily;
02175       style->m_featuresSet |= SFont;
02176       return style;
02177     }
02178     return this;
02179   }
02180 
02181   m_fontFamily   = fam;
02182   m_featuresSet |= SFont;
02183   m_featuresSet |= SFontFamily;
02184   return this;
02185 }
02186 
02187 Style * Style::setFontFlags( uint flags )
02188 {
02189   if ( m_type != AUTO || m_usageCount > 1 )
02190   {
02191     if ( m_fontFlags != flags )
02192     {
02193       Style * style = new Style( this );
02194       style->m_fontFlags = flags;
02195       style->m_featuresSet |= SFontFlag;
02196       style->m_featuresSet |= SFont;
02197       return style;
02198     }
02199     return this;
02200   }
02201 
02202   m_fontFlags    = flags;
02203   m_featuresSet |= SFont;
02204   m_featuresSet |= SFontFlag;
02205   return this;
02206 }
02207 
02208 Style * Style::setFontSize( int size )
02209 {
02210   if ( m_type != AUTO || m_usageCount > 1 )
02211   {
02212     if ( m_fontSize != size )
02213     {
02214       Style * style  = new Style( this );
02215       style->m_fontSize     = size;
02216       style->m_featuresSet |= SFontSize;
02217       style->m_featuresSet |= SFont;
02218       return style;
02219     }
02220     return this;
02221   }
02222 
02223   m_fontSize     = size;
02224   m_featuresSet |= SFont;
02225   m_featuresSet |= SFontSize;
02226   return this;
02227 }
02228 
02229 Style * Style::setPen( QPen const & pen )
02230 {
02231   if ( m_type != AUTO || m_usageCount > 1 )
02232   {
02233     Style * style = new Style( this );
02234     style->m_textPen = pen;
02235     if ( style->m_textPen.style() != Qt::NoPen )
02236     style->m_featuresSet |= STextPen;
02237     return style;
02238   }
02239 
02240   m_textPen = pen;
02241   if ( m_textPen.style() != Qt::NoPen )
02242       m_featuresSet |= STextPen;
02243   return this;
02244 }
02245 
02246 Style * Style::setBgColor( QColor const & color )
02247 {
02248   if ( m_type != AUTO || m_usageCount > 1 )
02249   {
02250     Style * style = new Style( this );
02251     style->m_bgColor = color;
02252     if ( style->m_bgColor != Qt::white )
02253     style->m_featuresSet |= SBackgroundColor;
02254     return style;
02255   }
02256 
02257   m_bgColor = color;
02258   if ( m_bgColor != Qt::white )
02259       m_featuresSet |= SBackgroundColor;
02260   return this;
02261 }
02262 
02263 Style * Style::setRightBorderPen( QPen const & pen )
02264 {
02265   if ( m_type != AUTO || m_usageCount > 1 )
02266   {
02267     Style * style = new Style( this );
02268     style->m_rightBorderPen = pen;
02269     style->m_rightPenValue = calculateValue( pen );
02270     if ( style->m_rightBorderPen.style() != Qt::NoPen )
02271     style->m_featuresSet |= SRightBorder;
02272     return style;
02273   }
02274 
02275   m_rightBorderPen = pen;
02276   m_rightPenValue = calculateValue( pen );
02277   if ( m_rightBorderPen.style() != Qt::NoPen )
02278       m_featuresSet |= SRightBorder;
02279   return this;
02280 }
02281 
02282 Style * Style::setBottomBorderPen( QPen const & pen )
02283 {
02284   if ( m_type != AUTO || m_usageCount > 1 )
02285   {
02286     Style * style = new Style( this );
02287     style->m_bottomBorderPen = pen;
02288     style->m_bottomPenValue = calculateValue( pen );
02289     if ( style->m_bottomBorderPen.style() != Qt::NoPen )
02290         style->m_featuresSet |= SBottomBorder;
02291     return style;
02292   }
02293 
02294   m_bottomBorderPen = pen;
02295   m_bottomPenValue = calculateValue( pen );
02296   if ( m_bottomBorderPen.style() != Qt::NoPen )
02297       m_featuresSet |= SBottomBorder;
02298   return this;
02299 }
02300 
02301 Style * Style::setLeftBorderPen( QPen const & pen )
02302 {
02303   if ( m_type != AUTO || m_usageCount > 1 )
02304   {
02305     Style * style = new Style( this );
02306     style->m_leftBorderPen = pen;
02307     style->m_leftPenValue = calculateValue( pen );
02308     if ( style->m_leftBorderPen.style() != Qt::NoPen )
02309     style->m_featuresSet |= SLeftBorder;
02310     return style;
02311   }
02312 
02313   m_leftBorderPen = pen;
02314   m_leftPenValue = calculateValue( pen );
02315   if ( m_leftBorderPen.style() != Qt::NoPen )
02316       m_featuresSet |= SLeftBorder;
02317   return this;
02318 }
02319 
02320 Style * Style::setTopBorderPen( QPen const & pen )
02321 {
02322   if ( m_type != AUTO || m_usageCount > 1 )
02323   {
02324     Style * style = new Style( this );
02325     style->m_topBorderPen = pen;
02326     style->m_topPenValue = calculateValue( pen );
02327     if ( style->m_topBorderPen.style() != Qt::NoPen )
02328     style->m_featuresSet |= STopBorder;
02329     return style;
02330   }
02331 
02332   m_topBorderPen = pen;
02333   m_topPenValue = calculateValue( pen );
02334   if ( m_topBorderPen.style() != Qt::NoPen )
02335       m_featuresSet |= STopBorder;
02336   return this;
02337 }
02338 
02339 Style * Style::setFallDiagonalPen( QPen const & pen )
02340 {
02341   if ( m_type != AUTO || m_usageCount > 1 )
02342   {
02343     Style * style = new Style( this );
02344     style->m_fallDiagonalPen = pen;
02345     if ( style->m_fallDiagonalPen.style() != Qt::NoPen )
02346     style->m_featuresSet |= SFallDiagonal;
02347     return style;
02348   }
02349 
02350   m_fallDiagonalPen = pen;
02351   if ( m_fallDiagonalPen.style() != Qt::NoPen )
02352       m_featuresSet |= SFallDiagonal;
02353   return this;
02354 }
02355 
02356 Style * Style::setGoUpDiagonalPen( QPen const & pen )
02357 {
02358   if ( m_type != AUTO || m_usageCount > 1 )
02359   {
02360     Style * style = new Style( this );
02361     style->m_goUpDiagonalPen = pen;
02362     if ( style->m_goUpDiagonalPen.style() != Qt::NoPen )
02363     style->m_featuresSet |= SGoUpDiagonal;
02364     return style;
02365   }
02366 
02367   m_goUpDiagonalPen = pen;
02368   if ( m_goUpDiagonalPen.style() != Qt::NoPen )
02369       m_featuresSet |= SGoUpDiagonal;
02370   return this;
02371 }
02372 
02373 Style * Style::setRotateAngle( int angle )
02374 {
02375   if ( m_type != AUTO || m_usageCount > 1 )
02376   {
02377     Style * style = new Style( this );
02378     style->m_rotateAngle = angle;
02379     style->m_featuresSet |= SAngle;
02380     return style;
02381   }
02382 
02383   m_rotateAngle = angle;
02384   m_featuresSet |= SAngle;
02385   return this;
02386 }
02387 
02388 Style * Style::setIndent( double indent )
02389 {
02390   if ( m_type != AUTO || m_usageCount > 1 )
02391   {
02392     Style * style = new Style( this );
02393     style->m_indent = indent;
02394     style->m_featuresSet |= SIndent;
02395     return style;
02396   }
02397 
02398   m_indent = indent;
02399   m_featuresSet |= SIndent;
02400   return this;
02401 }
02402 
02403 Style * Style::setBackGroundBrush( QBrush const & brush )
02404 {
02405   if ( m_type != AUTO || m_usageCount > 1 )
02406   {
02407     Style * style = new Style( this );
02408     style->m_backGroundBrush = brush;
02409     if ( style->m_backGroundBrush.style() != Qt::NoBrush )
02410     style->m_featuresSet |= SBackgroundBrush;
02411     return style;
02412   }
02413 
02414   m_backGroundBrush = brush;
02415   if ( m_backGroundBrush.style() != Qt::NoBrush )
02416       m_featuresSet |= SBackgroundBrush;
02417   return this;
02418 }
02419 
02420 Style * Style::setFloatFormat( Format::FloatFormat format )
02421 {
02422   if ( m_type != AUTO || m_usageCount > 1 )
02423   {
02424     Style * style = new Style( this );
02425     style->m_floatFormat = format;
02426     style->m_featuresSet |= SFloatFormat;
02427     return style;
02428   }
02429 
02430   m_floatFormat = format;
02431   m_featuresSet |= SFloatFormat;
02432   return this;
02433 }
02434 
02435 Style * Style::setFloatColor( Format::FloatColor color )
02436 {
02437   if ( m_type != AUTO || m_usageCount > 1 )
02438   {
02439     Style * style = new Style( this );
02440     style->m_floatColor = color;
02441     style->m_featuresSet |= SFloatColor;
02442     return style;
02443   }
02444 
02445   m_floatColor = color;
02446   m_featuresSet |= SFloatColor;
02447   return this;
02448 }
02449 
02450 Style * Style::setStrFormat( QString const & strFormat )
02451 {
02452   if ( m_type != AUTO || m_usageCount > 1 )
02453   {
02454     Style * style = new Style( this );
02455     style->m_strFormat = strFormat;
02456     style->m_featuresSet |= SCustomFormat;
02457     return style;
02458   }
02459 
02460   m_strFormat = strFormat;
02461   m_featuresSet |= SCustomFormat;
02462   return this;
02463 }
02464 
02465 Style * Style::setPrecision( int precision )
02466 {
02467   if ( m_type != AUTO || m_usageCount > 1 )
02468   {
02469     Style * style = new Style( this );
02470     style->m_precision = precision;
02471     style->m_featuresSet |= SPrecision;
02472     return style;
02473   }
02474 
02475   m_precision = precision;
02476   m_featuresSet |= SPrecision;
02477   return this;
02478 }
02479 
02480 Style * Style::setPrefix( QString const & prefix )
02481 {
02482   if ( m_type != AUTO || m_usageCount > 1 )
02483   {
02484     Style * style = new Style( this );
02485     style->m_prefix = prefix;
02486     style->m_featuresSet |= SPrefix;
02487     return style;
02488   }
02489 
02490   m_prefix = prefix;
02491   m_featuresSet |= SPrefix;
02492   return this;
02493 }
02494 
02495 Style * Style::setPostfix( QString const & postfix )
02496 {
02497   if ( m_type != AUTO || m_usageCount > 1 )
02498   {
02499     Style * style = new Style( this );
02500     style->m_postfix = postfix;
02501     style->m_featuresSet |= SPostfix;
02502     return style;
02503   }
02504 
02505   m_postfix = postfix;
02506   m_featuresSet |= SPostfix;
02507   return this;
02508 }
02509 
02510 Style * Style::setCurrency( Format::Currency const & currency )
02511 {
02512   if ( m_type != AUTO || m_usageCount > 1 )
02513   {
02514     Style * style = new Style( this );
02515     style->m_currency = currency;
02516     style->m_featuresSet |= SFormatType;
02517     return style;
02518   }
02519 
02520   m_currency = currency;
02521   m_featuresSet |= SFormatType;
02522   return this;
02523 }
02524 
02525 Style * Style::setProperty( Properties p )
02526 {
02527   if ( m_type != AUTO || m_usageCount > 1 )
02528   {
02529     Style * style = new Style( this );
02530     style->m_properties |= (uint) p;
02531     switch( p )
02532     {
02533      case PDontPrintText:
02534       style->m_featuresSet |= SDontPrintText;
02535       break;
02536      case PCustomFormat:
02537       style->m_featuresSet |= SCustomFormat;
02538       break;
02539      case PNotProtected:
02540       style->m_featuresSet |= SNotProtected;
02541       break;
02542      case PHideAll:
02543       style->m_featuresSet |= SHideAll;
02544       break;
02545      case PHideFormula:
02546       style->m_featuresSet |= SHideFormula;
02547       break;
02548      case PMultiRow:
02549       style->m_featuresSet |= SMultiRow;
02550       break;
02551      case PVerticalText:
02552       style->m_featuresSet |= SVerticalText;
02553       break;
02554      default:
02555       kdWarning() << "Unhandled property" << endl;
02556     }
02557     return style;
02558   }
02559 
02560   m_properties |= (uint) p;
02561   switch( p )
02562   {
02563    case PDontPrintText:
02564     m_featuresSet |= SDontPrintText;
02565     break;
02566    case PCustomFormat:
02567     m_featuresSet |= SCustomFormat;
02568     break;
02569    case PNotProtected:
02570      m_featuresSet |= SNotProtected;
02571     break;
02572    case PHideAll:
02573     m_featuresSet |= SHideAll;
02574     break;
02575    case PHideFormula:
02576     m_featuresSet |= SHideFormula;
02577     break;
02578    case PMultiRow:
02579     m_featuresSet |= SMultiRow;
02580     break;
02581    case PVerticalText:
02582     m_featuresSet |= SVerticalText;
02583     break;
02584    default:
02585     kdWarning() << "Unhandled property" << endl;
02586   }
02587   return this;
02588 }
02589 
02590 Style * Style::clearProperty( Properties p )
02591 {
02592   if ( m_type != AUTO || m_usageCount > 1 )
02593   {
02594     Style * style = new Style( this );
02595     style->m_properties &= ~(uint) p;
02596     switch( p )
02597     {
02598      case PDontPrintText:
02599       style->m_featuresSet |= SDontPrintText;
02600       break;
02601      case PCustomFormat:
02602       style->m_featuresSet |= SCustomFormat;
02603       break;
02604      case PNotProtected:
02605       style->m_featuresSet |= SNotProtected;
02606       break;
02607      case PHideAll:
02608       style->m_featuresSet |= SHideAll;
02609       break;
02610      case PHideFormula:
02611       style->m_featuresSet |= SHideFormula;
02612       break;
02613      case PMultiRow:
02614       style->m_featuresSet |= SMultiRow;
02615       break;
02616      case PVerticalText:
02617       style->m_featuresSet |= SVerticalText;
02618       break;
02619      default:
02620       kdWarning() << "Unhandled property" << endl;
02621     }
02622     return style;
02623   }
02624 
02625   m_properties &= ~(uint) p;
02626   switch( p )
02627   {
02628    case PDontPrintText:
02629     m_featuresSet |= SDontPrintText;
02630     break;
02631    case PCustomFormat:
02632     m_featuresSet |= SCustomFormat;
02633     break;
02634    case PNotProtected:
02635     m_featuresSet |= SNotProtected;
02636     break;
02637    case PHideAll:
02638     m_featuresSet |= SHideAll;
02639     break;
02640    case PHideFormula:
02641     m_featuresSet |= SHideFormula;
02642     break;
02643    case PMultiRow:
02644     m_featuresSet |= SMultiRow;
02645     break;
02646    case PVerticalText:
02647     m_featuresSet |= SVerticalText;
02648     break;
02649    default:
02650     kdWarning() << "Unhandled property" << endl;
02651   }
02652   return this;
02653 }
02654 
02655 
02656 Style * Style::setFormatType( FormatType format )
02657 {
02658   if ( m_type != AUTO || m_usageCount > 1 )
02659   {
02660     Style * style  = new Style( this );
02661     style->m_formatType  = format;
02662     style->m_featuresSet |= SFormatType;
02663     return style;
02664   }
02665 
02666   m_formatType  = format;
02667   m_featuresSet |= SFormatType;
02668   return this;
02669 }
02670 
02671 QString Style::colorName( const QColor& color )
02672 {
02673     static QMap<QRgb , QString> map;
02674 
02675     QRgb rgb = color.rgb();
02676 
02677     if (!map.contains( rgb ))
02678     {
02679         map[rgb] = color.name();
02680         return map[rgb];
02681     }
02682     else
02683     {
02684         return map[rgb];
02685     }
02686 }
02687 
02694 CustomStyle::CustomStyle()
02695   : Style(),
02696     m_name( "Default" )
02697 {
02698   m_type   = BUILTIN;
02699   m_parent = 0;
02700 }
02701 
02702 CustomStyle::CustomStyle( Style * parent, QString const & name )
02703   : Style(),
02704     m_name( name )
02705 {
02706   m_type   = CUSTOM;
02707   m_parent = 0;
02708 
02709   // one to one copy
02710   if ( parent->hasProperty( PDontPrintText ) )
02711     addProperty( PDontPrintText );
02712   if ( parent->hasProperty( PCustomFormat ) )
02713     addProperty( PCustomFormat );
02714   if ( parent->hasProperty( PNotProtected ) )
02715     addProperty( PNotProtected );
02716   if ( parent->hasProperty( PHideAll ) )
02717     addProperty( PHideAll );
02718   if ( parent->hasProperty( PHideFormula ) )
02719     addProperty( PHideFormula );
02720   if ( parent->hasProperty( PMultiRow ) )
02721     addProperty( PMultiRow );
02722   if ( parent->hasProperty( PVerticalText ) )
02723     addProperty( PVerticalText );
02724 
02725   changeAlignX( parent->alignX() );
02726   changeAlignY( parent->alignY() );
02727   changeFloatFormat( parent->floatFormat() );
02728   changeFloatColor( parent->floatColor() );
02729   changeFormatType( parent->formatType() );
02730   changeFontFamily( parent->fontFamily() );
02731   changeFontSize( parent->fontSize() );
02732   changeFontFlags( parent->fontFlags() );
02733   changePen( parent->pen() );
02734   changeBgColor( parent->bgColor() );
02735   changeRightBorderPen( parent->rightBorderPen() );
02736   changeBottomBorderPen( parent->bottomBorderPen() );
02737   changeLeftBorderPen( parent->leftBorderPen() );
02738   changeTopBorderPen( parent->topBorderPen() );
02739   changeFallBorderPen( parent->fallDiagonalPen() );
02740   changeGoUpBorderPen( parent->goUpDiagonalPen() );
02741   changeBackGroundBrush( parent->backGroundBrush() );
02742   changeRotateAngle( parent->rotateAngle() );
02743   changeIndent( parent->indent() );
02744   changeStrFormat( parent->strFormat() );
02745   changePrecision( parent->precision() );
02746   changePrefix( parent->prefix() );
02747   changePostfix( parent->postfix() );
02748   changeCurrency( parent->currency() );
02749 }
02750 
02751 CustomStyle::CustomStyle( QString const & name, CustomStyle * parent )
02752   : Style(),
02753     m_name( name )
02754 {
02755   m_parent = parent;
02756   if ( m_parent )
02757     m_parentName = m_parent->name();
02758 }
02759 
02760 CustomStyle::~CustomStyle()
02761 {
02762 }
02763 
02764 QString CustomStyle::saveOasis( KoGenStyle& style, KoGenStyles &mainStyles )
02765 {
02766     // If the type is undefined, we're called from Format
02767     // and the OASIS style is not an automatic style.
02768     // TODO: As the user styles are already created, look them up
02769     //       in what way ever and return here.
02770 //     if ( style.type() == 0 && ( m_type == BUILTIN ) && ( m_name == "Default" ) )
02771 //       return "Default";
02772     if ( style.type() == 0 )
02773       style = KoGenStyle( Doc::STYLE_CELL_USER, "table-cell" );
02774 
02775     if ( m_name.isEmpty() )
02776         return QString::null; // TODO fallback to Style::saveOasis() ???
02777 
02778     // default style does not need display name
02779     if( type() != BUILTIN || m_name != "Default" )
02780         style.addAttribute( "style:display-name", m_name );
02781 
02782     // doing the real work
02783     saveOasisStyle( style, mainStyles );
02784 
02785     // The lookup is done in the calling object (Format).
02786     if ( style.type() == Doc::STYLE_CELL_AUTO )
02787         return QString::null;
02788 
02789     if( ( m_type == BUILTIN ) && ( m_name == "Default" ) )
02790     {
02791         style.setDefaultStyle(true);
02792         // don't i18n'ize "Default" in this case
02793         return mainStyles.lookup( style, "Default", KoGenStyles::DontForceNumbering );
02794     }
02795     else
02796         // this is a custom style
02797         return mainStyles.lookup( style, "custom-style" );
02798 }
02799 
02800 void CustomStyle::loadOasis( KoOasisStyles& oasisStyles, const QDomElement& style, const QString & name )
02801 {
02802     m_name = name;
02803     if ( style.hasAttributeNS( KoXmlNS::style, "parent-style-name" ) )
02804         m_parentName = style.attributeNS( KoXmlNS::style, "parent-style-name", QString::null );
02805     else if ( m_name != "Default" )
02806         m_parentName = "Default";
02807 
02808     m_type = CUSTOM;
02809 
02810     Style::loadOasisStyle( oasisStyles, style );
02811 }
02812 
02813 void CustomStyle::save( QDomDocument & doc, QDomElement & styles )
02814 {
02815   if ( m_name.isEmpty() )
02816     return;
02817 
02818   QDomElement style( doc.createElement( "style" ) );
02819   style.setAttribute( "type", (int) m_type );
02820   if ( m_parent )
02821     style.setAttribute( "parent", m_parent->name() );
02822   style.setAttribute( "name", m_name );
02823 
02824   QDomElement format( doc.createElement( "format" ) );
02825   saveXML( doc, format );
02826   style.appendChild( format );
02827 
02828   styles.appendChild( style );
02829 }
02830 
02831 bool CustomStyle::loadXML( QDomElement const & style, QString const & name )
02832 {
02833   m_name = name;
02834 
02835   if ( style.hasAttribute( "parent" ) )
02836     m_parentName = style.attribute( "parent" );
02837 
02838   if ( !style.hasAttribute( "type" ) )
02839     return false;
02840 
02841   bool ok = true;
02842   m_type = (StyleType) style.attribute( "type" ).toInt( &ok );
02843   if ( !ok )
02844     return false;
02845 
02846   QDomElement f( style.namedItem( "format" ).toElement() );
02847   if ( !f.isNull() )
02848     if ( !Style::loadXML( f ) )
02849       return false;
02850 
02851   return true;
02852 }
02853 
02854 void CustomStyle::setName( QString const & name )
02855 {
02856   m_name = name;
02857 }
02858 
02859 void CustomStyle::refreshParentName()
02860 {
02861   if ( m_parent )
02862     m_parentName = m_parent->name();
02863 }
02864 
02865 bool CustomStyle::definesAll() const
02866 {
02867   if ( !( m_featuresSet & (uint) SAlignX ) )
02868     return false;
02869   if ( !( m_featuresSet & (uint) SAlignY ) )
02870     return false;
02871   if ( !( m_featuresSet & (uint) SPrefix ) )
02872     return false;
02873   if ( !( m_featuresSet & (uint) SPostfix ) )
02874     return false;
02875   if ( !( m_featuresSet & (uint) SLeftBorder ) )
02876     return false;
02877   if ( !( m_featuresSet & (uint) SRightBorder ) )
02878     return false;
02879   if ( !( m_featuresSet & (uint) STopBorder ) )
02880     return false;
02881   if ( !( m_featuresSet & (uint) SBottomBorder ) )
02882     return false;
02883   if ( !( m_featuresSet & (uint) SFallDiagonal ) )
02884     return false;
02885   if ( !( m_featuresSet & (uint) SGoUpDiagonal ) )
02886     return false;
02887   if ( !( m_featuresSet & (uint) SBackgroundBrush ) )
02888     return false;
02889   if ( !( m_featuresSet & (uint) SFontFamily ) )
02890     return false;
02891   if ( !( m_featuresSet & (uint) SFontSize ) )
02892     return false;
02893   if ( !( m_featuresSet & (uint) SFontFlag ) )
02894     return false;
02895   if ( !( m_featuresSet & (uint) STextPen ) )
02896     return false;
02897   if ( !( m_featuresSet & (uint) SBackgroundColor ) )
02898     return false;
02899   if ( !( m_featuresSet & (uint) SFloatFormat ) )
02900     return false;
02901   if ( !( m_featuresSet & (uint) SFloatColor ) )
02902     return false;
02903   if ( !( m_featuresSet & (uint) SMultiRow ) )
02904     return false;
02905   if ( !( m_featuresSet & (uint) SVerticalText ) )
02906     return false;
02907   if ( !( m_featuresSet & (uint) SPrecision ) )
02908     return false;
02909   if ( !( m_featuresSet & (uint) SFormatType ) )
02910     return false;
02911   if ( !( m_featuresSet & (uint) SAngle ) )
02912     return false;
02913   if ( !( m_featuresSet & (uint) SIndent ) )
02914     return false;
02915   if ( !( m_featuresSet & (uint) SDontPrintText ) )
02916     return false;
02917   if ( !( m_featuresSet & (uint) SCustomFormat ) )
02918     return false;
02919   if ( !( m_featuresSet & (uint) SNotProtected ) )
02920     return false;
02921   if ( !( m_featuresSet & (uint) SHideAll ) )
02922     return false;
02923   if ( !( m_featuresSet & (uint) SHideFormula ) )
02924     return false;
02925 
02926   return true;
02927 }
02928 
02929 void CustomStyle::changeAlignX( Format::Align alignX )
02930 {
02931   m_alignX = alignX;
02932   m_featuresSet |= SAlignX;
02933 }
02934 
02935 void CustomStyle::changeAlignY( Format::AlignY alignY )
02936 {
02937   m_alignY = alignY;
02938   m_featuresSet |= SAlignY;
02939 }
02940 
02941 void CustomStyle::changeFont( QFont const & f )
02942 {
02943   if ( m_fontFamily != f.family() )
02944   {
02945     m_fontFamily = f.family();
02946     m_featuresSet |= SFontFamily;
02947     m_featuresSet |= SFont;
02948   }
02949   if ( m_fontSize != f.pointSize() )
02950   {
02951     m_fontSize = f.pointSize();
02952     m_featuresSet |= SFont;
02953     m_featuresSet |= SFontSize;
02954   }
02955 
02956   if ( f.italic() != (m_fontFlags & (uint) FItalic ) )
02957   {
02958     if ( f.italic() )
02959       m_fontFlags |= FItalic;
02960     else
02961       m_fontFlags &= ~(uint) FItalic;
02962     m_featuresSet |= SFont;
02963     m_featuresSet |= SFontFlag;
02964   }
02965   if ( f.bold() != (m_fontFlags & (uint) FBold ) )
02966   {
02967     if ( f.bold() )
02968       m_fontFlags |= FBold;
02969     else
02970       m_fontFlags &= ~(uint) FBold;
02971     m_featuresSet |= SFont;
02972     m_featuresSet |= SFontFlag;
02973   }
02974   if ( f.underline() != (m_fontFlags & (uint) FUnderline ) )
02975   {
02976     if ( f.underline() )
02977       m_fontFlags |= FUnderline;
02978     else
02979       m_fontFlags &= ~(uint) FUnderline;
02980     m_featuresSet |= SFont;
02981     m_featuresSet |= SFontFlag;
02982   }
02983   if ( f.strikeOut() != (m_fontFlags & (uint) FStrike ) )
02984   {
02985     if ( f.strikeOut() )
02986       m_fontFlags |= FStrike;
02987     else
02988       m_fontFlags &= ~(uint) FStrike;
02989     m_featuresSet |= SFont;
02990     m_featuresSet |= SFontFlag;
02991   }
02992 }
02993 
02994 void CustomStyle::changeFontFamily( QString const & fam )
02995 {
02996   if ( m_fontFamily != fam )
02997   {
02998     m_fontFamily   = fam;
02999     m_featuresSet |= SFont;
03000     m_featuresSet |= SFontFamily;
03001   }
03002 }
03003 
03004 void CustomStyle::changeFontSize( int size )
03005 {
03006   if ( m_fontSize != size )
03007   {
03008     m_fontSize     = size;
03009     m_featuresSet |= SFont;
03010     m_featuresSet |= SFontSize;
03011   }
03012 }
03013 
03014 void CustomStyle::changeFontFlags( uint flags )
03015 {
03016   if ( m_fontFlags != flags )
03017   {
03018     m_fontFlags    = flags;
03019     m_featuresSet |= SFont;
03020     m_featuresSet |= SFontFlag;
03021   }
03022 }
03023 
03024 void CustomStyle::changeTextColor( QColor const & color )
03025 {
03026   m_textPen.setColor( color );
03027   m_featuresSet |= STextPen;
03028 }
03029 
03030 void CustomStyle::changePen( QPen const & pen )
03031 {
03032   m_textPen = pen;
03033   m_featuresSet |= STextPen;
03034 }
03035 
03036 void CustomStyle::changeBgColor( QColor const & color )
03037 {
03038   m_bgColor = color;
03039   m_featuresSet |= SBackgroundColor;
03040 }
03041 
03042 void CustomStyle::changeRightBorderPen( QPen const & pen )
03043 {
03044   m_rightBorderPen = pen;
03045   m_rightPenValue  = calculateValue( pen );
03046   m_featuresSet   |= SRightBorder;
03047 }
03048 
03049 void CustomStyle::changeBottomBorderPen( QPen const & pen )
03050 {
03051   m_bottomBorderPen = pen;
03052   m_bottomPenValue  = calculateValue( pen );
03053   m_featuresSet    |= SBottomBorder;
03054 }
03055 
03056 void CustomStyle::changeLeftBorderPen( QPen const & pen )
03057 {
03058   m_leftBorderPen = pen;
03059   m_leftPenValue  = calculateValue( pen );
03060   m_featuresSet  |= SLeftBorder;
03061 }
03062 
03063 void CustomStyle::changeTopBorderPen( QPen const & pen )
03064 {
03065   m_topBorderPen = pen;
03066   m_topPenValue  = calculateValue( pen );
03067   m_featuresSet |= STopBorder;
03068 }
03069 
03070 void CustomStyle::changeFallBorderPen( QPen const & pen )
03071 {
03072   m_fallDiagonalPen = pen;
03073   m_featuresSet |= SFallDiagonal;
03074 }
03075 
03076 void CustomStyle::changeGoUpBorderPen( QPen const & pen )
03077 {
03078   m_goUpDiagonalPen = pen;
03079   m_featuresSet |= SGoUpDiagonal;
03080 }
03081 
03082 void CustomStyle::changeRotateAngle( int angle )
03083 {
03084   m_rotateAngle = angle;
03085   m_featuresSet |= SAngle;
03086 }
03087 
03088 void CustomStyle::changeIndent( double indent )
03089 {
03090   m_indent = indent;
03091   m_featuresSet |= SIndent;
03092 }
03093 
03094 void CustomStyle::changeBackGroundBrush( QBrush const & brush )
03095 {
03096   m_backGroundBrush = brush;
03097   m_featuresSet |= SBackgroundBrush;
03098 }
03099 
03100 void CustomStyle::changeFloatFormat( Format::FloatFormat format )
03101 {
03102   m_floatFormat = format;
03103   m_featuresSet |= SFloatFormat;
03104 }
03105 
03106 void CustomStyle::changeFloatColor( Format::FloatColor color )
03107 {
03108   m_floatColor = color;
03109   m_featuresSet |= SFloatColor;
03110 }
03111 
03112 void CustomStyle::changeFormatType( FormatType format )
03113 {
03114   m_formatType = format;
03115   m_featuresSet |= SFormatType;
03116 }
03117 
03118 void CustomStyle::changeStrFormat( QString const & strFormat )
03119 {
03120   m_strFormat = strFormat;
03121   m_featuresSet |= SCustomFormat;
03122 }
03123 
03124 void CustomStyle::changePrecision( int precision )
03125 {
03126   m_precision = precision;
03127   m_featuresSet |= SPrecision;
03128 }
03129 
03130 void CustomStyle::changePrefix( QString const & prefix )
03131 {
03132   m_prefix = prefix;
03133   m_featuresSet |= SPrefix;
03134 }
03135 
03136 void CustomStyle::changePostfix( QString const & postfix )
03137 {
03138   m_postfix = postfix;
03139   m_featuresSet |= SPostfix;
03140 }
03141 
03142 void CustomStyle::changeCurrency( Format::Currency const & currency )
03143 {
03144   m_currency = currency;
03145 }
03146 
03147 void CustomStyle::addProperty( Properties p )
03148 {
03149   m_properties |= (uint) p;
03150   switch( p )
03151   {
03152    case PDontPrintText:
03153     m_featuresSet |= SDontPrintText;
03154     break;
03155    case PCustomFormat:
03156     m_featuresSet |= SCustomFormat;
03157     break;
03158    case PNotProtected:
03159     m_featuresSet |= SNotProtected;
03160     break;
03161    case PHideAll:
03162     m_featuresSet |= SHideAll;
03163     break;
03164    case PHideFormula:
03165     m_featuresSet |= SHideFormula;
03166     break;
03167    case PMultiRow:
03168     m_featuresSet |= SMultiRow;
03169     break;
03170    case PVerticalText:
03171     m_featuresSet |= SVerticalText;
03172     break;
03173    default:
03174     kdWarning() << "Unhandled property" << endl;
03175   }
03176 }
03177 
03178 void CustomStyle::removeProperty( Properties p )
03179 {
03180   m_properties &= ~(uint) p;
03181   switch( p )
03182   {
03183    case PDontPrintText:
03184     m_featuresSet &= SDontPrintText;
03185     break;
03186    case PCustomFormat:
03187     m_featuresSet &= SCustomFormat;
03188     break;
03189    case PNotProtected:
03190     m_featuresSet &= SNotProtected;
03191     break;
03192    case PHideAll:
03193     m_featuresSet &= SHideAll;
03194     break;
03195    case PHideFormula:
03196     m_featuresSet &= SHideFormula;
03197     break;
03198    case PMultiRow:
03199     m_featuresSet &= SMultiRow;
03200     break;
03201    case PVerticalText:
03202     m_featuresSet &= SVerticalText;
03203     break;
03204    default:
03205     kdWarning() << "Unhandled property" << endl;
03206   }
03207 }
03208 
03209 bool CustomStyle::operator==( const CustomStyle& other ) const
03210 {
03211   if ( m_name != other.m_name )
03212     return false;
03213   return Style::operator==( other );
03214 }
KDE Home | KDE Accessibility Home | Description of Access Keys