Mercurial > clickerconvert
view src/mainwindow.cpp @ 56:5410f9f279ea
Redefine question pattern to be more robust
We now assume that a question begins after two empty lines.
author | Andre Heinecke <andre.heinecke@intevation.de> |
---|---|
date | Tue, 09 Aug 2016 09:59:16 +0200 |
parents | a43d8cf2fa95 |
children | 82d38421fdf3 |
line wrap: on
line source
/* Copyright (C) 2016 by ETH Zürich * Software engineering by Intevation GmbH * * This file is Free Software under the GNU GPL (v>=2) * and comes with ABSOLUTELY NO WARRANTY! * See LICENSE.txt for details. */ /** @file See mainwindow.h */ #include "mainwindow.h" #include "constants.h" #include "converter.h" #include "filenamerequester.h" #include <QApplication> #include <QCheckBox> #include <QDebug> #include <QDialogButtonBox> #include <QDesktopServices> #include <QDir> #include <QGroupBox> #include <QHBoxLayout> #include <QLabel> #include <QLineEdit> #include <QMessageBox> #include <QMimeData> #include <QPushButton> #include <QUrl> #include <QStandardPaths> #include <QStyle> #include <QVBoxLayout> #include <QWidget> #include <QGridLayout> MainWindow::MainWindow() { setupGUI(); readSettings(); #ifndef Q_OS_WIN QIcon windowIcon = QIcon(ICON_NAME); setWindowIcon(windowIcon); setWindowTitle(QStringLiteral(APPNAME)); #endif } void MainWindow::setupGUI() { auto vLay = new QVBoxLayout; auto inoutLay = new QGridLayout; auto inputLabel = new QLabel(tr("Input File:")); inoutLay->addWidget(inputLabel, 0, 0); mInputRequester = new FileNameRequester(QDir::Files); mInputRequester->setExistingOnly(true); inputLabel->setBuddy(mInputRequester); setWindowTitle(QStringLiteral(PRETTY_NAME)); inoutLay->addWidget(mInputRequester, 0, 1); auto outLabel = new QLabel(tr("Export Folder:")); inoutLay->addWidget(outLabel, 1, 0); mOutRequester = new FileNameRequester(QDir::Dirs); mOutRequester->setExistingOnly(false); inoutLay->addWidget(mOutRequester, 1, 1); outLabel->setBuddy(mOutRequester); vLay->addLayout(inoutLay); auto optionsGrp = new QGroupBox("Export Options:"); auto optionsLay = new QVBoxLayout; mPdfChk = new QCheckBox(tr("PDF")); mPdfChk->setToolTip(tr("Convert into PDF Format.")); mHtmlChk = new QCheckBox(tr("HTML")); mHtmlChk->setToolTip(tr("Convert into HTML Format.")); mXlsxChk = new QCheckBox(tr("XLSX")); mXlsxChk->setToolTip(tr("Convert into XLSX Format.")); optionsLay->addWidget(mPdfChk); optionsLay->addWidget(mHtmlChk); optionsLay->addWidget(mXlsxChk); optionsGrp->setLayout(optionsLay); vLay->addWidget(optionsGrp); mTitleEdit = new QLineEdit; auto titleLay = new QHBoxLayout; auto titleLabel = new QLabel(QStringLiteral("<small>") + tr("mandatory") + QStringLiteral("</small>")); mTitleEdit->setPlaceholderText(tr("Title (e.g. Feedback Questions SS2016)")); titleLay->addWidget(mTitleEdit); titleLay->addWidget(titleLabel); vLay->addLayout(titleLay); vLay->addStretch(1); auto btns = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Close); mConvertBtn = btns->button(QDialogButtonBox::Ok); mConvertBtn->setText(tr("Convert")); vLay->addWidget(btns); auto widget = new QWidget; widget->setLayout(vLay); setCentralWidget(widget); checkCompleted(); connect(mConvertBtn, &QPushButton::clicked, this, &MainWindow::doConvert); connect(mPdfChk, &QCheckBox::stateChanged, this, &MainWindow::checkCompleted); connect(mHtmlChk, &QCheckBox::stateChanged, this, &MainWindow::checkCompleted); connect(mXlsxChk, &QCheckBox::stateChanged, this, &MainWindow::checkCompleted); connect(mTitleEdit, &QLineEdit::textChanged, this, &MainWindow::checkCompleted); connect(mInputRequester, &FileNameRequester::fileNameChanged, this, &MainWindow::checkCompleted); connect(mOutRequester, &FileNameRequester::fileNameChanged, this, &MainWindow::checkCompleted); connect(btns, &QDialogButtonBox::rejected, this, &QMainWindow::close); } void MainWindow::showErrorMessage(const QString& errMsg) { QMessageBox::warning(this, tr("Error!"), errMsg); } void MainWindow::closeEvent(QCloseEvent *event) { mSettings.setValue("geometry", saveGeometry()); mSettings.setValue("windowState", saveState()); QMainWindow::closeEvent(event); } void MainWindow::readSettings() { if (mSettings.contains("geometry")) { restoreGeometry(mSettings.value("geometry").toByteArray()); restoreState(mSettings.value("windowState").toByteArray()); } else { resize(480, 360); } setInputFile(mSettings.value("lastInput", QStandardPaths::writableLocation(DEFAULT_DIR)).toString()); mOutRequester->setFileName(mSettings.value("lastOutput", QStandardPaths::writableLocation(DEFAULT_DIR)).toString()); mPdfChk->setChecked(mSettings.value("pdfChk", true).toBool()); mHtmlChk->setChecked(mSettings.value("htmlChk", false).toBool()); mXlsxChk->setChecked(mSettings.value("xlsxChk", false).toBool()); } void MainWindow::setInputFile(const QString& file) { mInputRequester->setFileName(file); QFileInfo fi(file); mOutRequester->setFileName(fi.dir().path()); } void MainWindow::setTitle(const QString& title) { mTitleEdit->setText(title); } void MainWindow::checkCompleted() { if (!mTitleEdit->text().isEmpty() && (mPdfChk->isChecked() || mXlsxChk->isChecked() || mHtmlChk->isChecked())) { mConvertBtn->setEnabled(true); } else { mConvertBtn->setEnabled(false); } } void MainWindow::doConvert() { /* Construct output names */ QStringList outNames; QDir outDir(mOutRequester->fileName()); if (!outDir.exists() && !outDir.mkpath(mOutRequester->fileName())) { showErrorMessage(tr("Failed to create output directory.")); return; } const QFileInfo fi(mInputRequester->fileName()); if (!fi.exists() || !fi.isReadable()) { showErrorMessage(tr("Failed to open \"%1\" for reading.").arg(mInputRequester->fileName())); return; } if (mPdfChk->isChecked()) { outNames << outDir.absoluteFilePath(fi.baseName() + QStringLiteral(".pdf")); } if (mHtmlChk->isChecked()) { outNames << outDir.absoluteFilePath(fi.baseName() + QStringLiteral(".html")); } if (mXlsxChk->isChecked()) { outNames << outDir.absoluteFilePath(fi.baseName() + QStringLiteral(".xslx")); } QStringList cleanedNames; foreach (const QString &name, outNames) { const QFileInfo fi2(name); if (!fi2.exists()) { cleanedNames << name; continue; } /* File exists. Lets try a number. */ bool replacementFound = false; for (int i = 1; i < MAX_FILENAME_COUNT; i++) { const QString newName = outDir.absoluteFilePath(QStringLiteral("%1_%2.%3").arg( fi2.baseName()).arg(i).arg(fi2.suffix())); const QFileInfo fi3(newName); if (!fi3.exists()) { qDebug() << "Using " << newName << " as replacement because other files exist."; cleanedNames << newName; replacementFound = true; break; } } if (!replacementFound) { showErrorMessage(tr("Failed to find an available free name for \"%1\" please choose another folder.").arg(name)); return; } } mSettings.setValue("lastInput", mInputRequester->fileName()); mSettings.setValue("lastOutput", mOutRequester->fileName()); mSettings.setValue("pdfChk", mPdfChk->isChecked()); mSettings.setValue("xlsxChk", mXlsxChk->isChecked()); mSettings.setValue("htmlChk", mHtmlChk->isChecked()); /* Convert away */ Converter conv(mInputRequester->fileName(), cleanedNames, mTitleEdit->text()); conv.start(); hide(); qDebug() << "Waiting for conversion."; conv.wait(); qDebug() << "Conversion done."; const QStringList errors = conv.errors(); if (!errors.isEmpty()) { Q_FOREACH (const QString err, errors) { showErrorMessage(err); } } if (cleanedNames.size() == 1) { qDebug() << "Opening: " << QUrl(QStringLiteral("file:///%1").arg(cleanedNames[0]), QUrl::TolerantMode); QDesktopServices::openUrl(QUrl(QStringLiteral("file:///%1").arg(cleanedNames[0]), QUrl::TolerantMode)); } else { qDebug() << "Opening: " << QUrl(QStringLiteral("file:///%1").arg(outDir.path()), QUrl::TolerantMode); QDesktopServices::openUrl(QUrl(QStringLiteral("file:///%1").arg(outDir.path()), QUrl::TolerantMode)); } close(); }