From 45848c3f611b88015c8227be197baac07a284b3d Mon Sep 17 00:00:00 2001 From: Andrew Meyer Date: Fri, 8 May 2020 23:48:03 -0400 Subject: 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 --- src/gui/DatabaseWidget.cpp | 47 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) (limited to 'src/gui/DatabaseWidget.cpp') 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, -- cgit v1.2.3