14#include <QApplication>
15#include <QCoreApplication>
16#include <QDesktopWidget>
31#include "Application.h"
33#include "IException.h"
35#include "Preference.h"
36#include "ProgramLauncher.h"
40#include "SessionLog.h"
41#include "UserInterface.h"
65 Display *xDisplay = XOpenDisplay(NULL);
67 std::cerr <<
"cannot connect to X server...\n\n"
68 "Do you have an X server running?\n\n"
70 " If you are trying to run this program remotely using ssh, then "
71 "did you enable X11 forwarding?\n\n"
72 "If the possible causes cited above have been ruled out and this "
73 "problem persists, then check your X settings or contact your "
74 "system administrator.\n\n";
79 XCloseDisplay(xDisplay);
89 PvlGroup &uiPref = Preference::Preferences().findGroup(
"UserInterface");
94 setlocale(LC_ALL,
"en_US");
96 QApplication::setQuitOnLastWindowClosed(
true);
97 QApplication::setApplicationName(
FileName(argv[0]).baseName());
103 if(uiPref.hasKeyword(
"GuiStyle")) {
104 QString style = uiPref[
"GuiStyle"];
105 QApplication::setStyle(style);
109 if (uiPref.hasKeyword(
"GuiFontName")) {
110 QString fontString = uiPref[
"GuiFontName"];
111 QFont font = QFont(fontString);
113 if (uiPref.hasKeyword(
"GuiFontSize")) {
114 int pointSize = uiPref[
"GuiFontSize"];
115 font.setPointSize(pointSize);
118 QApplication::setFont(font);
135 QWidget::setWindowTitle(QApplication::applicationName());
138 for(
int group = 0; group < ui.NumGroups(); group++) {
139 for(
int param = 0; param < ui.NumParams(group); param++) {
140 p_parameters.push_back(AddParameter(ui, group, param));
145 for(
int p = 0; p < (int)p_parameters.size(); p++) {
153 p_scrollLayout->addStretch(1);
157 p_progressBar->setMinimum(0);
158 p_progressBar->setMaximum(100);
159 p_progressBar->setValue(0);
160 p_progressBar->setMinimumWidth(200);
162 p_statusText =
new QLabel(
"Ready");
164 statusBar()->setSizeGripEnabled(
true);
165 statusBar()->addWidget(p_progressBar, 0);
166 statusBar()->addWidget(p_statusText, 3);
176 for(
unsigned int i = 0; i < p_parameters.size(); i++) {
177 delete p_parameters[i];
180 p_parameters.clear();
184 void Gui::CreateAreas() {
186 QSplitter *split =
new QSplitter(Qt::Vertical,
this);
189 p_scrollArea =
new QScrollArea();
190 p_scrollWidget =
new QWidget();
191 p_scrollLayout =
new QVBoxLayout;
192 p_scrollWidget->setLayout(p_scrollLayout);
193 p_scrollArea->setWidget(p_scrollWidget);
194 p_scrollArea->setWidgetResizable(
true);
197 int height = QApplication::desktop()->height();
201 p_log->setMinimumHeight(10);
202 p_log->resize(p_log->width(), 250);
204 split->addWidget(p_scrollArea);
205 split->addWidget(p_log);
206 split->setChildrenCollapsible(
false);
207 split->setStretchFactor(0, 3);
208 split->setStretchFactor(1, 0);
209 setCentralWidget(split);
210 resize(720, (
int)(height / 2) + 350);
213 p_processAction = CreateProcessAction();
214 p_stopAction = CreateStopAction();
215 p_exitAction = CreateExitAction();
217 p_previousHistoryAction = CreatePreviousHistoryAction();
218 p_nextHistoryAction = CreateNextHistoryAction();
219 p_resetAction = CreateResetAction();
221 p_saveLogAction = CreateSaveLogAction();
222 p_clearLogAction = CreateClearLogAction();
224 QAction *whatsThisAction = CreateWhatsThisAction();
227 QMenu *fileMenu = menuBar()->addMenu(
"&File");
228 fileMenu->addAction(p_processAction);
229 fileMenu->addAction(p_stopAction);
230 fileMenu->addAction(p_exitAction);
233 QMenu *optionsMenu = menuBar()->addMenu(
"&Options");
234 optionsMenu->addAction(p_resetAction);
235 optionsMenu->addAction(p_previousHistoryAction);
236 optionsMenu->addAction(p_nextHistoryAction);
237 optionsMenu->addAction(p_saveLogAction);
238 optionsMenu->addAction(p_clearLogAction);
241 QToolBar *tb = addToolBar(
"Controls");
242 tb->setIconSize(QSize(22, 22));
243 tb->addAction(p_processAction);
244 tb->addAction(p_stopAction);
245 tb->addAction(p_exitAction);
248 tb->addAction(p_previousHistoryAction);
249 tb->addAction(p_nextHistoryAction);
250 tb->addAction(p_resetAction);
253 tb->addAction(p_saveLogAction);
254 tb->addAction(p_clearLogAction);
257 tb->addAction(whatsThisAction);
260 showControls->setText(
"Controls");
261 showControls->setCheckable(
true);
262 connect(showControls, SIGNAL(toggled(
bool)), tb, SLOT(setVisible(
bool)));
264 tb->installEventFilter(
this);
268 addToolBar(Qt::BottomToolBarArea, tb);
269 tb->setIconSize(QSize(22, 22));
270 tb->setAllowedAreas(Qt::BottomToolBarArea);
271 p_commandLineEdit =
new QLineEdit(tb);
272 p_commandLineEdit->setReadOnly(
true);
273 tb->addWidget(p_commandLineEdit);
275 showCommandLine->setText(
"Command Line");
276 showCommandLine->setCheckable(
true);
277 connect(showCommandLine, SIGNAL(toggled(
bool)), tb, SLOT(setVisible(
bool)));
281 QMenu *viewMenu = menuBar()->addMenu(
"&View");
282 viewMenu->addAction(showControls);
283 viewMenu->addAction(showCommandLine);
284 showControls->setChecked(
true);
285 showCommandLine->setChecked(
true);
288 QMenu *helpMenu = menuBar()->addMenu(
"&Help");
289 helpMenu->addAction(whatsThisAction);
292 aboutProgram->setMenuRole(QAction::AboutRole);
293 aboutProgram->setText(
"About this program");
294 aboutProgram->setShortcut(Qt::CTRL + Qt::Key_H);
295 helpMenu->addAction(aboutProgram);
296 connect(aboutProgram, SIGNAL(triggered(
bool)),
this, SLOT(AboutProgram()));
299 aboutIsis->setMenuRole(QAction::NoRole);
300 aboutIsis->setText(
"About Isis");
301 aboutIsis->setShortcut(Qt::CTRL + Qt::Key_I);
302 helpMenu->addAction(aboutIsis);
303 connect(aboutIsis, SIGNAL(triggered(
bool)),
this, SLOT(AboutIsis()));
308 QAction *Gui::CreateProcessAction() {
310 QString baseDir = FileName(
"$ISISROOT/appdata/images/icons").expanded();
311 processAction->setIcon(QPixmap(baseDir +
"/guiRun.png"));
312 processAction->setText(
"&Run");
313 processAction->setToolTip(
"Run");
314 QString processActionWhatsThisText =
"<p><b>Function: </b> \
315 Runs the application with the current parameters</p> \
316 <p><b>Shortcut: </b> Ctrl+R</p>";
317 processAction->setShortcut(Qt::CTRL + Qt::Key_R);
318 processAction->setWhatsThis(processActionWhatsThisText);
320 connect(processAction, SIGNAL(triggered(
bool)),
this, SLOT(
StartProcess()));
322 return processAction;
336 p_processAction->setEnabled(
false);
344 for(
int p = 0; p < (int)p_parameters.size(); p++) {
346 ui.Clear(param.Name());
347 if(param.IsEnabled() && param.IsModified()) {
348 QString value = param.Value().simplified().trimmed();
349 if(value.length() > 0) {
350 ui.PutAsString(param.Name(), value);
361 Isis::SessionLog::TheLog(
true);
362 QApplication::setOverrideCursor(Qt::WaitCursor);
364 QApplication::restoreOverrideCursor();
368 for(
int p = 0; p < (int)p_parameters.size(); p++) {
377 QApplication::restoreOverrideCursor();
378 if(e.toString() ==
"") {
391 p_processAction->setEnabled(
true);
395 QAction *Gui::CreateExitAction() {
398 exitAction->setIcon(QPixmap(baseDir +
"/guiExit.png"));
399 exitAction->setText(
"&Exit");
400 exitAction->setToolTip(
"Exit");
401 QString exitWhatsThisText =
"<p><b>Function: </b> \
402 Closes the program window </p> <p><b>Shortcut: </b> Ctrl+Q</p>";
403 exitAction->setWhatsThis(exitWhatsThisText);
404 exitAction->setShortcut(Qt::CTRL + Qt::Key_Q);
405 connect(exitAction, SIGNAL(triggered()), qApp, SLOT(quit()));
410 QAction *Gui::CreateResetAction() {
412 QString baseDir = FileName(
"$ISISROOT/appdata/images/icons").expanded();
413 resetAction->setIcon(QPixmap(baseDir +
"/guiReset.png"));
414 resetAction->setText(
"&Reset");
415 resetAction->setToolTip(
"Reset parameters");
416 QString resetWhatsThisText =
"<p><b>Function: </b> \
417 Resets the application parameters to their default values</p> \
418 <p><b>Shortcut: </b> F3</p>";
419 resetAction->setWhatsThis(resetWhatsThisText);
420 resetAction->setShortcut(Qt::Key_F3);
421 connect(resetAction, SIGNAL(triggered()),
this, SLOT(
ResetParameters()));
427 QAction *Gui::CreateStopAction() {
429 QString baseDir = FileName(
"$ISISROOT/appdata/images/icons").expanded();
430 stopAction->setIcon(QPixmap(baseDir +
"/guiStop.png"));
431 stopAction->setText(
"&Stop");
432 stopAction->setToolTip(
"Stop");
433 QString stopWhatsThisText =
"<p><b>Function: </b> \
434 Stops the application from running</p> \
435 <p><b>Shortcut: </b> Ctrl+E</p>";
436 stopAction->setShortcut(Qt::CTRL + Qt::Key_E);
437 stopAction->setWhatsThis(stopWhatsThisText);
438 connect(stopAction, SIGNAL(triggered()),
this, SLOT(
StopProcessing()));
444 QAction *Gui::CreateSaveLogAction() {
446 QString baseDir = FileName(
"$ISISROOT/appdata/images/icons").expanded();
447 saveLogAction->setIcon(QPixmap(baseDir +
"/guiSaveLog.png"));
448 saveLogAction->setText(
"&Save Log...");
449 saveLogAction->setToolTip(
"Save log");
450 QString saveWhatsThisText =
"<p><b>Function: </b> Saves the information \
451 currently in the log area to a file <p><b>Shortcut: </b> Ctrl+S</p>";
452 saveLogAction->setWhatsThis(saveWhatsThisText);
453 saveLogAction->setShortcut(Qt::CTRL + Qt::Key_S);
454 connect(saveLogAction, SIGNAL(triggered(
bool)), p_log, SLOT(Save()));
456 return saveLogAction;
460 QAction *Gui::CreateClearLogAction() {
462 QString baseDir = FileName(
"$ISISROOT/appdata/images/icons").expanded();
463 clearlogAction->setIcon(QPixmap(baseDir +
"/guiClearLog.png"));
464 clearlogAction->setText(
"&Clear Log");
465 clearlogAction->setToolTip(
"Clear log");
466 QString clearWhatsThisText =
"<p><b>Function: </b>Clears all information \
467 from the log area at the bottom of the application screen</p> \
468 <p><b>Shortcut: </b> Ctrl+L</p>";
469 clearlogAction->setWhatsThis(clearWhatsThisText);
470 clearlogAction->setShortcut(Qt::CTRL + Qt::Key_L);
471 connect(clearlogAction, SIGNAL(triggered(
bool)), p_log, SLOT(Clear()));
473 return clearlogAction;
477 QAction *Gui::CreatePreviousHistoryAction() {
479 QString baseDir = FileName(
"$ISISROOT/appdata/images/icons").expanded();
480 previousHistoryAction->setIcon(QPixmap(baseDir +
"/guiPrevHistory.png"));
481 previousHistoryAction->setText(
"&Previous");
482 previousHistoryAction->setToolTip(
"Previous parameters");
483 QString previousWhatsThisText =
"<p><b>Function: </b>Fills in parameter \
484 values using the previous history entry</p> \
485 <p><b>Shortcut: </b> F5</p>";
486 previousHistoryAction->setWhatsThis(previousWhatsThisText);
487 previousHistoryAction->setShortcut(Qt::Key_F5);
488 connect(previousHistoryAction, SIGNAL(triggered()),
this, SLOT(
PreviousHistory()));
490 return previousHistoryAction;
494 QAction *Gui::CreateNextHistoryAction() {
496 QString baseDir = FileName(
"$ISISROOT/appdata/images/icons").expanded();
497 nextHistoryAction->setIcon(QPixmap(baseDir +
"/guiNextHistory.png"));
498 nextHistoryAction->setText(
"&Next");
499 nextHistoryAction->setToolTip(
"Next parameters");
500 QString nextWhatsThisText =
"<p><b>Function: </b>Fills in parameter \
501 values using the next history entry</p> \
502 <p><b>Shortcut: </b>F6</p>";
503 nextHistoryAction->setWhatsThis(nextWhatsThisText);
504 nextHistoryAction->setShortcut(Qt::Key_F6);
505 connect(nextHistoryAction, SIGNAL(triggered()),
this, SLOT(
NextHistory()));
507 return nextHistoryAction;
511 QAction *Gui::CreateWhatsThisAction() {
513 QString baseDir = FileName(
"$ISISROOT/appdata/images/icons").expanded();
514 action->setIcon(QPixmap(baseDir +
"/contexthelp.png"));
515 action->setText(
"&What's This");
516 action->setToolTip(
"What's This");
517 QString whatsThisText =
"<p><b>Function: </b> Use this to get longer \
518 descriptions of button functions and parameter information</p> \
519 <p><b>Shortcut: </b> Shift+F1</p>";
520 action->setWhatsThis(whatsThisText);
521 action->setShortcut(Qt::SHIFT + Qt::Key_F1);
522 connect(action, SIGNAL(triggered(
bool)),
this, SLOT(WhatsThis()));
530 QGridLayout *gridLayout = NULL;
531 if(!p_grids.contains(ui.GroupName(group))) {
533 QGroupBox *groupBox =
new QGroupBox(ui.GroupName(group));
534 p_scrollLayout->addWidget(groupBox);
535 groupBox->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed);
536 groupBox->setAlignment(Qt::AlignHCenter);
539 gridLayout =
new QGridLayout;
540 gridLayout->setColumnStretch(0, 0);
541 gridLayout->setColumnStretch(1, 0);
542 gridLayout->setColumnMinimumWidth(1, 10);
543 gridLayout->setColumnStretch(2, 10);
544 groupBox->setLayout(gridLayout);
545 p_grids[ui.GroupName(group)] = gridLayout;
549 gridLayout = p_grids[ui.GroupName(group)];
552 GuiParameter *p = GuiParameterFactory::Create(gridLayout, ui, group, param);
554 if (p->Type() == GuiParameter::ListWidget || p->Type() == GuiParameter::ComboWidget ||
555 p->Type() == GuiParameter::BooleanWidget) {
559 connect(p, SIGNAL(HelperTrigger(
const QString &)),
566 p_statusText->setText(text);
567 qApp->processEvents();
572 p_progressBar->setValue(percent);
573 qApp->processEvents();
588 QString m = QString(message).replace(
"\n",
"<br>");
591 if(message.contains(
"[") &&
592 message.contains(
"]") &&
593 (message.indexOf(
"[") < message.indexOf(
"]"))) {
596 while(m.indexOf(
"[", indx) != -1) {
597 m.insert(m.indexOf(
"[", indx) + 1,
"<font color=#ff0000>");
598 m.insert(m.indexOf(
"]", indx),
"</font>");
599 indx = m.indexOf(
"]", indx) + 1;
608 int status = QMessageBox::warning(
this,
611 "Ok",
"Abort",
"", 0, 1);
612 p_errorString.clear();
623 if(e->type() == QEvent::Enter) {
624 if(p_processAction->isEnabled()) {
634 if(p_processAction->isEnabled())
return;
637 switch(QMessageBox::information(
this,
639 QString(
"Program suspended, choose to ") +
640 QString(
"continue processing, stop ") +
641 QString(
"processing or exit the program"),
662 qApp->processEvents();
670 for(
int p = 0; p < (int)p_parameters.size(); p++) {
672 ui.Clear(param.Name());
676 for(
int p = 0; p < (int)p_parameters.size(); p++) {
703 if(p_historyEntry < -1) {
705 QApplication::beep();
709 if(p_historyEntry == -1) {
719 Isis::FileName progHist(grp[
"HistoryPath"][0] +
"/" + ui.ProgramName() +
".par");
721 if(!progHist.fileExists()) {
723 QApplication::beep();
730 hist.
read(progHist.expanded());
734 QString msg =
"A corrupt parameter history file [" + progHist.expanded() +
735 "] has been detected. Please fix or remove this file";
745 for(
int i = 0; i < hist.groups(); i++) {
746 if(hist.group(i).isNamed(
"UserParameters")) entries++;
750 if(p_historyEntry == entries) {
751 p_historyEntry = entries - 1;
752 QApplication::beep();
756 int useEntry = entries - p_historyEntry - 1;
763 for (
int k = 0; k < up.keywords(); k++) {
764 QString key = up[k].
name();
768 if (up[k].size() > 1) {
770 for (
int i = 0; i < up[k].size(); i++) {
771 QString newVal = up[k][i];
772 if (newVal.contains(
",")) {
773 newVal =
'"' + newVal +
'"';
775 if (i == up[k].size() - 1) {
779 val += newVal +
", ";
785 QString newVal = up[k];
789 ui.PutAsString(key, val);
792 for(
unsigned int p = 0; p < p_parameters.size(); p++) {
799 p_historyEntry = entries - 1;
800 QApplication::beep();
810 for(
unsigned int p = 0; p < p_parameters.size(); p++) {
816 for(
unsigned int p = 0; p < p_parameters.size(); p++) {
818 std::vector<QString> excludeList = param.
Exclusions();
819 for(
int i = 0; i < (int)excludeList.size(); i++) {
820 for(
unsigned int e = 0; e < p_parameters.size(); e++) {
822 if(exclude.
Name() != excludeList[i])
continue;
823 exclude.
SetEnabled(
false, (param.Type()==GuiParameter::ComboWidget));
832 for(
int p = 0; p < (int)p_parameters.size(); p++) {
834 if(param.IsEnabled() && param.IsModified()) {
836 QString name = param.
Name().toLower();
839 QString value = param.Value();
840 if(param.Type() == GuiParameter::StringWidget) {
841 if(value.contains(
" ")) {
842 cline +=
"\"" + value +
"\"";
848 else if(param.Type() == GuiParameter::FileNameWidget ||
849 param.Type() == GuiParameter::CubeWidget) {
853 value = value.toLower();
858 p_commandLineEdit->setText(cline);
863 for(
unsigned int p = 0; p < p_parameters.size(); p++) {
870 void Gui::WhatsThis() {
871 QWhatsThis::enterWhatsThisMode();
875 void Gui::AboutIsis() {
876 Isis::PvlGroup &uig = Isis::Preference::Preferences().findGroup(
"UserInterface");
877#if defined(__linux__)
878 QString command = (QString) uig[
"GuiHelpBrowser"] +
879 " http://isis.astrogeology.usgs.gov >> /dev/null &";
880#elif defined(__APPLE__)
881 QString command =
"open -a" + (QString) uig[
"GuiHelpBrowser"] +
882 " http://isis.astrogeology.usgs.gov >> /dev/null &";
888 void Gui::AboutProgram() {
889 Isis::PvlGroup &uig = Isis::Preference::Preferences().findGroup(
"UserInterface");
890#if defined(__linux__)
891 QString command = (QString) uig[
"GuiHelpBrowser"] +
892 " http://isis.astrogeology.usgs.gov/Application/presentation/Tabbed/" +
895#elif defined(__APPLE__)
896 QString command =
"open -a" + (QString) uig[
"GuiHelpBrowser"] +
897 " http://isis.astrogeology.usgs.gov/Application/presentation/Tabbed/" +
906 p_processAction->setEnabled(
false);
911 for(
int p = 0; p < (int)p_parameters.size(); p++) {
913 ui.Clear(param.Name());
914 if(param.IsEnabled() && param.IsModified()) {
915 QString value = param.Value().simplified().trimmed();
916 if(value.length() > 0) {
917 ui.PutAsString(param.Name(), value);
925 helper = (void ( *)())ptr;
934 p_processAction->setEnabled(
true);
void FunctionCleanup()
Cleans up after the function by writing the log, saving the history, and either sending the log to th...
void GuiReportError(IException &e)
Loads the error message into the gui, but does not write it to the session log.
void * GetGuiHelper(QString helper)
static UserInterface & GetUserInterface()
Returns the UserInterface object.
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...
File name manipulation and expansion.
QString expanded() const
Returns a QString of the full file name including the file path, excluding the attributes.
Gui for Isis Applications.
void StopProcessing()
The user pressed the stop button ... see what they want to do.
void ResetParameters()
Reset the parameters fields to the defaults.
void InvokeHelper(const QString &funct)
Activate helper buttons.
int Exec(void(*funct)())
Start the Gui and enter the main loop This routine only returns when the program is ready to exit.
void Log(const QString &text)
Write text to the gui log.
void ProgressText(const QString &text)
Change progress text.
int ShowWarning()
Show an error message and return if the user wants to continue/abort.
void UpdateParameters()
Update Parameters.
void NextHistory()
Goto the next history entry.
void UpdateExclusions()
Grey out parameters that should be excluded for radio buttons and checkboxes.
void PreviousHistory()
Goto the previous history entry.
void StartProcess()
The user pressed the go button.
void Progress(int percent)
Update the progress bar.
void LoadMessage(const QString &message)
Add more information to the error message.
bool eventFilter(QObject *o, QEvent *e)
Reset the Progress bar when the user moves the mouse onto the toolbar.
Gui(Isis::UserInterface &ui)
Constructor.
static Gui * p_gui
Singleton.
void UpdateHistory()
Changed the parameters based on the history pointer.
bool ProcessEvents()
Let the event loop have some time to see if we need to cancel.
void UpdateCommandLine()
Update the command line toolbar.
static void checkX11()
check to see if X is available
void Write(const QString &string)
Add more information to the log widget.
void Update()
Update the value on the GUI with the value in the UI.
virtual std::vector< QString > Exclusions()
Return list of current exclusions.
void SetEnabled(bool enabled, bool isParentCombo=false)
Enable or disable the parameter.
QString Name() const
Return the name of the parameter.
Reads user preferences from a data file.
static void RunSystemCommand(QString commandLine)
This runs arbitrary system commands.
QString name() const
Returns the container name.
Contains multiple PvlContainers.
Container for cube-like labels.
void read(const QString &file)
Loads PVL information from a stream.
@ Traverse
Search child objects.
Command Line and Xml loader, validation, and access.
This is free and unencumbered software released into the public domain.