1 package fr.orsay.lri.varna.models;
4 import java.awt.geom.Point2D;
5 import java.util.ArrayList;
7 import javax.swing.undo.AbstractUndoableEdit;
8 import javax.swing.undo.CannotRedoException;
9 import javax.swing.undo.CannotUndoException;
10 import javax.swing.undo.UndoableEdit;
12 import fr.orsay.lri.varna.VARNAPanel;
13 import fr.orsay.lri.varna.applications.templateEditor.GraphicalTemplateElement;
14 import fr.orsay.lri.varna.applications.templateEditor.TemplatePanel;
15 import fr.orsay.lri.varna.applications.templateEditor.TemplateEdits.ElementEdgeMoveTemplateEdit;
16 import fr.orsay.lri.varna.exceptions.ExceptionNAViewAlgorithm;
17 import fr.orsay.lri.varna.models.rna.ModeleBase;
18 import fr.orsay.lri.varna.models.rna.ModeleBP;
19 import fr.orsay.lri.varna.models.rna.RNA;
21 public class VARNAEdits {
22 public static final double MAX_DISTANCE= 55.0;
23 public static class BasesShiftEdit extends AbstractUndoableEdit
25 private ArrayList<Integer> _indices;
28 private VARNAPanel _vp;
29 public BasesShiftEdit(ArrayList<Integer> indices, double dx, double dy, VARNAPanel p)
36 public void undo() throws CannotUndoException {
37 for (int index: _indices)
39 ModeleBase mb = _vp.getRNA().getBaseAt(index);
40 _vp.getRNA().setCoord(index,new Point2D.Double(mb.getCoords().x-_dx,mb.getCoords().y-_dy));
41 _vp.getRNA().setCenter(index,new Point2D.Double(mb.getCenter().x-_dx,mb.getCenter().y-_dy));
45 public void redo() throws CannotRedoException {
46 for (int index: _indices)
48 ModeleBase mb = _vp.getRNA().getBaseAt(index);
49 _vp.getRNA().setCoord(index,new Point2D.Double(mb.getCoords().x+_dx,mb.getCoords().y+_dy));
50 _vp.getRNA().setCenter(index,new Point2D.Double(mb.getCenter().x-_dx,mb.getCenter().y-_dy));
54 public boolean canUndo() { return true; }
55 public boolean canRedo() { return true; }
56 public String getPresentationName() { return "Base #"+_indices+" shifted"; }
57 public boolean addEdit(UndoableEdit anEdit)
59 if (anEdit instanceof BasesShiftEdit)
61 BasesShiftEdit e = (BasesShiftEdit) anEdit;
62 if (e._indices.equals(_indices))
64 Point2D.Double tot = new Point2D.Double(_dx+e._dx,_dy+e._dy);
65 if (tot.distance(0.0, 0.0)<MAX_DISTANCE)
77 public static class HelixRotateEdit extends AbstractUndoableEdit
79 private double _delta;
81 private double _pLimL;
82 private double _pLimR;
85 private VARNAPanel _vp;
86 public HelixRotateEdit(double delta, double base, double pLimL, double pLimR, Point h, Point ml, VARNAPanel vp)
96 public void undo() throws CannotUndoException {
97 _vp.getVARNAUI().UIRotateEverything(-_delta, _base, _pLimL, _pLimR, _h, _ml);
100 public void redo() throws CannotRedoException {
101 _vp.getVARNAUI().UIRotateEverything(_delta, _base, _pLimL, _pLimR, _h, _ml);
104 public boolean canUndo() { return true; }
105 public boolean canRedo() { return true; }
106 public String getPresentationName() { return "Helix #"+_h+" rotated angle:"+_delta; }
107 public boolean addEdit(UndoableEdit anEdit)
109 if (anEdit instanceof HelixRotateEdit)
111 HelixRotateEdit e = (HelixRotateEdit) anEdit;
114 double totAngle = e._delta+_delta;
115 while (totAngle>Math.PI)
116 { totAngle -= 2.0*Math.PI; }
117 if (Math.abs(totAngle)<Math.PI/8.0)
129 public static class SingleBaseMoveEdit extends AbstractUndoableEdit
136 private VARNAPanel _vp;
137 public SingleBaseMoveEdit(int index, double nx, double ny, VARNAPanel p)
140 ModeleBase mb = p.getRNA().getBaseAt(index);
141 _ox = mb.getCoords().x;
142 _oy = mb.getCoords().y;
147 public void undo() throws CannotUndoException {
148 _vp.getRNA().setCoord(_index,new Point2D.Double(_ox,_oy));
151 public void redo() throws CannotRedoException {
152 _vp.getRNA().setCoord(_index,new Point2D.Double(_nx,_ny));
155 public boolean canUndo() { return true; }
156 public boolean canRedo() { return true; }
157 public String getPresentationName() { return "Base #"+_index+" moved"; }
158 public boolean addEdit(UndoableEdit anEdit)
160 if (anEdit instanceof SingleBaseMoveEdit)
162 SingleBaseMoveEdit e = (SingleBaseMoveEdit) anEdit;
163 if (e._index==_index)
165 Point2D.Double po1 = new Point2D.Double(_ox,_oy);
166 Point2D.Double pn1 = new Point2D.Double(_nx,_ny);
167 Point2D.Double po2 = new Point2D.Double(e._ox,e._oy);
168 Point2D.Double pn2 = new Point2D.Double(e._nx,e._ny);
169 if ((pn1.equals(po2))&&(po1.distance(pn2)<MAX_DISTANCE))
181 public static class HelixFlipEdit extends AbstractUndoableEdit
184 private VARNAPanel _vp;
185 public HelixFlipEdit(Point h, VARNAPanel vp)
190 public void undo() throws CannotUndoException {
191 _vp.getVARNAUI().UIFlipHelix(_h);
194 public void redo() throws CannotRedoException {
195 _vp.getVARNAUI().UIFlipHelix(_h);
198 public boolean canUndo() { return true; }
199 public boolean canRedo() { return true; }
200 public String getPresentationName() { return "Helix #"+_h+" flipped";}
201 public boolean addEdit(UndoableEdit anEdit)
207 public static class AddBPEdit extends AbstractUndoableEdit
209 private ModeleBP _msbp;
212 private VARNAPanel _vp;
213 public AddBPEdit(int i, int j, ModeleBP msbp, VARNAPanel vp)
220 public void undo() throws CannotUndoException {
221 _vp.getRNA().removeBP(_msbp);
224 public void redo() throws CannotRedoException {
225 _vp.getRNA().addBP(_i,_j,_msbp);
228 public boolean canUndo() { return true; }
229 public boolean canRedo() { return true; }
230 public String getPresentationName() { return "Add BP ("+_i+","+_j+")";}
231 public boolean addEdit(UndoableEdit anEdit)
237 public static class RemoveBPEdit extends AbstractUndoableEdit
239 private ModeleBP _msbp;
242 private VARNAPanel _vp;
243 public RemoveBPEdit( int i, int j,ModeleBP msbp, VARNAPanel vp)
250 public void undo() throws CannotUndoException {
251 _vp.getRNA().addBP(_i,_j,_msbp);
254 public void redo() throws CannotRedoException {
255 _vp.getRNA().removeBP(_msbp);
258 public boolean canUndo() { return true; }
259 public boolean canRedo() { return true; }
260 public String getPresentationName() { return "Remove BP ("+_i+","+_j+")";}
261 public boolean addEdit(UndoableEdit anEdit)
267 public static class RescaleRNAEdit extends AbstractUndoableEdit
269 private double _factor;
270 private VARNAPanel _vp;
271 public RescaleRNAEdit( double angle, VARNAPanel vp)
276 public void undo() throws CannotUndoException {
277 _vp.getRNA().rescale(1.0/_factor);
280 public void redo() throws CannotRedoException {
281 _vp.getRNA().rescale(_factor);
284 public boolean canUndo() { return true; }
285 public boolean canRedo() { return true; }
286 public String getPresentationName() { return "Rescale RNA factor:"+_factor+"";}
287 public boolean addEdit(UndoableEdit anEdit)
289 if (anEdit instanceof RescaleRNAEdit)
291 RescaleRNAEdit e = (RescaleRNAEdit) anEdit;
292 double cumFact = _factor*e._factor;
293 if (cumFact>.7 || cumFact<1.3)
295 _factor *= e._factor;
303 public static class RotateRNAEdit extends AbstractUndoableEdit
305 private double _angle;
306 private VARNAPanel _vp;
307 public RotateRNAEdit( double angle, VARNAPanel vp)
312 public void undo() throws CannotUndoException {
313 _vp.getRNA().globalRotation(-_angle);
316 public void redo() throws CannotRedoException {
317 _vp.getRNA().globalRotation(_angle);
320 public boolean canUndo() { return true; }
321 public boolean canRedo() { return true; }
322 public String getPresentationName() { return "Rotate RNA angle:"+_angle+"";}
323 public boolean addEdit(UndoableEdit anEdit)
325 if (anEdit instanceof RotateRNAEdit)
327 RotateRNAEdit e = (RotateRNAEdit) anEdit;
328 if (Math.abs(_angle+e._angle)<30)
338 public static class RedrawEdit extends AbstractUndoableEdit
340 private int _prevMode;
341 private int _newMode;
342 private boolean _prevFlat;
343 private boolean _newFlat;
344 private ArrayList<Point2D.Double> _backupCoords = new ArrayList<Point2D.Double>();
345 private ArrayList<Point2D.Double> _backupCenters = new ArrayList<Point2D.Double>();
346 private VARNAPanel _vp;
349 public RedrawEdit(VARNAPanel vp,boolean newFlat)
351 this(vp.getRNA().getDrawMode(),vp,newFlat);
354 public RedrawEdit(int newMode, VARNAPanel vp)
356 this(newMode,vp,vp.getFlatExteriorLoop());
359 public RedrawEdit(int newMode, VARNAPanel vp, boolean newFlat)
364 _prevFlat = _vp.getFlatExteriorLoop();
365 for (ModeleBase mb: _vp.getRNA().get_listeBases())
367 _backupCoords.add(new Point2D.Double(mb.getCoords().x,mb.getCoords().y));
368 _backupCenters.add(new Point2D.Double(mb.getCenter().x,mb.getCenter().y));
370 _prevMode = _vp.getDrawMode();
372 public void undo() throws CannotUndoException {
373 RNA r = _vp.getRNA();
374 _vp.setFlatExteriorLoop(_prevFlat);
375 r.setDrawMode(_prevMode);
376 for (int index =0;index<_vp.getRNA().get_listeBases().size();index++)
378 Point2D.Double oldCoord = _backupCoords.get(index);
379 Point2D.Double oldCenter = _backupCenters.get(index);
380 r.setCoord(index, oldCoord);
381 r.setCenter(index, oldCenter);
385 public void redo() throws CannotRedoException {
387 _vp.setFlatExteriorLoop(_newFlat);
388 _vp.getRNA().drawRNA(_newMode,_vp.getConfig());
389 } catch (ExceptionNAViewAlgorithm e) {
394 public boolean canUndo() { return true; }
395 public boolean canRedo() { return true; }
396 public String getPresentationName() { return "Redraw whole RNA";}
397 public boolean addEdit(UndoableEdit anEdit)