view ui/mainwindow.h @ 1371:23df332b2a4c

(issue179) Read install signature timestamp from config This also changes the way the sigDt is propgated to the MainWindow. It no longer uses the settings but hands it over as a parameter directly.
author Andre Heinecke <andre.heinecke@intevation.de>
date Mon, 24 Nov 2014 15:48:49 +0100
parents 64f812a63de6
children 00fcb9c4d16b
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.
 */
#ifndef MAINWINDOW_H
#define MAINWINDOW_H

/**
 * @file mainwindow.h
 * @brief Main UI controller
 */

#include <QMainWindow>
#include <QSettings>
#include <QMenuBar>
#include <QListWidget>
#include <QTextEdit>
#include <QPushButton>
#include <QLabel>
#include <QCheckBox>
#include <QScrollArea>
#include <QProcess>
#include <QDateTime>

#include "downloader.h"
#include "certificatelist.h"
#include "certificatelistwidget.h"
#include "textoverlaybutton.h"
#include "trayicon.h"
class QMenu;
class QAction;
class QTimer;
class QPushButton;


/** @brief Main UI controller
 *
 * The MainWindow controls the logic of the Application
 * it is the central piece that controls the state and starts
 * updates / certificate installation.
 * It also controls the UI widgets for the various certificate lists.
 */
class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    /**@brief create a new Main Window object
     *
     * In tray mode this window is not shown and only shows
     * notification messages if there is some actionable state
     * reached. If tray mode is true it also exits after
     * an update check.
     *
     * The sigDt parameter is used to determine if a software
     * update should be installed.
     *
     * @param[in] trayMode set the tray mode
     * @param[in] sigDt the datetime when the binary was signed.
     * */
    MainWindow(bool trayMode, const QDateTime& sigDt = QDateTime());

    /**@brief set the current message to be shown
     *
     * The message will be shown at intervals in the system tray
     * or as a messagebox if no stystemtray is available.
     *
     * @param [in] message The message to show.
     */
    void setMessage(const QString message) {mCurMessage = message;}
    /**@brief accessor for the current message.
     *
     * @returns the currently shown message.*/
    QString getMessage() {return mCurMessage;}

    /**
     * @enum CurrentState
     * @brief The internal state of the application
     */
    enum CurrentState {
         /*! A new certificate list is available. */
        NewListAvailable,
         /*! A new Software is avaialable. */
        NewSoftwareAvailable,
         /*! Download in progress. */
        DownloadingSW,
         /*! An error happened on the last connection. */
        TransferError,
         /*! Update was susccessfull but nothing new is available. */
        NothingChanged
    };

    /**
     * @enum LongTimeErrors
     * @brief Errors that should be stored and only shown after some time has elapsed.
     */
    enum LongTimeErrors {
        /*! The downloaded Software was invalid. */
        lteInvalidSoftware,
        /*! The SSL certificate of the download server was wrong. */
        lteInvalidCertificate,
        /*! The downloaded Certificate List was invalid. */
        lteInvalidList,
        /*! No connection to the server could be established. */
        lteNoConnection
    };

    /** @brief accessor for the current state. */
    CurrentState getState() {return mCurState;}
    /** @brief set the current state. */
    void setState(CurrentState state) {mCurState = state;}

private slots:
    /** @brief Shows the current message to the user. */
    void showMessage();
    /** @brief User has clicked on the message notification. */
    void iconActivated(QSystemTrayIcon::ActivationReason reason);
    /** @brief Check if new updates are available.
     *
     * @param[in] downloadSW wether or not new software should be downloaded.
     */
    void checkUpdates(bool downloadSW = false);
    /**@brief parse a new certificate list and update the UI*/
    void handleNewList(const QString& fileName, const QDateTime& modDate);
    /**@brief handle a Software update, update state and inform the user */
    void handleNewSW(const QString& fileName, const QDateTime& modDate);
    /**@brief an error occured while downloading.*/
    void downloaderError(const QString &message, SSLConnection::ErrorCode error);
    /** @brief Trigger the appropiate action depending on the state */
    void messageClicked();
    /** @brief An error occured during certificate installation .*/
    void installerError(const QString& errMsg);
    /** @brief Certificate installation was successful. */
    void installerSuccess();
    /** @brief Install the currently selected certificates */
    void installCerts();
    /** @brief Handle a toggle action in the manual certificate list */
    void toggleInManual(bool state, const Certificate &cert);
    /** @brief Remove a certificate from the manual list. */
    void removeFromManual(bool state, const Certificate &cert);
    /** @brief Restart the application */
    void updaterFinished(int exitCode, QProcess::ExitStatus status);

    void togglePages(int button);
    void toggleUpdatesNew();
    void toggleUpdatesRemove();
    void toggleUpdatesManual();

    /** Reflect change list states in the UI
     *
     * This slot should be called each time the contents or selection
     * state of one of the certificate lists change to update the
     * UI elements accordingly.
     *
     * @param[in] selected unused. */
    void listChanged(int selected);

    /** @brief check for running software that needs to close before installing
     *
     * This function calls installCerts if no software is running otherwise
     * it informs the user about the software that still needs to be closed.
     */
    void checkAndInstallCerts();

    /** @brief get the last modified date on the download server for
     * the current version.
     *
     * After the initial installation this function can be used to
     * determine the DateTime that corresponds to the currently installed
     * version on the download server.
     *
     * Calls setLastModifiedSWDate on success. Otherwise downloaderError
     * is triggered. */
    void getLastModForCurrentVersion();

    /** @brief set the last modified software date/time
     *
     * The last modifiedSWDate is the corresponding last modified
     * timestamp from the download server vor the currently installed version.
     */
    void setLastModifiedSWDate(const QDateTime &date);

    /** @brief saves the currently unselected certificates
     *
     * This creates / updates a qsettings section that
     * [unselected] that contains the certificates that
     * were unselected previously.
     *
     * Unselected are certificates that are unchecked
     * in the certListWidget
     *
     * Returns false on error.
     */
    bool saveUnselectedCertificates(QStringList unselected);

    /** @brief loads previously unselected certificates from settings
     *
     * The certificates are strored in the list mPreviouslyUnselected.
     *
     * On error mPreviouslyUnselected is empty after this call.
     */
    void loadUnselectedCertificates();

    /** @brief log / store a successful downloader run
     *
     * A downloader run is successful if the finished signal
     * is emited and the state is not TransferError
     */
    void updateCheckSuccess();

    /** @brief open the manual in an external browser window
     */
    void showHelp();

    /** @brief open the proxy settings dialog */
    void showProxySettings();

protected:
    virtual void closeEvent(QCloseEvent *event);

protected slots:
    /** @brief cleanup and close the main window
     *
     * Perform a clean exit (saving state etc.) and close
     * the application */
    virtual void closeApp();

    /* @brief Execute the file fileName to install the softwareupdate.
     *
     * Once the installer process is started this function terminates
     * the application. */
    void installNewSW(const QString& fileName, const QDateTime& modDate);

    /** @brief show an error message
     *
     * This is a wrapper around QMessageBox to allow for central
     * styling of error messages.
     */
    void showErrorMessage(const QString &msg);

signals:
    /** @brief emits the changecount as a string when it changes */
    void changesChanged(const QString& cnt);

private:
    /** @brief Get a installer file name that can be shown to a user.
     *
     * This copys the real file to a temporary location with a user
     * visible localized file name. Does error Handling.
     *
     * @param [in] realFileName The original file name.
     *
     * @returns a null string in case on errors. The new filename
     * otherwise.
     */
    QString getPrettyInstallerName(QString realFileName);

    /** @brief the combined number of changes made in all lists */
    int changeCount();

    /** @brief use this to set the change count */
    void setChangeCount(int cnt);

    /** @brief check the integrity of available certificate lists.
     *
     * Note: Do not use this as a local trust check as this only works on
     * FileNames where the underlying files can change. This
     * is just meant to check if the downloaded data was somehow
     * removed or corrupted. It also initializes mListToInstall
     * and mInstalledList.
     */
    void verifyListData();

    /** @brief check the integrity of available software updates.
     *
     * Note: Do not use this as a local trust check as this only works on
     * FileNames where the underlying files can change. This
     * is just meant to check if the downloaded data was somehow
     * removed or corrupted.
     */
    void verifySWData();

    /** @brief note an long time error in the settings and show a message.
     *
     * Saves a software verify error in the settings and notifies the
     * user if necessary.
     *
     * @param [in] lte The error to handle.
     * @param [in] reset weather or not the error count should be reset.
     *
     **/
    void handleLTE(LongTimeErrors lte, bool reset = false);

    /** @brief note a verify error in the settings and show a message
     *
     * Saves a software verify error in the settings and notifies the
     * user if necessary.*/
    void swVerifyError();

    void createTrayIcon();
    void createActions();
    void loadCertificateList();

    /** @brief UI setup */
    void setupGUI();

    /** @brief create and set up the info widget (accessible via button panel) */
    QWidget *createInfoWidget();
    /** @brief create and set up the updates widget (accessible via button panel) */
    QWidget *createUpdatesWidget();
    /** @brief create and set up the certifcates to install widget
     * (accessible via button panel) */
    QWidget *createInstallWidget();
    /** @brief create and set up the certifcates to remove widget
     * (accessible via button panel) */
    QWidget *createRemoveWidget();

    /** @brief true if the software is running in tray mode*/
    const bool mTrayMode;

    /** @brief The currently shown message */
    QString mCurMessage;
    /** @brief The version the Software thinks is installed */
    QString mInstalledSWVersion;
    /** @brief The certificate list the Software thinks is installed */
    QString mInstalledListVersion;

    QSettings mSettings;

    TrayIcon *mTrayIcon;
    QTimer *mMessageTimer;
    QMenu *mTrayMenu;
    QAction *mCheckUpdates;
    QAction *mQuitAction;
    CurrentState mCurState;
    QMenuBar *mMenuBar;
    QPushButton *mQuitButton;

    /* The current list that should be installed */
    CertificateList mListToInstall;
    /* The last list that we installed */
    CertificateList mInstalledList;
    /* Previously made "unselect" choices in the form of
     * base64lines with I:/R: prefix */
    QStringList mPreviouslyUnselected;

    QLabel *mCurrentListDate;
    QLabel *mNewListDate;

    QButtonGroup *mButtonGroup;
    QWidget *mUpdatesWidget;
    QWidget *mInstallWidget;
    QWidget *mRemoveWidget;
    QWidget *mInfoWidget;

    QLabel *mUpdatesHeader;
    QLabel *mUpdatesDetailsHeader;
    QLabel *mCertListVersion;
    QLabel *mCertListVersionContents;
    QLabel *mLastUpdateCheck;
    QLabel *mLastUpdateCheckContents;
    QLabel *mUpdatesNewCertificates;
    QLabel *mUpdatesRemoveCertificates;
    QLabel *mUpdatesManualCertificates;
    QLabel *mUpdatesTip;

    /* These are a bit of a pattern break, they should
     * be accessed over the according page widgets.
     *
     * They are initialized in the create*widget functions.*/
    CertificateListWidget *mUpdatesNew;
    CertificateListWidget *mUpdatesRemove;
    CertificateListWidget *mUpdatesManual;
    CertificateListWidget *mInstallList;
    CertificateListWidget *mRemoveList;

    QPushButton *mUpdatesDetailsNew;
    QPushButton *mUpdatesDetailsRemove;
    QPushButton *mUpdatesDetailsManual;

    QPushButton *mInstallButton;
    int mChangeCount;
    bool mManualDetailsShown;
    int mFailedConnections;
    QDateTime mSigDt;
};

#endif // MAINWINDOW_H

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