kpresenter

KPrBrush.cpp

00001 // -*- Mode: c++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 4; -*-
00002 /* This file is part of the KDE project
00003    Copyright (C) 2005-2006 Thorsten Zachmann <zachmann@kde.org>
00004 
00005    This library is free software; you can redistribute it and/or
00006    modify it under the terms of the GNU Library General Public
00007    License as published by the Free Software Foundation; either
00008    version 2 of the License, or (at your option) any later version.
00009 
00010    This library is distributed in the hope that it will be useful,
00011    but WITHOUT ANY WARRANTY; without even the implied warranty of
00012    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013    Library General Public License for more details.
00014 
00015    You should have received a copy of the GNU Library General Public License
00016    along with this library; see the file COPYING.LIB.  If not, write to
00017    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00018  * Boston, MA 02110-1301, USA.
00019 */
00020 
00021 #include "KPrBrush.h"
00022 
00023 #include <KoGenStyles.h>
00024 #include <KoOasisStyles.h>
00025 #include <KoOasisContext.h>
00026 #include <KoXmlNS.h>
00027 #include "KPrDocument.h"
00028 
00029 KPrBrush::KPrBrush()
00030     : KoBrush()
00031 {
00032 }
00033 
00034 KPrBrush::KPrBrush( const QBrush &brush, const QColor &gColor1, const QColor &gColor2,
00035                     BCType gType, FillType fillType, bool unbalanced,
00036                     int xfactor, int yfactor )
00037     : KoBrush( brush, gColor1,gColor2, gType, fillType, unbalanced, xfactor, yfactor )
00038 {
00039 }
00040 
00041 void KPrBrush::saveOasisFillStyle( KoGenStyle &styleObjectAuto, KoGenStyles& mainStyles ) const
00042 {
00043     switch ( getFillType() )
00044     {
00045         case FT_BRUSH:
00046         {
00047             if( getBrush().style() != Qt::NoBrush )
00048             {
00049                 KoOasisStyles::saveOasisFillStyle( styleObjectAuto, mainStyles, getBrush() );
00050             }
00051             else
00052             {
00053                 styleObjectAuto.addProperty( "draw:fill","none" );
00054             }
00055             break;
00056         }
00057         case FT_GRADIENT:
00058             styleObjectAuto.addProperty( "draw:fill","gradient" );
00059             styleObjectAuto.addProperty( "draw:fill-gradient-name", saveOasisGradientStyle( mainStyles ) );
00060             break;
00061     }
00062 }
00063 
00064 
00065 QString KPrBrush::saveOasisGradientStyle( KoGenStyles& mainStyles ) const
00066 {
00067     KoGenStyle gradientStyle( KPrDocument::STYLE_GRADIENT /*no family name*/);
00068     gradientStyle.addAttribute( "draw:start-color", getGColor1().name() );
00069     gradientStyle.addAttribute( "draw:end-color", getGColor2().name() );
00070 
00071     QString unbalancedx( "50%" );
00072     QString unbalancedy( "50%" );
00073 
00074     if ( getGUnbalanced() )
00075     {
00076         unbalancedx = QString( "%1%" ).arg( getGXFactor() / 4 + 50 );
00077         unbalancedy = QString( "%1%" ).arg( getGYFactor() / 4 + 50 );
00078     }
00079     gradientStyle.addAttribute( "draw:cx", unbalancedx );
00080     gradientStyle.addAttribute( "draw:cy", unbalancedy );
00081 
00082     switch( getGType() )
00083     {
00084         case BCT_PLAIN:
00085             gradientStyle.addAttribute( "draw:angle", 0 );
00086             gradientStyle.addAttribute( "draw:style", "linear" );
00087             break;
00088         case BCT_GHORZ:
00089             gradientStyle.addAttribute( "draw:angle", 0 );
00090             gradientStyle.addAttribute( "draw:style", "linear" );
00091             break;
00092         case BCT_GVERT:
00093             gradientStyle.addAttribute( "draw:angle", 900 );
00094             gradientStyle.addAttribute( "draw:style", "linear" );
00095             break;
00096         case BCT_GDIAGONAL1:
00097             gradientStyle.addAttribute( "draw:angle", 450 );
00098             gradientStyle.addAttribute( "draw:style", "linear" );
00099             break;
00100         case BCT_GDIAGONAL2:
00101             gradientStyle.addAttribute( "draw:angle", 135 );
00102             gradientStyle.addAttribute( "draw:style", "linear" );
00103             break;
00104         case BCT_GCIRCLE:
00105             gradientStyle.addAttribute( "draw:angle", 0 );
00106             gradientStyle.addAttribute( "draw:style", "radial" );
00107             break;
00108         case BCT_GRECT:
00109             gradientStyle.addAttribute( "draw:angle", 0 );
00110             gradientStyle.addAttribute( "draw:style", "square" );
00111             break;
00112         case BCT_GPIPECROSS:
00113             gradientStyle.addAttribute( "draw:angle", 0 );
00114             gradientStyle.addAttribute( "draw:style", "axial" );
00115             break;
00116         case BCT_GPYRAMID: //todo fixme ! it doesn't work !
00117             gradientStyle.addAttribute( "draw:angle", 0 );
00118             gradientStyle.addAttribute( "draw:style", 0 );
00119             break;
00120     }
00121 
00122     return mainStyles.lookup( gradientStyle, "gradient" );
00123 }
00124 
00125 
00126 void KPrBrush::loadOasisFillStyle( KoOasisContext &context, const char * propertyType )
00127 {
00128     KoStyleStack &styleStack = context.styleStack();
00129     styleStack.setTypeProperties( propertyType );
00130 
00131     if ( styleStack.hasAttributeNS( KoXmlNS::draw, "fill" ) )
00132     {
00133         const QString fill = styleStack.attributeNS( KoXmlNS::draw, "fill" );
00134         kdDebug(33001) << " load object gradient fill type :" << fill << endl;
00135 
00136         if ( fill == "solid" || fill == "hatch" )
00137         {
00138             setBrush( KoOasisStyles::loadOasisFillStyle( styleStack, fill, context.oasisStyles() ) );
00139         }
00140         else if ( fill == "gradient" )
00141         {
00142             QString style = styleStack.attributeNS( KoXmlNS::draw, "fill-gradient-name" );
00143             QDomElement* draw = context.oasisStyles().drawStyles()[style];
00144 
00145             if ( draw )
00146             {
00147                 setGColor1( draw->attributeNS( KoXmlNS::draw, "start-color", QString::null ) );
00148                 setGColor2( draw->attributeNS( KoXmlNS::draw, "end-color", QString::null ) );
00149 
00150                 QString type = draw->attributeNS( KoXmlNS::draw, "style", QString::null );
00151                 kdDebug()<<" type :"<<type<<endl;
00152                 if ( type == "linear" )
00153                 {
00154                     int angle = draw->attributeNS( KoXmlNS::draw, "angle", QString::null ).toInt() / 10;
00155 
00156                     // make sure the angle is between 0 and 359
00157                     angle = abs( angle );
00158                     angle -= ( (int) ( angle / 360 ) ) * 360;
00159 
00160                     // What we are trying to do here is to find out if the given
00161                     // angle belongs to a horizontal, vertical or diagonal gradient.
00162                     int lower, upper, nearAngle = 0;
00163                     for ( lower = 0, upper = 45; upper < 360; lower += 45, upper += 45 )
00164                     {
00165                         if ( upper >= angle )
00166                         {
00167                             int distanceToUpper = abs( angle - upper );
00168                             int distanceToLower = abs( angle - lower );
00169                             nearAngle = distanceToUpper > distanceToLower ? lower : upper;
00170                             break;
00171                         }
00172                     }
00173                     // nearAngle should now be one of: 0, 45, 90, 135, 180...
00174                     if ( nearAngle == 0 || nearAngle == 180 )
00175                         setGType( BCT_GHORZ ); // horizontal
00176                     else if ( nearAngle == 90 || nearAngle == 270 )
00177                         setGType( BCT_GVERT ); // vertical
00178                     else if ( nearAngle == 45 || nearAngle == 225 )
00179                         setGType( BCT_GDIAGONAL1 ); // diagonal 1
00180                     else if ( nearAngle == 135 || nearAngle == 315 )
00181                         setGType( BCT_GDIAGONAL2 ); // diagonal 2
00182 
00183                     if ( nearAngle == 180 || nearAngle == 270 || nearAngle == 225 || nearAngle == 315 )
00184                     {
00185                         setGColor1( draw->attributeNS( KoXmlNS::draw, "end-color", QString::null ) );
00186                         setGColor2( draw->attributeNS( KoXmlNS::draw, "start-color", QString::null ) );
00187                     }
00188                 }
00189                 else if ( type == "radial" || type == "ellipsoid" )
00190                     setGType( BCT_GCIRCLE ); // circle
00191                 else if ( type == "square" || type == "rectangular" )
00192                     setGType( BCT_GRECT ); // rectangle
00193                 else if ( type == "axial" )
00194                     setGType( BCT_GPIPECROSS ); // pipecross
00195                 else //safe
00196                     setGType( BCT_PLAIN ); // plain
00197 
00198                 // Hard to map between x- and y-center settings of ooimpress
00199                 // and (un-)balanced settings of kpresenter. Let's try it.
00200                 int x, y;
00201                 if ( draw->hasAttributeNS( KoXmlNS::draw, "cx" ) )
00202                     x = draw->attributeNS( KoXmlNS::draw, "cx", QString::null ).remove( '%' ).toInt();
00203                 else
00204                     x = 50;
00205 
00206                 if ( draw->hasAttributeNS( KoXmlNS::draw, "cy" ) )
00207                     y = draw->attributeNS( KoXmlNS::draw, "cy", QString::null ).remove( '%' ).toInt();
00208                 else
00209                     y = 50;
00210 
00211                 if ( x == 50 && y == 50 )
00212                 {
00213                     setGUnbalanced( false );
00214                     setGXFactor( 100 );
00215                     setGYFactor( 100 );
00216                 }
00217                 else
00218                 {
00219                     setGUnbalanced( true );
00220                     // map 0 - 100% to -200 - 200
00221                     setGXFactor( 4 * x - 200 );
00222                     setGYFactor( 4 * y - 200 );
00223                 }
00224             }
00225 
00226             // We have to set a brush with brushstyle != no background fill
00227             // otherwise the properties dialog for the object won't
00228             // display the preview for the gradient.
00229             QBrush tmpBrush;
00230             tmpBrush.setStyle( static_cast<Qt::BrushStyle>( 1 ) );
00231             setBrush( tmpBrush );
00232             setFillType( FT_GRADIENT );
00233         }
00234         else if ( fill == "none" )
00235         {
00236             //nothing
00237         }
00238         else if ( fill == "bitmap" )
00239         {
00240             //todo
00241             //not implementer in kpresenter...
00242             //the drawing object is filled with the bitmap specified by the draw:fill-image-name attribute.
00243             //QBrush implement setPixmap
00244             //easy just add pixmap and store it.
00245         }
00246     }
00247 }
KDE Home | KDE Accessibility Home | Description of Access Keys