00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "kivio_common.h"
00020 #include "kivio_connector_point.h"
00021 #include "kivio_connector_target.h"
00022 #include "kivio_group_stencil.h"
00023 #include "kivio_intra_stencil_data.h"
00024 #include "kivio_layer.h"
00025 #include "kivio_painter.h"
00026 #include "kivio_stencil.h"
00027 #include "kivio_stencil_spawner.h"
00028 #include "kivio_stencil_spawner_info.h"
00029 #include "kivio_stencil_spawner_set.h"
00030 #include "KIvioLayerIface.h"
00031 #include "kivio_doc.h"
00032 #include "kivio_page.h"
00033
00034 #include <qdom.h>
00035
00036 #include <klocale.h>
00037 #include <kdebug.h>
00038 #include <KoZoomHandler.h>
00039 #include <KoPoint.h>
00040 #include <KoStore.h>
00041 #include <KoXmlWriter.h>
00042
00043 KivioLayer::KivioLayer( KivioPage *pPage )
00044 :m_pStencilList(NULL)
00045 {
00046 m_pPage = pPage;
00047 m_name = i18n("Untitled Layer");
00048
00049 m_pStencilList = new QPtrList<KivioStencil>;
00050 m_pStencilList->setAutoDelete(true);
00051
00052 m_pDeletedStencilList = new QPtrList<KivioStencil>;
00053 m_pDeletedStencilList->setAutoDelete(true);
00054
00055 m_flags = 0;
00056 m_dcop = 0;
00057 setVisible(true);
00058 setConnectable(false);
00059 setEditable(true);
00060 setPrintable(true);
00061 }
00062
00063 DCOPObject* KivioLayer::dcopObject()
00064 {
00065 if ( !m_dcop )
00066 m_dcop = new KIvioLayerIface( this );
00067 return m_dcop;
00068 }
00069
00070 KivioLayer::~KivioLayer()
00071 {
00072 kdDebug(43000)<<"KivioLayer::~KivioLayer()***************:"<<this<<endl;
00073 if( m_pStencilList )
00074 {
00075 delete m_pStencilList;
00076 m_pStencilList = NULL;
00077 }
00078 delete m_pDeletedStencilList;
00079 delete m_dcop;
00080 }
00081
00082 bool KivioLayer::addStencil( KivioStencil *pStencil )
00083 {
00084 int pos = m_pDeletedStencilList->findRef(pStencil);
00085 if ( pos != -1 )
00086 m_pDeletedStencilList->take( pos);
00087
00088 m_pStencilList->append( pStencil );
00089
00090 return true;
00091 }
00092
00093 void KivioLayer::takeStencilFromList( KivioStencil *pStencil )
00094 {
00095 int pos=m_pStencilList->findRef(pStencil);
00096 m_pStencilList->take( pos );
00097 m_pDeletedStencilList->append( pStencil );
00098 }
00099
00100 void KivioLayer::insertStencil( KivioStencil *pStencil )
00101 {
00102 int pos=m_pDeletedStencilList->findRef(pStencil);
00103 if ( pos != -1 )
00104 m_pDeletedStencilList->take( pos);
00105
00106 m_pStencilList->append( pStencil );
00107 }
00108
00109 bool KivioLayer::removeStencil( KivioStencil *pStencil )
00110 {
00111 return m_pStencilList->remove( pStencil );
00112 }
00113
00114
00127 KivioStencil *KivioLayer::loadSMLStencil( const QDomElement &stencilE )
00128 {
00129 QString setId, _id;
00130
00131 kdDebug(43000) << "KivioLayer::loadSMLStencil() " << setId << " " << _id << endl;
00132
00133 setId = XmlReadString( stencilE, "setId", "" );
00134 _id = XmlReadString( stencilE, "id", "" );
00135
00136
00137 if( setId.length() == 0 ||
00138 _id.length() == 0 )
00139 {
00140 return NULL;
00141 }
00142
00143
00144
00145 KivioStencilSpawner *pSpawner = m_pPage->doc()->findStencilSpawner(setId,_id);
00146 if( pSpawner )
00147 {
00148 KivioStencil *pStencil = pSpawner->newStencil();
00149 pStencil->loadXML( stencilE );
00150
00151 return pStencil;
00152 }
00153
00154 return NULL;
00155 }
00156
00169 KivioStencil *KivioLayer::loadGroupStencil( const QDomElement &stencilE )
00170 {
00171 kdDebug(43000) << "KivioLayer::loadGroupStencil()" << endl;
00172
00173 KivioGroupStencil *pStencil = new KivioGroupStencil();
00174
00175 if(pStencil->loadXML( stencilE, this )==false)
00176 {
00177 delete pStencil;
00178 return NULL;
00179 }
00180
00181 return pStencil;
00182 }
00183
00184 KivioStencil *KivioLayer::loadPluginStencil( const QDomElement &stencilE )
00185 {
00186 QString setId, _id;
00187
00188 kdDebug(43000) << "KivioLayer::loadPluginStencil() " << setId.ascii() << " / " << _id << endl;
00189
00190
00191 setId = XmlReadString( stencilE, "setId", "" );
00192 _id = XmlReadString( stencilE, "id", "" );
00193
00194
00195 if( setId.length() == 0 ||
00196 _id.length() == 0 )
00197 return NULL;
00198
00199
00200
00201 KivioStencilSpawner *pSpawner = m_pPage->doc()->findStencilSpawner(setId, _id);
00202 if( pSpawner )
00203 {
00204 KivioStencil *pStencil = pSpawner->newStencil();
00205 pStencil->loadXML( stencilE );
00206
00207 return pStencil;
00208 }
00209
00210 return NULL;
00211 }
00212
00213 bool KivioLayer::loadXML( const QDomElement &layerE )
00214 {
00215 m_flags = XmlReadInt( layerE, "flags", 1 );
00216 kdDebug(43000) << "Flags: " << m_flags << endl;
00217 m_name = XmlReadString( layerE, "name", "layerX" );
00218
00219 QDomNode node;
00220 node = layerE.firstChild();
00221 while( !node.isNull() )
00222 {
00223 QString name = node.nodeName();
00224 if( name == "KivioSMLStencil" || name == "KivioPyStencil" )
00225 {
00226 KivioStencil *pStencil = loadSMLStencil( node.toElement() );
00227 if( pStencil )
00228 {
00229 pStencil->updateGeometry();
00230 m_pStencilList->append( pStencil );
00231 }
00232 else
00233 {
00234 kdWarning(43000) << "KivioLayer::loadXML() - Unknown KivioSMLStencil (id=" <<
00235 XmlReadString( node.toElement(), "id", "" ) << " set=" <<
00236 XmlReadString( node.toElement(), "setId", "" ) << ") found." << endl;
00237 }
00238 }
00239 else if( name == "KivioGroupStencil" )
00240 {
00241 KivioStencil *pStencil = loadGroupStencil( node.toElement() );
00242 if( pStencil )
00243 {
00244 m_pStencilList->append(pStencil);
00245 }
00246 else
00247 {
00248 kdWarning(43000) << "KivioLayer::loadXML() - Unable to load KivioGroupStencil" << endl;
00249 }
00250 }
00251 else if( name == "KivioPluginStencil" )
00252 {
00253 KivioStencil *pStencil = loadPluginStencil( node.toElement() );
00254 if( pStencil )
00255 {
00256 m_pStencilList->append(pStencil);
00257 }
00258 else
00259 {
00260 kdWarning(43000) << "KivioLayer - Unable to load KivioPluginStencil" << endl;
00261 kdWarning(43000) << "KivioLayer::loadXML() - Unable to load KivioPluginStencil (id=" <<
00262 XmlReadString( node.toElement(), "id", "" ) << " set=" <<
00263 XmlReadString( node.toElement(), "setId", "" ) << ") found." << endl;
00264 }
00265 }
00266
00267 node = node.nextSibling();
00268 }
00269
00270 return true;
00271 }
00272
00273 void KivioLayer::loadOasis(const QDomElement& layer)
00274 {
00275 m_name = layer.attribute("draw:name");
00276
00277 }
00278
00279
00280 QDomElement KivioLayer::saveXML( QDomDocument &doc )
00281 {
00282 QDomElement e = doc.createElement("KivioLayer");
00283
00284 XmlWriteInt( e, "flags", m_flags );
00285 XmlWriteString( e, "name", m_name );
00286
00287 KivioStencil *pStencil = m_pStencilList->first();
00288 while( pStencil )
00289 {
00290 e.appendChild( pStencil->saveXML( doc ) );
00291
00292 pStencil = m_pStencilList->next();
00293 }
00294
00295 return e;
00296 }
00297
00298 void KivioLayer::saveOasis(KoXmlWriter* layerWriter)
00299 {
00300 layerWriter->startElement("draw:layer");
00301 layerWriter->addAttribute("draw:name", m_name);
00302
00303 layerWriter->endElement();
00304 }
00305
00306 void KivioLayer::paintContent( KivioPainter& painter, const QRect&, bool, QPoint,
00307 KoZoomHandler* zoom )
00308 {
00309 if(!visible()) {
00310 return;
00311 }
00312
00313 KivioStencil *pStencil = m_pStencilList->first();
00314 KivioIntraStencilData data;
00315
00316 painter.setFGColor( QColor(0,0,0) );
00317
00318 data.painter = &painter;
00319 data.zoomHandler = zoom;
00320
00321 while( pStencil )
00322 {
00323 if(!pStencil->hidden()) {
00324 pStencil->paint( &data );
00325 }
00326
00327 pStencil = m_pStencilList->next();
00328 }
00329 }
00330
00331 void KivioLayer::printContent( KivioPainter& painter, int xdpi, int ydpi )
00332 {
00333 if(!printable() || !visible())
00334 return;
00335
00336 if(!xdpi) {
00337 xdpi = KoGlobal::dpiX();
00338 }
00339
00340 if(!ydpi) {
00341 ydpi = KoGlobal::dpiY();
00342 }
00343
00344 KivioStencil *pStencil = m_pStencilList->first();
00345 KivioIntraStencilData data;
00346 KoZoomHandler zoomHandler;
00347 zoomHandler.setZoomAndResolution(100, xdpi, ydpi);
00348
00349 painter.setFGColor( QColor(0,0,0) );
00350
00351 data.painter = &painter;
00352 data.zoomHandler = &zoomHandler;
00353 data.printing = true;
00354
00355 while( pStencil )
00356 {
00357 pStencil->paint( &data );
00358
00359 pStencil = m_pStencilList->next();
00360 }
00361 }
00362
00363 void KivioLayer::printContent(KivioPainter& painter, KoZoomHandler* zoomHandler)
00364 {
00365 if(!printable() || !visible())
00366 return;
00367
00368 KivioStencil *pStencil = m_pStencilList->first();
00369 KivioIntraStencilData data;
00370
00371 painter.setFGColor( QColor(0,0,0) );
00372
00373 data.painter = &painter;
00374 data.zoomHandler = zoomHandler;
00375 data.printing = true;
00376
00377 while( pStencil )
00378 {
00379 pStencil->paint( &data );
00380
00381 pStencil = m_pStencilList->next();
00382 }
00383 }
00384
00385 void KivioLayer::paintConnectorTargets( KivioPainter& painter, const QRect&, bool, QPoint,
00386 KoZoomHandler* zoom )
00387 {
00388 if(!visible()) {
00389 return;
00390 }
00391
00392 KivioIntraStencilData data;
00393
00394 painter.setFGColor( QColor(0,0,0) );
00395
00396 data.painter = &painter;
00397 data.zoomHandler = zoom;
00398
00399 KivioStencil *pStencil = m_pStencilList->first();
00400 while( pStencil )
00401 {
00402 if(!pStencil->hidden()) {
00403 pStencil->paintConnectorTargets( &data );
00404 }
00405
00406 pStencil = m_pStencilList->next();
00407 }
00408 }
00409
00410 void KivioLayer::paintSelectionHandles( KivioPainter& painter, const QRect&, bool, QPoint, KoZoomHandler* zoom )
00411 {
00412 if(!visible()) {
00413 return;
00414 }
00415
00416 KivioIntraStencilData data;
00417
00418 painter.setFGColor( QColor(0,0,0) );
00419
00420 data.painter = &painter;
00421 data.zoomHandler = zoom;
00422
00423 KivioStencil *pStencil = m_pStencilList->first();
00424 while( pStencil )
00425 {
00426 if( pStencil->isSelected() && !pStencil->hidden() )
00427 pStencil->paintSelectionHandles( &data );
00428
00429 pStencil = m_pStencilList->next();
00430 }
00431 }
00432
00433 KivioStencil *KivioLayer::checkForStencil( KoPoint *pPoint, int *collisionType, float threshold, bool selectedOnly )
00434 {
00435 KivioStencil *pStencil;
00436 int colType;
00437
00438 if(editable()) {
00439 pStencil = m_pStencilList->last();
00440 while( pStencil )
00441 {
00442
00443
00444 if( (selectedOnly==true && pStencil->isSelected()==true) ||
00445 (selectedOnly==false) )
00446 {
00447 if( (colType = pStencil->checkForCollision( pPoint, threshold )) != kctNone )
00448 {
00449
00450 *collisionType = colType;
00451 return pStencil;
00452 }
00453 }
00454
00455 pStencil = m_pStencilList->prev();
00456 }
00457 }
00458
00459 *collisionType = kctNone;
00460
00461 return NULL;
00462 }
00463
00464 void KivioLayer::setVisible( bool f )
00465 {
00466 if( f==true )
00467 {
00468 m_flags = m_flags | FLOW_LAYER_VISIBLE;
00469 }
00470 else
00471 {
00472 m_flags = m_flags & (~FLOW_LAYER_VISIBLE);
00473 }
00474 }
00475
00476 void KivioLayer::setConnectable( bool f )
00477 {
00478 if( f==true )
00479 {
00480 m_flags = m_flags | FLOW_LAYER_CONNECTABLE;
00481 }
00482 else
00483 {
00484 m_flags = m_flags & (~FLOW_LAYER_CONNECTABLE);
00485 }
00486 }
00487
00488 void KivioLayer::setEditable(bool f)
00489 {
00490 if(f) {
00491 m_flags = m_flags & (~FLOW_LAYER_NOT_EDITABLE);
00492 } else {
00493 m_flags = m_flags | FLOW_LAYER_NOT_EDITABLE;
00494 }
00495 }
00496
00497 void KivioLayer::setPrintable(bool f)
00498 {
00499 if(f) {
00500 m_flags = m_flags & (~FLOW_LAYER_NOT_PRINTABLE);
00501 } else {
00502 m_flags = m_flags | FLOW_LAYER_NOT_PRINTABLE;
00503 }
00504 }
00505
00506 int KivioLayer::generateStencilIds( int next )
00507 {
00508 KivioStencil *pStencil;
00509
00510 pStencil = m_pStencilList->first();
00511 while( pStencil )
00512 {
00513 next = pStencil->generateIds( next );
00514
00515 pStencil = m_pStencilList->next();
00516 }
00517
00518 return next;
00519 }
00520
00521 void KivioLayer::searchForConnections( KivioPage *p )
00522 {
00523 KivioStencil *pStencil;
00524 KivioStencil *pCur;
00525
00526 pStencil = m_pStencilList->first();
00527 while( pStencil )
00528 {
00529
00530 pCur = pStencil;
00531
00532 pStencil->searchForConnections( p );
00533
00534
00535 m_pStencilList->find( pCur );
00536
00537 pStencil = m_pStencilList->next();
00538 }
00539 }
00540
00541 KivioStencil *KivioLayer::takeStencil( KivioStencil *p )
00542 {
00543 m_pStencilList->find( p );
00544
00545 return m_pStencilList->take();
00546 }
00547
00548
00556 KivioConnectorTarget *KivioLayer::connectPointToTarget( KivioConnectorPoint *p, float thresh )
00557 {
00558 KivioConnectorTarget *pTarget;
00559
00560 KivioStencil *pStencil = m_pStencilList->last();
00561 while( pStencil )
00562 {
00563
00564 if( pStencil != p->stencil() )
00565 {
00566 pTarget = pStencil->connectToTarget(p, thresh);
00567 if( pTarget )
00568 {
00569 return pTarget;
00570 }
00571 }
00572
00573 pStencil = m_pStencilList->prev();
00574 }
00575
00576 return NULL;
00577 }
00578
00579 KoPoint KivioLayer::snapToTarget( const KoPoint& p, double thresh, bool& hit )
00580 {
00581 KoPoint retVal = p;
00582 KivioStencil *pStencil = m_pStencilList->last();
00583
00584 while( pStencil && !hit)
00585 {
00586 retVal = pStencil->snapToTarget(p, thresh, hit);
00587 pStencil = m_pStencilList->prev();
00588 }
00589
00590 return retVal;
00591 }