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.
9 package eu
.etaxonomy
.taxeditor
.editor
.name
.e4
.container
;
11 import java
.util
.Iterator
;
12 import java
.util
.List
;
15 import org
.apache
.commons
.lang3
.StringUtils
;
16 import org
.eclipse
.core
.runtime
.Assert
;
17 import org
.eclipse
.e4
.ui
.di
.UISynchronize
;
18 import org
.eclipse
.jface
.dialogs
.Dialog
;
19 import org
.eclipse
.jface
.text
.IDocument
;
20 import org
.eclipse
.jface
.text
.Position
;
21 import org
.eclipse
.jface
.window
.DefaultToolTip
;
22 import org
.eclipse
.swt
.custom
.StyledText
;
23 import org
.eclipse
.swt
.dnd
.DND
;
24 import org
.eclipse
.swt
.dnd
.DragSource
;
25 import org
.eclipse
.swt
.dnd
.Transfer
;
26 import org
.eclipse
.swt
.events
.ControlAdapter
;
27 import org
.eclipse
.swt
.events
.ControlEvent
;
28 import org
.eclipse
.swt
.events
.ControlListener
;
29 import org
.eclipse
.swt
.events
.FocusAdapter
;
30 import org
.eclipse
.swt
.events
.FocusEvent
;
31 import org
.eclipse
.swt
.events
.FocusListener
;
32 import org
.eclipse
.swt
.events
.ModifyEvent
;
33 import org
.eclipse
.swt
.events
.ModifyListener
;
34 import org
.eclipse
.swt
.events
.MouseAdapter
;
35 import org
.eclipse
.swt
.events
.MouseEvent
;
36 import org
.eclipse
.swt
.graphics
.Color
;
37 import org
.eclipse
.swt
.graphics
.Font
;
38 import org
.eclipse
.swt
.graphics
.Image
;
39 import org
.eclipse
.swt
.widgets
.Composite
;
40 import org
.eclipse
.swt
.widgets
.Control
;
41 import org
.eclipse
.swt
.widgets
.Display
;
42 import org
.eclipse
.swt
.widgets
.Label
;
43 import org
.eclipse
.ui
.forms
.IFormPart
;
44 import org
.eclipse
.ui
.forms
.IManagedForm
;
45 import org
.eclipse
.ui
.forms
.widgets
.TableWrapData
;
46 import org
.eclipse
.ui
.forms
.widgets
.TableWrapLayout
;
48 import eu
.etaxonomy
.cdm
.hibernate
.HibernateProxyHelper
;
49 import eu
.etaxonomy
.cdm
.model
.common
.CdmBase
;
50 import eu
.etaxonomy
.cdm
.model
.name
.TaxonName
;
51 import eu
.etaxonomy
.cdm
.model
.taxon
.TaxonBase
;
52 import eu
.etaxonomy
.cdm
.strategy
.parser
.ParserProblem
;
53 import eu
.etaxonomy
.taxeditor
.editor
.CdmDataTransfer
;
54 import eu
.etaxonomy
.taxeditor
.editor
.l10n
.Messages
;
55 import eu
.etaxonomy
.taxeditor
.editor
.name
.container
.EditorAnnotation
;
56 import eu
.etaxonomy
.taxeditor
.editor
.name
.container
.EditorAnnotation
.EditorAnnotationType
;
57 import eu
.etaxonomy
.taxeditor
.editor
.name
.container
.IContainerConstants
;
58 import eu
.etaxonomy
.taxeditor
.editor
.name
.container
.LineBreakListener
;
59 import eu
.etaxonomy
.taxeditor
.editor
.name
.container
.LineWrapSupport
;
60 import eu
.etaxonomy
.taxeditor
.editor
.name
.e4
.TaxonEditor
;
61 import eu
.etaxonomy
.taxeditor
.editor
.name
.e4
.dnd
.NameEditorDragListenerE4
;
62 import eu
.etaxonomy
.taxeditor
.editor
.name
.e4
.dnd
.NameEditorDragSourceEffect
;
63 import eu
.etaxonomy
.taxeditor
.editor
.name
.operation
.CreateSynonymInNewGroupOperation
;
64 import eu
.etaxonomy
.taxeditor
.event
.EventUtility
;
65 import eu
.etaxonomy
.taxeditor
.event
.WorkbenchEventConstants
;
66 import eu
.etaxonomy
.taxeditor
.model
.AbstractUtility
;
67 import eu
.etaxonomy
.taxeditor
.model
.IElementHasDetails
;
68 import eu
.etaxonomy
.taxeditor
.model
.NameHelper
;
69 import eu
.etaxonomy
.taxeditor
.model
.TextHelper
;
70 import eu
.etaxonomy
.taxeditor
.parser
.ParseHandler
;
71 import eu
.etaxonomy
.taxeditor
.preference
.Resources
;
74 * Formats <code>GroupedComposite</code> with cosmetic and layout properties
75 * specific to the Editor. This should be used to maintain a consistent look and
76 * feel for all Editor freetext area components, such as
77 * DescriptionElementComposite.
79 * Requires an <code>IManagedForm</code>, whose <code>input</code> is set to the
80 * contents of {@link #getData()} when the <code>GroupedComposite</code> gets
81 * focus, i.e. to populate the property sheet with the data.
84 * The <code>IManagedForm</code> is also required to have a <code>Taxon</code>
85 * in its own <code>getData()</code>.
88 * The <code>IManagedForm</code> can also be used for drawing borders by calling
89 * the method <code>createBorderSupport()</code>.
96 abstract public class AbstractGroupedContainer
<T
extends TaxonBase
> implements
97 IFormPart
, IContainerConstants
, IElementHasDetails
{
99 protected ParseHandler parseHandler
;
101 private FocusListener nameCompositeFocusListener
;
102 private ModifyListener nameCompositeModifyListener
;
104 protected NameViewer nameViewer
;
106 private AbstractGroup group
;
108 private Label nonEditableInfoLabel
;
109 private DefaultToolTip nonEditableInfoHover
;
111 private static AbstractGroupedContainer
<?
> selection
;
113 private FocusListener focusListener
;
114 private LineBreakListener lineBreakListener
;
116 private int cursorPosition
;
118 private long lastEventTime
;
120 protected Composite control
;
122 private Color backgroundColor
;
123 private boolean isDirty
;
125 public AbstractGroupedContainer(AbstractGroup group
, T taxonBase
) {
128 parseHandler
= ParseHandler
.NewInstance(taxonBase
.getName());
131 public void createContent() {
135 createLineWrapSupport();
136 createLineBreakListener();
140 setDraggableControl(new Control
[] { getControl(),
141 getNameViewer().getRulerControl() });
143 createEmptyViewerPrompt(EMPTY_NAME_PROMPT
);
145 initializeComposite();
152 protected void createListener() {
153 nameCompositeModifyListener
= (ModifyEvent e
)->{
154 // mark the composite dirty
156 lastEventTime
= System
.currentTimeMillis();
158 String text
= nameViewer
.getTextWidget().getText();
160 TaxonName name
= (TaxonName
)parseHandler
.parse(text
);
161 getTaxonBase().setName(name
);
162 getTaxonBase().setTitleCache((getTaxonBase().generateTitle()));
165 // show errors resulting from parsing
166 calculateAnnotations();
167 // store the position of the cursor
169 // notify selection listener
170 setDelayedSelection();
171 EventUtility
.postAsyncEvent(WorkbenchEventConstants
.NEED_REFRESH_DETAILS
, false);
175 nameCompositeFocusListener
= new FocusAdapter() {
178 public void focusLost(FocusEvent e
) {
188 protected void addListener() {
189 getNameViewer().getTextWidget().addModifyListener(
190 nameCompositeModifyListener
);
191 getNameViewer().getTextWidget().addFocusListener(
192 nameCompositeFocusListener
);
195 protected void removeListener() {
196 getNameViewer().getTextWidget().removeModifyListener(
197 nameCompositeModifyListener
);
198 getNameViewer().getTextWidget().removeFocusListener(
199 nameCompositeFocusListener
);
203 * Initialize the composite specific code
205 protected abstract void initializeComposite();
207 protected String
getEmptyTextPrompt() {
208 return EMPTY_NAME_PROMPT
;
211 protected void initTextViewer() {
217 String text
= NameHelper
.getDisplayNameWithRef(getData());
219 if (text
.length() == 0) {
222 getNameViewer().setText(text
);
225 calculateAnnotations();
228 synchronized protected void calculateAnnotations() {
229 getNameViewer().clearAnnotations();
233 public void showAnnotations() {
235 if (getName() != null && getName().hasProblem()) {
236 showParsingProblems();
239 if (!isNameParsable()) {
242 new EditorAnnotation(EditorAnnotationType
.WARNING
,
244 Messages
.AbstractGroupedContainer_EDIT_IN_DETAILS_VIEW
));
247 if (isNameUsedMultipleTimes()) {
248 getNameViewer().addAnnotation(
249 new EditorAnnotation(EditorAnnotationType
.WARNING
, 0,
250 Messages
.AbstractGroupedContainer_MULTIPLE_USE
));
255 private void showParsingProblems() {
256 TaxonName name
= getName();
261 List
<ParserProblem
> parsingProblems
= name
.getParsingProblems();
263 for (ParserProblem problem
: parsingProblems
) {
264 getNameViewer().addAnnotation(new EditorAnnotation(problem
),
265 getParsingProblemPosition());
269 private Position
getParsingProblemPosition() {
270 String text
= getNameViewer().getTextWidget().getText();
272 if (getName() != null && getName().hasProblem() && text
.length() > 0) {
273 int start
= getName().getProblemStarts();
274 int length
= getName().getProblemEnds() - start
;
276 if (start
== -1 || getName().getProblemEnds() == -1) {
280 // Don't let squigglies try to draw beyond the end of the text
281 if (text
.length() < start
+ length
) {
282 length
= text
.length() - start
;
287 return new Position(start
, length
);
292 protected void handleSplitText(String text
) {
293 // Create a synonym in a new homotypic group using text as name
294 TaxonName synonymName
= TaxonName
.castAndDeproxy(
295 ParseHandler
.parseReferencedName(text
, null));
297 AbstractUtility
.executeOperation(new CreateSynonymInNewGroupOperation(
298 Messages
.AbstractGroupedContainer_NEW_HETERO_SYNONYM
, getEditor().getUndoContext(),
299 getEditor().getTaxon(), synonymName
, getEditor()), group
.getContext().get(UISynchronize
.class));
303 * Refreshes the display with latest data from the model.
305 * Note: Will not parse the text and not calculate errors!
308 public void refresh() {
309 // showNameRelations();
311 String text
= NameHelper
.getDisplayNameWithRef(getTaxonBase());
313 if (getNameViewer().getTextWidget() == null) {
314 // we might get here via dnd. Look slike it can be ignored
318 if (text
.length() == 0) {
320 } else if (!getNameViewer().getTextWidget().getText().equals(text
)) {
322 getNameViewer().getTextWidget().setText(text
);
326 updateNonEditableInfo();
331 setDelayedSelection();
335 protected abstract void updateIcon();
337 protected abstract void updateIndent();
339 protected abstract void updateNonEditableInfo();
341 protected void enableFreeText() {
342 setEnabled(isFreetextEditingAllowed());
346 * Checks whether the freetext should be editable based on specific empty
351 private boolean isFreetextEditingAllowed() {
352 boolean enableFreetext
= true;
354 enableFreetext
|= isNameUsedMultipleTimes();
355 enableFreetext
&= isNameParsable();
357 return enableFreetext
;
361 * Checks whether there are more than one, non-orphaned taxon bases
362 * attached to the taxon name
366 private boolean isNameUsedMultipleTimes() {
368 TaxonName name
= getName();
370 Set
<TaxonBase
> taxonBases
= name
.getTaxonBases();
371 Iterator
<TaxonBase
> tbItr
= taxonBases
.iterator();
372 int nonOrphanedTaxonBaseCount
= taxonBases
.size();
374 while(tbItr
.hasNext()) {
375 TaxonBase
<?
> tb
= tbItr
.next();
376 if(tb
.isOrphaned()) {
377 nonOrphanedTaxonBaseCount
--;
380 if(nonOrphanedTaxonBaseCount
> 1) {
387 private boolean isNameParsable() {
388 TaxonName name
= getName();
393 boolean isParsable
= true;
394 isParsable
&= StringUtils
.isBlank(name
.getAppendedPhrase()); // taxonFieldsEmpty();
395 if (name
.isProtectedAuthorshipCache()){
396 isParsable
&= nameAuthorsSet(name
);
398 if (name
.isProtectedNameCache()){
399 isParsable
&= nameEpithetsNotSet(name
) && nameAuthorsSet(name
);
405 private boolean nameAuthorsSet(TaxonName name
) {
406 boolean result
= true;
407 result
&= name
.getBasionymAuthorship() == null && name
.getCombinationAuthorship() == null && name
.getExBasionymAuthorship() == null && name
.getExCombinationAuthorship() == null;
411 private boolean nameEpithetsNotSet(TaxonName name
) {
412 boolean result
= true;
413 result
&= name
.getGenusOrUninomial() == null && name
.getInfraGenericEpithet() == null && name
.getSpecificEpithet() == null && name
.getInfraSpecificEpithet() == null;
419 * Parse the text and calculate errors
421 public void parseAndCalculateAnnotations() {
423 String unparsedNameString
= getNameViewer().getTextWidget().getText();
424 parseHandler
.parse(unparsedNameString
);
426 calculateAnnotations();
429 public T
getTaxonBase() {
433 public TaxonName
getName() {
434 return CdmBase
.deproxy(getTaxonBase().getName());
437 public void persistName() {
439 getNameViewer().getTextWidget().setEnabled(false);
440 final String unparsedNameString
= getNameViewer().getTextWidget()
442 final TaxonName name
= (TaxonName
)parseHandler
443 .parseAndResolveDuplicates(unparsedNameString
);
444 getTaxonBase().setName(name
);
445 getTaxonBase().setTitleCache((getTaxonBase().generateTitle()));
447 getNameViewer().getTextWidget().setEnabled(true);
451 public AbstractGroup
getGroup() {
453 throw new IllegalStateException("Group shall not be null."); //$NON-NLS-1$
458 public void remove() {
459 getGroup().remove(this);
462 protected void createControl() {
463 control
= getEditor().getToolkit().createComposite(
464 getGroup().getControl());
466 control
.setLayoutData(new TableWrapData(TableWrapData
.FILL_GRAB
));
467 TableWrapLayout layout
= new TableWrapLayout();
468 layout
.leftMargin
= 0;
469 layout
.rightMargin
= 0;
470 layout
.topMargin
= 5;
471 layout
.bottomMargin
= 5;
473 layout
.verticalSpacing
= 0;
474 layout
.horizontalSpacing
= 0;
476 control
.setLayout(layout
);
480 protected TaxonEditor
getEditor() {
481 return getGroup().getEditor();
484 public Composite
getControl() {
488 @SuppressWarnings("unused")
489 protected void createLineWrapSupport() {
490 new LineWrapSupport(getNameViewer(), getEditor().getManagedForm());
493 protected void createTextViewer() {
494 nameViewer
= new NameViewer(control
);
496 focusListener
= new FocusAdapter() {
498 public void focusGained(FocusEvent e
) {
500 .getGroupedContainers().isEmpty()){
504 for (AbstractGroupedContainer
<?
> container
: getEditor()
505 .getGroupedContainers()) {
506 container
.colorSelected(NOT_SELECTED
);
508 getEditor().getManagedForm().setInput(
509 AbstractGroupedContainer
.this);
511 colorSelected(SELECTED_FOCUS
);
514 nameViewer
.getTextWidget().addFocusListener(focusListener
);
516 MouseAdapter mouseListener
= new MouseAdapter() {
518 public void mouseDown(MouseEvent e
) {
522 control
.addMouseListener(mouseListener
);
523 nameViewer
.getRulerControl().addMouseListener(mouseListener
);
524 nameViewer
.getTextWidget().addMouseListener(mouseListener
);
527 public void setIcon(Image icon
) {
528 getNameViewer().setIcon(icon
);
531 public void setIndent(int indent
) {
532 if (control
.getLayout() instanceof TableWrapLayout
) {
533 TableWrapLayout layout
= ((TableWrapLayout
) control
.getLayout());
534 layout
.leftMargin
= indent
;
535 layout
.rightMargin
= ACCEPTED_INDENT
;
536 control
.setLayout(layout
);
539 throw new RuntimeException(
540 "Couldn't indent - composite's layout must be TableWrapLayout."); //$NON-NLS-1$
544 public void setSelected() {
545 if (getNameViewer() != null && getNameViewer().getTextWidget() != null) {
546 getNameViewer().getTextWidget().setFocus();
550 public boolean isSelected() {
551 return getEditor().getSelectedContainer() == this;
554 public void colorSelected(int mode
) {
555 if (control
!=null && !control
.isDisposed()) {
556 String colorString
= null;
560 colorString
= Resources
.COLOR_CONTROL_SELECTED_FOCUS
;
562 case SELECTED_NO_FOCUS
:
563 colorString
= Resources
.COLOR_CONTROL_SELECTED
;
566 colorString
= Resources
.COLOR_COMPOSITE_BACKGROUND
;
569 backgroundColor
= AbstractUtility
.getColor(colorString
);
571 setBackground(backgroundColor
);
575 private Delay delay
= new Delay(Display
.getCurrent());
577 private class Delay
extends Thread
{
579 private volatile boolean stop
= false;
580 private Display display
;
582 private Delay(Display display
) {
583 this.display
= display
;
594 display
.syncExec(() -> {
595 getEditor().getManagedForm().setInput(selection
);
599 } catch (InterruptedException ex
) {
604 public void requestStop() {
609 protected void setDelayedSelection() {
612 Display display
= Display
.getCurrent();
615 delay
= new Delay(display
);
619 public void setBackground(Color color
) {
620 control
.setBackground(color
);
622 for (Control child
: control
.getChildren()) {
623 child
.setBackground(color
);
626 getNameViewer().setBackground(color
);
629 public void setFont(Font font
) {
630 getNameViewer().getTextWidget().setFont(font
);
633 public NameViewer
getNameViewer() {
634 if (nameViewer
== null) {
635 throw new RuntimeException(
636 "The Name Viewer is corrupt for Name Container: " //$NON-NLS-1$
637 + getTaxonBase().getName().getTitleCache());
642 public void createEmptyViewerPrompt(final String prompt
) {
644 Assert
.isNotNull(getNameViewer());
646 final StyledText textControl
= getNameViewer().getTextWidget();
647 final IDocument document
= getNameViewer().getDocument();
649 setFocusListener(new FocusListener() {
652 public void focusGained(FocusEvent e
) {
653 if (document
.get().equals(prompt
)) {
654 textControl
.setFont(getViewerFont());
655 document
.set(""); //$NON-NLS-1$
660 public void focusLost(FocusEvent e
) {
661 if (document
.getLength() == 0) {
667 textControl
.addFocusListener(getFocusListener());
669 if (document
.getLength() == 0) {
670 textControl
.setFont(AbstractUtility
671 .getFont(Resources
.FONT_DEFAULT_PROMPT
));
672 document
.set(prompt
);
676 abstract protected Font
getViewerFont();
678 protected void initEmptyText() {
679 Font defaultFont
= AbstractUtility
.getFont(Resources
.FONT_DEFAULT_PROMPT
);
680 getNameViewer().getTextWidget().setFont(defaultFont
);
682 getNameViewer().getDocument().set(getEmptyTextPrompt());
685 protected void setFocusListener(FocusListener focusListener
) {
686 this.focusListener
= focusListener
;
689 private FocusListener
getFocusListener() {
690 return focusListener
;
693 public void setDirty(boolean isDirty
) {
695 getEditor().getManagedForm().dirtyStateChanged();
697 this.isDirty
= isDirty
;
701 public boolean isDirty() {
705 public void setMenu() {
706 getEditor().getMenuService().registerContextMenu(getNameViewer().getTextWidget(), "eu.etaxonomy.taxeditor.editor.popupmenu.nameeditor");
709 private Control
[] draggableControls
;
711 protected void setDraggableControl(Control
[] controls
) {
712 draggableControls
= controls
;
715 public void setIsDraggable(boolean draggable
) {
719 if (draggableControls
== null) {
720 throw new NullPointerException(
721 "Draggable controls must be set to add draggability"); //$NON-NLS-1$
724 Transfer
[] types
= new Transfer
[] { CdmDataTransfer
.getInstance() };
725 int operations
= DND
.DROP_MOVE
;
727 for (Control draggableControl
: draggableControls
) {
728 DragSource dragSource
= new DragSource(draggableControl
,
730 dragSource
.setTransfer(types
);
732 dragSource
.addDragListener(new NameEditorDragListenerE4(this));
733 dragSource
.setDragSourceEffect(new NameEditorDragSourceEffect(
739 private String nonEditableText
;
741 ControlListener nonEditableResizeListener
= new ControlAdapter() {
746 public void controlResized(ControlEvent e
) {
747 if (nonEditableInfoLabel
.getBounds().width
== width
) {
750 width
= nonEditableInfoLabel
.getBounds().width
;
751 if (nonEditableInfoLabel
.getBounds().width
> 0) {
752 nonEditableInfoLabel
.setText(Dialog
.shortenText(
753 nonEditableText
.toUpperCase(), nonEditableInfoLabel
));
758 private String nonEditableHoverText
;
760 private LabelEllipsisListener nonEditableLabelEllipsisListener
;
765 * nonEditableInfo is a label displayed underneath a GroupedComposite's
766 * input field. For instance, NameComposites display things like name
767 * relations, sec. references, etc. here.
770 * the text to display in the label
772 * whether the string should be appended to text that is already
775 public void setNonEditableInfo(String info
, boolean append
) {
776 // TODO non editable info should only be drawn once, when everything
778 info
= info
.toUpperCase();
781 nonEditableText
+= ", " + info
; //$NON-NLS-1$
782 nonEditableHoverText
+= "\n" + info
; //$NON-NLS-1$
784 nonEditableText
= info
;
785 nonEditableHoverText
= info
;
788 if (nonEditableInfoLabel
== null) {
789 nonEditableInfoLabel
= getEditor().getToolkit().createLabel(
790 control
, ""); //$NON-NLS-1$
791 TableWrapData layoutData
= new TableWrapData(
792 TableWrapData
.FILL_GRAB
, TableWrapData
.TOP
);
793 // Set indent to viewer ruler's width
794 if (getNameViewer().getRulerControl() != null) {
795 // TODO right justify
796 layoutData
.indent
= NameViewer
.RULER_WIDTH
;
798 nonEditableInfoLabel
.setLayoutData(layoutData
);
800 nonEditableLabelEllipsisListener
= new LabelEllipsisListener(
801 nonEditableInfoLabel
) {
803 public String
getLabelText() {
804 return nonEditableText
.toUpperCase();
808 .addControlListener(nonEditableLabelEllipsisListener
);
810 nonEditableInfoHover
= new DefaultToolTip(nonEditableInfoLabel
);
811 nonEditableInfoHover
.setRespectDisplayBounds(true);
814 nonEditableInfoHover
.setText(nonEditableHoverText
);
815 nonEditableInfoLabel
.setText(nonEditableText
);
817 calculateAnnotations();
825 public void setData(T data
) {
826 this.data
= HibernateProxyHelper
.deproxy(data
);
830 * If the user hitting carriage return should cause something to happen -
831 * i.e. the creation of a new composite - call this method and override the
832 * method handleSplitText().
834 protected void createLineBreakListener() {
835 lineBreakListener
= new LineBreakListener() {
837 public void handleSplitText(String text
) {
838 AbstractGroupedContainer
.this.handleSplitText(text
);
843 getNameViewer().getTextWidget().addVerifyListener(lineBreakListener
);
847 abstract class LabelEllipsisListener
extends ControlAdapter
{
849 private final Label label
;
852 LabelEllipsisListener(Label label
) {
856 abstract public String
getLabelText();
859 public void controlResized(ControlEvent e
) {
860 if (label
.getBounds().width
== width
) {
863 width
= label
.getBounds().width
;
864 if (label
.getBounds().width
> 0) {
865 label
.setText(TextHelper
.shortenText(getLabelText(), label
));
870 public void storeCursor() {
871 this.cursorPosition
= getNameViewer().getCursorPosition();
875 * Puts the cursor to the position it was last seen on or to the end of line
876 * if no former position is known.
878 public void placeCursor() {
879 if (cursorPosition
== 0) {
880 getNameViewer().setCursorToEOL();
882 getNameViewer().setCursorPosition(cursorPosition
);
886 public void restoreColor() {
887 setBackground(backgroundColor
);
891 public void initialize(IManagedForm form
) {
892 // TODO Auto-generated method stub
896 public void dispose() {
897 if (getControl() != null) {
898 getControl().dispose();
903 public void commit(boolean onSave
) {
910 public boolean setFormInput(Object input
) {
915 public void setFocus() {
916 getNameViewer().getControl().setFocus();
920 public boolean isStale() {
924 public void setDisabled(boolean disabled
) {
925 setEnabled(!disabled
);
928 public void setEnabled(boolean enabled
) {
929 Color color
= enabled ? control
.getForeground() : AbstractUtility
.getColor(Resources
.COLOR_DISABLED_EDITOR
);
931 getNameViewer().getTextWidget().setEditable(enabled
);
932 getNameViewer().getTextWidget().setForeground(color
);