changeset 654:129e611eaf50

Merge branch trustbridge-refactor
author Andre Heinecke <andre.heinecke@intevation.de>
date Wed, 25 Jun 2014 15:16:24 +0200
parents e41a2537b84d (current diff) 39f03316f675 (diff)
children 0ca15d937490
files ui/CMakeLists.txt ui/mainwindow.cpp ui/mainwindow.h
diffstat 20 files changed, 999 insertions(+), 302 deletions(-) [+]
line wrap: on
line diff
--- a/ui/CMakeLists.txt	Wed Jun 25 12:44:47 2014 +0200
+++ b/ui/CMakeLists.txt	Wed Jun 25 15:16:24 2014 +0200
@@ -33,6 +33,8 @@
     ${CMAKE_CURRENT_SOURCE_DIR}/mainwindow.cpp
     ${CMAKE_CURRENT_SOURCE_DIR}/helpdialog.cpp
     ${CMAKE_CURRENT_SOURCE_DIR}/certificateitemdelegate.cpp
+    ${CMAKE_CURRENT_SOURCE_DIR}/certificatelistwidget.cpp
+    ${CMAKE_CURRENT_SOURCE_DIR}/certificateitemwidget.cpp
     ${CMAKE_CURRENT_SOURCE_DIR}/separatoritemdelegate.cpp
     ${CMAKE_CURRENT_SOURCE_DIR}/installwrapper.cpp
     ${CMAKE_CURRENT_SOURCE_DIR}/aboutdialog.cpp
--- a/ui/certificateitemdelegate.h	Wed Jun 25 12:44:47 2014 +0200
+++ b/ui/certificateitemdelegate.h	Wed Jun 25 15:16:24 2014 +0200
@@ -5,8 +5,8 @@
  * and comes with ABSOLUTELY NO WARRANTY!
  * See LICENSE.txt for details.
  */
-#ifndef CERTIFICATELISTITEM_H
-#define CERTIFICATELISTITEM_H
+#ifndef CERTIFICATELISTDELEGATE_H
+#define CERTIFICATELISTDELEGATE_H
 /**
  * @file certificateitemdelegate.h
  * @brief Item delegate drawing custom certificate items in list views.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ui/certificateitemwidget.cpp	Wed Jun 25 15:16:24 2014 +0200
@@ -0,0 +1,97 @@
+/* Copyright (C) 2014 by Bundesamt für Sicherheit in der Informationstechnik
+ * 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.
+ */
+#include "certificateitemwidget.h"
+
+#include <QHBoxLayout>
+#include <QDebug>
+
+CertificateItemWidget::CertificateItemWidget(
+    QWidget *parent,
+    const Certificate &cert,
+    bool state,
+    bool editable) : QWidget(parent)
+{
+    mCertificate = cert;
+    mState = state;
+    mEditable = editable;
+    setupGUI();
+}
+
+void CertificateItemWidget::setupGUI()
+{
+    mLabel = new QLabel(mCertificate.subjectCN());
+    mComboBox = new QComboBox;
+    mComboBox->setFixedWidth(46);
+    connect(mComboBox, SIGNAL(currentIndexChanged(int)),
+        this, SLOT(currentStateChanged(int)));
+
+    QHBoxLayout *layout = new QHBoxLayout;
+    if (mCertificate.isInstallCert()) {
+        mComboBox->addItem(QIcon(":/img/security-high.png"), tr("install"), QVariant("true"));
+        mComboBox->addItem(QIcon(":/img/security-low.png"),
+            tr("remove"), QVariant("false"));
+        if (mState)
+            mComboBox->setCurrentIndex(0);
+        else {
+            mComboBox->setCurrentIndex(1);
+        }
+        layout->addWidget(mComboBox);
+    }
+    else if (!mCertificate.isInstallCert() && !mEditable){
+        QImage *img = new QImage(":/img/trash-empty.png");
+        QLabel *imgLabel = new QLabel;
+        imgLabel->setPixmap(QPixmap::fromImage(*img));
+        imgLabel->setFixedSize(28, 28);
+        imgLabel->setMargin(2);
+        layout->addWidget(imgLabel);
+    }
+    else {
+        mComboBox->addItem(QIcon(":/img/trash-empty.png"), tr("deinstall"), QVariant("true"));
+        mComboBox->addItem(QIcon(":/img/security-medium.png"),
+            tr("leave"), QVariant("false"));
+        if (mState)
+            mComboBox->setCurrentIndex(0);
+        else {
+            mComboBox->setCurrentIndex(1);
+        }
+        layout->addWidget(mComboBox);
+    }
+    layout->addWidget(mLabel);
+    this->setLayout(layout);
+}
+
+bool CertificateItemWidget::state()
+{
+    return mComboBox->currentData().toBool();
+}
+
+void CertificateItemWidget::setState(bool state)
+{
+    disconnect(mComboBox, SIGNAL(currentIndexChanged(int)),
+        this, SLOT(currentStateChanged(int)));
+
+    if (state) {
+        mComboBox->setCurrentIndex(0);
+    }
+    else {
+        mComboBox->setCurrentIndex(1);
+    }
+    connect(mComboBox, SIGNAL(currentIndexChanged(int)),
+        this, SLOT(currentStateChanged(int)));
+}
+
+Certificate CertificateItemWidget::certificate()
+{
+    return mCertificate;
+}
+
+void CertificateItemWidget::currentStateChanged(int)
+{
+    bool state = mComboBox->currentData().toBool();
+    emit stateChanged(state, mCertificate);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ui/certificateitemwidget.h	Wed Jun 25 15:16:24 2014 +0200
@@ -0,0 +1,50 @@
+/* Copyright (C) 2014 by Bundesamt für Sicherheit in der Informationstechnik
+ * 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.
+ */
+#ifndef CERTIFICATELISTITEM_H
+#define CERTIFICATELISTITEM_H
+/**
+ * @file certificateitemdelegate.h
+ * @brief Item delegate drawing custom certificate items in list views.
+ *
+ */
+#include <QWidget>
+#include <QLabel>
+#include <QComboBox>
+
+#include "certificate.h"
+
+class CertificateItemWidget : public QWidget
+{
+Q_OBJECT
+public:
+    CertificateItemWidget(
+        QWidget *parent = 0,
+        const Certificate &cert = Certificate(),
+        bool state = false,
+        bool edtiable = true);
+
+    bool state();
+    void setState(bool state);
+    Certificate certificate();
+
+private:
+    void setupGUI();
+
+    Certificate mCertificate;
+    bool mState;
+    bool mEditable;
+    QLabel *mLabel;
+    QComboBox *mComboBox;
+
+private slots:
+    void currentStateChanged(int ndx);
+
+signals:
+    void stateChanged(bool state, const Certificate &cert);
+};
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ui/certificatelistwidget.cpp	Wed Jun 25 15:16:24 2014 +0200
@@ -0,0 +1,245 @@
+/* Copyright (C) 2014 by Bundesamt für Sicherheit in der Informationstechnik
+ * 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.
+ */
+#include "certificatelistwidget.h"
+#include <QDebug>
+#include <QVBoxLayout>
+#include <QHBoxLayout>
+#include <QGroupBox>
+#include <QLabel>
+
+#include "certificateitemwidget.h"
+
+CertificateListWidget::CertificateListWidget(QWidget *parent, Qt::WindowFlags flags) :
+    QWidget(parent, flags)
+{
+    setupGUI();
+}
+
+void CertificateListWidget::setupGUI()
+{
+    QHBoxLayout *mainLayout = new QHBoxLayout;
+    QVBoxLayout *detailMainLayout = new QVBoxLayout;
+    mCertificateList = new QListWidget;
+    mCertificateList->setFixedWidth(250);
+    connect(mCertificateList,
+        SIGNAL(currentItemChanged(QListWidgetItem*, QListWidgetItem*)),
+        this,
+        SLOT(updateDetails(QListWidgetItem*)));
+
+    QHBoxLayout *detailLayout = new QHBoxLayout;
+    QVBoxLayout *detailLabelLayout = new QVBoxLayout;
+    QVBoxLayout *detailContentLayout = new QVBoxLayout;
+    QGroupBox *detailBox = new QGroupBox(tr("Details"));
+    QLabel *subjectCN = new QLabel(tr("Subject Common Name:"));
+    QLabel *subjectOU = new QLabel(tr("Subject Organisation:"));
+    QLabel *issuerCN = new QLabel(tr("Issuer Common Name:"));
+    QLabel *issuerOU = new QLabel(tr("Issuer Organisation:"));
+    QLabel *validFrom = new QLabel(tr("Valid from:"));
+    QLabel *validTo = new QLabel(tr("Valid to:"));
+    QLabel *fingerprint = new QLabel(tr("Fingerprint:"));
+    detailLabelLayout->addWidget(subjectCN);
+    detailLabelLayout->addWidget(subjectOU);
+    detailLabelLayout->addWidget(issuerCN);
+    detailLabelLayout->addWidget(issuerOU);
+    detailLabelLayout->addWidget(validFrom);
+    detailLabelLayout->addWidget(validTo);
+    detailLabelLayout->addWidget(fingerprint);
+    mSubjectCN = new QLabel(tr(""));
+    mSubjectO = new QLabel(tr(""));
+    mIssuerCN = new QLabel(tr(""));
+    mIssuerO = new QLabel(tr(""));
+    mValidFrom = new QLabel(tr(""));
+    mValidTo = new QLabel(tr(""));
+    mFingerprint = new QLabel(tr(""));
+    mFingerprint->setFont(QFont("DejaVu Sans Mono"));
+    detailContentLayout->addWidget(mSubjectCN);
+    detailContentLayout->addWidget(mSubjectO);
+    detailContentLayout->addWidget(mIssuerCN);
+    detailContentLayout->addWidget(mIssuerO);
+    detailContentLayout->addWidget(mValidFrom);
+    detailContentLayout->addWidget(mValidTo);
+    detailContentLayout->addWidget(mFingerprint);
+    detailLayout->addLayout(detailLabelLayout);
+    detailLayout->addLayout(detailContentLayout);
+    detailBox->setLayout(detailLayout);
+    detailMainLayout->addWidget(detailBox);
+    detailMainLayout->addStretch(1);
+
+    mainLayout->addWidget(mCertificateList);
+    mainLayout->addLayout(detailMainLayout);
+    this->setLayout(mainLayout);
+}
+
+void CertificateListWidget::addCertificate(
+    const Certificate &certificate,
+    bool state,
+    bool editable)
+{
+    QListWidgetItem* item = new QListWidgetItem(mCertificateList);
+    item->setData(Qt::UserRole,
+        QVariant::fromValue(certificate));
+    mCertificateList->addItem(item);
+    CertificateItemWidget *widget =
+        new CertificateItemWidget(mCertificateList, certificate, state, editable);
+    connect(widget, SIGNAL(stateChanged(bool, const Certificate&)),
+        this, SLOT(certStateChanged(bool, const Certificate&)));
+    item->setSizeHint(widget->minimumSizeHint());
+    mCertificateList->setItemWidget(item, widget);
+}
+
+void CertificateListWidget::addCertificates(const QList<Certificate> &list)
+{
+
+}
+
+void CertificateListWidget::removeCertificate(const Certificate &cert)
+{
+    for (int i = 0; i < mCertificateList->count(); i++) {
+        QListWidgetItem *item = mCertificateList->item(i);
+        CertificateItemWidget *itemWidget =
+            static_cast<CertificateItemWidget*>(mCertificateList->itemWidget(item));
+        if (itemWidget->certificate() == cert) {
+            QListWidgetItem* item = mCertificateList->takeItem(i);
+            delete(item);
+        }
+    }
+}
+
+void CertificateListWidget::clear()
+{
+    mCertificateList->clear();
+}
+
+QStringList CertificateListWidget::certificates()
+{
+    QStringList list;
+    for (int i = 0; i < mCertificateList->count(); i++) {
+        QListWidgetItem *item = mCertificateList->item(i);
+        CertificateItemWidget *itemWidget =
+            static_cast<CertificateItemWidget*>(mCertificateList->itemWidget(item));
+        list <<  itemWidget->certificate().base64Line();
+    }
+    return list;
+}
+
+QStringList CertificateListWidget::selectedCertificates() {
+    QStringList list;
+    for (int i = 0; i < mCertificateList->count(); i++) {
+        QListWidgetItem *item = mCertificateList->item(i);
+        CertificateItemWidget *itemWidget =
+            static_cast<CertificateItemWidget*>(mCertificateList->itemWidget(item));
+        if (itemWidget->state()) {
+            list << itemWidget->certificate().base64Line();
+        }
+    }
+    return list;
+}
+
+QStringList CertificateListWidget::unselectedCertificates() {
+    QStringList list;
+    for (int i = 0; i < mCertificateList->count(); i++) {
+        QListWidgetItem *item = mCertificateList->item(i);
+        CertificateItemWidget *itemWidget =
+            static_cast<CertificateItemWidget*>(mCertificateList->itemWidget(item));
+        if (!itemWidget->state()) {
+            list << itemWidget->certificate().base64Line();
+        }
+    }
+    return list;
+}
+
+QList<Certificate> CertificateListWidget::certificateList()
+{
+    QList<Certificate> list;
+    for (int i = 0; i < mCertificateList->count(); i++) {
+        QListWidgetItem *item = mCertificateList->item(i);
+        CertificateItemWidget *itemWidget =
+            static_cast<CertificateItemWidget*>(mCertificateList->itemWidget(item));
+        list << itemWidget->certificate();
+    }
+
+    return list;
+}
+
+void CertificateListWidget::setCertState(bool state, const Certificate &cert)
+{
+    for (int i = 0; i < mCertificateList->count(); i++) {
+        QListWidgetItem *item = mCertificateList->item(i);
+        CertificateItemWidget *itemWidget =
+            static_cast<CertificateItemWidget*>(mCertificateList->itemWidget(item));
+        if (itemWidget->certificate() == cert &&
+            itemWidget->state() != state) {
+            itemWidget->setState(state);
+        }
+    }
+}
+
+void CertificateListWidget::updateDetails(QListWidgetItem *item)
+{
+    if (item == NULL) {
+        return;
+    }
+    Certificate cert = item->data(Qt::UserRole).value<Certificate>();
+    mSubjectCN->setText(cert.subjectCN());
+    mSubjectO->setText(cert.subjectO());
+    mIssuerCN->setText(cert.issuerCN());
+    mIssuerO->setText(cert.issuerO());
+    mValidFrom->setText(cert.validFrom().toString());
+    mValidTo->setText(cert.validTo().toString());
+    mFingerprint->setText(cert.fingerprint());
+}
+
+void CertificateListWidget::certStateChanged(bool state, const Certificate &cert)
+{
+    int selected = 0;
+    for (int i = 0; i < mCertificateList->count(); i++) {
+        QListWidgetItem *item = mCertificateList->item(i);
+        CertificateItemWidget *itemWidget =
+            static_cast<CertificateItemWidget*>(mCertificateList->itemWidget(item));
+        if (itemWidget->state()) {
+            selected++;
+        }
+    }
+    emit certListChanged(selected);
+    emit certChanged(state, cert);
+}
+
+int CertificateListWidget::selectedCertCount()
+{
+    int selected = 0;
+    for (int i = 0; i < mCertificateList->count(); i++) {
+        QListWidgetItem *item = mCertificateList->item(i);
+        CertificateItemWidget *itemWidget =
+            static_cast<CertificateItemWidget*>(mCertificateList->itemWidget(item));
+        if (itemWidget->state()) {
+            selected++;
+        }
+    }
+    return selected;
+}
+
+bool CertificateListWidget::contains(const Certificate &cert)
+{
+    for (int i = 0; i < mCertificateList->count(); i++) {
+        QListWidgetItem *item = mCertificateList->item(i);
+        CertificateItemWidget *itemWidget =
+            static_cast<CertificateItemWidget*>(mCertificateList->itemWidget(item));
+        if (itemWidget->certificate() == cert) {
+            return true;
+        }
+    }
+    return false;
+}
+
+void CertificateListWidget::setSelected(int index)
+{
+    mCertificateList->setFocus();
+    if (mCertificateList->count() > 0) {
+        mCertificateList->item(0)->setSelected(true);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ui/certificatelistwidget.h	Wed Jun 25 15:16:24 2014 +0200
@@ -0,0 +1,64 @@
+/* Copyright (C) 2014 by Bundesamt für Sicherheit in der Informationstechnik
+ * 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.
+ */
+#ifndef CERTIFICATELISTWIDGET_H
+#define CERTIFICATELISTWIDGET_H
+
+#include <QWidget>
+#include <QMainWindow>
+#include <QLabel>
+#include <QListWidget>
+
+#include "certificate.h"
+/**
+ * @file certificatelistwidget.h
+ * @brief Displays a list of certificates and a details panel for a selected
+ * certificate.
+ */
+
+Q_DECLARE_METATYPE(Certificate);
+class CertificateListWidget : public QWidget
+{
+    Q_OBJECT
+public:
+    CertificateListWidget(QWidget *parent, Qt::WindowFlags flags = 0);
+
+    void addCertificate(const Certificate &certificate, bool state, bool editable = true);
+    void addCertificates(const QList<Certificate> &list);
+    void removeCertificate(const Certificate &cert);
+    void setCertState(bool state, const Certificate &cert);
+    void clear();
+    QStringList certificates();
+    QStringList selectedCertificates();
+    QStringList unselectedCertificates();
+    QList<Certificate> certificateList();
+    int selectedCertCount();
+    bool contains(const Certificate &cert);
+    void setSelected(int index);
+
+private:
+    void setupGUI();
+
+    QListWidget *mCertificateList;
+    QLabel *mSubjectCN;
+    QLabel *mSubjectO;
+    QLabel *mIssuerCN;
+    QLabel *mIssuerO;
+    QLabel *mValidFrom;
+    QLabel *mValidTo;
+    QLabel *mFingerprint;
+
+private slots:
+    void updateDetails(QListWidgetItem *item);
+    void certStateChanged(bool state, const Certificate &cert);
+
+signals:
+    void certListChanged(int selected);
+    void certChanged(bool state, const Certificate &cert);
+
+};
+#endif // CERTIFICATELISTWIDGET_H
--- a/ui/icons.qrc	Wed Jun 25 12:44:47 2014 +0200
+++ b/ui/icons.qrc	Wed Jun 25 15:16:24 2014 +0200
@@ -9,5 +9,16 @@
     <file>img/document-open.png</file>
     <file>img/document-new.png</file>
     <file>img/document-close.png</file>
+    <file>img/view-refresh.png</file>
+    <file>img/document-encrypt.png</file>
+    <file>img/task-attempt.png</file>
+    <file>img/dialog-information.png</file>
+    <file>img/system-search.png</file>
+    <file>img/system-shutdown.png</file>
+    <file>img/edit-redo.png</file>
+    <file>img/security-low.png</file>
+    <file>img/security-medium.png</file>
+    <file>img/security-high.png</file>
+    <file>img/trash-empty.png</file>
 </qresource>
 </RCC>
Binary file ui/img/dialog-information.png has changed
Binary file ui/img/document-encrypt.png has changed
Binary file ui/img/edit-redo.png has changed
Binary file ui/img/security-high.png has changed
Binary file ui/img/security-low.png has changed
Binary file ui/img/security-medium.png has changed
Binary file ui/img/system-search.png has changed
Binary file ui/img/system-shutdown.png has changed
Binary file ui/img/task-attempt.png has changed
Binary file ui/img/trash-empty.png has changed
Binary file ui/img/view-refresh.png has changed
--- a/ui/mainwindow.cpp	Wed Jun 25 12:44:47 2014 +0200
+++ b/ui/mainwindow.cpp	Wed Jun 25 15:16:24 2014 +0200
@@ -26,6 +26,8 @@
 #include <QLabel>
 #include <QImage>
 #include <QCheckBox>
+#include <QButtonGroup>
+#include <QToolButton>
 
 #include "certificatelist.h"
 #include "downloader.h"
@@ -73,7 +75,6 @@
 {
     createActions();
     createTrayIcon();
-    createMenuBar();
     createContent();
     resize(950, 540);
     qRegisterMetaType<SSLConnection::ErrorCode>("SSLConnection::ErrorCode");
@@ -213,6 +214,7 @@
 }
 
 void MainWindow::handleNewList(const QString& fileName, const QDateTime& modDate) {
+    qDebug() << "new list available";
     mSettings.setValue("List/available", fileName);
     mSettings.setValue("List/availableDate", modDate);
 
@@ -421,63 +423,26 @@
     connect(mTrayIcon, SIGNAL(messageClicked()), this, SLOT(messageClicked()));
 }
 
-void MainWindow::createMenuBar()
-{
-    mMenuBar = new QMenuBar(this);
-    QMenu *mMenu = new QMenu(tr("Menu"), mMenuBar);
-    mMenuBar->addMenu(mMenu);
-    QAction *update = mMenu->addAction(tr("Force Update"));
-    mMenu->addSeparator();
-    QAction *help = mMenu->addAction(tr("Help"));
-    QAction *about = mMenu->addAction(tr("About"));
-    mMenu->addSeparator();
-    QAction *quit = mMenu->addAction(tr("Quit"));
-    connect(update, SIGNAL(triggered()), this, SLOT(checkUpdates()));
-    connect(help, SIGNAL(triggered()), this, SLOT(showHelp()));
-    connect(about, SIGNAL(triggered()), this, SLOT(showAbout()));
-    connect(quit, SIGNAL(triggered()), this, SLOT(closeApp()));
-    setMenuBar(mMenuBar);
-}
-
 void MainWindow::createContent()
 {
     // Create a central widget containing the main layout.
     QWidget *base = new QWidget;
 
     // Layouts and Container
-    QHBoxLayout *mainLayout = new QHBoxLayout;
-    QVBoxLayout *infoLayout = new QVBoxLayout;
-    QVBoxLayout *certLayout = new QVBoxLayout;
-    QHBoxLayout *detailLayout = new QHBoxLayout;
-    QVBoxLayout *detailLabelLayout = new QVBoxLayout;
-    QVBoxLayout *detailContentLayout = new QVBoxLayout;
+    QVBoxLayout *mainLayout = new QVBoxLayout;
     QHBoxLayout *headerLayout = new QHBoxLayout;
     QVBoxLayout *headerTextLayout = new QVBoxLayout;
+    QHBoxLayout *centerLayout = new QHBoxLayout;
+    QVBoxLayout *buttonBarLayout = new QVBoxLayout;
     QHBoxLayout *bottomLayout = new QHBoxLayout;
-    QVBoxLayout *settingsLayout = new QVBoxLayout;
-    QVBoxLayout *listInfoLayout = new QVBoxLayout;
-
-    // The certificate list
-    QGroupBox *certBox = new QGroupBox(tr("Managed Certificates"));
-    mCertListWidget = new QListWidget;
-    connect(mCertListWidget, SIGNAL(currentItemChanged(QListWidgetItem*, QListWidgetItem*)),
-        this, SLOT(showDetails(QListWidgetItem*)));
-    certLayout->addWidget(mCertListWidget);
-
-    mCurrentListDate = new QLabel(tr("Current List Date: %1").arg(""));
-    mNewListDate = new QLabel("");
-    listInfoLayout->addWidget(mCurrentListDate);
-    listInfoLayout->addWidget(mNewListDate);
-    certLayout->addLayout(listInfoLayout);
-
-    certBox->setLayout(certLayout);
+    QHBoxLayout *containerLayout = new QHBoxLayout;
 
     // The header (icon, about text)
     QImage *logoImage = new QImage(":/img/logo.png");
     QLabel *logo = new QLabel;
     logo->setBackgroundRole(QPalette::Base);
     logo->setPixmap(QPixmap::fromImage(*logoImage));
-    QLabel *title = new QLabel("<h2>" + QString::fromLatin1(APPNAME) + "</h2>");
+    QLabel *title = new QLabel("<h1>" + QString::fromLatin1(APPNAME) + "</h1>");
     QLabel *subTitle = new QLabel("This Software installs and removes Certificates");
     headerTextLayout->addWidget(title);
     headerTextLayout->addWidget(subTitle);
@@ -486,106 +451,381 @@
     headerLayout->setStretch(0, 0);
     headerLayout->setStretch(1, 10);
 
-    // The settings.
-    QGroupBox *settingsBox = new QGroupBox(tr("Settings"));
-    mAutoUpdateOption = new QCheckBox(tr("Autoupdate"));
-    mAutoStartOption = new QCheckBox(tr("Autostart"));
-    settingsLayout->addWidget(mAutoUpdateOption);
-    settingsLayout->addWidget(mAutoStartOption);
-    settingsBox->setLayout(settingsLayout);
-    connect(mAutoUpdateOption, SIGNAL(stateChanged(int)),
-        this, SLOT(saveAutoUpdate(int)));
-    connect(mAutoStartOption, SIGNAL(stateChanged(int)),
-        this, SLOT(saveAutoStart(int)));
-    mSettings.beginGroup("settings");
-    bool autoUpdate = mSettings.value("autoupdate", false).toBool();
-    bool autoStart = mSettings.value("autostart", true).toBool();
-    mSettings.endGroup();
-    mAutoUpdateOption->setCheckState(autoUpdate ? Qt::Checked : Qt::Unchecked);
-    mAutoStartOption->setCheckState(autoStart ? Qt::Checked : Qt::Unchecked);
+    /***********************************
+     * The Buttonbar on the left side.
+     ***********************************/
+    mButtonGroup = new QButtonGroup;
 
+    QToolButton *updatesButton = new QToolButton;
+    updatesButton->setToolButtonStyle(Qt::ToolButtonTextUnderIcon);
+    updatesButton->setIcon(QIcon(":/img/view-refresh.png"));
+    updatesButton->setIconSize(QSize(32, 32));
+    updatesButton->setText(tr("Updates"));
+    updatesButton->setFixedWidth(90);
+    updatesButton->setFixedHeight(70);
+    updatesButton->setCheckable(true);
+    updatesButton->setChecked(true);
 
-    // The buttons.
-    bottomLayout->setAlignment(Qt::AlignBottom);
-    installButton = new QPushButton(tr("Install selected"));
-    installButton->setFixedHeight(80);
-    connect(installButton, SIGNAL(clicked()), this, SLOT(resizeButtons()));
-    connect(installButton, SIGNAL(clicked()), this, SLOT(checkAndInstallCerts()));
-    quitButton = new QPushButton(tr("Quit"));
-    quitButton->setFixedHeight(20);
-    connect(quitButton, SIGNAL(clicked()), this, SLOT(closeApp()));
-    bottomLayout->insertStretch(0, 10);
-    bottomLayout->addWidget(installButton);
-    bottomLayout->setAlignment(installButton, Qt::AlignBottom);
-    bottomLayout->addWidget(quitButton);
-    bottomLayout->setAlignment(quitButton, Qt::AlignBottom);
+    QToolButton *allInstallButton = new QToolButton;
+    allInstallButton->setToolButtonStyle(Qt::ToolButtonTextUnderIcon);
+    allInstallButton->setIcon(QIcon(":/img/document-encrypt.png"));
+    allInstallButton->setIconSize(QSize(32, 32));
+    allInstallButton->setText(tr("Trusted\nCertificates"));
+    allInstallButton->setFixedWidth(90);
+    allInstallButton->setFixedHeight(70);
+    allInstallButton->setCheckable(true);
 
+    QToolButton *allRemoveButton = new QToolButton;
+    allRemoveButton->setToolButtonStyle(Qt::ToolButtonTextUnderIcon);
+    allRemoveButton->setIcon(QIcon(":/img/task-attempt.png"));
+    allRemoveButton->setIconSize(QSize(32, 32));
+    allRemoveButton->setText(tr("Insecure\nCertificates"));
+    allRemoveButton->setFixedWidth(90);
+    allRemoveButton->setFixedHeight(70);
+    allRemoveButton->setCheckable(true);
+
+    QToolButton *infoButton = new QToolButton;
+    infoButton->setToolButtonStyle(Qt::ToolButtonTextUnderIcon);
+    infoButton->setIcon(QIcon(":/img/dialog-information.png"));
+    infoButton->setIconSize(QSize(32, 32));
+    infoButton->setText(tr("Information"));
+    infoButton->setFixedWidth(90);
+    infoButton->setFixedHeight(70);
+    infoButton->setCheckable(true);
+
+    mButtonGroup->addButton(updatesButton);
+    mButtonGroup->addButton(allInstallButton);
+    mButtonGroup->addButton(allRemoveButton);
+    mButtonGroup->addButton(infoButton);
+    mButtonGroup->setId(updatesButton, 0);
+    mButtonGroup->setId(allInstallButton, 1);
+    mButtonGroup->setId(allRemoveButton, 2);
+    mButtonGroup->setId(infoButton, 3);
+
+    connect(mButtonGroup, SIGNAL(buttonClicked(int)),
+        this, SLOT(togglePages(int)));
+    buttonBarLayout->addWidget(updatesButton);
+    buttonBarLayout->addWidget(allInstallButton);
+    buttonBarLayout->addWidget(allRemoveButton);
+    buttonBarLayout->insertStretch(3, 10);
+    buttonBarLayout->addWidget(infoButton);
+
+    /********************************
+     * The main pages.
+     ********************************/
+
+    /********************************
+     * The updates page.
+     ********************************/
+    QVBoxLayout *updatesMainLayout = new QVBoxLayout;
+    mUpdatesPanel = new QScrollArea;
+    QScrollArea *updatesContent = new QScrollArea;
+//    updatesContent->setFrameShape(QFrame::NoFrame);
+    mUpdatesWidget = new QWidget;
+
+    /* The updates header */
+    QHBoxLayout *updatesHeaderLayout = new QHBoxLayout;
+    QVBoxLayout *updatesHeaderTextLayout = new QVBoxLayout;
+    QVBoxLayout *updatesHeaderButtonLayout = new QVBoxLayout;
+    QHBoxLayout *updatesHeaderActionLayout = new QHBoxLayout;
+    QHBoxLayout *updatesHeaderSearchLayout = new QHBoxLayout;
+
+    mUpdatesHeader =
+        new QLabel("<h2>" + tr("Updates (%1/%2)").arg(0).arg(0)+ "</h2>");
+    mLastCertUpdate =
+        new QLabel(tr("Last certificate update: %1").arg(""));
+    mLastSWupdate =
+        new QLabel(tr("Last Software update: %1").arg(""));
+    QLabel *updatesTip =
+        new QLabel("<h4>" + tr("The following certificate changes are recommended.") + "</h4>");
+
+    updatesHeaderTextLayout->addWidget(mUpdatesHeader);
+    updatesHeaderTextLayout->addWidget(mLastCertUpdate);
+    updatesHeaderTextLayout->addWidget(mLastSWupdate);
+    updatesHeaderTextLayout->addSpacing(10);
+    updatesHeaderTextLayout->addWidget(updatesTip);
+
+    QPushButton *searchUpdates = new QPushButton(tr("Search for Updates"));
+    searchUpdates->setIcon(QIcon(":/img/system-search.png"));
+    QPushButton *quitButton = new QPushButton(tr("Quit without saving"));
+    quitButton->setIcon(QIcon(":/img/system-shutdown.png"));
+    QPushButton *installButton = new QPushButton(tr("Update"));
 #ifdef Q_OS_WIN
     if (is_admin()) {
         QIcon uacShield = QApplication::style()->standardIcon(QStyle::SP_VistaShield);
         installButton->setIcon(uacShield);
     }
+#else
+    installButton->setIcon(QIcon(":/img/edit-redo.png"));
 #endif
+    connect(quitButton, SIGNAL(clicked()), this, SLOT(closeApp()));
+    connect(installButton, SIGNAL(clicked()), this, SLOT(checkAndInstallCerts()));
+    connect(searchUpdates, SIGNAL(clicked()), this, SLOT(checkUpdates()));
 
-    // The certificate details
-    QGroupBox *detailBox = new QGroupBox(tr("Details"));
-    QLabel *subjectCN = new QLabel(tr("Subject Common Name:"));
-    QLabel *subjectOU = new QLabel(tr("Subject Organisation:"));
-    QLabel *issuerCN = new QLabel(tr("Issuer Common Name:"));
-    QLabel *issuerOU = new QLabel(tr("Issuer Organisation:"));
-    QLabel *validFrom = new QLabel(tr("Valid from:"));
-    QLabel *validTo = new QLabel(tr("Valid to:"));
-    QLabel *fingerprint = new QLabel(tr("Fingerprint:"));
-    detailLabelLayout->addWidget(subjectCN);
-    detailLabelLayout->addWidget(subjectOU);
-    detailLabelLayout->addWidget(issuerCN);
-    detailLabelLayout->addWidget(issuerOU);
-    detailLabelLayout->addWidget(validFrom);
-    detailLabelLayout->addWidget(validTo);
-    detailLabelLayout->addWidget(fingerprint);
-    mSubjectCN = new QLabel(tr(""));
-    mSubjectO = new QLabel(tr(""));
-    mIssuerCN = new QLabel(tr(""));
-    mIssuerO = new QLabel(tr(""));
-    mValidFrom = new QLabel(tr(""));
-    mValidTo = new QLabel(tr(""));
-    mFingerprint = new QLabel(tr(""));
-    mFingerprint->setFont(QFont("DejaVu Sans Mono"));
-    detailContentLayout->addWidget(mSubjectCN);
-    detailContentLayout->addWidget(mSubjectO);
-    detailContentLayout->addWidget(mIssuerCN);
-    detailContentLayout->addWidget(mIssuerO);
-    detailContentLayout->addWidget(mValidFrom);
-    detailContentLayout->addWidget(mValidTo);
-    detailContentLayout->addWidget(mFingerprint);
-    detailLayout->addLayout(detailLabelLayout);
-    detailLayout->addLayout(detailContentLayout);
-    detailBox->setLayout(detailLayout);
+    updatesHeaderActionLayout->addWidget(installButton);
+    updatesHeaderActionLayout->addWidget(quitButton);
+    updatesHeaderSearchLayout->insertStretch(0, 1);
+    updatesHeaderSearchLayout->addWidget(searchUpdates);
 
-    infoLayout->addSpacing(20);
-    infoLayout->addLayout(headerLayout);
-    infoLayout->addWidget(detailBox);
-    infoLayout->addWidget(settingsBox);
-    infoLayout->addLayout(bottomLayout);
+    updatesHeaderButtonLayout->addLayout(updatesHeaderSearchLayout);
+    updatesHeaderButtonLayout->addLayout(updatesHeaderActionLayout);
 
-    mainLayout->addWidget(certBox);
-    mainLayout->addLayout(infoLayout);
-    mainLayout->setStretchFactor(certBox, 37);
-    mainLayout->setStretchFactor(infoLayout, 63);
+    updatesHeaderLayout->addLayout(updatesHeaderTextLayout);
+    updatesHeaderLayout->insertStretch(1, 10);
+    updatesHeaderLayout->addLayout(updatesHeaderButtonLayout);
 
-    // QMainWindow allready has a layout. All child layouts and widgets are
-    // managed in the central widget.
+    /* The central panels. */
+    QVBoxLayout *updatesCenterLayout = new QVBoxLayout;
+    QHBoxLayout *updatesNewLayout = new QHBoxLayout;
+    QHBoxLayout *updatesRemoveLayout = new QHBoxLayout;
+    QHBoxLayout *updatesManualLayout = new QHBoxLayout;
+    mUpdatesNewCertificates =
+        new QLabel("<h3>" +
+            tr("Install new Certificates (%1/%2)").arg(0).arg(0) +
+            "</h3>");
+    mUpdatesDetailsNew = new QPushButton(tr("Show Details"));
+    connect(mUpdatesDetailsNew,
+        SIGNAL(clicked()),
+        this,
+        SLOT(toggleUpdatesNew()));
+    updatesNewLayout->addWidget(mUpdatesNewCertificates);
+    updatesNewLayout->addWidget(mUpdatesDetailsNew);
+    updatesNewLayout->insertStretch(2, 10);
+    mUpdatesNew = new CertificateListWidget(this);
+    connect(mUpdatesNew, SIGNAL(certListChanged(int)),
+        this, SLOT(listChanged(int)));
+    mUpdatesNew->hide();
+
+    mUpdatesRemoveCertificates =
+        new QLabel("<h3>" +
+            tr("Remove insecure Certificates (%1/%2)").arg(0).arg(0) +
+            "</h3>");
+    mUpdatesDetailsRemove = new QPushButton(tr("Show Details"));
+    connect(mUpdatesDetailsRemove,
+        SIGNAL(clicked()),
+        this,
+        SLOT(toggleUpdatesRemove()));
+    updatesRemoveLayout->addWidget(mUpdatesRemoveCertificates);
+    updatesRemoveLayout->addWidget(mUpdatesDetailsRemove);
+    updatesRemoveLayout->insertStretch(2, 10);
+    mUpdatesRemove = new CertificateListWidget(this);
+    connect(mUpdatesRemove, SIGNAL(certListChanged(int)),
+        this, SLOT(listChanged(int)));
+    mUpdatesRemove->hide();
+
+    mUpdatesManualCertificates =
+        new QLabel("<h3>" +
+            tr("Manualy changed Certificates (%1)").arg(0) +
+            "</h3>");
+    mUpdatesDetailsManual = new QPushButton(tr("Show Details"));
+    connect(mUpdatesDetailsManual,
+        SIGNAL(clicked()),
+        this,
+        SLOT(toggleUpdatesManual()));
+    updatesManualLayout->addWidget(mUpdatesManualCertificates);
+    updatesManualLayout->addWidget(mUpdatesDetailsManual);
+    updatesManualLayout->insertStretch(2, 10);
+    mUpdatesManual = new CertificateListWidget(this);
+    mUpdatesManual->hide();
+    connect(mUpdatesManual, SIGNAL(certChanged(bool, const Certificate&)),
+        this, SLOT(removeFromManual(bool, const Certificate&)));
+
+    updatesNewLayout->setAlignment(Qt::AlignTop);
+    updatesRemoveLayout->setAlignment(Qt::AlignTop);
+    updatesManualLayout->setAlignment(Qt::AlignTop);
+    updatesCenterLayout->addLayout(updatesNewLayout);
+    updatesCenterLayout->addWidget(mUpdatesNew);
+    updatesCenterLayout->addLayout(updatesRemoveLayout);
+    updatesCenterLayout->addWidget(mUpdatesRemove);
+    updatesCenterLayout->addLayout(updatesManualLayout);
+    updatesCenterLayout->addWidget(mUpdatesManual);
+    updatesCenterLayout->addStretch(1);
+
+    updatesCenterLayout->setSizeConstraint(QLayout::SetMinAndMaxSize);
+    mUpdatesWidget->setLayout(updatesCenterLayout);
+    updatesContent->setWidget(mUpdatesWidget);
+
+    updatesMainLayout->addLayout(updatesHeaderLayout);
+    updatesMainLayout->addWidget(updatesContent);
+    mUpdatesPanel->setLayout(updatesMainLayout);
+
+    /*********************************
+     * Panel for trusted certificates.
+     *********************************/
+    mInstallPanel = new QScrollArea;
+
+    QVBoxLayout *installPanelLayout = new QVBoxLayout;
+    QVBoxLayout *installHeaderLayout = new QVBoxLayout;
+    QVBoxLayout *installCenterLayout = new QVBoxLayout;
+
+    QLabel *installHeaderLabel =
+        new QLabel("<h2>" + tr("Trusted Certificates") + "</h2>");
+    QLabel *installHeaderText = new QLabel(tr("The following list of root"
+        " certificates was created by the BSI. The BSI vaidates authenticity,"
+        " security and actuality of these certificates"));
+    installHeaderLayout->addWidget(installHeaderLabel);
+    installHeaderLayout->addWidget(installHeaderText);
+
+    QLabel *installCenterText = new QLabel(tr("Please choose the certificates"
+        " you want to trust. TrustBridge will install these certificates for"
+        " secure communication via email or the internet (e.g. IE, Firefox,"
+        " Thunderbird)"));
+    installCenterLayout->addWidget(installCenterText);
+    mInstallList = new CertificateListWidget(this);
+    connect(mInstallList, SIGNAL(certChanged(bool, const Certificate&)),
+        this, SLOT(toggleInManual(bool, const Certificate&)));
+
+    installPanelLayout->addLayout(installHeaderLayout);
+    installPanelLayout->addLayout(installCenterLayout);
+    installPanelLayout->addWidget(mInstallList);
+    mInstallPanel->setLayout(installPanelLayout);
+
+    /**********************************
+     * Panel for insecure certificates.
+     **********************************/
+    mRemovePanel = new QScrollArea;
+    QVBoxLayout *removePanelLayout = new QVBoxLayout;
+    QVBoxLayout *removeHeaderLayout = new QVBoxLayout;
+    QVBoxLayout *removeCenterLayout = new QVBoxLayout;
+
+    QLabel *removeHeaderLabel =
+        new QLabel("<h2>" + tr("Insecure Certificates") + "</h2>");
+    QLabel *removeHeaderText = new QLabel(tr("The following list of root"
+        " certificates was created by the BSI. The BSI validates authenticity,"
+        " security and actuality of these certificates"));
+    removeHeaderLayout->addWidget(removeHeaderLabel);
+    removeHeaderLayout->addWidget(removeHeaderText);
+
+    QLabel *removeCenterText = new QLabel(tr("Please choose the certificates"
+        " you want to remove. TrustBridge will remove these certificates."));
+    removeCenterLayout->addWidget(removeCenterText);
+    mRemoveList = new CertificateListWidget(this);
+    connect(mRemoveList, SIGNAL(certChanged(bool, const Certificate&)),
+        this, SLOT(toggleInManual(bool, const Certificate&)));
+
+    removePanelLayout->addLayout(removeHeaderLayout);
+    removePanelLayout->addLayout(removeCenterLayout);
+    removePanelLayout->addWidget(mRemoveList);
+    mRemovePanel->setLayout(removePanelLayout);
+
+    /**********************************
+     * The info panel.
+     **********************************/
+    mInfoPanel = new QScrollArea;
+
+    QVBoxLayout *infoPanelLayout = new QVBoxLayout;
+    QHBoxLayout *infoHeaderLayout = new QHBoxLayout;
+    QVBoxLayout *infoHeaderTextLayout = new QVBoxLayout;
+    QVBoxLayout *infoCenterLayout = new QVBoxLayout;
+
+    QImage *infoLogoImage = new QImage(":/img/logo.png");
+    QLabel *infoLogo = new QLabel;
+    infoLogo->setBackgroundRole(QPalette::Base);
+    infoLogo->setPixmap(QPixmap::fromImage(*infoLogoImage));
+    QLabel *infoTitle = new QLabel("<h1>" + tr("TrustBridge") + "</h1>");
+    QString infoVersion = tr("Version: ");
+    infoVersion.append(QApplication::applicationVersion());
+    QLabel *appVersion = new QLabel(infoVersion);
+    appVersion->setTextInteractionFlags(
+        Qt::TextSelectableByMouse |
+        Qt::TextSelectableByKeyboard);
+
+    QFrame *infoHeaderSeparator = new QFrame();
+    infoHeaderSeparator->setFrameShape(QFrame::HLine);
+    infoHeaderSeparator->setFrameShadow(QFrame::Sunken);
+
+    infoHeaderTextLayout->addWidget(infoTitle);
+    infoHeaderTextLayout->addWidget(appVersion);
+    infoHeaderLayout->addWidget(infoLogo);
+    infoHeaderLayout->addLayout(infoHeaderTextLayout);
+    infoHeaderLayout->insertStretch(2, 10);
+
+    QLabel *textDesc = new QLabel(tr("TrustBridge is a root certificate"
+        " installer for Windows and Linux."));
+    textDesc->setTextInteractionFlags(
+        Qt::TextSelectableByMouse |
+        Qt::TextSelectableByKeyboard);
+    QLabel *textManage = new QLabel(tr("The root certificate lists are managed"
+        " by the German <a href=\"https://www.bsi.bund.de\">"
+        "Federal Office for Information Security (BSI)</a>.\n\n"));
+    textManage->setTextInteractionFlags(
+        Qt::TextBrowserInteraction |
+        Qt::TextSelectableByKeyboard);
+    QLabel *textDevel = new QLabel(tr("The software was developed by the companies"
+        " <a href=\"http://www.intevation.de\">Intevation GmbH</a> and "
+        " <a href=\"http://www.dn-systems.de\">DN-Systems GmbH</a>, <br>"
+        " contracted by the German Federal Office for Information Security (BSI).\n\n"));
+    textDevel->setTextInteractionFlags(
+        Qt::TextBrowserInteraction |
+        Qt::TextSelectableByKeyboard);
+    QLabel *textLicense = new QLabel(tr("TrustBridge is Free Software licensed"
+        " under GNU GPL v2+.\n\nCopyright (C) 2014 by Bundesamt für Sicherheit"
+        " in der Informationstechnik"));
+    textLicense->setTextInteractionFlags(
+        Qt::TextSelectableByMouse |
+        Qt::TextSelectableByKeyboard);
+
+    infoCenterLayout->addWidget(infoHeaderSeparator);
+    infoCenterLayout->addWidget(textDesc);
+    infoCenterLayout->addWidget(textManage);
+    infoCenterLayout->addWidget(textDevel);
+    infoCenterLayout->addWidget(textLicense);
+    infoCenterLayout->insertSpacing(2, 10);
+    infoCenterLayout->insertSpacing(4, 10);
+    infoCenterLayout->insertSpacing(6, 10);
+    infoCenterLayout->insertStretch(8, 10);
+
+    infoPanelLayout->addLayout(infoHeaderLayout);
+    infoPanelLayout->addLayout(infoCenterLayout);
+    mInfoPanel->setLayout(infoPanelLayout);
+
+    /********************************
+     * The main layout for pages.
+     ********************************/
+    mInstallPanel->hide();
+    mRemovePanel->hide();
+    mInfoPanel->hide();
+    containerLayout->addWidget(mUpdatesPanel);
+    containerLayout->addWidget(mInstallPanel);
+    containerLayout->addWidget(mRemovePanel);
+    containerLayout->addWidget(mInfoPanel);
+
+    centerLayout->addLayout(buttonBarLayout);
+    centerLayout->addLayout(containerLayout);
+
+    mainLayout->addLayout(headerLayout);
+    mainLayout->addLayout(centerLayout);
+    mainLayout->addLayout(bottomLayout);
     base->setLayout(mainLayout);
     setCentralWidget(base);
 }
 
+void MainWindow::listChanged(int selected)
+{
+    mUpdatesHeader->setText("<h2>" + tr("Updates (%1/%2)")
+            .arg(mUpdatesRemove->selectedCertCount() + mUpdatesNew->selectedCertCount())
+            .arg(mUpdatesRemove->certificates().size() + mUpdatesNew->certificates().size()) +
+            "</h2>");
+    mUpdatesNewCertificates->setText("<h3>" +
+            tr("Install new Certificates (%1/%2)")
+            .arg(mUpdatesNew->selectedCertCount())
+            .arg(mUpdatesNew->certificates().size()) +
+            "</h3>");
+    mUpdatesRemoveCertificates->setText("<h3>" +
+            tr("Remove insecure Certificates (%1/%2)")
+            .arg(mUpdatesRemove->selectedCertCount())
+            .arg(mUpdatesRemove->certificates().size()) +
+            "</h3>");
+}
+
 void MainWindow::loadCertificateList()
 {
-    mCertListWidget->clear();
-    int i = 0;
-
     /* TODO: if nothing is available (neither old nor new) add some progress
      * indication */
+    mInstallList->clear();
+    mUpdatesNew->clear();
+    mRemoveList->clear();
+    mUpdatesRemove->clear();
     QList<Certificate> newInstallCerts;
     QList<Certificate> newRemoveCerts;
     QList<Certificate> oldInstallCerts;
@@ -594,29 +834,32 @@
     if (mListToInstall.getCertificates().isEmpty()) {
         // No new list available, add old certificates.
         foreach (const Certificate &cert, mInstalledList.getCertificates()) {
+            bool state = !mPreviouslyUnselected.contains(cert.base64Line());
             if (cert.isInstallCert()) {
                 oldInstallCerts.append(cert);
+                mInstallList->addCertificate(cert, state);
             }
             else {
                 oldRemoveCerts.append(cert);
+                mRemoveList->addCertificate(cert, state, !state);
             }
         }
-        // Set the date of the old list.
-        mCurrentListDate->setText(tr("Current List Date: %1")
-            .arg(mInstalledList.date().toString()));
     }
     else {
         // Sort and filter both lists.
         foreach (const Certificate &cert, mListToInstall.getCertificates()) {
+            bool state = !mPreviouslyUnselected.contains(cert.base64Line());
             if (cert.isInstallCert()) {
                 // Certificate with status "install".
                 if (mInstalledList.getCertificates().contains(cert)) {
                     // Was in the old list.
                     oldInstallCerts.append(cert);
+                    mInstallList->addCertificate(cert, state);
                 }
                 else {
                     // Is a brand new certificate
                     newInstallCerts.append(cert);
+                    mUpdatesNew->addCertificate(cert, state);
                 }
             }
             else {
@@ -624,114 +867,38 @@
                 if (mInstalledList.getCertificates().contains(cert)) {
                     // Was in the old list.
                     oldRemoveCerts.append(cert);
+                    // Is removed, so set editable to false.
+                    mRemoveList->addCertificate(cert, state, !state);
                 }
                 else {
                     // Was in the old list with status "install" and now has the
                     // status "remove".
                     newRemoveCerts.append(cert);
+                    mUpdatesRemove->addCertificate(cert, state);
                 }
             }
         }
-        mCurrentListDate->setText(tr("Current List Date: %1")
+        mUpdatesHeader->setText("<h2>" +
+            tr("Updates (%1/%2)")
+                .arg(mUpdatesNew->selectedCertCount() + mUpdatesRemove->selectedCertCount())
+                .arg(newRemoveCerts.size() + newInstallCerts.size()) + "</h2>");
+        mLastCertUpdate->setText(tr("Last certificate update: %1")
             .arg(mInstalledList.date().toString()));
-        mNewListDate->setText(tr("New List Date: %1").arg(mListToInstall.date().toString()));
-    }
-
-    // Add separators and certificates to list widget.
-    if (!newInstallCerts.isEmpty()) {
-        mCertListWidget->addItem(createSeparator(tr("New certificates to install"), i++));
-        foreach (const Certificate &cert, newInstallCerts) {
-            mCertListWidget->addItem(createListItem(cert, Certificate::InstallNew, i++));
-        }
-    }
-
-    if (!newRemoveCerts.isEmpty()) {
-        mCertListWidget->addItem(createSeparator(tr("New certificates to remove"), i++));
-        foreach (const Certificate &cert, newRemoveCerts) {
-            mCertListWidget->addItem(createListItem(cert, Certificate::RemoveNew, i++));
-        }
     }
-
-    if (!oldInstallCerts.isEmpty()) {
-        mCertListWidget->addItem(createSeparator(tr("Old certificates to install"), i++));
-        foreach (const Certificate &cert, oldInstallCerts) {
-            mCertListWidget->addItem(createListItem(cert, Certificate::InstallOld, i++));
-        }
-    }
-
-    if (!oldRemoveCerts.isEmpty()) {
-        mCertListWidget->addItem(createSeparator(tr("Old certificates to remove"), i++));
-        foreach (const Certificate &cert, oldRemoveCerts) {
-            mCertListWidget->addItem(createListItem(cert, Certificate::RemoveOld, i++));
-        }
-    }
-}
-
-QListWidgetItem* MainWindow::createSeparator(const QString &text, int index)
-{
-    SeparatorItemDelegate *separatorDelegate = new SeparatorItemDelegate();
-    QListWidgetItem *separator = new QListWidgetItem(text);
-    mCertListWidget->setItemDelegateForRow(index, separatorDelegate);
-    separator->setFlags(separator->flags() ^ Qt::ItemIsUserCheckable);
-    return separator;
-}
+    mUpdatesNewCertificates->setText("<h3>" +
+            tr("Install new Certificates (%1/%2)")
+            .arg(mUpdatesNew->selectedCertCount())
+            .arg(mUpdatesNew->certificates().size()) +
+            "</h3>");
 
-QListWidgetItem* MainWindow::createListItem(const Certificate &certificate,
-    Certificate::Status status, int index)
-{
-    CertificateItemDelegate *certDelegate = new CertificateItemDelegate();
-    QListWidgetItem* item = new QListWidgetItem(certificate.shortDescription());
-    item->setData(CertificateItemDelegate::DataRole,
-        QVariant::fromValue(certificate));
-    item->setData(CertificateItemDelegate::StatusRole, status);
-    if (!mPreviouslyUnselected.contains(certificate.base64Line()) &&
-        status == Certificate::RemoveOld) {
-        item->setFlags(item->flags() ^ Qt::ItemIsUserCheckable);
-    }
-    else {
-        Qt::CheckState checkedState =
-            mPreviouslyUnselected.contains(certificate.base64Line()) ?
-                Qt::Unchecked : Qt::Checked;
-        item->setFlags(item->flags() | Qt::ItemIsUserCheckable);
-        item->setCheckState(checkedState);
-    }
-    mCertListWidget->setItemDelegateForRow(index, certDelegate);
-    return item;
-}
-
-void MainWindow::showHelp()
-{
-    qDebug() << "show helpdialog";
-    HelpDialog *help = new HelpDialog(this);
-    help->show();
-}
-
-void MainWindow::showAbout()
-{
-    qDebug() << "show aboutdialog";
-    AboutDialog *about = new AboutDialog(this);
-    about->show();
-}
-
-void MainWindow::showDetails(QListWidgetItem *item)
-{
-    if (item == NULL) {
-        return;
-    }
-    Certificate cert = item->data(CertificateItemDelegate::DataRole).value<Certificate>();
-    mSubjectCN->setText(cert.subjectCN());
-    mSubjectO->setText(cert.subjectO());
-    mIssuerCN->setText(cert.issuerCN());
-    mIssuerO->setText(cert.issuerO());
-    mValidFrom->setText(cert.validFrom().toString());
-    mValidTo->setText(cert.validTo().toString());
-    mFingerprint->setText(cert.fingerprint());
-}
-
-void MainWindow::resizeButtons()
-{
-    installButton->setFixedHeight(20);
-    quitButton->setFixedHeight(80);
+    mUpdatesRemoveCertificates->setText("<h3>" +
+            tr("Remove insecure Certificates (%1/%2)")
+            .arg(mUpdatesRemove->selectedCertCount())
+            .arg(mUpdatesRemove->certificates().size()) +
+            "</h3>");
+    mUpdatesManualCertificates->setText("<h3>" +
+            tr("Manualy changed Certificates (%1)").arg(0) +
+            "</h3>");
 }
 
 void MainWindow::installerError(const QString& errMsg) {
@@ -764,20 +931,26 @@
 
 void MainWindow::installCerts() {
     QStringList choices;
+    QStringList unselected;
 
-    for (int i = 0; i < mCertListWidget->count(); i++) {
-        QListWidgetItem *item = mCertListWidget->item(i);
-        if (item->checkState() == Qt::Checked) {
-            choices << item->data(CertificateItemDelegate::DataRole).value<Certificate>().base64Line();
-            continue;
-        }
-        QString certLine = item->data(CertificateItemDelegate::DataRole).value<Certificate>().base64Line();
-        if (certLine.startsWith("I:")) {
+    choices << mUpdatesNew->selectedCertificates();
+    choices << mUpdatesRemove->selectedCertificates();
+
+    choices <<  mUpdatesManual->selectedCertificates();
+    QStringList unselectedManuals = mUpdatesManual->unselectedCertificates();
+    for(int i = 0; i < unselectedManuals.size(); i++) {
+        if (unselectedManuals.at(i).startsWith("I:")) {
+            QString certLine = unselectedManuals.at(i);
             certLine[0] = 'R';
             choices << certLine;
         }
     }
 
+    unselected << mUpdatesNew->unselectedCertificates();
+    unselected << mUpdatesRemove->unselectedCertificates();
+    unselected << mInstallList->unselectedCertificates();
+    unselected << mRemoveList->unselectedCertificates();
+
     QProgressDialog *progress = new QProgressDialog(this);
     progress->setWindowModality(Qt::WindowModal);
     progress->setLabelText(tr("Installing certificates..."));
@@ -801,9 +974,10 @@
             this, SLOT(installerError(const QString &)));
     instWrap->start();
 
-    if (!saveUnselectedCertificates()) {
+    if (!saveUnselectedCertificates(unselected)) {
         qWarning() << "Failed to save previosly unselected certificates.";
     }
+
 }
 
 void MainWindow::loadUnselectedCertificates()
@@ -817,44 +991,56 @@
     mSettings.endGroup();
 }
 
-bool MainWindow::saveUnselectedCertificates()
+bool MainWindow::saveUnselectedCertificates(QStringList unselected)
 {
     mPreviouslyUnselected.clear();
     mSettings.beginGroup("unselected");
     mSettings.remove(""); /* Clears old choices */
-    for (int i = 0; i < mCertListWidget->count(); i++) {
-        QListWidgetItem *item = mCertListWidget->item(i);
-        if (item->checkState() != Qt::Checked &&
-            (item->flags() & Qt::ItemIsUserCheckable)) {
-            QString key = QString::fromLatin1("cert%1").arg(i);
-            QString value =
-                item->data(CertificateItemDelegate::DataRole).value<Certificate>().base64Line();
-            mSettings.setValue(key, value);
-            mPreviouslyUnselected << value;
-        }
+    for (int i = 0; i < unselected.size(); i++) {
+        QString key = QString::fromLatin1("cert%1").arg(i);
+        QString value = unselected.at(i);
+        mSettings.setValue(key, value);
+        mPreviouslyUnselected << value;
     }
     mSettings.endGroup();
     mSettings.sync();
     return mSettings.status() == QSettings::NoError;
 }
 
-void MainWindow::saveAutoUpdate(int state)
+void MainWindow::toggleInManual(bool state, const Certificate &cert)
 {
-    mSettings.beginGroup("settings");
-    mSettings.setValue("autoupdate", state != Qt::Unchecked);
-    mSettings.endGroup();
+    if (!mUpdatesManual->contains(cert)) {
+        mUpdatesManual->addCertificate(cert, state);
+    }
+    else {
+        mUpdatesManual->removeCertificate(cert);
+    }
+
+    mUpdatesManualCertificates->setText("<h3>" +
+            tr("Manualy changed Certificates (%1)")
+                .arg(mUpdatesManual->certificates().size()) +
+            "</h3>");
 }
 
-void MainWindow::saveAutoStart(int state)
+void MainWindow::removeFromManual(bool state, const Certificate &cert)
 {
-    mSettings.beginGroup("settings");
-    mSettings.setValue("autostart", state != Qt::Unchecked);
-    mSettings.endGroup();
+    mUpdatesManual->removeCertificate(cert);
+
+    mUpdatesManualCertificates->setText("<h3>" +
+            tr("Manualy changed Certificates (%1)")
+                .arg(mUpdatesManual->certificates().size()) +
+            "</h3>");
+
+    if (cert.isInstallCert()) {
+        mInstallList->setCertState(state, cert);
+    }
+    else {
+        mRemoveList->setCertState(state, cert);
+    }
 }
 
 void MainWindow::closeApp()
 {
-    saveUnselectedCertificates();
     qApp->quit();
 }
 
@@ -878,6 +1064,64 @@
     connect(waitDialog, SIGNAL(accepted()), waitDialog, SLOT(deleteLater()));
 
     waitDialog->exec();
-
     return;
 }
+
+void MainWindow::togglePages(int button)
+{
+    UpdatesPanel->hide();
+    mInstallPanel->hide();
+    mRemovePanel->hide();
+    mInfoPanel->hide();
+    switch(button) {
+    case 0: mUpdatesPanel->show(); break;
+    case 1: mInstallPanel->show(); break;
+    case 2: mRemovePanel->show(); break;
+    case 3: mInfoPanel->show(); break;
+    default: mUpdatesPanel->show(); break;
+    }
+    return;
+}
+
+void MainWindow::toggleUpdatesNew() {
+    if (!mUpdatesNew->isVisible()) {
+        mUpdatesDetailsNew->setText(tr("Hide Details"));
+        mUpdatesNew->show();
+        mUpdatesNew->setSelected(0);
+    }
+    else {
+        mUpdatesNew->hide();
+        mUpdatesDetailsNew->setText(tr("Show Details"));
+        QSize old = mUpdatesWidget->size();
+        mUpdatesWidget->resize(old.width(), old.height() - mUpdatesNew->height());
+    }
+}
+
+void MainWindow::toggleUpdatesRemove() {
+    if (!mUpdatesRemove->isVisible()) {
+        mUpdatesDetailsRemove->setText(tr("Hide Details"));
+        mUpdatesRemove->show();
+        mUpdatesRemove->setSelected(0);
+    }
+    else {
+        mUpdatesRemove->hide();
+        mUpdatesDetailsRemove->setText(tr("Show Details"));
+        QSize old = mUpdatesWidget->size();
+        mUpdatesWidget->resize(old.width(), old.height() - mUpdatesRemove->height());
+    }
+}
+
+void MainWindow::toggleUpdatesManual() {
+    if (!mUpdatesManual->isVisible()) {
+        mUpdatesDetailsManual->setText(tr("Hide Details"));
+        mUpdatesManual->show();
+        mUpdatesManual->setSelected(0);
+    }
+    else {
+        mUpdatesDetailsManual->setText(tr("Show Details"));
+        mUpdatesManual->hide();
+        QSize old = mUpdatesWidget->size();
+        mUpdatesWidget->resize(old.width(), old.height() - mUpdatesManual->height());
+    }
+}
+>>>>>>> other
--- a/ui/mainwindow.h	Wed Jun 25 12:44:47 2014 +0200
+++ b/ui/mainwindow.h	Wed Jun 25 15:16:24 2014 +0200
@@ -22,14 +22,15 @@
 #include <QPushButton>
 #include <QLabel>
 #include <QCheckBox>
+#include <QScrollArea>
 
 #include "downloader.h"
 #include "certificatelist.h"
+#include "certificatelistwidget.h"
 class QMenu;
 class QAction;
 class QTimer;
 
-Q_DECLARE_METATYPE(Certificate);
 
 class MainWindow : public QMainWindow
 {
@@ -70,16 +71,17 @@
     void downloaderError(const QString &message, SSLConnection::ErrorCode error);
     /** @brief Trigger the appropiate action depending on the state */
     void messageClicked();
-    void showHelp();
-    void showAbout();
-    void showDetails(QListWidgetItem*);
-    void resizeButtons();
     void installerError(const QString& errMsg);
     void installerSuccess();
     void installCerts();
+    void toggleInManual(bool state, const Certificate &cert);
+    void removeFromManual(bool state, const Certificate &cert);
 
-    void saveAutoUpdate(int state);
-    void saveAutoStart(int state);
+    void togglePages(int button);
+    void toggleUpdatesNew();
+    void toggleUpdatesRemove();
+    void toggleUpdatesManual();
+    void listChanged(int selected);
 
     /** @brief check for running software that needs to close before installing
      *
@@ -117,7 +119,7 @@
      *
      * Returns false on error.
      */
-    bool saveUnselectedCertificates();
+    bool saveUnselectedCertificates(QStringList unselected);
 
     /** @brief loads previously unselected certificates from settings
      *
@@ -162,35 +164,9 @@
 
     void createTrayIcon();
     void createActions();
-    void createMenuBar();
     void createContent();
     void loadCertificateList();
 
-    /** @brief Create a separator item for the certificate list.
-     *
-     * The item uses a SeparatorItemDelegate for layout and styling at the given
-     * index.
-     *
-     * @param[in] text  The text for the item.
-     * @param[in] index The index of the item.
-     *
-     * @return The new separator item.
-     */
-    QListWidgetItem* createSeparator(const QString &text, int index);
-
-    /** @brief Create a certificate list item for the list.
-     *
-     * The item uses a CertificateItemDelegate for layout and styling.
-     *
-     * @param[in] text   The certificate to display.
-     * @param[in] status The certificate status.
-     * @param[in] index  The index of the item.
-     *
-     * @return The new separator item.
-     */
-    QListWidgetItem* createListItem(const Certificate &certificate,
-        Certificate::Status status, int index);
-
     /* Are we running in tray mode ?*/
     const bool mTrayMode;
     /* The message currently shown at intervals */
@@ -216,24 +192,32 @@
      * base64lines with I:/R: prefix */
     QStringList mPreviouslyUnselected;
 
-    QListWidget *mCertListWidget;
-
-    QLabel *mSubjectCN;
-    QLabel *mSubjectO;
-    QLabel *mIssuerCN;
-    QLabel *mIssuerO;
-    QLabel *mValidFrom;
-    QLabel *mValidTo;
-    QLabel *mFingerprint;
-
     QLabel *mCurrentListDate;
     QLabel *mNewListDate;
 
-    QCheckBox *mAutoUpdateOption;
-    QCheckBox *mAutoStartOption;
+    QButtonGroup *mButtonGroup;
+    QScrollArea *mUpdatesPanel;
+    QWidget *mUpdatesWidget;
+    QScrollArea *mInstallPanel;
+    QScrollArea *mRemovePanel;
+    QScrollArea *mInfoPanel;
 
-    QPushButton *installButton;
-    QPushButton *quitButton;
+    QLabel *mUpdatesHeader;
+    QLabel *mLastCertUpdate;
+    QLabel *mLastSWupdate;
+    QLabel *mUpdatesNewCertificates;
+    QLabel *mUpdatesRemoveCertificates;
+    QLabel *mUpdatesManualCertificates;
+
+    CertificateListWidget *mUpdatesNew;
+    CertificateListWidget *mUpdatesRemove;
+    CertificateListWidget *mUpdatesManual;
+    CertificateListWidget *mInstallList;
+    CertificateListWidget *mRemoveList;
+
+    QPushButton *mUpdatesDetailsNew;
+    QPushButton *mUpdatesDetailsRemove;
+    QPushButton *mUpdatesDetailsManual;
 };
 
 #endif // MAINWINDOW_H

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