001package icy.roi.edit;
002
003import icy.roi.ROI;
004import icy.sequence.Sequence;
005import icy.type.point.Point5D;
006
007import java.util.List;
008import java.util.Set;
009
010import javax.swing.undo.CannotRedoException;
011import javax.swing.undo.CannotUndoException;
012import javax.swing.undo.UndoableEdit;
013
014/**
015 * Multiple position change implementation for ROI undoable edition.
016 * 
017 * @author Stephane
018 */
019public class PositionROIsEdit extends AbstractROIsEdit
020{
021    List<Point5D> previousPositions;
022    List<Point5D> newPositions;
023
024    public PositionROIsEdit(List<? extends ROI> rois, List<Point5D> previousPositions, List<Point5D> newPositions,
025            boolean mergeable)
026    {
027        super(rois, (rois.size() > 1) ? "ROIs position changed" : "ROI position changed");
028
029        if (rois.size() != previousPositions.size())
030            throw new IllegalArgumentException("ROI list and old values list size do not match (" + rois.size()
031                    + " != " + previousPositions.size() + ")");
032        if (rois.size() != newPositions.size())
033            throw new IllegalArgumentException("ROI list and new values list size do not match (" + rois.size()
034                    + " != " + newPositions.size() + ")");
035
036        this.previousPositions = previousPositions;
037        this.newPositions = newPositions;
038
039        setMergeable(mergeable);
040    }
041
042    public PositionROIsEdit(List<? extends ROI> rois, List<Point5D> previousPositions, List<Point5D> newPositions)
043    {
044        this(rois, previousPositions, newPositions, true);
045    }
046
047    @Override
048    public void undo() throws CannotUndoException
049    {
050        super.undo();
051
052        final Set<Sequence> sequences = getSequences();
053
054        // undo
055        for (Sequence sequence : sequences)
056            sequence.beginUpdate();
057        try
058        {
059            int ind = 0;
060            for (ROI roi : getROIs())
061                roi.setPosition5D(previousPositions.get(ind++));
062        }
063        finally
064        {
065            for (Sequence sequence : sequences)
066                sequence.endUpdate();
067        }
068    }
069
070    @Override
071    public void redo() throws CannotRedoException
072    {
073        super.redo();
074
075        final Set<Sequence> sequences = getSequences();
076
077        // redo
078        for (Sequence sequence : sequences)
079            sequence.beginUpdate();
080        try
081        {
082            int ind = 0;
083            for (ROI roi : getROIs())
084                roi.setPosition5D(newPositions.get(ind++));
085        }
086        finally
087        {
088            for (Sequence sequence : sequences)
089                sequence.endUpdate();
090        }
091    }
092
093    @Override
094    public boolean addEdit(UndoableEdit edit)
095    {
096        if (!isMergeable())
097            return false;
098
099        if (edit instanceof PositionROIsEdit)
100        {
101            final PositionROIsEdit posEdit = (PositionROIsEdit) edit;
102
103            // same ROI list ?
104            if (posEdit.getROIs().equals(getROIs()))
105            {
106                // collapse edits
107                newPositions = posEdit.newPositions;
108                return true;
109            }
110        }
111
112        return false;
113    }
114
115    @Override
116    public void die()
117    {
118        super.die();
119
120        previousPositions = null;
121        newPositions = null;
122    }
123}