/* * (c) Copyright 2010-2011 AgileBirds * * This file is part of OpenFlexo. * * OpenFlexo 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. * * OpenFlexo 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 for more details. * * You should have received a copy of the GNU General Public License * along with OpenFlexo. If not, see <http://www.gnu.org/licenses/>. * */ package org.openflexo.foundation.view.action; import java.util.Collections; import java.util.Comparator; import java.util.List; import java.util.Vector; import java.util.logging.Level; import java.util.logging.Logger; import org.openflexo.foundation.FlexoEditor; import org.openflexo.foundation.FlexoModelObject; import org.openflexo.foundation.action.FlexoActionType; import org.openflexo.foundation.action.FlexoUndoableAction; import org.openflexo.foundation.ontology.EditionPatternInstance; import org.openflexo.foundation.view.ViewConnector; import org.openflexo.foundation.view.ViewElement; import org.openflexo.foundation.view.ViewObject; import org.openflexo.foundation.view.ViewShape; import org.openflexo.foundation.viewpoint.ConnectorPatternRole; import org.openflexo.foundation.viewpoint.ShapePatternRole; public class DeleteViewElements extends FlexoUndoableAction<DeleteViewElements, ViewElement, ViewElement> { private static final Logger logger = Logger.getLogger(DeleteViewElements.class.getPackage().getName()); public static FlexoActionType<DeleteViewElements, ViewElement, ViewElement> actionType = new FlexoActionType<DeleteViewElements, ViewElement, ViewElement>( "delete", FlexoActionType.editGroup, FlexoActionType.DELETE_ACTION_TYPE) { /** * Factory method */ @Override public DeleteViewElements makeNewAction(ViewElement focusedObject, Vector<ViewElement> globalSelection, FlexoEditor editor) { return new DeleteViewElements(focusedObject, globalSelection, editor); } @Override public boolean isVisibleForSelection(ViewElement object, Vector<ViewElement> globalSelection) { return true; } @Override public boolean isEnabledForSelection(ViewElement focusedObject, Vector<ViewElement> globalSelection) { Vector<ViewElement> objectsToDelete = objectsToDelete(focusedObject, globalSelection); return objectsToDelete.size() > 0; } }; static { FlexoModelObject.addActionForClass(DeleteViewElements.actionType, ViewShape.class); FlexoModelObject.addActionForClass(DeleteViewElements.actionType, ViewConnector.class); } /** * Given a selection, compute a list of ViewElements ensuring deletion of right selection<br> * (extra selected embedded objects are removed from selection) * * @param focusedObject * @param globalSelection * @return */ protected static Vector<ViewElement> objectsToDelete(ViewElement focusedObject, Vector<ViewElement> globalSelection) { Vector<ViewElement> allSelection = new Vector<ViewElement>(); if (globalSelection == null || !globalSelection.contains(focusedObject)) { allSelection.add(focusedObject); } if (globalSelection != null) { for (ViewElement o : globalSelection) { if (!allSelection.contains(o)) { allSelection.add(o); } } } Vector<ViewElement> returned = new Vector<ViewElement>(); for (ViewElement o : allSelection) { boolean isContainedByAnOtherObject = false; for (ViewElement potentielContainer : allSelection) { if (potentielContainer != o && o.isContainedIn(potentielContainer)) { isContainedByAnOtherObject = true; break; } } if (!isContainedByAnOtherObject && !returned.contains(o)) { returned.add(o); } } return returned; } private Vector<ViewElement> viewElementsToDelete; private Vector<EditionPatternInstance> epiThatWillBeDeleted; private Vector<FlexoModelObject> allObjectsThatWillBeDeleted; protected DeleteViewElements(ViewElement focusedObject, Vector<ViewElement> globalSelection, FlexoEditor editor) { super(actionType, focusedObject, globalSelection, editor); logger.info("Created DeleteShemaElements action focusedObject=" + focusedObject + "globalSelection=" + globalSelection); } @Override protected void doAction(Object context) { if (logger.isLoggable(Level.INFO)) { logger.info("DeleteShemaElements"); } if (logger.isLoggable(Level.FINE)) { logger.fine("selection is: " + getGlobalSelection()); logger.fine("selection to delete is: " + getViewElementsToDelete()); logger.fine("all objects to delete are: " + getAllObjectsThatWillBeDeleted()); } /*if (deleteOntologicObjects) { for (OntologicObjectEntry e : getOntologicObjectsToBeDeleted()) { if (e.deleteIt && e.ontologicObject instanceof OntologyStatement) { e.ontologicObject.delete(); } } for (OntologicObjectEntry e : getOntologicObjectsToBeDeleted()) { if (e.deleteIt && !(e.ontologicObject instanceof OntologyStatement)) { e.ontologicObject.delete(); } } }*/ for (EditionPatternInstance epi : getEPIThatWillBeDeleted()) { epi.delete(); } for (ViewElement o : getViewElementsToDelete()) { if (!o.isDeleted()) { logger.info("Delete undeleted ViewElement " + o); o.delete(); } else { logger.info("ViewElement " + o + " has been successfully deleted"); } } } @Override protected void undoAction(Object context) { logger.warning("UNDO DELETE not implemented yet !"); } @Override protected void redoAction(Object context) { logger.warning("REDO DELETE not implemented yet !"); } public List<ViewElement> getViewElementsToDelete() { if (viewElementsToDelete == null) { computeElementsToDelete(); } return viewElementsToDelete; } private void computeElementsToDelete() { viewElementsToDelete = objectsToDelete(getFocusedObject(), getGlobalSelection()); Vector<ViewElement> viewElementsThatWillBeDeleted = new Vector<ViewElement>(); for (ViewElement o : viewElementsToDelete) { addAllEmbeddedObjects(o, viewElementsThatWillBeDeleted); } epiThatWillBeDeleted = new Vector<EditionPatternInstance>(); for (ViewElement o : viewElementsThatWillBeDeleted) { if (o.getEditionPatternInstance() != null && !epiThatWillBeDeleted.contains(o.getEditionPatternInstance())) { epiThatWillBeDeleted.add(o.getEditionPatternInstance()); } } // Sorts EPI in order to privilegiate deletion of connectors first Collections.sort(epiThatWillBeDeleted, new Comparator<EditionPatternInstance>() { @Override public int compare(EditionPatternInstance o1, EditionPatternInstance o2) { if (o1.getEditionPattern().getPrimaryRepresentationRole() instanceof ShapePatternRole && o2.getEditionPattern().getPrimaryRepresentationRole() instanceof ConnectorPatternRole) { return 1; } else if (o1.getEditionPattern().getPrimaryRepresentationRole() instanceof ConnectorPatternRole && o2.getEditionPattern().getPrimaryRepresentationRole() instanceof ShapePatternRole) { return -1; } return 0; } }); allObjectsThatWillBeDeleted = new Vector<FlexoModelObject>(); for (EditionPatternInstance epi : epiThatWillBeDeleted) { List<FlexoModelObject> l = epi.objectsThatWillBeDeleted(); if (l != null) { for (FlexoModelObject o : l) { if (!allObjectsThatWillBeDeleted.contains(o)) { allObjectsThatWillBeDeleted.add(o); } } } } } private void addAllEmbeddedObjects(ViewElement o, Vector<ViewElement> v) { if (!v.contains(o) && o.playsPrimaryRole()) { v.add(o); if (o instanceof ViewShape) { ViewShape s = (ViewShape) o; for (ViewConnector connector : s.getIncomingConnectors()) { if (!v.contains(connector) && connector.playsPrimaryRole()) { v.add(connector); } } for (ViewConnector connector : s.getOutgoingConnectors()) { if (!v.contains(connector) && connector.playsPrimaryRole()) { v.add(connector); } } } for (ViewObject child : o.getChilds()) { if (child instanceof ViewElement) { addAllEmbeddedObjects((ViewElement) child, v); } } } } public List<EditionPatternInstance> getEPIThatWillBeDeleted() { if (epiThatWillBeDeleted == null) { computeElementsToDelete(); } return epiThatWillBeDeleted; } public List<FlexoModelObject> getAllObjectsThatWillBeDeleted() { if (allObjectsThatWillBeDeleted == null) { computeElementsToDelete(); /*for (ViewElement e : getObjectsThatWillBeDeleted()) { if (e.getEditionPatternReferences() != null) { for (EditionPatternReference ref : e.getEditionPatternReferences()) { EditionPatternInstance epInstance = ref.getEditionPatternInstance(); for (String s : epInstance.getActors().keySet()) { FlexoModelObject actor = epInstance.getActors().get(s); if (actor instanceof AbstractOntologyObject) { if (!_ontologicObjectsToBeDeleted.contains(actor)) { _ontologicObjectsToBeDeleted.add(new OntologicObjectEntry(true, (AbstractOntologyObject) actor)); } } } } } }*/ } return allObjectsThatWillBeDeleted; } }