kpresenter

KPrLineObject.cpp

00001 // -*- Mode: c++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 4; -*-
00002 /* This file is part of the KDE project
00003    Copyright (C) 1998, 1999 Reginald Stadlbauer <reggie@kde.org>
00004    Copyright (C) 2005 Thorsten Zachmann <zachmann@kde.org>
00005 
00006    This library is free software; you can redistribute it and/or
00007    modify it under the terms of the GNU Library General Public
00008    License as published by the Free Software Foundation; either
00009    version 2 of the License, or (at your option) any later version.
00010 
00011    This library is distributed in the hope that it will be useful,
00012    but WITHOUT ANY WARRANTY; without even the implied warranty of
00013    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014    Library General Public License for more details.
00015 
00016    You should have received a copy of the GNU Library General Public License
00017    along with this library; see the file COPYING.LIB.  If not, write to
00018    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00019  * Boston, MA 02110-1301, USA.
00020 */
00021 
00022 #include "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 &/*sc*/ ) const
00076 {
00077     // nothing to do
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     //save all into pt
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         //define default height
00179         ext.setHeight( 10 );
00180         orig.setY( y - 5.0 );
00181     }
00182     else if ( x1 == x2 )
00183     {
00184         lineType=LT_VERT;
00185         //define default width
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 /* pageNum */, bool /*drawingShadow*/, 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 }
KDE Home | KDE Accessibility Home | Description of Access Keys