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>HOMOTYPIC_SYNONYM_IN_HETEROTYPIC_GROUP_INDENT = 60</code> */
120 public static final int HOMOTYPIC_SYNONYM_IN_HETEROTYPIC_GROUP_INDENT
= 60;
121 /** Constant <code>MISAPPLIEDNAME_INDENT=40</code> */
122 public static final int MISAPPLIEDNAME_INDENT
= 40;
123 /** Constant <code>CONCEPT_INDENT=40</code> */
124 public static final int CONCEPT_INDENT
= 40;
128 * ************ ICONS ************
130 public static final Image ACCEPTED_ICON
= ImageResources
.getImage(ImageResources
.BLACK_SQUARE_ICON
);
131 /** Constant <code>HOMOTYPIC_SYNONYM_ICON</code> */
132 public static final Image HOMOTYPIC_SYNONYM_ICON
= ImageResources
.getImage(ImageResources
.HOMOTYPIC_SYN_ICON
);
133 /** Constant <code>HOMOTYPIC_SYNONYM_ORIGINAL_COMBINATION_ICON</code> */
134 public static final Image HOMOTYPIC_SYNONYM_ORIGINAL_COMBINATION_ICON
= ImageResources
.getImage(
135 ImageResources
.HOMOTYPIC_SYN_ORIGINAL_ICON
);
136 /** Constant <code>HETEROTYPIC_SYNONYM_ICON</code> */
137 public static final Image HETEROTYPIC_SYNONYM_ICON
= ImageResources
.getImage(ImageResources
.HETEROTYPIC_SYN_ICON
);
138 public static final Image HOMOTYPIC_SYNONYM_IN_HETEROTYPIC_GROUP_ICON
= ImageResources
.getImage(ImageResources
.HOMOTYPIC_SYNONYM_IN_HETEROTYPIC_GROUP_ICON
);
139 public static final Image INVALID_OR_NUDUM_NAME_ICON
= ImageResources
.getImage(ImageResources
.NOM_INVAL_NUD_SYN_ICON
);
140 /** Constant <code>HETEROTYPIC_SYNONYM_ORIGINAL_COMBINATION_ICON</code> */
141 public static final Image HETEROTYPIC_SYNONYM_ORIGINAL_COMBINATION_ICON
= ImageResources
.getImage(
142 ImageResources
.HETEROTYPIC_SYN_ORIGINAL_ICON
);
143 /** Constant <code>MISAPPLIEDNAME_ICON</code> */
144 public static final Image MISAPPLIEDNAME_ICON
= ImageResources
.getImage(ImageResources
.MISAPPLIED_NAME_ICON
);
145 /** Constant <code>CONCEPT_ICON</code> */
146 public static final Image CONCEPT_ICON
= ImageResources
.getImage(ImageResources
.CONCEPT_ICON
);
147 /** Constant <code>AUTONYM_ICON</code> */
148 public static final Image AUTONYM_ICON
= ImageResources
149 .getImage(ImageResources
.AUTONYM_ICON
);
150 /** Constant <code>MOVE</code> */
151 public static final Image MOVE
= ImageResources
.getImage(ImageResources
.MOVE_ICON
);
154 * ************ TRANSFORMATIONS ************
156 public static final String ADD_GROUP_BASIONYM
= "add_group_basionym";
157 /** Constant <code>REMOVE_GROUP_BASIONYM="remove_group_basionym"</code> */
158 public static final String REMOVE_GROUP_BASIONYM
= "remove_group_basionym";
160 private static final String EMPTY_NAME_PROMPT
= "Click to add name";
162 protected ParseHandler parseHandler
;
164 private FocusListener nameCompositeFocusListener
;
165 private ModifyListener nameCompositeModifyListener
;
168 protected TaxonNameEditor editor
;
170 protected NameViewer nameViewer
;
172 private AbstractGroup
<T
> group
;
174 private Label nonEditableInfoLabel
;
175 private DefaultToolTip nonEditableInfoHover
;
177 private static AbstractGroupedContainer selection
;
179 private FocusListener focusListener
;
180 private LineBreakListener lineBreakListener
;
182 private int cursorPosition
;
184 protected Composite control
;
186 private Color backgroundColor
;
187 private boolean isDirty
;
191 * <p>Constructor for AbstractGroupedContainer.</p>
193 * @param editor a {@link eu.etaxonomy.taxeditor.editor.name.TaxonNameEditor} object.
194 * @param group a {@link eu.etaxonomy.taxeditor.editor.name.AbstractGroup} object.
195 * @param taxonBase a T object.
196 * @param <T> a T object.
198 public AbstractGroupedContainer(TaxonNameEditor editor
, AbstractGroup
<T
> group
, T taxonBase
){
199 this.editor
= editor
;
209 createLineWrapSupport();
210 createLineBreakListener();
212 setMenu(editor
.getMenu());
214 setDraggableControl(new Control
[]{getControl(), getNameViewer().getRulerControl()});
216 createEmptyViewerPrompt(EMPTY_NAME_PROMPT
);
218 parseHandler
= ParseHandler
.NewInstance(getNameViewer().getTextWidget(), taxonBase
.getName());
220 initializeComposite();
230 * <p>createListener</p>
232 protected void createListener(){
233 nameCompositeModifyListener
= new ModifyListener(){
235 public void modifyText(ModifyEvent e
) {
236 // mark the composite dirty
239 String text
= nameViewer
.getTextWidget().getText();
241 NonViralName name
= parseHandler
.parse(text
);
242 getTaxonBase().setName(name
);
243 getTaxonBase().setTitleCache((getTaxonBase().generateTitle()));
245 // show errors resulting from parsing
247 // store the position of the cursor
249 // notify selection listener
250 setDelayedSelection();
253 nameCompositeFocusListener
= new FocusAdapter(){
256 * @see org.eclipse.swt.events.FocusAdapter#focusLost(org.eclipse.swt.events.FocusEvent)
259 public void focusLost(FocusEvent e
) {
269 private void addListener(){
270 getNameViewer().getTextWidget().addModifyListener(nameCompositeModifyListener
);
271 getNameViewer().getTextWidget().addFocusListener(nameCompositeFocusListener
);
274 private void removeListener(){
275 getNameViewer().getTextWidget().removeModifyListener(nameCompositeModifyListener
);
276 getNameViewer().getTextWidget().removeFocusListener(nameCompositeFocusListener
);
280 * Initialize the composite specific code
282 protected abstract void initializeComposite();
285 * <p>getEmptyTextPrompt</p>
287 * @return a {@link java.lang.String} object.
289 protected String
getEmptyTextPrompt() {
290 return EMPTY_NAME_PROMPT
;
296 private void showNameRelations() {
297 TaxonNameBase
<?
, ?
> name
= getName();
302 ILabelImageStrategy strategy
= LabelImageProvider
.getLabelStrategy(name
);
303 LabelImageProvider labelProvider
= new LabelImageProvider(strategy
);
305 Set
<NameRelationship
> nameRelations
= name
.getNameRelations();
306 if (nameRelations
.size() == 0) {
309 // for (NameRelationship nameRelation : nameRelations) {
310 // String typeLabel = null;
311 // TaxonNameBase<?, ?> relatedName = null;
313 // if (name.equals(nameRelation.getFromName())) {
314 // typeLabel = labelProvider.getNameRelationTypeLabel(
315 // nameRelation.getType());
316 // relatedName = nameRelation.getToName();
318 // typeLabel = labelProvider.getNameRelationTypeInverseLabel(
319 // nameRelation.getType());
320 // relatedName = nameRelation.getFromName();
323 // setNonEditableInfo(typeLabel + " " + NameHelper.getDisplayName(relatedName));
328 * <p>initTextViewer</p>
330 protected void initTextViewer() {
332 // showNameRelations();
338 String text
= NameHelper
.getDisplayNameWithRef(getData());
340 if (text
.length() == 0) {
343 getNameViewer().setText(text
);
350 * <p>calculateErrors</p>
352 synchronized protected void calculateErrors() {
353 getNameViewer().clearErrors();
354 getNameViewer().setShowParsingErrors(getName());
358 * <p>handleSplitText</p>
360 * @param text a {@link java.lang.String} object.
362 protected void handleSplitText(String text
) {
363 // Create a synonym in a new homotypic group using text as name
364 TaxonNameBase synonymName
= ParseHandler
.quickParse(text
);
366 EditorUtil
.executeOperation(new CreateSynonymInNewGroupOperation
367 ("New Heterotypic Synonym", editor
.getUndoContext(), editor
.getTaxon(), synonymName
, editor
));
371 * Refreshes the display with latest data from the model.
373 * Note: Will not parse the text and not calculate errors!
375 public void refresh() {
376 // showNameRelations();
378 String text
= NameHelper
.getDisplayNameWithRef(getTaxonBase());
380 if (text
.length() == 0) {
384 getNameViewer().getTextWidget().setText(text
);
388 updateNonEditableInfo();
400 protected abstract void updateIcon();
403 protected abstract void updateIndent();
407 * <p>updateNonEditableInfo</p>
409 protected abstract void updateNonEditableInfo();
414 private void isFreeTextEnabled() {
415 // Decide whether editing of freetext is allowed or not.
416 if (freetextEditingAllowed()) {
419 getNameViewer().getTextWidget().setEditable(true);
421 // restore foreground font color again
422 getNameViewer().getTextWidget().setForeground(control
.getForeground());
425 getNameViewer().getTextWidget().setEditable(false);
427 // grey out text as a non-editable indicator
428 getNameViewer().getTextWidget().setForeground(EditorUtil
.getColor(Resources
.COLOR_DISABLED_EDITOR
));
434 * Checks whether the freetext should be editable based on specific empty fields.
437 private boolean freetextEditingAllowed() {
438 NonViralName name
= (NonViralName
) HibernateProxyHelper
.deproxy(getName());
439 boolean enableFreetext
= true;
441 enableFreetext
&= isNameUsedMultipleTimes(name
);
442 enableFreetext
&= isNameParsable(name
);
445 getNameViewer().setShowNameNotParsableWarning(name
);
448 return enableFreetext
;
451 private boolean isNameUsedMultipleTimes(NonViralName name
){
452 if(name
.getTaxonBases().size() != 1){
453 getNameViewer().setShowMultipleNameUsageWarning(name
);
459 private boolean isNameParsable(NonViralName name
){
460 boolean isParsable
= true;
461 isParsable
&= CdmUtils
.isEmpty(name
.getAppendedPhrase()); //taxonFieldsEmpty();
463 isParsable
&= ! name
.isProtectedAuthorshipCache();
464 isParsable
&= ! name
.isProtectedNameCache();
471 * Parse the text and calculate errors
473 public void parseAndCalculateErrors(){
475 String unparsedNameString
= getNameViewer().getTextWidget().getText();
476 parseHandler
.parse(unparsedNameString
);
482 * <p>getTaxonBase</p>
484 * @return the taxonBase
486 public T
getTaxonBase() {
493 * @return a {@link eu.etaxonomy.cdm.model.name.TaxonNameBase} object.
495 public TaxonNameBase
getName(){
496 return (TaxonNameBase
) HibernateProxyHelper
.deproxy(getTaxonBase().getName());
502 public void persistName(){
504 getNameViewer().getTextWidget().setEnabled(false);
505 final String unparsedNameString
= getNameViewer().getTextWidget().getText();
506 // Job job = new Job("Persisting Name"){
509 // protected IStatus run(IProgressMonitor monitor) {
511 final NonViralName name
= parseHandler
.parseAndResolveDuplicates(unparsedNameString
);
513 // Display.getDefault().asyncExec(new Runnable(){
514 // public void run() {
515 getTaxonBase().setName(name
);
516 getTaxonBase().setTitleCache((getTaxonBase().generateTitle()));
518 getNameViewer().getTextWidget().setEnabled(true);
523 // return Status.OK_STATUS;
528 // job.setPriority(Job.DECORATE);
534 * <p>Getter for the field <code>group</code>.</p>
536 * @return a {@link eu.etaxonomy.taxeditor.editor.name.AbstractGroup} object.
538 public AbstractGroup
getGroup(){
545 public void remove(){
546 getGroup().remove(this);
550 * <p>createControl</p>
552 protected void createControl() {
553 control
= editor
.getToolkit().createComposite(group
.getControl());
555 control
.setLayoutData(new TableWrapData(TableWrapData
.FILL_GRAB
));
556 TableWrapLayout layout
= new TableWrapLayout();
557 layout
.leftMargin
= 0;
558 layout
.rightMargin
= 0;
559 layout
.topMargin
= 5;
560 layout
.bottomMargin
= 5;
562 layout
.verticalSpacing
= 0;
563 layout
.horizontalSpacing
= 0;
565 control
.setLayout(layout
);
570 * <p>Getter for the field <code>control</code>.</p>
572 * @return a {@link org.eclipse.swt.widgets.Composite} object.
574 public Composite
getControl(){
579 * <p>createLineWrapSupport</p>
581 protected void createLineWrapSupport() {
582 new LineWrapSupport(getNameViewer(), editor
.getManagedForm());
587 * <p>createTextViewer</p>
589 protected void createTextViewer() {
590 nameViewer
= new NameViewer(control
);
592 focusListener
= new FocusAdapter() {
593 public void focusGained(FocusEvent e
) {
594 for(AbstractGroupedContainer container
: editor
.getGroupedContainers()){
595 container
.colorSelected(NOT_SELECTED
);
597 editor
.getManagedForm().setInput(AbstractGroupedContainer
.this);
599 colorSelected(SELECTED_FOCUS
);
602 nameViewer
.getTextWidget().addFocusListener(focusListener
);
605 MouseAdapter mouseListener
= new MouseAdapter() {
606 public void mouseDown(MouseEvent e
) {
610 control
.addMouseListener(mouseListener
);
611 nameViewer
.getRulerControl().addMouseListener(mouseListener
);
612 nameViewer
.getTextWidget().addMouseListener(mouseListener
);
618 * @param icon a {@link org.eclipse.swt.graphics.Image} object.
620 public void setIcon(Image icon
) {
621 getNameViewer().setIcon(icon
);
627 * @param indent a int.
629 public void setIndent(int indent
) {
630 if (control
.getLayout() instanceof TableWrapLayout
) {
631 TableWrapLayout layout
= ((TableWrapLayout
) control
.getLayout());
632 layout
.leftMargin
= indent
;
633 layout
.rightMargin
= ACCEPTED_INDENT
;
634 control
.setLayout(layout
);
637 new RuntimeException("Couldn't indent - composite's layout must be TableWrapLayout.");
644 public void setSelected() {
645 getNameViewer().getTextWidget().setFocus();
653 public boolean isSelected(){
654 return editor
.getSelectedObject() == this;
658 * <p>colorSelected</p>
662 public void colorSelected(int mode
){
663 if(!control
.isDisposed()){
664 String colorString
= null;
668 colorString
= Resources
.COLOR_CONTROL_SELECTED_FOCUS
;
670 case SELECTED_NO_FOCUS
:
671 colorString
= Resources
.COLOR_CONTROL_SELECTED
;
674 colorString
= Resources
.COLOR_COMPOSITE_BACKGROUND
;
677 backgroundColor
= EditorUtil
.getColor(colorString
);
679 setBackground(backgroundColor
);
685 * <p>setDelayedSelection</p>
687 protected void setDelayedSelection(){
688 //TODO this might be done better
689 // this is the quickest solution i could come up with and it improves performance
690 // please reimplement if you know better.
694 Display display
= Display
.getCurrent();
695 Runnable runnable
= new Runnable() {
698 editor
.getManagedForm().setInput(selection
);
701 display
.timerExec(1000, runnable
);
706 * <p>setBackground</p>
708 * @param color a {@link org.eclipse.swt.graphics.Color} object.
710 public void setBackground(Color color
) {
711 control
.setBackground(color
);
713 for(Control child
: control
.getChildren()){
714 child
.setBackground(color
);
717 getNameViewer().setBackground(color
);
721 * @see org.eclipse.swt.widgets.Control#setFont(org.eclipse.swt.graphics.Font)
726 * @param font a {@link org.eclipse.swt.graphics.Font} object.
728 public void setFont(Font font
) {
729 getNameViewer().getTextWidget().setFont(font
);
733 * <p>Getter for the field <code>nameViewer</code>.</p>
735 * @return a {@link eu.etaxonomy.taxeditor.editor.name.NameViewer} object.
737 public NameViewer
getNameViewer() {
738 if (nameViewer
== null){
739 throw new RuntimeException("The Name Viewer is corrupt for Name Container: " + getTaxonBase().getName().getTitleCache());
745 * If <code>textViewer</code> has already been set, it will show a
746 * <code>prompt</code> along the lines of "Click here to start entering data"
749 * @param prompt a {@link java.lang.String} object.
751 public void createEmptyViewerPrompt(final String prompt
) {
753 Assert
.isNotNull(getNameViewer());
755 final StyledText textControl
= getNameViewer().getTextWidget();
756 final IDocument document
= getNameViewer().getDocument();
758 setFocusListener(new FocusListener() {
761 public void focusGained(FocusEvent e
) {
762 if (document
.get().equals(prompt
)) {
763 textControl
.setFont(getViewerFont());
769 public void focusLost(FocusEvent e
) {
770 if (document
.getLength() == 0) {
776 textControl
.addFocusListener(getFocusListener());
778 if (document
.getLength() == 0) {
779 textControl
.setFont(EditorUtil
.getFont(Resources
.FONT_DEFAULT_PROMPT
));
780 document
.set(prompt
);
785 * <p>getViewerFont</p>
787 * @return a {@link org.eclipse.swt.graphics.Font} object.
789 abstract protected Font
getViewerFont();
792 * <p>initEmptyText</p>
794 protected void initEmptyText() {
795 Font defaultFont
= EditorUtil
.getFont(Resources
.FONT_DEFAULT_PROMPT
);
796 getNameViewer().getTextWidget().setFont(defaultFont
);
798 getNameViewer().getDocument().set(getEmptyTextPrompt());
803 * <p>Setter for the field <code>focusListener</code>.</p>
805 * @param focusListener a {@link org.eclipse.swt.events.FocusListener} object.
807 protected void setFocusListener(FocusListener focusListener
) {
808 this.focusListener
= focusListener
;
811 private FocusListener
getFocusListener() {
812 return focusListener
;
818 * @param isDirty a boolean.
820 public void setDirty(boolean isDirty
) {
822 editor
.getManagedForm().dirtyStateChanged();
824 this.isDirty
= isDirty
;
832 public boolean isDirty(){
839 * @param menu a {@link org.eclipse.swt.widgets.Menu} object.
841 public void setMenu (Menu menu
) {
842 control
.setMenu(menu
);
844 getNameViewer().setMenu(menu
);
847 private Control
[] draggableControls
;
850 * <p>setDraggableControl</p>
852 * @param controls an array of {@link org.eclipse.swt.widgets.Control} objects.
854 protected void setDraggableControl(Control
[] controls
) {
855 draggableControls
= controls
;
859 * <p>setIsDraggable</p>
861 * @param draggable a boolean.
863 public void setIsDraggable(boolean draggable
) {
867 if (draggableControls
== null) {
868 throw new NullPointerException(
869 "Draggable controls must be set to add draggability");
872 Transfer
[] types
= new Transfer
[] { CdmDataTransfer
.getInstance() };
873 int operations
= DND
.DROP_MOVE
;
875 for(Control draggableControl
: draggableControls
){
876 DragSource dragSource
= new DragSource(draggableControl
, operations
);
877 dragSource
.setTransfer(types
);
879 dragSource
.addDragListener(new NameEditorDragListener(this));
880 dragSource
.setDragSourceEffect(new NameEditorDragSourceEffect(control
));
885 private String nonEditableText
;
887 ControlListener nonEditableResizeListener
= new ControlAdapter() {
891 public void controlResized(ControlEvent e
) {
892 if (nonEditableInfoLabel
.getBounds().width
== width
) {
895 width
= nonEditableInfoLabel
.getBounds().width
;
896 if (nonEditableInfoLabel
.getBounds().width
> 0) {
897 nonEditableInfoLabel
.setText(
898 Dialog
.shortenText(nonEditableText
.toUpperCase(),
899 nonEditableInfoLabel
));
904 private String nonEditableHoverText
;
906 private LabelEllipsisListener nonEditableLabelEllipsisListener
;
911 * nonEditableInfo is a label displayed underneath a GroupedComposite's
912 * input field. For instance, NameComposites display things like name relations,
913 * sec. references, etc. here.
915 * @param info the text to display in the label
916 * @param append whether the string should be appended to text that is already shown in the label
918 public void setNonEditableInfo(String info
, boolean append
) {
919 // TODO non editable info should only be drawn once, when everything else is drawn
920 info
= info
.toUpperCase();
923 nonEditableText
+= ", " + info
;
924 nonEditableHoverText
+= "\n" + info
;
926 nonEditableText
= info
;
927 nonEditableHoverText
= info
;
930 if (nonEditableInfoLabel
== null) {
931 nonEditableInfoLabel
= editor
.getToolkit().createLabel(control
, "");
932 TableWrapData layoutData
= new TableWrapData(TableWrapData
.FILL_GRAB
, TableWrapData
.TOP
);
933 // Set indent to viewer ruler's width
934 if (getNameViewer().getRulerControl() != null) {
935 // TODO right justify
936 layoutData
.indent
= NameViewer
.RULER_WIDTH
;
938 nonEditableInfoLabel
.setLayoutData(layoutData
);
942 nonEditableLabelEllipsisListener
= new LabelEllipsisListener(nonEditableInfoLabel
) {
944 public String
getLabelText() {
945 return nonEditableText
.toUpperCase();
948 nonEditableInfoLabel
.addControlListener(nonEditableLabelEllipsisListener
);
950 nonEditableInfoHover
= new DefaultToolTip(nonEditableInfoLabel
);
951 nonEditableInfoHover
.setRespectDisplayBounds(true);
954 nonEditableInfoHover
.setText(nonEditableHoverText
);
955 nonEditableInfoLabel
.setText(nonEditableText
);
959 * <p>Getter for the field <code>data</code>.</p>
961 * @return a T object.
968 * <p>Setter for the field <code>data</code>.</p>
970 * @param data a T object.
972 public void setData(T data
){
973 this.data
= (T
) HibernateProxyHelper
.deproxy(data
);
977 * If the user hitting carriage return should cause something to happen -
978 * i.e. the creation of a new composite - call this method and override
979 * the method handleSplitText().
981 protected void createLineBreakListener() {
982 lineBreakListener
= new LineBreakListener() {
984 public void handleSplitText(String text
) {
985 AbstractGroupedContainer
.this.handleSplitText(text
);
989 getNameViewer().getTextWidget().addVerifyListener(lineBreakListener
);
990 getNameViewer().getTextWidget().addKeyListener(lineBreakListener
);
993 abstract class LabelEllipsisListener
extends ControlAdapter
{
998 LabelEllipsisListener(Label label
) {
1002 abstract public String
getLabelText();
1004 public void controlResized(ControlEvent e
) {
1005 if (label
.getBounds().width
== width
) {
1008 width
= label
.getBounds().width
;
1009 if (label
.getBounds().width
> 0) {
1010 label
.setText(TextHelper
.shortenText(getLabelText(), label
));
1016 * <p>storeCursor</p>
1018 public void storeCursor() {
1019 this.cursorPosition
= getNameViewer().getCursorPosition();
1023 * Puts the cursor to the position it was last seen on or to the end of line
1024 * if no former position is known.
1026 public void placeCursor(){
1027 if(cursorPosition
== 0){
1028 getNameViewer().setCursorToEOL();
1030 getNameViewer().setCursorPosition(cursorPosition
);
1037 * <p>Setter for the field <code>group</code>.</p>
1039 * @param group a {@link eu.etaxonomy.taxeditor.editor.name.AbstractGroup} object.
1041 public void setGroup(AbstractGroup
<T
> group
) {
1048 * <p>restoreColor</p>
1050 public void restoreColor() {
1051 setBackground(backgroundColor
);
1057 * @see org.eclipse.ui.forms.IFormPart#initialize(org.eclipse.ui.forms.IManagedForm)
1060 public void initialize(IManagedForm form
) {
1061 // TODO Auto-generated method stub
1067 * @see org.eclipse.ui.forms.IFormPart#dispose()
1070 public void dispose() {
1071 // TODO Auto-generated method stub
1077 * @see org.eclipse.ui.forms.IFormPart#commit(boolean)
1080 public void commit(boolean onSave
) {
1088 * @see org.eclipse.ui.forms.IFormPart#setFormInput(java.lang.Object)
1091 public boolean setFormInput(Object input
) {
1092 // TODO Auto-generated method stub
1098 * @see org.eclipse.ui.forms.IFormPart#setFocus()
1101 public void setFocus() {
1102 getNameViewer().getControl().setFocus();
1107 * @see org.eclipse.ui.forms.IFormPart#isStale()
1110 public boolean isStale() {
1111 // TODO Auto-generated method stub