widget is disposed exception ticket (#4657)
[taxeditor.git] / eu.etaxonomy.taxeditor.editor / src / main / java / eu / etaxonomy / taxeditor / editor / name / container / 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.container;
11
12 import java.util.Iterator;
13
14 import org.eclipse.core.commands.operations.IUndoContext;
15 import org.eclipse.core.runtime.Assert;
16 import org.eclipse.jface.text.Document;
17 import org.eclipse.jface.text.IUndoManager;
18 import org.eclipse.jface.text.IUndoManagerExtension;
19 import org.eclipse.jface.text.Position;
20 import org.eclipse.jface.text.TextViewerUndoManager;
21 import org.eclipse.jface.text.source.Annotation;
22 import org.eclipse.jface.text.source.AnnotationModel;
23 import org.eclipse.jface.text.source.AnnotationPainter;
24 import org.eclipse.jface.text.source.IAnnotationAccess;
25 import org.eclipse.jface.text.source.IVerticalRuler;
26 import org.eclipse.jface.text.source.SourceViewer;
27 import org.eclipse.swt.SWT;
28 import org.eclipse.swt.graphics.Color;
29 import org.eclipse.swt.graphics.Image;
30 import org.eclipse.swt.widgets.Canvas;
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.swt.widgets.Menu;
36 import org.eclipse.ui.IActionBars;
37 import org.eclipse.ui.IEditorSite;
38 import org.eclipse.ui.actions.ActionFactory;
39 import org.eclipse.ui.forms.widgets.TableWrapData;
40 import org.eclipse.ui.forms.widgets.TableWrapLayout;
41 import org.eclipse.ui.operations.OperationHistoryActionHandler;
42 import org.eclipse.ui.operations.RedoActionHandler;
43 import org.eclipse.ui.operations.UndoActionHandler;
44 import org.eclipse.ui.texteditor.DefaultMarkerAnnotationAccess;
45 import org.eclipse.ui.texteditor.IWorkbenchActionDefinitionIds;
46
47 import eu.etaxonomy.taxeditor.editor.EditorUtil;
48 import eu.etaxonomy.taxeditor.editor.ViewerConfiguration;
49 import eu.etaxonomy.taxeditor.editor.name.container.EditorAnnotation.EditorAnnotationType;
50 import eu.etaxonomy.taxeditor.preference.Resources;
51
52 /**
53 * SourceViewer implementation called by NameComposite.
54 *
55 * @author p.ciardelli
56 * @created 27.05.2008
57 * @version 1.0
58 */
59 public class NameViewer extends SourceViewer {
60
61 /** Constant <code>RULER_WIDTH=16</code> */
62 public static final int RULER_WIDTH = 16;
63
64 private final IVerticalRuler ruler;
65 private final AnnotationModel annotationModel;
66
67 /**
68 * <p>Constructor for NameViewer.</p>
69 *
70 * @param parent a {@link org.eclipse.swt.widgets.Composite} object.
71 */
72 public NameViewer(Composite parent) {
73 super(parent, new RulerWithIcon(RULER_WIDTH), SWT.WRAP | SWT.MULTI | SWT.RESIZE);
74
75 this.ruler = getVerticalRuler();
76
77 setBackground(EditorUtil.getColor(Resources.COLOR_COMPOSITE_BACKGROUND));
78
79 Canvas canvas = (Canvas) getControl();
80 TableWrapLayout layout = (TableWrapLayout) canvas.getLayout();
81 layout.topMargin = 0;
82 layout.rightMargin = 0;
83 layout.bottomMargin = 0;
84 layout.leftMargin = 0;
85 layout.verticalSpacing = 10;
86 layout.horizontalSpacing = 0;
87
88 canvas.setLayout(layout);
89
90 // Lay out the viewer's widgets
91 TableWrapData twdata = new TableWrapData(TableWrapData.FILL_GRAB);
92 getControl().setLayoutData(twdata);
93
94 twdata = new TableWrapData(TableWrapData.FILL_GRAB);
95 getTextWidget().setLayoutData(twdata);
96 getTextWidget().setLineSpacing(5);
97
98 // Default implementation adds ruler after the text widget, then
99 // uses a custom layout to display it before the text widget
100 ruler.getControl().moveAbove(getTextWidget());
101
102 annotationModel = new AnnotationModel();
103 this.setDocument(new Document(""), annotationModel);
104
105 createAnnotationPainter();
106
107 this.configure(new ViewerConfiguration());
108
109 // setDecorationSupport();
110 // DocumentUndoManagerRegistry.connect(this.getDocument());
111 // IDocumentUndoManager docUndoManager = DocumentUndoManagerRegistry.getDocumentUndoManager(this.getDocument());
112
113 /**
114 getEditorSite().getActionBars().setGlobalActionHandler(ActionFactory.UNDO.getId(), new UndoActionHandler(getSite(), undoContext));
115 getEditorSite().getActionBars().setGlobalActionHandler(ActionFactory.REDO.getId(), new RedoActionHandler(getSite(), undoContext));
116 **/
117 }
118
119 /**
120 * <p>setBackground</p>
121 *
122 * @param color a {@link org.eclipse.swt.graphics.Color} object.
123 */
124 public void setBackground(Color color) {
125
126 // Set background color of ruler
127 ruler.getControl().setBackground(color);
128
129 // Set background color of text widget
130 getTextWidget().setBackground(color);
131
132 // Set background color of strip between ruler and textWidget
133 getTextWidget().getParent().setBackground(color);
134 }
135
136 /**
137 * <p>getRulerControl</p>
138 *
139 * @return a {@link org.eclipse.swt.widgets.Control} object.
140 */
141 public Control getRulerControl() {
142 return ruler.getControl();
143 }
144
145 /**
146 * <p>setIcon</p>
147 *
148 * @param icon a {@link org.eclipse.swt.graphics.Image} object.
149 */
150 public void setIcon(Image icon) {
151 if (ruler instanceof RulerWithIcon) {
152 ((RulerWithIcon) ruler).setIcon(icon);
153 } else {
154 throw new IllegalStateException("Viewer's IVerticalRuler is not an instance of RulerWithIcon.");
155 }
156 }
157
158 /* (non-Javadoc)
159 * @see org.eclipse.jface.text.source.SourceViewer#createLayout()
160 */
161 /**
162 * <p>createLayout</p>
163 *
164 * @return a {@link org.eclipse.swt.widgets.Layout} object.
165 */
166 @Override
167 protected Layout createLayout() {
168 TableWrapLayout layout = new TableWrapLayout();
169 layout.numColumns = 2;
170 layout.verticalSpacing = 0;
171 return layout;
172 }
173
174 private void createAnnotationPainter(){
175 // Annotations section
176 IAnnotationAccess fAnnotationAccess = new DefaultMarkerAnnotationAccess();
177
178 // To paint the annotations
179 AnnotationPainter annotationPainter = new AnnotationPainter(this, fAnnotationAccess);
180
181 // Default SquigglesStrategy doesn't recognize line wraps
182 annotationPainter.addDrawingStrategy(LineWrapSquigglesStrategy.ID, new LineWrapSquigglesStrategy());
183
184 // Add ability to paint red squigglies
185 annotationPainter.addAnnotationType(EditorAnnotationType.ERROR.name(), LineWrapSquigglesStrategy.ID);
186 annotationPainter.setAnnotationTypeColor(EditorAnnotationType.ERROR.image,
187 new Color(Display.getDefault(), EditorAnnotationType.ERROR.color));
188
189 // Add ability to paint yellow squigglies
190 annotationPainter.addAnnotationType(EditorAnnotationType.WARNING.name(), LineWrapSquigglesStrategy.ID);
191 annotationPainter.setAnnotationTypeColor(EditorAnnotationType.WARNING.image,
192 new Color(Display.getDefault(), EditorAnnotationType.WARNING.color));
193
194 this.addPainter(annotationPainter);
195 }
196
197
198 /**
199 * <p>clearAnnotations</p>
200 */
201 public void clearAnnotations() {
202 Iterator<Annotation> annotations = this.getAnnotationModel().getAnnotationIterator();
203 while (annotations.hasNext()) {
204 Annotation annotation = annotations.next();
205 this.getAnnotationModel().removeAnnotation(annotation);
206 }
207 }
208
209 /**
210 * If <code>name.hasProblem()</code> is <code>true</code>, underlines section
211 * of text bounded by <code>name.getProblemStarts()</code> and
212 * <code>name.getProblemEnds()</code>.
213 *
214 * @param name a {@link eu.etaxonomy.cdm.model.name.TaxonNameBase} object.
215 */
216 // public void setShowParsingErrors(TaxonNameBase<?, ?> name) {
217 //
218 // String text = this.getTextWidget().getText();
219 //
220 // if (name.hasProblem() && text.length() > 0) {
221 // int start = name.getProblemStarts();
222 // int length = name.getProblemEnds() - start;
223 //
224 // if (start == -1 || name.getProblemEnds() == -1) {
225 // return;
226 // }
227 //
228 // // Don't let squigglies try to draw beyond the end of the text
229 // if (text.length() < start + length) {
230 // length = text.length() - start;
231 // }
232 //
233 // for (ParserProblem problem : name.getParsingProblems()) {
234 //
235 // String type = null;
236 // if (problem.isWarning()) {
237 // type = EditorAnnotation.WARNING_TYPE;
238 // }
239 // if (problem.isError()) {
240 // type = EditorAnnotation.ERROR_TYPE;
241 // }
242 // if (type == null) {
243 // continue;
244 // }
245 // this.getAnnotationModel().addAnnotation(
246 // new EditorAnnotation(type, 0, problem.getMessage()),
247 // new Position(start, length));
248 // }
249 //
250 // }
251 // }
252
253 public void addAnnotation(EditorAnnotation annotation){
254 addAnnotation(annotation, null);
255 }
256
257 public void addAnnotation(EditorAnnotation annotation, Position position){
258 if(position == null){
259 position = new Position(0, 0);
260 }
261
262 this.getAnnotationModel().addAnnotation(annotation, position);
263 }
264
265 /**
266 * <p>setText</p>
267 *
268 * @param text a {@link java.lang.String} object.
269 */
270 public void setText(String text) {
271 if (text == null) {
272 text = "";
273 }
274 try {
275 Assert.isNotNull(text);
276 // TODO figure out why getTextWidget() returns null!
277 if (this.getTextWidget() == null) {
278 return;
279 }
280 Assert.isNotNull(this.getTextWidget());
281 this.getTextWidget().setText(text);
282 } catch (RuntimeException e) {
283 throw e;
284 }
285 }
286
287 /**
288 * <p>setMenu</p>
289 *
290 * @param menu a {@link org.eclipse.swt.widgets.Menu} object.
291 */
292 public void setMenu(Menu menu) {
293 getRulerControl().setMenu(menu);
294 getTextWidget().setMenu(menu);
295 }
296
297 /**
298 * <p>setCursorToEOL</p>
299 */
300 public void setCursorToEOL() {
301 getTextWidget().setCaretOffset(getTextWidget().getText().length());
302 getTextWidget().setFocus();
303 }
304
305
306 /**
307 * <p>getCursorPosition</p>
308 *
309 * @return a int.
310 */
311 public int getCursorPosition(){
312 return getTextWidget().getCaretOffset();
313 }
314
315 /**
316 * <p>setCursorPosition</p>
317 *
318 * @param offset a int.
319 */
320 public void setCursorPosition(int offset){
321 try{
322 getTextWidget().setCaretOffset(offset);
323 }catch(IllegalArgumentException e){
324 // do nothing
325 }
326 }
327
328 /**
329 * <p>createUndoSupport</p>
330 *
331 * @param editorSite a {@link org.eclipse.ui.IEditorSite} object.
332 */
333 public void createUndoSupport(IEditorSite editorSite) {
334
335 IUndoManager undoManager = new TextViewerUndoManager(25);
336 this.setUndoManager(undoManager);
337 undoManager.connect(this);
338
339 // IUndoContext workbenchUndoContext = UiUtil.getWorkbenchUndoContext();
340
341 IUndoContext workbenchUndoContext = ((IUndoManagerExtension)undoManager).getUndoContext();
342
343 OperationHistoryActionHandler undoAction = new UndoActionHandler(editorSite, workbenchUndoContext);
344 // undoAction.setActionDefinitionId(IWorkbenchActionDefinitionIds.UNDO);
345 undoAction.setActionDefinitionId(ActionFactory.UNDO.getId());
346
347 // Create the redo action.
348 OperationHistoryActionHandler redoAction = new RedoActionHandler(editorSite, workbenchUndoContext);
349 // redoAction.setActionDefinitionId(IWorkbenchActionDefinitionIds.REDO);
350 undoAction.setActionDefinitionId(ActionFactory.REDO.getId());
351
352 IActionBars actionBars = editorSite.getActionBars();
353 if (actionBars != null) {
354 // actionBars.setGlobalActionHandler(IWorkbenchActionDefinitionIds.UNDO, undoAction);
355 // actionBars.setGlobalActionHandler(IWorkbenchActionDefinitionIds.REDO, redoAction);
356 actionBars.setGlobalActionHandler(ActionFactory.UNDO.getId(), undoAction);
357 actionBars.setGlobalActionHandler(ActionFactory.REDO.getId(), redoAction);
358
359 }
360
361 // actionBars.setGlobalActionHandler(ActionFactory.UNDO.getId(), undoAction);
362 // actionBars.setGlobalActionHandler(ActionFactory.REDO.getId(), redoAction);
363 }
364
365 /**
366 * <p>createUndoSupport_</p>
367 *
368 * @param editorSite a {@link org.eclipse.ui.IEditorSite} object.
369 */
370 public void createUndoSupport_(IEditorSite editorSite) {
371 IUndoManager undoManager = new TextViewerUndoManager(25);
372 this.setUndoManager(undoManager);
373 undoManager.connect(this);
374 IUndoContext undoContext;
375 if (undoManager instanceof IUndoManagerExtension) {
376 undoContext = ((IUndoManagerExtension)undoManager).getUndoContext();
377
378 OperationHistoryActionHandler undoAction = new UndoActionHandler(editorSite, undoContext);
379 // PlatformUI.getWorkbench().getHelpSystem().setHelp(undoAction, IAbstractTextEditorHelpContextIds.UNDO_ACTION);
380 undoAction.setActionDefinitionId(IWorkbenchActionDefinitionIds.UNDO);
381
382 // Create the redo action.
383 OperationHistoryActionHandler redoAction = new RedoActionHandler(editorSite, undoContext);
384 // PlatformUI.getWorkbench().getHelpSystem().setHelp(redoAction, IAbstractTextEditorHelpContextIds.REDO_ACTION);
385 redoAction.setActionDefinitionId(IWorkbenchActionDefinitionIds.REDO);
386
387
388 IActionBars actionBars = editorSite.getActionBars();
389 if (actionBars != null) {
390 actionBars.setGlobalActionHandler(IWorkbenchActionDefinitionIds.UNDO, undoAction);
391 actionBars.setGlobalActionHandler(IWorkbenchActionDefinitionIds.REDO, redoAction);
392
393 }
394 }
395 }
396
397 }
398