1 package eu
.etaxonomy
.taxeditor
.prototype2
.view
;
3 import java
.beans
.PropertyChangeListener
;
4 import java
.beans
.PropertyChangeSupport
;
6 import java
.util
.Scanner
;
8 import org
.eclipse
.core
.databinding
.Binding
;
9 import org
.eclipse
.core
.databinding
.DataBindingContext
;
10 import org
.eclipse
.core
.databinding
.beans
.BeansObservables
;
11 import org
.eclipse
.core
.databinding
.observable
.value
.IObservableValue
;
12 import org
.eclipse
.core
.resources
.IMarker
;
13 import org
.eclipse
.core
.runtime
.Assert
;
14 import org
.eclipse
.jface
.text
.BadLocationException
;
15 import org
.eclipse
.jface
.text
.Document
;
16 import org
.eclipse
.jface
.text
.IDocument
;
17 import org
.eclipse
.jface
.text
.IDocumentPartitioner
;
18 import org
.eclipse
.jface
.text
.ITypedRegion
;
19 import org
.eclipse
.jface
.text
.Position
;
20 import org
.eclipse
.jface
.text
.TypedRegion
;
21 import org
.eclipse
.jface
.text
.rules
.DefaultPartitioner
;
22 import org
.eclipse
.jface
.text
.rules
.FastPartitioner
;
23 import org
.eclipse
.jface
.text
.rules
.IPartitionTokenScanner
;
24 import org
.eclipse
.jface
.text
.source
.Annotation
;
25 import org
.eclipse
.jface
.text
.source
.AnnotationModel
;
26 import org
.eclipse
.jface
.text
.source
.AnnotationPainter
;
27 import org
.eclipse
.jface
.text
.source
.IAnnotationAccess
;
28 import org
.eclipse
.jface
.text
.source
.IAnnotationAccessExtension
;
29 import org
.eclipse
.jface
.text
.source
.ImageUtilities
;
30 import org
.eclipse
.jface
.text
.source
.SourceViewer
;
31 import org
.eclipse
.swt
.SWT
;
32 import org
.eclipse
.swt
.custom
.StyleRange
;
33 import org
.eclipse
.swt
.custom
.StyledText
;
34 import org
.eclipse
.swt
.events
.FocusEvent
;
35 import org
.eclipse
.swt
.events
.FocusListener
;
36 import org
.eclipse
.swt
.events
.KeyAdapter
;
37 import org
.eclipse
.swt
.events
.KeyEvent
;
38 import org
.eclipse
.swt
.graphics
.Color
;
39 import org
.eclipse
.swt
.graphics
.GC
;
40 import org
.eclipse
.swt
.graphics
.Image
;
41 import org
.eclipse
.swt
.graphics
.RGB
;
42 import org
.eclipse
.swt
.graphics
.Rectangle
;
43 import org
.eclipse
.swt
.layout
.GridData
;
44 import org
.eclipse
.swt
.widgets
.Canvas
;
45 import org
.eclipse
.swt
.widgets
.Composite
;
46 import org
.eclipse
.swt
.widgets
.Display
;
48 import com
.swtdesigner
.SWTResourceManager
;
50 import eu
.etaxonomy
.taxeditor
.prototype2
.view
.nameviewersupport
.AnnotationMarkerAccess
;
51 import eu
.etaxonomy
.taxeditor
.prototype2
.view
.nameviewersupport
.ErrorAnnotation
;
52 import eu
.etaxonomy
.taxeditor
.prototype2
.view
.nameviewersupport
.NamePartitionScanner_
;
55 * Creates zero-length fieldPartitions for Genus, Specific Epithet, etc., then fills them
58 * Partition data are bound to their respective model properties.
67 public class NameViewer_
extends SourceViewer
{
69 final Document document
;
70 final IDocumentPartitioner partitioner
;
71 private TaxonName taxonName
;
72 private DataBindingContext bindingContext
;
73 protected Composite parent
;
75 private BoundPartition
[] fieldPartitions
;
77 StyledText styledText
;
79 // error identifiers, images and colors
80 public static String ERROR_TYPE
= "error.type";
81 public static Image ERROR_IMAGE
;
82 public static final RGB ERROR_RGB
= new RGB(255, 0, 0);
85 private AnnotationModel fAnnotationModel
= new AnnotationModel();
87 NameViewer_(TaxonName taxonName
, DataBindingContext bindingContext
, Composite parent
) {
88 super(parent
, null, SWT
.WRAP
| SWT
.MULTI
| SWT
.RESIZE
); // null -> no vertical ruler
90 this.taxonName
= taxonName
;
91 this.bindingContext
= bindingContext
;
94 Assert
.isNotNull(bindingContext
,
95 "NameViewer_'s binding context must be explicitly set.");
97 fieldPartitions
= new BoundPartition
[] {
98 new BoundPartition("genus", SWT
.ITALIC
),
99 new BoundPartition("specificEpithet", SWT
.BOLD
)
102 document
= new Document(taxonName
.getGenus() + " " + taxonName
.getSpecificEpithet());
104 partitioner
= new NamePartitioner(new NamePartitionScanner_(),
105 NamePartitionScanner_
.PARTITION_TYPES
);
107 partitioner
.connect(document
);
108 document
.setDocumentPartitioner(partitioner
);
110 this.setDocument(document
, fAnnotationModel
); // put this back in nameeditorview so that it functions more like TextViewer
112 styledText
= this.getTextWidget();
113 // styledText.setIndent(8);
114 styledText
.addFocusListener(new FocusListener() {
116 public void focusGained(FocusEvent e
) {
117 ((StyledText
) e
.widget
).setBackground((Display
.getCurrent().getSystemColor(SWT
.COLOR_GRAY
)));
121 public void focusLost(FocusEvent e
) {
122 ((StyledText
) e
.widget
).setBackground((Display
.getCurrent().getSystemColor(SWT
.COLOR_WHITE
)));
127 // annotations section
128 IAnnotationAccess fAnnotationAccess
= new AnnotationMarkerAccess();
130 // to paint the annotations
131 AnnotationPainter ap
= new AnnotationPainter(this, fAnnotationAccess
);
132 ap
.addAnnotationType(ERROR_TYPE
);
133 ap
.setAnnotationTypeColor(ERROR_TYPE
, new Color(Display
.getDefault(), ERROR_RGB
));
135 // this will draw the squigglies under the text
139 ErrorAnnotation errorAnnotation
= new ErrorAnnotation(1, "Learn how to spell \"text!\"");
141 // lets underline the word "texst"
142 fAnnotationModel
.addAnnotation(errorAnnotation
, new Position(1, 5));
148 * Separate out properties that are different for accepted and related names
150 private void setViewerLayoutExtras() {
151 styledText
.setLayoutData(new GridData(SWT
.FILL
, SWT
.CENTER
, true, false, 2, 1));
152 styledText
.setFont(SWTResourceManager
.getFont("Georgia", 12, SWT
.NONE
));
155 public void setBindingContext(DataBindingContext bindingContext
) {
156 this.bindingContext
= bindingContext
;
159 class NamePartitioner
extends FastPartitioner
{
161 List
<ITypedRegion
> wordPartitions
;
163 public NamePartitioner(IPartitionTokenScanner scanner
,
164 String
[] legalContentTypes
) {
165 super(scanner
, legalContentTypes
);
168 public ITypedRegion
[] computePartitioning(int offset
, int length
, boolean includeZeroLengthPartitions
) {
172 // System.out.print("Start re-partition at: " + offset + " -");
173 // for (int i = 0; i < fieldPartitions.length; i++) {
174 // System.out.print(" " + fieldPartitions[i].getOffset());
176 // System.out.println();
178 // // find where the affected partitions begin
179 // while (fieldPartitions[fieldIndex].getOffset() < offset) {
180 // System.out.println(fieldPartitions[fieldIndex].getOffset() + " " + offset);
184 // ITypedRegion[] regions = super.computePartitioning(offset, document.getLength() - offset,
185 // includeZeroLengthPartitions);
186 ITypedRegion
[] regions
= super.computePartitioning(0, document
.getLength(),
187 includeZeroLengthPartitions
);
189 for (int i
= 0; i
< regions
.length
; i
++) {
190 if (regions
[i
].getType() == NamePartitionScanner_
.SINGLE_WORD
) {
191 // for now, assign first word to first fieldPartition, etc.
192 fieldPartitions
[fieldIndex
].setRegion(regions
[i
]);
197 // put zero-length regions in remaining fieldPartitions
198 for (int i
= fieldIndex
; i
< fieldPartitions
.length
; i
++) {
199 fieldPartitions
[fieldIndex
].setRegion(
200 new TypedRegion(document
.getLength(), 0,
201 NamePartitionScanner_
.SINGLE_WORD
));
207 public void connect(IDocument document
, boolean delayInitialise
)
209 super.connect(document
, delayInitialise
);
210 // computePartitioning(0, document.getLength(), false);
214 class BoundPartition
{
215 private ITypedRegion region
;
216 private Binding binding
;
217 private String field
; // the name field to track
218 private String value
; // the current value in this partition
221 private StyleRange style
= new StyleRange();
223 BoundPartition (String field
) {
231 BoundPartition (String field
, int fontStyle
) {
233 style
.fontStyle
= fontStyle
;
236 private void bindPartition() {
237 IObservableValue observePartitionValue
=
238 BeansObservables
.observeValue(this, "text");
239 IObservableValue observeModelValue
=
240 BeansObservables
.observeValue(taxonName
, field
);
241 this.binding
= bindingContext
.bindValue(
242 observePartitionValue
, observeModelValue
,
246 public void setRegion (ITypedRegion region
) {
247 this.region
= region
;
248 this.length
= region
.getLength();
249 this.offset
= region
.getOffset();
251 String oldValue
= this.value
;
253 this.value
= document
.get(this.offset
, this.length
);
254 } catch (BadLocationException e
) {
255 // TODO Auto-generated catch block
258 firePropertyChange("text",oldValue
,this.value
);
260 this.style
.start
= this.offset
;
261 this.style
.length
= this.length
;
262 styledText
.setStyleRange(this.style
);
265 public int getLength () {
269 public int getOffset () {
273 public void setText(String newText
) {
275 document
.replace(region
.getOffset(), region
.getLength(), newText
);
276 } catch (BadLocationException e
) {
277 // TODO Auto-generated catch block
282 public String
getText() {
286 protected final PropertyChangeSupport propertyChangeSupport
= new PropertyChangeSupport(this);
287 public void addPropertyChangeListener(PropertyChangeListener listener
) {
288 propertyChangeSupport
.addPropertyChangeListener(listener
);
291 public void addPropertyChangeListener(String propertyName
,
292 PropertyChangeListener listener
) {
293 propertyChangeSupport
.addPropertyChangeListener(propertyName
, listener
);
296 public void removePropertyChangeListener(PropertyChangeListener listener
) {
297 propertyChangeSupport
.removePropertyChangeListener(listener
);
300 public void removePropertyChangeListener(String propertyName
,
301 PropertyChangeListener listener
) {
302 propertyChangeSupport
.removePropertyChangeListener(propertyName
,
306 protected void firePropertyChange(String propertyName
, Object oldValue
,
308 propertyChangeSupport
.firePropertyChange(propertyName
, oldValue
,
312 // public StyleRange getStyle() {
316 // public void setStyle(StyleRange style) {
317 // this.style = style;
321 // class AnnotationMarkerAccess implements IAnnotationAccess, IAnnotationAccessExtension {
322 // public Object getType(Annotation annotation) {
323 // return annotation.getType();
326 // public boolean isMultiLine(Annotation annotation) {
330 // public boolean isTemporary(Annotation annotation) {
331 // return !annotation.isPersistent();
334 // public String getTypeLabel(Annotation annotation) {
335 // if (annotation instanceof ErrorAnnotation)
341 // public int getLayer(Annotation annotation) {
342 // if (annotation instanceof ErrorAnnotation)
343 // return ((ErrorAnnotation)annotation).getLayer();
348 // public void paint(Annotation annotation, GC gc, Canvas canvas, Rectangle bounds) {
349 // ImageUtilities.drawImage(((ErrorAnnotation)annotation).getImage(),
350 // gc, canvas, bounds, SWT.CENTER, SWT.TOP);
353 // public boolean isPaintable(Annotation annotation) {
354 // if (annotation instanceof ErrorAnnotation)
355 // return ((ErrorAnnotation)annotation).getImage() != null;
360 // public boolean isSubtype(Object annotationType, Object potentialSupertype) {
361 // if (annotationType.equals(potentialSupertype))
368 // public Object[] getSupertypes(Object annotationType) {
369 // return new Object[0];
373 // one error annotation
374 // class ErrorAnnotation extends Annotation {
375 // private IMarker marker;
376 // private String text;
378 // private Position position;
380 // public ErrorAnnotation(IMarker marker) {
381 // this.marker = marker;
384 // public ErrorAnnotation(int line, String text) {
385 // super(ERROR_TYPE, true, null);
386 // this.marker = null;
391 // public IMarker getMarker() {
395 // public int getLine() {
399 // public String getText() {
403 // public Image getImage() {
404 // return ERROR_IMAGE;
407 // public int getLayer() {
411 // public String getType() {
412 // return ERROR_TYPE;
415 // public Position getPosition() {
419 // public void setPosition(Position position) {
420 // this.position = position;