//----------------------------------------------------------------------------- int ctkExampleUseOfWorkflowWidgetUsingSignalsAndSlots(int argc, char * argv [] ) { QApplication app(argc, argv); // this boolean is used in setHideWidgetsOfNonCurrentSteps() below // false: when a widget does not belong to the current step, it is // hidden // true: when a widget does not belong to the current step, it is // shown, but disabled bool hideWidgets = false; // create the workflow ctkWorkflow* workflow = new ctkWorkflow; // create the workflow's UI component ctkWorkflowTabWidget* workflowWidget = new ctkWorkflowTabWidget; workflowWidget->setWorkflow(workflow); ctkWorkflowGroupBox* groupBox = workflowWidget->workflowGroupBox(); groupBox->setPreText("I am some pre-text"); groupBox->setPostText("I am some post-text"); groupBox->setHideWidgetsOfNonCurrentSteps(hideWidgets); // create and add the first workflow step ctkWorkflowWidgetStep* testStep1 = new ctkWorkflowWidgetStep(workflow, "Step 1"); testStep1->setName("Step 1"); testStep1->setDescription("I am in step 1"); // can specify the name of the tab workflowWidget->associateStepWithLabel(testStep1, "name 1"); // create and add the second workflow step ctkWorkflowWidgetStep* testStep2 = new ctkWorkflowWidgetStep(workflow, "Step 2"); testStep2->setName("Step 2"); testStep2->setDescription("I am in step 2"); // a new tab is automatically created workflowWidget->associateStepWithLabel(testStep2, "name 2"); // create and add a third workflow step ctkWorkflowWidgetStep* testStep3 = new ctkWorkflowWidgetStep(workflow, "Step 3"); testStep3->setName("Step 3"); testStep3->setDescription("I am in step 3"); // can place a step on a tab that was previously created by // specifying its index workflowWidget->associateStepWithPage(testStep3, 1, "name 3"); // add the steps to the workflow workflow->addTransition(testStep1, testStep2); workflow->addTransition(testStep2, testStep3); // create the qObjects that implement the required functions for // each step, and communicate with the workflow using signals and slots ctkExampleWorkflowWidgetStepUsingSignalsAndSlots* qObject1 = new ctkExampleWorkflowWidgetStepUsingSignalsAndSlots; ctkExampleWorkflowWidgetStepUsingSignalsAndSlots* qObject2 = new ctkExampleWorkflowWidgetStepUsingSignalsAndSlots; ctkExampleWorkflowWidgetStepUsingSignalsAndSlots* qObject3 = new ctkExampleWorkflowWidgetStepUsingSignalsAndSlots; // set the widget for each qObject qObject1->setWidget(testStep1->stepArea()); qObject2->setWidget(testStep2->stepArea()); qObject3->setWidget(testStep3->stepArea()); // use the qObjects for validation QObject::connect(testStep1->ctkWorkflowStepQObject(), SIGNAL(invokeValidateCommand(const QString&)), qObject1, SLOT(validate(const QString&))); QObject::connect(qObject1, SIGNAL(validationComplete(bool, const QString&)), workflow, SLOT(evaluateValidationResults(bool, const QString&))); QObject::connect(testStep2->ctkWorkflowStepQObject(), SIGNAL(invokeValidateCommand(const QString&)), qObject2, SLOT(validate(const QString&))); QObject::connect(qObject2, SIGNAL(validationComplete(bool, const QString&)), workflow, SLOT(evaluateValidationResults(bool, const QString&))); QObject::connect(testStep3->ctkWorkflowStepQObject(), SIGNAL(invokeValidateCommand(const QString&)), qObject3, SLOT(validate(const QString&))); QObject::connect(qObject3, SIGNAL(validationComplete(bool, const QString&)), workflow, SLOT(evaluateValidationResults(bool, const QString&))); // use the qObjects for entry processing QObject::connect(testStep1->ctkWorkflowStepQObject(), SIGNAL(invokeOnEntryCommand(const ctkWorkflowStep*, const ctkWorkflowInterstepTransition::InterstepTransitionType)), qObject1, SLOT(onEntry(const ctkWorkflowStep*, const ctkWorkflowInterstepTransition::InterstepTransitionType))); QObject::connect(qObject1, SIGNAL(onEntryComplete()), workflow, SLOT(processingAfterOnEntry())); QObject::connect(testStep2->ctkWorkflowStepQObject(), SIGNAL(invokeOnEntryCommand(const ctkWorkflowStep*, const ctkWorkflowInterstepTransition::InterstepTransitionType)), qObject2, SLOT(onEntry(const ctkWorkflowStep*, const ctkWorkflowInterstepTransition::InterstepTransitionType))); QObject::connect(qObject2, SIGNAL(onEntryComplete()), workflow, SLOT(processingAfterOnEntry())); QObject::connect(testStep3->ctkWorkflowStepQObject(), SIGNAL(invokeOnEntryCommand(const ctkWorkflowStep*, const ctkWorkflowInterstepTransition::InterstepTransitionType)), qObject3, SLOT(onEntry(const ctkWorkflowStep*, const ctkWorkflowInterstepTransition::InterstepTransitionType))); QObject::connect(qObject3, SIGNAL(onEntryComplete()), workflow, SLOT(processingAfterOnEntry())); // use the qObjects for exit processing QObject::connect(testStep1->ctkWorkflowStepQObject(), SIGNAL(invokeOnExitCommand(const ctkWorkflowStep*, const ctkWorkflowInterstepTransition::InterstepTransitionType)), qObject1, SLOT(onExit(const ctkWorkflowStep*, const ctkWorkflowInterstepTransition::InterstepTransitionType))); QObject::connect(qObject1, SIGNAL(onExitComplete()), workflow, SLOT(processingAfterOnExit())); QObject::connect(testStep2->ctkWorkflowStepQObject(), SIGNAL(invokeOnExitCommand(const ctkWorkflowStep*, const ctkWorkflowInterstepTransition::InterstepTransitionType)), qObject2, SLOT(onExit(const ctkWorkflowStep*, const ctkWorkflowInterstepTransition::InterstepTransitionType))); QObject::connect(qObject2, SIGNAL(onExitComplete()), workflow, SLOT(processingAfterOnExit())); QObject::connect(testStep3->ctkWorkflowStepQObject(), SIGNAL(invokeOnExitCommand(const ctkWorkflowStep*, const ctkWorkflowInterstepTransition::InterstepTransitionType)), qObject3, SLOT(onExit(const ctkWorkflowStep*, const ctkWorkflowInterstepTransition::InterstepTransitionType))); QObject::connect(qObject3, SIGNAL(onExitComplete()), workflow, SLOT(processingAfterOnExit())); // use the qObjects for populating the stepWidgetsList QObject::connect(testStep1->ctkWorkflowAbstractWidgetStepQObject(), SIGNAL(invokeCreateUserInterfaceCommand()), qObject1, SLOT(createUserInterface())); QObject::connect(qObject1, SIGNAL(createUserInterfaceComplete()), testStep1->ctkWorkflowAbstractWidgetStepQObject(), SIGNAL(showUserInterfaceComplete())); QObject::connect(testStep2->ctkWorkflowAbstractWidgetStepQObject(), SIGNAL(invokeCreateUserInterfaceCommand()), qObject2, SLOT(createUserInterface())); QObject::connect(qObject2, SIGNAL(createUserInterfaceComplete()), testStep2->ctkWorkflowAbstractWidgetStepQObject(), SIGNAL(showUserInterfaceComplete())); QObject::connect(testStep3->ctkWorkflowAbstractWidgetStepQObject(), SIGNAL(invokeCreateUserInterfaceCommand()), qObject3, SLOT(createUserInterface())); QObject::connect(qObject3, SIGNAL(createUserInterfaceComplete()), testStep3->ctkWorkflowAbstractWidgetStepQObject(), SIGNAL(showUserInterfaceComplete())); testStep1->setHasValidateCommand(1); testStep1->setHasOnEntryCommand(1); testStep1->setHasOnExitCommand(1); testStep1->setHasCreateUserInterfaceCommand(1); testStep2->setHasValidateCommand(1); testStep2->setHasOnEntryCommand(1); testStep2->setHasOnExitCommand(1); testStep2->setHasCreateUserInterfaceCommand(1); testStep3->setHasValidateCommand(1); testStep3->setHasOnEntryCommand(1); testStep3->setHasOnExitCommand(1); testStep3->setHasCreateUserInterfaceCommand(1); // testStep1 is the initial step workflow->setInitialStep(testStep1); // testStep3 will be a finish step // - will perform the processing associated with entering and // leaving each step, using the default values supplied // - if successful: brings you back to the step where you requested // to go to the finish step, so that you can begin customization // using user inputs if desired // - if unsuccessful: leaves you in the step of failure, so that you // can attempt to recify things from there; prints an error message // at the bottom of the widget. To see this behavior: // 1) "Next" to step 2 // 2) change step 2's value to something invalid (ex. 0) // 3) "Back" to step 1 // 4) "finish" - attempts to go to step 3, but leaves you in step 2 // start the workflow workflow->start(); workflowWidget->show(); // change this value (500) to increase the time that the widget is // shown QTimer::singleShot(500, &app, SLOT(quit())); app.exec(); // stop the workflow workflow->stop(); QTimer::singleShot(100, &app, SLOT(quit())); app.exec(); // handles deletion of the workflowWidget, workflow, steps, states // and transitions delete workflowWidget; return EXIT_SUCCESS; }
//----------------------------------------------------------------------------- int ctkWorkflowTest2(int argc, char * argv [] ) { QApplication app(argc, argv); int defaultTime = 100; // create the steps and the workflow ctkWorkflow *workflow = new ctkWorkflow(); ctkWorkflowStep *step1 = new ctkWorkflowStep(workflow, "Step 1"); step1->setName("Step 1"); step1->setDescription("Description for step 1"); ctkWorkflowStep *step2 = new ctkWorkflowStep(workflow, "Step 2"); step2->setName("Step 2"); step2->setDescription("Description for step 2"); ctkWorkflowStep *step3 = new ctkWorkflowStep(workflow, "Step 3"); step3->setName("Step 3"); step3->setDescription("Description for step 3"); ctkWorkflowStep *step4 = new ctkWorkflowStep(workflow, "Step 4"); step4->setName("Step 4"); step4->setDescription("Description for step 4"); // create the qObjects that implement the required functions, and // communicate with the workflow using signals and slots ctkExampleWorkflowStepUsingSignalsAndSlots* qObject1 = new ctkExampleWorkflowStepUsingSignalsAndSlots; ctkExampleWorkflowStepUsingSignalsAndSlots* qObject2 = new ctkExampleWorkflowStepUsingSignalsAndSlots; ctkExampleWorkflowStepUsingSignalsAndSlots* qObject3 = new ctkExampleWorkflowStepUsingSignalsAndSlots; ctkExampleWorkflowStepUsingSignalsAndSlots* qObject4 = new ctkExampleWorkflowStepUsingSignalsAndSlots; // use the qObjects for validation QObject::connect(step1->ctkWorkflowStepQObject(), SIGNAL(invokeValidateCommand(const QString&)), qObject1, SLOT(validate(const QString&))); QObject::connect(qObject1, SIGNAL(validationComplete(bool, const QString&)), workflow, SLOT(evaluateValidationResults(bool, const QString&))); QObject::connect(step2->ctkWorkflowStepQObject(), SIGNAL(invokeValidateCommand(const QString&)), qObject2, SLOT(validate(const QString&))); QObject::connect(qObject2, SIGNAL(validationComplete(bool, const QString&)), workflow, SLOT(evaluateValidationResults(bool, const QString&))); // step 3's validation will always fail QObject::connect(step3->ctkWorkflowStepQObject(), SIGNAL(invokeValidateCommand(const QString&)), qObject3, SLOT(validateFails())); QObject::connect(qObject3, SIGNAL(validationComplete(bool, const QString&)), workflow, SLOT(evaluateValidationResults(bool, const QString&))); QObject::connect(step4->ctkWorkflowStepQObject(), SIGNAL(invokeValidateCommand(const QString&)), qObject4, SLOT(validate(const QString&))); QObject::connect(qObject4, SIGNAL(validationComplete(bool, const QString&)), workflow, SLOT(evaluateValidationResults(bool, const QString&))); // use the qObjects for entry processing QObject::connect(step1->ctkWorkflowStepQObject(), SIGNAL(invokeOnEntryCommand(const ctkWorkflowStep*, const ctkWorkflowInterstepTransition::InterstepTransitionType)), qObject1, SLOT(onEntry(const ctkWorkflowStep*, const ctkWorkflowInterstepTransition::InterstepTransitionType))); QObject::connect(qObject1, SIGNAL(onEntryComplete()), workflow, SLOT(processingAfterOnEntry())); QObject::connect(step2->ctkWorkflowStepQObject(), SIGNAL(invokeOnEntryCommand(const ctkWorkflowStep*, const ctkWorkflowInterstepTransition::InterstepTransitionType)), qObject2, SLOT(onEntry(const ctkWorkflowStep*, const ctkWorkflowInterstepTransition::InterstepTransitionType))); QObject::connect(qObject2, SIGNAL(onEntryComplete()), workflow, SLOT(processingAfterOnEntry())); QObject::connect(step3->ctkWorkflowStepQObject(), SIGNAL(invokeOnEntryCommand(const ctkWorkflowStep*, const ctkWorkflowInterstepTransition::InterstepTransitionType)), qObject3, SLOT(onEntry(const ctkWorkflowStep*, const ctkWorkflowInterstepTransition::InterstepTransitionType))); QObject::connect(qObject3, SIGNAL(onEntryComplete()), workflow, SLOT(processingAfterOnEntry())); QObject::connect(step4->ctkWorkflowStepQObject(), SIGNAL(invokeOnEntryCommand(const ctkWorkflowStep*, const ctkWorkflowInterstepTransition::InterstepTransitionType)), qObject4, SLOT(onEntry(const ctkWorkflowStep*, const ctkWorkflowInterstepTransition::InterstepTransitionType))); QObject::connect(qObject4, SIGNAL(onEntryComplete()), workflow, SLOT(processingAfterOnEntry())); // use the qObjects for exit processing QObject::connect(step1->ctkWorkflowStepQObject(), SIGNAL(invokeOnExitCommand(const ctkWorkflowStep*, const ctkWorkflowInterstepTransition::InterstepTransitionType)), qObject1, SLOT(onExit(const ctkWorkflowStep*, const ctkWorkflowInterstepTransition::InterstepTransitionType))); QObject::connect(qObject1, SIGNAL(onExitComplete()), workflow, SLOT(processingAfterOnExit())); QObject::connect(step2->ctkWorkflowStepQObject(), SIGNAL(invokeOnExitCommand(const ctkWorkflowStep*, const ctkWorkflowInterstepTransition::InterstepTransitionType)), qObject2, SLOT(onExit(const ctkWorkflowStep*, const ctkWorkflowInterstepTransition::InterstepTransitionType))); QObject::connect(qObject2, SIGNAL(onExitComplete()), workflow, SLOT(processingAfterOnExit())); QObject::connect(step3->ctkWorkflowStepQObject(), SIGNAL(invokeOnExitCommand(const ctkWorkflowStep*, const ctkWorkflowInterstepTransition::InterstepTransitionType)), qObject3, SLOT(onExit(const ctkWorkflowStep*, const ctkWorkflowInterstepTransition::InterstepTransitionType))); QObject::connect(qObject3, SIGNAL(onExitComplete()), workflow, SLOT(processingAfterOnExit())); QObject::connect(step4->ctkWorkflowStepQObject(), SIGNAL(invokeOnExitCommand(const ctkWorkflowStep*, const ctkWorkflowInterstepTransition::InterstepTransitionType)), qObject4, SLOT(onExit(const ctkWorkflowStep*, const ctkWorkflowInterstepTransition::InterstepTransitionType))); QObject::connect(qObject4, SIGNAL(onExitComplete()), workflow, SLOT(processingAfterOnExit())); step1->setHasValidateCommand(1); step2->setHasValidateCommand(1); step3->setHasValidateCommand(1); step4->setHasValidateCommand(1); step1->setHasOnEntryCommand(1); step2->setHasOnEntryCommand(1); step3->setHasOnEntryCommand(1); step4->setHasOnEntryCommand(1); step1->setHasOnExitCommand(1); step2->setHasOnExitCommand(1); step3->setHasOnExitCommand(1); step4->setHasOnExitCommand(1); // set the initial step (which sets the initial state) workflow->setInitialStep(step1); // add the first and second steps if (!workflow->addTransition(step1, step2)) { std::cerr << "could not add 1st and 2nd step" << std::endl; return EXIT_FAILURE; } // add the third step if (!workflow->addTransition(step2, step3)) { std::cerr << "could not add 3rd step" << std::endl; return EXIT_FAILURE; } // add the fourth step if (!workflow->addTransition(step3, step4)) { std::cerr << "could not add 4rd step" << std::endl; return EXIT_FAILURE; } // start the workflow if (!testStartWorkflow(workflow, defaultTime, app, 1, step1, qObject1, true, 0, qObject2, 0, 0, qObject3, 0, 0, qObject4, 0, 0)) { std::cerr << "error starting workflow"; return EXIT_FAILURE; } // trigger transition to the next step workflow->goForward(); if (!transitionTest(workflow, defaultTime, app, step2, qObject1, 1, 1, qObject2, 1, 0, qObject3, 0, 0, qObject4, 0, 0)) { std::cerr << "error transitioning to step 2"; return EXIT_FAILURE; } // trigger transition to the next step workflow->goForward(); if (!transitionTest(workflow, defaultTime, app, step3, qObject1, 1, 1, qObject2, 1, 1, qObject3, 1, 0, qObject4, 0, 0)) { std::cerr << "error transitioning to step 3"; return EXIT_FAILURE; } // trigger transition to the next state (this should fail!) workflow->goForward(); if (!transitionTest(workflow, defaultTime, app, step3, qObject1, 1, 1, qObject2, 1, 1, qObject3, 1, 0, qObject4, 0, 0)) { std::cerr << "error after transition failure at step 3"; return EXIT_FAILURE; } // make sure the workflow stops properly if (!testStopWorkflow(workflow, defaultTime, app, qObject1, 1, 1, qObject2, 1, 1, qObject3, 1, 1, qObject4, 0, 0)) { std::cerr << "error after stopping workflow"; return EXIT_FAILURE; } // handles deletions of the workflow, steps, states and transitions delete workflow; return EXIT_SUCCESS; }