Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Eclipse Projects » Eclipse Platform » How to make a TextEditor know an external file is undo clean?
How to make a TextEditor know an external file is undo clean? [message #535299] Fri, 21 May 2010 22:43 Go to next message
Jeff Johnston is currently offline Jeff Johnston
Messages: 173
Registered: July 2009
Senior Member
I have a number of editors based on TextEditor. They support opening files on my local file system (i.e. not in the workspace) via the File menu.

The problem is that they never realize when undo actions are exhausted and take the file back to its saved condition. The file keeps a "*" beside it and will ask to save when the editor is closed.

I tried looking at a number of editors out there like the C and Java editors and they all support external files like mine but exhibit the same behaviour on undo.

So, what would be the best way to add support for this?

Ideally it would be nice if I could determine if the undo list for edit buffer changes was exhausted. Would that be doable?.

A brute force method might be to enhance the canSaveDocument() method of the document provider to compare the document to its original contents but I'm not at all thrilled with the idea.
.
Any suggestions? Any sample working editors out there I could look at?
Re: How to make a TextEditor know an external file is undo clean? [message #538061 is a reply to message #535299] Fri, 04 June 2010 18:35 Go to previous messageGo to next message
Jeff Johnston is currently offline Jeff Johnston
Messages: 173
Registered: July 2009
Senior Member
I came up with a solution using my brute force alternative discussed below if anybody is interested.

The following is what I added to my document provider which extends TextFileDocumentProvider.

The added logic basically keeps track of the document length and does a comparison with the saved file if the length is the same and the parent document provider doesn't think it is clean. The length of the document is stored on initial connect and when ever the document gets saved. I couldn't override the saveDocument method itself to update the length of the saved document because it is marked final so I got around this by overriding the createSaveOperation which is called by saveDocument and then added the setLength call in the run method.

The patch has the interesting side-effect of marking the file as clean even if the file gets there via edits (e.g. you add some blanks, then delete them away so the file is back to its original state).

If there is a better way to do this or something is wrong in the code below, I'm all ears. Otherwise, maybe this logic or some form of it could be added to the StorageDocumentProvider which gets used by the TextFileDocumentProvider for external files.

	private int originalLength;

	private void setDocumentLength(Object element) {
		IDocument doc = getDocument(element);
		originalLength = doc.getLength();
	}
	/*
	 * @see org.eclipse.ui.texteditor.IDocumentProvider#connect(java.lang.Object)
	 */
	@Override
	public void connect(Object element) throws CoreException {
		super.connect(element);
		setDocumentLength(element);
	}
	
	/*
	 * @see org.eclipse.ui.texteditor.IDocumentProvider#canSaveDocument(java.lang.Object)
	 */
	@Override
	public boolean canSaveDocument(Object element) {
		if (element instanceof FileStoreEditorInput) {
			FileStoreEditorInput fei = (FileStoreEditorInput)element;
			IDocument doc = getDocument(element);
			if (!super.canSaveDocument(element))
				return false;
			if (doc.getLength() != originalLength)
				return true;
			URI uri = fei.getURI();
			File f = URIUtil.toFile(uri);
			try {
				BufferedReader input = new BufferedReader(new FileReader(f));
				boolean finished = false;
				char[] buffer = new char[100];
				int curoffset = 0;
				while (!finished) {
					int len = input.read(buffer);
					if (len <= 0)
						break;
					String origbytes = new String(buffer, 0, len);
					String curbytes = doc.get(curoffset, len);
					if (!curbytes.equals(origbytes))
						return true;
					curoffset += len;
				}
				resetDocument(element);
				return false;
			} catch (Exception e) {
				return true;
			}
		}
		return super.canSaveDocument(element);
	}
	/*
	 * @see org.eclipse.ui.texteditor.IDocumentProvider#createSaveOperation(java.lang.Object, org.eclipse.jface.text.IDocument, boolean)
	 */
	@Override
	protected DocumentProviderOperation createSaveOperation(final Object element, final IDocument document, final boolean overwrite) throws CoreException {
		final DocumentProviderOperation saveOperation = super.createSaveOperation(element, document, overwrite);
		if (element instanceof IURIEditorInput) {
			return new DocumentProviderOperation() {
				/*
				 * @see org.eclipse.ui.editors.text.TextFileDocumentProvider.DocumentProviderOperation#execute(org.eclipse.core.runtime.IProgressMonitor)
				 */
				@Override
				public void execute(IProgressMonitor monitor) throws CoreException {
				}

				/*
				 * @see org.eclipse.jface.operation.IRunnableWithProgress#run(org.eclipse.core.runtime.IProgressMonitor)
				 */
				@Override
				public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
					saveOperation.run(monitor);
					// Here's where we sneak in resetting the original document length
					setDocumentLength(element);
				}

				/*
				 * @see org.eclipse.ui.editors.text.TextFileDocumentProvider.DocumentProviderOperation#getSchedulingRule()
				 */
				@Override
				public ISchedulingRule getSchedulingRule() {
					return saveOperation.getSchedulingRule();
				}
			};
		}
		return saveOperation;
	}

Re: How to make a TextEditor know an external file is undo clean? [message #539908 is a reply to message #535299] Mon, 14 June 2010 09:19 Go to previous message
Dani Megert is currently offline Dani Megert
Messages: 3801
Registered: July 2009
Senior Member
Jeff Johnston wrote:
> I have a number of editors based on TextEditor. They support opening
> files on my local file system (i.e. not in the workspace) via the File
> menu.
> The problem is that they never realize when undo actions are exhausted
> and take the file back to its saved condition. The file keeps a "*"
> beside it and will ask to save when the editor is closed.
FYI, see https://bugs.eclipse.org/bugs/show_bug.cgi?id=214351

Dani
>
> I tried looking at a number of editors out there like the C and Java
> editors and they all support external files like mine but exhibit the
> same behaviour on undo.
>
> So, what would be the best way to add support for this?
> Ideally it would be nice if I could determine if the undo list for
> edit buffer changes was exhausted. Would that be doable?.
>
> A brute force method might be to enhance the canSaveDocument() method
> of the document provider to compare the document to its original
> contents but I'm not at all thrilled with the idea.
Previous Topic:SourceViewer.setEditable() or disabled EditorParts
Next Topic:Highlight Text in Java Editor
Goto Forum:
  


Current Time: Fri Oct 24 20:41:02 GMT 2014

Powered by FUDForum. Page generated in 0.01957 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software