kivio

kivio_1d_stencil.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 
00020 /*
00021  * Implementing a connector involves deriving from this class.
00022  *
00023  * You need to implement the following routines:
00024  *   setStartPoint
00025  *   setEndPoint
00026  *   checkForCollision
00027  *   duplicate
00028  *   paint
00029  *   paintOutline
00030  *   saveXML
00031  *   loadXML
00032  *
00033  * Save and Load should call saveConnectors, loadConnectors, saveProperties, and
00034  * loadProperties.  These are helper functions which take care of the common
00035  * acts of saving/loading connectors and colors/line-styles, etc...
00036  *
00037  */
00038 
00039 #include "kivio_1d_stencil.h"
00040 #include "kivio_arrowhead.h"
00041 #include "kivio_common.h"
00042 #include "kivio_connector_point.h"
00043 #include "kivio_custom_drag_data.h"
00044 #include "kivio_fill_style.h"
00045 #include "kivio_intra_stencil_data.h"
00046 #include "kivio_layer.h"
00047 #include "kivio_line_style.h"
00048 #include "kivio_page.h"
00049 #include "kivio_painter.h"
00050 #include "kivio_point.h"
00051 #include "kivio_stencil.h"
00052 #include "kivio_stencil_spawner.h"
00053 #include "kivio_stencil_spawner_info.h"
00054 #include "kivio_stencil_spawner_set.h"
00055 #include "kivio_text_style.h"
00056 #include "kivio_connector_target.h"
00057 
00058 #include <kdebug.h>
00059 #include <math.h>
00060 #include <KoZoomHandler.h>
00061 
00062 #include <qbitmap.h>
00063 #include <qpainter.h>
00064 
00071 Kivio1DStencil::Kivio1DStencil()
00072     : KivioStencil()
00073 {
00074     m_pFillStyle = new KivioFillStyle();
00075     m_pLineStyle = new KivioLineStyle();
00076     m_pTextStyle = new KivioTextStyle();
00077 
00078     m_pConnectorPoints = new QPtrList<KivioConnectorPoint>;
00079     m_pConnectorPoints->setAutoDelete(true);
00080 
00081     m_pStart = new KivioConnectorPoint(this, true);
00082     m_pStart->setPosition(72.0f, 18.0f, false);
00083 
00084     m_pEnd = new KivioConnectorPoint(this, true);
00085     m_pEnd->setPosition(0.0f, 18.0f, false);
00086 
00087     m_pLeft = new KivioConnectorPoint(this, false);
00088     m_pLeft->setPosition(36.0f, 36.0f, false);
00089 
00090     m_pRight = new KivioConnectorPoint(this, false);
00091     m_pRight->setPosition(36.0f, 0.0f, false);
00092 
00093     m_pTextConn = new KivioConnectorPoint(this, false);
00094     m_pTextConn->setPosition(36.0f, 18.0f, false);
00095 
00096     m_connectorWidth = 36.0f;
00097     m_needsWidth = true;
00098     m_needsText = false;
00099 
00100     m_pConnectorPoints->append( m_pStart );
00101     m_pConnectorPoints->append( m_pEnd );
00102     m_pConnectorPoints->append( m_pLeft );
00103     m_pConnectorPoints->append( m_pRight );
00104     m_pConnectorPoints->append( m_pTextConn );
00105 }
00106 
00107 
00111 Kivio1DStencil::~Kivio1DStencil()
00112 {
00113    delete m_pFillStyle;
00114    delete m_pLineStyle;
00115    delete m_pTextStyle;
00116    delete m_pConnectorPoints;
00117 }
00118 
00119 void Kivio1DStencil::setFGColor( QColor c )
00120 {
00121     m_pLineStyle->setColor(c);
00122 }
00123 
00124 QColor Kivio1DStencil::fgColor()
00125 {
00126     return m_pLineStyle->color();
00127 }
00128 
00129 void Kivio1DStencil::setLineWidth( double f )
00130 {
00131     m_pLineStyle->setWidth(f);
00132 }
00133 
00134 double Kivio1DStencil::lineWidth()
00135 {
00136     return m_pLineStyle->width();
00137 }
00138 
00139 void Kivio1DStencil::setLinePattern(int p)
00140 {
00141     m_pLineStyle->setStyle(p);
00142 }
00143 
00144 int Kivio1DStencil::linePattern()
00145 {
00146     return m_pLineStyle->style();
00147 }
00148 
00149 void Kivio1DStencil::setFillPattern(int p)
00150 {
00151     m_pFillStyle->setBrushStyle(static_cast<Qt::BrushStyle>(p));
00152 }
00153 
00154 int Kivio1DStencil::fillPattern()
00155 {
00156     return m_pFillStyle->brushStyle();
00157 }
00158 
00159 void Kivio1DStencil::setBGColor( QColor c )
00160 {
00161     m_pFillStyle->setColor(c);
00162 }
00163 
00164 QColor Kivio1DStencil::bgColor()
00165 {
00166     return m_pFillStyle->color();
00167 }
00168 
00169 
00171 // Position functions
00173 void Kivio1DStencil::setX( double x )
00174 {
00175   double dx = x - m_x;
00176   KivioConnectorPoint *p = m_pConnectorPoints->first();
00177 
00178   while( p )
00179   {
00180     p->disconnect();
00181     p->setX( p->x() + dx, false );
00182     p = m_pConnectorPoints->next();
00183   }
00184 
00185   m_x = x;
00186 }
00187 
00188 void Kivio1DStencil::setY( double y )
00189 {
00190   double dy = y - m_y;
00191   KivioConnectorPoint *p = m_pConnectorPoints->first();
00192 
00193   while( p )
00194   {
00195     p->disconnect();
00196     p->setY( p->y() + dy, false );
00197     p = m_pConnectorPoints->next();
00198   }
00199 
00200   m_y = y;
00201 }
00202 
00203 void Kivio1DStencil::setPosition( double x, double y )
00204 {
00205     double dx = x - m_x;
00206     double dy = y - m_y;
00207 
00208     m_x += dx;
00209     m_y += dy;
00210 
00211     KivioConnectorPoint *p = m_pConnectorPoints->first();
00212     while( p )
00213     {
00214         p->setPosition( p->x()+dx, p->y()+dy, false );
00215         p->disconnect();
00216 
00217         p = m_pConnectorPoints->next();
00218     }
00219 
00220 
00221     m_x = x;
00222     m_y = y;
00223 }
00224 
00225 
00226 
00228 // Connection tool functions
00230 void Kivio1DStencil::setStartPoint( double x, double y )
00231 {
00232    double oldX = m_pStart->x();
00233    double oldY = m_pStart->y();
00234 
00235    m_pStart->setPosition(x, y, false);
00236    m_pStart->disconnect();
00237 
00238    updateConnectorPoints(m_pStart, oldX, oldY);
00239 }
00240 
00241 
00242 void Kivio1DStencil::setEndPoint( double x, double y )
00243 {
00244    double oldX = m_pEnd->x();
00245    double oldY = m_pEnd->y();
00246 
00247    m_pEnd->setPosition(x, y, false);
00248    m_pEnd->disconnect();
00249 
00250    updateConnectorPoints(m_pEnd, oldX, oldY);
00251 }
00252 
00253 void Kivio1DStencil::updateConnectorPoints( KivioConnectorPoint *p, double /*oldX*/, double /*oldY*/ )
00254 {
00255    // If p is the start or end, we need to adjust the width connectors
00256    if( p == m_pStart || p == m_pEnd )
00257    {
00258       double vx = m_pStart->x() - m_pEnd->x();
00259       double vy = m_pStart->y() - m_pEnd->y();
00260       double len = sqrt( vx*vx + vy*vy );
00261       double midX = (m_pStart->x() + m_pEnd->x())/2.0f;
00262       double midY = (m_pStart->y() + m_pEnd->y())/2.0f;
00263 
00264       vx /= len;
00265       vy /= len;
00266 
00267       double d = m_connectorWidth/2.0f;
00268 
00269       m_pLeft->setPosition( midX + d*vy, midY + d*(-vx), false );
00270       m_pRight->setPosition( midX + d*(-vy), midY + d*vx, false );
00271    }
00272 
00273    updateGeometry();
00274 }
00275 
00276 
00277 void Kivio1DStencil::paint( KivioIntraStencilData * )
00278 {
00279     /* Derived class must implement this */
00280 }
00281 
00282 void Kivio1DStencil::paintOutline( KivioIntraStencilData *pData )
00283 {
00284     /* Derived class should implement this */
00285     paint( pData );
00286 }
00287 
00288 void Kivio1DStencil::paintConnectorTargets( KivioIntraStencilData * )
00289 {
00290 }
00291 
00292 void Kivio1DStencil::paintSelectionHandles( KivioIntraStencilData *pData )
00293 {
00294   KivioPainter *painter = pData->painter;
00295   double x1, y1;
00296   int flag;
00297 
00298   KoZoomHandler* zoomHandler = pData->zoomHandler;
00299 
00300   KivioConnectorPoint *p = m_pConnectorPoints->first();
00301   while( p )
00302   {
00303     // If we don't need width connectors and we are on a width connector,
00304     // ignore it.
00305     x1 = zoomHandler->zoomItX(p->x());
00306     y1 = zoomHandler->zoomItY(p->y());
00307 
00308     flag = (p->target()) ? KivioPainter::cpfConnected : 0;
00309 
00310     if( p==m_pTextConn )
00311     {
00312       if( m_needsText==true )
00313       {
00314         painter->drawHandle( x1, y1, 0 );
00315       }
00316     }
00317     else if( p==m_pLeft || p==m_pRight )
00318     {
00319       if( m_needsWidth==true )
00320       {
00321         painter->drawHandle( x1, y1, 0 );
00322       }
00323     }
00324     else if( p==m_pStart )
00325     {
00326       painter->drawHandle( x1, y1, KivioPainter::cpfStart | flag );
00327     }
00328     else if( p==m_pEnd )
00329     {
00330       painter->drawHandle( x1, y1, KivioPainter::cpfEnd | flag );
00331     }
00332     else
00333     {
00334       if( p->connectable() ) {
00335         painter->drawHandle( x1, y1, KivioPainter::cpfConnectable | flag );
00336       } else {
00337         painter->drawHandle( x1, y1, flag );
00338       }
00339     }
00340 
00341     p = m_pConnectorPoints->next();
00342   }
00343 }
00344 
00345 
00346 
00348 // Collision detection
00350 KivioCollisionType Kivio1DStencil::checkForCollision( KoPoint *, double )
00351 {
00352     /* Derived class must implement this */
00353 
00354     return kctNone;
00355 }
00356 
00357 
00358 
00359 
00361 // Custom dragging
00363 
00371 void Kivio1DStencil::customDrag( KivioCustomDragData *pData )
00372 {
00373   setCustomIDPoint(pData->id, KoPoint(pData->x, pData->y), pData->page);
00374 }
00375 
00376 
00380 void Kivio1DStencil::updateGeometry()
00381 {
00382     double minX, minY, maxX, maxY;
00383 
00384     minX = 1000000000000.0f;
00385     minY = minX;
00386     maxX = -100000000000.0f;
00387     maxY = maxX;
00388 
00389 
00390     KivioConnectorPoint *p;
00391     p = m_pConnectorPoints->first();
00392     while( p )
00393     {
00394         if( p->x() < minX )
00395             minX = p->x();
00396         if( p->x() > maxX )
00397             maxX = p->x();
00398         if( p->y() < minY )
00399             minY = p->y();
00400         if( p->y() > maxY )
00401             maxY = p->y();
00402 
00403         p = m_pConnectorPoints->next();
00404     }
00405 
00406 
00407     m_x = minX;
00408     m_y = minY;
00409     m_w = maxX - minX + 1.0f;
00410     m_h = maxY - minY + 1.0f;
00411 }
00412 
00413 
00414 
00415 // file i/o routines
00416 bool Kivio1DStencil::loadXML( const QDomElement &e )
00417 {
00418    QDomNode node;
00419    QString name;
00420 
00421    node = e.firstChild();
00422    while( !node.isNull() )
00423    {
00424       name = node.nodeName();
00425 
00426       if( name == "KivioStencilProperties" )
00427       {
00428      loadProperties(node.toElement() );
00429       }
00430 
00431       node = node.nextSibling();
00432    }
00433 
00434    updateGeometry();
00435 
00436    return true;
00437 }
00438 
00439 
00440 QDomElement Kivio1DStencil::createRootElement( QDomDocument &doc )
00441 {
00442    QDomElement e = doc.createElement("KivioPluginStencil");
00443 
00444    XmlWriteString( e, "id", m_pSpawner->info()->id() );
00445    XmlWriteString( e, "setId", m_pSpawner->set()->id() );
00446 
00447    return e;
00448 }
00449 
00450 
00451 QDomElement Kivio1DStencil::saveXML( QDomDocument &doc )
00452 {
00453    QDomElement e = createRootElement(doc);
00454 
00455    e.appendChild( saveProperties(doc) );
00456 
00457    return e;
00458 }
00459 
00460 
00461 
00462 KivioStencil *Kivio1DStencil::duplicate()
00463 {
00464     /* Derived class must implement this function */
00465     return NULL;
00466 }
00467 
00468 
00469 bool Kivio1DStencil::boolAllTrue( bool *boolArray, int count )
00470 {
00471     int i;
00472 
00473     for( i=0; i<count; i++ )
00474     {
00475         if( boolArray[i]==false )
00476             return false;
00477     }
00478 
00479     return true;
00480 }
00481 
00482 bool Kivio1DStencil::boolContainsFalse( bool *boolArray, int count )
00483 {
00484     int i;
00485 
00486     for( i=0; i<count; i++ )
00487     {
00488         if( boolArray[i]==false )
00489             return true;
00490     }
00491 
00492     return false;
00493 }
00494 
00495 void Kivio1DStencil::searchForConnections( KivioPage *pPage )
00496 {
00497   bool *done = new bool[ m_pConnectorPoints->count()];
00498   unsigned int i;
00499 
00500   for(i = 0; i < m_pConnectorPoints->count(); i++) {
00501     done[i] = false;
00502   }
00503 
00504   KivioConnectorPoint *p;
00505   i = 0;
00506   p = m_pConnectorPoints->first();
00507 
00508   while( p )
00509   {
00510     if( p->targetId() == -1 ) {
00511       done[i] = true;
00512     }
00513 
00514     i++;
00515     p = m_pConnectorPoints->next();
00516   }
00517 
00518   // No connections? BaiL!
00519   if( boolAllTrue( done, m_pConnectorPoints->count() ) )
00520   {
00521     delete [] done;
00522     return;
00523   }
00524 
00525   KivioLayer *pLayer = pPage->firstLayer();
00526 
00527   while( pLayer && ( boolContainsFalse(done, m_pConnectorPoints->count()) ) )
00528   {
00529     KivioStencil *pStencil = pLayer->firstStencil();
00530 
00531     while( pStencil && ( boolContainsFalse(done, m_pConnectorPoints->count()) ) )
00532     {
00533       // No connecting to ourself!
00534       if((pStencil != this))
00535       {
00536 
00537         // Iterate through all connectors attempting to connect it to the stencil.
00538         // If it connects, mark it as done
00539         i=0;
00540         p = m_pConnectorPoints->first();
00541         while( p )
00542         {
00543           if( !done[i] && p->targetId() != -1 )
00544           {
00545             if(pStencil->connectToTarget( p, p->targetId()))
00546             {
00547               done[i] = true;
00548             }
00549           }
00550 
00551           i++;
00552           p = m_pConnectorPoints->next();
00553         }
00554 
00555       }
00556 
00557       pStencil = pLayer->nextStencil();
00558     }
00559 
00560     pLayer = pPage->nextLayer();
00561   }
00562 
00563   delete [] done;
00564 }
00565 
00566 void Kivio1DStencil::searchForConnections( KivioPage *pPage, double threshold )
00567 {
00568   bool *done = new bool[ m_pConnectorPoints->count()];
00569   int i;
00570 
00571   for( i=0; i<(int)m_pConnectorPoints->count(); i++ ) {
00572     done[i] = false;
00573   }
00574 
00575   KivioConnectorPoint *p;
00576   i = 0;
00577   p = m_pConnectorPoints->first();
00578 
00579   while( p )
00580   {
00581     if(p->target() != 0L) {
00582       done[i] = true;
00583     }
00584 
00585     i++;
00586     p = m_pConnectorPoints->next();
00587   }
00588 
00589   // No connections? BaiL!
00590   if( boolAllTrue( done, m_pConnectorPoints->count() ) )
00591   {
00592     delete [] done;
00593     return;
00594   }
00595 
00596   KivioLayer *pLayer = pPage->firstLayer();
00597 
00598   while( pLayer && ( boolContainsFalse(done, m_pConnectorPoints->count()) ) )
00599   {
00600     KivioStencil *pStencil = pLayer->firstStencil();
00601 
00602     while( pStencil && ( boolContainsFalse(done, m_pConnectorPoints->count()) ) )
00603     {
00604       // No connecting to ourself!
00605       if( pStencil != this )
00606       {
00607 
00608         // Iterate through all connectors attempting to connect it to the stencil.
00609         // If it connects, mark it as done
00610         i = 0;
00611         p = m_pConnectorPoints->first();
00612 
00613         while( p )
00614         {
00615           if( !done[i] && p->target() == 0 )
00616           {
00617             if( pStencil->connectToTarget( p, threshold ) )
00618             {
00619                 done[i] = true;
00620             }
00621           }
00622 
00623           i++;
00624           p = m_pConnectorPoints->next();
00625         }
00626 
00627       }
00628 
00629       pStencil = pLayer->nextStencil();
00630     }
00631 
00632     pLayer = pPage->nextLayer();
00633   }
00634 
00635   delete [] done;
00636 }
00637 
00639 // resize handles
00641 int Kivio1DStencil::resizeHandlePositions()
00642 {
00643     return (int)krhpNone;
00644 }
00645 
00646 QDomElement Kivio1DStencil::saveConnectors( QDomDocument &doc )
00647 {
00648     QDomElement eConns = doc.createElement("KivioConnectorList");
00649 
00650     KivioConnectorPoint *p;
00651     p = m_pConnectorPoints->first();
00652     while( p )
00653     {
00654         eConns.appendChild( p->saveXML(doc) );
00655 
00656         p = m_pConnectorPoints->next();
00657     }
00658 
00659     return eConns;
00660 }
00661 
00662 bool Kivio1DStencil::loadConnectors( const QDomElement &e )
00663 {
00664     m_pConnectorPoints->clear();
00665 
00666     KivioConnectorPoint *p;
00667 
00668     QDomNode node = e.firstChild();
00669     QDomElement e2;
00670     QString name;
00671 
00672     while( !node.isNull() )
00673     {
00674         e2 = node.toElement();
00675         name = e2.nodeName();
00676 
00677         if( name == "KivioConnectorPoint" )
00678         {
00679             p = new KivioConnectorPoint();
00680             p->setStencil(this);
00681             p->loadXML( e2 );
00682 
00683             m_pConnectorPoints->append( p );
00684             p = NULL;
00685         }
00686 
00687         node = node.nextSibling();
00688     }
00689 
00690     // Set the pointers to the start,end,left,right points
00691     m_pStart = m_pConnectorPoints->first();
00692     m_pEnd = m_pConnectorPoints->next();
00693     m_pLeft = m_pConnectorPoints->next();
00694     m_pRight = m_pConnectorPoints->next();
00695     m_pTextConn = m_pConnectorPoints->next();
00696 
00697     // Hopefully this will help with backwards compatibility
00698     if( m_pStart == NULL ) {
00699        m_pStart = new KivioConnectorPoint(this, true);
00700     }
00701     if( m_pEnd == NULL ) {
00702        m_pEnd = new KivioConnectorPoint(this, true);
00703     }
00704     if( m_pLeft == NULL ) {
00705        m_pLeft = new KivioConnectorPoint(this, false);
00706     }
00707     if( m_pRight == NULL ) {
00708        m_pRight = new KivioConnectorPoint(this, false);
00709     }
00710     if( m_pTextConn == NULL ) {
00711        m_pTextConn = new KivioConnectorPoint(this, false);
00712     }
00713 
00714 
00715     return true;
00716 }
00717 
00718 QDomElement Kivio1DStencil::saveProperties( QDomDocument &doc )
00719 {
00720     QDomElement propE = doc.createElement("KivioStencilProperties");
00721 
00722     QDomElement connE = doc.createElement("Kivio1DProperties");
00723     XmlWriteFloat( connE, "connectorWidth", m_connectorWidth );
00724     XmlWriteInt( connE, "needsWidth", m_needsWidth );
00725     propE.appendChild( connE );
00726 
00727     propE.appendChild( m_pLineStyle->saveXML( doc ) );
00728 
00729     propE.appendChild( m_pFillStyle->saveXML( doc ) );
00730 
00731     propE.appendChild( m_pTextStyle->saveXML( doc ) );
00732 
00733     propE.appendChild( saveConnectors(doc) );
00734 
00735     QDomElement customE = doc.createElement("CustomData");
00736     if( saveCustom( customE, doc )==true )
00737     {
00738        propE.appendChild( customE );
00739     }
00740 
00741     return propE;
00742 }
00743 
00744 bool Kivio1DStencil::loadProperties( const QDomElement &e )
00745 {
00746     QDomNode node;
00747     QDomElement nodeE;
00748     QString nodeName;
00749 
00750     node = e.firstChild();
00751     while( !node.isNull() )
00752     {
00753         nodeE = node.toElement();
00754         nodeName = node.nodeName();
00755 
00756         if( nodeName == "KivioFillStyle" )
00757         {
00758             m_pFillStyle->loadXML( nodeE );
00759         }
00760         else if( nodeName == "KivioLineStyle" )
00761         {
00762        m_pLineStyle->loadXML( nodeE );
00763         }
00764     else if( nodeName == "KivioTextStyle" )
00765     {
00766        m_pTextStyle->loadXML( nodeE );
00767     }
00768     else if( nodeName == "KivioConnectorList" )
00769     {
00770        loadConnectors( nodeE );
00771     }
00772     else if( nodeName == "Kivio1DProperties" )
00773     {
00774        m_needsWidth = (bool)XmlReadInt( nodeE, "needsWidth", (int)true );
00775        m_connectorWidth = XmlReadFloat( nodeE, "connectorWidth", 36.0f );
00776     }
00777     else if( nodeName == "CustomData" )
00778     {
00779        loadCustom( nodeE );
00780     }
00781 
00782         node = node.nextSibling();
00783     }
00784 
00785     return true;
00786 }
00787 
00788 bool Kivio1DStencil::loadCustom( const QDomElement & )
00789 {
00790    return true;
00791 }
00792 
00793 bool Kivio1DStencil::saveCustom( QDomElement &, QDomDocument & )
00794 {
00795    return false;
00796 }
00797 
00798 void Kivio1DStencil::copyBasicInto( Kivio1DStencil *pStencil )
00799 {
00800     KivioConnectorPoint *pSrc, *pTg;
00801 
00802     // Copy the spawner
00803     pStencil->setSpawner( m_pSpawner );
00804 
00805     // Copy the connector points
00806     pSrc = m_pConnectorPoints->first();
00807     pTg = pStencil->m_pConnectorPoints->first();
00808     while( pSrc && pTg )
00809     {
00810        pTg->setPosition( pSrc->x(), pSrc->y(), false );
00811 
00812        pSrc = m_pConnectorPoints->next();
00813        pTg = pStencil->m_pConnectorPoints->next();
00814     }
00815 
00816     // Copy the dimensions
00817     pStencil->m_x = m_x;
00818     pStencil->m_y = m_y;
00819     pStencil->m_w = m_w;
00820     pStencil->m_h = m_h;
00821 
00822     // Copy over the width info
00823     pStencil->m_connectorWidth = m_connectorWidth;
00824     pStencil->m_needsWidth = m_needsWidth;
00825 
00826     // Copy over the styles
00827     m_pFillStyle->copyInto( pStencil->m_pFillStyle );
00828     m_pLineStyle->copyInto( pStencil->m_pLineStyle );
00829     m_pTextStyle->copyInto( pStencil->m_pTextStyle );
00830 
00831     // Copy over the protection
00832     *(pStencil->m_pProtection) = *m_pProtection;
00833     *(pStencil->m_pCanProtect) = *m_pCanProtect;
00834 }
00835 
00836 void Kivio1DStencil::drawText( KivioIntraStencilData *pData )
00837 {
00838   if(m_pTextStyle->text().isEmpty()) {
00839     return;
00840   }
00841   
00842   KoZoomHandler* zoomHandler = pData->zoomHandler;
00843   KivioPainter *painter = pData->painter;
00844 
00845   int _x, _y, _w, _h;
00846 
00847   _x = zoomHandler->zoomItX(m_pTextConn->x());
00848   _y = zoomHandler->zoomItY(m_pTextConn->y());
00849   _w = 10000000;
00850   _h = 10000000;
00851 
00852   QFont f = m_pTextStyle->font();
00853   int tf = m_pTextStyle->hTextAlign() | m_pTextStyle->vTextAlign();
00854 
00855   f.setPointSizeFloat(f.pointSizeFloat() * (((float)zoomHandler->zoom()) / 100.0));
00856   painter->setFont(f);
00857   QRect boundRect = painter->boundingRect( _x, _y, _w, _h, tf, m_pTextStyle->text() );
00858   QPixmap pix(boundRect.width(), boundRect.height());
00859   pix.fill();
00860   QPainter p(&pix);
00861   p.setPen(m_pTextStyle->color());
00862   p.setFont(f);
00863   p.drawText( 0, 0, boundRect.width(), boundRect.height(), tf, m_pTextStyle->text() );
00864   QBitmap mask;
00865   mask = pix;
00866   pix.setMask(mask);
00867   painter->drawPixmap(_x, _y, pix);
00868 }
00869 
00870 bool Kivio1DStencil::connected()
00871 {
00872   KivioConnectorPoint *p;
00873   p = m_pConnectorPoints->first();
00874 
00875   while( p )
00876   {
00877     if(p->target() != 0) {
00878       return true;
00879     }
00880 
00881     p = m_pConnectorPoints->next();
00882   }
00883 
00884   return false;
00885 }
00886 
00887 void Kivio1DStencil::disconnectFromTargets()
00888 {
00889   KivioConnectorPoint *p;
00890   p = m_pConnectorPoints->first();
00891 
00892   while( p )
00893   {
00894     p->disconnect(true);
00895     p = m_pConnectorPoints->next();
00896   }
00897 }
00898 
00899 KivioLineStyle Kivio1DStencil::lineStyle()
00900 {
00901   return *m_pLineStyle;
00902 }
00903 
00904 void Kivio1DStencil::setLineStyle(KivioLineStyle ls)
00905 {
00906   ls.copyInto(m_pLineStyle);
00907 }
00908 
00909 void Kivio1DStencil::setCustomIDPoint(int customID, const KoPoint& point, KivioPage* page)
00910 {
00911   double oldX, oldY;
00912   KivioConnectorPoint *p;
00913 
00914   // Locate the point specified by customID
00915   p = m_pConnectorPoints->at( customID - (kctCustom+1));
00916 
00917   if( !p )
00918   {
00919     kdDebug(43000) << "Kivio1DStencil::customDrag() - KivioConnectorPoint customID: " << (customID - (kctCustom+1)) << "  not found\n" << endl;
00920     return;
00921   }
00922 
00923   oldX = p->x();
00924   oldY = p->y();
00925   p->setPosition(point.x(),point.y(),true);
00926 
00927   if( p->connectable()==true )
00928   {
00929     // Attempt a snap....
00930     KivioLayer *pCurLayer = page->curLayer();
00931     KivioLayer *pLayer = page->firstLayer(); //page->curLayer();
00932     bool foundConnection = false;
00933 
00934     while( pLayer && !foundConnection )
00935     {
00936       // To be connected to, a layer must be visible and connectable
00937       if( pLayer!=pCurLayer )
00938       {
00939         if( pLayer->connectable()==false || pLayer->visible()==false )
00940         {
00941           pLayer = page->nextLayer();
00942           continue;
00943         }
00944       }
00945 
00946       // Tell the layer to search for a target
00947       if( pLayer->connectPointToTarget( p, 8.0f ) )
00948       {
00949         foundConnection = true;
00950       }
00951 
00952       pLayer = page->nextLayer();
00953     }
00954 
00955     if( foundConnection == false )
00956     {
00957       p->disconnect();
00958     }
00959   }
00960 
00961   // If it is a start/end point, then make a request to update the connectors (must be implemented by stencil developer)
00962   if( customID == kctCustom+1 || customID == kctCustom+2 )
00963   {
00964     // If it's the end connector, then update the text point
00965     if( p==m_pEnd && m_needsText==true )
00966     {
00967       m_pTextConn->setPosition( m_pTextConn->x() + (m_pEnd->x() - oldX),
00968                                 m_pTextConn->y() + (m_pEnd->y() - oldY), false );
00969     }
00970 
00971     updateConnectorPoints(p, oldX, oldY);
00972   }
00973   // If it is one of the width handles, then fix the width and update the opposite point
00974   // only if the stencils 'needs width' connectors
00975   else if( (customID == kctCustom+3 || customID == kctCustom+4) && (m_needsWidth==true) )
00976   {
00977     double vx = m_pStart->x() - m_pEnd->x();
00978     double vy = m_pStart->y() - m_pEnd->y();
00979     double len = sqrt( vx*vx + vy*vy );
00980     double midX = (m_pStart->x() + m_pEnd->x())/2.0f;
00981     double midY = (m_pStart->y() + m_pEnd->y())/2.0f;
00982 
00983     vx /= len;
00984     vy /= len;
00985 
00986     double d = shortestDistance( m_pStart, m_pEnd, (customID==kctCustom+3) ? m_pLeft : m_pRight );
00987 
00988     m_pLeft->setPosition( midX + d*vy, midY + d*(-vx), false );
00989     m_pRight->setPosition( midX + d*(-vy), midY + d*vx, false );
00990 
00991     m_connectorWidth = d*2.0f;
00992 
00993     updateConnectorPoints(p, oldX, oldY);
00994     return;
00995   }
00996   // Text handle
00997   else if( customID == kctCustom+5 )
00998   {
00999     updateConnectorPoints(p, oldX, oldY);
01000   }
01001 }
01002 
01003 KoPoint Kivio1DStencil::customIDPoint(int customID)
01004 {
01005   KivioConnectorPoint *p;
01006 
01007   // Locate the point specified by customID
01008   p = m_pConnectorPoints->at( customID - (kctCustom+1));
01009 
01010   return p->position();
01011 }
KDE Home | KDE Accessibility Home | Description of Access Keys