Bug 519607 - Add support for Multi edit
* fixes application of multi editing context behavior only if
multi-selection occurs
* add support for add/remove notifications
* enable multi editing on view model editor
* add test case
Change-Id: I1e664caeac2fd56fff0beb80794df994981f95c9
Signed-off-by: Eugen Neufeld <eneufeld@eclipsesource.com>
diff --git a/bundles/org.eclipse.emf.ecp.ide.editor.view/src/org/eclipse/emf/ecp/ide/editor/view/ViewEditorPart.java b/bundles/org.eclipse.emf.ecp.ide.editor.view/src/org/eclipse/emf/ecp/ide/editor/view/ViewEditorPart.java
index 2839b8b..cd59331 100644
--- a/bundles/org.eclipse.emf.ecp.ide.editor.view/src/org/eclipse/emf/ecp/ide/editor/view/ViewEditorPart.java
+++ b/bundles/org.eclipse.emf.ecp.ide.editor.view/src/org/eclipse/emf/ecp/ide/editor/view/ViewEditorPart.java
@@ -58,6 +58,7 @@
import org.eclipse.emf.ecp.view.migrator.ViewModelMigratorUtil;
import org.eclipse.emf.ecp.view.migrator.ViewModelWorkspaceMigrator;
import org.eclipse.emf.ecp.view.model.common.edit.provider.CustomReflectiveItemProviderAdapterFactory;
+import org.eclipse.emf.ecp.view.spi.context.ViewModelContext;
import org.eclipse.emf.ecp.view.spi.context.ViewModelContextFactory;
import org.eclipse.emf.ecp.view.spi.model.VView;
import org.eclipse.emf.ecp.view.spi.model.reporting.StatusReport;
@@ -611,10 +612,11 @@
}
try {
-
- render = ECPSWTViewRenderer.INSTANCE.render(parent, ViewModelContextFactory.INSTANCE
+ final ViewModelContext viewModelContext = ViewModelContextFactory.INSTANCE
.createViewModelContext(ViewProviderHelper.getView(view, null), view, new DefaultReferenceService(),
- new EMFDeleteServiceImpl()));
+ new EMFDeleteServiceImpl());
+ viewModelContext.putContextValue("enableMultiEdit", Boolean.TRUE);
+ render = ECPSWTViewRenderer.INSTANCE.render(parent, viewModelContext);
} catch (final ECPRendererException ex) {
Activator.getDefault().getReportService().report(
new StatusReport(new Status(IStatus.ERROR, Activator.PLUGIN_ID, ex.getMessage(), ex)));
diff --git a/bundles/org.eclipse.emf.ecp.view.treemasterdetail.ui.swt/src/org/eclipse/emf/ecp/view/spi/treemasterdetail/ui/swt/TreeMasterDetailSWTRenderer.java b/bundles/org.eclipse.emf.ecp.view.treemasterdetail.ui.swt/src/org/eclipse/emf/ecp/view/spi/treemasterdetail/ui/swt/TreeMasterDetailSWTRenderer.java
index f784be1..63b260b 100644
--- a/bundles/org.eclipse.emf.ecp.view.treemasterdetail.ui.swt/src/org/eclipse/emf/ecp/view/spi/treemasterdetail/ui/swt/TreeMasterDetailSWTRenderer.java
+++ b/bundles/org.eclipse.emf.ecp.view.treemasterdetail.ui.swt/src/org/eclipse/emf/ecp/view/spi/treemasterdetail/ui/swt/TreeMasterDetailSWTRenderer.java
@@ -69,6 +69,7 @@
import org.eclipse.emf.ecp.view.treemasterdetail.ui.swt.internal.TreeMasterDetailSelectionManipulatorHelper;
import org.eclipse.emf.edit.command.AddCommand;
import org.eclipse.emf.edit.command.CommandParameter;
+import org.eclipse.emf.edit.command.DeleteCommand;
import org.eclipse.emf.edit.command.SetCommand;
import org.eclipse.emf.edit.domain.AdapterFactoryEditingDomain;
import org.eclipse.emf.edit.domain.EditingDomain;
@@ -852,6 +853,57 @@
*/
private class TreeMasterViewSelectionListener implements ISelectionChangedListener {
+ /**
+ * Adapter which listens to changes and delegates the notification to other EObjects.
+ *
+ * @author Eugen Neufeld
+ *
+ */
+ private final class MultiEditAdapter extends AdapterImpl {
+ private final EObject dummy;
+ private final Set<EObject> selectedEObjects;
+
+ private MultiEditAdapter(EObject dummy, Set<EObject> selectedEObjects) {
+ this.dummy = dummy;
+ this.selectedEObjects = selectedEObjects;
+ }
+
+ @Override
+ public void notifyChanged(Notification notification) {
+ final EditingDomain editingDomain = AdapterFactoryEditingDomain
+ .getEditingDomainFor(getViewModelContext().getDomainModel());
+ if (dummy.eClass().getEAllAttributes().contains(notification.getFeature())) {
+ final CompoundCommand cc = new CompoundCommand();
+ for (final EObject selected : selectedEObjects) {
+ Command command = null;
+ switch (notification.getEventType()) {
+ case Notification.SET:
+ command = SetCommand.create(editingDomain, selected,
+ notification.getFeature(), notification.getNewValue());
+ break;
+ case Notification.UNSET:
+ command = SetCommand.create(editingDomain, selected,
+ notification.getFeature(), SetCommand.UNSET_VALUE);
+ break;
+ case Notification.ADD:
+ case Notification.ADD_MANY:
+ command = AddCommand.create(editingDomain, selected,
+ notification.getFeature(), notification.getNewValue());
+ break;
+ case Notification.REMOVE:
+ case Notification.REMOVE_MANY:
+ command = DeleteCommand.create(editingDomain, notification.getOldValue());
+ break;
+ default:
+ continue;
+ }
+ cc.append(command);
+ }
+ editingDomain.getCommandStack().execute(cc);
+ }
+ }
+ }
+
private Composite childComposite;
private boolean currentDetailViewOriginalReadonly;
@@ -894,7 +946,10 @@
final ReferenceService referenceService = getViewModelContext().getService(
ReferenceService.class);
ViewModelContext childContext;
- if (getViewModelContext().getContextValue(ENABLE_MULTI_EDIT) == Boolean.TRUE) {
+ // we have a multi selection, the multi edit is enabled and the multi selection is valid
+ if (getViewModelContext().getContextValue(ENABLE_MULTI_EDIT) == Boolean.TRUE
+ && selection.size() > 1
+ && selected != getSelection(new StructuredSelection(selection.getFirstElement()))) {
childContext = ViewModelContextFactory.INSTANCE.createViewModelContext(view, (EObject) selected,
new TreeMasterDetailReferenceService(referenceService));
} else {
@@ -950,35 +1005,7 @@
}
if (allOfSameType) {
treeSelected = dummy;
- dummy.eAdapters().add(new AdapterImpl() {
-
- @Override
- public void notifyChanged(Notification notification) {
- final EditingDomain editingDomain = AdapterFactoryEditingDomain
- .getEditingDomainFor(getViewModelContext().getDomainModel());
- if (dummy.eClass().getEAllAttributes().contains(notification.getFeature())) {
- final CompoundCommand cc = new CompoundCommand();
- for (final EObject selected : selectedEObjects) {
- Command command = null;
- switch (notification.getEventType()) {
- case Notification.SET:
- command = SetCommand.create(editingDomain, selected,
- notification.getFeature(), notification.getNewValue());
- break;
- case Notification.UNSET:
- command = SetCommand.create(editingDomain, selected,
- notification.getFeature(), SetCommand.UNSET_VALUE);
- break;
- default:
- continue;
- }
- cc.append(command);
- }
- editingDomain.getCommandStack().execute(cc);
- }
- }
-
- });
+ dummy.eAdapters().add(new MultiEditAdapter(dummy, selectedEObjects));
}
}
return treeSelected;
diff --git a/bundles/org.eclipse.emfforms.swt.treemasterdetail/src/org/eclipse/emfforms/spi/swt/treemasterdetail/TreeMasterDetailComposite.java b/bundles/org.eclipse.emfforms.swt.treemasterdetail/src/org/eclipse/emfforms/spi/swt/treemasterdetail/TreeMasterDetailComposite.java
index a0fe12d..2f24e07 100644
--- a/bundles/org.eclipse.emfforms.swt.treemasterdetail/src/org/eclipse/emfforms/spi/swt/treemasterdetail/TreeMasterDetailComposite.java
+++ b/bundles/org.eclipse.emfforms.swt.treemasterdetail/src/org/eclipse/emfforms/spi/swt/treemasterdetail/TreeMasterDetailComposite.java
@@ -39,6 +39,8 @@
import org.eclipse.emf.ecp.view.spi.model.VViewModelProperties;
import org.eclipse.emf.ecp.view.spi.provider.ViewProviderHelper;
import org.eclipse.emf.ecp.view.treemasterdetail.model.VTreeMasterDetail;
+import org.eclipse.emf.edit.command.AddCommand;
+import org.eclipse.emf.edit.command.DeleteCommand;
import org.eclipse.emf.edit.command.SetCommand;
import org.eclipse.emf.edit.domain.AdapterFactoryEditingDomain;
import org.eclipse.emf.edit.domain.EditingDomain;
@@ -418,32 +420,7 @@
}
if (allOfSameType) {
selectedObject = dummy;
- dummy.eAdapters().add(new AdapterImpl() {
-
- @Override
- public void notifyChanged(Notification notification) {
- if (dummy.eClass().getEAllAttributes().contains(notification.getFeature())) {
- final CompoundCommand cc = new CompoundCommand();
- for (final EObject selected : selectedEObjects) {
- Command command = null;
- switch (notification.getEventType()) {
- case Notification.SET:
- command = SetCommand.create(editingDomain, selected,
- notification.getFeature(), notification.getNewValue());
- break;
- case Notification.UNSET:
- command = SetCommand.create(editingDomain, selected,
- notification.getFeature(), SetCommand.UNSET_VALUE);
- break;
- default:
- continue;
- }
- cc.append(command);
- }
- editingDomain.getCommandStack().execute(cc);
- }
- }
- });
+ dummy.eAdapters().add(new MultiEditAdapter(selectedEObjects, dummy));
}
}
return selectedObject;
@@ -591,6 +568,55 @@
}
/**
+ * Adapter which listens to changes and delegates the notification to other EObjects.
+ *
+ * @author Eugen Neufeld
+ *
+ */
+ private final class MultiEditAdapter extends AdapterImpl {
+ private final Set<EObject> selectedEObjects;
+ private final EObject dummy;
+
+ private MultiEditAdapter(Set<EObject> selectedEObjects, EObject dummy) {
+ this.selectedEObjects = selectedEObjects;
+ this.dummy = dummy;
+ }
+
+ @Override
+ public void notifyChanged(Notification notification) {
+ if (dummy.eClass().getEAllAttributes().contains(notification.getFeature())) {
+ final CompoundCommand cc = new CompoundCommand();
+ for (final EObject selected : selectedEObjects) {
+ Command command = null;
+ switch (notification.getEventType()) {
+ case Notification.SET:
+ command = SetCommand.create(editingDomain, selected,
+ notification.getFeature(), notification.getNewValue());
+ break;
+ case Notification.UNSET:
+ command = SetCommand.create(editingDomain, selected,
+ notification.getFeature(), SetCommand.UNSET_VALUE);
+ break;
+ case Notification.ADD:
+ case Notification.ADD_MANY:
+ command = AddCommand.create(editingDomain, selected,
+ notification.getFeature(), notification.getNewValue());
+ break;
+ case Notification.REMOVE:
+ case Notification.REMOVE_MANY:
+ command = DeleteCommand.create(editingDomain, notification.getOldValue());
+ break;
+ default:
+ continue;
+ }
+ cc.append(command);
+ }
+ editingDomain.getCommandStack().execute(cc);
+ }
+ }
+ }
+
+ /**
* Runnable which updates the detail panel.
*/
private final class UpdateDetailRunnable implements Runnable {
diff --git a/tests/ECPQ7Tests/EPPTests/update-site/project/ViewEditorMultiEdit.test b/tests/ECPQ7Tests/EPPTests/update-site/project/ViewEditorMultiEdit.test
new file mode 100644
index 0000000..e04eae8
--- /dev/null
+++ b/tests/ECPQ7Tests/EPPTests/update-site/project/ViewEditorMultiEdit.test
@@ -0,0 +1,57 @@
+--- RCPTT testcase ---
+Format-Version: 1.0
+Contexts: _D4Pj4C3lEeSwhO5Nwx0hPg,_Iu0EsS36EeSYRYqCbC6LMQ
+Element-Name: ViewEditorMultiEdit
+Element-Type: testcase
+Element-Version: 3.0
+External-Reference:
+Id: _1aNe4KerEeijWtYvZtcong
+Runtime-Version: 2.2.0.201706152316
+Save-Time: 8/24/18 5:10 PM
+Testcase-Type: ecl
+
+------=_.content-0a7243a0-75d3-3d5f-9791-539de0e5b7ac
+Content-Type: text/ecl
+Entry-Name: .content
+
+get-view "Project Explorer" | get-tree
+ | select "org.eclipse.emf.ecp.makeithappen.model.viewmodel/viewmodels/UserGroup.view"
+ | select "org.eclipse.emf.ecp.makeithappen.model.viewmodel/viewmodels/UserGroup.view" | get-menu
+ -path "Open With/View Model Editor" | click
+with [get-editor "UserGroup.view"] {
+ with [get-tree] {
+ select View | get-menu -path Control | click
+ select View | get-menu -path Control | click
+ select [get-item -path View | get-item -path Control -index 1] "View/Control"
+ }
+ with [get-editbox -after [get-label Name]] {
+ set-text aaa
+ key-type "TRAVERSE_TAB_NEXT"
+ }
+}
+with [get-editor "UserGroup.view" | get-tree] {
+ get-item -path "View/aaa" | get-property caption | equals aaa | verify-true
+ get-item -path View | get-item -path aaa -index 1 | get-property caption | equals aaa | verify-true
+}
+with [get-editor "UserGroup.view"] {
+ get-tree | select "View/aaa"
+ get-editbox -after [get-label Name] | set-text x
+ get-tree | select "View/aaa" "View/x"
+}
+get-editor "UserGroup.view" | get-editbox -after [get-label Name] | get-property text | equals "" | verify-true
+with [get-editor "UserGroup.view"] {
+ get-tree | select "View/x"
+ get-editbox -after [get-label Name] | set-text aaa
+ get-tree | select [get-item -path View | get-item -path aaa -index 1] "View/aaa"
+}
+get-editor "UserGroup.view" | get-editbox -after [get-label Name] | get-property text | equals aaa | verify-true
+with [get-editor "UserGroup.view"] {
+ get-combo -after [get-label "Label Alignment*"] | select Top
+ get-tree | select "View/aaa"
+}
+get-editor "UserGroup.view" | get-combo -after [get-label "Label Alignment*"] | get-property selection | equals Top
+ | verify-true
+get-editor "UserGroup.view" | get-tree | select [get-item -path View | get-item -path aaa -index 1]
+get-editor "UserGroup.view" | get-combo -after [get-label "Label Alignment*"] | get-property selection | equals Top
+ | verify-true
+------=_.content-0a7243a0-75d3-3d5f-9791-539de0e5b7ac--