vacomponent.cpp
---------------
begin : Thur Feb 21 2014
copyright : (C) 2014 by Guilherme Brondani Torri
email : guitorri AT gmail DOT com
***************************************************************************/
* *
* 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. *
* *
***************************************************************************/
#include "vacomponent.h"
#include <QString>
#include <QFile>
#include <QTextStream>
#include <QMessageBox>
#include <QJsonDocument>
#include <QJsonObject>
#include <QJsonArray>
#include "node.h"
* \file vacomponent.cpp
* \brief Implementation of the vacomponent class.
*/
vacomponent::vacomponent(QJsonObject json)
{
parseJson(json);
}
* \brief vacomponent::vacomponent
* \param filename File (JSON) containing the symbol paintins and properties.
*/
vacomponent::vacomponent(QString filename)
{
QJsonObject json;
try {
json = getJsonObject(filename);
} catch (const std::runtime_error& ex) {
return;
}
parseJson(json);
}
void vacomponent::parseJson(QJsonObject json)
{
Description = getString(json, "description");
Simulator = spicecompat::simAll;
QJsonArray propArray = json["property"].toArray();
for (int propIndex = 0; propIndex < propArray.size(); ++propIndex) {
QJsonObject property = propArray[propIndex].toObject();
QString name = getString(property, "name");
QString value = getString(property, "value");
QString display = getString(property, "display");
QString desc = getString(property, "desc");
bool show;
if (!display.compare("false"))
show = false;
else
show = true;
Props.append (new Property (name, value, show, desc));
}
createSymbol(json);
Model = getString(json, "Model");
Name = getString(json, "SymName");
SpiceModel = "N";
tx = x1+100;
ty = y1+20;
}
* \brief vacomponent::newOne is used to mouse drop new items into the schematic.
* \param filename File (JSON) containing the symbol paintins and properties.
* \return \a Component based on the \p filename
* Used by mouseactions to drop new items into the schematic.
*/
Component *vacomponent::newOne(QString filename)
{
vacomponent * p = new vacomponent(filename);
if (Props.count())
p->Props.front()->Value = Props.front()->Value;
p->recreate(0);
return p;
}
* \brief vacomponent::info is used to either get information or create objects.
* \param Name Model name, returned by reference
* \param BitmapFile Bitmap file for the dock, returned by reference
* \param getNewOne if set return new object based on JSON file
* \param filename File (JSON) containing the symbol paintins and properties.
* \return Null or a new \a Element if \p getNewOne is true
* Used to get \p Name and \p BitmapFile.
* It can also create new objects from symbol file.
*/
Element *vacomponent::info(QString &Name, QString &BitmapFile,
bool getNewOne, QString filename)
{
QJsonObject json;
try {
json = getJsonObject(filename);
} catch (const std::runtime_error& ex) {
return 0;
}
Name = getString(json, "Model");
BitmapFile = getString(json, "BitmapFile");
if(getNewOne) return new vacomponent(json);
return 0;
}
* \brief vacomponent::createSymbol Constructor call this to create the symbol.
* \param filename File (JSON) containing the symbol paintins and properties.
* It reads the JSON file and parses the symbol paintings. Data is appended to
* to the appropriate lists, Lines, Rects, Ellips, ...
*/
void vacomponent::createSymbol(QJsonObject json)
{
QMap<QString, Qt::BrushStyle> brushMap;
QMap<QString, Qt::PenStyle> penMap;
brushMap.insert("Qt::NoBrush", Qt::NoBrush);
brushMap.insert("Qt::SolidPattern", Qt::SolidPattern);
brushMap.insert("Qt::Dense1Pattern", Qt::Dense1Pattern);
brushMap.insert("Qt::Dense2Pattern", Qt::Dense2Pattern);
brushMap.insert("Qt::Dense3Pattern", Qt::Dense3Pattern);
brushMap.insert("Qt::Dense4Pattern", Qt::Dense4Pattern);
brushMap.insert("Qt::Dense5Pattern", Qt::Dense5Pattern);
brushMap.insert("Qt::Dense6Pattern", Qt::Dense6Pattern);
brushMap.insert("Qt::Dense7Pattern", Qt::Dense7Pattern);
brushMap.insert("Qt::HorPattern", Qt::HorPattern);
brushMap.insert("Qt::VerPattern", Qt::VerPattern);
brushMap.insert("Qt::CrossPattern", Qt::CrossPattern);
brushMap.insert("Qt::BDiagPattern", Qt::BDiagPattern);
brushMap.insert("Qt::FDiagPattern", Qt::FDiagPattern);
brushMap.insert("Qt::DiagCrossPattern", Qt::DiagCrossPattern);
penMap.insert("Qt::NoPen", Qt::NoPen);
penMap.insert("Qt::SolidLine", Qt::SolidLine);
penMap.insert("Qt::DashLine", Qt::DashLine);
penMap.insert("Qt::DotLine", Qt::DotLine);
penMap.insert("Qt::DashDotLine", Qt::DashDotLine);
penMap.insert("Qt::DashDotDotLine", Qt::DashDotDotLine);
penMap.insert("Qt::CustomDashLine", Qt::CustomDashLine);
QJsonArray paintArray = json["paintings"].toArray();
for (int paintIndex = 0; paintIndex < paintArray.size(); ++paintIndex) {
QJsonObject paint = paintArray[paintIndex].toObject();
qreal x, x1, x2, y, y1, y2, w, h, thick, angle, arclen;
qreal size, cos, sin;
QString color, style , colorfill, stylefill, s;
QString type = getString(paint, "type");
if (!type.compare("line")) {
x1 = getDouble(paint, "x1");
y1 = getDouble(paint, "y1");
x2 = getDouble(paint, "x2");
y2 = getDouble(paint, "y2");
color = getString(paint, "color");
thick = getDouble(paint, "thick");
style = getString(paint, "style");
Lines.append (new qucs::Line (x1, y1, x2, y2,
QPen (QColor (color), thick, penMap.value(style))));
}
if (!type.compare("rectangle")) {
x = getDouble(paint, "x");
y = getDouble(paint, "y");
w = getDouble(paint, "w");
h = getDouble(paint, "h");
color = getString(paint, "color");
thick = getDouble(paint, "thick");
style = getString(paint, "style");
colorfill = getString(paint, "colorfill");
stylefill = getString(paint, "stylefill");
Rects.append (new qucs::Rect (x, y, w, h,
QPen (QColor (color), thick, penMap.value(style)),
QBrush(QColor (colorfill), brushMap.value(stylefill))
));
}
if (!type.compare("ellipse")) {
x = getDouble(paint, "x");
y = getDouble(paint, "y");
w = getDouble(paint, "w");
h = getDouble(paint, "h");
color = getString(paint, "color");
thick = getDouble(paint, "thick");
style = getString(paint, "style");
colorfill = getString(paint, "colorfill");
stylefill = getString(paint, "stylefill");
Ellipses.append (new qucs::Ellips (x, y, w, h,
QPen (QColor (color), thick, penMap.value(style)),
QBrush(QColor (colorfill), brushMap.value(stylefill))
));
}
if (!type.compare("ellipsearc")) {
x = getDouble(paint, "x");
y = getDouble(paint, "y");
w = getDouble(paint, "w");
h = getDouble(paint, "h");
angle = getDouble(paint, "angle");
arclen = getDouble(paint, "arclen");
color = getString(paint, "color");
thick = getDouble(paint, "thick");
style = getString(paint, "style");
Arcs.append (new qucs::Arc (x, y, w, h, angle, arclen,
QPen (QColor (color), thick, penMap.value(style))));
}
if (!type.compare("portsymbol")) {
x = getDouble(paint, "x");
y = getDouble(paint, "y");
Ports.append (new Port (x, y));
}
if (!type.compare("graphictext")) {
x = getDouble(paint, "x");
y = getDouble(paint, "y");
s = getString(paint, "s");
color = getString(paint, "color");
size = getDouble(paint, "size");
cos = getDouble(paint, "cos");
sin = getDouble(paint, "sin");
Texts.append (new Text (x, y, s,
QColor (color), size, cos, sin));
}
if (!type.compare("arrow")) {
x1 = getDouble(paint, "x1");
y1 = getDouble(paint, "y1");
x2 = getDouble(paint, "x2");
y2 = getDouble(paint, "y2");
color = getString(paint, "color");
thick = getDouble(paint, "thick");
style = getString(paint, "style");
Lines.append (new qucs::Line (x1, y1, x2, y2,
QPen (QColor (color), thick, penMap.value(style))));
}
}
x1 = getDouble(json, "x1");
y1 = getDouble(json, "y1");
x2 = getDouble(json, "x2");
y2 = getDouble(json, "y2");
}
QString vacomponent::spice_netlist(spicecompat::SpiceDialect dialect )
{
if (dialect == spicecompat::SPICEXyce) return QString();
QString s = SpiceModel + Name + " ";
for(const auto pp: Ports) {
s += pp->Connection->Name + " ";
}
QString tmp_model = QStringLiteral("mod_%1_%2").arg(Model).arg(Name);
s += tmp_model + "\n";
QString par_str;
for(int i = 0; i < Props.count(); i++) {
par_str += QStringLiteral("%1=%2 ")
.arg(Props.at(i)->Name)
.arg(Props.at(i)->Value);
}
s += QStringLiteral(".MODEL %1 %2 %3\n").arg(tmp_model)
.arg(Model)
.arg(par_str);
return s;
}
* \brief getJsonObject Reads the JSON file
* \param filename File (JSON) containing the symbol paintings and properties.
* \return the parsed JSON file as a QJsonObject
*/
QJsonObject getJsonObject(QString filename)
{
QFile file(filename);
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
QMessageBox::critical(0, QObject::tr("Error"),
QObject::tr("Symbol file not found: %1").arg(filename));
throw std::runtime_error("File not found");
}
QTextStream in(&file);
QString data = (QString) in.readAll();
data = data.simplified();
data.remove(" ");
data.replace(",]","]");
data.replace(",}","}");
file.close();
QJsonParseError error;
QJsonDocument jdoc = QJsonDocument::fromJson(data.toUtf8(), &error);
if(error.error != QJsonParseError::NoError) {
QMessageBox::critical(0, QObject::tr("Error"),
QObject::tr("Symbol file not found: %1").arg(filename));
throw std::runtime_error("Json parse error");
}
QJsonObject object = jdoc.object();
return object;
}
* \brief getDouble Helper to get a property out of a JSON script
* \param data JSON data as a QJsonObject
* \param prop JSON property key
* \return a double corresponding to the JSON value
*/
double getDouble(QJsonObject data, QString prop){
return data[prop].toDouble();
}
* \brief getString Helper to get a property out of a JSON script
* \param data JSON data as a QScritValue
* \param prop JSON property key
* \return a QString corresponding to the JSON value
*/
QString getString(QJsonObject data, QString prop){
return data[prop].toString();
}