Isis 3 Programmer Reference
UserInterface.cpp
Go to the documentation of this file.
1 
22 #include "UserInterface.h"
23 
24 #include <sstream>
25 #include <vector>
26 
27 #include <QDir>
28 
29 #include "Application.h"
30 #include "FileName.h"
31 #include "Gui.h"
32 #include "IException.h"
33 #include "IString.h"
34 #include "Message.h"
35 #include "Preference.h"
36 #include "ProgramLauncher.h"
37 #include "TextFile.h"
38 
39 using namespace std;
40 namespace Isis {
41 
52  UserInterface::UserInterface(const QString &xmlfile, int &argc,
53  char *argv[]) : IsisAml::IsisAml(xmlfile) {
54  p_interactive = false;
55  p_info = false;
56  p_infoFileName = "";
57  p_gui = NULL;
58  p_errList = "";
59  p_saveFile = "";
60  p_abortOnError = true;
61  p_parentId = 0;
62 
63  // Make sure the user has a .Isis and .Isis/history directory
64  try {
65  FileName setup = "$HOME/.Isis/history";
66  // cannot completely test this if in unit test
67  if ( !setup.fileExists() ) {
68  setup.dir().mkpath(".");
69  }
70  }
71  catch (IException &) {
72  }
73 
74  // Parse the user input
75  loadCommandLine(argc, argv);
76 
77  // See if we need to create the gui
78  // can't unit test - don't want to create a Gui object while unit testing
79  if (p_interactive) {
80  Gui::checkX11();
81  p_gui = Gui::Create(*this, argc, argv);
82  }
83  }
84 
87  // can't unit test - p_gui will be NULL in unit test
88  if (p_gui) {
89  delete p_gui;
90  p_gui = NULL;
91  }
92  }
93 
101  return p_infoFileName;
102  }
103 
104 
112  return p_info;
113  }
114 
115 
125  //Clear all parameters currently in the gui
126  for (int k = 0; k < NumGroups(); k++) {
127  for (int j = 0; j < NumParams(k); j++) {
128  Clear( ParamName(k, j) );
129  }
130  }
131 
132  //Load the new parameters into the gui
133  cout << p_progName << " ";
134 
135  for (unsigned int currArgument = 1; currArgument < p_cmdline.size(); currArgument ++) {
136  QString paramName;
137  vector<QString> paramValue;
138 
139 
140  try {
141  getNextParameter(currArgument, paramName, paramValue);
142 
143  if (paramName[0] == '-')
144  continue;
145 
146  for (unsigned int value = 0; value < paramValue.size(); value++) {
147  IString thisValue = paramValue[value];
148  QString token = thisValue.Token("$").ToQt();
149 
150  QString newValue;
151 
152  while (thisValue != "") {
153  newValue += token;
154  try {
155  int j = toInt( thisValue.substr(0, 1).c_str() ) - 1;
156  newValue += p_batchList[i][j];
157  thisValue.replace(0, 1, "");
158  token = thisValue.Token("$").ToQt();
159  }
160  catch (IException &e) {
161  // Let the variable be parsed by the application
162  newValue += "$";
163  token = thisValue.Token("$").ToQt();
164  }
165  }
166 
167  if (token != "")
168  newValue += token;
169 
170  paramValue[value] = newValue;
171  }
172  }
173  // can't test with unit test - command line is already parsed before SetBatchList() is called
174  catch (IException &e) {
175  throw IException(IException::User, "Invalid command line", _FILEINFO_);
176  }
177 
178  PutAsString(paramName, paramValue);
179 
180  cout << paramName;
181 
182  if(paramValue.size() == 1) {
183  cout << "=" << paramValue[0] << " ";
184  }
185  else if (paramValue.size() > 1) {
186  cout << "=(";
187 
188  for (unsigned int value = 0; value < paramValue.size(); value++) {
189  if(value != 0)
190  cout << ",";
191 
192  cout << paramValue[value] << endl;
193  }
194 
195  cout << ") ";
196  }
197  }
198  cout << endl;
199 
200  // Verify the command line
201  VerifyAll();
202  }
203 
204 
216  if (p_errList != "") {
217  std::ofstream os;
218  QString fileName( FileName(p_errList).expanded() );
219  os.open(fileName.toLatin1().data(), std::ios::app);
220 
221  // did not unit test since it is assumed ofstream will be instantiated correctly
222  if ( !os.good() ) {
223  QString msg = "Unable to create error list [" + p_errList
224  + "] Disk may be full or directory permissions not writeable";
226  }
227 
228  for (int j = 0; j < (int) p_batchList[i].size(); j++) {
229  os << p_batchList[i][j] << " ";
230  }
231 
232  os << endl;
233  os.close();
234  }
235  }
236 
237 
243 
244  // If history recording is off, return
245  Preference &p = Preference::Preferences();
246  PvlGroup &grp = p.findGroup("UserInterface", Isis::Pvl::Traverse);
247  if (grp["HistoryRecording"][0] == "Off")
248  return;
249 
250  // Get the current history file
251  Isis::FileName histFile(grp["HistoryPath"][0] + "/" + ProgramName() + ".par");
252 
253  // If a save file is specified, override the default file path
254  if (p_saveFile != "")
255  histFile = p_saveFile;
256 
257  // Get the current command line
258  Isis::Pvl cmdLine;
259  CommandLine(cmdLine);
260 
261  Isis::Pvl hist;
262 
263  // If the history file's Pvl is corrupted, then
264  // leave hist empty such that the history gets
265  // overwriten with the new entry.
266  try {
267  if ( histFile.fileExists() ) {
268  hist.read( histFile.expanded() );
269  }
270  }
271  catch (IException &) {
272  }
273 
274  // Add it
275  hist.addGroup( cmdLine.findGroup("UserParameters") );
276 
277  // See if we have exceeded history length
278  while( hist.groups() > toInt(grp["HistoryLength"][0]) ) {
279  hist.deleteGroup("UserParameters");
280  }
281 
282  // Write it
283  try {
284  hist.write( histFile.expanded() );
285  }
286  catch (IException &) {
287  }
288 
289  }
290 
291 
304  void UserInterface::loadBatchList(const QString file) {
305  // Read in the batch list
306  TextFile temp;
307  try {
308  temp.Open(file);
309  }
310  catch (IException &e) {
311  QString msg = "The batchlist file [" + file + "] could not be opened";
313  }
314 
315  p_batchList.resize( temp.LineCount() );
316 
317  for (int i = 0; i < temp.LineCount(); i++) {
318  QString t;
319  temp.GetLine(t);
320 
321  // Convert tabs to spaces but leave tabs inside quotes alone
322  t = IString(t).Replace("\t", " ", true).ToQt();
323 
324  t = IString(t).Compress().ToQt().trimmed();
325  // Allow " ," " , " or ", " as a valid single seperator
326  t = IString(t).Replace(" ,", ",", true).ToQt();
327  t = IString(t).Replace(", ", ",", true).ToQt();
328  // Convert all spaces to "," the use "," as delimiter
329  t = IString(t).Replace(" ", ",", true).ToQt();
330  int j = 0;
331 
332  QStringList tokens = t.split(",");
333 
334  foreach (QString token, tokens) {
335  // removes quotes from tokens. NOTE: also removes escaped quotes.
336  token = token.remove( QRegExp("[\"']") );
337  p_batchList[i].push_back(token);
338  j++ ;
339  }
340 
341  p_batchList[i].resize(j);
342  // Every row in the batchlist must have the same number of columns
343  if (i == 0)
344  continue;
345  if ( p_batchList[i - 1].size() != p_batchList[i].size() ) {
346  QString msg = "The number of columns must be constant in batchlist";
348  }
349  }
350  // The batchlist cannot be empty
351  if (p_batchList.size() < 1) {
352  QString msg = "The list file [" + file + "] does not contain any data";
354  }
355  }
356 
357 
373  void UserInterface::loadCommandLine(int argc, char *argv[]) {
374  // The program will be interactive if it has no arguments or
375  // if it has the name unitTest
376  p_progName = argv[0];
378  // cannot completely test in a unit test since unitTest will always evaluate to true
379  if ( (argc == 1) && (file.name() != "unitTest") ) {
380  p_interactive = true;
381  }
382 
383  p_cmdline.clear();
384  for (int i = 0; i < argc; i++) {
385  p_cmdline.push_back(argv[i]);
386  }
387 
388  // Check for special tokens (reserved parameters) (those beginning with a dash)
389  vector<QString> options;
390  options.push_back("-GUI");
391  options.push_back("-NOGUI");
392  options.push_back("-BATCHLIST");
393  options.push_back("-LAST");
394  options.push_back("-RESTORE");
395  options.push_back("-WEBHELP");
396  options.push_back("-HELP");
397  options.push_back("-ERRLIST");
398  options.push_back("-ONERROR");
399  options.push_back("-SAVE");
400  options.push_back("-INFO");
401  options.push_back("-PREFERENCE");
402  options.push_back("-LOG");
403  options.push_back("-VERBOSE");
404  options.push_back("-PID");
405 
406  bool usedDashLast = false;
407  bool usedDashRestore = false; //< for throwing -batchlist exceptions at end of function
408 
409  // pre-process command line for -HELP first
410  preProcess("-HELP", options);
411  // pre-process command line for -WEBHELP
412  preProcess("-WEBHELP", options);
413  // now, parse command line to evaluate -LAST
414  preProcess("-LAST", options);
415 
416  for (unsigned int currArgument = 1; currArgument < (unsigned)argc; currArgument++) {
417  QString paramName;
418  vector<QString> paramValue;
419 
420  getNextParameter(currArgument, paramName, paramValue);
421 
422  // we now have a name,value pair
423  if (paramName[0] == '-') {
424  paramName = paramName.toUpper();
425 
426  // where if(paramname == -last ) to continue } was originally
427 
428  if (paramValue.size() > 1) {
429  QString msg = "Invalid value for reserve parameter ["
430  + paramName + "]";
432  }
433 
434  // resolve the reserved parameter (e.g. set -h to -HELP)
435  paramName = resolveParameter(paramName, options);
436 
437  // Prevent double handling of -LAST to prevent conflicts
438  // Keep track of using -LAST to prevent conflicts with -BATCHLIST
439  if (paramName == "-LAST") {
440  usedDashLast = true;
441  continue;
442  }
443 
444 
445  // Keep track of using -RESTORE to prevent conflicts with -BATCHLIST
446  if (paramName == "-RESTORE") {
447  usedDashRestore = true;
448  }
449 
450 
451  QString realValue = "";
452 
453  if ( paramValue.size() ) {
454  realValue = paramValue[0];
455  }
456 
457  evaluateOption(paramName, realValue);
458  continue;
459  }
460 
461  try {
462  Clear(paramName);
463  PutAsString(paramName, paramValue);
464  }
465  catch (IException &e) {
466  throw IException(e, IException::User, "Invalid command line", _FILEINFO_);
467  }
468  }
469 
470  // Can't use the batchlist with the gui, save, last or restore option
471  if ( BatchListSize() != 0 && (p_interactive || usedDashLast || p_saveFile != ""
472  || usedDashRestore) ) {
473  QString msg = "-BATCHLIST cannot be used with -GUI, -SAVE, -RESTORE, ";
474  msg += "or -LAST";
476  }
477 
478  // Must use batchlist if using errorlist or onerror=continue
479  if ( (BatchListSize() == 0) && (!p_abortOnError || p_errList != "") ) {
480  QString msg = "-ERRLIST and -ONERROR=continue cannot be used without ";
481  msg += " the -BATCHLIST option";
483  }
484  }
485 
486 
498  void UserInterface::loadHistory(const QString file) {
499  Isis::FileName hist(file);
500  if ( hist.fileExists() ) {
501  try {
502  Isis::Pvl lab( hist.expanded() );
503 
504  int g = lab.groups() - 1;
505  if (g >= 0 && lab.group(g).isNamed("UserParameters") ) {
506  Isis::PvlGroup &up = lab.group(g);
507  QString commandline(p_progName + " ");
508  for (int k = 0; k < up.keywords(); k++) {
509  QString keyword = up[k].name();
510 
511  vector<QString> values;
512 
513  for (int i = 0; i < up[k].size(); i++) {
514  values.push_back(up[k][i]);
515  }
516 
517  const IsisParameterData *paramData = ReturnParam(keyword);
518 
519  bool matchesDefault = false;
520  if (values.size() == 1 && paramData->internalDefault == values[0])
521  matchesDefault = true;
522 
523  if (!matchesDefault) {
524  matchesDefault =
525  (values.size() == paramData->defaultValues.size());
526 
527  for (int i = 0; matchesDefault && i < (int)values.size(); i++) {
528  matchesDefault = matchesDefault &&
529  values[i] == paramData->defaultValues[i];
530  }
531  }
532 
533  if (!matchesDefault) {
534  PutAsString(keyword, values);
535  commandline += keyword + "=";
536  foreach(QString val, values) {
537  commandline += val + " ";
538  }
539  }
540  }
541  std::cout << commandline << std::endl;
542  return;
543  }
544 
545  for (int o = lab.objects() - 1; o >= 0; o--) {
546  if ( lab.object(o).isNamed( ProgramName() ) ) {
547  Isis::PvlObject &obj = lab.object(o);
548  for (int g = obj.groups() - 1; g >= 0; g--) {
549  Isis::PvlGroup &up = obj.group(g);
550  if ( up.isNamed("UserParameters") ) {
551  for (int k = 0; k < up.keywords(); k++) {
552  QString keyword = up[k].name();
553  QString value = up[k][0];
554  PutAsString(keyword, value);
555  }
556  }
557  return;
558  }
559  }
560  }
561 
562  /*QString msg = "[" + hist.expanded() +
563  "] does not contain any parameters to restore";
564  throw Isis::iException::Message( Isis::iException::User, msg, _FILEINFO_ );*/
565  }
566  catch (...) {
567  QString msg = "The history file [" + file + "] is for a different application or corrupt, "\
568  "please fix or delete this file";
570  }
571  }
572  else {
573  QString msg = "The history file [" + file + "] does not exist";
575  }
576  }
577 
578 
593  void UserInterface::evaluateOption(const QString name,
594  const QString value) {
595  // check to see if the program is a unitTest
596  bool unitTest = false;
597  if (FileName(p_progName).name() == "unitTest") {
598  unitTest = true;
599  }
600  Preference &p = Preference::Preferences();
601 
602  if (name == "-GUI") {
603  p_interactive = true;
604  }
605  else if (name == "-NOGUI") {
606  p_interactive = false;
607  }
608  else if (name == "-BATCHLIST") {
609  loadBatchList(value);
610  }
611  else if (name == "-LAST") {
612  QString histFile;
613  // need to handle for unit test since -LAST is preprocessed
614  if (unitTest) {
615  histFile = "./" + FileName(p_progName).name() + ".par";
616  }
617  else {
618  PvlGroup &grp = p.findGroup("UserInterface", Isis::Pvl::Traverse);
619  histFile = grp["HistoryPath"][0] + "/" + FileName(p_progName).name() + ".par";
620  }
621 
622  loadHistory(histFile);
623  }
624  else if(name == "-RESTORE") {
625  loadHistory(value);
626  }
627  else if(name == "-WEBHELP") {
628  Isis::PvlGroup &pref = Isis::Preference::Preferences().findGroup("UserInterface");
629  QString command = pref["GuiHelpBrowser"];
630  command += " $ISISROOT/doc/Application/presentation/Tabbed/";
631  command += FileName(p_progName).name() + "/" + FileName(p_progName).name() + ".html";
632  // cannot test else in unit test - don't want to open webhelp
633  if (unitTest) {
635  "Evaluating -WEBHELP should only throw this exception during a unitTest",
636  _FILEINFO_);
637  }
638  else {
640  exit(0);
641  }
642 
643  }
644  else if (name == "-INFO") {
645  p_info = true;
646 
647  // check for filename and set value
648  if (value.size() != 0) {
649  p_infoFileName = value;
650  }
651  }
652  else if (name == "-HELP") {
653  if (value.size() == 0) {
654  Pvl params;
655  params.setTerminator("");
656  for (int k = 0; k < NumGroups(); k++) {
657  for (int j = 0; j < NumParams(k); j++) {
658  if (ParamListSize(k, j) == 0) {
659  params += PvlKeyword( ParamName(k, j), ParamDefault(k, j) );
660  }
661  else {
662  PvlKeyword key( ParamName(k, j) );
663  QString def = ParamDefault(k, j);
664  for (int l = 0; l < ParamListSize(k, j); l++) {
665  if (ParamListValue(k, j, l) == def)
666  key.addValue("*" + def);
667  else
668  key.addValue( ParamListValue(k, j, l) );
669  }
670  params += key;
671  }
672  }
673  }
674  cout << params;
675  }
676  else {
677  Pvl param;
678  param.setTerminator("");
679  QString key = value;
680  for (int k = 0; k < NumGroups(); k++) {
681  for (int j = 0; j < NumParams(k); j++) {
682  if (ParamName(k, j) == key) {
683  param += PvlKeyword("ParameterName", key);
684  param += PvlKeyword( "Brief", ParamBrief(k, j) );
685  param += PvlKeyword( "Type", ParamType(k, j) );
686  if (PixelType(k, j) != "") {
687  param += PvlKeyword( "PixelType", PixelType(k, j) );
688  }
689  if (ParamInternalDefault(k, j) != "") {
690  param += PvlKeyword( "InternalDefault", ParamInternalDefault(k, j) );
691  }
692  else {
693  param += PvlKeyword( "Default", ParamDefault(k, j) );
694  }
695  if (ParamMinimum(k, j) != "") {
696  if (ParamMinimumInclusive(k, j).toUpper() == "YES") {
697  param += PvlKeyword( "GreaterThanOrEqual",
698  ParamMinimum(k, j) );
699  }
700  else {
701  param += PvlKeyword( "GreaterThan",
702  ParamMinimum(k, j) );
703  }
704  }
705  if (ParamMaximum(k, j) != "") {
706  if (ParamMaximumInclusive(k, j).toUpper() == "YES") {
707  param += PvlKeyword( "LessThanOrEqual",
708  ParamMaximum(k, j) );
709  }
710  else {
711  param += PvlKeyword( "LessThan",
712  ParamMaximum(k, j) );
713  }
714  }
715  if (ParamLessThanSize(k, j) > 0) {
716  PvlKeyword key("LessThan");
717  for(int l = 0; l < ParamLessThanSize(k, j); l++) {
718  key.addValue( ParamLessThan(k, j, l) );
719  }
720  param += key;
721  }
722  if (ParamLessThanOrEqualSize(k, j) > 0) {
723  PvlKeyword key("LessThanOrEqual");
724  for (int l = 0; l < ParamLessThanOrEqualSize(k, j); l++) {
725  key.addValue( ParamLessThanOrEqual(k, j, l) );
726  }
727  param += key;
728  }
729  if (ParamNotEqualSize(k, j) > 0) {
730  PvlKeyword key("NotEqual");
731  for (int l = 0; l < ParamNotEqualSize(k, j); l++) {
732  key.addValue( ParamNotEqual(k, j, l) );
733  }
734  param += key;
735  }
736  if (ParamGreaterThanSize(k, j) > 0) {
737  PvlKeyword key("GreaterThan");
738  for (int l = 0; l < ParamGreaterThanSize(k, j); l++) {
739  key.addValue( ParamGreaterThan(k, j, l) );
740  }
741  param += key;
742  }
743  if (ParamGreaterThanOrEqualSize(k, j) > 0) {
744  PvlKeyword key("GreaterThanOrEqual");
745  for(int l = 0; l < ParamGreaterThanOrEqualSize(k, j); l++) {
746  key.addValue( ParamGreaterThanOrEqual(k, j, l) );
747  }
748  param += key;
749  }
750  if (ParamIncludeSize(k, j) > 0) {
751  PvlKeyword key("Inclusions");
752  for (int l = 0; l < ParamIncludeSize(k, j); l++) {
753  key.addValue( ParamInclude(k, j, l) );
754  }
755  param += key;
756  }
757  if (ParamExcludeSize(k, j) > 0) {
758  PvlKeyword key("Exclusions");
759  for (int l = 0; l < ParamExcludeSize(k, j); l++) {
760  key.addValue( ParamExclude(k, j, l) );
761  }
762  param += key;
763  }
764  if (ParamOdd(k, j) != "") {
765  param += PvlKeyword( "Odd", ParamOdd(k, j) );
766  }
767  if (ParamListSize(k, j) != 0) {
768  for (int l = 0; l < ParamListSize(k, j); l++) {
769  PvlGroup grp( ParamListValue(k, j, l) );
770  grp += PvlKeyword( "Brief", ParamListBrief(k, j, l) );
771  if (ParamListIncludeSize(k, j, l) != 0) {
772  PvlKeyword include("Inclusions");
773  for (int m = 0; m < ParamListIncludeSize(k, j, l); m++) {
774  include.addValue( ParamListInclude(k, j, l, m) );
775  }
776  grp += include;
777  }
778  if (ParamListExcludeSize(k, j, l) != 0) {
779  PvlKeyword exclude("Exclusions");
780  for (int m = 0; m < ParamListExcludeSize(k, j, l); m++) {
781  exclude.addValue( ParamListExclude(k, j, l, m) );
782  }
783  grp += exclude;
784  }
785  param.addGroup(grp);
786  }
787  }
788  cout << param;
789  }
790  }
791  }
792  }
793  // we must throw an exception for unitTest to handle to continue testing
794  if (unitTest) {
796  "Evaluating -HELP should only throw this exception during a unitTest",
797  _FILEINFO_);
798  }
799  // all other apps shall exit when -HELP is present
800  else {
801  exit(0);
802  }
803  }
804  else if (name == "-PID") {
805  p_parentId = toInt(value);
806  }
807  else if (name == "-ERRLIST") {
808  p_errList = value;
809 
810  if (value == "") {
811  QString msg = "-ERRLIST expects a file name";
813  }
814 
815  if ( FileName(p_errList).fileExists() ) {
816  QFile::remove(p_errList);
817  }
818  }
819  else if (name == "-ONERROR") {
820  if (value.toUpper() == "CONTINUE") {
821  p_abortOnError = false;
822  }
823 
824  else if (value.toUpper() == "ABORT") {
825  p_abortOnError = true;
826  }
827 
828  else {
829  QString msg = "[" + value
830  + "] is an invalid value for -ONERROR, options are ABORT or CONTINUE";
832  }
833  }
834  else if (name == "-SAVE") {
835  if (value.size() == 0) {
836  p_saveFile = ProgramName() + ".par";
837  }
838  else {
839  p_saveFile = value;
840  }
841  }
842  else if (name == "-PREFERENCE") {
843  p.Load(value);
844  }
845  else if (name == "-LOG") {
846  if( value.isEmpty() ) {
847  p.findGroup("SessionLog")["FileOutput"].setValue("On");
848  }
849  else {
850  p.findGroup("SessionLog")["FileOutput"].setValue("On");
851  p.findGroup("SessionLog")["FileName"].setValue(value);
852  }
853  }
854  // this only evaluates to true in unit test since this is last else if
855  else if (name == "-VERBOSE") {
856  p.findGroup("SessionLog")["TerminalOutput"].setValue("On");
857  }
858 
859  // Can't have a parent id and the gui
860  if (p_parentId > 0 && p_interactive) {
861  QString msg = "-GUI and -PID are incompatible arguments";
863  }
864  }
865 
866 
878  void UserInterface::getNextParameter(unsigned int &curPos,
879  QString &name,
880  std::vector<QString> &value) {
881  QString paramName = p_cmdline[curPos];
882  QString paramValue = "";
883 
884  // we need to split name and value, they can either be in 1, 2 or 3 arguments,
885  // try to see if "=" is end of argument to distinguish. Some options have no
886  // "=" and they are value-less (-gui for example).
887  if ( !paramName.contains("=") ) {
888  // This looks value-less, but lets make sure
889  // the next argument is not an equals sign by
890  // itself
891  if (curPos < p_cmdline.size() - 2) {
892  if (QString(p_cmdline[curPos + 1]).compare("=") == 0) {
893  paramValue = p_cmdline[curPos + 2];
894 
895  // increment extra to skip 2 elements next time around
896  curPos += 2;
897  }
898  }
899  }
900  // = is end of parameter, next item must be value
901  else if ( paramName.endsWith("=") ) {
902  paramName = paramName.mid(0, paramName.size() - 1);
903 
904  if (curPos + 1 < p_cmdline.size() ) {
905  paramValue = p_cmdline[curPos + 1];
906  }
907 
908  // increment extra to skip next element next time around
909  curPos++ ;
910  }
911  // we found "=" in the middle
912  else if (paramName.indexOf("=") > 0) {
913  QString parameterLiteral = p_cmdline[curPos];
914  paramName = parameterLiteral.mid( 0, parameterLiteral.indexOf("=") );
915  paramValue = parameterLiteral.mid(parameterLiteral.indexOf("=") + 1);
916  }
917  // We found "=" at the beginning - did we find "appname param =value" ?
918  else {
919  // parameters can not start with "="
920  QString msg = "Unknown parameter [" + QString(p_cmdline[curPos])
921  + "]";
923  }
924 
925  name = paramName;
926  value.clear();
927 
928  // read arrays out of paramValue
929  paramValue = paramValue.trimmed();
930 
931  if (paramValue.length() > 0 && paramValue[0] != '(') {
932  // We dont have an array... if they escaped
933  // an open paren, undo their escape
934 
935  // escape: \( result: (
936  if (paramValue.length() > 1 && paramValue.mid(0, 2) =="\\(") {
937  paramValue = paramValue.mid(1);
938  }
939  // escape: \\( result: \(
940  else if (paramValue.length() > 2 && paramValue.mid(0, 3) == "\\\\(") {
941  paramValue = paramValue.mid(1);
942  }
943 
944  value.push_back(paramValue);
945  }
946  else if ( paramValue.length() ) {
947  // We have an array...
948  value = readArray(paramValue);
949  }
950  }
951 
952 
965  void UserInterface::preProcess(QString fullReservedName,
966  std::vector<QString> &reservedParams) {
967  for (unsigned int currArgument = 1; currArgument < (unsigned)p_cmdline.size();
968  currArgument++) {
969 
970  QString paramName = p_cmdline[currArgument];
971  QString trueParamValue = "";
972  vector<QString> paramValue;
973 
974  // reserved parameters start with -
975  if (paramName[0] == '-') {
976 
977  // grab the current argument
978  getNextParameter(currArgument, paramName, paramValue);
979  paramName = paramName.toUpper();
980 
981  // grab the argument's value
982  if ( paramValue.size() ) {
983  trueParamValue = paramValue[0].toUpper();
984  }
985 
986  // resolve the reserved parameter token
987  paramName = resolveParameter(paramName, reservedParams, false);
988 
989  // evaluate the resolved parameter if it matches fullReservedName
990  if (fullReservedName == paramName) {
991  evaluateOption(paramName, trueParamValue);
992  }
993  }
994  }
995  }
996 
997 
1011  std::vector<QString> UserInterface::readArray(QString arrayString) {
1012  std::vector<QString> values;
1013 
1014  bool inDoubleQuotes = false;
1015  bool inSingleQuotes = false;
1016  bool arrayClosed = false;
1017  bool nextElementStarted = false;
1018  QString currElement = "";
1019 
1020  for (int strPos = 0; strPos < arrayString.size(); strPos++) {
1021  if (strPos == 0) {
1022  if (arrayString[strPos] != '(') {
1023  QString msg = "Invalid array format [" + arrayString + "]";
1024  throw IException(IException::User, msg, _FILEINFO_);
1025  }
1026 
1027  continue;
1028  }
1029 
1030  // take literally anything that is escaped and not quoted
1031  if ( arrayString[strPos] == '\\' && strPos + 1 < (int)arrayString.size() ) {
1032  currElement += arrayString[strPos+1];
1033  strPos++;
1034  continue;
1035  }
1036  // ends in a backslash??
1037  else if (arrayString[strPos] == '\\') {
1038  QString msg = "Invalid array format [" + arrayString + "]";
1039  throw IException(IException::User, msg, _FILEINFO_);
1040  }
1041 
1042  // not in quoted part of QString
1043  if (!inDoubleQuotes && !inSingleQuotes) {
1044  if (arrayClosed) {
1045  QString msg = "Invalid array format [" + arrayString + "]";
1046  throw IException(IException::User, msg, _FILEINFO_);
1047  }
1048 
1049  nextElementStarted = (nextElementStarted || arrayString[strPos] != ' ');
1050 
1051  if (!nextElementStarted) {
1052  continue;
1053  }
1054 
1055  if (arrayString[strPos] == '"') {
1056  inDoubleQuotes = true;
1057  }
1058  else if (arrayString[strPos] == '\'') {
1059  inSingleQuotes = true;
1060  }
1061  else if (arrayString[strPos] == ',') {
1062  values.push_back(currElement);
1063  currElement = "";
1064  nextElementStarted = false;
1065  }
1066  else if (arrayString[strPos] == ')') {
1067  values.push_back(currElement);
1068  currElement = "";
1069  arrayClosed = true;
1070  nextElementStarted = false;
1071  }
1072  else if (nextElementStarted && arrayString[strPos] == ' ') {
1073  // Make sure there's something before the next ',' or ')'
1074  bool onlyWhite = true;
1075  int closingPos = strPos + 1;
1076 
1077  for( int pos = strPos;
1078  onlyWhite && arrayString[pos] != ',' && arrayString[pos] != ')' &&
1079  pos < arrayString.size(); pos++) {
1080  closingPos++;
1081  onlyWhite &= (arrayString[pos] == ' ');
1082  }
1083 
1084  if (!onlyWhite) {
1085  currElement += arrayString[strPos];
1086  }
1087  }
1088  else if (nextElementStarted) {
1089  currElement += arrayString[strPos];
1090  }
1091  }
1092  else if (inSingleQuotes) {
1093  if(arrayString[strPos] == '\'') {
1094  inSingleQuotes = false;
1095  }
1096  else {
1097  currElement += arrayString[strPos];
1098  }
1099  }
1100  // in double quotes
1101  else {
1102  if (arrayString[strPos] == '"') {
1103  inDoubleQuotes = false;
1104  }
1105  else {
1106  currElement += arrayString[strPos];
1107  }
1108  }
1109  }
1110 
1111  if (!arrayClosed || currElement != "") {
1112  QString msg = "Invalid array format [" + arrayString + "]";
1113  throw IException(IException::User, msg, _FILEINFO_);
1114  }
1115 
1116  return values;
1117  }
1118 
1119 
1138  QString UserInterface::resolveParameter(QString &unresolvedParam,
1139  std::vector<QString> &reservedParams,
1140  bool handleNoMatches) {
1141  // index of the reserved parameter in options that matches the cmdline parameter
1142  int matchOption = -1;
1143  // determine if the reserved parameter on cmdline is shortened (e.g. -h for -HELP)
1144  for (int option = 0; option < (int)reservedParams.size(); option++) {
1145 
1146  // If our option starts with the parameter name so far, this is it
1147  if ( reservedParams[option].startsWith(unresolvedParam) ) {
1148  if (matchOption >= 0) {
1149  QString msg = "Ambiguous Reserve Parameter ["
1150  + unresolvedParam + "]. Please clarify.";
1151  throw IException(IException::User, msg, _FILEINFO_);
1152  }
1153  // set match to current iteration in loop
1154  matchOption = option;
1155  }
1156  }
1157  // handle matches by default
1158  if (handleNoMatches) {
1159  // handle no matches
1160  if (matchOption < 0) {
1161  QString msg = "Invalid Reserve Parameter Option ["
1162  + unresolvedParam + "]. Choices are ";
1163 
1164  QString msgOptions;
1165  for (int option = 0; option < (int)reservedParams.size(); option++) {
1166  // Make sure not to show -PID as an option
1167  if (reservedParams[option].compare("-PID") == 0) {
1168  continue;
1169  }
1170 
1171  msgOptions += reservedParams[option];
1172  msgOptions += ",";
1173 
1174  // this condition will never evaluate to FALSE -
1175  // this condition is only reachable when reservedParams.size() == 0 (empty) -
1176  // if this is the case, this for loop will never be entered
1177 // if ( !reservedParams.empty() ) {
1178 // msgOptions += ",";
1179 // }
1180  }
1181 
1182  // remove the terminating ',' from msgOptions
1183  msgOptions.chop(1);
1184  msg += " [" + msgOptions + "]";
1185 
1186  throw IException(IException::User, msg, _FILEINFO_);
1187  }
1188  }
1189  if (matchOption < 0) {
1190  return "";
1191  }
1192  else {
1193  return reservedParams[matchOption];
1194  }
1195  }
1196 } // end namespace isis
PvlObject & object(const int index)
Return the object at the specified index.
Definition: PvlObject.cpp:460
int NumParams(const int &) const
Returns the number of parameters in a group.
Definition: IsisAml.cpp:1223
QString ParamListBrief(const int &group, const int &param, const int &option) const
Returns the brief description for a specific option to a parameter.
Definition: IsisAml.cpp:1646
int keywords() const
Returns the number of keywords contained in the PvlContainer.
Definition: PvlContainer.h:100
int ParamLessThanOrEqualSize(const int &group, const int &param) const
Returns the number of values in the parameters less than or equal list.
Definition: IsisAml.cpp:1377
QString ProgramName() const
Returns the Program name.
Definition: IsisAml.cpp:1073
PvlGroupIterator findGroup(const QString &name, PvlGroupIterator beg, PvlGroupIterator end)
Find a group with the specified name, within these indexes.
Definition: PvlObject.h:141
File name manipulation and expansion.
Definition: FileName.h:116
int NumGroups() const
Returns the number of groups found in the XML.
Definition: IsisAml.cpp:1103
QString resolveParameter(QString &name, std::vector< QString > &reservedParams, bool handleNoMatches=true)
This resolves a reserved parameter token on the command line to its fullname.
int ParamListSize(const int &group, const int &param) const
Returns the number of options in the specified parameter&#39;s list.
Definition: IsisAml.cpp:1617
static void checkX11()
check to see if X is available
Definition: Gui.cpp:49
void Open(const QString &filename, const char *openmode="input", const char *extension="")
Opens a text file.
Definition: TextFile.cpp:233
void loadHistory(const QString file)
Loads the previous history for the program.
int ParamGreaterThanSize(const int &group, const int &param) const
Returns the number of values in the parameters greater than list.
Definition: IsisAml.cpp:1340
int ParamListExcludeSize(const int &group, const int &param, const int &option) const
Returns the number of items in a parameters list exclude section.
Definition: IsisAml.cpp:1676
void addGroup(const Isis::PvlGroup &group)
Add a group to the object.
Definition: PvlObject.h:198
int toInt(const QString &string)
Global function to convert from a string to an integer.
Definition: IString.cpp:108
Namespace for the standard library.
QString ParamMaximum(const int &group, const int &param) const
Returns the maximum value of a parameter in a specified group.
Definition: IsisAml.cpp:1287
void PutAsString(const QString &paramName, const QString &value)
Allows the insertion of a value for any parameter.
Definition: IsisAml.cpp:81
QString name() const
Returns the name of the file excluding the path and the attributes in the file name.
Definition: FileName.cpp:178
int BatchListSize()
Returns the size of the batchlist.
Search child objects.
Definition: PvlObject.h:170
int p_parentId
This is a status to indicate if the GUI is running or not.
Gui * p_gui
Pointer to the gui object.
QString GetInfoFileName()
This method returns the filename where the debugging info is stored when the "-info" tag is used...
This error is for when a programmer made an API call that was illegal.
Definition: IException.h:162
QString p_saveFile
FileName to save last history to.
int ParamIncludeSize(const int &group, const int &param) const
Returns the number of parameters included in this parameter&#39;s inclusions.
Definition: IsisAml.cpp:1747
std::vector< char * > p_cmdline
This variable will contain argv.
void deleteGroup(const QString &name)
Remove a group from the current PvlObject.
Definition: PvlObject.cpp:379
const IsisParameterData * ReturnParam(const QString &paramName) const
Returns a pointer to a parameter whose name starts with paramName.
Definition: IsisAml.cpp:1981
QString ParamType(const int &group, const int &param) const
Returns the parameter type of a parameter in a specified group.
Definition: IsisAml.cpp:1508
int ParamListIncludeSize(const int &group, const int &param, const int &option) const
Returns the number of items in a parameters list include section.
Definition: IsisAml.cpp:1706
void SaveHistory()
Saves the user parameter information in the history of the program for later use. ...
QString ParamInternalDefault(const int &group, const int &param) const
Returns the internal default for a parameter in a specified group.
Definition: IsisAml.cpp:1540
QString name() const
Returns the container name.
Definition: PvlContainer.h:77
QString PixelType(const int &group, const int &param) const
Returns the default pixel type from the XML.
Definition: IsisAml.cpp:1759
void setTerminator(const QString &term)
Sets the terminator used to signify the end of the PVL informationDefaults to "END".
Definition: Pvl.h:159
static void RunSystemCommand(QString commandLine)
This runs arbitrary system commands.
QString ParamListExclude(const int &group, const int &param, const int &option, const int &exclude) const
Returns the parameter name to be excluded if this option is selected.
Definition: IsisAml.cpp:1691
QString ParamGreaterThanOrEqual(const int &group, const int &param, const int &great) const
Returns the name of the specified greaterThanOrEqual parameter.
Definition: IsisAml.cpp:1418
QString ParamNotEqual(const int &group, const int &param, const int &notEq) const
Returns the name of the specified notEqual parameter.
Definition: IsisAml.cpp:1463
QString ParamOdd(const int &group, const int &param) const
Returns whether the selected parameter has a restriction on odd values or not.
Definition: IsisAml.cpp:1327
IString Compress(bool force=false)
Collapses multiple spaces into single spaces.
Definition: IString.cpp:989
IString Token(const IString &separator)
Returns the first token in the IString.
Definition: IString.cpp:912
QString ParamListInclude(const int &group, const int &param, const int &option, const int &include) const
Returns the parameter name to be included if this option is selected.
Definition: IsisAml.cpp:1721
Contains multiple PvlContainers.
Definition: PvlGroup.h:57
void evaluateOption(const QString name, const QString value)
This interprets the "-" options for reserved parameters.
#define _FILEINFO_
Macro for the filename and line number.
Definition: IException.h:40
A type of error that could only have occurred due to a mistake on the user&#39;s part (e...
Definition: IException.h:142
A single keyword-value pair.
Definition: PvlKeyword.h:98
QString p_infoFileName
FileName to save debugging info.
void loadBatchList(const QString file)
Loads the user entered batchlist file into a private variable for later use.
A type of error that cannot be classified as any of the other error types.
Definition: IException.h:134
QString ToQt() const
Retuns the object string as a QString.
Definition: IString.cpp:884
int LineCount(const int &maxLinesToRead=0)
Counts number of lines in file.
Definition: TextFile.cpp:623
QString expanded() const
Returns a QString of the full file name including the file path, excluding the attributes.
Definition: FileName.cpp:212
bool GetLine(QString &line, const bool skipComments=true)
Gets next line from file.
Definition: TextFile.cpp:427
int ParamLessThanSize(const int &group, const int &param) const
Returns the number of values in the parameters less than list.
Definition: IsisAml.cpp:1365
bool GetInfoFlag()
This method returns the flag state of info.
void Clear(const QString &paramName)
Clears the value(s) in the named parameter.
Definition: IsisAml.cpp:1868
QDir dir() const
Returns the path of the file&#39;s parent directory as a QDir object.
Definition: FileName.cpp:481
std::vector< std::vector< QString > > p_batchList
Vector of batchlist data.
void CommandLine(Isis::Pvl &lab) const
Creates a QString which could be used as a command line.
Definition: IsisAml.cpp:2926
Container for cube-like labels.
Definition: Pvl.h:135
~UserInterface()
Destroys the UserInterface object.
bool p_interactive
Boolean value representing whether the program is interactive or not.
QString ParamMaximumInclusive(const int &group, const int &param) const
Returns whether the maximum value is inclusive or not.
Definition: IsisAml.cpp:1313
QString ParamMinimum(const int &group, const int &param) const
Returns the minimum value of a parameter in a specified group.
Definition: IsisAml.cpp:1274
void loadCommandLine(int argc, char *argv[])
This is used to load the command line into p_cmdline and the Aml object using information contained i...
QString p_progName
Name of program to run.
Application program XML file parameter manager.
Definition: IsisAml.h:154
bool isNamed(const QString &match) const
Returns whether the given string is equal to the container name or not.
Definition: PvlContainer.h:86
QString p_errList
FileName to write batchlist line that caused error on.
Provides access to sequential ASCII stream I/O.
Definition: TextFile.h:54
int ParamExcludeSize(const int &group, const int &param) const
Returns the number of parameters excluded in this parameter&#39;s exclusions.
Definition: IsisAml.cpp:1735
PvlGroup & group(const int index)
Return the group at the specified index.
Definition: PvlObject.cpp:423
int ParamGreaterThanOrEqualSize(const int &group, const int &param) const
Returns the number of values in the parameters greater than or equal list.
Definition: IsisAml.cpp:1352
IString Replace(const std::string &from, const std::string &to, int maxReplaceCount=20)
Replaces all instances of the first input string with the second input string.
Definition: IString.cpp:1052
Isis exception class.
Definition: IException.h:107
Adds specific functionality to C++ strings.
Definition: IString.h:181
Namespace for ISIS/Bullet specific routines.
Definition: Apollo.h:31
void VerifyAll()
Verify all parameters.
Definition: IsisAml.cpp:2403
bool p_info
Boolean value representing if it&#39;s in debug mode.
QString ParamDefault(const int &group, const int &param) const
Returns the default for a parameter in a specified group.
Definition: IsisAml.cpp:1521
int groups() const
Returns the number of groups contained.
Definition: PvlObject.h:87
std::vector< QString > readArray(QString arrayString)
This interprets an array value from the command line.
QString ParamLessThanOrEqual(const int &group, const int &param, const int &les) const
Returns the name of the specified lessThanOrEqual parameter.
Definition: IsisAml.cpp:1448
void SetBatchList(int i)
Clears the gui parameters and sets the batch list information at line i as the new parameters...
void write(const QString &file)
Opens and writes PVL information to a file and handles the end of line sequence.
Definition: Pvl.cpp:116
QString ParamMinimumInclusive(const int &group, const int &param) const
Returns whether the minimum value is inclusive or not.
Definition: IsisAml.cpp:1300
QString ParamBrief(const int &group, const int &param) const
Returns the brief description of a parameter in a specified group.
Definition: IsisAml.cpp:1248
void SetErrorList(int i)
This method adds the line specified in the BatchList that the error occured on.
QString ParamGreaterThan(const int &group, const int &param, const int &great) const
Returns the name of the specified greaterThan parameter.
Definition: IsisAml.cpp:1403
Contains Pvl Groups and Pvl Objects.
Definition: PvlObject.h:74
QString ParamName(const int &group, const int &param) const
Returns the parameter name.
Definition: IsisAml.cpp:1235
void read(const QString &file)
Loads PVL information from a stream.
Definition: Pvl.cpp:76
void getNextParameter(unsigned int &curPos, QString &unresolvedParam, std::vector< QString > &value)
This gets the next parameter in the list of arguments.
QString ParamLessThan(const int &group, const int &param, const int &great) const
Returns the name of the specified lessThan parameter.
Definition: IsisAml.cpp:1433
QString ParamListValue(const int &group, const int &param, const int &option) const
Returns the option value for a specific option to a parameter.
Definition: IsisAml.cpp:1631
QString ParamExclude(const int &group, const int &param, const int &exclude) const
Returns the name of the specified excluded parameter.
Definition: IsisAml.cpp:1478
bool fileExists() const
Returns true if the file exists; false otherwise.
Definition: FileName.cpp:465
void preProcess(QString fullReservedName, std::vector< QString > &reservedParams)
This parses the command line and looks for the specified reserved parameter name passed.
bool p_abortOnError
Boolean value representing whether to abort or continue on error.
int ParamNotEqualSize(const int &group, const int &param) const
Returns the number of values in the not equal list.
Definition: IsisAml.cpp:1390
Reads user preferences from a data file.
Definition: Preference.h:77
QString ParamInclude(const int &group, const int &param, const int &include) const
Returns the name of the specified included parameter.
Definition: IsisAml.cpp:1493
void addValue(QString value, QString unit="")
Adds a value with units.
Definition: PvlKeyword.cpp:268