diff src/converter.cpp @ 76:1e6e7699f0b8

Add replacements.ini to configure text replacements
author Andre Heinecke <andre.heinecke@intevation.de>
date Wed, 05 Oct 2016 14:23:23 +0200
parents 92139cc60121
children f230ed9022e0
line wrap: on
line diff
--- a/src/converter.cpp	Tue Oct 04 17:12:28 2016 +0200
+++ b/src/converter.cpp	Wed Oct 05 14:23:23 2016 +0200
@@ -14,6 +14,10 @@
 #include <QPrinter>
 #include <QImage>
 #include <QPainter>
+#include <QMessageBox>
+#include <QDir>
+#include <QCoreApplication>
+#include <QSettings>
 
 #include "xlsxdocument.h"
 #include "xlsxconditionalformatting.h"
@@ -135,22 +139,80 @@
     return;
 }
 
-static void unescapeRegex(QString &str, const QRegularExpression &exp)
+static const QMap<QRegularExpression*, QString> loadExpressionsFromFile(const QString &path, QStringList &errors)
 {
-    QRegularExpressionMatch match = exp.match(str);
-    while (match.hasMatch()) {
-        str.replace(match.capturedStart(), match.capturedLength(), match.captured(1));
-        match = exp.match(str);
+    QFile file(path);
+    QMap<QRegularExpression*, QString> ret;
+
+    if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
+        errors << QObject::tr("Failed to open replacement file:") + "\n\"" + path + "\"";
+        return ret;
     }
+
+    while (!file.atEnd()) {
+        const auto line = file.readLine();
+        auto strline = QString::fromUtf8(line).trimmed();
+        if (strline.startsWith(QStringLiteral(";")) || strline.isEmpty()) {
+            continue;
+        }
+
+        auto split = strline.split("=");
+        if (split.count() != 2) {
+            errors << QObject::tr("Invalid replacement line:") + "\n\"" + strline + "\"";
+            continue;
+        }
+
+        auto exp = new QRegularExpression (split[0], QRegularExpression::MultilineOption);
+        if (!exp->isValid()) {
+            errors << QObject::tr("Invalid regular expression:") + "\n\"" + split[0] + "\"" +
+                                 "\n" + QObject::tr("Error: ") + exp->errorString();
+            continue;
+        }
+        const auto rep = split[1].replace("\"", "");
+        ret.insert(exp, rep);
+        qDebug() << "Loaded replacement: " << *exp << " replacement:" << rep << "";
+    }
+    /* Special one that does not fit into the ini format well. */
+    ret.insert(new QRegularExpression("^="), " =");
+    return ret;
 }
 
-static void unescapeString(QString &str)
+static const QMap<QRegularExpression*, QString> loadExpressions(QStringList &errors)
 {
-    static const QRegularExpression imgEx(IMAGE_PATTERN);
-    static const QRegularExpression texEx(LATEX_PATTERN);
+    QMap<QRegularExpression*, QString> regexs;
+    /* Look for file next to our place */
+    auto ourDir = QDir(QCoreApplication::applicationDirPath());
+    const auto filename = QStringLiteral(CONFIG_FILE_NAME);
+    if (ourDir.exists(filename)) {
+        regexs = loadExpressionsFromFile(ourDir.filePath(filename), errors);
+        return regexs;
+    }
 
-    unescapeRegex(str, imgEx);
-    unescapeRegex(str, texEx);
+    /* Look in ../share/apps/PROJECT_NAME */
+    ourDir.cd(QStringLiteral("../share/apps/" APPNAME).toLower());
+    if (ourDir.exists(filename)) {
+        regexs = loadExpressionsFromFile(ourDir.filePath(filename), errors);
+    } else {
+        qDebug() << "Failed to find regular expressions.";
+    }
+    return regexs;
+}
+
+static const QStringList sanitizeInput(QString &str)
+{
+    QStringList errors;
+    str.replace("\r\n", "\n");
+    str.replace("\n\r", "\n");
+    const auto expressions = loadExpressions(errors);
+    for (const auto regex: expressions.keys()) {
+        str.replace(*regex, expressions.value(regex));
+        delete regex;
+    }
+    return errors;
+}
+
+static void xlsEscape(QString &str)
+{
     if (str.startsWith("=")) {
         str = " " + str;
     }
@@ -203,9 +265,7 @@
     QRegularExpression freetxtEx(FREETXT_PATTERN);
     QRegularExpression firstQuestionEx(FIRST_QUESTION_PATTERN);
 
-    input.replace("\r\n", "\n");
-    input.replace("\n\r", "\n");
-    input.replace("#NAME?\n", "");
+    mErrors += sanitizeInput(input);
 
     QRegularExpressionMatch match = firstQuestionEx.match(input);
     bool foundSomething = false;
@@ -229,6 +289,7 @@
         const QString answerLine = match.captured(2).trimmed();
         xlsx.write(row, 2, QString(" "), mQuestionFmt);
         xlsx.write(row, 3, QString(" "), mQuestionFmt);
+        xlsEscape(question);
         xlsx.write(row++, 1, question, mQuestionFmt);
         html << mQuestionStyle.arg(question.toHtmlEscaped());
 
@@ -248,10 +309,7 @@
 
                 /* Write the values */
                 QString choiceName = choiceMatch.captured(1).trimmed();
-                if (choiceName.startsWith("=")) {
-                    choiceName = " " + choiceName;
-                }
-                unescapeString(choiceName);
+                xlsEscape(choiceName);
                 xlsx.write(row, 1, choiceName, mChoiceTextFmt);
                 html << mChoiceTextStyle.arg(choiceName.toHtmlEscaped());
                 qDebug() << "Captured for choice: " << choiceMatch.captured(0);
@@ -292,10 +350,10 @@
                 QString choice = choiceMatch.captured(1);
                 cursor = choiceMatch.capturedEnd();
                 /* Alternative answer that is just a list of strings */
-                unescapeString(choice);
                 qDebug() << "Captured unfilled choice: " << choice;
                 html << mChoiceTextStyle.arg(choice.toHtmlEscaped());
                 makeBar(html, 0, doc);
+                xlsEscape(choice);
                 xlsx.write(row, 1, choice);
                 xlsx.write(row, 2, QVariant());
                 const QString numVotesString = QStringLiteral("Keine eingegangenen Antworten");
@@ -345,14 +403,15 @@
                     const QString unquoted = input.mid(cursor, unquotedLen);
                     qDebug() << "Found inner quoted string: " << unquoted;
                     /* Now combine */
-                    const QString combined = QString("%1\"%2\"%3").arg(lastRow).
-                                                                   arg(unquoted).
-                                                                   arg(textMatch.captured(1).trimmed());
+                    QString combined = QString("%1\"%2\"%3").arg(lastRow).
+                                                                 arg(unquoted).
+                                                                 arg(textMatch.captured(1).trimmed());
                     qDebug() << "Last row: " << lastRow;
                     qDebug() << "Next Question is at: " << nextQuestion.capturedStart();
                     qDebug() << "Text match is: " << textMatch.captured(1).trimmed();
                     qDebug() << "cursor is at: " << cursor;
                     qDebug() << "text match starts at: " << textMatch.capturedStart();
+                    xlsEscape(combined);
                     xlsx.write(row - 1, 26, combined, mFreeTextFmt);
                     xlsx.write(row - 1, 1, combined, mFreeTextFmt);
                     cursor = textMatch.capturedEnd();
@@ -374,6 +433,7 @@
                    http://excel.tips.net/T003207_Automatic_Row_Height_For_Merged_Cells_with_Text_Wrap.html
                 */
                 /* Write the values */
+                xlsEscape(text);
                 xlsx.write(QString("Z%1").arg(row), text, mFreeTextFmt);
                 xlsx.write(row, 1, text, mFreeTextFmt);
                 row++;
This site is hosted by Intevation GmbH (Datenschutzerklärung und Impressum | Privacy Policy and Imprint)