00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036 #include <QDebug>
00037 #include <QString>
00038 #include <QLatin1String>
00039 #include <QSettings>
00040 #include <QHash>
00041 #include <QList>
00042 #include <QPointer>
00043 #include <QStringList>
00044
00045
00046 #include <ctkUtils.h>
00047 #include "ctkVTKCommandOptions.h"
00048
00049
00050 #include <vtksys/CommandLineArguments.hxx>
00051
00052
00053 class ctkVTKCommandOptionsPrivate: public ctkPrivate<ctkVTKCommandOptions>
00054 {
00055 public:
00056 typedef ctkVTKCommandOptionsPrivate Self;
00057 ctkVTKCommandOptionsPrivate();
00058 ~ctkVTKCommandOptionsPrivate();
00059
00060 void cleanArgcArgv();
00061
00063 static int unknownArgumentHandler(const char* argument, void* call_data);
00064
00068 bool checkForIgnoreRestFlag(const char* argument);
00069
00071 static int deprecatedArgumentHandler(const char* argument, const char* value, void* call_data);
00072
00075 char** mapQStringPtrToCharPtr(QString* qStringPtr);
00076
00079 std::vector<std::string>* mapQStringListPtrToStringVectorPtr(QStringList* qStringListPtr);
00080
00082 void syncQStringPtrWithCharPtr();
00083
00085 void syncQStringListPtrWithStringVectorPtr();
00086
00087 vtksys::CommandLineArguments CMD;
00088 QString UnknownArgument;
00089 QString ErrorMessage;
00090 bool HelpSelected;
00091 bool DisableSettings;
00092 bool IgnoreRest;
00093 QStringList IgnoredArguments;
00094 int Argc;
00095 char** Argv;
00096 QPointer<QSettings> Settings;
00097 int ProcessType;
00098
00099 QHash<QString*, char**> QStringPointerToCharPointerMap;
00100 QHash<QStringList*, std::vector<std::string>*> QStringListPointerToStringVectorPointerMap;
00101 };
00102
00103
00104
00105
00106
00107 ctkVTKCommandOptionsPrivate::ctkVTKCommandOptionsPrivate()
00108 {
00109 this->CMD.SetUnknownArgumentCallback(ctkVTKCommandOptionsPrivate::unknownArgumentHandler);
00110 this->CMD.SetClientData(this);
00111
00112 this->Argc = 0;
00113 this->Argv = 0;
00114 this->HelpSelected = false;
00115 this->DisableSettings = false;
00116 this->IgnoreRest = false;
00117 }
00118
00119
00120 ctkVTKCommandOptionsPrivate::~ctkVTKCommandOptionsPrivate()
00121 {
00122 this->cleanArgcArgv();
00123 foreach (QString* qStringPtr, this->QStringPointerToCharPointerMap.keys())
00124 {
00125 delete this->QStringPointerToCharPointerMap[qStringPtr];
00126 }
00127 foreach (QStringList* qStringListPtr, this->QStringListPointerToStringVectorPointerMap.keys())
00128 {
00129 delete this->QStringListPointerToStringVectorPointerMap[qStringListPtr];
00130 }
00131 }
00132
00133
00134 void ctkVTKCommandOptionsPrivate::cleanArgcArgv()
00135 {
00136 int cc;
00137 if (this->Argv)
00138 {
00139 for (cc = 0; cc < this->Argc; cc++)
00140 {
00141 delete [] this->Argv[cc];
00142 }
00143 delete [] this->Argv;
00144 this->Argv = 0;
00145 }
00146 }
00147
00148
00149 int ctkVTKCommandOptionsPrivate::unknownArgumentHandler(const char* argument,
00150 void* call_data)
00151 {
00152 ctkVTKCommandOptionsPrivate* self =
00153 static_cast<ctkVTKCommandOptionsPrivate*>(call_data);
00154 if (self)
00155 {
00156 self->UnknownArgument = QString::fromLatin1(argument);
00157 return self->checkForIgnoreRestFlag(argument);
00158 }
00159 return 0;
00160 }
00161
00162
00163 bool ctkVTKCommandOptionsPrivate::checkForIgnoreRestFlag(const char* argument)
00164 {
00165 CTK_P(ctkVTKCommandOptions);
00166 if (this->IgnoreRest)
00167 {
00168 this->IgnoredArguments << QLatin1String(argument);
00169 return true;
00170 }
00171 else
00172 {
00173 return p->wrongArgument(argument);
00174 }
00175 }
00176
00177
00178 int ctkVTKCommandOptionsPrivate::deprecatedArgumentHandler(const char* argument,
00179 const char* , void* call_data)
00180 {
00181
00182 ctkVTKCommandOptionsPrivate* self = static_cast<ctkVTKCommandOptionsPrivate*>(call_data);
00183 if (self)
00184 {
00185 return self->ctk_p()->deprecatedArgument(argument);
00186 }
00187 return 0;
00188 }
00189
00190
00191 char** ctkVTKCommandOptionsPrivate::mapQStringPtrToCharPtr(QString* qStringPtr)
00192 {
00193 Q_ASSERT(!this->QStringPointerToCharPointerMap.contains(qStringPtr));
00194 char** charPtr = new char*;
00195 *charPtr = 0;
00196 this->QStringPointerToCharPointerMap[qStringPtr] = charPtr;
00197 return charPtr;
00198 }
00199
00200
00201 std::vector<std::string>*
00202 ctkVTKCommandOptionsPrivate::mapQStringListPtrToStringVectorPtr(QStringList* qStringListPtr)
00203 {
00204 Q_ASSERT(!this->QStringListPointerToStringVectorPointerMap.contains(qStringListPtr));
00205 std::vector<std::string>* vectorPtr = new std::vector<std::string>();
00206 this->QStringListPointerToStringVectorPointerMap[qStringListPtr] = vectorPtr;
00207 return vectorPtr;
00208 }
00209
00210
00211 void ctkVTKCommandOptionsPrivate::syncQStringPtrWithCharPtr()
00212 {
00213 foreach(QString* qStringPtr, this->QStringPointerToCharPointerMap.keys())
00214 {
00215 char** charPtr = this->QStringPointerToCharPointerMap[qStringPtr];
00216 Q_ASSERT(charPtr);
00217
00218 if (*charPtr)
00219 {
00220 qStringPtr->clear();
00221 qStringPtr->append(QLatin1String(*charPtr));
00222 }
00223 }
00224 }
00225
00226
00227 void ctkVTKCommandOptionsPrivate::syncQStringListPtrWithStringVectorPtr()
00228 {
00229 foreach(QStringList* qStringListPtr, this->QStringListPointerToStringVectorPointerMap.keys())
00230 {
00231 std::vector<std::string>* vectorPtr =
00232 this->QStringListPointerToStringVectorPointerMap[qStringListPtr];
00233 Q_ASSERT(vectorPtr);
00234
00235 if (vectorPtr->size() > 0)
00236 {
00237 qStringListPtr->clear();
00238 QStringList convertedVector;
00239 ctk::stlVectorToQList(*vectorPtr, convertedVector);
00240 qStringListPtr->append(convertedVector);
00241 }
00242 }
00243 }
00244
00245
00246
00247
00248
00249 ctkVTKCommandOptions::ctkVTKCommandOptions(QSettings* _settings)
00250 {
00251 CTK_INIT_PRIVATE(ctkVTKCommandOptions);
00252 Q_ASSERT(_settings);
00253 CTK_D(ctkVTKCommandOptions);
00254 d->Settings = _settings;
00255 }
00256
00257
00258 ctkVTKCommandOptions::~ctkVTKCommandOptions()
00259 {
00260 }
00261
00262
00263 void ctkVTKCommandOptions::printAdditionalInfo()
00264 {
00265 CTK_D(ctkVTKCommandOptions);
00266 qDebug() << "ctkVTKCommandOptions:" << this << endl
00267 << " HelpSelected:" << this->helpSelected() << endl
00268 << " DisableSettings:" << d->DisableSettings << endl
00269 << " IgnoreRest:" << d->IgnoreRest << endl
00270 << " IgnoredArguments:" << d->IgnoredArguments;
00271 }
00272
00273
00274 CTK_GET_CXX(ctkVTKCommandOptions, QString, errorMessage, ErrorMessage);
00275 CTK_GET_CXX(ctkVTKCommandOptions, QString, unknownArgument, UnknownArgument);
00276 CTK_GET_CXX(ctkVTKCommandOptions, bool, helpSelected, HelpSelected);
00277 CTK_GET_CXX(ctkVTKCommandOptions, bool, disableSettings, DisableSettings);
00278 CTK_GET_CXX(ctkVTKCommandOptions, QSettings*, settings, Settings);
00279 CTK_GET_CXX(ctkVTKCommandOptions, bool, ignoreRest, IgnoreRest);
00280 CTK_GET_CXX(ctkVTKCommandOptions, QStringList, ignoredArguments, IgnoredArguments);
00281
00282
00283 CTK_GET_CXX(ctkVTKCommandOptions, int, processType, ProcessType);
00284 CTK_SET_CXX(ctkVTKCommandOptions, int, setProcessType, ProcessType);
00285
00286
00287 void ctkVTKCommandOptions::initialize()
00288 {
00289 }
00290
00291
00292 QString ctkVTKCommandOptions::help()
00293 {
00294 CTK_D(ctkVTKCommandOptions);
00295 d->CMD.SetLineLength(300);
00296 return QLatin1String(d->CMD.GetHelp());
00297 }
00298
00299
00300 bool ctkVTKCommandOptions::postProcess(int, const char* const*)
00301 {
00302 return true;
00303 }
00304
00305
00306 bool ctkVTKCommandOptions::parse(int argc, const char* const argv[])
00307 {
00308 CTK_D(ctkVTKCommandOptions);
00309 d->CMD.Initialize(argc, argv);
00310 this->initialize();
00311 this->addBooleanArgument("--help", "/?", &d->HelpSelected,
00312 "Displays available command line arguments.");
00313
00314 this->addBooleanArgument("--disable-settings", 0, &d->DisableSettings,
00315 "Start application ignoring user settings.");
00316
00317
00318 this->addBooleanArgument("--ignore-rest", "--", &d->IgnoreRest,
00319 "Ignores the rest of the labeled arguments following this flag.");
00320
00321
00322 bool res1 = d->CMD.Parse();
00323 bool res2 = this->postProcess(argc, argv);
00324
00325 d->cleanArgcArgv();
00326 d->CMD.GetRemainingArguments(&d->Argc, &d->Argv);
00327
00328 if (d->DisableSettings)
00329 {
00330 this->disableCurrentSettings();
00331 }
00332
00333 d->syncQStringPtrWithCharPtr();
00334 d->syncQStringListPtrWithStringVectorPtr();
00335
00336
00337
00338 QStringList _remaingingArguments = this->remainingArguments();
00339 _remaingingArguments.removeFirst();
00340
00341
00342 d->IgnoredArguments << _remaingingArguments;
00343
00344 return res1 && res2;
00345 }
00346
00347
00348 QStringList ctkVTKCommandOptions::remainingArguments()
00349 {
00350 CTK_D(ctkVTKCommandOptions);
00351 QStringList tmp;
00352 for(int i=0; i < d->Argc; ++i)
00353 {
00354 tmp << d->Argv[i];
00355 }
00356 return tmp;
00357 }
00358
00359
00360 void ctkVTKCommandOptions::remainingArguments(int* argc, char*** argv)
00361 {
00362 CTK_D(ctkVTKCommandOptions);
00363 *argc = d->Argc;
00364 *argv = d->Argv;
00365 }
00366
00367
00368 void ctkVTKCommandOptions::addDeprecatedArgument(const char* longarg, const char* shortarg,
00369 const char* arghelp, int type)
00370 {
00371 CTK_D(ctkVTKCommandOptions);
00372
00373
00374 if((type & ctkVTKCommandOptions::QSETTINGS_ONLY) ||
00375 !(type & d->ProcessType || type == ctkVTKCommandOptions::ALL))
00376 {
00377 return;
00378 }
00379
00380
00381 d->CMD.AddCallback(longarg, vtksys::CommandLineArguments::NO_ARGUMENT,
00382 ctkVTKCommandOptionsPrivate::deprecatedArgumentHandler, this, arghelp);
00383 if(shortarg)
00384 {
00385 d->CMD.AddCallback(shortarg, vtksys::CommandLineArguments::NO_ARGUMENT,
00386 ctkVTKCommandOptionsPrivate::deprecatedArgumentHandler, this, arghelp);
00387 }
00388 }
00389
00390
00391 bool ctkVTKCommandOptions::deprecatedArgument(const char* argument)
00392 {
00393 CTK_D(ctkVTKCommandOptions);
00394 d->ErrorMessage = QString(" %1").arg(d->CMD.GetHelp(argument));
00395 return false;
00396 }
00397
00398
00399 bool ctkVTKCommandOptions::wrongArgument(const char* argument)
00400 {
00401 Q_UNUSED(argument);
00402 return false;
00403 }
00404
00405
00406 void ctkVTKCommandOptions::addBooleanArgument(const char* longarg, const char* shortarg,
00407 bool* var, const char* arghelp,
00408 bool defaultValue, int type)
00409 {
00410 CTK_D(ctkVTKCommandOptions);
00411
00412
00413 if (QLatin1String(longarg) != "--disable-settings")
00414 {
00415 *var = d->Settings->value(QLatin1String(longarg+2), defaultValue).toBool();
00416
00417 if(type & ctkVTKCommandOptions::QSETTINGS_ONLY)
00418 {
00419 return;
00420 }
00421 }
00422
00423
00424 if(type & d->ProcessType || type == ctkVTKCommandOptions::ALL)
00425 {
00426 d->CMD.AddBooleanArgument(longarg, var, arghelp);
00427 if (shortarg)
00428 {
00429 d->CMD.AddBooleanArgument(shortarg, var, longarg);
00430 }
00431 }
00432 }
00433
00434
00435 void ctkVTKCommandOptions::addArgument(const char* longarg, const char* shortarg, QString* var,
00436 const char* arghelp, const QString& defaultValue, int type)
00437 {
00438 CTK_D(ctkVTKCommandOptions);
00439 *var = d->Settings->value(QLatin1String(longarg+2), defaultValue).toString();
00440
00441 if(type & ctkVTKCommandOptions::QSETTINGS_ONLY)
00442 {
00443 return;
00444 }
00445
00446 if(type & d->ProcessType || type == ctkVTKCommandOptions::ALL)
00447 {
00448 char ** charstar = d->mapQStringPtrToCharPtr(var);
00449 typedef vtksys::CommandLineArguments argT;
00450 d->CMD.AddArgument(longarg, argT::EQUAL_ARGUMENT, charstar, arghelp);
00451 if ( shortarg )
00452 {
00453 d->CMD.AddArgument(shortarg, argT::EQUAL_ARGUMENT, charstar, longarg);
00454 }
00455 }
00456 }
00457
00458
00459 void ctkVTKCommandOptions::addArgument(const char* longarg, const char* shortarg,
00460 QStringList* var, const char* arghelp,
00461 const QStringList& defaultValue, int type)
00462 {
00463 CTK_D(ctkVTKCommandOptions);
00464 *var = d->Settings->value(QLatin1String(longarg+2), defaultValue).toStringList();
00465
00466 if(type & ctkVTKCommandOptions::QSETTINGS_ONLY)
00467 {
00468 return;
00469 }
00470
00471 if(type & d->ProcessType || type == ctkVTKCommandOptions::ALL)
00472 {
00473 std::vector<std::string>* vectorPtr = d->mapQStringListPtrToStringVectorPtr(var);
00474 typedef vtksys::CommandLineArguments argT;
00475 d->CMD.AddArgument(longarg, argT::MULTI_ARGUMENT, vectorPtr, arghelp);
00476 if (shortarg)
00477 {
00478 d->CMD.AddArgument(shortarg, argT::MULTI_ARGUMENT, vectorPtr, longarg);
00479 }
00480 }
00481 }
00482
00483
00484 void ctkVTKCommandOptions::addArgument(const char* longarg, const char* shortarg, int* var,
00485 const char* arghelp, int defaultValue, int type)
00486 {
00487 CTK_D(ctkVTKCommandOptions);
00488 *var = d->Settings->value(QLatin1String(longarg+2), defaultValue).toInt();
00489
00490 if(type & ctkVTKCommandOptions::QSETTINGS_ONLY)
00491 {
00492 return;
00493 }
00494
00495 if(type & d->ProcessType || type == ctkVTKCommandOptions::ALL)
00496 {
00497 typedef vtksys::CommandLineArguments argT;
00498 d->CMD.AddArgument(longarg, argT::EQUAL_ARGUMENT, var, arghelp);
00499 if (shortarg)
00500 {
00501 d->CMD.AddArgument(shortarg, argT::EQUAL_ARGUMENT, var, longarg);
00502 }
00503 }
00504 }
00505
00506
00507 int ctkVTKCommandOptions::indexOfLastParsedArgument()
00508 {
00509 CTK_D(ctkVTKCommandOptions);
00510 return d->CMD.GetLastArgument();
00511 }