ctkWorkflowWidgetTest1.cpp 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736
  1. /*=========================================================================
  2. Library: CTK
  3. Copyright (c) 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.apache.org/licenses/LICENSE-2.0.txt
  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 <QDebug>
  17. #include <QIcon>
  18. #include <QLabel>
  19. #include <QLineEdit>
  20. #include <QList>
  21. #include <QPushButton>
  22. #include <QSignalSpy>
  23. #include <QStyle>
  24. #include <QTimer>
  25. // CTK includes
  26. #include "ctkPushButton.h"
  27. #include "ctkWorkflow.h"
  28. #include "ctkWorkflowWidget.h"
  29. #include "ctkWorkflowStackedWidget.h"
  30. #include "ctkWorkflowTabWidget.h"
  31. #include "ctkWorkflowGroupBox.h"
  32. #include "ctkWorkflowButtonBoxWidget.h"
  33. #include "ctkExampleDerivedWorkflowWidgetStep.h"
  34. // STD includes
  35. #include <cstdlib>
  36. #include <iostream>
  37. //-----------------------------------------------------------------------------
  38. bool buttonClickTest(QApplication& app, int defaultTime, ctkWorkflowWidgetStep* currentStep, QWidget* shownStepArea, QLineEdit* shownLineEdit, QLabel* shownLabel, QWidget* hiddenStepArea, QLineEdit* hiddenLineEdit, QLabel* hiddenLabel, ctkWorkflow* workflow, ctkWorkflowWidget* workflowWidget, QPushButton* backButton, QPushButton* nextButton, QPushButton* finishButton1=0, QPushButton* finishButton2=0)
  39. {
  40. QTimer::singleShot(defaultTime, &app, SLOT(quit()));
  41. app.exec();
  42. // // ensure we are in the correct step
  43. if (workflow->currentStep() != currentStep)
  44. {
  45. std::cerr << "In incorrect step" << std::endl;
  46. return false;
  47. }
  48. // ensure that the widgets of the current step are visible
  49. if ((currentStep && (!shownStepArea || !shownStepArea->isVisible()))
  50. || (shownLabel && !shownLabel->isVisible())
  51. || (shownLineEdit && !shownLineEdit->isVisible())
  52. || !backButton->isVisible()
  53. || !nextButton->isVisible()
  54. || (finishButton1 && !finishButton1->isVisible())
  55. || (finishButton2 && !finishButton2->isVisible()))
  56. {
  57. std::cerr << "Incorrect widget visibility - the current step's widgets are invisible" << std::endl;
  58. return false;
  59. }
  60. // ensure that buttons are appropriately enabled
  61. // TODO finish buttons
  62. if ((workflow->canGoBackward() != backButton->isEnabled()) || (workflow->canGoForward() != nextButton->isEnabled()) || (shownLineEdit && !shownLineEdit->isEnabled()))
  63. {
  64. std::cerr << "Incorrect widget visibility - the buttons are incorrectly enabled" << std::endl;
  65. return false;
  66. }
  67. // ensure that the currentStep step's name and description are shown in
  68. // the widget
  69. ctkWorkflowGroupBox* groupBox;
  70. if (ctkWorkflowAbstractPagedWidget* pagedWidget = qobject_cast<ctkWorkflowAbstractPagedWidget*>(workflowWidget))
  71. {
  72. groupBox = pagedWidget->workflowGroupBox(currentStep);
  73. }
  74. else
  75. {
  76. groupBox = workflowWidget->workflowGroupBox();
  77. }
  78. Q_ASSERT(groupBox);
  79. if (currentStep->name() != groupBox->title() || currentStep->description() != groupBox->subTitle())
  80. {
  81. std::cerr << "Incorrect widget title/subtitle" << std::endl;
  82. return false;
  83. }
  84. // ensure that the finish button has an icon
  85. if ((finishButton1 && finishButton1->icon().isNull()) || (finishButton2 && finishButton2->icon().isNull()))
  86. {
  87. std::cerr << "Incorrect finish icon visibility" << std::endl;
  88. return false;
  89. }
  90. // ensure that widgets of the other step are either invisible, or
  91. // visible but disabled
  92. if (hiddenStepArea)
  93. {
  94. if (hiddenStepArea->isVisible() && groupBox->hideWidgetsOfNonCurrentSteps())
  95. {
  96. std::cerr << "Incorrect widget visibility - the other step's stepArea is showing" << std::endl;
  97. return false;
  98. }
  99. else if (hiddenStepArea->isVisible() && hiddenStepArea->isEnabled())
  100. {
  101. std::cerr << "Incorrect widget visibility - the other step's stepArea is enabled" << std::endl;
  102. return false;
  103. }
  104. }
  105. if (hiddenLabel)
  106. {
  107. if (hiddenLabel->isVisible() && groupBox->hideWidgetsOfNonCurrentSteps())
  108. {
  109. std::cerr << "Incorrect widget visibility - the other step's label is showing" << std::endl;
  110. return false;
  111. }
  112. }
  113. if (hiddenLineEdit)
  114. {
  115. if (hiddenLineEdit->isVisible() && groupBox->hideWidgetsOfNonCurrentSteps())
  116. {
  117. std::cerr << "Incorrect widget visibility - the other step's lineEdit is showing" << std::endl;
  118. return false;
  119. }
  120. else if (hiddenLineEdit->isVisible() && hiddenLineEdit->isEnabled())
  121. {
  122. std::cerr << "Incorrect widget visibility - the other step's lineEdit is enabled" << std::endl;
  123. return false;
  124. }
  125. }
  126. return true;
  127. }
  128. //-----------------------------------------------------------------------------
  129. struct derivedTestData
  130. {
  131. QPushButton* buttonToClick;
  132. ctkExampleDerivedWorkflowWidgetStep* currentStep;
  133. ctkExampleDerivedWorkflowWidgetStep* hiddenStep;
  134. ctkExampleDerivedWorkflowWidgetStep* stepToChangeLineEdit;
  135. QString lineEditText;
  136. derivedTestData(QPushButton* newButtonToClick, ctkExampleDerivedWorkflowWidgetStep* newCurrentStep, ctkExampleDerivedWorkflowWidgetStep* newHiddenStep, ctkExampleDerivedWorkflowWidgetStep* newStepToChangeLineEdit=0, QString newLineEditText="")
  137. {
  138. this->buttonToClick = newButtonToClick;
  139. this->currentStep = newCurrentStep;
  140. this->hiddenStep = newHiddenStep;
  141. this->stepToChangeLineEdit = newStepToChangeLineEdit;
  142. this->lineEditText = newLineEditText;
  143. }
  144. bool runTest(QApplication& app, int defaultTime, ctkWorkflow* workflow, ctkWorkflowWidget* workflowWidget, QPushButton* backButton, QPushButton* nextButton, QPushButton* finishButton1=0, QPushButton* finishButton2=0)
  145. {
  146. if (this->stepToChangeLineEdit)
  147. {
  148. this->stepToChangeLineEdit->lineEdit()->setText(lineEditText);
  149. }
  150. if (this->buttonToClick)
  151. {
  152. this->buttonToClick->click();
  153. }
  154. if (this->currentStep)
  155. {
  156. return buttonClickTest(app, defaultTime, this->currentStep, this->currentStep->stepArea(), this->currentStep->lineEdit(), this->currentStep->label(), this->hiddenStep->stepArea(), this->hiddenStep->lineEdit(), this->hiddenStep->label(), workflow, workflowWidget, backButton, nextButton, finishButton1, finishButton2);
  157. }
  158. else
  159. {
  160. return buttonClickTest(app, defaultTime, this->currentStep, 0, 0, 0, this->hiddenStep->stepArea(), this->hiddenStep->lineEdit(), this->hiddenStep->label(), workflow, workflowWidget, backButton, nextButton, finishButton1, finishButton2);
  161. }
  162. }
  163. };
  164. //-----------------------------------------------------------------------------
  165. // simulates valid and invalid user interaction for a workflow with
  166. // two steps
  167. int userInteractionSimulator1(QApplication& app, ctkExampleDerivedWorkflowWidgetStep* step1, ctkExampleDerivedWorkflowWidgetStep* step2, ctkWorkflow* workflow, ctkWorkflowWidget* workflowWidget, int defaultTime)
  168. {
  169. QPushButton* backButton = workflowWidget->buttonBoxWidget()->backButton();
  170. QPushButton* nextButton = workflowWidget->buttonBoxWidget()->nextButton();
  171. Q_ASSERT(backButton);
  172. Q_ASSERT(nextButton);
  173. #ifndef QT_NO_DEBUG
  174. QPushButton* finishButton = workflowWidget->buttonBoxWidget()->goToButtons().first();
  175. Q_ASSERT(finishButton);
  176. #endif
  177. QList<derivedTestData*> tests;
  178. // we should be in the first step at the start of the workflow
  179. tests << new derivedTestData(0, step1, step2);
  180. // tests with good input (lineEdit value = 100, which passes the
  181. // condition that it be >= 10)
  182. // CurrentStep ButtonPress ExpectedStep Shouldn'tDoAnything
  183. // step1 next step2
  184. // step2 back step1
  185. // step1 next step2
  186. // step2 back step1
  187. tests << new derivedTestData(nextButton, step2, step1)
  188. << new derivedTestData(backButton, step1, step2)
  189. << new derivedTestData(nextButton, step2, step1)
  190. << new derivedTestData(backButton, step1, step2);
  191. // tests with both good and bad input (lineEdit value may be
  192. // invalid)
  193. // CurrentStep ButtonPress Invalid input ExpectedStep
  194. // step1 next * step1
  195. // step1 next step2
  196. // step2 back * step1
  197. // step1 next * (empty) step1
  198. // step1 next step2
  199. tests << new derivedTestData(nextButton, step1, step2, step1, "1")
  200. << new derivedTestData(nextButton, step2, step1, step1, "100")
  201. << new derivedTestData(backButton, step1, step2)
  202. << new derivedTestData(nextButton, step1, step2, step1, "")
  203. << new derivedTestData(nextButton, step2, step1, step1, "100");
  204. foreach (derivedTestData* test, tests)
  205. {
  206. if (!test->runTest(app, defaultTime, workflow, workflowWidget, backButton, nextButton))
  207. {
  208. return EXIT_FAILURE;
  209. }
  210. }
  211. // TODO
  212. // // after adding the steps, then the widget's client area should have
  213. // // them as a child
  214. // if (!workflowWidget->clientArea()->isAncestorOf(testStep1->stepArea()))
  215. // {
  216. // std::cerr << "testStep1 was incorrectly added to the workflowWidget" << std::endl;
  217. // return EXIT_FAILURE;
  218. // }
  219. // if (!workflowWidget->clientArea()->isAncestorOf(testStep2->stepArea()))
  220. // {
  221. // std::cerr << "testStep2 was incorrectly added to the workflowWidget" << std::endl;
  222. // return EXIT_FAILURE;
  223. // }
  224. return EXIT_SUCCESS;
  225. }
  226. //-----------------------------------------------------------------------------
  227. // simulates valid and invalid user interaction for a workflow with
  228. // three steps
  229. int userInteractionSimulator2(QApplication& app, ctkExampleDerivedWorkflowWidgetStep* step1, ctkExampleDerivedWorkflowWidgetStep* step2, ctkExampleDerivedWorkflowWidgetStep* step3, ctkWorkflow* workflow, ctkWorkflowWidget* workflowWidget, int defaultTime)
  230. {
  231. // ensure we can get the pages/layouts we may want
  232. if (ctkWorkflowAbstractPagedWidget* pagedWidget = qobject_cast<ctkWorkflowAbstractPagedWidget*>(workflowWidget))
  233. {
  234. if (!pagedWidget->workflowGroupBox(step1))
  235. {
  236. std::cerr << "could not access widget for page 1" << std::endl;
  237. return EXIT_FAILURE;
  238. }
  239. if (!pagedWidget->workflowGroupBox(step1)->clientAreaLayout())
  240. {
  241. std::cerr << "could not access client area layout for page 1" << std::endl;
  242. return EXIT_FAILURE;
  243. }
  244. }
  245. else
  246. {
  247. if (!workflowWidget->workflowGroupBox()->clientAreaLayout())
  248. {
  249. std::cerr << "could not access client area layout" << std::endl;
  250. return EXIT_FAILURE;
  251. }
  252. }
  253. QPushButton* backButton = workflowWidget->buttonBoxWidget()->backButton();
  254. QPushButton* nextButton = workflowWidget->buttonBoxWidget()->nextButton();
  255. QPushButton* finishButton = workflowWidget->buttonBoxWidget()->goToButtons().first();
  256. Q_ASSERT(backButton);
  257. Q_ASSERT(nextButton);
  258. Q_ASSERT(finishButton);
  259. QList<derivedTestData*> tests;
  260. // we should be in the first step at the start of the workflow
  261. tests << new derivedTestData(0, step1, step2);
  262. // tests with good input (lineEdit value = 100, which passes the
  263. // condition that it be >= 10)
  264. // CurrentStep ButtonPress ExpectedStep Shouldn'tDoAnything
  265. // step1 next step2
  266. // step2 next step3
  267. // step3 back step2
  268. // step2 back step1
  269. // step1 next step2
  270. // step2 next step3
  271. // step3 back step2
  272. tests << new derivedTestData(nextButton, step2, step1)
  273. << new derivedTestData(nextButton, step3, step2, step2, "100")
  274. << new derivedTestData(backButton, step2, step3)
  275. << new derivedTestData(backButton, step1, step2)
  276. << new derivedTestData(nextButton, step2, step1)
  277. << new derivedTestData(nextButton, step3, step2)
  278. << new derivedTestData(backButton, step2, step3);
  279. // tests with both good and bad input (lineEdit value may be
  280. // invalid)
  281. // CurrentStep ButtonPress Invalid input ExpectedStep
  282. // step2 next * step2
  283. // step2 next step3
  284. // step3 back * step2
  285. // step2 next * (empty) step2
  286. // step2 next step3
  287. tests << new derivedTestData(nextButton, step2, step3, step2, "1")
  288. << new derivedTestData(nextButton, step3, step2, step2, "100")
  289. << new derivedTestData(backButton, step2, step3)
  290. << new derivedTestData(nextButton, step2, step3, step2, "")
  291. << new derivedTestData(nextButton, step3, step2, step2, "100");
  292. // first go back to the beginning
  293. tests << new derivedTestData(backButton, step2, step3, step2, "100")
  294. << new derivedTestData(backButton, step1, step2);
  295. // tests going to the finish step
  296. // CurrentStep ButtonPress Invalid input ExpectedStep
  297. // step1 finish step1
  298. // step1 finish step1
  299. // step1 next step2
  300. // step2 finish step2
  301. // step2 next step3
  302. // step3 finish step3
  303. // step3 back step2
  304. // step2 finish step2
  305. // step2 back step1
  306. // step1 finish step1
  307. tests << new derivedTestData(finishButton, step1, step3)
  308. << new derivedTestData(finishButton, step1, step3)
  309. << new derivedTestData(nextButton, step2, step1)
  310. << new derivedTestData(finishButton, step2, step3)
  311. << new derivedTestData(nextButton, step3, step2)
  312. << new derivedTestData(finishButton, step3, step2)
  313. << new derivedTestData(backButton, step2, step3)
  314. << new derivedTestData(finishButton, step2, step3)
  315. << new derivedTestData(backButton, step1, step2)
  316. << new derivedTestData(finishButton, step1, step3);
  317. // tests going to the finish step with invalid input
  318. // CurrentStep ButtonPress Invalid input ExpectedStep
  319. // step1 finish * (step2) step2
  320. // step2 next step3
  321. // step3 back step2
  322. // step2 finish * (step2) step2
  323. // step2 back step1
  324. // step1 finish * (step3) step1
  325. tests << new derivedTestData(finishButton, step2, step1, step2, "0")
  326. << new derivedTestData(nextButton, step3, step2, step2, "100")
  327. << new derivedTestData(backButton, step2, step3)
  328. << new derivedTestData(finishButton, step2, step3, step2, "0")
  329. << new derivedTestData(backButton, step1, step2, step2, "100") // reset text for step2
  330. << new derivedTestData(finishButton, step1, step3, step3, "0");
  331. foreach (derivedTestData* test, tests)
  332. {
  333. if (!test->runTest(app, defaultTime, workflow, workflowWidget, backButton, nextButton, finishButton))
  334. {
  335. return EXIT_FAILURE;
  336. }
  337. }
  338. // TODO
  339. // // after adding the steps, then the widget's client area should have
  340. // // them as a child
  341. // if (!workflowWidget->workflowGroupBox()->isAncestorOf(step3->stepArea()))
  342. // {
  343. // std::cerr << "step3 was incorrectly added to the workflowWidget" << std::endl;
  344. // return EXIT_FAILURE;
  345. // }
  346. return EXIT_SUCCESS;
  347. }
  348. // //-----------------------------------------------------------------------------
  349. // // simulates valid and invalid user interaction for a workflow with
  350. // // three steps and two finish steps
  351. // int userInteractionSimulator3(QApplication& app, ctkExampleDerivedWorkflowWidgetStep* step1, ctkExampleDerivedWorkflowWidgetStep* step2, ctkExampleDerivedWorkflowWidgetStep* step3, ctkWorkflow* workflow, ctkWorkflowWidget* workflowWidget, int defaultTime)
  352. // {
  353. // QPushButton* backButton = workflowWidget->buttonBoxWidget()->backButton();
  354. // QPushButton* nextButton = workflowWidget->buttonBoxWidget()->nextButton();
  355. // QPushButton* finishButton1 = workflowWidget->buttonBoxWidget()->goToButtons().first();
  356. // QPushButton* finishButton2 = workflowWidget->buttonBoxWidget()->goToButtons().at(1);
  357. // Q_ASSERT(backButton);
  358. // Q_ASSERT(nextButton);
  359. // Q_ASSERT(finishButton1);
  360. // Q_ASSERT(finishButton2);
  361. // // if (!nextButton || !finishButton || !finishButton || nextButton->text() != "Next" || finishButton->text() != "finish" || finishButton->text() != "finish")
  362. // // {
  363. // // std::cerr << "incorrect button assignment for step1" << std::endl;
  364. // // return EXIT_FAILURE;
  365. // // }
  366. // // we should be in the first step
  367. // if (!buttonClickTest(app, defaultTime, step1, step2, workflow, workflowWidget, backButton, nextButton, finishButton1, finishButton2)) {return EXIT_FAILURE;}
  368. // // tests with good input, so that we can get all of the buttons
  369. // // (lineEdit value = 100, which passes the condition that it be >= 10)
  370. // // CurrentStep ButtonPress ExpectedStep Shouldn'tDoAnything
  371. // // step1 next step2
  372. // // step2 next step3
  373. // // normal forwards/backwards transitions
  374. // nextButton->click();
  375. // QTimer::singleShot(defaultTime, &app, SLOT(quit()));
  376. // app.exec();
  377. // // get the back/next buttons for the second step
  378. // // buttons = step2->stepArea()->findChildren<QPushButton*>();
  379. // // if (buttons.length() != 4)
  380. // // {
  381. // // std::cerr << "incorrect number of buttons for step2" << std::endl;
  382. // // std::cerr << "number of buttons = " << buttons.length() << ", expecting 4" << std::endl;
  383. // // return EXIT_FAILURE;
  384. // // }
  385. // // backButton = buttons.at(BACK_BUTTON_INDEX);
  386. // // nextButton = buttons.at(NEXT_BUTTON_INDEX);
  387. // // finishButton = buttons.at(FINISH_BUTTON_INDEX_1);
  388. // // finishButton = buttons.at(FINISH_BUTTON_INDEX_2);
  389. // // backButton = workflowWidget->buttonBoxWidget()->backButton();
  390. // // nextButton = workflowWidget->buttonBoxWidget()->nextButton();
  391. // // finishButton = workflowWidget->buttonBoxWidget()->goToButtons().first();
  392. // // finishButton = workflowWidget->buttonBoxWidget()->goToButtons().at(1);
  393. // // if (!backButton || !nextButton || !finishButton || !finishButton || backButton->text() != "Back" || nextButton->text() != "Next" || finishButton->text() != "finish" || finishButton->text() != "finish")
  394. // // {
  395. // // std::cerr << "incorrect button assignment for step2" << std::endl;
  396. // // return EXIT_FAILURE;
  397. // // }
  398. // if (!buttonClickTest(app, defaultTime, step2, step1, workflow, workflowWidget, backButton, nextButton, finishButton1, finishButton2)) {return EXIT_FAILURE;}
  399. // nextButton->click();
  400. // QTimer::singleShot(defaultTime, &app, SLOT(quit()));
  401. // app.exec();
  402. // // get the back/next buttons for the third step
  403. // // buttons = step3->stepArea()->findChildren<QPushButton*>();
  404. // // if (buttons.length() != 3)
  405. // // {
  406. // // std::cerr << "incorrect number of buttons for step3" << std::endl;
  407. // // std::cerr << "number of buttons = " << buttons.length() << ", expecting 3" << std::endl;
  408. // // return EXIT_FAILURE;
  409. // // }
  410. // // backButton = buttons.at(BACK_BUTTON_INDEX);
  411. // // finishButton1 = buttons.at(FINISH_BUTTON_INDEX_1);
  412. // // finishButton2 = buttons.at(FINISH_BUTTON_INDEX_2);
  413. // // backButton = workflowWidget->buttonBoxWidget()->backButton();
  414. // // finishButton1 = workflowWidget->buttonBoxWidget()->goToButtons().first();
  415. // // finishButton2 = workflowWidget->buttonBoxWidget()->goToButtons().at(1);
  416. // // if (!backButton || !finishButton1 || !finishButton2 || backButton->text() != "Back" || finishButton1->text() != "finish" || finishButton2->text() != "finish")
  417. // // {
  418. // // std::cerr << "incorrect button assignment for step3" << std::endl;
  419. // // return EXIT_FAILURE;
  420. // // }
  421. // if (!buttonClickTest(app, defaultTime, step3, step2, workflow, workflowWidget, backButton, nextButton, finishButton1, finishButton2)) {return EXIT_FAILURE;}
  422. // // tests going to the finish step
  423. // // CurrentStep ButtonPress Invalid input ExpectedStep
  424. // // step3 back step2
  425. // // step2 back step1
  426. // // step1 finish1 step1
  427. // // step1 next step2
  428. // // step2 finish1 step2
  429. // // step2 finish2 step2
  430. // // step2 back step1
  431. // // step1 finish2 step1
  432. // // step1 next step2
  433. // backButton->click();
  434. // if (!buttonClickTest(app, defaultTime, step2, step3, workflow, workflowWidget, backButton, nextButton, finishButton1, finishButton2)) {return EXIT_FAILURE;}
  435. // backButton->click();
  436. // if (!buttonClickTest(app, defaultTime, step1, step2, workflow, workflowWidget, backButton, nextButton, finishButton1, finishButton2)) {return EXIT_FAILURE;}
  437. // finishButton1->click();
  438. // if (!buttonClickTest(app, defaultTime, step1, step3, workflow, workflowWidget, backButton, nextButton, finishButton1, finishButton2)) {return EXIT_FAILURE;}
  439. // nextButton->click();
  440. // if (!buttonClickTest(app, defaultTime, step2, step1, workflow, workflowWidget, backButton, nextButton, finishButton1, finishButton2)) {return EXIT_FAILURE;}
  441. // finishButton1->click();
  442. // if (!buttonClickTest(app, defaultTime, step2, step3, workflow, workflowWidget, backButton, nextButton, finishButton1, finishButton2)) {return EXIT_FAILURE;}
  443. // finishButton2->click();
  444. // if (!buttonClickTest(app, defaultTime, step2, step3, workflow, workflowWidget, backButton, nextButton, finishButton1, finishButton2)) {return EXIT_FAILURE;}
  445. // backButton->click();
  446. // if (!buttonClickTest(app, defaultTime, step1, step2, workflow, workflowWidget, backButton, nextButton, finishButton1, finishButton2)) {return EXIT_FAILURE;}
  447. // finishButton2->click();
  448. // if (!buttonClickTest(app, defaultTime, step1, step2, workflow, workflowWidget, backButton, nextButton, finishButton1, finishButton2)) {return EXIT_FAILURE;}
  449. // nextButton->click();
  450. // if (!buttonClickTest(app, defaultTime, step2, step1, workflow, workflowWidget, backButton, nextButton, finishButton1, finishButton2)) {return EXIT_FAILURE;}
  451. // return EXIT_SUCCESS;
  452. // }
  453. //-----------------------------------------------------------------------------
  454. int runWorkflowWidgetTest(ctkWorkflowWidget* workflowWidget, QApplication& app, bool hideWidgets, int defaultTime)
  455. {
  456. ctkWorkflow* workflow = new ctkWorkflow;
  457. workflowWidget->setWorkflow(workflow);
  458. ctkWorkflowGroupBox* groupBox = workflowWidget->workflowGroupBox();
  459. groupBox->setPreText("I am some pre-text");
  460. groupBox->setPostText("I am some post-text");
  461. groupBox->setHideWidgetsOfNonCurrentSteps(hideWidgets);
  462. // create and add the first workflow step (depends on workflowWidget
  463. // type)
  464. ctkExampleDerivedWorkflowWidgetStep* step1 = new ctkExampleDerivedWorkflowWidgetStep("Step 1");
  465. step1->setName("Step 1");
  466. step1->setDescription("I am in step 1");
  467. if (ctkWorkflowTabWidget* tabWidget = qobject_cast<ctkWorkflowTabWidget*>(workflowWidget))
  468. {
  469. tabWidget->associateStepWithLabel(step1, "tab1");
  470. }
  471. // step1 is the initial step
  472. workflow->setInitialStep(step1);
  473. // create and add the second workflow step (depends on
  474. // workflowWidget type)
  475. ctkExampleDerivedWorkflowWidgetStep* step2 = new ctkExampleDerivedWorkflowWidgetStep("Step 2");
  476. step2->setName("Step 2");
  477. step2->setDescription("I am in step 2");
  478. if (ctkWorkflowTabWidget* tabWidget = qobject_cast<ctkWorkflowTabWidget*>(workflowWidget))
  479. {
  480. tabWidget->associateStepWithLabel(step2, "tab2");
  481. }
  482. int expectedStepCount = 0;
  483. int currentStepCount = workflow->steps().count();
  484. if (currentStepCount != expectedStepCount)
  485. {
  486. std::cerr << "Line " << __LINE__ << " - Problem with steps()\n"
  487. << "\tcurrentStepCount: " << currentStepCount << "\n"
  488. << "\texpectedStepCount:" << expectedStepCount << std::endl;
  489. return EXIT_FAILURE;
  490. }
  491. QSignalSpy signalSpyStepRegistered(workflow, SIGNAL(stepRegistered(ctkWorkflowStep*)));
  492. // add the steps to the workflow
  493. workflow->addTransition(step1, step2);
  494. expectedStepCount = 2;
  495. currentStepCount = workflow->steps().count();
  496. if (currentStepCount != expectedStepCount)
  497. {
  498. std::cerr << "Line " << __LINE__ << " - Problem with steps()\n"
  499. << "\tcurrentStepCount: " << currentStepCount << "\n"
  500. << "\texpectedStepCount:" << expectedStepCount << std::endl;
  501. return EXIT_FAILURE;
  502. }
  503. int expectedSignalStepRegisteredCount = 2;
  504. int currentSignalStepRegisteredCount = signalSpyStepRegistered.count();
  505. if (currentSignalStepRegisteredCount != expectedSignalStepRegisteredCount)
  506. {
  507. std::cerr << "Line " << __LINE__ << " - Problem with 'stepRegistered' signal\n"
  508. << "\tcurrentSignalStepRegisteredCount: " << currentSignalStepRegisteredCount << "\n"
  509. << "\texpectedSignalStepRegisteredCount:" << expectedSignalStepRegisteredCount << std::endl;
  510. return EXIT_FAILURE;
  511. }
  512. // start the workflow
  513. workflow->start();
  514. workflowWidget->show();
  515. // Attempt to add step to a different workflow
  516. ctkWorkflow* workflow2 = new ctkWorkflow;
  517. workflow2->addTransition(step1, step2);
  518. expectedStepCount = 0;
  519. currentStepCount = workflow2->steps().count();
  520. if (currentStepCount != expectedStepCount)
  521. {
  522. std::cerr << "Line " << __LINE__ << " - Problem with steps()\n"
  523. << "\tcurrentStepCount: " << currentStepCount << "\n"
  524. << "\texpectedStepCount:" << expectedStepCount << std::endl;
  525. return EXIT_FAILURE;
  526. }
  527. // first user interaction test
  528. if (userInteractionSimulator1(app, step1, step2, workflow, workflowWidget, defaultTime) == EXIT_FAILURE)
  529. {
  530. return EXIT_FAILURE;
  531. }
  532. // stop the workflow
  533. workflow->stop();
  534. QTimer::singleShot(defaultTime, &app, SLOT(quit()));
  535. app.exec();
  536. // create and add a third workflow step (depends on workflowWidget
  537. // type)
  538. ctkExampleDerivedWorkflowWidgetStep* step3 = new ctkExampleDerivedWorkflowWidgetStep("Step 3");
  539. step3->setName("Step 3");
  540. step3->setDescription("I am in step 3");
  541. if (ctkWorkflowStackedWidget* stackedWidget = qobject_cast<ctkWorkflowStackedWidget*>(workflowWidget))
  542. {
  543. stackedWidget->associateStepWithPage(step3, 1);
  544. }
  545. else if (ctkWorkflowTabWidget* tabWidget = qobject_cast<ctkWorkflowTabWidget*>(workflowWidget))
  546. {
  547. tabWidget->associateStepWithPage(step3, 1, "tab2");
  548. }
  549. // icon test - add an icon to step3, should show up as a icon on the finish button
  550. step3->setIcon(step3->stepArea()->style()->standardIcon(QStyle::SP_ArrowUp));
  551. workflow->addTransition(step2, step3);
  552. // restart the workflow
  553. workflow->start();
  554. // second user interaction test
  555. if (userInteractionSimulator2(app, step1, step2, step3, workflow, workflowWidget, defaultTime) == EXIT_FAILURE)
  556. {
  557. return EXIT_FAILURE;
  558. }
  559. // stop the workflow
  560. workflow->stop();
  561. QTimer::singleShot(defaultTime, &app, SLOT(quit()));
  562. app.exec();
  563. // TODO put back once we can have more than one finish step
  564. // make the second workflow step a finish step as well
  565. // finishSteps.push_back(step2);
  566. // step1->setFinishStepsToHaveButtonsInStepArea(finishSteps);
  567. // step2->setFinishStepsToHaveButtonsInStepArea(finishSteps);
  568. // step3->setFinishStepsToHaveButtonsInStepArea(finishSteps);
  569. // // workflow->addFinishStep(step2);
  570. // // restart the workflow
  571. // workflow->start();
  572. // QTimer::singleShot(defaultTime, &app, SLOT(quit()));
  573. // app.exec();
  574. // // third user interfaction test
  575. // if (userInteractionSimulator3(app, step1, step2, step3, workflow, workflowWidget, defaultTime) == EXIT_FAILURE)
  576. // {
  577. // return EXIT_FAILURE;
  578. // }
  579. // // stop the workflow
  580. // workflow->stop();
  581. // QTimer::singleShot(defaultTime, &app, SLOT(quit()));
  582. // app.exec();
  583. // handles deletion of the workflowWidget, workflow, steps, states
  584. // and transitions
  585. delete workflowWidget;
  586. return EXIT_SUCCESS;
  587. }
  588. //-----------------------------------------------------------------------------
  589. int ctkWorkflowWidgetTest1(int argc, char * argv [] )
  590. {
  591. QApplication app(argc, argv);
  592. int defaultTime = 100;
  593. bool hideWidgets = false;
  594. if (runWorkflowWidgetTest(new ctkWorkflowWidget, app, hideWidgets, defaultTime) == EXIT_FAILURE)
  595. {
  596. return EXIT_FAILURE;
  597. }
  598. if (runWorkflowWidgetTest(new ctkWorkflowStackedWidget, app, hideWidgets, defaultTime) == EXIT_FAILURE)
  599. {
  600. return EXIT_FAILURE;
  601. }
  602. if (runWorkflowWidgetTest(new ctkWorkflowTabWidget, app, hideWidgets, defaultTime) == EXIT_FAILURE)
  603. {
  604. return EXIT_FAILURE;
  605. }
  606. hideWidgets = true;
  607. if (runWorkflowWidgetTest(new ctkWorkflowWidget, app, hideWidgets, defaultTime) == EXIT_FAILURE)
  608. {
  609. return EXIT_FAILURE;
  610. }
  611. if (runWorkflowWidgetTest(new ctkWorkflowStackedWidget, app, hideWidgets, defaultTime) == EXIT_FAILURE)
  612. {
  613. return EXIT_FAILURE;
  614. }
  615. if (runWorkflowWidgetTest(new ctkWorkflowTabWidget, app, hideWidgets, defaultTime) == EXIT_FAILURE)
  616. {
  617. return EXIT_FAILURE;
  618. }
  619. return EXIT_SUCCESS;
  620. }