Skip to content

Commit 0a5fd4c

Browse files
committed
Support certain actions in dialog context with ApplicationPartService
Currently the ApplicationPartServiceImpl requires an active context from a part (what is valid most of the time) but this does not work if currently a dialog context is executing (in most cases a ProgresMonitorDialog or a wizard for example) that is triggered outside a part (e.g. menus/toolbars or background threads). In such cases all actions on the EPartService currently fail with a confusing "Application does not have an active window" what is actually a wrong message (becuase the application HAS an active window as one can see in the debugger). This change the behaviour in two ways: 1) a different message is thrwon in cases where previously the wrong message was issued to the user. 2) for certain actions there is a fallback to the PartService of the part itself if it was given, or implements a fallback strategy that do not require a part being focused
1 parent e8fbf41 commit 0a5fd4c

File tree

1 file changed

+71
-26
lines changed

1 file changed

+71
-26
lines changed
Lines changed: 71 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*******************************************************************************
2-
* Copyright (c) 2010, 2016 IBM Corporation and others.
2+
* Copyright (c) 2010, 2023 IBM Corporation and others.
33
*
44
* This program and the accompanying materials
55
* are made available under the terms of the Eclipse Public License 2.0
@@ -12,30 +12,42 @@
1212
* IBM Corporation - initial API and implementation
1313
* Lars Vogel <[email protected]> - Bug 395825
1414
* Simon Scholz <[email protected]> - Bug 486876
15+
* Christoph Läubrich - make the application service to work in dialog context
1516
******************************************************************************/
1617
package org.eclipse.e4.ui.internal.workbench;
1718

1819
import java.util.Collection;
20+
import java.util.List;
21+
import java.util.Objects;
1922
import java.util.Optional;
23+
import java.util.function.Supplier;
2024
import javax.inject.Inject;
2125
import org.eclipse.e4.core.contexts.IEclipseContext;
2226
import org.eclipse.e4.ui.model.application.MApplication;
2327
import org.eclipse.e4.ui.model.application.ui.advanced.MPerspective;
2428
import org.eclipse.e4.ui.model.application.ui.advanced.MPlaceholder;
2529
import org.eclipse.e4.ui.model.application.ui.basic.MPart;
30+
import org.eclipse.e4.ui.workbench.UIEvents;
31+
import org.eclipse.e4.ui.workbench.modeling.EModelService;
2632
import org.eclipse.e4.ui.workbench.modeling.EPartService;
2733
import org.eclipse.e4.ui.workbench.modeling.IPartListener;
2834

2935
public class ApplicationPartServiceImpl implements EPartService {
3036

37+
private static final Supplier<RuntimeException> NO_VALID_PARTSERVICE = () -> new IllegalStateException(
38+
"No valid PartService can be aquired from the current context"); //$NON-NLS-1$
39+
3140
private MApplication application;
3241

42+
private EModelService modelService;
43+
3344
@Inject
34-
ApplicationPartServiceImpl(MApplication application) {
45+
ApplicationPartServiceImpl(MApplication application, EModelService modelService) {
3546
this.application = application;
47+
this.modelService = modelService;
3648
}
3749

38-
private EPartService getActiveWindowService() {
50+
private Optional<EPartService> getActiveWindowService() {
3951
IEclipseContext activeWindowContext = application.getContext().getActiveChild();
4052
if (activeWindowContext == null) {
4153
throw new IllegalStateException("Application does not have an active window"); //$NON-NLS-1$
@@ -45,9 +57,24 @@ private EPartService getActiveWindowService() {
4557
throw new IllegalStateException("Active window context is invalid"); //$NON-NLS-1$
4658
}
4759
if (activeWindowPartService == this) {
48-
throw new IllegalStateException("Application does not have an active window"); //$NON-NLS-1$
60+
// in this cas we would run into an infinite recursion, so from the current
61+
// active window we can't aquire another part service
62+
return Optional.empty();
4963
}
50-
return activeWindowPartService;
64+
return Optional.of(activeWindowPartService);
65+
}
66+
67+
private Optional<EPartService> getActiveWindowService(MPart part) {
68+
return getActiveWindowService().or(() -> {
69+
IEclipseContext context = part.getContext();
70+
if (context != null) {
71+
EPartService partService = context.get(EPartService.class);
72+
if (partService instanceof PartServiceImpl) {
73+
return Optional.of(partService);
74+
}
75+
}
76+
return Optional.empty();
77+
});
5178
}
5279

5380
@Override
@@ -64,107 +91,125 @@ public void removePartListener(IPartListener listener) {
6491

6592
@Override
6693
public boolean isPartOrPlaceholderInPerspective(String elementId, MPerspective perspective) {
67-
return getActiveWindowService().isPartOrPlaceholderInPerspective(elementId, perspective);
94+
return getActiveWindowService().orElseThrow(NO_VALID_PARTSERVICE).isPartOrPlaceholderInPerspective(elementId,
95+
perspective);
6896
}
6997

7098
@Override
7199
public void switchPerspective(MPerspective perspective) {
72-
getActiveWindowService().switchPerspective(perspective);
100+
getActiveWindowService().ifPresentOrElse(service -> service.switchPerspective(perspective),
101+
() -> switchPerspectiveInternal(perspective));
73102
}
74103

75104
@Override
76105
public Optional<MPerspective> switchPerspective(String perspectiveId) {
77-
return getActiveWindowService().switchPerspective(perspectiveId);
106+
Objects.requireNonNull(perspectiveId);
107+
Optional<EPartService> windowService = getActiveWindowService();
108+
if (windowService.isPresent()) {
109+
return windowService.get().switchPerspective(perspectiveId);
110+
}
111+
List<MPerspective> result = modelService.findElements(application, perspectiveId, MPerspective.class, null);
112+
if (!result.isEmpty()) {
113+
MPerspective perspective = result.get(0);
114+
switchPerspectiveInternal(perspective);
115+
return java.util.Optional.of(perspective);
116+
}
117+
return Optional.empty();
118+
}
119+
120+
private void switchPerspectiveInternal(MPerspective perspective) {
121+
perspective.getParent().setSelectedElement(perspective);
122+
UIEvents.publishEvent(UIEvents.UILifeCycle.PERSPECTIVE_SWITCHED, perspective);
78123
}
79124

80125
@Override
81126
public void activate(MPart part) {
82-
getActiveWindowService().activate(part);
127+
getActiveWindowService(part).orElseThrow(NO_VALID_PARTSERVICE).activate(part);
83128
}
84129

85130
@Override
86131
public void activate(MPart part, boolean requiresFocus) {
87-
getActiveWindowService().activate(part, requiresFocus);
132+
getActiveWindowService(part).orElseThrow(NO_VALID_PARTSERVICE).activate(part, requiresFocus);
88133
}
89134

90135
@Override
91136
public void requestActivation() {
92-
getActiveWindowService().requestActivation();
137+
getActiveWindowService().orElseThrow(NO_VALID_PARTSERVICE).requestActivation();
93138
}
94139

95140
@Override
96141
public void bringToTop(MPart part) {
97-
getActiveWindowService().bringToTop(part);
142+
getActiveWindowService(part).orElseThrow(NO_VALID_PARTSERVICE).bringToTop(part);
98143
}
99144

100145
@Override
101146
public MPart findPart(String id) {
102-
return getActiveWindowService().findPart(id);
147+
return getActiveWindowService().orElseThrow(NO_VALID_PARTSERVICE).findPart(id);
103148
}
104149

105150
@Override
106151
public Collection<MPart> getParts() {
107-
return getActiveWindowService().getParts();
152+
return getActiveWindowService().orElseThrow(NO_VALID_PARTSERVICE).getParts();
108153
}
109154

110155
@Override
111156
public MPart getActivePart() {
112-
return getActiveWindowService().getActivePart();
157+
return getActiveWindowService().orElseThrow(NO_VALID_PARTSERVICE).getActivePart();
113158
}
114159

115160
@Override
116161
public boolean isPartVisible(MPart part) {
117-
return getActiveWindowService().isPartVisible(part);
162+
return getActiveWindowService(part).orElseThrow(NO_VALID_PARTSERVICE).isPartVisible(part);
118163
}
119164

120165
@Override
121166
public MPart createPart(String id) {
122-
return getActiveWindowService().createPart(id);
167+
return getActiveWindowService().orElseThrow(NO_VALID_PARTSERVICE).createPart(id);
123168
}
124169

125170
@Override
126171
public MPlaceholder createSharedPart(String id) {
127-
return getActiveWindowService().createSharedPart(id);
172+
return getActiveWindowService().orElseThrow(NO_VALID_PARTSERVICE).createSharedPart(id);
128173
}
129174

130175
@Override
131176
public MPlaceholder createSharedPart(String id, boolean force) {
132-
return getActiveWindowService().createSharedPart(id, force);
177+
return getActiveWindowService().orElseThrow(NO_VALID_PARTSERVICE).createSharedPart(id, force);
133178
}
134179

135180
@Override
136181
public MPart showPart(String id, PartState partState) {
137-
return getActiveWindowService().showPart(id, partState);
182+
return getActiveWindowService().orElseThrow(NO_VALID_PARTSERVICE).showPart(id, partState);
138183
}
139184

140185
@Override
141186
public MPart showPart(MPart part, PartState partState) {
142-
return getActiveWindowService().showPart(part, partState);
187+
return getActiveWindowService(part).orElseThrow(NO_VALID_PARTSERVICE).showPart(part, partState);
143188
}
144189

145190
@Override
146191
public void hidePart(MPart part) {
147-
getActiveWindowService().hidePart(part);
192+
getActiveWindowService(part).orElseThrow(NO_VALID_PARTSERVICE).hidePart(part);
148193
}
149194

150195
@Override
151196
public void hidePart(MPart part, boolean force) {
152-
getActiveWindowService().hidePart(part, force);
197+
getActiveWindowService(part).orElseThrow(NO_VALID_PARTSERVICE).hidePart(part, force);
153198
}
154199

155200
@Override
156201
public Collection<MPart> getDirtyParts() {
157-
return getActiveWindowService().getDirtyParts();
202+
return getActiveWindowService().orElseThrow(NO_VALID_PARTSERVICE).getDirtyParts();
158203
}
159204

160205
@Override
161206
public boolean savePart(MPart part, boolean confirm) {
162-
return getActiveWindowService().savePart(part, confirm);
207+
return getActiveWindowService(part).orElseThrow(NO_VALID_PARTSERVICE).savePart(part, confirm);
163208
}
164209

165210
@Override
166211
public boolean saveAll(boolean confirm) {
167-
return getActiveWindowService().saveAll(confirm);
212+
return getActiveWindowService().orElseThrow(NO_VALID_PARTSERVICE).saveAll(confirm);
168213
}
169214

170215
}

0 commit comments

Comments
 (0)