From 9b670b4b9420bc3116477cab098905de2750abc5 Mon Sep 17 00:00:00 2001 From: mgrojo Date: Mon, 6 Jan 2020 00:50:33 +0100 Subject: [PATCH] Support for control characters as quote and separator in CSV import New options and spin boxes are added for entering any non-printable character in the Import CSV dialog. This adds support for Concordance DAT files and similar cases. See issue #2012 --- src/FileDialog.h | 1 + src/ImportCsvDialog.cpp | 42 ++++++++++++++++++++++------- src/ImportCsvDialog.h | 5 ++++ src/ImportCsvDialog.ui | 60 +++++++++++++++++++++++++++++++++++++++-- src/MainWindow.cpp | 1 + 5 files changed, 98 insertions(+), 11 deletions(-) diff --git a/src/FileDialog.h b/src/FileDialog.h index 885f9580..6b4999fd 100644 --- a/src/FileDialog.h +++ b/src/FileDialog.h @@ -32,6 +32,7 @@ static const QString FILE_FILTER_CSV(QObject::tr("Comma-Separated Values Files ( static const QString FILE_EXT_CSV_DEFAULT(".csv"); static const QString FILE_FILTER_TSV(QObject::tr("Tab-Separated Values Files (*.tsv)")); static const QString FILE_FILTER_DSV(QObject::tr("Delimiter-Separated Values Files (*.dsv)")); +static const QString FILE_FILTER_DAT(QObject::tr("Concordance DAT files (*.dat)")); // JSON File Extensions Filter static const QString FILE_FILTER_JSON(QObject::tr("JSON Files (*.json *.js)")); diff --git a/src/ImportCsvDialog.cpp b/src/ImportCsvDialog.cpp index 8e173def..eb508384 100644 --- a/src/ImportCsvDialog.cpp +++ b/src/ImportCsvDialog.cpp @@ -217,8 +217,11 @@ void ImportCsvDialog::accept() void ImportCsvDialog::updatePreview() { // Show/hide custom quote/separator input fields - ui->editCustomQuote->setVisible(ui->comboQuote->currentIndex() == ui->comboQuote->count()-1); - ui->editCustomSeparator->setVisible(ui->comboSeparator->currentIndex() == ui->comboSeparator->count()-1); + ui->editCustomQuote->setVisible(ui->comboQuote->currentIndex() == ui->comboQuote->count() - OtherPrintable); + ui->editCustomSeparator->setVisible(ui->comboSeparator->currentIndex() == ui->comboSeparator->count() - OtherPrintable); + ui->spinBoxQuote->setVisible(ui->comboQuote->currentIndex() == ui->comboQuote->count() - OtherCode); + ui->spinBoxSeparator->setVisible(ui->comboSeparator->currentIndex() == ui->comboSeparator->count() - OtherCode); + ui->editCustomEncoding->setVisible(ui->comboEncoding->currentIndex() == ui->comboEncoding->count()-1); // Reset preview widget @@ -702,10 +705,18 @@ void ImportCsvDialog::setQuoteChar(QChar c) { QComboBox* combo = ui->comboQuote; int index = combo->findText(QString(c)); + ui->spinBoxQuote->setValue(c.unicode()); if(index == -1) { - combo->setCurrentIndex(combo->count() - 1); - ui->editCustomQuote->setText(QString(c)); + if(c.isPrint()) + { + combo->setCurrentIndex(combo->count() - OtherPrintable); + ui->editCustomQuote->setText(QString(c)); + } + else + { + combo->setCurrentIndex(combo->count() - OtherCode); + } } else { @@ -718,8 +729,10 @@ QChar ImportCsvDialog::currentQuoteChar() const QString value; // The last item in the combobox is the 'Other' item; if it is selected return the text of the line edit field instead - if(ui->comboQuote->currentIndex() == ui->comboQuote->count()-1) + if(ui->comboQuote->currentIndex() == ui->comboQuote->count() - OtherPrintable) value = ui->editCustomQuote->text().length() ? ui->editCustomQuote->text() : ""; + else if(ui->comboQuote->currentIndex() == ui->comboQuote->count() - OtherCode) + value = QString(QChar(ui->spinBoxQuote->value())); else if(ui->comboQuote->currentText().length()) value = ui->comboQuote->currentText(); @@ -731,10 +744,18 @@ void ImportCsvDialog::setSeparatorChar(QChar c) QComboBox* combo = ui->comboSeparator; QString sText = c == '\t' ? QString("Tab") : QString(c); int index = combo->findText(sText); + ui->spinBoxSeparator->setValue(c.unicode()); if(index == -1) { - combo->setCurrentIndex(combo->count() - 1); - ui->editCustomSeparator->setText(QString(c)); + if(c.isPrint()) + { + combo->setCurrentIndex(combo->count() - OtherPrintable); + ui->editCustomSeparator->setText(QString(c)); + } + else + { + combo->setCurrentIndex(combo->count() - OtherCode); + } } else { @@ -746,9 +767,12 @@ QChar ImportCsvDialog::currentSeparatorChar() const { QString value; - // The last item in the combobox is the 'Other' item; if it is selected return the text of the line edit field instead - if(ui->comboSeparator->currentIndex() == ui->comboSeparator->count()-1 || ui->comboSeparator->currentText().isEmpty()) + // The last options in the combobox are the 'Other (*)' items; + // if one of them is selected return the text or code of the corresponding field instead + if(ui->comboSeparator->currentIndex() == ui->comboSeparator->count() - OtherPrintable) value = ui->editCustomSeparator->text().length() ? ui->editCustomSeparator->text() : ""; + else if(ui->comboSeparator->currentIndex() == ui->comboSeparator->count() - OtherCode) + value = QString(QChar(ui->spinBoxSeparator->value())); else value = ui->comboSeparator->currentText() == tr("Tab") ? "\t" : ui->comboSeparator->currentText(); diff --git a/src/ImportCsvDialog.h b/src/ImportCsvDialog.h index c5891c02..6e7f92ee 100644 --- a/src/ImportCsvDialog.h +++ b/src/ImportCsvDialog.h @@ -33,6 +33,11 @@ private slots: void toggleAdvancedSection(bool show); private: + + // Positions for combos starting at the bottom + enum {OtherCode = 1, + OtherPrintable = 2}; + Ui::ImportCsvDialog* ui; std::vector csvFilenames; QString selectedFile; diff --git a/src/ImportCsvDialog.ui b/src/ImportCsvDialog.ui index 9947d3bb..c470c8db 100644 --- a/src/ImportCsvDialog.ui +++ b/src/ImportCsvDialog.ui @@ -85,7 +85,12 @@ - Other + Other (printable) + + + + + Other (code) @@ -97,6 +102,13 @@ + + + + 1114112 + + + @@ -143,7 +155,12 @@ - Other + Other (printable) + + + + + Other (code) @@ -155,6 +172,13 @@ + + + + 1114112 + + + @@ -719,6 +743,38 @@ + + spinBoxQuote + valueChanged(int) + ImportCsvDialog + updatePreview() + + + 529 + 111 + + + 393 + 358 + + + + + spinBoxSeparator + valueChanged(int) + ImportCsvDialog + updatePreview() + + + 529 + 77 + + + 393 + 358 + + + updatePreview() diff --git a/src/MainWindow.cpp b/src/MainWindow.cpp index 83228a98..8db2ddd9 100644 --- a/src/MainWindow.cpp +++ b/src/MainWindow.cpp @@ -1241,6 +1241,7 @@ void MainWindow::importTableFromCSV() << FILE_FILTER_TSV << FILE_FILTER_DSV << FILE_FILTER_TXT + << FILE_FILTER_DAT << FILE_FILTER_ALL; QStringList wFiles = FileDialog::getOpenFileNames(