/*************************************************************************** qucstrans.cpp - description ------------------- begin : Sun Feb 27 2005 copyright : (C) 2005, 2006 by Stefan Jahn email : stefan@lkcc.org ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifdef HAVE_CONFIG_H # include #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "qucstrans.h" #include "helpdialog.h" #include "optionsdialog.h" #include "transline.h" #include "units.h" #include "microstrip.h" #include "coplanar.h" #include "coax.h" #include "rectwaveguide.h" #include "c_microstrip.h" #include "stripline.h" // Defines maximum number of entries in each property category. static const int TransMaxBox[MAX_TRANS_BOXES] = { 9, 1, 4, 3 }; // Helper #defines for the below transmission line types. #define TRANS_RADIOS { -1, -1, -1, -1 } #define TRANS_QOBJS NULL, NULL, NULL, NULL #define TRANS_END { NULL, 0, NULL, { NULL }, 0, TRANS_QOBJS } #define TRANS_RESULT { NULL, NULL, NULL } #define TRANS_RESULTS { TRANS_RESULT } // Defines the available transmission line types. struct TransType TransLineTypes[] = { { ModeMicrostrip, "Microstrip", "microstrip.png", NULL, { { { { "Er", 2.94, NULL, TRANS_NONES, 0, TRANS_QOBJS }, { "Mur", 1, NULL, TRANS_NONES, 0, TRANS_QOBJS }, { "H", 10, NULL, TRANS_LENGTHS, 0, TRANS_QOBJS }, { "H_t", 1e20, NULL, TRANS_LENGTHS, 0, TRANS_QOBJS }, { "T", 0.1, NULL, TRANS_LENGTHS, 0, TRANS_QOBJS }, { "Cond", 4.1e7, NULL, TRANS_NONES, 0, TRANS_QOBJS }, { "Tand", 0, NULL, TRANS_NONES, 0, TRANS_QOBJS }, { "Rough", 0, NULL, TRANS_LENGTHS, 0, TRANS_QOBJS }, TRANS_END } }, { { { "Freq", 1, NULL, TRANS_FREQS, 0, TRANS_QOBJS }, TRANS_END } }, { { { "W", 10, NULL, TRANS_LENGTHS, 0, TRANS_QOBJS }, { "L", 100, NULL, TRANS_LENGTHS, 0, TRANS_QOBJS }, TRANS_END } }, { { { "Z0", 50, NULL, TRANS_OHMS, 0, TRANS_QOBJS }, { "Ang_l", 90, NULL, TRANS_ANGLES, 0, TRANS_QOBJS }, TRANS_END } } }, 4, TRANS_RESULTS, TRANS_RADIOS }, { ModeCoplanar, "Coplanar", "cpw.png", NULL, { { { { "Er", 2.94, NULL, TRANS_NONES, 0, TRANS_QOBJS }, { "H", 10, NULL, TRANS_LENGTHS, 0, TRANS_QOBJS }, { "T", 0.1, NULL, TRANS_LENGTHS, 0, TRANS_QOBJS }, { "Cond", 4.1e7, NULL, TRANS_NONES, 0, TRANS_QOBJS }, { "Tand", 0, NULL, TRANS_NONES, 0, TRANS_QOBJS }, TRANS_END } }, { { { "Freq", 1, NULL, TRANS_FREQS, 0, TRANS_QOBJS }, TRANS_END } }, { { { "W", 10, NULL, TRANS_LENGTHS, 0, TRANS_QOBJS }, { "S", 5, NULL, TRANS_LENGTHS, 0, TRANS_QOBJS }, { "L", 100, NULL, TRANS_LENGTHS, 0, TRANS_QOBJS }, TRANS_END } }, { { { "Z0", 50, NULL, TRANS_OHMS, 0, TRANS_QOBJS }, { "Ang_l", 90, NULL, TRANS_ANGLES, 0, TRANS_QOBJS }, TRANS_END } } }, 4, TRANS_RESULTS, { 1, 0, -1, -1 } }, { ModeGroundedCoplanar, "GroundedCoplanar", "cpw_back.png", NULL, { { { { "Er", 2.94, NULL, TRANS_NONES, 0, TRANS_QOBJS }, { "H", 10, NULL, TRANS_LENGTHS, 0, TRANS_QOBJS }, { "T", 0.1, NULL, TRANS_LENGTHS, 0, TRANS_QOBJS }, { "Cond", 4.1e7, NULL, TRANS_NONES, 0, TRANS_QOBJS }, { "Tand", 0, NULL, TRANS_NONES, 0, TRANS_QOBJS }, TRANS_END } }, { { { "Freq", 1, NULL, TRANS_FREQS, 0, TRANS_QOBJS }, TRANS_END } }, { { { "W", 10, NULL, TRANS_LENGTHS, 0, TRANS_QOBJS }, { "S", 5, NULL, TRANS_LENGTHS, 0, TRANS_QOBJS }, { "L", 100, NULL, TRANS_LENGTHS, 0, TRANS_QOBJS }, TRANS_END } }, { { { "Z0", 50, NULL, TRANS_OHMS, 0, TRANS_QOBJS }, { "Ang_l", 90, NULL, TRANS_ANGLES, 0, TRANS_QOBJS }, TRANS_END } } }, 4, TRANS_RESULTS, { 1, 0, -1, -1 } }, { ModeRectangular, "Rectangular", "rectwaveguide.png", NULL, { { { { "Er", 1, NULL, TRANS_NONES, 0, TRANS_QOBJS }, { "Mur", 1, NULL, TRANS_NONES, 0, TRANS_QOBJS }, { "Cond", 4.1e7, NULL, TRANS_NONES, 0, TRANS_QOBJS }, { "Tand", 0, NULL, TRANS_NONES, 0, TRANS_QOBJS }, { "TanM", 0, NULL, TRANS_NONES, 0, TRANS_QOBJS }, TRANS_END } }, { { { "Freq", 10, NULL, TRANS_FREQS, 0, TRANS_QOBJS }, TRANS_END } }, { { { "a", 1000, NULL, TRANS_LENGTHS, 0, TRANS_QOBJS }, { "b", 500, NULL, TRANS_LENGTHS, 0, TRANS_QOBJS }, { "L", 4000, NULL, TRANS_LENGTHS, 0, TRANS_QOBJS }, TRANS_END } }, { { { "Z0", 50, NULL, TRANS_OHMS, 0, TRANS_QOBJS }, { "Ang_l", 90, NULL, TRANS_ANGLES, 0, TRANS_QOBJS }, TRANS_END } } }, 3, TRANS_RESULTS, { 0, 1, -1, -1 } }, { ModeCoaxial, "Coaxial", "coax.png", NULL, { { { { "Er", 2.1, NULL, TRANS_NONES, 0, TRANS_QOBJS }, { "Mur", 1, NULL, TRANS_NONES, 0, TRANS_QOBJS }, { "Tand", 0.002, NULL, TRANS_NONES, 0, TRANS_QOBJS }, { "Sigma", 4.1e7, NULL, TRANS_NONES, 0, TRANS_QOBJS }, TRANS_END } }, { { { "Freq", 10, NULL, TRANS_FREQS, 0, TRANS_QOBJS }, TRANS_END } }, { { { "din", 40, NULL, TRANS_LENGTHS, 0, TRANS_QOBJS }, { "dout", 134, NULL, TRANS_LENGTHS, 0, TRANS_QOBJS }, { "L", 1000, NULL, TRANS_LENGTHS, 0, TRANS_QOBJS }, TRANS_END } }, { { { "Z0", 50, NULL, TRANS_OHMS, 0, TRANS_QOBJS }, { "Ang_l", 90, NULL, TRANS_ANGLES, 0, TRANS_QOBJS }, TRANS_END } } }, 2, TRANS_RESULTS, { 0, 1, -1, -1 } }, { ModeCoupledMicrostrip, "CoupledMicrostrip", "c_microstrip.png", NULL, { { { { "Er", 4.3, NULL, TRANS_NONES, 0, TRANS_QOBJS }, { "Mur", 1, NULL, TRANS_NONES, 0, TRANS_QOBJS }, { "H", 8.27, NULL, TRANS_LENGTHS, 0, TRANS_QOBJS }, { "H_t", 1e20, NULL, TRANS_LENGTHS, 0, TRANS_QOBJS }, { "T", 0.68, NULL, TRANS_LENGTHS, 0, TRANS_QOBJS }, { "Cond", 4.1e7, NULL, TRANS_NONES, 0, TRANS_QOBJS }, { "Tand", 0, NULL, TRANS_NONES, 0, TRANS_QOBJS }, { "Rough", 0, NULL, TRANS_LENGTHS, 0, TRANS_QOBJS }, TRANS_END } }, { { { "Freq", 10, NULL, TRANS_FREQS, 0, TRANS_QOBJS }, TRANS_END } }, { { { "W", 8.66, NULL, TRANS_LENGTHS, 0, TRANS_QOBJS }, { "S", 5.31, NULL, TRANS_LENGTHS, 0, TRANS_QOBJS }, { "L", 1000, NULL, TRANS_LENGTHS, 0, TRANS_QOBJS }, TRANS_END } }, { { { "Z0e", 50, NULL, TRANS_OHMS, 0, TRANS_QOBJS }, { "Z0o", 50, NULL, TRANS_OHMS, 0, TRANS_QOBJS }, { "Ang_l", 90, NULL, TRANS_ANGLES, 0, TRANS_QOBJS }, TRANS_END } } }, 7, TRANS_RESULTS, TRANS_RADIOS }, { ModeStripline, "Stripline", "stripline.png", NULL, { { { { "Er", 4.5, NULL, TRANS_NONES, 0, TRANS_QOBJS }, { "Mur", 1, NULL, TRANS_NONES, 0, TRANS_QOBJS }, { "h", 27.56, NULL, TRANS_LENGTHS, 0, TRANS_QOBJS }, { "Tand", 0.018, NULL, TRANS_NONES, 0, TRANS_QOBJS }, { "T", 1.42, NULL, TRANS_LENGTHS, 0, TRANS_QOBJS }, { "Sigma", 5.8e7, NULL, TRANS_NONES, 0, TRANS_QOBJS }, TRANS_END } }, { { { "Freq", 10, NULL, TRANS_FREQS, 0, TRANS_QOBJS }, TRANS_END } }, { { { "W", 19.69, NULL, TRANS_LENGTHS, 0, TRANS_QOBJS }, { "L", 100, NULL, TRANS_LENGTHS, 0, TRANS_QOBJS }, TRANS_END } }, { { { "Z0", 50, NULL, TRANS_OHMS, 0, TRANS_QOBJS }, { "Ang_l", 90, NULL, TRANS_ANGLES, 0, TRANS_QOBJS }, TRANS_END } } }, 2, TRANS_RESULTS, { 0, 1, -1, -1 } }, { ModeNone, NULL, NULL, NULL, { { { TRANS_END } } }, 0, TRANS_RESULTS, TRANS_RADIOS } }; struct TransUnit TransUnits[] = { { "Frequency", TRANS_FREQS }, { "Length", TRANS_LENGTHS }, { "Resistance", TRANS_OHMS }, { "Angle", TRANS_ANGLES }, }; /* Constructor setups the GUI. */ QucsTranscalc::QucsTranscalc() { QWidget *centralWidget = new QWidget(this); setCentralWidget(centralWidget); // set application icon setWindowIcon(QPixmap(":/bitmaps/big.qucs.xpm")); setWindowTitle("Qucs Transcalc " PACKAGE_VERSION); // create file menu QMenu *fileMenu = new QMenu(tr("&File")); QAction *fileLoad = new QAction(tr("&Load"), this); fileLoad->setShortcut(tr("Ctrl+L")); fileMenu->addAction(fileLoad); connect(fileLoad, SIGNAL(triggered(bool)), SLOT(slotFileLoad())); QAction *fileSave = new QAction (tr("&Save"), this); fileSave->setShortcut(tr("Ctrl+S")); fileMenu->addAction(fileSave); connect(fileSave, SIGNAL(triggered(bool)), SLOT(slotFileSave())); fileMenu->addSeparator(); QAction *fileOption = new QAction (tr("&Options"), this); fileOption->setShortcut(tr("Ctrl+O")); fileMenu->addAction(fileOption); connect(fileOption, SIGNAL(triggered(bool)), SLOT(slotOptions())); fileMenu->addSeparator(); QAction *fileQuit = new QAction (tr("&Quit"), this); fileQuit->setShortcut(QKeySequence::Quit); fileMenu->addAction(fileQuit); connect(fileQuit, SIGNAL(triggered(bool)), SLOT(slotQuit())); // create execute menu QMenu *execMenu = new QMenu(tr("&Execute")); QAction *execCopy = new QAction(tr("&Copy to Clipboard"), this); execCopy->setShortcut(Qt::Key_F2); execMenu->addAction(execCopy); connect(execCopy, SIGNAL(triggered(bool)), SLOT(slotCopyToClipBoard())); QAction *execAnalyze = new QAction(tr("&Analyze"), this); execAnalyze->setShortcut(Qt::Key_F3); execMenu->addAction(execAnalyze); connect(execAnalyze, SIGNAL(triggered(bool)), SLOT(slotAnalyze())); QAction *execSynthesize = new QAction (tr("&Synthesize"), this); execSynthesize->setShortcut(Qt::Key_F4); execMenu->addAction(execSynthesize); connect(execSynthesize, SIGNAL(triggered(bool)), SLOT(slotSynthesize())); // create help menu QMenu *helpMenu = new QMenu(tr("&Help")); QAction *helpHelp = new QAction(tr("&Help"), this); helpHelp->setShortcut(Qt::Key_F1); helpMenu->addAction(helpHelp); connect(helpHelp, SIGNAL(triggered(bool)), SLOT(slotHelpIntro())); QAction *helpAbout = new QAction(tr("About"), this); helpMenu->addAction(helpAbout); connect(helpAbout, SIGNAL(triggered(bool)), SLOT(slotAbout())); // setup menu bar menuBar()->addMenu(fileMenu); menuBar()->addMenu(execMenu); menuBar()->addSeparator(); menuBar()->addMenu(helpMenu); // === left // seletion combo and figure QVBoxLayout *vl = new QVBoxLayout(); // transmission line type choice QGroupBox * lineGroup = new QGroupBox (tr("Transmission Line Type")); tranType = new QComboBox (lineGroup); tranType->insertItem (0, tr("Microstrip Line")); tranType->insertItem (1, tr("Coplanar Waveguide")); tranType->insertItem (2, tr("Grounded Coplanar")); tranType->insertItem (3, tr("Rectangular Waveguide")); tranType->insertItem (4, tr("Coaxial Line")); tranType->insertItem (5, tr("Coupled Microstrip")); tranType->insertItem (6, tr("Stripline")); connect(tranType, SIGNAL(activated(int)), SLOT(slotSelectType(int))); // setup transmission line picture pix = new QLabel (lineGroup); pix->setPixmap(QPixmap(":/bitmaps/microstrip.png")); QVBoxLayout *vfig = new QVBoxLayout(); vfig->addWidget(tranType); vfig->addWidget(pix); vfig->setSpacing(3); lineGroup->setLayout(vfig); vl->addWidget(lineGroup); // init additional translations setupTranslations (); // set current mode mode = ModeMicrostrip; // === middle QVBoxLayout *vm = new QVBoxLayout(); vm->setSpacing (3); // substrate parameter box QGroupBox * substrate = new QGroupBox (tr("Substrate Parameters")); vm->addWidget(substrate); // Pass the GroupBox > create Grid layout > Add widgets > set layout createPropItems (substrate, TRANS_SUBSTRATE); // component parameter box QGroupBox * component = new QGroupBox (tr("Component Parameters")); vm->addWidget(component); createPropItems (component, TRANS_COMPONENT); // === right QVBoxLayout *vr = new QVBoxLayout(); vr->setSpacing (3); // physical parameter box QGroupBox * physical = new QGroupBox (tr("Physical Parameters")); vr->addWidget(physical); createPropItems (physical, TRANS_PHYSICAL); // analyze/synthesize buttons QHBoxLayout * h2 = new QHBoxLayout(); QPushButton * analyze = new QPushButton (tr("Analyze")); h2->addWidget(analyze); analyze->setToolTip(tr("Derive Electrical Parameters")); connect(analyze, SIGNAL(clicked()), SLOT(slotAnalyze())); QPushButton * synthesize = new QPushButton (tr("Synthesize")); h2->addWidget(synthesize); synthesize->setToolTip(tr("Compute Physical Parameters")); connect(synthesize, SIGNAL(clicked()), SLOT(slotSynthesize())); vr->addLayout(h2); // electrical parameter box QGroupBox * electrical = new QGroupBox (tr("Electrical Parameters")); vr->addWidget(electrical); createPropItems (electrical, TRANS_ELECTRICAL); calculated = new QGroupBox (tr("Calculated Results")); vr->addWidget(calculated); // status line //statBar = new QStatusBar (this); //QLabel * statText = new QLabel ("Ready.", statBar); statusBar()->showMessage (tr("Ready.")); //statBar->setFixedHeight (statText->height ()); //delete statText; QVBoxLayout *vmain = new QVBoxLayout(); QHBoxLayout *hmain = new QHBoxLayout(); hmain->addLayout(vl); hmain->addLayout(vm); hmain->addLayout(vr); vmain->addLayout(hmain); //vmain->addWidget(statBar); centralWidget->setLayout(vmain); // setup calculated result bix createResultItems (calculated); updateSelection (); // instantiate transmission lines TransLineTypes[0].line = new microstrip (); TransLineTypes[0].line->setApplication (this); TransLineTypes[1].line = new coplanar (); TransLineTypes[1].line->setApplication (this); TransLineTypes[2].line = new groundedCoplanar (); TransLineTypes[2].line->setApplication (this); TransLineTypes[3].line = new rectwaveguide (); TransLineTypes[3].line->setApplication (this); TransLineTypes[4].line = new coax (); TransLineTypes[4].line->setApplication (this); TransLineTypes[5].line = new c_microstrip (); TransLineTypes[5].line->setApplication (this); TransLineTypes[6].line = new stripline (); TransLineTypes[6].line->setApplication (this); } /* Destructor destroys the application. */ QucsTranscalc::~QucsTranscalc() { for (int i = 0; i < MAX_TRANS_TYPES; i++) { if (TransLineTypes[i].line) delete TransLineTypes[i].line; } } /* The function puts translatable text into the transmission line structures. */ void QucsTranscalc::setupTranslations () { // calculated results int i = 0;//Microstrip TransLineTypes[i].result[0].name = new QString(tr("ErEff")); TransLineTypes[i].result[1].name = new QString(tr("Conductor Losses")); TransLineTypes[i].result[2].name = new QString(tr("Dielectric Losses")); TransLineTypes[i].result[3].name = new QString(tr("Skin Depth")); i++;//CPW TransLineTypes[i].result[0].name = new QString(tr("ErEff")); TransLineTypes[i].result[1].name = new QString(tr("Conductor Losses")); TransLineTypes[i].result[2].name = new QString(tr("Dielectric Losses")); TransLineTypes[i].result[3].name = new QString(tr("Skin Depth")); i++;//GCPW TransLineTypes[i].result[0].name = new QString(tr("ErEff")); TransLineTypes[i].result[1].name = new QString(tr("Conductor Losses")); TransLineTypes[i].result[2].name = new QString(tr("Dielectric Losses")); TransLineTypes[i].result[3].name = new QString(tr("Skin Depth")); i++;//Rectangular waveguide TransLineTypes[i].result[0].name = new QString(tr("ErEff")); TransLineTypes[i].result[1].name = new QString(tr("Conductor Losses")); TransLineTypes[i].result[2].name = new QString(tr("Dielectric Losses")); TransLineTypes[i].result[3].name = new QString(tr("TE-Modes")); TransLineTypes[i].result[4].name = new QString(tr("TM-Modes")); i++;//Coaxial line TransLineTypes[i].result[0].name = new QString(tr("Conductor Losses")); TransLineTypes[i].result[1].name = new QString(tr("Dielectric Losses")); TransLineTypes[i].result[2].name = new QString(tr("TE-Modes")); TransLineTypes[i].result[3].name = new QString(tr("TM-Modes")); i++;//Coupled microstripx TransLineTypes[i].result[0].name = new QString(tr("ErEff Even")); TransLineTypes[i].result[1].name = new QString(tr("ErEff Odd")); TransLineTypes[i].result[2].name = new QString(tr("Conductor Losses Even")); TransLineTypes[i].result[3].name = new QString(tr("Conductor Losses Odd")); TransLineTypes[i].result[4].name = new QString(tr("Dielectric Losses Even")); TransLineTypes[i].result[5].name = new QString(tr("Dielectric Losses Odd")); TransLineTypes[i].result[6].name = new QString(tr("Skin Depth")); i++;//Stripline TransLineTypes[i].result[0].name = new QString(tr("Conductor Losses")); TransLineTypes[i].result[1].name = new QString(tr("Dielectric Losses")); TransLineTypes[i].result[2].name = new QString(tr("Skin Depth")); // extra tool tips struct TransType * t = TransLineTypes; //Microstrip t->array[0].item[0].tip = new QString(tr("Relative Permittivity")); t->array[0].item[1].tip = new QString(tr("Relative Permeability")); t->array[0].item[2].tip = new QString(tr("Height of Substrate")); t->array[0].item[3].tip = new QString(tr("Height of Box Top")); t->array[0].item[4].tip = new QString(tr("Strip Thickness")); t->array[0].item[5].tip = new QString(tr("Strip Conductivity")); t->array[0].item[6].tip = new QString(tr("Dielectric Loss Tangent")); t->array[0].item[7].tip = new QString(tr("Conductor Roughness")); t->array[1].item[0].tip = new QString(tr("Frequency")); t->array[2].item[0].tip = new QString(tr("Line Width")); t->array[2].item[1].tip = new QString(tr("Line Length")); t->array[3].item[0].tip = new QString(tr("Characteristic Impedance")); t->array[3].item[1].tip = new QString(tr("Electrical Length")); t++;//CPW t->array[0].item[0].tip = new QString(tr("Relative Permittivity")); t->array[0].item[1].tip = new QString(tr("Height of Substrate")); t->array[0].item[2].tip = new QString(tr("Strip Thickness")); t->array[0].item[3].tip = new QString(tr("Strip Conductivity")); t->array[0].item[4].tip = new QString(tr("Dielectric Loss Tangent")); t->array[1].item[0].tip = new QString(tr("Frequency")); t->array[2].item[0].tip = new QString(tr("Line Width")); t->array[2].item[1].tip = new QString(tr("Gap Width")); t->array[2].item[2].tip = new QString(tr("Line Length")); t->array[3].item[0].tip = new QString(tr("Characteristic Impedance")); t->array[3].item[1].tip = new QString(tr("Electrical Length")); t++;//GCPW t->array[0].item[0].tip = new QString(tr("Relative Permittivity")); t->array[0].item[1].tip = new QString(tr("Height of Substrate")); t->array[0].item[2].tip = new QString(tr("Strip Thickness")); t->array[0].item[3].tip = new QString(tr("Strip Conductivity")); t->array[0].item[4].tip = new QString(tr("Dielectric Loss Tangent")); t->array[1].item[0].tip = new QString(tr("Frequency")); t->array[2].item[0].tip = new QString(tr("Line Width")); t->array[2].item[1].tip = new QString(tr("Gap Width")); t->array[2].item[2].tip = new QString(tr("Line Length")); t->array[3].item[0].tip = new QString(tr("Characteristic Impedance")); t->array[3].item[1].tip = new QString(tr("Electrical Length")); t++;//Rectangular waveguide t->array[0].item[0].tip = new QString(tr("Relative Permittivity")); t->array[0].item[1].tip = new QString(tr("Relative Permeability")); t->array[0].item[2].tip = new QString(tr("Conductivity of Metal")); t->array[0].item[3].tip = new QString(tr("Dielectric Loss Tangent")); t->array[0].item[4].tip = new QString(tr("Magnetic Loss Tangent")); t->array[1].item[0].tip = new QString(tr("Frequency")); t->array[2].item[0].tip = new QString(tr("Width of Waveguide")); t->array[2].item[1].tip = new QString(tr("Height of Waveguide")); t->array[2].item[2].tip = new QString(tr("Waveguide Length")); t->array[3].item[0].tip = new QString(tr("Characteristic Impedance")); t->array[3].item[1].tip = new QString(tr("Electrical Length")); t++;//Coaxial line t->array[0].item[0].tip = new QString(tr("Relative Permittivity")); t->array[0].item[1].tip = new QString(tr("Relative Permeability")); t->array[0].item[2].tip = new QString(tr("Dielectric Loss Tangent")); t->array[0].item[3].tip = new QString(tr("Conductivity of Metal")); t->array[1].item[0].tip = new QString(tr("Frequency")); t->array[2].item[0].tip = new QString(tr("Inner Diameter")); t->array[2].item[1].tip = new QString(tr("Outer Diameter")); t->array[2].item[2].tip = new QString(tr("Length")); t->array[3].item[0].tip = new QString(tr("Characteristic Impedance")); t->array[3].item[1].tip = new QString(tr("Electrical Length")); t++;//Coupled microstrip t->array[0].item[0].tip = new QString(tr("Relative Permittivity")); t->array[0].item[1].tip = new QString(tr("Relative Permeability")); t->array[0].item[2].tip = new QString(tr("Height of Substrate")); t->array[0].item[3].tip = new QString(tr("Height of Box Top")); t->array[0].item[4].tip = new QString(tr("Strip Thickness")); t->array[0].item[5].tip = new QString(tr("Strip Conductivity")); t->array[0].item[6].tip = new QString(tr("Dielectric Loss Tangent")); t->array[0].item[7].tip = new QString(tr("Conductor Roughness")); t->array[1].item[0].tip = new QString(tr("Frequency")); t->array[2].item[0].tip = new QString(tr("Line Width")); t->array[2].item[1].tip = new QString(tr("Gap Width")); t->array[2].item[2].tip = new QString(tr("Length")); t->array[3].item[0].tip = new QString(tr("Even-Mode Impedance")); t->array[3].item[1].tip = new QString(tr("Odd-Mode Impedance")); t->array[3].item[2].tip = new QString(tr("Electrical Length")); t++;//Stripline t->array[0].item[0].tip = new QString(tr("Relative Permittivity")); t->array[0].item[1].tip = new QString(tr("Relative Permeability")); t->array[0].item[2].tip = new QString(tr("Dielectric Loss Tangent")); t->array[0].item[3].tip = new QString(tr("Conductivity of Metal")); t->array[0].item[4].tip = new QString(tr("Conductor thickness")); t->array[0].item[5].tip = new QString(tr("Substrate height")); t->array[1].item[0].tip = new QString(tr("Frequency")); t->array[2].item[0].tip = new QString(tr("Width")); t->array[2].item[1].tip = new QString(tr("Length")); t->array[3].item[0].tip = new QString(tr("Characteristic Impedance")); t->array[3].item[1].tip = new QString(tr("Electrical Length")); } /* Creates a property item 'val' in a parameter category specified by its 'box'. */ void QucsTranscalc::createPropItem (QGridLayout * parentGrid, TransValue * val, int box, QButtonGroup * group) { Q_UNUSED(group); QRadioButton * r = NULL; QLabel * l; QLineEdit * e; QComboBox * c; QDoubleValidator * v = new QDoubleValidator (this); v->setLocale(QLocale::C); // name label l = new QLabel (val->name); parentGrid->addWidget(l, parentGrid->rowCount(), 0); l->setAlignment (Qt::AlignRight); if (val->tip) l->setToolTip(*(val->tip)); val->label = l; // editable value text e = new QLineEdit (); parentGrid->addWidget(e, parentGrid->rowCount()-1, 1); e->setText (QString::number (val->value)); e->setAlignment (Qt::AlignRight); e->setValidator (v); connect(e, SIGNAL(textChanged(const QString&)), SLOT(slotValueChanged())); if (!val->name) e->setDisabled (true); val->lineedit = e; // unit choice c = new QComboBox (); parentGrid->addWidget(c, parentGrid->rowCount()-1, 2); if (!val->units[0]) { c->addItem ("NA"); c->setDisabled(true); } else { int nounit = 0; for (int i = 0; val->units[i]; i++) { c->addItem (val->units[i]); if (!strcmp (val->units[i], "NA")) nounit++; } c->setDisabled (nounit != 0); c->setCurrentIndex (0); } connect(c, SIGNAL(activated(int)), SLOT(slotValueChanged())); val->combobox = c; // special synthesize-computation choice if (box == TRANS_PHYSICAL) { r = new QRadioButton (); r->setDisabled (true); r->setHidden(true); val->radio = r; parentGrid->addWidget(r, parentGrid->rowCount()-1, 3); } } /* The function changes the content of a GUI's property entry depending on the given transmission line property. */ void QucsTranscalc::updatePropItem (TransValue * val) { // update label text val->label->setText (val->name); if (val->tip) val->label->setToolTip(*(val->tip)); // update editable value text val->lineedit->setText (QString::number (val->value)); val->lineedit->setDisabled (!val->name); // update unit choice val->combobox->clear(); if (!val->units[0]) { val->combobox->addItem ("NA"); val->combobox->setDisabled (true); } else { int nounit = 0; for (int i = 0; val->units[i]; i++) { val->combobox->addItem (val->units[i]); if (!strcmp (val->units[i], "NA")) nounit++; } val->combobox->setCurrentIndex(val->unit); val->combobox->setDisabled (nounit); } } /* Switches to the current type of transmission line layout. */ void QucsTranscalc::setMode (int _mode) { // change necessary? if (mode == _mode) return; storeValues (); mode = _mode; setUpdatesEnabled(false); updateMode (); // update selection and results updateSelection (); updateResultItems (); slotAnalyze(); setUpdatesEnabled(true); repaint(); } /* Updates the property items of the current mode. */ void QucsTranscalc::updateMode (void) { // go through each type of parameter category for (int box = 0; box < MAX_TRANS_BOXES; box++) { int last = 0, idx = getTypeIndex(); struct TransValue * val = TransLineTypes[idx].array[box].item; // update each property item for (int i = 0; i < TransMaxBox[box]; i++) { // fix uninitialized memory if (val->name == NULL) last++; if (last) { val->name = NULL; val->value = 0; val->tip = NULL; val->units[0] = NULL; } updatePropItem (val); val++; } } } /* Updates the current choice of physical property selection. */ void QucsTranscalc::updateSelection () { int idx = getTypeIndex (); struct TransValue * val = TransLineTypes[idx].array[TRANS_PHYSICAL].item; for (int i = 0; i < TransMaxBox[TRANS_PHYSICAL]; i++) { if (TransLineTypes[idx].radio[i] != -1) { val->radio->setHidden(false); if (TransLineTypes[idx].radio[i] == 1) { val->radio->setDown (true); val->radio->setChecked (true); val->radio->setToolTip(tr("Selected for Calculation")); } else { val->radio->setDown (false); val->radio->setChecked (false); val->radio->setToolTip(tr("Check item for Calculation")); } val->radio->setDisabled (false); } else { val->radio->setHidden(true); val->radio->setDown (false); val->radio->setChecked (false); val->radio->setDisabled (true); } val++; } } /* The function creates the property items for the given category of transmission line parameters. */ void QucsTranscalc::createPropItems (QGroupBox *parent, int box) { struct TransValue * val, * dup; int last = 0, idx = getTypeIndex (); val = TransLineTypes[idx].array[box].item; QGridLayout *boxGrid = new QGridLayout(); QButtonGroup * group = new QButtonGroup(); connect(group, SIGNAL(buttonPressed(int)), SLOT(slotRadioChecked(int))); boxGrid->setSpacing(2); parent->setLayout(boxGrid); // go through each parameter category for (int i = 0; i < TransMaxBox[box]; i++) { // fix uninitialized memory if (val->name == NULL) last++; if (last) { val->name = NULL; val->value = 0; val->tip = NULL; val->units[0] = NULL; } createPropItem (boxGrid, val, box, group); // publish the newly created widgets to the other transmission lines for (int _mode = 0; _mode < MAX_TRANS_TYPES; _mode++) { if (idx != _mode) { dup = & TransLineTypes[_mode].array[box].item[i]; dup->label = val->label; dup->lineedit = val->lineedit; dup->combobox = val->combobox; dup->radio = val->radio; // dup->value = val->value; } } val++; } } /* Creates a single result item. */ void QucsTranscalc::createResultItem (QGridLayout * parentGrid, TransResult * res) { QLabel * n = new QLabel (res->name ? *(res->name) + ":" : QString()); parentGrid->addWidget(n, parentGrid->count(),0,1,1); n->setAlignment (Qt::AlignRight); res->label = n; QLabel * v = new QLabel (); parentGrid->addWidget(v, parentGrid->count()-1,1,1,1); v->setAlignment (Qt::AlignLeft); res->value = v; if (!res->name) { v->hide (); n->hide (); } } /* Updates the given result item. */ void QucsTranscalc::updateResultItem (TransResult * res) { if (res->name) { res->label->setText (*(res->name) + ":"); res->label->show (); res->value->show (); } else { res->label->hide (); res->value->hide (); } } /* Creates all the result items. */ void QucsTranscalc::createResultItems (QGroupBox * parent) { struct TransResult * res, * dup; int idx = getTypeIndex (); res = & TransLineTypes[idx].result[0]; QGridLayout *boxGrid = new QGridLayout(); boxGrid->setSpacing(2); parent->setLayout(boxGrid); for (int i = 0; i < MAX_TRANS_RESULTS; i++) { createResultItem (boxGrid, res); for (int _mode = 0; _mode < MAX_TRANS_TYPES; _mode++) { if (idx != _mode) { dup = & TransLineTypes[_mode].result[i]; dup->label = res->label; dup->value = res->value; } } res++; } } /* Puts the given result into its widget. */ void QucsTranscalc::setResult (int line, const char * text) { struct TransResult * res; res = & TransLineTypes[getTypeIndex ()].result[line]; res->value->setText (text); } /* Updates the current result items. */ void QucsTranscalc::updateResultItems() { int idx = getTypeIndex (); struct TransResult * res = TransLineTypes[idx].result; for (int i = 0; i < MAX_TRANS_RESULTS; i++) { updateResultItem (res); res++; } } /* Returns the appropriate array index for the given mode. */ int QucsTranscalc::getTypeIndex () { struct TransType * type = TransLineTypes; for (int i = 0; type->type != ModeNone; i++) { if (type->type == mode) return i; type++; } return 0; } /* Returns the property value specified by its name. */ struct TransValue * QucsTranscalc::findProperty (QString prop) { struct TransValue * val = NULL; for (int box = 0; box < MAX_TRANS_BOXES; box++) { val = TransLineTypes[getTypeIndex ()].array[box].item; for (int i = 0; val->name; i++) { if (prop == val->name) return val; val++; } } return NULL; } /* Sets the given property to the given value. */ void QucsTranscalc::setProperty (QString prop, double value) { struct TransValue * val = findProperty (prop); if (val) { val->lineedit->setText (QString::number (value)); val->value = value; } } /* Returns the given property value. */ double QucsTranscalc::getProperty (QString prop) { struct TransValue * val = findProperty (prop); if (val) { QString str = val->lineedit->text (); val->value = str.toDouble (); return val->value; } return 0; } /* Sets the given property unit. */ void QucsTranscalc::setUnit (QString prop, const char * unit) { struct TransValue * val = findProperty (prop); if (val) { if (!unit) { val->combobox->setCurrentIndex (0); val->unit = 0; } else for (int i = 0; val->units[i]; i++) { if (!strcmp (unit, val->units[i])) { val->combobox->setCurrentIndex (i); val->unit = i; break; } } } } /* Returns the given property unit. */ char * QucsTranscalc::getUnit (QString prop) { struct TransValue * val = findProperty (prop); if (val) { QString str = val->combobox->currentText (); for (int i = 0; val->units[i]; i++) { if (str == val->units[i]) { val->unit = i; return (char *) val->units[i]; } } } return NULL; } /* Returns the given property selection. */ bool QucsTranscalc::isSelected (QString prop) { struct TransValue * val = findProperty (prop); if (val) { if (val->radio) if (val->radio->isChecked ()) { return true; } } return false; } void QucsTranscalc::slotAbout() { QMessageBox::about(this, tr("About..."), "QucsTranscalc Version " PACKAGE_VERSION "\n"+ tr("Transmission Line Calculator for Qucs\n")+ tr("Copyright (C) 2001 by Gopal Narayanan\n")+ tr("Copyright (C) 2002 by Claudio Girardi\n")+ tr("Copyright (C) 2005 by Stefan Jahn\n")+ tr("Copyright (C) 2008 by Michael Margraf\n")+ "\nThis is free software; see the source for copying conditions." "\nThere is NO warranty; not even for MERCHANTABILITY or " "\nFITNESS FOR A PARTICULAR PURPOSE."); } void QucsTranscalc::slotQuit() { int tmp; tmp = x(); // call size and position function in order to ... tmp = y(); // ... set them correctly before closing the ... tmp = width(); // dialog !!! Otherwise the frame of the window ... tmp = height(); // will not be recognized (a X11 problem). Q_UNUSED(tmp); storeValues (); qApp->quit(); } void QucsTranscalc::closeEvent(QCloseEvent *Event) { int tmp; tmp = x(); // call size and position function in order to ... tmp = y(); // ... set them correctly before closing the ... tmp = width(); // dialog !!! Otherwise the frame of the window ... tmp = height(); // will not be recognized (a X11 problem). Q_UNUSED(tmp); storeValues (); Event->accept(); } void QucsTranscalc::slotSelectType (int Type) { pix->setPixmap(QPixmap(":/bitmaps/" + QString(TransLineTypes[Type].bitmap))); setMode (Type); statusBar()->showMessage(tr("Ready.")); } void QucsTranscalc::slotAnalyze() { if (TransLineTypes[getTypeIndex()].line) TransLineTypes[getTypeIndex()].line->analyze(); statusBar()->showMessage(tr("Values are consistent.")); } void QucsTranscalc::slotSynthesize() { int status = -1; if (TransLineTypes[getTypeIndex()].line) status = TransLineTypes[getTypeIndex()].line->synthesize(); if (status == 0) statusBar()->showMessage(tr("Values are consistent.")); else statusBar()->showMessage(tr("Failed to converge!")); } void QucsTranscalc::slotValueChanged() { statusBar()->showMessage(tr("Values are inconsistent.")); } // Load transmission line values from the given file. bool QucsTranscalc::loadFile(QString fname, int * _mode) { QFile file(QDir::toNativeSeparators(fname)); if(!file.open(QIODevice::ReadOnly)) return false; // file doesn't exist QTextStream stream(&file); QString Line, Name, Unit; double Value; int oldmode = mode; while(!stream.atEnd()) { Line = stream.readLine(); for (int i = 0; i < MAX_TRANS_TYPES; i++) { if (Line == "<" + QString(TransLineTypes[i].description) + ">") { if (_mode) { *_mode = TransLineTypes[i].type; setMode (*_mode); updatePixmap (mode); } else { mode = TransLineTypes[i].type; } while(!stream.atEnd()) { Line = stream.readLine(); if (Line == "") break; Line = Line.simplified(); Name = Line.section(' ',0,0); Value = Line.section(' ',1,1).toDouble(); Unit = Line.section(' ',2,2); setProperty (Name, Value); setUnit (Name, Unit.toLatin1()); } break; } } } if (!_mode) mode = oldmode; updateMode (); file.close(); return true; } // Saves current transmission line values into the given file. bool QucsTranscalc::saveFile(QString fname) { QFile file (QDir::toNativeSeparators(fname)); if(!file.open (QIODevice::WriteOnly)) return false; // file not writable QTextStream stream (&file); // some lines of documentation stream << "# QucsTranscalc " << PACKAGE_VERSION << " " << fname << "\n"; stream << "# Generated on " << QDate::currentDate().toString() << " at " << QTime::currentTime().toString() << ".\n"; stream << "# It is not suggested to edit the file, use QucsTranscalc " << "instead.\n\n"; storeValues (); saveMode (stream); file.close (); return true; } /* Writes the transmission line values for the current modes into the given stream. */ void QucsTranscalc::saveMode(QTextStream& stream) { struct TransType * t = &TransLineTypes[getTypeIndex ()]; struct TransValue * val = NULL; stream << "<" << t->description << ">\n"; for (int box = 0; box < MAX_TRANS_BOXES; box++) { val = t->array[box].item; while (val->name) { stream << " " << val->name << " " << val->value << " " << val->units[val->unit] << "\n"; val++; } } stream << "description << ">\n"; } // Writes the transmission line values for all modes into the given file. bool QucsTranscalc::saveModes(QString fname) { int oldmode = mode; QFile file(fname); if(!file.open(QIODevice::WriteOnly)) { QMessageBox::warning(this, QObject::tr("Warning"), QObject::tr("Cannot save GUI settings in\n") + fname); return false; } QTextStream stream(&file); stream << "QucsTranscalc " PACKAGE_VERSION " GUI Settings File\n"; for (int i = 0; i < MAX_TRANS_TYPES; i++) { mode = TransLineTypes[i].type; saveMode (stream); } file.close(); mode = oldmode; return true; } // Saves the GUI values into internal data structures. void QucsTranscalc::storeValues (void) { struct TransType * t = &TransLineTypes[getTypeIndex ()]; struct TransValue * val; for (int box = 0; box < MAX_TRANS_BOXES; box++) { val = t->array[box].item; int i = 0; while (val->name) { getProperty (val->name); getUnit (val->name); if (box == TRANS_PHYSICAL) { if (val->radio->isEnabled()) { if (val->radio->isChecked()) t->radio[i] = 1; else t->radio[i] = 0; } else t->radio[i] = -1; } i++; val++; } } } void QucsTranscalc::slotFileLoad() { statusBar()->showMessage(tr("Loading file...")); int _mode = 0; QString s = QFileDialog::getOpenFileName(this, tr("Enter a Filename"), QucsSettings.QucsWorkDir.path(), tr("Transcalc File") + " (*.trc)"); if (!s.isEmpty()) { QucsSettings.QucsWorkDir.setPath(QDir::cleanPath(s)); if (!loadFile (s, &_mode)) { QMessageBox::critical (this, tr("Error"), tr("Cannot load file:")+" '"+s+"'!"); } } else statusBar()->showMessage(tr("Loading aborted."), 2000); statusBar()->showMessage(tr("Ready.")); } void QucsTranscalc::slotFileSave() { statusBar()->showMessage(tr("Saving file...")); QString s = QFileDialog::getSaveFileName(this, tr("Enter a Filename"), QucsSettings.QucsWorkDir.path(), tr("Transcalc File") + " (*.trc)"); if (!s.isEmpty()) { QucsSettings.QucsWorkDir.setPath(QDir::cleanPath(s)); if (!saveFile (s)) { QMessageBox::critical (this, tr("Error"), tr("Cannot save file:")+" '"+s+"'!"); } } else statusBar()->showMessage(tr("Saving aborted."), 2000); statusBar()->showMessage(tr("Ready.")); } // Returns the current textual mode. QString QucsTranscalc::getMode (void) { return TransLineTypes[getTypeIndex ()].description; } // Sets the mode according to the given textual mode. void QucsTranscalc::setMode (QString _mode) { for (int i = 0; i < MAX_TRANS_TYPES; i++) { if (TransLineTypes[i].description == _mode) { setMode (TransLineTypes[i].type); updatePixmap (mode); break; } } } // Updates the combobox and pixmap for the current mode. void QucsTranscalc::updatePixmap (int _mode) { pix->setPixmap(QPixmap(":/bitmaps/" + QString(TransLineTypes[_mode].bitmap))); tranType->setCurrentIndex(_mode); } void QucsTranscalc::slotHelpIntro() { HelpDialog *d = new HelpDialog(this); d->show(); } void QucsTranscalc::slotOptions() { OptionsDialog *d = new OptionsDialog(this); d->show(); } // Translates a given textual unit into a array index. int QucsTranscalc::translateUnit(const char * unit, int type) { for (int i = 0; TransUnits[type].units[i]; i++) { if (unit && !strcmp (unit, TransUnits[type].units[i])) return i; } return 0; } void QucsTranscalc::slotRadioChecked(int id) { int idx = getTypeIndex (); for (int i = 0; i < TransMaxBox[TRANS_PHYSICAL]; i++) { if (TransLineTypes[idx].radio[i] != -1) { TransLineTypes[idx].radio[i] = 0; if (i == id) { TransLineTypes[idx].radio[i] = 1; } } } updateSelection (); } void QucsTranscalc::slotCopyToClipBoard() { int created = 0; QString s = "\n"; // create microstrip schematic if (mode == ModeMicrostrip) { transline * l = TransLineTypes[ModeMicrostrip].line; s += "\n"; s += " \n"; s +=" \n"; s += " \n"; s += " \n"; s += QStringLiteral(" \n"). arg(l->getProperty("Er")). arg(l->getProperty("H", UNIT_LENGTH, LENGTH_MM)). arg(l->getProperty("T", UNIT_LENGTH, LENGTH_UM)). arg(l->getProperty("Tand")). arg(1 / l->getProperty("Cond")). arg(l->getProperty("Rough", UNIT_LENGTH, LENGTH_M)); s += " <.SP SPTC1 1 90 240 0 51 0 0 "; double freq = l->getProperty("Freq", UNIT_FREQ, FREQ_GHZ); if (freq > 0) s += QStringLiteral("\"log\" 1 \"%1 GHz\" 1 \"%2 GHz\" 1 "). arg(freq / 10).arg(freq * 10); else s += "\"lin\" 1 \"0 GHz\" 1 \"10 GHz\" 1 "; s += "\"51\" 1 \"no\" 0 \"1\" 0 \"2\" 0>\n"; s += QStringLiteral(" \n"). arg(l->getProperty("W", UNIT_LENGTH, LENGTH_MM)). arg(l->getProperty("L", UNIT_LENGTH, LENGTH_MM)); s += " \n"; s += "\n"; s += "\n"; s += " <90 100 150 100 \"\" 0 0 0 \"\">\n"; s += " <90 100 90 120 \"\" 0 0 0 \"\">\n"; s += " <210 100 270 100 \"\" 0 0 0 \"\">\n"; s += " <270 100 270 120 \"\" 0 0 0 \"\">\n"; s += "\n"; created++; } // create coupled microstrip schematic else if (mode == ModeCoupledMicrostrip) { transline * l = TransLineTypes[ModeCoupledMicrostrip].line; s += "\n"; s += " \n"; s += " \n"; s += " \n"; s += " \n"; s += " \n"; s += " \n"; s += " \n"; s += " \n"; s += QStringLiteral(" \n"). arg(l->getProperty("Er")). arg(l->getProperty("H", UNIT_LENGTH, LENGTH_MM)). arg(l->getProperty("T", UNIT_LENGTH, LENGTH_UM)). arg(l->getProperty("Tand")). arg(1 / l->getProperty("Cond")). arg(l->getProperty("Rough", UNIT_LENGTH, LENGTH_M)); s += " <.SP SPTC1 1 100 290 0 51 0 0 "; double freq = l->getProperty("Freq", UNIT_FREQ, FREQ_GHZ); if (freq > 0) s += QStringLiteral("\"log\" 1 \"%1 GHz\" 1 \"%2 GHz\" 1 "). arg(freq / 10).arg(freq * 10); else s += "\"lin\" 1 \"0 GHz\" 1 \"10 GHz\" 1 "; s += "\"51\" 1 \"no\" 0 \"1\" 0 \"2\" 0>\n"; s += QStringLiteral(" \n"). arg(l->getProperty("W", UNIT_LENGTH, LENGTH_MM)). arg(l->getProperty("L", UNIT_LENGTH, LENGTH_MM)). arg(l->getProperty("S", UNIT_LENGTH, LENGTH_MM)); s += "\n"; s += "\n"; s += " <100 80 160 80 \"\" 0 0 0 \"\">\n"; s += " <100 80 100 100 \"\" 0 0 0 \"\">\n"; s += " <140 140 140 170 \"\" 0 0 0 \"\">\n"; s += " <140 140 160 140 \"\" 0 0 0 \"\">\n"; s += " <320 80 320 100 \"\" 0 0 0 \"\">\n"; s += " <220 80 320 80 \"\" 0 0 0 \"\">\n"; s += " <280 140 280 190 \"\" 0 0 0 \"\">\n"; s += " <220 140 280 140 \"\" 0 0 0 \"\">\n"; s += "\n"; created++; } // create coaxial line schematic else if (mode == ModeCoaxial) { transline * l = TransLineTypes[ModeCoaxial].line; s += "\n"; s += " \n"; s +=" \n"; s += " \n"; s += " \n"; s += " <.SP SPTC1 1 90 240 0 51 0 0 "; double freq = l->getProperty("Freq", UNIT_FREQ, FREQ_GHZ); if (freq > 0) s += QStringLiteral("\"log\" 1 \"%1 GHz\" 1 \"%2 GHz\" 1 "). arg(freq / 10).arg(freq * 10); else s += "\"lin\" 1 \"0 GHz\" 1 \"10 GHz\" 1 "; s += "\"51\" 1 \"no\" 0 \"1\" 0 \"2\" 0>\n"; s += QStringLiteral(" \n"). arg(l->getProperty("Er")). arg(1 / l->getProperty("Sigma")). arg(l->getProperty("Mur")). arg(l->getProperty("dout", UNIT_LENGTH, LENGTH_MM)). arg(l->getProperty("din", UNIT_LENGTH, LENGTH_MM)). arg(l->getProperty("L", UNIT_LENGTH, LENGTH_MM)). arg(l->getProperty("Tand")); s += "\n"; s += "\n"; s += " <90 100 150 100 \"\" 0 0 0 \"\">\n"; s += " <90 100 90 120 \"\" 0 0 0 \"\">\n"; s += " <210 100 270 100 \"\" 0 0 0 \"\">\n"; s += " <270 100 270 120 \"\" 0 0 0 \"\">\n"; s += "\n"; created++; } // create coplanar schematic else if (mode == ModeCoplanar) { transline * l = TransLineTypes[ModeCoplanar].line; s += "\n"; s += " \n"; s +=" \n"; s += " \n"; s += " \n"; s += QStringLiteral(" \n"). arg(l->getProperty("Er")). arg(l->getProperty("H", UNIT_LENGTH, LENGTH_MM)). arg(l->getProperty("T", UNIT_LENGTH, LENGTH_UM)). arg(l->getProperty("Tand")). arg(1 / l->getProperty("Cond")); s += " <.SP SPTC1 1 90 240 0 51 0 0 "; double freq = l->getProperty("Freq", UNIT_FREQ, FREQ_GHZ); if (freq > 0) s += QStringLiteral("\"log\" 1 \"%1 GHz\" 1 \"%2 GHz\" 1 "). arg(freq / 10).arg(freq * 10); else s += "\"lin\" 1 \"0 GHz\" 1 \"10 GHz\" 1 "; s += "\"51\" 1 \"no\" 0 \"1\" 0 \"2\" 0>\n"; s += QStringLiteral(" \n"). arg(l->getProperty("W", UNIT_LENGTH, LENGTH_MM)). arg(l->getProperty("S", UNIT_LENGTH, LENGTH_MM)). arg(l->getProperty("L", UNIT_LENGTH, LENGTH_MM)); s += " \n"; s += "\n"; s += "\n"; s += " <90 100 150 100 \"\" 0 0 0 \"\">\n"; s += " <90 100 90 120 \"\" 0 0 0 \"\">\n"; s += " <210 100 270 100 \"\" 0 0 0 \"\">\n"; s += " <270 100 270 120 \"\" 0 0 0 \"\">\n"; s += "\n"; created++; } // create coplanar schematic else if (mode == ModeGroundedCoplanar) { transline * l = TransLineTypes[ModeGroundedCoplanar].line; s += "\n"; s += " \n"; s +=" \n"; s += " \n"; s += " \n"; s += QStringLiteral(" \n"). arg(l->getProperty("Er")). arg(l->getProperty("H", UNIT_LENGTH, LENGTH_MM)). arg(l->getProperty("T", UNIT_LENGTH, LENGTH_UM)). arg(l->getProperty("Tand")). arg(1 / l->getProperty("Cond")); s += " <.SP SPTC1 1 90 240 0 51 0 0 "; double freq = l->getProperty("Freq", UNIT_FREQ, FREQ_GHZ); if (freq > 0) s += QStringLiteral("\"log\" 1 \"%1 GHz\" 1 \"%2 GHz\" 1 "). arg(freq / 10).arg(freq * 10); else s += "\"lin\" 1 \"0 GHz\" 1 \"10 GHz\" 1 "; s += "\"51\" 1 \"no\" 0 \"1\" 0 \"2\" 0>\n"; s += QStringLiteral(" \n"). arg(l->getProperty("W", UNIT_LENGTH, LENGTH_MM)). arg(l->getProperty("S", UNIT_LENGTH, LENGTH_MM)). arg(l->getProperty("L", UNIT_LENGTH, LENGTH_MM)); s += " \n"; s += "\n"; s += "\n"; s += " <90 100 150 100 \"\" 0 0 0 \"\">\n"; s += " <90 100 90 120 \"\" 0 0 0 \"\">\n"; s += " <210 100 270 100 \"\" 0 0 0 \"\">\n"; s += " <270 100 270 120 \"\" 0 0 0 \"\">\n"; s += "\n"; created++; } // rectangular waveguide schematic else if (mode == ModeRectangular) { transline * l = TransLineTypes[ModeRectangular].line; s += "\n"; s += " \n"; s +=" \n"; s += " \n"; s += " \n"; s += " <.SP SPTC1 1 90 240 0 51 0 0 "; double freq = l->getProperty("Freq", UNIT_FREQ, FREQ_GHZ); if (freq > 0) s += QStringLiteral("\"log\" 1 \"%1 GHz\" 1 \"%2 GHz\" 1 "). arg(freq / 10).arg(freq * 10); else s += "\"lin\" 1 \"0 GHz\" 1 \"10 GHz\" 1 "; s += "\"51\" 1 \"no\" 0 \"1\" 0 \"2\" 0>\n"; s += QStringLiteral(" \n"). arg(l->getProperty("a", UNIT_LENGTH, LENGTH_MM)). arg(l->getProperty("b", UNIT_LENGTH, LENGTH_MM)). arg(l->getProperty("L", UNIT_LENGTH, LENGTH_MM)). arg(l->getProperty("Er")). arg(l->getProperty("Mur")). arg(l->getProperty("Tand")). arg(1 / l->getProperty("Cond")); s += " \n"; s += "\n"; s += "\n"; s += " <90 100 150 100 \"\" 0 0 0 \"\">\n"; s += " <90 100 90 120 \"\" 0 0 0 \"\">\n"; s += " <210 100 270 100 \"\" 0 0 0 \"\">\n"; s += " <270 100 270 120 \"\" 0 0 0 \"\">\n"; s += "\n"; created++; } // put resulting transmission line schematic into clipboard QClipboard *cb = QApplication::clipboard(); cb->setText(s); // put a message into status line if (created) statusBar()->showMessage(tr("Schematic copied into clipboard."), 2000); else statusBar()->showMessage(tr("Transmission line type not available."), 2000); }