Qucs-GUI  0.0.19
/home/travis/build/Qucs/qucs/qucs/qucs/main.cpp
Go to the documentation of this file.
00001 /***************************************************************************
00002                                  main.cpp
00003                                 ----------
00004     begin                : Thu Aug 28 2003
00005     copyright            : (C) 2003 by Michael Margraf
00006     email                : michael.margraf@alumni.tu-berlin.de
00007  ***************************************************************************/
00008 
00009 /***************************************************************************
00010  *                                                                         *
00011  *   This program is free software; you can redistribute it and/or modify  *
00012  *   it under the terms of the GNU General Public License as published by  *
00013  *   the Free Software Foundation; either version 2 of the License, or     *
00014  *   (at your option) any later version.                                   *
00015  *                                                                         *
00016  ***************************************************************************/
00022 #ifdef HAVE_CONFIG_H
00023 # include <config.h>
00024 #endif
00025 
00026 #include <stdlib.h>
00027 #include <ctype.h>
00028 #include <locale.h>
00029 
00030 #include <QApplication>
00031 #include <QString>
00032 #include <QStringList>
00033 #include <QTextCodec>
00034 #include <QTranslator>
00035 #include <QFile>
00036 #include <QMessageBox>
00037 #include <QRegExp>
00038 #include <QtSvg>
00039 
00040 #include "qucs.h"
00041 #include "main.h"
00042 #include "node.h"
00043 #include "printerwriter.h"
00044 #include "imagewriter.h"
00045 
00046 #include "schematic.h"
00047 #include "module.h"
00048 
00049 #include "components/components.h"
00050 
00051 #ifdef _WIN32
00052 #include <Windows.h>  //for OutputDebugString
00053 #endif
00054 
00055 #ifdef __MINGW32__
00056 #define executableSuffix ".exe"
00057 #else
00058 #define executableSuffix ""
00059 #endif
00060 
00061 tQucsSettings QucsSettings;
00062 
00063 QucsApp *QucsMain = 0;  // the Qucs application itself
00064 QString lastDir;    // to remember last directory for several dialogs
00065 QStringList qucsPathList;
00066 
00067 // #########################################################################
00068 // Loads the settings file and stores the settings.
00069 bool loadSettings()
00070 {
00071     QSettings settings("qucs","qucs");
00072 
00073     if(settings.contains("x"))QucsSettings.x=settings.value("x").toInt();
00074     if(settings.contains("y"))QucsSettings.y=settings.value("y").toInt();
00075     if(settings.contains("dx"))QucsSettings.dx=settings.value("dx").toInt();
00076     if(settings.contains("dy"))QucsSettings.dy=settings.value("dy").toInt();
00077     if(settings.contains("font"))QucsSettings.font.fromString(settings.value("font").toString());
00078     if(settings.contains("LargeFontSize"))QucsSettings.largeFontSize=settings.value("LargeFontSize").toDouble(); // use toDouble() as it can interpret the string according to the current locale
00079     if(settings.contains("maxUndo"))QucsSettings.maxUndo=settings.value("maxUndo").toInt();
00080     if(settings.contains("NodeWiring"))QucsSettings.NodeWiring=settings.value("NodeWiring").toInt();
00081     if(settings.contains("BGColor"))QucsSettings.BGColor.setNamedColor(settings.value("BGColor").toString());
00082     if(settings.contains("Editor"))QucsSettings.Editor=settings.value("Editor").toString();
00083     if(settings.contains("FileTypes"))QucsSettings.FileTypes=settings.value("FileTypes").toStringList();
00084     if(settings.contains("Language"))QucsSettings.Language=settings.value("Language").toString();
00085     if(settings.contains("Comment"))QucsSettings.Comment.setNamedColor(settings.value("Comment").toString());
00086     if(settings.contains("String"))QucsSettings.String.setNamedColor(settings.value("String").toString());
00087     if(settings.contains("Integer"))QucsSettings.Integer.setNamedColor(settings.value("Integer").toString());
00088     if(settings.contains("Real"))QucsSettings.Real.setNamedColor(settings.value("Real").toString());
00089     if(settings.contains("Character"))QucsSettings.Character.setNamedColor(settings.value("Character").toString());
00090     if(settings.contains("Type"))QucsSettings.Type.setNamedColor(settings.value("Type").toString());
00091     if(settings.contains("Attribute"))QucsSettings.Attribute.setNamedColor(settings.value("Attribute").toString());
00092     if(settings.contains("Directive"))QucsSettings.Directive.setNamedColor(settings.value("Directive").toString());
00093     if(settings.contains("Task"))QucsSettings.Comment.setNamedColor(settings.value("Task").toString());
00094 
00095     if(settings.contains("Qucsator"))QucsSettings.Qucsator = settings.value("Qucsator").toString();
00096     //if(settings.contains("BinDir"))QucsSettings.BinDir = settings.value("BinDir").toString();
00097     //if(settings.contains("LangDir"))QucsSettings.LangDir = settings.value("LangDir").toString();
00098     //if(settings.contains("LibDir"))QucsSettings.LibDir = settings.value("LibDir").toString();
00099     if(settings.contains("AdmsXmlBinDir"))QucsSettings.AdmsXmlBinDir = settings.value("AdmsXmlBinDir").toString();
00100     if(settings.contains("AscoBinDir"))QucsSettings.AscoBinDir = settings.value("AscoBinDir").toString();
00101     //if(settings.contains("OctaveDir"))QucsSettings.OctaveDir = settings.value("OctaveDir").toString();
00102     //if(settings.contains("ExamplesDir"))QucsSettings.ExamplesDir = settings.value("ExamplesDir").toString();
00103     //if(settings.contains("DocDir"))QucsSettings.DocDir = settings.value("DocDir").toString();
00104     if(settings.contains("OctaveBinDir"))QucsSettings.OctaveBinDir.setPath(settings.value("OctaveBinDir").toString());
00105     if(settings.contains("QucsHomeDir"))
00106       if(settings.value("QucsHomeDir").toString() != "")
00107          QucsSettings.QucsHomeDir.setPath(settings.value("QucsHomeDir").toString());
00108     QucsSettings.QucsWorkDir = QucsSettings.QucsHomeDir;
00109 
00110     if (settings.contains("IgnoreVersion")) QucsSettings.IgnoreFutureVersion = settings.value("IgnoreVersion").toBool();
00111     // check also for old setting name with typo...
00112     else if (settings.contains("IngnoreVersion")) QucsSettings.IgnoreFutureVersion = settings.value("IngnoreVersion").toBool();
00113     else QucsSettings.IgnoreFutureVersion = false;
00114 
00115     if (settings.contains("GraphAntiAliasing")) QucsSettings.GraphAntiAliasing = settings.value("GraphAntiAliasing").toBool();
00116     else QucsSettings.GraphAntiAliasing = false;
00117 
00118     if (settings.contains("TextAntiAliasing")) QucsSettings.TextAntiAliasing = settings.value("TextAntiAliasing").toBool();
00119     else QucsSettings.TextAntiAliasing = false;
00120 
00121     QucsSettings.RecentDocs = settings.value("RecentDocs").toString().split("*",QString::SkipEmptyParts);
00122     QucsSettings.numRecentDocs = QucsSettings.RecentDocs.count();
00123 
00124 
00125     QucsSettings.spiceExtensions << "*.sp" << "*.cir" << "*.spc" << "*.spi";
00126 
00127     // If present read in the list of directory paths in which Qucs should
00128     // search for subcircuit schematics
00129     int npaths = settings.beginReadArray("Paths");
00130     for (int i = 0; i < npaths; ++i)
00131     {
00132         settings.setArrayIndex(i);
00133         QString apath = settings.value("path").toString();
00134         qucsPathList.append(apath);
00135     }
00136     settings.endArray();
00137 
00138     QucsSettings.numRecentDocs = 0;
00139 
00140     return true;
00141 }
00142 
00143 // #########################################################################
00144 // Saves the settings in the settings file.
00145 bool saveApplSettings()
00146 {
00147     QSettings settings ("qucs","qucs");
00148 
00149     settings.setValue("x", QucsSettings.x);
00150     settings.setValue("y", QucsSettings.y);
00151     settings.setValue("dx", QucsSettings.dx);
00152     settings.setValue("dy", QucsSettings.dy);
00153     settings.setValue("font", QucsSettings.font.toString());
00154     // store LargeFontSize as a string, so it will be also human-readable in the settings file (will be a @Variant() otherwise)
00155     settings.setValue("LargeFontSize", QString::number(QucsSettings.largeFontSize));
00156     settings.setValue("maxUndo", QucsSettings.maxUndo);
00157     settings.setValue("NodeWiring", QucsSettings.NodeWiring);
00158     settings.setValue("BGColor", QucsSettings.BGColor.name());
00159     settings.setValue("Editor", QucsSettings.Editor);
00160     settings.setValue("FileTypes", QucsSettings.FileTypes);
00161     settings.setValue("Language", QucsSettings.Language);
00162     settings.setValue("Comment", QucsSettings.Comment.name());
00163     settings.setValue("String", QucsSettings.String.name());
00164     settings.setValue("Integer", QucsSettings.Integer.name());
00165     settings.setValue("Real", QucsSettings.Real.name());
00166     settings.setValue("Character", QucsSettings.Character.name());
00167     settings.setValue("Type", QucsSettings.Type.name());
00168     settings.setValue("Attribute", QucsSettings.Attribute.name());
00169     settings.setValue("Directive", QucsSettings.Directive.name());
00170     settings.setValue("Task", QucsSettings.Comment.name());
00171     //settings.setValue("Qucsator", QucsSettings.Qucsator);
00172     //settings.setValue("BinDir", QucsSettings.BinDir);
00173     //settings.setValue("LangDir", QucsSettings.LangDir);
00174     //settings.setValue("LibDir", QucsSettings.LibDir);
00175     settings.setValue("AdmsXmlBinDir", QucsSettings.AdmsXmlBinDir.canonicalPath());
00176     settings.setValue("AscoBinDir", QucsSettings.AscoBinDir.canonicalPath());
00177     //settings.setValue("OctaveDir", QucsSettings.OctaveDir);
00178     //settings.setValue("ExamplesDir", QucsSettings.ExamplesDir);
00179     //settings.setValue("DocDir", QucsSettings.DocDir);
00180     settings.setValue("OctaveBinDir", QucsSettings.OctaveBinDir.canonicalPath());
00181     settings.setValue("QucsHomeDir", QucsSettings.QucsHomeDir.canonicalPath());
00182     settings.setValue("IgnoreVersion", QucsSettings.IgnoreFutureVersion);
00183     settings.setValue("GraphAntiAliasing", QucsSettings.GraphAntiAliasing);
00184     settings.setValue("TextAntiAliasing", QucsSettings.TextAntiAliasing);
00185 
00186     // Copy the list of directory paths in which Qucs should
00187     // search for subcircuit schematics from qucsPathList
00188     settings.remove("Paths");
00189     settings.beginWriteArray("Paths");
00190     int i = 0;
00191     foreach(QString path, qucsPathList) {
00192          settings.setArrayIndex(i);
00193          settings.setValue("path", path);
00194          i++;
00195      }
00196      settings.endArray();
00197 
00198   return true;
00199 
00200 }
00201 
00214 void qucsMessageOutput(QtMsgType type, const char *msg)
00215 {
00216   switch (type) {
00217   case QtDebugMsg:
00218     fprintf(stderr, "Debug: %s\n", msg);
00219     break;
00220   case QtWarningMsg:
00221     fprintf(stderr, "Warning: %s\n", msg);
00222     break;
00223   case QtCriticalMsg:
00224     fprintf(stderr, "Critical: %s\n", msg);
00225     break;
00226   case QtFatalMsg:
00227     fprintf(stderr, "Fatal: %s\n", msg);
00228     abort();
00229   }
00230 
00231 #ifdef _WIN32
00232   OutputDebugStringA(msg);
00233 #endif
00234 }
00235 
00236 Schematic *openSchematic(QString schematic)
00237 {
00238   qDebug() << "*** try to load schematic :" << schematic;
00239 
00240   QFile file(schematic);  // save simulator messages
00241   if(file.open(QIODevice::ReadOnly)) {
00242     file.close();
00243   }
00244   else {
00245     fprintf(stderr, "Error: Could not load schematic %s\n", schematic.ascii());
00246     return NULL;
00247   }
00248 
00249   // populate Modules list
00250   Module::registerModules ();
00251 
00252   // new schematic from file
00253   Schematic *sch = new Schematic(0, schematic);
00254 
00255   // load schematic file if possible
00256   if(!sch->loadDocument()) {
00257     fprintf(stderr, "Error: Could not load schematic %s\n", schematic.ascii());
00258     delete sch;
00259     return NULL;
00260   }
00261   return sch;
00262 }
00263 
00264 int doNetlist(QString schematic, QString netlist)
00265 {
00266   Schematic *sch = openSchematic(schematic);
00267   if (sch == NULL) {
00268     return 1;
00269   }
00270 
00271   qDebug() << "*** try to write netlist  :" << netlist;
00272 
00273   QStringList Collect;
00274 
00275   QPlainTextEdit *ErrText = new QPlainTextEdit();  //dummy
00276   QFile NetlistFile;
00277   QTextStream   Stream;
00278 
00279   Collect.clear();  // clear list for NodeSets, SPICE components etc.
00280 
00281   NetlistFile.setFileName(netlist);
00282   if(!NetlistFile.open(QIODevice::WriteOnly)) {
00283     fprintf(stderr, "Error: Could not load netlist %s\n", netlist.ascii());
00284     return -1;
00285   }
00286 
00287   Stream.setDevice(&NetlistFile);
00288   int SimPorts = sch->prepareNetlist(Stream, Collect, ErrText);
00289 
00290   if(SimPorts < -5) {
00291     NetlistFile.close();
00292     fprintf(stderr, "Error: Could not prepare the netlist...\n");
00294     qCritical() << ErrText->toPlainText();
00295     return 1;
00296   }
00297 
00298   // output NodeSets, SPICE simulations etc.
00299   for(QStringList::Iterator it = Collect.begin();
00300   it != Collect.end(); ++it) {
00301     // don't put library includes into netlist...
00302     if ((*it).right(4) != ".lst" &&
00303     (*it).right(5) != ".vhdl" &&
00304     (*it).right(4) != ".vhd" &&
00305     (*it).right(2) != ".v") {
00306       Stream << *it << '\n';
00307     }
00308   }
00309 
00310   Stream << '\n';
00311 
00312   QString SimTime = sch->createNetlist(Stream, SimPorts);
00313   delete(sch);
00314 
00315   NetlistFile.close();
00316 
00317   return 0;
00318 }
00319 
00320 int doPrint(QString schematic, QString printFile,
00321     QString page, int dpi, QString color, QString orientation)
00322 {
00323   Schematic *sch = openSchematic(schematic);
00324   if (sch == NULL) {
00325     return 1;
00326   }
00327 
00328   sch->Nodes = &(sch->DocNodes);
00329   sch->Wires = &(sch->DocWires);
00330   sch->Diagrams = &(sch->DocDiags);
00331   sch->Paintings = &(sch->DocPaints);
00332   sch->Components = &(sch->DocComps);
00333   sch->reloadGraphs();
00334 
00335   qDebug() << "*** try to print file  :" << printFile;
00336 
00337   // determine filetype
00338   if (printFile.endsWith(".pdf")) {
00339     //initial printer
00340     PrinterWriter *Printer = new PrinterWriter();
00341     Printer->setFitToPage(true);
00342     Printer->noGuiPrint(sch, printFile, page, dpi, color, orientation);
00343   } else {
00344     ImageWriter *Printer = new ImageWriter("");
00345     Printer->noGuiPrint(sch, printFile, color);
00346   }
00347   return 0;
00348 }
00349 
00353 void createIcons() {
00354 
00355   int nCats = 0, nComps = 0;
00356 
00357   if(!QDir("./bitmaps_generated").exists()){
00358     QDir().mkdir("bitmaps_generated");
00359   }
00360   Module::registerModules ();
00361   QStringList cats = Category::getCategories ();
00362 
00363   foreach(QString category, cats) {
00364 
00365     QList<Module *> Comps;
00366     Comps = Category::getModules(category);
00367 
00368     // crash with diagrams, skip
00369     if(category == "diagrams") break;
00370 
00371     char * File;
00372     QString Name;
00373 
00374     foreach (Module *Mod, Comps) {
00375       if (Mod->info) {
00376 
00377         Element *e = (Mod->info) (Name, File, true);
00378 
00379         Component *c = (Component* ) e;
00380 
00381         QList<Line *> Lines      = c->Lines;
00382         QList<struct Arc *> Arcs = c-> Arcs;
00383         QList<Area *> Rects      = c-> Rects;
00384         QList<Area *> Ellips     = c-> Ellips;
00385         QList<Port *> Ports      = c->Ports;
00386         QList<Text*> Texts       = c->Texts;
00387 
00388         QGraphicsScene *scene = new QGraphicsScene();
00389 
00390         foreach (Line *l, Lines) {
00391           scene->addLine(l->x1, l->y1, l->x2, l->y2, l->style);
00392         }
00393 
00394         foreach(struct Arc *a, Arcs) {
00395           // we need an open item here; QGraphisEllipseItem draws a filled ellipse and doesn't do the job here...
00396           QPainterPath *path = new QPainterPath();
00397           // the components do not contain the angles in degrees but in 1/16th degrees -> conversion needed
00398           path->arcMoveTo(a->x,a->y,a->w,a->h,a->angle/16);
00399           path->arcTo(a->x,a->y,a->w,a->h,a->angle/16,a->arclen/16);
00400           scene->addPath(*path);
00401         }
00402 
00403         foreach(Area *a, Rects) {
00404           scene->addRect(a->x, a->y, a->w, a->h, a->Pen, a->Brush);
00405         }
00406 
00407         foreach(Area *a, Ellips) {
00408           scene->addEllipse(a->x, a->y, a->w, a->h, a->Pen, a->Brush);
00409         }
00410 
00411         foreach(Port *p, Ports) {
00412           scene->addEllipse(p->x-4, p->y-4, 8, 8, QPen(Qt::red));
00413         }
00414 
00415         foreach(Text *t, Texts) {
00416           QFont myFont;
00417           myFont.setPointSize(10);
00418           QGraphicsTextItem* item  = new QGraphicsTextItem(t->s);
00419           item->setX(t->x);
00420           item->setY(t->y);
00421           item->setFont(myFont);
00422 
00423           scene->addItem(item);
00424         }
00425 
00426         // this uses the size of the component as icon size
00427         // Qt bug ? The returned sceneRect() is often 1 px short on bottom
00428         //   and right sides without anti-aliasing. 1 px more missing on top
00429         //   and left when anti-aliasing is used
00430         QRectF rScene = scene->sceneRect().adjusted(-1,-1,1,1);
00431         // image and scene need to be the same size, since render()
00432         //   will fill the entire image, otherwise the scaling will
00433         //   introduce artifacts
00434         QSize sImage = rScene.size().toSize(); // rounding seems not to be an issue
00435         // ARGB32_Premultiplied is faster (Qt docs)
00436         //QImage image(sImage.toSize(), QImage::Format_ARGB32);
00437         QImage image(sImage, QImage::Format_ARGB32_Premultiplied);
00438         // this uses a fixed size for the icon (32 x 32)
00439         //QImage image(32, 32, QImage::Format_ARGB32);
00440         image.fill(Qt::transparent);
00441 
00442         QPainter painter(&image);
00443         QPainter::RenderHints hints = 0;
00444         // Ask to antialias drawings if requested
00445         if (QucsSettings.GraphAntiAliasing) hints |= QPainter::Antialiasing;
00446         // Ask to antialias text if requested
00447         if (QucsSettings.TextAntiAliasing) hints |= QPainter::TextAntialiasing;
00448         painter.setRenderHints(hints);
00449 
00450         // pass target and source size eplicitly, otherwise sceneRect() is used
00451         //   for the source size, which is often wrong (see comment above)
00452         scene->render(&painter, image.rect(), rScene);
00453 
00454         image.save("./bitmaps_generated/" + QString(File) + ".png");
00455 
00456         fprintf(stdout, "[%s] %s\n", category.toAscii().data(), File);
00457       }
00458       nComps++;
00459     } // module
00460     nCats++;
00461   } // category
00462   fprintf(stdout, "Created %i component icons from %i categories\n", nComps, nCats);
00463 }
00464 
00474 void createDocData() {
00475 
00476   QMap<int, QString> typeMap;
00477   typeMap.insert(0x30000, "Component");
00478   typeMap.insert(0x30002, "ComponentText");
00479   typeMap.insert(0x10000, "AnalogComponent");
00480   typeMap.insert(0x20000, "DigitalComponent") ;
00481 
00482   Module::registerModules ();
00483   QStringList cats = Category::getCategories ();
00484   int nCats = cats.size();
00485 
00486   QStringList catHeader;
00487   catHeader << "# Note: auto-generated file (changes will be lost on update)";
00488   QFile file("categories.txt");
00489   if (!file.open(QFile::WriteOnly | QFile::Text)) return;
00490   QTextStream out(&file);
00491   out << cats.join("\n");
00492   file.close();
00493 
00494   int nComps = 0;
00495 
00496   // table for quick reference, schematic and netlist entry
00497   foreach(QString category, cats) {
00498 
00499     QList<Module *> Comps;
00500     Comps = Category::getModules(category);
00501 
00502     // \fixme, crash with diagrams, skip
00503     if(category == "diagrams") break;
00504 
00505     // one dir per category
00506     QString curDir = "./"+category+"/";
00507     qDebug() << "Creating dir:" << curDir;
00508     if(!QDir(curDir).exists()){
00509         QDir().mkdir(curDir);
00510     }
00511 
00512     char * File;
00513     QString Name;
00514 
00515     int num = 0; // compoment id inside category
00516 
00517     foreach (Module *Mod, Comps) {
00518         num += 1;
00519 
00520         nComps += 1;
00521 
00522         Element *e = (Mod->info) (Name, File, true);
00523         Component *c = (Component* ) e;
00524 
00525         // object info
00526         QStringList compData;
00527 
00528         compData << "# Note: auto-generated file (changes will be lost on update)";
00529         compData << "Caption; "           + Name;
00530         compData << "Description; "       + c->Description;
00531         compData << "Identifier; ``"      + c->Model + "``"; // backticks for reST verbatim
00532         compData << "Default name; ``"    + c->Name  + "``";
00533         compData << "Type; "              + typeMap.value(c->Type);
00534         compData << "Bitmap file; "       + QString(File);
00535         compData << "Properties; "        + QString::number(c->Props.count());
00536         compData << "Category; "          + category;
00537 
00538         // 001_data.csv - CSV file with component data
00539         QString ID = QString("%1").arg(num,3,'d',0,'0');
00540         QString objDataFile;
00541         objDataFile = QString("%1_data.csv").arg( ID  ) ;
00542 
00543         QFile file(curDir + objDataFile);
00544         if (!file.open(QFile::WriteOnly | QFile::Text)) return;
00545         QTextStream out(&file);
00546         out << compData.join("\n");
00547         file.close();
00548         fprintf(stdout, "[%s] %s %s \n", category.toAscii().data(), c->Model.toAscii().data(), file.name().toAscii().data());
00549 
00550         QStringList compProps;
00551         compProps << "# Note: auto-generated file (changes will be lost on update)";
00552         compProps << QString("# %1; %2; %3; %4").arg(  "Name", "Value", "Display", "Description");
00553         foreach(Property *prop, c->Props) {
00554           compProps << QString("%1; \"%2\"; %3; \"%4\"").arg(
00555                          prop->Name,
00556                          prop->Value,
00557                          prop->display?"yes":"no",
00558                          prop->Description.replace("\"","\"\"")); // escape quote in quote
00559         }
00560 
00561         // 001_props.csv - CSV file with component properties
00562         QString objPropFile = QString("%1_prop.csv").arg( ID ) ;
00563 
00564         QFile fileProps(curDir + objPropFile );
00565         if (!fileProps.open(QFile::WriteOnly | QFile::Text)) return;
00566         QTextStream outProps(&fileProps);
00567         outProps << compProps.join("\n");
00568         compProps.clear();
00569         file.close();
00570         fprintf(stdout, "[%s] %s %s \n", category.toAscii().data(), c->Model.toAscii().data(), fileProps.name().toAscii().data());
00571     } // module
00572   } // category
00573   fprintf(stdout, "Created data for %i components from %i categories\n", nComps, nCats);
00574 }
00575 
00583 void createListComponentEntry(){
00584 
00585   Module::registerModules ();
00586   QStringList cats = Category::getCategories ();
00587   // table for quick reference, schematic and netlist entry
00588   foreach(QString category, cats) {
00589 
00590     QList<Module *> Comps;
00591     Comps = Category::getModules(category);
00592 
00593     // \fixme, crash with diagrams, skip
00594     if(category == "diagrams") break;
00595 
00596     char * File;
00597     QString Name;
00598 
00599     foreach (Module *Mod, Comps) {
00600       Element *e = (Mod->info) (Name, File, true);
00601       Component *c = (Component* ) e;
00602 
00603       QString qucsEntry = c->save();
00604       fprintf(stdout, "%s; qucs    ; %s\n", c->Model.toAscii().data(), qucsEntry.toAscii().data());
00605 
00606       // add dummy ports/wires, avoid segfault
00607       int port = 0;
00608       foreach (Port *p, c->Ports) {
00609         Node *n = new Node(0,0);
00610         n->Name="_net"+QString::number(port);
00611         p->Connection = n;
00612         port +=1;
00613       }
00614 
00615       // skip Subcircuit, segfault, there is nothing to netlist
00616       if (c->Model == "Sub" or c->Model == ".Opt") {
00617         fprintf(stdout, "WARNING, qucsator netlist not generated for %s\n\n", c->Model.toAscii().data());
00618         continue;
00619       }
00620 
00621       QString qucsatorEntry = c->getNetlist();
00622       fprintf(stdout, "%s; qucsator; %s\n", c->Model.toAscii().data(), qucsatorEntry.toAscii().data());
00623       } // module
00624     } // category
00625 }
00626 
00627 // #########################################################################
00628 // ##########                                                     ##########
00629 // ##########                  Program Start                      ##########
00630 // ##########                                                     ##########
00631 // #########################################################################
00632 int main(int argc, char *argv[])
00633 {
00634   qInstallMsgHandler(qucsMessageOutput);
00635   // apply default settings
00636   QucsSettings.font = QFont("Helvetica", 12);
00637   QucsSettings.largeFontSize = 16.0;
00638   QucsSettings.maxUndo = 20;
00639   QucsSettings.NodeWiring = 0;
00640 
00641   // initially center the application
00642   QApplication a(argc, argv);
00643   QDesktopWidget *d = a.desktop();
00644   int w = d->width();
00645   int h = d->height();
00646   QucsSettings.x = w/8;
00647   QucsSettings.y = h/8;
00648   QucsSettings.dx = w*3/4;
00649   QucsSettings.dy = h*3/4;
00650 
00651   // check for relocation env variable
00652   char* var = getenv("QUCSDIR");
00653   QDir QucsDir;
00654   if (var!= NULL)
00655   {
00656       QucsDir = QDir(QString(var));
00657       qDebug() << "QUCSDIR set: " << QucsDir.absolutePath();
00658   }
00659   else
00660   {
00661      QString QucsApplicationPath = QCoreApplication::applicationDirPath();
00662      #ifdef __APPLE__
00663      QucsDir = QDir(QucsApplicationPath.section("/bin",0,0));
00664      #else
00665      QucsDir = QDir(QucsApplicationPath);
00666      QucsDir.cdUp();
00667      #endif
00668 
00669   }
00670 
00671   QucsSettings.BinDir =      QucsDir.absolutePath() + "/bin/";
00672   QucsSettings.LangDir =     QucsDir.canonicalPath() + "/share/qucs/lang/";
00673   QucsSettings.LibDir =      QucsDir.canonicalPath() + "/share/qucs/library/";
00674   QucsSettings.OctaveDir =   QucsDir.canonicalPath() + "/share/qucs/octave/";
00675   QucsSettings.ExamplesDir = QucsDir.canonicalPath() + "/share/qucs/docs/examples/";
00676   QucsSettings.DocDir =      QucsDir.canonicalPath() + "/share/qucs/docs/";
00677 
00678   QucsSettings.Editor = "qucs";
00679   QucsSettings.QucsHomeDir.setPath(QDir::homeDirPath()+QDir::convertSeparators ("/.qucs"));
00680   QucsSettings.QucsWorkDir.setPath(QucsSettings.QucsHomeDir.canonicalPath());
00681 
00683   var = getenv("QUCSATOR");
00684   if(var != NULL) {
00685       QucsSettings.Qucsator = QString(var);
00686   }
00687   else {
00688       QucsSettings.Qucsator = QucsSettings.BinDir + "qucsator" + executableSuffix;
00689   }
00690 
00691   var = getenv("QUCSCONV");
00692   if(var != NULL) {
00693       QucsSettings.Qucsconv = QString(var);
00694   }
00695   else {
00696       QucsSettings.Qucsconv = QucsSettings.BinDir + "qucsconv" + executableSuffix;
00697   }
00698   QFile file(QucsSettings.Qucsconv);
00699   if(!file.exists())
00700       qWarning() << "QucsConv not found: " << QucsSettings.Qucsconv;
00701 
00702 
00703   var = getenv("ADMSXMLBINDIR");
00704   if(var != NULL) {
00705       QucsSettings.AdmsXmlBinDir.setPath(QString(var));
00706   }
00707   else {
00708       // default admsXml bindir same as Qucs
00709       QString admsExec;
00710 #ifdef __MINGW32__
00711       admsExec = QDir::toNativeSeparators(QucsSettings.BinDir+"/"+"admsXml.exe");
00712 #else
00713       admsExec = QDir::toNativeSeparators(QucsSettings.BinDir+"/"+"admsXml");
00714 #endif
00715       QFile adms(admsExec);
00716       if(adms.exists())
00717         QucsSettings.AdmsXmlBinDir.setPath(QucsSettings.BinDir);
00718   }
00719 
00720   var = getenv("ASCOBINDIR");
00721   if(var != NULL)  {
00722       QucsSettings.AscoBinDir.setPath(QString(var));
00723   }
00724   else  {
00725       // default ASCO bindir same as Qucs
00726       QString ascoExec;
00727 #ifdef __MINGW32__
00728       ascoExec = QDir::toNativeSeparators(QucsSettings.BinDir+"/"+"asco.exe");
00729 #else
00730       ascoExec = QDir::toNativeSeparators(QucsSettings.BinDir+"/"+"asco");
00731 #endif
00732       QFile asco(ascoExec);
00733       if(asco.exists())
00734         QucsSettings.AscoBinDir.setPath(QucsSettings.BinDir);
00735   }
00736 
00737   var = getenv("OCTAVEBINDIR");
00738   if(var != NULL)  {
00739       QucsSettings.OctaveBinDir.setPath(QString(var));
00740   }
00741   else  {
00742 #ifdef __MINGW32__
00743       QucsSettings.OctaveBinDir.setPath(QString("C:/Software/Octave-3.6.4/bin/"));
00744 #else
00745       QFile octaveExec("/usr/bin/octave");
00746       if(octaveExec.exists())QucsSettings.OctaveBinDir.setPath(QString("/usr/bin/"));
00747       QFile octaveExec1("/usr/local/bin/octave");
00748       if(octaveExec1.exists()) QucsSettings.OctaveBinDir.setPath(QString("/usr/local/bin/"));
00749 #endif
00750   }
00751   loadSettings();
00752 
00753   if(!QucsSettings.BGColor.isValid())
00754     QucsSettings.BGColor.setRgb(255, 250, 225);
00755 
00756   // syntax highlighting
00757   if(!QucsSettings.Comment.isValid())
00758     QucsSettings.Comment = Qt::gray;
00759   if(!QucsSettings.String.isValid())
00760     QucsSettings.String = Qt::red;
00761   if(!QucsSettings.Integer.isValid())
00762     QucsSettings.Integer = Qt::blue;
00763   if(!QucsSettings.Real.isValid())
00764     QucsSettings.Real = Qt::darkMagenta;
00765   if(!QucsSettings.Character.isValid())
00766     QucsSettings.Character = Qt::magenta;
00767   if(!QucsSettings.Type.isValid())
00768     QucsSettings.Type = Qt::darkRed;
00769   if(!QucsSettings.Attribute.isValid())
00770     QucsSettings.Attribute = Qt::darkCyan;
00771   if(!QucsSettings.Directive.isValid())
00772     QucsSettings.Directive = Qt::darkCyan;
00773   if(!QucsSettings.Task.isValid())
00774     QucsSettings.Task = Qt::darkRed;
00775 
00776 
00777   a.setFont(QucsSettings.font);
00778 
00779   // set codecs
00780   QTextCodec::setCodecForLocale(QTextCodec::codecForName("UTF-8"));
00781   QTextCodec::setCodecForTr(QTextCodec::codecForName("UTF-8"));
00782 
00783   QTranslator tor( 0 );
00784   QString lang = QucsSettings.Language;
00785   if(lang.isEmpty())
00786     lang = QTextCodec::locale();
00787   tor.load( QString("qucs_") + lang, QucsSettings.LangDir);
00788   a.installTranslator( &tor );
00789 
00790   // This seems to be neccessary on a few system to make strtod()
00791   // work properly !???!
00792   setlocale (LC_NUMERIC, "C");
00793 
00794   QString inputfile;
00795   QString outputfile;
00796 
00797   bool netlist_flag = false;
00798   bool print_flag = false;
00799   QString page = "A4";
00800   int dpi = 96;
00801   QString color = "RGB";
00802   QString orientation = "portraid";
00803 
00804   // simple command line parser
00805   for (int i = 1; i < argc; ++i) {
00806     if (!strcmp(argv[i], "-h") || !strcmp(argv[i], "--help")) {
00807       fprintf(stdout,
00808   "Usage: %s [-hv] \n"
00809   "       qucs -n -i FILENAME -o FILENAME\n"
00810   "       qucs -p -i FILENAME -o FILENAME.[pdf|png|svg|eps] \n\n"
00811   "  -h, --help     display this help and exit\n"
00812   "  -v, --version  display version information and exit\n"
00813   "  -n, --netlist  convert Qucs schematic into netlist\n"
00814   "  -p, --print    print Qucs schematic to file (eps needs inkscape)\n"
00815   "    --page [A4|A3|B4|B5]         set print page size (default A4)\n"
00816   "    --dpi NUMBER                 set dpi value (default 96)\n"
00817   "    --color [RGB|RGB]            set color mode (default RGB)\n"
00818   "    --orin [portraid|landscape]  set orientation (default portraid)\n"
00819   "  -i FILENAME    use file as input schematic\n"
00820   "  -o FILENAME    use file as output netlist\n"
00821   "  -icons         create component icons under ./bitmaps_generated\n"
00822   "  -doc           dump data for documentation:\n"
00823   "                 * file with of categories: categories.txt\n"
00824   "                 * one directory per category (e.g. ./lumped components/)\n"
00825   "                   - CSV file with component data ([comp#]_data.csv)\n"
00826   "                   - CSV file with component properties. ([comp#]_props.csv)\n"
00827   "  -list-entries  list component entry formats for schematic and netlist\n"
00828   , argv[0]);
00829       return 0;
00830     }
00831     else if (!strcmp(argv[i], "-v") || !strcmp(argv[i], "--version")) {
00832 #ifdef GIT
00833       fprintf(stdout, "Qucs " PACKAGE_VERSION " (" GIT ")" "\n");
00834 #else
00835       fprintf(stdout, "Qucs " PACKAGE_VERSION "\n");
00836 #endif
00837       return 0;
00838     }
00839     else if (!strcmp(argv[i], "-n") || !strcmp(argv[i], "--netlist")) {
00840       netlist_flag = true;
00841     }
00842     else if (!strcmp(argv[i], "-p") || !strcmp(argv[i], "--print")) {
00843       print_flag = true;
00844     }
00845     else if (!strcmp(argv[i], "--page")) {
00846       page = argv[++i];
00847     }
00848     else if (!strcmp(argv[i], "--dpi")) {
00849       dpi = QString(argv[++i]).toInt();
00850     }
00851     else if (!strcmp(argv[i], "--color")) {
00852       color = argv[++i];
00853     }
00854     else if (!strcmp(argv[i], "--orin")) {
00855       orientation = argv[++i];
00856     }
00857     else if (!strcmp(argv[i], "-i")) {
00858       inputfile = argv[++i];
00859     }
00860     else if (!strcmp(argv[i], "-o")) {
00861       outputfile = argv[++i];
00862     }
00863     else if(!strcmp(argv[i], "-icons")) {
00864       createIcons();
00865       return 0;
00866     }
00867     else if(!strcmp(argv[i], "-doc")) {
00868       createDocData();
00869       return 0;
00870     }
00871     else if(!strcmp(argv[i], "-list-entries")) {
00872       createListComponentEntry();
00873       return 0;
00874     }
00875     else {
00876       fprintf(stderr, "Error: Unknown option: %s\n", argv[i]);
00877       return -1;
00878     }
00879   }
00880 
00881   // check operation and its required arguments
00882   if (netlist_flag and print_flag) {
00883     fprintf(stderr, "Error: --print and --netlist cannot be used together\n");
00884     return -1;
00885   } else if (netlist_flag or print_flag) {
00886     if (inputfile.isEmpty()) {
00887       fprintf(stderr, "Error: Expected input file.\n");
00888       return -1;
00889     }
00890     if (outputfile.isEmpty()) {
00891       fprintf(stderr, "Error: Expected output file.\n");
00892       return -1;
00893     }
00894     // create netlist from schematic
00895     if (netlist_flag) {
00896       return doNetlist(inputfile, outputfile);
00897     } else if (print_flag) {
00898       return doPrint(inputfile, outputfile,
00899           page, dpi, color, orientation);
00900     }
00901   }
00902 
00903   QucsMain = new QucsApp();
00904   a.setMainWidget(QucsMain);
00905   
00906   QucsMain->show();
00907   int result = a.exec();
00908   //saveApplSettings(QucsMain);
00909   return result;
00910 }
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines