Project

General

Profile

Download (12.7 KB) Statistics
| Branch: | Tag: | Revision:
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.Canvas;
32
import org.eclipse.swt.widgets.Composite;
33
import org.eclipse.swt.widgets.Control;
34
import org.eclipse.swt.widgets.Display;
35
import org.eclipse.swt.widgets.Layout;
36
import org.eclipse.swt.widgets.Menu;
37
import org.eclipse.ui.IActionBars;
38
import org.eclipse.ui.IEditorSite;
39
import org.eclipse.ui.actions.ActionFactory;
40
import org.eclipse.ui.forms.widgets.TableWrapData;
41
import org.eclipse.ui.forms.widgets.TableWrapLayout;
42
import org.eclipse.ui.operations.OperationHistoryActionHandler;
43
import org.eclipse.ui.operations.RedoActionHandler;
44
import org.eclipse.ui.operations.UndoActionHandler;
45
import org.eclipse.ui.texteditor.DefaultMarkerAnnotationAccess;
46
import org.eclipse.ui.texteditor.IWorkbenchActionDefinitionIds;
47

    
48
import eu.etaxonomy.cdm.model.name.TaxonNameBase;
49
import eu.etaxonomy.cdm.model.taxon.Taxon;
50
import eu.etaxonomy.cdm.strategy.parser.ParserProblem;
51
import eu.etaxonomy.taxeditor.editor.EditorUtil;
52
import eu.etaxonomy.taxeditor.editor.ViewerConfiguration;
53
import eu.etaxonomy.taxeditor.preference.Resources;
54

    
55
/**
56
 * SourceViewer implementation called by NameComposite.
57
 *
58
 * @author p.ciardelli
59
 * @created 27.05.2008
60
 * @version 1.0
61
 */
62
public class NameViewer extends SourceViewer {
63
	private static final Logger logger = Logger
64
			.getLogger(NameViewer.class);
65
		
66
	/** Constant <code>RULER_WIDTH=16</code> */
67
	public static final int RULER_WIDTH = 16;
68
	
69
	private IVerticalRuler ruler;
70
	private AnnotationModel annotationModel;
71

    
72
	/**
73
	 * <p>Constructor for NameViewer.</p>
74
	 *
75
	 * @param parent a {@link org.eclipse.swt.widgets.Composite} object.
76
	 */
77
	public NameViewer(Composite parent) {
78
		super(parent, new RulerWithIcon(RULER_WIDTH), SWT.WRAP | SWT.MULTI | SWT.RESIZE);
79
											
80
		this.ruler = getVerticalRuler();
81
				
82
		setBackground(EditorUtil.getColor(Resources.COLOR_COMPOSITE_BACKGROUND));
83
				
84
		Canvas canvas = (Canvas) getControl();
85
		TableWrapLayout layout = (TableWrapLayout) canvas.getLayout();
86
		layout.topMargin = 0;
87
		layout.rightMargin = 0;
88
		layout.bottomMargin = 0;
89
		layout.leftMargin = 0;
90
		layout.verticalSpacing = 10;
91
		layout.horizontalSpacing = 0;
92
		
93
		canvas.setLayout(layout);
94
		
95
		// Lay out the viewer's widgets
96
		TableWrapData twdata = new TableWrapData(TableWrapData.FILL_GRAB);
97
		getControl().setLayoutData(twdata);
98
		
99
		twdata = new TableWrapData(TableWrapData.FILL_GRAB);
100
		getTextWidget().setLayoutData(twdata);
101
		getTextWidget().setLineSpacing(5);
102
		
103
		// Default implementation adds ruler after the text widget, then 
104
		//	uses a custom layout to display it before the text widget
105
		ruler.getControl().moveAbove(getTextWidget());
106

    
107
		annotationModel = new AnnotationModel();
108
		this.setDocument(new Document(""), annotationModel);
109
		
110
		createAnnotationPainter();
111

    
112
		this.configure(new ViewerConfiguration());		
113
		
114
//		setDecorationSupport();
115
//		DocumentUndoManagerRegistry.connect(this.getDocument());
116
//		IDocumentUndoManager docUndoManager = DocumentUndoManagerRegistry.getDocumentUndoManager(this.getDocument());
117
		
118
		/**
119
		getEditorSite().getActionBars().setGlobalActionHandler(ActionFactory.UNDO.getId(), new UndoActionHandler(getSite(), undoContext));
120
		getEditorSite().getActionBars().setGlobalActionHandler(ActionFactory.REDO.getId(), new RedoActionHandler(getSite(), undoContext));		
121
		**/
122
	}
123
	
124
	/**
125
	 * <p>setBackground</p>
126
	 *
127
	 * @param color a {@link org.eclipse.swt.graphics.Color} object.
128
	 */
129
	public void setBackground(Color color) {
130
		
131
		// Set background color of ruler
132
		ruler.getControl().setBackground(color);
133

    
134
		// Set background color of text widget
135
		getTextWidget().setBackground(color);
136
		
137
		// Set background color of strip between ruler and textWidget
138
		getTextWidget().getParent().setBackground(color); 
139
	}
140
	
141
	/**
142
	 * <p>getRulerControl</p>
143
	 *
144
	 * @return a {@link org.eclipse.swt.widgets.Control} object.
145
	 */
146
	public Control getRulerControl() {
147
		return ruler.getControl();
148
	}
149

    
150
	/**
151
	 * <p>setIcon</p>
152
	 *
153
	 * @param icon a {@link org.eclipse.swt.graphics.Image} object.
154
	 */
155
	public void setIcon(Image icon) {
156
		if (ruler instanceof RulerWithIcon) {
157
			((RulerWithIcon) ruler).setIcon(icon);
158
		} else {
159
			logger.warn("Viewer's IVerticalRuler is not an instance of RulerWithIcon.");
160
		}
161
	}
162
	
163
	/* (non-Javadoc)
164
	 * @see org.eclipse.jface.text.source.SourceViewer#createLayout()
165
	 */
166
	/**
167
	 * <p>createLayout</p>
168
	 *
169
	 * @return a {@link org.eclipse.swt.widgets.Layout} object.
170
	 */
171
	protected Layout createLayout() {
172
		TableWrapLayout layout = new TableWrapLayout();
173
		layout.numColumns = 2;
174
		layout.verticalSpacing = 0;
175
		return layout;
176
	}
177
		
178
	private void createAnnotationPainter(){
179
		// Annotations section
180
		IAnnotationAccess fAnnotationAccess = new DefaultMarkerAnnotationAccess();
181
		
182
		// To paint the annotations
183
		AnnotationPainter annotationPainter = new AnnotationPainter(this, fAnnotationAccess);
184

    
185
		// Default SquigglesStrategy doesn't recognize line wraps
186
		annotationPainter.addDrawingStrategy(LineWrapSquigglesStrategy.ID, new LineWrapSquigglesStrategy());
187
		
188
		// Add ability to paint red squigglies
189
		annotationPainter.addAnnotationType(EditorAnnotation.ERROR_TYPE, LineWrapSquigglesStrategy.ID);
190
		annotationPainter.setAnnotationTypeColor(EditorAnnotation.ERROR_TYPE, 
191
				new Color(Display.getDefault(), EditorAnnotation.ERROR_RGB));
192

    
193
		// Add ability to paint yellow squigglies
194
		annotationPainter.addAnnotationType(EditorAnnotation.WARNING_TYPE, LineWrapSquigglesStrategy.ID);
195
		annotationPainter.setAnnotationTypeColor(EditorAnnotation.WARNING_TYPE, 
196
				new Color(Display.getDefault(), EditorAnnotation.WARNING_RGB));
197
		
198
		this.addPainter(annotationPainter);
199
	}
200

    
201

    
202
	/**
203
	 * <p>clearErrors</p>
204
	 */
205
	public void clearErrors() {
206
		Iterator<Annotation> annotations = this.getAnnotationModel().getAnnotationIterator();
207
		while (annotations.hasNext()) {
208
			Annotation annotation = annotations.next(); 
209
			if (annotation.getType().equals(EditorAnnotation.ERROR_TYPE) || annotation.getType().equals(EditorAnnotation.WARNING_TYPE)) {
210
				this.getAnnotationModel().removeAnnotation(annotation);
211
			}
212
		}
213
	}
214
	
215
	/**
216
	 * If <code>name.hasProblem()</code> is <code>true</code>, underlines section
217
	 * of text bounded by <code>name.getProblemStarts()</code> and
218
	 * <code>name.getProblemEnds()</code>.
219
	 *
220
	 * @param name a {@link eu.etaxonomy.cdm.model.name.TaxonNameBase} object.
221
	 */
222
	public void setShowParsingErrors(TaxonNameBase<?, ?> name) {
223
				
224
		String text = this.getTextWidget().getText();
225
						
226
		if (name.hasProblem() && text.length() > 0) {
227
			int start = name.getProblemStarts();
228
			int length = name.getProblemEnds() - start;
229
			
230
			if (start == -1 || name.getProblemEnds() == -1) {
231
				return;
232
			}
233
			
234
			// Don't let squigglies try to draw beyond the end of the text
235
			if (text.length() < start + length) {
236
				length = text.length() - start;
237
			}
238
			
239
			for (ParserProblem problem : name.getParsingProblems()) {
240
				
241
				String type = null;
242
				if (problem.isWarning()) {
243
					type = EditorAnnotation.WARNING_TYPE;
244
				}
245
				if (problem.isError()) {
246
					type = EditorAnnotation.ERROR_TYPE;
247
				}
248
				if (type == null) {
249
					continue;
250
				}
251
				this.getAnnotationModel().addAnnotation(
252
						new EditorAnnotation(type, 0, problem.getMessage()), 
253
						new Position(start, length));
254
			}
255
		}
256
	}
257
	
258
	
259
	/**
260
	 * <p>setShowSecError</p>
261
	 *
262
	 * @param taxon a {@link eu.etaxonomy.cdm.model.taxon.Taxon} object.
263
	 */
264
	public void setShowSecError(Taxon taxon) {
265
		
266
		// If taxon has no sec, show an annotation
267
		if (taxon.getSec() == null) {
268
			
269
			String text = "This taxon requires a sec. reference.";
270
			
271
			this.getAnnotationModel().addAnnotation(
272
					new EditorAnnotation(0, text),
273
					new Position(0, 0));
274
		}
275
	}
276

    
277
			
278
	/**
279
	 * <p>setText</p>
280
	 *
281
	 * @param text a {@link java.lang.String} object.
282
	 */
283
	public void setText(String text) {
284
		if (text == null) {
285
			text = "";
286
		}
287
		try {
288
			Assert.isNotNull(text);
289
			// TODO figure out why getTextWidget() returns null!
290
			if (this.getTextWidget() == null) {
291
				return;
292
			}
293
			Assert.isNotNull(this.getTextWidget());
294
			this.getTextWidget().setText(text);
295
		} catch (RuntimeException e) {
296
			logger.error("Could not set the text for a name viewer");
297
			throw e;
298
		}
299
	}
300
	
301
	/**
302
	 * <p>setMenu</p>
303
	 *
304
	 * @param menu a {@link org.eclipse.swt.widgets.Menu} object.
305
	 */
306
	public void setMenu(Menu menu) {
307
		getRulerControl().setMenu(menu);
308
		getTextWidget().setMenu(menu);
309
	}
310

    
311
	/**
312
	 * <p>setCursorToEOL</p>
313
	 */
314
	public void setCursorToEOL() {
315
		getTextWidget().setCaretOffset(getTextWidget().getText().length());
316
		getTextWidget().setFocus();
317
	}
318

    
319
	
320
	/**
321
	 * <p>getCursorPosition</p>
322
	 *
323
	 * @return a int.
324
	 */
325
	public int getCursorPosition(){
326
		return getTextWidget().getCaretOffset();
327
	}
328
	
329
	/**
330
	 * <p>setCursorPosition</p>
331
	 *
332
	 * @param offset a int.
333
	 */
334
	public void setCursorPosition(int offset){
335
		try{
336
			getTextWidget().setCaretOffset(offset);
337
		}catch(IllegalArgumentException e){
338
			// do nothing
339
		}
340
	}
341

    
342
	/**
343
	 * <p>createUndoSupport</p>
344
	 *
345
	 * @param editorSite a {@link org.eclipse.ui.IEditorSite} object.
346
	 */
347
	public void createUndoSupport(IEditorSite editorSite) {
348

    
349
		IUndoManager undoManager = new TextViewerUndoManager(25);
350
		this.setUndoManager(undoManager);
351
		undoManager.connect(this);
352
		
353
//		IUndoContext workbenchUndoContext = UiUtil.getWorkbenchUndoContext();
354
		
355
		IUndoContext workbenchUndoContext = ((IUndoManagerExtension)undoManager).getUndoContext();
356
		
357
		OperationHistoryActionHandler undoAction = new UndoActionHandler(editorSite, workbenchUndoContext);
358
//		undoAction.setActionDefinitionId(IWorkbenchActionDefinitionIds.UNDO);
359
		undoAction.setActionDefinitionId(ActionFactory.UNDO.getId());
360
		
361
		// Create the redo action.
362
		OperationHistoryActionHandler redoAction = new RedoActionHandler(editorSite, workbenchUndoContext);
363
//		redoAction.setActionDefinitionId(IWorkbenchActionDefinitionIds.REDO);
364
		undoAction.setActionDefinitionId(ActionFactory.REDO.getId());
365

    
366
		IActionBars actionBars = editorSite.getActionBars();
367
		if (actionBars != null) {
368
//				actionBars.setGlobalActionHandler(IWorkbenchActionDefinitionIds.UNDO, undoAction);
369
//				actionBars.setGlobalActionHandler(IWorkbenchActionDefinitionIds.REDO, redoAction);
370
			actionBars.setGlobalActionHandler(ActionFactory.UNDO.getId(), undoAction);
371
			actionBars.setGlobalActionHandler(ActionFactory.REDO.getId(), redoAction);
372
			
373
		}		
374
		
375
//		actionBars.setGlobalActionHandler(ActionFactory.UNDO.getId(), undoAction);
376
//		actionBars.setGlobalActionHandler(ActionFactory.REDO.getId(), redoAction);
377
	}
378
	
379
	/**
380
	 * <p>createUndoSupport_</p>
381
	 *
382
	 * @param editorSite a {@link org.eclipse.ui.IEditorSite} object.
383
	 */
384
	public void createUndoSupport_(IEditorSite editorSite) {
385
		IUndoManager undoManager = new TextViewerUndoManager(25);
386
		this.setUndoManager(undoManager);
387
		undoManager.connect(this);
388
		IUndoContext undoContext;
389
		if (undoManager instanceof IUndoManagerExtension) {
390
			undoContext = ((IUndoManagerExtension)undoManager).getUndoContext();
391
		
392
			OperationHistoryActionHandler undoAction = new UndoActionHandler(editorSite, undoContext);
393
//			PlatformUI.getWorkbench().getHelpSystem().setHelp(undoAction, IAbstractTextEditorHelpContextIds.UNDO_ACTION);
394
			undoAction.setActionDefinitionId(IWorkbenchActionDefinitionIds.UNDO);
395
			
396
			// Create the redo action.
397
			OperationHistoryActionHandler redoAction = new RedoActionHandler(editorSite, undoContext);
398
//			PlatformUI.getWorkbench().getHelpSystem().setHelp(redoAction, IAbstractTextEditorHelpContextIds.REDO_ACTION);
399
			redoAction.setActionDefinitionId(IWorkbenchActionDefinitionIds.REDO);
400

    
401

    
402
			IActionBars actionBars = editorSite.getActionBars();
403
			if (actionBars != null) {
404
				actionBars.setGlobalActionHandler(IWorkbenchActionDefinitionIds.UNDO, undoAction);
405
				actionBars.setGlobalActionHandler(IWorkbenchActionDefinitionIds.REDO, redoAction);
406
				
407
			}
408
		}
409
	}
410
}
411

    
(19-19/22)