Add Import/Export for profile lists

File -> Export Profiles... writes all profiles (plus explicit, including
empty, folders) to a JSON file. File -> Import Profiles... reads one back,
recreates folders, and inserts profiles as new rows so IDs never collide
with the destination database. No credentials are ever persisted on a
Profile in the first place (only privateKeyPath, a filesystem path), so
nothing sensitive is exposed by an exported file.

Verified with a standalone headless round-trip test against isolated
app-data databases (SSH + RDP profiles, nested folders, all fields);
caught and fixed a bug where import was redundantly creating an explicit
folder row per profile that didn't exist in the original export.

Fixes #17.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-09-15 06:22:26 -06:00
co-authored by Claude Sonnet 5
parent 4f8fa3272b
commit dffca3afef
3 changed files with 190 additions and 0 deletions
+11
View File
@@ -170,6 +170,9 @@ SessionWindow::SessionWindow(QWidget* parent)
QAction* newProfileAction = fileMenu->addAction(QStringLiteral("New Profile"));
QAction* newFolderAction = fileMenu->addAction(QStringLiteral("New Folder"));
fileMenu->addSeparator();
QAction* importProfilesAction = fileMenu->addAction(QStringLiteral("Import Profiles..."));
QAction* exportProfilesAction = fileMenu->addAction(QStringLiteral("Export Profiles..."));
fileMenu->addSeparator();
QAction* quitAction = fileMenu->addAction(QStringLiteral("Quit"));
connect(newProfileAction,
@@ -180,6 +183,14 @@ SessionWindow::SessionWindow(QWidget* parent)
&QAction::triggered,
this,
[this]() { m_profilesWidget->createFolderInCurrentContext(); });
connect(importProfilesAction,
&QAction::triggered,
this,
[this]() { m_profilesWidget->importProfiles(); });
connect(exportProfilesAction,
&QAction::triggered,
this,
[this]() { m_profilesWidget->exportProfiles(); });
connect(quitAction, &QAction::triggered, this, []() { qApp->quit(); });
QMenu* helpMenu = menuBar()->addMenu(QStringLiteral("Help"));