diff --git a/docs/images/export_database.png b/docs/images/export_database.png index 92a417ac..aa46f086 100644 Binary files a/docs/images/export_database.png and b/docs/images/export_database.png differ diff --git a/docs/topics/ImportExport.adoc b/docs/topics/ImportExport.adoc index f56135a1..5a1991d0 100644 --- a/docs/topics/ImportExport.adoc +++ b/docs/topics/ImportExport.adoc @@ -55,7 +55,7 @@ To import a KeePass 1 database file in KeePassXC, perform the following steps: 6. The data from the `.kdb` file gets imported and converted to the new format, which is compatible with KeePassXC. You can now start using the new database file (`.kdbx`) in KeePassXC. == Exporting Databases -KeePassXC supports multiple ways to export your database for transfer to another program or to print out and archive. To export your database into the KDB XML format, you must use the KeePassXC CLI: `keepassxc-cli export `. +KeePassXC supports multiple ways to export your database for transfer to another program or to print out and archive. WARNING: Exporting your database will result in all of your passwords and sensitive information being stored in an unencrypted format. We do not recommend saving your exported database for long periods of time as that can cause a compromise of sensitive information. diff --git a/share/translations/keepassxc_en.ts b/share/translations/keepassxc_en.ts index e22ccb97..ac5d43f5 100644 --- a/share/translations/keepassxc_en.ts +++ b/share/translations/keepassxc_en.ts @@ -2246,6 +2246,18 @@ This is definitely a bug, please report it to the developers. Database tab name modifier + + Export database to XML file + + + + XML file + + + + Writing the XML file failed + + DatabaseWidget @@ -5434,6 +5446,14 @@ We recommend you use the AppImage available on our downloads page. Copy Password and TOTP + + &XML File… + + + + XML File… + + ManageDatabase diff --git a/src/gui/DatabaseTabWidget.cpp b/src/gui/DatabaseTabWidget.cpp index 21c367b8..8437a701 100644 --- a/src/gui/DatabaseTabWidget.cpp +++ b/src/gui/DatabaseTabWidget.cpp @@ -493,6 +493,40 @@ void DatabaseTabWidget::exportToHtml() exportDialog->exec(); } +void DatabaseTabWidget::exportToXML() +{ + auto db = databaseWidgetFromIndex(currentIndex())->database(); + if (!db) { + Q_ASSERT(false); + return; + } + + if (!warnOnExport()) { + return; + } + + auto fileName = fileDialog()->getSaveFileName( + this, tr("Export database to XML file"), FileDialog::getLastDir("xml"), tr("XML file").append(" (*.xml)")); + if (fileName.isEmpty()) { + return; + } + + FileDialog::saveLastDir("xml", fileName, true); + + QByteArray xmlData; + QString err; + if (!db->extract(xmlData, &err)) { + emit messageGlobal(tr("Writing the XML file failed").append("\n").append(err), MessageWidget::Error); + } + + QFile file(fileName); + if (!file.open(QIODevice::WriteOnly | QIODevice::Truncate)) { + emit messageGlobal(tr("Writing the XML file failed").append("\n").append(file.errorString()), + MessageWidget::Error); + } + file.write(xmlData); +} + bool DatabaseTabWidget::warnOnExport() { auto ans = diff --git a/src/gui/DatabaseTabWidget.h b/src/gui/DatabaseTabWidget.h index dfd0cff8..38a1822b 100644 --- a/src/gui/DatabaseTabWidget.h +++ b/src/gui/DatabaseTabWidget.h @@ -71,6 +71,7 @@ public slots: bool saveDatabaseBackup(int index = -1); void exportToCsv(); void exportToHtml(); + void exportToXML(); bool lockDatabases(); void lockDatabasesDelayed(); diff --git a/src/gui/MainWindow.cpp b/src/gui/MainWindow.cpp index d761e914..6e0207d6 100644 --- a/src/gui/MainWindow.cpp +++ b/src/gui/MainWindow.cpp @@ -485,6 +485,7 @@ MainWindow::MainWindow() connect(m_ui->actionImportOpVault, SIGNAL(triggered()), m_ui->tabWidget, SLOT(importOpVaultDatabase())); connect(m_ui->actionExportCsv, SIGNAL(triggered()), m_ui->tabWidget, SLOT(exportToCsv())); connect(m_ui->actionExportHtml, SIGNAL(triggered()), m_ui->tabWidget, SLOT(exportToHtml())); + connect(m_ui->actionExportXML, SIGNAL(triggered()), m_ui->tabWidget, SLOT(exportToXML())); connect( m_ui->actionLockDatabase, SIGNAL(triggered()), m_ui->tabWidget, SLOT(lockAndSwitchToFirstUnlockedDatabase())); connect(m_ui->actionLockDatabaseToolbar, SIGNAL(triggered()), m_ui->actionLockDatabase, SIGNAL(triggered())); @@ -973,6 +974,7 @@ void MainWindow::setMenuActionState(DatabaseWidget::Mode mode) m_ui->menuExport->setEnabled(true); m_ui->actionExportCsv->setEnabled(true); m_ui->actionExportHtml->setEnabled(true); + m_ui->actionExportXML->setEnabled(true); m_ui->actionDatabaseMerge->setEnabled(m_ui->tabWidget->currentIndex() != -1); #ifdef WITH_XC_SSHAGENT bool singleEntryHasSshKey = diff --git a/src/gui/MainWindow.ui b/src/gui/MainWindow.ui index f41cd508..60b9d1b8 100644 --- a/src/gui/MainWindow.ui +++ b/src/gui/MainWindow.ui @@ -216,7 +216,7 @@ 0 0 800 - 21 + 25 @@ -245,6 +245,12 @@ + + + + + &Quit + @@ -1101,6 +1107,17 @@ &Lock Database + + + false + + + &XML File… + + + XML File… + +