2 * Copyright (C) 2007 EDIT
3 * European Distributed Institute of Taxonomy
4 * http://www.e-taxonomy.eu
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.
10 package eu
.etaxonomy
.taxeditor
.editor
.name
.container
;
12 import java
.util
.List
;
15 import org
.eclipse
.core
.runtime
.Assert
;
16 import org
.eclipse
.jface
.dialogs
.Dialog
;
17 import org
.eclipse
.jface
.text
.IDocument
;
18 import org
.eclipse
.jface
.text
.Position
;
19 import org
.eclipse
.jface
.window
.DefaultToolTip
;
20 import org
.eclipse
.swt
.custom
.StyledText
;
21 import org
.eclipse
.swt
.dnd
.DND
;
22 import org
.eclipse
.swt
.dnd
.DragSource
;
23 import org
.eclipse
.swt
.dnd
.Transfer
;
24 import org
.eclipse
.swt
.events
.ControlAdapter
;
25 import org
.eclipse
.swt
.events
.ControlEvent
;
26 import org
.eclipse
.swt
.events
.ControlListener
;
27 import org
.eclipse
.swt
.events
.FocusAdapter
;
28 import org
.eclipse
.swt
.events
.FocusEvent
;
29 import org
.eclipse
.swt
.events
.FocusListener
;
30 import org
.eclipse
.swt
.events
.ModifyEvent
;
31 import org
.eclipse
.swt
.events
.ModifyListener
;
32 import org
.eclipse
.swt
.events
.MouseAdapter
;
33 import org
.eclipse
.swt
.events
.MouseEvent
;
34 import org
.eclipse
.swt
.graphics
.Color
;
35 import org
.eclipse
.swt
.graphics
.Font
;
36 import org
.eclipse
.swt
.graphics
.Image
;
37 import org
.eclipse
.swt
.widgets
.Composite
;
38 import org
.eclipse
.swt
.widgets
.Control
;
39 import org
.eclipse
.swt
.widgets
.Display
;
40 import org
.eclipse
.swt
.widgets
.Label
;
41 import org
.eclipse
.swt
.widgets
.Menu
;
42 import org
.eclipse
.ui
.forms
.IFormPart
;
43 import org
.eclipse
.ui
.forms
.IManagedForm
;
44 import org
.eclipse
.ui
.forms
.widgets
.TableWrapData
;
45 import org
.eclipse
.ui
.forms
.widgets
.TableWrapLayout
;
47 import eu
.etaxonomy
.cdm
.common
.CdmUtils
;
48 import eu
.etaxonomy
.cdm
.hibernate
.HibernateProxyHelper
;
49 import eu
.etaxonomy
.cdm
.model
.name
.NameRelationship
;
50 import eu
.etaxonomy
.cdm
.model
.name
.NonViralName
;
51 import eu
.etaxonomy
.cdm
.model
.name
.TaxonNameBase
;
52 import eu
.etaxonomy
.cdm
.model
.taxon
.TaxonBase
;
53 import eu
.etaxonomy
.cdm
.strategy
.parser
.ParserProblem
;
54 import eu
.etaxonomy
.taxeditor
.editor
.CdmDataTransfer
;
55 import eu
.etaxonomy
.taxeditor
.editor
.EditorUtil
;
56 import eu
.etaxonomy
.taxeditor
.editor
.name
.TaxonNameEditor
;
57 import eu
.etaxonomy
.taxeditor
.editor
.name
.container
.EditorAnnotation
.EditorAnnotationType
;
58 import eu
.etaxonomy
.taxeditor
.editor
.name
.dnd
.NameEditorDragListener
;
59 import eu
.etaxonomy
.taxeditor
.editor
.name
.dnd
.NameEditorDragSourceEffect
;
60 import eu
.etaxonomy
.taxeditor
.editor
.name
.operation
.CreateSynonymInNewGroupOperation
;
61 import eu
.etaxonomy
.taxeditor
.labels
.ILabelImageStrategy
;
62 import eu
.etaxonomy
.taxeditor
.labels
.LabelImageProvider
;
63 import eu
.etaxonomy
.taxeditor
.model
.IElementHasDetails
;
64 import eu
.etaxonomy
.taxeditor
.model
.NameHelper
;
65 import eu
.etaxonomy
.taxeditor
.model
.TextHelper
;
66 import eu
.etaxonomy
.taxeditor
.parser
.ParseHandler
;
67 import eu
.etaxonomy
.taxeditor
.preference
.Resources
;
70 * Formats <code>GroupedComposite</code> with cosmetic and layout properties
71 * specific to the Editor. This should be used to maintain a consistent look and
72 * feel for all Editor freetext area components, such as
73 * DescriptionElementComposite.
75 * Requires an <code>IManagedForm</code>, whose <code>input</code> is set to the
76 * contents of {@link #getData()} when the <code>GroupedComposite</code> gets
77 * focus, i.e. to populate the property sheet with the data.
80 * The <code>IManagedForm</code> is also required to have a <code>Taxon</code>
81 * in its own <code>getData()</code>.
84 * The <code>IManagedForm</code> can also used for drawing borders by calling
85 * the method <code>createBorderSupport()</code>.
93 abstract public class AbstractGroupedContainer
<T
extends TaxonBase
> implements
94 IFormPart
, IContainerConstants
, IElementHasDetails
{
96 protected ParseHandler parseHandler
;
98 private FocusListener nameCompositeFocusListener
;
99 private ModifyListener nameCompositeModifyListener
;
101 protected NameViewer nameViewer
;
103 private AbstractGroup group
;
105 private Label nonEditableInfoLabel
;
106 private DefaultToolTip nonEditableInfoHover
;
108 private static AbstractGroupedContainer selection
;
110 private FocusListener focusListener
;
111 private LineBreakListener lineBreakListener
;
113 private int cursorPosition
;
115 protected Composite control
;
117 private Color backgroundColor
;
118 private boolean isDirty
;
122 * Constructor for AbstractGroupedContainer.
126 * a {@link eu.etaxonomy.taxeditor.editor.name.TaxonNameEditor}
130 * {@link eu.etaxonomy.taxeditor.editor.name.container.AbstractGroup}
137 public AbstractGroupedContainer(T taxonBase
) {
139 parseHandler
= ParseHandler
.NewInstance(taxonBase
.getName());
142 public void createContent() {
146 createLineWrapSupport();
147 createLineBreakListener();
149 setMenu(getEditor().getMenu());
151 setDraggableControl(new Control
[] { getControl(),
152 getNameViewer().getRulerControl() });
154 createEmptyViewerPrompt(EMPTY_NAME_PROMPT
);
156 initializeComposite();
168 protected void createListener() {
169 nameCompositeModifyListener
= new ModifyListener() {
171 public void modifyText(ModifyEvent e
) {
172 // mark the composite dirty
175 String text
= nameViewer
.getTextWidget().getText();
177 NonViralName name
= parseHandler
.parse(text
);
178 getTaxonBase().setName(name
);
179 getTaxonBase().setTitleCache((getTaxonBase().generateTitle()));
181 // show errors resulting from parsing
182 calculateAnnotations();
183 // store the position of the cursor
185 // notify selection listener
186 setDelayedSelection();
189 nameCompositeFocusListener
= new FocusAdapter() {
195 * org.eclipse.swt.events.FocusAdapter#focusLost(org.eclipse.swt
196 * .events.FocusEvent)
199 public void focusLost(FocusEvent e
) {
209 private void addListener() {
210 getNameViewer().getTextWidget().addModifyListener(
211 nameCompositeModifyListener
);
212 getNameViewer().getTextWidget().addFocusListener(
213 nameCompositeFocusListener
);
216 private void removeListener() {
217 getNameViewer().getTextWidget().removeModifyListener(
218 nameCompositeModifyListener
);
219 getNameViewer().getTextWidget().removeFocusListener(
220 nameCompositeFocusListener
);
224 * Initialize the composite specific code
226 protected abstract void initializeComposite();
233 * @return a {@link java.lang.String} object.
235 protected String
getEmptyTextPrompt() {
236 return EMPTY_NAME_PROMPT
;
242 private void showNameRelations() {
243 TaxonNameBase
<?
, ?
> name
= getName();
248 ILabelImageStrategy strategy
= LabelImageProvider
249 .getLabelStrategy(name
);
250 LabelImageProvider labelProvider
= new LabelImageProvider(strategy
);
252 Set
<NameRelationship
> nameRelations
= name
.getNameRelations();
253 if (nameRelations
.size() == 0) {
256 // for (NameRelationship nameRelation : nameRelations) {
257 // String typeLabel = null;
258 // TaxonNameBase<?, ?> relatedName = null;
260 // if (name.equals(nameRelation.getFromName())) {
261 // typeLabel = labelProvider.getNameRelationTypeLabel(
262 // nameRelation.getType());
263 // relatedName = nameRelation.getToName();
265 // typeLabel = labelProvider.getNameRelationTypeInverseLabel(
266 // nameRelation.getType());
267 // relatedName = nameRelation.getFromName();
270 // setNonEditableInfo(typeLabel + " " +
271 // NameHelper.getDisplayName(relatedName));
280 protected void initTextViewer() {
282 // showNameRelations();
288 String text
= NameHelper
.getDisplayNameWithRef(getData());
290 if (text
.length() == 0) {
293 getNameViewer().setText(text
);
296 calculateAnnotations();
304 synchronized protected void calculateAnnotations() {
305 getNameViewer().clearAnnotations();
312 public void showAnnotations() {
314 if (getName().hasProblem()) {
315 showParsingProblems();
318 if (!isNameParsable()) {
321 new EditorAnnotation(EditorAnnotationType
.WARNING
,
323 "This name may only be edited in the details view."));
326 if (isNameUsedMultipleTimes()) {
327 getNameViewer().addAnnotation(
328 new EditorAnnotation(EditorAnnotationType
.WARNING
, 0,
329 "This taxons name is used multiple times."));
337 private void showParsingProblems() {
338 String text
= getNameViewer().getTextWidget().getText();
340 List
<ParserProblem
> parsingProblems
= getName().getParsingProblems();
342 for (ParserProblem problem
: parsingProblems
) {
343 getNameViewer().addAnnotation(new EditorAnnotation(problem
),
344 getParsingProblemPosition());
348 private Position
getParsingProblemPosition() {
349 String text
= getNameViewer().getTextWidget().getText();
351 if (getName().hasProblem() && text
.length() > 0) {
352 int start
= getName().getProblemStarts();
353 int length
= getName().getProblemEnds() - start
;
355 if (start
== -1 || getName().getProblemEnds() == -1) {
359 // Don't let squigglies try to draw beyond the end of the text
360 if (text
.length() < start
+ length
) {
361 length
= text
.length() - start
;
364 return new Position(start
, length
);
375 * a {@link java.lang.String} object.
377 protected void handleSplitText(String text
) {
378 // Create a synonym in a new homotypic group using text as name
379 TaxonNameBase synonymName
= ParseHandler
380 .parseReferencedName(text
, null);
382 EditorUtil
.executeOperation(new CreateSynonymInNewGroupOperation(
383 "New Heterotypic Synonym", getEditor().getUndoContext(),
384 getEditor().getTaxon(), synonymName
, getEditor()));
388 * Refreshes the display with latest data from the model.
390 * Note: Will not parse the text and not calculate errors!
392 public void refresh() {
393 // showNameRelations();
395 String text
= NameHelper
.getDisplayNameWithRef(getTaxonBase());
397 if (getNameViewer().getTextWidget() == null) {
398 // we might get here via dnd. Look slike it can be ignored
402 if (text
.length() == 0) {
404 } else if (!getNameViewer().getTextWidget().getText().equals(text
)) {
406 getNameViewer().getTextWidget().setText(text
);
410 updateNonEditableInfo();
422 protected abstract void updateIcon();
424 protected abstract void updateIndent();
428 * updateNonEditableInfo
431 protected abstract void updateNonEditableInfo();
436 private void enableFreeText() {
437 setEnabled(isFreetextEditingAllowed());
441 * Checks whether the freetext should be editable based on specific empty
446 private boolean isFreetextEditingAllowed() {
447 NonViralName name
= (NonViralName
) HibernateProxyHelper
449 boolean enableFreetext
= true;
451 enableFreetext
|= isNameUsedMultipleTimes();
452 enableFreetext
&= isNameParsable();
454 return enableFreetext
;
457 private boolean isNameUsedMultipleTimes() {
458 if (getName().getTaxonBases().size() > 1) {
464 private boolean isNameParsable() {
465 TaxonNameBase name
= getName();
467 boolean isParsable
= true;
468 isParsable
&= CdmUtils
.isEmpty(name
.getAppendedPhrase()); // taxonFieldsEmpty();
470 if (name
instanceof NonViralName
) {
471 NonViralName nonViralName
= (NonViralName
) name
;
472 isParsable
&= !nonViralName
.isProtectedAuthorshipCache();
473 isParsable
&= !nonViralName
.isProtectedNameCache();
480 * Parse the text and calculate errors
482 public void parseAndCalculateAnnotations() {
484 String unparsedNameString
= getNameViewer().getTextWidget().getText();
485 parseHandler
.parse(unparsedNameString
);
487 calculateAnnotations();
495 * @return the taxonBase
497 public T
getTaxonBase() {
506 * @return a {@link eu.etaxonomy.cdm.model.name.TaxonNameBase} object.
508 public TaxonNameBase
getName() {
509 return (TaxonNameBase
) HibernateProxyHelper
.deproxy(getTaxonBase()
518 public void persistName() {
520 getNameViewer().getTextWidget().setEnabled(false);
521 final String unparsedNameString
= getNameViewer().getTextWidget()
523 // Job job = new Job("Persisting Name"){
526 // protected IStatus run(IProgressMonitor monitor) {
528 final NonViralName name
= parseHandler
529 .parseAndResolveDuplicates(unparsedNameString
);
531 // Display.getDefault().asyncExec(new Runnable(){
532 // public void run() {
533 getTaxonBase().setName(name
);
534 getTaxonBase().setTitleCache((getTaxonBase().generateTitle()));
536 getNameViewer().getTextWidget().setEnabled(true);
541 // return Status.OK_STATUS;
546 // job.setPriority(Job.DECORATE);
553 * Getter for the field <code>group</code>.
557 * {@link eu.etaxonomy.taxeditor.editor.name.container.AbstractGroup}
560 public AbstractGroup
getGroup() {
562 throw new IllegalStateException("Group shall not be null.");
572 public void remove() {
573 getGroup().remove(this);
581 protected void createControl() {
582 control
= getEditor().getToolkit().createComposite(
583 getGroup().getControl());
585 control
.setLayoutData(new TableWrapData(TableWrapData
.FILL_GRAB
));
586 TableWrapLayout layout
= new TableWrapLayout();
587 layout
.leftMargin
= 0;
588 layout
.rightMargin
= 0;
589 layout
.topMargin
= 5;
590 layout
.bottomMargin
= 5;
592 layout
.verticalSpacing
= 0;
593 layout
.horizontalSpacing
= 0;
595 control
.setLayout(layout
);
602 protected TaxonNameEditor
getEditor() {
603 return getGroup().getEditor();
608 * Getter for the field <code>control</code>.
611 * @return a {@link org.eclipse.swt.widgets.Composite} object.
613 public Composite
getControl() {
619 * createLineWrapSupport
622 protected void createLineWrapSupport() {
623 new LineWrapSupport(getNameViewer(), getEditor().getManagedForm());
631 protected void createTextViewer() {
632 nameViewer
= new NameViewer(control
);
634 focusListener
= new FocusAdapter() {
636 public void focusGained(FocusEvent e
) {
640 for (AbstractGroupedContainer container
: getEditor()
641 .getGroupedContainers()) {
642 container
.colorSelected(NOT_SELECTED
);
644 getEditor().getManagedForm().setInput(
645 AbstractGroupedContainer
.this);
647 colorSelected(SELECTED_FOCUS
);
650 nameViewer
.getTextWidget().addFocusListener(focusListener
);
653 MouseAdapter mouseListener
= new MouseAdapter() {
655 public void mouseDown(MouseEvent e
) {
659 control
.addMouseListener(mouseListener
);
660 nameViewer
.getRulerControl().addMouseListener(mouseListener
);
661 nameViewer
.getTextWidget().addMouseListener(mouseListener
);
670 * a {@link org.eclipse.swt.graphics.Image} object.
672 public void setIcon(Image icon
) {
673 getNameViewer().setIcon(icon
);
684 public void setIndent(int indent
) {
685 if (control
.getLayout() instanceof TableWrapLayout
) {
686 TableWrapLayout layout
= ((TableWrapLayout
) control
.getLayout());
687 layout
.leftMargin
= indent
;
688 layout
.rightMargin
= ACCEPTED_INDENT
;
689 control
.setLayout(layout
);
692 new RuntimeException(
693 "Couldn't indent - composite's layout must be TableWrapLayout.");
702 public void setSelected() {
703 getNameViewer().getTextWidget().setFocus();
713 public boolean isSelected() {
714 return getEditor().getSelectedContainer() == this;
725 public void colorSelected(int mode
) {
726 if (!control
.isDisposed()) {
727 String colorString
= null;
731 colorString
= Resources
.COLOR_CONTROL_SELECTED_FOCUS
;
733 case SELECTED_NO_FOCUS
:
734 colorString
= Resources
.COLOR_CONTROL_SELECTED
;
737 colorString
= Resources
.COLOR_COMPOSITE_BACKGROUND
;
740 backgroundColor
= EditorUtil
.getColor(colorString
);
742 setBackground(backgroundColor
);
748 * setDelayedSelection
751 protected void setDelayedSelection() {
752 // TODO this might be done better
753 // this is the quickest solution i could come up with and it improves
755 // please reimplement if you know better.
759 Display display
= Display
.getCurrent();
760 Runnable runnable
= new Runnable() {
763 getEditor().getManagedForm().setInput(selection
);
766 display
.timerExec(1000, runnable
);
776 * a {@link org.eclipse.swt.graphics.Color} object.
778 public void setBackground(Color color
) {
779 control
.setBackground(color
);
781 for (Control child
: control
.getChildren()) {
782 child
.setBackground(color
);
785 getNameViewer().setBackground(color
);
792 * org.eclipse.swt.widgets.Control#setFont(org.eclipse.swt.graphics.Font)
800 * a {@link org.eclipse.swt.graphics.Font} object.
802 public void setFont(Font font
) {
803 getNameViewer().getTextWidget().setFont(font
);
808 * Getter for the field <code>nameViewer</code>.
811 * @return a {@link eu.etaxonomy.taxeditor.editor.name.container.NameViewer}
814 public NameViewer
getNameViewer() {
815 if (nameViewer
== null) {
816 throw new RuntimeException(
817 "The Name Viewer is corrupt for Name Container: "
818 + getTaxonBase().getName().getTitleCache());
824 * If <code>textViewer</code> has already been set, it will show a
825 * <code>prompt</code> along the lines of
826 * "Click here to start entering data" when empty.
829 * a {@link java.lang.String} object.
831 public void createEmptyViewerPrompt(final String prompt
) {
833 Assert
.isNotNull(getNameViewer());
835 final StyledText textControl
= getNameViewer().getTextWidget();
836 final IDocument document
= getNameViewer().getDocument();
838 setFocusListener(new FocusListener() {
840 public void focusGained(FocusEvent e
) {
841 if (document
.get().equals(prompt
)) {
842 textControl
.setFont(getViewerFont());
847 public void focusLost(FocusEvent e
) {
848 if (document
.getLength() == 0) {
854 textControl
.addFocusListener(getFocusListener());
856 if (document
.getLength() == 0) {
857 textControl
.setFont(EditorUtil
858 .getFont(Resources
.FONT_DEFAULT_PROMPT
));
859 document
.set(prompt
);
868 * @return a {@link org.eclipse.swt.graphics.Font} object.
870 abstract protected Font
getViewerFont();
877 protected void initEmptyText() {
878 Font defaultFont
= EditorUtil
.getFont(Resources
.FONT_DEFAULT_PROMPT
);
879 getNameViewer().getTextWidget().setFont(defaultFont
);
881 getNameViewer().getDocument().set(getEmptyTextPrompt());
887 * Setter for the field <code>focusListener</code>.
890 * @param focusListener
891 * a {@link org.eclipse.swt.events.FocusListener} object.
893 protected void setFocusListener(FocusListener focusListener
) {
894 this.focusListener
= focusListener
;
897 private FocusListener
getFocusListener() {
898 return focusListener
;
909 public void setDirty(boolean isDirty
) {
911 getEditor().getManagedForm().dirtyStateChanged();
913 this.isDirty
= isDirty
;
923 public boolean isDirty() {
933 * a {@link org.eclipse.swt.widgets.Menu} object.
935 public void setMenu(Menu menu
) {
936 control
.setMenu(menu
);
938 getNameViewer().setMenu(menu
);
941 private Control
[] draggableControls
;
945 * setDraggableControl
949 * an array of {@link org.eclipse.swt.widgets.Control} objects.
951 protected void setDraggableControl(Control
[] controls
) {
952 draggableControls
= controls
;
963 public void setIsDraggable(boolean draggable
) {
967 if (draggableControls
== null) {
968 throw new NullPointerException(
969 "Draggable controls must be set to add draggability");
972 Transfer
[] types
= new Transfer
[] { CdmDataTransfer
.getInstance() };
973 int operations
= DND
.DROP_MOVE
;
975 for (Control draggableControl
: draggableControls
) {
976 DragSource dragSource
= new DragSource(draggableControl
,
978 dragSource
.setTransfer(types
);
980 dragSource
.addDragListener(new NameEditorDragListener(this));
981 dragSource
.setDragSourceEffect(new NameEditorDragSourceEffect(
987 private String nonEditableText
;
989 ControlListener nonEditableResizeListener
= new ControlAdapter() {
994 public void controlResized(ControlEvent e
) {
995 if (nonEditableInfoLabel
.getBounds().width
== width
) {
998 width
= nonEditableInfoLabel
.getBounds().width
;
999 if (nonEditableInfoLabel
.getBounds().width
> 0) {
1000 nonEditableInfoLabel
.setText(Dialog
.shortenText(
1001 nonEditableText
.toUpperCase(), nonEditableInfoLabel
));
1006 private String nonEditableHoverText
;
1008 private LabelEllipsisListener nonEditableLabelEllipsisListener
;
1012 private boolean enabled
;
1015 * nonEditableInfo is a label displayed underneath a GroupedComposite's
1016 * input field. For instance, NameComposites display things like name
1017 * relations, sec. references, etc. here.
1020 * the text to display in the label
1022 * whether the string should be appended to text that is already
1023 * shown in the label
1025 public void setNonEditableInfo(String info
, boolean append
) {
1026 // TODO non editable info should only be drawn once, when everything
1028 info
= info
.toUpperCase();
1031 nonEditableText
+= ", " + info
;
1032 nonEditableHoverText
+= "\n" + info
;
1034 nonEditableText
= info
;
1035 nonEditableHoverText
= info
;
1038 if (nonEditableInfoLabel
== null) {
1039 nonEditableInfoLabel
= getEditor().getToolkit().createLabel(
1041 TableWrapData layoutData
= new TableWrapData(
1042 TableWrapData
.FILL_GRAB
, TableWrapData
.TOP
);
1043 // Set indent to viewer ruler's width
1044 if (getNameViewer().getRulerControl() != null) {
1045 // TODO right justify
1046 layoutData
.indent
= NameViewer
.RULER_WIDTH
;
1048 nonEditableInfoLabel
.setLayoutData(layoutData
);
1050 nonEditableLabelEllipsisListener
= new LabelEllipsisListener(
1051 nonEditableInfoLabel
) {
1053 public String
getLabelText() {
1054 return nonEditableText
.toUpperCase();
1057 nonEditableInfoLabel
1058 .addControlListener(nonEditableLabelEllipsisListener
);
1060 nonEditableInfoHover
= new DefaultToolTip(nonEditableInfoLabel
);
1061 nonEditableInfoHover
.setRespectDisplayBounds(true);
1064 nonEditableInfoHover
.setText(nonEditableHoverText
);
1065 nonEditableInfoLabel
.setText(nonEditableText
);
1067 calculateAnnotations();
1072 * Getter for the field <code>data</code>.
1075 * @return a T object.
1077 public T
getData() {
1083 * Setter for the field <code>data</code>.
1089 public void setData(T data
) {
1090 this.data
= (T
) HibernateProxyHelper
.deproxy(data
);
1094 * If the user hitting carriage return should cause something to happen -
1095 * i.e. the creation of a new composite - call this method and override the
1096 * method handleSplitText().
1098 protected void createLineBreakListener() {
1099 lineBreakListener
= new LineBreakListener() {
1101 public void handleSplitText(String text
) {
1102 AbstractGroupedContainer
.this.handleSplitText(text
);
1106 getNameViewer().getTextWidget().addVerifyListener(lineBreakListener
);
1109 abstract class LabelEllipsisListener
extends ControlAdapter
{
1111 private final Label label
;
1114 LabelEllipsisListener(Label label
) {
1118 abstract public String
getLabelText();
1121 public void controlResized(ControlEvent e
) {
1122 if (label
.getBounds().width
== width
) {
1125 width
= label
.getBounds().width
;
1126 if (label
.getBounds().width
> 0) {
1127 label
.setText(TextHelper
.shortenText(getLabelText(), label
));
1137 public void storeCursor() {
1138 this.cursorPosition
= getNameViewer().getCursorPosition();
1142 * Puts the cursor to the position it was last seen on or to the end of line
1143 * if no former position is known.
1145 public void placeCursor() {
1146 if (cursorPosition
== 0) {
1147 getNameViewer().setCursorToEOL();
1149 getNameViewer().setCursorPosition(cursorPosition
);
1155 * Setter for the field <code>group</code>.
1160 * {@link eu.etaxonomy.taxeditor.editor.name.container.AbstractGroup}
1163 public void setGroup(AbstractGroup group
) {
1172 public void restoreColor() {
1173 setBackground(backgroundColor
);
1180 * org.eclipse.ui.forms.IFormPart#initialize(org.eclipse.ui.forms.IManagedForm
1184 public void initialize(IManagedForm form
) {
1185 // TODO Auto-generated method stub
1192 * @see org.eclipse.ui.forms.IFormPart#dispose()
1195 public void dispose() {
1196 if (getControl() != null) {
1198 getControl().dispose();
1205 * @see org.eclipse.ui.forms.IFormPart#commit(boolean)
1208 public void commit(boolean onSave
) {
1217 * @see org.eclipse.ui.forms.IFormPart#setFormInput(java.lang.Object)
1220 public boolean setFormInput(Object input
) {
1221 // TODO Auto-generated method stub
1228 * @see org.eclipse.ui.forms.IFormPart#setFocus()
1231 public void setFocus() {
1232 getNameViewer().getControl().setFocus();
1238 * @see org.eclipse.ui.forms.IFormPart#isStale()
1241 public boolean isStale() {
1242 // TODO Auto-generated method stub
1246 public void setEnabled(boolean enabled
) {
1247 this.enabled
= enabled
;
1248 Color color
= enabled ? control
.getForeground() : EditorUtil
.getColor(Resources
.COLOR_DISABLED_EDITOR
);
1250 getNameViewer().getTextWidget().setEditable(enabled
);
1251 getNameViewer().getTextWidget().setForeground(color
);
1254 public boolean getEnabled(){