00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "KPrAutoformObject.h"
00023 #include "KPrAutoFormObjectIface.h"
00024 #include "KPrUtils.h"
00025 #include "KPrGradient.h"
00026
00027 #include <qbitmap.h>
00028 #include <qpointarray.h>
00029 #include <qptrlist.h>
00030 #include <qregion.h>
00031 #include <qdom.h>
00032 #include <qpainter.h>
00033 #include <qwmatrix.h>
00034 #include <kstandarddirs.h>
00035 #include <kdebug.h>
00036 #include <KoTextZoomHandler.h>
00037 #include <math.h>
00038 using namespace std;
00039
00040 KPrAutoformObject::KPrAutoformObject()
00041 : KPr2DObject()
00042 , KPrStartEndLine( L_NORMAL, L_NORMAL )
00043 , atfInterp()
00044 {
00045 }
00046
00047 KPrAutoformObject::KPrAutoformObject( const KoPen & _pen, const QBrush &_brush, const QString & _filename,
00048 LineEnd _lineBegin, LineEnd _lineEnd,
00049 FillType _fillType, const QColor &_gColor1,
00050 const QColor &_gColor2, BCType _gType,
00051 bool _unbalanced, int _xfactor, int _yfactor)
00052 : KPr2DObject( _pen, _brush, _fillType, _gColor1, _gColor2, _gType, _unbalanced, _xfactor, _yfactor )
00053 , KPrStartEndLine( _lineBegin, _lineEnd )
00054 , filename( _filename ), atfInterp()
00055 {
00056 atfInterp.load( filename );
00057 }
00058
00059 KPrAutoformObject &KPrAutoformObject::operator=( const KPrAutoformObject & )
00060 {
00061 return *this;
00062 }
00063
00064 DCOPObject* KPrAutoformObject::dcopObject()
00065 {
00066 if ( !dcop )
00067 dcop = new KPrAutoFormObjectIface( this );
00068 return dcop;
00069 }
00070
00071 void KPrAutoformObject::setFileName( const QString & _filename )
00072 {
00073 filename = _filename;
00074 atfInterp.load( filename );
00075 }
00076
00077
00078 bool KPrAutoformObject::saveOasisObjectAttributes( KPOasisSaveContext &sc ) const
00079 {
00080 kdDebug(33001) << "bool KPrAutoformObject::saveOasisObjectAttributes()" << endl;
00081 QSize size( int( ext.width() * 100 ), int( ext.height() * 100 ) );
00082
00083 sc.xmlWriter.addAttribute( "svg:viewBox", QString( "0 0 %1 %2" ).arg( size.width() )
00084 .arg( size.height() ) );
00085
00086 QPointArray points = const_cast<ATFInterpreter &>( atfInterp ).getPointArray( size.width(), size.height() );
00087
00088 unsigned int pointCount = points.size();
00089 unsigned int pos = 0;
00090 bool closed = points.at( 0 ) == points.at( pointCount - 1 );
00091
00092 if ( closed )
00093 --pointCount;
00094
00095 QString d;
00096 d += QString( "M%1 %2" ).arg( points.at(pos).x() )
00097 .arg( points.at(pos).y() );
00098 ++pos;
00099
00100 while ( pos < pointCount )
00101 {
00102 d += QString( "L%1 %2" ).arg( points.at( pos ).x() )
00103 .arg( points.at( pos ).y() );
00104 ++pos;
00105 }
00106
00107 if ( closed )
00108 d += "Z";
00109
00110 sc.xmlWriter.addAttribute( "svg:d", d );
00111
00112 return true;
00113 }
00114
00115 void KPrAutoformObject::fillStyle( KoGenStyle& styleObjectAuto, KoGenStyles& mainStyles ) const
00116 {
00117 kdDebug(33001) << "KPr2DObject::fillStyle" << endl;
00118 KPrShadowObject::fillStyle( styleObjectAuto, mainStyles );
00119
00120 QPointArray points = const_cast<ATFInterpreter &>( atfInterp ).getPointArray( int( ext.width() * 100 ),
00121 int( ext.height() * 100 ) );
00122
00123
00124 if ( points.at( 0 ) == points.at( points.size() - 1 ) )
00125 {
00126 m_brush.saveOasisFillStyle( styleObjectAuto, mainStyles );
00127 }
00128 else
00129 {
00130 saveOasisMarkerElement( mainStyles, styleObjectAuto );
00131 }
00132 }
00133
00134 const char * KPrAutoformObject::getOasisElementName() const
00135 {
00136 return "draw:path";
00137 }
00138
00139 QDomDocumentFragment KPrAutoformObject::save( QDomDocument& doc, double offset )
00140 {
00141 QDomDocumentFragment fragment=KPr2DObject::save(doc, offset);
00142 KPrStartEndLine::save( fragment, doc );
00143
00144
00145
00146
00147 QStringList afDirs = KPrFactory::global()->dirs()->resourceDirs("autoforms");
00148 QValueList<QString>::ConstIterator it=afDirs.begin();
00149 QString str;
00150 for( ; it!=afDirs.end(); ++it) {
00151 if(filename.startsWith(*it)) {
00152 str=filename.mid((*it).length());
00153 break;
00154 }
00155 }
00156 QDomElement elem=doc.createElement("FILENAME");
00157 elem.setAttribute("value", str);
00158 fragment.appendChild(elem);
00159 return fragment;
00160 }
00161
00162 double KPrAutoformObject::load(const QDomElement &element)
00163 {
00164 double offset=KPr2DObject::load(element);
00165 KPrStartEndLine::load( element );
00166 QDomElement e=element.namedItem("FILENAME").toElement();
00167 if(!e.isNull()) {
00168 if(e.hasAttribute("value"))
00169 filename=e.attribute("value");
00170
00171 if(filename.isEmpty())
00172 filename="Connections/.source/Connection1.atf";
00173
00174 if(filename[0]=='/') {
00175 kdDebug(33001) << "rubbish ahead! cleaning up..." << endl;
00176
00177 filename=filename.mid(filename.findRev('/', filename.findRev('/')-1)+1);
00178 }
00179
00180
00181
00182
00183 if(filename.find(".source")==-1) {
00184
00185 filename=filename.insert(filename.find('/'), "/.source");
00186 }
00187 filename = locate("autoforms", filename, KPrFactory::global());
00188 atfInterp.load( filename );
00189 }
00190 return offset;
00191 }
00192
00193 void KPrAutoformObject::paint( QPainter* _painter, KoTextZoomHandler *_zoomHandler,
00194 int , bool drawingShadow, bool drawContour )
00195 {
00196 unsigned int pw = 0, pwOrig = 0, px, py;
00197 QPen pen2;
00198 QSize size( _zoomHandler->zoomSize( ext ) );
00199
00200 if ( drawContour )
00201 pen2 = QPen( Qt::black, 1, Qt::DotLine );
00202 else {
00203 pen2 = pen.zoomedPen( _zoomHandler );
00204 }
00205
00206 _painter->setPen( pen2 );
00207 pwOrig = ( pen2.style() == Qt::NoPen ) ? 1 : pen2.width();
00208 if ( !drawContour )
00209 _painter->setBrush( getBrush() );
00210
00211 QPointArray pntArray = atfInterp.getPointArray( _zoomHandler->zoomItX( ext.width()),
00212 _zoomHandler->zoomItY( ext.height() ) );
00213 QPtrList<ATFInterpreter::AttribList> atrLs = atfInterp.getAttribList();
00214 QPointArray pntArray2( pntArray.size() );
00215 int ex = _zoomHandler->zoomItX(ext.width());
00216 int ey = _zoomHandler->zoomItY(ext.height());
00217 for ( unsigned int i = 0; i < pntArray.size(); i++ )
00218 {
00219 px = pntArray.at( i ).x();
00220 py = pntArray.at( i ).y();
00221 if ( atrLs.at( i )->pwDiv > 0 )
00222 {
00223 pw = pwOrig / atrLs.at( i )->pwDiv;
00224 px = (int)((double)(ex - pw) / (double)ex * px + pw / 2);
00225 py = (int)((double)(ey - pw) / (double)ey * py + pw / 2);
00226 }
00227 pntArray2.setPoint( i, px, py );
00228 }
00229
00230 if ( pntArray2.size() > 0 )
00231 {
00232 if ( pntArray2.at( 0 ) == pntArray2.at( pntArray2.size() - 1 ) )
00233 {
00234 if ( drawContour || (drawingShadow || getFillType() == FT_BRUSH || !gradient) )
00235 _painter->drawPolygon( pntArray2 );
00236 else
00237 {
00238 if ( angle == 0 || angle==360 )
00239 {
00240
00241
00242
00243 QPointArray pntArray3 = pntArray2.copy();
00244 _painter->save();
00245
00246 QRegion clipregion( pntArray3 );
00247
00248
00249 if ( _painter->hasClipping() )
00250 clipregion = _painter->clipRegion(QPainter::CoordPainter).intersect( clipregion );
00251
00252 _painter->setClipRegion( clipregion, QPainter::CoordPainter );
00253
00254 gradient->setSize( size );
00255 _painter->drawPixmap( 0, 0, gradient->pixmap() );
00256
00257 _painter->restore();
00258 }
00259 else
00260 {
00261 if ( m_redrawGradientPix || gradient->size() != size )
00262 {
00263 kdDebug(33001) << "KPrAutoformObject::draw redrawPix" << endl;
00264 gradient->setSize( size );
00265 m_redrawGradientPix = false;
00266 QRegion clipregion( pntArray2 );
00267 m_gradientPix.resize ( _zoomHandler->zoomItX(ext.width()),_zoomHandler->zoomItY(ext.height()) );
00268 m_gradientPix.fill( Qt::white );
00269
00270
00271 QPainter p;
00272 p.begin( &m_gradientPix );
00273 p.setClipRegion( clipregion , QPainter::CoordPainter);
00274 p.drawPixmap( 0, 0, gradient->pixmap() );
00275 p.end();
00276
00277 m_gradientPix.setMask( m_gradientPix.createHeuristicMask() );
00278 }
00279
00280 _painter->drawPixmap( 0, 0, m_gradientPix );
00281 }
00282
00283 _painter->setPen( pen2 );
00284 _painter->setBrush( Qt::NoBrush );
00285 _painter->drawPolygon( pntArray2 );
00286 }
00287 }
00288 else
00289 {
00290 KoSize diff1( 0, 0 ), diff2( 0, 0 );
00291 int _w = int( pen.pointWidth() );
00292
00293 if ( lineBegin != L_NORMAL )
00294 diff1 = getBoundingSize( lineBegin, _w, _zoomHandler );
00295
00296 if ( lineEnd != L_NORMAL )
00297 diff2 = getBoundingSize( lineEnd, _w, _zoomHandler );
00298
00299 if ( pntArray.size() > 1 )
00300 {
00301 if ( lineBegin != L_NORMAL && !drawContour )
00302 {
00303 QPoint pnt1( pntArray2.at( 0 ) ), pnt2( pntArray2.at( 1 ) );
00304 QPoint pnt3, pnt4( pntArray.at( 0 ) );
00305 float _angle = KoPoint::getAngle( KoPoint( pnt1 ), KoPoint( pnt2 ) );
00306
00307 switch ( static_cast<int>( _angle ) )
00308 {
00309 case 0:
00310 {
00311 pnt3.setX( pnt4.x() - (int)diff1.width() / 2 );
00312 pnt3.setY( pnt1.y() );
00313 } break;
00314 case 180:
00315 {
00316 pnt3.setX( pnt4.x() + (int)diff1.width() / 2 );
00317 pnt3.setY( pnt1.y() );
00318 } break;
00319 case 90:
00320 {
00321 pnt3.setX( pnt1.x() );
00322 pnt3.setY( pnt4.y() - (int)diff1.width() / 2 );
00323 } break;
00324 case 270:
00325 {
00326 pnt3.setX( pnt1.x() );
00327 pnt3.setY( pnt4.y() + (int)diff1.width() / 2 );
00328 } break;
00329 default:
00330 pnt3 = pnt1;
00331 break;
00332 }
00333
00334 drawFigure( lineBegin, _painter, _zoomHandler->unzoomPoint( pnt3 ), pen2.color(), _w, _angle, _zoomHandler );
00335 }
00336
00337 if ( lineEnd != L_NORMAL && !drawContour )
00338 {
00339 QPoint pnt1( pntArray2.at( pntArray2.size() - 1 ) ), pnt2( pntArray2.at( pntArray2.size() - 2 ) );
00340 QPoint pnt3, pnt4( pntArray.at( pntArray.size() - 1 ) );
00341 float _angle = KoPoint::getAngle( KoPoint( pnt1 ), KoPoint( pnt2 ) );
00342
00343 switch ( ( int )_angle )
00344 {
00345 case 0:
00346 {
00347 pnt3.setX( pnt4.x() - (int)diff2.width() / 2 );
00348 pnt3.setY( pnt1.y() );
00349 } break;
00350 case 180:
00351 {
00352 pnt3.setX( pnt4.x() + (int)diff2.width() / 2 );
00353 pnt3.setY( pnt1.y() );
00354 } break;
00355 case 90:
00356 {
00357 pnt3.setX( pnt1.x() );
00358 pnt3.setY( pnt4.y() - (int)diff2.width() / 2 );
00359 } break;
00360 case 270:
00361 {
00362 pnt3.setX( pnt1.x() );
00363 pnt3.setY( pnt4.y() + (int)diff2.width() / 2 );
00364 } break;
00365 default:
00366 pnt3 = pnt1;
00367 break;
00368 }
00369
00370 drawFigure( lineEnd, _painter, _zoomHandler->unzoomPoint( pnt3 ), pen2.color(), _w, _angle,_zoomHandler );
00371 }
00372 }
00373
00374 _painter->setPen( pen2 );
00375 _painter->drawPolyline( pntArray2 );
00376 }
00377 }
00378 }