IDEA-181448 RunDashboard: move run content to appropriate tool window when configured types changed

GitOrigin-RevId: d89304debabc4bc13366fbf8912171d0be5bb752
This commit is contained in:
Konstantin Aleev
2019-07-02 06:52:16 +03:00
committed by intellij-monorepo-bot
parent 16629935fa
commit a283d32675
3 changed files with 137 additions and 36 deletions
@@ -1,6 +1,7 @@
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.execution.dashboard;
import com.google.common.collect.Sets;
import com.intellij.execution.*;
import com.intellij.execution.configurations.RunConfiguration;
import com.intellij.execution.dashboard.tree.RunConfigurationNode;
@@ -168,11 +169,7 @@ public class RunDashboardManagerImpl implements RunDashboardManager, PersistentS
boolean onAdd = event.getOperation() == ContentManagerEvent.ContentOperation.add;
Content content = event.getContent();
if (onAdd) {
RunnerLayoutUiImpl ui = getRunnerLayoutUi(RunContentManagerImpl.getRunContentDescriptorByContent(content));
if (ui != null) {
ui.setLeftToolbarVisible(false);
ui.setContentToolbarBefore(false);
}
updateContentToolbar(content, false);
updateServiceContent(content);
}
@@ -203,6 +200,7 @@ public class RunDashboardManagerImpl implements RunDashboardManager, PersistentS
if (myContentManager.getContentCount() == 0 && !isShowConfigurations()) {
setShowConfigurations(true);
}
removeServiceContent(event.getContent());
}
});
}
@@ -323,15 +321,60 @@ public class RunDashboardManagerImpl implements RunDashboardManager, PersistentS
@Override
public void setTypes(@NotNull Set<String> types) {
Set<String> removed = new HashSet<>(Sets.difference(myState.configurationTypes, types));
Set<String> added = new HashSet<>(Sets.difference(types, myState.configurationTypes));
myState.configurationTypes.clear();
myState.configurationTypes.addAll(types);
if (!myState.configurationTypes.isEmpty()) {
initToolWindowContentListeners();
}
syncConfigurations();
moveRemovedTypesContent(removed);
moveAddedTypesContent(added);
updateDashboard(true);
}
private void moveRemovedTypesContent(Set<String> removedTypes) {
if (removedTypes.isEmpty()) return;
ExecutionManagerImpl executionManager = (ExecutionManagerImpl)ExecutionManager.getInstance(myProject);
RunContentManagerImpl runContentManager = (RunContentManagerImpl)executionManager.getContentManager();
for (RunDashboardService service : getRunConfigurations()) {
Content content = service.getContent();
if (content == null || !removedTypes.contains(service.getSettings().getType().getId())) continue;
RunContentDescriptor descriptor = RunContentManagerImpl.getRunContentDescriptorByContent(content);
if (descriptor == null) continue;
Executor executor = RunContentManagerImpl.getExecutorByContent(content);
if (executor == null) continue;
descriptor.setContentToolWindowId(null);
updateContentToolbar(content, true);
runContentManager.moveContent(executor, descriptor);
}
}
private void moveAddedTypesContent(Set<String> addedTypes) {
if (addedTypes.isEmpty()) return;
ExecutionManagerImpl executionManager = (ExecutionManagerImpl)ExecutionManager.getInstance(myProject);
RunContentManagerImpl runContentManager = (RunContentManagerImpl)executionManager.getContentManager();
List<RunContentDescriptor> descriptors =
executionManager.getRunningDescriptors(settings -> addedTypes.contains(settings.getType().getId()));
for (RunContentDescriptor descriptor : descriptors) {
Content content = descriptor.getAttachedContent();
if (content == null) continue;
Executor executor = RunContentManagerImpl.getExecutorByContent(content);
if (executor == null) continue;
descriptor.setContentToolWindowId(getToolWindowId());
runContentManager.moveContent(executor, descriptor);
}
}
@Override
@NotNull
public List<RunDashboardCustomizer> getCustomizers(@NotNull RunnerAndConfigurationSettings settings,
@@ -572,36 +615,37 @@ public class RunDashboardManagerImpl implements RunDashboardManager, PersistentS
myServiceLock.writeLock().lock();
try {
doAddServiceContent(settings, content);
Disposer.register(content, () -> {
RunDashboardServiceImpl service = findService(content);
if (service == null) return;
myServiceLock.writeLock().lock();
try {
removeServiceContent(service);
}
finally {
myServiceLock.writeLock().unlock();
updateDashboard(true);
}
});
}
finally {
myServiceLock.writeLock().unlock();
}
}
private void removeServiceContent(@NotNull Content content) {
myServiceLock.writeLock().lock();
try {
RunDashboardServiceImpl service = findService(content);
if (service == null) return;
doRemoveServiceContent(service);
}
finally {
myServiceLock.writeLock().unlock();
updateDashboard(true);
}
}
private void updateServiceContent(@NotNull Content content) {
RunnerAndConfigurationSettings settings = findSettings(content);
if (settings == null) return;
RunDashboardServiceImpl service = findService(content);
if (service == null || service.getSettings().equals(settings)) return;
myServiceLock.writeLock().lock();
try {
RunDashboardServiceImpl service = findService(content);
if (service == null || service.getSettings().equals(settings)) return;
doAddServiceContent(settings, content);
removeServiceContent(service);
doRemoveServiceContent(service);
}
finally {
myServiceLock.writeLock().unlock();
@@ -624,7 +668,7 @@ public class RunDashboardManagerImpl implements RunDashboardManager, PersistentS
newService.setContent(content);
}
private void removeServiceContent(@NotNull RunDashboardServiceImpl service) {
private void doRemoveServiceContent(@NotNull RunDashboardServiceImpl service) {
service.setContent(null);
RunnerAndConfigurationSettings contentSettings = service.getSettings();
List<RunDashboardServiceImpl> services = getServices(contentSettings);
@@ -675,6 +719,14 @@ public class RunDashboardManagerImpl implements RunDashboardManager, PersistentS
return null;
}
private static void updateContentToolbar(Content content, boolean visible) {
RunnerLayoutUiImpl ui = getRunnerLayoutUi(RunContentManagerImpl.getRunContentDescriptorByContent(content));
if (ui != null) {
ui.setLeftToolbarVisible(visible);
ui.setContentToolbarBefore(visible);
}
}
@Nullable
static RunnerLayoutUiImpl getRunnerLayoutUi(@Nullable RunContentDescriptor descriptor) {
if (descriptor == null) return null;
@@ -29,7 +29,7 @@ import org.jetbrains.annotations.NotNull;
public class RunDashboardToolWindowFactory implements ToolWindowFactory, Condition<Project>, DumbAware {
@Override
public boolean value(Project project) {
return !Registry.is("ide.service.view") && !RunDashboardManager.getInstance(project).getTypes().isEmpty();
return !Registry.is("ide.service.view");
}
@Override
@@ -46,6 +46,7 @@ public class RunContentManagerImpl implements RunContentManager, Disposable {
public static final Key<Boolean> ALWAYS_USE_DEFAULT_STOPPING_BEHAVIOUR_KEY = Key.create("ALWAYS_USE_DEFAULT_STOPPING_BEHAVIOUR_KEY");
private static final Logger LOG = Logger.getInstance(RunContentManagerImpl.class);
private static final Key<Executor> EXECUTOR_KEY = Key.create("Executor");
private static final Key<ContentManagerListener> CLOSE_LISTENER_KEY = Key.create("CloseListener");
private final Project myProject;
private final Map<String, ContentManager> myToolwindowIdToContentManagerMap = new THashMap<>();
@@ -295,19 +296,10 @@ public class RunContentManagerImpl implements RunContentManager, Disposable {
@Override
public void processTerminated(@NotNull final ProcessEvent event) {
ApplicationManager.getApplication().invokeLater(() -> {
boolean alive = false;
ContentManager manager = myToolwindowIdToContentManagerMap.get(toolWindowId);
if (manager == null) return;
for (Content content1 : manager.getContents()) {
RunContentDescriptor descriptor1 = getRunContentDescriptorByContent(content1);
if (descriptor1 != null) {
ProcessHandler handler = descriptor1.getProcessHandler();
if (handler != null && !handler.isProcessTerminated()) {
alive = true;
break;
}
}
}
boolean alive = isAlive(manager);
Icon base = myToolwindowIdToBaseIconMap.get(toolWindowId);
toolWindow.setIcon(alive ? ExecutionUtil.getLiveIndicator(base) : base);
@@ -330,7 +322,8 @@ public class RunContentManagerImpl implements RunContentManager, Disposable {
if (oldDescriptor == null) {
contentManager.addContent(content);
new CloseListener(content, executor);
CloseListener listener = new CloseListener(content, executor);
content.putUserData(CLOSE_LISTENER_KEY, listener);
}
if (descriptor.isSelectContentWhenAdded()
@@ -602,6 +595,62 @@ public class RunContentManagerImpl implements RunContentManager, Disposable {
return null;
}
public void moveContent(@NotNull Executor executor, @NotNull RunContentDescriptor descriptor) {
Content content = descriptor.getAttachedContent();
if (content == null) return;
ContentManager oldContentManager = content.getManager();
ContentManager newContentManager = getContentManagerForRunner(executor, descriptor);
if (oldContentManager == null || oldContentManager == newContentManager) return;
ContentManagerListener listener = content.getUserData(CLOSE_LISTENER_KEY);
if (listener != null) {
oldContentManager.removeContentManagerListener(listener);
}
oldContentManager.removeContent(content, false);
if (isAlive(descriptor)) {
if (!isAlive(oldContentManager)) {
updateToolWindowIcon(oldContentManager, false);
}
if (!isAlive(newContentManager)) {
updateToolWindowIcon(newContentManager, true);
}
}
newContentManager.addContent(content);
if (listener != null) {
newContentManager.addContentManagerListener(listener);
}
}
private void updateToolWindowIcon(@NotNull ContentManager contentManager, boolean alive) {
for (Map.Entry<String, ContentManager> entry : myToolwindowIdToContentManagerMap.entrySet()) {
if (entry.getValue().equals(contentManager)) {
String toolWindowId = entry.getKey();
ToolWindow toolWindow = ToolWindowManager.getInstance(myProject).getToolWindow(toolWindowId);
if (toolWindow != null) {
Icon base = myToolwindowIdToBaseIconMap.get(toolWindowId);
toolWindow.setIcon(alive ? ExecutionUtil.getLiveIndicator(base) : base);
}
return;
}
}
}
private static boolean isAlive(@NotNull ContentManager contentManager) {
for (Content content : contentManager.getContents()) {
RunContentDescriptor descriptor = getRunContentDescriptorByContent(content);
if (descriptor != null && isAlive(descriptor)) {
return true;
}
}
return false;
}
private static boolean isAlive(@NotNull RunContentDescriptor descriptor) {
ProcessHandler handler = descriptor.getProcessHandler();
return handler != null && !handler.isProcessTerminated();
}
private class CloseListener extends BaseContentCloseListener {
private final Executor myExecutor;