/********************************************** * Copyright (C) 2011 Lukas Laag * This file is part of svgreal. * * svgreal 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. * * svgreal 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 svgreal. If not, see http://www.gnu.org/licenses/ **********************************************/ package org.vectomatic.svg.edit.client.command.dnd; import java.util.ArrayList; import java.util.List; import org.vectomatic.dom.svg.OMSVGElement; import org.vectomatic.dom.svg.itf.ISVGTransformable; import org.vectomatic.dom.svg.utils.SVGConstants; import org.vectomatic.svg.edit.client.command.CommandFactories; import org.vectomatic.svg.edit.client.command.DndCommandFactory.DropGesture; import org.vectomatic.svg.edit.client.engine.SVGModel; import org.vectomatic.svg.edit.client.model.ModelConstants; import org.vectomatic.svg.edit.client.model.svg.SVGElementModel; import org.vectomatic.svg.edit.client.model.svg.SVGNamedElementModel; import com.extjs.gxt.ui.client.data.BeanModel; import com.extjs.gxt.ui.client.data.BeanModelLookup; import com.extjs.gxt.ui.client.util.Format; /** * Class to represent a tree cloning command * @author laaglu */ public class CloneCommand extends DndCommandBase { /** * The models to copy, unsorted */ protected List<SVGElementModel> models; /** * The cloned models, unsorted */ protected List<SVGElementModel> clones; /** * The target model */ protected SVGElementModel target; /** * The drop gesture */ protected DropGesture dropGesture; public CloneCommand(List<SVGElementModel> models, SVGElementModel target, DropGesture dropGesture) { super(CommandFactories.getDndCommandFactory()); this.models = models; this.target = target; this.dropGesture = dropGesture; for (SVGElementModel model : models) { assert model.getOwner() == target.getOwner() : "Attempt to copy models from heterogeneous owners: " + model.getOwner() + ", " + target.getOwner(); } } @Override public String getDescription() { String message = null; switch(dropGesture) { case OnNode: message = ModelConstants.INSTANCE.dndCloneCmdIn(); break; case BeforeNode: message = ModelConstants.INSTANCE.dndCloneCmdBefore(); break; case AfterNode: message = ModelConstants.INSTANCE.dndCloneCmdAfter(); break; } return Format.substitute(message, SVGNamedElementModel.getNames(models), target.toString()); } @Override public void commit() { SVGModel owner = target.getOwner(); if (clones == null) { clones = new ArrayList<SVGElementModel>(); for (SVGElementModel model : models) { SVGElementModel clone = owner.clone(model, Format.substitute(ModelConstants.INSTANCE.copyOf(), model.get(SVGConstants.SVG_TITLE_TAG).toString())); clones.add(clone); } } SVGElementModel parentModel = null; SVGElementModel refModel = null; if (dropGesture == DropGesture.OnNode) { // target is a folder parentModel = target; } else { // target is a leaf in the same document parentModel = (SVGElementModel) target.getParent(); if (dropGesture == DropGesture.BeforeNode) { refModel = target; } else if (dropGesture == DropGesture.AfterNode) { refModel = target.getNextSibling(); } } OMSVGElement parentElement = parentModel.getElementWrapper(); for (int i = 0, size = models.size(); i < size; i++) { SVGElementModel model = models.get(i); SVGElementModel clone = clones.get(i); // Update the transform of a model which is going to be // attached to a parent model so that the model appears // unchanged to the end-user. This is done by applying // a counter transform (the inverse of the transform // of the parent) to to nullify its effect OMSVGElement element = model.getElementWrapper(); clone.updateTransform(((ISVGTransformable)element).getTransformToElement(parentElement)); owner.insertBefore(parentModel, clone, refModel); } } @Override public void rollback() { SVGModel owner = target.getOwner(); for (SVGElementModel clone : clones) { owner.remove(clone); } } @Override public BeanModel asModel() { return BeanModelLookup.get().getFactory(CloneCommand.class).createModel(this); } }