View Javadoc

1   /**********************************************
2    * Copyright (C) 2011 Lukas Laag
3    * This file is part of svgreal.
4    * 
5    * svgreal is free software: you can redistribute it and/or modify
6    * it under the terms of the GNU General Public License as published by
7    * the Free Software Foundation, either version 3 of the License, or
8    * (at your option) any later version.
9    * 
10   * svgreal is distributed in the hope that it will be useful,
11   * but WITHOUT ANY WARRANTY; without even the implied warranty of
12   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13   * GNU General Public License for more details.
14   * 
15   * You should have received a copy of the GNU General Public License
16   * along with svgreal.  If not, see http://www.gnu.org/licenses/
17   **********************************************/
18  package org.vectomatic.svg.edit.client.command.dnd;
19  
20  import java.util.ArrayList;
21  import java.util.List;
22  
23  import org.vectomatic.dom.svg.OMSVGMatrix;
24  import org.vectomatic.dom.svg.itf.ISVGTransformable;
25  import org.vectomatic.dom.svg.utils.SVGConstants;
26  import org.vectomatic.svg.edit.client.command.CommandFactories;
27  import org.vectomatic.svg.edit.client.command.DndCommandFactory.DropGesture;
28  import org.vectomatic.svg.edit.client.engine.SVGModel;
29  import org.vectomatic.svg.edit.client.model.svg.SVGElementModel;
30  
31  import com.extjs.gxt.ui.client.data.BeanModel;
32  import com.extjs.gxt.ui.client.data.BeanModelLookup;
33  
34  /**
35   * Class to represent a svg model to svg model command
36   * @author laaglu
37   */
38  public class CopyCommand extends DndCommandBase {
39  //	public enum CopyRatio {
40  //		/**
41  //		 * The original dimensions of the source element are preserved,
42  //		 * which can make it appear either very large or very small
43  //		 * if the source and destination models have widely differing
44  //		 * coordinate systems.
45  //		 */
46  //		SourceSize,
47  //		/**
48  //		 * The size of the source element is altered so that
49  //		 * it appears to have the same size as the source element
50  //		 * in the destination model when the destination model
51  //		 * is not zoomed.
52  //		 */
53  //		DestinationSize,
54  //		/**
55  //		 * The size of the copied element is altered so that
56  //		 * it appears to have the same size as the source element
57  //		 * at the current zoom level of the destination model
58  //		 * and the current zoom level of the source model 
59  //		 */
60  //		VisibleSize
61  //	}
62  	/**
63  	 * The models to copy, unsorted
64  	 */
65  	protected List<SVGElementModel> models;
66  	/**
67  	 * The cloned models, unsorted
68  	 */
69  	protected List<SVGElementModel> clones;
70  	/**
71  	 * The target model
72  	 */
73  	protected SVGElementModel target;
74  	/**
75  	 * The drop gesture
76  	 */
77  	protected DropGesture dropGesture;
78  //	/**
79  //	 * The copy ratio
80  //	 */
81  //	protected CopyRatio copyRatio;
82  	/**
83  	 * The command description
84  	 */
85  	protected String description;
86  
87  	public CopyCommand(List<SVGElementModel> models, SVGElementModel target, DropGesture dropGesture, String description) {
88  		super(CommandFactories.getDndCommandFactory());
89  		this.models = models;
90  		this.target = target;
91  		this.dropGesture = dropGesture;
92  		this.description = description;
93  //		copyRatio = CopyRatio.SourceSize;
94  	}
95  
96  	@Override
97  	public String getDescription() {
98  		return description;
99  	}
100 
101 	@Override
102 	public void commit() {
103 		SVGModel owner = target.getOwner();
104 		SVGElementModel parentModel = null;
105 		SVGElementModel refModel = null;
106 		
107 		if (dropGesture == DropGesture.OnNode) {
108 			// target is a folder
109 			parentModel = target;
110 		} else {
111 			// target is a leaf in the same document
112 			parentModel = (SVGElementModel) target.getParent();
113 			if (dropGesture == DropGesture.BeforeNode) {
114 				refModel = target;
115 			} else if (dropGesture == DropGesture.AfterNode) {
116 				refModel = target.getNextSibling();
117 			}
118 		}
119 		
120 		if (clones == null) {
121 			ISVGTransformable parentElement = (ISVGTransformable)parentModel.getElementWrapper();
122 			OMSVGMatrix parentCTM = parentElement.getCTM();
123 			clones = new ArrayList<SVGElementModel>();
124 			for (SVGElementModel model : models) {
125 				SVGElementModel clone = owner.clone(model, model.<String>get(SVGConstants.SVG_TITLE_TAG));
126 				
127 				// Update the transform of a model which is going to be
128 				// attached to a parent model so that the model appears 
129 				// unchanged to the end-user. This is done by applying
130 				// a counter transform (the inverse of the transform
131 				// of the parent) to to nullify its effect
132 				ISVGTransformable element = (ISVGTransformable)model.getElementWrapper();
133 				OMSVGMatrix elementCTM = element.getCTM();
134 				clone.updateTransform(parentCTM.inverse().multiply(elementCTM));
135 				clones.add(clone);
136 			}
137 		}
138 		
139 		for (SVGElementModel clone : clones) {
140 			owner.insertBefore(parentModel, clone, refModel);
141 		}
142 
143 	}
144 
145 	@Override
146 	public void rollback() {
147 		SVGModel owner = target.getOwner();
148 		for (SVGElementModel clone : clones) {
149 			owner.remove(clone);
150 		}
151 	}
152 
153 	@Override
154 	public BeanModel asModel() {
155 		return BeanModelLookup.get().getFactory(CopyCommand.class).createModel(this);
156 	}
157 
158 }