From f2ac170b66f7a693229a4ba21539e35abeaa5d99 Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Thu, 19 Sep 2019 11:39:32 +0200 Subject: [PATCH 1/2] #4733 Summary Template : Add reload of templates Adjust save and load of templates Add save path to preferences --- .../Application/RiaPreferences.cpp | 16 ++ ApplicationCode/Application/RiaPreferences.h | 1 + .../CMakeLists_files.cmake | 4 + .../RicCreatePlotFromSelectionFeature.cpp | 167 +++++------------- .../RicCreatePlotFromSelectionFeature.h | 9 - .../RicReloadPlotTemplatesFeature.cpp | 66 +++++++ .../RicReloadPlotTemplatesFeature.h | 39 ++++ .../RicSavePlotTemplateFeature.cpp | 119 ++++++++++--- .../RicSavePlotTemplateFeature.h | 6 +- .../RicSelectPlotTemplateUi.cpp | 17 ++ .../RicSelectPlotTemplateUi.h | 4 + .../RicSummaryPlotTemplateTools.cpp | 158 +++++++++++++++++ .../RicSummaryPlotTemplateTools.h | 47 +++++ .../RimPlotTemplateFolderItem.cpp | 3 + .../RimContextCommandBuilder.cpp | 30 ++-- .../ProjectDataModel/RimDialogData.cpp | 12 ++ .../ProjectDataModel/RimDialogData.h | 4 + .../ProjectDataModel/RimProject.cpp | 6 +- .../UserInterface/RiuSummaryQwtPlot.cpp | 1 + 19 files changed, 535 insertions(+), 174 deletions(-) create mode 100644 ApplicationCode/Commands/PlotTemplateCommands/RicReloadPlotTemplatesFeature.cpp create mode 100644 ApplicationCode/Commands/PlotTemplateCommands/RicReloadPlotTemplatesFeature.h create mode 100644 ApplicationCode/Commands/PlotTemplateCommands/RicSummaryPlotTemplateTools.cpp create mode 100644 ApplicationCode/Commands/PlotTemplateCommands/RicSummaryPlotTemplateTools.h diff --git a/ApplicationCode/Application/RiaPreferences.cpp b/ApplicationCode/Application/RiaPreferences.cpp index a225c49df5..de20493978 100644 --- a/ApplicationCode/Application/RiaPreferences.cpp +++ b/ApplicationCode/Application/RiaPreferences.cpp @@ -716,6 +716,22 @@ QStringList RiaPreferences::plotTemplateFolders() const return filteredFolders; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiaPreferences::appendPlotTemplateFolders( const QString& folder ) +{ + QString folders = m_plotTemplateFolders(); + if ( !folders.isEmpty() ) + { + folders += ";"; + } + + folders += folder; + + m_plotTemplateFolders = folders; +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/Application/RiaPreferences.h b/ApplicationCode/Application/RiaPreferences.h index e0509f8aae..c5e5fb3da0 100644 --- a/ApplicationCode/Application/RiaPreferences.h +++ b/ApplicationCode/Application/RiaPreferences.h @@ -81,6 +81,7 @@ public: bool searchPlotTemplateFoldersRecursively() const; QStringList plotTemplateFolders() const; + void appendPlotTemplateFolders( const QString& folder ); std::map defaultFontSizes() const; diff --git a/ApplicationCode/Commands/PlotTemplateCommands/CMakeLists_files.cmake b/ApplicationCode/Commands/PlotTemplateCommands/CMakeLists_files.cmake index aab93f53af..9bb7dc6b79 100644 --- a/ApplicationCode/Commands/PlotTemplateCommands/CMakeLists_files.cmake +++ b/ApplicationCode/Commands/PlotTemplateCommands/CMakeLists_files.cmake @@ -3,12 +3,16 @@ set (SOURCE_GROUP_HEADER_FILES ${CMAKE_CURRENT_LIST_DIR}/RicSavePlotTemplateFeature.h ${CMAKE_CURRENT_LIST_DIR}/RicCreatePlotFromSelectionFeature.h ${CMAKE_CURRENT_LIST_DIR}/RicSelectPlotTemplateUi.h +${CMAKE_CURRENT_LIST_DIR}/RicSummaryPlotTemplateTools.h +${CMAKE_CURRENT_LIST_DIR}/RicReloadPlotTemplatesFeature.h ) set (SOURCE_GROUP_SOURCE_FILES ${CMAKE_CURRENT_LIST_DIR}/RicSavePlotTemplateFeature.cpp ${CMAKE_CURRENT_LIST_DIR}/RicCreatePlotFromSelectionFeature.cpp ${CMAKE_CURRENT_LIST_DIR}/RicSelectPlotTemplateUi.cpp +${CMAKE_CURRENT_LIST_DIR}/RicSummaryPlotTemplateTools.cpp +${CMAKE_CURRENT_LIST_DIR}/RicReloadPlotTemplatesFeature.cpp ) list(APPEND CODE_HEADER_FILES diff --git a/ApplicationCode/Commands/PlotTemplateCommands/RicCreatePlotFromSelectionFeature.cpp b/ApplicationCode/Commands/PlotTemplateCommands/RicCreatePlotFromSelectionFeature.cpp index 6b68d47b55..69595bf9b7 100644 --- a/ApplicationCode/Commands/PlotTemplateCommands/RicCreatePlotFromSelectionFeature.cpp +++ b/ApplicationCode/Commands/PlotTemplateCommands/RicCreatePlotFromSelectionFeature.cpp @@ -18,13 +18,15 @@ #include "RicCreatePlotFromSelectionFeature.h" +#include "RicSelectPlotTemplateUi.h" +#include "RicSummaryPlotTemplateTools.h" + #include "RiaGuiApplication.h" #include "RiaLogging.h" #include "RiaSummaryTools.h" -#include "RicSelectPlotTemplateUi.h" - #include "PlotTemplates/RimPlotTemplateFileItem.h" +#include "RimDialogData.h" #include "RimMainPlotCollection.h" #include "RimProject.h" #include "RimSummaryCase.h" @@ -44,20 +46,12 @@ CAF_CMD_SOURCE_INIT( RicCreatePlotFromSelectionFeature, "RicCreatePlotFromSelectionFeature" ); -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -RicCreatePlotFromSelectionFeature::RicCreatePlotFromSelectionFeature() {} - //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- bool RicCreatePlotFromSelectionFeature::isCommandEnabled() { - if ( selectedSummaryCases().size() == 2 ) return true; - if ( selectedWellPaths().size() == 2 ) return true; - - return false; + return !selectedSummaryCases().empty(); } //-------------------------------------------------------------------------------------------------- @@ -65,95 +59,59 @@ bool RicCreatePlotFromSelectionFeature::isCommandEnabled() //-------------------------------------------------------------------------------------------------- void RicCreatePlotFromSelectionFeature::onActionTriggered( bool isChecked ) { + RiuPlotMainWindow* plotwindow = RiaGuiApplication::instance()->mainPlotWindow(); + + RicSelectPlotTemplateUi* ui = RiaGuiApplication::instance()->project()->dialogData()->selectPlotTemplateUi(); + + caf::PdmUiPropertyViewDialog propertyDialog( plotwindow, ui, "Select Plot Template", "" ); + + if ( propertyDialog.exec() != QDialog::Accepted ) return; + + if ( ui->selectedPlotTemplates().empty() ) return; + + QString fileName = ui->selectedPlotTemplates().front()->absoluteFilePath(); + std::vector sumCases = selectedSummaryCases(); + + RimSummaryPlot* newSummaryPlot = RicSummaryPlotTemplateTools::createPlotFromTemplateFile( fileName ); + if ( newSummaryPlot ) { - RiuPlotMainWindow* plotwindow = RiaGuiApplication::instance()->mainPlotWindow(); + RimSummaryPlotCollection* plotColl = + RiaApplication::instance()->project()->mainPlotCollection()->summaryPlotCollection(); - RicSelectPlotTemplateUi ui; + plotColl->summaryPlots.push_back( newSummaryPlot ); + newSummaryPlot->resolveReferencesRecursively(); + newSummaryPlot->initAfterReadRecursively(); - caf::PdmUiPropertyViewDialog propertyDialog( plotwindow, - &ui, - "Select Case to create Pressure Saturation plots", - "" ); + QString nameOfCopy = QString( "Copy of " ) + newSummaryPlot->description(); + newSummaryPlot->setDescription( nameOfCopy ); - if ( propertyDialog.exec() != QDialog::Accepted ) return; + auto summaryCurves = newSummaryPlot->summaryCurves(); - if ( ui.selectedPlotTemplates().empty() ) return; - - QString fileName = ui.selectedPlotTemplates().front()->absoluteFilePath(); + for ( const auto& curve : summaryCurves ) { - auto sumCases = selectedSummaryCases(); - if ( sumCases.size() == 2 ) + auto fieldHandle = curve->findField( "SummaryCase" ); + if ( fieldHandle ) { - // QString fileName = "d:/projects/ri-plot-templates/one_well_two_cases.rpt"; - - RimSummaryPlot* newSummaryPlot = createPlotFromTemplateFile( fileName ); - if ( newSummaryPlot ) + auto referenceString = fieldHandle->xmlCapability()->referenceString(); + auto stringList = referenceString.split( " " ); + if ( stringList.size() == 2 ) { - RimSummaryPlotCollection* plotColl = - RiaApplication::instance()->project()->mainPlotCollection()->summaryPlotCollection(); + QString indexAsString = stringList[1]; - plotColl->summaryPlots.push_back( newSummaryPlot ); + bool conversionOk = false; + int index = indexAsString.toUInt( &conversionOk ); - // Resolve references after object has been inserted into the data model - newSummaryPlot->resolveReferencesRecursively(); - newSummaryPlot->initAfterReadRecursively(); - - QString nameOfCopy = QString( "Copy of " ) + newSummaryPlot->description(); - newSummaryPlot->setDescription( nameOfCopy ); - - auto summaryCurves = newSummaryPlot->summaryCurves(); - if ( summaryCurves.size() == sumCases.size() ) + if ( conversionOk && index < sumCases.size() ) { - for ( size_t i = 0; i < summaryCurves.size(); i++ ) - { - auto sumCase = sumCases[i]; - summaryCurves[i]->setSummaryCaseY( sumCase ); - } + curve->setSummaryCaseY( sumCases[index] ); } - - plotColl->updateConnectedEditors(); - - newSummaryPlot->loadDataAndUpdate(); } } } - { - auto wellPaths = selectedWellPaths(); - if ( wellPaths.size() == 2 ) - { - // QString fileName = "d:/projects/ri-plot-templates/one_well_two_cases.rpt"; - RimSummaryPlot* newSummaryPlot = createPlotFromTemplateFile( fileName ); - if ( newSummaryPlot ) - { - RimSummaryPlotCollection* plotColl = RiaSummaryTools::summaryPlotCollection(); + plotColl->updateConnectedEditors(); - plotColl->summaryPlots.push_back( newSummaryPlot ); - - // Resolve references after object has been inserted into the data model - newSummaryPlot->resolveReferencesRecursively(); - newSummaryPlot->initAfterReadRecursively(); - - QString nameOfCopy = QString( "Copy of " ) + newSummaryPlot->description(); - newSummaryPlot->setDescription( nameOfCopy ); - - auto summaryCurves = newSummaryPlot->summaryCurves(); - if ( summaryCurves.size() == wellPaths.size() ) - { - for ( size_t i = 0; i < summaryCurves.size(); i++ ) - { - auto wellPath = wellPaths[i]; - - summaryCurves[i]->summaryAddressY().setWellName( wellPath->name().toStdString() ); - } - } - - plotColl->updateConnectedEditors(); - - newSummaryPlot->loadDataAndUpdate(); - } - } - } + newSummaryPlot->loadDataAndUpdate(); } } @@ -166,38 +124,6 @@ void RicCreatePlotFromSelectionFeature::setupActionLook( QAction* actionToSetup actionToSetup->setIcon( QIcon( ":/SummaryTemplate16x16.png" ) ); } -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -RimSummaryPlot* RicCreatePlotFromSelectionFeature::createPlotFromTemplateFile( const QString& fileName ) const -{ - QFile importFile( fileName ); - if ( !importFile.open( QIODevice::ReadOnly | QIODevice::Text ) ) - { - RiaLogging::error( QString( "Create Plot from Template : Could not open the file: %1" ).arg( fileName ) ); - return nullptr; - } - - QTextStream stream( &importFile ); - - QString objectAsText = stream.readAll(); - - caf::PdmObjectHandle* obj = - caf::PdmXmlObjectHandle::readUnknownObjectFromXmlString( objectAsText, caf::PdmDefaultObjectFactory::instance() ); - - RimSummaryPlot* newSummaryPlot = dynamic_cast( obj ); - if ( newSummaryPlot ) - { - return newSummaryPlot; - } - else - { - delete obj; - } - - return nullptr; -} - //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -208,14 +134,3 @@ std::vector RicCreatePlotFromSelectionFeature::selectedSummaryC return objects; } - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -std::vector RicCreatePlotFromSelectionFeature::selectedWellPaths() const -{ - std::vector objects; - caf::SelectionManager::instance()->objectsByType( &objects ); - - return objects; -} diff --git a/ApplicationCode/Commands/PlotTemplateCommands/RicCreatePlotFromSelectionFeature.h b/ApplicationCode/Commands/PlotTemplateCommands/RicCreatePlotFromSelectionFeature.h index 8f24620107..65a18dcfef 100644 --- a/ApplicationCode/Commands/PlotTemplateCommands/RicCreatePlotFromSelectionFeature.h +++ b/ApplicationCode/Commands/PlotTemplateCommands/RicCreatePlotFromSelectionFeature.h @@ -21,8 +21,6 @@ #include "cafCmdFeature.h" class RimSummaryCase; -class RimSummaryPlot; -class RimWellPath; //================================================================================================== /// @@ -31,18 +29,11 @@ class RicCreatePlotFromSelectionFeature : public caf::CmdFeature { CAF_CMD_HEADER_INIT; -public: - RicCreatePlotFromSelectionFeature(); - protected: bool isCommandEnabled() override; void onActionTriggered( bool isChecked ) override; void setupActionLook( QAction* actionToSetup ) override; -private: - RimSummaryPlot* createPlotFromTemplateFile( const QString& fileName ) const; - private: std::vector selectedSummaryCases() const; - std::vector selectedWellPaths() const; }; diff --git a/ApplicationCode/Commands/PlotTemplateCommands/RicReloadPlotTemplatesFeature.cpp b/ApplicationCode/Commands/PlotTemplateCommands/RicReloadPlotTemplatesFeature.cpp new file mode 100644 index 0000000000..ad99b39e5e --- /dev/null +++ b/ApplicationCode/Commands/PlotTemplateCommands/RicReloadPlotTemplatesFeature.cpp @@ -0,0 +1,66 @@ +//////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2019- 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 "RicReloadPlotTemplatesFeature.h" + +#include "RiaApplication.h" +#include "RiaPreferences.h" + +#include "PlotTemplates/RimPlotTemplateFolderItem.h" +#include "RimProject.h" + +#include + +CAF_CMD_SOURCE_INIT( RicReloadPlotTemplatesFeature, "RicReloadPlotTemplatesFeature" ); + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicReloadPlotTemplatesFeature::rebuildFromDisc() +{ + RimProject* proj = RiaApplication::instance()->project(); + RiaPreferences* prefs = RiaApplication::instance()->preferences(); + + proj->setPlotTemplateFolders( prefs->plotTemplateFolders() ); + proj->rootPlotTemlateItem()->updateConnectedEditors(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RicReloadPlotTemplatesFeature::isCommandEnabled() +{ + return true; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicReloadPlotTemplatesFeature::onActionTriggered( bool isChecked ) +{ + RicReloadPlotTemplatesFeature::rebuildFromDisc(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicReloadPlotTemplatesFeature::setupActionLook( QAction* actionToSetup ) +{ + actionToSetup->setText( "Reload Templates" ); + actionToSetup->setIcon( QIcon( ":/SummaryTemplate16x16.png" ) ); +} diff --git a/ApplicationCode/Commands/PlotTemplateCommands/RicReloadPlotTemplatesFeature.h b/ApplicationCode/Commands/PlotTemplateCommands/RicReloadPlotTemplatesFeature.h new file mode 100644 index 0000000000..c5c298de2d --- /dev/null +++ b/ApplicationCode/Commands/PlotTemplateCommands/RicReloadPlotTemplatesFeature.h @@ -0,0 +1,39 @@ +//////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2019- 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 RimSummaryPlot; + +//================================================================================================== +/// +//================================================================================================== +class RicReloadPlotTemplatesFeature : public caf::CmdFeature +{ + CAF_CMD_HEADER_INIT; + +public: + static void rebuildFromDisc(); + +protected: + bool isCommandEnabled() override; + void onActionTriggered( bool isChecked ) override; + void setupActionLook( QAction* actionToSetup ) override; +}; diff --git a/ApplicationCode/Commands/PlotTemplateCommands/RicSavePlotTemplateFeature.cpp b/ApplicationCode/Commands/PlotTemplateCommands/RicSavePlotTemplateFeature.cpp index 09784e28fb..7e3f28de66 100644 --- a/ApplicationCode/Commands/PlotTemplateCommands/RicSavePlotTemplateFeature.cpp +++ b/ApplicationCode/Commands/PlotTemplateCommands/RicSavePlotTemplateFeature.cpp @@ -16,28 +16,29 @@ // ///////////////////////////////////////////////////////////////////////////////// -#include "RiaGuiApplication.h" -#include "RiaLogging.h" -#include "RiaSummaryTools.h" - #include "RicSavePlotTemplateFeature.h" +#include "RicReloadPlotTemplatesFeature.h" + +#include "RiaGuiApplication.h" +#include "RiaLogging.h" +#include "RiaPreferences.h" +#include "RiaSummaryTools.h" + #include "RimProject.h" +#include "RimSummaryCurve.h" #include "RimSummaryPlot.h" #include "cafPdmObject.h" #include "cafSelectionManager.h" +#include "cafUtils.h" #include #include +#include CAF_CMD_SOURCE_INIT( RicSavePlotTemplateFeature, "RicSavePlotTemplateFeature" ); -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -RicSavePlotTemplateFeature::RicSavePlotTemplateFeature() {} - //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -53,28 +54,30 @@ bool RicSavePlotTemplateFeature::isCommandEnabled() //-------------------------------------------------------------------------------------------------- void RicSavePlotTemplateFeature::onActionTriggered( bool isChecked ) { + if ( !selectedSummaryPlot() ) return; + RiaGuiApplication* app = RiaGuiApplication::instance(); - QString startPath; - if ( !app->project()->fileName().isEmpty() ) + QString fallbackPath; + auto folders = app->preferences()->plotTemplateFolders(); + if ( !folders.empty() ) { - startPath = app->project()->fileName(); - startPath = startPath.replace( QString( ".rsp" ), QString( ".rpt" ) ); - } - else - { - startPath = app->lastUsedDialogDirectory( "PLOT_TEMPLATE" ); - startPath += "/ri-plot-template.rpt"; + // Use the last folder from preferences as the default fall back folder + fallbackPath = folders.back(); } + QString startPath = app->lastUsedDialogDirectoryWithFallback( "PLOT_TEMPLATE", fallbackPath ); + + QString templateCandidateName = caf::Utils::makeValidFileBasename( selectedSummaryPlot()->description() ); + + startPath = startPath + "/" + templateCandidateName + ".rpt"; + QString fileName = QFileDialog::getSaveFileName( nullptr, tr( "Save Plot Template To File" ), startPath, tr( "Plot Template Files (*.rpt);;All files(*.*)" ) ); if ( !fileName.isEmpty() ) { - auto objectAsText = selectedSummaryPlot()->writeObjectToXmlString(); - QFile exportFile( fileName ); if ( !exportFile.open( QIODevice::WriteOnly | QIODevice::Text ) ) { @@ -82,11 +85,87 @@ void RicSavePlotTemplateFeature::onActionTriggered( bool isChecked ) return; } + QString objectAsText = createTextFromObject( selectedSummaryPlot() ); + QTextStream stream( &exportFile ); stream << objectAsText; + + QString absPath = QFileInfo( fileName ).absolutePath(); + bool foundPathInPreferences = false; + for ( const auto& f : folders ) + { + if ( absPath.indexOf( f ) != -1 ) + { + foundPathInPreferences = true; + } + } + + if ( !foundPathInPreferences ) + { + QMessageBox msgBox; + msgBox.setIcon( QMessageBox::Question ); + + QString questionText; + questionText = QString( "The path is not part of the search path for templates.\n\nDo you want to append " + "the destination path to the search path?" ); + + msgBox.setText( questionText ); + msgBox.setStandardButtons( QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel ); + + int ret = msgBox.exec(); + if ( ret == QMessageBox::Yes ) + { + app->preferences()->appendPlotTemplateFolders( absPath ); + } + } + + app->setLastUsedDialogDirectory( "PLOT_TEMPLATE", absPath ); + + RicReloadPlotTemplatesFeature::rebuildFromDisc(); } } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RicSavePlotTemplateFeature::createTextFromObject( RimSummaryPlot* summaryPlot ) +{ + if ( !summaryPlot ) return QString(); + + QString objectAsText = summaryPlot->writeObjectToXmlString(); + + caf::PdmObjectHandle* obj = + caf::PdmXmlObjectHandle::readUnknownObjectFromXmlString( objectAsText, caf::PdmDefaultObjectFactory::instance() ); + + RimSummaryPlot* newSummaryPlot = dynamic_cast( obj ); + if ( newSummaryPlot ) + { + std::set caseReferenceStrings; + + for ( const auto& curve : newSummaryPlot->summaryCurves() ) + { + auto fieldHandle = curve->findField( "SummaryCase" ); + if ( fieldHandle ) + { + auto reference = fieldHandle->xmlCapability()->referenceString(); + caseReferenceStrings.insert( reference ); + } + } + + size_t index = 0; + for ( const auto& s : caseReferenceStrings ) + { + QString caseName = QString( "CASE_NAME %1" ).arg( index++ ); + + objectAsText.replace( s, caseName ); + } + } + + delete obj; + + return objectAsText; +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/Commands/PlotTemplateCommands/RicSavePlotTemplateFeature.h b/ApplicationCode/Commands/PlotTemplateCommands/RicSavePlotTemplateFeature.h index 293df505d1..35839b4b57 100644 --- a/ApplicationCode/Commands/PlotTemplateCommands/RicSavePlotTemplateFeature.h +++ b/ApplicationCode/Commands/PlotTemplateCommands/RicSavePlotTemplateFeature.h @@ -29,14 +29,14 @@ class RicSavePlotTemplateFeature : public caf::CmdFeature { CAF_CMD_HEADER_INIT; -public: - RicSavePlotTemplateFeature(); - protected: bool isCommandEnabled() override; void onActionTriggered( bool isChecked ) override; void setupActionLook( QAction* actionToSetup ) override; +private: + static QString createTextFromObject( RimSummaryPlot* summaryPlot ); + private: RimSummaryPlot* selectedSummaryPlot() const; }; diff --git a/ApplicationCode/Commands/PlotTemplateCommands/RicSelectPlotTemplateUi.cpp b/ApplicationCode/Commands/PlotTemplateCommands/RicSelectPlotTemplateUi.cpp index 2f062a4fcb..46e9b453fe 100644 --- a/ApplicationCode/Commands/PlotTemplateCommands/RicSelectPlotTemplateUi.cpp +++ b/ApplicationCode/Commands/PlotTemplateCommands/RicSelectPlotTemplateUi.cpp @@ -78,3 +78,20 @@ QList return options; } + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicSelectPlotTemplateUi::defineEditorAttribute( const caf::PdmFieldHandle* field, + QString uiConfigName, + caf::PdmUiEditorAttribute* attribute ) +{ + if ( &m_selectedPlotTemplates == field ) + { + auto a = dynamic_cast( attribute ); + if ( a ) + { + a->singleSelectionMode = true; + } + } +} diff --git a/ApplicationCode/Commands/PlotTemplateCommands/RicSelectPlotTemplateUi.h b/ApplicationCode/Commands/PlotTemplateCommands/RicSelectPlotTemplateUi.h index 86e9487c65..c8ae4a1663 100644 --- a/ApplicationCode/Commands/PlotTemplateCommands/RicSelectPlotTemplateUi.h +++ b/ApplicationCode/Commands/PlotTemplateCommands/RicSelectPlotTemplateUi.h @@ -41,6 +41,10 @@ private: QList calculateValueOptions( const caf::PdmFieldHandle* fieldNeedingOptions, bool* useOptionsOnly ) override; + void defineEditorAttribute( const caf::PdmFieldHandle* field, + QString uiConfigName, + caf::PdmUiEditorAttribute* attribute ) override; + private: caf::PdmPtrArrayField m_selectedPlotTemplates; }; diff --git a/ApplicationCode/Commands/PlotTemplateCommands/RicSummaryPlotTemplateTools.cpp b/ApplicationCode/Commands/PlotTemplateCommands/RicSummaryPlotTemplateTools.cpp new file mode 100644 index 0000000000..b8fd3a59c9 --- /dev/null +++ b/ApplicationCode/Commands/PlotTemplateCommands/RicSummaryPlotTemplateTools.cpp @@ -0,0 +1,158 @@ +//////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2019- 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 "RicSummaryPlotTemplateTools.h" + +#include "RiaLogging.h" +#include "RiaSummaryCurveAnalyzer.h" + +#include "RimSummaryCurve.h" +#include "RimSummaryPlot.h" + +#include + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimSummaryPlot* RicSummaryPlotTemplateTools::createPlotFromTemplateFile( const QString& fileName ) +{ + QFile importFile( fileName ); + if ( !importFile.open( QIODevice::ReadOnly | QIODevice::Text ) ) + { + RiaLogging::error( QString( "Create Plot from Template : Could not open the file: %1" ).arg( fileName ) ); + return nullptr; + } + + QTextStream stream( &importFile ); + + QString objectAsText = stream.readAll(); + + caf::PdmObjectHandle* obj = + caf::PdmXmlObjectHandle::readUnknownObjectFromXmlString( objectAsText, caf::PdmDefaultObjectFactory::instance() ); + + RimSummaryPlot* newSummaryPlot = dynamic_cast( obj ); + if ( newSummaryPlot ) + { + return newSummaryPlot; + } + + delete obj; + + return nullptr; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RicSummaryPlotTemplateTools::htmlTextFromPlotAndSelection( + const RimSummaryPlot* templatePlot, + const std::set& selectedSummaryAddresses, + const std::vector& selectedSources ) +{ + QString text; + + RiaSummaryCurveAnalyzer selectionAnalyzer; + + selectionAnalyzer.appendAdresses( selectedSummaryAddresses ); + + if ( templatePlot ) + { + std::set templateSources; + RiaSummaryCurveAnalyzer templateAnalyzer; + + { + std::set templateAddresses; + + for ( const auto& curve : templatePlot->summaryCurves() ) + { + auto adr = curve->summaryAddressY(); + templateAddresses.insert( adr ); + + auto fieldHandle = curve->findField( "SummaryCase" ); + if ( fieldHandle ) + { + auto test = fieldHandle->xmlCapability()->referenceString(); + templateSources.insert( test ); + } + } + + templateAnalyzer.appendAdresses( templateAddresses ); + } + + text += " Requirements
"; + + if ( !templateSources.empty() ) + { + QString itemText = "Source Cases"; + size_t requiredCount = templateSources.size(); + size_t selectedCount = selectedSources.size(); + text += htmlTextFromCount( itemText, requiredCount, selectedCount ); + } + + if ( !templateAnalyzer.wellNames().empty() ) + { + QString itemText = "Wells"; + size_t requiredCount = templateAnalyzer.wellNames().size(); + size_t selectedCount = selectionAnalyzer.wellNames().size(); + text += htmlTextFromCount( itemText, requiredCount, selectedCount ); + } + + if ( !templateAnalyzer.wellGroupNames().empty() ) + { + QString itemText = "Well Groups"; + size_t requiredCount = templateAnalyzer.wellGroupNames().size(); + size_t selectedCount = selectionAnalyzer.wellGroupNames().size(); + text += htmlTextFromCount( itemText, requiredCount, selectedCount ); + } + + if ( !templateAnalyzer.regionNumbers().empty() ) + { + QString itemText = "Regions"; + size_t requiredCount = templateAnalyzer.regionNumbers().size(); + size_t selectedCount = selectionAnalyzer.regionNumbers().size(); + text += htmlTextFromCount( itemText, requiredCount, selectedCount ); + } + } + + return text; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RicSummaryPlotTemplateTools::htmlTextFromCount( const QString& itemText, + size_t requiredItemCount, + size_t selectionCount ) +{ + QString text; + + QString colorString = "green"; + + if ( selectionCount < requiredItemCount ) + colorString = "red"; + else if ( selectionCount > requiredItemCount ) + colorString = "orange"; + + text += QString( "" ).arg( colorString ); + text += QString( "%1 : %2 selected (%3 required)\n" ).arg( itemText ).arg( selectionCount ).arg( requiredItemCount ); + text += ""; + + text += "
"; + + return text; +} diff --git a/ApplicationCode/Commands/PlotTemplateCommands/RicSummaryPlotTemplateTools.h b/ApplicationCode/Commands/PlotTemplateCommands/RicSummaryPlotTemplateTools.h new file mode 100644 index 0000000000..9b6df007ec --- /dev/null +++ b/ApplicationCode/Commands/PlotTemplateCommands/RicSummaryPlotTemplateTools.h @@ -0,0 +1,47 @@ +//////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2019- 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 PdmObject; +} + +class RimSummaryPlot; +class RimSummaryPlot; +class RifEclipseSummaryAddress; + +//================================================================================================== +/// +//================================================================================================== +class RicSummaryPlotTemplateTools +{ +public: + static RimSummaryPlot* createPlotFromTemplateFile( const QString& fileName ); + static QString htmlTextFromPlotAndSelection( const RimSummaryPlot* templatePlot, + const std::set& selectedSummaryAddresses, + const std::vector& selectedSources ); + + static QString htmlTextFromCount( const QString& itemText, size_t requiredItemCount, size_t selectionCount ); +}; diff --git a/ApplicationCode/ProjectDataModel/PlotTemplates/RimPlotTemplateFolderItem.cpp b/ApplicationCode/ProjectDataModel/PlotTemplates/RimPlotTemplateFolderItem.cpp index 2e83ed6338..862a48e9fc 100644 --- a/ApplicationCode/ProjectDataModel/PlotTemplates/RimPlotTemplateFolderItem.cpp +++ b/ApplicationCode/ProjectDataModel/PlotTemplates/RimPlotTemplateFolderItem.cpp @@ -55,6 +55,9 @@ RimPlotTemplateFolderItem::~RimPlotTemplateFolderItem() {} //-------------------------------------------------------------------------------------------------- void RimPlotTemplateFolderItem::createRootFolderItemsFromFolderPaths( const QStringList& folderPaths ) { + m_fileNames.deleteAllChildObjects(); + m_subFolders.deleteAllChildObjects(); + createSubFolderItemsFromFolderPaths( folderPaths ); } diff --git a/ApplicationCode/ProjectDataModel/RimContextCommandBuilder.cpp b/ApplicationCode/ProjectDataModel/RimContextCommandBuilder.cpp index 786ecfc5be..2b65d88cd3 100644 --- a/ApplicationCode/ProjectDataModel/RimContextCommandBuilder.cpp +++ b/ApplicationCode/ProjectDataModel/RimContextCommandBuilder.cpp @@ -21,6 +21,8 @@ #include "RiaApplication.h" +#include "PlotTemplates/RimPlotTemplateFileItem.h" +#include "PlotTemplates/RimPlotTemplateFolderItem.h" #include "Rim3dOverlayInfoConfig.h" #include "Rim3dWellLogCurveCollection.h" #include "Rim3dWellLogExtractionCurve.h" @@ -43,6 +45,7 @@ #include "RimEclipsePropertyFilterCollection.h" #include "RimEclipseStatisticsCase.h" #include "RimEclipseView.h" +#include "RimEllipseFractureTemplate.h" #include "RimEnsembleCurveFilterCollection.h" #include "RimEnsembleCurveSet.h" #include "RimEnsembleCurveSetCollection.h" @@ -55,6 +58,8 @@ #include "RimFlowPlotCollection.h" #include "RimFormationNames.h" #include "RimFormationNamesCollection.h" +#include "RimFractureTemplate.h" +#include "RimFractureTemplateCollection.h" #include "RimGeoMechCase.h" #include "RimGeoMechContourMapViewCollection.h" #include "RimGeoMechPropertyFilter.h" @@ -68,6 +73,7 @@ #include "RimIntersection.h" #include "RimIntersectionBox.h" #include "RimIntersectionCollection.h" +#include "RimModeledWellPath.h" #include "RimObservedSummaryData.h" #include "RimPerforationCollection.h" #include "RimPerforationInterval.h" @@ -76,8 +82,10 @@ #include "RimRftPlotCollection.h" #include "RimSaturationPressurePlotCollection.h" #include "RimScriptCollection.h" +#include "RimSimWellFracture.h" #include "RimSimWellInView.h" #include "RimSimWellInViewCollection.h" +#include "RimStimPlanFractureTemplate.h" #include "RimSummaryCase.h" #include "RimSummaryCaseCollection.h" #include "RimSummaryCaseMainCollection.h" @@ -87,6 +95,8 @@ #include "RimSummaryCurveCollection.h" #include "RimSummaryPlot.h" #include "RimSummaryPlotCollection.h" +#include "RimValveTemplate.h" +#include "RimValveTemplateCollection.h" #include "RimViewController.h" #include "RimViewLinker.h" #include "RimViewLinkerCollection.h" @@ -101,21 +111,11 @@ #include "RimWellPathAttributeCollection.h" #include "RimWellPathCollection.h" #include "RimWellPathCompletions.h" +#include "RimWellPathFracture.h" #include "RimWellPathFractureCollection.h" #include "RimWellPltPlot.h" #include "RimWellRftPlot.h" -#include "RimEllipseFractureTemplate.h" -#include "RimFractureTemplate.h" -#include "RimFractureTemplateCollection.h" -#include "RimModeledWellPath.h" -#include "RimSimWellFracture.h" -#include "RimStimPlanFractureTemplate.h" -#include "RimValveTemplate.h" -#include "RimValveTemplateCollection.h" -#include "RimWellPathFracture.h" -#include "RimWellPathFractureCollection.h" - #include "RiuMainWindow.h" #include "OctaveScriptCommands/RicExecuteScriptForCasesFeature.h" @@ -548,14 +548,12 @@ caf::CmdFeatureMenuBuilder RimContextCommandBuilder::commandsFromSelection() menuBuilder << "RicDuplicateSummaryCrossPlotFeature"; menuBuilder << "RicNewSummaryCrossPlotCurveFeature"; menuBuilder << "Separator"; - menuBuilder << "RicShowSummaryCurveCalculatorFeature"; - menuBuilder << "Separator"; menuBuilder << "RicSavePlotTemplateFeature"; - menuBuilder << "Separator"; // Export is not supported for cross plot if ( !summaryCrossPlot ) menuBuilder << "RicAsciiExportSummaryPlotFeature"; + menuBuilder << "RicShowSummaryCurveCalculatorFeature"; menuBuilder << "Separator"; menuBuilder << "RicCopyReferencesToClipboardFeature"; menuBuilder << "Separator"; @@ -792,6 +790,10 @@ caf::CmdFeatureMenuBuilder RimContextCommandBuilder::commandsFromSelection() { menuBuilder << "RicCreateTextAnnotationFeature"; } + else if ( dynamic_cast( uiItem ) || dynamic_cast( uiItem ) ) + { + menuBuilder << "RicReloadPlotTemplatesFeature"; + } if ( dynamic_cast( uiItem ) ) { menuBuilder << "Separator"; diff --git a/ApplicationCode/ProjectDataModel/RimDialogData.cpp b/ApplicationCode/ProjectDataModel/RimDialogData.cpp index 7b9b48f8f6..99810ba07e 100644 --- a/ApplicationCode/ProjectDataModel/RimDialogData.cpp +++ b/ApplicationCode/ProjectDataModel/RimDialogData.cpp @@ -27,6 +27,7 @@ #include "ExportCommands/RicExportWellPathsUi.h" #include "FractureCommands/RicCreateMultipleFracturesUi.h" #include "HoloLensCommands/RicHoloLensExportToFolderUi.h" +#include "PlotTemplateCommands/RicSelectPlotTemplateUI.h" CAF_PDM_SOURCE_INIT( RimDialogData, "RimDialogData" ); @@ -65,6 +66,9 @@ RimDialogData::RimDialogData() CAF_PDM_InitFieldNoDefault( &m_mockModelSettings, "MockModelSettings", "Mock Model Settings", "", "", "" ); m_mockModelSettings = new RimMockModelSettings(); + + CAF_PDM_InitFieldNoDefault( &m_selectPlotTemplateUi, "SelectPlotTemplateUi", "Select Plot Template", "", "", "" ); + m_selectPlotTemplateUi = new RicSelectPlotTemplateUi(); } //-------------------------------------------------------------------------------------------------- @@ -155,3 +159,11 @@ RimMockModelSettings* RimDialogData::mockModelSettings() const { return m_mockModelSettings; } + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RicSelectPlotTemplateUi* RimDialogData::selectPlotTemplateUi() const +{ + return m_selectPlotTemplateUi; +} diff --git a/ApplicationCode/ProjectDataModel/RimDialogData.h b/ApplicationCode/ProjectDataModel/RimDialogData.h index 87c2a3cbd2..ce8f78c8b9 100644 --- a/ApplicationCode/ProjectDataModel/RimDialogData.h +++ b/ApplicationCode/ProjectDataModel/RimDialogData.h @@ -29,6 +29,7 @@ class RicHoloLensExportToFolderUi; class RicExportWellPathsUi; class RicExportLgrUi; class RimMockModelSettings; +class RicSelectPlotTemplateUi; //================================================================================================== /// @@ -62,6 +63,8 @@ public: RicExportEclipseSectorModelUi* exportSectorModelUi() const; RimMockModelSettings* mockModelSettings() const; + RicSelectPlotTemplateUi* selectPlotTemplateUi() const; + private: caf::PdmChildField m_exportCarfin; caf::PdmChildField m_exportCompletionData; @@ -71,4 +74,5 @@ private: caf::PdmChildField m_exportLgrData; caf::PdmChildField m_exportSectorModelData; caf::PdmChildField m_mockModelSettings; + caf::PdmChildField m_selectPlotTemplateUi; }; diff --git a/ApplicationCode/ProjectDataModel/RimProject.cpp b/ApplicationCode/ProjectDataModel/RimProject.cpp index 9966db6089..07a2a37c9d 100644 --- a/ApplicationCode/ProjectDataModel/RimProject.cpp +++ b/ApplicationCode/ProjectDataModel/RimProject.cpp @@ -363,8 +363,10 @@ void RimProject::setScriptDirectories( const QString& scriptDirectories ) //-------------------------------------------------------------------------------------------------- void RimProject::setPlotTemplateFolders( const QStringList& plotTemplateFolders ) { - if ( m_plotTemplateFolderItem() ) delete m_plotTemplateFolderItem(); - m_plotTemplateFolderItem = new RimPlotTemplateFolderItem(); + if ( !m_plotTemplateFolderItem() ) + { + m_plotTemplateFolderItem = new RimPlotTemplateFolderItem(); + } m_plotTemplateFolderItem->createRootFolderItemsFromFolderPaths( plotTemplateFolders ); } diff --git a/ApplicationCode/UserInterface/RiuSummaryQwtPlot.cpp b/ApplicationCode/UserInterface/RiuSummaryQwtPlot.cpp index ee18bfa61b..6bb4ad641f 100644 --- a/ApplicationCode/UserInterface/RiuSummaryQwtPlot.cpp +++ b/ApplicationCode/UserInterface/RiuSummaryQwtPlot.cpp @@ -187,6 +187,7 @@ void RiuSummaryQwtPlot::contextMenuEvent( QContextMenuEvent* event ) caf::SelectionManager::instance()->setSelectedItem( ownerViewWindow() ); menuBuilder << "RicShowPlotDataFeature"; + menuBuilder << "RicSavePlotTemplateFeature"; menuBuilder.appendToMenu( &menu ); From f088d99a02c8059992bd25b0518edec2bcafb72e Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Thu, 19 Sep 2019 14:32:35 +0200 Subject: [PATCH 2/2] Fix invalid case in file name --- ApplicationCode/ProjectDataModel/RimDialogData.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ApplicationCode/ProjectDataModel/RimDialogData.cpp b/ApplicationCode/ProjectDataModel/RimDialogData.cpp index 99810ba07e..a6ea0cd822 100644 --- a/ApplicationCode/ProjectDataModel/RimDialogData.cpp +++ b/ApplicationCode/ProjectDataModel/RimDialogData.cpp @@ -27,7 +27,7 @@ #include "ExportCommands/RicExportWellPathsUi.h" #include "FractureCommands/RicCreateMultipleFracturesUi.h" #include "HoloLensCommands/RicHoloLensExportToFolderUi.h" -#include "PlotTemplateCommands/RicSelectPlotTemplateUI.h" +#include "PlotTemplateCommands/RicSelectPlotTemplateUi.h" CAF_PDM_SOURCE_INIT( RimDialogData, "RimDialogData" );