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
;
12 import java
.lang
.reflect
.Method
;
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
.window
.DefaultToolTip
;
19 import org
.eclipse
.swt
.custom
.StyledText
;
20 import org
.eclipse
.swt
.dnd
.DND
;
21 import org
.eclipse
.swt
.dnd
.DragSource
;
22 import org
.eclipse
.swt
.dnd
.Transfer
;
23 import org
.eclipse
.swt
.events
.ControlAdapter
;
24 import org
.eclipse
.swt
.events
.ControlEvent
;
25 import org
.eclipse
.swt
.events
.ControlListener
;
26 import org
.eclipse
.swt
.events
.FocusAdapter
;
27 import org
.eclipse
.swt
.events
.FocusEvent
;
28 import org
.eclipse
.swt
.events
.FocusListener
;
29 import org
.eclipse
.swt
.events
.ModifyEvent
;
30 import org
.eclipse
.swt
.events
.ModifyListener
;
31 import org
.eclipse
.swt
.events
.MouseAdapter
;
32 import org
.eclipse
.swt
.events
.MouseEvent
;
33 import org
.eclipse
.swt
.graphics
.Color
;
34 import org
.eclipse
.swt
.graphics
.Font
;
35 import org
.eclipse
.swt
.graphics
.Image
;
36 import org
.eclipse
.swt
.widgets
.Composite
;
37 import org
.eclipse
.swt
.widgets
.Control
;
38 import org
.eclipse
.swt
.widgets
.Display
;
39 import org
.eclipse
.swt
.widgets
.Label
;
40 import org
.eclipse
.swt
.widgets
.Menu
;
41 import org
.eclipse
.ui
.forms
.IFormPart
;
42 import org
.eclipse
.ui
.forms
.IManagedForm
;
43 import org
.eclipse
.ui
.forms
.widgets
.TableWrapData
;
44 import org
.eclipse
.ui
.forms
.widgets
.TableWrapLayout
;
46 import eu
.etaxonomy
.cdm
.common
.CdmUtils
;
47 import eu
.etaxonomy
.cdm
.hibernate
.HibernateProxyHelper
;
48 import eu
.etaxonomy
.cdm
.model
.common
.CdmBase
;
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
.taxeditor
.editor
.CdmDataTransfer
;
54 import eu
.etaxonomy
.taxeditor
.editor
.EditorUtil
;
55 import eu
.etaxonomy
.taxeditor
.editor
.name
.operation
.CreateSynonymInNewGroupOperation
;
56 import eu
.etaxonomy
.taxeditor
.labels
.ILabelImageStrategy
;
57 import eu
.etaxonomy
.taxeditor
.labels
.LabelImageProvider
;
58 import eu
.etaxonomy
.taxeditor
.model
.ImageResources
;
59 import eu
.etaxonomy
.taxeditor
.model
.NameHelper
;
60 import eu
.etaxonomy
.taxeditor
.model
.TextHelper
;
61 import eu
.etaxonomy
.taxeditor
.parser
.ParseHandler
;
62 import eu
.etaxonomy
.taxeditor
.preference
.Resources
;
65 * Formats <code>GroupedComposite</code> with cosmetic and layout properties specific to the
66 * Editor. This should be used to maintain a consistent look and feel for all Editor
67 * freetext area components, such as DescriptionElementComposite.
69 * Requires an <code>IManagedForm</code>, whose <code>input</code> is set to the contents
70 * of {@link #getData()} when the <code>GroupedComposite</code> gets focus, i.e. to
71 * populate the property sheet with the data.
74 * The <code>IManagedForm</code> is also required to have a <code>Taxon</code> in its
75 * own <code>getData()</code>.
78 * The <code>IManagedForm</code> can also used for drawing borders by calling the method
79 * <code>createBorderSupport()</code>.
87 abstract public class AbstractGroupedContainer
<T
extends TaxonBase
> implements IFormPart
{
92 public static final int SELECTED_FOCUS
= 1;
93 /** Constant <code>SELECTED_NO_FOCUS=2</code> */
94 public static final int SELECTED_NO_FOCUS
= 2;
95 /** Constant <code>NOT_SELECTED=3</code> */
96 public static final int NOT_SELECTED
= 3;
99 * ************ COMPOSITE TYPES ************
101 public String compositeType
;
102 /** Constant <code>ACCEPTED_TAXON="accepted_name_composite"</code> */
103 public static final String ACCEPTED_TAXON
= "accepted_name_composite";
104 /** Constant <code>HOMOTYPIC_SYNONYM="homotypic_name_composite"</code> */
105 public static final String HOMOTYPIC_SYNONYM
= "homotypic_name_composite";
106 /** Constant <code>HETEROTYPIC_SYNONYM="heterotypic_name_composite"</code> */
107 public static final String HETEROTYPIC_SYNONYM
= "heterotypic_name_composite";
108 /** Constant <code>MISAPPLIED_NAME="misappliedname_name_composite"</code> */
109 public static final String MISAPPLIED_NAME
= "misappliedname_name_composite";
110 /** Constant <code>CONCEPTRELATION="concept_name_composite"</code> */
111 public static final String CONCEPTRELATION
= "concept_name_composite";
114 * ************ INDENTATIONS ************
116 public static final int ACCEPTED_INDENT
= 20;
117 /** Constant <code>SYNONYM_INDENT=40</code> */
118 public static final int SYNONYM_INDENT
= 40;
119 /** Constant <code>MISAPPLIEDNAME_INDENT=40</code> */
120 public static final int MISAPPLIEDNAME_INDENT
= 40;
121 /** Constant <code>CONCEPT_INDENT=40</code> */
122 public static final int CONCEPT_INDENT
= 40;
126 * ************ ICONS ************
128 public static final Image ACCEPTED_ICON
= ImageResources
.getImage(ImageResources
.BLACK_SQUARE_ICON
);
129 /** Constant <code>HOMOTYPIC_SYNONYM_ICON</code> */
130 public static final Image HOMOTYPIC_SYNONYM_ICON
= ImageResources
.getImage(ImageResources
.HOMOTYPIC_SYN_ICON
);
131 /** Constant <code>HOMOTYPIC_SYNONYM_ORIGINAL_COMBINATION_ICON</code> */
132 public static final Image HOMOTYPIC_SYNONYM_ORIGINAL_COMBINATION_ICON
= ImageResources
.getImage(
133 ImageResources
.HOMOTYPIC_SYN_ORIGINAL_ICON
);
134 /** Constant <code>HETEROTYPIC_SYNONYM_ICON</code> */
135 public static final Image HETEROTYPIC_SYNONYM_ICON
= ImageResources
.getImage(ImageResources
.HETEROTYPIC_SYN_ICON
);
136 public static final Image INVALID_OR_NUDUM_NAME_ICON
= ImageResources
.getImage(ImageResources
.NOM_INVAL_NUD_SYN_ICON
);
137 /** Constant <code>HETEROTYPIC_SYNONYM_ORIGINAL_COMBINATION_ICON</code> */
138 public static final Image HETEROTYPIC_SYNONYM_ORIGINAL_COMBINATION_ICON
= ImageResources
.getImage(
139 ImageResources
.HETEROTYPIC_SYN_ORIGINAL_ICON
);
140 /** Constant <code>MISAPPLIEDNAME_ICON</code> */
141 public static final Image MISAPPLIEDNAME_ICON
= ImageResources
.getImage(ImageResources
.MISAPPLIED_NAME_ICON
);
142 /** Constant <code>CONCEPT_ICON</code> */
143 public static final Image CONCEPT_ICON
= ImageResources
.getImage(ImageResources
.CONCEPT_ICON
);
144 /** Constant <code>AUTONYM_ICON</code> */
145 public static final Image AUTONYM_ICON
= ImageResources
146 .getImage(ImageResources
.AUTONYM_ICON
);
147 /** Constant <code>MOVE</code> */
148 public static final Image MOVE
= ImageResources
.getImage(ImageResources
.MOVE_ICON
);
151 * ************ TRANSFORMATIONS ************
153 public static final String ADD_GROUP_BASIONYM
= "add_group_basionym";
154 /** Constant <code>REMOVE_GROUP_BASIONYM="remove_group_basionym"</code> */
155 public static final String REMOVE_GROUP_BASIONYM
= "remove_group_basionym";
157 private static final String EMPTY_NAME_PROMPT
= "Click to add name";
159 protected ParseHandler parseHandler
;
161 private FocusListener nameCompositeFocusListener
;
162 private ModifyListener nameCompositeModifyListener
;
165 protected TaxonNameEditor editor
;
167 protected NameViewer nameViewer
;
169 private AbstractGroup
<T
> group
;
171 private Label nonEditableInfoLabel
;
172 private DefaultToolTip nonEditableInfoHover
;
174 private static AbstractGroupedContainer selection
;
176 private FocusListener focusListener
;
177 private LineBreakListener lineBreakListener
;
179 private int cursorPosition
;
181 protected Composite control
;
183 private Color backgroundColor
;
184 private boolean isDirty
;
188 * <p>Constructor for AbstractGroupedContainer.</p>
190 * @param editor a {@link eu.etaxonomy.taxeditor.editor.name.TaxonNameEditor} object.
191 * @param group a {@link eu.etaxonomy.taxeditor.editor.name.AbstractGroup} object.
192 * @param taxonBase a T object.
193 * @param <T> a T object.
195 public AbstractGroupedContainer(TaxonNameEditor editor
, AbstractGroup
<T
> group
, T taxonBase
){
196 this.editor
= editor
;
206 createLineWrapSupport();
207 createLineBreakListener();
209 setMenu(editor
.getMenu());
211 setDraggableControl(new Control
[]{getControl(), getNameViewer().getRulerControl()});
213 createEmptyViewerPrompt(EMPTY_NAME_PROMPT
);
215 parseHandler
= ParseHandler
.NewInstance(getNameViewer().getTextWidget(), taxonBase
.getName());
217 initializeComposite();
227 * <p>createListener</p>
229 protected void createListener(){
230 nameCompositeModifyListener
= new ModifyListener(){
232 public void modifyText(ModifyEvent e
) {
233 // mark the composite dirty
236 String text
= nameViewer
.getTextWidget().getText();
238 NonViralName name
= parseHandler
.parse(text
);
239 getTaxonBase().setName(name
);
240 getTaxonBase().setTitleCache((getTaxonBase().generateTitle()));
242 // show errors resulting from parsing
244 // store the position of the cursor
246 // notify selection listener
247 setDelayedSelection();
250 nameCompositeFocusListener
= new FocusAdapter(){
253 * @see org.eclipse.swt.events.FocusAdapter#focusLost(org.eclipse.swt.events.FocusEvent)
256 public void focusLost(FocusEvent e
) {
266 private void addListener(){
267 getNameViewer().getTextWidget().addModifyListener(nameCompositeModifyListener
);
268 getNameViewer().getTextWidget().addFocusListener(nameCompositeFocusListener
);
271 private void removeListener(){
272 getNameViewer().getTextWidget().removeModifyListener(nameCompositeModifyListener
);
273 getNameViewer().getTextWidget().removeFocusListener(nameCompositeFocusListener
);
277 * Initialize the composite specific code
279 protected abstract void initializeComposite();
282 * <p>getEmptyTextPrompt</p>
284 * @return a {@link java.lang.String} object.
286 protected String
getEmptyTextPrompt() {
287 return EMPTY_NAME_PROMPT
;
293 private void showNameRelations() {
294 TaxonNameBase
<?
, ?
> name
= getName();
299 ILabelImageStrategy strategy
= LabelImageProvider
.getLabelStrategy(name
);
300 LabelImageProvider labelProvider
= new LabelImageProvider(strategy
);
302 Set
<NameRelationship
> nameRelations
= name
.getNameRelations();
303 if (nameRelations
.size() == 0) {
306 // for (NameRelationship nameRelation : nameRelations) {
307 // String typeLabel = null;
308 // TaxonNameBase<?, ?> relatedName = null;
310 // if (name.equals(nameRelation.getFromName())) {
311 // typeLabel = labelProvider.getNameRelationTypeLabel(
312 // nameRelation.getType());
313 // relatedName = nameRelation.getToName();
315 // typeLabel = labelProvider.getNameRelationTypeInverseLabel(
316 // nameRelation.getType());
317 // relatedName = nameRelation.getFromName();
320 // setNonEditableInfo(typeLabel + " " + NameHelper.getDisplayName(relatedName));
325 * <p>initTextViewer</p>
327 protected void initTextViewer() {
329 // showNameRelations();
333 String text
= NameHelper
.getDisplayNameWithRef(getData());
335 if (text
.length() == 0) {
338 getNameViewer().setText(text
);
345 * <p>calculateErrors</p>
347 synchronized protected void calculateErrors() {
348 getNameViewer().clearErrors();
349 getNameViewer().setShowParsingErrors(getName());
353 * <p>handleSplitText</p>
355 * @param text a {@link java.lang.String} object.
357 protected void handleSplitText(String text
) {
358 // Create a synonym in a new homotypic group using text as name
359 TaxonNameBase synonymName
= ParseHandler
.quickParse(text
);
361 EditorUtil
.executeOperation(new CreateSynonymInNewGroupOperation
362 ("New Heterotypic Synonym", editor
.getUndoContext(), editor
.getTaxon(), synonymName
, editor
));
366 * Refreshes the display with latest data from the model.
368 * Note: Will not parse the text and not calculate errors!
370 public void refresh() {
371 // showNameRelations();
373 String text
= NameHelper
.getDisplayNameWithRef(getTaxonBase());
375 if (text
.length() == 0) {
379 getNameViewer().getTextWidget().setText(text
);
383 updateNonEditableInfo();
394 protected abstract void updateIcon();
399 * <p>updateNonEditableInfo</p>
401 protected abstract void updateNonEditableInfo();
406 private void isFreeTextEnabled() {
407 // Decide whether editing of freetext is allowed or not.
408 if (freetextEditingAllowed()) {
411 getNameViewer().getTextWidget().setEditable(true);
413 // restore foreground font color again
414 getNameViewer().getTextWidget().setForeground(control
.getForeground());
417 getNameViewer().getTextWidget().setEditable(false);
419 // grey out text as a non-editable indicator
420 getNameViewer().getTextWidget().setForeground(EditorUtil
.getColor(Resources
.COLOR_DISABLED_EDITOR
));
426 * Checks whether the freetext should be editable based on specific empty fields.
429 private boolean freetextEditingAllowed() {
430 NonViralName name
= (NonViralName
) HibernateProxyHelper
.deproxy(getName());
431 boolean enableFreetext
= true;
433 enableFreetext
&= isNameUsedMultipleTimes(name
);
434 enableFreetext
&= isNameParsable(name
);
437 getNameViewer().setShowNameNotParsableWarning(name
);
440 return enableFreetext
;
443 private boolean isNameUsedMultipleTimes(NonViralName name
){
444 if(name
.getTaxonBases().size() != 1){
445 getNameViewer().setShowMultipleNameUsageWarning(name
);
451 private boolean isNameParsable(NonViralName name
){
452 boolean isParsable
= true;
453 isParsable
&= CdmUtils
.isEmpty(name
.getAppendedPhrase()); //taxonFieldsEmpty();
455 isParsable
&= ! name
.isProtectedAuthorshipCache();
456 isParsable
&= ! name
.isProtectedNameCache();
463 * Parse the text and calculate errors
465 public void parseAndCalculateErrors(){
467 String unparsedNameString
= getNameViewer().getTextWidget().getText();
468 parseHandler
.parse(unparsedNameString
);
474 * <p>getTaxonBase</p>
476 * @return the taxonBase
478 public T
getTaxonBase() {
485 * @return a {@link eu.etaxonomy.cdm.model.name.TaxonNameBase} object.
487 public TaxonNameBase
getName(){
488 return (TaxonNameBase
) HibernateProxyHelper
.deproxy(getTaxonBase().getName());
494 public void persistName(){
496 getNameViewer().getTextWidget().setEnabled(false);
497 final String unparsedNameString
= getNameViewer().getTextWidget().getText();
498 // Job job = new Job("Persisting Name"){
501 // protected IStatus run(IProgressMonitor monitor) {
503 final NonViralName name
= parseHandler
.parseAndResolveDuplicates(unparsedNameString
);
505 // Display.getDefault().asyncExec(new Runnable(){
506 // public void run() {
507 getTaxonBase().setName(name
);
508 getTaxonBase().setTitleCache((getTaxonBase().generateTitle()));
510 getNameViewer().getTextWidget().setEnabled(true);
515 // return Status.OK_STATUS;
520 // job.setPriority(Job.DECORATE);
526 * <p>Getter for the field <code>group</code>.</p>
528 * @return a {@link eu.etaxonomy.taxeditor.editor.name.AbstractGroup} object.
530 public AbstractGroup
getGroup(){
537 public void remove(){
538 getGroup().remove(this);
542 * <p>createControl</p>
544 protected void createControl() {
545 control
= editor
.getToolkit().createComposite(group
.getControl());
547 control
.setLayoutData(new TableWrapData(TableWrapData
.FILL_GRAB
));
548 TableWrapLayout layout
= new TableWrapLayout();
549 layout
.leftMargin
= 0;
550 layout
.rightMargin
= 0;
551 layout
.topMargin
= 5;
552 layout
.bottomMargin
= 5;
554 layout
.verticalSpacing
= 0;
555 layout
.horizontalSpacing
= 0;
557 control
.setLayout(layout
);
562 * <p>Getter for the field <code>control</code>.</p>
564 * @return a {@link org.eclipse.swt.widgets.Composite} object.
566 public Composite
getControl(){
571 * <p>createLineWrapSupport</p>
573 protected void createLineWrapSupport() {
574 new LineWrapSupport(getNameViewer(), editor
.getManagedForm());
579 * <p>createTextViewer</p>
581 protected void createTextViewer() {
582 nameViewer
= new NameViewer(control
);
584 focusListener
= new FocusAdapter() {
585 public void focusGained(FocusEvent e
) {
586 for(AbstractGroupedContainer container
: editor
.getGroupedContainers()){
587 container
.colorSelected(NOT_SELECTED
);
589 editor
.getManagedForm().setInput(AbstractGroupedContainer
.this);
591 colorSelected(SELECTED_FOCUS
);
594 nameViewer
.getTextWidget().addFocusListener(focusListener
);
597 MouseAdapter mouseListener
= new MouseAdapter() {
598 public void mouseDown(MouseEvent e
) {
602 control
.addMouseListener(mouseListener
);
603 nameViewer
.getRulerControl().addMouseListener(mouseListener
);
604 nameViewer
.getTextWidget().addMouseListener(mouseListener
);
610 * @param icon a {@link org.eclipse.swt.graphics.Image} object.
612 public void setIcon(Image icon
) {
613 getNameViewer().setIcon(icon
);
619 * @param indent a int.
621 public void setIndent(int indent
) {
622 if (control
.getLayout() instanceof TableWrapLayout
) {
623 TableWrapLayout layout
= ((TableWrapLayout
) control
.getLayout());
624 layout
.leftMargin
= indent
;
625 layout
.rightMargin
= ACCEPTED_INDENT
;
626 control
.setLayout(layout
);
628 new RuntimeException("Couldn't indent - composite's layout must be TableWrapLayout.");
635 public void setSelected() {
636 getNameViewer().getTextWidget().setFocus();
644 public boolean isSelected(){
645 return editor
.getSelectedObject() == this;
649 * <p>colorSelected</p>
653 public void colorSelected(int mode
){
654 if(!control
.isDisposed()){
655 String colorString
= null;
659 colorString
= Resources
.COLOR_CONTROL_SELECTED_FOCUS
;
661 case SELECTED_NO_FOCUS
:
662 colorString
= Resources
.COLOR_CONTROL_SELECTED
;
665 colorString
= Resources
.COLOR_COMPOSITE_BACKGROUND
;
668 backgroundColor
= EditorUtil
.getColor(colorString
);
670 setBackground(backgroundColor
);
676 * <p>setDelayedSelection</p>
678 protected void setDelayedSelection(){
679 //TODO this might be done better
680 // this is the quickest solution i could come up with and it improves performance
681 // please reimplement if you know better.
685 Display display
= Display
.getCurrent();
686 Runnable runnable
= new Runnable() {
689 editor
.getManagedForm().setInput(selection
);
692 display
.timerExec(1000, runnable
);
697 * <p>setBackground</p>
699 * @param color a {@link org.eclipse.swt.graphics.Color} object.
701 public void setBackground(Color color
) {
702 control
.setBackground(color
);
704 for(Control child
: control
.getChildren()){
705 child
.setBackground(color
);
708 getNameViewer().setBackground(color
);
712 * @see org.eclipse.swt.widgets.Control#setFont(org.eclipse.swt.graphics.Font)
717 * @param font a {@link org.eclipse.swt.graphics.Font} object.
719 public void setFont(Font font
) {
720 getNameViewer().getTextWidget().setFont(font
);
724 * <p>Getter for the field <code>nameViewer</code>.</p>
726 * @return a {@link eu.etaxonomy.taxeditor.editor.name.NameViewer} object.
728 public NameViewer
getNameViewer() {
729 if (nameViewer
== null){
730 throw new RuntimeException("The Name Viewer is corrupt for Name Container: " + getTaxonBase().getName().getTitleCache());
736 * If <code>textViewer</code> has already been set, it will show a
737 * <code>prompt</code> along the lines of "Click here to start entering data"
740 * @param prompt a {@link java.lang.String} object.
742 public void createEmptyViewerPrompt(final String prompt
) {
744 Assert
.isNotNull(getNameViewer());
746 final StyledText textControl
= getNameViewer().getTextWidget();
747 final IDocument document
= getNameViewer().getDocument();
749 setFocusListener(new FocusListener() {
752 public void focusGained(FocusEvent e
) {
753 if (document
.get().equals(prompt
)) {
754 textControl
.setFont(getViewerFont());
760 public void focusLost(FocusEvent e
) {
761 if (document
.getLength() == 0) {
767 textControl
.addFocusListener(getFocusListener());
769 if (document
.getLength() == 0) {
770 textControl
.setFont(EditorUtil
.getFont(Resources
.FONT_DEFAULT_PROMPT
));
771 document
.set(prompt
);
776 * <p>getViewerFont</p>
778 * @return a {@link org.eclipse.swt.graphics.Font} object.
780 abstract protected Font
getViewerFont();
783 * <p>initEmptyText</p>
785 protected void initEmptyText() {
786 Font defaultFont
= EditorUtil
.getFont(Resources
.FONT_DEFAULT_PROMPT
);
787 getNameViewer().getTextWidget().setFont(defaultFont
);
789 getNameViewer().getDocument().set(getEmptyTextPrompt());
794 * <p>Setter for the field <code>focusListener</code>.</p>
796 * @param focusListener a {@link org.eclipse.swt.events.FocusListener} object.
798 protected void setFocusListener(FocusListener focusListener
) {
799 this.focusListener
= focusListener
;
802 private FocusListener
getFocusListener() {
803 return focusListener
;
809 * @param isDirty a boolean.
811 public void setDirty(boolean isDirty
) {
813 editor
.getManagedForm().dirtyStateChanged();
815 this.isDirty
= isDirty
;
823 public boolean isDirty(){
830 * @param menu a {@link org.eclipse.swt.widgets.Menu} object.
832 public void setMenu (Menu menu
) {
833 control
.setMenu(menu
);
835 getNameViewer().setMenu(menu
);
838 private Control
[] draggableControls
;
841 * <p>setDraggableControl</p>
843 * @param controls an array of {@link org.eclipse.swt.widgets.Control} objects.
845 protected void setDraggableControl(Control
[] controls
) {
846 draggableControls
= controls
;
850 * <p>setIsDraggable</p>
852 * @param draggable a boolean.
854 public void setIsDraggable(boolean draggable
) {
858 if (draggableControls
== null) {
859 throw new NullPointerException(
860 "Draggable controls must be set to add draggability");
863 Transfer
[] types
= new Transfer
[] { CdmDataTransfer
.getInstance() };
864 int operations
= DND
.DROP_MOVE
;
866 for(Control draggableControl
: draggableControls
){
867 DragSource dragSource
= new DragSource(draggableControl
, operations
);
868 dragSource
.setTransfer(types
);
870 dragSource
.addDragListener(new NameEditorDragListener(this));
871 dragSource
.setDragSourceEffect(new NameEditorDragSourceEffect(control
));
876 private String nonEditableText
;
878 ControlListener nonEditableResizeListener
= new ControlAdapter() {
882 public void controlResized(ControlEvent e
) {
883 if (nonEditableInfoLabel
.getBounds().width
== width
) {
886 width
= nonEditableInfoLabel
.getBounds().width
;
887 if (nonEditableInfoLabel
.getBounds().width
> 0) {
888 nonEditableInfoLabel
.setText(
889 Dialog
.shortenText(nonEditableText
.toUpperCase(),
890 nonEditableInfoLabel
));
895 private String nonEditableHoverText
;
897 private LabelEllipsisListener nonEditableLabelEllipsisListener
;
902 * nonEditableInfo is a label displayed underneath a GroupedComposite's
903 * input field. For instance, NameComposites display things like name relations,
904 * sec. references, etc. here.
906 * @param info the text to display in the label
907 * @param append whether the string should be appended to text that is already shown in the label
909 public void setNonEditableInfo(String info
, boolean append
) {
910 // TODO non editable info should only be drawn once, when everything else is drawn
911 info
= info
.toUpperCase();
914 nonEditableText
+= ", " + info
;
915 nonEditableHoverText
+= "\n" + info
;
917 nonEditableText
= info
;
918 nonEditableHoverText
= info
;
921 if (nonEditableInfoLabel
== null) {
922 nonEditableInfoLabel
= editor
.getToolkit().createLabel(control
, "");
923 TableWrapData layoutData
= new TableWrapData(TableWrapData
.FILL_GRAB
, TableWrapData
.TOP
);
924 // Set indent to viewer ruler's width
925 if (getNameViewer().getRulerControl() != null) {
926 // TODO right justify
927 layoutData
.indent
= NameViewer
.RULER_WIDTH
;
929 nonEditableInfoLabel
.setLayoutData(layoutData
);
933 nonEditableLabelEllipsisListener
= new LabelEllipsisListener(nonEditableInfoLabel
) {
935 public String
getLabelText() {
936 return nonEditableText
.toUpperCase();
939 nonEditableInfoLabel
.addControlListener(nonEditableLabelEllipsisListener
);
941 nonEditableInfoHover
= new DefaultToolTip(nonEditableInfoLabel
);
942 nonEditableInfoHover
.setRespectDisplayBounds(true);
945 nonEditableInfoHover
.setText(nonEditableHoverText
);
946 nonEditableInfoLabel
.setText(nonEditableText
);
950 * <p>Getter for the field <code>data</code>.</p>
952 * @return a T object.
959 * <p>Setter for the field <code>data</code>.</p>
961 * @param data a T object.
963 public void setData(T data
){
964 this.data
= (T
) HibernateProxyHelper
.deproxy(data
);
968 * If the user hitting carriage return should cause something to happen -
969 * i.e. the creation of a new composite - call this method and override
970 * the method handleSplitText().
972 protected void createLineBreakListener() {
973 lineBreakListener
= new LineBreakListener() {
975 public void handleSplitText(String text
) {
976 AbstractGroupedContainer
.this.handleSplitText(text
);
980 getNameViewer().getTextWidget().addVerifyListener(lineBreakListener
);
981 getNameViewer().getTextWidget().addKeyListener(lineBreakListener
);
984 abstract class LabelEllipsisListener
extends ControlAdapter
{
989 LabelEllipsisListener(Label label
) {
993 abstract public String
getLabelText();
995 public void controlResized(ControlEvent e
) {
996 if (label
.getBounds().width
== width
) {
999 width
= label
.getBounds().width
;
1000 if (label
.getBounds().width
> 0) {
1001 label
.setText(TextHelper
.shortenText(getLabelText(), label
));
1007 * <p>storeCursor</p>
1009 public void storeCursor() {
1010 this.cursorPosition
= getNameViewer().getCursorPosition();
1014 * Puts the cursor to the position it was last seen on or to the end of line
1015 * if no former position is known.
1017 public void placeCursor(){
1018 if(cursorPosition
== 0){
1019 getNameViewer().setCursorToEOL();
1021 getNameViewer().setCursorPosition(cursorPosition
);
1028 * <p>Setter for the field <code>group</code>.</p>
1030 * @param group a {@link eu.etaxonomy.taxeditor.editor.name.AbstractGroup} object.
1032 public void setGroup(AbstractGroup
<T
> group
) {
1039 * <p>restoreColor</p>
1041 public void restoreColor() {
1042 setBackground(backgroundColor
);
1048 * @see org.eclipse.ui.forms.IFormPart#initialize(org.eclipse.ui.forms.IManagedForm)
1051 public void initialize(IManagedForm form
) {
1052 // TODO Auto-generated method stub
1058 * @see org.eclipse.ui.forms.IFormPart#dispose()
1061 public void dispose() {
1062 // TODO Auto-generated method stub
1068 * @see org.eclipse.ui.forms.IFormPart#commit(boolean)
1071 public void commit(boolean onSave
) {
1079 * @see org.eclipse.ui.forms.IFormPart#setFormInput(java.lang.Object)
1082 public boolean setFormInput(Object input
) {
1083 // TODO Auto-generated method stub
1089 * @see org.eclipse.ui.forms.IFormPart#setFocus()
1092 public void setFocus() {
1093 getNameViewer().getControl().setFocus();
1098 * @see org.eclipse.ui.forms.IFormPart#isStale()
1101 public boolean isStale() {
1102 // TODO Auto-generated method stub