Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
[cdt-patch] Working Copy in cdt.ui

Index: ChangeLog
===================================================================
RCS file: /home/tools/org.eclipse.cdt.ui/ChangeLog,v
retrieving revision 1.71
diff -u -r1.71 ChangeLog
--- ChangeLog	13 Mar 2003 20:32:26 -0000	1.71
+++ ChangeLog	19 Mar 2003 20:03:27 -0000
@@ -1,3 +1,16 @@
+2003-03-19 Alain Magloire
+
+	Patch From Amer Hoda, to use the Working Copy of ICElement use in
+	the Core Model.
+
+	* src/org/eclipse/cdt/internal/ui/editor/CContentOutlinePage.java:
+	* src/org/eclipse/cdt/internal/ui/editor/CDocumentProvider.java:
+	* src/org/eclipse/cdt/internal/ui/editor/DocumentAdapter.java:
+	* src/org/eclipse/cdt/internal/ui/editor/IWorkingCopyManager.java:
+	* src/org/eclipse/cdt/internal/ui/text/CReconcilingStrategy.java:
+	* src/org/eclipse/cdt/internal/ui/CFileWorkingCopy.java:
+	* src/org/eclipse/cdt/ui/CUIPlugin.java:
+
 2003-03-13 Alain Magloire
 
 	* src/org/eclipse/cdt/utils/ui/controls/RadioButton.java:
Index: src/org/eclipse/cdt/internal/ui/CFileElementWorkingCopy.java
===================================================================
RCS file: /home/tools/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/CFileElementWorkingCopy.java,v
retrieving revision 1.2
diff -u -r1.2 CFileElementWorkingCopy.java
--- src/org/eclipse/cdt/internal/ui/CFileElementWorkingCopy.java	6 Feb 2003 20:48:31 -0000	1.2
+++ src/org/eclipse/cdt/internal/ui/CFileElementWorkingCopy.java	19 Mar 2003 20:03:27 -0000
@@ -7,19 +7,17 @@
  
 import java.io.IOException;
 
+import org.eclipse.cdt.internal.core.model.WorkingCopy;
+import org.eclipse.core.resources.IStorage;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.Path;
 import org.eclipse.jface.text.IDocument;
+import org.eclipse.ui.IEditorInput;
 import org.eclipse.ui.IFileEditorInput;
 import org.eclipse.ui.IStorageEditorInput;
-import org.eclipse.ui.IEditorInput;
 import org.eclipse.ui.texteditor.IDocumentProvider;
 
-import org.eclipse.core.resources.IStorage;
-import org.eclipse.core.runtime.Path;
-import org.eclipse.core.runtime.CoreException;
-
-import org.eclipse.cdt.internal.core.model.TranslationUnit;
-
-public class CFileElementWorkingCopy extends TranslationUnit {
+public class CFileElementWorkingCopy extends WorkingCopy {
 	
 	private IDocumentProvider fProvider;
 	//private IFileEditorInput input;
@@ -29,7 +27,7 @@
 	 * Creates a working copy of this element
 	 */
 	public CFileElementWorkingCopy(IFileEditorInput fileInput, IDocumentProvider provider) throws CoreException {
-		super(null, fileInput.getFile());
+		super(null, fileInput.getFile(), null);
 		input= fileInput;
 		fProvider= provider;
 	}
@@ -38,7 +36,7 @@
 	 * Creates a working copy of this element
 	 */
 	public CFileElementWorkingCopy(IStorageEditorInput StoreInput, IDocumentProvider provider) throws CoreException {
-		super(null, new Path(StoreInput.getName()));
+		super(null, new Path(StoreInput.getName()), null);
 		input = StoreInput;
 		fProvider = provider;
 		IStorage storage = StoreInput.getStorage();
Index: src/org/eclipse/cdt/internal/ui/editor/CContentOutlinePage.java
===================================================================
RCS file: /home/tools/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/CContentOutlinePage.java,v
retrieving revision 1.6
diff -u -r1.6 CContentOutlinePage.java
--- src/org/eclipse/cdt/internal/ui/editor/CContentOutlinePage.java	6 Feb 2003 20:48:31 -0000	1.6
+++ src/org/eclipse/cdt/internal/ui/editor/CContentOutlinePage.java	19 Mar 2003 20:03:28 -0000
@@ -8,11 +8,16 @@
 import java.util.ArrayList;
 import java.util.Iterator;
 
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Control;
-import org.eclipse.swt.widgets.Menu;
-
+import org.eclipse.cdt.core.model.ICElement;
+import org.eclipse.cdt.internal.core.model.WorkingCopy;
+import org.eclipse.cdt.internal.ui.CFileElementWorkingCopy;
+import org.eclipse.cdt.internal.ui.StandardCElementLabelProvider;
+import org.eclipse.cdt.internal.ui.util.ProblemTreeViewer;
+import org.eclipse.cdt.ui.CElementContentProvider;
+import org.eclipse.cdt.ui.CUIPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
 import org.eclipse.jface.action.IMenuListener;
 import org.eclipse.jface.action.IMenuManager;
 import org.eclipse.jface.action.IToolBarManager;
@@ -25,29 +30,21 @@
 import org.eclipse.jface.viewers.SelectionChangedEvent;
 import org.eclipse.jface.viewers.StructuredSelection;
 import org.eclipse.jface.viewers.TreeViewer;
-
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Menu;
 import org.eclipse.ui.IActionBars;
+import org.eclipse.ui.IEditorInput;
 import org.eclipse.ui.IFileEditorInput;
 import org.eclipse.ui.IStorageEditorInput;
-import org.eclipse.ui.IEditorInput;
 import org.eclipse.ui.part.Page;
 import org.eclipse.ui.texteditor.IDocumentProvider;
-
 import org.eclipse.ui.views.contentoutline.IContentOutlinePage;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.Status;
-import org.eclipse.core.runtime.IStatus;
-
-import org.eclipse.cdt.core.model.ICElement;
-import org.eclipse.cdt.internal.ui.CFileElementWorkingCopy;
-import org.eclipse.cdt.internal.ui.StandardCElementLabelProvider;
-import org.eclipse.cdt.internal.ui.util.ProblemTreeViewer;
-import org.eclipse.cdt.ui.CElementContentProvider;
-import org.eclipse.cdt.ui.CUIPlugin;
 
 public class CContentOutlinePage extends Page implements IContentOutlinePage, ISelectionChangedListener {
 	private CEditor fEditor;
-	private CFileElementWorkingCopy fInput;
+	private WorkingCopy fInput;
 	private ProblemTreeViewer treeViewer;
 	private ListenerList selectionChangedListeners = new ListenerList();
 	
@@ -73,7 +70,8 @@
 	public void contentUpdated() {
 		if (fInput != null) {
 			try {
-				fInput.update();
+				//fInput.update();
+				fInput.reconcile();				
 			} catch (CoreException e) {
 				CUIPlugin.getDefault().log(e.getStatus());
 				fInput= null;
@@ -154,13 +152,15 @@
 		IEditorInput editorInput= (IEditorInput)fEditor.getEditorInput();
 		IDocumentProvider provider= fEditor.getDocumentProvider();
 		try {
-			if (editorInput instanceof IFileEditorInput)
-				//fInput = ((CUIPlugin.ElementFactory)plugin.getCCore()).createWorkingCopy((IFileEditorInput)editorInput, provider);
-				fInput = new CFileElementWorkingCopy((IFileEditorInput)editorInput, provider);
-			else if (editorInput instanceof IStorageEditorInput)
+			if (editorInput instanceof IFileEditorInput){				
+				//fInput = new CFileElementWorkingCopy((IFileEditorInput)editorInput, provider);
+				IWorkingCopyManager wcManager = CUIPlugin.getDefault().getWorkingCopyManager();
+				fInput = (WorkingCopy)wcManager.getWorkingCopy(editorInput);
+			} else if (editorInput instanceof IStorageEditorInput){
+				// CHECKPOINT: do we create a CFileElementWorkingCopy or just a working copy for the IStorageEditorInput?
 				//fInput = ((CUIPlugin.ElementFactory)plugin.getCCore()).createWorkingCopy((IStorageEditorInput)editorInput, provider);
 				fInput = new CFileElementWorkingCopy((IStorageEditorInput)editorInput, provider);
-			else
+			} else
 				throw new CoreException(new Status(IStatus.ERROR, CUIPlugin.PLUGIN_ID, 0, "no Editor Input", null));
 
 			treeViewer.setInput(fInput);
Index: src/org/eclipse/cdt/internal/ui/editor/CDocumentProvider.java
===================================================================
RCS file: /home/tools/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/CDocumentProvider.java,v
retrieving revision 1.8
diff -u -r1.8 CDocumentProvider.java
--- src/org/eclipse/cdt/internal/ui/editor/CDocumentProvider.java	2 Jan 2003 21:46:52 -0000	1.8
+++ src/org/eclipse/cdt/internal/ui/editor/CDocumentProvider.java	19 Mar 2003 20:03:28 -0000
@@ -5,23 +5,44 @@
  * All Rights Reserved.
  */
 
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.eclipse.cdt.core.model.CModelException;
+import org.eclipse.cdt.core.model.CoreModel;
+import org.eclipse.cdt.core.model.ICOpenable;
+import org.eclipse.cdt.core.model.ITranslationUnit;
+import org.eclipse.cdt.internal.core.model.IBuffer;
+import org.eclipse.cdt.internal.core.model.IBufferFactory;
+import org.eclipse.cdt.internal.core.model.IWorkingCopy;
+import org.eclipse.cdt.internal.ui.CStatusConstants;
 import org.eclipse.cdt.ui.CUIPlugin;
+import org.eclipse.core.resources.IFile;
 import org.eclipse.core.resources.IResource;
 import org.eclipse.core.resources.IStorage;
+import org.eclipse.core.resources.ResourcesPlugin;
 import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
 import org.eclipse.jface.text.AbstractDocument;
 import org.eclipse.jface.text.DefaultLineTracker;
+import org.eclipse.jface.text.Document;
 import org.eclipse.jface.text.GapTextStore;
 import org.eclipse.jface.text.IDocument;
 import org.eclipse.jface.text.IDocumentExtension;
 import org.eclipse.jface.text.IDocumentListener;
 import org.eclipse.jface.text.IDocumentPartitioner;
 import org.eclipse.jface.text.source.IAnnotationModel;
+import org.eclipse.ui.IEditorInput;
 import org.eclipse.ui.IFileEditorInput;
 import org.eclipse.ui.IStorageEditorInput;
 import org.eclipse.ui.editors.text.FileDocumentProvider;
+import org.eclipse.ui.part.FileEditorInput;
+import org.eclipse.ui.texteditor.AbstractMarkerAnnotationModel;
 
-public class CDocumentProvider extends FileDocumentProvider {
+public class CDocumentProvider extends FileDocumentProvider implements IWorkingCopyManager {
 
 	static private class RegisteredReplace {
 		IDocumentListener fOwner;
@@ -63,6 +84,74 @@
 	};
 	
 	/**
+	 * Bundle of all required informations to allow working copy management. 
+	 */
+	protected class TranslationUnitFileInfo extends FileInfo {
+			
+		IWorkingCopy fCopy;
+			
+		TranslationUnitFileInfo(IDocument document, IAnnotationModel model, FileSynchronizer fileSynchronizer, IWorkingCopy copy) {
+			super(document, model, fileSynchronizer);
+			fCopy= copy;
+		}
+			
+		void setModificationStamp(long timeStamp) {
+			fModificationStamp= timeStamp;
+		}
+	};
+	/**
+	 * Creates <code>IBuffer</code>s based on documents.
+	 */
+	protected class BufferFactory implements IBufferFactory {
+			
+		private IDocument internalGetDocument(IFileEditorInput input) throws CoreException {
+			IDocument document= getDocument(input);
+			if (document != null)
+				return document;
+			return CDocumentProvider.this.createDocument(input);
+		}
+			
+		public IBuffer createBuffer(ICOpenable owner) {
+			try {
+				if (owner instanceof IWorkingCopy) {
+						
+					IWorkingCopy unit= (IWorkingCopy) owner;
+					ITranslationUnit original= (ITranslationUnit) unit.getOriginalElement();
+					IResource resource= original.getResource();
+					if (resource instanceof IFile) {
+						IFileEditorInput providerKey= new FileEditorInput((IFile) resource);
+							
+						IDocument document= null;
+						IStatus status= null;
+							
+						try {
+							document= internalGetDocument(providerKey);
+						} catch (CoreException x) {
+							status= x.getStatus();
+							document= new Document();
+							initializeDocument(document);
+						}
+							
+						DocumentAdapter adapter= new DocumentAdapter(unit, document, new DefaultLineTracker(), CDocumentProvider.this, providerKey);
+						adapter.setStatus(status);
+						return adapter;
+					}
+							
+				}
+			} catch (CModelException e) {
+				return DocumentAdapter.NULL;				
+			}
+			return DocumentAdapter.NULL;
+		}
+	};
+
+
+	/** The buffer factory */
+	private IBufferFactory fBufferFactory= new BufferFactory();
+	/** Indicates whether the save has been initialized by this provider */
+	private boolean fIsAboutToSave= false;
+
+	/**
 	 * @see AbstractDocumentProvider#createDocument(Object)
 	 */ 
 	protected IDocument createDocument(Object element) throws CoreException {
@@ -77,11 +166,7 @@
 			return null;
 		}
 		//IDocument document= super.createDocument(element);
-		if (document != null) {
-			IDocumentPartitioner partitioner= CUIPlugin.getDefault().getTextTools().createDocumentPartitioner();
-			partitioner.connect(document);
-			document.setDocumentPartitioner(partitioner);
-		}
+		initializeDocument(document);
 		return document;
 	}
 	
@@ -103,4 +188,214 @@
 		
 		return super.createAnnotationModel(element);
 	}
+	
+	/*
+	 * @see AbstractDocumentProvider#createElementInfo(Object)
+	 */
+	protected ElementInfo createElementInfo(Object element) throws CoreException {
+		if ( !(element instanceof IFileEditorInput))
+			return super.createElementInfo(element);
+			
+		IFileEditorInput input= (IFileEditorInput) element;
+		ITranslationUnit original= createTranslationUnit(input.getFile());
+		if (original != null) {
+				
+			try {
+								
+				try {
+					refreshFile(input.getFile());
+				} catch (CoreException x) {
+					handleCoreException(x, CEditorMessages.getString("TranslationUnitDocumentProvider.error.createElementInfo")); //$NON-NLS-1$
+				}
+				
+				IAnnotationModel m= createAnnotationModel(input);
+				IWorkingCopy c= (IWorkingCopy) original.getSharedWorkingCopy(getProgressMonitor(), fBufferFactory);
+				
+				DocumentAdapter a= null;
+				try {
+					a= (DocumentAdapter) c.getBuffer();
+				} catch (ClassCastException x) {
+					IStatus status= new Status(IStatus.ERROR, CUIPlugin.PLUGIN_ID, CStatusConstants.TEMPLATE_IO_EXCEPTION, "Shared working copy has wrong buffer", x); //$NON-NLS-1$
+					throw new CoreException(status);
+				}
+				
+				FileSynchronizer f= new FileSynchronizer(input); 
+				f.install();
+				
+				TranslationUnitFileInfo info= new TranslationUnitFileInfo(a.getDocument(), m, f, c);
+				info.setModificationStamp(computeModificationStamp(input.getFile()));
+				info.fStatus= a.getStatus();
+				info.fEncoding= getPersistedEncoding(input);
+								
+				return info;
+				
+			} catch (CModelException x) {
+				throw new CoreException(x.getStatus());
+			}
+		} else {		
+			return super.createElementInfo(element);
+		}
+	}
+	/*
+	 * Creates a translation unit using the core model
+	 */
+	protected ITranslationUnit createTranslationUnit(IFile file) {
+		Object element= CoreModel.getDefault().create(file);
+		if (element instanceof ITranslationUnit)
+			return (ITranslationUnit) element;
+		return null;
+	}
+	/*
+	 * @see AbstractDocumentProvider#disposeElementInfo(Object, ElementInfo)
+	 */
+	protected void disposeElementInfo(Object element, ElementInfo info) {
+		
+		if (info instanceof TranslationUnitFileInfo) {
+			TranslationUnitFileInfo cuInfo= (TranslationUnitFileInfo) info;
+			cuInfo.fCopy.destroy();
+		}
+		
+		super.disposeElementInfo(element, info);
+	}
+
+	/*
+	 * @see AbstractDocumentProvider#doSaveDocument(IProgressMonitor, Object, IDocument, boolean)
+	 */
+	protected void doSaveDocument(IProgressMonitor monitor, Object element, IDocument document, boolean overwrite) throws CoreException {
+
+		ElementInfo elementInfo= getElementInfo(element);		
+		if (elementInfo instanceof TranslationUnitFileInfo) {
+			TranslationUnitFileInfo info= (TranslationUnitFileInfo) elementInfo;
+			
+			// update structure, assumes lock on info.fCopy
+			info.fCopy.reconcile();
+			
+			ITranslationUnit original= (ITranslationUnit) info.fCopy.getOriginalElement();
+			IResource resource= original.getResource();
+			
+			if (resource == null) {
+				// underlying resource has been deleted, just recreate file, ignore the rest
+				super.doSaveDocument(monitor, element, document, overwrite);
+				return;
+			}
+			
+			if (resource != null && !overwrite)
+				checkSynchronizationState(info.fModificationStamp, resource);
+				
+//			if (fSavePolicy != null)
+//				fSavePolicy.preSave(info.fCopy);
+			
+			// inform about the upcoming content change
+			fireElementStateChanging(element);	
+			try {
+				fIsAboutToSave= true;
+				// commit working copy
+				info.fCopy.commit(overwrite, monitor);
+			} catch (CoreException x) {
+				// inform about the failure
+				fireElementStateChangeFailed(element);
+				throw x;
+			} catch (RuntimeException x) {
+				// inform about the failure
+				fireElementStateChangeFailed(element);
+				throw x;
+			} finally {
+				fIsAboutToSave= false;
+			}
+			
+			// If here, the dirty state of the editor will change to "not dirty".
+			// Thus, the state changing flag will be reset.
+			
+			AbstractMarkerAnnotationModel model= (AbstractMarkerAnnotationModel) info.fModel;
+			model.updateMarkers(info.fDocument);
+			
+			if (resource != null)
+				info.setModificationStamp(computeModificationStamp(resource));
+				
+//			if (fSavePolicy != null) {
+//				ICompilationUnit unit= fSavePolicy.postSave(original);
+//				if (unit != null) {
+//					IResource r= unit.getResource();
+//					IMarker[] markers= r.findMarkers(IMarker.MARKER, true, IResource.DEPTH_ZERO);
+//					if (markers != null && markers.length > 0) {
+//						for (int i= 0; i < markers.length; i++)
+//							model.updateMarker(markers[i], info.fDocument, null);
+//					}
+//				}
+//			}
+				
+			
+		} else {
+			super.doSaveDocument(monitor, element, document, overwrite);
+		}		
+	}
+
+	/**
+	 * Gets the BufferFactory.
+	 */
+	public IBufferFactory getBufferFactory() {
+		return fBufferFactory;
+	}
+	/**
+	 * Returns the underlying resource for the given element.
+	 * 
+	 * @param the element
+	 * @return the underlying resource of the given element
+	 */
+	public IResource getUnderlyingResource(Object element) {
+		if (element instanceof IFileEditorInput) {
+			IFileEditorInput input= (IFileEditorInput) element;
+			return input.getFile();
+		}
+		return null;
+	}
+
+	public IWorkingCopy getWorkingCopy(IEditorInput element) {
+		
+		ElementInfo elementInfo= getElementInfo(element);		
+		if (elementInfo instanceof TranslationUnitFileInfo) {
+			TranslationUnitFileInfo info= (TranslationUnitFileInfo) elementInfo;
+			return info.fCopy;
+		}
+		return null;
+	}
+
+	protected void initializeDocument(IDocument document) {
+		if (document != null) {
+			IDocumentPartitioner partitioner= CUIPlugin.getDefault().getTextTools().createDocumentPartitioner();
+			partitioner.connect(document);
+			document.setDocumentPartitioner(partitioner);
+		}
+	}
+	/**
+	 * Saves the content of the given document to the given element.
+	 * This is only performed when this provider initiated the save.
+	 * 
+	 * @param monitor the progress monitor
+	 * @param element the element to which to save
+	 * @param document the document to save
+	 * @param overwrite <code>true</code> if the save should be enforced
+	 */
+	public void saveDocumentContent(IProgressMonitor monitor, Object element, IDocument document, boolean overwrite) throws CoreException {
+		
+		if (!fIsAboutToSave)
+			return;
+		
+		if (element instanceof IFileEditorInput) {
+			IFileEditorInput input= (IFileEditorInput) element;
+			try {
+				String encoding= getEncoding(element);
+				if (encoding == null)
+					encoding= ResourcesPlugin.getEncoding();
+				InputStream stream= new ByteArrayInputStream(document.get().getBytes(encoding));
+				IFile file= input.getFile();
+				file.setContents(stream, overwrite, true, monitor);
+			} catch (IOException x)  {
+				IStatus s= new Status(IStatus.ERROR, CUIPlugin.PLUGIN_ID, IStatus.OK, x.getMessage(), x);
+				throw new CoreException(s);
+			}
+		}
+	}
+
+	
 }
Index: src/org/eclipse/cdt/internal/ui/editor/DocumentAdapter.java
===================================================================
RCS file: src/org/eclipse/cdt/internal/ui/editor/DocumentAdapter.java
diff -N src/org/eclipse/cdt/internal/ui/editor/DocumentAdapter.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ src/org/eclipse/cdt/internal/ui/editor/DocumentAdapter.java	19 Mar 2003 20:03:29 -0000
@@ -0,0 +1,486 @@
+package org.eclipse.cdt.internal.ui.editor;
+
+/**********************************************************************
+ * Copyright (c) 2002,2003 Rational Software Corporation and others.
+ * All rights reserved.   This program and the accompanying materials
+ * are made available under the terms of the Common Public License v0.5
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v05.html
+ * 
+ * Contributors: 
+ * Rational Software - Initial API and implementation
+***********************************************************************/
+
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.cdt.core.model.CModelException;
+import org.eclipse.cdt.core.model.ICOpenable;
+import org.eclipse.cdt.internal.core.model.BufferChangedEvent;
+import org.eclipse.cdt.internal.core.model.IBuffer;
+import org.eclipse.cdt.internal.core.model.IBufferChangedListener;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.DocumentEvent;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IDocumentListener;
+import org.eclipse.jface.text.ILineTracker;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.util.Assert;
+import org.eclipse.swt.widgets.Display;
+
+
+/**
+ * Adapts <code>IDocument</code> to <code>IBuffer</code>. Uses the
+ * same algorithm as the text widget to determine the buffer's line delimiter. 
+ * All text inserted into the buffer is converted to this line delimiter.
+ * This class is <code>public</code> for test purposes only.
+ * 
+ * This class is similar to the JDT DocumentAdapter class.
+ */
+public class DocumentAdapter implements IBuffer, IDocumentListener {
+
+	/**
+	 * Internal implementation of a NULL instanceof IBuffer.
+	 */
+	static private class NullBuffer implements IBuffer {
+			
+		public void addBufferChangedListener(IBufferChangedListener listener) {}
+		
+		public void append(char[] text) {}
+		
+		public void append(String text) {}
+		
+		public void close() {}
+		
+		public char getChar(int position) {
+			return 0;
+		}
+		
+		public char[] getCharacters() {
+			return null;
+		}
+		
+		public String getContents() {
+			return null;
+		}
+		
+		public int getLength() {
+			return 0;
+		}
+		
+		public ICOpenable getOwner() {
+			return null;
+		}
+		
+		public String getText(int offset, int length) {
+			return null;
+		}
+		
+		public IResource getUnderlyingResource() {
+			return null;
+		}
+		
+		public boolean hasUnsavedChanges() {
+			return false;
+		}
+		
+		public boolean isClosed() {
+			return false;
+		}
+		
+		public boolean isReadOnly() {
+			return true;
+		}
+		
+		public void removeBufferChangedListener(IBufferChangedListener listener) {}
+		
+		public void replace(int position, int length, char[] text) {}
+		
+		public void replace(int position, int length, String text) {}
+		
+		public void save(IProgressMonitor progress, boolean force) throws CModelException {}
+		
+		public void setContents(char[] contents) {}
+		
+		public void setContents(String contents) {}
+	};
+		
+	
+	/** NULL implementing <code>IBuffer</code> */
+	public final static IBuffer NULL= new NullBuffer();
+	/*
+	 * @see IBuffer#addBufferChangedListener(IBufferChangedListener)
+	 */
+	public void addBufferChangedListener(IBufferChangedListener listener) {
+		Assert.isNotNull(listener);
+		if (!fBufferListeners.contains(listener))
+			fBufferListeners.add(listener);
+	}
+	/**
+	 *  Executes a document set content call in the ui thread.
+	 */
+	protected class DocumentSetCommand implements Runnable {
+		
+		private String fContents;
+		
+		public void run() {
+			fDocument.set(fContents);
+		}
+	
+		public void set(String contents) {
+			fContents= contents;
+			Display.getDefault().syncExec(this);
+		}
+	};
+	/**
+	 * Executes a document replace call in the ui thread.
+	 */
+	protected class DocumentReplaceCommand implements Runnable {
+		
+		private int fOffset;
+		private int fLength;
+		private String fText;
+		
+		public void run() {
+			try {
+				fDocument.replace(fOffset, fLength, fText);
+			} catch (BadLocationException x) {
+				// ignore
+			}
+		}
+		
+		public void replace(int offset, int length, String text) {
+			fOffset= offset;
+			fLength= length;
+			fText= text;
+			Display.getDefault().syncExec(this);
+		}
+	};
+
+	private ICOpenable fOwner;
+	private IDocument fDocument;
+	private DocumentSetCommand fSetCmd= new DocumentSetCommand();
+	private DocumentReplaceCommand fReplaceCmd= new DocumentReplaceCommand();
+	
+	private Object fProviderKey;
+	private CDocumentProvider fProvider;
+	private String fLineDelimiter;
+	private ILineTracker fLineTracker;
+		
+	private List fBufferListeners= new ArrayList(3);
+	
+	private IStatus fStatus;
+
+	
+	public DocumentAdapter(ICOpenable owner, IDocument document, ILineTracker lineTracker, CDocumentProvider provider, Object providerKey) {
+		
+			Assert.isNotNull(document);
+			Assert.isNotNull(lineTracker);
+		
+			fOwner= owner;
+			fDocument= document;
+			fLineTracker= lineTracker;
+			fProvider= provider;
+			fProviderKey= providerKey;		
+			
+			fDocument.addPrenotifiedDocumentListener(this);
+
+		}
+	/**
+	 * Sets the status of this document adapter.
+	 */
+	public void setStatus(IStatus status) {
+		fStatus= status;
+	}
+	
+	/**
+	 * Returns the status of this document adapter.
+	 */
+	public IStatus getStatus() {
+		return fStatus;
+	}
+	
+	/**
+	 * Returns the adapted document.
+	 * 
+	 * @return the adapted document
+	 */
+	public IDocument getDocument() {
+		return fDocument;
+	}
+	/**
+	 * Returns the line delimiter of this buffer. As a document has a set of
+	 * valid line delimiters, this set must be reduced to size 1.
+	 */
+	protected String getLineDelimiter() {
+		
+		if (fLineDelimiter == null) {
+			
+			try {
+				fLineDelimiter= fDocument.getLineDelimiter(0);
+			} catch (BadLocationException x) {
+			}
+			
+			if (fLineDelimiter == null) {
+				/*
+				 * Follow up fix for: 1GF5UU0: ITPJUI:WIN2000 - "Organize Imports" in java editor inserts lines in wrong format
+				 * The line delimiter must always be a legal document line delimiter.
+				 */
+				String sysLineDelimiter= System.getProperty("line.separator"); //$NON-NLS-1$
+				String[] delimiters= fDocument.getLegalLineDelimiters();
+				Assert.isTrue(delimiters.length > 0);
+				for (int i= 0; i < delimiters.length; i++) {
+					if (delimiters[i].equals(sysLineDelimiter)) {
+						fLineDelimiter= sysLineDelimiter;
+						break;
+					}
+				}
+				
+				if (fLineDelimiter == null) {
+					// system line delimiter is not a legal document line delimiter
+					fLineDelimiter= delimiters[0];
+				}
+			}
+		}
+		
+		return fLineDelimiter;
+	}	
+
+	/**
+	 * Converts the given string to the line delimiter of this buffer.
+	 * This method is <code>public</code> for test purposes only.
+	 */
+	public String normalize(String text) {
+		fLineTracker.set(text);
+		
+		int lines= fLineTracker.getNumberOfLines();
+		if (lines <= 1)
+			return text;
+			
+		StringBuffer buffer= new StringBuffer(text);
+		
+		try {
+			IRegion previous= fLineTracker.getLineInformation(0);
+			for (int i= 1; i < lines; i++) {
+				int lastLineEnd= previous.getOffset() + previous.getLength();
+				int lineStart= fLineTracker.getLineInformation(i).getOffset();
+				fLineTracker.replace(lastLineEnd,  lineStart - lastLineEnd, getLineDelimiter());
+				buffer.replace(lastLineEnd, lineStart, getLineDelimiter());
+				previous= fLineTracker.getLineInformation(i);
+			}
+			
+			// last line
+			String delimiter= fLineTracker.getLineDelimiter(lines -1);
+			if (delimiter != null && delimiter.length() > 0)
+				buffer.replace(previous.getOffset() + previous.getLength(), buffer.length(), getLineDelimiter());
+				
+			return buffer.toString();
+		} catch (BadLocationException x) {
+		}
+		
+		return text;
+	}
+	/**
+	 * @see org.eclipse.cdt.internal.core.model.IBuffer#append(char)
+	 */
+	public void append(char[] text) {
+		append(new String(text));		
+	}
+
+	/**
+	 * @see org.eclipse.cdt.internal.core.model.IBuffer#append(java.lang.String)
+	 */
+	public void append(String text) {
+		fReplaceCmd.replace(fDocument.getLength(), 0, normalize(text));		
+	}
+
+
+	/**
+	 * @see org.eclipse.cdt.internal.core.model.IBuffer#close()
+	 */
+	public void close() {
+		if (isClosed())
+			return;
+			
+		IDocument d= fDocument;
+		fDocument= null;
+		d.removePrenotifiedDocumentListener(this);
+		
+		fireBufferChanged(new BufferChangedEvent(this, 0, 0, null));
+		fBufferListeners.clear();		
+	}
+
+	/**
+	 * @see org.eclipse.cdt.internal.core.model.IBuffer#getChar(int)
+	 */
+	public char getChar(int position) {
+		try {
+			return fDocument.getChar(position);
+		} catch (BadLocationException x) {
+			throw new ArrayIndexOutOfBoundsException();
+		}
+	}
+
+	/**
+	 * @see org.eclipse.cdt.internal.core.model.IBuffer#getCharacters()
+	 */
+	public char[] getCharacters() {
+		String content= getContents();
+		return content == null ? null : content.toCharArray();
+	}
+
+	/**
+	 * @see org.eclipse.cdt.internal.core.model.IBuffer#getContents()
+	 */
+	public String getContents() {
+		return fDocument.get();
+	}
+
+	/**
+	 * @see org.eclipse.cdt.internal.core.model.IBuffer#getLength()
+	 */
+	public int getLength() {
+		return fDocument.getLength();
+	}
+
+	/**
+	 * @see org.eclipse.cdt.internal.core.model.IBuffer#getOwner()
+	 */
+	public ICOpenable getOwner() {
+		return (ICOpenable) fOwner;
+	}
+
+	/**
+	 * @see org.eclipse.cdt.internal.core.model.IBuffer#getText(int, int)
+	 */
+	public String getText(int offset, int length) {
+		try {
+			return fDocument.get(offset, length);
+		} catch (BadLocationException x) {
+			throw new ArrayIndexOutOfBoundsException();
+		}
+	}
+
+	/**
+	 * @see org.eclipse.cdt.internal.core.model.IBuffer#getUnderlyingResource()
+	 */
+	public IResource getUnderlyingResource() {
+		//return null;
+		return fProvider != null ? fProvider.getUnderlyingResource(fProviderKey) : null;
+	}
+
+	/**
+	 * @see org.eclipse.cdt.internal.core.model.IBuffer#hasUnsavedChanges()
+	 */
+	public boolean hasUnsavedChanges() {
+		//return false;
+		return fProvider != null ? fProvider.canSaveDocument(fProviderKey) : false;		
+	}
+
+	/**
+	 * @see org.eclipse.cdt.internal.core.model.IBuffer#isClosed()
+	 */
+	public boolean isClosed() {
+		return fDocument == null;
+	}
+
+	/**
+	 * @see org.eclipse.cdt.internal.core.model.IBuffer#isReadOnly()
+	 */
+	public boolean isReadOnly() {
+		//return false;
+		IResource resource= getUnderlyingResource();
+		return resource == null ? true : resource.isReadOnly();		
+	}
+
+	/*
+	 * @see IBuffer#removeBufferChangedListener(IBufferChangedListener)
+	 */
+	public void removeBufferChangedListener(IBufferChangedListener listener) {
+		Assert.isNotNull(listener);
+		fBufferListeners.remove(listener);
+	}
+	/**
+	 * @see org.eclipse.cdt.internal.core.model.IBuffer#replace(int, int, char)
+	 */
+	public void replace(int position, int length, char[] text) {
+		replace(position, length, new String(text));		
+	}
+
+	/**
+	 * @see org.eclipse.cdt.internal.core.model.IBuffer#replace(int, int, java.lang.String)
+	 */
+	public void replace(int position, int length, String text) {
+		fReplaceCmd.replace(position, length, normalize(text));
+	}
+
+	/**
+	 * @see org.eclipse.cdt.internal.core.model.IBuffer#save(org.eclipse.core.runtime.IProgressMonitor, boolean)
+	 */
+	public void save(IProgressMonitor progress, boolean force) throws CModelException {
+			if (fProvider != null) {
+				try {
+					fProvider.saveDocumentContent(progress, fProviderKey, fDocument, force);
+				} catch (CoreException e) {
+					throw new CModelException(e);
+				}
+			}	
+	}
+
+	/**
+	 * @see org.eclipse.cdt.internal.core.model.IBuffer#setContents(char)
+	 */
+	public void setContents(char[] contents) {
+		setContents(new String(contents));		
+	}
+
+	/**
+	 * @see org.eclipse.cdt.internal.core.model.IBuffer#setContents(java.lang.String)
+	 */
+	public void setContents(String contents) {
+		int oldLength= fDocument.getLength();
+		
+		if (contents == null) {
+			
+			if (oldLength != 0)
+				fSetCmd.set(""); //$NON-NLS-1$
+		
+		} else {
+			
+			// set only if different
+			String newContents= normalize(contents);
+			int newLength= newContents.length();
+			
+			if (oldLength != newLength || !newContents.equals(fDocument.get()))
+				fSetCmd.set(newContents);
+		}
+	}
+	/*
+	 * @see IDocumentListener#documentAboutToBeChanged(DocumentEvent)
+	 */
+	public void documentAboutToBeChanged(DocumentEvent event) {
+		// there is nothing to do here
+	}
+
+	/*
+	 * @see IDocumentListener#documentChanged(DocumentEvent)
+	 */
+	public void documentChanged(DocumentEvent event) {
+		fireBufferChanged(new BufferChangedEvent(this, event.getOffset(), event.getLength(), event.getText()));
+	}
+	
+	private void fireBufferChanged(BufferChangedEvent event) {
+		if (fBufferListeners != null && fBufferListeners.size() > 0) {
+			Iterator e= new ArrayList(fBufferListeners).iterator();
+			while (e.hasNext())
+				((IBufferChangedListener) e.next()).bufferChanged(event);
+		}
+	}
+
+}
Index: src/org/eclipse/cdt/internal/ui/editor/IWorkingCopyManager.java
===================================================================
RCS file: src/org/eclipse/cdt/internal/ui/editor/IWorkingCopyManager.java
diff -N src/org/eclipse/cdt/internal/ui/editor/IWorkingCopyManager.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ src/org/eclipse/cdt/internal/ui/editor/IWorkingCopyManager.java	19 Mar 2003 20:03:29 -0000
@@ -0,0 +1,34 @@
+package org.eclipse.cdt.internal.ui.editor;
+
+/**********************************************************************
+ * Copyright (c) 2002,2003 Rational Software Corporation and others.
+ * All rights reserved.   This program and the accompanying materials
+ * are made available under the terms of the Common Public License v0.5
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v05.html
+ * 
+ * Contributors: 
+ * Rational Software - Initial API and implementation
+***********************************************************************/
+
+import org.eclipse.cdt.internal.core.model.IWorkingCopy;
+import org.eclipse.ui.IEditorInput;
+
+/**
+ * Interface for accessing working copies of <code>ITranslationUnit</code>
+ * objects. The original Translation unit is only given indirectly by means of
+ * an <code>IEditorInput</code>. 
+ * <p>
+ * This interface is not intended to be implemented by clients.
+ * </p>
+ *
+ * @see CUIPlugin#getWorkingCopyManager
+ * 
+ * This interface is similar to the JDT IWorkingCopyManager.
+ */
+
+public interface IWorkingCopyManager {
+
+	IWorkingCopy getWorkingCopy(IEditorInput input);
+
+}
\ No newline at end of file
Index: src/org/eclipse/cdt/internal/ui/text/CReconcilingStrategy.java
===================================================================
RCS file: /home/tools/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/CReconcilingStrategy.java,v
retrieving revision 1.1
diff -u -r1.1 CReconcilingStrategy.java
--- src/org/eclipse/cdt/internal/ui/text/CReconcilingStrategy.java	26 Jun 2002 20:55:44 -0000	1.1
+++ src/org/eclipse/cdt/internal/ui/text/CReconcilingStrategy.java	19 Mar 2003 20:03:29 -0000
@@ -5,12 +5,19 @@
  * All Rights Reserved.
  */
 
+import org.eclipse.cdt.core.model.CModelException;
+import org.eclipse.cdt.internal.core.model.IWorkingCopy;
 import org.eclipse.cdt.internal.ui.editor.CContentOutlinePage;
 import org.eclipse.cdt.internal.ui.editor.CEditor;
+import org.eclipse.cdt.internal.ui.editor.IWorkingCopyManager;
+import org.eclipse.cdt.ui.CUIPlugin;
+import org.eclipse.core.runtime.IProgressMonitor;
 import org.eclipse.jface.text.IDocument;
 import org.eclipse.jface.text.IRegion;
 import org.eclipse.jface.text.reconciler.DirtyRegion;
 import org.eclipse.jface.text.reconciler.IReconcilingStrategy;
+import org.eclipse.ui.texteditor.IDocumentProvider;
+import org.eclipse.ui.texteditor.ITextEditor;
 
 
 public class CReconcilingStrategy implements IReconcilingStrategy {
@@ -18,11 +25,18 @@
 
 	private CContentOutlinePage fOutliner;
 	private int fLastRegionOffset;
+	private ITextEditor fEditor;	
+	private IWorkingCopyManager fManager;
+	private IDocumentProvider fDocumentProvider;
+	private IProgressMonitor fProgressMonitor;
 
 
 	public CReconcilingStrategy(CEditor editor) {
 		fOutliner= editor.getOutlinePage();
 		fLastRegionOffset = Integer.MAX_VALUE;
+		fEditor= editor;
+		fManager= CUIPlugin.getDefault().getWorkingCopyManager();
+		fDocumentProvider= CUIPlugin.getDefault().getDocumentProvider();
 	}
 	
 	/**
@@ -32,6 +46,13 @@
 	}	
 
 
+	/*
+	 * @see IReconcilingStrategyExtension#setProgressMonitor(IProgressMonitor)
+	 */
+	public void setProgressMonitor(IProgressMonitor monitor) {
+		fProgressMonitor= monitor;
+	}
+
 	/**
 	 * @see IReconcilingStrategy#reconcile(region)
 	 */
@@ -57,6 +78,17 @@
 	}
 	
 	private void reconcile() {
-		fOutliner.contentUpdated();
-	}	
+		try {
+			IWorkingCopy workingCopy = fManager.getWorkingCopy(fEditor.getEditorInput());		
+			if (workingCopy != null) {
+				// reconcile
+				synchronized (workingCopy) {
+					workingCopy.reconcile(true, fProgressMonitor);
+				}
+			}
+			fOutliner.contentUpdated();
+		} catch(CModelException e) {
+				
+		}
+ 	}	
 }
Index: src/org/eclipse/cdt/ui/CUIPlugin.java
===================================================================
RCS file: /home/tools/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/CUIPlugin.java,v
retrieving revision 1.6
diff -u -r1.6 CUIPlugin.java
--- src/org/eclipse/cdt/ui/CUIPlugin.java	4 Mar 2003 18:25:43 -0000	1.6
+++ src/org/eclipse/cdt/ui/CUIPlugin.java	19 Mar 2003 20:03:29 -0000
@@ -18,6 +18,7 @@
 import org.eclipse.cdt.internal.ui.ResourceAdapterFactory;
 import org.eclipse.cdt.internal.ui.cview.CView;
 import org.eclipse.cdt.internal.ui.editor.CDocumentProvider;
+import org.eclipse.cdt.internal.ui.editor.IWorkingCopyManager;
 import org.eclipse.cdt.internal.ui.editor.asm.AsmTextTools;
 import org.eclipse.cdt.internal.ui.preferences.BuildConsolePreferencePage;
 import org.eclipse.cdt.internal.ui.preferences.CEditorPreferencePage;
@@ -149,6 +150,14 @@
 			fDocumentProvider = new CDocumentProvider();
 		}
 		return fDocumentProvider;
+	}
+
+	/**
+	 * Returns the working copy manager
+	 * @return IWorkingCopyManager
+	 */
+	public synchronized IWorkingCopyManager getWorkingCopyManager() {
+		return getDocumentProvider();
 	}
 
 	/**



Back to the top