kivio

kivio_shape_data.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_fill_style.h"
00021 #include "kivio_line_style.h"
00022 #include "kivio_point.h"
00023 #include "kivio_shape_data.h"
00024 #include "kivio_text_style.h"
00025 
00026 #include <qpainter.h>
00027 #include <kdebug.h>
00028 
00029 /*
00030  * Struct for holding information about a shape type
00031  */
00032 struct KivioShapeTypeInfo
00033 {
00034     const char *name;
00035     KivioShapeData::KivioShapeType type;
00036 };
00037 
00038 /*
00039  * Array of shape info used for loading/saving.
00040  */
00041 static const int numShapeInfo = 12;
00042 static struct KivioShapeTypeInfo shapeInfo[] = {
00043     { "Arc",        KivioShapeData::kstArc                  },
00044     { "Pie",        KivioShapeData::kstPie                  },
00045     { "LineArray",  KivioShapeData::kstLineArray            },
00046     { "Polyline",   KivioShapeData::kstPolyline             },
00047     { "Polygon",    KivioShapeData::kstPolygon              },
00048     { "Bezier",     KivioShapeData::kstBezier               },
00049     { "Rectangle",  KivioShapeData::kstRectangle            },
00050     { "RoundRectangle",   KivioShapeData::kstRoundRectangle },
00051     { "Ellipse",    KivioShapeData::kstEllipse              },
00052     { "OpenPath",   KivioShapeData::kstOpenPath             },
00053     { "ClosedPath", KivioShapeData::kstClosedPath           },
00054     { "TextBox",    KivioShapeData::kstTextBox              }
00055 };
00056 
00057 
00058 /*****************
00059  * FIXME
00060  *
00061  * Down the road, this will be phased out because of the KivioTextStyle
00062  * class.  But it's here for now to keep backwards compatibility with
00063  * beta 2 -- even though noone should be using it for anything important!!!
00064  ****************/
00065 KivioTextShapeData::KivioTextShapeData()
00066 {
00067     m_text = "";
00068     m_textFont = QFont("Times");
00069     m_textColor = QColor(0,0,0);
00070     m_isHtml = false;
00071     m_hTextAlign = Qt::AlignHCenter;
00072     m_vTextAlign = Qt::AlignVCenter;
00073 }
00074 
00075 
00076 KivioShapeData::KivioShapeData()
00077     : m_pOriginalPointList(NULL),
00078       m_pFillStyle(NULL)
00079 {
00080     m_pOriginalPointList = new QPtrList<KivioPoint>;
00081     m_pOriginalPointList->setAutoDelete(true);
00082 
00083     m_pFillStyle = new KivioFillStyle();
00084     m_pLineStyle = new KivioLineStyle();
00085 //    m_fgColor = QColor( 0, 0, 0 );
00086 
00087     m_shapeType = kstNone;
00088     m_name = "";
00089 //    m_lineWidth = 1.0f;
00090 
00091     m_pTextData = NULL;
00092 
00093     m_position.set( 0.0f, 0.0f );
00094     m_dimensions.set( 72.0f, 72.0f );
00095 }
00096 
00097 KivioShapeData::KivioShapeData( const KivioShapeData &source )
00098     : m_pOriginalPointList(NULL),
00099       m_pFillStyle(NULL)
00100 {
00101     // Allocate a new point list
00102     KivioPoint *pPoint;
00103     m_pOriginalPointList = new QPtrList<KivioPoint>;
00104     m_pOriginalPointList->setAutoDelete(true);
00105 
00106     // Copy over the point list
00107     pPoint = source.m_pOriginalPointList->first();
00108     while( pPoint )
00109     {
00110         m_pOriginalPointList->append( new KivioPoint( *pPoint ) );
00111         pPoint = source.m_pOriginalPointList->next();
00112     }
00113 
00114     // Copy the fill/line styles
00115     m_pFillStyle = new KivioFillStyle( *(source.m_pFillStyle) );
00116     m_pLineStyle = new KivioLineStyle( *(source.m_pLineStyle) );
00117 
00118     // Copy the fg color
00119     //m_fgColor = source.m_fgColor;
00120 
00121     // Copy the rest
00122     m_shapeType = source.m_shapeType;
00123     m_name      = QString(source.m_name);
00124     //m_lineWidth = source.m_lineWidth;
00125 
00126     // Copy the position and size
00127     source.m_position.copyInto( &m_position );
00128     source.m_dimensions.copyInto( &m_dimensions );
00129 
00130     // If this is a text shape, allocate a text data struct and copy the info
00131     if( m_shapeType == kstTextBox )
00132     {
00133         m_pTextData = new KivioTextStyle();
00134 
00135         source.m_pTextData->copyInto( m_pTextData );
00136 /*
00137         m_pTextData->m_text       = ((KivioShapeData)source).text();
00138         m_pTextData->m_isHtml     = ((KivioShapeData)source).isHtml();
00139         m_pTextData->m_hTextAlign = ((KivioShapeData)source).hTextAlign();
00140         m_pTextData->m_vTextAlign = ((KivioShapeData)source).vTextAlign();
00141         m_pTextData->m_textFont   = ((KivioShapeData)source).textFont();
00142         m_pTextData->m_textColor  = ((KivioShapeData)source).textColor();
00143 */
00144     }
00145     else
00146         m_pTextData = NULL;
00147 
00148 }
00149 
00150 
00151 KivioShapeData::~KivioShapeData()
00152 {
00153     if( m_pOriginalPointList )
00154     {
00155         delete m_pOriginalPointList;
00156         m_pOriginalPointList = NULL;
00157     }
00158 
00159     if( m_pFillStyle )
00160     {
00161         delete m_pFillStyle;
00162         m_pFillStyle = NULL;
00163     }
00164 
00165     if( m_pLineStyle )
00166     {
00167         delete m_pLineStyle;
00168         m_pLineStyle = NULL;
00169     }
00170 
00171     if( m_pTextData )
00172     {
00173         delete m_pTextData;
00174         m_pTextData = NULL;
00175     }
00176 }
00177 
00178 
00179 void KivioShapeData::copyInto( KivioShapeData *pTarget ) const
00180 {
00181     KivioPoint *pPoint;
00182 
00183     if( !pTarget )
00184         return;
00185 
00186     // Delete the old point list
00187     if( pTarget->m_pOriginalPointList )
00188     {
00189         delete pTarget->m_pOriginalPointList;
00190         pTarget->m_pOriginalPointList = NULL;
00191     }
00192 
00193     // Create a new point list and copy it over
00194     pTarget->m_pOriginalPointList = new QPtrList<KivioPoint>;
00195     pTarget->m_pOriginalPointList->setAutoDelete(true);
00196     pPoint = m_pOriginalPointList->first();
00197     while( pPoint )
00198     {
00199         pTarget->m_pOriginalPointList->append( new KivioPoint( *pPoint ) );
00200         pPoint = m_pOriginalPointList->next();
00201     }
00202 
00203     // Copy the fill/line styles
00204     m_pFillStyle->copyInto( pTarget->m_pFillStyle );
00205     m_pLineStyle->copyInto( pTarget->m_pLineStyle );
00206 
00207     // Copy the fg color
00208     //pTarget->m_fgColor = m_fgColor;
00209 
00210     // Copy the rest
00211     pTarget->m_shapeType = m_shapeType;
00212     pTarget->m_name = QString(m_name);
00213     //pTarget->m_lineWidth = m_lineWidth;
00214 
00215     m_position.copyInto( &(pTarget->m_position) );
00216     m_dimensions.copyInto( &(pTarget->m_dimensions) );
00217 
00218 
00219     // If this is a textbox, allocate & copy
00220     if( m_shapeType == kstTextBox )
00221     {
00222         if( !pTarget->m_pTextData )
00223         {
00224             pTarget->m_pTextData = new KivioTextStyle();
00225         }
00226 
00227         if( m_pTextData )
00228         {
00229             m_pTextData->copyInto( pTarget->m_pTextData );
00230         }
00231         else
00232         {
00233        kdWarning(43000) << "KivioShapeData::copyInto() - Shape is of type text-box, but our text data doens't exist." << endl;
00234             pTarget->m_pTextData->setText("");
00235             pTarget->m_pTextData->setIsHtml(false);
00236             pTarget->m_pTextData->setHTextAlign(Qt::AlignHCenter);
00237             pTarget->m_pTextData->setVTextAlign(Qt::AlignVCenter);
00238             pTarget->m_pTextData->setFont( QFont("Times",12) );
00239             pTarget->m_pTextData->setColor( QColor(0,0,0) );
00240         }
00241     }
00242     else
00243     {
00244         if( pTarget->m_pTextData )
00245         {
00246             delete pTarget->m_pTextData;
00247             pTarget->m_pTextData = NULL;
00248         }
00249     }
00250 }
00251 
00252 
00257 bool KivioShapeData::loadXML( const QDomElement &e )
00258 {
00259     QDomNode node;
00260     QDomElement ele;
00261 
00262     // Maintain backwards compatibility with the eariler betas. They saved
00263     // fg color and line style in this node.
00264     m_pLineStyle->setColor( XmlReadColor( e, "fgColor", QColor(0,0,0) ) );
00265     m_pLineStyle->setWidth( XmlReadFloat( e, "lineWidth", 1.0f ) );
00266 
00267 
00268     node = e.firstChild();
00269     while( !node.isNull() )
00270     {
00271         QString nodeName = node.nodeName();
00272         ele = node.toElement();
00273 
00274         if( nodeName == "KivioLineStyle" )
00275         {
00276             m_pLineStyle->loadXML( ele );
00277         }
00278         else if( nodeName == "KivioFillStyle" )
00279         {
00280             m_pFillStyle->loadXML( ele );
00281         }
00282         else if( nodeName == "KivioTextStyle" )
00283         {
00284 
00285             // First make sure we are a text box
00286             if( m_shapeType == kstTextBox )
00287             {
00288                 // If we don't have text data, allocate it
00289                 if( !m_pTextData )
00290                     m_pTextData = new KivioTextStyle();
00291 
00292                 m_pTextData->loadXML( ele );
00293 
00294             } // end if m_shapeType==kstTextBox
00295         }
00296         else if( nodeName == "KivioText" )
00297         {
00298             // First make sure we are a text box
00299             if( m_shapeType == kstTextBox )
00300             {
00301                 KivioTextShapeData *pData = new KivioTextShapeData;
00302 
00303                 pData->m_text = XmlReadString( ele, "text", "" );
00304                 pData->m_isHtml = (bool)XmlReadInt( ele, "isHtml", (int)false );
00305 
00306                 pData->m_hTextAlign = XmlReadInt( ele, "hTextAlign", Qt::AlignHCenter );
00307                 pData->m_vTextAlign = XmlReadInt( ele, "vTextAlign", Qt::AlignVCenter );
00308 
00309                 // Search for the font
00310                 QDomNode innerNode = ele.firstChild();
00311                 while( !innerNode.isNull() )
00312                 {
00313                     QString innerName = innerNode.nodeName();
00314                     QDomElement innerE = innerNode.toElement();
00315 
00316                     if( innerName == "TextFont" )
00317                     {
00318                         pData->m_textFont.setFamily( XmlReadString(innerE, "family", "times") );
00319                         pData->m_textFont.setPointSize( XmlReadInt(innerE, "size", 12 ) );
00320                         pData->m_textFont.setBold( (bool)XmlReadInt( innerE, "bold", 12 ) );
00321                         pData->m_textFont.setItalic( (bool)XmlReadInt( innerE, "italic", 12 ) );
00322                         pData->m_textFont.setUnderline( (bool)XmlReadInt( innerE, "underline", 12 ) );
00323                         pData->m_textFont.setStrikeOut( (bool)XmlReadInt( innerE, "strikeOut", 12 ) );
00324                         pData->m_textFont.setFixedPitch( (bool)XmlReadInt( innerE, "fixedPitch", false ) );
00325                         pData->m_textColor = XmlReadColor( innerE, "color", QColor(0,0,0) );
00326                     }
00327 
00328                     innerNode = innerNode.nextSibling();
00329                 }
00330 
00331                 // Now convert it to a KivioTextStyle
00332                 if( !m_pTextData )
00333                     m_pTextData = new KivioTextStyle();
00334 
00335                 m_pTextData->setText( pData->m_text );
00336                 m_pTextData->setHTextAlign( pData->m_hTextAlign );
00337                 m_pTextData->setVTextAlign( pData->m_vTextAlign );
00338                 m_pTextData->setFont( pData->m_textFont );
00339                 m_pTextData->setColor( pData->m_textColor );
00340 
00341             } // end if m_shapeType==kstTextBox
00342             else
00343             {
00344            kdDebug(43000) << "KivioShapeData::loadXML() - Loading KivioText, but this is not a textbox!" << endl;
00345             }
00346         }
00347 
00348         node = node.nextSibling();
00349     }
00350 
00351     return true;
00352 }
00353 
00358 QDomElement KivioShapeData::saveXML( QDomDocument &doc )
00359 {
00360     QDomElement e = doc.createElement("KivioShapeData");
00361 
00362     // FIXME: Do we need to save m_pOriginalPointList
00363 
00364     // We save all this, but we won't necessarily load it back.
00365 
00366     // The positions
00367     QDomElement posE = doc.createElement("Position");
00368     XmlWriteFloat( posE, "x", m_position.x() );
00369     XmlWriteFloat( posE, "y", m_position.y() );
00370     e.appendChild( posE );
00371 
00372     // The dimensions
00373     QDomElement dimE = doc.createElement("Dimension");
00374     XmlWriteFloat( dimE, "w", m_dimensions.x() );
00375     XmlWriteFloat( dimE, "h", m_dimensions.y() );
00376     e.appendChild( dimE );
00377 
00378     // The FGColor
00379 //    QDomElement foreE = doc.createElement("Foreground");
00380 //    XmlWriteUInt( foreE, "color", m_fgColor.rgb() );
00381 //    XmlWriteFloat( foreE, "lineWidth", m_lineWidth );
00382 //    e.appendChild( foreE );
00383     QDomElement foreE = m_pLineStyle->saveXML( doc );
00384     e.appendChild( foreE );
00385 
00386 
00387     // Save if we are a text box etc...
00388     if( m_shapeType == kstTextBox )
00389     {
00390         if( m_pTextData )
00391         {
00392             e.appendChild( m_pTextData->saveXML(doc) );
00393         /*
00394             // The text & formatting
00395             QDomElement textE = doc.createElement("KivioText");
00396             XmlWriteString( textE, "text", m_pTextData->m_text );
00397             XmlWriteInt( textE, "isHtml", m_pTextData->m_isHtml );
00398             XmlWriteInt( textE, "hTextAlign", m_pTextData->m_hTextAlign );
00399             XmlWriteInt( textE, "vTextAlign", m_pTextData->m_vTextAlign );
00400 
00401             // Text font & color
00402             QDomElement innerTextE = doc.createElement("TextFont");
00403             XmlWriteString( innerTextE, "family", m_pTextData->m_textFont.family() );
00404             XmlWriteColor( innerTextE, "color", m_pTextData->m_textColor );
00405             XmlWriteInt( innerTextE, "size", m_pTextData->m_textFont.pointSize() );
00406             XmlWriteInt( innerTextE, "bold", m_pTextData->m_textFont.bold() );
00407             XmlWriteInt( innerTextE, "italic", m_pTextData->m_textFont.italic() );
00408             XmlWriteInt( innerTextE, "underline", m_pTextData->m_textFont.underline() );
00409             XmlWriteInt( innerTextE, "strikeOut", m_pTextData->m_textFont.strikeOut() );
00410             XmlWriteInt( innerTextE, "fixedPitch", m_pTextData->m_textFont.fixedPitch() );
00411 
00412             textE.appendChild( innerTextE );
00413             e.appendChild( textE );
00414         */
00415         }
00416     }
00417 
00418 
00419 
00420     // The BGFillStyle
00421     e.appendChild( m_pFillStyle->saveXML( doc ) );
00422 
00423     // Shape type & name are stored in the shape node
00424     //XmlWriteInt( e, "shapeType", m_shapeType );
00425     //XmlWriteString( e, "name", m_name );
00426 
00427     return e;
00428 }
00429 
00430 
00431 KivioShapeData::KivioShapeType KivioShapeData::shapeTypeFromString( const QString &str )
00432 {
00433 
00434     for( int i=0; i<numShapeInfo; i++ )
00435     {
00436         if( str.compare( shapeInfo[i].name )==0 )
00437             return shapeInfo[i].type;
00438     }
00439 
00440     return kstNone;
00441 }
00442 
00443 void KivioShapeData::setShapeType( KivioShapeType st )
00444 {
00445     m_shapeType = st;
00446 
00447     // If it is a text box, make sure we have text data
00448     if( st == kstTextBox )
00449     {
00450         if( !m_pTextData )
00451             m_pTextData = new KivioTextStyle();
00452     }
00453     else    // Otherwise, make sure we DON'T have it.
00454     {
00455         if( m_pTextData )
00456         {
00457             delete m_pTextData;
00458             m_pTextData = NULL;
00459         }
00460     }
00461 }
00462 
00463 
00464 QString KivioShapeData::text()
00465 {
00466     if( m_pTextData )
00467         return m_pTextData->text();
00468 
00469     return QString("");
00470 }
00471 
00472 void KivioShapeData::setText( const QString &newText )
00473 {
00474     if( m_pTextData )
00475     {
00476         m_pTextData->setText(newText);
00477     }
00478 }
00479 
00480 bool KivioShapeData::isHtml() const
00481 {
00482     if( m_pTextData )
00483         return m_pTextData->isHtml();
00484 
00485     return false;
00486 }
00487 
00488 void KivioShapeData::setIsHtml( bool b )
00489 {
00490     if( m_pTextData )
00491         m_pTextData->setIsHtml(b);
00492 }
00493 
00494 int KivioShapeData::hTextAlign() const
00495 {
00496     if( m_pTextData )
00497         return m_pTextData->hTextAlign();
00498 
00499     return Qt::AlignHCenter;
00500 }
00501 
00502 void KivioShapeData::setHTextAlign( int i )
00503 {
00504     if( m_pTextData )
00505         m_pTextData->setHTextAlign(i);
00506 }
00507 
00508 int KivioShapeData::vTextAlign() const
00509 {
00510     if( m_pTextData )
00511         return m_pTextData->vTextAlign();
00512 
00513     return Qt::AlignVCenter;
00514 }
00515 
00516 void KivioShapeData::setVTextAlign( int i )
00517 {
00518     if( m_pTextData )
00519         m_pTextData->setVTextAlign(i);
00520 }
00521 
00522 QFont KivioShapeData::textFont()
00523 {
00524     if( m_pTextData )
00525         return m_pTextData->font();
00526 
00527     return QFont("Times");
00528 }
00529 
00530 void KivioShapeData::setTextFont( const QFont &f )
00531 {
00532     if( m_pTextData )
00533         m_pTextData->setFont(f);
00534 }
00535 
00536 QColor KivioShapeData::textColor()
00537 {
00538     if( m_pTextData )
00539         return m_pTextData->color();
00540 
00541     return QColor(0,0,0);
00542 }
00543 
00544 void KivioShapeData::setTextColor( QColor c )
00545 {
00546     if( m_pTextData )
00547         m_pTextData->setColor(c);
00548 }
00549 
00550 void KivioShapeData::setTextStyle( KivioTextStyle *pStyle )
00551 {
00552    if( m_pTextData )
00553    {
00554       pStyle->copyInto( m_pTextData );
00555    }
00556 }
00557 
00558 void KivioShapeData::setLineStyle(KivioLineStyle ls)
00559 {
00560     if(m_pLineStyle) {
00561       ls.copyInto(m_pLineStyle);
00562     }
00563 }
KDE Home | KDE Accessibility Home | Description of Access Keys