|
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 |
Jeff Johnston Messages: 215 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;
}
|
|
|
|
Powered by
FUDForum. Page generated in 0.03155 seconds