kpresenter

KPrObject.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) 1998, 1999 Reginald Stadlbauer <reggie@kde.org>
00004    Copyright (C) 2005-2006 Thorsten Zachmann <zachmann@kde.org>
00005 
00006    This library is free software; you can redistribute it and/or
00007    modify it under the terms of the GNU Library General Public
00008    License as published by the Free Software Foundation; either
00009    version 2 of the License, or (at your option) any later version.
00010 
00011    This library is distributed in the hope that it will be useful,
00012    but WITHOUT ANY WARRANTY; without even the implied warranty of
00013    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
00014    Library General Public License for more details.
00015 
00016    You should have received a copy of the GNU Library General Public License
00017    along with this library; see the file COPYING.LIB.  If not, write to
00018    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00019  * Boston, MA 02110-1301, USA.
00020 */
00021 
00022 #include "KPrObjectIface.h"
00023 
00024 #include "KPrObject.h"
00025 #include "KPrDocument.h"
00026 #include "KPrUtils.h"
00027 
00028 #include <qpainter.h>
00029 #include <qwmatrix.h>
00030 #include <qpointarray.h>
00031 #include <qregion.h>
00032 #include <qdom.h>
00033 #include <qbuffer.h>
00034 #include <qregexp.h>
00035 
00036 #include <kapplication.h>
00037 #include <KoOasisContext.h>
00038 #include "KoOasisStyles.h"
00039 
00040 #include <stdlib.h>
00041 #include <fstream>
00042 #include <math.h>
00043 #include <float.h>
00044 
00045 #include <KoTextZoomHandler.h>
00046 #include <KoRect.h>
00047 #include <KoSize.h>
00048 #include <KoPoint.h>
00049 #include <KoXmlNS.h>
00050 #include <KoDom.h>
00051 #include <kdebug.h>
00052 
00053 const QString &KPrObject::tagORIG=KGlobal::staticQString("ORIG");
00054 const QString &KPrObject::attrX=KGlobal::staticQString("x");
00055 const QString &KPrObject::attrY=KGlobal::staticQString("y");
00056 const QString &KPrObject::tagSIZE=KGlobal::staticQString("SIZE");
00057 const QString &KPrObject::attrWidth=KGlobal::staticQString("width");
00058 const QString &KPrObject::attrHeight=KGlobal::staticQString("height");
00059 const QString &KPrObject::tagSHADOW=KGlobal::staticQString("SHADOW");
00060 const QString &KPrObject::attrDistance=KGlobal::staticQString("distance");
00061 const QString &KPrObject::attrDirection=KGlobal::staticQString("direction");
00062 const QString &KPrObject::attrColor=KGlobal::staticQString("color");
00063 const QString &KPrObject::tagEFFECTS=KGlobal::staticQString("EFFECTS");
00064 const QString &KPrObject::attrEffect=KGlobal::staticQString("effect");
00065 const QString &KPrObject::attrEffect2=KGlobal::staticQString("effect2");
00066 const QString &KPrObject::tagPRESNUM=KGlobal::staticQString("PRESNUM");
00067 const QString &KPrObject::tagANGLE=KGlobal::staticQString("ANGLE");
00068 const QString &KPrObject::tagDISAPPEAR=KGlobal::staticQString("DISAPPEAR");
00069 const QString &KPrObject::attrDoit=KGlobal::staticQString("doit");
00070 const QString &KPrObject::attrNum=KGlobal::staticQString("num");
00071 const QString &KPrObject::tagFILLTYPE=KGlobal::staticQString("FILLTYPE");
00072 const QString &KPrObject::tagGRADIENT=KGlobal::staticQString("GRADIENT");
00073 const QString &KPrObject::tagPEN=KGlobal::staticQString("PEN");
00074 const QString &KPrObject::tagBRUSH=KGlobal::staticQString("BRUSH");
00075 const QString &KPrObject::attrValue=KGlobal::staticQString("value");
00076 const QString &KPrObject::attrC1=KGlobal::staticQString("color1");
00077 const QString &KPrObject::attrC2=KGlobal::staticQString("color2");
00078 const QString &KPrObject::attrType=KGlobal::staticQString("type");
00079 const QString &KPrObject::attrUnbalanced=KGlobal::staticQString("unbalanced");
00080 const QString &KPrObject::attrXFactor=KGlobal::staticQString("xfactor");
00081 const QString &KPrObject::attrYFactor=KGlobal::staticQString("yfactor");
00082 const QString &KPrObject::attrStyle=KGlobal::staticQString("style");
00083 
00084 KPrStartEndLine::KPrStartEndLine( LineEnd _start, LineEnd _end )
00085     : lineBegin( _start ), lineEnd( _end )
00086 {
00087 }
00088 
00089 void KPrStartEndLine::save( QDomDocumentFragment &fragment, QDomDocument& doc )
00090 {
00091     if (lineBegin!=L_NORMAL)
00092         fragment.appendChild(KPrStartEndLine::createValueElement("LINEBEGIN", static_cast<int>(lineBegin), doc));
00093     if (lineEnd!=L_NORMAL)
00094         fragment.appendChild(KPrStartEndLine::createValueElement("LINEEND", static_cast<int>(lineEnd), doc));
00095 }
00096 
00097 QDomElement KPrStartEndLine::createValueElement(const QString &tag, int value, QDomDocument &doc)
00098 {
00099     QDomElement elem=doc.createElement(tag);
00100     elem.setAttribute("value", value);
00101     return elem;
00102 }
00103 
00104 
00105 void KPrStartEndLine::load( const QDomElement &element )
00106 {
00107     QDomElement e=element.namedItem("LINEBEGIN").toElement();
00108     if(!e.isNull()) {
00109         int tmp=0;
00110         if(e.hasAttribute("value"))
00111             tmp=e.attribute("value").toInt();
00112         lineBegin=static_cast<LineEnd>(tmp);
00113     }
00114     e=element.namedItem("LINEEND").toElement();
00115     if(!e.isNull()) {
00116         int tmp=0;
00117         if(e.hasAttribute("value"))
00118             tmp=e.attribute("value").toInt();
00119         lineEnd=static_cast<LineEnd>(tmp);
00120     }
00121 }
00122 
00123 void KPrStartEndLine::loadOasisMarkerElement( KoOasisContext & context, const QString & attr, LineEnd &_element )
00124 {
00125     //kdDebug()<<"void KPrStartEndLine::loadOasisMarkerElement( KoOasisContext & context, const QString & attr, LineEnd &_element ) :"<<attr<<endl;
00126 
00127     KoStyleStack &styleStack = context.styleStack();
00128     styleStack.setTypeProperties( "graphic" );
00129     if ( styleStack.hasAttributeNS( KoXmlNS::draw,attr.latin1() ) )
00130     {
00131         QString style = styleStack.attributeNS( KoXmlNS::draw, attr.latin1() );
00132         //kdDebug()<<" marker style is  : "<<style<<endl;
00133 
00134         //type not defined by default
00135         //try to use style.
00136         QDomElement* draw = context.oasisStyles().drawStyles()[style];
00137         //kdDebug()<<" marker have oasis style defined :"<<draw<<endl;
00138         if ( draw )
00139         {
00140             if( draw->hasAttributeNS( KoXmlNS::svg, "d" ))
00141             {
00142                 QString str = draw->attributeNS( KoXmlNS::svg, "d", QString::null );
00143                 kdDebug()<<" svg type = "<<str<<endl;
00144                 if ( str == lineEndBeginSvg( L_ARROW ) )
00145                     _element = L_ARROW;
00146                 else if ( str == lineEndBeginSvg( L_CIRCLE ) )
00147                     _element = L_CIRCLE;
00148                 else if ( str == lineEndBeginSvg( L_SQUARE ) )
00149                     _element = L_SQUARE;
00150                 else if ( str == lineEndBeginSvg( L_LINE_ARROW ) )
00151                     _element = L_LINE_ARROW;
00152                 else if ( str == lineEndBeginSvg( L_DIMENSION_LINE ) )
00153                     _element = L_DIMENSION_LINE;
00154                 else if ( str == lineEndBeginSvg( L_DOUBLE_ARROW ) )
00155                     _element = L_DOUBLE_ARROW;
00156                 else if ( str == lineEndBeginSvg( L_DOUBLE_LINE_ARROW ) )
00157                     _element = L_DOUBLE_LINE_ARROW;
00158                 else
00159                 {
00160                     kdDebug()<<" element not defined :"<<str<<endl;
00161                     _element = L_NORMAL;
00162                 }
00163             }
00164         }
00165     }
00166 }
00167 
00168 void KPrStartEndLine::saveOasisMarkerElement( KoGenStyles& mainStyles,  KoGenStyle &styleobjectauto ) const
00169 {
00170     if ( lineBegin != L_NORMAL )
00171     {
00172         styleobjectauto.addProperty( "draw:marker-start", saveOasisMarkerStyle( mainStyles, lineBegin ) );
00173         styleobjectauto.addProperty( "draw:marker-start-width", "0.25cm" );//value from ooimpress
00174     }
00175     if ( lineEnd != L_NORMAL )
00176     {
00177         styleobjectauto.addProperty( "draw:marker-end", saveOasisMarkerStyle( mainStyles, lineEnd ) );
00178         styleobjectauto.addProperty( "draw:marker-end-width", "0.25cm" );
00179     }
00180 }
00181 
00182 QString KPrStartEndLine::saveOasisMarkerStyle( KoGenStyles &mainStyles, const LineEnd &_element ) const
00183 {
00184     KoGenStyle marker( KPrDocument::STYLE_MARKER /*, "graphic"*/ /*no name*/ );
00185     // value used from ooimpress filter I don't know if it's good
00186     switch( _element )
00187     {
00188     case L_NORMAL:
00189         //nothing
00190         break;
00191     case L_ARROW:
00192         marker.addAttribute( "svg:viewBox", "0 0 20 30" );
00193         break;
00194     case L_SQUARE:
00195         marker.addAttribute( "svg:viewBox", "0 0 10 10" );
00196         break;
00197     case L_CIRCLE:
00198         marker.addAttribute( "svg:viewBox", "0 0 1131 1131" );
00199         break;
00200     case L_LINE_ARROW:
00201         marker.addAttribute( "svg:viewBox", "0 0 1122 2243" );
00202         break;
00203     case L_DIMENSION_LINE:
00204         marker.addAttribute( "svg:viewBox", "0 0 836 110" );
00205         break;
00206     case L_DOUBLE_ARROW:
00207         marker.addAttribute( "svg:viewBox", "0 0 1131 1918" );
00208         break;
00209     case L_DOUBLE_LINE_ARROW:
00210         //FIXME !!!!!!!!!!!!
00211         // not defined into ooimpress filter.
00212         //marker.addAttribute( "svg:viewBox", "...." );
00213         //marker.addAttribute( "svg:d", "...." );
00214         break;
00215     }
00216     marker.addAttribute( "svg:d", lineEndBeginSvg( _element ));
00217 
00218     return mainStyles.lookup( marker, "marker" );
00219 }
00220 
00221 KPrObject::KPrObject()
00222     : orig(), ext(), shadowColor( Qt::gray )
00223 {
00224     appearStep = 0;
00225     disappearStep = 1;
00226     effect = EF_NONE;
00227     effect2 = EF2_NONE;
00228     effect3 = EF3_NONE;
00229     m_appearSpeed = ES_MEDIUM;
00230     m_disappearSpeed = ES_MEDIUM;
00231     disappear = false;
00232     appearTimer = 1;
00233     disappearTimer = 1;
00234     appearSoundEffect = false;
00235     disappearSoundEffect = false;
00236     a_fileName = QString::null;
00237     d_fileName = QString::null;
00238     objectName = QString::null;
00239     angle = 0.0;
00240     shadowDirection = SD_RIGHT_BOTTOM;
00241     shadowDistance = 0;
00242     selected = false;
00243     ownClipping = true;
00244     subPresStep = 0;
00245     specEffects = false;
00246     onlyCurrStep = true;
00247     inObjList = true;
00248     cmds = 0;
00249     resize = false;
00250     protect = false;
00251     keepRatio = false;
00252     dcop = 0;
00253 }
00254 
00255 KPrObject::~KPrObject()
00256 {
00257     delete dcop;
00258 }
00259 
00260 QDomDocumentFragment KPrObject::save( QDomDocument& doc, double offset )
00261 {
00262     QDomDocumentFragment fragment=doc.createDocumentFragment();
00263     QDomElement elem=doc.createElement(tagORIG);
00264     elem.setAttribute(attrX, orig.x());
00265     elem.setAttribute(attrY, QString::number( orig.y() + offset, 'g', DBL_DIG ) );
00266     fragment.appendChild(elem);
00267     elem=doc.createElement(tagSIZE);
00268     elem.setAttribute(attrWidth, ext.width());
00269     elem.setAttribute(attrHeight, ext.height());
00270     fragment.appendChild(elem);
00271     if(shadowDistance!=0 || shadowDirection!=SD_RIGHT_BOTTOM || shadowColor!=Qt::gray) {
00272         elem=doc.createElement(tagSHADOW);
00273         elem.setAttribute(attrDistance, shadowDistance);
00274         elem.setAttribute(attrDirection, static_cast<int>( shadowDirection ));
00275         elem.setAttribute(attrColor, shadowColor.name());
00276         fragment.appendChild(elem);
00277     }
00278     if(effect!=EF_NONE || effect2!=EF2_NONE) {
00279         elem=doc.createElement(tagEFFECTS);
00280         elem.setAttribute(attrEffect, static_cast<int>( effect ));
00281         elem.setAttribute(attrEffect2, static_cast<int>( effect2 ));
00282         elem.setAttribute( "speed", static_cast<int>(m_appearSpeed) );
00283         fragment.appendChild(elem);
00284     }
00285     if(appearStep!=0)
00286         fragment.appendChild(KPrObject::createValueElement(tagPRESNUM, appearStep, doc));
00287     if(angle!=0.0) {
00288         elem=doc.createElement(tagANGLE);
00289         elem.setAttribute(attrValue, angle);
00290         fragment.appendChild(elem);
00291     }
00292     if(effect3!=EF3_NONE || disappear) {
00293         elem=doc.createElement(tagDISAPPEAR);
00294         elem.setAttribute(attrEffect, static_cast<int>( effect3 ));
00295         elem.setAttribute(attrDoit, static_cast<int>( disappear ));
00296         elem.setAttribute( "speed", static_cast<int>(m_disappearSpeed) );
00297         elem.setAttribute(attrNum, disappearStep);
00298         fragment.appendChild(elem);
00299     }
00300     if(appearTimer!=1 || disappearTimer!=1) {
00301         elem=doc.createElement("TIMER");
00302         elem.setAttribute("appearTimer", appearTimer);
00303         elem.setAttribute("disappearTimer", disappearTimer);
00304         fragment.appendChild(elem);
00305     }
00306     if(appearSoundEffect || !a_fileName.isEmpty()) {
00307         elem=doc.createElement("APPEARSOUNDEFFECT");
00308         elem.setAttribute("appearSoundEffect", static_cast<int>(appearSoundEffect));
00309         elem.setAttribute("appearSoundFileName", a_fileName);
00310         fragment.appendChild(elem);
00311     }
00312     if(disappearSoundEffect || !d_fileName.isEmpty()) {
00313         elem=doc.createElement("DISAPPEARSOUNDEFFECT");
00314         elem.setAttribute("disappearSoundEffect", static_cast<int>(disappearSoundEffect));
00315         elem.setAttribute("disappearSoundFileName", d_fileName);
00316         fragment.appendChild(elem);
00317     }
00318     if( !objectName.isEmpty() ) {
00319         elem=doc.createElement("OBJECTNAME");
00320         elem.setAttribute("objectName", objectName);
00321         fragment.appendChild(elem);
00322     }
00323     if(protect) {
00324         elem=doc.createElement("PROTECT");
00325         elem.setAttribute("state" , protect);
00326         fragment.appendChild(elem);
00327     }
00328     if(keepRatio) {
00329         elem=doc.createElement("RATIO");
00330         elem.setAttribute("ratio" , keepRatio);
00331         fragment.appendChild(elem);
00332     }
00333 
00334     return fragment;
00335 }
00336 
00337 
00338 void KPrObject::saveOasisPosObject( KoXmlWriter &xmlWriter, int indexObj ) const
00339 {
00340     xmlWriter.addAttribute( "draw:id", "object" + QString::number( indexObj ) );
00341     //save all into pt
00342     xmlWriter.addAttributePt( "svg:width", ext.width() );
00343     xmlWriter.addAttributePt( "svg:height", ext.height() );
00344 
00345     if ( kAbs( angle ) > 1E-6 )
00346     {
00347         double angInRad = -angle * M_PI / 180.0;
00348         QWMatrix m( cos( angInRad ), -sin( angInRad ), sin( angInRad ), cos( angInRad ), 0, 0 );
00349         KoPoint center( ext.width() / 2, ext.height() / 2 );
00350         double rotX = 0.0;
00351         double rotY = 0.0;
00352         m.map( center.x(), center.y(), &rotX, &rotY );
00353         KoPoint rot( rotX, rotY );
00354         KoPoint trans( center - rot + orig );
00355 
00356         QCString transX;
00357         transX.setNum( trans.x(), 'g', DBL_DIG );
00358         QCString transY;
00359         transY.setNum( trans.y(), 'g', DBL_DIG );
00360         QString str = QString( "rotate(%1) translate(%2pt %3pt)" ).arg( angInRad ).arg( transX ).arg( transY );
00361         xmlWriter.addAttribute( "draw:transform", str );
00362     }
00363     else
00364     {
00365         xmlWriter.addAttributePt( "svg:x", orig.x() );
00366         xmlWriter.addAttributePt( "svg:y", orig.y() );
00367     }
00368 }
00369 
00370 void KPrObject::saveOasisObjectProtectStyle( KoGenStyle &styleobjectauto ) const
00371 {
00372     if ( protect )
00373     {
00374         styleobjectauto.addProperty( "draw:move-protect", "true" );
00375         styleobjectauto.addProperty( "draw:size-protect", "true" );
00376     }
00377 }
00378 
00379 QString KPrObject::getStyle( KPOasisSaveContext &sc ) const
00380 {
00381     kdDebug(33001) << "KPrObject::getStyle" << endl;
00382     KoGenStyle styleObjectAuto;
00383     KoGenStyles &mainStyles( sc.context.mainStyles() );
00384     if ( sc.onMaster )
00385     {
00386         styleObjectAuto = KoGenStyle( KPrDocument::STYLE_PRESENTATIONSTICKYOBJECT, "presentation" );
00387     }
00388     else
00389     {
00390         styleObjectAuto = KoGenStyle( KoGenStyle::STYLE_GRAPHICAUTO, "graphic" );
00391     }
00392     fillStyle( styleObjectAuto, mainStyles );
00393     if ( sc.onMaster )
00394     {
00395         return mainStyles.lookup( styleObjectAuto, "pr" );
00396     }
00397     return mainStyles.lookup( styleObjectAuto, "gr" );
00398 }
00399 
00400 void KPrObject::fillStyle( KoGenStyle& styleObjectAuto, KoGenStyles& /* mainStyles */ ) const
00401 {
00402     kdDebug(33001) << "KPrObject::fillStyle" << endl;
00403     saveOasisObjectProtectStyle( styleObjectAuto );
00404     saveOasisShadowElement( styleObjectAuto );
00405 }
00406 
00407 bool KPrObject::saveOasisObjectAttributes( KPOasisSaveContext &/* sc */ ) const
00408 {
00409     kdDebug()<<"bool saveOasisObjectAttributes not implemented";
00410     return true;
00411 }
00412 
00413 bool KPrObject::hasAnimation() const
00414 {
00415     return effect != EF_NONE || appearTimer != 0 || 
00416            effect3 != EF3_NONE || disappear || 
00417            !a_fileName.isEmpty() || ! d_fileName.isEmpty() ||
00418            appearTimer != 1;
00419 }
00420 
00421 bool KPrObject::saveOasisObjectStyleShowAnimation( KoXmlWriter &animation, int objectId )
00422 {
00423     if ( effect != EF_NONE || appearStep != 0 || !a_fileName.isEmpty() )
00424     {
00425         animation.startElement( "presentation:show-shape" );
00426         animation.addAttribute( "draw:shape-id", "object" + QString::number( objectId ) );
00427         animation.addAttribute( "koffice:order-id", appearStep );
00428 
00429         switch( effect )
00430         {
00431         case EF_NONE:
00432             // use appear instead none as oo understands this
00433             animation.addAttribute( "presentation:effect", "appear" );
00434             break;
00435         case EF_COME_RIGHT:
00436             animation.addAttribute( "presentation:effect", "move" );
00437             animation.addAttribute( "presentation:direction", "from-right" );
00438             break;
00439         case EF_COME_LEFT:
00440             animation.addAttribute( "presentation:effect", "move" );
00441             animation.addAttribute( "presentation:direction", "from-left" );
00442             break;
00443         case EF_COME_TOP:
00444             animation.addAttribute( "presentation:effect", "move" );
00445             animation.addAttribute( "presentation:direction", "from-top" );
00446             break;
00447         case EF_COME_BOTTOM:
00448             animation.addAttribute( "presentation:effect", "move" );
00449             animation.addAttribute( "presentation:direction", "from-bottom" );
00450             break;
00451         case EF_COME_RIGHT_TOP:
00452             animation.addAttribute( "presentation:effect", "move" );
00453             animation.addAttribute( "presentation:direction", "from-upper-right" );
00454             break;
00455         case EF_COME_RIGHT_BOTTOM:
00456             animation.addAttribute( "presentation:effect", "move" );
00457             animation.addAttribute( "presentation:direction", "from-lower-right" );
00458             break;
00459         case EF_COME_LEFT_TOP:
00460             animation.addAttribute( "presentation:effect", "move" );
00461             animation.addAttribute( "presentation:direction", "from-upper-left" );
00462             break;
00463         case EF_COME_LEFT_BOTTOM:
00464             animation.addAttribute( "presentation:effect", "move" );
00465             animation.addAttribute( "presentation:direction", "from-lower-left" );
00466             break;
00467         case EF_WIPE_LEFT:
00468             animation.addAttribute( "presentation:effect", "fade" );
00469             animation.addAttribute( "presentation:direction", "from-left" );
00470             break;
00471         case EF_WIPE_RIGHT:
00472             animation.addAttribute( "presentation:effect", "fade" );
00473             animation.addAttribute( "presentation:direction", "from-right" );
00474             break;
00475         case EF_WIPE_TOP:
00476             animation.addAttribute( "presentation:effect", "fade" );
00477             animation.addAttribute( "presentation:direction", "from-top" );
00478             break;
00479         case EF_WIPE_BOTTOM:
00480             animation.addAttribute( "presentation:effect", "fade" );
00481             animation.addAttribute( "presentation:direction", "from-bottom" );
00482             break;
00483         }
00484 
00485         if ( effect2 != EF2_NONE )
00486         {
00487             animation.addAttribute( "koffice:by-paragraph", "true" );
00488         }
00489 
00490         if ( m_appearSpeed == ES_SLOW )
00491         {
00492             animation.addAttribute( "presentation:speed", "slow" );
00493         }
00494         else if ( m_appearSpeed == ES_FAST )
00495         {
00496             animation.addAttribute( "presentation:speed", "fast" );
00497         }
00498 
00499         if ( appearTimer!=1 )
00500         {
00501             animation.addAttribute( "presentation:animation-delay", saveOasisTimer( appearTimer ) );
00502         }
00503         if( !a_fileName.isEmpty() )
00504         {
00505             //store sound into file ?
00506              //<presentation:sound xlink:href="../../usr/lib/openoffice/share/gallery/sounds/pluck.wav" xlink:type="simple" xlink:show="new" xlink:actuate="onRequest"/>
00507             animation.startElement( "presentation:sound" );
00508             animation.addAttribute( "xlink:href", a_fileName );
00509             animation.addAttribute( "xlink:type", "simple" );
00510             animation.addAttribute( "xlink:show", "new" );
00511             animation.addAttribute( "xlink:actuate", "onRequest" );
00512             animation.endElement();
00513         }
00514         animation.endElement();
00515     }
00516     return true;
00517 }
00518 
00519 bool KPrObject::saveOasisObjectStyleHideAnimation( KoXmlWriter &animation, int objectId )
00520 {
00521 
00522     //FIXME oo doesn't support hide animation object
00523     if ( effect3 != EF3_NONE || disappearStep != 0 || !d_fileName.isEmpty())
00524     {
00525         animation.startElement( "presentation:hide-shape" );
00526         animation.addAttribute( "draw:shape-id", "object" + QString::number( objectId ) );
00527         animation.addAttribute( "koffice:order-id", disappearStep );
00528         switch( effect3 )
00529         {
00530         case EF3_NONE:
00531             // use hide instead none as oo understands this
00532             animation.addAttribute( "presentation:effect", "hide" );
00533             break;
00534         case EF3_GO_RIGHT:
00535             animation.addAttribute( "presentation:effect", "move" );
00536             animation.addAttribute( "presentation:direction", "from-right" );
00537             break;
00538         case EF3_GO_LEFT:
00539             animation.addAttribute( "presentation:effect", "move" );
00540             animation.addAttribute( "presentation:direction", "from-left" );
00541             break;
00542         case EF3_GO_TOP:
00543             animation.addAttribute( "presentation:effect", "move" );
00544             animation.addAttribute( "presentation:direction", "from-top" );
00545             break;
00546         case EF3_GO_BOTTOM:
00547             animation.addAttribute( "presentation:effect", "move" );
00548             animation.addAttribute( "presentation:direction", "from-bottom" );
00549             break;
00550         case EF3_GO_RIGHT_TOP:
00551             animation.addAttribute( "presentation:effect", "move" );
00552             animation.addAttribute( "presentation:direction", "from-upper-right" );
00553             break;
00554         case EF3_GO_RIGHT_BOTTOM:
00555             animation.addAttribute( "presentation:effect", "move" );
00556             animation.addAttribute( "presentation:direction", "from-lower-right" );
00557             break;
00558         case EF3_GO_LEFT_TOP:
00559             animation.addAttribute( "presentation:effect", "move" );
00560             animation.addAttribute( "presentation:direction", "from-upper-left" );
00561             break;
00562         case EF3_GO_LEFT_BOTTOM:
00563             animation.addAttribute( "presentation:effect", "move" );
00564             animation.addAttribute( "presentation:direction", "from-lower-left" );
00565             break;
00566         case EF3_WIPE_LEFT:
00567             animation.addAttribute( "presentation:effect", "fade" );
00568             animation.addAttribute( "presentation:direction", "from-left" );
00569             break;
00570         case EF3_WIPE_RIGHT:
00571             animation.addAttribute( "presentation:effect", "fade" );
00572             animation.addAttribute( "presentation:direction", "from-right" );
00573             break;
00574         case EF3_WIPE_TOP:
00575             animation.addAttribute( "presentation:effect", "fade" );
00576             animation.addAttribute( "presentation:direction", "from-top" );
00577             break;
00578         case EF3_WIPE_BOTTOM:
00579             animation.addAttribute( "presentation:effect", "fade" );
00580             animation.addAttribute( "presentation:direction", "from-bottom" );
00581             break;
00582         }
00583 
00584         if ( m_disappearSpeed == ES_SLOW )
00585         {
00586             animation.addAttribute( "presentation:speed", "slow" );
00587         }
00588         else if ( m_disappearSpeed == ES_FAST )
00589         {
00590             animation.addAttribute( "presentation:speed", "fast" );
00591         }
00592 
00593         if ( disappearTimer!=1 )
00594         {
00595             animation.addAttribute( "presentation:animation-delay", saveOasisTimer( disappearTimer ) );
00596         }
00597         if( !d_fileName.isEmpty() )
00598         {
00599             //store sound into file ?
00600              //<presentation:sound xlink:href="../../usr/lib/openoffice/share/gallery/sounds/pluck.wav" xlink:type="simple" xlink:show="new" xlink:actuate="onRequest"/>
00601             animation.startElement( "presentation:sound" );
00602             animation.addAttribute( "xlink:href", a_fileName );
00603             animation.addAttribute( "xlink:type", "simple" );
00604             animation.addAttribute( "xlink:show", "new" );
00605             animation.addAttribute( "xlink:actuate", "onRequest" );
00606 
00607             animation.endElement();
00608         }
00609         animation.endElement();
00610     }
00611     return true;
00612 }
00613 
00614 void KPrObject::loadOasis(const QDomElement &element, KoOasisContext & context, KPrLoadingInfo *info)
00615 {
00616     if(element.hasAttributeNS( KoXmlNS::draw, "name" ))
00617        objectName = element.attributeNS( KoXmlNS::draw, "name", QString::null);
00618     orig.setX( KoUnit::parseValue( element.attributeNS( KoXmlNS::svg, "x", QString::null ) ) );
00619     orig.setY( KoUnit::parseValue( element.attributeNS( KoXmlNS::svg, "y", QString::null ) ) );
00620     ext.setWidth(KoUnit::parseValue( element.attributeNS( KoXmlNS::svg, "width", QString::null )) );
00621     ext.setHeight(KoUnit::parseValue( element.attributeNS( KoXmlNS::svg, "height", QString::null ) ) );
00622     //kdDebug()<<" orig.x() :"<<orig.x() <<" orig.y() :"<<orig.y() <<"ext.width() :"<<ext.width()<<" ext.height(): "<<ext.height()<<endl;
00623     KoStyleStack &styleStack = context.styleStack();
00624     styleStack.setTypeProperties( "" ); //no type default type
00625     if ( element.hasAttributeNS( KoXmlNS::draw, "transform" ) )
00626     {
00627         // there is some more stuff in the spezification
00628         // TODO make it work for all cases
00629         QString transform = element.attributeNS( KoXmlNS::draw, "transform", QString::null );
00630         kdDebug()<<" transform action :"<<transform<<endl;
00631         QRegExp rx( "rotate ?\\(([^)]+)\\) translate ?\\(([^ ]+) ([^)]+)\\)" );
00632         if ( rx.search( transform ) != - 1 && rx.numCaptures() == 3 )
00633         {
00634             bool ok = false;
00635             double angInRad = rx.cap( 1 ).toDouble( &ok );
00636             if( ok )
00637             {
00638                 angle = -angInRad * 180.0 / M_PI;
00639             }
00640             else
00641             {
00642                 angle = 0.0;
00643                 angInRad = 0.0;
00644             }
00645             QWMatrix m( cos( angInRad ), -sin( angInRad ), sin( angInRad ), cos( angInRad ), 0, 0 );
00646             KoPoint center( ext.width() / 2, ext.height() / 2 );
00647             double transX = 0.0;
00648             double transY = 0.0;
00649             m.map( center.x(), center.y(), &transX, &transY );
00650             KoPoint diff( transX, transY );
00651             KoPoint trans( KoUnit::parseValue( rx.cap( 2 ) ), KoUnit::parseValue( rx.cap( 3 ) ) );
00652             orig = trans - center + diff;
00653             kdDebug(33001) << "trans = " << trans << ", center = " << center << ", diff = " << diff << ", orig = " << orig << endl;
00654         }
00655     }
00656     QDomElement *animation = 0L;
00657     lstAnimation *tmp = 0L;
00658     if( element.hasAttributeNS( KoXmlNS::draw, "id"))
00659     {
00660         tmp = info->animationShowById(element.attributeNS( KoXmlNS::draw, "id", QString::null) );
00661         if ( tmp )
00662             animation = tmp->element;
00663     }
00664 
00665     if( animation)
00666     {
00667         QString effectStr = animation->attributeNS( KoXmlNS::presentation, "effect", QString::null);
00668         QString dir = animation->attributeNS( KoXmlNS::presentation, "direction", QString::null);
00669         QString speed = animation->attributeNS( KoXmlNS::presentation, "speed", QString::null );
00670         appearStep = tmp->order;
00671         kdDebug()<<" appear direction : "<<dir<<" effect :"<< effectStr <<" speed :"<<speed<<endl;
00672 
00673         if ( speed =="medium" )
00674         {
00675             m_appearSpeed = ES_MEDIUM;
00676         }
00677         else if ( speed=="slow" )
00678         {
00679             m_appearSpeed = ES_SLOW;
00680         }
00681         else if ( speed=="fast" )
00682         {
00683             m_appearSpeed = ES_FAST;
00684         }
00685         else
00686             kdDebug()<<" speed argument is not defined :"<<speed<<endl;
00687 
00688         if ( animation->hasAttributeNS( KoXmlNS::presentation, "animation-delay" ) )
00689         {
00690             appearTimer = loadOasisTimer(animation->attributeNS( KoXmlNS::presentation, "animation-delay", QString::null ) );
00691         }
00692         if (effectStr=="fade")
00693         {
00694             if (dir=="from-right")
00695                 effect = EF_WIPE_RIGHT;
00696             else if (dir=="from-left")
00697                 effect = EF_WIPE_LEFT;
00698             else if (dir=="from-top")
00699                 effect=  EF_WIPE_TOP;
00700             else if (dir=="from-bottom")
00701                 effect = EF_WIPE_BOTTOM;
00702             else
00703                 kdDebug(33001)<<" dir not supported: " << dir << endl;
00704         }
00705         else if (effectStr=="move")
00706         {
00707             if (dir=="from-right")
00708                 effect = EF_COME_RIGHT;
00709             else if (dir=="from-left")
00710                 effect = EF_COME_LEFT;
00711             else if (dir=="from-top")
00712                 effect = EF_COME_TOP;
00713             else if (dir=="from-bottom")
00714                 effect = EF_COME_BOTTOM;
00715             else if (dir=="from-upper-right")
00716                 effect = EF_COME_RIGHT_TOP;
00717             else if (dir=="from-lower-right")
00718                 effect = EF_COME_RIGHT_BOTTOM;
00719             else if (dir=="from-upper-left")
00720                 effect = EF_COME_LEFT_TOP;
00721             else if (dir=="from-lower-left")
00722                 effect = EF_COME_LEFT_BOTTOM;
00723             else
00724                 kdDebug(33001) << " dir not supported:" << dir << endl;
00725         }
00726         else if ( effectStr == "appear" )
00727         {
00728             effect = EF_NONE;
00729         }
00730         else
00731         {
00732             kdDebug(33001) << " appear effect not supported: " << effectStr << endl;
00733             effect = EF_NONE;
00734         }
00735 
00736         QString byParagaph = animation->attributeNS( KoXmlNS::koffice, "by-paragraph", QString::null );
00737         if ( byParagaph == "true" )
00738         {
00739             effect2 = EF2T_PARA;
00740         }
00741 
00742         QDomElement sound = KoDom::namedItemNS( *animation, KoXmlNS::presentation, "sound" );
00743         if ( !sound.isNull() )
00744         {
00745             kdDebug()<<" object has sound effect \n";
00746             if ( sound.hasAttributeNS( KoXmlNS::xlink, "href" ) )
00747             {
00748                 a_fileName =sound.attributeNS( KoXmlNS::xlink, "href", QString::null );
00749                 appearSoundEffect = true;
00750             }
00751         }
00752     }
00753 
00754     animation = 0L;
00755     tmp = 0L;
00756     if( element.hasAttributeNS( KoXmlNS::draw, "id"))
00757     {
00758         tmp = info->animationHideById(element.attributeNS( KoXmlNS::draw, "id", QString::null) );
00759         if ( tmp )
00760             animation = tmp->element;
00761     }
00762 
00763     if( animation)
00764     {
00765         QString effectStr = animation->attributeNS( KoXmlNS::presentation, "effect", QString::null);
00766         QString dir = animation->attributeNS( KoXmlNS::presentation, "direction", QString::null);
00767         QString speed = animation->attributeNS( KoXmlNS::presentation, "speed", QString::null );
00768         kdDebug()<<" disappear direction : "<<dir<<" effect :"<< effectStr <<" speed :"<<speed<<endl;
00769         disappearStep = tmp->order;
00770 
00771         if ( speed =="medium" )
00772         {
00773             m_disappearSpeed = ES_MEDIUM;
00774         }
00775         else if ( speed=="slow" )
00776         {
00777             m_disappearSpeed = ES_SLOW;
00778         }
00779         else if ( speed=="fast" )
00780         {
00781             m_disappearSpeed = ES_FAST;
00782         }
00783         else
00784             kdDebug()<<" speed argument is not defined :"<<speed<<endl;
00785 
00786         if ( animation->hasAttributeNS( KoXmlNS::presentation, "animation-delay" ) )
00787         {
00788             disappearTimer = loadOasisTimer(animation->attributeNS( KoXmlNS::presentation, "animation-delay", QString::null ) );
00789         }
00790         if (effectStr=="fade")
00791         {
00792             if (dir=="from-right")
00793                 effect3 = EF3_WIPE_RIGHT;
00794             else if (dir=="from-left")
00795                 effect3 = EF3_WIPE_LEFT;
00796             else if (dir=="from-top")
00797                 effect3 =  EF3_WIPE_TOP;
00798             else if (dir=="from-bottom")
00799                 effect3 = EF3_WIPE_BOTTOM;
00800             else
00801                 kdDebug(33001) << " dir not supported: " << dir << endl;
00802         }
00803         else if (effectStr=="move")
00804         {
00805             if (dir=="from-right")
00806                 effect3 = EF3_GO_RIGHT;
00807             else if (dir=="from-left")
00808                 effect3 = EF3_GO_LEFT;
00809             else if (dir=="from-top")
00810                 effect3 = EF3_GO_TOP;
00811             else if (dir=="from-bottom")
00812                 effect3 = EF3_GO_BOTTOM;
00813             else if (dir=="from-upper-right")
00814                 effect3 = EF3_GO_RIGHT_TOP;
00815             else if (dir=="from-lower-right")
00816                 effect3 = EF3_GO_RIGHT_BOTTOM;
00817             else if (dir=="from-upper-left")
00818                 effect3 = EF3_GO_LEFT_TOP;
00819             else if (dir=="from-lower-left")
00820                 effect3 = EF3_GO_LEFT_BOTTOM;
00821             else
00822                 kdDebug(33001) << " dir not supported: " << dir << endl;
00823         }
00824         else if ( effectStr == "hide" )
00825         {
00826             effect3 = EF3_NONE;
00827         }
00828         else
00829         {
00830             kdDebug(33001) << " hide effect not supported: " << effectStr << endl;
00831             effect3 = EF3_NONE;
00832         }
00833 
00834         disappear = true;
00835 
00836         QDomElement sound = KoDom::namedItemNS( *animation, KoXmlNS::presentation, "sound" );
00837         if ( !sound.isNull() )
00838         {
00839             kdDebug()<<" object has sound effect \n";
00840             if ( sound.hasAttributeNS( KoXmlNS::xlink, "href" ) )
00841             {
00842                 d_fileName =sound.attributeNS( KoXmlNS::xlink, "href", QString::null );
00843                 disappearSoundEffect = true;
00844             }
00845         }
00846     }
00847     //shadow
00848 #if 0 //move it to kptextobject
00849     if ( !element.hasAttribute( "type" ) ||
00850          ( element.hasAttribute( "type" ) && element.attribute( "type" ) == "4" ) )
00851     {
00852         kdDebug()<<" text document !!!!!\n";
00853         if ( styleStack.hasAttributeNS( KoXmlNS::fo, "text-shadow" ) &&
00854              styleStack.attributeNS( KoXmlNS::fo, "text-shadow" ) != "none" )
00855         {
00856             QString distance = styleStack.attributeNS( KoXmlNS::fo, "text-shadow" );
00857             distance.truncate( distance.find( ' ' ) );
00858             shadowDistance = (int)KoUnit::parseValue( distance );
00859             shadowDirection = SD_RIGHT_BOTTOM;
00860             shadowColor= QColor("#a0a0a0" );
00861         }
00862     }
00863 #endif
00864 
00865 // draw:textarea-horizontal-align="center" draw:textarea-vertical-align="middle" draw:shadow="visible" draw:move-protect="true" draw:size-protect="true"
00866     //kpresenter doesn't have two attribute for protect move and protect size perhaps create two argument for 1.4
00867     styleStack.setTypeProperties( "graphic" );
00868     if ( styleStack.hasAttributeNS( KoXmlNS::draw, "move-protect" ) )
00869     {
00870         kdDebug()<<" styleStack.attribute(draw:move-protect ) :"<<styleStack.attributeNS( KoXmlNS::draw, "move-protect" )<<endl;
00871         protect = ( styleStack.attributeNS( KoXmlNS::draw, "move-protect" ) == "true" );
00872     }
00873     if ( styleStack.hasAttributeNS( KoXmlNS::draw, "size-protect" ) )
00874     {
00875         kdDebug()<<" styleStack.attribute(draw:size-protect ) :"<<styleStack.attributeNS( KoXmlNS::draw, "size-protect" )<<endl;
00876         protect = ( styleStack.attributeNS( KoXmlNS::draw, "size-protect" ) == "true" );
00877     }
00878 
00879     //not supported into kpresenter
00880     if ( styleStack.hasAttributeNS( KoXmlNS::draw, "textarea-vertical-align" ) )
00881     {
00882         kdDebug()<<" styleStack.attribute(draw:textarea-vertical-align ) :"<<styleStack.attributeNS( KoXmlNS::draw, "textarea-vertical-align" )<<endl;
00883     }
00884     if ( styleStack.hasAttributeNS( KoXmlNS::draw, "textarea-horizontal-align") )
00885     {
00886         kdDebug()<<" styleStack.attribute(draw:textarea-horizontal-align ) :"<<styleStack.attributeNS( KoXmlNS::draw, "textarea-horizontal-align" )<<endl;
00887     }
00888     if ( styleStack.hasAttributeNS( KoXmlNS::draw, "shadow" ) &&
00889               styleStack.attributeNS( KoXmlNS::draw, "shadow") == "visible" )
00890     {
00891         // use the shadow attribute to indicate an object-shadow
00892         double x = KoUnit::parseValue( styleStack.attributeNS( KoXmlNS::draw, "shadow-offset-x" ) );
00893         double y = KoUnit::parseValue( styleStack.attributeNS( KoXmlNS::draw, "shadow-offset-y" ) );
00894         kdDebug()<<" shadow x : "<<x<<" shadow y :"<<y<<endl;
00895         if ( x < 0 && y < 0 )
00896         {
00897             shadowDirection = SD_LEFT_UP;
00898             shadowDistance = (int) fabs ( x );
00899         }
00900         else if ( x == 0 && y < 0 )
00901         {
00902             shadowDirection = SD_UP;
00903             shadowDistance = (int) fabs ( y );
00904         }
00905         else if ( x > 0 && y < 0 )
00906         {
00907             shadowDirection = SD_RIGHT_UP;
00908             shadowDistance = (int) fabs ( x );
00909         }
00910         else if ( x > 0 && y == 0 )
00911         {
00912             shadowDirection = SD_RIGHT;
00913             shadowDistance = (int) fabs ( x );
00914         }
00915         else if ( x > 0 && y > 0 )
00916         {
00917             shadowDirection = SD_RIGHT_BOTTOM;
00918             shadowDistance = (int) fabs ( x );
00919         }
00920         else if ( x == 0 && y > 0 )
00921         {
00922             shadowDirection = SD_BOTTOM;
00923             shadowDistance = (int) fabs ( y );
00924         }
00925         else if ( x < 0 && y > 0 )
00926         {
00927             shadowDirection = SD_LEFT_BOTTOM;
00928             shadowDistance = (int) fabs ( x );
00929         }
00930         else if ( x < 0 && y == 0 )
00931         {
00932             shadowDirection = SD_LEFT;
00933             shadowDistance = (int) fabs ( x );
00934         }
00935         if ( styleStack.hasAttributeNS( KoXmlNS::draw, "shadow-color" ) )
00936             shadowColor= QColor(styleStack.attributeNS( KoXmlNS::draw, "shadow-color" ) );
00937         kdDebug()<<" shadow color : "<<shadowColor.name()<<endl;
00938     }
00939 }
00940 
00941 bool KPrObject::saveOasisObject( KPOasisSaveContext &sc ) const
00942 {
00943     sc.xmlWriter.startElement( getOasisElementName() );
00944     sc.xmlWriter.addAttribute( sc.onMaster ? "presentation:style-name": "draw:style-name", getStyle( sc ) );
00945     saveOasisPosObject( sc.xmlWriter, sc.indexObj );
00946     if( !objectName.isEmpty())
00947         sc.xmlWriter.addAttribute( "draw:name", objectName );
00948 
00949     saveOasisObjectAttributes( sc );
00950 
00951     sc.xmlWriter.endElement();
00952     return true;
00953 }
00954 
00955 void KPrObject::saveOasisShadowElement( KoGenStyle &styleobjectauto ) const
00956 {
00957     //FIXME default value
00958     if(shadowDistance!=0 || shadowDirection!=SD_RIGHT_BOTTOM || shadowColor!=Qt::gray) {
00959         styleobjectauto.addProperty( "draw:shadow", "visible" );
00960         switch( shadowDirection )
00961         {
00962         case SD_LEFT_UP:
00963             styleobjectauto.addPropertyPt( "draw:shadow-offset-x", ( -1.0 * shadowDistance )  );
00964             styleobjectauto.addPropertyPt( "draw:shadow-offset-y", ( -1.0 * shadowDistance ) );
00965             break;
00966         case SD_UP:
00967             styleobjectauto.addPropertyPt( "draw:shadow-offset-x", 0.0 );
00968             styleobjectauto.addPropertyPt( "draw:shadow-offset-y", ( -1.0 * shadowDistance ) );
00969             break;
00970         case SD_RIGHT_UP:
00971             styleobjectauto.addPropertyPt( "draw:shadow-offset-x", shadowDistance );
00972             styleobjectauto.addPropertyPt( "draw:shadow-offset-y", ( -1.0 * shadowDistance ) );
00973             break;
00974         case SD_RIGHT:
00975             styleobjectauto.addPropertyPt( "draw:shadow-offset-x", shadowDistance );
00976             styleobjectauto.addPropertyPt( "draw:shadow-offset-y", 0.0 );
00977             break;
00978         case SD_RIGHT_BOTTOM:
00979             styleobjectauto.addPropertyPt( "draw:shadow-offset-x",shadowDistance  );
00980             styleobjectauto.addPropertyPt( "draw:shadow-offset-y", shadowDistance );
00981             break;
00982         case SD_BOTTOM:
00983             styleobjectauto.addPropertyPt( "draw:shadow-offset-x", 0.0 );
00984             styleobjectauto.addPropertyPt( "draw:shadow-offset-y",shadowDistance  );
00985             break;
00986         case SD_LEFT_BOTTOM:
00987             styleobjectauto.addPropertyPt( "draw:shadow-offset-x", ( -1.0*shadowDistance ) );
00988             styleobjectauto.addPropertyPt( "draw:shadow-offset-y", shadowDistance );
00989             break;
00990         case SD_LEFT:
00991             styleobjectauto.addPropertyPt( "draw:shadow-offset-x", ( -1.0 * shadowDistance ) );
00992             styleobjectauto.addPropertyPt( "draw:shadow-offset-y",  0.0 );
00993             break;
00994         }
00995         styleobjectauto.addProperty( "draw:shadow-color", shadowColor.name() );
00996     }
00997 }
00998 
00999 double KPrObject::load(const QDomElement &element) {
01000 
01001     double offset=-1.0;
01002     QDomElement e=element.namedItem(tagORIG).toElement();
01003     if(!e.isNull()) {
01004         if(e.hasAttribute(attrX))
01005             orig.setX(e.attribute(attrX).toDouble());
01006         if(e.hasAttribute(attrY))
01007         {
01008             offset=e.attribute(attrY).toDouble();
01009             orig.setY(0);
01010         }
01011     }
01012     e=element.namedItem(tagSIZE).toElement();
01013     if(!e.isNull()) {
01014         if(e.hasAttribute(attrWidth))
01015             ext.setWidth(e.attribute(attrWidth).toDouble());
01016         if(e.hasAttribute(attrHeight))
01017             ext.setHeight(e.attribute(attrHeight).toDouble());
01018     }
01019     e=element.namedItem(tagSHADOW).toElement();
01020     if(!e.isNull()) {
01021         if(e.hasAttribute(attrDistance))
01022             shadowDistance=e.attribute(attrDistance).toInt();
01023         if(e.hasAttribute(attrDirection))
01024             shadowDirection=static_cast<ShadowDirection>(e.attribute(attrDirection).toInt());
01025         shadowColor=retrieveColor(e);
01026     }
01027     else {
01028         shadowDistance=0;
01029         shadowDirection=SD_RIGHT_BOTTOM;
01030         shadowColor=Qt::gray;
01031     }
01032     e=element.namedItem(tagEFFECTS).toElement();
01033     if(!e.isNull()) {
01034         if(e.hasAttribute(attrEffect))
01035             effect=static_cast<Effect>(e.attribute(attrEffect).toInt());
01036         if(e.hasAttribute(attrEffect2))
01037             effect2=static_cast<Effect2>(e.attribute(attrEffect2).toInt());
01038         if(e.hasAttribute("speed"))
01039         {
01040             m_appearSpeed=static_cast<EffectSpeed>(e.attribute("speed").toInt());
01041             // this is a safty net as we had once speeds up to ten
01042             m_appearSpeed = m_appearSpeed > ES_FAST ? ES_FAST : m_appearSpeed;
01043         }
01044     }
01045     else {
01046         effect=EF_NONE;
01047         effect2=EF2_NONE;
01048     }
01049     e=element.namedItem(tagANGLE).toElement();
01050     if(!e.isNull()) {
01051         if(e.hasAttribute(attrValue))
01052             angle=e.attribute(attrValue).toFloat();
01053     }
01054     else
01055         angle=0.0;
01056     e=element.namedItem(tagPRESNUM).toElement();
01057     if(!e.isNull()) {
01058         if(e.hasAttribute(attrValue))
01059             appearStep=e.attribute(attrValue).toInt();
01060     }
01061     else
01062         appearStep=0;
01063     e=element.namedItem(tagDISAPPEAR).toElement();
01064     if(!e.isNull()) {
01065         if(e.hasAttribute(attrEffect))
01066             effect3=static_cast<Effect3>(e.attribute(attrEffect).toInt());
01067         if(e.hasAttribute(attrDoit))
01068             disappear=static_cast<bool>(e.attribute(attrDoit).toInt());
01069         if(e.hasAttribute(attrNum))
01070             disappearStep=e.attribute(attrNum).toInt();
01071         if(e.hasAttribute("speed"))
01072         {
01073             m_disappearSpeed=static_cast<EffectSpeed>(e.attribute("speed").toInt());
01074             // this is a safty net as we had once speeds up to ten
01075             m_disappearSpeed = m_appearSpeed > ES_FAST ? ES_FAST : m_appearSpeed;
01076         }
01077     }
01078     else {
01079         effect3=EF3_NONE;
01080         disappear=false;
01081         disappearStep=1;
01082     }
01083     e=element.namedItem("TIMER").toElement();
01084     if(!e.isNull()) {
01085         if(e.hasAttribute("appearTimer"))
01086             appearTimer = e.attribute("appearTimer").toInt();
01087         if(e.hasAttribute("disappearTimer"))
01088             disappearTimer = e.attribute("disappearTimer").toInt();
01089     }
01090     else {
01091         appearTimer = 1;
01092         disappearTimer = 1;
01093     }
01094     e=element.namedItem("APPEARSOUNDEFFECT").toElement();
01095     if(!e.isNull()) {
01096         if(e.hasAttribute("appearSoundEffect"))
01097             appearSoundEffect = static_cast<bool>(e.attribute("appearSoundEffect").toInt());
01098         if(e.hasAttribute("appearSoundFileName"))
01099             a_fileName = e.attribute("appearSoundFileName");
01100     }
01101     else {
01102         appearSoundEffect = false;
01103         a_fileName = QString::null;
01104     }
01105     e=element.namedItem("DISAPPEARSOUNDEFFECT").toElement();
01106     if(!e.isNull()) {
01107         if(e.hasAttribute("disappearSoundEffect"))
01108             disappearSoundEffect = static_cast<bool>(e.attribute("disappearSoundEffect").toInt());
01109         if(e.hasAttribute("disappearSoundFileName"))
01110             d_fileName = e.attribute("disappearSoundFileName");
01111     }
01112     else {
01113         disappearSoundEffect = false;
01114         d_fileName = QString::null;
01115     }
01116     e=element.namedItem("OBJECTNAME").toElement();
01117     if(!e.isNull()) {
01118         if(e.hasAttribute("objectName"))
01119             objectName = e.attribute("objectName");
01120     }
01121     else {
01122         objectName = QString::null;
01123     }
01124     e=element.namedItem("PROTECT").toElement();
01125     if (!e.isNull())
01126     {
01127         if(e.hasAttribute("state"))
01128             protect=static_cast<bool>(e.attribute("state").toInt());
01129     }
01130 
01131     e=element.namedItem("RATIO").toElement();
01132     if (!e.isNull())
01133     {
01134         if(e.hasAttribute("ratio"))
01135             keepRatio=static_cast<bool>(e.attribute("ratio").toInt());
01136     }
01137 
01138     return offset;
01139 }
01140 
01141 KoSize KPrObject::getRealSize() const {
01142     KoSize size = ext;
01143 
01144     if ( angle != 0.0 ) {
01145       float angInRad = angle * M_PI / 180;
01146       size.setWidth( ext.width() * fabs( cos( angInRad ) ) + ext.height() * fabs( sin( angInRad ) ) );
01147       size.setHeight( ext.width() * fabs( sin( angInRad ) ) + ext.height() * fabs( cos( angInRad ) ) );
01148     }
01149 
01150     return size;
01151 }
01152 
01153 KoPoint KPrObject::getRealOrig() const {
01154     KoPoint origin = orig;
01155 
01156     if ( angle != 0.0 ) {
01157         KoSize dist( ( getRealSize() - ext ) / 2 );
01158         origin.setX( orig.x() - dist.width() );
01159         origin.setY( orig.y() - dist.height() );
01160     }
01161 
01162     return origin;
01163 }
01164 
01165 KoRect KPrObject::getRealRect() const {
01166     return KoRect( getRealOrig(), getRealSize() );
01167 }
01168 
01169 KoRect KPrObject::getRepaintRect() const
01170 {
01171     KoRect rect( getRealOrig(), getRealSize() );
01172 
01173     if ( shadowDirection == SD_LEFT ||
01174          shadowDirection == SD_LEFT_UP ||
01175          shadowDirection == SD_LEFT_BOTTOM )
01176     {
01177         rect.setLeft( rect.left() - shadowDistance );
01178     }
01179     if ( shadowDirection == SD_UP ||
01180          shadowDirection == SD_LEFT_UP ||
01181          shadowDirection == SD_RIGHT_UP )
01182     {
01183         rect.setTop( rect.top() - shadowDistance );
01184     }
01185     if ( shadowDirection == SD_RIGHT ||
01186          shadowDirection == SD_RIGHT_UP ||
01187          shadowDirection == SD_RIGHT_BOTTOM )
01188     {
01189         rect.setRight( rect.right() + shadowDistance );
01190     }
01191     if ( shadowDirection == SD_BOTTOM ||
01192          shadowDirection == SD_LEFT_BOTTOM ||
01193          shadowDirection == SD_RIGHT_BOTTOM )
01194     {
01195         rect.setBottom( rect.bottom() + shadowDistance );
01196     }
01197 
01198     if ( angle != 0.0 )
01199     {
01200         double _dx = rect.x() - 1.0;
01201         double _dy = rect.y() - 1.0;
01202         double _dw = rect.width() + 2.0;
01203         double _dh = rect.height() + 2.0;
01204         rect.setRect(  _dx, _dy, _dw, _dh );
01205     }
01206 
01207     return rect;
01208 }
01209 
01210 void KPrObject::flip( bool /*horizontal*/ ) {
01211     // flip the angle
01212     if ( angle ) {
01213         angle = 360.0 - angle;
01214     }
01215 }
01216 
01217 KoRect KPrObject::rotateRectObject() const
01218 {
01219     KoRect br = KoRect( 0,0, ext.width(), ext.height() );
01220     double pw = br.width();
01221     double ph = br.height();
01222     KoRect rr = br;
01223     double yPos = -rr.y();
01224     double xPos = -rr.x();
01225     rr.moveTopLeft( KoPoint( -rr.width() / 2.0, -rr.height() / 2.0 ) );
01226     QWMatrix m;
01227     m.translate( pw / 2.0, ph / 2.0 );
01228     m.rotate( angle );
01229     m.translate( rr.left() + xPos, rr.top() + yPos );
01230     KoRect r = KoRect::fromQRect(m.mapRect( br.toQRect() )); // see above TODO
01231     r.moveBy( orig.x() , orig.y() );
01232     return r;
01233 }
01234 
01235 void KPrObject::rotateObject(QPainter *paint,KoTextZoomHandler *_zoomHandler)
01236 {
01237     KoRect rr = KoRect( 0, 0, ext.width(), ext.height() );
01238     rr.moveTopLeft( KoPoint( -ext.width() / 2.0, -ext.height() / 2.0 ) );
01239     QWMatrix m;
01240     m.translate( _zoomHandler->zoomItX(ext.width() / 2.0), _zoomHandler->zoomItY(ext.height() / 2.0 ));
01241     m.rotate( angle );
01242     m.translate( _zoomHandler->zoomItX(rr.left()), _zoomHandler->zoomItY(rr.top()) );
01243 
01244     paint->setWorldMatrix( m, true );
01245 }
01246 
01247 bool KPrObject::contains( const KoPoint &point ) const
01248 {
01249     return getRealRect().contains( point );
01250 }
01251 
01252 bool KPrObject::intersects( const KoRect &rect ) const
01253 {
01254     return getRealRect().intersects( rect );
01255 }
01256 
01257 QCursor KPrObject::getCursor( const KoPoint &_point, ModifyType &_modType,
01258                              KPrDocument *doc ) const
01259 {
01260     KoTextZoomHandler * zh = doc->zoomHandler();
01261     int px = zh->zoomItX(_point.x());
01262     int py = zh->zoomItY(_point.y());
01263 
01264     QRect rect = zh->zoomRect( getRealRect() );
01265     int ox = rect.left();
01266     int oy = rect.top();
01267     int ow = rect.width();
01268     int oh = rect.height();
01269 
01270     bool headerFooter=doc->isHeaderFooter(this);
01271 
01272     int sz = 4;
01273     if ( px >= ox && py >= oy && px <= ox + QMIN( ow / 3, sz ) && py <= oy + QMIN( oh / 3, sz ) )
01274     {
01275         _modType = MT_RESIZE_LU;
01276         if ( protect)
01277             return Qt::ForbiddenCursor;
01278         return Qt::sizeFDiagCursor;
01279     }
01280 
01281     if ( px >= ox && py >= oy + oh / 2 - QMIN( oh / 6, sz / 2 )
01282          && px <= ox + QMIN( ow / 3, sz)
01283          && py <= oy + oh / 2 + QMIN( oh / 6, sz / 2 ) )
01284     {
01285         _modType = MT_RESIZE_LF;
01286         if ( protect)
01287             return Qt::ForbiddenCursor;
01288         return Qt::sizeHorCursor;
01289     }
01290 
01291     if ( px >= ox && py >= oy + oh - QMIN( oh / 3, sz ) && px <= ox + QMIN( ow / 3, sz ) && py <= oy + oh )
01292     {
01293         _modType = MT_RESIZE_LD;
01294         if ( protect)
01295             return Qt::ForbiddenCursor;
01296         return Qt::sizeBDiagCursor;
01297     }
01298 
01299     if ( px >= ox + ow / 2 - QMIN( ow / 6, sz / 2 ) && py >= oy
01300          && px <= ox + ow / 2 + QMIN( ow / 6, sz / 2 )
01301          && py <= oy + QMIN( oh / 3, sz ) )
01302     {
01303         _modType = MT_RESIZE_UP;
01304         if ( protect)
01305             return Qt::ForbiddenCursor;
01306         return Qt::sizeVerCursor;
01307     }
01308 
01309     if ( px >= ox + ow / 2 - QMIN( ow / 6, sz / 2 ) && py >= oy + oh - QMIN( oh / 3, sz )
01310          && px <= ox + ow / 2 + QMIN( ow / 6, sz / 2 ) && py <= oy + oh )
01311     {
01312         _modType = MT_RESIZE_DN;
01313         if ( protect)
01314             return Qt::ForbiddenCursor;
01315         return Qt::sizeVerCursor;
01316     }
01317 
01318     if ( px >= ox + ow - QMIN( ow / 3, sz ) && py >= oy && px <= ox + ow && py <= oy + QMIN( oh / 3, sz) )
01319     {
01320         _modType = MT_RESIZE_RU;
01321         if ( protect)
01322             return Qt::ForbiddenCursor;
01323         return Qt::sizeBDiagCursor;
01324     }
01325 
01326     if ( px >= ox + ow - QMIN( ow / 3, sz ) && py >= oy + oh / 2 - QMIN( oh / 6, sz / 2 )
01327          && px <= ox + ow && py <= oy + oh / 2 + QMIN( oh / 6, sz / 2) )
01328     {
01329         _modType = MT_RESIZE_RT;
01330         if ( protect)
01331             return Qt::ForbiddenCursor;
01332         return Qt::sizeHorCursor;
01333     }
01334 
01335     if ( px >= ox + ow - QMIN( ow / 3, sz ) && py >= oy + oh - QMIN( oh / 3, sz)
01336          && px <= ox + ow && py <= oy + oh )
01337     {
01338         _modType = MT_RESIZE_RD;
01339         if ( protect)
01340             return Qt::ForbiddenCursor;
01341         return Qt::sizeFDiagCursor;
01342     }
01343 
01344     //header footer can't move
01345     if(!headerFooter)
01346         _modType = MT_MOVE;
01347     if ( protect )
01348         return Qt::ForbiddenCursor;
01349     else
01350         return Qt::sizeAllCursor;
01351 }
01352 
01353 void KPrObject::getShadowCoords( double& _x, double& _y ) const
01354 {
01355     double sx = 0, sy = 0;
01356 
01357     switch ( shadowDirection )
01358     {
01359     case SD_LEFT_UP:
01360     {
01361         sx = _x - shadowDistance;
01362         sy = _y - shadowDistance;
01363     } break;
01364     case SD_UP:
01365     {
01366         sx = _x;
01367         sy = _y - shadowDistance;
01368     } break;
01369     case SD_RIGHT_UP:
01370     {
01371         sx = _x + shadowDistance;
01372         sy = _y - shadowDistance;
01373     } break;
01374     case SD_RIGHT:
01375     {
01376         sx = _x + shadowDistance;
01377         sy = _y;
01378     } break;
01379     case SD_RIGHT_BOTTOM:
01380     {
01381         sx = _x + shadowDistance;
01382         sy = _y + shadowDistance;
01383     } break;
01384     case SD_BOTTOM:
01385     {
01386         sx = _x;
01387         sy = _y + shadowDistance;
01388     } break;
01389     case SD_LEFT_BOTTOM:
01390     {
01391         sx = _x - shadowDistance;
01392         sy = _y + shadowDistance;
01393     } break;
01394     case SD_LEFT:
01395     {
01396         sx = _x - shadowDistance;
01397         sy = _y;
01398     } break;
01399     }
01400 
01401     _x = sx; _y = sy;
01402 }
01403 
01404 void KPrObject::paintSelection( QPainter *_painter, KoTextZoomHandler *_zoomHandler, SelectionMode mode )
01405 {
01406     if ( !selected || mode == SM_NONE )
01407         return;
01408 
01409     _painter->save();
01410     _painter->translate( _zoomHandler->zoomItX(orig.x()), _zoomHandler->zoomItY(orig.y()) );
01411     _painter->setPen( QPen( Qt::black, 1, QPen::SolidLine ) );
01412     _painter->setBrush( kapp->palette().color( QPalette::Active, QColorGroup::Highlight ) );
01413 
01414     KoRect r = getRealRect();
01415 
01416     int x = _zoomHandler->zoomItX( r.left() - orig.x());
01417     int y = _zoomHandler->zoomItY( r.top() - orig.y());
01418     int zX6 = /*_zoomHandler->zoomItX(*/ 6 ;
01419     int zY6 = /*_zoomHandler->zoomItY(*/ 6 ;
01420     int w = _zoomHandler->zoomItX(r.width()) - 6;
01421     int h = _zoomHandler->zoomItY(r.height()) - 6;
01422 
01423     if ( mode == SM_MOVERESIZE ) {
01424         _painter->drawRect( x, y,  zX6, zY6 );
01425         _painter->drawRect( x, y + h / 2, zX6, zY6 );
01426         _painter->drawRect( x, y + h, zX6, zY6 );
01427         _painter->drawRect( x + w, y, zX6, zY6 );
01428         _painter->drawRect( x + w, y + h / 2, zX6, zY6 );
01429         _painter->drawRect( x + w, y + h, zX6, zY6 );
01430         _painter->drawRect( x + w / 2, y,zX6, zY6 );
01431         _painter->drawRect( x + w / 2, y + h, zX6, zY6 );
01432     }
01433     else if ( mode == SM_PROTECT) {
01434         _painter->drawRect( x, y,  zX6, zY6 );
01435         _painter->drawRect( x, y + h / 2, zX6, zY6 );
01436         _painter->drawRect( x, y + h, zX6, zY6 );
01437         _painter->drawRect( x + w, y, zX6, zY6 );
01438         _painter->drawRect( x + w, y + h / 2, zX6, zY6 );
01439         _painter->drawRect( x + w, y + h, zX6, zY6 );
01440         _painter->drawRect( x + w / 2, y,zX6, zY6 );
01441         _painter->drawRect( x + w / 2, y + h, zX6, zY6 );
01442 
01443         x= x + 1;
01444         y= y + 1;
01445         zX6=zX6-2;
01446         zY6=zY6-2;
01447 
01448         QBrush brush=kapp->palette().color( QPalette::Active,QColorGroup::Base );
01449         _painter->fillRect( x, y,  zX6, zY6, brush );
01450         _painter->fillRect( x, y + h / 2, zX6, zY6, brush);
01451         _painter->fillRect( x, y + h, zX6, zY6, brush );
01452         _painter->fillRect( x + w, y, zX6, zY6, brush );
01453         _painter->fillRect( x + w, y + h / 2, zX6, zY6, brush );
01454         _painter->fillRect( x + w  , y + h , zX6 , zY6 , brush );
01455         _painter->fillRect( x + w / 2 , y ,zX6 , zY6 , brush );
01456         _painter->fillRect( x + w / 2, y + h , zX6 , zY6 , brush );
01457     }
01458     else if ( mode == SM_ROTATE ) {
01459         _painter->drawEllipse( x, y,  zX6, zY6 );
01460         _painter->drawEllipse( x, y + h, zX6, zY6 );
01461         _painter->drawEllipse( x + w, y, zX6, zY6 );
01462         _painter->drawEllipse( x + w, y + h, zX6, zY6 );
01463     }
01464 
01465     _painter->restore();
01466 }
01467 
01468 void KPrObject::doDelete()
01469 {
01470     if ( cmds == 0 && !inObjList )
01471         delete this;
01472 }
01473 
01474 DCOPObject* KPrObject::dcopObject()
01475 {
01476     if ( !dcop )
01477         dcop = new KPrObjectIface( this );
01478 
01479     return dcop;
01480 }
01481 
01482 void KPrObject::setupClipRegion( QPainter *painter, const QRegion &clipRegion )
01483 {
01484     QRegion region = painter->clipRegion( QPainter::CoordPainter );
01485     if ( region.isEmpty() )
01486         region = clipRegion;
01487     else
01488         region.unite( clipRegion );
01489 
01490     painter->setClipRegion( region, QPainter::CoordPainter );
01491 }
01492 
01493 QDomElement KPrObject::createValueElement(const QString &tag, int value, QDomDocument &doc) {
01494     QDomElement elem=doc.createElement(tag);
01495     elem.setAttribute(attrValue, value);
01496     return elem;
01497 }
01498 
01499 QDomElement KPrObject::createGradientElement(const QString &tag, const QColor &c1, const QColor &c2,
01500                                             int type, bool unbalanced, int xfactor,
01501                                             int yfactor, QDomDocument &doc) {
01502     QDomElement elem=doc.createElement(tag);
01503     elem.setAttribute(attrC1, c1.name());
01504     elem.setAttribute(attrC2, c2.name());
01505     elem.setAttribute(attrType, type);
01506     elem.setAttribute(attrUnbalanced, (uint)unbalanced);
01507     elem.setAttribute(attrXFactor, xfactor);
01508     elem.setAttribute(attrYFactor, yfactor);
01509     return elem;
01510 }
01511 
01512 QDomElement KPrObject::createPenElement(const QString &tag, const KoPen &pen, QDomDocument &doc) {
01513 
01514     QDomElement elem=doc.createElement(tag);
01515     elem.setAttribute(attrColor, pen.color().name());
01516     elem.setAttribute(attrWidth, pen.pointWidth());
01517     elem.setAttribute(attrStyle, static_cast<int>(pen.style()));
01518     return elem;
01519 }
01520 
01521 KoPen KPrObject::toPen(const QDomElement &element) const {
01522 
01523     KoPen pen;
01524     pen.setColor(retrieveColor(element));
01525     if(element.hasAttribute(attrStyle))
01526         pen.setStyle(static_cast<Qt::PenStyle>(element.attribute(attrStyle).toInt()));
01527     if(element.hasAttribute(attrWidth))
01528         pen.setPointWidth(element.attribute(attrWidth).toDouble());
01529     return pen;
01530 }
01531 
01532 QDomElement KPrObject::createBrushElement(const QString &tag, const QBrush &brush, QDomDocument &doc) {
01533 
01534     QDomElement elem=doc.createElement(tag);
01535     elem.setAttribute(attrColor, brush.color().name());
01536     elem.setAttribute(attrStyle, static_cast<int>(brush.style()));
01537     return elem;
01538 }
01539 
01540 QBrush KPrObject::toBrush(const QDomElement &element) const {
01541 
01542     QBrush brush;
01543     brush.setColor(retrieveColor(element));
01544     if(element.hasAttribute(attrStyle))
01545         brush.setStyle(static_cast<Qt::BrushStyle>(element.attribute(attrStyle).toInt()));
01546     return brush;
01547 }
01548 
01549 QColor KPrObject::retrieveColor(const QDomElement &element, const QString &cattr,
01550                                const QString &rattr, const QString &gattr, const QString &battr) const {
01551     QColor ret;
01552     if(element.hasAttribute(cattr))
01553         ret.setNamedColor(element.attribute(cattr));
01554     else {
01555         int red=0, green=0, blue=0;
01556         if(element.hasAttribute(rattr))
01557             red=element.attribute(rattr).toInt();
01558         if(element.hasAttribute(gattr))
01559             green=element.attribute(gattr).toInt();
01560         if(element.hasAttribute(battr))
01561             blue=element.attribute(battr).toInt();
01562         ret.setRgb(red, green, blue);
01563     }
01564     return ret;
01565 }
01566 
01567 void KPrObject::draw( QPainter *_painter, KoTextZoomHandler*_zoomHandler,
01568                      int /*pageNum*/, SelectionMode selectionMode, bool drawContour )
01569 {
01570     if ( selectionMode != SM_NONE && !drawContour )
01571         paintSelection( _painter, _zoomHandler, selectionMode );
01572 }
01573 
01574 KoPen KPrObject::getPen() const
01575 {
01576     // Return the default pen
01577     return KoPen();
01578 }
01579 
01580 void KPrObject::getRealSizeAndOrigFromPoints( KoPointArray &points, float angle,
01581                                             KoSize &size, KoPoint &orig )
01582 {
01583     if ( angle == 0 )
01584         return;
01585 
01586     float angInRad = angle * M_PI / 180;
01587     float sinus = sin( angInRad );
01588     float cosinus = cos( angInRad );
01589 
01590     float mid_x = size.width() / 2;
01591     float mid_y = size.height() / 2;
01592 
01593     float min_x = 0;
01594     float max_x = 0;
01595     float min_y = 0;
01596     float max_y = 0;
01597     KoPointArray::ConstIterator it;
01598     for ( it = points.begin(); it != points.end(); ++it ) {
01599         KoPoint cord( mid_x - (*it).x(), (*it).y() - mid_y );
01600         float tmp_x = cord.x() * cosinus + cord.y() * sinus;
01601         float tmp_y = - cord.x() * sinus + cord.y() * cosinus;
01602 
01603         if ( tmp_x < min_x ) {
01604             min_x = tmp_x;
01605         }
01606         else if ( tmp_x > max_x ) {
01607             max_x = tmp_x;
01608         }
01609 
01610         if ( tmp_y < min_y ) {
01611             min_y = tmp_y;
01612         }
01613         else if ( tmp_y > max_y ) {
01614             max_y = tmp_y;
01615         }
01616     }
01617 
01618     size.setWidth( max_x - min_x );
01619     size.setHeight( max_y - min_y );
01620 
01621     orig.setX( orig.x() + mid_x - max_x );
01622     orig.setY( orig.y() + mid_y + min_y );
01623 }
01624 
01625 void KPrObject::addSelfToGuides(QValueList<double> &horizontalPos, QValueList<double> &verticalPos )
01626 {
01627     KoRect bounds = getRealRect();
01628 
01629     horizontalPos.append( bounds.top() );
01630     verticalPos.append( bounds.left() );
01631     horizontalPos.append( bounds.bottom() );
01632     verticalPos.append( bounds.right() );
01633 }
01634 
01635 KPrShadowObject::KPrShadowObject()
01636     : KPrObject()
01637 {
01638 }
01639 
01640 KPrShadowObject::KPrShadowObject( const KoPen &_pen )
01641     : KPrObject(), pen( _pen )
01642 {
01643 }
01644 
01645 KPrShadowObject &KPrShadowObject::operator=( const KPrShadowObject & )
01646 {
01647     return *this;
01648 }
01649 
01650 QDomDocumentFragment KPrShadowObject::save( QDomDocument& doc,double offset )
01651 {
01652     QDomDocumentFragment fragment=KPrObject::save(doc, offset);
01653 
01654     if(pen!=defaultPen())
01655         fragment.appendChild(KPrObject::createPenElement(tagPEN, pen, doc));
01656     return fragment;
01657 }
01658 
01659 void KPrShadowObject::saveOasisStrokeElement( KoGenStyles& mainStyles, KoGenStyle &styleobjectauto ) const
01660 {
01661     switch( pen.style() )
01662     {
01663         case Qt::NoPen:
01664             styleobjectauto.addProperty( "draw:stroke" , "none" );
01665             break;
01666         case Qt::SolidLine:
01667             styleobjectauto.addProperty( "draw:stroke" , "solid" );
01668             break;
01669         case Qt::DashLine:
01670         case Qt::DotLine:
01671         case Qt::DashDotLine:
01672         case Qt::DashDotDotLine:
01673             styleobjectauto.addProperty( "draw:stroke" , "dash" );
01674             //TODO FIXME
01675             styleobjectauto.addProperty( "draw:stroke-dash", saveOasisStrokeStyle( mainStyles ) );
01676             break;
01677         default:
01678             break;
01679     }
01680     if ( pen.style() != Qt::NoPen )
01681     {
01682         styleobjectauto.addProperty( "svg:stroke-color", pen.color().name() );
01683         styleobjectauto.addPropertyPt( "svg:stroke-width", pen.pointWidth() );
01684     }
01685 }
01686 
01687 QString KPrShadowObject::saveOasisStrokeStyle( KoGenStyles& mainStyles ) const
01688 {
01689     KoGenStyle stroke( KPrDocument::STYLE_STROKE /*, "graphic"*/ /*no name*/ );
01690     switch( pen.style() )
01691     {
01692     case Qt::NoPen:
01693         //nothing
01694         break;
01695     case Qt::SolidLine:
01696         //nothing
01697         break;
01698     case Qt::DashLine: //value from ooimpress filter
01699         stroke.addAttribute( "draw:style", "rect" );
01700         stroke.addAttribute( "draw:dots1", "1" );
01701         stroke.addAttribute( "draw:dots2", "1" );
01702         stroke.addAttribute( "draw:dots1-length", "0.508cm" );
01703         stroke.addAttribute( "draw:dots2-length", "0.508cm" );
01704         stroke.addAttribute( "draw:distance", "0.508cm" );
01705         break;
01706     case Qt::DotLine:
01707         stroke.addAttribute( "draw:style", "rect" );
01708         stroke.addAttribute( "draw:dots1", "1" );
01709         stroke.addAttribute( "draw:distance", "0.257cm" );
01710         break;
01711     case Qt::DashDotLine:
01712         stroke.addAttribute( "draw:style", "rect" );
01713         stroke.addAttribute( "draw:dots1", "1" );
01714         stroke.addAttribute( "draw:dots2", "1" );
01715         stroke.addAttribute( "draw:dots1-length", "0.051cm" );
01716         stroke.addAttribute( "draw:dots2-length", "0.254cm" );
01717         stroke.addAttribute( "draw:distance", "0.127cm" );
01718         break;
01719     case Qt::DashDotDotLine:
01720         stroke.addAttribute( "draw:style", "rect" );
01721         stroke.addAttribute( "draw:dots1", "2" );
01722         stroke.addAttribute( "draw:dots2", "1" );
01723         stroke.addAttribute( "draw:dots2-length", "0.203cm" );
01724         stroke.addAttribute( "draw:distance", "0.203cm" );
01725         break;
01726     default:
01727         break;
01728     }
01729     return mainStyles.lookup( stroke, "stroke" );
01730     //    <draw:stroke-dash draw:name="Fine Dotted" draw:style="rect" draw:dots1="1" draw:distance="0.457cm"/>
01731 }
01732 
01733 bool KPrShadowObject::saveOasisDrawPoints( const KoPointArray &points, KPOasisSaveContext &sc )
01734 {
01735     QString listOfPoint;
01736     int maxX=0;
01737     int maxY=0;
01738     KoPointArray::ConstIterator it( points.begin() );
01739     KoPointArray::ConstIterator end( points.end() );
01740     for ( ; it != end; ++it )
01741     {
01742         int tmpX = int( ( *it ).x() * 10000 );
01743         int tmpY = int( ( *it ).y() * 10000 );
01744         // no space allows before first element
01745         if ( !listOfPoint.isEmpty() )
01746             listOfPoint += QString( " %1,%2" ).arg( tmpX ).arg( tmpY );
01747         else
01748             listOfPoint = QString( "%1,%2" ).arg( tmpX ).arg( tmpY );
01749         maxX = QMAX( maxX, tmpX );
01750         maxY = QMAX( maxY, tmpY );
01751     }
01752     sc.xmlWriter.addAttribute("draw:points", listOfPoint );
01753     sc.xmlWriter.addAttribute("svg:viewBox", QString( "0 0 %1 %2" ).arg( maxX ).arg( maxY ) );
01754     return true;
01755 }
01756 
01757 bool KPrShadowObject::loadOasisDrawPoints( KoPointArray &points, const QDomElement &element,
01758                                           KoOasisContext & context, KPrLoadingInfo *info )
01759 {
01760     Q_UNUSED( context );
01761     Q_UNUSED( info );
01762     QStringList ptList = QStringList::split(' ', element.attributeNS( KoXmlNS::draw, "points", QString::null));
01763 
01764     unsigned int index = 0;
01765     for (QStringList::Iterator it = ptList.begin(); it != ptList.end(); ++it)
01766     {
01767         points.putPoints( index++, 1, ( *it ).section( ',', 0, 0 ).toInt(), ( *it ).section( ',', 1, 1 ).toInt() );
01768     }
01769     loadOasisApplyViewBox( element, points );
01770     return true;
01771 }
01772 
01773 
01774 bool KPrShadowObject::loadOasisApplyViewBox( const QDomElement &element, KoPointArray &points )
01775 {
01776     kdDebug(33001) << "loadOasisApplayViewBox svg:viewBox = " << element.attributeNS( KoXmlNS::svg, "viewBox", QString::null ) << endl;
01777     QStringList viewBoxPoints = QStringList::split( ' ', element.attributeNS( KoXmlNS::svg, "viewBox", QString::null ) );
01778 
01779     KoRect viewBox;
01780     if ( viewBoxPoints.size() == 4 )
01781     {
01782         QStringList::Iterator it = viewBoxPoints.begin();
01783         //viewBox.setCoords( ( *it++ ).toInt(), ( *it++ ).toInt(), ( *it++ ).toInt(), ( *it ).toInt() );
01784         viewBox.setLeft( ( *it++ ).toInt() );
01785         viewBox.setTop( ( *it++ ).toInt() );
01786         viewBox.setRight( ( *it++ ).toInt() );
01787         viewBox.setBottom( ( *it ).toInt() );
01788         
01789         kdDebug(33001) << "viewBox supplied = " << viewBox << endl;
01790     }
01791     else
01792     {
01793         //if no viewBox is found
01794         KoPointArray::ConstIterator it( points.begin() );
01795         bool first = true;
01796         for ( ; it != points.end(); ++it )
01797         {
01798             KoPoint p = (*it);
01799             if ( first )
01800             {
01801                 viewBox.setCoords( p.x(), p.y(), p.x(), p.y() );
01802                 first = false;
01803             }
01804             else
01805             {
01806                 viewBox.setLeft( QMIN( viewBox.left(), p.x() ) );
01807                 viewBox.setRight( QMAX( viewBox.right(), p.x() ) );
01808                 viewBox.setTop( QMIN( viewBox.top(), p.y() ) );
01809                 viewBox.setBottom( QMAX( viewBox.bottom(), p.y() ) );
01810             }
01811         }
01812         kdDebug(33001) << "viewBox calculated = " << viewBox << endl;
01813     }
01814 
01815     if ( viewBox.width() != 0 && viewBox.height() != 0 )
01816     {
01817         KoPointArray::Iterator it( points.begin() );
01818         for ( ; it != points.end(); ++it )
01819         {
01820             KoPoint *p = it;
01821             p->setX( ( p->x() - viewBox.left() ) / viewBox.width() * ext.width() );
01822             p->setY( ( p->y() - viewBox.top() ) / viewBox.height() * ext.height() );
01823         }
01824     }
01825     else
01826     {
01827         kdDebug(33001) << "problem in viewBox: " << viewBox << endl;
01828     }
01829     return true;
01830 }
01831 
01832 
01833 void KPrShadowObject::fillStyle( KoGenStyle& styleObjectAuto, KoGenStyles& mainStyles ) const
01834 {
01835     kdDebug(33001) << "KPrShadowObject::fillStyle" << endl;
01836     KPrObject::fillStyle( styleObjectAuto, mainStyles );
01837     saveOasisStrokeElement( mainStyles, styleObjectAuto );
01838 }
01839 
01840 void KPrShadowObject::loadOasis(const QDomElement &element, KoOasisContext & context, KPrLoadingInfo *info)
01841 {
01842     //kdDebug()<<"void KPrShadowObject::loadOasis(const QDomElement &element)**********************\n";
01843     KPrObject::loadOasis(element, context, info);
01844     KoStyleStack &styleStack = context.styleStack();
01845     styleStack.setTypeProperties( "graphic" );
01846     if ( styleStack.hasAttributeNS( KoXmlNS::draw, "stroke" ))
01847     {
01848         if ( styleStack.attributeNS( KoXmlNS::draw, "stroke" ) == "none" )
01849             pen.setStyle(Qt::NoPen );
01850         else if ( styleStack.attributeNS( KoXmlNS::draw, "stroke" ) == "solid" )
01851             pen.setStyle(Qt::SolidLine );
01852         else if ( styleStack.attributeNS( KoXmlNS::draw, "stroke" ) == "dash" )
01853         {
01854             QString style = styleStack.attributeNS( KoXmlNS::draw, "stroke-dash" );
01855 
01856             kdDebug()<<" stroke style is  : "<<style<<endl;
01857             //type not defined by default
01858             //try to use style.
01859             QDomElement* draw = context.oasisStyles().drawStyles()[style];
01860             kdDebug()<<" stroke have oasis style defined :"<<draw<<endl;
01861             if ( draw )
01862             {
01863                 //FIXME
01864                 if ( draw->attributeNS( KoXmlNS::draw, "style", QString::null )=="rect" )
01865                 {
01866                     if ( draw->attributeNS( KoXmlNS::draw, "dots1", QString::null )=="1" &&
01867                          draw->attributeNS( KoXmlNS::draw, "dots2", QString::null )=="1" &&
01868                          draw->attributeNS( KoXmlNS::draw, "dots1-length", QString::null )=="0.508cm" &&
01869                          draw->attributeNS( KoXmlNS::draw, "dots2-length", QString::null )=="0.508cm" &&
01870                          draw->attributeNS( KoXmlNS::draw, "distance", QString::null )=="0.508cm" )
01871                         pen.setStyle( Qt::DashLine );
01872                     else if ( draw->attributeNS( KoXmlNS::draw, "dots1", QString::null )=="1" &&
01873                               draw->attributeNS( KoXmlNS::draw, "distance", QString::null )=="0.257cm" )
01874                         pen.setStyle(Qt::DotLine );
01875                     else if ( draw->attributeNS( KoXmlNS::draw, "dots1", QString::null )=="1" &&
01876                          draw->attributeNS( KoXmlNS::draw, "dots2", QString::null )=="1" &&
01877                          draw->attributeNS( KoXmlNS::draw, "dots1-length", QString::null )=="0.051cm" &&
01878                          draw->attributeNS( KoXmlNS::draw, "dots2-length", QString::null )=="0.254cm" &&
01879                          draw->attributeNS( KoXmlNS::draw, "distance", QString::null )=="0.127cm" )
01880                         pen.setStyle(Qt::DashDotLine );
01881                     else if ( draw->attributeNS( KoXmlNS::draw, "dots1", QString::null )=="2" &&
01882                          draw->attributeNS( KoXmlNS::draw, "dots2", QString::null )=="1" &&
01883                          draw->attributeNS( KoXmlNS::draw, "dots2-length", QString::null )=="0.203cm" &&
01884                          draw->attributeNS( KoXmlNS::draw, "distance", QString::null )=="0.203cm" )
01885                         pen.setStyle(Qt::DashDotDotLine );
01886                     else
01887                     {
01888                         kdDebug()<<" stroke style undefined \n";
01889                         pen.setStyle(Qt::SolidLine );
01890                     }
01891 
01892                 }
01893             }
01894         }
01895         //FIXME witdh pen style is not good :(
01896         if ( styleStack.hasAttributeNS( KoXmlNS::svg, "stroke-width" ) )
01897             pen.setPointWidth( KoUnit::parseValue( styleStack.attributeNS( KoXmlNS::svg, "stroke-width" ) ) );
01898         if ( styleStack.hasAttributeNS( KoXmlNS::svg, "stroke-color" ) )
01899             pen.setColor( styleStack.attributeNS( KoXmlNS::svg, "stroke-color" ) );
01900     }
01901     else
01902         pen = defaultPen();
01903     kdDebug()<<"pen style :"<<pen<<endl;
01904 }
01905 
01906 double KPrShadowObject::load(const QDomElement &element)
01907 {
01908     double offset=KPrObject::load(element);
01909     QDomElement e=element.namedItem(tagPEN).toElement();
01910     if(!e.isNull())
01911         setPen(KPrObject::toPen(e));
01912     else
01913         pen = defaultPen();
01914     return offset;
01915 }
01916 
01917 void KPrShadowObject::draw( QPainter *_painter, KoTextZoomHandler*_zoomHandler,
01918                            int pageNum, SelectionMode selectionMode, bool drawContour )
01919 {
01920     double ox = orig.x();
01921     double oy = orig.y();
01922     _painter->save();
01923 
01924     // Draw the shadow if any
01925     if ( shadowDistance > 0 && !drawContour )
01926     {
01927         _painter->save();
01928         // tz TODO fix tmpPen usage
01929         KoPen tmpPen( pen );
01930         pen.setColor( shadowColor );
01931         QBrush brush;
01932         brush.setColor( shadowColor );
01933 
01934         double sx = ox;
01935         double sy = oy;
01936         getShadowCoords( sx, sy );
01937 
01938         _painter->translate( _zoomHandler->zoomItX( sx ), _zoomHandler->zoomItY( sy ) );
01939 
01940         if ( angle != 0 )
01941         {
01942             rotateObject( _painter, _zoomHandler );
01943         }
01944 
01945         paint( _painter, _zoomHandler, pageNum, true, drawContour );
01946 
01947         pen = tmpPen;
01948         _painter->restore();
01949     }
01950 
01951     _painter->translate( _zoomHandler->zoomItX(ox), _zoomHandler->zoomItY(oy) );
01952 
01953     if ( angle != 0 )
01954         rotateObject(_painter,_zoomHandler);
01955     paint( _painter, _zoomHandler, pageNum, false, drawContour );
01956 
01957     _painter->restore();
01958 
01959     KPrObject::draw( _painter, _zoomHandler, pageNum, selectionMode, drawContour );
01960 }
01961 
01962 KoPen KPrShadowObject::defaultPen() const
01963 {
01964     return KoPen();
01965 }
01966 
01967 void KPrShadowObject::paint(QPainter* painter, KoTextZoomHandler* zoomHandler, int pageNum, bool drawingShadow, bool drawContour) {
01968     Q_UNUSED(painter);
01969     Q_UNUSED(zoomHandler);
01970     Q_UNUSED(pageNum);
01971     Q_UNUSED(drawingShadow);
01972     Q_UNUSED(drawContour);
01973 }
01974 
01975 KPr2DObject::KPr2DObject()
01976     : KPrShadowObject()
01977     , gradient( 0 )
01978     , m_redrawGradientPix( false )
01979 {
01980 }
01981 
01982 KPr2DObject::KPr2DObject( const KoPen &_pen, const QBrush &_brush, FillType _fillType,
01983                         const QColor &_gColor1, const QColor &_gColor2, BCType _gType,
01984                         bool _unbalanced, int _xfactor, int _yfactor )
01985     : KPrShadowObject( _pen )
01986     , m_brush( _brush, _gColor1, _gColor2, _gType, _fillType, _unbalanced, _xfactor, _yfactor )
01987     , gradient( 0 )
01988     , m_redrawGradientPix( false )
01989 {
01990     if ( getFillType() == FT_GRADIENT )
01991     {
01992         gradient = new KPrGradient( getGColor1(), getGColor2(),
01993                                    getGType(), getGUnbalanced(),
01994                                    getGXFactor(), getGYFactor() );
01995         m_redrawGradientPix = true;
01996     }
01997 }
01998 
01999 void KPr2DObject::setFillType( FillType _fillType )
02000 {
02001     m_brush.setFillType( _fillType );
02002 
02003     if ( _fillType == FT_BRUSH && gradient )
02004     {
02005         delete gradient;
02006         gradient = 0;
02007     }
02008     if ( _fillType == FT_GRADIENT && !gradient )
02009     {
02010         gradient = new KPrGradient( getGColor1(), getGColor2(),
02011                                    getGType(), getGUnbalanced(),
02012                                    getGXFactor(), getGYFactor() );
02013         m_redrawGradientPix = true;
02014     }
02015 }
02016 
02017 QDomDocumentFragment KPr2DObject::save( QDomDocument& doc,double offset )
02018 {
02019     QDomDocumentFragment fragment=KPrShadowObject::save(doc, offset);
02020     QBrush brush = getBrush();
02021     if ( brush != QBrush() )
02022         fragment.appendChild( KPrObject::createBrushElement( tagBRUSH, brush, doc ) );
02023 
02024     FillType fillType = getFillType();
02025     if ( fillType != FT_BRUSH )
02026         fragment.appendChild( KPrObject::createValueElement( tagFILLTYPE, static_cast<int>(fillType), doc ) );
02027     QColor gColor1 = getGColor1();
02028     QColor gColor2 = getGColor2();
02029     BCType gType = getGType();
02030     bool unbalanced = getGUnbalanced();
02031     int xfactor = getGXFactor();
02032     int yfactor = getGYFactor();
02033     if ( gColor1!=Qt::red || gColor2!=Qt::green || gType!=BCT_GHORZ || unbalanced || xfactor != 100 || yfactor != 100 )
02034         fragment.appendChild( KPrObject::createGradientElement( tagGRADIENT, gColor1, gColor2, static_cast<int>(gType),
02035                                                                unbalanced, xfactor, yfactor, doc));
02036     return fragment;
02037 }
02038 
02039 void KPr2DObject::fillStyle( KoGenStyle& styleObjectAuto, KoGenStyles& mainStyles ) const
02040 {
02041     kdDebug(33001) << "KPr2DObject::fillStyle" << endl;
02042     KPrShadowObject::fillStyle( styleObjectAuto, mainStyles );
02043     m_brush.saveOasisFillStyle( styleObjectAuto, mainStyles );
02044 }
02045 
02046 
02047 void KPr2DObject::loadOasis(const QDomElement &element, KoOasisContext & context, KPrLoadingInfo *info)
02048 {
02049     kdDebug()<<"void KPr2DObject::loadOasis(const QDomElement &element)\n";
02050     QBrush tmpBrush;
02051 
02052     KPrShadowObject::loadOasis(element, context, info);
02053     m_brush.loadOasisFillStyle( context, "graphic" );
02054     setFillType( m_brush.getFillType() );
02055 }
02056 
02057 double KPr2DObject::load(const QDomElement &element)
02058 {
02059     double offset=KPrShadowObject::load(element);
02060 
02061     QDomElement e=element.namedItem(tagFILLTYPE).toElement();
02062     if(!e.isNull()) {
02063         if(e.hasAttribute(attrValue))
02064             setFillType(static_cast<FillType>(e.attribute(attrValue).toInt()));
02065     }
02066     else
02067         setFillType(FT_BRUSH);
02068 
02069     e=element.namedItem(tagBRUSH).toElement();
02070     if(!e.isNull())
02071         setBrush(KPrObject::toBrush(e));
02072     else
02073         setBrush( QBrush() );
02074 
02075     e=element.namedItem(tagGRADIENT).toElement();
02076     if(!e.isNull()) {
02077         setGColor1( retrieveColor( e, attrC1, "red1", "green1", "blue1" ) );
02078         setGColor2( retrieveColor( e, attrC2, "red2", "green2", "blue2" ) );
02079         if( e.hasAttribute( attrType ) )
02080             setGType( static_cast<BCType>( e.attribute( attrType ).toInt() ) );
02081         if( e.hasAttribute( attrUnbalanced ) )
02082             setGUnbalanced( static_cast<bool>( e.attribute( attrUnbalanced ).toInt() ) );
02083         if( e.hasAttribute( attrXFactor ) )
02084             setGXFactor( e.attribute( attrXFactor ).toInt() );
02085         if( e.hasAttribute( attrYFactor ) )
02086             setGYFactor( e.attribute( attrYFactor ).toInt() );
02087         if(gradient)
02088             gradient->setParameters(getGColor1(), getGColor2(), getGType(), getGUnbalanced(), getGXFactor(), getGYFactor() );
02089     }
02090     else {
02091         setGColor1( Qt::red );
02092         setGColor2( Qt::green );
02093         setGType( BCT_GHORZ );
02094         setGUnbalanced( false );
02095         setGXFactor( 100 );
02096         setGYFactor( 100 );
02097     }
02098     return offset;
02099 }
02100 
02101 void KPr2DObject::draw( QPainter *_painter, KoTextZoomHandler*_zoomHandler,
02102                            int pageNum, SelectionMode selectionMode, bool drawContour )
02103 {
02104     double ox = orig.x();
02105     double oy = orig.y();
02106     _painter->save();
02107 
02108     // Draw the shadow if any
02109     if ( shadowDistance > 0 && !drawContour )
02110     {
02111         _painter->save();
02112         KoPen tmpPen( pen );
02113         pen.setColor( shadowColor );
02114         QBrush tmpBrush( m_brush.getBrush() );
02115         QBrush shadowBrush( tmpBrush );
02116         shadowBrush.setColor( shadowColor );
02117         m_brush.setBrush( shadowBrush );
02118 
02119         double sx = ox;
02120         double sy = oy;
02121         getShadowCoords( sx, sy );
02122 
02123         _painter->translate( _zoomHandler->zoomItX( sx ), _zoomHandler->zoomItY( sy ) );
02124 
02125         if ( angle != 0 )
02126         {
02127             rotateObject( _painter, _zoomHandler );
02128         }
02129 
02130         paint( _painter, _zoomHandler, pageNum, true, drawContour );
02131 
02132         pen = tmpPen;
02133         m_brush.setBrush( tmpBrush );
02134         _painter->restore();
02135     }
02136 
02137     _painter->translate( _zoomHandler->zoomItX(ox), _zoomHandler->zoomItY(oy) );
02138 
02139     if ( angle != 0 )
02140         rotateObject(_painter,_zoomHandler);
02141     paint( _painter, _zoomHandler, pageNum, false, drawContour );
02142 
02143     _painter->restore();
02144 
02145     KPrObject::draw( _painter, _zoomHandler, pageNum, selectionMode, drawContour );
02146 }
02147 
02148 void KPr2DObject::flip( bool horizontal ) {
02149     KPrObject::flip( horizontal );
02150 
02151     // flip the gradient
02152     if ( getFillType() == FT_GRADIENT ) {
02153         BCType gType = getGType();
02154         if ( gType == BCT_GDIAGONAL1 ) {
02155             setGType( BCT_GDIAGONAL2 );
02156         }
02157         else if ( gType == BCT_GDIAGONAL2 ) {
02158             setGType( BCT_GDIAGONAL1 );
02159         }
02160         if ( ( ! horizontal && gType == BCT_GDIAGONAL1 ) ||
02161              ( ! horizontal && gType == BCT_GDIAGONAL2 ) ||
02162              ( ! horizontal && gType == BCT_GHORZ ) ||
02163              ( horizontal && gType == BCT_GVERT ) ) {
02164             QColor gColorTemp;
02165             gColorTemp = getGColor1();
02166             setGColor1( getGColor2() );
02167             setGColor2( gColorTemp );
02168         }
02169         delete gradient;
02170         gradient = new KPrGradient( getGColor1(), getGColor2(), gType, getGUnbalanced(), getGXFactor(), getGYFactor() );
02171     }
02172 }
KDE Home | KDE Accessibility Home | Description of Access Keys