Add ability to parse tags from CSV files

* Closes #7956
This commit is contained in:
Jonathan White 2025-02-23 22:33:48 -05:00
parent 1b1643b5d1
commit 33a3796074
3 changed files with 268 additions and 229 deletions

View File

@ -1445,6 +1445,10 @@ Do you want to overwrite the passkey in %1 - %2?</source>
Are you sure you want to import?</source> Are you sure you want to import?</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<source>Tags</source>
<translation type="unfinished"></translation>
</message>
</context> </context>
<context> <context>
<name>CsvParserModel</name> <name>CsvParserModel</name>
@ -9232,6 +9236,10 @@ This option is deprecated, use --set-key-file instead.</source>
<source>%1, row: %2, column: %3</source> <source>%1, row: %2, column: %3</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<source>Tags</source>
<translation type="unfinished"></translation>
</message>
</context> </context>
<context> <context>
<name>QtIOCompressor</name> <name>QtIOCompressor</name>

View File

@ -75,13 +75,14 @@ CsvImportWidget::CsvImportWidget(QWidget* parent)
m_ui->tableViewFields->setFocusPolicy(Qt::NoFocus); m_ui->tableViewFields->setFocusPolicy(Qt::NoFocus);
m_columnHeader << QObject::tr("Group") << QObject::tr("Title") << QObject::tr("Username") << QObject::tr("Password") m_columnHeader << QObject::tr("Group") << QObject::tr("Title") << QObject::tr("Username") << QObject::tr("Password")
<< QObject::tr("URL") << QObject::tr("Notes") << QObject::tr("TOTP") << QObject::tr("Icon") << QObject::tr("URL") << QObject::tr("Tags") << QObject::tr("Notes") << QObject::tr("TOTP")
<< QObject::tr("Last Modified") << QObject::tr("Created"); << QObject::tr("Icon") << QObject::tr("Last Modified") << QObject::tr("Created");
m_fieldSeparatorList << "," << ";" << "-" << ":" << "." << "\t"; m_fieldSeparatorList << "," << ";" << "-" << ":" << "." << "\t";
m_combos << m_ui->groupCombo << m_ui->titleCombo << m_ui->usernameCombo << m_ui->passwordCombo << m_ui->urlCombo m_combos << m_ui->groupCombo << m_ui->titleCombo << m_ui->usernameCombo << m_ui->passwordCombo << m_ui->urlCombo
<< m_ui->notesCombo << m_ui->totpCombo << m_ui->iconCombo << m_ui->lastModifiedCombo << m_ui->createdCombo; << m_ui->tagsCombo << m_ui->notesCombo << m_ui->totpCombo << m_ui->iconCombo << m_ui->lastModifiedCombo
<< m_ui->createdCombo;
for (auto combo : m_combos) { for (auto combo : m_combos) {
combo->setModel(m_comboModel); combo->setModel(m_comboModel);
@ -254,10 +255,11 @@ QSharedPointer<Database> CsvImportWidget::buildDatabase()
entry->setUsername(m_parserModel->data(m_parserModel->index(r, 2)).toString()); entry->setUsername(m_parserModel->data(m_parserModel->index(r, 2)).toString());
entry->setPassword(m_parserModel->data(m_parserModel->index(r, 3)).toString()); entry->setPassword(m_parserModel->data(m_parserModel->index(r, 3)).toString());
entry->setUrl(m_parserModel->data(m_parserModel->index(r, 4)).toString()); entry->setUrl(m_parserModel->data(m_parserModel->index(r, 4)).toString());
entry->setNotes(m_parserModel->data(m_parserModel->index(r, 5)).toString()); entry->setTags(m_parserModel->data(m_parserModel->index(r, 5)).toString());
entry->setNotes(m_parserModel->data(m_parserModel->index(r, 6)).toString());
// TOTP // TOTP
auto otpString = m_parserModel->data(m_parserModel->index(r, 6)); auto otpString = m_parserModel->data(m_parserModel->index(r, 7));
if (otpString.isValid() && !otpString.toString().isEmpty()) { if (otpString.isValid() && !otpString.toString().isEmpty()) {
auto totp = Totp::parseSettings(otpString.toString()); auto totp = Totp::parseSettings(otpString.toString());
if (!totp || totp->key.isEmpty()) { if (!totp || totp->key.isEmpty()) {
@ -269,14 +271,14 @@ QSharedPointer<Database> CsvImportWidget::buildDatabase()
// Icon // Icon
bool ok; bool ok;
int icon = m_parserModel->data(m_parserModel->index(r, 7)).toInt(&ok); int icon = m_parserModel->data(m_parserModel->index(r, 8)).toInt(&ok);
if (ok) { if (ok) {
entry->setIcon(icon); entry->setIcon(icon);
} }
// Modified Time // Modified Time
TimeInfo timeInfo; TimeInfo timeInfo;
if (m_parserModel->data(m_parserModel->index(r, 8)).isValid()) { if (m_parserModel->data(m_parserModel->index(r, 9)).isValid()) {
auto datetime = m_parserModel->data(m_parserModel->index(r, 8)).toString(); auto datetime = m_parserModel->data(m_parserModel->index(r, 8)).toString();
if (datetime.contains(QRegularExpression("^\\d+$"))) { if (datetime.contains(QRegularExpression("^\\d+$"))) {
auto t = datetime.toLongLong(); auto t = datetime.toLongLong();
@ -295,7 +297,7 @@ QSharedPointer<Database> CsvImportWidget::buildDatabase()
} }
} }
// Creation Time // Creation Time
if (m_parserModel->data(m_parserModel->index(r, 9)).isValid()) { if (m_parserModel->data(m_parserModel->index(r, 10)).isValid()) {
auto datetime = m_parserModel->data(m_parserModel->index(r, 9)).toString(); auto datetime = m_parserModel->data(m_parserModel->index(r, 9)).toString();
if (datetime.contains(QRegularExpression("^\\d+$"))) { if (datetime.contains(QRegularExpression("^\\d+$"))) {
auto t = datetime.toLongLong(); auto t = datetime.toLongLong();

View File

@ -40,95 +40,6 @@
<string>Column Association</string> <string>Column Association</string>
</property> </property>
<layout class="QGridLayout" name="gridLayout"> <layout class="QGridLayout" name="gridLayout">
<item row="2" column="3">
<widget class="QLabel" name="iconLabel">
<property name="font">
<font>
<weight>50</weight>
<bold>false</bold>
</font>
</property>
<property name="text">
<string>Icon</string>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
</property>
<property name="indent">
<number>2</number>
</property>
</widget>
</item>
<item row="1" column="3">
<widget class="QLabel" name="totpLabel">
<property name="font">
<font>
<weight>50</weight>
<bold>false</bold>
</font>
</property>
<property name="text">
<string>TOTP</string>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
</property>
<property name="indent">
<number>2</number>
</property>
</widget>
</item>
<item row="0" column="4">
<widget class="QComboBox" name="notesCombo">
<property name="maximumSize">
<size>
<width>200</width>
<height>16777215</height>
</size>
</property>
<property name="sizeAdjustPolicy">
<enum>QComboBox::AdjustToContents</enum>
</property>
</widget>
</item>
<item row="0" column="3">
<widget class="QLabel" name="notesLabel">
<property name="font">
<font>
<weight>50</weight>
<bold>false</bold>
</font>
</property>
<property name="text">
<string>Notes</string>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
</property>
<property name="indent">
<number>2</number>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="titleLabel">
<property name="font">
<font>
<weight>50</weight>
<bold>false</bold>
</font>
</property>
<property name="text">
<string>Title</string>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
</property>
<property name="indent">
<number>2</number>
</property>
</widget>
</item>
<item row="4" column="1"> <item row="4" column="1">
<widget class="QComboBox" name="urlCombo"> <widget class="QComboBox" name="urlCombo">
<property name="maximumSize"> <property name="maximumSize">
@ -142,74 +53,6 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="1" column="4">
<widget class="QComboBox" name="totpCombo">
<property name="maximumSize">
<size>
<width>200</width>
<height>16777215</height>
</size>
</property>
<property name="sizeAdjustPolicy">
<enum>QComboBox::AdjustToContents</enum>
</property>
</widget>
</item>
<item row="4" column="4">
<widget class="QComboBox" name="createdCombo">
<property name="maximumSize">
<size>
<width>200</width>
<height>16777215</height>
</size>
</property>
<property name="sizeAdjustPolicy">
<enum>QComboBox::AdjustToContents</enum>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QComboBox" name="titleCombo">
<property name="maximumSize">
<size>
<width>200</width>
<height>16777215</height>
</size>
</property>
<property name="sizeAdjustPolicy">
<enum>QComboBox::AdjustToContents</enum>
</property>
</widget>
</item>
<item row="5" column="0" colspan="5">
<widget class="QCheckBox" name="checkBoxFieldNames">
<property name="font">
<font>
<weight>50</weight>
<bold>false</bold>
</font>
</property>
<property name="text">
<string>First line has field names</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item row="2" column="4">
<widget class="QComboBox" name="iconCombo">
<property name="maximumSize">
<size>
<width>200</width>
<height>16777215</height>
</size>
</property>
<property name="sizeAdjustPolicy">
<enum>QComboBox::AdjustToContents</enum>
</property>
</widget>
</item>
<item row="2" column="1"> <item row="2" column="1">
<widget class="QComboBox" name="usernameCombo"> <widget class="QComboBox" name="usernameCombo">
<property name="maximumSize"> <property name="maximumSize">
@ -223,25 +66,6 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="3" column="0">
<widget class="QLabel" name="passwordLabel">
<property name="font">
<font>
<weight>50</weight>
<bold>false</bold>
</font>
</property>
<property name="text">
<string>Password</string>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
</property>
<property name="indent">
<number>2</number>
</property>
</widget>
</item>
<item row="0" column="0"> <item row="0" column="0">
<widget class="QLabel" name="groupLabel"> <widget class="QLabel" name="groupLabel">
<property name="font"> <property name="font">
@ -261,16 +85,22 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="3" column="1"> <item row="0" column="3">
<widget class="QComboBox" name="passwordCombo"> <widget class="QLabel" name="notesLabel">
<property name="maximumSize"> <property name="font">
<size> <font>
<width>200</width> <weight>50</weight>
<height>16777215</height> <bold>false</bold>
</size> </font>
</property> </property>
<property name="sizeAdjustPolicy"> <property name="text">
<enum>QComboBox::AdjustToContents</enum> <string>Notes</string>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
</property>
<property name="indent">
<number>2</number>
</property> </property>
</widget> </widget>
</item> </item>
@ -293,25 +123,6 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="4" column="0">
<widget class="QLabel" name="urlLabel">
<property name="font">
<font>
<weight>50</weight>
<bold>false</bold>
</font>
</property>
<property name="text">
<string>URL</string>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
</property>
<property name="indent">
<number>2</number>
</property>
</widget>
</item>
<item row="3" column="4"> <item row="3" column="4">
<widget class="QComboBox" name="lastModifiedCombo"> <widget class="QComboBox" name="lastModifiedCombo">
<property name="maximumSize"> <property name="maximumSize">
@ -325,27 +136,21 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="4" column="3"> <item row="2" column="4">
<widget class="QLabel" name="createdLabel"> <widget class="QComboBox" name="iconCombo">
<property name="font"> <property name="maximumSize">
<font> <size>
<weight>50</weight> <width>200</width>
<bold>false</bold> <height>16777215</height>
</font> </size>
</property> </property>
<property name="text"> <property name="sizeAdjustPolicy">
<string>Created</string> <enum>QComboBox::AdjustToContents</enum>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
</property>
<property name="indent">
<number>2</number>
</property> </property>
</widget> </widget>
</item> </item>
<item row="0" column="1"> <item row="1" column="4">
<widget class="QComboBox" name="groupCombo"> <widget class="QComboBox" name="totpCombo">
<property name="maximumSize"> <property name="maximumSize">
<size> <size>
<width>200</width> <width>200</width>
@ -376,6 +181,51 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="1" column="1">
<widget class="QComboBox" name="titleCombo">
<property name="maximumSize">
<size>
<width>200</width>
<height>16777215</height>
</size>
</property>
<property name="sizeAdjustPolicy">
<enum>QComboBox::AdjustToContents</enum>
</property>
</widget>
</item>
<item row="0" column="4">
<widget class="QComboBox" name="notesCombo">
<property name="maximumSize">
<size>
<width>200</width>
<height>16777215</height>
</size>
</property>
<property name="sizeAdjustPolicy">
<enum>QComboBox::AdjustToContents</enum>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="passwordLabel">
<property name="font">
<font>
<weight>50</weight>
<bold>false</bold>
</font>
</property>
<property name="text">
<string>Password</string>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
</property>
<property name="indent">
<number>2</number>
</property>
</widget>
</item>
<item row="0" column="2"> <item row="0" column="2">
<spacer name="horizontalSpacer_2"> <spacer name="horizontalSpacer_2">
<property name="orientation"> <property name="orientation">
@ -392,6 +242,169 @@
</property> </property>
</spacer> </spacer>
</item> </item>
<item row="4" column="3">
<widget class="QLabel" name="createdLabel">
<property name="font">
<font>
<weight>50</weight>
<bold>false</bold>
</font>
</property>
<property name="text">
<string>Created</string>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
</property>
<property name="indent">
<number>2</number>
</property>
</widget>
</item>
<item row="4" column="4">
<widget class="QComboBox" name="createdCombo">
<property name="maximumSize">
<size>
<width>200</width>
<height>16777215</height>
</size>
</property>
<property name="sizeAdjustPolicy">
<enum>QComboBox::AdjustToContents</enum>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QLabel" name="urlLabel">
<property name="font">
<font>
<weight>50</weight>
<bold>false</bold>
</font>
</property>
<property name="text">
<string>URL</string>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
</property>
<property name="indent">
<number>2</number>
</property>
</widget>
</item>
<item row="1" column="3">
<widget class="QLabel" name="totpLabel">
<property name="font">
<font>
<weight>50</weight>
<bold>false</bold>
</font>
</property>
<property name="text">
<string>TOTP</string>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
</property>
<property name="indent">
<number>2</number>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QComboBox" name="passwordCombo">
<property name="maximumSize">
<size>
<width>200</width>
<height>16777215</height>
</size>
</property>
<property name="sizeAdjustPolicy">
<enum>QComboBox::AdjustToContents</enum>
</property>
</widget>
</item>
<item row="2" column="3">
<widget class="QLabel" name="iconLabel">
<property name="font">
<font>
<weight>50</weight>
<bold>false</bold>
</font>
</property>
<property name="text">
<string>Icon</string>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
</property>
<property name="indent">
<number>2</number>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="titleLabel">
<property name="font">
<font>
<weight>50</weight>
<bold>false</bold>
</font>
</property>
<property name="text">
<string>Title</string>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
</property>
<property name="indent">
<number>2</number>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QComboBox" name="groupCombo">
<property name="maximumSize">
<size>
<width>200</width>
<height>16777215</height>
</size>
</property>
<property name="sizeAdjustPolicy">
<enum>QComboBox::AdjustToContents</enum>
</property>
</widget>
</item>
<item row="5" column="0">
<widget class="QLabel" name="tagsLabel">
<property name="font">
<font>
<weight>50</weight>
<bold>false</bold>
</font>
</property>
<property name="text">
<string>Tags</string>
</property>
<property name="indent">
<number>2</number>
</property>
</widget>
</item>
<item row="5" column="1">
<widget class="QComboBox" name="tagsCombo">
<property name="maximumSize">
<size>
<width>200</width>
<height>16777215</height>
</size>
</property>
<property name="sizeAdjustPolicy">
<enum>QComboBox::AdjustToContents</enum>
</property>
</widget>
</item>
</layout> </layout>
</widget> </widget>
</item> </item>
@ -684,6 +697,22 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="6" column="0" colspan="2">
<widget class="QCheckBox" name="checkBoxFieldNames">
<property name="font">
<font>
<weight>50</weight>
<bold>false</bold>
</font>
</property>
<property name="text">
<string>First line has field names</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
</layout> </layout>
</widget> </widget>
</item> </item>