#8345 Summary Plot Manager : Several improvements

Add checkboxes for individual plots for vectors/addresses and creation of multiplots.
Moved code into RicSummaryPlotBuilder.
Allow UiComboBoxEditor to disable autocomplete.
Create plot using Enter key without modifiers.
This commit is contained in:
Magne Sjaastad 2021-12-03 14:32:58 +01:00
parent 178a5ab583
commit 34fb7d7e84
12 changed files with 555 additions and 199 deletions

View File

@ -41,6 +41,7 @@ set(COMMAND_REFERENCED_CMAKE_FILES
WellPathCommands/CMakeLists_files.cmake
PlotTemplateCommands/CMakeLists_files.cmake
FractureCommands/CMakeLists_files.cmake
PlotBuilderCommands/CMakeLists_files.cmake
)
# Include source file lists from *.cmake files

View File

@ -61,7 +61,6 @@ set(SOURCE_GROUP_HEADER_FILES
${CMAKE_CURRENT_LIST_DIR}/RicDeleteTemporaryLgrsFeature.h
${CMAKE_CURRENT_LIST_DIR}/RicExportContourMapToTextFeature.h
${CMAKE_CURRENT_LIST_DIR}/RicExportContourMapToTextUi.h
${CMAKE_CURRENT_LIST_DIR}/RicNewMultiPlotFeature.h
${CMAKE_CURRENT_LIST_DIR}/RicExportStimPlanModelToFileFeature.h
${CMAKE_CURRENT_LIST_DIR}/RicStackSelectedCurvesFeature.h
${CMAKE_CURRENT_LIST_DIR}/RicUnstackSelectedCurvesFeature.h
@ -143,7 +142,6 @@ set(SOURCE_GROUP_SOURCE_FILES
${CMAKE_CURRENT_LIST_DIR}/RicDeleteTemporaryLgrsFeature.cpp
${CMAKE_CURRENT_LIST_DIR}/RicExportContourMapToTextFeature.cpp
${CMAKE_CURRENT_LIST_DIR}/RicExportContourMapToTextUi.cpp
${CMAKE_CURRENT_LIST_DIR}/RicNewMultiPlotFeature.cpp
${CMAKE_CURRENT_LIST_DIR}/RicExportStimPlanModelToFileFeature.cpp
${CMAKE_CURRENT_LIST_DIR}/RicStackSelectedCurvesFeature.cpp
${CMAKE_CURRENT_LIST_DIR}/RicUnstackSelectedCurvesFeature.cpp

View File

@ -0,0 +1,20 @@
set(SOURCE_GROUP_HEADER_FILES ${CMAKE_CURRENT_LIST_DIR}/RicNewMultiPlotFeature.h
${CMAKE_CURRENT_LIST_DIR}/RicSummaryPlotBuilder.h
)
set(SOURCE_GROUP_SOURCE_FILES
${CMAKE_CURRENT_LIST_DIR}/RicNewMultiPlotFeature.cpp
${CMAKE_CURRENT_LIST_DIR}/RicSummaryPlotBuilder.cpp
)
list(APPEND COMMAND_CODE_HEADER_FILES ${SOURCE_GROUP_HEADER_FILES})
list(APPEND COMMAND_CODE_SOURCE_FILES ${SOURCE_GROUP_SOURCE_FILES})
list(APPEND COMMAND_QT_MOC_HEADERS)
source_group(
"CommandFeature\\PlotBuilder"
FILES ${SOURCE_GROUP_HEADER_FILES} ${SOURCE_GROUP_SOURCE_FILES}
${CMAKE_CURRENT_LIST_DIR}/CMakeLists_files.cmake
)

View File

@ -19,21 +19,18 @@
#include "RicNewMultiPlotFeature.h"
#include "RimMainPlotCollection.h"
#include "RimMultiPlot.h"
#include "RimMultiPlotCollection.h"
#include "RicSummaryPlotBuilder.h"
#include "RimPlot.h"
#include "RimProject.h"
#include "RimSaturationPressurePlot.h"
#include "RimWellLogTrack.h"
#include "RiuPlotMainWindowTools.h"
#include <QAction>
#include "cafSelectionManager.h"
#include "cvfAssert.h"
#include <QAction>
RICF_SOURCE_INIT( RicNewMultiPlotFeature, "RicNewMultiPlotFeature", "createMultiPlot" );
//--------------------------------------------------------------------------------------------------
@ -49,14 +46,6 @@ RicNewMultiPlotFeature::RicNewMultiPlotFeature()
//--------------------------------------------------------------------------------------------------
caf::PdmScriptResponse RicNewMultiPlotFeature::execute()
{
RimProject* project = RimProject::current();
RimMultiPlotCollection* plotCollection = project->mainPlotCollection()->multiPlotCollection();
RimMultiPlot* plotWindow = new RimMultiPlot;
plotWindow->setMultiPlotTitle( QString( "Multi Plot %1" ).arg( plotCollection->multiPlots().size() + 1 ) );
plotWindow->setAsPlotMdiWindow();
plotCollection->addMultiPlot( plotWindow );
if ( !m_plots().empty() )
{
std::vector<RimPlot*> plots;
@ -65,40 +54,11 @@ caf::PdmScriptResponse RicNewMultiPlotFeature::execute()
plots.push_back( reinterpret_cast<RimPlot*>( ptr ) );
}
for ( auto plot : plots )
{
auto copy = dynamic_cast<RimPlot*>( plot->copyByXmlSerialization( caf::PdmDefaultObjectFactory::instance() ) );
auto copyOfPlots = RicSummaryPlotBuilder::duplicatePlots( plots );
{
// TODO: Workaround for fixing the PdmPointer in RimEclipseResultDefinition
// caf::PdmPointer<RimEclipseCase> m_eclipseCase;
// This pdmpointer must be changed to a ptrField
auto saturationPressurePlotOriginal = dynamic_cast<RimSaturationPressurePlot*>( plot );
auto saturationPressurePlotCopy = dynamic_cast<RimSaturationPressurePlot*>( copy );
if ( saturationPressurePlotCopy && saturationPressurePlotOriginal )
{
RimSaturationPressurePlot::fixPointersAfterCopy( saturationPressurePlotOriginal,
saturationPressurePlotCopy );
}
}
plotWindow->addPlot( copy );
copy->resolveReferencesRecursively();
copy->revokeMdiWindowStatus();
copy->setShowWindow( true );
copy->loadDataAndUpdate();
}
RicSummaryPlotBuilder::createAndAppendMultiPlot( copyOfPlots );
}
project->updateAllRequiredEditors();
plotWindow->loadDataAndUpdate();
RiuPlotMainWindowTools::setExpanded( plotCollection, true );
RiuPlotMainWindowTools::selectAsCurrentItem( plotWindow, true );
return caf::PdmScriptResponse();
}

View File

@ -0,0 +1,293 @@
////////////////////////////////////////////////////////////////////////////////
//
// 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 "RicSummaryPlotBuilder.h"
#include "RiaSummaryTools.h"
#include "RifEclipseSummaryAddress.h"
#include "RifReaderEclipseSummary.h"
#include "RifSummaryReaderInterface.h"
#include "RimEnsembleCurveSet.h"
#include "RimEnsembleCurveSetCollection.h"
#include "RimMainPlotCollection.h"
#include "RimMultiPlot.h"
#include "RimMultiPlotCollection.h"
#include "RimPlot.h"
#include "RimProject.h"
#include "RimSaturationPressurePlot.h"
#include "RimSummaryCase.h"
#include "RimSummaryCaseCollection.h"
#include "RimSummaryCurve.h"
#include "RimSummaryPlotCollection.h"
#include "RiuPlotMainWindowTools.h"
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RicSummaryPlotBuilder::RicSummaryPlotBuilder()
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RicSummaryPlotBuilder::setDataSources( const std::vector<RimSummaryCase*>& summaryCases,
const std::vector<RimSummaryCaseCollection*>& ensembles )
{
m_summaryCases = summaryCases;
m_ensembles = ensembles;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RicSummaryPlotBuilder::setAddresses( const std::set<RifEclipseSummaryAddress>& addresses )
{
m_addresses = addresses;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RicSummaryPlotBuilder::setIndividualPlotPerAddress( bool enable )
{
m_individualPlotPerAddress = enable;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RicSummaryPlotBuilder::setIndividualPlotPerDataSource( bool enable )
{
m_individualPlotPerDataSource = enable;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<RimSummaryPlot*> RicSummaryPlotBuilder::createPlots() const
{
std::vector<RimSummaryPlot*> plots;
if ( m_individualPlotPerDataSource && m_individualPlotPerAddress )
{
for ( auto adr : m_addresses )
{
for ( auto summaryCase : m_summaryCases )
{
auto plot = createPlot( { adr }, { summaryCase }, {} );
plots.push_back( plot );
}
for ( auto ensemble : m_ensembles )
{
auto plot = createPlot( { adr }, {}, { ensemble } );
plots.push_back( plot );
}
}
}
else if ( m_individualPlotPerAddress )
{
for ( auto adr : m_addresses )
{
auto plot = createPlot( { adr }, m_summaryCases, m_ensembles );
plots.push_back( plot );
}
}
else if ( m_individualPlotPerDataSource )
{
for ( auto summaryCase : m_summaryCases )
{
auto plot = createPlot( m_addresses, { summaryCase }, {} );
plots.push_back( plot );
}
for ( auto ensemble : m_ensembles )
{
auto plot = createPlot( m_addresses, {}, { ensemble } );
plots.push_back( plot );
}
}
else
{
auto plot = createPlot( m_addresses, m_summaryCases, m_ensembles );
plots.push_back( plot );
}
return plots;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::set<RifEclipseSummaryAddress> RicSummaryPlotBuilder::addressesForSource( caf::PdmObject* summarySource )
{
auto ensemble = dynamic_cast<RimSummaryCaseCollection*>( summarySource );
if ( ensemble )
{
return ensemble->ensembleSummaryAddresses();
}
auto sumCase = dynamic_cast<RimSummaryCase*>( summarySource );
if ( sumCase )
{
auto reader = sumCase ? sumCase->summaryReader() : nullptr;
if ( reader )
{
return reader->allResultAddresses();
}
}
return {};
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimEnsembleCurveSet* RicSummaryPlotBuilder::createCurveSet( RimSummaryCaseCollection* ensemble,
const RifEclipseSummaryAddress& addr )
{
auto curveSet = new RimEnsembleCurveSet();
curveSet->setSummaryCaseCollection( ensemble );
curveSet->setSummaryAddress( addr );
return curveSet;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimSummaryCurve* RicSummaryPlotBuilder::createCurve( RimSummaryCase* summaryCase, const RifEclipseSummaryAddress& addr )
{
auto curve = new RimSummaryCurve();
curve->setSummaryCaseY( summaryCase );
curve->setSummaryAddressY( addr );
return curve;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<RimPlot*> RicSummaryPlotBuilder::duplicatePlots( const std::vector<RimPlot*>& sourcePlots )
{
std::vector<RimPlot*> plots;
for ( auto plot : sourcePlots )
{
auto copy = dynamic_cast<RimPlot*>( plot->copyByXmlSerialization( caf::PdmDefaultObjectFactory::instance() ) );
{
// TODO: Workaround for fixing the PdmPointer in RimEclipseResultDefinition
// caf::PdmPointer<RimEclipseCase> m_eclipseCase;
// This pdmpointer must be changed to a ptrField
auto saturationPressurePlotOriginal = dynamic_cast<RimSaturationPressurePlot*>( plot );
auto saturationPressurePlotCopy = dynamic_cast<RimSaturationPressurePlot*>( copy );
if ( saturationPressurePlotCopy && saturationPressurePlotOriginal )
{
RimSaturationPressurePlot::fixPointersAfterCopy( saturationPressurePlotOriginal,
saturationPressurePlotCopy );
}
}
plots.push_back( copy );
}
return plots;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimMultiPlot* RicSummaryPlotBuilder::createAndAppendMultiPlot( const std::vector<RimPlot*>& plots )
{
RimProject* project = RimProject::current();
RimMultiPlotCollection* plotCollection = project->mainPlotCollection()->multiPlotCollection();
RimMultiPlot* plotWindow = new RimMultiPlot;
plotWindow->setMultiPlotTitle( QString( "Multi Plot %1" ).arg( plotCollection->multiPlots().size() + 1 ) );
plotWindow->setAsPlotMdiWindow();
plotCollection->addMultiPlot( plotWindow );
for ( auto plot : plots )
{
plotWindow->addPlot( plot );
plot->resolveReferencesRecursively();
plot->revokeMdiWindowStatus();
plot->setShowWindow( true );
plot->loadDataAndUpdate();
}
project->updateAllRequiredEditors();
plotWindow->loadDataAndUpdate();
RiuPlotMainWindowTools::setExpanded( plotCollection, true );
RiuPlotMainWindowTools::selectAsCurrentItem( plotWindow, true );
return plotWindow;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimSummaryPlot* RicSummaryPlotBuilder::createPlot( const std::set<RifEclipseSummaryAddress>& addresses,
const std::vector<RimSummaryCase*>& summaryCases,
const std::vector<RimSummaryCaseCollection*>& ensembles )
{
RimSummaryPlot* plot = new RimSummaryPlot();
plot->enableAutoPlotTitle( true );
appendCurvesToPlot( plot, addresses, summaryCases, ensembles );
plot->applyDefaultCurveAppearances();
return plot;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RicSummaryPlotBuilder::appendCurvesToPlot( RimSummaryPlot* summaryPlot,
const std::set<RifEclipseSummaryAddress>& addresses,
const std::vector<RimSummaryCase*>& summaryCases,
const std::vector<RimSummaryCaseCollection*>& ensembles )
{
for ( const auto& addr : addresses )
{
for ( const auto ensemble : ensembles )
{
auto curveSet = createCurveSet( ensemble, addr );
summaryPlot->ensembleCurveSetCollection()->addCurveSet( curveSet );
}
for ( const auto summaryCase : summaryCases )
{
auto curve = createCurve( summaryCase, addr );
summaryPlot->addCurveNoUpdate( curve );
}
}
}

View File

@ -0,0 +1,81 @@
////////////////////////////////////////////////////////////////////////////////
//
// 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.
//
/////////////////////////////////////////////////////////////////////////////////
#pragma once
class RimPlot;
class RimMultiPlot;
class RifEclipseSummaryAddress;
class RimSummaryCase;
class RimSummaryCaseCollection;
class RimSummaryPlot;
class RimEnsembleCurveSet;
class RimSummaryCurve;
namespace caf
{
class PdmObject;
}
#include <set>
#include <vector>
//==================================================================================================
///
//==================================================================================================
class RicSummaryPlotBuilder
{
public:
RicSummaryPlotBuilder();
void setDataSources( const std::vector<RimSummaryCase*>& summaryCases,
const std::vector<RimSummaryCaseCollection*>& ensembles );
void setAddresses( const std::set<RifEclipseSummaryAddress>& addresses );
void setIndividualPlotPerAddress( bool enable );
void setIndividualPlotPerDataSource( bool enable );
std::vector<RimSummaryPlot*> createPlots() const;
// Static helper functions
static std::set<RifEclipseSummaryAddress> addressesForSource( caf::PdmObject* summarySource );
static RimEnsembleCurveSet* createCurveSet( RimSummaryCaseCollection* ensemble, const RifEclipseSummaryAddress& addr );
static RimSummaryCurve* createCurve( RimSummaryCase* summaryCase, const RifEclipseSummaryAddress& addr );
static std::vector<RimPlot*> duplicatePlots( const std::vector<RimPlot*>& plots );
static RimMultiPlot* createAndAppendMultiPlot( const std::vector<RimPlot*>& plots );
static RimSummaryPlot* createPlot( const std::set<RifEclipseSummaryAddress>& addresses,
const std::vector<RimSummaryCase*>& summaryCases,
const std::vector<RimSummaryCaseCollection*>& ensembles );
static void appendCurvesToPlot( RimSummaryPlot* summaryPlot,
const std::set<RifEclipseSummaryAddress>& addresses,
const std::vector<RimSummaryCase*>& summaryCases,
const std::vector<RimSummaryCaseCollection*>& ensembles );
private:
std::set<RifEclipseSummaryAddress> m_addresses;
std::vector<RimSummaryCase*> m_summaryCases;
std::vector<RimSummaryCaseCollection*> m_ensembles;
bool m_individualPlotPerAddress;
bool m_individualPlotPerDataSource;
};

View File

@ -35,6 +35,7 @@
#include "RimSummaryPlot.h"
#include "RimSummaryPlotCollection.h"
#include "PlotBuilderCommands/RicSummaryPlotBuilder.h"
#include "SummaryPlotCommands/RicSummaryPlotFeatureImpl.h"
#include "RiuPlotMainWindowTools.h"
@ -45,6 +46,7 @@
#include "cafPdmUiLabelEditor.h"
#include "cafPdmUiLineEditor.h"
#include "cafPdmUiPushButtonEditor.h"
#include "cafPdmUiTreeSelectionEditor.h"
#include "cafSelectionManager.h"
#include <QKeyEvent>
@ -64,8 +66,9 @@ RimSummaryPlotManager::RimSummaryPlotManager()
CAF_PDM_InitFieldNoDefault( &m_addressCandidates, "AddressCandidates", "Vectors" );
m_addressCandidates.uiCapability()->setUiLabelPosition( caf::PdmUiItemInfo::TOP );
CAF_PDM_InitFieldNoDefault( &m_dataSourceCandidates, "DataSourceCandidates", "Data Sources" );
m_dataSourceCandidates.uiCapability()->setUiLabelPosition( caf::PdmUiItemInfo::TOP );
CAF_PDM_InitFieldNoDefault( &m_selectedDataSources, "SelectedDataSources", "Data Sources" );
m_selectedDataSources.uiCapability()->setUiLabelPosition( caf::PdmUiItemInfo::TOP );
m_selectedDataSources.uiCapability()->setUiEditorTypeName( caf::PdmUiTreeSelectionEditor::uiEditorTypeName() );
CAF_PDM_InitField( &m_includeDiffCurves,
"IncludeDiffCurves",
@ -96,6 +99,10 @@ RimSummaryPlotManager::RimSummaryPlotManager()
CAF_PDM_InitFieldNoDefault( &m_labelB, "LabelB", "" );
m_labelB.uiCapability()->setUiEditorTypeName( caf::PdmUiLabelEditor::uiEditorTypeName() );
m_labelB.xmlCapability()->disableIO();
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" );
}
//--------------------------------------------------------------------------------------------------
@ -124,7 +131,6 @@ void RimSummaryPlotManager::fieldChangedByUi( const caf::PdmFieldHandle* changed
if ( changedField == &m_summaryPlot || changedField == &m_filterText || changedField == &m_includeDiffCurves )
{
updateCurveCandidates();
updateDataSourceCandidates();
}
else if ( changedField == &m_pushButtonReplace )
{
@ -158,8 +164,7 @@ QList<caf::PdmOptionItemInfo>
auto coll = RiaSummaryTools::summaryPlotCollection();
coll->summaryPlotItemInfos( &options );
}
if ( fieldNeedingOptions == &m_filterText )
else if ( fieldNeedingOptions == &m_filterText )
{
RiaStringListSerializer stringListSerializer( curveFilterRecentlyUsedRegistryKey() );
@ -168,6 +173,35 @@ QList<caf::PdmOptionItemInfo>
options.push_back( caf::PdmOptionItemInfo( s, s ) );
}
}
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() );
}
return options;
}
@ -189,22 +223,6 @@ void RimSummaryPlotManager::updateCurveCandidates()
m_addressCandidates = curveCandidates;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimSummaryPlotManager::updateDataSourceCandidates()
{
std::vector<QString> dataSourceDisplayNames;
std::vector<std::pair<QString, PdmObject*>> dataSourceCandidates = findDataSourceCandidates();
for ( const auto& candidate : dataSourceCandidates )
{
dataSourceDisplayNames.push_back( candidate.first );
}
m_dataSourceCandidates = dataSourceDisplayNames;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@ -314,7 +332,7 @@ void RimSummaryPlotManager::defineEditorAttribute( const caf::PdmFieldHandle* fi
}
if ( field == &m_pushButtonNewPlot )
{
attr->m_buttonText = "Create New Plot \n(Alt + Enter)";
attr->m_buttonText = "Create New Plot \n(Enter)";
}
if ( field == &m_pushButtonAppend )
{
@ -329,6 +347,7 @@ void RimSummaryPlotManager::defineEditorAttribute( const caf::PdmFieldHandle* fi
if ( attr )
{
attr->enableEditableContent = true;
attr->enableAutoComplete = false;
attr->adjustWidthToContents = true;
attr->notifyWhenTextIsEdited = true;
}
@ -346,7 +365,11 @@ void RimSummaryPlotManager::defineUiOrdering( QString uiConfigName, caf::PdmUiOr
uiOrdering.add( &m_filterText );
uiOrdering.add( &m_addressCandidates );
uiOrdering.add( &m_dataSourceCandidates, false );
uiOrdering.add( &m_selectedDataSources, false );
uiOrdering.add( &m_individualPlotPerVector );
uiOrdering.add( &m_individualPlotPerDataSource );
uiOrdering.add( &m_createMultiPlot );
uiOrdering.add( &m_pushButtonAppend );
uiOrdering.add( &m_pushButtonReplace, { false } );
@ -359,9 +382,9 @@ void RimSummaryPlotManager::defineUiOrdering( QString uiConfigName, caf::PdmUiOr
//--------------------------------------------------------------------------------------------------
void RimSummaryPlotManager::appendCurves()
{
RimSummaryPlot* destinationPlot = m_summaryPlot;
if ( !m_summaryPlot ) return;
appendCurvesToPlot( destinationPlot );
appendCurvesToPlot( m_summaryPlot );
}
//--------------------------------------------------------------------------------------------------
@ -369,6 +392,8 @@ void RimSummaryPlotManager::appendCurves()
//--------------------------------------------------------------------------------------------------
void RimSummaryPlotManager::replaceCurves()
{
if ( !m_summaryPlot ) return;
RimSummaryPlot* destinationPlot = m_summaryPlot;
destinationPlot->deleteAllSummaryCurves();
destinationPlot->ensembleCurveSetCollection()->deleteAllCurveSets();
@ -383,9 +408,43 @@ void RimSummaryPlotManager::replaceCurves()
//--------------------------------------------------------------------------------------------------
void RimSummaryPlotManager::createNewPlot()
{
RimSummaryPlot* destinationPlot = RiaSummaryTools::summaryPlotCollection()->createSummaryPlotWithAutoTitle();
std::vector<RimSummaryCase*> summaryCases;
std::vector<RimSummaryCaseCollection*> ensembles;
findFilteredSummaryCasesAndEnsembles( summaryCases, ensembles );
appendCurvesToPlot( destinationPlot );
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();
}
//--------------------------------------------------------------------------------------------------
@ -405,13 +464,8 @@ bool RimSummaryPlotManager::eventFilter( QObject* obj, QEvent* event )
appendCurves();
else if ( mods & Qt::ControlModifier )
replaceCurves();
else if ( mods & Qt::AltModifier )
createNewPlot();
else if ( mods == Qt::NoModifier )
{
updateCurveCandidates();
updateDataSourceCandidates();
}
createNewPlot();
}
}
@ -442,22 +496,23 @@ void RimSummaryPlotManager::updateUiFromSelection()
RimSummaryPlot* summaryPlot = nullptr;
if ( destinationObject ) destinationObject->firstAncestorOrThisOfType( summaryPlot );
if ( m_summaryPlot != summaryPlot )
if ( summaryPlot && ( m_summaryPlot() != summaryPlot ) )
{
m_summaryPlot = summaryPlot;
if ( summaryPlot )
{
updateCurveCandidates();
updateDataSourceCandidates();
}
else
{
std::vector<QString> tmp;
m_addressCandidates = tmp;
m_dataSourceCandidates = tmp;
}
updateConnectedEditors();
updateCurveCandidates();
}
if ( !summaryPlot )
{
m_summaryPlot = nullptr;
std::vector<QString> tmp;
m_addressCandidates = tmp;
m_selectedDataSources = tmp;
}
updateConnectedEditors();
}
//--------------------------------------------------------------------------------------------------
@ -472,11 +527,11 @@ std::set<RifEclipseSummaryAddress> RimSummaryPlotManager::filteredAddresses()
std::set<RifEclipseSummaryAddress> nativeAddresses;
if ( !summaryCases.empty() )
{
nativeAddresses = addressesForSource( summaryCases.front() );
nativeAddresses = RicSummaryPlotBuilder::addressesForSource( summaryCases.front() );
}
else if ( !ensembles.empty() )
{
nativeAddresses = addressesForSource( ensembles.front() );
nativeAddresses = RicSummaryPlotBuilder::addressesForSource( ensembles.front() );
}
if ( nativeAddresses.empty() ) return {};
@ -486,82 +541,6 @@ std::set<RifEclipseSummaryAddress> RimSummaryPlotManager::filteredAddresses()
return computeFilteredAddresses( allCurveAddressFilters, nativeAddresses );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::set<RifEclipseSummaryAddress> RimSummaryPlotManager::addressesForSource( caf::PdmObject* summarySource )
{
auto ensemble = dynamic_cast<RimSummaryCaseCollection*>( summarySource );
if ( ensemble )
{
return ensemble->ensembleSummaryAddresses();
}
auto sumCase = dynamic_cast<RimSummaryCase*>( summarySource );
if ( sumCase )
{
auto reader = sumCase ? sumCase->summaryReader() : nullptr;
if ( reader )
{
return reader->allResultAddresses();
}
}
return {};
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimEnsembleCurveSet* RimSummaryPlotManager::createCurveSet( RimSummaryCaseCollection* ensemble,
const RifEclipseSummaryAddress& addr )
{
auto curveSet = new RimEnsembleCurveSet();
curveSet->setSummaryCaseCollection( ensemble );
curveSet->setSummaryAddress( addr );
return curveSet;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimSummaryCurve* RimSummaryPlotManager::createCurve( RimSummaryCase* summaryCase, const RifEclipseSummaryAddress& addr )
{
auto curve = new RimSummaryCurve();
curve->setSummaryCaseY( summaryCase );
curve->setSummaryAddressY( addr );
return curve;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimSummaryPlotManager::appendCurvesToPlot( RimSummaryPlot* summaryPlot,
const std::set<RifEclipseSummaryAddress>& addresses,
const std::vector<RimSummaryCase*>& summaryCases,
const std::vector<RimSummaryCaseCollection*>& ensembles )
{
for ( const auto& addr : addresses )
{
for ( const auto ensemble : ensembles )
{
auto curveSet = createCurveSet( ensemble, addr );
summaryPlot->ensembleCurveSetCollection()->addCurveSet( curveSet );
}
for ( const auto summaryCase : summaryCases )
{
auto curve = createCurve( summaryCase, addr );
summaryPlot->addCurveNoUpdate( curve );
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@ -574,17 +553,12 @@ void RimSummaryPlotManager::appendCurvesToPlot( RimSummaryPlot* destinationPlot
findFilteredSummaryCasesAndEnsembles( summaryCases, ensembles );
std::set<RifEclipseSummaryAddress> filteredAddressesFromSource = filteredAddresses();
appendCurvesToPlot( destinationPlot, filteredAddressesFromSource, summaryCases, ensembles );
RicSummaryPlotBuilder::appendCurvesToPlot( destinationPlot, filteredAddressesFromSource, summaryCases, ensembles );
destinationPlot->applyDefaultCurveAppearances();
destinationPlot->loadDataAndUpdate();
RiaSummaryTools::summaryPlotCollection()->updateConnectedEditors();
updateFilterTextHistory();
m_filterText.uiCapability()->updateConnectedEditors();
setFocusToFilterText();
updateProjectTreeAndRefresUi();
}
//--------------------------------------------------------------------------------------------------
@ -598,6 +572,19 @@ void RimSummaryPlotManager::updateFilterTextHistory()
stringListSerializer.addString( m_filterText, maxItemCount );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimSummaryPlotManager::updateProjectTreeAndRefresUi()
{
RiaSummaryTools::summaryPlotCollection()->updateConnectedEditors();
updateFilterTextHistory();
m_filterText.uiCapability()->updateConnectedEditors();
setFocusToFilterText();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@ -655,15 +642,21 @@ void RimSummaryPlotManager::findFilteredSummaryCasesAndEnsembles( std::vector<Ri
std::vector<RimSummaryCaseCollection*>& ensembles ) const
{
auto filteredDataSources = findDataSourceCandidates();
for ( const auto& ds : filteredDataSources )
for ( const auto& [dataSourceName, dataSource] : filteredDataSources )
{
auto summaryCase = dynamic_cast<RimSummaryCase*>( ds.second );
auto selectedDataSources = m_selectedDataSources();
if ( std::find( selectedDataSources.begin(), selectedDataSources.end(), dataSourceName ) ==
std::end( selectedDataSources ) )
continue;
auto summaryCase = dynamic_cast<RimSummaryCase*>( dataSource );
if ( summaryCase )
{
summaryCases.push_back( summaryCase );
}
auto ensemble = dynamic_cast<RimSummaryCaseCollection*>( ds.second );
auto ensemble = dynamic_cast<RimSummaryCaseCollection*>( dataSource );
if ( ensemble )
{
ensembles.push_back( ensemble );

View File

@ -29,6 +29,8 @@ class RimSummaryCase;
class RimSummaryCaseCollection;
class RimEnsembleCurveSet;
class RimSummaryCurve;
class RimMultiPlot;
class RimPlot;
class RimSummaryPlotManager : public QObject, public caf::PdmObject, public caf::SelectionChangedReceiver
@ -62,7 +64,6 @@ private:
bool eventFilter( QObject* obj, QEvent* event ) override;
void updateCurveCandidates();
void updateDataSourceCandidates();
std::vector<std::pair<QString, caf::PdmObject*>> findDataSourceCandidates() const;
@ -71,28 +72,18 @@ private:
std::pair<std::vector<RimSummaryCase*>, std::vector<RimSummaryCaseCollection*>> allDataSourcesInProject() const;
void updateUiFromSelection();
std::set<RifEclipseSummaryAddress> filteredAddresses();
void appendCurvesToPlot( RimSummaryPlot* destinationPlot );
void updateFilterTextHistory();
// Static helper functions
static std::set<RifEclipseSummaryAddress> addressesForSource( caf::PdmObject* summarySource );
static RimEnsembleCurveSet* createCurveSet( RimSummaryCaseCollection* ensemble, const RifEclipseSummaryAddress& addr );
static RimSummaryCurve* createCurve( RimSummaryCase* summaryCase, const RifEclipseSummaryAddress& addr );
static void appendCurvesToPlot( RimSummaryPlot* summaryPlot,
const std::set<RifEclipseSummaryAddress>& addresses,
const std::vector<RimSummaryCase*>& summaryCases,
const std::vector<RimSummaryCaseCollection*>& ensembles );
static void setFocusToEditorWidget( caf::PdmUiFieldHandle* uiFieldHandle );
void updateUiFromSelection();
void appendCurvesToPlot( RimSummaryPlot* destinationPlot );
void updateFilterTextHistory();
void updateProjectTreeAndRefresUi();
void splitIntoAddressAndDataSourceFilters( QStringList& addressFilters, QStringList& dataSourceFilters ) const;
void findFilteredSummaryCasesAndEnsembles( std::vector<RimSummaryCase*>& summaryCases,
std::vector<RimSummaryCaseCollection*>& ensembles ) const;
static void setFocusToEditorWidget( caf::PdmUiFieldHandle* uiFieldHandle );
static QString curveFilterRecentlyUsedRegistryKey();
private:
@ -100,7 +91,7 @@ private:
caf::PdmField<QString> m_filterText;
caf::PdmField<std::vector<QString>> m_addressCandidates;
caf::PdmField<std::vector<QString>> m_dataSourceCandidates;
caf::PdmField<std::vector<QString>> m_selectedDataSources;
caf::PdmField<bool> m_includeDiffCurves;
@ -108,6 +99,12 @@ private:
caf::PdmField<bool> m_pushButtonNewPlot;
caf::PdmField<bool> m_pushButtonAppend;
caf::PdmField<bool> m_individualPlotPerVector;
caf::PdmField<bool> m_individualPlotPerDataSource;
caf::PdmField<bool> m_createMultiPlot;
caf::PdmField<QString> m_labelA;
caf::PdmField<QString> m_labelB;
std::set<QString> m_previousDataSourceSelection;
};

View File

@ -131,6 +131,12 @@ void RiuPlotMainWindow::initializeGuiNewProjectLoaded()
m_pdmUiPropertyView->currentObject()->uiCapability()->updateConnectedEditors();
}
auto sumPlotManager = dynamic_cast<RimSummaryPlotManager*>( m_summaryPlotManager.get() );
if ( sumPlotManager )
{
sumPlotManager->updateConnectedEditors();
}
{
auto* obj = RiaSummaryTools::summaryCaseMainCollection();
if ( obj )

View File

@ -281,6 +281,11 @@ void PdmUiComboBoxEditor::configureAndUpdateUi( const QString& uiConfigName )
{
m_comboBox->setEditable( true );
if ( !m_attributes.enableAutoComplete )
{
m_comboBox->setCompleter( nullptr );
}
m_comboBox->lineEdit()->setPlaceholderText( m_attributes.placeholderText );
}

View File

@ -61,6 +61,7 @@ public:
minimumContentsLength = 8;
maximumMenuContentsLength = 40;
enableEditableContent = false;
enableAutoComplete = true;
minimumWidth = -1;
iconSize = QSize( 14, 14 );
notifyWhenTextIsEdited = false;
@ -73,6 +74,7 @@ public:
// Set to <= 0 to ignore and use AdjustToContentsOnFirstShow instead
int maximumMenuContentsLength;
bool enableEditableContent;
bool enableAutoComplete;
int minimumWidth;
QString placeholderText;
QString nextButtonText;