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
;
14 import org
.eclipse
.core
.runtime
.Assert
;
15 import org
.eclipse
.jface
.dialogs
.Dialog
;
16 import org
.eclipse
.jface
.text
.IDocument
;
17 import org
.eclipse
.jface
.window
.DefaultToolTip
;
18 import org
.eclipse
.swt
.custom
.StyledText
;
19 import org
.eclipse
.swt
.dnd
.DND
;
20 import org
.eclipse
.swt
.dnd
.DragSource
;
21 import org
.eclipse
.swt
.dnd
.Transfer
;
22 import org
.eclipse
.swt
.events
.ControlAdapter
;
23 import org
.eclipse
.swt
.events
.ControlEvent
;
24 import org
.eclipse
.swt
.events
.ControlListener
;
25 import org
.eclipse
.swt
.events
.FocusAdapter
;
26 import org
.eclipse
.swt
.events
.FocusEvent
;
27 import org
.eclipse
.swt
.events
.FocusListener
;
28 import org
.eclipse
.swt
.events
.ModifyEvent
;
29 import org
.eclipse
.swt
.events
.ModifyListener
;
30 import org
.eclipse
.swt
.events
.MouseAdapter
;
31 import org
.eclipse
.swt
.events
.MouseEvent
;
32 import org
.eclipse
.swt
.graphics
.Color
;
33 import org
.eclipse
.swt
.graphics
.Font
;
34 import org
.eclipse
.swt
.graphics
.Image
;
35 import org
.eclipse
.swt
.widgets
.Composite
;
36 import org
.eclipse
.swt
.widgets
.Control
;
37 import org
.eclipse
.swt
.widgets
.Display
;
38 import org
.eclipse
.swt
.widgets
.Label
;
39 import org
.eclipse
.swt
.widgets
.Menu
;
40 import org
.eclipse
.ui
.forms
.IFormPart
;
41 import org
.eclipse
.ui
.forms
.IManagedForm
;
42 import org
.eclipse
.ui
.forms
.widgets
.TableWrapData
;
43 import org
.eclipse
.ui
.forms
.widgets
.TableWrapLayout
;
45 import eu
.etaxonomy
.cdm
.common
.CdmUtils
;
46 import eu
.etaxonomy
.cdm
.hibernate
.HibernateProxyHelper
;
47 import eu
.etaxonomy
.cdm
.model
.name
.NameRelationship
;
48 import eu
.etaxonomy
.cdm
.model
.name
.NonViralName
;
49 import eu
.etaxonomy
.cdm
.model
.name
.TaxonNameBase
;
50 import eu
.etaxonomy
.cdm
.model
.taxon
.TaxonBase
;
51 import eu
.etaxonomy
.taxeditor
.editor
.CdmDataTransfer
;
52 import eu
.etaxonomy
.taxeditor
.editor
.EditorUtil
;
53 import eu
.etaxonomy
.taxeditor
.editor
.name
.TaxonNameEditor
;
54 import eu
.etaxonomy
.taxeditor
.editor
.name
.dnd
.NameEditorDragListener
;
55 import eu
.etaxonomy
.taxeditor
.editor
.name
.dnd
.NameEditorDragSourceEffect
;
56 import eu
.etaxonomy
.taxeditor
.editor
.name
.operation
.CreateSynonymInNewGroupOperation
;
57 import eu
.etaxonomy
.taxeditor
.labels
.ILabelImageStrategy
;
58 import eu
.etaxonomy
.taxeditor
.labels
.LabelImageProvider
;
59 import eu
.etaxonomy
.taxeditor
.model
.IElementHasDetails
;
60 import eu
.etaxonomy
.taxeditor
.model
.NameHelper
;
61 import eu
.etaxonomy
.taxeditor
.model
.TextHelper
;
62 import eu
.etaxonomy
.taxeditor
.parser
.ParseHandler
;
63 import eu
.etaxonomy
.taxeditor
.preference
.Resources
;
66 * Formats <code>GroupedComposite</code> with cosmetic and layout properties specific to the
67 * Editor. This should be used to maintain a consistent look and feel for all Editor
68 * freetext area components, such as DescriptionElementComposite.
70 * Requires an <code>IManagedForm</code>, whose <code>input</code> is set to the contents
71 * of {@link #getData()} when the <code>GroupedComposite</code> gets focus, i.e. to
72 * populate the property sheet with the data.
75 * The <code>IManagedForm</code> is also required to have a <code>Taxon</code> in its
76 * own <code>getData()</code>.
79 * The <code>IManagedForm</code> can also used for drawing borders by calling the method
80 * <code>createBorderSupport()</code>.
88 abstract public class AbstractGroupedContainer
<T
extends TaxonBase
> implements IFormPart
, IContainerConstants
, IElementHasDetails
{
90 protected ParseHandler parseHandler
;
92 private FocusListener nameCompositeFocusListener
;
93 private ModifyListener nameCompositeModifyListener
;
95 protected NameViewer nameViewer
;
97 private AbstractGroup group
;
99 private Label nonEditableInfoLabel
;
100 private DefaultToolTip nonEditableInfoHover
;
102 private static AbstractGroupedContainer selection
;
104 private FocusListener focusListener
;
105 private LineBreakListener lineBreakListener
;
107 private int cursorPosition
;
109 protected Composite control
;
111 private Color backgroundColor
;
112 private boolean isDirty
;
116 * <p>Constructor for AbstractGroupedContainer.</p>
118 * @param editor a {@link eu.etaxonomy.taxeditor.editor.name.TaxonNameEditor} object.
119 * @param group a {@link eu.etaxonomy.taxeditor.editor.name.container.AbstractGroup} object.
120 * @param taxonBase a T object.
121 * @param <T> a T object.
123 public AbstractGroupedContainer(T taxonBase
){
125 parseHandler
= ParseHandler
.NewInstance(taxonBase
.getName());
128 public void createContent(){
132 createLineWrapSupport();
133 createLineBreakListener();
135 setMenu(getEditor().getMenu());
137 setDraggableControl(new Control
[]{getControl(), getNameViewer().getRulerControl()});
139 createEmptyViewerPrompt(EMPTY_NAME_PROMPT
);
142 initializeComposite();
152 * <p>createListener</p>
154 protected void createListener(){
155 nameCompositeModifyListener
= new ModifyListener(){
157 public void modifyText(ModifyEvent e
) {
158 // mark the composite dirty
161 String text
= nameViewer
.getTextWidget().getText();
163 NonViralName name
= parseHandler
.parse(text
);
164 getTaxonBase().setName(name
);
165 getTaxonBase().setTitleCache((getTaxonBase().generateTitle()));
167 // show errors resulting from parsing
169 // store the position of the cursor
171 // notify selection listener
172 setDelayedSelection();
175 nameCompositeFocusListener
= new FocusAdapter(){
178 * @see org.eclipse.swt.events.FocusAdapter#focusLost(org.eclipse.swt.events.FocusEvent)
181 public void focusLost(FocusEvent e
) {
191 private void addListener(){
192 getNameViewer().getTextWidget().addModifyListener(nameCompositeModifyListener
);
193 getNameViewer().getTextWidget().addFocusListener(nameCompositeFocusListener
);
196 private void removeListener(){
197 getNameViewer().getTextWidget().removeModifyListener(nameCompositeModifyListener
);
198 getNameViewer().getTextWidget().removeFocusListener(nameCompositeFocusListener
);
202 * Initialize the composite specific code
204 protected abstract void initializeComposite();
207 * <p>getEmptyTextPrompt</p>
209 * @return a {@link java.lang.String} object.
211 protected String
getEmptyTextPrompt() {
212 return EMPTY_NAME_PROMPT
;
218 private void showNameRelations() {
219 TaxonNameBase
<?
, ?
> name
= getName();
224 ILabelImageStrategy strategy
= LabelImageProvider
.getLabelStrategy(name
);
225 LabelImageProvider labelProvider
= new LabelImageProvider(strategy
);
227 Set
<NameRelationship
> nameRelations
= name
.getNameRelations();
228 if (nameRelations
.size() == 0) {
231 // for (NameRelationship nameRelation : nameRelations) {
232 // String typeLabel = null;
233 // TaxonNameBase<?, ?> relatedName = null;
235 // if (name.equals(nameRelation.getFromName())) {
236 // typeLabel = labelProvider.getNameRelationTypeLabel(
237 // nameRelation.getType());
238 // relatedName = nameRelation.getToName();
240 // typeLabel = labelProvider.getNameRelationTypeInverseLabel(
241 // nameRelation.getType());
242 // relatedName = nameRelation.getFromName();
245 // setNonEditableInfo(typeLabel + " " + NameHelper.getDisplayName(relatedName));
250 * <p>initTextViewer</p>
252 protected void initTextViewer() {
254 // showNameRelations();
260 String text
= NameHelper
.getDisplayNameWithRef(getData());
262 if (text
.length() == 0) {
265 getNameViewer().setText(text
);
272 * <p>calculateErrors</p>
274 synchronized protected void calculateErrors() {
275 getNameViewer().clearErrors();
276 getNameViewer().setShowParsingErrors(getName());
280 * <p>handleSplitText</p>
282 * @param text a {@link java.lang.String} object.
284 protected void handleSplitText(String text
) {
285 // Create a synonym in a new homotypic group using text as name
286 TaxonNameBase synonymName
= ParseHandler
.parseReferencedName(text
, null);
288 EditorUtil
.executeOperation(new CreateSynonymInNewGroupOperation
289 ("New Heterotypic Synonym", getEditor().getUndoContext(), getEditor().getTaxon(), synonymName
, getEditor()));
293 * Refreshes the display with latest data from the model.
295 * Note: Will not parse the text and not calculate errors!
297 public void refresh() {
298 // showNameRelations();
300 String text
= NameHelper
.getDisplayNameWithRef(getTaxonBase());
302 if(getNameViewer().getTextWidget() == null){
303 // we might get here via dnd. Look slike it can be ignored
307 if (text
.length() == 0) {
309 } else if(! getNameViewer().getTextWidget().getText().equals(text
)) {
311 getNameViewer().getTextWidget().setText(text
);
315 updateNonEditableInfo();
327 protected abstract void updateIcon();
330 protected abstract void updateIndent();
334 * <p>updateNonEditableInfo</p>
336 protected abstract void updateNonEditableInfo();
341 private void isFreeTextEnabled() {
342 // Decide whether editing of freetext is allowed or not.
343 if (freetextEditingAllowed()) {
346 getNameViewer().getTextWidget().setEditable(true);
348 // restore foreground font color again
349 getNameViewer().getTextWidget().setForeground(control
.getForeground());
352 getNameViewer().getTextWidget().setEditable(false);
354 // grey out text as a non-editable indicator
355 getNameViewer().getTextWidget().setForeground(EditorUtil
.getColor(Resources
.COLOR_DISABLED_EDITOR
));
361 * Checks whether the freetext should be editable based on specific empty fields.
364 private boolean freetextEditingAllowed() {
365 NonViralName name
= (NonViralName
) HibernateProxyHelper
.deproxy(getName());
366 boolean enableFreetext
= true;
368 enableFreetext
&= isNameUsedMultipleTimes(name
);
369 enableFreetext
&= isNameParsable(name
);
372 getNameViewer().setShowNameNotParsableWarning(name
);
375 return enableFreetext
;
378 private boolean isNameUsedMultipleTimes(NonViralName name
){
379 if(name
.getTaxonBases().size() != 1){
380 getNameViewer().setShowMultipleNameUsageWarning(name
);
386 private boolean isNameParsable(NonViralName name
){
387 boolean isParsable
= true;
388 isParsable
&= CdmUtils
.isEmpty(name
.getAppendedPhrase()); //taxonFieldsEmpty();
390 isParsable
&= ! name
.isProtectedAuthorshipCache();
391 isParsable
&= ! name
.isProtectedNameCache();
398 * Parse the text and calculate errors
400 public void parseAndCalculateErrors(){
402 String unparsedNameString
= getNameViewer().getTextWidget().getText();
403 parseHandler
.parse(unparsedNameString
);
409 * <p>getTaxonBase</p>
411 * @return the taxonBase
413 public T
getTaxonBase() {
420 * @return a {@link eu.etaxonomy.cdm.model.name.TaxonNameBase} object.
422 public TaxonNameBase
getName(){
423 return (TaxonNameBase
) HibernateProxyHelper
.deproxy(getTaxonBase().getName());
429 public void persistName(){
431 getNameViewer().getTextWidget().setEnabled(false);
432 final String unparsedNameString
= getNameViewer().getTextWidget().getText();
433 // Job job = new Job("Persisting Name"){
436 // protected IStatus run(IProgressMonitor monitor) {
438 final NonViralName name
= parseHandler
.parseAndResolveDuplicates(unparsedNameString
);
440 // Display.getDefault().asyncExec(new Runnable(){
441 // public void run() {
442 getTaxonBase().setName(name
);
443 getTaxonBase().setTitleCache((getTaxonBase().generateTitle()));
445 getNameViewer().getTextWidget().setEnabled(true);
450 // return Status.OK_STATUS;
455 // job.setPriority(Job.DECORATE);
461 * <p>Getter for the field <code>group</code>.</p>
463 * @return a {@link eu.etaxonomy.taxeditor.editor.name.container.AbstractGroup} object.
465 public AbstractGroup
getGroup(){
467 throw new IllegalStateException("Group shall not be null.");
475 public void remove(){
476 getGroup().remove(this);
480 * <p>createControl</p>
482 protected void createControl() {
483 control
= getEditor().getToolkit().createComposite(getGroup().getControl());
485 control
.setLayoutData(new TableWrapData(TableWrapData
.FILL_GRAB
));
486 TableWrapLayout layout
= new TableWrapLayout();
487 layout
.leftMargin
= 0;
488 layout
.rightMargin
= 0;
489 layout
.topMargin
= 5;
490 layout
.bottomMargin
= 5;
492 layout
.verticalSpacing
= 0;
493 layout
.horizontalSpacing
= 0;
495 control
.setLayout(layout
);
502 protected TaxonNameEditor
getEditor() {
503 return getGroup().getEditor();
507 * <p>Getter for the field <code>control</code>.</p>
509 * @return a {@link org.eclipse.swt.widgets.Composite} object.
511 public Composite
getControl(){
516 * <p>createLineWrapSupport</p>
518 protected void createLineWrapSupport() {
519 new LineWrapSupport(getNameViewer(), getEditor().getManagedForm());
524 * <p>createTextViewer</p>
526 protected void createTextViewer() {
527 nameViewer
= new NameViewer(control
);
529 focusListener
= new FocusAdapter() {
531 public void focusGained(FocusEvent e
) {
532 for(AbstractGroupedContainer container
: getEditor().getGroupedContainers()){
533 container
.colorSelected(NOT_SELECTED
);
535 getEditor().getManagedForm().setInput(AbstractGroupedContainer
.this);
537 colorSelected(SELECTED_FOCUS
);
540 nameViewer
.getTextWidget().addFocusListener(focusListener
);
543 MouseAdapter mouseListener
= new MouseAdapter() {
545 public void mouseDown(MouseEvent e
) {
549 control
.addMouseListener(mouseListener
);
550 nameViewer
.getRulerControl().addMouseListener(mouseListener
);
551 nameViewer
.getTextWidget().addMouseListener(mouseListener
);
557 * @param icon a {@link org.eclipse.swt.graphics.Image} object.
559 public void setIcon(Image icon
) {
560 getNameViewer().setIcon(icon
);
566 * @param indent a int.
568 public void setIndent(int indent
) {
569 if (control
.getLayout() instanceof TableWrapLayout
) {
570 TableWrapLayout layout
= ((TableWrapLayout
) control
.getLayout());
571 layout
.leftMargin
= indent
;
572 layout
.rightMargin
= ACCEPTED_INDENT
;
573 control
.setLayout(layout
);
576 new RuntimeException("Couldn't indent - composite's layout must be TableWrapLayout.");
583 public void setSelected() {
584 getNameViewer().getTextWidget().setFocus();
592 public boolean isSelected(){
593 return getEditor().getSelectedContainer() == this;
597 * <p>colorSelected</p>
601 public void colorSelected(int mode
){
602 if(!control
.isDisposed()){
603 String colorString
= null;
607 colorString
= Resources
.COLOR_CONTROL_SELECTED_FOCUS
;
609 case SELECTED_NO_FOCUS
:
610 colorString
= Resources
.COLOR_CONTROL_SELECTED
;
613 colorString
= Resources
.COLOR_COMPOSITE_BACKGROUND
;
616 backgroundColor
= EditorUtil
.getColor(colorString
);
618 setBackground(backgroundColor
);
624 * <p>setDelayedSelection</p>
626 protected void setDelayedSelection(){
627 //TODO this might be done better
628 // this is the quickest solution i could come up with and it improves performance
629 // please reimplement if you know better.
633 Display display
= Display
.getCurrent();
634 Runnable runnable
= new Runnable() {
637 getEditor().getManagedForm().setInput(selection
);
640 display
.timerExec(1000, runnable
);
645 * <p>setBackground</p>
647 * @param color a {@link org.eclipse.swt.graphics.Color} object.
649 public void setBackground(Color color
) {
650 control
.setBackground(color
);
652 for(Control child
: control
.getChildren()){
653 child
.setBackground(color
);
656 getNameViewer().setBackground(color
);
660 * @see org.eclipse.swt.widgets.Control#setFont(org.eclipse.swt.graphics.Font)
665 * @param font a {@link org.eclipse.swt.graphics.Font} object.
667 public void setFont(Font font
) {
668 getNameViewer().getTextWidget().setFont(font
);
672 * <p>Getter for the field <code>nameViewer</code>.</p>
674 * @return a {@link eu.etaxonomy.taxeditor.editor.name.container.NameViewer} object.
676 public NameViewer
getNameViewer() {
677 if (nameViewer
== null){
678 throw new RuntimeException("The Name Viewer is corrupt for Name Container: " + getTaxonBase().getName().getTitleCache());
684 * If <code>textViewer</code> has already been set, it will show a
685 * <code>prompt</code> along the lines of "Click here to start entering data"
688 * @param prompt a {@link java.lang.String} object.
690 public void createEmptyViewerPrompt(final String prompt
) {
692 Assert
.isNotNull(getNameViewer());
694 final StyledText textControl
= getNameViewer().getTextWidget();
695 final IDocument document
= getNameViewer().getDocument();
697 setFocusListener(new FocusListener() {
700 public void focusGained(FocusEvent e
) {
701 if (document
.get().equals(prompt
)) {
702 textControl
.setFont(getViewerFont());
708 public void focusLost(FocusEvent e
) {
709 if (document
.getLength() == 0) {
715 textControl
.addFocusListener(getFocusListener());
717 if (document
.getLength() == 0) {
718 textControl
.setFont(EditorUtil
.getFont(Resources
.FONT_DEFAULT_PROMPT
));
719 document
.set(prompt
);
724 * <p>getViewerFont</p>
726 * @return a {@link org.eclipse.swt.graphics.Font} object.
728 abstract protected Font
getViewerFont();
731 * <p>initEmptyText</p>
733 protected void initEmptyText() {
734 Font defaultFont
= EditorUtil
.getFont(Resources
.FONT_DEFAULT_PROMPT
);
735 getNameViewer().getTextWidget().setFont(defaultFont
);
737 getNameViewer().getDocument().set(getEmptyTextPrompt());
742 * <p>Setter for the field <code>focusListener</code>.</p>
744 * @param focusListener a {@link org.eclipse.swt.events.FocusListener} object.
746 protected void setFocusListener(FocusListener focusListener
) {
747 this.focusListener
= focusListener
;
750 private FocusListener
getFocusListener() {
751 return focusListener
;
757 * @param isDirty a boolean.
759 public void setDirty(boolean isDirty
) {
761 getEditor().getManagedForm().dirtyStateChanged();
763 this.isDirty
= isDirty
;
771 public boolean isDirty(){
778 * @param menu a {@link org.eclipse.swt.widgets.Menu} object.
780 public void setMenu (Menu menu
) {
781 control
.setMenu(menu
);
783 getNameViewer().setMenu(menu
);
786 private Control
[] draggableControls
;
789 * <p>setDraggableControl</p>
791 * @param controls an array of {@link org.eclipse.swt.widgets.Control} objects.
793 protected void setDraggableControl(Control
[] controls
) {
794 draggableControls
= controls
;
798 * <p>setIsDraggable</p>
800 * @param draggable a boolean.
802 public void setIsDraggable(boolean draggable
) {
806 if (draggableControls
== null) {
807 throw new NullPointerException(
808 "Draggable controls must be set to add draggability");
811 Transfer
[] types
= new Transfer
[] { CdmDataTransfer
.getInstance() };
812 int operations
= DND
.DROP_MOVE
;
814 for(Control draggableControl
: draggableControls
){
815 DragSource dragSource
= new DragSource(draggableControl
, operations
);
816 dragSource
.setTransfer(types
);
818 dragSource
.addDragListener(new NameEditorDragListener(this));
819 dragSource
.setDragSourceEffect(new NameEditorDragSourceEffect(control
));
824 private String nonEditableText
;
826 ControlListener nonEditableResizeListener
= new ControlAdapter() {
831 public void controlResized(ControlEvent e
) {
832 if (nonEditableInfoLabel
.getBounds().width
== width
) {
835 width
= nonEditableInfoLabel
.getBounds().width
;
836 if (nonEditableInfoLabel
.getBounds().width
> 0) {
837 nonEditableInfoLabel
.setText(
838 Dialog
.shortenText(nonEditableText
.toUpperCase(),
839 nonEditableInfoLabel
));
844 private String nonEditableHoverText
;
846 private LabelEllipsisListener nonEditableLabelEllipsisListener
;
851 * nonEditableInfo is a label displayed underneath a GroupedComposite's
852 * input field. For instance, NameComposites display things like name relations,
853 * sec. references, etc. here.
855 * @param info the text to display in the label
856 * @param append whether the string should be appended to text that is already shown in the label
858 public void setNonEditableInfo(String info
, boolean append
) {
859 // TODO non editable info should only be drawn once, when everything else is drawn
860 info
= info
.toUpperCase();
863 nonEditableText
+= ", " + info
;
864 nonEditableHoverText
+= "\n" + info
;
866 nonEditableText
= info
;
867 nonEditableHoverText
= info
;
870 if (nonEditableInfoLabel
== null) {
871 nonEditableInfoLabel
= getEditor().getToolkit().createLabel(control
, "");
872 TableWrapData layoutData
= new TableWrapData(TableWrapData
.FILL_GRAB
, TableWrapData
.TOP
);
873 // Set indent to viewer ruler's width
874 if (getNameViewer().getRulerControl() != null) {
875 // TODO right justify
876 layoutData
.indent
= NameViewer
.RULER_WIDTH
;
878 nonEditableInfoLabel
.setLayoutData(layoutData
);
882 nonEditableLabelEllipsisListener
= new LabelEllipsisListener(nonEditableInfoLabel
) {
884 public String
getLabelText() {
885 return nonEditableText
.toUpperCase();
888 nonEditableInfoLabel
.addControlListener(nonEditableLabelEllipsisListener
);
890 nonEditableInfoHover
= new DefaultToolTip(nonEditableInfoLabel
);
891 nonEditableInfoHover
.setRespectDisplayBounds(true);
894 nonEditableInfoHover
.setText(nonEditableHoverText
);
895 nonEditableInfoLabel
.setText(nonEditableText
);
901 * <p>Getter for the field <code>data</code>.</p>
903 * @return a T object.
910 * <p>Setter for the field <code>data</code>.</p>
912 * @param data a T object.
914 public void setData(T data
){
915 this.data
= (T
) HibernateProxyHelper
.deproxy(data
);
919 * If the user hitting carriage return should cause something to happen -
920 * i.e. the creation of a new composite - call this method and override
921 * the method handleSplitText().
923 protected void createLineBreakListener() {
924 lineBreakListener
= new LineBreakListener() {
926 public void handleSplitText(String text
) {
927 AbstractGroupedContainer
.this.handleSplitText(text
);
931 getNameViewer().getTextWidget().addVerifyListener(lineBreakListener
);
934 abstract class LabelEllipsisListener
extends ControlAdapter
{
936 private final Label label
;
939 LabelEllipsisListener(Label label
) {
943 abstract public String
getLabelText();
946 public void controlResized(ControlEvent e
) {
947 if (label
.getBounds().width
== width
) {
950 width
= label
.getBounds().width
;
951 if (label
.getBounds().width
> 0) {
952 label
.setText(TextHelper
.shortenText(getLabelText(), label
));
960 public void storeCursor() {
961 this.cursorPosition
= getNameViewer().getCursorPosition();
965 * Puts the cursor to the position it was last seen on or to the end of line
966 * if no former position is known.
968 public void placeCursor(){
969 if(cursorPosition
== 0){
970 getNameViewer().setCursorToEOL();
972 getNameViewer().setCursorPosition(cursorPosition
);
979 * <p>Setter for the field <code>group</code>.</p>
981 * @param group a {@link eu.etaxonomy.taxeditor.editor.name.container.AbstractGroup} object.
983 public void setGroup(AbstractGroup group
) {
990 * <p>restoreColor</p>
992 public void restoreColor() {
993 setBackground(backgroundColor
);
999 * @see org.eclipse.ui.forms.IFormPart#initialize(org.eclipse.ui.forms.IManagedForm)
1002 public void initialize(IManagedForm form
) {
1003 // TODO Auto-generated method stub
1009 * @see org.eclipse.ui.forms.IFormPart#dispose()
1012 public void dispose() {
1013 if(getControl() != null){
1015 getControl().dispose();
1021 * @see org.eclipse.ui.forms.IFormPart#commit(boolean)
1024 public void commit(boolean onSave
) {
1032 * @see org.eclipse.ui.forms.IFormPart#setFormInput(java.lang.Object)
1035 public boolean setFormInput(Object input
) {
1036 // TODO Auto-generated method stub
1042 * @see org.eclipse.ui.forms.IFormPart#setFocus()
1045 public void setFocus() {
1046 getNameViewer().getControl().setFocus();
1051 * @see org.eclipse.ui.forms.IFormPart#isStale()
1054 public boolean isStale() {
1055 // TODO Auto-generated method stub