2013-10-08 14:28:01 +02:00
/////////////////////////////////////////////////////////////////////////////////
//
2014-09-23 15:04:57 +02:00
// Copyright (C) 2011- Statoil ASA
// Copyright (C) 2013- Ceetron Solutions AS
// Copyright (C) 2011-2012 Ceetron AS
2013-10-08 14:28:01 +02:00
//
// ResInsight is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE.
//
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#include "RiaApplication.h"
#include "RiaBaseDefs.h"
#include "RiaImageCompareReporter.h"
#include "RiaImageFileCompare.h"
2017-02-23 14:24:18 +01:00
#include "RiaLogging.h"
2015-09-25 15:57:43 +02:00
#include "RiaPreferences.h"
2013-12-04 12:04:42 +01:00
#include "RiaProjectModifier.h"
2015-09-25 15:57:43 +02:00
#include "RiaSocketServer.h"
#include "RiaVersionInfo.h"
2013-10-08 14:28:01 +02:00
2015-09-25 15:57:43 +02:00
#include "RigGridManager.h"
2013-10-08 14:28:01 +02:00
2015-09-25 15:57:43 +02:00
#include "Rim3dOverlayInfoConfig.h"
2013-10-08 14:28:01 +02:00
#include "RimCaseCollection.h"
2015-06-25 13:45:32 +02:00
#include "RimCellEdgeColors.h"
2013-10-08 14:28:01 +02:00
#include "RimCellRangeFilterCollection.h"
2015-09-25 15:57:43 +02:00
#include "RimCommandObject.h"
2017-06-13 15:41:52 +02:00
#include "RiaDefines.h"
2015-09-25 15:57:43 +02:00
#include "RimEclipseCaseCollection.h"
#include "RimEclipseCellColors.h"
#include "RimEclipseFaultColors.h"
#include "RimEclipseInputCase.h"
#include "RimEclipseInputPropertyCollection.h"
2015-06-25 13:05:28 +02:00
#include "RimEclipsePropertyFilterCollection.h"
2015-09-25 15:57:43 +02:00
#include "RimEclipseResultCase.h"
2015-06-25 13:23:36 +02:00
#include "RimEclipseStatisticsCase.h"
2015-09-25 15:57:43 +02:00
#include "RimEclipseView.h"
#include "RimEclipseWellCollection.h"
#include "RimFaultCollection.h"
2017-03-28 23:30:01 +02:00
#include "RimFlowCharacteristicsPlot.h"
2017-04-20 11:02:05 +02:00
#include "RimFlowPlotCollection.h"
#include "RimFormationNamesCollection.h"
2015-04-20 09:02:33 +02:00
#include "RimGeoMechCase.h"
2015-09-25 15:57:43 +02:00
#include "RimGeoMechCellColors.h"
2015-04-20 09:02:33 +02:00
#include "RimGeoMechModels.h"
#include "RimGeoMechView.h"
2015-09-25 15:57:43 +02:00
#include "RimIdenticalGridCaseGroup.h"
2015-09-03 08:09:06 +02:00
#include "RimMainPlotCollection.h"
2015-09-25 15:57:43 +02:00
#include "RimOilField.h"
#include "RimProject.h"
#include "RimReservoirCellResultsStorage.h"
#include "RimScriptCollection.h"
2016-06-24 15:10:18 +02:00
#include "RimSummaryCase.h"
#include "RimSummaryCaseCollection.h"
2016-11-07 15:57:21 +01:00
#include "RimSummaryCurve.h"
#include "RimSummaryCurveFilter.h"
2016-06-24 15:10:18 +02:00
#include "RimSummaryPlot.h"
#include "RimSummaryPlotCollection.h"
2017-04-20 11:02:05 +02:00
#include "RimTreeViewStateSerializer.h"
2015-10-23 14:13:14 +02:00
#include "RimViewLinker.h"
#include "RimViewLinkerCollection.h"
2017-01-13 13:32:02 +01:00
#include "RimWellAllocationPlot.h"
2015-09-03 08:09:06 +02:00
#include "RimWellLogPlot.h"
2015-09-25 15:57:43 +02:00
#include "RimWellLogPlotCollection.h"
#include "RimWellPath.h"
#include "RimWellPathCollection.h"
2016-06-24 15:10:18 +02:00
#include "RiuMainPlotWindow.h"
2015-09-25 15:57:43 +02:00
#include "RiuMainWindow.h"
#include "RiuProcessMonitor.h"
2016-10-05 08:23:07 +02:00
#include "RiuRecentFileActionProvider.h"
2015-11-09 19:05:00 +01:00
#include "RiuSelectionManager.h"
2016-09-01 13:01:17 +02:00
#include "RiuSummaryQwtPlot.h"
2015-09-25 15:57:43 +02:00
#include "RiuViewer.h"
2016-09-01 13:01:17 +02:00
#include "RiuWellLogPlot.h"
2017-02-13 15:47:24 +01:00
#include "RiuWellAllocationPlot.h"
2017-03-28 23:30:01 +02:00
#include "RiuFlowCharacteristicsPlot.h"
2015-09-25 15:57:43 +02:00
2016-10-06 10:33:57 +02:00
#include "RicImportSummaryCaseFeature.h"
2017-06-29 22:41:34 +02:00
#include "ExportCommands/RicSnapshotViewToClipboardFeature.h"
2016-06-30 13:21:04 +02:00
#include "SummaryPlotCommands/RicNewSummaryPlotFeature.h"
2017-07-26 16:41:17 +02:00
#include "RicfCommandFileExecutor.h"
2016-08-09 13:09:08 +02:00
#include "cafFixedAtlasFont.h"
2015-09-25 15:57:43 +02:00
#include "cafAppEnum.h"
#include "cafCeetronPlusNavigation.h"
#include "cafEffectCache.h"
#include "cafPdmFieldCvfColor.h"
#include "cafPdmFieldCvfMat4d.h"
#include "cafPdmSettings.h"
2017-04-20 08:07:47 +02:00
#include "cafPdmUiModelChangeDetector.h"
2015-09-18 19:24:02 +02:00
#include "cafPdmUiTreeView.h"
2015-09-25 15:57:43 +02:00
#include "cafProgressInfo.h"
#include "cafUiProcess.h"
#include "cafUtils.h"
2017-04-20 08:07:47 +02:00
2015-09-25 15:57:43 +02:00
#include "cvfProgramOptions.h"
#include "cvfqtUtils.h"
2016-10-05 08:23:07 +02:00
#include <QAction>
2015-09-25 15:57:43 +02:00
#include <QDesktopServices>
#include <QDir>
#include <QFileDialog>
2015-10-23 14:13:14 +02:00
#include <QMdiSubWindow>
2015-09-25 15:57:43 +02:00
#include <QMessageBox>
#include <QTimer>
#include <QUrl>
2017-04-20 11:02:05 +02:00
#include <QTreeView>
2015-09-25 15:57:43 +02:00
2015-10-05 16:09:51 +02:00
#include "gtest/gtest.h"
#ifdef WIN32
#include <fcntl.h>
#endif
2013-12-04 12:04:42 +01:00
2017-02-23 14:24:18 +01:00
2013-10-08 14:28:01 +02:00
namespace caf
{
template <>
void AppEnum < RiaApplication :: RINavigationPolicy >:: setUp ()
{
addItem ( RiaApplication :: NAVIGATION_POLICY_CEETRON , "NAVIGATION_POLICY_CEETRON" , "Ceetron" );
addItem ( RiaApplication :: NAVIGATION_POLICY_CAD , "NAVIGATION_POLICY_CAD" , "CAD" );
2015-07-02 12:31:35 +02:00
addItem ( RiaApplication :: NAVIGATION_POLICY_GEOQUEST , "NAVIGATION_POLICY_GEOQUEST" , "GEOQUEST" );
addItem ( RiaApplication :: NAVIGATION_POLICY_RMS , "NAVIGATION_POLICY_RMS" , "RMS" );
2015-07-02 13:33:07 +02:00
setDefault ( RiaApplication :: NAVIGATION_POLICY_RMS );
2013-10-08 14:28:01 +02:00
}
}
namespace RegTestNames
{
const QString generatedFolderName = "RegTestGeneratedImages" ;
const QString diffFolderName = "RegTestDiffImages" ;
const QString baseFolderName = "RegTestBaseImages" ;
2017-04-20 21:21:12 +02:00
const QString testProjectName = "RegressionTest" ;
2013-10-08 14:28:01 +02:00
const QString testFolderFilter = "TestCase*" ;
const QString imageCompareExeName = "compare" ;
const QString reportFileName = "ResInsightRegressionTestReport.html" ;
};
2013-12-04 12:04:42 +01:00
2013-10-08 14:28:01 +02:00
//==================================================================================================
///
/// \class RiaApplication
///
/// Application class
///
//==================================================================================================
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RiaApplication :: RiaApplication ( int & argc , char ** argv )
: QApplication ( argc , argv )
{
// USed to get registry settings in the right place
QCoreApplication :: setOrganizationName ( RI_COMPANY_NAME );
QCoreApplication :: setApplicationName ( RI_APPLICATION_NAME );
// For idle processing
// m_idleTimerStarted = false;
installEventFilter ( this );
//cvf::Trace::enable(false);
m_preferences = new RiaPreferences ;
2015-10-23 15:46:25 +02:00
caf :: PdmSettings :: readFieldsFromApplicationStore ( m_preferences );
2013-10-08 14:28:01 +02:00
applyPreferences ();
if ( useShaders ())
{
caf :: EffectGenerator :: setRenderingMode ( caf :: EffectGenerator :: SHADER_BASED );
}
else
{
caf :: EffectGenerator :: setRenderingMode ( caf :: EffectGenerator :: FIXED_FUNCTION );
}
// Start with a project
m_project = new RimProject ;
setWindowIcon ( QIcon ( ":/AppLogo48x48.png" ));
m_socketServer = new RiaSocketServer ( this );
m_workerProcess = NULL ;
#ifdef WIN32
m_startupDefaultDirectory = QDir :: homePath ();
#else
m_startupDefaultDirectory = QDir :: currentPath ();
#endif
2016-09-21 09:46:17 +02:00
setLastUsedDialogDirectory ( "MULTICASEIMPORT" , "/" );
2013-10-08 14:28:01 +02:00
// The creation of a font is time consuming, so make sure you really need your own font
// instead of using the application font
2016-08-09 13:09:08 +02:00
m_standardFont = new caf :: FixedAtlasFont ( caf :: FixedAtlasFont :: POINT_SIZE_8 );
2013-10-08 14:28:01 +02:00
m_resViewUpdateTimer = NULL ;
2015-06-26 13:44:16 +02:00
m_runningRegressionTests = false ;
2016-06-27 11:07:01 +02:00
m_mainPlotWindow = NULL ;
2016-10-05 08:23:07 +02:00
m_recentFileActionProvider = std :: unique_ptr < RiuRecentFileActionProvider > ( new RiuRecentFileActionProvider );
2013-10-08 14:28:01 +02:00
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RiaApplication ::~ RiaApplication ()
{
2016-06-27 15:27:18 +02:00
deleteMainPlotWindow ();
2013-10-08 14:28:01 +02:00
delete m_preferences ;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RiaApplication * RiaApplication :: instance ()
{
return static_cast < RiaApplication *> qApp ;
}
2015-12-03 10:33:38 +01:00
//--------------------------------------------------------------------------------------------------
/// Return -1 if unit test is not executed, returns 0 if test passed, returns 1 if tests failed
//--------------------------------------------------------------------------------------------------
int RiaApplication :: parseArgumentsAndRunUnitTestsIfRequested ()
{
cvf :: ProgramOptions progOpt ;
progOpt . registerOption ( "unittest" , "" , "Execute unit tests" );
progOpt . setOptionPrefix ( cvf :: ProgramOptions :: DOUBLE_DASH );
QStringList arguments = QCoreApplication :: arguments ();
bool parseOk = progOpt . parse ( cvfqt :: Utils :: toStringVector ( arguments ));
if ( ! parseOk )
{
return - 1 ;
}
// Unit testing
// --------------------------------------------------------
if ( cvf :: Option o = progOpt . option ( "unittest" ))
{
int testReturnValue = launchUnitTestsWithConsole ();
return testReturnValue ;
}
return - 1 ;
}
2013-10-08 14:28:01 +02:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiaApplication :: setWindowCaptionFromAppState ()
{
RiuMainWindow * mainWnd = RiuMainWindow :: instance ();
if ( ! mainWnd ) return ;
// The stuff being done here should really be handled by Qt automatically as a result of
// setting applicationName and windowFilePath
// Was unable to make this work in Qt4.4.0!
QString capt = RI_APPLICATION_NAME ;
#ifdef _DEBUG
capt += " ##DEBUG##" ;
#endif
{
QString projFileName = m_project -> fileName ();
if ( projFileName . isEmpty ()) projFileName = "Untitled project" ;
capt = projFileName + QString ( "[*]" ) + QString ( " - " ) + capt ;
}
mainWnd -> setWindowTitle ( capt );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiaApplication :: processNonGuiEvents ()
{
processEvents ( QEventLoop :: ExcludeUserInputEvents );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const char * RiaApplication :: getVersionStringApp ( bool includeCrtInfo )
{
// Use static buf so we can return ptr
static char szBuf [ 1024 ];
cvf :: String crtInfo ;
if ( includeCrtInfo )
{
#ifdef _MT
#ifdef _DLL
crtInfo = " (DLL CRT)" ;
#else
crtInfo = " (static CRT)" ;
#endif
#endif //_MT
}
cvf :: System :: sprintf ( szBuf , 1024 , "%s%s" , STRPRODUCTVER , crtInfo . toAscii (). ptr ());
return szBuf ;
}
2013-12-04 12:04:42 +01:00
2013-10-08 14:28:01 +02:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
2013-12-04 12:04:42 +01:00
bool RiaApplication :: loadProject ( const QString & projectFileName , ProjectLoadAction loadAction , RiaProjectModifier * projectModifier )
2013-10-08 14:28:01 +02:00
{
// First Close the current project
2016-10-04 11:02:56 +02:00
closeProject ();
2013-10-08 14:28:01 +02:00
2017-02-27 13:17:32 +01:00
RiaLogging :: info ( QString ( "Starting to open project file : '%1'" ). arg ( projectFileName ));
2017-02-23 14:24:18 +01:00
2013-10-08 14:28:01 +02:00
// Open the project file and read the serialized data.
// Will initialize itself.
2017-05-11 09:23:13 +02:00
if ( ! caf :: Utils :: fileExists ( projectFileName ))
2017-02-23 14:24:18 +01:00
{
2017-02-27 13:17:32 +01:00
RiaLogging :: info ( QString ( "File does not exist : '%1'" ). arg ( projectFileName ));
2017-02-23 14:24:18 +01:00
return false ;
}
2013-10-08 14:28:01 +02:00
m_project -> fileName = projectFileName ;
m_project -> readFile ();
2016-10-04 14:23:34 +02:00
// Apply any modifications to the loaded project before we go ahead and load actual data
2013-12-04 12:04:42 +01:00
if ( projectModifier )
{
projectModifier -> applyModificationsToProject ( m_project );
}
2013-10-08 14:28:01 +02:00
// Propagate possible new location of project
m_project -> setProjectFileNameAndUpdateDependencies ( projectFileName );
// On error, delete everything, and bail out.
if ( m_project -> projectFileVersionString (). isEmpty ())
{
2016-10-04 11:02:56 +02:00
closeProject ();
2013-10-08 14:28:01 +02:00
QString tmp = QString ( "Unknown project file version detected in file \n %1 \n\n Could not open project." ). arg ( projectFileName );
QMessageBox :: warning ( NULL , "Error when opening project file" , tmp );
RiuMainWindow * mainWnd = RiuMainWindow :: instance ();
mainWnd -> setPdmRoot ( NULL );
// Delete all object possibly generated by readFile()
delete m_project ;
m_project = new RimProject ;
onProjectOpenedOrClosed ();
return true ;
}
2016-10-04 14:23:34 +02:00
if ( m_project -> show3DWindow ())
{
RiuMainWindow :: instance () -> show ();
}
else
{
2016-10-06 15:01:27 +02:00
RiuMainWindow :: instance () -> hide ();
2016-10-04 14:23:34 +02:00
}
if ( m_project -> showPlotWindow ())
{
2016-11-10 09:26:53 +01:00
if ( ! m_mainPlotWindow )
{
createMainPlotWindow ();
}
else
{
m_mainPlotWindow -> show ();
m_mainPlotWindow -> raise ();
}
2016-10-04 14:23:34 +02:00
}
else if ( mainPlotWindow ())
{
2016-10-06 15:01:27 +02:00
mainPlotWindow () -> hide ();
2016-10-04 14:23:34 +02:00
}
2013-10-08 14:28:01 +02:00
///////
// Load the external data, and initialize stuff that needs specific ordering
// VL check regarding specific order mentioned in comment above...
m_preferences -> lastUsedProjectFileName = projectFileName ;
2015-08-04 11:47:06 +02:00
caf :: PdmSettings :: writeFieldsToApplicationStore ( m_preferences );
2013-10-08 14:28:01 +02:00
for ( size_t oilFieldIdx = 0 ; oilFieldIdx < m_project -> oilFields (). size (); oilFieldIdx ++ )
{
RimOilField * oilField = m_project -> oilFields [ oilFieldIdx ];
2015-06-25 12:11:06 +02:00
RimEclipseCaseCollection * analysisModels = oilField ? oilField -> analysisModels () : NULL ;
2013-10-08 14:28:01 +02:00
if ( analysisModels == NULL ) continue ;
for ( size_t cgIdx = 0 ; cgIdx < analysisModels -> caseGroups . size (); ++ cgIdx )
{
// Load the Main case of each IdenticalGridCaseGroup
RimIdenticalGridCaseGroup * igcg = analysisModels -> caseGroups [ cgIdx ];
igcg -> loadMainCaseAndActiveCellInfo (); // VL is this supposed to be done for each RimOilField?
}
}
2016-08-24 08:30:12 +02:00
// Load the formation names
for ( RimOilField * oilField : m_project -> oilFields )
{
if ( oilField == NULL ) continue ;
if ( oilField -> formationNamesCollection () != NULL )
{
oilField -> formationNamesCollection () -> readAllFormationNames ();
}
}
2013-10-08 14:28:01 +02:00
// Add well paths for each oil field
for ( size_t oilFieldIdx = 0 ; oilFieldIdx < m_project -> oilFields (). size (); oilFieldIdx ++ )
{
RimOilField * oilField = m_project -> oilFields [ oilFieldIdx ];
if ( oilField == NULL ) continue ;
if ( oilField -> wellPathCollection == NULL )
{
//printf("Create well path collection for oil field %i in loadProject.\n", oilFieldIdx);
oilField -> wellPathCollection = new RimWellPathCollection ();
}
if ( oilField -> wellPathCollection ) oilField -> wellPathCollection -> readWellPathFiles ();
}
2016-05-31 13:42:27 +02:00
for ( RimOilField * oilField : m_project -> oilFields )
{
if ( oilField == NULL ) continue ;
// Temporary
if ( ! oilField -> summaryCaseCollection ())
{
oilField -> summaryCaseCollection = new RimSummaryCaseCollection ();
}
oilField -> summaryCaseCollection () -> createSummaryCasesFromRelevantEclipseResultCases ();
oilField -> summaryCaseCollection () -> loadAllSummaryCaseData ();
}
2013-12-04 12:04:42 +01:00
// If load action is specified to recalculate statistics, do it now.
// Apparently this needs to be done before the views are loaded, lest the number of time steps for statistics will be clamped
if ( loadAction & PLA_CALCULATE_STATISTICS )
{
for ( size_t oilFieldIdx = 0 ; oilFieldIdx < m_project -> oilFields (). size (); oilFieldIdx ++ )
{
RimOilField * oilField = m_project -> oilFields [ oilFieldIdx ];
2015-06-25 12:11:06 +02:00
RimEclipseCaseCollection * analysisModels = oilField ? oilField -> analysisModels () : NULL ;
2013-12-04 12:04:42 +01:00
if ( analysisModels )
{
analysisModels -> recomputeStatisticsForAllCaseGroups ();
}
}
}
2013-10-08 14:28:01 +02:00
// Now load the ReservoirViews for the cases
// Add all "native" cases in the project
2015-05-15 18:51:49 +02:00
std :: vector < RimCase *> casesToLoad ;
2013-10-08 14:28:01 +02:00
m_project -> allCases ( casesToLoad );
{
2015-09-28 08:21:51 +02:00
caf :: ProgressInfo caseProgress ( casesToLoad . size (), "Reading Cases" );
2013-10-08 14:28:01 +02:00
2015-09-28 08:21:51 +02:00
for ( size_t cIdx = 0 ; cIdx < casesToLoad . size (); ++ cIdx )
2013-10-08 14:28:01 +02:00
{
2015-09-28 08:21:51 +02:00
RimCase * cas = casesToLoad [ cIdx ];
CVF_ASSERT ( cas );
2013-10-08 14:28:01 +02:00
2015-09-28 08:21:51 +02:00
caseProgress . setProgressDescription ( cas -> caseUserDescription ());
std :: vector < RimView *> views = cas -> views ();
caf :: ProgressInfo viewProgress ( views . size (), "Creating Views" );
2013-10-08 14:28:01 +02:00
2015-09-28 08:21:51 +02:00
size_t j ;
for ( j = 0 ; j < views . size (); j ++ )
{
RimView * riv = views [ j ];
CVF_ASSERT ( riv );
2013-10-08 14:28:01 +02:00
2015-09-28 08:21:51 +02:00
viewProgress . setProgressDescription ( riv -> name ());
riv -> loadDataAndUpdate ();
this -> setActiveReservoirView ( riv );
2015-10-28 12:23:24 +01:00
riv -> rangeFilterCollection () -> updateIconState ();
2015-09-28 08:21:51 +02:00
viewProgress . incrementProgress ();
}
caseProgress . incrementProgress ();
}
2013-10-08 14:28:01 +02:00
}
2015-10-22 16:02:28 +02:00
2015-10-22 16:46:58 +02:00
if ( m_project -> viewLinkerCollection () && m_project -> viewLinkerCollection () -> viewLinker ())
2015-10-22 16:02:28 +02:00
{
m_project -> viewLinkerCollection () -> viewLinker () -> updateOverrides ();
}
2016-10-05 10:04:41 +02:00
loadAndUpdatePlotData ();
2013-10-08 14:28:01 +02:00
// NB! This function must be called before executing command objects,
// because the tree view state is restored from project file and sets
// current active view ( see restoreTreeViewState() )
// Default behavior for scripts is to use current active view for data read/write
onProjectOpenedOrClosed ();
processEvents ();
// Loop over command objects and execute them
for ( size_t i = 0 ; i < m_project -> commandObjects . size (); i ++ )
{
m_commandQueue . push_back ( m_project -> commandObjects [ i ]);
}
// Lock the command queue
m_commandQueueLock . lock ();
// Execute command objects, and release the mutex when the queue is empty
executeCommandObjects ();
2017-02-27 13:17:32 +01:00
RiaLogging :: info ( QString ( "Completed open of project file : '%1'" ). arg ( projectFileName ));
2017-02-23 14:24:18 +01:00
2013-10-08 14:28:01 +02:00
return true ;
}
2013-12-04 12:04:42 +01:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RiaApplication :: loadProject ( const QString & projectFileName )
{
return loadProject ( projectFileName , PLA_NONE , NULL );
}
2016-10-05 10:04:41 +02:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiaApplication :: loadAndUpdatePlotData ()
{
RimWellLogPlotCollection * wlpColl = nullptr ;
RimSummaryPlotCollection * spColl = nullptr ;
2017-01-13 13:32:02 +01:00
RimFlowPlotCollection * flowColl = nullptr ;
2016-10-05 10:04:41 +02:00
if ( m_project -> mainPlotCollection () && m_project -> mainPlotCollection () -> wellLogPlotCollection ())
{
wlpColl = m_project -> mainPlotCollection () -> wellLogPlotCollection ();
}
if ( m_project -> mainPlotCollection () && m_project -> mainPlotCollection () -> summaryPlotCollection ())
{
spColl = m_project -> mainPlotCollection () -> summaryPlotCollection ();
}
2017-01-13 13:32:02 +01:00
if ( m_project -> mainPlotCollection () && m_project -> mainPlotCollection () -> flowPlotCollection ())
{
flowColl = m_project -> mainPlotCollection () -> flowPlotCollection ();
}
2016-10-05 10:04:41 +02:00
size_t plotCount = 0 ;
plotCount += wlpColl ? wlpColl -> wellLogPlots (). size () : 0 ;
2017-01-13 09:51:37 +01:00
plotCount += spColl ? spColl -> summaryPlots (). size () : 0 ;
2017-02-13 14:49:52 +01:00
plotCount += flowColl ? flowColl -> plotCount () : 0 ;
2016-10-05 10:04:41 +02:00
caf :: ProgressInfo plotProgress ( plotCount , "Loading Plot Data" );
if ( wlpColl )
{
for ( size_t wlpIdx = 0 ; wlpIdx < wlpColl -> wellLogPlots (). size (); ++ wlpIdx )
{
wlpColl -> wellLogPlots [ wlpIdx ] -> loadDataAndUpdate ();
plotProgress . incrementProgress ();
}
}
if ( spColl )
{
2017-01-13 09:51:37 +01:00
for ( size_t wlpIdx = 0 ; wlpIdx < spColl -> summaryPlots (). size (); ++ wlpIdx )
2016-10-05 10:04:41 +02:00
{
2017-01-13 09:51:37 +01:00
spColl -> summaryPlots [ wlpIdx ] -> loadDataAndUpdate ();
2016-10-05 10:04:41 +02:00
plotProgress . incrementProgress ();
}
}
2017-02-13 14:49:52 +01:00
2017-01-13 13:32:02 +01:00
if ( flowColl )
{
2017-02-24 16:00:56 +01:00
plotProgress . setNextProgressIncrement ( flowColl -> plotCount ());
2017-03-07 12:19:54 +01:00
flowColl -> loadDataAndUpdate ();
plotProgress . incrementProgress ();
2017-01-13 13:32:02 +01:00
}
2016-10-05 10:04:41 +02:00
}
2013-12-04 12:04:42 +01:00
2017-04-20 11:02:05 +02:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiaApplication :: storeTreeViewState ()
{
{
if ( mainPlotWindow () && mainPlotWindow () -> projectTreeView ())
{
caf :: PdmUiTreeView * projectTreeView = mainPlotWindow () -> projectTreeView ();
QString treeViewState ;
RimTreeViewStateSerializer :: storeTreeViewStateToString ( projectTreeView -> treeView (), treeViewState );
QModelIndex mi = projectTreeView -> treeView () -> currentIndex ();
QString encodedModelIndexString ;
RimTreeViewStateSerializer :: encodeStringFromModelIndex ( mi , encodedModelIndexString );
project () -> plotWindowTreeViewState = treeViewState ;
project () -> plotWindowCurrentModelIndexPath = encodedModelIndexString ;
}
}
{
caf :: PdmUiTreeView * projectTreeView = RiuMainWindow :: instance () -> projectTreeView ();
if ( projectTreeView )
{
QString treeViewState ;
RimTreeViewStateSerializer :: storeTreeViewStateToString ( projectTreeView -> treeView (), treeViewState );
QModelIndex mi = projectTreeView -> treeView () -> currentIndex ();
QString encodedModelIndexString ;
RimTreeViewStateSerializer :: encodeStringFromModelIndex ( mi , encodedModelIndexString );
project () -> mainWindowTreeViewState = treeViewState ;
project () -> mainWindowCurrentModelIndexPath = encodedModelIndexString ;
}
}
}
2013-10-08 14:28:01 +02:00
//--------------------------------------------------------------------------------------------------
/// Add a list of well path file paths (JSON files) to the well path collection
//--------------------------------------------------------------------------------------------------
void RiaApplication :: addWellPathsToModel ( QList < QString > wellPathFilePaths )
{
if ( m_project == NULL || m_project -> oilFields . size () < 1 ) return ;
RimOilField * oilField = m_project -> activeOilField ();
if ( oilField == NULL ) return ;
if ( oilField -> wellPathCollection == NULL )
{
//printf("Create well path collection.\n");
oilField -> wellPathCollection = new RimWellPathCollection ();
2015-08-12 17:46:22 +02:00
m_project -> updateConnectedEditors ();
2013-10-08 14:28:01 +02:00
}
if ( oilField -> wellPathCollection ) oilField -> wellPathCollection -> addWellPaths ( wellPathFilePaths );
2015-08-12 17:46:22 +02:00
oilField -> wellPathCollection -> updateConnectedEditors ();
2013-10-08 14:28:01 +02:00
}
2015-09-14 16:33:28 +02:00
//--------------------------------------------------------------------------------------------------
/// Add a list of well log file paths (LAS files) to the well path collection
//--------------------------------------------------------------------------------------------------
void RiaApplication :: addWellLogsToModel ( const QList < QString >& wellLogFilePaths )
{
if ( m_project == NULL || m_project -> oilFields . size () < 1 ) return ;
RimOilField * oilField = m_project -> activeOilField ();
if ( oilField == NULL ) return ;
if ( oilField -> wellPathCollection == NULL )
{
oilField -> wellPathCollection = new RimWellPathCollection ();
m_project -> updateConnectedEditors ();
}
if ( oilField -> wellPathCollection ) oilField -> wellPathCollection -> addWellLogs ( wellLogFilePaths );
oilField -> wellPathCollection -> updateConnectedEditors ();
}
2013-10-08 14:28:01 +02:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RiaApplication :: saveProject ()
{
CVF_ASSERT ( m_project . notNull ());
2017-05-11 09:23:13 +02:00
if ( ! caf :: Utils :: fileExists ( m_project -> fileName ()))
2013-10-08 14:28:01 +02:00
{
return saveProjectPromptForFileName ();
}
else
{
return saveProjectAs ( m_project -> fileName ());
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RiaApplication :: saveProjectPromptForFileName ()
{
//if (m_project.isNull()) return true;
RiaApplication * app = RiaApplication :: instance ();
QString startPath ;
if ( ! m_project -> fileName (). isEmpty ())
{
2015-09-18 18:48:29 +02:00
startPath = m_project -> fileName ();
2013-10-08 14:28:01 +02:00
}
else
{
2016-09-21 09:46:17 +02:00
startPath = app -> lastUsedDialogDirectory ( "BINARY_GRID" );
2015-09-18 18:48:29 +02:00
startPath += "/ResInsightProject.rsp" ;
2013-10-08 14:28:01 +02:00
}
QString fileName = QFileDialog :: getSaveFileName ( NULL , tr ( "Save File" ), startPath , tr ( "Project Files (*.rsp);;All files(*.*)" ));
if ( fileName . isEmpty ())
{
return false ;
}
// Remember the directory to next time
2016-09-21 09:46:17 +02:00
app -> setLastUsedDialogDirectory ( "BINARY_GRID" , QFileInfo ( fileName ). absolutePath ());
2013-10-08 14:28:01 +02:00
bool bSaveOk = saveProjectAs ( fileName );
setWindowCaptionFromAppState ();
return bSaveOk ;
}
2017-04-20 08:07:47 +02:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RiaApplication :: hasValidProjectFileExtension ( const QString & fileName )
{
if ( fileName . contains ( ".rsp" , Qt :: CaseInsensitive ) || fileName . contains ( ".rip" , Qt :: CaseInsensitive ))
{
return true ;
}
return false ;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RiaApplication :: askUserToSaveModifiedProject ()
{
if ( caf :: PdmUiModelChangeDetector :: instance () -> isModelChanged ())
{
QMessageBox msgBox ;
msgBox . setIcon ( QMessageBox :: Question );
QString questionText ;
questionText = QString ( "The current project is modified. \n\n Do you want to save the changes?" );
msgBox . setText ( questionText );
msgBox . setStandardButtons ( QMessageBox :: Yes | QMessageBox :: No | QMessageBox :: Cancel );
int ret = msgBox . exec ();
if ( ret == QMessageBox :: Cancel )
{
return false ;
}
else if ( ret == QMessageBox :: Yes )
{
if ( ! saveProject ())
{
return false ;
}
}
else
{
caf :: PdmUiModelChangeDetector :: instance () -> reset ();
}
}
return true ;
}
2013-10-08 14:28:01 +02:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RiaApplication :: saveProjectAs ( const QString & fileName )
{
m_project -> fileName = fileName ;
2015-11-20 10:50:23 +01:00
2017-04-20 11:02:05 +02:00
storeTreeViewState ();
2015-11-20 10:50:23 +01:00
if ( ! m_project -> writeFile ())
{
QMessageBox :: warning ( NULL , "Error when saving project file" , QString ( "Not possible to save project file. Make sure you have sufficient access rights. \n\n Project file location : %1" ). arg ( fileName ));
return false ;
}
2013-10-08 14:28:01 +02:00
m_preferences -> lastUsedProjectFileName = fileName ;
2015-10-23 15:46:25 +02:00
caf :: PdmSettings :: writeFieldsToApplicationStore ( m_preferences );
2013-10-08 14:28:01 +02:00
2016-10-05 08:23:07 +02:00
m_recentFileActionProvider -> addFileName ( fileName );
2015-11-20 10:50:23 +01:00
2017-04-20 08:07:47 +02:00
caf :: PdmUiModelChangeDetector :: instance () -> reset ();
2013-10-08 14:28:01 +02:00
return true ;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
2016-10-04 11:02:56 +02:00
void RiaApplication :: closeProject ()
2013-10-08 14:28:01 +02:00
{
RiuMainWindow * mainWnd = RiuMainWindow :: instance ();
2015-10-23 14:13:14 +02:00
clearViewsScheduledForUpdate ();
2013-10-08 14:28:01 +02:00
terminateProcess ();
2015-11-09 19:05:00 +01:00
RiuSelectionManager :: instance () -> deleteAllItems ();
2013-10-08 14:28:01 +02:00
mainWnd -> cleanupGuiBeforeProjectClose ();
2016-06-27 11:07:01 +02:00
if ( m_mainPlotWindow )
{
m_mainPlotWindow -> cleanupGuiBeforeProjectClose ();
}
2016-06-24 15:10:18 +02:00
2013-10-08 14:28:01 +02:00
caf :: EffectGenerator :: clearEffectCache ();
m_project -> close ();
m_commandQueue . clear ();
onProjectOpenedOrClosed ();
2015-10-28 15:30:20 +01:00
// Make sure all project windows are closed down properly before returning
processEvents ();
2013-10-08 14:28:01 +02:00
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiaApplication :: onProjectOpenedOrClosed ()
{
RiuMainWindow * mainWnd = RiuMainWindow :: instance ();
2016-06-24 15:53:04 +02:00
if ( mainWnd )
{
mainWnd -> initializeGuiNewProjectLoaded ();
}
2016-06-27 11:07:01 +02:00
if ( m_mainPlotWindow )
2016-06-24 15:53:04 +02:00
{
2016-06-27 11:07:01 +02:00
m_mainPlotWindow -> initializeGuiNewProjectLoaded ();
2016-06-24 15:53:04 +02:00
}
2013-10-08 14:28:01 +02:00
setWindowCaptionFromAppState ();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
2016-09-21 09:46:17 +02:00
QString RiaApplication :: currentProjectPath () const
2013-10-08 14:28:01 +02:00
{
2016-09-21 09:46:17 +02:00
QString projectFolder ;
if ( m_project )
{
QString projectFileName = m_project -> fileName ();
2013-10-08 14:28:01 +02:00
2016-09-21 09:46:17 +02:00
if ( ! projectFileName . isEmpty ())
{
QFileInfo fi ( projectFileName );
projectFolder = fi . absolutePath ();
}
}
2013-10-08 14:28:01 +02:00
2016-09-21 09:46:17 +02:00
return projectFolder ;
}
2013-12-04 12:04:42 +01:00
//--------------------------------------------------------------------------------------------------
/// Create an absolute path from a path that is specified relative to the project directory
///
/// If the path specified in \a projectRelativePath is already absolute, no changes will be made
//--------------------------------------------------------------------------------------------------
QString RiaApplication :: createAbsolutePathFromProjectRelativePath ( QString projectRelativePath )
{
// Check if path is already absolute
if ( QDir :: isAbsolutePath ( projectRelativePath ))
{
return projectRelativePath ;
}
2017-02-14 14:59:08 +01:00
QString absolutePath ;
2013-12-04 12:04:42 +01:00
if ( m_project && ! m_project -> fileName (). isEmpty ())
{
2017-02-14 14:59:08 +01:00
absolutePath = QFileInfo ( m_project -> fileName ()). absolutePath ();
2013-12-04 12:04:42 +01:00
}
else
{
2017-02-14 14:59:08 +01:00
absolutePath = this -> lastUsedDialogDirectory ( "BINARY_GRID" );
2013-12-04 12:04:42 +01:00
}
2017-02-14 14:59:08 +01:00
QDir projectDir ( absolutePath );
return projectDir . absoluteFilePath ( projectRelativePath );
2013-12-04 12:04:42 +01:00
}
2013-10-08 14:28:01 +02:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RiaApplication :: openEclipseCaseFromFile ( const QString & fileName )
{
2017-05-11 09:23:13 +02:00
if ( ! caf :: Utils :: fileExists ( fileName )) return false ;
2013-10-08 14:28:01 +02:00
QFileInfo gridFileName ( fileName );
QString caseName = gridFileName . completeBaseName ();
return openEclipseCase ( caseName , fileName );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RiaApplication :: openEclipseCase ( const QString & caseName , const QString & caseFileName )
{
2015-06-25 11:56:18 +02:00
RimEclipseResultCase * rimResultReservoir = new RimEclipseResultCase ();
2013-10-08 14:28:01 +02:00
rimResultReservoir -> setCaseInfo ( caseName , caseFileName );
2015-06-25 12:11:06 +02:00
RimEclipseCaseCollection * analysisModels = m_project -> activeOilField () ? m_project -> activeOilField () -> analysisModels () : NULL ;
2013-10-08 14:28:01 +02:00
if ( analysisModels == NULL ) return false ;
2016-10-24 16:01:19 +02:00
RiuMainWindow :: instance () -> show ();
2013-10-08 14:28:01 +02:00
analysisModels -> cases . push_back ( rimResultReservoir );
2015-05-21 10:05:33 +02:00
RimEclipseView * riv = rimResultReservoir -> createAndAddReservoirView ();
2013-10-08 14:28:01 +02:00
// Select SOIL as default result variable
2017-06-13 15:41:52 +02:00
riv -> cellResult () -> setResultType ( RiaDefines :: DYNAMIC_NATIVE );
2014-10-24 11:38:47 +02:00
if ( m_preferences -> loadAndShowSoil )
{
riv -> cellResult () -> setResultVariable ( "SOIL" );
}
2015-06-09 16:18:11 +02:00
riv -> hasUserRequestedAnimation = true ;
2013-10-08 14:28:01 +02:00
riv -> loadDataAndUpdate ();
2016-05-31 13:42:27 +02:00
// Add a corresponding summary case if it exists
{
RimSummaryCaseCollection * sumCaseColl = m_project -> activeOilField () ? m_project -> activeOilField () -> summaryCaseCollection () : NULL ;
if ( sumCaseColl )
{
2016-10-24 16:01:19 +02:00
if ( sumCaseColl -> summaryCaseCount () == 0 && m_mainPlotWindow )
{
m_mainPlotWindow -> hide ();
}
2016-11-07 15:57:21 +01:00
if ( ! sumCaseColl -> findSummaryCaseFromEclipseResultCase ( rimResultReservoir ))
2016-06-30 13:21:04 +02:00
{
2016-11-07 15:57:21 +01:00
RimSummaryCase * newSumCase = sumCaseColl -> createAndAddSummaryCaseFromEclipseResultCase ( rimResultReservoir );
2016-06-30 13:21:04 +02:00
2016-11-07 15:57:21 +01:00
if ( newSumCase )
2016-10-24 13:54:35 +02:00
{
2016-11-07 15:57:21 +01:00
newSumCase -> loadCase ();
RimSummaryCase * existingFileSummaryCase = sumCaseColl -> findSummaryCaseFromFileName ( newSumCase -> summaryHeaderFilename ());
if ( existingFileSummaryCase )
{
// Replace all occurrences of file sum with ecl sum
std :: vector < caf :: PdmObjectHandle *> referringObjects ;
existingFileSummaryCase -> objectsWithReferringPtrFields ( referringObjects );
std :: set < RimSummaryCurveFilter *> curveFilters ;
for ( caf :: PdmObjectHandle * objHandle : referringObjects )
{
RimSummaryCurve * summaryCurve = dynamic_cast < RimSummaryCurve *> ( objHandle );
if ( summaryCurve )
{
summaryCurve -> setSummaryCase ( newSumCase );
summaryCurve -> updateConnectedEditors ();
RimSummaryCurveFilter * parentFilter = nullptr ;
summaryCurve -> firstAncestorOrThisOfType ( parentFilter );
if ( parentFilter )
{
curveFilters . insert ( parentFilter );
}
}
}
// UI settings of a curve filter is updated based
// on the new case association for the curves in the curve filter
// UI is updated by loadDataAndUpdate()
for ( RimSummaryCurveFilter * curveFilter : curveFilters )
{
curveFilter -> loadDataAndUpdate ();
curveFilter -> updateConnectedEditors ();
}
sumCaseColl -> deleteCase ( existingFileSummaryCase );
delete existingFileSummaryCase ;
}
else
{
if ( m_preferences -> autoCreatePlotsOnImport ())
{
RimMainPlotCollection * mainPlotColl = m_project -> mainPlotCollection ();
RimSummaryPlotCollection * summaryPlotColl = mainPlotColl -> summaryPlotCollection ();
2016-06-30 13:21:04 +02:00
2016-11-07 15:57:21 +01:00
RicNewSummaryPlotFeature :: createNewSummaryPlot ( summaryPlotColl , newSumCase );
}
}
2016-07-01 09:20:20 +02:00
2016-11-07 15:57:21 +01:00
sumCaseColl -> updateConnectedEditors ();
}
2016-06-30 13:21:04 +02:00
}
2016-05-31 13:42:27 +02:00
}
}
2013-10-08 14:28:01 +02:00
if ( ! riv -> cellResult () -> hasResult ())
{
2017-06-13 15:41:52 +02:00
riv -> cellResult () -> setResultVariable ( RiaDefines :: undefinedResultName ());
2013-10-08 14:28:01 +02:00
}
2016-05-31 13:42:27 +02:00
2015-08-13 21:28:09 +02:00
analysisModels -> updateConnectedEditors ();
2013-10-08 14:28:01 +02:00
2015-12-07 10:07:51 +01:00
RiuMainWindow :: instance () -> selectAsCurrentItem ( riv -> cellResult ());
2013-10-08 14:28:01 +02:00
2015-08-10 18:22:54 +02:00
2013-10-08 14:28:01 +02:00
return true ;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RiaApplication :: openInputEclipseCaseFromFileNames ( const QStringList & fileNames )
{
2015-06-25 11:50:13 +02:00
RimEclipseInputCase * rimInputReservoir = new RimEclipseInputCase ();
2013-10-08 14:28:01 +02:00
m_project -> assignCaseIdToCase ( rimInputReservoir );
rimInputReservoir -> openDataFileSet ( fileNames );
2015-06-25 12:11:06 +02:00
RimEclipseCaseCollection * analysisModels = m_project -> activeOilField () ? m_project -> activeOilField () -> analysisModels () : NULL ;
2013-10-08 14:28:01 +02:00
if ( analysisModels == NULL ) return false ;
analysisModels -> cases . push_back ( rimInputReservoir );
2015-05-21 10:05:33 +02:00
RimEclipseView * riv = rimInputReservoir -> createAndAddReservoirView ();
2013-10-08 14:28:01 +02:00
2017-06-13 15:41:52 +02:00
riv -> cellResult () -> setResultType ( RiaDefines :: INPUT_PROPERTY );
2015-06-09 16:18:11 +02:00
riv -> hasUserRequestedAnimation = true ;
2013-10-08 14:28:01 +02:00
riv -> loadDataAndUpdate ();
if ( ! riv -> cellResult () -> hasResult ())
{
2017-06-13 15:41:52 +02:00
riv -> cellResult () -> setResultVariable ( RiaDefines :: undefinedResultName ());
2013-10-08 14:28:01 +02:00
}
2015-08-13 21:28:09 +02:00
analysisModels -> updateConnectedEditors ();
2013-10-08 14:28:01 +02:00
2015-12-07 10:07:51 +01:00
RiuMainWindow :: instance () -> selectAsCurrentItem ( riv -> cellResult ());
2013-10-08 14:28:01 +02:00
2016-11-28 07:25:04 +01:00
if ( fileNames . size () == 1 )
{
addToRecentFiles ( fileNames [ 0 ]);
}
2013-10-08 14:28:01 +02:00
return true ;
}
2015-04-20 09:02:33 +02:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RiaApplication :: openOdbCaseFromFile ( const QString & fileName )
{
2017-05-11 09:23:13 +02:00
if ( ! caf :: Utils :: fileExists ( fileName )) return false ;
2015-04-20 09:02:33 +02:00
QFileInfo gridFileName ( fileName );
QString caseName = gridFileName . completeBaseName ();
RimGeoMechCase * geoMechCase = new RimGeoMechCase ();
2015-04-25 08:57:34 +02:00
geoMechCase -> setFileName ( fileName );
2015-04-20 09:02:33 +02:00
geoMechCase -> caseUserDescription = caseName ;
RimGeoMechModels * geoMechModelCollection = m_project -> activeOilField () ? m_project -> activeOilField () -> geoMechModels () : NULL ;
// Create the geoMech model container if it is not there already
if ( geoMechModelCollection == NULL )
{
geoMechModelCollection = new RimGeoMechModels ();
m_project -> activeOilField () -> geoMechModels = geoMechModelCollection ;
}
geoMechModelCollection -> cases . push_back ( geoMechCase );
RimGeoMechView * riv = geoMechCase -> createAndAddReservoirView ();
2015-05-29 12:14:40 +02:00
caf :: ProgressInfo progress ( 11 , "Loading Case" );
progress . setNextProgressIncrement ( 10 );
2015-04-20 09:02:33 +02:00
2015-04-20 16:56:26 +02:00
riv -> loadDataAndUpdate ();
2015-04-20 09:02:33 +02:00
//if (!riv->cellResult()->hasResult())
//{
// riv->cellResult()->setResultVariable(RimDefines::undefinedResultName());
//}
2015-05-29 12:14:40 +02:00
progress . incrementProgress ();
progress . setProgressDescription ( "Loading results information" );
2015-04-20 09:02:33 +02:00
2015-08-13 21:28:09 +02:00
m_project -> updateConnectedEditors ();
2015-04-20 09:02:33 +02:00
2015-12-07 10:07:51 +01:00
RiuMainWindow :: instance () -> selectAsCurrentItem ( riv -> cellResult ());
2015-05-29 12:14:40 +02:00
2015-04-20 09:02:33 +02:00
return true ;
}
2013-10-08 14:28:01 +02:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiaApplication :: createMockModel ()
{
2017-06-13 15:41:52 +02:00
openEclipseCase ( RiaDefines :: mockModelBasic (), RiaDefines :: mockModelBasic ());
2013-10-08 14:28:01 +02:00
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiaApplication :: createResultsMockModel ()
{
2017-06-13 15:41:52 +02:00
openEclipseCase ( RiaDefines :: mockModelBasicWithResults (), RiaDefines :: mockModelBasicWithResults ());
2013-10-08 14:28:01 +02:00
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiaApplication :: createLargeResultsMockModel ()
{
2017-06-13 15:41:52 +02:00
openEclipseCase ( RiaDefines :: mockModelLargeWithResults (), RiaDefines :: mockModelLargeWithResults ());
2013-10-08 14:28:01 +02:00
}
2013-10-28 10:32:24 +01:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiaApplication :: createMockModelCustomized ()
{
2017-06-13 15:41:52 +02:00
openEclipseCase ( RiaDefines :: mockModelCustomized (), RiaDefines :: mockModelCustomized ());
2013-10-28 10:32:24 +01:00
}
2013-10-08 14:28:01 +02:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiaApplication :: createInputMockModel ()
{
2017-06-13 15:41:52 +02:00
openInputEclipseCaseFromFileNames ( QStringList ( RiaDefines :: mockModelBasicInputCase ()));
2013-10-08 14:28:01 +02:00
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
2015-05-08 14:13:26 +02:00
const RimView * RiaApplication :: activeReservoirView () const
2013-10-08 14:28:01 +02:00
{
return m_activeReservoirView ;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
2015-05-08 14:13:26 +02:00
RimView * RiaApplication :: activeReservoirView ()
2013-10-08 14:28:01 +02:00
{
return m_activeReservoirView ;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
2017-03-31 15:10:39 +02:00
RimViewWindow * RiaApplication :: activePlotWindow () const
2013-10-08 14:28:01 +02:00
{
2017-03-31 15:10:39 +02:00
RimViewWindow * viewWindow = nullptr ;
2013-10-08 14:28:01 +02:00
2017-03-31 15:10:39 +02:00
if ( m_mainPlotWindow )
{
QList < QMdiSubWindow *> subwindows = m_mainPlotWindow -> subWindowList ( QMdiArea :: StackingOrder );
if ( subwindows . size () > 0 )
{
viewWindow = RiuInterfaceToViewWindow :: viewWindowFromWidget ( subwindows . back () -> widget ());
}
}
2016-06-28 10:58:22 +02:00
2017-03-31 15:10:39 +02:00
return viewWindow ;
2017-01-13 13:32:02 +01:00
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
2017-03-31 15:10:39 +02:00
void RiaApplication :: setActiveReservoirView ( RimView * rv )
2017-01-13 13:32:02 +01:00
{
2017-03-31 15:10:39 +02:00
m_activeReservoirView = rv ;
2017-01-13 13:32:02 +01:00
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
2013-10-08 14:28:01 +02:00
void RiaApplication :: setUseShaders ( bool enable )
{
m_preferences -> useShaders = enable ;
2015-10-23 15:46:25 +02:00
caf :: PdmSettings :: writeFieldsToApplicationStore ( m_preferences );
2013-10-08 14:28:01 +02:00
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RiaApplication :: useShaders () const
{
if ( ! m_preferences -> useShaders ) return false ;
bool isShadersSupported = caf :: Viewer :: isShadersSupported ();
if ( ! isShadersSupported ) return false ;
return true ;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RiaApplication :: RINavigationPolicy RiaApplication :: navigationPolicy () const
{
return m_preferences -> navigationPolicy ();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiaApplication :: setShowPerformanceInfo ( bool enable )
{
m_preferences -> showHud = enable ;
2015-10-23 15:46:25 +02:00
caf :: PdmSettings :: writeFieldsToApplicationStore ( m_preferences );
2013-10-08 14:28:01 +02:00
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RiaApplication :: showPerformanceInfo () const
{
return m_preferences -> showHud ;
}
2013-12-04 12:04:42 +01:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RiaApplication :: parseArguments ()
{
cvf :: ProgramOptions progOpt ;
2013-12-19 10:06:56 +01:00
progOpt . registerOption ( "last" , "" , "Open last used project." );
progOpt . registerOption ( "project" , "<filename>" , "Open project file <filename>." , cvf :: ProgramOptions :: SINGLE_VALUE );
progOpt . registerOption ( "case" , "<casename>" , "Import Eclipse case <casename> (do not include the .GRID/.EGRID extension.)" , cvf :: ProgramOptions :: MULTI_VALUE );
progOpt . registerOption ( "startdir" , "<folder>" , "Set startup directory." , cvf :: ProgramOptions :: SINGLE_VALUE );
2016-11-09 12:22:07 +01:00
progOpt . registerOption ( "savesnapshots" , "all|views|plots" , "Save snapshot of all views or plots to project file location sub folder 'snapshots'. Option 'all' will include both views and plots. Application closes after snapshots have been written." , cvf :: ProgramOptions :: OPTIONAL_MULTI_VALUE );
2013-12-19 10:06:56 +01:00
progOpt . registerOption ( "size" , "<width> <height>" , "Set size of the main application window." , cvf :: ProgramOptions :: MULTI_VALUE );
2016-11-28 09:03:36 +01:00
progOpt . registerOption ( "replaceCase" , "[<caseId>] <newGridFile>" , "Replace grid in <caseId> or first case with <newgridFile>. Repeat parameter for multiple replace operations." , cvf :: ProgramOptions :: MULTI_VALUE , cvf :: ProgramOptions :: COMBINE_REPEATED );
progOpt . registerOption ( "replaceSourceCases" , "[<caseGroupId>] <gridListFile>" , "Replace source cases in <caseGroupId> or first grid case group with the grid files listed in the <gridListFile> file. Repeat parameter for multiple replace operations." , cvf :: ProgramOptions :: MULTI_VALUE , cvf :: ProgramOptions :: COMBINE_REPEATED );
2017-06-28 20:10:06 +02:00
progOpt . registerOption ( "replacePropertiesFolder" , "[<caseId>] <newPropertiesFolder>" , "Replace the folder containing property files for an eclipse input case." , cvf :: ProgramOptions :: MULTI_VALUE );
2013-12-19 10:06:56 +01:00
progOpt . registerOption ( "multiCaseSnapshots" , "<gridListFile>" , "For each grid file listed in the <gridListFile> file, replace the first case in the project and save snapshot of all views." , cvf :: ProgramOptions :: SINGLE_VALUE );
2017-07-26 16:41:17 +02:00
progOpt . registerOption ( "commandFile" , "<commandfile>" , "Execute the command file." , cvf :: ProgramOptions :: SINGLE_VALUE );
2013-12-19 10:06:56 +01:00
progOpt . registerOption ( "help" , "" , "Displays help text." );
progOpt . registerOption ( "?" , "" , "Displays help text." );
2016-11-28 08:59:20 +01:00
progOpt . registerOption ( "regressiontest" , "<folder>" , "System command" , cvf :: ProgramOptions :: SINGLE_VALUE );
progOpt . registerOption ( "updateregressiontestbase" , "<folder>" , "System command" , cvf :: ProgramOptions :: SINGLE_VALUE );
progOpt . registerOption ( "unittest" , "" , "System command" );
2013-12-04 12:04:42 +01:00
progOpt . setOptionPrefix ( cvf :: ProgramOptions :: DOUBLE_DASH );
2013-12-19 10:45:15 +01:00
m_helpText = QString ( " \n %1 v. %2 \n " ). arg ( RI_APPLICATION_NAME ). arg ( getVersionStringApp ( false ));
2014-09-24 07:21:26 +02:00
m_helpText += "Copyright Statoil ASA, Ceetron Solution AS, Ceetron AS \n\n " ;
2013-12-19 10:45:15 +01:00
const cvf :: String usageText = progOpt . usageText ( 110 , 30 );
m_helpText += cvfqt :: Utils :: toQString ( usageText );
2013-12-04 12:04:42 +01:00
QStringList arguments = QCoreApplication :: arguments ();
bool parseOk = progOpt . parse ( cvfqt :: Utils :: toStringVector ( arguments ));
2014-06-05 07:34:34 +02:00
// If positional parameter functionality is to be supported, the test for existence of positionalParameters must be removed
// This is based on a pull request by @andlaus https://github.com/OPM/ResInsight/pull/162
if ( ! parseOk ||
progOpt . hasOption ( "help" ) ||
progOpt . hasOption ( "?" ) ||
progOpt . positionalParameters (). size () > 0 )
2013-12-04 12:04:42 +01:00
{
#if defined(_MSC_VER) && defined(_WIN32)
2013-12-19 10:45:15 +01:00
showFormattedTextInMessageBox ( m_helpText );
2013-12-04 12:04:42 +01:00
#else
2013-12-19 11:06:59 +01:00
fprintf ( stdout , "%s \n " , m_helpText . toAscii (). data ());
2013-12-04 12:04:42 +01:00
fflush ( stdout );
#endif
return false ;
}
// Handling of the actual command line options
// --------------------------------------------------------
2013-12-04 14:56:04 +01:00
if ( cvf :: Option o = progOpt . option ( "regressiontest" ))
2013-12-04 12:04:42 +01:00
{
2013-12-04 14:56:04 +01:00
CVF_ASSERT ( o . valueCount () == 1 );
QString regressionTestPath = cvfqt :: Utils :: toQString ( o . value ( 0 ));
2013-12-04 12:04:42 +01:00
executeRegressionTests ( regressionTestPath );
return false ;
}
2013-12-04 14:56:04 +01:00
if ( cvf :: Option o = progOpt . option ( "updateregressiontestbase" ))
2013-12-04 12:04:42 +01:00
{
2013-12-04 14:56:04 +01:00
CVF_ASSERT ( o . valueCount () == 1 );
QString regressionTestPath = cvfqt :: Utils :: toQString ( o . value ( 0 ));
2013-12-04 12:04:42 +01:00
updateRegressionTest ( regressionTestPath );
return false ;
}
2013-12-04 14:56:04 +01:00
if ( cvf :: Option o = progOpt . option ( "startdir" ))
2013-12-04 12:04:42 +01:00
{
2013-12-04 14:56:04 +01:00
CVF_ASSERT ( o . valueCount () == 1 );
m_startupDefaultDirectory = cvfqt :: Utils :: toQString ( o . value ( 0 ));
2013-12-04 12:04:42 +01:00
}
2013-12-04 14:56:04 +01:00
if ( cvf :: Option o = progOpt . option ( "size" ))
2013-12-04 12:04:42 +01:00
{
RiuMainWindow * mainWnd = RiuMainWindow :: instance ();
2013-12-04 14:56:04 +01:00
int width = o . safeValue ( 0 ). toInt ( - 1 );
int height = o . safeValue ( 1 ). toInt ( - 1 );
2013-12-04 12:04:42 +01:00
if ( mainWnd && width > 0 && height > 0 )
{
mainWnd -> resize ( width , height );
}
}
QString projectFileName ;
if ( progOpt . hasOption ( "last" ))
{
projectFileName = m_preferences -> lastUsedProjectFileName ;
}
2013-12-04 14:56:04 +01:00
if ( cvf :: Option o = progOpt . option ( "project" ))
2013-12-04 12:04:42 +01:00
{
2013-12-04 14:56:04 +01:00
CVF_ASSERT ( o . valueCount () == 1 );
projectFileName = cvfqt :: Utils :: toQString ( o . value ( 0 ));
2013-12-04 12:04:42 +01:00
}
2013-12-04 14:56:04 +01:00
if ( ! projectFileName . isEmpty ())
2013-12-04 12:04:42 +01:00
{
2013-12-04 14:56:04 +01:00
if ( cvf :: Option o = progOpt . option ( "multiCaseSnapshots" ))
{
QString gridListFile = cvfqt :: Utils :: toQString ( o . safeValue ( 0 ));
std :: vector < QString > gridFiles = readFileListFromTextFile ( gridListFile );
runMultiCaseSnapshots ( projectFileName , gridFiles , "multiCaseSnapshots" );
2016-07-15 10:55:20 +02:00
2017-05-04 14:28:32 +02:00
closeAllWindows ();
processEvents ();
2016-07-15 10:55:20 +02:00
2013-12-04 14:56:04 +01:00
return false ;
}
2013-12-04 12:04:42 +01:00
}
if ( ! projectFileName . isEmpty ())
{
cvf :: ref < RiaProjectModifier > projectModifier ;
ProjectLoadAction projectLoadAction = PLA_NONE ;
2013-12-04 14:56:04 +01:00
if ( cvf :: Option o = progOpt . option ( "replaceCase" ))
2013-12-04 12:04:42 +01:00
{
if ( projectModifier . isNull ()) projectModifier = new RiaProjectModifier ;
2016-11-25 14:21:40 +01:00
if ( o . valueCount () == 1 )
2013-12-04 12:04:42 +01:00
{
2016-11-25 14:21:40 +01:00
// One argument is available, use replace case for first occurrence in the project
QString gridFileName = cvfqt :: Utils :: toQString ( o . safeValue ( 0 ));
projectModifier -> setReplaceCaseFirstOccurrence ( gridFileName );
2013-12-04 12:04:42 +01:00
}
else
{
2016-11-25 14:21:40 +01:00
size_t optionIdx = 0 ;
while ( optionIdx < o . valueCount ())
{
const int caseId = o . safeValue ( optionIdx ++ ). toInt ( - 1 );
QString gridFileName = cvfqt :: Utils :: toQString ( o . safeValue ( optionIdx ++ ));
if ( caseId != - 1 && ! gridFileName . isEmpty ())
{
projectModifier -> setReplaceCase ( caseId , gridFileName );
}
}
2013-12-04 12:04:42 +01:00
}
}
2013-12-04 14:56:04 +01:00
if ( cvf :: Option o = progOpt . option ( "replaceSourceCases" ))
2013-12-04 12:04:42 +01:00
{
if ( projectModifier . isNull ()) projectModifier = new RiaProjectModifier ;
2016-11-25 14:21:40 +01:00
if ( o . valueCount () == 1 )
2013-12-04 12:04:42 +01:00
{
2016-11-25 14:21:40 +01:00
// One argument is available, use replace case for first occurrence in the project
std :: vector < QString > gridFileNames = readFileListFromTextFile ( cvfqt :: Utils :: toQString ( o . safeValue ( 0 )));
projectModifier -> setReplaceSourceCasesFirstOccurrence ( gridFileNames );
2013-12-04 12:04:42 +01:00
}
else
{
2016-11-25 14:21:40 +01:00
size_t optionIdx = 0 ;
while ( optionIdx < o . valueCount ())
{
const int groupId = o . safeValue ( optionIdx ++ ). toInt ( - 1 );
std :: vector < QString > gridFileNames = readFileListFromTextFile ( cvfqt :: Utils :: toQString ( o . safeValue ( optionIdx ++ )));
if ( groupId != - 1 && gridFileNames . size () > 0 )
{
projectModifier -> setReplaceSourceCasesById ( groupId , gridFileNames );
}
}
2013-12-04 12:04:42 +01:00
}
projectLoadAction = PLA_CALCULATE_STATISTICS ;
}
2017-06-28 20:10:06 +02:00
if ( cvf :: Option o = progOpt . option ( "replacePropertiesFolder" ))
{
if ( projectModifier . isNull ()) projectModifier = new RiaProjectModifier ;
if ( o . valueCount () == 1 )
{
QString propertiesFolder = cvfqt :: Utils :: toQString ( o . safeValue ( 0 ));
projectModifier -> setReplacePropertiesFolderFirstOccurrence ( propertiesFolder );
}
else
{
size_t optionIdx = 0 ;
while ( optionIdx < o . valueCount ())
{
const int caseId = o . safeValue ( optionIdx ++ ). toInt ( - 1 );
QString propertiesFolder = cvfqt :: Utils :: toQString ( o . safeValue ( optionIdx ++ ));
if ( caseId != - 1 && ! propertiesFolder . isEmpty ())
{
projectModifier -> setReplacePropertiesFolder ( caseId , propertiesFolder );
}
}
}
}
2013-12-04 12:04:42 +01:00
loadProject ( projectFileName , projectLoadAction , projectModifier . p ());
}
2013-12-04 14:56:04 +01:00
if ( cvf :: Option o = progOpt . option ( "case" ))
2013-12-04 12:04:42 +01:00
{
2013-12-04 14:56:04 +01:00
QStringList caseNames = cvfqt :: Utils :: toQStringList ( o . values ());
2013-12-04 12:04:42 +01:00
foreach ( QString caseName , caseNames )
{
2017-06-27 14:49:33 +02:00
QString fileExtension = caf :: Utils :: fileExtension ( caseName );
if ( caf :: Utils :: fileExists ( caseName ) &&
( fileExtension == "EGRID" || fileExtension == "GRID" ))
2013-12-04 12:04:42 +01:00
{
2017-06-27 14:49:33 +02:00
openEclipseCaseFromFile ( caseName );
2013-12-04 12:04:42 +01:00
}
else
{
2017-06-27 14:49:33 +02:00
QString caseFileNameWithExt = caseName + ".EGRID" ;
2017-06-07 07:18:44 +02:00
if ( caf :: Utils :: fileExists ( caseFileNameWithExt ))
2013-12-04 12:04:42 +01:00
{
openEclipseCaseFromFile ( caseFileNameWithExt );
}
2017-06-27 14:49:33 +02:00
else
{
caseFileNameWithExt = caseName + ".GRID" ;
if ( caf :: Utils :: fileExists ( caseFileNameWithExt ))
{
openEclipseCaseFromFile ( caseFileNameWithExt );
}
}
2013-12-04 12:04:42 +01:00
}
}
}
2016-11-09 12:22:07 +01:00
if ( cvf :: Option o = progOpt . option ( "savesnapshots" ))
2013-12-04 12:04:42 +01:00
{
2016-11-09 12:22:07 +01:00
bool snapshotViews = false ;
bool snapshotPlots = false ;
QStringList snapshotItemTexts = cvfqt :: Utils :: toQStringList ( o . values ());
if ( snapshotItemTexts . size () == 0 )
2013-12-04 12:04:42 +01:00
{
2016-11-09 12:22:07 +01:00
// No options will keep backwards compability before we introduced snapshot of plots
snapshotViews = true ;
}
2013-12-04 12:04:42 +01:00
2016-11-09 12:22:07 +01:00
for ( QString s : snapshotItemTexts )
{
if ( s . toLower () == "all" )
{
snapshotViews = true ;
snapshotPlots = true ;
}
else if ( s . toLower () == "views" )
{
snapshotViews = true ;
}
else if ( s . toLower () == "plots" )
{
snapshotPlots = true ;
}
}
2013-12-04 12:04:42 +01:00
2016-11-09 12:22:07 +01:00
if ( m_project . notNull () && ! m_project -> fileName (). isEmpty ())
{
if ( snapshotViews )
{
RiuMainWindow * mainWnd = RiuMainWindow :: instance ();
CVF_ASSERT ( mainWnd );
mainWnd -> hideAllDockWindows ();
// 2016-11-09 : Location of snapshot folder was previously located in 'snapshot' folder
// relative to current working folder. Now harmonized to behave as RiuMainWindow::slotSnapshotAllViewsToFile()
QString absolutePathToSnapshotDir = createAbsolutePathFromProjectRelativePath ( "snapshots" );
saveSnapshotForAllViews ( absolutePathToSnapshotDir );
mainWnd -> loadWinGeoAndDockToolBarLayout ();
}
2016-07-15 10:55:20 +02:00
2016-11-09 12:22:07 +01:00
if ( snapshotPlots )
{
if ( m_mainPlotWindow )
{
m_mainPlotWindow -> hideAllDockWindows ();
// Will be saved relative to current directory
RicSnapshotAllPlotsToFileFeature :: saveAllPlots ();
m_mainPlotWindow -> loadWinGeoAndDockToolBarLayout ();
}
}
2017-05-04 14:28:32 +02:00
closeAllWindows ();
processEvents ();
2013-12-04 12:04:42 +01:00
}
// Returning false will exit the application
return false ;
}
2017-07-26 16:41:17 +02:00
if ( cvf :: Option o = progOpt . option ( "commandFile" ))
{
QString commandFile = cvfqt :: Utils :: toQString ( o . safeValue ( 0 ));
QFile file ( commandFile );
RicfMessages messages ;
if ( ! file . open ( QIODevice :: ReadOnly | QIODevice :: Text ))
{
// TODO : Error logging?
return false ;
}
QTextStream in ( & file );
RicfCommandFileExecutor :: instance () -> executeCommands ( in );
closeAllWindows ();
processEvents ();
return false ;
}
2013-12-04 12:04:42 +01:00
return true ;
}
2015-10-05 16:09:51 +02:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
2015-12-03 10:33:38 +01:00
int RiaApplication :: launchUnitTests ()
2015-10-05 16:09:51 +02:00
{
2015-12-03 11:38:59 +01:00
#ifdef USE_UNIT_TESTS
2015-10-05 16:09:51 +02:00
cvf :: Assert :: setReportMode ( cvf :: Assert :: CONSOLE );
int argc = QCoreApplication :: argc ();
testing :: InitGoogleTest ( & argc , QCoreApplication :: argv ());
2015-12-03 10:33:38 +01:00
// Use this macro in main() to run all tests. It returns 0 if all
// tests are successful, or 1 otherwise.
//
// RUN_ALL_TESTS() should be invoked after the command line has been
// parsed by InitGoogleTest().
return RUN_ALL_TESTS ();
2015-12-03 11:38:59 +01:00
#else
return - 1 ;
#endif
2015-10-05 16:09:51 +02:00
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
2015-12-03 10:33:38 +01:00
int RiaApplication :: launchUnitTestsWithConsole ()
2015-10-05 16:09:51 +02:00
{
// Following code is taken from cvfAssert.cpp
#ifdef WIN32
{
// Allocate a new console for this app
// Only one console can be associated with an app, so should fail if a console is already present.
AllocConsole ();
2016-05-04 15:11:42 +02:00
FILE * consoleFilePointer ;
2015-10-05 16:09:51 +02:00
2016-05-04 15:11:42 +02:00
freopen_s ( & consoleFilePointer , "CONOUT$" , "w" , stdout );
freopen_s ( & consoleFilePointer , "CONOUT$" , "w" , stderr );
2015-10-05 16:09:51 +02:00
// Make cout, wcout, cin, wcin, wcerr, cerr, wclog and clog point to console as well
std :: ios :: sync_with_stdio ();
}
#endif
2015-12-03 10:33:38 +01:00
return launchUnitTests ();
2015-10-05 16:09:51 +02:00
}
2013-12-04 12:04:42 +01:00
2016-06-27 11:07:01 +02:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiaApplication :: createMainPlotWindow ()
{
CVF_ASSERT ( m_mainPlotWindow == NULL );
m_mainPlotWindow = new RiuMainPlotWindow ;
2016-06-29 14:15:39 +02:00
m_mainPlotWindow -> setWindowTitle ( "Plots - ResInsight" );
2016-06-27 11:07:01 +02:00
m_mainPlotWindow -> setDefaultWindowSize ();
m_mainPlotWindow -> loadWinGeoAndDockToolBarLayout ();
m_mainPlotWindow -> showWindow ();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiaApplication :: deleteMainPlotWindow ()
{
2016-06-29 14:15:39 +02:00
if ( m_mainPlotWindow )
{
m_mainPlotWindow -> deleteLater ();
m_mainPlotWindow = NULL ;
}
2016-06-27 11:07:01 +02:00
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
2016-06-27 14:00:19 +02:00
RiuMainPlotWindow * RiaApplication :: getOrCreateAndShowMainPlotWindow ()
2016-06-27 11:07:01 +02:00
{
if ( ! m_mainPlotWindow )
{
createMainPlotWindow ();
2016-10-05 10:04:41 +02:00
loadAndUpdatePlotData ();
2016-06-27 11:07:01 +02:00
}
2016-11-24 14:47:20 +01:00
if ( m_mainPlotWindow -> isMinimized ())
{
m_mainPlotWindow -> showNormal ();
m_mainPlotWindow -> update ();
}
else
{
m_mainPlotWindow -> show ();
}
2016-10-04 09:29:45 +02:00
m_mainPlotWindow -> raise ();
2016-06-27 14:00:19 +02:00
2016-06-27 11:07:01 +02:00
return m_mainPlotWindow ;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RiuMainPlotWindow * RiaApplication :: mainPlotWindow ()
{
return m_mainPlotWindow ;
}
2016-08-31 17:34:31 +02:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
2017-01-17 13:06:57 +01:00
RiuMainWindowBase * RiaApplication :: mainWindowByID ( int mainWindowID )
{
if ( mainWindowID == 0 ) return RiuMainWindow :: instance ();
else if ( mainWindowID == 1 ) return m_mainPlotWindow ;
else return nullptr ;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
2016-08-31 17:34:31 +02:00
RimViewWindow * RiaApplication :: activeViewWindow ()
{
RimViewWindow * viewWindow = NULL ;
2017-03-31 15:10:39 +02:00
QWidget * mainWindowWidget = RiaApplication :: activeWindow ();
2016-08-31 17:34:31 +02:00
2017-03-31 15:10:39 +02:00
if ( dynamic_cast < RiuMainWindow *> ( mainWindowWidget ))
2016-08-31 17:34:31 +02:00
{
viewWindow = RiaApplication :: instance () -> activeReservoirView ();
}
2017-03-31 15:10:39 +02:00
else if ( dynamic_cast < RiuMainPlotWindow *> ( mainWindowWidget ))
2016-08-31 17:34:31 +02:00
{
2017-03-31 15:10:39 +02:00
RiuMainPlotWindow * mainPlotWindow = dynamic_cast < RiuMainPlotWindow *> ( mainWindowWidget );
2016-08-31 17:34:31 +02:00
QList < QMdiSubWindow *> subwindows = mainPlotWindow -> subWindowList ( QMdiArea :: StackingOrder );
if ( subwindows . size () > 0 )
{
2017-03-31 15:10:39 +02:00
viewWindow = RiuInterfaceToViewWindow :: viewWindowFromWidget ( subwindows . back () -> widget ());
2016-08-31 17:34:31 +02:00
}
}
return viewWindow ;
}
2017-04-25 15:01:31 +02:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RiaApplication :: isMain3dWindowVisible () const
{
return RiuMainWindow :: instance () -> isVisible ();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RiaApplication :: isMainPlotWindowVisible () const
{
if ( ! m_mainPlotWindow ) return false ;
return m_mainPlotWindow -> isVisible ();
}
2016-10-04 09:29:45 +02:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RiaApplication :: tryCloseMainWindow ()
{
RiuMainWindow * mainWindow = RiuMainWindow :: instance ();
if ( mainWindow && ! mainWindow -> isVisible ())
{
mainWindow -> close ();
return true ;
}
return false ;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RiaApplication :: tryClosePlotWindow ()
{
2016-10-04 13:14:39 +02:00
if ( ! m_mainPlotWindow )
{
return true ;
}
2016-10-04 09:29:45 +02:00
if ( m_mainPlotWindow && ! m_mainPlotWindow -> isVisible ())
{
m_mainPlotWindow -> close ();
return true ;
}
return false ;
}
2016-10-05 08:23:07 +02:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiaApplication :: addToRecentFiles ( const QString & fileName )
{
m_recentFileActionProvider -> addFileName ( fileName );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std :: vector < QAction *> RiaApplication :: recentFileActions () const
{
return m_recentFileActionProvider -> actions ();
}
2017-07-26 16:57:43 +02:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiaApplication :: setStartDir ( const QString & startDir )
{
m_startupDefaultDirectory = startDir ;
}
2013-12-04 12:04:42 +01:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std :: vector < QString > RiaApplication :: readFileListFromTextFile ( QString listFileName )
{
std :: vector < QString > fileList ;
QFile file ( listFileName );
if ( ! file . open ( QIODevice :: ReadOnly | QIODevice :: Text ))
{
return fileList ;
}
QTextStream in ( & file );
QString line = in . readLine ();
while ( ! line . isNull ())
{
line = line . trimmed ();
if ( ! line . isEmpty ())
{
fileList . push_back ( line );
}
line = in . readLine ();
}
return fileList ;
}
2013-10-08 14:28:01 +02:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RiaApplication :: scriptDirectories () const
{
return m_preferences -> scriptDirectories ();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RiaApplication :: scriptEditorPath () const
{
return m_preferences -> scriptEditorExecutable ();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RiaApplication :: octavePath () const
{
return m_preferences -> octaveExecutable ();
}
2014-07-22 12:11:48 +02:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QStringList RiaApplication :: octaveArguments () const
{
// http://www.gnu.org/software/octave/doc/interpreter/Command-Line-Options.html#Command-Line-Options
// -p path
// Add path to the head of the search path for function files. The value of path specified on the command line
// will override any value of OCTAVE_PATH found in the environment, but not any commands in the system or
// user startup files that set the internal load path through one of the path functions.
QStringList arguments ;
arguments . append ( "--path" );
arguments << QApplication :: applicationDirPath ();
if ( ! m_preferences -> octaveShowHeaderInfoWhenExecutingScripts )
{
// -q
// Don't print the usual greeting and version message at startup.
arguments . append ( "-q" );
}
return arguments ;
}
2013-10-08 14:28:01 +02:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiaApplication :: slotWorkerProcessFinished ( int exitCode , QProcess :: ExitStatus exitStatus )
{
RiuMainWindow :: instance () -> processMonitor () -> stopMonitorWorkProcess ();
// Execute delete later so that other slots that are hooked up
// get a chance to run before we delete the object
if ( m_workerProcess )
{
m_workerProcess -> close ();
}
m_workerProcess = NULL ;
// Either the work process crashed or was aborted by the user
if ( exitStatus == QProcess :: CrashExit )
{
// MFLog::error("Simulation execution crashed or was aborted.");
return ;
}
executeCommandObjects ();
// Exit code != 0 means we have an error
if ( exitCode != 0 )
{
// MFLog::error(QString("Simulation execution failed (exit code %1).").arg(exitCode));
return ;
}
// If multiple cases are present, invoke launchProcess() which will set next current case, and run script on this case
2015-11-27 16:37:26 +01:00
if ( ! m_currentCaseIds . empty ())
2013-10-08 14:28:01 +02:00
{
launchProcess ( m_currentProgram , m_currentArguments );
}
else
{
// Disable concept of current case
m_socketServer -> setCurrentCaseId ( - 1 );
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RiaApplication :: launchProcess ( const QString & program , const QStringList & arguments )
{
if ( m_workerProcess == NULL )
{
// If multiple cases are present, pop the first case ID from the list and set as current case
2015-11-27 16:37:26 +01:00
if ( ! m_currentCaseIds . empty ())
2013-10-08 14:28:01 +02:00
{
int nextCaseId = m_currentCaseIds . front ();
m_currentCaseIds . pop_front ();
m_socketServer -> setCurrentCaseId ( nextCaseId );
}
else
{
// Disable current case concept
m_socketServer -> setCurrentCaseId ( - 1 );
}
m_workerProcess = new caf :: UiProcess ( this );
QProcessEnvironment penv = QProcessEnvironment :: systemEnvironment ();
2014-01-02 14:31:10 +01:00
#ifdef WIN32
// Octave plugins compiled by ResInsight are dependent on Qt (currently Qt 32-bit only)
// Some Octave installations for Windows have included Qt, and some don't. To make sure these plugins always can be executed,
// the path to octave_plugin_dependencies is added to global path
QString pathString = penv . value ( "PATH" , "" );
if ( pathString == "" ) pathString = QApplication :: applicationDirPath () + " \\ octave_plugin_dependencies" ;
else pathString = QApplication :: applicationDirPath () + " \\ octave_plugin_dependencies" + ";" + pathString ;
penv . insert ( "PATH" , pathString );
#else
// Set the LD_LIBRARY_PATH to make the octave plugins find the embedded Qt
QString ldPath = penv . value ( "LD_LIBRARY_PATH" , "" );
if ( ldPath == "" ) ldPath = QApplication :: applicationDirPath ();
else ldPath = QApplication :: applicationDirPath () + ":" + ldPath ;
penv . insert ( "LD_LIBRARY_PATH" , ldPath );
#endif
2013-10-08 14:28:01 +02:00
m_workerProcess -> setProcessEnvironment ( penv );
connect ( m_workerProcess , SIGNAL ( finished ( int , QProcess :: ExitStatus )), SLOT ( slotWorkerProcessFinished ( int , QProcess :: ExitStatus )));
RiuMainWindow :: instance () -> processMonitor () -> startMonitorWorkProcess ( m_workerProcess );
m_workerProcess -> start ( program , arguments );
if ( ! m_workerProcess -> waitForStarted ( 1000 ))
{
m_workerProcess -> close ();
m_workerProcess = NULL ;
RiuMainWindow :: instance () -> processMonitor () -> stopMonitorWorkProcess ();
QMessageBox :: warning ( RiuMainWindow :: instance (), "Script execution" , "Failed to start script executable located at \n " + program );
return false ;
}
return true ;
}
else
{
QMessageBox :: warning ( NULL , "Script execution" , "An Octave process is still running. Please stop this process before executing a new script." );
return false ;
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RiaApplication :: launchProcessForMultipleCases ( const QString & program , const QStringList & arguments , const std :: vector < int >& caseIds )
{
m_currentCaseIds . clear ();
std :: copy ( caseIds . begin (), caseIds . end (), std :: back_inserter ( m_currentCaseIds ) );
m_currentProgram = program ;
m_currentArguments = arguments ;
return launchProcess ( m_currentProgram , m_currentArguments );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RiaPreferences * RiaApplication :: preferences ()
{
return m_preferences ;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiaApplication :: applyPreferences ()
{
if ( m_activeReservoirView && m_activeReservoirView -> viewer ())
{
2015-07-02 12:44:57 +02:00
m_activeReservoirView -> viewer () -> updateNavigationPolicy ();
2013-10-08 14:28:01 +02:00
m_activeReservoirView -> viewer () -> enablePerfInfoHud ( m_preferences -> showHud ());
}
if ( useShaders ())
{
caf :: EffectGenerator :: setRenderingMode ( caf :: EffectGenerator :: SHADER_BASED );
}
else
{
caf :: EffectGenerator :: setRenderingMode ( caf :: EffectGenerator :: FIXED_FUNCTION );
}
2015-09-18 19:24:02 +02:00
if ( RiuMainWindow :: instance () && RiuMainWindow :: instance () -> projectTreeView ())
{
RiuMainWindow :: instance () -> projectTreeView () -> enableAppendOfClassNameToUiItemText ( m_preferences -> appendClassNameToUiText ());
2017-01-19 17:35:47 +01:00
if ( mainPlotWindow ()) mainPlotWindow () -> projectTreeView () -> enableAppendOfClassNameToUiItemText ( m_preferences -> appendClassNameToUiText ());
2015-09-18 19:24:02 +02:00
}
2016-08-09 13:09:08 +02:00
caf :: FixedAtlasFont :: FontSize fontSizeType = caf :: FixedAtlasFont :: POINT_SIZE_16 ;
if ( m_preferences -> fontSizeInScene () == "8" )
{
fontSizeType = caf :: FixedAtlasFont :: POINT_SIZE_8 ;
}
else if ( m_preferences -> fontSizeInScene () == "12" )
{
fontSizeType = caf :: FixedAtlasFont :: POINT_SIZE_12 ;
}
else if ( m_preferences -> fontSizeInScene () == "16" )
{
fontSizeType = caf :: FixedAtlasFont :: POINT_SIZE_16 ;
}
else if ( m_preferences -> fontSizeInScene () == "24" )
{
fontSizeType = caf :: FixedAtlasFont :: POINT_SIZE_24 ;
}
else if ( m_preferences -> fontSizeInScene () == "32" )
{
fontSizeType = caf :: FixedAtlasFont :: POINT_SIZE_32 ;
}
m_customFont = new caf :: FixedAtlasFont ( fontSizeType );
2013-10-08 14:28:01 +02:00
if ( this -> project ())
{
this -> project () -> setScriptDirectories ( m_preferences -> scriptDirectories ());
2015-09-18 19:24:02 +02:00
this -> project () -> updateConnectedEditors ();
2016-08-09 13:09:08 +02:00
std :: vector < RimView *> visibleViews ;
this -> project () -> allVisibleViews ( visibleViews );
for ( auto view : visibleViews )
{
RimEclipseView * eclipseView = dynamic_cast < RimEclipseView *> ( view );
if ( eclipseView )
{
eclipseView -> scheduleReservoirGridGeometryRegen ();
}
view -> scheduleCreateDisplayModelAndRedraw ();
}
2013-10-08 14:28:01 +02:00
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiaApplication :: terminateProcess ()
{
if ( m_workerProcess )
{
m_workerProcess -> close ();
}
m_workerProcess = NULL ;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
2016-09-21 09:46:17 +02:00
QString RiaApplication :: lastUsedDialogDirectory ( const QString & dialogName )
2013-10-08 14:28:01 +02:00
{
2016-09-21 09:46:17 +02:00
QString lastUsedDirectory = m_startupDefaultDirectory ;
auto it = m_fileDialogDefaultDirectories . find ( dialogName );
if ( it != m_fileDialogDefaultDirectories . end ())
{
lastUsedDirectory = it -> second ;
}
return lastUsedDirectory ;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RiaApplication :: lastUsedDialogDirectoryWithFallback ( const QString & dialogName , const QString & fallbackDirectory )
{
QString lastUsedDirectory = m_startupDefaultDirectory ;
if ( ! fallbackDirectory . isEmpty ())
{
lastUsedDirectory = fallbackDirectory ;
}
auto it = m_fileDialogDefaultDirectories . find ( dialogName );
if ( it != m_fileDialogDefaultDirectories . end ())
2013-10-08 14:28:01 +02:00
{
2016-09-21 09:46:17 +02:00
lastUsedDirectory = it -> second ;
2013-10-08 14:28:01 +02:00
}
2016-09-21 09:46:17 +02:00
return lastUsedDirectory ;
2013-10-08 14:28:01 +02:00
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
2016-09-21 09:46:17 +02:00
void RiaApplication :: setLastUsedDialogDirectory ( const QString & dialogName , const QString & directory )
2013-10-08 14:28:01 +02:00
{
2016-09-21 09:46:17 +02:00
m_fileDialogDefaultDirectories [ dialogName ] = directory ;
2013-10-08 14:28:01 +02:00
}
2013-12-04 12:04:42 +01:00
2016-10-05 10:42:08 +02:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RiaApplication :: openFile ( const QString & fileName )
{
2017-05-11 09:23:13 +02:00
if ( ! caf :: Utils :: fileExists ( fileName )) return false ;
2016-11-24 10:51:20 +01:00
2016-10-05 10:42:08 +02:00
bool loadingSucceded = false ;
2017-04-20 08:07:47 +02:00
if ( RiaApplication :: hasValidProjectFileExtension ( fileName ))
2016-10-05 10:42:08 +02:00
{
loadingSucceded = loadProject ( fileName );
}
else if ( fileName . contains ( ".egrid" , Qt :: CaseInsensitive ) || fileName . contains ( ".grid" , Qt :: CaseInsensitive ))
{
loadingSucceded = openEclipseCaseFromFile ( fileName );
}
2016-11-28 07:25:04 +01:00
else if ( fileName . contains ( ".grdecl" , Qt :: CaseInsensitive ))
{
loadingSucceded = openInputEclipseCaseFromFileNames ( QStringList ( fileName ));
}
2016-10-05 10:42:08 +02:00
else if ( fileName . contains ( ".odb" , Qt :: CaseInsensitive ))
{
loadingSucceded = openOdbCaseFromFile ( fileName );
}
2016-10-06 10:33:57 +02:00
else if ( fileName . contains ( ".smspec" , Qt :: CaseInsensitive ))
{
loadingSucceded = RicImportSummaryCaseFeature :: createAndAddSummaryCaseFromFile ( fileName );
if ( loadingSucceded )
{
getOrCreateAndShowMainPlotWindow ();
2016-10-24 16:01:19 +02:00
std :: vector < RimCase *> cases ;
m_project -> allCases ( cases );
if ( cases . size () == 0 )
{
RiuMainWindow :: instance () -> close ();
}
2016-10-06 10:33:57 +02:00
m_project -> updateConnectedEditors ();
}
}
2016-10-05 10:42:08 +02:00
2017-04-20 08:07:47 +02:00
if ( loadingSucceded && ! RiaApplication :: hasValidProjectFileExtension ( fileName ))
{
caf :: PdmUiModelChangeDetector :: instance () -> setModelChanged ();
}
2016-10-05 10:42:08 +02:00
return loadingSucceded ;
}
2013-10-08 14:28:01 +02:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiaApplication :: saveSnapshotForAllViews ( const QString & snapshotFolderName )
{
RiuMainWindow * mainWnd = RiuMainWindow :: instance ();
if ( ! mainWnd ) return ;
2016-11-01 11:50:38 +01:00
if ( m_project . isNull ()) return ;
2013-10-08 14:28:01 +02:00
2013-12-04 12:04:42 +01:00
QDir snapshotPath ( snapshotFolderName );
if ( ! snapshotPath . exists ())
2013-10-08 14:28:01 +02:00
{
2013-12-04 12:04:42 +01:00
if ( ! snapshotPath . mkpath ( "." )) return ;
2013-10-08 14:28:01 +02:00
}
2013-12-04 12:04:42 +01:00
const QString absSnapshotPath = snapshotPath . absolutePath ();
2013-10-08 14:28:01 +02:00
2015-05-15 18:51:49 +02:00
std :: vector < RimCase *> projectCases ;
2013-10-08 14:28:01 +02:00
m_project -> allCases ( projectCases );
for ( size_t i = 0 ; i < projectCases . size (); i ++ )
{
2015-05-15 18:51:49 +02:00
RimCase * cas = projectCases [ i ];
if ( ! cas ) continue ;
std :: vector < RimView *> views = cas -> views ();
2013-10-08 14:28:01 +02:00
2015-05-15 18:51:49 +02:00
for ( size_t j = 0 ; j < views . size (); j ++ )
2013-10-08 14:28:01 +02:00
{
2015-05-15 18:51:49 +02:00
RimView * riv = views [ j ];
2013-10-08 14:28:01 +02:00
if ( riv && riv -> viewer ())
{
setActiveReservoirView ( riv );
RiuViewer * viewer = riv -> viewer ();
2015-09-02 15:53:49 +02:00
mainWnd -> setActiveViewer ( viewer -> layoutWidget ());
2013-10-08 14:28:01 +02:00
2015-10-23 14:13:14 +02:00
clearViewsScheduledForUpdate ();
2013-10-08 14:28:01 +02:00
2015-12-11 10:45:48 +01:00
//riv->updateCurrentTimeStepAndRedraw();
riv -> createDisplayModelAndRedraw ();
viewer -> repaint ();
2015-05-15 18:51:49 +02:00
QString fileName = cas -> caseUserDescription () + "-" + riv -> name ();
2017-01-04 10:45:04 +01:00
fileName = caf :: Utils :: makeValidFileBasename ( fileName );
2013-10-08 14:28:01 +02:00
2013-12-04 12:04:42 +01:00
QString absoluteFileName = caf :: Utils :: constructFullFileName ( absSnapshotPath , fileName , ".png" );
2016-10-27 08:35:57 +02:00
2016-11-09 12:22:07 +01:00
RicSnapshotViewToFileFeature :: saveSnapshotAs ( absoluteFileName , riv );
2013-10-08 14:28:01 +02:00
}
}
}
}
2013-12-04 12:04:42 +01:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiaApplication :: runMultiCaseSnapshots ( const QString & templateProjectFileName , std :: vector < QString > gridFileNames , const QString & snapshotFolderName )
{
RiuMainWindow * mainWnd = RiuMainWindow :: instance ();
if ( ! mainWnd ) return ;
mainWnd -> hideAllDockWindows ();
const size_t numGridFiles = gridFileNames . size ();
for ( size_t i = 0 ; i < numGridFiles ; i ++ )
{
QString gridFn = gridFileNames [ i ];
RiaProjectModifier modifier ;
2016-11-25 14:21:40 +01:00
modifier . setReplaceCaseFirstOccurrence ( gridFn );
2013-12-04 12:04:42 +01:00
bool loadOk = loadProject ( templateProjectFileName , PLA_NONE , & modifier );
if ( loadOk )
{
saveSnapshotForAllViews ( snapshotFolderName );
}
}
mainWnd -> loadWinGeoAndDockToolBarLayout ();
}
2016-10-27 08:35:57 +02:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
2013-10-08 14:28:01 +02:00
void removeDirectoryWithContent ( QDir dirToDelete )
{
QStringList files = dirToDelete . entryList ();
for ( int fIdx = 0 ; fIdx < files . size (); ++ fIdx )
{
dirToDelete . remove ( files [ fIdx ]);
}
dirToDelete . rmdir ( "." );
}
2017-04-20 22:34:15 +02:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void logInfoTextWithTimeInSeconds ( const QTime & time , const QString & msg )
{
double timeRunning = time . elapsed () / 1000.0 ;
QString timeText = QString ( "(%1 s) " ). arg ( timeRunning , 0 , 'f' , 1 );
RiaLogging :: info ( timeText + msg );
}
2013-10-08 14:28:01 +02:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiaApplication :: runRegressionTest ( const QString & testRootPath )
{
2015-06-26 13:44:16 +02:00
m_runningRegressionTests = true ;
2013-10-08 14:28:01 +02:00
QString generatedFolderName = RegTestNames :: generatedFolderName ;
QString diffFolderName = RegTestNames :: diffFolderName ;
QString baseFolderName = RegTestNames :: baseFolderName ;
QString regTestProjectName = RegTestNames :: testProjectName ;
QString regTestFolderFilter = RegTestNames :: testFolderFilter ;
// Find all sub folders
QDir testDir ( testRootPath ); // If string is empty it will end up as cwd
testDir . setFilter ( QDir :: Dirs );
QStringList dirNameFilter ;
dirNameFilter . append ( regTestFolderFilter );
testDir . setNameFilters ( dirNameFilter );
QFileInfoList folderList = testDir . entryInfoList ();
// delete diff and generated images
for ( int i = 0 ; i < folderList . size (); ++ i )
{
QDir testCaseFolder ( folderList [ i ]. filePath ());
QDir genDir ( testCaseFolder . filePath ( generatedFolderName ));
removeDirectoryWithContent ( genDir );
QDir diffDir ( testCaseFolder . filePath ( diffFolderName ));
removeDirectoryWithContent ( diffDir );
QDir baseDir ( testCaseFolder . filePath ( baseFolderName ));
}
// Generate html report
RiaImageCompareReporter imageCompareReporter ;
2016-01-11 07:59:44 +01:00
// Minor workaround
// Use registry to define if interactive diff images should be created
// Defined by user in RiaRegressionTest
{
QSettings settings ;
bool useInteractiveDiff = settings . value ( "showInteractiveDiffImages" ). toBool ();
if ( useInteractiveDiff )
{
imageCompareReporter . showInteractiveOnly ();
}
}
2017-04-20 22:34:15 +02:00
QTime timeStamp ;
timeStamp . start ();
logInfoTextWithTimeInSeconds ( timeStamp , "Starting regression tests \n " );
2013-10-08 14:28:01 +02:00
for ( int dirIdx = 0 ; dirIdx < folderList . size (); ++ dirIdx )
{
QDir testCaseFolder ( folderList [ dirIdx ]. filePath ());
QString testFolderName = testCaseFolder . dirName ();
QString reportBaseFolderName = testCaseFolder . filePath ( baseFolderName );
QString reportGeneratedFolderName = testCaseFolder . filePath ( generatedFolderName );
QString reportDiffFolderName = testCaseFolder . filePath ( diffFolderName );
imageCompareReporter . addImageDirectoryComparisonSet ( testFolderName . toStdString (), reportBaseFolderName . toStdString (), reportGeneratedFolderName . toStdString (), reportDiffFolderName . toStdString ());
}
QString htmlReportFileName = testDir . filePath ( RegTestNames :: reportFileName );
imageCompareReporter . generateHTMLReport ( htmlReportFileName . toStdString ());
// Open HTML report
QDesktopServices :: openUrl ( htmlReportFileName );
for ( int dirIdx = 0 ; dirIdx < folderList . size (); ++ dirIdx )
{
QDir testCaseFolder ( folderList [ dirIdx ]. filePath ());
2017-04-20 21:21:12 +02:00
QString projectFileName ;
if ( testCaseFolder . exists ( regTestProjectName + ".rip" ))
{
projectFileName = regTestProjectName + ".rip" ;
}
if ( testCaseFolder . exists ( regTestProjectName + ".rsp" ))
{
projectFileName = regTestProjectName + ".rsp" ;
}
if ( ! projectFileName . isEmpty ())
2013-10-08 14:28:01 +02:00
{
2017-04-20 22:34:15 +02:00
logInfoTextWithTimeInSeconds ( timeStamp , "Initializing test :" + testCaseFolder . absolutePath ());
loadProject ( testCaseFolder . filePath ( projectFileName ));
// Wait until all command objects have completed
while ( ! m_commandQueueLock . tryLock ())
{
processEvents ();
}
m_commandQueueLock . unlock ();
regressionTestConfigureProject ();
2017-04-24 09:39:54 +02:00
resizeMaximizedPlotWindows ();
2017-04-20 22:34:15 +02:00
QString fullPathGeneratedFolder = testCaseFolder . absoluteFilePath ( generatedFolderName );
saveSnapshotForAllViews ( fullPathGeneratedFolder );
RicSnapshotAllPlotsToFileFeature :: exportSnapshotOfAllPlotsIntoFolder ( fullPathGeneratedFolder );
QDir baseDir ( testCaseFolder . filePath ( baseFolderName ));
QDir genDir ( testCaseFolder . filePath ( generatedFolderName ));
QDir diffDir ( testCaseFolder . filePath ( diffFolderName ));
if ( ! diffDir . exists ()) testCaseFolder . mkdir ( diffFolderName );
baseDir . setFilter ( QDir :: Files );
QStringList baseImageFileNames = baseDir . entryList ();
for ( int fIdx = 0 ; fIdx < baseImageFileNames . size (); ++ fIdx )
{
QString fileName = baseImageFileNames [ fIdx ];
RiaImageFileCompare imgComparator ( RegTestNames :: imageCompareExeName );
bool ok = imgComparator . runComparison ( genDir . filePath ( fileName ), baseDir . filePath ( fileName ), diffDir . filePath ( fileName ));
if ( ! ok )
{
2013-10-08 14:28:01 +02:00
qDebug () << "Error comparing :" << imgComparator . errorMessage () << " \n " << imgComparator . errorDetails ();
2017-04-20 22:34:15 +02:00
}
}
2013-10-08 14:28:01 +02:00
2017-04-20 22:34:15 +02:00
closeProject ();
logInfoTextWithTimeInSeconds ( timeStamp , "Completed test :" + testCaseFolder . absolutePath ());
2013-10-08 14:28:01 +02:00
}
}
2015-06-26 13:44:16 +02:00
2017-04-20 22:34:15 +02:00
RiaLogging :: info ( " \n " );
logInfoTextWithTimeInSeconds ( timeStamp , "Completed regression tests" );
2015-06-26 13:44:16 +02:00
m_runningRegressionTests = false ;
2013-10-08 14:28:01 +02:00
}
2017-04-24 09:39:54 +02:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiaApplication :: resizeMaximizedPlotWindows ()
{
std :: vector < RimViewWindow *> viewWindows ;
2017-04-24 21:40:46 +02:00
m_project -> mainPlotCollection () -> descendantsIncludingThisOfType ( viewWindows );
2017-04-24 09:39:54 +02:00
for ( auto viewWindow : viewWindows )
{
if ( viewWindow -> isMdiWindow ())
{
RimMdiWindowGeometry wndGeo = viewWindow -> mdiWindowGeometry ();
if ( wndGeo . isMaximized )
{
QWidget * viewWidget = viewWindow -> viewWidget ();
if ( viewWidget )
{
QMdiSubWindow * mdiWindow = m_mainPlotWindow -> findMdiSubWindow ( viewWidget );
if ( mdiWindow )
{
mdiWindow -> showNormal ();
viewWidget -> resize ( RiaApplication :: regressionDefaultImageSize ());
}
}
}
}
}
}
2013-10-08 14:28:01 +02:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiaApplication :: updateRegressionTest ( const QString & testRootPath )
{
// Find all sub folders
QDir testDir ( testRootPath ); // If string is empty it will end up as cwd
testDir . setFilter ( QDir :: Dirs );
QStringList dirNameFilter ;
dirNameFilter . append ( RegTestNames :: testFolderFilter );
testDir . setNameFilters ( dirNameFilter );
QFileInfoList folderList = testDir . entryInfoList ();
for ( int i = 0 ; i < folderList . size (); ++ i )
{
QDir testCaseFolder ( folderList [ i ]. filePath ());
QDir baseDir ( testCaseFolder . filePath ( RegTestNames :: baseFolderName ));
removeDirectoryWithContent ( baseDir );
testCaseFolder . mkdir ( RegTestNames :: baseFolderName );
QDir genDir ( testCaseFolder . filePath ( RegTestNames :: generatedFolderName ));
QStringList imageFileNames = genDir . entryList ();
for ( int fIdx = 0 ; fIdx < imageFileNames . size (); ++ fIdx )
{
QString fileName = imageFileNames [ fIdx ];
QFile :: copy ( genDir . filePath ( fileName ), baseDir . filePath ( fileName ));
}
}
}
//--------------------------------------------------------------------------------------------------
/// Make sure changes in this functions is validated to RimIdenticalGridCaseGroup::initAfterRead()
//--------------------------------------------------------------------------------------------------
bool RiaApplication :: addEclipseCases ( const QStringList & fileNames )
{
if ( fileNames . size () == 0 ) return true ;
// First file is read completely including grid.
// The main grid from the first case is reused directly in for the other cases.
// When reading active cell info, only the total cell count is tested for consistency
2015-06-25 11:56:18 +02:00
RimEclipseResultCase * mainResultCase = NULL ;
2013-10-08 14:28:01 +02:00
std :: vector < std :: vector < int > > mainCaseGridDimensions ;
RimIdenticalGridCaseGroup * gridCaseGroup = NULL ;
{
QString firstFileName = fileNames [ 0 ];
QFileInfo gridFileName ( firstFileName );
QString caseName = gridFileName . completeBaseName ();
2015-06-25 11:56:18 +02:00
RimEclipseResultCase * rimResultReservoir = new RimEclipseResultCase ();
2013-10-08 14:28:01 +02:00
rimResultReservoir -> setCaseInfo ( caseName , firstFileName );
if ( ! rimResultReservoir -> openEclipseGridFile ())
{
delete rimResultReservoir ;
return false ;
}
rimResultReservoir -> readGridDimensions ( mainCaseGridDimensions );
mainResultCase = rimResultReservoir ;
RimOilField * oilField = m_project -> activeOilField ();
if ( oilField && oilField -> analysisModels ())
{
gridCaseGroup = oilField -> analysisModels -> createIdenticalCaseGroupFromMainCase ( mainResultCase );
}
}
caf :: ProgressInfo info ( fileNames . size (), "Reading Active Cell data" );
for ( int i = 1 ; i < fileNames . size (); i ++ )
{
QString caseFileName = fileNames [ i ];
QFileInfo gridFileName ( caseFileName );
QString caseName = gridFileName . completeBaseName ();
2015-06-25 11:56:18 +02:00
RimEclipseResultCase * rimResultReservoir = new RimEclipseResultCase ();
2013-10-08 14:28:01 +02:00
rimResultReservoir -> setCaseInfo ( caseName , caseFileName );
std :: vector < std :: vector < int > > caseGridDimensions ;
rimResultReservoir -> readGridDimensions ( caseGridDimensions );
bool identicalGrid = RigGridManager :: isGridDimensionsEqual ( mainCaseGridDimensions , caseGridDimensions );
if ( identicalGrid )
{
2017-03-15 09:10:16 +01:00
if ( rimResultReservoir -> openAndReadActiveCellData ( mainResultCase -> eclipseCaseData ()))
2013-10-08 14:28:01 +02:00
{
RimOilField * oilField = m_project -> activeOilField ();
if ( oilField && oilField -> analysisModels ())
{
oilField -> analysisModels () -> insertCaseInCaseGroup ( gridCaseGroup , rimResultReservoir );
}
}
else
{
delete rimResultReservoir ;
}
}
else
{
delete rimResultReservoir ;
}
info . setProgress ( i );
}
2014-10-28 18:33:23 +01:00
if ( gridCaseGroup )
{
// Create placeholder results and propagate results info from main case to all other cases
gridCaseGroup -> loadMainCaseAndActiveCellInfo ();
}
2015-08-13 21:28:09 +02:00
m_project -> activeOilField () -> analysisModels () -> updateConnectedEditors ();
2013-10-08 14:28:01 +02:00
if ( gridCaseGroup -> statisticsCaseCollection () -> reservoirs . size () > 0 )
{
2015-12-07 10:07:51 +01:00
RiuMainWindow :: instance () -> selectAsCurrentItem ( gridCaseGroup -> statisticsCaseCollection () -> reservoirs [ 0 ]);
2013-10-08 14:28:01 +02:00
}
return true ;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
cvf :: Font * RiaApplication :: standardFont ()
{
CVF_ASSERT ( m_standardFont . notNull ());
// The creation of a font is time consuming, so make sure you really need your own font
// instead of using the application font
return m_standardFont . p ();
}
2016-08-09 13:09:08 +02:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
cvf :: Font * RiaApplication :: customFont ()
{
CVF_ASSERT ( m_customFont . notNull ());
return m_customFont . p ();
}
2013-10-08 14:28:01 +02:00
//--------------------------------------------------------------------------------------------------
2015-10-23 14:13:14 +02:00
///
//--------------------------------------------------------------------------------------------------
void RiaApplication :: clearViewsScheduledForUpdate ()
{
if ( m_resViewUpdateTimer )
{
while ( m_resViewUpdateTimer -> isActive ())
{
QCoreApplication :: processEvents ();
}
}
m_resViewsToUpdate . clear ();
}
2013-10-08 14:28:01 +02:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimProject * RiaApplication :: project ()
{
return m_project ;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiaApplication :: showFormattedTextInMessageBox ( const QString & text )
{
QString helpText = text ;
QMessageBox msgBox ;
msgBox . setIcon ( QMessageBox :: Information );
msgBox . setWindowTitle ( "ResInsight" );
helpText . replace ( "&" , "&" );
helpText . replace ( "<" , "<" );
helpText . replace ( ">" , ">" );
helpText = QString ( "<pre>%1</pre>" ). arg ( helpText );
msgBox . setText ( helpText );
msgBox . exec ();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RiaApplication :: commandLineParameterHelp () const
{
2013-12-19 10:45:15 +01:00
return m_helpText ;
/*
2013-10-08 14:28:01 +02:00
QString text = QString("\n%1 v. %2\n").arg(RI_APPLICATION_NAME).arg(getVersionStringApp(false));
text += "Copyright Statoil ASA, Ceetron AS 2011, 2012\n\n";
text +=
"\nParameter Description\n"
"-----------------------------------------------------------------\n"
"-last Open last used project\n"
"\n"
"-project <filename> Open project file <filename>\n"
"\n"
2013-10-18 16:23:31 +02:00
"-case <casename> Import Eclipse case <casename>\n"
2013-10-08 14:28:01 +02:00
" (do not include .GRID/.EGRID)\n"
"\n"
"-savesnapshots Save snapshot of all views to 'snapshots' folder in project file folder\n"
" Application closes after snapshots are written to file\n"
"\n"
"-regressiontest <folder> Run a regression test on all sub-folders starting with \"" + RegTestNames::testFolderFilter + "\" of the given folder: \n"
" " + RegTestNames::testProjectName + " files in the sub-folders will be opened and \n"
" snapshots of all the views is written to the sub-sub-folder " + RegTestNames::generatedFolderName + ". \n"
" Then difference images is generated in the sub-sub-folder " + RegTestNames::diffFolderName + " based \n"
" on the images in sub-sub-folder " + RegTestNames::baseFolderName + ".\n"
" The results are presented in " + RegTestNames::reportFileName + " that is\n"
" written in the given folder.\n"
"\n"
"-updateregressiontestbase <folder> For all sub-folders starting with \"" + RegTestNames::testFolderFilter + "\" of the given folder: \n"
" Copy the images in the sub-sub-folder " + RegTestNames::generatedFolderName + " to the sub-sub-folder\n"
" " + RegTestNames::baseFolderName + " after deleting " + RegTestNames::baseFolderName + " completely.\n"
"\n"
"-help, -? Displays help text\n"
"-----------------------------------------------------------------";
return text;
2013-12-19 10:45:15 +01:00
*/
2013-10-08 14:28:01 +02:00
}
//--------------------------------------------------------------------------------------------------
/// Schedule a creation of the Display model and redraw of the reservoir view
/// The redraw will happen as soon as the event loop is entered
//--------------------------------------------------------------------------------------------------
2015-04-30 10:34:15 +02:00
void RiaApplication :: scheduleDisplayModelUpdateAndRedraw ( RimView * resViewToUpdate )
2013-10-08 14:28:01 +02:00
{
m_resViewsToUpdate . push_back ( resViewToUpdate );
if ( ! m_resViewUpdateTimer )
{
m_resViewUpdateTimer = new QTimer ( this );
connect ( m_resViewUpdateTimer , SIGNAL ( timeout ()), this , SLOT ( slotUpdateScheduledDisplayModels ()));
}
if ( ! m_resViewUpdateTimer -> isActive ())
{
m_resViewUpdateTimer -> setSingleShot ( true );
m_resViewUpdateTimer -> start ( 0 );
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiaApplication :: slotUpdateScheduledDisplayModels ()
{
// Compress to remove duplicates
2015-09-18 17:02:24 +02:00
// and update dependent views after independent views
std :: set < RimView *> independent3DViewsToUpdate ;
std :: set < RimView *> dependent3DViewsToUpdate ;
2013-10-08 14:28:01 +02:00
for ( size_t i = 0 ; i < m_resViewsToUpdate . size (); ++ i )
{
2015-10-23 14:13:14 +02:00
if ( ! m_resViewsToUpdate [ i ]) continue ;
2015-09-25 11:01:41 +02:00
if ( m_resViewsToUpdate [ i ] -> viewController ())
2015-09-18 17:02:24 +02:00
dependent3DViewsToUpdate . insert ( m_resViewsToUpdate [ i ]);
else
independent3DViewsToUpdate . insert ( m_resViewsToUpdate [ i ]);
}
for ( std :: set < RimView *>:: iterator it = independent3DViewsToUpdate . begin (); it != independent3DViewsToUpdate . end (); ++ it )
{
if ( * it )
{
( * it ) -> createDisplayModelAndRedraw ();
}
2013-10-08 14:28:01 +02:00
}
2015-09-18 17:02:24 +02:00
for ( std :: set < RimView *>:: iterator it = dependent3DViewsToUpdate . begin (); it != dependent3DViewsToUpdate . end (); ++ it )
2013-10-08 14:28:01 +02:00
{
if ( * it )
{
( * it ) -> createDisplayModelAndRedraw ();
}
}
2015-09-21 15:06:11 +02:00
m_resViewsToUpdate . clear ();
2013-10-08 14:28:01 +02:00
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiaApplication :: setCacheDataObject ( const QString & key , const QVariant & dataObject )
{
m_sessionCache [ key ] = dataObject ;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QVariant RiaApplication :: cacheDataObject ( const QString & key ) const
{
QMap < QString , QVariant >:: const_iterator it = m_sessionCache . find ( key );
if ( it != m_sessionCache . end ())
{
return it . value ();
}
return QVariant ();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiaApplication :: addCommandObject ( RimCommandObject * commandObject )
{
m_commandQueue . push_back ( commandObject );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiaApplication :: executeCommandObjects ()
{
std :: list < RimCommandObject * >:: iterator it = m_commandQueue . begin ();
while ( it != m_commandQueue . end ())
{
RimCommandObject * toBeRemoved = * it ;
if ( ! toBeRemoved -> isAsyncronous ())
{
toBeRemoved -> redo ();
2015-11-27 16:37:26 +01:00
++ it ;
2013-10-08 14:28:01 +02:00
m_commandQueue . remove ( toBeRemoved );
}
else
{
2015-11-27 16:37:26 +01:00
++ it ;
2013-10-08 14:28:01 +02:00
}
}
2015-11-27 16:37:26 +01:00
if ( ! m_commandQueue . empty ())
2013-10-08 14:28:01 +02:00
{
std :: list < RimCommandObject * >:: iterator it = m_commandQueue . begin ();
RimCommandObject * first = * it ;
first -> redo ();
m_commandQueue . pop_front ();
}
else
{
// Unlock the command queue lock when the command queue is empty
m_commandQueueLock . unlock ();
}
}
2015-06-26 13:44:16 +02:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RiaApplication :: isRunningRegressionTests () const
{
return m_runningRegressionTests ;
}
2013-10-08 14:28:01 +02:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiaApplication :: executeRegressionTests ( const QString & regressionTestPath )
{
RiuMainWindow * mainWnd = RiuMainWindow :: instance ();
if ( mainWnd )
{
mainWnd -> hideAllDockWindows ();
mainWnd -> setDefaultWindowSize ();
runRegressionTest ( regressionTestPath );
mainWnd -> loadWinGeoAndDockToolBarLayout ();
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
2014-01-23 13:17:49 +01:00
void RiaApplication :: regressionTestConfigureProject ()
2013-10-08 14:28:01 +02:00
{
RiuMainWindow * mainWnd = RiuMainWindow :: instance ();
if ( ! mainWnd ) return ;
if ( m_project . isNull ()) return ;
2015-05-15 18:51:49 +02:00
std :: vector < RimCase *> projectCases ;
2013-10-08 14:28:01 +02:00
m_project -> allCases ( projectCases );
for ( size_t i = 0 ; i < projectCases . size (); i ++ )
{
2015-05-15 18:51:49 +02:00
RimCase * cas = projectCases [ i ];
if ( ! cas ) continue ;
std :: vector < RimView *> views = cas -> views ();
2013-10-08 14:28:01 +02:00
2015-05-15 18:51:49 +02:00
for ( size_t j = 0 ; j < views . size (); j ++ )
2013-10-08 14:28:01 +02:00
{
2015-05-15 18:51:49 +02:00
RimView * riv = views [ j ];
2013-10-08 14:28:01 +02:00
if ( riv && riv -> viewer ())
{
2015-10-23 14:13:14 +02:00
// Make sure all views are maximized for snapshotting
QMdiSubWindow * subWnd = mainWnd -> findMdiSubWindow ( riv -> viewer () -> layoutWidget ());
if ( subWnd )
{
subWnd -> showMaximized ();
}
2013-10-08 14:28:01 +02:00
// This size is set to match the regression test reference images
2017-04-24 09:23:32 +02:00
riv -> viewer () -> setFixedSize ( RiaApplication :: regressionDefaultImageSize ());
2013-10-08 14:28:01 +02:00
}
}
}
}
2017-04-24 09:23:32 +02:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QSize RiaApplication :: regressionDefaultImageSize ()
{
return QSize ( 1000 , 745 );
}