--- /dev/null
+// $Id$
+/**
+* Copyright (C) 2017 EDIT
+* European Distributed Institute of Taxonomy
+* http://www.e-taxonomy.eu
+*
+* The contents of this file are subject to the Mozilla Public License Version 1.1
+* See LICENSE.TXT at the top of this package for the full license terms.
+*/
+package eu.etaxonomy.taxeditor.editor.workingSet;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+
+import javax.annotation.PostConstruct;
+import javax.annotation.PreDestroy;
+import javax.inject.Inject;
+import javax.inject.Named;
+
+import org.eclipse.e4.ui.di.Focus;
+import org.eclipse.e4.ui.di.Persist;
+import org.eclipse.e4.ui.model.application.ui.MDirtyable;
+import org.eclipse.e4.ui.services.IServiceConstants;
+import org.eclipse.e4.ui.workbench.modeling.ESelectionService;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.jface.viewers.TreeSelection;
+import org.eclipse.jface.viewers.TreeViewer;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.SashForm;
+import org.eclipse.swt.dnd.DND;
+import org.eclipse.swt.dnd.Transfer;
+import org.eclipse.swt.events.ModifyEvent;
+import org.eclipse.swt.events.ModifyListener;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Tree;
+import org.eclipse.ui.forms.widgets.FormToolkit;
+
+import eu.etaxonomy.cdm.api.conversation.ConversationHolder;
+import eu.etaxonomy.cdm.api.service.IFeatureNodeService;
+import eu.etaxonomy.cdm.api.service.IFeatureTreeService;
+import eu.etaxonomy.cdm.hibernate.HibernateProxyHelper;
+import eu.etaxonomy.cdm.model.description.Character;
+import eu.etaxonomy.cdm.model.description.FeatureNode;
+import eu.etaxonomy.cdm.model.description.FeatureTree;
+import eu.etaxonomy.taxeditor.featuretree.FeatureNodeDragListener;
+import eu.etaxonomy.taxeditor.featuretree.FeatureNodeDropAdapter;
+import eu.etaxonomy.taxeditor.featuretree.FeatureNodeTransfer;
+import eu.etaxonomy.taxeditor.featuretree.FeatureTreeContentProvider;
+import eu.etaxonomy.taxeditor.featuretree.FeatureTreeLabelProvider;
+import eu.etaxonomy.taxeditor.featuretree.e4.FeatureTreeEditorComposite;
+import eu.etaxonomy.taxeditor.model.MessagingUtils;
+import eu.etaxonomy.taxeditor.session.ICdmEntitySession;
+import eu.etaxonomy.taxeditor.session.ICdmEntitySessionEnabled;
+import eu.etaxonomy.taxeditor.store.CdmStore;
+import eu.etaxonomy.taxeditor.ui.dialog.selection.FeatureTreeSelectionDialog;
+
+/**
+ * @author pplitzner
+ * @date 24.05.2017
+ *
+ */
+public class CharacterEditor implements ICdmEntitySessionEnabled, ISelectionChangedListener, ModifyListener{
+
+
+ private FeatureTreeEditorComposite featureTreeEditorComposite;
+ private TreeViewer treeViewerProperties;
+ private TreeViewer treeViewerStructures;
+ private final FormToolkit formToolkit = new FormToolkit(Display.getDefault());
+ private Button btnAddCharacter;
+
+ @Inject
+ private ESelectionService selService;
+
+ @Inject
+ private MDirtyable dirty;
+
+ private ConversationHolder conversation;
+
+ private ICdmEntitySession cdmEntitySession;
+
+ private FeatureTree featureTree;
+
+ public CharacterEditor() {
+ if(conversation==null){
+ conversation = CdmStore.createConversation();
+ }
+ if (CdmStore.isActive()) {
+ cdmEntitySession = CdmStore.getCurrentSessionManager().newSession(this, true);
+ }
+ }
+
+ /**
+ * Create contents of the view part.
+ */
+ @PostConstruct
+ public void createControls(Composite parent, @Named(IServiceConstants.ACTIVE_SHELL)Shell shell) {
+ parent.setLayout(new GridLayout(1, false));
+
+ SashForm sashForm = new SashForm(parent, SWT.NONE);
+ sashForm.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1));
+ formToolkit.adapt(sashForm);
+ formToolkit.paintBordersFor(sashForm);
+
+ Composite composite = new Composite(sashForm, SWT.NONE);
+ formToolkit.adapt(composite);
+ formToolkit.paintBordersFor(composite);
+ composite.setLayout(new GridLayout(1, false));
+
+ Label lblNewLabel = new Label(composite, SWT.NONE);
+ lblNewLabel.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, true, false, 1, 1));
+ formToolkit.adapt(lblNewLabel, true, true);
+ lblNewLabel.setText("Structures");
+
+ treeViewerStructures = new TreeViewer(composite, SWT.BORDER);
+ Tree tree = treeViewerStructures.getTree();
+ tree.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1));
+
+ Composite composite_1 = new Composite(sashForm, SWT.NONE);
+ formToolkit.adapt(composite_1);
+ formToolkit.paintBordersFor(composite_1);
+ composite_1.setLayout(new GridLayout(1, false));
+
+ Label lblNewLabel_1 = new Label(composite_1, SWT.NONE);
+ lblNewLabel_1.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, true, false, 1, 1));
+ formToolkit.adapt(lblNewLabel_1, true, true);
+ lblNewLabel_1.setText("Properties");
+
+ treeViewerProperties = new TreeViewer(composite_1, SWT.BORDER);
+ Tree tree_1 = treeViewerProperties.getTree();
+ tree_1.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1));
+
+ Composite composite_2 = new Composite(sashForm, SWT.NONE);
+ formToolkit.adapt(composite_2);
+ formToolkit.paintBordersFor(composite_2);
+ composite_2.setLayout(new GridLayout(1, false));
+
+ btnAddCharacter = new Button(composite_2, SWT.NONE);
+ btnAddCharacter.setText(">>");
+ btnAddCharacter.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, false, true, 1, 1));
+ formToolkit.adapt(btnAddCharacter, true, true);
+
+ Composite composite_3 = new Composite(sashForm, SWT.NONE);
+ formToolkit.adapt(composite_3);
+ formToolkit.paintBordersFor(composite_3);
+ composite_3.setLayout(new GridLayout(1, false));
+
+ featureTreeEditorComposite = new FeatureTreeEditorComposite(composite_3, SWT.BORDER);
+ featureTreeEditorComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1));
+ featureTreeEditorComposite.getButton_add().setVisible(false);
+ featureTreeEditorComposite.getButton_remove().setVisible(false);
+ featureTreeEditorComposite.init(new FeatureNodeDragListener(featureTreeEditorComposite.getViewer()), new FeatureNodeDropAdapter(featureTreeEditorComposite.getViewer()), this, new SelectionAdapter() {
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ FeatureTree tree = FeatureTreeSelectionDialog.select(shell, conversation, null);
+ if(tree!=null){
+ setSelectedTree(tree);
+ }
+ }
+ }, new SelectionAdapter() {
+ }, new SelectionAdapter() {
+ });
+ sashForm.setWeights(new int[] {3, 3, 1, 3});
+
+ init();
+ }
+
+ @Focus
+ public void focus(){
+ featureTreeEditorComposite.getViewer().getControl().setFocus();
+ if(conversation!=null && !conversation.isBound()){
+ conversation.bind();
+ }
+ if(cdmEntitySession != null) {
+ cdmEntitySession.bind();
+ }
+ }
+
+ public void setSelectedTree(FeatureTree featureTree) {
+ this.featureTree = HibernateProxyHelper.deproxy(featureTree, FeatureTree.class);
+ this.featureTree.setRoot(HibernateProxyHelper.deproxy(featureTree.getRoot(), FeatureNode.class));
+ featureTreeEditorComposite.getViewer().setInput(featureTree);
+
+ featureTreeEditorComposite.getText_title().removeModifyListener(this);
+ featureTreeEditorComposite.getText_title().setText(featureTree.getTitleCache());
+ featureTreeEditorComposite.getText_title().addModifyListener(this);
+ }
+
+ private void init(){
+ int dndOperations = DND.DROP_COPY | DND.DROP_MOVE;
+ Transfer[] transfers = new Transfer[] { FeatureNodeTransfer.getInstance() };
+
+ FeatureTree structureFeatureTree = CdmStore.getService(IFeatureTreeService.class).load(UUID.fromString("3a953dd1-2b5f-482f-9a33-664ee7ef6c68"));
+ treeViewerStructures.setContentProvider(new FeatureTreeContentProvider());
+ treeViewerStructures.setLabelProvider(new FeatureTreeLabelProvider());
+ treeViewerStructures.setInput(structureFeatureTree);
+
+ FeatureTree propertiesFeatureTree = CdmStore.getService(IFeatureTreeService.class).load(UUID.fromString("e283bbf5-bda3-449d-98de-3601ac8a8bbd"));
+ treeViewerProperties.setContentProvider(new FeatureTreeContentProvider());
+ treeViewerProperties.setLabelProvider(new FeatureTreeLabelProvider());
+ treeViewerProperties.addDragSupport(dndOperations, transfers, new CharacterDragListener(treeViewerStructures, treeViewerProperties));
+ treeViewerProperties.setInput(propertiesFeatureTree);
+
+ btnAddCharacter.addSelectionListener(new SelectionAdapter() {
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ ISelection structureTreeSelection = treeViewerStructures.getSelection();
+ ISelection propertyTreeSelection = treeViewerProperties.getSelection();
+ if(structureTreeSelection==null || propertyTreeSelection==null || featureTree==null){
+ MessagingUtils.warningDialog("Cannot perform action", CharacterEditor.this,
+ "You have to select a structure, a property and a feature tree to perform this action.");
+ return;
+ }
+ //get selected structure and property
+ FeatureNode structureNode = (FeatureNode) ((TreeSelection)structureTreeSelection).getFirstElement();
+ FeatureNode propertyNode = (FeatureNode) ((TreeSelection)propertyTreeSelection).getFirstElement();
+ //create new Character
+ String label = structureNode.getFeature().toString()+" "+propertyNode.getFeature().toString();
+ Character character = Character.NewInstance(structureNode, propertyNode, null, label, label);
+// CdmStore.getService(ITermService.class).saveOrUpdate(character);
+
+ //add new Character to feature tree
+ FeatureNode parent = ((FeatureTree) featureTreeEditorComposite.getViewer().getInput()).getRoot();
+ CdmStore.getService(IFeatureNodeService.class).addChildFeaturNode(parent.getUuid(), character.getUuid());
+
+ setDirty(true);
+ featureTreeEditorComposite.getViewer().refresh();
+ }
+ });
+ }
+
+ @Persist
+ public void save(){
+ if (!conversation.isBound()) {
+ conversation.bind();
+ }
+
+ // commit the conversation and start a new transaction immediately
+ conversation.commit(true);
+
+ CdmStore.getService(IFeatureTreeService.class).saveOrUpdate(featureTree);
+
+ this.setDirty(false);
+ }
+
+ @PreDestroy
+ public void dispose(){
+ if(conversation!=null){
+ conversation.close();
+ }
+ if(cdmEntitySession != null) {
+ cdmEntitySession.dispose();
+ }
+ }
+
+ @Override
+ public Map<Object, List<String>> getPropertyPathsMap() {
+ List<String> propertyPaths = Arrays.asList(new String[] {
+ "children", //$NON-NLS-1$
+ "feature", //$NON-NLS-1$
+ "featureTree", //$NON-NLS-1$
+ });
+ Map<Object, List<String>> propertyPathMap =
+ new HashMap<Object, List<String>>();
+ propertyPathMap.put(FeatureNode.class,propertyPaths);
+ return propertyPathMap;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public List<FeatureTree> getRootEntities() {
+ List<FeatureTree> root = new ArrayList<>();
+ root.add(featureTree);
+ return root;
+ }
+
+ @Override
+ public ICdmEntitySession getCdmEntitySession() {
+ return cdmEntitySession;
+ }
+
+ @Focus
+ public void setFocus() {
+ if(conversation!=null && !conversation.isBound()){
+ conversation.bind();
+ }
+ }
+
+ public TreeViewer getTreeViewerProperties() {
+ return treeViewerProperties;
+ }
+ public TreeViewer getTreeViewerStructures() {
+ return treeViewerStructures;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void selectionChanged(SelectionChangedEvent event) {
+ //propagate selection
+ IStructuredSelection isel = (IStructuredSelection) event.getSelection();
+ selService.setSelection((isel.size() == 1 ? isel.getFirstElement() : isel.toArray()));
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void modifyText(ModifyEvent e) {
+ featureTree.setTitleCache(featureTreeEditorComposite.getText_title().getText(), true);
+ setDirty(true);
+ }
+
+ public void setDirty(boolean isDirty) {
+ dirty.setDirty(isDirty);
+ }
+
+}