KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > pde > internal > ui > editor > ModelUndoManager


1 /*******************************************************************************
2  * Copyright (c) 2000, 2006 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  *******************************************************************************/

11 package org.eclipse.pde.internal.ui.editor;
12 import java.util.List JavaDoc;
13 import java.util.Vector JavaDoc;
14
15 import org.eclipse.jface.action.IAction;
16 import org.eclipse.osgi.util.NLS;
17 import org.eclipse.pde.core.IModelChangeProvider;
18 import org.eclipse.pde.core.IModelChangedEvent;
19 import org.eclipse.pde.core.IModelChangedListener;
20 import org.eclipse.pde.internal.ui.PDEUIMessages;
21 import org.eclipse.ui.forms.editor.IFormPage;
22
23 public abstract class ModelUndoManager
24     implements IModelUndoManager, IModelChangedListener {
25     private boolean ignoreChanges;
26     private List JavaDoc operations;
27     private int undoLevelLimit = 10;
28     private int cursor = -1;
29     private IAction undoAction;
30     private IAction redoAction;
31     private PDEFormEditor editor;
32     
33     public ModelUndoManager(PDEFormEditor editor) {
34         this.editor = editor;
35         operations = new Vector JavaDoc();
36     }
37
38     /*
39      * @see IModelUndoManager#connect(IModelChangeProvider)
40      */

41     public void connect(IModelChangeProvider provider) {
42         provider.addModelChangedListener(this);
43         if (operations==null) initialize();
44     }
45
46     /*
47      * @see IModelUndoManager#disconnect(IModelChangeProvider)
48      */

49     public void disconnect(IModelChangeProvider provider) {
50         provider.removeModelChangedListener(this);
51     }
52
53     private void initialize() {
54         operations = new Vector JavaDoc();
55         cursor = -1;
56         updateActions();
57     }
58
59     /*
60      * @see IModelUndoManager#isUndoable()
61      */

62     public boolean isUndoable() {
63         return cursor>=0;
64     }
65
66     /*
67      * @see IModelUndoManager#isRedoable()
68      */

69     public boolean isRedoable() {
70         if (operations == null) initialize();
71         return (cursor+1)<operations.size();
72     }
73
74     /*
75      * @see IModelUndoManager#undo()
76      */

77     public void undo() {
78         IModelChangedEvent op = getCurrentOperation();
79         if (op==null) return;
80         ignoreChanges = true;
81         openRelatedPage(op);
82         execute(op, true);
83         cursor --;
84         updateActions();
85         ignoreChanges = false;
86     }
87
88     /*
89      * @see IModelUndoManager#redo()
90      */

91     public void redo() {
92         cursor ++;
93         IModelChangedEvent op = getCurrentOperation();
94         if (op==null) return;
95         ignoreChanges = true;
96         openRelatedPage(op);
97         execute(op, false);
98         ignoreChanges = false;
99         updateActions();
100     }
101     
102     protected abstract String JavaDoc getPageId(Object JavaDoc object);
103     
104     protected abstract void execute(IModelChangedEvent op, boolean undo);
105     
106     private void openRelatedPage(IModelChangedEvent op) {
107         Object JavaDoc obj = op.getChangedObjects()[0];
108         String JavaDoc pageId = getPageId(obj);
109         if (pageId!=null) {
110             IFormPage cpage = editor.getActivePageInstance();
111             IFormPage newPage = editor.findPage(pageId);
112             if (cpage != newPage)
113                 editor.setActivePage(newPage.getId());
114         }
115     }
116
117     /*
118      * @see IModelChangedListener#modelChanged(IModelChangedEvent)
119      */

120     public void modelChanged(IModelChangedEvent event) {
121         if (ignoreChanges)
122             return;
123             
124         if (event.getChangeType()==IModelChangedEvent.WORLD_CHANGED) {
125             initialize();
126             return;
127         }
128         addOperation(event);
129     }
130     
131     private IModelChangedEvent getCurrentOperation() {
132         if (cursor == -1 || cursor == operations.size()) return null;
133         return (IModelChangedEvent)operations.get(cursor);
134     }
135     
136     private IModelChangedEvent getNextOperation() {
137         int peekCursor = cursor+1;
138         if (peekCursor >= operations.size()) return null;
139         return (IModelChangedEvent)operations.get(peekCursor);
140     }
141     
142     private void addOperation(IModelChangedEvent operation) {
143         operations.add(operation);
144         int size = operations.size();
145         if (size > undoLevelLimit) {
146             int extra = size-undoLevelLimit;
147             // trim
148
for (int i=0; i<extra; i++) {
149                 operations.remove(i);
150             }
151         }
152         cursor = operations.size() -1;
153         updateActions();
154     }
155     
156     public void setActions(IAction undoAction, IAction redoAction) {
157         this.undoAction = undoAction;
158         this.redoAction = redoAction;
159         updateActions();
160     }
161     
162     private void updateActions() {
163         if (undoAction!=null && redoAction!=null) {
164             undoAction.setEnabled(isUndoable());
165             undoAction.setText(getUndoText());
166             redoAction.setEnabled(isRedoable());
167             redoAction.setText(getRedoText());
168         }
169     }
170     
171     private String JavaDoc getUndoText() {
172         IModelChangedEvent op = getCurrentOperation();
173         if (op == null) {
174             return PDEUIMessages.UpdateManager_noUndo;
175         }
176         return NLS.bind(PDEUIMessages.UpdateManager_undo, getOperationText(op));
177     }
178
179     private String JavaDoc getRedoText() {
180         IModelChangedEvent op = getNextOperation();
181         if (op == null) {
182             return PDEUIMessages.UpdateManager_noRedo;
183         }
184         return NLS.bind(PDEUIMessages.UpdateManager_redo, getOperationText(op));
185     }
186         
187     private String JavaDoc getOperationText(IModelChangedEvent op) {
188         String JavaDoc opText=""; //$NON-NLS-1$
189
switch (op.getChangeType()) {
190             case IModelChangedEvent.INSERT:
191             opText = PDEUIMessages.UpdateManager_op_add;
192             break;
193             case IModelChangedEvent.REMOVE:
194             opText = PDEUIMessages.UpdateManager_op_remove;
195             break;
196             case IModelChangedEvent.CHANGE:
197             opText = PDEUIMessages.UpdateManager_op_change;
198             break;
199         }
200         return opText;
201     }
202     
203     public void setUndoLevelLimit(int limit) {
204         this.undoLevelLimit = limit;
205     }
206
207     public void setIgnoreChanges(boolean ignore) {
208         this.ignoreChanges = ignore;
209     }
210 }
211
Popular Tags