///////////////////////////////////////////////////////////////////////////////// // // Copyright (C) 2017- Statoil 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 "RicDeleteSummaryCaseCollectionFeature.h" #include "Summary/RiaSummaryTools.h" #include "RimDeltaSummaryEnsemble.h" #include "RimDepthTrackPlot.h" #include "RimMainPlotCollection.h" #include "RimProject.h" #include "RimSummaryCase.h" #include "RimSummaryCaseMainCollection.h" #include "RimSummaryEnsemble.h" #include "RimSummaryMultiPlot.h" #include "RimSummaryMultiPlotCollection.h" #include "RimSummaryPlot.h" #include "RimWellPlotTools.h" #include "RiuPlotMainWindow.h" #include "cafPdmObject.h" #include "cafPdmObjectHandleTools.h" #include "cafSelectionManager.h" #include #include #include CAF_CMD_SOURCE_INIT( RicDeleteSummaryCaseCollectionFeature, "RicDeleteSummaryCaseCollectionFeature" ); //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RicDeleteSummaryCaseCollectionFeature::deleteSummaryCaseCollection( RimSummaryEnsemble* caseCollection ) { auto cases = caseCollection->allSummaryCases(); if ( cases.empty() ) return; // Delete the curves for all the cases in one pass per plot, and update each multi plot only if it actually lost a // curve. Doing this per case meant scanning every plot once per realization and updating the connected editors // once per realization and multi plot. const std::set casesToDelete( cases.begin(), cases.end() ); RimSummaryMultiPlotCollection* summaryPlotColl = RiaSummaryTools::summaryMultiPlotCollection(); for ( RimSummaryMultiPlot* multiPlot : summaryPlotColl->multiPlots() ) { bool curvesDeleted = false; for ( RimSummaryPlot* summaryPlot : multiPlot->summaryPlots() ) { if ( summaryPlot->deleteCurvesAssosiatedWithCases( casesToDelete ) ) curvesDeleted = true; } if ( curvesDeleted ) multiPlot->updateConnectedEditors(); } } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- bool RicDeleteSummaryCaseCollectionFeature::isCommandEnabled() const { auto selection = caf::SelectionManager::instance()->objectsByType(); selection.erase( std::remove_if( selection.begin(), selection.end(), []( RimSummaryEnsemble* coll ) { return dynamic_cast( coll ) != nullptr; } ), selection.end() ); return ( !selection.empty() ); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RicDeleteSummaryCaseCollectionFeature::onActionTriggered( bool isChecked ) { const auto ensembles = caf::SelectionManager::instance()->objectsByType(); if ( ensembles.empty() ) return; QMessageBox msgBox( RiuPlotMainWindow::instance() ); msgBox.setIcon( QMessageBox::Question ); QString questionText; questionText = QString( "Do you also want to close the summary cases in the group?" ); msgBox.setText( questionText ); msgBox.setStandardButtons( QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel ); int ret = msgBox.exec(); if ( ret == QMessageBox::Cancel ) { return; } auto depthTrackPlots = caf::PdmObjectHandleTools::referringAncestorOfType( ensembles ); for ( RimSummaryEnsemble* ensemble : ensembles ) { if ( ret == QMessageBox::Yes ) { RicDeleteSummaryCaseCollectionFeature::deleteSummaryCaseCollection( ensemble ); } else if ( ret == QMessageBox::No ) { RicDeleteSummaryCaseCollectionFeature::moveAllCasesToMainSummaryCollection( ensemble ); } } RimSummaryCaseMainCollection* summaryCaseMainCollection = ensembles[0]->firstAncestorOrThisOfTypeAsserted(); for ( RimSummaryEnsemble* ensemble : ensembles ) { summaryCaseMainCollection->removeEnsemble( ensemble ); ensemble->cleanupBeforeDelete(); } // Rebuild the tree and connected editors while the detached ensembles are still alive, so no tree item // editor ends up referencing freed objects during the update (see caf::CmdDeleteItemExec for the same // ordering). Deleting the ensembles before the tree update caused a use-after-free crash. summaryCaseMainCollection->updateConnectedEditors(); for ( RimSummaryEnsemble* ensemble : ensembles ) { delete ensemble; } RimWellPlotTools::loadDataAndUpdateDepthTrackPlots( depthTrackPlots ); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RicDeleteSummaryCaseCollectionFeature::setupActionLook( QAction* actionToSetup ) { actionToSetup->setText( "Delete Summary Case Group/Ensemble" ); actionToSetup->setIcon( QIcon( ":/Erase.svg" ) ); applyShortcutWithHintToAction( actionToSetup, QKeySequence::Delete ); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RicDeleteSummaryCaseCollectionFeature::moveAllCasesToMainSummaryCollection( RimSummaryEnsemble* summaryCaseCollection ) { std::vector summaryCases = summaryCaseCollection->allSummaryCases(); if ( summaryCases.empty() ) return; RimSummaryCaseMainCollection* summaryCaseMainCollection = summaryCaseCollection->firstAncestorOrThisOfType(); for ( RimSummaryCase* summaryCase : summaryCases ) { summaryCaseCollection->removeCase( summaryCase ); summaryCaseMainCollection->addCase( summaryCase ); } }