From 4c940a940dd76b52fb0d8fa1be0170577ae8cdfa Mon Sep 17 00:00:00 2001 From: Vadim Kuznetsov Date: Wed, 20 Mar 2024 09:26:11 +0300 Subject: [PATCH 1/4] Add GUI controls to run RFLayout --- qucs/dialogs/qucssettingsdialog.cpp | 26 +++++++++++++++++++++----- qucs/dialogs/qucssettingsdialog.h | 3 ++- qucs/qucs.h | 3 ++- qucs/qucs_actions.cpp | 6 +++++- qucs/qucs_init.cpp | 7 +++++++ 5 files changed, 37 insertions(+), 8 deletions(-) diff --git a/qucs/dialogs/qucssettingsdialog.cpp b/qucs/dialogs/qucssettingsdialog.cpp index 873e9999..59e857e4 100644 --- a/qucs/dialogs/qucssettingsdialog.cpp +++ b/qucs/dialogs/qucssettingsdialog.cpp @@ -374,6 +374,13 @@ QucsSettingsDialog::QucsSettingsDialog(QucsApp *parent) locationsGrid->addWidget(OpenVAFButt, 5, 2); connect(OpenVAFButt, SIGNAL(clicked()), SLOT(slotOpenVAFDirBrowse())); + locationsGrid->addWidget(new QLabel(tr("RF Layout Path:"), locationsTab) ,6,0); + RFLayoutEdit = new QLineEdit(locationsTab); + locationsGrid->addWidget(RFLayoutEdit,6,1); + QPushButton *RFLButt = new QPushButton("Browse"); + locationsGrid->addWidget(RFLButt, 6, 2); + connect(RFLButt, SIGNAL(clicked()), SLOT(slotRFLayoutDirBrowse())); + // the pathsTableWidget displays the path list pathsTableWidget = new QTableWidget(locationsTab); @@ -394,20 +401,20 @@ QucsSettingsDialog::QucsSettingsDialog(QucsApp *parent) pathsTableWidget->setSelectionMode(QAbstractItemView::ExtendedSelection); connect(pathsTableWidget, SIGNAL(cellClicked(int,int)), SLOT(slotPathTableClicked(int,int))); connect(pathsTableWidget, SIGNAL(itemSelectionChanged()), SLOT(slotPathSelectionChanged())); - locationsGrid->addWidget(pathsTableWidget,6,0,3,2); + locationsGrid->addWidget(pathsTableWidget,7,0,3,2); QPushButton *AddPathButt = new QPushButton("Add Path"); - locationsGrid->addWidget(AddPathButt, 6, 2); + locationsGrid->addWidget(AddPathButt, 7, 2); connect(AddPathButt, SIGNAL(clicked()), SLOT(slotAddPath())); QPushButton *AddPathSubFolButt = new QPushButton("Add Path With SubFolders"); - locationsGrid->addWidget(AddPathSubFolButt, 7, 2); + locationsGrid->addWidget(AddPathSubFolButt, 8, 2); connect(AddPathSubFolButt, SIGNAL(clicked()), SLOT(slotAddPathWithSubFolders())); RemovePathButt = new QPushButton("Remove Path"); // disable button if no paths in the table are selected RemovePathButt->setEnabled(false); - locationsGrid->addWidget(RemovePathButt , 8, 2); + locationsGrid->addWidget(RemovePathButt , 9, 2); connect(RemovePathButt, SIGNAL(clicked()), SLOT(slotRemovePath())); // create a copy of the current global path list @@ -1010,12 +1017,21 @@ void QucsSettingsDialog::slotOctaveDirBrowse() void QucsSettingsDialog::slotOpenVAFDirBrowse() { QString d = QFileDialog::getOpenFileName(this, tr("Select the OpenVAF executable"), - octaveEdit->text(), "All files (*)"); + OpenVAFEdit->text(), "All files (*)"); if(!d.isEmpty()) OpenVAFEdit->setText(d); } +void QucsSettingsDialog::slotRFLayoutDirBrowse() +{ + QString d = QFileDialog::getOpenFileName(this, tr("Select the Qucs-RFLayout executable"), + RFLayoutEdit->text(), "All files (*)"); + + if(!d.isEmpty()) + RFLayoutEdit->setText(d); +} + /*! \brief (seems unused at present) */ void QucsSettingsDialog::slotPathTableClicked(int row, int col) diff --git a/qucs/dialogs/qucssettingsdialog.h b/qucs/dialogs/qucssettingsdialog.h index 4df87526..ddcfe395 100644 --- a/qucs/dialogs/qucssettingsdialog.h +++ b/qucs/dialogs/qucssettingsdialog.h @@ -71,6 +71,7 @@ private slots: void slotAscoDirBrowse(); void slotOctaveDirBrowse(); void slotOpenVAFDirBrowse(); + void slotRFLayoutDirBrowse(); void slotAddPath(); void slotAddPathWithSubFolders(); @@ -91,7 +92,7 @@ public: QPushButton *FontButton, *AppFontButton, *TextFontButton, *BGColorButton; QLineEdit *LargeFontSizeEdit, *undoNumEdit, *editorEdit, *Input_Suffix, *Input_Program, *homeEdit, *admsXmlEdit, *ascoEdit, *octaveEdit, - *OpenVAFEdit; + *OpenVAFEdit, *RFLayoutEdit; QTableWidget *fileTypesTableWidget, *pathsTableWidget; QStandardItemModel *model; QPushButton *ColorComment, *ColorString, *ColorInteger, diff --git a/qucs/qucs.h b/qucs/qucs.h index 8bcf5834..19dd7357 100644 --- a/qucs/qucs.h +++ b/qucs/qucs.h @@ -355,7 +355,7 @@ public: *distrHor, *distrVert, *selectAll, *callMatch, *changeProps, *addToProj, *editFind, *insEntity, *selectMarker, *createLib, *importData, *graph2csv, *createPkg, *extractPkg, - *callAtt, *centerHor, *centerVert, *loadModule, *buildModule, *callPwrComb; + *callAtt, *centerHor, *centerVert, *loadModule, *buildModule, *callPwrComb, *callRFLayout; QAction *helpQucsIndex; QAction *simSettings; @@ -406,6 +406,7 @@ public slots: void slotCallMatch(); void slotCallAtt(); void slotCallPwrComb(); + void slotCallRFLayout(); void slotHelpIndex(); // shows a HTML docu: Help Index void slotHelpQucsIndex(); void slotGettingStarted(); // shows a HTML docu: Getting started diff --git a/qucs/qucs_actions.cpp b/qucs/qucs_actions.cpp index 58c31247..5a6af5a2 100644 --- a/qucs/qucs_actions.cpp +++ b/qucs/qucs_actions.cpp @@ -890,7 +890,6 @@ void QucsApp::slotCallPwrComb() launchTool(QUCS_NAME "powercombining", "power combining calculation",QStringList()); } - /*! * \brief launch an external application passing arguments * @@ -930,6 +929,11 @@ void QucsApp::launchTool(const QString& prog, const QString& progDesc, const QSt } +void QucsApp::slotCallRFLayout() +{ + +} + // -------------------------------------------------------------- void QucsApp::slotHelpIndex() { diff --git a/qucs/qucs_init.cpp b/qucs/qucs_init.cpp index 35f0d15b..33d0dd7a 100644 --- a/qucs/qucs_init.cpp +++ b/qucs/qucs_init.cpp @@ -537,6 +537,12 @@ void QucsApp::initActions() callPwrComb->setWhatsThis(tr("Power combining\n\nStarts power combining calculation program")); connect(callPwrComb, SIGNAL(triggered()), SLOT(slotCallPwrComb())); + callRFLayout = new QAction(tr("RF Layout"), this); + callRFLayout->setShortcut(tr("Ctrl+8")); + callRFLayout->setStatusTip(tr("Starts Qucs-RFLayout")); + callRFLayout->setWhatsThis(tr("Power combining\n\nStarts power combining calculation program")); + connect(callRFLayout, SIGNAL(triggered()), SLOT(slotCallRFLayout())); + simulate = new QAction(QIcon((":/bitmaps/svg/gear.svg")), tr("Simulate"), this); simulate->setShortcut(Qt::Key_F2); simulate->setStatusTip(tr("Simulates the current schematic")); @@ -774,6 +780,7 @@ void QucsApp::initMenuBar() toolMenu->addAction(callMatch); toolMenu->addAction(callAtt); toolMenu->addAction(callPwrComb); + toolMenu->addAction(callRFLayout); toolMenu->addSeparator(); cmMenu = new QMenu(tr("Compact modelling")); From cf375c5aa5691dba04437bdbaca46afe3237b4d8 Mon Sep 17 00:00:00 2001 From: Vadim Kuznetsov Date: Wed, 20 Mar 2024 09:33:33 +0300 Subject: [PATCH 2/4] Add setting to hold RFlayout tool location --- qucs/dialogs/qucssettingsdialog.cpp | 2 ++ qucs/main.cpp | 6 ++++++ qucs/main.h | 1 + 3 files changed, 9 insertions(+) diff --git a/qucs/dialogs/qucssettingsdialog.cpp b/qucs/dialogs/qucssettingsdialog.cpp index 59e857e4..a89b8959 100644 --- a/qucs/dialogs/qucssettingsdialog.cpp +++ b/qucs/dialogs/qucssettingsdialog.cpp @@ -475,6 +475,7 @@ QucsSettingsDialog::QucsSettingsDialog(QucsApp *parent) ascoEdit->setText(QucsSettings.AscoBinDir.canonicalPath()); octaveEdit->setText(QucsSettings.OctaveExecutable); OpenVAFEdit->setText(QucsSettings.OpenVAFExecutable); + RFLayoutEdit->setText(QucsSettings.RFLayoutExecutable); resize(300, 200); @@ -674,6 +675,7 @@ void QucsSettingsDialog::slotApply() QucsSettings.AscoBinDir.setPath(ascoEdit->text()); QucsSettings.OctaveExecutable = octaveEdit->text(); QucsSettings.OpenVAFExecutable = OpenVAFEdit->text(); + QucsSettings.RFLayoutExecutable = RFLayoutEdit->text(); if (QucsSettings.IgnoreFutureVersion != checkLoadFromFutureVersions->isChecked()) { diff --git a/qucs/main.cpp b/qucs/main.cpp index 58055b3a..3dddbfd6 100644 --- a/qucs/main.cpp +++ b/qucs/main.cpp @@ -171,6 +171,11 @@ bool loadSettings() } else { QucsSettings.OpenVAFExecutable = "openvaf" + QString(executableSuffix); } + if(settings.contains("RFLayoutExecutable")) { + QucsSettings.RFLayoutExecutable = settings.value("RFLayoutExecutable").toString(); + } else { + QucsSettings.RFLayoutExecutable = "qucsrflayout" + QString(executableSuffix); + } if(settings.contains("QucsHomeDir")) if(settings.value("QucsHomeDir").toString() != "") QucsSettings.QucsHomeDir.setPath(settings.value("QucsHomeDir").toString()); @@ -272,6 +277,7 @@ bool saveApplSettings() // settings.setValue("OctaveBinDir", QucsSettings.OctaveBinDir.canonicalPath()); settings.setValue("OctaveExecutable",QucsSettings.OctaveExecutable); settings.setValue("OpenVAFExecutable",QucsSettings.OpenVAFExecutable); + settings.setValue("RFLayoutExecutable",QucsSettings.RFLayoutExecutable); settings.setValue("QucsHomeDir", QucsSettings.QucsHomeDir.canonicalPath()); settings.setValue("IgnoreVersion", QucsSettings.IgnoreFutureVersion); settings.setValue("GraphAntiAliasing", QucsSettings.GraphAntiAliasing); diff --git a/qucs/main.h b/qucs/main.h index 36144c48..65084926 100644 --- a/qucs/main.h +++ b/qucs/main.h @@ -91,6 +91,7 @@ struct tQucsSettings { unsigned int NProcs; // Number of processors for Xyce QString OctaveExecutable; // OctaveExecutable location QString QucsOctave; // OUCS_OCTAVE variable + QString RFLayoutExecutable; // registered filename extensions with program to open the file QStringList FileTypes; From 70bef65cf080c480d6d3cd6b9879e8ed8abde091 Mon Sep 17 00:00:00 2001 From: Vadim Kuznetsov Date: Wed, 20 Mar 2024 09:55:17 +0300 Subject: [PATCH 3/4] Implement tool launch and schematic read --- qucs/qucs_actions.cpp | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/qucs/qucs_actions.cpp b/qucs/qucs_actions.cpp index 5a6af5a2..ea0bd551 100644 --- a/qucs/qucs_actions.cpp +++ b/qucs/qucs_actions.cpp @@ -931,7 +931,36 @@ void QucsApp::launchTool(const QString& prog, const QString& progDesc, const QSt void QucsApp::slotCallRFLayout() { + QString input_file; + if (!isTextDocument(DocumentTab->currentWidget())) { + Schematic *sch = (Schematic*)DocumentTab->currentWidget(); + if(sch->fileSuffix() == "dpl") { + QMessageBox::critical(this,tr("Error"), + tr("Layouting of display pages is not supported!")); + return; + } + input_file = sch->DocName; + } else { + QMessageBox::critical(this,tr("Error"), + tr("Layouting of text documents is not supported!")); + return; + } + QProcess *tool = new QProcess(); + QStringList args; + args.append("-G"); + args.append("-i"); + args.append(input_file); + tool->start(QucsSettings.RFLayoutExecutable,args); + + if(!tool->waitForStarted(1000) ) { + QMessageBox::critical(this, tr("Error"), + tr("Cannot start Qucs-RFLayout: \n%1") + .arg(QucsSettings.RFLayoutExecutable)); + delete tool; + return; + } + connect(this, SIGNAL(signalKillEmAll()), tool, SLOT(kill())); } // -------------------------------------------------------------- From f8878aabfd77e06623d13cf7c2b1d89b4f59c04f Mon Sep 17 00:00:00 2001 From: Vadim Kuznetsov Date: Wed, 20 Mar 2024 10:46:22 +0300 Subject: [PATCH 4/4] Generate netlist without Qucs invocation --- qucs/qucs_actions.cpp | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/qucs/qucs_actions.cpp b/qucs/qucs_actions.cpp index ea0bd551..ca2d8cf0 100644 --- a/qucs/qucs_actions.cpp +++ b/qucs/qucs_actions.cpp @@ -931,7 +931,7 @@ void QucsApp::launchTool(const QString& prog, const QString& progDesc, const QSt void QucsApp::slotCallRFLayout() { - QString input_file; + QString input_file, netlist_file, odir; if (!isTextDocument(DocumentTab->currentWidget())) { Schematic *sch = (Schematic*)DocumentTab->currentWidget(); if(sch->fileSuffix() == "dpl") { @@ -940,6 +940,26 @@ void QucsApp::slotCallRFLayout() return; } input_file = sch->DocName; + QFileInfo inf(sch->DocName); + odir = inf.absolutePath(); + netlist_file = inf.absolutePath() + QDir::separator() + + inf.baseName() + ".net"; + QFile f(netlist_file); + if (!f.open(QIODevice::WriteOnly)) { + QMessageBox::critical(this, tr("Error"), tr("Cannot write netlist!")); + return; + } + QTextStream stream(&f); + QStringList Collect; + QPlainTextEdit *ErrText = new QPlainTextEdit(); //dummy + int pNum = sch->prepareNetlist(stream, Collect, ErrText); + if (!sch->isAnalog) { + QMessageBox::critical(this, tr("Error"), tr("Digital schematic not supported!")); + return; + } + stream << '\n'; + sch->createNetlist(stream, pNum); + f.close(); } else { QMessageBox::critical(this,tr("Error"), tr("Layouting of text documents is not supported!")); @@ -951,6 +971,10 @@ void QucsApp::slotCallRFLayout() args.append("-G"); args.append("-i"); args.append(input_file); + args.append("-n"); + args.append(netlist_file); + args.append("-o"); + args.append(odir); tool->start(QucsSettings.RFLayoutExecutable,args); if(!tool->waitForStarted(1000) ) {