1 /*
2 -------------------------------------------------------------------------
3  CxxTest: A lightweight C++ unit testing library.
4  Copyright (c) 2008 Sandia Corporation.
5  This software is distributed under the LGPL License v3
6  For more information, see the COPYING file in the top CxxTest directory.
7  Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
8  the U.S. Government retains certain rights in this software.
9 -------------------------------------------------------------------------
10 */
11 
12 #ifndef __cxxtest__QtGui_h__
13 #define __cxxtest__QtGui_h__
14 
15 //
16 // The QtGui displays a simple progress bar using the Qt Toolkit.  It
17 // has been tested with versions 2.x and 3.x.
18 //
19 // Apart from normal Qt command-line arguments, it accepts the following options:
20 //   -minimized    Start minimized, pop up on error
21 //   -keep         Don't close the window at the end
22 //   -title TITLE  Set the window caption
23 //
24 // If both are -minimized and -keep specified, GUI will only keep the
25 // window if it's in focus.
26 //
27 
28 #include <cxxtest/Gui.h>
29 
30 #include <qapplication.h>
31 #include <qglobal.h>
32 #include <qlabel.h>
33 #include <qlayout.h>
34 #include <qmessagebox.h>
35 #include <qpixmap.h>
36 #include <qprogressbar.h>
37 #include <qstatusbar.h>
38 
39 namespace CxxTest
40 {
41 class QtGui : public GuiListener
42 {
43 public:
enterGui(int & argc,char ** argv)44     void enterGui(int &argc, char **argv)
45     {
46         parseCommandLine(argc, argv);
47         createApplication(argc, argv);
48     }
49 
enterWorld(const WorldDescription & wd)50     void enterWorld(const WorldDescription &wd)
51     {
52         createWindow(wd);
53         processEvents();
54     }
55 
guiEnterSuite(const char * suiteName)56     void guiEnterSuite(const char *suiteName)
57     {
58         showSuiteName(suiteName);
59     }
60 
guiEnterTest(const char * suiteName,const char * testName)61     void guiEnterTest(const char *suiteName, const char *testName)
62     {
63         setCaption(suiteName, testName);
64         advanceProgressBar();
65         showTestName(testName);
66         showTestsDone(_progressBar->progress());
67         processEvents();
68     }
69 
yellowBar()70     void yellowBar()
71     {
72         setColor(255, 255, 0);
73         setIcon(QMessageBox::Warning);
74         getTotalTests();
75         processEvents();
76     }
77 
redBar()78     void redBar()
79     {
80         if (_startMinimized && _mainWindow->isMinimized())
81         {
82             showNormal();
83         }
84         setColor(255, 0, 0);
85         setIcon(QMessageBox::Critical);
86         getTotalTests();
87         processEvents();
88     }
89 
leaveGui()90     void leaveGui()
91     {
92         if (keep())
93         {
94             showSummary();
95             _application->exec();
96         }
97         else
98         {
99             _mainWindow->close(true);
100         }
101     }
102 
103 private:
104     QString _title;
105     bool _startMinimized, _keep;
106     unsigned _numTotalTests;
107     QString _strTotalTests;
108     QApplication *_application;
109     QWidget *_mainWindow;
110     QVBoxLayout *_layout;
111     QProgressBar *_progressBar;
112     QStatusBar *_statusBar;
113     QLabel *_suiteName, *_testName, *_testsDone;
114 
parseCommandLine(int argc,char ** argv)115     void parseCommandLine(int argc, char **argv)
116     {
117         _startMinimized = _keep = false;
118         _title = argv[0];
119 
120         for (int i = 1; i < argc; ++ i)
121         {
122             QString arg(argv[i]);
123             if (arg == "-minimized")
124             {
125                 _startMinimized = true;
126             }
127             else if (arg == "-keep")
128             {
129                 _keep = true;
130             }
131             else if (arg == "-title" && (i + 1 < argc))
132             {
133                 _title = argv[++i];
134             }
135         }
136     }
137 
createApplication(int & argc,char ** argv)138     void createApplication(int &argc, char **argv)
139     {
140         _application = new QApplication(argc, argv);
141     }
142 
createWindow(const WorldDescription & wd)143     void createWindow(const WorldDescription &wd)
144     {
145         getTotalTests(wd);
146         createMainWindow();
147         createProgressBar();
148         createStatusBar();
149         setMainWidget();
150         if (_startMinimized)
151         {
152             showMinimized();
153         }
154         else
155         {
156             showNormal();
157         }
158     }
159 
getTotalTests()160     void getTotalTests()
161     {
162         getTotalTests(tracker().world());
163     }
164 
getTotalTests(const WorldDescription & wd)165     void getTotalTests(const WorldDescription &wd)
166     {
167         _numTotalTests = wd.numTotalTests();
168         char s[WorldDescription::MAX_STRLEN_TOTAL_TESTS];
169         _strTotalTests = wd.strTotalTests(s);
170     }
171 
createMainWindow()172     void createMainWindow()
173     {
174         _mainWindow = new QWidget();
175         _layout = new QVBoxLayout(_mainWindow);
176     }
177 
createProgressBar()178     void createProgressBar()
179     {
180         _layout->addWidget(_progressBar = new QProgressBar(_numTotalTests, _mainWindow));
181         _progressBar->setProgress(0);
182         setColor(0, 255, 0);
183         setIcon(QMessageBox::Information);
184     }
185 
createStatusBar()186     void createStatusBar()
187     {
188         _layout->addWidget(_statusBar = new QStatusBar(_mainWindow));
189         _statusBar->addWidget(_suiteName = new QLabel(_statusBar), 2);
190         _statusBar->addWidget(_testName = new QLabel(_statusBar), 4);
191         _statusBar->addWidget(_testsDone = new QLabel(_statusBar), 1);
192     }
193 
setMainWidget()194     void setMainWidget()
195     {
196         _application->setMainWidget(_mainWindow);
197     }
198 
showMinimized()199     void showMinimized()
200     {
201         _mainWindow->showMinimized();
202     }
203 
showNormal()204     void showNormal()
205     {
206         _mainWindow->showNormal();
207         centerWindow();
208     }
209 
setCaption(const QString & suiteName,const QString & testName)210     void setCaption(const QString &suiteName, const QString &testName)
211     {
212         _mainWindow->setCaption(_title + " - " + suiteName + "::" + testName + "()");
213     }
214 
showSuiteName(const QString & suiteName)215     void showSuiteName(const QString &suiteName)
216     {
217         _suiteName->setText("class " + suiteName);
218     }
219 
advanceProgressBar()220     void advanceProgressBar()
221     {
222         _progressBar->setProgress(_progressBar->progress() + 1);
223     }
224 
showTestName(const QString & testName)225     void showTestName(const QString &testName)
226     {
227         _testName->setText(testName + "()");
228     }
229 
showTestsDone(unsigned testsDone)230     void showTestsDone(unsigned testsDone)
231     {
232         _testsDone->setText(asString(testsDone) + " of " + _strTotalTests);
233     }
234 
asString(unsigned n)235     static QString asString(unsigned n)
236     {
237         return QString::number(n);
238     }
239 
setColor(int r,int g,int b)240     void setColor(int r, int g, int b)
241     {
242         QPalette palette = _progressBar->palette();
243         palette.setColor(QColorGroup::Highlight, QColor(r, g, b));
244         _progressBar->setPalette(palette);
245     }
246 
setIcon(QMessageBox::Icon icon)247     void setIcon(QMessageBox::Icon icon)
248     {
249 #if QT_VERSION >= 0x030000
250         _mainWindow->setIcon(QMessageBox::standardIcon(icon));
251 #else // Qt version < 3.0.0
252         _mainWindow->setIcon(QMessageBox::standardIcon(icon, QApplication::style().guiStyle()));
253 #endif // QT_VERSION
254     }
255 
processEvents()256     void processEvents()
257     {
258         _application->processEvents();
259     }
260 
centerWindow()261     void centerWindow()
262     {
263         QWidget *desktop = QApplication::desktop();
264         int xCenter = desktop->x() + (desktop->width() / 2);
265         int yCenter = desktop->y() + (desktop->height() / 2);
266 
267         int windowWidth = (desktop->width() * 4) / 5;
268         int windowHeight = _mainWindow->height();
269         _mainWindow->setGeometry(xCenter - (windowWidth / 2), yCenter - (windowHeight / 2), windowWidth, windowHeight);
270     }
271 
keep()272     bool keep()
273     {
274         if (!_keep)
275         {
276             return false;
277         }
278         if (!_startMinimized)
279         {
280             return true;
281         }
282         return (_mainWindow == _application->activeWindow());
283     }
284 
showSummary()285     void showSummary()
286     {
287         QString summary = _strTotalTests + (_numTotalTests == 1 ? " test" : " tests");
288         if (tracker().failedTests())
289         {
290             summary = "Failed " + asString(tracker().failedTests()) + " of " + summary;
291         }
292         else
293         {
294             summary = summary + " passed";
295         }
296 
297         _mainWindow->setCaption(_title + " - " + summary);
298 
299         _statusBar->removeWidget(_suiteName);
300         _statusBar->removeWidget(_testName);
301         _testsDone->setText(summary);
302     }
303 };
304 }
305 
306 #endif // __cxxtest__QtGui_h__
307