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() {
530 public void focusGained(FocusEvent e
) {
531 for(AbstractGroupedContainer container
: getEditor().getGroupedContainers()){
532 container
.colorSelected(NOT_SELECTED
);
534 getEditor().getManagedForm().setInput(AbstractGroupedContainer
.this);
536 colorSelected(SELECTED_FOCUS
);
539 nameViewer
.getTextWidget().addFocusListener(focusListener
);
542 MouseAdapter mouseListener
= new MouseAdapter() {
543 public void mouseDown(MouseEvent e
) {
547 control
.addMouseListener(mouseListener
);
548 nameViewer
.getRulerControl().addMouseListener(mouseListener
);
549 nameViewer
.getTextWidget().addMouseListener(mouseListener
);
555 * @param icon a {@link org.eclipse.swt.graphics.Image} object.
557 public void setIcon(Image icon
) {
558 getNameViewer().setIcon(icon
);
564 * @param indent a int.
566 public void setIndent(int indent
) {
567 if (control
.getLayout() instanceof TableWrapLayout
) {
568 TableWrapLayout layout
= ((TableWrapLayout
) control
.getLayout());
569 layout
.leftMargin
= indent
;
570 layout
.rightMargin
= ACCEPTED_INDENT
;
571 control
.setLayout(layout
);
574 new RuntimeException("Couldn't indent - composite's layout must be TableWrapLayout.");
581 public void setSelected() {
582 getNameViewer().getTextWidget().setFocus();
590 public boolean isSelected(){
591 return getEditor().getSelectedContainer() == this;
595 * <p>colorSelected</p>
599 public void colorSelected(int mode
){
600 if(!control
.isDisposed()){
601 String colorString
= null;
605 colorString
= Resources
.COLOR_CONTROL_SELECTED_FOCUS
;
607 case SELECTED_NO_FOCUS
:
608 colorString
= Resources
.COLOR_CONTROL_SELECTED
;
611 colorString
= Resources
.COLOR_COMPOSITE_BACKGROUND
;
614 backgroundColor
= EditorUtil
.getColor(colorString
);
616 setBackground(backgroundColor
);
622 * <p>setDelayedSelection</p>
624 protected void setDelayedSelection(){
625 //TODO this might be done better
626 // this is the quickest solution i could come up with and it improves performance
627 // please reimplement if you know better.
631 Display display
= Display
.getCurrent();
632 Runnable runnable
= new Runnable() {
635 getEditor().getManagedForm().setInput(selection
);
638 display
.timerExec(1000, runnable
);
643 * <p>setBackground</p>
645 * @param color a {@link org.eclipse.swt.graphics.Color} object.
647 public void setBackground(Color color
) {
648 control
.setBackground(color
);
650 for(Control child
: control
.getChildren()){
651 child
.setBackground(color
);
654 getNameViewer().setBackground(color
);
658 * @see org.eclipse.swt.widgets.Control#setFont(org.eclipse.swt.graphics.Font)
663 * @param font a {@link org.eclipse.swt.graphics.Font} object.
665 public void setFont(Font font
) {
666 getNameViewer().getTextWidget().setFont(font
);
670 * <p>Getter for the field <code>nameViewer</code>.</p>
672 * @return a {@link eu.etaxonomy.taxeditor.editor.name.container.NameViewer} object.
674 public NameViewer
getNameViewer() {
675 if (nameViewer
== null){
676 throw new RuntimeException("The Name Viewer is corrupt for Name Container: " + getTaxonBase().getName().getTitleCache());
682 * If <code>textViewer</code> has already been set, it will show a
683 * <code>prompt</code> along the lines of "Click here to start entering data"
686 * @param prompt a {@link java.lang.String} object.
688 public void createEmptyViewerPrompt(final String prompt
) {
690 Assert
.isNotNull(getNameViewer());
692 final StyledText textControl
= getNameViewer().getTextWidget();
693 final IDocument document
= getNameViewer().getDocument();
695 setFocusListener(new FocusListener() {
698 public void focusGained(FocusEvent e
) {
699 if (document
.get().equals(prompt
)) {
700 textControl
.setFont(getViewerFont());
706 public void focusLost(FocusEvent e
) {
707 if (document
.getLength() == 0) {
713 textControl
.addFocusListener(getFocusListener());
715 if (document
.getLength() == 0) {
716 textControl
.setFont(EditorUtil
.getFont(Resources
.FONT_DEFAULT_PROMPT
));
717 document
.set(prompt
);
722 * <p>getViewerFont</p>
724 * @return a {@link org.eclipse.swt.graphics.Font} object.
726 abstract protected Font
getViewerFont();
729 * <p>initEmptyText</p>
731 protected void initEmptyText() {
732 Font defaultFont
= EditorUtil
.getFont(Resources
.FONT_DEFAULT_PROMPT
);
733 getNameViewer().getTextWidget().setFont(defaultFont
);
735 getNameViewer().getDocument().set(getEmptyTextPrompt());
740 * <p>Setter for the field <code>focusListener</code>.</p>
742 * @param focusListener a {@link org.eclipse.swt.events.FocusListener} object.
744 protected void setFocusListener(FocusListener focusListener
) {
745 this.focusListener
= focusListener
;
748 private FocusListener
getFocusListener() {
749 return focusListener
;
755 * @param isDirty a boolean.
757 public void setDirty(boolean isDirty
) {
759 getEditor().getManagedForm().dirtyStateChanged();
761 this.isDirty
= isDirty
;
769 public boolean isDirty(){
776 * @param menu a {@link org.eclipse.swt.widgets.Menu} object.
778 public void setMenu (Menu menu
) {
779 control
.setMenu(menu
);
781 getNameViewer().setMenu(menu
);
784 private Control
[] draggableControls
;
787 * <p>setDraggableControl</p>
789 * @param controls an array of {@link org.eclipse.swt.widgets.Control} objects.
791 protected void setDraggableControl(Control
[] controls
) {
792 draggableControls
= controls
;
796 * <p>setIsDraggable</p>
798 * @param draggable a boolean.
800 public void setIsDraggable(boolean draggable
) {
804 if (draggableControls
== null) {
805 throw new NullPointerException(
806 "Draggable controls must be set to add draggability");
809 Transfer
[] types
= new Transfer
[] { CdmDataTransfer
.getInstance() };
810 int operations
= DND
.DROP_MOVE
;
812 for(Control draggableControl
: draggableControls
){
813 DragSource dragSource
= new DragSource(draggableControl
, operations
);
814 dragSource
.setTransfer(types
);
816 dragSource
.addDragListener(new NameEditorDragListener(this));
817 dragSource
.setDragSourceEffect(new NameEditorDragSourceEffect(control
));
822 private String nonEditableText
;
824 ControlListener nonEditableResizeListener
= new ControlAdapter() {
828 public void controlResized(ControlEvent e
) {
829 if (nonEditableInfoLabel
.getBounds().width
== width
) {
832 width
= nonEditableInfoLabel
.getBounds().width
;
833 if (nonEditableInfoLabel
.getBounds().width
> 0) {
834 nonEditableInfoLabel
.setText(
835 Dialog
.shortenText(nonEditableText
.toUpperCase(),
836 nonEditableInfoLabel
));
841 private String nonEditableHoverText
;
843 private LabelEllipsisListener nonEditableLabelEllipsisListener
;
848 * nonEditableInfo is a label displayed underneath a GroupedComposite's
849 * input field. For instance, NameComposites display things like name relations,
850 * sec. references, etc. here.
852 * @param info the text to display in the label
853 * @param append whether the string should be appended to text that is already shown in the label
855 public void setNonEditableInfo(String info
, boolean append
) {
856 // TODO non editable info should only be drawn once, when everything else is drawn
857 info
= info
.toUpperCase();
860 nonEditableText
+= ", " + info
;
861 nonEditableHoverText
+= "\n" + info
;
863 nonEditableText
= info
;
864 nonEditableHoverText
= info
;
867 if (nonEditableInfoLabel
== null) {
868 nonEditableInfoLabel
= getEditor().getToolkit().createLabel(control
, "");
869 TableWrapData layoutData
= new TableWrapData(TableWrapData
.FILL_GRAB
, TableWrapData
.TOP
);
870 // Set indent to viewer ruler's width
871 if (getNameViewer().getRulerControl() != null) {
872 // TODO right justify
873 layoutData
.indent
= NameViewer
.RULER_WIDTH
;
875 nonEditableInfoLabel
.setLayoutData(layoutData
);
879 nonEditableLabelEllipsisListener
= new LabelEllipsisListener(nonEditableInfoLabel
) {
881 public String
getLabelText() {
882 return nonEditableText
.toUpperCase();
885 nonEditableInfoLabel
.addControlListener(nonEditableLabelEllipsisListener
);
887 nonEditableInfoHover
= new DefaultToolTip(nonEditableInfoLabel
);
888 nonEditableInfoHover
.setRespectDisplayBounds(true);
891 nonEditableInfoHover
.setText(nonEditableHoverText
);
892 nonEditableInfoLabel
.setText(nonEditableText
);
896 * <p>Getter for the field <code>data</code>.</p>
898 * @return a T object.
905 * <p>Setter for the field <code>data</code>.</p>
907 * @param data a T object.
909 public void setData(T data
){
910 this.data
= (T
) HibernateProxyHelper
.deproxy(data
);
914 * If the user hitting carriage return should cause something to happen -
915 * i.e. the creation of a new composite - call this method and override
916 * the method handleSplitText().
918 protected void createLineBreakListener() {
919 lineBreakListener
= new LineBreakListener() {
921 public void handleSplitText(String text
) {
922 AbstractGroupedContainer
.this.handleSplitText(text
);
926 getNameViewer().getTextWidget().addVerifyListener(lineBreakListener
);
929 abstract class LabelEllipsisListener
extends ControlAdapter
{
934 LabelEllipsisListener(Label label
) {
938 abstract public String
getLabelText();
940 public void controlResized(ControlEvent e
) {
941 if (label
.getBounds().width
== width
) {
944 width
= label
.getBounds().width
;
945 if (label
.getBounds().width
> 0) {
946 label
.setText(TextHelper
.shortenText(getLabelText(), label
));
954 public void storeCursor() {
955 this.cursorPosition
= getNameViewer().getCursorPosition();
959 * Puts the cursor to the position it was last seen on or to the end of line
960 * if no former position is known.
962 public void placeCursor(){
963 if(cursorPosition
== 0){
964 getNameViewer().setCursorToEOL();
966 getNameViewer().setCursorPosition(cursorPosition
);
973 * <p>Setter for the field <code>group</code>.</p>
975 * @param group a {@link eu.etaxonomy.taxeditor.editor.name.container.AbstractGroup} object.
977 public void setGroup(AbstractGroup group
) {
984 * <p>restoreColor</p>
986 public void restoreColor() {
987 setBackground(backgroundColor
);
993 * @see org.eclipse.ui.forms.IFormPart#initialize(org.eclipse.ui.forms.IManagedForm)
996 public void initialize(IManagedForm form
) {
997 // TODO Auto-generated method stub
1003 * @see org.eclipse.ui.forms.IFormPart#dispose()
1006 public void dispose() {
1007 if(getControl() != null){
1009 getControl().dispose();
1015 * @see org.eclipse.ui.forms.IFormPart#commit(boolean)
1018 public void commit(boolean onSave
) {
1026 * @see org.eclipse.ui.forms.IFormPart#setFormInput(java.lang.Object)
1029 public boolean setFormInput(Object input
) {
1030 // TODO Auto-generated method stub
1036 * @see org.eclipse.ui.forms.IFormPart#setFocus()
1039 public void setFocus() {
1040 getNameViewer().getControl().setFocus();
1045 * @see org.eclipse.ui.forms.IFormPart#isStale()
1048 public boolean isStale() {
1049 // TODO Auto-generated method stub