Isis 3.0 Programmer Reference
Back | Home
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  for (int k = 0; k < up.keywords(); k++) {
508  QString keyword = up[k].name();
509 
510  vector<QString> values;
511 
512  for (int i = 0; i < up[k].size(); i++) {
513  values.push_back(up[k][i]);
514  }
515 
516  const IsisParameterData *paramData = ReturnParam(keyword);
517 
518  bool matchesDefault = false;
519  if (values.size() == 1 && paramData->internalDefault == values[0])
520  matchesDefault = true;
521 
522  if (!matchesDefault) {
523  matchesDefault =
524  (values.size() == paramData->defaultValues.size());
525 
526  for (int i = 0; matchesDefault && i < (int)values.size(); i++) {
527  matchesDefault = matchesDefault &&
528  values[i] == paramData->defaultValues[i];
529  }
530  }
531 
532  if (!matchesDefault)
533  PutAsString(keyword, values);
534  }
535  return;
536  }
537 
538  for (int o = lab.objects() - 1; o >= 0; o--) {
539  if ( lab.object(o).isNamed( ProgramName() ) ) {
540  Isis::PvlObject &obj = lab.object(o);
541  for (int g = obj.groups() - 1; g >= 0; g--) {
542  Isis::PvlGroup &up = obj.group(g);
543  if ( up.isNamed("UserParameters") ) {
544  for (int k = 0; k < up.keywords(); k++) {
545  QString keyword = up[k].name();
546  QString value = up[k][0];
547  PutAsString(keyword, value);
548  }
549  }
550  return;
551  }
552  }
553  }
554 
555  /*QString msg = "[" + hist.expanded() +
556  "] does not contain any parameters to restore";
557  throw Isis::iException::Message( Isis::iException::User, msg, _FILEINFO_ );*/
558  }
559  catch (...) {
560  QString msg = "The history file [" + file + "] is for a different application or corrupt, "\
561  "please fix or delete this file";
563  }
564  }
565  else {
566  QString msg = "The history file [" + file + "] does not exist";
568  }
569  }
570 
571 
586  void UserInterface::evaluateOption(const QString name,
587  const QString value) {
588  // check to see if the program is a unitTest
589  bool unitTest = false;
590  if (FileName(p_progName).name() == "unitTest") {
591  unitTest = true;
592  }
593  Preference &p = Preference::Preferences();
594 
595  if (name == "-GUI") {
596  p_interactive = true;
597  }
598  else if (name == "-NOGUI") {
599  p_interactive = false;
600  }
601  else if (name == "-BATCHLIST") {
602  loadBatchList(value);
603  }
604  else if (name == "-LAST") {
605  QString histFile;
606  // need to handle for unit test since -LAST is preprocessed
607  if (unitTest) {
608  histFile = "./" + FileName(p_progName).name() + ".par";
609  }
610  else {
611  PvlGroup &grp = p.findGroup("UserInterface", Isis::Pvl::Traverse);
612  histFile = grp["HistoryPath"][0] + "/" + FileName(p_progName).name() + ".par";
613  }
614 
615  loadHistory(histFile);
616  }
617  else if(name == "-RESTORE") {
618  loadHistory(value);
619  }
620  else if(name == "-WEBHELP") {
621  Isis::PvlGroup &pref = Isis::Preference::Preferences().findGroup("UserInterface");
622  QString command = pref["GuiHelpBrowser"];
623  command += " $ISISROOT/doc/Application/presentation/Tabbed/";
624  command += FileName(p_progName).name() + "/" + FileName(p_progName).name() + ".html";
625  // cannot test else in unit test - don't want to open webhelp
626  if (unitTest) {
628  "Evaluating -WEBHELP should only throw this exception during a unitTest",
629  _FILEINFO_);
630  }
631  else {
633  exit(0);
634  }
635 
636  }
637  else if (name == "-INFO") {
638  p_info = true;
639 
640  // check for filename and set value
641  if (value.size() != 0) {
642  p_infoFileName = value;
643  }
644  }
645  else if (name == "-HELP") {
646  if (value.size() == 0) {
647  Pvl params;
648  params.setTerminator("");
649  for (int k = 0; k < NumGroups(); k++) {
650  for (int j = 0; j < NumParams(k); j++) {
651  if (ParamListSize(k, j) == 0) {
652  params += PvlKeyword( ParamName(k, j), ParamDefault(k, j) );
653  }
654  else {
655  PvlKeyword key( ParamName(k, j) );
656  QString def = ParamDefault(k, j);
657  for (int l = 0; l < ParamListSize(k, j); l++) {
658  if (ParamListValue(k, j, l) == def)
659  key.addValue("*" + def);
660  else
661  key.addValue( ParamListValue(k, j, l) );
662  }
663  params += key;
664  }
665  }
666  }
667  cout << params;
668  }
669  else {
670  Pvl param;
671  param.setTerminator("");
672  QString key = value;
673  for (int k = 0; k < NumGroups(); k++) {
674  for (int j = 0; j < NumParams(k); j++) {
675  if (ParamName(k, j) == key) {
676  param += PvlKeyword("ParameterName", key);
677  param += PvlKeyword( "Brief", ParamBrief(k, j) );
678  param += PvlKeyword( "Type", ParamType(k, j) );
679  if (PixelType(k, j) != "") {
680  param += PvlKeyword( "PixelType", PixelType(k, j) );
681  }
682  if (ParamInternalDefault(k, j) != "") {
683  param += PvlKeyword( "InternalDefault", ParamInternalDefault(k, j) );
684  }
685  else {
686  param += PvlKeyword( "Default", ParamDefault(k, j) );
687  }
688  if (ParamMinimum(k, j) != "") {
689  if (ParamMinimumInclusive(k, j).toUpper() == "YES") {
690  param += PvlKeyword( "GreaterThanOrEqual",
691  ParamMinimum(k, j) );
692  }
693  else {
694  param += PvlKeyword( "GreaterThan",
695  ParamMinimum(k, j) );
696  }
697  }
698  if (ParamMaximum(k, j) != "") {
699  if (ParamMaximumInclusive(k, j).toUpper() == "YES") {
700  param += PvlKeyword( "LessThanOrEqual",
701  ParamMaximum(k, j) );
702  }
703  else {
704  param += PvlKeyword( "LessThan",
705  ParamMaximum(k, j) );
706  }
707  }
708  if (ParamLessThanSize(k, j) > 0) {
709  PvlKeyword key("LessThan");
710  for(int l = 0; l < ParamLessThanSize(k, j); l++) {
711  key.addValue( ParamLessThan(k, j, l) );
712  }
713  param += key;
714  }
715  if (ParamLessThanOrEqualSize(k, j) > 0) {
716  PvlKeyword key("LessThanOrEqual");
717  for (int l = 0; l < ParamLessThanOrEqualSize(k, j); l++) {
718  key.addValue( ParamLessThanOrEqual(k, j, l) );
719  }
720  param += key;
721  }
722  if (ParamNotEqualSize(k, j) > 0) {
723  PvlKeyword key("NotEqual");
724  for (int l = 0; l < ParamNotEqualSize(k, j); l++) {
725  key.addValue( ParamNotEqual(k, j, l) );
726  }
727  param += key;
728  }
729  if (ParamGreaterThanSize(k, j) > 0) {
730  PvlKeyword key("GreaterThan");
731  for (int l = 0; l < ParamGreaterThanSize(k, j); l++) {
732  key.addValue( ParamGreaterThan(k, j, l) );
733  }
734  param += key;
735  }
736  if (ParamGreaterThanOrEqualSize(k, j) > 0) {
737  PvlKeyword key("GreaterThanOrEqual");
738  for(int l = 0; l < ParamGreaterThanOrEqualSize(k, j); l++) {
739  key.addValue( ParamGreaterThanOrEqual(k, j, l) );
740  }
741  param += key;
742  }
743  if (ParamIncludeSize(k, j) > 0) {
744  PvlKeyword key("Inclusions");
745  for (int l = 0; l < ParamIncludeSize(k, j); l++) {
746  key.addValue( ParamInclude(k, j, l) );
747  }
748  param += key;
749  }
750  if (ParamExcludeSize(k, j) > 0) {
751  PvlKeyword key("Exclusions");
752  for (int l = 0; l < ParamExcludeSize(k, j); l++) {
753  key.addValue( ParamExclude(k, j, l) );
754  }
755  param += key;
756  }
757  if (ParamOdd(k, j) != "") {
758  param += PvlKeyword( "Odd", ParamOdd(k, j) );
759  }
760  if (ParamListSize(k, j) != 0) {
761  for (int l = 0; l < ParamListSize(k, j); l++) {
762  PvlGroup grp( ParamListValue(k, j, l) );
763  grp += PvlKeyword( "Brief", ParamListBrief(k, j, l) );
764  if (ParamListIncludeSize(k, j, l) != 0) {
765  PvlKeyword include("Inclusions");
766  for (int m = 0; m < ParamListIncludeSize(k, j, l); m++) {
767  include.addValue( ParamListInclude(k, j, l, m) );
768  }
769  grp += include;
770  }
771  if (ParamListExcludeSize(k, j, l) != 0) {
772  PvlKeyword exclude("Exclusions");
773  for (int m = 0; m < ParamListExcludeSize(k, j, l); m++) {
774  exclude.addValue( ParamListExclude(k, j, l, m) );
775  }
776  grp += exclude;
777  }
778  param.addGroup(grp);
779  }
780  }
781  cout << param;
782  }
783  }
784  }
785  }
786  // we must throw an exception for unitTest to handle to continue testing
787  if (unitTest) {
789  "Evaluating -HELP should only throw this exception during a unitTest",
790  _FILEINFO_);
791  }
792  // all other apps shall exit when -HELP is present
793  else {
794  exit(0);
795  }
796  }
797  else if (name == "-PID") {
798  p_parentId = toInt(value);
799  }
800  else if (name == "-ERRLIST") {
801  p_errList = value;
802 
803  if (value == "") {
804  QString msg = "-ERRLIST expects a file name";
806  }
807 
808  if ( FileName(p_errList).fileExists() ) {
809  QFile::remove(p_errList);
810  }
811  }
812  else if (name == "-ONERROR") {
813  if (value.toUpper() == "CONTINUE") {
814  p_abortOnError = false;
815  }
816 
817  else if (value.toUpper() == "ABORT") {
818  p_abortOnError = true;
819  }
820 
821  else {
822  QString msg = "[" + value
823  + "] is an invalid value for -ONERROR, options are ABORT or CONTINUE";
825  }
826  }
827  else if (name == "-SAVE") {
828  if (value.size() == 0) {
829  p_saveFile = ProgramName() + ".par";
830  }
831  else {
832  p_saveFile = value;
833  }
834  }
835  else if (name == "-PREFERENCE") {
836  p.Load(value);
837  }
838  else if (name == "-LOG") {
839  if( value.isEmpty() ) {
840  p.findGroup("SessionLog")["FileOutput"].setValue("On");
841  }
842  else {
843  p.findGroup("SessionLog")["FileOutput"].setValue("On");
844  p.findGroup("SessionLog")["FileName"].setValue(value);
845  }
846  }
847  // this only evaluates to true in unit test since this is last else if
848  else if (name == "-VERBOSE") {
849  p.findGroup("SessionLog")["TerminalOutput"].setValue("On");
850  }
851 
852  // Can't have a parent id and the gui
853  if (p_parentId > 0 && p_interactive) {
854  QString msg = "-GUI and -PID are incompatible arguments";
856  }
857  }
858 
859 
871  void UserInterface::getNextParameter(unsigned int &curPos,
872  QString &name,
873  std::vector<QString> &value) {
874  QString paramName = p_cmdline[curPos];
875  QString paramValue = "";
876 
877  // we need to split name and value, they can either be in 1, 2 or 3 arguments,
878  // try to see if "=" is end of argument to distinguish. Some options have no
879  // "=" and they are value-less (-gui for example).
880  if ( !paramName.contains("=") ) {
881  // This looks value-less, but lets make sure
882  // the next argument is not an equals sign by
883  // itself
884  if (curPos < p_cmdline.size() - 2) {
885  if (QString(p_cmdline[curPos + 1]).compare("=") == 0) {
886  paramValue = p_cmdline[curPos + 2];
887 
888  // increment extra to skip 2 elements next time around
889  curPos += 2;
890  }
891  }
892  }
893  // = is end of parameter, next item must be value
894  else if ( paramName.endsWith("=") ) {
895  paramName = paramName.mid(0, paramName.size() - 1);
896 
897  if (curPos + 1 < p_cmdline.size() ) {
898  paramValue = p_cmdline[curPos + 1];
899  }
900 
901  // increment extra to skip next element next time around
902  curPos++ ;
903  }
904  // we found "=" in the middle
905  else if (paramName.indexOf("=") > 0) {
906  QString parameterLiteral = p_cmdline[curPos];
907  paramName = parameterLiteral.mid( 0, parameterLiteral.indexOf("=") );
908  paramValue = parameterLiteral.mid(parameterLiteral.indexOf("=") + 1);
909  }
910  // We found "=" at the beginning - did we find "appname param =value" ?
911  else {
912  // parameters can not start with "="
913  QString msg = "Unknown parameter [" + QString(p_cmdline[curPos])
914  + "]";
916  }
917 
918  name = paramName;
919  value.clear();
920 
921  // read arrays out of paramValue
922  paramValue = paramValue.trimmed();
923 
924  if (paramValue.length() > 0 && paramValue[0] != '(') {
925  // We dont have an array... if they escaped
926  // an open paren, undo their escape
927 
928  // escape: \( result: (
929  if (paramValue.length() > 1 && paramValue.mid(0, 2) =="\\(") {
930  paramValue = paramValue.mid(1);
931  }
932  // escape: \\( result: \(
933  else if (paramValue.length() > 2 && paramValue.mid(0, 3) == "\\\\(") {
934  paramValue = paramValue.mid(1);
935  }
936 
937  value.push_back(paramValue);
938  }
939  else if ( paramValue.length() ) {
940  // We have an array...
941  value = readArray(paramValue);
942  }
943  }
944 
945 
958  void UserInterface::preProcess(QString fullReservedName,
959  std::vector<QString> &reservedParams) {
960  for (unsigned int currArgument = 1; currArgument < (unsigned)p_cmdline.size();
961  currArgument++) {
962 
963  QString paramName = p_cmdline[currArgument];
964  QString trueParamValue = "";
965  vector<QString> paramValue;
966 
967  // reserved parameters start with -
968  if (paramName[0] == '-') {
969 
970  // grab the current argument
971  getNextParameter(currArgument, paramName, paramValue);
972  paramName = paramName.toUpper();
973 
974  // grab the argument's value
975  if ( paramValue.size() ) {
976  trueParamValue = paramValue[0].toUpper();
977  }
978 
979  // resolve the reserved parameter token
980  paramName = resolveParameter(paramName, reservedParams, false);
981 
982  // evaluate the resolved parameter if it matches fullReservedName
983  if (fullReservedName == paramName) {
984  evaluateOption(paramName, trueParamValue);
985  }
986  }
987  }
988  }
989 
990 
1004  std::vector<QString> UserInterface::readArray(QString arrayString) {
1005  std::vector<QString> values;
1006 
1007  bool inDoubleQuotes = false;
1008  bool inSingleQuotes = false;
1009  bool arrayClosed = false;
1010  bool nextElementStarted = false;
1011  QString currElement = "";
1012 
1013  for (int strPos = 0; strPos < arrayString.size(); strPos++) {
1014  if (strPos == 0) {
1015  if (arrayString[strPos] != '(') {
1016  QString msg = "Invalid array format [" + arrayString + "]";
1017  throw IException(IException::User, msg, _FILEINFO_);
1018  }
1019 
1020  continue;
1021  }
1022 
1023  // take literally anything that is escaped and not quoted
1024  if ( arrayString[strPos] == '\\' && strPos + 1 < (int)arrayString.size() ) {
1025  currElement += arrayString[strPos+1];
1026  strPos++;
1027  continue;
1028  }
1029  // ends in a backslash??
1030  else if (arrayString[strPos] == '\\') {
1031  QString msg = "Invalid array format [" + arrayString + "]";
1032  throw IException(IException::User, msg, _FILEINFO_);
1033  }
1034 
1035  // not in quoted part of QString
1036  if (!inDoubleQuotes && !inSingleQuotes) {
1037  if (arrayClosed) {
1038  QString msg = "Invalid array format [" + arrayString + "]";
1039  throw IException(IException::User, msg, _FILEINFO_);
1040  }
1041 
1042  nextElementStarted = (nextElementStarted || arrayString[strPos] != ' ');
1043 
1044  if (!nextElementStarted) {
1045  continue;
1046  }
1047 
1048  if (arrayString[strPos] == '"') {
1049  inDoubleQuotes = true;
1050  }
1051  else if (arrayString[strPos] == '\'') {
1052  inSingleQuotes = true;
1053  }
1054  else if (arrayString[strPos] == ',') {
1055  values.push_back(currElement);
1056  currElement = "";
1057  nextElementStarted = false;
1058  }
1059  else if (arrayString[strPos] == ')') {
1060  values.push_back(currElement);
1061  currElement = "";
1062  arrayClosed = true;
1063  nextElementStarted = false;
1064  }
1065  else if (nextElementStarted && arrayString[strPos] == ' ') {
1066  // Make sure there's something before the next ',' or ')'
1067  bool onlyWhite = true;
1068  int closingPos = strPos + 1;
1069 
1070  for( int pos = strPos;
1071  onlyWhite && arrayString[pos] != ',' && arrayString[pos] != ')' &&
1072  pos < arrayString.size(); pos++) {
1073  closingPos++;
1074  onlyWhite &= (arrayString[pos] == ' ');
1075  }
1076 
1077  if (!onlyWhite) {
1078  currElement += arrayString[strPos];
1079  }
1080  }
1081  else if (nextElementStarted) {
1082  currElement += arrayString[strPos];
1083  }
1084  }
1085  else if (inSingleQuotes) {
1086  if(arrayString[strPos] == '\'') {
1087  inSingleQuotes = false;
1088  }
1089  else {
1090  currElement += arrayString[strPos];
1091  }
1092  }
1093  // in double quotes
1094  else {
1095  if (arrayString[strPos] == '"') {
1096  inDoubleQuotes = false;
1097  }
1098  else {
1099  currElement += arrayString[strPos];
1100  }
1101  }
1102  }
1103 
1104  if (!arrayClosed || currElement != "") {
1105  QString msg = "Invalid array format [" + arrayString + "]";
1106  throw IException(IException::User, msg, _FILEINFO_);
1107  }
1108 
1109  return values;
1110  }
1111 
1112 
1131  QString UserInterface::resolveParameter(QString &unresolvedParam,
1132  std::vector<QString> &reservedParams,
1133  bool handleNoMatches) {
1134  // index of the reserved parameter in options that matches the cmdline parameter
1135  int matchOption = -1;
1136  // determine if the reserved parameter on cmdline is shortened (e.g. -h for -HELP)
1137  for (int option = 0; option < (int)reservedParams.size(); option++) {
1138 
1139  // If our option starts with the parameter name so far, this is it
1140  if ( reservedParams[option].startsWith(unresolvedParam) ) {
1141  if (matchOption >= 0) {
1142  QString msg = "Ambiguous Reserve Parameter ["
1143  + unresolvedParam + "]. Please clarify.";
1144  throw IException(IException::User, msg, _FILEINFO_);
1145  }
1146  // set match to current iteration in loop
1147  matchOption = option;
1148  }
1149  }
1150  // handle matches by default
1151  if (handleNoMatches) {
1152  // handle no matches
1153  if (matchOption < 0) {
1154  QString msg = "Invalid Reserve Parameter Option ["
1155  + unresolvedParam + "]. Choices are ";
1156 
1157  QString msgOptions;
1158  for (int option = 0; option < (int)reservedParams.size(); option++) {
1159  // Make sure not to show -PID as an option
1160  if (reservedParams[option].compare("-PID") == 0) {
1161  continue;
1162  }
1163 
1164  msgOptions += reservedParams[option];
1165  msgOptions += ",";
1166 
1167  // this condition will never evaluate to FALSE -
1168  // this condition is only reachable when reservedParams.size() == 0 (empty) -
1169  // if this is the case, this for loop will never be entered
1170 // if ( !reservedParams.empty() ) {
1171 // msgOptions += ",";
1172 // }
1173  }
1174 
1175  // remove the terminating ',' from msgOptions
1176  msgOptions.chop(1);
1177  msg += " [" + msgOptions + "]";
1178 
1179  throw IException(IException::User, msg, _FILEINFO_);
1180  }
1181  }
1182  if (matchOption < 0) {
1183  return "";
1184  }
1185  else {
1186  return reservedParams[matchOption];
1187  }
1188  }
1189 } // 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
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
PvlGroupIterator findGroup(const QString &name, PvlGroupIterator beg, PvlGroupIterator end)
Find a group with the specified name, within these indexes.
Definition: PvlObject.h:141
QString ToQt() const
Retuns the object string as a QString.
Definition: IString.cpp:884
QString ParamDefault(const int &group, const int &param) const
Returns the default for a parameter in a specified group.
Definition: IsisAml.cpp:1521
File name manipulation and expansion.
Definition: FileName.h:111
QString ParamMinimum(const int &group, const int &param) const
Returns the minimum value of a parameter in a specified group.
Definition: IsisAml.cpp:1274
const IsisParameterData * ReturnParam(const QString &paramName) const
Returns a pointer to a parameter whose name starts with paramName.
Definition: IsisAml.cpp:1981
QString resolveParameter(QString &name, std::vector< QString > &reservedParams, bool handleNoMatches=true)
This resolves a reserved parameter token on the command line to its fullname.
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
static void checkX11()
check to see if X is available
Definition: Gui.cpp:48
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.
QString ParamMaximum(const int &group, const int &param) const
Returns the maximum value of a parameter in a specified group.
Definition: IsisAml.cpp:1287
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
int ParamNotEqualSize(const int &group, const int &param) const
Returns the number of values in the not equal list.
Definition: IsisAml.cpp:1390
int keywords() const
Returns the number of keywords contained in the PvlContainer.
Definition: PvlContainer.h:101
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
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
void PutAsString(const QString &paramName, const QString &value)
Allows the insertion of a value for any parameter.
Definition: IsisAml.cpp:81
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.
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
Gui * p_gui
Pointer to the gui object.
QString GetInfoFileName()
This method returns the filename where the debugging info is stored when the &quot;-info&quot; tag is used...
This error is for when a programmer made an API call that was illegal.
Definition: IException.h:154
QString p_saveFile
FileName to save last history to.
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
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 SaveHistory()
Saves the user parameter information in the history of the program for later use. ...
void setTerminator(const QString &term)
Sets the terminator used to signify the end of the PVL informationDefaults to &quot;END&quot;.
Definition: Pvl.h:159
static void RunSystemCommand(QString commandLine)
This runs arbitrary system commands.
QString ParamLessThan(const int &group, const int &param, const int &great) const
Returns the name of the specified lessThan parameter.
Definition: IsisAml.cpp:1433
IString Compress(bool force=false)
Collapses multiple spaces into single spaces.
Definition: IString.cpp:989
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 ParamMinimumInclusive(const int &group, const int &param) const
Returns whether the minimum value is inclusive or not.
Definition: IsisAml.cpp:1300
IString Token(const IString &separator)
Returns the first token in the IString.
Definition: IString.cpp:912
QString ParamInclude(const int &group, const int &param, const int &include) const
Returns the name of the specified included parameter.
Definition: IsisAml.cpp:1493
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 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
Contains multiple PvlContainers.
Definition: PvlGroup.h:57
void evaluateOption(const QString name, const QString value)
This interprets the &quot;-&quot; options for reserved parameters.
#define _FILEINFO_
Macro for the filename and line number.
Definition: IException.h:38
QString ParamExclude(const int &group, const int &param, const int &exclude) const
Returns the name of the specified excluded parameter.
Definition: IsisAml.cpp:1478
A type of error that could only have occurred due to a mistake on the user&#39;s part (e...
Definition: IException.h:134
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.
int ParamLessThanSize(const int &group, const int &param) const
Returns the number of values in the parameters less than list.
Definition: IsisAml.cpp:1365
A type of error that cannot be classified as any of the other error types.
Definition: IException.h:126
QString ParamGreaterThan(const int &group, const int &param, const int &great) const
Returns the name of the specified greaterThan parameter.
Definition: IsisAml.cpp:1403
int LineCount(const int &maxLinesToRead=0)
Counts number of lines in file.
Definition: TextFile.cpp:623
bool GetLine(QString &line, const bool skipComments=true)
Gets next line from file.
Definition: TextFile.cpp:427
QString ParamName(const int &group, const int &param) const
Returns the parameter name.
Definition: IsisAml.cpp:1235
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
std::vector< std::vector< QString > > p_batchList
Vector of batchlist data.
QString PixelType(const int &group, const int &param) const
Returns the default pixel type from the XML.
Definition: IsisAml.cpp:1759
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 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
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.
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
Application program XML file parameter manager.
Definition: IsisAml.h:152
QString p_errList
FileName to write batchlist line that caused error on.
Provides access to sequential ASCII stream I/O.
Definition: TextFile.h:54
QString ParamBrief(const int &group, const int &param) const
Returns the brief description of a parameter in a specified group.
Definition: IsisAml.cpp:1248
int groups() const
Returns the number of groups contained.
Definition: PvlObject.h:87
PvlGroup & group(const int index)
Return the group at the specified index.
Definition: PvlObject.cpp:423
QString ProgramName() const
Returns the Program name.
Definition: IsisAml.cpp:1073
int NumGroups() const
Returns the number of groups found in the XML.
Definition: IsisAml.cpp:1103
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:99
Adds specific functionality to C++ strings.
Definition: IString.h:179
QString ParamNotEqual(const int &group, const int &param, const int &notEq) const
Returns the name of the specified notEqual parameter.
Definition: IsisAml.cpp:1463
void VerifyAll()
Verify all parameters.
Definition: IsisAml.cpp:2403
bool p_info
Boolean value representing if it&#39;s in debug mode.
QString ParamGreaterThanOrEqual(const int &group, const int &param, const int &great) const
Returns the name of the specified greaterThanOrEqual parameter.
Definition: IsisAml.cpp:1418
bool isNamed(const QString &match) const
Returns whether the given string is equal to the container name or not.
Definition: PvlContainer.h:87
QString ParamInternalDefault(const int &group, const int &param) const
Returns the internal default for a parameter in a specified group.
Definition: IsisAml.cpp:1540
std::vector< QString > readArray(QString arrayString)
This interprets an array value from the command line.
void SetBatchList(int i)
Clears the gui parameters and sets the batch list information at line i as the new parameters...
void CommandLine(Isis::Pvl &lab) const
Creates a QString which could be used as a command line.
Definition: IsisAml.cpp:2926
void write(const QString &file)
Opens and writes PVL information to a file and handles the end of line sequence.
Definition: Pvl.cpp:116
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
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
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 SetErrorList(int i)
This method adds the line specified in the BatchList that the error occured on.
Contains Pvl Groups and Pvl Objects.
Definition: PvlObject.h:74
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.
int ParamGreaterThanSize(const int &group, const int &param) const
Returns the number of values in the parameters greater than list.
Definition: IsisAml.cpp:1340
QString name() const
Returns the container name.
Definition: PvlContainer.h:78
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.
Reads user preferences from a data file.
Definition: Preference.h:77
QString ParamMaximumInclusive(const int &group, const int &param) const
Returns whether the maximum value is inclusive or not.
Definition: IsisAml.cpp:1313
void addValue(QString value, QString unit="")
Adds a value with units.
Definition: PvlKeyword.cpp:268

U.S. Department of the Interior | U.S. Geological Survey
ISIS | Privacy & Disclaimers | Astrogeology Research Program
To contact us, please post comments and questions on the ISIS Support Center
File Modified: 07/12/2023 23:31:16