annotate src/converter.cpp @ 82:9e3c05a03a6f

Check for double newline in unquoted strings
author Andre Heinecke <andre.heinecke@intevation.de>
date Wed, 05 Oct 2016 14:43:06 +0200
parents f3481e9e44b2
children f505df84380d
rev   line source
3
8b4c49c92451 Add initial implementation that handles choices
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
1 /* Copyright (C) 2016 by ETH Zürich
8b4c49c92451 Add initial implementation that handles choices
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
2 * Software engineering by Intevation GmbH
8b4c49c92451 Add initial implementation that handles choices
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
3 *
8b4c49c92451 Add initial implementation that handles choices
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
4 * This file is Free Software under the GNU GPL (v>=2)
8b4c49c92451 Add initial implementation that handles choices
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
5 * and comes with ABSOLUTELY NO WARRANTY!
8b4c49c92451 Add initial implementation that handles choices
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
6 * See LICENSE.txt for details.
8b4c49c92451 Add initial implementation that handles choices
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
7 */
8b4c49c92451 Add initial implementation that handles choices
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
8
8b4c49c92451 Add initial implementation that handles choices
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
9 #include "converter.h"
8b4c49c92451 Add initial implementation that handles choices
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
10 #include <QDebug>
8b4c49c92451 Add initial implementation that handles choices
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
11 #include <QRegularExpression>
8b4c49c92451 Add initial implementation that handles choices
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
12 #include <QRegularExpressionMatch>
23
927794e3cc52 Add HTML output and some pdf support
Andre Heinecke <andre.heinecke@intevation.de>
parents: 21
diff changeset
13 #include <QTextDocument>
927794e3cc52 Add HTML output and some pdf support
Andre Heinecke <andre.heinecke@intevation.de>
parents: 21
diff changeset
14 #include <QPrinter>
26
5acd601356ba Make HTML work for QTextDocument
Andre Heinecke <andre.heinecke@intevation.de>
parents: 25
diff changeset
15 #include <QImage>
5acd601356ba Make HTML work for QTextDocument
Andre Heinecke <andre.heinecke@intevation.de>
parents: 25
diff changeset
16 #include <QPainter>
76
1e6e7699f0b8 Add replacements.ini to configure text replacements
Andre Heinecke <andre.heinecke@intevation.de>
parents: 75
diff changeset
17 #include <QMessageBox>
1e6e7699f0b8 Add replacements.ini to configure text replacements
Andre Heinecke <andre.heinecke@intevation.de>
parents: 75
diff changeset
18 #include <QDir>
1e6e7699f0b8 Add replacements.ini to configure text replacements
Andre Heinecke <andre.heinecke@intevation.de>
parents: 75
diff changeset
19 #include <QCoreApplication>
1e6e7699f0b8 Add replacements.ini to configure text replacements
Andre Heinecke <andre.heinecke@intevation.de>
parents: 75
diff changeset
20 #include <QSettings>
3
8b4c49c92451 Add initial implementation that handles choices
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
21
8b4c49c92451 Add initial implementation that handles choices
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
22 #include "xlsxdocument.h"
8b4c49c92451 Add initial implementation that handles choices
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
23 #include "xlsxconditionalformatting.h"
8b4c49c92451 Add initial implementation that handles choices
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
24
8b4c49c92451 Add initial implementation that handles choices
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
25 #include "constants.h"
8b4c49c92451 Add initial implementation that handles choices
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
26
8b4c49c92451 Add initial implementation that handles choices
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
27 QTXLSX_USE_NAMESPACE
8b4c49c92451 Add initial implementation that handles choices
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
28
38
5354cbda7188 Fix HTML Layout. Support multiple formats at once. More handling.
Andre Heinecke <andre.heinecke@intevation.de>
parents: 35
diff changeset
29 Converter::Converter(const QString &input, const QStringList &outputs,
5354cbda7188 Fix HTML Layout. Support multiple formats at once. More handling.
Andre Heinecke <andre.heinecke@intevation.de>
parents: 35
diff changeset
30 const QString &title):
3
8b4c49c92451 Add initial implementation that handles choices
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
31 QThread(Q_NULLPTR),
8b4c49c92451 Add initial implementation that handles choices
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
32 mInput(input),
38
5354cbda7188 Fix HTML Layout. Support multiple formats at once. More handling.
Andre Heinecke <andre.heinecke@intevation.de>
parents: 35
diff changeset
33 mOutputs(outputs),
3
8b4c49c92451 Add initial implementation that handles choices
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
34 mTitle(title)
8b4c49c92451 Add initial implementation that handles choices
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
35 {
8b4c49c92451 Add initial implementation that handles choices
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
36 mTitleFmt.setFontUnderline(Format::FontUnderlineSingle);
8b4c49c92451 Add initial implementation that handles choices
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
37 mTitleFmt.setFontSize(18);
8b4c49c92451 Add initial implementation that handles choices
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
38 mTitleFmt.setFontName("Calibri");
8b4c49c92451 Add initial implementation that handles choices
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
39 mTitleFmt.setFontBold(true);
8b4c49c92451 Add initial implementation that handles choices
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
40 mTitleFmt.setVerticalAlignment(Format::AlignTop);
8b4c49c92451 Add initial implementation that handles choices
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
41
23
927794e3cc52 Add HTML output and some pdf support
Andre Heinecke <andre.heinecke@intevation.de>
parents: 21
diff changeset
42
3
8b4c49c92451 Add initial implementation that handles choices
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
43 mQuestionFmt.setFontSize(11);
8b4c49c92451 Add initial implementation that handles choices
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
44 mQuestionFmt.setFontName("Calibri");
8b4c49c92451 Add initial implementation that handles choices
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
45 mQuestionFmt.setFontBold(true);
8b4c49c92451 Add initial implementation that handles choices
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
46 mQuestionFmt.setTopBorderStyle(Format::BorderThin);
6
a10425e7ef98 Add free text handling
Andre Heinecke <andre.heinecke@intevation.de>
parents: 3
diff changeset
47 mQuestionFmt.setBottomBorderStyle(Format::BorderThin);
3
8b4c49c92451 Add initial implementation that handles choices
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
48 mQuestionFmt.setTextWarp(true);
8b4c49c92451 Add initial implementation that handles choices
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
49
8b4c49c92451 Add initial implementation that handles choices
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
50 mAnswerChoiceFmt.setFontSize(11);
8b4c49c92451 Add initial implementation that handles choices
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
51 mAnswerChoiceFmt.setFontName("Calibri");
23
927794e3cc52 Add HTML output and some pdf support
Andre Heinecke <andre.heinecke@intevation.de>
parents: 21
diff changeset
52 mAnswerChoiceFmt.setHorizontalAlignment(Format::AlignLeft);
6
a10425e7ef98 Add free text handling
Andre Heinecke <andre.heinecke@intevation.de>
parents: 3
diff changeset
53 mAnswerChoiceFmt.setTextWarp(true);
3
8b4c49c92451 Add initial implementation that handles choices
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
54
8b4c49c92451 Add initial implementation that handles choices
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
55 mChoiceTextFmt = mAnswerChoiceFmt;
8b4c49c92451 Add initial implementation that handles choices
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
56 mChoiceTextFmt.setVerticalAlignment(Format::AlignVCenter);
69
dab9c19252bd Set wordwrap exiplicitly for multiple choice answers
Andre Heinecke <andre.heinecke@intevation.de>
parents: 65
diff changeset
57 mChoiceTextFmt.setTextWarp(true);
3
8b4c49c92451 Add initial implementation that handles choices
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
58
15
03dad1cff5b9 Minor layout fixes
Andre Heinecke <andre.heinecke@intevation.de>
parents: 13
diff changeset
59 mChoiceVotesFmt = mChoiceTextFmt;
03dad1cff5b9 Minor layout fixes
Andre Heinecke <andre.heinecke@intevation.de>
parents: 13
diff changeset
60 mChoiceVotesFmt.setFontSize(10);
03dad1cff5b9 Minor layout fixes
Andre Heinecke <andre.heinecke@intevation.de>
parents: 13
diff changeset
61
6
a10425e7ef98 Add free text handling
Andre Heinecke <andre.heinecke@intevation.de>
parents: 3
diff changeset
62 mFreeTextFmt = mQuestionFmt;
a10425e7ef98 Add free text handling
Andre Heinecke <andre.heinecke@intevation.de>
parents: 3
diff changeset
63 mFreeTextFmt.setFontBold(false);
3
8b4c49c92451 Add initial implementation that handles choices
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
64
6
a10425e7ef98 Add free text handling
Andre Heinecke <andre.heinecke@intevation.de>
parents: 3
diff changeset
65 mAnswerTextFmt = mQuestionFmt;
a10425e7ef98 Add free text handling
Andre Heinecke <andre.heinecke@intevation.de>
parents: 3
diff changeset
66 mAnswerTextFmt.setVerticalAlignment(Format::AlignVCenter);
a10425e7ef98 Add free text handling
Andre Heinecke <andre.heinecke@intevation.de>
parents: 3
diff changeset
67 mAnswerTextFmt.setHorizontalAlignment(Format::AlignLeft);
25
e5c5ebfa4205 Refactor to centralise html tags
Andre Heinecke <andre.heinecke@intevation.de>
parents: 23
diff changeset
68
e5c5ebfa4205 Refactor to centralise html tags
Andre Heinecke <andre.heinecke@intevation.de>
parents: 23
diff changeset
69 mTitleStyle = QStringLiteral("<tr><td colspan='3' style='vertical-align: top;"
26
5acd601356ba Make HTML work for QTextDocument
Andre Heinecke <andre.heinecke@intevation.de>
parents: 25
diff changeset
70 "font-weight: bold; text-decoration:underline; font-size: 18pt;'>"
5acd601356ba Make HTML work for QTextDocument
Andre Heinecke <andre.heinecke@intevation.de>
parents: 25
diff changeset
71 "%1</td></tr><tr/>");
32
ad54c98cb8d8 Minor layout fixes
Andre Heinecke <andre.heinecke@intevation.de>
parents: 26
diff changeset
72 mQuestionStyle = QStringLiteral("<tr><td colspan='3' style='font-size: 11pt;font-weight: bold;'"
ad54c98cb8d8 Minor layout fixes
Andre Heinecke <andre.heinecke@intevation.de>
parents: 26
diff changeset
73 "><hr/>%1<hr/></td></tr>");
26
5acd601356ba Make HTML work for QTextDocument
Andre Heinecke <andre.heinecke@intevation.de>
parents: 25
diff changeset
74 mAnswerChoiceStyle= QStringLiteral("<tr><td colspan='3' style='text-align: left; font-size: 11pt;'>Answer</td></tr>");
5acd601356ba Make HTML work for QTextDocument
Andre Heinecke <andre.heinecke@intevation.de>
parents: 25
diff changeset
75 mChoiceTextStyle= QStringLiteral("<tr><td align='right' style='vertical-align: middle; font-size:11pt;'>%1</td>");
79
a8cd9b27e3d5 Fix vote string valign
Andre Heinecke <andre.heinecke@intevation.de>
parents: 78
diff changeset
76 mChoiceVotesStyle = QStringLiteral("<td align='left' style='vertical-align: middle; font-size:10pt;'>%1</td></tr>");
26
5acd601356ba Make HTML work for QTextDocument
Andre Heinecke <andre.heinecke@intevation.de>
parents: 25
diff changeset
77 mAnswerTextStyle = QStringLiteral("<tr><td colspan='3' style='font-weight: bold;vertical-algin: middle;"
5acd601356ba Make HTML work for QTextDocument
Andre Heinecke <andre.heinecke@intevation.de>
parents: 25
diff changeset
78 "font-size:11pt;'>Answer<hr/></td></tr>");
78
f230ed9022e0 Rework questions to new logic for multilne questions
Andre Heinecke <andre.heinecke@intevation.de>
parents: 76
diff changeset
79 mFreeTextStyle = QStringLiteral("<tr><td colspan='3'; style='font-size:11pt;'>%1<hr/></td></tr>");
25
e5c5ebfa4205 Refactor to centralise html tags
Andre Heinecke <andre.heinecke@intevation.de>
parents: 23
diff changeset
80 mEmptyRow = QStringLiteral("<tr style='height: %1px'/>").arg(CHOICE_ROW_HEIGHT);
3
8b4c49c92451 Add initial implementation that handles choices
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
81 }
8b4c49c92451 Add initial implementation that handles choices
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
82
8b4c49c92451 Add initial implementation that handles choices
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
83 void Converter::run()
8b4c49c92451 Add initial implementation that handles choices
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
84 {
8b4c49c92451 Add initial implementation that handles choices
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
85 QFile infile;
8b4c49c92451 Add initial implementation that handles choices
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
86
8b4c49c92451 Add initial implementation that handles choices
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
87 if (mInput.isEmpty()) {
8b4c49c92451 Add initial implementation that handles choices
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
88 if (!infile.open(stdin, QIODevice::ReadOnly)) {
8b4c49c92451 Add initial implementation that handles choices
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
89 mErrors << tr("Failed to open standard input and no input file provided.");
8b4c49c92451 Add initial implementation that handles choices
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
90 return;
8b4c49c92451 Add initial implementation that handles choices
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
91 }
8b4c49c92451 Add initial implementation that handles choices
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
92 } else {
8b4c49c92451 Add initial implementation that handles choices
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
93 infile.setFileName(mInput);
8b4c49c92451 Add initial implementation that handles choices
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
94 if (!infile.open(QIODevice::ReadOnly)) {
8b4c49c92451 Add initial implementation that handles choices
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
95 mErrors << tr("Failed to open %1 for reading.").arg(mInput);
8b4c49c92451 Add initial implementation that handles choices
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
96 return;
8b4c49c92451 Add initial implementation that handles choices
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
97 }
8b4c49c92451 Add initial implementation that handles choices
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
98 }
8b4c49c92451 Add initial implementation that handles choices
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
99 QTextStream instream(&infile);
8b4c49c92451 Add initial implementation that handles choices
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
100
38
5354cbda7188 Fix HTML Layout. Support multiple formats at once. More handling.
Andre Heinecke <andre.heinecke@intevation.de>
parents: 35
diff changeset
101 QList<QFile*> outfiles;
5354cbda7188 Fix HTML Layout. Support multiple formats at once. More handling.
Andre Heinecke <andre.heinecke@intevation.de>
parents: 35
diff changeset
102
5354cbda7188 Fix HTML Layout. Support multiple formats at once. More handling.
Andre Heinecke <andre.heinecke@intevation.de>
parents: 35
diff changeset
103 if (mOutputs.isEmpty()) {
5354cbda7188 Fix HTML Layout. Support multiple formats at once. More handling.
Andre Heinecke <andre.heinecke@intevation.de>
parents: 35
diff changeset
104 QFile *outfile = new QFile();
5354cbda7188 Fix HTML Layout. Support multiple formats at once. More handling.
Andre Heinecke <andre.heinecke@intevation.de>
parents: 35
diff changeset
105 if (!outfile->open(stdout, QIODevice::WriteOnly)) {
3
8b4c49c92451 Add initial implementation that handles choices
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
106 mErrors << tr("Failed to open standard output and no output file provided.");
8b4c49c92451 Add initial implementation that handles choices
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
107 return;
8b4c49c92451 Add initial implementation that handles choices
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
108 }
38
5354cbda7188 Fix HTML Layout. Support multiple formats at once. More handling.
Andre Heinecke <andre.heinecke@intevation.de>
parents: 35
diff changeset
109 outfiles << outfile;
5354cbda7188 Fix HTML Layout. Support multiple formats at once. More handling.
Andre Heinecke <andre.heinecke@intevation.de>
parents: 35
diff changeset
110 }
5354cbda7188 Fix HTML Layout. Support multiple formats at once. More handling.
Andre Heinecke <andre.heinecke@intevation.de>
parents: 35
diff changeset
111 foreach (const QString &fileName, mOutputs) {
5354cbda7188 Fix HTML Layout. Support multiple formats at once. More handling.
Andre Heinecke <andre.heinecke@intevation.de>
parents: 35
diff changeset
112 QFile *outfile = new QFile();
5354cbda7188 Fix HTML Layout. Support multiple formats at once. More handling.
Andre Heinecke <andre.heinecke@intevation.de>
parents: 35
diff changeset
113 outfile->setFileName(fileName);
5354cbda7188 Fix HTML Layout. Support multiple formats at once. More handling.
Andre Heinecke <andre.heinecke@intevation.de>
parents: 35
diff changeset
114 if (!outfile->open(QIODevice::WriteOnly)) {
5354cbda7188 Fix HTML Layout. Support multiple formats at once. More handling.
Andre Heinecke <andre.heinecke@intevation.de>
parents: 35
diff changeset
115 mErrors << tr("Failed to open %1 for writing.").arg(fileName);
3
8b4c49c92451 Add initial implementation that handles choices
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
116 return;
8b4c49c92451 Add initial implementation that handles choices
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
117 }
38
5354cbda7188 Fix HTML Layout. Support multiple formats at once. More handling.
Andre Heinecke <andre.heinecke@intevation.de>
parents: 35
diff changeset
118 outfiles << outfile;
3
8b4c49c92451 Add initial implementation that handles choices
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
119 }
38
5354cbda7188 Fix HTML Layout. Support multiple formats at once. More handling.
Andre Heinecke <andre.heinecke@intevation.de>
parents: 35
diff changeset
120 convertToXSLX(instream, outfiles);
3
8b4c49c92451 Add initial implementation that handles choices
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
121 }
8b4c49c92451 Add initial implementation that handles choices
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
122
38
5354cbda7188 Fix HTML Layout. Support multiple formats at once. More handling.
Andre Heinecke <andre.heinecke@intevation.de>
parents: 35
diff changeset
123 static void makeBar(QTextStream &html, double percent, QTextDocument &doc)
25
e5c5ebfa4205 Refactor to centralise html tags
Andre Heinecke <andre.heinecke@intevation.de>
parents: 23
diff changeset
124 {
38
5354cbda7188 Fix HTML Layout. Support multiple formats at once. More handling.
Andre Heinecke <andre.heinecke@intevation.de>
parents: 35
diff changeset
125 QImage image(QSize(IMAGE_WIDTH, 25), QImage::Format_RGB32);
26
5acd601356ba Make HTML work for QTextDocument
Andre Heinecke <andre.heinecke@intevation.de>
parents: 25
diff changeset
126 QPainter painter(&image);
5acd601356ba Make HTML work for QTextDocument
Andre Heinecke <andre.heinecke@intevation.de>
parents: 25
diff changeset
127 QRect rect = image.rect();
38
5354cbda7188 Fix HTML Layout. Support multiple formats at once. More handling.
Andre Heinecke <andre.heinecke@intevation.de>
parents: 35
diff changeset
128 if (percent) {
5354cbda7188 Fix HTML Layout. Support multiple formats at once. More handling.
Andre Heinecke <andre.heinecke@intevation.de>
parents: 35
diff changeset
129 rect.setRight(rect.right() / (100. / percent));
5354cbda7188 Fix HTML Layout. Support multiple formats at once. More handling.
Andre Heinecke <andre.heinecke@intevation.de>
parents: 35
diff changeset
130 painter.fillRect(rect, QColor(BAR_COLOR));
5354cbda7188 Fix HTML Layout. Support multiple formats at once. More handling.
Andre Heinecke <andre.heinecke@intevation.de>
parents: 35
diff changeset
131 rect.setLeft(rect.right());
5354cbda7188 Fix HTML Layout. Support multiple formats at once. More handling.
Andre Heinecke <andre.heinecke@intevation.de>
parents: 35
diff changeset
132 }
5354cbda7188 Fix HTML Layout. Support multiple formats at once. More handling.
Andre Heinecke <andre.heinecke@intevation.de>
parents: 35
diff changeset
133 rect.setRight(IMAGE_WIDTH);
26
5acd601356ba Make HTML work for QTextDocument
Andre Heinecke <andre.heinecke@intevation.de>
parents: 25
diff changeset
134 painter.fillRect(rect, Qt::white);
38
5354cbda7188 Fix HTML Layout. Support multiple formats at once. More handling.
Andre Heinecke <andre.heinecke@intevation.de>
parents: 35
diff changeset
135 doc.addResource(QTextDocument::ImageResource, QUrl(QStringLiteral("internal://bar%1.png").arg((int)percent)),
26
5acd601356ba Make HTML work for QTextDocument
Andre Heinecke <andre.heinecke@intevation.de>
parents: 25
diff changeset
136 QVariant(image));
38
5354cbda7188 Fix HTML Layout. Support multiple formats at once. More handling.
Andre Heinecke <andre.heinecke@intevation.de>
parents: 35
diff changeset
137 html << QStringLiteral("<td style='vertical-align: middle'><img src=\"internal://bar%1.png\"/></td>").arg((int)percent);
25
e5c5ebfa4205 Refactor to centralise html tags
Andre Heinecke <andre.heinecke@intevation.de>
parents: 23
diff changeset
138 return;
e5c5ebfa4205 Refactor to centralise html tags
Andre Heinecke <andre.heinecke@intevation.de>
parents: 23
diff changeset
139 }
e5c5ebfa4205 Refactor to centralise html tags
Andre Heinecke <andre.heinecke@intevation.de>
parents: 23
diff changeset
140
76
1e6e7699f0b8 Add replacements.ini to configure text replacements
Andre Heinecke <andre.heinecke@intevation.de>
parents: 75
diff changeset
141 static const QMap<QRegularExpression*, QString> loadExpressionsFromFile(const QString &path, QStringList &errors)
65
defd29b9f25a Converter: Unescape IMG and Latex references
Andre Heinecke <andre.heinecke@intevation.de>
parents: 63
diff changeset
142 {
76
1e6e7699f0b8 Add replacements.ini to configure text replacements
Andre Heinecke <andre.heinecke@intevation.de>
parents: 75
diff changeset
143 QFile file(path);
1e6e7699f0b8 Add replacements.ini to configure text replacements
Andre Heinecke <andre.heinecke@intevation.de>
parents: 75
diff changeset
144 QMap<QRegularExpression*, QString> ret;
1e6e7699f0b8 Add replacements.ini to configure text replacements
Andre Heinecke <andre.heinecke@intevation.de>
parents: 75
diff changeset
145
1e6e7699f0b8 Add replacements.ini to configure text replacements
Andre Heinecke <andre.heinecke@intevation.de>
parents: 75
diff changeset
146 if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
1e6e7699f0b8 Add replacements.ini to configure text replacements
Andre Heinecke <andre.heinecke@intevation.de>
parents: 75
diff changeset
147 errors << QObject::tr("Failed to open replacement file:") + "\n\"" + path + "\"";
1e6e7699f0b8 Add replacements.ini to configure text replacements
Andre Heinecke <andre.heinecke@intevation.de>
parents: 75
diff changeset
148 return ret;
65
defd29b9f25a Converter: Unescape IMG and Latex references
Andre Heinecke <andre.heinecke@intevation.de>
parents: 63
diff changeset
149 }
76
1e6e7699f0b8 Add replacements.ini to configure text replacements
Andre Heinecke <andre.heinecke@intevation.de>
parents: 75
diff changeset
150
1e6e7699f0b8 Add replacements.ini to configure text replacements
Andre Heinecke <andre.heinecke@intevation.de>
parents: 75
diff changeset
151 while (!file.atEnd()) {
1e6e7699f0b8 Add replacements.ini to configure text replacements
Andre Heinecke <andre.heinecke@intevation.de>
parents: 75
diff changeset
152 const auto line = file.readLine();
1e6e7699f0b8 Add replacements.ini to configure text replacements
Andre Heinecke <andre.heinecke@intevation.de>
parents: 75
diff changeset
153 auto strline = QString::fromUtf8(line).trimmed();
1e6e7699f0b8 Add replacements.ini to configure text replacements
Andre Heinecke <andre.heinecke@intevation.de>
parents: 75
diff changeset
154 if (strline.startsWith(QStringLiteral(";")) || strline.isEmpty()) {
1e6e7699f0b8 Add replacements.ini to configure text replacements
Andre Heinecke <andre.heinecke@intevation.de>
parents: 75
diff changeset
155 continue;
1e6e7699f0b8 Add replacements.ini to configure text replacements
Andre Heinecke <andre.heinecke@intevation.de>
parents: 75
diff changeset
156 }
1e6e7699f0b8 Add replacements.ini to configure text replacements
Andre Heinecke <andre.heinecke@intevation.de>
parents: 75
diff changeset
157
1e6e7699f0b8 Add replacements.ini to configure text replacements
Andre Heinecke <andre.heinecke@intevation.de>
parents: 75
diff changeset
158 auto split = strline.split("=");
1e6e7699f0b8 Add replacements.ini to configure text replacements
Andre Heinecke <andre.heinecke@intevation.de>
parents: 75
diff changeset
159 if (split.count() != 2) {
1e6e7699f0b8 Add replacements.ini to configure text replacements
Andre Heinecke <andre.heinecke@intevation.de>
parents: 75
diff changeset
160 errors << QObject::tr("Invalid replacement line:") + "\n\"" + strline + "\"";
1e6e7699f0b8 Add replacements.ini to configure text replacements
Andre Heinecke <andre.heinecke@intevation.de>
parents: 75
diff changeset
161 continue;
1e6e7699f0b8 Add replacements.ini to configure text replacements
Andre Heinecke <andre.heinecke@intevation.de>
parents: 75
diff changeset
162 }
1e6e7699f0b8 Add replacements.ini to configure text replacements
Andre Heinecke <andre.heinecke@intevation.de>
parents: 75
diff changeset
163
1e6e7699f0b8 Add replacements.ini to configure text replacements
Andre Heinecke <andre.heinecke@intevation.de>
parents: 75
diff changeset
164 auto exp = new QRegularExpression (split[0], QRegularExpression::MultilineOption);
1e6e7699f0b8 Add replacements.ini to configure text replacements
Andre Heinecke <andre.heinecke@intevation.de>
parents: 75
diff changeset
165 if (!exp->isValid()) {
1e6e7699f0b8 Add replacements.ini to configure text replacements
Andre Heinecke <andre.heinecke@intevation.de>
parents: 75
diff changeset
166 errors << QObject::tr("Invalid regular expression:") + "\n\"" + split[0] + "\"" +
1e6e7699f0b8 Add replacements.ini to configure text replacements
Andre Heinecke <andre.heinecke@intevation.de>
parents: 75
diff changeset
167 "\n" + QObject::tr("Error: ") + exp->errorString();
1e6e7699f0b8 Add replacements.ini to configure text replacements
Andre Heinecke <andre.heinecke@intevation.de>
parents: 75
diff changeset
168 continue;
1e6e7699f0b8 Add replacements.ini to configure text replacements
Andre Heinecke <andre.heinecke@intevation.de>
parents: 75
diff changeset
169 }
1e6e7699f0b8 Add replacements.ini to configure text replacements
Andre Heinecke <andre.heinecke@intevation.de>
parents: 75
diff changeset
170 const auto rep = split[1].replace("\"", "");
1e6e7699f0b8 Add replacements.ini to configure text replacements
Andre Heinecke <andre.heinecke@intevation.de>
parents: 75
diff changeset
171 ret.insert(exp, rep);
1e6e7699f0b8 Add replacements.ini to configure text replacements
Andre Heinecke <andre.heinecke@intevation.de>
parents: 75
diff changeset
172 qDebug() << "Loaded replacement: " << *exp << " replacement:" << rep << "";
1e6e7699f0b8 Add replacements.ini to configure text replacements
Andre Heinecke <andre.heinecke@intevation.de>
parents: 75
diff changeset
173 }
1e6e7699f0b8 Add replacements.ini to configure text replacements
Andre Heinecke <andre.heinecke@intevation.de>
parents: 75
diff changeset
174 /* Special one that does not fit into the ini format well. */
1e6e7699f0b8 Add replacements.ini to configure text replacements
Andre Heinecke <andre.heinecke@intevation.de>
parents: 75
diff changeset
175 ret.insert(new QRegularExpression("^="), " =");
1e6e7699f0b8 Add replacements.ini to configure text replacements
Andre Heinecke <andre.heinecke@intevation.de>
parents: 75
diff changeset
176 return ret;
65
defd29b9f25a Converter: Unescape IMG and Latex references
Andre Heinecke <andre.heinecke@intevation.de>
parents: 63
diff changeset
177 }
defd29b9f25a Converter: Unescape IMG and Latex references
Andre Heinecke <andre.heinecke@intevation.de>
parents: 63
diff changeset
178
76
1e6e7699f0b8 Add replacements.ini to configure text replacements
Andre Heinecke <andre.heinecke@intevation.de>
parents: 75
diff changeset
179 static const QMap<QRegularExpression*, QString> loadExpressions(QStringList &errors)
65
defd29b9f25a Converter: Unescape IMG and Latex references
Andre Heinecke <andre.heinecke@intevation.de>
parents: 63
diff changeset
180 {
76
1e6e7699f0b8 Add replacements.ini to configure text replacements
Andre Heinecke <andre.heinecke@intevation.de>
parents: 75
diff changeset
181 QMap<QRegularExpression*, QString> regexs;
1e6e7699f0b8 Add replacements.ini to configure text replacements
Andre Heinecke <andre.heinecke@intevation.de>
parents: 75
diff changeset
182 /* Look for file next to our place */
1e6e7699f0b8 Add replacements.ini to configure text replacements
Andre Heinecke <andre.heinecke@intevation.de>
parents: 75
diff changeset
183 auto ourDir = QDir(QCoreApplication::applicationDirPath());
1e6e7699f0b8 Add replacements.ini to configure text replacements
Andre Heinecke <andre.heinecke@intevation.de>
parents: 75
diff changeset
184 const auto filename = QStringLiteral(CONFIG_FILE_NAME);
1e6e7699f0b8 Add replacements.ini to configure text replacements
Andre Heinecke <andre.heinecke@intevation.de>
parents: 75
diff changeset
185 if (ourDir.exists(filename)) {
1e6e7699f0b8 Add replacements.ini to configure text replacements
Andre Heinecke <andre.heinecke@intevation.de>
parents: 75
diff changeset
186 regexs = loadExpressionsFromFile(ourDir.filePath(filename), errors);
1e6e7699f0b8 Add replacements.ini to configure text replacements
Andre Heinecke <andre.heinecke@intevation.de>
parents: 75
diff changeset
187 return regexs;
1e6e7699f0b8 Add replacements.ini to configure text replacements
Andre Heinecke <andre.heinecke@intevation.de>
parents: 75
diff changeset
188 }
65
defd29b9f25a Converter: Unescape IMG and Latex references
Andre Heinecke <andre.heinecke@intevation.de>
parents: 63
diff changeset
189
76
1e6e7699f0b8 Add replacements.ini to configure text replacements
Andre Heinecke <andre.heinecke@intevation.de>
parents: 75
diff changeset
190 /* Look in ../share/apps/PROJECT_NAME */
1e6e7699f0b8 Add replacements.ini to configure text replacements
Andre Heinecke <andre.heinecke@intevation.de>
parents: 75
diff changeset
191 ourDir.cd(QStringLiteral("../share/apps/" APPNAME).toLower());
1e6e7699f0b8 Add replacements.ini to configure text replacements
Andre Heinecke <andre.heinecke@intevation.de>
parents: 75
diff changeset
192 if (ourDir.exists(filename)) {
1e6e7699f0b8 Add replacements.ini to configure text replacements
Andre Heinecke <andre.heinecke@intevation.de>
parents: 75
diff changeset
193 regexs = loadExpressionsFromFile(ourDir.filePath(filename), errors);
1e6e7699f0b8 Add replacements.ini to configure text replacements
Andre Heinecke <andre.heinecke@intevation.de>
parents: 75
diff changeset
194 } else {
1e6e7699f0b8 Add replacements.ini to configure text replacements
Andre Heinecke <andre.heinecke@intevation.de>
parents: 75
diff changeset
195 qDebug() << "Failed to find regular expressions.";
1e6e7699f0b8 Add replacements.ini to configure text replacements
Andre Heinecke <andre.heinecke@intevation.de>
parents: 75
diff changeset
196 }
1e6e7699f0b8 Add replacements.ini to configure text replacements
Andre Heinecke <andre.heinecke@intevation.de>
parents: 75
diff changeset
197 return regexs;
1e6e7699f0b8 Add replacements.ini to configure text replacements
Andre Heinecke <andre.heinecke@intevation.de>
parents: 75
diff changeset
198 }
1e6e7699f0b8 Add replacements.ini to configure text replacements
Andre Heinecke <andre.heinecke@intevation.de>
parents: 75
diff changeset
199
1e6e7699f0b8 Add replacements.ini to configure text replacements
Andre Heinecke <andre.heinecke@intevation.de>
parents: 75
diff changeset
200 static const QStringList sanitizeInput(QString &str)
1e6e7699f0b8 Add replacements.ini to configure text replacements
Andre Heinecke <andre.heinecke@intevation.de>
parents: 75
diff changeset
201 {
1e6e7699f0b8 Add replacements.ini to configure text replacements
Andre Heinecke <andre.heinecke@intevation.de>
parents: 75
diff changeset
202 QStringList errors;
1e6e7699f0b8 Add replacements.ini to configure text replacements
Andre Heinecke <andre.heinecke@intevation.de>
parents: 75
diff changeset
203 str.replace("\r\n", "\n");
1e6e7699f0b8 Add replacements.ini to configure text replacements
Andre Heinecke <andre.heinecke@intevation.de>
parents: 75
diff changeset
204 str.replace("\n\r", "\n");
1e6e7699f0b8 Add replacements.ini to configure text replacements
Andre Heinecke <andre.heinecke@intevation.de>
parents: 75
diff changeset
205 const auto expressions = loadExpressions(errors);
1e6e7699f0b8 Add replacements.ini to configure text replacements
Andre Heinecke <andre.heinecke@intevation.de>
parents: 75
diff changeset
206 for (const auto regex: expressions.keys()) {
1e6e7699f0b8 Add replacements.ini to configure text replacements
Andre Heinecke <andre.heinecke@intevation.de>
parents: 75
diff changeset
207 str.replace(*regex, expressions.value(regex));
1e6e7699f0b8 Add replacements.ini to configure text replacements
Andre Heinecke <andre.heinecke@intevation.de>
parents: 75
diff changeset
208 delete regex;
1e6e7699f0b8 Add replacements.ini to configure text replacements
Andre Heinecke <andre.heinecke@intevation.de>
parents: 75
diff changeset
209 }
1e6e7699f0b8 Add replacements.ini to configure text replacements
Andre Heinecke <andre.heinecke@intevation.de>
parents: 75
diff changeset
210 return errors;
1e6e7699f0b8 Add replacements.ini to configure text replacements
Andre Heinecke <andre.heinecke@intevation.de>
parents: 75
diff changeset
211 }
1e6e7699f0b8 Add replacements.ini to configure text replacements
Andre Heinecke <andre.heinecke@intevation.de>
parents: 75
diff changeset
212
1e6e7699f0b8 Add replacements.ini to configure text replacements
Andre Heinecke <andre.heinecke@intevation.de>
parents: 75
diff changeset
213 static void xlsEscape(QString &str)
1e6e7699f0b8 Add replacements.ini to configure text replacements
Andre Heinecke <andre.heinecke@intevation.de>
parents: 75
diff changeset
214 {
74
9a2e35a7c19c Also escape leading equal sign in questions / choices
Andre Heinecke <andre.heinecke@intevation.de>
parents: 73
diff changeset
215 if (str.startsWith("=")) {
9a2e35a7c19c Also escape leading equal sign in questions / choices
Andre Heinecke <andre.heinecke@intevation.de>
parents: 73
diff changeset
216 str = " " + str;
9a2e35a7c19c Also escape leading equal sign in questions / choices
Andre Heinecke <andre.heinecke@intevation.de>
parents: 73
diff changeset
217 }
65
defd29b9f25a Converter: Unescape IMG and Latex references
Andre Heinecke <andre.heinecke@intevation.de>
parents: 63
diff changeset
218 }
defd29b9f25a Converter: Unescape IMG and Latex references
Andre Heinecke <andre.heinecke@intevation.de>
parents: 63
diff changeset
219
38
5354cbda7188 Fix HTML Layout. Support multiple formats at once. More handling.
Andre Heinecke <andre.heinecke@intevation.de>
parents: 35
diff changeset
220 void Converter::convertToXSLX(QTextStream& instream, QList<QFile *>outputs)
3
8b4c49c92451 Add initial implementation that handles choices
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
221 {
8b4c49c92451 Add initial implementation that handles choices
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
222 Document xlsx;
23
927794e3cc52 Add HTML output and some pdf support
Andre Heinecke <andre.heinecke@intevation.de>
parents: 21
diff changeset
223 QTextDocument doc;
927794e3cc52 Add HTML output and some pdf support
Andre Heinecke <andre.heinecke@intevation.de>
parents: 21
diff changeset
224 QString htmlString;
927794e3cc52 Add HTML output and some pdf support
Andre Heinecke <andre.heinecke@intevation.de>
parents: 21
diff changeset
225 QTextStream html (&htmlString);
70
3438f5cce8cc Force text codec for html to use UTF-8
Andre Heinecke <andre.heinecke@intevation.de>
parents: 69
diff changeset
226 html.setCodec("UTF-8");
3
8b4c49c92451 Add initial implementation that handles choices
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
227
8b4c49c92451 Add initial implementation that handles choices
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
228 ConditionalFormatting bars;
8b4c49c92451 Add initial implementation that handles choices
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
229
6
a10425e7ef98 Add free text handling
Andre Heinecke <andre.heinecke@intevation.de>
parents: 3
diff changeset
230 bars.addDataBarRule(QColor(0xFF, 0x99, 0x33), ConditionalFormatting::VOT_Num,
a10425e7ef98 Add free text handling
Andre Heinecke <andre.heinecke@intevation.de>
parents: 3
diff changeset
231 "0", ConditionalFormatting::VOT_Num, "100", false);
3
8b4c49c92451 Add initial implementation that handles choices
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
232
8b4c49c92451 Add initial implementation that handles choices
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
233 const double colWidth[] = COLUMN_WIDTHS;
6
a10425e7ef98 Add free text handling
Andre Heinecke <andre.heinecke@intevation.de>
parents: 3
diff changeset
234 double sum = 0;
23
927794e3cc52 Add HTML output and some pdf support
Andre Heinecke <andre.heinecke@intevation.de>
parents: 21
diff changeset
235
3
8b4c49c92451 Add initial implementation that handles choices
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
236 for (int i = 1; i <= COLUMN_CNT; i++) {
8b4c49c92451 Add initial implementation that handles choices
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
237 xlsx.setColumnWidth(i, colWidth[i-1]);
6
a10425e7ef98 Add free text handling
Andre Heinecke <andre.heinecke@intevation.de>
parents: 3
diff changeset
238 sum += colWidth[i-1];
3
8b4c49c92451 Add initial implementation that handles choices
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
239 }
8b4c49c92451 Add initial implementation that handles choices
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
240
6
a10425e7ef98 Add free text handling
Andre Heinecke <andre.heinecke@intevation.de>
parents: 3
diff changeset
241 /* For the merged cell wordwrap trick. */
15
03dad1cff5b9 Minor layout fixes
Andre Heinecke <andre.heinecke@intevation.de>
parents: 13
diff changeset
242 xlsx.setColumnWidth(26, sum + 1);
6
a10425e7ef98 Add free text handling
Andre Heinecke <andre.heinecke@intevation.de>
parents: 3
diff changeset
243 xlsx.setColumnHidden(26, true);
a10425e7ef98 Add free text handling
Andre Heinecke <andre.heinecke@intevation.de>
parents: 3
diff changeset
244
80
2f81925b0eee Make html valid and add title
Andre Heinecke <andre.heinecke@intevation.de>
parents: 79
diff changeset
245 const QString title = mTitle.isEmpty() ? DEFAULT_TITLE : mTitle;
2f81925b0eee Make html valid and add title
Andre Heinecke <andre.heinecke@intevation.de>
parents: 79
diff changeset
246
26
5acd601356ba Make HTML work for QTextDocument
Andre Heinecke <andre.heinecke@intevation.de>
parents: 25
diff changeset
247 int row = 1;
80
2f81925b0eee Make html valid and add title
Andre Heinecke <andre.heinecke@intevation.de>
parents: 79
diff changeset
248 html << QStringLiteral("<!DOCTYPE html><html xmlns=\"http://www.w3.org/1999/xhtml\">"
2f81925b0eee Make html valid and add title
Andre Heinecke <andre.heinecke@intevation.de>
parents: 79
diff changeset
249 "<head><meta http-equiv=\"Content-Type\" content=\"text/html;charset=UTF-8\"/>"
2f81925b0eee Make html valid and add title
Andre Heinecke <andre.heinecke@intevation.de>
parents: 79
diff changeset
250 "<title>%1</title>"
2f81925b0eee Make html valid and add title
Andre Heinecke <andre.heinecke@intevation.de>
parents: 79
diff changeset
251 "</head><body><table border=\"0\" width=\"100%\">").arg(title.toHtmlEscaped());
38
5354cbda7188 Fix HTML Layout. Support multiple formats at once. More handling.
Andre Heinecke <andre.heinecke@intevation.de>
parents: 35
diff changeset
252 html << QStringLiteral("<tr><th width=\"%1%\"></th>").arg(HTML_COL1_PERCENT);
5354cbda7188 Fix HTML Layout. Support multiple formats at once. More handling.
Andre Heinecke <andre.heinecke@intevation.de>
parents: 35
diff changeset
253 html << QStringLiteral("<th width=\"%1%\"></th>").arg(HTML_COL2_PERCENT);
5354cbda7188 Fix HTML Layout. Support multiple formats at once. More handling.
Andre Heinecke <andre.heinecke@intevation.de>
parents: 35
diff changeset
254 html << QStringLiteral("<th width=\"%1%\"></th>").arg(HTML_COL3_PERCENT);
23
927794e3cc52 Add HTML output and some pdf support
Andre Heinecke <andre.heinecke@intevation.de>
parents: 21
diff changeset
255
927794e3cc52 Add HTML output and some pdf support
Andre Heinecke <andre.heinecke@intevation.de>
parents: 21
diff changeset
256 // Set the title of the Questionaire
927794e3cc52 Add HTML output and some pdf support
Andre Heinecke <andre.heinecke@intevation.de>
parents: 21
diff changeset
257 xlsx.write(row++, 1, title, mTitleFmt);
25
e5c5ebfa4205 Refactor to centralise html tags
Andre Heinecke <andre.heinecke@intevation.de>
parents: 23
diff changeset
258 html << mTitleStyle.arg(title.toHtmlEscaped());
20
df7936065450 Add default title
Andre Heinecke <andre.heinecke@intevation.de>
parents: 15
diff changeset
259 xlsx.mergeCells("A1:C1");
df7936065450 Add default title
Andre Heinecke <andre.heinecke@intevation.de>
parents: 15
diff changeset
260 xlsx.setRowHeight(1, TITLE_ROW_HEIGHT);
3
8b4c49c92451 Add initial implementation that handles choices
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
261
43
f9a0b2b6832e Sanitize input and unify Lineendings
Andre Heinecke <andre.heinecke@intevation.de>
parents: 41
diff changeset
262 QString input = instream.readAll();
3
8b4c49c92451 Add initial implementation that handles choices
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
263
8b4c49c92451 Add initial implementation that handles choices
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
264 QRegularExpression questionEx(QUESTION_PATTERN);
8b4c49c92451 Add initial implementation that handles choices
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
265 QRegularExpression choiceEx(CHOICE_PATTERN);
38
5354cbda7188 Fix HTML Layout. Support multiple formats at once. More handling.
Andre Heinecke <andre.heinecke@intevation.de>
parents: 35
diff changeset
266 QRegularExpression choiceAltEx(CHOICE_UNFILLED_PATTERN);
5354cbda7188 Fix HTML Layout. Support multiple formats at once. More handling.
Andre Heinecke <andre.heinecke@intevation.de>
parents: 35
diff changeset
267 QRegularExpression freetxtEx(FREETXT_PATTERN);
3
8b4c49c92451 Add initial implementation that handles choices
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
268
76
1e6e7699f0b8 Add replacements.ini to configure text replacements
Andre Heinecke <andre.heinecke@intevation.de>
parents: 75
diff changeset
269 mErrors += sanitizeInput(input);
43
f9a0b2b6832e Sanitize input and unify Lineendings
Andre Heinecke <andre.heinecke@intevation.de>
parents: 41
diff changeset
270
78
f230ed9022e0 Rework questions to new logic for multilne questions
Andre Heinecke <andre.heinecke@intevation.de>
parents: 76
diff changeset
271 QRegularExpressionMatch match = questionEx.match(input);
3
8b4c49c92451 Add initial implementation that handles choices
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
272 bool foundSomething = false;
8b4c49c92451 Add initial implementation that handles choices
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
273 int cursor = match.capturedEnd();
8b4c49c92451 Add initial implementation that handles choices
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
274 while (match.hasMatch() && cursor != -1) {
8b4c49c92451 Add initial implementation that handles choices
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
275 /* We've matched a question pattern. With the answer
8b4c49c92451 Add initial implementation that handles choices
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
276 line */
8b4c49c92451 Add initial implementation that handles choices
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
277 if (!match.lastCapturedIndex() == 2) {
8b4c49c92451 Add initial implementation that handles choices
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
278 /* Should not happen without misconfiguration. */
8b4c49c92451 Add initial implementation that handles choices
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
279 mErrors << "Internal parser error.";
8b4c49c92451 Add initial implementation that handles choices
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
280 return;
8b4c49c92451 Add initial implementation that handles choices
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
281 }
8b4c49c92451 Add initial implementation that handles choices
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
282 foundSomething = true;
78
f230ed9022e0 Rework questions to new logic for multilne questions
Andre Heinecke <andre.heinecke@intevation.de>
parents: 76
diff changeset
283 /* A question is everything until the last two newlines
f230ed9022e0 Rework questions to new logic for multilne questions
Andre Heinecke <andre.heinecke@intevation.de>
parents: 76
diff changeset
284 * before an answer line.*/
f230ed9022e0 Rework questions to new logic for multilne questions
Andre Heinecke <andre.heinecke@intevation.de>
parents: 76
diff changeset
285 QString question;
f230ed9022e0 Rework questions to new logic for multilne questions
Andre Heinecke <andre.heinecke@intevation.de>
parents: 76
diff changeset
286
f230ed9022e0 Rework questions to new logic for multilne questions
Andre Heinecke <andre.heinecke@intevation.de>
parents: 76
diff changeset
287 int lastBreaks = input.lastIndexOf(QStringLiteral("\n\n"), cursor);
f230ed9022e0 Rework questions to new logic for multilne questions
Andre Heinecke <andre.heinecke@intevation.de>
parents: 76
diff changeset
288 if (lastBreaks == -1) {
f230ed9022e0 Rework questions to new logic for multilne questions
Andre Heinecke <andre.heinecke@intevation.de>
parents: 76
diff changeset
289 /* First question */
f230ed9022e0 Rework questions to new logic for multilne questions
Andre Heinecke <andre.heinecke@intevation.de>
parents: 76
diff changeset
290 lastBreaks = 0;
f230ed9022e0 Rework questions to new logic for multilne questions
Andre Heinecke <andre.heinecke@intevation.de>
parents: 76
diff changeset
291 }
f230ed9022e0 Rework questions to new logic for multilne questions
Andre Heinecke <andre.heinecke@intevation.de>
parents: 76
diff changeset
292
f230ed9022e0 Rework questions to new logic for multilne questions
Andre Heinecke <andre.heinecke@intevation.de>
parents: 76
diff changeset
293 question = input.mid(lastBreaks, match.capturedStart() - lastBreaks);
f230ed9022e0 Rework questions to new logic for multilne questions
Andre Heinecke <andre.heinecke@intevation.de>
parents: 76
diff changeset
294 qDebug() << "Found question: " << question;
f230ed9022e0 Rework questions to new logic for multilne questions
Andre Heinecke <andre.heinecke@intevation.de>
parents: 76
diff changeset
295 const QString answerLine = match.captured(1).trimmed();
6
a10425e7ef98 Add free text handling
Andre Heinecke <andre.heinecke@intevation.de>
parents: 3
diff changeset
296 xlsx.write(row, 2, QString(" "), mQuestionFmt);
a10425e7ef98 Add free text handling
Andre Heinecke <andre.heinecke@intevation.de>
parents: 3
diff changeset
297 xlsx.write(row, 3, QString(" "), mQuestionFmt);
76
1e6e7699f0b8 Add replacements.ini to configure text replacements
Andre Heinecke <andre.heinecke@intevation.de>
parents: 75
diff changeset
298 xlsEscape(question);
3
8b4c49c92451 Add initial implementation that handles choices
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
299 xlsx.write(row++, 1, question, mQuestionFmt);
25
e5c5ebfa4205 Refactor to centralise html tags
Andre Heinecke <andre.heinecke@intevation.de>
parents: 23
diff changeset
300 html << mQuestionStyle.arg(question.toHtmlEscaped());
3
8b4c49c92451 Add initial implementation that handles choices
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
301
8b4c49c92451 Add initial implementation that handles choices
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
302 if (answerLine == QStringLiteral(CHOICE_IDENTIFIER)) {
8b4c49c92451 Add initial implementation that handles choices
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
303 xlsx.setRowHeight(row, CHOICE_ROW_HEIGHT);
21
0b66b10a287d Add german translation
Andre Heinecke <andre.heinecke@intevation.de>
parents: 20
diff changeset
304 xlsx.write(row++, 1, "Answer", mAnswerChoiceFmt);
25
e5c5ebfa4205 Refactor to centralise html tags
Andre Heinecke <andre.heinecke@intevation.de>
parents: 23
diff changeset
305 html << mAnswerChoiceStyle;
3
8b4c49c92451 Add initial implementation that handles choices
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
306 int firstChoiceRow = row;
8b4c49c92451 Add initial implementation that handles choices
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
307 int lastChoiceRow = row;
38
5354cbda7188 Fix HTML Layout. Support multiple formats at once. More handling.
Andre Heinecke <andre.heinecke@intevation.de>
parents: 35
diff changeset
308 repeat:
5354cbda7188 Fix HTML Layout. Support multiple formats at once. More handling.
Andre Heinecke <andre.heinecke@intevation.de>
parents: 35
diff changeset
309 QRegularExpressionMatch choiceMatch = choiceEx.match(input, cursor);
3
8b4c49c92451 Add initial implementation that handles choices
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
310 while (choiceMatch.hasMatch() && choiceMatch.capturedStart() == cursor + 1) {
8b4c49c92451 Add initial implementation that handles choices
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
311 /* We use the cursor here to keep track of the state. Only if an answer
8b4c49c92451 Add initial implementation that handles choices
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
312 follows immediately behind the last answer we treat it as valid as
8b4c49c92451 Add initial implementation that handles choices
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
313 otherwise we can't figure out when the next question begins. */
8b4c49c92451 Add initial implementation that handles choices
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
314 cursor = choiceMatch.capturedEnd();
8b4c49c92451 Add initial implementation that handles choices
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
315
8b4c49c92451 Add initial implementation that handles choices
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
316 /* Write the values */
12
21f11f988115 Make sure strings don't start with = and duplicate text instead of formula
Andre Heinecke <andre.heinecke@intevation.de>
parents: 6
diff changeset
317 QString choiceName = choiceMatch.captured(1).trimmed();
76
1e6e7699f0b8 Add replacements.ini to configure text replacements
Andre Heinecke <andre.heinecke@intevation.de>
parents: 75
diff changeset
318 xlsEscape(choiceName);
12
21f11f988115 Make sure strings don't start with = and duplicate text instead of formula
Andre Heinecke <andre.heinecke@intevation.de>
parents: 6
diff changeset
319 xlsx.write(row, 1, choiceName, mChoiceTextFmt);
25
e5c5ebfa4205 Refactor to centralise html tags
Andre Heinecke <andre.heinecke@intevation.de>
parents: 23
diff changeset
320 html << mChoiceTextStyle.arg(choiceName.toHtmlEscaped());
38
5354cbda7188 Fix HTML Layout. Support multiple formats at once. More handling.
Andre Heinecke <andre.heinecke@intevation.de>
parents: 35
diff changeset
321 qDebug() << "Captured for choice: " << choiceMatch.captured(0);
3
8b4c49c92451 Add initial implementation that handles choices
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
322 bool ok;
56
5410f9f279ea Redefine question pattern to be more robust
Andre Heinecke <andre.heinecke@intevation.de>
parents: 55
diff changeset
323 QString percentStr = choiceMatch.captured("percent");
38
5354cbda7188 Fix HTML Layout. Support multiple formats at once. More handling.
Andre Heinecke <andre.heinecke@intevation.de>
parents: 35
diff changeset
324 double percent;
63
4d65e654abf7 Converter: Handle empty percent strings again
Andre Heinecke <andre.heinecke@intevation.de>
parents: 56
diff changeset
325 if (percentStr.isEmpty()) {
38
5354cbda7188 Fix HTML Layout. Support multiple formats at once. More handling.
Andre Heinecke <andre.heinecke@intevation.de>
parents: 35
diff changeset
326 percent = 0;
5354cbda7188 Fix HTML Layout. Support multiple formats at once. More handling.
Andre Heinecke <andre.heinecke@intevation.de>
parents: 35
diff changeset
327 ok = true;
5354cbda7188 Fix HTML Layout. Support multiple formats at once. More handling.
Andre Heinecke <andre.heinecke@intevation.de>
parents: 35
diff changeset
328 } else {
5354cbda7188 Fix HTML Layout. Support multiple formats at once. More handling.
Andre Heinecke <andre.heinecke@intevation.de>
parents: 35
diff changeset
329 percent = percentStr.toDouble(&ok);
5354cbda7188 Fix HTML Layout. Support multiple formats at once. More handling.
Andre Heinecke <andre.heinecke@intevation.de>
parents: 35
diff changeset
330 }
3
8b4c49c92451 Add initial implementation that handles choices
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
331 if (!ok) {
8b4c49c92451 Add initial implementation that handles choices
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
332 mErrors << "Unparsable number in string: " + choiceMatch.captured();
63
4d65e654abf7 Converter: Handle empty percent strings again
Andre Heinecke <andre.heinecke@intevation.de>
parents: 56
diff changeset
333 percent = 0;
4d65e654abf7 Converter: Handle empty percent strings again
Andre Heinecke <andre.heinecke@intevation.de>
parents: 56
diff changeset
334 percentStr = QString();
4d65e654abf7 Converter: Handle empty percent strings again
Andre Heinecke <andre.heinecke@intevation.de>
parents: 56
diff changeset
335 /* PercentStr was not a number. */
3
8b4c49c92451 Add initial implementation that handles choices
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
336 }
38
5354cbda7188 Fix HTML Layout. Support multiple formats at once. More handling.
Andre Heinecke <andre.heinecke@intevation.de>
parents: 35
diff changeset
337 makeBar(html, percent, doc);
39
41cd27a64365 Write empty columns for XSLX to avoid strange 0 formatting
Andre Heinecke <andre.heinecke@intevation.de>
parents: 35
diff changeset
338 xlsx.write(row, 2, percent == 0 ? QVariant() : percent);
38
5354cbda7188 Fix HTML Layout. Support multiple formats at once. More handling.
Andre Heinecke <andre.heinecke@intevation.de>
parents: 35
diff changeset
339 const QString numStr = choiceMatch.captured("num");
81
f3481e9e44b2 Pre align number of votes
Andre Heinecke <andre.heinecke@intevation.de>
parents: 80
diff changeset
340 const QString numVotesString = QString("<pre>%1% | %2 Number of votes</pre> ").
f3481e9e44b2 Pre align number of votes
Andre Heinecke <andre.heinecke@intevation.de>
parents: 80
diff changeset
341 arg(percentStr.isEmpty() ? QStringLiteral("0") : percentStr, 8).
f3481e9e44b2 Pre align number of votes
Andre Heinecke <andre.heinecke@intevation.de>
parents: 80
diff changeset
342 arg(numStr.isEmpty() ? QStringLiteral("0") : numStr, 3);
f3481e9e44b2 Pre align number of votes
Andre Heinecke <andre.heinecke@intevation.de>
parents: 80
diff changeset
343 html << mChoiceVotesStyle.arg(numVotesString);
23
927794e3cc52 Add HTML output and some pdf support
Andre Heinecke <andre.heinecke@intevation.de>
parents: 21
diff changeset
344 xlsx.write(row, 3, numVotesString, mChoiceVotesFmt);
3
8b4c49c92451 Add initial implementation that handles choices
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
345 xlsx.setRowHeight(row, CHOICE_ROW_HEIGHT);
8b4c49c92451 Add initial implementation that handles choices
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
346 /* As long as we can match a choice which is either before the next question
8b4c49c92451 Add initial implementation that handles choices
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
347 or before the end of the document */
8b4c49c92451 Add initial implementation that handles choices
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
348 choiceMatch = choiceEx.match(input, cursor);
8b4c49c92451 Add initial implementation that handles choices
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
349 row++;
8b4c49c92451 Add initial implementation that handles choices
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
350 lastChoiceRow++;
8b4c49c92451 Add initial implementation that handles choices
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
351 }
38
5354cbda7188 Fix HTML Layout. Support multiple formats at once. More handling.
Andre Heinecke <andre.heinecke@intevation.de>
parents: 35
diff changeset
352 choiceMatch = choiceAltEx.match(input, cursor);
5354cbda7188 Fix HTML Layout. Support multiple formats at once. More handling.
Andre Heinecke <andre.heinecke@intevation.de>
parents: 35
diff changeset
353 bool additionalFound = false;
5354cbda7188 Fix HTML Layout. Support multiple formats at once. More handling.
Andre Heinecke <andre.heinecke@intevation.de>
parents: 35
diff changeset
354 while (choiceMatch.hasMatch() && choiceMatch.capturedStart() <= cursor + 1) {
5354cbda7188 Fix HTML Layout. Support multiple formats at once. More handling.
Andre Heinecke <andre.heinecke@intevation.de>
parents: 35
diff changeset
355 additionalFound = true;
65
defd29b9f25a Converter: Unescape IMG and Latex references
Andre Heinecke <andre.heinecke@intevation.de>
parents: 63
diff changeset
356 QString choice = choiceMatch.captured(1);
38
5354cbda7188 Fix HTML Layout. Support multiple formats at once. More handling.
Andre Heinecke <andre.heinecke@intevation.de>
parents: 35
diff changeset
357 cursor = choiceMatch.capturedEnd();
5354cbda7188 Fix HTML Layout. Support multiple formats at once. More handling.
Andre Heinecke <andre.heinecke@intevation.de>
parents: 35
diff changeset
358 /* Alternative answer that is just a list of strings */
70
3438f5cce8cc Force text codec for html to use UTF-8
Andre Heinecke <andre.heinecke@intevation.de>
parents: 69
diff changeset
359 qDebug() << "Captured unfilled choice: " << choice;
38
5354cbda7188 Fix HTML Layout. Support multiple formats at once. More handling.
Andre Heinecke <andre.heinecke@intevation.de>
parents: 35
diff changeset
360 html << mChoiceTextStyle.arg(choice.toHtmlEscaped());
5354cbda7188 Fix HTML Layout. Support multiple formats at once. More handling.
Andre Heinecke <andre.heinecke@intevation.de>
parents: 35
diff changeset
361 makeBar(html, 0, doc);
76
1e6e7699f0b8 Add replacements.ini to configure text replacements
Andre Heinecke <andre.heinecke@intevation.de>
parents: 75
diff changeset
362 xlsEscape(choice);
71
7e195eacb0da Acutally write unfilled choices in XLSX
Andre Heinecke <andre.heinecke@intevation.de>
parents: 70
diff changeset
363 xlsx.write(row, 1, choice);
39
41cd27a64365 Write empty columns for XSLX to avoid strange 0 formatting
Andre Heinecke <andre.heinecke@intevation.de>
parents: 35
diff changeset
364 xlsx.write(row, 2, QVariant());
38
5354cbda7188 Fix HTML Layout. Support multiple formats at once. More handling.
Andre Heinecke <andre.heinecke@intevation.de>
parents: 35
diff changeset
365 const QString numVotesString = QStringLiteral("Keine eingegangenen Antworten");
5354cbda7188 Fix HTML Layout. Support multiple formats at once. More handling.
Andre Heinecke <andre.heinecke@intevation.de>
parents: 35
diff changeset
366 html << mChoiceVotesStyle.arg(numVotesString.toHtmlEscaped());
5354cbda7188 Fix HTML Layout. Support multiple formats at once. More handling.
Andre Heinecke <andre.heinecke@intevation.de>
parents: 35
diff changeset
367 xlsx.write(row, 3, numVotesString, mChoiceVotesFmt);
5354cbda7188 Fix HTML Layout. Support multiple formats at once. More handling.
Andre Heinecke <andre.heinecke@intevation.de>
parents: 35
diff changeset
368 xlsx.setRowHeight(row, CHOICE_ROW_HEIGHT);
5354cbda7188 Fix HTML Layout. Support multiple formats at once. More handling.
Andre Heinecke <andre.heinecke@intevation.de>
parents: 35
diff changeset
369 row++;
5354cbda7188 Fix HTML Layout. Support multiple formats at once. More handling.
Andre Heinecke <andre.heinecke@intevation.de>
parents: 35
diff changeset
370 lastChoiceRow++;
5354cbda7188 Fix HTML Layout. Support multiple formats at once. More handling.
Andre Heinecke <andre.heinecke@intevation.de>
parents: 35
diff changeset
371 choiceMatch = choiceAltEx.match(input, cursor);
5354cbda7188 Fix HTML Layout. Support multiple formats at once. More handling.
Andre Heinecke <andre.heinecke@intevation.de>
parents: 35
diff changeset
372 QRegularExpressionMatch realMatch = choiceEx.match(input, cursor);
5354cbda7188 Fix HTML Layout. Support multiple formats at once. More handling.
Andre Heinecke <andre.heinecke@intevation.de>
parents: 35
diff changeset
373 if (choiceMatch.hasMatch() && choiceMatch.capturedStart() == realMatch.capturedStart()) {
5354cbda7188 Fix HTML Layout. Support multiple formats at once. More handling.
Andre Heinecke <andre.heinecke@intevation.de>
parents: 35
diff changeset
374 /* We have a real match so back to the other pattern. */
5354cbda7188 Fix HTML Layout. Support multiple formats at once. More handling.
Andre Heinecke <andre.heinecke@intevation.de>
parents: 35
diff changeset
375 break;
5354cbda7188 Fix HTML Layout. Support multiple formats at once. More handling.
Andre Heinecke <andre.heinecke@intevation.de>
parents: 35
diff changeset
376 }
5354cbda7188 Fix HTML Layout. Support multiple formats at once. More handling.
Andre Heinecke <andre.heinecke@intevation.de>
parents: 35
diff changeset
377 }
5354cbda7188 Fix HTML Layout. Support multiple formats at once. More handling.
Andre Heinecke <andre.heinecke@intevation.de>
parents: 35
diff changeset
378 if (additionalFound) {
5354cbda7188 Fix HTML Layout. Support multiple formats at once. More handling.
Andre Heinecke <andre.heinecke@intevation.de>
parents: 35
diff changeset
379 goto repeat;
5354cbda7188 Fix HTML Layout. Support multiple formats at once. More handling.
Andre Heinecke <andre.heinecke@intevation.de>
parents: 35
diff changeset
380 }
3
8b4c49c92451 Add initial implementation that handles choices
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
381 bars.addRange(QString("B%1:B%2").arg(firstChoiceRow).arg(lastChoiceRow));
13
101ee762f021 Add commented out Grouping
Andre Heinecke <andre.heinecke@intevation.de>
parents: 12
diff changeset
382 // xlsx.groupRows(firstChoiceRow - 2, lastChoiceRow - 1, false);
3
8b4c49c92451 Add initial implementation that handles choices
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
383 } else if (answerLine == QStringLiteral(TEXT_IDENTIFIER)) {
6
a10425e7ef98 Add free text handling
Andre Heinecke <andre.heinecke@intevation.de>
parents: 3
diff changeset
384 QRegularExpressionMatch textMatch = freetxtEx.match(input, cursor);
a10425e7ef98 Add free text handling
Andre Heinecke <andre.heinecke@intevation.de>
parents: 3
diff changeset
385 xlsx.setRowHeight(row, CHOICE_ROW_HEIGHT);
21
0b66b10a287d Add german translation
Andre Heinecke <andre.heinecke@intevation.de>
parents: 20
diff changeset
386 xlsx.write(row++, 1, "Answer", mAnswerTextFmt);
25
e5c5ebfa4205 Refactor to centralise html tags
Andre Heinecke <andre.heinecke@intevation.de>
parents: 23
diff changeset
387 html << mAnswerTextStyle;
23
927794e3cc52 Add HTML output and some pdf support
Andre Heinecke <andre.heinecke@intevation.de>
parents: 21
diff changeset
388
927794e3cc52 Add HTML output and some pdf support
Andre Heinecke <andre.heinecke@intevation.de>
parents: 21
diff changeset
389 /* To handle the workaround for quotes in answers we store
927794e3cc52 Add HTML output and some pdf support
Andre Heinecke <andre.heinecke@intevation.de>
parents: 21
diff changeset
390 * the number of rows and only afterwards create the html rows. */
927794e3cc52 Add HTML output and some pdf support
Andre Heinecke <andre.heinecke@intevation.de>
parents: 21
diff changeset
391 int firstFreeRow = row;
6
a10425e7ef98 Add free text handling
Andre Heinecke <andre.heinecke@intevation.de>
parents: 3
diff changeset
392 while (textMatch.hasMatch()) {
a10425e7ef98 Add free text handling
Andre Heinecke <andre.heinecke@intevation.de>
parents: 3
diff changeset
393 if (textMatch.capturedStart() != cursor + 1) {
a10425e7ef98 Add free text handling
Andre Heinecke <andre.heinecke@intevation.de>
parents: 3
diff changeset
394 /* The format allows unescaped quotes in the text.
a10425e7ef98 Add free text handling
Andre Heinecke <andre.heinecke@intevation.de>
parents: 3
diff changeset
395 This makes a workaround neccessary. If we have
a10425e7ef98 Add free text handling
Andre Heinecke <andre.heinecke@intevation.de>
parents: 3
diff changeset
396 an Unquoted string between the next quoted string
a10425e7ef98 Add free text handling
Andre Heinecke <andre.heinecke@intevation.de>
parents: 3
diff changeset
397 and that Unquoted string is before the next question
a10425e7ef98 Add free text handling
Andre Heinecke <andre.heinecke@intevation.de>
parents: 3
diff changeset
398 we append the unquoted string and the next quoted string
a10425e7ef98 Add free text handling
Andre Heinecke <andre.heinecke@intevation.de>
parents: 3
diff changeset
399 with Quotes in the Row.*/
a10425e7ef98 Add free text handling
Andre Heinecke <andre.heinecke@intevation.de>
parents: 3
diff changeset
400 QRegularExpressionMatch nextQuestion = questionEx.match(input, cursor);
a10425e7ef98 Add free text handling
Andre Heinecke <andre.heinecke@intevation.de>
parents: 3
diff changeset
401 if (nextQuestion.hasMatch() &&
a10425e7ef98 Add free text handling
Andre Heinecke <andre.heinecke@intevation.de>
parents: 3
diff changeset
402 nextQuestion.capturedStart() < textMatch.capturedEnd()) {
a10425e7ef98 Add free text handling
Andre Heinecke <andre.heinecke@intevation.de>
parents: 3
diff changeset
403 /* The next question comes before the textMatch so we really have
a10425e7ef98 Add free text handling
Andre Heinecke <andre.heinecke@intevation.de>
parents: 3
diff changeset
404 a new question. */
a10425e7ef98 Add free text handling
Andre Heinecke <andre.heinecke@intevation.de>
parents: 3
diff changeset
405 break;
a10425e7ef98 Add free text handling
Andre Heinecke <andre.heinecke@intevation.de>
parents: 3
diff changeset
406 }
a10425e7ef98 Add free text handling
Andre Heinecke <andre.heinecke@intevation.de>
parents: 3
diff changeset
407 const QString lastRow = xlsx.read(row - 1, 26).toString();
a10425e7ef98 Add free text handling
Andre Heinecke <andre.heinecke@intevation.de>
parents: 3
diff changeset
408 int unquotedLen = textMatch.capturedStart() - cursor;
a10425e7ef98 Add free text handling
Andre Heinecke <andre.heinecke@intevation.de>
parents: 3
diff changeset
409 const QString unquoted = input.mid(cursor, unquotedLen);
82
9e3c05a03a6f Check for double newline in unquoted strings
Andre Heinecke <andre.heinecke@intevation.de>
parents: 81
diff changeset
410 if (unquoted.startsWith("\n\n")) {
9e3c05a03a6f Check for double newline in unquoted strings
Andre Heinecke <andre.heinecke@intevation.de>
parents: 81
diff changeset
411 qDebug() << "Double newline outside quote. Assuming a question follows.";
9e3c05a03a6f Check for double newline in unquoted strings
Andre Heinecke <andre.heinecke@intevation.de>
parents: 81
diff changeset
412 break;
9e3c05a03a6f Check for double newline in unquoted strings
Andre Heinecke <andre.heinecke@intevation.de>
parents: 81
diff changeset
413 }
6
a10425e7ef98 Add free text handling
Andre Heinecke <andre.heinecke@intevation.de>
parents: 3
diff changeset
414 qDebug() << "Found inner quoted string: " << unquoted;
a10425e7ef98 Add free text handling
Andre Heinecke <andre.heinecke@intevation.de>
parents: 3
diff changeset
415 /* Now combine */
76
1e6e7699f0b8 Add replacements.ini to configure text replacements
Andre Heinecke <andre.heinecke@intevation.de>
parents: 75
diff changeset
416 QString combined = QString("%1\"%2\"%3").arg(lastRow).
1e6e7699f0b8 Add replacements.ini to configure text replacements
Andre Heinecke <andre.heinecke@intevation.de>
parents: 75
diff changeset
417 arg(unquoted).
1e6e7699f0b8 Add replacements.ini to configure text replacements
Andre Heinecke <andre.heinecke@intevation.de>
parents: 75
diff changeset
418 arg(textMatch.captured(1).trimmed());
6
a10425e7ef98 Add free text handling
Andre Heinecke <andre.heinecke@intevation.de>
parents: 3
diff changeset
419 qDebug() << "Last row: " << lastRow;
a10425e7ef98 Add free text handling
Andre Heinecke <andre.heinecke@intevation.de>
parents: 3
diff changeset
420 qDebug() << "Next Question is at: " << nextQuestion.capturedStart();
a10425e7ef98 Add free text handling
Andre Heinecke <andre.heinecke@intevation.de>
parents: 3
diff changeset
421 qDebug() << "Text match is: " << textMatch.captured(1).trimmed();
a10425e7ef98 Add free text handling
Andre Heinecke <andre.heinecke@intevation.de>
parents: 3
diff changeset
422 qDebug() << "cursor is at: " << cursor;
a10425e7ef98 Add free text handling
Andre Heinecke <andre.heinecke@intevation.de>
parents: 3
diff changeset
423 qDebug() << "text match starts at: " << textMatch.capturedStart();
76
1e6e7699f0b8 Add replacements.ini to configure text replacements
Andre Heinecke <andre.heinecke@intevation.de>
parents: 75
diff changeset
424 xlsEscape(combined);
6
a10425e7ef98 Add free text handling
Andre Heinecke <andre.heinecke@intevation.de>
parents: 3
diff changeset
425 xlsx.write(row - 1, 26, combined, mFreeTextFmt);
12
21f11f988115 Make sure strings don't start with = and duplicate text instead of formula
Andre Heinecke <andre.heinecke@intevation.de>
parents: 6
diff changeset
426 xlsx.write(row - 1, 1, combined, mFreeTextFmt);
6
a10425e7ef98 Add free text handling
Andre Heinecke <andre.heinecke@intevation.de>
parents: 3
diff changeset
427 cursor = textMatch.capturedEnd();
a10425e7ef98 Add free text handling
Andre Heinecke <andre.heinecke@intevation.de>
parents: 3
diff changeset
428 textMatch = freetxtEx.match(input, cursor);
a10425e7ef98 Add free text handling
Andre Heinecke <andre.heinecke@intevation.de>
parents: 3
diff changeset
429 continue;
a10425e7ef98 Add free text handling
Andre Heinecke <andre.heinecke@intevation.de>
parents: 3
diff changeset
430 }
a10425e7ef98 Add free text handling
Andre Heinecke <andre.heinecke@intevation.de>
parents: 3
diff changeset
431 cursor = textMatch.capturedEnd();
a10425e7ef98 Add free text handling
Andre Heinecke <andre.heinecke@intevation.de>
parents: 3
diff changeset
432
a10425e7ef98 Add free text handling
Andre Heinecke <andre.heinecke@intevation.de>
parents: 3
diff changeset
433 QString text = textMatch.captured(1).trimmed();
a10425e7ef98 Add free text handling
Andre Heinecke <andre.heinecke@intevation.de>
parents: 3
diff changeset
434 qDebug() << "Found free text: " << text;
12
21f11f988115 Make sure strings don't start with = and duplicate text instead of formula
Andre Heinecke <andre.heinecke@intevation.de>
parents: 6
diff changeset
435 if (text.startsWith("=")) {
21f11f988115 Make sure strings don't start with = and duplicate text instead of formula
Andre Heinecke <andre.heinecke@intevation.de>
parents: 6
diff changeset
436 text = " " + text;
21f11f988115 Make sure strings don't start with = and duplicate text instead of formula
Andre Heinecke <andre.heinecke@intevation.de>
parents: 6
diff changeset
437 }
6
a10425e7ef98 Add free text handling
Andre Heinecke <andre.heinecke@intevation.de>
parents: 3
diff changeset
438
a10425e7ef98 Add free text handling
Andre Heinecke <andre.heinecke@intevation.de>
parents: 3
diff changeset
439 /* Merge the cells */
a10425e7ef98 Add free text handling
Andre Heinecke <andre.heinecke@intevation.de>
parents: 3
diff changeset
440 xlsx.mergeCells(QString("A%1:C%1").arg(row), mFreeTextFmt);
a10425e7ef98 Add free text handling
Andre Heinecke <andre.heinecke@intevation.de>
parents: 3
diff changeset
441
a10425e7ef98 Add free text handling
Andre Heinecke <andre.heinecke@intevation.de>
parents: 3
diff changeset
442 /* Merged cells ignore wordwrap the following trick is based on:
a10425e7ef98 Add free text handling
Andre Heinecke <andre.heinecke@intevation.de>
parents: 3
diff changeset
443 http://excel.tips.net/T003207_Automatic_Row_Height_For_Merged_Cells_with_Text_Wrap.html
a10425e7ef98 Add free text handling
Andre Heinecke <andre.heinecke@intevation.de>
parents: 3
diff changeset
444 */
a10425e7ef98 Add free text handling
Andre Heinecke <andre.heinecke@intevation.de>
parents: 3
diff changeset
445 /* Write the values */
76
1e6e7699f0b8 Add replacements.ini to configure text replacements
Andre Heinecke <andre.heinecke@intevation.de>
parents: 75
diff changeset
446 xlsEscape(text);
6
a10425e7ef98 Add free text handling
Andre Heinecke <andre.heinecke@intevation.de>
parents: 3
diff changeset
447 xlsx.write(QString("Z%1").arg(row), text, mFreeTextFmt);
12
21f11f988115 Make sure strings don't start with = and duplicate text instead of formula
Andre Heinecke <andre.heinecke@intevation.de>
parents: 6
diff changeset
448 xlsx.write(row, 1, text, mFreeTextFmt);
6
a10425e7ef98 Add free text handling
Andre Heinecke <andre.heinecke@intevation.de>
parents: 3
diff changeset
449 row++;
23
927794e3cc52 Add HTML output and some pdf support
Andre Heinecke <andre.heinecke@intevation.de>
parents: 21
diff changeset
450
6
a10425e7ef98 Add free text handling
Andre Heinecke <andre.heinecke@intevation.de>
parents: 3
diff changeset
451 textMatch = freetxtEx.match(input, cursor);
a10425e7ef98 Add free text handling
Andre Heinecke <andre.heinecke@intevation.de>
parents: 3
diff changeset
452 }
23
927794e3cc52 Add HTML output and some pdf support
Andre Heinecke <andre.heinecke@intevation.de>
parents: 21
diff changeset
453 for (int i = firstFreeRow; i < row; i++) {
25
e5c5ebfa4205 Refactor to centralise html tags
Andre Heinecke <andre.heinecke@intevation.de>
parents: 23
diff changeset
454 html << mFreeTextStyle.arg(xlsx.read(i, 1).toString().toHtmlEscaped());
23
927794e3cc52 Add HTML output and some pdf support
Andre Heinecke <andre.heinecke@intevation.de>
parents: 21
diff changeset
455 }
3
8b4c49c92451 Add initial implementation that handles choices
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
456 }
8b4c49c92451 Add initial implementation that handles choices
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
457 /* Insert Empty row. */
8b4c49c92451 Add initial implementation that handles choices
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
458 xlsx.setRowHeight(row++, CHOICE_ROW_HEIGHT);
8b4c49c92451 Add initial implementation that handles choices
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
459 match = questionEx.match(input, cursor);
8b4c49c92451 Add initial implementation that handles choices
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
460 cursor = match.capturedEnd();
25
e5c5ebfa4205 Refactor to centralise html tags
Andre Heinecke <andre.heinecke@intevation.de>
parents: 23
diff changeset
461 html << mEmptyRow;
3
8b4c49c92451 Add initial implementation that handles choices
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
462 }
8b4c49c92451 Add initial implementation that handles choices
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
463 xlsx.addConditionalFormatting(bars);
8b4c49c92451 Add initial implementation that handles choices
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
464
8b4c49c92451 Add initial implementation that handles choices
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
465 if (!foundSomething) {
8b4c49c92451 Add initial implementation that handles choices
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
466 mErrors << tr("Failed to parse input document.");
8b4c49c92451 Add initial implementation that handles choices
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
467 }
8b4c49c92451 Add initial implementation that handles choices
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
468
23
927794e3cc52 Add HTML output and some pdf support
Andre Heinecke <andre.heinecke@intevation.de>
parents: 21
diff changeset
469 html << "</table></body></html>";
38
5354cbda7188 Fix HTML Layout. Support multiple formats at once. More handling.
Andre Heinecke <andre.heinecke@intevation.de>
parents: 35
diff changeset
470 doc.setHtml(htmlString);
23
927794e3cc52 Add HTML output and some pdf support
Andre Heinecke <andre.heinecke@intevation.de>
parents: 21
diff changeset
471
38
5354cbda7188 Fix HTML Layout. Support multiple formats at once. More handling.
Andre Heinecke <andre.heinecke@intevation.de>
parents: 35
diff changeset
472 /* Fixup images for html */
5354cbda7188 Fix HTML Layout. Support multiple formats at once. More handling.
Andre Heinecke <andre.heinecke@intevation.de>
parents: 35
diff changeset
473 QRegularExpression htmlRe = QRegularExpression("<td style='vertical-align: middle'><img src=\"internal://bar(\\d+).png\"/></td>");
5354cbda7188 Fix HTML Layout. Support multiple formats at once. More handling.
Andre Heinecke <andre.heinecke@intevation.de>
parents: 35
diff changeset
474 htmlString.replace(htmlRe, QStringLiteral("<td style='background:linear-gradient(to right,"
5354cbda7188 Fix HTML Layout. Support multiple formats at once. More handling.
Andre Heinecke <andre.heinecke@intevation.de>
parents: 35
diff changeset
475 BAR_COLOR ", " BAR_COLOR " \\1%, #ffffff \\1%)'></td>"));
5354cbda7188 Fix HTML Layout. Support multiple formats at once. More handling.
Andre Heinecke <andre.heinecke@intevation.de>
parents: 35
diff changeset
476
5354cbda7188 Fix HTML Layout. Support multiple formats at once. More handling.
Andre Heinecke <andre.heinecke@intevation.de>
parents: 35
diff changeset
477 foreach (QFile *output, outputs) {
5354cbda7188 Fix HTML Layout. Support multiple formats at once. More handling.
Andre Heinecke <andre.heinecke@intevation.de>
parents: 35
diff changeset
478 const QString fName = output->fileName().toLower();
5354cbda7188 Fix HTML Layout. Support multiple formats at once. More handling.
Andre Heinecke <andre.heinecke@intevation.de>
parents: 35
diff changeset
479 if (fName.endsWith(".html")) {
5354cbda7188 Fix HTML Layout. Support multiple formats at once. More handling.
Andre Heinecke <andre.heinecke@intevation.de>
parents: 35
diff changeset
480 QTextStream outstream(output);
70
3438f5cce8cc Force text codec for html to use UTF-8
Andre Heinecke <andre.heinecke@intevation.de>
parents: 69
diff changeset
481 outstream.setCodec("UTF-8");
38
5354cbda7188 Fix HTML Layout. Support multiple formats at once. More handling.
Andre Heinecke <andre.heinecke@intevation.de>
parents: 35
diff changeset
482 outstream << htmlString;
5354cbda7188 Fix HTML Layout. Support multiple formats at once. More handling.
Andre Heinecke <andre.heinecke@intevation.de>
parents: 35
diff changeset
483 output->close();
5354cbda7188 Fix HTML Layout. Support multiple formats at once. More handling.
Andre Heinecke <andre.heinecke@intevation.de>
parents: 35
diff changeset
484 } else if (fName.endsWith(".pdf")) {
5354cbda7188 Fix HTML Layout. Support multiple formats at once. More handling.
Andre Heinecke <andre.heinecke@intevation.de>
parents: 35
diff changeset
485 output->close();
5354cbda7188 Fix HTML Layout. Support multiple formats at once. More handling.
Andre Heinecke <andre.heinecke@intevation.de>
parents: 35
diff changeset
486 QPrinter printer(QPrinter::PrinterResolution);
5354cbda7188 Fix HTML Layout. Support multiple formats at once. More handling.
Andre Heinecke <andre.heinecke@intevation.de>
parents: 35
diff changeset
487 printer.setOutputFormat(QPrinter::PdfFormat);
5354cbda7188 Fix HTML Layout. Support multiple formats at once. More handling.
Andre Heinecke <andre.heinecke@intevation.de>
parents: 35
diff changeset
488 printer.setPaperSize(QPrinter::A4);
5354cbda7188 Fix HTML Layout. Support multiple formats at once. More handling.
Andre Heinecke <andre.heinecke@intevation.de>
parents: 35
diff changeset
489 printer.setOutputFileName(output->fileName());
5354cbda7188 Fix HTML Layout. Support multiple formats at once. More handling.
Andre Heinecke <andre.heinecke@intevation.de>
parents: 35
diff changeset
490 /*
5354cbda7188 Fix HTML Layout. Support multiple formats at once. More handling.
Andre Heinecke <andre.heinecke@intevation.de>
parents: 35
diff changeset
491 QPageLayout layout = printer.pageLayout();
5354cbda7188 Fix HTML Layout. Support multiple formats at once. More handling.
Andre Heinecke <andre.heinecke@intevation.de>
parents: 35
diff changeset
492 layout.setUnits(QPageLayout::Millimeter);
5354cbda7188 Fix HTML Layout. Support multiple formats at once. More handling.
Andre Heinecke <andre.heinecke@intevation.de>
parents: 35
diff changeset
493 layout.setMargins(QMarginsF(20, 20, 20, 20));
5354cbda7188 Fix HTML Layout. Support multiple formats at once. More handling.
Andre Heinecke <andre.heinecke@intevation.de>
parents: 35
diff changeset
494 printer.setPageLayout(layout);
5354cbda7188 Fix HTML Layout. Support multiple formats at once. More handling.
Andre Heinecke <andre.heinecke@intevation.de>
parents: 35
diff changeset
495 doc.setPageSize(printer.pageRect().size());
5354cbda7188 Fix HTML Layout. Support multiple formats at once. More handling.
Andre Heinecke <andre.heinecke@intevation.de>
parents: 35
diff changeset
496 */
5354cbda7188 Fix HTML Layout. Support multiple formats at once. More handling.
Andre Heinecke <andre.heinecke@intevation.de>
parents: 35
diff changeset
497 doc.print(&printer);
5354cbda7188 Fix HTML Layout. Support multiple formats at once. More handling.
Andre Heinecke <andre.heinecke@intevation.de>
parents: 35
diff changeset
498 } else {
5354cbda7188 Fix HTML Layout. Support multiple formats at once. More handling.
Andre Heinecke <andre.heinecke@intevation.de>
parents: 35
diff changeset
499 if (!xlsx.saveAs(output)) {
5354cbda7188 Fix HTML Layout. Support multiple formats at once. More handling.
Andre Heinecke <andre.heinecke@intevation.de>
parents: 35
diff changeset
500 mErrors << tr("Saving the XLSX document failed.");
5354cbda7188 Fix HTML Layout. Support multiple formats at once. More handling.
Andre Heinecke <andre.heinecke@intevation.de>
parents: 35
diff changeset
501 }
5354cbda7188 Fix HTML Layout. Support multiple formats at once. More handling.
Andre Heinecke <andre.heinecke@intevation.de>
parents: 35
diff changeset
502 output->close();
5354cbda7188 Fix HTML Layout. Support multiple formats at once. More handling.
Andre Heinecke <andre.heinecke@intevation.de>
parents: 35
diff changeset
503 }
23
927794e3cc52 Add HTML output and some pdf support
Andre Heinecke <andre.heinecke@intevation.de>
parents: 21
diff changeset
504 }
3
8b4c49c92451 Add initial implementation that handles choices
Andre Heinecke <andre.heinecke@intevation.de>
parents:
diff changeset
505 }
This site is hosted by Intevation GmbH (Datenschutzerklärung und Impressum | Privacy Policy and Imprint)