00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include <qdom.h>
00021 #include <qfile.h>
00022 #include <qregexp.h>
00023 #include <qstringlist.h>
00024 #include <kdebug.h>
00025 #include <math.h>
00026
00027 #include "kivio_stencil.h"
00028 #include "kivio_dia_stencil_spawner.h"
00029 #include "diapathparser.h"
00030
00031 KivioDiaStencilSpawner::KivioDiaStencilSpawner(KivioStencilSpawnerSet *p) : KivioStencilSpawner(p)
00032 {
00033 m_smlStencilSpawner = new KivioSMLStencilSpawner(p);
00034 }
00035
00036 KivioDiaStencilSpawner::~KivioDiaStencilSpawner()
00037 {
00038 }
00039
00040 QDomElement KivioDiaStencilSpawner::saveXML(QDomDocument &d)
00041 {
00042 return m_smlStencilSpawner->saveXML(d);
00043 }
00044
00045 void KivioDiaStencilSpawner::calculateDimensions(float x, float y)
00046 {
00047 m_xlist.append(x);
00048 m_ylist.append(y);
00049 }
00050
00051 float KivioDiaStencilSpawner::diaPointToKivio(float point, bool xpoint)
00052 {
00053 float returnPoint = 0.0;
00054 if(xpoint)
00055 {
00056
00057 returnPoint = point - m_lowestx;
00058
00059
00060 }
00061 else
00062 {
00063
00064 returnPoint =point - m_lowesty;
00065
00066
00067 }
00068
00069 return returnPoint;
00070 }
00071
00072 bool KivioDiaStencilSpawner::load(const QString &file)
00073 {
00074 QDomDocument dia("test");
00075 QDomDocument kivio("XML");
00076
00077 m_filename = file;
00078 QFile f(file);
00079
00080 if(f.open(IO_ReadOnly) == false)
00081 {
00082 kdDebug(43000) << "KivioDiaStencilSpawner::load() - Error opening stencil: " << file << endl;
00083 return false;
00084 }
00085 dia.setContent(&f);
00086 QDomNode diaMain = dia.namedItem("shape");
00087
00088
00089 QDomElement firstElement = kivio.createElement("KivioShapeStencil");
00090 firstElement.setAttribute("creator", "kiviodiafilter");
00091
00092 kivio.appendChild(firstElement);
00093
00094
00095 QDomElement spawnerInfoElement = kivio.createElement("KivioSMLStencilSpawnerInfo");
00096 QDomElement authorInfoElement = kivio.createElement("Author");
00097 authorInfoElement.setAttribute("data", "n/a");
00098 QDomElement titleInfoElement = kivio.createElement("Title");
00099 titleInfoElement.setAttribute("data", diaMain.namedItem("name").toElement().text());
00100 QDomElement idInfoElement = kivio.createElement("Id");
00101 idInfoElement.setAttribute("data", diaMain.namedItem("name").toElement().text());
00102 QDomElement descriptionInfoElement = kivio.createElement("Description");
00103 descriptionInfoElement.setAttribute("data", diaMain.namedItem("description").toElement().text());
00104 QDomElement versionInfoElement = kivio.createElement("Version");
00105 versionInfoElement.setAttribute("data", "1.0");
00106 QDomElement webInfoElement = kivio.createElement("Web");
00107 webInfoElement.setAttribute("data", "http://");
00108 QDomElement emailInfoElement = kivio.createElement("Email");
00109 emailInfoElement.setAttribute("data", "n/a");
00110 QDomElement copyrightInfoElement = kivio.createElement("Copyright");
00111 copyrightInfoElement.setAttribute("data", "n/a");
00112 QDomElement autoUpdateInfoElement = kivio.createElement("AutoUpdate");
00113 autoUpdateInfoElement.setAttribute("data", "off");
00114
00115 spawnerInfoElement.appendChild(authorInfoElement);
00116 spawnerInfoElement.appendChild(titleInfoElement);
00117 spawnerInfoElement.appendChild(idInfoElement);
00118 spawnerInfoElement.appendChild(descriptionInfoElement);
00119 spawnerInfoElement.appendChild(versionInfoElement);
00120 spawnerInfoElement.appendChild(webInfoElement);
00121 spawnerInfoElement.appendChild(emailInfoElement);
00122 spawnerInfoElement.appendChild(copyrightInfoElement);
00123 spawnerInfoElement.appendChild(autoUpdateInfoElement);
00124
00125 kivio.documentElement().appendChild(spawnerInfoElement);
00126
00127 m_xscale = m_yscale = 20.0f;
00128
00129
00130 QDomElement dimensionsElement = kivio.createElement("Dimensions");
00131 kivio.documentElement().appendChild(dimensionsElement);
00132
00133
00134 QDomElement svgElement = diaMain.namedItem("svg:svg").toElement();
00135 QDomNode svgNode = svgElement.firstChild();
00136 while(!svgNode.isNull())
00137 {
00138 QDomElement svgChild = svgNode.toElement();
00139 if(!svgChild.isNull())
00140 {
00141 if(svgChild.tagName() == "svg:rect")
00142 {
00143
00144 if(svgChild.hasAttribute("x") && svgChild.hasAttribute("y") && svgChild.hasAttribute("width") && svgChild.hasAttribute("height"))
00145 {
00146 calculateDimensions(svgChild.attribute("x").toFloat(), svgChild.attribute("y").toFloat());
00147 calculateDimensions(svgChild.attribute("x").toFloat() + svgChild.attribute("width").toFloat(), svgChild.attribute("y").toFloat() + svgChild.attribute("height").toFloat());
00148 }
00149 }
00150 else if(svgChild.tagName() == "svg:circle")
00151 {
00152 if(svgChild.hasAttribute("cx") && svgChild.hasAttribute("cy") && svgChild.hasAttribute("r"))
00153 {
00154 calculateDimensions((svgChild.attribute("cx").toFloat()) - (svgChild.attribute("r").toFloat()), (svgChild.attribute("cy").toFloat()) - (svgChild.attribute("r").toFloat()));
00155 calculateDimensions((svgChild.attribute("cx").toFloat()) + (svgChild.attribute("r").toFloat()), (svgChild.attribute("cy").toFloat()) + (svgChild.attribute("r").toFloat()));
00156 }
00157 }
00158 else if(svgChild.tagName() == "svg:ellipse")
00159 {
00160 if(svgChild.hasAttribute("cx") && svgChild.hasAttribute("cy") && svgChild.hasAttribute("rx") && svgChild.hasAttribute("ry"))
00161 {
00162 calculateDimensions((svgChild.attribute("cx").toFloat()) - (svgChild.attribute("rx").toFloat()), (svgChild.attribute("cy").toFloat()) - (svgChild.attribute("ry").toFloat()));
00163 calculateDimensions((svgChild.attribute("cx").toFloat()) + (svgChild.attribute("rx").toFloat()), (svgChild.attribute("cy").toFloat()) + (svgChild.attribute("ry").toFloat()));
00164 }
00165 }
00166 else if(svgChild.tagName() == "svg:line")
00167 {
00168 if(svgChild.hasAttribute("x1") && svgChild.hasAttribute("y1") && svgChild.hasAttribute("x2") && svgChild.hasAttribute("y2"))
00169 {
00170 calculateDimensions(svgChild.attribute("x1").toFloat(), svgChild.attribute("y1").toFloat());
00171 calculateDimensions(svgChild.attribute("x2").toFloat(), svgChild.attribute("y2").toFloat());
00172 }
00173 }
00174 else if(svgChild.tagName() == "svg:polyline")
00175 {
00176 if(svgChild.hasAttribute("points"))
00177 {
00178 QStringList points = QStringList::split(" ", svgChild.attribute("points"));
00179 for(QStringList::Iterator it = points.begin(); it != points.end(); ++it)
00180 {
00181 QString x, y;
00182
00183 QStringList parsed = QStringList::split(",", (*it));
00184 QStringList::Iterator itp = parsed.begin();
00185 x = (*itp);
00186 ++itp;
00187 y = (*itp);
00188
00189 calculateDimensions(x.toFloat(), y.toFloat());
00190 }
00191 }
00192 }
00193 else if(svgChild.tagName() == "svg:polygon")
00194 {
00195 if(svgChild.hasAttribute("points"))
00196 {
00197 QStringList points = QStringList::split(" ", svgChild.attribute("points"));
00198 for(QStringList::Iterator it = points.begin(); it != points.end(); ++it)
00199 {
00200 QString x, y;
00201
00202 QStringList parsed = QStringList::split(",", (*it));
00203 QStringList::Iterator itp = parsed.begin();
00204 x = (*itp);
00205 ++itp;
00206 y = (*itp);
00207
00208 calculateDimensions(x.toFloat(), y.toFloat());
00209 }
00210 }
00211 }
00212 else if(svgChild.tagName() == "svg:path")
00213 {
00214 if(svgChild.hasAttribute("d"))
00215 {
00216 DiaPointFinder *dpf = new DiaPointFinder(&m_xlist, &m_ylist);
00217 dpf->parseSVG(svgChild.attribute("d"), true);
00218 delete dpf;
00219 }
00220 }
00221 }
00222 svgNode = svgNode.nextSibling();
00223 }
00224
00225 QValueList<float>::Iterator itx = m_xlist.begin();
00226 QValueList<float>::Iterator ity = m_ylist.begin();
00227 m_highestx = *itx;
00228 m_lowestx = *itx;
00229 m_highesty = *ity;
00230 m_lowesty = *ity;
00231 ++itx;
00232 ++ity;
00233
00234 for( ; itx != m_xlist.end(); ++itx)
00235 {
00236 m_highestx = QMAX(m_highestx, *itx);
00237 m_lowestx = QMIN(m_lowestx, *itx);
00238 }
00239
00240 for( ; ity != m_ylist.end(); ++ity)
00241 {
00242 m_highesty = QMAX(m_highesty, *ity);
00243 m_lowesty = QMIN(m_lowesty, *ity);
00244 }
00245
00246
00247
00248
00249
00250
00251
00252 {
00253
00254 m_yscale = 30.0/(m_highesty - m_lowesty);
00255 m_xscale = 30.0/(m_highestx - m_lowestx);
00256 }
00257
00258
00259 QDomElement connectionsElement = diaMain.namedItem("connections").toElement();
00260 QDomNode connectionsNode = connectionsElement.firstChild();
00261 while(!connectionsNode.isNull())
00262 {
00263 QDomElement connectionChild = connectionsNode.toElement();
00264 if(!connectionChild.isNull())
00265 {
00266 if(connectionChild.tagName() == "point")
00267 {
00268 if(connectionChild.hasAttribute("x") && connectionChild.hasAttribute("y"))
00269 {
00270 QDomElement kivioConnectorTarget = kivio.createElement("KivioConnectorTarget");
00271 kivioConnectorTarget.setAttribute("x", QString::number(diaPointToKivio(connectionChild.attribute("x").toFloat(),true) * m_xscale));
00272 kivioConnectorTarget.setAttribute("y", QString::number(diaPointToKivio(connectionChild.attribute("y").toFloat(), false) * m_yscale));
00273
00274 kivio.documentElement().appendChild(kivioConnectorTarget);
00275 }
00276 }
00277 }
00278 connectionsNode = connectionsNode.nextSibling();
00279 }
00280
00281
00282 svgNode = svgElement.firstChild();
00283 int runs = 0;
00284 while(!svgNode.isNull())
00285 {
00286 QDomElement svgChild = svgNode.toElement();
00287 if(!svgChild.isNull())
00288 {
00289 if(svgChild.tagName() == "svg:rect")
00290 {
00291 runs++;
00292
00293 if(svgChild.hasAttribute("x") && svgChild.hasAttribute("y") && svgChild.hasAttribute("width") && svgChild.hasAttribute("height"))
00294 {
00295 QDomElement kivioShape = kivio.createElement("KivioShape");
00296 kivioShape.setAttribute("type", "Rectangle");
00297 kivioShape.setAttribute("name", QString::fromLatin1("Element") + QString::number(runs));
00298 kivioShape.setAttribute("x", QString::number(diaPointToKivio(svgChild.attribute("x").toFloat(),true) * m_xscale));
00299 kivioShape.setAttribute("y", QString::number(diaPointToKivio(svgChild.attribute("y").toFloat(), false) * m_yscale));
00300 kivioShape.setAttribute("w", QString::number(svgChild.attribute("width").toFloat() * m_xscale));
00301 kivioShape.setAttribute("h", QString::number(svgChild.attribute("height").toFloat() * m_yscale));
00302 kivio.documentElement().appendChild(kivioShape);
00303 }
00304 }
00305 else if(svgChild.tagName() == "svg:circle")
00306 {
00307 runs++;
00308 if(svgChild.hasAttribute("cx") && svgChild.hasAttribute("cy") && svgChild.hasAttribute("r"))
00309 {
00310 QDomElement kivioShape = kivio.createElement("KivioShape");
00311 kivioShape.setAttribute("type", "Ellipse");
00312 kivioShape.setAttribute("name", QString::fromLatin1("Element") + QString::number(runs));
00313 kivioShape.setAttribute("x", QString::number((diaPointToKivio(svgChild.attribute("cx").toFloat() - svgChild.attribute("r").toFloat(),true) * m_xscale)));
00314 kivioShape.setAttribute("y", QString::number((diaPointToKivio(svgChild.attribute("cy").toFloat() - svgChild.attribute("r").toFloat(), false) * m_yscale)));
00315 kivioShape.setAttribute("w", QString::number(svgChild.attribute("r").toFloat() * m_xscale * 2));
00316 kivioShape.setAttribute("h", QString::number(svgChild.attribute("r").toFloat() * m_yscale * 2));
00317 kivio.documentElement().appendChild(kivioShape);
00318 }
00319 }
00320 else if(svgChild.tagName() == "svg:ellipse")
00321 {
00322 runs++;
00323 if(svgChild.hasAttribute("cx") && svgChild.hasAttribute("cy") && svgChild.hasAttribute("rx") && svgChild.hasAttribute("ry"))
00324 {
00325 QDomElement kivioShape = kivio.createElement("KivioShape");
00326 kivioShape.setAttribute("type", "Ellipse");
00327 kivioShape.setAttribute("name", QString::fromLatin1("Element") + QString::number(runs));
00328 kivioShape.setAttribute("x", QString::number((diaPointToKivio(svgChild.attribute("cx").toFloat() - svgChild.attribute("rx").toFloat(),true) * m_xscale)));
00329 kivioShape.setAttribute("y", QString::number((diaPointToKivio(svgChild.attribute("cy").toFloat() - svgChild.attribute("ry").toFloat(), false) * m_yscale)));
00330 kivioShape.setAttribute("w", QString::number(svgChild.attribute("rx").toFloat() * m_xscale * 2));
00331 kivioShape.setAttribute("h", QString::number(svgChild.attribute("ry").toFloat() * m_yscale * 2));
00332 kivio.documentElement().appendChild(kivioShape);
00333 }
00334 }
00335 else if(svgChild.tagName() == "svg:line")
00336 {
00337 runs++;
00338 if(svgChild.hasAttribute("x1") && svgChild.hasAttribute("y1") && svgChild.hasAttribute("x2") && svgChild.hasAttribute("y2"))
00339 {
00340 QDomElement kivioShape = kivio.createElement("KivioShape");
00341 kivioShape.setAttribute("type", "LineArray");
00342 kivioShape.setAttribute("name", QString::fromLatin1("Element") + QString::number(runs));
00343
00344 QDomElement lineArrayElement = kivio.createElement("Line");
00345 lineArrayElement.setAttribute("x1", QString::number(diaPointToKivio(svgChild.attribute("x1").toFloat(),true) * m_xscale));
00346 lineArrayElement.setAttribute("y1", QString::number(diaPointToKivio(svgChild.attribute("y1").toFloat(), false) * m_yscale));
00347 lineArrayElement.setAttribute("x2", QString::number(diaPointToKivio(svgChild.attribute("x2").toFloat(),true) * m_xscale));
00348 lineArrayElement.setAttribute("y2", QString::number(diaPointToKivio(svgChild.attribute("y2").toFloat(), false) * m_yscale));
00349
00350 kivioShape.appendChild(lineArrayElement);
00351 kivio.documentElement().appendChild(kivioShape);
00352 }
00353 }
00354 else if(svgChild.tagName() == "svg:polyline")
00355 {
00356 runs++;
00357 if(svgChild.hasAttribute("points"))
00358 {
00359 QDomElement kivioShape = kivio.createElement("KivioShape");
00360 kivioShape.setAttribute("type", "Polyline");
00361 kivioShape.setAttribute("name", QString::fromLatin1("Element") + QString::number(runs));
00362
00363 QStringList points = QStringList::split(" ", svgChild.attribute("points"));
00364 for(QStringList::Iterator it = points.begin(); it != points.end(); ++it)
00365 {
00366 QString x, y;
00367
00368 QStringList parsed = QStringList::split(",", (*it));
00369 QStringList::Iterator itp = parsed.begin();
00370 x = (*itp);
00371 ++itp;
00372 y = (*itp);
00373
00374 QDomElement kivioPointElement = kivio.createElement("KivioPoint");
00375 kivioPointElement.setAttribute("x", QString::number(diaPointToKivio(x.toFloat(),true) * m_xscale));
00376 kivioPointElement.setAttribute("y", QString::number(diaPointToKivio(y.toFloat(), false) * m_yscale));
00377
00378 kivioShape.appendChild(kivioPointElement);
00379 }
00380 kivio.documentElement().appendChild(kivioShape);
00381 }
00382 }
00383 else if(svgChild.tagName() == "svg:polygon")
00384 {
00385 runs++;
00386 if(svgChild.hasAttribute("points"))
00387 {
00388 QDomElement kivioShape = kivio.createElement("KivioShape");
00389 kivioShape.setAttribute("type", "Polygon");
00390 kivioShape.setAttribute("name", QString::fromLatin1("Element") + QString::number(runs));
00391
00392 QStringList points = QStringList::split(" ", svgChild.attribute("points"));
00393 for(QStringList::Iterator it = points.begin(); it != points.end(); ++it)
00394 {
00395 QString x, y;
00396
00397 QStringList parsed = QStringList::split(",", (*it));
00398 QStringList::Iterator itp = parsed.begin();
00399 x = (*itp);
00400 ++itp;
00401 y = (*itp);
00402
00403 QDomElement kivioPointElement = kivio.createElement("KivioPoint");
00404 kivioPointElement.setAttribute("x", QString::number(diaPointToKivio(x.toFloat(),true) * m_xscale));
00405 kivioPointElement.setAttribute("y", QString::number(diaPointToKivio(y.toFloat(), false) * m_yscale));
00406
00407 kivioShape.appendChild(kivioPointElement);
00408 }
00409 kivio.documentElement().appendChild(kivioShape);
00410 }
00411 }
00412 else if(svgChild.tagName() == "svg:path")
00413 {
00414 runs++;
00415 bool isClosed;
00416 QDomElement kivioShape = kivio.createElement("KivioShape");
00417 if(svgChild.hasAttribute("d"))
00418 {
00419
00420 if(svgChild.attribute("d").contains('z') || svgChild.attribute("d").contains('Z'))
00421 {
00422 isClosed = true;
00423 kivioShape.setAttribute("type", "ClosedPath");
00424 }
00425 else
00426 {
00427 isClosed = false;
00428 kivioShape.setAttribute("type", "OpenPath");
00429 }
00430
00431 kivioShape.setAttribute("name", QString::fromLatin1("Element") + QString::number(runs));
00432
00433 DiaPathParser *dpp = new DiaPathParser(&kivio,
00434 &kivioShape, m_xscale, m_yscale,
00435 m_lowestx, m_lowesty);
00436 dpp->parseSVG(svgChild.attribute("d"), true);
00437 delete dpp;
00438
00439
00440 }
00441
00442 if( svgChild.hasAttribute("style"))
00443 {
00444
00445
00446
00447
00448
00449
00450 QStringList styles = QStringList::split(";", svgChild.attribute("style"));
00451 for( uint idx = 0; idx < styles.count(); idx++)
00452 {
00453
00454 if( isClosed && styles[idx].contains("fill:"))
00455 {
00456 QDomElement fillStyle = kivio.createElement("KivioFillStyle");
00457 if( styles[idx].contains("forground"))
00458 fillStyle.setAttribute("color", "#0000");
00459 else if (styles[idx].contains("background"))
00460 fillStyle.setAttribute("color", "#ffff");
00461
00462 fillStyle.setAttribute("colorStyle", "1");
00463 kivioShape.appendChild(fillStyle);
00464 }
00465 }
00466 }
00467 kivio.documentElement().appendChild(kivioShape);
00468 }
00469 }
00470 svgNode = svgNode.nextSibling();
00471 }
00472
00473
00474
00475 dimensionsElement.setAttribute("w", QString::number((fabs(m_highestx - m_lowestx)) * m_xscale));
00476 dimensionsElement.setAttribute("h", QString::number((fabs(m_highesty - m_lowesty)) * m_yscale));
00477
00478 m_xlist.clear();
00479 m_ylist.clear();
00480
00481 return loadXML(file, kivio);
00482 }
00483
00484 bool KivioDiaStencilSpawner::loadXML(const QString &file, QDomDocument &d)
00485 {
00486 bool ret = m_smlStencilSpawner->loadXML(file, d);
00487
00488 m_icon = *m_smlStencilSpawner->icon();
00489 m_pSet = m_smlStencilSpawner->set();
00490 m_pInfo = m_smlStencilSpawner->info();
00491 m_defWidth = m_smlStencilSpawner->defWidth();
00492 m_defHeight = m_smlStencilSpawner->defHeight();
00493
00494 return ret;
00495 }
00496
00497 KivioStencil *KivioDiaStencilSpawner::newStencil()
00498 {
00499 KivioStencil *newStencil = m_smlStencilSpawner->newStencil();
00500 newStencil->setSpawner(this);
00501
00502 return newStencil;
00503 }