Isis 3.0 Programmer Reference
Back | Home
Gui.cpp
1 #include "Gui.h"
2 
3 #include <clocale>
4 
5 #include <sstream>
6 #include <string>
7 
8 #include <QApplication>
9 #include <QCoreApplication>
10 #include <QDesktopWidget>
11 #include <QFrame>
12 #include <QIcon>
13 #include <QLineEdit>
14 #include <QMenu>
15 #include <QMenuBar>
16 #include <QMessageBox>
17 #include <QSplitter>
18 #include <QScrollArea>
19 #include <QStatusBar>
20 #include <QToolBar>
21 #include <QWhatsThis>
22 #include <QWidget>
23 
24 #include "Application.h"
25 #include "FileName.h"
26 #include "IException.h"
27 #include "IString.h"
28 #include "Preference.h"
29 #include "ProgramLauncher.h"
30 #include "PvlObject.h"
31 #include "PvlGroup.h"
32 #include "Pvl.h"
33 #include "SessionLog.h"
34 #include "UserInterface.h"
35 
36 #ifdef Q_OS_LINUX
37 #include <X11/Xlib.h>
38 #endif
39 
40 namespace Isis {
41 
43  Gui *Gui::p_gui = NULL;
44 
48  void Gui::checkX11() {
49  // Many users who run xorg compatible servers on windows like to forget to
50  // start their Xhack software before launching X clients.
51  // The standard "cannot connect to X server" message that Qt gives is not
52  // enough to explain what the problem is, because we keep getting bug
53  // reports for this. Hopefully detecting this ourselves and printing the
54  // following message will help. If not then yes, this is the message that
55  // needs changing...
56 
57  #ifdef Q_OS_LINUX
58  if (!XOpenDisplay(NULL)) {
59  std::cerr << "cannot connect to X server...\n\n"
60  "Do you have an X server running?\n\n"
61  "If yes then...\n\n"
62  " If you are trying to run this program remotely using ssh, then "
63  "did you enable X11 forwarding?\n\n"
64  "If the possible causes cited above have been ruled out and this "
65  "problem persists, then check your X settings or contact your "
66  "system administrator.\n\n";
67 
68  abort();
69  }
70  #endif
71  }
72 
73 
74  Gui *Gui::Create(Isis::UserInterface &ui, int &argc, char *argv[]) {
75  // Don't recreate
76  if(p_gui != NULL) return p_gui;
77 
78  // Get preferences
79  PvlGroup &uiPref = Preference::Preferences().findGroup("UserInterface");
80 
81  // Create the application
82  new QApplication(argc, argv);
83  // When QApplication is initialized, it will reset the locale to the shells locale. As a result
84  // the locale needs to be reset after QApplications initialization.
85  setlocale(LC_ALL, "en_US");
86  QCoreApplication::setApplicationName(FileName(argv[0]).baseName());
87  QApplication::setQuitOnLastWindowClosed(true);
88 
89 
90  // Qt is smart enough to use the style of the system running the program.
91  // However, Isis supports overriding this with a setting in IsisPreferences.
92  // Here we check to see if this has been done and force the style if needed.
93  if(uiPref.hasKeyword("GuiStyle")) {
94  QString style = uiPref["GuiStyle"];
95  QApplication::setStyle(style);
96  }
97 
98  // Create the main window
99  p_gui = new Gui(ui);
100  p_gui->show();
101 
102  return p_gui;
103  }
104 
106  Gui::Gui(Isis::UserInterface &ui) : QMainWindow(0, Qt::Window) {
107  // Create the toolbar and menu and populate them with actions
108  CreateAreas();
109 
110  // Add parameters to the main area
111  for(int group = 0; group < ui.NumGroups(); group++) {
112  for(int param = 0; param < ui.NumParams(group); param++) {
113  p_parameters.push_back(AddParameter(ui, group, param));
114  }
115  }
116 
117  // Load the values from the UI into the GUI
118  for(int p = 0; p < (int)p_parameters.size(); p++) {
119  GuiParameter *param = p_parameters[p];
120  param->Update();
121  connect(param, SIGNAL(ValueChanged()), this, SLOT(UpdateCommandLine()));
122  }
123 
124 
125  // Make the horizontal direction in the scrolling widget non-stretchable
126  p_scrollLayout->addStretch(1);
127 
128  // Setup status bar
129  p_progressBar = new QProgressBar();
130  p_progressBar->setMinimum(0);
131  p_progressBar->setMaximum(100);
132  p_progressBar->setValue(0);
133  p_progressBar->setMinimumWidth(200);
134 
135  p_statusText = new QLabel("Ready");
136 
137  statusBar()->setSizeGripEnabled(true);
138  statusBar()->addWidget(p_progressBar, 0);
139  statusBar()->addWidget(p_statusText, 3);
140 
141  // Setup the current history pointer
142  p_historyEntry = -1;
143 
144  }
145 
148  for(unsigned int i = 0; i < p_parameters.size(); i++) {
149  delete p_parameters[i];
150  }
151 
152  p_parameters.clear();
153  }
154 
155  // Create the main widget, menus, toolbars, status, actions
156  void Gui::CreateAreas() {
157  // Create the main area
158  QSplitter *split = new QSplitter(Qt::Vertical, this);
159 
160  // Add a scrolled area for the parameters to the splitter
161  p_scrollArea = new QScrollArea();
162  p_scrollWidget = new QWidget();
163  p_scrollLayout = new QVBoxLayout;
164  p_scrollWidget->setLayout(p_scrollLayout);
165  p_scrollArea->setWidget(p_scrollWidget);
166  p_scrollArea->setWidgetResizable(true);
167 
168  // Set the scroll area size
169  int height = QApplication::desktop()->height();
170 
171  // Add the log area to the bottom of the spliter
172  p_log = new GuiLog();
173  p_log->setMinimumHeight(10);
174  p_log->resize(p_log->width(), 250);
175 
176  split->addWidget(p_scrollArea);
177  split->addWidget(p_log);
178  split->setChildrenCollapsible(false);
179  split->setStretchFactor(0, 3);
180  split->setStretchFactor(1, 0);
181  setCentralWidget(split);
182  resize(720, (int)(height / 2) + 350);
183 
184  // Create all the actions for menus, toolbars...
185  p_processAction = CreateProcessAction();
186  p_stopAction = CreateStopAction();
187  p_exitAction = CreateExitAction();
188 
189  p_previousHistoryAction = CreatePreviousHistoryAction();
190  p_nextHistoryAction = CreateNextHistoryAction();
191  p_resetAction = CreateResetAction();
192 
193  p_saveLogAction = CreateSaveLogAction();
194  p_clearLogAction = CreateClearLogAction();
195 
196  QAction *whatsThisAction = CreateWhatsThisAction();
197 
198  // Create the File menu
199  QMenu *fileMenu = menuBar()->addMenu("&File");
200  fileMenu->addAction(p_processAction);
201  fileMenu->addAction(p_stopAction);
202  fileMenu->addAction(p_exitAction);
203 
204  // Create the Options menu
205  QMenu *optionsMenu = menuBar()->addMenu("&Options");
206  optionsMenu->addAction(p_resetAction);
207  optionsMenu->addAction(p_previousHistoryAction);
208  optionsMenu->addAction(p_nextHistoryAction);
209  optionsMenu->addAction(p_saveLogAction);
210  optionsMenu->addAction(p_clearLogAction);
211 
212  // Create the Controls Toolbar
213  QToolBar *tb = addToolBar("Controls");
214  tb->setIconSize(QSize(22, 22));
215  tb->addAction(p_processAction);
216  tb->addAction(p_stopAction);
217  tb->addAction(p_exitAction);
218  tb->addSeparator();
219 
220  tb->addAction(p_previousHistoryAction);
221  tb->addAction(p_nextHistoryAction);
222  tb->addAction(p_resetAction);
223  tb->addSeparator();
224 
225  tb->addAction(p_saveLogAction);
226  tb->addAction(p_clearLogAction);
227  tb->addSeparator();
228 
229  tb->addAction(whatsThisAction);
230 
231  QAction *showControls = new QAction(this);
232  showControls->setText("Controls");
233  showControls->setCheckable(true);
234  connect(showControls, SIGNAL(toggled(bool)), tb, SLOT(setVisible(bool)));
235 
236  tb->installEventFilter(this);
237 
238  // Create the command line toolbar
239  tb = new QToolBar("Command Line");
240  addToolBar(Qt::BottomToolBarArea, tb);
241  tb->setIconSize(QSize(22, 22));
242  tb->setAllowedAreas(Qt::BottomToolBarArea);
243  p_commandLineEdit = new QLineEdit(tb);
244  p_commandLineEdit->setReadOnly(true);
245  tb->addWidget(p_commandLineEdit);
246  QAction *showCommandLine = new QAction(this);
247  showCommandLine->setText("Command Line");
248  showCommandLine->setCheckable(true);
249  connect(showCommandLine, SIGNAL(toggled(bool)), tb, SLOT(setVisible(bool)));
250  //tb->hide();
251 
252  // Create the view menu
253  QMenu *viewMenu = menuBar()->addMenu("&View");
254  viewMenu->addAction(showControls);
255  viewMenu->addAction(showCommandLine);
256  showControls->setChecked(true);
257  showCommandLine->setChecked(true);
258 
259  // Create the Help menu
260  QMenu *helpMenu = menuBar()->addMenu("&Help");
261  helpMenu->addAction(whatsThisAction);
262 
263  QAction *aboutProgram = new QAction(this);
264  aboutProgram->setMenuRole(QAction::AboutRole);
265  aboutProgram->setText("About this program");
266  aboutProgram->setShortcut(Qt::CTRL + Qt::Key_H);
267  helpMenu->addAction(aboutProgram);
268  connect(aboutProgram, SIGNAL(triggered(bool)), this, SLOT(AboutProgram()));
269 
270  QAction *aboutIsis = new QAction(this);
271  aboutIsis->setMenuRole(QAction::NoRole);
272  aboutIsis->setText("About Isis");
273  aboutIsis->setShortcut(Qt::CTRL + Qt::Key_I);
274  helpMenu->addAction(aboutIsis);
275  connect(aboutIsis, SIGNAL(triggered(bool)), this, SLOT(AboutIsis()));
276  }
277 
278 
279  // Create the "Begin/Start Processing" action
280  QAction *Gui::CreateProcessAction() {
281  QAction *processAction = new QAction(this);
282  QString baseDir = FileName("$BASE/icons").expanded();
283  processAction->setIcon(QPixmap(baseDir + "/guiRun.png"));
284  processAction->setText("&Run");
285  processAction->setToolTip("Run");
286  QString processActionWhatsThisText = "<p><b>Function: </b> \
287  Runs the application with the current parameters</p> \
288  <p><b>Shortcut: </b> Ctrl+R</p>";
289  processAction->setShortcut(Qt::CTRL + Qt::Key_R);
290  processAction->setWhatsThis(processActionWhatsThisText);
291 
292  connect(processAction, SIGNAL(triggered(bool)), this, SLOT(StartProcess()));
293 
294  return processAction;
295  }
296 
308  p_processAction->setEnabled(false);
309  ProgressText("Working");
310  Progress(0);
311  p_stop = false;
312 
313  Isis::UserInterface &ui = Isis::iApp->GetUserInterface();
314 
315  // Pull the values from the parameters and put them into the Aml
316  for(int p = 0; p < (int)p_parameters.size(); p++) {
317  GuiParameter &param = *(p_parameters[p]);
318  ui.Clear(param.Name());
319  if(param.IsEnabled() && param.IsModified()) {
320  QString value = param.Value().simplified().trimmed();
321  if(value.length() > 0) {
322  ui.PutAsString(param.Name(), value);
323  }
324  }
325  }
326 
327  // Make sure the parameters were valid
328  // Call the application's main
329  ProcessEvents();
330  try {
331  ui.VerifyAll();
332  ui.SaveHistory();
333  Isis::SessionLog::TheLog(true);
334  QApplication::setOverrideCursor(Qt::WaitCursor);
335  (*p_funct)(); // Call IsisMain
336  QApplication::restoreOverrideCursor();
337  Isis::iApp->FunctionCleanup();
338 
339  // Display the parameters incase the app changed one or more
340  for(int p = 0; p < (int)p_parameters.size(); p++) {
341  GuiParameter &param = *(p_parameters[p]);
342  param.Update();
343  }
344 
345  Progress(100);
346  ProgressText("Done");
347  }
348  catch(IException &e) {
349  QApplication::restoreOverrideCursor();
350  if(e.toString() == "") {
351  ProgressText("Stopped");
352  }
353  else {
354  Isis::iApp->FunctionError(e);
355  ProgressText("Error");
356  // When the warning is rejected (i.e. Abort), clean up from within qApp's exec event loop
357  if(ShowWarning()) {
358  qApp->quit();
359  }
360  }
361  }
362 
363  p_processAction->setEnabled(true);
364  }
365 
366  // Create the "Exit" action
367  QAction *Gui::CreateExitAction() {
368  QAction *exitAction = new QAction(this);
369  QString baseDir = FileName("$BASE/icons").expanded();
370  exitAction->setIcon(QPixmap(baseDir + "/guiExit.png"));
371  exitAction->setText("&Exit");
372  exitAction->setToolTip("Exit");
373  QString exitWhatsThisText = "<p><b>Function: </b> \
374  Closes the program window </p> <p><b>Shortcut: </b> Ctrl+Q</p>";
375  exitAction->setWhatsThis(exitWhatsThisText);
376  exitAction->setShortcut(Qt::CTRL + Qt::Key_Q);
377  connect(exitAction, SIGNAL(triggered()), qApp, SLOT(quit()));
378  return exitAction;
379  }
380 
381  // Create the "Reset" action
382  QAction *Gui::CreateResetAction() {
383  QAction *resetAction = new QAction(this);
384  QString baseDir = FileName("$BASE/icons").expanded();
385  resetAction->setIcon(QPixmap(baseDir + "/guiReset.png"));
386  resetAction->setText("&Reset");
387  resetAction->setToolTip("Reset parameters");
388  QString resetWhatsThisText = "<p><b>Function: </b> \
389  Resets the application parameters to their default values</p> \
390  <p><b>Shortcut: </b> F3</p>";
391  resetAction->setWhatsThis(resetWhatsThisText);
392  resetAction->setShortcut(Qt::Key_F3);
393  connect(resetAction, SIGNAL(triggered()), this, SLOT(ResetParameters()));
394 
395  return resetAction;
396  }
397 
398  // Create the "Stop" action
399  QAction *Gui::CreateStopAction() {
400  QAction *stopAction = new QAction(this);
401  QString baseDir = FileName("$BASE/icons").expanded();
402  stopAction->setIcon(QPixmap(baseDir + "/guiStop.png"));
403  stopAction->setText("&Stop");
404  stopAction->setToolTip("Stop");
405  QString stopWhatsThisText = "<p><b>Function: </b> \
406  Stops the application from running</p> \
407  <p><b>Shortcut: </b> Ctrl+E</p>";
408  stopAction->setShortcut(Qt::CTRL + Qt::Key_E);
409  stopAction->setWhatsThis(stopWhatsThisText);
410  connect(stopAction, SIGNAL(triggered()), this, SLOT(StopProcessing()));
411 
412  return stopAction;
413  }
414 
415  // Create the "SaveLog" action
416  QAction *Gui::CreateSaveLogAction() {
417  QAction *saveLogAction = new QAction(this);
418  QString baseDir = FileName("$BASE/icons").expanded();
419  saveLogAction->setIcon(QPixmap(baseDir + "/guiSaveLog.png"));
420  saveLogAction->setText("&Save Log...");
421  saveLogAction->setToolTip("Save log");
422  QString saveWhatsThisText = "<p><b>Function: </b> Saves the information \
423  currently in the log area to a file <p><b>Shortcut: </b> Ctrl+S</p>";
424  saveLogAction->setWhatsThis(saveWhatsThisText);
425  saveLogAction->setShortcut(Qt::CTRL + Qt::Key_S);
426  connect(saveLogAction, SIGNAL(triggered(bool)), p_log, SLOT(Save()));
427 
428  return saveLogAction;
429  }
430 
431  // Create the "ClearLog" action
432  QAction *Gui::CreateClearLogAction() {
433  QAction *clearlogAction = new QAction(this);
434  QString baseDir = FileName("$BASE/icons").expanded();
435  clearlogAction->setIcon(QPixmap(baseDir + "/guiClearLog.png"));
436  clearlogAction->setText("&Clear Log");
437  clearlogAction->setToolTip("Clear log");
438  QString clearWhatsThisText = "<p><b>Function: </b>Clears all information \
439  from the log area at the bottom of the application screen</p> \
440  <p><b>Shortcut: </b> Ctrl+L</p>";
441  clearlogAction->setWhatsThis(clearWhatsThisText);
442  clearlogAction->setShortcut(Qt::CTRL + Qt::Key_L);
443  connect(clearlogAction, SIGNAL(triggered(bool)), p_log, SLOT(Clear()));
444 
445  return clearlogAction;
446  }
447 
448  // Create the "Previous History" action
449  QAction *Gui::CreatePreviousHistoryAction() {
450  QAction *previousHistoryAction = new QAction(this);
451  QString baseDir = FileName("$BASE/icons").expanded();
452  previousHistoryAction->setIcon(QPixmap(baseDir + "/guiPrevHistory.png"));
453  previousHistoryAction->setText("&Previous");
454  previousHistoryAction->setToolTip("Previous parameters");
455  QString previousWhatsThisText = "<p><b>Function: </b>Fills in parameter \
456  values using the previous history entry</p> \
457  <p><b>Shortcut: </b> F5</p>";
458  previousHistoryAction->setWhatsThis(previousWhatsThisText);
459  previousHistoryAction->setShortcut(Qt::Key_F5);
460  connect(previousHistoryAction, SIGNAL(triggered()), this, SLOT(PreviousHistory()));
461 
462  return previousHistoryAction;
463  }
464 
465  // Create the "Next History" action
466  QAction *Gui::CreateNextHistoryAction() {
467  QAction *nextHistoryAction = new QAction(this);
468  QString baseDir = FileName("$BASE/icons").expanded();
469  nextHistoryAction->setIcon(QPixmap(baseDir + "/guiNextHistory.png"));
470  nextHistoryAction->setText("&Next");
471  nextHistoryAction->setToolTip("Next parameters");
472  QString nextWhatsThisText = "<p><b>Function: </b>Fills in parameter \
473  values using the next history entry</p> \
474  <p><b>Shortcut: </b>F6</p>";
475  nextHistoryAction->setWhatsThis(nextWhatsThisText);
476  nextHistoryAction->setShortcut(Qt::Key_F6);
477  connect(nextHistoryAction, SIGNAL(triggered()), this, SLOT(NextHistory()));
478 
479  return nextHistoryAction;
480  }
481 
482  // Create the Whats Action action
483  QAction *Gui::CreateWhatsThisAction() {
484  QAction *action = new QAction(this);
485  QString baseDir = FileName("$BASE/icons").expanded();
486  action->setIcon(QPixmap(baseDir + "/contexthelp.png"));
487  action->setText("&What's This");
488  action->setToolTip("What's This");
489  QString whatsThisText = "<p><b>Function: </b> Use this to get longer \
490  descriptions of button functions and parameter information</p> \
491  <p><b>Shortcut: </b> Shift+F1</p>";
492  action->setWhatsThis(whatsThisText);
493  action->setShortcut(Qt::SHIFT + Qt::Key_F1);
494  connect(action, SIGNAL(triggered(bool)), this, SLOT(WhatsThis()));
495 
496  return action;
497  }
498 
499  // Add a new parameter to this main window
500  GuiParameter *Gui::AddParameter(Isis::UserInterface &ui, int group, int param) {
501  // Create the group box if this is the first parameter in the group
502  QGridLayout *gridLayout = NULL;
503  if(!p_grids.contains(ui.GroupName(group))) {
504  // Create a new groupbox and add it to the scroll layout
505  QGroupBox *groupBox = new QGroupBox(ui.GroupName(group));
506  p_scrollLayout->addWidget(groupBox);
507  groupBox->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed);
508  groupBox->setAlignment(Qt::AlignHCenter);
509 
510  // Create a gridlayout for the new groupbox and save it
511  gridLayout = new QGridLayout;
512  gridLayout->setColumnStretch(0, 0);
513  gridLayout->setColumnStretch(1, 0);
514  gridLayout->setColumnMinimumWidth(1, 10);
515  gridLayout->setColumnStretch(2, 10);
516  groupBox->setLayout(gridLayout);
517  p_grids[ui.GroupName(group)] = gridLayout;
518  }
519  // Find the group box for this parameter
520  else {
521  gridLayout = p_grids[ui.GroupName(group)];
522  }
523 
524  GuiParameter *p = GuiParameterFactory::Create(gridLayout, ui, group, param);
525 
526  if (p->Type() == GuiParameter::ListWidget || p->Type() == GuiParameter::ComboWidget ||
527  p->Type() == GuiParameter::BooleanWidget) {
528  connect(p, SIGNAL(ValueChanged()), this, SLOT(UpdateExclusions()));
529  }
530 
531  connect(p, SIGNAL(HelperTrigger(const QString &)),
532  this, SLOT(InvokeHelper(const QString &)));
533  return p;
534  }
535 
537  void Gui::ProgressText(const QString &text) {
538  p_statusText->setText(text);
539  qApp->processEvents(); // Needed when programs run programs
540  }
541 
543  void Gui::Progress(int percent) {
544  p_progressBar->setValue(percent);
545  qApp->processEvents(); // Needed when programs run programs
546  }
547 
552  int Gui::Exec(void (*funct)()) {
553  p_funct = funct;
554  return qApp->exec();
555  }
556 
558  void Gui::LoadMessage(const QString &message) {
559  // Convert newlines to breaks
560  QString m = QString(message).replace("\n", "<br>");
561 
562  // If there is a set of "[]" change everything between them to red text
563  if(message.contains("[") &&
564  message.contains("]") &&
565  (message.indexOf("[") < message.indexOf("]"))) {
566 
567  int indx = 0;
568  while(m.indexOf("[", indx) != -1) {
569  m.insert(m.indexOf("[", indx) + 1, "<font color=#ff0000>");
570  m.insert(m.indexOf("]", indx), "</font>");
571  indx = m.indexOf("]", indx) + 1;
572  }
573  }
574  p_errorString += m;
575  }
576 
579  Isis::UserInterface &ui = Isis::iApp->GetUserInterface();
580  int status = QMessageBox::warning(this,
581  ui.ProgramName(),
582  p_errorString,
583  "Ok", "Abort", "", 0, 1);
584  p_errorString.clear();
585  return status;
586  }
587 
589  void Gui::Log(const QString &text) {
590  p_log->Write(text);
591  }
592 
594  bool Gui::eventFilter(QObject *o, QEvent *e) {
595  if(e->type() == QEvent::Enter) {
596  if(p_processAction->isEnabled()) {
597  ProgressText("Ready");
598  Progress(0);
599  }
600  }
601  return false;
602  }
603 
606  if(p_processAction->isEnabled()) return;
607 
609  switch(QMessageBox::information(this,
610  ui.ProgramName(),
611  QString("Program suspended, choose to ") +
612  QString("continue processing, stop ") +
613  QString("processing or exit the program"),
614  "Continue",
615  "Stop",
616  "Exit", 0, 2)) {
617  case 0: // Pressed continue
618  break;
619 
620  case 1: // Pressed stop
621  p_stop = true;
622  break;
623 
624  case 2: // Pressed exit
625  p_stop = true;
626  qApp->quit();
627  }
628  }
629 
634  qApp->processEvents();
635  return p_stop;
636  }
637 
640  // Clear the AML to default values
642  for(int p = 0; p < (int)p_parameters.size(); p++) {
643  GuiParameter &param = *(p_parameters[p]);
644  ui.Clear(param.Name());
645  }
646 
647  // Display the updated parameters
648  for(int p = 0; p < (int)p_parameters.size(); p++) {
649  GuiParameter &param = *(p_parameters[p]);
650  param.Update();
651  }
652  }
653 
656  p_historyEntry--;
657  UpdateHistory();
658  }
659 
662  p_historyEntry++;
663  UpdateHistory();
664  }
665 
666 
675  if(p_historyEntry < -1) {
676  p_historyEntry = -1;
677  QApplication::beep();
678  return;
679  }
680 
681  if(p_historyEntry == -1) {
682  ResetParameters();
683  return;
684  }
685 
686  // Find out if this application has a history file
688  Preference &p = Preference::Preferences();
689 
690  PvlGroup &grp = p.findGroup("UserInterface", Isis::Pvl::Traverse);
691  Isis::FileName progHist(grp["HistoryPath"][0] + "/" + ui.ProgramName() + ".par");
692 
693  if(!progHist.fileExists()) {
694  p_historyEntry = -1;
695  QApplication::beep();
696  return;
697  }
698 
699  Isis::Pvl hist;
700 
701  try {
702  hist.read(progHist.expanded());
703  }
704  catch(...) {
705  p_historyEntry = -1;
706  QString msg = "A corrupt parameter history file [" + progHist.expanded() +
707  "] has been detected. Please fix or remove this file";
708  LoadMessage(msg);
709  // When the warning is rejected (i.e. Abort), clean up from within qApp's exec event loop
710  if (ShowWarning()) {
711  qApp->quit();
712  }
713  return;
714  }
715 
716  int entries = 0;
717  for(int i = 0; i < hist.groups(); i++) {
718  if(hist.group(i).isNamed("UserParameters")) entries++;
719  }
720 
721  // If we are past the last entry ring the bell
722  if(p_historyEntry == entries) {
723  p_historyEntry = entries - 1;
724  QApplication::beep();
725  return;
726  }
727 
728  int useEntry = entries - p_historyEntry - 1;
729 
730  try {
731  //When defaults are used they do not get rewritten because they do not
732  //exist in the history file to be written over. Must reset parameters first.
733  ResetParameters();
734  Isis::PvlGroup &up = hist.group(useEntry);
735  for (int k = 0; k < up.keywords(); k++) {
736  QString key = up[k].name();
737  QString val;
738  // If the value has more than one element,
739  // construct a string array of those elements
740  if (up[k].size() > 1) {
741  val = "(";
742  for (int i = 0; i < up[k].size(); i++) {
743  QString newVal = up[k][i];
744  if (newVal.contains(",")) {
745  newVal = '"' + newVal + '"';
746  }
747  if (i == up[k].size() - 1) {
748  val += newVal + ")";
749  }
750  else {
751  val += newVal + ", ";
752  }
753  }
754  }
755  // Else, return the value on its own
756  else {
757  QString newVal = up[k];
758  val = newVal;
759  }
760  ui.Clear(key);
761  ui.PutAsString(key, val);
762  }
763 
764  for(unsigned int p = 0; p < p_parameters.size(); p++) {
765  GuiParameter &param = *(p_parameters[p]);
766  param.Update();
767  }
768 
769  }
770  catch(IException &e) {
771  p_historyEntry = entries - 1;
772  QApplication::beep();
773  return;
774  }
775  }
776 
781  // First enable everything
782  for(unsigned int p = 0; p < p_parameters.size(); p++) {
783  GuiParameter &param = *(p_parameters[p]);
784  param.SetEnabled(true);
785  }
786 
787  // Now disable things
788  for(unsigned int p = 0; p < p_parameters.size(); p++) {
789  GuiParameter &param = *(p_parameters[p]);
790  std::vector<QString> excludeList = param.Exclusions();
791  for(int i = 0; i < (int)excludeList.size(); i++) {
792  for(unsigned int e = 0; e < p_parameters.size(); e++) {
793  GuiParameter &exclude = *(p_parameters[e]);
794  if(exclude.Name() != excludeList[i]) continue;
795  exclude.SetEnabled(false, (param.Type()==GuiParameter::ComboWidget));
796  }
797  }
798  }
799  }
800 
804  for(int p = 0; p < (int)p_parameters.size(); p++) {
805  GuiParameter &param = *(p_parameters[p]);
806  if(param.IsEnabled() && param.IsModified()) {
807  cline += " ";
808  QString name = param.Name().toLower();
809  cline += name;
810  cline += "=";
811  QString value = param.Value();
812  if(param.Type() == GuiParameter::StringWidget) {
813  if(value.contains(" ")) {
814  cline += "\"" + value + "\"";
815  }
816  else {
817  cline += value;
818  }
819  }
820  else if(param.Type() == GuiParameter::FileNameWidget ||
821  param.Type() == GuiParameter::CubeWidget) {
822  cline += value;
823  }
824  else {
825  value = value.toLower();
826  cline += value;
827  }
828  }
829  }
830  p_commandLineEdit->setText(cline);
831  }
832 
835  for(unsigned int p = 0; p < p_parameters.size(); p++) {
836  GuiParameter &param = *(p_parameters[p]);
837  param.Update();
838  }
839  }
840 
841  // Enter into what's this mode
842  void Gui::WhatsThis() {
843  QWhatsThis::enterWhatsThisMode();
844  }
845 
846  // Show help for Isis
847  void Gui::AboutIsis() {
848  Isis::PvlGroup &uig = Isis::Preference::Preferences().findGroup("UserInterface");
849  QString command = (QString) uig["GuiHelpBrowser"] +
850  " http://isis.astrogeology.usgs.gov >> /dev/null &";
852  }
853 
854  // Show help for the current app
855  void Gui::AboutProgram() {
856  Isis::FileName file((QString)
857  "$ISISROOT/doc/Application/presentation/PrinterFriendly/" +
858  Isis::Application::GetUserInterface().ProgramName() +
859  "/" +
860  Isis::Application::GetUserInterface().ProgramName() +
861  ".html");
862 
863  Isis::PvlGroup &uig = Isis::Preference::Preferences().findGroup("UserInterface");
864  QString command = (QString) uig["GuiHelpBrowser"] +
865  (QString)" file:" + file.expanded() + " &";
867  }
868 
870  void Gui::InvokeHelper(const QString &funct) {
871  p_processAction->setEnabled(false);
872  try {
874 
875  // Pull the values from the parameters and put them into the Aml
876  for(int p = 0; p < (int)p_parameters.size(); p++) {
877  GuiParameter &param = *(p_parameters[p]);
878  ui.Clear(param.Name());
879  if(param.IsEnabled() && param.IsModified()) {
880  QString value = param.Value().simplified().trimmed();
881  if(value.length() > 0) {
882  ui.PutAsString(param.Name(), value);
883  }
884  }
885  }
886 
887  // Get the helper function and run
888  void *ptr = Isis::iApp->GetGuiHelper(funct);
889  void (*helper)();
890  helper = (void ( *)())ptr;
891  helper();
892  }
893  catch(IException &e) {
894  Isis::iApp->GuiReportError(e);
895  }
896 
897  // Update parameters in GUI
899  p_processAction->setEnabled(true);
900  }
901 
902 }
bool eventFilter(QObject *o, QEvent *e)
Reset the Progress bar when the user moves the mouse onto the toolbar.
Definition: Gui.cpp:594
int NumParams(const int &) const
Returns the number of parameters in a group.
Definition: IsisAml.cpp:1223
void NextHistory()
Goto the next history entry.
Definition: Gui.cpp:655
void FunctionCleanup()
Cleans up after the function by writing the log, saving the history, and either sending the log to th...
PvlGroupIterator findGroup(const QString &name, PvlGroupIterator beg, PvlGroupIterator end)
Find a group with the specified name, within these indexes.
Definition: PvlObject.h:141
void SetEnabled(bool enabled, bool isParentCombo=false)
Enable or disable the parameter.
static UserInterface & GetUserInterface()
Returns the UserInterface object.
File name manipulation and expansion.
Definition: FileName.h:111
void ProgressText(const QString &text)
Change progress text.
Definition: Gui.cpp:537
void InvokeHelper(const QString &funct)
Activate helper buttons.
Definition: Gui.cpp:870
void StopProcessing()
The user pressed the stop button ... see what they want to do.
Definition: Gui.cpp:605
static void checkX11()
check to see if X is available
Definition: Gui.cpp:48
bool ProcessEvents()
Let the event loop have some time to see if we need to cancel.
Definition: Gui.cpp:633
int keywords() const
Returns the number of keywords contained in the PvlContainer.
Definition: PvlContainer.h:101
void Write(const QString &string)
Add more information to the log widget.
Definition: GuiLog.cpp:32
Gui(Isis::UserInterface &ui)
Constructor.
Definition: Gui.cpp:106
void UpdateParameters()
Update Parameters.
Definition: Gui.cpp:834
void PutAsString(const QString &paramName, const QString &value)
Allows the insertion of a value for any parameter.
Definition: IsisAml.cpp:81
Search child objects.
Definition: PvlObject.h:170
void GuiReportError(IException &e)
Loads the error message into the gui, but does not write it to the session log.
void Update()
Update the value on the GUI with the value in the UI.
void Progress(int percent)
Update the progress bar.
Definition: Gui.cpp:543
static Gui * p_gui
Singleton.
Definition: Gui.h:114
void UpdateCommandLine()
Update the command line toolbar.
Definition: Gui.cpp:802
void SaveHistory()
Saves the user parameter information in the history of the program for later use. ...
void ResetParameters()
Reset the parameters fields to the defaults.
Definition: Gui.cpp:639
static void RunSystemCommand(QString commandLine)
This runs arbitrary system commands.
void PreviousHistory()
Goto the previous history entry.
Definition: Gui.cpp:661
void Log(const QString &text)
Write text to the gui log.
Definition: Gui.cpp:589
Contains multiple PvlContainers.
Definition: PvlGroup.h:57
void UpdateHistory()
Changed the parameters based on the history pointer.
Definition: Gui.cpp:674
QString Name() const
Return the name of the parameter.
Definition: GuiParameter.h:60
virtual bool IsModified()
Return if the parameter value is different from the default value.
void Clear(const QString &paramName)
Clears the value(s) in the named parameter.
Definition: IsisAml.cpp:1868
Container for cube-like labels.
Definition: Pvl.h:135
int FunctionError(IException &e)
Adds the error to the session log, sends the error to the parent if it has one, loads the error messa...
int Exec(void(*funct)())
Start the Gui and enter the main loop This routine only returns when the program is ready to exit...
Definition: Gui.cpp:552
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
void StartProcess()
The user pressed the go button.
Definition: Gui.cpp:307
int NumGroups() const
Returns the number of groups found in the XML.
Definition: IsisAml.cpp:1103
QString toString() const
Returns a string representation of this exception.
Definition: IException.cpp:553
void LoadMessage(const QString &message)
Add more information to the error message.
Definition: Gui.cpp:558
Isis exception class.
Definition: IException.h:99
virtual std::vector< QString > Exclusions()
Return list of current exclusions.
void VerifyAll()
Verify all parameters.
Definition: IsisAml.cpp:2403
Command Line and Xml loader, validation, and access.
~Gui()
Destructor.
Definition: Gui.cpp:147
int ShowWarning()
Show an error message and return if the user wants to continue/abort.
Definition: Gui.cpp:578
bool isNamed(const QString &match) const
Returns whether the given string is equal to the container name or not.
Definition: PvlContainer.h:87
void read(const QString &file)
Loads PVL information from a stream.
Definition: Pvl.cpp:76
void UpdateExclusions()
Grey out parameters that should be excluded for radio buttons and checkboxes.
Definition: Gui.cpp:780
bool hasKeyword(const QString &name) const
Check to see if a keyword exists.
QString name() const
Returns the container name.
Definition: PvlContainer.h:78
QString GroupName(const int &group) const
Returns the group name of group[index].
Definition: IsisAml.cpp:1114
void * GetGuiHelper(QString helper)
Definition: Application.h:142
Reads user preferences from a data file.
Definition: Preference.h:77
bool IsEnabled() const
Is the parameter enabled.
Definition: GuiParameter.h:75
Gui for Isis Applications.
Definition: Gui.h:86

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:18:56