diff --git a/ApplicationExeCode/Resources/CheckOverlay16x16.png b/ApplicationExeCode/Resources/CheckOverlay16x16.png new file mode 100644 index 0000000000..23979cd107 Binary files /dev/null and b/ApplicationExeCode/Resources/CheckOverlay16x16.png differ diff --git a/ApplicationExeCode/Resources/ResInsight.qrc b/ApplicationExeCode/Resources/ResInsight.qrc index 3b07b776da..f0ce42be12 100644 --- a/ApplicationExeCode/Resources/ResInsight.qrc +++ b/ApplicationExeCode/Resources/ResInsight.qrc @@ -146,6 +146,7 @@ SummaryPlots16x16.png SummaryPlotsLight16x16.png SummaryTemplate16x16.png + SummaryEnsembleTemplate16x16.png SummaryXPlotLight16x16.png SummaryXPlotsLight16x16.png Swap.png @@ -267,6 +268,7 @@ AppendPrevCurve.svg AppendNextCurve.png AppendPrevCurve.png + CheckOverlay16x16.png fs_CellFace.glsl diff --git a/ApplicationExeCode/Resources/SummaryEnsembleTemplate16x16.png b/ApplicationExeCode/Resources/SummaryEnsembleTemplate16x16.png new file mode 100644 index 0000000000..cac7f2e6bb Binary files /dev/null and b/ApplicationExeCode/Resources/SummaryEnsembleTemplate16x16.png differ diff --git a/ApplicationLibCode/Application/RiaPreferences.cpp b/ApplicationLibCode/Application/RiaPreferences.cpp index f2e2594507..f1d7970401 100644 --- a/ApplicationLibCode/Application/RiaPreferences.cpp +++ b/ApplicationLibCode/Application/RiaPreferences.cpp @@ -213,13 +213,12 @@ RiaPreferences::RiaPreferences() CAF_PDM_InitFieldNoDefault( &m_plotTemplateFolders, "plotTemplateFolders", "Plot Template Folder(s)" ); m_plotTemplateFolders.uiCapability()->setUiEditorTypeName( caf::PdmUiFilePathEditor::uiEditorTypeName() ); - CAF_PDM_InitField( &m_searchPlotTemplateFoldersRecursively, - "SearchPlotTemplateFoldersRecursively", - true, - "Search Plot Templates Recursively" ); - caf::PdmUiNativeCheckBoxEditor::configureFieldForEditor( &m_searchPlotTemplateFoldersRecursively ); + CAF_PDM_InitField( &m_maxPlotTemplateFoldersDepth, + "MaxPlotTemplateFoldersDepth", + 2, + "Maximum Plot Template Folder Search Depth" ); - CAF_PDM_InitFieldNoDefault( &m_defaultPlotTemplate, "defaultPlotTemplate", "Default Plot Template" ); + CAF_PDM_InitFieldNoDefault( &m_lastUsedPlotTemplate, "defaultPlotTemplate", "Default Plot Template" ); CAF_PDM_InitFieldNoDefault( &m_pageSize, "pageSize", "Page Size" ); CAF_PDM_InitFieldNoDefault( &m_pageOrientation, "pageOrientation", "Page Orientation" ); @@ -383,7 +382,7 @@ void RiaPreferences::defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& caf::PdmUiGroup* group = summaryGrp->addNewGroup( "Plot Templates" ); group->add( &m_plotTemplateFolders ); - group->add( &m_searchPlotTemplateFoldersRecursively ); + group->add( &m_maxPlotTemplateFoldersDepth ); caf::PdmUiGroup* generalGrp = uiOrdering.addNewGroup( "General" ); @@ -671,9 +670,9 @@ QString RiaPreferences::dateTimeFormat( RiaDefines::DateFormatComponents dateCom //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -bool RiaPreferences::searchPlotTemplateFoldersRecursively() const +int RiaPreferences::maxPlotTemplateFoldersDepth() const { - return m_searchPlotTemplateFoldersRecursively(); + return m_maxPlotTemplateFoldersDepth(); } //-------------------------------------------------------------------------------------------------- @@ -714,17 +713,17 @@ void RiaPreferences::appendPlotTemplateFolders( const QString& folder ) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -QString RiaPreferences::defaultPlotTemplateAbsolutePath() const +QString RiaPreferences::lastUsedPlotTemplateAbsolutePath() const { - return m_defaultPlotTemplate().path(); + return m_lastUsedPlotTemplate().path(); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RiaPreferences::setDefaultPlotTemplatePath( const QString& templatePath ) +void RiaPreferences::setLastUsedPlotTemplatePath( const QString& templatePath ) { - m_defaultPlotTemplate = templatePath; + m_lastUsedPlotTemplate = templatePath; } //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationLibCode/Application/RiaPreferences.h b/ApplicationLibCode/Application/RiaPreferences.h index 7e5ad4d062..620fbe2c5c 100644 --- a/ApplicationLibCode/Application/RiaPreferences.h +++ b/ApplicationLibCode/Application/RiaPreferences.h @@ -76,11 +76,11 @@ public: RiaDefines::DateFormatComponents dateComponents = RiaDefines::DateFormatComponents::DATE_FORMAT_YEAR_MONTH_DAY, RiaDefines::TimeFormatComponents timeComponents = RiaDefines::TimeFormatComponents::TIME_FORMAT_HOUR_MINUTE_SECOND ) const; - bool searchPlotTemplateFoldersRecursively() const; + int maxPlotTemplateFoldersDepth() const; QStringList plotTemplateFolders() const; void appendPlotTemplateFolders( const QString& folder ); - QString defaultPlotTemplateAbsolutePath() const; - void setDefaultPlotTemplatePath( const QString& templatePath ); + QString lastUsedPlotTemplateAbsolutePath() const; + void setLastUsedPlotTemplatePath( const QString& templatePath ); bool openExportedPdfInViewer() const; bool useQtChartsAsDefaultPlotType() const; @@ -182,8 +182,8 @@ private: caf::PdmField m_openExportedPdfInViewer; caf::PdmField m_plotTemplateFolders; - caf::PdmField m_searchPlotTemplateFoldersRecursively; - caf::PdmField m_defaultPlotTemplate; + caf::PdmField m_maxPlotTemplateFoldersDepth; + caf::PdmField m_lastUsedPlotTemplate; caf::PdmField m_useQtChartsPlotByDefault; // Script paths diff --git a/ApplicationLibCode/Application/RiaPreferencesSummary.cpp b/ApplicationLibCode/Application/RiaPreferencesSummary.cpp index e555f89bac..31157b72e8 100644 --- a/ApplicationLibCode/Application/RiaPreferencesSummary.cpp +++ b/ApplicationLibCode/Application/RiaPreferencesSummary.cpp @@ -31,6 +31,7 @@ #include "cafPdmUiPushButtonEditor.h" #include +#include namespace caf { @@ -535,9 +536,20 @@ RiaPreferencesSummary::DefaultSummaryPlotType RiaPreferencesSummary::defaultSumm //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -std::vector RiaPreferencesSummary::defaultSummaryPlotTemplates() const +std::vector RiaPreferencesSummary::defaultSummaryPlotTemplates( bool returnEnsembleTemplates ) const { - return m_selectedDefaultTemplates(); + std::vector templatesToUse; + for ( auto& fileName : m_selectedDefaultTemplates() ) + { + bool singleTemplate = fileName.toLower().endsWith( ".rpt" ); + if ( singleTemplate && returnEnsembleTemplates ) continue; + if ( !singleTemplate && !returnEnsembleTemplates ) continue; + + if ( std::count( templatesToUse.begin(), templatesToUse.end(), fileName ) == 0 ) + templatesToUse.push_back( fileName ); + } + + return templatesToUse; } //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationLibCode/Application/RiaPreferencesSummary.h b/ApplicationLibCode/Application/RiaPreferencesSummary.h index 18f3035876..acfaa97169 100644 --- a/ApplicationLibCode/Application/RiaPreferencesSummary.h +++ b/ApplicationLibCode/Application/RiaPreferencesSummary.h @@ -84,7 +84,7 @@ public: int createH5SummaryDataThreadCount() const; DefaultSummaryPlotType defaultSummaryPlotType() const; - std::vector defaultSummaryPlotTemplates() const; + std::vector defaultSummaryPlotTemplates( bool returnEnsembleTemplates ) const; bool isDefaultSummaryPlotTemplate( QString filename ) const; void addToDefaultPlotTemplates( QString filename ); void removeFromDefaultPlotTemplates( QString filename ); diff --git a/ApplicationLibCode/Commands/PlotBuilderCommands/RicSummaryPlotBuilder.cpp b/ApplicationLibCode/Commands/PlotBuilderCommands/RicSummaryPlotBuilder.cpp index 113655244a..c50a907c8d 100644 --- a/ApplicationLibCode/Commands/PlotBuilderCommands/RicSummaryPlotBuilder.cpp +++ b/ApplicationLibCode/Commands/PlotBuilderCommands/RicSummaryPlotBuilder.cpp @@ -416,8 +416,9 @@ RimSummaryMultiPlot* if ( prefs->defaultSummaryPlotType() == RiaPreferencesSummary::DefaultSummaryPlotType::PLOT_TEMPLATES ) { - RimSummaryMultiPlot* plotToSelect = nullptr; - for ( auto& filename : prefs->defaultSummaryPlotTemplates() ) + RimSummaryMultiPlot* plotToSelect = nullptr; + bool ensembleTemplates = ( ensembles.size() > 0 ); + for ( auto& filename : prefs->defaultSummaryPlotTemplates( ensembleTemplates ) ) { plotToSelect = RicSummaryPlotTemplateTools::create( filename, cases, ensembles ); } diff --git a/ApplicationLibCode/Commands/PlotTemplateCommands/CMakeLists_files.cmake b/ApplicationLibCode/Commands/PlotTemplateCommands/CMakeLists_files.cmake index 226231216b..667b6c1e0d 100644 --- a/ApplicationLibCode/Commands/PlotTemplateCommands/CMakeLists_files.cmake +++ b/ApplicationLibCode/Commands/PlotTemplateCommands/CMakeLists_files.cmake @@ -10,6 +10,8 @@ set(SOURCE_GROUP_HEADER_FILES ${CMAKE_CURRENT_LIST_DIR}/RicEditPlotTemplateFeature.h ${CMAKE_CURRENT_LIST_DIR}/RicDeletePlotTemplateFeature.h ${CMAKE_CURRENT_LIST_DIR}/RicSetAsDefaultTemplateFeature.h + ${CMAKE_CURRENT_LIST_DIR}/RicCreateNewPlotFromTemplateFeature.h + ${CMAKE_CURRENT_LIST_DIR}/RicSelectCaseOrEnsembleUi.h ) set(SOURCE_GROUP_SOURCE_FILES @@ -24,6 +26,8 @@ set(SOURCE_GROUP_SOURCE_FILES ${CMAKE_CURRENT_LIST_DIR}/RicEditPlotTemplateFeature.cpp ${CMAKE_CURRENT_LIST_DIR}/RicDeletePlotTemplateFeature.cpp ${CMAKE_CURRENT_LIST_DIR}/RicSetAsDefaultTemplateFeature.cpp + ${CMAKE_CURRENT_LIST_DIR}/RicCreateNewPlotFromTemplateFeature.cpp + ${CMAKE_CURRENT_LIST_DIR}/RicSelectCaseOrEnsembleUi.cpp ) list(APPEND COMMAND_CODE_HEADER_FILES ${SOURCE_GROUP_HEADER_FILES}) diff --git a/ApplicationLibCode/Commands/PlotTemplateCommands/RicCreateNewPlotFromTemplateFeature.cpp b/ApplicationLibCode/Commands/PlotTemplateCommands/RicCreateNewPlotFromTemplateFeature.cpp new file mode 100644 index 0000000000..659c2297ba --- /dev/null +++ b/ApplicationLibCode/Commands/PlotTemplateCommands/RicCreateNewPlotFromTemplateFeature.cpp @@ -0,0 +1,145 @@ +//////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2022 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 "RicCreateNewPlotFromTemplateFeature.h" + +#include "PlotTemplates/RimPlotTemplateFileItem.h" + +#include "RiaGuiApplication.h" +#include "RiaPreferences.h" + +#include "RicSelectCaseOrEnsembleUi.h" +#include "RicSummaryPlotTemplateTools.h" + +#include "RimSummaryCase.h" +#include "RimSummaryCaseCollection.h" +#include "RimSummaryMultiPlot.h" + +#include "RiuPlotMainWindow.h" +#include "RiuPlotMainWindowTools.h" + +#include "cafPdmUiPropertyViewDialog.h" +#include "cafSelectionManager.h" + +#include +#include + +CAF_CMD_SOURCE_INIT( RicCreateNewPlotFromTemplateFeature, "RicCreateNewPlotFromTemplateFeature" ); + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RicCreateNewPlotFromTemplateFeature::isCommandEnabled() +{ + std::vector uiItems; + caf::SelectionManager::instance()->selectedItems( uiItems ); + if ( uiItems.size() != 1 ) return false; + + RimPlotTemplateFileItem* file = dynamic_cast( uiItems[0] ); + return ( file != nullptr ); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicCreateNewPlotFromTemplateFeature::onActionTriggered( bool isChecked ) +{ + std::vector uiItems; + caf::SelectionManager::instance()->selectedItems( uiItems ); + + if ( uiItems.size() != 1 ) return; + + RimPlotTemplateFileItem* file = dynamic_cast( uiItems[0] ); + if ( file == nullptr ) return; + + RimSummaryMultiPlot* plot = nullptr; + + if ( file->isEnsembleTemplate() ) + { + auto ensemble = selectEnsemble(); + if ( !ensemble ) return; + + plot = RicSummaryPlotTemplateTools::create( file->absoluteFilePath(), {}, { ensemble } ); + } + else + { + auto sumCase = selectSummaryCase(); + if ( !sumCase ) return; + + plot = RicSummaryPlotTemplateTools::create( file->absoluteFilePath(), { sumCase }, {} ); + } + + if ( plot != nullptr ) + { + RiaPreferences::current()->setLastUsedPlotTemplatePath( file->absoluteFilePath() ); + RiaPreferences::current()->writePreferencesToApplicationStore(); + } + + RiuPlotMainWindowTools::selectAsCurrentItem( plot ); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicCreateNewPlotFromTemplateFeature::setupActionLook( QAction* actionToSetup ) +{ + actionToSetup->setText( "Create New Plot" ); + actionToSetup->setIcon( QIcon( ":/SummaryPlotLight16x16.png" ) ); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimSummaryCase* RicCreateNewPlotFromTemplateFeature::selectSummaryCase() +{ + RiuPlotMainWindow* plotwindow = RiaGuiApplication::instance()->mainPlotWindow(); + RicSelectCaseOrEnsembleUi ui; + + ui.setEnsembleSelectionMode( false ); + + caf::PdmUiPropertyViewDialog propertyDialog( plotwindow, &ui, "Create New Plot - Select Summary Case", "" ); + propertyDialog.resize( QSize( 400, 200 ) ); + + if ( propertyDialog.exec() == QDialog::Accepted ) + { + return ui.selectedSummaryCase(); + } + + return nullptr; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimSummaryCaseCollection* RicCreateNewPlotFromTemplateFeature::selectEnsemble() +{ + RiuPlotMainWindow* plotwindow = RiaGuiApplication::instance()->mainPlotWindow(); + RicSelectCaseOrEnsembleUi ui; + + ui.setEnsembleSelectionMode( true ); + + caf::PdmUiPropertyViewDialog propertyDialog( plotwindow, &ui, "Create New Plot - Select Ensemble", "" ); + propertyDialog.resize( QSize( 400, 200 ) ); + + if ( propertyDialog.exec() == QDialog::Accepted ) + { + return ui.selectedEnsemble(); + } + + return nullptr; +} diff --git a/ApplicationLibCode/Commands/PlotTemplateCommands/RicCreateNewPlotFromTemplateFeature.h b/ApplicationLibCode/Commands/PlotTemplateCommands/RicCreateNewPlotFromTemplateFeature.h new file mode 100644 index 0000000000..3712ec5be1 --- /dev/null +++ b/ApplicationLibCode/Commands/PlotTemplateCommands/RicCreateNewPlotFromTemplateFeature.h @@ -0,0 +1,41 @@ +//////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2022 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" + +class RimSummaryCase; +class RimSummaryCaseCollection; + +//================================================================================================== +/// +//================================================================================================== +class RicCreateNewPlotFromTemplateFeature : public caf::CmdFeature +{ + CAF_CMD_HEADER_INIT; + +protected: + bool isCommandEnabled() override; + void onActionTriggered( bool isChecked ) override; + void setupActionLook( QAction* actionToSetup ) override; + +private: + RimSummaryCase* selectSummaryCase(); + RimSummaryCaseCollection* selectEnsemble(); +}; diff --git a/ApplicationLibCode/Commands/PlotTemplateCommands/RicCreatePlotFromTemplateByShortcutFeature.cpp b/ApplicationLibCode/Commands/PlotTemplateCommands/RicCreatePlotFromTemplateByShortcutFeature.cpp index 77a8433b5e..1909f6e78d 100644 --- a/ApplicationLibCode/Commands/PlotTemplateCommands/RicCreatePlotFromTemplateByShortcutFeature.cpp +++ b/ApplicationLibCode/Commands/PlotTemplateCommands/RicCreatePlotFromTemplateByShortcutFeature.cpp @@ -47,7 +47,7 @@ bool RicCreatePlotFromTemplateByShortcutFeature::isCommandEnabled() //-------------------------------------------------------------------------------------------------- void RicCreatePlotFromTemplateByShortcutFeature::onActionTriggered( bool isChecked ) { - QString fileName = RiaPreferences::current()->defaultPlotTemplateAbsolutePath(); + QString fileName = RiaPreferences::current()->lastUsedPlotTemplateAbsolutePath(); if ( !QFile::exists( fileName ) ) { diff --git a/ApplicationLibCode/Commands/PlotTemplateCommands/RicEditPlotTemplateFeature.cpp b/ApplicationLibCode/Commands/PlotTemplateCommands/RicEditPlotTemplateFeature.cpp index 7af55df646..d83da0d050 100644 --- a/ApplicationLibCode/Commands/PlotTemplateCommands/RicEditPlotTemplateFeature.cpp +++ b/ApplicationLibCode/Commands/PlotTemplateCommands/RicEditPlotTemplateFeature.cpp @@ -88,5 +88,4 @@ void RicEditPlotTemplateFeature::onActionTriggered( bool isChecked ) void RicEditPlotTemplateFeature::setupActionLook( QAction* actionToSetup ) { actionToSetup->setText( "Edit" ); - actionToSetup->setIcon( QIcon( ":/SummaryTemplate16x16.png" ) ); } diff --git a/ApplicationLibCode/Commands/PlotTemplateCommands/RicRenamePlotTemplateFeature.cpp b/ApplicationLibCode/Commands/PlotTemplateCommands/RicRenamePlotTemplateFeature.cpp index 78672c3a31..a180372d95 100644 --- a/ApplicationLibCode/Commands/PlotTemplateCommands/RicRenamePlotTemplateFeature.cpp +++ b/ApplicationLibCode/Commands/PlotTemplateCommands/RicRenamePlotTemplateFeature.cpp @@ -95,5 +95,4 @@ void RicRenamePlotTemplateFeature::onActionTriggered( bool isChecked ) void RicRenamePlotTemplateFeature::setupActionLook( QAction* actionToSetup ) { actionToSetup->setText( "Rename" ); - actionToSetup->setIcon( QIcon( ":/SummaryTemplate16x16.png" ) ); } diff --git a/ApplicationLibCode/Commands/PlotTemplateCommands/RicSaveMultiPlotTemplateFeature.cpp b/ApplicationLibCode/Commands/PlotTemplateCommands/RicSaveMultiPlotTemplateFeature.cpp index 36f1a81781..c5ced2b877 100644 --- a/ApplicationLibCode/Commands/PlotTemplateCommands/RicSaveMultiPlotTemplateFeature.cpp +++ b/ApplicationLibCode/Commands/PlotTemplateCommands/RicSaveMultiPlotTemplateFeature.cpp @@ -89,7 +89,13 @@ void RicSaveMultiPlotTemplateFeature::onActionTriggered( bool isChecked ) caf::PdmUiPropertyViewDialog propertyDialog( RiuPlotMainWindow::instance(), &settings, "Export Plot Template", "" ); if ( propertyDialog.exec() != QDialog::Accepted ) return; - QString fileName = settings.filePath() + "/" + settings.name() + ".rpt"; + auto plot = selectedSummaryPlot(); + if ( !plot ) return; + + QString ext = ".rpt"; + if ( selectedSummaryPlot()->curveSets().size() > 0 ) ext = ".erpt"; + + QString fileName = settings.filePath() + "/" + settings.name() + ext; if ( !fileName.isEmpty() ) { QFile exportFile( fileName ); diff --git a/ApplicationLibCode/Commands/PlotTemplateCommands/RicSelectCaseOrEnsembleUi.cpp b/ApplicationLibCode/Commands/PlotTemplateCommands/RicSelectCaseOrEnsembleUi.cpp new file mode 100644 index 0000000000..d669925c66 --- /dev/null +++ b/ApplicationLibCode/Commands/PlotTemplateCommands/RicSelectCaseOrEnsembleUi.cpp @@ -0,0 +1,134 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2022 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 "RicSelectCaseOrEnsembleUi.h" + +#include "RimProject.h" +#include "RimSummaryCase.h" +#include "RimSummaryCaseCollection.h" + +CAF_PDM_SOURCE_INIT( RicSelectCaseOrEnsembleUi, "RicSelectCaseOrEnsembleUi" ); + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RicSelectCaseOrEnsembleUi::RicSelectCaseOrEnsembleUi() + : m_useEnsembleMode( false ) +{ + CAF_PDM_InitObject( "RicSelectCaseOrEnsembleUi" ); + + CAF_PDM_InitFieldNoDefault( &m_selectedSummaryCase, "SelectedSummaryCase", "Summary Case" ); + m_selectedSummaryCase.uiCapability()->setAutoAddingOptionFromValue( false ); + + CAF_PDM_InitFieldNoDefault( &m_selectedEnsemble, "SelectedEnsemble", "Ensemble" ); + m_selectedEnsemble.uiCapability()->setAutoAddingOptionFromValue( false ); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicSelectCaseOrEnsembleUi::setEnsembleSelectionMode( bool ensembleMode ) +{ + m_useEnsembleMode = ensembleMode; + + RimProject* proj = RimProject::current(); + + if ( ensembleMode ) + { + std::vector groups = proj->summaryGroups(); + + for ( RimSummaryCaseCollection* group : groups ) + { + if ( group->isEnsemble() ) + { + m_selectedEnsemble = group; + break; + } + } + } + else + { + std::vector cases = proj->allSummaryCases(); + if ( cases.size() > 0 ) m_selectedSummaryCase = cases.front(); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QList + RicSelectCaseOrEnsembleUi::calculateValueOptions( const caf::PdmFieldHandle* fieldNeedingOptions ) +{ + QList options; + + if ( fieldNeedingOptions == &m_selectedSummaryCase ) + { + RimProject* proj = RimProject::current(); + + std::vector cases = proj->allSummaryCases(); + + for ( RimSummaryCase* rimCase : cases ) + { + options.push_back( caf::PdmOptionItemInfo( rimCase->displayCaseName(), rimCase ) ); + } + } + else if ( fieldNeedingOptions == &m_selectedEnsemble ) + { + RimProject* proj = RimProject::current(); + std::vector groups = proj->summaryGroups(); + + for ( RimSummaryCaseCollection* group : groups ) + { + if ( group->isEnsemble() ) options.push_back( caf::PdmOptionItemInfo( group->name(), group ) ); + } + } + + return options; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicSelectCaseOrEnsembleUi::defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ) +{ + if ( m_useEnsembleMode ) + uiOrdering.add( &m_selectedEnsemble ); + else + uiOrdering.add( &m_selectedSummaryCase ); + + uiOrdering.skipRemainingFields(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimSummaryCase* RicSelectCaseOrEnsembleUi::selectedSummaryCase() const +{ + if ( m_useEnsembleMode ) return nullptr; + + return m_selectedSummaryCase(); +} +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimSummaryCaseCollection* RicSelectCaseOrEnsembleUi::selectedEnsemble() const +{ + if ( !m_useEnsembleMode ) return nullptr; + + return m_selectedEnsemble(); +} diff --git a/ApplicationLibCode/Commands/PlotTemplateCommands/RicSelectCaseOrEnsembleUi.h b/ApplicationLibCode/Commands/PlotTemplateCommands/RicSelectCaseOrEnsembleUi.h new file mode 100644 index 0000000000..bbb77062e6 --- /dev/null +++ b/ApplicationLibCode/Commands/PlotTemplateCommands/RicSelectCaseOrEnsembleUi.h @@ -0,0 +1,56 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2022 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 "cafPdmObject.h" +#include "cafPdmPtrField.h" + +#include +#include +#include + +class RimSummaryCase; +class RimSummaryCaseCollection; + +//================================================================================================== +/// +//================================================================================================== +class RicSelectCaseOrEnsembleUi : public caf::PdmObject +{ + CAF_PDM_HEADER_INIT; + +public: + RicSelectCaseOrEnsembleUi(); + + void setEnsembleSelectionMode( bool selectEnsemble ); + + RimSummaryCase* selectedSummaryCase() const; + RimSummaryCaseCollection* selectedEnsemble() const; + +protected: + void defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ) override; + + QList calculateValueOptions( const caf::PdmFieldHandle* fieldNeedingOptions ) override; + +private: + caf::PdmPtrField m_selectedSummaryCase; + caf::PdmPtrField m_selectedEnsemble; + + bool m_useEnsembleMode; +}; diff --git a/ApplicationLibCode/Commands/PlotTemplateCommands/RicSetAsDefaultTemplateFeature.cpp b/ApplicationLibCode/Commands/PlotTemplateCommands/RicSetAsDefaultTemplateFeature.cpp index 088e03a826..b6a5b5b088 100644 --- a/ApplicationLibCode/Commands/PlotTemplateCommands/RicSetAsDefaultTemplateFeature.cpp +++ b/ApplicationLibCode/Commands/PlotTemplateCommands/RicSetAsDefaultTemplateFeature.cpp @@ -53,6 +53,8 @@ void RicSetAsDefaultTemplateFeature::onActionTriggered( bool isChecked ) RiaPreferencesSummary::current()->addToDefaultPlotTemplates( file->absoluteFilePath() ); else RiaPreferencesSummary::current()->removeFromDefaultPlotTemplates( file->absoluteFilePath() ); + + file->updateIconState(); } //-------------------------------------------------------------------------------------------------- @@ -67,8 +69,7 @@ void RicSetAsDefaultTemplateFeature::setupActionLook( QAction* actionToSetup ) if ( file != nullptr ) { actionToSetup->setCheckable( true ); - actionToSetup->setChecked( - RiaPreferencesSummary::current()->isDefaultSummaryPlotTemplate( file->absoluteFilePath() ) ); + actionToSetup->setChecked( file->isDefaultTemplate() ); } } diff --git a/ApplicationLibCode/Commands/PlotTemplateCommands/RicSummaryPlotTemplateTools.cpp b/ApplicationLibCode/Commands/PlotTemplateCommands/RicSummaryPlotTemplateTools.cpp index c0f0a94685..ea6cab589c 100644 --- a/ApplicationLibCode/Commands/PlotTemplateCommands/RicSummaryPlotTemplateTools.cpp +++ b/ApplicationLibCode/Commands/PlotTemplateCommands/RicSummaryPlotTemplateTools.cpp @@ -444,7 +444,7 @@ QString RicSummaryPlotTemplateTools::selectPlotTemplatePath() { QString fileName = ui.selectedPlotTemplates().front()->absoluteFilePath(); - RiaPreferences::current()->setDefaultPlotTemplatePath( fileName ); + RiaPreferences::current()->setLastUsedPlotTemplatePath( fileName ); RiaPreferences::current()->writePreferencesToApplicationStore(); return fileName; diff --git a/ApplicationLibCode/ProjectDataModel/PlotTemplates/RimPlotTemplateFileItem.cpp b/ApplicationLibCode/ProjectDataModel/PlotTemplates/RimPlotTemplateFileItem.cpp index 6f1d91aa42..78b4bd43ca 100644 --- a/ApplicationLibCode/ProjectDataModel/PlotTemplates/RimPlotTemplateFileItem.cpp +++ b/ApplicationLibCode/ProjectDataModel/PlotTemplates/RimPlotTemplateFileItem.cpp @@ -20,6 +20,7 @@ #include "RiaFieldHandleTools.h" #include "RiaLogging.h" +#include "RiaPreferencesSummary.h" #include "cafPdmField.h" #include "cafPdmUiFilePathEditor.h" @@ -55,6 +56,9 @@ void RimPlotTemplateFileItem::setFilePath( const QString& filePath ) this->uiCapability()->setUiName( fi.baseName() ); m_absoluteFileName = filePath; + + if ( isEnsembleTemplate() ) + this->uiCapability()->setUiIcon( caf::IconProvider( ":/SummaryEnsembleTemplate16x16.png" ) ); } //-------------------------------------------------------------------------------------------------- @@ -64,3 +68,39 @@ QString RimPlotTemplateFileItem::absoluteFilePath() const { return m_absoluteFileName(); } + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimPlotTemplateFileItem::isEnsembleTemplate() const +{ + return m_absoluteFileName().toLower().endsWith( ".erpt" ); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimPlotTemplateFileItem::updateIconState() +{ + caf::IconProvider iconProvider = this->uiIconProvider(); + if ( !iconProvider.valid() ) return; + + if ( isDefaultTemplate() ) + { + iconProvider.setOverlayResourceString( ":/CheckOverlay16x16.png" ); + } + else + { + iconProvider.setOverlayResourceString( "" ); + } + + this->setUiIcon( iconProvider ); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimPlotTemplateFileItem::isDefaultTemplate() const +{ + return RiaPreferencesSummary::current()->isDefaultSummaryPlotTemplate( absoluteFilePath() ); +} diff --git a/ApplicationLibCode/ProjectDataModel/PlotTemplates/RimPlotTemplateFileItem.h b/ApplicationLibCode/ProjectDataModel/PlotTemplates/RimPlotTemplateFileItem.h index 6e5d59e15d..ae84a2af8a 100644 --- a/ApplicationLibCode/ProjectDataModel/PlotTemplates/RimPlotTemplateFileItem.h +++ b/ApplicationLibCode/ProjectDataModel/PlotTemplates/RimPlotTemplateFileItem.h @@ -36,6 +36,12 @@ public: void setFilePath( const QString& filePath ); QString absoluteFilePath() const; + bool isEnsembleTemplate() const; + + bool isDefaultTemplate() const; + + void updateIconState(); + private: caf::PdmField m_absoluteFileName; }; diff --git a/ApplicationLibCode/ProjectDataModel/PlotTemplates/RimPlotTemplateFolderItem.cpp b/ApplicationLibCode/ProjectDataModel/PlotTemplates/RimPlotTemplateFolderItem.cpp index 55dbc92ac6..6dcd38add2 100644 --- a/ApplicationLibCode/ProjectDataModel/PlotTemplates/RimPlotTemplateFolderItem.cpp +++ b/ApplicationLibCode/ProjectDataModel/PlotTemplates/RimPlotTemplateFolderItem.cpp @@ -38,6 +38,7 @@ RimPlotTemplateFolderItem::RimPlotTemplateFolderItem() CAF_PDM_InitObject( "Plot Templates", ":/Folder.png" ); CAF_PDM_InitFieldNoDefault( &m_folderName, "FolderName", "Folder" ); + m_folderName.uiCapability()->setUiReadOnly( true ); CAF_PDM_InitFieldNoDefault( &m_fileNames, "FileNames", "" ); m_fileNames.uiCapability()->setUiTreeHidden( true ); CAF_PDM_InitFieldNoDefault( &m_subFolders, "SubFolders", "" ); @@ -59,7 +60,24 @@ void RimPlotTemplateFolderItem::createRootFolderItemsFromFolderPaths( const QStr m_fileNames.deleteChildren(); m_subFolders.deleteChildren(); - createSubFolderItemsFromFolderPaths( folderPaths ); + createSubFolderItemsFromFolderPaths( folderPaths, RiaPreferences::current()->maxPlotTemplateFoldersDepth() ); + updateIconState(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimPlotTemplateFolderItem::updateIconState() const +{ + for ( auto& folder : m_subFolders() ) + { + folder->updateIconState(); + } + + for ( auto& item : m_fileNames() ) + { + item->updateIconState(); + } } //-------------------------------------------------------------------------------------------------- @@ -101,16 +119,19 @@ void RimPlotTemplateFolderItem::setFolderPath( const QString& path ) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RimPlotTemplateFolderItem::searchForFileAndFolderNames() +void RimPlotTemplateFolderItem::searchForFileAndFolderNames( int levelsLeft ) { m_fileNames.deleteChildren(); m_subFolders.deleteChildren(); + levelsLeft--; + if ( levelsLeft < 0 ) return; + if ( m_folderName().path().isEmpty() ) { for ( size_t i = 0; i < m_subFolders.size(); ++i ) { - if ( m_subFolders[i] ) m_subFolders[i]->searchForFileAndFolderNames(); + if ( m_subFolders[i] ) m_subFolders[i]->searchForFileAndFolderNames( levelsLeft ); } return; } @@ -121,10 +142,11 @@ void RimPlotTemplateFolderItem::searchForFileAndFolderNames() return; } - // Build a list of all scripts in the specified directory + // Build a list of all templates in the specified directory { QStringList nameFilters; nameFilters << "*.rpt"; + nameFilters << "*.erpt"; QStringList fileList = caf::Utils::getFilesInDirectory( m_folderName().path(), nameFilters, true ); for ( int i = 0; i < fileList.size(); i++ ) @@ -140,7 +162,7 @@ void RimPlotTemplateFolderItem::searchForFileAndFolderNames() } } - if ( searchSubFoldersRecursively() ) + if ( levelsLeft > 0 ) { QStringList folderPaths; @@ -152,23 +174,7 @@ void RimPlotTemplateFolderItem::searchForFileAndFolderNames() folderPaths.push_back( fi.absoluteFilePath() ); } - createSubFolderItemsFromFolderPaths( folderPaths ); - } -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RimPlotTemplateFolderItem::fieldChangedByUi( const caf::PdmFieldHandle* changedField, - const QVariant& oldValue, - const QVariant& newValue ) -{ - if ( &m_folderName == changedField ) - { - QFileInfo fi( m_folderName().path() ); - this->setUiName( fi.baseName() ); - - this->searchForFileAndFolderNames(); + createSubFolderItemsFromFolderPaths( folderPaths, levelsLeft ); } } @@ -189,6 +195,19 @@ void RimPlotTemplateFolderItem::defineEditorAttribute( const caf::PdmFieldHandle } } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimPlotTemplateFolderItem::defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ) +{ + if ( !m_folderName().path().isEmpty() ) + { + uiOrdering.add( &m_folderName ); + } + + uiOrdering.skipRemainingFields( true ); +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -209,11 +228,15 @@ void RimPlotTemplateFolderItem::appendOptionItemsForPlotTemplatesRecursively( QL } caf::IconProvider templateIcon( ":/SummaryTemplate16x16.png" ); + caf::IconProvider ensTemplateIcon( ":/SummaryEnsembleTemplate16x16.png" ); auto files = templateFolderItem->fileNames(); for ( auto file : files ) { - caf::PdmOptionItemInfo optionInfo( file->uiName(), file, false, templateIcon ); + caf::IconProvider icon = templateIcon; + if ( file->isEnsembleTemplate() ) icon = ensTemplateIcon; + + caf::PdmOptionItemInfo optionInfo( file->uiName(), file, false, icon ); optionInfo.setLevel( menuLevel ); @@ -224,22 +247,14 @@ void RimPlotTemplateFolderItem::appendOptionItemsForPlotTemplatesRecursively( QL //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RimPlotTemplateFolderItem::createSubFolderItemsFromFolderPaths( const QStringList& folderPaths ) +void RimPlotTemplateFolderItem::createSubFolderItemsFromFolderPaths( const QStringList& folderPaths, int levelsLeft ) { for ( const auto& path : folderPaths ) { - RimPlotTemplateFolderItem* scriptLocation = new RimPlotTemplateFolderItem(); - scriptLocation->setFolderPath( path ); - scriptLocation->searchForFileAndFolderNames(); + RimPlotTemplateFolderItem* templateLocation = new RimPlotTemplateFolderItem(); + templateLocation->setFolderPath( path ); + templateLocation->searchForFileAndFolderNames( levelsLeft ); - m_subFolders.push_back( scriptLocation ); + m_subFolders.push_back( templateLocation ); } } - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -bool RimPlotTemplateFolderItem::searchSubFoldersRecursively() const -{ - return RiaPreferences::current()->searchPlotTemplateFoldersRecursively(); -} diff --git a/ApplicationLibCode/ProjectDataModel/PlotTemplates/RimPlotTemplateFolderItem.h b/ApplicationLibCode/ProjectDataModel/PlotTemplates/RimPlotTemplateFolderItem.h index 069685bf92..35a61283ef 100644 --- a/ApplicationLibCode/ProjectDataModel/PlotTemplates/RimPlotTemplateFolderItem.h +++ b/ApplicationLibCode/ProjectDataModel/PlotTemplates/RimPlotTemplateFolderItem.h @@ -48,18 +48,17 @@ public: static void appendOptionItemsForPlotTemplates( QList& options, RimPlotTemplateFolderItem* templateFolderItem ); + void updateIconState() const; private: - void searchForFileAndFolderNames(); + void searchForFileAndFolderNames( int levelsLeft ); void setFolderPath( const QString& path ); - void createSubFolderItemsFromFolderPaths( const QStringList& folderPaths ); + void createSubFolderItemsFromFolderPaths( const QStringList& folderPaths, int levelsLeft ); - bool searchSubFoldersRecursively() const; - - void fieldChangedByUi( const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue ) override; void defineEditorAttribute( const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute* attribute ) override; + void defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ) override; static void appendOptionItemsForPlotTemplatesRecursively( QList& options, RimPlotTemplateFolderItem* templateFolderItem, diff --git a/ApplicationLibCode/ProjectDataModel/RimContextCommandBuilder.cpp b/ApplicationLibCode/ProjectDataModel/RimContextCommandBuilder.cpp index c7773f1b0d..f66795d28a 100644 --- a/ApplicationLibCode/ProjectDataModel/RimContextCommandBuilder.cpp +++ b/ApplicationLibCode/ProjectDataModel/RimContextCommandBuilder.cpp @@ -1024,6 +1024,8 @@ caf::CmdFeatureMenuBuilder RimContextCommandBuilder::commandsFromSelection() else if ( dynamic_cast( firstUiItem ) || dynamic_cast( firstUiItem ) ) { + menuBuilder << "RicCreateNewPlotFromTemplateFeature"; + menuBuilder << "Separator"; menuBuilder << "RicRenamePlotTemplateFeature"; menuBuilder << "RicDeletePlotTemplateFeature"; menuBuilder << "RicEditPlotTemplateFeature";