kivio

sml_connector.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 <stdio.h>
00020 #include <math.h>
00021 #include "sml_connector.h"
00022 
00023 #include "kivio_common.h"
00024 #include "kivio_connector_target.h"
00025 #include "kivio_layer.h"
00026 #include "kivio_line_style.h"
00027 #include "kivio_page.h"
00028 #include "kivio_painter.h"
00029 #include "kivio_stencil.h"
00030 #include "kivio_stencil_spawner.h"
00031 #include "kivio_stencil_spawner_info.h"
00032 #include "kivio_stencil_spawner_set.h"
00033 #include "kivio_text_style.h"
00034 #include "kivio_shape.h"
00035 #include "kivio_shape_data.h"
00036 #include "kivio_point.h"
00037 
00038 #include "tkmath.h"
00039 
00040 #include <qcolor.h>
00041 #include <qpixmap.h>
00042 #include <kdebug.h>
00043 #include <KoZoomHandler.h>
00044 #include <kiconloader.h>
00045 
00046 static KivioStencilSpawnerInfo sinfo = KivioStencilSpawnerInfo( "Ian Reinhart Geiser", "SML Connector", "SML Connector", "SML Based Connector", "0.1", "http://localhost/", "", "off" );
00047 #include <kgenericfactory.h>
00048 
00049 K_EXPORT_COMPONENT_FACTORY( sml_connector, KGenericFactory<KivioSMLConnectorFactory>( "KivioSMLConnectorFactory" ) )
00050 
00051 KivioSMLConnectorFactory::KivioSMLConnectorFactory( QObject *parent, const char* name, const QStringList& args ) :
00052         KivioStencilFactory( parent, name, args )
00053 {
00054     kdDebug(43000) << "new sml stencil factory: " << endl;
00055 }
00056 
00057 KivioStencil *KivioSMLConnectorFactory::NewStencil( const QString& name )
00058 {
00059     return new KivioSMLConnector( name );
00060 }
00061 
00062 KivioStencil *KivioSMLConnectorFactory::NewStencil()
00063 {
00064     return new KivioSMLConnector( "basic_line" );
00065 }
00066 
00067 
00068 QPixmap *KivioSMLConnectorFactory::GetIcon()
00069 {
00070     return & BarIcon( "SML_conn" );
00071 }
00072 
00073 KivioStencilSpawnerInfo *KivioSMLConnectorFactory::GetSpawnerInfo()
00074 {
00075     return & sinfo;
00076 }
00077 
00078 KivioSMLConnector::KivioSMLConnector( const QString &name )
00079         : Kivio1DStencil(), m_name( name )
00080 {
00081 
00082     m_pStart->setPosition( 0.0f, 0.0f, false );
00083     m_pEnd->setPosition( 72.0f, 72.0f, false );
00084 
00085     m_startAH = new KivioArrowHead();
00086     m_endAH = new KivioArrowHead();
00087     m_needsWidth = false;
00088     m_needsText = true;
00089 
00090     m_pCanProtect->clearBit( kpAspect );
00091     m_pCanProtect->clearBit( kpWidth );
00092     m_pCanProtect->clearBit( kpHeight );
00093     m_pCanProtect->clearBit( kpX );
00094     m_pCanProtect->clearBit( kpY );
00095 
00096     // This is a stencil of type connector
00097     setType( kstConnector );
00098 
00099     // We only have one shape, an open path.
00100     //m_shape = new KivioShape();
00101     //m_shape->shapeData() ->setShapeType( KivioShapeData::kstOpenPath );
00102     loadPath( name );
00103 }
00104 
00105 KivioSMLConnector::~KivioSMLConnector()
00106 {
00107     delete m_startAH;
00108     delete m_endAH;
00109 }
00110 
00111 void KivioSMLConnector::setStartPoint( double x, double y )
00112 {
00113     m_pStart->setPosition( x, y, false );
00114     m_pStart->disconnect();
00115 
00116     if ( m_needsText )
00117     {
00118         m_pTextConn->setPosition( ( m_pEnd->x() + m_pStart->x() ) / 2.0f,
00119                                   ( m_pEnd->y() + m_pStart->y() ) / 2.0f,
00120                                   false );
00121     }
00122 
00123     // Set list end point
00124     m_pConnectorPoints ->first() ->setX( x );
00125     m_pConnectorPoints ->first() ->setY( y );
00126 
00127 }
00128 
00129 void KivioSMLConnector::setEndPoint( double x, double y )
00130 {
00131     m_pEnd->setPosition( x, y, false );
00132     m_pEnd->disconnect();
00133     m_pConnectorPoints ->last() ->setX( x );
00134     m_pConnectorPoints ->last() ->setY( y );
00135 }
00136 
00137 KivioCollisionType KivioSMLConnector::checkForCollision( KivioPoint *p, double threshold )
00138 {
00139     const double end_thresh = 4.0f;
00140 
00141     double px = p->x();
00142     double py = p->y();
00143 
00144     KivioConnectorPoint *pPoint;
00145 
00146     int i = kctCustom + 1;
00147     pPoint = m_pConnectorPoints->first();
00148     while ( pPoint )
00149     {
00150         if ( px >= pPoint->x() - end_thresh &&
00151                 px <= pPoint->x() + end_thresh &&
00152                 py >= pPoint->y() - end_thresh &&
00153                 py <= pPoint->y() + end_thresh )
00154         {
00155             return ( KivioCollisionType ) i;
00156         }
00157 
00158         i++;
00159         pPoint = m_pConnectorPoints->next();
00160     }
00161 
00162 
00163     if ( collisionLine( m_pStart->x(), m_pStart->y(),
00164                         m_pEnd->x(), m_pEnd->y(),
00165                         px, py,
00166                         threshold ) )
00167     {
00168         return kctBody;
00169     }
00170 
00171     return kctNone;
00172 }
00173 
00174 KivioStencil *KivioSMLConnector::duplicate()
00175 {
00176     KivioSMLConnector * pStencil = new KivioSMLConnector( m_name );
00177 
00178 
00179     // TODO: Copy internal pointlist information?
00180 
00181     // Copy the arrow head information
00182     pStencil->setStartAHType( m_startAH->type() );
00183     pStencil->setStartAHWidth( m_startAH->width() );
00184     pStencil->setStartAHLength( m_startAH->length() );
00185 
00186     pStencil->setEndAHType( m_endAH->type() );
00187     pStencil->setEndAHWidth( m_endAH->width() );
00188     pStencil->setEndAHLength( m_endAH->length() );
00189 
00190     *( pStencil->protection() ) = *m_pProtection;
00191     *( pStencil->canProtect() ) = *m_pCanProtect;
00192 
00193     return pStencil;
00194 }
00195 /*
00196 void KivioSMLConnector::drawOpenPath( KivioShape *pShape, KivioIntraStencilData *pData )
00197 {
00198     KivioPainter * painter;
00199     KivioShapeData *pShapeData = pShape->shapeData();
00200     KivioPoint *pPoint, *pNewPoint;
00201     QPtrList <KivioPoint> *pPointList = pShapeData->pointList();
00202 
00203     QPtrList <KivioPoint> *pNewPoints = new QPtrList<KivioPoint>;
00204     pNewPoints->setAutoDelete( true );
00205 
00206     pPoint = pPointList->first();
00207     while ( pPoint )
00208     {
00209         pNewPoint = new KivioPoint( pData->zoomHandler->zoomItX( pPoint->x() ),
00210                                     pData->zoomHandler->zoomItY( pPoint->y() ),
00211                                     pPoint->pointType() );
00212         pNewPoints->append( pNewPoint );
00213 
00214         pPoint = pPointList->next();
00215     }
00216 
00217     painter = pData->painter;
00218     double lineWidth = pShapeData->lineStyle() ->width();
00219     painter->setLineWidth( pData->zoomHandler->zoomItY( lineWidth ) );
00220     painter->setFGColor( pShapeData->lineStyle() ->color() );
00221 
00222     painter->drawOpenPath( pNewPoints );
00223     delete pNewPoints;
00224 }
00225 */
00226 void KivioSMLConnector::paint( KivioIntraStencilData *pData )
00227 {
00228     KivioPainter * painter = pData->painter;
00229     KoZoomHandler* zoomHandler = pData->zoomHandler;
00230     double x1, y1, x2, y2;
00231     double vecX, vecY;
00232     double len;
00233 
00234 
00235     painter->setFGColor( m_pLineStyle->color() );
00236     painter->setLineWidth( zoomHandler->zoomItY( m_pLineStyle->width() ) );
00237 
00238     x1 = zoomHandler->zoomItX( m_pStart->x() );
00239     x2 = zoomHandler->zoomItX( m_pEnd->x() );
00240 
00241     y1 = zoomHandler->zoomItY( m_pStart->y() );
00242     y2 = zoomHandler->zoomItY( m_pEnd->y() );
00243 
00244 
00245     // Calculate the direction vector from start -> end
00246     vecX = m_pEnd->x() - m_pStart->x();
00247     vecY = m_pEnd->y() - m_pStart->y();
00248 
00249     // Normalize the vector
00250     len = sqrt( vecX * vecX + vecY * vecY );
00251     if ( len )
00252     {
00253         vecX /= len;
00254         vecY /= len;
00255 
00256         // Move the endpoints by the cuts
00257         x1 += vecX * zoomHandler->zoomItX( m_startAH->cut() );
00258         y1 += vecY * zoomHandler->zoomItY( m_startAH->cut() );
00259 
00260         x2 -= vecX * zoomHandler->zoomItX( m_endAH->cut() );
00261         y2 -= vecY * zoomHandler->zoomItY( m_endAH->cut() );
00262     }
00263 
00264 
00265     // Build shape up from m_pConnectorPoints
00266 
00267 
00268     QPtrList <KivioPoint> *pNewPoints = new QPtrList<KivioPoint>;
00269     pNewPoints->setAutoDelete( true );
00270 
00271     pNewPoints->append(new KivioPoint( zoomHandler->zoomItX( m_pStart->x() ),
00272                                     zoomHandler->zoomItY( m_pStart->y() )));
00273 
00274     KivioConnectorPoint *pPoint = m_PointList.first();
00275     while ( pPoint )
00276     {
00277         KivioPoint *pNewPoint = new KivioPoint( zoomHandler->zoomItX( pPoint->x() ),
00278                                     zoomHandler->zoomItY( pPoint->y() ));
00279         pNewPoints->append( pNewPoint );
00280 
00281         pPoint = m_PointList.next();
00282     }
00283 
00284     pNewPoints->append(new KivioPoint( zoomHandler->zoomItX( m_pEnd->x() ),
00285                                     zoomHandler->zoomItY( m_pEnd->y() )));
00286     painter = pData->painter;
00287     double lineWidth = m_pLineStyle ->width();
00288     painter->setLineWidth( zoomHandler->zoomItY( lineWidth ) );
00289     painter->setFGColor( m_pLineStyle ->color() );
00290 
00291     painter->drawOpenPath( pNewPoints );
00292     delete pNewPoints;
00293 
00294     // Now draw the arrow heads
00295     if ( len )
00296     {
00297         painter->setBGColor( m_pFillStyle->color() );
00298 
00299         m_startAH->paint( painter, m_pStart->x(), m_pStart->y(), -vecX, -vecY, zoomHandler );
00300         m_endAH->paint( painter, m_pEnd->x(), m_pEnd->y(), vecX, vecY, zoomHandler );
00301     }
00302 
00303     // TODO: Text
00304     drawText( pData );
00305 }
00306 
00307 void KivioSMLConnector::paintOutline( KivioIntraStencilData *pData )
00308 {
00309     paint( pData );
00310 }
00311 
00312 bool KivioSMLConnector::saveCustom( QDomElement &e, QDomDocument &doc )
00313 {
00314     kdDebug(43000) << "Save custom " << endl;
00315     e.appendChild( saveArrowHeads( doc ) );
00316 
00317     //QDomElement type = m_shape->saveXML(doc);
00318     KivioConnectorPoint *p = m_PointList.first();
00319     while ( p )
00320     {
00321             QDomElement pt = p->saveXML( doc );
00322             e.appendChild( pt );
00323             p = m_PointList.next();
00324     }
00325     return true;
00326 }
00327 
00328 bool KivioSMLConnector::loadCustom( const QDomElement &e )
00329 {
00330     kdDebug(43000) << "Load custom " << endl;
00331     QDomNode node;
00332     QString name;
00333 
00334     node = e.firstChild();
00335     while ( !node.isNull() )
00336     {
00337         name = node.nodeName();
00338         if ( name == "KivioArrowHeads" )
00339         {
00340             loadArrowHeads( node.toElement() );
00341         }
00342         else if ( name == "KivioShape" )
00343         {
00344             //m_shape->loadXML(node.toElement());
00345             QDomNode pts = node.firstChild();
00346             while ( !pts.isNull() )
00347             {
00348                 KivioConnectorPoint * pt = new KivioConnectorPoint();
00349                 pt->loadXML( pts.toElement() );
00350                 m_pConnectorPoints->append( pt );
00351                 m_PointList.append( pt );
00352                 pts = pts.nextSibling();
00353             }
00354         }
00355         node = node.nextSibling();
00356     }
00357 
00358     updateGeometry();
00359 
00360     return true;
00361 }
00362 
00363 QDomElement KivioSMLConnector::saveArrowHeads( QDomDocument &doc )
00364 {
00365     QDomElement e = doc.createElement( "KivioArrowHeads" );
00366 
00367     e.appendChild( m_startAH->saveXML( doc ) );
00368     e.appendChild( m_endAH->saveXML( doc ) );
00369 
00370     return e;
00371 }
00372 
00373 bool KivioSMLConnector::loadArrowHeads( const QDomElement &e )
00374 {
00375     QDomNode node;
00376     QString nodeName;
00377     QDomElement arrowE;
00378     bool first = true;
00379 
00380     node = e.firstChild();
00381     while ( !node.isNull() )
00382     {
00383         nodeName = node.nodeName();
00384         arrowE = node.toElement();
00385 
00386         if ( nodeName == "KivioArrowHead" )
00387         {
00388             if ( first == true )
00389             {
00390                 m_startAH->loadXML( arrowE );
00391 
00392                 first = false;
00393             }
00394             else
00395             {
00396                 m_endAH->loadXML( arrowE );
00397             }
00398         }
00399 
00400         node = node.nextSibling();
00401     }
00402 
00403     return true;
00404 }
00405 
00406 
00407 bool KivioSMLConnector::loadPath( const QString &file )
00408 {
00409     kdDebug(43000) << "Loading :" << file << endl;
00410 
00411     m_PointList.clear();
00412     m_PointList.append(m_pStart);
00413 
00414     KivioConnectorPoint *pt = new KivioConnectorPoint(this,false);
00415     pt->setPosition(m_pStart->x()+10,m_pStart->y()+10,false);
00416 //  m_PointList.append( pt );
00417     m_pConnectorPoints->append(pt);
00418 
00419     pt = new KivioConnectorPoint(this,false);
00420     pt->setPosition(m_pStart->x()+20,m_pStart->y()+20,false);
00421     m_PointList.append( pt );
00422     m_pConnectorPoints->append(pt);
00423 
00424     pt = new KivioConnectorPoint(this,false);
00425     pt->setPosition(m_pStart->x()+30,m_pStart->y()+30,false);
00426     m_PointList.append( pt );
00427     m_pConnectorPoints->append(pt);
00428 
00429 //  m_PointList.append(m_pEnd);
00430     m_name = file;
00431         return true;
00432 }
00433 
00434 #include "sml_connector.moc"
KDE Home | KDE Accessibility Home | Description of Access Keys