Pārlūkot izejas kodu

Merge branch 'commandlineparser'

  ENH: Simplified the ctkCommandLineParser API
Jean-Christophe Fillion-Robin 15 gadi atpakaļ
vecāks
revīzija
1fe124f48a

+ 72 - 66
Libs/Core/Testing/Cpp/ctkCommandLineParserTest1.cpp

@@ -17,7 +17,9 @@ int ctkCommandLineParserTest1(int, char*[])
   arguments1 << "--test-string";
   arguments1 << "--test-string";
   arguments1 << "ctkrocks";
   arguments1 << "ctkrocks";
   ctkCommandLineParser parser1;
   ctkCommandLineParser parser1;
-  if (!parser1.parseArguments(arguments1))
+  bool ok = false;
+  parser1.parseArguments(arguments1, &ok);
+  if (!ok)
     {
     {
     qCritical() << "Test1 - Failed to parse arguments";
     qCritical() << "Test1 - Failed to parse arguments";
     return EXIT_FAILURE;
     return EXIT_FAILURE;
@@ -33,16 +35,17 @@ int ctkCommandLineParserTest1(int, char*[])
     return EXIT_FAILURE;
     return EXIT_FAILURE;
     }
     }
 
 
-  // Test2 - Check if addBooleanArgument() worked as expected
+  // Test2 - Check if addArgument() for a boolean workes as expected
   QStringList arguments2;
   QStringList arguments2;
   arguments2 << "ctkCommandLineParserTest1";
   arguments2 << "ctkCommandLineParserTest1";
   arguments2 << "--test-bool";
   arguments2 << "--test-bool";
   arguments2 << "--test-string";
   arguments2 << "--test-string";
   arguments2 << "ctkrocks";
   arguments2 << "ctkrocks";
-  bool testBool = false;
   ctkCommandLineParser parser2;
   ctkCommandLineParser parser2;
-  parser2.addBooleanArgument("--test-bool", 0, &testBool, "This is a test bool", false);
-  if (!parser2.parseArguments(arguments2))
+  parser2.addArgument("--test-bool", "", QVariant::Bool, "This is a test bool", false);
+  ok = false;
+  QHash<QString, QVariant> parsedArgs = parser2.parseArguments(arguments2, &ok);
+  if (!ok)
     {
     {
     qCritical() << "Test2 - Failed to parse arguments";
     qCritical() << "Test2 - Failed to parse arguments";
     return EXIT_FAILURE;
     return EXIT_FAILURE;
@@ -58,78 +61,72 @@ int ctkCommandLineParserTest1(int, char*[])
     return EXIT_FAILURE;
     return EXIT_FAILURE;
     }
     }
 
 
-  if (!testBool)
+  if (parsedArgs["--test-bool"].isNull() || !parsedArgs["--test-bool"].toBool())
     {
     {
     qCritical() << "Test2 - Failed to parse --test-bool";
     qCritical() << "Test2 - Failed to parse --test-bool";
     return EXIT_FAILURE;
     return EXIT_FAILURE;
     }
     }
 
 
-  // Test3 - check if addStringArgument(), addIntegerArgument() and addStringListArgument() works
+  // Test3 - check if adding QString, int, and QStringList arguments works
   QStringList arguments3;
   QStringList arguments3;
   arguments3 << "ctkCommandLineParserTest1";
   arguments3 << "ctkCommandLineParserTest1";
   arguments3 << "--test-string" << "TestingIsGood";
   arguments3 << "--test-string" << "TestingIsGood";
   arguments3 << "--test-string2"<< "CTKSuperRocks";
   arguments3 << "--test-string2"<< "CTKSuperRocks";
   arguments3 << "--test-integer"<< "-3";
   arguments3 << "--test-integer"<< "-3";
   arguments3 << "--test-stringlist"<< "item1" << "item2" << "item3";
   arguments3 << "--test-stringlist"<< "item1" << "item2" << "item3";
-  QString testString;
-  QString testString2;
-  int testInteger = 1;
-  QStringList testStringlist;
   ctkCommandLineParser parser3;
   ctkCommandLineParser parser3;
-  parser3.addStringArgument("--test-string", 0, &testString, "This is a test string");
-  parser3.addStringArgument("--test-string2", 0, &testString2, "This is a test string2", "CTKGood");
-  parser3.addIntegerArgument("--test-integer", 0, &testInteger, "This is a test integer");
-  parser3.addStringListArgument("--test-stringlist", 0, &testStringlist,
+  parser3.addArgument("--test-string", "", QVariant::String, "This is a test string");
+  parser3.addArgument("--test-string2", "", QVariant::String, "This is a test string2", "CTKGood");
+  parser3.addArgument("--test-integer", "", QVariant::Int, "This is a test integer");
+  parser3.addArgument("--test-stringlist", "", QVariant::StringList,
                                 "This is a test stringlist");
                                 "This is a test stringlist");
-  if (!parser3.parseArguments(arguments3))
+  ok = false;
+  parsedArgs = parser3.parseArguments(arguments3, &ok);
+  if (!ok)
     {
     {
     qCritical() << "Test3 - Failed to parse arguments";
     qCritical() << "Test3 - Failed to parse arguments";
     return EXIT_FAILURE;
     return EXIT_FAILURE;
     }
     }
 
 
   QString expectedTestString = "TestingIsGood";
   QString expectedTestString = "TestingIsGood";
-  if (testString != expectedTestString)
+  if (parsedArgs["--test-string"].toString() != expectedTestString)
     {
     {
-    qCritical() << "Test3 - Failed - testString" << testString
+    qCritical() << "Test3 - Failed - testString" << parsedArgs["--test-string"].toString()
         << ", expectedTestString" << expectedTestString;
         << ", expectedTestString" << expectedTestString;
     return EXIT_FAILURE;
     return EXIT_FAILURE;
     }
     }
 
 
   QString expectedTestString2 = "CTKSuperRocks";
   QString expectedTestString2 = "CTKSuperRocks";
-  if (testString2 != expectedTestString2)
+  if (parsedArgs["--test-string2"].toString() != expectedTestString2)
     {
     {
-    qCritical() << "Test3 - Failed - testString2" << testString2
+    qCritical() << "Test3 - Failed - testString2" << parsedArgs["--test-string2"].toString()
         << ", expectedTestString2" << expectedTestString2;
         << ", expectedTestString2" << expectedTestString2;
     return EXIT_FAILURE;
     return EXIT_FAILURE;
     }
     }
 
 
   int expectedTestInteger = -3;
   int expectedTestInteger = -3;
-  if (testInteger != expectedTestInteger)
+  if (parsedArgs["--test-integer"].toInt() != expectedTestInteger)
     {
     {
-    qCritical() << "Test3 - Failed - testInteger" << testInteger
+    qCritical() << "Test3 - Failed - testInteger" << parsedArgs["--test-integer"].toInt()
         << ", expectedTestInteger" << expectedTestInteger;
         << ", expectedTestInteger" << expectedTestInteger;
     return EXIT_FAILURE;
     return EXIT_FAILURE;
     }
     }
 
 
   QStringList expectedTestStringlist;
   QStringList expectedTestStringlist;
   expectedTestStringlist << "item1" << "item2" << "item3";
   expectedTestStringlist << "item1" << "item2" << "item3";
-  if (testStringlist != expectedTestStringlist)
+  if (parsedArgs["--test-stringlist"].toStringList() != expectedTestStringlist)
     {
     {
-    qCritical() << "Test3 - Failed - testStringlist" << testStringlist
+    qCritical() << "Test3 - Failed - testStringlist" << parsedArgs["--test-stringlist"].toStringList()
         << ", expectedTestStringlist" << expectedTestStringlist;
         << ", expectedTestStringlist" << expectedTestStringlist;
     return EXIT_FAILURE;
     return EXIT_FAILURE;
     }
     }
 
 
   // Test4 - check if helpText() works as expected
   // Test4 - check if helpText() works as expected
   ctkCommandLineParser parser4;
   ctkCommandLineParser parser4;
-  QString helpString;
-  QString helpString1;
-  QString helpString2;
-  QString helpString3;
-  parser4.addStringArgument("--help-string", 0, &helpString, "This is an help string");
-  parser4.addStringArgument("--help-string-med", 0, &helpString1, "");
-  parser4.addStringArgument("--help-string-long", "-hs2", &helpString2, "This is an help string too !");
-  parser4.addStringArgument(0, "-hs3", &helpString3, "This is an help string too for sure !?");
+  parser4.addArgument("--help-string", "", QVariant::String, "This is an help string");
+  parser4.addArgument("--help-string-med", "", QVariant::String, "");
+  parser4.addArgument("--help-string-long", "-hs2", QVariant::String, "This is an help string too !");
+  parser4.addArgument("", "-hs3", QVariant::String, "This is an help string too for sure !?");
 
 
   QString expectedHelpString;
   QString expectedHelpString;
   QTextStream streamExpectedHelpString(&expectedHelpString);
   QTextStream streamExpectedHelpString(&expectedHelpString);
@@ -170,32 +167,28 @@ int ctkCommandLineParserTest1(int, char*[])
     return EXIT_FAILURE;
     return EXIT_FAILURE;
     }
     }
 
 
-  bool test5Bool = false;
-  QString test5String;
-  int test5Int = 0;
-  QStringList test5List;
-  parser5.addStringListArgument("--list", 0, &test5List, "Test5 list");
+  parser5.addArgument("--list", "", QVariant::StringList, "Test5 list");
   if (!parser5.setExactMatchRegularExpression("--list","item[0-9]",
   if (!parser5.setExactMatchRegularExpression("--list","item[0-9]",
                                               "Element of the form item[0-9] are expected."))
                                               "Element of the form item[0-9] are expected."))
     {
     {
     qCritical() << "Test5 - Problem with setExactMatchRegularExpression(StringListArg)";
     qCritical() << "Test5 - Problem with setExactMatchRegularExpression(StringListArg)";
     return EXIT_FAILURE;
     return EXIT_FAILURE;
     }
     }
-  parser5.addStringArgument("--string", 0, &test5String, "Test5 string");
+  parser5.addArgument("--string", "", QVariant::String, "Test5 string");
   if (!parser5.setExactMatchRegularExpression("--string","ctkStop|ctkStart",
   if (!parser5.setExactMatchRegularExpression("--string","ctkStop|ctkStart",
                                               "ctkStop or ctkStart is expected."))
                                               "ctkStop or ctkStart is expected."))
     {
     {
     qCritical() << "Test5 - Problem with setExactMatchRegularExpression(StringArg)";
     qCritical() << "Test5 - Problem with setExactMatchRegularExpression(StringArg)";
     return EXIT_FAILURE;
     return EXIT_FAILURE;
     }
     }
-  parser5.addBooleanArgument("--bool", 0, &test5Bool, "Test5 bool");
+  parser5.addArgument("--bool", "", QVariant::Bool, "Test5 bool");
   if (parser5.setExactMatchRegularExpression("--bool",".*", "invalid"))
   if (parser5.setExactMatchRegularExpression("--bool",".*", "invalid"))
     {
     {
     qCritical() << "Test5 - Problem with setExactMatchRegularExpression(BooleanArg) - "
     qCritical() << "Test5 - Problem with setExactMatchRegularExpression(BooleanArg) - "
                    "The function should return false if a boolean argument is passed";
                    "The function should return false if a boolean argument is passed";
     return EXIT_FAILURE;
     return EXIT_FAILURE;
     }
     }
-  parser5.addIntegerArgument("--int", 0, &test5Int, "Test5 int");
+  parser5.addArgument("--int", "", QVariant::Int, "Test5 int");
   if (!parser5.setExactMatchRegularExpression("--int","[1-3]",
   if (!parser5.setExactMatchRegularExpression("--int","[1-3]",
                                               "Value 1, 2 or 3 is expected."))
                                               "Value 1, 2 or 3 is expected."))
     {
     {
@@ -209,7 +202,9 @@ int ctkCommandLineParserTest1(int, char*[])
   arguments5 << "--int"<< "2";
   arguments5 << "--int"<< "2";
   arguments5 << "--list"<< "item2" << "item3";
   arguments5 << "--list"<< "item2" << "item3";
   
   
-  if (!parser5.parseArguments(arguments5))
+  ok = false;
+  parser5.parseArguments(arguments5, &ok);
+  if (!ok)
     {
     {
     qCritical() << "Test5 - Failed to parse arguments";
     qCritical() << "Test5 - Failed to parse arguments";
     return EXIT_FAILURE;
     return EXIT_FAILURE;
@@ -221,7 +216,9 @@ int ctkCommandLineParserTest1(int, char*[])
   arguments5 << "--int"<< "2";
   arguments5 << "--int"<< "2";
   arguments5 << "--list"<< "item2" << "item3";
   arguments5 << "--list"<< "item2" << "item3";
 
 
-  if (parser5.parseArguments(arguments5))
+  ok = false;
+  parser5.parseArguments(arguments5, &ok);
+  if (ok)
     {
     {
     qCritical() << "Test5 - parseArguments() should return False - 'ctkStopp' isn't a valid string";
     qCritical() << "Test5 - parseArguments() should return False - 'ctkStopp' isn't a valid string";
     return EXIT_FAILURE;
     return EXIT_FAILURE;
@@ -244,7 +241,9 @@ int ctkCommandLineParserTest1(int, char*[])
   arguments5 << "--int"<< "4";
   arguments5 << "--int"<< "4";
   arguments5 << "--list"<< "item2" << "item3";
   arguments5 << "--list"<< "item2" << "item3";
 
 
-  if (parser5.parseArguments(arguments5))
+  ok = false;
+  parser5.parseArguments(arguments5, &ok);
+  if (ok)
     {
     {
     qCritical() << "Test5 - parseArguments() should return False - '4' isn't a valid int";
     qCritical() << "Test5 - parseArguments() should return False - '4' isn't a valid int";
     return EXIT_FAILURE;
     return EXIT_FAILURE;
@@ -267,7 +266,9 @@ int ctkCommandLineParserTest1(int, char*[])
   arguments5 << "--int"<< "2";
   arguments5 << "--int"<< "2";
   arguments5 << "--list"<< "item2" << "item10";
   arguments5 << "--list"<< "item2" << "item10";
 
 
-  if (parser5.parseArguments(arguments5))
+  ok = false;
+  parser5.parseArguments(arguments5, &ok);
+  if (ok)
     {
     {
     qCritical() << "Test5 - parseArguments() should return False "
     qCritical() << "Test5 - parseArguments() should return False "
                    "- 'item10' isn't a valid list element";
                    "- 'item10' isn't a valid list element";
@@ -287,17 +288,17 @@ int ctkCommandLineParserTest1(int, char*[])
     
     
   // Test6 - Check if the parser handle the case when value of parameter is omitted
   // Test6 - Check if the parser handle the case when value of parameter is omitted
   ctkCommandLineParser parser6;
   ctkCommandLineParser parser6;
-  QString test6String;
-  bool test6Bool = false;
-  parser6.addStringArgument("--string", 0, &test6String, "This is a string");
-  parser6.addBooleanArgument("--bool", 0, &test6Bool, "This is a bool");
+  parser6.addArgument("--string", "", QVariant::String, "This is a string");
+  parser6.addArgument("--bool", "", QVariant::Bool, "This is a bool");
   
   
   QStringList arguments6; 
   QStringList arguments6; 
   arguments6 << "ctkCommandLineParserTest1"
   arguments6 << "ctkCommandLineParserTest1"
              << "--string";
              << "--string";
   
   
   // since --string is missing a parameter, parseArgument is expected to fail
   // since --string is missing a parameter, parseArgument is expected to fail
-  if (parser6.parseArguments(arguments6))
+  ok = false;
+  parser6.parseArguments(arguments6, &ok);
+  if (ok)
     {
     {
     qCritical() << "Test6 - Problem with parseArguments()";
     qCritical() << "Test6 - Problem with parseArguments()";
     return EXIT_FAILURE;
     return EXIT_FAILURE;
@@ -310,20 +311,22 @@ int ctkCommandLineParserTest1(int, char*[])
   // Test7 - Check if addBooleanArgument and ignore_rest=true works as expected
   // Test7 - Check if addBooleanArgument and ignore_rest=true works as expected
   ctkCommandLineParser parser7;
   ctkCommandLineParser parser7;
   bool test7Bool = false;
   bool test7Bool = false;
-  parser7.addBooleanArgument("--bool", 0, &test7Bool, "This is a boolean",
+  parser7.addArgument("--bool", "", QVariant::Bool, "This is a boolean",
                              false /*defaultValue*/, true /* ignoreRest*/);
                              false /*defaultValue*/, true /* ignoreRest*/);
   QStringList arguments7;
   QStringList arguments7;
   arguments7 << "ctkCommandLineParserTest1";
   arguments7 << "ctkCommandLineParserTest1";
   arguments7 << "--bool";
   arguments7 << "--bool";
   arguments7 << expectedUnparsedArguments;
   arguments7 << expectedUnparsedArguments;
 
 
-  if (!parser7.parseArguments(arguments7))
+  ok = false;
+  parsedArgs = parser7.parseArguments(arguments7, &ok);
+  if (!ok)
     {
     {
     qCritical() << "Test7 - Failed to parse arguments";
     qCritical() << "Test7 - Failed to parse arguments";
     return EXIT_FAILURE;
     return EXIT_FAILURE;
     }
     }
   bool expectedTest7Bool = true;
   bool expectedTest7Bool = true;
-  if (test7Bool != expectedTest7Bool)
+  if (parsedArgs["--bool"].toBool() != expectedTest7Bool)
     {
     {
     qCritical() << "Test7 - Failed - test7Bool" << test7Bool
     qCritical() << "Test7 - Failed - test7Bool" << test7Bool
         << ", expectedTest7Bool" << expectedTest7Bool;
         << ", expectedTest7Bool" << expectedTest7Bool;
@@ -339,8 +342,7 @@ int ctkCommandLineParserTest1(int, char*[])
 
 
   // Test8 - Check if addStringArgument and ignore_rest=true works as expected
   // Test8 - Check if addStringArgument and ignore_rest=true works as expected
   ctkCommandLineParser parser8;
   ctkCommandLineParser parser8;
-  QString test8String;
-  parser8.addStringArgument("--string", 0, &test8String, "This is a string",
+  parser8.addArgument("--string", "", QVariant::String, "This is a string",
                             QString() /*defaultValue*/, true /* ignoreRest*/);
                             QString() /*defaultValue*/, true /* ignoreRest*/);
 
 
   QStringList arguments8;
   QStringList arguments8;
@@ -348,16 +350,18 @@ int ctkCommandLineParserTest1(int, char*[])
   arguments8 << "--string" << "ctk";
   arguments8 << "--string" << "ctk";
   arguments8 << expectedUnparsedArguments;
   arguments8 << expectedUnparsedArguments;
 
 
-  if (!parser8.parseArguments(arguments8))
+  ok = false;
+  parsedArgs = parser8.parseArguments(arguments8, &ok);
+  if (!ok)
     {
     {
     qCritical() << "Test8 - Failed to parse arguments";
     qCritical() << "Test8 - Failed to parse arguments";
     return EXIT_FAILURE;
     return EXIT_FAILURE;
     }
     }
 
 
   QString expectedTest8String = "ctk";
   QString expectedTest8String = "ctk";
-  if (test8String != expectedTest8String)
+  if (parsedArgs["--string"].toString() != expectedTest8String)
     {
     {
-    qCritical() << "Test8 - Failed - test8String" << test8String
+    qCritical() << "Test8 - Failed - test8String" << parsedArgs["--string"].toString()
         << ", expectedTest8String" << expectedTest8String;
         << ", expectedTest8String" << expectedTest8String;
     return EXIT_FAILURE;
     return EXIT_FAILURE;
     }
     }
@@ -369,10 +373,9 @@ int ctkCommandLineParserTest1(int, char*[])
     return EXIT_FAILURE;
     return EXIT_FAILURE;
     }
     }
 
 
-  // Test9 - Check if addIntegerArgument and ignore_rest=true works as expected
+  // Test9 - Check if addArgument for int and ignore_rest=true works as expected
   ctkCommandLineParser parser9;
   ctkCommandLineParser parser9;
-  int test9Int = 0;
-  parser9.addIntegerArgument("--integer", 0, &test9Int, "This is an integer",
+  parser9.addArgument("--integer", "", QVariant::Int, "This is an integer",
                              0 /*defaultValue*/, true /* ignoreRest*/);
                              0 /*defaultValue*/, true /* ignoreRest*/);
 
 
   QStringList arguments9;
   QStringList arguments9;
@@ -380,16 +383,18 @@ int ctkCommandLineParserTest1(int, char*[])
   arguments9 << "--integer" << "74";
   arguments9 << "--integer" << "74";
   arguments9 << expectedUnparsedArguments;
   arguments9 << expectedUnparsedArguments;
 
 
-  if (!parser9.parseArguments(arguments9))
+  ok = false;
+  parsedArgs = parser9.parseArguments(arguments9, &ok);
+  if (!ok)
     {
     {
     qCritical() << "Test9 - Failed to parse arguments";
     qCritical() << "Test9 - Failed to parse arguments";
     return EXIT_FAILURE;
     return EXIT_FAILURE;
     }
     }
 
 
   int expectedTest9Int = 74;
   int expectedTest9Int = 74;
-  if (test9Int != expectedTest9Int)
+  if (parsedArgs["--integer"].toInt() != expectedTest9Int)
     {
     {
-    qCritical() << "Test9 - Failed - test9Int" << test9Int
+    qCritical() << "Test9 - Failed - test9Int" << parsedArgs["--integer"].toInt()
         << ", expectedTest9Int" << expectedTest9Int;
         << ", expectedTest9Int" << expectedTest9Int;
     return EXIT_FAILURE;
     return EXIT_FAILURE;
     }
     }
@@ -403,8 +408,7 @@ int ctkCommandLineParserTest1(int, char*[])
 
 
   // Test10 - Check if argumentParsed works as expected
   // Test10 - Check if argumentParsed works as expected
   ctkCommandLineParser parser10;
   ctkCommandLineParser parser10;
-  bool test10bool = false;
-  parser10.addBooleanArgument("--bool", 0, &test10bool, "This is a boolean");
+  parser10.addArgument("--bool", "", QVariant::Bool, "This is a boolean");
 
 
   // Since parseArguments hasn't been called, argumentParsed should return False
   // Since parseArguments hasn't been called, argumentParsed should return False
   if(parser10.argumentParsed("--bool"))
   if(parser10.argumentParsed("--bool"))
@@ -417,7 +421,9 @@ int ctkCommandLineParserTest1(int, char*[])
   arguments10 << "ctkCommandLineParserTest1";
   arguments10 << "ctkCommandLineParserTest1";
   arguments10 << "--bool";
   arguments10 << "--bool";
 
 
-  if (!parser10.parseArguments(arguments10))
+  ok = false;
+  parser10.parseArguments(arguments10, &ok);
+  if (!ok)
     {
     {
     qCritical() << "Test10 - Failed to parse arguments.";
     qCritical() << "Test10 - Failed to parse arguments.";
     return EXIT_FAILURE;
     return EXIT_FAILURE;

+ 186 - 179
Libs/Core/ctkCommandLineParser.cpp

@@ -11,21 +11,60 @@
 namespace
 namespace
 {
 {
 
 
-class CommandLineParserArgumentDescriptionBase
+class CommandLineParserArgumentDescription
 {
 {
 public:
 public:
-  CommandLineParserArgumentDescriptionBase(
-    const char* longArg, const char* shortArg, const QString& argHelp, bool ignoreRest)
+  CommandLineParserArgumentDescription(
+    const QString& longArg, const QString& shortArg, QVariant::Type type,
+    const QString& argHelp, const QVariant& defaultValue, bool ignoreRest)
+      : LongArg(longArg), ShortArg(shortArg), ArgHelp(argHelp),
+  IgnoreRest(ignoreRest), NumberOfParametersToProcess(0),
+  Value(type)
+  {
+    if (defaultValue.isValid())
     {
     {
-    this->LongArg = QLatin1String(longArg);
-    this->ShortArg = QLatin1String(shortArg);
-    this->ArgHelp = argHelp;
-    this->IgnoreRest = ignoreRest;
-    this->NumberOfParametersToProcess = 0;
+      Value = defaultValue;
     }
     }
-  virtual ~CommandLineParserArgumentDescriptionBase(){}
-  virtual bool addParameter(const QString& value) = 0;
+
+    switch (type)
+    {
+    case QVariant::String:
+      {
+        NumberOfParametersToProcess = 1;
+        RegularExpression = ".*";
+      }
+      break;
+    case QVariant::Bool:
+      {
+        NumberOfParametersToProcess = 0;
+        RegularExpression = "";
+      }
+      break;
+    case QVariant::StringList:
+      {
+        NumberOfParametersToProcess = -1;
+        RegularExpression = ".*";
+      }
+      break;
+    case QVariant::Int:
+      {
+        NumberOfParametersToProcess = 1;
+        RegularExpression = "-?[0-9]+";
+        ExactMatchFailedMessage = "A negative or positive integer is expected.";
+      }
+      break;
+    default:
+      ExactMatchFailedMessage = QString("Type %1 not supported.").arg(static_cast<int>(type));
+    }
+
+  }
+
+  ~CommandLineParserArgumentDescription(){}
+
+  bool addParameter(const QString& value);
+
   QString helpText(int fieldWidth, const char charPad);
   QString helpText(int fieldWidth, const char charPad);
+
   QString LongArg;
   QString LongArg;
   QString ShortArg;
   QString ShortArg;
   QString ArgHelp;
   QString ArgHelp;
@@ -33,11 +72,65 @@ public:
   int     NumberOfParametersToProcess;
   int     NumberOfParametersToProcess;
   QString RegularExpression;
   QString RegularExpression;
   QString ExactMatchFailedMessage;
   QString ExactMatchFailedMessage;
-  QString ArgumentType;
+
+  QVariant Value;
 };
 };
 
 
 // --------------------------------------------------------------------------
 // --------------------------------------------------------------------------
-QString CommandLineParserArgumentDescriptionBase::helpText(int fieldWidth, const char charPad)
+bool CommandLineParserArgumentDescription::addParameter(const QString& value)
+{
+  if (!RegularExpression.isEmpty())
+  {
+    // Validate value
+    QRegExp regexp(this->RegularExpression);
+    if (!regexp.exactMatch(value))
+    {
+      return false;
+    }
+  }
+
+  switch (Value.type())
+  {
+  case QVariant::String:
+    {
+      Value.setValue(value);
+    }
+    break;
+  case QVariant::Bool:
+    {
+      Value.setValue(!QString::compare(value, "true", Qt::CaseInsensitive));
+    }
+    break;
+  case QVariant::StringList:
+    {
+      if (Value.isNull())
+      {
+        QStringList list;
+        list << value;
+        Value.setValue(list);
+      }
+      else
+      {
+        QStringList list = Value.toStringList();
+        list << value;
+        Value.setValue(list);
+      }
+    }
+    break;
+  case QVariant::Int:
+    {
+      Value.setValue(value.toInt());
+    }
+    break;
+  default:
+    return false;
+  }
+
+  return true;
+}
+
+// --------------------------------------------------------------------------
+QString CommandLineParserArgumentDescription::helpText(int fieldWidth, const char charPad)
 {
 {
   QString text;
   QString text;
   QTextStream stream(&text);
   QTextStream stream(&text);
@@ -71,86 +164,6 @@ QString CommandLineParserArgumentDescriptionBase::helpText(int fieldWidth, const
   return text;
   return text;
 }
 }
 
 
-#define CommandLineParserArgumentDescription_class(_NAME, _TYPE,                        \
-                                                   _NUMBEROFPARAMTOPROCESS,             \
-                                                   _REGEXP, _EXACTMACTHERRORMSG)        \
-  class CommandLineParser##_NAME##ArgumentDescription:                                  \
-    public CommandLineParserArgumentDescriptionBase                                     \
-  {                                                                                     \
-  public:                                                                               \
-    CommandLineParser##_NAME##ArgumentDescription(                                      \
-      const char* longArg, const char* shortArg, _TYPE * variable,                      \
-      const QString& argHelp, const _TYPE& defaultValue,                                \
-      bool ignoreRest):                                                                 \
-      CommandLineParserArgumentDescriptionBase(longArg , shortArg, argHelp, ignoreRest) \
-      {                                                                                 \
-      this->Variable = variable;                                                        \
-      this->DefaultValue = defaultValue;                                                \
-      this->NumberOfParametersToProcess = _NUMBEROFPARAMTOPROCESS;                      \
-      this->RegularExpression = _REGEXP;                                                \
-      this->ArgumentType = #_TYPE;                                                      \
-      }                                                                                 \
-    virtual ~ CommandLineParser##_NAME##ArgumentDescription(){}                         \
-     virtual bool addParameter(const QString& value);                                   \
-    _TYPE* Variable;                                                                    \
-    _TYPE DefaultValue;                                                                 \
-  };
-
-CommandLineParserArgumentDescription_class(String, QString, 1, ".*", "");
-CommandLineParserArgumentDescription_class(Boolean, bool, 0, "", "");
-CommandLineParserArgumentDescription_class(StringList, QStringList, -1, ".*", "");
-CommandLineParserArgumentDescription_class(Integer, int, 1, "-?[0-9]+",
-                                           "A negative or positive integer is expected.");
-
-#undef CommandLineParserArgumentDescription_class
-
-// --------------------------------------------------------------------------
-bool CommandLineParserStringArgumentDescription::addParameter(const QString& value)
-{
-  // Validate value
-  QRegExp regexp(this->RegularExpression);
-  if (!regexp.exactMatch(value))
-    {
-    return false;
-    }
-  (*this->Variable).clear();
-  (*this->Variable).append(value);
-  return true;
-}
-
-// --------------------------------------------------------------------------
-bool CommandLineParserBooleanArgumentDescription::addParameter(const QString& value)
-{
-  *this->Variable = (value == "true");
-  return true;
-}
-
-// --------------------------------------------------------------------------
-bool CommandLineParserStringListArgumentDescription::addParameter(const QString& value)
-{
-  // Validate value
-  QRegExp regexp(this->RegularExpression);
-  if (!regexp.exactMatch(value))
-    {
-    return false;
-    }
-  *this->Variable << value;
-  return true;
-}
-
-// --------------------------------------------------------------------------
-bool CommandLineParserIntegerArgumentDescription::addParameter(const QString& value)
-{
-  // Validate value
-  QRegExp regexp(this->RegularExpression);
-  if (!regexp.exactMatch(value))
-    {
-    return false;
-    }
-  *this->Variable = value.toInt();
-  return true;
-}
-
 }
 }
 
 
 // --------------------------------------------------------------------------
 // --------------------------------------------------------------------------
@@ -161,24 +174,13 @@ class ctkCommandLineParser::ctkInternal
 {
 {
 public:
 public:
   ctkInternal():Debug(false),FieldWidth(0){}
   ctkInternal():Debug(false),FieldWidth(0){}
+
+  ~ctkInternal() { qDeleteAll(ArgumentDescriptionList); }
   
   
-  CommandLineParserArgumentDescriptionBase* argumentDescription(const QString& argument);
-  
-  QList<CommandLineParserArgumentDescriptionBase*>          ArgumentDescriptionList;
-  QHash<QString, CommandLineParserArgumentDescriptionBase*> ArgNameToArgumentDescriptionMap;
-  
-  #define ctkCommandLineParser_ctkInternal_declare_map(_NAME) \
-    QHash<QString, CommandLineParser##_NAME##ArgumentDescription*>       \
-      LongArgTo##_NAME##ArgumentDescriptionMap;                          \
-    QHash<QString, CommandLineParser##_NAME##ArgumentDescription*>       \
-      ShortArgTo##_NAME##ArgumentDescriptionMap;
-  
-  ctkCommandLineParser_ctkInternal_declare_map(String);
-  ctkCommandLineParser_ctkInternal_declare_map(Boolean);
-  ctkCommandLineParser_ctkInternal_declare_map(StringList);
-  ctkCommandLineParser_ctkInternal_declare_map(Integer);
+  CommandLineParserArgumentDescription* argumentDescription(const QString& argument);
   
   
-  #undef ctkCommandLineParser_ctkInternal_declare_map
+  QList<CommandLineParserArgumentDescription*>          ArgumentDescriptionList;
+  QHash<QString, CommandLineParserArgumentDescription*> ArgNameToArgumentDescriptionMap;
   
   
   QStringList UnparsedArguments; 
   QStringList UnparsedArguments; 
   QStringList ProcessedArguments;
   QStringList ProcessedArguments;
@@ -191,7 +193,7 @@ public:
 // ctkCommandLineParser::ctkInternal methods
 // ctkCommandLineParser::ctkInternal methods
 
 
 // --------------------------------------------------------------------------
 // --------------------------------------------------------------------------
-CommandLineParserArgumentDescriptionBase* 
+CommandLineParserArgumentDescription*
   ctkCommandLineParser::ctkInternal::argumentDescription(const QString& argument)
   ctkCommandLineParser::ctkInternal::argumentDescription(const QString& argument)
 {
 {
   if (this->ArgNameToArgumentDescriptionMap.contains(argument))
   if (this->ArgNameToArgumentDescriptionMap.contains(argument))
@@ -217,7 +219,8 @@ ctkCommandLineParser::~ctkCommandLineParser()
 }
 }
 
 
 // --------------------------------------------------------------------------
 // --------------------------------------------------------------------------
-bool ctkCommandLineParser::parseArguments(const QStringList& arguments)
+QHash<QString, QVariant> ctkCommandLineParser::parseArguments(const QStringList& arguments,
+                                                              bool* ok)
 {
 {
   // Reset
   // Reset
   this->Internal->UnparsedArguments.clear();
   this->Internal->UnparsedArguments.clear();
@@ -225,7 +228,7 @@ bool ctkCommandLineParser::parseArguments(const QStringList& arguments)
   this->Internal->ErrorString.clear();
   this->Internal->ErrorString.clear();
 
 
   bool ignoreRest = false;
   bool ignoreRest = false;
-  CommandLineParserArgumentDescriptionBase * currentArgDesc = 0;
+  CommandLineParserArgumentDescription * currentArgDesc = 0;
   for(int i = 1; i < arguments.size(); ++i)
   for(int i = 1; i < arguments.size(); ++i)
     {
     {
 
 
@@ -272,7 +275,8 @@ bool ctkCommandLineParser::parseArguments(const QStringList& arguments)
             this->Internal->ErrorString = 
             this->Internal->ErrorString = 
                 missingParameterError.arg(argument).arg(j-1).arg(numberOfParametersToProcess);
                 missingParameterError.arg(argument).arg(j-1).arg(numberOfParametersToProcess);
             if (this->Internal->Debug) { qDebug() << this->Internal->ErrorString; }
             if (this->Internal->Debug) { qDebug() << this->Internal->ErrorString; }
-            return false;
+            if (ok) *ok = false;
+            return QHash<QString, QVariant>();
             }
             }
           QString parameter = arguments.at(i + j);
           QString parameter = arguments.at(i + j);
           if (this->Internal->Debug)
           if (this->Internal->Debug)
@@ -284,7 +288,8 @@ bool ctkCommandLineParser::parseArguments(const QStringList& arguments)
             this->Internal->ErrorString =
             this->Internal->ErrorString =
                 missingParameterError.arg(argument).arg(j-1).arg(numberOfParametersToProcess);
                 missingParameterError.arg(argument).arg(j-1).arg(numberOfParametersToProcess);
             if (this->Internal->Debug) { qDebug() << this->Internal->ErrorString; }
             if (this->Internal->Debug) { qDebug() << this->Internal->ErrorString; }
-            return false;
+            if (ok) *ok = false;
+            return QHash<QString, QVariant>();
             }
             }
           if (!currentArgDesc->addParameter(parameter))
           if (!currentArgDesc->addParameter(parameter))
             {
             {
@@ -293,7 +298,8 @@ bool ctkCommandLineParser::parseArguments(const QStringList& arguments)
                 arg(argument).arg(currentArgDesc->ExactMatchFailedMessage);
                 arg(argument).arg(currentArgDesc->ExactMatchFailedMessage);
 
 
             if (this->Internal->Debug) { qDebug() << this->Internal->ErrorString; }
             if (this->Internal->Debug) { qDebug() << this->Internal->ErrorString; }
-            return false;
+            if (ok) *ok = false;
+            return QHash<QString, QVariant>();
             }
             }
           }
           }
         // Update main loop increment
         // Update main loop increment
@@ -328,7 +334,8 @@ bool ctkCommandLineParser::parseArguments(const QStringList& arguments)
                 arg(argument).arg(currentArgDesc->ExactMatchFailedMessage);
                 arg(argument).arg(currentArgDesc->ExactMatchFailedMessage);
 
 
             if (this->Internal->Debug) { qDebug() << this->Internal->ErrorString; }
             if (this->Internal->Debug) { qDebug() << this->Internal->ErrorString; }
-            return false;
+            if (ok) *ok = false;
+            return QHash<QString, QVariant>();
             }
             }
           j++;
           j++;
           }
           }
@@ -341,7 +348,27 @@ bool ctkCommandLineParser::parseArguments(const QStringList& arguments)
       this->Internal->UnparsedArguments << argument;
       this->Internal->UnparsedArguments << argument;
       }
       }
     }
     }
-  return true;
+
+  if (ok) *ok = true;
+
+  QHash<QString, QVariant> parsedArguments;
+  QListIterator<CommandLineParserArgumentDescription*> it(this->Internal->ArgumentDescriptionList);
+  while (it.hasNext())
+  {
+    QString key;
+    CommandLineParserArgumentDescription* desc = it.next();
+    if (!desc->LongArg.isEmpty())
+    {
+      key = desc->LongArg;
+    }
+    else
+    {
+      key = desc->ShortArg;
+    }
+
+    parsedArguments.insert(key, desc->Value);
+  }
+  return parsedArguments;
 }
 }
 
 
 // -------------------------------------------------------------------------
 // -------------------------------------------------------------------------
@@ -356,83 +383,63 @@ const QStringList& ctkCommandLineParser::unparsedArguments()
   return this->Internal->UnparsedArguments;
   return this->Internal->UnparsedArguments;
 }
 }
 
 
-// -------------------------------------------------------------------------
-#define ctkCommandLineParser_addArgument_cxx_core(_NAME, _TYPE)                 \
-  /* Make sure it's not already added */                                                   \
-  bool added = this->Internal->LongArgTo##_NAME##ArgumentDescriptionMap.contains(longarg); \
-  Q_ASSERT(!added);                                                                        \
-  if (added) { return; }                                                                   \
-                                                                                           \
-  added = this->Internal->ShortArgTo##_NAME##ArgumentDescriptionMap.contains(shortarg);    \
-  Q_ASSERT(!added);                                                                        \
-  if (added) { return; }                                                                   \
-                                                                                           \
-  CommandLineParser##_NAME##ArgumentDescription * argDesc =                                \
-    new CommandLineParser##_NAME##ArgumentDescription(longarg, shortarg, var,              \
-                                                      argHelp, defaultValue, ignoreRest);  \
-                                                                                           \
-  Q_ASSERT(!(longarg == 0 && shortarg == 0));                                              \
-  if (longarg == 0 && shortarg == 0) { return; }                                           \
-  if (longarg != 0)                                                                        \
-    {                                                                                      \
-    this->Internal->LongArgTo##_NAME##ArgumentDescriptionMap[longarg] = argDesc;           \
-    int argWidth = QString(longarg).length() + 7;                                          \
-    if (argWidth > this->Internal->FieldWidth)                                             \
-      {                                                                                    \
-      this->Internal->FieldWidth = argWidth;                                               \
-      }                                                                                    \
-    }                                                                                      \
-  if (shortarg != 0)                                                                       \
-    {                                                                                      \
-    this->Internal->ShortArgTo##_NAME##ArgumentDescriptionMap[shortarg] = argDesc;         \
-    int argWidth = QString(shortarg).length() + 7;                                         \
-    if (argWidth > this->Internal->FieldWidth)                                             \
-      {                                                                                    \
-      this->Internal->FieldWidth = argWidth;                                               \
-      }                                                                                    \
-    }                                                                                      \
-  this->Internal->ArgNameToArgumentDescriptionMap[longarg] = argDesc;                      \
-  this->Internal->ArgNameToArgumentDescriptionMap[shortarg] = argDesc;                     \
-  this->Internal->ArgumentDescriptionList << argDesc;
+// --------------------------------------------------------------------------
+void ctkCommandLineParser::addArgument(const QString& longarg, const QString& shortarg,
+                                       QVariant::Type type, const QString& argHelp,
+                                       const QVariant& defaultValue, bool ignoreRest)
+{
+  Q_ASSERT(!defaultValue.isValid() || defaultValue.type() == type);
 
 
-  // -------------------------------------------------------------------------
-  #define ctkCommandLineParser_addArgument_cxx(_NAME, _TYPE)                        \
-    void ctkCommandLineParser::add##_NAME##Argument(const char* longarg,            \
-      const char* shortarg, _TYPE* var, const QString& argHelp, const _TYPE& defaultValue,     \
-      bool ignoreRest)                                                                         \
-    {                                                                                          \
-    ctkCommandLineParser_addArgument_cxx_core(_NAME, _TYPE);                        \
-    }
+  /* Make sure it's not already added */
+  bool added = this->Internal->ArgNameToArgumentDescriptionMap.contains(longarg);
+  Q_ASSERT(!added);
+  if (added) { return; }
 
 
-  // -------------------------------------------------------------------------
-  #define ctkCommandLineParser_addArgument_cxx_without_ignore_rest(_NAME, _TYPE)    \
-    void ctkCommandLineParser::add##_NAME##Argument(const char* longarg,            \
-      const char* shortarg, _TYPE* var, const QString& argHelp, const _TYPE& defaultValue)     \
-    {                                                                                          \
-    bool ignoreRest = false;                                                                   \
-    ctkCommandLineParser_addArgument_cxx_core(_NAME, _TYPE);                        \
-    }
+  added = this->Internal->ArgNameToArgumentDescriptionMap.contains(shortarg);
+  Q_ASSERT(!added);
+  if (added) { return; }
 
 
-// --------------------------------------------------------------------------
-ctkCommandLineParser_addArgument_cxx(String, QString);
-ctkCommandLineParser_addArgument_cxx(Boolean, bool);
-ctkCommandLineParser_addArgument_cxx_without_ignore_rest(StringList, QStringList);
-ctkCommandLineParser_addArgument_cxx(Integer, int);
+  CommandLineParserArgumentDescription* argDesc =
+    new CommandLineParserArgumentDescription(longarg, shortarg, type,
+                                             argHelp, defaultValue, ignoreRest);
+
+  Q_ASSERT(!(longarg.isEmpty() && shortarg.isEmpty()));
+  if (longarg.isEmpty() && shortarg.isEmpty()) { return; }
+
+  if (!longarg.isEmpty())
+  {
+    this->Internal->ArgNameToArgumentDescriptionMap[longarg] = argDesc;
+    int argWidth = longarg.length() + 7;
+    if (argWidth > this->Internal->FieldWidth)
+    {
+      this->Internal->FieldWidth = argWidth;
+    }
+  }
+  if (!shortarg.isEmpty())
+  {
+    this->Internal->ArgNameToArgumentDescriptionMap[shortarg] = argDesc;
+    int argWidth = shortarg.length() + 7;
+    if (argWidth > this->Internal->FieldWidth)
+    {
+      this->Internal->FieldWidth = argWidth;
+    }
+  }
 
 
-#undef ctkCommandLineParser_addArgument_cxx
+  this->Internal->ArgumentDescriptionList << argDesc;
+}
 
 
 // --------------------------------------------------------------------------
 // --------------------------------------------------------------------------
 bool ctkCommandLineParser::setExactMatchRegularExpression(
 bool ctkCommandLineParser::setExactMatchRegularExpression(
     const QString& argument, const QString& expression, const QString& exactMatchFailedMessage)
     const QString& argument, const QString& expression, const QString& exactMatchFailedMessage)
 {
 {
-  CommandLineParserArgumentDescriptionBase * argDesc =
+  CommandLineParserArgumentDescription * argDesc =
       this->Internal->argumentDescription(argument);
       this->Internal->argumentDescription(argument);
   if (!argDesc)
   if (!argDesc)
     {
     {
     return false;
     return false;
     }
     }
 
 
-  if (argDesc->ArgumentType == "bool")
+  if (argDesc->Value.type() == QVariant::Bool)
     {
     {
     return false;
     return false;
     }
     }
@@ -448,7 +455,7 @@ QString ctkCommandLineParser::helpText(const char charPad)
   QTextStream stream(&text);
   QTextStream stream(&text);
 
 
   // Loop over argument descriptions
   // Loop over argument descriptions
-  foreach(CommandLineParserArgumentDescriptionBase* argDesc,
+  foreach(CommandLineParserArgumentDescription* argDesc,
           this->Internal->ArgumentDescriptionList)
           this->Internal->ArgumentDescriptionList)
     {
     {
     stream << argDesc->helpText(this->Internal->FieldWidth, charPad);
     stream << argDesc->helpText(this->Internal->FieldWidth, charPad);

+ 5 - 16
Libs/Core/ctkCommandLineParser.h

@@ -4,6 +4,7 @@
 // Qt includes
 // Qt includes
 #include <QString>
 #include <QString>
 #include <QStringList>
 #include <QStringList>
+#include <QVariant>
 
 
 // CTK includes
 // CTK includes
 #include "CTKCoreExport.h"
 #include "CTKCoreExport.h"
@@ -16,7 +17,7 @@ public:
   ctkCommandLineParser();
   ctkCommandLineParser();
   ~ctkCommandLineParser();
   ~ctkCommandLineParser();
   
   
-  bool parseArguments(const QStringList& arguments);
+  QHash<QString /*longarg*/, QVariant> parseArguments(const QStringList &arguments, bool* ok = 0);
 
 
   QString errorString();
   QString errorString();
   
   
@@ -25,22 +26,10 @@ public:
   bool argumentAdded(const QString& argument);
   bool argumentAdded(const QString& argument);
 
 
   bool argumentParsed(const QString& argument);
   bool argumentParsed(const QString& argument);
-  
-  void addBooleanArgument(const char* longarg, const char* shortarg, bool* var, 
-                          const QString& argHelp = QString(), const bool& defaultValue = false,
-                          bool ignoreRest = false);
-
-  void addStringArgument(const char* longarg, const char* shortarg, QString* var, 
-                         const QString& argHelp = QString(), const QString& defaultValue = QString(),
-                         bool ignoreRest = false);
-
-  void addIntegerArgument(const char* longarg, const char* shortarg, int* var,
-                         const QString& argHelp = QString(), const int& defaultValue = 0,
-                         bool ignoreRest = false);
 
 
-  void addStringListArgument(const char* longarg, const char* shortarg, QStringList* var,
-                             const QString& argHelp = QString(),
-                             const QStringList& defaultValue = QStringList());
+  void addArgument(const QString& longarg, const QString& shortarg,
+                   QVariant::Type type, const QString& argHelp = QString(),
+                   const QVariant& defaultValue = QVariant(), bool ignoreRest = false);
 
 
   bool setExactMatchRegularExpression(const QString& argument, const QString& expression,
   bool setExactMatchRegularExpression(const QString& argument, const QString& expression,
                                       const QString& ExactMatchFailedMessage);
                                       const QString& ExactMatchFailedMessage);

+ 8 - 7
Libs/Visualization/VTK/Widgets/Testing/Cpp/ctkVTKRenderViewTest1.cpp

@@ -46,20 +46,21 @@ int ctkVTKRenderViewTest1(int argc, char * argv [] )
 {
 {
   QApplication app(argc, argv);
   QApplication app(argc, argv);
 
 
-  // Test arguments
-  bool interactive = false;
-  QString data_directory;
-
   // Command line parser
   // Command line parser
   ctkCommandLineParser parser;
   ctkCommandLineParser parser;
-  parser.addBooleanArgument(0, "-I", &interactive);
-  parser.addStringArgument(0, "-D", &data_directory);
-  if (!parser.parseArguments(app.arguments()))
+  parser.addArgument("", "-I", QVariant::Bool);
+  parser.addArgument("", "-D", QVariant::String);
+  bool ok = false;
+  QHash<QString, QVariant> parsedArgs = parser.parseArguments(app.arguments(), &ok);
+  if (!ok)
     {
     {
     std::cerr << qPrintable(parser.errorString()) << std::endl;
     std::cerr << qPrintable(parser.errorString()) << std::endl;
     return EXIT_FAILURE;
     return EXIT_FAILURE;
     }
     }
 
 
+  bool interactive = parsedArgs["-I"].toBool();
+  QString data_directory = parsedArgs["-D"].toString();
+
   // Instanciate widget
   // Instanciate widget
   ctkVTKRenderView renderView;
   ctkVTKRenderView renderView;
   renderView.resize(300, 300);
   renderView.resize(300, 300);

+ 8 - 5
Libs/Visualization/VTK/Widgets/Testing/Cpp/ctkVTKSliceViewTest1.cpp

@@ -45,20 +45,23 @@ int ctkVTKSliceViewTest1(int argc, char * argv [] )
   QApplication app(argc, argv);
   QApplication app(argc, argv);
 
 
   // Test arguments
   // Test arguments
-  bool interactive = false;
-  QString data_directory;
   QString filename = "HeadMRVolume.mhd";
   QString filename = "HeadMRVolume.mhd";
 
 
   // Command line parser
   // Command line parser
   ctkCommandLineParser parser;
   ctkCommandLineParser parser;
-  parser.addBooleanArgument(0, "-I", &interactive);
-  parser.addStringArgument(0, "-D", &data_directory);
-  if (!parser.parseArguments(app.arguments()))
+  parser.addArgument("", "-I", QVariant::Bool);
+  parser.addArgument("", "-D", QVariant::String);
+  bool ok = false;
+  QHash<QString, QVariant> parsedArgs = parser.parseArguments(app.arguments(), &ok);
+  if (!ok)
     {
     {
     std::cerr << qPrintable(parser.errorString()) << std::endl;
     std::cerr << qPrintable(parser.errorString()) << std::endl;
     return EXIT_FAILURE;
     return EXIT_FAILURE;
     }
     }
 
 
+  bool interactive = parsedArgs["-I"].toBool();
+  QString data_directory = parsedArgs["-D"].toString();
+
   QString imageFilename = data_directory + "/" + filename;
   QString imageFilename = data_directory + "/" + filename;
 
 
   // Instanciate the reader factory
   // Instanciate the reader factory