kpresenter

KPrObject.cpp
1/* This file is part of the KDE project
2 Copyright (C) 1998, 1999 Reginald Stadlbauer <reggie@kde.org>
3 Copyright (C) 2005-2006 Thorsten Zachmann <zachmann@kde.org>
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public
7 License as published by the Free Software Foundation; either
8 version 2 of the License, or (at your option) any later version.
9
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Library General Public License for more details.
14
15 You should have received a copy of the GNU Library General Public License
16 along with this library; see the file COPYING.LIB. If not, write to
17 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 * Boston, MA 02110-1301, USA.
19*/
20
21#include "KPrObjectIface.h"
22
23#include "KPrObject.h"
24#include "KPrDocument.h"
25#include "KPrUtils.h"
26
27#include <tqpainter.h>
28#include <tqwmatrix.h>
29#include <tqpointarray.h>
30#include <tqregion.h>
31#include <tqdom.h>
32#include <tqbuffer.h>
33#include <tqregexp.h>
34
35#include <tdeapplication.h>
36#include <KoOasisContext.h>
37#include "KoOasisStyles.h"
38
39#include <stdlib.h>
40#include <fstream>
41#include <math.h>
42#include <float.h>
43
44#include <KoTextZoomHandler.h>
45#include <KoRect.h>
46#include <KoSize.h>
47#include <KoPoint.h>
48#include <KoXmlNS.h>
49#include <KoDom.h>
50#include <kdebug.h>
51
52const TQString &KPrObject::tagORIG=TDEGlobal::staticQString("ORIG");
53const TQString &KPrObject::attrX=TDEGlobal::staticQString("x");
54const TQString &KPrObject::attrY=TDEGlobal::staticQString("y");
55const TQString &KPrObject::tagSIZE=TDEGlobal::staticQString("SIZE");
56const TQString &KPrObject::attrWidth=TDEGlobal::staticQString("width");
57const TQString &KPrObject::attrHeight=TDEGlobal::staticQString("height");
58const TQString &KPrObject::tagSHADOW=TDEGlobal::staticQString("SHADOW");
59const TQString &KPrObject::attrDistance=TDEGlobal::staticQString("distance");
60const TQString &KPrObject::attrDirection=TDEGlobal::staticQString("direction");
61const TQString &KPrObject::attrColor=TDEGlobal::staticQString("color");
62const TQString &KPrObject::tagEFFECTS=TDEGlobal::staticQString("EFFECTS");
63const TQString &KPrObject::attrEffect=TDEGlobal::staticQString("effect");
64const TQString &KPrObject::attrEffect2=TDEGlobal::staticQString("effect2");
65const TQString &KPrObject::tagPRESNUM=TDEGlobal::staticQString("PRESNUM");
66const TQString &KPrObject::tagANGLE=TDEGlobal::staticQString("ANGLE");
67const TQString &KPrObject::tagDISAPPEAR=TDEGlobal::staticQString("DISAPPEAR");
68const TQString &KPrObject::attrDoit=TDEGlobal::staticQString("doit");
69const TQString &KPrObject::attrNum=TDEGlobal::staticQString("num");
70const TQString &KPrObject::tagFILLTYPE=TDEGlobal::staticQString("FILLTYPE");
71const TQString &KPrObject::tagGRADIENT=TDEGlobal::staticQString("GRADIENT");
72const TQString &KPrObject::tagPEN=TDEGlobal::staticQString("PEN");
73const TQString &KPrObject::tagBRUSH=TDEGlobal::staticQString("BRUSH");
74const TQString &KPrObject::attrValue=TDEGlobal::staticQString("value");
75const TQString &KPrObject::attrC1=TDEGlobal::staticQString("color1");
76const TQString &KPrObject::attrC2=TDEGlobal::staticQString("color2");
77const TQString &KPrObject::attrType=TDEGlobal::staticQString("type");
78const TQString &KPrObject::attrUnbalanced=TDEGlobal::staticQString("unbalanced");
79const TQString &KPrObject::attrXFactor=TDEGlobal::staticQString("xfactor");
80const TQString &KPrObject::attrYFactor=TDEGlobal::staticQString("yfactor");
81const TQString &KPrObject::attrStyle=TDEGlobal::staticQString("style");
82
83KPrStartEndLine::KPrStartEndLine( LineEnd _start, LineEnd _end )
84 : lineBegin( _start ), lineEnd( _end )
85{
86}
87
88void KPrStartEndLine::save( TQDomDocumentFragment &fragment, TQDomDocument& doc )
89{
90 if (lineBegin!=L_NORMAL)
91 fragment.appendChild(KPrStartEndLine::createValueElement("LINEBEGIN", static_cast<int>(lineBegin), doc));
92 if (lineEnd!=L_NORMAL)
93 fragment.appendChild(KPrStartEndLine::createValueElement("LINEEND", static_cast<int>(lineEnd), doc));
94}
95
96TQDomElement KPrStartEndLine::createValueElement(const TQString &tag, int value, TQDomDocument &doc)
97{
98 TQDomElement elem=doc.createElement(tag);
99 elem.setAttribute("value", value);
100 return elem;
101}
102
103
104void KPrStartEndLine::load( const TQDomElement &element )
105{
106 TQDomElement e=element.namedItem("LINEBEGIN").toElement();
107 if(!e.isNull()) {
108 int tmp=0;
109 if(e.hasAttribute("value"))
110 tmp=e.attribute("value").toInt();
111 lineBegin=static_cast<LineEnd>(tmp);
112 }
113 e=element.namedItem("LINEEND").toElement();
114 if(!e.isNull()) {
115 int tmp=0;
116 if(e.hasAttribute("value"))
117 tmp=e.attribute("value").toInt();
118 lineEnd=static_cast<LineEnd>(tmp);
119 }
120}
121
122void KPrStartEndLine::loadOasisMarkerElement( KoOasisContext & context, const TQString & attr, LineEnd &_element )
123{
124 //kdDebug()<<"void KPrStartEndLine::loadOasisMarkerElement( KoOasisContext & context, const TQString & attr, LineEnd &_element ) :"<<attr<<endl;
125
126 KoStyleStack &styleStack = context.styleStack();
127 styleStack.setTypeProperties( "graphic" );
128 if ( styleStack.hasAttributeNS( KoXmlNS::draw,attr.latin1() ) )
129 {
130 TQString style = styleStack.attributeNS( KoXmlNS::draw, attr.latin1() );
131 //kdDebug()<<" marker style is : "<<style<<endl;
132
133 //type not defined by default
134 //try to use style.
135 TQDomElement* draw = context.oasisStyles().drawStyles()[style];
136 //kdDebug()<<" marker have oasis style defined :"<<draw<<endl;
137 if ( draw )
138 {
139 if( draw->hasAttributeNS( KoXmlNS::svg, "d" ))
140 {
141 TQString str = draw->attributeNS( KoXmlNS::svg, "d", TQString() );
142 kdDebug()<<" svg type = "<<str<<endl;
143 if ( str == lineEndBeginSvg( L_ARROW ) )
144 _element = L_ARROW;
145 else if ( str == lineEndBeginSvg( L_CIRCLE ) )
146 _element = L_CIRCLE;
147 else if ( str == lineEndBeginSvg( L_SQUARE ) )
148 _element = L_SQUARE;
149 else if ( str == lineEndBeginSvg( L_LINE_ARROW ) )
150 _element = L_LINE_ARROW;
151 else if ( str == lineEndBeginSvg( L_DIMENSION_LINE ) )
152 _element = L_DIMENSION_LINE;
153 else if ( str == lineEndBeginSvg( L_DOUBLE_ARROW ) )
154 _element = L_DOUBLE_ARROW;
155 else if ( str == lineEndBeginSvg( L_DOUBLE_LINE_ARROW ) )
156 _element = L_DOUBLE_LINE_ARROW;
157 else
158 {
159 kdDebug()<<" element not defined :"<<str<<endl;
160 _element = L_NORMAL;
161 }
162 }
163 }
164 }
165}
166
167void KPrStartEndLine::saveOasisMarkerElement( KoGenStyles& mainStyles, KoGenStyle &styleobjectauto ) const
168{
169 if ( lineBegin != L_NORMAL )
170 {
171 styleobjectauto.addProperty( "draw:marker-start", saveOasisMarkerStyle( mainStyles, lineBegin ) );
172 styleobjectauto.addProperty( "draw:marker-start-width", "0.25cm" );//value from ooimpress
173 }
174 if ( lineEnd != L_NORMAL )
175 {
176 styleobjectauto.addProperty( "draw:marker-end", saveOasisMarkerStyle( mainStyles, lineEnd ) );
177 styleobjectauto.addProperty( "draw:marker-end-width", "0.25cm" );
178 }
179}
180
181TQString KPrStartEndLine::saveOasisMarkerStyle( KoGenStyles &mainStyles, const LineEnd &_element ) const
182{
183 KoGenStyle marker( KPrDocument::STYLE_MARKER /*, "graphic"*/ /*no name*/ );
184 // value used from ooimpress filter I don't know if it's good
185 switch( _element )
186 {
187 case L_NORMAL:
188 //nothing
189 break;
190 case L_ARROW:
191 marker.addAttribute( "svg:viewBox", "0 0 20 30" );
192 break;
193 case L_SQUARE:
194 marker.addAttribute( "svg:viewBox", "0 0 10 10" );
195 break;
196 case L_CIRCLE:
197 marker.addAttribute( "svg:viewBox", "0 0 1131 1131" );
198 break;
199 case L_LINE_ARROW:
200 marker.addAttribute( "svg:viewBox", "0 0 1122 2243" );
201 break;
202 case L_DIMENSION_LINE:
203 marker.addAttribute( "svg:viewBox", "0 0 836 110" );
204 break;
205 case L_DOUBLE_ARROW:
206 marker.addAttribute( "svg:viewBox", "0 0 1131 1918" );
207 break;
208 case L_DOUBLE_LINE_ARROW:
209 //FIXME !!!!!!!!!!!!
210 // not defined into ooimpress filter.
211 //marker.addAttribute( "svg:viewBox", "...." );
212 //marker.addAttribute( "svg:d", "...." );
213 break;
214 }
215 marker.addAttribute( "svg:d", lineEndBeginSvg( _element ));
216
217 return mainStyles.lookup( marker, "marker" );
218}
219
220KPrObject::KPrObject()
221 : orig(), ext(), shadowColor( TQt::gray )
222{
223 appearStep = 0;
224 disappearStep = 1;
225 effect = EF_NONE;
226 effect2 = EF2_NONE;
227 effect3 = EF3_NONE;
228 m_appearSpeed = ES_MEDIUM;
229 m_disappearSpeed = ES_MEDIUM;
230 disappear = false;
231 appearTimer = 1;
232 disappearTimer = 1;
233 appearSoundEffect = false;
234 disappearSoundEffect = false;
235 a_fileName = TQString();
236 d_fileName = TQString();
237 objectName = TQString();
238 angle = 0.0;
239 shadowDirection = SD_RIGHT_BOTTOM;
240 shadowDistance = 0;
241 selected = false;
242 ownClipping = true;
243 subPresStep = 0;
244 specEffects = false;
245 onlyCurrStep = true;
246 inObjList = true;
247 cmds = 0;
248 resize = false;
249 protect = false;
250 keepRatio = false;
251 dcop = 0;
252}
253
254KPrObject::~KPrObject()
255{
256 delete dcop;
257}
258
259TQDomDocumentFragment KPrObject::save( TQDomDocument& doc, double offset )
260{
261 TQDomDocumentFragment fragment=doc.createDocumentFragment();
262 TQDomElement elem=doc.createElement(tagORIG);
263 elem.setAttribute(attrX, orig.x());
264 elem.setAttribute(attrY, TQString::number( orig.y() + offset, 'g', DBL_DIG ) );
265 fragment.appendChild(elem);
266 elem=doc.createElement(tagSIZE);
267 elem.setAttribute(attrWidth, ext.width());
268 elem.setAttribute(attrHeight, ext.height());
269 fragment.appendChild(elem);
270 if(shadowDistance!=0 || shadowDirection!=SD_RIGHT_BOTTOM || shadowColor!=TQt::gray) {
271 elem=doc.createElement(tagSHADOW);
272 elem.setAttribute(attrDistance, shadowDistance);
273 elem.setAttribute(attrDirection, static_cast<int>( shadowDirection ));
274 elem.setAttribute(attrColor, shadowColor.name());
275 fragment.appendChild(elem);
276 }
277 if(effect!=EF_NONE || effect2!=EF2_NONE) {
278 elem=doc.createElement(tagEFFECTS);
279 elem.setAttribute(attrEffect, static_cast<int>( effect ));
280 elem.setAttribute(attrEffect2, static_cast<int>( effect2 ));
281 elem.setAttribute( "speed", static_cast<int>(m_appearSpeed) );
282 fragment.appendChild(elem);
283 }
284 if(appearStep!=0)
285 fragment.appendChild(KPrObject::createValueElement(tagPRESNUM, appearStep, doc));
286 if(angle!=0.0) {
287 elem=doc.createElement(tagANGLE);
288 elem.setAttribute(attrValue, angle);
289 fragment.appendChild(elem);
290 }
291 if(effect3!=EF3_NONE || disappear) {
292 elem=doc.createElement(tagDISAPPEAR);
293 elem.setAttribute(attrEffect, static_cast<int>( effect3 ));
294 elem.setAttribute(attrDoit, static_cast<int>( disappear ));
295 elem.setAttribute( "speed", static_cast<int>(m_disappearSpeed) );
296 elem.setAttribute(attrNum, disappearStep);
297 fragment.appendChild(elem);
298 }
299 if(appearTimer!=1 || disappearTimer!=1) {
300 elem=doc.createElement("TIMER");
301 elem.setAttribute("appearTimer", appearTimer);
302 elem.setAttribute("disappearTimer", disappearTimer);
303 fragment.appendChild(elem);
304 }
305 if(appearSoundEffect || !a_fileName.isEmpty()) {
306 elem=doc.createElement("APPEARSOUNDEFFECT");
307 elem.setAttribute("appearSoundEffect", static_cast<int>(appearSoundEffect));
308 elem.setAttribute("appearSoundFileName", a_fileName);
309 fragment.appendChild(elem);
310 }
311 if(disappearSoundEffect || !d_fileName.isEmpty()) {
312 elem=doc.createElement("DISAPPEARSOUNDEFFECT");
313 elem.setAttribute("disappearSoundEffect", static_cast<int>(disappearSoundEffect));
314 elem.setAttribute("disappearSoundFileName", d_fileName);
315 fragment.appendChild(elem);
316 }
317 if( !objectName.isEmpty() ) {
318 elem=doc.createElement("OBJECTNAME");
319 elem.setAttribute("objectName", objectName);
320 fragment.appendChild(elem);
321 }
322 if(protect) {
323 elem=doc.createElement("PROTECT");
324 elem.setAttribute("state" , protect);
325 fragment.appendChild(elem);
326 }
327 if(keepRatio) {
328 elem=doc.createElement("RATIO");
329 elem.setAttribute("ratio" , keepRatio);
330 fragment.appendChild(elem);
331 }
332
333 return fragment;
334}
335
336
337void KPrObject::saveOasisPosObject( KoXmlWriter &xmlWriter, int indexObj ) const
338{
339 xmlWriter.addAttribute( "draw:id", "object" + TQString::number( indexObj ) );
340 //save all into pt
341 xmlWriter.addAttributePt( "svg:width", ext.width() );
342 xmlWriter.addAttributePt( "svg:height", ext.height() );
343
344 if ( kAbs( angle ) > 1E-6 )
345 {
346 double angInRad = -angle * M_PI / 180.0;
347 TQWMatrix m( cos( angInRad ), -sin( angInRad ), sin( angInRad ), cos( angInRad ), 0, 0 );
348 KoPoint center( ext.width() / 2, ext.height() / 2 );
349 double rotX = 0.0;
350 double rotY = 0.0;
351 m.map( center.x(), center.y(), &rotX, &rotY );
352 KoPoint rot( rotX, rotY );
353 KoPoint trans( center - rot + orig );
354
355 TQCString transX;
356 transX.setNum( trans.x(), 'g', DBL_DIG );
357 TQCString transY;
358 transY.setNum( trans.y(), 'g', DBL_DIG );
359 TQString str = TQString( "rotate(%1) translate(%2pt %3pt)" ).arg( angInRad ).arg( transX.data() ).arg( transY.data() );
360 xmlWriter.addAttribute( "draw:transform", str );
361 }
362 else
363 {
364 xmlWriter.addAttributePt( "svg:x", orig.x() );
365 xmlWriter.addAttributePt( "svg:y", orig.y() );
366 }
367}
368
369void KPrObject::saveOasisObjectProtectStyle( KoGenStyle &styleobjectauto ) const
370{
371 if ( protect )
372 {
373 styleobjectauto.addProperty( "draw:move-protect", "true" );
374 styleobjectauto.addProperty( "draw:size-protect", "true" );
375 }
376}
377
378TQString KPrObject::getStyle( KPOasisSaveContext &sc ) const
379{
380 kdDebug(33001) << "KPrObject::getStyle" << endl;
381 KoGenStyle styleObjectAuto;
382 KoGenStyles &mainStyles( sc.context.mainStyles() );
383 if ( sc.onMaster )
384 {
385 styleObjectAuto = KoGenStyle( KPrDocument::STYLE_PRESENTATIONSTICKYOBJECT, "presentation" );
386 }
387 else
388 {
389 styleObjectAuto = KoGenStyle( KoGenStyle::STYLE_GRAPHICAUTO, "graphic" );
390 }
391 fillStyle( styleObjectAuto, mainStyles );
392 if ( sc.onMaster )
393 {
394 return mainStyles.lookup( styleObjectAuto, "pr" );
395 }
396 return mainStyles.lookup( styleObjectAuto, "gr" );
397}
398
399void KPrObject::fillStyle( KoGenStyle& styleObjectAuto, KoGenStyles& /* mainStyles */ ) const
400{
401 kdDebug(33001) << "KPrObject::fillStyle" << endl;
402 saveOasisObjectProtectStyle( styleObjectAuto );
403 saveOasisShadowElement( styleObjectAuto );
404}
405
406bool KPrObject::saveOasisObjectAttributes( KPOasisSaveContext &/* sc */ ) const
407{
408 kdDebug()<<"bool saveOasisObjectAttributes not implemented";
409 return true;
410}
411
412bool KPrObject::hasAnimation() const
413{
414 return effect != EF_NONE || appearTimer != 0 ||
415 effect3 != EF3_NONE || disappear ||
416 !a_fileName.isEmpty() || ! d_fileName.isEmpty() ||
417 appearTimer != 1;
418}
419
420bool KPrObject::saveOasisObjectStyleShowAnimation( KoXmlWriter &animation, int objectId )
421{
422 if ( effect != EF_NONE || appearStep != 0 || !a_fileName.isEmpty() )
423 {
424 animation.startElement( "presentation:show-shape" );
425 animation.addAttribute( "draw:shape-id", "object" + TQString::number( objectId ) );
426 animation.addAttribute( "koffice:order-id", appearStep );
427
428 switch( effect )
429 {
430 case EF_NONE:
431 // use appear instead none as oo understands this
432 animation.addAttribute( "presentation:effect", "appear" );
433 break;
434 case EF_COME_RIGHT:
435 animation.addAttribute( "presentation:effect", "move" );
436 animation.addAttribute( "presentation:direction", "from-right" );
437 break;
438 case EF_COME_LEFT:
439 animation.addAttribute( "presentation:effect", "move" );
440 animation.addAttribute( "presentation:direction", "from-left" );
441 break;
442 case EF_COME_TOP:
443 animation.addAttribute( "presentation:effect", "move" );
444 animation.addAttribute( "presentation:direction", "from-top" );
445 break;
446 case EF_COME_BOTTOM:
447 animation.addAttribute( "presentation:effect", "move" );
448 animation.addAttribute( "presentation:direction", "from-bottom" );
449 break;
450 case EF_COME_RIGHT_TOP:
451 animation.addAttribute( "presentation:effect", "move" );
452 animation.addAttribute( "presentation:direction", "from-upper-right" );
453 break;
454 case EF_COME_RIGHT_BOTTOM:
455 animation.addAttribute( "presentation:effect", "move" );
456 animation.addAttribute( "presentation:direction", "from-lower-right" );
457 break;
458 case EF_COME_LEFT_TOP:
459 animation.addAttribute( "presentation:effect", "move" );
460 animation.addAttribute( "presentation:direction", "from-upper-left" );
461 break;
462 case EF_COME_LEFT_BOTTOM:
463 animation.addAttribute( "presentation:effect", "move" );
464 animation.addAttribute( "presentation:direction", "from-lower-left" );
465 break;
466 case EF_WIPE_LEFT:
467 animation.addAttribute( "presentation:effect", "fade" );
468 animation.addAttribute( "presentation:direction", "from-left" );
469 break;
470 case EF_WIPE_RIGHT:
471 animation.addAttribute( "presentation:effect", "fade" );
472 animation.addAttribute( "presentation:direction", "from-right" );
473 break;
474 case EF_WIPE_TOP:
475 animation.addAttribute( "presentation:effect", "fade" );
476 animation.addAttribute( "presentation:direction", "from-top" );
477 break;
478 case EF_WIPE_BOTTOM:
479 animation.addAttribute( "presentation:effect", "fade" );
480 animation.addAttribute( "presentation:direction", "from-bottom" );
481 break;
482 }
483
484 if ( effect2 != EF2_NONE )
485 {
486 animation.addAttribute( "koffice:by-paragraph", "true" );
487 }
488
489 if ( m_appearSpeed == ES_SLOW )
490 {
491 animation.addAttribute( "presentation:speed", "slow" );
492 }
493 else if ( m_appearSpeed == ES_FAST )
494 {
495 animation.addAttribute( "presentation:speed", "fast" );
496 }
497
498 if ( appearTimer!=1 )
499 {
500 animation.addAttribute( "presentation:animation-delay", saveOasisTimer( appearTimer ) );
501 }
502 if( !a_fileName.isEmpty() )
503 {
504 //store sound into file ?
505 //<presentation:sound xlink:href="../../usr/lib/openoffice/share/gallery/sounds/pluck.wav" xlink:type="simple" xlink:show="new" xlink:actuate="onRequest"/>
506 animation.startElement( "presentation:sound" );
507 animation.addAttribute( "xlink:href", a_fileName );
508 animation.addAttribute( "xlink:type", "simple" );
509 animation.addAttribute( "xlink:show", "new" );
510 animation.addAttribute( "xlink:actuate", "onRequest" );
511 animation.endElement();
512 }
513 animation.endElement();
514 }
515 return true;
516}
517
518bool KPrObject::saveOasisObjectStyleHideAnimation( KoXmlWriter &animation, int objectId )
519{
520
521 //FIXME oo doesn't support hide animation object
522 if ( effect3 != EF3_NONE || disappearStep != 0 || !d_fileName.isEmpty())
523 {
524 animation.startElement( "presentation:hide-shape" );
525 animation.addAttribute( "draw:shape-id", "object" + TQString::number( objectId ) );
526 animation.addAttribute( "koffice:order-id", disappearStep );
527 switch( effect3 )
528 {
529 case EF3_NONE:
530 // use hide instead none as oo understands this
531 animation.addAttribute( "presentation:effect", "hide" );
532 break;
533 case EF3_GO_RIGHT:
534 animation.addAttribute( "presentation:effect", "move" );
535 animation.addAttribute( "presentation:direction", "from-right" );
536 break;
537 case EF3_GO_LEFT:
538 animation.addAttribute( "presentation:effect", "move" );
539 animation.addAttribute( "presentation:direction", "from-left" );
540 break;
541 case EF3_GO_TOP:
542 animation.addAttribute( "presentation:effect", "move" );
543 animation.addAttribute( "presentation:direction", "from-top" );
544 break;
545 case EF3_GO_BOTTOM:
546 animation.addAttribute( "presentation:effect", "move" );
547 animation.addAttribute( "presentation:direction", "from-bottom" );
548 break;
549 case EF3_GO_RIGHT_TOP:
550 animation.addAttribute( "presentation:effect", "move" );
551 animation.addAttribute( "presentation:direction", "from-upper-right" );
552 break;
553 case EF3_GO_RIGHT_BOTTOM:
554 animation.addAttribute( "presentation:effect", "move" );
555 animation.addAttribute( "presentation:direction", "from-lower-right" );
556 break;
557 case EF3_GO_LEFT_TOP:
558 animation.addAttribute( "presentation:effect", "move" );
559 animation.addAttribute( "presentation:direction", "from-upper-left" );
560 break;
561 case EF3_GO_LEFT_BOTTOM:
562 animation.addAttribute( "presentation:effect", "move" );
563 animation.addAttribute( "presentation:direction", "from-lower-left" );
564 break;
565 case EF3_WIPE_LEFT:
566 animation.addAttribute( "presentation:effect", "fade" );
567 animation.addAttribute( "presentation:direction", "from-left" );
568 break;
569 case EF3_WIPE_RIGHT:
570 animation.addAttribute( "presentation:effect", "fade" );
571 animation.addAttribute( "presentation:direction", "from-right" );
572 break;
573 case EF3_WIPE_TOP:
574 animation.addAttribute( "presentation:effect", "fade" );
575 animation.addAttribute( "presentation:direction", "from-top" );
576 break;
577 case EF3_WIPE_BOTTOM:
578 animation.addAttribute( "presentation:effect", "fade" );
579 animation.addAttribute( "presentation:direction", "from-bottom" );
580 break;
581 }
582
583 if ( m_disappearSpeed == ES_SLOW )
584 {
585 animation.addAttribute( "presentation:speed", "slow" );
586 }
587 else if ( m_disappearSpeed == ES_FAST )
588 {
589 animation.addAttribute( "presentation:speed", "fast" );
590 }
591
592 if ( disappearTimer!=1 )
593 {
594 animation.addAttribute( "presentation:animation-delay", saveOasisTimer( disappearTimer ) );
595 }
596 if( !d_fileName.isEmpty() )
597 {
598 //store sound into file ?
599 //<presentation:sound xlink:href="../../usr/lib/openoffice/share/gallery/sounds/pluck.wav" xlink:type="simple" xlink:show="new" xlink:actuate="onRequest"/>
600 animation.startElement( "presentation:sound" );
601 animation.addAttribute( "xlink:href", a_fileName );
602 animation.addAttribute( "xlink:type", "simple" );
603 animation.addAttribute( "xlink:show", "new" );
604 animation.addAttribute( "xlink:actuate", "onRequest" );
605
606 animation.endElement();
607 }
608 animation.endElement();
609 }
610 return true;
611}
612
613void KPrObject::loadOasis(const TQDomElement &element, KoOasisContext & context, KPrLoadingInfo *info)
614{
615 if(element.hasAttributeNS( KoXmlNS::draw, "name" ))
616 objectName = element.attributeNS( KoXmlNS::draw, "name", TQString());
617 orig.setX( KoUnit::parseValue( element.attributeNS( KoXmlNS::svg, "x", TQString() ) ) );
618 orig.setY( KoUnit::parseValue( element.attributeNS( KoXmlNS::svg, "y", TQString() ) ) );
619 ext.setWidth(KoUnit::parseValue( element.attributeNS( KoXmlNS::svg, "width", TQString() )) );
620 ext.setHeight(KoUnit::parseValue( element.attributeNS( KoXmlNS::svg, "height", TQString() ) ) );
621 //kdDebug()<<" orig.x() :"<<orig.x() <<" orig.y() :"<<orig.y() <<"ext.width() :"<<ext.width()<<" ext.height(): "<<ext.height()<<endl;
622 KoStyleStack &styleStack = context.styleStack();
623 styleStack.setTypeProperties( "" ); //no type default type
624 if ( element.hasAttributeNS( KoXmlNS::draw, "transform" ) )
625 {
626 // there is some more stuff in the spezification
627 // TODO make it work for all cases
628 TQString transform = element.attributeNS( KoXmlNS::draw, "transform", TQString() );
629 kdDebug()<<" transform action :"<<transform<<endl;
630 TQRegExp rx( "rotate ?\\(([^)]+)\\) translate ?\\(([^ ]+) ([^)]+)\\)" );
631 if ( rx.search( transform ) != - 1 && rx.numCaptures() == 3 )
632 {
633 bool ok = false;
634 double angInRad = rx.cap( 1 ).toDouble( &ok );
635 if( ok )
636 {
637 angle = -angInRad * 180.0 / M_PI;
638 }
639 else
640 {
641 angle = 0.0;
642 angInRad = 0.0;
643 }
644 TQWMatrix m( cos( angInRad ), -sin( angInRad ), sin( angInRad ), cos( angInRad ), 0, 0 );
645 KoPoint center( ext.width() / 2, ext.height() / 2 );
646 double transX = 0.0;
647 double transY = 0.0;
648 m.map( center.x(), center.y(), &transX, &transY );
649 KoPoint diff( transX, transY );
650 KoPoint trans( KoUnit::parseValue( rx.cap( 2 ) ), KoUnit::parseValue( rx.cap( 3 ) ) );
651 orig = trans - center + diff;
652 kdDebug(33001) << "trans = " << trans << ", center = " << center << ", diff = " << diff << ", orig = " << orig << endl;
653 }
654 }
655 TQDomElement *animation = 0L;
656 lstAnimation *tmp = 0L;
657 if( element.hasAttributeNS( KoXmlNS::draw, "id"))
658 {
659 tmp = info->animationShowById(element.attributeNS( KoXmlNS::draw, "id", TQString()) );
660 if ( tmp )
661 animation = tmp->element;
662 }
663
664 if( animation)
665 {
666 TQString effectStr = animation->attributeNS( KoXmlNS::presentation, "effect", TQString());
667 TQString dir = animation->attributeNS( KoXmlNS::presentation, "direction", TQString());
668 TQString speed = animation->attributeNS( KoXmlNS::presentation, "speed", TQString() );
669 appearStep = tmp->order;
670 kdDebug()<<" appear direction : "<<dir<<" effect :"<< effectStr <<" speed :"<<speed<<endl;
671
672 if ( speed =="medium" )
673 {
674 m_appearSpeed = ES_MEDIUM;
675 }
676 else if ( speed=="slow" )
677 {
678 m_appearSpeed = ES_SLOW;
679 }
680 else if ( speed=="fast" )
681 {
682 m_appearSpeed = ES_FAST;
683 }
684 else
685 kdDebug()<<" speed argument is not defined :"<<speed<<endl;
686
687 if ( animation->hasAttributeNS( KoXmlNS::presentation, "animation-delay" ) )
688 {
689 appearTimer = loadOasisTimer(animation->attributeNS( KoXmlNS::presentation, "animation-delay", TQString() ) );
690 }
691 if (effectStr=="fade")
692 {
693 if (dir=="from-right")
694 effect = EF_WIPE_RIGHT;
695 else if (dir=="from-left")
696 effect = EF_WIPE_LEFT;
697 else if (dir=="from-top")
698 effect= EF_WIPE_TOP;
699 else if (dir=="from-bottom")
700 effect = EF_WIPE_BOTTOM;
701 else
702 kdDebug(33001)<<" dir not supported: " << dir << endl;
703 }
704 else if (effectStr=="move")
705 {
706 if (dir=="from-right")
707 effect = EF_COME_RIGHT;
708 else if (dir=="from-left")
709 effect = EF_COME_LEFT;
710 else if (dir=="from-top")
711 effect = EF_COME_TOP;
712 else if (dir=="from-bottom")
713 effect = EF_COME_BOTTOM;
714 else if (dir=="from-upper-right")
715 effect = EF_COME_RIGHT_TOP;
716 else if (dir=="from-lower-right")
717 effect = EF_COME_RIGHT_BOTTOM;
718 else if (dir=="from-upper-left")
719 effect = EF_COME_LEFT_TOP;
720 else if (dir=="from-lower-left")
721 effect = EF_COME_LEFT_BOTTOM;
722 else
723 kdDebug(33001) << " dir not supported:" << dir << endl;
724 }
725 else if ( effectStr == "appear" )
726 {
727 effect = EF_NONE;
728 }
729 else
730 {
731 kdDebug(33001) << " appear effect not supported: " << effectStr << endl;
732 effect = EF_NONE;
733 }
734
735 TQString byParagaph = animation->attributeNS( KoXmlNS::koffice, "by-paragraph", TQString() );
736 if ( byParagaph == "true" )
737 {
738 effect2 = EF2T_PARA;
739 }
740
741 TQDomElement sound = KoDom::namedItemNS( *animation, KoXmlNS::presentation, "sound" );
742 if ( !sound.isNull() )
743 {
744 kdDebug()<<" object has sound effect \n";
745 if ( sound.hasAttributeNS( KoXmlNS::xlink, "href" ) )
746 {
747 a_fileName =sound.attributeNS( KoXmlNS::xlink, "href", TQString() );
748 appearSoundEffect = true;
749 }
750 }
751 }
752
753 animation = 0L;
754 tmp = 0L;
755 if( element.hasAttributeNS( KoXmlNS::draw, "id"))
756 {
757 tmp = info->animationHideById(element.attributeNS( KoXmlNS::draw, "id", TQString()) );
758 if ( tmp )
759 animation = tmp->element;
760 }
761
762 if( animation)
763 {
764 TQString effectStr = animation->attributeNS( KoXmlNS::presentation, "effect", TQString());
765 TQString dir = animation->attributeNS( KoXmlNS::presentation, "direction", TQString());
766 TQString speed = animation->attributeNS( KoXmlNS::presentation, "speed", TQString() );
767 kdDebug()<<" disappear direction : "<<dir<<" effect :"<< effectStr <<" speed :"<<speed<<endl;
768 disappearStep = tmp->order;
769
770 if ( speed =="medium" )
771 {
772 m_disappearSpeed = ES_MEDIUM;
773 }
774 else if ( speed=="slow" )
775 {
776 m_disappearSpeed = ES_SLOW;
777 }
778 else if ( speed=="fast" )
779 {
780 m_disappearSpeed = ES_FAST;
781 }
782 else
783 kdDebug()<<" speed argument is not defined :"<<speed<<endl;
784
785 if ( animation->hasAttributeNS( KoXmlNS::presentation, "animation-delay" ) )
786 {
787 disappearTimer = loadOasisTimer(animation->attributeNS( KoXmlNS::presentation, "animation-delay", TQString() ) );
788 }
789 if (effectStr=="fade")
790 {
791 if (dir=="from-right")
792 effect3 = EF3_WIPE_RIGHT;
793 else if (dir=="from-left")
794 effect3 = EF3_WIPE_LEFT;
795 else if (dir=="from-top")
796 effect3 = EF3_WIPE_TOP;
797 else if (dir=="from-bottom")
798 effect3 = EF3_WIPE_BOTTOM;
799 else
800 kdDebug(33001) << " dir not supported: " << dir << endl;
801 }
802 else if (effectStr=="move")
803 {
804 if (dir=="from-right")
805 effect3 = EF3_GO_RIGHT;
806 else if (dir=="from-left")
807 effect3 = EF3_GO_LEFT;
808 else if (dir=="from-top")
809 effect3 = EF3_GO_TOP;
810 else if (dir=="from-bottom")
811 effect3 = EF3_GO_BOTTOM;
812 else if (dir=="from-upper-right")
813 effect3 = EF3_GO_RIGHT_TOP;
814 else if (dir=="from-lower-right")
815 effect3 = EF3_GO_RIGHT_BOTTOM;
816 else if (dir=="from-upper-left")
817 effect3 = EF3_GO_LEFT_TOP;
818 else if (dir=="from-lower-left")
819 effect3 = EF3_GO_LEFT_BOTTOM;
820 else
821 kdDebug(33001) << " dir not supported: " << dir << endl;
822 }
823 else if ( effectStr == "hide" )
824 {
825 effect3 = EF3_NONE;
826 }
827 else
828 {
829 kdDebug(33001) << " hide effect not supported: " << effectStr << endl;
830 effect3 = EF3_NONE;
831 }
832
833 disappear = true;
834
835 TQDomElement sound = KoDom::namedItemNS( *animation, KoXmlNS::presentation, "sound" );
836 if ( !sound.isNull() )
837 {
838 kdDebug()<<" object has sound effect \n";
839 if ( sound.hasAttributeNS( KoXmlNS::xlink, "href" ) )
840 {
841 d_fileName =sound.attributeNS( KoXmlNS::xlink, "href", TQString() );
842 disappearSoundEffect = true;
843 }
844 }
845 }
846 //shadow
847#if 0 //move it to kptextobject
848 if ( !element.hasAttribute( "type" ) ||
849 ( element.hasAttribute( "type" ) && element.attribute( "type" ) == "4" ) )
850 {
851 kdDebug()<<" text document !!!!!\n";
852 if ( styleStack.hasAttributeNS( KoXmlNS::fo, "text-shadow" ) &&
853 styleStack.attributeNS( KoXmlNS::fo, "text-shadow" ) != "none" )
854 {
855 TQString distance = styleStack.attributeNS( KoXmlNS::fo, "text-shadow" );
856 distance.truncate( distance.find( ' ' ) );
857 shadowDistance = (int)KoUnit::parseValue( distance );
858 shadowDirection = SD_RIGHT_BOTTOM;
859 shadowColor= TQColor("#a0a0a0" );
860 }
861 }
862#endif
863
864// draw:textarea-horizontal-align="center" draw:textarea-vertical-align="middle" draw:shadow="visible" draw:move-protect="true" draw:size-protect="true"
865 //kpresenter doesn't have two attribute for protect move and protect size perhaps create two argument for 1.4
866 styleStack.setTypeProperties( "graphic" );
867 if ( styleStack.hasAttributeNS( KoXmlNS::draw, "move-protect" ) )
868 {
869 kdDebug()<<" styleStack.attribute(draw:move-protect ) :"<<styleStack.attributeNS( KoXmlNS::draw, "move-protect" )<<endl;
870 protect = ( styleStack.attributeNS( KoXmlNS::draw, "move-protect" ) == "true" );
871 }
872 if ( styleStack.hasAttributeNS( KoXmlNS::draw, "size-protect" ) )
873 {
874 kdDebug()<<" styleStack.attribute(draw:size-protect ) :"<<styleStack.attributeNS( KoXmlNS::draw, "size-protect" )<<endl;
875 protect = ( styleStack.attributeNS( KoXmlNS::draw, "size-protect" ) == "true" );
876 }
877
878 //not supported into kpresenter
879 if ( styleStack.hasAttributeNS( KoXmlNS::draw, "textarea-vertical-align" ) )
880 {
881 kdDebug()<<" styleStack.attribute(draw:textarea-vertical-align ) :"<<styleStack.attributeNS( KoXmlNS::draw, "textarea-vertical-align" )<<endl;
882 }
883 if ( styleStack.hasAttributeNS( KoXmlNS::draw, "textarea-horizontal-align") )
884 {
885 kdDebug()<<" styleStack.attribute(draw:textarea-horizontal-align ) :"<<styleStack.attributeNS( KoXmlNS::draw, "textarea-horizontal-align" )<<endl;
886 }
887 if ( styleStack.hasAttributeNS( KoXmlNS::draw, "shadow" ) &&
888 styleStack.attributeNS( KoXmlNS::draw, "shadow") == "visible" )
889 {
890 // use the shadow attribute to indicate an object-shadow
891 double x = KoUnit::parseValue( styleStack.attributeNS( KoXmlNS::draw, "shadow-offset-x" ) );
892 double y = KoUnit::parseValue( styleStack.attributeNS( KoXmlNS::draw, "shadow-offset-y" ) );
893 kdDebug()<<" shadow x : "<<x<<" shadow y :"<<y<<endl;
894 if ( x < 0 && y < 0 )
895 {
896 shadowDirection = SD_LEFT_UP;
897 shadowDistance = (int) fabs ( x );
898 }
899 else if ( x == 0 && y < 0 )
900 {
901 shadowDirection = SD_UP;
902 shadowDistance = (int) fabs ( y );
903 }
904 else if ( x > 0 && y < 0 )
905 {
906 shadowDirection = SD_RIGHT_UP;
907 shadowDistance = (int) fabs ( x );
908 }
909 else if ( x > 0 && y == 0 )
910 {
911 shadowDirection = SD_RIGHT;
912 shadowDistance = (int) fabs ( x );
913 }
914 else if ( x > 0 && y > 0 )
915 {
916 shadowDirection = SD_RIGHT_BOTTOM;
917 shadowDistance = (int) fabs ( x );
918 }
919 else if ( x == 0 && y > 0 )
920 {
921 shadowDirection = SD_BOTTOM;
922 shadowDistance = (int) fabs ( y );
923 }
924 else if ( x < 0 && y > 0 )
925 {
926 shadowDirection = SD_LEFT_BOTTOM;
927 shadowDistance = (int) fabs ( x );
928 }
929 else if ( x < 0 && y == 0 )
930 {
931 shadowDirection = SD_LEFT;
932 shadowDistance = (int) fabs ( x );
933 }
934 if ( styleStack.hasAttributeNS( KoXmlNS::draw, "shadow-color" ) )
935 shadowColor= TQColor(styleStack.attributeNS( KoXmlNS::draw, "shadow-color" ) );
936 kdDebug()<<" shadow color : "<<TQString(shadowColor.name())<<endl;
937 }
938}
939
940bool KPrObject::saveOasisObject( KPOasisSaveContext &sc ) const
941{
942 sc.xmlWriter.startElement( getOasisElementName() );
943 sc.xmlWriter.addAttribute( sc.onMaster ? "presentation:style-name": "draw:style-name", getStyle( sc ) );
944 saveOasisPosObject( sc.xmlWriter, sc.indexObj );
945 if( !objectName.isEmpty())
946 sc.xmlWriter.addAttribute( "draw:name", objectName );
947
948 saveOasisObjectAttributes( sc );
949
950 sc.xmlWriter.endElement();
951 return true;
952}
953
954void KPrObject::saveOasisShadowElement( KoGenStyle &styleobjectauto ) const
955{
956 //FIXME default value
957 if(shadowDistance!=0 || shadowDirection!=SD_RIGHT_BOTTOM || shadowColor!=TQt::gray) {
958 styleobjectauto.addProperty( "draw:shadow", "visible" );
959 switch( shadowDirection )
960 {
961 case SD_LEFT_UP:
962 styleobjectauto.addPropertyPt( "draw:shadow-offset-x", ( -1.0 * shadowDistance ) );
963 styleobjectauto.addPropertyPt( "draw:shadow-offset-y", ( -1.0 * shadowDistance ) );
964 break;
965 case SD_UP:
966 styleobjectauto.addPropertyPt( "draw:shadow-offset-x", 0.0 );
967 styleobjectauto.addPropertyPt( "draw:shadow-offset-y", ( -1.0 * shadowDistance ) );
968 break;
969 case SD_RIGHT_UP:
970 styleobjectauto.addPropertyPt( "draw:shadow-offset-x", shadowDistance );
971 styleobjectauto.addPropertyPt( "draw:shadow-offset-y", ( -1.0 * shadowDistance ) );
972 break;
973 case SD_RIGHT:
974 styleobjectauto.addPropertyPt( "draw:shadow-offset-x", shadowDistance );
975 styleobjectauto.addPropertyPt( "draw:shadow-offset-y", 0.0 );
976 break;
977 case SD_RIGHT_BOTTOM:
978 styleobjectauto.addPropertyPt( "draw:shadow-offset-x",shadowDistance );
979 styleobjectauto.addPropertyPt( "draw:shadow-offset-y", shadowDistance );
980 break;
981 case SD_BOTTOM:
982 styleobjectauto.addPropertyPt( "draw:shadow-offset-x", 0.0 );
983 styleobjectauto.addPropertyPt( "draw:shadow-offset-y",shadowDistance );
984 break;
985 case SD_LEFT_BOTTOM:
986 styleobjectauto.addPropertyPt( "draw:shadow-offset-x", ( -1.0*shadowDistance ) );
987 styleobjectauto.addPropertyPt( "draw:shadow-offset-y", shadowDistance );
988 break;
989 case SD_LEFT:
990 styleobjectauto.addPropertyPt( "draw:shadow-offset-x", ( -1.0 * shadowDistance ) );
991 styleobjectauto.addPropertyPt( "draw:shadow-offset-y", 0.0 );
992 break;
993 }
994 styleobjectauto.addProperty( "draw:shadow-color", shadowColor.name() );
995 }
996}
997
998double KPrObject::load(const TQDomElement &element) {
999
1000 double offset=-1.0;
1001 TQDomElement e=element.namedItem(tagORIG).toElement();
1002 if(!e.isNull()) {
1003 if(e.hasAttribute(attrX))
1004 orig.setX(e.attribute(attrX).toDouble());
1005 if(e.hasAttribute(attrY))
1006 {
1007 offset=e.attribute(attrY).toDouble();
1008 orig.setY(0);
1009 }
1010 }
1011 e=element.namedItem(tagSIZE).toElement();
1012 if(!e.isNull()) {
1013 if(e.hasAttribute(attrWidth))
1014 ext.setWidth(e.attribute(attrWidth).toDouble());
1015 if(e.hasAttribute(attrHeight))
1016 ext.setHeight(e.attribute(attrHeight).toDouble());
1017 }
1018 e=element.namedItem(tagSHADOW).toElement();
1019 if(!e.isNull()) {
1020 if(e.hasAttribute(attrDistance))
1021 shadowDistance=e.attribute(attrDistance).toInt();
1022 if(e.hasAttribute(attrDirection))
1023 shadowDirection=static_cast<ShadowDirection>(e.attribute(attrDirection).toInt());
1024 shadowColor=retrieveColor(e);
1025 }
1026 else {
1027 shadowDistance=0;
1028 shadowDirection=SD_RIGHT_BOTTOM;
1029 shadowColor=TQt::gray;
1030 }
1031 e=element.namedItem(tagEFFECTS).toElement();
1032 if(!e.isNull()) {
1033 if(e.hasAttribute(attrEffect))
1034 effect=static_cast<Effect>(e.attribute(attrEffect).toInt());
1035 if(e.hasAttribute(attrEffect2))
1036 effect2=static_cast<Effect2>(e.attribute(attrEffect2).toInt());
1037 if(e.hasAttribute("speed"))
1038 {
1039 m_appearSpeed=static_cast<EffectSpeed>(e.attribute("speed").toInt());
1040 // this is a safty net as we had once speeds up to ten
1041 m_appearSpeed = m_appearSpeed > ES_FAST ? ES_FAST : m_appearSpeed;
1042 }
1043 }
1044 else {
1045 effect=EF_NONE;
1046 effect2=EF2_NONE;
1047 }
1048 e=element.namedItem(tagANGLE).toElement();
1049 if(!e.isNull()) {
1050 if(e.hasAttribute(attrValue))
1051 angle=e.attribute(attrValue).toFloat();
1052 }
1053 else
1054 angle=0.0;
1055 e=element.namedItem(tagPRESNUM).toElement();
1056 if(!e.isNull()) {
1057 if(e.hasAttribute(attrValue))
1058 appearStep=e.attribute(attrValue).toInt();
1059 }
1060 else
1061 appearStep=0;
1062 e=element.namedItem(tagDISAPPEAR).toElement();
1063 if(!e.isNull()) {
1064 if(e.hasAttribute(attrEffect))
1065 effect3=static_cast<Effect3>(e.attribute(attrEffect).toInt());
1066 if(e.hasAttribute(attrDoit))
1067 disappear=static_cast<bool>(e.attribute(attrDoit).toInt());
1068 if(e.hasAttribute(attrNum))
1069 disappearStep=e.attribute(attrNum).toInt();
1070 if(e.hasAttribute("speed"))
1071 {
1072 m_disappearSpeed=static_cast<EffectSpeed>(e.attribute("speed").toInt());
1073 // this is a safty net as we had once speeds up to ten
1074 m_disappearSpeed = m_appearSpeed > ES_FAST ? ES_FAST : m_appearSpeed;
1075 }
1076 }
1077 else {
1078 effect3=EF3_NONE;
1079 disappear=false;
1080 disappearStep=1;
1081 }
1082 e=element.namedItem("TIMER").toElement();
1083 if(!e.isNull()) {
1084 if(e.hasAttribute("appearTimer"))
1085 appearTimer = e.attribute("appearTimer").toInt();
1086 if(e.hasAttribute("disappearTimer"))
1087 disappearTimer = e.attribute("disappearTimer").toInt();
1088 }
1089 else {
1090 appearTimer = 1;
1091 disappearTimer = 1;
1092 }
1093 e=element.namedItem("APPEARSOUNDEFFECT").toElement();
1094 if(!e.isNull()) {
1095 if(e.hasAttribute("appearSoundEffect"))
1096 appearSoundEffect = static_cast<bool>(e.attribute("appearSoundEffect").toInt());
1097 if(e.hasAttribute("appearSoundFileName"))
1098 a_fileName = e.attribute("appearSoundFileName");
1099 }
1100 else {
1101 appearSoundEffect = false;
1102 a_fileName = TQString();
1103 }
1104 e=element.namedItem("DISAPPEARSOUNDEFFECT").toElement();
1105 if(!e.isNull()) {
1106 if(e.hasAttribute("disappearSoundEffect"))
1107 disappearSoundEffect = static_cast<bool>(e.attribute("disappearSoundEffect").toInt());
1108 if(e.hasAttribute("disappearSoundFileName"))
1109 d_fileName = e.attribute("disappearSoundFileName");
1110 }
1111 else {
1112 disappearSoundEffect = false;
1113 d_fileName = TQString();
1114 }
1115 e=element.namedItem("OBJECTNAME").toElement();
1116 if(!e.isNull()) {
1117 if(e.hasAttribute("objectName"))
1118 objectName = e.attribute("objectName");
1119 }
1120 else {
1121 objectName = TQString();
1122 }
1123 e=element.namedItem("PROTECT").toElement();
1124 if (!e.isNull())
1125 {
1126 if(e.hasAttribute("state"))
1127 protect=static_cast<bool>(e.attribute("state").toInt());
1128 }
1129
1130 e=element.namedItem("RATIO").toElement();
1131 if (!e.isNull())
1132 {
1133 if(e.hasAttribute("ratio"))
1134 keepRatio=static_cast<bool>(e.attribute("ratio").toInt());
1135 }
1136
1137 return offset;
1138}
1139
1140KoSize KPrObject::getRealSize() const {
1141 KoSize size = ext;
1142
1143 if ( angle != 0.0 ) {
1144 float angInRad = angle * M_PI / 180;
1145 size.setWidth( ext.width() * fabs( cos( angInRad ) ) + ext.height() * fabs( sin( angInRad ) ) );
1146 size.setHeight( ext.width() * fabs( sin( angInRad ) ) + ext.height() * fabs( cos( angInRad ) ) );
1147 }
1148
1149 return size;
1150}
1151
1152KoPoint KPrObject::getRealOrig() const {
1153 KoPoint origin = orig;
1154
1155 if ( angle != 0.0 ) {
1156 KoSize dist( ( getRealSize() - ext ) / 2 );
1157 origin.setX( orig.x() - dist.width() );
1158 origin.setY( orig.y() - dist.height() );
1159 }
1160
1161 return origin;
1162}
1163
1164KoRect KPrObject::getRealRect() const {
1165 return KoRect( getRealOrig(), getRealSize() );
1166}
1167
1168KoRect KPrObject::getRepaintRect() const
1169{
1170 KoRect rect( getRealOrig(), getRealSize() );
1171
1172 if ( shadowDirection == SD_LEFT ||
1173 shadowDirection == SD_LEFT_UP ||
1174 shadowDirection == SD_LEFT_BOTTOM )
1175 {
1176 rect.setLeft( rect.left() - shadowDistance );
1177 }
1178 if ( shadowDirection == SD_UP ||
1179 shadowDirection == SD_LEFT_UP ||
1180 shadowDirection == SD_RIGHT_UP )
1181 {
1182 rect.setTop( rect.top() - shadowDistance );
1183 }
1184 if ( shadowDirection == SD_RIGHT ||
1185 shadowDirection == SD_RIGHT_UP ||
1186 shadowDirection == SD_RIGHT_BOTTOM )
1187 {
1188 rect.setRight( rect.right() + shadowDistance );
1189 }
1190 if ( shadowDirection == SD_BOTTOM ||
1191 shadowDirection == SD_LEFT_BOTTOM ||
1192 shadowDirection == SD_RIGHT_BOTTOM )
1193 {
1194 rect.setBottom( rect.bottom() + shadowDistance );
1195 }
1196
1197 if ( angle != 0.0 )
1198 {
1199 double _dx = rect.x() - 1.0;
1200 double _dy = rect.y() - 1.0;
1201 double _dw = rect.width() + 2.0;
1202 double _dh = rect.height() + 2.0;
1203 rect.setRect( _dx, _dy, _dw, _dh );
1204 }
1205
1206 return rect;
1207}
1208
1209void KPrObject::flip( bool /*horizontal*/ ) {
1210 // flip the angle
1211 if ( angle ) {
1212 angle = 360.0 - angle;
1213 }
1214}
1215
1216KoRect KPrObject::rotateRectObject() const
1217{
1218 KoRect br = KoRect( 0,0, ext.width(), ext.height() );
1219 double pw = br.width();
1220 double ph = br.height();
1221 KoRect rr = br;
1222 double yPos = -rr.y();
1223 double xPos = -rr.x();
1224 rr.moveTopLeft( KoPoint( -rr.width() / 2.0, -rr.height() / 2.0 ) );
1225 TQWMatrix m;
1226 m.translate( pw / 2.0, ph / 2.0 );
1227 m.rotate( angle );
1228 m.translate( rr.left() + xPos, rr.top() + yPos );
1229 KoRect r = KoRect::fromTQRect(m.mapRect( br.toTQRect() )); // see above TODO
1230 r.moveBy( orig.x() , orig.y() );
1231 return r;
1232}
1233
1234void KPrObject::rotateObject(TQPainter *paint,KoTextZoomHandler *_zoomHandler)
1235{
1236 KoRect rr = KoRect( 0, 0, ext.width(), ext.height() );
1237 rr.moveTopLeft( KoPoint( -ext.width() / 2.0, -ext.height() / 2.0 ) );
1238 TQWMatrix m;
1239 m.translate( _zoomHandler->zoomItX(ext.width() / 2.0), _zoomHandler->zoomItY(ext.height() / 2.0 ));
1240 m.rotate( angle );
1241 m.translate( _zoomHandler->zoomItX(rr.left()), _zoomHandler->zoomItY(rr.top()) );
1242
1243 paint->setWorldMatrix( m, true );
1244}
1245
1246bool KPrObject::contains( const KoPoint &point ) const
1247{
1248 return getRealRect().contains( point );
1249}
1250
1251bool KPrObject::intersects( const KoRect &rect ) const
1252{
1253 return getRealRect().intersects( rect );
1254}
1255
1256TQCursor KPrObject::getCursor( const KoPoint &_point, ModifyType &_modType,
1257 KPrDocument *doc ) const
1258{
1259 KoTextZoomHandler * zh = doc->zoomHandler();
1260 int px = zh->zoomItX(_point.x());
1261 int py = zh->zoomItY(_point.y());
1262
1263 TQRect rect = zh->zoomRect( getRealRect() );
1264 int ox = rect.left();
1265 int oy = rect.top();
1266 int ow = rect.width();
1267 int oh = rect.height();
1268
1269 bool headerFooter=doc->isHeaderFooter(this);
1270
1271 int sz = 4;
1272 if ( px >= ox && py >= oy && px <= ox + TQMIN( ow / 3, sz ) && py <= oy + TQMIN( oh / 3, sz ) )
1273 {
1274 _modType = MT_RESIZE_LU;
1275 if ( protect)
1276 return TQt::ForbiddenCursor;
1277 return TQt::sizeFDiagCursor;
1278 }
1279
1280 if ( px >= ox && py >= oy + oh / 2 - TQMIN( oh / 6, sz / 2 )
1281 && px <= ox + TQMIN( ow / 3, sz)
1282 && py <= oy + oh / 2 + TQMIN( oh / 6, sz / 2 ) )
1283 {
1284 _modType = MT_RESIZE_LF;
1285 if ( protect)
1286 return TQt::ForbiddenCursor;
1287 return TQt::sizeHorCursor;
1288 }
1289
1290 if ( px >= ox && py >= oy + oh - TQMIN( oh / 3, sz ) && px <= ox + TQMIN( ow / 3, sz ) && py <= oy + oh )
1291 {
1292 _modType = MT_RESIZE_LD;
1293 if ( protect)
1294 return TQt::ForbiddenCursor;
1295 return TQt::sizeBDiagCursor;
1296 }
1297
1298 if ( px >= ox + ow / 2 - TQMIN( ow / 6, sz / 2 ) && py >= oy
1299 && px <= ox + ow / 2 + TQMIN( ow / 6, sz / 2 )
1300 && py <= oy + TQMIN( oh / 3, sz ) )
1301 {
1302 _modType = MT_RESIZE_UP;
1303 if ( protect)
1304 return TQt::ForbiddenCursor;
1305 return TQt::sizeVerCursor;
1306 }
1307
1308 if ( px >= ox + ow / 2 - TQMIN( ow / 6, sz / 2 ) && py >= oy + oh - TQMIN( oh / 3, sz )
1309 && px <= ox + ow / 2 + TQMIN( ow / 6, sz / 2 ) && py <= oy + oh )
1310 {
1311 _modType = MT_RESIZE_DN;
1312 if ( protect)
1313 return TQt::ForbiddenCursor;
1314 return TQt::sizeVerCursor;
1315 }
1316
1317 if ( px >= ox + ow - TQMIN( ow / 3, sz ) && py >= oy && px <= ox + ow && py <= oy + TQMIN( oh / 3, sz) )
1318 {
1319 _modType = MT_RESIZE_RU;
1320 if ( protect)
1321 return TQt::ForbiddenCursor;
1322 return TQt::sizeBDiagCursor;
1323 }
1324
1325 if ( px >= ox + ow - TQMIN( ow / 3, sz ) && py >= oy + oh / 2 - TQMIN( oh / 6, sz / 2 )
1326 && px <= ox + ow && py <= oy + oh / 2 + TQMIN( oh / 6, sz / 2) )
1327 {
1328 _modType = MT_RESIZE_RT;
1329 if ( protect)
1330 return TQt::ForbiddenCursor;
1331 return TQt::sizeHorCursor;
1332 }
1333
1334 if ( px >= ox + ow - TQMIN( ow / 3, sz ) && py >= oy + oh - TQMIN( oh / 3, sz)
1335 && px <= ox + ow && py <= oy + oh )
1336 {
1337 _modType = MT_RESIZE_RD;
1338 if ( protect)
1339 return TQt::ForbiddenCursor;
1340 return TQt::sizeFDiagCursor;
1341 }
1342
1343 //header footer can't move
1344 if(!headerFooter)
1345 _modType = MT_MOVE;
1346 if ( protect )
1347 return TQt::ForbiddenCursor;
1348 else
1349 return TQt::sizeAllCursor;
1350}
1351
1352void KPrObject::getShadowCoords( double& _x, double& _y ) const
1353{
1354 double sx = 0, sy = 0;
1355
1356 switch ( shadowDirection )
1357 {
1358 case SD_LEFT_UP:
1359 {
1360 sx = _x - shadowDistance;
1361 sy = _y - shadowDistance;
1362 } break;
1363 case SD_UP:
1364 {
1365 sx = _x;
1366 sy = _y - shadowDistance;
1367 } break;
1368 case SD_RIGHT_UP:
1369 {
1370 sx = _x + shadowDistance;
1371 sy = _y - shadowDistance;
1372 } break;
1373 case SD_RIGHT:
1374 {
1375 sx = _x + shadowDistance;
1376 sy = _y;
1377 } break;
1378 case SD_RIGHT_BOTTOM:
1379 {
1380 sx = _x + shadowDistance;
1381 sy = _y + shadowDistance;
1382 } break;
1383 case SD_BOTTOM:
1384 {
1385 sx = _x;
1386 sy = _y + shadowDistance;
1387 } break;
1388 case SD_LEFT_BOTTOM:
1389 {
1390 sx = _x - shadowDistance;
1391 sy = _y + shadowDistance;
1392 } break;
1393 case SD_LEFT:
1394 {
1395 sx = _x - shadowDistance;
1396 sy = _y;
1397 } break;
1398 }
1399
1400 _x = sx; _y = sy;
1401}
1402
1403void KPrObject::paintSelection( TQPainter *_painter, KoTextZoomHandler *_zoomHandler, SelectionMode mode )
1404{
1405 if ( !selected || mode == SM_NONE )
1406 return;
1407
1408 _painter->save();
1409 _painter->translate( _zoomHandler->zoomItX(orig.x()), _zoomHandler->zoomItY(orig.y()) );
1410 _painter->setPen( TQPen( TQt::black, 1, TQPen::SolidLine ) );
1411 _painter->setBrush( kapp->palette().color( TQPalette::Active, TQColorGroup::Highlight ) );
1412
1413 KoRect r = getRealRect();
1414
1415 int x = _zoomHandler->zoomItX( r.left() - orig.x());
1416 int y = _zoomHandler->zoomItY( r.top() - orig.y());
1417 int zX6 = /*_zoomHandler->zoomItX(*/ 6 ;
1418 int zY6 = /*_zoomHandler->zoomItY(*/ 6 ;
1419 int w = _zoomHandler->zoomItX(r.width()) - 6;
1420 int h = _zoomHandler->zoomItY(r.height()) - 6;
1421
1422 if ( mode == SM_MOVERESIZE ) {
1423 _painter->drawRect( x, y, zX6, zY6 );
1424 _painter->drawRect( x, y + h / 2, zX6, zY6 );
1425 _painter->drawRect( x, y + h, zX6, zY6 );
1426 _painter->drawRect( x + w, y, zX6, zY6 );
1427 _painter->drawRect( x + w, y + h / 2, zX6, zY6 );
1428 _painter->drawRect( x + w, y + h, zX6, zY6 );
1429 _painter->drawRect( x + w / 2, y,zX6, zY6 );
1430 _painter->drawRect( x + w / 2, y + h, zX6, zY6 );
1431 }
1432 else if ( mode == SM_PROTECT) {
1433 _painter->drawRect( x, y, zX6, zY6 );
1434 _painter->drawRect( x, y + h / 2, zX6, zY6 );
1435 _painter->drawRect( x, y + h, zX6, zY6 );
1436 _painter->drawRect( x + w, y, zX6, zY6 );
1437 _painter->drawRect( x + w, y + h / 2, zX6, zY6 );
1438 _painter->drawRect( x + w, y + h, zX6, zY6 );
1439 _painter->drawRect( x + w / 2, y,zX6, zY6 );
1440 _painter->drawRect( x + w / 2, y + h, zX6, zY6 );
1441
1442 x= x + 1;
1443 y= y + 1;
1444 zX6=zX6-2;
1445 zY6=zY6-2;
1446
1447 TQBrush brush=kapp->palette().color( TQPalette::Active,TQColorGroup::Base );
1448 _painter->fillRect( x, y, zX6, zY6, brush );
1449 _painter->fillRect( x, y + h / 2, zX6, zY6, brush);
1450 _painter->fillRect( x, y + h, zX6, zY6, brush );
1451 _painter->fillRect( x + w, y, zX6, zY6, brush );
1452 _painter->fillRect( x + w, y + h / 2, zX6, zY6, brush );
1453 _painter->fillRect( x + w , y + h , zX6 , zY6 , brush );
1454 _painter->fillRect( x + w / 2 , y ,zX6 , zY6 , brush );
1455 _painter->fillRect( x + w / 2, y + h , zX6 , zY6 , brush );
1456 }
1457 else if ( mode == SM_ROTATE ) {
1458 _painter->drawEllipse( x, y, zX6, zY6 );
1459 _painter->drawEllipse( x, y + h, zX6, zY6 );
1460 _painter->drawEllipse( x + w, y, zX6, zY6 );
1461 _painter->drawEllipse( x + w, y + h, zX6, zY6 );
1462 }
1463
1464 _painter->restore();
1465}
1466
1467void KPrObject::doDelete()
1468{
1469 if ( cmds == 0 && !inObjList )
1470 delete this;
1471}
1472
1473DCOPObject* KPrObject::dcopObject()
1474{
1475 if ( !dcop )
1476 dcop = new KPrObjectIface( this );
1477
1478 return dcop;
1479}
1480
1481void KPrObject::setupClipRegion( TQPainter *painter, const TQRegion &clipRegion )
1482{
1483 TQRegion region = painter->clipRegion( TQPainter::CoordPainter );
1484 if ( region.isEmpty() )
1485 region = clipRegion;
1486 else
1487 region.unite( clipRegion );
1488
1489 painter->setClipRegion( region, TQPainter::CoordPainter );
1490}
1491
1492TQDomElement KPrObject::createValueElement(const TQString &tag, int value, TQDomDocument &doc) {
1493 TQDomElement elem=doc.createElement(tag);
1494 elem.setAttribute(attrValue, value);
1495 return elem;
1496}
1497
1498TQDomElement KPrObject::createGradientElement(const TQString &tag, const TQColor &c1, const TQColor &c2,
1499 int type, bool unbalanced, int xfactor,
1500 int yfactor, TQDomDocument &doc) {
1501 TQDomElement elem=doc.createElement(tag);
1502 elem.setAttribute(attrC1, c1.name());
1503 elem.setAttribute(attrC2, c2.name());
1504 elem.setAttribute(attrType, type);
1505 elem.setAttribute(attrUnbalanced, (uint)unbalanced);
1506 elem.setAttribute(attrXFactor, xfactor);
1507 elem.setAttribute(attrYFactor, yfactor);
1508 return elem;
1509}
1510
1511TQDomElement KPrObject::createPenElement(const TQString &tag, const KoPen &pen, TQDomDocument &doc) {
1512
1513 TQDomElement elem=doc.createElement(tag);
1514 elem.setAttribute(attrColor, pen.color().name());
1515 elem.setAttribute(attrWidth, pen.pointWidth());
1516 elem.setAttribute(attrStyle, static_cast<int>(pen.style()));
1517 return elem;
1518}
1519
1520KoPen KPrObject::toPen(const TQDomElement &element) const {
1521
1522 KoPen pen;
1523 pen.setColor(retrieveColor(element));
1524 if(element.hasAttribute(attrStyle))
1525 pen.setStyle(static_cast<TQt::PenStyle>(element.attribute(attrStyle).toInt()));
1526 if(element.hasAttribute(attrWidth))
1527 pen.setPointWidth(element.attribute(attrWidth).toDouble());
1528 return pen;
1529}
1530
1531TQDomElement KPrObject::createBrushElement(const TQString &tag, const TQBrush &brush, TQDomDocument &doc) {
1532
1533 TQDomElement elem=doc.createElement(tag);
1534 elem.setAttribute(attrColor, brush.color().name());
1535 elem.setAttribute(attrStyle, static_cast<int>(brush.style()));
1536 return elem;
1537}
1538
1539TQBrush KPrObject::toBrush(const TQDomElement &element) const {
1540
1541 TQBrush brush;
1542 brush.setColor(retrieveColor(element));
1543 if(element.hasAttribute(attrStyle))
1544 brush.setStyle(static_cast<TQt::BrushStyle>(element.attribute(attrStyle).toInt()));
1545 return brush;
1546}
1547
1548TQColor KPrObject::retrieveColor(const TQDomElement &element, const TQString &cattr,
1549 const TQString &rattr, const TQString &gattr, const TQString &battr) const {
1550 TQColor ret;
1551 if(element.hasAttribute(cattr))
1552 ret.setNamedColor(element.attribute(cattr));
1553 else {
1554 int red=0, green=0, blue=0;
1555 if(element.hasAttribute(rattr))
1556 red=element.attribute(rattr).toInt();
1557 if(element.hasAttribute(gattr))
1558 green=element.attribute(gattr).toInt();
1559 if(element.hasAttribute(battr))
1560 blue=element.attribute(battr).toInt();
1561 ret.setRgb(red, green, blue);
1562 }
1563 return ret;
1564}
1565
1566void KPrObject::draw( TQPainter *_painter, KoTextZoomHandler*_zoomHandler,
1567 int /*pageNum*/, SelectionMode selectionMode, bool drawContour )
1568{
1569 if ( selectionMode != SM_NONE && !drawContour )
1570 paintSelection( _painter, _zoomHandler, selectionMode );
1571}
1572
1573KoPen KPrObject::getPen() const
1574{
1575 // Return the default pen
1576 return KoPen();
1577}
1578
1579void KPrObject::getRealSizeAndOrigFromPoints( KoPointArray &points, float angle,
1580 KoSize &size, KoPoint &orig )
1581{
1582 if ( angle == 0 )
1583 return;
1584
1585 float angInRad = angle * M_PI / 180;
1586 float sinus = sin( angInRad );
1587 float cosinus = cos( angInRad );
1588
1589 float mid_x = size.width() / 2;
1590 float mid_y = size.height() / 2;
1591
1592 float min_x = 0;
1593 float max_x = 0;
1594 float min_y = 0;
1595 float max_y = 0;
1596 KoPointArray::ConstIterator it;
1597 for ( it = points.begin(); it != points.end(); ++it ) {
1598 KoPoint cord( mid_x - (*it).x(), (*it).y() - mid_y );
1599 float tmp_x = cord.x() * cosinus + cord.y() * sinus;
1600 float tmp_y = - cord.x() * sinus + cord.y() * cosinus;
1601
1602 if ( tmp_x < min_x ) {
1603 min_x = tmp_x;
1604 }
1605 else if ( tmp_x > max_x ) {
1606 max_x = tmp_x;
1607 }
1608
1609 if ( tmp_y < min_y ) {
1610 min_y = tmp_y;
1611 }
1612 else if ( tmp_y > max_y ) {
1613 max_y = tmp_y;
1614 }
1615 }
1616
1617 size.setWidth( max_x - min_x );
1618 size.setHeight( max_y - min_y );
1619
1620 orig.setX( orig.x() + mid_x - max_x );
1621 orig.setY( orig.y() + mid_y + min_y );
1622}
1623
1624void KPrObject::addSelfToGuides(TQValueList<double> &horizontalPos, TQValueList<double> &verticalPos )
1625{
1626 KoRect bounds = getRealRect();
1627
1628 horizontalPos.append( bounds.top() );
1629 verticalPos.append( bounds.left() );
1630 horizontalPos.append( bounds.bottom() );
1631 verticalPos.append( bounds.right() );
1632}
1633
1634KPrShadowObject::KPrShadowObject()
1635 : KPrObject()
1636{
1637}
1638
1639KPrShadowObject::KPrShadowObject( const KoPen &_pen )
1640 : KPrObject(), pen( _pen )
1641{
1642}
1643
1644KPrShadowObject &KPrShadowObject::operator=( const KPrShadowObject & )
1645{
1646 return *this;
1647}
1648
1649TQDomDocumentFragment KPrShadowObject::save( TQDomDocument& doc,double offset )
1650{
1651 TQDomDocumentFragment fragment=KPrObject::save(doc, offset);
1652
1653 if(pen!=defaultPen())
1654 fragment.appendChild(KPrObject::createPenElement(tagPEN, pen, doc));
1655 return fragment;
1656}
1657
1658void KPrShadowObject::saveOasisStrokeElement( KoGenStyles& mainStyles, KoGenStyle &styleobjectauto ) const
1659{
1660 switch( pen.style() )
1661 {
1662 case TQt::NoPen:
1663 styleobjectauto.addProperty( "draw:stroke" , "none" );
1664 break;
1665 case TQt::SolidLine:
1666 styleobjectauto.addProperty( "draw:stroke" , "solid" );
1667 break;
1668 case TQt::DashLine:
1669 case TQt::DotLine:
1670 case TQt::DashDotLine:
1671 case TQt::DashDotDotLine:
1672 styleobjectauto.addProperty( "draw:stroke" , "dash" );
1673 //TODO FIXME
1674 styleobjectauto.addProperty( "draw:stroke-dash", saveOasisStrokeStyle( mainStyles ) );
1675 break;
1676 default:
1677 break;
1678 }
1679 if ( pen.style() != TQt::NoPen )
1680 {
1681 styleobjectauto.addProperty( "svg:stroke-color", pen.color().name() );
1682 styleobjectauto.addPropertyPt( "svg:stroke-width", pen.pointWidth() );
1683 }
1684}
1685
1686TQString KPrShadowObject::saveOasisStrokeStyle( KoGenStyles& mainStyles ) const
1687{
1688 KoGenStyle stroke( KPrDocument::STYLE_STROKE /*, "graphic"*/ /*no name*/ );
1689 switch( pen.style() )
1690 {
1691 case TQt::NoPen:
1692 //nothing
1693 break;
1694 case TQt::SolidLine:
1695 //nothing
1696 break;
1697 case TQt::DashLine: //value from ooimpress filter
1698 stroke.addAttribute( "draw:style", "rect" );
1699 stroke.addAttribute( "draw:dots1", "1" );
1700 stroke.addAttribute( "draw:dots2", "1" );
1701 stroke.addAttribute( "draw:dots1-length", "0.508cm" );
1702 stroke.addAttribute( "draw:dots2-length", "0.508cm" );
1703 stroke.addAttribute( "draw:distance", "0.508cm" );
1704 break;
1705 case TQt::DotLine:
1706 stroke.addAttribute( "draw:style", "rect" );
1707 stroke.addAttribute( "draw:dots1", "1" );
1708 stroke.addAttribute( "draw:distance", "0.257cm" );
1709 break;
1710 case TQt::DashDotLine:
1711 stroke.addAttribute( "draw:style", "rect" );
1712 stroke.addAttribute( "draw:dots1", "1" );
1713 stroke.addAttribute( "draw:dots2", "1" );
1714 stroke.addAttribute( "draw:dots1-length", "0.051cm" );
1715 stroke.addAttribute( "draw:dots2-length", "0.254cm" );
1716 stroke.addAttribute( "draw:distance", "0.127cm" );
1717 break;
1718 case TQt::DashDotDotLine:
1719 stroke.addAttribute( "draw:style", "rect" );
1720 stroke.addAttribute( "draw:dots1", "2" );
1721 stroke.addAttribute( "draw:dots2", "1" );
1722 stroke.addAttribute( "draw:dots2-length", "0.203cm" );
1723 stroke.addAttribute( "draw:distance", "0.203cm" );
1724 break;
1725 default:
1726 break;
1727 }
1728 return mainStyles.lookup( stroke, "stroke" );
1729 // <draw:stroke-dash draw:name="Fine Dotted" draw:style="rect" draw:dots1="1" draw:distance="0.457cm"/>
1730}
1731
1732bool KPrShadowObject::saveOasisDrawPoints( const KoPointArray &points, KPOasisSaveContext &sc )
1733{
1734 TQString listOfPoint;
1735 int maxX=0;
1736 int maxY=0;
1737 KoPointArray::ConstIterator it( points.begin() );
1738 KoPointArray::ConstIterator end( points.end() );
1739 for ( ; it != end; ++it )
1740 {
1741 int tmpX = int( ( *it ).x() * 10000 );
1742 int tmpY = int( ( *it ).y() * 10000 );
1743 // no space allows before first element
1744 if ( !listOfPoint.isEmpty() )
1745 listOfPoint += TQString( " %1,%2" ).arg( tmpX ).arg( tmpY );
1746 else
1747 listOfPoint = TQString( "%1,%2" ).arg( tmpX ).arg( tmpY );
1748 maxX = TQMAX( maxX, tmpX );
1749 maxY = TQMAX( maxY, tmpY );
1750 }
1751 sc.xmlWriter.addAttribute("draw:points", listOfPoint );
1752 sc.xmlWriter.addAttribute("svg:viewBox", TQString( "0 0 %1 %2" ).arg( maxX ).arg( maxY ) );
1753 return true;
1754}
1755
1756bool KPrShadowObject::loadOasisDrawPoints( KoPointArray &points, const TQDomElement &element,
1757 KoOasisContext & context, KPrLoadingInfo *info )
1758{
1759 Q_UNUSED( context );
1760 Q_UNUSED( info );
1761 TQStringList ptList = TQStringList::split(' ', element.attributeNS( KoXmlNS::draw, "points", TQString()));
1762
1763 unsigned int index = 0;
1764 for (TQStringList::Iterator it = ptList.begin(); it != ptList.end(); ++it)
1765 {
1766 points.putPoints( index++, 1, ( *it ).section( ',', 0, 0 ).toInt(), ( *it ).section( ',', 1, 1 ).toInt() );
1767 }
1768 loadOasisApplyViewBox( element, points );
1769 return true;
1770}
1771
1772
1773bool KPrShadowObject::loadOasisApplyViewBox( const TQDomElement &element, KoPointArray &points )
1774{
1775 kdDebug(33001) << "loadOasisApplayViewBox svg:viewBox = " << element.attributeNS( KoXmlNS::svg, "viewBox", TQString() ) << endl;
1776 TQStringList viewBoxPoints = TQStringList::split( ' ', element.attributeNS( KoXmlNS::svg, "viewBox", TQString() ) );
1777
1778 KoRect viewBox;
1779 if ( viewBoxPoints.size() == 4 )
1780 {
1781 TQStringList::Iterator it = viewBoxPoints.begin();
1782 //viewBox.setCoords( ( *it++ ).toInt(), ( *it++ ).toInt(), ( *it++ ).toInt(), ( *it ).toInt() );
1783 viewBox.setLeft( ( *it++ ).toInt() );
1784 viewBox.setTop( ( *it++ ).toInt() );
1785 viewBox.setRight( ( *it++ ).toInt() );
1786 viewBox.setBottom( ( *it ).toInt() );
1787
1788 kdDebug(33001) << "viewBox supplied = " << viewBox << endl;
1789 }
1790 else
1791 {
1792 //if no viewBox is found
1793 KoPointArray::ConstIterator it( points.begin() );
1794 bool first = true;
1795 for ( ; it != points.end(); ++it )
1796 {
1797 KoPoint p = (*it);
1798 if ( first )
1799 {
1800 viewBox.setCoords( p.x(), p.y(), p.x(), p.y() );
1801 first = false;
1802 }
1803 else
1804 {
1805 viewBox.setLeft( TQMIN( viewBox.left(), p.x() ) );
1806 viewBox.setRight( TQMAX( viewBox.right(), p.x() ) );
1807 viewBox.setTop( TQMIN( viewBox.top(), p.y() ) );
1808 viewBox.setBottom( TQMAX( viewBox.bottom(), p.y() ) );
1809 }
1810 }
1811 kdDebug(33001) << "viewBox calculated = " << viewBox << endl;
1812 }
1813
1814 if ( viewBox.width() != 0 && viewBox.height() != 0 )
1815 {
1816 KoPointArray::Iterator it( points.begin() );
1817 for ( ; it != points.end(); ++it )
1818 {
1819 KoPoint *p = it;
1820 p->setX( ( p->x() - viewBox.left() ) / viewBox.width() * ext.width() );
1821 p->setY( ( p->y() - viewBox.top() ) / viewBox.height() * ext.height() );
1822 }
1823 }
1824 else
1825 {
1826 kdDebug(33001) << "problem in viewBox: " << viewBox << endl;
1827 }
1828 return true;
1829}
1830
1831
1832void KPrShadowObject::fillStyle( KoGenStyle& styleObjectAuto, KoGenStyles& mainStyles ) const
1833{
1834 kdDebug(33001) << "KPrShadowObject::fillStyle" << endl;
1835 KPrObject::fillStyle( styleObjectAuto, mainStyles );
1836 saveOasisStrokeElement( mainStyles, styleObjectAuto );
1837}
1838
1839void KPrShadowObject::loadOasis(const TQDomElement &element, KoOasisContext & context, KPrLoadingInfo *info)
1840{
1841 //kdDebug()<<"void KPrShadowObject::loadOasis(const TQDomElement &element)**********************\n";
1842 KPrObject::loadOasis(element, context, info);
1843 KoStyleStack &styleStack = context.styleStack();
1844 styleStack.setTypeProperties( "graphic" );
1845 if ( styleStack.hasAttributeNS( KoXmlNS::draw, "stroke" ))
1846 {
1847 if ( styleStack.attributeNS( KoXmlNS::draw, "stroke" ) == "none" )
1848 pen.setStyle(TQt::NoPen );
1849 else if ( styleStack.attributeNS( KoXmlNS::draw, "stroke" ) == "solid" )
1850 pen.setStyle(TQt::SolidLine );
1851 else if ( styleStack.attributeNS( KoXmlNS::draw, "stroke" ) == "dash" )
1852 {
1853 TQString style = styleStack.attributeNS( KoXmlNS::draw, "stroke-dash" );
1854
1855 kdDebug()<<" stroke style is : "<<style<<endl;
1856 //type not defined by default
1857 //try to use style.
1858 TQDomElement* draw = context.oasisStyles().drawStyles()[style];
1859 kdDebug()<<" stroke have oasis style defined :"<<draw<<endl;
1860 if ( draw )
1861 {
1862 //FIXME
1863 if ( draw->attributeNS( KoXmlNS::draw, "style", TQString() )=="rect" )
1864 {
1865 if ( draw->attributeNS( KoXmlNS::draw, "dots1", TQString() )=="1" &&
1866 draw->attributeNS( KoXmlNS::draw, "dots2", TQString() )=="1" &&
1867 draw->attributeNS( KoXmlNS::draw, "dots1-length", TQString() )=="0.508cm" &&
1868 draw->attributeNS( KoXmlNS::draw, "dots2-length", TQString() )=="0.508cm" &&
1869 draw->attributeNS( KoXmlNS::draw, "distance", TQString() )=="0.508cm" )
1870 pen.setStyle(TQt::DashLine );
1871 else if ( draw->attributeNS( KoXmlNS::draw, "dots1", TQString() )=="1" &&
1872 draw->attributeNS( KoXmlNS::draw, "distance", TQString() )=="0.257cm" )
1873 pen.setStyle(TQt::DotLine );
1874 else if ( draw->attributeNS( KoXmlNS::draw, "dots1", TQString() )=="1" &&
1875 draw->attributeNS( KoXmlNS::draw, "dots2", TQString() )=="1" &&
1876 draw->attributeNS( KoXmlNS::draw, "dots1-length", TQString() )=="0.051cm" &&
1877 draw->attributeNS( KoXmlNS::draw, "dots2-length", TQString() )=="0.254cm" &&
1878 draw->attributeNS( KoXmlNS::draw, "distance", TQString() )=="0.127cm" )
1879 pen.setStyle(TQt::DashDotLine );
1880 else if ( draw->attributeNS( KoXmlNS::draw, "dots1", TQString() )=="2" &&
1881 draw->attributeNS( KoXmlNS::draw, "dots2", TQString() )=="1" &&
1882 draw->attributeNS( KoXmlNS::draw, "dots2-length", TQString() )=="0.203cm" &&
1883 draw->attributeNS( KoXmlNS::draw, "distance", TQString() )=="0.203cm" )
1884 pen.setStyle(TQt::DashDotDotLine );
1885 else
1886 {
1887 kdDebug()<<" stroke style undefined \n";
1888 pen.setStyle(TQt::SolidLine );
1889 }
1890
1891 }
1892 }
1893 }
1894 //FIXME witdh pen style is not good :(
1895 if ( styleStack.hasAttributeNS( KoXmlNS::svg, "stroke-width" ) )
1896 pen.setPointWidth( KoUnit::parseValue( styleStack.attributeNS( KoXmlNS::svg, "stroke-width" ) ) );
1897 if ( styleStack.hasAttributeNS( KoXmlNS::svg, "stroke-color" ) )
1898 pen.setColor( styleStack.attributeNS( KoXmlNS::svg, "stroke-color" ) );
1899 }
1900 else
1901 pen = defaultPen();
1902 kdDebug()<<"pen style :"<<pen<<endl;
1903}
1904
1905double KPrShadowObject::load(const TQDomElement &element)
1906{
1907 double offset=KPrObject::load(element);
1908 TQDomElement e=element.namedItem(tagPEN).toElement();
1909 if(!e.isNull())
1910 setPen(KPrObject::toPen(e));
1911 else
1912 pen = defaultPen();
1913 return offset;
1914}
1915
1916void KPrShadowObject::draw( TQPainter *_painter, KoTextZoomHandler*_zoomHandler,
1917 int pageNum, SelectionMode selectionMode, bool drawContour )
1918{
1919 double ox = orig.x();
1920 double oy = orig.y();
1921 _painter->save();
1922
1923 // Draw the shadow if any
1924 if ( shadowDistance > 0 && !drawContour )
1925 {
1926 _painter->save();
1927 // tz TODO fix tmpPen usage
1928 KoPen tmpPen( pen );
1929 pen.setColor( shadowColor );
1930 TQBrush brush;
1931 brush.setColor( shadowColor );
1932
1933 double sx = ox;
1934 double sy = oy;
1935 getShadowCoords( sx, sy );
1936
1937 _painter->translate( _zoomHandler->zoomItX( sx ), _zoomHandler->zoomItY( sy ) );
1938
1939 if ( angle != 0 )
1940 {
1941 rotateObject( _painter, _zoomHandler );
1942 }
1943
1944 paint( _painter, _zoomHandler, pageNum, true, drawContour );
1945
1946 pen = tmpPen;
1947 _painter->restore();
1948 }
1949
1950 _painter->translate( _zoomHandler->zoomItX(ox), _zoomHandler->zoomItY(oy) );
1951
1952 if ( angle != 0 )
1953 rotateObject(_painter,_zoomHandler);
1954 paint( _painter, _zoomHandler, pageNum, false, drawContour );
1955
1956 _painter->restore();
1957
1958 KPrObject::draw( _painter, _zoomHandler, pageNum, selectionMode, drawContour );
1959}
1960
1962{
1963 return KoPen();
1964}
1965
1966void KPrShadowObject::paint(TQPainter* painter, KoTextZoomHandler* zoomHandler, int pageNum, bool drawingShadow, bool drawContour) {
1967 Q_UNUSED(painter);
1968 Q_UNUSED(zoomHandler);
1969 Q_UNUSED(pageNum);
1970 Q_UNUSED(drawingShadow);
1971 Q_UNUSED(drawContour);
1972}
1973
1974KPr2DObject::KPr2DObject()
1975 : KPrShadowObject()
1976 , gradient( 0 )
1977 , m_redrawGradientPix( false )
1978{
1979}
1980
1981KPr2DObject::KPr2DObject( const KoPen &_pen, const TQBrush &_brush, FillType _fillType,
1982 const TQColor &_gColor1, const TQColor &_gColor2, BCType _gType,
1983 bool _unbalanced, int _xfactor, int _yfactor )
1984 : KPrShadowObject( _pen )
1985 , m_brush( _brush, _gColor1, _gColor2, _gType, _fillType, _unbalanced, _xfactor, _yfactor )
1986 , gradient( 0 )
1987 , m_redrawGradientPix( false )
1988{
1989 if ( getFillType() == FT_GRADIENT )
1990 {
1991 gradient = new KPrGradient( getGColor1(), getGColor2(),
1992 getGType(), getGUnbalanced(),
1993 getGXFactor(), getGYFactor() );
1994 m_redrawGradientPix = true;
1995 }
1996}
1997
1998void KPr2DObject::setFillType( FillType _fillType )
1999{
2000 m_brush.setFillType( _fillType );
2001
2002 if ( _fillType == FT_BRUSH && gradient )
2003 {
2004 delete gradient;
2005 gradient = 0;
2006 }
2007 if ( _fillType == FT_GRADIENT && !gradient )
2008 {
2009 gradient = new KPrGradient( getGColor1(), getGColor2(),
2010 getGType(), getGUnbalanced(),
2011 getGXFactor(), getGYFactor() );
2012 m_redrawGradientPix = true;
2013 }
2014}
2015
2016TQDomDocumentFragment KPr2DObject::save( TQDomDocument& doc,double offset )
2017{
2018 TQDomDocumentFragment fragment=KPrShadowObject::save(doc, offset);
2019 TQBrush brush = getBrush();
2020 if ( brush != TQBrush() )
2021 fragment.appendChild( KPrObject::createBrushElement( tagBRUSH, brush, doc ) );
2022
2023 FillType fillType = getFillType();
2024 if ( fillType != FT_BRUSH )
2025 fragment.appendChild( KPrObject::createValueElement( tagFILLTYPE, static_cast<int>(fillType), doc ) );
2026 TQColor gColor1 = getGColor1();
2027 TQColor gColor2 = getGColor2();
2028 BCType gType = getGType();
2029 bool unbalanced = getGUnbalanced();
2030 int xfactor = getGXFactor();
2031 int yfactor = getGYFactor();
2032 if ( gColor1!=TQt::red || gColor2!=TQt::green || gType!=BCT_GHORZ || unbalanced || xfactor != 100 || yfactor != 100 )
2033 fragment.appendChild( KPrObject::createGradientElement( tagGRADIENT, gColor1, gColor2, static_cast<int>(gType),
2034 unbalanced, xfactor, yfactor, doc));
2035 return fragment;
2036}
2037
2038void KPr2DObject::fillStyle( KoGenStyle& styleObjectAuto, KoGenStyles& mainStyles ) const
2039{
2040 kdDebug(33001) << "KPr2DObject::fillStyle" << endl;
2041 KPrShadowObject::fillStyle( styleObjectAuto, mainStyles );
2042 m_brush.saveOasisFillStyle( styleObjectAuto, mainStyles );
2043}
2044
2045
2046void KPr2DObject::loadOasis(const TQDomElement &element, KoOasisContext & context, KPrLoadingInfo *info)
2047{
2048 kdDebug()<<"void KPr2DObject::loadOasis(const TQDomElement &element)\n";
2049 TQBrush tmpBrush;
2050
2051 KPrShadowObject::loadOasis(element, context, info);
2052 m_brush.loadOasisFillStyle( context, "graphic" );
2053 setFillType( m_brush.getFillType() );
2054}
2055
2056double KPr2DObject::load(const TQDomElement &element)
2057{
2058 double offset=KPrShadowObject::load(element);
2059
2060 TQDomElement e=element.namedItem(tagFILLTYPE).toElement();
2061 if(!e.isNull()) {
2062 if(e.hasAttribute(attrValue))
2063 setFillType(static_cast<FillType>(e.attribute(attrValue).toInt()));
2064 }
2065 else
2066 setFillType(FT_BRUSH);
2067
2068 e=element.namedItem(tagBRUSH).toElement();
2069 if(!e.isNull())
2070 setBrush(KPrObject::toBrush(e));
2071 else
2072 setBrush( TQBrush() );
2073
2074 e=element.namedItem(tagGRADIENT).toElement();
2075 if(!e.isNull()) {
2076 setGColor1( retrieveColor( e, attrC1, "red1", "green1", "blue1" ) );
2077 setGColor2( retrieveColor( e, attrC2, "red2", "green2", "blue2" ) );
2078 if( e.hasAttribute( attrType ) )
2079 setGType( static_cast<BCType>( e.attribute( attrType ).toInt() ) );
2080 if( e.hasAttribute( attrUnbalanced ) )
2081 setGUnbalanced( static_cast<bool>( e.attribute( attrUnbalanced ).toInt() ) );
2082 if( e.hasAttribute( attrXFactor ) )
2083 setGXFactor( e.attribute( attrXFactor ).toInt() );
2084 if( e.hasAttribute( attrYFactor ) )
2085 setGYFactor( e.attribute( attrYFactor ).toInt() );
2086 if(gradient)
2087 gradient->setParameters(getGColor1(), getGColor2(), getGType(), getGUnbalanced(), getGXFactor(), getGYFactor() );
2088 }
2089 else {
2090 setGColor1( TQt::red );
2091 setGColor2( TQt::green );
2092 setGType( BCT_GHORZ );
2093 setGUnbalanced( false );
2094 setGXFactor( 100 );
2095 setGYFactor( 100 );
2096 }
2097 return offset;
2098}
2099
2100void KPr2DObject::draw( TQPainter *_painter, KoTextZoomHandler*_zoomHandler,
2101 int pageNum, SelectionMode selectionMode, bool drawContour )
2102{
2103 double ox = orig.x();
2104 double oy = orig.y();
2105 _painter->save();
2106
2107 // Draw the shadow if any
2108 if ( shadowDistance > 0 && !drawContour )
2109 {
2110 _painter->save();
2111 KoPen tmpPen( pen );
2112 pen.setColor( shadowColor );
2113 TQBrush tmpBrush( m_brush.getBrush() );
2114 TQBrush shadowBrush( tmpBrush );
2115 shadowBrush.setColor( shadowColor );
2116 m_brush.setBrush( shadowBrush );
2117
2118 double sx = ox;
2119 double sy = oy;
2120 getShadowCoords( sx, sy );
2121
2122 _painter->translate( _zoomHandler->zoomItX( sx ), _zoomHandler->zoomItY( sy ) );
2123
2124 if ( angle != 0 )
2125 {
2126 rotateObject( _painter, _zoomHandler );
2127 }
2128
2129 paint( _painter, _zoomHandler, pageNum, true, drawContour );
2130
2131 pen = tmpPen;
2132 m_brush.setBrush( tmpBrush );
2133 _painter->restore();
2134 }
2135
2136 _painter->translate( _zoomHandler->zoomItX(ox), _zoomHandler->zoomItY(oy) );
2137
2138 if ( angle != 0 )
2139 rotateObject(_painter,_zoomHandler);
2140 paint( _painter, _zoomHandler, pageNum, false, drawContour );
2141
2142 _painter->restore();
2143
2144 KPrObject::draw( _painter, _zoomHandler, pageNum, selectionMode, drawContour );
2145}
2146
2147void KPr2DObject::flip( bool horizontal ) {
2148 KPrObject::flip( horizontal );
2149
2150 // flip the gradient
2151 if ( getFillType() == FT_GRADIENT ) {
2152 BCType gType = getGType();
2153 if ( gType == BCT_GDIAGONAL1 ) {
2154 setGType( BCT_GDIAGONAL2 );
2155 }
2156 else if ( gType == BCT_GDIAGONAL2 ) {
2157 setGType( BCT_GDIAGONAL1 );
2158 }
2159 if ( ( ! horizontal && gType == BCT_GDIAGONAL1 ) ||
2160 ( ! horizontal && gType == BCT_GDIAGONAL2 ) ||
2161 ( ! horizontal && gType == BCT_GHORZ ) ||
2162 ( horizontal && gType == BCT_GVERT ) ) {
2163 TQColor gColorTemp;
2164 gColorTemp = getGColor1();
2165 setGColor1( getGColor2() );
2166 setGColor2( gColorTemp );
2167 }
2168 delete gradient;
2169 gradient = new KPrGradient( getGColor1(), getGColor2(), gType, getGUnbalanced(), getGXFactor(), getGYFactor() );
2170 }
2171}
Temporary information used only during loading.
Base class for objects with a pen and a brush, and which takes care of painting the shadow in draw() ...
Definition KPrObject.h:406
bool loadOasisDrawPoints(KoPointArray &points, const TQDomElement &element, KoOasisContext &context, KPrLoadingInfo *info)
Helper method for loading draw:points.
virtual KoPen defaultPen() const
save() only saves if the pen is different from the default pen.
virtual void paint(TQPainter *, KoTextZoomHandler *, int, bool drawingShadow, bool=false)
This method is to be implemented by all KPShadowObjects, to draw themselves.
bool loadOasisApplyViewBox(const TQDomElement &element, KoPointArray &points)
Apply the svg:viewBox attribute to the points.
static bool saveOasisDrawPoints(const KoPointArray &points, KPOasisSaveContext &sc)
Helper method for saving draw:points.