2

I'm developing an Eclipse plugin, where I need every editor of the application to be readonly, depending on the path of the contained file (relative to the project).

I've made my own editor class, and been able to override some method to get what I want:

public class MyTextEditor extends TextEditor {

    /**
     * Overridden to inhibit the replace action in find&replace dialog.
     */
    @Override
    public boolean isEditorInputModifiable() {
        if (!super.isEditorInputModifiable()) {
            return false;
        }

        return Utils.checkEditorInputModifiable(getEditorInput());
    }

    /**
     * Overridden to inhibit any user edit in the editor input.
     */
    @Override
    public boolean isEditable() {
        if (!super.isEditable()) {
            return false;
        }

        return Utils.checkEditorInputModifiable(getEditorInput());
    }

How to make read only editor in Eclipse (Eclipse Plugin Development)

But the question is: how to do that on the compare editor??

The editor used by eclipse in each compare dialog is a different editor, I can use my content ContentMergeViewer and set the compareConfiguration as readonly (on one side or both) but this is not sufficient. The compareInput on each side should be made readonly!

Or is there any other more convenient way to achive what I want??

Thank you!

greg-449
  • 109,219
  • 232
  • 102
  • 145
Gionata
  • 133
  • 11
  • How is it 'not sufficient'? Calling setLeftEditable(false) and setRightEditable(false) on the CompareConfiguration looks like it stops editing. – greg-449 Dec 06 '19 at 07:49
  • It is not enough... the two small arrow in the middle of the compare will disapear for the side that is readonly.. so ok. But the buttons on the top bar, to copy differences from one side to the other, are still enabled! You have to implement `IEditableContent` interface on the compare input object, the isEditable() method. I did on a custom compare dialog, but in this case Eclipse use it's own dialog and compare infrastructure.. so I don't now how to do it.. – Gionata Dec 06 '19 at 07:56

1 Answers1

0

I have a possible solution: you can extend the TextMergeViewer and override some method to check the file path "on the fly":

public abstract class AbstractMergeViewer extends TextMergeViewer {
     /**
     * Overridden to check if the editor input is modifiable.
     * 
     * @see {@link TextMergeViewer#setEditable(ISourceViewer sourceViewer, boolean state)}
     */
    @Override
    protected void setEditable(ISourceViewer sourceViewer, boolean state) {
        if (!Utils.checkEditorInputModifiable(getEditorInput(sourceViewer))) {
            state = false;
        }
        super.setEditable(sourceViewer, state);
    }

    /**
     * Return a custom implementation of a {@link MergeViewerContentProvider},
     * to check if the content is modifiable.
     */
    public IContentProvider getContentProvider() {
        return new MASMergeViewerContentProvider(getCompareConfiguration());
    }
}

The contentProvider has to be extended too:

public class MyMergeViewerContentProvider extends MergeViewerContentProvider {

    /**
     * Check if the left content is modifiable, with
     * {@link Utils#checkResourceModifiable}.
     * 
     * @see org.eclipse.compare.internal.MergeViewerContentProvider#isLeftEditable(java.lang.Object)
     */
    @Override
    public boolean isLeftEditable(Object element) {
        if (element instanceof ICompareInput) {
            Object left = ((ICompareInput) element).getLeft();
            if (left instanceof LocalResourceTypedElement) {
                LocalResourceTypedElement res = (LocalResourceTypedElement) left;
                if (!Utils.checkResourceModifiable(res.getResource())) {
                    return false;
                }
            }
        }
        return super.isLeftEditable(element);
    }

    /**
     * Check if the right content is modifiable, with
     * {@link Utils#checkResourceModifiable}.
     * 
     * @see org.eclipse.compare.internal.MergeViewerContentProvider#isRightEditable(java.lang.Object)
     */
    @Override
    public boolean isRightEditable(Object element) {
        if (element instanceof ICompareInput) {
            Object right = ((ICompareInput) element).getRight();
            if (right instanceof LocalResourceTypedElement) {
                LocalResourceTypedElement res = (LocalResourceTypedElement) right;
                if (!Utils.checkResourceModifiable(res.getResource())) {
                    return false;
                }
            }
        }
        return super.isRightEditable(element);
    }

This way all the graphic element in the compare dialog have the right state (disabled if the file is readonly). MergeViewerContentProvider is an internal class, and should not be extended.. but I haven't found another solution.

The MergeViewer can be applied to a contentType via the extension point org.eclipse.compare.contentMergeViewers

Now I have another problem: if the contentType is not one that I have defined, Eclipse uses its own implementation of the compare editor, and not mine. Should I open a new question?

Gionata
  • 133
  • 11