Mercurial > trustbridge
view ui/mainwindow.h @ 1373:00fcb9c4d16b
(issue179) Handle SW verify failures and try to redownload the update
author | Andre Heinecke <andre.heinecke@intevation.de> |
---|---|
date | Mon, 24 Nov 2014 16:46:08 +0100 |
parents | 23df332b2a4c |
children |
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. * * Wether the software should be downloaded or not is determined by * the mDownloadSWAccepted value. */ void checkUpdates(); /**@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 schedule an update check retry or close the application. * * An update check retry is scheduled base on getNextUpdateInterval. * If getNextUpdateInterval returns a negative value the application * is closed if the parameter close is true. * * This function also increases the failed connection count. */ void scheduleFailureRetryOrClose(bool close); /** @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; bool mDownloadSWAccepted; }; #endif // MAINWINDOW_H