You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
koffice/kivio/kiviopart/kiviosdk/kivio_shape.cpp

665 lines
18 KiB

/*
* 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 <stdio.h>
#include <kdebug.h>
#include "kivio_common.h"
#include "kivio_fill_style.h"
#include "kivio_line_style.h"
#include "kivio_point.h"
#include "kivio_shape.h"
#include "kivio_text_style.h"
/**
* Default constructor
*
* Does nothing
*/
KivioShape::KivioShape()
{
}
/**
* Copy constructor
*
* @param source The object to copy data from
*
* Copies all data from source
*/
KivioShape::KivioShape( const KivioShape &source )
{
source.m_shapeData.copyInto( &m_shapeData );
}
/**
* Destructor
*/
KivioShape::~KivioShape()
{
}
/**
* Copy all data into pTarget
*
* @param pTarget The target &ref KivioShape to copy into
*
* This will copy all data contained in this, into pTarget.
*/
void KivioShape::copyInto( KivioShape *pTarget ) const
{
if( !pTarget )
return;
m_shapeData.copyInto( &(pTarget->m_shapeData) );
}
/**
* Load this object from an XML element
*
* @param e The element to load from
* @returns true on success, false on failure.
*/
bool KivioShape::loadXML( const TQDomElement &e )
{
TQDomElement ele;
TQDomNode node = e.firstChild();
TQString name = XmlReadString( e, "name", "" );
m_shapeData.setName( name );
m_shapeData.setShapeType( (KivioShapeData::KivioShapeType)XmlReadInt( e, "shapeType", -1 ));
if( m_shapeData.name().isEmpty() ||
m_shapeData.shapeType() == -1 )
{
kdWarning(43000) << "-LOAD KivioShape::loadXML() - Unknown shape or bad name read. Shape load aborted." << endl;
return false;
}
while( !node.isNull() )
{
TQString nodeName = node.nodeName();
ele = node.toElement();
if( nodeName == "KivioShapeData" )
{
m_shapeData.loadXML( ele );
}
node = node.nextSibling();
}
return true;
}
/**
* Save this object to an XML element
*
* @param doc The document to save to
* @returns TQDomElement representing this object.
*/
TQDomElement KivioShape::saveXML( TQDomDocument &doc )
{
TQDomElement e = doc.createElement("KivioShape");
XmlWriteString( e, "name", m_shapeData.m_name );
XmlWriteInt( e, "shapeType", m_shapeData.m_shapeType );
e.appendChild( m_shapeData.saveXML( doc ) );
return e;
}
/**
* Loads a shape of type arc
*
* @param e The element to load from
* @returns A newly allocated KivioShape, or NULL on error.
*
* FIXME: implement this
*/
KivioShape *KivioShape::loadShapeArc( const TQDomElement & )
{
return NULL;
}
/**
* Loads a shape of type closed-path.
*
* @param e The element to load from.
* @returns A newly allocated KivioShape, or NULL on error.
*/
KivioShape *KivioShape::loadShapeClosedPath( const TQDomElement &e )
{
KivioShape *pShape = NULL;
KivioPoint *pPoint = NULL;
TQDomNode node;
TQString nodeName;
// Create the new shape to load into
pShape = new KivioShape();
// Load the type, name, and lineWidth properties
pShape->m_shapeData.m_shapeType = KivioShapeData::kstClosedPath;
pShape->m_shapeData.m_name = XmlReadString( e, "name", "" );
// Iterate through the nodes loading the various items
node = e.firstChild();
while( !node.isNull() )
{
nodeName = node.nodeName();
// The line array is made up of pairs of points
if( nodeName == "KivioPoint" )
{
// Allocate a new point, load it, and store it in the list
pPoint = new KivioPoint(0.0f, 0.0f, KivioPoint::kptBezier);
pPoint->loadXML( node.toElement() );
pShape->m_shapeData.m_pOriginalPointList->append( pPoint );
pPoint = NULL;
}
else if( nodeName == "KivioFillStyle" )
{
pShape->m_shapeData.m_pFillStyle->loadXML( node.toElement() );
}
else if( nodeName == "KivioLineStyle" )
{
pShape->m_shapeData.m_pLineStyle->loadXML( node.toElement() );
}
node = node.nextSibling();
}
return pShape;
}
/**
* Loads a shape of type bezier
*
* @param e The element to load from.
* @returns A newly allocated KivioShape, or NULL on error.
*/
KivioShape *KivioShape::loadShapeBezier( const TQDomElement &e )
{
KivioShape *pShape = NULL;
KivioPoint *pPoint = NULL;
TQDomNode node;
TQString nodeName;
// Create the new shape to load into
pShape = new KivioShape();
// Load the type, name, and lineWidth properties
pShape->m_shapeData.m_shapeType = KivioShapeData::kstBezier;
pShape->m_shapeData.m_name = XmlReadString( e, "name", "" );
// Iterate through the nodes loading the various items
node = e.firstChild();
while( !node.isNull() )
{
nodeName = node.nodeName();
// The line array is made up of pairs of points
if( nodeName == "KivioPoint" )
{
// Allocate a new point, load it, and store it in the list
pPoint = new KivioPoint(0.0f, 0.0f, KivioPoint::kptBezier);
pPoint->loadXML( node.toElement() );
if( pPoint->pointType() != KivioPoint::kptBezier )
{
kdDebug(43000) << "KivioShape::loadShapeBezier() - Non-bezier point found. Aborting shape." << endl;
delete pPoint;
delete pShape;
return NULL;
}
pShape->m_shapeData.m_pOriginalPointList->append( pPoint );
pPoint = NULL;
}
else if( nodeName == "KivioLineStyle" )
{
pShape->m_shapeData.m_pLineStyle->loadXML( node.toElement() );
}
node = node.nextSibling();
}
if( pShape->m_shapeData.m_pOriginalPointList->count() != 4 )
{
kdDebug(43000) << "KivioShape::loadShapeBezier() - Wrong number of points loaded, should be 4, shape aborted" << endl;
delete pShape;
return NULL;
}
return pShape;
}
/**
* Loads a shape of type ellipse.
*
* @param e The element to load from.
* @returns A newly allocated KivioShape, or NULL on error.
*/
KivioShape *KivioShape::loadShapeEllipse( const TQDomElement &e )
{
KivioShape *pShape = NULL;
TQDomNode node;
TQString nodeName;
// Create the new shape to load into
pShape = new KivioShape();
// Load the type, name, and lineWidth properties
pShape->m_shapeData.m_shapeType = KivioShapeData::kstEllipse;
pShape->m_shapeData.m_name = XmlReadString( e, "name", "" );
pShape->m_shapeData.m_position.set( XmlReadFloat( e, "x", 0.0f ), XmlReadFloat( e, "y", 0.0f ) );
pShape->m_shapeData.m_dimensions.set( XmlReadFloat( e, "w", 0.0f ), XmlReadFloat( e, "h", 0.0f ) );
// Iterate through the nodes loading the various items
node = e.firstChild();
while( !node.isNull() )
{
nodeName = node.nodeName();
if( nodeName == "KivioFillStyle" )
{
pShape->m_shapeData.m_pFillStyle->loadXML( node.toElement() );
}
else if( nodeName == "KivioLineStyle" )
{
pShape->m_shapeData.m_pLineStyle->loadXML( node.toElement() );
}
node = node.nextSibling();
}
return pShape;
}
/**
* Loads a shape of type line-array.
*
* @param e The element to load from.
* @returns A newly allocated KivioShape, or NULL on error.
*/
KivioShape *KivioShape::loadShapeLineArray( const TQDomElement &e )
{
KivioShape *pShape = NULL;
KivioPoint *pPoint = NULL;
TQDomNode node;
TQString nodeName;
TQDomElement lineElement;
// Create the new shape to load into
pShape = new KivioShape();
// Load the type, name, and lineWidth properties
pShape->m_shapeData.m_shapeType = KivioShapeData::kstLineArray;
pShape->m_shapeData.m_name = XmlReadString( e, "name", "" );
// Iterate through the nodes loading the various items
node = e.firstChild();
while( !node.isNull() )
{
nodeName = node.nodeName();
// The line array is made up of pairs of points
if( nodeName == "Line" )
{
lineElement = node.toElement();
// Allocate a new point, load it, and store it in the list
pPoint = new KivioPoint( XmlReadFloat( lineElement, "x1", 0.0f ), XmlReadFloat( lineElement, "y1", 0.0f ) );
pShape->m_shapeData.m_pOriginalPointList->append( pPoint );
pPoint = new KivioPoint( XmlReadFloat( lineElement, "x2", 0.0f ), XmlReadFloat( lineElement, "y2", 0.0f ) );
pShape->m_shapeData.m_pOriginalPointList->append( pPoint );
pPoint = NULL;
}
else if( nodeName == "KivioLineStyle" )
{
pShape->m_shapeData.m_pLineStyle->loadXML( node.toElement() );
}
node = node.nextSibling();
}
return pShape;
}
/**
* Loads a shape of type open-path.
*
* @param e The element to load from.
* @returns A newly allocated KivioShape, or NULL on error.
*/
KivioShape *KivioShape::loadShapeOpenPath( const TQDomElement &e )
{
KivioShape *pShape = NULL;
KivioPoint *pPoint = NULL;
TQDomNode node;
TQString nodeName;
// Create the new shape to load into
pShape = new KivioShape();
// Load the type, name, and lineWidth properties
pShape->m_shapeData.m_shapeType = KivioShapeData::kstOpenPath;
pShape->m_shapeData.m_name = XmlReadString( e, "name", "" );
// Iterate through the nodes loading the various items
node = e.firstChild();
while( !node.isNull() )
{
nodeName = node.nodeName();
// The line array is made up of pairs of points
if( nodeName == "KivioPoint" )
{
// Allocate a new point, load it, and store it in the list
pPoint = new KivioPoint(0.0f, 0.0f, KivioPoint::kptBezier);
pPoint->loadXML( node.toElement() );
pShape->m_shapeData.m_pOriginalPointList->append( pPoint );
pPoint = NULL;
}
else if( nodeName == "KivioLineStyle" )
{
pShape->m_shapeData.m_pLineStyle->loadXML( node.toElement() );
}
node = node.nextSibling();
}
return pShape;
}
/**
* Loads a shape of type pie.
*
* @param e The element to load from.
* @returns A newly allocated KivioShape, or NULL on error.
*
* FIXME: Implement this
*/
KivioShape *KivioShape::loadShapePie( const TQDomElement & )
{
return NULL;
}
/**
* Loads a shape of type polygon.
*
* @param e The element to load from.
* @returns A newly allocated KivioShape, or NULL on error.
*/
KivioShape *KivioShape::loadShapePolygon( const TQDomElement &e )
{
KivioShape *pShape = NULL;
KivioPoint *pPoint = NULL;
TQDomNode node;
TQString nodeName;
// Create the new shape to load into
pShape = new KivioShape();
// Load the type, name, and lineWidth properties
pShape->m_shapeData.m_shapeType = KivioShapeData::kstPolygon;
pShape->m_shapeData.m_name = XmlReadString( e, "name", "" );
// Iterate through the nodes loading the various items
node = e.firstChild();
while( !node.isNull() )
{
nodeName = node.nodeName();
// The polygon is made up of a series of points
if( nodeName == "KivioPoint" )
{
// Allocate a new point, load it, and store it in the list
pPoint = new KivioPoint();
pPoint->loadXML( node.toElement() );
pShape->m_shapeData.m_pOriginalPointList->append( pPoint );
pPoint = NULL;
}
else if( nodeName == "KivioFillStyle" )
{
pShape->m_shapeData.m_pFillStyle->loadXML( node.toElement() );
}
else if( nodeName == "KivioLineStyle" )
{
pShape->m_shapeData.m_pLineStyle->loadXML( node.toElement() );
}
node = node.nextSibling();
}
return pShape;
}
/**
* Loads a shape of type polyline.
*
* @param e The element to load from.
* @returns A newly allocated KivioShape, or NULL on error.
*/
KivioShape *KivioShape::loadShapePolyline( const TQDomElement &e )
{
KivioShape *pShape = NULL;
KivioPoint *pPoint = NULL;
TQDomNode node;
TQString nodeName;
// Create the new shape to load into
pShape = new KivioShape();
// Load the type, name, and lineWidth properties
pShape->m_shapeData.m_shapeType = KivioShapeData::kstPolyline;
pShape->m_shapeData.m_name = XmlReadString( e, "name", "" );
// Iterate through the nodes loading the various items
node = e.firstChild();
while( !node.isNull() )
{
nodeName = node.nodeName();
// The polygon is made up of a series of points
if( nodeName == "KivioPoint" )
{
// Allocate a new point, load it, and store it in the list
pPoint = new KivioPoint();
pPoint->loadXML( node.toElement() );
pShape->m_shapeData.m_pOriginalPointList->append( pPoint );
pPoint = NULL;
}
else if( nodeName == "KivioLineStyle" )
{
pShape->m_shapeData.m_pLineStyle->loadXML( node.toElement() );
}
node = node.nextSibling();
}
return pShape;
}
/**
* Loads a shape of type rectangle.
*
* @param e The element to load from.
* @returns A newly allocated KivioShape, or NULL on error.
*/
KivioShape *KivioShape::loadShapeRectangle( const TQDomElement &e )
{
KivioShape *pShape = NULL;
TQDomNode node;
TQString nodeName;
// Create the new shape to load into
pShape = new KivioShape();
// Load the type, name, and lineWidth properties
pShape->m_shapeData.m_shapeType = KivioShapeData::kstRectangle;
pShape->m_shapeData.m_name = XmlReadString( e, "name", "" );
pShape->m_shapeData.m_position.set( XmlReadFloat( e, "x", 0.0f ), XmlReadFloat( e, "y", 0.0f ) );
pShape->m_shapeData.m_dimensions.set( XmlReadFloat( e, "w", 72.0f ), XmlReadFloat( e, "h", 72.0f ) );
// Iterate through the nodes loading the various items
node = e.firstChild();
while( !node.isNull() )
{
nodeName = node.nodeName();
// Read the fill style
if( nodeName == "KivioFillStyle" )
{
pShape->m_shapeData.m_pFillStyle->loadXML( node.toElement() );
}
else if( nodeName == "KivioLineStyle" )
{
pShape->m_shapeData.m_pLineStyle->loadXML( node.toElement() );
}
node = node.nextSibling();
}
return pShape;
}
/**
* Loads a shape of type round rectangle.
*
* @param e The element to load from.
* @returns A newly allocated KivioShape, or NULL on error.
*/
KivioShape *KivioShape::loadShapeRoundRectangle( const TQDomElement &e )
{
KivioShape *pShape = NULL;
KivioPoint *pPoint = NULL;
TQDomNode node;
TQString nodeName;
// Create the new shape to load into
pShape = new KivioShape();
// Load the type, name, and lineWidth properties
pShape->m_shapeData.m_shapeType = KivioShapeData::kstRoundRectangle;
pShape->m_shapeData.m_name = XmlReadString( e, "name", "" );
pShape->m_shapeData.m_position.set( XmlReadFloat( e, "x", 0.0f ), XmlReadFloat( e, "y", 0.0f ) );
pShape->m_shapeData.m_dimensions.set( XmlReadFloat( e, "w", 72.0f ), XmlReadFloat( e, "h", 72.0f ) );
// Read and store the radii of the curves
pPoint = new KivioPoint(0.0f, 0.0f);
pPoint->set( XmlReadFloat( e, "r1", 1.0f ), XmlReadFloat( e, "r2", 1.0f ) );
pShape->m_shapeData.m_pOriginalPointList->append( pPoint );
// Iterate through the nodes loading the various items
node = e.firstChild();
while( !node.isNull() )
{
nodeName = node.nodeName();
// Read the fill style
if( nodeName == "KivioFillStyle" )
{
pShape->m_shapeData.m_pFillStyle->loadXML( node.toElement() );
}
else if( nodeName == "KivioLineStyle" )
{
pShape->m_shapeData.m_pLineStyle->loadXML( node.toElement() );
}
node = node.nextSibling();
}
return pShape;
}
/**
* Loads a shape of type textbox.
*
* @param e The element to load from.
* @returns A newly allocated KivioShape, or NULL on error.
*/
KivioShape *KivioShape::loadShapeTextBox( const TQDomElement &e )
{
KivioShape *pShape = NULL;
TQDomNode node;
TQString nodeName;
KivioTextStyle ts;
TQString name;
// Create the new shape to load into
pShape = new KivioShape();
// Load the type and name
pShape->m_shapeData.setShapeType(KivioShapeData::kstTextBox);
pShape->m_shapeData.setName( XmlReadString( e, "name", "" ) );
pShape->m_shapeData.setTextColor(XmlReadColor(e,"color",TQColor(0,0,0)));
pShape->m_shapeData.m_position.set(
XmlReadFloat( e, "x", 0.0f ), XmlReadFloat( e, "y", 0.0f ) );
pShape->m_shapeData.m_dimensions.set(
XmlReadFloat( e, "w", 72.0f ), XmlReadFloat( e, "h", 72.0f ) );
// Now look for the KivioTextStyle
node = e.firstChild();
while( !node.isNull() )
{
nodeName = node.nodeName();
if( nodeName == "KivioTextStyle" )
{
ts.loadXML( node.toElement() );
pShape->m_shapeData.setTextStyle( &ts );
}
node = node.nextSibling();
}
// TQString text = XmlReadString( e, "text", "" );
// pShape->m_shapeData.setText( text );
return pShape;
}