2021-11-17 02:58:10 -06:00
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
//
|
|
|
|
// Copyright (C) 2021- 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 "RimSummaryPlotManager.h"
|
|
|
|
|
|
|
|
#include "RiaStdStringTools.h"
|
2021-11-19 07:53:01 -06:00
|
|
|
#include "RiaStringListSerializer.h"
|
|
|
|
#include "RiaSummaryStringTools.h"
|
2021-11-17 02:58:10 -06:00
|
|
|
#include "RiaSummaryTools.h"
|
|
|
|
|
|
|
|
#include "RifReaderEclipseSummary.h"
|
|
|
|
#include "RifSummaryReaderInterface.h"
|
|
|
|
|
|
|
|
#include "RimEnsembleCurveSet.h"
|
|
|
|
#include "RimEnsembleCurveSetCollection.h"
|
|
|
|
#include "RimSummaryCase.h"
|
|
|
|
#include "RimSummaryCaseCollection.h"
|
|
|
|
#include "RimSummaryCaseMainCollection.h"
|
|
|
|
#include "RimSummaryCurve.h"
|
|
|
|
#include "RimSummaryPlot.h"
|
|
|
|
#include "RimSummaryPlotCollection.h"
|
|
|
|
|
2021-12-03 07:32:58 -06:00
|
|
|
#include "PlotBuilderCommands/RicSummaryPlotBuilder.h"
|
2021-11-17 02:58:10 -06:00
|
|
|
#include "SummaryPlotCommands/RicSummaryPlotFeatureImpl.h"
|
|
|
|
|
2021-11-19 07:53:01 -06:00
|
|
|
#include "RiuPlotMainWindowTools.h"
|
|
|
|
|
2021-11-17 02:58:10 -06:00
|
|
|
#include "cafPdmObjectHandle.h"
|
|
|
|
#include "cafPdmUiCheckBoxEditor.h"
|
2021-11-19 07:53:01 -06:00
|
|
|
#include "cafPdmUiComboBoxEditor.h"
|
2021-11-17 02:58:10 -06:00
|
|
|
#include "cafPdmUiLabelEditor.h"
|
2021-11-19 07:53:01 -06:00
|
|
|
#include "cafPdmUiLineEditor.h"
|
2021-11-17 02:58:10 -06:00
|
|
|
#include "cafPdmUiPushButtonEditor.h"
|
2021-12-03 07:32:58 -06:00
|
|
|
#include "cafPdmUiTreeSelectionEditor.h"
|
2021-11-17 02:58:10 -06:00
|
|
|
#include "cafSelectionManager.h"
|
|
|
|
|
|
|
|
#include <QKeyEvent>
|
|
|
|
|
|
|
|
CAF_PDM_SOURCE_INIT( RimSummaryPlotManager, "RimSummaryPlotManager" );
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
///
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
RimSummaryPlotManager::RimSummaryPlotManager()
|
|
|
|
{
|
|
|
|
CAF_PDM_InitObject( "Summary Plot Manager" );
|
|
|
|
|
|
|
|
CAF_PDM_InitFieldNoDefault( &m_summaryPlot, "SummaryPlot", "Summary Plot" );
|
2021-11-19 07:53:01 -06:00
|
|
|
CAF_PDM_InitFieldNoDefault( &m_filterText, "FilterText", "Filter Text" );
|
|
|
|
m_filterText.uiCapability()->setUiEditorTypeName( caf::PdmUiComboBoxEditor::uiEditorTypeName() );
|
|
|
|
|
|
|
|
CAF_PDM_InitFieldNoDefault( &m_addressCandidates, "AddressCandidates", "Vectors" );
|
|
|
|
m_addressCandidates.uiCapability()->setUiLabelPosition( caf::PdmUiItemInfo::TOP );
|
2021-12-03 07:32:58 -06:00
|
|
|
CAF_PDM_InitFieldNoDefault( &m_selectedDataSources, "SelectedDataSources", "Data Sources" );
|
|
|
|
m_selectedDataSources.uiCapability()->setUiLabelPosition( caf::PdmUiItemInfo::TOP );
|
|
|
|
m_selectedDataSources.uiCapability()->setUiEditorTypeName( caf::PdmUiTreeSelectionEditor::uiEditorTypeName() );
|
2021-11-17 02:58:10 -06:00
|
|
|
|
|
|
|
CAF_PDM_InitField( &m_includeDiffCurves,
|
|
|
|
"IncludeDiffCurves",
|
2021-11-19 07:53:01 -06:00
|
|
|
false,
|
|
|
|
"Include Difference Vectors",
|
2021-11-17 02:58:10 -06:00
|
|
|
"",
|
|
|
|
"Difference between simulated and observed(history) curve",
|
|
|
|
"" );
|
|
|
|
m_includeDiffCurves.uiCapability()->setUiEditorTypeName( caf::PdmUiNativeCheckBoxEditor::uiEditorTypeName() );
|
|
|
|
|
|
|
|
CAF_PDM_InitFieldNoDefault( &m_pushButtonReplace, "PushButtonReplace", "Replace (CTRL + Enter)" );
|
|
|
|
m_pushButtonReplace.uiCapability()->setUiEditorTypeName( caf::PdmUiPushButtonEditor::uiEditorTypeName() );
|
|
|
|
m_pushButtonReplace.uiCapability()->setUiLabelPosition( caf::PdmUiItemInfo::HIDDEN );
|
|
|
|
|
|
|
|
CAF_PDM_InitFieldNoDefault( &m_pushButtonNewPlot, "PushButtonNewPlot", "New (Alt + Enter)" );
|
|
|
|
m_pushButtonNewPlot.uiCapability()->setUiEditorTypeName( caf::PdmUiPushButtonEditor::uiEditorTypeName() );
|
|
|
|
m_pushButtonNewPlot.uiCapability()->setUiLabelPosition( caf::PdmUiItemInfo::HIDDEN );
|
|
|
|
|
|
|
|
CAF_PDM_InitFieldNoDefault( &m_pushButtonAppend, "PushButtonAppend", "Append (Shift + Enter)" );
|
|
|
|
m_pushButtonAppend.uiCapability()->setUiEditorTypeName( caf::PdmUiPushButtonEditor::uiEditorTypeName() );
|
|
|
|
m_pushButtonAppend.uiCapability()->setUiLabelPosition( caf::PdmUiItemInfo::HIDDEN );
|
|
|
|
|
|
|
|
CAF_PDM_InitFieldNoDefault( &m_labelA, "LabelA", "" );
|
|
|
|
m_labelA.uiCapability()->setUiEditorTypeName( caf::PdmUiLabelEditor::uiEditorTypeName() );
|
|
|
|
m_labelA.xmlCapability()->disableIO();
|
|
|
|
m_labelA.uiCapability()->setUiLabelPosition( caf::PdmUiItemInfo::HIDDEN );
|
|
|
|
|
|
|
|
CAF_PDM_InitFieldNoDefault( &m_labelB, "LabelB", "" );
|
|
|
|
m_labelB.uiCapability()->setUiEditorTypeName( caf::PdmUiLabelEditor::uiEditorTypeName() );
|
|
|
|
m_labelB.xmlCapability()->disableIO();
|
2021-12-03 07:32:58 -06:00
|
|
|
|
|
|
|
CAF_PDM_InitField( &m_individualPlotPerVector, "IndividualPlotPerVector", false, "One plot per Vector" );
|
|
|
|
CAF_PDM_InitField( &m_individualPlotPerDataSource, "IndividualPlotPerDataSource", false, "One plot per Data Source" );
|
|
|
|
CAF_PDM_InitField( &m_createMultiPlot, "CreateMultiPlot", false, "Create Multiple Plots in One Window" );
|
2021-11-17 02:58:10 -06:00
|
|
|
}
|
|
|
|
|
2021-11-19 07:53:01 -06:00
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
///
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
void RimSummaryPlotManager::setFocusToFilterText()
|
|
|
|
{
|
|
|
|
setFocusToEditorWidget( m_filterText.uiCapability() );
|
|
|
|
}
|
|
|
|
|
2021-11-17 02:58:10 -06:00
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
///
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
void RimSummaryPlotManager::onSelectionManagerSelectionChanged( const std::set<int>& changedSelectionLevels )
|
|
|
|
{
|
|
|
|
updateUiFromSelection();
|
|
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
///
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
void RimSummaryPlotManager::fieldChangedByUi( const caf::PdmFieldHandle* changedField,
|
|
|
|
const QVariant& oldValue,
|
|
|
|
const QVariant& newValue )
|
|
|
|
{
|
2021-11-19 07:53:01 -06:00
|
|
|
if ( changedField == &m_summaryPlot || changedField == &m_filterText || changedField == &m_includeDiffCurves )
|
2021-11-17 02:58:10 -06:00
|
|
|
{
|
|
|
|
updateCurveCandidates();
|
|
|
|
}
|
|
|
|
else if ( changedField == &m_pushButtonReplace )
|
|
|
|
{
|
|
|
|
replaceCurves();
|
|
|
|
m_pushButtonReplace = false;
|
2021-11-19 07:53:01 -06:00
|
|
|
updateFilterTextHistory();
|
2021-11-17 02:58:10 -06:00
|
|
|
}
|
|
|
|
else if ( changedField == &m_pushButtonNewPlot )
|
|
|
|
{
|
|
|
|
createNewPlot();
|
|
|
|
m_pushButtonNewPlot = false;
|
2021-11-19 07:53:01 -06:00
|
|
|
updateFilterTextHistory();
|
2021-11-17 02:58:10 -06:00
|
|
|
}
|
|
|
|
else if ( changedField == &m_pushButtonAppend )
|
|
|
|
{
|
|
|
|
appendCurves();
|
|
|
|
m_pushButtonAppend = false;
|
2021-11-19 07:53:01 -06:00
|
|
|
updateFilterTextHistory();
|
2021-11-17 02:58:10 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
///
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
QList<caf::PdmOptionItemInfo>
|
|
|
|
RimSummaryPlotManager::calculateValueOptions( const caf::PdmFieldHandle* fieldNeedingOptions, bool* useOptionsOnly )
|
|
|
|
{
|
|
|
|
QList<caf::PdmOptionItemInfo> options;
|
|
|
|
if ( fieldNeedingOptions == &m_summaryPlot )
|
|
|
|
{
|
|
|
|
auto coll = RiaSummaryTools::summaryPlotCollection();
|
|
|
|
coll->summaryPlotItemInfos( &options );
|
|
|
|
}
|
2021-12-03 07:32:58 -06:00
|
|
|
else if ( fieldNeedingOptions == &m_filterText )
|
2021-11-19 07:53:01 -06:00
|
|
|
{
|
|
|
|
RiaStringListSerializer stringListSerializer( curveFilterRecentlyUsedRegistryKey() );
|
|
|
|
|
|
|
|
for ( const auto& s : stringListSerializer.textStrings() )
|
|
|
|
{
|
|
|
|
options.push_back( caf::PdmOptionItemInfo( s, s ) );
|
|
|
|
}
|
|
|
|
}
|
2021-12-03 07:32:58 -06:00
|
|
|
else if ( fieldNeedingOptions == &m_selectedDataSources )
|
|
|
|
{
|
|
|
|
auto [summaryCases, ensembles] = allDataSourcesInProject();
|
|
|
|
|
|
|
|
std::vector<QString> dataSourceDisplayNames;
|
|
|
|
|
|
|
|
bool resetCheckedItems = false;
|
|
|
|
|
|
|
|
std::vector<std::pair<QString, PdmObject*>> dataSources = findDataSourceCandidates();
|
|
|
|
for ( const auto& dataSource : dataSources )
|
|
|
|
{
|
|
|
|
auto displayName = dataSource.first;
|
|
|
|
dataSourceDisplayNames.push_back( displayName );
|
|
|
|
options.push_back( caf::PdmOptionItemInfo( displayName, displayName ) );
|
|
|
|
|
|
|
|
if ( m_previousDataSourceSelection.count( displayName ) == 0 ) resetCheckedItems = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( m_previousDataSourceSelection.size() != dataSourceDisplayNames.size() ) resetCheckedItems = true;
|
|
|
|
|
|
|
|
if ( resetCheckedItems )
|
|
|
|
{
|
|
|
|
// By default select all available data sources
|
|
|
|
m_selectedDataSources = dataSourceDisplayNames;
|
|
|
|
}
|
|
|
|
|
|
|
|
m_previousDataSourceSelection.clear();
|
|
|
|
m_previousDataSourceSelection.insert( dataSourceDisplayNames.begin(), dataSourceDisplayNames.end() );
|
|
|
|
}
|
2021-11-19 07:53:01 -06:00
|
|
|
|
2021-11-17 02:58:10 -06:00
|
|
|
return options;
|
|
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
///
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
void RimSummaryPlotManager::updateCurveCandidates()
|
|
|
|
{
|
2021-11-19 07:53:01 -06:00
|
|
|
std::vector<QString> curveCandidates;
|
|
|
|
|
|
|
|
auto addresses = filteredAddresses();
|
|
|
|
|
|
|
|
for ( const auto& adr : addresses )
|
|
|
|
{
|
|
|
|
curveCandidates.push_back( QString::fromStdString( adr.uiText() ) );
|
|
|
|
}
|
|
|
|
|
|
|
|
m_addressCandidates = curveCandidates;
|
|
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
///
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
std::vector<std::pair<QString, caf::PdmObject*>> RimSummaryPlotManager::findDataSourceCandidates() const
|
|
|
|
{
|
|
|
|
std::vector<std::pair<QString, PdmObject*>> candidates;
|
2021-11-17 02:58:10 -06:00
|
|
|
|
2021-11-19 07:53:01 -06:00
|
|
|
QStringList addressFilters;
|
|
|
|
QStringList dataSourceFilters;
|
|
|
|
splitIntoAddressAndDataSourceFilters( addressFilters, dataSourceFilters );
|
2021-11-17 02:58:10 -06:00
|
|
|
|
2021-11-19 07:53:01 -06:00
|
|
|
// If no filter on data source is specified, use wildcard to match all
|
|
|
|
if ( dataSourceFilters.empty() ) dataSourceFilters.push_back( "*" );
|
2021-11-17 02:58:10 -06:00
|
|
|
|
2021-11-19 07:53:01 -06:00
|
|
|
auto [summaryCases, ensembles] = allDataSourcesInProject();
|
|
|
|
|
|
|
|
for ( const auto& dsFilter : dataSourceFilters )
|
2021-11-17 02:58:10 -06:00
|
|
|
{
|
2021-11-19 07:53:01 -06:00
|
|
|
QString searchString = dsFilter.left( dsFilter.indexOf( ':' ) );
|
|
|
|
QRegExp searcher( searchString, Qt::CaseInsensitive, QRegExp::WildcardUnix );
|
|
|
|
|
|
|
|
for ( const auto& ensemble : ensembles )
|
|
|
|
{
|
|
|
|
auto ensembleName = ensemble->name();
|
|
|
|
if ( searcher.exactMatch( ensembleName ) )
|
|
|
|
{
|
|
|
|
if ( searchString == dsFilter )
|
|
|
|
{
|
|
|
|
// Match on ensemble name without realization filter
|
|
|
|
|
|
|
|
candidates.push_back( std::make_pair( ensembleName, ensemble ) );
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// Match on subset of realisations in ensemble
|
|
|
|
|
|
|
|
QString realizationSearchString = dsFilter.right( dsFilter.size() - dsFilter.indexOf( ':' ) - 1 );
|
|
|
|
QRegExp realizationSearcher( realizationSearchString, Qt::CaseInsensitive, QRegExp::WildcardUnix );
|
|
|
|
|
|
|
|
for ( const auto& summaryCase : ensemble->allSummaryCases() )
|
|
|
|
{
|
|
|
|
auto realizationName = summaryCase->displayCaseName();
|
|
|
|
if ( realizationSearcher.exactMatch( realizationName ) )
|
|
|
|
{
|
|
|
|
QString displayName = ensembleName + ":" + realizationName;
|
|
|
|
candidates.push_back( std::make_pair( displayName, summaryCase ) );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
for ( const auto& summaryCase : summaryCases )
|
|
|
|
{
|
|
|
|
auto summaryCaseName = summaryCase->displayCaseName();
|
|
|
|
if ( searcher.exactMatch( summaryCaseName ) )
|
|
|
|
{
|
|
|
|
candidates.push_back( std::make_pair( summaryCase->displayCaseName(), summaryCase ) );
|
|
|
|
}
|
|
|
|
}
|
2021-11-17 02:58:10 -06:00
|
|
|
}
|
|
|
|
|
2021-11-19 07:53:01 -06:00
|
|
|
return candidates;
|
2021-11-17 02:58:10 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
///
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
std::set<RifEclipseSummaryAddress>
|
|
|
|
RimSummaryPlotManager::computeFilteredAddresses( const QStringList& textFilters,
|
|
|
|
const std::set<RifEclipseSummaryAddress>& sourceAddresses )
|
|
|
|
{
|
|
|
|
std::set<RifEclipseSummaryAddress> addresses;
|
|
|
|
|
|
|
|
std::vector<bool> usedFilters;
|
|
|
|
RicSummaryPlotFeatureImpl::insertFilteredAddressesInSet( textFilters, sourceAddresses, &addresses, &usedFilters );
|
|
|
|
|
|
|
|
if ( m_includeDiffCurves ) return addresses;
|
|
|
|
|
|
|
|
const auto diffText = RifReaderEclipseSummary::differenceIdentifier();
|
|
|
|
|
|
|
|
std::set<RifEclipseSummaryAddress> addressesWithoutDiffVectors;
|
|
|
|
for ( const auto& adr : addresses )
|
|
|
|
{
|
|
|
|
if ( RiaStdStringTools::endsWith( adr.quantityName(), diffText ) ) continue;
|
|
|
|
|
|
|
|
addressesWithoutDiffVectors.insert( adr );
|
|
|
|
}
|
|
|
|
|
|
|
|
return addressesWithoutDiffVectors;
|
|
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
///
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
void RimSummaryPlotManager::defineEditorAttribute( const caf::PdmFieldHandle* field,
|
|
|
|
QString uiConfigName,
|
|
|
|
caf::PdmUiEditorAttribute* attribute )
|
|
|
|
{
|
|
|
|
{
|
2021-11-19 07:53:01 -06:00
|
|
|
auto attr = dynamic_cast<caf::PdmUiPushButtonEditorAttribute*>( attribute );
|
|
|
|
if ( attr )
|
2021-11-17 02:58:10 -06:00
|
|
|
{
|
|
|
|
if ( field == &m_pushButtonReplace )
|
|
|
|
{
|
2021-11-19 07:53:01 -06:00
|
|
|
attr->m_buttonText = "Replace Curves \n(Ctrl + Enter)";
|
2021-11-17 02:58:10 -06:00
|
|
|
}
|
|
|
|
if ( field == &m_pushButtonNewPlot )
|
|
|
|
{
|
2021-12-03 07:32:58 -06:00
|
|
|
attr->m_buttonText = "Create New Plot \n(Enter)";
|
2021-11-17 02:58:10 -06:00
|
|
|
}
|
|
|
|
if ( field == &m_pushButtonAppend )
|
|
|
|
{
|
2021-11-19 07:53:01 -06:00
|
|
|
attr->m_buttonText = "Append Curves \n(Shift + Enter)";
|
2021-11-17 02:58:10 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2021-11-19 07:53:01 -06:00
|
|
|
|
|
|
|
if ( field == &m_filterText )
|
|
|
|
{
|
|
|
|
auto attr = dynamic_cast<caf::PdmUiComboBoxEditorAttribute*>( attribute );
|
|
|
|
if ( attr )
|
|
|
|
{
|
|
|
|
attr->enableEditableContent = true;
|
2021-12-03 07:32:58 -06:00
|
|
|
attr->enableAutoComplete = false;
|
2021-11-19 07:53:01 -06:00
|
|
|
attr->adjustWidthToContents = true;
|
|
|
|
attr->notifyWhenTextIsEdited = true;
|
|
|
|
}
|
|
|
|
}
|
2021-11-17 02:58:10 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
///
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
void RimSummaryPlotManager::defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering )
|
|
|
|
{
|
|
|
|
uiOrdering.add( &m_summaryPlot );
|
|
|
|
|
|
|
|
uiOrdering.add( &m_includeDiffCurves );
|
|
|
|
|
2021-11-19 07:53:01 -06:00
|
|
|
uiOrdering.add( &m_filterText );
|
|
|
|
uiOrdering.add( &m_addressCandidates );
|
2021-12-03 07:32:58 -06:00
|
|
|
uiOrdering.add( &m_selectedDataSources, false );
|
|
|
|
|
|
|
|
uiOrdering.add( &m_individualPlotPerVector );
|
|
|
|
uiOrdering.add( &m_individualPlotPerDataSource );
|
|
|
|
uiOrdering.add( &m_createMultiPlot );
|
2021-11-17 02:58:10 -06:00
|
|
|
|
2021-11-19 07:53:01 -06:00
|
|
|
uiOrdering.add( &m_pushButtonAppend );
|
2021-11-17 02:58:10 -06:00
|
|
|
uiOrdering.add( &m_pushButtonReplace, { false } );
|
2021-11-19 07:53:01 -06:00
|
|
|
uiOrdering.add( &m_labelB, { false } );
|
2021-11-17 02:58:10 -06:00
|
|
|
uiOrdering.add( &m_pushButtonNewPlot, { false } );
|
|
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
///
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
void RimSummaryPlotManager::appendCurves()
|
|
|
|
{
|
2021-12-03 07:32:58 -06:00
|
|
|
if ( !m_summaryPlot ) return;
|
2021-11-17 02:58:10 -06:00
|
|
|
|
2021-12-03 07:32:58 -06:00
|
|
|
appendCurvesToPlot( m_summaryPlot );
|
2021-11-17 02:58:10 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
///
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
void RimSummaryPlotManager::replaceCurves()
|
|
|
|
{
|
2021-12-03 07:32:58 -06:00
|
|
|
if ( !m_summaryPlot ) return;
|
|
|
|
|
2021-11-17 02:58:10 -06:00
|
|
|
RimSummaryPlot* destinationPlot = m_summaryPlot;
|
|
|
|
destinationPlot->deleteAllSummaryCurves();
|
|
|
|
destinationPlot->ensembleCurveSetCollection()->deleteAllCurveSets();
|
|
|
|
|
2021-11-19 07:53:01 -06:00
|
|
|
RiuPlotMainWindowTools::selectAsCurrentItem( destinationPlot );
|
|
|
|
|
2021-11-17 02:58:10 -06:00
|
|
|
appendCurvesToPlot( destinationPlot );
|
|
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
///
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
void RimSummaryPlotManager::createNewPlot()
|
|
|
|
{
|
2021-12-03 07:32:58 -06:00
|
|
|
std::vector<RimSummaryCase*> summaryCases;
|
|
|
|
std::vector<RimSummaryCaseCollection*> ensembles;
|
|
|
|
findFilteredSummaryCasesAndEnsembles( summaryCases, ensembles );
|
2021-11-17 02:58:10 -06:00
|
|
|
|
2021-12-03 07:32:58 -06:00
|
|
|
std::set<RifEclipseSummaryAddress> filteredAddressesFromSource = filteredAddresses();
|
|
|
|
|
|
|
|
RicSummaryPlotBuilder plotBuilder;
|
|
|
|
plotBuilder.setAddresses( filteredAddressesFromSource );
|
|
|
|
plotBuilder.setDataSources( summaryCases, ensembles );
|
|
|
|
plotBuilder.setIndividualPlotPerAddress( m_individualPlotPerVector );
|
|
|
|
plotBuilder.setIndividualPlotPerDataSource( m_individualPlotPerDataSource );
|
|
|
|
|
|
|
|
auto plots = plotBuilder.createPlots();
|
|
|
|
if ( m_createMultiPlot )
|
|
|
|
{
|
|
|
|
std::vector<RimPlot*> plotsForMultiPlot;
|
|
|
|
for ( auto p : plots )
|
|
|
|
{
|
|
|
|
p->loadDataAndUpdate();
|
|
|
|
plotsForMultiPlot.push_back( dynamic_cast<RimPlot*>( p ) );
|
|
|
|
}
|
|
|
|
RicSummaryPlotBuilder::createAndAppendMultiPlot( plotsForMultiPlot );
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
auto plotCollection = RiaSummaryTools::summaryPlotCollection();
|
|
|
|
for ( auto plot : plots )
|
|
|
|
{
|
|
|
|
plot->setAsPlotMdiWindow();
|
|
|
|
|
|
|
|
plotCollection->addPlot( plot );
|
|
|
|
|
|
|
|
plot->loadDataAndUpdate();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
updateProjectTreeAndRefresUi();
|
2021-11-17 02:58:10 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
///
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
bool RimSummaryPlotManager::eventFilter( QObject* obj, QEvent* event )
|
|
|
|
{
|
|
|
|
if ( event->type() == QEvent::KeyPress )
|
|
|
|
{
|
|
|
|
QKeyEvent* keyEvent = static_cast<QKeyEvent*>( event );
|
|
|
|
|
|
|
|
if ( keyEvent && ( keyEvent->key() == Qt::Key_Enter || keyEvent->key() == Qt::Key_Return ) )
|
|
|
|
{
|
|
|
|
auto mods = keyEvent->modifiers();
|
|
|
|
|
|
|
|
if ( mods & Qt::ShiftModifier )
|
|
|
|
appendCurves();
|
|
|
|
else if ( mods & Qt::ControlModifier )
|
|
|
|
replaceCurves();
|
2021-11-19 07:53:01 -06:00
|
|
|
else if ( mods == Qt::NoModifier )
|
2021-12-03 07:32:58 -06:00
|
|
|
createNewPlot();
|
2021-11-17 02:58:10 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return QObject::eventFilter( obj, event );
|
|
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
///
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
2021-11-19 07:53:01 -06:00
|
|
|
std::pair<std::vector<RimSummaryCase*>, std::vector<RimSummaryCaseCollection*>>
|
|
|
|
RimSummaryPlotManager::allDataSourcesInProject() const
|
2021-11-17 02:58:10 -06:00
|
|
|
{
|
|
|
|
auto sumCaseMainColl = RiaSummaryTools::summaryCaseMainCollection();
|
|
|
|
|
|
|
|
auto summaryCases = sumCaseMainColl->topLevelSummaryCases();
|
|
|
|
auto ensembles = sumCaseMainColl->summaryCaseCollections();
|
|
|
|
|
|
|
|
return { summaryCases, ensembles };
|
|
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
///
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
void RimSummaryPlotManager::updateUiFromSelection()
|
|
|
|
{
|
|
|
|
auto destinationObject = dynamic_cast<caf::PdmObjectHandle*>( caf::SelectionManager::instance()->selectedItem() );
|
|
|
|
|
|
|
|
RimSummaryPlot* summaryPlot = nullptr;
|
|
|
|
if ( destinationObject ) destinationObject->firstAncestorOrThisOfType( summaryPlot );
|
|
|
|
|
2021-12-03 07:32:58 -06:00
|
|
|
if ( summaryPlot && ( m_summaryPlot() != summaryPlot ) )
|
2021-11-17 02:58:10 -06:00
|
|
|
{
|
|
|
|
m_summaryPlot = summaryPlot;
|
2021-12-03 07:32:58 -06:00
|
|
|
|
|
|
|
updateCurveCandidates();
|
2021-11-17 02:58:10 -06:00
|
|
|
}
|
2021-12-03 07:32:58 -06:00
|
|
|
|
|
|
|
if ( !summaryPlot )
|
|
|
|
{
|
|
|
|
m_summaryPlot = nullptr;
|
|
|
|
|
|
|
|
std::vector<QString> tmp;
|
|
|
|
m_addressCandidates = tmp;
|
|
|
|
m_selectedDataSources = tmp;
|
|
|
|
}
|
|
|
|
|
|
|
|
updateConnectedEditors();
|
2021-11-17 02:58:10 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
///
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
std::set<RifEclipseSummaryAddress> RimSummaryPlotManager::filteredAddresses()
|
|
|
|
{
|
2021-11-19 07:53:01 -06:00
|
|
|
std::vector<RimSummaryCase*> summaryCases;
|
|
|
|
std::vector<RimSummaryCaseCollection*> ensembles;
|
|
|
|
findFilteredSummaryCasesAndEnsembles( summaryCases, ensembles );
|
2021-11-17 02:58:10 -06:00
|
|
|
|
2021-11-19 07:53:01 -06:00
|
|
|
std::set<RifEclipseSummaryAddress> nativeAddresses;
|
2021-11-17 02:58:10 -06:00
|
|
|
if ( !summaryCases.empty() )
|
|
|
|
{
|
2021-12-03 07:32:58 -06:00
|
|
|
nativeAddresses = RicSummaryPlotBuilder::addressesForSource( summaryCases.front() );
|
2021-11-17 02:58:10 -06:00
|
|
|
}
|
|
|
|
else if ( !ensembles.empty() )
|
|
|
|
{
|
2021-12-03 07:32:58 -06:00
|
|
|
nativeAddresses = RicSummaryPlotBuilder::addressesForSource( ensembles.front() );
|
2021-11-17 02:58:10 -06:00
|
|
|
}
|
|
|
|
|
2021-11-19 07:53:01 -06:00
|
|
|
if ( nativeAddresses.empty() ) return {};
|
2021-11-17 02:58:10 -06:00
|
|
|
|
2021-11-19 07:53:01 -06:00
|
|
|
QStringList allCurveAddressFilters = m_filterText().split( QRegExp( "\\s+" ), QString::SkipEmptyParts );
|
2021-11-17 02:58:10 -06:00
|
|
|
|
2021-11-19 07:53:01 -06:00
|
|
|
return computeFilteredAddresses( allCurveAddressFilters, nativeAddresses );
|
2021-11-17 02:58:10 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
///
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
void RimSummaryPlotManager::appendCurvesToPlot( RimSummaryPlot* destinationPlot )
|
|
|
|
{
|
|
|
|
CAF_ASSERT( destinationPlot );
|
|
|
|
|
2021-11-19 07:53:01 -06:00
|
|
|
std::vector<RimSummaryCase*> summaryCases;
|
|
|
|
std::vector<RimSummaryCaseCollection*> ensembles;
|
|
|
|
findFilteredSummaryCasesAndEnsembles( summaryCases, ensembles );
|
2021-11-17 02:58:10 -06:00
|
|
|
|
|
|
|
std::set<RifEclipseSummaryAddress> filteredAddressesFromSource = filteredAddresses();
|
2021-12-03 07:32:58 -06:00
|
|
|
RicSummaryPlotBuilder::appendCurvesToPlot( destinationPlot, filteredAddressesFromSource, summaryCases, ensembles );
|
2021-11-17 02:58:10 -06:00
|
|
|
|
|
|
|
destinationPlot->applyDefaultCurveAppearances();
|
|
|
|
destinationPlot->loadDataAndUpdate();
|
|
|
|
|
2021-12-03 07:32:58 -06:00
|
|
|
updateProjectTreeAndRefresUi();
|
2021-11-19 07:53:01 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
///
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
void RimSummaryPlotManager::updateFilterTextHistory()
|
|
|
|
{
|
|
|
|
RiaStringListSerializer stringListSerializer( curveFilterRecentlyUsedRegistryKey() );
|
|
|
|
|
|
|
|
int maxItemCount = 10;
|
|
|
|
stringListSerializer.addString( m_filterText, maxItemCount );
|
2021-11-17 02:58:10 -06:00
|
|
|
}
|
|
|
|
|
2021-12-03 07:32:58 -06:00
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
///
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
void RimSummaryPlotManager::updateProjectTreeAndRefresUi()
|
|
|
|
{
|
|
|
|
RiaSummaryTools::summaryPlotCollection()->updateConnectedEditors();
|
|
|
|
|
|
|
|
updateFilterTextHistory();
|
|
|
|
m_filterText.uiCapability()->updateConnectedEditors();
|
|
|
|
|
|
|
|
setFocusToFilterText();
|
|
|
|
}
|
|
|
|
|
2021-11-17 02:58:10 -06:00
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
///
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
void RimSummaryPlotManager::setFocusToEditorWidget( caf::PdmUiFieldHandle* uiFieldHandle )
|
|
|
|
{
|
|
|
|
CAF_ASSERT( uiFieldHandle );
|
|
|
|
|
|
|
|
auto editors = uiFieldHandle->connectedEditors();
|
|
|
|
if ( !editors.empty() )
|
|
|
|
{
|
|
|
|
auto fieldEditorHandle = dynamic_cast<caf::PdmUiFieldEditorHandle*>( editors.front() );
|
|
|
|
if ( fieldEditorHandle && fieldEditorHandle->editorWidget() )
|
|
|
|
{
|
|
|
|
auto widget = fieldEditorHandle->editorWidget();
|
|
|
|
|
|
|
|
// If the dock widget is floating, activateWindow() must be called to make sure the top level widget has
|
|
|
|
// focus before the editor widget is given focus
|
|
|
|
widget->activateWindow();
|
|
|
|
widget->setFocus();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2021-11-19 07:53:01 -06:00
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
///
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
void RimSummaryPlotManager::splitIntoAddressAndDataSourceFilters( QStringList& addressFilters,
|
|
|
|
QStringList& dataSourceFilters ) const
|
|
|
|
{
|
|
|
|
QStringList filterItems = m_filterText().split( QRegExp( "\\s+" ), QString::SkipEmptyParts );
|
|
|
|
|
|
|
|
auto [summaryCases, ensembles] = allDataSourcesInProject();
|
|
|
|
|
|
|
|
QStringList dataSourceNames;
|
|
|
|
for ( const auto& summaryCase : summaryCases )
|
|
|
|
{
|
|
|
|
dataSourceNames.push_back( summaryCase->displayCaseName() );
|
|
|
|
}
|
|
|
|
|
|
|
|
for ( const auto& ensemble : ensembles )
|
|
|
|
{
|
|
|
|
dataSourceNames.push_back( ensemble->name() );
|
|
|
|
}
|
|
|
|
|
|
|
|
RiaSummaryStringTools::splitIntoAddressAndDataSourceFilters( filterItems,
|
|
|
|
dataSourceNames,
|
|
|
|
addressFilters,
|
|
|
|
dataSourceFilters );
|
|
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
///
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
void RimSummaryPlotManager::findFilteredSummaryCasesAndEnsembles( std::vector<RimSummaryCase*>& summaryCases,
|
|
|
|
std::vector<RimSummaryCaseCollection*>& ensembles ) const
|
|
|
|
{
|
|
|
|
auto filteredDataSources = findDataSourceCandidates();
|
2021-12-03 07:32:58 -06:00
|
|
|
for ( const auto& [dataSourceName, dataSource] : filteredDataSources )
|
2021-11-19 07:53:01 -06:00
|
|
|
{
|
2021-12-03 07:32:58 -06:00
|
|
|
auto selectedDataSources = m_selectedDataSources();
|
|
|
|
|
|
|
|
if ( std::find( selectedDataSources.begin(), selectedDataSources.end(), dataSourceName ) ==
|
|
|
|
std::end( selectedDataSources ) )
|
|
|
|
continue;
|
|
|
|
|
|
|
|
auto summaryCase = dynamic_cast<RimSummaryCase*>( dataSource );
|
2021-11-19 07:53:01 -06:00
|
|
|
if ( summaryCase )
|
|
|
|
{
|
|
|
|
summaryCases.push_back( summaryCase );
|
|
|
|
}
|
|
|
|
|
2021-12-03 07:32:58 -06:00
|
|
|
auto ensemble = dynamic_cast<RimSummaryCaseCollection*>( dataSource );
|
2021-11-19 07:53:01 -06:00
|
|
|
if ( ensemble )
|
|
|
|
{
|
|
|
|
ensembles.push_back( ensemble );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
///
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
QString RimSummaryPlotManager::curveFilterRecentlyUsedRegistryKey()
|
|
|
|
{
|
|
|
|
return "SummaryPlotManagerCurveFilterStrings";
|
|
|
|
}
|