summaryrefslogtreecommitdiffstats
path: root/kivio/kiviopart/kiviosdk/kivio_common.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'kivio/kiviopart/kiviosdk/kivio_common.cpp')
-rw-r--r--kivio/kiviopart/kiviosdk/kivio_common.cpp452
1 files changed, 452 insertions, 0 deletions
diff --git a/kivio/kiviopart/kiviosdk/kivio_common.cpp b/kivio/kiviopart/kiviosdk/kivio_common.cpp
new file mode 100644
index 000000000..8de8e1e04
--- /dev/null
+++ b/kivio/kiviopart/kiviosdk/kivio_common.cpp
@@ -0,0 +1,452 @@
+/*
+ * Kivio - Visual Modelling and Flowcharting
+ * Copyright (C) 2000-2001 theKompany.com & Dave Marotti
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+#include "kivio_common.h"
+#include "kivio_connector_point.h"
+#include <kdebug.h>
+#include <qstringlist.h>
+#include <math.h>
+#include <KoPoint.h>
+#include <KoRect.h>
+
+/**
+ * Read a floating point value from a @ref QDomElement.
+ *
+ * @param e The @ref QDomElement to read from
+ * @param att The attribute to locate
+ * @param def The default value to return if the attribute is not found
+ *
+ * This will read a floating point attribute from a @ref QDomElement, and
+ * if it is not found, return the default value.
+ */
+float XmlReadFloat( const QDomElement &e, const QString &att, const float &def)
+{
+ // Check if this value exists, if not, return the default
+ if( e.hasAttribute( att )==false )
+ return def;
+
+ // Read the attribute
+ QString val = e.attribute( att );
+ bool ok=false;
+
+ // Make sure it is a floating point value. If not, return the default
+ float fVal = val.toFloat( &ok );
+ if( !ok )
+ {
+ kdDebug(43000) << "Invalid XML-value read for " << att.ascii() << ", expected float\n" << endl;
+ return 1.0;
+ }
+
+ // Return the value
+ return fVal;
+}
+
+
+/**
+ * Write a floating point value to a @ref QDomElement
+ *
+ * @param e The @ref QDomElement to write to
+ * @param att The attribute to write
+ * @param val The value of the attribute to write
+ *
+ * This will write a floating point value to a @ref QDomElement.
+ */
+void XmlWriteFloat( QDomElement &e, const QString &att, const float &val )
+{
+ e.setAttribute( att, (double)val );
+}
+
+
+/**
+ * Read an int value from a @ref QDomElement.
+ *
+ * @param e The @ref QDomElement to read from
+ * @param att The attribute to locate
+ * @param def The default value to return if the attribute is not found
+ *
+ * This will read an int attribute from a @ref QDomElement, and
+ * if it is not found, return the default value.
+ */
+int XmlReadInt( const QDomElement &e, const QString &att, const int &def)
+{
+ // Check if this value exists, if not, return the default
+ if( e.hasAttribute( att )==false )
+ return def;
+
+ // Read the attribute
+ QString val = e.attribute( att, "1" );
+ bool ok=false;
+
+ // Make sure it is a floating point value. If not, return the default
+ int iVal = val.toInt( &ok );
+ if( !ok )
+ {
+ kdDebug(43000) << "Invalid XML-value read for " << att << " expected int\n" << endl;
+ return 1;
+ }
+
+ // Return the value
+ return iVal;
+}
+
+
+/**
+ * Write a int value to a @ref QDomElement
+ *
+ * @param e The @ref QDomElement to write to
+ * @param att The attribute to write
+ * @param val The value of the attribute to write
+ *
+ * This will write an int value to a @ref QDomElement.
+ */
+void XmlWriteInt( QDomElement &e, const QString &att, const int &val )
+{
+ e.setAttribute( att, (int)val );
+}
+
+
+/**
+ * Read an uint value from a @ref QDomElement.
+ *
+ * @param e The @ref QDomElement to read from
+ * @param att The attribute to locate
+ * @param def The default value to return if the attribute is not found
+ *
+ * This will read an uint attribute from a @ref QDomElement, and
+ * if it is not found, return the default value.
+ */
+uint XmlReadUInt( const QDomElement &e, const QString &att, const uint &def)
+{
+ // Check if this value exists, if not, return the default
+ if( e.hasAttribute( att )==false )
+ return def;
+
+ // Read the attribute
+ QString val = e.attribute( att, "1" );
+ bool ok=false;
+
+ // Make sure it is a floating point value. If not, return the default
+ uint iVal = val.toUInt( &ok );
+ if( !ok )
+ {
+ kdDebug(43000) << "Invalid XML-value read for " << att.ascii() << ", expected uint\n" << endl;
+ return 1;
+ }
+
+ // Return the value
+ return iVal;
+}
+
+
+/**
+ * Write an uint value to a @ref QDomElement
+ *
+ * @param e The @ref QDomElement to write to
+ * @param att The attribute to write
+ * @param val The value of the attribute to write
+ *
+ * This will write an uint value to a @ref QDomElement.
+ */
+void XmlWriteUInt( QDomElement &e, const QString &att, const uint &val )
+{
+ e.setAttribute( att, (uint)val );
+}
+
+
+/**
+ * Read a @ref QString from a @ref QDomElement.
+ *
+ * @param e The @ref QDomElement to read from
+ * @param att The attribute to locate
+ * @param def The default value to return if the attribute is not found
+ *
+ * This will read a QString attribute from a @ref QDomElement, and
+ * if it is not found, return the default value.
+ */
+QString XmlReadString( const QDomElement &e, const QString &att, const QString &def )
+{
+ // Check if the attribute exists, if not, return the default
+ if( e.hasAttribute( att )==false )
+ return QString(def);
+ // Otherwise return the attribute
+ else return e.attribute( att );
+}
+
+
+/**
+ * Write a QString to a @ref QDomElement
+ *
+ * @param e The @ref QDomElement to write to
+ * @param att The attribute to write
+ * @param val The value of the attribute to write
+ *
+ * This will write a QString to a @ref QDomElement.
+ */
+void XmlWriteString( QDomElement &e, const QString &att, const QString &val )
+{
+ e.setAttribute( att, val );
+}
+
+
+/**
+ * Read a QColor value from a @ref QDomElement.
+ *
+ * @param e The @ref QDomElement to read from
+ * @param att The attribute to locate
+ * @param def The default value to return if the attribute is not found
+ *
+ * This will read a QColor attribute from a @ref QDomElement, and
+ * if it is not found, return the default value.
+ */
+QColor XmlReadColor( const QDomElement &e, const QString &att, const QColor &def)
+{
+ // Check if this value exists, if not, return the default
+ if( e.hasAttribute( att )==false )
+ return def;
+
+ // Read the attribute
+ QString val = e.attribute( att, "1" );
+ bool ok=false;
+ QColor newColor;
+
+ if( val.contains("#") ) // Is it #RRGGBB format?
+ {
+ newColor.setNamedColor(val);
+ return newColor;
+ }
+
+ // Otherwise it is a #xxxxxxxx color (rgb format)
+ // Make sure it is a uint value. If not, return the default
+ uint iVal = val.toUInt( &ok );
+ if( !ok )
+ {
+ kdDebug(43000) << "Invalid XML-value read for " << att.ascii() << ", expected QColor" << endl;
+ return 1;
+ }
+
+ // Return the value
+ return QColor(iVal);
+}
+
+
+/**
+ * Write a QColor value to a @ref QDomElement
+ *
+ * @param e The @ref QDomElement to write to
+ * @param att The attribute to write
+ * @param val The value of the attribute to write
+ *
+ * This will write a QColor value to a @ref QDomElement.
+ */
+void XmlWriteColor( QDomElement &e, const QString &att, const QColor &val )
+{
+ // Write it out in #RRGGBB format
+ e.setAttribute( att, val.name() );
+}
+
+
+/**
+ * Read a double value from a @ref QDomElement.
+ *
+ * @param e The @ref QDomElement to read from
+ * @param att The attribute to locate
+ * @param def The default value to return if the attribute is not found
+ *
+ * This will read a double attribute from a @ref QDomElement, and
+ * if it is not found, return the default value.
+ */
+double XmlReadDouble( const QDomElement &e, const QString &att, const double &def)
+{
+ // Check if this value exists, if not, return the default
+ if( e.hasAttribute( att )==false )
+ return def;
+
+ // Read the attribute
+ QString val = e.attribute( att, "1.0" );
+ bool ok=false;
+
+ // Make sure it is a floating point value. If not, return the default
+ double dVal = val.toDouble( &ok );
+ if( !ok )
+ {
+ kdDebug(43000) << "Invalid XML-value read for ," << att.ascii() << " expected double" << endl;
+ return 1.0;
+ }
+
+ // Return the value
+ return dVal;
+}
+
+
+/**
+ * Write a double value to a @ref QDomElement
+ *
+ * @param e The @ref QDomElement to write to
+ * @param att The attribute to write
+ * @param val The value of the attribute to write
+ *
+ * This will write a double value to a @ref QDomElement.
+ */
+void XmlWriteDouble( QDomElement &e, const QString &att, const double &val )
+{
+ e.setAttribute( att, (double)val );
+}
+
+
+#define WHICH_QUAD( vertex, hitPos ) \
+ ( (vertex.x() > hitPos->x()) ? ((vertex.y() > hitPos->y()) ? 1 : 4 ) : ((vertex.y() > hitPos->y())?2:3))
+
+#define X_INTERCEPT( point1, point2, hitY ) \
+ (point2.x() - (((point2.y()-hitY)*(point1.x()-point2.x()))/(point1.y()-point2.y())))
+
+/**
+ * Determines if a point is inside a given polygon
+ * @param points An array of points representing the polygon
+ * @param numPoints The number of points in the array
+ * @param hitPos The point we are to check
+ *
+ * Code taken from Game Developer magazine page 22, January 1999 issue
+ * Explaination:
+ *
+ * A better strategy is to divide the polygon into quadrants centered on the test point.
+ * Start at the first vertex in the polygon and set a counter to 0. Anytime an edge crosses
+ * from one quadrant to the next, add one to the counter if it crosses clockwise around the
+ * test point and subtract one if it crosses counter-clockwise. If the edge crosses diagonally
+ * across two quadrants, you need to determine which side of the test point it crossed, and then
+ * either add or subtract 2.
+ *
+ * Quad layout:
+ * 1 2
+ * 4 3
+ */
+bool PointInPoly( KoPoint *points, int numPoints, KoPoint *hitPos )
+{
+ int edge, next;
+ int quad, next_quad, delta, total;
+
+ edge = 0;
+
+ quad = WHICH_QUAD( points[ edge ], hitPos );
+ total = 0; // count of absolute sectors crossed
+
+ // Loop through all the vertices
+ do {
+ next = (edge + 1) % numPoints;
+ next_quad = WHICH_QUAD( points[ next ], hitPos );
+
+ // Calculate how many quads have been crossed
+ delta = next_quad - quad;
+
+ // Special case to handle crossings of more than one quad
+ switch( delta )
+ {
+ case 2: // If we crossed the middle, figure out if it was clockwise or counter clockwise
+ case -2: // Use the X-position at the hit point to determine which way around
+ if( X_INTERCEPT( points[edge], points[next], hitPos->y() ) > hitPos->x() )
+ delta = -delta;
+ break;
+
+ case 3: // Moving 3 quads is like moving back 1
+ delta = -1;
+ break;
+
+ case -3: // Moving back 3 is like moving forward 1
+ delta = 1;
+ break;
+ }
+
+ // Add in the delta
+ total += delta;
+ quad = next_quad;
+ edge = next;
+ } while( edge != 0 );
+
+
+ // After everything, if the total is 4, then we are inside
+ if((total==4) || (total==-4))
+ return true;
+ else
+ return false;
+}
+
+KoRect XmlReadRect( const QDomElement &e, const QString &att, const KoRect &def )
+{
+ // Check if this value exists, if not, return the default
+ if( e.hasAttribute( att )==false )
+ return def;
+
+ // Read the attribute
+ QString val = e.attribute( att );
+
+ if (val.find("[") == 0 && val.find("]") == (int)val.length()-1) {
+ val.remove(0,1);
+ val.remove(val.length()-1,1);
+ QStringList vlist = QStringList::split(",",val);
+ if (vlist.count() == 4) {
+ bool allOk = true;
+ bool ok = false;
+
+ double x = vlist[0].toDouble(&ok);
+ allOk = allOk & ok;
+
+ double y = vlist[1].toDouble(&ok);
+ allOk = allOk & ok;
+
+ double w = vlist[2].toDouble(&ok);
+ allOk = allOk & ok;
+
+ double h = vlist[3].toDouble(&ok);
+ allOk = allOk & ok;
+
+ if (allOk)
+ return KoRect(x, y, w, h);
+ }
+ }
+
+ return def;
+}
+
+void XmlWriteRect( QDomElement &e, const QString &att, const KoRect &val )
+{
+ e.setAttribute( att, QString("[%1,%2,%3,%4]").arg(val.x()).arg(val.y()).arg(val.width()).arg(val.height()) );
+}
+
+
+float shortestDistance( KivioConnectorPoint *pStart, KivioConnectorPoint *pEnd, KivioConnectorPoint *q )
+{
+ float uX, uY;
+ float pqX, pqY;
+
+ uX = pStart->x() - pEnd->x();
+ uY = pStart->y() - pEnd->y();
+
+ pqX = pStart->x() - q->x();
+ pqY = pStart->y() - q->y();
+
+ float magTop = fabs(pqX*uY - (pqY*uX));
+
+ float magU = sqrt( uX*uX + uY*uY );
+
+ if( magU == 0.0f )
+ {
+ kdDebug(43000) << "shortestDistance() - SERIOUS ERROR: magU is 0.0f!\n";
+ return 10.0f;
+ }
+
+ return magTop / magU;
+}