diff options
| author | pguilet | 2017-07-24 12:20:23 +0000 |
|---|---|---|
| committer | Pierre Guilet | 2017-08-03 07:51:20 +0000 |
| commit | ecadab994e07292d8babbb78efc3c277de9a4356 (patch) | |
| tree | 12fb324785d711d3c23c8e06e7f85b7dcf638a33 | |
| parent | a8295012e10299b30dbbe3f9be6f696504bf1dbc (diff) | |
| download | org.eclipse.sirius-ecadab994e07292d8babbb78efc3c277de9a4356.tar.gz org.eclipse.sirius-ecadab994e07292d8babbb78efc3c277de9a4356.tar.xz org.eclipse.sirius-ecadab994e07292d8babbb78efc3c277de9a4356.zip | |
[518524] Add tests and fix bugs
- Add tests for extensibility
- Fix a bug where custom pages placed regarding non existing pages
caused NPE
- Fix debug page duplicating when resource set event occurs.
Bug: 518524
Change-Id: Ie9d5c8134c3b6f33e8b5944ef1d4fe58da17f9e9
Signed-off-by: pguilet <pierre.guilet@obeo.fr>
11 files changed, 1584 insertions, 76 deletions
diff --git a/plugins/org.eclipse.sirius.tests.junit/META-INF/MANIFEST.MF b/plugins/org.eclipse.sirius.tests.junit/META-INF/MANIFEST.MF index 05a6640866..07c9058d55 100644 --- a/plugins/org.eclipse.sirius.tests.junit/META-INF/MANIFEST.MF +++ b/plugins/org.eclipse.sirius.tests.junit/META-INF/MANIFEST.MF @@ -77,7 +77,8 @@ Require-Bundle: org.eclipse.sirius.tests.sample.benchmark, org.eclipse.sirius.diagram.formatdata;bundle-version="4.1.0", org.eclipse.sirius.ext.emf.edit;bundle-version="4.1.0", org.eclipse.ui.editors, - org.eclipse.emf.ecore + org.eclipse.emf.ecore, + org.eclipse.sirius.ui.editor;bundle-version="5.1.0" Bundle-Activator: org.eclipse.sirius.tests.SiriusTestsPlugin Eclipse-LazyStart: true Bundle-Localization: plugin diff --git a/plugins/org.eclipse.sirius.tests.junit/src/org/eclipse/sirius/tests/suite/common/AllCommonPluginTests.java b/plugins/org.eclipse.sirius.tests.junit/src/org/eclipse/sirius/tests/suite/common/AllCommonPluginTests.java index e3d1ad99bb..e90de9ba0f 100644 --- a/plugins/org.eclipse.sirius.tests.junit/src/org/eclipse/sirius/tests/suite/common/AllCommonPluginTests.java +++ b/plugins/org.eclipse.sirius.tests.junit/src/org/eclipse/sirius/tests/suite/common/AllCommonPluginTests.java @@ -13,6 +13,7 @@ package org.eclipse.sirius.tests.suite.common; import org.eclipse.core.runtime.Platform; import org.eclipse.emf.ecore.EcorePackage; import org.eclipse.sirius.ext.jface.viewers.IToolTipProvider; +import org.eclipse.sirius.tests.unit.airdeditor.PageOrdererTest; import org.eclipse.sirius.tests.unit.api.componentization.DiagramComponentizationManagerTest; import org.eclipse.sirius.tests.unit.api.componentization.DiagramExtensionDescriptionTest; import org.eclipse.sirius.tests.unit.api.componentization.MetamodelSpecificationInRepresentationExtensionDescriptionTest; @@ -146,6 +147,7 @@ import org.eclipse.sirius.tests.unit.diagram.migration.RgbValuesEDataTypeMigrati import org.eclipse.sirius.tests.unit.diagram.migration.RunRepairTest; import org.eclipse.sirius.tests.unit.diagram.migration.SetVersionTest; import org.eclipse.sirius.tests.unit.diagram.migration.SnapBackDistantLabelsMigrationTest; +import org.eclipse.sirius.tests.unit.multipageeditor.SessionEditorTest; import org.eclipse.sirius.tests.unit.multipageeditor.SiriusMultiPageEditorTest; import org.eclipse.sirius.tests.unit.perf.common.CommonPreferencesTest; import org.eclipse.sirius.tests.unit.perf.common.Session1MillionTests; @@ -331,11 +333,13 @@ public class AllCommonPluginTests extends TestCase { suite.addTestSuite(SubMenusPrioritiesTest.class); suite.addTestSuite(ZombieViewpointsTest.class); suite.addTestSuite(DAnnotationTest.class); + + suite.addTestSuite(PageOrdererTest.class); + suite.addTestSuite(SessionEditorTest.class); } /** - * Add the tests which for one reason or another are not part of the suite - * launched on each Gerrit verification. + * Add the tests which for one reason or another are not part of the suite launched on each Gerrit verification. * * @param suite * the suite to add the tests into. diff --git a/plugins/org.eclipse.sirius.tests.junit/src/org/eclipse/sirius/tests/unit/airdeditor/AbstractSessionEditorTest.java b/plugins/org.eclipse.sirius.tests.junit/src/org/eclipse/sirius/tests/unit/airdeditor/AbstractSessionEditorTest.java new file mode 100644 index 0000000000..a3d6111455 --- /dev/null +++ b/plugins/org.eclipse.sirius.tests.junit/src/org/eclipse/sirius/tests/unit/airdeditor/AbstractSessionEditorTest.java @@ -0,0 +1,263 @@ +/******************************************************************************* + * Copyright (c) 2017 Obeo + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Obeo - initial API and implementation + *******************************************************************************/ +package org.eclipse.sirius.tests.unit.airdeditor; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.function.Function; +import java.util.function.Supplier; + +import org.eclipse.emf.transaction.ResourceSetChangeEvent; +import org.eclipse.sirius.business.internal.resource.AirDResourceImpl; +import org.eclipse.sirius.tests.support.api.SiriusTestCase; +import org.eclipse.sirius.tools.api.command.ICommandFactory; +import org.eclipse.sirius.ui.editor.SessionEditor; +import org.eclipse.sirius.ui.editor.SessionEditorPlugin; +import org.eclipse.sirius.ui.editor.api.pages.AbstractSessionEditorPage; +import org.eclipse.sirius.ui.editor.api.pages.PageProvider; +import org.eclipse.sirius.ui.editor.api.pages.PageProviderRegistry; +import org.eclipse.sirius.ui.editor.api.pages.PageProviderRegistry.PositioningKind; +import org.eclipse.sirius.ui.editor.api.pages.PageUpdateCommandBuilder.PageUpdateCommand; + +/** + * This abstract class provides methods to initialize test context for aird editor extensibility testing. + * + * @author <a href="mailto:pierre.guilet@obeo.fr">Pierre Guilet</a> + * + */ +public class AbstractSessionEditorTest extends SiriusTestCase { + /** + * This enum is used to synchronize the page creation/removal/update conditions between the static call from + * {@link PageProvider} and the dynamic call from the methods {@link AbstractSessionEditorPage#pageChanged(boolean)} + * and {@link AbstractSessionEditorPage#resourceSetChanged(ResourceSetChangeEvent)}. + * + * @author <a href="mailto:pierre.guilet@obeo.fr">Pierre Guilet</a> + * + */ + protected enum CommandSynchronization { + VISIBILITY_SYNCHRONIZATION, RESOURCE_SET_CHANGE_SYNCHRONIZATION, BOTH_SYNCHRONIZATION + + } + + protected PageProviderRegistry pageRegistry; + + protected SessionEditor sessionEditor; + + protected static final String PAGE2_ID = "page2"; // $NON-NLS-N$ + + protected static final String PAGE3_ID = "page3"; // $NON-NLS-N$ + + protected static final String PAGE4_ID = "page4"; // $NON-NLS-N$ + + protected List<PageProviderExtension> pageProviders; + + protected Map<String, AbstractSessionEditorPage> idToPageMap; + + /** + * Test page that can have its display conditions parameterized as well as the dynamic update it can provides with + * methods {@link AbstractSessionEditorPage#resourceSetChanged(ResourceSetChangeEvent)} and + * {@link AbstractSessionEditorPage#pageChanged(boolean)}. + * + * @author <a href="mailto:pierre.guilet@obeo.fr">Pierre Guilet</a> + * + */ + protected final class AbstractAirdEditorCustomPageExtension extends AbstractSessionEditorPage { + private PositioningKind positioningKind; + + private String targetPageId; + + private Function<Boolean, Optional<PageUpdateCommand>> updateWhenVisibleSupplier; + + private Supplier<Optional<PageUpdateCommand>> updateWhenChangedSupplier; + + private CommandSynchronization commandSynchronization; + + private AbstractAirdEditorCustomPageExtension(String id, String title, PositioningKind positioningKind, String targetPageId) { + super(sessionEditor, id, title); + this.positioningKind = positioningKind; + this.targetPageId = targetPageId; + } + + public AbstractAirdEditorCustomPageExtension(String id, String title, PositioningKind positioningKind, String targetPageId, + Function<Boolean, Optional<PageUpdateCommand>> updateWhenVisibleSupplier, Supplier<Optional<PageUpdateCommand>> updateWhenChangedSupplier, + CommandSynchronization commandSynchronization) { + this(id, title, positioningKind, targetPageId); + this.updateWhenVisibleSupplier = updateWhenVisibleSupplier; + this.updateWhenChangedSupplier = updateWhenChangedSupplier; + this.commandSynchronization = commandSynchronization; + } + + @Override + public Optional<String> getLocationId() { + if (commandSynchronization != null && updateWhenChangedSupplier != null + && !AirDResourceImpl.class.getName().equals(sessionEditor.getSession().getTransactionalEditingDomain().getResourceSet().getResources().get(0).getClass().getName())) { + return Optional.of(updateWhenChangedSupplier.get().get().getReorderCommand().getTargetPageId()); + } + return targetPageId == null ? Optional.empty() : Optional.of(targetPageId); + } + + @Override + public Optional<PositioningKind> getPositioning() { + if (commandSynchronization != null && updateWhenChangedSupplier != null + && !AirDResourceImpl.class.getName().equals(sessionEditor.getSession().getTransactionalEditingDomain().getResourceSet().getResources().get(0).getClass().getName())) { + return Optional.of(updateWhenChangedSupplier.get().get().getReorderCommand().getPositioningKind()); + } + return positioningKind == null ? Optional.empty() : Optional.of(positioningKind); + } + + @Override + public Optional<PageUpdateCommand> resourceSetChanged(ResourceSetChangeEvent resourceSetChangeEvent) { + if ((CommandSynchronization.RESOURCE_SET_CHANGE_SYNCHRONIZATION == commandSynchronization || CommandSynchronization.BOTH_SYNCHRONIZATION == commandSynchronization) + && AirDResourceImpl.class.getName().equals(sessionEditor.getSession().getTransactionalEditingDomain().getResourceSet().getResources().get(0).getClass().getName())) { + return updateWhenChangedSupplier.get(); + } else { + return updateWhenChangedSupplier == null ? Optional.empty() : updateWhenChangedSupplier.get(); + } + } + + @Override + public Optional<PageUpdateCommand> pageChanged(boolean isVisible) { + if ((CommandSynchronization.VISIBILITY_SYNCHRONIZATION == commandSynchronization || CommandSynchronization.BOTH_SYNCHRONIZATION == commandSynchronization) && isVisible + && !AirDResourceImpl.class.getName().equals(sessionEditor.getSession().getTransactionalEditingDomain().getResourceSet().getResources().get(0).getClass().getName())) { + return updateWhenVisibleSupplier.apply(isVisible); + } else if (commandSynchronization == null) { + return updateWhenVisibleSupplier == null ? Optional.empty() : updateWhenVisibleSupplier.apply(isVisible); + } + return Optional.empty(); + } + } + + /** + * Page provider allowing to create a page that can have its display condition parameterized. + * + * @author <a href="mailto:pierre.guilet@obeo.fr">Pierre Guilet</a> + * + */ + protected final class PageProviderExtension extends PageProvider { + + private String newPageId; + + private PositioningKind positioningKind; + + private String targetPageId; + + private Function<Boolean, Optional<PageUpdateCommand>> updateWhenVisibleSupplier; + + private Supplier<Optional<PageUpdateCommand>> updateWhenChangedSupplier; + + private CommandSynchronization commandSynchronization; + + public PageProviderExtension(PositioningKind positioningKind, String targetPageId, String newPageId) { + this.positioningKind = positioningKind; + this.targetPageId = targetPageId; + this.newPageId = newPageId; + } + + public PageProviderExtension(PositioningKind positioningKind, String targetPageId, String newPageId, Function<Boolean, Optional<PageUpdateCommand>> updateWhenVisibleSupplier, + Supplier<Optional<PageUpdateCommand>> updateWhenChangedSupplier, CommandSynchronization commandSynchronization) { + this(positioningKind, targetPageId, newPageId); + this.updateWhenVisibleSupplier = updateWhenVisibleSupplier; + this.updateWhenChangedSupplier = updateWhenChangedSupplier; + this.commandSynchronization = commandSynchronization; + } + + @Override + public boolean provides(String pageId) { + return this.newPageId.equals(pageId); + } + + @Override + public Map<String, Supplier<AbstractSessionEditorPage>> getPages(SessionEditor editor) { + Map<String, Supplier<AbstractSessionEditorPage>> resultMap = new HashMap<>(); + if (commandSynchronization == null || (commandSynchronization != null + && AirDResourceImpl.class.getName().equals(sessionEditor.getSession().getTransactionalEditingDomain().getResourceSet().getResources().get(0).getClass().getName()))) { + resultMap.put(this.newPageId, () -> { + AbstractAirdEditorCustomPageExtension newPage = new AbstractAirdEditorCustomPageExtension(this.newPageId, this.newPageId, positioningKind, targetPageId, updateWhenVisibleSupplier, + updateWhenChangedSupplier, commandSynchronization); + idToPageMap.put(this.newPageId, newPage); + return newPage; + }); + } + return resultMap; + } + } + + @Override + public void setUp() throws Exception { + super.setUp(); + pageProviders = new ArrayList<PageProviderExtension>(); + pageRegistry = SessionEditorPlugin.getPlugin().getPageRegistry(); + idToPageMap = new HashMap<String, AbstractSessionEditorPage>(); + } + + /** + * Initialize a page provider providing one page. + * + * @param positioningKind + * the positioning of the page provided. + * @param targetPageId + * the id of the page taken in consideration when positioning the page provided. + * @param newPageId + * the id of the page produced by the provider. + */ + protected void initOnePageProvider(PositioningKind positioningKind, String targetPageId, String newPageId) { + PageProviderExtension pageProviderExtension = new PageProviderExtension(positioningKind, targetPageId, newPageId); + pageProviders.add(pageProviderExtension); + pageRegistry.addPageProvider(pageProviderExtension); + } + + protected void initOnePageProvider(PositioningKind positioningKind, String targetPageId, String newPageId, Function<Boolean, Optional<PageUpdateCommand>> updateWhenVisibleSupplier, + Supplier<Optional<PageUpdateCommand>> updateWhenChangedSupplier, CommandSynchronization commandSynchronization) { + PageProviderExtension pageProviderExtension = new PageProviderExtension(positioningKind, targetPageId, newPageId, updateWhenVisibleSupplier, updateWhenChangedSupplier, commandSynchronization); + pageProviders.add(pageProviderExtension); + pageRegistry.addPageProvider(pageProviderExtension); + } + + protected void initTwoPageProvider(PositioningKind positioningKind1, String pageId1, String newPageId1, PositioningKind positioningKind2, String pageId2, String newPageId2) { + PageProviderExtension pageProviderExtension1 = new PageProviderExtension(positioningKind1, pageId1, newPageId1); + PageProviderExtension pageProviderExtension2 = new PageProviderExtension(positioningKind2, pageId2, newPageId2); + pageProviders.add(pageProviderExtension1); + pageRegistry.addPageProvider(pageProviderExtension1); + pageProviders.add(pageProviderExtension2); + pageRegistry.addPageProvider(pageProviderExtension2); + } + + protected void initThreePageProvider(PositioningKind positioningKind1, String pageId1, String newPageId1, PositioningKind positioningKind2, String pageId2, String newPageId2, + PositioningKind positioningKind3, String pageId3, String newPageId3) { + PageProviderExtension pageProviderExtension1 = new PageProviderExtension(positioningKind1, pageId1, newPageId1); + PageProviderExtension pageProviderExtension2 = new PageProviderExtension(positioningKind2, pageId2, newPageId2); + PageProviderExtension pageProviderExtension3 = new PageProviderExtension(positioningKind3, pageId3, newPageId3); + pageProviders.add(pageProviderExtension1); + pageRegistry.addPageProvider(pageProviderExtension1); + pageProviders.add(pageProviderExtension2); + pageRegistry.addPageProvider(pageProviderExtension2); + pageProviders.add(pageProviderExtension3); + pageRegistry.addPageProvider(pageProviderExtension3); + } + + @Override + protected void tearDown() throws Exception { + for (PageProviderExtension pageProviderExtension : pageProviders) { + pageRegistry.removePageProvider(pageProviderExtension); + } + idToPageMap.clear(); + + super.tearDown(); + } + + @Override + protected ICommandFactory getCommandFactory() { + return null; + } +} diff --git a/plugins/org.eclipse.sirius.tests.junit/src/org/eclipse/sirius/tests/unit/airdeditor/PageOrdererTest.java b/plugins/org.eclipse.sirius.tests.junit/src/org/eclipse/sirius/tests/unit/airdeditor/PageOrdererTest.java new file mode 100644 index 0000000000..de42b0a5e2 --- /dev/null +++ b/plugins/org.eclipse.sirius.tests.junit/src/org/eclipse/sirius/tests/unit/airdeditor/PageOrdererTest.java @@ -0,0 +1,359 @@ +/******************************************************************************* + * Copyright (c) 2017 Obeo + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Obeo - initial API and implementation + *******************************************************************************/ +package org.eclipse.sirius.tests.unit.airdeditor; + +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; + +import org.eclipse.sirius.ui.editor.SessionEditor; +import org.eclipse.sirius.ui.editor.api.pages.AbstractSessionEditorPage; +import org.eclipse.sirius.ui.editor.api.pages.DefaultSessionEditorPage; +import org.eclipse.sirius.ui.editor.api.pages.PageProviderRegistry.PositioningKind; + +/** + * Tests the component {@link PageRegistry} + * + * @author <a href="mailto:pierre.guilet@obeo.fr">Pierre Guilet</a> + * + */ +public class PageOrdererTest extends AbstractSessionEditorTest { + + @Override + public void setUp() throws Exception { + super.setUp(); + sessionEditor = new SessionEditor(); + } + + /** + * Asserts that computed pages order have the right order. + * + * @param expectedTotalPagesNumber + * @param orderedExpectedPages + */ + protected void assertRightPageOrdering(int expectedTotalPagesNumber, String... orderedExpectedPages) { + List<AbstractSessionEditorPage> pagesOrdered = pageRegistry.getPagesOrdered(sessionEditor, null, new ArrayList<>(), null); + Optional<AbstractSessionEditorPage> defaultPage = pagesOrdered.stream().filter(DefaultSessionEditorPage.class::isInstance).findFirst(); + if (defaultPage.isPresent()) { + idToPageMap.put(DefaultSessionEditorPage.PAGE_ID, defaultPage.get()); + } + int i = 0; + for (String expectedPageId : orderedExpectedPages) { + assertEquals("The page order is wrong.", idToPageMap.get(expectedPageId), pagesOrdered.get(i)); + i++; + } + assertEquals("The number of page in the editor is wrong.", expectedTotalPagesNumber, pagesOrdered.size()); + } + + /** + * Test {@link PositioningKind#BEFORE} positioning: + * + * There are the default page "Overview". We add a page before the default one. + */ + public void testPageOrderingBefore() { + initOnePageProvider(PositioningKind.BEFORE, DefaultSessionEditorPage.PAGE_ID, PAGE2_ID); + assertRightPageOrdering(2, PAGE2_ID, DefaultSessionEditorPage.PAGE_ID); + } + + /** + * Tests that when a page is placed after a page that does not exists, then it is added to the end. + * + * We have the default page P1 and we add a page P2 before a page P3 that does not exist. + * + * Result should be P1,P2. + */ + public void testPageOrderingBeforeMissingPage() { + initOnePageProvider(PositioningKind.BEFORE, PAGE3_ID, PAGE2_ID); + assertRightPageOrdering(2, DefaultSessionEditorPage.PAGE_ID, PAGE2_ID); + } + + /** + * Tests that when a page is placed after a page that does not exists, then it is added to the end. + * + * We have the default page P1 and we add a page P2 after a page P3 that does not exist. + * + * Result should be P1,P2. + */ + public void testPageOrderingAfterMissingPage() { + initOnePageProvider(PositioningKind.AFTER, PAGE3_ID, PAGE2_ID); + assertRightPageOrdering(2, DefaultSessionEditorPage.PAGE_ID, PAGE2_ID); + } + + /** + * Tests that when a page is placed after a page that does not exists, then it is added to the end. + * + * We have the default page P1 and we add a page P2 that replaces a page P3 that does not exist. + * + * Result should be P1,P2. + */ + public void testPageOrderingReplaceMissingPage() { + initOnePageProvider(PositioningKind.REPLACE, PAGE3_ID, PAGE2_ID); + assertRightPageOrdering(2, DefaultSessionEditorPage.PAGE_ID, PAGE2_ID); + } + + /** + * Test {@link PositioningKind#AFTER} positioning: + * + * There are the default page "Overview". We add a page after the default one. + */ + public void testPageOrderingAfter() { + initOnePageProvider(PositioningKind.AFTER, DefaultSessionEditorPage.PAGE_ID, PAGE2_ID); + assertRightPageOrdering(2, DefaultSessionEditorPage.PAGE_ID, PAGE2_ID); + } + + /** + * Test {@link PositioningKind#REPLACE} positioning: + * + * There are the default page "Overview". We add a page that replaces the default one. + */ + public void testPageOrderingReplacement() { + initOnePageProvider(PositioningKind.REPLACE, DefaultSessionEditorPage.PAGE_ID, PAGE2_ID); + assertRightPageOrdering(1, PAGE2_ID); + } + + /** + * Test positioning when no positioning is provided by the added page: + * + * There are the default page "Overview". We add a page without positioning information that is put at the most + * right position. + */ + public void testPageOrderingNoPositioning() { + initOnePageProvider(null, DefaultSessionEditorPage.PAGE_ID, PAGE2_ID); + assertRightPageOrdering(2, DefaultSessionEditorPage.PAGE_ID, PAGE2_ID); + } + + /** + * Test positioning when no positioning is provided by the added page: + * + * There are the default page "Overview". We add two pages without positioning information that are put at the most + * right position. + */ + public void testMultiPageOrderingNoPositioning() { + initTwoPageProvider(null, DefaultSessionEditorPage.PAGE_ID, PAGE2_ID, null, DefaultSessionEditorPage.PAGE_ID, PAGE3_ID); + assertRightPageOrdering(3, DefaultSessionEditorPage.PAGE_ID, PAGE2_ID, PAGE3_ID); + } + + /** + * Test page positioning : + * + * There are the default page "Overview". + * + * One page P2 is placed after the default one P1. + * + * Another page P3 is provided and is placed before P2. + * + * The page order should be P1, P3, P2. + */ + public void testMultiPageOrderingBeforeConflict() { + initTwoPageProvider(PositioningKind.AFTER, DefaultSessionEditorPage.PAGE_ID, PAGE2_ID, PositioningKind.BEFORE, PAGE2_ID, PAGE3_ID); + assertRightPageOrdering(3, DefaultSessionEditorPage.PAGE_ID, PAGE3_ID, PAGE2_ID); + } + + /** + * Test page positioning : + * + * There are the default page "Overview". + * + * One page P2 is placed before the default one P1. + * + * Another page P3 is provided and is placed after P2. + * + * The page order should be P2, P3, P1. + */ + public void testMultiPageOrderingAfterFirstPage() { + initTwoPageProvider(PositioningKind.BEFORE, DefaultSessionEditorPage.PAGE_ID, PAGE2_ID, PositioningKind.AFTER, PAGE2_ID, PAGE3_ID); + assertRightPageOrdering(3, PAGE2_ID, PAGE3_ID, DefaultSessionEditorPage.PAGE_ID); + } + + /** + * Test page positioning : + * + * There are the default page "Overview" P1. + * + * One page P2 is placed after the default one P1. + * + * Another page P3 is provided and is placed after P1 also. + * + * The page order should be P1,P3,P2. + */ + public void testMultiPageOrderingAfterConflict() { + initTwoPageProvider(PositioningKind.AFTER, DefaultSessionEditorPage.PAGE_ID, PAGE2_ID, PositioningKind.AFTER, DefaultSessionEditorPage.PAGE_ID, PAGE3_ID); + assertRightPageOrdering(3, DefaultSessionEditorPage.PAGE_ID, PAGE3_ID, PAGE2_ID); + } + + /** + * Test page positioning : + * + * There are the default page "Overview" P1. + * + * One page P2 is placed before the default one P1. + * + * Another page P3 is placed after P2. + * + * The page order should be P1,P3,P2. + */ + public void testMultiPageOrderingAfterConflict2() { + initTwoPageProvider(PositioningKind.BEFORE, DefaultSessionEditorPage.PAGE_ID, PAGE2_ID, PositioningKind.AFTER, PAGE2_ID, PAGE3_ID); + assertRightPageOrdering(3, PAGE2_ID, PAGE3_ID, DefaultSessionEditorPage.PAGE_ID); + } + + /** + * Test page positioning : + * + * There are the default page "Overview" P1. + * + * One page P2 is placed before the default one P1. + * + * Another page P3 is provided and is placed before P1 also. + * + * The page order should be P2,P3,P1. + */ + public void testMultiPageOrderingBeforeConflict2() { + initTwoPageProvider(PositioningKind.BEFORE, DefaultSessionEditorPage.PAGE_ID, PAGE2_ID, PositioningKind.BEFORE, DefaultSessionEditorPage.PAGE_ID, PAGE3_ID); + assertRightPageOrdering(3, PAGE2_ID, PAGE3_ID, DefaultSessionEditorPage.PAGE_ID); + } + + /** + * Test page positioning : + * + * There are the default page "Overview" P1. + * + * One page P2 replaces the default one P1. + * + * Another page P3 replaces P1 also. + * + * The page order should be P2,P3 because P2 replace P1 and P3 has no P1 to replace after P2 replacement. + */ + public void testMultiPageOrderingReplaceConflict() { + initTwoPageProvider(PositioningKind.REPLACE, DefaultSessionEditorPage.PAGE_ID, PAGE2_ID, PositioningKind.REPLACE, DefaultSessionEditorPage.PAGE_ID, PAGE3_ID); + assertRightPageOrdering(2, PAGE2_ID, PAGE3_ID); + } + + /** + * Test page positioning : + * + * There are the default page "Overview" P1. + * + * One page P2 replaces the default one P1. + * + * Another page P3 replaces P2. + * + * The page order should be P3 only. + */ + public void testMultiPageOrderingReplace() { + initTwoPageProvider(PositioningKind.REPLACE, DefaultSessionEditorPage.PAGE_ID, PAGE2_ID, PositioningKind.REPLACE, PAGE2_ID, PAGE3_ID); + assertRightPageOrdering(1, PAGE3_ID); + } + + /** + * Test page positioning : + * + * There are the default page "Overview" P1. + * + * One page P2 is placed before the default one P1. + * + * Another page P3 is placed before P2. + * + * The page order should be P3,P2,P1. + */ + public void testMultiPageOrderingBefore() { + initTwoPageProvider(PositioningKind.BEFORE, DefaultSessionEditorPage.PAGE_ID, PAGE2_ID, PositioningKind.BEFORE, PAGE2_ID, PAGE3_ID); + assertRightPageOrdering(3, PAGE3_ID, PAGE2_ID, DefaultSessionEditorPage.PAGE_ID); + } + + /** + * Test page positioning : + * + * There are the default page "Overview" P1. + * + * One page P2 is placed after the default one P1. + * + * Another page P3 is placed after P2. + * + * The page order should be P1, P2, P3. + */ + public void testMultiPageOrderingAfter() { + initTwoPageProvider(PositioningKind.AFTER, DefaultSessionEditorPage.PAGE_ID, PAGE2_ID, PositioningKind.AFTER, PAGE2_ID, PAGE3_ID); + assertRightPageOrdering(3, DefaultSessionEditorPage.PAGE_ID, PAGE2_ID, PAGE3_ID); + } + + /** + * Test page positioning : + * + * There are the default page "Overview" P1. + * + * One page P2 has no positioning information. + * + * Another page P3 is placed before P1. + * + * The page order should be P3, P1, P2. + */ + public void testMultiPageOrderingNoPositioningAndBefore() { + initTwoPageProvider(null, DefaultSessionEditorPage.PAGE_ID, PAGE2_ID, PositioningKind.BEFORE, DefaultSessionEditorPage.PAGE_ID, PAGE3_ID); + assertRightPageOrdering(3, PAGE3_ID, DefaultSessionEditorPage.PAGE_ID, PAGE2_ID); + } + + /** + * Test page positioning : + * + * There are the default page "Overview" P1. + * + * One page P2 is placed after P3. + * + * Another page P3 is placed before P1. + * + * The page order should be P3, P1, P2. + */ + public void testMultiPageOrderingConflict() { + initTwoPageProvider(null, DefaultSessionEditorPage.PAGE_ID, PAGE2_ID, PositioningKind.BEFORE, DefaultSessionEditorPage.PAGE_ID, PAGE3_ID); + assertRightPageOrdering(3, PAGE3_ID, DefaultSessionEditorPage.PAGE_ID, PAGE2_ID); + } + + /** + * Test page positioning : + * + * There are the default page "Overview" P1. + * + * One page P2 is placed before P1 + * + * Another page P3 is not placed. + * + * Another page P4 is placed before P3. + * + * We have two independent cluster {P4, P3} and {P2, P1}. + * + * The page order should be P4, P3, P2, P1. + */ + public void testMultiPageOrderingClustering() { + initThreePageProvider(PositioningKind.BEFORE, DefaultSessionEditorPage.PAGE_ID, PAGE2_ID, null, null, PAGE3_ID, PositioningKind.BEFORE, PAGE3_ID, PAGE4_ID); + assertRightPageOrdering(4, PAGE4_ID, PAGE3_ID, PAGE2_ID, DefaultSessionEditorPage.PAGE_ID); + } + + /** + * Test page positioning : + * + * There are the default page "Overview" P1. + * + * One page P2 is not placed + * + * Another page P3 is placed before P1. + * + * Another page P4 is placed before P3. + * + * We have two independent cluster {P4, P3, P1} and {P2}. + * + * The page order should be P4, P3, P1, P2. + */ + public void testMultiPageOrderingClustering2() { + initThreePageProvider(null, null, PAGE2_ID, PositioningKind.BEFORE, DefaultSessionEditorPage.PAGE_ID, PAGE3_ID, PositioningKind.BEFORE, PAGE3_ID, PAGE4_ID); + assertRightPageOrdering(4, PAGE4_ID, PAGE3_ID, DefaultSessionEditorPage.PAGE_ID, PAGE2_ID); + } +} diff --git a/plugins/org.eclipse.sirius.tests.junit/src/org/eclipse/sirius/tests/unit/multipageeditor/SessionEditorTest.java b/plugins/org.eclipse.sirius.tests.junit/src/org/eclipse/sirius/tests/unit/multipageeditor/SessionEditorTest.java new file mode 100644 index 0000000000..3b9aaad6c0 --- /dev/null +++ b/plugins/org.eclipse.sirius.tests.junit/src/org/eclipse/sirius/tests/unit/multipageeditor/SessionEditorTest.java @@ -0,0 +1,849 @@ +/******************************************************************************* + * Copyright (c) 2017 Obeo. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Obeo - initial API and implementation + *******************************************************************************/ +package org.eclipse.sirius.tests.unit.multipageeditor; + +import java.lang.reflect.Field; +import java.util.List; +import java.util.Optional; + +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Path; +import org.eclipse.emf.common.util.URI; +import org.eclipse.emf.transaction.RunnableWithResult; +import org.eclipse.sirius.business.internal.resource.AirDResourceImpl; +import org.eclipse.sirius.tests.SiriusTestsPlugin; +import org.eclipse.sirius.tests.unit.airdeditor.AbstractSessionEditorTest; +import org.eclipse.sirius.ui.editor.SessionEditor; +import org.eclipse.sirius.ui.editor.api.pages.AbstractSessionEditorPage; +import org.eclipse.sirius.ui.editor.api.pages.DefaultSessionEditorPage; +import org.eclipse.sirius.ui.editor.api.pages.PageProvider; +import org.eclipse.sirius.ui.editor.api.pages.PageProviderRegistry.PositioningKind; +import org.eclipse.sirius.ui.editor.api.pages.PageUpdateCommandBuilder; +import org.eclipse.swt.custom.CTabFolder; +import org.eclipse.swt.custom.CTabItem; +import org.eclipse.ui.IEditorPart; +import org.eclipse.ui.PartInitException; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.forms.editor.IFormPage; +import org.eclipse.ui.part.FileEditorInput; +import org.eclipse.ui.part.MultiPageEditorPart; + +/** + * This class tests the {@link SessionEditor} page extensibility functionality from the UI point of view. + * + * Warning: the plugin org.eclipse.sirius.ui.debug must be not in runtime so the tests can work. + * + * @author <a href="mailto:pierre.guilet@obeo.fr">Pierre Guilet</a> + * + */ +public class SessionEditorTest extends AbstractSessionEditorTest { + + private static final String NEW_LABEL_INVISIBLE = "newLabelInvisible"; + + private static final String NEW_LABEL_VISIBLE = "newLabelVisible"; + + private static final String UPDATED_PAGE_LABEL = "newLabel"; + + private static final String PAGE2_TAB_LABEL = "page2"; + + private static final String DEFAULT_PAGE_TAB_LABEL = "Overview"; + + public static final String PATH = "/data/unit/layoutingMode/"; + + private static final String SEMANTIC_MODEL_FILENAME = "vp2120.ecore"; + + private static final String MODELER_MODEL_FILENAME = "vp2120.odesign"; + + private static final String SESSION_PATH = "vp2120.aird"; + + @Override + public void setUp() throws Exception { + super.setUp(); + copyFilesToTestProject(SiriusTestsPlugin.PLUGIN_ID, PATH, SEMANTIC_MODEL_FILENAME, MODELER_MODEL_FILENAME, SESSION_PATH); + genericSetUp(TEMPORARY_PROJECT_NAME + "/" + SEMANTIC_MODEL_FILENAME, TEMPORARY_PROJECT_NAME + "/" + MODELER_MODEL_FILENAME, TEMPORARY_PROJECT_NAME + "/" + SESSION_PATH); + RunnableWithResult<IEditorPart> result = new RunnableWithResult<IEditorPart>() { + private IEditorPart resultEditor; + + @Override + public void run() { + URI uri = session.getSessionResource().getURI(); + try { + resultEditor = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage() + .openEditor(new FileEditorInput(ResourcesPlugin.getWorkspace().getRoot().getFile(new Path(uri.toPlatformString(true)))), SessionEditor.EDITOR_ID); + } catch (PartInitException e) { + throw new RuntimeException(e); + } + } + + @Override + public IEditorPart getResult() { + return resultEditor; + } + + @Override + public void setStatus(IStatus status) { + + } + + @Override + public IStatus getStatus() { + return null; + } + }; + PlatformUI.getWorkbench().getDisplay().syncExec(result); + sessionEditor = (SessionEditor) result.getResult(); + assertEquals("There should be only the default page after initialization.", 1, sessionEditor.getPages().size()); + idToPageMap.put(DefaultSessionEditorPage.PAGE_ID, (AbstractSessionEditorPage) sessionEditor.getPages().get(0)); + } + + /* + * (non-Javadoc) + * @see org.eclipse.sirius.tests.unit.airdeditor.AbstractSessionEditorTest#tearDown() + */ + @Override + protected void tearDown() throws Exception { + sessionEditor.close(false); + super.tearDown(); + + } + + private CTabItem[] getPageTabItems(SessionEditor sessionEditor) { + Field f; + try { + f = MultiPageEditorPart.class.getDeclaredField("container"); + + f.setAccessible(true); + CTabFolder tabFolder = (CTabFolder) f.get(sessionEditor); + return tabFolder.getItems(); + } catch (NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException e) { + throw new RuntimeException(e); + } + } + + /** + * Asserts that computed pages order have the right order by testing tab labels. + * + * @param expectedTotalPagesNumber + * @param orderedExpectedPages + */ + protected void assertRightPageOrderingByLabel(int expectedTotalPagesNumber, String... orderedExpectedPages) { + List<IFormPage> pagesOrdered = sessionEditor.getPages(); + CTabItem[] pageItems = getPageTabItems(sessionEditor); + int i = 0; + for (String expectedPageTabLAbel : orderedExpectedPages) { + assertEquals("The test context is wrong", expectedPageTabLAbel, pageItems[i].getText()); + i++; + } + assertEquals("The number of page in the editor is wrong.", expectedTotalPagesNumber, pageItems.length); + assertEquals("The number of page in the editor is wrong.", expectedTotalPagesNumber, pagesOrdered.size()); + } + + /** + * Asserts that computed pages order have the right order. + * + * @param expectedTotalPagesNumber + * @param orderedExpectedPages + */ + protected void assertRightPageOrdering(int expectedTotalPagesNumber, String... orderedExpectedPages) { + List<IFormPage> pagesOrdered = sessionEditor.getPages(); + int i = 0; + for (String expectedPageId : orderedExpectedPages) { + assertEquals("The page order is wrong.", idToPageMap.get(expectedPageId), pagesOrdered.get(i)); + i++; + } + CTabItem[] pageItems = getPageTabItems(sessionEditor); + assertEquals("The number of page in the editor is wrong.", expectedTotalPagesNumber, pageItems.length); + assertEquals("The number of page in the editor is wrong.", expectedTotalPagesNumber, pagesOrdered.size()); + } + + /** + * Test {@link PositioningKind#BEFORE} positioning: + * + * There are the default page "Overview". We add a page before the default one. + */ + public void testPageOrderingBefore() { + initOnePageProvider(PositioningKind.BEFORE, DefaultSessionEditorPage.PAGE_ID, PAGE2_ID); + assertRightPageOrdering(2, PAGE2_ID, DefaultSessionEditorPage.PAGE_ID); + } + + /** + * Tests that when a page is placed after a page that does not exists, then it is added to the end. + * + * We have the default page P1 and we add a page P2 before a page P3 that does not exist. + * + * Result should be P1,P2. + */ + public void testPageOrderingBeforeMissingPage() { + initOnePageProvider(PositioningKind.BEFORE, PAGE3_ID, PAGE2_ID); + assertRightPageOrdering(2, DefaultSessionEditorPage.PAGE_ID, PAGE2_ID); + } + + /** + * Tests that when a page is placed after a page that does not exists, then it is added to the end. + * + * We have the default page P1 and we add a page P2 after a page P3 that does not exist. + * + * Result should be P1,P2. + */ + public void testPageOrderingAfterMissingPage() { + initOnePageProvider(PositioningKind.AFTER, PAGE3_ID, PAGE2_ID); + assertRightPageOrdering(2, DefaultSessionEditorPage.PAGE_ID, PAGE2_ID); + } + + /** + * Tests that when a page is placed after a page that does not exists, then it is added to the end. + * + * We have the default page P1 and we add a page P2 that replaces a page P3 that does not exist. + * + * Result should be P1,P2. + */ + public void testPageOrderingReplaceMissingPage() { + initOnePageProvider(PositioningKind.REPLACE, PAGE3_ID, PAGE2_ID); + assertRightPageOrdering(2, DefaultSessionEditorPage.PAGE_ID, PAGE2_ID); + } + + /** + * Test {@link PositioningKind#AFTER} positioning: + * + * There are the default page "Overview". We add a page after the default one. + */ + public void testPageOrderingAfter() { + initOnePageProvider(PositioningKind.AFTER, DefaultSessionEditorPage.PAGE_ID, PAGE2_ID); + assertRightPageOrdering(2, DefaultSessionEditorPage.PAGE_ID, PAGE2_ID); + } + + /** + * Test {@link PositioningKind#REPLACE} positioning: + * + * There are the default page "Overview". We add a page that replaces the default one. + */ + public void testPageOrderingReplacement() { + initOnePageProvider(PositioningKind.REPLACE, DefaultSessionEditorPage.PAGE_ID, PAGE2_ID); + assertRightPageOrdering(1, PAGE2_ID); + } + + /** + * Test positioning when no positioning is provided by the added page: + * + * There are the default page "Overview". We add a page without positioning information that is put at the most + * right position. + */ + public void testPageOrderingNoPositioning() { + initOnePageProvider(null, DefaultSessionEditorPage.PAGE_ID, PAGE2_ID); + assertRightPageOrdering(2, DefaultSessionEditorPage.PAGE_ID, PAGE2_ID); + } + + /** + * Test positioning when no positioning is provided by the added page: + * + * There are the default page "Overview". We add two pages without positioning information that are put at the most + * right position. + */ + public void testMultiPageOrderingNoPositioning() { + initTwoPageProvider(null, DefaultSessionEditorPage.PAGE_ID, PAGE2_ID, null, DefaultSessionEditorPage.PAGE_ID, PAGE3_ID); + assertRightPageOrdering(3, DefaultSessionEditorPage.PAGE_ID, PAGE2_ID, PAGE3_ID); + } + + /** + * Test page positioning : + * + * There are the default page "Overview". + * + * One page P2 is placed after the default one P1. + * + * Another page P3 is provided and is placed before P2. + * + * The page order should be P1, P3, P2. + */ + public void testMultiPageOrderingBeforeConflict() { + initTwoPageProvider(PositioningKind.AFTER, DefaultSessionEditorPage.PAGE_ID, PAGE2_ID, PositioningKind.BEFORE, PAGE2_ID, PAGE3_ID); + assertRightPageOrdering(3, DefaultSessionEditorPage.PAGE_ID, PAGE3_ID, PAGE2_ID); + } + + /** + * Test page positioning : + * + * There are the default page "Overview". + * + * One page P2 is placed before the default one P1. + * + * Another page P3 is provided and is placed after P2. + * + * The page order should be P2, P3, P1. + */ + public void testMultiPageOrderingAfterFirstPage() { + initTwoPageProvider(PositioningKind.BEFORE, DefaultSessionEditorPage.PAGE_ID, PAGE2_ID, PositioningKind.AFTER, PAGE2_ID, PAGE3_ID); + assertRightPageOrdering(3, PAGE2_ID, PAGE3_ID, DefaultSessionEditorPage.PAGE_ID); + } + + /** + * Test page positioning : + * + * There are the default page "Overview" P1. + * + * One page P2 is placed after the default one P1. + * + * Another page P3 is provided and is placed after P1 also. + * + * The page order should be P1,P3,P2. + */ + public void testMultiPageOrderingAfterConflict() { + initTwoPageProvider(PositioningKind.AFTER, DefaultSessionEditorPage.PAGE_ID, PAGE2_ID, PositioningKind.AFTER, DefaultSessionEditorPage.PAGE_ID, PAGE3_ID); + assertRightPageOrdering(3, DefaultSessionEditorPage.PAGE_ID, PAGE3_ID, PAGE2_ID); + } + + /** + * Test page positioning : + * + * There are the default page "Overview" P1. + * + * One page P2 is placed before the default one P1. + * + * Another page P3 is placed after P2. + * + * The page order should be P1,P3,P2. + */ + public void testMultiPageOrderingAfterConflict2() { + initTwoPageProvider(PositioningKind.BEFORE, DefaultSessionEditorPage.PAGE_ID, PAGE2_ID, PositioningKind.AFTER, PAGE2_ID, PAGE3_ID); + assertRightPageOrdering(3, PAGE2_ID, PAGE3_ID, DefaultSessionEditorPage.PAGE_ID); + } + + /** + * Test page positioning : + * + * There are the default page "Overview" P1. + * + * One page P2 is placed before the default one P1. + * + * Another page P3 is provided and is placed before P1 also. + * + * The page order should be P2,P3,P1. + */ + public void testMultiPageOrderingBeforeConflict2() { + initTwoPageProvider(PositioningKind.BEFORE, DefaultSessionEditorPage.PAGE_ID, PAGE2_ID, PositioningKind.BEFORE, DefaultSessionEditorPage.PAGE_ID, PAGE3_ID); + assertRightPageOrdering(3, PAGE2_ID, PAGE3_ID, DefaultSessionEditorPage.PAGE_ID); + } + + /** + * Test page positioning : + * + * There are the default page "Overview" P1. + * + * One page P2 replaces the default one P1. + * + * Another page P3 replaces P1 also. + * + * The page order should be P2,P3 because P2 replace P1 and P3 has no P1 to replace after P2 replacement. + */ + public void testMultiPageOrderingReplaceConflict() { + initTwoPageProvider(PositioningKind.REPLACE, DefaultSessionEditorPage.PAGE_ID, PAGE2_ID, PositioningKind.REPLACE, DefaultSessionEditorPage.PAGE_ID, PAGE3_ID); + assertRightPageOrdering(2, PAGE2_ID, PAGE3_ID); + } + + /** + * Test page positioning : + * + * There are the default page "Overview" P1. + * + * One page P2 replaces the default one P1. + * + * Another page P3 replaces P2. + * + * The page order should be P3 only. + */ + public void testMultiPageOrderingReplace() { + initTwoPageProvider(PositioningKind.REPLACE, DefaultSessionEditorPage.PAGE_ID, PAGE2_ID, PositioningKind.REPLACE, PAGE2_ID, PAGE3_ID); + assertRightPageOrdering(1, PAGE3_ID); + } + + /** + * Test page positioning : + * + * There are the default page "Overview" P1. + * + * One page P2 is placed before the default one P1. + * + * Another page P3 is placed before P2. + * + * The page order should be P3,P2,P1. + */ + public void testMultiPageOrderingBefore() { + initTwoPageProvider(PositioningKind.BEFORE, DefaultSessionEditorPage.PAGE_ID, PAGE2_ID, PositioningKind.BEFORE, PAGE2_ID, PAGE3_ID); + assertRightPageOrdering(3, PAGE3_ID, PAGE2_ID, DefaultSessionEditorPage.PAGE_ID); + } + + /** + * Test page positioning : + * + * There are the default page "Overview" P1. + * + * One page P2 is placed after the default one P1. + * + * Another page P3 is placed after P2. + * + * The page order should be P1, P2, P3. + */ + public void testMultiPageOrderingAfter() { + initTwoPageProvider(PositioningKind.AFTER, DefaultSessionEditorPage.PAGE_ID, PAGE2_ID, PositioningKind.AFTER, PAGE2_ID, PAGE3_ID); + assertRightPageOrdering(3, DefaultSessionEditorPage.PAGE_ID, PAGE2_ID, PAGE3_ID); + } + + /** + * Test page positioning : + * + * There are the default page "Overview" P1. + * + * One page P2 has no positioning information. + * + * Another page P3 is placed before P1. + * + * The page order should be P3, P1, P2. + */ + public void testMultiPageOrderingNoPositioningAndBefore() { + initTwoPageProvider(null, DefaultSessionEditorPage.PAGE_ID, PAGE2_ID, PositioningKind.BEFORE, DefaultSessionEditorPage.PAGE_ID, PAGE3_ID); + assertRightPageOrdering(3, PAGE3_ID, DefaultSessionEditorPage.PAGE_ID, PAGE2_ID); + } + + /** + * Test page positioning : + * + * There are the default page "Overview" P1. + * + * One page P2 is placed after P3. + * + * Another page P3 is placed before P1. + * + * The page order should be P3, P1, P2. + */ + public void testMultiPageOrderingConflict() { + initTwoPageProvider(null, DefaultSessionEditorPage.PAGE_ID, PAGE2_ID, PositioningKind.BEFORE, DefaultSessionEditorPage.PAGE_ID, PAGE3_ID); + assertRightPageOrdering(3, PAGE3_ID, DefaultSessionEditorPage.PAGE_ID, PAGE2_ID); + } + + /** + * Test page positioning : + * + * There are the default page "Overview" P1. + * + * One page P2 is placed before P1 + * + * Another page P3 is not placed. + * + * Another page P4 is placed before P3. + * + * We have two independent cluster {P4, P3} and {P2, P1}. + * + * The page order should be P4, P3, P2, P1. + */ + public void testMultiPageOrderingClustering() { + initThreePageProvider(PositioningKind.BEFORE, DefaultSessionEditorPage.PAGE_ID, PAGE2_ID, null, null, PAGE3_ID, PositioningKind.BEFORE, PAGE3_ID, PAGE4_ID); + assertRightPageOrdering(4, PAGE4_ID, PAGE3_ID, PAGE2_ID, DefaultSessionEditorPage.PAGE_ID); + } + + /** + * Test page positioning : + * + * There are the default page "Overview" P1. + * + * One page P2 is not placed + * + * Another page P3 is placed before P1. + * + * Another page P4 is placed before P3. + * + * We have two independent cluster {P4, P3, P1} and {P2}. + * + * The page order should be P4, P3, P1, P2. + */ + public void testMultiPageOrderingClustering2() { + initThreePageProvider(null, null, PAGE2_ID, PositioningKind.BEFORE, DefaultSessionEditorPage.PAGE_ID, PAGE3_ID, PositioningKind.BEFORE, PAGE3_ID, PAGE4_ID); + assertRightPageOrdering(4, PAGE4_ID, PAGE3_ID, DefaultSessionEditorPage.PAGE_ID, PAGE2_ID); + } + + /** + * Test page positioning : + * + * We add a page by adding a {@link PageProvider}. Then we remove the page provider from the registry. The page + * should be removed. + */ + public void testPageProviderRemoval() { + initOnePageProvider(PositioningKind.AFTER, DefaultSessionEditorPage.PAGE_ID, PAGE2_ID); + assertRightPageOrdering(2, DefaultSessionEditorPage.PAGE_ID, PAGE2_ID); + + pageRegistry.removePageProvider(pageProviders.get(0)); + + assertRightPageOrdering(1, DefaultSessionEditorPage.PAGE_ID); + } + + /** + * Test page positioning : + * + * A page has its tab label updated each time the session's resource set is updated. This tests the rename is done + * correctly. + */ + public void testDynamicPageRenameUpdate() { + initOnePageProvider(PositioningKind.AFTER, DefaultSessionEditorPage.PAGE_ID, PAGE2_ID, null, () -> { + return Optional.of(new PageUpdateCommandBuilder().renameTab(UPDATED_PAGE_LABEL).build()); + }, null); + + assertRightPageOrderingByLabel(2, DEFAULT_PAGE_TAB_LABEL, PAGE2_TAB_LABEL); + + sessionEditor.getSession().getTransactionalEditingDomain().getResourceSet().getResources().remove(0); + + assertRightPageOrderingByLabel(2, DEFAULT_PAGE_TAB_LABEL, UPDATED_PAGE_LABEL); + + sessionEditor.getSession().getTransactionalEditingDomain().getResourceSet().getResources().remove(0); + + assertRightPageOrderingByLabel(2, DEFAULT_PAGE_TAB_LABEL, UPDATED_PAGE_LABEL); + + } + + /** + * Test page positioning : + * + * A page has its tab label set to newLabelVisible when the page is made visible and newLabelInvisible when it is + * made not visible. + */ + public void testDynamicPageRenameVisibilityUpdate() { + initOnePageProvider(PositioningKind.AFTER, DefaultSessionEditorPage.PAGE_ID, PAGE2_ID, (isVisible) -> { + if (isVisible) { + return Optional.of(new PageUpdateCommandBuilder().renameTab(NEW_LABEL_VISIBLE).build()); + } else { + return Optional.of(new PageUpdateCommandBuilder().renameTab(NEW_LABEL_INVISIBLE).build()); + } + }, null, null); + + assertRightPageOrderingByLabel(2, DEFAULT_PAGE_TAB_LABEL, PAGE2_TAB_LABEL); + + sessionEditor.setActivePage(PAGE2_ID); + + assertRightPageOrderingByLabel(2, DEFAULT_PAGE_TAB_LABEL, NEW_LABEL_VISIBLE); + + sessionEditor.setActivePage(PAGE2_ID); + + assertRightPageOrderingByLabel(2, DEFAULT_PAGE_TAB_LABEL, NEW_LABEL_VISIBLE); + + sessionEditor.setActivePage(0); + + assertRightPageOrderingByLabel(2, DEFAULT_PAGE_TAB_LABEL, NEW_LABEL_INVISIBLE); + + sessionEditor.setActivePage(0); + + assertRightPageOrderingByLabel(2, DEFAULT_PAGE_TAB_LABEL, NEW_LABEL_INVISIBLE); + } + + /** + * Test page positioning : + * + * A page is removed when any change occurs from session's resource set. But the page provider has no condition + * preventing its initialization when called. The page visibility is not synchronized between page and page + * provider. + * + * So just after the removal, the page should be added again. + */ + public void testDynamicPageRemovalDesynchroUpdate() { + initOnePageProvider(PositioningKind.AFTER, DefaultSessionEditorPage.PAGE_ID, PAGE2_ID, null, () -> { + return Optional.of(new PageUpdateCommandBuilder().removePage().build()); + }, null); + + assertRightPageOrderingByLabel(2, DEFAULT_PAGE_TAB_LABEL, PAGE2_TAB_LABEL); + + sessionEditor.getSession().getTransactionalEditingDomain().getResourceSet().getResources().remove(0); + + assertRightPageOrderingByLabel(2, DEFAULT_PAGE_TAB_LABEL, PAGE2_TAB_LABEL); + } + + /** + * Test page positioning : + * + * A page is removed when the {@link AirDResourceImpl} resource is removed. The page provider and the page method + * {@link AbstractSessionEditorPage#resourceSetChanged(org.eclipse.emf.transaction.ResourceSetChangeEvent)} are + * synchronized. I.e if the page is removed dynamically, the page provider update will not provide the page again + * The page removal condition is the the exact contrary of the page providing condition. + */ + public void testDynamicPageRemovalUpdate() { + initOnePageProvider(PositioningKind.AFTER, DefaultSessionEditorPage.PAGE_ID, PAGE2_ID, null, () -> { + return Optional.of(new PageUpdateCommandBuilder().removePage().build()); + }, CommandSynchronization.RESOURCE_SET_CHANGE_SYNCHRONIZATION); + + assertRightPageOrderingByLabel(2, DEFAULT_PAGE_TAB_LABEL, PAGE2_TAB_LABEL); + + sessionEditor.getSession().getTransactionalEditingDomain().getResourceSet().getResources().remove(0); + + assertRightPageOrderingByLabel(1, DEFAULT_PAGE_TAB_LABEL); + + sessionEditor.getSession().getTransactionalEditingDomain().getResourceSet().getResources().remove(0); + + assertRightPageOrderingByLabel(1, DEFAULT_PAGE_TAB_LABEL); + } + + /** + * Test page positioning : + * + * A page is removed when the {@link AirDResourceImpl} resource is removed and the page is visible. The page + * provider and the page method {@link AbstractSessionEditorPage#pageChanged(boolean)} are synchronized. I.e if the + * page is removed dynamically, the page provider update will not provide the page again The page removal condition + * is the the exact contrary of the page providing condition. + */ + public void testDynamicPageRemovalVisibilityUpdate() { + initOnePageProvider(PositioningKind.AFTER, DefaultSessionEditorPage.PAGE_ID, PAGE2_ID, (isVisible) -> { + return Optional.of(new PageUpdateCommandBuilder().removePage().build()); + }, null, CommandSynchronization.VISIBILITY_SYNCHRONIZATION); + + assertRightPageOrderingByLabel(2, DEFAULT_PAGE_TAB_LABEL, PAGE2_TAB_LABEL); + + sessionEditor.setActivePage(0); + + assertRightPageOrderingByLabel(2, DEFAULT_PAGE_TAB_LABEL, PAGE2_TAB_LABEL); + + sessionEditor.setActivePage(PAGE2_ID); + + assertRightPageOrderingByLabel(2, DEFAULT_PAGE_TAB_LABEL, PAGE2_TAB_LABEL); + + sessionEditor.getSession().getTransactionalEditingDomain().getResourceSet().getResources().remove(0); + + assertRightPageOrderingByLabel(2, DEFAULT_PAGE_TAB_LABEL, PAGE2_TAB_LABEL); + + sessionEditor.setActivePage(0); + + assertRightPageOrderingByLabel(2, DEFAULT_PAGE_TAB_LABEL, PAGE2_TAB_LABEL); + + sessionEditor.setActivePage(PAGE2_ID); + + assertRightPageOrderingByLabel(1, DEFAULT_PAGE_TAB_LABEL); + } + + /** + * Test page positioning : + * + * A page is reordered before the default one when the {@link AirDResourceImpl} resource is removed. The method + * {@link AbstractSessionEditorPage#getPositioning()} is synchronized with the method + * {@link AbstractSessionEditorPage#resourceSetChanged(org.eclipse.emf.transaction.ResourceSetChangeEvent)} doing + * the removal. So the page reorder information when called from a resource set changed are the same than the page + * positioning from methods {@link AbstractSessionEditorPage#getPositioning()} and + * {@link AbstractSessionEditorPage#getLocationId()} + */ + public void testDynamicPageReorderUpdate() { + initOnePageProvider(PositioningKind.AFTER, DefaultSessionEditorPage.PAGE_ID, PAGE2_ID, null, () -> { + return Optional.of(new PageUpdateCommandBuilder().reorderPage(PositioningKind.BEFORE, DefaultSessionEditorPage.PAGE_ID).build()); + }, CommandSynchronization.RESOURCE_SET_CHANGE_SYNCHRONIZATION); + + assertRightPageOrderingByLabel(2, DEFAULT_PAGE_TAB_LABEL, PAGE2_TAB_LABEL); + + sessionEditor.getSession().getTransactionalEditingDomain().getResourceSet().getResources().remove(0); + + assertRightPageOrderingByLabel(2, PAGE2_TAB_LABEL, DEFAULT_PAGE_TAB_LABEL); + + sessionEditor.getSession().getTransactionalEditingDomain().getResourceSet().getResources().remove(0); + + assertRightPageOrderingByLabel(2, PAGE2_TAB_LABEL, DEFAULT_PAGE_TAB_LABEL); + } + + /** + * Test page positioning : + * + * The default page is reordered after another page when the {@link AirDResourceImpl} resource is removed. The + * method {@link AbstractSessionEditorPage#getPositioning()} is synchronized with the method + * {@link AbstractSessionEditorPage#resourceSetChanged(org.eclipse.emf.transaction.ResourceSetChangeEvent)} doing + * the removal. So the page reorder information when called from a resource set changed are the same than the page + * positioning from methods {@link AbstractSessionEditorPage#getPositioning()} and + * {@link AbstractSessionEditorPage#getLocationId()} + */ + public void testDynamicPageReorderUpdate2() { + initOnePageProvider(PositioningKind.BEFORE, DefaultSessionEditorPage.PAGE_ID, PAGE2_ID, null, () -> { + return Optional.of(new PageUpdateCommandBuilder().reorderPage(PositioningKind.AFTER, DefaultSessionEditorPage.PAGE_ID).build()); + }, CommandSynchronization.RESOURCE_SET_CHANGE_SYNCHRONIZATION); + + assertRightPageOrderingByLabel(2, PAGE2_TAB_LABEL, DEFAULT_PAGE_TAB_LABEL); + + sessionEditor.getSession().getTransactionalEditingDomain().getResourceSet().getResources().remove(0); + + assertRightPageOrderingByLabel(2, DEFAULT_PAGE_TAB_LABEL, PAGE2_TAB_LABEL); + + sessionEditor.getSession().getTransactionalEditingDomain().getResourceSet().getResources().remove(0); + + assertRightPageOrderingByLabel(2, DEFAULT_PAGE_TAB_LABEL, PAGE2_TAB_LABEL); + } + + /** + * Test page positioning : + * + * The default page is reordered after another page when the {@link AirDResourceImpl} resource is removed. The + * method {@link AbstractSessionEditorPage#getPositioning()} is synchronized with the method + * {@link AbstractSessionEditorPage#resourceSetChanged(org.eclipse.emf.transaction.ResourceSetChangeEvent)} doing + * the removal. So the page reorder information when called from a resource set changed are the same than the page + * positioning from methods {@link AbstractSessionEditorPage#getPositioning()} and + * {@link AbstractSessionEditorPage#getLocationId()} + */ + public void testDynamicPageReorderUpdate3() { + initOnePageProvider(PositioningKind.BEFORE, DefaultSessionEditorPage.PAGE_ID, PAGE2_ID, null, () -> { + return Optional.of(new PageUpdateCommandBuilder().reorderPage(PositioningKind.REPLACE, DefaultSessionEditorPage.PAGE_ID).build()); + }, CommandSynchronization.RESOURCE_SET_CHANGE_SYNCHRONIZATION); + + assertRightPageOrderingByLabel(2, PAGE2_TAB_LABEL, DEFAULT_PAGE_TAB_LABEL); + + sessionEditor.getSession().getTransactionalEditingDomain().getResourceSet().getResources().remove(0); + + assertRightPageOrderingByLabel(1, PAGE2_TAB_LABEL); + + sessionEditor.getSession().getTransactionalEditingDomain().getResourceSet().getResources().remove(0); + + assertRightPageOrderingByLabel(1, PAGE2_TAB_LABEL); + } + + /** + * Test page positioning : + * + * The default page is replaced by another page when the {@link AirDResourceImpl} resource is removed and the page + * gains focus. This tests the method {@link AbstractSessionEditorPage#pageChanged(boolean)}. The page reorder + * information when called from the previous method are the same than the page positioning from methods + * {@link AbstractSessionEditorPage#getPositioning()} and {@link AbstractSessionEditorPage#getLocationId()} + */ + public void testDynamicPageReorderVisibilityUpdate() { + initOnePageProvider(PositioningKind.AFTER, DefaultSessionEditorPage.PAGE_ID, PAGE2_ID, (isVisible) -> { + return Optional.of(new PageUpdateCommandBuilder().reorderPage(PositioningKind.REPLACE, DefaultSessionEditorPage.PAGE_ID).build()); + }, null, CommandSynchronization.VISIBILITY_SYNCHRONIZATION); + + assertRightPageOrderingByLabel(2, DEFAULT_PAGE_TAB_LABEL, PAGE2_TAB_LABEL); + + sessionEditor.setActivePage(0); + + assertRightPageOrderingByLabel(2, DEFAULT_PAGE_TAB_LABEL, PAGE2_TAB_LABEL); + + sessionEditor.setActivePage(PAGE2_ID); + + assertRightPageOrderingByLabel(2, DEFAULT_PAGE_TAB_LABEL, PAGE2_TAB_LABEL); + + sessionEditor.getSession().getTransactionalEditingDomain().getResourceSet().getResources().remove(0); + + assertRightPageOrderingByLabel(2, DEFAULT_PAGE_TAB_LABEL, PAGE2_TAB_LABEL); + + sessionEditor.setActivePage(0); + + assertRightPageOrderingByLabel(2, DEFAULT_PAGE_TAB_LABEL, PAGE2_TAB_LABEL); + + sessionEditor.setActivePage(PAGE2_ID); + + assertRightPageOrderingByLabel(1, PAGE2_TAB_LABEL); + } + + /** + * Test page positioning : + * + * The default page is reordered before another page when the {@link AirDResourceImpl} resource is removed and the + * page gains focus. This tests the method {@link AbstractSessionEditorPage#pageChanged(boolean)}. The page reorder + * information when called from the previous method are the same than the page positioning from methods + * {@link AbstractSessionEditorPage#getPositioning()} and {@link AbstractSessionEditorPage#getLocationId()} + */ + public void testDynamicPageReorderVisibilityUpdate2() { + initOnePageProvider(PositioningKind.AFTER, DefaultSessionEditorPage.PAGE_ID, PAGE2_ID, (isVisible) -> { + return Optional.of(new PageUpdateCommandBuilder().reorderPage(PositioningKind.BEFORE, DefaultSessionEditorPage.PAGE_ID).build()); + }, null, CommandSynchronization.VISIBILITY_SYNCHRONIZATION); + + assertRightPageOrderingByLabel(2, DEFAULT_PAGE_TAB_LABEL, PAGE2_TAB_LABEL); + + sessionEditor.setActivePage(0); + + assertRightPageOrderingByLabel(2, DEFAULT_PAGE_TAB_LABEL, PAGE2_TAB_LABEL); + + sessionEditor.setActivePage(PAGE2_ID); + + assertRightPageOrderingByLabel(2, DEFAULT_PAGE_TAB_LABEL, PAGE2_TAB_LABEL); + + sessionEditor.getSession().getTransactionalEditingDomain().getResourceSet().getResources().remove(0); + + assertRightPageOrderingByLabel(2, DEFAULT_PAGE_TAB_LABEL, PAGE2_TAB_LABEL); + + sessionEditor.setActivePage(0); + + assertRightPageOrderingByLabel(2, DEFAULT_PAGE_TAB_LABEL, PAGE2_TAB_LABEL); + + sessionEditor.setActivePage(PAGE2_ID); + + assertRightPageOrderingByLabel(2, PAGE2_TAB_LABEL, DEFAULT_PAGE_TAB_LABEL); + } + + /** + * Test page positioning : + * + * The default page is reordered after another page when the {@link AirDResourceImpl} resource is removed and the + * page gains focus. This tests the method {@link AbstractSessionEditorPage#pageChanged(boolean)}. The page reorder + * information when called from the previous method are the same than the page positioning from methods + * {@link AbstractSessionEditorPage#getPositioning()} and {@link AbstractSessionEditorPage#getLocationId()}. + */ + public void testDynamicPageReorderVisibilityUpdate3() { + initOnePageProvider(PositioningKind.BEFORE, DefaultSessionEditorPage.PAGE_ID, PAGE2_ID, (isVisible) -> { + return Optional.of(new PageUpdateCommandBuilder().reorderPage(PositioningKind.AFTER, DefaultSessionEditorPage.PAGE_ID).build()); + }, null, CommandSynchronization.VISIBILITY_SYNCHRONIZATION); + + assertRightPageOrderingByLabel(2, PAGE2_TAB_LABEL, DEFAULT_PAGE_TAB_LABEL); + + sessionEditor.setActivePage(1); + + assertRightPageOrderingByLabel(2, PAGE2_TAB_LABEL, DEFAULT_PAGE_TAB_LABEL); + + sessionEditor.setActivePage(PAGE2_ID); + + assertRightPageOrderingByLabel(2, PAGE2_TAB_LABEL, DEFAULT_PAGE_TAB_LABEL); + + sessionEditor.getSession().getTransactionalEditingDomain().getResourceSet().getResources().remove(0); + + assertRightPageOrderingByLabel(2, PAGE2_TAB_LABEL, DEFAULT_PAGE_TAB_LABEL); + + sessionEditor.setActivePage(1); + + assertRightPageOrderingByLabel(2, PAGE2_TAB_LABEL, DEFAULT_PAGE_TAB_LABEL); + + sessionEditor.setActivePage(PAGE2_ID); + + assertRightPageOrderingByLabel(2, DEFAULT_PAGE_TAB_LABEL, PAGE2_TAB_LABEL); + } + + /** + * Test page positioning : + * + * The methods + * {@link AbstractSessionEditorPage#resourceSetChanged(org.eclipse.emf.transaction.ResourceSetChangeEvent)} and + * {@link AbstractSessionEditorPage#pageChanged(boolean)} reorder the page after and before the default one + * respectively when {@link AirDResourceImpl} is removed and when the page is set visible. + */ + public void testBothDynamicPageUpdate() { + initOnePageProvider(PositioningKind.BEFORE, DefaultSessionEditorPage.PAGE_ID, PAGE2_ID, (isVisible) -> { + return Optional.of(new PageUpdateCommandBuilder().reorderPage(PositioningKind.BEFORE, DefaultSessionEditorPage.PAGE_ID).build()); + }, () -> { + return Optional.of(new PageUpdateCommandBuilder().reorderPage(PositioningKind.AFTER, DefaultSessionEditorPage.PAGE_ID).build()); + }, CommandSynchronization.BOTH_SYNCHRONIZATION); + + assertRightPageOrderingByLabel(2, PAGE2_TAB_LABEL, DEFAULT_PAGE_TAB_LABEL); + + sessionEditor.setActivePage(1); + + assertRightPageOrderingByLabel(2, PAGE2_TAB_LABEL, DEFAULT_PAGE_TAB_LABEL);; + + sessionEditor.setActivePage(PAGE2_ID); + + assertRightPageOrderingByLabel(2, PAGE2_TAB_LABEL, DEFAULT_PAGE_TAB_LABEL); + + sessionEditor.getSession().getTransactionalEditingDomain().getResourceSet().getResources().remove(0); + + assertRightPageOrderingByLabel(2, DEFAULT_PAGE_TAB_LABEL, PAGE2_TAB_LABEL); + + sessionEditor.setActivePage(0); + + assertRightPageOrderingByLabel(2, DEFAULT_PAGE_TAB_LABEL, PAGE2_TAB_LABEL); + + sessionEditor.setActivePage(PAGE2_ID); + + assertRightPageOrderingByLabel(2, PAGE2_TAB_LABEL, DEFAULT_PAGE_TAB_LABEL); + } + +} diff --git a/plugins/org.eclipse.sirius.ui.editor/plugin.properties b/plugins/org.eclipse.sirius.ui.editor/plugin.properties index d8c5ca2c0c..c64ca1dd4b 100644 --- a/plugins/org.eclipse.sirius.ui.editor/plugin.properties +++ b/plugins/org.eclipse.sirius.ui.editor/plugin.properties @@ -44,3 +44,4 @@ SessionEditor_PageCommand_Integrity_Error=Some page update commands from page {0 PluginPageProviderRegistry_classInitialization=The PageProvider class ''{0}'' could not be initialized. PluginPageProviderRegistry_badClassType=The class ''{0}'' provided by the extension to extension point ''org.eclipse.sirius.ui.editor.airdEditoPageProvider'' is not an instance of ''org.eclipse.sirius.ui.editor.api.pages.PageProvider'' SessionEditor_PageCommand_Integrity_Error=Some page update commands from page {0} were ignored because a remove command was executed first and thus no update cannot be done anymore. +SessionEditor_PageActivation_Failure=Page activation cannot be done because the given page ''{0}'' is not present in the editor. diff --git a/plugins/org.eclipse.sirius.ui.editor/src/org/eclipse/sirius/ui/editor/Messages.java b/plugins/org.eclipse.sirius.ui.editor/src/org/eclipse/sirius/ui/editor/Messages.java index 672f279fe9..faa703b2d8 100644 --- a/plugins/org.eclipse.sirius.ui.editor/src/org/eclipse/sirius/ui/editor/Messages.java +++ b/plugins/org.eclipse.sirius.ui.editor/src/org/eclipse/sirius/ui/editor/Messages.java @@ -106,6 +106,9 @@ public final class Messages { @TranslatableMessage public static String PluginPageProviderRegistry_badClassType; + @TranslatableMessage + public static String SessionEditor_PageActivation_Failure; + // CHECKSTYLE:ON private Messages() { diff --git a/plugins/org.eclipse.sirius.ui.editor/src/org/eclipse/sirius/ui/editor/SessionEditor.java b/plugins/org.eclipse.sirius.ui.editor/src/org/eclipse/sirius/ui/editor/SessionEditor.java index 7e673e6aba..ce73ea6174 100644 --- a/plugins/org.eclipse.sirius.ui.editor/src/org/eclipse/sirius/ui/editor/SessionEditor.java +++ b/plugins/org.eclipse.sirius.ui.editor/src/org/eclipse/sirius/ui/editor/SessionEditor.java @@ -173,7 +173,7 @@ public class SessionEditor extends SharedHeaderFormEditor implements ITabbedProp pages.stream().filter(AbstractSessionEditorPage.class::isInstance).map(AbstractSessionEditorPage.class::cast).collect(Collectors.toList()), event); CTabFolder cTabF = (CTabFolder) this.getContainer(); - IFormPage activePage = getActivePageInstance(); + IFormPage lastActivePage = getActivePageInstance(); for (int i = 0; i < newOrderedPages.size(); i++) { AbstractSessionEditorPage page = newOrderedPages.get(i); int pageIndex = pages.indexOf(page); @@ -194,13 +194,26 @@ public class SessionEditor extends SharedHeaderFormEditor implements ITabbedProp if (newOrderedPages.size() < pages.size()) { // obsolete pages must be removed. for (int i = newOrderedPages.size(); i < pages.size(); i++) { + if (lastActivePage.equals(pages.get(i))) { + lastActivePage = null; + } removePage(i); - } } cTabF.getParent().layout(); - setActivePage(activePage); + if (getActivePageInstance() == null && lastActivePage != null) { + setActivePage(lastActivePage); + } + } + + /** + * Returns the pages this editor displays. + * + * @return the pages this editor displays. + */ + public List<IFormPage> getPages() { + return pages.stream().filter(IFormPage.class::isInstance).map(IFormPage.class::cast).collect(Collectors.toList()); } /** @@ -258,9 +271,46 @@ public class SessionEditor extends SharedHeaderFormEditor implements ITabbedProp if (activePage != null) { int activePageIndex = pages.indexOf(activePage); if (activePageIndex != -1) { - this.setActivePage(activePageIndex); + setActivePage(activePageIndex); + } else { + SessionEditorPlugin.getPlugin().error(MessageFormat.format(Messages.SessionEditor_PageActivation_Failure, activePage.getClass().getName()), null); + } + } + } + + /** + * Set the currently active page. + * + * @param pageIndex + * the index of the page to set as the active page of this + * editor. + */ + @Override + public void setActivePage(int pageIndex) { + // we notifies all pages the change of page visibility. + Object pageToSelect = pages.get(pageIndex); + if (pageToSelect instanceof AbstractSessionEditorPage) { + AbstractSessionEditorPage theSelectedPage = (AbstractSessionEditorPage) pageToSelect; + Optional<PageUpdateCommand> selectedPageCommand = theSelectedPage.pageChanged(true); + List<Runnable> commandsToExecute = new ArrayList<>(); + commandsToExecute.addAll(prepareUpdateCommands(theSelectedPage, selectedPageCommand)); + for (Object page : pages) { + if (page instanceof AbstractSessionEditorPage) { + AbstractSessionEditorPage sessionEditorPage = (AbstractSessionEditorPage) page; + if (sessionEditorPage.getIndex() != theSelectedPage.getIndex()) { + Optional<PageUpdateCommand> pageCommand = sessionEditorPage.pageChanged(false); + commandsToExecute.addAll(prepareUpdateCommands(sessionEditorPage, pageCommand)); + } + } + } + commandsToExecute.stream().forEach(Runnable::run); + + getContainer().getParent().layout(); + int selectedPageIndex = pages.indexOf(pageToSelect); + if (selectedPageIndex > -1) { + super.setActivePage(selectedPageIndex); } else { - this.setActivePage(0); + super.setActivePage(0); } } } @@ -273,25 +323,6 @@ public class SessionEditor extends SharedHeaderFormEditor implements ITabbedProp @Override public void init(IEditorSite site, IEditorInput input) throws PartInitException { super.init(site, input); - this.addPageChangedListener(event -> { - Object selectedPage = event.getSelectedPage(); - if (selectedPage instanceof AbstractSessionEditorPage) { - AbstractSessionEditorPage theSelectedPage = (AbstractSessionEditorPage) selectedPage; - Optional<PageUpdateCommand> selectedPageCommand = theSelectedPage.pageChanged(true); - List<Runnable> commandsToExecute = new ArrayList<>(); - commandsToExecute.addAll(prepareUpdateCommands(theSelectedPage, selectedPageCommand)); - for (Object page : pages) { - if (page instanceof AbstractSessionEditorPage) { - AbstractSessionEditorPage sessionEditorPage = (AbstractSessionEditorPage) page; - if (sessionEditorPage.getIndex() != theSelectedPage.getIndex()) { - Optional<PageUpdateCommand> pageCommand = sessionEditorPage.pageChanged(false); - commandsToExecute.addAll(prepareUpdateCommands(sessionEditorPage, pageCommand)); - } - } - } - commandsToExecute.stream().forEach(Runnable::run); - } - }); IEditorInput editorInput = this.getEditorInput(); URI sessionResourceURI = null; if (editorInput instanceof FileEditorInput) { @@ -370,11 +401,6 @@ public class SessionEditor extends SharedHeaderFormEditor implements ITabbedProp @Override public void dispose() { - super.dispose(); - if (pageRegistry != null) { - pageRegistry.removeRegistryListener(this); - pageRegistry = null; - } if (resourceSetListener != null && session != null && session.getTransactionalEditingDomain() != null) { session.getTransactionalEditingDomain().removeResourceSetListener(resourceSetListener); resourceSetListener = null; @@ -383,7 +409,6 @@ public class SessionEditor extends SharedHeaderFormEditor implements ITabbedProp final IEditingSession editingSession = SessionUIManager.INSTANCE.getUISession(session); if (editingSession != null) { editingSession.detachEditor(this, choice == ISaveablePart2.NO); - } if (session.getTransactionalEditingDomain() != null) { session.getTransactionalEditingDomain().getCommandStack().removeCommandStackListener(listener); @@ -391,6 +416,16 @@ public class SessionEditor extends SharedHeaderFormEditor implements ITabbedProp } session = null; propertySheetPage = null; + super.dispose(); + } + + @Override + public void close(boolean save) { + if (pageRegistry != null) { + pageRegistry.removeRegistryListener(this); + pageRegistry = null; + } + super.close(save); } @Override @@ -520,12 +555,12 @@ public class SessionEditor extends SharedHeaderFormEditor implements ITabbedProp } if (!removeCommandExecuted && updateCommandTemp.getReorderCommand() != null) { runnables.add(prepareReorderCommand(updateCommandTemp.getReorderCommand(), SessionEditor.this, customPage)); - } else { + } else if (updateCommandTemp.getReorderCommand() != null) { SessionEditorPlugin.getPlugin().error(MessageFormat.format(Messages.SessionEditor_PageCommand_Integrity_Error, customPage.getClass().getName()), null); } if (!removeCommandExecuted && updateCommandTemp.getRenameCommand() != null) { runnables.add(prepareRenameCommand(updateCommandTemp.getRenameCommand(), SessionEditor.this, customPage)); - } else { + } else if (updateCommandTemp.getRenameCommand() != null) { SessionEditorPlugin.getPlugin().error(MessageFormat.format(Messages.SessionEditor_PageCommand_Integrity_Error, customPage.getClass().getName()), null); } }); @@ -547,7 +582,6 @@ public class SessionEditor extends SharedHeaderFormEditor implements ITabbedProp Composite container = editor.getContainer(); if (container instanceof CTabFolder) { CTabFolder tabFolder = (CTabFolder) editor.getContainer(); - IFormPage activePage = editor.getActivePageInstance(); int targetPageIndex = -1; String targetPageId = pageUpdateCommand.getTargetPageId(); for (Object object : pages) { @@ -579,10 +613,6 @@ public class SessionEditor extends SharedHeaderFormEditor implements ITabbedProp break; } } - tabFolder.getParent().redraw(); - tabFolder.getParent().layout(); - editor.setFocus(); - editor.setActivePage(activePage); } }; } @@ -594,7 +624,7 @@ public class SessionEditor extends SharedHeaderFormEditor implements ITabbedProp * @param pageUpdateCommand * the command containing removal information. * @param editor - * the editor calling for a page removal.. + * the editor calling for a page removal. * @param page * the page that will be removed from editor. */ @@ -625,7 +655,6 @@ public class SessionEditor extends SharedHeaderFormEditor implements ITabbedProp CTabFolder tabFolder = (CTabFolder) container; CTabItem tabItem = tabFolder.getItem(index); tabItem.setText(pageUpdateCommand.getNewLabel()); - tabFolder.getParent().layout(); } } }; diff --git a/plugins/org.eclipse.sirius.ui.editor/src/org/eclipse/sirius/ui/editor/api/pages/DefaultSessionEditorPage.java b/plugins/org.eclipse.sirius.ui.editor/src/org/eclipse/sirius/ui/editor/api/pages/DefaultSessionEditorPage.java index eac346ead5..7901e1146f 100644 --- a/plugins/org.eclipse.sirius.ui.editor/src/org/eclipse/sirius/ui/editor/api/pages/DefaultSessionEditorPage.java +++ b/plugins/org.eclipse.sirius.ui.editor/src/org/eclipse/sirius/ui/editor/api/pages/DefaultSessionEditorPage.java @@ -50,8 +50,8 @@ import org.eclipse.ui.IEditorSite; import org.eclipse.ui.PartInitException; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.forms.IManagedForm; +import org.eclipse.ui.forms.events.HyperlinkAdapter; import org.eclipse.ui.forms.events.HyperlinkEvent; -import org.eclipse.ui.forms.events.IHyperlinkListener; import org.eclipse.ui.forms.widgets.FormText; import org.eclipse.ui.forms.widgets.FormToolkit; import org.eclipse.ui.forms.widgets.ScrolledForm; @@ -153,16 +153,7 @@ public class DefaultSessionEditorPage extends AbstractSessionEditorPage implemen body.setLayout(GridLayoutFactory.swtDefaults().create()); informativeLabel = toolkit.createFormText(body, false); - informativeLabel.addHyperlinkListener(new IHyperlinkListener() { - - @Override - public void linkExited(HyperlinkEvent e) { - } - - @Override - public void linkEntered(HyperlinkEvent e) { - } - + informativeLabel.addHyperlinkListener(new HyperlinkAdapter() { @Override public void linkActivated(HyperlinkEvent e) { try { @@ -171,6 +162,7 @@ public class DefaultSessionEditorPage extends AbstractSessionEditorPage implemen SessionEditorPlugin.getPlugin().error("An error occured while opening the external web browser.", ex); //$NON-NLS-1$ } } + }); informativeLabel.setForeground(body.getDisplay().getSystemColor(SWT.COLOR_RED)); diff --git a/plugins/org.eclipse.sirius.ui.editor/src/org/eclipse/sirius/ui/editor/api/pages/PageProviderRegistry.java b/plugins/org.eclipse.sirius.ui.editor/src/org/eclipse/sirius/ui/editor/api/pages/PageProviderRegistry.java index a52d512742..477029ba38 100644 --- a/plugins/org.eclipse.sirius.ui.editor/src/org/eclipse/sirius/ui/editor/api/pages/PageProviderRegistry.java +++ b/plugins/org.eclipse.sirius.ui.editor/src/org/eclipse/sirius/ui/editor/api/pages/PageProviderRegistry.java @@ -139,7 +139,7 @@ public class PageProviderRegistry { * @param session * the aird editor's session from which page request is done. * @param displayedPages - * pages already dysplayed by the editor. + * pages already displayed by the editor. * @param event * the event triggering the call to this method. Can be null. * @return a list of {@link AbstractSessionEditorPage} in the order computed diff --git a/plugins/org.eclipse.sirius.ui.editor/src/org/eclipse/sirius/ui/editor/internal/pages/PageOrderer.java b/plugins/org.eclipse.sirius.ui.editor/src/org/eclipse/sirius/ui/editor/internal/pages/PageOrderer.java index 4a081184dd..75c1e1777b 100644 --- a/plugins/org.eclipse.sirius.ui.editor/src/org/eclipse/sirius/ui/editor/internal/pages/PageOrderer.java +++ b/plugins/org.eclipse.sirius.ui.editor/src/org/eclipse/sirius/ui/editor/internal/pages/PageOrderer.java @@ -182,12 +182,14 @@ public class PageOrderer { for (PagePositioning pagePositioning : pagePositioningElements) { if (pagePositioning.replacePortPageId != null) { PagePositioning replacedPage = pageIdToPageMap.get(pagePositioning.replacePortPageId); - pagePositioning.replacePortPage = replacedPage; - // the page replace the target. I.e it connects to target - // left and right pages. - pagePositioning.leftPortPage = pagePositioning.replacePortPage.leftPortPage; - pagePositioning.rightPortPage = pagePositioning.replacePortPage.rightPortPage; - replacedPages.add(pagePositioning.replacePortPage); + if (replacedPage != null) { + pagePositioning.replacePortPage = replacedPage; + // the page replace the target. I.e it connects to target + // left and right pages. + pagePositioning.leftPortPage = pagePositioning.replacePortPage.leftPortPage; + pagePositioning.rightPortPage = pagePositioning.replacePortPage.rightPortPage; + replacedPages.add(pagePositioning.replacePortPage); + } } } } @@ -221,27 +223,32 @@ public class PageOrderer { for (PagePositioning pagePositioning : pagePositioningElements) { if (pagePositioning.leftPortPageId != null) { PagePositioning targetPagePositioning = pageIdToPageMap.get(pagePositioning.leftPortPageId); - pagePositioning.leftPortPage = targetPagePositioning; - if (targetPagePositioning.rightPortPage != null) { - // We put this page in between the target page and the page - // already to its right. This is a conflict. - targetPagePositioning.rightPortPage.leftPortPage = pagePositioning; - pagePositioning.rightPortPage = targetPagePositioning.rightPortPage; + if (targetPagePositioning != null) { + pagePositioning.leftPortPage = targetPagePositioning; + if (targetPagePositioning.rightPortPage != null) { + // We put this page in between the target page and the + // page + // already to its right. This is a conflict. + targetPagePositioning.rightPortPage.leftPortPage = pagePositioning; + pagePositioning.rightPortPage = targetPagePositioning.rightPortPage; + } + targetPagePositioning.rightPortPage = pagePositioning; } - targetPagePositioning.rightPortPage = pagePositioning; } if (pagePositioning.rightPortPageId != null) { PagePositioning targetPagePositioning = pageIdToPageMap.get(pagePositioning.rightPortPageId); - pagePositioning.rightPortPage = targetPagePositioning; - if (targetPagePositioning.leftPortPage != null) { - // We put this page in between the target page and the page - // already to its left. This is a conflict. - targetPagePositioning.leftPortPage.rightPortPage = pagePositioning; - pagePositioning.leftPortPage = targetPagePositioning.leftPortPage; + if (targetPagePositioning != null) { + pagePositioning.rightPortPage = targetPagePositioning; + if (targetPagePositioning.leftPortPage != null) { + // We put this page in between the target page and the + // page + // already to its left. This is a conflict. + targetPagePositioning.leftPortPage.rightPortPage = pagePositioning; + pagePositioning.leftPortPage = targetPagePositioning.leftPortPage; + } + targetPagePositioning.leftPortPage = pagePositioning; } - targetPagePositioning.leftPortPage = pagePositioning; - } } } @@ -290,7 +297,7 @@ public class PageOrderer { for (Entry<String, Supplier<AbstractSessionEditorPage>> pageEntry : pagesToAdd.entrySet()) { if (!alreadyInitializedPagesId.contains(pageEntry.getKey())) { AbstractSessionEditorPage page = pageEntry.getValue().get(); - + page.initialize(editor); PagePositioning pagePositioning = new PagePositioning(); pageIdToPageMap.put(page.getId(), pagePositioning); pagePositioningElements.add(pagePositioning); |
