mirror of
https://github.com/keepassxreboot/keepassxc.git
synced 2024-10-01 01:26:01 -04:00
Add tab delimiter in CSV import. (#1842)
* Add tab delimiter in CSV import. Closes #1798 * Corrected several code style issues
This commit is contained in:
parent
d06819eb6c
commit
0142e070cc
@ -27,8 +27,8 @@
|
|||||||
#include "gui/MessageBox.h"
|
#include "gui/MessageBox.h"
|
||||||
#include "gui/MessageWidget.h"
|
#include "gui/MessageWidget.h"
|
||||||
|
|
||||||
// I wanted to make the CSV import GUI future-proof, so if one day you need entries
|
// I wanted to make the CSV import GUI future-proof, so if one day you need a new field,
|
||||||
// to have a new field, all you have to do is uncomment a row or two here, and the GUI will follow:
|
// all you have to do is uncomment a row or two here, and the GUI will follow:
|
||||||
// dynamic generation of comboBoxes, labels, placement and so on. Try it for immense fun!
|
// dynamic generation of comboBoxes, labels, placement and so on. Try it for immense fun!
|
||||||
const QStringList CsvImportWidget::m_columnHeader =
|
const QStringList CsvImportWidget::m_columnHeader =
|
||||||
QStringList() << QObject::tr("Group") << QObject::tr("Title") << QObject::tr("Username") << QObject::tr("Password")
|
QStringList() << QObject::tr("Group") << QObject::tr("Title") << QObject::tr("Username") << QObject::tr("Password")
|
||||||
@ -56,7 +56,14 @@ CsvImportWidget::CsvImportWidget(QWidget* parent)
|
|||||||
<< ";"
|
<< ";"
|
||||||
<< "-"
|
<< "-"
|
||||||
<< ":"
|
<< ":"
|
||||||
<< ".");
|
<< "."
|
||||||
|
<< "TAB (\\t)");
|
||||||
|
m_fieldSeparatorList = QStringList() << ","
|
||||||
|
<< ";"
|
||||||
|
<< "-"
|
||||||
|
<< ":"
|
||||||
|
<< "."
|
||||||
|
<< "\t";
|
||||||
m_ui->comboBoxTextQualifier->addItems(QStringList() << "\""
|
m_ui->comboBoxTextQualifier->addItems(QStringList() << "\""
|
||||||
<< "'"
|
<< "'"
|
||||||
<< ":"
|
<< ":"
|
||||||
@ -115,9 +122,10 @@ CsvImportWidget::CsvImportWidget(QWidget* parent)
|
|||||||
void CsvImportWidget::comboChanged(int comboId)
|
void CsvImportWidget::comboChanged(int comboId)
|
||||||
{
|
{
|
||||||
QComboBox* currentSender = qobject_cast<QComboBox*>(m_comboMapper->mapping(comboId));
|
QComboBox* currentSender = qobject_cast<QComboBox*>(m_comboMapper->mapping(comboId));
|
||||||
if (currentSender->currentIndex() != -1)
|
if (currentSender->currentIndex() != -1) {
|
||||||
// this line is the one that actually updates GUI table
|
// this line is the one that actually updates GUI table
|
||||||
m_parserModel->mapColumns(currentSender->currentIndex(), comboId);
|
m_parserModel->mapColumns(currentSender->currentIndex(), comboId);
|
||||||
|
}
|
||||||
updateTableview();
|
updateTableview();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -137,7 +145,7 @@ void CsvImportWidget::configParser()
|
|||||||
m_parserModel->setComment(m_ui->comboBoxComment->currentText().at(0));
|
m_parserModel->setComment(m_ui->comboBoxComment->currentText().at(0));
|
||||||
m_parserModel->setTextQualifier(m_ui->comboBoxTextQualifier->currentText().at(0));
|
m_parserModel->setTextQualifier(m_ui->comboBoxTextQualifier->currentText().at(0));
|
||||||
m_parserModel->setCodec(m_ui->comboBoxCodec->currentText());
|
m_parserModel->setCodec(m_ui->comboBoxCodec->currentText());
|
||||||
m_parserModel->setFieldSeparator(m_ui->comboBoxFieldSeparator->currentText().at(0));
|
m_parserModel->setFieldSeparator(m_fieldSeparatorList.at(m_ui->comboBoxFieldSeparator->currentIndex()).at(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
void CsvImportWidget::updateTableview()
|
void CsvImportWidget::updateTableview()
|
||||||
@ -145,16 +153,17 @@ void CsvImportWidget::updateTableview()
|
|||||||
m_ui->tableViewFields->resizeRowsToContents();
|
m_ui->tableViewFields->resizeRowsToContents();
|
||||||
m_ui->tableViewFields->resizeColumnsToContents();
|
m_ui->tableViewFields->resizeColumnsToContents();
|
||||||
|
|
||||||
for (int c = 0; c < m_ui->tableViewFields->horizontalHeader()->count(); ++c)
|
for (int c = 0; c < m_ui->tableViewFields->horizontalHeader()->count(); ++c) {
|
||||||
m_ui->tableViewFields->horizontalHeader()->setSectionResizeMode(c, QHeaderView::Stretch);
|
m_ui->tableViewFields->horizontalHeader()->setSectionResizeMode(c, QHeaderView::Stretch);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CsvImportWidget::updatePreview()
|
void CsvImportWidget::updatePreview()
|
||||||
{
|
{
|
||||||
|
|
||||||
int minSkip = 0;
|
int minSkip = 0;
|
||||||
if (m_ui->checkBoxFieldNames->isChecked())
|
if (m_ui->checkBoxFieldNames->isChecked()) {
|
||||||
minSkip = 1;
|
minSkip = 1;
|
||||||
|
}
|
||||||
m_ui->labelSizeRowsCols->setText(m_parserModel->getFileInfo());
|
m_ui->labelSizeRowsCols->setText(m_parserModel->getFileInfo());
|
||||||
m_ui->spinBoxSkip->setRange(minSkip, qMax(minSkip, m_parserModel->rowCount() - 1));
|
m_ui->spinBoxSkip->setRange(minSkip, qMax(minSkip, m_parserModel->rowCount() - 1));
|
||||||
m_ui->spinBoxSkip->setValue(minSkip);
|
m_ui->spinBoxSkip->setValue(minSkip);
|
||||||
@ -166,8 +175,9 @@ void CsvImportWidget::updatePreview()
|
|||||||
for (int i = 1; i < m_parserModel->getCsvCols(); ++i) {
|
for (int i = 1; i < m_parserModel->getCsvCols(); ++i) {
|
||||||
if (m_ui->checkBoxFieldNames->isChecked()) {
|
if (m_ui->checkBoxFieldNames->isChecked()) {
|
||||||
columnName = m_parserModel->getCsvTable().at(0).at(i);
|
columnName = m_parserModel->getCsvTable().at(0).at(i);
|
||||||
if (columnName.isEmpty())
|
if (columnName.isEmpty()) {
|
||||||
columnName = "<" + tr("Empty fieldname %1").arg(++emptyId) + ">";
|
columnName = "<" + tr("Empty fieldname %1").arg(++emptyId) + ">";
|
||||||
|
}
|
||||||
list << columnName;
|
list << columnName;
|
||||||
} else {
|
} else {
|
||||||
list << QString(tr("column %1").arg(i));
|
list << QString(tr("column %1").arg(i));
|
||||||
@ -177,10 +187,11 @@ void CsvImportWidget::updatePreview()
|
|||||||
|
|
||||||
int j = 1;
|
int j = 1;
|
||||||
for (QComboBox* b : m_combos) {
|
for (QComboBox* b : m_combos) {
|
||||||
if (j < m_parserModel->getCsvCols())
|
if (j < m_parserModel->getCsvCols()) {
|
||||||
b->setCurrentIndex(j);
|
b->setCurrentIndex(j);
|
||||||
else
|
} else {
|
||||||
b->setCurrentIndex(0);
|
b->setCurrentIndex(0);
|
||||||
|
}
|
||||||
++j;
|
++j;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -205,11 +216,12 @@ void CsvImportWidget::parse()
|
|||||||
bool good = m_parserModel->parse();
|
bool good = m_parserModel->parse();
|
||||||
updatePreview();
|
updatePreview();
|
||||||
QApplication::restoreOverrideCursor();
|
QApplication::restoreOverrideCursor();
|
||||||
if (!good)
|
if (!good) {
|
||||||
m_ui->messageWidget->showMessage(tr("Error(s) detected in CSV file!").append("\n").append(formatStatusText()),
|
m_ui->messageWidget->showMessage(tr("Error(s) detected in CSV file!").append("\n").append(formatStatusText()),
|
||||||
MessageWidget::Warning);
|
MessageWidget::Warning);
|
||||||
else
|
} else {
|
||||||
m_ui->messageWidget->setHidden(true);
|
m_ui->messageWidget->setHidden(true);
|
||||||
|
}
|
||||||
QWidget::adjustSize();
|
QWidget::adjustSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -228,12 +240,12 @@ QString CsvImportWidget::formatStatusText() const
|
|||||||
|
|
||||||
void CsvImportWidget::writeDatabase()
|
void CsvImportWidget::writeDatabase()
|
||||||
{
|
{
|
||||||
|
|
||||||
setRootGroup();
|
setRootGroup();
|
||||||
for (int r = 0; r < m_parserModel->rowCount(); ++r) {
|
for (int r = 0; r < m_parserModel->rowCount(); ++r) {
|
||||||
// use validity of second column as a GO/NOGO for all others fields
|
// use validity of second column as a GO/NOGO for all others fields
|
||||||
if (not m_parserModel->data(m_parserModel->index(r, 1)).isValid())
|
if (not m_parserModel->data(m_parserModel->index(r, 1)).isValid()) {
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
Entry* entry = new Entry();
|
Entry* entry = new Entry();
|
||||||
entry->setUuid(Uuid::random());
|
entry->setUuid(Uuid::random());
|
||||||
entry->setGroup(splitGroups(m_parserModel->data(m_parserModel->index(r, 0)).toString()));
|
entry->setGroup(splitGroups(m_parserModel->data(m_parserModel->index(r, 0)).toString()));
|
||||||
@ -264,12 +276,13 @@ void CsvImportWidget::writeDatabase()
|
|||||||
|
|
||||||
KeePass2Writer writer;
|
KeePass2Writer writer;
|
||||||
writer.writeDatabase(&buffer, m_db);
|
writer.writeDatabase(&buffer, m_db);
|
||||||
if (writer.hasError())
|
if (writer.hasError()) {
|
||||||
MessageBox::warning(this,
|
MessageBox::warning(this,
|
||||||
tr("Error"),
|
tr("Error"),
|
||||||
tr("CSV import: writer has errors:\n%1").arg(writer.errorString()),
|
tr("CSV import: writer has errors:\n%1").arg(writer.errorString()),
|
||||||
QMessageBox::Ok,
|
QMessageBox::Ok,
|
||||||
QMessageBox::Ok);
|
QMessageBox::Ok);
|
||||||
|
}
|
||||||
emit editFinished(true);
|
emit editFinished(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -310,13 +323,15 @@ Group* CsvImportWidget::splitGroups(QString label)
|
|||||||
{
|
{
|
||||||
// extract group names from nested path provided in "label"
|
// extract group names from nested path provided in "label"
|
||||||
Group* current = m_db->rootGroup();
|
Group* current = m_db->rootGroup();
|
||||||
if (label.isEmpty())
|
if (label.isEmpty()) {
|
||||||
return current;
|
return current;
|
||||||
|
}
|
||||||
|
|
||||||
QStringList groupList = label.split("/", QString::SkipEmptyParts);
|
QStringList groupList = label.split("/", QString::SkipEmptyParts);
|
||||||
// avoid the creation of a subgroup with the same name as Root
|
// avoid the creation of a subgroup with the same name as Root
|
||||||
if (m_db->rootGroup()->name() == "Root" && groupList.first() == "Root")
|
if (m_db->rootGroup()->name() == "Root" && groupList.first() == "Root") {
|
||||||
groupList.removeFirst();
|
groupList.removeFirst();
|
||||||
|
}
|
||||||
|
|
||||||
for (const QString& groupName : groupList) {
|
for (const QString& groupName : groupList) {
|
||||||
Group* children = hasChildren(current, groupName);
|
Group* children = hasChildren(current, groupName);
|
||||||
@ -338,8 +353,9 @@ Group* CsvImportWidget::hasChildren(Group* current, QString groupName)
|
|||||||
{
|
{
|
||||||
// returns the group whose name is "groupName" and is child of "current" group
|
// returns the group whose name is "groupName" and is child of "current" group
|
||||||
for (Group* group : current->children()) {
|
for (Group* group : current->children()) {
|
||||||
if (group->name() == groupName)
|
if (group->name() == groupName) {
|
||||||
return group;
|
return group;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
@ -67,6 +67,7 @@ private:
|
|||||||
Database* m_db;
|
Database* m_db;
|
||||||
|
|
||||||
static const QStringList m_columnHeader;
|
static const QStringList m_columnHeader;
|
||||||
|
QStringList m_fieldSeparatorList;
|
||||||
void configParser();
|
void configParser();
|
||||||
void updateTableview();
|
void updateTableview();
|
||||||
Group* splitGroups(QString label);
|
Group* splitGroups(QString label);
|
||||||
|
Loading…
Reference in New Issue
Block a user