From 4ff5aaf381e716e1cc7dcb85b89025f266fcb35b Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Fri, 18 Oct 2024 14:25:04 +0200 Subject: [PATCH] Add quick access data model objects --- .../Application/CMakeLists_files.cmake | 2 + .../Application/RiaQuickAccessScheduler.cpp | 58 ++++ .../Application/RiaQuickAccessScheduler.h | 33 ++ ApplicationLibCode/CMakeLists.txt | 1 + .../QuickAccess/CMakeLists_files.cmake | 18 ++ .../QuickAccess/RimFieldQuickAccess.cpp | 178 +++++++++++ .../QuickAccess/RimFieldQuickAccess.h | 63 ++++ .../QuickAccess/RimFieldQuickAccessGroup.cpp | 156 ++++++++++ .../QuickAccess/RimFieldQuickAccessGroup.h | 62 ++++ .../RimFieldQuickAccessInterface.h | 36 +++ .../QuickAccess/RimFieldReference.cpp | 196 ++++++++++++ .../QuickAccess/RimFieldReference.h | 62 ++++ .../QuickAccess/RimQuickAccessCollection.cpp | 285 ++++++++++++++++++ .../QuickAccess/RimQuickAccessCollection.h | 60 ++++ .../ProjectDataModel/RimProject.cpp | 13 +- .../ProjectDataModel/RimProject.h | 6 +- 16 files changed, 1227 insertions(+), 2 deletions(-) create mode 100644 ApplicationLibCode/Application/RiaQuickAccessScheduler.cpp create mode 100644 ApplicationLibCode/Application/RiaQuickAccessScheduler.h create mode 100644 ApplicationLibCode/ProjectDataModel/QuickAccess/CMakeLists_files.cmake create mode 100644 ApplicationLibCode/ProjectDataModel/QuickAccess/RimFieldQuickAccess.cpp create mode 100644 ApplicationLibCode/ProjectDataModel/QuickAccess/RimFieldQuickAccess.h create mode 100644 ApplicationLibCode/ProjectDataModel/QuickAccess/RimFieldQuickAccessGroup.cpp create mode 100644 ApplicationLibCode/ProjectDataModel/QuickAccess/RimFieldQuickAccessGroup.h create mode 100644 ApplicationLibCode/ProjectDataModel/QuickAccess/RimFieldQuickAccessInterface.h create mode 100644 ApplicationLibCode/ProjectDataModel/QuickAccess/RimFieldReference.cpp create mode 100644 ApplicationLibCode/ProjectDataModel/QuickAccess/RimFieldReference.h create mode 100644 ApplicationLibCode/ProjectDataModel/QuickAccess/RimQuickAccessCollection.cpp create mode 100644 ApplicationLibCode/ProjectDataModel/QuickAccess/RimQuickAccessCollection.h diff --git a/ApplicationLibCode/Application/CMakeLists_files.cmake b/ApplicationLibCode/Application/CMakeLists_files.cmake index ea2ea6c50d..3fdac472c4 100644 --- a/ApplicationLibCode/Application/CMakeLists_files.cmake +++ b/ApplicationLibCode/Application/CMakeLists_files.cmake @@ -40,6 +40,7 @@ set(SOURCE_GROUP_HEADER_FILES ${CMAKE_CURRENT_LIST_DIR}/RiaCloudDefines.h ${CMAKE_CURRENT_LIST_DIR}/RiaWellFlowDefines.h ${CMAKE_CURRENT_LIST_DIR}/RiaSummaryCurveAddress.h + ${CMAKE_CURRENT_LIST_DIR}/RiaQuickAccessScheduler.h ) set(SOURCE_GROUP_SOURCE_FILES @@ -84,6 +85,7 @@ set(SOURCE_GROUP_SOURCE_FILES ${CMAKE_CURRENT_LIST_DIR}/RiaCloudDefines.cpp ${CMAKE_CURRENT_LIST_DIR}/RiaWellFlowDefines.cpp ${CMAKE_CURRENT_LIST_DIR}/RiaSummaryCurveAddress.cpp + ${CMAKE_CURRENT_LIST_DIR}/RiaQuickAccessScheduler.cpp ) list(APPEND CODE_HEADER_FILES ${SOURCE_GROUP_HEADER_FILES}) diff --git a/ApplicationLibCode/Application/RiaQuickAccessScheduler.cpp b/ApplicationLibCode/Application/RiaQuickAccessScheduler.cpp new file mode 100644 index 0000000000..4ead48ed00 --- /dev/null +++ b/ApplicationLibCode/Application/RiaQuickAccessScheduler.cpp @@ -0,0 +1,58 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2018- 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 +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RiaQuickAccessScheduler.h" + +#include "QuickAccess/RimQuickAccessCollection.h" + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RiaQuickAccessScheduler::RiaQuickAccessScheduler() +{ +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RiaQuickAccessScheduler* RiaQuickAccessScheduler::instance() +{ + static RiaQuickAccessScheduler theInstance; + + return &theInstance; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiaQuickAccessScheduler::scheduleDisplayModelUpdateAndRedraw() +{ + startTimer( 0 ); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiaQuickAccessScheduler::performScheduledUpdates() +{ + auto quickColl = RimQuickAccessCollection::instance(); + if ( quickColl ) + { + quickColl->updateAllRequiredEditors(); + } +} diff --git a/ApplicationLibCode/Application/RiaQuickAccessScheduler.h b/ApplicationLibCode/Application/RiaQuickAccessScheduler.h new file mode 100644 index 0000000000..22cccd4eb4 --- /dev/null +++ b/ApplicationLibCode/Application/RiaQuickAccessScheduler.h @@ -0,0 +1,33 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2018- 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 +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "RiaScheduler.h" + +class RiaQuickAccessScheduler : public RiaScheduler +{ +public: + RiaQuickAccessScheduler(); + + static RiaQuickAccessScheduler* instance(); + + void scheduleDisplayModelUpdateAndRedraw(); + + void performScheduledUpdates() override; +}; diff --git a/ApplicationLibCode/CMakeLists.txt b/ApplicationLibCode/CMakeLists.txt index d243e3b398..3172fe9010 100644 --- a/ApplicationLibCode/CMakeLists.txt +++ b/ApplicationLibCode/CMakeLists.txt @@ -128,6 +128,7 @@ list( ProjectDataModelCommands/CMakeLists_files.cmake ProjectDataModelCommands/CommandRouter/CMakeLists_files.cmake ProjectDataModel/VerticalFlowPerformance/CMakeLists_files.cmake + ProjectDataModel/QuickAccess/CMakeLists_files.cmake GeoMech/GeoMechVisualization/CMakeLists_files.cmake ModelVisualization/CMakeLists_files.cmake ModelVisualization/Faults/CMakeLists_files.cmake diff --git a/ApplicationLibCode/ProjectDataModel/QuickAccess/CMakeLists_files.cmake b/ApplicationLibCode/ProjectDataModel/QuickAccess/CMakeLists_files.cmake new file mode 100644 index 0000000000..2599c59cda --- /dev/null +++ b/ApplicationLibCode/ProjectDataModel/QuickAccess/CMakeLists_files.cmake @@ -0,0 +1,18 @@ +set(SOURCE_GROUP_HEADER_FILES + ${CMAKE_CURRENT_LIST_DIR}/RimFieldQuickAccess.h + ${CMAKE_CURRENT_LIST_DIR}/RimFieldQuickAccessGroup.h + ${CMAKE_CURRENT_LIST_DIR}/RimFieldQuickAccessInterface.h + ${CMAKE_CURRENT_LIST_DIR}/RimFieldReference.h + ${CMAKE_CURRENT_LIST_DIR}/RimQuickAccessCollection.h +) + +set(SOURCE_GROUP_SOURCE_FILES + ${CMAKE_CURRENT_LIST_DIR}/RimFieldQuickAccess.cpp + ${CMAKE_CURRENT_LIST_DIR}/RimFieldQuickAccessGroup.cpp + ${CMAKE_CURRENT_LIST_DIR}/RimFieldReference.cpp + ${CMAKE_CURRENT_LIST_DIR}/RimQuickAccessCollection.cpp +) + +list(APPEND CODE_HEADER_FILES ${SOURCE_GROUP_HEADER_FILES}) + +list(APPEND CODE_SOURCE_FILES ${SOURCE_GROUP_SOURCE_FILES}) diff --git a/ApplicationLibCode/ProjectDataModel/QuickAccess/RimFieldQuickAccess.cpp b/ApplicationLibCode/ProjectDataModel/QuickAccess/RimFieldQuickAccess.cpp new file mode 100644 index 0000000000..0a3f10a46c --- /dev/null +++ b/ApplicationLibCode/ProjectDataModel/QuickAccess/RimFieldQuickAccess.cpp @@ -0,0 +1,178 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2024- 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 +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RimFieldQuickAccess.h" + +#include "RiaQuickAccessScheduler.h" + +#include "RimFieldReference.h" + +#include "Riu3DMainWindowTools.h" + +#include "cafPdmUiToolButtonCallbackEditor.h" + +CAF_PDM_SOURCE_INIT( RimFieldQuickAccess, "RimFieldQuickAccess" ); + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimFieldQuickAccess::RimFieldQuickAccess() +{ + CAF_PDM_InitObject( "Quick Access" ); + + CAF_PDM_InitFieldNoDefault( &m_fieldReference, "FieldReference", "FieldReference" ); + m_fieldReference = new RimFieldReference(); + + CAF_PDM_InitFieldNoDefault( &m_selectObjectButton, "SelectObject", "...", ":/Bullet.png", "Select Object in Property Editor" ); + m_selectObjectButton.uiCapability()->setUiEditorTypeName( caf::PdmUiToolButtonCallbackEditor::uiEditorTypeName() ); + m_selectObjectButton.xmlCapability()->disableIO(); + + CAF_PDM_InitFieldNoDefault( &m_removeItemButton, "RemoveItem", "...", ":/pin.svg", "Remove Quick Access" ); + m_removeItemButton.uiCapability()->setUiEditorTypeName( caf::PdmUiToolButtonCallbackEditor::uiEditorTypeName() ); + m_removeItemButton.xmlCapability()->disableIO(); + + m_markedForRemoval = false; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimFieldQuickAccess::setField( caf::PdmFieldHandle* field ) +{ + if ( !m_fieldReference() ) return; + + m_fieldReference->setField( field ); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimFieldQuickAccess::defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ) +{ + if ( m_fieldReference() && m_fieldReference()->field() ) + { + uiOrdering.add( m_fieldReference()->field() ); + uiOrdering.add( &m_selectObjectButton, { .newRow = false } ); + uiOrdering.add( &m_removeItemButton, { .newRow = false } ); + } + + uiOrdering.skipRemainingFields(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimFieldQuickAccess::onSelectObjectButton() +{ + if ( m_fieldReference() ) + { + if ( auto pdmObj = dynamic_cast( m_fieldReference->object() ) ) + { + Riu3DMainWindowTools::selectAsCurrentItem( pdmObj ); + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimFieldQuickAccess::onRemoveObjectButton() +{ + m_markedForRemoval = true; + + RiaQuickAccessScheduler::instance()->scheduleDisplayModelUpdateAndRedraw(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimFieldQuickAccess::defineEditorAttribute( const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute* attribute ) +{ + if ( field == &m_selectObjectButton ) + { + if ( auto attr = dynamic_cast( attribute ) ) + { + attr->setCallback( std::bind( &RimFieldQuickAccess::onSelectObjectButton, this ) ); + } + } + else if ( field == &m_removeItemButton ) + { + if ( auto attr = dynamic_cast( attribute ) ) + { + attr->setCallback( std::bind( &RimFieldQuickAccess::onRemoveObjectButton, this ) ); + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +caf::PdmFieldHandle* RimFieldQuickAccess::field() const +{ + if ( !m_fieldReference() ) return nullptr; + + return m_fieldReference->field(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimFieldQuickAccess::markedForRemoval() const +{ + return m_markedForRemoval; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimFieldQuickAccess::onSel() +{ + if ( m_fieldReference() ) + { + if ( auto pdmObj = dynamic_cast( m_fieldReference->object() ) ) + { + Riu3DMainWindowTools::selectAsCurrentItem( pdmObj ); + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimFieldQuickAccess::fieldChangedByUi( const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue ) +{ + if ( changedField == &m_selectObjectButton ) + { + m_selectObjectButton = false; + + if ( m_fieldReference() ) + { + if ( auto pdmObj = dynamic_cast( m_fieldReference->object() ) ) + { + Riu3DMainWindowTools::selectAsCurrentItem( pdmObj ); + } + } + } + + if ( changedField == &m_removeItemButton ) + { + m_removeItemButton = false; + + m_markedForRemoval = true; + } +} diff --git a/ApplicationLibCode/ProjectDataModel/QuickAccess/RimFieldQuickAccess.h b/ApplicationLibCode/ProjectDataModel/QuickAccess/RimFieldQuickAccess.h new file mode 100644 index 0000000000..133e93ff1b --- /dev/null +++ b/ApplicationLibCode/ProjectDataModel/QuickAccess/RimFieldQuickAccess.h @@ -0,0 +1,63 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2024- 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 +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "RimNamedObject.h" + +#include "cafPdmChildField.h" +#include "cafPdmField.h" +#include "cafPdmObject.h" +#include "cafPdmProxyValueField.h" + +class RimFieldReference; + +//================================================================================================== +/// +/// +//================================================================================================== +class RimFieldQuickAccess : public caf::PdmObject +{ + CAF_PDM_HEADER_INIT; + +public: + RimFieldQuickAccess(); + + void setField( caf::PdmFieldHandle* field ); + caf::PdmFieldHandle* field() const; + + bool markedForRemoval() const; + + void onSel(); + +private: + void fieldChangedByUi( const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue ) override; + void defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ) override; + void defineEditorAttribute( const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute* attribute ) override; + + void onSelectObjectButton(); + void onRemoveObjectButton(); + +private: + caf::PdmChildField m_fieldReference; + + caf::PdmProxyValueField m_selectObjectButton; + caf::PdmProxyValueField m_removeItemButton; + + bool m_markedForRemoval; +}; diff --git a/ApplicationLibCode/ProjectDataModel/QuickAccess/RimFieldQuickAccessGroup.cpp b/ApplicationLibCode/ProjectDataModel/QuickAccess/RimFieldQuickAccessGroup.cpp new file mode 100644 index 0000000000..507f79c778 --- /dev/null +++ b/ApplicationLibCode/ProjectDataModel/QuickAccess/RimFieldQuickAccessGroup.cpp @@ -0,0 +1,156 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2024- 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 +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RimFieldQuickAccessGroup.h" + +#include "RiaLogging.h" + +CAF_PDM_SOURCE_INIT( RimFieldQuickAccessGroup, "RimFieldQuickAccessGroup" ); + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimFieldQuickAccessGroup::RimFieldQuickAccessGroup() +{ + CAF_PDM_InitObject( "Quick Access Group" ); + + CAF_PDM_InitFieldNoDefault( &m_fieldQuickAccess, "FieldReferences", "Field References" ); + CAF_PDM_InitFieldNoDefault( &m_ownerView, "OwnerView", "Owner View" ); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimGridView* RimFieldQuickAccessGroup::ownerView() const +{ + return m_ownerView; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimFieldQuickAccessGroup::setOwnerView( RimGridView* viewObject ) +{ + m_ownerView = viewObject; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimFieldQuickAccessGroup::addFields( const std::vector& fields ) +{ + if ( !m_ownerView ) return; + + for ( auto field : fields ) + { + if ( findField( field ) ) continue; + + addField( field ); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimFieldQuickAccessGroup::addField( caf::PdmFieldHandle* field ) +{ + if ( !field ) return; + if ( !m_ownerView ) return; + + if ( !isOwnerViewMatching( field ) ) return; + + auto fieldReference = new RimFieldQuickAccess(); + fieldReference->setField( field ); + + addFieldQuickAccess( fieldReference ); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector RimFieldQuickAccessGroup::fieldQuickAccesses() const +{ + return m_fieldQuickAccess.childrenByType(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +caf::PdmObjectHandle* RimFieldQuickAccessGroup::groupOwner() const +{ + for ( auto f : m_fieldQuickAccess ) + { + if ( f && f->field() ) + { + return f->field()->ownerObject(); + } + } + + return nullptr; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimFieldQuickAccessGroup::removeFieldQuickAccess( RimFieldQuickAccess* fieldQuickAccess ) +{ + m_fieldQuickAccess.removeChild( fieldQuickAccess ); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimFieldQuickAccessGroup::addFieldQuickAccess( RimFieldQuickAccess* fieldQuickAccess ) +{ + if ( !fieldQuickAccess ) return; + + m_fieldQuickAccess.push_back( fieldQuickAccess ); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimFieldQuickAccessGroup::findField( const caf::PdmFieldHandle* field ) const +{ + for ( auto fieldRef : m_fieldQuickAccess ) + { + if ( field == fieldRef->field() ) + { + return true; + } + } + + return false; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimFieldQuickAccessGroup::isOwnerViewMatching( caf::PdmFieldHandle* field ) +{ + if ( !field || !field->ownerObject() ) return false; + auto parentView = field->ownerObject()->firstAncestorOrThisOfType(); + + if ( parentView != m_ownerView ) + { + RiaLogging::debug( "Field does not belong to the owner view" ); + return false; + } + + return true; +} diff --git a/ApplicationLibCode/ProjectDataModel/QuickAccess/RimFieldQuickAccessGroup.h b/ApplicationLibCode/ProjectDataModel/QuickAccess/RimFieldQuickAccessGroup.h new file mode 100644 index 0000000000..ee9bcc4e64 --- /dev/null +++ b/ApplicationLibCode/ProjectDataModel/QuickAccess/RimFieldQuickAccessGroup.h @@ -0,0 +1,62 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2024- 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 +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "RimNamedObject.h" + +#include "cafPdmChildArrayField.h" +#include "cafPdmField.h" +#include "cafPdmObject.h" +#include "cafPdmPtrField.h" + +class RimGridView; +class RimFieldQuickAccess; + +//================================================================================================== +/// +/// +//================================================================================================== +class RimFieldQuickAccessGroup : public RimNamedObject +{ + CAF_PDM_HEADER_INIT; + +public: + RimFieldQuickAccessGroup(); + + RimGridView* ownerView() const; + void setOwnerView( RimGridView* owner ); + + void addFields( const std::vector& fields ); + void addField( caf::PdmFieldHandle* field ); + + std::vector fieldQuickAccesses() const; + caf::PdmObjectHandle* groupOwner() const; + + void removeFieldQuickAccess( RimFieldQuickAccess* fieldQuickAccess ); + +private: + void addFieldQuickAccess( RimFieldQuickAccess* fieldQuickAccess ); + bool findField( const caf::PdmFieldHandle* field ) const; + + bool isOwnerViewMatching( caf::PdmFieldHandle* field ); + +private: + caf::PdmChildArrayField m_fieldQuickAccess; + caf::PdmPtrField m_ownerView; +}; diff --git a/ApplicationLibCode/ProjectDataModel/QuickAccess/RimFieldQuickAccessInterface.h b/ApplicationLibCode/ProjectDataModel/QuickAccess/RimFieldQuickAccessInterface.h new file mode 100644 index 0000000000..86e5dc1834 --- /dev/null +++ b/ApplicationLibCode/ProjectDataModel/QuickAccess/RimFieldQuickAccessInterface.h @@ -0,0 +1,36 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2024- 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 +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include +#include + +#include + +namespace caf +{ +class PdmFieldHandle; +class PdmUiOrdering; +}; // namespace caf + +class RimFieldQuickAccessInterface +{ +public: + virtual std::map> quickAccessFields() = 0; +}; diff --git a/ApplicationLibCode/ProjectDataModel/QuickAccess/RimFieldReference.cpp b/ApplicationLibCode/ProjectDataModel/QuickAccess/RimFieldReference.cpp new file mode 100644 index 0000000000..4493216d55 --- /dev/null +++ b/ApplicationLibCode/ProjectDataModel/QuickAccess/RimFieldReference.cpp @@ -0,0 +1,196 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2024- 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 +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RimFieldReference.h" + +CAF_PDM_SOURCE_INIT( RimFieldReference, "RimFieldReference" ); + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimFieldReference::RimFieldReference() +{ + CAF_PDM_InitFieldNoDefault( &m_object, "Object", "Object" ); + CAF_PDM_InitFieldNoDefault( &m_fieldKeyword, "FieldKeyword", "Field Keyword" ); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimFieldReference::setObject( caf::PdmObject* object ) +{ + m_object = object; + + auto keywordAndNames = RimFieldReference::fieldKeywordAndNames( object ); + if ( !keywordAndNames.empty() ) + { + m_fieldKeyword = keywordAndNames[0].first; + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimFieldReference::setField( caf::PdmFieldHandle* field ) +{ + if ( !field ) return; + + auto ownerObject = dynamic_cast( field->ownerObject() ); + if ( !ownerObject ) return; + + setField( ownerObject, field->keyword() ); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector> RimFieldReference::fieldKeywordAndNames( caf::PdmObject* object ) +{ + std::vector> names; + + if ( object ) + { + // Get the fields for the current uiOrdering. Calling object->fields() will not work as it will return all fields. + caf::PdmUiOrdering uiOrdering; + object->uiOrdering( "", uiOrdering ); + + std::vector fields; + for ( auto item : uiOrdering.uiItems() ) + { + findFieldsRecursively( item, fields ); + } + + for ( auto item : fields ) + { + if ( auto field = dynamic_cast( item ) ) + { + auto text = field->keyword(); + + if ( auto uiCapability = field->uiCapability() ) + { + text = uiCapability->uiName(); + } + + names.push_back( { field->keyword(), text } ); + } + } + } + + return names; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimFieldReference::findFieldsRecursively( caf::PdmUiItem* object, std::vector& fields ) +{ + if ( auto uiFieldHandle = dynamic_cast( object ) ) + { + if ( uiFieldHandle->fieldHandle() ) fields.push_back( uiFieldHandle->fieldHandle() ); + } + + if ( auto group = dynamic_cast( object ) ) + { + for ( auto child : group->uiItems() ) + { + findFieldsRecursively( child, fields ); + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimFieldReference::defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ) +{ + uiOrdering.add( &m_object ); + uiOrdering.add( &m_fieldKeyword ); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QList RimFieldReference::calculateValueOptions( const caf::PdmFieldHandle* fieldNeedingOptions ) +{ + QList options; + + if ( fieldNeedingOptions == &m_fieldKeyword ) + { + auto keywordAndNames = RimFieldReference::fieldKeywordAndNames( m_object ); + for ( const auto& [keyword, name] : keywordAndNames ) + { + options.push_back( caf::PdmOptionItemInfo( name, keyword ) ); + } + } + else if ( fieldNeedingOptions == &m_object ) + { + if ( m_objectsForSelection.empty() ) + { + if ( m_object ) + { + QString text = m_object()->uiName(); + options.push_back( caf::PdmOptionItemInfo( text, m_object ) ); + } + } + else + { + for ( auto obj : m_objectsForSelection ) + { + QString text = obj->uiName(); + options.push_back( caf::PdmOptionItemInfo( text, obj ) ); + } + } + } + + return options; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +caf::PdmFieldHandle* RimFieldReference::field() const +{ + if ( !m_object() ) return nullptr; + + return m_object->findField( m_fieldKeyword() ); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +caf::PdmObject* RimFieldReference::object() const +{ + return m_object; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimFieldReference::setObjectsForSelection( const std::vector& objectsForSelection ) +{ + m_objectsForSelection = objectsForSelection; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimFieldReference::setField( caf::PdmObject* object, const QString& fieldName ) +{ + m_object = object; + m_fieldKeyword = fieldName; +} diff --git a/ApplicationLibCode/ProjectDataModel/QuickAccess/RimFieldReference.h b/ApplicationLibCode/ProjectDataModel/QuickAccess/RimFieldReference.h new file mode 100644 index 0000000000..1cd5946781 --- /dev/null +++ b/ApplicationLibCode/ProjectDataModel/QuickAccess/RimFieldReference.h @@ -0,0 +1,62 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2024- 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 +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "cafPdmField.h" +#include "cafPdmObject.h" +#include "cafPdmPtrField.h" + +//================================================================================================== +/// +/// This class is used to store a reference to a field in a PdmObject, and is similar to caf::PdmPtrField that is +/// used for a non-owning reference to an object. Consider creating a caf::PdmPtrField instead of this class. +/// +/// Investigate if PdmFieldCapability::attributes can be used to store the field name for a caf::PdmPtrField +/// +//================================================================================================== +class RimFieldReference : public caf::PdmObject +{ + CAF_PDM_HEADER_INIT; + +public: + RimFieldReference(); + + void setObject( caf::PdmObject* object ); + + void setField( caf::PdmFieldHandle* field ); + caf::PdmFieldHandle* field() const; + + caf::PdmObject* object() const; + void setObjectsForSelection( const std::vector& objectsForSelection ); + +private: + void defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ) override; + QList calculateValueOptions( const caf::PdmFieldHandle* fieldNeedingOptions ) override; + + void setField( caf::PdmObject* object, const QString& fieldName ); + + static std::vector> fieldKeywordAndNames( caf::PdmObject* object ); + static void findFieldsRecursively( caf::PdmUiItem* object, std::vector& fields ); + +private: + caf::PdmPtrField m_object; + caf::PdmField m_fieldKeyword; + + std::vector m_objectsForSelection; +}; diff --git a/ApplicationLibCode/ProjectDataModel/QuickAccess/RimQuickAccessCollection.cpp b/ApplicationLibCode/ProjectDataModel/QuickAccess/RimQuickAccessCollection.cpp new file mode 100644 index 0000000000..bbd0aa4606 --- /dev/null +++ b/ApplicationLibCode/ProjectDataModel/QuickAccess/RimQuickAccessCollection.cpp @@ -0,0 +1,285 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2024- 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 +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RimQuickAccessCollection.h" + +#include "RiaApplication.h" + +#include "RimFieldQuickAccess.h" +#include "RimFieldQuickAccessInterface.h" +#include "RimFieldReference.h" +#include "RimGridView.h" +#include "RimProject.h" + +#include "cafAssert.h" + +CAF_PDM_SOURCE_INIT( RimQuickAccessCollection, "RimQuickAccessCollection" ); + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimQuickAccessCollection::RimQuickAccessCollection() +{ + CAF_PDM_InitObject( "Field Reference Collection" ); + + CAF_PDM_InitFieldNoDefault( &m_fieldQuickAccesGroups, "FieldReferencesGroup", "Field References Group" ); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimQuickAccessCollection* RimQuickAccessCollection::instance() +{ + auto proj = RimProject::current(); + CAF_ASSERT( proj && "RimProject is nullptr when trying to access RimQuickAccessCollection::instance()" ); + + return proj->pinnedFieldCollection(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimQuickAccessCollection::addQuickAccessFieldsRecursively( caf::PdmObjectHandle* object ) +{ + if ( object == nullptr ) return; + addQuickAccessFields( object ); + + for ( auto field : object->fields() ) + { + if ( !field ) continue; + + for ( auto childObject : field->children() ) + { + addQuickAccessFieldsRecursively( childObject ); + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimQuickAccessCollection::addQuickAccessFields( caf::PdmObjectHandle* object ) +{ + if ( !object ) return; + + if ( auto quickInterface = dynamic_cast( object ) ) + { + for ( const auto& [groupName, fields] : quickInterface->quickAccessFields() ) + { + if ( auto group = findOrCreateGroup( object, groupName ) ) + { + group->addFields( fields ); + } + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimQuickAccessCollection::addQuickAccessField( const RimFieldReference& fieldReference ) +{ + auto object = fieldReference.object(); + auto field = fieldReference.field(); + if ( object && field ) + { + if ( auto group = findOrCreateGroup( object, "" ) ) + { + group->addField( field ); + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimQuickAccessCollection::defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ) +{ + auto activeView = RiaApplication::instance()->activeGridView(); + if ( !activeView ) return; + + deleteMarkedObjects(); + + std::vector groupsForView; + + for ( auto group : m_fieldQuickAccesGroups ) + { + if ( group->ownerView() == activeView ) + { + updateGroupName( group ); + groupsForView.push_back( group ); + } + } + + for ( auto group : groupsForView ) + { + auto name = group->name(); + if ( name.isEmpty() ) name = defaultGroupName(); + + // Make sure the name of the group is unique in the UI ordering. This is a requirement for the UI ordering, as the groups are + // identified by name. + auto uiName = name; + caf::PdmUiGroup* uiGroup = uiOrdering.findGroup( uiName ); + int index = 1; + while ( uiGroup ) + { + uiName = "(" + QString::number( index++ ) + ") " + name; + uiGroup = uiOrdering.findGroup( uiName ); + } + + uiGroup = uiOrdering.addNewGroup( uiName ); + + for ( auto quickAccess : group->fieldQuickAccesses() ) + { + quickAccess->uiOrdering( uiConfigName, *uiGroup ); + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimQuickAccessCollection::deleteMarkedObjects() +{ + // Delete marked objects and objects pointing to fields that are no longer valid + { + std::set toBeDeleted; + + for ( auto group : m_fieldQuickAccesGroups.childrenByType() ) + { + for ( auto quickAccess : group->fieldQuickAccesses() ) + { + if ( quickAccess->markedForRemoval() || !quickAccess->field() ) + { + toBeDeleted.insert( quickAccess ); + } + } + } + + for ( auto quickAccess : toBeDeleted ) + { + for ( auto group : m_fieldQuickAccesGroups ) + { + group->removeFieldQuickAccess( quickAccess ); + } + + delete quickAccess; + } + } + + // Delete groups with no quick access fields + { + std::set toBeDeleted; + for ( auto group : m_fieldQuickAccesGroups.childrenByType() ) + { + if ( group->fieldQuickAccesses().empty() ) + { + toBeDeleted.insert( group ); + } + } + + for ( auto group : toBeDeleted ) + { + m_fieldQuickAccesGroups.removeChild( group ); + delete group; + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimFieldQuickAccessGroup* RimQuickAccessCollection::findOrCreateGroup( caf::PdmObjectHandle* object, const QString& groupName ) +{ + if ( !object ) return nullptr; + + auto parentView = object->firstAncestorOrThisOfType(); + if ( !parentView ) return nullptr; + + for ( auto group : m_fieldQuickAccesGroups ) + { + if ( !group ) continue; + + if ( groupName.isEmpty() && group->name().isEmpty() && group->ownerView() == parentView ) + { + // If group name is empty, we assume that this is the default group for the view + return group; + } + + if ( group->groupOwner() == object ) return group; + } + + auto group = new RimFieldQuickAccessGroup(); + group->setName( groupName ); + group->setOwnerView( parentView ); + m_fieldQuickAccesGroups.push_back( group ); + + return group; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimQuickAccessCollection::updateGroupName( RimFieldQuickAccessGroup* quickAccessGroup ) +{ + if ( !quickAccessGroup ) return; + + caf::PdmObjectHandle* commonOwnerObject = nullptr; + caf::PdmFieldHandle* firstFieldInQuickAccess = nullptr; + + for ( auto quickAccess : quickAccessGroup->fieldQuickAccesses() ) + { + if ( !quickAccess || !quickAccess->field() || !quickAccess->field()->ownerObject() ) continue; + + if ( !firstFieldInQuickAccess ) firstFieldInQuickAccess = quickAccess->field(); + + auto ownerToField = quickAccess->field()->ownerObject(); + if ( !commonOwnerObject ) + { + commonOwnerObject = ownerToField; + } + else + { + if ( commonOwnerObject != ownerToField ) return; + } + } + + if ( auto fieldInterface = dynamic_cast( commonOwnerObject ) ) + { + auto ownerFields = fieldInterface->quickAccessFields(); + for ( const auto& [groupName, fields] : ownerFields ) + { + for ( auto field : fields ) + { + if ( field == firstFieldInQuickAccess ) + { + quickAccessGroup->setName( groupName ); + return; + } + } + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RimQuickAccessCollection::defaultGroupName() +{ + return "Quick Access for View"; +} diff --git a/ApplicationLibCode/ProjectDataModel/QuickAccess/RimQuickAccessCollection.h b/ApplicationLibCode/ProjectDataModel/QuickAccess/RimQuickAccessCollection.h new file mode 100644 index 0000000000..19b85c74db --- /dev/null +++ b/ApplicationLibCode/ProjectDataModel/QuickAccess/RimQuickAccessCollection.h @@ -0,0 +1,60 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2024- 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 +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "cafPdmChildArrayField.h" +#include "cafPdmField.h" +#include "cafPdmObject.h" +#include "cafPdmPtrArrayField.h" + +class RimFieldQuickAccess; +class RimFieldQuickAccessGroup; +class RimFieldReference; + +//================================================================================================== +/// +/// +//================================================================================================== +class RimQuickAccessCollection : public caf::PdmObject +{ + CAF_PDM_HEADER_INIT; + +public: + RimQuickAccessCollection(); + + static RimQuickAccessCollection* instance(); + + void addQuickAccessFieldsRecursively( caf::PdmObjectHandle* object ); + void addQuickAccessFields( caf::PdmObjectHandle* object ); + + void addQuickAccessField( const RimFieldReference& fieldReference ); + +private: + void defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ) override; + + RimFieldQuickAccessGroup* findOrCreateGroup( caf::PdmObjectHandle* object, const QString& groupName ); + + void deleteMarkedObjects(); + + static void updateGroupName( RimFieldQuickAccessGroup* group ); + static QString defaultGroupName(); + +private: + caf::PdmChildArrayField m_fieldQuickAccesGroups; +}; diff --git a/ApplicationLibCode/ProjectDataModel/RimProject.cpp b/ApplicationLibCode/ProjectDataModel/RimProject.cpp index c2a6f89685..084e723e6b 100644 --- a/ApplicationLibCode/ProjectDataModel/RimProject.cpp +++ b/ApplicationLibCode/ProjectDataModel/RimProject.cpp @@ -37,6 +37,7 @@ #include "Cloud/RimCloudDataSourceCollection.h" #include "PlotTemplates/RimPlotTemplateFolderItem.h" #include "Polygons/RimPolygonCollection.h" +#include "QuickAccess/RimQuickAccessCollection.h" #include "RimAdvancedSnapshotExportDefinition.h" #include "RimAnalysisPlotCollection.h" #include "RimAnnotationCollection.h" @@ -161,6 +162,7 @@ RimProject::RimProject() scriptCollection.xmlCapability()->disableIO(); CAF_PDM_InitFieldNoDefault( &m_mainPlotCollection, "MainPlotCollection", "Plots" ); + CAF_PDM_InitFieldNoDefault( &m_pinnedFieldCollection, "PinnedFieldCollection", "PinnedFieldCollection" ); CAF_PDM_InitFieldNoDefault( &viewLinkerCollection, "LinkedViews", "Linked Views", ":/LinkView.svg" ); viewLinkerCollection = new RimViewLinkerCollection; @@ -221,7 +223,8 @@ RimProject::RimProject() scriptCollection->uiCapability()->setUiName( "Scripts" ); scriptCollection->uiCapability()->setUiIconFromResourceString( ":/octave.png" ); - m_mainPlotCollection = new RimMainPlotCollection(); + m_mainPlotCollection = new RimMainPlotCollection(); + m_pinnedFieldCollection = new RimQuickAccessCollection(); CAF_PDM_InitFieldNoDefault( &m_plotTemplateTopFolder, "PlotTemplateCollection", "Plot Templates" ); m_plotTemplateTopFolder = new RimPlotTemplateFolderItem(); @@ -352,6 +355,14 @@ void RimProject::updatesAfterProjectFileIsRead() if ( m_subWindowsTiledPlotWindow_OBSOLETE ) m_subWindowsTileModePlotWindow = RiaDefines::WindowTileMode::DEFAULT; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimQuickAccessCollection* RimProject::pinnedFieldCollection() const +{ + return m_pinnedFieldCollection(); +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationLibCode/ProjectDataModel/RimProject.h b/ApplicationLibCode/ProjectDataModel/RimProject.h index 92b414698f..06cc3dcda7 100644 --- a/ApplicationLibCode/ProjectDataModel/RimProject.h +++ b/ApplicationLibCode/ProjectDataModel/RimProject.h @@ -71,6 +71,7 @@ class RimValveTemplate; class RimCompletionTemplateCollection; class RimPlotTemplateFolderItem; class RimGridCalculationCollection; +class RimQuickAccessCollection; namespace caf { @@ -190,6 +191,8 @@ public: void updatesAfterProjectFileIsRead(); + RimQuickAccessCollection* pinnedFieldCollection() const; + protected: void initAfterRead() override; void setupBeforeSave() override; @@ -202,7 +205,8 @@ private: QString updatedFilePathFromPathId( QString filePath, RiaVariableMapper* pathListMapper = nullptr ) const; private: - caf::PdmChildField m_mainPlotCollection; + caf::PdmChildField m_mainPlotCollection; + caf::PdmChildField m_pinnedFieldCollection; caf::PdmField m_globalPathList; caf::PdmField m_projectFileVersionString;