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_dia_stencil_spawner.cpp

504 lines
19 KiB

/*
* Kivio - Visual Modelling and Flowcharting
* Copyright (C) 2001 Nikolas Zimmermann <wildfox@kde.org>
*
* 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 <tqdom.h>
#include <tqfile.h>
#include <tqregexp.h>
#include <tqstringlist.h>
#include <kdebug.h>
#include <math.h>
#include "kivio_stencil.h"
#include "kivio_dia_stencil_spawner.h"
#include "diapathparser.h"
KivioDiaStencilSpawner::KivioDiaStencilSpawner(KivioStencilSpawnerSet *p) : KivioStencilSpawner(p)
{
m_smlStencilSpawner = new KivioSMLStencilSpawner(p);
}
KivioDiaStencilSpawner::~KivioDiaStencilSpawner()
{
}
TQDomElement KivioDiaStencilSpawner::saveXML(TQDomDocument &d)
{
return m_smlStencilSpawner->saveXML(d);
}
void KivioDiaStencilSpawner::calculateDimensions(float x, float y)
{
m_xlist.append(x);
m_ylist.append(y);
}
float KivioDiaStencilSpawner::diaPointToKivio(float point, bool xpoint)
{
float returnPoint = 0.0;
if(xpoint)
{
//if(m_lowestx < 0)
returnPoint = point - m_lowestx;
//else
// returnPoint = (fabs(m_highestx) - fabs(m_lowestx)) - (fabs(m_highestx) + fabs(point));
}
else
{
//if(m_lowesty < 0)
returnPoint =point - m_lowesty;
//else
// returnPoint = (fabs(m_highesty) + fabs(m_lowesty)) - (fabs(m_highesty) + fabs(point));
}
//kdDebug () << "Point " << point << " Return point " << returnPoint << endl;
return returnPoint;
}
bool KivioDiaStencilSpawner::load(const TQString &file)
{
TQDomDocument dia("test");
TQDomDocument kivio("XML");
m_filename = file;
TQFile f(file);
if(f.open(IO_ReadOnly) == false)
{
kdDebug(43000) << "KivioDiaStencilSpawner::load() - Error opening stencil: " << file << endl;
return false;
}
dia.setContent(&f);
TQDomNode diaMain = dia.namedItem("shape");
// Set "creator" attribute
TQDomElement firstElement = kivio.createElement("KivioShapeStencil");
firstElement.setAttribute("creator", "kiviodiafilter");
kivio.appendChild(firstElement);
// Add KivioSMLStencilSpawnerInfo
TQDomElement spawnerInfoElement = kivio.createElement("KivioSMLStencilSpawnerInfo");
TQDomElement authorInfoElement = kivio.createElement("Author");
authorInfoElement.setAttribute("data", "n/a");
TQDomElement titleInfoElement = kivio.createElement("Title");
titleInfoElement.setAttribute("data", diaMain.namedItem("name").toElement().text());
TQDomElement idInfoElement = kivio.createElement("Id");
idInfoElement.setAttribute("data", diaMain.namedItem("name").toElement().text());
TQDomElement descriptionInfoElement = kivio.createElement("Description");
descriptionInfoElement.setAttribute("data", diaMain.namedItem("description").toElement().text());
TQDomElement versionInfoElement = kivio.createElement("Version");
versionInfoElement.setAttribute("data", "1.0");
TQDomElement webInfoElement = kivio.createElement("Web");
webInfoElement.setAttribute("data", "http://");
TQDomElement emailInfoElement = kivio.createElement("Email");
emailInfoElement.setAttribute("data", "n/a");
TQDomElement copyrightInfoElement = kivio.createElement("Copyright");
copyrightInfoElement.setAttribute("data", "n/a");
TQDomElement autoUpdateInfoElement = kivio.createElement("AutoUpdate");
autoUpdateInfoElement.setAttribute("data", "off");
spawnerInfoElement.appendChild(authorInfoElement);
spawnerInfoElement.appendChild(titleInfoElement);
spawnerInfoElement.appendChild(idInfoElement);
spawnerInfoElement.appendChild(descriptionInfoElement);
spawnerInfoElement.appendChild(versionInfoElement);
spawnerInfoElement.appendChild(webInfoElement);
spawnerInfoElement.appendChild(emailInfoElement);
spawnerInfoElement.appendChild(copyrightInfoElement);
spawnerInfoElement.appendChild(autoUpdateInfoElement);
kivio.documentElement().appendChild(spawnerInfoElement);
m_xscale = m_yscale = 20.0f;
// Add Dimensions
TQDomElement dimensionsElement = kivio.createElement("Dimensions");
kivio.documentElement().appendChild(dimensionsElement);
// Calculate Dimensions
TQDomElement svgElement = diaMain.namedItem("svg:svg").toElement();
TQDomNode svgNode = svgElement.firstChild();
while(!svgNode.isNull())
{
TQDomElement svgChild = svgNode.toElement();
if(!svgChild.isNull())
{
if(svgChild.tagName() == "svg:rect")
{
// TODO: rx and ry -> rounded rects
if(svgChild.hasAttribute("x") && svgChild.hasAttribute("y") && svgChild.hasAttribute("width") && svgChild.hasAttribute("height"))
{
calculateDimensions(svgChild.attribute("x").toFloat(), svgChild.attribute("y").toFloat());
calculateDimensions(svgChild.attribute("x").toFloat() + svgChild.attribute("width").toFloat(), svgChild.attribute("y").toFloat() + svgChild.attribute("height").toFloat());
}
}
else if(svgChild.tagName() == "svg:circle")
{
if(svgChild.hasAttribute("cx") && svgChild.hasAttribute("cy") && svgChild.hasAttribute("r"))
{
calculateDimensions((svgChild.attribute("cx").toFloat()) - (svgChild.attribute("r").toFloat()), (svgChild.attribute("cy").toFloat()) - (svgChild.attribute("r").toFloat()));
calculateDimensions((svgChild.attribute("cx").toFloat()) + (svgChild.attribute("r").toFloat()), (svgChild.attribute("cy").toFloat()) + (svgChild.attribute("r").toFloat()));
}
}
else if(svgChild.tagName() == "svg:ellipse")
{
if(svgChild.hasAttribute("cx") && svgChild.hasAttribute("cy") && svgChild.hasAttribute("rx") && svgChild.hasAttribute("ry"))
{
calculateDimensions((svgChild.attribute("cx").toFloat()) - (svgChild.attribute("rx").toFloat()), (svgChild.attribute("cy").toFloat()) - (svgChild.attribute("ry").toFloat()));
calculateDimensions((svgChild.attribute("cx").toFloat()) + (svgChild.attribute("rx").toFloat()), (svgChild.attribute("cy").toFloat()) + (svgChild.attribute("ry").toFloat()));
}
}
else if(svgChild.tagName() == "svg:line")
{
if(svgChild.hasAttribute("x1") && svgChild.hasAttribute("y1") && svgChild.hasAttribute("x2") && svgChild.hasAttribute("y2"))
{
calculateDimensions(svgChild.attribute("x1").toFloat(), svgChild.attribute("y1").toFloat());
calculateDimensions(svgChild.attribute("x2").toFloat(), svgChild.attribute("y2").toFloat());
}
}
else if(svgChild.tagName() == "svg:polyline")
{
if(svgChild.hasAttribute("points"))
{
TQStringList points = TQStringList::split(" ", svgChild.attribute("points"));
for(TQStringList::Iterator it = points.begin(); it != points.end(); ++it)
{
TQString x, y;
TQStringList parsed = TQStringList::split(",", (*it));
TQStringList::Iterator itp = parsed.begin();
x = (*itp);
++itp;
y = (*itp);
calculateDimensions(x.toFloat(), y.toFloat());
}
}
}
else if(svgChild.tagName() == "svg:polygon")
{
if(svgChild.hasAttribute("points"))
{
TQStringList points = TQStringList::split(" ", svgChild.attribute("points"));
for(TQStringList::Iterator it = points.begin(); it != points.end(); ++it)
{
TQString x, y;
TQStringList parsed = TQStringList::split(",", (*it));
TQStringList::Iterator itp = parsed.begin();
x = (*itp);
++itp;
y = (*itp);
calculateDimensions(x.toFloat(), y.toFloat());
}
}
}
else if(svgChild.tagName() == "svg:path")
{
if(svgChild.hasAttribute("d"))
{
DiaPointFinder *dpf = new DiaPointFinder(&m_xlist, &m_ylist);
dpf->parseSVG(svgChild.attribute("d"), true);
delete dpf;
}
}
}
svgNode = svgNode.nextSibling();
}
TQValueList<float>::Iterator itx = m_xlist.begin();
TQValueList<float>::Iterator ity = m_ylist.begin();
m_highestx = *itx;
m_lowestx = *itx;
m_highesty = *ity;
m_lowesty = *ity;
++itx;
++ity;
for( ; itx != m_xlist.end(); ++itx)
{
m_highestx = TQMAX(m_highestx, *itx);
m_lowestx = TQMIN(m_lowestx, *itx);
}
for( ; ity != m_ylist.end(); ++ity)
{
m_highesty = TQMAX(m_highesty, *ity);
m_lowesty = TQMIN(m_lowesty, *ity);
}
//if( svgElement.hasAttribute("width") && svgElement.hasAttribute("height"))
//{
// m_yscale = svgElement.attribute("height").toFloat()/(m_highesty - m_lowesty);
// m_xscale = svgElement.attribute("width").toFloat()/(m_highestx - m_lowestx);
//}
//else
{
// scale the shape to be close to 30 by 30
m_yscale = 30.0/(m_highesty - m_lowesty);
m_xscale = 30.0/(m_highestx - m_lowestx);
}
// Add KivioConnectorTarget's
TQDomElement connectionsElement = diaMain.namedItem("connections").toElement();
TQDomNode connectionsNode = connectionsElement.firstChild();
while(!connectionsNode.isNull())
{
TQDomElement connectionChild = connectionsNode.toElement();
if(!connectionChild.isNull())
{
if(connectionChild.tagName() == "point")
{
if(connectionChild.hasAttribute("x") && connectionChild.hasAttribute("y"))
{
TQDomElement kivioConnectorTarget = kivio.createElement("KivioConnectorTarget");
kivioConnectorTarget.setAttribute("x", TQString::number(diaPointToKivio(connectionChild.attribute("x").toFloat(),true) * m_xscale));
kivioConnectorTarget.setAttribute("y", TQString::number(diaPointToKivio(connectionChild.attribute("y").toFloat(), false) * m_yscale));
kivio.documentElement().appendChild(kivioConnectorTarget);
}
}
}
connectionsNode = connectionsNode.nextSibling();
}
// Add KivioShape's and convert to Kivio's Coordinate System
svgNode = svgElement.firstChild();
int runs = 0;
while(!svgNode.isNull())
{
TQDomElement svgChild = svgNode.toElement();
if(!svgChild.isNull())
{
if(svgChild.tagName() == "svg:rect")
{
runs++;
// TODO: rx and ry -> rounded rects
if(svgChild.hasAttribute("x") && svgChild.hasAttribute("y") && svgChild.hasAttribute("width") && svgChild.hasAttribute("height"))
{
TQDomElement kivioShape = kivio.createElement("KivioShape");
kivioShape.setAttribute("type", "Rectangle");
kivioShape.setAttribute("name", TQString::fromLatin1("Element") + TQString::number(runs));
kivioShape.setAttribute("x", TQString::number(diaPointToKivio(svgChild.attribute("x").toFloat(),true) * m_xscale));
kivioShape.setAttribute("y", TQString::number(diaPointToKivio(svgChild.attribute("y").toFloat(), false) * m_yscale));
kivioShape.setAttribute("w", TQString::number(svgChild.attribute("width").toFloat() * m_xscale));
kivioShape.setAttribute("h", TQString::number(svgChild.attribute("height").toFloat() * m_yscale));
kivio.documentElement().appendChild(kivioShape);
}
}
else if(svgChild.tagName() == "svg:circle")
{
runs++;
if(svgChild.hasAttribute("cx") && svgChild.hasAttribute("cy") && svgChild.hasAttribute("r"))
{
TQDomElement kivioShape = kivio.createElement("KivioShape");
kivioShape.setAttribute("type", "Ellipse");
kivioShape.setAttribute("name", TQString::fromLatin1("Element") + TQString::number(runs));
kivioShape.setAttribute("x", TQString::number((diaPointToKivio(svgChild.attribute("cx").toFloat() - svgChild.attribute("r").toFloat(),true) * m_xscale)));
kivioShape.setAttribute("y", TQString::number((diaPointToKivio(svgChild.attribute("cy").toFloat() - svgChild.attribute("r").toFloat(), false) * m_yscale)));
kivioShape.setAttribute("w", TQString::number(svgChild.attribute("r").toFloat() * m_xscale * 2));
kivioShape.setAttribute("h", TQString::number(svgChild.attribute("r").toFloat() * m_yscale * 2));
kivio.documentElement().appendChild(kivioShape);
}
}
else if(svgChild.tagName() == "svg:ellipse")
{
runs++;
if(svgChild.hasAttribute("cx") && svgChild.hasAttribute("cy") && svgChild.hasAttribute("rx") && svgChild.hasAttribute("ry"))
{
TQDomElement kivioShape = kivio.createElement("KivioShape");
kivioShape.setAttribute("type", "Ellipse");
kivioShape.setAttribute("name", TQString::fromLatin1("Element") + TQString::number(runs));
kivioShape.setAttribute("x", TQString::number((diaPointToKivio(svgChild.attribute("cx").toFloat() - svgChild.attribute("rx").toFloat(),true) * m_xscale)));
kivioShape.setAttribute("y", TQString::number((diaPointToKivio(svgChild.attribute("cy").toFloat() - svgChild.attribute("ry").toFloat(), false) * m_yscale)));
kivioShape.setAttribute("w", TQString::number(svgChild.attribute("rx").toFloat() * m_xscale * 2));
kivioShape.setAttribute("h", TQString::number(svgChild.attribute("ry").toFloat() * m_yscale * 2));
kivio.documentElement().appendChild(kivioShape);
}
}
else if(svgChild.tagName() == "svg:line")
{
runs++;
if(svgChild.hasAttribute("x1") && svgChild.hasAttribute("y1") && svgChild.hasAttribute("x2") && svgChild.hasAttribute("y2"))
{
TQDomElement kivioShape = kivio.createElement("KivioShape");
kivioShape.setAttribute("type", "LineArray");
kivioShape.setAttribute("name", TQString::fromLatin1("Element") + TQString::number(runs));
TQDomElement lineArrayElement = kivio.createElement("Line");
lineArrayElement.setAttribute("x1", TQString::number(diaPointToKivio(svgChild.attribute("x1").toFloat(),true) * m_xscale));
lineArrayElement.setAttribute("y1", TQString::number(diaPointToKivio(svgChild.attribute("y1").toFloat(), false) * m_yscale));
lineArrayElement.setAttribute("x2", TQString::number(diaPointToKivio(svgChild.attribute("x2").toFloat(),true) * m_xscale));
lineArrayElement.setAttribute("y2", TQString::number(diaPointToKivio(svgChild.attribute("y2").toFloat(), false) * m_yscale));
kivioShape.appendChild(lineArrayElement);
kivio.documentElement().appendChild(kivioShape);
}
}
else if(svgChild.tagName() == "svg:polyline")
{
runs++;
if(svgChild.hasAttribute("points"))
{
TQDomElement kivioShape = kivio.createElement("KivioShape");
kivioShape.setAttribute("type", "Polyline");
kivioShape.setAttribute("name", TQString::fromLatin1("Element") + TQString::number(runs));
TQStringList points = TQStringList::split(" ", svgChild.attribute("points"));
for(TQStringList::Iterator it = points.begin(); it != points.end(); ++it)
{
TQString x, y;
TQStringList parsed = TQStringList::split(",", (*it));
TQStringList::Iterator itp = parsed.begin();
x = (*itp);
++itp;
y = (*itp);
TQDomElement kivioPointElement = kivio.createElement("KivioPoint");
kivioPointElement.setAttribute("x", TQString::number(diaPointToKivio(x.toFloat(),true) * m_xscale));
kivioPointElement.setAttribute("y", TQString::number(diaPointToKivio(y.toFloat(), false) * m_yscale));
kivioShape.appendChild(kivioPointElement);
}
kivio.documentElement().appendChild(kivioShape);
}
}
else if(svgChild.tagName() == "svg:polygon")
{
runs++;
if(svgChild.hasAttribute("points"))
{
TQDomElement kivioShape = kivio.createElement("KivioShape");
kivioShape.setAttribute("type", "Polygon");
kivioShape.setAttribute("name", TQString::fromLatin1("Element") + TQString::number(runs));
TQStringList points = TQStringList::split(" ", svgChild.attribute("points"));
for(TQStringList::Iterator it = points.begin(); it != points.end(); ++it)
{
TQString x, y;
TQStringList parsed = TQStringList::split(",", (*it));
TQStringList::Iterator itp = parsed.begin();
x = (*itp);
++itp;
y = (*itp);
TQDomElement kivioPointElement = kivio.createElement("KivioPoint");
kivioPointElement.setAttribute("x", TQString::number(diaPointToKivio(x.toFloat(),true) * m_xscale));
kivioPointElement.setAttribute("y", TQString::number(diaPointToKivio(y.toFloat(), false) * m_yscale));
kivioShape.appendChild(kivioPointElement);
}
kivio.documentElement().appendChild(kivioShape);
}
}
else if(svgChild.tagName() == "svg:path")
{
runs++;
bool isClosed;
TQDomElement kivioShape = kivio.createElement("KivioShape");
if(svgChild.hasAttribute("d"))
{
if(svgChild.attribute("d").contains('z') || svgChild.attribute("d").contains('Z'))
{
isClosed = true;
kivioShape.setAttribute("type", "ClosedPath");
}
else
{
isClosed = false;
kivioShape.setAttribute("type", "OpenPath");
}
kivioShape.setAttribute("name", TQString::fromLatin1("Element") + TQString::number(runs));
DiaPathParser *dpp = new DiaPathParser(&kivio,
&kivioShape, m_xscale, m_yscale,
m_lowestx, m_lowesty);
dpp->parseSVG(svgChild.attribute("d"), true);
delete dpp;
}
if( svgChild.hasAttribute("style"))
{
// style="stroke: background; stroke-width: 0.8; stroke-miterlimit: 1; stroke-linecap: round; stroke-linejoin: round"
// Supported:
// stroke-width:
// stroke-linejoin: milter, bevel, round
// stroke-linecap: round, square, flat
// fill: ?
TQStringList styles = TQStringList::split(";", svgChild.attribute("style"));
for( uint idx = 0; idx < styles.count(); idx++)
{
//kdDebug(43000) << "Style: " << styles[idx] << endl;
if( isClosed && styles[idx].contains("fill:"))
{
TQDomElement fillStyle = kivio.createElement("KivioFillStyle");
if( styles[idx].contains("forground"))
fillStyle.setAttribute("color", "#0000");
else if (styles[idx].contains("background"))
fillStyle.setAttribute("color", "#ffff");
fillStyle.setAttribute("colorStyle", "1");
kivioShape.appendChild(fillStyle);
}
}
}
kivio.documentElement().appendChild(kivioShape);
}
}
svgNode = svgNode.nextSibling();
}
// Apply width and height
dimensionsElement.setAttribute("w", TQString::number((fabs(m_highestx - m_lowestx)) * m_xscale));
dimensionsElement.setAttribute("h", TQString::number((fabs(m_highesty - m_lowesty)) * m_yscale));
m_xlist.clear();
m_ylist.clear();
return loadXML(file, kivio);
}
bool KivioDiaStencilSpawner::loadXML(const TQString &file, TQDomDocument &d)
{
bool ret = m_smlStencilSpawner->loadXML(file, d);
m_icon = *m_smlStencilSpawner->icon();
m_pSet = m_smlStencilSpawner->set();
m_pInfo = m_smlStencilSpawner->info();
m_defWidth = m_smlStencilSpawner->defWidth();
m_defHeight = m_smlStencilSpawner->defHeight();
return ret;
}
KivioStencil *KivioDiaStencilSpawner::newStencil()
{
KivioStencil *newStencil = m_smlStencilSpawner->newStencil();
newStencil->setSpawner(this);
return newStencil;
}