Qucs-GUI
0.0.19
|
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 }