editor now updatable via updateSite
[taxeditor.git] / taxeditor-editor / src / main / java / eu / etaxonomy / taxeditor / editor / name / NameViewer.java
1 /**
2 * Copyright (C) 2007 EDIT
3 * European Distributed Institute of Taxonomy
4 * http://www.e-taxonomy.eu
5 *
6 * The contents of this file are subject to the Mozilla Public License Version 1.1
7 * See LICENSE.TXT at the top of this package for the full license terms.
8 */
9
10 package eu.etaxonomy.taxeditor.editor.name;
11
12 import java.util.Iterator;
13
14 import org.apache.log4j.Logger;
15 import org.eclipse.core.commands.operations.IUndoContext;
16 import org.eclipse.core.runtime.Assert;
17 import org.eclipse.jface.text.Document;
18 import org.eclipse.jface.text.IUndoManager;
19 import org.eclipse.jface.text.IUndoManagerExtension;
20 import org.eclipse.jface.text.Position;
21 import org.eclipse.jface.text.TextViewerUndoManager;
22 import org.eclipse.jface.text.source.Annotation;
23 import org.eclipse.jface.text.source.AnnotationModel;
24 import org.eclipse.jface.text.source.AnnotationPainter;
25 import org.eclipse.jface.text.source.IAnnotationAccess;
26 import org.eclipse.jface.text.source.IVerticalRuler;
27 import org.eclipse.jface.text.source.SourceViewer;
28 import org.eclipse.swt.SWT;
29 import org.eclipse.swt.graphics.Color;
30 import org.eclipse.swt.graphics.Image;
31 import org.eclipse.swt.widgets.Composite;
32 import org.eclipse.swt.widgets.Control;
33 import org.eclipse.swt.widgets.Display;
34 import org.eclipse.swt.widgets.Layout;
35 import org.eclipse.ui.IActionBars;
36 import org.eclipse.ui.IEditorSite;
37 import org.eclipse.ui.actions.ActionFactory;
38 import org.eclipse.ui.forms.widgets.TableWrapData;
39 import org.eclipse.ui.forms.widgets.TableWrapLayout;
40 import org.eclipse.ui.operations.OperationHistoryActionHandler;
41 import org.eclipse.ui.operations.RedoActionHandler;
42 import org.eclipse.ui.operations.UndoActionHandler;
43 import org.eclipse.ui.texteditor.DefaultMarkerAnnotationAccess;
44 import org.eclipse.ui.texteditor.IWorkbenchActionDefinitionIds;
45
46 import eu.etaxonomy.cdm.model.name.TaxonNameBase;
47 import eu.etaxonomy.cdm.model.taxon.Taxon;
48 import eu.etaxonomy.taxeditor.editor.ErrorAnnotation;
49 import eu.etaxonomy.taxeditor.editor.LineWrapSquigglesStrategy;
50 import eu.etaxonomy.taxeditor.editor.ViewerConfiguration;
51 import eu.etaxonomy.taxeditor.editor.WarningAnnotation;
52 import eu.etaxonomy.taxeditor.store.model.Resources;
53
54 /**
55 * SourceViewer implementation called by NameComposite.
56 *
57 * @author p.ciardelli
58 * @created 27.05.2008
59 * @version 1.0
60 */
61 public class NameViewer extends SourceViewer {
62 private static final Logger logger = Logger
63 .getLogger(NameViewer.class);
64
65 public static final int RULER_WIDTH = 16;
66
67 private IVerticalRuler ruler;
68 private AnnotationModel annotationModel;
69
70 public NameViewer(Composite parent) {
71 super(parent, new RulerWithIcon(RULER_WIDTH), SWT.WRAP | SWT.MULTI | SWT.RESIZE);
72
73 this.ruler = getVerticalRuler();
74
75 setBackground(Resources.getColor(Resources.COLOR_COMPOSITE_BACKGROUND));
76
77 // Lay out the viewer's widgets
78 getControl().setLayoutData(new TableWrapData(TableWrapData.FILL_GRAB));
79 getTextWidget().setLayoutData(new TableWrapData(TableWrapData.FILL_GRAB));
80
81 // Default implentation adds ruler after the text widget, then
82 // uses a custom layout to display it before the text widget
83 ruler.getControl().moveAbove(getTextWidget());
84
85 annotationModel = new AnnotationModel();
86 this.setDocument(new Document(""), annotationModel);
87
88 createAnnotationPainter();
89
90 this.configure(new ViewerConfiguration());
91
92 // setDecorationSupport();
93 // DocumentUndoManagerRegistry.connect(this.getDocument());
94 // IDocumentUndoManager docUndoManager = DocumentUndoManagerRegistry.getDocumentUndoManager(this.getDocument());
95
96 /**
97 getEditorSite().getActionBars().setGlobalActionHandler(ActionFactory.UNDO.getId(), new UndoActionHandler(getSite(), undoContext));
98 getEditorSite().getActionBars().setGlobalActionHandler(ActionFactory.REDO.getId(), new RedoActionHandler(getSite(), undoContext));
99 **/
100 }
101
102 public void setBackground(Color color) {
103 // Set background color of ruler
104 ruler.getControl().setBackground(color);
105
106 // Set background color of text widget
107 getTextWidget().setBackground(color);
108
109 // Set background color of strip between ruler and textWidget
110 getTextWidget().getParent().setBackground(color);
111 }
112
113 public Control getRulerControl() {
114 return ruler.getControl();
115 }
116
117 public void setIcon(Image icon) {
118 if (ruler instanceof RulerWithIcon) {
119 ((RulerWithIcon) ruler).setIcon(icon);
120 } else {
121 logger.warn("Viewer's IVerticalRuler is not an instance of RulerWithIcon.");
122 }
123 }
124
125 /* (non-Javadoc)
126 * @see org.eclipse.jface.text.source.SourceViewer#createLayout()
127 */
128 protected Layout createLayout() {
129 TableWrapLayout layout = new TableWrapLayout();
130 layout.numColumns = 2;
131 layout.verticalSpacing = 0;
132 return layout;
133 }
134
135 private void createAnnotationPainter(){
136 // Annotations section
137 IAnnotationAccess fAnnotationAccess = new DefaultMarkerAnnotationAccess();
138
139 // To paint the annotations
140 AnnotationPainter annotationPainter = new AnnotationPainter(this, fAnnotationAccess);
141
142 // Default SquigglesStrategy doesn't recognize line wraps
143 annotationPainter.addDrawingStrategy(LineWrapSquigglesStrategy.ID, new LineWrapSquigglesStrategy());
144
145 // Add ability to paint red squigglies
146 annotationPainter.addAnnotationType(ErrorAnnotation.ERROR_TYPE, LineWrapSquigglesStrategy.ID);
147 annotationPainter.setAnnotationTypeColor(ErrorAnnotation.ERROR_TYPE,
148 new Color(Display.getDefault(), ErrorAnnotation.ERROR_RGB));
149
150 // Add ability to paint yellow squigglies
151 annotationPainter.addAnnotationType(WarningAnnotation.WARNING_TYPE, LineWrapSquigglesStrategy.ID);
152 annotationPainter.setAnnotationTypeColor(WarningAnnotation.WARNING_TYPE,
153 new Color(Display.getDefault(), WarningAnnotation.WARNING_RGB));
154
155 this.addPainter(annotationPainter);
156 }
157
158
159 public void clearErrors() {
160 Iterator<Annotation> annotations = this.getAnnotationModel().getAnnotationIterator();
161 while (annotations.hasNext()) {
162 Annotation annotation = annotations.next();
163 if (annotation.getType().equals(ErrorAnnotation.ERROR_TYPE))
164 this.getAnnotationModel().removeAnnotation(annotation);
165 }
166 }
167
168 /**
169 * If <code>name.hasProblem()</code> is <code>true</code>, underlines section
170 * of text bounded by <code>name.getProblemStarts()</code> and
171 * <code>name.getProblemEnds()</code>.
172 *
173 * @param name
174 */
175 public void setShowParsingError(TaxonNameBase<?, ?> name) {
176
177 // testMarkers();
178
179 boolean hasProblem = name.getHasProblem();
180
181 if (!hasProblem) {
182 logger.debug(name.getProblemStarts());
183 }
184
185 String text = this.getTextWidget().getText();
186
187 if (hasProblem && text.length() > 0) {
188 // logger.warn("Name: " + name.getTitleCache() + ", start: " + name.getProblemStarts()+ ", end: " + name.getProblemEnds());
189 int start = name.getProblemStarts();
190 int length = name.getProblemEnds() - start;
191
192 if (start == -1 || name.getProblemEnds() == -1) {
193 // logger.warn("Start: " + start + ", End " + name.getProblemEnds());
194 return;
195 }
196
197 // Don't let squigglies try to draw beyond the end of the text
198 if (text.length() < start + length) {
199 length = text.length() - start;
200 }
201
202 this.getAnnotationModel().addAnnotation(
203 new ErrorAnnotation(0, "Error parsing string '" + text + "'"),
204 new Position(start, length));
205 }
206 }
207
208 public void setShowSecError(Taxon taxon) {
209
210 // If taxon has no sec, show an annotation
211 if (taxon.getSec() == null) {
212
213 String text = "This taxon requires a sec. reference.";
214
215 this.getAnnotationModel().addAnnotation(
216 new ErrorAnnotation(0, text),
217 new Position(0, 0));
218 // new Position(0, getTextWidget().getText().length()));
219 }
220 }
221
222
223 public void setText(String text) {
224 if (text == null) {
225 text = "";
226 }
227 try {
228 Assert.isNotNull(text);
229 // TODO figure out why getTextWidget() returns null!
230 if (this.getTextWidget() == null) {
231 return;
232 }
233 Assert.isNotNull(this.getTextWidget());
234 this.getTextWidget().setText(text);
235 } catch (RuntimeException e) {
236 e.printStackTrace();
237 }
238 }
239
240 public void setCursorToEOL() {
241 getTextWidget().setCaretOffset(getTextWidget().getText().length());
242 getTextWidget().setFocus();
243 }
244
245 public void createUndoSupport(IEditorSite editorSite) {
246
247 IUndoManager undoManager = new TextViewerUndoManager(25);
248 this.setUndoManager(undoManager);
249 undoManager.connect(this);
250
251 // IUndoContext workbenchUndoContext = UiUtil.getWorkbenchUndoContext();
252
253 IUndoContext workbenchUndoContext = ((IUndoManagerExtension)undoManager).getUndoContext();
254
255 OperationHistoryActionHandler undoAction = new UndoActionHandler(editorSite, workbenchUndoContext);
256 // undoAction.setActionDefinitionId(IWorkbenchActionDefinitionIds.UNDO);
257 undoAction.setActionDefinitionId(ActionFactory.UNDO.getId());
258
259 // Create the redo action.
260 OperationHistoryActionHandler redoAction = new RedoActionHandler(editorSite, workbenchUndoContext);
261 // redoAction.setActionDefinitionId(IWorkbenchActionDefinitionIds.REDO);
262 undoAction.setActionDefinitionId(ActionFactory.REDO.getId());
263
264 IActionBars actionBars = editorSite.getActionBars();
265 if (actionBars != null) {
266 // actionBars.setGlobalActionHandler(IWorkbenchActionDefinitionIds.UNDO, undoAction);
267 // actionBars.setGlobalActionHandler(IWorkbenchActionDefinitionIds.REDO, redoAction);
268 actionBars.setGlobalActionHandler(ActionFactory.UNDO.getId(), undoAction);
269 actionBars.setGlobalActionHandler(ActionFactory.REDO.getId(), redoAction);
270
271 }
272
273 // actionBars.setGlobalActionHandler(ActionFactory.UNDO.getId(), undoAction);
274 // actionBars.setGlobalActionHandler(ActionFactory.REDO.getId(), redoAction);
275 }
276
277 public void createUndoSupport_(IEditorSite editorSite) {
278 IUndoManager undoManager = new TextViewerUndoManager(25);
279 this.setUndoManager(undoManager);
280 undoManager.connect(this);
281 IUndoContext undoContext;
282 if (undoManager instanceof IUndoManagerExtension) {
283 undoContext = ((IUndoManagerExtension)undoManager).getUndoContext();
284
285 OperationHistoryActionHandler undoAction = new UndoActionHandler(editorSite, undoContext);
286 // PlatformUI.getWorkbench().getHelpSystem().setHelp(undoAction, IAbstractTextEditorHelpContextIds.UNDO_ACTION);
287 undoAction.setActionDefinitionId(IWorkbenchActionDefinitionIds.UNDO);
288
289 // Create the redo action.
290 OperationHistoryActionHandler redoAction = new RedoActionHandler(editorSite, undoContext);
291 // PlatformUI.getWorkbench().getHelpSystem().setHelp(redoAction, IAbstractTextEditorHelpContextIds.REDO_ACTION);
292 redoAction.setActionDefinitionId(IWorkbenchActionDefinitionIds.REDO);
293
294
295 IActionBars actionBars = editorSite.getActionBars();
296 if (actionBars != null) {
297 actionBars.setGlobalActionHandler(IWorkbenchActionDefinitionIds.UNDO, undoAction);
298 actionBars.setGlobalActionHandler(IWorkbenchActionDefinitionIds.REDO, redoAction);
299
300 }
301 }
302 }
303 }
304