1 11 package org.eclipse.pde.internal.ui.editor.context; 12 13 import java.util.ArrayList ; 14 import java.util.Enumeration ; 15 import java.util.Hashtable ; 16 17 import org.eclipse.core.resources.IFile; 18 import org.eclipse.core.resources.IProject; 19 import org.eclipse.core.resources.IResource; 20 import org.eclipse.core.resources.IResourceChangeEvent; 21 import org.eclipse.core.resources.IResourceChangeListener; 22 import org.eclipse.core.resources.IResourceDelta; 23 import org.eclipse.core.resources.IResourceDeltaVisitor; 24 import org.eclipse.core.runtime.CoreException; 25 import org.eclipse.core.runtime.IProgressMonitor; 26 import org.eclipse.pde.core.IBaseModel; 27 import org.eclipse.pde.core.IModelChangeProvider; 28 import org.eclipse.pde.internal.ui.PDEPlugin; 29 import org.eclipse.pde.internal.ui.PDEUIMessages; 30 import org.eclipse.pde.internal.ui.editor.IModelUndoManager; 31 import org.eclipse.pde.internal.ui.editor.PDEFormEditor; 32 import org.eclipse.swt.widgets.Display; 33 import org.eclipse.swt.widgets.Shell; 34 import org.eclipse.ui.IEditorInput; 35 import org.eclipse.ui.IFileEditorInput; 36 37 public abstract class InputContextManager implements IResourceChangeListener { 38 private PDEFormEditor editor; 39 private Hashtable inputContexts; 40 private ArrayList monitoredFiles; 41 private ArrayList listeners; 42 private IModelUndoManager undoManager; 43 46 public InputContextManager(PDEFormEditor editor) { 47 this.editor = editor; 48 inputContexts = new Hashtable (); 49 listeners = new ArrayList (); 50 PDEPlugin.getWorkspace().addResourceChangeListener(this, IResourceChangeEvent.POST_CHANGE); 51 } 52 53 public void addInputContextListener(IInputContextListener listener) { 54 if (!listeners.contains(listener)) 55 listeners.add(listener); 56 } 57 public void removeInputContextListener(IInputContextListener listener) { 58 listeners.remove(listener); 59 } 60 64 public void dispose() { 65 PDEPlugin.getWorkspace().removeResourceChangeListener(this); 66 for (Enumeration contexts = inputContexts.elements(); contexts 68 .hasMoreElements();) { 69 InputContext context = (InputContext) contexts.nextElement(); 70 unhookUndo(context); 71 context.dispose(); 72 } 73 inputContexts.clear(); 74 undoManager = null; 75 } 76 80 public void save(IProgressMonitor monitor) { 81 for (Enumeration contexts = inputContexts.elements(); contexts 82 .hasMoreElements();) { 83 InputContext context = (InputContext) contexts.nextElement(); 84 if (context.mustSave()) 85 context.doSave(monitor); 86 } 87 } 88 public IProject getCommonProject() { 89 for (Enumeration contexts = inputContexts.elements(); contexts 90 .hasMoreElements();) { 91 InputContext context = (InputContext) contexts.nextElement(); 92 IEditorInput input = context.getInput(); 93 if (input instanceof IFileEditorInput) 94 return ((IFileEditorInput)input).getFile().getProject(); 95 } 96 return null; 97 } 98 public boolean hasContext(String id) { 99 return findContext(id) != null; 100 } 101 public InputContext findContext(String id) { 102 for (Enumeration contexts = inputContexts.elements(); contexts 103 .hasMoreElements();) { 104 InputContext context = (InputContext) contexts.nextElement(); 105 if (context.getId().equals(id)) 106 return context; 107 } 108 return null; 109 } 110 public InputContext findContext(IResource resource) { 111 for (Enumeration contexts = inputContexts.elements(); contexts 112 .hasMoreElements();) { 113 InputContext context = (InputContext) contexts.nextElement(); 114 if (context.matches(resource)) 115 return context; 116 } 117 return null; 118 } 119 120 public abstract IBaseModel getAggregateModel(); 121 122 public InputContext getContext(IEditorInput input) { 123 return (InputContext)inputContexts.get(input); 124 } 125 public void putContext(IEditorInput input, InputContext context) { 126 inputContexts.put(input, context); 127 fireContextChange(context, true); 128 } 129 130 138 private void updateInputContext(IEditorInput newInput, IEditorInput oldInput) 139 throws Exception { 140 Object value = null; 141 if (inputContexts.containsKey(oldInput)) { 144 value = inputContexts.remove(oldInput); 145 } else { 146 throw new Exception (PDEUIMessages.InputContextManager_errorMessageInputContextNotFound); 147 } 148 inputContexts.put(newInput, value); 151 } 152 153 158 public void saveAs(IProgressMonitor monitor, String contextID) 159 throws Exception { 160 InputContext inputContext = findContext(contextID); 162 if (inputContext != null) { 163 IEditorInput oldInput = editor.getEditorInput(); 165 inputContext.doSaveAs(monitor); 167 IEditorInput newInput = inputContext.getInput(); 169 updateInputContext(newInput, oldInput); 171 } else { 172 throw new Exception (PDEUIMessages.InputContextManager_errorMessageInputContextNotFound); 173 } 174 } 175 176 public InputContext getPrimaryContext() { 177 for (Enumeration contexts = inputContexts.elements(); contexts 178 .hasMoreElements();) { 179 InputContext context = (InputContext) contexts.nextElement(); 180 if (context.isPrimary()) 181 return context; 182 } 183 return null; 184 } 185 public InputContext [] getInvalidContexts() { 186 ArrayList result = new ArrayList (); 187 for (Enumeration contexts = inputContexts.elements(); contexts 188 .hasMoreElements();) { 189 InputContext context = (InputContext) contexts.nextElement(); 190 if (context.isModelCorrect()==false) 191 result.add(context); 192 } 193 return (InputContext[])result.toArray(new InputContext[result.size()]); 194 } 195 196 public boolean isDirty() { 197 for (Enumeration contexts=inputContexts.elements(); contexts.hasMoreElements();) { 198 InputContext context = (InputContext)contexts.nextElement(); 199 if (context.mustSave()) 200 return true; 201 } 202 return false; 203 } 204 205 public void monitorFile(IFile file) { 206 if (monitoredFiles==null) monitoredFiles = new ArrayList (); 207 monitoredFiles.add(file); 208 } 209 212 public void resourceChanged(IResourceChangeEvent event) { 213 IResourceDelta delta = event.getDelta(); 214 215 try { 216 delta.accept(new IResourceDeltaVisitor() { 217 public boolean visit(IResourceDelta delta) { 218 int kind = delta.getKind(); 219 IResource resource = delta.getResource(); 220 if (resource instanceof IFile) { 221 if (kind == IResourceDelta.ADDED) 222 asyncStructureChanged((IFile)resource, true); 223 else if (kind==IResourceDelta.REMOVED) 224 asyncStructureChanged((IFile)resource, false); 225 return false; 226 } 227 return true; 228 } 229 }); 230 } catch (CoreException e) { 231 PDEPlugin.logException(e); 232 } 233 } 234 235 private void asyncStructureChanged(final IFile file, final boolean added) { 236 if (editor == null || editor.getEditorSite() == null) 237 return; 238 Shell shell = editor.getEditorSite().getShell(); 239 Display display = shell != null ? shell.getDisplay() : Display.getDefault(); 240 241 display.asyncExec(new Runnable () { 242 public void run() { 243 structureChanged(file, added); 244 } 245 }); 246 } 247 248 private void structureChanged(IFile file, boolean added) { 249 if (monitoredFiles==null) return; 250 for (int i=0; i<monitoredFiles.size(); i++) { 251 IFile ifile = (IFile)monitoredFiles.get(i); 252 if (ifile.equals(file)) { 253 if (added) { 254 fireStructureChange(file, true); 255 } 256 else { 257 fireStructureChange(file, false); 258 removeContext(file); 259 } 260 } 261 } 262 } 263 264 private void removeContext(IFile file) { 265 for (Enumeration contexts = inputContexts.elements(); contexts 266 .hasMoreElements();) { 267 InputContext context = (InputContext) contexts.nextElement(); 268 IEditorInput input = context.getInput(); 269 if (input instanceof IFileEditorInput) { 270 IFileEditorInput fileInput = (IFileEditorInput)input; 271 if (file.equals(fileInput.getFile())) { 272 inputContexts.remove(input); 273 fireContextChange(context, false); 274 return; 275 } 276 } 277 } 278 } 279 protected void fireStructureChange(IFile file, boolean added) { 280 for (int i=0; i<listeners.size(); i++) { 281 IInputContextListener listener = (IInputContextListener)listeners.get(i); 282 if (added) 283 listener.monitoredFileAdded(file); 284 else 285 listener.monitoredFileRemoved(file); 286 } 287 } 288 protected void fireContextChange(InputContext context, boolean added) { 289 for (int i=0; i<listeners.size(); i++) { 290 IInputContextListener listener = (IInputContextListener)listeners.get(i); 291 if (added) 292 listener.contextAdded(context); 293 else 294 listener.contextRemoved(context); 295 } 296 if (added) 297 hookUndo(context); 298 else 299 unhookUndo(context); 300 } 301 public void undo() { 302 if (undoManager!=null && undoManager.isUndoable()) 303 undoManager.undo(); 304 } 305 306 public void redo() { 307 if (undoManager!=null && undoManager.isRedoable()) 308 undoManager.redo(); 309 } 310 311 private void hookUndo(InputContext context) { 312 if (undoManager==null) return; 313 IBaseModel model = context.getModel(); 314 if (model instanceof IModelChangeProvider) 315 undoManager.connect((IModelChangeProvider)model); 316 } 317 318 private void unhookUndo(InputContext context) { 319 if (undoManager==null) return; 320 IBaseModel model = context.getModel(); 321 if (model instanceof IModelChangeProvider) 322 undoManager.disconnect((IModelChangeProvider)model); 323 } 324 327 public IModelUndoManager getUndoManager() { 328 return undoManager; 329 } 330 333 public void setUndoManager(IModelUndoManager undoManager) { 334 this.undoManager = undoManager; 335 } 336 } 337 | Popular Tags |