kivio

kivio_common.cpp
1/*
2 * Kivio - Visual Modelling and Flowcharting
3 * Copyright (C) 2000-2001 theKompany.com & Dave Marotti
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation; either version 2
8 * of the License, or (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 */
19#include "kivio_common.h"
20#include "kivio_connector_point.h"
21#include <kdebug.h>
22#include <tqstringlist.h>
23#include <math.h>
24#include <KoPoint.h>
25#include <KoRect.h>
26
37float XmlReadFloat( const TQDomElement &e, const TQString &att, const float &def)
38{
39 // Check if this value exists, if not, return the default
40 if( e.hasAttribute( att )==false )
41 return def;
42
43 // Read the attribute
44 TQString val = e.attribute( att );
45 bool ok=false;
46
47 // Make sure it is a floating point value. If not, return the default
48 float fVal = val.toFloat( &ok );
49 if( !ok )
50 {
51 kdDebug(43000) << "Invalid XML-value read for " << att.ascii() << ", expected float\n" << endl;
52 return 1.0;
53 }
54
55 // Return the value
56 return fVal;
57}
58
59
69void XmlWriteFloat( TQDomElement &e, const TQString &att, const float &val )
70{
71 e.setAttribute( att, (double)val );
72}
73
74
85int XmlReadInt( const TQDomElement &e, const TQString &att, const int &def)
86{
87 // Check if this value exists, if not, return the default
88 if( e.hasAttribute( att )==false )
89 return def;
90
91 // Read the attribute
92 TQString val = e.attribute( att, "1" );
93 bool ok=false;
94
95 // Make sure it is a floating point value. If not, return the default
96 int iVal = val.toInt( &ok );
97 if( !ok )
98 {
99 kdDebug(43000) << "Invalid XML-value read for " << att << " expected int\n" << endl;
100 return 1;
101 }
102
103 // Return the value
104 return iVal;
105}
106
107
117void XmlWriteInt( TQDomElement &e, const TQString &att, const int &val )
118{
119 e.setAttribute( att, (int)val );
120}
121
122
133uint XmlReadUInt( const TQDomElement &e, const TQString &att, const uint &def)
134{
135 // Check if this value exists, if not, return the default
136 if( e.hasAttribute( att )==false )
137 return def;
138
139 // Read the attribute
140 TQString val = e.attribute( att, "1" );
141 bool ok=false;
142
143 // Make sure it is a floating point value. If not, return the default
144 uint iVal = val.toUInt( &ok );
145 if( !ok )
146 {
147 kdDebug(43000) << "Invalid XML-value read for " << att.ascii() << ", expected uint\n" << endl;
148 return 1;
149 }
150
151 // Return the value
152 return iVal;
153}
154
155
165void XmlWriteUInt( TQDomElement &e, const TQString &att, const uint &val )
166{
167 e.setAttribute( att, (uint)val );
168}
169
170
181TQString XmlReadString( const TQDomElement &e, const TQString &att, const TQString &def )
182{
183 // Check if the attribute exists, if not, return the default
184 if( e.hasAttribute( att )==false )
185 return TQString(def);
186 // Otherwise return the attribute
187 else return e.attribute( att );
188}
189
190
200void XmlWriteString( TQDomElement &e, const TQString &att, const TQString &val )
201{
202 e.setAttribute( att, val );
203}
204
205
216TQColor XmlReadColor( const TQDomElement &e, const TQString &att, const TQColor &def)
217{
218 // Check if this value exists, if not, return the default
219 if( e.hasAttribute( att )==false )
220 return def;
221
222 // Read the attribute
223 TQString val = e.attribute( att, "1" );
224 bool ok=false;
225 TQColor newColor;
226
227 if( val.contains("#") ) // Is it #RRGGBB format?
228 {
229 newColor.setNamedColor(val);
230 return newColor;
231 }
232
233 // Otherwise it is a #xxxxxxxx color (rgb format)
234 // Make sure it is a uint value. If not, return the default
235 uint iVal = val.toUInt( &ok );
236 if( !ok )
237 {
238 kdDebug(43000) << "Invalid XML-value read for " << att.ascii() << ", expected TQColor" << endl;
239 return 1;
240 }
241
242 // Return the value
243 return TQColor(iVal);
244}
245
246
256void XmlWriteColor( TQDomElement &e, const TQString &att, const TQColor &val )
257{
258 // Write it out in #RRGGBB format
259 e.setAttribute( att, val.name() );
260}
261
262
273double XmlReadDouble( const TQDomElement &e, const TQString &att, const double &def)
274{
275 // Check if this value exists, if not, return the default
276 if( e.hasAttribute( att )==false )
277 return def;
278
279 // Read the attribute
280 TQString val = e.attribute( att, "1.0" );
281 bool ok=false;
282
283 // Make sure it is a floating point value. If not, return the default
284 double dVal = val.toDouble( &ok );
285 if( !ok )
286 {
287 kdDebug(43000) << "Invalid XML-value read for ," << att.ascii() << " expected double" << endl;
288 return 1.0;
289 }
290
291 // Return the value
292 return dVal;
293}
294
295
305void XmlWriteDouble( TQDomElement &e, const TQString &att, const double &val )
306{
307 e.setAttribute( att, (double)val );
308}
309
310
311#define WHICH_QUAD( vertex, hitPos ) \
312 ( (vertex.x() > hitPos->x()) ? ((vertex.y() > hitPos->y()) ? 1 : 4 ) : ((vertex.y() > hitPos->y())?2:3))
313
314#define X_INTERCEPT( point1, point2, hitY ) \
315 (point2.x() - (((point2.y()-hitY)*(point1.x()-point2.x()))/(point1.y()-point2.y())))
316
337bool PointInPoly( KoPoint *points, int numPoints, KoPoint *hitPos )
338{
339 int edge, next;
340 int quad, next_quad, delta, total;
341
342 edge = 0;
343
344 quad = WHICH_QUAD( points[ edge ], hitPos );
345 total = 0; // count of absolute sectors crossed
346
347 // Loop through all the vertices
348 do {
349 next = (edge + 1) % numPoints;
350 next_quad = WHICH_QUAD( points[ next ], hitPos );
351
352 // Calculate how many quads have been crossed
353 delta = next_quad - quad;
354
355 // Special case to handle crossings of more than one quad
356 switch( delta )
357 {
358 case 2: // If we crossed the middle, figure out if it was clockwise or counter clockwise
359 case -2: // Use the X-position at the hit point to determine which way around
360 if( X_INTERCEPT( points[edge], points[next], hitPos->y() ) > hitPos->x() )
361 delta = -delta;
362 break;
363
364 case 3: // Moving 3 quads is like moving back 1
365 delta = -1;
366 break;
367
368 case -3: // Moving back 3 is like moving forward 1
369 delta = 1;
370 break;
371 }
372
373 // Add in the delta
374 total += delta;
375 quad = next_quad;
376 edge = next;
377 } while( edge != 0 );
378
379
380 // After everything, if the total is 4, then we are inside
381 if((total==4) || (total==-4))
382 return true;
383 else
384 return false;
385}
386
387KoRect XmlReadRect( const TQDomElement &e, const TQString &att, const KoRect &def )
388{
389 // Check if this value exists, if not, return the default
390 if( e.hasAttribute( att )==false )
391 return def;
392
393 // Read the attribute
394 TQString val = e.attribute( att );
395
396 if (val.find("[") == 0 && val.find("]") == (int)val.length()-1) {
397 val.remove(0,1);
398 val.remove(val.length()-1,1);
399 TQStringList vlist = TQStringList::split(",",val);
400 if (vlist.count() == 4) {
401 bool allOk = true;
402 bool ok = false;
403
404 double x = vlist[0].toDouble(&ok);
405 allOk = allOk & ok;
406
407 double y = vlist[1].toDouble(&ok);
408 allOk = allOk & ok;
409
410 double w = vlist[2].toDouble(&ok);
411 allOk = allOk & ok;
412
413 double h = vlist[3].toDouble(&ok);
414 allOk = allOk & ok;
415
416 if (allOk)
417 return KoRect(x, y, w, h);
418 }
419 }
420
421 return def;
422}
423
424void XmlWriteRect( TQDomElement &e, const TQString &att, const KoRect &val )
425{
426 e.setAttribute( att, TQString("[%1,%2,%3,%4]").arg(val.x()).arg(val.y()).arg(val.width()).arg(val.height()) );
427}
428
429
430float shortestDistance( KivioConnectorPoint *pStart, KivioConnectorPoint *pEnd, KivioConnectorPoint *q )
431{
432 float uX, uY;
433 float pqX, pqY;
434
435 uX = pStart->x() - pEnd->x();
436 uY = pStart->y() - pEnd->y();
437
438 pqX = pStart->x() - q->x();
439 pqY = pStart->y() - q->y();
440
441 float magTop = fabs(pqX*uY - (pqY*uX));
442
443 float magU = sqrt( uX*uX + uY*uY );
444
445 if( magU == 0.0f )
446 {
447 kdDebug(43000) << "shortestDistance() - SERIOUS ERROR: magU is 0.0f!\n";
448 return 10.0f;
449 }
450
451 return magTop / magU;
452}