Back to index

wims  3.65+svn20090927
History.java
Go to the documentation of this file.
00001 /*
00002  * @(#)History.java
00003  *
00004  * $Id: History.java,v 1.26 2002/08/08 05:15:06 huaz Exp $
00005  *
00006  * Created on November 15, 2000, 10:38 PM
00007  */
00008 package SharpTools;
00009 import java.util.*;
00010 import javax.swing.*;
00011 
00033 public class History {
00034 
00039     class ListNode {
00040 
00041        private ListNode prev; // points to previous node
00042        private ListNode next; // points to next node
00043        private int type; // one of the 5 History static values defined below
00044        private Object obj; // could be a SharpClipboard or a CellRange
00045        
00046        ListNode(Object obj) {
00047            setObject(obj);
00048        }
00049 
00050        // simple get/set functions
00051        Object getObject() { return obj; }
00052        ListNode getPrev() { return prev; }    
00053        ListNode getNext() { return next; }
00054        
00055        void setObject(Object obj) { this.obj = obj; }
00056        void setPrev(ListNode prev) { this.prev = prev; }
00057        void setNext(ListNode next) { this.next = next; }
00058        
00059        int getType() { return type; }    
00060        void setType(int type) { this.type = type; }    
00061     }
00062 
00063     private SharpTools sharp;
00064     final public static int UNCHANGED = 0;
00065     final public static int INSERTROW = 1;
00066     final public static int INSERTCOLUMN = 2;
00067     final public static int REMOVEROW = 3;
00068     final public static int REMOVECOLUMN = 4;
00069 
00071     private ListNode current;
00072 
00078     History(SharpTools sharp) {
00079        this.sharp = sharp;
00080        current = new ListNode(null);      
00081     }
00082 
00089     public void add(SharpTableModel model, CellRange range) {
00090        // construct the clipboard to be saved
00091        SharpClipboard clip = new SharpClipboard(model, range, false);
00092         add(model, clip);
00093     }
00094 
00101     public void add(SharpTableModel model, SharpClipboard clip) {
00102        ListNode node = new ListNode(clip);
00103        if (Debug.isDebug())
00104            Debug.println("Add history for range "+clip.getSource());
00105 
00106        // add to the linked list
00107        current.setNext(node);
00108        node.setPrev(current);
00109 
00110        // move current forward
00111        current = node;
00112 
00113        // modified!
00114        // all operations should call add instead of setModified themselves
00115        model.setModified(true);
00116        sharp.checkUndoRedoState();
00117     }
00118 
00119     /*
00120      * This method should only be called with type != UNCHANGED,
00121      * i.e., for table insertion/deletion operations.
00122      *
00123      * @param model the SharpTableModel we operate on
00124      * @param range the cell range the operation will affect
00125      * @param type the operation type
00126      */
00127     public void add(SharpTableModel model, CellRange range, int type) {
00128        SharpClipboard clip;
00129        ListNode node;       
00130 
00131        if (type == UNCHANGED) {
00132            add(model, range);
00133            return;
00134        }
00135            
00136        if (type == REMOVEROW || type == REMOVECOLUMN) {
00137            // save the current range
00138            clip = new SharpClipboard(model, range, false);
00139            node = new ListNode(clip);
00140        }
00141        else {
00142            // for insertion, no data need to be saved
00143            // just save the range value
00144            node = new ListNode(range);
00145        }
00146        
00147        node.setType(type);
00148 
00149        // add to the end of history list
00150        current.setNext(node);
00151        node.setPrev(current);
00152 
00153        // move current forward
00154        current = node;
00155        model.setModified(true);
00156        sharp.checkUndoRedoState();
00157     }
00158 
00164     public void undo(SharpTableModel model) {
00165        if (!isUndoable())
00166            return;
00167 
00168        int type = current.getType();
00169        CellRange range;
00170        
00171        if (type == UNCHANGED) {
00172            // get the saved clipboard and its range
00173            SharpClipboard oldClip = (SharpClipboard)current.getObject();
00174            range = oldClip.getSource();
00175        
00176            // replace the current object with the current table data
00177            SharpClipboard newClip = new SharpClipboard(model, range, false);
00178            current.setObject(newClip);
00179        
00180            // recover the data (undo)
00181            oldClip.paste(model, range.getminCorner());
00182        }
00183        else if (type == REMOVEROW ||
00184                type == REMOVECOLUMN) {
00185            // undo a removal is just do an insertion and paste
00186            // saved data to it
00187            SharpClipboard clip = (SharpClipboard)current.getObject();
00188            range = clip.getSource();
00189            // insert lines first
00190            if (type == REMOVEROW)
00191               model.insertRow(range);
00192            else
00193               model.insertColumn(range);
00194 
00195            // then paste stuff
00196            clip.paste(model, range.getminCorner());
00197        }
00198        else {
00199            // undo an insertion is just a removal
00200            range = (CellRange)current.getObject();
00201            //     System.out.println("Undo: remove "+range);
00202            if (type == INSERTROW)
00203               model.removeRow(range);
00204            else
00205               model.removeColumn(range);
00206        }
00207 
00208        current = current.getPrev();
00209 
00210        // recover the selection
00211        model.setSelection(range);
00212 
00213        /*
00214        if (!isUndoable()) { // has come back to the beginning
00215            model.setModified(false);
00216        }
00217        */
00218        model.setModified(true);
00219        sharp.checkUndoRedoState();
00220     }
00221 
00227     public void redo(SharpTableModel model) {
00228        if (!isRedoable())
00229            return;
00230        
00231        current = current.getNext();
00232        int type = current.getType();
00233        CellRange range;
00234        
00235        if (type == UNCHANGED) {
00236 
00237            // get the saved clipboard
00238            SharpClipboard oldClip = (SharpClipboard)current.getObject();
00239            range = oldClip.getSource();
00240        
00241            // replace the current object with the current model data
00242            SharpClipboard newClip = new SharpClipboard(model, range, false);
00243            current.setObject(newClip);
00244 
00245            // restore data and selection
00246            oldClip.paste(model, range.getminCorner());
00247            model.setSelection(range);
00248        }
00249        else if (type == REMOVEROW ||
00250                type == REMOVECOLUMN) {
00251            // redo a removal
00252            SharpClipboard clip = (SharpClipboard)current.getObject();
00253            range = clip.getSource();
00254            // insert lines first
00255            if (type == REMOVEROW)
00256               model.removeRow(range);
00257            else
00258               model.removeColumn(range);
00259        }
00260        else {
00261            // redo an insertion
00262            range = (CellRange)current.getObject();
00263            
00264            if (type == INSERTROW)
00265               model.insertRow(range);
00266            else
00267               model.insertColumn(range);      
00268        }
00269 
00270        model.setModified(true);
00271        sharp.checkUndoRedoState();
00272     }
00273 
00279     public boolean isUndoable() {
00280        return current.getPrev() != null;
00281     }
00282 
00288     public boolean isRedoable() {
00289        return current.getNext() != null;
00290     }
00291 }
00292