Qucs-GUI  0.0.18
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
main.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  main.cpp
3  ----------
4  begin : Thu Aug 28 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  ***************************************************************************/
22 #ifdef HAVE_CONFIG_H
23 # include <config.h>
24 #endif
25 
26 #include <QtGui>
27 #include <stdlib.h>
28 #include <ctype.h>
29 #include <math.h>
30 #include <locale.h>
31 
32 #include <QApplication>
33 #include <QString>
34 #include <QStringList>
35 #include <QTextCodec>
36 #include <QTranslator>
37 #include <QFile>
38 #include <QMessageBox>
39 #include <QRegExp>
40 
41 #include "qucs.h"
42 #include "main.h"
43 #include "node.h"
44 
45 #include "schematic.h"
46 #include "module.h"
47 
48 #ifdef _WIN32
49 #include <Windows.h> //for OutputDebugString
50 #endif
51 
53 
54 QucsApp *QucsMain = 0; // the Qucs application itself
55 QString lastDir; // to remember last directory for several dialogs
56 QStringList qucsPathList;
57 
58 // #########################################################################
59 // Loads the settings file and stores the settings.
61 {
62  QSettings settings("qucs","qucs");
63 
64  if(settings.contains("x"))QucsSettings.x=settings.value("x").toInt();
65  if(settings.contains("y"))QucsSettings.y=settings.value("y").toInt();
66  if(settings.contains("dx"))QucsSettings.dx=settings.value("dx").toInt();
67  if(settings.contains("dy"))QucsSettings.dy=settings.value("dy").toInt();
68  if(settings.contains("font"))QucsSettings.font.fromString(settings.value("font").toString());
69  if(settings.contains("largeFontSize"))QucsSettings.largeFontSize=settings.value("largeFontSize").toDouble();
70  if(settings.contains("maxUndo"))QucsSettings.maxUndo=settings.value("maxUndo").toInt();
71  if(settings.contains("NodeWiring"))QucsSettings.NodeWiring=settings.value("NodeWiring").toInt();
72  if(settings.contains("BGColor"))QucsSettings.BGColor.setNamedColor(settings.value("BGColor").toString());
73  if(settings.contains("Editor"))QucsSettings.Editor=settings.value("Editor").toString();
74  if(settings.contains("FileTypes"))QucsSettings.FileTypes=settings.value("FileTypes").toStringList();
75  if(settings.contains("Language"))QucsSettings.Language=settings.value("Language").toString();
76  if(settings.contains("Comment"))QucsSettings.Comment.setNamedColor(settings.value("Comment").toString());
77  if(settings.contains("String"))QucsSettings.String.setNamedColor(settings.value("String").toString());
78  if(settings.contains("Integer"))QucsSettings.Integer.setNamedColor(settings.value("Integer").toString());
79  if(settings.contains("Real"))QucsSettings.Real.setNamedColor(settings.value("Real").toString());
80  if(settings.contains("Character"))QucsSettings.Character.setNamedColor(settings.value("Character").toString());
81  if(settings.contains("Type"))QucsSettings.Type.setNamedColor(settings.value("Type").toString());
82  if(settings.contains("Attribute"))QucsSettings.Attribute.setNamedColor(settings.value("Attribute").toString());
83  if(settings.contains("Directive"))QucsSettings.Directive.setNamedColor(settings.value("Directive").toString());
84  if(settings.contains("Task"))QucsSettings.Comment.setNamedColor(settings.value("Task").toString());
85 
86  if(settings.contains("Editor"))QucsSettings.Editor = settings.value("Editor").toString();
87  //if(settings.contains("BinDir"))QucsSettings.BinDir = settings.value("BinDir").toString();
88  //if(settings.contains("LangDir"))QucsSettings.LangDir = settings.value("LangDir").toString();
89  //if(settings.contains("LibDir"))QucsSettings.LibDir = settings.value("LibDir").toString();
90  if(settings.contains("AdmsXmlBinDir"))QucsSettings.AdmsXmlBinDir = settings.value("AdmsXmlBinDir").toString();
91  if(settings.contains("AscoBinDir"))QucsSettings.AscoBinDir = settings.value("AscoBinDir").toString();
92  //if(settings.contains("OctaveDir"))QucsSettings.OctaveDir = settings.value("OctaveDir").toString();
93  //if(settings.contains("ExamplesDir"))QucsSettings.ExamplesDir = settings.value("ExamplesDir").toString();
94  //if(settings.contains("DocDir"))QucsSettings.DocDir = settings.value("DocDir").toString();
95  if(settings.contains("OctaveBinDir"))QucsSettings.OctaveBinDir.setPath(settings.value("OctaveBinDir").toString());
96  if(settings.contains("QucsHomeDir"))
97  if(settings.value("QucsHomeDir").toString() != "")
98  QucsSettings.QucsHomeDir.setPath(settings.value("QucsHomeDir").toString());
99  QucsSettings.QucsWorkDir = QucsSettings.QucsHomeDir;
100 
101  if (settings.contains("IngnoreVersion")) QucsSettings.IgnoreFutureVersion = settings.value("IngnoreVersion").toBool();
102  else QucsSettings.IgnoreFutureVersion = false;
103 
104 
105  QucsSettings.RecentDocs = settings.value("RecentDocs").toString().split("*",QString::SkipEmptyParts);
106  QucsSettings.numRecentDocs = QucsSettings.RecentDocs.count();
107 
108 
109  // If present read in the list of directory paths in which Qucs should
110  // search for subcircuit schematics
111  int npaths = settings.beginReadArray("Paths");
112  for (int i = 0; i < npaths; ++i)
113  {
114  settings.setArrayIndex(i);
115  QString apath = settings.value("path").toString();
116  qucsPathList.append(apath);
117  }
118  settings.endArray();
119 
120  QucsSettings.numRecentDocs = 0;
121 
122  return true;
123 }
124 
125 // #########################################################################
126 // Saves the settings in the settings file.
128 {
129  QSettings settings ("qucs","qucs");
130 
131  settings.setValue("x", QucsSettings.x);
132  settings.setValue("y", QucsSettings.y);
133  settings.setValue("dx", QucsSettings.dx);
134  settings.setValue("dy", QucsSettings.dy);
135  settings.setValue("font", QucsSettings.font.toString());
136  settings.setValue("largeFontSize", QucsSettings.largeFontSize);
137  settings.setValue("maxUndo", QucsSettings.maxUndo);
138  settings.setValue("NodeWiring", QucsSettings.NodeWiring);
139  settings.setValue("BGColor", QucsSettings.BGColor.name());
140  settings.setValue("Editor", QucsSettings.Editor);
141  settings.setValue("FileTypes", QucsSettings.FileTypes);
142  settings.setValue("Language", QucsSettings.Language);
143  settings.setValue("Comment", QucsSettings.Comment.name());
144  settings.setValue("String", QucsSettings.String.name());
145  settings.setValue("Integer", QucsSettings.Integer.name());
146  settings.setValue("Real", QucsSettings.Real.name());
147  settings.setValue("Character", QucsSettings.Character.name());
148  settings.setValue("Type", QucsSettings.Type.name());
149  settings.setValue("Attribute", QucsSettings.Attribute.name());
150  settings.setValue("Directive", QucsSettings.Directive.name());
151  settings.setValue("Task", QucsSettings.Comment.name());
152  settings.setValue("Editor", QucsSettings.Editor);
153  //settings.setValue("BinDir", QucsSettings.BinDir);
154  //settings.setValue("LangDir", QucsSettings.LangDir);
155  //settings.setValue("LibDir", QucsSettings.LibDir);
156  settings.setValue("AdmsXmlBinDir", QucsSettings.AdmsXmlBinDir.canonicalPath());
157  settings.setValue("AscoBinDir", QucsSettings.AscoBinDir.canonicalPath());
158  //settings.setValue("OctaveDir", QucsSettings.OctaveDir);
159  //settings.setValue("ExamplesDir", QucsSettings.ExamplesDir);
160  //settings.setValue("DocDir", QucsSettings.DocDir);
161  settings.setValue("OctaveBinDir", QucsSettings.OctaveBinDir.canonicalPath());
162  settings.setValue("QucsHomeDir", QucsSettings.QucsHomeDir.canonicalPath());
163  settings.setValue("IngnoreVersion",QucsSettings.IgnoreFutureVersion);
164 
165  // Copy the list of directory paths in which Qucs should
166  // search for subcircuit schematics from qucsPathList
167  settings.remove("Paths");
168  settings.beginWriteArray("Paths");
169  int i = 0;
170  foreach(QString path, qucsPathList) {
171  settings.setArrayIndex(i);
172  settings.setValue("path", path);
173  i++;
174  }
175  settings.endArray();
176 
177  return true;
178 
179 }
180 
193 void qucsMessageOutput(QtMsgType type, const char *msg)
194 {
195  switch (type) {
196  case QtDebugMsg:
197  fprintf(stderr, "Debug: %s\n", msg);
198  break;
199  case QtWarningMsg:
200  fprintf(stderr, "Warning: %s\n", msg);
201  break;
202  case QtCriticalMsg:
203  fprintf(stderr, "Critical: %s\n", msg);
204  break;
205  case QtFatalMsg:
206  fprintf(stderr, "Fatal: %s\n", msg);
207  abort();
208  }
209 
210 #ifdef _WIN32
211  OutputDebugStringA(msg);
212 #endif
213 }
214 
215 // #########################################################################
216 // #########################################################################
217 // ########## ##########
218 // ########## MOVE SOMEWHERE ELSE START ##########
219 // ########## ##########
220 // #########################################################################
221 
222 
223 
224 QString complexRect(double real, double imag, int Precision)
225 {
226  QString Text;
227  if(fabs(imag) < 1e-250) Text = QString::number(real,'g',Precision);
228  else {
229  Text = QString::number(imag,'g',Precision);
230  if(Text.at(0) == '-') {
231  Text.replace(0,1,'j');
232  Text = '-'+Text;
233  }
234  else Text = "+j"+Text;
235  Text = QString::number(real,'g',Precision) + Text;
236  }
237  return Text;
238 }
239 
240 QString complexDeg(double real, double imag, int Precision)
241 {
242  QString Text;
243  if(fabs(imag) < 1e-250) Text = QString::number(real,'g',Precision);
244  else {
245  Text = QString::number(sqrt(real*real+imag*imag),'g',Precision) + " / ";
246  Text += QString::number(180.0/M_PI*atan2(imag,real),'g',Precision) + QString::fromUtf8("°");
247  }
248  return Text;
249 }
250 
251 QString complexRad (double real, double imag, int Precision)
252 {
253  QString Text;
254  if(fabs(imag) < 1e-250) Text = QString::number(real,'g',Precision);
255  else {
256  Text = QString::number(sqrt(real*real+imag*imag),'g',Precision);
257  Text += " / " + QString::number(atan2(imag,real),'g',Precision) + "rad";
258  }
259  return Text;
260 }
261 
262 // #########################################################################
263 QString StringNum(double num, char form, int Precision)
264 {
265  int a = 0;
266  char *p, Buffer[512], Format[6] = "%.00g";
267 
268  if(Precision < 0) {
269  Format[1] = form;
270  Format[2] = 0;
271  }
272  else {
273  Format[4] = form;
274  Format[2] += Precision / 10;
275  Format[3] += Precision % 10;
276  }
277  sprintf(Buffer, Format, num);
278  p = strchr(Buffer, 'e');
279  if(p) {
280  p++;
281  if(*(p++) == '+') { a = 1; } // remove '+' of exponent
282  if(*p == '0') { a++; p++; } // remove leading zeros of exponent
283  if(a > 0)
284  do {
285  *(p-a) = *p;
286  } while(*(p++) != 0); // override characters not needed
287  }
288 
289  return QString(Buffer);
290 }
291 
292 // #########################################################################
293 QString StringNiceNum(double num)
294 {
295  char Format[6] = "%.8e";
296  if(fabs(num) < 1e-250) return QString("0"); // avoid many problems
297  if(fabs(log10(fabs(num))) < 3.0) Format[3] = 'g';
298 
299  int a = 0;
300  char *p, *pe, Buffer[512];
301 
302  sprintf(Buffer, Format, num);
303  p = pe = strchr(Buffer, 'e');
304  if(p) {
305  if(*(++p) == '+') { a = 1; } // remove '+' of exponent
306  if(*(++p) == '0') { a++; p++; } // remove leading zeros of exponent
307  if(a > 0)
308  do {
309  *(p-a) = *p;
310  } while(*(p++) != 0); // override characters not needed
311 
312  // In 'g' format, trailing zeros are already cut off !!!
313  p = strchr(Buffer, '.');
314  if(p) {
315  if(!pe) pe = Buffer + strlen(Buffer);
316  p = pe-1;
317  while(*p == '0') // looking for unneccessary zero characters
318  if((--p) <= Buffer) break;
319  if(*p != '.') p++; // no digit after decimal point ?
320  while( (*(p++) = *(pe++)) != 0 ) ; // overwrite zero characters
321  }
322  }
323 
324  return QString(Buffer);
325 }
326 
327 // #########################################################################
328 void str2num(const QString& s_, double& Number, QString& Unit, double& Factor)
329 {
330  QString str = s_.stripWhiteSpace();
331 
332 /* int i=0;
333  bool neg = false;
334  if(str[0] == '-') { // check sign
335  neg = true;
336  i++;
337  }
338  else if(str[0] == '+') i++;
339 
340  double num = 0.0;
341  for(;;) {
342  if(str[i] >= '0') if(str[i] <= '9') {
343  num = 10.0*num + double(str[i]-'0');
344  }
345  }*/
346 
347  QRegExp Expr( QRegExp("[^0-9\\x2E\\x2D\\x2B]") );
348  int i = str.find( Expr );
349  if(i >= 0)
350  if((str.at(i).latin1() | 0x20) == 'e') {
351  int j = str.find( Expr , ++i);
352  if(j == i) j--;
353  i = j;
354  }
355 
356  Number = str.left(i).toDouble();
357  Unit = str.mid(i).stripWhiteSpace();
358  if(Unit.length()>0)
359  {
360  switch(Unit.at(0).latin1()) {
361  case 'T': Factor = 1e12; break;
362  case 'G': Factor = 1e9; break;
363  case 'M': Factor = 1e6; break;
364  case 'k': Factor = 1e3; break;
365  case 'c': Factor = 1e-2; break;
366  case 'm': Factor = 1e-3; break;
367  case 'u': Factor = 1e-6; break;
368  case 'n': Factor = 1e-9; break;
369  case 'p': Factor = 1e-12; break;
370  case 'f': Factor = 1e-15; break;
371  // case 'd':
372  default: Factor = 1.0;
373  }
374  }
375  else
376  {
377  Factor = 1.0;
378  }
379 
380  return;
381 }
382 
383 // #########################################################################
384 QString num2str(double Num)
385 {
386  char c = 0;
387  double cal = fabs(Num);
388  if(cal > 1e-20) {
389  cal = log10(cal) / 3.0;
390  if(cal < -0.2) cal -= 0.98;
391  int Expo = int(cal);
392 
393  if(Expo >= -5) if(Expo <= 4)
394  switch(Expo) {
395  case -5: c = 'f'; break;
396  case -4: c = 'p'; break;
397  case -3: c = 'n'; break;
398  case -2: c = 'u'; break;
399  case -1: c = 'm'; break;
400  case 1: c = 'k'; break;
401  case 2: c = 'M'; break;
402  case 3: c = 'G'; break;
403  case 4: c = 'T'; break;
404  }
405 
406  if(c) Num /= pow(10.0, double(3*Expo));
407  }
408 
409  QString Str = QString::number(Num);
410  if(c) Str += c;
411 
412  return Str;
413 }
414 
415 // #########################################################################
416 void convert2Unicode(QString& Text)
417 {
418  bool ok;
419  int i = 0;
420  QString n;
421  unsigned short ch;
422  while((i=Text.find("\\x", i)) >= 0) {
423  n = Text.mid(i, 6);
424  ch = n.mid(2).toUShort(&ok, 16);
425  if(ok) Text.replace(n, QChar(ch));
426  i++;
427  }
428  Text.replace("\\n", "\n");
429  Text.replace("\\\\", "\\");
430 }
431 
432 // #########################################################################
433 void convert2ASCII(QString& Text)
434 {
435  Text.replace('\\', "\\\\");
436  Text.replace('\n', "\\n");
437 
438  int i = 0;
439  QChar ch;
440  char Str[8];
441  while(Text.size()<i) { // convert special characters
442  if(ch > QChar(0x7F)) {
443  sprintf(Str, "\\x%04X", ch.unicode());
444  Text.replace(ch, Str);
445  }
446  }
447 }
448 
449 // #########################################################################
450 // Converts a path to an absolute path and resolves paths relative to the
451 // Qucs home directory
452 QString properAbsFileName(const QString& Name)
453 {
454  QString s = Name;
455  QFileInfo Info(s);
456 
457  if(Info.isRelative())
458  {
459  // if it's a relative file, look for it relative to the
460  // working directory (the qucs home directory)
461  s = QucsSettings.QucsWorkDir.filePath(s);
462  }
463  // return the clean path
464  return QDir::cleanPath(s);
465 }
466 
467 // #########################################################################
468 QString properFileName(const QString& Name)
469 {
470  QFileInfo Info(Name);
471  return Info.fileName();
472 }
473 
474 // #########################################################################
475 // Takes a file name (with path) and replaces all special characters.
476 QString properName(const QString& Name)
477 {
478  QString s = Name;
479  QFileInfo Info(s);
480  if(Info.extension() == "sch")
481  s = s.left(s.length()-4);
482  if(s.at(0) <= '9') if(s.at(0) >= '0')
483  s = 'n' + s;
484  s.replace(QRegExp("\\W"), "_"); // none [a-zA-Z0-9] into "_"
485  s.replace("__", "_"); // '__' not allowed in VHDL
486  if(s.at(0) == '_')
487  s = 'n' + s;
488  return s;
489 }
490 
491 // #########################################################################
492 // Creates and returns delay time for VHDL entities.
493 bool VHDL_Delay(QString& td, const QString& Name)
494 {
495  if(strtod(td.latin1(), 0) != 0.0) { // delay time property
496  if(!VHDL_Time(td, Name))
497  return false; // time has not VHDL format
498  td = " after " + td;
499  return true;
500  }
501  else if(isalpha(td.latin1()[0])) {
502  td = " after " + td;
503  return true;
504  }
505  else {
506  td = "";
507  return true;
508  }
509 }
510 
511 // #########################################################################
512 // Checks and corrects a time (number & unit) according VHDL standard.
513 bool VHDL_Time(QString& t, const QString& Name)
514 {
515  char *p;
516  double Time = strtod(t.latin1(), &p);
517  while(*p == ' ') p++;
518  for(;;) {
519  if(Time >= 0.0) {
520  if(strcmp(p, "fs") == 0) break;
521  if(strcmp(p, "ps") == 0) break;
522  if(strcmp(p, "ns") == 0) break;
523  if(strcmp(p, "us") == 0) break;
524  if(strcmp(p, "ms") == 0) break;
525  if(strcmp(p, "sec") == 0) break;
526  if(strcmp(p, "min") == 0) break;
527  if(strcmp(p, "hr") == 0) break;
528  }
529  t = QString::fromUtf8("§") + QObject::tr("Error: Wrong time format in \"%1\". Use positive number with units").arg(Name)
530  + " fs, ps, ns, us, ms, sec, min, hr.\n";
531  return false;
532  }
533 
534  t = QString::number(Time) + " " + QString(p); // the space is mandatory !
535  return true;
536 }
537 
538 // #########################################################################
539 // Returns parameters for Verilog modules.
540 QString Verilog_Param(const QString Value)
541 {
542  if(strtod(Value.latin1(), 0) != 0.0) {
543  QString td = Value;
544  if(!Verilog_Time(td, "parameter"))
545  return Value;
546  else
547  return td;
548  }
549  else
550  return Value;
551 }
552 
553 // #########################################################################
554 // Creates and returns delay time for Verilog modules.
555 bool Verilog_Delay(QString& td, const QString& Name)
556 {
557  if(strtod(td.latin1(), 0) != 0.0) { // delay time property
558  if(!Verilog_Time(td, Name))
559  return false; // time has not Verilog format
560  td = " #" + td;
561  return true;
562  }
563  else if(isalpha(td.latin1()[0])) {
564  td = " #" + td;
565  return true;
566  }
567  else {
568  td = "";
569  return true;
570  }
571 }
572 
573 // #########################################################################
574 // Checks and corrects a time (number & unit) according Verilog standard.
575 bool Verilog_Time(QString& t, const QString& Name)
576 {
577  char *p;
578  double Time = strtod(t.latin1(), &p);
579  double factor = 1.0;
580  while(*p == ' ') p++;
581  for(;;) {
582  if(Time >= 0.0) {
583  if(strcmp(p, "fs") == 0) { factor = 1e-3; break; }
584  if(strcmp(p, "ps") == 0) { factor = 1; break; }
585  if(strcmp(p, "ns") == 0) { factor = 1e3; break; }
586  if(strcmp(p, "us") == 0) { factor = 1e6; break; }
587  if(strcmp(p, "ms") == 0) { factor = 1e9; break; }
588  if(strcmp(p, "sec") == 0) { factor = 1e12; break; }
589  if(strcmp(p, "min") == 0) { factor = 1e12*60; break; }
590  if(strcmp(p, "hr") == 0) { factor = 1e12*60*60; break; }
591  }
592  t = QString::fromUtf8("§") + QObject::tr("Error: Wrong time format in \"%1\". Use positive number with units").arg(Name)
593  + " fs, ps, ns, us, ms, sec, min, hr.\n";
594  return false;
595  }
596 
597  t = QString::number(Time*factor);
598  return true;
599 }
600 
601 // #########################################################################
602 bool checkVersion(QString& Line)
603 {
604  QStringList sl = QStringList::split('.',PACKAGE_VERSION);
605  QStringList ll = QStringList::split('.',Line);
606  if (ll.count() != 3 || sl.count() != 3)
607  return false;
608  int sv = (int)sl.at(1).toLongLong()*10000+sl.at(2).toLongLong()*100;
609  int lv = (int)ll.at(1).toLongLong()*10000+ll.at(2).toLongLong()*100;
610  if(lv > sv) // wrong version number ? (only backward compatible)
611  return false;
612  return true;
613 }
614 // #########################################################################
615 // ########## ##########
616 // ########## MOVE SOMEWHERE ELSE END ##########
617 // ########## ##########
618 // #########################################################################
619 
620 int doNetlist(QString schematic, QString netlist)
621 {
622  qDebug() << "*** try to load schematic :" << schematic;
623 
624  QFile file(schematic); // save simulator messages
625  if(file.open(QIODevice::ReadOnly)) {
626  file.close();
627  }
628  else {
629  fprintf(stderr, "Error: Could not load schematic %s\n", schematic.ascii());
630  return 1;
631  }
632 
633  // populate Modules list
635 
636  // new schematic from file
637  Schematic *sch = new Schematic(0, schematic);
638 
639  // load schematic file if possible
640  if(!sch->loadDocument()) {
641  fprintf(stderr, "Error: Could not load schematic %s\n", schematic.ascii());
642  delete sch;
643  return 1;
644  }
645 
646  qDebug() << "*** try to write netlist :" << netlist;
647 
648  QStringList Collect;
649 
650  QTextEdit *ErrText = new QTextEdit(); //dummy
651  QFile NetlistFile;
652  QTextStream Stream;
653 
654  Collect.clear(); // clear list for NodeSets, SPICE components etc.
655 
656  NetlistFile.setName(netlist);
657  if(!NetlistFile.open(QIODevice::WriteOnly)) {
658  fprintf(stderr, "Error: Could not load netlist %s\n", netlist.ascii());
659  return -1;
660  }
661 
662  Stream.setDevice(&NetlistFile);
663  int SimPorts = sch->prepareNetlist(Stream, Collect, ErrText);
664 
665  if(SimPorts < -5) {
666  NetlistFile.close();
667  fprintf(stderr, "Error: Could not prepare the netlist...\n");
668  return 1;
669  }
670 
671  // output NodeSets, SPICE simulations etc.
672  for(QStringList::Iterator it = Collect.begin();
673  it != Collect.end(); ++it) {
674  // don't put library includes into netlist...
675  if ((*it).right(4) != ".lst" &&
676  (*it).right(5) != ".vhdl" &&
677  (*it).right(4) != ".vhd" &&
678  (*it).right(2) != ".v") {
679  Stream << *it << '\n';
680  }
681  }
682 
683  Stream << '\n';
684 
685  QString SimTime = sch->createNetlist(Stream, SimPorts);
686 
687  NetlistFile.close();
688 
689  return 0;
690 }
691 
692 
693 // #########################################################################
694 // ########## ##########
695 // ########## Program Start ##########
696 // ########## ##########
697 // #########################################################################
698 int main(int argc, char *argv[])
699 {
700  // apply default settings
701  QucsSettings.font = QFont("Helvetica", 12);
702  QucsSettings.largeFontSize = 16.0;
703  QucsSettings.maxUndo = 20;
704  QucsSettings.NodeWiring = 0;
705 
706  // initially center the application
707  QApplication a(argc, argv);
708  QDesktopWidget *d = a.desktop();
709  int w = d->width();
710  int h = d->height();
711  QucsSettings.x = w/8;
712  QucsSettings.y = h/8;
713  QucsSettings.dx = w*3/4;
714  QucsSettings.dy = h*3/4;
715 
716  // check for relocation env variable
717  char* var = getenv("QUCSDIR");
718  QDir QucsDir;
719  if (var!= NULL)
720  {
721  QucsDir = QDir(QString(var));
722  qDebug() << "QUCSDIR set: " << QucsDir.absolutePath();
723  }
724  else
725  {
726  QString QucsApplicationPath = QCoreApplication::applicationDirPath();
727  #ifdef __APPLE__
728  QucsDir = QDir(QucsApplicationPath.section("/bin",0,0));
729  #else
730  QucsDir = QDir(QucsApplicationPath.replace("/bin",""));
731  #endif
732 
733  }
734 
735  QucsSettings.BinDir = QucsDir.absolutePath() + "/bin/";
736  QucsSettings.LangDir = QucsDir.canonicalPath() + "/share/qucs/lang/";
737  QucsSettings.LibDir = QucsDir.canonicalPath() + "/share/qucs/library/";
738  QucsSettings.OctaveDir = QucsDir.canonicalPath() + "/share/qucs/octave/";
739  QucsSettings.ExamplesDir = QucsDir.canonicalPath() + "/share/qucs/docs/examples/";
740  QucsSettings.DocDir = QucsDir.canonicalPath() + "/share/qucs/docs/";
741 
742  QucsSettings.Editor = "qucs";
743  QucsSettings.QucsHomeDir.setPath(QDir::homeDirPath()+QDir::convertSeparators ("/.qucs"));
744  QucsSettings.QucsWorkDir.setPath(QucsSettings.QucsHomeDir.canonicalPath());
745 
746 
747  var = getenv("ADMSXMLBINDIR");
748  if(var != NULL) {
749  QucsSettings.AdmsXmlBinDir.setPath(QString(var));
750  }
751  else {
752  // default admsXml bindir same as Qucs
753  QString admsExec;
754 #ifdef __MINGW32__
755  admsExec = QDir::toNativeSeparators(QucsSettings.BinDir+"/"+"admsXml.exe");
756 #else
757  admsExec = QDir::toNativeSeparators(QucsSettings.BinDir+"/"+"admsXml");
758 #endif
759  QFile adms(admsExec);
760  if(adms.exists())
761  QucsSettings.AdmsXmlBinDir.setPath(QucsSettings.BinDir);
762  }
763 
764  var = getenv("ASCOBINDIR");
765  if(var != NULL) {
766  QucsSettings.AscoBinDir.setPath(QString(var));
767  }
768  else {
769  // default ASCO bindir same as Qucs
770  QString ascoExec;
771 #ifdef __MINGW32__
772  ascoExec = QDir::toNativeSeparators(QucsSettings.BinDir+"/"+"asco.exe");
773 #else
774  ascoExec = QDir::toNativeSeparators(QucsSettings.BinDir+"/"+"asco");
775 #endif
776  QFile asco(ascoExec);
777  if(asco.exists())
778  QucsSettings.AscoBinDir.setPath(QucsSettings.BinDir);
779  }
780 
781  var = getenv("OCTAVEBINDIR");
782  if(var != NULL) {
783  QucsSettings.OctaveBinDir.setPath(QString(var));
784  }
785  else {
786 #ifdef __MINGW32__
787  QucsSettings.OctaveBinDir.setPath(QString("C:/Software/Octave-3.6.4/bin/"));
788 #else
789  QFile octaveExec("/usr/bin/octave");
790  if(octaveExec.exists())QucsSettings.OctaveBinDir.setPath(QString("/usr/bin/"));
791  QFile octaveExec1("/usr/local/bin/octave");
792  if(octaveExec1.exists()) QucsSettings.OctaveBinDir.setPath(QString("/usr/local/bin/"));
793 #endif
794  }
795  loadSettings();
796 
797  if(!QucsSettings.BGColor.isValid())
798  QucsSettings.BGColor.setRgb(255, 250, 225);
799 
800  // syntax highlighting
801  if(!QucsSettings.Comment.isValid())
802  QucsSettings.Comment = Qt::gray;
803  if(!QucsSettings.String.isValid())
804  QucsSettings.String = Qt::red;
805  if(!QucsSettings.Integer.isValid())
806  QucsSettings.Integer = Qt::blue;
807  if(!QucsSettings.Real.isValid())
808  QucsSettings.Real = Qt::darkMagenta;
809  if(!QucsSettings.Character.isValid())
810  QucsSettings.Character = Qt::magenta;
811  if(!QucsSettings.Type.isValid())
812  QucsSettings.Type = Qt::darkRed;
813  if(!QucsSettings.Attribute.isValid())
814  QucsSettings.Attribute = Qt::darkCyan;
815  if(!QucsSettings.Directive.isValid())
816  QucsSettings.Directive = Qt::darkCyan;
817  if(!QucsSettings.Task.isValid())
818  QucsSettings.Task = Qt::darkRed;
819 
820 
821  a.setFont(QucsSettings.font);
822 
823  // set codecs
824  QTextCodec::setCodecForLocale(QTextCodec::codecForName("UTF-8"));
825  QTextCodec::setCodecForTr(QTextCodec::codecForName("UTF-8"));
826 
827  QTranslator tor( 0 );
828  QString lang = QucsSettings.Language;
829  if(lang.isEmpty())
830  lang = QTextCodec::locale();
831  tor.load( QString("qucs_") + lang, QucsSettings.LangDir);
832  a.installTranslator( &tor );
833 
834  // This seems to be neccessary on a few system to make strtod()
835  // work properly !???!
836  setlocale (LC_NUMERIC, "C");
837 
838  QString schematic;
839  QString netlist;
840 
841  QString operation;
842 
843  // simple command line parser
844  for (int i = 1; i < argc; ++i) {
845  if (!strcmp(argv[i], "-h") || !strcmp(argv[i], "--help")) {
846  fprintf(stdout,
847  "Usage: %s [OPTION]...\n\n"
848  " -h, --help display this help and exit\n"
849  " -v, --version display version information and exit\n"
850  " -n, --netlist convert Qucs schematic into netlist\n"
851  " -i FILENAME use file as input schematic\n"
852  " -o FILENAME use file as output netlist\n"
853  , argv[0]);
854  return 0;
855  }
856  else if (!strcmp(argv[i], "-v") || !strcmp(argv[i], "--version")) {
857  fprintf(stdout, "Qucs " PACKAGE_VERSION "\n");
858  return 0;
859  }
860  else if (!strcmp(argv[i], "-n") || !strcmp(argv[i], "--netlist")) {
861  operation = "netlist";
862  }
863  else if (!strcmp(argv[i], "-i")) {
864  schematic = argv[++i];
865  }
866  else if (!strcmp(argv[i], "-o")) {
867  netlist = argv[++i];
868  }
869  else {
870  fprintf(stderr, "Error: Unknown option: %s\n", argv[i]);
871  return -1;
872  }
873  }
874 
875  // check operation and its required arguments
876  if (operation == "netlist") {
877  if (schematic.isEmpty()) {
878  fprintf(stderr, "Error: Expected input schematic file.\n");
879  return -1;
880  }
881  if (netlist.isEmpty()) {
882  fprintf(stderr, "Error: Expected output netlist file.\n");
883  return -1;
884  }
885  // create netlist from schematic
886  return doNetlist(schematic, netlist);
887  }
888 
889  QucsMain = new QucsApp();
890  a.setMainWidget(QucsMain);
891  qInstallMsgHandler(qucsMessageOutput);
892  QucsMain->show();
893  int result = a.exec();
894  //saveApplSettings(QucsMain);
895  return result;
896 }
QDir AdmsXmlBinDir
Definition: main.h:67
QString OctaveDir
Definition: main.h:60
QDir QucsWorkDir
Definition: main.h:65
void str2num(const QString &s_, double &Number, QString &Unit, double &Factor)
Definition: main.cpp:328
QString LangDir
Definition: main.h:58
QString properFileName(const QString &Name)
Definition: main.cpp:468
bool VHDL_Delay(QString &td, const QString &Name)
Definition: main.cpp:493
QFont font
Definition: main.h:46
QColor Real
Definition: main.h:52
QString Verilog_Param(const QString Value)
Definition: main.cpp:540
tQucsSettings QucsSettings
Definition: main.cpp:52
QColor Directive
Definition: main.h:52
QString complexDeg(double real, double imag, int Precision)
Definition: main.cpp:240
bool checkVersion(QString &Line)
Definition: main.cpp:602
QString StringNum(double num, char form, int Precision)
Definition: main.cpp:263
static void registerModules(void)
Definition: module.cpp:223
void convert2Unicode(QString &Text)
Definition: main.cpp:416
QColor Integer
Definition: main.h:52
int dy
Definition: main.h:45
QColor Type
Definition: main.h:52
QColor String
Definition: main.h:52
QColor Attribute
Definition: main.h:52
QStringList qucsPathList
Definition: main.cpp:56
unsigned int numRecentDocs
Definition: main.h:74
QString BinDir
Definition: main.h:57
bool Verilog_Delay(QString &td, const QString &Name)
Definition: main.cpp:555
QString Language
Definition: main.h:49
Definitions and declarations for the main application.
int doNetlist(QString schematic, QString netlist)
Definition: main.cpp:620
QString ExamplesDir
Definition: main.h:61
QucsApp * QucsMain
Definition: main.cpp:54
QString StringNiceNum(double num)
Definition: main.cpp:293
QDir AscoBinDir
Definition: main.h:68
QColor Comment
Definition: main.h:52
QString properAbsFileName(const QString &Name)
Definition: main.cpp:452
QString complexRad(double real, double imag, int Precision)
Definition: main.cpp:251
QString lastDir
Definition: main.cpp:55
QString createNetlist(QTextStream &, int)
unsigned int NodeWiring
Definition: main.h:64
QString num2str(double Num)
Definition: main.cpp:384
bool Verilog_Time(QString &t, const QString &Name)
Definition: main.cpp:575
bool VHDL_Time(QString &t, const QString &Name)
Definition: main.cpp:513
bool saveApplSettings(QucsApp *qucs)
Definition: main.cpp:127
QString complexRect(double real, double imag, int Precision)
Definition: main.cpp:224
QString DocDir
Definition: main.h:62
Definition: element.h:82
Definition: element.h:48
bool IgnoreFutureVersion
Definition: main.h:77
QStringList RecentDocs
Definition: main.h:75
QDir QucsHomeDir
Definition: main.h:66
void qucsMessageOutput(QtMsgType type, const char *msg)
qucsMessageOutput handles qDebug, qWarning, qCritical, qFatal.
Definition: main.cpp:193
void convert2ASCII(QString &Text)
Definition: main.cpp:433
int y
Definition: main.h:45
QColor Task
Definition: main.h:52
QColor Character
Definition: main.h:52
QString Editor
Definition: main.h:56
int prepareNetlist(QTextStream &, QStringList &, QTextEdit *)
QDir OctaveBinDir
Definition: main.h:69
float largeFontSize
Definition: main.h:47
unsigned int maxUndo
Definition: main.h:55
QString properName(const QString &Name)
Definition: main.cpp:476
Definition: qucs.h:61
#define M_PI
Definition: diagramdialog.h:25
bool loadSettings()
Definition: main.cpp:60
int main(int argc, char *argv[])
Definition: main.cpp:698
int dx
Definition: main.h:45
bool loadDocument()
QColor BGColor
Definition: main.h:48
QString LibDir
Definition: main.h:59
QStringList FileTypes
Definition: main.h:72
int x
Definition: main.h:45