view ui/listupdatedialog.cpp @ 249:6a7eb102716d

Remove code duplication by unifying the certificatelist. You should now check for isInstallCert to determine wether this certificate should be installed or removed. Leaving the getInstallCertificates and getRemoveCertificates in place for compatibilty would have been easier to keep the tests stable.
author Andre Heinecke <aheinecke@intevation.de>
date Mon, 31 Mar 2014 08:06:17 +0000
parents 431b058e903d
children 06089ba2614a
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 "certificate.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::executeUpdate() {
    /* 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;
    }
}

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

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