kivio

straight_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 "straight_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 "tkmath.h"
00035 
00036 #include <qcolor.h>
00037 #include <qpixmap.h>
00038 #include <kdebug.h>
00039 #include <KoZoomHandler.h>
00040 
00041 #include "straight_connector.xpm"
00042 
00043 
00044 static QPixmap *pIcon = NULL;
00045 
00046 static KivioStencilSpawnerInfo sinfo = KivioStencilSpawnerInfo("Dave Marotti", "Straight Connector", "Dave Marotti - Straight Connector", "Basic Straight Connector", "0.1", "http://localhost/", "", "off");
00047 
00048 #include <kgenericfactory.h>
00049 K_EXPORT_COMPONENT_FACTORY( straight_connector, KGenericFactory<KivioConnectorFactory>( "KivioConnectorFactory" ) )
00050 
00051 KivioConnectorFactory::KivioConnectorFactory(QObject *parent, const char* name, const QStringList& args) :
00052     KivioStencilFactory(parent, name, args)
00053 {
00054     kdDebug(43000) << "new straight line connector factory: " << endl;
00055 }
00056 
00057 KivioStencil *KivioConnectorFactory::NewStencil()
00058 {
00059     return new KivioStraightConnector();
00060 }
00061 
00062 KivioStencil *KivioConnectorFactory::NewStencil(const QString&)
00063 {
00064     return new KivioStraightConnector();
00065 }
00066 
00067 //FIXME: Is this a memory leak?
00068 QPixmap *KivioConnectorFactory::GetIcon()
00069 {
00070     if( pIcon )
00071         return pIcon;
00072 
00073     pIcon = new QPixmap( (const char **)straight_connector_xpm );
00074     return pIcon;
00075 }
00076 
00077 KivioStencilSpawnerInfo *KivioConnectorFactory::GetSpawnerInfo()
00078 {
00079     return &sinfo;
00080 }
00081 
00082 
00083 KivioStraightConnector::KivioStraightConnector()
00084    : Kivio1DStencil()
00085 {
00086    m_pStart->setPosition(0.0f, 0.0f, false);
00087    m_pEnd->setPosition(72.0f, 72.0f, false);
00088 
00089    m_startAH = new KivioArrowHead();
00090    m_endAH = new KivioArrowHead();
00091    m_needsWidth = false;
00092    m_needsText = true;
00093 
00094    m_pCanProtect->clearBit( kpAspect );
00095    m_pCanProtect->clearBit( kpWidth );
00096    m_pCanProtect->clearBit( kpHeight );
00097    m_pCanProtect->clearBit( kpX );
00098    m_pCanProtect->clearBit( kpY );
00099 
00100    // This is a stencil of type connector
00101    setType(kstConnector);
00102 }
00103 
00104 KivioStraightConnector::~KivioStraightConnector()
00105 {
00106    delete m_startAH;
00107    delete m_endAH;
00108 }
00109 
00110 void KivioStraightConnector::setStartPoint( double x, double y )
00111 {
00112     m_pStart->setPosition( x, y, false );
00113     m_pStart->disconnect();
00114 }
00115 
00116 void KivioStraightConnector::setEndPoint( double x, double y )
00117 {
00118     m_pEnd->setPosition( x, y, false );
00119     m_pEnd->disconnect();
00120 
00121     if( m_needsText )
00122     {
00123        m_pTextConn->setPosition( (m_pStart->x()+m_pEnd->x())/2.0f,
00124         (m_pStart->y()+m_pEnd->y())/2.0f,
00125         false );
00126     }
00127 }
00128 
00129 KivioCollisionType KivioStraightConnector::checkForCollision( KoPoint *p, double threshold )
00130 {
00131     const double end_thresh = 4.0f;
00132 
00133     double px = p->x();
00134     double py = p->y();
00135 
00136     KivioConnectorPoint *pPoint;
00137 
00138     int i = kctCustom + 1;
00139     pPoint = m_pConnectorPoints->first();
00140     while( pPoint )
00141     {
00142         if( px >= pPoint->x() - end_thresh &&
00143             px <= pPoint->x() + end_thresh &&
00144             py >= pPoint->y() - end_thresh &&
00145             py <= pPoint->y() + end_thresh )
00146         {
00147             return (KivioCollisionType)i;
00148         }
00149 
00150         i++;
00151         pPoint = m_pConnectorPoints->next();
00152     }
00153 
00154 
00155     if( collisionLine( m_pStart->x(), m_pStart->y(),
00156           m_pEnd->x(), m_pEnd->y(),
00157           px, py,
00158           threshold ) )
00159     {
00160       return kctBody;
00161     }
00162 
00163     return kctNone;
00164 }
00165 
00166 KivioStencil *KivioStraightConnector::duplicate()
00167 {
00168     KivioStraightConnector *pStencil = new KivioStraightConnector();
00169 
00170     copyBasicInto( pStencil );
00171 
00172     // Copy the arrow head information
00173     pStencil->setStartAHType( m_startAH->type() );
00174     pStencil->setStartAHWidth( m_startAH->width() );
00175     pStencil->setStartAHLength( m_startAH->length() );
00176 
00177     pStencil->setEndAHType( m_endAH->type() );
00178     pStencil->setEndAHWidth( m_endAH->width() );
00179     pStencil->setEndAHLength( m_endAH->length() );
00180 
00181     *(pStencil->protection()) = *m_pProtection;
00182     *(pStencil->canProtect()) = *m_pCanProtect;
00183 
00184     return pStencil;
00185 }
00186 
00187 void KivioStraightConnector::paint( KivioIntraStencilData *pData )
00188 {
00189   KivioPainter *painter = pData->painter;
00190   KoZoomHandler* zoomHandler = pData->zoomHandler;
00191   double x1, y1, x2, y2;
00192   double vecX, vecY;
00193   double len;
00194 
00195 
00196   painter->setLineStyle(m_pLineStyle);
00197   double lineWidth = m_pLineStyle->width();
00198   painter->setLineWidth(zoomHandler->zoomItY(lineWidth));
00199 
00200   x1 = zoomHandler->zoomItX(m_pStart->x());
00201   x2 = zoomHandler->zoomItX(m_pEnd->x());
00202 
00203   y1 = zoomHandler->zoomItY(m_pStart->y());
00204   y2 = zoomHandler->zoomItY(m_pEnd->y());
00205 
00206 
00207   // Calculate the direction vector from start -> end
00208   vecX = m_pEnd->x() - m_pStart->x();
00209   vecY = m_pEnd->y() - m_pStart->y();
00210 
00211   // Normalize the vector
00212   len = sqrt( vecX*vecX + vecY*vecY );
00213   if( len )
00214   {
00215     vecX /= len;
00216     vecY /= len;
00217 
00218     // Move the endpoints by the cuts
00219     x1 += vecX * zoomHandler->zoomItX(m_startAH->cut());
00220     y1 += vecY * zoomHandler->zoomItY(m_startAH->cut());
00221 
00222     x2 -= vecX * zoomHandler->zoomItX(m_endAH->cut());
00223     y2 -= vecY * zoomHandler->zoomItY(m_endAH->cut());
00224   }
00225 
00226 
00227   // Draw the line
00228   painter->drawLine( x1, y1, x2, y2 );
00229 
00230 
00231   // Now draw the arrow heads
00232   if( len )
00233   {
00234     painter->setBGColor( m_pFillStyle->color() );
00235 
00236     m_startAH->paint(painter, m_pStart->x(), m_pStart->y(), -vecX, -vecY, zoomHandler);
00237     m_endAH->paint(painter, m_pEnd->x(), m_pEnd->y(), vecX, vecY, zoomHandler);
00238   }
00239 
00240   // Text
00241   drawText(pData);
00242 }
00243 
00244 void KivioStraightConnector::paintOutline( KivioIntraStencilData *pData )
00245 {
00246   KivioPainter *painter = pData->painter;
00247   KoZoomHandler* zoomHandler = pData->zoomHandler;
00248   double x1, y1, x2, y2;
00249   double vecX, vecY;
00250   double len;
00251 
00252 
00253   painter->setLineStyle(m_pLineStyle);
00254   double lineWidth = m_pLineStyle->width();
00255   painter->setLineWidth(zoomHandler->zoomItY(lineWidth));
00256 
00257   x1 = zoomHandler->zoomItX(m_pStart->x());
00258   x2 = zoomHandler->zoomItX(m_pEnd->x());
00259 
00260   y1 = zoomHandler->zoomItY(m_pStart->y());
00261   y2 = zoomHandler->zoomItY(m_pEnd->y());
00262 
00263 
00264   // Calculate the direction vector from start -> end
00265   vecX = m_pEnd->x() - m_pStart->x();
00266   vecY = m_pEnd->y() - m_pStart->y();
00267 
00268   // Normalize the vector
00269   len = sqrt( vecX*vecX + vecY*vecY );
00270   if( len )
00271   {
00272     vecX /= len;
00273     vecY /= len;
00274 
00275     // Move the endpoints by the cuts
00276     x1 += vecX * zoomHandler->zoomItX(m_startAH->cut());
00277     y1 += vecY * zoomHandler->zoomItY(m_startAH->cut());
00278 
00279     x2 -= vecX * zoomHandler->zoomItX(m_endAH->cut());
00280     y2 -= vecY * zoomHandler->zoomItY(m_endAH->cut());
00281   }
00282 
00283 
00284   // Draw the line
00285   painter->drawLine( x1, y1, x2, y2 );
00286 
00287 
00288   // Now draw the arrow heads
00289   if( len )
00290   {
00291     painter->setBGColor( m_pFillStyle->color() );
00292 
00293     m_startAH->paint(painter, m_pStart->x(), m_pStart->y(), -vecX, -vecY, zoomHandler);
00294     m_endAH->paint(painter, m_pEnd->x(), m_pEnd->y(), vecX, vecY, zoomHandler);
00295   }
00296 
00297   // Text
00298   // Don't paint text in outline mode as it makes moving harder
00299   drawText(pData);
00300 }
00301 
00302 bool KivioStraightConnector::saveCustom( QDomElement &e, QDomDocument &doc )
00303 {
00304    e.appendChild( saveArrowHeads(doc) );
00305 
00306    return true;
00307 }
00308 
00309 bool KivioStraightConnector::loadCustom( const QDomElement &e )
00310 {
00311    QDomNode node;
00312    QString name;
00313 
00314    node = e.firstChild();
00315    while( !node.isNull() )
00316    {
00317       name = node.nodeName();
00318       if( name == "KivioArrowHeads" )
00319       {
00320      loadArrowHeads( node.toElement() );
00321       }
00322 
00323       node = node.nextSibling();
00324    }
00325 
00326    updateGeometry();
00327 
00328    return true;
00329 }
00330 
00331 QDomElement KivioStraightConnector::saveArrowHeads( QDomDocument &doc )
00332 {
00333     QDomElement e = doc.createElement("KivioArrowHeads");
00334 
00335     e.appendChild( m_startAH->saveXML(doc) );
00336     e.appendChild( m_endAH->saveXML(doc) );
00337 
00338     return e;
00339 }
00340 
00341 bool KivioStraightConnector::loadArrowHeads( const QDomElement &e )
00342 {
00343     QDomNode node;
00344     QString nodeName;
00345     QDomElement arrowE;
00346     bool first=true;
00347 
00348     node = e.firstChild();
00349     while( !node.isNull() )
00350     {
00351         nodeName = node.nodeName();
00352         arrowE = node.toElement();
00353 
00354         if( nodeName == "KivioArrowHead" )
00355         {
00356             if( first==true )
00357             {
00358                 m_startAH->loadXML(arrowE);
00359 
00360                 first = false;
00361             }
00362             else
00363             {
00364                 m_endAH->loadXML(arrowE);
00365             }
00366         }
00367 
00368         node = node.nextSibling();
00369     }
00370 
00371     return true;
00372 }
00373 
00374 bool KivioStraightConnector::hasTextBox() const
00375 {
00376   return true;
00377 }
00378 
00379 #include "straight_connector.moc"
KDE Home | KDE Accessibility Home | Description of Access Keys