kivio

kivio_common.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 <kdebug.h>
00022 #include <qstringlist.h>
00023 #include <math.h>
00024 #include <KoPoint.h>
00025 #include <KoRect.h>
00026 
00037 float XmlReadFloat( const QDomElement &e, const QString &att, const float &def)
00038 {
00039     // Check if this value exists, if not, return the default
00040     if( e.hasAttribute( att )==false )
00041         return def;
00042     
00043     // Read the attribute
00044     QString val = e.attribute( att );
00045     bool ok=false;
00046     
00047     // Make sure it is a floating point value.  If not, return the default
00048     float fVal = val.toFloat( &ok );
00049     if( !ok )
00050     {
00051     kdDebug(43000) << "Invalid XML-value read for " << att.ascii() << ", expected float\n" << endl;
00052     return 1.0;
00053     }
00054     
00055     // Return the value
00056     return fVal;
00057 }
00058 
00059 
00069 void XmlWriteFloat( QDomElement &e, const QString &att, const float &val )
00070 {
00071     e.setAttribute( att, (double)val );
00072 }
00073 
00074 
00085 int XmlReadInt( const QDomElement &e, const QString &att, const int &def)
00086 {
00087     // Check if this value exists, if not, return the default
00088     if( e.hasAttribute( att )==false )
00089         return def;
00090 
00091     // Read the attribute
00092     QString val = e.attribute( att, "1" );
00093     bool ok=false;
00094 
00095     // Make sure it is a floating point value.  If not, return the default
00096     int iVal = val.toInt( &ok );
00097     if( !ok )
00098     {
00099        kdDebug(43000) << "Invalid XML-value read for " << att << " expected int\n" << endl;
00100       return 1;
00101     }
00102 
00103     // Return the value
00104     return iVal;
00105 }
00106 
00107 
00117 void XmlWriteInt( QDomElement &e, const QString &att, const int &val )
00118 {
00119     e.setAttribute( att, (int)val );
00120 }
00121 
00122 
00133 uint XmlReadUInt( const QDomElement &e, const QString &att, const uint &def)
00134 {
00135     // Check if this value exists, if not, return the default
00136     if( e.hasAttribute( att )==false )
00137         return def;
00138 
00139     // Read the attribute
00140     QString val = e.attribute( att, "1" );
00141     bool ok=false;
00142 
00143     // Make sure it is a floating point value.  If not, return the default
00144     uint iVal = val.toUInt( &ok );
00145     if( !ok )
00146     {
00147        kdDebug(43000) << "Invalid XML-value read for " << att.ascii() << ", expected uint\n" << endl;
00148         return 1;
00149     }
00150 
00151     // Return the value
00152     return iVal;
00153 }
00154 
00155 
00165 void XmlWriteUInt( QDomElement &e, const QString &att, const uint &val )
00166 {
00167     e.setAttribute( att, (uint)val );
00168 }
00169 
00170 
00181 QString XmlReadString( const QDomElement &e, const QString &att, const QString &def )
00182 {
00183     // Check if the attribute exists, if not, return the default
00184     if( e.hasAttribute( att )==false )
00185         return QString(def);
00186     // Otherwise return the attribute
00187     else return e.attribute( att );
00188 }
00189 
00190 
00200 void XmlWriteString( QDomElement &e,  const QString &att,  const QString &val )
00201 {
00202     e.setAttribute( att, val );
00203 }
00204 
00205 
00216 QColor XmlReadColor( const QDomElement &e, const QString &att, const QColor &def)
00217 {
00218     // Check if this value exists, if not, return the default
00219     if( e.hasAttribute( att )==false )
00220         return def;
00221 
00222     // Read the attribute
00223     QString val = e.attribute( att, "1" );
00224     bool ok=false;
00225     QColor newColor;
00226 
00227     if( val.contains("#") ) // Is it #RRGGBB format?
00228     {
00229         newColor.setNamedColor(val);
00230         return newColor;
00231     }
00232 
00233     // Otherwise it is a #xxxxxxxx color (rgb format)
00234     // Make sure it is a uint value.  If not, return the default
00235     uint iVal = val.toUInt( &ok );
00236     if( !ok )
00237     {
00238        kdDebug(43000) << "Invalid XML-value read for " << att.ascii() << ", expected QColor" << endl;
00239         return 1;
00240     }
00241 
00242     // Return the value
00243     return QColor(iVal);
00244 }
00245 
00246 
00256 void XmlWriteColor( QDomElement &e, const QString &att, const QColor &val )
00257 {
00258     // Write it out in #RRGGBB format
00259     e.setAttribute( att, val.name() );
00260 }
00261 
00262 
00273 double XmlReadDouble( const QDomElement &e, const QString &att, const double &def)
00274 {
00275     // Check if this value exists, if not, return the default
00276     if( e.hasAttribute( att )==false )
00277         return def;
00278 
00279     // Read the attribute
00280     QString val = e.attribute( att, "1.0" );
00281     bool ok=false;
00282 
00283     // Make sure it is a floating point value.  If not, return the default
00284     double dVal = val.toDouble( &ok );
00285     if( !ok )
00286     {
00287        kdDebug(43000) << "Invalid XML-value read for ," << att.ascii() << " expected double" << endl;
00288         return 1.0;
00289     }
00290 
00291     // Return the value
00292     return dVal;
00293 }
00294 
00295 
00305 void XmlWriteDouble( QDomElement &e, const QString &att, const double &val )
00306 {
00307     e.setAttribute( att, (double)val );
00308 }
00309 
00310 
00311 #define WHICH_QUAD( vertex, hitPos ) \
00312     ( (vertex.x() > hitPos->x()) ? ((vertex.y() > hitPos->y()) ? 1 : 4 ) : ((vertex.y() > hitPos->y())?2:3))
00313 
00314 #define X_INTERCEPT( point1, point2, hitY ) \
00315     (point2.x() - (((point2.y()-hitY)*(point1.x()-point2.x()))/(point1.y()-point2.y())))
00316 
00337 bool PointInPoly( KoPoint *points, int numPoints, KoPoint *hitPos )
00338 {
00339     int edge,  next;
00340     int quad, next_quad, delta, total;
00341 
00342     edge = 0;
00343 
00344     quad = WHICH_QUAD( points[ edge ], hitPos );
00345     total = 0; // count of absolute sectors crossed
00346 
00347     // Loop through all the vertices
00348     do {
00349         next = (edge + 1) % numPoints;
00350         next_quad = WHICH_QUAD( points[ next ], hitPos );
00351 
00352         // Calculate how many quads have been crossed
00353         delta = next_quad - quad;
00354 
00355         // Special case to handle crossings of more than one quad
00356         switch( delta )
00357         {
00358             case 2:     // If we crossed the middle, figure out if it was clockwise or counter clockwise
00359             case -2:    // Use the X-position at the hit point to determine which way around
00360                 if( X_INTERCEPT( points[edge], points[next], hitPos->y() ) > hitPos->x() )
00361                     delta = -delta;
00362                 break;
00363 
00364             case 3:     // Moving 3 quads is like moving back 1
00365                 delta = -1;
00366                 break;
00367 
00368             case -3:    // Moving back 3 is like moving forward 1
00369                 delta = 1;
00370                 break;
00371         }
00372 
00373         // Add in the delta
00374         total += delta;
00375         quad = next_quad;
00376         edge = next;
00377     } while( edge != 0 );
00378     
00379 
00380     // After everything, if the total is 4, then we are inside
00381     if((total==4) || (total==-4))
00382         return true;
00383     else
00384         return false;
00385 }
00386 
00387 KoRect XmlReadRect( const QDomElement &e, const QString &att, const KoRect &def )
00388 {
00389     // Check if this value exists, if not, return the default
00390     if( e.hasAttribute( att )==false )
00391         return def;
00392 
00393     // Read the attribute
00394     QString val = e.attribute( att );
00395 
00396     if (val.find("[") == 0 && val.find("]") == (int)val.length()-1) {
00397       val.remove(0,1);
00398       val.remove(val.length()-1,1);
00399       QStringList vlist = QStringList::split(",",val);
00400       if (vlist.count() == 4) {
00401         bool allOk = true;
00402         bool ok = false;
00403 
00404         double x = vlist[0].toDouble(&ok);
00405         allOk = allOk & ok;
00406 
00407         double y = vlist[1].toDouble(&ok);
00408         allOk = allOk & ok;
00409 
00410         double w = vlist[2].toDouble(&ok);
00411         allOk = allOk & ok;
00412 
00413         double h = vlist[3].toDouble(&ok);
00414         allOk = allOk & ok;
00415 
00416         if (allOk)
00417           return KoRect(x, y, w, h);
00418       }
00419     }
00420 
00421     return def;
00422 }
00423 
00424 void  XmlWriteRect( QDomElement &e, const QString &att, const KoRect &val )
00425 {
00426     e.setAttribute( att, QString("[%1,%2,%3,%4]").arg(val.x()).arg(val.y()).arg(val.width()).arg(val.height()) );
00427 }
00428 
00429 
00430 float shortestDistance( KivioConnectorPoint *pStart, KivioConnectorPoint *pEnd, KivioConnectorPoint *q )
00431 {
00432    float uX, uY;
00433    float pqX, pqY;
00434 
00435    uX = pStart->x() - pEnd->x();
00436    uY = pStart->y() - pEnd->y();
00437 
00438    pqX = pStart->x() - q->x();
00439    pqY = pStart->y() - q->y();
00440 
00441    float magTop = fabs(pqX*uY - (pqY*uX));
00442 
00443    float magU = sqrt( uX*uX + uY*uY );
00444    
00445    if( magU == 0.0f )
00446    {
00447       kdDebug(43000) << "shortestDistance() - SERIOUS ERROR: magU is 0.0f!\n";
00448       return 10.0f;
00449    }
00450 
00451    return magTop / magU;
00452 }
KDE Home | KDE Accessibility Home | Description of Access Keys