kpresenter

KPrGroupObject.cpp
1/* This file is part of the KDE project
2 Copyright (C) 1998, 1999 Reginald Stadlbauer <reggie@kde.org>
3 Copyright (C) 2005 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 "KPrGroupObject.h"
22
23#include "KPrDocument.h"
24#include "KPrLineObject.h"
25#include "KPrRectObject.h"
26#include "KPrEllipseObject.h"
27#include "KPrAutoformObject.h"
28#include "KPrTextObject.h"
29#include "KPrPixmapObject.h"
30#include "KPrPieObject.h"
31#include "KPrFreehandObject.h"
32#include "KPrPolylineObject.h"
33#include "KPrBezierCurveObject.h"
34#include "KPrPolygonObject.h"
35#include "KPrClosedLineObject.h"
36#include <kdebug.h>
37#include <KoOasisContext.h>
38
39#include <tqpainter.h>
40using namespace std;
41
42KPrGroupObject::KPrGroupObject()
43 : KPrObject(), objects( TQPtrList<KPrObject>() ), updateObjs( false )
44{
45 objects.setAutoDelete( false );
46}
47
48KPrGroupObject::KPrGroupObject( const TQPtrList<KPrObject> &objs )
49 : KPrObject(), objects( objs ), updateObjs( false )
50{
51 objects.setAutoDelete( false );
52}
53
54KPrGroupObject &KPrGroupObject::operator=( const KPrGroupObject & )
55{
56 return *this;
57}
58
59void KPrGroupObject::selectAllObj()
60{
61 TQPtrListIterator<KPrObject> it( objects );
62 for ( ; it.current() ; ++it )
63 it.current()->setSelected(true);
64}
65
66void KPrGroupObject::deSelectAllObj()
67{
68 TQPtrListIterator<KPrObject> it( objects );
69 for ( ; it.current() ; ++it )
70 it.current()->setSelected(false);
71}
72
73void KPrGroupObject::setSize( double _width, double _height )
74{
75 KoSize origSize( ext );
76 KPrObject::setSize( _width, _height );
77
78 double fx = ext.width() / origSize.width();
79 double fy = ext.height() / origSize.height();
80
81 updateSizes( fx, fy );
82}
83
84void KPrGroupObject::setOrig( const KoPoint &_point )
85{
86 setOrig( _point.x(), _point.y() );
87}
88
89void KPrGroupObject::setOrig( double _x, double _y )
90{
91 double dx = 0;
92 double dy = 0;
93 if ( !orig.isNull() ) {
94 dx = _x - orig.x();
95 dy = _y - orig.y();
96 }
97
98 KPrObject::setOrig( _x, _y );
99
100 if ( dx != 0 || dy != 0 )
101 updateCoords( dx, dy );
102}
103
104void KPrGroupObject::moveBy( const KoPoint &_point )
105{
106 moveBy( _point.x(), _point.y() );
107}
108
109void KPrGroupObject::moveBy( double _dx, double _dy )
110{
111 KPrObject::moveBy( _dx, _dy );
112 updateCoords( _dx, _dy );
113}
114
115TQDomDocumentFragment KPrGroupObject::save( TQDomDocument& doc, double offset )
116{
117 TQDomDocumentFragment fragment=KPrObject::save(doc, offset);
118 TQDomElement objs=doc.createElement("OBJECTS");
119 fragment.appendChild(objs);
120 TQPtrListIterator<KPrObject> it( objects );
121 for ( ; it.current() ; ++it )
122 {
123 if ( it.current()->getType() == OT_PART )
124 continue;
125 TQDomElement object=doc.createElement("OBJECT");
126 object.setAttribute("type", static_cast<int>( it.current()->getType() ));
127 object.appendChild(it.current()->save( doc,offset ));
128 objs.appendChild(object);
129 }
130 return fragment;
131}
132
133
134bool KPrGroupObject::saveOasisObjectAttributes( KPOasisSaveContext &sc ) const
135{
136 TQPtrListIterator<KPrObject> it( objects );
137 for ( ; it.current() ; ++it )
138 {
139 //TODO what to do with parts?
140 it.current()->saveOasisObject( sc );
141 }
142 return true;
143}
144
145void KPrGroupObject::saveOasisPosObject( KoXmlWriter &xmlWriter, int indexObj ) const
146{
147 xmlWriter.addAttribute( "draw:id", "object" + TQString::number( indexObj ) );
148}
149
150
151const char * KPrGroupObject::getOasisElementName() const
152{
153 return "draw:g";
154}
155
156
157void KPrGroupObject::loadOasisGroupObject( KPrDocument *_doc, KPrPage * newpage, TQDomNode &element, KoOasisContext & context, KPrLoadingInfo */*info*/ )
158{
159 //KPrObject::loadOasis( element, context, info );
160 updateObjs = false;
161 _doc->loadOasisObject( newpage,element, context, this);
162 TQPtrListIterator<KPrObject> it( objects );
163 KoRect r=KoRect();
164 for ( ; it.current() ; ++it )
165 {
166 r |= it.current()->getRealRect();
167 }
168 setOrig( r.x(), r.y() );
169 setSize( r.width(), r.height() );
170 updateObjs = true;
171}
172
173void KPrGroupObject::addObjects( KPrObject * obj )
174{
175 kdDebug()<<"add object to group object:"<<obj<<endl;
176 objects.append( obj );
177}
178
179double KPrGroupObject::load( const TQDomElement &element, KPrDocument *doc)
180{
181 //FIXME
182 double offset=KPrObject::load(element);
183 updateObjs = false;
184 TQDomElement group=element.namedItem("OBJECTS").toElement();
185 if(!group.isNull()) {
186 TQDomElement current=group.firstChild().toElement();
187 while(!current.isNull()) {
188 ObjType t = OT_LINE;
189 if(current.tagName()=="OBJECT") {
190 if(current.hasAttribute("type"))
191 t=static_cast<ObjType>(current.attribute("type").toInt());
192 double objOffset;
193 switch ( t ) {
194 case OT_LINE: {
195 KPrLineObject *kplineobject = new KPrLineObject();
196 objOffset = kplineobject->load(current);
197 kplineobject->setOrig(kplineobject->getOrig().x(),objOffset - offset);
198 objects.append( kplineobject );
199 } break;
200 case OT_RECT: {
201 KPrRectObject *kprectobject = new KPrRectObject();
202 objOffset = kprectobject->load(current);
203 kprectobject->setOrig(kprectobject->getOrig().x(),objOffset - offset);
204 objects.append( kprectobject );
205 } break;
206 case OT_ELLIPSE: {
207 KPrEllipseObject *kpellipseobject = new KPrEllipseObject();
208 objOffset = kpellipseobject->load(current);
209 kpellipseobject->setOrig(kpellipseobject->getOrig().x(),objOffset - offset);
210 objects.append( kpellipseobject );
211 } break;
212 case OT_PIE: {
213 KPrPieObject *kppieobject = new KPrPieObject();
214 objOffset = kppieobject->load(current);
215 kppieobject->setOrig(kppieobject->getOrig().x(),objOffset - offset);
216 objects.append( kppieobject );
217 } break;
218 case OT_AUTOFORM: {
219 KPrAutoformObject *kpautoformobject = new KPrAutoformObject();
220 objOffset = kpautoformobject->load(current);
221 kpautoformobject->setOrig(kpautoformobject->getOrig().x(),objOffset - offset);
222 objects.append( kpautoformobject );
223 } break;
224 case OT_TEXT: {
225 KPrTextObject *kptextobject = new KPrTextObject( doc );
226 objOffset = kptextobject->load(current);
227 kptextobject->setOrig(kptextobject->getOrig().x(),objOffset - offset);
228 objects.append( kptextobject );
229 } break;
230 case OT_CLIPART:
231 case OT_PICTURE: {
232 KPrPixmapObject *kppixmapobject = new KPrPixmapObject( doc->pictureCollection() );
233 objOffset = kppixmapobject->load(current);
234 kppixmapobject->setOrig(kppixmapobject->getOrig().x(),objOffset - offset);
235 kppixmapobject->reload();
236 objects.append( kppixmapobject );
237 } break;
238 case OT_FREEHAND: {
239 KPrFreehandObject *kpfreehandobject = new KPrFreehandObject();
240 objOffset = kpfreehandobject->load( current );
241 kpfreehandobject->setOrig(kpfreehandobject->getOrig().x(),objOffset - offset);
242 objects.append( kpfreehandobject );
243 } break;
244 case OT_POLYLINE: {
245 KPrPolylineObject *kppolylineobject = new KPrPolylineObject();
246 objOffset = kppolylineobject->load( current );
247 kppolylineobject->setOrig(kppolylineobject->getOrig().x(),objOffset - offset);
248 objects.append( kppolylineobject );
249 } break;
250 case OT_QUADRICBEZIERCURVE: {
251 KPrQuadricBezierCurveObject *kpQuadricBezierCurveObject = new KPrQuadricBezierCurveObject();
252 objOffset = kpQuadricBezierCurveObject->load( current );
253 kpQuadricBezierCurveObject->setOrig(kpQuadricBezierCurveObject->getOrig().x(),objOffset - offset);
254 objects.append( kpQuadricBezierCurveObject );
255 } break;
256 case OT_CUBICBEZIERCURVE: {
257 KPrCubicBezierCurveObject *kpCubicBezierCurveObject = new KPrCubicBezierCurveObject();
258 objOffset = kpCubicBezierCurveObject->load( current );
259 kpCubicBezierCurveObject->setOrig(kpCubicBezierCurveObject->getOrig().x(),objOffset - offset);
260 objects.append( kpCubicBezierCurveObject );
261 } break;
262 case OT_POLYGON: {
263 KPrPolygonObject *kpPolygonObject = new KPrPolygonObject();
264 objOffset = kpPolygonObject->load( current );
265 kpPolygonObject->setOrig(kpPolygonObject->getOrig().x(),objOffset - offset);
266 objects.append( kpPolygonObject );
267 } break;
268 case OT_GROUP: {
269 KPrGroupObject *kpgroupobject = new KPrGroupObject();
270 objOffset = kpgroupobject->load(current, doc);
271 kpgroupobject->setOrig(kpgroupobject->getOrig().x(),objOffset - offset);
272 objects.append( kpgroupobject );
273 } break;
274 case OT_CLOSED_LINE: {
275 KPrClosedLineObject *kpClosedLinneObject = new KPrClosedLineObject();
276 objOffset = kpClosedLinneObject->load( current );
277 kpClosedLinneObject->setOrig(kpClosedLinneObject->getOrig().x(),objOffset - offset);
278 objects.append( kpClosedLinneObject );
279 } break;
280 default: break;
281 }
282 }
283 current=current.nextSibling().toElement();
284 }
285 }
286 updateObjs = true;
287 return offset;
288}
289
290void KPrGroupObject::draw( TQPainter *_painter,KoTextZoomHandler *_zoomhandler,
291 int pageNum, SelectionMode selectionMode, bool drawContour )
292{
293 TQPtrListIterator<KPrObject> it( objects );
294 for ( ; it.current() ; ++it )
295 it.current()->draw( _painter, _zoomhandler, pageNum, selectionMode, drawContour );
296
297 KPrObject::draw( _painter, _zoomhandler, pageNum, selectionMode, drawContour );
298}
299
300void KPrGroupObject::updateSizes( double fx, double fy )
301{
302 if ( !updateObjs )
303 return;
304 KoRect r = KoRect();
305 TQPtrListIterator<KPrObject> it( objects );
306 for ( ; it.current() ; ++it )
307 {
308 double _x = ( it.current()->getOrig().x() - orig.x() ) * fx + orig.x();
309 double _y = ( it.current()->getOrig().y() - orig.y() ) * fy + orig.y();
310 it.current()->setOrig( _x, _y );
311
312 double _w = it.current()->getSize().width() * fx;
313 double _h = it.current()->getSize().height() * fy;
314 it.current()->setSize( _w, _h );
315 }
316}
317
318void KPrGroupObject::updateCoords( double dx, double dy )
319{
320 if ( !updateObjs )
321 return;
322 TQPtrListIterator<KPrObject> it( objects );
323 for ( ; it.current() ; ++it )
324 it.current()->moveBy( dx, dy );
325}
326
327void KPrGroupObject::rotate( float _angle )
328{
329 float oldAngle = angle;
330 float diffAngle = _angle - angle;
331 float angInRad = diffAngle * M_PI / 180;
332
333 KPrObject::rotate( _angle );
334
335 // find center of the group
336 double centerx = orig.x() + ext.width() / 2.0;
337 double centery = orig.y() + ext.height() / 2.0;
338
339 if ( !updateObjs )
340 return;
341 TQPtrListIterator<KPrObject> it( objects );
342 for ( ; it.current() ; ++it ) {
343 // find distance of object center to group center
344 double px = it.current()->getOrig().x() + it.current()->getSize().width() / 2.0 - centerx;
345 double py = it.current()->getOrig().y() + it.current()->getSize().height() / 2.0 - centery;
346 // find distance for move
347 double mx = px * cos( angInRad ) - py * sin( angInRad ) - px;
348 double my = px * sin( angInRad ) + py * cos( angInRad ) - py;
349 double objAngle = it.current()->getAngle();
350 // If part of group was already rotated the difference has to be added
351 // to the angle
352 if ( objAngle != oldAngle )
353 it.current()->rotate( objAngle + diffAngle );
354 else
355 it.current()->rotate( _angle );
356 it.current()->moveBy( mx, my );
357 }
358}
359
360void KPrGroupObject::setShadowParameter( int _distance, ShadowDirection _direction, const TQColor &_color )
361{
362 KPrObject::setShadowParameter( _distance, _direction, _color );
363
364 if ( !updateObjs )
365 return;
366 TQPtrListIterator<KPrObject> it( objects );
367 for ( ; it.current() ; ++it )
368 it.current()->setShadowParameter( _distance, _direction, _color );
369}
370
371void KPrGroupObject::setShadowDistance( int _distance )
372{
373 KPrObject::setShadowDistance( _distance );
374
375 if ( !updateObjs )
376 return;
377 TQPtrListIterator<KPrObject> it( objects );
378 for ( ; it.current() ; ++it )
379 it.current()->setShadowDistance( _distance );
380}
381
382void KPrGroupObject::setShadowDirection( ShadowDirection _direction )
383{
384 KPrObject::setShadowDirection( _direction );
385
386 if ( !updateObjs )
387 return;
388 TQPtrListIterator<KPrObject> it( objects );
389 for ( ; it.current() ; ++it )
390 it.current()->setShadowDirection( _direction );
391}
392
393void KPrGroupObject::setShadowColor( const TQColor &_color )
394{
395 KPrObject::setShadowColor( _color );
396 kdDebug(33001) << "KPrGroupObject::setShadowColor"<<updateObjs << endl;
397 if ( !updateObjs )
398 return;
399 TQPtrListIterator<KPrObject> it( objects );
400 for ( ; it.current() ; ++it )
401 it.current()->setShadowColor( _color );
402}
403
404void KPrGroupObject::setEffect( Effect _effect )
405{
406 KPrObject::setEffect( _effect );
407
408 if ( !updateObjs )
409 return;
410 TQPtrListIterator<KPrObject> it( objects );
411 for ( ; it.current() ; ++it )
412 it.current()->setEffect( _effect );
413}
414
415void KPrGroupObject::setEffect2( Effect2 _effect2 )
416{
417 KPrObject::setEffect2( _effect2 );
418
419 if ( !updateObjs )
420 return;
421 TQPtrListIterator<KPrObject> it( objects );
422 for ( ; it.current() ; ++it )
423 it.current()->setEffect2( _effect2 );
424}
425
426void KPrGroupObject::setAppearStep( int _appearStep )
427{
428 KPrObject::setAppearStep( _appearStep );
429
430 if ( !updateObjs )
431 return;
432 TQPtrListIterator<KPrObject> it( objects );
433 for ( ; it.current() ; ++it )
434 it.current()->setAppearStep( _appearStep );
435}
436
437void KPrGroupObject::setDisappear( bool b )
438{
439 KPrObject::setDisappear( b );
440
441 if ( !updateObjs )
442 return;
443 TQPtrListIterator<KPrObject> it( objects );
444 for ( ; it.current() ; ++it )
445 it.current()->setDisappear( b );
446}
447
448void KPrGroupObject::setDisappearStep( int _disappearStep )
449{
450 KPrObject::setDisappearStep( _disappearStep );
451
452 if ( !updateObjs )
453 return;
454 TQPtrListIterator<KPrObject> it( objects );
455 for ( ; it.current() ; ++it )
456 it.current()->setDisappearStep( _disappearStep );
457}
458
459void KPrGroupObject::setEffect3( Effect3 _effect3)
460{
461 KPrObject::setEffect3( _effect3 );
462
463 if ( !updateObjs )
464 return;
465 TQPtrListIterator<KPrObject> it( objects );
466 for ( ; it.current() ; ++it )
467 it.current()->setEffect3( _effect3 );
468}
469
470void KPrGroupObject::setAppearTimer( int _appearTimer )
471{
472 KPrObject::setAppearTimer( _appearTimer );
473
474 if ( !updateObjs )
475 return;
476 TQPtrListIterator<KPrObject> it( objects );
477 for ( ; it.current() ; ++it )
478 it.current()->setAppearTimer( _appearTimer );
479}
480
481void KPrGroupObject::setDisappearTimer( int _disappearTimer )
482{
483 KPrObject::setDisappearTimer( _disappearTimer );
484
485 if ( !updateObjs )
486 return;
487 TQPtrListIterator<KPrObject> it( objects );
488 for ( ; it.current() ; ++it )
489 it.current()->setDisappearTimer( _disappearTimer );
490}
491
492void KPrGroupObject::setOwnClipping( bool _ownClipping )
493{
494 KPrObject::setOwnClipping( _ownClipping );
495
496 if ( !updateObjs )
497 return;
498 TQPtrListIterator<KPrObject> it( objects );
499 for ( ; it.current() ; ++it )
500 it.current()->setOwnClipping( _ownClipping );
501}
502
503void KPrGroupObject::setSubPresStep( int _subPresStep )
504{
505 KPrObject::setSubPresStep( _subPresStep );
506
507 if ( !updateObjs )
508 return;
509 TQPtrListIterator<KPrObject> it( objects );
510 for ( ; it.current() ; ++it )
511 it.current()->setSubPresStep( _subPresStep );
512}
513
514void KPrGroupObject::doSpecificEffects( bool _specEffects, bool _onlyCurrStep )
515{
516 KPrObject::doSpecificEffects( _specEffects, _onlyCurrStep );
517
518 if ( !updateObjs )
519 return;
520 TQPtrListIterator<KPrObject> it( objects );
521 for ( ; it.current() ; ++it )
522 it.current()->doSpecificEffects( _specEffects, _onlyCurrStep );
523}
524
525void KPrGroupObject::setAppearSoundEffect( bool b )
526{
527 KPrObject::setAppearSoundEffect( b );
528
529 if ( !updateObjs )
530 return;
531 TQPtrListIterator<KPrObject> it( objects );
532 for ( ; it.current() ; ++it )
533 it.current()->setAppearSoundEffect( b );
534}
535
536void KPrGroupObject::setDisappearSoundEffect( bool b )
537{
538 KPrObject::setDisappearSoundEffect( b );
539
540 if ( !updateObjs )
541 return;
542 TQPtrListIterator<KPrObject> it( objects);
543 for ( ; it.current() ; ++it )
544 it.current()->setDisappearSoundEffect( b );
545}
546
547void KPrGroupObject::setAppearSoundEffectFileName( const TQString &_a_fileName )
548{
549 KPrObject::setAppearSoundEffectFileName( _a_fileName );
550
551 if ( !updateObjs )
552 return;
553 TQPtrListIterator<KPrObject> it( objects);
554 for ( ; it.current() ; ++it )
555 it.current()->setAppearSoundEffectFileName( _a_fileName );
556}
557
558void KPrGroupObject::setDisappearSoundEffectFileName( const TQString &_d_fileName )
559{
560 KPrObject::setDisappearSoundEffectFileName( _d_fileName );
561
562 if ( !updateObjs )
563 return;
564 TQPtrListIterator<KPrObject> it( objects);
565 for ( ; it.current() ; ++it )
566 it.current()->setDisappearSoundEffectFileName( _d_fileName );
567}
568
569void KPrGroupObject::getAllObjectSelectedList(TQPtrList<KPrObject> &lst,bool force )
570{
571 if ( selected || force)
572 {
573 TQPtrListIterator<KPrObject> it( objects);
574 for ( ; it.current() ; ++it )
575 it.current()->getAllObjectSelectedList( lst, true );
576 }
577}
578
579void KPrGroupObject::addTextObjects( TQPtrList<KoTextObject> &lst ) const
580{
581 TQPtrListIterator<KPrObject> it( objects);
582 for ( ; it.current() ; ++it )
583 it.current()->addTextObjects( lst );
584}
585
586void KPrGroupObject::flip( bool horizontal ) {
587 TQPtrListIterator<KPrObject> it( objects );
588 for ( ; it.current() ; ++it ) {
589 it.current()->flip( horizontal );
590 double mx = 0;
591 double my = 0;
592 if ( ! horizontal )
593 {
594 double disttop = it.current()->getOrig().y() - orig.y();
595 double distbottom = ext.height() - disttop - it.current()->getSize().height();
596 my = distbottom - disttop;
597 }
598 else
599 {
600 double distleft = it.current()->getOrig().x() - orig.x();
601 double distright = ext.width() - distleft - it.current()->getSize().width();
602 mx = distright - distleft;
603 }
604 it.current()->moveBy( mx, my );
605 }
606}
607
608void KPrGroupObject::removeFromObjList()
609{
610 inObjList = false;
611 TQPtrListIterator<KPrObject> it( objects );
612 for ( ; it.current() ; ++it )
613 it.current()->removeFromObjList();
614}
615
616void KPrGroupObject::addToObjList()
617{
618 inObjList = true;
619 TQPtrListIterator<KPrObject> it( objects );
620 for ( ; it.current() ; ++it )
621 it.current()->addToObjList();
622}
623
624void KPrGroupObject::incCmdRef()
625{
626 TQPtrListIterator<KPrObject> it( objects );
627 for ( ; it.current() ; ++it )
628 it.current()->incCmdRef();
629
630 cmds++;
631}
632
633void KPrGroupObject::decCmdRef()
634{
635 TQPtrListIterator<KPrObject> it( objects );
636 for ( ; it.current() ; ++it )
637 it.current()->decCmdRef();
638
639 cmds--;
640 doDelete();
641}
Temporary information used only during loading.