<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://www.commontk.org/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Danielle.pace</id>
	<title>Commontk - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://www.commontk.org/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Danielle.pace"/>
	<link rel="alternate" type="text/html" href="https://www.commontk.org/index.php?title=Special:Contributions/Danielle.pace"/>
	<updated>2026-04-13T08:35:39Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.43.6</generator>
	<entry>
		<id>https://www.commontk.org/index.php?title=Contributing_to_CTK&amp;diff=1617</id>
		<title>Contributing to CTK</title>
		<link rel="alternate" type="text/html" href="https://www.commontk.org/index.php?title=Contributing_to_CTK&amp;diff=1617"/>
		<updated>2012-09-20T19:55:40Z</updated>

		<summary type="html">&lt;p&gt;Danielle.pace: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The present document aims at describing how a developer should contribute to CTK. &lt;br /&gt;
&lt;br /&gt;
* The source code of CTK is currently hosted on Github [http://github.com]. See http://github.com/commonth/CTK&lt;br /&gt;
&lt;br /&gt;
* It&#039;s also assumed the developer is familiar with [http://git-scm.com/ git]. There are countless amount of resources available online. A good start point could the list presented on CMake/git page [http://www.cmake.org/Wiki/CMake/Git#Resources].&lt;br /&gt;
&lt;br /&gt;
* We use a topic-based workflow as documented [http://public.kitware.com/Wiki/Git/Workflow/Topic here] and thus define integration branches:&lt;br /&gt;
** &#039;&#039;&#039;master&#039;&#039;&#039; Release preparation; starting point for new features (default) &lt;br /&gt;
** &amp;lt;del&amp;gt;&#039;&#039;&#039;next&#039;&#039;&#039; Development; new features published here first &amp;lt;/del&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* We also accept commit following the more classic rebase workflow. See [http://unethicalblogger.com/2010/04/02/a-rebase-based-workflow.html]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Prerequisites =&lt;br /&gt;
* [https://github.com/signup/free Create an account on github.com]&lt;br /&gt;
* Fork http://github.com/commontk/CTK&lt;br /&gt;
* Introduce yourself&lt;br /&gt;
 $ git config --global user.name &amp;quot;Your Name&amp;quot;&lt;br /&gt;
 $ git config --global user.email &amp;quot;you@yourdomain.com&amp;quot;&lt;br /&gt;
* Use correct line endings ([http://help.github.com/dealing-with-lineendings/ more info])&lt;br /&gt;
 [On Linux] $ git config --global core.autocrlf input&lt;br /&gt;
 [On Windows] $ git config --global core.autocrlf true&lt;br /&gt;
&lt;br /&gt;
= Checkout your fork =&lt;br /&gt;
 cd MyProject&lt;br /&gt;
 git clone git@github.com:&#039;&#039;&#039;&amp;lt;MYACCOUNT&amp;gt;&#039;&#039;&#039;/CTK.git&lt;br /&gt;
 cd CTK&lt;br /&gt;
 git remote add origin git@github.com:&#039;&#039;&#039;&amp;lt;MYACCOUNT&amp;gt;&#039;&#039;&#039;/CTK.git&lt;br /&gt;
 git remote add upstream git@github.com:commontk/CTK.git&lt;br /&gt;
&lt;br /&gt;
= Publishing your branch =&lt;br /&gt;
* Having your own fork CTK allows you to backup and publish your work avoiding the &#039;&#039;urge to merge&#039;&#039; [http://public.kitware.com/Wiki/Git/Workflow/Topic#Urge_to_Merge]&lt;br /&gt;
 git checkout -b YYY-new-feature&lt;br /&gt;
 hack, hack, hack, add, commit&lt;br /&gt;
 git push origin topic1:refs/heads/YYY-new-feature&lt;br /&gt;
&lt;br /&gt;
* Note that &amp;lt;code&amp;gt;YYY&amp;lt;/code&amp;gt; reference an issue entered in the tracker.&lt;br /&gt;
&lt;br /&gt;
* As a shortcut, you could also enter the following. Some useful script are also available [http://git-wt-commit.rubyforge.org/ here]:&lt;br /&gt;
 git config branch.topic1.remote origin&lt;br /&gt;
 git config branch.topic1.merge refs/heads/YYY-new-feature&lt;br /&gt;
&lt;br /&gt;
* Then, from the topic branch &#039;&#039;YYY-new-feature&#039;&#039;, you could just enter the following to backup/publish your work:&lt;br /&gt;
 git push&lt;br /&gt;
&lt;br /&gt;
* To delete a branch from your fork:&lt;br /&gt;
 git push origin :YYY-new-feature&lt;br /&gt;
&lt;br /&gt;
= Checkout a branch from a different fork =&lt;br /&gt;
* You may want to collaborate with an other developer and work conjointly on a feature.&lt;br /&gt;
* Let&#039;s say, &#039;&#039;jcfr&#039;&#039; published the branch &#039;&#039;awesome_feature&#039;&#039; on his fork. You should do the following to check out his branch:&lt;br /&gt;
 git remote add jcfr git://github.com/jcfr/CTK.git&lt;br /&gt;
 git fetch jcfr&lt;br /&gt;
 git checkout -b awesome_feature refs/remotes/jcfr/awesome_feature&lt;br /&gt;
or &lt;br /&gt;
 git checkout -b awesome_feature jcfr/awesome_feature&lt;br /&gt;
* You should now have a local branch named awesome_feature. You can now add, commit and publish your work.&lt;br /&gt;
&lt;br /&gt;
= Sync your topic branch =&lt;br /&gt;
* If a collaborator previously checked out your published branch, committed some changes, then published a revised branch on his github fork, you may want to grab its changes.&lt;br /&gt;
* Different ways:&lt;br /&gt;
1) If you didn&#039;t work on your branch, you could do the following:&lt;br /&gt;
 git fetch jcfr&lt;br /&gt;
 git checkout my_topic&lt;br /&gt;
 git merge jcfr/my_topic&lt;br /&gt;
&lt;br /&gt;
2) If you worked on your branch while your collaborator was working, you may want to select only the commit your collaborator pushed on his fork: &lt;br /&gt;
&lt;br /&gt;
 git fetch jcfr&lt;br /&gt;
 git checkout my_topic&lt;br /&gt;
 git cherry-pick &amp;lt;sha1&amp;gt;   # sha1 identifying a specific commit&lt;br /&gt;
&lt;br /&gt;
= Integrate your new feature =&lt;br /&gt;
* Initially, your feature should be integrated to &#039;&#039;&#039;next&#039;&#039;&#039;.&lt;br /&gt;
* To integrate your change to &#039;&#039;&#039;next&#039;&#039;&#039;, you could follow the steps listed below. More details are also available [http://public.kitware.com/Wiki/Git/Workflow/Topic#New_Topic here].&lt;br /&gt;
 git fetch upstream                             # Retrieve change from upstream repository&lt;br /&gt;
 git checkout next                              # Checkout your local &amp;quot;next&amp;quot; branch&lt;br /&gt;
 git merge upstream                             # Make sure your local branch is up-to-date.&lt;br /&gt;
 git merge new_feature                          # Merge locally to &amp;quot;next&amp;quot; - Your changes are now integrated&lt;br /&gt;
 git push upstream                              # Publish your change on the official repository&lt;br /&gt;
 git push origin                                # Publish your change on your fork&lt;br /&gt;
&lt;br /&gt;
* After it has been validated and tested, it could be integrated to &#039;&#039;&#039;master&#039;&#039;&#039;. More details [http://public.kitware.com/Wiki/Git/Workflow/Topic#Mature_Topic here].&lt;br /&gt;
 Repeat the command listed above changing &amp;quot;next&amp;quot; into &amp;quot;master&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
= Tutorial =&lt;br /&gt;
The idea behind the tutorial is the following, it will guide you through the basic step allowing to:&lt;br /&gt;
* Step1 - Fork and clone the tutorial repository&lt;br /&gt;
* Step2 - Create a new feature from &#039;&#039;&#039;master&#039;&#039;&#039; branch&lt;br /&gt;
* Step3 - Add and commit a file representing the feature&lt;br /&gt;
* Step4 - Merge the feature into the &#039;&#039;&#039;next&#039;&#039;&#039; branch&lt;br /&gt;
* Step5 - Refine your feature by doing an additional commit&lt;br /&gt;
* Step6 - Merge again with &#039;&#039;&#039;next&#039;&#039;&lt;br /&gt;
* Step7 - Merge feature with &#039;&#039;&#039;master&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The &#039;tutorial feature&#039; you will create could be correspond to a TXT file containing either a proverb, sentence, thought of the day, proverb, ... &lt;br /&gt;
* For the sake of the tutorial, let&#039;s make sure the text you create for the first commit contain an &amp;quot;error&amp;quot; (missing the author name, spell mistake, ...).&lt;br /&gt;
* The second commit will intent to fix the &amp;quot;error&amp;quot;&lt;br /&gt;
&lt;br /&gt;
For example:&lt;br /&gt;
* Commit1&lt;br /&gt;
** Filename: ghandi.txt&lt;br /&gt;
** Content: &amp;quot;Be the change you want to see in the world.&amp;quot; Mahatma Gandhi&lt;br /&gt;
** CommitMsg: Added Mahatma Gandhi proverb about change&lt;br /&gt;
* Commit2:&lt;br /&gt;
** New content: &amp;quot;Be the change you want to see in the world.&amp;quot; Mahatma Gandhi, Indian philosopher, internationally esteemed for his doctrine of nonviolent protest, 1869-1948&lt;br /&gt;
** CommitMsg: Specified who is Mahatma Gandhi&lt;br /&gt;
&lt;br /&gt;
You will find a repository named GitTutorial here: http://github.com/commontk/GitTutorial&lt;br /&gt;
&lt;br /&gt;
* Step1&lt;br /&gt;
&lt;br /&gt;
* Step2&lt;br /&gt;
&lt;br /&gt;
* Step3&lt;br /&gt;
&lt;br /&gt;
* Step4&lt;br /&gt;
&lt;br /&gt;
* Step5&lt;br /&gt;
&lt;br /&gt;
* Step6&lt;br /&gt;
&lt;br /&gt;
* Step7&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Git Commit Style =&lt;br /&gt;
&lt;br /&gt;
* Write very descriptive and concise first line summary of your commit&lt;br /&gt;
** try to stick to 50 characters max (no more than 65)&lt;br /&gt;
** do not use &#039;COMP&#039; &#039;ENH&#039; etc.  (these cut into your 50 characters)&lt;br /&gt;
** summary should be a complete English sentence starting with a capital letter (terminating period is optional)&lt;br /&gt;
* Include a blank line after the summary and then a more detailed multi-line description (72 character max line length)&lt;br /&gt;
* In the body of the commit message, include #123 where 123 is the issue number.  If a final commit fixes the issue, include &amp;quot;Fixes #123&amp;quot; or &amp;quot;Closes #123&amp;quot; in the commit message.&lt;br /&gt;
* Use &amp;lt;code&amp;gt;git merge --log --no-ff &amp;lt;topicname&amp;gt;&amp;lt;/code&amp;gt; (this keeps the logs messages of the merged branch)&lt;br /&gt;
&lt;br /&gt;
= CTK Coding Style =&lt;br /&gt;
The overall policy is to follow the coding conventions of the parent classes unless there is an accepted CTK exception to improve consistency or usability (to account for inconsistency in the parent class system).  &lt;br /&gt;
&lt;br /&gt;
* If you are writing a widget that inherits from QObject, all your code should follow Qt coding conventions.&lt;br /&gt;
** Use the [http://www.commontk.org/docs/html/CorePimpl.html Private Implementation approach (&amp;quot;PIMPL&amp;quot;)] &#039;&#039;&#039;except&#039;&#039;&#039; make the member variables of your private class begin with a capital letter.  This means that when you create a widget using the QtDesigner, you must rename the widget to a local name that begins with a capital letter (since this will be an instance variable in your private implementation).&lt;br /&gt;
&lt;br /&gt;
* Use &#039;&#039;virtual&#039;&#039; keyword also in derived class. Doing so improve readability of the code.&lt;br /&gt;
&lt;br /&gt;
* Use const reference if it applies. For example:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp-qt&amp;quot;&amp;gt;&lt;br /&gt;
 void setName(const QString&amp;amp; newName); // better&lt;br /&gt;
 void setName(QString newName); // poor&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Use &#039;&#039;comment line&#039;&#039; separator. For example:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp-qt&amp;quot;&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
void Foo::setName(const QString&amp;amp; newName)&lt;br /&gt;
{&lt;br /&gt;
  Q_D(Foo);&lt;br /&gt;
  d-&amp;gt;Name = newName;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
QString Foo::name() const&lt;br /&gt;
{&lt;br /&gt;
  Q_D(const Foo);&lt;br /&gt;
  return d-&amp;gt;Name;&lt;br /&gt;
}&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* The following statements &#039;&#039;for&#039;&#039;, &#039;&#039;while&#039;&#039;, &#039;&#039;switch&#039;&#039;, &#039;&#039;if&#039;&#039;, &#039;&#039;else&#039;&#039;, &#039;&#039;try&#039;&#039;, &#039;&#039;catch&#039;&#039; should, most of time, be multi-line. The brackets should also be indented with 2 spaces.  For example:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp-qt&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
//----------------------------------------------------------------------------&lt;br /&gt;
bool Foo::doSomething(int count)&lt;br /&gt;
{&lt;br /&gt;
  // Better&lt;br /&gt;
  for(int i=1; i &amp;lt; count; ++i)&lt;br /&gt;
    {&lt;br /&gt;
    if (i == 100)&lt;br /&gt;
      {&lt;br /&gt;
      qDebug() &amp;lt;&amp;lt; &amp;quot;i = 100&amp;quot;;&lt;br /&gt;
      break;&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
  // Poor&lt;br /&gt;
  for(int i=1; i &amp;lt; count; ++i)&lt;br /&gt;
    if (i == 100) { qDebug() &amp;lt;&amp;lt; &amp;quot;i = 100&amp;quot;; break; }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* Within CMakeLists.txt files, source/header file names should be sorted alphabetically. It also applies with inclusion order in header/implementation files&lt;br /&gt;
* [http://marcmutz.wordpress.com/effective-qt/prefer-to-use-normalised-signalslot-signatures/ Prefer to use normalised signal/slot signatures]&lt;br /&gt;
&lt;br /&gt;
= FAQ =&lt;br /&gt;
* What the meaning of &#039;&#039;fatal: The current branch master is not tracking anything.&#039;&#039; ?&lt;/div&gt;</summary>
		<author><name>Danielle.pace</name></author>
	</entry>
	<entry>
		<id>https://www.commontk.org/index.php?title=Documentation/ctkWorkflowWidget&amp;diff=502</id>
		<title>Documentation/ctkWorkflowWidget</title>
		<link rel="alternate" type="text/html" href="https://www.commontk.org/index.php?title=Documentation/ctkWorkflowWidget&amp;diff=502"/>
		<updated>2011-01-13T17:46:34Z</updated>

		<summary type="html">&lt;p&gt;Danielle.pace: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Summary ==&lt;br /&gt;
&lt;br /&gt;
* Image analysis and image guided therapy procedures often have fairly complicated workflows&lt;br /&gt;
* CTK&#039;s workflow manager and workflow widgets provide a mechanism to construct workflows, display the appropriate user interface for each step, validatee user input and transition appropriately between steps of the workflow&lt;br /&gt;
* They use Qt&#039;s state machine implementation, with an additional CTK workflow manager layer&lt;br /&gt;
&lt;br /&gt;
== Workflow classes ==&lt;br /&gt;
* Core workflow functionality (no widgets):&lt;br /&gt;
** [https://github.com/commontk/CTK/tree/master/Libs/Core/ctkWorkflowStep.h ctkWorkflowStep]: a step in the workflow&lt;br /&gt;
** [https://github.com/commontk/CTK/tree/master/Libs/Core/ctkWorkflow.h ctkWorkflow]: the workflow&lt;br /&gt;
** [https://github.com/commontk/CTK/tree/master/Libs/ctkWorkflowTransition.h ctkWorkflowTransition]: a transition in the workflow&lt;br /&gt;
* Workflows associated with widgets:&lt;br /&gt;
** [https://github.com/commontk/CTK/tree/master/Libs/Widgets/ctkWorkflowWidgetStep.h ctkWorkflowWidgetStep]: a step in the workflow with a user interface&lt;br /&gt;
** [https://github.com/commontk/CTK/tree/master/Libs/Widgets/ctkWorkflowWidget.h ctkWorkflowWidget]: a workflow with a user interface&lt;br /&gt;
** [https://github.com/commontk/CTK/tree/master/Libs/Widgets/ctkWorkflowStackedWidget.h ctkWorkflowStackedWidget]: a workflow with a user interface with many pages, based on a QStackedWidget&lt;br /&gt;
** [https://github.com/commontk/CTK/tree/master/Libs/Widgets/ctkWorkflowTabWidget.h ctkWorkflowTabWidget]: a workflow with a user interface with many pages, based on a QTabWidget&lt;br /&gt;
** [https://github.com/commontk/CTK/tree/master/Libs/Widgets/ctkWorkflowGroupBox.h ctkWorkflowGroupBox]: organizes display of the user interface for a particular step, including a subtitle, pre-text, client area, post-text and error text&lt;br /&gt;
** [https://github.com/commontk/CTK/tree/master/Libs/Widgets/ctkWorkflowButtonBoxWidget.h ctkWorkflowButtonBoxWidget]: a widget containing &amp;quot;next&amp;quot;, &amp;quot;back&amp;quot; and &amp;quot;jump step&amp;quot; buttons&lt;br /&gt;
&lt;br /&gt;
== To define a new workflow step with a user interface ==&lt;br /&gt;
* Method 1: derive ctkWorkflowWidgetStep:&lt;br /&gt;
** Implement validate(): evaluates user input and returns true if valid, false if not.  Emits validateComplete(int) when finished.&lt;br /&gt;
** Implement entryProcessing(): processing that is done when entering the step.  Emits entryProcessingComplete() when finished.&lt;br /&gt;
** Implement exitProcessing(): processing that is done when exiting the step.  Emits exitProcessingComplete() when finished.&lt;br /&gt;
** Either:&lt;br /&gt;
*** Implement populateStepWidgetsList(QList&amp;lt;QWidget*&amp;gt;&amp;amp; stepWidgetsList): add the step&#039;s widgets to the given list; by default they will be displayed vertically in the order in which they were added.  Emits populateStepWidgetsListComplete() when finished.&lt;br /&gt;
*** Implement showUserInterface() and hideUserInterface(): for more control over the step&#039;s UI.  Emits showUserInterfaceComplete() and hideUserInterfaceComplete(), respectively, when finished.&lt;br /&gt;
&lt;br /&gt;
* Method 2: use signals and slots&lt;br /&gt;
** Create an object that derives QObject&lt;br /&gt;
** Implement slots that mimic the functionality of validate() / entryProcessing() / exitProcessing() / populateStepWidgetsList() / showUserInterface() / hideUserInterface(), and which emit a signal when completed&lt;br /&gt;
** Use regular ctkWorkflowWidgetSteps in the workflow, and set their hasXXXCommands (ex. hasValidateCommand) to 1&lt;br /&gt;
** Connect your object&#039;s signals/slots to those of the steps/workflow&lt;br /&gt;
** When the workflow runs, it will emit the relevant signals to trigger your QObject&#039;s slots, which will then send indicate completion by the signals they send.&lt;br /&gt;
&lt;br /&gt;
== Examples ==&lt;br /&gt;
&lt;br /&gt;
* Examples of how to create a custom workflow step:&lt;br /&gt;
** Method 1: [https://github.com/commontk/CTK/tree/master/Libs/Widgets/Testing/Cpp/ctkExampleDerivedWorkflowWidgetStep.h ctkExampleDerivedWorkflowWidgetStep.h] and [https://github.com/commontk/CTK/tree/master/Libs/Widgets/Testing/Cpp/ctkExampleDerivedWorkflowWidgetStep.cpp ctkExampleDerivedWorkflowWidgetStep.cpp]: custom step created by deriving [https://github.com/commontk/CTK/tree/master/Libs/Widgets/ctkWorkflowWidgetStep.h ctkWorkflowWidgetStep]&lt;br /&gt;
** Method 2: [https://github.com/commontk/CTK/tree/master/Libs/Widgets/Testing/Cpp/ctkExampleWorkflowWidgetStepUsingSignalsAndSlots.h ctkExampleWorkflowWidgetStepUsingSignalsAndSlots.h] and [hhttps://github.com/commontk/CTK/tree/master/Libs/Widgets/Testing/Cpp/ctkExampleWorkflowWidgetStepUsingSignalsAndSlots.cpp ctkExampleWorkflowWidgetStepUsingSignalsAndSlots.cpp]: custom step created by implementing the step&#039;s functionality in a class derived from QObject, and communicating with the workflow using its signal-slot mechanism&lt;br /&gt;
* Examples of how to create a workflow:&lt;br /&gt;
** Method 1: [https://github.com/commontk/CTK/tree/master/Libs/Widgets/Testing/Cpp/ctkExampleUseOfWorkflowWidgetUsingDerivedSteps.cpp ctkExampleUseOfWorkflowWidgetUsingDerivedSteps]: builds a simple workflow using custom steps that derive ctkWorkflowWidgetStep&lt;br /&gt;
** Method 2: [https://github.com/commontk/CTK/tree/master/Libs/Widgets/Testing/Cpp/ctkExampleUseOfWorkflowWidgetUsingSignalsAndSlots.cpp ctkExampleUseOfWorkflowWidgetUsingSignalsAndSlots]: builds a simple workflow using custom steps that communicate with the workflow using its signal-slot mechanism&lt;br /&gt;
* Examples of the workflow manager in Slicer 4:&lt;br /&gt;
** EM Segmenter module&lt;br /&gt;
&lt;br /&gt;
== Overview of state diagram underlying ctkWorkflow ==&lt;br /&gt;
* Processing step = handles user interaction, and supports additional processing (ex. image processing) as well&lt;br /&gt;
* Validation step = evaluates the success of the processing step&lt;br /&gt;
* Currently supported transitions:&lt;br /&gt;
** Transition to the next step&lt;br /&gt;
** Transition to the previous step&lt;br /&gt;
** Transition to a &amp;quot;finish&amp;quot; step&lt;br /&gt;
*** Equivalent to doing &amp;quot;next, next, next, next...&amp;quot; until you hit the finish step: completes all entry/exit processing associated with each step encountered on the way to the finish step, without showing user interface.&lt;br /&gt;
*** Success relies on the suitability of the default processing, parameters, etc&lt;br /&gt;
*** &amp;quot;Blocking&amp;quot; steps, ex. those requiring user interaction, will prohibit success in transitioning to the finish step&lt;br /&gt;
*** On success: transitions back to the step where the attempt to go to the finish step was initiated, so that the user can perform additional customization from there if needed.&lt;br /&gt;
*** On failure: remains in the step whose validate() returned failure, and shows its user interface.&lt;br /&gt;
&lt;br /&gt;
== GUI implementation in ctkWorkflowWidget ==&lt;br /&gt;
* workflowWidget-&amp;gt;addWidget(QWidget* widget): adds a widget to the clientArea&lt;br /&gt;
* workflowWidget-&amp;gt;showWidget(QWidget* widget): shows the clientArea (i.e. for ctkWorkflowStackedWidget and ctkWorkflowTabWidget, ensures that the correct &amp;quot;page&amp;quot; is shownl&lt;br /&gt;
&lt;br /&gt;
== Examples ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ctkworkflow w;&lt;br /&gt;
ctkWorkflowStep s1(&amp;quot;select_image&amp;quot;);&lt;br /&gt;
ctkWorkflowStep s2(&amp;quot;input_new_size&amp;quot;);&lt;br /&gt;
ctkWorkflowStep s3(&amp;quot;display_resized_image&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
w.addTransition(&amp;amp;s1, &amp;amp;s2);&lt;br /&gt;
w.addTransition(&amp;amp;s2, &amp;amp;s3);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Workflow layout =&lt;br /&gt;
[[File:workflowWidgetLayout.png]]&lt;br /&gt;
&lt;br /&gt;
= Branching workflows = &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
                s3----s4    &amp;quot;simple&amp;quot;&lt;br /&gt;
               /&lt;br /&gt;
  s0----s1----s2&lt;br /&gt;
               \&lt;br /&gt;
                s5----s6    &amp;quot;advanced&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Associated code:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ctkWorkflow w;&lt;br /&gt;
&lt;br /&gt;
ctkWorkflowStep s0;&lt;br /&gt;
...&lt;br /&gt;
ctkWorkflowStep s6;&lt;br /&gt;
&lt;br /&gt;
w.setInitialStep(s0); [Ideally - should be optional]&lt;br /&gt;
&lt;br /&gt;
w.addTransition(s0, s1);&lt;br /&gt;
w.addTransition(s1, s2);&lt;br /&gt;
w.addTransition(s2, s3, ctkWorkflow::BiDirectionnal, &amp;quot;simple&amp;quot;);&lt;br /&gt;
w.addTransition(s3, s4);&lt;br /&gt;
w.addTransition(s2, s5, ctkWorkflow::BiDirectionnal, &amp;quot;advanced&amp;quot;);&lt;br /&gt;
w.addTransition(s5, s6);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Conditional branching:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[signal] void validationComplete(bool isValid, const QString&amp;amp; branchId)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;ctkWorkflow::validate() doesn&#039;t give branchId:&#039;&#039;&#039;&lt;br /&gt;
** Single transition:&lt;br /&gt;
*** transition created without branchId: post transition&lt;br /&gt;
*** transition created with branchId: post transition&lt;br /&gt;
&lt;br /&gt;
** Multiple transitions:&lt;br /&gt;
*** &#039;&#039;(incorrect usage)&#039;&#039; transitions created with branchIds: use first transition that was added&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;ctkWorkflow::validate() gives branchId:&#039;&#039;&#039;&lt;br /&gt;
** Single transition:&lt;br /&gt;
*** transition created without branchId: post transition &#039;&#039;(workflow overrides step)&#039;&#039;&lt;br /&gt;
*** transition created with branchId: conditional transition based on match, if no match then stay in current step&lt;br /&gt;
** Multiple transitions:&lt;br /&gt;
*** transitions created with branchIds: conditional transition based on match, if no match then stay in current step&lt;/div&gt;</summary>
		<author><name>Danielle.pace</name></author>
	</entry>
	<entry>
		<id>https://www.commontk.org/index.php?title=Documentation/ctkWorkflowWidget&amp;diff=501</id>
		<title>Documentation/ctkWorkflowWidget</title>
		<link rel="alternate" type="text/html" href="https://www.commontk.org/index.php?title=Documentation/ctkWorkflowWidget&amp;diff=501"/>
		<updated>2011-01-13T17:44:35Z</updated>

		<summary type="html">&lt;p&gt;Danielle.pace: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Summary ==&lt;br /&gt;
&lt;br /&gt;
* Image analysis and image guided therapy procedures often have fairly complicated workflows&lt;br /&gt;
* CTK&#039;s workflow manager and workflow widgets provide a mechanism to construct workflows, display the appropriate user interface for each step, validatee user input and transition appropriately between steps of the workflow&lt;br /&gt;
* They use Qt&#039;s state machine implementation, with an additional CTK workflow manager layer&lt;br /&gt;
&lt;br /&gt;
== Workflow classes ==&lt;br /&gt;
* Core workflow functionality (no widgets):&lt;br /&gt;
** [https://github.com/commontk/CTK/tree/master/Libs/Core/ctkWorkflowStep.h ctkWorkflowStep]: a step in the workflow&lt;br /&gt;
** [https://github.com/commontk/CTK/tree/master/Libs/Core/ctkWorkflow.h ctkWorkflow]: the workflow&lt;br /&gt;
** [https://github.com/commontk/CTK/tree/master/Libs/ctkWorkflowTransition.h ctkWorkflowTransition]: a transition in the workflow&lt;br /&gt;
* Workflows associated with widgets:&lt;br /&gt;
** [https://github.com/commontk/CTK/tree/master/Libs/Widgets/ctkWorkflowWidgetStep.h ctkWorkflowWidgetStep]: a step in the workflow with a user interface&lt;br /&gt;
** [https://github.com/commontk/CTK/tree/master/Libs/Widgets/ctkWorkflowWidget.h ctkWorkflowWidget]: a workflow with a user interface&lt;br /&gt;
** [https://github.com/commontk/CTK/tree/master/Libs/Widgets/ctkWorkflowStackedWidget.h ctkWorkflowStackedWidget]: a workflow with a user interface with many pages, based on a QStackedWidget&lt;br /&gt;
** [https://github.com/commontk/CTK/tree/master/Libs/Libs/Widgets/ctkWorkflowTabWidget.h ctkWorkflowTabWidget]: a workflow with a user interface with many pages, based on a QTabWidget&lt;br /&gt;
** [https://github.com/commontk/CTK/tree/master/Libs/Libs/Widgets/ctkWorkflowGroupBox.h ctkWorkflowGroupBox]: organizes display of the user interface for a particular step, including a subtitle, pre-text, client area, post-text and error text&lt;br /&gt;
** [https://github.com/commontk/CTK/tree/master/Libs/Libs/Widgets/ctkWorkflowButtonBoxWidget.h ctkWorkflowButtonBoxWidget]: a widget containing &amp;quot;next&amp;quot;, &amp;quot;back&amp;quot; and &amp;quot;jump step&amp;quot; buttons&lt;br /&gt;
&lt;br /&gt;
== To define a new workflow step with a user interface ==&lt;br /&gt;
* Method 1: derive ctkWorkflowWidgetStep:&lt;br /&gt;
** Implement validate(): evaluates user input and returns true if valid, false if not.  Emits validateComplete(int) when finished.&lt;br /&gt;
** Implement entryProcessing(): processing that is done when entering the step.  Emits entryProcessingComplete() when finished.&lt;br /&gt;
** Implement exitProcessing(): processing that is done when exiting the step.  Emits exitProcessingComplete() when finished.&lt;br /&gt;
** Either:&lt;br /&gt;
*** Implement populateStepWidgetsList(QList&amp;lt;QWidget*&amp;gt;&amp;amp; stepWidgetsList): add the step&#039;s widgets to the given list; by default they will be displayed vertically in the order in which they were added.  Emits populateStepWidgetsListComplete() when finished.&lt;br /&gt;
*** Implement showUserInterface() and hideUserInterface(): for more control over the step&#039;s UI.  Emits showUserInterfaceComplete() and hideUserInterfaceComplete(), respectively, when finished.&lt;br /&gt;
&lt;br /&gt;
* Method 2: use signals and slots&lt;br /&gt;
** Create an object that derives QObject&lt;br /&gt;
** Implement slots that mimic the functionality of validate() / entryProcessing() / exitProcessing() / populateStepWidgetsList() / showUserInterface() / hideUserInterface(), and which emit a signal when completed&lt;br /&gt;
** Use regular ctkWorkflowWidgetSteps in the workflow, and set their hasXXXCommands (ex. hasValidateCommand) to 1&lt;br /&gt;
** Connect your object&#039;s signals/slots to those of the steps/workflow&lt;br /&gt;
** When the workflow runs, it will emit the relevant signals to trigger your QObject&#039;s slots, which will then send indicate completion by the signals they send.&lt;br /&gt;
&lt;br /&gt;
== Examples ==&lt;br /&gt;
&lt;br /&gt;
* Examples of how to create a custom workflow step:&lt;br /&gt;
** Method 1: [https://github.com/commontk/CTK/tree/master/Libs/Widgets/Testing/Cpp/ctkExampleDerivedWorkflowWidgetStep.h ctkExampleDerivedWorkflowWidgetStep.h] and [https://github.com/commontk/CTK/tree/master/Libs/Widgets/Testing/Cpp/ctkExampleDerivedWorkflowWidgetStep.cpp ctkExampleDerivedWorkflowWidgetStep.cpp]: custom step created by deriving [https://github.com/commontk/CTK/tree/master/Libs/Widgets/ctkWorkflowWidgetStep.h ctkWorkflowWidgetStep]&lt;br /&gt;
** Method 2: [https://github.com/commontk/CTK/tree/master/Libs/Widgets/Testing/Cpp/ctkExampleWorkflowWidgetStepUsingSignalsAndSlots.h ctkExampleWorkflowWidgetStepUsingSignalsAndSlots.h] and [hhttps://github.com/commontk/CTK/tree/master/Libs/Widgets/Testing/Cpp/ctkExampleWorkflowWidgetStepUsingSignalsAndSlots.cpp ctkExampleWorkflowWidgetStepUsingSignalsAndSlots.cpp]: custom step created by implementing the step&#039;s functionality in a class derived from QObject, and communicating with the workflow using its signal-slot mechanism&lt;br /&gt;
* Examples of how to create a workflow:&lt;br /&gt;
** Method 1: [https://github.com/commontk/CTK/tree/master/Libs/Widgets/Testing/Cpp/ctkExampleUseOfWorkflowWidgetUsingDerivedSteps.cpp ctkExampleUseOfWorkflowWidgetUsingDerivedSteps]: builds a simple workflow using custom steps that derive ctkWorkflowWidgetStep&lt;br /&gt;
** Method 2: [https://github.com/commontk/CTK/tree/master/Libs/Widgets/Testing/Cpp/ctkExampleUseOfWorkflowWidgetUsingSignalsAndSlots.cpp ctkExampleUseOfWorkflowWidgetUsingSignalsAndSlots]: builds a simple workflow using custom steps that communicate with the workflow using its signal-slot mechanism&lt;br /&gt;
* Examples of the workflow manager in Slicer 4:&lt;br /&gt;
** EM Segmenter module&lt;br /&gt;
&lt;br /&gt;
== Overview of state diagram underlying ctkWorkflow ==&lt;br /&gt;
* Processing step = handles user interaction, and supports additional processing (ex. image processing) as well&lt;br /&gt;
* Validation step = evaluates the success of the processing step&lt;br /&gt;
* Currently supported transitions:&lt;br /&gt;
** Transition to the next step&lt;br /&gt;
** Transition to the previous step&lt;br /&gt;
** Transition to a &amp;quot;finish&amp;quot; step&lt;br /&gt;
*** Equivalent to doing &amp;quot;next, next, next, next...&amp;quot; until you hit the finish step: completes all entry/exit processing associated with each step encountered on the way to the finish step, without showing user interface.&lt;br /&gt;
*** Success relies on the suitability of the default processing, parameters, etc&lt;br /&gt;
*** &amp;quot;Blocking&amp;quot; steps, ex. those requiring user interaction, will prohibit success in transitioning to the finish step&lt;br /&gt;
*** On success: transitions back to the step where the attempt to go to the finish step was initiated, so that the user can perform additional customization from there if needed.&lt;br /&gt;
*** On failure: remains in the step whose validate() returned failure, and shows its user interface.&lt;br /&gt;
&lt;br /&gt;
== GUI implementation in ctkWorkflowWidget ==&lt;br /&gt;
* workflowWidget-&amp;gt;addWidget(QWidget* widget): adds a widget to the clientArea&lt;br /&gt;
* workflowWidget-&amp;gt;showWidget(QWidget* widget): shows the clientArea (i.e. for ctkWorkflowStackedWidget and ctkWorkflowTabWidget, ensures that the correct &amp;quot;page&amp;quot; is shownl&lt;br /&gt;
&lt;br /&gt;
== Examples ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ctkworkflow w;&lt;br /&gt;
ctkWorkflowStep s1(&amp;quot;select_image&amp;quot;);&lt;br /&gt;
ctkWorkflowStep s2(&amp;quot;input_new_size&amp;quot;);&lt;br /&gt;
ctkWorkflowStep s3(&amp;quot;display_resized_image&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
w.addTransition(&amp;amp;s1, &amp;amp;s2);&lt;br /&gt;
w.addTransition(&amp;amp;s2, &amp;amp;s3);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Workflow layout =&lt;br /&gt;
[[File:workflowWidgetLayout.png]]&lt;br /&gt;
&lt;br /&gt;
= Branching workflows = &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
                s3----s4    &amp;quot;simple&amp;quot;&lt;br /&gt;
               /&lt;br /&gt;
  s0----s1----s2&lt;br /&gt;
               \&lt;br /&gt;
                s5----s6    &amp;quot;advanced&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Associated code:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ctkWorkflow w;&lt;br /&gt;
&lt;br /&gt;
ctkWorkflowStep s0;&lt;br /&gt;
...&lt;br /&gt;
ctkWorkflowStep s6;&lt;br /&gt;
&lt;br /&gt;
w.setInitialStep(s0); [Ideally - should be optional]&lt;br /&gt;
&lt;br /&gt;
w.addTransition(s0, s1);&lt;br /&gt;
w.addTransition(s1, s2);&lt;br /&gt;
w.addTransition(s2, s3, ctkWorkflow::BiDirectionnal, &amp;quot;simple&amp;quot;);&lt;br /&gt;
w.addTransition(s3, s4);&lt;br /&gt;
w.addTransition(s2, s5, ctkWorkflow::BiDirectionnal, &amp;quot;advanced&amp;quot;);&lt;br /&gt;
w.addTransition(s5, s6);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Conditional branching:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[signal] void validationComplete(bool isValid, const QString&amp;amp; branchId)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;ctkWorkflow::validate() doesn&#039;t give branchId:&#039;&#039;&#039;&lt;br /&gt;
** Single transition:&lt;br /&gt;
*** transition created without branchId: post transition&lt;br /&gt;
*** transition created with branchId: post transition&lt;br /&gt;
&lt;br /&gt;
** Multiple transitions:&lt;br /&gt;
*** &#039;&#039;(incorrect usage)&#039;&#039; transitions created with branchIds: use first transition that was added&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;ctkWorkflow::validate() gives branchId:&#039;&#039;&#039;&lt;br /&gt;
** Single transition:&lt;br /&gt;
*** transition created without branchId: post transition &#039;&#039;(workflow overrides step)&#039;&#039;&lt;br /&gt;
*** transition created with branchId: conditional transition based on match, if no match then stay in current step&lt;br /&gt;
** Multiple transitions:&lt;br /&gt;
*** transitions created with branchIds: conditional transition based on match, if no match then stay in current step&lt;/div&gt;</summary>
		<author><name>Danielle.pace</name></author>
	</entry>
	<entry>
		<id>https://www.commontk.org/index.php?title=Documentation/ctkWorkflowWidget&amp;diff=500</id>
		<title>Documentation/ctkWorkflowWidget</title>
		<link rel="alternate" type="text/html" href="https://www.commontk.org/index.php?title=Documentation/ctkWorkflowWidget&amp;diff=500"/>
		<updated>2011-01-13T17:42:28Z</updated>

		<summary type="html">&lt;p&gt;Danielle.pace: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Summary ==&lt;br /&gt;
&lt;br /&gt;
* Image analysis and image guided therapy procedures often have fairly complicated workflows&lt;br /&gt;
* CTK&#039;s workflow manager and workflow widgets provide a mechanism to construct workflows, display the appropriate user interface for each step, validatee user input and transition appropriately between steps of the workflow&lt;br /&gt;
* They use Qt&#039;s state machine implementation, with an additional CTK workflow manager layer&lt;br /&gt;
&lt;br /&gt;
== Workflow classes ==&lt;br /&gt;
* Core workflow functionality (no widgets):&lt;br /&gt;
** [https://github.com/commontk/CTK/tree/master/Libs/Core/ctkWorkflowStep.h ctkWorkflowStep]: a step in the workflow&lt;br /&gt;
** [https://github.com/commontk/CTK/tree/master/Libs/Core/ctkWorkflow.h ctkWorkflow]: the workflow&lt;br /&gt;
** [https://github.com/commontk/CTK/tree/master/Libs/ctkWorkflowTransition.h ctkWorkflowTransition]: a transition in the workflow&lt;br /&gt;
* Workflows associated with widgets:&lt;br /&gt;
** [https://github.com/commontk/CTK/tree/master/Libs/Widgets/ctkWorkflowWidgetStep.h ctkWorkflowWidgetStep]: a step in the workflow with a user interface&lt;br /&gt;
** [https://github.com/commontk/CTK/tree/master/Libs/Widgets/ctkWorkflowWidget.h ctkWorkflowWidget]: a workflow with a user interface&lt;br /&gt;
** [https://github.com/commontk/CTK/tree/master/Libs/Widgets/ctkWorkflowStackedWidget.h ctkWorkflowStackedWidget]: a workflow with a user interface with many pages, based on a QStackedWidget&lt;br /&gt;
** [https://github.com/commontk/CTK/tree/master/Libs/Libs/Widgets/ctkWorkflowTabWidget.h ctkWorkflowTabWidget]: a workflow with a user interface with many pages, based on a QTabWidget&lt;br /&gt;
** [https://github.com/commontk/CTK/tree/master/Libs/Libs/Widgets/ctkWorkflowGroupBox.h ctkWorkflowGroupBox]: organizes display of the user interface for a particular step, including a subtitle, pre-text, client area, post-text and error text&lt;br /&gt;
** [https://github.com/commontk/CTK/tree/master/Libs/Libs/Widgets/ctkWorkflowButtonBoxWidget.h ctkWorkflowButtonBoxWidget]: a widget containing &amp;quot;next&amp;quot;, &amp;quot;back&amp;quot; and &amp;quot;jump step&amp;quot; buttons&lt;br /&gt;
&lt;br /&gt;
== To define a new workflow step with a user interface ==&lt;br /&gt;
* Method 1: derive ctkWorkflowWidgetStep:&lt;br /&gt;
** Implement validate(): evaluates user input and returns true if valid, false if not.  Emits validateComplete(int) when finished.&lt;br /&gt;
** Implement entryProcessing(): processing that is done when entering the step.  Emits entryProcessingComplete() when finished.&lt;br /&gt;
** Implement exitProcessing(): processing that is done when exiting the step.  Emits exitProcessingComplete() when finished.&lt;br /&gt;
** Either:&lt;br /&gt;
*** Implement populateStepWidgetsList(QList&amp;lt;QWidget*&amp;gt;&amp;amp; stepWidgetsList): add the step&#039;s widgets to the given list; by default they will be displayed vertically in the order in which they were added.  Emits populateStepWidgetsListComplete() when finished.&lt;br /&gt;
*** Implement showUserInterface() and hideUserInterface(): for more control over the step&#039;s UI.  Emits showUserInterfaceComplete() and hideUserInterfaceComplete(), respectively, when finished.&lt;br /&gt;
&lt;br /&gt;
* Method 2: use signals and slots&lt;br /&gt;
** Create an object that derives QObject&lt;br /&gt;
** Implement slots that mimic the functionality of validate() / entryProcessing() / exitProcessing() / populateStepWidgetsList() / showUserInterface() / hideUserInterface(), and which emit a signal when completed&lt;br /&gt;
** Use regular ctkWorkflowWidgetSteps in the workflow, and set their hasXXXCommands (ex. hasValidateCommand) to 1&lt;br /&gt;
** Connect your object&#039;s signals/slots to those of the steps/workflow&lt;br /&gt;
** When the workflow runs, it will emit the relevant signals to trigger your QObject&#039;s slots, which will then send indicate completion by the signals they send.&lt;br /&gt;
&lt;br /&gt;
== Examples ==&lt;br /&gt;
&lt;br /&gt;
* examples of how to create a custom workflow step:&lt;br /&gt;
** Method 1: [https://github.com/commontk/CTK/tree/master/Libs/Widgets/Testing/Cpp/ctkExampleDerivedWorkflowWidgetStep.h ctkExampleDerivedWorkflowWidgetStep.h] and [https://github.com/commontk/CTK/tree/master/Libs/Widgets/Testing/Cpp/ctkExampleDerivedWorkflowWidgetStep.cpp ctkExampleDerivedWorkflowWidgetStep.cpp]: custom step created by deriving [https://github.com/commontk/CTK/tree/master/Libs/Widgets/ctkWorkflowWidgetStep.h ctkWorkflowWidgetStep]&lt;br /&gt;
** Method 2: [https://github.com/commontk/CTK/tree/master/Libs/Widgets/Testing/Cpp/ctkExampleWorkflowWidgetStepUsingSignalsAndSlots.h ctkExampleWorkflowWidgetStepUsingSignalsAndSlots.h] and [hhttps://github.com/commontk/CTK/tree/master/Libs/Widgets/Testing/Cpp/ctkExampleWorkflowWidgetStepUsingSignalsAndSlots.cpp ctkExampleWorkflowWidgetStepUsingSignalsAndSlots.cpp]: custom step created by implementing the step&#039;s functionality in a class derived from QObject, and communicating with the workflow using its signal-slot mechanism&lt;br /&gt;
* examples of how to create a workflow:&lt;br /&gt;
** Method 1: [hhttps://github.com/commontk/CTK/tree/master/Libs/Widgets/Testing/Cpp/ctkExampleUseOfWorkflowWidgetUsingDerivedSteps.cpp ctkExampleUseOfWorkflowWidgetUsingDerivedSteps]: builds a simple workflow using custom steps that derive ctkWorkflowWidgetStep&lt;br /&gt;
** Method 2: [https://github.com/commontk/CTK/tree/master/Libs/Widgets/Testing/Cpp/ctkExampleUseOfWorkflowWidgetUsingSignalsAndSlots.cpp ctkExampleUseOfWorkflowWidgetUsingSignalsAndSlots]: builds a simple workflow using custom steps that communicate with the workflow using its signal-slot mechanism&lt;br /&gt;
&lt;br /&gt;
== Overview of state diagram underlying ctkWorkflow ==&lt;br /&gt;
* Processing step = handles user interaction, and supports additional processing (ex. image processing) as well&lt;br /&gt;
* Validation step = evaluates the success of the processing step&lt;br /&gt;
* Currently supported transitions:&lt;br /&gt;
** Transition to the next step&lt;br /&gt;
** Transition to the previous step&lt;br /&gt;
** Transition to a &amp;quot;finish&amp;quot; step&lt;br /&gt;
*** Equivalent to doing &amp;quot;next, next, next, next...&amp;quot; until you hit the finish step: completes all entry/exit processing associated with each step encountered on the way to the finish step, without showing user interface.&lt;br /&gt;
*** Success relies on the suitability of the default processing, parameters, etc&lt;br /&gt;
*** &amp;quot;Blocking&amp;quot; steps, ex. those requiring user interaction, will prohibit success in transitioning to the finish step&lt;br /&gt;
*** On success: transitions back to the step where the attempt to go to the finish step was initiated, so that the user can perform additional customization from there if needed.&lt;br /&gt;
*** On failure: remains in the step whose validate() returned failure, and shows its user interface.&lt;br /&gt;
&lt;br /&gt;
== GUI implementation in ctkWorkflowWidget ==&lt;br /&gt;
* workflowWidget-&amp;gt;addWidget(QWidget* widget): adds a widget to the clientArea&lt;br /&gt;
* workflowWidget-&amp;gt;showWidget(QWidget* widget): shows the clientArea (i.e. for ctkWorkflowStackedWidget and ctkWorkflowTabWidget, ensures that the correct &amp;quot;page&amp;quot; is shownl&lt;br /&gt;
&lt;br /&gt;
== Examples ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ctkworkflow w;&lt;br /&gt;
ctkWorkflowStep s1(&amp;quot;select_image&amp;quot;);&lt;br /&gt;
ctkWorkflowStep s2(&amp;quot;input_new_size&amp;quot;);&lt;br /&gt;
ctkWorkflowStep s3(&amp;quot;display_resized_image&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
w.addTransition(&amp;amp;s1, &amp;amp;s2);&lt;br /&gt;
w.addTransition(&amp;amp;s2, &amp;amp;s3);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Workflow layout =&lt;br /&gt;
[[File:workflowWidgetLayout.png]]&lt;br /&gt;
&lt;br /&gt;
= Branching workflows = &lt;br /&gt;
&lt;br /&gt;
API:&lt;br /&gt;
&lt;br /&gt;
* addTransition(ctkWorkflowStep* originStep, ctkWorkflowStep* destinationStep, const ctkWorkflow::TransitionType&amp;amp; transitionType, const QString&amp;amp; branchId = &amp;quot;&amp;quot;)&lt;br /&gt;
** must give a branchId if destinationStep is the 2nd/3rd/4th, etc step added to originStep&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
                s3----s4    &amp;quot;simple&amp;quot;&lt;br /&gt;
               /&lt;br /&gt;
  s0----s1----s2&lt;br /&gt;
               \&lt;br /&gt;
                s5----s6    &amp;quot;advanced&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Associated code:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ctkWorkflow w;&lt;br /&gt;
&lt;br /&gt;
ctkWorkflowStep s0;&lt;br /&gt;
...&lt;br /&gt;
ctkWorkflowStep s6;&lt;br /&gt;
&lt;br /&gt;
w.setInitialStep(s0); [Ideally - should be optional]&lt;br /&gt;
&lt;br /&gt;
w.addTransition(s0, s1);&lt;br /&gt;
w.addTransition(s1, s2);&lt;br /&gt;
w.addTransition(s2, s3, ctkWorkflow::BiDirectionnal, &amp;quot;simple&amp;quot;);&lt;br /&gt;
w.addTransition(s3, s4);&lt;br /&gt;
w.addTransition(s2, s5, ctkWorkflow::BiDirectionnal, &amp;quot;advanced&amp;quot;);&lt;br /&gt;
w.addTransition(s5, s6);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Conditional branching:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[signal] void validationComplete(bool isValid, const QString&amp;amp; branchId)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;ctkWorkflow::validate() doesn&#039;t give branchId:&#039;&#039;&#039;&lt;br /&gt;
** Single transition:&lt;br /&gt;
*** transition created without branchId: post transition&lt;br /&gt;
*** transition created with branchId: post transition&lt;br /&gt;
&lt;br /&gt;
** Multiple transitions:&lt;br /&gt;
*** &#039;&#039;(incorrect usage)&#039;&#039; transitions created with branchIds: use first transition that was added&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;ctkWorkflow::validate() gives branchId:&#039;&#039;&#039;&lt;br /&gt;
** Single transition:&lt;br /&gt;
*** transition created without branchId: post transition &#039;&#039;(workflow overrides step)&#039;&#039;&lt;br /&gt;
*** transition created with branchId: conditional transition based on match, if no match then stay in current step&lt;br /&gt;
** Multiple transitions:&lt;br /&gt;
*** transitions created with branchIds: conditional transition based on match, if no match then stay in current step&lt;/div&gt;</summary>
		<author><name>Danielle.pace</name></author>
	</entry>
	<entry>
		<id>https://www.commontk.org/index.php?title=File:WorkflowWidgetLayout.png&amp;diff=499</id>
		<title>File:WorkflowWidgetLayout.png</title>
		<link rel="alternate" type="text/html" href="https://www.commontk.org/index.php?title=File:WorkflowWidgetLayout.png&amp;diff=499"/>
		<updated>2011-01-13T17:32:43Z</updated>

		<summary type="html">&lt;p&gt;Danielle.pace: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Danielle.pace</name></author>
	</entry>
	<entry>
		<id>https://www.commontk.org/index.php?title=Documentation/ctkWorkflowWidget&amp;diff=498</id>
		<title>Documentation/ctkWorkflowWidget</title>
		<link rel="alternate" type="text/html" href="https://www.commontk.org/index.php?title=Documentation/ctkWorkflowWidget&amp;diff=498"/>
		<updated>2011-01-13T17:30:03Z</updated>

		<summary type="html">&lt;p&gt;Danielle.pace: Created page with &amp;#039;== Summary ==  * Image analysis and image guided therapy procedures often have fairly complicated workflows * CTK&amp;#039;s workflow manager and workflow widgets provide a mechanism to c…&amp;#039;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Summary ==&lt;br /&gt;
&lt;br /&gt;
* Image analysis and image guided therapy procedures often have fairly complicated workflows&lt;br /&gt;
* CTK&#039;s workflow manager and workflow widgets provide a mechanism to construct workflows, display the appropriate user interface for each step, validatee user input and transition appropriately between steps of the workflow&lt;br /&gt;
* They use Qt&#039;s state machine implementation, with an additional CTK workflow manager layer&lt;br /&gt;
&lt;br /&gt;
== Workflow classes ==&lt;br /&gt;
* Core workflow functionality (no widgets):&lt;br /&gt;
** [https://github.com/commontk/CTK/tree/master/Libs/Core/ctkWorkflowStep.h ctkWorkflowStep]: a step in the workflow&lt;br /&gt;
** [https://github.com/commontk/CTK/tree/master/Libs/Core/ctkWorkflow.h ctkWorkflow]: the workflow&lt;br /&gt;
** [https://github.com/commontk/CTK/tree/master/Libs/ctkWorkflowTransition.h ctkWorkflowTransition]: a transition in the workflow&lt;br /&gt;
* Workflows associated with widgets:&lt;br /&gt;
** [https://github.com/commontk/CTK/tree/master/Libs/Widgets/ctkWorkflowWidgetStep.h ctkWorkflowWidgetStep]: a step in the workflow with a user interface&lt;br /&gt;
** [https://github.com/commontk/CTK/tree/master/Libs/Widgets/ctkWorkflowWidget.h ctkWorkflowWidget]: a workflow with a user interface&lt;br /&gt;
** [https://github.com/commontk/CTK/tree/master/Libs/Widgets/ctkWorkflowStackedWidget.h ctkWorkflowStackedWidget]: a workflow with a user interface with many pages, based on a QStackedWidget&lt;br /&gt;
** [https://github.com/commontk/CTK/tree/master/Libs/Libs/Widgets/ctkWorkflowTabWidget.h ctkWorkflowTabWidget]: a workflow with a user interface with many pages, based on a QTabWidget&lt;br /&gt;
** [https://github.com/commontk/CTK/tree/master/Libs/Libs/Widgets/ctkWorkflowGroupBox.h ctkWorkflowGroupBox]: organizes display of the user interface for a particular step, including a subtitle, pre-text, client area, post-text and error text&lt;br /&gt;
** [https://github.com/commontk/CTK/tree/master/Libs/Libs/Widgets/ctkWorkflowButtonBoxWidget.h ctkWorkflowButtonBoxWidget]: a widget containing &amp;quot;next&amp;quot;, &amp;quot;back&amp;quot; and &amp;quot;jump step&amp;quot; buttons&lt;br /&gt;
&lt;br /&gt;
== To define a new workflow step with a user interface ==&lt;br /&gt;
* Method 1: derive ctkWorkflowWidgetStep:&lt;br /&gt;
** Implement validate(): evaluates user input and returns true if valid, false if not.  Emits validateComplete(int) when finished.&lt;br /&gt;
** Implement entryProcessing(): processing that is done when entering the step.  Emits entryProcessingComplete() when finished.&lt;br /&gt;
** Implement exitProcessing(): processing that is done when exiting the step.  Emits exitProcessingComplete() when finished.&lt;br /&gt;
** Either:&lt;br /&gt;
*** Implement populateStepWidgetsList(QList&amp;lt;QWidget*&amp;gt;&amp;amp; stepWidgetsList): add the step&#039;s widgets to the given list; by default they will be displayed vertically in the order in which they were added.  Emits populateStepWidgetsListComplete() when finished.&lt;br /&gt;
*** Implement showUserInterface() and hideUserInterface(): for more control over the step&#039;s UI.  Emits showUserInterfaceComplete() and hideUserInterfaceComplete(), respectively, when finished.&lt;br /&gt;
&lt;br /&gt;
* Method 2: use signals and slots&lt;br /&gt;
** Create an object that derives QObject&lt;br /&gt;
** Implement slots that mimic the functionality of validate() / entryProcessing() / exitProcessing() / populateStepWidgetsList() / showUserInterface() / hideUserInterface(), and which emit a signal when completed&lt;br /&gt;
** Use regular ctkWorkflowWidgetSteps in the workflow, and set their hasXXXCommands (ex. hasValidateCommand) to 1&lt;br /&gt;
** Connect your object&#039;s signals/slots to those of the steps/workflow&lt;br /&gt;
** When the workflow runs, it will emit the relevant signals to trigger your QObject&#039;s slots, which will then send indicate completion by the signals they send.&lt;br /&gt;
&lt;br /&gt;
== Examples ==&lt;br /&gt;
&lt;br /&gt;
* examples of how to create a custom workflow step:&lt;br /&gt;
** Method 1: [https://github.com/commontk/CTK/tree/master/Libs/Widgets/Testing/Cpp/ctkExampleDerivedWorkflowWidgetStep.h ctkExampleDerivedWorkflowWidgetStep.h] and [https://github.com/commontk/CTK/tree/master/Libs/Widgets/Testing/Cpp/ctkExampleDerivedWorkflowWidgetStep.cpp ctkExampleDerivedWorkflowWidgetStep.cpp]: custom step created by deriving [https://github.com/commontk/CTK/tree/master/Libs/Widgets/ctkWorkflowWidgetStep.h ctkWorkflowWidgetStep]&lt;br /&gt;
** Method 2: [https://github.com/commontk/CTK/tree/master/Libs/Widgets/Testing/Cpp/ctkExampleWorkflowWidgetStepUsingSignalsAndSlots.h ctkExampleWorkflowWidgetStepUsingSignalsAndSlots.h] and [hhttps://github.com/commontk/CTK/tree/master/Libs/Widgets/Testing/Cpp/ctkExampleWorkflowWidgetStepUsingSignalsAndSlots.cpp ctkExampleWorkflowWidgetStepUsingSignalsAndSlots.cpp]: custom step created by implementing the step&#039;s functionality in a class derived from QObject, and communicating with the workflow using its signal-slot mechanism&lt;br /&gt;
* examples of how to create a workflow:&lt;br /&gt;
** Method 1: [hhttps://github.com/commontk/CTK/tree/master/Libs/Widgets/Testing/Cpp/ctkExampleUseOfWorkflowWidgetUsingDerivedSteps.cpp ctkExampleUseOfWorkflowWidgetUsingDerivedSteps]: builds a simple workflow using custom steps that derive ctkWorkflowWidgetStep&lt;br /&gt;
** Method 2: [https://github.com/commontk/CTK/tree/master/Libs/Widgets/Testing/Cpp/ctkExampleUseOfWorkflowWidgetUsingSignalsAndSlots.cpp ctkExampleUseOfWorkflowWidgetUsingSignalsAndSlots]: builds a simple workflow using custom steps that communicate with the workflow using its signal-slot mechanism&lt;br /&gt;
&lt;br /&gt;
== Overview of state diagram underlying ctkWorkflow ==&lt;br /&gt;
* Processing step = handles user interaction, and supports additional processing (ex. image processing) as well&lt;br /&gt;
* Validation step = evaluates the success of the processing step&lt;br /&gt;
* Currently supported transitions:&lt;br /&gt;
** Transition to the next step&lt;br /&gt;
** Transition to the previous step&lt;br /&gt;
** Transition to a &amp;quot;finish&amp;quot; step&lt;br /&gt;
*** Equivalent to doing &amp;quot;next, next, next, next...&amp;quot; until you hit the finish step: completes all entry/exit processing associated with each step encountered on the way to the finish step, without showing user interface.&lt;br /&gt;
*** Success relies on the suitability of the default processing, parameters, etc&lt;br /&gt;
*** &amp;quot;Blocking&amp;quot; steps, ex. those requiring user interaction, will prohibit success in transitioning to the finish step&lt;br /&gt;
*** On success: transitions back to the step where the attempt to go to the finish step was initiated, so that the user can perform additional customization from there if needed.&lt;br /&gt;
*** On failure: remains in the step whose validate() returned failure, and shows its user interface.&lt;br /&gt;
&lt;br /&gt;
== GUI implementation in ctkWorkflowWidget ==&lt;br /&gt;
* workflowWidget-&amp;gt;addWidget(QWidget* widget): adds a widget to the clientArea&lt;br /&gt;
* workflowWidget-&amp;gt;showWidget(QWidget* widget): shows the clientArea (i.e. for ctkWorkflowStackedWidget and ctkWorkflowTabWidget, ensures that the correct &amp;quot;page&amp;quot; is shownl&lt;br /&gt;
&lt;br /&gt;
== Examples ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ctkworkflow w;&lt;br /&gt;
ctkWorkflowStep s1(&amp;quot;select_image&amp;quot;);&lt;br /&gt;
ctkWorkflowStep s2(&amp;quot;input_new_size&amp;quot;);&lt;br /&gt;
ctkWorkflowStep s3(&amp;quot;display_resized_image&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
w.addTransition(&amp;amp;s1, &amp;amp;s2);&lt;br /&gt;
w.addTransition(&amp;amp;s2, &amp;amp;s3);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Workflow layout =&lt;br /&gt;
[[File:Projects-ARRA-SlicerEM-Developer-EMSegment_workflowWidgetLayout.png]]&lt;br /&gt;
&lt;br /&gt;
= Branching workflows = &lt;br /&gt;
&lt;br /&gt;
API:&lt;br /&gt;
&lt;br /&gt;
* addTransition(ctkWorkflowStep* originStep, ctkWorkflowStep* destinationStep, const ctkWorkflow::TransitionType&amp;amp; transitionType, const QString&amp;amp; branchId = &amp;quot;&amp;quot;)&lt;br /&gt;
** must give a branchId if destinationStep is the 2nd/3rd/4th, etc step added to originStep&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
                s3----s4    &amp;quot;simple&amp;quot;&lt;br /&gt;
               /&lt;br /&gt;
  s0----s1----s2&lt;br /&gt;
               \&lt;br /&gt;
                s5----s6    &amp;quot;advanced&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Associated code:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ctkWorkflow w;&lt;br /&gt;
&lt;br /&gt;
ctkWorkflowStep s0;&lt;br /&gt;
...&lt;br /&gt;
ctkWorkflowStep s6;&lt;br /&gt;
&lt;br /&gt;
w.setInitialStep(s0); [Ideally - should be optional]&lt;br /&gt;
&lt;br /&gt;
w.addTransition(s0, s1);&lt;br /&gt;
w.addTransition(s1, s2);&lt;br /&gt;
w.addTransition(s2, s3, ctkWorkflow::BiDirectionnal, &amp;quot;simple&amp;quot;);&lt;br /&gt;
w.addTransition(s3, s4);&lt;br /&gt;
w.addTransition(s2, s5, ctkWorkflow::BiDirectionnal, &amp;quot;advanced&amp;quot;);&lt;br /&gt;
w.addTransition(s5, s6);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Conditional branching:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[signal] void validationComplete(bool isValid, const QString&amp;amp; branchId)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;ctkWorkflow::validate() doesn&#039;t give branchId:&#039;&#039;&#039;&lt;br /&gt;
** Single transition:&lt;br /&gt;
*** transition created without branchId: post transition&lt;br /&gt;
*** transition created with branchId: post transition&lt;br /&gt;
&lt;br /&gt;
** Multiple transitions:&lt;br /&gt;
*** &#039;&#039;(incorrect usage)&#039;&#039; transitions created with branchIds: use first transition that was added&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;ctkWorkflow::validate() gives branchId:&#039;&#039;&#039;&lt;br /&gt;
** Single transition:&lt;br /&gt;
*** transition created without branchId: post transition &#039;&#039;(workflow overrides step)&#039;&#039;&lt;br /&gt;
*** transition created with branchId: conditional transition based on match, if no match then stay in current step&lt;br /&gt;
** Multiple transitions:&lt;br /&gt;
*** transitions created with branchIds: conditional transition based on match, if no match then stay in current step&lt;/div&gt;</summary>
		<author><name>Danielle.pace</name></author>
	</entry>
	<entry>
		<id>https://www.commontk.org/index.php?title=Documentation&amp;diff=497</id>
		<title>Documentation</title>
		<link rel="alternate" type="text/html" href="https://www.commontk.org/index.php?title=Documentation&amp;diff=497"/>
		<updated>2011-01-13T16:48:37Z</updated>

		<summary type="html">&lt;p&gt;Danielle.pace: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Main Page|Back to CTK main page]]&lt;br /&gt;
&lt;br /&gt;
=== Architectural Notes ===&lt;br /&gt;
&lt;br /&gt;
Everything is open to discussion at this time.   &lt;br /&gt;
&lt;br /&gt;
Topics being discussed include the following&lt;br /&gt;
* [[Documentation/Whitepaper|Whitepaper]]&lt;br /&gt;
* [[Documentation/Architecture|Architecture ideas]]&lt;br /&gt;
* [[Documentation/ctkScene|ctkScene ideas]]&lt;br /&gt;
* [[Documentation/Events|Inter- and Intra-process events]]&lt;br /&gt;
* [[Documentation/Plugins_And_Modules|Plugins and Modules: pass data, parameters, and results]]&lt;br /&gt;
* [[Documentation/Interfacing_Via_OpenGL|Interfacing systems at the OpenGL level (i.e. VTK and OpenInventor)]]&lt;br /&gt;
* [[Documentation/Messaging | Messaging service for event management and system integration]]&lt;br /&gt;
* [[Documentation/DicomApplicationHosting | DICOM Suppl 118 / WG 23 compliant application hosting]]&lt;br /&gt;
&lt;br /&gt;
=== Widgets ===&lt;br /&gt;
* [[Documentation/WidgetPlans|Plans for widgets]]&lt;br /&gt;
* [[Documentation/ImageGallery|Image Gallery]]&lt;br /&gt;
* [[Documentation/ctkTransferFunctionWidget|Transfer function widgets]]&lt;br /&gt;
* [[Documentation/ctkWorkflowWidget|Workflow widgets]]&lt;br /&gt;
&lt;br /&gt;
=== Plugin Framework ===&lt;br /&gt;
&lt;br /&gt;
* [[Documentation/PluginFramework_DesignDoc | Design Document]]&lt;br /&gt;
* [[Documentation/PluginFramework_Specifications | Specifications]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Build System ===&lt;br /&gt;
* [[Documentation/BuildSystem_Description | Description]]&lt;/div&gt;</summary>
		<author><name>Danielle.pace</name></author>
	</entry>
</feed>