00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "omgabout.h"
00021 #include "omgalgorithm.h"
00022 #include "omgalgorithmmanager.h"
00023 #include "omgclimateconverter.h"
00024 #include "omgexperimentdesigner.h"
00025 #include "omgexperimentselector.h"
00026 #include "omggdalconverter.h"
00027 #include "omggdalrastercontour.h"
00028 #include "omggdalwarp.h"
00029 #include "omglayersetmanager.h"
00030 #include "omgmainwindow.h"
00031 #include "omgoptions.h"
00032 #include "omgrasterthreshold.h"
00033 #include "omgdatafetcherwizard.h"
00034 #include "omgtermsandconditions.h"
00035 #include "omgtextfilesplitter.h"
00036 #include "omgtipfactory.h"
00037 #include "omgsurveywizard.h"
00038 #include "omgpublishtocatalogue.h"
00039 #include "omgmodellerplugininterface.h"
00040 #include "omgmodellerpluginregistry.h"
00041 #include <omgui.h>
00042
00043 #ifdef WITH_QGIS
00044
00045
00046
00047
00048 #include "qgisappinterface.h"
00049
00050
00051
00052 #include <qgsproject.h>
00053 #include <qgisplugin.h>
00054 #include <qgsapplication.h>
00055 #include <qgsmapcanvas.h>
00056 #include <qgsmaplayerregistry.h>
00057 #include <qgspluginregistry.h>
00058 #include <qgsproviderregistry.h>
00059 #include <qgsrasterlayer.h>
00060 #include <qgsuniquevaluerenderer.h>
00061 #include <qgssinglesymbolrenderer.h>
00062 #include <qgssymbol.h>
00063 #include <qgsvectorlayer.h>
00064 #include <qgsvectordataprovider.h>
00065 #include <qgsfield.h>
00066
00067
00068
00069
00070 #include "qgsmaptoolpan.h"
00071 #include "qgsmaptoolzoom.h"
00072
00073
00074
00075
00076
00077
00078
00079
00080 #endif
00081
00082 #include <QAction>
00083 #include <QCloseEvent>
00084 #include <QDebug>
00085 #include <QDesktopWidget>
00086 #include <QFileDialog>
00087 #include <QFrame>
00088 #include <QHeaderView>
00089 #include <QImage>
00090 #include <QLayout>
00091 #include <QLibrary>
00092 #include <QListWidget>
00093 #include <QMap>
00094 #include <QMenuBar>
00095 #include <QMessageBox>
00096 #include <QPair>
00097 #include <QPixmap>
00098 #include <QPrinter>
00099 #include <QScrollArea>
00100 #include <QSettings>
00101 #include <QStatusBar>
00102 #include <QString>
00103 #include <QTextDocument>
00104 #include <QTextEdit>
00105 #include <QToolBar>
00106 #include <QTreeWidget>
00107 #include <QWhatsThis>
00108 #include <QWidget>
00109
00110
00111
00112 typedef QgisPlugin *create_ui(QgisInterface * qI);
00113
00114 OmgMainWindow::OmgMainWindow(QWidget* parent, Qt::WFlags fl)
00115 : QMainWindow(parent,fl),
00116
00117 mpQgisInterface(new QgisAppInterface(this)),
00118 mpCurrentModel(new OmgModel()),
00119 mpLocalitiesModel(new OmgLocalitiesModel())
00120
00121 {
00122
00123 setupUi(this);
00124
00125
00126 connect(splitter, SIGNAL(splitterMoved(int, int)), this, SLOT(setTreeColumnSizes(int, int)));
00127 connect(cboReportMode, SIGNAL(currentIndexChanged(QString)), this, SLOT(reportModeChanged(QString)));
00128
00129
00130 setViewMode("Browse");
00131
00132
00133
00134 treeExperiment->clear();
00135 tableView->setModel(mpLocalitiesModel);
00136 setEnableModelDetailWidgets(false);
00137
00138
00139
00140
00141
00142 createActions();
00143 createTrayIcon();
00144 createMenus();
00145 createToolBars();
00146 createStatusBar();
00147
00148 #ifdef WITH_QGIS
00149
00150
00151
00152
00153 QString myPluginDirName = QgsApplication::pluginPath();
00154 QgsProviderRegistry::instance(myPluginDirName);
00155
00156
00157 mpMapCanvas= new QgsMapCanvas(0, 0);
00158
00159 mpMapCanvas->enableAntiAliasing(true);
00160 mpMapCanvas->useQImageToRender(false);
00161 mpMapCanvas->setCanvasColor(QColor(255, 255, 255));
00162 mpMapCanvas->freeze(false);
00163 mpMapCanvas->setVisible(true);
00164 mpMapCanvas->refresh();
00165 mpMapCanvas->show();
00166
00167
00168
00169 #ifdef WIN32
00170 QString pluginExt = "*.dll";
00171 #else
00172 QString pluginExt = "*.so*";
00173 #endif
00174
00175
00176 QDir myPluginDir(myPluginDirName, pluginExt, QDir::Name | QDir::IgnoreCase, QDir::Files | QDir::NoSymLinks);
00177
00178 for (uint i = 0; i < myPluginDir.count(); i++)
00179 {
00180 QString myFullPath = myPluginDirName + QDir::separator() + myPluginDir[i];
00181 qDebug("Examining " + myFullPath.toLocal8Bit());
00182
00183
00184
00185
00186
00187 bool myPluginWantedFlag=false;
00188 QStringList myPluginList;
00189 myPluginList << "north" << "copyright" << "scalebar";
00190 QStringListIterator myIterator(myPluginList);
00191 while (myIterator.hasNext())
00192 {
00193 if (myFullPath.contains(myIterator.next()))
00194 {
00195 myPluginWantedFlag=true;
00196 break;
00197 }
00198 }
00199 if (!myPluginWantedFlag)
00200 {
00201 continue;
00202 }
00203
00204
00205 QLibrary *myLib = new QLibrary(myFullPath);
00206 bool myLoadedFlag = myLib->load();
00207 if (myLoadedFlag)
00208 {
00209
00210 std::cout << "Loaded " << myLib->library().toLocal8Bit().data() << std::endl;
00211
00212 name_t * myName = (name_t *) myLib->resolve("name");
00213 description_t * myDescription = (description_t *) myLib->resolve("description");
00214 version_t * myVersion = (version_t *) myLib->resolve("version");
00215 if (myName && myDescription && myVersion )
00216 {
00217
00218 QString myEntryName = myName();
00219
00220
00221
00222 qDebug("Loading plugin: " + myEntryName.toLocal8Bit());
00223
00224 loadQGisPlugin(myName(), myDescription(), myFullPath);
00225 }
00226 else
00227 {
00228 qDebug("Failed to get name, description, or type for " +
00229 myLib->library().toLocal8Bit());
00230 }
00231 }
00232 else
00233 {
00234 qDebug("Failed to load " + myLib->library().toLocal8Bit());
00235 qDebug("Reason: " + myLib->errorString().toLocal8Bit());
00236 }
00237 delete myLib;
00238 }
00239
00240
00241
00242 delete lblOutputMap;
00243 tabMap->layout()->addWidget(mpMapCanvas);
00244
00245 mpPanTool = new QgsMapToolPan(mpMapCanvas);
00246 mpPanTool->setAction(mpPanAct);
00247 mpZoomInTool = new QgsMapToolZoom(mpMapCanvas, FALSE);
00248 mpZoomInTool->setAction(mpZoomInAct);
00249 mpZoomOutTool = new QgsMapToolZoom(mpMapCanvas, TRUE );
00250 mpZoomOutTool->setAction(mpZoomOutAct);
00251
00252
00253
00254
00255
00256
00257
00258
00259 #endif //with qgis
00260
00261 #ifdef OMG_NO_EXPERIMENTAL
00262
00263 mpToolsContourAct->setVisible(false);
00264 mpToolsWarpAct->setVisible(false);
00265 mpCloseAct->setVisible(false);
00266 mpToolsClimateConvertAct->setVisible(false);
00267
00268
00269 mpDataPrepToolBar->removeAction(mpToolsWarpAct);
00270 mpDataPrepToolBar->removeAction(mpToolsClimateConvertAct);
00271 mpPostProcessingToolBar->removeAction(mpToolsContourAct);
00272
00273
00274 mpSaveAct->setVisible(false);
00275 mpFileToolBar->removeAction(mpSaveAct);
00276 #endif
00277
00278
00279 readSettings();
00280 setTreeColumnSizes(0,0);
00281 disableMapControls();
00282
00283 showHelp();
00284
00285
00286
00287
00288
00289 cboReportMode->hide();
00290 lblReportMode->hide();
00291
00292
00293
00294 mSortMode = BY_ALGORITHM;
00295
00296 #ifdef WITH_OSSIMPLANET_QT
00297 initialiseOssimPlanet();
00298 #else
00299 tabModelViewDetails->removeTab(3);
00300 #endif
00301 listThumbnails->hide();
00302
00303
00304
00305 mRunningIcon = QIcon(":/status_running.png");
00306
00307 if (!QFile::exists(":/status_running.gif"))
00308 {
00309
00310 }
00311 else
00312 {
00313 mpRunningMovie = new QMovie(":/status_running.gif");
00314 if (mpRunningMovie->isValid())
00315 {
00316
00317 connect(mpRunningMovie, SIGNAL(updated(const QRect)), this, SLOT(updateRunningIcon(const QRect)));
00318 }
00319 else
00320 {
00321
00322 }
00323 }
00324
00325 QString myPath = Omgui::userAlgorithmProfilesDirPath();
00326 QStringList myList;
00327 myList << "algorithm-EnvironmentalDistance-Chebyshev.xml";
00328 myList << "algorithm-EnvironmentalDistance-Mahalanobis.xml";
00329 myList << "algorithm-EnvironmentalDistance-Manhattan.xml";
00330 myList << "algorithm-SVM-C-SVC.xml";
00331 myList << "algorithm-SVM-Nu-SVC.xml";
00332 myList << "algorithm-SVM-One-Class.xml";
00333 QStringListIterator myIterator(myList);
00334 while (myIterator.hasNext())
00335 {
00336 QString myProfile = myIterator.next();
00337 if (!QFile::exists(myPath+myProfile))
00338 {
00339
00340 if (!QFile::exists(":/" + myProfile))
00341 {
00342 qDebug("Resouce file :/" + myProfile.toLocal8Bit()
00343 + " does not exist...skipping");
00344 continue;
00345 }
00346
00347 bool myResult = QFile::copy(":/" + myProfile,
00348 myPath+myProfile);
00349 QString myMessage = "Copying :/" + myProfile +
00350 " to " + myPath + myProfile;
00351 if (myResult)
00352 {
00353 myMessage += " succeeded";
00354 }
00355 else
00356 {
00357 myMessage += " failed";
00358 }
00359 qDebug(myMessage.toLocal8Bit());
00360 }
00361 }
00362 }
00363
00364
00365 OmgMainWindow::~OmgMainWindow()
00366 {
00367 }
00368
00369 void OmgMainWindow::loadQGisPlugin(QString theName,
00370 QString theDescription, QString theFullPathName)
00371 {
00372 QSettings mySettings;
00373
00374 QgsPluginRegistry *mypRegistry = QgsPluginRegistry::instance();
00375 QString myLibName = mypRegistry->library(theName);
00376 if (myLibName.length() > 0)
00377 {
00378
00379
00380 }
00381 else
00382 {
00383 QLibrary *mypLib = new QLibrary(theFullPathName);
00384 qDebug("Library name is " + mypLib->library().toLocal8Bit());
00385
00386 bool myLoadedFlag = mypLib->load();
00387 if (myLoadedFlag)
00388 {
00389 std::cerr << "Loaded test plugin library" << std::endl;
00390 std::cerr << "Attempting to resolve the classFactory function" << std::endl;
00391
00392 type_t *mypType = (type_t *) mypLib->resolve("type");
00393
00394
00395 switch (mypType())
00396 {
00397 case QgisPlugin::UI:
00398 {
00399 create_ui *cf = (create_ui *) mypLib->resolve("classFactory");
00400 if (cf)
00401 {
00402 QgisPlugin *mypPlugin = cf(mpQgisInterface);
00403 if (mypPlugin)
00404 {
00405 mypPlugin->initGui();
00406
00407 mypRegistry->addPlugin(mypLib->library(), theName, mypPlugin);
00408
00409 mySettings.setValue("/QGisPlugins/" + theName, true);
00410 }
00411 else
00412 {
00413
00414 QMessageBox::warning(this, tr("Error Loading Plugin"), tr("There was an error loading %1."));
00415
00416 mySettings.setValue("/QGisPlugins/" + theName, false);
00417 }
00418 }
00419 else
00420 {
00421
00422 std::cerr << "Unable to find the class factory for "
00423 << theFullPathName.toLocal8Bit().data() << std::endl;
00424
00425 }
00426
00427 }
00428 break;
00429 case QgisPlugin::MAPLAYER:
00430 default:
00431
00432
00433 std::cerr << "Plugin " << theFullPathName.toLocal8Bit().data() << " did not return a valid type and cannot be loaded" << std::endl;
00434
00435 break;
00436 }
00437 }
00438 else
00439 {
00440
00441 std::cerr << "Failed to load " << theFullPathName.toLocal8Bit().data() << "\n";
00442
00443 }
00444 delete mypLib;
00445 }
00446 }
00447
00448 void OmgMainWindow::fileExit()
00449 {
00450 #ifdef WITH_QGIS
00451 mpMapCanvas->freeze(true);
00452 delete mpMapCanvas;
00453 #endif
00454 writeSettings();
00455 if (QSystemTrayIcon::isSystemTrayAvailable ())
00456 {
00457 mTrayIcon->hide();
00458 if (mTrayIcon)
00459 {
00460 delete mTrayIcon;
00461 }
00462 }
00463 qApp->quit();
00464 }
00465
00466 void OmgMainWindow::closeEvent(QCloseEvent *thepEvent)
00467 {
00468 QSettings mySettings;
00469 bool myUseSytemTrayFlag = mySettings.value("openModeller/useSystemTray", false).toBool();
00470 bool myMinimiseToSystemTrayFlag = mySettings.value("openModeller/closeToSystemTray", false).toBool();
00471 if (QSystemTrayIcon::isSystemTrayAvailable() &&
00472 myUseSytemTrayFlag &&
00473 myMinimiseToSystemTrayFlag)
00474 {
00475 QSettings mySettings;
00476 if (mySettings.value("openModeller/closeToSystemTray", true).toBool())
00477 {
00478 QMessageBox::information(this, tr("Systray"),
00479 tr("The program will keep running in the "
00480 "system tray. To terminate the program, "
00481 "choose <b>Quit</b> in the context menu "
00482 "of the system tray entry, or choose exit "
00483 "from the file menu. You can disable this "
00484 "behaviour in the options dialog."));
00485 hide();
00486 thepEvent->ignore();
00487 return;
00488 }
00489 }
00490
00491 fileExit();
00492 }
00493
00494 void OmgMainWindow::fileNew()
00495 {
00496
00497
00498 if ( Omgui::getAvailableLayerSets().count() < 1)
00499 {
00500 QMessageBox myMessage;
00501 myMessage.setText(tr("You have not created any LayerSets yet. Before attempting to create an") +
00502 tr(" experiment you need to have at least one LayerSet defined. Would") +
00503 tr(" you like to open the LayerSet Manager now?"));
00504 myMessage.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
00505 switch (myMessage.exec()) {
00506 case QMessageBox::Yes:
00507
00508 showLayerSetManager();
00509 return;
00510 break;
00511 case QMessageBox::No:
00512
00513 return;
00514 break;
00515 default:
00516
00517 break;
00518 }
00519 }
00520
00521
00522 OmgExperimentDesigner myOmgExperimentDesigner(this) ;
00523 connect(&myOmgExperimentDesigner, SIGNAL(experimentCreated(OmgExperiment *)),
00524 this, SLOT(setCurrentExperiment(OmgExperiment *)));
00525 myOmgExperimentDesigner.exec();
00526 }
00527 void OmgMainWindow::resetExperiment()
00528 {
00529 if (!mpCurrentExperiment)
00530 {
00531 return;
00532 }
00533 QMessageBox myMessage;
00534 myMessage.setText(tr("Resetting an experiment will mark"
00535 " all models as 'not run'. You will need to rerun the "
00536 " experiment to have the models considered complete."
00537 " No existing model outputs will be deleted, but when you "
00538 " rerun the experiment they will be overwritten."
00539 " Are you sure you want to reset the experiment now?"));
00540 myMessage.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
00541 switch (myMessage.exec())
00542 {
00543 case QMessageBox::Yes:
00544
00545 mpCurrentExperiment->reset();
00546 populateTree();
00547 return;
00548 break;
00549 case QMessageBox::No:
00550
00551
00552 break;
00553 default:
00554
00555 break;
00556 }
00557 }
00558 void OmgMainWindow::runExperiment()
00559 {
00560 if (!mpCurrentExperiment)
00561 {
00562 return;
00563 }
00564 mpRunningMovie->start();
00565
00566
00567 OmgModellerPluginInterface * mypModellerPlugin =
00568 OmgModellerPluginRegistry::instance()->getPlugin();
00569 mpCurrentExperiment->setModellerPlugin(mypModellerPlugin);
00570
00571
00572
00573
00574
00575
00576 const OmgPluginMessenger * mypMessenger =
00577 mpCurrentExperiment->modellerPlugin()->getMessenger();
00578
00579
00580
00581
00582
00583 disconnect(mpCurrentExperiment, SIGNAL(experimentProgress(int )),
00584 this, SLOT(setExperimentProgress(int)));
00585 disconnect(mpCurrentExperiment, SIGNAL(experimentMaximum(int )),
00586 this, SLOT(setExperimentMaximum(int)));
00587 disconnect(mpCurrentExperiment, SIGNAL(logMessage(QString )),
00588 this, SLOT(logMessage(QString)));
00589 disconnect(mpCurrentExperiment, SIGNAL(experimentStopped()),
00590 this, SLOT(experimentStopped()));
00591 disconnect(mpCurrentExperiment, SIGNAL(modelCompleted(QString)),
00592 this, SLOT(modelCompleted(QString)));
00593
00594
00595 disconnect(mypMessenger, SIGNAL(modelCreationProgress(QString,int )),
00596 this, SLOT(setModelCreationProgress(QString,int)));
00597 disconnect(mypMessenger, SIGNAL(modelProjectionProgress(QString,int )),
00598 this, SLOT(setModelProjectionProgress(QString,int)));
00599 disconnect(mypMessenger, SIGNAL(modelMessage(QString,QString )),
00600 this, SLOT(logMessage(QString,QString)));
00601 disconnect(mypMessenger, SIGNAL(modelError(QString,QString )),
00602 this, SLOT(logError(QString,QString)));
00603
00604
00605
00606
00607
00608 connect(mpCurrentExperiment, SIGNAL(experimentProgress(int )),
00609 this, SLOT(setExperimentProgress(int)));
00610 connect(mpCurrentExperiment, SIGNAL(experimentMaximum(int )),
00611 this, SLOT(setExperimentMaximum(int)));
00612 connect(mpCurrentExperiment, SIGNAL(logMessage(QString )),
00613 this, SLOT(logMessage(QString)));
00614 connect(mpCurrentExperiment, SIGNAL(experimentStopped()),
00615 this, SLOT(experimentStopped()));
00616
00617
00618 connect(mypMessenger, SIGNAL(modelCreationProgress(QString,int )),
00619 this, SLOT(setModelCreationProgress(QString,int)));
00620 connect(mypMessenger, SIGNAL(modelProjectionProgress(QString,int )),
00621 this, SLOT(setModelProjectionProgress(QString,int)));
00622 connect(mypMessenger, SIGNAL(modelMessage(QString,QString )),
00623 this, SLOT(logMessage(QString,QString)));
00624 connect(mypMessenger, SIGNAL(modelError(QString,QString )),
00625 this, SLOT(logError(QString,QString)));
00626 connect(mpCurrentExperiment, SIGNAL(modelCompleted(QString)),
00627 this, SLOT(modelCompleted(QString)));
00628
00629 mpModelProgress->show();
00630 mpExperimentProgress->show();
00631
00632
00633 mpRunAct->setIcon(QIcon(":/status_aborted.png"));
00634 mpRunAct->setText(tr("Cancel cu&rrent experiment"));
00635 mpRunAct->setShortcut(tr("Ctrl+R"));
00636 mpRunAct->setStatusTip(tr("Cancel current experiment"));
00637 disconnect(mpRunAct);
00638 connect(mpRunAct, SIGNAL(triggered()), this, SLOT(stopExperiment()));
00639 disableControlsWhileRunning();
00640
00641 QSettings mySettings;
00642
00643 bool myLogToFileFlag = mySettings.value("openModeller/logToFile", false).toBool();
00644 if (myLogToFileFlag)
00645 {
00646 QString myFileName = mySettings.value("openModeller/logFile","/tmp/omglog.txt").toString();
00647 QFile myFile( myFileName );
00648 if ( myFile.exists() )
00649 {
00650 myFile.remove(myFileName);
00651 }
00652 }
00653
00654
00655
00656
00657
00658
00659 QString myString;
00660 myString = "<h1>" + tr("Experiment in progress") + "</h1>\n";
00661 myString += "<table>";
00662 myString += experimentHelpText();
00663
00664
00665 myString += "</table>";
00666 tabModelViewDetails->setEnabled(true);
00667 setReportStyleSheet();
00668 tbReport->setHtml(myString);
00669
00670
00671
00672
00673
00674 bool myThreadingFlag = mySettings.value("openModeller/runExperimentInThread", true).toBool();
00675 if (myThreadingFlag)
00676 {
00677
00678
00679
00680 logMessage ("Running experiment in its own thread is enabled");
00681 mpCurrentExperiment->start();
00682 }
00683 else
00684 {
00685 logMessage ("Running experiment in its own thread is disabled");
00686 mpCurrentExperiment->run();
00687 }
00688 }
00689
00690 void OmgMainWindow::closeExperiment()
00691 {
00692
00693 clearCurrentExperiment();
00694
00695 }
00696
00697 void OmgMainWindow::fileFetch()
00698 {
00699 OmgDataFetcherWizard myWizard;
00700 myWizard.exec();
00701 }
00702
00703 bool OmgMainWindow::toolsConvert()
00704 {
00705 OmgGdalConverter myConverter;
00706 if (myConverter.exec()==QDialog::Accepted)
00707 {
00708 return true;
00709 }
00710 else
00711 {
00712 return false;
00713 }
00714 }
00715
00716 bool OmgMainWindow::toolsContour()
00717 {
00718 OmgGdalRasterContour myContour;
00719 if (myContour.exec()==QDialog::Accepted)
00720 {
00721 return true;
00722 }
00723 else
00724 {
00725 return false;
00726 }
00727 }
00728
00729 bool OmgMainWindow::toolsRasterThreshold()
00730 {
00731 OmgRasterThreshold myRasterThreshold;
00732 myRasterThreshold.setExperiment(mpCurrentExperiment);
00733 if (myRasterThreshold.exec()==QDialog::Accepted)
00734 {
00735 return true;
00736 }
00737 else
00738 {
00739 return false;
00740 }
00741 }
00742
00743 bool OmgMainWindow::toolsClimateConvert()
00744 {
00745 OmgClimateConverter myConverter;
00746 if (myConverter.exec()==QDialog::Accepted)
00747 {
00748 return true;
00749 }
00750 else
00751 {
00752 return false;
00753 }
00754 }
00755
00756 bool OmgMainWindow::toolsWarp()
00757 {
00758 OmgGdalWarp myWarp;
00759 if (myWarp.exec()==QDialog::Accepted)
00760 {
00761 return true;
00762 }
00763 else
00764 {
00765 return false;
00766 }
00767 }
00768
00769 bool OmgMainWindow::toolsFileSplitter()
00770 {
00771 OmgTextFileSplitter mySplitter;
00772 if (mySplitter.exec()==QDialog::Accepted)
00773 {
00774 return true;
00775 }
00776 else
00777 {
00778 return false;
00779 }
00780 }
00781
00782 bool OmgMainWindow::checkLicenseIsAgreed()
00783 {
00784 QSettings mySettings;
00785 if (mySettings.value("licensing/termsAgreedFlag",0).toInt()==1)
00786 {
00787 return true;
00788 }
00789 else
00790 {
00791 OmgTermsAndConditions myTerms;
00792 if (myTerms.exec()==QDialog::Accepted)
00793 {
00794 return true;
00795 }
00796 else
00797 {
00798 return false;
00799 }
00800 }
00801 }
00802
00803 void OmgMainWindow::showLicense()
00804 {
00805 OmgTermsAndConditions myTerms;
00806 myTerms.show();
00807 myTerms.exec();
00808
00809 }
00810
00811
00812 void OmgMainWindow::about()
00813 {
00814 OmgAbout myAbout;
00815 myAbout.show();
00816 myAbout.exec();
00817 }
00818
00819 void OmgMainWindow::settingsOptions()
00820 {
00821 OmgOptions myOptions(this);
00822 myOptions.exec();
00823
00824
00825 QSettings mySettings;
00826 bool myUseSytemTrayFlag = mySettings.value("openModeller/useSystemTray", false).toBool();
00827 if (myUseSytemTrayFlag)
00828 {
00829 mTrayIcon->show();
00830 }
00831 else
00832 {
00833 mTrayIcon->hide();
00834 }
00835 }
00836
00837 void OmgMainWindow::createActions()
00838 {
00839 mpNewAct = new QAction(QIcon(":/filenewExperiment.png"), tr("&New Experiment"), this);
00840 mpNewAct->setShortcut(tr("Ctrl+N"));
00841 mpNewAct->setStatusTip(tr("Create a new experiment"));
00842 connect(mpNewAct, SIGNAL(triggered()), this, SLOT(fileNew()));
00843
00844 mpPrintPdfAct = new QAction(QIcon(":/pdf.png"), tr("&Save as pdf"), this);
00845 mpPrintPdfAct->setShortcut(tr("Ctrl+P"));
00846 mpPrintPdfAct->setStatusTip(tr("Save the experiment report as a pdf"));
00847 connect(mpPrintPdfAct, SIGNAL(triggered()), this, SLOT(printPdf()));
00848
00849 mpRefreshReportsAct = new QAction(QIcon(":/refresh.png"), tr("Refresh all reports"), this);
00850 mpRefreshReportsAct->setStatusTip(tr("Refresh all reports"));
00851 connect(mpRefreshReportsAct, SIGNAL(triggered()), this, SLOT(refreshReports()));
00852
00853 mpRunAct = new QAction(QIcon(":/status_restart.png"), tr("&Run / Resume current experiment"), this);
00854 mpRunAct->setShortcut(tr("Ctrl+R"));
00855 mpRunAct->setStatusTip(tr("Run / Resume current experiment"));
00856 connect(mpRunAct, SIGNAL(triggered()), this, SLOT(runExperiment()));
00857
00858 mpResetAct = new QAction(QIcon(":/status_reset.png"), tr("&Reset the current experiment"), this);
00859 mpResetAct->setStatusTip(tr("Reset the current experiment"));
00860 connect(mpResetAct, SIGNAL(triggered()), this, SLOT(resetExperiment()));
00861
00862 mpOpenAct = new QAction(QIcon(":/fileopen.png"), tr("&Open..."), this);
00863 mpOpenAct->setShortcut(tr("Ctrl+O"));
00864 mpOpenAct->setStatusTip(tr("Open a previously saved experiment"));
00865 connect(mpOpenAct, SIGNAL(triggered()), this, SLOT(fileOpen()));
00866 mpOpenAct->setEnabled(true);
00867
00868 mpSaveAct = new QAction(QIcon(":/filesave.png"), tr("&Save..."), this);
00869 mpSaveAct->setShortcut(tr("Ctrl+S"));
00870 mpSaveAct->setStatusTip(tr("Save the experiment"));
00871 connect(mpSaveAct, SIGNAL(triggered()), this, SLOT(fileSave()));
00872 mpSaveAct->setEnabled(true);
00873
00874
00875 mpCloseAct = new QAction(QIcon(":/fileclose.png"), tr("&Close"), this);
00876 mpCloseAct->setStatusTip(tr("Close current experiment"));
00877 connect(mpCloseAct, SIGNAL(triggered()), this, SLOT(closeExperiment()));
00878
00879 mpFetchAct = new QAction(QIcon(":/filefetch.png"), tr("&Search for locality data..."), this);
00880 mpFetchAct->setShortcut(tr("Ctrl+W"));
00881 mpFetchAct->setStatusTip(tr("Search for locality data on GBIF and other data sources"));
00882 connect(mpFetchAct, SIGNAL(triggered()), this, SLOT(fileFetch()));
00883
00884 mpExitAct = new QAction(QIcon(":/exit.png"), tr("&Exit..."), this);
00885 mpExitAct->setShortcut(tr("Ctrl+Q"));
00886 mpExitAct->setStatusTip(tr("Close this application"));
00887 connect(mpExitAct, SIGNAL(triggered()), this, SLOT(fileExit()));
00888
00889 mpToolsConvertAct = new QAction(QIcon(":/tools_converter.png"), tr("Convert &GIS Formats"), this);
00890 mpToolsConvertAct->setShortcut(tr("Ctrl+G"));
00891 mpToolsConvertAct->setStatusTip(tr("Convert model and environmental data"));
00892 connect(mpToolsConvertAct, SIGNAL(triggered()), this, SLOT(toolsConvert()));
00893
00894 mpToolsClimateConvertAct = new QAction(QIcon(":/hadleyicon.png"), tr("&Import Climate Data"), this);
00895 mpToolsClimateConvertAct->setShortcut(tr("Ctrl+I"));
00896 mpToolsClimateConvertAct->setStatusTip(tr("Convert climate data to generic GIS format"));
00897 connect(mpToolsClimateConvertAct, SIGNAL(triggered()), this, SLOT(toolsClimateConvert()));
00898
00899 mpToolsContourAct = new QAction(QIcon(":/contour.png"), tr("&Convert to Contours"), this);
00900 mpToolsContourAct->setShortcut(tr("Ctrl+C"));
00901 mpToolsContourAct->setStatusTip(tr("Create contours at equal intervals from raster data"));
00902 connect(mpToolsContourAct, SIGNAL(triggered()), this, SLOT(toolsContour()));
00903
00904
00905 mpToolsRasterThresholdAct = new QAction(QIcon(":/threshold.png"), tr("Compute &Thresholds and Hotspots..."), this);
00906 mpToolsRasterThresholdAct->setShortcut(tr("Ctrl+t"));
00907 mpToolsRasterThresholdAct->setStatusTip(tr("Perform postprocessing functions to calculate thresholds and hotspots"));
00908 connect(mpToolsRasterThresholdAct, SIGNAL(triggered()), this, SLOT(toolsRasterThreshold()));
00909
00910 mpExportToCsvAct = new QAction(QIcon(":/export_csv.png"), tr("Export current model samples to CSV..."), this);
00911
00912 mpExportToCsvAct->setStatusTip(tr("Export current model samples to CSV"));
00913 connect(mpExportToCsvAct, SIGNAL(triggered()), this, SLOT(exportSamplesToCsv()));
00914
00915 mpToolsWarpAct = new QAction(QIcon(":/resize.png"), tr("&Resize Raster..."), this);
00916 mpToolsWarpAct->setShortcut(tr("Ctrl+R"));
00917 mpToolsWarpAct->setStatusTip(tr("Resize a raster file"));
00918 connect(mpToolsWarpAct, SIGNAL(triggered()), this, SLOT(toolsWarp()));
00919
00920 mpToolsFileSplitterAct = new QAction(QIcon(":/filesplitter.png"), tr("&Split Text File..."), this);
00921 mpToolsFileSplitterAct->setShortcut(tr("Ctrl+S"));
00922 mpToolsFileSplitterAct->setStatusTip(tr("Split a text file into several parts"));
00923 connect(mpToolsFileSplitterAct, SIGNAL(triggered()), this, SLOT(toolsFileSplitter()));
00924
00925 mpOptionsAct = new QAction(QIcon(":/configure.png"), tr("&Preferences..."), this);
00926 mpOptionsAct->setShortcut(tr("Ctrl+P"));
00927 mpOptionsAct->setStatusTip(tr("Configure preferences for this application"));
00928 connect(mpOptionsAct, SIGNAL(triggered()), this, SLOT(settingsOptions()));
00929
00930 mpAboutOmgAct = new QAction(QIcon(":/om_logo.png"), tr("About &openModeller Desktop"), this);
00931 mpAboutOmgAct->setStatusTip(tr("Show this application's About box"));
00932 connect(mpAboutOmgAct, SIGNAL(triggered()), this, SLOT(about()));
00933
00934 mpLicenseAct = new QAction(tr("License Agreement"), this);
00935 mpLicenseAct->setStatusTip(tr("Show this application's licensing terms"));
00936 connect(mpLicenseAct, SIGNAL(triggered()), this, SLOT(showLicense()));
00937
00938 mpHelpAct = new QAction(QIcon(":/help.png"),tr("Documentation"), this);
00939 mpHelpAct->setStatusTip(tr("Show help text for openModeller Desktop"));
00940 connect(mpHelpAct, SIGNAL(triggered()), this, SLOT(showHelp()));
00941
00942 mpSurveyAct = new QAction(QIcon(":/survey.png"),tr("User Survey"), this);
00943 mpSurveyAct->setStatusTip(tr("Participate in the openModeller Desktop user survey"));
00944 connect(mpSurveyAct, SIGNAL(triggered()), this, SLOT(showSurvey()));
00945
00946 mpLayerSetManagerAct = new QAction(QIcon(":/layersetmanager.png"),tr("LayerSets"), this);
00947 mpLayerSetManagerAct->setStatusTip(tr("Edit layerSets"));
00948 connect(mpLayerSetManagerAct, SIGNAL(triggered()), this, SLOT(showLayerSetManager()));
00949
00950 mpAlgorithmManagerAct = new QAction(QIcon(":/algorithmmanager.png"),tr("Algorithm profiles"), this);
00951 mpAlgorithmManagerAct->setShortcut(tr("Ctrl+A"));
00952 mpAlgorithmManagerAct->setStatusTip(tr("Edit algorithm profiles"));
00953 connect(mpAlgorithmManagerAct, SIGNAL(triggered()), this, SLOT(showAlgorithmManager()));
00954
00955 mpAvailableAlgorithmsReportAct = new QAction(QIcon(":/algorithmReport.png"),tr("Algorithm Profiles Report"), this);
00956 mpAvailableAlgorithmsReportAct->setStatusTip(tr("Print a report showing the various algorithm profiles that have been defined"));
00957 mpAvailableAlgorithmsReportAct->setEnabled(true);
00958 connect(mpAvailableAlgorithmsReportAct, SIGNAL(triggered()), this, SLOT(printAlgorithmProfilesReport()));
00959
00960 mpExperimentReportAct = new QAction(QIcon(":/experimentReport.png"),tr("Experiment Report"), this);
00961 mpExperimentReportAct->setStatusTip(tr("Print a report showing all the models in this experiment"));
00962 mpExperimentReportAct->setEnabled(true);
00963 connect(mpExperimentReportAct, SIGNAL(triggered()), this, SLOT(printExperimentReport()));
00964
00965 #ifdef WITH_QGIS
00966
00967 mpSaveAsImageAct = new QAction(QIcon(":/export_image.png"), tr("Export map image &as..."), this);
00968 mpSaveAsImageAct->setShortcut(tr("Ctrl+A"));
00969 mpSaveAsImageAct->setStatusTip(tr("Save map current map view as an image"));
00970 connect(mpSaveAsImageAct, SIGNAL(triggered()), this, SLOT(saveMapAsImage()));
00971 mpSaveAsImageAct->setEnabled(true);
00972
00973 mpZoomInAct = new QAction(QIcon(":/zoomIn.png"),tr("Zoom In"), this);
00974 mpZoomInAct->setStatusTip(tr("Zoom in on the map by dragging a rectangle"));
00975 mpZoomInAct->setEnabled(true);
00976 connect(mpZoomInAct, SIGNAL(triggered()), this, SLOT(zoomInMode()));
00977
00978 mpZoomOutAct = new QAction(QIcon(":/zoomOut.png"),tr("Zoom Out"), this);
00979 mpZoomOutAct->setStatusTip(tr("Zoom out on the map by dragging a rectangle"));
00980 mpZoomOutAct->setEnabled(true);
00981 connect(mpZoomOutAct, SIGNAL(triggered()), this, SLOT(zoomOutMode()));
00982
00983 mpPanAct = new QAction(QIcon(":/pan.png"),tr("Pan"), this);
00984 mpPanAct->setStatusTip(tr("Pan the map by dragging it"));
00985 mpPanAct->setEnabled(true);
00986 connect(mpPanAct, SIGNAL(triggered()), this, SLOT(panMode()));
00987
00988 mpZoomFullAct = new QAction(QIcon(":/zoomFull.png"),tr("Zoom to all"), this);
00989 mpZoomFullAct->setStatusTip(tr("Zoom to the full extents of the layers"));
00990 mpZoomFullAct->setEnabled(true);
00991 connect(mpZoomFullAct, SIGNAL(triggered()), this, SLOT(zoomFull()));
00992
00993 mpZoomPreviousAct = new QAction(QIcon(":/zoomPrevious.png"),tr("Zoom to previous"), this);
00994 mpZoomPreviousAct->setStatusTip(tr("Zoom to the previous extents"));
00995 mpZoomPreviousAct->setEnabled(true);
00996 connect(mpZoomPreviousAct, SIGNAL(triggered()), this, SLOT(zoomPrevious()));
00997
00998
00999
01000
01001
01002
01003
01004
01005
01006
01007
01008
01009
01010
01011
01012
01013
01014 #endif
01015
01016
01017
01018
01019
01020 mMinimizeAct = new QAction(tr("Mi&nimize"), this);
01021 connect(mMinimizeAct, SIGNAL(triggered()), this, SLOT(hide()));
01022
01023 mMaximizeAct = new QAction(tr("Ma&ximize"), this);
01024 connect(mMaximizeAct, SIGNAL(triggered()), this, SLOT(showMaximized()));
01025
01026 mRestoreAct = new QAction(tr("&Restore"), this);
01027 connect(mRestoreAct, SIGNAL(triggered()), this, SLOT(showNormal()));
01028
01029 mQuitAct = new QAction(tr("&Quit"), this);
01030 connect(mQuitAct, SIGNAL(triggered()), this, SLOT(fileExit()));
01031
01032
01033
01034
01035 mpDeleteModelAct = new QAction(tr("Delete &model"), this);
01036 connect(mpDeleteModelAct, SIGNAL(triggered()), this, SLOT(removeModelFromExperiment()));
01037 mpPublishModelAct = new QAction(tr("Publish &model"), this);
01038 connect(mpPublishModelAct, SIGNAL(triggered()), this, SLOT(publishModel()));
01039
01040 mpDeleteAlgorithmAct = new QAction(tr("Delete &algorithm "), this);
01041 connect(mpDeleteAlgorithmAct, SIGNAL(triggered()), this, SLOT(removeAlgorithmFromExperiment()));
01042 mpDeleteTaxonAct = new QAction(tr("Delete &taxon"), this);
01043 connect(mpDeleteTaxonAct, SIGNAL(triggered()), this, SLOT(removeTaxonFromExperiment()));
01044 }
01045
01046 void OmgMainWindow::createMenus()
01047 {
01048 mpFileMenu = menuBar()->addMenu(tr("&File"));
01049 mpFileMenu->addSeparator();
01050 mpFileMenu->addAction(mpNewAct);
01051 mpFileMenu->addAction(mpRunAct);
01052 mpFileMenu->addAction(mpResetAct);
01053 mpFileMenu->addAction(mpOpenAct);
01054 mpFileMenu->addAction(mpCloseAct);
01055 mpFileMenu->addAction(mpSaveAct);
01056 mpFileMenu->addAction(mpSaveAsImageAct);
01057 mpFileMenu->addAction(mpPrintPdfAct);
01058 mpFileMenu->addAction(mpRefreshReportsAct);
01059 mpFileMenu->addSeparator();
01060 mpFileMenu->addAction(mpExitAct);
01061
01062 mpEditMenu = menuBar()->addMenu(tr("&Edit"));
01063 mpEditMenu->addAction(mpLayerSetManagerAct);
01064 mpEditMenu->addAction(mpAlgorithmManagerAct);
01065 mpEditMenu->addSeparator();
01066 mpEditMenu->addAction(mpOptionsAct);
01067
01068 mpDataPrepMenu = menuBar()->addMenu(tr("&Data Preparation"));
01069 mpDataPrepMenu->addAction(mpFetchAct);
01070 mpDataPrepMenu->addAction(mpToolsConvertAct);
01071 mpDataPrepMenu->addAction(mpToolsClimateConvertAct);
01072 mpDataPrepMenu->addAction(mpToolsWarpAct);
01073 mpDataPrepMenu->addAction(mpToolsFileSplitterAct);
01074
01075 mpReportsMenu = menuBar()->addMenu(tr("&Reports"));
01076 mpReportsMenu->addAction(mpAvailableAlgorithmsReportAct);
01077 mpReportsMenu->addAction(mpExperimentReportAct);
01078
01079 mpPostProcessingMenu = menuBar()->addMenu(tr("&Post Processing"));
01080 mpPostProcessingMenu->addAction(mpToolsRasterThresholdAct);
01081 #ifndef OMG_NO_EXPERIMENTAL
01082 mpPostProcessingMenu->addAction(mpToolsContourAct);
01083 #endif
01084 mpPostProcessingMenu->addAction(mpExportToCsvAct);
01085 menuBar()->addSeparator();
01086
01087 mpHelpMenu = menuBar()->addMenu(tr("&Help"));
01088 mpHelpMenu->addAction(mpHelpAct);
01089 mpHelpMenu->addAction(mpLicenseAct);
01090
01091 mpHelpMenu->addSeparator();
01092 mpHelpMenu->addAction(mpAboutOmgAct);
01093
01094
01095
01096
01097
01098
01099 mpExperimentContextMenu = new QMenu(this);
01100
01101 mpTaxonContextMenu = new QMenu(this);
01102 mpTaxonContextMenu->addAction(mpDeleteTaxonAct);
01103
01104 mpModelContextMenu = new QMenu(this);
01105 mpModelContextMenu->addAction(mpDeleteModelAct);
01106 #ifdef OMG_WEBCATALOGUE
01107 mpModelContextMenu->addAction(mpPublishModelAct);
01108 #endif
01109
01110 mpAlgorithmContextMenu = new QMenu(this);
01111 mpAlgorithmContextMenu->addAction(mpDeleteAlgorithmAct);
01112 }
01113
01114 void OmgMainWindow::createToolBars()
01115 {
01116
01117
01118
01119
01120 mpFileToolBar = addToolBar(tr("File"));
01121 mpFileToolBar->setIconSize(QSize(32,32));
01122 mpFileToolBar->setObjectName("FileToolBar");
01123 mpFileToolBar->addAction(mpLayerSetManagerAct);
01124 mpFileToolBar->addAction(mpAlgorithmManagerAct);
01125 mpFileToolBar->addAction(mpNewAct);
01126 mpFileToolBar->addAction(mpRunAct);
01127 mpFileToolBar->addAction(mpSaveAct);
01128 mpFileToolBar->addAction(mpOpenAct);
01129 mpFileToolBar->addAction(mpPrintPdfAct);
01130 mpFileToolBar->addAction(mpOptionsAct);
01131
01132 mpDataPrepToolBar = addToolBar(tr("Data Preparation Tools"));
01133 mpDataPrepToolBar->setIconSize(QSize(32,32));
01134 mpDataPrepToolBar->setObjectName("DataPrepToolBar");
01135 mpDataPrepToolBar->addAction(mpFetchAct);
01136 mpDataPrepToolBar->addAction(mpToolsConvertAct);
01137 mpDataPrepToolBar->addAction(mpToolsClimateConvertAct);
01138 mpDataPrepToolBar->addAction(mpToolsWarpAct);
01139 mpDataPrepToolBar->addAction(mpToolsFileSplitterAct);
01140
01141
01142 mpPostProcessingToolBar = addToolBar(tr("Post Processing Tools"));
01143 mpPostProcessingToolBar->setIconSize(QSize(32,32));
01144 mpPostProcessingToolBar->setObjectName("PostProcessingToolBar");
01145 mpPostProcessingToolBar->addAction(mpToolsRasterThresholdAct);
01146 mpPostProcessingToolBar->addAction(mpToolsContourAct);
01147 mpPostProcessingToolBar->addAction(mpExportToCsvAct);
01148
01149
01150 mpReportsToolBar = addToolBar(tr("Reports"));
01151 mpReportsToolBar->setIconSize(QSize(32,32));
01152 mpReportsToolBar->setObjectName("ReportsToolBar");
01153 mpReportsToolBar->addAction(mpAvailableAlgorithmsReportAct);
01154 mpReportsToolBar->addAction(mpExperimentReportAct);
01155
01156 #ifdef WITH_QGIS
01157
01158
01159 mpMapToolBar = addToolBar(tr("Map"));
01160 mpMapToolBar->setIconSize(QSize(32,32));
01161 mpMapToolBar->setObjectName("MapToolBar");
01162
01163 mpMapToolBar->addAction(mpSaveAsImageAct);
01164 mpMapToolBar->addAction(mpZoomInAct);
01165 mpMapToolBar->addAction(mpZoomOutAct);
01166 mpMapToolBar->addAction(mpZoomFullAct);
01167 mpMapToolBar->addAction(mpZoomPreviousAct);
01168 mpMapToolBar->addAction(mpPanAct);
01169
01170
01171
01172
01173
01174 #endif
01175 }
01176 void OmgMainWindow::createStatusBar()
01177 {
01178
01179
01180
01181
01182 mpModelProgress = new QProgressBar(statusBar());
01183
01184 mpModelProgress->setMaximumWidth(100);
01185 mpModelProgress->hide();
01186 QWhatsThis::add(mpModelProgress, tr("This bar displays how far any running model job has progressed."));
01187 statusBar()->addWidget(mpModelProgress, 1,true);
01188
01189 mpExperimentProgress = new QProgressBar(statusBar());
01190 mpExperimentProgress->setMaximumWidth(100);
01191 mpExperimentProgress->hide();
01192 QWhatsThis::add(mpExperimentProgress, tr("This bar displays how far the current running experiment has progressed."));
01193 statusBar()->addWidget(mpExperimentProgress, 1,true);
01194
01195
01196 QFont myFont( "Arial", 9 );
01197 statusBar()->setFont(myFont);
01198 mpExperimentProgressLabel = new QLabel(QString(),statusBar());
01199 mpExperimentProgressLabel->setFont(myFont);
01200 mpExperimentProgressLabel->setMinimumWidth(10);
01201 mpExperimentProgressLabel->setMargin(3);
01202 mpExperimentProgressLabel->setAlignment(Qt::AlignCenter);
01203 mpExperimentProgressLabel->setFrameStyle(QFrame::NoFrame);
01204 mpExperimentProgressLabel->setText("");
01205 statusBar()->addWidget(mpExperimentProgressLabel, 0,true);
01206
01207 statusBar()->showMessage(tr("Ready"));
01208 }
01209
01210 void OmgMainWindow::readSettings()
01211 {
01212
01213 QSettings mySettings;
01214
01215 QVariant myState = mySettings.value("/Geometry/state");
01216 this->restoreState(myState.toByteArray());
01217
01218 splitter->restoreState(mySettings.value("/Geometry/splitterState").toByteArray());
01219
01220 QDesktopWidget *myDesktop = QApplication::desktop();
01221 int myDesktopWidth = myDesktop->width();
01222 int myDesktopHeight = myDesktop->height();
01223 int myWidth = mySettings.value("/Geometry/width", 600).toInt();
01224 int myHeight = mySettings.value("/Geometry/height", 400).toInt();
01225 int myPosX = mySettings.value("/Geometry/x", (myDesktopWidth - 600) / 2).toInt();
01226 int myPosY = mySettings.value("/Geometry/y", (myDesktopHeight - 400) / 2).toInt();
01227 resize(myWidth,myHeight);
01228 move(myPosX,myPosY);
01229 if (mySettings.value("/Geometry/maximized", false).toBool())
01230 {
01231 showMaximized();
01232 }
01233
01234
01235
01236
01237
01238
01239
01240
01241
01242
01243
01244 }
01245
01246 void OmgMainWindow::writeSettings()
01247 {
01248
01249 QSettings mySettings;
01250
01251 mySettings.setValue("/Geometry/maximized", this->isMaximized());
01252
01253 showNormal();
01254
01255
01256
01257 mySettings.setValue("/Geometry/state", this->saveState());
01258 mySettings.setValue("/Geometry/splitterState", splitter->saveState());
01259
01260
01261
01262 QPoint myPoint = this->pos();
01263 QSize mySize = this->size();
01264 mySettings.setValue("/Geometry/x", myPoint.x());
01265 mySettings.setValue("/Geometry/y", myPoint.y());
01266 mySettings.setValue("/Geometry/width", mySize.width());
01267 mySettings.setValue("/Geometry/height", mySize.height());
01268 }
01269
01270 void OmgMainWindow::publishModel()
01271 {
01272 OmgPublishToCatalogue myPublisher;
01273 myPublisher.setModel(mpCurrentModel);
01274 myPublisher.exec();
01275 }
01276
01277 #ifdef WITH_QGIS
01278
01289 static QString createFileFilter_(QString const &theLongName, QString const &glob)
01290 {
01291 return theLongName + " (" + glob.toLower() + " " + glob.toUpper() + ");;";
01292 }
01293
01294 #endif
01295
01296
01297
01298 void OmgMainWindow::fileSave()
01299 {
01300
01301 }
01302 void OmgMainWindow::fileOpen()
01303 {
01304 OmgExperimentSelector mySelector(this);
01305
01306 connect(&mySelector, SIGNAL(loadExperiment(OmgExperiment *)), this, SLOT(setCurrentExperiment(OmgExperiment *)));
01307 mySelector.exec();
01308 }
01309 void OmgMainWindow::exportSamplesToCsv()
01310 {
01311 QSettings myQSettings;
01312 QString myLastUsedDir = myQSettings.value("openModeller/lastSaveAsCsvDir",".").toString();
01313
01314
01315 std::auto_ptr < QFileDialog > myQFileDialog
01316 (
01317 new QFileDialog(
01318 this,
01319 QFileDialog::tr("Save samples to delimited file"),
01320 myLastUsedDir,
01321 "Comma delimited (*.csv);;Tab delimited (*.txt)"
01322 )
01323 );
01324 myQFileDialog->setFileMode(QFileDialog::AnyFile);
01325 myQFileDialog->setAcceptMode(QFileDialog::AcceptSave);
01326
01327
01328 QString myOutputFileName;
01329 if (myQFileDialog->exec() == QDialog::Accepted)
01330 {
01331 QStringList myFiles = myQFileDialog->selectedFiles();
01332 if (!myFiles.isEmpty())
01333 {
01334 myOutputFileName = myFiles[0];
01335 }
01336 }
01337
01338 if (!myOutputFileName.isEmpty())
01339 {
01340 if (myQFileDialog->selectedFilter()=="Comma delimited (*.csv)")
01341 {
01342
01343 if (!myOutputFileName.toUpper().endsWith(".CSV"))
01344 {
01345 myOutputFileName+=".csv";
01346 }
01347 Omgui::createTextFile(myOutputFileName , mpCurrentModel->localitiesToCsv(","));
01348 }
01349 else if (myQFileDialog->selectedFilter()=="Tab delimited (*.txt)")
01350 {
01351
01352 if (!myOutputFileName.toUpper().endsWith(".TXT"))
01353 {
01354 myOutputFileName+=".txt";
01355 }
01356 Omgui::createTextFile(myOutputFileName , mpCurrentModel->localitiesToCsv("\t"));
01357 }
01358 else
01359 {
01360 QMessageBox::warning( this,tr("openModeller Desktop"),tr("Unknown delimited format: ") +
01361 myQFileDialog->selectedFilter());
01362
01363 }
01364
01365 myQSettings.setValue("openModeller/lastSaveAsCsvDir", myQFileDialog->directory().dirName());
01366 }
01367 }
01368
01369 void OmgMainWindow::saveMapAsImage()
01370 {
01371 #ifdef WITH_QGIS
01372
01373
01374
01375 typedef QMap<QString, QString> FilterMap;
01376 FilterMap myFilterMap;
01377
01378
01379 QSettings myQSettings;
01380 QString myLastUsedFilter = myQSettings.value("openModeller/saveAsImageFilter").toString();
01381 QString myLastUsedDir = myQSettings.value("openModeller/lastSaveAsImageDir",".").toString();
01382
01383 QList<QByteArray> myFormats = QPictureIO::outputFormats();
01384
01385
01386 if (myFormats.count() == 0)
01387 {
01388 myFormats.append("png");
01389 myFormats.append("jpg");
01390 }
01391
01392 int myCounterInt=0;
01393 QString myFilters;
01394 for ( ; myCounterInt < myFormats.count(); myCounterInt++ )
01395 {
01396 QString myFormat=QString(myFormats.at( myCounterInt ));
01397 QString myFilter = createFileFilter_(myFormat + " format", "*."+myFormat);
01398 myFilters += myFilter;
01399 myFilterMap[myFilter] = myFormat;
01400 }
01401
01402
01403
01404
01405
01406
01407
01408
01409
01410 std::auto_ptr < QFileDialog > myQFileDialog
01411 (
01412 new QFileDialog(
01413 this,
01414 QFileDialog::tr("Save file dialog"),
01415 myLastUsedDir,
01416 myFilters
01417 )
01418 );
01419
01420
01421
01422 myQFileDialog->setFileMode(QFileDialog::AnyFile);
01423
01424 if (myLastUsedFilter!=QString::null)
01425 {
01426 myQFileDialog->selectFilter(myLastUsedFilter);
01427 }
01428
01429
01430
01431 QString myOutputFileName;
01432 if (myQFileDialog->exec() == QDialog::Accepted)
01433 {
01434 QStringList myFiles = myQFileDialog->selectedFiles();
01435 if (!myFiles.isEmpty())
01436 {
01437 myOutputFileName = myFiles[0];
01438 }
01439 }
01440
01441 QString myFilterString = myQFileDialog->selectedFilter()+";;";
01442
01443
01444
01445
01446 myQSettings.setValue("openModeller/lastSaveAsImageFilter" , myFilterString);
01447 myQSettings.setValue("openModeller/lastSaveAsImageDir", myQFileDialog->directory().dirName());
01448
01449 if (!myOutputFileName.isEmpty())
01450 {
01451 mpMapCanvas->saveAsImage(myOutputFileName,NULL,myFilterMap[myFilterString]);
01452 statusBar()->message(tr("Saved map image to") + " " + myOutputFileName);
01453 }
01454 #endif
01455 }
01456
01457
01458 void OmgMainWindow::setCurrentModel(OmgModel * thepModel)
01459 {
01460 if (thepModel == NULL)
01461 {
01462 return;
01463 }
01464 else if (thepModel->hasError())
01465 {
01466 QString myBusyText = tr("This model failed. See log report below for "
01467 "possible reasons why.");
01468 tbReport->clear();
01469 setReportStyleSheet();
01470 tbReport->setHtml(
01471 "<center>"
01472 "<table>"
01473 "<tr>"
01474 "<td><center><img src=\":/status_aborted.png\"></center></td>"
01475 "</tr><tr>"
01476 "<td><h2><center>" + myBusyText + "</center></h2></td>"
01477 "</tr>"
01478 "</table>"
01479 "</center>"
01480 "<pre>"
01481 + thepModel->modelLog() +
01482 "</pre>"
01483 );
01484 return;
01485 }
01486 else if (thepModel->isCompleted() != true)
01487 {
01488 QString myBusyText = tr("This model is currently"
01489 " running or has not yet been run.");
01490 tbReport->clear();
01491 setReportStyleSheet();
01492 tbReport->setHtml(
01493 "<center>"
01494 "<table>"
01495 "<tr>"
01496 "<td><center><img src=\":/status_queued.png\"></center></td>"
01497 "</tr><tr>"
01498 "<td><h2><center>" + myBusyText + "</center></h2></td>"
01499 "</tr>"
01500 "</table>"
01501 "</center>");
01502 return;
01503 }
01504 mpCurrentModel = thepModel;
01505 mpLocalitiesModel->setModel(mpCurrentModel);
01506 disableMapControls();
01507
01508 showReport(cboReportMode->currentText());
01509
01510 #ifdef WITH_QGIS
01511 QSettings mySettings;
01512
01513
01514
01515
01516 QString myLabel(mpCurrentModel->algorithm().name() +
01517 "<br/>" +
01518 mpCurrentModel->taxonName());
01519 QgsProject::instance()->writeEntry("CopyrightLabel","/Label", myLabel);
01520
01521
01522
01523 emit projectRead();
01524
01525
01526
01527 QList<QgsMapCanvasLayer> myList;
01528 mpMapCanvas->freeze(true);
01529 QgsMapLayerRegistry::instance()->removeAllMapLayers();
01530 mpMapCanvas->freeze(false);
01531
01532
01533
01534
01535
01536
01537 QString myShapeFile (mpCurrentModel->workDir() + mpCurrentModel->shapefileName());
01538 qDebug("Trying to load: " + mpCurrentModel->shapefileName().toLocal8Bit());
01539 QString myRasterFile (mpCurrentModel->workDir() + mpCurrentModel->rawImageFileName());
01540 if (!QFile::exists(myShapeFile))
01541 {
01542 qDebug("Vector layer does not exist");
01543 logMessage ("Vector Layer does not exist in file system");
01544 }
01545 else
01546 {
01547 QString myProviderName = "ogr";
01548 QFileInfo myVectorFileInfo(myShapeFile);
01549 QgsVectorLayer * mypVectorLayer = new QgsVectorLayer(myVectorFileInfo.filePath(),
01550 myVectorFileInfo.completeBaseName(), myProviderName);
01551 if (mypVectorLayer->isValid())
01552 {
01553
01554
01555
01556
01557
01558
01559
01560 QgsVectorDataProvider *mypProvider =
01561 dynamic_cast<QgsVectorDataProvider *>(mypVectorLayer->getDataProvider());
01562 if (mypProvider)
01563 {
01564 int mySymbolSize(mySettings.value("mapping/localitySymbolSize",10).toInt());
01565 QgsFieldMap myFields = mypProvider->fields();
01566 bool myNewFormatFlag = false;
01567 for (int i = 0; i < myFields.size(); i++ )
01568 {
01569 if (myFields[i].name()=="status")
01570 {
01571 myNewFormatFlag=true;
01572 break;
01573 }
01574 }
01575 if (myNewFormatFlag)
01576 {
01577 QColor myPresenceColor(mySettings.value("mapping/presenceColour",QColor(Qt::green).name()).toString());
01578 QColor myAbsenceColor(mySettings.value("mapping/absenceColour",QColor(Qt::red).name()).toString());
01579
01580
01581
01582 QgsSymbol * mypPresenceSymbol = new QgsSymbol(mypVectorLayer->vectorType(),"Present","");
01583 mypPresenceSymbol->setNamedPointSymbol("hard:circle");
01584 mypPresenceSymbol->setFillColor(myPresenceColor);
01585 mypPresenceSymbol->setColor(Qt::black);
01586 mypPresenceSymbol->setPointSize(mySymbolSize);
01587 mypPresenceSymbol->setFillStyle(Qt::SolidPattern);
01588
01589
01590
01591
01592 QgsSymbol * mypPresence2Symbol = new QgsSymbol(mypVectorLayer->vectorType(),"Present - Not Used","");
01593 mypPresence2Symbol->setNamedPointSymbol("hard:triangle");
01594 mypPresence2Symbol->setFillColor(myPresenceColor);
01595 mypPresence2Symbol->setColor(Qt::black);
01596 mypPresence2Symbol->setPointSize(mySymbolSize);
01597 mypPresence2Symbol->setFillStyle(Qt::SolidPattern);
01598
01599
01600
01601
01602 QgsSymbol * mypAbsenceSymbol = new QgsSymbol(mypVectorLayer->vectorType(),"Absent","");
01603 mypAbsenceSymbol->setNamedPointSymbol("hard:circle");
01604 mypAbsenceSymbol->setFillColor(myAbsenceColor);
01605 mypAbsenceSymbol->setColor(Qt::black);
01606 mypAbsenceSymbol->setPointSize(mySymbolSize);
01607 mypAbsenceSymbol->setFillStyle(Qt::SolidPattern);
01608
01609
01610
01611
01612 QgsSymbol * mypAbsence2Symbol = new QgsSymbol(mypVectorLayer->vectorType(),"Absent","");
01613 mypAbsence2Symbol->setNamedPointSymbol("hard:triangle");
01614 mypAbsence2Symbol->setFillColor(myAbsenceColor);
01615 mypAbsence2Symbol->setColor(Qt::black);
01616 mypAbsence2Symbol->setPointSize(mySymbolSize);
01617 mypAbsence2Symbol->setFillStyle(Qt::SolidPattern);
01618
01619
01620
01621
01622 QgsUniqueValueRenderer *mypRenderer = new QgsUniqueValueRenderer(mypVectorLayer->vectorType());
01623 qDebug("Provider ok...getting status field");
01624 int myFieldIndex = mypProvider->indexFromFieldName("status");
01625 if(myFieldIndex > 0)
01626 {
01627 qDebug("Status field found");
01628 mypRenderer->setClassificationField(myFieldIndex);
01629 mypRenderer->insertValue("Present",mypPresenceSymbol);
01630 mypRenderer->insertValue("Present - Not Used",mypPresence2Symbol);
01631 mypRenderer->insertValue("Absent",mypAbsenceSymbol);
01632 mypRenderer->insertValue("Absent - Not Used",mypAbsence2Symbol);
01633 mypVectorLayer->setRenderer(mypRenderer);
01634
01635 QgsMapLayerRegistry::instance()->addMapLayer(mypVectorLayer, TRUE);
01636 myList.append(QgsMapCanvasLayer(mypVectorLayer, TRUE));
01637 }
01638 }
01639 else
01640 {
01641
01642 QgsSymbol * mypSymbol = new QgsSymbol(mypVectorLayer->vectorType());
01643 QColor myPresenceColor(mySettings.value("mapping/presenceColour",QColor(Qt::green).name()).toString());
01644 mypSymbol->setFillColor(myPresenceColor);
01645 mypSymbol->setColor(Qt::black);
01646 mypSymbol->setPointSize(mySymbolSize);
01647 mypSymbol->setFillStyle(Qt::SolidPattern);
01648 QgsSingleSymbolRenderer *mypRenderer = new QgsSingleSymbolRenderer(mypVectorLayer->vectorType());
01649 mypRenderer->addSymbol(mypSymbol);
01650 mypVectorLayer->setRenderer(mypRenderer);
01651
01652 QgsMapLayerRegistry::instance()->addMapLayer(mypVectorLayer, TRUE);
01653 myList.append(QgsMapCanvasLayer(mypVectorLayer, TRUE));
01654 }
01655 }
01656 }
01657 else
01658 {
01659
01660 }
01661 }
01662
01663
01664
01665 myShapeFile = mySettings.value("mapping/contextLayer").toString();
01666 QFileInfo myVectorFileInfo(myShapeFile);
01667 if (myVectorFileInfo.exists())
01668 {
01669 qDebug("Loading context layer");
01670 QString myProviderName = "ogr";
01671 QgsVectorLayer * mypVectorLayer = new QgsVectorLayer(myVectorFileInfo.filePath(),
01672 myVectorFileInfo.completeBaseName(), myProviderName);
01673 if (mypVectorLayer->isValid())
01674 {
01675
01676
01677
01678
01679
01680
01681
01682 QgsVectorDataProvider *mypProvider =
01683 dynamic_cast<QgsVectorDataProvider *>(mypVectorLayer->getDataProvider());
01684 if (mypProvider)
01685 {
01686 QgsSymbol * mypSymbol = new QgsSymbol(mypVectorLayer->vectorType());
01687 QColor myContextColor(mySettings.value("mapping/contextLineColour",QColor(Qt::gray).name()).toString());
01688 mypSymbol->setFillColor(myContextColor);
01689 mypSymbol->setColor(myContextColor);
01690 mypSymbol->setLineWidth(mySettings.value("mapping/contextLineWidth",1).toInt());
01691 mypSymbol->setFillStyle(Qt::NoBrush);
01692 QgsSingleSymbolRenderer *mypRenderer = new QgsSingleSymbolRenderer(mypVectorLayer->vectorType());
01693 mypRenderer->addSymbol(mypSymbol);
01694 mypVectorLayer->setRenderer(mypRenderer);
01695
01696 QgsMapLayerRegistry::instance()->addMapLayer(mypVectorLayer, TRUE);
01697 myList.append(QgsMapCanvasLayer(mypVectorLayer, TRUE));
01698 }
01699 }
01700 }
01701
01702
01703
01704
01705
01706 if (!QFile::exists(myRasterFile))
01707 {
01708 qDebug("Layer does not exist in file system");
01709
01710 mpMapCanvas->zoomFullExtent();
01711 }
01712 else
01713 {
01714 QFileInfo myRasterFileInfo(myRasterFile);
01715 QgsRasterLayer * mypRasterLayer = new QgsRasterLayer(myRasterFileInfo.filePath(),
01716 myRasterFileInfo.completeBaseName());
01717
01718 if (mypRasterLayer->isValid())
01719 {
01720 QString myFormat = mpCurrentModel->modelRasterFormat();
01721
01722 float myFormatMinimum = Omgui::getOutputFormatRanges().value(myFormat).first;
01723 float myFormatMaximum = Omgui::getOutputFormatRanges().value(myFormat).second;
01724 mypRasterLayer->setDrawingStyle(QgsRasterLayer::SINGLE_BAND_PSEUDO_COLOR);
01725 mypRasterLayer->setColorShadingAlgorithm(QgsRasterLayer::PSEUDO_COLOR);
01726 mypRasterLayer->setMinimumValue(mypRasterLayer->getGrayBandName(),myFormatMinimum, false);
01727 mypRasterLayer->setMaximumValue(mypRasterLayer->getGrayBandName(),myFormatMaximum);
01728 mypRasterLayer->setContrastEnhancementAlgorithm(
01729 QgsContrastEnhancement::STRETCH_TO_MINMAX, false);
01730 qDebug("Raster Layer is valid");
01731
01732 QgsMapLayerRegistry::instance()->addMapLayer(mypRasterLayer, TRUE);
01733
01734 myList.append(QgsMapCanvasLayer(mypRasterLayer, TRUE));
01735
01736
01737
01738 bool myResetExtentsFlag= mySettings.value("mapping/resetExtents", false).toBool();
01739 if (myResetExtentsFlag || mResetExtentsFlag)
01740 {
01741 mpMapCanvas->setExtent(mypRasterLayer->extent());
01742 mResetExtentsFlag=false;
01743 }
01744 }
01745 else
01746 {
01747 qDebug("Raster Layer is NOT valid");
01748 }
01749 }
01750
01751 mpMapCanvas->setLayerSet(myList);
01752 enableMapControls();
01753 #else
01754 lblOutputMap->setPixmap(QPixmap(mpCurrentModel->workDir() + mpCurrentModel->colouredImageFileName()));
01755 #endif
01756
01757 }
01758
01759
01760 void OmgMainWindow::on_cboSortBy_currentIndexChanged(QString theString)
01761 {
01762 if (theString==tr("Algorithm"))
01763 {
01764 mSortMode= BY_ALGORITHM;
01765 }
01766 else
01767 {
01768 mSortMode= BY_TAXON;
01769 }
01770 populateTree();
01771 }
01772 void OmgMainWindow::setCurrentExperiment(OmgExperiment * theExperiment)
01773 {
01774 if (mpCurrentExperiment)
01775 {
01776 delete mpCurrentExperiment;
01777 }
01778 mpCurrentExperiment = theExperiment;
01779
01780 mResetExtentsFlag=true;
01781
01782 bool myHasIncompleteModelsFlag = populateTree();
01783
01784
01785 setEnableModelDetailWidgets(true);
01786
01787 setWindowTitle("openModeller Desktop - " + mpCurrentExperiment->name());
01788
01789 if ( myHasIncompleteModelsFlag )
01790 {
01791 QMessageBox myMessage;
01792 myMessage.setText(tr("Would you like to run this experiment now?"));
01793 myMessage.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
01794 switch (myMessage.exec()) {
01795 case QMessageBox::Yes:
01796
01797 runExperiment();
01798 return;
01799 break;
01800 case QMessageBox::No:
01801
01802
01803 break;
01804 default:
01805
01806 break;
01807 }
01808 }
01809 }
01810 bool OmgMainWindow::populateTree()
01811 {
01812 if (!mpCurrentExperiment)
01813 {
01814 return false;
01815 }
01816 bool myHasIncompleteModelsFlag=false;
01817 disconnect(treeExperiment, SIGNAL(currentItemChanged(QTreeWidgetItem * ,QTreeWidgetItem *)), 0, 0);
01818 treeExperiment->clear();
01819 int myCount = mpCurrentExperiment->count();
01820
01821 QTreeWidgetItem * mypExperimentItem = new QTreeWidgetItem(treeExperiment);
01822 mypExperimentItem->setText(0,tr("Experiment"));
01823 QIcon myExperimentIcon;
01824 myExperimentIcon.addFile(":/filenewExperiment.png");
01825 mypExperimentItem->setIcon(0,myExperimentIcon);
01826 treeExperiment->setItemExpanded(mypExperimentItem,true);
01827
01828 treeExperiment->setItemSelected(mypExperimentItem,true);
01829 currentItemChanged(mypExperimentItem,mypExperimentItem);
01830
01831
01832
01833 QMap <QString,QTreeWidgetItem *> myParentMap;
01834 for (int i=0; i<myCount; i++)
01835 {
01836 OmgModel * mypModel=mpCurrentExperiment->getModel(i);
01837 if (mypModel==NULL)
01838 {
01839 emit logMessage("Model is null is NULL, skipping");
01840 continue;
01841 }
01842 QString myName;
01843 QString myParentType;
01844 QString myIconFileName;
01845 if (mSortMode==BY_TAXON)
01846 {
01847 myName = mypModel->taxonName();
01848 myParentType = "Taxon";
01849 myIconFileName = ":/taxon.png";
01850 }
01851 else
01852 {
01853 myName = mypModel->algorithm().name();
01854 myParentType = "Algorithm";
01855 myIconFileName = ":/algorithmmanager.png";
01856 }
01857 if (!myParentMap.contains(myName))
01858 {
01859 QTreeWidgetItem * mypParentItem = new QTreeWidgetItem(mypExperimentItem);
01860 mypParentItem->setText(0,myName);
01861 QIcon myParentIcon;
01862 myParentIcon.addFile(myIconFileName);
01863 mypParentItem->setIcon(0,myParentIcon);
01864 myParentMap[myName]=mypParentItem;
01865
01866 mypParentItem->setText(1,myParentType);
01867
01868
01869 treeExperiment->setItemExpanded(mypParentItem,true);
01870 }
01871 }
01872
01873
01874
01875
01876 mTreeItemsHash.clear();
01877 for (int i=0; i<myCount; i++)
01878 {
01879 OmgModel * mypModel=mpCurrentExperiment->getModel(i);
01880 if (mypModel==NULL)
01881 {
01882 emit logMessage("Model is null is NULL, skipping");
01883 continue;
01884 }
01885
01886 QTreeWidgetItem * mypParentItem;
01887 QString myItemText;
01888 if (mSortMode==BY_TAXON)
01889 {
01890 mypParentItem = myParentMap.value(mypModel->taxonName());
01891 myItemText = mypModel->algorithm().name();
01892 }
01893 else
01894 {
01895 mypParentItem = myParentMap.value(mypModel->algorithm().name());
01896 myItemText = mypModel->taxonName();
01897 }
01898
01899 QTreeWidgetItem * mypItem = new QTreeWidgetItem(mypParentItem);
01900 mypItem->setText(0,myItemText);
01901
01902 mTreeItemsHash.insert(mypModel->guid(),mypItem);
01903 if (mypModel->isCompleted())
01904 {
01905 QIcon myIcon;
01906 myIcon.addFile(":/status_complete.png");
01907 mypItem->setIcon(0,myIcon);
01908 }
01909 else if (mypModel->hasError())
01910 {
01911 QIcon myIcon;
01912 myIcon.addFile(":/status_aborted.png");
01913 mypItem->setIcon(0,myIcon);
01914 }
01915 else
01916 {
01917 QIcon myIcon;
01918 myIcon.addFile(":/status_queued.png");
01919 mypItem->setIcon(0,myIcon);
01920 myHasIncompleteModelsFlag=true;
01921 }
01922 mypItem->setText(1,mypModel->guid());
01923 }
01924 treeExperiment->sortItems (0, Qt::AscendingOrder );
01925
01926
01927
01928
01929
01930
01931
01932
01933 treeExperiment->setContextMenuPolicy ( Qt::CustomContextMenu );
01934 connect(treeExperiment, SIGNAL(customContextMenuRequested (const QPoint & )),
01935 this, SLOT(treeContextMenuEvent(const QPoint & )));
01936
01937 connect(treeExperiment, SIGNAL(currentItemChanged(QTreeWidgetItem * ,QTreeWidgetItem *)),
01938 this, SLOT(currentItemChanged(QTreeWidgetItem * ,QTreeWidgetItem *)));
01939 return myHasIncompleteModelsFlag;
01940 }
01941 void OmgMainWindow::showAlgorithmSummary(QString theAlgorithmName)
01942 {
01943 if (!mpCurrentExperiment)
01944 {
01945 return;
01946 }
01947
01948 tbReport->hide();
01949 listThumbnails->show();
01950 listThumbnails->clear();
01951 int myCount = mpCurrentExperiment->count();
01952
01953
01954
01955 for (int i=0; i<myCount; i++)
01956 {
01957 OmgModel * mypModel=mpCurrentExperiment->getModel(i);
01958 if (mypModel==NULL)
01959 {
01960 emit logMessage("Model is null is NULL, skipping");
01961 continue;
01962 }
01963
01964 QString myItemText;
01965 myItemText = mypModel->algorithm().name();
01966 if (myItemText==theAlgorithmName)
01967 {
01968 QFileInfo myFileInfo(mypModel->workDir() + mypModel->thumbnailFileName());
01969 if (myFileInfo.exists() && !mypModel->thumbnailFileName().isEmpty())
01970 {
01971
01972 QListWidgetItem * mypItem = new QListWidgetItem(listThumbnails);
01973 QIcon myIcon;
01974 myIcon.addFile(mypModel->workDir() + mypModel->thumbnailFileName());
01975 mypItem->setIcon(myIcon);
01976 }
01977 else
01978 {
01979 emit logMessage(mypModel->thumbnailFileName() + " is missing, not added to thumbnail view");
01980 }
01981 }
01982 }
01983
01984
01985 }
01986
01987 void OmgMainWindow::showTaxonSummary(QString theTaxonName)
01988 {
01989 if (!mpCurrentExperiment)
01990 {
01991 return;
01992 }
01993
01994 tbReport->hide();
01995 listThumbnails->show();
01996 listThumbnails->clear();
01997 int myCount = mpCurrentExperiment->count();
01998
01999
02000
02001 for (int i=0; i<myCount; i++)
02002 {
02003 OmgModel * mypModel=mpCurrentExperiment->getModel(i);
02004 if (mypModel==NULL)
02005 {
02006 emit logMessage("Model is null is NULL, skipping");
02007 continue;
02008 }
02009
02010 QString myItemText = mypModel->taxonName();
02011 if (myItemText==theTaxonName)
02012 {
02013 QFileInfo myFileInfo(mypModel->workDir() + mypModel->thumbnailFileName());
02014 if (myFileInfo.exists() && !mypModel->thumbnailFileName().isEmpty())
02015 {
02016
02017 QListWidgetItem * mypItem = new QListWidgetItem(listThumbnails);
02018 QIcon myIcon;
02019 myIcon.addFile(mypModel->workDir() + mypModel->thumbnailFileName());
02020 mypItem->setIcon(myIcon);
02021 }
02022 }
02023 }
02024
02025
02026 }
02027
02028 void OmgMainWindow::currentItemChanged(QTreeWidgetItem * thepCurrentItem, QTreeWidgetItem * thepPreviousItem)
02029 {
02030 if (!mpCurrentExperiment)
02031 {
02032 return;
02033 }
02034
02035 if (thepCurrentItem->text(0) == tr("Experiment"))
02036 {
02037 listThumbnails->hide();
02038 tbReport->show();
02039 QString myUrl = mpCurrentExperiment->toSummaryHtml();
02040
02041 setReportStyleSheet();
02042 tbReport->setSource(QUrl::fromLocalFile( myUrl ));
02043 tabModelViewDetails->setCurrentIndex(0);
02044 return;
02045 }
02046 else if (thepCurrentItem->text(1) == "Algorithm")
02047 {
02048 qDebug("Algorithm node clicked");
02049 qDebug(thepCurrentItem->text(0));
02050 tabModelViewDetails->setCurrentIndex(0);
02051 showAlgorithmSummary(thepCurrentItem->text(0));
02052 return;
02053 }
02054 else if (thepCurrentItem->text(1) == "Taxon")
02055 {
02056 qDebug("Taxon node clicked");
02057 qDebug(thepCurrentItem->text(0));
02058
02059 tabModelViewDetails->setCurrentIndex(0);
02060 showTaxonSummary(thepCurrentItem->text(0));
02061 return;
02062 }
02063
02064 listThumbnails->hide();
02065 tbReport->show();
02066
02067
02068
02069
02070 OmgModel * mypModel =
02071 mpCurrentExperiment->getModel(thepCurrentItem->text(1));
02072
02073
02074 if (mypModel)
02075 {
02076 setCurrentModel(mypModel);
02077 return;
02078 }
02079
02080 }
02081 void OmgMainWindow::treeContextMenuEvent(const QPoint & thePoint)
02082 {
02083 QTreeWidgetItem* mypItem = treeExperiment->itemAt(thePoint);
02084 currentItemChanged (mypItem,mypItem);
02085
02086
02087
02088 if (mypItem->text(0) == tr("Experiment"))
02089 {
02090 qDebug("Experiment context");
02091 return;
02092 }
02093 else if (mypItem->text(1) == "Algorithm")
02094 {
02095 qDebug("Algorithm context");
02096 mpAlgorithmContextMenu->popup(treeExperiment->mapToGlobal(thePoint));
02097 return;
02098 }
02099 else if (mypItem->text(1) == "Taxon")
02100 {
02101 qDebug("Taxon context");
02102 mpTaxonContextMenu->popup(treeExperiment->mapToGlobal(thePoint));
02103 return;
02104 }
02105 else
02106 {
02107 qDebug("Model context");
02108 mpModelContextMenu->popup(treeExperiment->mapToGlobal(thePoint));
02109 return;
02110 }
02111 }
02112 void OmgMainWindow::removeModelFromExperiment()
02113 {
02114 QString myGuid = mpCurrentModel->guid();
02115 mpCurrentExperiment->removeModel(myGuid);
02116 mpCurrentExperiment->save();
02117 mpCurrentExperiment->toSummaryHtml(true);
02118 populateTree();
02119 }
02120 void OmgMainWindow::removeAlgorithmFromExperiment()
02121 {
02122 QList<QTreeWidgetItem *> myList = treeExperiment->selectedItems();
02123 QTreeWidgetItem * mypItem = myList.at(0);
02124 if (mypItem->text(1) != "Algorithm")
02125 {
02126 return;
02127 }
02128 QString myAlgorithmName = mypItem->text(0);
02129 mpCurrentExperiment->removeAlgorithm(myAlgorithmName);
02130 mpCurrentExperiment->save();
02131 mpCurrentExperiment->toSummaryHtml(true);
02132 populateTree();
02133 }
02134 void OmgMainWindow::removeTaxonFromExperiment()
02135 {
02136 QList<QTreeWidgetItem *> myList = treeExperiment->selectedItems();
02137 QTreeWidgetItem * mypItem = myList.at(0);
02138 if (mypItem->text(1) != "Taxon")
02139 {
02140 return;
02141 }
02142 QString myTaxonName = mypItem->text(0);
02143 mpCurrentExperiment->removeTaxon(myTaxonName);
02144 mpCurrentExperiment->save();
02145 mpCurrentExperiment->toSummaryHtml(true);
02146 populateTree();
02147
02148 }
02149 void OmgMainWindow::reportModeChanged(QString theReportMode)
02150 {
02151
02152 showReport(theReportMode);
02153 }
02154
02155 void OmgMainWindow::setTreeColumnSizes(int position,int index)
02156 {
02157 QString myWidth = QString::number(treeExperiment->width());
02158
02159 treeExperiment->header()->resizeSection(0,treeExperiment->width());
02160 treeExperiment->header()->resizeSection(1,0);
02161 }
02162
02163 void OmgMainWindow::resizeEvent ( QResizeEvent * theEvent )
02164 {
02165 setTreeColumnSizes(0,0);
02166 }
02167
02168 void OmgMainWindow::showReport(QString theReportMode)
02169 {
02170
02171 if (theReportMode==QString("HTML"))
02172 {
02173 tbReport->clear();
02174 setReportStyleSheet();
02175 tbReport->setSource(QUrl::fromLocalFile(mpCurrentModel->toHtml()));
02176 }
02177 else if(theReportMode=="Text")
02178 {
02179 tbReport->clear();
02180 tbReport->insertPlainText(mpCurrentModel->toString());
02181 }
02182 else if(theReportMode=="XML")
02183 {
02184 tbReport->clear();
02185
02186 tbReport->insertPlainText(mpCurrentModel->toXml());
02187
02188 OmgAlgorithm myAlgorithm=mpCurrentModel->algorithm();
02189
02190 }
02191 else
02192 {
02193
02194 }
02195 }
02196
02197 void OmgMainWindow::setEnableModelDetailWidgets(bool theBool)
02198 {
02199
02200
02201 treeExperiment->setEnabled(theBool);
02202 tabModelViewDetails->setEnabled(theBool);
02203 cboSortBy->setEnabled(theBool);
02204
02205 if(theBool)
02206 {
02207 treeExperiment->showColumn(1);
02208 setTreeColumnSizes(0,0);
02209 }
02210 else
02211 {
02212 treeExperiment->hideColumn(1);
02213 }
02214 }
02215
02216 void OmgMainWindow::clearCurrentExperiment()
02217 {
02218
02219
02220
02221 treeExperiment->clear();
02222 lblOutputMap->clear();
02223 tbReport->clear();
02224
02225
02226 setEnableModelDetailWidgets(false);
02227
02228 }
02229
02230 void OmgMainWindow::showLayerSetManager()
02231 {
02232 OmgLayerSetManager myManager;
02233 myManager.show();
02234 myManager.exec();
02235
02236 }
02237
02238
02239 void OmgMainWindow::showAlgorithmManager()
02240 {
02241
02242 OmgAlgorithmManager myManager(this,Qt::Dialog);
02243 myManager.exec();
02244
02245 }
02246
02247
02248 void OmgMainWindow::setViewMode(QString theMode)
02249 {
02250
02251 if(theMode=="Browse")
02252 {
02253
02254 setEnableModelDetailWidgets(true);
02255
02256
02257 }
02258 else if (theMode=="Process")
02259 {
02260
02261 setEnableModelDetailWidgets(true);
02262
02263
02264 }
02265 else
02266 {
02267
02268 }
02269
02270 }
02271
02272 void OmgMainWindow::printAlgorithmProfilesReport()
02273 {
02274 QTextDocument myTextDocument;
02275 QString myReport;
02276 myReport += "<center><h1>openModeller Algorithm Profiles</h1>";
02277 myReport += "<hr/>";
02278 OmgAlgorithmSet myAlgorithmSet = OmgAlgorithmSet::getFromActivePlugin();
02279 myAlgorithmSet.loadAlgorithms(Omgui::userAlgorithmProfilesDirPath());
02280 myReport += myAlgorithmSet.toHtml();
02281 myTextDocument.setHtml(myReport);
02282 statusBar()->showMessage(tr("Printing Algorithm Profiles Report..."));
02283 myTextDocument.setHtml(myReport);
02284 QPrinter myPrinter;
02285
02286
02287
02288
02289
02290 myPrinter.setOutputFormat(QPrinter::NativeFormat);
02291 myPrinter.setDocName("openModellerDesktopExperimentReport");
02292 myTextDocument.print(&myPrinter);
02293 }
02294
02295 void OmgMainWindow::printExperimentReport()
02296 {
02297 if (!mpCurrentExperiment)
02298 {
02299 return;
02300 }
02301 QTextDocument myTextDocument;
02302 QString myReport;
02303 myReport += "<center><h1>openModeller Experiment Report</h1>";
02304 myReport += "<hr/>";
02305 myReport += Omgui::readTextFile(mpCurrentExperiment->toSummaryHtml());
02306 int myCount = mpCurrentExperiment->count();
02307 for (int i=0; i<myCount; i++)
02308 {
02309 OmgModel * mypModel=mpCurrentExperiment->getModel(i);
02310 if (mypModel==NULL)
02311 {
02312 emit logMessage("Model is null is NULL, skipping");
02313 continue;
02314 }
02315 myReport += Omgui::readTextFile(mypModel->toHtml());
02316 }
02317 myTextDocument.setHtml(myReport);
02318 QPrinter myPrinter;
02319
02320
02321
02322
02323
02324 myPrinter.setOutputFormat(QPrinter::NativeFormat);
02325 myPrinter.setDocName("openModellerDesktopExperimentReport");
02326 myTextDocument.print(&myPrinter);
02327 }
02328
02329 void OmgMainWindow::printPdf()
02330 {
02331 QSettings myQSettings;
02332 QString myLastUsedDir = myQSettings.value("openModeller/lastSaveAsPdfDir",".").toString();
02333
02334
02335 std::auto_ptr < QFileDialog > myFileDialog
02336 (
02337 new QFileDialog(
02338 this,
02339 QFileDialog::tr("Save experiment report to portable document format (.pdf)"),
02340 myLastUsedDir,
02341 tr("Portable Document Format (*.pdf)")
02342 )
02343 );
02344 myFileDialog->setFileMode(QFileDialog::AnyFile);
02345 myFileDialog->setAcceptMode(QFileDialog::AcceptSave);
02346
02347
02348 QString myOutputFileName;
02349 if (myFileDialog->exec() == QDialog::Accepted)
02350 {
02351 QStringList myFiles = myFileDialog->selectedFiles();
02352 if (!myFiles.isEmpty())
02353 {
02354 myOutputFileName = myFiles[0];
02355 }
02356 }
02357
02358 if (!myOutputFileName.isEmpty())
02359 {
02360 if (myFileDialog->selectedFilter()==tr("Portable Document Format (*.pdf)"))
02361 {
02362
02363 if (!myOutputFileName.toUpper().endsWith(".PDF"))
02364 {
02365 myOutputFileName+=".pdf";
02366 }
02367
02368 QPrinter myPrinter;
02369 myPrinter.setPageSize(QPrinter::A4);
02370 myPrinter.setOutputFormat(QPrinter::PdfFormat);
02371 myPrinter.setOutputFileName(myOutputFileName);
02372 myPrinter.setDocName("openModellerDesktopExperimentReport");
02373
02374 if (!mpExperimentPrinter)
02375 {
02376 mpExperimentPrinter = new OmgExperimentPrinter();
02377 }
02378 mProgressDialog.setValue(0);
02379 mProgressDialog.setLabelText(tr("Please wait while your report is generated"));
02380 mProgressDialog.show();
02381 mProgressDialog.setWindowModality(Qt::WindowModal);
02382 mProgressDialog.setAutoClose(true);
02383 connect(mpExperimentPrinter, SIGNAL(progress(int)), &mProgressDialog, SLOT(setValue(int)));
02384 connect(mpExperimentPrinter, SIGNAL(maximum(int)), &mProgressDialog, SLOT(setMaximum(int)));
02385 mpExperimentPrinter->setExperiment(mpCurrentExperiment);
02386 mpExperimentPrinter->setPrinter(myPrinter);
02387
02388
02389 mpExperimentPrinter->run();
02390
02391
02392 QApplication::alert(this);
02393 }
02394 else
02395 {
02396 QMessageBox::warning( this,tr("openModeller Desktop"),tr("Unknown delimited format: ") +
02397 myFileDialog->selectedFilter());
02398
02399 }
02400 myQSettings.setValue("openModeller/lastSaveAsPdfDir", myFileDialog->directory().absolutePath());
02401 }
02402 }
02403
02404 void OmgMainWindow::on_tabModelViewDetails_currentChanged(int theIndex)
02405 {
02406 #ifdef WITH_QGIS
02407
02408 if (theIndex==0)
02409 {
02410 disableMapControls();
02411 }
02412 else
02413 {
02414 enableMapControls();
02415 }
02416 #endif
02417 }
02418 void OmgMainWindow::disableControlsWhileRunning()
02419 {
02420 mpSaveAsImageAct->setEnabled(false);
02421 mpNewAct->setEnabled(false);
02422 mpResetAct->setEnabled(false);
02423 mpOpenAct->setEnabled(false);
02424 mpCloseAct->setEnabled(false);
02425 mpSaveAct->setEnabled(false);
02426 mpPrintPdfAct->setEnabled(false);
02427 mpRefreshReportsAct->setEnabled(false);
02428 mpLayerSetManagerAct->setEnabled(false);
02429 mpAlgorithmManagerAct->setEnabled(false);
02430 mpOptionsAct->setEnabled(false);
02431 mpToolsConvertAct->setEnabled(false);
02432 mpToolsClimateConvertAct->setEnabled(false);
02433 mpAvailableAlgorithmsReportAct->setEnabled(false);
02434 mpExperimentReportAct->setEnabled(false);
02435 mpToolsRasterThresholdAct->setEnabled(false);
02436 #ifndef OMG_NO_EXPERIMENTAL
02437 mpToolsContourAct->setEnabled(false);
02438 #endif
02439 }
02440 void OmgMainWindow::enableControlsAfterRunning()
02441 {
02442 mpSaveAsImageAct->setEnabled(true);
02443 mpNewAct->setEnabled(true);
02444 mpResetAct->setEnabled(true);
02445 mpOpenAct->setEnabled(true);
02446 mpCloseAct->setEnabled(true);
02447 mpSaveAct->setEnabled(true);
02448 mpPrintPdfAct->setEnabled(true);
02449 mpRefreshReportsAct->setEnabled(true);
02450 mpLayerSetManagerAct->setEnabled(true);
02451 mpAlgorithmManagerAct->setEnabled(true);
02452 mpOptionsAct->setEnabled(true);
02453 mpToolsConvertAct->setEnabled(true);
02454 mpToolsClimateConvertAct->setEnabled(true);
02455 mpAvailableAlgorithmsReportAct->setEnabled(true);
02456 mpExperimentReportAct->setEnabled(true);
02457 mpToolsRasterThresholdAct->setEnabled(true);
02458 #ifndef OMG_NO_EXPERIMENTAL
02459 mpToolsContourAct->setEnabled(true);
02460 #endif
02461 }
02462 void OmgMainWindow::disableMapControls()
02463 {
02464 #ifdef WITH_QGIS
02465 mpSaveAsImageAct->setEnabled(false);
02466 mpZoomInAct->setEnabled(false);
02467 mpZoomOutAct->setEnabled(false);
02468 mpPanAct->setEnabled(false);
02469 mpZoomFullAct->setEnabled(false);
02470 mpZoomPreviousAct->setEnabled(false);
02471 #endif
02472 }
02473 void OmgMainWindow::enableMapControls()
02474 {
02475 #ifdef WITH_QGIS
02476
02477 if (QFile::exists(mpCurrentModel->workDir() + mpCurrentModel->rawImageFileName()) &&
02478 tabModelViewDetails->currentIndex()==2 )
02479 {
02480 mpSaveAsImageAct->setEnabled(true);
02481 mpZoomInAct->setEnabled(true);
02482 mpZoomOutAct->setEnabled(true);
02483 mpPanAct->setEnabled(true);
02484 mpZoomFullAct->setEnabled(true);
02485 mpZoomPreviousAct->setEnabled(true);
02486 }
02487 else
02488 {
02489 disableMapControls();
02490 }
02491 #endif
02492 }
02493
02494
02495 #ifdef WITH_QGIS
02496 void OmgMainWindow::zoomInMode()
02497 {
02498
02499 mpMapCanvas->setMapTool(mpZoomInTool);
02500 }
02501 void OmgMainWindow::zoomOutMode()
02502 {
02503
02504 mpMapCanvas->setMapTool(mpZoomOutTool);
02505 }
02506 void OmgMainWindow::panMode()
02507 {
02508
02509 mpMapCanvas->setMapTool(mpPanTool);
02510 }
02511 void OmgMainWindow::zoomFull()
02512 {
02513
02514 mpMapCanvas->zoomFullExtent();
02515 }
02516
02517 void OmgMainWindow::zoomPrevious()
02518 {
02519
02520 mpMapCanvas->zoomPreviousExtent();
02521 }
02522
02523
02524
02525
02526
02527
02528
02529
02530
02531
02532
02533
02534
02535
02536
02537
02538 void OmgMainWindow::addLayer()
02539 {
02540 }
02541 #endif
02542
02543 #ifdef WITH_OSSIMPLANET_QT
02544 void OmgMainWindow::initialiseOssimPlanet()
02545 {
02546 QGLFormat myFormat;
02547 myFormat.setSwapInterval(1);
02548 mpPlanet = new ossimPlanetQtGlWidget(myFormat, planetWidget);
02549 }
02550 #endif
02551
02552 void OmgMainWindow::createTrayIcon()
02553 {
02554 QSettings mySettings;
02555 bool myUseSytemTrayFlag = mySettings.value("openModeller/useSystemTray", false).toBool();
02556 if ( QSystemTrayIcon::isSystemTrayAvailable() )
02557 {
02558 mTrayIconMenu = new QMenu(this);
02559 mTrayIconMenu->addAction(mMinimizeAct);
02560 mTrayIconMenu->addAction(mMaximizeAct);
02561 mTrayIconMenu->addAction(mRestoreAct);
02562 mTrayIconMenu->addAction(mpRunAct);
02563 mTrayIconMenu->addSeparator();
02564 mTrayIconMenu->addAction(mQuitAct);
02565
02566 mTrayIcon = new QSystemTrayIcon(QIcon(":/om_logo.png"),this);
02567 mTrayIcon->setContextMenu(mTrayIconMenu);
02568
02569
02570
02571 if (myUseSytemTrayFlag)
02572 {
02573 mTrayIcon->show();
02574 bool myShowSystemTrayMessagesFlag = mySettings.value("openModeller/showSystemTrayMessages", false).toBool();
02575 if (QSystemTrayIcon::supportsMessages() && myShowSystemTrayMessagesFlag)
02576 {
02577 mTrayIcon->showMessage("openModeller Desktop",
02578 Omgui::version(),QSystemTrayIcon::Information,1000);
02579 }
02580 }
02581 }
02582 else
02583 {
02584 logMessage(tr("No system tray available on this platform, tray icon disabled"));
02585 }
02586 }
02587
02588 void OmgMainWindow::setModelCreationProgress (QString theModelGuid, int theProgress)
02589 {
02590 QSettings mySettings;
02591 bool myUseSytemTrayFlag = mySettings.value("openModeller/useSystemTray", false).toBool();
02592 QTreeWidgetItem * mypTreeItem = mTreeItemsHash[theModelGuid];
02593 mpModelProgress->setValue(theProgress);
02594 if (theProgress==0)
02595 {
02596 mypTreeItem->setIcon(0,mRunningIcon);
02597 if (QSystemTrayIcon::isSystemTrayAvailable() && myUseSytemTrayFlag)
02598 {
02599 mTrayIcon->setIcon(mRunningIcon);
02600 }
02601
02602
02603 QPalette myPalette = mpModelProgress->palette();
02604
02605 myPalette.setColor(QPalette::Highlight, QColor("red"));
02606
02607 myPalette.setColor(QPalette::WindowText, QColor("yellow"));
02608
02609
02610 mpModelProgress->setPalette(myPalette);
02611 statusBar()->showMessage(mpCurrentExperiment->currentStatus());
02612 }
02613 else
02614 {
02615 mypTreeItem->setIcon(0,mRunningIcon);
02616 if (QSystemTrayIcon::isSystemTrayAvailable() && myUseSytemTrayFlag)
02617 {
02618 mTrayIcon->setIcon(mRunningIcon);
02619 }
02620 statusBar()->showMessage(mpCurrentExperiment->currentStatus());
02621 }
02622 }
02623
02624 void OmgMainWindow::setModelProjectionProgress (QString theModelGuid, int theProgress)
02625 {
02626 if (!mpCurrentExperiment)
02627 {
02628 return;
02629 }
02630 QSettings mySettings;
02631 bool myUseSytemTrayFlag =
02632 mySettings.value("openModeller/useSystemTray", false).toBool();
02633
02634
02635 QTreeWidgetItem * mypTreeItem = mTreeItemsHash[theModelGuid];
02636 mpModelProgress->setValue(theProgress);
02637 if (theProgress >= 100)
02638 {
02639
02640 }
02641 else if (theProgress == 0)
02642 {
02643 mypTreeItem->setIcon(0,mRunningIcon);
02644 QSettings mySettings;
02645 if (QSystemTrayIcon::isSystemTrayAvailable() && myUseSytemTrayFlag)
02646 {
02647 mTrayIcon->setIcon(mRunningIcon);
02648 }
02649 QPalette myPalette = mpModelProgress->palette();
02650
02651 myPalette.setColor(QPalette::Highlight, QColor("green"));
02652
02653 myPalette.setColor(QPalette::WindowText, QColor("yellow"));
02654
02655
02656 mpModelProgress->setPalette(myPalette);
02657 statusBar()->showMessage(mpCurrentExperiment->currentStatus());
02658 }
02659 else
02660 {
02661 mypTreeItem->setIcon(0,mRunningIcon);
02662 if (QSystemTrayIcon::isSystemTrayAvailable() && myUseSytemTrayFlag)
02663 {
02664 mTrayIcon->setIcon(mRunningIcon);
02665 statusBar()->showMessage(mpCurrentExperiment->currentStatus());
02666 }
02667 }
02668 }
02669
02670
02671
02672 void OmgMainWindow::modelCompleted(QString theModelGuid)
02673 {
02674 if (!mpCurrentExperiment)
02675 {
02676 return;
02677 }
02678
02679
02680
02681 QTreeWidgetItem * mypItem = treeExperiment->currentItem();
02682 if (mypItem)
02683 {
02684 if (theModelGuid==mypItem->text(1))
02685 {
02686 OmgModel * mypModel =
02687 mpCurrentExperiment->getModel(mypItem->text(1));
02688
02689
02690 if (mypModel)
02691 {
02692 setCurrentModel(mypModel);
02693 }
02694 }
02695
02696
02697
02698
02699
02700
02701
02702
02703
02704
02705
02706 else if (mypItem->text(0) == tr("Experiment"))
02707 {
02708 listThumbnails->hide();
02709 tbReport->show();
02710 QString myUrl = mpCurrentExperiment->toSummaryHtml();
02711 setReportStyleSheet();
02712 tbReport->setSource(QUrl::fromLocalFile( myUrl ));
02713 tabModelViewDetails->setCurrentIndex(0);
02714 logMessage("Experiment report updated as a model just completed");
02715 logMessage(myUrl);
02716 }
02717 else if (mypItem->text(1) == "Algorithm")
02718 {
02719 showAlgorithmSummary(mypItem->text(0));
02720 }
02721 else if (mypItem->text(1) == "Taxon")
02722 {
02723 showTaxonSummary(mypItem->text(0));
02724 }
02725 }
02726
02727
02728
02729 QSettings mySettings;
02730 bool myUseSytemTrayFlag =
02731 mySettings.value("openModeller/useSystemTray", false).toBool();
02732 bool myShowSystemTrayMessagesFlag =
02733 mySettings.value("openModeller/showSystemTrayMessages", false).toBool();
02734 QTreeWidgetItem * mypTreeItem = mTreeItemsHash[theModelGuid];
02735 QIcon myIcon;
02736 myIcon.addFile(":/status_complete.png");
02737 mypTreeItem->setIcon(0,myIcon);
02738
02739 if (QSystemTrayIcon::isSystemTrayAvailable() && myUseSytemTrayFlag)
02740 {
02741 mTrayIcon->setIcon(myIcon);
02742 if (QSystemTrayIcon::supportsMessages() && myShowSystemTrayMessagesFlag)
02743 {
02744 QString myAlgorithmName =
02745 mpCurrentExperiment->getModel(theModelGuid)->algorithm().name();
02746 mTrayIcon->showMessage("openModeller Desktop",myAlgorithmName + "\n"
02747 +mypTreeItem->text(0) +
02748 tr(" model and projection completed."),QSystemTrayIcon::Information, 1000);
02749 }
02750 }
02751 }
02752
02753 void OmgMainWindow::setExperimentProgress (int theProgress)
02754 {
02755 mpExperimentProgressLabel->setText(tr("Experiment Progress (")
02756 + QString::number(theProgress)
02757 + "/"
02758 + QString::number(mpExperimentProgress->maximum()) +")");
02759 mpExperimentProgress->setValue(theProgress);
02760 }
02761
02762 void OmgMainWindow::setExperimentMaximum(int theMaximum)
02763 {
02764 mpExperimentProgressLabel->setText(tr("Experiment Progress (")
02765 +"0/"
02766 + QString::number(theMaximum) +")");
02767 mpExperimentProgress->setMaximum(theMaximum);
02768 mpExperimentProgress->setValue(0);
02769 }
02770 void OmgMainWindow::logMessage(QString theMessage)
02771 {
02772 tbLog->append(theMessage);
02773 tbLog->ensureCursorVisible();
02774
02775
02776
02777 QSettings mySettings;
02778 bool myLogToFileFlag = mySettings.value("openModeller/logToFile", false).toBool();
02779 if (myLogToFileFlag)
02780 {
02781 QString myFileName = mySettings.value("openModeller/logFile","/tmp/omglog.txt").toString();
02782 QFile myFile( myFileName );
02783 if ( myFile.open( QIODevice::Append ) )
02784 {
02785 QTextStream myQTextStream( &myFile );
02786 myQTextStream << theMessage << "\n";
02787 myFile.close();
02788 }
02789 }
02790 }
02791 void OmgMainWindow::logMessage(QString theModelGuid, QString theMessage)
02792 {
02793
02794 logMessage(theMessage);
02795 }
02796 void OmgMainWindow::logError(QString theModelGuid, QString theMessage)
02797 {
02798
02799
02800 tbLog->textCursor().movePosition(QTextCursor::End);
02801 tbLog->insertHtml("<br/><font color=\"red\">" + theMessage + "</font><font color=\"black\"> * </font><br/>");
02802 tbLog->ensureCursorVisible();
02803
02804
02805
02806
02807 QSettings mySettings;
02808 bool myLogToFileFlag = mySettings.value("openModeller/logToFile", false).toBool();
02809 if (myLogToFileFlag)
02810 {
02811 QString myFileName = mySettings.value("openModeller/logFile","/tmp/omglog.txt").toString();
02812 QFile myFile( myFileName );
02813 if ( myFile.open( QIODevice::Append) )
02814 {
02815 QTextStream myQTextStream( &myFile );
02816
02817 myQTextStream << theMessage;
02818 myFile.close();
02819 }
02820 }
02821
02822
02823
02824
02825
02826 mpModelProgress->setValue(100);
02827 QTreeWidgetItem * mypTreeItem = mTreeItemsHash[theModelGuid];
02828 QIcon myIcon;
02829 myIcon.addFile(":/status_aborted.png");
02830 mypTreeItem->setIcon(0,myIcon);
02831 treeExperiment->setItemWidget(mypTreeItem,0,NULL);
02832
02833
02834
02835
02836 bool myUseSytemTrayFlag =
02837 mySettings.value("openModeller/useSystemTray", false).toBool();
02838 bool myShowSystemTrayMessagesFlag =
02839 mySettings.value("openModeller/showSystemTrayMessages", false).toBool();
02840 if (QSystemTrayIcon::isSystemTrayAvailable() && myUseSytemTrayFlag)
02841 {
02842 mTrayIcon->setIcon(myIcon);
02843 if (QSystemTrayIcon::supportsMessages() && myShowSystemTrayMessagesFlag)
02844 {
02845 QString myAlgorithmName =
02846 mpCurrentExperiment->getModel(theModelGuid)->algorithm().name();
02847 mTrayIcon->showMessage("openModeller Desktop",myAlgorithmName + "\n"
02848 +mypTreeItem->text(0) +
02849 tr(" model and projection failed!"),QSystemTrayIcon::Warning, 1000);
02850 }
02851 }
02852 }
02853
02854 void OmgMainWindow::stopExperiment()
02855 {
02856 if (!mpCurrentExperiment)
02857 {
02858 return;
02859 }
02860 mpCurrentExperiment->abort();
02861
02862
02863 }
02864 void OmgMainWindow::experimentStopped()
02865 {
02866 mpModelProgress->hide();
02867 mpExperimentProgress->hide();
02868 statusBar()->showMessage(tr("Experiment processing completed!"));
02869
02870 mpRunAct->setIcon(QIcon(":/status_restart.png"));
02871 mpRunAct->setText(tr("&Run / Resume current experiment"));
02872 mpRunAct->setShortcut(tr("Ctrl+R"));
02873 mpRunAct->setStatusTip(tr("Run / Resume current experiment"));
02874 disconnect(mpRunAct);
02875 connect(mpRunAct, SIGNAL(triggered()), this, SLOT(runExperiment()));
02876 mpRunningMovie->stop();
02877 enableControlsAfterRunning();
02878
02879
02880 QApplication::alert(this);
02881
02882 QSettings mySettings;
02883 bool myUseSytemTrayFlag = mySettings.value("openModeller/useSystemTray", false).toBool();
02884 if (QSystemTrayIcon::isSystemTrayAvailable() && myUseSytemTrayFlag)
02885 {
02886 mTrayIcon->setIcon(QIcon(":/om_logo.png"));
02887 bool myShowSystemTrayMessagesFlag =
02888 mySettings.value("openModeller/showSystemTrayMessages", false).toBool();
02889 if (QSystemTrayIcon::supportsMessages() && myShowSystemTrayMessagesFlag)
02890 {
02891 mTrayIcon->showMessage("openModeller Desktop",
02892 tr("Experiment completed"),QSystemTrayIcon::Information,1000);
02893 }
02894 }
02895 }
02896 void OmgMainWindow::updateRunningIcon(const QRect & theRect )
02897 {
02898
02899 mRunningIcon = QIcon(mpRunningMovie->currentPixmap());
02900 }
02901
02902
02903 void OmgMainWindow::refreshReports()
02904 {
02905 if (!mpCurrentExperiment) return;
02906 QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
02907 mpCurrentExperiment->toSummaryHtml(true);
02908 int myCount = mpCurrentExperiment->count();
02909 for (int i=0; i<myCount; i++)
02910 {
02911 OmgModel * mypModel=mpCurrentExperiment->getModel(i);
02912 mypModel->toHtml(true);
02913 mypModel->createThumbnail();
02914 }
02915 QApplication::restoreOverrideCursor();
02916 }
02917
02918 void OmgMainWindow::setReportStyleSheet()
02919 {
02920 QString myStyle = Omgui::defaultStyleSheet();
02921 tbReport->document()->setDefaultStyleSheet(myStyle);
02922 }
02923
02924 QString OmgMainWindow::helpText()
02925 {
02926
02927
02928
02929
02930 QString myString;
02931 myString += "<h1><center>";
02932 myString += ("openModeller Desktop - Documentation");
02933 myString += "</center></h1>";
02934 myString += "<p>";
02935 myString += tr("This is the help documentation for"
02936 " openModeller Desktop. You can return to this help"
02937 " document at any stage by using Help->Documentation"
02938 " from the menu. Please visit the openModeller home"
02939 " page at http://openmodeller.sf.net for additional"
02940 " information about openModeller.");
02941 myString += "</p>";
02942 myString += "<br/>";
02943 myString += "<table>";
02944
02945 myString += "<tr>";
02946 myString += "<td rowspan=\"2\">";
02947 myString +="<img src=\":/localities_file.png\">\n";
02948 myString += "</td>";
02949 myString += "<td>";
02950 myString += "<h2>";
02951 myString += tr("Important notes about the occurrences file format");
02952 myString += "</h2>";
02953 myString += "</td>";
02954 myString += "</tr>";
02955 myString += "<tr>";
02956 myString += "<td>";
02957 myString +=tr("As of openModellerDesktop version 1.0.6 your occurrence "
02958 "files need to be in the following format:"
02959 );
02960 myString += "<p><pre>";
02961 myString +=tr("#ID-tab-Taxon Name-tab-Longitude-tab-Latitude-tab-Abundance (optional)");
02962 myString += "</p></pre>";
02963 myString += "<ul>";
02964 myString += "<li>";
02965 myString +=tr("Lines starting with # are ignored."
02966 );
02967 myString += "<li>";
02968 myString +=tr("The -tab- markers above should be the inserted by pressing the tab key "
02969 "on your keyboard."
02970 );
02971 myString += "<li>";
02972 myString +=tr("The Id can be a number, text or combination there-of."
02973 );
02974 myString += "<li>";
02975 myString +=tr("The taxon name should be separated with spaces and may include "
02976 "specific and subspecific epithet. Note that names should be identical "
02977 "for the ths same taxon otherwise openModeller Desktop will treat "
02978 "each name variation as a separate taxon."
02979 );
02980 myString += "<li>";
02981 myString +=tr("The abundance column is optional. An abundance of 0 is used "
02982 "to indicate an absence record. Note that not all openModeller "
02983 "algorithms support the use of absence data."
02984 );
02985 myString += "<li>";
02986 myString +=tr("You can automatically retrieve occurrence data using the "
02987 "openModeller Desktop localities search tool (see below). "
02988 "We recommend using the 'GBIF Rest' option for best results."
02989 );
02990 myString += "</ul>";
02991 myString +=tr("Here is a worked example of a typical occurrences file:"
02992 );
02993 myString += "<p><pre>";
02994 myString +=tr("#ID Taxon Name Longitude Latitude Abundance\n");
02995 myString += "23842684 Acacia cyclops 115.76 -31.98 1\n"
02996 "23842770 Acacia cyclops 120.867 -33.7166 1\n"
02997 "23842772 Acacia cyclops 121.33 -33.8 1\n"
02998 "23842910 Acacia cyclops 115.767 -32.115 0\n"
02999 "23843184 Acacia cyclops 115.733 -32.05 1\n";
03000 myString += "</p></pre>";
03001 myString += "</td>";
03002 myString += "</tr>";
03003
03004 myString += "<tr>";
03005 myString += "<td rowspan=\"2\">";
03006 myString +="<img src=\":/filefetch.png\">\n";
03007 myString += "</td>";
03008 myString += "<td>";
03009 myString += "<h2>";
03010 myString += tr("Localities Search Tool");
03011 myString += "</h2>";
03012 myString += "</td>";
03013 myString += "</tr>";
03014 myString += "<tr>";
03015 myString += "<td>";
03016 myString +=tr("You can use the localities search tool to"
03017 " automatically retrieve species occurrence data."
03018 " The localities search tool is plugin based so"
03019 " we provide search functionality against various"
03020 " online resources such as GBIF and speciesLink."
03021 " More data sources will be added over time."
03022 " If you need a custom search plugin for your "
03023 " institution please contact us (tim@linfiniti.com)"
03024 " - we may be able to help"
03025 );
03026 myString += "</td>";
03027 myString += "</tr>";
03028
03029 myString += "<tr>";
03030 myString += "<td rowspan=\"2\">";
03031 myString +="<img src=\":/layersetmanager.png\">\n";
03032 myString += "</td>";
03033 myString += "<td>";
03034 myString += "<h2>";
03035 myString += tr("Layer Set Manager");
03036 myString += "</h2>";
03037 myString += "</tr>";
03038 myString += "<tr>";
03039 myString += "</td>";
03040 myString += "<td>";
03041 myString +=tr("Use the layer set manager to define layer sets."
03042 " Layer sets are named groups of layers. In openModeller"
03043 " Desktop you use layer sets to specify the raster"
03044 " layers that should be used for creating models and "
03045 " for projecting models."
03046 );
03047 myString += "</td>";
03048 myString += "</tr>";
03049
03050 myString += "<tr>";
03051 myString += "<td rowspan=\"2\">";
03052 myString +="<img src=\":/algorithmmanager.png\">\n";
03053 myString += "</td>";
03054 myString += "<td>";
03055 myString += "<h2>";
03056 myString +=tr("Algorithm Manager");
03057 myString += "</h2>";
03058 myString += "</tr>";
03059 myString += "<tr>";
03060 myString += "</td>";
03061 myString += "<td>";
03062 myString += tr("The authors of openModeller algorithms"
03063 " provide sensible defaults for each algorithm. With the"
03064 " algorithm manager you can cutomise these defaults to"
03065 " make the algorithm perform in a way more suited to your needs."
03066 " The default algorithm parameters are called 'System Profiles'."
03067 " You can clone any profile using the algorithm manager to create"
03068 " a 'User Profile', and then customise the user profile as you like."
03069 );
03070 myString += "</td>";
03071 myString += "</tr>";
03072
03073 myString += "<tr>";
03074 myString += "<td rowspan=\"2\">";
03075 myString +="<img src=\":/filenewExperiment.png\">\n";
03076 myString += "</td>";
03077 myString += "<td>";
03078 myString += "<h2>";
03079 myString += tr("Experiment Designer");
03080 myString += "</h2>";
03081 myString += "</tr>";
03082 myString += "<tr>";
03083 myString += "</td>";
03084 myString += "<td>";
03085 myString +=tr("Once you have defined at least one layer set"
03086 " and have some occurrence data available, you can use"
03087 " the experiment designer to prepare an experiment. An"
03088 " experiment is a collection of models. Once the"
03089 " experiment has been created, it will be loaded"
03090 " in the experiment tree on the left of this window, and"
03091 " you will be asked if you wish to start running the experiment."
03092 );
03093
03094 myString += "<tr>";
03095 myString += "<td rowspan=\"2\">";
03096 myString +="<img src=\":/threshold.png\">\n";
03097 myString += "</td>";
03098 myString += "<td>";
03099 myString += "<h2>";
03100 myString += tr("Threshold Tool");
03101 myString += "</h2>";
03102 myString += "</tr>";
03103 myString += "<tr>";
03104 myString += "</td>";
03105 myString += "<td>";
03106 myString +=tr("The threshold tool creates boolean model projection"
03107 " rasters from probability range rasters using a Minimum Cut-off "
03108 " Threshold Percentage. Using this tool you "
03109 " can:");
03110 myString += "<ul>";
03111 myString += "<li>";
03112 myString +=tr("Create a model projection map that shows only cells"
03113 " that were above a specific probabilty of occurrence.");
03114 myString += "</li>";
03115 myString += "<li>";
03116 myString +=tr("Create a 'hotspot' map showing predicted alpha"
03117 " biodiversity based on the number of thresholded probability"
03118 " layers for different taxa predicting presence in each cell."
03119 );
03120 myString += "</li>";
03121 myString += "<li>";
03122 myString +=tr("Create a 'concensus' model showing "
03123 " number of thresholded models predicting presence in each cell."
03124 );
03125 myString += "</li>";
03126 myString += "</ul>";
03127 myString += tr("To perform a threshold analysis, you can select any "
03128 "number of models from the experiment tree. Only succaessfully "
03129 "completed model projections are shown in the tree. A thumbnail "
03130 "preview of each model is drawn next to each entry in the tree. "
03131 "By sorting the tree by taxon or by algorithm, you can easily "
03132 "select a group of model projections.");
03133 myString += "\n";
03134 myString += tr("Selecting one or more taxa from the same algorithm "
03135 "group (sort by algorithm view) will effectively perform a "
03136 "'hotspot' analysis, where each cell in the output raster "
03137 "represents the number of taxa predicted presence in that cell "
03138 "based on the defined Minimum Cut-off Threshold Percentage.");
03139 myString += "\n";
03140 myString += tr("Selecting one or more algorithms for a given taxon "
03141 "(sort by taxon view) will allow you to create a 'concensus model'."
03142 "In a concensus model, the value of each cell in the output raster "
03143 "indicates the number of algorithms that predict presence for that "
03144 "cell - based on the Minimum Cut-off Threshold Percentage selected.");
03145 myString += "\n";
03146 myString += tr("Optionally you can write out each model projection "
03147 "as a boolean layer where 0 indicates absence and 1 indicates "
03148 "presence, based on the Minimum Cut-off Threshold Percentage selected.");
03149 myString += "</td>";
03150 myString += "</tr>";
03151
03152 myString += "</td>";
03153 myString += "</tr>";
03154 myString += experimentHelpText();
03155
03156
03157
03158
03159
03160
03161
03162
03163
03164
03165
03166
03167
03168
03169
03170
03171
03172
03173
03174
03175 myString += "<table>";
03176 return myString;
03177 }
03178
03179 QString OmgMainWindow::experimentHelpText()
03180 {
03181 QString myString;
03182
03183 myString += "<tr>";
03184 myString += "<td>";
03185 myString += "</td>";
03186 myString += "<td>";
03187 myString +=tr("While the "
03188 " experiment is running you can browse the results "
03189 " of models as they are completed. Click on "
03190 " a taxon node (when sort by taxon is enabled) "
03191 " or an algorithm node (when sort by algorithm is "
03192 " enabled) for a thumbnail overview of completed "
03193 " model projections. Model nodes in the tree are "
03194 " marked with the following symbols according to "
03195 " the model status:");
03196 myString += "</td>";
03197 myString += "</tr>";
03198
03199 myString += "<tr>";
03200 myString += "<td rowspan=\"2\">";
03201 myString +="<img src=\":/status_queued.png\">\n";
03202 myString += "</td>";
03203 myString += "<td>";
03204 myString += "<h2>";
03205 myString += tr("Model queued for execution ...");
03206 myString += "</h2>";
03207 myString += "</td>";
03208 myString += "</tr>";
03209 myString += "<tr>";
03210 myString += "<td>";
03211 myString +=tr("When you see this icon next to a model node "
03212 " it means the model is queued, awaiting execution."
03213 );
03214 myString += "</td>";
03215 myString += "</tr>";
03216
03217 myString += "<tr>";
03218 myString += "<td rowspan=\"2\">";
03219 myString +="<img src=\":/status_running.png\">\n";
03220 myString += "</td>";
03221 myString += "<td>";
03222 myString += "<h2>";
03223 myString += tr("Model is running ...");
03224 myString += "</h2>";
03225 myString += "</td>";
03226 myString += "</tr>";
03227 myString += "<tr>";
03228 myString += "<td>";
03229 myString +=tr("When you see this icon next to a model node "
03230 " it means the model is busy running. "
03231 " The status bar help and the progress bars at the "
03232 " bottom of this windows will update you with the "
03233 " progress of the model. For more detailed information "
03234 " use the 'log' tab."
03235 );
03236 myString += "</td>";
03237 myString += "</tr>";
03238
03239 myString += "<tr>";
03240 myString += "<td rowspan=\"2\">";
03241 myString +="<img src=\":/status_complete.png\">\n";
03242 myString += "</td>";
03243 myString += "<td>";
03244 myString += "<h2>";
03245 myString += tr("Model is complete ...");
03246 myString += "</h2>";
03247 myString += "</td>";
03248 myString += "</tr>";
03249 myString += "<tr>";
03250 myString += "<td>";
03251 myString +=tr("When you see this icon next to a model node "
03252 " it means the model is finished running, "
03253 " and it has been projected. "
03254 " If you click on the model node you will be "
03255 " able to view a detailed report for the model."
03256 );
03257 myString += "</td>";
03258 myString += "</tr>";
03259
03260 myString += "<tr>";
03261 myString += "<td rowspan=\"2\">";
03262 myString +="<img src=\":/status_aborted.png\">\n";
03263 myString += "</td>";
03264 myString += "<td>";
03265 myString += "<h2>";
03266 myString += tr("Model is aborted ...");
03267 myString += "</h2>";
03268 myString += "</td>";
03269 myString += "</tr>";
03270 myString += "<tr>";
03271 myString += "<td>";
03272 myString +=tr("When you see this icon next to a model node "
03273 " it means the model is finished running, "
03274 " but it had errors and did not complete successfully. "
03275 " You may be able to find more information as "
03276 " to the cause of the model failure by consulting "
03277 " the logs in the log tab."
03278 );
03279 myString += "</td>";
03280 myString += "</tr>";
03281
03282 return myString;
03283 }
03284
03285 void OmgMainWindow::showSurvey()
03286 {
03287 OmgSurveyWizard myWizard;
03288 myWizard.exec();
03289 }
03290 void OmgMainWindow::showHelp()
03291 {
03292
03293
03294 tabModelViewDetails->setEnabled(true);
03295 tbReport->setSearchPaths(QStringList(":/"));
03296 setReportStyleSheet();
03297 QString myHelpText;
03298 QSettings mySettings;
03299 if (mySettings.value("tipOfTheDay/tipOfTheDay",true).toBool()==true)
03300 {
03301 OmgTipFactory myFactory;
03302 OmgTip myTip = myFactory.getTip();
03303 QString myTipString;
03304 myTipString += "<h1><center>";
03305 myTipString += tr("Tip of the day: ") + myTip.title();
03306 myTipString += "</center></h1><br/>";
03307 myTipString +="<p><img src=\":/tip.png\" align=\"left\">\n";
03308 myTipString += myTip.content() + "</p>";
03309 myTipString += "<hr/>";
03310 myHelpText += myTipString;
03311 }
03312 myHelpText += helpText();
03313 tbReport->setHtml(myHelpText);
03314 }