aheinecke@404: /* Copyright (C) 2014 by Bundesamt für Sicherheit in der Informationstechnik aheinecke@404: * Software engineering by Intevation GmbH aheinecke@404: * aheinecke@404: * This file is Free Software under the GNU GPL (v>=2) aheinecke@404: * and comes with ABSOLUTELY NO WARRANTY! aheinecke@404: * See LICENSE.txt for details. aheinecke@404: */ aheinecke@0: #include "mainwindow.h" aheinecke@0: aheinecke@0: #include aheinecke@551: #include aheinecke@365: #include aheinecke@0: #include aheinecke@0: #include aheinecke@0: #include aheinecke@0: #include aheinecke@563: #include aheinecke@0: #include aheinecke@2: #include aheinecke@16: #include aheinecke@19: #include rrenkert@187: #include rrenkert@187: #include rrenkert@187: #include rrenkert@189: #include rrenkert@205: #include rrenkert@205: #include rrenkert@250: #include rrenkert@584: #include rrenkert@584: #include aheinecke@19: aheinecke@19: // The amount of time in minutes stay silent if we have aheinecke@19: // something to say aheinecke@548: #define NAG_INTERVAL_MINUTES 70 aheinecke@0: aheinecke@409: #ifndef APPNAME aheinecke@409: #define APPNAME "TrustBridge" aheinecke@409: #endif aheinecke@409: aheinecke@409: #define SERVER_URL "https://files.intevation.de:443" aheinecke@531: #define LIST_RESOURCE "/users/aheinecke/zertifikatsliste.txt" aheinecke@554: #define SW_RESOURCE "/users/aheinecke/TrustBridge.exe" rrenkert@486: #ifdef Q_OS_WIN aheinecke@554: #define SW_RESOURCE_VERSION "/users/aheinecke/TrustBridge-%1.exe" rrenkert@486: #else aheinecke@554: #define SW_RESOURCE_VERSION "/users/aheinecke/TrustBridge-%1.sh" rrenkert@486: #endif aheinecke@72: aheinecke@7: #include "certificatelist.h" aheinecke@10: #include "downloader.h" rrenkert@191: #include "helpdialog.h" rrenkert@200: #include "aboutdialog.h" rrenkert@267: #include "certificateitemdelegate.h" rrenkert@274: #include "separatoritemdelegate.h" aheinecke@365: #include "installwrapper.h" aheinecke@507: #include "util.h" aheinecke@551: #include "logging.h" aheinecke@7: aheinecke@365: MainWindow::MainWindow(bool trayMode): aheinecke@365: mTrayMode(trayMode) aheinecke@365: { aheinecke@0: createActions(); aheinecke@0: createTrayIcon(); rrenkert@187: createContent(); rrenkert@450: resize(950, 540); aheinecke@45: qRegisterMetaType("SSLConnection::ErrorCode"); rrenkert@265: qRegisterMetaType("Certificate::Status"); aheinecke@0: aheinecke@0: connect(mTrayIcon, SIGNAL(activated(QSystemTrayIcon::ActivationReason)), aheinecke@0: this, SLOT(iconActivated(QSystemTrayIcon::ActivationReason))); aheinecke@19: aheinecke@19: mMessageTimer = new QTimer(this); aheinecke@19: connect(mMessageTimer, SIGNAL(timeout()), this, SLOT(showMessage())); aheinecke@19: mMessageTimer->setInterval(NAG_INTERVAL_MINUTES * 60 * 1000); aheinecke@19: mMessageTimer->start(); aheinecke@71: checkUpdates(); andre@389: loadUnselectedCertificates(); andre@389: loadCertificateList(); aheinecke@365: if (!trayMode) { aheinecke@365: show(); aheinecke@365: } aheinecke@0: } aheinecke@0: aheinecke@0: void MainWindow::iconActivated(QSystemTrayIcon::ActivationReason reason) aheinecke@0: { aheinecke@0: switch (reason) { aheinecke@0: case QSystemTrayIcon::Trigger: aheinecke@0: case QSystemTrayIcon::MiddleClick: aheinecke@0: showMessage(); aheinecke@0: break; aheinecke@16: case QSystemTrayIcon::DoubleClick: aheinecke@365: show(); aheinecke@16: break; aheinecke@0: default: aheinecke@0: ; aheinecke@0: } aheinecke@0: } aheinecke@0: aheinecke@71: void MainWindow::messageClicked() aheinecke@71: { aheinecke@71: if (mCurState == NewListAvailable) { aheinecke@365: show(); aheinecke@71: } aheinecke@551: aheinecke@551: if (mCurState == NewSoftwareAvailable) { aheinecke@551: checkUpdates(true); aheinecke@551: mCurState = DownloadingSW; aheinecke@551: } aheinecke@71: } aheinecke@71: aheinecke@0: void MainWindow::showMessage() aheinecke@0: { aheinecke@365: if (!isVisible() && !mCurMessage.isEmpty()) { aheinecke@16: mTrayIcon->showMessage(QApplication::applicationName(), mCurMessage, aheinecke@16: QSystemTrayIcon::Information, 5000); aheinecke@19: mMessageTimer->start(); // Restart the timer so that we don't spam aheinecke@16: } aheinecke@0: } aheinecke@16: aheinecke@16: void MainWindow::verifyAvailableData() aheinecke@0: { andre@389: QString availableFileName = mSettings.value("List/available").toString(); andre@389: QString installedFileName = mSettings.value("List/installed").toString(); aheinecke@16: QString swFileName = mSettings.value("Software/available").toString(); aheinecke@16: andre@389: if (!availableFileName.isEmpty()) { andre@389: mListToInstall.readList(availableFileName.toLocal8Bit().constData()); aheinecke@71: if (!mListToInstall.isValid()) { aheinecke@82: mCurState = TransferError; aheinecke@16: // Probably a bug when Qt fileName is encoded and cFileName aheinecke@16: // fails because of this. This needs a unit test! aheinecke@16: // Maybe check that the file is in our data directory andre@389: QFile::remove(availableFileName); aheinecke@16: mSettings.remove("List/available"); aheinecke@16: mSettings.remove("List/availableDate"); aheinecke@16: } aheinecke@16: } else { aheinecke@16: // Make sure the available notation is also removed aheinecke@16: mSettings.remove("List/available"); aheinecke@16: mSettings.remove("List/availableDate"); aheinecke@16: } aheinecke@16: andre@389: if (!installedFileName.isEmpty()) { andre@389: mInstalledList.readList(installedFileName.toLocal8Bit().constData()); andre@389: if (!mInstalledList.isValid()) { andre@389: // Probably a bug when Qt fileName is encoded and cFileName andre@389: // fails because of this. This needs a unit test! andre@389: // Maybe check that the file is in our data directory andre@389: QFile::remove(installedFileName); andre@389: mSettings.remove("List/installed"); andre@389: mSettings.remove("List/installedDate"); andre@389: } andre@389: } else { andre@389: mSettings.remove("List/installed"); andre@389: mSettings.remove("List/installedDate"); andre@389: } andre@389: aheinecke@16: if (!swFileName.isEmpty()) { aheinecke@551: // TODO Verify integrity of the software aheinecke@16: } else { aheinecke@16: mSettings.remove("Software/available"); aheinecke@16: mSettings.remove("Software/availableDate"); aheinecke@16: } aheinecke@16: } aheinecke@16: aheinecke@16: void MainWindow::handleNewList(const QString& fileName, const QDateTime& modDate) { aheinecke@71: mSettings.setValue("List/available", fileName); aheinecke@71: mSettings.setValue("List/availableDate", modDate); aheinecke@16: aheinecke@71: verifyAvailableData(); aheinecke@71: if (!mListToInstall.isValid()) { aheinecke@71: /* Downloader provided invalid files */ aheinecke@71: /* TODO: Error count. Error handling. Otherwise aheinecke@71: * we can go into an endless loop here */ aheinecke@71: aheinecke@71: /* Retry the download again in 10 - 20 minutes */ aheinecke@71: QTimer::singleShot(600000 + (qrand() % 60000), this, SLOT(checkUpdates())); aheinecke@82: } else { aheinecke@82: mCurMessage = tr("An updated certificate list is available. Click here to install."); aheinecke@82: setState(NewListAvailable); aheinecke@82: showMessage(); rrenkert@189: loadCertificateList(); aheinecke@71: } aheinecke@16: } aheinecke@16: aheinecke@16: void MainWindow::handleNewSW(const QString& fileName, const QDateTime& modDate) { aheinecke@555: mCurMessage = tr("An update for %1 is available.\n" aheinecke@551: "Click here to download and install the update.").arg( aheinecke@16: QApplication::applicationName()); aheinecke@16: setState(NewSoftwareAvailable); aheinecke@16: mSettings.setValue("Software/available", fileName); aheinecke@16: mSettings.setValue("Software/availableDate", modDate); aheinecke@16: aheinecke@16: mSettings.sync(); aheinecke@16: showMessage(); aheinecke@16: } aheinecke@16: aheinecke@551: void MainWindow::installNewSW(const QString& fileName, const QDateTime& modDate) { aheinecke@551: QFileInfo instProcInfo = QFileInfo(fileName); aheinecke@551: if (!instProcInfo.isExecutable()) { aheinecke@551: qWarning() << "Downloaded file: " << fileName << " is not executable."; aheinecke@551: setState(TransferError); aheinecke@551: return; aheinecke@551: } aheinecke@563: QString filePath = QDir::toNativeSeparators(instProcInfo.absoluteFilePath()); aheinecke@551: #ifdef WIN32 aheinecke@551: SHELLEXECUTEINFOW shExecInfo; aheinecke@563: memset (&shExecInfo, 0, sizeof(SHELLEXECUTEINFOW)); aheinecke@563: shExecInfo.cbSize = sizeof(SHELLEXECUTEINFOW); aheinecke@563: aheinecke@563: shExecInfo.lpFile = reinterpret_cast (filePath.utf16()); aheinecke@563: aheinecke@563: shExecInfo.fMask = SEE_MASK_NOASYNC; aheinecke@551: aheinecke@551: if (!is_admin()) { aheinecke@551: shExecInfo.lpVerb = L"open"; aheinecke@551: } else { aheinecke@551: shExecInfo.lpVerb = L"runas"; aheinecke@551: } aheinecke@551: aheinecke@563: qDebug() << "Starting process: " << filePath; aheinecke@551: aheinecke@551: if (!ShellExecuteExW(&shExecInfo)) { aheinecke@551: /* Execution failed, maybe the user aborted the UAC check? */ aheinecke@551: char* errmsg = getLastErrorMsg(); aheinecke@551: QString qerrmsg = QString::fromUtf8(errmsg); aheinecke@551: free(errmsg); aheinecke@551: qDebug() << "Failed to start process: " << qerrmsg; aheinecke@551: setState(NewSoftwareAvailable); aheinecke@551: return; aheinecke@551: } aheinecke@551: #else /* WIN32 */ aheinecke@563: qDebug() << "Starting process " << filePath; aheinecke@551: aheinecke@563: if (!QProcess::startDetached(filePath)) { aheinecke@551: qDebug() << "Failed to start process."; aheinecke@551: return; aheinecke@551: } aheinecke@551: #endif aheinecke@551: /* Installer process should now be running. We exit */ aheinecke@551: aheinecke@551: closeApp(); aheinecke@551: } aheinecke@551: rrenkert@461: void MainWindow::checkUpdates(bool downloadSW) aheinecke@16: { aheinecke@16: verifyAvailableData(); aheinecke@16: aheinecke@551: if (!mSettings.contains("Software/installedDate") || aheinecke@551: mSettings.value("Software/installedVersion").toString() != QApplication::applicationVersion()) { aheinecke@551: /* This should only happen on initial startup and after an update has aheinecke@551: * been installed */ aheinecke@551: getLastModForCurrentVersion(); rrenkert@486: return; rrenkert@486: } aheinecke@17: QDateTime listInstalledLastMod = mSettings.value("List/installedDate").toDateTime(); aheinecke@17: QDateTime swInstalledLastMod = mSettings.value("Software/installedDate").toDateTime(); aheinecke@16: andre@389: QString listResource = QString::fromLatin1(LIST_RESOURCE); andre@389: QString swResource = QString::fromLatin1(SW_RESOURCE); andre@389: andre@389: #ifndef RELEASE_BUILD andre@389: /* Use this for testing to specify another file name for updates */ andre@389: listResource = mSettings.value("List/resource", listResource).toString(); andre@389: swResource = mSettings.value("Software/resource", swResource).toString(); andre@389: #endif andre@389: andre@389: aheinecke@72: Downloader* downloader = new Downloader(this, aheinecke@72: QString::fromLatin1(SERVER_URL), aheinecke@72: QByteArray(), aheinecke@551: swInstalledLastMod, aheinecke@72: listInstalledLastMod, aheinecke@437: swResource, rrenkert@461: listResource, rrenkert@461: downloadSW); aheinecke@17: aheinecke@16: connect(downloader, SIGNAL(newListAvailable(const QString&, const QDateTime&)), aheinecke@16: this, SLOT(handleNewList(const QString&, const QDateTime&))); rrenkert@461: if (!downloadSW) { rrenkert@461: connect(downloader, SIGNAL(newSoftwareAvailable(const QString&, const QDateTime&)), aheinecke@551: this, SLOT(handleNewSW(const QString&, const QDateTime&))); aheinecke@551: } else { aheinecke@551: connect(downloader, SIGNAL(newSoftwareAvailable(const QString&, const QDateTime&)), aheinecke@551: this, SLOT(installNewSW(const QString&, const QDateTime&))); rrenkert@461: } aheinecke@551: aheinecke@16: connect(downloader, SIGNAL(finished()), downloader, SLOT(deleteLater())); aheinecke@45: connect(downloader, SIGNAL(error(const QString &, SSLConnection::ErrorCode)), aheinecke@45: this, SLOT(downloaderError(const QString &, SSLConnection::ErrorCode))); aheinecke@10: downloader->start(); aheinecke@0: } aheinecke@0: aheinecke@551: void MainWindow::getLastModForCurrentVersion() rrenkert@486: { rrenkert@486: QString softwareVersion = QString::fromLatin1(SW_RESOURCE_VERSION).arg( rrenkert@486: QApplication::applicationVersion()); rrenkert@486: qDebug() << softwareVersion; rrenkert@486: QString listResource = QString::fromLatin1(LIST_RESOURCE); rrenkert@486: Downloader* downloader = new Downloader(this, rrenkert@486: QString::fromLatin1(SERVER_URL), rrenkert@486: QByteArray(), rrenkert@486: QDateTime::currentDateTime(), rrenkert@486: QDateTime::currentDateTime(), rrenkert@486: softwareVersion, rrenkert@486: listResource, rrenkert@486: false); rrenkert@486: connect(downloader, SIGNAL(finished()), downloader, SLOT(deleteLater())); rrenkert@486: connect(downloader, SIGNAL(error(const QString &, SSLConnection::ErrorCode)), rrenkert@486: this, SLOT(downloaderError(const QString &, SSLConnection::ErrorCode))); rrenkert@486: connect(downloader, SIGNAL(lastModifiedDate(const QDateTime&)), aheinecke@551: this, SLOT(setLastModifiedSWDate(const QDateTime&))); rrenkert@486: rrenkert@486: downloader->start(); rrenkert@486: } rrenkert@486: aheinecke@551: void MainWindow::setLastModifiedSWDate(const QDateTime &date) rrenkert@486: { rrenkert@486: mSettings.beginGroup("Software"); rrenkert@486: mSettings.setValue("installedDate", date); aheinecke@551: mSettings.setValue("installedVersion", QApplication::applicationVersion()); rrenkert@486: mSettings.endGroup(); rrenkert@486: checkUpdates(); rrenkert@486: } rrenkert@486: aheinecke@45: void MainWindow::downloaderError(const QString &message, SSLConnection::ErrorCode error) aheinecke@16: { aheinecke@551: /* TODO logging and handle error according to a plan */ aheinecke@16: mCurMessage = message; andre@27: showMessage(); aheinecke@551: setState(TransferError); aheinecke@16: } aheinecke@16: aheinecke@0: void MainWindow::createActions() aheinecke@0: { aheinecke@0: mCheckUpdates = new QAction(tr("Check for Updates"), this); aheinecke@16: connect(mCheckUpdates, SIGNAL(triggered()), this, SLOT(checkUpdates())); aheinecke@2: mQuitAction = new QAction(tr("Quit"), this); aheinecke@2: connect(mQuitAction, SIGNAL(triggered()), qApp, SLOT(quit())); aheinecke@0: } aheinecke@0: aheinecke@0: void MainWindow::createTrayIcon() aheinecke@0: { aheinecke@11: QIcon trayImg(":/img/tray_22.png"); aheinecke@0: aheinecke@0: mTrayMenu = new QMenu(this); aheinecke@0: mTrayMenu->addAction(mCheckUpdates); aheinecke@2: mTrayMenu->addAction(mQuitAction); aheinecke@0: aheinecke@0: mTrayIcon = new QSystemTrayIcon(this); aheinecke@0: mTrayIcon->setContextMenu(mTrayMenu); aheinecke@0: aheinecke@0: mTrayIcon->setIcon(trayImg); aheinecke@0: setWindowIcon(trayImg); aheinecke@0: mTrayIcon->show(); aheinecke@407: mTrayIcon->setToolTip(tr("TrustBridge")); aheinecke@71: aheinecke@71: connect(mTrayIcon, SIGNAL(messageClicked()), this, SLOT(messageClicked())); aheinecke@0: } rrenkert@155: rrenkert@187: void MainWindow::createContent() rrenkert@187: { rrenkert@187: // Create a central widget containing the main layout. rrenkert@187: QWidget *base = new QWidget; rrenkert@187: rrenkert@250: // Layouts and Container rrenkert@584: QVBoxLayout *mainLayout = new QVBoxLayout; rrenkert@205: QHBoxLayout *headerLayout = new QHBoxLayout; rrenkert@205: QVBoxLayout *headerTextLayout = new QVBoxLayout; rrenkert@584: QHBoxLayout *centerLayout = new QHBoxLayout; rrenkert@584: QVBoxLayout *buttonBarLayout = new QVBoxLayout; rrenkert@271: QHBoxLayout *bottomLayout = new QHBoxLayout; rrenkert@584: QHBoxLayout *containerLayout = new QHBoxLayout; rrenkert@584: QVBoxLayout *updatesPanelLayout = new QVBoxLayout; rrenkert@187: rrenkert@584: // The header (icon, about text) rrenkert@584: QImage *logoImage = new QImage(":/img/logo.png"); rrenkert@584: QLabel *logo = new QLabel; rrenkert@584: logo->setBackgroundRole(QPalette::Base); rrenkert@584: logo->setPixmap(QPixmap::fromImage(*logoImage)); rrenkert@584: QLabel *title = new QLabel("

" + QString::fromLatin1(APPNAME) + "

"); rrenkert@584: QLabel *subTitle = new QLabel("This Software installs and removes Certificates"); rrenkert@584: headerTextLayout->addWidget(title); rrenkert@584: headerTextLayout->addWidget(subTitle); rrenkert@584: headerLayout->addWidget(logo); rrenkert@584: headerLayout->addLayout(headerTextLayout); rrenkert@584: headerLayout->setStretch(0, 0); rrenkert@584: headerLayout->setStretch(1, 10); rrenkert@584: rrenkert@584: // Buttonbar rrenkert@584: mButtonGroup = new QButtonGroup; rrenkert@584: rrenkert@584: QToolButton *updatesButton = new QToolButton; rrenkert@584: updatesButton->setToolButtonStyle(Qt::ToolButtonTextUnderIcon); rrenkert@584: updatesButton->setIcon(QIcon(":/img/view-refresh.png")); rrenkert@584: updatesButton->setIconSize(QSize(32, 32)); rrenkert@584: updatesButton->setText(tr("Updates")); rrenkert@584: updatesButton->setFixedWidth(90); rrenkert@584: updatesButton->setFixedHeight(70); rrenkert@584: updatesButton->setCheckable(true); rrenkert@584: updatesButton->setChecked(true); rrenkert@584: rrenkert@584: QToolButton *allInstallButton = new QToolButton; rrenkert@584: allInstallButton->setToolButtonStyle(Qt::ToolButtonTextUnderIcon); rrenkert@584: allInstallButton->setIcon(QIcon(":/img/document-encrypt.png")); rrenkert@584: allInstallButton->setIconSize(QSize(32, 32)); rrenkert@584: allInstallButton->setText(tr("Trusted\nCertificates")); rrenkert@584: allInstallButton->setFixedWidth(90); rrenkert@584: allInstallButton->setFixedHeight(70); rrenkert@584: allInstallButton->setCheckable(true); rrenkert@584: rrenkert@584: QToolButton *allRemoveButton = new QToolButton; rrenkert@584: allRemoveButton->setToolButtonStyle(Qt::ToolButtonTextUnderIcon); rrenkert@584: allRemoveButton->setIcon(QIcon(":/img/task-attempt.png")); rrenkert@584: allRemoveButton->setIconSize(QSize(32, 32)); rrenkert@584: allRemoveButton->setText(tr("Insecure\nCertificates")); rrenkert@584: allRemoveButton->setFixedWidth(90); rrenkert@584: allRemoveButton->setFixedHeight(70); rrenkert@584: allRemoveButton->setCheckable(true); rrenkert@584: rrenkert@584: QToolButton *infoButton = new QToolButton; rrenkert@584: infoButton->setToolButtonStyle(Qt::ToolButtonTextUnderIcon); rrenkert@584: infoButton->setIcon(QIcon(":/img/dialog-information.png")); rrenkert@584: infoButton->setIconSize(QSize(32, 32)); rrenkert@584: infoButton->setText(tr("Information")); rrenkert@584: infoButton->setFixedWidth(90); rrenkert@584: infoButton->setFixedHeight(70); rrenkert@584: infoButton->setCheckable(true); rrenkert@584: rrenkert@584: mButtonGroup->addButton(updatesButton); rrenkert@584: mButtonGroup->addButton(allInstallButton); rrenkert@584: mButtonGroup->addButton(allRemoveButton); rrenkert@584: mButtonGroup->addButton(infoButton); rrenkert@584: mButtonGroup->setId(updatesButton, 0); rrenkert@584: mButtonGroup->setId(allInstallButton, 1); rrenkert@584: mButtonGroup->setId(allRemoveButton, 2); rrenkert@584: mButtonGroup->setId(infoButton, 3); rrenkert@584: rrenkert@584: connect(mButtonGroup, SIGNAL(buttonClicked(int)), rrenkert@584: this, SLOT(togglePages(int))); rrenkert@584: buttonBarLayout->addWidget(updatesButton); rrenkert@584: buttonBarLayout->addWidget(allInstallButton); rrenkert@584: buttonBarLayout->addWidget(allRemoveButton); rrenkert@584: buttonBarLayout->insertStretch(3, 10); rrenkert@584: buttonBarLayout->addWidget(infoButton); rrenkert@584: rrenkert@584: //The main panels. rrenkert@584: //The updates page. rrenkert@584: mUpdatesPanel = new QScrollArea; rrenkert@584: mUpdatesWidget = new QWidget; rrenkert@584: QHBoxLayout *updatesHeaderLayout = new QHBoxLayout; rrenkert@584: QVBoxLayout *updatesHeaderTextLayout = new QVBoxLayout; rrenkert@584: QVBoxLayout *updatesHeaderSettLayout = new QVBoxLayout; rrenkert@584: rrenkert@584: QLabel *updatesHeader = rrenkert@584: new QLabel("

" + tr("Updates (%1/%2)").arg(2).arg(4)+ "

"); rrenkert@584: QLabel *lastCertUpdate = rrenkert@584: new QLabel(tr("Last certificate update: %1").arg("today")); rrenkert@584: QLabel *lastSWupdate = rrenkert@584: new QLabel(tr("Last Software update: %1").arg("today")); rrenkert@584: updatesHeaderTextLayout->addWidget(updatesHeader); rrenkert@584: updatesHeaderTextLayout->addWidget(lastCertUpdate); rrenkert@584: updatesHeaderTextLayout->addWidget(lastSWupdate); rrenkert@584: rrenkert@584: QPushButton *searchUpdates = new QPushButton(tr("Search for Updates")); rrenkert@584: updatesHeaderSettLayout->insertStretch(0, 10); rrenkert@584: updatesHeaderSettLayout->addWidget(searchUpdates); rrenkert@584: updatesHeaderLayout->addLayout(updatesHeaderTextLayout); rrenkert@584: updatesHeaderLayout->insertStretch(1, 10); rrenkert@584: updatesHeaderLayout->addLayout(updatesHeaderSettLayout); rrenkert@584: rrenkert@584: QVBoxLayout *updatesCenterLayout = new QVBoxLayout; rrenkert@584: QHBoxLayout *updatesNewLayout = new QHBoxLayout; rrenkert@584: QHBoxLayout *updatesRemoveLayout = new QHBoxLayout; rrenkert@584: QHBoxLayout *updatesManualLayout = new QHBoxLayout; rrenkert@584: QLabel *updatesTip = rrenkert@584: new QLabel(tr("The following certificate changes are recommended.")); rrenkert@584: QLabel *updatesNewCertificates = rrenkert@584: new QLabel("

" + rrenkert@584: tr("Install new Certificates (%1/%2)").arg(2).arg(2) + rrenkert@584: "

"); rrenkert@584: QPushButton *updatesDetailsNew = new QPushButton(tr("Details")); rrenkert@584: connect(updatesDetailsNew, rrenkert@584: SIGNAL(clicked()), rrenkert@584: this, rrenkert@584: SLOT(toggleUpdatesNew())); rrenkert@584: updatesNewLayout->addWidget(updatesNewCertificates); rrenkert@584: updatesNewLayout->addWidget(updatesDetailsNew); rrenkert@584: updatesNewLayout->insertStretch(2, 10); rrenkert@584: mUpdatesNew = new CertificateListWidget(this); rrenkert@584: mUpdatesNew->hide(); rrenkert@584: rrenkert@584: QLabel *updatesRemoveCertificates = rrenkert@584: new QLabel("

" + rrenkert@584: tr("Remove insecure Certificates (%1/%2)").arg(2).arg(2) + rrenkert@584: "

"); rrenkert@584: QPushButton *updatesDetailsRemove = new QPushButton(tr("Details")); rrenkert@584: connect(updatesDetailsRemove, rrenkert@584: SIGNAL(clicked()), rrenkert@584: this, rrenkert@584: SLOT(toggleUpdatesRemove())); rrenkert@584: updatesRemoveLayout->addWidget(updatesRemoveCertificates); rrenkert@584: updatesRemoveLayout->addWidget(updatesDetailsRemove); rrenkert@584: updatesRemoveLayout->insertStretch(2, 10); rrenkert@584: mUpdatesRemove = new CertificateListWidget(this); rrenkert@584: mUpdatesRemove->hide(); rrenkert@584: rrenkert@584: QLabel *updatesManualCertificates = rrenkert@584: new QLabel("

" + rrenkert@584: tr("Manualy changed Certificates (%1)").arg(2) + rrenkert@584: "

"); rrenkert@584: QPushButton *updatesDetailsManual = new QPushButton(tr("Details")); rrenkert@584: connect(updatesDetailsManual, rrenkert@584: SIGNAL(clicked()), rrenkert@584: this, rrenkert@584: SLOT(toggleUpdatesManual())); rrenkert@584: updatesManualLayout->addWidget(updatesManualCertificates); rrenkert@584: updatesManualLayout->addWidget(updatesDetailsManual); rrenkert@584: updatesManualLayout->insertStretch(2, 10); rrenkert@584: mUpdatesManual = new CertificateListWidget(this); rrenkert@584: mUpdatesManual->hide(); rrenkert@584: rrenkert@584: updatesCenterLayout->addWidget(updatesTip); rrenkert@584: updatesCenterLayout->addLayout(updatesNewLayout); rrenkert@584: updatesCenterLayout->addWidget(mUpdatesNew); rrenkert@584: updatesCenterLayout->addLayout(updatesRemoveLayout); rrenkert@584: updatesCenterLayout->addWidget(mUpdatesRemove); rrenkert@584: updatesCenterLayout->addLayout(updatesManualLayout); rrenkert@584: updatesCenterLayout->addWidget(mUpdatesManual); rrenkert@584: rrenkert@584: QHBoxLayout *updatesBottomLayout = new QHBoxLayout; rrenkert@584: quitButton = new QPushButton(tr("Quit without saving")); rrenkert@584: QPushButton *saveButton = new QPushButton(tr("Update")); rrenkert@584: connect(quitButton, SIGNAL(clicked()), this, SLOT(closeApp())); rrenkert@584: updatesBottomLayout->insertStretch(0, 10); rrenkert@584: updatesBottomLayout->addWidget(saveButton); rrenkert@584: updatesBottomLayout->addWidget(quitButton); rrenkert@584: rrenkert@584: QFrame *updatesPanelSeparator = new QFrame(); rrenkert@584: updatesPanelSeparator->setFrameShape(QFrame::HLine); rrenkert@584: updatesPanelSeparator->setFrameShadow(QFrame::Sunken); rrenkert@584: updatesPanelLayout->addLayout(updatesHeaderLayout); rrenkert@584: updatesPanelLayout->addWidget(updatesPanelSeparator); rrenkert@584: updatesPanelLayout->addLayout(updatesCenterLayout); rrenkert@584: updatesPanelLayout->insertStretch(3, 10); rrenkert@584: updatesPanelLayout->addLayout(updatesBottomLayout); rrenkert@584: mUpdatesWidget->setLayout(updatesPanelLayout); rrenkert@584: mUpdatesWidget->setMinimumSize(QSize(820, 440)); rrenkert@584: mUpdatesPanel->setWidget(mUpdatesWidget); rrenkert@584: rrenkert@584: // Panel for trusted certificates. rrenkert@584: mInstallPanel = new QScrollArea; rrenkert@584: rrenkert@584: QVBoxLayout *installPanelLayout = new QVBoxLayout; rrenkert@584: QVBoxLayout *installHeaderLayout = new QVBoxLayout; rrenkert@584: QVBoxLayout *installCenterLayout = new QVBoxLayout; rrenkert@584: rrenkert@584: QLabel *installHeaderLabel = rrenkert@584: new QLabel("

" + tr("Trusted Certificates") + "

"); rrenkert@584: QLabel *installHeaderText = new QLabel(tr("The following list of root" rrenkert@584: " certificates was created by the BSI. The BSI vaidates authenticity," rrenkert@584: " security and actuality of these certificates")); rrenkert@584: installHeaderLayout->addWidget(installHeaderLabel); rrenkert@584: installHeaderLayout->addWidget(installHeaderText); rrenkert@584: rrenkert@584: QLabel *installCenterText = new QLabel(tr("Please choose the certificates" rrenkert@584: " you want to trust. TrustBridge will install these certificates for" rrenkert@584: " secure communication via email or the internet (e.g. IE, Firefox," rrenkert@584: " Thunderbird)")); rrenkert@584: installCenterLayout->addWidget(installCenterText); rrenkert@584: mInstallList = new CertificateListWidget(this); rrenkert@584: rrenkert@584: installPanelLayout->addLayout(installHeaderLayout); rrenkert@584: installPanelLayout->addLayout(installCenterLayout); rrenkert@584: installPanelLayout->addWidget(mInstallList); rrenkert@584: mInstallPanel->setLayout(installPanelLayout); rrenkert@584: rrenkert@584: // Panel for insecure certificates. rrenkert@584: mRemovePanel = new QScrollArea; rrenkert@584: QVBoxLayout *removePanelLayout = new QVBoxLayout; rrenkert@584: QVBoxLayout *removeHeaderLayout = new QVBoxLayout; rrenkert@584: QVBoxLayout *removeCenterLayout = new QVBoxLayout; rrenkert@584: rrenkert@584: QLabel *removeHeaderLabel = rrenkert@584: new QLabel("

" + tr("Insecure Certificates") + "

"); rrenkert@584: QLabel *removeHeaderText = new QLabel(tr("The following list of root" rrenkert@584: " certificates was created by the BSI. The BSI validates authenticity," rrenkert@584: " security and actuality of these certificates")); rrenkert@584: removeHeaderLayout->addWidget(removeHeaderLabel); rrenkert@584: removeHeaderLayout->addWidget(removeHeaderText); rrenkert@584: rrenkert@584: QLabel *removeCenterText = new QLabel(tr("Please choose the certificates" rrenkert@584: " you want to remove. TrustBridge will remove these certificates.")); rrenkert@584: removeCenterLayout->addWidget(removeCenterText); rrenkert@584: rrenkert@584: removePanelLayout->addLayout(removeHeaderLayout); rrenkert@584: removePanelLayout->addLayout(removeCenterLayout); rrenkert@584: mRemovePanel->setLayout(removePanelLayout); rrenkert@584: rrenkert@584: // Info panel. rrenkert@584: mInfoPanel = new QScrollArea; rrenkert@584: rrenkert@584: QVBoxLayout *infoPanelLayout = new QVBoxLayout(this); rrenkert@584: QHBoxLayout *infoHeaderLayout = new QHBoxLayout; rrenkert@584: QVBoxLayout *infoHeaderTextLayout = new QVBoxLayout; rrenkert@584: QVBoxLayout *infoCenterLayout = new QVBoxLayout; rrenkert@584: rrenkert@584: QImage *infoLogoImage = new QImage(":/img/logo.png"); rrenkert@584: QLabel *infoLogo = new QLabel; rrenkert@584: infoLogo->setBackgroundRole(QPalette::Base); rrenkert@584: infoLogo->setPixmap(QPixmap::fromImage(*infoLogoImage)); rrenkert@584: QLabel *infoTitle = new QLabel("

" + tr("TrustBridge") + "

"); rrenkert@584: QString infoVersion = tr("Version: "); rrenkert@584: infoVersion.append(QApplication::applicationVersion()); rrenkert@584: QLabel *appVersion = new QLabel(infoVersion); rrenkert@584: appVersion->setTextInteractionFlags( rrenkert@584: Qt::TextSelectableByMouse | rrenkert@584: Qt::TextSelectableByKeyboard); rrenkert@584: rrenkert@584: QFrame *infoHeaderSeparator = new QFrame(); rrenkert@584: infoHeaderSeparator->setFrameShape(QFrame::HLine); rrenkert@584: infoHeaderSeparator->setFrameShadow(QFrame::Sunken); rrenkert@584: rrenkert@584: infoHeaderTextLayout->addWidget(infoTitle); rrenkert@584: infoHeaderTextLayout->addWidget(appVersion); rrenkert@584: infoHeaderLayout->addWidget(infoLogo); rrenkert@584: infoHeaderLayout->addLayout(infoHeaderTextLayout); rrenkert@584: infoHeaderLayout->insertStretch(2, 10); rrenkert@584: rrenkert@584: QLabel *textDesc = new QLabel(tr("TrustBridge is a root certificate" rrenkert@584: " installer for Windows and Linux.")); rrenkert@584: textDesc->setTextInteractionFlags( rrenkert@584: Qt::TextSelectableByMouse | rrenkert@584: Qt::TextSelectableByKeyboard); rrenkert@584: QLabel *textManage = new QLabel(tr("The root certificate lists are managed" rrenkert@584: " by the German " rrenkert@584: "Federal Office for Information Security (BSI).\n\n")); rrenkert@584: textManage->setTextInteractionFlags( rrenkert@584: Qt::TextBrowserInteraction | rrenkert@584: Qt::TextSelectableByKeyboard); rrenkert@584: QLabel *textDevel = new QLabel(tr("The software was developed by the companies" rrenkert@584: " Intevation GmbH and " rrenkert@584: " DN-Systems GmbH,
" rrenkert@584: " contracted by the German Federal Office for Information Security (BSI).\n\n")); rrenkert@584: textDevel->setTextInteractionFlags( rrenkert@584: Qt::TextBrowserInteraction | rrenkert@584: Qt::TextSelectableByKeyboard); rrenkert@584: QLabel *textLicense = new QLabel(tr("TrustBridge is Free Software licensed" rrenkert@584: " under GNU GPL v2+.\n\nCopyright (C) 2014 by Bundesamt für Sicherheit" rrenkert@584: " in der Informationstechnik")); rrenkert@584: textLicense->setTextInteractionFlags( rrenkert@584: Qt::TextSelectableByMouse | rrenkert@584: Qt::TextSelectableByKeyboard); rrenkert@584: rrenkert@584: infoCenterLayout->addWidget(infoHeaderSeparator); rrenkert@584: infoCenterLayout->addWidget(textDesc); rrenkert@584: infoCenterLayout->addWidget(textManage); rrenkert@584: infoCenterLayout->addWidget(textDevel); rrenkert@584: infoCenterLayout->addWidget(textLicense); rrenkert@584: infoCenterLayout->insertSpacing(2, 10); rrenkert@584: infoCenterLayout->insertSpacing(4, 10); rrenkert@584: infoCenterLayout->insertSpacing(6, 10); rrenkert@584: infoCenterLayout->insertStretch(8, 10); rrenkert@584: rrenkert@584: infoPanelLayout->addLayout(infoHeaderLayout); rrenkert@584: infoPanelLayout->addLayout(infoCenterLayout); rrenkert@584: mInfoPanel->setLayout(infoPanelLayout); rrenkert@584: rrenkert@584: // The main layout for pages. rrenkert@584: mInstallPanel->hide(); rrenkert@584: mRemovePanel->hide(); rrenkert@584: mInfoPanel->hide(); rrenkert@584: containerLayout->addWidget(mUpdatesPanel); rrenkert@584: containerLayout->addWidget(mInstallPanel); rrenkert@584: containerLayout->addWidget(mRemovePanel); rrenkert@584: containerLayout->addWidget(mInfoPanel); rrenkert@584: rrenkert@584: centerLayout->addLayout(buttonBarLayout); rrenkert@584: centerLayout->addLayout(containerLayout); rrenkert@584: rrenkert@584: rrenkert@584: /* rrenkert@250: // The certificate list rrenkert@250: QGroupBox *certBox = new QGroupBox(tr("Managed Certificates")); aheinecke@365: mCertListWidget = new QListWidget; rrenkert@449: connect(mCertListWidget, SIGNAL(currentItemChanged(QListWidgetItem*, QListWidgetItem*)), rrenkert@250: this, SLOT(showDetails(QListWidgetItem*))); aheinecke@365: certLayout->addWidget(mCertListWidget); rrenkert@456: rrenkert@456: mCurrentListDate = new QLabel(tr("Current List Date: %1").arg("")); rrenkert@456: mNewListDate = new QLabel(""); rrenkert@456: listInfoLayout->addWidget(mCurrentListDate); rrenkert@456: listInfoLayout->addWidget(mNewListDate); rrenkert@456: certLayout->addLayout(listInfoLayout); rrenkert@456: rrenkert@250: certBox->setLayout(certLayout); rrenkert@250: rrenkert@205: rrenkert@271: // The settings. rrenkert@432: QGroupBox *settingsBox = new QGroupBox(tr("Settings")); rrenkert@432: mAutoUpdateOption = new QCheckBox(tr("Autoupdate")); rrenkert@432: mAutoStartOption = new QCheckBox(tr("Autostart")); rrenkert@432: settingsLayout->addWidget(mAutoUpdateOption); rrenkert@432: settingsLayout->addWidget(mAutoStartOption); rrenkert@432: settingsBox->setLayout(settingsLayout); rrenkert@481: connect(mAutoUpdateOption, SIGNAL(stateChanged(int)), rrenkert@481: this, SLOT(saveAutoUpdate(int))); rrenkert@481: connect(mAutoStartOption, SIGNAL(stateChanged(int)), rrenkert@481: this, SLOT(saveAutoStart(int))); rrenkert@481: mSettings.beginGroup("settings"); aheinecke@499: bool autoUpdate = mSettings.value("autoupdate", false).toBool(); aheinecke@499: bool autoStart = mSettings.value("autostart", true).toBool(); rrenkert@481: mSettings.endGroup(); aheinecke@499: mAutoUpdateOption->setCheckState(autoUpdate ? Qt::Checked : Qt::Unchecked); aheinecke@499: mAutoStartOption->setCheckState(autoStart ? Qt::Checked : Qt::Unchecked); rrenkert@481: rrenkert@271: aheinecke@507: #ifdef Q_OS_WIN aheinecke@507: if (is_admin()) { aheinecke@507: QIcon uacShield = QApplication::style()->standardIcon(QStyle::SP_VistaShield); aheinecke@507: installButton->setIcon(uacShield); aheinecke@507: } aheinecke@507: #endif aheinecke@507: rrenkert@250: // The certificate details rrenkert@271: QGroupBox *detailBox = new QGroupBox(tr("Details")); rrenkert@432: QLabel *subjectCN = new QLabel(tr("Subject Common Name:")); rrenkert@432: QLabel *subjectOU = new QLabel(tr("Subject Organisation:")); rrenkert@432: QLabel *issuerCN = new QLabel(tr("Issuer Common Name:")); rrenkert@432: QLabel *issuerOU = new QLabel(tr("Issuer Organisation:")); rrenkert@432: QLabel *validFrom = new QLabel(tr("Valid from:")); rrenkert@432: QLabel *validTo = new QLabel(tr("Valid to:")); rrenkert@432: QLabel *fingerprint = new QLabel(tr("Fingerprint:")); rrenkert@432: detailLabelLayout->addWidget(subjectCN); rrenkert@432: detailLabelLayout->addWidget(subjectOU); rrenkert@432: detailLabelLayout->addWidget(issuerCN); rrenkert@432: detailLabelLayout->addWidget(issuerOU); rrenkert@432: detailLabelLayout->addWidget(validFrom); rrenkert@432: detailLabelLayout->addWidget(validTo); rrenkert@432: detailLabelLayout->addWidget(fingerprint); rrenkert@432: mSubjectCN = new QLabel(tr("")); aheinecke@531: mSubjectO = new QLabel(tr("")); rrenkert@432: mIssuerCN = new QLabel(tr("")); aheinecke@531: mIssuerO = new QLabel(tr("")); rrenkert@432: mValidFrom = new QLabel(tr("")); rrenkert@432: mValidTo = new QLabel(tr("")); rrenkert@432: mFingerprint = new QLabel(tr("")); rrenkert@451: mFingerprint->setFont(QFont("DejaVu Sans Mono")); rrenkert@432: detailContentLayout->addWidget(mSubjectCN); aheinecke@531: detailContentLayout->addWidget(mSubjectO); rrenkert@432: detailContentLayout->addWidget(mIssuerCN); aheinecke@531: detailContentLayout->addWidget(mIssuerO); rrenkert@432: detailContentLayout->addWidget(mValidFrom); rrenkert@432: detailContentLayout->addWidget(mValidTo); rrenkert@432: detailContentLayout->addWidget(mFingerprint); rrenkert@432: detailLayout->addLayout(detailLabelLayout); rrenkert@432: detailLayout->addLayout(detailContentLayout); rrenkert@271: detailBox->setLayout(detailLayout); rrenkert@187: rrenkert@250: infoLayout->addSpacing(20); rrenkert@250: infoLayout->addLayout(headerLayout); rrenkert@584: //infoLayout->addWidget(detailBox); rrenkert@584: //infoLayout->addWidget(settingsBox); rrenkert@271: infoLayout->addLayout(bottomLayout); rrenkert@250: rrenkert@584: //mainLayout->addWidget(certBox); rrenkert@250: mainLayout->addLayout(infoLayout); rrenkert@450: mainLayout->setStretchFactor(certBox, 37); rrenkert@450: mainLayout->setStretchFactor(infoLayout, 63); rrenkert@187: rrenkert@187: // QMainWindow allready has a layout. All child layouts and widgets are rrenkert@187: // managed in the central widget. rrenkert@584: */ rrenkert@584: rrenkert@584: QFrame *topSeparator = new QFrame(); rrenkert@584: topSeparator->setFrameShape(QFrame::HLine); rrenkert@584: topSeparator->setFrameShadow(QFrame::Sunken); rrenkert@584: rrenkert@584: mainLayout->addLayout(headerLayout); rrenkert@584: mainLayout->addWidget(topSeparator); rrenkert@584: mainLayout->addLayout(centerLayout); rrenkert@584: mainLayout->addLayout(bottomLayout); rrenkert@187: base->setLayout(mainLayout); rrenkert@187: setCentralWidget(base); rrenkert@187: } rrenkert@187: rrenkert@189: void MainWindow::loadCertificateList() rrenkert@189: { rrenkert@584: //mCertListWidget->clear(); rrenkert@584: //int i = 0; andre@389: andre@389: /* TODO: if nothing is available (neither old nor new) add some progress andre@389: * indication */ rrenkert@445: QList newInstallCerts; rrenkert@445: QList newRemoveCerts; rrenkert@445: QList oldInstallCerts; rrenkert@445: QList oldRemoveCerts; andre@389: rrenkert@445: if (mListToInstall.getCertificates().isEmpty()) { rrenkert@445: // No new list available, add old certificates. rrenkert@445: foreach (const Certificate &cert, mInstalledList.getCertificates()) { rrenkert@445: if (cert.isInstallCert()) { rrenkert@445: oldInstallCerts.append(cert); rrenkert@584: mInstallList->addCertificate(cert); rrenkert@267: } rrenkert@267: else { rrenkert@445: oldRemoveCerts.append(cert); rrenkert@267: } rrenkert@267: } rrenkert@456: // Set the date of the old list. rrenkert@456: mCurrentListDate->setText(tr("Current List Date: %1") rrenkert@456: .arg(mInstalledList.date().toString())); rrenkert@445: } rrenkert@445: else { rrenkert@445: // Sort and filter both lists. rrenkert@445: foreach (const Certificate &cert, mListToInstall.getCertificates()) { rrenkert@445: if (cert.isInstallCert()) { rrenkert@445: // Certificate with status "install". rrenkert@445: if (mInstalledList.getCertificates().contains(cert)) { rrenkert@445: // Was in the old list. rrenkert@445: oldInstallCerts.append(cert); rrenkert@445: } rrenkert@445: else { rrenkert@445: // Is a brand new certificate rrenkert@445: newInstallCerts.append(cert); rrenkert@584: mUpdatesNew->addCertificate(cert); rrenkert@445: } rrenkert@267: } rrenkert@267: else { rrenkert@445: // Certificate with status "remove". rrenkert@445: if (mInstalledList.getCertificates().contains(cert)) { rrenkert@445: // Was in the old list. rrenkert@445: oldRemoveCerts.append(cert); rrenkert@445: } rrenkert@445: else { rrenkert@445: // Was in the old list with status "install" and now has the rrenkert@445: // status "remove". rrenkert@445: newRemoveCerts.append(cert); rrenkert@445: } rrenkert@267: } rrenkert@267: } rrenkert@584: /* mCurrentListDate->setText(tr("Current List Date: %1") rrenkert@456: .arg(mInstalledList.date().toString())); rrenkert@584: mNewListDate->setText(tr("New List Date: %1").arg(mListToInstall.date().toString()));*/ rrenkert@189: } rrenkert@584: /* rrenkert@445: // Add separators and certificates to list widget. aheinecke@512: if (!newInstallCerts.isEmpty()) { aheinecke@512: mCertListWidget->addItem(createSeparator(tr("New certificates to install"), i++)); aheinecke@512: foreach (const Certificate &cert, newInstallCerts) { aheinecke@512: mCertListWidget->addItem(createListItem(cert, Certificate::InstallNew, i++)); aheinecke@512: } rrenkert@445: } rrenkert@445: aheinecke@512: if (!newRemoveCerts.isEmpty()) { aheinecke@512: mCertListWidget->addItem(createSeparator(tr("New certificates to remove"), i++)); aheinecke@512: foreach (const Certificate &cert, newRemoveCerts) { aheinecke@512: mCertListWidget->addItem(createListItem(cert, Certificate::RemoveNew, i++)); aheinecke@512: } rrenkert@445: } rrenkert@445: aheinecke@512: if (!oldInstallCerts.isEmpty()) { aheinecke@512: mCertListWidget->addItem(createSeparator(tr("Old certificates to install"), i++)); aheinecke@512: foreach (const Certificate &cert, oldInstallCerts) { aheinecke@512: mCertListWidget->addItem(createListItem(cert, Certificate::InstallOld, i++)); aheinecke@512: } rrenkert@445: } rrenkert@445: aheinecke@512: if (!oldRemoveCerts.isEmpty()) { aheinecke@512: mCertListWidget->addItem(createSeparator(tr("Old certificates to remove"), i++)); aheinecke@512: foreach (const Certificate &cert, oldRemoveCerts) { aheinecke@512: mCertListWidget->addItem(createListItem(cert, Certificate::RemoveOld, i++)); aheinecke@512: } rrenkert@445: } rrenkert@584: */ rrenkert@445: } rrenkert@445: rrenkert@445: QListWidgetItem* MainWindow::createSeparator(const QString &text, int index) rrenkert@445: { rrenkert@445: SeparatorItemDelegate *separatorDelegate = new SeparatorItemDelegate(); rrenkert@445: QListWidgetItem *separator = new QListWidgetItem(text); rrenkert@445: mCertListWidget->setItemDelegateForRow(index, separatorDelegate); rrenkert@445: separator->setFlags(separator->flags() ^ Qt::ItemIsUserCheckable); rrenkert@445: return separator; rrenkert@445: } rrenkert@445: rrenkert@445: QListWidgetItem* MainWindow::createListItem(const Certificate &certificate, rrenkert@445: Certificate::Status status, int index) rrenkert@445: { rrenkert@445: CertificateItemDelegate *certDelegate = new CertificateItemDelegate(); rrenkert@445: QListWidgetItem* item = new QListWidgetItem(certificate.shortDescription()); rrenkert@445: item->setData(CertificateItemDelegate::DataRole, rrenkert@445: QVariant::fromValue(certificate)); rrenkert@445: item->setData(CertificateItemDelegate::StatusRole, status); rrenkert@445: if (!mPreviouslyUnselected.contains(certificate.base64Line()) && rrenkert@445: status == Certificate::RemoveOld) { rrenkert@445: item->setFlags(item->flags() ^ Qt::ItemIsUserCheckable); rrenkert@445: } rrenkert@445: else { rrenkert@445: Qt::CheckState checkedState = rrenkert@445: mPreviouslyUnselected.contains(certificate.base64Line()) ? rrenkert@445: Qt::Unchecked : Qt::Checked; rrenkert@445: item->setFlags(item->flags() | Qt::ItemIsUserCheckable); rrenkert@445: item->setCheckState(checkedState); rrenkert@445: } rrenkert@445: mCertListWidget->setItemDelegateForRow(index, certDelegate); rrenkert@445: return item; rrenkert@189: } rrenkert@189: rrenkert@155: void MainWindow::showHelp() rrenkert@155: { rrenkert@155: qDebug() << "show helpdialog"; rrenkert@191: HelpDialog *help = new HelpDialog(this); rrenkert@191: help->show(); rrenkert@155: } rrenkert@155: rrenkert@155: void MainWindow::showAbout() rrenkert@155: { rrenkert@155: qDebug() << "show aboutdialog"; rrenkert@200: AboutDialog *about = new AboutDialog(this); rrenkert@200: about->show(); rrenkert@155: } rrenkert@187: rrenkert@189: void MainWindow::showDetails(QListWidgetItem *item) rrenkert@189: { rrenkert@449: if (item == NULL) { rrenkert@449: return; rrenkert@449: } rrenkert@445: Certificate cert = item->data(CertificateItemDelegate::DataRole).value(); rrenkert@432: mSubjectCN->setText(cert.subjectCN()); aheinecke@531: mSubjectO->setText(cert.subjectO()); rrenkert@432: mIssuerCN->setText(cert.issuerCN()); aheinecke@531: mIssuerO->setText(cert.issuerO()); rrenkert@432: mValidFrom->setText(cert.validFrom().toString()); rrenkert@432: mValidTo->setText(cert.validTo().toString()); rrenkert@432: mFingerprint->setText(cert.fingerprint()); rrenkert@189: } rrenkert@271: rrenkert@271: void MainWindow::resizeButtons() rrenkert@271: { rrenkert@271: installButton->setFixedHeight(20); rrenkert@271: quitButton->setFixedHeight(80); rrenkert@271: } aheinecke@365: aheinecke@365: void MainWindow::installerError(const QString& errMsg) { aheinecke@365: QMessageBox::warning(this, tr("Error executing update"), errMsg); aheinecke@365: } aheinecke@365: andre@389: void MainWindow::installerSuccess() { andre@389: if (mCurState == NewListAvailable) { andre@389: mCurState = NothingChanged; andre@389: mCurMessage = QString(); andre@389: andre@389: QString listFileName = mSettings.value("List/available").toString(); andre@389: QDateTime listFileDate = mSettings.value("List/availableDate").toDateTime(); andre@389: andre@389: mSettings.remove("List/available"); andre@389: mSettings.remove("List/availableDate"); andre@389: andre@389: if (listFileName.isEmpty() || !listFileDate.isValid()) { andre@389: qWarning() << "Error accessing settings"; andre@389: return; /* Try again with next check */ andre@389: } andre@389: andre@389: mSettings.setValue("List/installed", listFileName); andre@389: mSettings.setValue("List/installedDate", listFileDate); rrenkert@480: mInstalledList = mListToInstall; rrenkert@480: mListToInstall = CertificateList(); andre@389: } rrenkert@584: //loadCertificateList(); andre@389: } andre@389: aheinecke@365: void MainWindow::installCerts() { aheinecke@365: QStringList choices; aheinecke@365: aheinecke@365: for (int i = 0; i < mCertListWidget->count(); i++) { aheinecke@365: QListWidgetItem *item = mCertListWidget->item(i); aheinecke@365: if (item->checkState() == Qt::Checked) { rrenkert@445: choices << item->data(CertificateItemDelegate::DataRole).value().base64Line(); aheinecke@365: continue; aheinecke@365: } rrenkert@445: QString certLine = item->data(CertificateItemDelegate::DataRole).value().base64Line(); aheinecke@365: if (certLine.startsWith("I:")) { aheinecke@365: certLine[0] = 'R'; aheinecke@365: choices << certLine; aheinecke@365: } aheinecke@365: } aheinecke@365: aheinecke@365: QProgressDialog *progress = new QProgressDialog(this); aheinecke@365: progress->setWindowModality(Qt::WindowModal); aheinecke@365: progress->setLabelText(tr("Installing certificates...")); aheinecke@365: progress->setCancelButton(0); aheinecke@365: progress->setRange(0,0); aheinecke@365: progress->setMinimumDuration(0); aheinecke@365: progress->show(); aheinecke@365: aheinecke@365: InstallWrapper *instWrap = new InstallWrapper(this, andre@393: mListToInstall.isValid() ? andre@393: mListToInstall.fileName() : andre@393: mInstalledList.fileName(), aheinecke@365: choices); aheinecke@365: /* Clean up object and progress dialog */ aheinecke@365: connect(instWrap, SIGNAL(finished()), instWrap, SLOT(deleteLater())); aheinecke@365: connect(instWrap, SIGNAL(finished()), progress, SLOT(deleteLater())); aheinecke@365: connect(instWrap, SIGNAL(finished()), progress, SLOT(cancel())); andre@389: connect(instWrap, SIGNAL(installationSuccessful()), andre@389: this, SLOT(installerSuccess())); aheinecke@365: connect(instWrap, SIGNAL(error(const QString &)), andre@389: this, SLOT(installerError(const QString &))); aheinecke@365: instWrap->start(); rrenkert@584: /* andre@372: if (!saveUnselectedCertificates()) { andre@372: qWarning() << "Failed to save previosly unselected certificates."; andre@372: } rrenkert@584: */ aheinecke@365: } andre@372: andre@372: void MainWindow::loadUnselectedCertificates() andre@372: { andre@372: mPreviouslyUnselected.clear(); andre@372: mSettings.beginGroup("unselected"); andre@372: QStringList keys = mSettings.allKeys(); andre@372: foreach (const QString &key, keys) { andre@372: mPreviouslyUnselected << mSettings.value(key, QString()).toString(); andre@372: } andre@372: mSettings.endGroup(); andre@372: } andre@372: andre@372: bool MainWindow::saveUnselectedCertificates() andre@372: { rrenkert@479: mPreviouslyUnselected.clear(); andre@372: mSettings.beginGroup("unselected"); andre@372: mSettings.remove(""); /* Clears old choices */ andre@372: for (int i = 0; i < mCertListWidget->count(); i++) { andre@372: QListWidgetItem *item = mCertListWidget->item(i); rrenkert@446: if (item->checkState() != Qt::Checked && rrenkert@446: (item->flags() & Qt::ItemIsUserCheckable)) { rrenkert@479: QString key = QString::fromLatin1("cert%1").arg(i); rrenkert@479: QString value = rrenkert@479: item->data(CertificateItemDelegate::DataRole).value().base64Line(); rrenkert@479: mSettings.setValue(key, value); rrenkert@479: mPreviouslyUnselected << value; andre@372: } andre@372: } andre@372: mSettings.endGroup(); andre@372: mSettings.sync(); andre@372: return mSettings.status() == QSettings::NoError; andre@372: } rrenkert@447: rrenkert@481: void MainWindow::saveAutoUpdate(int state) rrenkert@481: { rrenkert@481: mSettings.beginGroup("settings"); aheinecke@499: mSettings.setValue("autoupdate", state != Qt::Unchecked); rrenkert@481: mSettings.endGroup(); rrenkert@481: } rrenkert@481: rrenkert@481: void MainWindow::saveAutoStart(int state) rrenkert@481: { rrenkert@481: mSettings.beginGroup("settings"); aheinecke@499: mSettings.setValue("autostart", state != Qt::Unchecked); rrenkert@481: mSettings.endGroup(); rrenkert@481: } rrenkert@481: rrenkert@447: void MainWindow::closeApp() rrenkert@447: { rrenkert@584: //saveUnselectedCertificates(); rrenkert@447: qApp->quit(); rrenkert@447: } rrenkert@584: rrenkert@584: void MainWindow::togglePages(int button) rrenkert@584: { rrenkert@584: mUpdatesPanel->hide(); rrenkert@584: mInstallPanel->hide(); rrenkert@584: mRemovePanel->hide(); rrenkert@584: mInfoPanel->hide(); rrenkert@584: switch(button) { rrenkert@584: case 0: mUpdatesPanel->show(); break; rrenkert@584: case 1: mInstallPanel->show(); break; rrenkert@584: case 2: mRemovePanel->show(); break; rrenkert@584: case 3: mInfoPanel->show(); break; rrenkert@584: default: mUpdatesPanel->show(); break; rrenkert@584: } rrenkert@584: return; rrenkert@584: } rrenkert@584: rrenkert@584: void MainWindow::toggleUpdatesNew() { rrenkert@584: QSize old = mUpdatesWidget->size(); rrenkert@584: if (!mUpdatesNew->isVisible()) { rrenkert@584: mUpdatesWidget->resize(old.width(), old.height() + mUpdatesNew->height()); rrenkert@584: mUpdatesNew->show(); rrenkert@584: } rrenkert@584: else { rrenkert@584: mUpdatesWidget->resize(old.width(), old.height() - mUpdatesNew->height()); rrenkert@584: mUpdatesNew->hide(); rrenkert@584: } rrenkert@584: } rrenkert@584: rrenkert@584: void MainWindow::toggleUpdatesRemove() { rrenkert@584: QSize old = mUpdatesWidget->size(); rrenkert@584: if (!mUpdatesRemove->isVisible()) { rrenkert@584: mUpdatesWidget->resize(old.width(), old.height() + mUpdatesRemove->height()); rrenkert@584: mUpdatesRemove->show(); rrenkert@584: } rrenkert@584: else { rrenkert@584: mUpdatesWidget->resize(old.width(), old.height() - mUpdatesRemove->height()); rrenkert@584: mUpdatesRemove->hide(); rrenkert@584: } rrenkert@584: } rrenkert@584: rrenkert@584: void MainWindow::toggleUpdatesManual() { rrenkert@584: QSize old = mUpdatesWidget->size(); rrenkert@584: if (!mUpdatesManual->isVisible()) { rrenkert@584: mUpdatesWidget->resize(old.width(), old.height() + mUpdatesManual->height()); rrenkert@584: mUpdatesManual->show(); rrenkert@584: } rrenkert@584: else { rrenkert@584: mUpdatesManual->hide(); rrenkert@584: mUpdatesWidget->resize(old.width(), old.height() - mUpdatesManual->height()); rrenkert@584: } rrenkert@584: }