1 /* 2 * Copyright 2015-2021 The Regents of the University of California 3 * All rights reserved. 4 * 5 * This file is part of Spoofer. 6 * 7 * Spoofer is free software: you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License as published by 9 * the Free Software Foundation, either version 3 of the License, or 10 * (at your option) any later version. 11 * 12 * Spoofer is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with Spoofer. If not, see <http://www.gnu.org/licenses/>. 19 */ 20 21 #include <QMainWindow> 22 #include <QPlainTextEdit> 23 #include <QTimer> 24 #include "SpooferUI.h" 25 26 // forward declarations 27 QT_BEGIN_NAMESPACE 28 class QFileSystemWatcher; 29 class QWidget; 30 class QLabel; 31 class QTableWidget; 32 class QFrame; 33 class QVBoxLayout; 34 class QMessageBox; 35 class QAbstractButton; 36 QT_END_NAMESPACE 37 template<class T> class TableRow; 38 class ProgressRow; 39 class SessionResults; 40 class RunResults; 41 class ActionButton; 42 class PreferencesDialog; 43 44 class MainWindow Q_DECL_FINAL : public QMainWindow, public SpooferUI { 45 Q_OBJECT 46 47 friend class RunResults; 48 49 MainWindow(const MainWindow&) NO_METHOD; // no copy-ctor 50 MainWindow operator=(const MainWindow&) NO_METHOD; // no copy-assign 51 52 class WindowOutput : public QIODevice { 53 QPlainTextEdit *_textedit; 54 QTextCursor *_cursor; 55 int overwritableStart; // position of beginning of overwritable text 56 WindowOutput(const WindowOutput&) NO_METHOD; // no copy-ctor 57 WindowOutput operator=(const WindowOutput&) NO_METHOD; // no copy-assign 58 public: WindowOutput(QPlainTextEdit * textedit)59 WindowOutput(QPlainTextEdit *textedit) : 60 QIODevice(), _textedit(textedit), 61 _cursor(new QTextCursor(textedit->textCursor())), 62 overwritableStart(-1) 63 {} setLogCharFmt(QtMsgType type)64 QTextCharFormat setLogCharFmt(QtMsgType type) { 65 QTextCharFormat oldFmt = _cursor->charFormat(); 66 QTextCharFormat newFmt = oldFmt; 67 newFmt.setForeground(QBrush( 68 (type == QtDebugMsg) ? Qt::darkBlue : 69 (type == QtWarningMsg) ? Qt::darkMagenta : 70 (type == QtCriticalMsg) ? Qt::darkRed : 71 (type == QtFatalMsg) ? Qt::darkRed : 72 Qt::darkBlue)); 73 _cursor->setCharFormat(newFmt); 74 return oldFmt; 75 } setProberCharFmt()76 QTextCharFormat setProberCharFmt() { 77 QTextCharFormat oldFmt = _cursor->charFormat(); 78 QTextCharFormat newFmt = oldFmt; 79 QFont font(QSL("Courier"), oldFmt.font().pointSize()); 80 font.setStyleHint(QFont::TypeWriter); 81 newFmt.setFont(font); 82 newFmt.setForeground(QBrush(Qt::darkGreen)); 83 _cursor->setCharFormat(newFmt); 84 return oldFmt; 85 } setCharFmt(const QTextCharFormat & fmt)86 void setCharFmt(const QTextCharFormat &fmt) { _cursor->setCharFormat(fmt); } 87 protected: readData(char * data,qint64 maxSize)88 qint64 readData(char *data, qint64 maxSize) Q_DECL_OVERRIDE 89 { Q_UNUSED(data); Q_UNUSED(maxSize); return -1; } 90 qint64 writeData(const char *data, qint64 maxSize) Q_DECL_OVERRIDE; 91 }; 92 93 public: 94 static void logHandler(QtMsgType type, const QMessageLogContext &ctx, 95 const QString &msg); instance()96 static MainWindow *instance() { return theInstance; } 97 static QString mainTitle; 98 99 MainWindow(QWidget *parent = nullptr); 100 void init(); 101 QStringList additionalArgs() Q_DECL_OVERRIDE; 102 private slots: 103 void initEvents(); 104 bool opAllowed(const Config::MemberBase &cfgItem); 105 void openPreferences(); 106 void closePreferences(); 107 void help(); 108 void about(); 109 void runProber(); 110 void abortProber(); 111 void pauseScheduler(); 112 void resumeScheduler(); 113 void shutdownScheduler(); 114 void schedConnected(); 115 void schedError(); readScheduler()116 void readScheduler() { SpooferUI::readScheduler(); showStatus(); } 117 void schedDisconnected(); 118 void handleProberText(QString *text); 119 bool finishProber() Q_DECL_OVERRIDE; 120 void reconnectScheduler(); 121 void setCountdownLabel(); 122 void hideBlankTests(bool checked); 123 #ifdef AUTOUPGRADE_ENABLED 124 void showUpgradeTimer(); 125 void doUpgrade(); 126 void cancelUpgrade(); 127 #endif 128 void toggleUpgradeDetails(const QString &link); 129 void handleHistoryColumnClick(int logicalIndex); 130 private: 131 static MainWindow *theInstance; 132 static WindowOutput *winout; 133 QFileSystemWatcher *schedWatcher; 134 QTimer countdownTimer; 135 QVBoxLayout *centralLayout; 136 QLabel *proberInfoLabel; 137 QLabel *proberCountdownLabel; 138 QLabel *schedulerStatusLabel; 139 QVBoxLayout *proberBoxLayout; 140 int firstProberMsgIdx; 141 int nextProberMsgIdx; 142 TableRow<QLabel> *proberTimeRow; 143 ProgressRow *progRow4; 144 ProgressRow *progRow6; 145 RunResults *currentRun; 146 QAction *aboutAct; 147 QAction *exitAct; 148 QAction *runAct; 149 QAction *abortAct; 150 QAction *pauseAct; 151 QAction *resumeAct; 152 QAction *shutdownAct; 153 QAction *hideGuiAct; 154 QAction *showGuiAct; 155 ActionButton *runButton; 156 ActionButton *pauseButton; 157 static QPlainTextEdit *consoleWidget; 158 static ActionButton *consoleButton; 159 QTableWidget *historyWidget; 160 PreferencesDialog *prefDialog; 161 QFrame *upgradeBox; 162 QLabel *upgradeNotice; 163 QLabel *upgradeDetails; 164 QLabel *upgradeAutoNotice; 165 #ifdef AUTOUPGRADE_ENABLED 166 QFrame *upgradeResultBox; 167 QLabel *upgradeResultLabel; 168 time_t upgradeResultTime; 169 QAction *upgradeAct; 170 QAction *upgradeCancelAct; 171 ActionButton *upgradeButton; 172 ActionButton *upgradeCancelButton; 173 QTimer autoupgradeTimer; 174 time_t autoupgradeTime; 175 #endif 176 QString debugFlags; 177 void showEvent(QShowEvent *ev) Q_DECL_OVERRIDE; 178 void schedCleanup(bool isError); 179 bool connectScheduler(bool privileged); 180 void showStatus(); 181 void addHistoryCell(int row, int column, Qt::Alignment halign, QLabel *label); 182 bool addHistoryReport(const RunResults *runResults); 183 void initRunDisplay(const RunResults *runResults, const QString &timeTitle); 184 void addHistorySession(SessionResults *results); 185 void endHistorySession(SessionResults *results); 186 void loadHistoricLogs(); 187 void startFileTail(QString logname) Q_DECL_OVERRIDE; 188 void watchForSchedulerRestart(); 189 void printNextProberStart() Q_DECL_OVERRIDE; 190 bool setCountdownUnit(time_t when, time_t now, int count, int size, 191 QString unit, QString units); 192 void proberError(const QString &text) Q_DECL_OVERRIDE; 193 void configChanged() Q_DECL_OVERRIDE; 194 void needConfig() Q_DECL_OVERRIDE; 195 void clearProberMessages(int n = 0); 196 void displayProberMessage(const QString &text, bool enabled = true, 197 const QColor &color = QColor()); 198 void promptForUpgrade() Q_DECL_OVERRIDE; 199 void cancelUpgradePrompt() Q_DECL_OVERRIDE; 200 #ifdef AUTOUPGRADE_ENABLED 201 void showUpgradeProgress(const QString &str) Q_DECL_OVERRIDE; 202 void showUpgradeResult(const QString &str) Q_DECL_OVERRIDE; 203 #endif 204 }; 205