22 #include <QMessageBox>
24 #include <QStringList>
30 #include <QTextStream>
31 #include <Q3ValueList>
61 QString s(
"<Qucs Schematic " PACKAGE_VERSION
">\n");
64 s +=
"<Components>\n";
67 s += pc->
save()+
"\n"; z++; }
68 s +=
"</Components>\n";
71 for(pw =
Wires->first(); pw != 0; pw =
Wires->next())
75 s += pw->
save().section(
'"', 0, 0)+
"\"\" 0 0 0>\n";
81 if(pn->Label)
if(pn->Label->isSelected) {
82 s += pn->Label->save()+
"\n"; z++; }
88 s += pd->
save()+
"\n"; z++; }
94 if(pp->
Name.at(0) !=
'.') {
95 s +=
"<"+pp->
save()+
">\n"; z++; }
96 s +=
"</Paintings>\n";
108 while(!stream->atEnd()) {
109 Line = stream->readLine();
110 if(Line.at(0) ==
'<')
if(Line.at(1) ==
'/')
return true;
113 QMessageBox::critical(0, QObject::tr(
"Error"),
114 QObject::tr(
"Format Error:\n'Painting' field is not closed!"));
124 Line = stream->readLine();
125 if(Line.left(16) !=
"<Qucs Schematic ")
128 QString s = PACKAGE_VERSION;
129 Line = Line.mid(16, Line.length()-17);
131 QMessageBox::critical(0, QObject::tr(
"Error"),
132 QObject::tr(
"Wrong document version: ")+Line);
138 while(!stream->atEnd()) {
139 Line = stream->readLine();
140 if(Line ==
"<Components>") {
143 if(Line ==
"<Wires>") {
146 if(Line ==
"<Diagrams>") {
149 if(Line ==
"<Paintings>") {
150 if(!
loadPaintings(stream, (Q3PtrList<Painting>*)pe))
return false; }
152 QMessageBox::critical(0, QObject::tr(
"Error"),
153 QObject::tr(
"Clipboard Format Error:\nUnknown field!"));
162 while(!stream->atEnd()) {
163 Line = stream->readLine();
164 if(Line ==
"<Components>") {
165 if(!
loadComponents(stream, (Q3PtrList<Component>*)pe))
return false; }
167 if(Line ==
"<Wires>") {
168 if(!
loadWires(stream, pe))
return false; }
170 if(Line ==
"<Diagrams>") {
171 if(!
loadDiagrams(stream, (Q3PtrList<Diagram>*)pe))
return false; }
173 if(Line ==
"<Paintings>") {
174 if(!
loadPaintings(stream, (Q3PtrList<Painting>*)pe))
return false; }
176 QMessageBox::critical(0, QObject::tr(
"Error"),
177 QObject::tr(
"Clipboard Format Error:\nUnknown field!"));
189 QString cppfile = info.dirPath () + QDir::separator() +
DataSet;
190 QFile file (cppfile);
192 if (!file.open (QIODevice::WriteOnly)) {
193 QMessageBox::critical (0, QObject::tr(
"Error"),
194 QObject::tr(
"Cannot save C++ file \"%1\"!").arg(cppfile));
198 QTextStream stream (&file);
209 stream <<
" // symbol drawing code\n";
211 if (pp->
Name ==
".ID ")
continue;
212 if (pp->
Name ==
".PortSym ") {
213 if (((
PortSymbol*)pp)->numberStr.toInt() > maxNum)
214 maxNum = ((
PortSymbol*)pp)->numberStr.toInt();
217 if (x1 < xmin) xmin = x1;
218 if (x1 > xmax) xmax = x1;
219 if (y1 < ymin) ymin = y1;
220 if (y1 > ymax) ymax = y1;
224 if (x1 < xmin) xmin = x1;
225 if (x2 > xmax) xmax = x2;
226 if (y1 < ymin) ymin = y1;
227 if (y2 > ymax) ymax = y2;
228 stream <<
" " << pp->
saveCpp () <<
"\n";
231 stream <<
"\n // terminal definitions\n";
232 for (
int i = 1; i <= maxNum; i++) {
234 if (pp->
Name ==
".PortSym ")
235 if (((
PortSymbol*)pp)->numberStr.toInt() == i)
236 stream <<
" " << pp->
saveCpp () <<
"\n";
240 stream <<
"\n // symbol boundings\n"
241 <<
" x1 = " << xmin <<
"; " <<
" y1 = " << ymin <<
";\n"
242 <<
" x2 = " << xmax <<
"; " <<
" y2 = " << ymax <<
";\n";
244 stream <<
"\n // property text position\n";
246 if (pp->
Name ==
".ID ")
247 stream <<
" " << pp->
saveCpp () <<
"\n";
257 QString jsonfile = info.dirPath () + QDir::separator()
258 + info.baseName() +
"_sym.json";
260 qDebug() <<
"saveSymbolJson for " << jsonfile;
262 QFile file (jsonfile);
264 if (!file.open (QIODevice::WriteOnly)) {
265 QMessageBox::critical (0, QObject::tr(
"Error"),
266 QObject::tr(
"Cannot save JSON symbol file \"%1\"!").arg(jsonfile));
270 QTextStream stream (&file);
283 stream <<
"\"paintings\" : [\n";
287 if (pp->
Name ==
".ID ")
continue;
288 if (pp->
Name ==
".PortSym ") {
289 if (((
PortSymbol*)pp)->numberStr.toInt() > maxNum)
290 maxNum = ((
PortSymbol*)pp)->numberStr.toInt();
293 if (x1 < xmin) xmin = x1;
294 if (x1 > xmax) xmax = x1;
295 if (y1 < ymin) ymin = y1;
296 if (y1 > ymax) ymax = y1;
300 if (x1 < xmin) xmin = x1;
301 if (x2 > xmax) xmax = x2;
302 if (y1 < ymin) ymin = y1;
303 if (y2 > ymax) ymax = y2;
304 stream <<
" " << pp->
saveJSON() <<
"\n";
309 for (
int i = 1; i <= maxNum; i++) {
311 if (pp->
Name ==
".PortSym ")
312 if (((
PortSymbol*)pp)->numberStr.toInt() == i)
313 stream <<
" " << pp->
saveJSON () <<
"\n";
321 <<
" \"x1\" : " << xmin <<
",\n" <<
" \"y1\" : " << ymin <<
",\n"
322 <<
" \"x2\" : " << xmax <<
",\n" <<
" \"y2\" : " << ymax <<
",\n";
326 if (pp->
Name ==
".ID ")
327 stream <<
" " << pp->
saveJSON () <<
"\n";
342 if(!file.open(QIODevice::WriteOnly)) {
343 QMessageBox::critical(0, QObject::tr(
"Error"),
344 QObject::tr(
"Cannot save document!"));
348 QTextStream stream(&file);
350 stream <<
"<Qucs Schematic " << PACKAGE_VERSION <<
">\n";
352 stream <<
"<Properties>\n";
361 stream <<
Scale <<
","<<contentsX()<<
","<<contentsY() <<
">\n";
365 stream <<
" <DataSet=" <<
DataSet <<
">\n";
366 stream <<
" <DataDisplay=" <<
DataDisplay <<
">\n";
367 stream <<
" <OpenDisplay=" <<
SimOpenDpl <<
">\n";
368 stream <<
" <Script=" <<
Script <<
">\n";
370 stream <<
" <showFrame=" <<
showFrame <<
">\n";
374 stream <<
" <FrameText0=" << t <<
">\n";
376 stream <<
" <FrameText1=" << t <<
">\n";
378 stream <<
" <FrameText2=" << t <<
">\n";
380 stream <<
" <FrameText3=" << t <<
">\n";
381 stream <<
"</Properties>\n";
384 stream <<
"<Symbol>\n";
386 stream <<
" <" << pp->
save() <<
">\n";
387 stream <<
"</Symbol>\n";
389 stream <<
"<Components>\n";
391 stream <<
" " << pc->save() <<
"\n";
392 stream <<
"</Components>\n";
394 stream <<
"<Wires>\n";
396 stream <<
" " << pw->save() <<
"\n";
400 if(pn->Label) stream <<
" " << pn->Label->save() <<
"\n";
401 stream <<
"</Wires>\n";
403 stream <<
"<Diagrams>\n";
405 stream <<
" " << pd->save() <<
"\n";
406 stream <<
"</Diagrams>\n";
408 stream <<
"<Paintings>\n";
410 stream <<
" <" << pp->
save() <<
">\n";
411 stream <<
"</Paintings>\n";
424 qDebug() <<
" -> Run adms for symbol";
436 admsXml = QDir::toNativeSeparators(admsXml+
"/"+
"admsXml.exe");
438 admsXml = QDir::toNativeSeparators(admsXml+
"/"+
"admsXml");
443 qDebug() <<
"App path : " << qApp->applicationDirPath();
444 qDebug() <<
"workdir" << workDir;
449 QStringList Arguments;
450 Arguments << QDir::toNativeSeparators(vaFile)
451 <<
"-I" << QDir::toNativeSeparators(include.absolutePath())
452 <<
"-e" << QDir::toNativeSeparators(include.absFilePath(
"qucsMODULEguiJSONsymbol.xml"))
459 if ( !file.exists() ){
460 QMessageBox::critical(
this, tr(
"Error"),
461 tr(
"Program admsXml not found: %1\n\n"
462 "Set the admsXml location on the application settings.").arg(admsXml));
466 qDebug() <<
"Command: " << admsXml << Arguments.join(
" ");
469 QDir::setCurrent(workDir);
472 builder.setProcessChannelMode(QProcess::MergedChannels);
474 builder.start(admsXml, Arguments);
479 if (!builder.waitForFinished()) {
480 QString cmdString = QString(
"%1 %2\n\n").arg(admsXml, Arguments.join(
" "));
481 cmdString = cmdString + builder.errorString();
482 QMessageBox::critical(
this, tr(
"Error"), cmdString);
485 QString cmdString = QString(
"%1 %2\n\n").arg(admsXml, Arguments.join(
" "));
486 cmdString = cmdString + builder.readAll();
487 QMessageBox::information(
this, tr(
"Status"), cmdString);
493 f1.open(QIODevice::ReadOnly | QIODevice::Text);
494 f2.open(QIODevice::ReadOnly | QIODevice::Text);
496 QString dat1 = QString(f1.readAll());
497 QString dat2 = QString(f2.readAll());
498 QString finalJSON = dat1.append(dat2);
501 finalJSON = finalJSON.replace(
"}{",
"");
504 f3.open(QIODevice::WriteOnly | QIODevice::Text);
505 QTextStream out(&f3);
524 QString
Line, cstr, nstr;
525 while(!stream->atEnd()) {
526 Line = stream->readLine();
527 if(Line.at(0) ==
'<')
if(Line.at(1) ==
'/')
return true;
528 Line = Line.stripWhiteSpace();
529 if(Line.isEmpty())
continue;
531 if(Line.at(0) !=
'<') {
532 QMessageBox::critical(0, QObject::tr(
"Error"),
533 QObject::tr(
"Format Error:\nWrong property field limiter!"));
536 if(Line.at(Line.length()-1) !=
'>') {
537 QMessageBox::critical(0, QObject::tr(
"Error"),
538 QObject::tr(
"Format Error:\nWrong property field limiter!"));
541 Line = Line.mid(1, Line.length()-2);
543 cstr = Line.section(
'=',0,0);
544 nstr = Line.section(
'=',1,1);
546 ViewX1 = nstr.section(
',',0,0).toInt(&ok);
if(ok) {
547 ViewY1 = nstr.section(
',',1,1).toInt(&ok);
if(ok) {
548 ViewX2 = nstr.section(
',',2,2).toInt(&ok);
if(ok) {
549 ViewY2 = nstr.section(
',',3,3).toInt(&ok);
if(ok) {
550 Scale = nstr.section(
',',4,4).toDouble(&ok);
if(ok) {
551 tmpViewX1 = nstr.section(
',',5,5).toInt(&ok);
if(ok)
552 tmpViewY1 = nstr.section(
',',6,6).toInt(&ok); }}}}} }
553 else if(cstr ==
"Grid") {
554 GridX = nstr.section(
',',0,0).toInt(&ok);
if(ok) {
555 GridY = nstr.section(
',',1,1).toInt(&ok);
if(ok) {
556 if(nstr.section(
',',2,2).toInt(&ok) == 0)
GridOn =
false;
558 else if(cstr ==
"DataSet")
DataSet = nstr;
560 else if(cstr ==
"OpenDisplay")
563 else if(cstr ==
"Script")
Script = nstr;
564 else if(cstr ==
"RunScript")
567 else if(cstr ==
"showFrame")
574 QMessageBox::critical(0, QObject::tr(
"Error"),
575 QObject::tr(
"Format Error:\nUnknown property: ")+cstr);
579 QMessageBox::critical(0, QObject::tr(
"Error"),
580 QObject::tr(
"Format Error:\nNumber expected in property field!"));
585 QMessageBox::critical(0, QObject::tr(
"Error"),
586 QObject::tr(
"Format Error:\n'Property' field is not closed!"));
603 if(pn->
cx == x)
if(pn->
cy == y) {
604 if (!pn->
DType.isEmpty()) {
605 pp->Type = pn->
DType;
607 if (!pp->Type.isEmpty()) {
608 pn->
DType = pp->Type;
618 if (!pp->Type.isEmpty()) {
619 pn->
DType = pp->Type;
633 while(!stream->atEnd()) {
634 Line = stream->readLine();
635 if(Line.at(0) ==
'<')
if(Line.at(1) ==
'/')
return true;
636 Line = Line.stripWhiteSpace();
637 if(Line.isEmpty())
continue;
645 for(z=c->
Name.length()-1; z>=0; z--)
646 if(!c->
Name.at(z).isDigit())
break;
653 QMessageBox::critical(0, QObject::tr(
"Error"),
654 QObject::tr(
"Format Error:\n'Component' field is not closed!"));
665 if(pn->
cx == pw->
x1)
if(pn->
cy == pw->
y1)
break;
672 if(pw->
x1 == pw->
x2)
if(pw->
y1 == pw->
y2) {
686 if(pn->
cx == pw->
x2)
if(pn->
cy == pw->
y2)
break;
703 while(!stream->atEnd()) {
704 Line = stream->readLine();
705 if(Line.at(0) ==
'<')
if(Line.at(1) ==
'/')
return true;
706 Line = Line.stripWhiteSpace();
707 if(Line.isEmpty())
continue;
712 QMessageBox::critical(0, QObject::tr(
"Error"),
713 QObject::tr(
"Format Error:\nWrong 'wire' line format!"));
720 List->append(w->
Label);
730 QMessageBox::critical(0, QObject::tr(
"Error"),
731 QObject::tr(
"Format Error:\n'Wire' field is not closed!"));
740 while(!stream->atEnd()) {
741 Line = stream->readLine();
742 if(Line.at(0) ==
'<')
if(Line.at(1) ==
'/')
return true;
743 Line = Line.stripWhiteSpace();
744 if(Line.isEmpty())
continue;
746 cstr = Line.section(
' ',0,0);
751 else if(cstr ==
"<ySmith") d =
new SmithDiagram(0,0,
false);
752 else if(cstr ==
"<PS") d =
new PSDiagram();
753 else if(cstr ==
"<SP") d =
new PSDiagram(0,0,
false);
759 QMessageBox::critical(0, QObject::tr(
"Error"),
760 QObject::tr(
"Format Error:\nUnknown diagram!"));
764 if(!d->
load(Line, stream)) {
765 QMessageBox::critical(0, QObject::tr(
"Error"),
766 QObject::tr(
"Format Error:\nWrong 'diagram' line format!"));
773 QMessageBox::critical(0, QObject::tr(
"Error"),
774 QObject::tr(
"Format Error:\n'Diagram' field is not closed!"));
783 while(!stream->atEnd()) {
784 Line = stream->readLine();
785 if(Line.at(0) ==
'<')
if(Line.at(1) ==
'/')
return true;
787 Line = Line.stripWhiteSpace();
788 if(Line.isEmpty())
continue;
789 if( (Line.at(0) !=
'<') || (Line.at(Line.length()-1) !=
'>')) {
790 QMessageBox::critical(0, QObject::tr(
"Error"),
791 QObject::tr(
"Format Error:\nWrong 'painting' line delimiter!"));
794 Line = Line.mid(1, Line.length()-2);
796 cstr = Line.section(
' ',0,0);
799 else if(cstr ==
".PortSym") p =
new PortSymbol();
800 else if(cstr ==
".ID") p =
new ID_Text();
802 else if(cstr ==
"Rectangle") p =
new Rectangle();
803 else if(cstr ==
"Arrow") p =
new Arrow();
804 else if(cstr ==
"Ellipse") p =
new Ellipse();
806 QMessageBox::critical(0, QObject::tr(
"Error"),
807 QObject::tr(
"Format Error:\nUnknown painting!"));
812 QMessageBox::critical(0, QObject::tr(
"Error"),
813 QObject::tr(
"Format Error:\nWrong 'painting' line format!"));
820 QMessageBox::critical(0, QObject::tr(
"Error"),
821 QObject::tr(
"Format Error:\n'Painting' field is not closed!"));
829 if(!file.open(QIODevice::ReadOnly)) {
830 QMessageBox::critical(0, QObject::tr(
"Error"),
831 QObject::tr(
"Cannot load document: ")+
DocName);
836 QTextStream stream(&file);
845 Line = stream.readLine();
846 }
while(Line.isEmpty());
848 if(Line.left(16) !=
"<Qucs Schematic ") {
850 QMessageBox::critical(0, QObject::tr(
"Error"),
851 QObject::tr(
"Wrong document type: ")+
DocName);
855 Line = Line.mid(16, Line.length()-17);
858 QMessageBox::StandardButton result;
859 result = QMessageBox::warning(0,
860 QObject::tr(
"Warning"),
861 QObject::tr(
"Wrong document version \n" +
863 "Try to open it anyway?"),
864 QMessageBox::Yes|QMessageBox::No);
866 if (result==QMessageBox::No) {
876 while(!stream.atEnd()) {
877 Line = stream.readLine();
878 Line = Line.stripWhiteSpace();
879 if(Line.isEmpty())
continue;
881 if(Line ==
"<Symbol>") {
889 if(Line ==
"<Properties>") {
892 if(Line ==
"<Components>") {
895 if(Line ==
"<Wires>") {
896 if(!
loadWires(&stream)) { file.close();
return false; } }
899 if(Line ==
"<Diagrams>") {
902 if(Line ==
"<Paintings>") {
906 QMessageBox::critical(0, QObject::tr(
"Error"),
907 QObject::tr(
"File Format Error:\nUnknown field!"));
932 s += pc->
save()+
"\n";
936 s += pw->
save()+
"\n";
939 if(pn->Label) s += pn->Label->save()+
"\n";
943 s += pd->
save()+
"\n";
947 s +=
"<"+pp->
save()+
">\n";
967 s +=
"<"+pp->
save()+
">\n";
985 QTextStream stream(s, QIODevice::ReadOnly);
986 Line = stream.readLine();
1004 QTextStream stream(s, QIODevice::ReadOnly);
1005 Line = stream.readLine();
1008 Line = stream.readLine();
1009 Line = stream.readLine();
1010 Line = stream.readLine();
1028 Collect.append(
"NodeSet:NS" + QString::number(countInit++) +
" " +
1040 if(pn->
Name.isEmpty() == User) {
1047 pn->
Name =
"net_net";
1048 pn->
Name += QString::number(z++);
1050 else if(pn->
State) {
1071 }
else if (!pn->
DType.isEmpty()) {
1072 it.data().Type = pn->
DType;
1080 int& countInit,
Node *pn)
1083 Q3PtrList<Node> Cons;
1089 for(p2 = Cons.first(); p2 != 0; p2 = Cons.next())
1093 if(p2 != pw->
Port1) {
1097 Cons.append(pw->
Port1);
1105 Cons.append(pw->
Port2);
1123 QStringList& Collect, QTextEdit *ErrText,
int NumPorts)
1129 Q3PtrListIterator<Component> it(
DocComps);
1131 while((pc = it.current()) != 0) {
1138 ErrText->insert(QObject::tr(
"ERROR: Component \"%1\" has no analog model.").arg(pc->
Name));
1143 ErrText->insert(QObject::tr(
"ERROR: Component \"%1\" has no digital model.").arg(pc->
Name));
1149 if(pc->
Model ==
"GND") {
1150 pc->
Ports.getFirst()->Connection->Name =
"gnd";
1155 if(pc->
Model ==
"Sub")
1161 SubMap::Iterator it =
FileList.find(f);
1164 if (!it.data().PortTypes.isEmpty())
1168 for(
Port *pp = pc->
Ports.first(); pp; pp = pc->
Ports.next(), i++)
1170 pp->Type = it.data().PortTypes[i];
1171 pp->Connection->DType = pp->Type;
1183 s = pc->
Props.first()->Value;
1188 ErrText->insert(QObject::tr(
"ERROR: Cannot load subcircuit \"%1\".").arg(s));
1200 for(
Port *pp = pc->
Ports.first(); pp; pp = pc->
Ports.next(), i++)
1204 pp->Connection->DType = pp->Type;
1218 if(pc->
Model ==
"Lib") {
1221 QObject::tr(
"WARNING: Skipping library component \"%1\".").
1226 SubMap::Iterator it =
FileList.find(s);
1232 r = ((
LibComp*)pc)->createSubNetlist(stream, Collect, 1);
1235 r = ((
LibComp*)pc)->createSubNetlist(stream, Collect, 4);
1237 r = ((
LibComp*)pc)->createSubNetlist(stream, Collect, 2);
1241 QObject::tr(
"ERROR: Cannot load library component \"%1\".").
1249 if(pc->
Model ==
"SPICE") {
1250 s = pc->
Props.first()->Value;
1254 ErrText->insert(QObject::tr(
"ERROR: No file name in SPICE component \"%1\".").
1259 SubMap::Iterator it =
FileList.find(f);
1267 if(!r)
return false;
1272 if(pc->
Model ==
"VHDL" || pc->
Model ==
"Verilog") {
1277 s = pc->
Props.getFirst()->Value;
1279 ErrText->insert(QObject::tr(
"ERROR: No file name in %1 component \"%2\".").
1285 SubMap::Iterator it =
FileList.find(f);
1288 s = ((pc->
Model ==
"VHDL") ?
"VHD" :
"VER");
1291 if(pc->
Model ==
"VHDL") {
1295 if(!r)
return false;
1297 if(pc->
Model ==
"Verilog") {
1301 if(!r)
return false;
1314 QStringList& Collect, QTextEdit *ErrText,
int NumPorts)
1321 pn->Name = pn->Label->Name;
1323 pn->Name =
"net" + pn->Label->Name;
1330 if(pw->Label != 0) {
1332 pw->Port1->Name = pw->Label->Name;
1334 pw->Port1->Name =
"net" + pw->Label->Name;
1358 QStringList Collect;
1364 if(!
giveNodeNames(stream, countInit, Collect, ErrText, NumPorts)) {
1379 (*stream) <<
"\n" << c <<
" TOP LEVEL MARK " << c <<
"\n";
1390 #define VHDL_SIGNAL_TYPE "std_logic"
1391 #define VHDL_LIBRARIES "\nlibrary ieee;\nuse ieee.std_logic_1164.all;\n"
1399 QStringList SubcircuitPortNames;
1400 QStringList SubcircuitPortTypes;
1401 QStringList InPorts;
1402 QStringList OutPorts;
1403 QStringList InOutPorts;
1404 QStringList::iterator it_name;
1405 QStringList::iterator it_type;
1409 QTextStream * tstream = stream;
1414 if(!ofile.open(IO_WriteOnly)) {
1415 ErrText->insert(tr(
"ERROR: Cannot create library file \"%s\".").arg(f));
1418 tstream =
new QTextStream(&ofile);
1425 if(pc->
Model.at(0) ==
'.') {
1427 QObject::tr(
"WARNING: Ignore simulation component in subcircuit \"%1\".").arg(
DocName)+
"\n");
1430 else if(pc->
Model ==
"Port") {
1431 i = pc->
Props.first()->Value.toInt();
1432 for(z=SubcircuitPortNames.size(); z<i; z++) {
1433 SubcircuitPortNames.append(
" ");
1434 SubcircuitPortTypes.append(
" ");
1436 it_name = SubcircuitPortNames.begin();
1437 it_type = SubcircuitPortTypes.begin();
1438 for(
int n=1;n<i;n++)
1443 (*it_name) = pc->
Ports.getFirst()->Connection->Name;
1444 DigMap::Iterator it =
Signals.find(*it_name);
1446 (*it_type) = it.data().Type;
1448 pc->
Ports.getFirst()->Connection->DType = *it_type;
1453 switch(pc->
Props.at(1)->Value.at(0).latin1()) {
1455 InOutPorts.append(*it_name);
1458 OutPorts.append(*it_name);
1461 InPorts.append(*it_name);
1467 switch(pc->
Props.at(1)->Value.at(0).latin1()) {
1469 (*it_name) +=
" : inout";
1473 (*it_name) =
"net_out" + (*it_name);
1476 (*it_name) +=
" : " + pc->
Props.at(1)->Value;
1478 (*it_name) +=
" " + ((*it_type).isEmpty() ?
1486 for(it_name = SubcircuitPortNames.begin(),
1487 it_type = SubcircuitPortTypes.begin();
1488 it_name != SubcircuitPortNames.end(); ) {
1489 if(*it_name ==
" ") {
1490 it_name = SubcircuitPortNames.remove(it_name);
1491 it_type = SubcircuitPortTypes.remove(it_type);
1505 (*tstream) <<
"\n.Def:" << Type <<
" " << SubcircuitPortNames.join(
" ");
1507 if(pi->
Name ==
".ID ") {
1512 (*tstream) <<
" " << s.replace(
"=",
"=\"") <<
'"';
1522 (*tstream) <<
".Def:End\n";
1528 (*tstream) <<
"\nmodule Sub_" << Type <<
" ("
1529 << SubcircuitPortNames.join(
", ") <<
");\n";
1532 if(!InPorts.isEmpty())
1533 (*tstream) <<
" input " << InPorts.join(
", ") <<
";\n";
1534 if(!OutPorts.isEmpty())
1535 (*tstream) <<
" output " << OutPorts.join(
", ") <<
";\n";
1536 if(!InOutPorts.isEmpty())
1537 (*tstream) <<
" inout " << InOutPorts.join(
", ") <<
";\n";
1541 Q3ValueList<DigSignal> values =
Signals.values();
1542 Q3ValueList<DigSignal>::iterator it;
1543 for (it = values.begin(); it != values.end(); ++it) {
1544 (*tstream) <<
" wire " << (*it).Name <<
";\n";
1551 if(pi->
Name ==
".ID ") {
1555 for(pp = pid->
Parameter.first(); pp != 0;) {
1556 s = pp->
Name.section(
'=', 0,0);
1558 (*tstream) <<
" parameter " << s <<
" = " << v <<
";\n";
1568 if(pc->
Model ==
"Eqn") {
1574 (*tstream) <<
" assign gnd = 0;\n";
1578 if(pc->
Model !=
"Eqn") {
1580 if(s.length()>0 && s.at(0) ==
'\xA7') {
1581 ErrText->insert(s.mid(1));
1583 else (*tstream) << s;
1587 (*tstream) <<
"endmodule\n";
1591 (*tstream) <<
"entity Sub_" << Type <<
" is\n"
1593 << SubcircuitPortNames.join(
";\n ") <<
");\n";
1596 if(pi->
Name ==
".ID ") {
1600 (*tstream) <<
" generic (";
1601 for(pp = pid->
Parameter.first(); pp != 0;) {
1603 QString t = pp->
Type.isEmpty() ?
"real" : pp->
Type;
1604 (*tstream) << s.replace(
"=",
" : "+t+
" := ");
1606 if(pp) (*tstream) <<
";\n ";
1608 (*tstream) <<
");\n";
1613 (*tstream) <<
"end entity;\n"
1614 <<
"use work.all;\n"
1615 <<
"architecture Arch_Sub_" << Type <<
" of Sub_" << Type
1619 Q3ValueList<DigSignal> values =
Signals.values();
1620 Q3ValueList<DigSignal>::iterator it;
1621 for (it = values.begin(); it != values.end(); ++it) {
1622 (*tstream) <<
" signal " << (*it).Name <<
" : "
1623 << ((*it).Type.isEmpty() ?
1630 if(pc->
Model ==
"Eqn") {
1632 QObject::tr(
"WARNING: Equations in \"%1\" are 'time' typed.").
1638 (*tstream) <<
"begin\n";
1641 (*tstream) <<
" gnd <= '0';\n";
1645 if(pc->
Model !=
"Eqn") {
1647 if(s.length()>0 && s.at(0) ==
'\xA7') {
1648 ErrText->insert(s.mid(1));
1650 else (*tstream) << s;
1654 (*tstream) <<
"end architecture;\n";
1667 QStringList& Collect, QTextEdit *ErrText,
int NumPorts)
1672 if(!
giveNodeNames(stream, countInit, Collect, ErrText, NumPorts))
1699 bool isTruthTable =
false;
1700 int allTypes = 0, NumPorts = 0;
1705 if(pc->Model.at(0) ==
'.') {
1706 if(pc->Model ==
".Digi") {
1709 QObject::tr(
"ERROR: Only one digital simulation allowed."));
1712 if(pc->Props.getFirst()->Value !=
"TimeList")
1713 isTruthTable =
true;
1714 if(pc->Props.getLast()->Value !=
"VHDL")
1722 QObject::tr(
"ERROR: Analog and digital simulations cannot be mixed."));
1726 else if(pc->Model ==
"DigiSource") NumPorts++;
1739 if(NumPorts < 1 && isTruthTable) {
1741 QObject::tr(
"ERROR: Digital simulation needs at least one digital source."));
1744 if(!isTruthTable) NumPorts = 0;
1753 if(allTypes & isAnalogComponent)
1759 stream <<
" Qucs " << PACKAGE_VERSION <<
" " <<
DocName <<
"\n";
1763 stream <<
"\n`timescale 1ps/100fs\n";
1767 if(!
giveNodeNames(&stream, countInit, Collect, ErrText, NumPorts))
1770 if(allTypes & isAnalogComponent)
1775 stream <<
"entity TestBench is\n"
1777 <<
"use work.all;\n";
1787 stream <<
"module TestBench ();\n";
1788 Q3ValueList<DigSignal> values =
Signals.values();
1789 Q3ValueList<DigSignal>::iterator it;
1790 for (it = values.begin(); it != values.end(); ++it) {
1791 stream <<
" wire " << (*it).Name <<
";\n";
1795 stream <<
"architecture Arch_TestBench of TestBench is\n";
1796 Q3ValueList<DigSignal> values =
Signals.values();
1797 Q3ValueList<DigSignal>::iterator it;
1798 for (it = values.begin(); it != values.end(); ++it) {
1799 stream <<
" signal " << (*it).Name <<
" : "
1800 << ((*it).Type.isEmpty() ?
1803 stream <<
"begin\n";
1808 stream <<
" assign gnd = 0;\n";
1810 stream <<
" gnd <= '0';\n";
1821 stream <<
"end architecture;\n";
1839 s = pc->getNetlist();
1842 if(pc->Model ==
".Digi" && pc->isActive) {
1845 Time = QString::number((1 << NumPorts));
1847 Time = QString::number((1 << NumPorts) - 1) +
" ns";
1849 Time = pc->Props.at(1)->Value;
1853 if(!
VHDL_Time(Time, pc->Name))
return Time;
1858 s = pc->get_Verilog_Code(NumPorts);
1860 s = pc->get_VHDL_Code(NumPorts);
1862 if (s.length()>0 && s.at(0) ==
'\xA7'){
static void createNodeSet(QStringList &, int &, Conductor *, Node *)
bool createSubNetlist(QTextStream *, int &, QStringList &, QTextEdit *, int)
Q3PtrList< Painting > DocPaints
void createSubNetlistPlain(QTextStream *, QTextEdit *, int)
bool load(const QString &, QTextStream *)
QString properFileName(const QString &Name)
QString get_Verilog_Code(int)
bool createSubNetlist(QTextStream *)
void simpleInsertWire(Wire *)
label for Node and Wire classes
bool loadComponents(QTextStream *, Q3PtrList< Component > *List=0)
QString Verilog_Param(const QString Value)
tQucsSettings QucsSettings
bool giveNodeNames(QTextStream *, int &, QStringList &, QTextEdit *, int)
Component * getComponentFromName(QString &Line, Schematic *p)
QString createSymbolUndoString(char)
bool checkVersion(QString &Line)
void convert2Unicode(QString &Text)
QString createClipboardFile()
virtual QString saveJSON()
QMap< QString, SubFile > SubMap
void collectDigitalSignals(void)
#define isDigitalComponent
Q3PtrList< Diagram > * Diagrams
Definitions and declarations for the main application.
bool loadWires(QTextStream *, Q3PtrList< Element > *List=0)
QString properAbsFileName(const QString &Name)
QString createNetlist(QTextStream &, int)
Q3PtrList< Component > * Components
Q3PtrList< Property > Props
bool createSubNetlist(QTextStream *)
void throughAllNodes(bool, QStringList &, int &)
void simpleInsertComponent(Component *)
void endNetlistDigital(QTextStream &)
Q3PtrList< Diagram > DocDiags
bool loadPaintings(QTextStream *, Q3PtrList< Painting > *)
bool createSubNetlist(QTextStream *)
bool Verilog_Time(QString &t, const QString &Name)
bool VHDL_Time(QString &t, const QString &Name)
Q3PtrList< Element > Connections
QString createUndoString(char)
Q3PtrList< Node > * Nodes
virtual void setSchematic(Schematic *p)
bool pasteFromClipboard(QTextStream *, Q3PtrList< Element > *)
#define isAnalogComponent
Superclass of all schematic drawing elements.
virtual QString getSubcircuitFile()
bool rebuildSymbol(QString *)
void convert2ASCII(QString &Text)
bool load(const QString &)
bool createLibNetlist(QTextStream *, QTextEdit *, int)
Schematic(QucsApp *, const QString &)
bool throughAllComps(QTextStream *, int &, QStringList &, QTextEdit *, int)
int prepareNetlist(QTextStream &, QStringList &, QTextEdit *)
Q3PtrList< Painting > SymbolPaints
Q3PtrList< SubParameter > Parameter
void propagateNode(QStringList &, int &, Node *)
Q3PtrList< Wire > DocWires
QString properName(const QString &Name)
virtual QString saveCpp()
bool loadProperties(QTextStream *)
void beginNetlistDigital(QTextStream &)
void setName(const QString &)
Q3PtrList< Node > DocNodes
Q3PtrList< Painting > * Paintings
bool loadIntoNothing(QTextStream *)
Q3PtrList< Wire > * Wires
virtual void Bounding(int &, int &, int &, int &)
bool loadDiagrams(QTextStream *, Q3PtrList< Diagram > *)
QString get_VHDL_Code(int)
virtual bool load(const QString &)
Q3PtrList< Component > DocComps