00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "KPrLineObject.h"
00023 #include "KPrUtils.h"
00024 #include "KPrDocument.h"
00025 #include "KPrLineObjectIface.h"
00026 #include "KoPointArray.h"
00027 #include <KoStyleStack.h>
00028 #include <KoOasisContext.h>
00029
00030 #include <qpainter.h>
00031 #include <qwmatrix.h>
00032 #include <qdom.h>
00033 #include <kdebug.h>
00034 #include <KoUnit.h>
00035 #include <KoTextZoomHandler.h>
00036 #include <math.h>
00037 #include <KoDom.h>
00038 #include <KoXmlNS.h>
00039
00040 using namespace std;
00041
00042 KPrLineObject::KPrLineObject()
00043 : KPrShadowObject(), KPrStartEndLine( L_NORMAL, L_NORMAL )
00044 {
00045 lineType = LT_HORZ;
00046 }
00047
00048 KPrLineObject::KPrLineObject( const KoPen &_pen, LineEnd _lineBegin,
00049 LineEnd _lineEnd, LineType _lineType )
00050 : KPrShadowObject( _pen ), KPrStartEndLine( _lineBegin, _lineEnd )
00051 {
00052 lineType = _lineType;
00053 }
00054
00055 KPrLineObject &KPrLineObject::operator=( const KPrLineObject & )
00056 {
00057 return *this;
00058 }
00059
00060 DCOPObject* KPrLineObject::dcopObject()
00061 {
00062 if ( !dcop )
00063 dcop = new KPrLineObjectIface( this );
00064 return dcop;
00065 }
00066
00067
00068 void KPrLineObject::fillStyle( KoGenStyle& styleObjectAuto, KoGenStyles& mainStyles ) const
00069 {
00070 KPrShadowObject::fillStyle( styleObjectAuto, mainStyles );
00071 saveOasisMarkerElement( mainStyles, styleObjectAuto );
00072 }
00073
00074
00075 bool KPrLineObject::saveOasisObjectAttributes( KPOasisSaveContext & ) const
00076 {
00077
00078 return true;
00079 }
00080
00081 void KPrLineObject::saveOasisPosObject( KoXmlWriter &xmlWriter, int indexObj ) const
00082 {
00083 xmlWriter.addAttribute( "draw:id", "object" + QString::number( indexObj ) );
00084
00085 double x1 = 0.0;
00086 double y1 = 0.0;
00087 double x2 = 0.0;
00088 double y2 = 0.0;
00089 KoPoint center( ext.width() / 2, ext.height() / 2 );
00090
00091 switch ( lineType )
00092 {
00093 case LT_LD_RU:
00094 x1 = -center.x();
00095 y1 = center.y();
00096 x2 = -x1;
00097 y2 = -y1;
00098 break;
00099 case LT_HORZ:
00100 x1 = -center.x();
00101 x2 = -x1;
00102 break;
00103 case LT_VERT:
00104 y1 = -center.y();
00105 y2 = -y1;
00106 break;
00107 case LT_LU_RD:
00108 x1 = -center.x();
00109 y1 = -center.y();
00110 x2 = -x1;
00111 y2 = -y1;
00112 break;
00113 }
00114 if ( kAbs( angle ) > 1E-6 )
00115 {
00116 double angInRad = -angle * M_PI / 180.0;
00117 QWMatrix m( cos( angInRad ), -sin( angInRad ), sin( angInRad ), cos( angInRad ), 0, 0 );
00118 double transX1 = 0.0;
00119 double transY1 = 0.0;
00120 double transX2 = 0.0;
00121 double transY2 = 0.0;
00122 m.map( x1, y1, &transX1, &transY1 );
00123 m.map( x2, y2, &transX2, &transY2 );
00124 x1 = transX1;
00125 y1 = transY1;
00126 x2 = transX2;
00127 y2 = transY2;
00128 }
00129
00130 x1 += orig.x() + center.x();
00131 y1 += orig.y() + center.y();
00132 x2 += orig.x() + center.x();
00133 y2 += orig.y() + center.y();
00134
00135
00136 xmlWriter.addAttributePt( "svg:x1", x1 );
00137 xmlWriter.addAttributePt( "svg:y1", y1 );
00138 xmlWriter.addAttributePt( "svg:x2", x2 );
00139 xmlWriter.addAttributePt( "svg:y2", y2 );
00140 }
00141
00142 const char * KPrLineObject::getOasisElementName() const
00143 {
00144 return "draw:line";
00145 }
00146
00147 QDomDocumentFragment KPrLineObject::save( QDomDocument& doc, double offset )
00148 {
00149 QDomDocumentFragment fragment=KPrShadowObject::save(doc, offset);
00150 if (lineType!=LT_HORZ)
00151 fragment.appendChild(KPrObject::createValueElement("LINETYPE", static_cast<int>(lineType), doc));
00152 KPrStartEndLine::save( fragment, doc );
00153 return fragment;
00154 }
00155
00156 void KPrLineObject::loadOasis(const QDomElement &element, KoOasisContext & context, KPrLoadingInfo *info)
00157 {
00158 KPrShadowObject::loadOasis(element, context, info);
00159
00160 double x1 = KoUnit::parseValue( element.attributeNS( KoXmlNS::svg, "x1", QString::null ) );
00161 double y1 = KoUnit::parseValue( element.attributeNS( KoXmlNS::svg, "y1", QString::null ) );
00162 double x2 = KoUnit::parseValue( element.attributeNS( KoXmlNS::svg, "x2", QString::null ) );
00163 double y2 = KoUnit::parseValue( element.attributeNS( KoXmlNS::svg, "y2", QString::null ) );
00164
00165 kdDebug()<<" KPrLineObject::loadOasis(const QDomElement &element) : x1 "<< x1 <<" y1 : "<<y1<<" x2 :"<<x2 <<" y2 "<<y2<<endl;
00166 double x = QMIN( x1, x2 );
00167 double y = QMIN( y1, y2 );
00168
00169 orig.setX( x );
00170 orig.setY( y );
00171
00172 ext.setWidth( fabs( x1 - x2 ) );
00173 ext.setHeight( fabs( y1 - y2 ) );
00174
00175 if ( y1 == y2 )
00176 {
00177 lineType=LT_HORZ;
00178
00179 ext.setHeight( 10 );
00180 orig.setY( y - 5.0 );
00181 }
00182 else if ( x1 == x2 )
00183 {
00184 lineType=LT_VERT;
00185
00186 ext.setWidth( 10 );
00187 orig.setX( x - 5.0 );
00188 }
00189 else if ( ( x1 < x2 && y1 < y2 ) || ( x1 > x2 && y1 > y2 ) )
00190 lineType=LT_LU_RD;
00191 else
00192 lineType=LT_LD_RU;
00193
00194 kdDebug()<<"KPrLineObject::loadOasis(const QDomElement &element) : real position x :"<<orig.x()<<" y "<<orig.y()<< " width :"<<ext.width()<<" height :"<<ext.height()<<endl;
00195
00196 QString attr = (x1 <= x2) ? "marker-start" : "marker-end";
00197 loadOasisMarkerElement( context, attr, lineBegin );
00198
00199 attr = (x1 <= x2) ? "marker-end" : "marker-start";
00200 loadOasisMarkerElement( context, attr, lineEnd );
00201 }
00202
00203 double KPrLineObject::load(const QDomElement &element)
00204 {
00205 double offset=KPrShadowObject::load(element);
00206 QDomElement e=element.namedItem("LINETYPE").toElement();
00207 if(!e.isNull()) {
00208 int tmp=0;
00209 if(e.hasAttribute("value"))
00210 tmp=e.attribute("value").toInt();
00211 lineType=static_cast<LineType>(tmp);
00212 }
00213 KPrStartEndLine::load( element );
00214 return offset;
00215 }
00216
00217 void KPrLineObject::paint( QPainter* _painter, KoTextZoomHandler*_zoomHandler,
00218 int , bool , bool drawContour )
00219 {
00220 double ow = ext.width();
00221 double oh = ext.height();
00222 int _w = int( pen.pointWidth() );
00223
00224 QPen pen2;
00225 if ( drawContour ) {
00226 pen2 = QPen( Qt::black, 1, Qt::DotLine );
00227 _painter->setRasterOp( Qt::NotXorROP );
00228 }
00229 else {
00230 pen2 = pen.zoomedPen( _zoomHandler );
00231 }
00232 _painter->setPen( pen2 );
00233
00234
00235 KoSize diff1( 0, 0 ), diff2( 0, 0 );
00236
00237 float _angle = 0;
00238 switch ( lineType )
00239 {
00240 case LT_HORZ: {
00241 _angle = 0;
00242 } break;
00243 case LT_VERT: {
00244 _angle = 90 ;
00245 } break;
00246 case LT_LU_RD: {
00247 KoRect _rect = KoRect( orig, ext );
00248 KoPoint pnt1 = _rect.topLeft();
00249 KoPoint pnt2 = _rect.bottomRight();
00250
00251 _angle = KoPoint::getAngle( pnt1, pnt2 ) - 180.0;
00252 } break;
00253 case LT_LD_RU: {
00254 KoRect _rect = KoRect( orig, ext );
00255 KoPoint pnt1 = _rect.bottomLeft();
00256 KoPoint pnt2 = _rect.topRight();
00257
00258 _angle = KoPoint::getAngle( pnt1, pnt2 ) - 180.0;
00259 } break;
00260 }
00261
00262 if ( lineBegin != L_NORMAL )
00263 diff1 = getOffset( lineBegin, _w, _angle + 180.0);
00264
00265 if ( lineEnd != L_NORMAL )
00266 diff2 = getOffset( lineEnd, _w, _angle );
00267
00268 switch ( lineType )
00269 {
00270 case LT_HORZ: {
00271 if ( lineBegin != L_NORMAL && !drawContour )
00272 drawFigure( lineBegin, _painter,
00273 KoPoint( 0, oh / 2.0 ),
00274 pen2.color(), _w, 180.0, _zoomHandler );
00275
00276 if ( lineEnd != L_NORMAL && !drawContour )
00277 drawFigure( lineEnd, _painter,
00278 KoPoint( ow , oh / 2.0),
00279 pen2.color(), _w, 0.0, _zoomHandler );
00280
00281 _painter->drawLine( _zoomHandler->zoomItX( - diff1.width() ),
00282 _zoomHandler->zoomItY( oh / 2 ),
00283 _zoomHandler->zoomItX( ow - diff2.width() ),
00284 _zoomHandler->zoomItY( oh / 2 ) );
00285 } break;
00286 case LT_VERT: {
00287 if ( lineBegin != L_NORMAL && !drawContour )
00288 drawFigure( lineBegin, _painter,
00289 KoPoint( ow / 2.0, 0 ),
00290 pen2.color(), _w, 270.0, _zoomHandler );
00291
00292 if ( lineEnd != L_NORMAL && !drawContour )
00293 drawFigure( lineEnd, _painter,
00294 KoPoint( ow / 2.0, oh ),
00295 pen2.color(), _w, 90.0, _zoomHandler );
00296
00297 _painter->drawLine( _zoomHandler->zoomItX( ow / 2 ),
00298 _zoomHandler->zoomItX( - diff1.height() ),
00299 _zoomHandler->zoomItX( ow / 2 ),
00300 _zoomHandler->zoomItY( oh - diff2.height() ) );
00301 } break;
00302 case LT_LU_RD: {
00303 if ( lineBegin != L_NORMAL && !drawContour ) {
00304 _painter->save();
00305 drawFigure( lineBegin, _painter,
00306 KoPoint( 0, 0 ), pen2.color(),
00307 _w, _angle + 180, _zoomHandler );
00308 _painter->restore();
00309 }
00310 if ( lineEnd != L_NORMAL && !drawContour ) {
00311 _painter->save();
00312 _painter->translate( _zoomHandler->zoomItX( ow ),
00313 _zoomHandler->zoomItY( oh ) );
00314 drawFigure( lineEnd, _painter,
00315 KoPoint( 0, 0 ), pen2.color(),
00316 _w, _angle, _zoomHandler );
00317 _painter->restore();
00318
00319 }
00320 _painter->drawLine( _zoomHandler->zoomItX( - diff1.width() ),
00321 _zoomHandler->zoomItY( - diff1.height() ),
00322 _zoomHandler->zoomItX( ow - diff2.width() ),
00323 _zoomHandler->zoomItY( oh - diff2.height() ) );
00324 } break;
00325 case LT_LD_RU: {
00326 if ( lineBegin != L_NORMAL && !drawContour ) {
00327 _painter->save();
00328 _painter->translate( _zoomHandler->zoomItX( 0 ),
00329 _zoomHandler->zoomItY( oh ) );
00330 drawFigure( lineBegin, _painter,
00331 KoPoint( 0, 0 ), pen2.color(),
00332 _w, _angle + 180,_zoomHandler );
00333 _painter->restore();
00334 }
00335 if ( lineEnd != L_NORMAL && !drawContour ) {
00336 _painter->save();
00337 _painter->translate( _zoomHandler->zoomItX( ow ),
00338 _zoomHandler->zoomItY( 0 ) );
00339 drawFigure( lineEnd, _painter,
00340 KoPoint( 0, 0 ), pen2.color(),
00341 _w, _angle,_zoomHandler );
00342 _painter->restore();
00343 }
00344 _painter->drawLine( _zoomHandler->zoomItX( - diff1.width() ),
00345 _zoomHandler->zoomItY( oh - diff1.height() ),
00346 _zoomHandler->zoomItX( ow - diff2.width() ),
00347 _zoomHandler->zoomItY( - diff2.height() ));
00348 } break;
00349 }
00350 }
00351
00352 void KPrLineObject::flip( bool horizontal )
00353 {
00354 KPrObject::flip( horizontal );
00355 if ( ! horizontal )
00356 {
00357 if ( lineType == LT_LU_RD )
00358 lineType = LT_LD_RU;
00359 else if ( lineType == LT_LD_RU )
00360 lineType = LT_LU_RD;
00361 }
00362 else
00363 {
00364 if ( lineType == LT_LU_RD )
00365 lineType = LT_LD_RU;
00366 else if ( lineType == LT_LD_RU )
00367 lineType = LT_LU_RD;
00368
00369 LineEnd tmp = lineBegin;
00370 lineBegin = lineEnd;
00371 lineEnd = tmp;
00372 }
00373 }
00374
00375 KoSize KPrLineObject::getRealSize() const {
00376 KoPoint realOrig( orig );
00377 KoSize size( ext );
00378
00379 KoPointArray points(4);
00380
00381 if ( lineType == LT_LU_RD || lineType == LT_LD_RU )
00382 {
00383 double objAngle = atan( ext.width() / ext.height() );
00384 double x = cos( objAngle ) * pen.pointWidth();
00385 double y = sin( objAngle ) * pen.pointWidth();
00386
00387 if ( lineType == LT_LU_RD )
00388 {
00389 points.setPoint( 0, x, 0 );
00390 points.setPoint( 1, 0, y );
00391 points.setPoint( 2, ext.width() + x, ext.height() );
00392 points.setPoint( 3, ext.width(), ext.height() + y );
00393 }
00394 else
00395 {
00396 points.setPoint( 0, 0, ext.height() );
00397 points.setPoint( 1, x, ext.height() + y );
00398 points.setPoint( 2, ext.width(), 0 );
00399 points.setPoint( 3, ext.width() + x, y );
00400 }
00401 realOrig.setX( realOrig.x() - x / 2.0 );
00402 realOrig.setY( realOrig.y() - y / 2.0 );
00403 size.setWidth( size.width() + x );
00404 size.setHeight( size.height() + y );
00405 }
00406
00407 if ( angle == 0.0 && lineType == LT_HORZ )
00408 {
00409 size.setHeight( pen.pointWidth() );
00410 }
00411 else if ( angle == 0.0 && lineType == LT_VERT )
00412 {
00413 size.setWidth( pen.pointWidth() );
00414 }
00415 else
00416 {
00417 if ( lineType == LT_HORZ )
00418 {
00419 points.setPoint( 0, 0, ( ext.height() - pen.pointWidth() ) / 2.0 );
00420 points.setPoint( 1, 0, ( ext.height() + pen.pointWidth() ) / 2.0 );
00421 points.setPoint( 2, ext.width(), ( ext.height() - pen.pointWidth() ) / 2.0 );
00422 points.setPoint( 3, ext.width(), ( ext.height() + pen.pointWidth() ) / 2.0 );
00423 }
00424 else if ( lineType == LT_VERT )
00425 {
00426 points.setPoint( 0, ( ext.width() - pen.pointWidth() ) / 2.0, 0 );
00427 points.setPoint( 1, ( ext.width() + pen.pointWidth() ) / 2.0, 0 );
00428 points.setPoint( 2, ( ext.width() - pen.pointWidth() ) / 2.0, ext.height() );
00429 points.setPoint( 3, ( ext.width() + pen.pointWidth() ) / 2.0, ext.height() );
00430 }
00431
00432 getRealSizeAndOrigFromPoints( points, angle, size, realOrig );
00433 }
00434
00435 return size;
00436 }
00437
00438 KoPoint KPrLineObject::getRealOrig() const {
00439 KoPoint realOrig( orig );
00440 KoSize size( ext );
00441
00442 KoPointArray points(4);
00443
00444 if ( lineType == LT_LU_RD || lineType == LT_LD_RU )
00445 {
00446 double objAngle = atan( ext.width() / ext.height() );
00447 double x = cos( objAngle ) * pen.pointWidth();
00448 double y = sin( objAngle ) * pen.pointWidth();
00449
00450 if ( lineType == LT_LU_RD )
00451 {
00452 points.setPoint( 0, x, 0 );
00453 points.setPoint( 1, 0, y );
00454 points.setPoint( 2, ext.width() + x, ext.height() );
00455 points.setPoint( 3, ext.width(), ext.height() + y );
00456 }
00457 else
00458 {
00459 points.setPoint( 0, 0, ext.height() );
00460 points.setPoint( 1, x, ext.height() + y );
00461 points.setPoint( 2, ext.width(), 0 );
00462 points.setPoint( 3, ext.width() + x, y );
00463 }
00464 realOrig.setX( realOrig.x() - x / 2.0 );
00465 realOrig.setY( realOrig.y() - y / 2.0 );
00466 size.setWidth( size.width() + x );
00467 size.setHeight( size.height() + y );
00468 }
00469
00470 if ( angle == 0.0 && lineType == LT_HORZ )
00471 {
00472 realOrig.setY( realOrig.y() + ( ext.height() - pen.pointWidth() ) / 2.0 );
00473 }
00474 else if ( angle == 0.0 && lineType == LT_VERT )
00475 {
00476 realOrig.setX( realOrig.x() + ( ext.width() - pen.pointWidth() ) / 2.0 );
00477 }
00478 else
00479 {
00480 if ( lineType == LT_HORZ )
00481 {
00482 points.setPoint( 0, 0, ( ext.height() - pen.pointWidth() ) / 2.0 );
00483 points.setPoint( 1, 0, ( ext.height() + pen.pointWidth() ) / 2.0 );
00484 points.setPoint( 2, ext.width(), ( ext.height() - pen.pointWidth() ) / 2.0 );
00485 points.setPoint( 3, ext.width(), ( ext.height() + pen.pointWidth() ) / 2.0 );
00486 }
00487 else if ( lineType == LT_VERT )
00488 {
00489 points.setPoint( 0, ( ext.width() - pen.pointWidth() ) / 2.0, 0 );
00490 points.setPoint( 1, ( ext.width() + pen.pointWidth() ) / 2.0, 0 );
00491 points.setPoint( 2, ( ext.width() - pen.pointWidth() ) / 2.0, ext.height() );
00492 points.setPoint( 3, ( ext.width() + pen.pointWidth() ) / 2.0, ext.height() );
00493 }
00494
00495 getRealSizeAndOrigFromPoints( points, angle, size, realOrig );
00496 }
00497
00498 return realOrig;
00499 }