Checkin before attempting to put each "save taxon" in its own transaction.
[taxeditor.git] / eclipseprojects / eu.etaxonomy.taxeditor / src / eu / etaxonomy / taxeditor / editor / GroupedComposite.java
1 package eu.etaxonomy.taxeditor.editor;
2
3 import org.eclipse.swt.SWT;
4 import org.eclipse.swt.dnd.DND;
5 import org.eclipse.swt.dnd.DragSource;
6 import org.eclipse.swt.dnd.DragSourceAdapter;
7 import org.eclipse.swt.dnd.DragSourceEvent;
8 import org.eclipse.swt.dnd.DragSourceListener;
9 import org.eclipse.swt.dnd.Transfer;
10 import org.eclipse.swt.widgets.Composite;
11 import org.eclipse.swt.widgets.Control;
12
13 import eu.etaxonomy.taxeditor.actions.WidgetTransfer;
14
15 /**
16 * A composite which can be dragged between different EditorGroupComposite. The user
17 * uses the draggable control for dragging the whole composite.
18 *
19 * @see eu.etaxonomy.taxeditor.editor.EditorGroupComposite
20 *
21 * @author p.ciardelli
22 *
23 */
24 abstract public class GroupedComposite extends Composite {
25
26 IParentDataAdapter parentDataAdapter;
27 private Control draggableControl;
28
29 public GroupedComposite(Composite parent) {
30 super(parent, SWT.NONE);
31
32 createContent();
33 }
34
35 abstract protected void createContent();
36
37 protected void setDraggableControl(Control control) {
38 draggableControl = control;
39 }
40
41 public void setDraggable(boolean draggable) {
42
43 if (draggable) {
44
45 if (dragger != null) {
46 // Already initalized
47 return;
48 }
49
50 if (draggableControl == null) {
51 throw new NullPointerException(
52 "Draggable control must be set to add draggability");
53 }
54
55 Transfer[] types = new Transfer[] { WidgetTransfer.getInstance() };
56 int operations = DND.DROP_MOVE | DND.DROP_COPY | DND.DROP_LINK;
57
58 dragger = new DragSource(draggableControl, operations);
59 dragger.setTransfer(types);
60 dragger.addDragListener(dragSourceListener);
61
62 } else {
63 dragger = null;
64 }
65 }
66
67 /**
68 * Drag listener which passes the Composite as the data in a drag event.
69 */
70 DragSourceListener dragSourceListener = new DragSourceAdapter() {
71
72 public void dragStart(DragSourceEvent event) {
73 GroupedComposite.this.setFocus();
74 event.doit = true;
75 }
76
77 public void dragSetData(DragSourceEvent event) {
78 WidgetTransfer.getInstance().setWidget(GroupedComposite.this);
79 }
80 };
81 private DragSource dragger;
82
83 /**
84 * Override of setParent: dispose of parent if this is its last child
85 * composite
86 *
87 * @see org.eclipse.swt.widgets.Control#setParent(org.eclipse.swt.widgets.Composite)
88 */
89 public boolean setParent(Composite parent) {
90
91 Composite oldParent = this.getParent();
92 Composite oldGrandparent = oldParent.getParent();
93
94 if (super.setParent(parent)) {
95 if (oldParent instanceof EditorGroupComposite
96 && oldParent.getChildren().length == 0) {
97 oldParent.dispose();
98 }
99 adaptParentData();
100
101 // Redraw the component holding the group and grouped composites
102 parent.getParent().layout();
103
104 // In case we are dragging between different views, redraw the
105 // "old" view
106 if (!oldGrandparent.equals(parent.getParent())) {
107 oldGrandparent.layout();
108 }
109
110 return true;
111 }
112 return false;
113 }
114
115 public void dispose () {
116 Composite parent = this.getParent();
117 Composite grandParent = null;
118 if (parent != null) {
119 grandParent = parent.getParent();
120 }
121 super.dispose();
122 if (parent instanceof Composite
123 && parent.getChildren().length == 0) {
124 parent.dispose();
125 }
126
127 // Redraw the component holding the group and grouped composites
128 if (grandParent != null) {
129 grandParent.layout();
130 }
131 }
132
133 /**
134 * A grouped composite is usually grouped according to data held by its
135 * parent. When the composite changes parents, this method gets called to
136 * update data as needed.
137 */
138 protected void adaptParentData() {
139 if (parentDataAdapter != null) {
140 parentDataAdapter.adaptParentData();
141 }
142 }
143
144 public void setParentDataAdapter(IParentDataAdapter parentDataAdapter) {
145 this.parentDataAdapter = parentDataAdapter;
146 }
147 }