Grid Calculator: refactor summary curve calculator and add grid calculator.

This commit is contained in:
Kristian Bendiksen 2022-04-22 12:18:34 +02:00
parent 621100f0cf
commit 4304bbbc48
52 changed files with 2493 additions and 1015 deletions

View File

@ -226,13 +226,17 @@ void RiaSummaryTools::getSummaryCasesAndAddressesForCalculation( int
RimSummaryCalculationCollection* calculationColl = proj->calculationCollection();
if ( !calculationColl ) return;
RimSummaryCalculation* calculation = calculationColl->findCalculationById( id );
RimUserDefinedCalculation* calculation = calculationColl->findCalculationById( id );
if ( !calculation ) return;
for ( RimSummaryCalculationVariable* v : calculation->allVariables() )
for ( RimUserDefinedCalculationVariable* v : calculation->allVariables() )
{
cases.push_back( v->summaryCase() );
addresses.push_back( v->summaryAddress()->address() );
RimSummaryCalculationVariable* scv = dynamic_cast<RimSummaryCalculationVariable*>( v );
if ( scv )
{
cases.push_back( scv->summaryCase() );
addresses.push_back( scv->summaryAddress()->address() );
}
}
}

View File

@ -78,6 +78,12 @@ set(SOURCE_GROUP_HEADER_FILES
${CMAKE_CURRENT_LIST_DIR}/RicCreateEnsembleWellLogUi.h
${CMAKE_CURRENT_LIST_DIR}/RicCreateSurfaceIntersectionBandFeature.h
${CMAKE_CURRENT_LIST_DIR}/RicCreateSurfaceIntersectionCurveFeature.h
${CMAKE_CURRENT_LIST_DIR}/RicShowGridCalculatorFeature.h
${CMAKE_CURRENT_LIST_DIR}/RicUserDefinedCalculatorDialog.h
${CMAKE_CURRENT_LIST_DIR}/RicGridCalculatorDialog.h
${CMAKE_CURRENT_LIST_DIR}/RicGridCalculatorUi.h
${CMAKE_CURRENT_LIST_DIR}/RicCalculatorWidgetCreator.h
${CMAKE_CURRENT_LIST_DIR}/RicUserDefinedCalculatorUi.h
)
set(SOURCE_GROUP_SOURCE_FILES
@ -159,6 +165,12 @@ set(SOURCE_GROUP_SOURCE_FILES
${CMAKE_CURRENT_LIST_DIR}/RicCreateEnsembleWellLogUi.cpp
${CMAKE_CURRENT_LIST_DIR}/RicCreateSurfaceIntersectionBandFeature.cpp
${CMAKE_CURRENT_LIST_DIR}/RicCreateSurfaceIntersectionCurveFeature.cpp
${CMAKE_CURRENT_LIST_DIR}/RicShowGridCalculatorFeature.cpp
${CMAKE_CURRENT_LIST_DIR}/RicUserDefinedCalculatorDialog.cpp
${CMAKE_CURRENT_LIST_DIR}/RicGridCalculatorDialog.cpp
${CMAKE_CURRENT_LIST_DIR}/RicGridCalculatorUi.cpp
${CMAKE_CURRENT_LIST_DIR}/RicCalculatorWidgetCreator.cpp
${CMAKE_CURRENT_LIST_DIR}/RicUserDefinedCalculatorUi.cpp
)
if(RESINSIGHT_USE_QT_CHARTS)
@ -185,6 +197,9 @@ list(
${CMAKE_CURRENT_LIST_DIR}/RicRecursiveFileSearchDialog.h
${CMAKE_CURRENT_LIST_DIR}/RicSummaryCaseRestartDialog.h
${CMAKE_CURRENT_LIST_DIR}/RicResampleDialog.h
${CMAKE_CURRENT_LIST_DIR}/RicUserDefinedCalculatorDialog.h
${CMAKE_CURRENT_LIST_DIR}/RicGridCalculatorDialog.h
${CMAKE_CURRENT_LIST_DIR}/RicCalculatorWidgetCreator.h
)
source_group(

View File

@ -16,10 +16,11 @@
//
/////////////////////////////////////////////////////////////////////////////////
#include "RicSummaryCurveCalculatorWidgetCreator.h"
#include "RicCalculatorWidgetCreator.h"
#include "RicSummaryCurveCalculatorUi.h"
#include "RimSummaryCalculation.h"
#include "RimUserDefinedCalculation.h"
#include "RicUserDefinedCalculatorUi.h"
#include "cafPdmUiTableView.h"
@ -34,18 +35,17 @@
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RicSummaryCurveCalculatorWidgetCreator::RicSummaryCurveCalculatorWidgetCreator()
RicCalculatorWidgetCreator::RicCalculatorWidgetCreator( std::unique_ptr<RicUserDefinedCalculatorUi> calculator )
: m_pdmTableView( nullptr )
{
m_calculator = std::unique_ptr<RicSummaryCurveCalculatorUi>( new RicSummaryCurveCalculatorUi );
m_calculator = std::move( calculator );
this->setPdmObject( m_calculator.get() );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RicSummaryCurveCalculatorWidgetCreator::~RicSummaryCurveCalculatorWidgetCreator()
RicCalculatorWidgetCreator::~RicCalculatorWidgetCreator()
{
if ( m_pdmTableView )
{
@ -61,9 +61,8 @@ RicSummaryCurveCalculatorWidgetCreator::~RicSummaryCurveCalculatorWidgetCreator(
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RicSummaryCurveCalculatorWidgetCreator::recursivelyConfigureAndUpdateTopLevelUiOrdering(
const caf::PdmUiOrdering& topLevelUiOrdering,
const QString& uiConfigName )
void RicCalculatorWidgetCreator::recursivelyConfigureAndUpdateTopLevelUiOrdering( const caf::PdmUiOrdering& topLevelUiOrdering,
const QString& uiConfigName )
{
if ( !m_firstRowLeftLayout || !m_firstRowRightLayout ) return;
@ -79,11 +78,11 @@ void RicSummaryCurveCalculatorWidgetCreator::recursivelyConfigureAndUpdateTopLev
caf::PdmUiGroup* group = static_cast<caf::PdmUiGroup*>( topLevelUiItems[i] );
auto groupBox = updateGroupBoxWithContent( group, uiConfigName );
if ( group->keyword() == RicSummaryCurveCalculatorUi::calculatedSummariesGroupName() )
if ( group->keyword() == m_calculator->calculationsGroupName() )
{
m_firstRowLeftLayout->addWidget( groupBox );
}
else if ( group->keyword() == RicSummaryCurveCalculatorUi::calulationGroupName() )
else if ( group->keyword() == m_calculator->calulationGroupName() )
{
m_firstRowRightLayout->insertWidget( layoutItemIndex++, groupBox );
}
@ -117,7 +116,7 @@ void RicSummaryCurveCalculatorWidgetCreator::recursivelyConfigureAndUpdateTopLev
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QWidget* RicSummaryCurveCalculatorWidgetCreator::createWidget( QWidget* parent )
QWidget* RicCalculatorWidgetCreator::createWidget( QWidget* parent )
{
m_pdmTableView = new caf::PdmUiTableView( parent );
m_pdmTableView->tableView()->setSelectionMode( QAbstractItemView::ExtendedSelection );
@ -182,8 +181,7 @@ QWidget* RicSummaryCurveCalculatorWidgetCreator::createWidget( QWidget* parent )
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QMinimizePanel* RicSummaryCurveCalculatorWidgetCreator::updateGroupBoxWithContent( caf::PdmUiGroup* group,
const QString& uiConfigName )
QMinimizePanel* RicCalculatorWidgetCreator::updateGroupBoxWithContent( caf::PdmUiGroup* group, const QString& uiConfigName )
{
QMinimizePanel* groupBox = findOrCreateGroupBox( this->widget(), group, uiConfigName );
@ -194,7 +192,7 @@ QMinimizePanel* RicSummaryCurveCalculatorWidgetCreator::updateGroupBoxWithConten
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RicSummaryCurveCalculatorUi* RicSummaryCurveCalculatorWidgetCreator::calculator() const
RicUserDefinedCalculatorUi* RicCalculatorWidgetCreator::calculator() const
{
return m_calculator.get();
}
@ -202,7 +200,7 @@ RicSummaryCurveCalculatorUi* RicSummaryCurveCalculatorWidgetCreator::calculator(
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RicSummaryCurveCalculatorWidgetCreator::slotCalculate()
void RicCalculatorWidgetCreator::slotCalculate()
{
m_calculator->calculate();
@ -212,7 +210,7 @@ void RicSummaryCurveCalculatorWidgetCreator::slotCalculate()
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RicSummaryCurveCalculatorWidgetCreator::slotParseExpression()
void RicCalculatorWidgetCreator::slotParseExpression()
{
m_calculator->parseExpression();

View File

@ -23,7 +23,7 @@
#include <memory>
#include <vector>
class RicSummaryCurveCalculatorUi;
class RicUserDefinedCalculatorUi;
class QMinimizePanel;
class QString;
@ -41,15 +41,15 @@ class PdmUiTableView;
///
///
//==================================================================================================
class RicSummaryCurveCalculatorWidgetCreator : public caf::PdmUiFormLayoutObjectEditor
class RicCalculatorWidgetCreator : public caf::PdmUiFormLayoutObjectEditor
{
Q_OBJECT
public:
RicSummaryCurveCalculatorWidgetCreator();
~RicSummaryCurveCalculatorWidgetCreator() override;
RicCalculatorWidgetCreator( std::unique_ptr<RicUserDefinedCalculatorUi> calculator );
~RicCalculatorWidgetCreator() override;
RicSummaryCurveCalculatorUi* calculator() const;
RicUserDefinedCalculatorUi* calculator() const;
private:
void recursivelyConfigureAndUpdateTopLevelUiOrdering( const caf::PdmUiOrdering& topLevelUiItems,
@ -72,5 +72,5 @@ private:
caf::PdmUiTableView* m_pdmTableView;
std::unique_ptr<RicSummaryCurveCalculatorUi> m_calculator;
std::unique_ptr<RicUserDefinedCalculatorUi> m_calculator;
};

View File

@ -0,0 +1,83 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2022- Equinor ASA
//
// 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 "RicGridCalculatorDialog.h"
#include "RicCalculatorWidgetCreator.h"
#include "RicGridCalculatorUi.h"
#include "RimGridCalculation.h"
#include "RimGridCalculationCollection.h"
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RicGridCalculatorDialog::RicGridCalculatorDialog( QWidget* parent )
: RicUserDefinedCalculatorDialog( parent, "Grid Calculator" )
{
setUp();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RicGridCalculatorDialog::~RicGridCalculatorDialog()
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RicGridCalculatorDialog::setCalculationAndUpdateUi( RimUserDefinedCalculation* calculation )
{
CAF_ASSERT( m_calcEditor );
m_calcEditor->calculator()->setCurrentCalculation( calculation );
updateUi();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RicGridCalculatorDialog::updateUi()
{
CAF_ASSERT( m_calcEditor );
m_calcEditor->updateUi();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimUserDefinedCalculationCollection* RicGridCalculatorDialog::calculationCollection() const
{
CAF_ASSERT( m_calcEditor );
return m_calcEditor->calculator()->calculationCollection();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QWidget* RicGridCalculatorDialog::getCalculatorWidget()
{
if ( !m_calcEditor )
{
m_calcEditor = std::unique_ptr<RicCalculatorWidgetCreator>(
new RicCalculatorWidgetCreator( std::make_unique<RicGridCalculatorUi>() ) );
}
return m_calcEditor->getOrCreateWidget( this );
}

View File

@ -0,0 +1,46 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2022- Equinor ASA
//
// 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.
//
/////////////////////////////////////////////////////////////////////////////////
#pragma once
#include "RicUserDefinedCalculatorDialog.h"
#include <memory>
class RicCalculatorWidgetCreator;
//==================================================================================================
///
///
//==================================================================================================
class RicGridCalculatorDialog : public RicUserDefinedCalculatorDialog
{
Q_OBJECT
public:
RicGridCalculatorDialog( QWidget* parent );
~RicGridCalculatorDialog() override;
void setCalculationAndUpdateUi( RimUserDefinedCalculation* calculation ) override;
QWidget* getCalculatorWidget() override;
void updateUi() override;
RimUserDefinedCalculationCollection* calculationCollection() const override;
private:
std::unique_ptr<RicCalculatorWidgetCreator> m_calcEditor;
};

View File

@ -0,0 +1,64 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2022- Equinor ASA
//
// 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 "RicGridCalculatorUi.h"
#include "RimGridCalculationCollection.h"
#include "RimProject.h"
#include "RimUserDefinedCalculationCollection.h"
CAF_PDM_SOURCE_INIT( RicGridCalculatorUi, "RicGridCalculator" );
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RicGridCalculatorUi::RicGridCalculatorUi()
{
CAF_PDM_InitObject( "RicGridCalculator" );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RicGridCalculatorUi::calculationsGroupName() const
{
return "CalculationsGroupName";
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RicGridCalculatorUi::calulationGroupName() const
{
return "CalulationGroupName";
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RicGridCalculatorUi::notifyCalculatedNameChanged( int id, const QString& newName ) const
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimUserDefinedCalculationCollection* RicGridCalculatorUi::calculationCollection() const
{
return RimProject::current()->gridCalculationCollection();
}

View File

@ -0,0 +1,39 @@
//////////////////////////// /////////////////////////////////////////////////////
//
// Copyright (C) 2022- Equinor ASA
//
// 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.
//
/////////////////////////////////////////////////////////////////////////////////
#pragma once
#include "RicUserDefinedCalculatorUi.h"
class RimUserDefinedCalculationCollection;
//==================================================================================================
///
//==================================================================================================
class RicGridCalculatorUi : public RicUserDefinedCalculatorUi
{
CAF_PDM_HEADER_INIT;
public:
RicGridCalculatorUi();
QString calculationsGroupName() const override;
QString calulationGroupName() const override;
RimUserDefinedCalculationCollection* calculationCollection() const override;
void notifyCalculatedNameChanged( int id, const QString& newName ) const override;
};

View File

@ -54,7 +54,7 @@ void RicReplaceSummaryCaseFeature::updateRequredCalculatedCurves( RimSummaryCase
{
RimSummaryCalculationCollection* calcColl = RimProject::current()->calculationCollection();
for ( RimSummaryCalculation* summaryCalculation : calcColl->calculations() )
for ( RimUserDefinedCalculation* summaryCalculation : calcColl->calculations() )
{
bool needsUpdate =
RicReplaceSummaryCaseFeature::checkIfCalculationNeedsUpdate( summaryCalculation, sourceSummaryCase );
@ -62,7 +62,7 @@ void RicReplaceSummaryCaseFeature::updateRequredCalculatedCurves( RimSummaryCase
{
summaryCalculation->parseExpression();
summaryCalculation->calculate();
summaryCalculation->updateDependentCurvesAndPlots();
summaryCalculation->updateDependentObjects();
}
}
}
@ -102,7 +102,7 @@ void RicReplaceSummaryCaseFeature::onActionTriggered( bool isChecked )
// Find and update all changed calculations
std::set<int> ids;
RimSummaryCalculationCollection* calcColl = RimProject::current()->calculationCollection();
for ( RimSummaryCalculation* summaryCalculation : calcColl->calculations() )
for ( RimUserDefinedCalculation* summaryCalculation : calcColl->calculations() )
{
bool needsUpdate = checkIfCalculationNeedsUpdate( summaryCalculation, summaryCase );
if ( needsUpdate )
@ -126,8 +126,8 @@ void RicReplaceSummaryCaseFeature::onActionTriggered( bool isChecked )
{
if ( calcColl )
{
RimSummaryCalculation* calculation = calcColl->findCalculationById( summaryAddressY.id() );
QString description = calculation->description();
RimUserDefinedCalculation* calculation = calcColl->findCalculationById( summaryAddressY.id() );
QString description = calculation->description();
RifEclipseSummaryAddress updatedAdr =
RifEclipseSummaryAddress::calculatedAddress( description.toStdString(), calculation->id() );
@ -154,8 +154,8 @@ void RicReplaceSummaryCaseFeature::onActionTriggered( bool isChecked )
{
if ( calcColl )
{
RimSummaryCalculation* calculation = calcColl->findCalculationById( summaryAddressX.id() );
QString description = calculation->description();
RimUserDefinedCalculation* calculation = calcColl->findCalculationById( summaryAddressX.id() );
QString description = calculation->description();
RifEclipseSummaryAddress updatedAdr =
RifEclipseSummaryAddress::calculatedAddress( description.toStdString(), calculation->id() );
@ -170,8 +170,8 @@ void RicReplaceSummaryCaseFeature::onActionTriggered( bool isChecked )
{
if ( calcColl )
{
RimSummaryCalculation* calculation = calcColl->findCalculationById( summaryAddressX.id() );
QString description = calculation->description();
RimUserDefinedCalculation* calculation = calcColl->findCalculationById( summaryAddressX.id() );
QString description = calculation->description();
RifEclipseSummaryAddress updatedAdr =
RifEclipseSummaryAddress::calculatedAddress( description.toStdString(), calculation->id() );
@ -197,13 +197,14 @@ void RicReplaceSummaryCaseFeature::setupActionLook( QAction* actionToSetup )
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RicReplaceSummaryCaseFeature::checkIfCalculationNeedsUpdate( const RimSummaryCalculation* summaryCalculation,
const RimSummaryCase* summaryCase )
bool RicReplaceSummaryCaseFeature::checkIfCalculationNeedsUpdate( const RimUserDefinedCalculation* summaryCalculation,
const RimSummaryCase* summaryCase )
{
std::vector<RimSummaryCalculationVariable*> variables = summaryCalculation->allVariables();
for ( RimSummaryCalculationVariable* variable : variables )
std::vector<RimUserDefinedCalculationVariable*> variables = summaryCalculation->allVariables();
for ( RimUserDefinedCalculationVariable* variable : variables )
{
if ( variable->summaryCase() == summaryCase )
RimSummaryCalculationVariable* summaryVariable = dynamic_cast<RimSummaryCalculationVariable*>( variable );
if ( summaryVariable->summaryCase() == summaryCase )
{
return true;
}

View File

@ -20,7 +20,7 @@
#include "cafCmdFeature.h"
class RimSummaryCalculation;
class RimUserDefinedCalculation;
class RimSummaryCase;
class RicReplaceSummaryCaseFeature : public caf::CmdFeature
@ -35,6 +35,6 @@ protected:
void onActionTriggered( bool isChecked ) override;
void setupActionLook( QAction* actionToSetup ) override;
static bool checkIfCalculationNeedsUpdate( const RimSummaryCalculation* summaryCalculation,
const RimSummaryCase* summaryCase );
static bool checkIfCalculationNeedsUpdate( const RimUserDefinedCalculation* summaryCalculation,
const RimSummaryCase* summaryCase );
};

View File

@ -0,0 +1,94 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2022 Equinor ASA
//
// 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 "RicShowGridCalculatorFeature.h"
#include "RicGridCalculatorDialog.h"
#include "RiaGuiApplication.h"
#include "RimGridCalculationCollection.h"
#include "RimProject.h"
#include "RimSummaryCalculationCollection.h"
#include "RiuMainWindow.h"
#include <QAction>
CAF_CMD_SOURCE_INIT( RicShowGridCalculatorFeature, "RicShowGridCalculatorFeature" );
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RicGridCalculatorDialog* RicShowGridCalculatorFeature::gridCalculatorDialog( bool createIfNotPresent )
{
RiuMainWindow* mainWindow = RiaGuiApplication::instance()->mainWindow();
if ( mainWindow )
{
return mainWindow->gridCalculatorDialog( createIfNotPresent );
}
return nullptr;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RicShowGridCalculatorFeature::hideGridCalculatorDialog()
{
auto dialog = RicShowGridCalculatorFeature::gridCalculatorDialog( false );
if ( dialog ) dialog->hide();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RicShowGridCalculatorFeature::isCommandEnabled()
{
return true;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RicShowGridCalculatorFeature::onActionTriggered( bool isChecked )
{
RicGridCalculatorDialog* dialog = RicShowGridCalculatorFeature::gridCalculatorDialog( true );
RimProject* proj = RimProject::current();
RimGridCalculationCollection* calcColl = proj->gridCalculationCollection();
if ( calcColl->calculations().empty() )
{
calcColl->addCalculation();
}
dialog->setCalculationAndUpdateUi( calcColl->calculations()[0] );
dialog->show();
dialog->raise();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RicShowGridCalculatorFeature::setupActionLook( QAction* actionToSetup )
{
actionToSetup->setText( "Grid Calculator" );
actionToSetup->setIcon( QIcon( ":/Calculator.svg" ) );
}

View File

@ -0,0 +1,40 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2022 Equinor ASA
//
// 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.
//
/////////////////////////////////////////////////////////////////////////////////
#pragma once
#include "cafCmdFeature.h"
class RicGridCalculatorDialog;
//==================================================================================================
///
//==================================================================================================
class RicShowGridCalculatorFeature : public caf::CmdFeature
{
CAF_CMD_HEADER_INIT;
public:
static RicGridCalculatorDialog* gridCalculatorDialog( bool createIfNotPresent );
static void hideGridCalculatorDialog();
protected:
bool isCommandEnabled() override;
void onActionTriggered( bool isChecked ) override;
void setupActionLook( QAction* actionToSetup ) override;
};

View File

@ -0,0 +1,131 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2017- Statoil ASA
//
// 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 "RicUserDefinedCalculatorDialog.h"
#include "RiuTools.h"
#include "RimUserDefinedCalculation.h"
#include "RimUserDefinedCalculationCollection.h"
#include <QDialogButtonBox>
#include <QMessageBox>
#include <QVBoxLayout>
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RicUserDefinedCalculatorDialog::RicUserDefinedCalculatorDialog( QWidget* parent, const QString& title )
: QDialog( parent, RiuTools::defaultDialogFlags() )
{
setWindowTitle( title );
resize( 1200, 800 );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RicUserDefinedCalculatorDialog::~RicUserDefinedCalculatorDialog()
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RicUserDefinedCalculatorDialog::slotTryCloseDialog()
{
RimUserDefinedCalculationCollection* calcCollection = calculationCollection();
if ( dirtyCount() > 0 )
{
QMessageBox msgBox( this );
msgBox.setIcon( QMessageBox::Question );
QString questionText = QString( "Detected calculation expression text modifications." );
msgBox.setText( questionText );
msgBox.setInformativeText( "Do you want to trigger calculation?" );
msgBox.setStandardButtons( QMessageBox::Yes | QMessageBox::No );
int ret = msgBox.exec();
if ( ret == QMessageBox::No )
{
reject();
}
else if ( ret == QMessageBox::Yes )
{
for ( auto c : calcCollection->calculations() )
{
if ( c->isDirty() )
{
c->calculate();
c->updateDependentObjects();
}
}
if ( dirtyCount() > 0 )
{
return;
}
}
else
{
return;
}
}
accept();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RicUserDefinedCalculatorDialog::setUp()
{
QVBoxLayout* mainLayout = new QVBoxLayout( this );
mainLayout->setContentsMargins( 0, 0, 0, 0 );
QWidget* calcEditorWidget = getCalculatorWidget();
mainLayout->addWidget( calcEditorWidget );
QDialogButtonBox* buttonBox = new QDialogButtonBox( QDialogButtonBox::Close );
connect( buttonBox, SIGNAL( rejected() ), this, SLOT( slotTryCloseDialog() ) );
mainLayout->addWidget( buttonBox );
updateUi();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
size_t RicUserDefinedCalculatorDialog::dirtyCount() const
{
size_t count = 0;
RimUserDefinedCalculationCollection* calcCollection = calculationCollection();
for ( auto c : calcCollection->calculations() )
{
if ( c->isDirty() )
{
count++;
}
}
return count;
}

View File

@ -0,0 +1,49 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2017- Statoil ASA
//
// 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.
//
/////////////////////////////////////////////////////////////////////////////////
#pragma once
#include <QDialog>
class RimUserDefinedCalculation;
class RimUserDefinedCalculationCollection;
//==================================================================================================
///
///
//==================================================================================================
class RicUserDefinedCalculatorDialog : public QDialog
{
Q_OBJECT
public:
RicUserDefinedCalculatorDialog( QWidget* parent, const QString& title );
~RicUserDefinedCalculatorDialog() override;
virtual void setCalculationAndUpdateUi( RimUserDefinedCalculation* calculation ) = 0;
virtual RimUserDefinedCalculationCollection* calculationCollection() const = 0;
virtual QWidget* getCalculatorWidget() = 0;
virtual void updateUi() = 0;
private slots:
void slotTryCloseDialog();
protected:
void setUp();
size_t dirtyCount() const;
};

View File

@ -0,0 +1,260 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2017- Statoil ASA
//
// 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 "RicUserDefinedCalculatorUi.h"
#include "RimUserDefinedCalculation.h"
#include "RimUserDefinedCalculationCollection.h"
#include "cafAssert.h"
#include "cafPdmUiListEditor.h"
#include "cafPdmUiObjectEditorHandle.h"
#include "cafPdmUiPushButtonEditor.h"
#include "cafPdmUiTreeSelectionEditor.h"
CAF_PDM_ABSTRACT_SOURCE_INIT( RicUserDefinedCalculatorUi, "RicUserDefinedCalculator" );
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RicUserDefinedCalculatorUi::RicUserDefinedCalculatorUi()
{
CAF_PDM_InitObject( "RicUserDefinedCalculator" );
CAF_PDM_InitFieldNoDefault( &m_currentCalculation, "CurrentCalculation", "" );
m_currentCalculation.uiCapability()->setUiLabelPosition( caf::PdmUiItemInfo::HIDDEN );
// m_currentCalculation.uiCapability()->setUiEditorTypeName(caf::PdmUiTreeSelectionEditor::uiEditorTypeName());
m_currentCalculation.uiCapability()->setUiEditorTypeName( caf::PdmUiListEditor::uiEditorTypeName() );
CAF_PDM_InitFieldNoDefault( &m_newCalculation, "NewCalculation", "New Calculation" );
RicUserDefinedCalculatorUi::assignPushButtonEditor( &m_newCalculation );
CAF_PDM_InitFieldNoDefault( &m_deleteCalculation, "DeleteCalculation", "Delete Calculation" );
RicUserDefinedCalculatorUi::assignPushButtonEditor( &m_deleteCalculation );
m_calcContextMenuMgr = std::unique_ptr<RiuCalculationsContextMenuManager>( new RiuCalculationsContextMenuManager() );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimUserDefinedCalculation* RicUserDefinedCalculatorUi::currentCalculation() const
{
return m_currentCalculation();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RicUserDefinedCalculatorUi::setCurrentCalculation( RimUserDefinedCalculation* calculation )
{
m_currentCalculation = calculation;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RicUserDefinedCalculatorUi::parseExpression() const
{
if ( m_currentCalculation() )
{
QString previousCurveName = m_currentCalculation->description();
if ( !m_currentCalculation()->parseExpression() )
{
return false;
}
QString currentCurveName = m_currentCalculation->description();
if ( previousCurveName != currentCurveName )
{
notifyCalculatedNameChanged( m_currentCalculation()->id(), currentCurveName );
}
m_currentCalculation()->updateDependentObjects();
}
return true;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RicUserDefinedCalculatorUi::fieldChangedByUi( const caf::PdmFieldHandle* changedField,
const QVariant& oldValue,
const QVariant& newValue )
{
if ( changedField == &m_newCalculation )
{
m_newCalculation = false;
m_currentCalculation = calculationCollection()->addCalculation();
this->updateConnectedEditors();
}
else if ( changedField == &m_deleteCalculation )
{
m_deleteCalculation = false;
if ( m_currentCalculation() )
{
calculationCollection()->deleteCalculation( m_currentCalculation() );
m_currentCalculation = nullptr;
this->updateConnectedEditors();
caf::PdmUiObjectEditorHandle::updateUiAllObjectEditors();
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RicUserDefinedCalculatorUi::defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering )
{
if ( !m_currentCalculation() && !calculationCollection()->calculations().empty() )
{
m_currentCalculation = calculationCollection()->calculations()[0];
}
{
caf::PdmUiGroup* group = uiOrdering.addNewGroupWithKeyword( "Calculated Summaries", calculationsGroupName() );
group->add( &m_currentCalculation );
group->add( &m_newCalculation );
group->add( &m_deleteCalculation );
}
{
caf::PdmUiGroup* group = uiOrdering.addNewGroupWithKeyword( "Calculation Settings", calulationGroupName() );
if ( m_currentCalculation() )
{
m_currentCalculation->uiOrdering( uiConfigName, *group );
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QList<caf::PdmOptionItemInfo>
RicUserDefinedCalculatorUi::calculateValueOptions( const caf::PdmFieldHandle* fieldNeedingOptions, bool* useOptionsOnly )
{
QList<caf::PdmOptionItemInfo> options;
if ( fieldNeedingOptions == &m_currentCalculation )
{
for ( auto c : calculationCollection()->calculations() )
{
options.push_back( caf::PdmOptionItemInfo( c->description(), c ) );
}
}
return options;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RicUserDefinedCalculatorUi::assignPushButtonEditor( caf::PdmFieldHandle* fieldHandle )
{
CAF_ASSERT( fieldHandle );
CAF_ASSERT( fieldHandle->uiCapability() );
fieldHandle->uiCapability()->setUiEditorTypeName( caf::PdmUiPushButtonEditor::uiEditorTypeName() );
fieldHandle->uiCapability()->setUiLabelPosition( caf::PdmUiItemInfo::HIDDEN );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RicUserDefinedCalculatorUi::assignPushButtonEditorText( caf::PdmUiEditorAttribute* attribute, const QString& text )
{
caf::PdmUiPushButtonEditorAttribute* attrib = dynamic_cast<caf::PdmUiPushButtonEditorAttribute*>( attribute );
if ( attrib )
{
attrib->m_buttonText = text;
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RicUserDefinedCalculatorUi::calculate() const
{
if ( m_currentCalculation() )
{
QString previousCurveName = m_currentCalculation->description();
if ( !m_currentCalculation()->parseExpression() )
{
return false;
}
QString currentCurveName = m_currentCalculation->description();
if ( previousCurveName != currentCurveName )
{
notifyCalculatedNameChanged( m_currentCalculation()->id(), currentCurveName );
}
if ( !m_currentCalculation()->calculate() )
{
return false;
}
m_currentCalculation()->updateDependentObjects();
caf::PdmUiObjectEditorHandle::updateUiAllObjectEditors();
}
return true;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RicUserDefinedCalculatorUi::defineEditorAttribute( const caf::PdmFieldHandle* field,
QString uiConfigName,
caf::PdmUiEditorAttribute* attribute )
{
if ( &m_newCalculation == field )
{
RicUserDefinedCalculatorUi::assignPushButtonEditorText( attribute, "New Calculation" );
}
else if ( &m_deleteCalculation == field )
{
RicUserDefinedCalculatorUi::assignPushButtonEditorText( attribute, "Delete Calculation" );
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RicUserDefinedCalculatorUi::onEditorWidgetsCreated()
{
if ( m_currentCalculation() != nullptr )
{
m_currentCalculation->attachToWidget();
}
for ( const auto& e : m_currentCalculation.uiCapability()->connectedEditors() )
{
caf::PdmUiListEditor* listEditor = dynamic_cast<caf::PdmUiListEditor*>( e );
if ( !listEditor ) continue;
QWidget* widget = listEditor->editorWidget();
if ( !widget ) continue;
m_calcContextMenuMgr->attachWidget( widget, this );
}
}

View File

@ -0,0 +1,73 @@
//////////////////////////// /////////////////////////////////////////////////////
//
// Copyright (C) 2017- Statoil ASA
//
// 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.
//
/////////////////////////////////////////////////////////////////////////////////
#pragma once
#include "RiuCalculationsContextMenuManager.h"
#include "cafPdmField.h"
#include "cafPdmObject.h"
#include "cafPdmPtrField.h"
#include <memory>
class RimUserDefinedCalculationCollection;
class RimUserDefinedCalculation;
//==================================================================================================
///
//==================================================================================================
class RicUserDefinedCalculatorUi : public caf::PdmObject
{
CAF_PDM_HEADER_INIT;
public:
RicUserDefinedCalculatorUi();
RimUserDefinedCalculation* currentCalculation() const;
void setCurrentCalculation( RimUserDefinedCalculation* calculation );
bool parseExpression() const;
bool calculate() const;
virtual QString calculationsGroupName() const = 0;
virtual QString calulationGroupName() const = 0;
virtual RimUserDefinedCalculationCollection* calculationCollection() const = 0;
virtual void notifyCalculatedNameChanged( int id, const QString& newName ) const = 0;
private:
void fieldChangedByUi( const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue ) override;
void defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ) override;
QList<caf::PdmOptionItemInfo> calculateValueOptions( const caf::PdmFieldHandle* fieldNeedingOptions,
bool* useOptionsOnly ) override;
void defineEditorAttribute( const caf::PdmFieldHandle* field,
QString uiConfigName,
caf::PdmUiEditorAttribute* attribute ) override;
void onEditorWidgetsCreated() override;
private:
// TODO : Move to a common caf helper class
static void assignPushButtonEditor( caf::PdmFieldHandle* fieldHandle );
static void assignPushButtonEditorText( caf::PdmUiEditorAttribute* attribute, const QString& text );
private:
caf::PdmPtrField<RimUserDefinedCalculation*> m_currentCalculation;
caf::PdmField<bool> m_newCalculation;
caf::PdmField<bool> m_deleteCalculation;
std::unique_ptr<RiuCalculationsContextMenuManager> m_calcContextMenuMgr;
};

View File

@ -29,7 +29,6 @@ set(SOURCE_GROUP_HEADER_FILES
${CMAKE_CURRENT_LIST_DIR}/RicShowSummaryCurveCalculatorFeature.h
${CMAKE_CURRENT_LIST_DIR}/RicEditSummaryCurveCalculationFeature.h
${CMAKE_CURRENT_LIST_DIR}/RicSummaryCurveCalculatorDialog.h
${CMAKE_CURRENT_LIST_DIR}/RicSummaryCurveCalculatorWidgetCreator.h
${CMAKE_CURRENT_LIST_DIR}/RicSummaryCurveCalculatorUi.h
${CMAKE_CURRENT_LIST_DIR}/RicNewSummaryCrossPlotCurveFeature.h
${CMAKE_CURRENT_LIST_DIR}/RicNewSummaryEnsembleCurveSetFeature.h
@ -76,7 +75,6 @@ set(SOURCE_GROUP_SOURCE_FILES
${CMAKE_CURRENT_LIST_DIR}/RicShowSummaryCurveCalculatorFeature.cpp
${CMAKE_CURRENT_LIST_DIR}/RicEditSummaryCurveCalculationFeature.cpp
${CMAKE_CURRENT_LIST_DIR}/RicSummaryCurveCalculatorDialog.cpp
${CMAKE_CURRENT_LIST_DIR}/RicSummaryCurveCalculatorWidgetCreator.cpp
${CMAKE_CURRENT_LIST_DIR}/RicSummaryCurveCalculatorUi.cpp
${CMAKE_CURRENT_LIST_DIR}/RicNewSummaryCrossPlotCurveFeature.cpp
${CMAKE_CURRENT_LIST_DIR}/RicNewSummaryEnsembleCurveSetFeature.cpp
@ -101,7 +99,6 @@ list(
COMMAND_QT_MOC_HEADERS
${CMAKE_CURRENT_LIST_DIR}/RicSummaryPlotEditorWidgetCreator.h
${CMAKE_CURRENT_LIST_DIR}/RicSummaryPlotEditorDialog.h
${CMAKE_CURRENT_LIST_DIR}/RicSummaryCurveCalculatorWidgetCreator.h
${CMAKE_CURRENT_LIST_DIR}/RicSummaryCurveCalculatorDialog.h
)

View File

@ -55,7 +55,7 @@ bool RicEditSummaryCurveCalculationFeature::isCommandEnabled()
void RicEditSummaryCurveCalculationFeature::onActionTriggered( bool isChecked )
{
std::vector<RimSummaryCurve*> selectedCurves = caf::selectedObjectsByType<RimSummaryCurve*>();
RimSummaryCalculation* calculation = nullptr;
RimUserDefinedCalculation* calculation = nullptr;
if ( selectedCurves.size() > 0 )
{

View File

@ -77,7 +77,7 @@ void RicShowSummaryCurveCalculatorFeature::onActionTriggered( bool isChecked )
RimProject* proj = RimProject::current();
RimSummaryCalculationCollection* calcColl = proj->calculationCollection();
if ( calcColl->calculations().size() == 0 )
if ( calcColl->calculations().empty() )
{
calcColl->addCalculation();
}

View File

@ -18,27 +18,18 @@
#include "RicSummaryCurveCalculatorDialog.h"
#include "RicCalculatorWidgetCreator.h"
#include "RicSummaryCurveCalculatorUi.h"
#include "RicSummaryCurveCalculatorWidgetCreator.h"
#include "RimSummaryCalculation.h"
#include "RimSummaryCalculationCollection.h"
#include "RiuTools.h"
#include <QDialogButtonBox>
#include <QMessageBox>
#include <QVBoxLayout>
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RicSummaryCurveCalculatorDialog::RicSummaryCurveCalculatorDialog( QWidget* parent )
: QDialog( parent, RiuTools::defaultDialogFlags() )
: RicUserDefinedCalculatorDialog( parent, "Summary Curve Calculator" )
{
setWindowTitle( "Summary Curve Calculator" );
resize( 1200, 800 );
setUp();
}
@ -52,96 +43,41 @@ RicSummaryCurveCalculatorDialog::~RicSummaryCurveCalculatorDialog()
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RicSummaryCurveCalculatorDialog::setCalculationAndUpdateUi( RimSummaryCalculation* calculation )
void RicSummaryCurveCalculatorDialog::setCalculationAndUpdateUi( RimUserDefinedCalculation* calculation )
{
m_summaryCalcEditor->calculator()->setCurrentCalculation( calculation );
CAF_ASSERT( m_summaryCalcEditor );
m_summaryCalcEditor->calculator()->setCurrentCalculation( dynamic_cast<RimSummaryCalculation*>( calculation ) );
updateUi();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RicSummaryCurveCalculatorDialog::updateUi()
{
CAF_ASSERT( m_summaryCalcEditor );
m_summaryCalcEditor->updateUi();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RicSummaryCurveCalculatorDialog::slotTryCloseDialog()
RimUserDefinedCalculationCollection* RicSummaryCurveCalculatorDialog::calculationCollection() const
{
RimSummaryCalculationCollection* calculationCollection = RicSummaryCurveCalculatorUi::calculationCollection();
if ( dirtyCount() > 0 )
{
QMessageBox msgBox( this );
msgBox.setIcon( QMessageBox::Question );
QString questionText = QString( "Detected calculation expression text modifications." );
msgBox.setText( questionText );
msgBox.setInformativeText( "Do you want to trigger calculation?" );
msgBox.setStandardButtons( QMessageBox::Yes | QMessageBox::No );
int ret = msgBox.exec();
if ( ret == QMessageBox::No )
{
reject();
}
else if ( ret == QMessageBox::Yes )
{
for ( auto c : calculationCollection->calculations() )
{
if ( c->isDirty() )
{
c->calculate();
c->updateDependentCurvesAndPlots();
}
}
if ( dirtyCount() > 0 )
{
return;
}
}
else
{
return;
}
}
accept();
CAF_ASSERT( m_summaryCalcEditor );
return m_summaryCalcEditor->calculator()->calculationCollection();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RicSummaryCurveCalculatorDialog::setUp()
QWidget* RicSummaryCurveCalculatorDialog::getCalculatorWidget()
{
QVBoxLayout* mainLayout = new QVBoxLayout( this );
mainLayout->setContentsMargins( 0, 0, 0, 0 );
m_summaryCalcEditor =
std::unique_ptr<RicSummaryCurveCalculatorWidgetCreator>( new RicSummaryCurveCalculatorWidgetCreator() );
mainLayout->addWidget( m_summaryCalcEditor->getOrCreateWidget( this ) );
QDialogButtonBox* buttonBox = new QDialogButtonBox( QDialogButtonBox::Close );
connect( buttonBox, SIGNAL( rejected() ), this, SLOT( slotTryCloseDialog() ) );
mainLayout->addWidget( buttonBox );
m_summaryCalcEditor->updateUi();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
size_t RicSummaryCurveCalculatorDialog::dirtyCount() const
{
size_t count = 0;
RimSummaryCalculationCollection* calculationCollection = RicSummaryCurveCalculatorUi::calculationCollection();
for ( auto c : calculationCollection->calculations() )
if ( !m_summaryCalcEditor )
{
if ( c->isDirty() )
{
count++;
}
m_summaryCalcEditor = std::unique_ptr<RicCalculatorWidgetCreator>(
new RicCalculatorWidgetCreator( std::make_unique<RicSummaryCurveCalculatorUi>() ) );
}
return count;
return m_summaryCalcEditor->getOrCreateWidget( this );
}

View File

@ -18,17 +18,17 @@
#pragma once
#include <QDialog>
#include "RicUserDefinedCalculatorDialog.h"
#include <memory>
class RicSummaryCurveCalculatorWidgetCreator;
class RimSummaryCalculation;
class RicCalculatorWidgetCreator;
//==================================================================================================
///
///
//==================================================================================================
class RicSummaryCurveCalculatorDialog : public QDialog
class RicSummaryCurveCalculatorDialog : public RicUserDefinedCalculatorDialog
{
Q_OBJECT
@ -36,15 +36,11 @@ public:
RicSummaryCurveCalculatorDialog( QWidget* parent );
~RicSummaryCurveCalculatorDialog() override;
void setCalculationAndUpdateUi( RimSummaryCalculation* calculation );
private slots:
void slotTryCloseDialog();
void setCalculationAndUpdateUi( RimUserDefinedCalculation* calculation ) override;
QWidget* getCalculatorWidget() override;
void updateUi() override;
RimUserDefinedCalculationCollection* calculationCollection() const override;
private:
void setUp();
size_t dirtyCount() const;
private:
std::unique_ptr<RicSummaryCurveCalculatorWidgetCreator> m_summaryCalcEditor;
std::unique_ptr<RicCalculatorWidgetCreator> m_summaryCalcEditor;
};

View File

@ -21,13 +21,9 @@
#include "RiaSummaryTools.h"
#include "RimProject.h"
#include "RimSummaryCalculation.h"
#include "RimSummaryCalculationCollection.h"
#include "cafPdmUiListEditor.h"
#include "cafPdmUiObjectEditorHandle.h"
#include "cafPdmUiPushButtonEditor.h"
#include "cafPdmUiTreeSelectionEditor.h"
#include "RimUserDefinedCalculation.h"
#include "RimUserDefinedCalculationCollection.h"
CAF_PDM_SOURCE_INIT( RicSummaryCurveCalculatorUi, "RicSummaryCurveCalculator" );
@ -37,25 +33,12 @@ CAF_PDM_SOURCE_INIT( RicSummaryCurveCalculatorUi, "RicSummaryCurveCalculator" );
RicSummaryCurveCalculatorUi::RicSummaryCurveCalculatorUi()
{
CAF_PDM_InitObject( "RicSummaryCurveCalculator" );
CAF_PDM_InitFieldNoDefault( &m_currentCalculation, "CurrentCalculation", "" );
m_currentCalculation.uiCapability()->setUiLabelPosition( caf::PdmUiItemInfo::HIDDEN );
// m_currentCalculation.uiCapability()->setUiEditorTypeName(caf::PdmUiTreeSelectionEditor::uiEditorTypeName());
m_currentCalculation.uiCapability()->setUiEditorTypeName( caf::PdmUiListEditor::uiEditorTypeName() );
CAF_PDM_InitFieldNoDefault( &m_newCalculation, "NewCalculation", "New Calculation" );
RicSummaryCurveCalculatorUi::assignPushButtonEditor( &m_newCalculation );
CAF_PDM_InitFieldNoDefault( &m_deleteCalculation, "DeleteCalculation", "Delete Calculation" );
RicSummaryCurveCalculatorUi::assignPushButtonEditor( &m_deleteCalculation );
m_calcContextMenuMgr = std::unique_ptr<RiuCalculationsContextMenuManager>( new RiuCalculationsContextMenuManager() );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RicSummaryCurveCalculatorUi::calculatedSummariesGroupName()
QString RicSummaryCurveCalculatorUi::calculationsGroupName() const
{
return "CalculatedSummariesGroupName";
}
@ -63,7 +46,7 @@ QString RicSummaryCurveCalculatorUi::calculatedSummariesGroupName()
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RicSummaryCurveCalculatorUi::calulationGroupName()
QString RicSummaryCurveCalculatorUi::calulationGroupName() const
{
return "CalulationGroupName";
}
@ -71,228 +54,15 @@ QString RicSummaryCurveCalculatorUi::calulationGroupName()
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimSummaryCalculation* RicSummaryCurveCalculatorUi::currentCalculation() const
void RicSummaryCurveCalculatorUi::notifyCalculatedNameChanged( int id, const QString& newName ) const
{
return m_currentCalculation();
RiaSummaryTools::notifyCalculatedCurveNameHasChanged( id, newName );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RicSummaryCurveCalculatorUi::setCurrentCalculation( RimSummaryCalculation* calculation )
RimUserDefinedCalculationCollection* RicSummaryCurveCalculatorUi::calculationCollection() const
{
m_currentCalculation = calculation;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RicSummaryCurveCalculatorUi::parseExpression() const
{
if ( m_currentCalculation() )
{
QString previousCurveName = m_currentCalculation->description();
if ( !m_currentCalculation()->parseExpression() )
{
return false;
}
QString currentCurveName = m_currentCalculation->description();
if ( previousCurveName != currentCurveName )
{
RiaSummaryTools::notifyCalculatedCurveNameHasChanged( m_currentCalculation()->id(), currentCurveName );
}
m_currentCalculation()->updateDependentCurvesAndPlots();
}
return true;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RicSummaryCurveCalculatorUi::fieldChangedByUi( const caf::PdmFieldHandle* changedField,
const QVariant& oldValue,
const QVariant& newValue )
{
if ( changedField == &m_newCalculation )
{
m_newCalculation = false;
m_currentCalculation = calculationCollection()->addCalculation();
this->updateConnectedEditors();
}
else if ( changedField == &m_deleteCalculation )
{
m_deleteCalculation = false;
if ( m_currentCalculation() )
{
calculationCollection()->deleteCalculation( m_currentCalculation() );
m_currentCalculation = nullptr;
this->updateConnectedEditors();
caf::PdmUiObjectEditorHandle::updateUiAllObjectEditors();
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RicSummaryCurveCalculatorUi::defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering )
{
if ( !m_currentCalculation() )
{
if ( calculationCollection()->calculations().size() > 0 )
{
m_currentCalculation = calculationCollection()->calculations()[0];
}
}
{
caf::PdmUiGroup* group =
uiOrdering.addNewGroupWithKeyword( "Calculated Summaries",
RicSummaryCurveCalculatorUi::calculatedSummariesGroupName() );
group->add( &m_currentCalculation );
group->add( &m_newCalculation );
group->add( &m_deleteCalculation );
}
{
caf::PdmUiGroup* group = uiOrdering.addNewGroupWithKeyword( "Calculation Settings",
RicSummaryCurveCalculatorUi::calulationGroupName() );
if ( m_currentCalculation() )
{
m_currentCalculation->uiOrdering( uiConfigName, *group );
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QList<caf::PdmOptionItemInfo>
RicSummaryCurveCalculatorUi::calculateValueOptions( const caf::PdmFieldHandle* fieldNeedingOptions, bool* useOptionsOnly )
{
QList<caf::PdmOptionItemInfo> options;
if ( fieldNeedingOptions == &m_currentCalculation )
{
for ( auto c : calculationCollection()->calculations() )
{
options.push_back( caf::PdmOptionItemInfo( c->description(), c ) );
}
}
return options;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimSummaryCalculationCollection* RicSummaryCurveCalculatorUi::calculationCollection()
{
RimProject* proj = RimProject::current();
if ( proj )
{
return proj->calculationCollection();
}
return nullptr;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RicSummaryCurveCalculatorUi::assignPushButtonEditor( caf::PdmFieldHandle* fieldHandle )
{
CVF_ASSERT( fieldHandle );
CVF_ASSERT( fieldHandle->uiCapability() );
fieldHandle->uiCapability()->setUiEditorTypeName( caf::PdmUiPushButtonEditor::uiEditorTypeName() );
fieldHandle->uiCapability()->setUiLabelPosition( caf::PdmUiItemInfo::HIDDEN );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RicSummaryCurveCalculatorUi::assignPushButtonEditorText( caf::PdmUiEditorAttribute* attribute, const QString& text )
{
caf::PdmUiPushButtonEditorAttribute* attrib = dynamic_cast<caf::PdmUiPushButtonEditorAttribute*>( attribute );
if ( attrib )
{
attrib->m_buttonText = text;
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RicSummaryCurveCalculatorUi::calculate() const
{
if ( m_currentCalculation() )
{
QString previousCurveName = m_currentCalculation->description();
if ( !m_currentCalculation()->parseExpression() )
{
return false;
}
QString currentCurveName = m_currentCalculation->description();
if ( previousCurveName != currentCurveName )
{
RiaSummaryTools::notifyCalculatedCurveNameHasChanged( m_currentCalculation()->id(), currentCurveName );
}
if ( !m_currentCalculation()->calculate() )
{
return false;
}
m_currentCalculation()->updateDependentCurvesAndPlots();
caf::PdmUiObjectEditorHandle::updateUiAllObjectEditors();
}
return true;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RicSummaryCurveCalculatorUi::defineEditorAttribute( const caf::PdmFieldHandle* field,
QString uiConfigName,
caf::PdmUiEditorAttribute* attribute )
{
if ( &m_newCalculation == field )
{
RicSummaryCurveCalculatorUi::assignPushButtonEditorText( attribute, "New Calculation" );
}
else if ( &m_deleteCalculation == field )
{
RicSummaryCurveCalculatorUi::assignPushButtonEditorText( attribute, "Delete Calculation" );
}
}
//--------------------------------------------------------------------------------------------------
/// f
//--------------------------------------------------------------------------------------------------
void RicSummaryCurveCalculatorUi::onEditorWidgetsCreated()
{
if ( m_currentCalculation() != nullptr )
{
m_currentCalculation->attachToWidget();
}
for ( const auto& e : m_currentCalculation.uiCapability()->connectedEditors() )
{
caf::PdmUiListEditor* listEditor = dynamic_cast<caf::PdmUiListEditor*>( e );
if ( !listEditor ) continue;
QWidget* widget = listEditor->editorWidget();
if ( !widget ) continue;
m_calcContextMenuMgr->attachWidget( widget, this );
}
return RimProject::current()->calculationCollection();
}

View File

@ -18,56 +18,22 @@
#pragma once
#include "RiuCalculationsContextMenuManager.h"
#include "cafPdmField.h"
#include "cafPdmObject.h"
#include "cafPdmPtrField.h"
#include <memory>
#include "RicUserDefinedCalculatorUi.h"
class RimSummaryCalculationCollection;
class RimSummaryCalculation;
class RimUserDefinedCalculationCollection;
//==================================================================================================
///
//==================================================================================================
class RicSummaryCurveCalculatorUi : public caf::PdmObject
class RicSummaryCurveCalculatorUi : public RicUserDefinedCalculatorUi
{
CAF_PDM_HEADER_INIT;
public:
RicSummaryCurveCalculatorUi();
static QString calculatedSummariesGroupName();
static QString calulationGroupName();
RimSummaryCalculation* currentCalculation() const;
void setCurrentCalculation( RimSummaryCalculation* calculation );
bool parseExpression() const;
bool calculate() const;
static RimSummaryCalculationCollection* calculationCollection();
private:
void fieldChangedByUi( const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue ) override;
void defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ) override;
QList<caf::PdmOptionItemInfo> calculateValueOptions( const caf::PdmFieldHandle* fieldNeedingOptions,
bool* useOptionsOnly ) override;
void defineEditorAttribute( const caf::PdmFieldHandle* field,
QString uiConfigName,
caf::PdmUiEditorAttribute* attribute ) override;
void onEditorWidgetsCreated() override;
private:
// TODO : Move to a common caf helper class
static void assignPushButtonEditor( caf::PdmFieldHandle* fieldHandle );
static void assignPushButtonEditorText( caf::PdmUiEditorAttribute* attribute, const QString& text );
private:
caf::PdmPtrField<RimSummaryCalculation*> m_currentCalculation;
caf::PdmField<bool> m_newCalculation;
caf::PdmField<bool> m_deleteCalculation;
std::unique_ptr<RiuCalculationsContextMenuManager> m_calcContextMenuMgr;
QString calculationsGroupName() const override;
QString calulationGroupName() const override;
RimUserDefinedCalculationCollection* calculationCollection() const override;
void notifyCalculatedNameChanged( int id, const QString& newName ) const override;
};

View File

@ -74,9 +74,15 @@ set(SOURCE_GROUP_HEADER_FILES
${CMAKE_CURRENT_LIST_DIR}/RimEclipseGeometrySelectionItem.h
${CMAKE_CURRENT_LIST_DIR}/RimDialogData.h
${CMAKE_CURRENT_LIST_DIR}/RimTimeStepFilter.h
${CMAKE_CURRENT_LIST_DIR}/RimUserDefinedCalculation.h
${CMAKE_CURRENT_LIST_DIR}/RimUserDefinedCalculationCollection.cpp
${CMAKE_CURRENT_LIST_DIR}/RimUserDefinedCalculationVariable.h
${CMAKE_CURRENT_LIST_DIR}/RimSummaryCalculation.h
${CMAKE_CURRENT_LIST_DIR}/RimSummaryCalculationCollection.h
${CMAKE_CURRENT_LIST_DIR}/RimSummaryCalculationVariable.h
${CMAKE_CURRENT_LIST_DIR}/RimGridCalculation.h
${CMAKE_CURRENT_LIST_DIR}/RimGridCalculationCollection.h
${CMAKE_CURRENT_LIST_DIR}/RimGridCalculationVariable.h
${CMAKE_CURRENT_LIST_DIR}/RimStimPlanLegendConfig.h
${CMAKE_CURRENT_LIST_DIR}/RimStimPlanColors.h
${CMAKE_CURRENT_LIST_DIR}/RimVirtualPerforationResults.h
@ -196,9 +202,15 @@ set(SOURCE_GROUP_SOURCE_FILES
${CMAKE_CURRENT_LIST_DIR}/RimEclipseGeometrySelectionItem.cpp
${CMAKE_CURRENT_LIST_DIR}/RimDialogData.cpp
${CMAKE_CURRENT_LIST_DIR}/RimTimeStepFilter.cpp
${CMAKE_CURRENT_LIST_DIR}/RimUserDefinedCalculation.cpp
${CMAKE_CURRENT_LIST_DIR}/RimUserDefinedCalculationCollection.cpp
${CMAKE_CURRENT_LIST_DIR}/RimUserDefinedCalculationVariable.cpp
${CMAKE_CURRENT_LIST_DIR}/RimSummaryCalculation.cpp
${CMAKE_CURRENT_LIST_DIR}/RimSummaryCalculationCollection.cpp
${CMAKE_CURRENT_LIST_DIR}/RimSummaryCalculationVariable.cpp
${CMAKE_CURRENT_LIST_DIR}/RimGridCalculation.cpp
${CMAKE_CURRENT_LIST_DIR}/RimGridCalculationCollection.cpp
${CMAKE_CURRENT_LIST_DIR}/RimGridCalculationVariable.cpp
${CMAKE_CURRENT_LIST_DIR}/RimStimPlanLegendConfig.cpp
${CMAKE_CURRENT_LIST_DIR}/RimStimPlanColors.cpp
${CMAKE_CURRENT_LIST_DIR}/RimVirtualPerforationResults.cpp

View File

@ -318,6 +318,7 @@ caf::CmdFeatureMenuBuilder RimContextCommandBuilder::commandsFromSelection()
menuBuilder << "RicSaveEclipseInputVisibleCellsFeature";
menuBuilder << "RicCreateGridCrossPlotFeature";
menuBuilder << "RicAddEclipseInputPropertyFeature";
menuBuilder << "RicShowGridCalculatorFeature";
}
else if ( dynamic_cast<RimEclipseInputProperty*>( firstUiItem ) )
{

View File

@ -0,0 +1,177 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2022 Equinor ASA
//
// 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 "RimGridCalculation.h"
#include "RigCaseCellResultsData.h"
#include "RimEclipseCase.h"
#include "expressionparser/ExpressionParser.h"
#include "RiaLogging.h"
#include "RiaPorosityModel.h"
#include "RigEclipseResultAddress.h"
CAF_PDM_SOURCE_INIT( RimGridCalculation, "RimGridCalculation" );
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimGridCalculation::RimGridCalculation()
{
CAF_PDM_InitObject( "RimGridCalculation", ":/octave.png", "Calculation", "" );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimGridCalculationVariable* RimGridCalculation::createVariable() const
{
return new RimGridCalculationVariable;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RimGridCalculation::calculate()
{
QString leftHandSideVariableName = RimGridCalculation::findLeftHandSide( m_expression );
auto porosityModel = RiaDefines::PorosityModelType::MATRIX_MODEL;
RimEclipseCase* eclipseCase = nullptr;
std::vector<std::vector<double>> values;
for ( size_t i = 0; i < m_variables.size(); i++ )
{
RimGridCalculationVariable* v = dynamic_cast<RimGridCalculationVariable*>( m_variables[i] );
// Use the first defined eclipse case from for output
if ( !eclipseCase ) eclipseCase = v->eclipseCase();
if ( !v->eclipseCase() )
{
RiaLogging::errorInMessageBox( nullptr,
"Expression Parser",
QString( "No case defined for variable : %1" ).arg( v->name() ) );
return false;
}
if ( v->resultVariable().isEmpty() )
{
RiaLogging::errorInMessageBox( nullptr,
"Expression Parser",
QString( "No result variable defined for variable : %1" ).arg( v->name() ) );
return false;
}
RigEclipseResultAddress resAddr( v->resultCategoryType(), v->resultVariable() );
if ( !eclipseCase->results( porosityModel )->ensureKnownResultLoaded( resAddr ) )
{
RiaLogging::errorInMessageBox( nullptr,
"Expression Parser",
QString( "Unable to load result for variable : %1" ).arg( v->name() ) );
return false;
}
std::vector<std::vector<double>> inputValues = eclipseCase->results( porosityModel )->cellScalarResults( resAddr );
values.push_back( inputValues[0] );
}
ExpressionParser parser;
for ( size_t i = 0; i < m_variables.size(); i++ )
{
RimGridCalculationVariable* v = dynamic_cast<RimGridCalculationVariable*>( m_variables[i] );
parser.assignVector( v->name(), values[i] );
}
std::vector<double> resultValues;
resultValues.resize( values[0].size() );
parser.assignVector( leftHandSideVariableName, resultValues );
QString errorText;
bool evaluatedOk = parser.expandIfStatementsAndEvaluate( m_expression, &errorText );
if ( evaluatedOk )
{
m_timesteps.v().clear();
m_calculatedValues.v().clear();
RigEclipseResultAddress resAddr( RiaDefines::ResultCatType::GENERATED, leftHandSideVariableName );
if ( !eclipseCase->results( porosityModel )->ensureKnownResultLoaded( resAddr ) )
{
eclipseCase->results( porosityModel )->createResultEntry( resAddr, true );
}
std::vector<std::vector<double>>* scalarResultFrames =
eclipseCase->results( porosityModel )->modifiableCellScalarResultTimesteps( resAddr );
size_t timeStepCount = eclipseCase->results( porosityModel )->maxTimeStepCount();
scalarResultFrames->resize( timeStepCount );
size_t tsId = 0;
scalarResultFrames->at( tsId ) = resultValues;
m_isDirty = false;
}
else
{
QString s = "The following error message was received from the parser library : \n\n";
s += errorText;
RiaLogging::errorInMessageBox( nullptr, "Expression Parser", s );
}
return evaluatedOk;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimGridCalculation::updateDependentObjects()
{
// RimGridCalculationCollection* calcColl = nullptr;
// this->firstAncestorOrThisOfTypeAsserted( calcColl );
// calcColl->rebuildCaseMetaData();
// RimGridMultiPlotCollection* summaryPlotCollection = RiaGridTools::summaryMultiPlotCollection();
// for ( auto multiPlot : summaryPlotCollection->multiPlots() )
// {
// for ( RimGridPlot* sumPlot : multiPlot->summaryPlots() )
// {
// bool plotContainsCalculatedCurves = false;
// for ( RimGridCurve* sumCurve : sumPlot->summaryCurves() )
// {
// if ( sumCurve->summaryAddressY().category() == RifEclipseGridAddress::SUMMARY_CALCULATED )
// {
// sumCurve->updateConnectedEditors();
// plotContainsCalculatedCurves = true;
// }
// }
// if ( plotContainsCalculatedCurves )
// {
// sumPlot->loadDataAndUpdate();
// }
// }
// }
}

View File

@ -0,0 +1,40 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2022 Equinor ASA
//
// 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.
//
/////////////////////////////////////////////////////////////////////////////////
#pragma once
#include "RimGridCalculationVariable.h"
#include "RimUserDefinedCalculation.h"
//==================================================================================================
///
///
//==================================================================================================
class RimGridCalculation : public RimUserDefinedCalculation
{
CAF_PDM_HEADER_INIT;
public:
RimGridCalculation();
bool calculate() override;
void updateDependentObjects() override;
protected:
RimGridCalculationVariable* createVariable() const override;
};

View File

@ -0,0 +1,57 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2022 Equinor ASA
//
// 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 "RimGridCalculationCollection.h"
#include "RimGridCalculation.h"
#include "cafPdmUiGroup.h"
#include "cafPdmUiTreeSelectionEditor.h"
CAF_PDM_SOURCE_INIT( RimGridCalculationCollection, "RimGridCalculationCollection" );
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimGridCalculationCollection::RimGridCalculationCollection()
{
CAF_PDM_InitObject( "Calculation Collection", ":/chain.png" );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimGridCalculation* RimGridCalculationCollection::createCalculation() const
{
return new RimGridCalculation;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimGridCalculationCollection::rebuildCaseMetaData()
{
ensureCalculationIds();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimGridCalculationCollection::initAfterRead()
{
rebuildCaseMetaData();
}

View File

@ -0,0 +1,48 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2022 Equinor ASA
//
// 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.
//
/////////////////////////////////////////////////////////////////////////////////
#pragma once
#include "RimGridCalculation.h"
#include "RimUserDefinedCalculationCollection.h"
#include "cafPdmChildArrayField.h"
#include "cafPdmChildField.h"
#include "cafPdmObject.h"
class RimGridCase;
class RimCalculatedGridCase;
//==================================================================================================
///
///
//==================================================================================================
class RimGridCalculationCollection : public RimUserDefinedCalculationCollection
{
CAF_PDM_HEADER_INIT;
public:
RimGridCalculationCollection();
void rebuildCaseMetaData() override;
RimGridCalculation* createCalculation() const override;
private:
void initAfterRead() override;
};

View File

@ -0,0 +1,204 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2022 Equinor ASA
//
// 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 "RimGridCalculationVariable.h"
#include "RiaApplication.h"
#include "RiaPorosityModel.h"
#include "RiaResultNames.h"
#include "RigCaseCellResultsData.h"
#include "RimEclipseCase.h"
#include "RimTools.h"
CAF_PDM_SOURCE_INIT( RimGridCalculationVariable, "RimGridCalculationVariable" );
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimGridCalculationVariable::RimGridCalculationVariable()
{
CAF_PDM_InitObject( "RimGridCalculationVariable", ":/octave.png" );
CAF_PDM_InitFieldNoDefault( &m_resultType, "ResultType", "Type" );
CAF_PDM_InitField( &m_resultVariable, "ResultVariable", RiaResultNames::undefinedResultName(), "Variable" );
CAF_PDM_InitFieldNoDefault( &m_eclipseCase, "EclipseGridCase", "Grid Case" );
CAF_PDM_InitFieldNoDefault( &m_timeStep, "TimeStep", "Time Step" );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimGridCalculationVariable::fieldChangedByUi( const caf::PdmFieldHandle* changedField,
const QVariant& oldValue,
const QVariant& newValue )
{
// if ( changedField == &m_button )
// {
// bool updateContainingEditor = false;
// {
// RiuGridVectorSelectionDialog dlg( nullptr );
// dlg.hideEnsembles();
// readDataFromApplicationStore( &dlg );
// if ( dlg.exec() == QDialog::Accepted )
// {
// std::vector<RiaGridCurveDefinition> curveSelection = dlg.curveSelection();
// if ( curveSelection.size() > 0 )
// {
// m_case = curveSelection[0].summaryCase();
// m_summaryAddress->setAddress( curveSelection[0].summaryAddress() );
// writeDataToApplicationStore();
// updateContainingEditor = true;
// }
// }
// }
// if ( updateContainingEditor )
// {
// RimGridCalculation* rimCalculation = nullptr;
// this->firstAncestorOrThisOfTypeAsserted( rimCalculation );
// // RimCalculation is pointed to by RicGridCurveCalculator in a PtrField
// // Update editors connected to RicGridCurveCalculator
// std::vector<caf::PdmObjectHandle*> referringObjects;
// rimCalculation->objectsWithReferringPtrFields( referringObjects );
// for ( auto o : referringObjects )
// {
// o->uiCapability()->updateConnectedEditors();
// }
// }
// }
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RimGridCalculationVariable::displayString() const
{
QStringList nameComponents;
if ( m_eclipseCase() ) nameComponents.append( m_eclipseCase()->uiName() );
nameComponents.append( m_resultVariable() );
return nameComponents.join( " - " );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimGridCalculationVariable::defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering )
{
uiOrdering.add( &m_name );
uiOrdering.add( &m_eclipseCase );
uiOrdering.add( &m_resultType );
uiOrdering.add( &m_resultVariable );
uiOrdering.add( &m_timeStep );
uiOrdering.skipRemainingFields();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QList<caf::PdmOptionItemInfo>
RimGridCalculationVariable::calculateValueOptions( const caf::PdmFieldHandle* fieldNeedingOptions, bool* useOptionsOnly )
{
QList<caf::PdmOptionItemInfo> options;
if ( fieldNeedingOptions == &m_resultVariable )
{
auto results = currentGridCellResults();
if ( results )
{
for ( const QString& s : getResultNamesForResultType( m_resultType(), results ) )
{
options.push_back( caf::PdmOptionItemInfo( s, s ) );
}
}
}
else if ( fieldNeedingOptions == &m_eclipseCase )
{
RimTools::eclipseCaseOptionItems( &options );
}
else if ( fieldNeedingOptions == &m_timeStep )
{
RimTools::timeStepsForCase( m_eclipseCase(), &options );
}
if ( useOptionsOnly ) *useOptionsOnly = true;
return options;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RigCaseCellResultsData* RimGridCalculationVariable::currentGridCellResults() const
{
if ( !m_eclipseCase ) return nullptr;
return m_eclipseCase->results( RiaDefines::PorosityModelType::MATRIX_MODEL );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QStringList RimGridCalculationVariable::getResultNamesForResultType( RiaDefines::ResultCatType resultCatType,
const RigCaseCellResultsData* results )
{
if ( !results ) return QStringList();
return results->resultNames( resultCatType );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimEclipseCase* RimGridCalculationVariable::eclipseCase() const
{
return m_eclipseCase;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RiaDefines::ResultCatType RimGridCalculationVariable::resultCategoryType() const
{
return m_resultType();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RimGridCalculationVariable::resultVariable() const
{
return m_resultVariable;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
int RimGridCalculationVariable::timeStep() const
{
return m_timeStep;
}

View File

@ -0,0 +1,67 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2022 Equinor ASA
//
// 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.
//
/////////////////////////////////////////////////////////////////////////////////
#pragma once
#include "RimUserDefinedCalculationVariable.h"
#include "RiaDefines.h"
#include "cafPdmChildField.h"
#include "cafPdmField.h"
#include "cafPdmObject.h"
#include "cafPdmProxyValueField.h"
#include "cafPdmPtrField.h"
class RimEclipseCase;
class RigCaseCellResultsData;
//==================================================================================================
///
///
//==================================================================================================
class RimGridCalculationVariable : public RimUserDefinedCalculationVariable
{
CAF_PDM_HEADER_INIT;
public:
RimGridCalculationVariable();
QString displayString() const override;
RimEclipseCase* eclipseCase() const;
RiaDefines::ResultCatType resultCategoryType() const;
QString resultVariable() const;
int timeStep() const;
private:
void fieldChangedByUi( const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue ) override;
void defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ) override;
QList<caf::PdmOptionItemInfo> calculateValueOptions( const caf::PdmFieldHandle* fieldNeedingOptions,
bool* useOptionsOnly ) override;
RigCaseCellResultsData* currentGridCellResults() const;
QStringList getResultNamesForResultType( RiaDefines::ResultCatType resultCatType,
const RigCaseCellResultsData* results );
private:
caf::PdmPtrField<RimEclipseCase*> m_eclipseCase;
caf::PdmField<caf::AppEnum<RiaDefines::ResultCatType>> m_resultType;
caf::PdmField<QString> m_resultVariable;
caf::PdmField<int> m_timeStep;
};

View File

@ -55,6 +55,7 @@
#include "RimFractureTemplateCollection.h"
#include "RimGeoMechCase.h"
#include "RimGeoMechModels.h"
#include "RimGridCalculationCollection.h"
#include "RimGridCrossPlotCollection.h"
#include "RimGridSummaryCase.h"
#include "RimGridView.h"
@ -126,7 +127,6 @@ RimProject::RimProject( void )
, m_nextValidCaseGroupId( 0 )
, m_nextValidViewId( 1 )
, m_nextValidPlotId( 1 )
, m_nextValidCalculationId( 1 )
, m_nextValidSummaryCaseId( 1 )
, m_nextValidEnsembleId( 1 )
{
@ -164,6 +164,9 @@ RimProject::RimProject( void )
CAF_PDM_InitFieldNoDefault( &calculationCollection, "CalculationCollection", "Calculation Collection" );
calculationCollection = new RimSummaryCalculationCollection;
CAF_PDM_InitFieldNoDefault( &gridCalculationCollection, "GridCalculationCollection", "Grid Calculation Collection" );
gridCalculationCollection = new RimGridCalculationCollection;
CAF_PDM_InitFieldNoDefault( &commandObjects, "CommandObjects", "Command Objects" );
CAF_PDM_InitFieldNoDefault( &multiSnapshotDefinitions, "MultiSnapshotDefinitions", "Multi Snapshot Definitions" );
@ -261,6 +264,7 @@ void RimProject::close()
m_dialogData->clearProjectSpecificData();
calculationCollection->deleteAllContainedObjects();
gridCalculationCollection->deleteAllContainedObjects();
colorLegendCollection->deleteCustomColorLegends();
delete viewLinkerCollection->viewLinker();
@ -277,7 +281,6 @@ void RimProject::close()
m_nextValidCaseGroupId = 0;
m_nextValidViewId = 1;
m_nextValidPlotId = 1;
m_nextValidCalculationId = 1;
m_nextValidSummaryCaseId = 1;
m_nextValidEnsembleId = 1;
}
@ -607,22 +610,6 @@ void RimProject::assignPlotIdToPlotWindow( RimPlotWindow* plotWindow )
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimProject::assignCalculationIdToCalculation( RimSummaryCalculation* calculation )
{
if ( calculation )
{
for ( RimSummaryCalculation* existingCalculation : calculationCollection->calculations() )
{
m_nextValidCalculationId = std::max( m_nextValidCalculationId, existingCalculation->id() + 1 );
}
calculation->setId( m_nextValidCalculationId++ );
}
}
//--------------------------------------------------------------------------------------------------
/// TODO: This function is deprecated, use allGridCases()
//--------------------------------------------------------------------------------------------------

View File

@ -70,6 +70,7 @@ class RimValveTemplateCollection;
class RimValveTemplate;
class RimCompletionTemplateCollection;
class RimPlotTemplateFolderItem;
class RimGridCalculationCollection;
namespace caf
{
@ -99,6 +100,7 @@ public:
caf::PdmChildField<RimMainPlotCollection*> mainPlotCollection;
caf::PdmChildField<RimViewLinkerCollection*> viewLinkerCollection;
caf::PdmChildField<RimSummaryCalculationCollection*> calculationCollection;
caf::PdmChildField<RimGridCalculationCollection*> gridCalculationCollection;
caf::PdmChildArrayField<RimCommandObject*> commandObjects;
caf::PdmChildArrayField<RimAdvancedSnapshotExportDefinition*> multiSnapshotDefinitions;
@ -124,7 +126,6 @@ public:
void assignIdToCaseGroup( RimIdenticalGridCaseGroup* caseGroup );
void assignViewIdToView( Rim3dView* view );
void assignPlotIdToPlotWindow( RimPlotWindow* plotWindow );
void assignCalculationIdToCalculation( RimSummaryCalculation* calculation );
void assignCaseIdToSummaryCase( RimSummaryCase* summaryCase );
void assignIdToEnsemble( RimSummaryCaseCollection* summaryCaseCollection );
@ -223,7 +224,6 @@ private:
int m_nextValidCaseGroupId;
int m_nextValidViewId;
int m_nextValidPlotId;
int m_nextValidCalculationId;
int m_nextValidSummaryCaseId;
int m_nextValidEnsembleId;

View File

@ -25,7 +25,6 @@
#include "RiaSummaryCurveDefinition.h"
#include "RiaSummaryTools.h"
#include "RimProject.h"
#include "RimSummaryAddress.h"
#include "RimSummaryCalculationCollection.h"
#include "RimSummaryCalculationVariable.h"
@ -50,204 +49,14 @@ CAF_PDM_SOURCE_INIT( RimSummaryCalculation, "RimSummaryCalculation" );
RimSummaryCalculation::RimSummaryCalculation()
{
CAF_PDM_InitObject( "RimSummaryCalculation", ":/octave.png", "Calculation", "" );
CAF_PDM_InitFieldNoDefault( &m_description, "Description", "Description" );
m_description.uiCapability()->setUiReadOnly( true );
CAF_PDM_InitField( &m_expression, "Expression", QString( "" ), "Expression" );
m_expression.uiCapability()->setUiEditorTypeName( caf::PdmUiTextEditor::uiEditorTypeName() );
CAF_PDM_InitField( &m_unit, "Unit", QString( "" ), "Unit" );
m_unit.uiCapability()->setUiEditorTypeName( caf::PdmUiLineEditor::uiEditorTypeName() );
CAF_PDM_InitFieldNoDefault( &m_variables, "Variables", "Variables" );
CAF_PDM_InitFieldNoDefault( &m_calculatedValues, "CalculatedValues", "Calculated Values" );
CAF_PDM_InitFieldNoDefault( &m_timesteps, "TimeSteps", "Time Steps" );
CAF_PDM_InitField( &m_id, "Id", -1, "Id" );
m_id.uiCapability()->setUiHidden( true );
m_exprContextMenuMgr = std::unique_ptr<RiuExpressionContextMenuManager>( new RiuExpressionContextMenuManager() );
m_isDirty = false;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimSummaryCalculation::setDescription( const QString& description )
RimSummaryCalculationVariable* RimSummaryCalculation::createVariable() const
{
m_description = description;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RimSummaryCalculation::description() const
{
return m_description;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimSummaryCalculation::setId( int id )
{
m_id = id;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
int RimSummaryCalculation::id() const
{
return m_id;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RimSummaryCalculation::isDirty() const
{
return m_isDirty;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
caf::PdmChildArrayFieldHandle* RimSummaryCalculation::variables()
{
return &m_variables;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimSummaryCalculationVariable* RimSummaryCalculation::addVariable( const QString& name )
{
RimSummaryCalculationVariable* v = new RimSummaryCalculationVariable;
v->setName( name );
m_variables.push_back( v );
return v;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimSummaryCalculation::deleteVariable( RimSummaryCalculationVariable* calcVariable )
{
m_variables.removeChildObject( calcVariable );
delete calcVariable;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const std::vector<double>& RimSummaryCalculation::values() const
{
return m_calculatedValues();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const std::vector<time_t>& RimSummaryCalculation::timeSteps() const
{
return m_timesteps();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimSummaryCalculation::setExpression( const QString& expr )
{
m_expression = expr;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RimSummaryCalculation::expression() const
{
return m_expression;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RimSummaryCalculation::unitName() const
{
return m_unit;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
caf::PdmFieldHandle* RimSummaryCalculation::userDescriptionField()
{
return &m_description;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RimSummaryCalculation::parseExpression()
{
QString leftHandSideVariableName = RimSummaryCalculation::findLeftHandSide( m_expression );
if ( leftHandSideVariableName.isEmpty() )
{
RiaLogging::errorInMessageBox( nullptr, "Expression Parser", "Failed to detect left hand side of equation" );
return false;
}
std::vector<QString> variableNames = ExpressionParser::detectReferencedVariables( m_expression );
if ( variableNames.size() < 1 )
{
RiaLogging::errorInMessageBox( nullptr, "Expression Parser", "Failed to detect any variable names" );
return false;
}
// Remove variables not present in expression
{
std::vector<RimSummaryCalculationVariable*> toBeDeleted;
for ( RimSummaryCalculationVariable* v : m_variables )
{
if ( std::find( variableNames.begin(), variableNames.end(), v->name() ) == variableNames.end() )
{
toBeDeleted.push_back( v );
}
if ( leftHandSideVariableName == v->name() )
{
toBeDeleted.push_back( v );
}
}
for ( RimSummaryCalculationVariable* v : toBeDeleted )
{
deleteVariable( v );
}
}
for ( auto variableName : variableNames )
{
if ( leftHandSideVariableName != variableName )
{
if ( !findByName( variableName ) )
{
this->addVariable( variableName );
}
}
}
m_description = buildCalculationName();
return true;
return new RimSummaryCalculationVariable;
}
//--------------------------------------------------------------------------------------------------
@ -261,7 +70,7 @@ bool RimSummaryCalculation::calculate()
for ( size_t i = 0; i < m_variables.size(); i++ )
{
RimSummaryCalculationVariable* v = m_variables[i];
RimSummaryCalculationVariable* v = dynamic_cast<RimSummaryCalculationVariable*>( m_variables[i] );
if ( !v->summaryCase() )
{
@ -299,7 +108,7 @@ bool RimSummaryCalculation::calculate()
ExpressionParser parser;
for ( size_t i = 0; i < m_variables.size(); i++ )
{
RimSummaryCalculationVariable* v = m_variables[i];
RimSummaryCalculationVariable* v = dynamic_cast<RimSummaryCalculationVariable*>( m_variables[i] );
parser.assignVector( v->name(), timeHistoryCurveMerger.interpolatedYValuesForAllXValues( i ) );
}
@ -348,138 +157,10 @@ bool RimSummaryCalculation::calculate()
return evaluatedOk;
}
//--------------------------------------------------------------------------------------------------
/// Find the last assignment using := and interpret the text before the := as LHS
//--------------------------------------------------------------------------------------------------
QString RimSummaryCalculation::findLeftHandSide( const QString& expression )
{
int index = expression.lastIndexOf( ":=" );
if ( index > 0 )
{
QString s = expression.left( index ).simplified();
QStringList words = s.split( " " );
if ( words.size() > 0 )
{
return words.back();
}
}
return "";
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimSummaryCalculation::attachToWidget()
{
for ( auto e : m_expression.uiCapability()->connectedEditors() )
{
caf::PdmUiTextEditor* textEditor = dynamic_cast<caf::PdmUiTextEditor*>( e );
if ( !textEditor ) continue;
QWidget* containerWidget = textEditor->editorWidget();
if ( !containerWidget ) continue;
for ( auto qObj : containerWidget->children() )
{
QTextEdit* textEdit = dynamic_cast<QTextEdit*>( qObj );
if ( textEdit )
{
m_exprContextMenuMgr->attachTextEdit( textEdit );
}
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimSummaryCalculation::fieldChangedByUi( const caf::PdmFieldHandle* changedField,
const QVariant& oldValue,
const QVariant& newValue )
{
m_isDirty = true;
PdmObject::fieldChangedByUi( changedField, oldValue, newValue );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimSummaryCalculationVariable* RimSummaryCalculation::findByName( const QString& name ) const
{
for ( RimSummaryCalculationVariable* v : m_variables )
{
if ( v->name() == name )
{
return v;
}
}
return nullptr;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RimSummaryCalculation::buildCalculationName() const
{
QString name = "Default Calculation Name";
QString lhs = RimSummaryCalculation::findLeftHandSide( m_expression );
if ( !lhs.isEmpty() )
{
name = lhs;
name += " ( ";
for ( RimSummaryCalculationVariable* v : m_variables )
{
name += v->summaryAddressDisplayString();
if ( v != m_variables[m_variables.size() - 1] )
{
name += ", ";
}
}
name += " )";
}
return name;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimSummaryCalculation::defineEditorAttribute( const caf::PdmFieldHandle* field,
QString uiConfigName,
caf::PdmUiEditorAttribute* attribute )
{
if ( field == &m_expression )
{
caf::PdmUiTextEditorAttribute* myAttr = dynamic_cast<caf::PdmUiTextEditorAttribute*>( attribute );
if ( myAttr )
{
myAttr->heightHint = -1;
}
}
else if ( field == &m_variables )
{
auto* myAttr = dynamic_cast<caf::PdmUiTableViewEditorAttribute*>( attribute );
if ( myAttr )
{
myAttr->enableDropTarget = true;
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimSummaryCalculation::updateDependentCurvesAndPlots()
void RimSummaryCalculation::updateDependentObjects()
{
RimSummaryCalculationCollection* calcColl = nullptr;
this->firstAncestorOrThisOfTypeAsserted( calcColl );
@ -509,15 +190,3 @@ void RimSummaryCalculation::updateDependentCurvesAndPlots()
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<RimSummaryCalculationVariable*> RimSummaryCalculation::allVariables() const
{
std::vector<RimSummaryCalculationVariable*> outVariables;
for ( RimSummaryCalculationVariable* v : m_variables )
outVariables.push_back( v );
return outVariables;
}

View File

@ -18,79 +18,35 @@
#pragma once
#include "RimSummaryCalculationVariable.h"
#include "RimUserDefinedCalculation.h"
#include "RiuExpressionContextMenuManager.h"
#include "cafPdmChildArrayField.h"
#include "cafPdmField.h"
#include "cafPdmObject.h"
#include <QPointer>
#include <memory>
class RimSummaryCalculationVariable;
class QTextEdit;
//==================================================================================================
///
///
//==================================================================================================
class RimSummaryCalculation : public caf::PdmObject
class RimSummaryCalculation : public RimUserDefinedCalculation
{
CAF_PDM_HEADER_INIT;
public:
RimSummaryCalculation();
void setDescription( const QString& description );
QString description() const;
bool calculate() override;
void updateDependentObjects() override;
void setId( int id );
int id() const;
bool isDirty() const;
caf::PdmChildArrayFieldHandle* variables();
std::vector<RimSummaryCalculationVariable*> allVariables() const;
const std::vector<double>& values() const;
const std::vector<time_t>& timeSteps() const;
void setExpression( const QString& expr );
QString expression() const;
QString unitName() const;
bool parseExpression();
bool calculate();
void updateDependentCurvesAndPlots();
caf::PdmFieldHandle* userDescriptionField() override;
static QString findLeftHandSide( const QString& expression );
void attachToWidget();
private:
void fieldChangedByUi( const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue ) override;
void defineEditorAttribute( const caf::PdmFieldHandle* field,
QString uiConfigName,
caf::PdmUiEditorAttribute* attribute ) override;
RimSummaryCalculationVariable* findByName( const QString& name ) const;
RimSummaryCalculationVariable* addVariable( const QString& name );
void deleteVariable( RimSummaryCalculationVariable* calcVariable );
QString buildCalculationName() const;
private:
caf::PdmField<QString> m_description;
caf::PdmField<QString> m_expression;
caf::PdmField<QString> m_unit;
caf::PdmChildArrayField<RimSummaryCalculationVariable*> m_variables;
caf::PdmField<std::vector<double>> m_calculatedValues;
caf::PdmField<std::vector<time_t>> m_timesteps;
caf::PdmField<int> m_id;
std::unique_ptr<RiuExpressionContextMenuManager> m_exprContextMenuMgr;
bool m_isDirty;
protected:
RimSummaryCalculationVariable* createVariable() const override;
};

View File

@ -33,9 +33,6 @@ RimSummaryCalculationCollection::RimSummaryCalculationCollection()
{
CAF_PDM_InitObject( "Calculation Collection", ":/chain.png" );
CAF_PDM_InitFieldNoDefault( &m_calculations, "Calculations", "Calculations" );
m_calculations.uiCapability()->setUiEditorTypeName( caf::PdmUiTreeSelectionEditor::uiEditorTypeName() );
CAF_PDM_InitFieldNoDefault( &m_calcuationSummaryCase, "CalculationsSummaryCase", "Calculations Summary Case" );
m_calcuationSummaryCase.xmlCapability()->disableIO();
m_calcuationSummaryCase = new RimCalculatedSummaryCase;
@ -44,95 +41,9 @@ RimSummaryCalculationCollection::RimSummaryCalculationCollection()
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimSummaryCalculation* RimSummaryCalculationCollection::addCalculation()
RimSummaryCalculation* RimSummaryCalculationCollection::createCalculation() const
{
RimSummaryCalculation* calculation = new RimSummaryCalculation;
RimProject::current()->assignCalculationIdToCalculation( calculation );
QString varName = QString( "Calculation_%1" ).arg( calculation->id() );
calculation->setDescription( varName );
calculation->setExpression( varName + " := x + y" );
calculation->parseExpression();
m_calculations.push_back( calculation );
rebuildCaseMetaData();
return calculation;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimSummaryCalculation* RimSummaryCalculationCollection::addCalculationCopy( const RimSummaryCalculation* sourceCalculation )
{
RimSummaryCalculation* calcCopy = dynamic_cast<RimSummaryCalculation*>(
sourceCalculation->xmlCapability()->copyByXmlSerialization( caf::PdmDefaultObjectFactory::instance() ) );
CVF_ASSERT( calcCopy );
std::set<QString> calcNames;
for ( const auto& calc : m_calculations )
{
calcNames.insert( calc->findLeftHandSide( calc->expression() ) );
}
QString expression = calcCopy->expression();
QString currVarName = calcCopy->findLeftHandSide( expression );
QString newVarName = currVarName;
while ( calcNames.count( newVarName ) > 0 )
{
newVarName += "_copy";
}
expression.replace( currVarName, newVarName );
calcCopy->setExpression( expression );
RimProject::current()->assignCalculationIdToCalculation( calcCopy );
m_calculations.push_back( calcCopy );
calcCopy->resolveReferencesRecursively();
rebuildCaseMetaData();
calcCopy->parseExpression();
return calcCopy;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimSummaryCalculationCollection::deleteCalculation( RimSummaryCalculation* calculation )
{
m_calculations.removeChildObject( calculation );
rebuildCaseMetaData();
delete calculation;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<RimSummaryCalculation*> RimSummaryCalculationCollection::calculations() const
{
return m_calculations.childObjects();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimSummaryCalculation* RimSummaryCalculationCollection::findCalculationById( int id ) const
{
for ( RimSummaryCalculation* calc : m_calculations )
{
if ( calc->id() == id )
{
return calc;
}
}
return nullptr;
return new RimSummaryCalculation;
}
//--------------------------------------------------------------------------------------------------
@ -143,29 +54,12 @@ RimSummaryCase* RimSummaryCalculationCollection::calculationSummaryCase()
return m_calcuationSummaryCase();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimSummaryCalculationCollection::deleteAllContainedObjects()
{
m_calculations.deleteAllChildObjects();
rebuildCaseMetaData();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimSummaryCalculationCollection::rebuildCaseMetaData()
{
for ( RimSummaryCalculation* calculation : m_calculations )
{
if ( calculation->id() == -1 )
{
RimProject::current()->assignCalculationIdToCalculation( calculation );
}
}
ensureCalculationIds();
m_calcuationSummaryCase->buildMetaData();
}

View File

@ -18,11 +18,13 @@
#pragma once
#include "RimSummaryCalculation.h"
#include "RimUserDefinedCalculationCollection.h"
#include "cafPdmChildArrayField.h"
#include "cafPdmChildField.h"
#include "cafPdmObject.h"
class RimSummaryCalculation;
class RimSummaryCase;
class RimCalculatedSummaryCase;
@ -30,28 +32,22 @@ class RimCalculatedSummaryCase;
///
///
//==================================================================================================
class RimSummaryCalculationCollection : public caf::PdmObject
class RimSummaryCalculationCollection : public RimUserDefinedCalculationCollection
{
CAF_PDM_HEADER_INIT;
public:
RimSummaryCalculationCollection();
RimSummaryCalculation* addCalculation();
RimSummaryCalculation* addCalculationCopy( const RimSummaryCalculation* sourceCalculation );
void deleteCalculation( RimSummaryCalculation* calculation );
std::vector<RimSummaryCalculation*> calculations() const;
RimSummaryCalculation* findCalculationById( int id ) const;
RimSummaryCase* calculationSummaryCase();
void deleteAllContainedObjects();
void rebuildCaseMetaData();
void rebuildCaseMetaData() override;
RimSummaryCalculation* createCalculation() const override;
private:
void initAfterRead() override;
private:
caf::PdmChildArrayField<RimSummaryCalculation*> m_calculations;
caf::PdmChildField<RimCalculatedSummaryCase*> m_calcuationSummaryCase;
caf::PdmChildField<RimCalculatedSummaryCase*> m_calcuationSummaryCase;
};

View File

@ -45,40 +45,16 @@ RimSummaryCalculationVariable::RimSummaryCalculationVariable()
{
CAF_PDM_InitObject( "RimSummaryCalculationVariable", ":/octave.png" );
CAF_PDM_InitFieldNoDefault( &m_name, "VariableName", "Variable Name" );
m_name.uiCapability()->setUiReadOnly( true );
CAF_PDM_InitFieldNoDefault( &m_button, "PushButton", "" );
m_button.uiCapability()->setUiEditorTypeName( caf::PdmUiPushButtonEditor::uiEditorTypeName() );
m_button.xmlCapability()->disableIO();
CAF_PDM_InitFieldNoDefault( &m_summaryAddressUi, "SummaryAddressUi", "Summary Address" );
m_summaryAddressUi.registerGetMethod( this, &RimSummaryCalculationVariable::summaryAddressDisplayString );
m_summaryAddressUi.xmlCapability()->disableIO();
m_summaryAddressUi.uiCapability()->setUiReadOnly( true );
CAF_PDM_InitFieldNoDefault( &m_case, "SummaryCase", "Summary Case" );
CAF_PDM_InitFieldNoDefault( &m_summaryAddress, "SummaryAddress", "Summary Address" );
m_summaryAddress = new RimSummaryAddress;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RimSummaryCalculationVariable::name() const
{
return m_name;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimSummaryCalculationVariable::setName( const QString& name )
{
m_name = name;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@ -131,7 +107,7 @@ void RimSummaryCalculationVariable::fieldChangedByUi( const caf::PdmFieldHandle*
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RimSummaryCalculationVariable::summaryAddressDisplayString() const
QString RimSummaryCalculationVariable::displayString() const
{
QString caseName;
if ( m_case() ) caseName = m_case()->displayCaseName();
@ -188,7 +164,7 @@ void RimSummaryCalculationVariable::handleDroppedMimeData( const QMimeData*
void RimSummaryCalculationVariable::defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering )
{
uiOrdering.add( &m_name );
uiOrdering.add( &m_summaryAddressUi );
uiOrdering.add( &m_addressUi );
uiOrdering.add( &m_button );
uiOrdering.skipRemainingFields();

View File

@ -18,13 +18,15 @@
#pragma once
#include "RimUserDefinedCalculationVariable.h"
#include "cafPdmChildField.h"
#include "cafPdmField.h"
#include "cafPdmObject.h"
#include "cafPdmProxyValueField.h"
#include "cafPdmPtrField.h"
#include "RifEclipseSummaryAddressQMetaType.h"
#include "cafPdmChildField.h"
class RimSummaryCase;
class RimSummaryAddress;
@ -34,17 +36,14 @@ class RiuSummaryVectorSelectionDialog;
///
///
//==================================================================================================
class RimSummaryCalculationVariable : public caf::PdmObject
class RimSummaryCalculationVariable : public RimUserDefinedCalculationVariable
{
CAF_PDM_HEADER_INIT;
public:
RimSummaryCalculationVariable();
QString name() const;
void setName( const QString& name );
QString summaryAddressDisplayString() const;
QString displayString() const override;
RimSummaryCase* summaryCase();
RimSummaryAddress* summaryAddress();
@ -62,9 +61,6 @@ private:
void writeDataToApplicationStore() const;
private:
caf::PdmField<QString> m_name;
caf::PdmProxyValueField<QString> m_summaryAddressUi;
caf::PdmField<bool> m_button;
caf::PdmPtrField<RimSummaryCase*> m_case;

View File

@ -0,0 +1,382 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2017 Statoil ASA
//
// 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 "RimUserDefinedCalculation.h"
#include "expressionparser/ExpressionParser.h"
#include "RiaLogging.h"
#include "RimProject.h"
#include "RimUserDefinedCalculationVariable.h"
#include "RiuExpressionContextMenuManager.h"
#include "cafPdmUiLineEditor.h"
#include "cafPdmUiTableViewEditor.h"
#include "cafPdmUiTextEditor.h"
#include <algorithm>
CAF_PDM_XML_ABSTRACT_SOURCE_INIT( RimUserDefinedCalculation, "RimUserDefinedCalculation" );
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimUserDefinedCalculation::RimUserDefinedCalculation()
{
CAF_PDM_InitObject( "RimUserDefinedCalculation", ":/octave.png", "Calculation", "" );
CAF_PDM_InitFieldNoDefault( &m_description, "Description", "Description" );
m_description.uiCapability()->setUiReadOnly( true );
CAF_PDM_InitField( &m_expression, "Expression", QString( "" ), "Expression" );
m_expression.uiCapability()->setUiEditorTypeName( caf::PdmUiTextEditor::uiEditorTypeName() );
CAF_PDM_InitField( &m_unit, "Unit", QString( "" ), "Unit" );
m_unit.uiCapability()->setUiEditorTypeName( caf::PdmUiLineEditor::uiEditorTypeName() );
CAF_PDM_InitFieldNoDefault( &m_variables, "Variables", "Variables" );
CAF_PDM_InitFieldNoDefault( &m_calculatedValues, "CalculatedValues", "Calculated Values" );
CAF_PDM_InitFieldNoDefault( &m_timesteps, "TimeSteps", "Time Steps" );
CAF_PDM_InitField( &m_id, "Id", -1, "Id" );
m_id.uiCapability()->setUiHidden( true );
m_exprContextMenuMgr = std::unique_ptr<RiuExpressionContextMenuManager>( new RiuExpressionContextMenuManager() );
m_isDirty = false;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimUserDefinedCalculation::setDescription( const QString& description )
{
m_description = description;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RimUserDefinedCalculation::description() const
{
return m_description;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimUserDefinedCalculation::setId( int id )
{
m_id = id;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
int RimUserDefinedCalculation::id() const
{
return m_id;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RimUserDefinedCalculation::isDirty() const
{
return m_isDirty;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
caf::PdmChildArrayFieldHandle* RimUserDefinedCalculation::variables()
{
return &m_variables;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimUserDefinedCalculationVariable* RimUserDefinedCalculation::addVariable( const QString& name )
{
RimUserDefinedCalculationVariable* v = createVariable();
v->setName( name );
m_variables.push_back( v );
return v;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimUserDefinedCalculation::deleteVariable( RimUserDefinedCalculationVariable* calcVariable )
{
m_variables.removeChildObject( calcVariable );
delete calcVariable;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const std::vector<double>& RimUserDefinedCalculation::values() const
{
return m_calculatedValues();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const std::vector<time_t>& RimUserDefinedCalculation::timeSteps() const
{
return m_timesteps();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimUserDefinedCalculation::setExpression( const QString& expr )
{
m_expression = expr;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RimUserDefinedCalculation::expression() const
{
return m_expression;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RimUserDefinedCalculation::unitName() const
{
return m_unit;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
caf::PdmFieldHandle* RimUserDefinedCalculation::userDescriptionField()
{
return &m_description;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RimUserDefinedCalculation::parseExpression()
{
QString leftHandSideVariableName = RimUserDefinedCalculation::findLeftHandSide( m_expression );
if ( leftHandSideVariableName.isEmpty() )
{
RiaLogging::errorInMessageBox( nullptr, "Expression Parser", "Failed to detect left hand side of equation" );
return false;
}
std::vector<QString> variableNames = ExpressionParser::detectReferencedVariables( m_expression );
if ( variableNames.size() < 1 )
{
RiaLogging::errorInMessageBox( nullptr, "Expression Parser", "Failed to detect any variable names" );
return false;
}
// Remove variables not present in expression
{
std::vector<RimUserDefinedCalculationVariable*> toBeDeleted;
for ( RimUserDefinedCalculationVariable* v : m_variables )
{
if ( std::find( variableNames.begin(), variableNames.end(), v->name() ) == variableNames.end() )
{
toBeDeleted.push_back( v );
}
if ( leftHandSideVariableName == v->name() )
{
toBeDeleted.push_back( v );
}
}
for ( RimUserDefinedCalculationVariable* v : toBeDeleted )
{
deleteVariable( v );
}
}
for ( auto variableName : variableNames )
{
if ( leftHandSideVariableName != variableName )
{
if ( !findByName( variableName ) )
{
this->addVariable( variableName );
}
}
}
m_description = buildCalculationName();
return true;
}
//--------------------------------------------------------------------------------------------------
/// Find the last assignment using := and interpret the text before the := as LHS
//--------------------------------------------------------------------------------------------------
QString RimUserDefinedCalculation::findLeftHandSide( const QString& expression )
{
int index = expression.lastIndexOf( ":=" );
if ( index > 0 )
{
QString s = expression.left( index ).simplified();
QStringList words = s.split( " " );
if ( words.size() > 0 )
{
return words.back();
}
}
return "";
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimUserDefinedCalculation::attachToWidget()
{
for ( auto e : m_expression.uiCapability()->connectedEditors() )
{
caf::PdmUiTextEditor* textEditor = dynamic_cast<caf::PdmUiTextEditor*>( e );
if ( !textEditor ) continue;
QWidget* containerWidget = textEditor->editorWidget();
if ( !containerWidget ) continue;
for ( auto qObj : containerWidget->children() )
{
QTextEdit* textEdit = dynamic_cast<QTextEdit*>( qObj );
if ( textEdit )
{
m_exprContextMenuMgr->attachTextEdit( textEdit );
}
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimUserDefinedCalculation::fieldChangedByUi( const caf::PdmFieldHandle* changedField,
const QVariant& oldValue,
const QVariant& newValue )
{
m_isDirty = true;
PdmObject::fieldChangedByUi( changedField, oldValue, newValue );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimUserDefinedCalculationVariable* RimUserDefinedCalculation::findByName( const QString& name ) const
{
for ( RimUserDefinedCalculationVariable* v : m_variables )
{
if ( v->name() == name )
{
return v;
}
}
return nullptr;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RimUserDefinedCalculation::buildCalculationName() const
{
QString name = "Default Calculation Name";
QString lhs = RimUserDefinedCalculation::findLeftHandSide( m_expression );
if ( !lhs.isEmpty() )
{
name = lhs;
name += " ( ";
for ( RimUserDefinedCalculationVariable* v : m_variables )
{
name += v->displayString();
if ( v != m_variables[m_variables.size() - 1] )
{
name += ", ";
}
}
name += " )";
}
return name;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimUserDefinedCalculation::defineEditorAttribute( const caf::PdmFieldHandle* field,
QString uiConfigName,
caf::PdmUiEditorAttribute* attribute )
{
if ( field == &m_expression )
{
caf::PdmUiTextEditorAttribute* myAttr = dynamic_cast<caf::PdmUiTextEditorAttribute*>( attribute );
if ( myAttr )
{
myAttr->heightHint = -1;
}
}
else if ( field == &m_variables )
{
auto* myAttr = dynamic_cast<caf::PdmUiTableViewEditorAttribute*>( attribute );
if ( myAttr )
{
myAttr->enableDropTarget = true;
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<RimUserDefinedCalculationVariable*> RimUserDefinedCalculation::allVariables() const
{
std::vector<RimUserDefinedCalculationVariable*> outVariables;
for ( RimUserDefinedCalculationVariable* v : m_variables )
outVariables.push_back( v );
return outVariables;
}

View File

@ -0,0 +1,101 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2017 Statoil ASA
//
// 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.
//
/////////////////////////////////////////////////////////////////////////////////
#pragma once
#include "RiuExpressionContextMenuManager.h"
#include "cafPdmChildArrayField.h"
#include "cafPdmField.h"
#include "cafPdmObject.h"
#include <QPointer>
#include <memory>
class RimUserDefinedCalculationVariable;
class QTextEdit;
//==================================================================================================
///
///
//==================================================================================================
class RimUserDefinedCalculation : public caf::PdmObject
{
CAF_PDM_HEADER_INIT;
public:
RimUserDefinedCalculation();
void setDescription( const QString& description );
QString description() const;
void setId( int id );
int id() const;
bool isDirty() const;
caf::PdmChildArrayFieldHandle* variables();
std::vector<RimUserDefinedCalculationVariable*> allVariables() const;
const std::vector<double>& values() const;
const std::vector<time_t>& timeSteps() const;
void setExpression( const QString& expr );
QString expression() const;
QString unitName() const;
bool parseExpression();
virtual bool calculate() = 0;
virtual void updateDependentObjects() = 0;
caf::PdmFieldHandle* userDescriptionField() override;
static QString findLeftHandSide( const QString& expression );
void attachToWidget();
protected:
virtual RimUserDefinedCalculationVariable* createVariable() const = 0;
void fieldChangedByUi( const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue ) override;
void defineEditorAttribute( const caf::PdmFieldHandle* field,
QString uiConfigName,
caf::PdmUiEditorAttribute* attribute ) override;
RimUserDefinedCalculationVariable* findByName( const QString& name ) const;
RimUserDefinedCalculationVariable* addVariable( const QString& name );
void deleteVariable( RimUserDefinedCalculationVariable* calcVariable );
QString buildCalculationName() const;
protected:
caf::PdmField<QString> m_description;
caf::PdmField<QString> m_expression;
caf::PdmField<QString> m_unit;
caf::PdmChildArrayField<RimUserDefinedCalculationVariable*> m_variables;
caf::PdmField<std::vector<double>> m_calculatedValues;
caf::PdmField<std::vector<time_t>> m_timesteps;
caf::PdmField<int> m_id;
std::unique_ptr<RiuExpressionContextMenuManager> m_exprContextMenuMgr;
bool m_isDirty;
};

View File

@ -0,0 +1,172 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2017 Statoil ASA
//
// 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 "RimUserDefinedCalculationCollection.h"
#include "RimCalculatedSummaryCase.h"
#include "RimProject.h"
#include "RimUserDefinedCalculation.h"
#include "cafPdmUiGroup.h"
#include "cafPdmUiTreeSelectionEditor.h"
CAF_PDM_XML_ABSTRACT_SOURCE_INIT( RimUserDefinedCalculationCollection, "RimUserDefinedCalculationCollection" );
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimUserDefinedCalculationCollection::RimUserDefinedCalculationCollection()
{
CAF_PDM_InitObject( "Calculation Collection", ":/chain.png" );
CAF_PDM_InitFieldNoDefault( &m_calculations, "Calculations", "Calculations" );
m_calculations.uiCapability()->setUiEditorTypeName( caf::PdmUiTreeSelectionEditor::uiEditorTypeName() );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimUserDefinedCalculation* RimUserDefinedCalculationCollection::addCalculation()
{
RimUserDefinedCalculation* calculation = createCalculation();
assignCalculationIdToCalculation( calculation );
QString varName = QString( "Calculation_%1" ).arg( calculation->id() );
calculation->setDescription( varName );
calculation->setExpression( varName + " := x + y" );
calculation->parseExpression();
m_calculations.push_back( calculation );
rebuildCaseMetaData();
return calculation;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimUserDefinedCalculation*
RimUserDefinedCalculationCollection::addCalculationCopy( const RimUserDefinedCalculation* sourceCalculation )
{
RimUserDefinedCalculation* calcCopy = dynamic_cast<RimUserDefinedCalculation*>(
sourceCalculation->xmlCapability()->copyByXmlSerialization( caf::PdmDefaultObjectFactory::instance() ) );
CVF_ASSERT( calcCopy );
std::set<QString> calcNames;
for ( const auto& calc : m_calculations )
{
calcNames.insert( calc->findLeftHandSide( calc->expression() ) );
}
QString expression = calcCopy->expression();
QString currVarName = calcCopy->findLeftHandSide( expression );
QString newVarName = currVarName;
while ( calcNames.count( newVarName ) > 0 )
{
newVarName += "_copy";
}
expression.replace( currVarName, newVarName );
calcCopy->setExpression( expression );
assignCalculationIdToCalculation( calcCopy );
m_calculations.push_back( calcCopy );
calcCopy->resolveReferencesRecursively();
rebuildCaseMetaData();
calcCopy->parseExpression();
return calcCopy;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimUserDefinedCalculationCollection::deleteCalculation( RimUserDefinedCalculation* calculation )
{
m_calculations.removeChildObject( calculation );
rebuildCaseMetaData();
delete calculation;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<RimUserDefinedCalculation*> RimUserDefinedCalculationCollection::calculations() const
{
return m_calculations.childObjects();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimUserDefinedCalculation* RimUserDefinedCalculationCollection::findCalculationById( int id ) const
{
for ( RimUserDefinedCalculation* calc : m_calculations )
{
if ( calc->id() == id )
{
return calc;
}
}
return nullptr;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimUserDefinedCalculationCollection::deleteAllContainedObjects()
{
m_calculations.deleteAllChildObjects();
rebuildCaseMetaData();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimUserDefinedCalculationCollection::ensureCalculationIds()
{
for ( RimUserDefinedCalculation* calculation : m_calculations )
{
if ( calculation->id() == -1 )
{
assignCalculationIdToCalculation( calculation );
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimUserDefinedCalculationCollection::assignCalculationIdToCalculation( RimUserDefinedCalculation* calculation ) const
{
int nextValidCalculationId = 1;
for ( RimUserDefinedCalculation* existingCalculation : calculations() )
{
nextValidCalculationId = std::max( nextValidCalculationId, existingCalculation->id() + 1 );
}
calculation->setId( nextValidCalculationId++ );
}

View File

@ -0,0 +1,56 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2017 Statoil ASA
//
// 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.
//
/////////////////////////////////////////////////////////////////////////////////
#pragma once
#include "cafPdmChildArrayField.h"
#include "cafPdmChildField.h"
#include "cafPdmObject.h"
class RimUserDefinedCalculation;
class RimUserDefinedCase;
class RimCalculatedSummaryCase;
//==================================================================================================
///
///
//==================================================================================================
class RimUserDefinedCalculationCollection : public caf::PdmObject
{
CAF_PDM_HEADER_INIT;
public:
RimUserDefinedCalculationCollection();
RimUserDefinedCalculation* addCalculation();
RimUserDefinedCalculation* addCalculationCopy( const RimUserDefinedCalculation* sourceCalculation );
void deleteCalculation( RimUserDefinedCalculation* calculation );
std::vector<RimUserDefinedCalculation*> calculations() const;
RimUserDefinedCalculation* findCalculationById( int id ) const;
void deleteAllContainedObjects();
virtual RimUserDefinedCalculation* createCalculation() const = 0;
virtual void rebuildCaseMetaData() = 0;
void ensureCalculationIds();
void assignCalculationIdToCalculation( RimUserDefinedCalculation* calculation ) const;
private:
caf::PdmChildArrayField<RimUserDefinedCalculation*> m_calculations;
};

View File

@ -0,0 +1,53 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2017 Statoil ASA
//
// 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 "RimUserDefinedCalculationVariable.h"
CAF_PDM_XML_ABSTRACT_SOURCE_INIT( RimUserDefinedCalculationVariable, "RimUserDefinedCalculationVariable" );
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimUserDefinedCalculationVariable::RimUserDefinedCalculationVariable()
{
CAF_PDM_InitObject( "RimUserDefinedCalculationVariable", ":/octave.png" );
CAF_PDM_InitFieldNoDefault( &m_name, "VariableName", "Variable Name" );
m_name.uiCapability()->setUiReadOnly( true );
CAF_PDM_InitFieldNoDefault( &m_addressUi, "AddressUi", "Address" );
m_addressUi.registerGetMethod( this, &RimUserDefinedCalculationVariable::displayString );
m_addressUi.xmlCapability()->disableIO();
m_addressUi.uiCapability()->setUiReadOnly( true );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RimUserDefinedCalculationVariable::name() const
{
return m_name;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimUserDefinedCalculationVariable::setName( const QString& name )
{
m_name = name;
}

View File

@ -0,0 +1,46 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2017 Statoil ASA
//
// 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.
//
/////////////////////////////////////////////////////////////////////////////////
#pragma once
#include "cafPdmField.h"
#include "cafPdmObject.h"
#include "cafPdmProxyValueField.h"
class RimUserDefinedCase;
//==================================================================================================
///
///
//==================================================================================================
class RimUserDefinedCalculationVariable : public caf::PdmObject
{
CAF_PDM_HEADER_INIT;
public:
RimUserDefinedCalculationVariable();
QString name() const;
void setName( const QString& name );
virtual QString displayString() const = 0;
protected:
caf::PdmField<QString> m_name;
caf::PdmProxyValueField<QString> m_addressUi;
};

View File

@ -82,7 +82,7 @@ void RifCalculatedSummaryCurveReader::buildMetaData()
{
m_allResultAddresses.clear();
for ( RimSummaryCalculation* calc : m_calculationCollection->calculations() )
for ( RimUserDefinedCalculation* calc : m_calculationCollection->calculations() )
{
m_allResultAddresses.insert(
RifEclipseSummaryAddress::calculatedAddress( calc->description().toStdString(), calc->id() ) );
@ -97,7 +97,7 @@ RimSummaryCalculation*
{
if ( m_calculationCollection && resultAddress.category() == RifEclipseSummaryAddress::SUMMARY_CALCULATED )
{
return m_calculationCollection->findCalculationById( resultAddress.id() );
return dynamic_cast<RimSummaryCalculation*>( m_calculationCollection->findCalculationById( resultAddress.id() ) );
}
return nullptr;

View File

@ -165,7 +165,7 @@ void RimSummaryAddress::ensureCalculationIdIsAssigned()
{
RimSummaryCalculationCollection* calcColl = RimProject::current()->calculationCollection();
for ( const RimSummaryCalculation* c : calcColl->calculations() )
for ( const RimUserDefinedCalculation* c : calcColl->calculations() )
{
QString description = c->description();

View File

@ -217,7 +217,7 @@ QString RimSummaryCurveAutoName::buildCurveName( const RifEclipseSummaryAddress&
RimProject* proj = RimProject::current();
RimSummaryCalculationCollection* calcColl = proj->calculationCollection();
RimSummaryCalculation* calculation = calcColl->findCalculationById( summaryAddress.id() );
RimUserDefinedCalculation* calculation = calcColl->findCalculationById( summaryAddress.id() );
if ( calculation )
{
text = calculation->description().toStdString();

View File

@ -17,14 +17,17 @@
/////////////////////////////////////////////////////////////////////////////////
#include "RiuCalculationsContextMenuManager.h"
#include "RimSummaryCalculationCollection.h"
#include "SummaryPlotCommands/RicSummaryCurveCalculatorUi.h"
#include "RicUserDefinedCalculatorUi.h"
#include <QMenu>
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuCalculationsContextMenuManager::attachWidget( QWidget* widget, RicSummaryCurveCalculatorUi* curveCalc )
void RiuCalculationsContextMenuManager::attachWidget( QWidget* widget, RicUserDefinedCalculatorUi* curveCalc )
{
if ( m_widget != widget )
{
@ -63,13 +66,15 @@ void RiuCalculationsContextMenuManager::slotMenuItems( QPoint point )
//--------------------------------------------------------------------------------------------------
void RiuCalculationsContextMenuManager::slotCreateCalculationCopy()
{
RimSummaryCalculation* currCalculation = m_curveCalc != nullptr ? m_curveCalc->currentCalculation() : nullptr;
if ( m_widget != nullptr && currCalculation != nullptr )
if ( m_widget != nullptr && m_curveCalc != nullptr )
{
RimSummaryCalculationCollection* coll = RicSummaryCurveCalculatorUi::calculationCollection();
RimSummaryCalculation* calcCopy = coll->addCalculationCopy( currCalculation );
m_curveCalc->setCurrentCalculation( calcCopy );
m_curveCalc->updateConnectedEditors();
RimUserDefinedCalculation* currCalculation = m_curveCalc->currentCalculation();
if ( currCalculation != nullptr )
{
RimUserDefinedCalculationCollection* coll = m_curveCalc->calculationCollection();
RimUserDefinedCalculation* calcCopy = coll->addCalculationCopy( currCalculation );
m_curveCalc->setCurrentCalculation( calcCopy );
m_curveCalc->updateConnectedEditors();
}
}
}

View File

@ -21,14 +21,15 @@
#include "cafPdmChildArrayField.h"
#include "cafPdmField.h"
#include "cafPdmObject.h"
#include <QAction>
#include <QPointer>
#include <QWidget>
#include <map>
#include <memory>
class RimSummaryCalculationVariable;
class RicSummaryCurveCalculatorUi;
class RicUserDefinedCalculatorUi;
//==================================================================================================
///
@ -47,7 +48,7 @@ public:
{
}
void attachWidget( QWidget* widget, RicSummaryCurveCalculatorUi* curveCalc );
void attachWidget( QWidget* widget, RicUserDefinedCalculatorUi* curveCalc );
public slots:
void slotMenuItems( QPoint point );
@ -57,7 +58,7 @@ private slots:
private:
QPointer<QWidget> m_widget;
RicSummaryCurveCalculatorUi* m_curveCalc;
RicUserDefinedCalculatorUi* m_curveCalc;
int m_textPosition;
std::map<QString, std::unique_ptr<QAction>> m_actionCache;
};

View File

@ -27,6 +27,8 @@
#include "RiaRegressionTest.h"
#include "RiaRegressionTestRunner.h"
#include "RicGridCalculatorDialog.h"
#include "Rim2dIntersectionView.h"
#include "Rim3dView.h"
#include "RimCellEdgeColors.h"
@ -2113,3 +2115,16 @@ bool RiuMainWindow::isAnyMdiSubWindowVisible()
{
return !m_mdiArea->subWindowList().empty();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RicGridCalculatorDialog* RiuMainWindow::gridCalculatorDialog( bool createIfNotPresent )
{
if ( !m_gridCalculatorDialog && createIfNotPresent )
{
m_gridCalculatorDialog = std::make_unique<RicGridCalculatorDialog>( this );
}
return m_gridCalculatorDialog.get();
}

View File

@ -51,6 +51,8 @@ class RiuRelativePermeabilityPlotPanel;
class RiuPvtPlotPanel;
class RiuMohrsCirclePlot;
class RicGridCalculatorDialog;
struct RimMdiWindowGeometry;
namespace caf
@ -126,6 +128,8 @@ public:
void setDefaultToolbarVisibility();
void applyFontSizesToDockedPlots();
RicGridCalculatorDialog* gridCalculatorDialog( bool createIfNotPresent );
protected:
void closeEvent( QCloseEvent* event ) override;
@ -171,10 +175,11 @@ private:
RiuProcessMonitor* m_processMonitor;
QPointer<RiuMessagePanel> m_messagePanel;
RiuResultQwtPlot* m_resultQwtPlot;
RiuMohrsCirclePlot* m_mohrsCirclePlot;
RiuRelativePermeabilityPlotPanel* m_relPermPlotPanel;
RiuPvtPlotPanel* m_pvtPlotPanel;
RiuResultQwtPlot* m_resultQwtPlot;
RiuMohrsCirclePlot* m_mohrsCirclePlot;
RiuRelativePermeabilityPlotPanel* m_relPermPlotPanel;
RiuPvtPlotPanel* m_pvtPlotPanel;
std::unique_ptr<RicGridCalculatorDialog> m_gridCalculatorDialog;
QMenu* m_windowMenu;
QLabel* m_memoryCriticalWarning;