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