kivio

kivio_layer.cpp

00001 /*
00002  * Kivio - Visual Modelling and Flowcharting
00003  * Copyright (C) 2000-2001 theKompany.com & Dave Marotti
00004  *
00005  * This program is free software; you can redistribute it and/or
00006  * modify it under the terms of the GNU General Public License
00007  * as published by the Free Software Foundation; either version 2
00008  * of the License, or (at your option) any later version.
00009  *
00010  * This program is distributed in the hope that it will be useful,
00011  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013  * GNU General Public License for more details.
00014  *
00015  * You should have received a copy of the GNU General Public License
00016  * along with this program; if not, write to the Free Software
00017  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
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     // Locate the spawner set
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     // Locate the spawner set
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   // TODO OASIS Load flags
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   // TODO OASIS Save flags
00303   layerWriter->endElement(); // draw:layer
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         // If we are only supposed to check the selected stencils, then only do that.  Otherwise
00443         // check them all.
00444         if( (selectedOnly==true && pStencil->isSelected()==true) ||
00445           (selectedOnly==false) )
00446         {
00447           if( (colType = pStencil->checkForCollision( pPoint, threshold )) != kctNone )
00448           {
00449             // Assign the collision type and return
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         // Backup the current list position
00530         pCur = pStencil;
00531 
00532         pStencil->searchForConnections( p );
00533 
00534         // Restore it
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         // Don't allow the connector point to connect to the stencil that owns it
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 }
KDE Home | KDE Accessibility Home | Description of Access Keys