view ui/listupdatedialog.cpp @ 285:f23e0ccd5d14

Fix call to windows process. This now uses the correct parameters, emits the signals correctly as errors and waits for the process to finish instead of relying on NOASYNC which did not work for runas and also made it impossible to get the return code
author Andre Heinecke <aheinecke@intevation.de>
date Wed, 02 Apr 2014 13:45:57 +0000
parents 06089ba2614a
children
line wrap: on
line source
#include "listupdatedialog.h"
#include <QCoreApplication>
#include <QDebug>
#include <QDir>
#include <QFileInfo>
#include <QProcess>
#include <QPushButton>
#include <QGroupBox>
#include <QHBoxLayout>
#include <QListWidget>
#include <QVBoxLayout>
#include <QLabel>
#include <QMessageBox>


#include "certificate.h"
#include "installwrapper.h"

ListUpdateDialog::ListUpdateDialog(QMainWindow *parent,
                                   const CertificateList &listToInstall) :
    QDialog(parent),
    mCertificateList(listToInstall)
{
    setupGUI();
}

void ListUpdateDialog::setupGUI()
{
    /* Top level layout / widgets */
    QVBoxLayout *topLayout = new QVBoxLayout;
    QHBoxLayout *headerLayout = new QHBoxLayout;
    QHBoxLayout *listLayout = new QHBoxLayout;
    QHBoxLayout *bottomLayout = new QHBoxLayout;

    QImage *logoImage = new QImage(":/img/logo-small.png");
    QLabel *logo = new QLabel;
    logo->setBackgroundRole(QPalette::Base);
    logo->setPixmap(QPixmap::fromImage(*logoImage));
    QLabel *title = new QLabel("<h3>" + tr("Update Certificate") + "</h3>");
    headerLayout->addWidget(logo);
    headerLayout->addWidget(title);
    headerLayout->setStretch(0, 0);
    headerLayout->setStretch(1, 10);

    QPushButton *executeUpdate = new QPushButton(tr("Update Stores"));
    connect(executeUpdate, &QPushButton::clicked,
            this, &ListUpdateDialog::executeUpdate);
    QPushButton *install = new QPushButton(tr("Install selected"));
    QPushButton *later = new QPushButton(tr("Remind me later"));
    bottomLayout->insertStretch(0, 10);
    bottomLayout->addWidget(executeUpdate);
    bottomLayout->addWidget(install);
    bottomLayout->addWidget(later);

    /* The certificate groups */
    mCertListWidget = new QListWidget;
    connect(mCertListWidget, SIGNAL(itemClicked(QListWidgetItem*)),
        this, SLOT(showDetails(QListWidgetItem*)));
    mDetailWidget = new QTextEdit;
    mDetailWidget->setReadOnly(true);
    listLayout->addWidget(mCertListWidget);
    listLayout->addWidget(mDetailWidget);
    QGroupBox *certGroup = new QGroupBox(tr("Select certificates"));
    certGroup->setLayout(listLayout);

    foreach (const Certificate& cert, mCertificateList.getCertificates()) {
        if (!cert.isValid()) {
            qWarning() << "Invalid certificate in list";
            continue;
        }
        QListWidgetItem* item = new QListWidgetItem(cert.shortDescription());
        item->setFlags(item->flags() | Qt::ItemIsUserCheckable);
        item->setData(Qt::ToolTipRole, cert.details());
        item->setData(Qt::UserRole, cert.base64Line());
        item->setCheckState(Qt::Checked);
        QIcon *certIcon = cert.isInstallCert() ? new QIcon(":/img/list-add.png") :
                                                 new QIcon(":/img/list-remove.png");
        item->setIcon(*certIcon);

        mCertListWidget->addItem(item);
    }

    /* Fill top level layout */
    topLayout->addLayout(headerLayout);
    topLayout->addWidget(certGroup);
    topLayout->addLayout(bottomLayout);

    setLayout(topLayout);

    return;
}

void ListUpdateDialog::installerError(const QString& errMsg) {
    QMessageBox::warning(this, tr("Installation Error"), errMsg);
}

void ListUpdateDialog::executeUpdate() {

    QStringList instructions;

    for (int i = 0; i < mCertListWidget->count(); i++) {
        QListWidgetItem *item = mCertListWidget->item(i);
        if (item->checkState() == Qt::Checked) {
            instructions << item->data(Qt::UserRole).toString();
        }

        /* TODO: Check if it was an install instruction for an old certificate
         * (already installed) and remove it in case it is unchecked. */
    }

    InstallWrapper *instWrap = new InstallWrapper(this,
                                                  mCertificateList.fileName(),
                                                  instructions);
    connect(instWrap, SIGNAL(finished()), instWrap, SLOT(deleteLater()));
    connect(instWrap, SIGNAL(error(const QString &)),
        this, SLOT(installerError(const QString &)));
    instWrap->start();

#if 0
    /* TODO move this in another dialog and call it async*/
    QProcess installerProcess;
    QFileInfo fi(QCoreApplication::applicationFilePath());
    QDir myDir = fi.absoluteDir();
    QString instProcName = "cinst";
    if (!fi.suffix().isEmpty()) {
        instProcName += "." + fi.suffix();
    }
    QString instPath = myDir.absoluteFilePath(instProcName);

    installerProcess.setProgram(instPath);
    installerProcess.start();
    installerProcess.waitForStarted();
    if (installerProcess.state() == QProcess::NotRunning) {
        qWarning() << "Failed to start installer Process.";
        /* TODO ERROR message for the user */
        return;
    }

    installerProcess.write("-----BEGIN CERTIFICATE LIST-----\r\n");
    installerProcess.write(mCertificateList.rawData().toLatin1());
    installerProcess.write("-----END CERTIFICATE LIST-----\r\n");

    /* Items to install */
    for (int i = 0; i < mCertListWidget->count(); i++) {
        QListWidgetItem *item = mCertListWidget->item(i);
        if (item->checkState() != Qt::Checked &&
            item->data(Qt::UserRole).toString().startsWith("I:")) {
            continue;
        }
        installerProcess.write(item->data(Qt::UserRole).toString().toLatin1());
        installerProcess.write("\r\n");
    }

    /* Items to remove */
    for (int i = 0; i < mCertListWidget->count(); i++) {
        QListWidgetItem *item = mCertListWidget->item(i);
        if (!item->checkState() != Qt::Checked &&
            item->data(Qt::UserRole).toString().startsWith("R:")) {
            continue;
        }
        installerProcess.write(item->data(Qt::UserRole).toString().toLatin1());
        installerProcess.write("\r\n");
    }

    installerProcess.waitForBytesWritten();
    installerProcess.closeWriteChannel();
    installerProcess.waitForFinished();

    if (installerProcess.exitStatus() == QProcess::CrashExit) {
        /* Woops */
        qWarning() << "Installer process crashed";
    } else if (installerProcess.exitStatus() != QProcess::NormalExit) {
        /* Can not Happen. there are only those two values but maybe
         * qt changed.. */
        qWarning() << "Exit status neither normal nor crash.";
        return;
    }

    if (installerProcess.exitCode() == 0) {
        qDebug() << "Success!";
        qDebug() << "output: " << installerProcess.readAllStandardOutput();
    } else {
        /* TODO handle errors defined by errorcodes.h */
        qDebug() << "Installer Process returned: " << installerProcess.exitCode();
        qDebug() << "output: " << installerProcess.readAllStandardOutput();
        return;
    }
#endif
}

void ListUpdateDialog::showDetails(QListWidgetItem *item)
{
    QString details = item->data(Qt::ToolTipRole).toString();
    mDetailWidget->setPlainText(details);
}

http://wald.intevation.org/projects/trustbridge/