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