0fcfaecf9079705c4c23430b4601a5aab5c1de14
[taxeditor.git] / eu.etaxonomy.taxeditor.store / src / main / java / eu / etaxonomy / taxeditor / featuretree / EditFeatureTreeWizardPage.java
1 /**
2 * Copyright (C) 2007 EDIT
3 * European Distributed Institute of Taxonomy
4 * http://www.e-taxonomy.eu
5 *
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.
8 */
9
10 package eu.etaxonomy.taxeditor.featuretree;
11
12 import java.util.Collection;
13
14 import org.eclipse.core.runtime.IStatus;
15 import org.eclipse.jface.viewers.ISelectionChangedListener;
16 import org.eclipse.jface.viewers.IStructuredSelection;
17 import org.eclipse.jface.viewers.SelectionChangedEvent;
18 import org.eclipse.jface.viewers.TreeViewer;
19 import org.eclipse.jface.viewers.Viewer;
20 import org.eclipse.jface.viewers.ViewerDropAdapter;
21 import org.eclipse.jface.wizard.WizardDialog;
22 import org.eclipse.jface.wizard.WizardPage;
23 import org.eclipse.swt.SWT;
24 import org.eclipse.swt.dnd.DND;
25 import org.eclipse.swt.dnd.DragSourceAdapter;
26 import org.eclipse.swt.dnd.DragSourceEvent;
27 import org.eclipse.swt.dnd.Transfer;
28 import org.eclipse.swt.dnd.TransferData;
29 import org.eclipse.swt.events.ModifyEvent;
30 import org.eclipse.swt.events.ModifyListener;
31 import org.eclipse.swt.events.SelectionAdapter;
32 import org.eclipse.swt.events.SelectionEvent;
33 import org.eclipse.swt.layout.GridData;
34 import org.eclipse.swt.layout.GridLayout;
35 import org.eclipse.swt.widgets.Button;
36 import org.eclipse.swt.widgets.Composite;
37 import org.eclipse.swt.widgets.Label;
38 import org.eclipse.swt.widgets.Text;
39 import org.hibernate.proxy.HibernateProxy;
40
41 import eu.etaxonomy.cdm.api.service.IFeatureNodeService;
42 import eu.etaxonomy.cdm.api.service.config.FeatureNodeDeletionConfigurator;
43 import eu.etaxonomy.cdm.hibernate.HibernateProxyHelper;
44 import eu.etaxonomy.cdm.model.description.Feature;
45 import eu.etaxonomy.cdm.model.description.FeatureNode;
46 import eu.etaxonomy.cdm.model.description.FeatureTree;
47 import eu.etaxonomy.taxeditor.model.MessagingUtils;
48 import eu.etaxonomy.taxeditor.store.CdmStore;
49
50 /**
51 * <p>
52 * EditFeatureTreeWizardPage class.
53 * </p>
54 *
55 * @author n.hoffmann
56 * @created Aug 5, 2010
57 * @version 1.0
58 */
59 public class EditFeatureTreeWizardPage extends WizardPage implements
60 ModifyListener, ISelectionChangedListener {
61
62 private TreeViewer viewer;
63 private Label label_title;
64 private Text text_title;
65 private Button button_add;
66 private Button button_remove;
67 private Label label_treeInfo;
68 private FeatureTree featureTree;
69
70 /**
71 * <p>
72 * Constructor for EditFeatureTreeWizardPage.
73 * </p>
74 *
75 * @param pageName
76 * a {@link java.lang.String} object.
77 */
78 protected EditFeatureTreeWizardPage(String pageName) {
79 super(pageName);
80 setMessage("Edit the Feature Tree.");
81 }
82
83 /*
84 * (non-Javadoc)
85 *
86 * @see
87 * org.eclipse.jface.dialogs.IDialogPage#createControl(org.eclipse.swt.widgets
88 * .Composite)
89 */
90 /** {@inheritDoc} */
91 @Override
92 public void createControl(Composite parent) {
93 Composite composite = new Composite(parent, SWT.NULL);
94 composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
95 composite.setLayout(new GridLayout());
96
97 Composite composite_treeTitle = new Composite(composite, SWT.NULL);
98 composite_treeTitle.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true,
99 false));
100 composite_treeTitle.setLayout(new GridLayout(2, false));
101
102 label_title = new Label(composite_treeTitle, SWT.NULL);
103 label_title.setText("Title");
104
105 text_title = new Text(composite_treeTitle, SWT.NULL);
106 text_title.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));
107
108 Composite composite_treeContent = new Composite(composite, SWT.NULL);
109 composite_treeContent.setLayoutData(new GridData(SWT.FILL, SWT.FILL,
110 true, true));
111 composite_treeContent.setLayout(new GridLayout(2, false));
112
113 viewer = new TreeViewer(composite_treeContent);
114 viewer.getControl().setLayoutData(
115 new GridData(SWT.FILL, SWT.FILL, true, true));
116
117 Composite composite_buttons = new Composite(composite_treeContent,
118 SWT.NULL);
119 composite_buttons.setLayoutData(new GridData(SWT.LEFT, SWT.TOP, false,
120 false));
121 composite_buttons.setLayout(new GridLayout());
122
123 button_add = new Button(composite_buttons, SWT.PUSH);
124 button_add.setText("Add");
125 button_add.setToolTipText("Add a feature to this feature treee.");
126 button_remove = new Button(composite_buttons, SWT.PUSH);
127 button_remove.setText("Remove");
128 button_remove
129 .setToolTipText("Remove a feature from this feature tree.");
130
131 label_treeInfo = new Label(composite, SWT.NULL);
132 label_treeInfo
133 .setText("Order and nesting of feature nodes may be changed through drag and drop.");
134
135 viewer.setContentProvider(new FeatureTreeContentProvider());
136 viewer.setLabelProvider(new FeatureTreeLabelProvider());
137
138 int ops = DND.DROP_COPY | DND.DROP_MOVE;
139 Transfer[] transfers = new Transfer[] { FeatureNodeTransfer
140 .getInstance() };
141 viewer.addDragSupport(ops, transfers, new FeatureNodeDragListener(
142 viewer));
143 viewer.addDropSupport(ops, transfers,
144 new FeatureNodeDropAdapter(viewer));
145
146 viewer.addSelectionChangedListener(this);
147
148 button_add.addSelectionListener(new AddButtonListener());
149 button_remove.addSelectionListener(new RemoveSelectionListener());
150
151 setControl(composite);
152 }
153
154 /**
155 * <p>
156 * setSelectedTree
157 * </p>
158 *
159 * @param featureTree
160 * a {@link eu.etaxonomy.cdm.model.description.FeatureTree}
161 * object.
162 */
163 public void setSelectedTree(FeatureTree featureTree) {
164 this.featureTree = HibernateProxyHelper.deproxy(featureTree, FeatureTree.class);
165 this.featureTree.setRoot(HibernateProxyHelper.deproxy(featureTree.getRoot(), FeatureNode.class));
166 viewer.setInput(featureTree);
167
168 text_title.removeModifyListener(this);
169 if (featureTree != null){
170 text_title.setText(featureTree.getTitleCache());
171 }
172 text_title.addModifyListener(this);
173 }
174
175 /** {@inheritDoc} */
176 @Override
177 public void modifyText(ModifyEvent e) {
178 featureTree.setTitleCache(text_title.getText(), true);
179 }
180
181 /** {@inheritDoc} */
182 @Override
183 public void selectionChanged(SelectionChangedEvent event) {
184 IStructuredSelection selection = (IStructuredSelection) event
185 .getSelection();
186
187 button_add.setEnabled(selection.size() <= 1);
188 button_remove.setEnabled(selection.size() > 0);
189 }
190
191 private class AddButtonListener extends SelectionAdapter {
192 @Override
193 public void widgetSelected(SelectionEvent e) {
194 AvailableFeaturesWizard wizard = new AvailableFeaturesWizard(
195 featureTree);
196 WizardDialog dialog = new WizardDialog(getShell(), wizard);
197
198 if (dialog.open() == IStatus.OK) {
199 IStructuredSelection selection = (IStructuredSelection) viewer
200 .getSelection();
201 FeatureNode parent = (FeatureNode) (selection.getFirstElement() != null ? selection
202 .getFirstElement() : ((FeatureTree) viewer.getInput())
203 .getRoot());
204 Collection<Feature> additionalFeatures = wizard
205 .getAdditionalFeatures();
206 for (Feature feature : additionalFeatures) {
207 FeatureNode child = FeatureNode.NewInstance(feature);
208 CdmStore.getService(IFeatureNodeService.class).merge(child, true);
209
210 parent.addChild(child);
211 }
212 viewer.refresh();
213 }
214 }
215 }
216
217 private class RemoveSelectionListener extends SelectionAdapter {
218 @Override
219 public void widgetSelected(SelectionEvent e) {
220 IStructuredSelection selection = (IStructuredSelection) viewer
221 .getSelection();
222
223 for (Object selectedObject : selection.toArray()) {
224 FeatureNode featureNode = (FeatureNode) selectedObject;
225 FeatureNode parent = featureNode.getParent();
226 parent.removeChild(featureNode);
227
228 CdmStore.getService(IFeatureNodeService.class).deleteFeatureNode(featureNode.getUuid(), new FeatureNodeDeletionConfigurator());
229
230 }
231 viewer.refresh();
232 }
233 }
234
235 private class FeatureNodeDragListener extends DragSourceAdapter {
236
237 private final TreeViewer viewer;
238
239 public FeatureNodeDragListener(TreeViewer viewer) {
240 this.viewer = viewer;
241 }
242
243 /**
244 * Method declared on DragSourceListener
245 */
246 @Override
247 public void dragFinished(DragSourceEvent event) {
248 if (!event.doit) {
249 return;
250 }
251 // if the featureNode was moved, remove it from the source viewer
252 if (event.detail == DND.DROP_MOVE) {
253 IStructuredSelection selection = (IStructuredSelection) viewer
254 .getSelection();
255 viewer.refresh();
256 }
257 }
258
259 /**
260 * Method declared on DragSourceListener
261 */
262 @Override
263 public void dragSetData(DragSourceEvent event) {
264 IStructuredSelection selection = (IStructuredSelection) viewer
265 .getSelection();
266 FeatureNode[] featureNodes = (FeatureNode[]) selection.toList()
267 .toArray(new FeatureNode[selection.size()]);
268 if (FeatureNodeTransfer.getInstance().isSupportedType(
269 event.dataType)) {
270 event.data = featureNodes;
271 }
272 }
273
274 /**
275 * Method declared on DragSourceListener
276 */
277 @Override
278 public void dragStart(DragSourceEvent event) {
279 event.doit = !viewer.getSelection().isEmpty();
280 }
281
282 }
283
284 private class FeatureNodeDropAdapter extends ViewerDropAdapter {
285
286 protected FeatureNodeDropAdapter(Viewer viewer) {
287 super(viewer);
288 }
289
290 @Override
291 public boolean performDrop(Object data) {
292 FeatureNode target = (FeatureNode) getCurrentTarget();
293 int position = 0;
294
295 if (target != null) {
296 int location = getCurrentLocation();
297 FeatureNode parent = target.getParent();
298 if (location == LOCATION_BEFORE) {
299 position = Math.max(0, parent.getIndex(target) - 1);
300 target = parent;
301 }
302
303 if (location == LOCATION_AFTER) {
304 position = parent.getIndex(target);
305 target = parent;
306 }
307 }
308
309 // set target to root node if there is no target specified
310 if (target == null) {
311 FeatureTree featureTree = (FeatureTree) getViewer().getInput();
312 target = featureTree.getRoot();
313 }
314
315 Object[] droppedObjects = (Object[]) data;
316 TreeViewer viewer = (TreeViewer) getViewer();
317
318 // cannot drop a feature node onto itself
319 for (Object droppedObject : droppedObjects) {
320 if (droppedObject == null) {
321 MessagingUtils.warningDialog(
322 "Operation not supported yet",
323 this,
324 "We are currently unable to change the order of freshly created "
325 + "feature trees nodes. Please close and reopen the dialog to change the order of features.");
326 return false;
327 }
328 if (droppedObject.equals(target)) {
329 return false;
330 }
331 }
332 for (Object droppedObject : droppedObjects) {
333 FeatureNode droppedNode = (FeatureNode) droppedObject;
334 target.addChild(droppedNode, position);
335 viewer.add(target, droppedNode);
336 viewer.reveal(droppedNode);
337 }
338 return true;
339 }
340
341 @Override
342 public boolean validateDrop(Object target, int operation,
343 TransferData transferData) {
344 return FeatureNodeTransfer.getInstance().isSupportedType(
345 transferData);
346 }
347
348 }
349 }