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();
}
This site is hosted by Intevation GmbH (Datenschutzerklärung und Impressum | Privacy Policy and Imprint)