feat(cpn): add "use saved settings" option to application and profiles settings (#6999)

This commit is contained in:
Neil Horne
2026-01-25 09:39:50 +10:00
committed by GitHub
parent fbf96600a3
commit 87b2788884
9 changed files with 914 additions and 793 deletions
+4
View File
@@ -103,6 +103,7 @@ void AppPreferencesDialog::accept()
g.fwTraceLog(ui->opt_fwTraceLog->isChecked());
g.appLogsDir(ui->appLogsDir->text());
g.runAppInstaller(ui->chkPromptInstall->isChecked());
g.useSavedSettings(ui->chkUseSavedSettingsApp->isChecked());
// Simulator tab
g.simuSW(ui->simuSW->isChecked());
@@ -181,6 +182,7 @@ void AppPreferencesDialog::accept()
profile.splashFile(ui->SplashFileName->text());
profile.runSDSync(ui->chkPromptSDSync->isChecked());
profile.radioSimCaseColor(ui->lblRadioColorSample->palette().button().color());
profile.useSavedSettings(ui->chkUseSavedSettingsProfile->isChecked());
// The profile name may NEVER be empty
if (ui->profileNameLE->text().isEmpty())
@@ -294,6 +296,7 @@ void AppPreferencesDialog::initSettings()
ui->cboSimuGenericKeysPos->setCurrentIndex(g.simuGenericKeysPos());
ui->chkSimuScrollButtons->setChecked(g.simuScrollButtons());
ui->joystickWarningCB->setChecked(g.disableJoystickWarning());
ui->chkUseSavedSettingsApp->setChecked(g.useSavedSettings());
#if defined(USE_SDL)
ui->joystickChkB->setChecked(g.jsSupport());
@@ -373,6 +376,7 @@ void AppPreferencesDialog::initSettings()
hwSettings = tr("AVAILABLE: Radio settings stored %1").arg(str);
}
ui->chkUseSavedSettingsProfile->setChecked(profile.useSavedSettings());
ui->lblGeneralSettings->setText(hwSettings);
ui->chkPromptSDSync->setChecked(profile.runSDSync());
ui->lblRadioColorSample->setPalette(QPalette(profile.radioSimCaseColor()));
File diff suppressed because it is too large Load Diff
+75 -30
View File
@@ -41,9 +41,8 @@ GeneralEdit::GeneralEdit(QWidget * parent, RadioData & radioData, Firmware * fir
firmware(firmware)
{
ui->setupUi(this);
this->setWindowIcon(CompanionIcon("open.png"));
ui->btnLoadSettings->setDisabled(g.currentProfile().generalSettings().isEmpty());
ui->btnClearSettings->setDisabled(g.currentProfile().generalSettings().isEmpty());
setWindowIcon(CompanionIcon("open.png"));
setAttribute(Qt::WA_DeleteOnClose);
editorItemModels = new CompoundItemModelFactory(&generalSettings, nullptr);
// tabs created below expect these item models to be pre-registered
@@ -64,9 +63,16 @@ GeneralEdit::GeneralEdit(QWidget * parent, RadioData & radioData, Firmware * fir
if (firmware->getCapability(KeyShortcuts))
addTab(new GeneralKeysPanel(this, generalSettings, firmware), tr("Key Shortcuts"));
connect(hwpnl, &HardwarePanel::internalModuleChanged, this, [&] { intModChanged = true; });
ui->btnSettingsRestore->setDisabled(g.currentProfile().generalSettings().isEmpty());
ui->btnSettingsBackupDelete->setDisabled(g.currentProfile().generalSettings().isEmpty());
ui->tabWidget->setCurrentIndex( g.generalEditTab() );
connect(hwpnl, &HardwarePanel::internalModuleChanged, this, [&] { intModChanged = true; });
connect(ui->btnSettingsBackup, &QPushButton::clicked, this, &GeneralEdit::on_btnSettingsBackupClicked);
connect(ui->btnSettingsRestore, &QPushButton::clicked, this, &GeneralEdit::on_btnSettingsRestoreClicked);
connect(ui->btnSettingsBackupDelete, &QPushButton::clicked, this, &GeneralEdit::on_btnSettingsBackupDeleteClicked);
connect(ui->btnSettingsDefaults, &QPushButton::clicked, this, &GeneralEdit::on_btnSettingsDefaultsClicked);
ui->tabWidget->setCurrentIndex(g.generalEditTab());
}
GeneralEdit::~GeneralEdit()
@@ -103,62 +109,101 @@ void GeneralEdit::on_tabWidget_currentChanged(int index)
panels[index]->update();
}
void GeneralEdit::on_btnLoadSettings_clicked()
void GeneralEdit::on_btnSettingsRestoreClicked()
{
if (QMessageBox::question(this, tr("Profile Radio Settings"),
tr("WARNING: Loading settings from profile is irreversable.\n\nAre you sure?"),
if (QMessageBox::question(this, tr("Radio Settings"),
tr("WARNING: Restore settings from profile.\n\nAre you sure?"),
QMessageBox::Yes | QMessageBox::No, QMessageBox::No) == QMessageBox::No)
return;
const unsigned int oldIntMod = generalSettings.internalModule;
QByteArray data = g.currentProfile().generalSettings();
try {
if (!loadRadioSettingsFromYaml(generalSettings, data)) {
QMessageBox::critical(this, tr("Profile Radio Settings"), tr("Unable to load settings from profile!"));
QMessageBox::critical(this, tr("Radio Settings"), tr("Unable to restore settings from profile!"));
return;
}
} catch(const std::runtime_error& e) {
QMessageBox::critical(this, tr("Profile Radio Settings"),
tr("Unable to load settings from profile!") + ":\n" + QString(e.what()));
QMessageBox::critical(this, tr("Radio Settings"),
tr("Unable to restore settings from profile!") + ":\n" + QString(e.what()));
return;
}
on_tabWidget_currentChanged(ui->tabWidget->currentIndex());
QMessageBox::information(this, tr("Profile Radio Settings"),
tr("Settings successfully loaded.") + "\n\n" +
tr("The Radio Settings window will now be closed for the settings to take effect"));
postSettingsChangeMsg(oldIntMod);
emit modified();
accept();
closeEvent(new QCloseEvent());
done(-1);
}
void GeneralEdit::on_btnSaveSettings_clicked()
void GeneralEdit::on_btnSettingsBackupClicked()
{
if (QMessageBox::question(this, tr("Profile Radio Settings"),
tr("WARNING: Saving settings to the profile is irreversable.\n\nAre you sure?"),
if (QMessageBox::question(this, tr("Radio Settings"),
tr("WARNING: Backup settings to profile.\n\nAre you sure?"),
QMessageBox::Yes | QMessageBox::No, QMessageBox::No) == QMessageBox::No)
return;
QByteArray data;
writeRadioSettingsToYaml(generalSettings, data);
try {
if (!writeRadioSettingsToYaml(generalSettings, data)) {
QMessageBox::critical(this, tr("Radio Settings"), tr("Unable to backup settings to profile!"));
return;
}
} catch(const std::runtime_error& e) {
QMessageBox::critical(this, tr("Radio Settings"),
tr("Unable to backup settings to profile!") + ":\n" + QString(e.what()));
return;
}
g.currentProfile().generalSettings(data);
QDateTime dateTime = QDateTime::currentDateTime();
g.currentProfile().timeStamp(dateTime.toString("yyyy-MM-dd hh:mm"));
ui->btnLoadSettings->setEnabled(true);
ui->btnClearSettings->setEnabled(true);
QMessageBox::information(this, tr("Save Radio Settings to Profile"), tr("Settings saved to profile."));
ui->btnSettingsRestore->setEnabled(true);
ui->btnSettingsBackupDelete->setEnabled(true);
QMessageBox::information(this, tr("Radio Settings"), tr("Settings saved to profile."));
}
void GeneralEdit::on_btnClearSettings_clicked()
void GeneralEdit::on_btnSettingsBackupDeleteClicked()
{
if (QMessageBox::question(this, tr("Profile Radio Settings"),
tr("WARNING: Clearing settings from the profile is irreversable.\n\nAre you sure?"),
if (QMessageBox::question(this, tr("Radio Settings"),
tr("WARNING: Delete settings backup from profile.\n\nAre you sure?"),
QMessageBox::Yes | QMessageBox::No, QMessageBox::No) == QMessageBox::No)
return;
g.currentProfile().generalSettings(QByteArray());
g.currentProfile().timeStamp(QString());
ui->btnLoadSettings->setEnabled(false);
ui->btnClearSettings->setEnabled(false);
QMessageBox::information(this, tr("Profile Radio Settings"), tr("Settings cleared from profile."));
ui->btnSettingsRestore->setEnabled(false);
ui->btnSettingsBackupDelete->setEnabled(false);
QMessageBox::information(this, tr("Radio Settings"), tr("Settings backup deleted from profile."));
}
void GeneralEdit::on_btnSettingsDefaultsClicked()
{
if (QMessageBox::question(this, tr("Radio Settings"),
tr("WARNING: Reset settings to defaults.\n\nAre you sure?"),
QMessageBox::Yes | QMessageBox::No, QMessageBox::No) == QMessageBox::No)
return;
const unsigned int oldIntMod = generalSettings.internalModule;
generalSettings.clear();
postSettingsChangeMsg(oldIntMod);
emit modified();
closeEvent(new QCloseEvent());
done(-1);
}
void GeneralEdit::postSettingsChangeMsg(const unsigned int oldIntMod)
{
QString intmodmsg;
if (oldIntMod != generalSettings.internalModule) {
intModChanged = true;
intmodmsg = tr("The internal module type has been changed and may trigger model updates.") + "\n";
}
QMessageBox::information(this, tr("Radio Settings"),
tr("Default settings successfully applied.") + "\n" +
intmodmsg +
tr("The Radio Settings window will be closed and re-opened for the changes to take effect."));
}
+6 -3
View File
@@ -69,9 +69,10 @@ class GeneralEdit : public QDialog
private slots:
void onTabModified();
void on_tabWidget_currentChanged(int index);
void on_btnClearSettings_clicked();
void on_btnLoadSettings_clicked();
void on_btnSaveSettings_clicked();
void on_btnSettingsBackupClicked();
void on_btnSettingsBackupDeleteClicked();
void on_btnSettingsRestoreClicked();
void on_btnSettingsDefaultsClicked();
private:
Firmware * firmware;
@@ -79,4 +80,6 @@ class GeneralEdit : public QDialog
void addTab(GenericPanel *panel, QString text);
CompoundItemModelFactory *editorItemModels;
bool intModChanged = false;
void postSettingsChangeMsg(const unsigned int oldIntMod);
};
+128 -88
View File
@@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>787</width>
<height>577</height>
<height>576</height>
</rect>
</property>
<property name="sizePolicy">
@@ -23,93 +23,6 @@
<bool>true</bool>
</property>
<layout class="QGridLayout" name="gridLayout_4">
<item row="1" column="0">
<widget class="QFrame" name="frame">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="frameShape">
<enum>QFrame::Shape::Panel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Shadow::Raised</enum>
</property>
<layout class="QGridLayout" name="gridLayout_7">
<property name="sizeConstraint">
<enum>QLayout::SizeConstraint::SetDefaultConstraint</enum>
</property>
<item row="0" column="0">
<layout class="QGridLayout" name="gridLayout_6" rowstretch="0">
<item row="0" column="2">
<widget class="QPushButton" name="btnClearSettings">
<property name="text">
<string>Clear settings from profile</string>
</property>
</widget>
</item>
<item row="0" column="4">
<widget class="QPushButton" name="btnSaveSettings">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Store settings in profile</string>
</property>
</widget>
</item>
<item row="0" column="1">
<spacer name="horizontalSpacer_5">
<property name="orientation">
<enum>Qt::Orientation::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Policy::Expanding</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>10</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="0" column="0">
<widget class="QPushButton" name="btnLoadSettings">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Load settings from profile</string>
</property>
</widget>
</item>
<item row="0" column="3">
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Orientation::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout>
</widget>
</item>
<item row="0" column="0">
<widget class="QTabWidget" name="tabWidget">
<property name="sizePolicy">
@@ -127,6 +40,133 @@ These will be relevant for all models in the same EEPROM.</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QGroupBox" name="groupBox">
<property name="styleSheet">
<string notr="true"/>
</property>
<property name="title">
<string>Note: these functions apply to all radio settings</string>
</property>
<property name="alignment">
<set>Qt::AlignmentFlag::AlignCenter</set>
</property>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QPushButton" name="btnSettingsBackup">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="focusPolicy">
<enum>Qt::FocusPolicy::WheelFocus</enum>
</property>
<property name="contextMenuPolicy">
<enum>Qt::ContextMenuPolicy::CustomContextMenu</enum>
</property>
<property name="toolTip">
<string>Take a backup of all settings and save to current radio profile</string>
</property>
<property name="whatsThis">
<string extracomment="what does this button do"/>
</property>
<property name="text">
<string>Backup</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_5">
<property name="orientation">
<enum>Qt::Orientation::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Policy::Expanding</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>10</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="btnSettingsRestore">
<property name="focusPolicy">
<enum>Qt::FocusPolicy::NoFocus</enum>
</property>
<property name="toolTip">
<string>Restore all settings from backup saved in current radio profile</string>
</property>
<property name="text">
<string>Restore</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Orientation::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="btnSettingsDefaults">
<property name="focusPolicy">
<enum>Qt::FocusPolicy::NoFocus</enum>
</property>
<property name="toolTip">
<string>Reset all settings to current radio defaults</string>
</property>
<property name="text">
<string>Set to Defaults</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Orientation::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="btnSettingsBackupDelete">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="focusPolicy">
<enum>Qt::FocusPolicy::NoFocus</enum>
</property>
<property name="toolTip">
<string>Delete settings backup from current radio profile</string>
</property>
<property name="text">
<string>Delete Backup</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<resources>
+4 -3
View File
@@ -335,7 +335,7 @@ void MainWindow::setTabbedWindows(bool on)
void MainWindow::newFile()
{
MdiChild * child = createMdiChild();
child->newFile();
child->newFile(true);
child->show();
}
@@ -544,7 +544,7 @@ void MainWindow::readSettings()
if (readSettingsFromRadio(tempFile)) {
MdiChild * child = createMdiChild();
child->newFile(false);
child->newFile();
child->loadFile(tempFile, false);
child->show();
qunlink(tempFile);
@@ -1325,6 +1325,7 @@ int MainWindow::newProfile(bool loadProfile)
g.profile[i].fwType(newfw->getId());
g.profile[i].defaultInternalModule(Boards::getDefaultInternalModules(newfw->getBoard()));
g.profile[i].externalModuleSize(Boards::getDefaultExternalModuleSize(newfw->getBoard()));
g.profile[i].useSavedSettings(g.useSavedSettings());
if (loadProfile) {
if (loadProfileId(i))
@@ -1491,7 +1492,7 @@ void MainWindow::readSettingsSDPath()
if (readSettingsFromSDPath(tempFile)) {
MdiChild * child = createMdiChild();
child->newFile(false);
child->newFile();
child->loadFile(tempFile, false);
child->show();
qunlink(tempFile);
+15 -3
View File
@@ -33,6 +33,7 @@
#include "radiodataconversionstate.h"
#include "filtereditemmodels.h"
#include "labels.h"
#include "firmwares/edgetx/edgetxinterface.h"
#include <algorithm>
#include <ExportableTableView>
@@ -1055,7 +1056,8 @@ void MdiChild::generalEdit()
GeneralEdit * t = new GeneralEdit(this, radioData, firmware);
connect(t, &GeneralEdit::modified, this, &MdiChild::setModified);
connect(t, &GeneralEdit::internalModuleChanged, this, &MdiChild::onInternalModuleChanged); // passed up from HardwarePanel >> GeneralEdit
t->exec();
if (t->exec() == -1) // -1 is user defined return value
generalEdit();
}
void MdiChild::copyGeneralSettings()
@@ -1267,7 +1269,7 @@ void MdiChild::modelSimulate()
startSimulation(this, radioData, getCurrentModel());
}
void MdiChild::newFile(bool createDefaults)
void MdiChild::newFile(bool useProfileSettings)
{
static int sequenceNumber = 1;
isUntitled = true;
@@ -1276,12 +1278,22 @@ void MdiChild::newFile(bool createDefaults)
modelsListModel->setFilename(curFile);
radioData.addLabel(tr("Favorites"));
labelsListModel->buildLabelsList();
if (useProfileSettings && g.currentProfile().useSavedSettings() &&
!g.currentProfile().generalSettings().isEmpty()) {
QByteArray data = g.currentProfile().generalSettings();
if (!loadRadioSettingsFromYaml(radioData.generalSettings, data)) {
QMessageBox::critical(this, tr("New File"), tr("Unable to load settings from profile!"));
return;
}
}
}
bool MdiChild::loadFile(const QString & filename, bool resetCurrentFile)
{
if (getStorageType(filename) == STORAGE_TYPE_YML) {
newFile(false);
newFile();
resetCurrentFile = false;
}
+1 -1
View File
@@ -93,7 +93,7 @@ class MdiChild : public QWidget
bool invalidModels();
public slots:
void newFile(bool createDefaults = true);
void newFile(bool useProfileSettings = false);
bool loadFile(const QString & fileName, bool resetCurrentFile=true);
bool save();
bool saveAs(bool isNew=false);
+2
View File
@@ -508,6 +508,7 @@ class Profile: public CompStoreObj
// General settings
PROPERTYQBA(generalSettings)
PROPERTYSTR2(timeStamp, "TimeStamp")
PROPERTY(bool, useSavedSettings, true)
PROPERTYSTRD(jsName, "")
@@ -781,6 +782,7 @@ class AppData: public CompStoreObj
PROPERTY(bool, tabbedMdi, false)
PROPERTY(bool, appDebugLog, false)
PROPERTY(bool, fwTraceLog, false)
PROPERTY(bool, useSavedSettings, true)
// Simulator global (non-profile) settings
PROPERTY(QStringList, simuDbgFilters, QStringList())