Skip to content
Snippets Groups Projects
Commit dc241c46 authored by Alexander Diewald's avatar Alexander Diewald
Browse files

Merge branch '3536' into 'master'

Moved the abstract source editor to tooling base.

See merge request !40
parents 54cab21b 37be3236
No related branches found
No related tags found
1 merge request!40Moved the abstract source editor to tooling base.
Showing
with 983 additions and 0 deletions
......@@ -23,6 +23,7 @@ Export-Package: org.fortiss.tooling.base.ui,
org.fortiss.tooling.base.ui.dnd.gef,
org.fortiss.tooling.base.ui.dnd.jface,
org.fortiss.tooling.base.ui.editor,
org.fortiss.tooling.base.ui.editor.annotations,
org.fortiss.tooling.base.ui.editpart,
org.fortiss.tooling.base.ui.editpart.allocation,
org.fortiss.tooling.base.ui.editpart.command,
......
......@@ -7,4 +7,7 @@ DiagramEditorBase.java 09663ce095074d1a8eef086284eea0a7776e0431 GREEN
DiagramKeyHandler.java cfd15ac8f9fc933739cef5e7039960e19826d1ce GREEN
FormsEditorBase.java 4046d340913d951340084ae7240d79f8e75cb8d4 GREEN
GEFEditorBase.java e668f596f45f07215994cbbd3929a9438331718f GREEN
SourceEditorBase.java 347d6b45d577abd7e23a7234904be118e82469f1 YELLOW
SourceEditorConfigurationBase.java db3898fe1cace33aab0dd83d9711205c235c9861 YELLOW
SourceEditorUndoRedo.java 5f5d1b05c8b1287a9e37d866eda3474b6dcbd014 YELLOW
TreeViewerEditorBase.java 1c59689ff57c4f3cc180d85f13021fc03461ecb0 GREEN
/*-------------------------------------------------------------------------+
| Copyright 2012 fortiss GmbH |
| |
| Licensed under the Apache License, Version 2.0 (the "License"); |
| you may not use this file except in compliance with the License. |
| You may obtain a copy of the License at |
| |
| http://www.apache.org/licenses/LICENSE-2.0 |
| |
| Unless required by applicable law or agreed to in writing, software |
| distributed under the License is distributed on an "AS IS" BASIS, |
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| See the License for the specific language governing permissions and |
| limitations under the License. |
+--------------------------------------------------------------------------*/
package org.fortiss.tooling.base.ui.editor;
import static java.util.regex.Pattern.compile;
import static org.eclipse.wb.swt.SWTResourceManager.getColor;
import static org.fortiss.tooling.base.ui.editor.annotations.ErrorAnnotation.ERROR_RGB;
import static org.fortiss.tooling.base.ui.editor.annotations.ErrorAnnotation.ERROR_TYPE;
import static org.fortiss.tooling.base.ui.utils.FontUtils.CODEFONT_11PT;
import static org.fortiss.tooling.base.ui.utils.FontUtils.createFont;
import java.util.regex.Pattern;
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.ecore.EAttribute;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.util.EContentAdapter;
import org.eclipse.jface.text.DefaultInformationControl;
import org.eclipse.jface.text.Document;
import org.eclipse.jface.text.IInformationControl;
import org.eclipse.jface.text.IInformationControlCreator;
import org.eclipse.jface.text.ITextListener;
import org.eclipse.jface.text.TextEvent;
import org.eclipse.jface.text.source.AnnotationBarHoverManager;
import org.eclipse.jface.text.source.AnnotationModel;
import org.eclipse.jface.text.source.AnnotationPainter;
import org.eclipse.jface.text.source.AnnotationRulerColumn;
import org.eclipse.jface.text.source.CompositeRuler;
import org.eclipse.jface.text.source.IAnnotationAccess;
import org.eclipse.jface.text.source.ISharedTextColors;
import org.eclipse.jface.text.source.OverviewRuler;
import org.eclipse.jface.text.source.SourceViewer;
import org.eclipse.jface.text.source.SourceViewerConfiguration;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.ST;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.RGB;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.MenuItem;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.IActionBars;
import org.eclipse.ui.actions.TextStyledTextActionHandler;
import org.eclipse.ui.forms.widgets.FormToolkit;
import org.eclipse.ui.forms.widgets.ScrolledForm;
import org.eclipse.wb.swt.SWTResourceManager;
import org.fortiss.tooling.base.ui.editor.annotations.AnnotationHover;
import org.fortiss.tooling.base.ui.editor.annotations.AnnotationMarkerAccess;
import org.fortiss.tooling.kernel.extension.data.ITopLevelElement;
import org.fortiss.tooling.kernel.service.ILibraryService;
import org.fortiss.tooling.kernel.service.IPersistencyService;
import org.fortiss.tooling.kernel.ui.extension.base.EditorBase;
import org.fortiss.tooling.kernel.ui.service.IActionService;
/**
* Editor for code specifications.
*
* @author kanav
* @param <T>
*/
public abstract class SourceEditorBase<T extends EObject> extends EditorBase<T> {
/** Stores the forms toolkit. */
private final FormToolkit formToolkit = new FormToolkit(Display.getDefault());
/** Stores the scrolled form. */
private ScrolledForm scrldfrm;
/** Stores the source viewer. */
protected SourceViewer sourceViewer;
/** Stores the annotation model. */
protected AnnotationModel annotationModel = new AnnotationModel();
/** Tracks whether changes to the source programmatically or by the user. */
private EditSource editSource = new EditSource();
/** Returns annotationModel. */
public AnnotationModel getAnnotationModel() {
return annotationModel;
}
/** Stores the pattern applied to the error messages. */
protected final Pattern pattern = compile("line (\\d*):(\\d*) (.*)");
/** {@inheritDoc} */
@Override
public void createPartControl(Composite parent) {
installModelChangeListener();
parent.setLayout(new FillLayout());
scrldfrm = formToolkit.createScrolledForm(parent);
formToolkit.paintBordersFor(scrldfrm);
scrldfrm.setText(getTitleText());
scrldfrm.getBody().setLayout(new FillLayout(SWT.HORIZONTAL));
formToolkit.decorateFormHeading(scrldfrm.getForm());
createCodeEditor(scrldfrm.getBody());
updateModel();
if(ILibraryService.getInstance().isLibraryElementShadow(editedObject)) {
sourceViewer.getControl().setEnabled(false);
}
}
/** Returns the title of the source viewer. */
protected abstract String getTitleText();
/**
* Installs an adapter that updates the editor whenever the underlying
* model is modified. Currently, only renaming is supported.
*/
protected void installModelChangeListener() {
getEditedObject().eAdapters().add(new EContentAdapter() {
/** {@inheritDoc} */
@Override
public void notifyChanged(Notification notification) {
if((notification.getEventType() == Notification.SET)) {
// Only trigger for model changes of the string representation. Otherwise, we
// would also react on the indirect change of the container.
if(!isTargetFeature(notification) || !isUpdateableAndRequired()) {
return;
}
// Do not act on user edits.
if(editSource.editor) {
return;
}
// Update the displayed sources and track the state.
editSource.model = true;
String formattedCode = getStringRepresentation();
sourceViewer.getTextWidget().setText(formattedCode);
sourceViewer.unconfigure();
sourceViewer.configure(getSourceViewerConfig());
editSource.model = false;
showErrors();
}
}
/**
* Check whether the modification updated the string representation of the code spec.
*/
private boolean isTargetFeature(Notification notification) {
if(notification.getFeature() instanceof EAttribute) {
EAttribute feature = (EAttribute)notification.getFeature();
if(feature == getTargetFeature()) {
return true;
}
}
return false;
}
/** Check parsability and the presence of a change. */
private boolean isUpdateableAndRequired() {
// Only update parsable models.
if(toBeParsed()) {
return false;
}
// No change --> Exit.
if((sourceViewer.getTextWidget() == null) || (sourceViewer.getTextWidget().getText()
.equals(getStringRepresentation()))) {
return false;
}
return true;
}
});
}
/** Returns the feature in ecore model for this source editor. */
protected abstract EAttribute getTargetFeature();
/** Creates the actual editor. */
private void createCodeEditor(Composite parent) {
IAnnotationAccess fAnnotationAccess = new AnnotationMarkerAccess();
// rulers
CompositeRuler fCompositeRuler = new CompositeRuler();
OverviewRuler fOverviewRuler =
new OverviewRuler(fAnnotationAccess, 12, new ISharedTextColors() {
/** {@inheritDoc} */
@Override
public Color getColor(RGB rgb) {
// Cannot use static import to disambiguate from local method name
return SWTResourceManager.getColor(rgb);
}
/** {@inheritDoc} */
@Override
public void dispose() {
// Nothing to do
}
});
AnnotationRulerColumn annotationRuler =
new AnnotationRulerColumn(annotationModel, 16, fAnnotationAccess);
fCompositeRuler.setModel(annotationModel);
fOverviewRuler.setModel(annotationModel);
// annotation ruler is decorating our composite ruler
fCompositeRuler.addDecorator(0, annotationRuler);
// add what types are show on the different rulers
annotationRuler.addAnnotationType(ERROR_TYPE);
fOverviewRuler.addAnnotationType(ERROR_TYPE);
fOverviewRuler.addHeaderAnnotationType(ERROR_TYPE);
// set what layer this type is on
fOverviewRuler.setAnnotationTypeLayer(ERROR_TYPE, 3);
// set what color is used on the overview ruler for the type
fOverviewRuler.setAnnotationTypeColor(ERROR_TYPE, getColor(ERROR_RGB));
// create the actual source viewer
sourceViewer = new SourceViewer(parent, fCompositeRuler, fOverviewRuler, true,
SWT.MULTI | SWT.V_SCROLL | SWT.H_SCROLL);
sourceViewer.setDocument(new Document(), annotationModel);
// Context menu
Menu menu = new Menu(parent.getShell(), SWT.POP_UP);
final StyledText editor = sourceViewer.getTextWidget();
createMenuItem(menu, "Cut", () -> editor.invokeAction(ST.CUT));
createMenuItem(menu, "Copy", () -> editor.invokeAction(ST.COPY));
createMenuItem(menu, "Paste", () -> editor.invokeAction(ST.PASTE));
editor.setMenu(menu);
// hover manager that shows text when hovering
AnnotationBarHoverManager fAnnotationHoverManager =
new AnnotationBarHoverManager(fCompositeRuler, sourceViewer,
new AnnotationHover(annotationModel), new AnnotationConfiguration());
fAnnotationHoverManager.install(annotationRuler.getControl());
// to paint the annotations
AnnotationPainter ap = new AnnotationPainter(sourceViewer, fAnnotationAccess);
ap.addAnnotationType(null, ERROR_TYPE);
ap.setAnnotationTypeColor(ERROR_TYPE, getColor(ERROR_RGB));
sourceViewer.addPainter(ap);
// Setup the editor concerning syntax highlighting and content assist
sourceViewer.configure(getSourceViewerConfig());
Font font = createFont(CODEFONT_11PT);
sourceViewer.getTextWidget().setFont(font);
new SourceEditorUndoRedo(sourceViewer.getTextWidget());
sourceViewer.addTextListener(new ITextListener() {
@Override
public void textChanged(TextEvent event) {
if(editSource.model) {
return;
}
if(event.getDocumentEvent() != null) {
if(!isInitialLoading(event)) {
// Persist the current state of the editor on every input. Guarded to
// support the model change listener (responsible for renaming).
editSource.editor = true;
ITopLevelElement modelContext = IPersistencyService.getInstance()
.getTopLevelElementFor(getEditedObject());
modelContext.runAsCommand(() -> setStringRepresentation(
sourceViewer.getTextWidget().getText()));
editSource.editor = false;
}
showErrors();
}
}
private boolean isInitialLoading(TextEvent event) {
if(event.getDocumentEvent().getModificationStamp() == 1) {
return true;
}
return false;
}
});
sourceViewer.getControl().addDisposeListener(new DisposeListener() {
/** {@inheritDoc} */
@Override
public void widgetDisposed(DisposeEvent e) {
font.dispose();
}
});
}
/**
* Creates the SourceViewerConfiguration containing the setup for both syntax highlighting and
* content assist.
*/
abstract protected SourceViewerConfiguration getSourceViewerConfig();
/** Returns the string representation of the object. */
abstract protected String getStringRepresentation();
/** Update the string representation in the model element. */
abstract protected void setStringRepresentation(String s);
/** Displays the actual error in the editor. */
public abstract void showErrors();
/** {@inheritDoc} */
@Override
public void registerGlobalActions(IActionBars bars) {
IActionService.getInstance().registerGlobalUndoRedoActions(bars);
super.registerGlobalActions(bars);
}
/** {@inheritDoc} */
@Override
protected void addTextStyledText(TextStyledTextActionHandler textStyledTextActionHandler) {
textStyledTextActionHandler.addText(sourceViewer.getTextWidget());
}
/** {@inheritDoc} */
@Override
public void dispose() {
super.dispose();
}
/** Performs the text to model binding. */
abstract protected void updateModel();
/** Checks if the model element is to be parsed or not. */
abstract protected boolean toBeParsed();
/**
* Adds a menu item to <code>menu</code> with description <code>description</code>, triggering
* <code>r</code> when selected.
*/
protected static void createMenuItem(Menu menu, String description, Runnable r) {
MenuItem pasteItem = new MenuItem(menu, SWT.PUSH);
pasteItem.setText(description);
pasteItem.addSelectionListener(new SelectionAdapter() {
/** {@inheritDoc} */
@Override
public void widgetSelected(SelectionEvent e) {
r.run();
}
});
}
/** Encapsulates the source of a textual change in the spec. */
private class EditSource {
/** Change performed by a user. */
public boolean editor = false;
/** Change coming from the model. */
public boolean model = false;
}
/** Class acting as annotation configuration. */
public static class AnnotationConfiguration implements IInformationControlCreator {
/** {@inheritDoc} */
@Override
public IInformationControl createInformationControl(Shell shell) {
return new DefaultInformationControl(shell);
}
}
}
/*-------------------------------------------------------------------------+
| Copyright 2012 fortiss GmbH |
| |
| Licensed under the Apache License, Version 2.0 (the "License"); |
| you may not use this file except in compliance with the License. |
| You may obtain a copy of the License at |
| |
| http://www.apache.org/licenses/LICENSE-2.0 |
| |
| Unless required by applicable law or agreed to in writing, software |
| distributed under the License is distributed on an "AS IS" BASIS, |
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| See the License for the specific language governing permissions and |
| limitations under the License. |
+--------------------------------------------------------------------------*/
package org.fortiss.tooling.base.ui.editor;
import static org.eclipse.jface.text.IDocument.DEFAULT_CONTENT_TYPE;
import static org.eclipse.wb.swt.SWTResourceManager.getColor;
import java.util.List;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.jface.text.presentation.IPresentationReconciler;
import org.eclipse.jface.text.presentation.PresentationReconciler;
import org.eclipse.jface.text.rules.DefaultDamagerRepairer;
import org.eclipse.jface.text.rules.IRule;
import org.eclipse.jface.text.rules.IToken;
import org.eclipse.jface.text.rules.ITokenScanner;
import org.eclipse.jface.text.rules.IWordDetector;
import org.eclipse.jface.text.rules.RuleBasedScanner;
import org.eclipse.jface.text.rules.WordRule;
import org.eclipse.jface.text.source.IAnnotationHover;
import org.eclipse.jface.text.source.ISourceViewer;
import org.eclipse.jface.text.source.SourceViewerConfiguration;
import org.eclipse.swt.graphics.Color;
import org.fortiss.tooling.base.ui.editor.SourceEditorBase;
import org.fortiss.tooling.base.ui.editor.annotations.AnnotationHover;
/**
* Class responsible for proper configuration of the {@link SourceEditorBase}.
*
* @author doebber
*/
public abstract class SourceEditorConfigurationBase<T extends EObject>
extends SourceViewerConfiguration {
/** Stores the actual editor object. */
protected SourceEditorBase<T> editor;
/** Constructor. */
public SourceEditorConfigurationBase(SourceEditorBase<T> editor) {
this.editor = editor;
}
/** Color constant used to display code dark red. */
protected Color DARK_RED = getColor(128, 0, 0);
/** Color constant used to display code dark blue. */
protected Color DARK_BLUE = getColor(0, 0, 128);
/** Detector used to create the scanners. */
protected IWordDetector detector = new IWordDetector() {
/** {@inheritDoc} */
@Override
public boolean isWordStart(char c) {
return Character.isLetterOrDigit(c);
}
/** {@inheritDoc} */
@Override
public boolean isWordPart(char c) {
return Character.isLetterOrDigit(c) || c == '_';
}
};
/** {@inheritDoc} */
@Override
public IPresentationReconciler getPresentationReconciler(ISourceViewer sourceViewer) {
PresentationReconciler reconciler = new PresentationReconciler();
DefaultDamagerRepairer dr = new DefaultDamagerRepairer(getScanner());
reconciler.setDamager(dr, DEFAULT_CONTENT_TYPE);
reconciler.setRepairer(dr, DEFAULT_CONTENT_TYPE);
return reconciler;
}
/** Returns the scanner. */
private ITokenScanner getScanner() {
return getScannerForSyntaxHighlighting();
}
/** Returns the annotation hover. */
@Override
public IAnnotationHover getAnnotationHover(ISourceViewer sourceViewer) {
return new AnnotationHover(editor.getAnnotationModel());
}
/** Returns the rule based scanner. */
private RuleBasedScanner getScannerForSyntaxHighlighting() {
List<WordRule> rules = getCommonRules();
rules.add(getRuleSpecificToEditor());
RuleBasedScanner scanner = new RuleBasedScanner();
scanner.setRules(rules.toArray(new IRule[0]));
return scanner;
}
/** Returns a list of rules common for the syntax highlighting. */
abstract protected List<WordRule> getCommonRules();
/** Returns a rule specific to the editor. */
abstract protected WordRule getRuleSpecificToEditor();
/** Adds the words to the rule with the given token. */
protected void addWordsToRule(List<String> words, WordRule rule, IToken token) {
for(String word : words) {
rule.addWord(word, token);
}
}
}
/*-------------------------------------------------------------------------+
| Copyright 2014 fortiss GmbH |
| |
| Licensed under the Apache License, Version 2.0 (the "License"); |
| you may not use this file except in compliance with the License. |
| You may obtain a copy of the License at |
| |
| http://www.apache.org/licenses/LICENSE-2.0 |
| |
| Unless required by applicable law or agreed to in writing, software |
| distributed under the License is distributed on an "AS IS" BASIS, |
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| See the License for the specific language governing permissions and |
| limitations under the License. |
+--------------------------------------------------------------------------*/
package org.fortiss.tooling.base.ui.editor;
import java.util.Stack;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.ExtendedModifyEvent;
import org.eclipse.swt.custom.ExtendedModifyListener;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.KeyListener;
/**
* Hack to fix the seemingly broken undo-redo functionality of SourceViewer.
*
* @author aravantinos
*/
public class SourceEditorUndoRedo implements KeyListener, ExtendedModifyListener {
/**
* Encapsulation of the Undo and Redo stack(s).
*/
private static class UndoRedoStack<T> {
/** Command stack in the "undo direction". */
private Stack<T> undo;
/** Command stack in the "redo direction". */
private Stack<T> redo;
/** Constructor. */
public UndoRedoStack() {
undo = new Stack<T>();
redo = new Stack<T>();
}
/** Adds a command to the undo stack. */
public void pushUndo(T delta) {
undo.add(delta);
}
/** Adds a command to the redo stack. */
public void pushRedo(T delta) {
redo.add(delta);
}
/** Pops a command from the undo stack. */
public T popUndo() {
T res = undo.pop();
return res;
}
/** Pops a command from the redo stack. */
public T popRedo() {
T res = redo.pop();
return res;
}
/** Empties the redo stack. */
public void clearRedo() {
redo.clear();
}
/** Returns true if the undo stack is not empty. */
public boolean hasUndo() {
return !undo.isEmpty();
}
/** Returns true if the redo stack is not empty. */
public boolean hasRedo() {
return !redo.isEmpty();
}
}
/** The editor GUI itself. */
private StyledText editor;
/** The local undo/redo command stack. */
private UndoRedoStack<ExtendedModifyEvent> stack;
/** Flag to know whether we are in the course of an undo event. */
private boolean isUndo;
/** Flag to know whether we are in the course of an redo event. */
private boolean isRedo;
/**
* Creates a new instance of this class. Automatically starts listening to
* corresponding key and modify events coming from the given
* <var>editor</var>.
*
* @param editor
* the text field to which the Undo-Redo functionality should be
* added
*/
public SourceEditorUndoRedo(StyledText editor) {
editor.addExtendedModifyListener(this);
editor.addKeyListener(this);
this.editor = editor;
stack = new UndoRedoStack<ExtendedModifyEvent>();
}
/** {@inheritDoc} */
@Override
public void keyPressed(KeyEvent e) {
// Listen to CTRL+Z for Undo, to CTRL+Y or CTRL+SHIFT+Z for Redo
if((e.stateMask & SWT.MOD1) > 0 && !((e.stateMask & SWT.ALT) > 0)) {
boolean isShift = (e.stateMask & SWT.SHIFT) > 0;
if(!isShift && e.keyCode == 'z') {
undo();
}
}
}
/** {@inheritDoc} */
@Override
public void keyReleased(KeyEvent e) {
// Listen to CTRL+Z for Undo, to CTRL+Y or CTRL+SHIFT+Z for Redo
if((e.stateMask & SWT.MOD1) > 0 && !((e.stateMask & SWT.ALT) > 0)) {
boolean isShift = (e.stateMask & SWT.SHIFT) > 0;
if(!isShift && e.keyCode == 'z') {
undo();
} else if(!isShift && e.keyCode == 'y' || isShift && e.keyCode == 'z') {
redo();
}
}
}
/**
* Creates a corresponding Undo or Redo step from the given event and pushes
* it to the stack. The Redo stack is, logically, emptied if the event comes
* from a normal user action.
*
* @param event
* @see org.eclipse.swt.custom.ExtendedModifyListener#modifyText(org.eclipse.
* swt.custom.ExtendedModifyEvent)
*/
@Override
public void modifyText(ExtendedModifyEvent event) {
if(isUndo) {
stack.pushRedo(event);
} else { // is Redo or a normal user action
stack.pushUndo(event);
if(!isRedo) {
stack.clearRedo();
}
}
}
/**
* Performs the Undo action. A new corresponding Redo step is automatically
* pushed to the stack.
*/
private void undo() {
if(stack.hasUndo()) {
isUndo = true;
revertEvent(stack.popUndo());
isUndo = false;
}
}
/**
* Performs the Redo action. A new corresponding Undo step is automatically
* pushed to the stack.
*/
private void redo() {
if(stack.hasRedo()) {
isRedo = true;
revertEvent(stack.popRedo());
isRedo = false;
}
}
/**
* Reverts the given modify event, in the way as the Eclipse text editor
* does it.
*
* @param event
*/
private void revertEvent(ExtendedModifyEvent event) {
editor.replaceTextRange(event.start, event.length, event.replacedText);
// (causes the modifyText() listener method to be called)
editor.setSelectionRange(event.start, event.replacedText.length());
}
}
AnnotationHover.java 02988c3a040a394afb427af10c965d9f82b9a01d GREEN
AnnotationMarkerAccess.java 1977a4093f76d42638a560ed305f1d2cc3dedc4e GREEN
ErrorAnnotation.java 3e05aaeb93ca19bb99aed312427752c2c3f1959f GREEN
/*-------------------------------------------------------------------------+
| Copyright 2012 fortiss GmbH |
| |
| Licensed under the Apache License, Version 2.0 (the "License"); |
| you may not use this file except in compliance with the License. |
| You may obtain a copy of the License at |
| |
| http://www.apache.org/licenses/LICENSE-2.0 |
| |
| Unless required by applicable law or agreed to in writing, software |
| distributed under the License is distributed on an "AS IS" BASIS, |
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| See the License for the specific language governing permissions and |
| limitations under the License. |
+--------------------------------------------------------------------------*/
package org.fortiss.tooling.base.ui.editor.annotations;
import java.util.ArrayList;
import java.util.Iterator;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.ITextHover;
import org.eclipse.jface.text.ITextViewer;
import org.eclipse.jface.text.source.Annotation;
import org.eclipse.jface.text.source.AnnotationModel;
import org.eclipse.jface.text.source.IAnnotationHover;
import org.eclipse.jface.text.source.ISourceViewer;
import org.fortiss.tooling.base.ui.editor.annotations.ErrorAnnotation;
/**
* Class acting as annotation hover manager.
*
* @author doebber
*/
public class AnnotationHover implements IAnnotationHover, ITextHover {
/** Stores the {@link AnnotationModel}. */
private final AnnotationModel model;
/** Constructor. */
public AnnotationHover(AnnotationModel model) {
this.model = model;
}
/** {@inheritDoc} */
@Override
public String getHoverInfo(ISourceViewer sourceViewer, int lineNumber) {
Iterator<?> ite = model.getAnnotationIterator();
ArrayList<String> all = new ArrayList<String>();
while(ite.hasNext()) {
Annotation a = (Annotation)ite.next();
if(a instanceof ErrorAnnotation) {
all.add(((ErrorAnnotation)a).getText());
}
}
StringBuffer total = new StringBuffer();
for(String str : all) {
total.append(" " + str);// + "\n");
}
return total.toString();
}
/** {@inheritDoc} */
@Override
public String getHoverInfo(ITextViewer textViewer, IRegion hoverRegion) {
return null;
}
/** {@inheritDoc} */
@Override
public IRegion getHoverRegion(ITextViewer textViewer, int offset) {
return null;
}
}
/*-------------------------------------------------------------------------+
| Copyright 2012 fortiss GmbH |
| |
| Licensed under the Apache License, Version 2.0 (the "License"); |
| you may not use this file except in compliance with the License. |
| You may obtain a copy of the License at |
| |
| http://www.apache.org/licenses/LICENSE-2.0 |
| |
| Unless required by applicable law or agreed to in writing, software |
| distributed under the License is distributed on an "AS IS" BASIS, |
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| See the License for the specific language governing permissions and |
| limitations under the License. |
+--------------------------------------------------------------------------*/
package org.fortiss.tooling.base.ui.editor.annotations;
import static org.eclipse.jface.text.source.ImageUtilities.drawImage;
import org.eclipse.jface.text.source.Annotation;
import org.eclipse.jface.text.source.IAnnotationAccess;
import org.eclipse.jface.text.source.IAnnotationAccessExtension;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Canvas;
/**
* Class providing annotation marker access.
*
* @author doebber
*/
public class AnnotationMarkerAccess implements IAnnotationAccess, IAnnotationAccessExtension {
/** {@inheritDoc} */
@Override
public Object getType(Annotation annotation) {
return annotation.getType();
}
/** {@inheritDoc} */
@Override
public boolean isMultiLine(Annotation annotation) {
return true;
}
/** {@inheritDoc} */
@Override
public boolean isTemporary(Annotation annotation) {
return !annotation.isPersistent();
}
/** {@inheritDoc} */
@Override
public String getTypeLabel(Annotation annotation) {
if(annotation instanceof ErrorAnnotation) {
return "Errors";
}
return null;
}
/** {@inheritDoc} */
@Override
public int getLayer(Annotation annotation) {
if(annotation instanceof ErrorAnnotation) {
return ((ErrorAnnotation)annotation).getLayer();
}
return 0;
}
/** {@inheritDoc} */
@Override
public void paint(Annotation annotation, GC gc, Canvas canvas, Rectangle bounds) {
drawImage(((ErrorAnnotation)annotation).getImage(), gc, canvas, bounds, SWT.CENTER,
SWT.TOP);
}
/** {@inheritDoc} */
@Override
public boolean isPaintable(Annotation annotation) {
if(annotation instanceof ErrorAnnotation) {
return ((ErrorAnnotation)annotation).getImage() != null;
}
return false;
}
/** {@inheritDoc} */
@Override
public boolean isSubtype(Object annotationType, Object potentialSupertype) {
if(annotationType.equals(potentialSupertype)) {
return true;
}
return false;
}
/** {@inheritDoc} */
@Override
public Object[] getSupertypes(Object annotationType) {
return new Object[0];
}
}
/*-------------------------------------------------------------------------+
| Copyright 2012 fortiss GmbH |
| |
| Licensed under the Apache License, Version 2.0 (the "License"); |
| you may not use this file except in compliance with the License. |
| You may obtain a copy of the License at |
| |
| http://www.apache.org/licenses/LICENSE-2.0 |
| |
| Unless required by applicable law or agreed to in writing, software |
| distributed under the License is distributed on an "AS IS" BASIS, |
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| See the License for the specific language governing permissions and |
| limitations under the License. |
+--------------------------------------------------------------------------*/
package org.fortiss.tooling.base.ui.editor.annotations;
import static org.eclipse.wb.swt.ResourceManager.getPluginImage;
import static org.fortiss.tooling.base.ui.ToolingBaseUIActivator.PLUGIN_ID;
import org.eclipse.core.resources.IMarker;
import org.eclipse.jface.text.Position;
import org.eclipse.jface.text.source.Annotation;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.RGB;
/**
* Objects of this class represent one error annotation.
*
* @author doebber
*/
public class ErrorAnnotation extends Annotation {
/** Stores the marker. */
private IMarker marker;
/** Stores the error text. */
private String text;
/** Stores the line number. */
private int line;
/** Stores the error's text position. */
private Position position;
/** Stores the error type. */
public static String ERROR_TYPE = "error.type";
/** Stores the error color. */
public static final RGB ERROR_RGB = new RGB(255, 0, 0);
/** Constructor. */
public ErrorAnnotation(IMarker marker) {
this.marker = marker;
}
/** Constructor. */
public ErrorAnnotation(int line, String text) {
super(ERROR_TYPE, true, null);
this.marker = null;
this.line = line;
this.text = text;
}
/** Returns the marker. */
public IMarker getMarker() {
return marker;
}
/** Returns the line. */
public int getLine() {
return line;
}
/** Returns the error text. */
@Override
public String getText() {
return text;
}
/** Returns the image. */
public Image getImage() {
return getPluginImage(PLUGIN_ID, "/icons/error.gif");
}
/** Returns the layer. */
public int getLayer() {
return 3;
}
/** Returns the type. */
@Override
public String getType() {
return ERROR_TYPE;
}
/** Returns the position. */
public Position getPosition() {
return position;
}
/** Sets the position. */
public void setPosition(Position position) {
this.position = position;
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment