How to make a TextEditor know an external file is undo clean? [message #535299] |
Fri, 21 May 2010 18:43  |
Eclipse User |
|
|
|
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 14:35   |
Eclipse User |
|
|
|
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 05:19  |
Eclipse User |
|
|
|
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.
|
|
|
Powered by
FUDForum. Page generated in 0.03994 seconds