mirror of
https://github.com/OPM/ResInsight.git
synced 2025-01-21 05:53:25 -06:00
#8966 Improve performance when changing multiple field values
This commit is contained in:
parent
3545d16fbb
commit
b17e3813df
@ -121,6 +121,25 @@ void RimSummaryCurveCollection::loadDataAndUpdate( bool updateParentPlot )
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimSummaryCurveCollection::onChildrenUpdated( caf::PdmChildArrayFieldHandle* childArray,
|
||||
std::vector<caf::PdmObjectHandle*>& updatedObjects )
|
||||
{
|
||||
if ( childArray == &m_curves )
|
||||
{
|
||||
for ( RimSummaryCurve* curve : m_curves )
|
||||
{
|
||||
curve->updateCurveAppearance();
|
||||
}
|
||||
|
||||
RimSummaryPlot* parentPlot;
|
||||
firstAncestorOrThisOfTypeAsserted( parentPlot );
|
||||
parentPlot->plotWidget()->scheduleReplot();
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
@ -99,6 +99,9 @@ private:
|
||||
void onChildDeleted( caf::PdmChildArrayFieldHandle* childArray,
|
||||
std::vector<caf::PdmObjectHandle*>& referringObjects ) override;
|
||||
|
||||
void onChildrenUpdated( caf::PdmChildArrayFieldHandle* childArray,
|
||||
std::vector<caf::PdmObjectHandle*>& updatedObjects ) override;
|
||||
|
||||
private:
|
||||
friend class RimSummaryCrossPlot;
|
||||
friend class RimSummaryPlot;
|
||||
|
@ -41,15 +41,15 @@
|
||||
|
||||
namespace caf
|
||||
{
|
||||
CAF_PDM_SOURCE_INIT( CmdFieldChangeExecData, "CmdFieldChangeExecData" );
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QString CmdFieldChangeExec::name()
|
||||
{
|
||||
if ( !m_commandData->m_pathToFields.empty() )
|
||||
{
|
||||
PdmFieldHandle* field =
|
||||
PdmReferenceHelper::fieldFromReference( m_commandData->m_rootObject, m_commandData->m_pathToField );
|
||||
PdmReferenceHelper::fieldFromReference( m_commandData->m_rootObject, m_commandData->m_pathToFields.front() );
|
||||
if ( field )
|
||||
{
|
||||
QString fieldText;
|
||||
@ -70,10 +70,9 @@ QString CmdFieldChangeExec::name()
|
||||
}
|
||||
return fieldText;
|
||||
}
|
||||
else
|
||||
{
|
||||
return m_commandData->classKeyword();
|
||||
}
|
||||
|
||||
return "Field Changed";
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -81,23 +80,26 @@ QString CmdFieldChangeExec::name()
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void CmdFieldChangeExec::redo()
|
||||
{
|
||||
PdmFieldHandle* field =
|
||||
PdmReferenceHelper::fieldFromReference( m_commandData->m_rootObject, m_commandData->m_pathToField );
|
||||
if ( !field )
|
||||
m_commandData->m_undoFieldValueSerialized.resize( m_commandData->m_pathToFields.size() );
|
||||
|
||||
for ( size_t i = 0; i < m_commandData->m_pathToFields.size(); i++ )
|
||||
{
|
||||
CAF_ASSERT( false );
|
||||
return;
|
||||
}
|
||||
auto fieldTextPath = m_commandData->m_pathToFields[i];
|
||||
|
||||
PdmFieldHandle* field = PdmReferenceHelper::fieldFromReference( m_commandData->m_rootObject, fieldTextPath );
|
||||
if ( !field ) continue;
|
||||
|
||||
PdmUiFieldHandle* uiFieldHandle = field->uiCapability();
|
||||
PdmXmlFieldHandle* xmlFieldHandle = field->xmlCapability();
|
||||
if ( uiFieldHandle && xmlFieldHandle )
|
||||
{
|
||||
if ( m_commandData->m_redoFieldValueSerialized.isEmpty() )
|
||||
bool isLastField = ( i == m_commandData->m_pathToFields.size() - 1 );
|
||||
|
||||
if ( m_commandData->m_undoFieldValueSerialized[i].isEmpty() )
|
||||
{
|
||||
// We end up here only when the user actually has done something in the actual living Gui editor.
|
||||
{
|
||||
QXmlStreamWriter xmlStream( &m_commandData->m_undoFieldValueSerialized );
|
||||
QXmlStreamWriter xmlStream( &m_commandData->m_undoFieldValueSerialized[i] );
|
||||
writeFieldDataToValidXmlDocument( xmlStream, xmlFieldHandle );
|
||||
}
|
||||
|
||||
@ -105,8 +107,9 @@ void CmdFieldChangeExec::redo()
|
||||
// The ui value might be an index into the option entry cache, so we need to set the value
|
||||
// and be aware of the option entries, and then serialize the actual field value we ended up with.
|
||||
|
||||
uiFieldHandle->setValueFromUiEditor( m_commandData->m_newUiValue );
|
||||
uiFieldHandle->setValueFromUiEditor( m_commandData->m_newUiValue, isLastField );
|
||||
|
||||
if ( m_commandData->m_redoFieldValueSerialized.isEmpty() )
|
||||
{
|
||||
QXmlStreamWriter xmlStream( &m_commandData->m_redoFieldValueSerialized );
|
||||
writeFieldDataToValidXmlDocument( xmlStream, xmlFieldHandle );
|
||||
@ -123,11 +126,21 @@ void CmdFieldChangeExec::redo()
|
||||
QVariant newFieldData = uiFieldHandle->toUiBasedQVariant();
|
||||
|
||||
// New data is present in field, notify data changed
|
||||
if ( isLastField )
|
||||
{
|
||||
uiFieldHandle->notifyFieldChanged( oldFieldData, newFieldData );
|
||||
if ( m_notificationCenter )
|
||||
m_notificationCenter->notifyObserversOfDataChange( field->ownerObject() );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( m_notificationCenter ) m_notificationCenter->notifyObserversOfDataChange( field->ownerObject() );
|
||||
if ( m_commandData->m_ownerOfChildArrayField && m_commandData->m_childArrayFieldHandle )
|
||||
{
|
||||
std::vector<caf::PdmObjectHandle*> objs;
|
||||
m_commandData->m_ownerOfChildArrayField->onChildrenUpdated( m_commandData->m_childArrayFieldHandle, objs );
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -135,19 +148,20 @@ void CmdFieldChangeExec::redo()
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void CmdFieldChangeExec::undo()
|
||||
{
|
||||
PdmFieldHandle* field =
|
||||
PdmReferenceHelper::fieldFromReference( m_commandData->m_rootObject, m_commandData->m_pathToField );
|
||||
if ( !field )
|
||||
for ( size_t i = 0; i < m_commandData->m_pathToFields.size(); i++ )
|
||||
{
|
||||
CAF_ASSERT( false );
|
||||
return;
|
||||
}
|
||||
auto fieldTextPath = m_commandData->m_pathToFields[i];
|
||||
|
||||
PdmFieldHandle* field = PdmReferenceHelper::fieldFromReference( m_commandData->m_rootObject, fieldTextPath );
|
||||
if ( !field ) continue;
|
||||
|
||||
PdmUiFieldHandle* uiFieldHandle = field->uiCapability();
|
||||
PdmXmlFieldHandle* xmlFieldHandle = field->xmlCapability();
|
||||
if ( uiFieldHandle && xmlFieldHandle )
|
||||
{
|
||||
QXmlStreamReader xmlStream( m_commandData->m_undoFieldValueSerialized );
|
||||
bool isLastField = ( i == m_commandData->m_pathToFields.size() - 1 );
|
||||
|
||||
QXmlStreamReader xmlStream( m_commandData->m_undoFieldValueSerialized[i] );
|
||||
QVariant oldFieldData = uiFieldHandle->toUiBasedQVariant();
|
||||
|
||||
readFieldValueFromValidXmlDocument( xmlStream, xmlFieldHandle );
|
||||
@ -155,10 +169,19 @@ void CmdFieldChangeExec::undo()
|
||||
QVariant newFieldData = uiFieldHandle->toUiBasedQVariant();
|
||||
|
||||
// New data is present in field, notify data changed
|
||||
if ( isLastField )
|
||||
{
|
||||
uiFieldHandle->notifyFieldChanged( oldFieldData, newFieldData );
|
||||
if ( m_notificationCenter ) m_notificationCenter->notifyObserversOfDataChange( field->ownerObject() );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( m_notificationCenter ) m_notificationCenter->notifyObserversOfDataChange( field->ownerObject() );
|
||||
if ( m_commandData->m_ownerOfChildArrayField && m_commandData->m_childArrayFieldHandle )
|
||||
{
|
||||
std::vector<caf::PdmObjectHandle*> objs;
|
||||
m_commandData->m_ownerOfChildArrayField->onChildrenUpdated( m_commandData->m_childArrayFieldHandle, objs );
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
@ -40,34 +40,31 @@
|
||||
#include "cafPdmField.h"
|
||||
#include "cafPdmObject.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace caf
|
||||
{
|
||||
class PdmChildArrayFieldHandle;
|
||||
|
||||
//==================================================================================================
|
||||
///
|
||||
//==================================================================================================
|
||||
class CmdFieldChangeExecData : public PdmObject
|
||||
class CmdFieldChangeExecData
|
||||
{
|
||||
CAF_PDM_HEADER_INIT;
|
||||
|
||||
public:
|
||||
CmdFieldChangeExecData()
|
||||
: m_rootObject( nullptr )
|
||||
, m_childArrayFieldHandle( nullptr )
|
||||
, m_ownerOfChildArrayField( nullptr )
|
||||
{
|
||||
CAF_PDM_InitObject( "CmdFieldChangeExecData uiName",
|
||||
"",
|
||||
"CmdFieldChangeExecData tooltip",
|
||||
"CmdFieldChangeExecData whatsthis" );
|
||||
|
||||
CAF_PDM_InitField( &m_pathToField, "PathToField", QString(), "PathToField", "", "PathToField tooltip", "PathToField whatsthis" );
|
||||
}
|
||||
|
||||
caf::PdmPointer<PdmObjectHandle> m_rootObject;
|
||||
PdmChildArrayFieldHandle* m_childArrayFieldHandle;
|
||||
PdmObjectHandle* m_ownerOfChildArrayField;
|
||||
|
||||
PdmField<QString> m_pathToField;
|
||||
QVariant m_newUiValue; // QVariant coming from the UI
|
||||
std::vector<QString> m_pathToFields;
|
||||
std::vector<QString> m_undoFieldValueSerialized;
|
||||
|
||||
QString m_undoFieldValueSerialized;
|
||||
QVariant m_newUiValue;
|
||||
QString m_redoFieldValueSerialized;
|
||||
};
|
||||
|
||||
|
@ -40,10 +40,10 @@
|
||||
#include "cafCmdExecuteCommand.h"
|
||||
#include "cafCmdFeatureManager.h"
|
||||
#include "cafCmdFieldChangeExec.h"
|
||||
|
||||
#include "cafPdmChildArrayField.h"
|
||||
#include "cafPdmFieldHandle.h"
|
||||
#include "cafPdmObjectHandle.h"
|
||||
#include "cafPdmUiObjectHandle.h"
|
||||
|
||||
#include "cafSelectionManager.h"
|
||||
|
||||
#include <QMenu>
|
||||
@ -71,45 +71,64 @@ void CmdUiCommandSystemImpl::fieldChangedCommand( const std::vector<PdmFieldHand
|
||||
|
||||
std::vector<CmdExecuteCommand*> commands;
|
||||
|
||||
for ( size_t i = 0; i < fieldsToUpdate.size(); i++ )
|
||||
PdmChildArrayFieldHandle* childArrayFieldHandle = nullptr;
|
||||
PdmObjectHandle* ownerOfChildArrayField = nullptr;
|
||||
PdmObjectHandle* rootObjHandle = nullptr;
|
||||
|
||||
auto firstField = fieldsToUpdate.front();
|
||||
if ( firstField )
|
||||
{
|
||||
// Find the first childArrayField by traversing parent field and objects. Usually, the childArrayField is
|
||||
// the parent, but in some cases when we change fields in a sub-object of the object we need to traverse
|
||||
// more levels
|
||||
|
||||
ownerOfChildArrayField = firstField->ownerObject();
|
||||
while ( ownerOfChildArrayField )
|
||||
{
|
||||
if ( ownerOfChildArrayField->parentField() )
|
||||
{
|
||||
childArrayFieldHandle =
|
||||
dynamic_cast<caf::PdmChildArrayFieldHandle*>( ownerOfChildArrayField->parentField() );
|
||||
ownerOfChildArrayField = ownerOfChildArrayField->parentField()->ownerObject();
|
||||
|
||||
if ( childArrayFieldHandle && ownerOfChildArrayField ) break;
|
||||
}
|
||||
else
|
||||
{
|
||||
ownerOfChildArrayField = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
rootObjHandle = PdmReferenceHelper::findRoot( firstField );
|
||||
}
|
||||
|
||||
std::vector<QString> pathsToFields;
|
||||
for ( caf::PdmFieldHandle* field : fieldsToUpdate )
|
||||
{
|
||||
PdmFieldHandle* field = fieldsToUpdate[i];
|
||||
PdmUiFieldHandle* uiFieldHandle = field->uiCapability();
|
||||
if ( uiFieldHandle )
|
||||
{
|
||||
QVariant fieldCurrentUiValue = uiFieldHandle->uiValue();
|
||||
|
||||
if ( fieldCurrentUiValue != newUiValue )
|
||||
{
|
||||
PdmObjectHandle* rootObjHandle = PdmReferenceHelper::findRoot( field );
|
||||
|
||||
QString reference = PdmReferenceHelper::referenceFromRootToField( rootObjHandle, field );
|
||||
if ( reference.isEmpty() )
|
||||
QString pathToField = PdmReferenceHelper::referenceFromRootToField( rootObjHandle, field );
|
||||
if ( !pathToField.isEmpty() )
|
||||
{
|
||||
CAF_ASSERT( false );
|
||||
return;
|
||||
pathsToFields.push_back( pathToField );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CmdFieldChangeExec* fieldChangeExec =
|
||||
new CmdFieldChangeExec( SelectionManager::instance()->notificationCenter() );
|
||||
auto* fieldChangeExec = new CmdFieldChangeExec( SelectionManager::instance()->notificationCenter() );
|
||||
|
||||
fieldChangeExec->commandData()->m_newUiValue = newUiValue;
|
||||
fieldChangeExec->commandData()->m_pathToField = reference;
|
||||
fieldChangeExec->commandData()->m_pathToFields = pathsToFields;
|
||||
fieldChangeExec->commandData()->m_rootObject = rootObjHandle;
|
||||
fieldChangeExec->commandData()->m_ownerOfChildArrayField = ownerOfChildArrayField;
|
||||
fieldChangeExec->commandData()->m_childArrayFieldHandle = childArrayFieldHandle;
|
||||
|
||||
commands.push_back( fieldChangeExec );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( commands.size() == 1 )
|
||||
{
|
||||
CmdExecCommandManager::instance()->processExecuteCommand( commands[0] );
|
||||
}
|
||||
else
|
||||
{
|
||||
CmdExecCommandManager::instance()->processExecuteCommandsAsMacro( commands );
|
||||
}
|
||||
CmdExecCommandManager::instance()->processExecuteCommand( fieldChangeExec );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
@ -107,6 +107,8 @@ public:
|
||||
std::vector<caf::PdmObjectHandle*>& referringObjects );
|
||||
|
||||
virtual void onChildAdded( caf::PdmFieldHandle* containerForNewObject ){};
|
||||
virtual void onChildrenUpdated( PdmChildArrayFieldHandle* childArray,
|
||||
std::vector<caf::PdmObjectHandle*>& updatedObjects ){};
|
||||
|
||||
virtual void
|
||||
handleDroppedMimeData( const QMimeData* data, Qt::DropAction action, caf::PdmFieldHandle* destinationField ){};
|
||||
|
@ -17,7 +17,7 @@ public:
|
||||
// Gui generalized interface
|
||||
public:
|
||||
QVariant uiValue() const override;
|
||||
void setValueFromUiEditor( const QVariant& uiValue ) override;
|
||||
void setValueFromUiEditor( const QVariant& uiValue, bool notifyFieldChanged ) override;
|
||||
QList<PdmOptionItemInfo> valueOptions( bool* useOptionsOnly ) const override;
|
||||
|
||||
QVariant toUiBasedQVariant() const override;
|
||||
@ -48,7 +48,7 @@ public:
|
||||
// Gui generalized interface
|
||||
public:
|
||||
QVariant uiValue() const override { return QVariant(); }
|
||||
void setValueFromUiEditor( const QVariant& uiValue ) override {}
|
||||
void setValueFromUiEditor( const QVariant& uiValue, bool notifyFieldChanged ) override {}
|
||||
QList<PdmOptionItemInfo> valueOptions( bool* useOptionsOnly ) const override { return QList<PdmOptionItemInfo>(); }
|
||||
|
||||
QVariant toUiBasedQVariant() const override { return QVariant(); }
|
||||
@ -71,7 +71,7 @@ public:
|
||||
// Gui generalized interface
|
||||
public:
|
||||
QVariant uiValue() const override { return QVariant(); }
|
||||
void setValueFromUiEditor( const QVariant& uiValue ) override {}
|
||||
void setValueFromUiEditor( const QVariant& uiValue, bool notifyFieldChanged ) override {}
|
||||
QList<PdmOptionItemInfo> valueOptions( bool* useOptionsOnly ) const override { return QList<PdmOptionItemInfo>(); }
|
||||
|
||||
QVariant toUiBasedQVariant() const override { return QVariant(); }
|
||||
|
@ -14,7 +14,7 @@ namespace caf
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
||||
template <typename FieldType>
|
||||
void PdmFieldUiCap<FieldType>::setValueFromUiEditor( const QVariant& uiValue )
|
||||
void PdmFieldUiCap<FieldType>::setValueFromUiEditor( const QVariant& uiValue, bool notifyFieldChanged )
|
||||
{
|
||||
QVariant oldUiBasedQVariant = toUiBasedQVariant();
|
||||
|
||||
@ -100,7 +100,7 @@ void PdmFieldUiCap<FieldType>::setValueFromUiEditor( const QVariant& uiValue )
|
||||
|
||||
QVariant newUiBasedQVariant = toUiBasedQVariant();
|
||||
|
||||
this->notifyFieldChanged( oldUiBasedQVariant, newUiBasedQVariant );
|
||||
if ( notifyFieldChanged ) this->notifyFieldChanged( oldUiBasedQVariant, newUiBasedQVariant );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
@ -114,7 +114,7 @@ void PdmUiCommandSystemProxy::setUiValueToField( PdmUiFieldHandle* uiFieldHandle
|
||||
|
||||
for ( auto fieldHandle : fieldsToUpdate )
|
||||
{
|
||||
fieldHandle->uiCapability()->setValueFromUiEditor( newUiValue );
|
||||
fieldHandle->uiCapability()->setValueFromUiEditor( newUiValue, true );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -124,7 +124,7 @@ void PdmUiFieldHandle::setAutoAddingOptionFromValue( bool isAddingValue )
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void PdmUiFieldHandle::setValueFromUiEditor( const QVariant& uiValue )
|
||||
void PdmUiFieldHandle::setValueFromUiEditor( const QVariant& uiValue, bool notifyFieldChanged )
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -30,7 +30,7 @@ public:
|
||||
private:
|
||||
friend class PdmUiCommandSystemProxy;
|
||||
friend class CmdFieldChangeExec;
|
||||
virtual void setValueFromUiEditor( const QVariant& uiValue );
|
||||
virtual void setValueFromUiEditor( const QVariant& uiValue, bool notifyFieldChanged );
|
||||
// This is needed to handle custom types in QVariants since operator == between QVariant does not work when they use
|
||||
// custom types.
|
||||
virtual bool isQVariantDataEqual( const QVariant& oldUiBasedQVariant, const QVariant& newUiBasedQVariant ) const;
|
||||
|
Loading…
Reference in New Issue
Block a user