Forráskód Böngészése

Merge remote branch 'finetjul/Module'

* finetjul/Module:
  Fix compilation issues with GCC
  Add Slicer Command line module XML Schema
  Parse Slicer Command line module descriptions
  Cleanup ModuleDescription
  STYLE: cleanup code to follow CTK style and extensively use Qt functions
  Added module description execution interface
  ENH: Added StringConverter plugin to create the command line taking as input a ModuleDescription
  ENH: Added a converter interface for Automated GUI generation
  ENH: Use const to pass and retrieve parameters
  ENH: Added reader interface and slicermodule plugin to implement the XML Slicer reader
  ENH: Use foreach instead of for(...)
  ENH: Added ModuleDescription and a test

Conflicts:
	CMakeLists.txt
Julien Finet 14 éve
szülő
commit
93d5c57220
38 módosított fájl, 2936 hozzáadás és 0 törlés
  1. 2 0
      CMakeLists.txt
  2. 72 0
      Libs/ModuleDescription/CMakeLists.txt
  3. 0 0
      Libs/ModuleDescription/README
  4. 1 0
      Libs/ModuleDescription/Testing/CMakeLists.txt
  5. 27 0
      Libs/ModuleDescription/Testing/Cpp/CMakeLists.txt
  6. 92 0
      Libs/ModuleDescription/Testing/Cpp/ctkModuleDescriptionTest.cpp
  7. 191 0
      Libs/ModuleDescription/ctkModuleDescription.cpp
  8. 99 0
      Libs/ModuleDescription/ctkModuleDescription.h
  9. 38 0
      Libs/ModuleDescription/ctkModuleDescriptionConverter.cpp
  10. 50 0
      Libs/ModuleDescription/ctkModuleDescriptionConverter.h
  11. 54 0
      Libs/ModuleDescription/ctkModuleDescriptionConverterInterface.h
  12. 38 0
      Libs/ModuleDescription/ctkModuleDescriptionExecution.cpp
  13. 50 0
      Libs/ModuleDescription/ctkModuleDescriptionExecution.h
  14. 49 0
      Libs/ModuleDescription/ctkModuleDescriptionExecutionInterface.h
  15. 39 0
      Libs/ModuleDescription/ctkModuleDescriptionReader.cpp
  16. 50 0
      Libs/ModuleDescription/ctkModuleDescriptionReader.h
  17. 28 0
      Libs/ModuleDescription/ctkModuleDescriptionReaderInterface.cpp
  18. 51 0
      Libs/ModuleDescription/ctkModuleDescriptionReaderInterface.h
  19. 92 0
      Libs/ModuleDescription/ctkModuleParameter.cpp
  20. 55 0
      Libs/ModuleDescription/ctkModuleParameter.h
  21. 110 0
      Libs/ModuleDescription/ctkModuleParameterGroup.cpp
  22. 55 0
      Libs/ModuleDescription/ctkModuleParameterGroup.h
  23. 9 0
      Libs/ModuleDescription/target_libraries.cmake
  24. 57 0
      Plugins/org.commontk.slicermodule/CMakeLists.txt
  25. 144 0
      Plugins/org.commontk.slicermodule/Resources/Xml/slicerModuleDescription.xsd
  26. 5 0
      Plugins/org.commontk.slicermodule/Resources/org_commontk_slicermodule.qrc
  27. 1 0
      Plugins/org.commontk.slicermodule/Testing/CMakeLists.txt
  28. 29 0
      Plugins/org.commontk.slicermodule/Testing/Cpp/CMakeLists.txt
  29. 110 0
      Plugins/org.commontk.slicermodule/Testing/Cpp/TestData/ParserTest1.xml
  30. 110 0
      Plugins/org.commontk.slicermodule/Testing/Cpp/TestData/ParserTest2.xml
  31. 146 0
      Plugins/org.commontk.slicermodule/Testing/Cpp/ctkSlicerModuleTest.cpp
  32. 79 0
      Plugins/org.commontk.slicermodule/ctkSlicerModulePlugin.cpp
  33. 59 0
      Plugins/org.commontk.slicermodule/ctkSlicerModulePlugin_p.h
  34. 617 0
      Plugins/org.commontk.slicermodule/ctkSlicerModuleReader.cpp
  35. 94 0
      Plugins/org.commontk.slicermodule/ctkSlicerModuleReader.h
  36. 158 0
      Plugins/org.commontk.slicermodule/ctkSlicerModuleStringConverter.cpp
  37. 65 0
      Plugins/org.commontk.slicermodule/ctkSlicerModuleStringConverter.h
  38. 10 0
      Plugins/org.commontk.slicermodule/target_libraries.cmake

+ 2 - 0
CMakeLists.txt

@@ -305,6 +305,7 @@ SET(CTK_LIBS
   DICOM/Widgets:OFF
   ImageProcessing/ITK/Core:OFF
   #Messaging/Core:OFF  # MessagingCore library need some love :) - Let's disable it for now :(
+  ModuleDescription:OFF
   Scripting/Python/Core:OFF
   Scripting/Python/Widgets:OFF
   Visualization/VTK/Core:OFF
@@ -331,6 +332,7 @@ SET(CTK_PLUGINS
   org.commontk.plugingenerator.core:OFF
   org.commontk.plugingenerator.ui:OFF
   org.commontk.qtmobility.service:OFF
+  org.commontk.slicermodule:OFF
   )
 
 #-----------------------------------------------------------------------------

+ 72 - 0
Libs/ModuleDescription/CMakeLists.txt

@@ -0,0 +1,72 @@
+PROJECT(CTKModuleDescription)
+
+#
+# 3rd party dependencies
+#
+
+#
+# See CTK/CMake/ctkMacroBuildLib.cmake for details
+#
+
+SET(KIT_export_directive "CTK_MODULDESC_EXPORT")
+
+# Additional directories to include
+  
+# Source files
+SET(KIT_SRCS
+  ctkModuleDescription.h
+  ctkModuleDescription.cpp
+  ctkModuleParameter.h
+  ctkModuleParameter.cpp
+  ctkModuleParameterGroup.h
+  ctkModuleParameterGroup.cpp
+  ctkModuleDescriptionReaderInterface.cpp
+  ctkModuleDescriptionReaderInterface.h
+  ctkModuleDescriptionReader.h
+  ctkModuleDescriptionReader.cpp
+  ctkModuleDescriptionConverterInterface.h
+  ctkModuleDescriptionConverter.h
+  ctkModuleDescriptionConverter.cpp
+  ctkModuleDescriptionExecutionInterface.h
+  ctkModuleDescriptionExecution.h
+  ctkModuleDescriptionExecution.cpp
+  )
+
+# Headers that should run through moc
+SET(KIT_MOC_SRCS
+  ctkModuleDescriptionReaderInterface.h
+  ctkModuleDescriptionReader.h
+  ctkModuleDescriptionConverterInterface.h
+  ctkModuleDescriptionConverter.h
+  ctkModuleDescriptionExecutionInterface.h
+  ctkModuleDescriptionExecution.h
+)
+
+# UI files
+SET(KIT_UI_FORMS
+)
+
+# Resources
+SET(KIT_resources
+)
+
+# Target libraries - See CMake/ctkMacroGetTargetLibraries.cmake
+# The following macro will read the target libraries from the file 'target_libraries.cmake'
+ctkMacroGetTargetLibraries(KIT_target_libraries)
+
+ctkMacroBuildLib(
+  NAME ${PROJECT_NAME}
+  EXPORT_DIRECTIVE ${KIT_export_directive}
+  INCLUDE_DIRECTORIES ${KIT_include_directories}
+  SRCS ${KIT_SRCS}
+  MOC_SRCS ${KIT_MOC_SRCS}
+  UI_FORMS ${KIT_UI_FORMS}
+  TARGET_LIBRARIES ${KIT_target_libraries}
+  RESOURCES ${KIT_resources}
+  LIBRARY_TYPE ${CTK_LIBRARY_MODE}
+  )
+
+# Testing
+IF(BUILD_TESTING)
+  ADD_SUBDIRECTORY(Testing)
+ENDIF(BUILD_TESTING)

+ 0 - 0
Libs/ModuleDescription/README


+ 1 - 0
Libs/ModuleDescription/Testing/CMakeLists.txt

@@ -0,0 +1 @@
+ADD_SUBDIRECTORY(Cpp)

+ 27 - 0
Libs/ModuleDescription/Testing/Cpp/CMakeLists.txt

@@ -0,0 +1,27 @@
+SET(KIT ${PROJECT_NAME})
+
+CREATE_TEST_SOURCELIST(Tests ${KIT}CppTests.cpp
+  ctkModuleDescriptionTest.cpp
+  )
+
+SET (TestsToRun ${Tests})
+REMOVE (TestsToRun ${KIT}CppTests.cpp)
+
+SET(LIBRARY_NAME ${PROJECT_NAME})
+
+ADD_EXECUTABLE(${KIT}CppTests ${Tests})
+TARGET_LINK_LIBRARIES(${KIT}CppTests ${LIBRARY_NAME} ${CTK_BASE_LIBRARIES})
+
+SET( KIT_TESTS ${CPP_TEST_PATH}/${KIT}CppTests)
+
+MACRO( SIMPLE_TEST  TESTNAME )
+  ADD_TEST( ${TESTNAME} ${KIT_TESTS} ${TESTNAME} )
+  SET_PROPERTY(TEST ${TESTNAME} PROPERTY LABELS ${PROJECT_NAME})
+ENDMACRO( SIMPLE_TEST  )
+
+#
+# Add Tests
+#
+
+SIMPLE_TEST( ctkModuleDescriptionTest.cpp )
+

+ 92 - 0
Libs/ModuleDescription/Testing/Cpp/ctkModuleDescriptionTest.cpp

@@ -0,0 +1,92 @@
+/*=========================================================================
+
+  Library:   CTK
+ 
+  Copyright (c) 2010  Kitware Inc.
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+      http://www.commontk.org/LICENSE
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+ 
+=========================================================================*/
+
+// Qt includes
+#include <QTextStream>
+
+// CTK includes
+#include "ctkModuleDescription.h"
+#include <iostream>
+
+//-----------------------------------------------------------------------------
+int ctkModuleDescriptionTest(int argc, char * argv [] )
+{
+  Q_UNUSED(argc);
+  Q_UNUSED(argv);  
+
+
+  ctkModuleParameter param;
+  param[ "Tag" ] = "MyTag";
+  param[ "Name" ] = "MyName";
+  param[ "Description" ] = "MyDescription";
+  param[ "Label" ] = "MyLabel";
+  param[ "CPPType" ] = "MyCPPType";
+  param[ "Type" ] = "MyType";
+  param[ "Reference" ] = "MyReference";
+  param[ "Hidden" ] = "false";
+  param[ "ArgType" ] = "MyArgType";
+  param[ "StringToType" ] = "MyStringToType";
+  param[ "Default" ] = "MyDefault";
+  param[ "Flag" ] = "MyFlag";
+  param[ "LongFlag" ] = "MyLongFlag";
+  param[ "Constraints" ] = "MyConstraints";
+  param[ "Minimum" ] = "MyMinimum";
+  param[ "Maximum" ] = "MyMaximum";
+  param[ "Channel" ] = "MyChannel";
+  param[ "Index" ] = "MyIndex";
+  param[ "Multiple" ] = "false";
+  param[ "Aggregate" ] = "false";
+  param[ "FileExtensions" ] = ".vtk,.jpg";
+  param[ "FlagAliases" ] = "MyFlagAliases";
+  param[ "DeprecatedFlagAliases" ] = "MyDeprecatedFlagAliases";
+  param[ "LongFlagAliases" ] = "MyLongFlagAliases";
+  param[ "DeprecatedLongFlagAliases" ] = "MyDeprecatedLongFlagAliases";
+  param[ "CoordinateSystem" ] = "MyCoordinateSystem";
+
+
+  ctkModuleParameterGroup group;
+  group[ "Label" ] = "MyLabel";
+  group[ "Description" ] = "MyDescription";
+  group[ "Advanced" ] = "MyAdvanced";
+
+
+  ctkModuleDescription module;
+  module[ "Category" ] = "MyCategory";
+  module[ "Index" ] = "MyIndex";
+  module[ "Title" ] = "MyTitle";
+  module[ "Description" ] = "MyDescription";
+  module[ "DocumentationURL" ] = "MyDocumentationURL";
+  module[ "License" ] = "MyLicense";
+  module[ "Acknowledgements" ] = "MyAcknowledgements";
+  module[ "Contributor" ] = "MyContributor";
+  module[ "Type" ] = "MyType";
+  module[ "AlternativeType" ] = "MyAlternativeType";
+  module[ "Target" ] = "MyTarget";
+  module[ "AlternativeTarget" ] = "MyAlternativeTarget";
+  module[ "Location" ] = "MyLocation";
+
+  group.addParameter( new ctkModuleParameter(param) );
+  module.addParameterGroup( new ctkModuleParameterGroup(group) );
+
+  QTextStream stream(stdout);
+  stream<< module;
+
+  return EXIT_SUCCESS;
+}

+ 191 - 0
Libs/ModuleDescription/ctkModuleDescription.cpp

@@ -0,0 +1,191 @@
+/*=============================================================================
+
+Library: CTK
+
+Copyright (c) 2010 Brigham and Women's Hospital (BWH) All Rights Reserved.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+=============================================================================*/
+
+#include "ctkModuleDescription.h"
+#include <iostream>
+#include "QFile"
+#include "QTextStream"
+
+//----------------------------------------------------------------------------
+void ctkModuleDescription::addParameterGroup( ctkModuleParameterGroup* group )
+{
+  Q_ASSERT(group);
+	this->ParameterGroups.push_back(group);
+}
+
+//----------------------------------------------------------------------------
+const QVector<ctkModuleParameterGroup*>& ctkModuleDescription::parameterGroups() const
+{
+	return this->ParameterGroups;
+}
+
+//----------------------------------------------------------------------------
+bool ctkModuleDescription::hasReturnParameters() const
+{
+  // iterate over each parameter group
+  foreach( const ctkModuleParameterGroup* group, this->ParameterGroups)
+    {
+    if (group->hasReturnParameters())
+      {
+      return true;
+      }
+    }
+
+  return false;
+}
+
+//----------------------------------------------------------------------------
+bool ctkModuleDescription::setParameterDefaultValue(const QString& name, const QString& value)
+{
+  ctkModuleParameter* param = this->parameter( name );
+  if ( param )
+    {
+    (*param)[ "Default" ] = value;
+    return true;
+    }
+
+  return false;
+}
+
+//----------------------------------------------------------------------------
+ctkModuleParameterGroup* ctkModuleDescription::parameterGroup(const QString& parameterName)const
+{
+  // iterate over each parameter group
+  foreach( ctkModuleParameterGroup* group, this->ParameterGroups)
+    {
+    ctkModuleParameter* param = group->parameter(parameterName);
+    if (param)
+      {
+      return group;
+      }    
+    }
+  return 0;
+}
+
+//----------------------------------------------------------------------------
+ctkModuleParameter* ctkModuleDescription::parameter(const QString& name)const
+{
+  // iterate over each parameter group
+  foreach( const ctkModuleParameterGroup* group, this->ParameterGroups)
+    {
+    ctkModuleParameter* param = group->parameter(name);
+    if (param)
+      {
+      return param;
+      }    
+    }
+  return 0;
+}
+
+//----------------------------------------------------------------------------
+void ctkModuleDescription ::setIcon(const QIcon& logo)
+{
+  this->Icon = logo;
+}
+
+//----------------------------------------------------------------------------
+const QIcon& ctkModuleDescription::icon() const
+{
+  return this->Icon;
+}
+
+//----------------------------------------------------------------------------
+bool ctkModuleDescription ::readParameterFile(const QString& filename)
+{
+  bool modified = false;
+
+  QFile file(filename);
+  if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
+    {
+    std::cout << "Parameter file " << filename.toStdString( ) << " could not be opened." << endl;
+    return false;
+    }
+
+  QTextStream in(&file);
+  while (!in.atEnd())
+    {
+    QString line = in.readLine();
+
+    // split the line into key: value
+    QString key, value;
+
+    line = line.trimmed();
+    QStringList list = line.split( "=" );
+    key = list[ 0 ].trimmed();
+    if ( list.size() == 1 )
+      {
+      continue;
+      }
+    value = list[ 1 ].trimmed();
+
+    
+    // std::cout << "key=" << key << ", value=" << value << "!" << endl;
+
+    ctkModuleParameter *param = this->parameter( key );
+    if ( param )
+      {
+      if (value != (*param)["Default"] )
+        {
+        (*param)["Default"] = value;
+        modified = true;
+
+        // multiple="true" may have to be handled differently
+        }
+      }
+    }
+
+  return modified;
+}
+
+//----------------------------------------------------------------------------
+bool ctkModuleDescription::
+writeParameterFile(const QString& filename, bool withHandlesToBulkParameters)const
+{
+  QFile rtp(filename);
+
+  if (!rtp.open(QIODevice::WriteOnly | QIODevice::Text))
+    {
+    std::cout << "Parameter file " << filename.toStdString() << " could not be opened for writing." << endl;
+    return false;
+    }
+
+  QTextStream in(&rtp);
+  // iterate over each parameter group
+  foreach(const ctkModuleParameterGroup* group, this->ParameterGroups)
+    {
+    group->writeParameterFile(in, withHandlesToBulkParameters);
+    }
+
+  return true;
+}
+
+//----------------------------------------------------------------------------
+QTextStream & operator<<(QTextStream &os, const ctkModuleDescription &module)
+{
+  os << QHash<QString, QString>(module);
+  os << "Icon: " << !module.icon().isNull() << endl;
+
+  os << "ParameterGroups: " << endl;
+  foreach(const ctkModuleParameterGroup* group, module.ParameterGroups)
+    {
+    os << *group;
+    }
+  return os;
+}

+ 99 - 0
Libs/ModuleDescription/ctkModuleDescription.h

@@ -0,0 +1,99 @@
+/*=============================================================================
+
+  Library: CTK
+
+  Copyright (c) 2010 Brigham and Women's Hospital (BWH) All Rights Reserved.
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+
+=============================================================================*/
+
+#ifndef __ctkModuleDescription_h
+#define __ctkModuleDescription_h
+
+// Qt includes
+#include <QHash>
+#include <QIcon>
+#include <QVector>
+
+// Module parameter
+#include "ctkModuleParameterGroup.h"
+
+/**
+* Description of the parameters of a module
+*
+* The parameters can be used for automated GUI generation or execution
+* of the module.
+*
+* For example:
+* - Target: This is the entry point for a shared object module and the full 
+* command (with path) for an executable.
+* - Type: Unknown, SharedObjectModule, CommandLineModule
+* - AlternativeTarget: This is the entry
+* point for a shared object module and the full command (with path)
+* for an executable. The alternative target is used for a second version
+* of a module (whose type differs from the primary target,
+* executable verses shared object).
+* - Location: This is path to the file (shared
+* object or executable) for the module
+* - AlternativeLocation: This is path to the
+* file (shared object or executable) for a second version of the
+* module (usually a different type from the primary).
+*/
+class CTK_MODULDESC_EXPORT ctkModuleDescription : public QHash<QString, QString>
+{
+public:
+  // Optional icon associated to the module
+  void setIcon(const QIcon& logo);
+  const QIcon& icon() const;
+  
+  void addParameterGroup(ctkModuleParameterGroup* group);
+
+  const QVector<ctkModuleParameterGroup*>& parameterGroups() const;
+  
+  // Return the group that contain the parameter associated to the name
+  ctkModuleParameterGroup* parameterGroup(const QString& parameterName) const;
+  // Return the first parameter corresponding to the name from any group
+  ctkModuleParameter* parameter(const QString& parameterName) const;
+  
+  // Does the module have any simple (primitive) return types?
+  bool hasReturnParameters() const;
+
+  /// TODO: move to ctkModuleParameter
+  bool setParameterDefaultValue(const QString& parameterName,
+                                const QString& value);
+
+  ///
+  /// Read a parameter file. Syntax of file is "name: value" for each
+  /// parameter. Returns a bool indicating whether any parameter value
+  /// was modified.
+  bool readParameterFile(const QString& filename);
+
+  ///
+  /// Write a parameter file. By default, the method writes out all
+  /// the parameters.  The "withHandlesToBulkParameters" parameter
+  /// controls whether the handles to the bulk parameters (image,
+  /// geometry, etc.) are written to the file.
+  bool writeParameterFile(const QString& filename, bool withHandlesToBulkParameters = true)const;
+
+private:
+  friend CTK_MODULDESC_EXPORT QTextStream & operator<<(QTextStream &os, const ctkModuleDescription &module);
+  /// Groups of parameters
+  QVector<ctkModuleParameterGroup*> ParameterGroups;
+  /// Icon of the module
+  QIcon Icon;
+};
+
+CTK_MODULDESC_EXPORT QTextStream & operator<<(QTextStream &os, const ctkModuleDescription &module);
+
+#endif

+ 38 - 0
Libs/ModuleDescription/ctkModuleDescriptionConverter.cpp

@@ -0,0 +1,38 @@
+/*=============================================================================
+
+Library: CTK
+
+Copyright (c) 2010 CISTIB - Universitat Pompeu Fabra
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+=============================================================================*/
+
+
+#include "ctkModuleDescriptionConverter.h"
+
+ctkModuleDescriptionConverter::ctkModuleDescriptionConverter() 
+{
+
+}
+
+ctkModuleDescriptionConverter::~ctkModuleDescriptionConverter()
+{
+
+}
+
+void ctkModuleDescriptionConverter::setModuleDescription( const ctkModuleDescription &val )
+{
+  this->ModuleDescription = val;
+}
+

+ 50 - 0
Libs/ModuleDescription/ctkModuleDescriptionConverter.h

@@ -0,0 +1,50 @@
+/*=============================================================================
+
+Library: CTK
+
+Copyright (c) 2010 CISTIB - Universitat Pompeu Fabra
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+=============================================================================*/
+
+#ifndef __ctkModuleDescriptionConverter_h
+#define __ctkModuleDescriptionConverter_h
+
+#include <QString>
+
+#include "CTKModuleDescriptionExport.h"
+#include "ctkModuleDescriptionConverterInterface.h"
+
+/** 
+ * \brief Base Reader of ModuleDescription
+ *
+ * This is the base interface
+ */
+class CTK_MODULDESC_EXPORT ctkModuleDescriptionConverter :
+  virtual public ctkModuleDescriptionConverterInterface
+{
+  Q_OBJECT
+public:
+  ctkModuleDescriptionConverter();
+  ~ctkModuleDescriptionConverter();
+
+  ///
+  virtual void setModuleDescription(const ctkModuleDescription &val);
+
+protected:
+  ///
+  ctkModuleDescription ModuleDescription;
+};
+
+#endif

+ 54 - 0
Libs/ModuleDescription/ctkModuleDescriptionConverterInterface.h

@@ -0,0 +1,54 @@
+/*=============================================================================
+
+Library: CTK
+
+Copyright (c) 2010 CISTIB - Universitat Pompeu Fabra
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+=============================================================================*/
+
+#ifndef __ctkModuleDescriptionConverterInterface_h
+#define __ctkModuleDescriptionConverterInterface_h
+
+#include <QVariant>
+
+#include "CTKModuleDescriptionExport.h"
+#include "ctkModuleDescription.h"
+
+/** 
+ * \brief Interface of ModuleDescription converter
+ *
+ * A converter can be a Automated GUI generator that converts
+ * ctkModuleDescription into a Qt window. A converter can also be
+ * a command line generator that creates a command line string to 
+ * execute an application
+ */
+class CTK_MODULDESC_EXPORT ctkModuleDescriptionConverterInterface : public QObject
+{
+    Q_OBJECT
+public:
+  ctkModuleDescriptionConverterInterface(){};
+  ~ctkModuleDescriptionConverterInterface(){};
+
+  //! Set input Module Description
+  virtual void setModuleDescription(const ctkModuleDescription &val) = 0;
+
+  //!
+  virtual void update( ) = 0;
+
+  //!
+  virtual const QVariant GetOutput( ) = 0;
+};
+
+#endif

+ 38 - 0
Libs/ModuleDescription/ctkModuleDescriptionExecution.cpp

@@ -0,0 +1,38 @@
+/*=============================================================================
+
+Library: CTK
+
+Copyright (c) 2010 CISTIB - Universitat Pompeu Fabra
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+=============================================================================*/
+
+
+#include "ctkModuleDescriptionExecution.h"
+
+ctkModuleDescriptionExecution::ctkModuleDescriptionExecution() 
+{
+
+}
+
+ctkModuleDescriptionExecution::~ctkModuleDescriptionExecution()
+{
+
+}
+
+void ctkModuleDescriptionExecution::setModuleDescription( const ctkModuleDescription &val )
+{
+  this->ModuleDescription = val;
+}
+

+ 50 - 0
Libs/ModuleDescription/ctkModuleDescriptionExecution.h

@@ -0,0 +1,50 @@
+/*=============================================================================
+
+Library: CTK
+
+Copyright (c) 2010 CISTIB - Universitat Pompeu Fabra
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+=============================================================================*/
+
+#ifndef __ctkModuleDescriptionExecution_h
+#define __ctkModuleDescriptionExecution_h
+
+#include <QString>
+
+#include "CTKModuleDescriptionExport.h"
+#include "ctkModuleDescriptionExecutionInterface.h"
+
+/** 
+ * \brief Base Reader of ModuleDescription
+ *
+ * This is the base interface
+ */
+class CTK_MODULDESC_EXPORT ctkModuleDescriptionExecution :
+  virtual public ctkModuleDescriptionExecutionInterface
+{
+  Q_OBJECT
+public:
+  ctkModuleDescriptionExecution();
+  ~ctkModuleDescriptionExecution();
+
+  ///
+  virtual void setModuleDescription(const ctkModuleDescription &val);
+
+protected:
+  ///
+  ctkModuleDescription ModuleDescription;
+};
+
+#endif

+ 49 - 0
Libs/ModuleDescription/ctkModuleDescriptionExecutionInterface.h

@@ -0,0 +1,49 @@
+/*=============================================================================
+
+Library: CTK
+
+Copyright (c) 2010 CISTIB - Universitat Pompeu Fabra
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+=============================================================================*/
+
+#ifndef __ctkModuleDescriptionExecutionInterface_h
+#define __ctkModuleDescriptionExecutionInterface_h
+
+#include <QVariant>
+
+#include "CTKModuleDescriptionExport.h"
+#include "ctkModuleDescription.h"
+
+/** 
+ * \brief Interface of ModuleDescription execution
+ *
+ * This allows to execute a filter using an executable application
+ * or a DLL Command Line Plugin
+ */
+class CTK_MODULDESC_EXPORT ctkModuleDescriptionExecutionInterface : public QObject
+{
+    Q_OBJECT
+public:
+  ctkModuleDescriptionExecutionInterface(){};
+  ~ctkModuleDescriptionExecutionInterface(){};
+
+  //! Set input Module Description
+  virtual void setModuleDescription(const ctkModuleDescription &val) = 0;
+
+  //!
+  virtual void Update( ) = 0;
+};
+
+#endif

+ 39 - 0
Libs/ModuleDescription/ctkModuleDescriptionReader.cpp

@@ -0,0 +1,39 @@
+/*=============================================================================
+
+Library: CTK
+
+Copyright (c) 2010 Brigham and Women's Hospital (BWH) All Rights Reserved.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+=============================================================================*/
+
+#include "ctkModuleDescriptionReader.h"
+
+//----------------------------------------------------------------------------
+ctkModuleDescriptionReader::ctkModuleDescriptionReader() 
+{
+  this->Device = 0;
+}
+
+//-----------------------------------------------------------------------------
+void ctkModuleDescriptionReader::setInput(QIODevice * device)
+{
+  this->Device = device;
+}
+
+//-----------------------------------------------------------------------------
+QIODevice* ctkModuleDescriptionReader::input()const
+{
+  return this->Device;
+}

+ 50 - 0
Libs/ModuleDescription/ctkModuleDescriptionReader.h

@@ -0,0 +1,50 @@
+/*=============================================================================
+
+Library: CTK
+
+Copyright (c) 2010 Brigham and Women's Hospital (BWH) All Rights Reserved.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+=============================================================================*/
+
+#ifndef __ctkModuleDescriptionReader_h
+#define __ctkModuleDescriptionReader_h
+
+#include "CTKModuleDescriptionExport.h"
+#include "ctkModuleDescriptionReaderInterface.h"
+
+class QIODevice;
+/** 
+ * \brief Base XML Reader of ModuleDescription
+ *
+ * This specialized ctkModuleDescriptionReaderInterface can initialize
+ * a module description from an XML file. update() must be reimplemented
+ * in inherited classes.
+ */
+class CTK_MODULDESC_EXPORT ctkModuleDescriptionReader :
+  public ctkModuleDescriptionReaderInterface
+{
+  Q_OBJECT
+public:
+  ctkModuleDescriptionReader();
+
+  //! xml is the content of the XML file
+  void setInput(QIODevice * device);
+  QIODevice* input()const;
+
+protected:
+  QIODevice*           Device;
+};
+
+#endif

+ 28 - 0
Libs/ModuleDescription/ctkModuleDescriptionReaderInterface.cpp

@@ -0,0 +1,28 @@
+/*=============================================================================
+
+Library: CTK
+
+Copyright (c) 2010 Brigham and Women's Hospital (BWH) All Rights Reserved.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+=============================================================================*/
+
+// CTK includes
+#include "ctkModuleDescriptionReaderInterface.h"
+
+//-----------------------------------------------------------------------------
+const ctkModuleDescription& ctkModuleDescriptionReaderInterface::moduleDescription()const
+{
+  return this->ModuleDescription;
+}

+ 51 - 0
Libs/ModuleDescription/ctkModuleDescriptionReaderInterface.h

@@ -0,0 +1,51 @@
+/*=============================================================================
+
+Library: CTK
+
+Copyright (c) 2010 Brigham and Women's Hospital (BWH) All Rights Reserved.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+=============================================================================*/
+
+#ifndef __ctkModuleDescriptionReaderInterface_h
+#define __ctkModuleDescriptionReaderInterface_h
+
+// Qt includes
+#include <QObject>
+#include <QString>
+
+// CTK includes
+#include "ctkModuleDescription.h"
+#include "CTKModuleDescriptionExport.h"
+
+/** 
+ * \brief Interface of ModuleDescription reader
+ */
+class CTK_MODULDESC_EXPORT ctkModuleDescriptionReaderInterface : public QObject
+{
+  Q_OBJECT
+public:
+
+  //!
+  virtual void update( ) = 0;
+
+  //! Returns the populated module description.
+  //! Note: the module description is set after update() is called
+  const ctkModuleDescription &moduleDescription() const;
+
+protected:
+  ctkModuleDescription ModuleDescription;
+};
+
+#endif

+ 92 - 0
Libs/ModuleDescription/ctkModuleParameter.cpp

@@ -0,0 +1,92 @@
+/*=============================================================================
+
+Library: CTK
+
+Copyright (c) 2010 Brigham and Women's Hospital (BWH) All Rights Reserved.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+=============================================================================*/
+
+#include "ctkModuleParameter.h"
+#include "QStringList"
+
+//----------------------------------------------------------------------------
+bool ctkModuleParameter::isReturnParameter() const
+{
+  // could check for tag == float, int, float-vector, ...
+  return (*this)["Channel"] == "output" 
+         && !this->isFlagParameter()
+         && !this->isIndexParameter();
+}
+
+//----------------------------------------------------------------------------
+bool ctkModuleParameter::isFlagParameter() const
+{
+  return ((*this)["Flag"] != "" || (*this)[ "LongFlag" ] != "");
+}
+
+//----------------------------------------------------------------------------
+bool ctkModuleParameter::isIndexParameter() const
+{
+  return ((*this)[ "Index" ] != "");
+}
+
+//-----------------------------------------------------------------------------
+QTextStream & operator<<(QTextStream &os, const ctkModuleParameter &parameter)
+{ 
+  os << "    Parameter" << endl;
+  os << "      ";
+  os.setFieldWidth(7);
+  os.setFieldAlignment(QTextStream::AlignLeft);
+  os << QHash<QString, QString>( parameter );
+  os.setFieldWidth(0);
+
+  os << "Flag aliases: ";
+  os << parameter["FlagAliases"].split( "," );
+
+  os << "      " << "Deprecated Flag aliases: ";
+  os << parameter["DeprecatedFlagAliases"].split( "," );
+
+  os << "      " << "LongFlag aliases: ";
+  os << parameter["LongFlagAliases"].split( "," );
+
+  os << "      " << "Deprecated LongFlag aliases: ";
+  os << parameter["DeprecatedLongFlagAliases"].split( "," );
+
+  os << "      " << "FileExtensions: ";
+  os << parameter["FileExtensions"].split( "," );
+
+  return os;
+}
+
+//----------------------------------------------------------------------------
+QTextStream & operator<<(QTextStream &os, const QStringList &list)
+{
+  os << list.join(", ") << endl;
+  return os;
+}
+
+//----------------------------------------------------------------------------
+QTextStream & operator<<(QTextStream &os, const QHash<QString, QString> &hash)
+{ 
+  QHash<QString,QString>::const_iterator itProp;
+  for ( itProp = hash.begin( ) ; 
+        itProp != hash.end( ) ; 
+        itProp++ )
+    {
+    os << itProp.key( ) << ": " << itProp.value( ) << endl;
+    }
+
+  return os;
+}

+ 55 - 0
Libs/ModuleDescription/ctkModuleParameter.h

@@ -0,0 +1,55 @@
+/*=============================================================================
+
+  Library: CTK
+
+  Copyright (c) 2010 Brigham and Women's Hospital (BWH) All Rights Reserved.
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+
+=============================================================================*/
+
+#ifndef __ctkModuleParameter_h
+#define __ctkModuleParameter_h
+
+#include "CTKModuleDescriptionExport.h"
+#include "QHash"
+#include "QTextStream"
+
+/** 
+ *  \brief Single parameter to a module, like a threshold of a filter.
+ *
+ * ctkModuleParameter describes a single parameters to a
+ * module. Information on the parameter type, name, flag, label,
+ * description, channel, index, default, and constraints can be
+ * stored.
+ *
+ */
+class CTK_MODULDESC_EXPORT ctkModuleParameter : public QHash<QString, QString>
+{
+public:
+  /// Simple return types are parameters on output channel with no
+  /// flags and without a specified index 
+  bool isReturnParameter() const;
+  
+  /// Has a flag or a long flag?
+  bool isFlagParameter() const;
+
+  /// Is an index type?
+  bool isIndexParameter() const;
+};
+
+CTK_MODULDESC_EXPORT QTextStream & operator<<(QTextStream &os, const ctkModuleParameter &parameter);
+CTK_MODULDESC_EXPORT QTextStream & operator<<(QTextStream &os, const QStringList &list);
+CTK_MODULDESC_EXPORT QTextStream & operator<<(QTextStream &os, const QHash<QString, QString> &hash);
+
+#endif

+ 110 - 0
Libs/ModuleDescription/ctkModuleParameterGroup.cpp

@@ -0,0 +1,110 @@
+/*=============================================================================
+
+Library: CTK
+
+Copyright (c) 2010 Brigham and Women's Hospital (BWH) All Rights Reserved.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+=============================================================================*/
+
+#include "ctkModuleParameterGroup.h"
+
+//----------------------------------------------------------------------------
+ctkModuleParameterGroup::~ctkModuleParameterGroup()
+{
+  foreach(ctkModuleParameter* param, this->Parameters)
+    {
+    delete param;
+    }
+  this->Parameters.clear();
+}
+
+//----------------------------------------------------------------------------
+void ctkModuleParameterGroup::addParameter( ctkModuleParameter* parameter )
+{
+  Q_ASSERT(parameter);
+  this->Parameters.push_back(parameter);
+}
+
+//----------------------------------------------------------------------------
+const QVector<ctkModuleParameter*>& ctkModuleParameterGroup::parameters() const
+{
+	return this->Parameters;
+}
+
+//----------------------------------------------------------------------------
+ctkModuleParameter* ctkModuleParameterGroup::parameter( const QString& parameterName )const
+{
+  foreach(ctkModuleParameter* param, this->Parameters)
+    {
+    if ((*param)["Name"] == parameterName)
+      {
+      return param;
+      }
+    }
+  return 0;
+}
+
+//----------------------------------------------------------------------------
+bool ctkModuleParameterGroup::hasReturnParameters() const
+{
+  // iterate over each parameter in this group
+  foreach(const ctkModuleParameter* param, this->Parameters)
+    {
+    if (param->isReturnParameter())
+      {
+      return true;
+      }
+    }
+  return false;
+}
+
+//----------------------------------------------------------------------------
+bool ctkModuleParameterGroup::
+writeParameterFile(QTextStream& in, bool withHandlesToBulkParameters)const
+{
+  // iterate over each parameter in this group
+  foreach(const ctkModuleParameter* moduleParameter, this->Parameters)
+    {
+    const ctkModuleParameter& param = *moduleParameter;
+    // write out all parameters or just the ones that are not bulk parameters
+    if (withHandlesToBulkParameters
+        || (!withHandlesToBulkParameters 
+            && (param[ "Tag" ] != "image"
+            && param[ "Tag" ] != "geometry"
+            && param[ "Tag" ] != "transform"
+            && param[ "Tag" ] != "table"
+            && param[ "Tag" ] != "measurement"
+            && param[ "Tag" ] != "point"  // point and region are special
+            && param[ "Tag" ] != "region")))
+      {
+      in << param[ "Name" ] << " = " << param[ "Default" ] << endl;
+      // multiple="true" may have to be handled differently
+      }
+    }
+  return true;
+}
+
+//----------------------------------------------------------------------------
+QTextStream & operator<<(QTextStream &os, const ctkModuleParameterGroup &group)
+{ 
+  os << QHash<QString, QString>(group);
+
+  os << "  Parameters: " << endl;
+  foreach (const ctkModuleParameter* it, group.Parameters)
+    {
+    os << *it;
+    }
+  return os;
+}

+ 55 - 0
Libs/ModuleDescription/ctkModuleParameterGroup.h

@@ -0,0 +1,55 @@
+/*=============================================================================
+
+  Library: CTK
+
+  Copyright (c) 2010 Brigham and Women's Hospital (BWH) All Rights Reserved.
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+
+=============================================================================*/
+
+#ifndef __ctkModuleParameterGroup_h
+#define __ctkModuleParameterGroup_h
+
+#include "ctkModuleParameter.h"
+#include "QHash"
+#include "QVector"
+
+/** 
+*  \brief Group of parameters
+*
+*/
+class CTK_MODULDESC_EXPORT ctkModuleParameterGroup : public QHash<QString, QString>
+{
+public:
+  virtual ~ctkModuleParameterGroup();
+  
+  /// Takes ownership of parameter
+  void addParameter(ctkModuleParameter* parameter);
+  const QVector<ctkModuleParameter*>& parameters() const;
+
+  /// Returns 0 if not found.
+  ctkModuleParameter* parameter(const QString& parameterName)const;
+  /// Returns true if at least 1 parameter is a return type
+  bool hasReturnParameters()const;
+  bool writeParameterFile(QTextStream& in, bool withHandlesToBulkParameters = true)const;
+  
+private:
+  friend CTK_MODULDESC_EXPORT QTextStream & operator<<(QTextStream &os, const ctkModuleParameterGroup &group);
+  ///
+  QVector<ctkModuleParameter*> Parameters;
+};
+
+CTK_MODULDESC_EXPORT QTextStream & operator<<(QTextStream &os, const ctkModuleParameterGroup &group);
+
+#endif

+ 9 - 0
Libs/ModuleDescription/target_libraries.cmake

@@ -0,0 +1,9 @@
+#
+# See CMake/ctkMacroGetTargetLibraries.cmake
+# 
+# This file should list the libraries required to build the current CTK libraries
+#
+
+SET(target_libraries
+  CTKCore
+  )

+ 57 - 0
Plugins/org.commontk.slicermodule/CMakeLists.txt

@@ -0,0 +1,57 @@
+PROJECT(org_commontk_slicermodule)
+
+SET(PLUGIN_export_directive "org_commontk_slicermodule_EXPORT")
+
+SET(PLUGIN_SRCS
+  ctkSlicerModulePlugin.cpp
+  ctkSlicerModulePlugin_p.h
+  ctkSlicerModuleReader.cpp
+  ctkSlicerModuleReader.h
+  ctkSlicerModuleStringConverter.h
+  ctkSlicerModuleStringConverter.cpp
+)
+
+# Files which should be processed by Qts moc
+SET(PLUGIN_MOC_SRCS
+  ctkSlicerModulePlugin_p.h
+  ctkSlicerModuleReader.h
+  ctkSlicerModuleStringConverter.h
+)
+
+# Qt Designer files which should be processed by Qts uic
+SET(PLUGIN_UI_FORMS
+)
+
+# QRC Files which should be compiled into the plugin
+SET(PLUGIN_resources
+  Resources/org_commontk_slicermodule.qrc
+)
+
+
+# Update CTK_BASE_LIBRARIES with QT libraries
+IF(QT4_FOUND)
+  SET(CTK_BASE_LIBRARIES ${CTK_BASE_LIBRARIES} ${QT_LIBRARIES} CACHE INTERNAL "CTK base libraries" FORCE)
+ENDIF()
+
+#Compute the plugin dependencies
+ctkMacroGetTargetLibraries(PLUGIN_target_libraries)
+
+ctkMacroBuildPlugin(
+  NAME ${PROJECT_NAME}
+  EXPORT_DIRECTIVE ${PLUGIN_export_directive}
+  SRCS ${PLUGIN_SRCS}
+  MOC_SRCS ${PLUGIN_MOC_SRCS}
+  UI_FORMS ${PLUGIN_UI_FORMS}
+  RESOURCES ${PLUGIN_resources}
+  TARGET_LIBRARIES ${PLUGIN_target_libraries}
+)
+
+SET( QT_USE_QTXML ON )
+SET( QT_USE_QTXMLPATTERNS ON )
+INCLUDE(${QT_USE_FILE})
+TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${QT_LIBRARIES})
+
+# Testing
+IF(BUILD_TESTING)
+  ADD_SUBDIRECTORY(Testing)
+ENDIF(BUILD_TESTING)

+ 144 - 0
Plugins/org.commontk.slicermodule/Resources/Xml/slicerModuleDescription.xsd

@@ -0,0 +1,144 @@
+<?xml version="1.0"?>
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
+
+    <xsd:element name="executable">
+        <xsd:complexType>
+            <xsd:sequence>
+                <xsd:element name="category" type="xsd:string"/>
+                <xsd:element name="title" type="xsd:string"/>
+                <xsd:element name="description" type="xsd:string"/>
+                <xsd:element name="version" type="xsd:string"/>
+                <xsd:element name="documentation-url" type="xsd:string"/>
+                <xsd:element name="license" type="xsd:string"/>
+                <xsd:element name="contributor" type="xsd:string"/>
+                <xsd:element name="parameters" type="parameters" maxOccurs="unbounded"/>
+            </xsd:sequence>
+        </xsd:complexType>
+    </xsd:element>
+
+    <xsd:complexType name="parameters">
+      <xsd:choice minOccurs="0" maxOccurs="unbounded">
+        <xsd:element name="label" type="xsd:string"/>
+        <xsd:element name="description" type="xsd:string"/>
+        <xsd:element name="integer" type="scalarType"/>
+        <xsd:element name="integer-vector" type="scalarType"/>
+        <xsd:element name="boolean" type="scalarType"/>
+        <xsd:element name="boolean-vector" type="scalarType"/>
+        <xsd:element name="float" type="scalarType"/>
+        <xsd:element name="float-vector" type="scalarType"/>
+        <xsd:element name="double" type="scalarType"/>
+        <xsd:element name="double-vector" type="scalarType"/>
+        <xsd:element name="string" type="paramType"/>
+        <xsd:element name="string-vector" type="paramType"/>
+        <xsd:element name="point" type="pointType"/>
+        <xsd:element name="point-vector" type="pointType"/>
+        <xsd:element name="region" type="pointType"/>
+        <xsd:element name="region-vector" type="pointType"/>
+        <xsd:element name="string-enumeration" type="enumerationType"/>
+        <xsd:element name="integer-enumeration" type="enumerationType"/>
+        <xsd:element name="float-enumeration" type="enumerationType"/>
+        <xsd:element name="double-enumeration" type="enumerationType"/>
+        <xsd:element name="file" type="indexedParamType"/>
+        <xsd:element name="directory" type="paramType"/>
+        <xsd:element name="transform" type="typedIndexParamType"/>
+        <xsd:element name="image" type="typedIndexParamType"/>
+        <xsd:element name="geometry" type="typedIndexParamType"/>
+        <xsd:element name="table" type="typedIndexParamType"/>
+        <xsd:element name="measurement" type="typedIndexParamType"/>
+      </xsd:choice>
+    </xsd:complexType>
+
+    <xsd:complexType name="paramType">    
+      <xsd:choice minOccurs="0" maxOccurs="unbounded">
+        <xsd:element name="name" type="xsd:string"/>
+        <xsd:element name="flag" type="flagType" />
+        <xsd:element name="longflag" type="flagType"/>
+        <xsd:element name="description" type="xsd:string"/>
+        <xsd:element name="label" type="xsd:string"/>
+        <xsd:element name="default" type="xsd:string"/>
+      </xsd:choice>
+      <xsd:attribute name="multiple" type="xsd:boolean"/>
+      <xsd:attribute name="hidden" type="xsd:boolean"/>
+    </xsd:complexType>
+    
+    <xsd:complexType name="scalarType" >
+      <xsd:complexContent>
+        <xsd:extension base="paramType">
+          <xsd:sequence>
+            <xsd:element name="constraints" type="constraintsType"  minOccurs="0" />
+          </xsd:sequence>
+        </xsd:extension>
+      </xsd:complexContent>
+    </xsd:complexType>
+
+    <xsd:complexType name="pointType" >
+      <xsd:complexContent>
+        <xsd:extension base="paramType">
+          <xsd:attribute name="coordinateSystem">
+            <xsd:simpleType>
+              <xsd:restriction base="xsd:string">
+                <xsd:enumeration value="RAS"/>
+                <xsd:enumeration value="IJK"/>
+              </xsd:restriction>
+            </xsd:simpleType>
+          </xsd:attribute>
+        </xsd:extension>
+      </xsd:complexContent>
+    </xsd:complexType>
+
+    <xsd:complexType name="enumerationType" >
+      <xsd:complexContent>
+        <xsd:extension base="paramType">
+          <xsd:sequence>
+            <xsd:element name="element" type="xsd:string"/>
+          </xsd:sequence>
+        </xsd:extension>
+      </xsd:complexContent>
+    </xsd:complexType>
+
+    <xsd:complexType name="indexedParamType" >
+      <xsd:all>
+        <xsd:element name="name" type="xsd:string"/>
+        <xsd:element name="label" type="xsd:string"/>
+        <xsd:element name="description" type="xsd:string"/>
+        <xsd:element name="channel" maxOccurs="1">
+          <xsd:simpleType>
+            <xsd:restriction base="xsd:string">
+              <xsd:enumeration value="input"/>
+              <xsd:enumeration value="output"/>
+            </xsd:restriction>
+          </xsd:simpleType>
+        </xsd:element>
+        <xsd:element name="index" type="xsd:nonNegativeInteger"/>
+      </xsd:all>
+      <xsd:attribute name="fileExtensions" type="xsd:string"/>
+    </xsd:complexType>
+
+    <xsd:complexType name="typedIndexParamType" >
+      <xsd:complexContent>
+        <xsd:extension base="indexedParamType">
+          <xsd:attribute name="reference" type="xsd:string"/>
+          <xsd:attribute name="type" type="xsd:string"/>
+          <xsd:attribute name="hidden" type="xsd:boolean"/>
+        </xsd:extension>
+      </xsd:complexContent>
+    </xsd:complexType>
+    
+    <xsd:complexType name="flagType">
+      <xsd:simpleContent>
+        <xsd:extension base="xsd:string">
+          <xsd:attribute name="alias" type="xsd:string"/>
+          <xsd:attribute name="deprecatedalias" type="xsd:string"/>
+        </xsd:extension>
+      </xsd:simpleContent>
+    </xsd:complexType>
+    
+    <xsd:complexType name="constraintsType">
+      <xsd:sequence>
+        <xsd:element name="minimum" type="xsd:double"/>
+        <xsd:element name="maximum" type="xsd:double"/>
+        <xsd:element name="step" type="xsd:double"/>
+      </xsd:sequence>
+    </xsd:complexType>
+
+</xsd:schema>

+ 5 - 0
Plugins/org.commontk.slicermodule/Resources/org_commontk_slicermodule.qrc

@@ -0,0 +1,5 @@
+<!DOCTYPE RCC><RCC version="1.0">
+  <qresource>
+    <file alias="slicerModuleDescription.xsd">Xml/slicerModuleDescription.xsd</file>
+  </qresource>
+</RCC>

+ 1 - 0
Plugins/org.commontk.slicermodule/Testing/CMakeLists.txt

@@ -0,0 +1 @@
+ADD_SUBDIRECTORY(Cpp)

+ 29 - 0
Plugins/org.commontk.slicermodule/Testing/Cpp/CMakeLists.txt

@@ -0,0 +1,29 @@
+SET(KIT ${PROJECT_NAME})
+
+CREATE_TEST_SOURCELIST(Tests ${KIT}CppTests.cpp
+  ctkSlicerModuleTest.cpp
+  )
+
+SET (TestsToRun ${Tests})
+REMOVE (TestsToRun ${KIT}CppTests.cpp)
+
+SET(LIBRARY_NAME ${PROJECT_NAME})
+
+ADD_EXECUTABLE(${KIT}CppTests ${Tests})
+TARGET_LINK_LIBRARIES(${KIT}CppTests ${LIBRARY_NAME} ${CTK_BASE_LIBRARIES})
+
+SET( KIT_TESTS ${CPP_TEST_PATH}/${KIT}CppTests)
+
+SET(TEST_DATA ${${PROJECT_NAME}_SOURCE_DIR}/TestData)
+
+MACRO( SIMPLE_TEST  TESTNAME DATA_FILE )
+  ADD_TEST( ${TESTNAME} "${KIT_TESTS}" "${TESTNAME}" "${TEST_DATA}/${DATA_FILE}" )
+  SET_PROPERTY(TEST ${TESTNAME} PROPERTY LABELS ${PROJECT_NAME})
+ENDMACRO( SIMPLE_TEST  )
+
+#
+# Add Tests
+#
+
+SIMPLE_TEST( ctkSlicerModuleTest ParserTest1.xml )
+

+ 110 - 0
Plugins/org.commontk.slicermodule/Testing/Cpp/TestData/ParserTest1.xml

@@ -0,0 +1,110 @@
+<?xml version="1.0" encoding="utf-8"?>
+<executable>
+  <category>registration</category>
+  <title>NAMIC sample registration</title>
+  <description>Registers two images together using a rigid transform and MI</description>
+  <version>1.0</version>
+  <documentation-url></documentation-url>
+  <license></license>
+  <contributor>Daniel Blezek</contributor>
+
+  <parameters>
+    <label>Registration Parameters</label>
+    <description>Parameters used for registration</description>
+    <integer>
+      <name>HistogramBins</name>
+      <flag>-b</flag>
+      <longflag>--histogrambins</longflag>
+      <description>Number of histogram bins to use for Mattes Mutual Information</description>
+      <label>Histogram Bins</label>
+      <default>30</default>
+      <constraints>
+        <minimum>1</minimum>
+        <maximum>500</maximum>
+        <step>5</step>
+      </constraints>
+    </integer>
+
+    <integer>
+      <name>SpatialSamples</name>
+      <flag>-s</flag>
+      <longflag>--spatialsamples</longflag>
+      <description>Number of spatial samples to use in estimating Mattes Mutual Information</description>
+      <label>Spatial Samples</label>
+      <default>10000</default>
+      <constraints>
+        <minimum>1000</minimum>
+        <maximum>50000</maximum>
+        <step>1000</step>
+      </constraints>
+    </integer>
+
+    <boolean>
+      <name>InitializeTransform</name>
+      <flag>-u</flag>
+      <longflag>--noinitializetransform</longflag>
+      <description>Calculate initial transform</description>
+      <label>Initialize TransformSpatial Samples</label>
+      <default>false</default>
+    </boolean>
+
+    <integer-vector>
+      <name>Iterations</name>
+      <flag>-i</flag>
+      <longflag>--iterations</longflag>
+      <description>Comma separated list of iterations. Must have the same number of elements as learning rate</description>
+      <label>Iterations</label>
+      <default>100,100,100,200</default>
+    </integer-vector>
+
+    <float-vector>
+      <name>LearningRate</name>
+      <flag>-l</flag>
+      <longflag>--learningrate</longflag>
+      <description>Comma separated list of learning rates must have the same number of elements as iterations</description>
+      <label>Learning Rates</label>
+      <default>0.005,0.001,0.0005,0.0002</default>
+    </float-vector>
+    
+    <double>
+      <name>TranslationScale</name>
+      <longflag>--translationscale</longflag>
+      <flag>-t</flag>
+      <description>Relative scale of translations to rotations, i.e. a value of 100 means 10mm = 1 degree</description>
+      <label>Translation scaling</label>
+      <default>100.0</default>
+      <constraints>
+        <minimum>10.0</minimum>
+        <maximum>500.0</maximum>
+        <step>50.0</step>
+      </constraints>
+    </double>
+  </parameters>
+
+  <parameters>
+    <label>IO</label>
+    <description>Input/output parameters</description>
+    <file>
+      <name>FixedImage</name>
+      <label>Fixed Image</label>
+      <channel>input</channel>
+      <index>0</index>
+      <description>Fixed image to register to</description>
+    </file>
+    <file>
+      <name>MovingImage</name>
+      <label>Moving Image</label>
+      <channel>input</channel>
+      <index>1</index>
+      <description>Moving image</description>
+    </file>
+    <file>
+      <name>OutputImage</name>
+      <label>Output Volume</label>
+      <channel>output</channel>
+      <index>2</index>
+      <description>Resampled Moving Image</description>
+    </file>
+  </parameters>
+
+</executable>

+ 110 - 0
Plugins/org.commontk.slicermodule/Testing/Cpp/TestData/ParserTest2.xml

@@ -0,0 +1,110 @@
+<?xml version="1.0" encoding="utf-8"?>
+<executable>
+  <category>registration</category>
+  <title>NAMIC sample registration</title>
+  <description>Registers two images together using a rigid transform and MI</description>
+  <version>1.0</version>
+  <documentation-url></documentation-url>
+  <license></license>
+  <contributor>Daniel Blezek</contributor>
+
+  <parameters>
+    <label>Registration Parameters</label>
+    <description>Parameters used for registration</description>
+    <integer>
+      <name>HistogramBins</name>
+      <flag>-b</flag>
+      <longflag>--histogrambins</longflag>
+      <description>Number of histogram bins to use for Mattes Mutual Information</description>
+      <label>Histogram Bins</label>
+      <default>30</default>
+      <constraints>
+        <minimum>1</minimum>
+        <maximum>500</maximum>
+        <step>5</step>
+      </constraints>
+    </integer>
+
+    <integer>
+      <name>SpatialSamples</name>
+      <flag>-s</flag>
+      <longflag>--spatialsamples</longflag>
+      <description>Number of spatial samples to use in estimating Mattes Mutual Information</description>
+      <label>Spatial Samples</label>
+      <default>10000</default>
+      <constraints>
+        <minimum>1000</minimum>
+        <maximum>50000</maximum>
+        <step>1000</step>
+      </constraints>
+    </integer>
+
+    <boolean>
+      <name>InitializeTransform</name>
+      <flag>-u</flag>
+      <longflag>--noinitializetransform</longflag>
+      <description>Calculate initial transform</description>
+      <label>Initialize TransformSpatial Samples</label>
+      <default>false</default>
+    </boolean>
+
+    <integer-vector>
+      <name>Iterations</name>
+      <flag>-i</flag>
+      <longflag>--iterations</longflag>
+      <description>Comma separated list of iterations. Must have the same number of elements as learning rate</description>
+      <label>Iterations</label>
+      <default>100,100,100,200</default>
+    </integer-vector>
+
+    <float-vector>
+      <name>LearningRate</name>
+      <flag>-l</flag>
+      <longflag>--learningrate</longflag>
+      <description>Comma separated list of learning rates must have the same number of elements as iterations</description>
+      <label>Learning Rates</label>
+      <default>0.005,0.001,0.0005,0.0002</default>
+    </float-vector>
+    
+    <double>
+      <name>TranslationScale</name>
+      <longflag>--translationscale</longflag>
+      <flag>-t</flag>
+      <description>Relative scale of translations to rotations, i.e. a value of 100 means 10mm = 1 degree</description>
+      <label>Translation scaling</label>
+      <default>100.0</default>
+      <constraints>
+        <minimum>10.0</minimum>
+        <maximum>500.0</maximum>
+        <step>50.0</step>
+      </constraints>
+    </double>
+  </parameters>
+
+  <parameters>
+    <label>IO</label>
+    <description>Input/output parameters</description>
+    <image fileExtensions=".png,.nrrd">
+      <name>FixedImage</name>
+      <label>Fixed Image</label>
+      <channel>input</channel>
+      <index>0</index>
+      <description>Fixed image to register to</description>
+    </image>
+    <file fileExtensions=".txt,*.csv,*.html">
+      <name>MovingImage</name>
+      <label>Moving Image</label>
+      <channel>input</channel>
+      <index>1</index>
+      <description>Moving image</description>
+    </file>
+    <file fileExtensions="">
+      <name>OutputImage</name>
+      <label>Output Volume</label>
+      <channel>output</channel>
+      <index>2</index>
+      <description>Resampled Moving Image</description>
+    </file>
+  </parameters>
+
+</executable>

+ 146 - 0
Plugins/org.commontk.slicermodule/Testing/Cpp/ctkSlicerModuleTest.cpp

@@ -0,0 +1,146 @@
+/*=========================================================================
+
+  Library:   CTK
+ 
+  Copyright (c) 2010  CISTIB - Universitat Pompeu Fabra
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+      http://www.commontk.org/LICENSE
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+ 
+=========================================================================*/
+
+// Qt includes
+#include <QApplication>
+#include <QFile>
+
+// CTK includes
+#include "ctkModuleDescription.h"
+#include "ctkPluginFrameworkFactory.h"
+#include "ctkPluginFramework.h"
+#include "ctkPluginException.h"
+#include "ctkModuleDescriptionReader.h"
+#include "ctkModuleDescriptionConverterInterface.h"
+#include "ctkCommandLineParser.h"
+
+// STD includes
+#include <iostream>
+
+ctkModuleDescription ReadModuleDescription( ctkPluginContext* context, const QString &xmlFileName ) ;
+void BuildCommandLine( ctkPluginContext* context, const ctkModuleDescription& module ) ;
+
+
+//-----------------------------------------------------------------------------
+int ctkSlicerModuleTest(int argc, char * argv [] )
+{
+  QApplication app(argc, argv);
+  ctkCommandLineParser parser;
+  parser.addArgument("", "-F", QVariant::String);
+  bool ok = false;
+  QHash<QString, QVariant> parsedArgs = parser.parseArguments(argc, argv, &ok);
+  if (!ok)
+  {
+    std::cerr << qPrintable(parser.errorString()) << std::endl;
+    return EXIT_FAILURE;
+  }
+  QString xmlFileName = parsedArgs["-F"].toString();
+
+  ctkPluginFrameworkFactory fwFactory;
+  ctkPluginFramework* framework = fwFactory.getFramework();
+
+  try {
+    framework->init();
+  }
+  catch (const ctkPluginException& exc)
+  {
+    qCritical() << "Failed to initialize the plug-in framework:" << exc;
+    exit(1);
+  }
+
+
+#ifdef CMAKE_INTDIR
+  QString pluginPath = "/../plugins/" CMAKE_INTDIR "/";
+#else
+  QString pluginPath = "/plugins/";
+#endif
+
+  try
+  {
+    QString pluginLocation = "." + pluginPath + "liborg_commontk_slicermodule.dll";
+    ctkPlugin* plugin = framework->getPluginContext()->installPlugin(QUrl::fromLocalFile(pluginLocation));
+    plugin->start(ctkPlugin::START_TRANSIENT);
+
+    framework->start();
+
+    ctkModuleDescription module;
+    module = ReadModuleDescription( framework->getPluginContext(), xmlFileName );
+
+    BuildCommandLine( framework->getPluginContext(), module );
+
+  }
+  catch (const ctkPluginException& e)
+  {
+    qCritical() << e.what();
+  }
+
+  return EXIT_SUCCESS;
+}
+
+
+
+ctkModuleDescription ReadModuleDescription( 
+    ctkPluginContext* context, const QString &xmlFileName )
+{
+
+  ctkServiceReference* serviceRef;
+  serviceRef = context->getServiceReference( 
+    "ctkModuleDescriptionReaderInterface" );
+
+  ctkModuleDescriptionReader* reader;
+  reader = qobject_cast<ctkModuleDescriptionReader*>
+    (context->getService(serviceRef));
+
+
+  // Read file
+  QFile file( xmlFileName );
+  if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
+    {
+    std::cout << "XML file " << xmlFileName.toStdString( ) << " could not be opened." << std::endl;
+    exit(1);
+    }
+
+  // Parse XML file
+  reader->setInput( &file );
+  reader->update();
+  QTextStream stream(stdout);
+  stream << reader->moduleDescription( );
+
+  return reader->moduleDescription( );
+}
+
+void BuildCommandLine( ctkPluginContext* context, const ctkModuleDescription& module )
+{
+  ctkServiceReference* serviceRef;
+  serviceRef = context->getServiceReference( 
+    "ctkModuleDescriptionConverterInterface" );
+
+  ctkModuleDescriptionConverterInterface* converter;
+  converter = qobject_cast<ctkModuleDescriptionConverterInterface*>
+    (context->getService(serviceRef));
+
+  QStringList commandLineString;
+  converter->setModuleDescription( module );
+  converter->update();
+  commandLineString = converter->GetOutput().toStringList();
+  QTextStream stream(stdout);
+  stream << commandLineString;
+}
+

+ 79 - 0
Plugins/org.commontk.slicermodule/ctkSlicerModulePlugin.cpp

@@ -0,0 +1,79 @@
+/*=============================================================================
+
+  Library: CTK
+
+  Copyright (c) 2010 CISTIB - Universitat Pompeu Fabra
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+
+=============================================================================*/
+
+
+#include "ctkSlicerModulePlugin_p.h"
+#include "ctkSlicerModuleReader.h"
+#include "ctkSlicerModuleStringConverter.h"
+#include <QtPlugin>
+#include <QDebug>
+
+ctkSlicerModulePlugin* ctkSlicerModulePlugin::instance = 0;
+
+ctkSlicerModulePlugin::ctkSlicerModulePlugin()
+  : context(0)
+{
+}
+
+ctkSlicerModulePlugin::~ctkSlicerModulePlugin()
+{
+  
+}
+
+void ctkSlicerModulePlugin::start(ctkPluginContext* context)
+{
+  instance = this;
+  this->context = context;
+
+  this->reader = new ctkSlicerModuleReader( );
+  context->registerService(QStringList("ctkModuleDescriptionReaderInterface"),
+    this->reader);
+
+  this->stringConverter = new ctkSlicerModuleStringConverter( );
+  context->registerService(QStringList("ctkModuleDescriptionConverterInterface"),
+    this->stringConverter);
+
+  qDebug() << "Registered Slicer Module Description";
+}
+
+void ctkSlicerModulePlugin::stop(ctkPluginContext* context)
+{
+  delete this->reader;
+  this->reader = NULL;
+
+  delete this->stringConverter;
+  this->stringConverter = NULL;
+
+  Q_UNUSED(context)
+}
+
+ctkSlicerModulePlugin* ctkSlicerModulePlugin::getInstance()
+{
+  return instance;
+}
+
+ctkPluginContext* ctkSlicerModulePlugin::getPluginContext() const
+{
+  return context;
+}
+
+Q_EXPORT_PLUGIN2(org_commontk_slicermodule, ctkSlicerModulePlugin)
+
+

+ 59 - 0
Plugins/org.commontk.slicermodule/ctkSlicerModulePlugin_p.h

@@ -0,0 +1,59 @@
+/*=============================================================================
+
+  Library: CTK
+
+  Copyright (c) 2010 CISTIB - Universitat Pompeu Fabra
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+
+=============================================================================*/
+
+
+#ifndef CTKSLICERMODULEPLUGIN_P_H
+#define CTKSLICERMODULEPLUGIN_P_H
+
+#include <ctkPluginActivator.h>
+
+class ctkModuleDescriptionReaderInterface;
+class ctkSlicerModuleStringConverter;
+
+class ctkSlicerModulePlugin :
+  public QObject, public ctkPluginActivator
+{
+  Q_OBJECT
+  Q_INTERFACES(ctkPluginActivator)
+
+public:
+
+  ctkSlicerModulePlugin();
+  ~ctkSlicerModulePlugin();
+
+  void start(ctkPluginContext* context);
+  void stop(ctkPluginContext* context);
+
+  static ctkSlicerModulePlugin* getInstance();
+
+  ctkPluginContext* getPluginContext() const;
+
+
+private:
+
+  static ctkSlicerModulePlugin* instance;
+  ctkPluginContext* context;
+  ctkModuleDescriptionReaderInterface* reader;
+  ctkSlicerModuleStringConverter* stringConverter;
+
+
+}; // ctkSlicerModulePlugin
+
+#endif // CTKSLICERMODULEPLUGIN_P_H

+ 617 - 0
Plugins/org.commontk.slicermodule/ctkSlicerModuleReader.cpp

@@ -0,0 +1,617 @@
+/*=============================================================================
+
+Library: CTK
+
+Copyright (c) 2010 Brigham and Women's Hospital (BWH) All Rights Reserved.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+=============================================================================*/
+
+// Qt includes
+#include <QAbstractMessageHandler>
+#include <QDebug>
+#include <QXmlSchema>
+#include <QXmlSchemaValidator>
+#include <QVariant>
+
+// CTK includes
+#include "ctkSlicerModuleReader.h"
+
+// STD includes
+#include <stdexcept>
+
+class ctkDefaultMessageHandler : public QAbstractMessageHandler
+{
+public:
+  ctkDefaultMessageHandler(): QAbstractMessageHandler(0)
+  {
+  }
+
+  QString statusMessage() const
+  {
+  return m_description;
+  }
+
+  int line() const
+  {
+    return m_sourceLocation.line();
+  }
+
+  int column() const
+  {
+    return m_sourceLocation.column();
+  }
+
+protected:
+  virtual void handleMessage(QtMsgType type, const QString &description,
+                             const QUrl &identifier, const QSourceLocation &sourceLocation)
+  {
+    Q_UNUSED(type);
+    Q_UNUSED(identifier);
+
+    m_messageType = type;
+    m_description = description;
+    m_sourceLocation = sourceLocation;
+  }
+
+private:
+   QtMsgType m_messageType;
+   QString m_description;
+   QSourceLocation m_sourceLocation;
+ };
+ 
+// ----------------------------------------------------------------------------
+bool ctkSlicerModuleReader::validate()const
+{
+  ctkDefaultMessageHandler errorHandler;
+
+  QXmlSchema schema;
+  schema.setMessageHandler(&errorHandler);
+  schema.load(QUrl::fromLocalFile(":slicerModuleDescription.xsd"));
+  
+  bool res = schema.isValid();
+  if (!res)
+    {
+    QString error = errorHandler.statusMessage();
+    throw std::runtime_error( tr("Invalid Schema %1")
+      .arg(errorHandler.statusMessage()).toStdString() );
+    }
+
+  QXmlSchemaValidator validator(schema);
+  res = validator.validate(this->Device);
+
+  if (!res)
+    {
+    throw std::runtime_error( tr("Invalid XML(%1,%2):\n %3")
+      .arg(errorHandler.line())
+      .arg(errorHandler.column())
+      .arg(errorHandler.statusMessage()).toStdString());
+    }
+  this->Device->reset();
+  return res;
+}
+
+// ----------------------------------------------------------------------------
+void ctkSlicerModuleReader::update()
+{
+  // Verify the xml is correct
+  this->validate();
+
+  QXmlSimpleReader xmlReader;
+  QXmlInputSource *source = new QXmlInputSource(this->Device);
+  
+  ctkSlicerModuleHandler handler;
+  handler.setModuleDescription(&this->ModuleDescription);
+  xmlReader.setContentHandler(&handler);
+  xmlReader.setErrorHandler(&handler);
+
+  bool res = xmlReader.parse(source);
+
+  if (!res)
+    {
+    throw std::runtime_error( tr("Parse error %1")
+      .arg(handler.errorString()).toStdString() );
+    }
+}
+
+// ----------------------------------------------------------------------------
+ctkSlicerModuleHandler::ctkSlicerModuleHandler()
+{
+  this->ModuleDescription = 0;
+  this->State.CurrentParameter = 0;
+  this->State.CurrentGroup = 0;
+  this->State.InExecutable = 0;
+  this->State.InGroup = 0;
+  this->State.InParameter = 0;
+  this->ParamValidator = QRegExp("\\W");
+}
+
+// ----------------------------------------------------------------------------
+void ctkSlicerModuleHandler::setModuleDescription(ctkModuleDescription* moduleDescription)
+{
+  this->ModuleDescription = moduleDescription;
+}
+
+// ----------------------------------------------------------------------------
+ctkModuleDescription* ctkSlicerModuleHandler::moduleDescription()const
+{
+  return this->ModuleDescription;
+}
+// ----------------------------------------------------------------------------
+bool ctkSlicerModuleHandler::characters(const QString& ch)
+{
+  this->State.CurrentText = ch.trimmed();
+  return true;
+}
+
+// ----------------------------------------------------------------------------
+bool ctkSlicerModuleHandler::startElement(const QString& namespaceURI, const QString& localName,
+                                   const QString& name, const QXmlAttributes& atts)
+{
+  if (this->State.CurrentGroup == 0)
+    {
+    return this->startExecutableElement(namespaceURI, localName, name, atts);
+    }
+  else if (this->State.CurrentParameter == 0)
+    {
+    return this->startGroupElement(namespaceURI, localName, name, atts);
+    }
+  else
+    {
+    return this->startParameterElement(namespaceURI, localName, name, atts);
+    }
+  return false;
+}
+
+// ----------------------------------------------------------------------------
+bool ctkSlicerModuleHandler::endElement(const QString& namespaceURI,
+                                 const QString& localName,
+                                 const QString& qName)
+{
+  if (this->State.InParameter)
+    {
+    return this->endParameterElement(namespaceURI, localName, qName);
+    }
+  else if (this->State.InGroup)
+    {
+    return this->endGroupElement(namespaceURI, localName, qName);
+    }
+  else if (this->State.InExecutable)
+    {
+    return this->endExecutableElement(namespaceURI, localName, qName);
+    }
+  return false;
+}
+// ----------------------------------------------------------------------------
+bool ctkSlicerModuleHandler::startExecutableElement(const QString& namespaceURI,
+                                             const QString& localName,
+                                             const QString& name,
+                                             const QXmlAttributes& atts)
+{
+  Q_UNUSED(namespaceURI);
+  Q_UNUSED(localName);
+  ++this->State.InExecutable;
+  ctkModuleParameterGroup group;
+  if (name == "parameters")
+    {
+    if (!atts.value("advanced").isEmpty())
+      {
+      group["Advanced"] = QVariant(atts.value("advanced")).toBool() ? "true" : "false";
+      }
+    this->State.CurrentGroup = new ctkModuleParameterGroup(group);
+    }
+  return true;
+}
+
+// ----------------------------------------------------------------------------
+bool ctkSlicerModuleHandler::startGroupElement(const QString& namespaceURI,
+                                        const QString& localName,
+                                        const QString& name,
+                                        const QXmlAttributes& atts)
+{
+  Q_UNUSED(namespaceURI);
+  Q_UNUSED(localName);
+
+  ++this->State.InGroup;
+  if (name == "label" || name == "description")
+    {// not a parameter
+    return true;
+    }
+  ctkModuleParameter param;
+  param["Tag"] = name;
+  bool multiple = QVariant(atts.value("multiple")).toBool(); //empty (not found) is false
+  bool hidden = QVariant(atts.value("hidden")).toBool(); //empty (not found) is false
+  
+  if (name == "integer" || name == "integer-vector")
+    {
+    if (name == "integer-vector")
+      {
+      multiple = true;
+      }
+    param["Multiple"] = multiple ? "true" : "false";
+    param["CPPStyle"] = multiple ? "std::vector<int>" : "int";
+    param["ArgType"] = "int";
+    param["StringToType"] = "atoi";
+    }
+  else if (name == "float" || name == "float-vector")
+    {
+    if (name == "integer-vector")
+      {
+      multiple = true;
+      }
+    param["Multiple"] = multiple ? "true" : "false";
+    param["CPPStyle"] = multiple ? "std::vector<float>" : "float";
+    param["ArgType"] = "float";
+    param["StringToType"] = "atof";
+    }
+  else if (name == "double" || name == "double-vector")
+    {
+    if (name == "double-vector")
+      {
+      multiple = true;
+      }
+    param["Multiple"] = multiple ? "true" : "false";
+    param["CPPStyle"] = multiple ? "std::vector<double>" : "double";
+    param["ArgType"] = "double";
+    param["StringToType"] = "atof";
+    }
+  else if (name == "string")
+    {
+    if (name == "string-vector")
+      {
+      multiple = true;
+      }
+    param["Multiple"] = multiple ? "true" : "false";
+    param["CPPStyle"] = multiple ? "std::vector<std::string>" : "std::string";
+    param["ArgType"] = "std::string";
+    param["StringToType"] = "";
+    }
+  else if (name == "boolean")
+    {
+    if (name == "boolean-vector")
+      {
+      multiple = true;
+      }
+    param["Multiple"] = multiple ? "true" : "false";
+    param["CPPStyle"] = multiple ? "std::vector<bool>" : "bool";
+    param["ArgType"] = "bool";
+    param["StringToType"] = "";
+    param["Hidden"] = hidden ? "true" : "false";
+    }
+  else if (name == "point" || name == "point-vector" ||
+           name == "region" || name == "region-vector")
+    {
+    if (name == "point-vector" || name == "region-vector")
+      {
+      multiple = true;
+      }
+    param["Multiple"] = multiple ? "true" : "false";
+    param["CPPStyle"] = multiple ? "std::vector<std::vector<float> >" : "std::vector<float>";
+    param["ArgType"] = "float";
+    param["StringToType"] = "atof";
+    if (!atts.value("coordinateSystem").isEmpty())
+      {
+      param["CoordinateSystem"] = atts.value("coordinateSystem");
+      }
+    }
+  else if (name == "string-enumeration")
+    {
+    param["CPPStyle"] = "std::string";
+    }
+  else if (name == "integer-enumeration")
+    {
+    param["CPPStyle"] = "int";
+    }
+  else if (name == "float-enumeration")
+    {
+    param["CPPStyle"] = "float";
+    }
+  else if (name == "double-enumeration")
+    {
+    param["CPPStyle"] = "double";
+    }
+  else if (name == "file")
+    {
+    param["Multiple"] = multiple ? "true" : "false";
+    param["CPPType"] = multiple ? "std::vector<std::string>" : "std::string";
+    param["ArgType"] = "std::string";
+    param["Type"] = "scalar";
+    if (!atts.value("fileExtensions").isEmpty())
+      {
+      param["FileExtensionsAsString"] = atts.value("fileExtensions");
+      }
+    }
+  else if (name == "directory")
+    {
+    param["Multiple"] = multiple ? "true" : "false";
+    param["CPPStyle"] = multiple ? "std::vector<std::string>" : "std::string";
+    param["ArgType"] = "std::string";
+    }
+  else if (name == "transform")
+    {
+    param["Multiple"] = multiple ? "true" : "false";
+    param["CPPStyle"] = multiple ? "std::vector<std::string>" : "std::string";
+    param["ArgType"] = "std::string";
+    param["Type"] = atts.value("type").isEmpty() ? atts.value("type") : "unknown";
+    if (!atts.value("fileExtensions").isEmpty())
+      {
+      param["FileExtensionsAsString"] = atts.value("fileExtensions");
+      }
+    if (!atts.value("reference").isEmpty())
+      {
+      param["Reference"] = atts.value("reference");
+      }
+    }
+  else if (name == "image")
+    {
+    param["Multiple"] = multiple ? "true" : "false";
+    param["CPPStyle"] = multiple ? "std::vector<std::string>" : "std::string";
+    param["ArgType"] = "std::string";
+    param["Type"] = (!atts.value("type").isEmpty()) ? atts.value("type") : "scalar";
+    if (!atts.value("fileExtensions").isEmpty())
+      {
+      param["FileExtensionsAsString"] = atts.value("fileExtensions");
+      }
+    param["Hidden"] = hidden ? "true" : "false";
+    if (!atts.value("reference").isEmpty())
+      {
+      param["Reference"] = atts.value("reference");
+      }
+    }
+  else if (name == "geometry")
+    {
+    bool aggregate = QVariant(atts.value("aggregate")).toBool();
+    param["Multiple"] = multiple ? "true" : "false";
+    param["Aggregate"] = aggregate ? "true" : "false";
+    param["CPPType"] = (multiple && !aggregate) ? "std::vector<std::string>" : "std::string";
+    param["ArgType"] = "std::string";
+    param["Type"] = (!atts.value("type").isEmpty())? atts.value("type") : "scalar";
+    }
+  else if (name == "table")
+    {
+    param["Multiple"] = multiple ? "true" : "false";
+    param["CPPType"] = multiple ? "std::vector<std::string>" : "std::string";
+    param["ArgType"] = "std::string";
+    param["Type"] = (!atts.value("type").isEmpty())? atts.value("type") : "scalar";
+    if (!atts.value("reference").isEmpty())
+      {
+      param["Reference"] = atts.value("reference");
+      }
+    if (!atts.value("fileExtensions").isEmpty())
+      {
+      param["FileExtensionsAsString"] = atts.value("fileExtensions");
+      }
+    }
+  else if (name == "measurement")
+    {
+    param["Multiple"] = multiple ? "true" : "false";
+    param["CPPType"] = multiple ? "std::vector<std::string>" : "std::string";
+    param["ArgType"] = "std::string";
+    param["Type"] = (!atts.value("type").isEmpty())? atts.value("type") : "scalar";
+    param["Hidden"] = hidden ? "true" : "false";
+    if (!atts.value("reference").isEmpty())
+      {
+      param["Reference"] = atts.value("reference");
+      }
+    if (!atts.value("fileExtensions").isEmpty())
+      {
+      param["FileExtensionsAsString"] = atts.value("fileExtensions");
+      }
+    }
+  this->State.CurrentParameter = new ctkModuleParameter(param);
+  return true;
+}
+
+// ----------------------------------------------------------------------------
+bool ctkSlicerModuleHandler::startParameterElement(const QString& namespaceURI, const QString& localName,
+                                            const QString& name, const QXmlAttributes& atts)
+{
+  Q_UNUSED(namespaceURI);
+  Q_UNUSED(localName);
+
+  ++this->State.InParameter;
+  ctkModuleParameter& param = *this->State.CurrentParameter;
+  if (name == "flag")
+    {
+    if (!atts.value("alias").isEmpty())
+      {
+      param["FlagAliasesAsString"] = atts.value("alias");
+      }
+    if (!atts.value("deprecatedalias").isEmpty())
+      {
+      param["DeprecatedFlagAliasesAsString"] = atts.value("deprecatedalias");
+      }
+    }
+  else if (name == "longflag")
+    {
+    if (!atts.value("alias").isEmpty())
+      {
+      param["LongFlagAliasesAsString"] = atts.value("alias");
+      }
+    if (!atts.value("deprecatedalias").isEmpty())
+      {
+      param["DeprecatedLongFlagAliasesAsString"] = atts.value("deprecatedalias");
+      }
+    }
+  else if (name == "constraints")
+    {
+    param["Constraints"] = "true";
+    }
+  return true;
+}
+
+// ----------------------------------------------------------------------------
+bool ctkSlicerModuleHandler::endExecutableElement(const QString& namespaceURI,
+                                           const QString& localName,
+                                           const QString& name)
+{
+  Q_UNUSED(namespaceURI);
+  Q_UNUSED(localName);
+
+  --this->State.InExecutable;
+  ctkModuleDescription& module= *this->ModuleDescription;
+  if (name == "parameters")
+    {
+    Q_ASSERT(this->State.CurrentGroup);
+    this->ModuleDescription->addParameterGroup(this->State.CurrentGroup);
+    this->State.CurrentGroup = 0;
+    }
+  else if (name == "category")
+    {
+    module["Category"] = this->State.CurrentText;
+    }
+  else if (name == "index")
+    {
+    module["Index"] = this->State.CurrentText;
+    }
+  else if (name == "title")
+    {
+    module["Title"] = this->State.CurrentText;
+    }
+  else if (name == "version")
+    {
+    module["Version"] = this->State.CurrentText;
+    }
+  else if (name == "documentation-url")
+    {
+    module["DocumentationUrl"] = this->State.CurrentText;
+    }
+  else if (name == "license")
+    {
+    module["License"] = this->State.CurrentText;
+    }
+  else if (name == "acknowledgements")
+    {
+    module["License"] = this->State.CurrentText;
+    }
+  else if (name == "contributor")
+    {
+    module["Contributor"] = this->State.CurrentText;
+    }
+  else if (name == "location")
+    {
+    module["Location"] = this->State.CurrentText;
+    }
+  else if (name == "description")
+    {
+    module["Description"] = this->State.CurrentText.replace('\"','\'');
+    }
+  return true;
+}
+
+// ----------------------------------------------------------------------------
+bool ctkSlicerModuleHandler::endGroupElement(const QString& namespaceURI,
+                                      const QString& localName,
+                                      const QString& name)
+{
+  Q_UNUSED(namespaceURI);
+  Q_UNUSED(localName);
+
+  --this->State.InGroup;
+  Q_ASSERT(this->State.CurrentGroup);
+  ctkModuleParameterGroup& group = *this->State.CurrentGroup;
+  if (name == "label")
+    {
+    group["Label"] = this->State.CurrentText;
+    return true;
+    }
+  else if (name == "description")
+    {
+    group["Description"] = this->State.CurrentText.replace('\"', '\'');
+    return true;
+    }
+  Q_ASSERT(this->State.CurrentParameter);
+  this->State.CurrentGroup->addParameter(this->State.CurrentParameter);
+  this->State.CurrentParameter = 0;
+  return true;
+}
+
+// ----------------------------------------------------------------------------
+bool ctkSlicerModuleHandler::endParameterElement(const QString& namespaceURI, const QString& localName,
+                                          const QString& name)
+{
+  Q_UNUSED(namespaceURI);
+  Q_UNUSED(localName);
+
+  --this->State.InParameter;
+  bool res = true;
+  ctkModuleParameter& parameter = *this->State.CurrentParameter;
+  if (name == "flag")
+    {
+    QString flag = this->State.CurrentText;
+    flag.remove(0, flag.indexOf('-') + 1);
+    res = (flag.size() == 1);
+    if (!res)
+      {
+      qWarning() << "Invalid flag" << flag;
+      }
+    parameter["Flag"] = flag;
+    }
+  else if (name == "longflag")
+    {
+    QString flag = this->State.CurrentText;
+    flag.remove(0, flag.indexOf("--") + 2);
+    res = (flag.size() != 0 && this->ParamValidator.indexIn(flag) == -1);
+    if (!res)
+      {
+      qWarning() << "Invalid flag" << flag;
+      }
+    parameter["LongFlag"] = flag;
+    parameter["Name"] = parameter.value("Name", flag);
+    }
+  else if (name == "name")
+    {
+    QString paramName = this->State.CurrentText;
+    if (this->ParamValidator.indexIn(paramName) != -1)
+      {
+      res = false;
+      qWarning() << "Invalid name" << paramName;
+      }
+    parameter["Name"] = paramName;
+    }
+  else if (name == "label")
+    {
+    parameter["Label"] = this->State.CurrentText;
+    }
+  else if (name == "element")
+    {
+    parameter.insertMulti("Element", this->State.CurrentText);
+    }
+  else if (name == "default")
+    {
+    parameter["Default"] = this->State.CurrentText;
+    }
+  else if (name == "channel")
+    {
+    parameter["Channel"] = this->State.CurrentText;
+    }
+  else if (name == "index")
+    {
+    // TODO make sure Flag and LongFlag are empty
+    parameter["Index"] = this->State.CurrentText;
+    }
+  else if (name == "minimum")
+    {
+    parameter["Minimum"] = this->State.CurrentText;
+    }
+  else if (name == "maximum")
+    {
+    parameter["Maximum"] = this->State.CurrentText;
+    }
+  else if (name == "step")
+    {
+    parameter["Step"] = this->State.CurrentText;
+    }
+  return res;
+}

+ 94 - 0
Plugins/org.commontk.slicermodule/ctkSlicerModuleReader.h

@@ -0,0 +1,94 @@
+/*=============================================================================
+
+  Library: CTK
+
+  Copyright (c) 2010 Brigham and Women's Hospital (BWH) All Rights Reserved.
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+
+=============================================================================*/
+
+#ifndef __ctkSlicerModuleReader_h
+#define __ctkSlicerModuleReader_h
+
+// Qt includes
+#include <QRegExp>
+#include <QStack>
+#include <QXmlAttributes>
+#include <QXmlDefaultHandler>
+
+// CTK includes
+#include "ctkModuleDescriptionReader.h"
+
+/**
+ * Reader of Slicer Module XML description
+ * Freely inspired from 
+ * Slicer/Libs/SlicerExecutionModel/ModuleDescriptionParser/ModuleDescriptionParser.cxx
+ */
+class ctkSlicerModuleReader : public ctkModuleDescriptionReader
+{
+  Q_OBJECT
+public:
+  virtual void update();
+  bool validate()const; 
+};
+
+/**
+ * Utility class to parse the Slicer Module XML descriptions using the
+ * SAX interface.
+ */
+class ctkSlicerModuleHandler: public QXmlDefaultHandler
+{
+public:
+  ctkSlicerModuleHandler();
+  bool characters(const QString& ch);
+  virtual bool endElement(const QString& namespaceURI, const QString& localName, const QString& qName);
+  virtual bool startElement(const QString& namespaceURI, const QString& localName, const QString& qName, const QXmlAttributes& atts );
+  
+  void setModuleDescription(ctkModuleDescription* moduleDescription);
+  ctkModuleDescription* moduleDescription()const;
+
+protected:
+
+  bool startExecutableElement(const QString& namespaceURI, const QString& localName,
+                              const QString& name, const QXmlAttributes& atts);
+
+  bool startGroupElement(const QString& namespaceURI, const QString& localName,
+                         const QString& name, const QXmlAttributes& atts);
+
+  bool startParameterElement(const QString& namespaceURI, const QString& localName,
+                             const QString& name, const QXmlAttributes& atts);
+
+  bool endExecutableElement(const QString& namespaceURI, const QString& localName,
+                            const QString& name);
+
+  bool endGroupElement(const QString& namespaceURI, const QString& localName,
+                       const QString& name);
+
+  bool endParameterElement(const QString& namespaceURI, const QString& localName,
+                           const QString& name);
+                            
+  ctkModuleDescription* ModuleDescription;
+  struct ParserState{
+    ctkModuleParameter*      CurrentParameter;
+    ctkModuleParameterGroup* CurrentGroup;
+    QString                  CurrentText;
+    int                      InExecutable;
+    int                      InGroup;
+    int                      InParameter;
+  };
+  ParserState State;
+  QRegExp     ParamValidator;
+};
+
+#endif

+ 158 - 0
Plugins/org.commontk.slicermodule/ctkSlicerModuleStringConverter.cpp

@@ -0,0 +1,158 @@
+/*=============================================================================
+
+Library: CTK
+
+Copyright (c) 2010 CISTIB - Universtitat Pompeu Fabra
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+=============================================================================*/
+
+#include "ctkSlicerModuleStringConverter.h"
+#include <QVector>
+
+
+void ctkSlicerModuleStringConverter::update()
+{
+  SetTarget( );
+
+  SetAllParameters( );
+}
+
+const QVariant ctkSlicerModuleStringConverter::GetOutput()
+{
+  return this->CommandLineAsString;
+}
+
+void ctkSlicerModuleStringConverter::SetAllParameters()
+{
+  foreach( const ctkModuleParameterGroup* itGroup, this->ModuleDescription.parameterGroups())
+  {
+    foreach( const ctkModuleParameter* itParam, itGroup->parameters())
+    {
+      SetParameterValue( *itParam );
+    }
+  }
+}
+
+void ctkSlicerModuleStringConverter::SetParameterValue( const ctkModuleParameter &param )
+{
+  QString prefix;
+  QString flag;
+  bool hasFlag = false;
+
+  if ( param["LongFlag"] != "")
+  {
+    prefix = "--";
+    flag = param["LongFlag"];
+    hasFlag = true;
+  }
+  else if (param["Flag"] != "")
+  {
+    prefix = "-";
+    flag = param["Flag"];
+    hasFlag = true;
+  }
+
+
+  if (hasFlag)
+  {
+    if (   param["Tag"] != "boolean"
+      && param["Tag"] != "file" 
+      && param["Tag"] != "directory"
+      && param["Tag"] != "string"
+      && param["Tag"] != "integer-vector"
+      && param["Tag"] != "float-vector"
+      && param["Tag"] != "double-vector"
+      && param["Tag"] != "string-vector"
+      && param["Tag"] != "image"
+      && param["Tag"] != "point"
+      && param["Tag"] != "region"
+      && param["Tag"] != "transform"
+      && param["Tag"] != "geometry"
+      && param["Tag"] != "table"
+      && param["Tag"] != "measurement")
+    {
+      // simple parameter, write flag and value
+      this->CommandLineAsString.push_back(prefix + flag);
+      this->CommandLineAsString.push_back(param["Default"]);
+    }
+    else if (param["Tag"] == "boolean" && param["Default"] == "true")
+    {
+      this->CommandLineAsString.push_back(prefix + flag);
+    }
+    else if (param["Tag"] == "file" 
+      || param["Tag"] == "directory"
+      || param["Tag"] == "string"
+      || param["Tag"] == "integer-vector"
+      || param["Tag"] == "float-vector"
+      || param["Tag"] == "double-vector"
+      || param["Tag"] == "string-vector")
+    {
+      // Only write out the flag if value is not empty
+      if ( param["Default"] != "")
+      {
+        this->CommandLineAsString.push_back(prefix + flag);
+        this->CommandLineAsString.push_back( param["Default"] );
+      }
+    }
+    // data passed as parameter
+    else if ( param["Tag"] == "image" 
+      || param["Tag"] == "geometry"
+      || param["Tag"] == "transform" 
+      || param["Tag"] == "table" 
+      || param["Tag"] == "measurement" )
+    {
+      if ( param["Default"] != "")
+      {
+        this->CommandLineAsString.push_back(prefix + flag);
+        this->CommandLineAsString.push_back(param["Default"]);
+      }
+    }
+    else if ( param["Tag"] == "region" )
+    {
+      this->CommandLineAsString.push_back(prefix + flag);
+      this->CommandLineAsString.push_back( param["Default"] );
+    }
+    else if ( param["Tag"] == "point" )
+    {
+      QStringList points = param["Default"].split( ";");
+      foreach ( const QString &it, points )
+      {
+        this->CommandLineAsString.push_back(prefix + flag);
+        this->CommandLineAsString.push_back( it );
+      }
+    }
+
+  }
+
+  // If index is not empty -> It's a command line argument arg0, arg1, ... without flag prefix
+  if ( param["Index"] != "")
+  {
+    this->CommandLineAsString.push_back( param["Default"] );
+  }
+}
+
+void ctkSlicerModuleStringConverter::SetTarget()
+{
+  this->CommandLineAsString.clear();
+
+  if (!this->ModuleDescription["Location"].isEmpty() && 
+    this->ModuleDescription["Location"] != this->ModuleDescription["Target"])
+  {
+    this->CommandLineAsString.push_back(this->ModuleDescription["Location"]);
+  }
+  this->CommandLineAsString.push_back( this->ModuleDescription["Target"] );
+}
+
+

+ 65 - 0
Plugins/org.commontk.slicermodule/ctkSlicerModuleStringConverter.h

@@ -0,0 +1,65 @@
+/*=============================================================================
+
+  Library: CTK
+
+  Copyright (c) 2010 CISTIB - Universtitat Pompeu Fabra
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+
+=============================================================================*/
+
+#ifndef __ctkSlicerModuleStringConverter_h
+#define __ctkSlicerModuleStringConverter_h
+
+#include <string>
+
+#include "ctkModuleDescriptionConverter.h"
+
+class ModuleDescription;
+class ModuleParameterGroup;
+
+
+/**
+ * Convert Slicer Module description to command line string QStringList
+ *
+ */
+class ctkSlicerModuleStringConverter : public ctkModuleDescriptionConverter
+{
+  Q_OBJECT
+public:
+  ctkSlicerModuleStringConverter() {};
+  ~ctkSlicerModuleStringConverter() {};
+
+  ///
+  void update( );
+
+  ///
+  virtual const QVariant GetOutput( );
+
+protected:
+
+  //!
+  void SetAllParameters();
+
+  //!
+  void SetParameterValue( const ctkModuleParameter &param );
+
+  ///
+  void SetTarget();
+
+protected:
+
+  QStringList CommandLineAsString;
+};
+
+#endif

+ 10 - 0
Plugins/org.commontk.slicermodule/target_libraries.cmake

@@ -0,0 +1,10 @@
+# See CMake/ctkMacroGetTargetLibraries.cmake
+#
+# This file should list the libraries required to build the current CTK plugin.
+# For specifying required plugins, see the manifest_headers.cmake file.
+#
+
+SET(target_libraries
+  CTKPluginFramework
+  CTKModuleDescription
+)