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