desktop: block signals when setting combobox-indexes

On the InformationTab a signal is emitted when programatically
setting the index of the dive mode combobox which in turn then
edits the dive.

Usually not a problem, because the editing code realizes that
the value is not changed. It is however a problem when multiple
dives are selected.

Therefore, block the signals when setting the index. Same for
the other comboboxes on the same page.

Fixes #3960.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
This commit is contained in:
Berthold Stoeger 2024-01-16 18:11:02 +01:00 committed by Dirk Hohndel
parent bdade9e499
commit 35ff6eea35

View file

@ -13,9 +13,19 @@
#include "core/statistics.h" #include "core/statistics.h"
#include "core/divelist.h" #include "core/divelist.h"
#include <QSignalBlocker>
#define COMBO_CHANGED 0 #define COMBO_CHANGED 0
#define TEXT_EDITED 1 #define TEXT_EDITED 1
// Helper function to set index of combobox without emitting a signal
// that would fire an editing event.
static void setIndexNoSignal(QComboBox *combobox, int index)
{
QSignalBlocker blocker(combobox);
combobox->setCurrentIndex(index);
}
TabDiveInformation::TabDiveInformation(MainTab *parent) : TabBase(parent), ui(new Ui::TabDiveInformation()) TabDiveInformation::TabDiveInformation(MainTab *parent) : TabBase(parent), ui(new Ui::TabDiveInformation())
{ {
ui->setupUi(this); ui->setupUi(this);
@ -74,7 +84,7 @@ void TabDiveInformation::clear()
ui->atmPressVal->clear(); ui->atmPressVal->clear();
ui->salinityText->clear(); ui->salinityText->clear();
ui->waterTypeText->clear(); ui->waterTypeText->clear();
ui->waterTypeCombo->setCurrentIndex(0); setIndexNoSignal(ui->waterTypeCombo, 0);
} }
void TabDiveInformation::divesEdited(int i) void TabDiveInformation::divesEdited(int i)
@ -211,17 +221,17 @@ void TabDiveInformation::updateData(const std::vector<dive *> &, dive *currentDi
ui->watertemp->setText(get_temperature_string(currentDive->watertemp, true)); ui->watertemp->setText(get_temperature_string(currentDive->watertemp, true));
ui->airtemp->setText(get_temperature_string(currentDive->airtemp, true)); ui->airtemp->setText(get_temperature_string(currentDive->airtemp, true));
ui->atmPressType->setItemText(1, get_depth_unit()); // Check for changes in depth unit (imperial/metric) ui->atmPressType->setItemText(1, get_depth_unit()); // Check for changes in depth unit (imperial/metric)
ui->atmPressType->setCurrentIndex(0); // Set the atmospheric pressure combo box to mbar setIndexNoSignal(ui->atmPressType, 0); // Set the atmospheric pressure combo box to mbar
salinity_value = get_dive_salinity(currentDive); salinity_value = get_dive_salinity(currentDive);
if (salinity_value) { // Set water type indicator (EN13319 = 1.020 g/l) if (salinity_value) { // Set water type indicator (EN13319 = 1.020 g/l)
if (ui->waterTypeCombo->isVisible()) { // If water salinity is editable then set correct water type in combobox: if (ui->waterTypeCombo->isVisible()) { // If water salinity is editable then set correct water type in combobox:
ui->waterTypeCombo->setCurrentIndex(updateSalinityComboIndex(salinity_value)); setIndexNoSignal(ui->waterTypeCombo, updateSalinityComboIndex(salinity_value));
} else { // If water salinity is not editable: show water type as a text label } else { // If water salinity is not editable: show water type as a text label
ui->waterTypeText->setText(get_water_type_string(salinity_value)); ui->waterTypeText->setText(get_water_type_string(salinity_value));
} }
ui->salinityText->setText(get_salinity_string(salinity_value)); ui->salinityText->setText(get_salinity_string(salinity_value));
} else { } else {
ui->waterTypeCombo->setCurrentIndex(-1); setIndexNoSignal(ui->waterTypeCombo, -1);
ui->waterTypeText->setText(tr("unknown")); ui->waterTypeText->setText(tr("unknown"));
ui->salinityText->clear(); ui->salinityText->clear();
} }
@ -273,7 +283,7 @@ void TabDiveInformation::on_waterTypeCombo_activated(int index)
break; break;
case DC_WATERTYPE: case DC_WATERTYPE:
combobox_salinity = dc_salinity; combobox_salinity = dc_salinity;
ui->waterTypeCombo->setCurrentIndex(updateSalinityComboIndex(combobox_salinity)); setIndexNoSignal(ui->waterTypeCombo, updateSalinityComboIndex(combobox_salinity));
break; break;
default: default:
// the index was set to -1 to indicate an unknown water type // the index was set to -1 to indicate an unknown water type
@ -338,7 +348,7 @@ void TabDiveInformation::divesChanged(const QVector<dive *> &dives, DiveField fi
salinity_value = currentDive->user_salinity; salinity_value = currentDive->user_salinity;
else else
salinity_value = currentDive->salinity; salinity_value = currentDive->salinity;
ui->waterTypeCombo->setCurrentIndex(updateSalinityComboIndex(salinity_value)); setIndexNoSignal(ui->waterTypeCombo, updateSalinityComboIndex(salinity_value));
ui->salinityText->setText(QString("%L1g/").arg(salinity_value / 10.0)); ui->salinityText->setText(QString("%L1g/").arg(salinity_value / 10.0));
} }
@ -376,7 +386,7 @@ void TabDiveInformation::updateMode()
{ {
divecomputer *currentDC = parent.getCurrentDC(); divecomputer *currentDC = parent.getCurrentDC();
if (currentDC) if (currentDC)
ui->diveType->setCurrentIndex(currentDC->divemode); setIndexNoSignal(ui->diveType, currentDC->divemode);
} }
void TabDiveInformation::diveModeChanged(int index) void TabDiveInformation::diveModeChanged(int index)
@ -436,7 +446,7 @@ void TabDiveInformation::updateTextBox(int event) // Either the text box has bee
altitudeVal = altitudeVal * 1000; // metric: convert altitude from meters to mm altitudeVal = altitudeVal * 1000; // metric: convert altitude from meters to mm
atmpress.mbar = altitude_to_pressure((int32_t) altitudeVal); // convert altitude (mm) to pressure (mbar) atmpress.mbar = altitude_to_pressure((int32_t) altitudeVal); // convert altitude (mm) to pressure (mbar)
ui->atmPressVal->setText(QString::number(atmpress.mbar)); ui->atmPressVal->setText(QString::number(atmpress.mbar));
ui->atmPressType->setCurrentIndex(0); // reset combobox to mbar setIndexNoSignal(ui->atmPressType, 0); // reset combobox to mbar
} else { // i.e. event == COMBO_CHANGED, that is, "m" or "ft" was selected from combobox } else { // i.e. event == COMBO_CHANGED, that is, "m" or "ft" was selected from combobox
// Show estimated altitude // Show estimated altitude
bool ok; bool ok;
@ -452,7 +462,7 @@ void TabDiveInformation::updateTextBox(int event) // Either the text box has bee
case 2: // i.e. event = COMBO_CHANGED, that is, the option "Use dc" was selected from combobox case 2: // i.e. event = COMBO_CHANGED, that is, the option "Use dc" was selected from combobox
atmpress = calculate_surface_pressure(currentDive); // re-calculate air pressure from dc data atmpress = calculate_surface_pressure(currentDive); // re-calculate air pressure from dc data
ui->atmPressVal->setText(QString::number(atmpress.mbar)); // display it in text box ui->atmPressVal->setText(QString::number(atmpress.mbar)); // display it in text box
ui->atmPressType->setCurrentIndex(0); // reset combobox to mbar setIndexNoSignal(ui->atmPressType, 0); // reset combobox to mbar
break; break;
default: default:
atmpress.mbar = 1013; // This line should never execute atmpress.mbar = 1013; // This line should never execute