Improve database encryption settings UX

Fixes #6190

Remove the advanced settings checkbox and replace with a dedicated tab widget interface to toggle between basic and advanced encryption settings.
This commit is contained in:
Jonathan White 2023-06-24 12:25:18 -04:00
parent 190a1fa10c
commit 3cf14971f2
21 changed files with 574 additions and 649 deletions

View File

@ -1581,10 +1581,6 @@ If you do not have a key file, please leave the field empty.</source>
</context> </context>
<context> <context>
<name>DatabaseSettingsDialog</name> <name>DatabaseSettingsDialog</name>
<message>
<source>Advanced Settings</source>
<translation type="unfinished"></translation>
</message>
<message> <message>
<source>General</source> <source>General</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
@ -1778,14 +1774,6 @@ Are you sure you want to continue without a password?</source>
<source>Decryption Time:</source> <source>Decryption Time:</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<source>Change existing decryption time</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Change</source>
<translation type="unfinished"></translation>
</message>
<message> <message>
<source>Decryption time in seconds</source> <source>Decryption time in seconds</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
@ -1866,11 +1854,6 @@ Are you sure you want to continue without a password?</source>
<source>KDBX 3</source> <source>KDBX 3</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<source>unchanged</source>
<comment>Database decryption time is unchanged</comment>
<translation type="unfinished"></translation>
</message>
<message> <message>
<source>Number of rounds too high</source> <source>Number of rounds too high</source>
<comment>Key transformation rounds</comment> <comment>Key transformation rounds</comment>
@ -1925,6 +1908,18 @@ If you keep this number, your database will not be protected from brute force at
<numerusform></numerusform> <numerusform></numerusform>
</translation> </translation>
</message> </message>
<message>
<source>Encryption Settings:</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Basic</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Advanced</source>
<translation type="unfinished"></translation>
</message>
</context> </context>
<context> <context>
<name>DatabaseSettingsWidgetFdoSecrets</name> <name>DatabaseSettingsWidgetFdoSecrets</name>
@ -5592,14 +5587,6 @@ We recommend you use the AppImage available on our downloads page.</source>
<source>Here you can adjust the database encryption settings. Don&apos;t worry, you can change them later in the database settings.</source> <source>Here you can adjust the database encryption settings. Don&apos;t worry, you can change them later in the database settings.</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<source>Advanced Settings</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Simple Settings</source>
<translation type="unfinished"></translation>
</message>
</context> </context>
<context> <context>
<name>NewDatabaseWizardPageDatabaseKey</name> <name>NewDatabaseWizardPageDatabaseKey</name>

View File

@ -104,7 +104,6 @@ static const QHash<Config::ConfigKey, ConfigDirective> configStrings = {
{Config::GUI_MinimizeOnClose, {QS("GUI/MinimizeOnClose"), Roaming, false}}, {Config::GUI_MinimizeOnClose, {QS("GUI/MinimizeOnClose"), Roaming, false}},
{Config::GUI_HideUsernames, {QS("GUI/HideUsernames"), Roaming, false}}, {Config::GUI_HideUsernames, {QS("GUI/HideUsernames"), Roaming, false}},
{Config::GUI_HidePasswords, {QS("GUI/HidePasswords"), Roaming, true}}, {Config::GUI_HidePasswords, {QS("GUI/HidePasswords"), Roaming, true}},
{Config::GUI_AdvancedSettings, {QS("GUI/AdvancedSettings"), Roaming, false}},
{Config::GUI_ColorPasswords, {QS("GUI/ColorPasswords"), Roaming, false}}, {Config::GUI_ColorPasswords, {QS("GUI/ColorPasswords"), Roaming, false}},
{Config::GUI_MonospaceNotes, {QS("GUI/MonospaceNotes"), Roaming, false}}, {Config::GUI_MonospaceNotes, {QS("GUI/MonospaceNotes"), Roaming, false}},
{Config::GUI_ApplicationTheme, {QS("GUI/ApplicationTheme"), Roaming, QS("auto")}}, {Config::GUI_ApplicationTheme, {QS("GUI/ApplicationTheme"), Roaming, QS("auto")}},
@ -371,7 +370,10 @@ static const QHash<QString, Config::ConfigKey> deprecationMap = {
{QS("UseTouchID"), Config::Deleted}, {QS("UseTouchID"), Config::Deleted},
{QS("Security/ResetTouchId"), Config::Deleted}, {QS("Security/ResetTouchId"), Config::Deleted},
{QS("Security/ResetTouchIdTimeout"), Config::Deleted}, {QS("Security/ResetTouchIdTimeout"), Config::Deleted},
{QS("Security/ResetTouchIdScreenlock"), Config::Deleted}}; {QS("Security/ResetTouchIdScreenlock"), Config::Deleted},
// 2.8.0
{QS("GUI/AdvancedSettings"), Config::Deleted}};
/** /**
* Migrate settings from previous versions. * Migrate settings from previous versions.

View File

@ -85,7 +85,6 @@ public:
GUI_MinimizeOnClose, GUI_MinimizeOnClose,
GUI_HideUsernames, GUI_HideUsernames,
GUI_HidePasswords, GUI_HidePasswords,
GUI_AdvancedSettings,
GUI_ColorPasswords, GUI_ColorPasswords,
GUI_MonospaceNotes, GUI_MonospaceNotes,
GUI_ApplicationTheme, GUI_ApplicationTheme,

View File

@ -33,7 +33,6 @@
#include "fdosecrets/DatabaseSettingsPageFdoSecrets.h" #include "fdosecrets/DatabaseSettingsPageFdoSecrets.h"
#endif #endif
#include "core/Config.h"
#include "core/Database.h" #include "core/Database.h"
#include "core/Global.h" #include "core/Global.h"
#include "gui/Icons.h" #include "gui/Icons.h"
@ -109,7 +108,6 @@ DatabaseSettingsDialog::DatabaseSettingsDialog(QWidget* parent)
connect(m_securityTabWidget, SIGNAL(currentChanged(int)), SLOT(pageChanged())); connect(m_securityTabWidget, SIGNAL(currentChanged(int)), SLOT(pageChanged()));
connect(m_ui->categoryList, SIGNAL(categoryChanged(int)), m_ui->stackedWidget, SLOT(setCurrentIndex(int))); connect(m_ui->categoryList, SIGNAL(categoryChanged(int)), m_ui->stackedWidget, SLOT(setCurrentIndex(int)));
connect(m_ui->advancedSettingsToggle, SIGNAL(toggled(bool)), SLOT(toggleAdvancedMode(bool)));
#ifdef WITH_XC_BROWSER #ifdef WITH_XC_BROWSER
m_ui->categoryList->addCategory(tr("Browser Integration"), icons()->icon("internet-web-browser")); m_ui->categoryList->addCategory(tr("Browser Integration"), icons()->icon("internet-web-browser"));
@ -137,7 +135,6 @@ void DatabaseSettingsDialog::load(const QSharedPointer<Database>& db)
for (const ExtraPage& page : asConst(m_extraPages)) { for (const ExtraPage& page : asConst(m_extraPages)) {
page.loadSettings(db); page.loadSettings(db);
} }
m_ui->advancedSettingsToggle->setChecked(config()->get(Config::GUI_AdvancedSettings).toBool());
m_db = db; m_db = db;
} }
@ -189,32 +186,5 @@ void DatabaseSettingsDialog::reject()
void DatabaseSettingsDialog::pageChanged() void DatabaseSettingsDialog::pageChanged()
{ {
int pageIndex = m_ui->stackedWidget->currentIndex(); m_ui->stackedWidget->currentIndex();
bool enabled = (pageIndex == Page::General && m_generalWidget->hasAdvancedMode());
if (Page::Security == pageIndex) {
int tabIndex = m_securityTabWidget->currentIndex();
enabled = (tabIndex == 0 && m_databaseKeyWidget->hasAdvancedMode());
enabled |= (tabIndex == 1 && m_encryptionWidget->hasAdvancedMode());
}
m_ui->advancedSettingsToggle->setEnabled(enabled);
}
void DatabaseSettingsDialog::toggleAdvancedMode(bool advanced)
{
if (m_generalWidget->hasAdvancedMode()) {
m_generalWidget->setAdvancedMode(advanced);
}
if (m_databaseKeyWidget->hasAdvancedMode()) {
m_databaseKeyWidget->setAdvancedMode(advanced);
}
if (m_encryptionWidget->hasAdvancedMode()) {
m_encryptionWidget->setAdvancedMode(advanced);
}
config()->set(Config::GUI_AdvancedSettings, advanced);
} }

View File

@ -69,7 +69,6 @@ private slots:
void save(); void save();
void reject(); void reject();
void pageChanged(); void pageChanged();
void toggleAdvancedMode(bool advanced);
private: private:
enum Page enum Page

View File

@ -17,15 +17,6 @@
</item> </item>
</layout> </layout>
</item> </item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QCheckBox" name="advancedSettingsToggle">
<property name="text">
<string>Advanced Settings</string>
</property>
</widget>
</item>
<item> <item>
<widget class="QDialogButtonBox" name="buttonBox"> <widget class="QDialogButtonBox" name="buttonBox">
<property name="standardButtons"> <property name="standardButtons">
@ -34,8 +25,6 @@
</widget> </widget>
</item> </item>
</layout> </layout>
</item>
</layout>
</widget> </widget>
<customwidgets> <customwidgets>
<customwidget> <customwidget>

View File

@ -43,10 +43,6 @@ public:
~DatabaseSettingsWidgetBrowser() override; ~DatabaseSettingsWidgetBrowser() override;
CustomData* customData() const; CustomData* customData() const;
inline bool hasAdvancedMode() const override
{
return false;
}
public slots: public slots:
void initialize() override; void initialize() override;

View File

@ -44,11 +44,6 @@ public:
void load(QSharedPointer<Database> db) override; void load(QSharedPointer<Database> db) override;
inline bool hasAdvancedMode() const override
{
return false;
}
public slots: public slots:
void initialize() override; void initialize() override;
void uninitialize() override; void uninitialize() override;

View File

@ -27,8 +27,24 @@
#include "format/KeePass2Writer.h" #include "format/KeePass2Writer.h"
#include "gui/MessageBox.h" #include "gui/MessageBox.h"
#include <QPushButton>
const char* DatabaseSettingsWidgetEncryption::CD_DECRYPTION_TIME_PREFERENCE_KEY = "KPXC_DECRYPTION_TIME_PREFERENCE"; const char* DatabaseSettingsWidgetEncryption::CD_DECRYPTION_TIME_PREFERENCE_KEY = "KPXC_DECRYPTION_TIME_PREFERENCE";
#define IS_ARGON2(uuid) (uuid == KeePass2::KDF_ARGON2D || uuid == KeePass2::KDF_ARGON2ID)
#define IS_AES_KDF(uuid) (uuid == KeePass2::KDF_AES_KDBX3 || uuid == KeePass2::KDF_AES_KDBX4)
namespace
{
QString getTextualEncryptionTime(int millisecs)
{
if (millisecs < 1000) {
return QObject::tr("%1 ms", "milliseconds", millisecs).arg(millisecs);
}
return QObject::tr("%1 s", "seconds", millisecs / 1000).arg(millisecs / 1000.0, 0, 'f', 1);
}
} // namespace
DatabaseSettingsWidgetEncryption::DatabaseSettingsWidgetEncryption(QWidget* parent) DatabaseSettingsWidgetEncryption::DatabaseSettingsWidgetEncryption(QWidget* parent)
: DatabaseSettingsWidget(parent) : DatabaseSettingsWidget(parent)
, m_ui(new Ui::DatabaseSettingsWidgetEncryption()) , m_ui(new Ui::DatabaseSettingsWidgetEncryption())
@ -50,19 +66,16 @@ DatabaseSettingsWidgetEncryption::DatabaseSettingsWidgetEncryption(QWidget* pare
updateDecryptionTime(m_ui->decryptionTimeSlider->value()); updateDecryptionTime(m_ui->decryptionTimeSlider->value());
m_ui->transformBenchmarkButton->setText( m_ui->transformBenchmarkButton->setText(
QObject::tr("Benchmark %1 delay") QObject::tr("Benchmark %1 delay").arg(getTextualEncryptionTime(Kdf::DEFAULT_ENCRYPTION_TIME)));
.arg(DatabaseSettingsWidgetEncryption::getTextualEncryptionTime(Kdf::DEFAULT_ENCRYPTION_TIME))); m_ui->minTimeLabel->setText(getTextualEncryptionTime(Kdf::MIN_ENCRYPTION_TIME));
m_ui->minTimeLabel->setText(DatabaseSettingsWidgetEncryption::getTextualEncryptionTime(Kdf::MIN_ENCRYPTION_TIME)); m_ui->maxTimeLabel->setText(getTextualEncryptionTime(Kdf::MAX_ENCRYPTION_TIME));
m_ui->maxTimeLabel->setText(DatabaseSettingsWidgetEncryption::getTextualEncryptionTime(Kdf::MAX_ENCRYPTION_TIME));
connect(m_ui->activateChangeDecryptionTimeButton, SIGNAL(clicked()), SLOT(activateChangeDecryptionTime()));
connect(m_ui->decryptionTimeSlider, SIGNAL(valueChanged(int)), SLOT(updateDecryptionTime(int))); connect(m_ui->decryptionTimeSlider, SIGNAL(valueChanged(int)), SLOT(updateDecryptionTime(int)));
connect(m_ui->compatibilitySelection, SIGNAL(currentIndexChanged(int)), SLOT(updateFormatCompatibility(int))); connect(m_ui->compatibilitySelection, SIGNAL(currentIndexChanged(int)), SLOT(updateFormatCompatibility(int)));
// conditions under which a key re-transformation is needed // conditions under which a key re-transformation is needed
connect(m_ui->decryptionTimeSlider, SIGNAL(valueChanged(int)), SLOT(markDirty())); connect(m_ui->decryptionTimeSlider, SIGNAL(valueChanged(int)), SLOT(markDirty()));
connect(m_ui->compatibilitySelection, SIGNAL(currentIndexChanged(int)), SLOT(markDirty())); connect(m_ui->compatibilitySelection, SIGNAL(currentIndexChanged(int)), SLOT(markDirty()));
connect(m_ui->activateChangeDecryptionTimeButton, SIGNAL(clicked()), SLOT(markDirty()));
connect(m_ui->algorithmComboBox, SIGNAL(currentIndexChanged(int)), SLOT(markDirty())); connect(m_ui->algorithmComboBox, SIGNAL(currentIndexChanged(int)), SLOT(markDirty()));
connect(m_ui->kdfComboBox, SIGNAL(currentIndexChanged(int)), SLOT(markDirty())); connect(m_ui->kdfComboBox, SIGNAL(currentIndexChanged(int)), SLOT(markDirty()));
connect(m_ui->transformRoundsSpinBox, SIGNAL(valueChanged(int)), SLOT(markDirty())); connect(m_ui->transformRoundsSpinBox, SIGNAL(valueChanged(int)), SLOT(markDirty()));
@ -72,8 +85,13 @@ DatabaseSettingsWidgetEncryption::DatabaseSettingsWidgetEncryption(QWidget* pare
DatabaseSettingsWidgetEncryption::~DatabaseSettingsWidgetEncryption() = default; DatabaseSettingsWidgetEncryption::~DatabaseSettingsWidgetEncryption() = default;
#define IS_ARGON2(uuid) (uuid == KeePass2::KDF_ARGON2D || uuid == KeePass2::KDF_ARGON2ID) void DatabaseSettingsWidgetEncryption::showBasicEncryption(int decryptionMillisecs)
#define IS_AES_KDF(uuid) (uuid == KeePass2::KDF_AES_KDBX3 || uuid == KeePass2::KDF_AES_KDBX4) {
// Show the basic encryption settings tab and set the slider to the stored values
m_ui->decryptionTimeSlider->setValue(decryptionMillisecs / 100);
m_ui->encryptionSettingsTabWidget->setCurrentWidget(m_ui->basicTab);
m_initWithAdvanced = false;
}
void DatabaseSettingsWidgetEncryption::initialize() void DatabaseSettingsWidgetEncryption::initialize()
{ {
@ -82,39 +100,44 @@ void DatabaseSettingsWidgetEncryption::initialize()
return; return;
} }
bool isDirty = false; auto version = KDBX4;
if (m_db->kdf()) {
version = (m_db->kdf()->uuid() == KeePass2::KDF_AES_KDBX3) ? KDBX3 : KDBX4;
}
m_ui->compatibilitySelection->setCurrentIndex(version);
bool isNewDatabase = false;
if (!m_db->kdf()) { if (!m_db->kdf()) {
m_db->setKdf(KeePass2::uuidToKdf(KeePass2::KDF_ARGON2D)); m_db->setKdf(KeePass2::uuidToKdf(KeePass2::KDF_ARGON2D));
isDirty = true; isNewDatabase = true;
} }
if (!m_db->key()) { if (!m_db->key()) {
m_db->setKey(QSharedPointer<CompositeKey>::create(), true, false, false); m_db->setKey(QSharedPointer<CompositeKey>::create(), true, false, false);
m_db->setCipher(KeePass2::CIPHER_AES256); m_db->setCipher(KeePass2::CIPHER_AES256);
isDirty = true; isNewDatabase = true;
} }
bool kdbx3Enabled = KeePass2Writer::kdbxVersionRequired(m_db.data(), true, true) <= KeePass2::FILE_VERSION_3_1; bool kdbx3Enabled = KeePass2Writer::kdbxVersionRequired(m_db.data(), true, true) <= KeePass2::FILE_VERSION_3_1;
// check if the DB's custom data has a decryption time setting stored // check if the DB's custom data has a decryption time setting stored
// and set the slider to it, otherwise just state that the time is unchanged // and set the slider to it, otherwise just state that the time is unchanged
// (we cannot infer the time from the raw KDF settings) // (we cannot infer the time from the raw KDF settings)
auto* cd = m_db->metadata()->customData(); auto* cd = m_db->metadata()->customData();
if (cd->hasKey(CD_DECRYPTION_TIME_PREFERENCE_KEY)) { if (cd->hasKey(CD_DECRYPTION_TIME_PREFERENCE_KEY)) {
int decryptionTime = qMax(100, cd->value(CD_DECRYPTION_TIME_PREFERENCE_KEY).toInt()); int decryptionTime = qMax(100, cd->value(CD_DECRYPTION_TIME_PREFERENCE_KEY).toInt());
bool block = m_ui->decryptionTimeSlider->blockSignals(true); showBasicEncryption(decryptionTime);
m_ui->decryptionTimeSlider->setValue(decryptionTime / 100); } else if (isNewDatabase) {
updateDecryptionTime(decryptionTime / 100); showBasicEncryption();
m_ui->decryptionTimeSlider->blockSignals(block);
m_ui->activateChangeDecryptionTimeButton->setVisible(false);
} else { } else {
m_ui->decryptionTimeSettings->setVisible(isDirty); // Set default basic decryption time
m_ui->activateChangeDecryptionTimeButton->setVisible(!isDirty); m_ui->decryptionTimeSlider->setValue(Kdf::DEFAULT_ENCRYPTION_TIME / 100);
if (!isDirty) { // Show the advanced encryption settings tab
m_ui->decryptionTimeValueLabel->setText(tr("unchanged", "Database decryption time is unchanged")); m_ui->encryptionSettingsTabWidget->setCurrentWidget(m_ui->advancedTab);
} m_initWithAdvanced = true;
} }
updateFormatCompatibility(m_db->kdf()->uuid() == KeePass2::KDF_AES_KDBX3 ? KDBX3 : KDBX4, isDirty); updateFormatCompatibility(m_db->kdf()->uuid() == KeePass2::KDF_AES_KDBX3 ? KDBX3 : KDBX4, isNewDatabase);
setupAlgorithmComboBox(); setupAlgorithmComboBox();
setupKdfComboBox(kdbx3Enabled); setupKdfComboBox(kdbx3Enabled);
loadKdfParameters(); loadKdfParameters();
@ -124,7 +147,7 @@ void DatabaseSettingsWidgetEncryption::initialize()
m_ui->formatCannotBeChanged->setVisible(true); m_ui->formatCannotBeChanged->setVisible(true);
} }
m_isDirty = isDirty; m_isDirty = isNewDatabase;
} }
void DatabaseSettingsWidgetEncryption::uninitialize() void DatabaseSettingsWidgetEncryption::uninitialize()
@ -170,7 +193,6 @@ void DatabaseSettingsWidgetEncryption::loadKdfParameters()
} }
auto kdf = m_db->kdf(); auto kdf = m_db->kdf();
Q_ASSERT(kdf);
if (!kdf) { if (!kdf) {
return; return;
} }
@ -202,13 +224,6 @@ void DatabaseSettingsWidgetEncryption::updateKdfFields()
m_ui->parallelismSpinBox->setVisible(IS_ARGON2(id)); m_ui->parallelismSpinBox->setVisible(IS_ARGON2(id));
} }
void DatabaseSettingsWidgetEncryption::activateChangeDecryptionTime()
{
m_ui->decryptionTimeSettings->setVisible(true);
m_ui->activateChangeDecryptionTimeButton->setVisible(false);
updateDecryptionTime(m_ui->decryptionTimeSlider->value());
}
void DatabaseSettingsWidgetEncryption::markDirty() void DatabaseSettingsWidgetEncryption::markDirty()
{ {
m_isDirty = true; m_isDirty = true;
@ -221,6 +236,11 @@ bool DatabaseSettingsWidgetEncryption::save()
return false; return false;
} }
if (m_initWithAdvanced != isAdvancedMode()) {
// Switched from basic <-> advanced mode, need to recalculate everything
m_isDirty = true;
}
if (m_db->key() && !m_db->key()->keys().isEmpty() && !m_isDirty) { if (m_db->key() && !m_db->key()->keys().isEmpty() && !m_isDirty) {
// nothing has changed, don't re-transform // nothing has changed, don't re-transform
return true; return true;
@ -229,7 +249,7 @@ bool DatabaseSettingsWidgetEncryption::save()
auto kdf = m_db->kdf(); auto kdf = m_db->kdf();
Q_ASSERT(kdf); Q_ASSERT(kdf);
if (!advancedMode()) { if (!isAdvancedMode()) {
if (kdf && !m_isDirty && !m_ui->decryptionTimeSettings->isVisible()) { if (kdf && !m_isDirty && !m_ui->decryptionTimeSettings->isVisible()) {
return true; return true;
} }
@ -352,7 +372,6 @@ void DatabaseSettingsWidgetEncryption::changeKdf(int index)
QUuid id(m_ui->kdfComboBox->itemData(index).toByteArray()); QUuid id(m_ui->kdfComboBox->itemData(index).toByteArray());
m_db->setKdf(KeePass2::uuidToKdf(id)); m_db->setKdf(KeePass2::uuidToKdf(id));
updateKdfFields(); updateKdfFields();
activateChangeDecryptionTime();
benchmarkTransformRounds(); benchmarkTransformRounds();
} }
@ -372,22 +391,14 @@ void DatabaseSettingsWidgetEncryption::parallelismChanged(int value)
m_ui->parallelismSpinBox->setSuffix(tr(" thread(s)", "Threads for parallel execution (KDF settings)", value)); m_ui->parallelismSpinBox->setSuffix(tr(" thread(s)", "Threads for parallel execution (KDF settings)", value));
} }
void DatabaseSettingsWidgetEncryption::setAdvancedMode(bool advanced) bool DatabaseSettingsWidgetEncryption::isAdvancedMode()
{ {
DatabaseSettingsWidget::setAdvancedMode(advanced); return m_ui->encryptionSettingsTabWidget->currentWidget() == m_ui->advancedTab;
if (advanced) {
loadKdfParameters();
m_ui->stackedWidget->setCurrentIndex(1);
} else {
m_ui->compatibilitySelection->setCurrentIndex(m_db->kdf()->uuid() == KeePass2::KDF_AES_KDBX3 ? KDBX3 : KDBX4);
m_ui->stackedWidget->setCurrentIndex(0);
}
} }
void DatabaseSettingsWidgetEncryption::updateDecryptionTime(int value) void DatabaseSettingsWidgetEncryption::updateDecryptionTime(int value)
{ {
m_ui->decryptionTimeValueLabel->setText(DatabaseSettingsWidgetEncryption::getTextualEncryptionTime(value * 100)); m_ui->decryptionTimeValueLabel->setText(getTextualEncryptionTime(value * 100));
} }
void DatabaseSettingsWidgetEncryption::updateFormatCompatibility(int index, bool retransform) void DatabaseSettingsWidgetEncryption::updateFormatCompatibility(int index, bool retransform)
@ -415,16 +426,5 @@ void DatabaseSettingsWidgetEncryption::updateFormatCompatibility(int index, bool
argon2Kdf->setMemory(1 << 16); argon2Kdf->setMemory(1 << 16);
argon2Kdf->setParallelism(2); argon2Kdf->setParallelism(2);
} }
activateChangeDecryptionTime();
}
}
QString DatabaseSettingsWidgetEncryption::getTextualEncryptionTime(int millisecs)
{
if (millisecs < 1000) {
return QObject::tr("%1 ms", "milliseconds", millisecs).arg(millisecs);
} else {
return QObject::tr("%1 s", "seconds", millisecs / 1000).arg(millisecs / 1000.0, 0, 'f', 1);
} }
} }

View File

@ -37,19 +37,11 @@ public:
Q_DISABLE_COPY(DatabaseSettingsWidgetEncryption); Q_DISABLE_COPY(DatabaseSettingsWidgetEncryption);
~DatabaseSettingsWidgetEncryption() override; ~DatabaseSettingsWidgetEncryption() override;
inline bool hasAdvancedMode() const override
{
return true;
}
void setAdvancedMode(bool advanced) override;
public slots: public slots:
void initialize() override; void initialize() override;
void uninitialize() override; void uninitialize() override;
bool save() override; bool save() override;
static QString getTextualEncryptionTime(int millisecs);
protected: protected:
void showEvent(QShowEvent* event) override; void showEvent(QShowEvent* event) override;
@ -64,10 +56,12 @@ private slots:
void setupKdfComboBox(bool enableKdbx3); void setupKdfComboBox(bool enableKdbx3);
void loadKdfParameters(); void loadKdfParameters();
void updateKdfFields(); void updateKdfFields();
void activateChangeDecryptionTime();
void markDirty(); void markDirty();
private: private:
bool isAdvancedMode();
void showBasicEncryption(int decryptionMillisecs = Kdf::DEFAULT_ENCRYPTION_TIME);
enum FormatSelection enum FormatSelection
{ {
KDBX4, KDBX4,
@ -76,6 +70,7 @@ private:
static const char* CD_DECRYPTION_TIME_PREFERENCE_KEY; static const char* CD_DECRYPTION_TIME_PREFERENCE_KEY;
bool m_isDirty = false; bool m_isDirty = false;
bool m_initWithAdvanced = false;
bool m_formatCompatibilityDirty = false; bool m_formatCompatibilityDirty = false;
const QScopedPointer<Ui::DatabaseSettingsWidgetEncryption> m_ui; const QScopedPointer<Ui::DatabaseSettingsWidgetEncryption> m_ui;
}; };

View File

@ -6,23 +6,40 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>585</width> <width>451</width>
<height>339</height> <height>329</height>
</rect> </rect>
</property> </property>
<layout class="QVBoxLayout" name="_2"> <layout class="QVBoxLayout" name="verticalLayout_3">
<item> <item>
<widget class="QStackedWidget" name="stackedWidget"> <widget class="QScrollArea" name="scrollArea">
<property name="currentIndex"> <property name="frameShape">
<number>0</number> <enum>QFrame::NoFrame</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Plain</enum>
</property>
<property name="widgetResizable">
<bool>true</bool>
</property>
<widget class="QWidget" name="scrollAreaWidgetContents">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>433</width>
<height>311</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout" stretch="0,0,0,0,1">
<property name="spacing">
<number>6</number>
</property> </property>
<widget class="QWidget" name="simpleSettings">
<layout class="QVBoxLayout" name="verticalLayout_2">
<property name="leftMargin"> <property name="leftMargin">
<number>0</number> <number>0</number>
</property> </property>
<property name="topMargin"> <property name="topMargin">
<number>0</number> <number>10</number>
</property> </property>
<property name="rightMargin"> <property name="rightMargin">
<number>0</number> <number>0</number>
@ -30,6 +47,60 @@
<property name="bottomMargin"> <property name="bottomMargin">
<number>0</number> <number>0</number>
</property> </property>
<item>
<layout class="QFormLayout" name="formLayout">
<property name="rowWrapPolicy">
<enum>QFormLayout::DontWrapRows</enum>
</property>
<property name="verticalSpacing">
<number>2</number>
</property>
<item row="0" column="0">
<widget class="QLabel" name="compatibilityLabel">
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>Database format:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QComboBox" name="compatibilitySelection">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="toolTip">
<string>Unless you need to open your database with other programs, always use the latest format.</string>
</property>
<property name="accessibleName">
<string>Database format</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLabel" name="formatCannotBeChanged">
<property name="font">
<font>
<italic>true</italic>
</font>
</property>
<property name="text">
<string>Format cannot be changed: Your database uses KDBX 4 features</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
<item> <item>
<spacer name="verticalSpacer_2"> <spacer name="verticalSpacer_2">
<property name="orientation"> <property name="orientation">
@ -46,10 +117,60 @@
</property> </property>
</spacer> </spacer>
</item> </item>
<item>
<widget class="QLabel" name="label">
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>Encryption Settings:</string>
</property>
</widget>
</item>
<item>
<widget class="QTabWidget" name="encryptionSettingsTabWidget">
<property name="tabPosition">
<enum>QTabWidget::North</enum>
</property>
<property name="tabShape">
<enum>QTabWidget::Rounded</enum>
</property>
<property name="currentIndex">
<number>0</number>
</property>
<widget class="QWidget" name="basicTab">
<attribute name="title">
<string>Basic</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_8">
<property name="spacing">
<number>6</number>
</property>
<property name="leftMargin">
<number>9</number>
</property>
<property name="topMargin">
<number>6</number>
</property>
<property name="rightMargin">
<number>9</number>
</property>
<property name="bottomMargin">
<number>6</number>
</property>
<item> <item>
<layout class="QHBoxLayout" name="horizontalLayout_2"> <layout class="QHBoxLayout" name="horizontalLayout_2">
<item> <item>
<widget class="QLabel" name="decryptionTimeLabel"> <widget class="QLabel" name="decryptionTimeLabel">
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text"> <property name="text">
<string>Decryption Time:</string> <string>Decryption Time:</string>
</property> </property>
@ -57,6 +178,12 @@
</item> </item>
<item> <item>
<widget class="QLabel" name="decryptionTimeValueLabel"> <widget class="QLabel" name="decryptionTimeValueLabel">
<property name="font">
<font>
<weight>50</weight>
<bold>false</bold>
</font>
</property>
<property name="text"> <property name="text">
<string notr="true">?? s</string> <string notr="true">?? s</string>
</property> </property>
@ -75,21 +202,23 @@
</property> </property>
</spacer> </spacer>
</item> </item>
<item>
<widget class="QPushButton" name="activateChangeDecryptionTimeButton">
<property name="accessibleName">
<string>Change existing decryption time</string>
</property>
<property name="text">
<string>Change</string>
</property>
</widget>
</item>
</layout> </layout>
</item> </item>
<item> <item>
<widget class="QWidget" name="decryptionTimeSettings" native="true"> <widget class="QWidget" name="decryptionTimeSettings" native="true">
<layout class="QVBoxLayout" name="decryptionTimeSliderLayout"> <layout class="QVBoxLayout" name="decryptionTimeSliderLayout">
<property name="leftMargin">
<number>6</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>6</number>
</property>
<property name="bottomMargin">
<number>9</number>
</property>
<item> <item>
<widget class="QSlider" name="decryptionTimeSlider"> <widget class="QSlider" name="decryptionTimeSlider">
<property name="accessibleName"> <property name="accessibleName">
@ -167,13 +296,10 @@
<property name="orientation"> <property name="orientation">
<enum>Qt::Vertical</enum> <enum>Qt::Vertical</enum>
</property> </property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
</property>
<property name="sizeHint" stdset="0"> <property name="sizeHint" stdset="0">
<size> <size>
<width>20</width> <width>20</width>
<height>20</height> <height>0</height>
</size> </size>
</property> </property>
</spacer> </spacer>
@ -181,122 +307,93 @@
</layout> </layout>
</widget> </widget>
</item> </item>
<item>
<layout class="QFormLayout" name="formLayout">
<property name="verticalSpacing">
<number>2</number>
</property>
<item row="0" column="0">
<widget class="QLabel" name="compatibilityLabel">
<property name="text">
<string>Database format:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QComboBox" name="compatibilitySelection">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="accessibleName">
<string>Database format</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLabel" name="formatCannotBeChanged">
<property name="font">
<font>
<italic>true</italic>
</font>
</property>
<property name="text">
<string>Format cannot be changed: Your database uses KDBX 4 features</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>Unless you need to open your database with other programs, always use the latest format.</string>
</property>
</widget>
</item>
</layout> </layout>
</widget> </widget>
<widget class="QWidget" name="advancedSettings"> <widget class="QWidget" name="advancedTab">
<layout class="QFormLayout" name="formLayout_2"> <attribute name="title">
<property name="leftMargin"> <string>Advanced</string>
<number>0</number> </attribute>
</property> <layout class="QGridLayout" name="gridLayout">
<property name="topMargin"> <property name="topMargin">
<number>0</number> <number>6</number>
</property>
<property name="rightMargin">
<number>0</number>
</property> </property>
<property name="bottomMargin"> <property name="bottomMargin">
<number>0</number> <number>6</number>
</property> </property>
<item row="0" column="0"> <item row="0" column="2">
<widget class="QLabel" name="algorithmLabel"> <spacer name="horizontalSpacer_4">
<property name="text"> <property name="orientation">
<string>Encryption Algorithm:</string> <enum>Qt::Horizontal</enum>
</property> </property>
</widget> <property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item> </item>
<item row="0" column="1"> <item row="4" column="1">
<widget class="QComboBox" name="algorithmComboBox"> <widget class="QSpinBox" name="parallelismSpinBox">
<property name="sizePolicy"> <property name="minimumSize">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed"> <size>
<horstretch>0</horstretch> <width>150</width>
<verstretch>0</verstretch> <height>0</height>
</sizepolicy> </size>
</property>
<property name="maximumSize">
<size>
<width>150</width>
<height>16777215</height>
</size>
</property> </property>
<property name="accessibleName"> <property name="accessibleName">
<string>Encryption algorithm</string> <string>Parallelism</string>
</property> </property>
<item> <property name="minimum">
<property name="text"> <number>1</number>
<string>AES: 256 Bit (default)</string>
</property> </property>
</item> <property name="maximum">
<item> <number>128</number>
<property name="text">
<string>Twofish: 256 Bit</string>
</property>
</item>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="kdfLabel">
<property name="text">
<string>Key Derivation Function:</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="1" column="1"> <item row="4" column="0">
<widget class="QComboBox" name="kdfComboBox"> <widget class="QLabel" name="parallelismLabel">
<property name="sizePolicy"> <property name="text">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed"> <string>Parallelism:</string>
<horstretch>0</horstretch> </property>
<verstretch>0</verstretch> </widget>
</sizepolicy> </item>
<item row="3" column="1">
<widget class="QSpinBox" name="memorySpinBox">
<property name="minimumSize">
<size>
<width>150</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>150</width>
<height>16777215</height>
</size>
</property> </property>
<property name="accessibleName"> <property name="accessibleName">
<string>Key derivation function</string> <string>Memory usage</string>
</property>
<property name="minimum">
<number>1</number>
</property>
<property name="maximum">
<number>1048576</number>
</property> </property>
</widget> </widget>
</item> </item>
<item row="2" column="0"> <item row="3" column="0">
<widget class="QLabel" name="transformRoundsLabel"> <widget class="QLabel" name="memoryUsageLabel">
<property name="text"> <property name="text">
<string>Transform rounds:</string> <string>Memory Usage:</string>
</property> </property>
</widget> </widget>
</item> </item>
@ -352,67 +449,60 @@
</item> </item>
</layout> </layout>
</item> </item>
<item row="3" column="0"> <item row="2" column="0">
<widget class="QLabel" name="memoryUsageLabel"> <widget class="QLabel" name="transformRoundsLabel">
<property name="text"> <property name="text">
<string>Memory Usage:</string> <string>Transform rounds:</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="3" column="1"> <item row="1" column="1">
<widget class="QSpinBox" name="memorySpinBox"> <widget class="QComboBox" name="kdfComboBox">
<property name="minimumSize"> <property name="sizePolicy">
<size> <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<width>150</width> <horstretch>0</horstretch>
<height>0</height> <verstretch>0</verstretch>
</size> </sizepolicy>
</property>
<property name="maximumSize">
<size>
<width>150</width>
<height>16777215</height>
</size>
</property> </property>
<property name="accessibleName"> <property name="accessibleName">
<string>Memory usage</string> <string>Key derivation function</string>
</property>
<property name="minimum">
<number>1</number>
</property>
<property name="maximum">
<number>1048576</number>
</property> </property>
</widget> </widget>
</item> </item>
<item row="4" column="0"> <item row="1" column="0">
<widget class="QLabel" name="parallelismLabel"> <widget class="QLabel" name="kdfLabel">
<property name="text"> <property name="text">
<string>Parallelism:</string> <string>Key Derivation Function:</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="4" column="1"> <item row="0" column="1">
<widget class="QSpinBox" name="parallelismSpinBox"> <widget class="QComboBox" name="algorithmComboBox">
<property name="minimumSize"> <property name="sizePolicy">
<size> <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<width>150</width> <horstretch>0</horstretch>
<height>0</height> <verstretch>0</verstretch>
</size> </sizepolicy>
</property>
<property name="maximumSize">
<size>
<width>150</width>
<height>16777215</height>
</size>
</property> </property>
<property name="accessibleName"> <property name="accessibleName">
<string>Parallelism</string> <string>Encryption algorithm</string>
</property> </property>
<property name="minimum"> <item>
<number>1</number> <property name="text">
<string>AES: 256 Bit (default)</string>
</property> </property>
<property name="maximum"> </item>
<number>128</number> <item>
<property name="text">
<string>Twofish: 256 Bit</string>
</property>
</item>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="algorithmLabel">
<property name="text">
<string>Encryption Algorithm:</string>
</property> </property>
</widget> </widget>
</item> </item>
@ -428,17 +518,19 @@
<property name="sizeHint" stdset="0"> <property name="sizeHint" stdset="0">
<size> <size>
<width>20</width> <width>20</width>
<height>40</height> <height>0</height>
</size> </size>
</property> </property>
</spacer> </spacer>
</item> </item>
</layout> </layout>
</widget> </widget>
</widget>
</item>
</layout>
</widget>
<tabstops> <tabstops>
<tabstop>activateChangeDecryptionTimeButton</tabstop>
<tabstop>decryptionTimeSlider</tabstop> <tabstop>decryptionTimeSlider</tabstop>
<tabstop>compatibilitySelection</tabstop>
<tabstop>algorithmComboBox</tabstop> <tabstop>algorithmComboBox</tabstop>
<tabstop>kdfComboBox</tabstop> <tabstop>kdfComboBox</tabstop>
<tabstop>transformRoundsSpinBox</tabstop> <tabstop>transformRoundsSpinBox</tabstop>

View File

@ -35,11 +35,6 @@ public:
Q_DISABLE_COPY(DatabaseSettingsWidgetGeneral); Q_DISABLE_COPY(DatabaseSettingsWidgetGeneral);
~DatabaseSettingsWidgetGeneral() override; ~DatabaseSettingsWidgetGeneral() override;
inline bool hasAdvancedMode() const override
{
return false;
}
public slots: public slots:
void initialize() override; void initialize() override;
void uninitialize() override; void uninitialize() override;

View File

@ -37,11 +37,6 @@ public:
Q_DISABLE_COPY(DatabaseSettingsWidgetMaintenance); Q_DISABLE_COPY(DatabaseSettingsWidgetMaintenance);
~DatabaseSettingsWidgetMaintenance() override; ~DatabaseSettingsWidgetMaintenance() override;
inline bool hasAdvancedMode() const override
{
return false;
}
public slots: public slots:
void initialize() override; void initialize() override;
void uninitialize() override{}; void uninitialize() override{};

View File

@ -35,11 +35,6 @@ public:
Q_DISABLE_COPY(DatabaseSettingWidgetMetaData); Q_DISABLE_COPY(DatabaseSettingWidgetMetaData);
~DatabaseSettingWidgetMetaData() override; ~DatabaseSettingWidgetMetaData() override;
inline bool hasAdvancedMode() const override
{
return false;
}
public slots: public slots:
void initialize() override; void initialize() override;
void uninitialize() override; void uninitialize() override;

View File

@ -24,28 +24,6 @@ SettingsWidget::SettingsWidget(QWidget* parent)
SettingsWidget::~SettingsWidget() = default; SettingsWidget::~SettingsWidget() = default;
/** void SettingsWidget::discard()
* Switch between simple mode (the default) and advanced mode.
* Subclasses which implement an advanced mode, need to override this method,
* \link advancedMode() and \link hasAdvancedMode.
*
* When overriding this method, make sure to also emit the
* \link advancedModeChanged() signal.
*
* @param advanced whether advanced mode is enabled
*/
void SettingsWidget::setAdvancedMode(bool advanced)
{ {
if (hasAdvancedMode() && advanced != advancedMode()) {
m_advancedMode = advanced;
emit advancedModeChanged(advanced);
}
}
/**
* @return true if advanced mode is on (default: false)
*/
bool SettingsWidget::advancedMode() const
{
return m_advancedMode;
} }

View File

@ -34,13 +34,6 @@ public:
Q_DISABLE_COPY(SettingsWidget); Q_DISABLE_COPY(SettingsWidget);
~SettingsWidget() override; ~SettingsWidget() override;
/**
* @return true if widget has an advanced mode
*/
virtual bool hasAdvancedMode() const = 0;
virtual void setAdvancedMode(bool advanced);
virtual bool advancedMode() const;
public slots: public slots:
/** /**
* Initialize settings widget. * Initialize settings widget.
@ -62,11 +55,10 @@ public slots:
/** /**
* Discard settings. * Discard settings.
*/ */
virtual void discard(){}; virtual void discard();
signals: signals:
void editFinished(bool saved); void editFinished(bool saved);
void advancedModeChanged(bool advanced);
private: private:
bool m_advancedMode = false; bool m_advancedMode = false;

View File

@ -27,8 +27,6 @@ NewDatabaseWizardPage::NewDatabaseWizardPage(QWidget* parent)
, m_ui(new Ui::NewDatabaseWizardPage()) , m_ui(new Ui::NewDatabaseWizardPage())
{ {
m_ui->setupUi(this); m_ui->setupUi(this);
connect(m_ui->advancedSettingsButton, SIGNAL(clicked()), SLOT(toggleAdvancedSettings()));
} }
NewDatabaseWizardPage::~NewDatabaseWizardPage() = default; NewDatabaseWizardPage::~NewDatabaseWizardPage() = default;
@ -43,7 +41,6 @@ void NewDatabaseWizardPage::setPageWidget(DatabaseSettingsWidget* page)
{ {
m_pageWidget = page; m_pageWidget = page;
m_ui->pageContent->setWidget(m_pageWidget); m_ui->pageContent->setWidget(m_pageWidget);
m_ui->advancedSettingsButton->setVisible(m_pageWidget->hasAdvancedMode());
} }
/** /**
@ -86,21 +83,3 @@ bool NewDatabaseWizardPage::validatePage()
m_pageWidget->uninitialize(); m_pageWidget->uninitialize();
return valid; return valid;
} }
/**
* Toggle settings page widget between simple and advanced mode.
*/
void NewDatabaseWizardPage::toggleAdvancedSettings()
{
if (!m_pageWidget || !m_pageWidget->hasAdvancedMode()) {
return;
}
if (m_pageWidget->advancedMode()) {
m_pageWidget->setAdvancedMode(false);
m_ui->advancedSettingsButton->setText(tr("Advanced Settings"));
} else {
m_pageWidget->setAdvancedMode(true);
m_ui->advancedSettingsButton->setText(tr("Simple Settings"));
}
}

View File

@ -47,9 +47,6 @@ public:
void initializePage() override; void initializePage() override;
bool validatePage() override; bool validatePage() override;
public slots:
void toggleAdvancedSettings();
protected: protected:
QPointer<DatabaseSettingsWidget> m_pageWidget; QPointer<DatabaseSettingsWidget> m_pageWidget;
QSharedPointer<Database> m_db; QSharedPointer<Database> m_db;

View File

@ -25,7 +25,7 @@
<property name="subTitle"> <property name="subTitle">
<string>Here you can adjust the database encryption settings. Don't worry, you can change them later in the database settings.</string> <string>Here you can adjust the database encryption settings. Don't worry, you can change them later in the database settings.</string>
</property> </property>
<layout class="QVBoxLayout" name="verticalLayout" stretch="1,0,0"> <layout class="QVBoxLayout" name="verticalLayout" stretch="1">
<item> <item>
<widget class="QScrollArea" name="pageContent"> <widget class="QScrollArea" name="pageContent">
<property name="sizePolicy"> <property name="sizePolicy">
@ -66,49 +66,12 @@ QScrollArea &gt; QWidget &gt; QScrollBar { background: 1; }</string>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>560</width> <width>560</width>
<height>349</height> <height>392</height>
</rect> </rect>
</property> </property>
</widget> </widget>
</widget> </widget>
</item> </item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>6</height>
</size>
</property>
</spacer>
</item>
<item>
<layout class="QHBoxLayout" name="advancedSettings">
<item>
<spacer name="horizontalSpacer_3">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="advancedSettingsButton">
<property name="text">
<string>Advanced Settings</string>
</property>
</widget>
</item>
</layout>
</item>
</layout> </layout>
</widget> </widget>
<resources/> <resources/>

View File

@ -189,7 +189,7 @@ void TestGui::testSettingsDefaultTabOrder()
QVERIFY(dbSettingsWidget->isVisible()); QVERIFY(dbSettingsWidget->isVisible());
QCOMPARE(dbSettingsWidget->findChild<CategoryListWidget*>("categoryList")->currentCategory(), 0); QCOMPARE(dbSettingsWidget->findChild<CategoryListWidget*>("categoryList")->currentCategory(), 0);
for (auto* w : dbSettingsWidget->findChildren<QTabWidget*>()) { for (auto* w : dbSettingsWidget->findChildren<QTabWidget*>()) {
if (w->currentIndex() != 0) { if (w->currentIndex() != 0 && w->objectName() != "encryptionSettingsTabWidget") {
QFAIL("Database settings contain QTabWidgets whose default index is not 0"); QFAIL("Database settings contain QTabWidgets whose default index is not 0");
} }
} }
@ -208,12 +208,16 @@ void TestGui::testCreateDatabase()
QTest::keyClick(wizard, Qt::Key_Enter); QTest::keyClick(wizard, Qt::Key_Enter);
QCOMPARE(wizard->currentId(), 1); QCOMPARE(wizard->currentId(), 1);
// Check that basic encryption settings are visible
auto decryptionTimeSlider = wizard->currentPage()->findChild<QSlider*>("decryptionTimeSlider"); auto decryptionTimeSlider = wizard->currentPage()->findChild<QSlider*>("decryptionTimeSlider");
auto algorithmComboBox = wizard->currentPage()->findChild<QComboBox*>("algorithmComboBox"); auto algorithmComboBox = wizard->currentPage()->findChild<QComboBox*>("algorithmComboBox");
QTRY_VERIFY(decryptionTimeSlider->isVisible()); QTRY_VERIFY(decryptionTimeSlider->isVisible());
QVERIFY(!algorithmComboBox->isVisible()); QVERIFY(!algorithmComboBox->isVisible());
auto advancedToggle = wizard->currentPage()->findChild<QPushButton*>("advancedSettingsButton");
QTest::mouseClick(advancedToggle, Qt::MouseButton::LeftButton); // Set the encryption settings to the advanced view
auto encryptionSettings = wizard->currentPage()->findChild<QTabWidget*>("encryptionSettingsTabWidget");
auto advancedTab = encryptionSettings->findChild<QWidget*>("advancedTab");
encryptionSettings->setCurrentWidget(advancedTab);
QTRY_VERIFY(!decryptionTimeSlider->isVisible()); QTRY_VERIFY(!decryptionTimeSlider->isVisible());
QVERIFY(algorithmComboBox->isVisible()); QVERIFY(algorithmComboBox->isVisible());
@ -1468,19 +1472,24 @@ void TestGui::testDatabaseSettings()
auto* dbSettingsDialog = m_dbWidget->findChild<QWidget*>("databaseSettingsDialog"); auto* dbSettingsDialog = m_dbWidget->findChild<QWidget*>("databaseSettingsDialog");
auto* dbSettingsCategoryList = dbSettingsDialog->findChild<CategoryListWidget*>("categoryList"); auto* dbSettingsCategoryList = dbSettingsDialog->findChild<CategoryListWidget*>("categoryList");
auto* dbSettingsStackedWidget = dbSettingsDialog->findChild<QStackedWidget*>("stackedWidget"); auto* dbSettingsStackedWidget = dbSettingsDialog->findChild<QStackedWidget*>("stackedWidget");
auto* transformRoundsSpinBox = dbSettingsDialog->findChild<QSpinBox*>("transformRoundsSpinBox");
auto advancedToggle = dbSettingsDialog->findChild<QCheckBox*>("advancedSettingsToggle");
auto* autosaveDelayCheckBox = dbSettingsDialog->findChild<QCheckBox*>("autosaveDelayCheckBox"); auto* autosaveDelayCheckBox = dbSettingsDialog->findChild<QCheckBox*>("autosaveDelayCheckBox");
auto* autosaveDelaySpinBox = dbSettingsDialog->findChild<QSpinBox*>("autosaveDelaySpinBox"); auto* autosaveDelaySpinBox = dbSettingsDialog->findChild<QSpinBox*>("autosaveDelaySpinBox");
auto* dbSettingsButtonBox = dbSettingsDialog->findChild<QDialogButtonBox*>("buttonBox"); auto* dbSettingsButtonBox = dbSettingsDialog->findChild<QDialogButtonBox*>("buttonBox");
int autosaveDelayTestValue = 2; int autosaveDelayTestValue = 2;
advancedToggle->setChecked(true);
QApplication::processEvents();
dbSettingsCategoryList->setCurrentCategory(1); // go into security category dbSettingsCategoryList->setCurrentCategory(1); // go into security category
dbSettingsStackedWidget->findChild<QTabWidget*>()->setCurrentIndex(1); // go into encryption tab dbSettingsStackedWidget->findChild<QTabWidget*>()->setCurrentIndex(1); // go into encryption tab
QVERIFY(transformRoundsSpinBox != nullptr);
auto encryptionSettings = dbSettingsDialog->findChild<QTabWidget*>("encryptionSettingsTabWidget");
auto advancedTab = encryptionSettings->findChild<QWidget*>("advancedTab");
encryptionSettings->setCurrentWidget(advancedTab);
QApplication::processEvents();
auto transformRoundsSpinBox = advancedTab->findChild<QSpinBox*>("transformRoundsSpinBox");
QVERIFY(transformRoundsSpinBox);
QVERIFY(transformRoundsSpinBox->isVisible());
transformRoundsSpinBox->setValue(123456); transformRoundsSpinBox->setValue(123456);
QTest::keyClick(transformRoundsSpinBox, Qt::Key_Enter); QTest::keyClick(transformRoundsSpinBox, Qt::Key_Enter);
QTRY_COMPARE(m_db->kdf()->rounds(), 123456); QTRY_COMPARE(m_db->kdf()->rounds(), 123456);

View File

@ -66,8 +66,6 @@ void TestGuiBrowser::initTestCase()
config()->set(Config::AutoSaveOnExit, false); config()->set(Config::AutoSaveOnExit, false);
// Enable the tray icon so we can test hiding/restoring the windowQByteArray // Enable the tray icon so we can test hiding/restoring the windowQByteArray
config()->set(Config::GUI_ShowTrayIcon, true); config()->set(Config::GUI_ShowTrayIcon, true);
// Disable advanced settings mode (activate within individual tests to test advanced settings)
config()->set(Config::GUI_AdvancedSettings, false);
// Disable the update check first time alert // Disable the update check first time alert
config()->set(Config::UpdateCheckMessageShown, true); config()->set(Config::UpdateCheckMessageShown, true);