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@365: #include aheinecke@0: #include aheinecke@0: #include aheinecke@0: #include aheinecke@0: #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 aheinecke@19: aheinecke@19: // The amount of time in minutes stay silent if we have aheinecke@19: // something to say aheinecke@365: #define NAG_INTERVAL_MINUTES 60 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@409: #define LIST_RESOURCE "/users/aheinecke/zertifikatsliste_1.txt" aheinecke@409: #define SW_RESOURCE "/users/aheinecke/zertifikatsliste_1.txt" aheinecke@72: aheinecke@7: #include "certificatelist.h" aheinecke@10: #include "downloader.h" rrenkert@191: #include "helpdialog.h" rrenkert@200: #include "aboutdialog.h" rrenkert@212: #include "statusdialog.h" rrenkert@267: #include "certificateitemdelegate.h" rrenkert@274: #include "separatoritemdelegate.h" aheinecke@365: #include "installwrapper.h" aheinecke@7: aheinecke@365: MainWindow::MainWindow(bool trayMode): aheinecke@365: mTrayMode(trayMode) aheinecke@365: { aheinecke@0: createActions(); aheinecke@0: createTrayIcon(); rrenkert@155: createMenuBar(); rrenkert@187: createContent(); rrenkert@434: resize(900, 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@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: // Make sure the available notation is also removed andre@389: mSettings.remove("List/installed"); andre@389: mSettings.remove("List/installedDate"); andre@389: } andre@389: aheinecke@16: if (!swFileName.isEmpty()) { aheinecke@16: // TODO 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@16: mCurMessage = tr("An update for %1 is available. Click here to install.").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@16: void MainWindow::checkUpdates() aheinecke@16: { aheinecke@16: verifyAvailableData(); aheinecke@16: 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@72: QDateTime::currentDateTime(), andre@389: // TODO swInstalledLastMod, aheinecke@72: listInstalledLastMod, aheinecke@437: swResource, aheinecke@437: listResource); aheinecke@17: aheinecke@16: connect(downloader, SIGNAL(newListAvailable(const QString&, const QDateTime&)), aheinecke@16: this, SLOT(handleNewList(const QString&, const QDateTime&))); aheinecke@16: connect(downloader, SIGNAL(newSoftwareAvailable(const QString&, const QDateTime&)), aheinecke@16: this, SLOT(handleNewSW(const QString&, const QDateTime&))); 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@16: aheinecke@45: void MainWindow::downloaderError(const QString &message, SSLConnection::ErrorCode error) aheinecke@16: { aheinecke@16: mCurMessage = message; andre@27: showMessage(); aheinecke@16: } 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@155: void MainWindow::createMenuBar() rrenkert@155: { rrenkert@155: mMenuBar = new QMenuBar(this); rrenkert@155: QMenu *mMenu = new QMenu(tr("Menu"), mMenuBar); rrenkert@155: mMenuBar->addMenu(mMenu); rrenkert@155: QAction *update = mMenu->addAction(tr("Force Update")); rrenkert@155: QAction *settings = mMenu->addAction(tr("Settings")); rrenkert@212: QAction *status = mMenu->addAction(tr("Statusdialog")); rrenkert@155: mMenu->addSeparator(); rrenkert@155: QAction *help = mMenu->addAction(tr("Help")); rrenkert@155: QAction *about = mMenu->addAction(tr("About")); rrenkert@155: mMenu->addSeparator(); rrenkert@155: QAction *quit = mMenu->addAction(tr("Quit")); rrenkert@155: connect(update, SIGNAL(triggered()), this, SLOT(checkUpdates())); rrenkert@155: connect(settings, SIGNAL(triggered()), this, SLOT(showSettings())); rrenkert@212: connect(status, SIGNAL(triggered()), this, SLOT(showStatus())); rrenkert@155: connect(help, SIGNAL(triggered()), this, SLOT(showHelp())); rrenkert@155: connect(about, SIGNAL(triggered()), this, SLOT(showAbout())); rrenkert@155: connect(quit, SIGNAL(triggered()), qApp, SLOT(quit())); rrenkert@155: setMenuBar(mMenuBar); rrenkert@155: } 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@250: QHBoxLayout *mainLayout = new QHBoxLayout; rrenkert@250: QVBoxLayout *infoLayout = new QVBoxLayout; rrenkert@250: QVBoxLayout *certLayout = new QVBoxLayout; rrenkert@432: QHBoxLayout *detailLayout = new QHBoxLayout; rrenkert@432: QVBoxLayout *detailLabelLayout = new QVBoxLayout; rrenkert@432: QVBoxLayout *detailContentLayout = new QVBoxLayout; rrenkert@205: QHBoxLayout *headerLayout = new QHBoxLayout; rrenkert@205: QVBoxLayout *headerTextLayout = new QVBoxLayout; rrenkert@271: QHBoxLayout *bottomLayout = new QHBoxLayout; rrenkert@432: QVBoxLayout *settingsLayout = new QVBoxLayout; rrenkert@187: rrenkert@250: // The certificate list rrenkert@250: QGroupBox *certBox = new QGroupBox(tr("Managed Certificates")); aheinecke@365: mCertListWidget = new QListWidget; aheinecke@365: connect(mCertListWidget, SIGNAL(itemClicked(QListWidgetItem*)), rrenkert@250: this, SLOT(showDetails(QListWidgetItem*))); aheinecke@365: certLayout->addWidget(mCertListWidget); rrenkert@250: certBox->setLayout(certLayout); rrenkert@250: rrenkert@250: // The header (icon, about text) rrenkert@205: QImage *logoImage = new QImage(":/img/logo.png"); rrenkert@205: QLabel *logo = new QLabel; rrenkert@205: logo->setBackgroundRole(QPalette::Base); rrenkert@205: logo->setPixmap(QPixmap::fromImage(*logoImage)); aheinecke@409: QLabel *title = new QLabel("

" + QString::fromLatin1(APPNAME) + "

"); rrenkert@205: QLabel *subTitle = new QLabel("This Software installs and removes Certificates"); rrenkert@205: headerTextLayout->addWidget(title); rrenkert@205: headerTextLayout->addWidget(subTitle); rrenkert@205: headerLayout->addWidget(logo); rrenkert@205: headerLayout->addLayout(headerTextLayout); rrenkert@210: headerLayout->setStretch(0, 0); rrenkert@210: headerLayout->setStretch(1, 10); 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@250: // connect(autoUpdateOption, SIGNAL(stateChanged()), this, SLOT(setAutoUpdate())); rrenkert@271: rrenkert@271: // The buttons. rrenkert@271: bottomLayout->setAlignment(Qt::AlignBottom); rrenkert@271: installButton = new QPushButton(tr("Install selected")); rrenkert@271: installButton->setFixedHeight(80); rrenkert@271: connect(installButton, SIGNAL(clicked()), this, SLOT(resizeButtons())); aheinecke@365: connect(installButton, SIGNAL(clicked()), this, SLOT(installCerts())); rrenkert@271: quitButton = new QPushButton(tr("Quit")); rrenkert@271: quitButton->setFixedHeight(20); rrenkert@271: connect(quitButton, SIGNAL(clicked()), qApp, SLOT(quit())); rrenkert@271: bottomLayout->insertStretch(0, 10); rrenkert@271: bottomLayout->addWidget(installButton); rrenkert@271: bottomLayout->setAlignment(installButton, Qt::AlignBottom); rrenkert@271: bottomLayout->addWidget(quitButton); rrenkert@271: bottomLayout->setAlignment(quitButton, Qt::AlignBottom); rrenkert@250: 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("")); rrenkert@432: mSubjectOU = new QLabel(tr("")); rrenkert@432: mIssuerCN = new QLabel(tr("")); rrenkert@432: mIssuerOU = new QLabel(tr("")); rrenkert@432: mValidFrom = new QLabel(tr("")); rrenkert@432: mValidTo = new QLabel(tr("")); rrenkert@432: mFingerprint = new QLabel(tr("")); rrenkert@432: detailContentLayout->addWidget(mSubjectCN); rrenkert@432: detailContentLayout->addWidget(mSubjectOU); rrenkert@432: detailContentLayout->addWidget(mIssuerCN); rrenkert@432: detailContentLayout->addWidget(mIssuerOU); 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@271: infoLayout->addWidget(detailBox); rrenkert@432: infoLayout->addWidget(settingsBox); rrenkert@271: infoLayout->addLayout(bottomLayout); rrenkert@250: rrenkert@187: mainLayout->addWidget(certBox); rrenkert@250: mainLayout->addLayout(infoLayout); rrenkert@250: rrenkert@187: rrenkert@187: // QMainWindow allready has a layout. All child layouts and widgets are rrenkert@187: // managed in the central widget. rrenkert@187: base->setLayout(mainLayout); rrenkert@187: setCentralWidget(base); rrenkert@187: } rrenkert@187: rrenkert@189: void MainWindow::loadCertificateList() rrenkert@189: { aheinecke@365: mCertListWidget->clear(); rrenkert@267: 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@267: } rrenkert@267: else { rrenkert@445: oldRemoveCerts.append(cert); rrenkert@267: } rrenkert@267: } 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@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@189: } rrenkert@445: rrenkert@445: // Add separators and certificates to list widget. rrenkert@445: mCertListWidget->addItem(createSeparator(tr("New certificates to install"), i++)); rrenkert@445: foreach (const Certificate &cert, newInstallCerts) { rrenkert@445: mCertListWidget->addItem(createListItem(cert, Certificate::InstallNew, i++)); rrenkert@445: } rrenkert@445: rrenkert@445: mCertListWidget->addItem(createSeparator(tr("New certificates to remove"), i++)); rrenkert@445: foreach (const Certificate &cert, newRemoveCerts) { rrenkert@445: mCertListWidget->addItem(createListItem(cert, Certificate::RemoveNew, i++)); rrenkert@445: } rrenkert@445: rrenkert@445: mCertListWidget->addItem(createSeparator(tr("Old certificates to install"), i++)); rrenkert@445: foreach (const Certificate &cert, oldInstallCerts) { rrenkert@445: mCertListWidget->addItem(createListItem(cert, Certificate::InstallOld, i++)); rrenkert@445: } rrenkert@445: rrenkert@445: mCertListWidget->addItem(createSeparator(tr("Old certificates to remove"), i++)); rrenkert@445: foreach (const Certificate &cert, oldRemoveCerts) { rrenkert@445: mCertListWidget->addItem(createListItem(cert, Certificate::RemoveOld, i++)); rrenkert@445: } 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@189: void MainWindow::showSettings() rrenkert@189: { rrenkert@155: qDebug() << "show settingsdialog"; rrenkert@155: } rrenkert@155: rrenkert@212: void MainWindow::showStatus() rrenkert@212: { rrenkert@212: qDebug() << "show settingsdialog"; rrenkert@212: StatusDialog *status = new StatusDialog(this); rrenkert@212: status->show(); rrenkert@212: } rrenkert@212: 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@445: Certificate cert = item->data(CertificateItemDelegate::DataRole).value(); rrenkert@432: mSubjectCN->setText(cert.subjectCN()); rrenkert@432: mSubjectOU->setText(cert.subjectOU()); rrenkert@432: mIssuerCN->setText(cert.issuerCN()); rrenkert@432: mIssuerOU->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); andre@389: } 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(); aheinecke@365: andre@372: if (!saveUnselectedCertificates()) { andre@372: qWarning() << "Failed to save previosly unselected certificates."; andre@372: } 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: { 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)) { andre@372: mSettings.setValue(QString::fromLatin1("cert%1").arg(i), rrenkert@445: item->data(CertificateItemDelegate::DataRole).value().base64Line()); andre@372: } andre@372: } andre@372: mSettings.endGroup(); andre@372: mSettings.sync(); andre@372: return mSettings.status() == QSettings::NoError; andre@372: }