diff --git a/share/translations/keepassx_en.ts b/share/translations/keepassx_en.ts
index 677273187..694c27c9b 100644
--- a/share/translations/keepassx_en.ts
+++ b/share/translations/keepassx_en.ts
@@ -19,10 +19,6 @@
KeePassXC is distributed under the terms of the GNU General Public License (GPL) version 2 or (at your option) version 3.
-
- Project Maintainers:
-
- Contributors
@@ -70,6 +66,11 @@ Kernel: %3 %4
Enabled extensions:
+
+ Build Type: Snapshot
+
+
+ AccessControlDialog
@@ -819,6 +820,22 @@ If you keep this number, your database may be too easy to crack!
Failed to transform key with new KDF parameters; KDF unchanged.
+
+ MiB
+ Abbreviation for Mebibytes (KDF settings)
+
+
+
+
+
+
+ thread(s)
+ Threads for parallel execution (KDF settings)
+
+
+
+
+ DatabaseSettingsWidgetEncryption
@@ -850,18 +867,10 @@ If you keep this number, your database may be too easy to crack!
Memory Usage:
-
- MB
-
- Parallelism:
-
- thread
-
- DatabaseSettingsWidgetGeneral
@@ -901,6 +910,14 @@ If you keep this number, your database may be too easy to crack!
Use recycle bin
+
+ Additional Database Settings
+
+
+
+ Enable &compression (recommended)
+
+ DatabaseTabWidget
@@ -1018,6 +1035,15 @@ Do you want to save the database before locking it?
Otherwise your changes are lost.
+
+ Disable safe saves?
+
+
+
+ KeePassXC has failed to save the database multiple times. This is likely caused by file sync services holding a lock on the save file.
+Disable safe saves and try again?
+
+ DatabaseWidget
@@ -1817,6 +1843,65 @@ Do you want to merge your changes?
URL
+
+ Never
+
+
+
+ Password
+
+
+
+ Notes
+
+
+
+ Expires
+
+
+
+ Created
+
+
+
+ Modified
+
+
+
+ Accessed
+
+
+
+ Attachments
+
+
+
+
+ EntryView
+
+ Customize View
+
+
+
+ Hide Usernames
+
+
+
+ Hide Passwords
+
+
+
+ Fit to window
+
+
+
+ Fit to contents
+
+
+
+ Reset to defaults
+
+ Group
@@ -2694,6 +2779,12 @@ This is a one-way migration. You won't be able to open the imported databas
Please touch the button on your YubiKey!
+
+ WARNING: You are using an unstable build of KeePassXC!
+There is a high risk of corruption, maintain a backup of your databases.
+This version is not meant for production use.
+
+ OpenSSHKey
@@ -3650,6 +3741,30 @@ Please unlock the selected database or choose another one which is unlocked.Milliseconds
+
+ Startup
+
+
+
+ File Management
+
+
+
+ Safely save database files (may be incompatible with Dropbox, etc)
+
+
+
+ Backup database file before saving
+
+
+
+ Entry Management
+
+
+
+ General
+
+ SettingsWidgetSecurity
@@ -3787,10 +3902,6 @@ Please unlock the selected database or choose another one which is unlocked.
WelcomeWidget
-
- Welcome to KeePassXC
-
- Start storing your passwords securely in a KeePassXC database
@@ -3815,6 +3926,10 @@ Please unlock the selected database or choose another one which is unlocked.Recent databases
+
+ Welcome to KeePassXC %1
+
+ main
diff --git a/src/core/Config.cpp b/src/core/Config.cpp
index f42bb6044..c83c1e720 100644
--- a/src/core/Config.cpp
+++ b/src/core/Config.cpp
@@ -21,7 +21,6 @@
#include
#include
#include
-#include
#include
Config* Config::m_instance(nullptr);
@@ -51,6 +50,18 @@ void Config::set(const QString& key, const QVariant& value)
m_settings->setValue(key, value);
}
+/**
+ * Sync configuration with persistent storage.
+ *
+ * Usually, you don't need to call this method manually, but if you are writing
+ * configurations after an emitted \link QCoreApplication::aboutToQuit() signal,
+ * use it to guarantee your config values are persisted.
+ */
+void Config::sync()
+{
+ m_settings->sync();
+}
+
Config::Config(const QString& fileName, QObject* parent)
: QObject(parent)
{
@@ -106,6 +117,7 @@ Config::~Config()
void Config::init(const QString& fileName)
{
m_settings.reset(new QSettings(fileName, QSettings::IniFormat));
+ connect(qApp, &QCoreApplication::aboutToQuit, this, &Config::sync);
m_defaults.insert("SingleInstance", true);
m_defaults.insert("RememberLastDatabases", true);
@@ -162,7 +174,7 @@ void Config::createConfigFromFile(const QString& file)
void Config::createTempFileInstance()
{
Q_ASSERT(!m_instance);
- QTemporaryFile* tmpFile = new QTemporaryFile();
+ auto* tmpFile = new QTemporaryFile();
bool openResult = tmpFile->open();
Q_ASSERT(openResult);
Q_UNUSED(openResult);
diff --git a/src/core/Config.h b/src/core/Config.h
index 2ee3f4dce..eb7978622 100644
--- a/src/core/Config.h
+++ b/src/core/Config.h
@@ -26,15 +26,18 @@ class QSettings;
class Config : public QObject
{
- Q_OBJECT
+Q_OBJECT
public:
- ~Config();
+ Q_DISABLE_COPY(Config)
+
+ ~Config() override;
QVariant get(const QString& key);
QVariant get(const QString& key, const QVariant& defaultValue);
QString getFileName();
void set(const QString& key, const QVariant& value);
bool hasAccessError();
+ void sync();
static Config* instance();
static void createConfigFromFile(const QString& file);
@@ -49,8 +52,6 @@ private:
QScopedPointer m_settings;
QHash m_defaults;
-
- Q_DISABLE_COPY(Config)
};
inline Config* config() {
diff --git a/src/gui/DatabaseSettingsWidget.cpp b/src/gui/DatabaseSettingsWidget.cpp
index baea2558a..cad04b297 100644
--- a/src/gui/DatabaseSettingsWidget.cpp
+++ b/src/gui/DatabaseSettingsWidget.cpp
@@ -57,6 +57,9 @@ DatabaseSettingsWidget::DatabaseSettingsWidget(QWidget* parent)
connect(m_uiEncryption->transformBenchmarkButton, SIGNAL(clicked()), SLOT(transformRoundsBenchmark()));
connect(m_uiEncryption->kdfComboBox, SIGNAL(currentIndexChanged(int)), SLOT(kdfChanged(int)));
+ connect(m_uiEncryption->memorySpinBox, SIGNAL(valueChanged(int)), this, SLOT(memoryChanged(int)));
+ connect(m_uiEncryption->parallelismSpinBox, SIGNAL(valueChanged(int)), this, SLOT(parallelismChanged(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);
@@ -121,7 +124,7 @@ void DatabaseSettingsWidget::load(Database* db)
kdfChanged(kdfIndex);
}
- // properly initialize parallelism spin box (may be overwritten by actual KDF values)
+ m_uiEncryption->memorySpinBox->setValue(64);
m_uiEncryption->parallelismSpinBox->setValue(QThread::idealThreadCount());
// Setup kdf parameters
@@ -289,3 +292,21 @@ void DatabaseSettingsWidget::kdfChanged(int index)
transformRoundsBenchmark();
}
+
+/**
+ * Update memory spin box suffix on value change.
+ */
+void DatabaseSettingsWidget::memoryChanged(int value)
+{
+ m_uiEncryption->memorySpinBox->setSuffix(
+ tr(" MiB", "Abbreviation for Mebibytes (KDF settings)", value));
+}
+
+/**
+ * Update parallelism spin box suffix on value change.
+ */
+void DatabaseSettingsWidget::parallelismChanged(int value)
+{
+ m_uiEncryption->parallelismSpinBox->setSuffix(
+ tr(" thread(s)", "Threads for parallel execution (KDF settings)", value));
+}
diff --git a/src/gui/DatabaseSettingsWidget.h b/src/gui/DatabaseSettingsWidget.h
index 8410af37e..b0cae5dbc 100644
--- a/src/gui/DatabaseSettingsWidget.h
+++ b/src/gui/DatabaseSettingsWidget.h
@@ -54,6 +54,8 @@ private slots:
void reject();
void transformRoundsBenchmark();
void kdfChanged(int index);
+ void memoryChanged(int value);
+ void parallelismChanged(int value);
private:
void truncateHistories();
diff --git a/src/gui/DatabaseSettingsWidgetEncryption.ui b/src/gui/DatabaseSettingsWidgetEncryption.ui
index 4c4d2aed2..502bc012c 100644
--- a/src/gui/DatabaseSettingsWidgetEncryption.ui
+++ b/src/gui/DatabaseSettingsWidgetEncryption.ui
@@ -139,18 +139,12 @@
16777215
-
- MB
- 11048576
-
- 64
-
@@ -174,9 +168,6 @@
16777215
-
- thread
- 1
diff --git a/src/gui/DatabaseTabWidget.h b/src/gui/DatabaseTabWidget.h
index b216750ea..b839fb3ab 100644
--- a/src/gui/DatabaseTabWidget.h
+++ b/src/gui/DatabaseTabWidget.h
@@ -1,19 +1,19 @@
/*
- * Copyright (C) 2011 Felix Geyer
- * Copyright (C) 2017 KeePassXC Team
+ * Copyright (C) 2017 KeePassXC Team
+ * Copyright (C) 2011 Felix Geyer
*
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 2 or (at your option)
- * version 3 of the License.
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 or (at your option)
+ * version 3 of the License.
*
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
*/
#ifndef KEEPASSX_DATABASETABWIDGET_H
@@ -51,7 +51,7 @@ class DatabaseTabWidget : public QTabWidget
public:
explicit DatabaseTabWidget(QWidget* parent = nullptr);
- ~DatabaseTabWidget();
+ ~DatabaseTabWidget() override;
void openDatabase(const QString& fileName, const QString& pw = QString(),
const QString& keyFile = QString());
void mergeDatabase(const QString& fileName);
@@ -116,7 +116,7 @@ private:
void connectDatabase(Database* newDb, Database* oldDb = nullptr);
QHash m_dbList;
- DatabaseWidgetStateSync* m_dbWidgetStateSync;
+ QPointer m_dbWidgetStateSync;
};
#endif // KEEPASSX_DATABASETABWIDGET_H
diff --git a/src/gui/DatabaseWidget.cpp b/src/gui/DatabaseWidget.cpp
index 5f6ee56bb..b7a622b19 100644
--- a/src/gui/DatabaseWidget.cpp
+++ b/src/gui/DatabaseWidget.cpp
@@ -1,19 +1,19 @@
/*
- * Copyright (C) 2010 Felix Geyer
- * Copyright (C) 2017 KeePassXC Team
+ * Copyright (C) 2017 KeePassXC Team
+ * Copyright (C) 2010 Felix Geyer
*
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 2 or (at your option)
- * version 3 of the License.
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 or (at your option)
+ * version 3 of the License.
*
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
*/
#include "DatabaseWidget.h"
diff --git a/src/gui/DatabaseWidgetStateSync.cpp b/src/gui/DatabaseWidgetStateSync.cpp
index 39904ed99..9b89412ea 100644
--- a/src/gui/DatabaseWidgetStateSync.cpp
+++ b/src/gui/DatabaseWidgetStateSync.cpp
@@ -1,24 +1,26 @@
/*
- * Copyright (C) 2014 Felix Geyer
- * Copyright (C) 2014 Florian Geyer
+ * Copyright (C) 2018 KeePassXC Team
+ * Copyright (C) 2014 Felix Geyer
+ * Copyright (C) 2014 Florian Geyer
*
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 2 or (at your option)
- * version 3 of the License.
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 or (at your option)
+ * version 3 of the License.
*
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
*/
#include "DatabaseWidgetStateSync.h"
#include "core/Config.h"
+#include
DatabaseWidgetStateSync::DatabaseWidgetStateSync(QObject* parent)
: QObject(parent)
@@ -31,9 +33,18 @@ DatabaseWidgetStateSync::DatabaseWidgetStateSync(QObject* parent)
m_hidePasswords = config()->get("GUI/HidePasswords").toBool();
m_listViewState = config()->get("GUI/ListViewState").toByteArray();
m_searchViewState = config()->get("GUI/SearchViewState").toByteArray();
+
+ connect(qApp, &QCoreApplication::aboutToQuit, this, &DatabaseWidgetStateSync::sync);
}
DatabaseWidgetStateSync::~DatabaseWidgetStateSync()
+{
+}
+
+/**
+ * Sync state with persistent storage.
+ */
+void DatabaseWidgetStateSync::sync()
{
config()->set("GUI/SplitterState", intListToVariant(m_mainSplitterSizes));
config()->set("GUI/DetailSplitterState", intListToVariant(m_detailSplitterSizes));
@@ -41,12 +52,13 @@ DatabaseWidgetStateSync::~DatabaseWidgetStateSync()
config()->set("GUI/HidePasswords", m_hidePasswords);
config()->set("GUI/ListViewState", m_listViewState);
config()->set("GUI/SearchViewState", m_searchViewState);
+ config()->sync();
}
void DatabaseWidgetStateSync::setActive(DatabaseWidget* dbWidget)
{
if (m_activeDbWidget) {
- disconnect(m_activeDbWidget, 0, this, 0);
+ disconnect(m_activeDbWidget, nullptr, this, nullptr);
}
m_activeDbWidget = dbWidget;
diff --git a/src/gui/DatabaseWidgetStateSync.h b/src/gui/DatabaseWidgetStateSync.h
index aca593f1f..0b1c9b7cb 100644
--- a/src/gui/DatabaseWidgetStateSync.h
+++ b/src/gui/DatabaseWidgetStateSync.h
@@ -1,19 +1,20 @@
/*
- * Copyright (C) 2014 Felix Geyer
- * Copyright (C) 2014 Florian Geyer
+ * Copyright (C) 2018 KeePassXC Team
+ * Copyright (C) 2014 Felix Geyer
+ * Copyright (C) 2014 Florian Geyer
*
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 2 or (at your option)
- * version 3 of the License.
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 or (at your option)
+ * version 3 of the License.
*
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
*/
#ifndef KEEPASSX_DATABASEWIDGETSTATESYNC_H
@@ -27,7 +28,7 @@ class DatabaseWidgetStateSync : public QObject
public:
explicit DatabaseWidgetStateSync(QObject* parent = nullptr);
- ~DatabaseWidgetStateSync();
+ ~DatabaseWidgetStateSync() override;
public slots:
void setActive(DatabaseWidget* dbWidget);
@@ -38,12 +39,13 @@ private slots:
void blockUpdates();
void updateSplitterSizes();
void updateViewState();
+ void sync();
private:
static QList variantToIntList(const QVariant& variant);
static QVariant intListToVariant(const QList& list);
- DatabaseWidget* m_activeDbWidget;
+ QPointer m_activeDbWidget;
bool m_blockUpdates;
QList m_mainSplitterSizes;
diff --git a/src/gui/entry/EntryView.cpp b/src/gui/entry/EntryView.cpp
index 36d60ced5..67169d27f 100644
--- a/src/gui/entry/EntryView.cpp
+++ b/src/gui/entry/EntryView.cpp
@@ -1,18 +1,19 @@
/*
- * Copyright (C) 2010 Felix Geyer
+ * Copyright (C) 2018 KeePassXC Team
+ * Copyright (C) 2010 Felix Geyer
*
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 2 or (at your option)
- * version 3 of the License.
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 or (at your option)
+ * version 3 of the License.
*
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
*/
#include "EntryView.h"
@@ -88,11 +89,11 @@ EntryView::EntryView(QWidget* parent)
// Stretching of last section interferes with fitting columns to window
header()->setStretchLastSection(false);
header()->setContextMenuPolicy(Qt::CustomContextMenu);
- connect(header(), SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(showHeaderMenu(QPoint)));
- connect(header(), SIGNAL(sectionCountChanged(int, int)), this, SIGNAL(viewStateChanged()));
- connect(header(), SIGNAL(sectionMoved(int, int, int)), this, SIGNAL(viewStateChanged()));
- connect(header(), SIGNAL(sectionResized(int, int, int)), this, SIGNAL(viewStateChanged()));
- connect(header(), SIGNAL(sortIndicatorChanged(int, Qt::SortOrder)), this, SIGNAL(viewStateChanged()));
+ connect(header(), SIGNAL(customContextMenuRequested(QPoint)), SLOT(showHeaderMenu(QPoint)));
+ connect(header(), SIGNAL(sectionCountChanged(int, int)), SIGNAL(viewStateChanged()));
+ connect(header(), SIGNAL(sectionMoved(int, int, int)), SIGNAL(viewStateChanged()));
+ connect(header(), SIGNAL(sectionResized(int, int, int)), SIGNAL(viewStateChanged()));
+ connect(header(), SIGNAL(sortIndicatorChanged(int, Qt::SortOrder)), SIGNAL(viewStateChanged()));
// TODO: not working as expected, columns will end up being very small,
// most likely due to the widget not being sized properly at this time
diff --git a/src/gui/entry/EntryView.h b/src/gui/entry/EntryView.h
index 1bea22f49..26672a665 100644
--- a/src/gui/entry/EntryView.h
+++ b/src/gui/entry/EntryView.h
@@ -1,18 +1,19 @@
/*
- * Copyright (C) 2010 Felix Geyer
+ * Copyright (C) 2018 KeePassXC Team
+ * Copyright (C) 2010 Felix Geyer
*
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 2 or (at your option)
- * version 3 of the License.
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 or (at your option)
+ * version 3 of the License.
*
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
*/
#ifndef KEEPASSX_ENTRYVIEW_H