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
diff options
context:
space:
mode:
authorAndrew Meyer <apmeyer@bgsu.edu>2020-05-09 06:48:03 +0300
committerJonathan White <support@dmapps.us>2020-05-16 18:00:27 +0300
commit45848c3f611b88015c8227be197baac07a284b3d (patch)
tree04f2706254702c443a01cd09308acfbd1473338f /src
parent2237cf0188af38898e1492f5d7ce2c0f087c8f35 (diff)
Implement 'Save Database Backup' option
Add an option in the 'Database' menu to save a backup of the current database. Add unit test for saving database copy * Open a test database, mark it as modified, and save a copy * Fail if the copy is not a valid database * Fail if the original database is saved * Fail if the original database is no longer marked as modified
Diffstat (limited to 'src')
-rw-r--r--src/gui/DatabaseTabWidget.cpp14
-rw-r--r--src/gui/DatabaseTabWidget.h1
-rw-r--r--src/gui/DatabaseWidget.cpp47
-rw-r--r--src/gui/DatabaseWidget.h1
-rw-r--r--src/gui/MainWindow.cpp5
-rw-r--r--src/gui/MainWindow.ui12
6 files changed, 77 insertions, 3 deletions
diff --git a/src/gui/DatabaseTabWidget.cpp b/src/gui/DatabaseTabWidget.cpp
index 8088ae829..f484815af 100644
--- a/src/gui/DatabaseTabWidget.cpp
+++ b/src/gui/DatabaseTabWidget.cpp
@@ -393,6 +393,20 @@ bool DatabaseTabWidget::saveDatabaseAs(int index)
return ok;
}
+bool DatabaseTabWidget::saveDatabaseBackup(int index)
+{
+ if (index == -1) {
+ index = currentIndex();
+ }
+
+ auto* dbWidget = databaseWidgetFromIndex(index);
+ bool ok = dbWidget->saveBackup();
+ if (ok) {
+ updateLastDatabases(dbWidget->database()->filePath());
+ }
+ return ok;
+}
+
void DatabaseTabWidget::closeDatabaseFromSender()
{
auto* dbWidget = qobject_cast<DatabaseWidget*>(sender());
diff --git a/src/gui/DatabaseTabWidget.h b/src/gui/DatabaseTabWidget.h
index b8cbdbb6f..d7c656908 100644
--- a/src/gui/DatabaseTabWidget.h
+++ b/src/gui/DatabaseTabWidget.h
@@ -68,6 +68,7 @@ public slots:
void importOpVaultDatabase();
bool saveDatabase(int index = -1);
bool saveDatabaseAs(int index = -1);
+ bool saveDatabaseBackup(int index = -1);
void exportToCsv();
void exportToHtml();
diff --git a/src/gui/DatabaseWidget.cpp b/src/gui/DatabaseWidget.cpp
index a7531537e..310f141d7 100644
--- a/src/gui/DatabaseWidget.cpp
+++ b/src/gui/DatabaseWidget.cpp
@@ -1866,6 +1866,53 @@ bool DatabaseWidget::saveAs()
}
}
+/**
+ * Save copy of database under a new user-selected filename.
+ *
+ * @return true on success
+ */
+bool DatabaseWidget::saveBackup()
+{
+ while (true) {
+ QString oldFilePath = m_db->filePath();
+ if (!QFileInfo::exists(oldFilePath)) {
+ oldFilePath = QDir::toNativeSeparators(config()->get(Config::LastDir).toString() + "/"
+ + tr("Passwords").append(".kdbx"));
+ }
+ const QString newFilePath = fileDialog()->getSaveFileName(this,
+ tr("Save database backup"),
+ oldFilePath,
+ tr("KeePass 2 Database").append(" (*.kdbx)"),
+ nullptr,
+ nullptr);
+
+ if (!newFilePath.isEmpty()) {
+ // Ensure we don't recurse back into this function
+ m_db->setReadOnly(false);
+ m_db->setFilePath(newFilePath);
+ m_saveAttempts = 0;
+
+ bool modified = m_db->isModified();
+
+ if (!save()) {
+ // Failed to save, try again
+ m_db->setFilePath(oldFilePath);
+ continue;
+ }
+
+ m_db->setFilePath(oldFilePath);
+ if (modified) {
+ // Source database is marked as clean when copy is saved, even if source has unsaved changes
+ m_db->markAsModified();
+ }
+ return true;
+ }
+
+ // Canceled file selection
+ return false;
+ }
+}
+
void DatabaseWidget::showMessage(const QString& text,
MessageWidget::MessageType type,
bool showClosebutton,
diff --git a/src/gui/DatabaseWidget.h b/src/gui/DatabaseWidget.h
index 0d0afe8f1..3f25a4361 100644
--- a/src/gui/DatabaseWidget.h
+++ b/src/gui/DatabaseWidget.h
@@ -158,6 +158,7 @@ public slots:
bool lock();
bool save();
bool saveAs();
+ bool saveBackup();
void replaceDatabase(QSharedPointer<Database> db);
void createEntry();
diff --git a/src/gui/MainWindow.cpp b/src/gui/MainWindow.cpp
index 0a0118eda..476a675fa 100644
--- a/src/gui/MainWindow.cpp
+++ b/src/gui/MainWindow.cpp
@@ -324,6 +324,7 @@ MainWindow::MainWindow()
m_ui->actionDatabaseOpen->setIcon(resources()->icon("document-open"));
m_ui->actionDatabaseSave->setIcon(resources()->icon("document-save"));
m_ui->actionDatabaseSaveAs->setIcon(resources()->icon("document-save-as"));
+ m_ui->actionDatabaseSaveBackup->setIcon(resources()->icon("document-save-copy"));
m_ui->actionDatabaseClose->setIcon(resources()->icon("document-close"));
m_ui->actionReports->setIcon(resources()->icon("reports"));
m_ui->actionChangeDatabaseSettings->setIcon(resources()->icon("document-edit"));
@@ -396,6 +397,7 @@ MainWindow::MainWindow()
connect(m_ui->actionDatabaseOpen, SIGNAL(triggered()), m_ui->tabWidget, SLOT(openDatabase()));
connect(m_ui->actionDatabaseSave, SIGNAL(triggered()), m_ui->tabWidget, SLOT(saveDatabase()));
connect(m_ui->actionDatabaseSaveAs, SIGNAL(triggered()), m_ui->tabWidget, SLOT(saveDatabaseAs()));
+ connect(m_ui->actionDatabaseSaveBackup, SIGNAL(triggered()), m_ui->tabWidget, SLOT(saveDatabaseBackup()));
connect(m_ui->actionDatabaseClose, SIGNAL(triggered()), m_ui->tabWidget, SLOT(closeCurrentDatabaseTab()));
connect(m_ui->actionDatabaseMerge, SIGNAL(triggered()), m_ui->tabWidget, SLOT(mergeDatabase()));
connect(m_ui->actionChangeMasterKey, SIGNAL(triggered()), m_ui->tabWidget, SLOT(changeMasterKey()));
@@ -681,6 +683,7 @@ void MainWindow::setMenuActionState(DatabaseWidget::Mode mode)
m_ui->actionChangeDatabaseSettings->setEnabled(true);
m_ui->actionDatabaseSave->setEnabled(m_ui->tabWidget->canSave());
m_ui->actionDatabaseSaveAs->setEnabled(true);
+ m_ui->actionDatabaseSaveBackup->setEnabled(true);
m_ui->menuExport->setEnabled(true);
m_ui->actionExportCsv->setEnabled(true);
m_ui->actionExportHtml->setEnabled(true);
@@ -736,6 +739,7 @@ void MainWindow::setMenuActionState(DatabaseWidget::Mode mode)
m_ui->actionChangeDatabaseSettings->setEnabled(false);
m_ui->actionDatabaseSave->setEnabled(false);
m_ui->actionDatabaseSaveAs->setEnabled(false);
+ m_ui->actionDatabaseSaveBackup->setEnabled(false);
m_ui->menuExport->setEnabled(false);
m_ui->actionExportCsv->setEnabled(false);
m_ui->actionExportHtml->setEnabled(false);
@@ -764,6 +768,7 @@ void MainWindow::setMenuActionState(DatabaseWidget::Mode mode)
m_ui->actionChangeDatabaseSettings->setEnabled(false);
m_ui->actionDatabaseSave->setEnabled(false);
m_ui->actionDatabaseSaveAs->setEnabled(false);
+ m_ui->actionDatabaseSaveBackup->setEnabled(false);
m_ui->actionDatabaseClose->setEnabled(false);
m_ui->menuExport->setEnabled(false);
m_ui->actionExportCsv->setEnabled(false);
diff --git a/src/gui/MainWindow.ui b/src/gui/MainWindow.ui
index c40191d6b..bc8aa48de 100644
--- a/src/gui/MainWindow.ui
+++ b/src/gui/MainWindow.ui
@@ -260,6 +260,7 @@
<addaction name="menuRecentDatabases"/>
<addaction name="actionDatabaseSave"/>
<addaction name="actionDatabaseSaveAs"/>
+ <addaction name="actionDatabaseSaveBackup"/>
<addaction name="actionDatabaseClose"/>
<addaction name="separator"/>
<addaction name="actionChangeMasterKey"/>
@@ -332,9 +333,6 @@
<addaction name="separator"/>
<addaction name="actionEntryOpenUrl"/>
<addaction name="actionEntryDownloadIcon"/>
- <addaction name="separator"/>
- <addaction name="actionEntryAddToAgent"/>
- <addaction name="actionEntryRemoveFromAgent"/>
</widget>
<widget class="QMenu" name="menuGroups">
<property name="title">
@@ -808,6 +806,14 @@
<string notr="true">Ctrl+/</string>
</property>
</action>
+ <action name="actionDatabaseSaveBackup">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="text">
+ <string>Save Database Backup...</string>
+ </property>
+ </action>
<action name="actionEntryAddToAgent">
<property name="text">
<string>Add key to SSH Agent</string>