diff --git a/widgets/MultiGeometryWidget.hpp b/widgets/MultiGeometryWidget.hpp new file mode 100644 index 000000000..a9386189c --- /dev/null +++ b/widgets/MultiGeometryWidget.hpp @@ -0,0 +1,92 @@ +#ifndef MULTI_GEOMETRY_WIDGET_HPP__ +#define MULTI_GEOMETRY_WIDGET_HPP__ + +#include +#include +#include + +#include +#include +#include + +// +// Class MultiGeometryWidget - Decorate a QWidget type with +// switchable geometries +// +// The abstract base class imbues a Qt Widget type with N alternative +// geometries. Sub-classes can initialise the currently selected +// geometry and the initial geometries using geometries. To switch +// geometry call select_geometry(n) which saves the current geometry +// and switches to the n'th saved geometry. +// +template +class MultiGeometryWidget + : public Widget +{ +public: + template + explicit MultiGeometryWidget (Args&&... args) + : Widget {std::forward (args)...} + , current_geometry_ {0} + { + } + + void geometries (std::size_t current + , std::array const& the_geometries = std::array {}) + { + Q_ASSERT (current < the_geometries.size ()); + saved_geometries_ = the_geometries; + current_geometry_ = current; + Widget::restoreGeometry (saved_geometries_[current_geometry_]); + } + + std::array const& geometries () const {return saved_geometries_;} + std::size_t current () {return current_geometry_;} + + // Call this to select a new geometry denoted by the 'n' argument, + // any actual layout changes should be made in the implementation of + // the change_layout operation below. + void select_geometry (std::size_t n) + { + Q_ASSERT (n < N); + auto geometry = Widget::saveGeometry (); + change_layout (n); + saved_geometries_[current_geometry_] = geometry; + current_geometry_ = n; + + // Defer restoration of the window geometry until the layour + // request event has been processed, this is necessary otherwise + // the final geometry may be affected by widgets not shown in the + // new layout. + desired_geometry_ = saved_geometries_[n]; + } + +protected: + virtual ~MultiGeometryWidget () {} + +private: + // Override this operation to implement any layout changes for the + // geometry specified by the argument 'n'. + virtual void change_layout (std::size_t n) = 0; + + bool event (QEvent * e) override + { + auto ret = Widget::event (e); + if (QEvent::LayoutRequest == e->type () + && desired_geometry_.size ()) + { + // Restore the new desired geometry and flag that we have done + // so by clearing the desired_geometry_ member variable. + QByteArray geometry; + std::swap (geometry, desired_geometry_); + Widget::restoreGeometry (geometry); + } + return ret; + } + + std::size_t current_geometry_; + std::array saved_geometries_; + QByteArray desired_geometry_; +}; + +#endif diff --git a/widgets/mainwindow.cpp b/widgets/mainwindow.cpp index 44a1af29e..eafa76545 100644 --- a/widgets/mainwindow.cpp +++ b/widgets/mainwindow.cpp @@ -236,7 +236,7 @@ MainWindow::MainWindow(QDir const& temp_directory, bool multiple, MultiSettings * multi_settings, QSharedMemory *shdmem, unsigned downSampleFactor, QSplashScreen * splash, QProcessEnvironment const& env, QWidget *parent) : - QMainWindow(parent), + MultiGeometryWidget {parent}, m_env {env}, m_network_manager {this}, m_valid {true}, @@ -1022,10 +1022,7 @@ MainWindow::MainWindow(QDir const& temp_directory, bool multiple, } ui->pbBestSP->setVisible(m_mode=="FT4"); - if(!ui->cbMenus->isChecked()) { - ui->cbMenus->setChecked(true); - ui->cbMenus->setChecked(false); - } + // this must be the last statement of constructor if (!m_valid) throw std::runtime_error {"Fatal initialization exception"}; } @@ -1094,8 +1091,33 @@ MainWindow::~MainWindow() void MainWindow::writeSettings() { m_settings->beginGroup("MainWindow"); - m_settings->setValue ("geometry", saveGeometry ()); - m_settings->setValue ("geometryNoControls", m_geometryNoControls); + if (ui->actionSWL_Mode->isChecked ()) + { + m_settings->setValue ("SWLView", true); + m_settings->setValue ("ShowMenus", ui->cbMenus->isChecked ()); + m_settings->setValue ("geometry", geometries ()[0]); + m_settings->setValue ("SWLModeGeometry", saveGeometry ()); + m_settings->setValue ("geometryNoControls", geometries ()[2]); + } + else + { + if (ui->cbMenus->isChecked()) + { + m_settings->setValue ("SWLView", ui->actionSWL_Mode->isChecked ()); + m_settings->setValue ("ShowMenus", true); + m_settings->setValue ("geometry", saveGeometry ()); + m_settings->setValue ("SWLModeGeometry", geometries ()[1]); + m_settings->setValue ("geometryNoControls", geometries ()[2]); + } + else + { + m_settings->setValue ("SWLView", ui->actionSWL_Mode->isChecked ()); + m_settings->setValue ("ShowMenus", false); + m_settings->setValue ("geometry", geometries ()[0]); + m_settings->setValue ("SWLModeGeometry", geometries ()[1]); + m_settings->setValue ("geometryNoControls", saveGeometry ()); + } + } m_settings->setValue ("state", saveState ()); m_settings->setValue("MRUdir", m_path); m_settings->setValue("TxFirst",m_txFirst); @@ -1105,7 +1127,6 @@ void MainWindow::writeSettings() m_settings->setValue ("MsgAvgDisplayed", m_msgAvgWidget && m_msgAvgWidget->isVisible ()); m_settings->setValue ("FoxLogDisplayed", m_foxLogWindow && m_foxLogWindow->isVisible ()); m_settings->setValue ("ContestLogDisplayed", m_contestLogWindow && m_contestLogWindow->isVisible ()); - m_settings->setValue("ShowMenus",ui->cbMenus->isChecked()); m_settings->setValue("CallFirst",ui->cbFirst->isChecked()); m_settings->setValue("HoundSort",ui->comboBoxHoundSort->currentIndex()); m_settings->setValue("FoxNlist",ui->sbNlist->value()); @@ -1159,9 +1180,8 @@ void MainWindow::writeSettings() m_settings->setValue("pwrBandTuneMemory",m_pwrBandTuneMemory); m_settings->setValue ("FT8AP", ui->actionEnable_AP_FT8->isChecked ()); m_settings->setValue ("JT65AP", ui->actionEnable_AP_JT65->isChecked ()); - m_settings->setValue("SplitterState",ui->splitter->saveState()); + m_settings->setValue("SplitterState",ui->decodes_splitter->saveState()); m_settings->setValue("Blanker",ui->sbNB->value()); - m_settings->setValue ("SWLView", ui->actionSWL_Mode->isChecked ()); { QList coeffs; // suitable for QSettings @@ -1180,8 +1200,17 @@ void MainWindow::readSettings() ui->cbAutoSeq->setVisible(false); ui->cbFirst->setVisible(false); m_settings->beginGroup("MainWindow"); - restoreGeometry (m_settings->value ("geometry", saveGeometry ()).toByteArray ()); - m_geometryNoControls = m_settings->value ("geometryNoControls",saveGeometry()).toByteArray(); + std::array the_geometries; + the_geometries[0] = m_settings->value ("geometry", saveGeometry ()).toByteArray (); + the_geometries[1] = m_settings->value ("SWLModeGeometry", saveGeometry ()).toByteArray (); + the_geometries[2] = m_settings->value ("geometryNoControls", saveGeometry ()).toByteArray (); + auto SWL_mode = m_settings->value ("SWLView", false).toBool (); + auto show_menus = m_settings->value ("ShowMenus", true).toBool (); + ui->actionSWL_Mode->setChecked (SWL_mode); + ui->cbMenus->setChecked (show_menus); + auto current_view_mode = SWL_mode ? 1 : show_menus ? 0 : 2; + change_layout (current_view_mode); + geometries (current_view_mode, the_geometries); restoreState (m_settings->value ("state", saveState ()).toByteArray ()); ui->dxCallEntry->setText (m_settings->value ("DXcall", QString {}).toString ()); ui->dxGridEntry->setText (m_settings->value ("DXgrid", QString {}).toString ()); @@ -1191,7 +1220,6 @@ void MainWindow::readSettings() auto displayMsgAvg = m_settings->value ("MsgAvgDisplayed", false).toBool (); auto displayFoxLog = m_settings->value ("FoxLogDisplayed", false).toBool (); auto displayContestLog = m_settings->value ("ContestLogDisplayed", false).toBool (); - ui->cbMenus->setChecked(m_settings->value("ShowMenus",true).toBool()); ui->cbFirst->setChecked(m_settings->value("CallFirst",true).toBool()); ui->comboBoxHoundSort->setCurrentIndex(m_settings->value("HoundSort",3).toInt()); ui->sbNlist->setValue(m_settings->value("FoxNlist",12).toInt()); @@ -1265,10 +1293,8 @@ void MainWindow::readSettings() m_pwrBandTuneMemory=m_settings->value("pwrBandTuneMemory").toHash(); ui->actionEnable_AP_FT8->setChecked (m_settings->value ("FT8AP", false).toBool()); ui->actionEnable_AP_JT65->setChecked (m_settings->value ("JT65AP", false).toBool()); - ui->splitter->restoreState(m_settings->value("SplitterState").toByteArray()); + ui->decodes_splitter->restoreState(m_settings->value("SplitterState").toByteArray()); ui->sbNB->setValue(m_settings->value("Blanker",0).toInt()); - ui->actionSWL_Mode->setChecked (m_settings->value ("SWLView", false).toBool ()); - on_actionSWL_Mode_triggered (ui->actionSWL_Mode->isChecked ()); { auto const& coeffs = m_settings->value ("PhaseEqualizationCoefficients" , QList {0., 0., 0., 0., 0.}).toList (); @@ -2568,34 +2594,47 @@ void MainWindow::on_actionCopyright_Notice_triggered() MessageBox::warning_message(this, message); } +// Implement the MultiGeometryWidget::change_layout() operation. +void MainWindow::change_layout (std::size_t n) +{ + switch (n) + { + case 1: // SWL view + ui->menuBar->show (); + ui->lower_panel_widget->hide (); + trim_view (false); // ensure we can switch back + break; + + case 2: // hide menus view + ui->menuBar->hide (); + ui->lower_panel_widget->show (); + trim_view (true); + break; + + default: // normal view + ui->menuBar->setVisible (ui->cbMenus->isChecked ()); + ui->lower_panel_widget->show (); + trim_view (!ui->cbMenus->isChecked ()); + break; + } +} + void MainWindow::on_actionSWL_Mode_triggered (bool checked) { - ui->lower_panel_widget->setVisible (!checked); - if (checked) - { - hideMenus (false); // make sure we can be turned off - } + select_geometry (checked ? 1 : ui->cbMenus->isChecked () ? 0 : 2); } // This allows the window to shrink by removing certain things // and reducing space used by controls -void MainWindow::hideMenus(bool checked) +void MainWindow::trim_view (bool checked) { int spacing = checked ? 1 : 6; if (checked) { statusBar ()->removeWidget (&auto_tx_label); - minimumSize().setHeight(450); - minimumSize().setWidth(700); - restoreGeometry(m_geometryNoControls); - updateGeometry(); } else { - m_geometryNoControls = saveGeometry(); statusBar ()->addWidget(&auto_tx_label); - minimumSize().setHeight(520); - minimumSize().setWidth(770); } - ui->menuBar->setVisible(!checked); - if(m_mode!="FreqCal" and m_mode!="WSPR" and m_mode!="FST4W") { + if (m_mode != "FreqCal" && m_mode != "WSPR" && m_mode != "FST4W") { ui->lh_decodes_title_label->setVisible(!checked); ui->rh_decodes_title_label->setVisible(!checked); } @@ -8437,7 +8476,7 @@ void MainWindow::update_watchdog_label () void MainWindow::on_cbMenus_toggled(bool b) { - hideMenus(!b); + select_geometry (!b ? 2 : ui->actionSWL_Mode->isChecked () ? 1 : 0); } void MainWindow::on_cbCQonly_toggled(bool) diff --git a/widgets/mainwindow.h b/widgets/mainwindow.h index c51a418de..dd53e8837 100644 --- a/widgets/mainwindow.h +++ b/widgets/mainwindow.h @@ -26,6 +26,7 @@ #include #include +#include "MultiGeometryWidget.hpp" #include "NonInheritingProcess.hpp" #include "Audio/AudioDevice.hpp" #include "commons.h" @@ -94,7 +95,8 @@ class MultiSettings; class EqualizationToolsDialog; class DecodedText; -class MainWindow : public QMainWindow +class MainWindow + : public MultiGeometryWidget<3, QMainWindow> { Q_OBJECT; @@ -130,7 +132,8 @@ public slots: void msgAvgDecode2(); void fastPick(int x0, int x1, int y); -protected: +private: + void change_layout (std::size_t) override; void keyPressEvent (QKeyEvent *) override; void closeEvent(QCloseEvent *) override; void childEvent(QChildEvent *) override; @@ -353,7 +356,7 @@ private: void astroUpdate (); void writeAllTxt(QString message); void auto_sequence (DecodedText const& message, unsigned start_tolerance, unsigned stop_tolerance); - void hideMenus(bool b); + void trim_view (bool b); void foxTest(); void setColorHighlighting(); void chkFT4(); diff --git a/widgets/mainwindow.ui b/widgets/mainwindow.ui index f4f1ed750..61affd377 100644 --- a/widgets/mainwindow.ui +++ b/widgets/mainwindow.ui @@ -2,20 +2,6 @@ MainWindow - - - 0 - 0 - 692 - 498 - - - - - 0 - 0 - - WSJT-X by K1JT @@ -25,7 +11,7 @@ - + Qt::Horizontal @@ -148,18 +134,6 @@ - - - 0 - 10 - - - - - 200 - 100 - - QFrame::StyledPanel @@ -307,12 +281,6 @@ true - - - 200 - 100 - - Qt::ScrollBarAlwaysOn @@ -2857,7 +2825,7 @@ Double-click to reset to the standard 73 message 0 0 - 692 + 834 21