From 03fd78f382dd6b25aa926487071b4eaef0d051bd Mon Sep 17 00:00:00 2001 From: Jonathan White Date: Sat, 1 Jun 2024 15:24:55 -0400 Subject: [PATCH] Improve CSV import when title field isn't specified * Fixes #10433 --- share/translations/keepassxc_en.ts | 9 +++++++++ src/gui/csvImport/CsvImportWidget.cpp | 25 ++++++++++++++++++++----- src/gui/csvImport/CsvParserModel.cpp | 5 +++++ src/gui/csvImport/CsvParserModel.h | 2 +- 4 files changed, 35 insertions(+), 6 deletions(-) diff --git a/share/translations/keepassxc_en.ts b/share/translations/keepassxc_en.ts index 6192f8d1cd..24c3b1dd7d 100644 --- a/share/translations/keepassxc_en.ts +++ b/share/translations/keepassxc_en.ts @@ -1391,6 +1391,15 @@ Do you want to overwrite the passkey in %1 - %2? Imported from CSV file: %1 + + No Title Selected + + + + No title column was selected, entries will be hard to tell apart. +Are you sure you want to import? + + CsvParserModel diff --git a/src/gui/csvImport/CsvImportWidget.cpp b/src/gui/csvImport/CsvImportWidget.cpp index dfd3606da7..91613d1f83 100644 --- a/src/gui/csvImport/CsvImportWidget.cpp +++ b/src/gui/csvImport/CsvImportWidget.cpp @@ -25,6 +25,7 @@ #include "core/Totp.h" #include "format/CsvParser.h" #include "format/KeePass2Writer.h" +#include "gui/MessageBox.h" #include "gui/csvImport/CsvParserModel.h" #include @@ -213,19 +214,29 @@ void CsvImportWidget::parse() QSharedPointer CsvImportWidget::buildDatabase() { + // Warn if the title column wasn't specified + if (m_combos[1]->currentIndex() == 0) { + auto ans = MessageBox::question( + this, + tr("No Title Selected"), + tr("No title column was selected, entries will be hard to tell apart.\nAre you sure you want to import?"), + MessageBox::Continue | MessageBox::Cancel); + if (ans == MessageBox::Cancel) { + return {}; + } + } + auto db = QSharedPointer::create(); db->rootGroup()->setNotes(tr("Imported from CSV file: %1").arg(m_filename)); - for (int r = 0; r < m_parserModel->rowCount(); ++r) { - // use validity of second column as a GO/NOGO for all others fields - if (!m_parserModel->data(m_parserModel->index(r, 1)).isValid()) { - continue; - } + auto rows = m_parserModel->rowCount() - m_parserModel->skippedRows(); + for (int r = 0; r < rows; ++r) { auto group = createGroupStructure(db.data(), m_parserModel->data(m_parserModel->index(r, 0)).toString()); if (!group) { continue; } + // Standard entry fields auto entry = new Entry(); entry->setUuid(QUuid::createUuid()); entry->setGroup(group); @@ -235,6 +246,7 @@ QSharedPointer CsvImportWidget::buildDatabase() entry->setUrl(m_parserModel->data(m_parserModel->index(r, 4)).toString()); entry->setNotes(m_parserModel->data(m_parserModel->index(r, 5)).toString()); + // TOTP auto otpString = m_parserModel->data(m_parserModel->index(r, 6)); if (otpString.isValid() && !otpString.toString().isEmpty()) { auto totp = Totp::parseSettings(otpString.toString()); @@ -245,12 +257,14 @@ QSharedPointer CsvImportWidget::buildDatabase() entry->setTotp(totp); } + // Icon bool ok; int icon = m_parserModel->data(m_parserModel->index(r, 7)).toInt(&ok); if (ok) { entry->setIcon(icon); } + // Modified Time TimeInfo timeInfo; if (m_parserModel->data(m_parserModel->index(r, 8)).isValid()) { auto datetime = m_parserModel->data(m_parserModel->index(r, 8)).toString(); @@ -270,6 +284,7 @@ QSharedPointer CsvImportWidget::buildDatabase() } } } + // Creation Time if (m_parserModel->data(m_parserModel->index(r, 9)).isValid()) { auto datetime = m_parserModel->data(m_parserModel->index(r, 9)).toString(); if (datetime.contains(QRegularExpression("^\\d+$"))) { diff --git a/src/gui/csvImport/CsvParserModel.cpp b/src/gui/csvImport/CsvParserModel.cpp index eb59157d33..892b8917bb 100644 --- a/src/gui/csvImport/CsvParserModel.cpp +++ b/src/gui/csvImport/CsvParserModel.cpp @@ -92,6 +92,11 @@ void CsvParserModel::setSkippedRows(int skipped) emit layoutChanged(); } +int CsvParserModel::skippedRows() const +{ + return m_skipped; +} + void CsvParserModel::setHeaderLabels(const QStringList& labels) { m_columnHeader = labels; diff --git a/src/gui/csvImport/CsvParserModel.h b/src/gui/csvImport/CsvParserModel.h index 2717b826dc..d9fb4af468 100644 --- a/src/gui/csvImport/CsvParserModel.h +++ b/src/gui/csvImport/CsvParserModel.h @@ -45,8 +45,8 @@ class CsvParserModel : public QAbstractTableModel QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override; QVariant headerData(int section, Qt::Orientation orientation, int role) const override; -public slots: void setSkippedRows(int skipped); + int skippedRows() const; private: CsvParser* m_parser;