Pārlūkot izejas kodu

Made ctkCmdLineModuleDescription and related classes read-only.

Sascha Zelzer 12 gadi atpakaļ
vecāks
revīzija
bfbaa88c14

+ 3 - 0
Libs/CommandLineModules/CMakeLists.txt

@@ -15,10 +15,13 @@ set(KIT_export_directive "CTK_CMDLINEMODULE_EXPORT")
 # Source files
 set(KIT_SRCS
   ctkCmdLineModuleDescription.cpp
+  ctkCmdLineModuleDescriptionPrivate.h
   ctkCmdLineModuleManager.cpp
   ctkCmdLineModuleObjectHierarchyReader.cpp
   ctkCmdLineModuleParameter.cpp
+  ctkCmdLineModuleParameterPrivate.cpp
   ctkCmdLineModuleParameterGroup.cpp
+  ctkCmdLineModuleParameterGroupPrivate.h
   ctkCmdLineModuleParameterParsers_p.h
   ctkCmdLineModuleProcessException.cpp
   ctkCmdLineModuleProcessFuture.cpp

+ 20 - 237
Libs/CommandLineModules/ctkCmdLineModuleDescription.cpp

@@ -19,332 +19,120 @@ limitations under the License.
 =============================================================================*/
 
 #include "ctkCmdLineModuleDescription.h"
-#include <iostream>
-#include "QFile"
-#include "QTextStream"
+#include "ctkCmdLineModuleDescriptionPrivate.h"
 
-struct ctkCmdLineModuleDescriptionPrivate
-{
-  ~ctkCmdLineModuleDescriptionPrivate()
-  {
-    qDeleteAll(ParameterGroups);
-  }
-
-  QString Title;
-  QString Category;
-  QString Description;
-  QString Version;
-  QString DocumentationURL;
-  QString License;
-  QString Acknowledgements;
-  QString Contributor;
-  QString Type;
-  QString Target;
-  QString Location;
-  QString AlternativeType;
-  QString AlternativeTarget;
-  QString AlternativeLocation;
+#include "ctkCmdLineModuleParameter.h"
+#include "ctkCmdLineModuleParameterGroup.h"
 
-  QIcon Logo;
+#include "ctkException.h"
 
-  QList<ctkCmdLineModuleParameterGroup*> ParameterGroups;
+#include <QTextStream>
 
-  //ModuleProcessInformation ProcessInformation;
-};
 
 //----------------------------------------------------------------------------
 ctkCmdLineModuleDescription::ctkCmdLineModuleDescription()
-  : d_ptr(new ctkCmdLineModuleDescriptionPrivate)
+  : d(new ctkCmdLineModuleDescriptionPrivate)
 {
 }
 
 //----------------------------------------------------------------------------
 ctkCmdLineModuleDescription::~ctkCmdLineModuleDescription()
 {
-  delete d_ptr;
-}
-
-
-//----------------------------------------------------------------------------
-void ctkCmdLineModuleDescription::setCategory(const QString& cat)
-{
-  Q_D(ctkCmdLineModuleDescription);
-  d->Category = cat;
 }
 
 //----------------------------------------------------------------------------
 QString ctkCmdLineModuleDescription::category() const
 {
-  Q_D(const ctkCmdLineModuleDescription);
   return d->Category;
 }
 
 //----------------------------------------------------------------------------
-void ctkCmdLineModuleDescription::setTitle(const QString& title)
-{
-  Q_D(ctkCmdLineModuleDescription);
-  d->Title = title;
-}
-
-//----------------------------------------------------------------------------
 QString ctkCmdLineModuleDescription::title() const
 {
-  Q_D(const ctkCmdLineModuleDescription);
   return d->Title;
 }
 
 //----------------------------------------------------------------------------
-void ctkCmdLineModuleDescription::setDescription(const QString& description)
-{
-  Q_D(ctkCmdLineModuleDescription);
-  d->Description = description;
-}
-
-//----------------------------------------------------------------------------
 QString ctkCmdLineModuleDescription::description() const
 {
-  Q_D(const ctkCmdLineModuleDescription);
   return d->Description;
 }
 
 //----------------------------------------------------------------------------
-void ctkCmdLineModuleDescription::setVersion(const QString& version)
-{
-  Q_D(ctkCmdLineModuleDescription);
-  d->Version = version;
-}
-
-//----------------------------------------------------------------------------
 QString ctkCmdLineModuleDescription::version() const
 {
-  Q_D(const ctkCmdLineModuleDescription);
   return d->Version;
 }
 
 //----------------------------------------------------------------------------
-void ctkCmdLineModuleDescription::setDocumentationURL(const QString& documentationURL)
-{
-  Q_D(ctkCmdLineModuleDescription);
-  d->DocumentationURL = documentationURL;
-}
-
-//----------------------------------------------------------------------------
 QString ctkCmdLineModuleDescription::documentationURL() const
 {
-  Q_D(const ctkCmdLineModuleDescription);
   return d->DocumentationURL;
 }
 
 //----------------------------------------------------------------------------
-void ctkCmdLineModuleDescription::setLicense(const QString& license)
-{
-  Q_D(ctkCmdLineModuleDescription);
-  d->License = license;
-}
-
-//----------------------------------------------------------------------------
 QString ctkCmdLineModuleDescription::license() const
 {
-  Q_D(const ctkCmdLineModuleDescription);
   return d->License;
 }
 
 //----------------------------------------------------------------------------
-void ctkCmdLineModuleDescription::setAcknowledgements(const QString& acknowledgements)
-{
-  Q_D(ctkCmdLineModuleDescription);
-  d->Acknowledgements = acknowledgements;
-}
-
-//----------------------------------------------------------------------------
 QString ctkCmdLineModuleDescription::acknowledgements() const
 {
-  Q_D(const ctkCmdLineModuleDescription);
   return d->Acknowledgements;
 }
 
 //----------------------------------------------------------------------------
-void ctkCmdLineModuleDescription::setContributor(const QString& contributor)
-{
-  Q_D(ctkCmdLineModuleDescription);
-  d->Contributor = contributor;
-}
-
-//----------------------------------------------------------------------------
 QString ctkCmdLineModuleDescription::contributor() const
 {
-  Q_D(const ctkCmdLineModuleDescription);
   return d->Contributor;
 }
 
 //----------------------------------------------------------------------------
-void ctkCmdLineModuleDescription::setLocation(const QString& target)
-{
-  Q_D(ctkCmdLineModuleDescription);
-  d->Location = target;
-}
-
-//----------------------------------------------------------------------------
-QString ctkCmdLineModuleDescription::location() const
-{
-  Q_D(const ctkCmdLineModuleDescription);
-  return d->Location;
-}
-
-//----------------------------------------------------------------------------
-void ctkCmdLineModuleDescription::setLogo(const QIcon& logo)
-{
-  Q_D(ctkCmdLineModuleDescription);
-  d->Logo = logo;
-}
-
-//----------------------------------------------------------------------------
 QIcon ctkCmdLineModuleDescription::logo() const
 {
-  Q_D(const ctkCmdLineModuleDescription);
   return d->Logo;
 }
 
 //----------------------------------------------------------------------------
-void ctkCmdLineModuleDescription::addParameterGroup(ctkCmdLineModuleParameterGroup* group)
+QList<ctkCmdLineModuleParameterGroup> ctkCmdLineModuleDescription::parameterGroups() const
 {
-  Q_D(ctkCmdLineModuleDescription);
-  d->ParameterGroups.push_back(group);
-}
-
-//----------------------------------------------------------------------------
-QList<ctkCmdLineModuleParameterGroup*> ctkCmdLineModuleDescription::parameterGroups() const
-{
-  Q_D(const ctkCmdLineModuleDescription);
   return d->ParameterGroups;
 }
 
 //----------------------------------------------------------------------------
-void ctkCmdLineModuleDescription::setParameterGroups(const QList<ctkCmdLineModuleParameterGroup*>& groups)
-{
-  Q_D(ctkCmdLineModuleDescription);
-  d->ParameterGroups = groups;
-}
-
-//----------------------------------------------------------------------------
 bool ctkCmdLineModuleDescription::hasParameter(const QString& name) const
 {
-  Q_D(const ctkCmdLineModuleDescription);
   // iterate over each parameter group
-  foreach(const ctkCmdLineModuleParameterGroup* group, d->ParameterGroups)
-  {
-    if (group->hasParameter(name)) return true;
-  }
-  return false;
-}
-
-//----------------------------------------------------------------------------
-ctkCmdLineModuleParameter* ctkCmdLineModuleDescription::parameter(const QString& name) const
-{
-  Q_D(const ctkCmdLineModuleDescription);
-  foreach(const ctkCmdLineModuleParameterGroup* group, d->ParameterGroups)
-  {
-    ctkCmdLineModuleParameter* param = group->parameter(name);
-    if (param) return param;
-  }
-  return 0;
-}
-
-//----------------------------------------------------------------------------
-bool ctkCmdLineModuleDescription::hasReturnParameters() const
-{
-  Q_D(const ctkCmdLineModuleDescription);
-  // iterate over each parameter group
-  foreach(const ctkCmdLineModuleParameterGroup* group, d->ParameterGroups)
-  {
-    if (group->hasReturnParameters()) return true;
-  }
-  return false;
-}
-
-//----------------------------------------------------------------------------
-bool ctkCmdLineModuleDescription::setParameterDefaultValue(const QString& name,
-                                                    const QString& value)
-{
-  ctkCmdLineModuleParameter* param = parameter(name);
-  if (param)
+  foreach(const ctkCmdLineModuleParameterGroup group, d->ParameterGroups)
   {
-    param->setDefaultValue(value);
-    return true;
+    if (group.hasParameter(name)) return true;
   }
   return false;
 }
 
 //----------------------------------------------------------------------------
-bool ctkCmdLineModuleDescription ::readParameterFile(const QString& filename)
+ctkCmdLineModuleParameter ctkCmdLineModuleDescription::parameter(const QString& name) const
 {
-  bool modified = false;
-
-  QFile file(filename);
-  if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
-  {
-    std::cout << "Parameter file " << filename.toStdString( ) << " could not be opened." << '\n';
-    return false;
-  }
-
-  QTextStream in(&file);
-  while (!in.atEnd())
+  foreach(const ctkCmdLineModuleParameterGroup group, d->ParameterGroups)
   {
-    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 )
+    if (group.hasParameter(name))
     {
-      continue;
-    }
-    value = list[ 1 ].trimmed();
-
-    
-    // std::cout << "key=" << key << ", value=" << value << "!" << endl;
-
-    ctkCmdLineModuleParameter* param = this->parameter(key);
-    if (param)
-    {
-      if (value != param->defaultValue())
-      {
-        param->setDefaultValue(value);
-        modified = true;
-
-        // multiple="true" may have to be handled differently
-      }
+      return group.parameter(name);
     }
   }
-
-  return modified;
+  throw ctkInvalidArgumentException(QString("No parameter named \"%1\" available.").arg(name));
 }
 
 //----------------------------------------------------------------------------
-bool ctkCmdLineModuleDescription::
-writeParameterFile(const QString& filename, bool withHandlesToBulkParameters)const
+bool ctkCmdLineModuleDescription::hasReturnParameters() const
 {
-  Q_D(const ctkCmdLineModuleDescription);
-
-  QFile rtp(filename);
-
-  if (!rtp.open(QIODevice::WriteOnly | QIODevice::Text))
-    {
-    std::cout << "Parameter file " << filename.toStdString() << " could not be opened for writing." << '\n';
-    return false;
-    }
-
-  QTextStream in(&rtp);
   // iterate over each parameter group
-  foreach(const ctkCmdLineModuleParameterGroup* group, d->ParameterGroups)
+  foreach(const ctkCmdLineModuleParameterGroup group, d->ParameterGroups)
   {
-    group->writeParameterFile(in, withHandlesToBulkParameters);
+    if (group.hasReturnParameters()) return true;
   }
-
-  return true;
+  return false;
 }
 
 //----------------------------------------------------------------------------
@@ -358,17 +146,12 @@ QTextStream & operator<<(QTextStream &os, const ctkCmdLineModuleDescription &mod
   os << "License: " << module.license() << '\n';
   os << "Contributor: " << module.contributor() << '\n';
   os << "Acknowledgements: " << module.acknowledgements() << '\n';
-  os << "Location: " << module.location() << '\n';
   //os << "Logo: " << module.GetLogo() << '\n';
 
-  //os << "ProcessInformation: " << '\n'
-  //   << *(module.GetProcessInformation());
-
   os << "ParameterGroups: " << '\n';
-  foreach(const ctkCmdLineModuleParameterGroup* group, module.parameterGroups())
+  foreach(const ctkCmdLineModuleParameterGroup group, module.parameterGroups())
   {
-    os << *group;
+    os << group;
   }
   return os;
 }
-

+ 20 - 57
Libs/CommandLineModules/ctkCmdLineModuleDescription.h

@@ -21,105 +21,68 @@
 #ifndef __ctkCmdLineModuleDescription_h
 #define __ctkCmdLineModuleDescription_h
 
-#include <QIcon>
+#include <ctkCommandLineModulesExport.h>
 
-#include "ctkCmdLineModuleParameterGroup.h"
+#include <QList>
+#include <QSharedDataPointer>
+
+class QIcon;
+class QIODevice;
+class QTextStream;
 
 struct ctkCmdLineModuleDescriptionPrivate;
+class ctkCmdLineModuleParameterGroup;
+class ctkCmdLineModuleParameter;
 
 /**
-* 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.
-* - Location: This is path to the executable for the module
-*/
+ * Description of the parameters of a command line module.
+ *
+ * The parameters can be used for automated GUI generation or execution
+ * of the module.
+ */
 class CTK_CMDLINEMODULE_EXPORT ctkCmdLineModuleDescription
 {
-  Q_DECLARE_PRIVATE(ctkCmdLineModuleDescription)
 
 public:
 
   ~ctkCmdLineModuleDescription();
 
-  static ctkCmdLineModuleDescription* parse(QIODevice* input);
+  static ctkCmdLineModuleDescription parse(QIODevice* input);
 
-  void setCategory(const QString& cat);
   QString category() const;
 
-  void setTitle(const QString& title);
   QString title() const;
 
-  void setDescription(const QString& description);
   QString description() const;
 
-  void setVersion(const QString& version);
   QString version() const;
 
-  void setDocumentationURL(const QString& documentationURL);
   QString documentationURL() const;
 
-  void setLicense(const QString& license);
   QString license() const;
 
-  void setAcknowledgements(const QString& acknowledgements);
   QString acknowledgements() const;
 
-  void setContributor(const QString& contributor);
   QString contributor() const;
 
-  /// Set the location for the module.  This is path to the file for the module.
-  void setLocation(const QString& target);
-  /// Get the location for the module.  This is path to the file for the module.
-  QString location() const;
-
-  void setLogo(const QIcon& logo);
   QIcon logo() const;
 
-  void addParameterGroup(ctkCmdLineModuleParameterGroup* group);
-  QList<ctkCmdLineModuleParameterGroup*> parameterGroups() const;
-  void setParameterGroups(const QList<ctkCmdLineModuleParameterGroup*>& groups);
+  QList<ctkCmdLineModuleParameterGroup> parameterGroups() const;
 
   bool hasParameter(const QString& name) const;
 
-  ctkCmdLineModuleParameter* parameter(const QString& name) const;
+  ctkCmdLineModuleParameter parameter(const QString& name) const;
 
   // Does the module have any simple (primitive) return types?
   bool hasReturnParameters() const;
 
-  bool setParameterDefaultValue(const QString& name,
-                                const QString& value);
-
-//  const ModuleProcessInformation* processInformation() const
-//  {return &ProcessInformation;}
-
-//  ModuleProcessInformation* processInformation()
-//  {return &ProcessInformation;}
-
-  ///
-  /// 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:
 
-  ctkCmdLineModuleDescription();
+  friend class ctkCmdLineModuleXmlParser;
 
-  Q_DISABLE_COPY(ctkCmdLineModuleDescription)
+  ctkCmdLineModuleDescription();
 
-  ctkCmdLineModuleDescriptionPrivate * const d_ptr;
+  QSharedDataPointer<ctkCmdLineModuleDescriptionPrivate> d;
 
 };
 

+ 53 - 0
Libs/CommandLineModules/ctkCmdLineModuleDescriptionPrivate.h

@@ -0,0 +1,53 @@
+/*=============================================================================
+  
+  Library: CTK
+  
+  Copyright (c) German Cancer Research Center,
+    Division of Medical and Biological Informatics
+    
+  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 CTKCMDLINEMODULEDESCRIPTIONPRIVATE_H
+#define CTKCMDLINEMODULEDESCRIPTIONPRIVATE_H
+
+#include <QString>
+#include <QIcon>
+
+class ctkCmdLineModuleParameterGroup;
+
+struct ctkCmdLineModuleDescriptionPrivate : public QSharedData
+{
+  QString Title;
+  QString Category;
+  QString Description;
+  QString Version;
+  QString DocumentationURL;
+  QString License;
+  QString Acknowledgements;
+  QString Contributor;
+  QString Type;
+  QString Target;
+  QString Location;
+  QString AlternativeType;
+  QString AlternativeTarget;
+  QString AlternativeLocation;
+
+  QIcon Logo;
+
+  QList<ctkCmdLineModuleParameterGroup> ParameterGroups;
+
+};
+
+#endif // CTKCMDLINEMODULEDESCRIPTIONPRIVATE_H

+ 15 - 295
Libs/CommandLineModules/ctkCmdLineModuleParameter.cpp

@@ -19,96 +19,43 @@ limitations under the License.
 =============================================================================*/
 
 #include "ctkCmdLineModuleParameter.h"
+
+#include "ctkCmdLineModuleParameterPrivate.h"
+
 #include <QStringList>
+#include <QTextStream>
 
-struct ctkCmdLineModuleParameterPrivate
-{
-  ctkCmdLineModuleParameterPrivate()
-    : Hidden(false), Constraints(false), Index(-1), Multiple(false), Aggregate("false")
-  {}
-
-  QString Tag;
-  QString Name;
-  QString Description;
-  QString Label;
-  //QString CPPType;
-  QString Type;
-  QString Reference;
-  bool Hidden;
-  QString ArgType;
-  //QString StringToType;
-  QString Default;
-  QString Flag;
-  QString LongFlag;
-  bool Constraints;
-  QString Minimum;
-  QString Maximum;
-  QString Step;
-  QString Channel;
-  int Index;
-  int Multiple;
-  QString Aggregate;
-  QString FileExtensionsAsString;
-  QStringList FileExtensions;
-  QString CoordinateSystem;
-  QStringList Elements;
-  QString FlagAliasesAsString;
-  QString DeprecatedFlagAliasesAsString;
-  QString LongFlagAliasesAsString;
-  QString DeprecatedLongFlagAliasesAsString;
-  QStringList FlagAliases;
-  QStringList DeprecatedFlagAliases;
-  QStringList LongFlagAliases;
-  QStringList DeprecatedLongFlagAliases;
-
-  QStringList splitAndTrim(const QString& str, const QString& separator)
-  {
-    QStringList l = str.split(separator, QString::SkipEmptyParts);
-    l.removeDuplicates();
-    // trim the strings
-    QMutableStringListIterator i(l);
-    while(i.hasNext())
-    {
-      QString& n = i.next();
-      n = n.trimmed();
-    }
-    return l;
-  }
-};
 
 //----------------------------------------------------------------------------
 ctkCmdLineModuleParameter::ctkCmdLineModuleParameter()
-  : d_ptr(new ctkCmdLineModuleParameterPrivate)
+  : d(new ctkCmdLineModuleParameterPrivate())
 { }
 
 //----------------------------------------------------------------------------
 ctkCmdLineModuleParameter::~ctkCmdLineModuleParameter()
 {
-  delete d_ptr;
 }
 
 //----------------------------------------------------------------------------
-void ctkCmdLineModuleParameter::setTag(const QString& tag)
+ctkCmdLineModuleParameter::ctkCmdLineModuleParameter(const ctkCmdLineModuleParameter &other)
+  : d(other.d)
+{
+}
+
+//----------------------------------------------------------------------------
+ctkCmdLineModuleParameter& ctkCmdLineModuleParameter::operator=(const ctkCmdLineModuleParameter& other)
 {
-  Q_D(ctkCmdLineModuleParameter);
-  d->Tag = tag;
+  d = other.d;
+  return *this;
 }
 
 //----------------------------------------------------------------------------
 QString ctkCmdLineModuleParameter::tag() const
 {
-  Q_D(const ctkCmdLineModuleParameter);
   return d->Tag;
 }
 
 ////----------------------------------------------------------------------------
-//void ctkCmdLineModuleParameter::setCPPType(const QString& type)
-//{
-//  Q_D(ctkCmdLineModuleParameter);
-//  d->CPPType = type;
-//}
-
-////----------------------------------------------------------------------------
 //QString ctkCmdLineModuleParameter::cppType() const
 //{
 //  Q_D(const ctkCmdLineModuleParameter);
@@ -116,51 +63,26 @@ QString ctkCmdLineModuleParameter::tag() const
 //}
 
 //----------------------------------------------------------------------------
-void ctkCmdLineModuleParameter::setType(const QString& type)
-{
-  Q_D(ctkCmdLineModuleParameter);
-  d->Type = type;
-}
-
-//----------------------------------------------------------------------------
 QString ctkCmdLineModuleParameter::type() const
 {
-  Q_D(const ctkCmdLineModuleParameter);
   return d->Type;
 }
 
 //----------------------------------------------------------------------------
-void ctkCmdLineModuleParameter::setReference(const QString& ref)
-{
-  Q_D(ctkCmdLineModuleParameter);
-  d->Reference = ref;
-}
-
-//----------------------------------------------------------------------------
 QString ctkCmdLineModuleParameter::reference() const
 {
-  Q_D(const ctkCmdLineModuleParameter);
   return d->Reference;
 }
 
 //----------------------------------------------------------------------------
-void ctkCmdLineModuleParameter::setHidden(bool hidden)
-{
-  Q_D(ctkCmdLineModuleParameter);
-  d->Hidden = hidden;
-}
-
-//----------------------------------------------------------------------------
 bool ctkCmdLineModuleParameter::hidden() const
 {
-  Q_D(const ctkCmdLineModuleParameter);
   return d->Hidden;
 }
 
 //----------------------------------------------------------------------------
 bool ctkCmdLineModuleParameter::isReturnParameter() const
 {
-  Q_D(const ctkCmdLineModuleParameter);
   // could check for tag == float, int, float-vector, ...
   if (d->Channel == "output"
       && !this->isFlagParameter() && !this->isIndexParameter())
@@ -173,39 +95,22 @@ bool ctkCmdLineModuleParameter::isReturnParameter() const
 //----------------------------------------------------------------------------
 bool ctkCmdLineModuleParameter::isFlagParameter() const
 {
-  Q_D(const ctkCmdLineModuleParameter);
   return (d->Flag != "" || d->LongFlag != "");
 }
 
 //----------------------------------------------------------------------------
 bool ctkCmdLineModuleParameter::isIndexParameter() const
 {
-  Q_D(const ctkCmdLineModuleParameter);
   return (d->Index > -1);
 }
 
 //----------------------------------------------------------------------------
-void ctkCmdLineModuleParameter::setArgType(const QString& argType)
-{
-  Q_D(ctkCmdLineModuleParameter);
-  d->ArgType = argType;
-}
-
-//----------------------------------------------------------------------------
 QString ctkCmdLineModuleParameter::argType() const
 {
-  Q_D(const ctkCmdLineModuleParameter);
   return d->ArgType;
 }
 
 ////----------------------------------------------------------------------------
-//void ctkCmdLineModuleParameter::setStringToType(const QString& stringToType)
-//{
-//  Q_D(ctkCmdLineModuleParameter);
-//  d->StringToType = stringToType;
-//}
-
-////----------------------------------------------------------------------------
 //QString ctkCmdLineModuleParameter::stringToType() const
 //{
 //  Q_D(const ctkCmdLineModuleParameter);
@@ -213,343 +118,158 @@ QString ctkCmdLineModuleParameter::argType() const
 //}
 
 //----------------------------------------------------------------------------
-void ctkCmdLineModuleParameter::setName(const QString& name)
-{
-  Q_D(ctkCmdLineModuleParameter);
-  d->Name = name;
-}
-
-//----------------------------------------------------------------------------
 QString ctkCmdLineModuleParameter::name() const
 {
-  Q_D(const ctkCmdLineModuleParameter);
-  return d->Name;
-}
-
-//----------------------------------------------------------------------------
-void ctkCmdLineModuleParameter::setLongFlag(const QString& longFlag)
-{
-  Q_D(ctkCmdLineModuleParameter);
-  d->LongFlag = longFlag;
+ return d->Name;
 }
 
 //----------------------------------------------------------------------------
 QString ctkCmdLineModuleParameter::longFlag() const
 {
-  Q_D(const ctkCmdLineModuleParameter);
   return d->LongFlag;
 }
 
 //----------------------------------------------------------------------------
-void ctkCmdLineModuleParameter::setLongFlagAliasesAsString(const QString& aliases)
-{
-  Q_D(ctkCmdLineModuleParameter);
-  d->LongFlagAliases = d->splitAndTrim(aliases, ",");
-  d->LongFlagAliasesAsString = d->LongFlagAliases.join(", ");
-}
-
-//----------------------------------------------------------------------------
 QString ctkCmdLineModuleParameter::longFlagAliasesAsString() const
 {
-  Q_D(const ctkCmdLineModuleParameter);
   return d->LongFlagAliasesAsString;
 }
 
 //----------------------------------------------------------------------------
 QStringList ctkCmdLineModuleParameter::longFlagAliases() const
 {
-  Q_D(const ctkCmdLineModuleParameter);
   return d->LongFlagAliases;
 }
 
 //----------------------------------------------------------------------------
-void ctkCmdLineModuleParameter::setDeprecatedLongFlagAliasesAsString(const QString& aliases)
-{
-  Q_D(ctkCmdLineModuleParameter);
-  d->DeprecatedLongFlagAliases = d->splitAndTrim(aliases, ",");
-  d->DeprecatedLongFlagAliasesAsString = d->DeprecatedLongFlagAliases.join(", ");
-}
-
-//----------------------------------------------------------------------------
 QString ctkCmdLineModuleParameter::deprecatedLongFlagAliasesAsString() const
 {
-  Q_D(const ctkCmdLineModuleParameter);
   return d->DeprecatedLongFlagAliasesAsString;
 }
 
 //----------------------------------------------------------------------------
 QStringList ctkCmdLineModuleParameter::deprecatedLongFlagAliases() const
 {
-  Q_D(const ctkCmdLineModuleParameter);
   return d->DeprecatedLongFlagAliases;
 }
 
 //----------------------------------------------------------------------------
-void ctkCmdLineModuleParameter::setLabel(const QString& label)
-{
-  Q_D(ctkCmdLineModuleParameter);
-  d->Label = label;
-}
-
-//----------------------------------------------------------------------------
 QString ctkCmdLineModuleParameter::label() const
 {
-  Q_D(const ctkCmdLineModuleParameter);
   return d->Label;
 }
 
 //----------------------------------------------------------------------------
-void ctkCmdLineModuleParameter::setConstraints(bool constraints)
-{
-  Q_D(ctkCmdLineModuleParameter);
-  d->Constraints = constraints;
-}
-
-//----------------------------------------------------------------------------
 bool ctkCmdLineModuleParameter::constraints() const
 {
-  Q_D(const ctkCmdLineModuleParameter);
   return d->Constraints;
 }
 
 //----------------------------------------------------------------------------
-void ctkCmdLineModuleParameter::setMaximum(const QString& maximum)
-{
-  Q_D(ctkCmdLineModuleParameter);
-  d->Maximum = maximum;
-}
-
-//----------------------------------------------------------------------------
 QString ctkCmdLineModuleParameter::maximum() const
 {
-  Q_D(const ctkCmdLineModuleParameter);
   return d->Maximum;
 }
 
 //----------------------------------------------------------------------------
-void ctkCmdLineModuleParameter::setMinimum(const QString& minimum)
-{
-  Q_D(ctkCmdLineModuleParameter);
-  d->Minimum = minimum;
-}
-
-//----------------------------------------------------------------------------
 QString ctkCmdLineModuleParameter::minimum() const
 {
-  Q_D(const ctkCmdLineModuleParameter);
   return d->Minimum;
 }
 
 //----------------------------------------------------------------------------
-void ctkCmdLineModuleParameter::setStep(const QString& step)
-{
-  Q_D(ctkCmdLineModuleParameter);
-  d->Step = step;
-}
-
-//----------------------------------------------------------------------------
 QString ctkCmdLineModuleParameter::step() const
 {
-  Q_D(const ctkCmdLineModuleParameter);
   return d->Step;
 }
 
 //----------------------------------------------------------------------------
-void ctkCmdLineModuleParameter::setDescription(const QString& description)
-{
-  Q_D(ctkCmdLineModuleParameter);
-  d->Description = description;
-}
-
-//----------------------------------------------------------------------------
 QString ctkCmdLineModuleParameter::description() const
 {
-  Q_D(const ctkCmdLineModuleParameter);
   return d->Description;
 }
 
 //----------------------------------------------------------------------------
-void ctkCmdLineModuleParameter::setChannel(const QString& channel)
-{
-  Q_D(ctkCmdLineModuleParameter);
-  d->Channel = channel;
-}
-
-//----------------------------------------------------------------------------
 QString ctkCmdLineModuleParameter::channel() const
 {
-  Q_D(const ctkCmdLineModuleParameter);
   return d->Channel;
 }
 
 //----------------------------------------------------------------------------
-void ctkCmdLineModuleParameter::setIndex(int index)
-{
-  Q_D(ctkCmdLineModuleParameter);
-  d->Index = index;
-}
-
-//----------------------------------------------------------------------------
 int ctkCmdLineModuleParameter::index() const
 {
-  Q_D(const ctkCmdLineModuleParameter);
   return d->Index;
 }
 
 //----------------------------------------------------------------------------
-void ctkCmdLineModuleParameter::setDefaultValue(const QString& def)
-{
-  Q_D(ctkCmdLineModuleParameter);
-  d->Default = def;
-}
-
-//----------------------------------------------------------------------------
 QString ctkCmdLineModuleParameter::defaultValue() const
 {
-  Q_D(const ctkCmdLineModuleParameter);
   return d->Default;
 }
 
 //----------------------------------------------------------------------------
-void ctkCmdLineModuleParameter::setFlag(const QString& flag)
-{
-  Q_D(ctkCmdLineModuleParameter);
-  d->Flag = flag;
-}
-
-//----------------------------------------------------------------------------
 QString ctkCmdLineModuleParameter::flag() const
 {
-  Q_D(const ctkCmdLineModuleParameter);
   return d->Flag;
 }
 
 //----------------------------------------------------------------------------
-void ctkCmdLineModuleParameter::setFlagAliasesAsString(const QString& aliases)
-{
-  Q_D(ctkCmdLineModuleParameter);
-  d->FlagAliases = d->splitAndTrim(aliases, ",");
-  d->FlagAliasesAsString = d->FlagAliases.join(", ");
-}
-
-//----------------------------------------------------------------------------
 QString ctkCmdLineModuleParameter::flagAliasesAsString() const
 {
-  Q_D(const ctkCmdLineModuleParameter);
   return d->FlagAliasesAsString;
 }
 
 //----------------------------------------------------------------------------
 QStringList ctkCmdLineModuleParameter::flagAliases() const
 {
-  Q_D(const ctkCmdLineModuleParameter);
   return d->FlagAliases;
 }
 
 //----------------------------------------------------------------------------
-void ctkCmdLineModuleParameter::setDeprecatedFlagAliasesAsString(const QString& aliases)
-{
-  Q_D(ctkCmdLineModuleParameter);
-  d->DeprecatedFlagAliases = d->splitAndTrim(aliases, ",");
-  d->DeprecatedFlagAliasesAsString = d->DeprecatedFlagAliases.join(", ");
-}
-
-//----------------------------------------------------------------------------
 QString ctkCmdLineModuleParameter::deprecatedFlagAliasesAsString() const
 {
-  Q_D(const ctkCmdLineModuleParameter);
   return d->DeprecatedFlagAliasesAsString;
 }
 
 //----------------------------------------------------------------------------
 QStringList ctkCmdLineModuleParameter::deprecatedFlagAliases() const
 {
-  Q_D(const ctkCmdLineModuleParameter);
   return d->DeprecatedFlagAliases;
 }
 
 //----------------------------------------------------------------------------
-void ctkCmdLineModuleParameter::setMultiple(bool multiple)
-{
-  Q_D(ctkCmdLineModuleParameter);
-  d->Multiple = multiple;
-}
-
-//----------------------------------------------------------------------------
 bool ctkCmdLineModuleParameter::multiple() const
 {
-  Q_D(const ctkCmdLineModuleParameter);
   return d->Multiple;
 }
 
 //----------------------------------------------------------------------------
-void ctkCmdLineModuleParameter::setAggregate(const QString& aggregate)
-{
-  Q_D(ctkCmdLineModuleParameter);
-  d->Aggregate = aggregate;
-}
-
-//----------------------------------------------------------------------------
 QString ctkCmdLineModuleParameter::aggregate() const
 {
-  Q_D(const ctkCmdLineModuleParameter);
   return d->Aggregate;
 }
 
 //----------------------------------------------------------------------------
-void ctkCmdLineModuleParameter::setFileExtensionsAsString(const QString& extensions)
-{
-  Q_D(ctkCmdLineModuleParameter);
-  d->FileExtensions = d->splitAndTrim(extensions, ",");
-  d->FileExtensionsAsString = d->FileExtensions.join(",");
-}
-
-//----------------------------------------------------------------------------
 QString ctkCmdLineModuleParameter::fileExtensionsAsString() const
 {
-  Q_D(const ctkCmdLineModuleParameter);
   return d->FileExtensionsAsString;
 }
 
 //----------------------------------------------------------------------------
 QStringList ctkCmdLineModuleParameter::fileExtensions() const
 {
-  Q_D(const ctkCmdLineModuleParameter);
   return d->FileExtensions;
 }
 
 //----------------------------------------------------------------------------
-void ctkCmdLineModuleParameter::setCoordinateSystem(const QString& coordinateSystem)
-{
-  Q_D(ctkCmdLineModuleParameter);
-  d->CoordinateSystem = coordinateSystem;
-}
-
-//----------------------------------------------------------------------------
 QString ctkCmdLineModuleParameter::coordinateSystem() const
 {
-  Q_D(const ctkCmdLineModuleParameter);
   return d->CoordinateSystem;
 }
 
 //----------------------------------------------------------------------------
-void ctkCmdLineModuleParameter::addElement(const QString &elem)
-{
-  Q_D(ctkCmdLineModuleParameter);
-  d->Elements.push_back(elem);
-}
-
-//----------------------------------------------------------------------------
-void ctkCmdLineModuleParameter::setElements(const QStringList& elems)
-{
-  Q_D(ctkCmdLineModuleParameter);
-  d->Elements = elems;
-}
-
-//----------------------------------------------------------------------------
 QStringList ctkCmdLineModuleParameter::elements() const
 {
-  Q_D(const ctkCmdLineModuleParameter);
   return d->Elements;
 }
 

+ 12 - 33
Libs/CommandLineModules/ctkCmdLineModuleParameter.h

@@ -23,7 +23,10 @@
 
 #include "ctkCommandLineModulesExport.h"
 
-#include <QTextStream>
+#include <QSharedDataPointer>
+
+class QTextStream;
+class QStringList;
 
 class ctkCmdLineModuleParameterPrivate;
 
@@ -38,26 +41,22 @@ class ctkCmdLineModuleParameterPrivate;
  */
 class CTK_CMDLINEMODULE_EXPORT ctkCmdLineModuleParameter
 {
-  Q_DECLARE_PRIVATE(ctkCmdLineModuleParameter)
 
 public:
 
-  ctkCmdLineModuleParameter();
+  ctkCmdLineModuleParameter(const ctkCmdLineModuleParameter& other);
   ~ctkCmdLineModuleParameter();
 
-  void setTag(const QString& tag);
+  ctkCmdLineModuleParameter& operator=(const ctkCmdLineModuleParameter& other);
+
   QString tag() const;
 
-//  void setCPPType(const QString& type);
 //  QString cppType() const;
 
-  void setType(const QString& type);
   QString type() const;
 
-  void setReference(const QString& ref);
   QString reference() const;
 
-  void setHidden(bool hidden);
   bool hidden() const;
 
   // Simple return types are parameters on output channel with no
@@ -70,86 +69,66 @@ public:
   // Is an index type?
   bool isIndexParameter() const;
 
-  void setArgType(const QString& argType);
   QString argType() const;
 
   //void setStringToType(const QString& stringToType);
   //QString stringToType() const;
 
-  void setName(const QString& name);
   QString name() const;
 
-  void setLongFlag(const QString& longFlag);
   QString longFlag() const;
 
-  void setLongFlagAliasesAsString(const QString& aliases);
   QString longFlagAliasesAsString() const;
   QStringList longFlagAliases() const;
 
-  void setDeprecatedLongFlagAliasesAsString(const QString& aliases);
   QString deprecatedLongFlagAliasesAsString() const;
   QStringList deprecatedLongFlagAliases() const;
 
-  void setLabel(const QString& label);
   QString label() const;
 
-  void setConstraints(bool constraints);
   bool constraints() const;
 
-  void setMaximum(const QString& maximum);
   QString maximum() const;
 
-  void setMinimum(const QString& minimum);
   QString minimum() const;
 
-  void setStep(const QString& step);
   QString step() const;
 
-  void setDescription(const QString& description);
   QString description() const;
 
-  void setChannel(const QString& channel);
   QString channel() const;
 
-  void setIndex(int index);
   int index() const;
 
-  void setDefaultValue(const QString& def);
   QString defaultValue() const;
 
-  void setFlag(const QString& flag);
   QString flag() const;
 
-  void setFlagAliasesAsString(const QString& aliases);
   QString flagAliasesAsString() const;
   QStringList flagAliases() const;
 
-  void setDeprecatedFlagAliasesAsString(const QString& aliases);
   QString deprecatedFlagAliasesAsString() const;
   QStringList deprecatedFlagAliases() const;
 
-  void setMultiple(bool multiple);
   bool multiple() const;
 
-  void setAggregate(const QString& aggregate);
   QString aggregate() const;
 
-  void setFileExtensionsAsString(const QString& extensions);
   QString fileExtensionsAsString() const;
   QStringList fileExtensions() const;
 
-  void setCoordinateSystem(const QString& coordinateSystem);
   QString coordinateSystem() const;
 
-  void addElement(const QString& elem);
-  void setElements(const QStringList& elems);
   QStringList elements() const;
 
 private:
 
-  Q_DISABLE_COPY(ctkCmdLineModuleParameter)
+  friend class ctkCmdLineModuleParameterParser;
+  friend class ctkCmdLineModuleXmlParser;
+
+  ctkCmdLineModuleParameter();
 
-  ctkCmdLineModuleParameterPrivate * const d_ptr;
+  QSharedDataPointer<ctkCmdLineModuleParameterPrivate> d;
 };
 
 CTK_CMDLINEMODULE_EXPORT QTextStream& operator<<(QTextStream& os, const ctkCmdLineModuleParameter& parameter);

+ 26 - 75
Libs/CommandLineModules/ctkCmdLineModuleParameterGroup.cpp

@@ -20,117 +20,89 @@ limitations under the License.
 
 #include "ctkCmdLineModuleParameterGroup.h"
 
-struct ctkCmdLineModuleParameterGroupPrivate
-{
-  ~ctkCmdLineModuleParameterGroupPrivate()
-  {
-    qDeleteAll(Parameters);
-  }
+#include "ctkCmdLineModuleParameter.h"
+#include "ctkCmdLineModuleParameterGroupPrivate.h"
+
+#include "ctkException.h"
 
-  QString Label;
-  QString Description;
-  bool Advanced;
-  QList<ctkCmdLineModuleParameter*> Parameters;
-};
+#include <QTextStream>
 
 //----------------------------------------------------------------------------
 ctkCmdLineModuleParameterGroup::ctkCmdLineModuleParameterGroup()
-  : d_ptr(new ctkCmdLineModuleParameterGroupPrivate())
+  : d(new ctkCmdLineModuleParameterGroupPrivate())
 {
 }
 
 //----------------------------------------------------------------------------
-ctkCmdLineModuleParameterGroup::~ctkCmdLineModuleParameterGroup()
+ctkCmdLineModuleParameterGroup::ctkCmdLineModuleParameterGroup(const ctkCmdLineModuleParameterGroup& other)
+  : d(other.d)
 {
-  delete d_ptr;
 }
 
 //----------------------------------------------------------------------------
-void ctkCmdLineModuleParameterGroup::setLabel(const QString& label)
+ctkCmdLineModuleParameterGroup::~ctkCmdLineModuleParameterGroup()
 {
-  Q_D(ctkCmdLineModuleParameterGroup);
-  d->Label = label;
+
 }
 
 //----------------------------------------------------------------------------
-QString ctkCmdLineModuleParameterGroup::label() const
+ctkCmdLineModuleParameterGroup& ctkCmdLineModuleParameterGroup::operator=(const ctkCmdLineModuleParameterGroup& other)
 {
-  Q_D(const ctkCmdLineModuleParameterGroup);
-  return d->Label;
+  d = other.d;
+  return *this;
 }
 
 //----------------------------------------------------------------------------
-void ctkCmdLineModuleParameterGroup::setDescription(const QString& description)
+QString ctkCmdLineModuleParameterGroup::label() const
 {
-  Q_D(ctkCmdLineModuleParameterGroup);
-  d->Description = description;
+  return d->Label;
 }
 
 //----------------------------------------------------------------------------
 QString ctkCmdLineModuleParameterGroup::description() const
 {
-  Q_D(const ctkCmdLineModuleParameterGroup);
   return d->Description;
 }
 
 //----------------------------------------------------------------------------
-void ctkCmdLineModuleParameterGroup::setAdvanced(bool advanced)
-{
-  Q_D(ctkCmdLineModuleParameterGroup);
-  d->Advanced = advanced;
-}
-
-//----------------------------------------------------------------------------
 bool ctkCmdLineModuleParameterGroup::advanced() const
 {
-  Q_D(const ctkCmdLineModuleParameterGroup);
   return d->Advanced;
 }
 
 //----------------------------------------------------------------------------
-void ctkCmdLineModuleParameterGroup::addParameter(ctkCmdLineModuleParameter* parameter)
+QList<ctkCmdLineModuleParameter> ctkCmdLineModuleParameterGroup::parameters() const
 {
-  Q_D(ctkCmdLineModuleParameterGroup);
-  d->Parameters.push_back(parameter);
-}
-
-//----------------------------------------------------------------------------
-QList<ctkCmdLineModuleParameter*> ctkCmdLineModuleParameterGroup::parameters() const
-{
-  Q_D(const ctkCmdLineModuleParameterGroup);
   return d->Parameters;
 }
 
 //----------------------------------------------------------------------------
 bool ctkCmdLineModuleParameterGroup::hasParameter(const QString& name) const
 {
-  Q_D(const ctkCmdLineModuleParameterGroup);
-  foreach(const ctkCmdLineModuleParameter* param, d->Parameters)
+  foreach(const ctkCmdLineModuleParameter param, d->Parameters)
   {
-    if (param->name() == name) return true;
+    if (param.name() == name) return true;
   }
   return false;
 }
 
 //----------------------------------------------------------------------------
-ctkCmdLineModuleParameter* ctkCmdLineModuleParameterGroup::parameter(const QString& name) const
+ctkCmdLineModuleParameter ctkCmdLineModuleParameterGroup::parameter(const QString& name) const
 {
-  Q_D(const ctkCmdLineModuleParameterGroup);
-  foreach(ctkCmdLineModuleParameter* param, d->Parameters)
+  foreach(const ctkCmdLineModuleParameter param, d->Parameters)
   {
-    if (param->name() == name) return param;
+    if (param.name() == name) return param;
   }
-  return 0;
+  throw ctkInvalidArgumentException(QString("No parameter group named \"%1\" available.").arg(name));
 }
 
 //----------------------------------------------------------------------------
 bool ctkCmdLineModuleParameterGroup::hasReturnParameters() const
 {
-  Q_D(const ctkCmdLineModuleParameterGroup);
   // iterate over each parameter in d group
-  foreach(const ctkCmdLineModuleParameter* param, d->Parameters)
+  foreach(const ctkCmdLineModuleParameter param, d->Parameters)
   {
-    if (param->isReturnParameter())
+    if (param.isReturnParameter())
     {
       return true;
     }
@@ -139,36 +111,15 @@ bool ctkCmdLineModuleParameterGroup::hasReturnParameters() const
 }
 
 //----------------------------------------------------------------------------
-bool ctkCmdLineModuleParameterGroup::writeParameterFile(QTextStream& in, bool withHandlesToBulkParameters) const
-{
-  Q_D(const ctkCmdLineModuleParameterGroup);
-  // iterate over each parameter in d group
-  foreach(const ctkCmdLineModuleParameter* param, d->Parameters)
-  {
-    // write out all parameters or just the ones that are not bulk parameters
-    QString tag = param->tag();
-    if (withHandlesToBulkParameters ||
-        !(tag == "image" || tag == "geometry" || tag == "transform" ||
-          tag == "table" || tag == "measurement" ||
-          tag == "point" || tag == "region"))  // point and region are special
-    {
-      in << param->name() << " = " << param->defaultValue() << endl;
-      // multiple="true" may have to be handled differently
-    }
-  }
-  return true;
-}
-
-//----------------------------------------------------------------------------
 QTextStream & operator<<(QTextStream &os, const ctkCmdLineModuleParameterGroup &group)
 { 
   os << "  Advanced: " << (group.advanced() ? "true" : "false") << '\n';
   os << "  Label: " << group.label() << '\n';
   os << "  Description: " << group.description() << '\n';
   os << "  Parameters: " << '\n';
-  foreach(ctkCmdLineModuleParameter* param, group.parameters())
+  foreach(const ctkCmdLineModuleParameter param, group.parameters())
   {
-    os << *param;
+    os << param;
   }
   return os;
 }

+ 17 - 14
Libs/CommandLineModules/ctkCmdLineModuleParameterGroup.h

@@ -21,8 +21,14 @@
 #ifndef __ctkCmdLineModuleParameterGroup_h
 #define __ctkCmdLineModuleParameterGroup_h
 
-#include "ctkCmdLineModuleParameter.h"
+#include "ctkCommandLineModulesExport.h"
 
+#include <QList>
+#include <QSharedDataPointer>
+
+class QTextStream;
+
+class ctkCmdLineModuleParameter;
 class ctkCmdLineModuleParameterGroupPrivate;
 
 /** 
@@ -31,38 +37,35 @@ class ctkCmdLineModuleParameterGroupPrivate;
 */
 class CTK_CMDLINEMODULE_EXPORT ctkCmdLineModuleParameterGroup
 {
-  Q_DECLARE_PRIVATE(ctkCmdLineModuleParameterGroup)
 
 public:
 
-  ctkCmdLineModuleParameterGroup();
+  ctkCmdLineModuleParameterGroup(const ctkCmdLineModuleParameterGroup& other);
   ~ctkCmdLineModuleParameterGroup();
-  
-  void setLabel(const QString& label);
+
+  ctkCmdLineModuleParameterGroup& operator=(const ctkCmdLineModuleParameterGroup& other);
+
   QString label() const;
 
-  void setDescription(const QString& description);
   QString description() const;
 
-  void setAdvanced(bool advanced);
   bool advanced() const;
 
-  void addParameter(ctkCmdLineModuleParameter* parameter);
-  QList<ctkCmdLineModuleParameter*> parameters() const;
+  QList<ctkCmdLineModuleParameter> parameters() const;
 
   bool hasParameter(const QString& name) const;
 
-  ctkCmdLineModuleParameter* parameter(const QString& name) const;
+  ctkCmdLineModuleParameter parameter(const QString& name) const;
 
   bool hasReturnParameters() const;
 
-  bool writeParameterFile(QTextStream& in, bool withHandlesToBulkParameters) const;
-  
 private:
 
-  Q_DISABLE_COPY(ctkCmdLineModuleParameterGroup)
+  friend class ctkCmdLineModuleXmlParser;
+
+  ctkCmdLineModuleParameterGroup();
 
-  ctkCmdLineModuleParameterGroupPrivate * const d_ptr;
+  QSharedDataPointer<ctkCmdLineModuleParameterGroupPrivate> d;
 };
 
 CTK_CMDLINEMODULE_EXPORT QTextStream & operator<<(QTextStream &os, const ctkCmdLineModuleParameterGroup& group);

+ 39 - 0
Libs/CommandLineModules/ctkCmdLineModuleParameterGroupPrivate.h

@@ -0,0 +1,39 @@
+/*=============================================================================
+  
+  Library: CTK
+  
+  Copyright (c) German Cancer Research Center,
+    Division of Medical and Biological Informatics
+    
+  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 CTKCMDLINEMODULEPARAMETERGROUPPRIVATE_H
+#define CTKCMDLINEMODULEPARAMETERGROUPPRIVATE_H
+
+#include <QSharedData>
+#include <QString>
+#include <QList>
+
+class ctkCmdLineModuleParameter;
+
+struct ctkCmdLineModuleParameterGroupPrivate : public QSharedData
+{
+  QString Label;
+  QString Description;
+  bool Advanced;
+  QList<ctkCmdLineModuleParameter> Parameters;
+};
+
+#endif // CTKCMDLINEMODULEPARAMETERGROUPPRIVATE_H

+ 55 - 54
Libs/CommandLineModules/ctkCmdLineModuleParameterParsers_p.h

@@ -25,6 +25,7 @@
 #include <QXmlStreamReader>
 
 #include "ctkCmdLineModuleParameter.h"
+#include "ctkCmdLineModuleParameterPrivate.h"
 
 namespace {
 
@@ -46,15 +47,15 @@ public:
 
   virtual ~ctkCmdLineModuleParameterParser() {}
 
-  virtual ctkCmdLineModuleParameter* parse(QXmlStreamReader &xmlReader)
+  virtual ctkCmdLineModuleParameter parse(QXmlStreamReader &xmlReader)
   {
-    ctkCmdLineModuleParameter* moduleParam = this->createModuleParameter();
+    ctkCmdLineModuleParameter moduleParam = this->createModuleParameter();
 
-    this->handleAttributes(moduleParam, xmlReader);
+    this->handleAttributes(moduleParam.d.data(), xmlReader);
 
     while(xmlReader.readNextStartElement())
     {
-      this->handleSubElement(moduleParam, xmlReader);
+      this->handleSubElement(moduleParam.d.data(), xmlReader);
     }
 
     return moduleParam;
@@ -62,18 +63,18 @@ public:
 
 protected:
 
-  virtual ctkCmdLineModuleParameter* createModuleParameter()
+  virtual ctkCmdLineModuleParameter createModuleParameter()
   {
-    return new ctkCmdLineModuleParameter;
+    return ctkCmdLineModuleParameter();
   }
 
-  virtual void handleAttributes(ctkCmdLineModuleParameter* moduleParam, QXmlStreamReader& xmlReader)
+  virtual void handleAttributes(ctkCmdLineModuleParameterPrivate* moduleParamPrivate, QXmlStreamReader& xmlReader)
   {
     // handle common attributes
-    moduleParam->setHidden(parseBooleanAttribute(xmlReader.attributes().value("hidden")));
+    moduleParamPrivate->Hidden = parseBooleanAttribute(xmlReader.attributes().value("hidden"));
   }
 
-  virtual bool handleSubElement(ctkCmdLineModuleParameter* moduleParam, QXmlStreamReader& xmlReader)
+  virtual bool handleSubElement(ctkCmdLineModuleParameterPrivate* moduleParamPrivate, QXmlStreamReader& xmlReader)
   {
     // handle common sub-elements
 
@@ -81,39 +82,39 @@ protected:
 
     if (name.compare("name", Qt::CaseInsensitive) == 0)
     {
-      moduleParam->setName(xmlReader.readElementText().trimmed());
+      moduleParamPrivate->Name = xmlReader.readElementText().trimmed();
     }
     else if (name.compare("description", Qt::CaseInsensitive) == 0)
     {
-      moduleParam->setDescription(xmlReader.readElementText().trimmed());
+      moduleParamPrivate->Description = xmlReader.readElementText().trimmed();
     }
     else if (name.compare("label", Qt::CaseInsensitive) == 0)
     {
-      moduleParam->setLabel(xmlReader.readElementText().trimmed());
+      moduleParamPrivate->Label = xmlReader.readElementText().trimmed();
     }
     else if (name.compare("default", Qt::CaseInsensitive) == 0)
     {
-      moduleParam->setDefaultValue(xmlReader.readElementText().trimmed());
+      moduleParamPrivate->Default = xmlReader.readElementText().trimmed();
     }
     else if (name.compare("flag", Qt::CaseInsensitive) == 0)
     {
       QString flag = xmlReader.readElementText().trimmed();
       if (flag.startsWith('-')) flag = flag.remove(0, 1);
-      moduleParam->setFlag(flag);
-      moduleParam->setFlagAliasesAsString(xmlReader.attributes().value("alias").toString());
-      moduleParam->setDeprecatedFlagAliasesAsString(xmlReader.attributes().value("deprecatedalias").toString());
+      moduleParamPrivate->Flag = flag;
+      moduleParamPrivate->FlagAliasesAsString = xmlReader.attributes().value("alias").toString();
+      moduleParamPrivate->DeprecatedFlagAliasesAsString = xmlReader.attributes().value("deprecatedalias").toString();
     }
     else if (name.compare("longflag", Qt::CaseInsensitive) == 0)
     {
       QString longFlag = xmlReader.readElementText().trimmed();
       if (longFlag.startsWith('-')) longFlag = longFlag.remove(0, 1);
-      moduleParam->setLongFlag(longFlag);
-      moduleParam->setLongFlagAliasesAsString(xmlReader.attributes().value("alias").toString());
-      moduleParam->setDeprecatedLongFlagAliasesAsString(xmlReader.attributes().value("deprecatedalias").toString());
+      moduleParamPrivate->LongFlag = longFlag;
+      moduleParamPrivate->LongFlagAliasesAsString = xmlReader.attributes().value("alias").toString();
+      moduleParamPrivate->DeprecatedLongFlagAliasesAsString = xmlReader.attributes().value("deprecatedalias").toString();
     }
     else if (name.compare("index", Qt::CaseInsensitive) == 0)
     {
-      moduleParam->setIndex(xmlReader.readElementText().toInt());
+      moduleParamPrivate->Index = xmlReader.readElementText().toInt();
     }
     else
     {
@@ -124,23 +125,23 @@ protected:
     return true;
   }
 
-  bool handleConstraintsElement(ctkCmdLineModuleParameter* moduleParam, QXmlStreamReader& xmlReader)
+  bool handleConstraintsElement(ctkCmdLineModuleParameterPrivate* moduleParamPrivate, QXmlStreamReader& xmlReader)
   {
-    moduleParam->setConstraints(true);
+    moduleParamPrivate->Constraints = true;
     while(xmlReader.readNextStartElement())
     {
       QStringRef constraintElem = xmlReader.name();
       if (constraintElem.compare("minimum", Qt::CaseInsensitive) == 0)
       {
-        moduleParam->setMinimum(xmlReader.readElementText().trimmed());
+        moduleParamPrivate->Minimum = xmlReader.readElementText().trimmed();
       }
       else if (constraintElem.compare("maximum", Qt::CaseInsensitive) == 0)
       {
-        moduleParam->setMaximum(xmlReader.readElementText().trimmed());
+        moduleParamPrivate->Maximum = xmlReader.readElementText().trimmed();
       }
       else if (constraintElem.compare("step", Qt::CaseInsensitive) == 0)
       {
-        moduleParam->setStep(xmlReader.readElementText().trimmed());
+        moduleParamPrivate->Step = xmlReader.readElementText().trimmed();
       }
       else
       {
@@ -157,10 +158,10 @@ class ctkCmdLineModuleMultipleParameterParser : public ctkCmdLineModuleParameter
 
 protected:
 
-  void handleAttributes(ctkCmdLineModuleParameter* moduleParam, QXmlStreamReader& xmlReader)
+  void handleAttributes(ctkCmdLineModuleParameterPrivate* moduleParamPrivate, QXmlStreamReader& xmlReader)
   {
-    ctkCmdLineModuleParameterParser::handleAttributes(moduleParam, xmlReader);
-    moduleParam->setHidden(parseBooleanAttribute(xmlReader.attributes().value("multiple")));
+    ctkCmdLineModuleParameterParser::handleAttributes(moduleParamPrivate, xmlReader);
+    moduleParamPrivate->Hidden = parseBooleanAttribute(xmlReader.attributes().value("multiple"));
   }
 };
 
@@ -169,17 +170,17 @@ class ctkCmdLineModuleScalarVectorParameterParser : public ctkCmdLineModuleParam
 
 protected:
 
-  bool handleSubElement(ctkCmdLineModuleParameter* moduleParam, QXmlStreamReader& xmlReader)
+  bool handleSubElement(ctkCmdLineModuleParameterPrivate* moduleParamPrivate, QXmlStreamReader& xmlReader)
   {
     QStringRef name = xmlReader.name();
 
     if (name.compare("constraints", Qt::CaseInsensitive) == 0)
     {
-      return handleConstraintsElement(moduleParam, xmlReader);
+      return handleConstraintsElement(moduleParamPrivate, xmlReader);
     }
     else
     {
-      return ctkCmdLineModuleParameterParser::handleSubElement(moduleParam, xmlReader);
+      return ctkCmdLineModuleParameterParser::handleSubElement(moduleParamPrivate, xmlReader);
     }
   }
 };
@@ -189,17 +190,17 @@ class ctkCmdLineModuleScalarParameterParser : public ctkCmdLineModuleMultiplePar
 
 protected:
 
-  bool handleSubElement(ctkCmdLineModuleParameter* moduleParam, QXmlStreamReader& xmlReader)
+  bool handleSubElement(ctkCmdLineModuleParameterPrivate* moduleParamPrivate, QXmlStreamReader& xmlReader)
   {
     QStringRef name = xmlReader.name();
 
     if (name.compare("constraints", Qt::CaseInsensitive) == 0)
     {
-      return handleConstraintsElement(moduleParam, xmlReader);
+      return handleConstraintsElement(moduleParamPrivate, xmlReader);
     }
     else
     {
-      return ctkCmdLineModuleMultipleParameterParser::handleSubElement(moduleParam, xmlReader);
+      return ctkCmdLineModuleMultipleParameterParser::handleSubElement(moduleParamPrivate, xmlReader);
     }
   }
 };
@@ -209,18 +210,18 @@ class ctkCmdLineModuleEnumerationParameterParser : public ctkCmdLineModuleParame
 
 protected:
 
-  bool handleSubElement(ctkCmdLineModuleParameter* moduleParam, QXmlStreamReader& xmlReader)
+  bool handleSubElement(ctkCmdLineModuleParameterPrivate* moduleParamPrivate, QXmlStreamReader& xmlReader)
   {
     QStringRef name = xmlReader.name();
 
     if (name.compare("element", Qt::CaseInsensitive) == 0)
     {
-      moduleParam->addElement(xmlReader.readElementText().trimmed());
+      moduleParamPrivate->Elements.push_back(xmlReader.readElementText().trimmed());
       return true;
     }
     else
     {
-      return ctkCmdLineModuleParameterParser::handleSubElement(moduleParam, xmlReader);
+      return ctkCmdLineModuleParameterParser::handleSubElement(moduleParamPrivate, xmlReader);
     }
   }
 };
@@ -230,10 +231,10 @@ class ctkCmdLineModulePointParameterParser : public ctkCmdLineModuleMultiplePara
 
 protected:
 
-  void handleAttributes(ctkCmdLineModuleParameter* moduleParam, QXmlStreamReader& xmlReader)
+  void handleAttributes(ctkCmdLineModuleParameterPrivate* moduleParamPrivate, QXmlStreamReader& xmlReader)
   {
-    ctkCmdLineModuleMultipleParameterParser::handleAttributes(moduleParam, xmlReader);
-    moduleParam->setCoordinateSystem(xmlReader.attributes().value("coordinateSystem").toString().trimmed());
+    ctkCmdLineModuleMultipleParameterParser::handleAttributes(moduleParamPrivate, xmlReader);
+    moduleParamPrivate->CoordinateSystem = xmlReader.attributes().value("coordinateSystem").toString().trimmed();
   }
 };
 
@@ -242,18 +243,18 @@ class ctkCmdLineModuleChannelParameterParser : public ctkCmdLineModuleMultiplePa
 
 protected:
 
-  bool handleSubElement(ctkCmdLineModuleParameter* moduleParam, QXmlStreamReader& xmlReader)
+  bool handleSubElement(ctkCmdLineModuleParameterPrivate* moduleParamPrivate, QXmlStreamReader& xmlReader)
   {
     QStringRef name = xmlReader.name();
 
     if (name.compare("channel", Qt::CaseInsensitive) == 0)
     {
-      moduleParam->setChannel(xmlReader.readElementText().trimmed());
+      moduleParamPrivate->Channel = xmlReader.readElementText().trimmed();
       return true;
     }
     else
     {
-      return ctkCmdLineModuleMultipleParameterParser::handleSubElement(moduleParam, xmlReader);
+      return ctkCmdLineModuleMultipleParameterParser::handleSubElement(moduleParamPrivate, xmlReader);
     }
   }
 };
@@ -263,10 +264,10 @@ class ctkCmdLineModuleFileParameterParser : public ctkCmdLineModuleChannelParame
 
 protected:
 
-  void handleAttributes(ctkCmdLineModuleParameter* moduleParam, QXmlStreamReader& xmlReader)
+  void handleAttributes(ctkCmdLineModuleParameterPrivate* moduleParamPrivate, QXmlStreamReader& xmlReader)
   {
-    ctkCmdLineModuleChannelParameterParser::handleAttributes(moduleParam, xmlReader);
-    moduleParam->setFileExtensionsAsString(xmlReader.attributes().value("fileExtensions").toString().trimmed());
+    ctkCmdLineModuleChannelParameterParser::handleAttributes(moduleParamPrivate, xmlReader);
+    moduleParamPrivate->FileExtensionsAsString =xmlReader.attributes().value("fileExtensions").toString().trimmed();
   }
 };
 
@@ -275,11 +276,11 @@ class ctkCmdLineModuleGeometryParameterParser : public ctkCmdLineModuleMultipleP
 
 protected:
 
-  void handleAttributes(ctkCmdLineModuleParameter* moduleParam, QXmlStreamReader& xmlReader)
+  void handleAttributes(ctkCmdLineModuleParameterPrivate* moduleParamPrivate, QXmlStreamReader& xmlReader)
   {
-    ctkCmdLineModuleMultipleParameterParser::handleAttributes(moduleParam, xmlReader);
-    moduleParam->setFileExtensionsAsString(xmlReader.attributes().value("fileExtensions").toString().trimmed());
-    moduleParam->setType(xmlReader.attributes().value("type").toString().trimmed());
+    ctkCmdLineModuleMultipleParameterParser::handleAttributes(moduleParamPrivate, xmlReader);
+    moduleParamPrivate->setFileExtensionsAsString(xmlReader.attributes().value("fileExtensions").toString().trimmed());
+    moduleParamPrivate->Type = xmlReader.attributes().value("type").toString().trimmed();
   }
 };
 
@@ -288,11 +289,11 @@ class ctkCmdLineModuleImageParameterParser : public ctkCmdLineModuleChannelParam
 
 protected:
 
-  void handleAttributes(ctkCmdLineModuleParameter* moduleParam, QXmlStreamReader& xmlReader)
+  void handleAttributes(ctkCmdLineModuleParameterPrivate* moduleParamPrivate, QXmlStreamReader& xmlReader)
   {
-    ctkCmdLineModuleChannelParameterParser::handleAttributes(moduleParam, xmlReader);
-    moduleParam->setFileExtensionsAsString(xmlReader.attributes().value("fileExtensions").toString().trimmed());
-    moduleParam->setType(xmlReader.attributes().value("type").toString().trimmed());
+    ctkCmdLineModuleChannelParameterParser::handleAttributes(moduleParamPrivate, xmlReader);
+    moduleParamPrivate->setFileExtensionsAsString(xmlReader.attributes().value("fileExtensions").toString().trimmed());
+    moduleParamPrivate->Type = xmlReader.attributes().value("type").toString().trimmed();
   }
 };
 

+ 46 - 0
Libs/CommandLineModules/ctkCmdLineModuleParameterPrivate.cpp

@@ -0,0 +1,46 @@
+/*=============================================================================
+  
+  Library: CTK
+  
+  Copyright (c) German Cancer Research Center,
+    Division of Medical and Biological Informatics
+    
+  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 "ctkCmdLineModuleParameterPrivate.h"
+
+ctkCmdLineModuleParameterPrivate::ctkCmdLineModuleParameterPrivate()
+  : Hidden(false), Constraints(false), Index(-1), Multiple(false), Aggregate("false")
+{}
+
+QStringList ctkCmdLineModuleParameterPrivate::splitAndTrim(const QString& str, const QString& separator)
+{
+  QStringList l = str.split(separator, QString::SkipEmptyParts);
+  l.removeDuplicates();
+  // trim the strings
+  QMutableStringListIterator i(l);
+  while(i.hasNext())
+  {
+    QString& n = i.next();
+    n = n.trimmed();
+  }
+  return l;
+}
+
+void ctkCmdLineModuleParameterPrivate::setFileExtensionsAsString(const QString& extensions)
+{
+  FileExtensions = splitAndTrim(extensions, ",");
+  FileExtensionsAsString = FileExtensions.join(",");
+}

+ 74 - 0
Libs/CommandLineModules/ctkCmdLineModuleParameterPrivate.h

@@ -0,0 +1,74 @@
+/*=============================================================================
+  
+  Library: CTK
+  
+  Copyright (c) German Cancer Research Center,
+    Division of Medical and Biological Informatics
+    
+  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 CTKCMDLINEMODULEPARAMETERPRIVATE_H
+#define CTKCMDLINEMODULEPARAMETERPRIVATE_H
+
+#include "ctkCmdLineModuleParameter.h"
+
+#include <QString>
+#include <QStringList>
+
+struct ctkCmdLineModuleParameterPrivate : public QSharedData
+{
+  ctkCmdLineModuleParameterPrivate();
+
+  QStringList splitAndTrim(const QString& str, const QString& separator);
+
+  void setFileExtensionsAsString(const QString& extensions);
+
+  QString Tag;
+  QString Name;
+  QString Description;
+  QString Label;
+  //QString CPPType;
+  QString Type;
+  QString Reference;
+  bool Hidden;
+  QString ArgType;
+  //QString StringToType;
+  QString Default;
+  QString Flag;
+  QString LongFlag;
+  bool Constraints;
+  QString Minimum;
+  QString Maximum;
+  QString Step;
+  QString Channel;
+  int Index;
+  int Multiple;
+  QString Aggregate;
+  QString FileExtensionsAsString;
+  QStringList FileExtensions;
+  QString CoordinateSystem;
+  QStringList Elements;
+  QString FlagAliasesAsString;
+  QString DeprecatedFlagAliasesAsString;
+  QString LongFlagAliasesAsString;
+  QString DeprecatedLongFlagAliasesAsString;
+  QStringList FlagAliases;
+  QStringList DeprecatedFlagAliases;
+  QStringList LongFlagAliases;
+  QStringList DeprecatedLongFlagAliases;
+
+};
+
+#endif // CTKCMDLINEMODULEPARAMETERPRIVATE_H

+ 38 - 38
Libs/CommandLineModules/ctkCmdLineModuleXmlParser.cpp

@@ -27,8 +27,13 @@ limitations under the License.
 
 // CTK includes
 #include "ctkCmdLineModuleDescription.h"
+#include "ctkCmdLineModuleDescriptionPrivate.h"
+#include "ctkCmdLineModuleParameterGroup.h"
+#include "ctkCmdLineModuleParameterGroupPrivate.h"
 #include "ctkCmdLineModuleParameterParsers_p.h"
 
+#include "ctkException.h"
+
 // STD includes
 #include <stdexcept>
 
@@ -44,7 +49,7 @@ public:
 
   void handleExecutableElement();
   void handleParametersElement();
-  ctkCmdLineModuleParameter* handleParameterElement();
+  ctkCmdLineModuleParameter handleParameterElement();
 
 private:
 
@@ -203,35 +208,35 @@ void ctkCmdLineModuleXmlParser::handleExecutableElement()
 
     if (name.compare("category", Qt::CaseInsensitive) == 0)
     {
-      _md->setCategory(_xmlReader.readElementText().trimmed());
+      _md->d->Category = _xmlReader.readElementText().trimmed();
     }
     else if (name.compare("title", Qt::CaseInsensitive) == 0)
     {
-      _md->setTitle(_xmlReader.readElementText().trimmed());
+      _md->d->Title = _xmlReader.readElementText().trimmed();
     }
     else if (name.compare("version", Qt::CaseInsensitive) == 0)
     {
-      _md->setVersion(_xmlReader.readElementText().trimmed());
+      _md->d->Version = _xmlReader.readElementText().trimmed();
     }
     else if (name.compare("documentation-url", Qt::CaseInsensitive) == 0)
     {
-      _md->setDocumentationURL(_xmlReader.readElementText().trimmed());
+      _md->d->DocumentationURL = _xmlReader.readElementText().trimmed();
     }
     else if (name.compare("license", Qt::CaseInsensitive) == 0)
     {
-      _md->setLicense(_xmlReader.readElementText().trimmed());
+      _md->d->License = _xmlReader.readElementText().trimmed();
     }
     else if (name.compare("acknowledgements", Qt::CaseInsensitive) == 0)
     {
-      _md->setAcknowledgements(_xmlReader.readElementText().trimmed());
+      _md->d->Acknowledgements = _xmlReader.readElementText().trimmed();
     }
     else if (name.compare("contributor", Qt::CaseInsensitive) == 0)
     {
-      _md->setContributor(_xmlReader.readElementText().trimmed());
+      _md->d->Contributor = _xmlReader.readElementText().trimmed();
     }
     else if (name.compare("description", Qt::CaseInsensitive) == 0)
     {
-      _md->setDescription(_xmlReader.readElementText().trimmed());
+      _md->d->Description = _xmlReader.readElementText().trimmed();
     }
     else if (name.compare("parameters", Qt::CaseInsensitive) == 0)
     {
@@ -249,9 +254,9 @@ void ctkCmdLineModuleXmlParser::handleExecutableElement()
 // ----------------------------------------------------------------------------
 void ctkCmdLineModuleXmlParser::handleParametersElement()
 {
-  ctkCmdLineModuleParameterGroup* group = new ctkCmdLineModuleParameterGroup();
+  ctkCmdLineModuleParameterGroup group;
 
-  group->setAdvanced(parseBooleanAttribute(_xmlReader.attributes().value("advanced")));
+  group.d->Advanced = parseBooleanAttribute(_xmlReader.attributes().value("advanced"));
 
   while(_xmlReader.readNextStartElement())
   {
@@ -259,63 +264,58 @@ void ctkCmdLineModuleXmlParser::handleParametersElement()
 
     if (name.compare("label", Qt::CaseInsensitive) == 0)
     {
-      group->setLabel(_xmlReader.readElementText().trimmed());
+      group.d->Label = _xmlReader.readElementText().trimmed();
     }
     else if (name.compare("description", Qt::CaseInsensitive) == 0)
     {
-      group->setDescription(_xmlReader.readElementText().trimmed());
+      group.d->Description = _xmlReader.readElementText().trimmed();
     }
     else
     {
-      ctkCmdLineModuleParameter* parameter = this->handleParameterElement();
-      if (parameter)
+      try
+      {
+        ctkCmdLineModuleParameter parameter = this->handleParameterElement();
+        group.d->Parameters.push_back(parameter);
+      }
+      catch (const ctkException& e)
       {
-        group->addParameter(parameter);
+        // Just print the exception and continue
+        qCritical() << e;
       }
     }
   }
 
-  _md->addParameterGroup(group);
+  _md->d->ParameterGroups.push_back(group);
 }
 
 // ----------------------------------------------------------------------------
-ctkCmdLineModuleParameter* ctkCmdLineModuleXmlParser::handleParameterElement()
+ctkCmdLineModuleParameter ctkCmdLineModuleXmlParser::handleParameterElement()
 {
   QString paramTag = _xmlReader.name().toString().toLower();
   ctkCmdLineModuleParameterParser* paramParser = _paramParsers[paramTag];
   if (paramParser == 0)
   {
     _xmlReader.skipCurrentElement();
-    qCritical() << "No parser for element" << paramTag << "available, line"
-                << _xmlReader.lineNumber() << ", column" << _xmlReader.columnNumber();
-    return 0;
+    QString msg = "No parser for element \"%1\" available, line %2, column %3";
+    throw ctkIllegalStateException(msg.arg(paramTag).arg(_xmlReader.lineNumber()).arg(_xmlReader.columnNumber()));
   }
   else
   {
-    ctkCmdLineModuleParameter* moduleParam = paramParser->parse(_xmlReader);
-    moduleParam->setTag(paramTag);
+    ctkCmdLineModuleParameter moduleParam = paramParser->parse(_xmlReader);
+    moduleParam.d->Tag = paramTag;
     return moduleParam;
   }
 }
 
 // ----------------------------------------------------------------------------
-ctkCmdLineModuleDescription* ctkCmdLineModuleDescription::parse(QIODevice* device)
+ctkCmdLineModuleDescription ctkCmdLineModuleDescription::parse(QIODevice* device)
 {
-  ctkCmdLineModuleDescription* moduleDescription = new ctkCmdLineModuleDescription();
-  ctkCmdLineModuleXmlParser parser(device, moduleDescription);
-
-  try
-  {
-    // Verify the xml is correct
-    parser.validate();
+  ctkCmdLineModuleDescription moduleDescription;
+  ctkCmdLineModuleXmlParser parser(device, &moduleDescription);
 
-    parser.doParse();
-  }
-  catch(...)
-  {
-    delete moduleDescription;
-    throw;
-  }
+  // Verify the xml is correct
+  parser.validate();
+  parser.doParse();
 
   return moduleDescription;
 }