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