From a283d326756d7e62d2de7009ffa3e6cf4bd8cca4 Mon Sep 17 00:00:00 2001 From: Konstantin Aleev Date: Mon, 17 Jun 2019 13:08:15 +0300 Subject: [PATCH] IDEA-181448 RunDashboard: move run content to appropriate tool window when configured types changed GitOrigin-RevId: d89304debabc4bc13366fbf8912171d0be5bb752 --- .../dashboard/RunDashboardManagerImpl.java | 98 ++++++++++++++----- .../RunDashboardToolWindowFactory.java | 2 +- .../execution/ui/RunContentManagerImpl.java | 73 +++++++++++--- 3 files changed, 137 insertions(+), 36 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/execution/dashboard/RunDashboardManagerImpl.java b/platform/lang-impl/src/com/intellij/execution/dashboard/RunDashboardManagerImpl.java index 2ccd3684524f..d163ede5887e 100644 --- a/platform/lang-impl/src/com/intellij/execution/dashboard/RunDashboardManagerImpl.java +++ b/platform/lang-impl/src/com/intellij/execution/dashboard/RunDashboardManagerImpl.java @@ -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 types) { + Set removed = new HashSet<>(Sets.difference(myState.configurationTypes, types)); + Set 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 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 addedTypes) { + if (addedTypes.isEmpty()) return; + + ExecutionManagerImpl executionManager = (ExecutionManagerImpl)ExecutionManager.getInstance(myProject); + RunContentManagerImpl runContentManager = (RunContentManagerImpl)executionManager.getContentManager(); + List 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 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 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; diff --git a/platform/lang-impl/src/com/intellij/execution/dashboard/RunDashboardToolWindowFactory.java b/platform/lang-impl/src/com/intellij/execution/dashboard/RunDashboardToolWindowFactory.java index 36ef1695edad..1dfc29036142 100644 --- a/platform/lang-impl/src/com/intellij/execution/dashboard/RunDashboardToolWindowFactory.java +++ b/platform/lang-impl/src/com/intellij/execution/dashboard/RunDashboardToolWindowFactory.java @@ -29,7 +29,7 @@ import org.jetbrains.annotations.NotNull; public class RunDashboardToolWindowFactory implements ToolWindowFactory, Condition, 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 diff --git a/platform/lang-impl/src/com/intellij/execution/ui/RunContentManagerImpl.java b/platform/lang-impl/src/com/intellij/execution/ui/RunContentManagerImpl.java index 8aa13e035e46..5c6c7f3aa6d0 100644 --- a/platform/lang-impl/src/com/intellij/execution/ui/RunContentManagerImpl.java +++ b/platform/lang-impl/src/com/intellij/execution/ui/RunContentManagerImpl.java @@ -46,6 +46,7 @@ public class RunContentManagerImpl implements RunContentManager, Disposable { public static final Key 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_KEY = Key.create("Executor"); + private static final Key CLOSE_LISTENER_KEY = Key.create("CloseListener"); private final Project myProject; private final Map 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 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;