diff --git a/share/icons/application/32x32/actions/document-encrypt.png b/share/icons/application/32x32/actions/document-encrypt.png new file mode 100644 index 000000000..353a22ca2 Binary files /dev/null and b/share/icons/application/32x32/actions/document-encrypt.png differ diff --git a/src/gui/DatabaseSettingsWidget.cpp b/src/gui/DatabaseSettingsWidget.cpp index 5d1764cd6..9335b0ab8 100644 --- a/src/gui/DatabaseSettingsWidget.cpp +++ b/src/gui/DatabaseSettingsWidget.cpp @@ -17,10 +17,13 @@ #include "DatabaseSettingsWidget.h" #include "ui_DatabaseSettingsWidget.h" +#include "ui_DatabaseSettingsWidgetGeneral.h" +#include "ui_DatabaseSettingsWidgetEncryption.h" #include #include "core/Global.h" +#include "core/FilePath.h" #include "core/AsyncTask.h" #include "core/Database.h" #include "core/Group.h" @@ -32,18 +35,31 @@ DatabaseSettingsWidget::DatabaseSettingsWidget(QWidget* parent) : DialogyWidget(parent) , m_ui(new Ui::DatabaseSettingsWidget()) + , m_uiGeneral(new Ui::DatabaseSettingsWidgetGeneral()) + , m_uiEncryption(new Ui::DatabaseSettingsWidgetEncryption()) + , m_uiGeneralPage(new QWidget()) + , m_uiEncryptionPage(new QWidget()) , m_db(nullptr) { m_ui->setupUi(this); + m_uiGeneral->setupUi(m_uiGeneralPage); + m_uiEncryption->setupUi(m_uiEncryptionPage); connect(m_ui->buttonBox, SIGNAL(accepted()), SLOT(save())); connect(m_ui->buttonBox, SIGNAL(rejected()), SLOT(reject())); - connect(m_ui->historyMaxItemsCheckBox, SIGNAL(toggled(bool)), - m_ui->historyMaxItemsSpinBox, SLOT(setEnabled(bool))); - connect(m_ui->historyMaxSizeCheckBox, SIGNAL(toggled(bool)), - m_ui->historyMaxSizeSpinBox, SLOT(setEnabled(bool))); - connect(m_ui->transformBenchmarkButton, SIGNAL(clicked()), SLOT(transformRoundsBenchmark())); - connect(m_ui->kdfComboBox, SIGNAL(currentIndexChanged(int)), SLOT(kdfChanged(int))); + connect(m_uiGeneral->historyMaxItemsCheckBox, SIGNAL(toggled(bool)), + m_uiGeneral->historyMaxItemsSpinBox, SLOT(setEnabled(bool))); + connect(m_uiGeneral->historyMaxSizeCheckBox, SIGNAL(toggled(bool)), + m_uiGeneral->historyMaxSizeSpinBox, SLOT(setEnabled(bool))); + connect(m_uiEncryption->transformBenchmarkButton, SIGNAL(clicked()), SLOT(transformRoundsBenchmark())); + connect(m_uiEncryption->kdfComboBox, SIGNAL(currentIndexChanged(int)), SLOT(kdfChanged(int))); + + m_ui->categoryList->addCategory(tr("General"), FilePath::instance()->icon("categories", "preferences-other")); + m_ui->categoryList->addCategory(tr("Encryption"), FilePath::instance()->icon("actions", "document-encrypt")); + m_ui->stackedWidget->addWidget(m_uiGeneralPage); + m_ui->stackedWidget->addWidget(m_uiEncryptionPage); + + connect(m_ui->categoryList, SIGNAL(categoryChanged(int)), m_ui->stackedWidget, SLOT(setCurrentIndex(int))); } DatabaseSettingsWidget::~DatabaseSettingsWidget() @@ -56,77 +72,77 @@ void DatabaseSettingsWidget::load(Database* db) Metadata* meta = m_db->metadata(); - m_ui->dbNameEdit->setText(meta->name()); - m_ui->dbDescriptionEdit->setText(meta->description()); - m_ui->recycleBinEnabledCheckBox->setChecked(meta->recycleBinEnabled()); - m_ui->defaultUsernameEdit->setText(meta->defaultUserName()); + m_uiGeneral->dbNameEdit->setText(meta->name()); + m_uiGeneral->dbDescriptionEdit->setText(meta->description()); + m_uiGeneral->recycleBinEnabledCheckBox->setChecked(meta->recycleBinEnabled()); + m_uiGeneral->defaultUsernameEdit->setText(meta->defaultUserName()); if (meta->historyMaxItems() > -1) { - m_ui->historyMaxItemsSpinBox->setValue(meta->historyMaxItems()); - m_ui->historyMaxItemsCheckBox->setChecked(true); + m_uiGeneral->historyMaxItemsSpinBox->setValue(meta->historyMaxItems()); + m_uiGeneral->historyMaxItemsCheckBox->setChecked(true); } else { - m_ui->historyMaxItemsSpinBox->setValue(Metadata::DefaultHistoryMaxItems); - m_ui->historyMaxItemsCheckBox->setChecked(false); + m_uiGeneral->historyMaxItemsSpinBox->setValue(Metadata::DefaultHistoryMaxItems); + m_uiGeneral->historyMaxItemsCheckBox->setChecked(false); } int historyMaxSizeMiB = qRound(meta->historyMaxSize() / qreal(1048576)); if (historyMaxSizeMiB > 0) { - m_ui->historyMaxSizeSpinBox->setValue(historyMaxSizeMiB); - m_ui->historyMaxSizeCheckBox->setChecked(true); + m_uiGeneral->historyMaxSizeSpinBox->setValue(historyMaxSizeMiB); + m_uiGeneral->historyMaxSizeCheckBox->setChecked(true); } else { - m_ui->historyMaxSizeSpinBox->setValue(Metadata::DefaultHistoryMaxSize); - m_ui->historyMaxSizeCheckBox->setChecked(false); + m_uiGeneral->historyMaxSizeSpinBox->setValue(Metadata::DefaultHistoryMaxSize); + m_uiGeneral->historyMaxSizeCheckBox->setChecked(false); } - m_ui->algorithmComboBox->clear(); + m_uiEncryption->algorithmComboBox->clear(); for (auto& cipher: asConst(KeePass2::CIPHERS)) { - m_ui->algorithmComboBox->addItem(cipher.second, cipher.first.toByteArray()); + m_uiEncryption->algorithmComboBox->addItem(cipher.second, cipher.first.toByteArray()); } - int cipherIndex = m_ui->algorithmComboBox->findData(m_db->cipher().toByteArray()); + int cipherIndex = m_uiEncryption->algorithmComboBox->findData(m_db->cipher().toByteArray()); if (cipherIndex > -1) { - m_ui->algorithmComboBox->setCurrentIndex(cipherIndex); + m_uiEncryption->algorithmComboBox->setCurrentIndex(cipherIndex); } // Setup kdf combo box - m_ui->kdfComboBox->blockSignals(true); - m_ui->kdfComboBox->clear(); + m_uiEncryption->kdfComboBox->blockSignals(true); + m_uiEncryption->kdfComboBox->clear(); for (auto& kdf: asConst(KeePass2::KDFS)) { - m_ui->kdfComboBox->addItem(kdf.second, kdf.first.toByteArray()); + m_uiEncryption->kdfComboBox->addItem(kdf.second, kdf.first.toByteArray()); } - m_ui->kdfComboBox->blockSignals(false); + m_uiEncryption->kdfComboBox->blockSignals(false); auto kdfUuid = m_db->kdf()->uuid(); - int kdfIndex = m_ui->kdfComboBox->findData(kdfUuid.toByteArray()); + int kdfIndex = m_uiEncryption->kdfComboBox->findData(kdfUuid.toByteArray()); if (kdfIndex > -1) { - m_ui->kdfComboBox->setCurrentIndex(kdfIndex); + m_uiEncryption->kdfComboBox->setCurrentIndex(kdfIndex); kdfChanged(kdfIndex); } // Setup kdf parameters auto kdf = m_db->kdf(); - m_ui->transformRoundsSpinBox->setValue(kdf->rounds()); + m_uiEncryption->transformRoundsSpinBox->setValue(kdf->rounds()); if (kdfUuid == KeePass2::KDF_ARGON2) { auto argon2Kdf = kdf.staticCast(); - m_ui->memorySpinBox->setValue(argon2Kdf->memory() / (1<<10)); - m_ui->parallelismSpinBox->setValue(argon2Kdf->parallelism()); + m_uiEncryption->memorySpinBox->setValue(static_cast(argon2Kdf->memory()) / (1 << 10)); + m_uiEncryption->parallelismSpinBox->setValue(argon2Kdf->parallelism()); } - m_ui->dbNameEdit->setFocus(); + m_uiGeneral->dbNameEdit->setFocus(); } void DatabaseSettingsWidget::save() { Metadata* meta = m_db->metadata(); - meta->setName(m_ui->dbNameEdit->text()); - meta->setDescription(m_ui->dbDescriptionEdit->text()); - meta->setDefaultUserName(m_ui->defaultUsernameEdit->text()); - meta->setRecycleBinEnabled(m_ui->recycleBinEnabledCheckBox->isChecked()); + meta->setName(m_uiGeneral->dbNameEdit->text()); + meta->setDescription(m_uiGeneral->dbDescriptionEdit->text()); + meta->setDefaultUserName(m_uiGeneral->defaultUsernameEdit->text()); + meta->setRecycleBinEnabled(m_uiGeneral->recycleBinEnabledCheckBox->isChecked()); meta->setSettingsChanged(QDateTime::currentDateTimeUtc()); bool truncate = false; int historyMaxItems; - if (m_ui->historyMaxItemsCheckBox->isChecked()) { - historyMaxItems = m_ui->historyMaxItemsSpinBox->value(); + if (m_uiGeneral->historyMaxItemsCheckBox->isChecked()) { + historyMaxItems = m_uiGeneral->historyMaxItemsSpinBox->value(); } else { historyMaxItems = -1; } @@ -136,8 +152,8 @@ void DatabaseSettingsWidget::save() } int historyMaxSize; - if (m_ui->historyMaxSizeCheckBox->isChecked()) { - historyMaxSize = m_ui->historyMaxSizeSpinBox->value() * 1048576; + if (m_uiGeneral->historyMaxSizeCheckBox->isChecked()) { + historyMaxSize = m_uiGeneral->historyMaxSizeSpinBox->value() * 1048576; } else { historyMaxSize = -1; } @@ -150,15 +166,15 @@ void DatabaseSettingsWidget::save() truncateHistories(); } - m_db->setCipher(Uuid(m_ui->algorithmComboBox->currentData().toByteArray())); + m_db->setCipher(Uuid(m_uiEncryption->algorithmComboBox->currentData().toByteArray())); // Save kdf parameters - auto kdf = KeePass2::uuidToKdf(Uuid(m_ui->kdfComboBox->currentData().toByteArray())); - kdf->setRounds(m_ui->transformRoundsSpinBox->value()); + auto kdf = KeePass2::uuidToKdf(Uuid(m_uiEncryption->kdfComboBox->currentData().toByteArray())); + kdf->setRounds(m_uiEncryption->transformRoundsSpinBox->value()); if (kdf->uuid() == KeePass2::KDF_ARGON2) { auto argon2Kdf = kdf.staticCast(); - argon2Kdf->setMemory(m_ui->memorySpinBox->value() * (1<<10)); - argon2Kdf->setParallelism(m_ui->parallelismSpinBox->value()); + argon2Kdf->setMemory(static_cast(m_uiEncryption->memorySpinBox->value()) * (1 << 10)); + argon2Kdf->setParallelism(static_cast(m_uiEncryption->parallelismSpinBox->value())); } QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); @@ -183,30 +199,30 @@ void DatabaseSettingsWidget::reject() void DatabaseSettingsWidget::transformRoundsBenchmark() { QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); - m_ui->transformBenchmarkButton->setEnabled(false); + m_uiEncryption->transformBenchmarkButton->setEnabled(false); + m_uiEncryption->transformRoundsSpinBox->setFocus(); // Create a new kdf with the current parameters - auto kdf = KeePass2::uuidToKdf(Uuid(m_ui->kdfComboBox->currentData().toByteArray())); - kdf->setRounds(m_ui->transformRoundsSpinBox->value()); + auto kdf = KeePass2::uuidToKdf(Uuid(m_uiEncryption->kdfComboBox->currentData().toByteArray())); + kdf->setRounds(m_uiEncryption->transformRoundsSpinBox->value()); if (kdf->uuid() == KeePass2::KDF_ARGON2) { auto argon2Kdf = kdf.staticCast(); - if (!argon2Kdf->setMemory(m_ui->memorySpinBox->value() * (1<<10))) { - m_ui->memorySpinBox->setValue(argon2Kdf->memory() / (1<<10)); + if (!argon2Kdf->setMemory(static_cast(m_uiEncryption->memorySpinBox->value()) * (1 << 10))) { + m_uiEncryption->memorySpinBox->setValue(static_cast(argon2Kdf->memory() / (1 << 10))); } - if (!argon2Kdf->setParallelism(m_ui->parallelismSpinBox->value())) { - m_ui->parallelismSpinBox->setValue(argon2Kdf->parallelism()); + if (!argon2Kdf->setParallelism(static_cast(m_uiEncryption->parallelismSpinBox->value()))) { + m_uiEncryption->parallelismSpinBox->setValue(argon2Kdf->parallelism()); } } // Determine the number of rounds required to meet 1 second delay - int rounds = AsyncTask::runAndWaitForFuture([kdf]() { + int rounds = AsyncTask::runAndWaitForFuture([&kdf]() { return kdf->benchmark(1000); }); - m_ui->transformRoundsSpinBox->setValue(rounds); - + m_uiEncryption->transformRoundsSpinBox->setValue(rounds); + m_uiEncryption->transformBenchmarkButton->setEnabled(true); QApplication::restoreOverrideCursor(); - m_ui->transformBenchmarkButton->setEnabled(true); } void DatabaseSettingsWidget::truncateHistories() @@ -219,12 +235,13 @@ void DatabaseSettingsWidget::truncateHistories() void DatabaseSettingsWidget::kdfChanged(int index) { - Uuid id(m_ui->kdfComboBox->itemData(index).toByteArray()); - if (id == KeePass2::KDF_ARGON2) { - m_ui->memorySpinBox->setEnabled(true); - m_ui->parallelismSpinBox->setEnabled(true); - } else { - m_ui->memorySpinBox->setEnabled(false); - m_ui->parallelismSpinBox->setEnabled(false); - } + Uuid id(m_uiEncryption->kdfComboBox->itemData(index).toByteArray()); + + bool memoryEnabled = id == KeePass2::KDF_ARGON2; + m_uiEncryption->memoryUsageLabel->setEnabled(memoryEnabled); + m_uiEncryption->memorySpinBox->setEnabled(memoryEnabled); + + bool parallelismEnabled = id == KeePass2::KDF_ARGON2; + m_uiEncryption->parallelismLabel->setEnabled(parallelismEnabled); + m_uiEncryption->parallelismSpinBox->setEnabled(parallelismEnabled); } diff --git a/src/gui/DatabaseSettingsWidget.h b/src/gui/DatabaseSettingsWidget.h index 83a5eb098..8410af37e 100644 --- a/src/gui/DatabaseSettingsWidget.h +++ b/src/gui/DatabaseSettingsWidget.h @@ -31,6 +31,8 @@ class Database; namespace Ui { class DatabaseSettingsWidget; +class DatabaseSettingsWidgetGeneral; +class DatabaseSettingsWidgetEncryption; } class DatabaseSettingsWidget: public DialogyWidget @@ -57,6 +59,10 @@ private: void truncateHistories(); const QScopedPointer m_ui; + const QScopedPointer m_uiGeneral; + const QScopedPointer m_uiEncryption; + QWidget* m_uiGeneralPage; + QWidget* m_uiEncryptionPage; Database* m_db; }; diff --git a/src/gui/DatabaseSettingsWidget.ui b/src/gui/DatabaseSettingsWidget.ui index 5a6778678..9b45feaa7 100644 --- a/src/gui/DatabaseSettingsWidget.ui +++ b/src/gui/DatabaseSettingsWidget.ui @@ -7,320 +7,45 @@ 0 0 1082 - 506 + 578 - + - - - Qt::Vertical - - - - 0 - 0 - - - - - - + - - - Qt::Horizontal - - - - 0 - 0 - - - + - - - - 400 - 16777215 - + + + -1 - - - - - Max. history size: - - - - - - - - - - - - MB - - - 1 - - - 1048576 - - - 64 - - - - - - - - - Database name: - - - - - - - Max. history items: - - - - - - - Key Derivation Function - - - - - - - - AES: 256 Bit (default) - - - - - Twofish: 256 Bit - - - - - - - - Encryption Algorithm: - - - - - - - Database description: - - - - - - - - - - - - - - - - 0 - 0 - - - - 2000000000 - - - - - - - - - - - - 0 - 0 - - - - MiB - - - 1 - - - 2000000000 - - - - - - - - - - 0 - 0 - - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - 1 - - - 1000000000 - - - - - - - - 0 - 0 - - - - Benchmark 1-second delay - - - - - - - true - - - - - - - Default username: - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - Transform rounds: - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - Memory Usage: - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - Parallelism: - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - thread - - - 1 - - - 128 - - - - - - - Use recycle bin - - - - - - - - Qt::Horizontal - - - - 0 - 0 - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - QDialogButtonBox::Cancel|QDialogButtonBox::Ok - - + + + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + - - dbNameEdit - dbDescriptionEdit - historyMaxItemsCheckBox - historyMaxItemsSpinBox - historyMaxSizeCheckBox - historyMaxSizeSpinBox - buttonBox - + + + CategoryListWidget + QWidget +
gui/CategoryListWidget.h
+ 1 +
+
- + \ No newline at end of file diff --git a/src/gui/DatabaseSettingsWidgetEncryption.ui b/src/gui/DatabaseSettingsWidgetEncryption.ui new file mode 100644 index 000000000..4c4d2aed2 --- /dev/null +++ b/src/gui/DatabaseSettingsWidgetEncryption.ui @@ -0,0 +1,192 @@ + + + DatabaseSettingsWidgetEncryption + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + Encryption Algorithm: + + + + + + + + 0 + 0 + + + + + AES: 256 Bit (default) + + + + + Twofish: 256 Bit + + + + + + + + Key Derivation Function: + + + + + + + + 0 + 0 + + + + + + + + Transform rounds: + + + + + + + + + + 150 + 0 + + + + + 150 + 16777215 + + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + 1 + + + 1000000000 + + + + + + + Qt::WheelFocus + + + Benchmark 1-second delay + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + Memory Usage: + + + + + + + + 150 + 0 + + + + + 150 + 16777215 + + + + MB + + + 1 + + + 1048576 + + + 64 + + + + + + + Parallelism: + + + + + + + + 150 + 0 + + + + + 150 + 16777215 + + + + thread + + + 1 + + + 128 + + + + + + + + diff --git a/src/gui/DatabaseSettingsWidgetGeneral.ui b/src/gui/DatabaseSettingsWidgetGeneral.ui new file mode 100644 index 000000000..c072c1d8d --- /dev/null +++ b/src/gui/DatabaseSettingsWidgetGeneral.ui @@ -0,0 +1,154 @@ + + + DatabaseSettingsWidgetGeneral + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + Database Meta Data + + + + + + Database name: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + + + Database description: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + + + Default username: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + true + + + + + + + + + + History Settings + + + + + + + + Max. history items: + + + + + + + Max. history size: + + + + + + + MiB + + + 1 + + + 2000000000 + + + + + + + 2000000000 + + + + + + + Use recycle bin + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + +