kpresenter

KPrLineObject.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 "KPrLineObject.h"
22#include "KPrUtils.h"
23#include "KPrDocument.h"
24#include "KPrLineObjectIface.h"
25#include "KoPointArray.h"
26#include <KoStyleStack.h>
27#include <KoOasisContext.h>
28
29#include <tqpainter.h>
30#include <tqwmatrix.h>
31#include <tqdom.h>
32#include <kdebug.h>
33#include <KoUnit.h>
34#include <KoTextZoomHandler.h>
35#include <math.h>
36#include <KoDom.h>
37#include <KoXmlNS.h>
38
39using namespace std;
40
41KPrLineObject::KPrLineObject()
42 : KPrShadowObject(), KPrStartEndLine( L_NORMAL, L_NORMAL )
43{
44 lineType = LT_HORZ;
45}
46
47KPrLineObject::KPrLineObject( const KoPen &_pen, LineEnd _lineBegin,
48 LineEnd _lineEnd, LineType _lineType )
49 : KPrShadowObject( _pen ), KPrStartEndLine( _lineBegin, _lineEnd )
50{
51 lineType = _lineType;
52}
53
54KPrLineObject &KPrLineObject::operator=( const KPrLineObject & )
55{
56 return *this;
57}
58
59DCOPObject* KPrLineObject::dcopObject()
60{
61 if ( !dcop )
62 dcop = new KPrLineObjectIface( this );
63 return dcop;
64}
65
66
67void KPrLineObject::fillStyle( KoGenStyle& styleObjectAuto, KoGenStyles& mainStyles ) const
68{
69 KPrShadowObject::fillStyle( styleObjectAuto, mainStyles );
70 saveOasisMarkerElement( mainStyles, styleObjectAuto );
71}
72
73
74bool KPrLineObject::saveOasisObjectAttributes( KPOasisSaveContext &/*sc*/ ) const
75{
76 // nothing to do
77 return true;
78}
79
80void KPrLineObject::saveOasisPosObject( KoXmlWriter &xmlWriter, int indexObj ) const
81{
82 xmlWriter.addAttribute( "draw:id", "object" + TQString::number( indexObj ) );
83
84 double x1 = 0.0;
85 double y1 = 0.0;
86 double x2 = 0.0;
87 double y2 = 0.0;
88 KoPoint center( ext.width() / 2, ext.height() / 2 );
89
90 switch ( lineType )
91 {
92 case LT_LD_RU:
93 x1 = -center.x();
94 y1 = center.y();
95 x2 = -x1;
96 y2 = -y1;
97 break;
98 case LT_HORZ:
99 x1 = -center.x();
100 x2 = -x1;
101 break;
102 case LT_VERT:
103 y1 = -center.y();
104 y2 = -y1;
105 break;
106 case LT_LU_RD:
107 x1 = -center.x();
108 y1 = -center.y();
109 x2 = -x1;
110 y2 = -y1;
111 break;
112 }
113 if ( kAbs( angle ) > 1E-6 )
114 {
115 double angInRad = -angle * M_PI / 180.0;
116 TQWMatrix m( cos( angInRad ), -sin( angInRad ), sin( angInRad ), cos( angInRad ), 0, 0 );
117 double transX1 = 0.0;
118 double transY1 = 0.0;
119 double transX2 = 0.0;
120 double transY2 = 0.0;
121 m.map( x1, y1, &transX1, &transY1 );
122 m.map( x2, y2, &transX2, &transY2 );
123 x1 = transX1;
124 y1 = transY1;
125 x2 = transX2;
126 y2 = transY2;
127 }
128
129 x1 += orig.x() + center.x();
130 y1 += orig.y() + center.y();
131 x2 += orig.x() + center.x();
132 y2 += orig.y() + center.y();
133
134 //save all into pt
135 xmlWriter.addAttributePt( "svg:x1", x1 );
136 xmlWriter.addAttributePt( "svg:y1", y1 );
137 xmlWriter.addAttributePt( "svg:x2", x2 );
138 xmlWriter.addAttributePt( "svg:y2", y2 );
139}
140
141const char * KPrLineObject::getOasisElementName() const
142{
143 return "draw:line";
144}
145
146TQDomDocumentFragment KPrLineObject::save( TQDomDocument& doc, double offset )
147{
148 TQDomDocumentFragment fragment=KPrShadowObject::save(doc, offset);
149 if (lineType!=LT_HORZ)
150 fragment.appendChild(KPrObject::createValueElement("LINETYPE", static_cast<int>(lineType), doc));
151 KPrStartEndLine::save( fragment, doc );
152 return fragment;
153}
154
155void KPrLineObject::loadOasis(const TQDomElement &element, KoOasisContext & context, KPrLoadingInfo *info)
156{
157 KPrShadowObject::loadOasis(element, context, info);
158
159 double x1 = KoUnit::parseValue( element.attributeNS( KoXmlNS::svg, "x1", TQString() ) );
160 double y1 = KoUnit::parseValue( element.attributeNS( KoXmlNS::svg, "y1", TQString() ) );
161 double x2 = KoUnit::parseValue( element.attributeNS( KoXmlNS::svg, "x2", TQString() ) );
162 double y2 = KoUnit::parseValue( element.attributeNS( KoXmlNS::svg, "y2", TQString() ) );
163
164 kdDebug()<<" KPrLineObject::loadOasis(const TQDomElement &element) : x1 "<< x1 <<" y1 : "<<y1<<" x2 :"<<x2 <<" y2 "<<y2<<endl;
165 double x = TQMIN( x1, x2 );
166 double y = TQMIN( y1, y2 );
167
168 orig.setX( x );
169 orig.setY( y );
170
171 ext.setWidth( fabs( x1 - x2 ) );
172 ext.setHeight( fabs( y1 - y2 ) );
173
174 if ( y1 == y2 )
175 {
176 lineType=LT_HORZ;
177 //define default height
178 ext.setHeight( 10 );
179 orig.setY( y - 5.0 );
180 }
181 else if ( x1 == x2 )
182 {
183 lineType=LT_VERT;
184 //define default width
185 ext.setWidth( 10 );
186 orig.setX( x - 5.0 );
187 }
188 else if ( ( x1 < x2 && y1 < y2 ) || ( x1 > x2 && y1 > y2 ) )
189 lineType=LT_LU_RD;
190 else
191 lineType=LT_LD_RU;
192
193 kdDebug()<<"KPrLineObject::loadOasis(const TQDomElement &element) : real position x :"<<orig.x()<<" y "<<orig.y()<< " width :"<<ext.width()<<" height :"<<ext.height()<<endl;
194
195 TQString attr = (x1 <= x2) ? "marker-start" : "marker-end";
196 loadOasisMarkerElement( context, attr, lineBegin );
197
198 attr = (x1 <= x2) ? "marker-end" : "marker-start";
199 loadOasisMarkerElement( context, attr, lineEnd );
200}
201
202double KPrLineObject::load(const TQDomElement &element)
203{
204 double offset=KPrShadowObject::load(element);
205 TQDomElement e=element.namedItem("LINETYPE").toElement();
206 if(!e.isNull()) {
207 int tmp=0;
208 if(e.hasAttribute("value"))
209 tmp=e.attribute("value").toInt();
210 lineType=static_cast<LineType>(tmp);
211 }
212 KPrStartEndLine::load( element );
213 return offset;
214}
215
216void KPrLineObject::paint( TQPainter* _painter, KoTextZoomHandler*_zoomHandler,
217 int /* pageNum */, bool /*drawingShadow*/, bool drawContour )
218{
219 double ow = ext.width();
220 double oh = ext.height();
221 int _w = int( pen.pointWidth() );
222
223 TQPen pen2;
224 if ( drawContour ) {
225 pen2 = TQPen( TQt::black, 1, TQt::DotLine );
226 _painter->setRasterOp( TQt::NotXorROP );
227 }
228 else {
229 pen2 = pen.zoomedPen( _zoomHandler );
230 }
231 _painter->setPen( pen2 );
232
233
234 KoSize diff1( 0, 0 ), diff2( 0, 0 );
235
236 float _angle = 0;
237 switch ( lineType )
238 {
239 case LT_HORZ: {
240 _angle = 0;
241 } break;
242 case LT_VERT: {
243 _angle = 90 ;
244 } break;
245 case LT_LU_RD: {
246 KoRect _rect = KoRect( orig, ext );
247 KoPoint pnt1 = _rect.topLeft();
248 KoPoint pnt2 = _rect.bottomRight();
249
250 _angle = KoPoint::getAngle( pnt1, pnt2 ) - 180.0;
251 } break;
252 case LT_LD_RU: {
253 KoRect _rect = KoRect( orig, ext );
254 KoPoint pnt1 = _rect.bottomLeft();
255 KoPoint pnt2 = _rect.topRight();
256
257 _angle = KoPoint::getAngle( pnt1, pnt2 ) - 180.0;
258 } break;
259 }
260
261 if ( lineBegin != L_NORMAL )
262 diff1 = getOffset( lineBegin, _w, _angle + 180.0);
263
264 if ( lineEnd != L_NORMAL )
265 diff2 = getOffset( lineEnd, _w, _angle );
266
267 switch ( lineType )
268 {
269 case LT_HORZ: {
270 if ( lineBegin != L_NORMAL && !drawContour )
271 drawFigure( lineBegin, _painter,
272 KoPoint( 0, oh / 2.0 ),
273 pen2.color(), _w, 180.0, _zoomHandler );
274
275 if ( lineEnd != L_NORMAL && !drawContour )
276 drawFigure( lineEnd, _painter,
277 KoPoint( ow , oh / 2.0),
278 pen2.color(), _w, 0.0, _zoomHandler );
279
280 _painter->drawLine( _zoomHandler->zoomItX( - diff1.width() ),
281 _zoomHandler->zoomItY( oh / 2 ),
282 _zoomHandler->zoomItX( ow - diff2.width() ),
283 _zoomHandler->zoomItY( oh / 2 ) );
284 } break;
285 case LT_VERT: {
286 if ( lineBegin != L_NORMAL && !drawContour )
287 drawFigure( lineBegin, _painter,
288 KoPoint( ow / 2.0, 0 ),
289 pen2.color(), _w, 270.0, _zoomHandler );
290
291 if ( lineEnd != L_NORMAL && !drawContour )
292 drawFigure( lineEnd, _painter,
293 KoPoint( ow / 2.0, oh ),
294 pen2.color(), _w, 90.0, _zoomHandler );
295
296 _painter->drawLine( _zoomHandler->zoomItX( ow / 2 ),
297 _zoomHandler->zoomItX( - diff1.height() ),
298 _zoomHandler->zoomItX( ow / 2 ),
299 _zoomHandler->zoomItY( oh - diff2.height() ) );
300 } break;
301 case LT_LU_RD: {
302 if ( lineBegin != L_NORMAL && !drawContour ) {
303 _painter->save();
304 drawFigure( lineBegin, _painter,
305 KoPoint( 0, 0 ), pen2.color(),
306 _w, _angle + 180, _zoomHandler );
307 _painter->restore();
308 }
309 if ( lineEnd != L_NORMAL && !drawContour ) {
310 _painter->save();
311 _painter->translate( _zoomHandler->zoomItX( ow ),
312 _zoomHandler->zoomItY( oh ) );
313 drawFigure( lineEnd, _painter,
314 KoPoint( 0, 0 ), pen2.color(),
315 _w, _angle, _zoomHandler );
316 _painter->restore();
317
318 }
319 _painter->drawLine( _zoomHandler->zoomItX( - diff1.width() ),
320 _zoomHandler->zoomItY( - diff1.height() ),
321 _zoomHandler->zoomItX( ow - diff2.width() ),
322 _zoomHandler->zoomItY( oh - diff2.height() ) );
323 } break;
324 case LT_LD_RU: {
325 if ( lineBegin != L_NORMAL && !drawContour ) {
326 _painter->save();
327 _painter->translate( _zoomHandler->zoomItX( 0 ),
328 _zoomHandler->zoomItY( oh ) );
329 drawFigure( lineBegin, _painter,
330 KoPoint( 0, 0 ), pen2.color(),
331 _w, _angle + 180,_zoomHandler );
332 _painter->restore();
333 }
334 if ( lineEnd != L_NORMAL && !drawContour ) {
335 _painter->save();
336 _painter->translate( _zoomHandler->zoomItX( ow ),
337 _zoomHandler->zoomItY( 0 ) );
338 drawFigure( lineEnd, _painter,
339 KoPoint( 0, 0 ), pen2.color(),
340 _w, _angle,_zoomHandler );
341 _painter->restore();
342 }
343 _painter->drawLine( _zoomHandler->zoomItX( - diff1.width() ),
344 _zoomHandler->zoomItY( oh - diff1.height() ),
345 _zoomHandler->zoomItX( ow - diff2.width() ),
346 _zoomHandler->zoomItY( - diff2.height() ));
347 } break;
348 }
349}
350
351void KPrLineObject::flip( bool horizontal )
352{
353 KPrObject::flip( horizontal );
354 if ( ! horizontal )
355 {
356 if ( lineType == LT_LU_RD )
357 lineType = LT_LD_RU;
358 else if ( lineType == LT_LD_RU )
359 lineType = LT_LU_RD;
360 }
361 else
362 {
363 if ( lineType == LT_LU_RD )
364 lineType = LT_LD_RU;
365 else if ( lineType == LT_LD_RU )
366 lineType = LT_LU_RD;
367
368 LineEnd tmp = lineBegin;
369 lineBegin = lineEnd;
370 lineEnd = tmp;
371 }
372}
373
374KoSize KPrLineObject::getRealSize() const {
375 KoPoint realOrig( orig );
376 KoSize size( ext );
377
378 KoPointArray points(4);
379
380 if ( lineType == LT_LU_RD || lineType == LT_LD_RU )
381 {
382 double objAngle = atan( ext.width() / ext.height() );
383 double x = cos( objAngle ) * pen.pointWidth();
384 double y = sin( objAngle ) * pen.pointWidth();
385
386 if ( lineType == LT_LU_RD )
387 {
388 points.setPoint( 0, x, 0 );
389 points.setPoint( 1, 0, y );
390 points.setPoint( 2, ext.width() + x, ext.height() );
391 points.setPoint( 3, ext.width(), ext.height() + y );
392 }
393 else
394 {
395 points.setPoint( 0, 0, ext.height() );
396 points.setPoint( 1, x, ext.height() + y );
397 points.setPoint( 2, ext.width(), 0 );
398 points.setPoint( 3, ext.width() + x, y );
399 }
400 realOrig.setX( realOrig.x() - x / 2.0 );
401 realOrig.setY( realOrig.y() - y / 2.0 );
402 size.setWidth( size.width() + x );
403 size.setHeight( size.height() + y );
404 }
405
406 if ( angle == 0.0 && lineType == LT_HORZ )
407 {
408 size.setHeight( pen.pointWidth() );
409 }
410 else if ( angle == 0.0 && lineType == LT_VERT )
411 {
412 size.setWidth( pen.pointWidth() );
413 }
414 else
415 {
416 if ( lineType == LT_HORZ )
417 {
418 points.setPoint( 0, 0, ( ext.height() - pen.pointWidth() ) / 2.0 );
419 points.setPoint( 1, 0, ( ext.height() + pen.pointWidth() ) / 2.0 );
420 points.setPoint( 2, ext.width(), ( ext.height() - pen.pointWidth() ) / 2.0 );
421 points.setPoint( 3, ext.width(), ( ext.height() + pen.pointWidth() ) / 2.0 );
422 }
423 else if ( lineType == LT_VERT )
424 {
425 points.setPoint( 0, ( ext.width() - pen.pointWidth() ) / 2.0, 0 );
426 points.setPoint( 1, ( ext.width() + pen.pointWidth() ) / 2.0, 0 );
427 points.setPoint( 2, ( ext.width() - pen.pointWidth() ) / 2.0, ext.height() );
428 points.setPoint( 3, ( ext.width() + pen.pointWidth() ) / 2.0, ext.height() );
429 }
430
431 getRealSizeAndOrigFromPoints( points, angle, size, realOrig );
432 }
433
434 return size;
435}
436
437KoPoint KPrLineObject::getRealOrig() const {
438 KoPoint realOrig( orig );
439 KoSize size( ext );
440
441 KoPointArray points(4);
442
443 if ( lineType == LT_LU_RD || lineType == LT_LD_RU )
444 {
445 double objAngle = atan( ext.width() / ext.height() );
446 double x = cos( objAngle ) * pen.pointWidth();
447 double y = sin( objAngle ) * pen.pointWidth();
448
449 if ( lineType == LT_LU_RD )
450 {
451 points.setPoint( 0, x, 0 );
452 points.setPoint( 1, 0, y );
453 points.setPoint( 2, ext.width() + x, ext.height() );
454 points.setPoint( 3, ext.width(), ext.height() + y );
455 }
456 else
457 {
458 points.setPoint( 0, 0, ext.height() );
459 points.setPoint( 1, x, ext.height() + y );
460 points.setPoint( 2, ext.width(), 0 );
461 points.setPoint( 3, ext.width() + x, y );
462 }
463 realOrig.setX( realOrig.x() - x / 2.0 );
464 realOrig.setY( realOrig.y() - y / 2.0 );
465 size.setWidth( size.width() + x );
466 size.setHeight( size.height() + y );
467 }
468
469 if ( angle == 0.0 && lineType == LT_HORZ )
470 {
471 realOrig.setY( realOrig.y() + ( ext.height() - pen.pointWidth() ) / 2.0 );
472 }
473 else if ( angle == 0.0 && lineType == LT_VERT )
474 {
475 realOrig.setX( realOrig.x() + ( ext.width() - pen.pointWidth() ) / 2.0 );
476 }
477 else
478 {
479 if ( lineType == LT_HORZ )
480 {
481 points.setPoint( 0, 0, ( ext.height() - pen.pointWidth() ) / 2.0 );
482 points.setPoint( 1, 0, ( ext.height() + pen.pointWidth() ) / 2.0 );
483 points.setPoint( 2, ext.width(), ( ext.height() - pen.pointWidth() ) / 2.0 );
484 points.setPoint( 3, ext.width(), ( ext.height() + pen.pointWidth() ) / 2.0 );
485 }
486 else if ( lineType == LT_VERT )
487 {
488 points.setPoint( 0, ( ext.width() - pen.pointWidth() ) / 2.0, 0 );
489 points.setPoint( 1, ( ext.width() + pen.pointWidth() ) / 2.0, 0 );
490 points.setPoint( 2, ( ext.width() - pen.pointWidth() ) / 2.0, ext.height() );
491 points.setPoint( 3, ( ext.width() + pen.pointWidth() ) / 2.0, ext.height() );
492 }
493
494 getRealSizeAndOrigFromPoints( points, angle, size, realOrig );
495 }
496
497 return realOrig;
498}
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