1 11 package org.eclipse.pde.internal.ui.editor; 12 import java.util.List ; 13 import java.util.Vector ; 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 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 (); 36 } 37 38 41 public void connect(IModelChangeProvider provider) { 42 provider.addModelChangedListener(this); 43 if (operations==null) initialize(); 44 } 45 46 49 public void disconnect(IModelChangeProvider provider) { 50 provider.removeModelChangedListener(this); 51 } 52 53 private void initialize() { 54 operations = new Vector (); 55 cursor = -1; 56 updateActions(); 57 } 58 59 62 public boolean isUndoable() { 63 return cursor>=0; 64 } 65 66 69 public boolean isRedoable() { 70 if (operations == null) initialize(); 71 return (cursor+1)<operations.size(); 72 } 73 74 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 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 getPageId(Object object); 103 104 protected abstract void execute(IModelChangedEvent op, boolean undo); 105 106 private void openRelatedPage(IModelChangedEvent op) { 107 Object obj = op.getChangedObjects()[0]; 108 String 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 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 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 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 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 getOperationText(IModelChangedEvent op) { 188 String opText=""; 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 |