Skip to content

Commit

Permalink
Focus switches after closing the last editor in a part stack when a c…
Browse files Browse the repository at this point in the history
…omposite part is used

fixes eclipse-platform#951

We remove now the children of the composite part from the activation candidate calculation.
They do not need to be contained here as the activation of the composite part propagates down to its children.
  • Loading branch information
N1k145 authored and BeckerWdf committed Aug 4, 2023
1 parent b5dac3e commit 9d8703d
Show file tree
Hide file tree
Showing 7 changed files with 201 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import org.eclipse.e4.ui.model.application.ui.advanced.MArea;
import org.eclipse.e4.ui.model.application.ui.advanced.MPerspective;
import org.eclipse.e4.ui.model.application.ui.advanced.MPlaceholder;
import org.eclipse.e4.ui.model.application.ui.basic.MCompositePart;
import org.eclipse.e4.ui.model.application.ui.basic.MPart;
import org.eclipse.e4.ui.model.application.ui.basic.MWindow;
import org.eclipse.e4.ui.workbench.modeling.EModelService;
Expand Down Expand Up @@ -190,6 +191,15 @@ private MPart getActivationCandidate(MPart part) {
private MPart findActivationCandidate(Collection<MPart> candidates, MPart currentlyActivePart) {
candidates.remove(currentlyActivePart);

// If there is a composite part in the candidates, remove the child Parts
List<MPart> compositeParts = candidates.stream().filter(MCompositePart.class::isInstance).toList();
for (MPart compositePart : compositeParts) {

List<MPart> childParts = modelService.findElements(compositePart, null, MPart.class);
childParts.remove(compositePart);
candidates.removeAll(childParts);
}

MPlaceholder activePlaceholder = partService.getLocalPlaceholder(currentlyActivePart);
for (MPart candidate : candidates) {
// make sure it's rendered and visible
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import org.eclipse.e4.ui.tests.application.UIEventTypesTest;
import org.eclipse.e4.ui.tests.workbench.AreaRendererTest;
import org.eclipse.e4.ui.tests.workbench.Bug308317Test;
import org.eclipse.e4.ui.tests.workbench.CompositePartClosingTest;
import org.eclipse.e4.ui.tests.workbench.ContextTest;
import org.eclipse.e4.ui.tests.workbench.ContributionsAnalyzerTest;
import org.eclipse.e4.ui.tests.workbench.ExtensionsSortTests;
Expand Down Expand Up @@ -102,7 +103,8 @@
E4ResourceTest.class,
AreaRendererTest.class,
SWTPartRendererTest.class,
ModelServiceImplTest.class
ModelServiceImplTest.class,
CompositePartClosingTest.class
})
public class UIAllTests {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
/*******************************************************************************
* Copyright (c) 2023 IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* IBM Corporation - initial API and implementation
******************************************************************************/

package org.eclipse.e4.ui.tests.workbench;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;

import javax.inject.Inject;
import org.eclipse.e4.ui.model.application.MApplication;
import org.eclipse.e4.ui.model.application.ui.advanced.MArea;
import org.eclipse.e4.ui.model.application.ui.basic.MCompositePart;
import org.eclipse.e4.ui.model.application.ui.basic.MPart;
import org.eclipse.e4.ui.model.application.ui.basic.MPartSashContainer;
import org.eclipse.e4.ui.model.application.ui.basic.MPartStack;
import org.eclipse.e4.ui.model.application.ui.basic.MWindow;
import org.eclipse.e4.ui.tests.rules.WorkbenchContextRule;
import org.eclipse.e4.ui.workbench.modeling.EModelService;
import org.eclipse.e4.ui.workbench.modeling.EPartService;
import org.junit.Rule;
import org.junit.Test;

/**
*
*/
public class CompositePartClosingTest {

@Rule
public WorkbenchContextRule contextRule = new WorkbenchContextRule();

@Inject
private EModelService ems;

@Inject
private MApplication application;

@Inject
private EPartService partService;

@Test
public void test_partClosing() {
MWindow window = ems.createModelElement(MWindow.class);
application.getChildren().add(window);
application.setSelectedElement(window);

MArea rootArea = ems.createModelElement(MArea.class);
window.getChildren().add(rootArea);
window.setSelectedElement(rootArea);

MPartStack partStack1 = ems.createModelElement(MPartStack.class);
rootArea.getChildren().add(partStack1);
MPartStack partStack2 = ems.createModelElement(MPartStack.class);
rootArea.getChildren().add(partStack2);

MPart part1 = createPart();
MCompositePart compositePart = createCompositePart();
MPart part2 = createPart();

partStack1.getChildren().add(compositePart);
partStack1.getChildren().add(part1);
partStack1.setSelectedElement(part1);

partStack2.getChildren().add(part2);
partStack2.setSelectedElement(part2);

contextRule.createAndRunWorkbench(window);

partService.activate(part2);
partService.hidePart(part2);

assertNotEquals("Composite part got activated", compositePart, partStack1.getSelectedElement());
assertEquals("Wrong part got activated", part1, partStack1.getSelectedElement());

}

private MCompositePart createCompositePart() {

MCompositePart compositePart = ems.createModelElement(MCompositePart.class);
MPartSashContainer partSashContainer = ems.createModelElement(MPartSashContainer.class);
MPartStack partStack = ems.createModelElement(MPartStack.class);

compositePart.getChildren().add(partSashContainer);
partSashContainer.getChildren().add(partStack);
partStack.getChildren().add(createPart());
partStack.getChildren().add(createPart());

return compositePart;
}

private MPart createPart() {
MPart part = ems.createModelElement(MPart.class);
part.setContributionURI("bundleclass://org.eclipse.e4.ui.tests/org.eclipse.e4.ui.tests.workbench.SampleView");

return part;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package org.eclipse.ui.tests.e4;

import javax.annotation.PostConstruct;

import org.eclipse.swt.widgets.Composite;

public class E4CompositePart {

@PostConstruct
public void create(Composite parent) {

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package org.eclipse.ui.tests.e4;

import javax.annotation.PostConstruct;

import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;


public class E4Part {

@PostConstruct
public void createPart(Composite parent) {
new Label(parent, SWT.NONE).setText("TEST");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package org.eclipse.ui.tests.e4;

import java.util.List;

import org.eclipse.e4.core.di.annotations.Execute;
import org.eclipse.e4.ui.model.application.MApplication;
import org.eclipse.e4.ui.model.application.ui.MUIElement;
import org.eclipse.e4.ui.model.application.ui.advanced.MPlaceholder;
import org.eclipse.e4.ui.model.application.ui.basic.MPart;
import org.eclipse.e4.ui.model.application.ui.basic.MPartStack;
import org.eclipse.e4.ui.model.application.ui.basic.MStackElement;
import org.eclipse.e4.ui.workbench.modeling.EModelService;
import org.eclipse.e4.ui.workbench.modeling.EPartService;

public class OpenCompositePartHandler {


@Execute
public void execute(EModelService modelService, MApplication app, EPartService partService) {
MUIElement compositePart = modelService.cloneSnippet(app, "org.eclipse.ui.tests.compositepart.test",
app.getSelectedElement());

MUIElement muiElement = modelService.find("org.eclipse.ui.editorss", app);

MUIElement element = ((MPlaceholder) muiElement).getRef();

List<MPartStack> primaryStack = modelService.findElements(element, "org.eclipse.e4.primaryDataStack",
MPartStack.class);

if (!primaryStack.isEmpty()) {
MPartStack partStack = primaryStack.get(0);
partStack.getChildren().add((MStackElement) compositePart);
}

partService.activate((MPart) compositePart);

}
}
14 changes: 13 additions & 1 deletion tests/org.eclipse.ui.tests/fragment.e4xmi
Original file line number Diff line number Diff line change
@@ -1,9 +1,21 @@
<?xml version="1.0" encoding="ASCII"?>
<fragment:ModelFragments xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:commands="http://www.eclipse.org/ui/2010/UIModel/application/commands" xmlns:fragment="http://www.eclipse.org/ui/2010/UIModel/fragment" xmi:id="_zPmxwL5fEe2xycAdAs49Bg">
<fragment:ModelFragments xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:basic="http://www.eclipse.org/ui/2010/UIModel/application/ui/basic" xmlns:commands="http://www.eclipse.org/ui/2010/UIModel/application/commands" xmlns:fragment="http://www.eclipse.org/ui/2010/UIModel/fragment" xmi:id="_zPmxwL5fEe2xycAdAs49Bg">
<fragments xsi:type="fragment:StringModelFragment" xmi:id="_2DG0IL5fEe2xycAdAs49Bg" featurename="commands" parentElementId="org.eclipse.e4.legacy.ide.application">
<elements xsi:type="commands:Command" xmi:id="__OUmgL5fEe2xycAdAs49Bg" elementId="org.eclipse.ui.tests.command.iconTest" commandName="Test Icon Command" commandIconURI="platform:/plugin/org.eclipse.ui.tests/icons/view.gif"/>
<elements xsi:type="commands:Command" xmi:id="_syckcCn0Ee6GCubbIJXTcg" elementId="org.eclipse.ui.tests.command.openCompositePart" commandName="Open Composite Part"/>
</fragments>
<fragments xsi:type="fragment:StringModelFragment" xmi:id="_MALdgL5iEe2xycAdAs49Bg" featurename="handlers" parentElementId="org.eclipse.e4.legacy.ide.application">
<elements xsi:type="commands:Handler" xmi:id="_NTEBsL5iEe2xycAdAs49Bg" elementId="org.eclipse.ui.tests.handler.iconTest" contributionURI="bundleclass://org.eclipse.ui.tests/org.eclipse.ui.tests.commands.EmptyE4CommandHandler" command="__OUmgL5fEe2xycAdAs49Bg"/>
<elements xsi:type="commands:Handler" xmi:id="_vKc9oCn0Ee6GCubbIJXTcg" elementId="org.eclipse.ui.tests.handler.openCompositePart" contributionURI="bundleclass://org.eclipse.ui.tests/org.eclipse.ui.tests.e4.OpenCompositePartHandler" command="_syckcCn0Ee6GCubbIJXTcg"/>
</fragments>
<fragments xsi:type="fragment:StringModelFragment" xmi:id="_6zwroOM-Ee2Ne81-gfjahg" featurename="snippets" parentElementId="org.eclipse.e4.legacy.ide.application">
<elements xsi:type="basic:CompositePart" xmi:id="_HAAmEOM_Ee2Ne81-gfjahg" elementId="org.eclipse.ui.tests.compositepart.test" contributionURI="bundleclass://org.eclipse.ui.tests/org.eclipse.ui.tests.e4.E4CompositePart" label="Wrapper" closeable="true">
<children xsi:type="basic:PartSashContainer" xmi:id="_MepZAOM_Ee2Ne81-gfjahg" elementId="org.eclipse.ui.tests.partsashcontainer.0" horizontal="true">
<children xsi:type="basic:PartStack" xmi:id="_gtThIDFTEe6hAtk0uJc72w" elementId="org.eclipse.ui.tests.partstack.0">
<children xsi:type="basic:Part" xmi:id="_QQpD8OM_Ee2Ne81-gfjahg" elementId="org.eclipse.ui.tests.compositepart.part.left" contributionURI="bundleclass://org.eclipse.ui.tests/org.eclipse.ui.tests.e4.E4Part" label="Left"/>
<children xsi:type="basic:Part" xmi:id="_QhgKcOM_Ee2Ne81-gfjahg" elementId="org.eclipse.ui.tests.compositepart.part.right" contributionURI="bundleclass://org.eclipse.ui.tests/org.eclipse.ui.tests.e4.E4Part" label="Right"/>
</children>
</children>
</elements>
</fragments>
</fragment:ModelFragments>

0 comments on commit 9d8703d

Please sign in to comment.