ctkWorkflowWidgetTest1.cpp 44 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924
  1. /*=========================================================================
  2. Library: CTK
  3. Copyright (c) 2010 Kitware Inc.
  4. Licensed under the Apache License, Version 2.0 (the "License");
  5. you may not use this file except in compliance with the License.
  6. You may obtain a copy of the License at
  7. http://www.commontk.org/LICENSE
  8. Unless required by applicable law or agreed to in writing, software
  9. distributed under the License is distributed on an "AS IS" BASIS,
  10. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  11. See the License for the specific language governing permissions and
  12. limitations under the License.
  13. =========================================================================*/
  14. // QT includes
  15. #include <QApplication>
  16. #include <QTimer>
  17. #include <QPushButton>
  18. #include <QLabel>
  19. #include <QLineEdit>
  20. #include <QList>
  21. #include <QIcon>
  22. #include <QStyle>
  23. // CTK includes
  24. #include "ctkWorkflow.h"
  25. #include "ctkWorkflowWidget.h"
  26. #include "ctkWorkflowStackedWidget.h"
  27. #include "ctkWorkflowTabWidget.h"
  28. #include "ctkExampleDerivedWorkflowWidgetStep.h"
  29. // STD includes
  30. #include <cstdlib>
  31. #include <iostream>
  32. // //-----------------------------------------------------------------------------
  33. bool buttonClickTest(QApplication& app, int defaultTime, ctkExampleDerivedWorkflowWidgetStep* shown, ctkExampleDerivedWorkflowWidgetStep* hidden, ctkWorkflow* workflow, ctkWorkflowWidget* workflowWidget, QPushButton* shownBackButton=0, QPushButton* shownNextButton=0, QPushButton* hiddenBackButton=0, QPushButton* hiddenNextButton=0, QPushButton* shownFinishButton=0, QPushButton* hiddenFinishButton = 0, QPushButton* shownFinishButton2=0, QPushButton* hiddenFinishButton2=0)
  34. {
  35. QTimer::singleShot(defaultTime, &app, SLOT(quit()));
  36. app.exec();
  37. // // ensure we are in the correct step
  38. if (workflow->currentStep() != shown)
  39. {
  40. std::cerr << "In incorrect step" << std::endl;
  41. return false;
  42. }
  43. // ensure that widgets of current step are visible and enabled
  44. if (!shown->stepArea()->isVisible() || (shownBackButton && !shownBackButton->isVisible()) || (shownNextButton && !shownNextButton->isVisible()) || !shown->label()->isVisible() || !shown->lineEdit()->isVisible() || (shownFinishButton && !shownFinishButton->isVisible()) || (shownFinishButton2 && !shownFinishButton2->isVisible()))
  45. {
  46. std::cerr << "Incorrect widget visibility - the current step's widgets are invisible" << std::endl;
  47. return false;
  48. }
  49. if ((shownBackButton && !shownBackButton->isEnabled()) || (shownNextButton && !shownNextButton->isEnabled()) || !shown->lineEdit()->isEnabled() || (shownFinishButton && !shownFinishButton->isEnabled()) || (shownFinishButton2 && !shownFinishButton2->isEnabled()))
  50. {
  51. std::cerr << "Incorrect widget visibility - the current step's widgets are disabled" << std::endl;
  52. return false;
  53. }
  54. // ensure that the shown step's name and description are shown in
  55. // the widget
  56. if (shown->name() != workflowWidget->title() || shown->description() != workflowWidget->subTitle())
  57. {
  58. std::cerr << "Incorrect widget title/subtitle" << std::endl;
  59. return false;
  60. }
  61. // ensure that the finish button has an icon
  62. if (shownFinishButton && shownFinishButton->icon().isNull())
  63. {
  64. std::cerr << "Incorrect finish icon visibility" << std::endl;
  65. return false;
  66. }
  67. // ensure that widgets of the other step are either invisible, or
  68. // visible but disabled
  69. if (hidden->stepArea())
  70. {
  71. if (hidden->stepArea()->isVisible() && workflowWidget->hideWidgetsOfNonCurrentSteps())
  72. {
  73. std::cerr << "Incorrect widget visibility - the other step's stepArea is showing" << std::endl;
  74. return false;
  75. }
  76. else if (hidden->stepArea()->isVisible() && hidden->stepArea()->isEnabled())
  77. {
  78. std::cerr << "Incorrect widget visibility - the other step's stepArea is enabled" << std::endl;
  79. return false;
  80. }
  81. }
  82. if (hidden->label())
  83. {
  84. if (hidden->label()->isVisible() && workflowWidget->hideWidgetsOfNonCurrentSteps())
  85. {
  86. std::cerr << "Incorrect widget visibility - the other step's label is showing" << std::endl;
  87. return false;
  88. }
  89. }
  90. if (hiddenBackButton)
  91. {
  92. if (hiddenBackButton->isVisible() && workflowWidget->hideWidgetsOfNonCurrentSteps())
  93. {
  94. std::cerr << "Incorrect widget visibility - the other step's backButton is showing" << std::endl;
  95. return false;
  96. }
  97. else if (hiddenBackButton->isVisible() && hiddenBackButton->isEnabled())
  98. {
  99. std::cerr << "Incorrect widget visibility - the other step's backButton is enabled" << std::endl;
  100. return false;
  101. }
  102. }
  103. if (hiddenNextButton)
  104. {
  105. if (hiddenNextButton->isVisible() && workflowWidget->hideWidgetsOfNonCurrentSteps())
  106. {
  107. std::cerr << "Incorrect widget visibility - the other step's nextButton is showing" << std::endl;
  108. return false;
  109. }
  110. else if (hiddenNextButton->isVisible() && hiddenNextButton->isEnabled())
  111. {
  112. std::cerr << "Incorrect widget visibility - the other step's nextButton is enabled" << std::endl;
  113. return false;
  114. }
  115. }
  116. if (hidden->lineEdit())
  117. {
  118. if (hidden->lineEdit()->isVisible() && workflowWidget->hideWidgetsOfNonCurrentSteps())
  119. {
  120. std::cerr << "Incorrect widget visibility - the other step's lineEdit is showing" << std::endl;
  121. return false;
  122. }
  123. else if (hidden->lineEdit()->isVisible() && hidden->lineEdit()->isEnabled())
  124. {
  125. std::cerr << "Incorrect widget visibility - the other step's lineEdit is enabled" << std::endl;
  126. return false;
  127. }
  128. }
  129. if (hiddenFinishButton)
  130. {
  131. if (hiddenFinishButton->isVisible() && workflowWidget->hideWidgetsOfNonCurrentSteps())
  132. {
  133. std::cerr << "Incorrect widget visibility - the other step's finishButton is showing" << std::endl;
  134. return false;
  135. }
  136. else if (hiddenFinishButton->isVisible() && hiddenFinishButton->isEnabled())
  137. {
  138. std::cerr << "Incorrect widget visibility - the other step's finishButton is enabled" << std::endl;
  139. return false;
  140. }
  141. }
  142. if (hiddenFinishButton2)
  143. {
  144. if (hiddenFinishButton2->isVisible() && workflowWidget->hideWidgetsOfNonCurrentSteps())
  145. {
  146. std::cerr << "Incorrect widget visibility - the other step's finishButton is showing" << std::endl;
  147. return false;
  148. }
  149. else if (hiddenFinishButton2->isVisible() && hiddenFinishButton->isEnabled())
  150. {
  151. std::cerr << "Incorrect widget visibility - the other step's finishButton is enabled" << std::endl;
  152. return false;
  153. }
  154. }
  155. return true;
  156. }
  157. //-----------------------------------------------------------------------------
  158. // simulates valid and invalid user interaction for a workflow with
  159. // two steps
  160. int userInteractionSimulator1(QApplication& app, ctkExampleDerivedWorkflowWidgetStep* testStep1, ctkExampleDerivedWorkflowWidgetStep* testStep2, ctkWorkflow* workflow, ctkWorkflowWidget* workflowWidget, int defaultTime)
  161. {
  162. int BACK_BUTTON_INDEX = 0;
  163. int NEXT_BUTTON_INDEX = 1;
  164. // test to ensure we can change the layout of the workflow widget
  165. workflowWidget->setDirection(QBoxLayout::LeftToRight);
  166. // get the buttons
  167. QPushButton* testStep1BackButton = 0;
  168. QPushButton* testStep1NextButton = 0;
  169. QPushButton* testStep2BackButton = 0;
  170. QPushButton* testStep2NextButton = 0;
  171. // get the back/next buttons for the first step
  172. QList<QPushButton*> buttons = testStep1->stepArea()->findChildren<QPushButton*>();
  173. // if (buttons.length() != 1)
  174. // {
  175. // std::cerr << "incorrect number of buttons for testStep1" << std::endl;
  176. // std::cerr << "number of buttons = " << buttons.length() << ", expecting 1" << std::endl;
  177. // return EXIT_FAILURE;
  178. // }
  179. testStep1NextButton = buttons.at(NEXT_BUTTON_INDEX);
  180. if (!testStep1NextButton || testStep1NextButton->text() != "Next")
  181. {
  182. std::cerr << "incorrect button assignment for testStep1" << std::endl;
  183. return EXIT_FAILURE;
  184. }
  185. // we should be in the first step at the start of the workflow
  186. if (!buttonClickTest(app, defaultTime, testStep1, testStep2, workflow, workflowWidget, testStep1BackButton, testStep1NextButton, testStep2BackButton, testStep2NextButton)) {return EXIT_FAILURE;}
  187. // tests with good input (lineEdit value = 100, which passes the
  188. // condition that it be >= 10)
  189. // CurrentStep ButtonPress ExpectedStep Shouldn'tDoAnything
  190. // step1 next step2
  191. // step2 back step1
  192. // step1 next step2
  193. // step2 back step1
  194. // normal forwards/backwards transitions
  195. testStep1NextButton->click();
  196. QTimer::singleShot(defaultTime, &app, SLOT(quit()));
  197. app.exec();
  198. // get the back/next buttons for the second step
  199. buttons = testStep2->stepArea()->findChildren<QPushButton*>();
  200. // if (buttons.length() != 1)
  201. // {
  202. // std::cerr << "incorrect number of buttons for testStep2" << std::endl;
  203. // std::cerr << "number of buttons = " << buttons.length() << ", expecting 1" << std::endl;
  204. // return EXIT_FAILURE;
  205. // }
  206. testStep2BackButton = buttons.at(BACK_BUTTON_INDEX);
  207. if (!testStep2BackButton || testStep2BackButton->text() != "Back")
  208. {
  209. std::cerr << "incorrect button assignment for testStep2" << std::endl;
  210. return EXIT_FAILURE;
  211. }
  212. if (!buttonClickTest(app, defaultTime, testStep2, testStep1, workflow, workflowWidget, testStep2BackButton, testStep2NextButton, testStep1BackButton, testStep1NextButton)) {return EXIT_FAILURE;}
  213. testStep2BackButton->click();
  214. if (!buttonClickTest(app, defaultTime, testStep1, testStep2, workflow, workflowWidget, testStep1BackButton, testStep1NextButton, testStep2BackButton, testStep2NextButton)) {return EXIT_FAILURE;}
  215. testStep1NextButton->click();
  216. if (!buttonClickTest(app, defaultTime, testStep2, testStep1, workflow, workflowWidget, testStep2BackButton, testStep2NextButton, testStep1BackButton, testStep1NextButton)) {return EXIT_FAILURE;}
  217. testStep2BackButton->click();
  218. if (!buttonClickTest(app, defaultTime, testStep1, testStep2, workflow, workflowWidget, testStep1BackButton, testStep1NextButton, testStep2BackButton, testStep2NextButton)) {return EXIT_FAILURE;}
  219. // tests with both good and bad input (lineEdit value may be
  220. // invalid)
  221. // CurrentStep ButtonPress Invalid input ExpectedStep
  222. // step1 next * step1
  223. // step1 next step2
  224. // step2 back * step1
  225. // step1 next * (empty) step1
  226. // step1 next step2
  227. // ensure transition to the next step fails on bad input
  228. testStep1->lineEdit()->setText("1");
  229. testStep1NextButton->click();
  230. if (!buttonClickTest(app, defaultTime, testStep1, testStep2, workflow, workflowWidget, testStep1BackButton, testStep1NextButton, testStep2BackButton, testStep2NextButton)) {return EXIT_FAILURE;}
  231. // now recover, going to the next step using some good input
  232. testStep1->lineEdit()->setText("100");
  233. testStep1NextButton->click();
  234. if (!buttonClickTest(app, defaultTime, testStep2, testStep1, workflow, workflowWidget, testStep2BackButton, testStep2NextButton, testStep1BackButton, testStep1NextButton)) {return EXIT_FAILURE;}
  235. // on bad input, going "Back" should be allowed
  236. testStep2BackButton->click();
  237. if (!buttonClickTest(app, defaultTime, testStep1, testStep2, workflow, workflowWidget, testStep1BackButton, testStep1NextButton, testStep2BackButton, testStep2NextButton)) {return EXIT_FAILURE;}
  238. // ensure transition to the next step fails on empty input
  239. testStep1->lineEdit()->setText("");
  240. testStep1NextButton->click();
  241. if (!buttonClickTest(app, defaultTime, testStep1, testStep2, workflow, workflowWidget, testStep1BackButton, testStep1NextButton, testStep2BackButton, testStep2NextButton)) {return EXIT_FAILURE;}
  242. // try again with some good input to ensure we can recover
  243. testStep1->lineEdit()->setText("100");
  244. testStep1NextButton->click();
  245. if (!buttonClickTest(app, defaultTime, testStep2, testStep1, workflow, workflowWidget, testStep2BackButton, testStep2NextButton, testStep1BackButton, testStep1NextButton)) {return EXIT_FAILURE;}
  246. // after adding the steps, then the widget's client area should have
  247. // them as a child
  248. if (!workflowWidget->clientArea()->isAncestorOf(testStep1->stepArea()))
  249. {
  250. std::cerr << "testStep1 was incorrectly added to the workflowWidget" << std::endl;
  251. return EXIT_FAILURE;
  252. }
  253. if (!workflowWidget->clientArea()->isAncestorOf(testStep2->stepArea()))
  254. {
  255. std::cerr << "testStep2 was incorrectly added to the workflowWidget" << std::endl;
  256. return EXIT_FAILURE;
  257. }
  258. return EXIT_SUCCESS;
  259. }
  260. //-----------------------------------------------------------------------------
  261. // simulates valid and invalid user interaction for a workflow with
  262. // three steps
  263. int userInteractionSimulator2(QApplication& app, ctkExampleDerivedWorkflowWidgetStep* testStep1, ctkExampleDerivedWorkflowWidgetStep* testStep2, ctkExampleDerivedWorkflowWidgetStep* testStep3, bool hideWidgets, ctkWorkflow* workflow, ctkWorkflowWidget* workflowWidget, int defaultTime)
  264. {
  265. int BACK_BUTTON_INDEX = 0;
  266. int NEXT_BUTTON_INDEX = 1;
  267. int FINISH_BUTTON_INDEX_1 = 2;
  268. // test that the setDirection layout was applied
  269. // properly: the widget should be much wider than it is tall
  270. QSize size = workflowWidget->size();
  271. int height = size.height();
  272. int width = size.width();
  273. if (height >= (width/2))
  274. {
  275. std::cerr << "The workflow widget is too tall - was the direction applied?" << std::endl;
  276. return EXIT_FAILURE;
  277. }
  278. // test that we can change the layout of the stepAreas: it should be
  279. // wider than it was before
  280. testStep1->setStepAreaDirection(QBoxLayout::LeftToRight);
  281. testStep2->setStepAreaDirection(QBoxLayout::LeftToRight);
  282. QTimer::singleShot(defaultTime, &app, SLOT(quit()));
  283. app.exec();
  284. size = workflowWidget->size();
  285. if (size.width() <= width)
  286. {
  287. std::cerr << "The workflow widget did not increase in width after setting the step area direction to LeftToRight" << std::endl;
  288. return EXIT_FAILURE;
  289. }
  290. // test to ensure we can change the layout of the workflow widget's
  291. // client area after having added some steps to it
  292. if (ctkWorkflowAbstractPagedWidget* pagedWidget = qobject_cast<ctkWorkflowAbstractPagedWidget*>(workflowWidget))
  293. {
  294. pagedWidget->setClientAreaDirection(QBoxLayout::LeftToRight);
  295. }
  296. else
  297. {
  298. workflowWidget->setClientAreaDirection(QBoxLayout::LeftToRight);
  299. }
  300. // ensure we can get the pages/layouts we may want
  301. if (ctkWorkflowAbstractPagedWidget* pagedWidget = qobject_cast<ctkWorkflowAbstractPagedWidget*>(workflowWidget))
  302. {
  303. if (!pagedWidget->getWidgetFromIndex(1))
  304. {
  305. std::cerr << "could not access widget for page 1" << std::endl;
  306. return EXIT_FAILURE;
  307. }
  308. if (!pagedWidget->getWidgetFromIndex(1)->layout())
  309. {
  310. std::cerr << "could not access client area layout for page 1" << std::endl;
  311. return EXIT_FAILURE;
  312. }
  313. }
  314. else
  315. {
  316. if (!workflowWidget->clientArea()->layout())
  317. {
  318. std::cerr << "could not access client area layout" << std::endl;
  319. return EXIT_FAILURE;
  320. }
  321. }
  322. // get the buttons
  323. QPushButton* testStep1BackButton = 0;
  324. QPushButton* testStep1NextButton = 0;
  325. QPushButton* testStep1FinishButton = 0;
  326. QPushButton* testStep2BackButton = 0;
  327. QPushButton* testStep2NextButton = 0;
  328. QPushButton* testStep2FinishButton = 0;
  329. QPushButton* testStep3BackButton = 0;
  330. QPushButton* testStep3NextButton = 0;
  331. QPushButton* testStep3FinishButton = 0;
  332. // get the back/next buttons for the first step
  333. QList<QPushButton*> buttons = testStep1->stepArea()->findChildren<QPushButton*>();
  334. // if (buttons.length() != 2)
  335. // {
  336. // std::cerr << "incorrect number of buttons for testStep1" << std::endl;
  337. // std::cerr << "number of buttons = " << buttons.length() << ", expecting 2" << std::endl;
  338. // return EXIT_FAILURE;
  339. // }
  340. testStep1NextButton = buttons.at(NEXT_BUTTON_INDEX);
  341. testStep1FinishButton = buttons.at(FINISH_BUTTON_INDEX_1);
  342. if (!testStep1NextButton || !testStep1FinishButton || testStep1NextButton->text() != "Next" || testStep1FinishButton->text() != "Step 3")
  343. {
  344. std::cerr << "incorrect button assignment for testStep1" << std::endl;
  345. return EXIT_FAILURE;
  346. }
  347. // we should be in the first step when we start the workflow
  348. if (!buttonClickTest(app, defaultTime, testStep1, testStep2, workflow, workflowWidget, testStep1BackButton, testStep1NextButton, testStep2BackButton, testStep2NextButton, testStep1FinishButton, testStep2FinishButton)) {return EXIT_FAILURE;}
  349. // tests with good input (lineEdit value = 100, which passes the
  350. // condition that it be >= 10)
  351. // CurrentStep ButtonPress ExpectedStep Shouldn'tDoAnything
  352. // step1 next step2
  353. // step2 next step3
  354. // step3 back step2
  355. // step2 back step1
  356. // step1 next step2
  357. // step2 next step3
  358. // step3 back step2
  359. // normal forwards/backwards transitions
  360. testStep1NextButton->click();
  361. QTimer::singleShot(defaultTime, &app, SLOT(quit()));
  362. app.exec();
  363. // get the back/next buttons for the second step
  364. buttons = testStep2->stepArea()->findChildren<QPushButton*>();
  365. // if (buttons.length() != 3)
  366. // {
  367. // std::cerr << "incorrect number of buttons for testStep2" << std::endl;
  368. // std::cerr << "number of buttons = " << buttons.length() << ", expecting 3" << std::endl;
  369. // return EXIT_FAILURE;
  370. // }
  371. testStep2BackButton = buttons.at(BACK_BUTTON_INDEX);
  372. testStep2NextButton = buttons.at(NEXT_BUTTON_INDEX);
  373. testStep2FinishButton = buttons.at(FINISH_BUTTON_INDEX_1);
  374. if (!testStep2BackButton || !testStep2NextButton || !testStep2FinishButton || testStep2BackButton->text() != "Back" || testStep2NextButton->text() != "Next" || testStep2FinishButton->text() != "Step 3")
  375. {
  376. std::cerr << "incorrect button assignment for testStep2" << std::endl;
  377. return EXIT_FAILURE;
  378. }
  379. if (!buttonClickTest(app, defaultTime, testStep2, testStep1, workflow, workflowWidget, testStep2BackButton, testStep2NextButton, testStep1BackButton, testStep1NextButton, testStep2FinishButton, testStep1FinishButton)) {return EXIT_FAILURE;}
  380. testStep2->lineEdit()->setText("100");
  381. testStep2NextButton->click();
  382. QTimer::singleShot(defaultTime, &app, SLOT(quit()));
  383. app.exec();
  384. // get the back/next buttons for the third step
  385. buttons = testStep3->stepArea()->findChildren<QPushButton*>();
  386. // if (buttons.length() != 2)
  387. // {
  388. // std::cerr << "incorrect number of buttons for testStep3" << std::endl;
  389. // std::cerr << "number of buttons = " << buttons.length() << ", expecting 2" << std::endl;
  390. // return EXIT_FAILURE;
  391. // }
  392. testStep3BackButton = buttons.at(BACK_BUTTON_INDEX);
  393. testStep3FinishButton = buttons.at(FINISH_BUTTON_INDEX_1);
  394. if (!testStep3BackButton || !testStep3FinishButton || testStep3BackButton->text() != "Back" || testStep3FinishButton->text() != "Step 3")
  395. {
  396. std::cerr << "incorrect button assignment for testStep3" << std::endl;
  397. return EXIT_FAILURE;
  398. }
  399. if (!buttonClickTest(app, defaultTime, testStep3, testStep2, workflow, workflowWidget, testStep3BackButton, testStep3NextButton, testStep2BackButton, testStep2NextButton, testStep3FinishButton, testStep2FinishButton)) {return EXIT_FAILURE;}
  400. // test that the setClientAreaDirection layout was applied properly:
  401. // the widget should be quite a bit wider than it was before
  402. if (!hideWidgets)
  403. {
  404. QSize size = workflowWidget->size();
  405. if (size.width() <= width)
  406. {
  407. std::cerr << "The workflow widget is not wide enough - was the clientAreaDirection applied?" << std::endl;
  408. return EXIT_FAILURE;
  409. }
  410. }
  411. testStep3BackButton->click();
  412. if (!buttonClickTest(app, defaultTime, testStep2, testStep3, workflow, workflowWidget, testStep2BackButton, testStep2NextButton, testStep3BackButton, testStep3NextButton, testStep2FinishButton, testStep3FinishButton)) {return EXIT_FAILURE;}
  413. testStep2BackButton->click();
  414. if (!buttonClickTest(app, defaultTime, testStep1, testStep2, workflow, workflowWidget, testStep1BackButton, testStep1NextButton, testStep2BackButton, testStep2NextButton, testStep1FinishButton, testStep2FinishButton)) {return EXIT_FAILURE;}
  415. // normal forwards/backwards transitions
  416. testStep1NextButton->click();
  417. if (!buttonClickTest(app, defaultTime, testStep2, testStep1, workflow, workflowWidget, testStep2BackButton, testStep2NextButton, testStep1BackButton, testStep1NextButton, testStep2FinishButton, testStep1FinishButton)) {return EXIT_FAILURE;}
  418. testStep2NextButton->click();
  419. if (!buttonClickTest(app, defaultTime, testStep3, testStep2, workflow, workflowWidget, testStep3BackButton, testStep3NextButton, testStep2BackButton, testStep2NextButton, testStep3FinishButton, testStep2FinishButton)) {return EXIT_FAILURE;}
  420. testStep3BackButton->click();
  421. if (!buttonClickTest(app, defaultTime, testStep2, testStep3, workflow, workflowWidget, testStep2BackButton, testStep2NextButton, testStep3BackButton, testStep3NextButton, testStep2FinishButton, testStep3FinishButton)) {return EXIT_FAILURE;}
  422. // tests with both good and bad input (lineEdit value may be
  423. // invalid)
  424. // CurrentStep ButtonPress Invalid input ExpectedStep
  425. // step2 next * step2
  426. // step2 next step3
  427. // step3 back * step2
  428. // step2 next * (empty) step2
  429. // step2 next step3
  430. // ensure transition to the next step fails on bad input
  431. testStep2->lineEdit()->setText("1");
  432. testStep2NextButton->click();
  433. if (!buttonClickTest(app, defaultTime, testStep2, testStep3, workflow, workflowWidget, testStep2BackButton, testStep2NextButton, testStep3BackButton, testStep3NextButton, testStep2FinishButton, testStep3FinishButton)) {return EXIT_FAILURE;}
  434. // now recover, going to the next step with some good input
  435. testStep2->lineEdit()->setText("100");
  436. testStep2NextButton->click();
  437. if (!buttonClickTest(app, defaultTime, testStep3, testStep2, workflow, workflowWidget, testStep3BackButton, testStep3NextButton, testStep2BackButton, testStep2NextButton, testStep3FinishButton, testStep2FinishButton)) {return EXIT_FAILURE;}
  438. // on bad input, going "Back" should be allowed
  439. testStep3BackButton->click();
  440. if (!buttonClickTest(app, defaultTime, testStep2, testStep3, workflow, workflowWidget, testStep2BackButton, testStep2NextButton, testStep3BackButton, testStep3NextButton, testStep2FinishButton, testStep3FinishButton)) {return EXIT_FAILURE;}
  441. // ensure transition to the next step fails on empty input
  442. testStep2->lineEdit()->setText("");
  443. testStep2NextButton->click();
  444. if (!buttonClickTest(app, defaultTime, testStep2, testStep3, workflow, workflowWidget, testStep2BackButton, testStep2NextButton, testStep3BackButton, testStep3NextButton, testStep2FinishButton, testStep3FinishButton)) {return EXIT_FAILURE;}
  445. // try again with some good input to ensure we can recover
  446. testStep2->lineEdit()->setText("100");
  447. testStep2NextButton->click();
  448. if (!buttonClickTest(app, defaultTime, testStep3, testStep2, workflow, workflowWidget, testStep3BackButton, testStep3NextButton, testStep2BackButton, testStep2NextButton, testStep3FinishButton, testStep2FinishButton)) {return EXIT_FAILURE;}
  449. // tests going to the finish step
  450. // CurrentStep ButtonPress Invalid input ExpectedStep
  451. // step1 finish step1
  452. // step1 finish step1
  453. // step1 next step2
  454. // step2 finish step2
  455. // step2 next step3
  456. // step3 finish step3
  457. // step3 back step2
  458. // step2 finish step2
  459. // step2 back step1
  460. // step1 finish step1
  461. // first go back to the beginning
  462. testStep3->lineEdit()->setText("100");
  463. testStep3BackButton->click();
  464. QTimer::singleShot(defaultTime, &app, SLOT(quit()));
  465. app.exec();
  466. testStep2BackButton->click();
  467. if (!buttonClickTest(app, defaultTime, testStep1, testStep2, workflow, workflowWidget, testStep1BackButton, testStep1NextButton, testStep2BackButton, testStep2NextButton, testStep1FinishButton, testStep2FinishButton)) {return EXIT_FAILURE;}
  468. testStep1FinishButton->click();
  469. if (!buttonClickTest(app, defaultTime, testStep1, testStep3, workflow, workflowWidget, testStep1BackButton, testStep1NextButton, testStep3BackButton, testStep3NextButton, testStep1FinishButton, testStep3FinishButton)) {return EXIT_FAILURE;}
  470. testStep1FinishButton->click();
  471. if (!buttonClickTest(app, defaultTime, testStep1, testStep3, workflow, workflowWidget, testStep1BackButton, testStep1NextButton, testStep3BackButton, testStep3NextButton, testStep1FinishButton, testStep3FinishButton)) {return EXIT_FAILURE;}
  472. testStep1NextButton->click();
  473. if (!buttonClickTest(app, defaultTime, testStep2, testStep1, workflow, workflowWidget, testStep2BackButton, testStep2NextButton, testStep1BackButton, testStep1NextButton, testStep2FinishButton, testStep1FinishButton)) {return EXIT_FAILURE;}
  474. testStep2FinishButton->click();
  475. if (!buttonClickTest(app, defaultTime, testStep2, testStep3, workflow, workflowWidget, testStep2BackButton, testStep2NextButton, testStep3BackButton, testStep3NextButton, testStep2FinishButton, testStep3FinishButton)) {return EXIT_FAILURE;}
  476. testStep2NextButton->click();
  477. if (!buttonClickTest(app, defaultTime, testStep3, testStep2, workflow, workflowWidget, testStep3BackButton, testStep3NextButton, testStep2BackButton, testStep2NextButton, testStep3FinishButton, testStep2FinishButton)) {return EXIT_FAILURE;}
  478. testStep3FinishButton->click();
  479. if (!buttonClickTest(app, defaultTime, testStep3, testStep2, workflow, workflowWidget, testStep3BackButton, testStep3NextButton, testStep2BackButton, testStep2NextButton, testStep3FinishButton, testStep2FinishButton)) {return EXIT_FAILURE;}
  480. testStep3BackButton->click();
  481. if (!buttonClickTest(app, defaultTime, testStep2, testStep3, workflow, workflowWidget, testStep2BackButton, testStep2NextButton, testStep3BackButton, testStep3NextButton, testStep2FinishButton, testStep3FinishButton)) {return EXIT_FAILURE;}
  482. testStep2FinishButton->click();
  483. if (!buttonClickTest(app, defaultTime, testStep2, testStep3, workflow, workflowWidget, testStep2BackButton, testStep2NextButton, testStep3BackButton, testStep3NextButton, testStep2FinishButton, testStep3FinishButton)) {return EXIT_FAILURE;}
  484. testStep2BackButton->click();
  485. if (!buttonClickTest(app, defaultTime, testStep1, testStep2, workflow, workflowWidget, testStep1BackButton, testStep1NextButton, testStep2BackButton, testStep2NextButton, testStep1FinishButton, testStep2FinishButton)) {return EXIT_FAILURE;}
  486. testStep1FinishButton->click();
  487. if (!buttonClickTest(app, defaultTime, testStep1, testStep3, workflow, workflowWidget, testStep1BackButton, testStep1NextButton, testStep3BackButton, testStep3NextButton, testStep1FinishButton, testStep3FinishButton)) {return EXIT_FAILURE;}
  488. // tests going to the finish step with invalid input
  489. // CurrentStep ButtonPress Invalid input ExpectedStep
  490. // step1 finish * (step2) step2
  491. // step2 next step3
  492. // step3 back step2
  493. // step2 finish * (step2) step2
  494. // step2 back step1
  495. // step1 finish * (step3) step1
  496. testStep2->lineEdit()->setText("0");
  497. testStep1FinishButton->click();
  498. if (!buttonClickTest(app, defaultTime, testStep2, testStep1, workflow, workflowWidget, testStep2BackButton, testStep2NextButton, testStep1BackButton, testStep1NextButton, testStep2FinishButton, testStep1FinishButton)) {return EXIT_FAILURE;}
  499. testStep2->lineEdit()->setText("100");
  500. testStep2NextButton->click();
  501. if (!buttonClickTest(app, defaultTime, testStep3, testStep2, workflow, workflowWidget, testStep3BackButton, testStep3NextButton, testStep2BackButton, testStep2NextButton, testStep3FinishButton, testStep2FinishButton)) {return EXIT_FAILURE;}
  502. testStep3BackButton->click();
  503. if (!buttonClickTest(app, defaultTime, testStep2, testStep3, workflow, workflowWidget, testStep2BackButton, testStep2NextButton, testStep3BackButton, testStep3NextButton, testStep2FinishButton, testStep3FinishButton)) {return EXIT_FAILURE;}
  504. testStep2->lineEdit()->setText("0");
  505. testStep2FinishButton->click();
  506. if (!buttonClickTest(app, defaultTime, testStep2, testStep3, workflow, workflowWidget, testStep2BackButton, testStep2NextButton, testStep3BackButton, testStep3NextButton, testStep2FinishButton, testStep3FinishButton)) {return EXIT_FAILURE;}
  507. testStep2BackButton->click();
  508. if (!buttonClickTest(app, defaultTime, testStep1, testStep2, workflow, workflowWidget, testStep1BackButton, testStep1NextButton, testStep2BackButton, testStep2NextButton, testStep1FinishButton, testStep2FinishButton)) {return EXIT_FAILURE;}
  509. testStep2->lineEdit()->setText("100");
  510. testStep3->lineEdit()->setText("0");
  511. testStep1FinishButton->click();
  512. if (!buttonClickTest(app, defaultTime, testStep1, testStep3, workflow, workflowWidget, testStep1BackButton, testStep1NextButton, testStep3BackButton, testStep3NextButton, testStep1FinishButton, testStep3FinishButton)) {return EXIT_FAILURE;}
  513. // calling showWidget() with a widget that hasn't been previously
  514. // used with addWidget() would work for ctkWorkflowWidget, but not
  515. // ctkWorkflowAbstractPagedWidget) - make sure it fails
  516. if (ctkWorkflowAbstractPagedWidget* pagedWidget = qobject_cast<ctkWorkflowAbstractPagedWidget*>(workflowWidget))
  517. {
  518. QWidget* test = new QWidget;
  519. pagedWidget->showWidget(test);
  520. if (test->isVisible())
  521. {
  522. std::cerr << "calling ctkWorkflowAbstractPagedWidget::showWidget() using a widget that was not previously added seems to work - and it shouldn't" << std::endl;
  523. return EXIT_FAILURE;
  524. }
  525. }
  526. // after adding the steps, then the widget's client area should have
  527. // them as a child
  528. if (!workflowWidget->clientArea()->isAncestorOf(testStep3->stepArea()))
  529. {
  530. std::cerr << "testStep3 was incorrectly added to the workflowWidget" << std::endl;
  531. return EXIT_FAILURE;
  532. }
  533. return EXIT_SUCCESS;
  534. }
  535. //-----------------------------------------------------------------------------
  536. // simulates valid and invalid user interaction for a workflow with
  537. // three steps and two finish steps
  538. int userInteractionSimulator3(QApplication& app, ctkExampleDerivedWorkflowWidgetStep* testStep1, ctkExampleDerivedWorkflowWidgetStep* testStep2, ctkExampleDerivedWorkflowWidgetStep* testStep3, ctkWorkflow* workflow, ctkWorkflowWidget* workflowWidget, int defaultTime)
  539. {
  540. int BACK_BUTTON_INDEX = 0;
  541. int NEXT_BUTTON_INDEX = 1;
  542. int FINISH_BUTTON_INDEX_1 = 2;
  543. int FINISH_BUTTON_INDEX_2 = 3;
  544. // get the buttons
  545. QPushButton* testStep1BackButton = 0;
  546. QPushButton* testStep1NextButton = 0;
  547. QPushButton* testStep1FinishButton1 = 0;
  548. QPushButton* testStep1FinishButton2 = 0;
  549. QPushButton* testStep2BackButton = 0;
  550. QPushButton* testStep2NextButton = 0;
  551. QPushButton* testStep2FinishButton1 = 0;
  552. QPushButton* testStep2FinishButton2 = 0;
  553. QPushButton* testStep3BackButton = 0;
  554. QPushButton* testStep3NextButton = 0;
  555. QPushButton* testStep3FinishButton1 = 0;
  556. QPushButton* testStep3FinishButton2 = 0;
  557. // get the back/next buttons for the first step
  558. QList<QPushButton*> buttons = testStep1->stepArea()->findChildren<QPushButton*>();
  559. // if (buttons.length() != 3)
  560. // {
  561. // std::cerr << "incorrect number of buttons for testStep1" << std::endl;
  562. // std::cerr << "number of buttons = " << buttons.length() << ", expecting 3" << std::endl;
  563. // return EXIT_FAILURE;
  564. // }
  565. testStep1NextButton = buttons.at(NEXT_BUTTON_INDEX);
  566. testStep1FinishButton1 = buttons.at(FINISH_BUTTON_INDEX_1);
  567. testStep1FinishButton2 = buttons.at(FINISH_BUTTON_INDEX_2);
  568. if (!testStep1NextButton || !testStep1FinishButton1 || !testStep1FinishButton2 || testStep1NextButton->text() != "Next" || testStep1FinishButton1->text() != "finish" || testStep1FinishButton2->text() != "finish")
  569. {
  570. std::cerr << "incorrect button assignment for testStep1" << std::endl;
  571. return EXIT_FAILURE;
  572. }
  573. // we should be in the first step
  574. if (!buttonClickTest(app, defaultTime, testStep1, testStep2, workflow, workflowWidget, testStep1BackButton, testStep1NextButton, testStep2BackButton, testStep2NextButton, testStep1FinishButton1, testStep2FinishButton1, testStep1FinishButton2, testStep2FinishButton2)) {return EXIT_FAILURE;}
  575. // tests with good input, so that we can get all of the buttons
  576. // (lineEdit value = 100, which passes the condition that it be >= 10)
  577. // CurrentStep ButtonPress ExpectedStep Shouldn'tDoAnything
  578. // step1 next step2
  579. // step2 next step3
  580. // normal forwards/backwards transitions
  581. testStep1NextButton->click();
  582. QTimer::singleShot(defaultTime, &app, SLOT(quit()));
  583. app.exec();
  584. // get the back/next buttons for the second step
  585. buttons = testStep2->stepArea()->findChildren<QPushButton*>();
  586. // if (buttons.length() != 4)
  587. // {
  588. // std::cerr << "incorrect number of buttons for testStep2" << std::endl;
  589. // std::cerr << "number of buttons = " << buttons.length() << ", expecting 4" << std::endl;
  590. // return EXIT_FAILURE;
  591. // }
  592. testStep2BackButton = buttons.at(BACK_BUTTON_INDEX);
  593. testStep2NextButton = buttons.at(NEXT_BUTTON_INDEX);
  594. testStep2FinishButton1 = buttons.at(FINISH_BUTTON_INDEX_1);
  595. testStep2FinishButton2 = buttons.at(FINISH_BUTTON_INDEX_2);
  596. if (!testStep2BackButton || !testStep2NextButton || !testStep2FinishButton1 || !testStep2FinishButton2 || testStep2BackButton->text() != "Back" || testStep2NextButton->text() != "Next" || testStep2FinishButton1->text() != "finish" || testStep2FinishButton2->text() != "finish")
  597. {
  598. std::cerr << "incorrect button assignment for testStep2" << std::endl;
  599. return EXIT_FAILURE;
  600. }
  601. if (!buttonClickTest(app, defaultTime, testStep2, testStep1, workflow, workflowWidget, testStep2BackButton, testStep2NextButton, testStep1BackButton, testStep1NextButton, testStep2FinishButton1, testStep1FinishButton1, testStep2FinishButton2, testStep1FinishButton2)) {return EXIT_FAILURE;}
  602. testStep2NextButton->click();
  603. QTimer::singleShot(defaultTime, &app, SLOT(quit()));
  604. app.exec();
  605. // get the back/next buttons for the third step
  606. buttons = testStep3->stepArea()->findChildren<QPushButton*>();
  607. // if (buttons.length() != 3)
  608. // {
  609. // std::cerr << "incorrect number of buttons for testStep3" << std::endl;
  610. // std::cerr << "number of buttons = " << buttons.length() << ", expecting 3" << std::endl;
  611. // return EXIT_FAILURE;
  612. // }
  613. testStep3BackButton = buttons.at(BACK_BUTTON_INDEX);
  614. testStep3FinishButton1 = buttons.at(FINISH_BUTTON_INDEX_1);
  615. testStep3FinishButton2 = buttons.at(FINISH_BUTTON_INDEX_2);
  616. if (!testStep3BackButton || !testStep3FinishButton1 || !testStep3FinishButton2 || testStep3BackButton->text() != "Back" || testStep3FinishButton1->text() != "finish" || testStep3FinishButton2->text() != "finish")
  617. {
  618. std::cerr << "incorrect button assignment for testStep3" << std::endl;
  619. return EXIT_FAILURE;
  620. }
  621. if (!buttonClickTest(app, defaultTime, testStep3, testStep2, workflow, workflowWidget, testStep3BackButton, testStep3NextButton, testStep2BackButton, testStep2NextButton, testStep3FinishButton1, testStep2FinishButton1, testStep3FinishButton2, testStep2FinishButton2)) {return EXIT_FAILURE;}
  622. // tests going to the finish step
  623. // CurrentStep ButtonPress Invalid input ExpectedStep
  624. // step3 back step2
  625. // step2 back step1
  626. // step1 finish1 step1
  627. // step1 next step2
  628. // step2 finish1 step2
  629. // step2 finish2 step2
  630. // step2 back step1
  631. // step1 finish2 step1
  632. // step1 next step2
  633. testStep3BackButton->click();
  634. if (!buttonClickTest(app, defaultTime, testStep2, testStep3, workflow, workflowWidget, testStep2BackButton, testStep2NextButton, testStep3BackButton, testStep3NextButton, testStep2FinishButton1, testStep3FinishButton1, testStep2FinishButton2, testStep3FinishButton2)) {return EXIT_FAILURE;}
  635. testStep2BackButton->click();
  636. if (!buttonClickTest(app, defaultTime, testStep1, testStep2, workflow, workflowWidget, testStep1BackButton, testStep1NextButton, testStep2BackButton, testStep2NextButton, testStep1FinishButton1, testStep2FinishButton1, testStep1FinishButton2, testStep2FinishButton2)) {return EXIT_FAILURE;}
  637. testStep1FinishButton1->click();
  638. if (!buttonClickTest(app, defaultTime, testStep1, testStep3, workflow, workflowWidget, testStep1BackButton, testStep1NextButton, testStep3BackButton, testStep3BackButton, testStep1FinishButton1, testStep3FinishButton1, testStep1FinishButton2, testStep3FinishButton2)) {return EXIT_FAILURE;}
  639. testStep1NextButton->click();
  640. if (!buttonClickTest(app, defaultTime, testStep2, testStep1, workflow, workflowWidget, testStep2BackButton, testStep2NextButton, testStep1BackButton, testStep1BackButton, testStep2FinishButton1, testStep1FinishButton1, testStep2FinishButton2, testStep1FinishButton2)) {return EXIT_FAILURE;}
  641. testStep2FinishButton1->click();
  642. if (!buttonClickTest(app, defaultTime, testStep2, testStep3, workflow, workflowWidget, testStep2BackButton, testStep2NextButton, testStep3BackButton, testStep3NextButton, testStep2FinishButton1, testStep3FinishButton1, testStep2FinishButton2, testStep3FinishButton2)) {return EXIT_FAILURE;}
  643. testStep2FinishButton2->click();
  644. if (!buttonClickTest(app, defaultTime, testStep2, testStep3, workflow, workflowWidget, testStep2BackButton, testStep2NextButton, testStep3BackButton, testStep3NextButton, testStep2FinishButton1, testStep3FinishButton1, testStep2FinishButton2, testStep3FinishButton2)) {return EXIT_FAILURE;}
  645. testStep2BackButton->click();
  646. if (!buttonClickTest(app, defaultTime, testStep1, testStep2, workflow, workflowWidget, testStep1BackButton, testStep1NextButton, testStep2BackButton, testStep2NextButton, testStep1FinishButton1, testStep2FinishButton1, testStep1FinishButton2, testStep2FinishButton2)) {return EXIT_FAILURE;}
  647. testStep1FinishButton2->click();
  648. if (!buttonClickTest(app, defaultTime, testStep1, testStep2, workflow, workflowWidget, testStep1BackButton, testStep1NextButton, testStep2BackButton, testStep2BackButton, testStep1FinishButton1, testStep2FinishButton1, testStep1FinishButton2, testStep2FinishButton2)) {return EXIT_FAILURE;}
  649. testStep1NextButton->click();
  650. if (!buttonClickTest(app, defaultTime, testStep2, testStep1, workflow, workflowWidget, testStep2BackButton, testStep2NextButton, testStep1BackButton, testStep1BackButton, testStep2FinishButton1, testStep1FinishButton1, testStep2FinishButton2, testStep1FinishButton2)) {return EXIT_FAILURE;}
  651. return EXIT_SUCCESS;
  652. }
  653. //-----------------------------------------------------------------------------
  654. int runWorkflowWidgetTest(ctkWorkflowWidget* workflowWidget, QApplication& app, bool hideWidgets, int defaultTime)
  655. {
  656. ctkWorkflow* workflow = new ctkWorkflow;
  657. workflowWidget->setWorkflow(workflow);
  658. workflowWidget->setPreText("I am some pre-text");
  659. workflowWidget->setPostText("I am some post-text");
  660. workflowWidget->setHideWidgetsOfNonCurrentSteps(hideWidgets);
  661. workflowWidget->setHasButtonBoxWidget(false);
  662. // create and add the first workflow step (depends on workflowWidget
  663. // type)
  664. ctkExampleDerivedWorkflowWidgetStep* testStep1 = new ctkExampleDerivedWorkflowWidgetStep(workflow, "Step 1");
  665. testStep1->setName("Step 1");
  666. testStep1->setDescription("I am in step 1");
  667. if (ctkWorkflowTabWidget* tabWidget = qobject_cast<ctkWorkflowTabWidget*>(workflowWidget))
  668. {
  669. tabWidget->addStepArea(testStep1, "tab1");
  670. }
  671. testStep1->setHasButtonBoxWidget(true);
  672. // testStep1 is the initial step
  673. workflow->setInitialStep(testStep1);
  674. // create and add the second workflow step (depends on
  675. // workflowWidget type)
  676. ctkExampleDerivedWorkflowWidgetStep* testStep2 = new ctkExampleDerivedWorkflowWidgetStep(workflow, "Step 2");
  677. testStep2->setName("Step 2");
  678. testStep2->setDescription("I am in step 2");
  679. if (ctkWorkflowTabWidget* tabWidget = qobject_cast<ctkWorkflowTabWidget*>(workflowWidget))
  680. {
  681. tabWidget->addStepArea(testStep2, "tab2");
  682. }
  683. testStep2->setHasButtonBoxWidget(true);
  684. // add the steps to the workflow
  685. workflow->addTransition(testStep1, testStep2);
  686. // start the workflow
  687. workflow->start();
  688. workflowWidget->show();
  689. // first user interaction test
  690. if (userInteractionSimulator1(app, testStep1, testStep2, workflow, workflowWidget, defaultTime) == EXIT_FAILURE)
  691. {
  692. return EXIT_FAILURE;
  693. }
  694. // stop the workflow
  695. workflow->stop();
  696. QTimer::singleShot(defaultTime, &app, SLOT(quit()));
  697. app.exec();
  698. // create and add a third workflow step (depends on workflowWidget
  699. // type)
  700. ctkExampleDerivedWorkflowWidgetStep* testStep3 = new ctkExampleDerivedWorkflowWidgetStep(workflow, "Step 3");
  701. testStep3->setName("Step 3");
  702. testStep3->setDescription("I am in step 3");
  703. if (ctkWorkflowStackedWidget* stackedWidget = qobject_cast<ctkWorkflowStackedWidget*>(workflowWidget))
  704. {
  705. stackedWidget->addStepArea(testStep3, 1);
  706. }
  707. else if (ctkWorkflowTabWidget* tabWidget = qobject_cast<ctkWorkflowTabWidget*>(workflowWidget))
  708. {
  709. tabWidget->addStepArea(testStep3, 1, "tab2");
  710. }
  711. testStep3->setHasButtonBoxWidget(true);
  712. // icon test - add an icon to testStep3, should show up as a icon on the finish button
  713. testStep3->setIcon(testStep3->stepArea()->style()->standardIcon(QStyle::SP_ArrowUp));
  714. workflow->addTransition(testStep2, testStep3);
  715. // restart the workflow
  716. workflow->start();
  717. // second user interaction test
  718. if (userInteractionSimulator2(app, testStep1, testStep2, testStep3, hideWidgets, workflow, workflowWidget, defaultTime) == EXIT_FAILURE)
  719. {
  720. return EXIT_FAILURE;
  721. }
  722. // stop the workflow
  723. workflow->stop();
  724. QTimer::singleShot(defaultTime, &app, SLOT(quit()));
  725. app.exec();
  726. // TODO put back once we can have more than one finish step
  727. // make the second workflow step a finish step as well
  728. // finishSteps.push_back(testStep2);
  729. // testStep1->setFinishStepsToHaveButtonsInStepArea(finishSteps);
  730. // testStep2->setFinishStepsToHaveButtonsInStepArea(finishSteps);
  731. // testStep3->setFinishStepsToHaveButtonsInStepArea(finishSteps);
  732. // // workflow->addFinishStep(testStep2);
  733. // // restart the workflow
  734. // workflow->start();
  735. // QTimer::singleShot(defaultTime, &app, SLOT(quit()));
  736. // app.exec();
  737. // // third user interfaction test
  738. // if (userInteractionSimulator3(app, testStep1, testStep2, testStep3, workflow, workflowWidget, defaultTime) == EXIT_FAILURE)
  739. // {
  740. // return EXIT_FAILURE;
  741. // }
  742. // // stop the workflow
  743. // workflow->stop();
  744. // QTimer::singleShot(defaultTime, &app, SLOT(quit()));
  745. // app.exec();
  746. // handles deletion of the workflowWidget, workflow, steps, states
  747. // and transitions
  748. delete workflowWidget;
  749. return EXIT_SUCCESS;
  750. }
  751. //-----------------------------------------------------------------------------
  752. int ctkWorkflowWidgetTest1(int argc, char * argv [] )
  753. {
  754. QApplication app(argc, argv);
  755. int defaultTime = 100;
  756. bool hideWidgets = false;
  757. if (runWorkflowWidgetTest(new ctkWorkflowWidget, app, hideWidgets, defaultTime) == EXIT_FAILURE)
  758. {
  759. return EXIT_FAILURE;
  760. }
  761. if (runWorkflowWidgetTest(new ctkWorkflowStackedWidget, app, hideWidgets, defaultTime) == EXIT_FAILURE)
  762. {
  763. return EXIT_FAILURE;
  764. }
  765. if (runWorkflowWidgetTest(new ctkWorkflowTabWidget, app, hideWidgets, defaultTime) == EXIT_FAILURE)
  766. {
  767. return EXIT_FAILURE;
  768. }
  769. hideWidgets = true;
  770. if (runWorkflowWidgetTest(new ctkWorkflowWidget, app, hideWidgets, defaultTime) == EXIT_FAILURE)
  771. {
  772. return EXIT_FAILURE;
  773. }
  774. if (runWorkflowWidgetTest(new ctkWorkflowStackedWidget, app, hideWidgets, defaultTime) == EXIT_FAILURE)
  775. {
  776. return EXIT_FAILURE;
  777. }
  778. if (runWorkflowWidgetTest(new ctkWorkflowTabWidget, app, hideWidgets, defaultTime) == EXIT_FAILURE)
  779. {
  780. return EXIT_FAILURE;
  781. }
  782. return EXIT_SUCCESS;
  783. }