Project

General

Profile

Download (12.2 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.e4;
11

    
12
import java.util.Collection;
13

    
14
import javax.annotation.PostConstruct;
15
import javax.inject.Inject;
16
import javax.inject.Named;
17

    
18
import org.eclipse.core.runtime.IStatus;
19
import org.eclipse.e4.ui.di.Persist;
20
import org.eclipse.e4.ui.model.application.ui.MDirtyable;
21
import org.eclipse.e4.ui.services.IServiceConstants;
22
import org.eclipse.jface.viewers.ISelectionChangedListener;
23
import org.eclipse.jface.viewers.IStructuredSelection;
24
import org.eclipse.jface.viewers.SelectionChangedEvent;
25
import org.eclipse.jface.viewers.TreeViewer;
26
import org.eclipse.jface.viewers.Viewer;
27
import org.eclipse.jface.viewers.ViewerDropAdapter;
28
import org.eclipse.jface.wizard.WizardDialog;
29
import org.eclipse.swt.SWT;
30
import org.eclipse.swt.dnd.DND;
31
import org.eclipse.swt.dnd.DragSourceAdapter;
32
import org.eclipse.swt.dnd.DragSourceEvent;
33
import org.eclipse.swt.dnd.Transfer;
34
import org.eclipse.swt.dnd.TransferData;
35
import org.eclipse.swt.events.ModifyEvent;
36
import org.eclipse.swt.events.ModifyListener;
37
import org.eclipse.swt.events.SelectionAdapter;
38
import org.eclipse.swt.events.SelectionEvent;
39
import org.eclipse.swt.events.SelectionListener;
40
import org.eclipse.swt.layout.GridData;
41
import org.eclipse.swt.layout.GridLayout;
42
import org.eclipse.swt.widgets.Button;
43
import org.eclipse.swt.widgets.Composite;
44
import org.eclipse.swt.widgets.Label;
45
import org.eclipse.swt.widgets.Shell;
46
import org.eclipse.swt.widgets.Text;
47
import org.eclipse.swt.widgets.Tree;
48

    
49
import eu.etaxonomy.cdm.api.conversation.ConversationHolder;
50
import eu.etaxonomy.cdm.api.service.IFeatureNodeService;
51
import eu.etaxonomy.cdm.api.service.IFeatureTreeService;
52
import eu.etaxonomy.cdm.api.service.config.FeatureNodeDeletionConfigurator;
53
import eu.etaxonomy.cdm.hibernate.HibernateProxyHelper;
54
import eu.etaxonomy.cdm.model.description.Feature;
55
import eu.etaxonomy.cdm.model.description.FeatureNode;
56
import eu.etaxonomy.cdm.model.description.FeatureTree;
57
import eu.etaxonomy.taxeditor.featuretree.AvailableFeaturesWizard;
58
import eu.etaxonomy.taxeditor.featuretree.FeatureNodeTransfer;
59
import eu.etaxonomy.taxeditor.featuretree.FeatureTreeContentProvider;
60
import eu.etaxonomy.taxeditor.featuretree.FeatureTreeLabelProvider;
61
import eu.etaxonomy.taxeditor.model.ImageResources;
62
import eu.etaxonomy.taxeditor.model.MessagingUtils;
63
import eu.etaxonomy.taxeditor.store.CdmStore;
64
import eu.etaxonomy.taxeditor.ui.dialog.selection.FeatureTreeSelectionDialog;
65

    
66
/**
67
 *
68
 * @author pplitzner
69
 * @date 06.06.2017
70
 *
71
 */
72
public class FeatureTreeEditor implements
73
		ModifyListener, ISelectionChangedListener {
74

    
75
	private TreeViewer viewer;
76
	private Label label_title;
77
	private Button button_add;
78
	private Button button_remove;
79
	private FeatureTree featureTree;
80
	private Text text_title;
81
    private Button btnOpenFeatureTree;
82

    
83
    private ConversationHolder conversation;
84
    @Inject
85
    private MDirtyable dirty;
86

    
87
    private Shell shell;
88

    
89
    @Inject
90
    public FeatureTreeEditor(@Named(IServiceConstants.ACTIVE_SHELL)Shell shell) {
91
        this.shell = shell;
92
        if(conversation==null){
93
            conversation = CdmStore.createConversation();
94
        }
95
    }
96

    
97
	/** {@inheritDoc} */
98
	@PostConstruct
99
	public void createControl(Composite parent, @Named(IServiceConstants.ACTIVE_SHELL)Shell shell) {
100
	    parent.setLayout(new GridLayout());
101
		Composite composite = new Composite(parent, SWT.NULL);
102
		composite.setLayout(new GridLayout());
103
		composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
104

    
105
		Composite composite_treeTitle = new Composite(composite, SWT.NULL);
106
		composite_treeTitle.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true,
107
				false));
108
		composite_treeTitle.setLayout(new GridLayout(3, false));
109

    
110
		label_title = new Label(composite_treeTitle, SWT.NULL);
111
		label_title.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1));
112
		label_title.setText("Title");
113

    
114
		text_title = new Text(composite_treeTitle, SWT.BORDER);
115
		text_title.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
116

    
117
		btnOpenFeatureTree = new Button(composite_treeTitle, SWT.NONE);
118
		btnOpenFeatureTree.setToolTipText("Open Tree");
119
		btnOpenFeatureTree.setImage(ImageResources.getImage(ImageResources.BROWSE_ICON));
120

    
121
		Composite composite_treeContent = new Composite(composite, SWT.NULL);
122
		composite_treeContent.setLayoutData(new GridData(SWT.FILL, SWT.FILL,
123
				true, true));
124
		composite_treeContent.setLayout(new GridLayout(2, false));
125

    
126
		viewer = new TreeViewer(composite_treeContent);
127
		Tree tree = viewer.getTree();
128
		tree.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1));
129
		viewer.getControl().setLayoutData(
130
				new GridData(SWT.FILL, SWT.FILL, true, true));
131

    
132
		Composite composite_buttons = new Composite(composite_treeContent,
133
				SWT.NULL);
134
		composite_buttons.setLayoutData(new GridData(SWT.LEFT, SWT.TOP, false,
135
				false));
136
		composite_buttons.setLayout(new GridLayout());
137

    
138
		button_add = new Button(composite_buttons, SWT.PUSH);
139
		button_add.setToolTipText("Add a feature to this feature tree.");
140
		button_add.setImage(ImageResources.getImage(ImageResources.ADD_EDIT));
141
		button_remove = new Button(composite_buttons, SWT.PUSH);
142
		button_remove.setToolTipText("Remove a feature from this feature tree.");
143
		button_remove.setImage(ImageResources.getImage(ImageResources.TRASH_ICON));
144

    
145
		init(shell);
146
	}
147

    
148
	private void setDirty(boolean isDirty){
149
	    this.dirty.setDirty(isDirty);
150
	}
151

    
152
    private void init(Shell shell) {
153
        viewer.setContentProvider(new FeatureTreeContentProvider());
154
        viewer.setLabelProvider(new FeatureTreeLabelProvider());
155

    
156
        int ops = DND.DROP_COPY | DND.DROP_MOVE;
157
        Transfer[] transfers = new Transfer[] { FeatureNodeTransfer
158
                .getInstance() };
159
        viewer.addDragSupport(ops, transfers, new FeatureNodeDragListener(
160
                viewer));
161
        viewer.addDropSupport(ops, transfers,
162
                new FeatureNodeDropAdapter(viewer));
163

    
164
        viewer.addSelectionChangedListener(this);
165

    
166
        button_add.addSelectionListener(new AddButtonListener());
167
        button_remove.addSelectionListener(new RemoveSelectionListener());
168

    
169
        btnOpenFeatureTree.addSelectionListener(new SelectionListener() {
170

    
171
            @Override
172
            public void widgetSelected(SelectionEvent e) {
173
                FeatureTree tree = FeatureTreeSelectionDialog.select(shell, conversation, null);
174
                if(tree!=null){
175
                    setSelectedTree(tree);
176
                }
177
            }
178

    
179
            @Override
180
            public void widgetDefaultSelected(SelectionEvent e) {
181
            }
182
        });
183
    }
184

    
185
    public void setSelectedTree(FeatureTree featureTree) {
186
		this.featureTree = HibernateProxyHelper.deproxy(featureTree, FeatureTree.class);
187
		this.featureTree.setRoot(HibernateProxyHelper.deproxy(featureTree.getRoot(), FeatureNode.class));
188
		viewer.setInput(featureTree);
189

    
190
		text_title.removeModifyListener(this);
191
		text_title.setText(featureTree.getTitleCache());
192
		text_title.addModifyListener(this);
193
	}
194

    
195
	/** {@inheritDoc} */
196
	@Override
197
	public void modifyText(ModifyEvent e) {
198
		featureTree.setTitleCache(text_title.getText(), true);
199
		setDirty(true);
200
	}
201

    
202
	/** {@inheritDoc} */
203
	@Override
204
	public void selectionChanged(SelectionChangedEvent event) {
205
		IStructuredSelection selection = (IStructuredSelection) event
206
				.getSelection();
207

    
208
		button_add.setEnabled(selection.size() <= 1);
209
		button_remove.setEnabled(selection.size() > 0);
210
	}
211

    
212
	@Persist
213
	public void save(){
214
	    CdmStore.getService(IFeatureTreeService.class).saveOrUpdate(featureTree);
215
	    setDirty(false);
216
	}
217

    
218
	private class AddButtonListener extends SelectionAdapter {
219
		@Override
220
		public void widgetSelected(SelectionEvent e) {
221
			AvailableFeaturesWizard wizard = new AvailableFeaturesWizard(
222
					featureTree);
223
			WizardDialog dialog = new WizardDialog(shell, wizard);
224

    
225
			if (dialog.open() == IStatus.OK) {
226
				IStructuredSelection selection = (IStructuredSelection) viewer
227
						.getSelection();
228
				FeatureNode parent = (FeatureNode) (selection.getFirstElement() != null ? selection
229
						.getFirstElement() : ((FeatureTree) viewer.getInput())
230
						.getRoot());
231
				Collection<Feature> additionalFeatures = wizard
232
						.getAdditionalFeatures();
233
				for (Feature feature : additionalFeatures) {
234
					FeatureNode child = FeatureNode.NewInstance(feature);
235
					CdmStore.getService(IFeatureNodeService.class).merge(child, true);
236

    
237
					parent.addChild(child);
238
				}
239
				setDirty(true);
240
				viewer.refresh();
241
			}
242
		}
243

    
244
	}
245

    
246
	private class RemoveSelectionListener extends SelectionAdapter {
247
		@Override
248
		public void widgetSelected(SelectionEvent e) {
249
			IStructuredSelection selection = (IStructuredSelection) viewer
250
					.getSelection();
251

    
252
			for (Object selectedObject : selection.toArray()) {
253
				FeatureNode featureNode = (FeatureNode) selectedObject;
254
				FeatureNode parent = featureNode.getParent();
255
				parent.removeChild(featureNode);
256

    
257
				CdmStore.getService(IFeatureNodeService.class).deleteFeatureNode(featureNode.getUuid(), new FeatureNodeDeletionConfigurator());
258

    
259
			}
260
			setDirty(true);
261
			viewer.refresh();
262
		}
263
	}
264

    
265
	private class FeatureNodeDragListener extends DragSourceAdapter {
266

    
267
		private final TreeViewer viewer;
268

    
269
		public FeatureNodeDragListener(TreeViewer viewer) {
270
			this.viewer = viewer;
271
		}
272

    
273
		/**
274
		 * Method declared on DragSourceListener
275
		 */
276
		@Override
277
		public void dragFinished(DragSourceEvent event) {
278
			if (!event.doit) {
279
                return;
280
            }
281
			// if the featureNode was moved, remove it from the source viewer
282
			if (event.detail == DND.DROP_MOVE) {
283
				IStructuredSelection selection = (IStructuredSelection) viewer
284
						.getSelection();
285
				viewer.refresh();
286
			}
287
		}
288

    
289
		/**
290
		 * Method declared on DragSourceListener
291
		 */
292
		@Override
293
		public void dragSetData(DragSourceEvent event) {
294
			IStructuredSelection selection = (IStructuredSelection) viewer
295
					.getSelection();
296
			FeatureNode[] featureNodes = (FeatureNode[]) selection.toList()
297
					.toArray(new FeatureNode[selection.size()]);
298
			if (FeatureNodeTransfer.getInstance().isSupportedType(
299
					event.dataType)) {
300
				event.data = featureNodes;
301
			}
302
		}
303

    
304
		/**
305
		 * Method declared on DragSourceListener
306
		 */
307
		@Override
308
		public void dragStart(DragSourceEvent event) {
309
			event.doit = !viewer.getSelection().isEmpty();
310
		}
311

    
312
	}
313

    
314
	private class FeatureNodeDropAdapter extends ViewerDropAdapter {
315

    
316
		protected FeatureNodeDropAdapter(Viewer viewer) {
317
			super(viewer);
318
		}
319

    
320
		@Override
321
		public boolean performDrop(Object data) {
322
			FeatureNode target = (FeatureNode) getCurrentTarget();
323
			int position = 0;
324

    
325
			if (target != null) {
326
				int location = getCurrentLocation();
327
				FeatureNode parent = target.getParent();
328
				if (location == LOCATION_BEFORE) {
329
					position = Math.max(0, parent.getIndex(target) - 1);
330
					target = parent;
331
				}
332

    
333
				if (location == LOCATION_AFTER) {
334
					position = parent.getIndex(target);
335
					target = parent;
336
				}
337
			}
338

    
339
			// set target to root node if there is no target specified
340
			if (target == null) {
341
				FeatureTree featureTree = (FeatureTree) getViewer().getInput();
342
				target = featureTree.getRoot();
343
			}
344

    
345
			Object[] droppedObjects = (Object[]) data;
346
			TreeViewer viewer = (TreeViewer) getViewer();
347

    
348
			// cannot drop a feature node onto itself
349
			for (Object droppedObject : droppedObjects) {
350
				if (droppedObject == null) {
351
					MessagingUtils.warningDialog(
352
									"Operation not supported yet",
353
									this,
354
									"We are currently unable to change the order of freshly created "
355
											+ "feature trees nodes. Please close and reopen the dialog to change the order of features.");
356
					return false;
357
				}
358
				if (droppedObject.equals(target)) {
359
					return false;
360
				}
361
			}
362
			for (Object droppedObject : droppedObjects) {
363
				FeatureNode droppedNode = (FeatureNode) droppedObject;
364
				target.addChild(droppedNode, position);
365
				viewer.add(target, droppedNode);
366
				viewer.reveal(droppedNode);
367
			}
368
			return true;
369
		}
370

    
371
		@Override
372
		public boolean validateDrop(Object target, int operation,
373
				TransferData transferData) {
374
			return FeatureNodeTransfer.getInstance().isSupportedType(
375
					transferData);
376
		}
377

    
378
	}
379
}
    (1-1/1)