Qucs-GUI  0.0.18
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
simmessage.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  simmessage.cpp
3  ----------------
4  begin : Sat Sep 6 2003
5  copyright : (C) 2003 by Michael Margraf
6  email : michael.margraf@alumni.tu-berlin.de
7  ***************************************************************************/
8 
9 /***************************************************************************
10  * *
11  * This program is free software; you can redistribute it and/or modify *
12  * it under the terms of the GNU General Public License as published by *
13  * the Free Software Foundation; either version 2 of the License, or *
14  * (at your option) any later version. *
15  * *
16  ***************************************************************************/
17 #include <QtGui>
18 #include <stdlib.h>
19 #include <iostream>
20 using namespace std;
21 #include <QLabel>
22 #include <QGroupBox>
23 #include <QTimer>
24 #include <QPushButton>
25 #include <QTextEdit>
26 #include <QDateTime>
27 #include <QRegExp>
28 #include <QTextStream>
29 #include <QVBoxLayout>
30 #include <QHBoxLayout>
31 #include <QProcess>
32 
33 #include "simmessage.h"
34 #include "main.h"
35 #include "module.h"
36 #include "qucs.h"
37 #include "textdoc.h"
38 #include "schematic.h"
39 #include "components/opt_sim.h"
40 #include "components/vhdlfile.h"
41 
42 #ifdef __MINGW32__
43 #define executableSuffix ".exe"
44 #else
45 #define executableSuffix ""
46 #endif
47 
48 
49 SimMessage::SimMessage(QWidget *w, QWidget *parent)
50  : QDialog(parent) //, 0, FALSE, Qt::WDestructiveClose)
51 {
52  setWindowTitle(tr("Qucs Simulation Messages"));
53  QucsDoc *Doc;
54  DocWidget = w;
55  if(DocWidget->inherits("QTextEdit"))
56  Doc = (QucsDoc*) ((TextDoc*)DocWidget);
57  else
58  Doc = (QucsDoc*) ((Schematic*)DocWidget);
59 
60  DocName = Doc->DocName;
61  DataDisplay = Doc->DataDisplay;
62  Script = Doc->Script;
63  QFileInfo Info(DocName);
64  DataSet = QDir::convertSeparators(Info.dirPath()) +
65  QDir::separator() + Doc->DataSet;
66  showBias = Doc->showBias; // save some settings as the document...
67  SimOpenDpl = Doc->SimOpenDpl; // ...could be closed during the simulation.
69 
70  all = new QVBoxLayout(this);
71  all->setSpacing(5);
72  all->setMargin(5);
73  QGroupBox *Group1 = new QGroupBox(tr("Progress:"));
74  all->addWidget(Group1);
75  QVBoxLayout *vbox1 = new QVBoxLayout();
76  Group1->setLayout(vbox1);
77 
78  ProgText = new QTextEdit();
79  vbox1->addWidget(ProgText);
80  ProgText->setTextFormat(Qt::PlainText);
81  ProgText->setReadOnly(true);
82  //ProgText->setWordWrapMode(QTextOption::NoWrap);
83  ProgText->setMinimumSize(400,80);
84  wasLF = false;
85 
86  QGroupBox *HGroup = new QGroupBox();
87  QHBoxLayout *hbox = new QHBoxLayout();
88  //HGroup->setInsideMargin(5);
89  //HGroup->setInsideSpacing(5);
90  all->addWidget(HGroup);
91  QLabel *progr = new QLabel(tr("Progress:"));
92  hbox->addWidget(progr);
93  SimProgress = new QProgressBar();
94  hbox->addWidget(SimProgress);
95 // SimProgress->setPercentageVisible(false);
96  HGroup->setLayout(hbox);
97 
98  QGroupBox *Group2 = new QGroupBox(tr("Errors and Warnings:"));
99  all->addWidget(Group2);
100  QVBoxLayout *vbox2 = new QVBoxLayout();
101 
102  ErrText = new QTextEdit();
103  vbox2->addWidget(ErrText);
104  ErrText->setTextFormat(Qt::PlainText);
105  ErrText->setReadOnly(true);
106  ErrText->setWordWrapMode(QTextOption::NoWrap);
107  ErrText->setMinimumSize(400,80);
108  Group2->setLayout(vbox2);
109 
110  QHBoxLayout *Butts = new QHBoxLayout();
111  all->addLayout(Butts);
112 
113  Display = new QPushButton(tr("Goto display page"));
114  Butts->addWidget(Display);
115  Display->setDisabled(true);
116  connect(Display,SIGNAL(clicked()),SLOT(slotDisplayButton()));
117 
118  Abort = new QPushButton(tr("Abort simulation"));
119  Butts->addWidget(Abort);
120  connect(Abort,SIGNAL(clicked()),SLOT(reject()));
121  connect(Abort,SIGNAL(clicked()),SLOT(AbortSim()));
122 }
123 
125 {
126  if(SimProcess.state()==QProcess::Running) SimProcess.kill();
127  delete all;
128 }
129 
130 // ------------------------------------------------------------------------
132 {
133  Abort->setText(tr("Abort simulation"));
134  Display->setDisabled(true);
135 
136  QString txt = tr("Starting new simulation on %1 at %2").
137  arg(QDate::currentDate().toString("ddd dd. MMM yyyy")).
138  arg(QTime::currentTime().toString("hh:mm:ss:zzz"));
139  ProgText->insert(txt + "\n\n");
140 
141  SimProcess.blockSignals(false);
142  /* On Qt4 it shows as running even before we .start it. FIXME*/
143  if(SimProcess.state()==QProcess::Running ||SimProcess.state()==QProcess::Starting) {
144  qDebug() << "running!";
145  ErrText->insert(tr("ERROR: Simulator is still running!"));
146  FinishSimulation(-1);
147  return false;
148  }
149 
150  Collect.clear(); // clear list for NodeSets, SPICE components etc.
151  ProgText->insert(tr("creating netlist... "));
152  NetlistFile.setName(QucsSettings.QucsHomeDir.filePath("netlist.txt"));
153  if(!NetlistFile.open(QIODevice::WriteOnly)) {
154  ErrText->insert(tr("ERROR: Cannot write netlist file!"));
155  FinishSimulation(-1);
156  return false;
157  }
158 
159  Stream.setDevice(&NetlistFile);
160 
161  if(!DocWidget->inherits("QTextEdit")) {
162  SimPorts =
163  ((Schematic*)DocWidget)->prepareNetlist(Stream, Collect, ErrText);
164  if(SimPorts < -5) {
165  NetlistFile.close();
166  ErrText->insert(tr("ERROR: Cannot simulate a text file!"));
167  FinishSimulation(-1);
168  return false;
169  }
170  }
171  Collect.append("*"); // mark the end
172 
173 
174  disconnect(&SimProcess, 0, 0, 0);
175  connect(&SimProcess, SIGNAL(readyReadStandardError()), SLOT(slotDisplayErr()));
176  connect(&SimProcess, SIGNAL(readyReadStandardOutput()),
177  SLOT(slotReadSpiceNetlist()));
178  connect(&SimProcess, SIGNAL(finished(int)),
179  SLOT(slotFinishSpiceNetlist(int)));
180 
181  nextSPICE();
182  return true;
183  // Since now, the Doc pointer may be obsolete, as the user could have
184  // closed the schematic !!!
185 }
186 
187 // ---------------------------------------------------
188 // Converts a spice netlist into Qucs format and outputs it.
190 {
191  QString Line;
192  for(;;) { // search for next SPICE component
193  Line = *(Collect.begin());
194  Collect.remove(Collect.begin());
195  if(Line == "*") { // worked on all components ?
196  startSimulator(); // <<<<<================== go on ===
197  return;
198  }
199 // FIXME #warning SPICE section below not being covered?
200  qDebug() << "goin thru SPICE branch on simmmessage.cpp";
201  if(Line.left(5) == "SPICE") {
202  if(Line.at(5) != 'o') insertSim = true;
203  else insertSim = false;
204  break;
205  }
206  Collect.append(Line);
207  }
208 
209 
210  QString FileName = Line.section('"', 1,1);
211  Line = Line.section('"', 2); // port nodes
212  if(Line.isEmpty()) makeSubcircuit = false;
213  else makeSubcircuit = true;
214 
215  QString prog;
216  QStringList com;
217  prog = QucsSettings.BinDir + "qucsconv" + executableSuffix;
218  if(makeSubcircuit)
219  com << "-g" << "_ref";
220  com << "-if" << "spice" << "-of" << "qucs";
221 
222  QFile SpiceFile;
223  if(FileName.find(QDir::separator()) < 0) // add path ?
224  SpiceFile.setName(QucsSettings.QucsWorkDir.path() + QDir::separator() + FileName);
225  else
226  SpiceFile.setName(FileName);
227  if(!SpiceFile.open(QIODevice::ReadOnly)) {
228  ErrText->insert(tr("ERROR: Cannot open SPICE file \"%1\".").arg(FileName));
229  FinishSimulation(-1);
230  return;
231  }
232 
233  if(makeSubcircuit) {
234  Stream << "\n.Def:" << properName(FileName) << " ";
235 
236  Line.replace(',', ' ');
237  Stream << Line;
238  if(!Line.isEmpty()) Stream << " _ref";
239  }
240  Stream << "\n";
241 
242  ProgressText = "";
243 
244  qDebug() << "start QucsConv" << prog << com.join(" ");
245  SimProcess.start(prog, com);
246 
247  if(!SimProcess.Running) {
248  ErrText->insert(tr("SIM ERROR: Cannot start QucsConv!"));
249  FinishSimulation(-1);
250  return;
251  }
252 
253  QByteArray SpiceContent = SpiceFile.readAll();
254  SpiceFile.close();
255  QString command(SpiceContent); //to convert byte array to string
256  SimProcess.setStandardInputFile(command); //? FIXME works?
257  qDebug() << command;
258  connect(&SimProcess, SIGNAL(wroteToStdin()), SLOT(slotCloseStdin()));
259 }
260 
261 // ------------------------------------------------------------------------
263 {
264  //SimProcess.closeStdin(); //? channel not available in Qt4?
265  disconnect(&SimProcess, SIGNAL(wroteToStdin()), 0, 0);
266 }
267 
268 // ------------------------------------------------------------------------
270 {
271  int i;
272  QString s;
273  ProgressText += QString(SimProcess.readAllStandardOutput());
274 
275  while((i = ProgressText.find('\n')) >= 0) {
276 
277  s = ProgressText.left(i);
278  ProgressText.remove(0, i+1);
279 
280 
281  s = s.stripWhiteSpace();
282  if(s.isEmpty()) continue;
283  if(s.at(0) == '#') continue;
284  if(s.at(0) == '.') if(s.left(5) != ".Def:") { // insert simulations later
285  if(insertSim) Collect.append(s);
286  continue;
287  }
288  Stream << " " << s << '\n';
289  }
290 }
291 
292 // ------------------------------------------------------------------------
294 {
295  if(makeSubcircuit)
296  Stream << ".Def:End\n\n";
297 
298  nextSPICE();
299 }
300 
301 // ------------------------------------------------------------------------
302 #ifdef __MINGW32__
303 #include <windows.h>
304 static QString pathName(QString longpath) {
305  const char * lpath = QDir::convertSeparators(longpath).ascii();
306  char spath[2048];
307  int len = GetShortPathNameA(lpath,spath,sizeof(spath)-1);
308  spath[len] = '\0';
309  return QString(spath);
310 }
311 #else
312 static QString pathName(QString longpath) {
313  return longpath;
314 }
315 #endif
316 
317 
322 {
323  // Using the Doc pointer here is risky as the user may have closed
324  // the schematic, but converting the SPICE netlists is (hopefully)
325  // faster than the user (I have no other idea).
326 
327  QString SimTime;
328  QString Program;
329  QStringList Arguments;
330  QString SimPath = QDir::convertSeparators (QucsSettings.QucsHomeDir.absPath());
331 #ifdef __MINGW32__
332  QString QucsDigiLib = "qucsdigilib.bat";
333  QString QucsDigi = "qucsdigi.bat";
334  QString QucsVeri = "qucsveri.bat";
335 #else
336  QString QucsDigiLib = "qucsdigilib";
337  QString QucsDigi = "qucsdigi";
338  QString QucsVeri = "qucsveri";
339 #endif
340  SimOpt = NULL;
341  bool isVerilog = false;
342 
343  // Simulate text window.
344  if(DocWidget->inherits("QTextEdit")) {
345 
346  TextDoc * Doc = (TextDoc*)DocWidget;
347 
348  // Take VHDL file in memory as it could contain unsaved changes.
349  Stream << Doc->toPlainText();
350  NetlistFile.close();
351  ProgText->insert(tr("done.")+"\n"); // of "creating netlist...
352 
353  // Simulation.
354  if (Doc->simulation) {
355  SimTime = Doc->SimTime;
356  QString libs = Doc->Libraries.lower();
358 #ifdef __MINGW32__
359  if(libs.isEmpty()) {
360  libs = "";
361  }
362  else {
363  libs.replace(" ",",-l");
364  libs = "-Wl,-l" + libs;
365  }
366 #else
367  if(libs.isEmpty()) {
368  libs = "-c";
369  }
370  else {
371  libs.replace(" ",",-l");
372  libs = "-c,-l" + libs;
373  }
374 #endif
375  Program = pathName(QucsSettings.BinDir + QucsDigi);
376  Arguments << QucsSettings.QucsHomeDir.filePath("netlist.txt")
377  << DataSet << SimTime << pathName(SimPath)
378  << pathName(QucsSettings.BinDir) << libs;
379  }
380  // Module.
381  else {
382  QString text = Doc->toPlainText();
383  VHDL_File_Info VInfo (text);
384  QString entity = VInfo.EntityName.lower();
385  QString lib = Doc->Library.lower();
386  if (lib.isEmpty()) lib = "work";
387  QString dir = QDir::convertSeparators (QucsSettings.QucsHomeDir.path());
388  QDir vhdlDir(dir);
389  if(!vhdlDir.exists("vhdl"))
390  if(!vhdlDir.mkdir("vhdl")) {
391  ErrText->insert(tr("ERROR: Cannot create VHDL directory \"%1\"!")
392  .arg(vhdlDir.path()+"/vhdl"));
393  return;
394  }
395  vhdlDir.setPath(vhdlDir.path()+"/vhdl");
396  if(!vhdlDir.exists(lib))
397  if(!vhdlDir.mkdir(lib)) {
398  ErrText->insert(tr("ERROR: Cannot create VHDL directory \"%1\"!")
399  .arg(vhdlDir.path()+"/"+lib));
400  return;
401  }
402  vhdlDir.setPath(vhdlDir.path()+"/"+lib);
403  QFile destFile;
404  destFile.setName(vhdlDir.filePath(entity+".vhdl"));
405  if(!destFile.open(QIODevice::WriteOnly)) {
406  ErrText->insert(tr("ERROR: Cannot create \"%1\"!")
407  .arg(destFile.name()));
408  return;
409  }
410  destFile.writeBlock(text.ascii(), text.length());
411  destFile.close();
412  Program = pathName(QucsSettings.BinDir + QucsDigiLib);
413  Arguments << QucsSettings.QucsHomeDir.filePath("netlist.txt")
414  << pathName(SimPath)
415  << entity
416  << lib;
417  }
418  }
419  // Simulate schematic window.
420  else {
421  // output NodeSets, SPICE simulations etc.
422  for(QStringList::Iterator it = Collect.begin();
423  it != Collect.end(); ++it) {
424  // don't put library includes into netlist...
425  if ((*it).right(4) != ".lst" &&
426  (*it).right(5) != ".vhdl" &&
427  (*it).right(4) != ".vhd" &&
428  (*it).right(2) != ".v") {
429  Stream << *it << '\n';
430  }
431  }
432  Stream << '\n';
433 
434  isVerilog = ((Schematic*)DocWidget)->isVerilog;
435  SimTime = ((Schematic*)DocWidget)->createNetlist(Stream, SimPorts);
436  if(SimTime.length()>0&&SimTime.at(0) == '\xA7') {
437  NetlistFile.close();
438  ErrText->insert(SimTime.mid(1));
439  FinishSimulation(-1);
440  return;
441  }
442  if (isVerilog) {
443  Stream << "\n"
444  << " initial begin\n"
445  << " $dumpfile(\"digi.vcd\");\n"
446  << " $dumpvars();\n"
447  << " #" << SimTime << " $finish;\n"
448  << " end\n\n"
449  << "endmodule // TestBench\n";
450  }
451  NetlistFile.close();
452  ProgText->insert(tr("done.")+"\n"); // of "creating netlist...
453 
454  if(SimPorts < 0) {
455 
456  // append command arguments
457  // append netlist with same arguments
458  if (! Module::vaComponents.isEmpty()) {
459 
469  QStringList usedComponents;
470 
471  if (!NetlistFile.open(QIODevice::ReadOnly))
472  QMessageBox::critical(this, tr("Error"), tr("Cannot read netlist!"));
473  else {
474  QString net = QString(NetlistFile.readAll());
475 
476  QMapIterator<QString, QString> i(Module::vaComponents);
477  while (i.hasNext()) {
478  i.next();
479  if (net.contains(i.key()))
480  usedComponents << i.key();
481  }
482  NetlistFile.close();
483  }
484 
485  if (! usedComponents.isEmpty()) {
486 
487 
488  // \todo remvoe the command line arguments? use only netlist annotation?
489  //Arguments << "-p" << QucsSettings.QucsWorkDir.absolutePath()
490  // << "-m" << usedComponents;
491  //qDebug() << "Command :" << Program << Arguments.join(" ");
492 
495  if (!NetlistFile.open(QFile::Append | QFile::Text))
496  QMessageBox::critical(this, tr("Error"), tr("Cannot read netlist!"));
497  else {
498  QTextStream out(&NetlistFile);
499  out << "\n";
500  out << "# --path=" << QucsSettings.QucsWorkDir.absolutePath() << "\n";
501  out << "# --module=" << usedComponents.join(" ") << "\n";
502 
503  NetlistFile.close();
504  }
505  }
506  } // vaComponents not empty
507 
509  ((Optimize_Sim*)SimOpt)->createASCOnetlist();
510 
511  Program = QucsSettings.AscoBinDir.canonicalPath();
512  Program = QDir::toNativeSeparators(Program+"/"+"asco"+QString(executableSuffix));
513  Arguments << "-qucs" << QucsSettings.QucsHomeDir.filePath("asco_netlist.txt")
514  << "-o" << "asco_out";
515  }
516  else {
517  Program = QucsSettings.BinDir + "qucsator" + executableSuffix;
518  Arguments << "-b" << "-g" << "-i"
519  << QucsSettings.QucsHomeDir.filePath("netlist.txt")
520  << "-o" << DataSet;
521  }
522  }
523  else {
524  if (isVerilog) {
525  Program = QDir::toNativeSeparators(QucsSettings.BinDir + QucsVeri);
526  Arguments << QDir::toNativeSeparators(QucsSettings.QucsHomeDir.filePath("netlist.txt"))
527  << DataSet
528  << SimTime
529  << QDir::toNativeSeparators(SimPath)
530  << QDir::toNativeSeparators(QucsSettings.BinDir)
531  << "-c";
532  } else {
534 #ifdef __MINGW32__
535  Program = QDir::toNativeSeparators(pathName(QucsSettings.BinDir + QucsDigi));
536  Arguments << QDir::toNativeSeparators(QucsSettings.QucsHomeDir.filePath("netlist.txt"))
537  << DataSet
538  << SimTime
539  << QDir::toNativeSeparators(SimPath)
540  << QDir::toNativeSeparators(QucsSettings.BinDir) << "-Wall" << "-c";
541 #else
542  Program = QDir::toNativeSeparators(pathName(QucsSettings.BinDir + QucsDigi));
543  Arguments << QucsSettings.QucsHomeDir.filePath("netlist.txt")
544  << DataSet << SimTime << pathName(SimPath)
545  << pathName(QucsSettings.BinDir) << "-Wall" << "-c";
546 
547 #endif
548  }
549  }
550  }
551 
552  disconnect(&SimProcess, 0, 0, 0);
553  connect(&SimProcess, SIGNAL(readyReadStandardError()), SLOT(slotDisplayErr()));
554  connect(&SimProcess, SIGNAL(readyReadStandardOutput()), SLOT(slotDisplayMsg()));
555  connect(&SimProcess, SIGNAL(finished(int)), SLOT(slotSimEnded(int)));
556 
557 #ifdef SPEEDUP_PROGRESSBAR
558  waitForUpdate = false;
559 #endif
560  wasLF = false;
561 
562  ProgressText = "";
563 
564 #ifdef __MINGW32__
565  QString sep(";"); // path separator
566 #else
567  QString sep(":");
568 #endif
569 
570  // append process PATH
571  QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
572  // insert Qucs bin dir, so ASCO can find qucsator
573  env.insert("PATH", env.value("PATH") + sep + QucsSettings.BinDir );
574  SimProcess.setProcessEnvironment(env);
575  QFile file(Program);
576  if ( !file.exists() ){
577  ErrText->insert(tr("ERROR: Program not found: %1").arg(Program));
578  FinishSimulation(-1);
579  return;
580  }
581  else
582  file.close();
583 
584  qDebug() << "Command :" << Program << Arguments.join(" ");
585  SimProcess.start(Program, Arguments); // launch the program
586 
587  if(!SimProcess.Running) {
588  ErrText->insert(tr("ERROR: Cannot start simulator!"));
589  FinishSimulation(-1);
590  return;
591  }
592 
593 }
594 
595 // ------------------------------------------------------------------------
597  Component *pc;
598  for(pc=Doc->Components->first(); pc!=0; pc=Doc->Components->next())
599  if(pc->isActive)
600  if(pc->Model == ".Opt")
601  return pc;
602  return NULL;
603 }
604 
605 
606 // ------------------------------------------------------------------------
607 // Is called when the process sends an output to stdout.
609 {
610  int i;
611  ProgressText += QString(SimProcess.readAllStandardOutput());
612  if(wasLF) {
613  i = ProgressText.findRev('\r');
614  if(i > 1) {
615 #ifdef SPEEDUP_PROGRESSBAR
616  iProgress = 10*int(ProgressText.at(i-2).latin1()-'0') +
617  int(ProgressText.at(i-1).latin1()-'0');
618  if(!waitForUpdate) {
619  QTimer::singleShot(20, this, SLOT(slotUpdateProgressBar()));
620  waitForUpdate = true;
621  }
622 #else
623  SimProgress->setMaximum(100);
624  SimProgress->setValue(
625  10*int(ProgressText.at(i-2).latin1()-'0') +
626  int(ProgressText.at(i-1).latin1()-'0'));
627 #endif
628  ProgressText.remove(0, i+1);
629  }
630 
631  if(ProgressText.size()>0&&ProgressText.at(0).latin1() <= '\t')
632  return;
633  }
634  else {
635  i = ProgressText.find('\t');
636  if(i >= 0) {
637  wasLF = true;
638  ProgText->insert(ProgressText.left(i));
639  ProgressText.remove(0, i+1);
640  return;
641  }
642  }
643 
644  ProgText->insert(ProgressText);
645  ProgressText = "";
646  wasLF = false;
647 }
648 
649 #ifdef SPEEDUP_PROGRESSBAR
650 // ------------------------------------------------------------------------
651 void SimMessage::slotUpdateProgressBar()
652 {
653  SimProgress->setProgress(iProgress, 100);
654  waitForUpdate = false;
655 }
656 #endif
657 
658 // ------------------------------------------------------------------------
659 // Is called when the process sends an output to stderr.
661 {
662  QTextCursor cursor = ErrText->textCursor();
663  cursor.movePosition(QTextCursor::End);
664  ErrText->insert(QString(SimProcess.readAllStandardError()));
665 }
666 
667 // ------------------------------------------------------------------------
668 // Is called when the simulation process terminates.
669 void SimMessage::slotSimEnded(int status)
670 {
671  FinishSimulation(status); //0 - normal | 1 - crash
672 }
673 
674 // ------------------------------------------------------------------------
675 // Is called when the simulation ended with errors before starting simulator
676 // process.
678 {
679  Abort->setText(tr("Close window"));
680  Display->setDisabled(false);
681  SimProgress->setValue(100); // progress bar to 100%
682 
683  QDate d = QDate::currentDate(); // get date of today
684  QTime t = QTime::currentTime(); // get time
685 
686  if(Status == 0) {
687  QString txt = tr("Simulation ended on %1 at %2").
688  arg(d.toString("ddd dd. MMM yyyy")).
689  arg(t.toString("hh:mm:ss:zzz"));
690  ProgText->insert("\n" + txt + "\n" + tr("Ready.") + "\n");
691  }
692  else {
693  QString txt = tr("Errors occurred during simulation on %1 at %2").
694  arg(d.toString("ddd dd. MMM yyyy")).
695  arg(t.toString("hh:mm:ss:zzz"));
696  ProgText->insert("\n" + txt + "\n" + tr("Aborted.") + "\n");
697  }
698 
699  QFile file(QucsSettings.QucsHomeDir.filePath("log.txt")); // save simulator messages
700  if(file.open(QIODevice::WriteOnly)) {
701  int z;
702  QTextStream stream(&file);
703  stream << tr("Output:\n-------") << "\n\n";
704  for(int z=0; z<ProgText->document()->blockCount(); z++)
705  stream << ProgText->document()->findBlockByNumber(z).text() << "\n";
706  stream << "\n\n\n" << tr("Errors:\n-------") << "\n\n";
707  for(int z=0; z<ErrText->document()->blockCount(); z++)
708  stream << ErrText->document()->findBlockByNumber(z).text() << "\n";
709  file.close();
710  }
711 
712  if(Status == 0) {
713  if(SimOpt) { // save optimization data
714  QFile ifile(QucsSettings.QucsHomeDir.filePath("asco_out.dat"));
715  QFile ofile(DataSet);
716  if(ifile.open(QIODevice::ReadOnly)) {
717  if(ofile.open(QIODevice::WriteOnly)) {
718  QByteArray data = ifile.readAll();
719  ofile.writeBlock(data);
720  ofile.close();
721  }
722  ifile.close();
723  }
724  if(((Optimize_Sim*)SimOpt)->loadASCOout())
725  ((Schematic*)DocWidget)->setChanged(true,true);
726  }
727  }
728 
729  emit SimulationEnded(Status, this);
730 }
731 
732 // ------------------------------------------------------------------------
733 // To call accept(), which is protected, from the outside.
735 {
736  accept();
737 }
738 
739 // ------------------------------------------------------------------------
741 {
743  accept();
744 }
745 
747 {
748  SimProcess.kill();
749 }
QString EntityName
Definition: vhdlfile.h:59
void nextSPICE()
Definition: simmessage.cpp:189
static QString pathName(QString longpath)
Definition: simmessage.cpp:312
QString Libraries
Definition: textdoc.h:73
void slotReadSpiceNetlist()
Definition: simmessage.cpp:269
QDir QucsWorkDir
Definition: main.h:65
QString Script
Definition: qucsdoc.h:54
Definition of the TextDoc class.
bool SimOpenDpl
Definition: qucsdoc.h:61
void AbortSim()
Definition: simmessage.cpp:746
QFile NetlistFile
Definition: simmessage.h:99
QTextEdit * ErrText
Definition: simmessage.h:89
QString DocName
Definition: simmessage.h:86
int isActive
Definition: component.h:77
QString Library
Definition: textdoc.h:72
tQucsSettings QucsSettings
Definition: main.cpp:52
void slotDisplayErr()
Definition: simmessage.cpp:660
int showBias
Definition: qucsdoc.h:63
void FinishSimulation(int)
Definition: simmessage.cpp:677
bool simulation
Definition: textdoc.h:71
Component * findOptimization(Schematic *)
Definition: simmessage.cpp:596
void displayDataPage(QString &, QString &)
QTextStream Stream
Definition: simmessage.h:100
QString Script
Definition: simmessage.h:86
SimMessage(QWidget *, QWidget *parent=0)
Definition: simmessage.cpp:49
QPushButton * Display
Definition: simmessage.h:91
QPushButton * Abort
Definition: simmessage.h:91
bool SimRunScript
Definition: qucsdoc.h:62
int showBias
Definition: simmessage.h:83
QString BinDir
Definition: main.h:57
QProgressBar * SimProgress
Definition: simmessage.h:92
Definitions and declarations for the main application.
QDir AscoBinDir
Definition: main.h:68
bool insertSim
Definition: simmessage.h:97
bool SimOpenDpl
Definition: simmessage.h:84
Q3PtrList< Component > * Components
Definition: schematic.h:123
void SimulationEnded(int, SimMessage *)
void slotDisplayButton()
Definition: simmessage.cpp:740
QProcess SimProcess
Definition: simmessage.h:88
Component * SimOpt
Definition: simmessage.h:95
Definition: element.h:48
QDir QucsHomeDir
Definition: main.h:66
QString SimTime
Definition: qucsdoc.h:55
QString DataSet
Definition: qucsdoc.h:52
static QMap< QString, QString > vaComponents
Definition: module.h:43
void startSimulator()
SimMessage::startSimulator simulates the document in view.
Definition: simmessage.cpp:321
QWidget * DocWidget
Definition: simmessage.h:82
#define executableSuffix
Definition: simmessage.cpp:45
bool startProcess()
Definition: simmessage.cpp:131
QString Model
Definition: component.h:80
QString DataSet
Definition: simmessage.h:86
void slotCloseStdin()
Definition: simmessage.cpp:262
QStringList Collect
Definition: simmessage.h:98
QString DocName
Definition: qucsdoc.h:51
void slotClose()
Definition: simmessage.cpp:734
The TextDoc class definition.
Definition: textdoc.h:49
bool makeSubcircuit
Definition: simmessage.h:97
void slotFinishSpiceNetlist(int status)
Definition: simmessage.cpp:293
int SimPorts
Definition: simmessage.h:96
QVBoxLayout * all
Definition: simmessage.h:102
QString properName(const QString &Name)
Definition: main.cpp:476
void slotDisplayMsg()
Definition: simmessage.cpp:608
void slotSimEnded(int status)
Definition: simmessage.cpp:669
bool wasLF
Definition: simmessage.h:90
QString ProgressText
Definition: simmessage.h:93
QString DataDisplay
Definition: qucsdoc.h:53
bool SimRunScript
Definition: simmessage.h:85
QString DataDisplay
Definition: simmessage.h:86
QTextEdit * ProgText
Definition: simmessage.h:89