瀏覽代碼

Parse Slicer Command line module descriptions

Based on ModuleDescriptionParser, parse the command line module
XML descriptions of the slicer modules using SAX
Julien Finet 14 年之前
父節點
當前提交
fd382fa983

+ 1 - 0
Libs/ModuleDescription/CMakeLists.txt

@@ -20,6 +20,7 @@ SET(KIT_SRCS
   ctkModuleParameter.cpp
   ctkModuleParameterGroup.h
   ctkModuleParameterGroup.cpp
+  ctkModuleDescriptionReaderInterface.cpp
   ctkModuleDescriptionReaderInterface.h
   ctkModuleDescriptionReader.h
   ctkModuleDescriptionReader.cpp

+ 2 - 2
Libs/ModuleDescription/ctkModuleDescription.cpp

@@ -29,12 +29,12 @@ 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

+ 1 - 1
Libs/ModuleDescription/ctkModuleDescription.h

@@ -59,7 +59,7 @@ public:
   
   void addParameterGroup(ctkModuleParameterGroup* group);
 
-  //const QVector<ctkModuleParameterGroup*>& parameterGroups() const;
+  const QVector<ctkModuleParameterGroup*>& parameterGroups() const;
   
   // Return the group that contain the parameter associated to the name
   ctkModuleParameterGroup* parameterGroup(const QString& parameterName) const;

+ 1 - 1
Libs/ModuleDescription/ctkModuleDescriptionConverterInterface.h

@@ -45,7 +45,7 @@ public:
   virtual void setModuleDescription(const ctkModuleDescription &val) = 0;
 
   //!
-  virtual void Update( ) = 0;
+  virtual void update( ) = 0;
 
   //!
   virtual const QVariant GetOutput( ) = 0;

+ 6 - 0
Libs/ModuleDescription/ctkModuleParameterGroup.cpp

@@ -38,6 +38,12 @@ void ctkModuleParameterGroup::addParameter( ctkModuleParameter* parameter )
 }
 
 //----------------------------------------------------------------------------
+const QVector<ctkModuleParameter*>& ctkModuleParameterGroup::parameters() const
+{
+	return this->Parameters;
+}
+
+//----------------------------------------------------------------------------
 ctkModuleParameter* ctkModuleParameterGroup::parameter( const QString& parameterName )const
 {
   foreach(ctkModuleParameter* param, this->Parameters)

+ 2 - 0
Libs/ModuleDescription/ctkModuleParameterGroup.h

@@ -36,6 +36,8 @@ public:
   
   /// 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

+ 2 - 1
Plugins/org.commontk.slicermodule/CMakeLists.txt

@@ -4,8 +4,9 @@ SET(PLUGIN_export_directive "org_commontk_slicermodule_EXPORT")
 
 SET(PLUGIN_SRCS
   ctkSlicerModulePlugin.cpp
+  ctkSlicerModulePlugin_p.h
+  ctkSlicerModuleReader.cpp
   ctkSlicerModuleReader.h
-  ctkSlicerModuleReader.cxx
   ctkSlicerModuleStringConverter.h
   ctkSlicerModuleStringConverter.cpp
 )

+ 9 - 10
Plugins/org.commontk.slicermodule/Testing/Cpp/ctkSlicerModuleTest.cpp

@@ -18,21 +18,21 @@
  
 =========================================================================*/
 
+// Qt includes
+#include <QFile>
+
 // CTK includes
 #include "ctkModuleDescription.h"
 #include "ctkPluginFrameworkFactory.h"
 #include "ctkPluginFramework.h"
 #include "ctkPluginException.h"
-#include "ctkModuleDescriptionReaderInterface.h"
+#include "ctkModuleDescriptionReader.h"
 #include "ctkModuleDescriptionConverterInterface.h"
 #include "ctkCommandLineParser.h"
 
 // STD includes
 #include <iostream>
 
-#include "QFile"
-
-
 ctkModuleDescription ReadModuleDescription( ctkPluginContext* context, const QString &xmlFileName ) ;
 void BuildCommandLine( ctkPluginContext* context, const ctkModuleDescription& module ) ;
 
@@ -103,8 +103,8 @@ ctkModuleDescription ReadModuleDescription(
   serviceRef = context->getServiceReference( 
     "ctkModuleDescriptionReaderInterface" );
 
-  ctkModuleDescriptionReaderInterface* reader;
-  reader = qobject_cast<ctkModuleDescriptionReaderInterface*>
+  ctkModuleDescriptionReader* reader;
+  reader = qobject_cast<ctkModuleDescriptionReader*>
     (context->getService(serviceRef));
 
 
@@ -115,11 +115,10 @@ ctkModuleDescription ReadModuleDescription(
     std::cout << "XML file " << xmlFileName.toStdString( ) << " could not be opened." << endl;
     exit(1);
   }
-  QTextStream stream( &file );
 
   // Parse XML file
-  reader->setXmlContent( stream.readAll() );
-  reader->Update();
+  reader->setInput( &file );
+  reader->update();
   QTextStream(stdout) << reader->moduleDescription( );
 
   return reader->moduleDescription( );
@@ -137,7 +136,7 @@ void BuildCommandLine( ctkPluginContext* context, const ctkModuleDescription& mo
 
   QStringList commandLineString;
   converter->setModuleDescription( module );
-  converter->Update();
+  converter->update();
   commandLineString = converter->GetOutput().toStringList();
   QTextStream(stdout) << commandLineString;
 }

+ 494 - 15
Plugins/org.commontk.slicermodule/ctkSlicerModuleReader.cpp

@@ -18,25 +18,504 @@ limitations under the License.
 
 =============================================================================*/
 
+// Qt includes
+#include <QDebug>
+#include <QVariant>
+
+// CTK includes
 #include "ctkSlicerModuleReader.h"
-#include <QtXml/QDomDocument>
 
 // ----------------------------------------------------------------------------
 void ctkSlicerModuleReader::update()
 {
-  QDomDocument domDocument;
-  QString errorStr;
-  int errorLine;
-  int errorColumn;
-
-  if (!domDocument.setContent(XmlContent, &errorStr, &errorLine,
-    &errorColumn)) {
-      throw std::runtime_error( 
-        tr("Parse error at line %1, column %2:\n%3")
-        .arg(errorLine)
-        .arg(errorColumn)
-        .arg(errorStr).toStdString().c_str() );
-      return ;
-  }
 
+  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)
+{
+  ++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)
+{
+  ++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").isEmpty() : "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").isEmpty() : "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").isEmpty() : "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)
+{
+  ++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)
+{
+  --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)
+{
+  --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)
+{
+  --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;
 }

+ 57 - 1
Plugins/org.commontk.slicermodule/ctkSlicerModuleReader.h

@@ -21,11 +21,19 @@
 #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
 {
@@ -34,4 +42,52 @@ public:
   virtual void update();
 };
 
+/**
+ * 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

+ 4 - 4
Plugins/org.commontk.slicermodule/ctkSlicerModuleStringConverter.cpp

@@ -22,7 +22,7 @@ limitations under the License.
 #include <QVector>
 
 
-void ctkSlicerModuleStringConverter::Update()
+void ctkSlicerModuleStringConverter::update()
 {
   SetTarget( );
 
@@ -36,11 +36,11 @@ const QVariant ctkSlicerModuleStringConverter::GetOutput()
 
 void ctkSlicerModuleStringConverter::SetAllParameters()
 {
-  foreach( const ctkModuleParameterGroup& itGroup, this->ModuleDescription.parameterGroups())
+  foreach( const ctkModuleParameterGroup* itGroup, this->ModuleDescription.parameterGroups())
   {
-    foreach( const ctkModuleParameter& itParam, itGroup.parameters())
+    foreach( const ctkModuleParameter* itParam, itGroup->parameters())
     {
-      SetParameterValue( itParam );
+      SetParameterValue( *itParam );
     }
   }
 }

+ 1 - 1
Plugins/org.commontk.slicermodule/ctkSlicerModuleStringConverter.h

@@ -41,7 +41,7 @@ public:
   ~ctkSlicerModuleStringConverter() {};
 
   ///
-  void Update( );
+  void update( );
 
   ///
   virtual const QVariant GetOutput( );