Quellcode durchsuchen

Parse Slicer Command line module descriptions

Based on ModuleDescriptionParser, parse the command line module
XML descriptions of the slicer modules using SAX
Julien Finet vor 14 Jahren
Ursprung
Commit
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( );