28 #include <qlineedit.h>
29 #include <qvalidator.h>
30 #include <qfiledialog.h>
31 #include <qpushbutton.h>
33 #include <qcheckbox.h>
35 #include <qmessagebox.h>
36 #include <qcombobox.h>
40 : QDialog(d, 0, TRUE, Qt::WDestructiveClose)
43 setCaption(tr(
"Edit SPICE Component Properties"));
47 all =
new QVBoxLayout(
this);
48 QWidget *myParent =
this;
50 Expr.setPattern(
"[^\"=]+");
51 Validator =
new QRegExpValidator(Expr,
this);
52 Expr.setPattern(
"[\\w_]+");
53 ValRestrict =
new QRegExpValidator(Expr,
this);
57 QGridLayout *topGrid =
new QGridLayout(0, 4,3,3,3);
58 all->addLayout(topGrid);
60 topGrid->addWidget(
new QLabel(tr(
"Name:"), myParent), 0,0);
61 CompNameEdit =
new QLineEdit(myParent);
62 CompNameEdit->setValidator(ValRestrict);
63 topGrid->addWidget(CompNameEdit, 0,1);
64 connect(CompNameEdit, SIGNAL(returnPressed()), SLOT(slotButtOK()));
66 topGrid->addWidget(
new QLabel(tr(
"File:"), myParent), 1,0);
67 FileEdit =
new QLineEdit(myParent);
68 FileEdit->setValidator(ValRestrict);
69 topGrid->addWidget(FileEdit, 1,1);
70 connect(FileEdit, SIGNAL(returnPressed()), SLOT(slotButtOK()));
72 ButtBrowse =
new QPushButton(tr(
"Browse"), myParent);
73 topGrid->addWidget(ButtBrowse, 1,2);
74 connect(ButtBrowse, SIGNAL(clicked()), SLOT(slotButtBrowse()));
76 ButtEdit =
new QPushButton(tr(
"Edit"), myParent);
77 topGrid->addWidget(ButtEdit, 2,2);
78 connect(ButtEdit, SIGNAL(clicked()), SLOT(slotButtEdit()));
80 FileCheck =
new QCheckBox(tr(
"show file name in schematic"), myParent);
81 topGrid->addWidget(FileCheck, 2,1);
83 SimCheck =
new QCheckBox(tr(
"include SPICE simulations"), myParent);
84 topGrid->addWidget(SimCheck, 3,1);
86 QHBox *h1 =
new QHBox(myParent);
88 PrepCombo =
new QComboBox(h1);
89 PrepCombo->insertItem(
"none");
90 PrepCombo->insertItem(
"ps2sp");
91 PrepCombo->insertItem(
"spicepp");
92 PrepCombo->insertItem(
"spiceprm");
93 QLabel * PrepLabel =
new QLabel(tr(
"preprocessor"), h1);
94 PrepLabel->setMargin(5);
95 topGrid->addWidget(h1, 4,1);
96 connect(PrepCombo, SIGNAL(activated(
int)), SLOT(slotPrepChanged(
int)));
99 QGridLayout *midGrid =
new QGridLayout(0, 2,3,5,5);
100 all->addLayout(midGrid);
102 midGrid->addWidget(
new QLabel(tr(
"SPICE net nodes:"), myParent), 0,0);
103 NodesList =
new QListBox(myParent);
104 midGrid->addWidget(NodesList, 1,0);
105 connect(NodesList, SIGNAL(doubleClicked(QListBoxItem*)),
106 SLOT(slotAddPort(QListBoxItem*)));
108 QVBox *v0 =
new QVBox(myParent);
110 midGrid->addWidget(v0, 1,1);
111 ButtAdd =
new QPushButton(tr(
"Add >>"), v0);
112 connect(ButtAdd, SIGNAL(clicked()), SLOT(slotButtAdd()));
113 ButtRemove =
new QPushButton(tr(
"<< Remove"), v0);
114 connect(ButtRemove, SIGNAL(clicked()), SLOT(slotButtRemove()));
115 v0->setStretchFactor(
new QWidget(v0), 5);
117 midGrid->addWidget(
new QLabel(tr(
"Component ports:"), myParent), 0,2);
118 PortsList =
new QListBox(myParent);
119 midGrid->addWidget(PortsList, 1,2);
120 connect(PortsList, SIGNAL(doubleClicked(QListBoxItem*)),
121 SLOT(slotRemovePort(QListBoxItem*)));
125 QHBox *h0 =
new QHBox(
this);
128 connect(
new QPushButton(tr(
"OK"),h0), SIGNAL(clicked()),
130 connect(
new QPushButton(tr(
"Apply"),h0), SIGNAL(clicked()),
131 SLOT(slotButtApply()));
132 connect(
new QPushButton(tr(
"Cancel"),h0), SIGNAL(clicked()),
133 SLOT(slotButtCancel()));
136 CompNameEdit->setText(Comp->
Name);
141 FileEdit->setText(pp->
Value);
142 FileCheck->setChecked(pp->
display);
143 SimCheck->setChecked(Comp->
Props.at(2)->Value ==
"yes");
144 for(
int i=0;
i<PrepCombo->count();
i++) {
145 if(PrepCombo->text(
i) == Comp->
Props.at(3)->Value) {
146 PrepCombo->setCurrentItem(
i);
152 loadSpiceNetList(pp->
Value);
164 void SpiceDialog::slotButtOK()
172 void SpiceDialog::slotButtCancel()
187 void SpiceDialog::slotButtApply()
190 if(CompNameEdit->text().isEmpty()) CompNameEdit->setText(Comp->
Name);
192 if(CompNameEdit->text() != Comp->
Name) {
194 if(pc->
Name == CompNameEdit->text())
196 if(pc) CompNameEdit->setText(Comp->
Name);
198 Comp->
Name = CompNameEdit->text();
206 if(pp->
Value != FileEdit->text()) {
207 pp->
Value = FileEdit->text();
210 if(pp->
display != FileCheck->isChecked()) {
211 pp->
display = FileCheck->isChecked();
216 for(
unsigned int i=0;
i<PortsList->count();
i++) {
217 if(!tmp.isEmpty()) tmp +=
',';
218 tmp +=
"_net" + PortsList->text(
i);
220 pp = Comp->
Props.next();
221 if(pp->
Value != tmp) {
225 pp = Comp->
Props.next();
226 if((pp->
Value==
"yes") != SimCheck->isChecked()) {
227 if(SimCheck->isChecked()) pp->
Value =
"yes";
228 else pp->
Value =
"no";
233 pp = Comp->
Props.next();
234 if(pp->
Value != PrepCombo->currentText()) {
235 pp->
Value = PrepCombo->currentText();
241 Doc->viewport()->repaint();
246 void SpiceDialog::slotButtBrowse()
248 QString
s = QFileDialog::getOpenFileName(
250 tr(
"SPICE netlist")+
" (*.cir);;"+tr(
"All Files")+
" (*.*)",
251 this,
"", tr(
"Select a file"));
252 if(s.isEmpty())
return;
259 QucsWorkDir.absPath() == Info.dirPath(
true)) s = Info.fileName();
260 FileEdit->setText(s);
262 Comp->
Props.at(1)->Value =
"";
267 void SpiceDialog::slotPrepChanged(
int i)
269 if(currentPrep != i) {
271 PrepCombo->setCurrentItem(i);
272 loadSpiceNetList(FileEdit->text());
277 bool SpiceDialog::loadSpiceNetList(
const QString& s)
280 if(s.isEmpty())
return false;
288 QString preprocessor = PrepCombo->currentText();
289 if (preprocessor !=
"none") {
293 QString interpreter =
"tinyperl.exe";
295 QString interpreter =
"perl";
297 if (preprocessor ==
"ps2sp") {
299 }
else if (preprocessor ==
"spicepp") {
300 script =
"spicepp.pl";
301 }
else if (preprocessor ==
"spiceprm") {
306 SpicePrep =
new QProcess(
this);
307 SpicePrep->addArgument(interpreter);
308 SpicePrep->addArgument(script);
309 SpicePrep->addArgument(FileInfo.filePath());
313 QString PrepName = PrepInfo.filePath();
316 SpicePrep->addArgument(PrepName);
317 connect(SpicePrep, SIGNAL(readyReadStdout()), SLOT(slotSkipOut()));
318 connect(SpicePrep, SIGNAL(readyReadStderr()), SLOT(slotGetPrepErr()));
320 connect(SpicePrep, SIGNAL(readyReadStdout()), SLOT(slotGetPrepOut()));
321 connect(SpicePrep, SIGNAL(readyReadStderr()), SLOT(slotGetPrepErr()));
324 QMessageBox *MBox =
new QMessageBox(tr(
"Info"),
325 tr(
"Preprocessing SPICE file \"%1\".").
arg(FileInfo.filePath()),
326 QMessageBox::NoIcon, QMessageBox::Abort,
327 QMessageBox::NoButton, QMessageBox::NoButton,
this, 0,
true,
328 Qt::WStyle_DialogBorder | Qt::WDestructiveClose);
329 connect(SpicePrep, SIGNAL(processExited()), MBox, SLOT(close()));
332 PrepFile.setName(PrepName);
333 if(!PrepFile.open(IO_WriteOnly)) {
334 QMessageBox::critical(
this, tr(
"Error"),
335 tr(
"Cannot save preprocessed SPICE file \"%1\".").
339 prestream =
new QTextStream(&PrepFile);
342 if(!SpicePrep->start()) {
343 QMessageBox::critical(
this, tr(
"Error"),
344 tr(
"Cannot execute \"%1\".").
arg(interpreter +
" " + script));
351 SpicePrep->closeStdin();
360 if(!Error.isEmpty()) {
361 QMessageBox::critical(
this, tr(
"SPICE Preprocessor Error"), Error);
368 QucsConv =
new QProcess(
this);
370 QucsConv->addArgument(
"-if");
371 QucsConv->addArgument(
"spice");
372 QucsConv->addArgument(
"-of");
373 QucsConv->addArgument(
"qucs");
374 QucsConv->addArgument(
"-i");
375 QucsConv->addArgument(FileInfo.filePath());
376 connect(QucsConv, SIGNAL(readyReadStdout()), SLOT(slotGetNetlist()));
377 connect(QucsConv, SIGNAL(readyReadStderr()), SLOT(slotGetError()));
379 QMessageBox *MBox =
new QMessageBox(tr(
"Info"),
380 tr(
"Converting SPICE file \"%1\".").
arg(FileInfo.filePath()),
381 QMessageBox::NoIcon, QMessageBox::Abort,
382 QMessageBox::NoButton, QMessageBox::NoButton,
this, 0,
true,
383 Qt::WStyle_DialogBorder | Qt::WDestructiveClose);
384 connect(QucsConv, SIGNAL(processExited()), MBox, SLOT(close()));
386 if(!QucsConv->start()) {
387 QMessageBox::critical(
this, tr(
"Error"),
391 QucsConv->closeStdin();
397 QMessageBox::critical(
this, tr(
"QucsConv Error"), Error);
400 if(!pp->
Value.isEmpty()) {
402 PortsList->insertStringList(QStringList::split(
',', pp->
Value));
407 for(
unsigned int i=0; i<PortsList->count(); i++) {
408 tmp = PortsList->text(i).remove(0, 4);
409 PortsList->changeItem(tmp, i);
411 pi = NodesList->findItem(tmp, Qt::CaseSensitive | Qt::ExactMatch);
413 else PortsList->removeItem(i--);
419 void SpiceDialog::slotSkipErr()
421 SpicePrep->readStderr();
425 void SpiceDialog::slotSkipOut()
427 SpicePrep->readStdout();
431 void SpiceDialog::slotGetPrepErr()
433 Error += QString(SpicePrep->readStderr());
437 void SpiceDialog::slotGetPrepOut()
439 (*prestream) << QString(SpicePrep->readStdout());
443 void SpiceDialog::slotGetError()
445 Error += QString(QucsConv->readStderr());
449 void SpiceDialog::slotGetNetlist()
453 Line += QString(QucsConv->readStdout());
455 while((i =
Line.find(
'\n')) >= 0) {
461 s = s.stripWhiteSpace();
463 if(s.left(5) !=
".Def:") Comp->
withSim =
true;
469 if(s ==
"### TOPLEVEL NODELIST BEGIN")
471 else if(s ==
"### SPICE OUTPUT NODELIST BEGIN")
476 if(s ==
"### TOPLEVEL NODELIST END") {
480 if(s.left(2) !=
"# ")
break;
483 if(s.left(4) ==
"_net")
484 NodesList->insertItem(s.remove(0, 4));
488 if(s ==
"### SPICE OUTPUT NODELIST END") {
492 if(s.left(2) !=
"# ")
break;
495 if(s.left(4) ==
"_net")
496 PortsList->insertItem(s);
503 void SpiceDialog::slotButtEdit()
510 void SpiceDialog::slotButtAdd()
512 int i = NodesList->currentItem();
514 PortsList->insertItem(NodesList->currentText());
515 NodesList->removeItem(i);
520 void SpiceDialog::slotButtRemove()
522 int i = PortsList->currentItem();
524 NodesList->insertItem(PortsList->currentText());
525 PortsList->removeItem(i);
530 void SpiceDialog::slotAddPort(QListBoxItem *Item)
532 if(Item) slotButtAdd();
537 void SpiceDialog::slotRemovePort(QListBoxItem *Item)
539 if(Item) slotButtRemove();