///////////////////////////////////////////////////////////////////////////////// // // Copyright (C) 2015- Statoil ASA // Copyright (C) 2015- Ceetron Solutions AS // // 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 "RicCopyIntersectionsToAllViewsInCaseFeature.h" #include "RimBoxIntersection.h" #include "RimCase.h" #include "RimEclipseCase.h" #include "RimExtrudedCurveIntersection.h" #include "RimGridView.h" #include "RimIntersectionCollection.h" #include "cafCmdExecCommandManager.h" #include "cafPdmUiItem.h" #include "cafSelectionManagerTools.h" #include "cvfAssert.h" #include CAF_CMD_SOURCE_INIT( RicCopyIntersectionsToAllViewsInCaseFeature, "RicCopyIntersectionsToAllViewsInCaseFeature" ); //-------------------------------------------------------------------------------------------------- /// Internal definitions //-------------------------------------------------------------------------------------------------- enum SelectionComposition { SEL_INVALID, SEL_COLLECTION, SEL_INTERSECTIONS, SEL_INTERSECTION_BOXES, SEL_BOTH_INTERSECTION_TYPES }; static RimIntersectionCollection* selectedIntersectionCollection(); static std::vector selectedIntersections(); static std::vector selectedIntersectionBoxes(); static SelectionComposition selectionComposition(); static RimCase* commonGridCase( std::vector selectedItems ); //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- bool RicCopyIntersectionsToAllViewsInCaseFeature::isCommandEnabled() const { return selectionComposition() != SEL_INVALID; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RicCopyIntersectionsToAllViewsInCaseFeature::onActionTriggered( bool isChecked ) { RimCase* gridCase = caf::firstAncestorOfTypeFromSelectedObject(); if ( gridCase ) { SelectionComposition compostion = selectionComposition(); if ( compostion == SEL_COLLECTION ) { RimIntersectionCollection* coll = selectedIntersectionCollection(); copyIntersectionsToOtherViews( *gridCase, coll->intersections() ); copyIntersectionBoxesToOtherViews( *gridCase, coll->intersectionBoxes() ); } std::vector selIntersections = selectedIntersections(); std::vector selIntersectionBoxes = selectedIntersectionBoxes(); if ( compostion == SEL_INTERSECTIONS || compostion == SEL_BOTH_INTERSECTION_TYPES ) { copyIntersectionsToOtherViews( *gridCase, selIntersections ); } if ( compostion == SEL_INTERSECTION_BOXES || compostion == SEL_BOTH_INTERSECTION_TYPES ) { copyIntersectionBoxesToOtherViews( *gridCase, selIntersectionBoxes ); } } } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RicCopyIntersectionsToAllViewsInCaseFeature::setupActionLook( QAction* actionToSetup ) { actionToSetup->setIcon( QIcon( ":/Copy.png" ) ); actionToSetup->setText( "Copy intersections to all views in case" ); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RicCopyIntersectionsToAllViewsInCaseFeature::copyIntersectionsToOtherViews( RimCase& gridCase, std::vector intersections ) { for ( RimExtrudedCurveIntersection* intersection : intersections ) { for ( Rim3dView* const view : gridCase.views() ) { RimGridView* currGridView = dynamic_cast( view ); RimGridView* parentView = intersection->firstAncestorOrThisOfType(); if ( currGridView && parentView != nullptr && parentView != currGridView ) { RimIntersectionCollection* destCollection = currGridView->intersectionCollection(); auto copy = intersection->copyObject(); CVF_ASSERT( copy ); destCollection->appendIntersectionAndUpdate( copy, false ); // Resolve references after object has been inserted into the project data model copy->resolveReferencesRecursively(); copy->updateConnectedEditors(); } } } } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RicCopyIntersectionsToAllViewsInCaseFeature::copyIntersectionBoxesToOtherViews( RimCase& gridCase, std::vector intersectionBoxes ) { for ( RimBoxIntersection* intersectionBox : intersectionBoxes ) { for ( Rim3dView* const view : gridCase.views() ) { RimGridView* currGridView = dynamic_cast( view ); RimGridView* parentView = intersectionBox->firstAncestorOrThisOfType(); if ( currGridView && parentView != nullptr && parentView != currGridView ) { RimIntersectionCollection* destCollection = currGridView->intersectionCollection(); auto copy = intersectionBox->copyObject(); CVF_ASSERT( copy ); destCollection->appendIntersectionBoxAndUpdate( copy ); } } } } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- RimIntersectionCollection* selectedIntersectionCollection() { std::vector selObjects = caf::selectedObjectsByType(); return !selObjects.empty() ? selObjects[0] : nullptr; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- std::vector selectedIntersections() { return caf::selectedObjectsByType(); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- std::vector selectedIntersectionBoxes() { return caf::selectedObjectsByType(); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- SelectionComposition selectionComposition() { std::vector allSelectedObjects; caf::SelectionManager::instance()->selectedItems( allSelectedObjects ); RimCase* gridCase = commonGridCase( allSelectedObjects ); if ( gridCase && gridCase->gridViews().size() > 1 ) { RimIntersectionCollection* selColl = selectedIntersectionCollection(); std::vector selIntersections = selectedIntersections(); std::vector selIntersectionBoxes = selectedIntersectionBoxes(); if ( selColl ) { if ( allSelectedObjects.size() == 1 ) return SEL_COLLECTION; } else { if ( !selIntersections.empty() && !selIntersectionBoxes.empty() ) return SEL_BOTH_INTERSECTION_TYPES; else if ( !selIntersections.empty() ) return SEL_INTERSECTIONS; else if ( !selIntersectionBoxes.empty() ) return SEL_INTERSECTION_BOXES; } } return SEL_INVALID; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- RimCase* commonGridCase( std::vector selectedItems ) { RimCase* gridCase = nullptr; for ( caf::PdmUiItem* item : selectedItems ) { caf::PdmObjectHandle* obj = dynamic_cast( item ); if ( !obj ) { continue; } RimCase* itemCase = obj->firstAncestorOrThisOfType(); if ( gridCase == nullptr ) gridCase = itemCase; else if ( gridCase != itemCase ) return nullptr; } return gridCase; }