kivio_shape.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 <stdio.h>
20#include <kdebug.h>
21#include "kivio_common.h"
22#include "kivio_fill_style.h"
23#include "kivio_line_style.h"
24#include "kivio_point.h"
25#include "kivio_shape.h"
26#include "kivio_text_style.h"
27
33KivioShape::KivioShape()
34{
35}
36
37
45KivioShape::KivioShape( const KivioShape &source )
46{
47 source.m_shapeData.copyInto( &m_shapeData );
48}
49
50
54KivioShape::~KivioShape()
55{
56}
57
58
66void KivioShape::copyInto( KivioShape *pTarget ) const
67{
68 if( !pTarget )
69 return;
70
71 m_shapeData.copyInto( &(pTarget->m_shapeData) );
72}
73
74
81bool KivioShape::loadXML( const TQDomElement &e )
82{
83 TQDomElement ele;
84 TQDomNode node = e.firstChild();
85
86 TQString name = XmlReadString( e, "name", "" );
87 m_shapeData.setName( name );
88 m_shapeData.setShapeType( (KivioShapeData::KivioShapeType)XmlReadInt( e, "shapeType", -1 ));
89
90 if( m_shapeData.name().isEmpty() ||
91 m_shapeData.shapeType() == -1 )
92 {
93 kdWarning(43000) << "-LOAD KivioShape::loadXML() - Unknown shape or bad name read. Shape load aborted." << endl;
94 return false;
95 }
96
97 while( !node.isNull() )
98 {
99 TQString nodeName = node.nodeName();
100 ele = node.toElement();
101
102 if( nodeName == "KivioShapeData" )
103 {
104 m_shapeData.loadXML( ele );
105 }
106
107 node = node.nextSibling();
108 }
109 return true;
110}
111
112
119TQDomElement KivioShape::saveXML( TQDomDocument &doc )
120{
121 TQDomElement e = doc.createElement("KivioShape");
122
123 XmlWriteString( e, "name", m_shapeData.m_name );
124 XmlWriteInt( e, "shapeType", m_shapeData.m_shapeType );
125
126 e.appendChild( m_shapeData.saveXML( doc ) );
127
128 return e;
129}
130
131
140KivioShape *KivioShape::loadShapeArc( const TQDomElement & )
141{
142 return NULL;
143}
144
145
152KivioShape *KivioShape::loadShapeClosedPath( const TQDomElement &e )
153{
154 KivioShape *pShape = NULL;
155 KivioPoint *pPoint = NULL;
156 TQDomNode node;
157 TQString nodeName;
158
159
160 // Create the new shape to load into
161 pShape = new KivioShape();
162
163 // Load the type, name, and lineWidth properties
164 pShape->m_shapeData.m_shapeType = KivioShapeData::kstClosedPath;
165 pShape->m_shapeData.m_name = XmlReadString( e, "name", "" );
166
167 // Iterate through the nodes loading the various items
168 node = e.firstChild();
169 while( !node.isNull() )
170 {
171 nodeName = node.nodeName();
172
173 // The line array is made up of pairs of points
174 if( nodeName == "KivioPoint" )
175 {
176 // Allocate a new point, load it, and store it in the list
177 pPoint = new KivioPoint(0.0f, 0.0f, KivioPoint::kptBezier);
178 pPoint->loadXML( node.toElement() );
179 pShape->m_shapeData.m_pOriginalPointList->append( pPoint );
180 pPoint = NULL;
181 }
182 else if( nodeName == "KivioFillStyle" )
183 {
184 pShape->m_shapeData.m_pFillStyle->loadXML( node.toElement() );
185 }
186 else if( nodeName == "KivioLineStyle" )
187 {
188 pShape->m_shapeData.m_pLineStyle->loadXML( node.toElement() );
189 }
190
191 node = node.nextSibling();
192 }
193
194 return pShape;
195}
196
197
204KivioShape *KivioShape::loadShapeBezier( const TQDomElement &e )
205{
206 KivioShape *pShape = NULL;
207 KivioPoint *pPoint = NULL;
208 TQDomNode node;
209 TQString nodeName;
210
211
212 // Create the new shape to load into
213 pShape = new KivioShape();
214
215 // Load the type, name, and lineWidth properties
216 pShape->m_shapeData.m_shapeType = KivioShapeData::kstBezier;
217 pShape->m_shapeData.m_name = XmlReadString( e, "name", "" );
218
219 // Iterate through the nodes loading the various items
220 node = e.firstChild();
221 while( !node.isNull() )
222 {
223 nodeName = node.nodeName();
224
225 // The line array is made up of pairs of points
226 if( nodeName == "KivioPoint" )
227 {
228 // Allocate a new point, load it, and store it in the list
229 pPoint = new KivioPoint(0.0f, 0.0f, KivioPoint::kptBezier);
230 pPoint->loadXML( node.toElement() );
231 if( pPoint->pointType() != KivioPoint::kptBezier )
232 {
233 kdDebug(43000) << "KivioShape::loadShapeBezier() - Non-bezier point found. Aborting shape." << endl;
234 delete pPoint;
235 delete pShape;
236 return NULL;
237 }
238 pShape->m_shapeData.m_pOriginalPointList->append( pPoint );
239 pPoint = NULL;
240 }
241 else if( nodeName == "KivioLineStyle" )
242 {
243 pShape->m_shapeData.m_pLineStyle->loadXML( node.toElement() );
244 }
245
246 node = node.nextSibling();
247 }
248
249 if( pShape->m_shapeData.m_pOriginalPointList->count() != 4 )
250 {
251 kdDebug(43000) << "KivioShape::loadShapeBezier() - Wrong number of points loaded, should be 4, shape aborted" << endl;
252 delete pShape;
253 return NULL;
254 }
255
256 return pShape;
257}
258
259
266KivioShape *KivioShape::loadShapeEllipse( const TQDomElement &e )
267{
268 KivioShape *pShape = NULL;
269 TQDomNode node;
270 TQString nodeName;
271
272
273 // Create the new shape to load into
274 pShape = new KivioShape();
275
276 // Load the type, name, and lineWidth properties
277 pShape->m_shapeData.m_shapeType = KivioShapeData::kstEllipse;
278 pShape->m_shapeData.m_name = XmlReadString( e, "name", "" );
279
280 pShape->m_shapeData.m_position.set( XmlReadFloat( e, "x", 0.0f ), XmlReadFloat( e, "y", 0.0f ) );
281 pShape->m_shapeData.m_dimensions.set( XmlReadFloat( e, "w", 0.0f ), XmlReadFloat( e, "h", 0.0f ) );
282
283 // Iterate through the nodes loading the various items
284 node = e.firstChild();
285 while( !node.isNull() )
286 {
287 nodeName = node.nodeName();
288
289 if( nodeName == "KivioFillStyle" )
290 {
291 pShape->m_shapeData.m_pFillStyle->loadXML( node.toElement() );
292 }
293 else if( nodeName == "KivioLineStyle" )
294 {
295 pShape->m_shapeData.m_pLineStyle->loadXML( node.toElement() );
296 }
297
298 node = node.nextSibling();
299 }
300
301 return pShape;
302}
303
304
311KivioShape *KivioShape::loadShapeLineArray( const TQDomElement &e )
312{
313 KivioShape *pShape = NULL;
314 KivioPoint *pPoint = NULL;
315 TQDomNode node;
316 TQString nodeName;
317 TQDomElement lineElement;
318
319
320 // Create the new shape to load into
321 pShape = new KivioShape();
322
323 // Load the type, name, and lineWidth properties
324 pShape->m_shapeData.m_shapeType = KivioShapeData::kstLineArray;
325 pShape->m_shapeData.m_name = XmlReadString( e, "name", "" );
326
327 // Iterate through the nodes loading the various items
328 node = e.firstChild();
329 while( !node.isNull() )
330 {
331 nodeName = node.nodeName();
332
333 // The line array is made up of pairs of points
334 if( nodeName == "Line" )
335 {
336 lineElement = node.toElement();
337
338 // Allocate a new point, load it, and store it in the list
339 pPoint = new KivioPoint( XmlReadFloat( lineElement, "x1", 0.0f ), XmlReadFloat( lineElement, "y1", 0.0f ) );
340 pShape->m_shapeData.m_pOriginalPointList->append( pPoint );
341 pPoint = new KivioPoint( XmlReadFloat( lineElement, "x2", 0.0f ), XmlReadFloat( lineElement, "y2", 0.0f ) );
342 pShape->m_shapeData.m_pOriginalPointList->append( pPoint );
343 pPoint = NULL;
344 }
345 else if( nodeName == "KivioLineStyle" )
346 {
347 pShape->m_shapeData.m_pLineStyle->loadXML( node.toElement() );
348 }
349
350 node = node.nextSibling();
351 }
352
353 return pShape;
354}
355
356
363KivioShape *KivioShape::loadShapeOpenPath( const TQDomElement &e )
364{
365 KivioShape *pShape = NULL;
366 KivioPoint *pPoint = NULL;
367 TQDomNode node;
368 TQString nodeName;
369
370
371 // Create the new shape to load into
372 pShape = new KivioShape();
373
374 // Load the type, name, and lineWidth properties
375 pShape->m_shapeData.m_shapeType = KivioShapeData::kstOpenPath;
376 pShape->m_shapeData.m_name = XmlReadString( e, "name", "" );
377
378 // Iterate through the nodes loading the various items
379 node = e.firstChild();
380 while( !node.isNull() )
381 {
382 nodeName = node.nodeName();
383
384 // The line array is made up of pairs of points
385 if( nodeName == "KivioPoint" )
386 {
387 // Allocate a new point, load it, and store it in the list
388 pPoint = new KivioPoint(0.0f, 0.0f, KivioPoint::kptBezier);
389 pPoint->loadXML( node.toElement() );
390 pShape->m_shapeData.m_pOriginalPointList->append( pPoint );
391 pPoint = NULL;
392 }
393 else if( nodeName == "KivioLineStyle" )
394 {
395 pShape->m_shapeData.m_pLineStyle->loadXML( node.toElement() );
396 }
397
398 node = node.nextSibling();
399 }
400
401 return pShape;
402}
403
404
413KivioShape *KivioShape::loadShapePie( const TQDomElement & )
414{
415 return NULL;
416}
417
418
425KivioShape *KivioShape::loadShapePolygon( const TQDomElement &e )
426{
427 KivioShape *pShape = NULL;
428 KivioPoint *pPoint = NULL;
429 TQDomNode node;
430 TQString nodeName;
431
432
433 // Create the new shape to load into
434 pShape = new KivioShape();
435
436 // Load the type, name, and lineWidth properties
437 pShape->m_shapeData.m_shapeType = KivioShapeData::kstPolygon;
438 pShape->m_shapeData.m_name = XmlReadString( e, "name", "" );
439
440 // Iterate through the nodes loading the various items
441 node = e.firstChild();
442 while( !node.isNull() )
443 {
444 nodeName = node.nodeName();
445
446 // The polygon is made up of a series of points
447 if( nodeName == "KivioPoint" )
448 {
449 // Allocate a new point, load it, and store it in the list
450 pPoint = new KivioPoint();
451 pPoint->loadXML( node.toElement() );
452 pShape->m_shapeData.m_pOriginalPointList->append( pPoint );
453 pPoint = NULL;
454 }
455 else if( nodeName == "KivioFillStyle" )
456 {
457 pShape->m_shapeData.m_pFillStyle->loadXML( node.toElement() );
458 }
459 else if( nodeName == "KivioLineStyle" )
460 {
461 pShape->m_shapeData.m_pLineStyle->loadXML( node.toElement() );
462 }
463
464 node = node.nextSibling();
465 }
466
467 return pShape;
468}
469
470
477KivioShape *KivioShape::loadShapePolyline( const TQDomElement &e )
478{
479 KivioShape *pShape = NULL;
480 KivioPoint *pPoint = NULL;
481 TQDomNode node;
482 TQString nodeName;
483
484
485 // Create the new shape to load into
486 pShape = new KivioShape();
487
488 // Load the type, name, and lineWidth properties
489 pShape->m_shapeData.m_shapeType = KivioShapeData::kstPolyline;
490 pShape->m_shapeData.m_name = XmlReadString( e, "name", "" );
491
492 // Iterate through the nodes loading the various items
493 node = e.firstChild();
494 while( !node.isNull() )
495 {
496 nodeName = node.nodeName();
497
498 // The polygon is made up of a series of points
499 if( nodeName == "KivioPoint" )
500 {
501 // Allocate a new point, load it, and store it in the list
502 pPoint = new KivioPoint();
503 pPoint->loadXML( node.toElement() );
504 pShape->m_shapeData.m_pOriginalPointList->append( pPoint );
505 pPoint = NULL;
506 }
507 else if( nodeName == "KivioLineStyle" )
508 {
509 pShape->m_shapeData.m_pLineStyle->loadXML( node.toElement() );
510 }
511
512 node = node.nextSibling();
513 }
514
515 return pShape;
516}
517
518
525KivioShape *KivioShape::loadShapeRectangle( const TQDomElement &e )
526{
527 KivioShape *pShape = NULL;
528 TQDomNode node;
529 TQString nodeName;
530
531
532 // Create the new shape to load into
533 pShape = new KivioShape();
534
535 // Load the type, name, and lineWidth properties
536 pShape->m_shapeData.m_shapeType = KivioShapeData::kstRectangle;
537 pShape->m_shapeData.m_name = XmlReadString( e, "name", "" );
538
539 pShape->m_shapeData.m_position.set( XmlReadFloat( e, "x", 0.0f ), XmlReadFloat( e, "y", 0.0f ) );
540 pShape->m_shapeData.m_dimensions.set( XmlReadFloat( e, "w", 72.0f ), XmlReadFloat( e, "h", 72.0f ) );
541
542 // Iterate through the nodes loading the various items
543 node = e.firstChild();
544 while( !node.isNull() )
545 {
546 nodeName = node.nodeName();
547
548 // Read the fill style
549 if( nodeName == "KivioFillStyle" )
550 {
551 pShape->m_shapeData.m_pFillStyle->loadXML( node.toElement() );
552 }
553 else if( nodeName == "KivioLineStyle" )
554 {
555 pShape->m_shapeData.m_pLineStyle->loadXML( node.toElement() );
556 }
557
558 node = node.nextSibling();
559 }
560
561 return pShape;
562}
563
564
565
572KivioShape *KivioShape::loadShapeRoundRectangle( const TQDomElement &e )
573{
574 KivioShape *pShape = NULL;
575 KivioPoint *pPoint = NULL;
576 TQDomNode node;
577 TQString nodeName;
578
579
580 // Create the new shape to load into
581 pShape = new KivioShape();
582
583 // Load the type, name, and lineWidth properties
584 pShape->m_shapeData.m_shapeType = KivioShapeData::kstRoundRectangle;
585 pShape->m_shapeData.m_name = XmlReadString( e, "name", "" );
586
587 pShape->m_shapeData.m_position.set( XmlReadFloat( e, "x", 0.0f ), XmlReadFloat( e, "y", 0.0f ) );
588 pShape->m_shapeData.m_dimensions.set( XmlReadFloat( e, "w", 72.0f ), XmlReadFloat( e, "h", 72.0f ) );
589
590 // Read and store the radii of the curves
591 pPoint = new KivioPoint(0.0f, 0.0f);
592 pPoint->set( XmlReadFloat( e, "r1", 1.0f ), XmlReadFloat( e, "r2", 1.0f ) );
593 pShape->m_shapeData.m_pOriginalPointList->append( pPoint );
594
595 // Iterate through the nodes loading the various items
596 node = e.firstChild();
597 while( !node.isNull() )
598 {
599 nodeName = node.nodeName();
600
601 // Read the fill style
602 if( nodeName == "KivioFillStyle" )
603 {
604 pShape->m_shapeData.m_pFillStyle->loadXML( node.toElement() );
605 }
606 else if( nodeName == "KivioLineStyle" )
607 {
608 pShape->m_shapeData.m_pLineStyle->loadXML( node.toElement() );
609 }
610
611 node = node.nextSibling();
612 }
613
614 return pShape;
615}
616
617
624KivioShape *KivioShape::loadShapeTextBox( const TQDomElement &e )
625{
626 KivioShape *pShape = NULL;
627 TQDomNode node;
628 TQString nodeName;
629 KivioTextStyle ts;
630 TQString name;
631
632
633 // Create the new shape to load into
634 pShape = new KivioShape();
635
636 // Load the type and name
637 pShape->m_shapeData.setShapeType(KivioShapeData::kstTextBox);
638 pShape->m_shapeData.setName( XmlReadString( e, "name", "" ) );
639 pShape->m_shapeData.setTextColor(XmlReadColor(e,"color",TQColor(0,0,0)));
640
641 pShape->m_shapeData.m_position.set(
642 XmlReadFloat( e, "x", 0.0f ), XmlReadFloat( e, "y", 0.0f ) );
643 pShape->m_shapeData.m_dimensions.set(
644 XmlReadFloat( e, "w", 72.0f ), XmlReadFloat( e, "h", 72.0f ) );
645
646 // Now look for the KivioTextStyle
647 node = e.firstChild();
648 while( !node.isNull() )
649 {
650 nodeName = node.nodeName();
651 if( nodeName == "KivioTextStyle" )
652 {
653 ts.loadXML( node.toElement() );
654 pShape->m_shapeData.setTextStyle( &ts );
655 }
656
657 node = node.nextSibling();
658 }
659// TQString text = XmlReadString( e, "text", "" );
660// pShape->m_shapeData.setText( text );
661
662
663 return pShape;
664}
KivioShapeType
The possible shape types.