mirror of
https://github.com/ra3xdh/qucs_s
synced 2025-03-28 21:13:26 +00:00
1512 lines
52 KiB
C++
1512 lines
52 KiB
C++
/***************************************************************************
|
|
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 <config.h>
|
|
#endif
|
|
|
|
#include <QDate>
|
|
#include <QTime>
|
|
#include <QLayout>
|
|
#include <QPushButton>
|
|
#include <QFile>
|
|
#include <QTextStream>
|
|
#include <QMessageBox>
|
|
#include <QToolButton>
|
|
#include <QImage>
|
|
#include <QFileDialog>
|
|
#include <QMenuBar>
|
|
#include <QAction>
|
|
#include <QGroupBox>
|
|
#include <QComboBox>
|
|
#include <QLabel>
|
|
#include <QLineEdit>
|
|
#include <QImage>
|
|
#include <QIcon>
|
|
#include <QToolTip>
|
|
#include <QRadioButton>
|
|
#include <QStatusBar>
|
|
#include <QDir>
|
|
#include <QButtonGroup>
|
|
#include <QStackedWidget>
|
|
#include <QRegularExpression>
|
|
#include <QValidator>
|
|
#include <QClipboard>
|
|
#include <QApplication>
|
|
#include <QPixmap>
|
|
#include <QVBoxLayout>
|
|
#include <QCloseEvent>
|
|
#include <QAction>
|
|
#include <QDebug>
|
|
|
|
#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 == "</" + QString(TransLineTypes[i].description) + ">")
|
|
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 << "</" << t->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 = "<Qucs Schematic " PACKAGE_VERSION ">\n";
|
|
|
|
// create microstrip schematic
|
|
if (mode == ModeMicrostrip) {
|
|
transline * l = TransLineTypes[ModeMicrostrip].line;
|
|
s += "<Components>\n";
|
|
s += " <Pac P1 1 90 150 -74 -26 1 1 \"1\" 1 \"50 Ohm\" 1 \"0 dBm\" 0 \"1 GHz\" 0 \"26.85\" 0>\n";
|
|
s +=" <Pac P2 1 270 150 18 -26 0 1 \"2\" 1 \"50 Ohm\" 1 \"0 dBm\" 0 \"1 GHz\" 0 \"26.85\" 0>\n";
|
|
s += " <GND * 1 90 180 0 0 0 0>\n";
|
|
s += " <GND * 1 270 180 0 0 0 0>\n";
|
|
s += QString(" <SUBST SubstTC1 1 390 140 -30 24 0 0 \"%1\" 1 \"%2 mm\" 1 \"%3 um\" 1 \"%4\" 1 \"%5\" 1 \"%6\" 1>\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 += QString("\"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 += QString(" <MLIN MSTC1 1 180 100 -26 15 0 0 \"SubstTC1\" 1 \"%1 mm\" 1 \"%2 mm\" 1 \"Hammerstad\" 0 \"Kirschning\" 0 \"26.85\" 0>\n").
|
|
arg(l->getProperty("W", UNIT_LENGTH, LENGTH_MM)).
|
|
arg(l->getProperty("L", UNIT_LENGTH, LENGTH_MM));
|
|
s += " <Eqn EqnTC1 1 240 260 -23 12 0 0 \"A=twoport(S,'S','A')\" 1 \"ZL=real(sqrt(A[1,2]/A[2,1]))\" 1 \"yes\" 0>\n";
|
|
s += "</Components>\n";
|
|
s += "<Wires>\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 += "</Wires>\n";
|
|
created++;
|
|
}
|
|
|
|
// create coupled microstrip schematic
|
|
else if (mode == ModeCoupledMicrostrip) {
|
|
transline * l = TransLineTypes[ModeCoupledMicrostrip].line;
|
|
s += "<Components>\n";
|
|
s += " <Pac P1 1 100 130 -74 -26 1 1 \"1\" 1 \"50 Ohm\" 1 \"0 dBm\" 0 \"1 GHz\" 0 \"26.85\" 0>\n";
|
|
s += " <Pac P2 1 320 130 18 -26 0 1 \"2\" 1 \"50 Ohm\" 1 \"0 dBm\" 0 \"1 GHz\" 0 \"26.85\" 0>\n";
|
|
s += " <Pac P3 1 280 220 18 -26 0 1 \"3\" 1 \"50 Ohm\" 1 \"0 dBm\" 0 \"1 GHz\" 0 \"26.85\" 0>\n";
|
|
s += " <Pac P4 1 140 200 -74 -26 1 1 \"4\" 1 \"50 Ohm\" 1 \"0 dBm\" 0 \"1 GHz\" 0 \"26.85\" 0>\n";
|
|
s += " <GND * 1 100 160 0 0 0 0>\n";
|
|
s += " <GND * 1 140 230 0 0 0 0>\n";
|
|
s += " <GND * 1 320 160 0 0 0 0>\n";
|
|
s += " <GND * 1 280 250 0 0 0 0>\n";
|
|
s += QString(" <SUBST SubstTC1 1 410 220 -30 24 0 0 \"%1\" 1 \"%2 mm\" 1 \"%3 um\" 1 \"%4\" 1 \"%5\" 1 \"%6\" 1>\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 += QString("\"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 += QString(" <MCOUPLED MSTC1 1 190 110 -26 37 0 0 \"SubstTC1\" 1 \"%1 mm\" 1 \"%2 mm\" 1 \"%3 mm\" 1 \"Kirschning\" 0 \"Kirschning\" 0 \"26.85\" 0>\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 += "</Components>\n";
|
|
s += "<Wires>\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 += "</Wires>\n";
|
|
created++;
|
|
}
|
|
|
|
// create coaxial line schematic
|
|
else if (mode == ModeCoaxial) {
|
|
transline * l = TransLineTypes[ModeCoaxial].line;
|
|
s += "<Components>\n";
|
|
s += " <Pac P1 1 90 150 -74 -26 1 1 \"1\" 1 \"50 Ohm\" 1 \"0 dBm\" 0 \"1 GHz\" 0 \"26.85\" 0>\n";
|
|
s +=" <Pac P2 1 270 150 18 -26 0 1 \"2\" 1 \"50 Ohm\" 1 \"0 dBm\" 0 \"1 GHz\" 0 \"26.85\" 0>\n";
|
|
s += " <GND * 1 90 180 0 0 0 0>\n";
|
|
s += " <GND * 1 270 180 0 0 0 0>\n";
|
|
s += " <.SP SPTC1 1 90 240 0 51 0 0 ";
|
|
double freq = l->getProperty("Freq", UNIT_FREQ, FREQ_GHZ);
|
|
if (freq > 0)
|
|
s += QString("\"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 += QString(" <COAX CXTC1 1 180 100 -26 15 0 0 \"%1\" 1 \"%2\" 0 \"%3\" 0 \"%4 mm\" 1 \"%5 mm\" 1 \"%6 mm\" 1 \"%7\" 0 \"26.85\" 0>\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 += "</Components>\n";
|
|
s += "<Wires>\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 += "</Wires>\n";
|
|
created++;
|
|
}
|
|
|
|
// create coplanar schematic
|
|
else if (mode == ModeCoplanar) {
|
|
transline * l = TransLineTypes[ModeCoplanar].line;
|
|
s += "<Components>\n";
|
|
s += " <Pac P1 1 90 150 -74 -26 1 1 \"1\" 1 \"50 Ohm\" 1 \"0 dBm\" 0 \"1 GHz\" 0 \"26.85\" 0>\n";
|
|
s +=" <Pac P2 1 270 150 18 -26 0 1 \"2\" 1 \"50 Ohm\" 1 \"0 dBm\" 0 \"1 GHz\" 0 \"26.85\" 0>\n";
|
|
s += " <GND * 1 90 180 0 0 0 0>\n";
|
|
s += " <GND * 1 270 180 0 0 0 0>\n";
|
|
s += QString(" <SUBST SubstTC1 1 390 140 -30 24 0 0 \"%1\" 1 \"%2 mm\" 1 \"%3 um\" 1 \"%4\" 1 \"%5\" 1 \"0\" 1>\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 += QString("\"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 += QString(" <CLIN CLTC1 1 180 100 -26 25 0 0 \"SubstTC1\" 1 \"%1 mm\" 1 \"%2 mm\" 1 \"%3 mm\" 1 \"Air\" 1 \"yes\" 0>\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 += " <Eqn EqnTC1 1 240 260 -23 12 0 0 \"A=twoport(S,'S','A')\" 1 \"ZL=real(sqrt(A[1,2]/A[2,1]))\" 1 \"yes\" 0>\n";
|
|
s += "</Components>\n";
|
|
s += "<Wires>\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 += "</Wires>\n";
|
|
created++;
|
|
}
|
|
|
|
// create coplanar schematic
|
|
else if (mode == ModeGroundedCoplanar) {
|
|
transline * l = TransLineTypes[ModeGroundedCoplanar].line;
|
|
s += "<Components>\n";
|
|
s += " <Pac P1 1 90 150 -74 -26 1 1 \"1\" 1 \"50 Ohm\" 1 \"0 dBm\" 0 \"1 GHz\" 0 \"26.85\" 0>\n";
|
|
s +=" <Pac P2 1 270 150 18 -26 0 1 \"2\" 1 \"50 Ohm\" 1 \"0 dBm\" 0 \"1 GHz\" 0 \"26.85\" 0>\n";
|
|
s += " <GND * 1 90 180 0 0 0 0>\n";
|
|
s += " <GND * 1 270 180 0 0 0 0>\n";
|
|
s += QString(" <SUBST SubstTC1 1 390 140 -30 24 0 0 \"%1\" 1 \"%2 mm\" 1 \"%3 um\" 1 \"%4\" 1 \"%5\" 1 \"0\" 1>\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 += QString("\"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 += QString(" <CLIN CLTC1 1 180 100 -26 25 0 0 \"SubstTC1\" 1 \"%1 mm\" 1 \"%2 mm\" 1 \"%3 mm\" 1 \"Metal\" 1 \"yes\" 0>\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 += " <Eqn EqnTC1 1 240 260 -23 12 0 0 \"A=twoport(S,'S','A')\" 1 \"ZL=real(sqrt(A[1,2]/A[2,1]))\" 1 \"yes\" 0>\n";
|
|
s += "</Components>\n";
|
|
s += "<Wires>\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 += "</Wires>\n";
|
|
created++;
|
|
}
|
|
|
|
// rectangular waveguide schematic
|
|
else if (mode == ModeRectangular) {
|
|
transline * l = TransLineTypes[ModeRectangular].line;
|
|
s += "<Components>\n";
|
|
s += " <Pac P1 1 90 150 -74 -26 1 1 \"1\" 1 \"50 Ohm\" 1 \"0 dBm\" 0 \"1 GHz\" 0 \"26.85\" 0>\n";
|
|
s +=" <Pac P2 1 270 150 18 -26 0 1 \"2\" 1 \"50 Ohm\" 1 \"0 dBm\" 0 \"1 GHz\" 0 \"26.85\" 0>\n";
|
|
s += " <GND * 1 90 180 0 0 0 0>\n";
|
|
s += " <GND * 1 270 180 0 0 0 0>\n";
|
|
s += " <.SP SPTC1 1 90 240 0 51 0 0 ";
|
|
double freq = l->getProperty("Freq", UNIT_FREQ, FREQ_GHZ);
|
|
if (freq > 0)
|
|
s += QString("\"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 += QString(" <RECTLINE RLTC1 1 180 100 -26 25 0 0 \"%1 mm\" 1 \"%2 mm\" 1 \"%3 mm\" 1 \"%4\" 0 \"%5\" 0 \"%6\" 0 \"%7\" 0 \"26.85\" 0>\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 += " <Eqn EqnTC1 1 240 260 -23 12 0 0 \"A=twoport(S,'S','A')\" 1 \"ZL=real(sqrt(A[1,2]/A[2,1]))\" 1 \"yes\" 0>\n";
|
|
s += "</Components>\n";
|
|
s += "<Wires>\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 += "</Wires>\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);
|
|
}
|