Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/keepassxreboot/keepassxc.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/src/gui
diff options
context:
space:
mode:
authorPatrick Klein <42714034+libklein@users.noreply.github.com>2021-11-08 01:41:17 +0300
committerGitHub <noreply@github.com>2021-11-08 01:41:17 +0300
commit84ff6a13f9cd11214396deb31d54955abbcd7b0b (patch)
tree0fa0d84475f9f79c4a8ce12d8582715b0f084940 /src/gui
parent8d7e4918109b1e40660e2988e79e1cf15e899580 (diff)
Allow specifing database backup paths. (#7035)
- Default backupFilePath is '{DB_FILENAME}.old.kdbx' to conform to existing standards - Implement backupPathPattern tests. - Show tooltip on how to format database backup location text field.
Diffstat (limited to 'src/gui')
-rw-r--r--src/gui/ApplicationSettingsWidget.cpp25
-rw-r--r--src/gui/ApplicationSettingsWidget.h1
-rw-r--r--src/gui/ApplicationSettingsWidgetGeneral.ui50
-rw-r--r--src/gui/DatabaseWidget.cpp25
4 files changed, 97 insertions, 4 deletions
diff --git a/src/gui/ApplicationSettingsWidget.cpp b/src/gui/ApplicationSettingsWidget.cpp
index 100258120..ac96d23b4 100644
--- a/src/gui/ApplicationSettingsWidget.cpp
+++ b/src/gui/ApplicationSettingsWidget.cpp
@@ -19,6 +19,8 @@
#include "ApplicationSettingsWidget.h"
#include "ui_ApplicationSettingsWidgetGeneral.h"
#include "ui_ApplicationSettingsWidgetSecurity.h"
+#include <QDesktopServices>
+#include <QDir>
#include "config-keepassx.h"
@@ -28,6 +30,7 @@
#include "gui/MainWindow.h"
#include "gui/osutils/OSUtils.h"
+#include "FileDialog.h"
#include "MessageBox.h"
#ifdef Q_OS_MACOS
#include "touchid/TouchID.h"
@@ -112,6 +115,12 @@ ApplicationSettingsWidget::ApplicationSettingsWidget(QWidget* parent)
connect(m_generalUi->useAlternativeSaveCheckBox, SIGNAL(toggled(bool)),
m_generalUi->alternativeSaveComboBox, SLOT(setEnabled(bool)));
+ connect(m_generalUi->backupBeforeSaveCheckBox, SIGNAL(toggled(bool)),
+ m_generalUi->backupFilePath, SLOT(setEnabled(bool)));
+ connect(m_generalUi->backupBeforeSaveCheckBox, SIGNAL(toggled(bool)),
+ m_generalUi->backupFilePathPicker, SLOT(setEnabled(bool)));
+ connect(m_generalUi->backupFilePathPicker, SIGNAL(pressed()), SLOT(selectBackupDirectory()));
+
connect(m_secUi->clearClipboardCheckBox, SIGNAL(toggled(bool)),
m_secUi->clearClipboardSpinBox, SLOT(setEnabled(bool)));
connect(m_secUi->clearSearchCheckBox, SIGNAL(toggled(bool)),
@@ -188,6 +197,9 @@ void ApplicationSettingsWidget::loadSettings()
m_generalUi->autoSaveOnExitCheckBox->setChecked(config()->get(Config::AutoSaveOnExit).toBool());
m_generalUi->autoSaveNonDataChangesCheckBox->setChecked(config()->get(Config::AutoSaveNonDataChanges).toBool());
m_generalUi->backupBeforeSaveCheckBox->setChecked(config()->get(Config::BackupBeforeSave).toBool());
+
+ m_generalUi->backupFilePath->setText(config()->get(Config::BackupFilePathPattern).toString());
+
m_generalUi->useAlternativeSaveCheckBox->setChecked(!config()->get(Config::UseAtomicSaves).toBool());
m_generalUi->alternativeSaveComboBox->setCurrentIndex(config()->get(Config::UseDirectWriteSaves).toBool() ? 1 : 0);
m_generalUi->autoReloadOnChangeCheckBox->setChecked(config()->get(Config::AutoReloadOnChange).toBool());
@@ -326,6 +338,9 @@ void ApplicationSettingsWidget::saveSettings()
config()->set(Config::AutoSaveOnExit, m_generalUi->autoSaveOnExitCheckBox->isChecked());
config()->set(Config::AutoSaveNonDataChanges, m_generalUi->autoSaveNonDataChangesCheckBox->isChecked());
config()->set(Config::BackupBeforeSave, m_generalUi->backupBeforeSaveCheckBox->isChecked());
+
+ config()->set(Config::BackupFilePathPattern, m_generalUi->backupFilePath->text());
+
config()->set(Config::UseAtomicSaves, !m_generalUi->useAlternativeSaveCheckBox->isChecked());
config()->set(Config::UseDirectWriteSaves, m_generalUi->alternativeSaveComboBox->currentIndex() == 1);
config()->set(Config::AutoReloadOnChange, m_generalUi->autoReloadOnChangeCheckBox->isChecked());
@@ -504,3 +519,13 @@ void ApplicationSettingsWidget::checkUpdatesToggled(bool checked)
{
m_generalUi->checkForUpdatesIncludeBetasCheckBox->setEnabled(checked);
}
+
+void ApplicationSettingsWidget::selectBackupDirectory()
+{
+ auto backupDirectory =
+ FileDialog::instance()->getExistingDirectory(this, tr("Select backup storage directory"), QDir::homePath());
+ if (!backupDirectory.isEmpty()) {
+ m_generalUi->backupFilePath->setText(
+ QDir(backupDirectory).filePath(config()->getDefault(Config::BackupFilePathPattern).toString()));
+ }
+} \ No newline at end of file
diff --git a/src/gui/ApplicationSettingsWidget.h b/src/gui/ApplicationSettingsWidget.h
index f36e5ef12..c5f2ed7e3 100644
--- a/src/gui/ApplicationSettingsWidget.h
+++ b/src/gui/ApplicationSettingsWidget.h
@@ -62,6 +62,7 @@ private slots:
void systrayToggled(bool checked);
void rememberDatabasesToggled(bool checked);
void checkUpdatesToggled(bool checked);
+ void selectBackupDirectory();
private:
QWidget* const m_secWidget;
diff --git a/src/gui/ApplicationSettingsWidgetGeneral.ui b/src/gui/ApplicationSettingsWidgetGeneral.ui
index 0e18dfde6..7729e7c8f 100644
--- a/src/gui/ApplicationSettingsWidgetGeneral.ui
+++ b/src/gui/ApplicationSettingsWidgetGeneral.ui
@@ -58,8 +58,8 @@
<rect>
<x>0</x>
<y>0</y>
- <width>581</width>
- <height>924</height>
+ <width>664</width>
+ <height>1215</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_8">
@@ -279,6 +279,52 @@
</widget>
</item>
<item>
+ <layout class="QHBoxLayout" name="horizontalLayout_4">
+ <item>
+ <widget class="QLabel" name="label">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Minimum" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Backup destination</string>
+ </property>
+ <property name="buddy">
+ <cstring>backupFilePath</cstring>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLineEdit" name="backupFilePath">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="toolTip">
+ <string>Specifies the database backup file location. Occurences of &quot;{DB_FILENAME}&quot; are replaced with the filename of the saved database without extension. {TIME:&lt;format&gt;} is replaced with the backup time, see https://doc.qt.io/qt-5/qdatetime.html#toString. &lt;format&gt; defaults to format string &quot;dd_MM_yyyy_hh-mm-ss&quot;.</string>
+ </property>
+ <property name="placeholderText">
+ <string>{DB_FILENAME}.old.kdbx</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="backupFilePathPicker">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="text">
+ <string>Choose...</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_5"/>
+ </item>
+ <item>
<widget class="QCheckBox" name="useAlternativeSaveCheckBox">
<property name="text">
<string>Use alternative saving method (may solve problems with Dropbox, Google Drive, GVFS, etc.)</string>
diff --git a/src/gui/DatabaseWidget.cpp b/src/gui/DatabaseWidget.cpp
index 7a7d961ae..6d88a6613 100644
--- a/src/gui/DatabaseWidget.cpp
+++ b/src/gui/DatabaseWidget.cpp
@@ -27,6 +27,7 @@
#include <QProcess>
#include <QSplitter>
#include <QTextEdit>
+#include <core/Tools.h>
#include "autotype/AutoType.h"
#include "core/EntrySearcher.h"
@@ -1879,11 +1880,31 @@ bool DatabaseWidget::performSave(QString& errorMessage, const QString& fileName)
}
}
+ QString backupFilePath;
+ if (config()->get(Config::BackupBeforeSave).toBool()) {
+ backupFilePath = config()->get(Config::BackupFilePathPattern).toString();
+ // Fall back to default
+ if (backupFilePath.isEmpty()) {
+ backupFilePath = config()->getDefault(Config::BackupFilePathPattern).toString();
+ }
+
+ QFileInfo dbFileInfo(m_db->filePath());
+ backupFilePath = Tools::substituteBackupFilePath(backupFilePath, dbFileInfo.canonicalFilePath());
+ if (!backupFilePath.isNull()) {
+ // Note that we cannot guarantee that backupFilePath is actually a valid filename. QT currently provides
+ // no function for this. Moreover, we don't check if backupFilePath is a file and not a directory.
+ // If this isn't the case, just let the backup fail.
+ if (QDir::isRelativePath(backupFilePath)) {
+ backupFilePath = QDir::cleanPath(dbFileInfo.absolutePath() + QDir::separator() + backupFilePath);
+ }
+ }
+ }
+
bool ok;
if (fileName.isEmpty()) {
- ok = m_db->save(saveAction, config()->get(Config::BackupBeforeSave).toBool(), &errorMessage);
+ ok = m_db->save(saveAction, backupFilePath, &errorMessage);
} else {
- ok = m_db->saveAs(fileName, saveAction, config()->get(Config::BackupBeforeSave).toBool(), &errorMessage);
+ ok = m_db->saveAs(fileName, saveAction, backupFilePath, &errorMessage);
}
// Return control