kivio_shape_data.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_fill_style.h"
21#include "kivio_line_style.h"
22#include "kivio_point.h"
23#include "kivio_shape_data.h"
24#include "kivio_text_style.h"
25
26#include <tqpainter.h>
27#include <kdebug.h>
28
29/*
30 * Struct for holding information about a shape type
31 */
32struct KivioShapeTypeInfo
33{
34 const char *name;
36};
37
38/*
39 * Array of shape info used for loading/saving.
40 */
41static const int numShapeInfo = 12;
42static struct KivioShapeTypeInfo shapeInfo[] = {
43 { "Arc", KivioShapeData::kstArc },
44 { "Pie", KivioShapeData::kstPie },
45 { "LineArray", KivioShapeData::kstLineArray },
46 { "Polyline", KivioShapeData::kstPolyline },
47 { "Polygon", KivioShapeData::kstPolygon },
48 { "Bezier", KivioShapeData::kstBezier },
49 { "Rectangle", KivioShapeData::kstRectangle },
50 { "RoundRectangle", KivioShapeData::kstRoundRectangle },
51 { "Ellipse", KivioShapeData::kstEllipse },
52 { "OpenPath", KivioShapeData::kstOpenPath },
53 { "ClosedPath", KivioShapeData::kstClosedPath },
54 { "TextBox", KivioShapeData::kstTextBox }
55};
56
57
58/*****************
59 * FIXME
60 *
61 * Down the road, this will be phased out because of the KivioTextStyle
62 * class. But it's here for now to keep backwards compatibility with
63 * beta 2 -- even though noone should be using it for anything important!!!
64 ****************/
65KivioTextShapeData::KivioTextShapeData()
66{
67 m_text = "";
68 m_textFont = TQFont("Times");
69 m_textColor = TQColor(0,0,0);
70 m_isHtml = false;
71 m_hTextAlign = TQt::AlignHCenter;
72 m_vTextAlign = TQt::AlignVCenter;
73}
74
75
76KivioShapeData::KivioShapeData()
77 : m_pOriginalPointList(NULL),
78 m_pFillStyle(NULL)
79{
80 m_pOriginalPointList = new TQPtrList<KivioPoint>;
81 m_pOriginalPointList->setAutoDelete(true);
82
83 m_pFillStyle = new KivioFillStyle();
84 m_pLineStyle = new KivioLineStyle();
85// m_fgColor = TQColor( 0, 0, 0 );
86
87 m_shapeType = kstNone;
88 m_name = "";
89// m_lineWidth = 1.0f;
90
91 m_pTextData = NULL;
92
93 m_position.set( 0.0f, 0.0f );
94 m_dimensions.set( 72.0f, 72.0f );
95}
96
97KivioShapeData::KivioShapeData( const KivioShapeData &source )
98 : m_pOriginalPointList(NULL),
99 m_pFillStyle(NULL)
100{
101 // Allocate a new point list
102 KivioPoint *pPoint;
103 m_pOriginalPointList = new TQPtrList<KivioPoint>;
104 m_pOriginalPointList->setAutoDelete(true);
105
106 // Copy over the point list
107 pPoint = source.m_pOriginalPointList->first();
108 while( pPoint )
109 {
110 m_pOriginalPointList->append( new KivioPoint( *pPoint ) );
111 pPoint = source.m_pOriginalPointList->next();
112 }
113
114 // Copy the fill/line styles
115 m_pFillStyle = new KivioFillStyle( *(source.m_pFillStyle) );
116 m_pLineStyle = new KivioLineStyle( *(source.m_pLineStyle) );
117
118 // Copy the fg color
119 //m_fgColor = source.m_fgColor;
120
121 // Copy the rest
122 m_shapeType = source.m_shapeType;
123 m_name = TQString(source.m_name);
124 //m_lineWidth = source.m_lineWidth;
125
126 // Copy the position and size
127 source.m_position.copyInto( &m_position );
128 source.m_dimensions.copyInto( &m_dimensions );
129
130 // If this is a text shape, allocate a text data struct and copy the info
131 if( m_shapeType == kstTextBox )
132 {
133 m_pTextData = new KivioTextStyle();
134
135 source.m_pTextData->copyInto( m_pTextData );
136/*
137 m_pTextData->m_text = ((KivioShapeData)source).text();
138 m_pTextData->m_isHtml = ((KivioShapeData)source).isHtml();
139 m_pTextData->m_hTextAlign = ((KivioShapeData)source).hTextAlign();
140 m_pTextData->m_vTextAlign = ((KivioShapeData)source).vTextAlign();
141 m_pTextData->m_textFont = ((KivioShapeData)source).textFont();
142 m_pTextData->m_textColor = ((KivioShapeData)source).textColor();
143*/
144 }
145 else
146 m_pTextData = NULL;
147
148}
149
150
151KivioShapeData::~KivioShapeData()
152{
153 if( m_pOriginalPointList )
154 {
155 delete m_pOriginalPointList;
156 m_pOriginalPointList = NULL;
157 }
158
159 if( m_pFillStyle )
160 {
161 delete m_pFillStyle;
162 m_pFillStyle = NULL;
163 }
164
165 if( m_pLineStyle )
166 {
167 delete m_pLineStyle;
168 m_pLineStyle = NULL;
169 }
170
171 if( m_pTextData )
172 {
173 delete m_pTextData;
174 m_pTextData = NULL;
175 }
176}
177
178
179void KivioShapeData::copyInto( KivioShapeData *pTarget ) const
180{
181 KivioPoint *pPoint;
182
183 if( !pTarget )
184 return;
185
186 // Delete the old point list
187 if( pTarget->m_pOriginalPointList )
188 {
189 delete pTarget->m_pOriginalPointList;
190 pTarget->m_pOriginalPointList = NULL;
191 }
192
193 // Create a new point list and copy it over
194 pTarget->m_pOriginalPointList = new TQPtrList<KivioPoint>;
195 pTarget->m_pOriginalPointList->setAutoDelete(true);
196 pPoint = m_pOriginalPointList->first();
197 while( pPoint )
198 {
199 pTarget->m_pOriginalPointList->append( new KivioPoint( *pPoint ) );
200 pPoint = m_pOriginalPointList->next();
201 }
202
203 // Copy the fill/line styles
204 m_pFillStyle->copyInto( pTarget->m_pFillStyle );
205 m_pLineStyle->copyInto( pTarget->m_pLineStyle );
206
207 // Copy the fg color
208 //pTarget->m_fgColor = m_fgColor;
209
210 // Copy the rest
211 pTarget->m_shapeType = m_shapeType;
212 pTarget->m_name = TQString(m_name);
213 //pTarget->m_lineWidth = m_lineWidth;
214
215 m_position.copyInto( &(pTarget->m_position) );
216 m_dimensions.copyInto( &(pTarget->m_dimensions) );
217
218
219 // If this is a textbox, allocate & copy
220 if( m_shapeType == kstTextBox )
221 {
222 if( !pTarget->m_pTextData )
223 {
224 pTarget->m_pTextData = new KivioTextStyle();
225 }
226
227 if( m_pTextData )
228 {
229 m_pTextData->copyInto( pTarget->m_pTextData );
230 }
231 else
232 {
233 kdWarning(43000) << "KivioShapeData::copyInto() - Shape is of type text-box, but our text data doens't exist." << endl;
234 pTarget->m_pTextData->setText("");
235 pTarget->m_pTextData->setIsHtml(false);
236 pTarget->m_pTextData->setHTextAlign(TQt::AlignHCenter);
237 pTarget->m_pTextData->setVTextAlign(TQt::AlignVCenter);
238 pTarget->m_pTextData->setFont( TQFont("Times",12) );
239 pTarget->m_pTextData->setColor( TQColor(0,0,0) );
240 }
241 }
242 else
243 {
244 if( pTarget->m_pTextData )
245 {
246 delete pTarget->m_pTextData;
247 pTarget->m_pTextData = NULL;
248 }
249 }
250}
251
252
257bool KivioShapeData::loadXML( const TQDomElement &e )
258{
259 TQDomNode node;
260 TQDomElement ele;
261
262 // Maintain backwards compatibility with the eariler betas. They saved
263 // fg color and line style in this node.
264 m_pLineStyle->setColor( XmlReadColor( e, "fgColor", TQColor(0,0,0) ) );
265 m_pLineStyle->setWidth( XmlReadFloat( e, "lineWidth", 1.0f ) );
266
267
268 node = e.firstChild();
269 while( !node.isNull() )
270 {
271 TQString nodeName = node.nodeName();
272 ele = node.toElement();
273
274 if( nodeName == "KivioLineStyle" )
275 {
276 m_pLineStyle->loadXML( ele );
277 }
278 else if( nodeName == "KivioFillStyle" )
279 {
280 m_pFillStyle->loadXML( ele );
281 }
282 else if( nodeName == "KivioTextStyle" )
283 {
284
285 // First make sure we are a text box
286 if( m_shapeType == kstTextBox )
287 {
288 // If we don't have text data, allocate it
289 if( !m_pTextData )
290 m_pTextData = new KivioTextStyle();
291
292 m_pTextData->loadXML( ele );
293
294 } // end if m_shapeType==kstTextBox
295 }
296 else if( nodeName == "KivioText" )
297 {
298 // First make sure we are a text box
299 if( m_shapeType == kstTextBox )
300 {
301 KivioTextShapeData *pData = new KivioTextShapeData;
302
303 pData->m_text = XmlReadString( ele, "text", "" );
304 pData->m_isHtml = (bool)XmlReadInt( ele, "isHtml", (int)false );
305
306 pData->m_hTextAlign = XmlReadInt( ele, "hTextAlign", TQt::AlignHCenter );
307 pData->m_vTextAlign = XmlReadInt( ele, "vTextAlign", TQt::AlignVCenter );
308
309 // Search for the font
310 TQDomNode innerNode = ele.firstChild();
311 while( !innerNode.isNull() )
312 {
313 TQString innerName = innerNode.nodeName();
314 TQDomElement innerE = innerNode.toElement();
315
316 if( innerName == "TextFont" )
317 {
318 pData->m_textFont.setFamily( XmlReadString(innerE, "family", "times") );
319 pData->m_textFont.setPointSize( XmlReadInt(innerE, "size", 12 ) );
320 pData->m_textFont.setBold( (bool)XmlReadInt( innerE, "bold", 12 ) );
321 pData->m_textFont.setItalic( (bool)XmlReadInt( innerE, "italic", 12 ) );
322 pData->m_textFont.setUnderline( (bool)XmlReadInt( innerE, "underline", 12 ) );
323 pData->m_textFont.setStrikeOut( (bool)XmlReadInt( innerE, "strikeOut", 12 ) );
324 pData->m_textFont.setFixedPitch( (bool)XmlReadInt( innerE, "fixedPitch", false ) );
325 pData->m_textColor = XmlReadColor( innerE, "color", TQColor(0,0,0) );
326 }
327
328 innerNode = innerNode.nextSibling();
329 }
330
331 // Now convert it to a KivioTextStyle
332 if( !m_pTextData )
333 m_pTextData = new KivioTextStyle();
334
335 m_pTextData->setText( pData->m_text );
336 m_pTextData->setHTextAlign( pData->m_hTextAlign );
337 m_pTextData->setVTextAlign( pData->m_vTextAlign );
338 m_pTextData->setFont( pData->m_textFont );
339 m_pTextData->setColor( pData->m_textColor );
340
341 } // end if m_shapeType==kstTextBox
342 else
343 {
344 kdDebug(43000) << "KivioShapeData::loadXML() - Loading KivioText, but this is not a textbox!" << endl;
345 }
346 }
347
348 node = node.nextSibling();
349 }
350
351 return true;
352}
353
358TQDomElement KivioShapeData::saveXML( TQDomDocument &doc )
359{
360 TQDomElement e = doc.createElement("KivioShapeData");
361
362 // FIXME: Do we need to save m_pOriginalPointList
363
364 // We save all this, but we won't necessarily load it back.
365
366 // The positions
367 TQDomElement posE = doc.createElement("Position");
368 XmlWriteFloat( posE, "x", m_position.x() );
369 XmlWriteFloat( posE, "y", m_position.y() );
370 e.appendChild( posE );
371
372 // The dimensions
373 TQDomElement dimE = doc.createElement("Dimension");
374 XmlWriteFloat( dimE, "w", m_dimensions.x() );
375 XmlWriteFloat( dimE, "h", m_dimensions.y() );
376 e.appendChild( dimE );
377
378 // The FGColor
379// TQDomElement foreE = doc.createElement("Foreground");
380// XmlWriteUInt( foreE, "color", m_fgColor.rgb() );
381// XmlWriteFloat( foreE, "lineWidth", m_lineWidth );
382// e.appendChild( foreE );
383 TQDomElement foreE = m_pLineStyle->saveXML( doc );
384 e.appendChild( foreE );
385
386
387 // Save if we are a text box etc...
388 if( m_shapeType == kstTextBox )
389 {
390 if( m_pTextData )
391 {
392 e.appendChild( m_pTextData->saveXML(doc) );
393 /*
394 // The text & formatting
395 TQDomElement textE = doc.createElement("KivioText");
396 XmlWriteString( textE, "text", m_pTextData->m_text );
397 XmlWriteInt( textE, "isHtml", m_pTextData->m_isHtml );
398 XmlWriteInt( textE, "hTextAlign", m_pTextData->m_hTextAlign );
399 XmlWriteInt( textE, "vTextAlign", m_pTextData->m_vTextAlign );
400
401 // Text font & color
402 TQDomElement innerTextE = doc.createElement("TextFont");
403 XmlWriteString( innerTextE, "family", m_pTextData->m_textFont.family() );
404 XmlWriteColor( innerTextE, "color", m_pTextData->m_textColor );
405 XmlWriteInt( innerTextE, "size", m_pTextData->m_textFont.pointSize() );
406 XmlWriteInt( innerTextE, "bold", m_pTextData->m_textFont.bold() );
407 XmlWriteInt( innerTextE, "italic", m_pTextData->m_textFont.italic() );
408 XmlWriteInt( innerTextE, "underline", m_pTextData->m_textFont.underline() );
409 XmlWriteInt( innerTextE, "strikeOut", m_pTextData->m_textFont.strikeOut() );
410 XmlWriteInt( innerTextE, "fixedPitch", m_pTextData->m_textFont.fixedPitch() );
411
412 textE.appendChild( innerTextE );
413 e.appendChild( textE );
414 */
415 }
416 }
417
418
419
420 // The BGFillStyle
421 e.appendChild( m_pFillStyle->saveXML( doc ) );
422
423 // Shape type & name are stored in the shape node
424 //XmlWriteInt( e, "shapeType", m_shapeType );
425 //XmlWriteString( e, "name", m_name );
426
427 return e;
428}
429
430
431KivioShapeData::KivioShapeType KivioShapeData::shapeTypeFromString( const TQString &str )
432{
433
434 for( int i=0; i<numShapeInfo; i++ )
435 {
436 if( str.compare( shapeInfo[i].name )==0 )
437 return shapeInfo[i].type;
438 }
439
440 return kstNone;
441}
442
443void KivioShapeData::setShapeType( KivioShapeType st )
444{
445 m_shapeType = st;
446
447 // If it is a text box, make sure we have text data
448 if( st == kstTextBox )
449 {
450 if( !m_pTextData )
451 m_pTextData = new KivioTextStyle();
452 }
453 else // Otherwise, make sure we DON'T have it.
454 {
455 if( m_pTextData )
456 {
457 delete m_pTextData;
458 m_pTextData = NULL;
459 }
460 }
461}
462
463
464TQString KivioShapeData::text()
465{
466 if( m_pTextData )
467 return m_pTextData->text();
468
469 return TQString("");
470}
471
472void KivioShapeData::setText( const TQString &newText )
473{
474 if( m_pTextData )
475 {
476 m_pTextData->setText(newText);
477 }
478}
479
480bool KivioShapeData::isHtml() const
481{
482 if( m_pTextData )
483 return m_pTextData->isHtml();
484
485 return false;
486}
487
488void KivioShapeData::setIsHtml( bool b )
489{
490 if( m_pTextData )
491 m_pTextData->setIsHtml(b);
492}
493
494int KivioShapeData::hTextAlign() const
495{
496 if( m_pTextData )
497 return m_pTextData->hTextAlign();
498
499 return TQt::AlignHCenter;
500}
501
502void KivioShapeData::setHTextAlign( int i )
503{
504 if( m_pTextData )
505 m_pTextData->setHTextAlign(i);
506}
507
508int KivioShapeData::vTextAlign() const
509{
510 if( m_pTextData )
511 return m_pTextData->vTextAlign();
512
513 return TQt::AlignVCenter;
514}
515
516void KivioShapeData::setVTextAlign( int i )
517{
518 if( m_pTextData )
519 m_pTextData->setVTextAlign(i);
520}
521
522TQFont KivioShapeData::textFont()
523{
524 if( m_pTextData )
525 return m_pTextData->font();
526
527 return TQFont("Times");
528}
529
530void KivioShapeData::setTextFont( const TQFont &f )
531{
532 if( m_pTextData )
533 m_pTextData->setFont(f);
534}
535
536TQColor KivioShapeData::textColor()
537{
538 if( m_pTextData )
539 return m_pTextData->color();
540
541 return TQColor(0,0,0);
542}
543
544void KivioShapeData::setTextColor( TQColor c )
545{
546 if( m_pTextData )
547 m_pTextData->setColor(c);
548}
549
550void KivioShapeData::setTextStyle( KivioTextStyle *pStyle )
551{
552 if( m_pTextData )
553 {
554 pStyle->copyInto( m_pTextData );
555 }
556}
557
558void KivioShapeData::setLineStyle(KivioLineStyle ls)
559{
560 if(m_pLineStyle) {
561 ls.copyInto(m_pLineStyle);
562 }
563}
A class containing all the data for a KivioShape.
virtual bool loadXML(const TQDomElement &)
Load this object from an XML element.
KivioShapeType
The possible shape types.
virtual TQDomElement saveXML(TQDomDocument &)
Save this object to an XML element.