view ui/listupdatedialog.cpp @ 289:9ad00a3255f4

Change cinst from stdin input to use arguments. As we have to execute this process on Windows over the shell a stdin / stdout communication is not really possible without some major hacks. So you now have to supply an instructions file and the path to the certificatelist as arguments when this process is called
author Andre Heinecke <aheinecke@intevation.de>
date Wed, 02 Apr 2014 13:52:02 +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/