Project

General

Profile

« Previous | Next » 

Revision 9092e20b

Added by Patrick Plitzner over 5 years ago

ref #6805 Fix term dragging into feature tree editor

View differences:

eu.etaxonomy.taxeditor.editor/src/main/java/eu/etaxonomy/taxeditor/editor/descriptiveDataSet/character/CharacterDropAdapter.java
10 10

  
11 11
import java.util.Iterator;
12 12

  
13
import org.eclipse.e4.ui.di.UISynchronize;
13 14
import org.eclipse.jface.util.LocalSelectionTransfer;
14 15
import org.eclipse.jface.viewers.ISelection;
15 16
import org.eclipse.jface.viewers.IStructuredSelection;
......
21 22
import eu.etaxonomy.cdm.model.description.Character;
22 23
import eu.etaxonomy.cdm.model.description.FeatureNode;
23 24
import eu.etaxonomy.cdm.model.description.FeatureTree;
24
import eu.etaxonomy.taxeditor.featuretree.e4.FeatureNodeDropAdapter;
25
import eu.etaxonomy.taxeditor.featuretree.e4.FeatureTreeDropAdapter;
26
import eu.etaxonomy.taxeditor.featuretree.e4.IFeatureTreeEditor;
25 27
import eu.etaxonomy.taxeditor.store.CdmStore;
26 28
import eu.etaxonomy.taxeditor.store.StoreUtil;
27
import eu.etaxonomy.taxeditor.workbench.part.IE4SavablePart;
28 29

  
29 30
/**
30 31
 *
......
32 33
 * @date Jun 1, 2017
33 34
 *
34 35
 */
35
public class CharacterDropAdapter extends FeatureNodeDropAdapter {
36
public class CharacterDropAdapter extends FeatureTreeDropAdapter {
36 37

  
37
	protected CharacterDropAdapter(IE4SavablePart savablePart, Viewer viewer) {
38
	    super(savablePart, viewer);
38
	protected CharacterDropAdapter(IFeatureTreeEditor editor, Viewer viewer, UISynchronize sync) {
39
	    super(editor, viewer, sync);
39 40
	}
40 41

  
41 42
	@Override
......
45 46

  
46 47
	@Override
47 48
	public boolean performDrop(Object data) {
48
	    if(StoreUtil.checkDirty(savablePart)){
49
	    if(StoreUtil.checkDirty(editor)){
49 50
	        return false;
50 51
	    }
51 52
	    FeatureNode target = (FeatureNode) getCurrentTarget();
eu.etaxonomy.taxeditor.editor/src/main/java/eu/etaxonomy/taxeditor/editor/descriptiveDataSet/character/CharacterEditor.java
23 23
import org.eclipse.core.runtime.IProgressMonitor;
24 24
import org.eclipse.e4.ui.di.Focus;
25 25
import org.eclipse.e4.ui.di.Persist;
26
import org.eclipse.e4.ui.di.UISynchronize;
26 27
import org.eclipse.e4.ui.model.application.ui.MDirtyable;
27 28
import org.eclipse.e4.ui.services.EMenuService;
28 29
import org.eclipse.e4.ui.workbench.modeling.ESelectionService;
......
59 60
import eu.etaxonomy.taxeditor.editor.AppModelId;
60 61
import eu.etaxonomy.taxeditor.editor.l10n.Messages;
61 62
import eu.etaxonomy.taxeditor.featuretree.e4.FeatureNodeDragListener;
62
import eu.etaxonomy.taxeditor.featuretree.e4.FeatureNodeDropAdapter;
63
import eu.etaxonomy.taxeditor.featuretree.e4.FeatureTreeDropAdapter;
63 64
import eu.etaxonomy.taxeditor.featuretree.e4.FeatureTreeEditorComposite;
64 65
import eu.etaxonomy.taxeditor.featuretree.e4.IFeatureTreeEditor;
65 66
import eu.etaxonomy.taxeditor.model.IDirtyMarkable;
......
89 90
    @Inject
90 91
    private ESelectionService selService;
91 92

  
93
    @Inject
94
    private UISynchronize sync;
95

  
92 96
    @Inject
93 97
    private MDirtyable dirty;
94 98

  
......
157 161
        formToolkit.adapt(btnAddCharacter, true, true);
158 162

  
159 163
        characterTreeEditorComposite = addFeatureTreeEditor(composite_3);
160
        initFeatureTreeComposite(characterTreeEditorComposite, new FeatureNodeDragListener(characterTreeEditorComposite.getViewer()), new CharacterDropAdapter(this, characterTreeEditorComposite.getViewer()));
164
        initFeatureTreeComposite(characterTreeEditorComposite, new FeatureNodeDragListener(characterTreeEditorComposite.getViewer()), new CharacterDropAdapter(this, characterTreeEditorComposite.getViewer(), sync));
161 165
        characterTreeEditorComposite.getLabel_title().setText(Messages.CharacterEditor_CHARACTERS);
162 166

  
163 167
        //add context menu to character viewer//create context menu
......
174 178
    }
175 179

  
176 180
    private void initFeatureTreeComposite(FeatureTreeEditorComposite featureTreeEditorComposite,
177
            FeatureNodeDragListener featureNodeDragListener, FeatureNodeDropAdapter featureNodeDropAdapter) {
181
            FeatureNodeDragListener featureNodeDragListener, FeatureTreeDropAdapter featureNodeDropAdapter) {
178 182
        featureTreeEditorComposite.init(featureNodeDragListener, featureNodeDropAdapter, this,
179 183
                new FeatureTreeChooserListener(featureTreeEditorComposite), this);
180 184
    }
eu.etaxonomy.taxeditor.store/src/main/java/eu/etaxonomy/taxeditor/featuretree/e4/FeatureNodeDragListener.java
30 30
    @Override
31 31
    public void dragSetData(DragSourceEvent event) {
32 32
        IStructuredSelection selection = (IStructuredSelection) viewer.getSelection();
33
        FeatureNode[] featureNodes = (FeatureNode[]) selection.toList().toArray(new FeatureNode[selection.size()]);
34
        if (FeatureNodeTransfer.getInstance().isSupportedType(event.dataType)) {
35
            event.data = featureNodes;
33
        if(selection!=null && !selection.isEmpty()){
34
            FeatureNode[] featureNodes = (FeatureNode[]) selection.toList().toArray(new FeatureNode[selection.size()]);
35
            if (FeatureNodeTransfer.getInstance().isSupportedType(event.dataType)) {
36
                event.data = featureNodes;
37
            }
36 38
        }
37 39
    }
38 40

  
......
41 43
	 */
42 44
	@Override
43 45
	public void dragStart(DragSourceEvent event) {
44
		event.doit = !viewer.getSelection().isEmpty();
46
        event.doit = !viewer.getSelection().isEmpty()
47
                && ((IStructuredSelection) viewer.getSelection()).toList()
48
                .stream().allMatch(element -> element instanceof FeatureNode);
45 49
	}
46 50

  
47 51
}
eu.etaxonomy.taxeditor.store/src/main/java/eu/etaxonomy/taxeditor/featuretree/e4/FeatureNodeDropAdapter.java
1
/**
2
* Copyright (C) 2017 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
package eu.etaxonomy.taxeditor.featuretree.e4;
10

  
11
import java.net.URI;
12
import java.util.Arrays;
13
import java.util.Collection;
14
import java.util.Collections;
15

  
16
import org.eclipse.jface.util.LocalSelectionTransfer;
17
import org.eclipse.jface.viewers.IStructuredSelection;
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.swt.dnd.DND;
22
import org.eclipse.swt.dnd.TransferData;
23

  
24
import eu.etaxonomy.cdm.api.service.IFeatureNodeService;
25
import eu.etaxonomy.cdm.model.common.OrderedTermVocabulary;
26
import eu.etaxonomy.cdm.model.common.TermVocabulary;
27
import eu.etaxonomy.cdm.model.description.Feature;
28
import eu.etaxonomy.cdm.model.description.FeatureNode;
29
import eu.etaxonomy.cdm.model.description.FeatureTree;
30
import eu.etaxonomy.taxeditor.editor.definedterm.TermTransfer;
31
import eu.etaxonomy.taxeditor.featuretree.FeatureNodeTransfer;
32
import eu.etaxonomy.taxeditor.l10n.Messages;
33
import eu.etaxonomy.taxeditor.model.MessagingUtils;
34
import eu.etaxonomy.taxeditor.store.CdmStore;
35
import eu.etaxonomy.taxeditor.store.StoreUtil;
36
import eu.etaxonomy.taxeditor.ui.dialog.selection.TermVocabularySelectionDialog;
37
import eu.etaxonomy.taxeditor.view.webimport.termimport.wrapper.OntologyTermWrapper;
38
import eu.etaxonomy.taxeditor.workbench.part.IE4SavablePart;
39

  
40
public class FeatureNodeDropAdapter extends ViewerDropAdapter {
41

  
42
    protected IE4SavablePart savablePart;
43

  
44
    public FeatureNodeDropAdapter(IE4SavablePart savablePart, Viewer viewer) {
45
		super(viewer);
46
		this.savablePart = savablePart;
47
	}
48

  
49
	@Override
50
	public boolean performDrop(Object data) {
51
	    if(StoreUtil.checkDirty(savablePart)){
52
	        return false;
53
	    }
54
		Object currentTarget = getCurrentTarget();
55
		FeatureNode target = null;
56
		if(currentTarget instanceof FeatureTree){
57
		    target = ((FeatureTree) currentTarget).getRoot();
58
		}
59
		else if(currentTarget instanceof FeatureNode){
60
		    target = (FeatureNode) currentTarget;
61
		}
62
		int position = 0;
63

  
64
		if (target != null) {
65
			int location = getCurrentLocation();
66
			FeatureNode parent = target.getParent();
67
			if(parent!=null){
68
			    if (location == LOCATION_BEFORE) {
69
			        position = Math.max(0, parent.getIndex(target) - 1);
70
			        target = parent;
71
			    }
72

  
73
			    if (location == LOCATION_AFTER) {
74
			        position = parent.getIndex(target);
75
			        target = parent;
76
			    }
77
			}
78
		}
79

  
80
        if(target==null){
81
            MessagingUtils.warningDialog(Messages.FeatureNodeDropAdapter_INVALID_TARGET, this, Messages.FeatureNodeDropAdapter_INVALID_TARGET_MESSAGE);
82
            return false;
83
        }
84
		Collection<Object> droppedObjects = Collections.emptyList();
85
		if(data instanceof Object[]){
86
		    droppedObjects = Arrays.asList((Object[])data);
87
		}
88
		else if(data instanceof IStructuredSelection){
89
		    droppedObjects = ((IStructuredSelection) data).toList();
90
		}
91
		TreeViewer viewer = (TreeViewer) getViewer();
92

  
93
		// cannot drop a feature node onto itself
94
		for (Object droppedObject : droppedObjects) {
95
		    if(droppedObject==null){
96
		        MessagingUtils.warningDialog("Move failed", this.getClass(),
97
		                "Moving the feature node failed. Try saving before.");
98
		        return false;
99
		    }
100
			if (droppedObject.equals(target)) {
101
				return false;
102
			}
103
		}
104
		for (Object droppedObject : droppedObjects) {
105
		    if(droppedObject instanceof FeatureNode){
106
		        FeatureNode droppedNode = (FeatureNode) droppedObject;
107
		        //move operation
108
		        if(getCurrentOperation()==DND.DROP_MOVE){
109
		            CdmStore.getService(IFeatureNodeService.class).moveFeatureNode(droppedNode.getUuid(), target.getUuid(), position);
110
		        }
111
		        //copy operation
112
		        else if(getCurrentOperation()==DND.DROP_COPY){
113
		            CdmStore.getService(IFeatureNodeService.class).addChildFeatureNode(target.getUuid(), droppedNode.getFeature().getUuid());
114
		        }
115
		        viewer.reveal(droppedNode);
116
		    }
117
		    else if(droppedObject instanceof Feature){
118
		        Feature droppedFeature = (Feature) droppedObject;
119
		        CdmStore.getService(IFeatureNodeService.class).addChildFeatureNode(target.getUuid(), droppedFeature.getUuid());
120
		    }
121
		    else if(droppedObject instanceof OntologyTermWrapper){
122
		        OntologyTermWrapper wrapper = (OntologyTermWrapper)droppedObject;
123
		        TermVocabulary vocabulary = wrapper.getTermVocabulary();
124
		        if(vocabulary==null){
125
		            vocabulary =  TermVocabularySelectionDialog.select(
126
		                    "Choose vocabulary for import", viewer.getControl().getShell(), null);
127
		            if(vocabulary instanceof OrderedTermVocabulary){
128
		                MessagingUtils.warningDialog("Import not possible", this,
129
		                        "The chosen vocabulary is an ordered vocabulary.\n"
130
		                                + "Importing into ordered vocabularies is currently not supported.");
131
		                return false;
132
		            }
133
		        }
134
		        if(vocabulary==null){
135
		            return false;
136
		        }
137
		        else{
138
		            Feature feature = Feature.NewInstance(wrapper.getDescription(), wrapper.getLabel(), null);
139
		            feature.setUri(URI.create(wrapper.getUri()));
140
		            vocabulary.addTerm(feature);
141
		            CdmStore.getService(IFeatureNodeService.class).createChildFeatureNode(target, feature);
142
		        }
143
		    }
144
		}
145
		viewer.refresh();
146
		return true;
147
	}
148

  
149
    @Override
150
    public boolean validateDrop(Object target, int operation, TransferData transferData) {
151
        boolean isSupported = FeatureNodeTransfer.getInstance().isSupportedType(transferData);
152
        isSupported |= TermTransfer.getInstance().isSupportedType(transferData);
153
        isSupported |= LocalSelectionTransfer.getTransfer().isSupportedType(transferData);
154
        isSupported &= getViewer().getInput()!=null;
155
        return isSupported;
156
    }
157

  
158
}
eu.etaxonomy.taxeditor.store/src/main/java/eu/etaxonomy/taxeditor/featuretree/e4/FeatureTreeDropAdapter.java
1
/**
2
* Copyright (C) 2017 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
package eu.etaxonomy.taxeditor.featuretree.e4;
10

  
11
import java.net.URI;
12
import java.util.Arrays;
13
import java.util.Collection;
14
import java.util.Collections;
15

  
16
import org.eclipse.e4.ui.di.UISynchronize;
17
import org.eclipse.jface.util.LocalSelectionTransfer;
18
import org.eclipse.jface.viewers.IStructuredSelection;
19
import org.eclipse.jface.viewers.TreeViewer;
20
import org.eclipse.jface.viewers.Viewer;
21
import org.eclipse.jface.viewers.ViewerDropAdapter;
22
import org.eclipse.swt.dnd.DND;
23
import org.eclipse.swt.dnd.TransferData;
24

  
25
import eu.etaxonomy.cdm.api.service.IFeatureNodeService;
26
import eu.etaxonomy.cdm.api.service.ITermService;
27
import eu.etaxonomy.cdm.model.common.OrderedTermVocabulary;
28
import eu.etaxonomy.cdm.model.common.TermVocabulary;
29
import eu.etaxonomy.cdm.model.description.Feature;
30
import eu.etaxonomy.cdm.model.description.FeatureNode;
31
import eu.etaxonomy.cdm.model.description.FeatureTree;
32
import eu.etaxonomy.cdm.persistence.dto.TermDto;
33
import eu.etaxonomy.taxeditor.editor.definedterm.TermTransfer;
34
import eu.etaxonomy.taxeditor.featuretree.FeatureNodeTransfer;
35
import eu.etaxonomy.taxeditor.featuretree.e4.operation.AddFeatureOperation;
36
import eu.etaxonomy.taxeditor.l10n.Messages;
37
import eu.etaxonomy.taxeditor.model.AbstractUtility;
38
import eu.etaxonomy.taxeditor.model.MessagingUtils;
39
import eu.etaxonomy.taxeditor.store.CdmStore;
40
import eu.etaxonomy.taxeditor.store.StoreUtil;
41
import eu.etaxonomy.taxeditor.ui.dialog.selection.TermVocabularySelectionDialog;
42
import eu.etaxonomy.taxeditor.view.webimport.termimport.wrapper.OntologyTermWrapper;
43

  
44
public class FeatureTreeDropAdapter extends ViewerDropAdapter {
45

  
46
    protected IFeatureTreeEditor editor;
47
    private UISynchronize sync;
48

  
49
    public FeatureTreeDropAdapter(IFeatureTreeEditor editor, Viewer viewer, UISynchronize sync) {
50
		super(viewer);
51
		this.editor = editor;
52
		this.sync = sync;
53
	}
54

  
55
	@Override
56
	public boolean performDrop(Object data) {
57
	    if(StoreUtil.checkDirty(editor)){
58
	        return false;
59
	    }
60
		Object currentTarget = getCurrentTarget();
61
		FeatureNode target = null;
62
		if(currentTarget instanceof FeatureTree){
63
		    target = ((FeatureTree) currentTarget).getRoot();
64
		}
65
		else if(currentTarget instanceof FeatureNode){
66
		    target = (FeatureNode) currentTarget;
67
		}
68
		int position = 0;
69

  
70
		if (target != null) {
71
			int location = getCurrentLocation();
72
			FeatureNode parent = target.getParent();
73
			if(parent!=null){
74
			    if (location == LOCATION_BEFORE) {
75
			        position = Math.max(0, parent.getIndex(target) - 1);
76
			        target = parent;
77
			    }
78

  
79
			    if (location == LOCATION_AFTER) {
80
			        position = parent.getIndex(target);
81
			        target = parent;
82
			    }
83
			}
84
		}
85

  
86
        if(target==null){
87
            MessagingUtils.warningDialog(Messages.FeatureNodeDropAdapter_INVALID_TARGET, this, Messages.FeatureNodeDropAdapter_INVALID_TARGET_MESSAGE);
88
            return false;
89
        }
90
		Collection<Object> droppedObjects = Collections.emptyList();
91
		if(data instanceof Object[]){
92
		    droppedObjects = Arrays.asList((Object[])data);
93
		}
94
		else if(data instanceof IStructuredSelection){
95
		    droppedObjects = ((IStructuredSelection) data).toList();
96
		}
97
		TreeViewer viewer = (TreeViewer) getViewer();
98

  
99
		// cannot drop a feature node onto itself
100
		for (Object droppedObject : droppedObjects) {
101
		    if(droppedObject==null){
102
		        MessagingUtils.warningDialog("Move failed", this.getClass(),
103
		                "Moving the feature node failed. Try saving before.");
104
		        return false;
105
		    }
106
			if (droppedObject.equals(target)) {
107
				return false;
108
			}
109
		}
110
		for (Object droppedObject : droppedObjects) {
111
		    if(droppedObject instanceof FeatureNode){
112
		        FeatureNode droppedNode = (FeatureNode) droppedObject;
113
		        //move operation
114
		        if(getCurrentOperation()==DND.DROP_MOVE){
115
		            CdmStore.getService(IFeatureNodeService.class).moveFeatureNode(droppedNode.getUuid(), target.getUuid(), position);
116
		        }
117
		        //copy operation
118
		        else if(getCurrentOperation()==DND.DROP_COPY){
119
		            CdmStore.getService(IFeatureNodeService.class).addChildFeatureNode(target.getUuid(), droppedNode.getFeature().getUuid());
120
		        }
121
		        viewer.reveal(droppedNode);
122
		    }
123
		    else if(droppedObject instanceof Feature){
124
		        Feature droppedFeature = (Feature) droppedObject;
125
		        AddFeatureOperation operation = new AddFeatureOperation(
126
		                (Feature) CdmStore.getService(ITermService.class).load(droppedFeature.getUuid()),
127
		                target, editor, editor);
128
		        AbstractUtility.executeOperation(operation, sync);
129
		    }
130
		    else if(droppedObject instanceof TermDto){
131
		        TermDto termDto = (TermDto) droppedObject;
132
                AddFeatureOperation operation = new AddFeatureOperation(
133
                        (Feature) CdmStore.getService(ITermService.class).load(termDto.getUuid()),
134
                        target, editor, editor);
135
                AbstractUtility.executeOperation(operation, sync);
136
		    }
137
		    else if(droppedObject instanceof OntologyTermWrapper){
138
		        OntologyTermWrapper wrapper = (OntologyTermWrapper)droppedObject;
139
		        TermVocabulary vocabulary = wrapper.getTermVocabulary();
140
		        if(vocabulary==null){
141
		            vocabulary =  TermVocabularySelectionDialog.select(
142
		                    "Choose vocabulary for import", viewer.getControl().getShell(), null);
143
		            if(vocabulary instanceof OrderedTermVocabulary){
144
		                MessagingUtils.warningDialog("Import not possible", this,
145
		                        "The chosen vocabulary is an ordered vocabulary.\n"
146
		                                + "Importing into ordered vocabularies is currently not supported.");
147
		                return false;
148
		            }
149
		        }
150
		        if(vocabulary==null){
151
		            return false;
152
		        }
153
		        else{
154
		            Feature feature = Feature.NewInstance(wrapper.getDescription(), wrapper.getLabel(), null);
155
		            feature.setUri(URI.create(wrapper.getUri()));
156
		            vocabulary.addTerm(feature);
157
		            CdmStore.getService(IFeatureNodeService.class).createChildFeatureNode(target, feature);
158
		        }
159
		    }
160
		}
161
		viewer.refresh();
162
		return true;
163
	}
164

  
165
    @Override
166
    public boolean validateDrop(Object target, int operation, TransferData transferData) {
167
        boolean isSupported = FeatureNodeTransfer.getInstance().isSupportedType(transferData);
168
        isSupported |= TermTransfer.getInstance().isSupportedType(transferData);
169
        isSupported |= LocalSelectionTransfer.getTransfer().isSupportedType(transferData);
170
        isSupported |= TermTransfer.getInstance().isSupportedType(transferData);
171
        isSupported &= getViewer().getInput()!=null;
172
        return isSupported;
173
    }
174

  
175
}
eu.etaxonomy.taxeditor.store/src/main/java/eu/etaxonomy/taxeditor/featuretree/e4/FeatureTreeEditor.java
21 21
import org.eclipse.core.runtime.IProgressMonitor;
22 22
import org.eclipse.e4.ui.di.Focus;
23 23
import org.eclipse.e4.ui.di.Persist;
24
import org.eclipse.e4.ui.di.UISynchronize;
24 25
import org.eclipse.e4.ui.model.application.ui.MDirtyable;
25 26
import org.eclipse.e4.ui.model.application.ui.basic.MPart;
26 27
import org.eclipse.e4.ui.services.EMenuService;
......
77 78
    @Inject
78 79
    private MDirtyable dirty;
79 80

  
81
    @Inject
82
    private UISynchronize sync;
83

  
80 84
    @Inject
81 85
    private MPart thisPart;
82 86

  
......
106 110
                TermTransfer.getInstance(),
107 111
                LocalSelectionTransfer.getTransfer()};
108 112
        viewer.addDragSupport(ops, transfers, new FeatureNodeDragListener(viewer));
109
        viewer.addDropSupport(ops, transfers, new FeatureNodeDropAdapter(this, viewer));
113
        viewer.addDropSupport(ops, transfers, new FeatureTreeDropAdapter(this, viewer, sync));
110 114
        viewer.addSelectionChangedListener(this);
111 115

  
112 116
        List<FeatureTree> trees = CdmStore.getService(IFeatureTreeService.class).list(FeatureTree.class, null, null, null, null);
......
196 200

  
197 201
        CdmStore.getService(IFeatureTreeService.class).saveOrUpdate(getRootEntities());
198 202

  
199
        initialiseRootEntities();
203
        initializeTrees();
200 204

  
201 205
        this.setDirty(false);
202 206
	}
203 207

  
204
    private void initialiseRootEntities() {
208
    private void initializeTrees() {
205 209
        Object[] expandedElements = viewer.getExpandedElements();
206 210
        viewer.getTree().removeAll();
207 211
        List<FeatureTree> trees = CdmStore.getService(IFeatureTreeService.class).list(FeatureTree.class, null, null, null, null);
......
282 286

  
283 287
    @Override
284 288
    public boolean postOperation(Object objectAffectedByOperation) {
285
        initialiseRootEntities();
289
        initializeTrees();
286 290
        viewer.refresh();
287 291
        if(objectAffectedByOperation instanceof FeatureNode){
288 292
            FeatureNode node = (FeatureNode)objectAffectedByOperation;

Also available in: Unified diff