view ui/mainwindow.cpp @ 187:0c06a608e15f

Create the mainwindow content.
author Raimund Renkert <rrenkert@intevation.de>
date Wed, 26 Mar 2014 09:10:46 +0100
parents c0fdb8d336cf
children 5f0d45ca9de4
line wrap: on
line source
#include "mainwindow.h"

#include <QDebug>
#include <QMessageBox>
#include <QSystemTrayIcon>
#include <QAction>
#include <QDialog>
#include <QMenu>
#include <QApplication>
#include <QFile>
#include <QTimer>
#include <QHBoxLayout>
#include <QListWidget>
#include <QVBoxLayout>
#include <QGroupBox>
#include <QPushButton>

// The amount of time in minutes stay silent if we have
// something to say
#define NAG_INTERVAL_MINUTES 2

#define SERVER_URL "https://files.kolab.org:443"
#define LIST_RESOURCE "/incoming/aheinecke/test"
#define SW_RESOURCE "/incoming/aheinecke/test"

#include "certificatelist.h"
#include "downloader.h"
#include "listupdatedialog.h"

MainWindow::MainWindow() {
    createActions();
    createTrayIcon();
    createMenuBar();
    createContent();
    qRegisterMetaType<SSLConnection::ErrorCode>("SSLConnection::ErrorCode");

    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();
}

void MainWindow::iconActivated(QSystemTrayIcon::ActivationReason reason)
{
    switch (reason) {
    case QSystemTrayIcon::Trigger:
    case QSystemTrayIcon::MiddleClick:
        showMessage();
        break;
    case QSystemTrayIcon::DoubleClick:
        // TODO show menu
        break;
    default:
        ;
    }
}

void MainWindow::messageClicked()
{
    if (mCurState == NewListAvailable) {
        ListUpdateDialog *listUpdateDialog = new ListUpdateDialog(this,
                mListToInstall);
        listUpdateDialog->show();
        qDebug() << "NewListAvailable";
    }
}

void MainWindow::showMessage()
{
    if (!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 listFileName = mSettings.value("List/available").toString();
    QString swFileName = mSettings.value("Software/available").toString();

    if (!listFileName.isEmpty()) {
        mListToInstall.readList(listFileName.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(listFileName);
            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 (!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();
    }
}

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()
{
    verifyAvailableData();

    QDateTime listInstalledLastMod = mSettings.value("List/installedDate").toDateTime();
    QDateTime swInstalledLastMod = mSettings.value("Software/installedDate").toDateTime();

    Downloader* downloader = new Downloader(this,
                                            QString::fromLatin1(SERVER_URL),
                                            QByteArray(),
                                            QDateTime::currentDateTime(),
//                                            swInstalledLastMod,
                                            listInstalledLastMod,
                                            QString::fromLatin1(SW_RESOURCE),
                                            QString::fromLatin1(LIST_RESOURCE));

    connect(downloader, SIGNAL(newListAvailable(const QString&, const QDateTime&)),
            this, SLOT(handleNewList(const QString&, const QDateTime&)));
    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::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("m13ui"));

    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"));
    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(help, SIGNAL(triggered()), this, SLOT(showHelp()));
    connect(about, SIGNAL(triggered()), this, SLOT(showAbout()));
    connect(quit, SIGNAL(triggered()), qApp, SLOT(quit()));
    setMenuBar(mMenuBar);
}

void MainWindow::createContent()
{
    // Create a central widget containing the main layout.
    QWidget *base = new QWidget;

    QVBoxLayout *mainLayout = new QVBoxLayout;
    QHBoxLayout *certLayout = new QHBoxLayout;
    QHBoxLayout *bottomLayout = new QHBoxLayout;

    QGroupBox *certBox = new QGroupBox(tr("Managed Certificates"));
    QListWidget *certificates = new QListWidget;
    QListWidget *details = new QListWidget;
    certLayout->addWidget(certificates);
    certLayout->addWidget(details);
    certBox->setLayout(certLayout);

    QPushButton *update = new QPushButton("Search for Updates");
    connect(update, SIGNAL(clicked()), this, SLOT(checkUpdates()));
    bottomLayout->insertStretch(0, 10);
    bottomLayout->addWidget(update);
    mainLayout->addWidget(certBox);
    mainLayout->addLayout(bottomLayout);

    // QMainWindow allready has a layout. All child layouts and widgets are
    // managed in the central widget.
    base->setLayout(mainLayout);
    setCentralWidget(base);
}

void MainWindow::showSettings() {
    qDebug() << "show settingsdialog";
}

void MainWindow::showHelp()
{
    qDebug() << "show helpdialog";
}

void MainWindow::showAbout()
{
    qDebug() << "show aboutdialog";
}

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