Mercurial > clickerconvert
comparison src/mainwindow.cpp @ 50:36ee5dd46fd3
Add GUI
New Mainwindow that allows to set output formats and input
files through a GUI.
author | Andre Heinecke <andre.heinecke@intevation.de> |
---|---|
date | Tue, 19 Jul 2016 12:19:45 +0200 |
parents | |
children | a43d8cf2fa95 |
comparison
equal
deleted
inserted
replaced
49:a849b1de248f | 50:36ee5dd46fd3 |
---|---|
1 /* Copyright (C) 2016 by ETH Zürich | |
2 * Software engineering by Intevation GmbH | |
3 * | |
4 * This file is Free Software under the GNU GPL (v>=2) | |
5 * and comes with ABSOLUTELY NO WARRANTY! | |
6 * See LICENSE.txt for details. | |
7 */ | |
8 | |
9 /** @file See mainwindow.h */ | |
10 #include "mainwindow.h" | |
11 | |
12 #include "constants.h" | |
13 #include "converter.h" | |
14 #include "filenamerequester.h" | |
15 | |
16 #include <QApplication> | |
17 #include <QCheckBox> | |
18 #include <QDebug> | |
19 #include <QDialogButtonBox> | |
20 #include <QDesktopServices> | |
21 #include <QDir> | |
22 #include <QGroupBox> | |
23 #include <QHBoxLayout> | |
24 #include <QLabel> | |
25 #include <QLineEdit> | |
26 #include <QMessageBox> | |
27 #include <QMimeData> | |
28 #include <QPushButton> | |
29 #include <QUrl> | |
30 #include <QStandardPaths> | |
31 #include <QStyle> | |
32 #include <QVBoxLayout> | |
33 #include <QWidget> | |
34 #include <QGridLayout> | |
35 | |
36 MainWindow::MainWindow() { | |
37 setupGUI(); | |
38 readSettings(); | |
39 #ifndef Q_OS_WIN | |
40 QIcon windowIcon = QIcon(ICON_NAME); | |
41 setWindowIcon(windowIcon); | |
42 setWindowTitle(QStringLiteral(APPNAME)); | |
43 #endif | |
44 } | |
45 | |
46 void MainWindow::setupGUI() { | |
47 auto vLay = new QVBoxLayout; | |
48 auto inoutLay = new QGridLayout; | |
49 auto inputLabel = new QLabel(tr("Input File:")); | |
50 inoutLay->addWidget(inputLabel, 0, 0); | |
51 mInputRequester = new FileNameRequester(QDir::Files); | |
52 mInputRequester->setExistingOnly(true); | |
53 inputLabel->setBuddy(mInputRequester); | |
54 | |
55 inoutLay->addWidget(mInputRequester, 0, 1); | |
56 | |
57 auto outLabel = new QLabel(tr("Export Folder:")); | |
58 inoutLay->addWidget(outLabel, 1, 0); | |
59 mOutRequester = new FileNameRequester(QDir::Dirs); | |
60 mOutRequester->setExistingOnly(false); | |
61 inoutLay->addWidget(mOutRequester, 1, 1); | |
62 outLabel->setBuddy(mOutRequester); | |
63 | |
64 vLay->addLayout(inoutLay); | |
65 | |
66 auto optionsGrp = new QGroupBox("Export Options:"); | |
67 auto optionsLay = new QVBoxLayout; | |
68 mPdfChk = new QCheckBox(tr("PDF")); | |
69 mPdfChk->setToolTip(tr("Convert into PDF Format.")); | |
70 mHtmlChk = new QCheckBox(tr("HTML")); | |
71 mHtmlChk->setToolTip(tr("Convert into HTML Format.")); | |
72 mXlsxChk = new QCheckBox(tr("XLSX")); | |
73 mXlsxChk->setToolTip(tr("Convert into XLSX Format.")); | |
74 | |
75 optionsLay->addWidget(mPdfChk); | |
76 optionsLay->addWidget(mHtmlChk); | |
77 optionsLay->addWidget(mXlsxChk); | |
78 optionsGrp->setLayout(optionsLay); | |
79 vLay->addWidget(optionsGrp); | |
80 | |
81 mTitleEdit = new QLineEdit; | |
82 auto titleLay = new QHBoxLayout; | |
83 auto titleLabel = new QLabel(QStringLiteral("<small>") + tr("mandatory") + | |
84 QStringLiteral("</small>")); | |
85 mTitleEdit->setPlaceholderText(tr("Title (e.g. Feedback Questions SS2016)")); | |
86 titleLay->addWidget(mTitleEdit); | |
87 titleLay->addWidget(titleLabel); | |
88 vLay->addLayout(titleLay); | |
89 vLay->addStretch(1); | |
90 auto btns = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Close); | |
91 mConvertBtn = btns->button(QDialogButtonBox::Ok); | |
92 mConvertBtn->setText(tr("Convert")); | |
93 vLay->addWidget(btns); | |
94 | |
95 auto widget = new QWidget; | |
96 widget->setLayout(vLay); | |
97 setCentralWidget(widget); | |
98 checkCompleted(); | |
99 | |
100 connect(mConvertBtn, &QPushButton::clicked, this, &MainWindow::doConvert); | |
101 connect(mPdfChk, &QCheckBox::stateChanged, this, &MainWindow::checkCompleted); | |
102 connect(mHtmlChk, &QCheckBox::stateChanged, this, &MainWindow::checkCompleted); | |
103 connect(mXlsxChk, &QCheckBox::stateChanged, this, &MainWindow::checkCompleted); | |
104 connect(mTitleEdit, &QLineEdit::textChanged, this, &MainWindow::checkCompleted); | |
105 connect(mInputRequester, &FileNameRequester::fileNameChanged, this, &MainWindow::checkCompleted); | |
106 connect(mOutRequester, &FileNameRequester::fileNameChanged, this, &MainWindow::checkCompleted); | |
107 } | |
108 | |
109 void MainWindow::showErrorMessage(const QString& errMsg) { | |
110 QMessageBox::warning(this, tr("Error!"), errMsg); | |
111 } | |
112 | |
113 void MainWindow::closeEvent(QCloseEvent *event) { | |
114 mSettings.setValue("geometry", saveGeometry()); | |
115 mSettings.setValue("windowState", saveState()); | |
116 QMainWindow::closeEvent(event); | |
117 } | |
118 | |
119 void MainWindow::readSettings() { | |
120 if (mSettings.contains("geometry")) { | |
121 restoreGeometry(mSettings.value("geometry").toByteArray()); | |
122 restoreState(mSettings.value("windowState").toByteArray()); | |
123 } | |
124 | |
125 setInputFile(mSettings.value("lastInput", | |
126 QStandardPaths::writableLocation(DEFAULT_DIR)).toString()); | |
127 mOutRequester->setFileName(mSettings.value("lastOutput", | |
128 QStandardPaths::writableLocation(DEFAULT_DIR)).toString()); | |
129 | |
130 mPdfChk->setChecked(mSettings.value("pdfChk", true).toBool()); | |
131 mHtmlChk->setChecked(mSettings.value("htmlChk", false).toBool()); | |
132 mXlsxChk->setChecked(mSettings.value("xlsxChk", false).toBool()); | |
133 } | |
134 | |
135 void MainWindow::setInputFile(const QString& file) | |
136 { | |
137 mInputRequester->setFileName(file); | |
138 } | |
139 | |
140 void MainWindow::setTitle(const QString& title) { | |
141 mTitleEdit->setText(title); | |
142 } | |
143 | |
144 void MainWindow::checkCompleted() { | |
145 if (!mTitleEdit->text().isEmpty() && | |
146 (mPdfChk->isChecked() || mXlsxChk->isChecked() || mHtmlChk->isChecked())) { | |
147 mConvertBtn->setEnabled(true); | |
148 } else { | |
149 mConvertBtn->setEnabled(false); | |
150 } | |
151 } | |
152 | |
153 void MainWindow::doConvert() { | |
154 /* Construct output names */ | |
155 QStringList outNames; | |
156 | |
157 QDir outDir(mOutRequester->fileName()); | |
158 if (!outDir.exists() && !outDir.mkpath(mOutRequester->fileName())) { | |
159 showErrorMessage(tr("Failed to create output directory.")); | |
160 return; | |
161 } | |
162 | |
163 const QFileInfo fi(mInputRequester->fileName()); | |
164 if (!fi.exists() || !fi.isReadable()) { | |
165 showErrorMessage(tr("Failed to open \"%1\" for reading.").arg(mInputRequester->fileName())); | |
166 return; | |
167 } | |
168 if (mPdfChk->isChecked()) { | |
169 outNames << outDir.absoluteFilePath(fi.baseName() + QStringLiteral(".pdf")); | |
170 } | |
171 if (mHtmlChk->isChecked()) { | |
172 outNames << outDir.absoluteFilePath(fi.baseName() + QStringLiteral(".html")); | |
173 } | |
174 if (mXlsxChk->isChecked()) { | |
175 outNames << outDir.absoluteFilePath(fi.baseName() + QStringLiteral(".xslx")); | |
176 } | |
177 | |
178 QStringList cleanedNames; | |
179 foreach (const QString &name, outNames) { | |
180 const QFileInfo fi2(name); | |
181 if (!fi2.exists()) { | |
182 cleanedNames << name; | |
183 continue; | |
184 } | |
185 /* File exists. Lets try a number. */ | |
186 bool replacementFound = false; | |
187 for (int i = 1; i < MAX_FILENAME_COUNT; i++) { | |
188 const QString newName = outDir.absoluteFilePath(QStringLiteral("%1_%2.%3").arg( | |
189 fi2.baseName()).arg(i).arg(fi2.suffix())); | |
190 const QFileInfo fi3(newName); | |
191 if (!fi3.exists()) { | |
192 qDebug() << "Using " << newName << " as replacement because other files exist."; | |
193 cleanedNames << newName; | |
194 replacementFound = true; | |
195 break; | |
196 } | |
197 } | |
198 if (!replacementFound) { | |
199 showErrorMessage(tr("Failed to find an available free name for \"%1\" please choose another folder.").arg(name)); | |
200 return; | |
201 } | |
202 } | |
203 | |
204 mSettings.setValue("lastInput", mInputRequester->fileName()); | |
205 mSettings.setValue("lastOutput", mOutRequester->fileName()); | |
206 mSettings.setValue("pdfChk", mPdfChk->isChecked()); | |
207 mSettings.setValue("xlsxChk", mXlsxChk->isChecked()); | |
208 mSettings.setValue("htmlChk", mHtmlChk->isChecked()); | |
209 | |
210 /* Convert away */ | |
211 Converter conv(mInputRequester->fileName(), cleanedNames, mTitleEdit->text()); | |
212 | |
213 conv.start(); | |
214 hide(); | |
215 qDebug() << "Waiting for conversion."; | |
216 conv.wait(); | |
217 qDebug() << "Conversion done."; | |
218 const QStringList errors = conv.errors(); | |
219 if (!errors.isEmpty()) { | |
220 Q_FOREACH (const QString err, errors) { | |
221 showErrorMessage(err); | |
222 } | |
223 } | |
224 | |
225 if (cleanedNames.size() == 1) { | |
226 qDebug() << "Opening: " << QUrl(QStringLiteral("file:///%1").arg(cleanedNames[0]), QUrl::TolerantMode); | |
227 QDesktopServices::openUrl(QUrl(QStringLiteral("file:///%1").arg(cleanedNames[0]), QUrl::TolerantMode)); | |
228 } else { | |
229 qDebug() << "Opening: " << QUrl(QStringLiteral("file:///%1").arg(outDir.path()), QUrl::TolerantMode); | |
230 QDesktopServices::openUrl(QUrl(QStringLiteral("file:///%1").arg(outDir.path()), QUrl::TolerantMode)); | |
231 } | |
232 | |
233 close(); | |
234 } |