Project

General

Profile

Download (10.5 KB) Statistics
| Branch: | Tag: | Revision:
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
}
(3-3/10)