diff --git a/ApplicationLibCode/Commands/WellPathCommands/CMakeLists_files.cmake b/ApplicationLibCode/Commands/WellPathCommands/CMakeLists_files.cmake index e8720d49b1..05d2b44324 100644 --- a/ApplicationLibCode/Commands/WellPathCommands/CMakeLists_files.cmake +++ b/ApplicationLibCode/Commands/WellPathCommands/CMakeLists_files.cmake @@ -31,6 +31,7 @@ set(SOURCE_GROUP_HEADER_FILES ${CMAKE_CURRENT_LIST_DIR}/PointTangentManipulator/RicPolyline3dEditor.h ${CMAKE_CURRENT_LIST_DIR}/PointTangentManipulator/RicPolylineTarget3dEditor.h ${CMAKE_CURRENT_LIST_DIR}/RicDuplicateWellPathFeature.h + ${CMAKE_CURRENT_LIST_DIR}/RicSetParentWellPathFeature.h ) set(SOURCE_GROUP_SOURCE_FILES @@ -66,6 +67,7 @@ set(SOURCE_GROUP_SOURCE_FILES ${CMAKE_CURRENT_LIST_DIR}/PointTangentManipulator/RicPolyline3dEditor.cpp ${CMAKE_CURRENT_LIST_DIR}/PointTangentManipulator/RicPolylineTarget3dEditor.cpp ${CMAKE_CURRENT_LIST_DIR}/RicDuplicateWellPathFeature.cpp + ${CMAKE_CURRENT_LIST_DIR}/RicSetParentWellPathFeature.cpp ) list(APPEND COMMAND_CODE_HEADER_FILES ${SOURCE_GROUP_HEADER_FILES}) diff --git a/ApplicationLibCode/Commands/WellPathCommands/RicSetParentWellPathFeature.cpp b/ApplicationLibCode/Commands/WellPathCommands/RicSetParentWellPathFeature.cpp new file mode 100644 index 0000000000..a130320d9b --- /dev/null +++ b/ApplicationLibCode/Commands/WellPathCommands/RicSetParentWellPathFeature.cpp @@ -0,0 +1,149 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// 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 "RicSetParentWellPathFeature.h" + +#include "RigWellPath.h" + +#include "RimTools.h" +#include "RimWellPath.h" +#include "RimWellPathCollection.h" +#include "RimWellPathTieIn.h" + +#include "RiuMainWindow.h" + +#include "cafPdmUiPropertyViewDialog.h" +#include "cafSelectionManager.h" + +#include + +CAF_PDM_SOURCE_INIT( RicSelectWellPathUi, "RicSelectWellPathUi" ); + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RicSelectWellPathUi::RicSelectWellPathUi() +{ + CAF_PDM_InitObject( "RicSelectWellPathUi" ); + + CAF_PDM_InitFieldNoDefault( &m_selectedWellPath, "SelectedWellPath", "Well Path" ); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicSelectWellPathUi::setWellPaths( const std::vector& wellPaths ) +{ + m_wellPaths = wellPaths; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicSelectWellPathUi::setSelectedWell( RimWellPath* selectedWell ) +{ + m_selectedWellPath = selectedWell; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimWellPath* RicSelectWellPathUi::wellPath() const +{ + return m_selectedWellPath(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QList RicSelectWellPathUi::calculateValueOptions( const caf::PdmFieldHandle* fieldNeedingOptions ) +{ + QList options; + + options.push_back( caf::PdmOptionItemInfo( "None", nullptr ) ); + + RimTools::optionItemsForSpecifiedWellPaths( m_wellPaths, &options ); + return options; +} + +CAF_CMD_SOURCE_INIT( RicSetParentWellPathFeature, "RicSetParentWellPathFeature" ); + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicSetParentWellPathFeature::onActionTriggered( bool isChecked ) +{ + auto selectedWellPath = caf::SelectionManager::instance()->selectedItemOfType(); + if ( !selectedWellPath ) return; + + auto wpc = RimTools::wellPathCollection(); + if ( !wpc ) return; + + std::vector wellPathCandidates; + for ( auto w : wpc->allWellPaths() ) + { + if ( w != selectedWellPath ) wellPathCandidates.push_back( w ); + } + + RicSelectWellPathUi ui; + ui.setWellPaths( wellPathCandidates ); + + RimWellPath* parentWell = nullptr; + if ( selectedWellPath->wellPathTieIn() ) parentWell = selectedWellPath->wellPathTieIn()->parentWell(); + ui.setSelectedWell( parentWell ); + + caf::PdmUiPropertyViewDialog propertyDialog( nullptr, &ui, "Select Parent Well", "" ); + propertyDialog.resize( QSize( 400, 200 ) ); + + if ( propertyDialog.exec() == QDialog::Accepted ) + { + auto parentWellPath = ui.wellPath(); + + double tieInMeasuredDepth = 0.0; + if ( parentWellPath ) + { + if ( !parentWellPath->wellPathGeometry() || parentWellPath->wellPathGeometry()->measuredDepths().size() < 2 ) return; + if ( selectedWellPath->wellPathGeometry()->wellPathPoints().empty() ) return; + + auto headOfLateral = selectedWellPath->wellPathGeometry()->wellPathPoints().front(); + + cvf::Vec3d p1, p2; + parentWellPath->wellPathGeometry()->twoClosestPoints( headOfLateral, &p1, &p2 ); + + tieInMeasuredDepth = parentWellPath->wellPathGeometry()->closestMeasuredDepth( p1 ); + } + + selectedWellPath->connectWellPaths( parentWellPath, tieInMeasuredDepth ); + + wpc->rebuildWellPathNodes(); + wpc->scheduleRedrawAffectedViews(); + wpc->updateAllRequiredEditors(); + + RiuMainWindow::instance()->setExpanded( selectedWellPath ); + RiuMainWindow::instance()->selectAsCurrentItem( selectedWellPath ); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicSetParentWellPathFeature::setupActionLook( QAction* actionToSetup ) +{ + actionToSetup->setText( "Set Parent Well Path" ); + actionToSetup->setIcon( QIcon( ":/Well.svg" ) ); +} diff --git a/ApplicationLibCode/Commands/WellPathCommands/RicSetParentWellPathFeature.h b/ApplicationLibCode/Commands/WellPathCommands/RicSetParentWellPathFeature.h new file mode 100644 index 0000000000..880d067515 --- /dev/null +++ b/ApplicationLibCode/Commands/WellPathCommands/RicSetParentWellPathFeature.h @@ -0,0 +1,66 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// 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 "cafCmdFeature.h" +#include "cafPdmObject.h" +#include "cafPdmPtrField.h" + +#include + +#include + +namespace caf +{ +class PdmOptionItemInfo; +} + +class RimWellPath; + +class RicSelectWellPathUi : public caf::PdmObject +{ + CAF_PDM_HEADER_INIT; + +public: + RicSelectWellPathUi(); + + void setWellPaths( const std::vector& wellPaths ); + void setSelectedWell( RimWellPath* selectedWell ); + + RimWellPath* wellPath() const; + +protected: + QList calculateValueOptions( const caf::PdmFieldHandle* fieldNeedingOptions ) override; + +private: + caf::PdmPtrField m_selectedWellPath; + std::vector m_wellPaths; +}; + +//================================================================================================== +/// +//================================================================================================== +class RicSetParentWellPathFeature : public caf::CmdFeature +{ + CAF_CMD_HEADER_INIT; + +protected: + void onActionTriggered( bool isChecked ) override; + void setupActionLook( QAction* actionToSetup ) override; +}; diff --git a/ApplicationLibCode/ProjectDataModel/RimContextCommandBuilder.cpp b/ApplicationLibCode/ProjectDataModel/RimContextCommandBuilder.cpp index a6769cf17d..71841548ff 100644 --- a/ApplicationLibCode/ProjectDataModel/RimContextCommandBuilder.cpp +++ b/ApplicationLibCode/ProjectDataModel/RimContextCommandBuilder.cpp @@ -389,9 +389,11 @@ caf::CmdFeatureMenuBuilder RimContextCommandBuilder::commandsFromSelection() { menuBuilder << "RicNewEditableWellPathFeature"; menuBuilder << "RicNewWellPathLateralFeature"; - menuBuilder << "RicLinkWellPathFeature"; menuBuilder << "RicDuplicateWellPathFeature"; + menuBuilder.addSeparator(); + menuBuilder << "RicSetParentWellPathFeature"; + menuBuilder.addSeparator(); menuBuilder << "RicNewWellPathIntersectionFeature"; @@ -421,6 +423,7 @@ caf::CmdFeatureMenuBuilder RimContextCommandBuilder::commandsFromSelection() menuBuilder.subMenuEnd(); menuBuilder.addSeparator(); + menuBuilder << "RicLinkWellPathFeature"; menuBuilder << "RicDeleteWellPathFeature"; menuBuilder.addSeparator(); diff --git a/ApplicationLibCode/ProjectDataModel/RimTools.h b/ApplicationLibCode/ProjectDataModel/RimTools.h index 5146a59cc7..8985404324 100644 --- a/ApplicationLibCode/ProjectDataModel/RimTools.h +++ b/ApplicationLibCode/ProjectDataModel/RimTools.h @@ -82,6 +82,5 @@ public: static void timeStepsForCase( RimCase* gridCase, QList* options ); -private: static void optionItemsForSpecifiedWellPaths( const std::vector& wellPaths, QList* options ); }; diff --git a/ApplicationLibCode/ProjectDataModel/WellPath/RimWellPath.h b/ApplicationLibCode/ProjectDataModel/WellPath/RimWellPath.h index e1d8a03bf8..8bf83163cf 100644 --- a/ApplicationLibCode/ProjectDataModel/WellPath/RimWellPath.h +++ b/ApplicationLibCode/ProjectDataModel/WellPath/RimWellPath.h @@ -170,7 +170,7 @@ public: std::vector wellPathLaterals() const; RimWellPathTieIn* wellPathTieIn() const; - void connectWellPaths( RimWellPath* childWell, double tieInMeasuredDepth ); + void connectWellPaths( RimWellPath* parentWell, double tieInMeasuredDepth ); protected: // Override PdmObject diff --git a/ApplicationLibCode/ProjectDataModel/WellPath/RimWellPathTieIn.cpp b/ApplicationLibCode/ProjectDataModel/WellPath/RimWellPathTieIn.cpp index d29d0e7aba..6cf36935b1 100644 --- a/ApplicationLibCode/ProjectDataModel/WellPath/RimWellPathTieIn.cpp +++ b/ApplicationLibCode/ProjectDataModel/WellPath/RimWellPathTieIn.cpp @@ -30,8 +30,8 @@ #include "RiuMainWindow.h" -#include "RigWellPathGeometryTools.h" #include "cafPdmUiDoubleSliderEditor.h" +#include "cafPdmUiLabelEditor.h" CAF_PDM_SOURCE_INIT( RimWellPathTieIn, "RimWellPathTieIn" ); @@ -42,7 +42,14 @@ RimWellPathTieIn::RimWellPathTieIn() { CAF_PDM_InitObject( "Well Path Tie In", ":/NotDefined.png", "", "Well Path Tie In description" ); + CAF_PDM_InitFieldNoDefault( &m_infoLabel, "InfoLabel", "Use right-click menu of well to set parent well." ); + m_infoLabel.uiCapability()->setUiEditorTypeName( caf::PdmUiLabelEditor::uiEditorTypeName() ); + m_infoLabel.xmlCapability()->disableIO(); + m_infoLabel.uiCapability()->setUiLabelPosition( caf::PdmUiItemInfo::TOP ); + CAF_PDM_InitFieldNoDefault( &m_parentWell, "ParentWellPath", "Parent Well Path" ); + m_parentWell.uiCapability()->setUiReadOnly( true ); + CAF_PDM_InitFieldNoDefault( &m_childWell, "ChildWellPath", "ChildWellPath" ); CAF_PDM_InitFieldNoDefault( &m_tieInMeasuredDepth, "TieInMeasuredDepth", "Tie In Measured Depth" ); m_tieInMeasuredDepth.uiCapability()->setUiEditorTypeName( caf::PdmUiDoubleSliderEditor::uiEditorTypeName() ); @@ -161,6 +168,7 @@ const RimWellPathValve* RimWellPathTieIn::outletValve() const void RimWellPathTieIn::defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ) { auto tieInGroup = uiOrdering.addNewGroup( "Tie In Settings" ); + tieInGroup->add( &m_infoLabel ); tieInGroup->add( &m_parentWell ); if ( m_parentWell() != nullptr ) { @@ -187,6 +195,11 @@ void RimWellPathTieIn::defineUiOrdering( QString uiConfigName, caf::PdmUiOrderin //-------------------------------------------------------------------------------------------------- void RimWellPathTieIn::fieldChangedByUi( const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue ) { + // TODO: It is not possible to change the parent well from the UI as the field is set to read only. Refactor and possibly delete this + // method. + // https://github.com/OPM/ResInsight/issues/11312 + // https://github.com/OPM/ResInsight/issues/11313 + if ( changedField == &m_parentWell ) { updateFirstTargetFromParentWell(); diff --git a/ApplicationLibCode/ProjectDataModel/WellPath/RimWellPathTieIn.h b/ApplicationLibCode/ProjectDataModel/WellPath/RimWellPathTieIn.h index 09a82f4054..35576f85cc 100644 --- a/ApplicationLibCode/ProjectDataModel/WellPath/RimWellPathTieIn.h +++ b/ApplicationLibCode/ProjectDataModel/WellPath/RimWellPathTieIn.h @@ -55,6 +55,8 @@ private: void defineEditorAttribute( const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute* attribute ) override; private: + caf::PdmField m_infoLabel; + caf::PdmPtrField m_parentWell; caf::PdmPtrField m_childWell; caf::PdmField m_tieInMeasuredDepth;