Mercurial > trustbridge
view ui/mainwindow.cpp @ 502:e551de11d8b6
Properly handle the case that the file does not exist.
TRUNCATE makes create file fail if the file does not exist
but we need TRUNCATE in the case that the file already exists
author | Andre Heinecke <aheinecke@intevation.de> |
---|---|
date | Mon, 28 Apr 2014 09:18:07 +0000 |
parents | 077b4342d69b |
children | 20973a56d5ec |
line wrap: on
line source
/* 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 "mainwindow.h" #include <QDebug> #include <QProgressDialog> #include <QMessageBox> #include <QSystemTrayIcon> #include <QAction> #include <QDialog> #include <QMenu> #include <QApplication> #include <QFile> #include <QTimer> #include <QHBoxLayout> #include <QVBoxLayout> #include <QGroupBox> #include <QSplitter> #include <QLabel> #include <QImage> #include <QCheckBox> // The amount of time in minutes stay silent if we have // something to say #define NAG_INTERVAL_MINUTES 60 #ifndef APPNAME #define APPNAME "TrustBridge" #endif #define SERVER_URL "https://files.intevation.de:443" #define LIST_RESOURCE "/users/aheinecke/zertifikatsliste_1.txt" #define SW_RESOURCE "/users/aheinecke/zertifikatsliste_1.txt" #ifdef Q_OS_WIN #define SW_RESOURCE_VERSION "/users/aheinecke/trustbridge-%1.exe" #else #define SW_RESOURCE_VERSION "/users/aheinecke/trustbridge-%1.sh" #endif #include "certificatelist.h" #include "downloader.h" #include "helpdialog.h" #include "aboutdialog.h" #include "statusdialog.h" #include "certificateitemdelegate.h" #include "separatoritemdelegate.h" #include "installwrapper.h" MainWindow::MainWindow(bool trayMode): mTrayMode(trayMode) { createActions(); createTrayIcon(); createMenuBar(); createContent(); resize(950, 540); qRegisterMetaType<SSLConnection::ErrorCode>("SSLConnection::ErrorCode"); qRegisterMetaType<Certificate::Status>("Certificate::Status"); connect(mTrayIcon, SIGNAL(activated(QSystemTrayIcon::ActivationReason)), this, SLOT(iconActivated(QSystemTrayIcon::ActivationReason))); mMessageTimer = new QTimer(this); connect(mMessageTimer, SIGNAL(timeout()), this, SLOT(showMessage())); mMessageTimer->setInterval(NAG_INTERVAL_MINUTES * 60 * 1000); mMessageTimer->start(); checkUpdates(); loadUnselectedCertificates(); loadCertificateList(); if (!trayMode) { show(); } } void MainWindow::iconActivated(QSystemTrayIcon::ActivationReason reason) { switch (reason) { case QSystemTrayIcon::Trigger: case QSystemTrayIcon::MiddleClick: showMessage(); break; case QSystemTrayIcon::DoubleClick: show(); break; default: ; } } void MainWindow::messageClicked() { if (mCurState == NewListAvailable) { show(); } } void MainWindow::showMessage() { if (!isVisible() && !mCurMessage.isEmpty()) { mTrayIcon->showMessage(QApplication::applicationName(), mCurMessage, QSystemTrayIcon::Information, 5000); mMessageTimer->start(); // Restart the timer so that we don't spam } } void MainWindow::verifyAvailableData() { QString availableFileName = mSettings.value("List/available").toString(); QString installedFileName = mSettings.value("List/installed").toString(); QString swFileName = mSettings.value("Software/available").toString(); if (!availableFileName.isEmpty()) { mListToInstall.readList(availableFileName.toLocal8Bit().constData()); if (!mListToInstall.isValid()) { mCurState = TransferError; // Probably a bug when Qt fileName is encoded and cFileName // fails because of this. This needs a unit test! // Maybe check that the file is in our data directory QFile::remove(availableFileName); mSettings.remove("List/available"); mSettings.remove("List/availableDate"); } } else { // Make sure the available notation is also removed mSettings.remove("List/available"); mSettings.remove("List/availableDate"); } if (!installedFileName.isEmpty()) { mInstalledList.readList(installedFileName.toLocal8Bit().constData()); if (!mInstalledList.isValid()) { // Probably a bug when Qt fileName is encoded and cFileName // fails because of this. This needs a unit test! // Maybe check that the file is in our data directory QFile::remove(installedFileName); mSettings.remove("List/installed"); mSettings.remove("List/installedDate"); } } else { // Make sure the available notation is also removed mSettings.remove("List/installed"); mSettings.remove("List/installedDate"); } if (!swFileName.isEmpty()) { // TODO } else { mSettings.remove("Software/available"); mSettings.remove("Software/availableDate"); } } void MainWindow::handleNewList(const QString& fileName, const QDateTime& modDate) { mSettings.setValue("List/available", fileName); mSettings.setValue("List/availableDate", modDate); verifyAvailableData(); if (!mListToInstall.isValid()) { /* Downloader provided invalid files */ /* TODO: Error count. Error handling. Otherwise * we can go into an endless loop here */ /* Retry the download again in 10 - 20 minutes */ QTimer::singleShot(600000 + (qrand() % 60000), this, SLOT(checkUpdates())); } else { mCurMessage = tr("An updated certificate list is available. Click here to install."); setState(NewListAvailable); showMessage(); loadCertificateList(); } } void MainWindow::handleNewSW(const QString& fileName, const QDateTime& modDate) { mCurMessage = tr("An update for %1 is available. Click here to install.").arg( QApplication::applicationName()); setState(NewSoftwareAvailable); mSettings.setValue("Software/available", fileName); mSettings.setValue("Software/availableDate", modDate); mSettings.sync(); showMessage(); } void MainWindow::checkUpdates(bool downloadSW) { verifyAvailableData(); if (!mSettings.contains("Software/installedDate")) { lookUpDateForVersion(); return; } QDateTime listInstalledLastMod = mSettings.value("List/installedDate").toDateTime(); QDateTime swInstalledLastMod = mSettings.value("Software/installedDate").toDateTime(); QString listResource = QString::fromLatin1(LIST_RESOURCE); QString swResource = QString::fromLatin1(SW_RESOURCE); #ifndef RELEASE_BUILD /* Use this for testing to specify another file name for updates */ listResource = mSettings.value("List/resource", listResource).toString(); swResource = mSettings.value("Software/resource", swResource).toString(); #endif Downloader* downloader = new Downloader(this, QString::fromLatin1(SERVER_URL), QByteArray(), QDateTime::currentDateTime(), // TODO swInstalledLastMod, listInstalledLastMod, swResource, listResource, downloadSW); connect(downloader, SIGNAL(newListAvailable(const QString&, const QDateTime&)), this, SLOT(handleNewList(const QString&, const QDateTime&))); if (!downloadSW) { connect(downloader, SIGNAL(newSoftwareAvailable(const QString&, const QDateTime&)), this, SLOT(newSWAvailable(const QString&, const QDateTime&))); } else { connect(downloader, SIGNAL(newSoftwareAvailable(const QString&, const QDateTime&)), this, SLOT(handleNewSW(const QString&, const QDateTime&))); } connect(downloader, SIGNAL(finished()), downloader, SLOT(deleteLater())); connect(downloader, SIGNAL(error(const QString &, SSLConnection::ErrorCode)), this, SLOT(downloaderError(const QString &, SSLConnection::ErrorCode))); downloader->start(); } void MainWindow::lookUpDateForVersion() { QString softwareVersion = QString::fromLatin1(SW_RESOURCE_VERSION).arg( QApplication::applicationVersion()); qDebug() << softwareVersion; QString listResource = QString::fromLatin1(LIST_RESOURCE); Downloader* downloader = new Downloader(this, QString::fromLatin1(SERVER_URL), QByteArray(), QDateTime::currentDateTime(), QDateTime::currentDateTime(), softwareVersion, listResource, false); connect(downloader, SIGNAL(finished()), downloader, SLOT(deleteLater())); connect(downloader, SIGNAL(error(const QString &, SSLConnection::ErrorCode)), this, SLOT(downloaderError(const QString &, SSLConnection::ErrorCode))); connect(downloader, SIGNAL(lastModifiedDate(const QDateTime&)), this, SLOT(setLastModifiedDate(const QDateTime&))); downloader->start(); } void MainWindow::setLastModifiedDate(const QDateTime &date) { mSettings.beginGroup("Software"); mSettings.setValue("installedDate", date); mSettings.endGroup(); checkUpdates(); } void MainWindow::newSWAvailable(const QString &fileName, const QDateTime &date) { QMessageBox msgBox; msgBox.setIcon(QMessageBox::Information); msgBox.setText("<h3>" + tr("New Software version is available.") + "</h3>"); msgBox.setInformativeText(tr("Do you want to install the new Version?")); msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::Cancel); msgBox.setDefaultButton(QMessageBox::Yes); int selection = msgBox.exec(); if (selection == QMessageBox::Yes) { checkUpdates(true); } } void MainWindow::downloaderError(const QString &message, SSLConnection::ErrorCode error) { mCurMessage = message; showMessage(); } void MainWindow::createActions() { mCheckUpdates = new QAction(tr("Check for Updates"), this); connect(mCheckUpdates, SIGNAL(triggered()), this, SLOT(checkUpdates())); mQuitAction = new QAction(tr("Quit"), this); connect(mQuitAction, SIGNAL(triggered()), qApp, SLOT(quit())); } void MainWindow::createTrayIcon() { QIcon trayImg(":/img/tray_22.png"); mTrayMenu = new QMenu(this); mTrayMenu->addAction(mCheckUpdates); mTrayMenu->addAction(mQuitAction); mTrayIcon = new QSystemTrayIcon(this); mTrayIcon->setContextMenu(mTrayMenu); mTrayIcon->setIcon(trayImg); setWindowIcon(trayImg); mTrayIcon->show(); mTrayIcon->setToolTip(tr("TrustBridge")); 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")); QAction *settings = mMenu->addAction(tr("Settings")); QAction *status = mMenu->addAction(tr("Statusdialog")); 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(settings, SIGNAL(triggered()), this, SLOT(showSettings())); connect(status, SIGNAL(triggered()), this, SLOT(showStatus())); 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; QHBoxLayout *headerLayout = new QHBoxLayout; QVBoxLayout *headerTextLayout = 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); // 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 *subTitle = new QLabel("This Software installs and removes Certificates"); headerTextLayout->addWidget(title); headerTextLayout->addWidget(subTitle); headerLayout->addWidget(logo); headerLayout->addLayout(headerTextLayout); 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 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(installCerts())); 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); // 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("")); mSubjectOU = new QLabel(tr("")); mIssuerCN = new QLabel(tr("")); mIssuerOU = 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(mSubjectOU); detailContentLayout->addWidget(mIssuerCN); detailContentLayout->addWidget(mIssuerOU); detailContentLayout->addWidget(mValidFrom); detailContentLayout->addWidget(mValidTo); detailContentLayout->addWidget(mFingerprint); detailLayout->addLayout(detailLabelLayout); detailLayout->addLayout(detailContentLayout); detailBox->setLayout(detailLayout); infoLayout->addSpacing(20); infoLayout->addLayout(headerLayout); infoLayout->addWidget(detailBox); infoLayout->addWidget(settingsBox); infoLayout->addLayout(bottomLayout); mainLayout->addWidget(certBox); mainLayout->addLayout(infoLayout); mainLayout->setStretchFactor(certBox, 37); mainLayout->setStretchFactor(infoLayout, 63); // QMainWindow allready has a layout. All child layouts and widgets are // managed in the central widget. base->setLayout(mainLayout); setCentralWidget(base); } void MainWindow::loadCertificateList() { mCertListWidget->clear(); int i = 0; /* TODO: if nothing is available (neither old nor new) add some progress * indication */ QList<Certificate> newInstallCerts; QList<Certificate> newRemoveCerts; QList<Certificate> oldInstallCerts; QList<Certificate> oldRemoveCerts; if (mListToInstall.getCertificates().isEmpty()) { // No new list available, add old certificates. foreach (const Certificate &cert, mInstalledList.getCertificates()) { if (cert.isInstallCert()) { oldInstallCerts.append(cert); } else { oldRemoveCerts.append(cert); } } // 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()) { if (cert.isInstallCert()) { // Certificate with status "install". if (mInstalledList.getCertificates().contains(cert)) { // Was in the old list. oldInstallCerts.append(cert); } else { // Is a brand new certificate newInstallCerts.append(cert); } } else { // Certificate with status "remove". if (mInstalledList.getCertificates().contains(cert)) { // Was in the old list. oldRemoveCerts.append(cert); } else { // Was in the old list with status "install" and now has the // status "remove". newRemoveCerts.append(cert); } } } mCurrentListDate->setText(tr("Current List Date: %1") .arg(mInstalledList.date().toString())); mNewListDate->setText(tr("New List Date: %1").arg(mListToInstall.date().toString())); } // Add separators and certificates to list widget. mCertListWidget->addItem(createSeparator(tr("New certificates to install"), i++)); foreach (const Certificate &cert, newInstallCerts) { mCertListWidget->addItem(createListItem(cert, Certificate::InstallNew, i++)); } mCertListWidget->addItem(createSeparator(tr("New certificates to remove"), i++)); foreach (const Certificate &cert, newRemoveCerts) { mCertListWidget->addItem(createListItem(cert, Certificate::RemoveNew, i++)); } mCertListWidget->addItem(createSeparator(tr("Old certificates to install"), i++)); foreach (const Certificate &cert, oldInstallCerts) { mCertListWidget->addItem(createListItem(cert, Certificate::InstallOld, i++)); } 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; } 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::showSettings() { qDebug() << "show settingsdialog"; } void MainWindow::showStatus() { qDebug() << "show settingsdialog"; StatusDialog *status = new StatusDialog(this); status->show(); } 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()); mSubjectOU->setText(cert.subjectOU()); mIssuerCN->setText(cert.issuerCN()); mIssuerOU->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); } void MainWindow::installerError(const QString& errMsg) { QMessageBox::warning(this, tr("Error executing update"), errMsg); } void MainWindow::installerSuccess() { if (mCurState == NewListAvailable) { mCurState = NothingChanged; mCurMessage = QString(); QString listFileName = mSettings.value("List/available").toString(); QDateTime listFileDate = mSettings.value("List/availableDate").toDateTime(); mSettings.remove("List/available"); mSettings.remove("List/availableDate"); if (listFileName.isEmpty() || !listFileDate.isValid()) { qWarning() << "Error accessing settings"; return; /* Try again with next check */ } mSettings.setValue("List/installed", listFileName); mSettings.setValue("List/installedDate", listFileDate); mInstalledList = mListToInstall; mListToInstall = CertificateList(); } loadCertificateList(); } void MainWindow::installCerts() { QStringList choices; 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:")) { certLine[0] = 'R'; choices << certLine; } } QProgressDialog *progress = new QProgressDialog(this); progress->setWindowModality(Qt::WindowModal); progress->setLabelText(tr("Installing certificates...")); progress->setCancelButton(0); progress->setRange(0,0); progress->setMinimumDuration(0); progress->show(); InstallWrapper *instWrap = new InstallWrapper(this, mListToInstall.isValid() ? mListToInstall.fileName() : mInstalledList.fileName(), choices); /* Clean up object and progress dialog */ connect(instWrap, SIGNAL(finished()), instWrap, SLOT(deleteLater())); connect(instWrap, SIGNAL(finished()), progress, SLOT(deleteLater())); connect(instWrap, SIGNAL(finished()), progress, SLOT(cancel())); connect(instWrap, SIGNAL(installationSuccessful()), this, SLOT(installerSuccess())); connect(instWrap, SIGNAL(error(const QString &)), this, SLOT(installerError(const QString &))); instWrap->start(); if (!saveUnselectedCertificates()) { qWarning() << "Failed to save previosly unselected certificates."; } } void MainWindow::loadUnselectedCertificates() { mPreviouslyUnselected.clear(); mSettings.beginGroup("unselected"); QStringList keys = mSettings.allKeys(); foreach (const QString &key, keys) { mPreviouslyUnselected << mSettings.value(key, QString()).toString(); } mSettings.endGroup(); } bool MainWindow::saveUnselectedCertificates() { 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; } } mSettings.endGroup(); mSettings.sync(); return mSettings.status() == QSettings::NoError; } void MainWindow::saveAutoUpdate(int state) { mSettings.beginGroup("settings"); mSettings.setValue("autoupdate", state != Qt::Unchecked); mSettings.endGroup(); } void MainWindow::saveAutoStart(int state) { mSettings.beginGroup("settings"); mSettings.setValue("autostart", state != Qt::Unchecked); mSettings.endGroup(); } void MainWindow::closeApp() { saveUnselectedCertificates(); qApp->quit(); }