Histogram drag/drop and paste improvements (#12851)

* Add drag'n'drop support for ensemble summary vectors and ensembles into histogram plots

* Make sure histogram plot is shown and all update signals are connected when loading a project.

* Support ensemble parameter drag'n'drop from data sources into histogram plots. 

* Show ensemble parameters in data sources tree.

* Add copy/paste of histogram curves

* Re-use all existing parameters in a plot when dragging a new ensemble into it
This commit is contained in:
JJ authored and GitHub committed 2025-08-29 15:12:32 +02:00
1 parent 35d1279b1d
commit 393917e6f3
23 files changed
+746 -15

No files matched your search

@@ -1,9 +1,13 @@
set(SOURCE_GROUP_HEADER_FILES
${CMAKE_CURRENT_LIST_DIR}/RimSummaryFileSetEnsemble.h
${CMAKE_CURRENT_LIST_DIR}/RimSummaryEnsembleParameter.h
${CMAKE_CURRENT_LIST_DIR}/RimSummaryEnsembleParameterCollection.h
)
set(SOURCE_GROUP_SOURCE_FILES
${CMAKE_CURRENT_LIST_DIR}/RimSummaryFileSetEnsemble.cpp
${CMAKE_CURRENT_LIST_DIR}/RimSummaryEnsembleParameter.cpp
${CMAKE_CURRENT_LIST_DIR}/RimSummaryEnsembleParameterCollection.cpp
)
list(APPEND CODE_HEADER_FILES ${SOURCE_GROUP_HEADER_FILES})
@@ -0,0 +1,76 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2025 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 "RimSummaryEnsembleParameter.h"
CAF_PDM_SOURCE_INIT( RimSummaryEnsembleParameter, "RimSummaryEnsembleParameter" );
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimSummaryEnsembleParameter::RimSummaryEnsembleParameter()
{
CAF_PDM_InitObject( "Summary Ensemble Parameter", ":/Parameter.svg" );
CAF_PDM_InitFieldNoDefault( &m_name, "Name", "Name" );
m_name.uiCapability()->setUiReadOnly( true );
CAF_PDM_InitField( &m_ensembleId, "EnsembleId", -1, "EnsembleId" );
m_ensembleId.uiCapability()->setUiHidden( true );
setDeletable( false );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimSummaryEnsembleParameter::~RimSummaryEnsembleParameter()
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RimSummaryEnsembleParameter::name() const
{
return m_name;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimSummaryEnsembleParameter::setName( const QString& name )
{
setUiName( name );
m_name = name;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimSummaryEnsembleParameter::setEnsembleId( int ensembleId )
{
m_ensembleId = ensembleId;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
int RimSummaryEnsembleParameter::ensembleId() const
{
return m_ensembleId;
}
@@ -0,0 +1,47 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2025 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 "cafPdmField.h"
#include "cafPdmObject.h"
#include <QString>
//==================================================================================================
//
//
//==================================================================================================
class RimSummaryEnsembleParameter : public caf::PdmObject
{
CAF_PDM_HEADER_INIT;
public:
RimSummaryEnsembleParameter();
~RimSummaryEnsembleParameter();
QString name() const;
void setName( const QString& name );
void setEnsembleId( int ensembleId );
int ensembleId() const;
private:
caf::PdmField<QString> m_name;
caf::PdmField<int> m_ensembleId;
};
@@ -0,0 +1,123 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2025 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 "RimSummaryEnsembleParameterCollection.h"
#include "RimSummaryEnsembleParameter.h"
#include "cafPdmUiTreeOrdering.h"
CAF_PDM_SOURCE_INIT( RimSummaryEnsembleParameterCollection, "RimSummaryEnsembleParameterCollection" );
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimSummaryEnsembleParameterCollection::RimSummaryEnsembleParameterCollection()
{
CAF_PDM_InitObject( "Ensemble Parameters", ":/Parameter.svg", "", "" );
CAF_PDM_InitFieldNoDefault( &m_parameters, "Parameters", "Parameters" );
CAF_PDM_InitField( &m_ensembleId, "EnsembleId", -1, "EnsembleId" );
m_ensembleId.uiCapability()->setUiHidden( true );
nameField()->uiCapability()->setUiHidden( true );
nameField()->uiCapability()->setUiReadOnly( true );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimSummaryEnsembleParameterCollection::~RimSummaryEnsembleParameterCollection()
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RimSummaryEnsembleParameterCollection::hasParameter( const QString name ) const
{
for ( const auto& p : m_parameters )
{
if ( p->name() == name ) return true;
}
return false;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimSummaryEnsembleParameterCollection::addParameter( QString name, bool checkDuplicates )
{
bool okToAdd = checkDuplicates ? !hasParameter( name ) : true;
if ( okToAdd )
{
auto p = new RimSummaryEnsembleParameter();
p->setName( name );
p->setEnsembleId( ensembleId() );
m_parameters.push_back( p );
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimSummaryEnsembleParameterCollection::deleteChildren()
{
m_parameters.deleteChildren();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RimSummaryEnsembleParameterCollection::isEmpty() const
{
return m_parameters.empty();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimSummaryEnsembleParameterCollection::updateUiTreeOrdering( caf::PdmUiTreeOrdering& uiTreeOrdering ) const
{
if ( isEmpty() ) return;
auto subnode = uiTreeOrdering.add( "Parameters", ":/Parameter.svg" );
for ( auto& p : m_parameters() )
{
subnode->add( p );
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimSummaryEnsembleParameterCollection::setEnsembleId( int ensembleId )
{
m_ensembleId = ensembleId;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
int RimSummaryEnsembleParameterCollection::ensembleId() const
{
return m_ensembleId;
}
@@ -0,0 +1,54 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2025 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 "RimNamedObject.h"
#include "cafPdmChildArrayField.h"
#include <QString>
#include <string>
#include <vector>
class RimSummaryEnsembleParameter;
class RimSummaryEnsembleParameterCollection : public RimNamedObject
{
CAF_PDM_HEADER_INIT;
public:
RimSummaryEnsembleParameterCollection();
~RimSummaryEnsembleParameterCollection() override;
void addParameter( QString name, bool checkDuplicates = true );
bool hasParameter( const QString name ) const;
void setEnsembleId( int ensembleId );
int ensembleId() const;
void deleteChildren();
bool isEmpty() const;
void updateUiTreeOrdering( caf::PdmUiTreeOrdering& uiTreeOrdering ) const;
private:
caf::PdmChildArrayField<RimSummaryEnsembleParameter*> m_parameters;
caf::PdmField<int> m_ensembleId;
};
@@ -25,6 +25,7 @@
#include "RiaStatisticsTools.h"
#include "RiaStdStringTools.h"
#include "RiaTextStringTools.h"
#include "Summary/Ensemble/RimSummaryEnsembleParameterCollection.h"
#include "Summary/RiaSummaryAddressAnalyzer.h"
#include "Summary/RiaSummaryTools.h"
@@ -91,6 +92,12 @@ RimSummaryEnsemble::RimSummaryEnsemble()
m_dataVectorFolders->uiCapability()->setUiTreeHidden( true );
m_dataVectorFolders.xmlCapability()->disableIO();
CAF_PDM_InitFieldNoDefault( &m_ensembleParameters, "EnsembleParameters", "Ensemble Parameters" );
m_ensembleParameters = new RimSummaryEnsembleParameterCollection();
m_ensembleParameters.uiCapability()->setUiHidden( true );
m_ensembleParameters->uiCapability()->setUiTreeHidden( true );
m_ensembleParameters.xmlCapability()->disableIO();
CAF_PDM_InitFieldNoDefault( &m_ensembleDescription, "Description", "Description" );
m_ensembleDescription.registerGetMethod( this, &RimSummaryEnsemble::ensembleDescription );
m_ensembleDescription.uiCapability()->setUiLabelPosition( caf::PdmUiItemInfo::TOP );
@@ -1000,6 +1007,8 @@ void RimSummaryEnsemble::defineUiTreeOrdering( caf::PdmUiTreeOrdering& uiTreeOrd
}
}
m_ensembleParameters->updateUiTreeOrdering( uiTreeOrdering );
uiTreeOrdering.skipRemainingChildren( true );
}
}
@@ -1183,6 +1192,14 @@ void RimSummaryEnsemble::buildChildNodes()
{
m_dataVectorFolders->updateFolderStructure( ensembleSummaryAddresses(), -1, m_ensembleId );
}
if ( m_ensembleParameters->isEmpty() )
{
m_ensembleParameters->setEnsembleId( ensembleId() );
for ( auto& ensPar : variationSortedEnsembleParameters() )
{
m_ensembleParameters->addParameter( ensPar.name, false /*check duplicate*/ );
}
}
}
//--------------------------------------------------------------------------------------------------
@@ -40,6 +40,7 @@
class RimSummaryCase;
class RimSummaryAddressCollection;
class RiaSummaryAddressAnalyzer;
class RimSummaryEnsembleParameterCollection;
//==================================================================================================
///
@@ -167,6 +168,8 @@ private:
caf::PdmField<bool> m_isEnsemble;
caf::PdmChildField<RimSummaryAddressCollection*> m_dataVectorFolders;
caf::PdmChildField<RimSummaryEnsembleParameterCollection*> m_ensembleParameters;
caf::PdmField<int> m_ensembleId;
mutable std::vector<RigEnsembleParameter> m_cachedSortedEnsembleParameters;