From 34e0c64b2b23817fd6c14d56ba8f3545b4549ca2 Mon Sep 17 00:00:00 2001 From: Vassiliy Kudryashov Date: Thu, 24 May 2012 15:49:13 +0400 Subject: [PATCH] IDEA-48900 Temporary run configuration: on exceeding the limit erase the oldest used one, not the oldest created --- .../com/intellij/execution/RunManager.java | 6 +- .../runners/GenericProgramRunner.java | 5 ++ .../actions/RunConfigurationAction.java | 5 +- .../impl/ProjectRunConfigurationManager.java | 2 +- .../execution/impl/RunConfigurable.java | 60 ++++++++++---- .../execution/impl/RunManagerImpl.java | 82 ++++++++++++++----- .../src/com/intellij/mock/MockRunManager.java | 7 +- 7 files changed, 123 insertions(+), 44 deletions(-) diff --git a/platform/lang-api/src/com/intellij/execution/RunManager.java b/platform/lang-api/src/com/intellij/execution/RunManager.java index 4280e6b7c729..3f9522eb4c5f 100644 --- a/platform/lang-api/src/com/intellij/execution/RunManager.java +++ b/platform/lang-api/src/com/intellij/execution/RunManager.java @@ -18,6 +18,7 @@ package com.intellij.execution; import com.intellij.execution.configurations.ConfigurationFactory; import com.intellij.execution.configurations.ConfigurationType; import com.intellij.execution.configurations.RunConfiguration; +import com.intellij.execution.configurations.RunProfile; import com.intellij.openapi.project.Project; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -45,7 +46,7 @@ public abstract class RunManager { public abstract boolean isTemporary(@NotNull RunConfiguration configuration); - public abstract void makeStable(@Nullable RunConfiguration configuration); + public abstract void makeStable(@NotNull RunConfiguration configuration); @Nullable public abstract RunnerAndConfigurationSettings getSelectedConfiguration(); @@ -58,4 +59,7 @@ public abstract class RunManager { @NotNull public abstract RunnerAndConfigurationSettings[] getConfigurationSettings(@NotNull ConfigurationType type); + + public abstract void refreshUsagesList(RunProfile profile); + } diff --git a/platform/lang-api/src/com/intellij/execution/runners/GenericProgramRunner.java b/platform/lang-api/src/com/intellij/execution/runners/GenericProgramRunner.java index 8d8550e664cc..1605124ffcbf 100644 --- a/platform/lang-api/src/com/intellij/execution/runners/GenericProgramRunner.java +++ b/platform/lang-api/src/com/intellij/execution/runners/GenericProgramRunner.java @@ -75,6 +75,11 @@ public abstract class GenericProgramRunner return; } + RunnerSettings runnerSettings = env.getRunnerSettings(); + if (runnerSettings != null) { + RunManager.getInstance(project).refreshUsagesList(runnerSettings.getRunProfile()); + } + ExecutionManager.getInstance(project).startRunProfile(new RunProfileStarter() { @Override public RunContentDescriptor execute(@NotNull Project project, diff --git a/platform/lang-impl/src/com/intellij/execution/actions/RunConfigurationAction.java b/platform/lang-impl/src/com/intellij/execution/actions/RunConfigurationAction.java index 006f4060141b..68e4b437a954 100644 --- a/platform/lang-impl/src/com/intellij/execution/actions/RunConfigurationAction.java +++ b/platform/lang-impl/src/com/intellij/execution/actions/RunConfigurationAction.java @@ -186,9 +186,10 @@ public class RunConfigurationAction extends ComboBoxAction implements DumbAware public void actionPerformed(final AnActionEvent e) { final Project project = e.getData(PlatformDataKeys.PROJECT); - if (project != null) { + RunConfiguration configuration = chooseTempConfiguration(project); + if (project != null && configuration != null) { final RunManager runManager = RunManager.getInstance(project); - runManager.makeStable(chooseTempConfiguration(project)); + runManager.makeStable(configuration); } } diff --git a/platform/lang-impl/src/com/intellij/execution/impl/ProjectRunConfigurationManager.java b/platform/lang-impl/src/com/intellij/execution/impl/ProjectRunConfigurationManager.java index 3ec35bfe5f28..ec3bcdb65793 100644 --- a/platform/lang-impl/src/com/intellij/execution/impl/ProjectRunConfigurationManager.java +++ b/platform/lang-impl/src/com/intellij/execution/impl/ProjectRunConfigurationManager.java @@ -112,7 +112,7 @@ public class ProjectRunConfigurationManager implements ProjectComponent, Persist } if (configuration != null) { - existing.add(RunManagerImpl.getUniqueName(configuration)); + existing.add(RunManagerImpl.getUniqueName(configuration.getConfiguration())); } } diff --git a/platform/lang-impl/src/com/intellij/execution/impl/RunConfigurable.java b/platform/lang-impl/src/com/intellij/execution/impl/RunConfigurable.java index 6f798533f6ff..1d20640a7930 100644 --- a/platform/lang-impl/src/com/intellij/execution/impl/RunConfigurable.java +++ b/platform/lang-impl/src/com/intellij/execution/impl/RunConfigurable.java @@ -54,10 +54,7 @@ import org.jetbrains.annotations.Nullable; import javax.swing.*; import javax.swing.border.EmptyBorder; import javax.swing.event.*; -import javax.swing.tree.DefaultMutableTreeNode; -import javax.swing.tree.DefaultTreeModel; -import javax.swing.tree.TreeNode; -import javax.swing.tree.TreePath; +import javax.swing.tree.*; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; @@ -518,7 +515,19 @@ class RunConfigurable extends BaseConfigurable { updateActiveConfigurationFromSelected(); final RunManagerImpl manager = getRunManager(); - final ConfigurationType[] configurationTypes = manager.getConfigurationFactories(); + final ConfigurationType[] types = manager.getConfigurationFactories(); + List configurationTypes = new ArrayList(); + for (int i = 0; i < myRoot.getChildCount(); i++) { + final DefaultMutableTreeNode node = (DefaultMutableTreeNode)myRoot.getChildAt(i); + if (node.getUserObject() instanceof ConfigurationType) { + configurationTypes.add((ConfigurationType)node.getUserObject()); + } + } + for (ConfigurationType type : types) { + if (!configurationTypes.contains(type)) + configurationTypes.add(type); + } + for (ConfigurationType configurationType : configurationTypes) { applyByType(configurationType); } @@ -1092,6 +1101,23 @@ class RunConfigurable extends BaseConfigurable { final RunnerAndConfigurationSettings originalConfiguration = configurationConfigurable.getSettings(); if (getRunManager().isTemporary(originalConfiguration)) { getRunManager().makeStable(originalConfiguration.getConfiguration()); + final DefaultMutableTreeNode treeNode = (DefaultMutableTreeNode)myTree.getSelectionPath().getLastPathComponent(); + MutableTreeNode parent = (MutableTreeNode)treeNode.getParent(); + int initialPosition = parent.getIndex(treeNode); + int position = parent.getIndex(treeNode); + DefaultMutableTreeNode node = treeNode.getPreviousSibling(); + while (node != null) { + RunnerAndConfigurationSettings settings = getSettings(node); + if (settings != null && settings.isTemporary()) { + position--; + } else { + break; + } + node = node.getPreviousSibling(); + } + for (int i = 0; i < initialPosition - position; i++) { + TreeUtil.moveSelectedRow(myTree, -1); + } } myTree.repaint(); } @@ -1139,20 +1165,20 @@ class RunConfigurable extends BaseConfigurable { } } } + } - @Nullable - private RunnerAndConfigurationSettings getSettings(DefaultMutableTreeNode treeNode) { - if (treeNode == null) - return null; - RunnerAndConfigurationSettings settings = null; - if (treeNode.getUserObject() instanceof SingleConfigurationConfigurable) { - settings = (RunnerAndConfigurationSettings)((SingleConfigurationConfigurable)treeNode.getUserObject()).getSettings(); - } - if (treeNode.getUserObject() instanceof RunnerAndConfigurationSettings) { - settings = (RunnerAndConfigurationSettings)treeNode.getUserObject(); - } - return settings; + @Nullable + private static RunnerAndConfigurationSettings getSettings(DefaultMutableTreeNode treeNode) { + if (treeNode == null) + return null; + RunnerAndConfigurationSettings settings = null; + if (treeNode.getUserObject() instanceof SingleConfigurationConfigurable) { + settings = (RunnerAndConfigurationSettings)((SingleConfigurationConfigurable)treeNode.getUserObject()).getSettings(); } + if (treeNode.getUserObject() instanceof RunnerAndConfigurationSettings) { + settings = (RunnerAndConfigurationSettings)treeNode.getUserObject(); + } + return settings; } private static class RunConfigurationBean { diff --git a/platform/lang-impl/src/com/intellij/execution/impl/RunManagerImpl.java b/platform/lang-impl/src/com/intellij/execution/impl/RunManagerImpl.java index 6fbf4652024e..a476cef85d14 100644 --- a/platform/lang-impl/src/com/intellij/execution/impl/RunManagerImpl.java +++ b/platform/lang-impl/src/com/intellij/execution/impl/RunManagerImpl.java @@ -59,6 +59,7 @@ public class RunManagerImpl extends RunManagerEx implements JDOMExternalizable, @NonNls protected static final String CONFIGURATION = "configuration"; + protected static final String RECENT = "recent_temporary"; private ConfigurationType[] myTypes; private final RunManagerConfig myConfig; @NonNls @@ -70,6 +71,7 @@ public class RunManagerImpl extends RunManagerEx implements JDOMExternalizable, private List myUnknownElements = null; private JDOMExternalizableStringList myOrder = new JDOMExternalizableStringList(); + private final ArrayList myRecentlyUsedTemporaries = new ArrayList(); private boolean myOrdered = true; private final EventDispatcher myDispatcher = EventDispatcher.create(RunManagerListener.class); @@ -243,7 +245,7 @@ public class RunManagerImpl extends RunManagerEx implements JDOMExternalizable, List tasks, boolean addEnabledTemplateTasksIfAbsent) { final RunConfiguration configuration = settings.getConfiguration(); - Integer existingId = findConfigurationIdByUniqueName(getUniqueName(settings)); + Integer existingId = findConfigurationIdByUniqueName(getUniqueName(configuration)); Integer newId = configuration.getUniqueID(); RunnerAndConfigurationSettings existingSettings = null; @@ -252,14 +254,17 @@ public class RunManagerImpl extends RunManagerEx implements JDOMExternalizable, mySharedConfigurations.remove(existingId); } - if (mySelectedConfigurationId != null && mySelectedConfigurationId.equals(existingId)) setSelectedConfigurationId(newId); + if (mySelectedConfigurationId != null && mySelectedConfigurationId.equals(existingId)) { + setSelectedConfigurationId(newId); + } myConfigurations.put(newId, settings); + if (existingId == null) { + refreshUsagesList(configuration); + } checkRecentsLimit(); mySharedConfigurations.put(newId, shared); setBeforeRunTasks(configuration, tasks, addEnabledTemplateTasksIfAbsent); - saveOrder(); - myOrdered = false; if (existingSettings == settings) { myDispatcher.getMulticaster().runConfigurationChanged(settings); @@ -269,12 +274,23 @@ public class RunManagerImpl extends RunManagerEx implements JDOMExternalizable, } } + @Override + public void refreshUsagesList(RunProfile profile) { + if (profile instanceof RunConfiguration && isTemporary((RunConfiguration)profile)) { + myRecentlyUsedTemporaries.remove((RunConfiguration)profile); + myRecentlyUsedTemporaries.add(0, (RunConfiguration)profile); + while(myRecentlyUsedTemporaries.size() > getConfig().getRecentsLimit()) { + myRecentlyUsedTemporaries.remove(myRecentlyUsedTemporaries.size() - 1); + } + } + } + void checkRecentsLimit() { List removed = new ArrayList(); while (getTempConfigurations().length > getConfig().getRecentsLimit()) { for (Iterator> it = myConfigurations.entrySet().iterator(); it.hasNext(); ) { Map.Entry entry = it.next(); - if (entry.getValue().isTemporary()) { + if (entry.getValue().isTemporary() && !myRecentlyUsedTemporaries.contains(entry.getValue().getConfiguration())) { removed.add(entry.getValue()); it.remove(); break; @@ -292,13 +308,12 @@ public class RunManagerImpl extends RunManagerEx implements JDOMExternalizable, myOrder.clear(); for (RunnerAndConfigurationSettings each : myConfigurations.values()) { if (each.getType() instanceof UnknownConfigurationType) continue; - myOrder.add(getUniqueName(each)); + myOrder.add(getUniqueName(each.getConfiguration())); } } - static String getUniqueName(@NotNull RunnerAndConfigurationSettings settings) { - RunConfiguration config = settings.getConfiguration(); - return config.getType().getDisplayName() + "." + settings.getName() + + static String getUniqueName(@NotNull RunConfiguration config) { + return config.getType().getDisplayName() + "." + config.getName() + (config instanceof UnknownRunConfiguration ? config.getUniqueID() : ""); } @@ -348,7 +363,7 @@ public class RunManagerImpl extends RunManagerEx implements JDOMExternalizable, List> order = new ArrayList>(myConfigurations.size()); for (RunnerAndConfigurationSettings each : myConfigurations.values()) { - order.add(Pair.create(getUniqueName(each), each)); + order.add(Pair.create(getUniqueName(each.getConfiguration()), each)); } myConfigurations.clear(); @@ -428,11 +443,20 @@ public class RunManagerImpl extends RunManagerEx implements JDOMExternalizable, //temp && stable configurations, !unknown for (RunnerAndConfigurationSettings each : myConfigurations.values()) { if (each.getType() instanceof UnknownConfigurationType) continue; - order.add(getUniqueName(each)); + order.add(getUniqueName(each.getConfiguration())); } order.writeExternal(parentNode); + final JDOMExternalizableStringList recentList = new JDOMExternalizableStringList(); + for (RunConfiguration each : myRecentlyUsedTemporaries) { + if (each.getType() instanceof UnknownConfigurationType) continue; + recentList.add(getUniqueName(each)); + } + final Element recent = new Element(RECENT); + parentNode.addContent(recent); + recentList.writeExternal(recent); + if (myUnknownElements != null) { for (Element unloadedElement : myUnknownElements) { parentNode.addContent((Element)unloadedElement.clone()); @@ -448,7 +472,7 @@ public class RunManagerImpl extends RunManagerEx implements JDOMExternalizable, } RunnerAndConfigurationSettings selected = getSelectedConfiguration(); if (selected != null) { - parentNode.setAttribute(SELECTED_ATTR, getUniqueName(selected)); + parentNode.setAttribute(SELECTED_ATTR, getUniqueName(selected.getConfiguration())); } } @@ -533,6 +557,18 @@ public class RunManagerImpl extends RunManagerEx implements JDOMExternalizable, } myOrder.readExternal(parentNode); + myRecentlyUsedTemporaries.clear(); + Element recentNode = parentNode.getChild(RECENT); + if (recentNode != null) { + JDOMExternalizableStringList list = new JDOMExternalizableStringList(); + list.readExternal(recentNode); + for (String name : list) { + Integer id = findConfigurationIdByUniqueName(name); + if (id != null) { + myRecentlyUsedTemporaries.add(myConfigurations.get(id).getConfiguration()); + } + } + } myOrdered = false; myLoadedSelectedConfigurationUniqueName = parentNode.getAttributeValue(SELECTED_ATTR); @@ -551,7 +587,7 @@ public class RunManagerImpl extends RunManagerEx implements JDOMExternalizable, if (myLoadedSelectedConfigurationUniqueName == null && config != null && Boolean.valueOf(element.getAttributeValue(SELECTED_ATTR)).booleanValue()) { - myLoadedSelectedConfigurationUniqueName = getUniqueName(config); + myLoadedSelectedConfigurationUniqueName = getUniqueName(config.getConfiguration()); } } @@ -564,7 +600,7 @@ public class RunManagerImpl extends RunManagerEx implements JDOMExternalizable, private Integer findConfigurationIdByUniqueName(@Nullable String selectedUniqueName) { if (selectedUniqueName != null) { for (RunnerAndConfigurationSettings each : myConfigurations.values()) { - if (selectedUniqueName.equals(getUniqueName(each))) { + if (selectedUniqueName.equals(getUniqueName(each.getConfiguration()))) { return each.getConfiguration().getUniqueID(); } } @@ -589,6 +625,7 @@ public class RunManagerImpl extends RunManagerEx implements JDOMExternalizable, mySelectedConfigurationId = null; myLoadedSelectedConfigurationUniqueName = null; myIdToIcon.clear(); + myRecentlyUsedTemporaries.clear(); fireRunConfigurationsRemoved(configurations); } @@ -728,11 +765,13 @@ public class RunManagerImpl extends RunManagerEx implements JDOMExternalizable, return configurations.toArray(new RunConfiguration[configurations.size()]); } - public void makeStable(@Nullable RunConfiguration configuration) { + public void makeStable(@NotNull RunConfiguration configuration) { RunnerAndConfigurationSettings settings = getSettings(configuration); if (settings != null) { invalidateConfigurationIcon(settings); settings.setTemporary(false); + myRecentlyUsedTemporaries.remove(configuration); + setOrdered(false); fireRunConfigurationChanged(settings); } } @@ -926,11 +965,11 @@ public class RunManagerImpl extends RunManagerEx implements JDOMExternalizable, void removeNotExistingSharedConfigurations(final Set existing) { List removed = new ArrayList(); for (Iterator> it = myConfigurations.entrySet().iterator(); it.hasNext(); ) { - Map.Entry c = it.next(); - final RunnerAndConfigurationSettings o = c.getValue(); - if (!o.isTemplate() && isConfigurationShared(o) && !existing.contains(getUniqueName(o))) { - removed.add(o); - invalidateConfigurationIcon(o); + Map.Entry entry = it.next(); + final RunnerAndConfigurationSettings settings = entry.getValue(); + if (!settings.isTemplate() && isConfigurationShared(settings) && !existing.contains(getUniqueName(settings.getConfiguration()))) { + removed.add(settings); + invalidateConfigurationIcon(settings); it.remove(); } } @@ -938,13 +977,12 @@ public class RunManagerImpl extends RunManagerEx implements JDOMExternalizable, } public void fireRunConfigurationChanged(@NotNull RunnerAndConfigurationSettings settings) { - myOrdered = false; invalidateConfigurationIcon(settings); myDispatcher.getMulticaster().runConfigurationChanged(settings); } private void fireRunConfigurationsRemoved(@NotNull List removed) { - myOrdered = false; + myRecentlyUsedTemporaries.removeAll(removed); for (RunnerAndConfigurationSettings settings : removed) { myDispatcher.getMulticaster().runConfigurationRemoved(settings); } diff --git a/platform/testFramework/src/com/intellij/mock/MockRunManager.java b/platform/testFramework/src/com/intellij/mock/MockRunManager.java index 450d8b68ba4f..ff465a3d13cb 100644 --- a/platform/testFramework/src/com/intellij/mock/MockRunManager.java +++ b/platform/testFramework/src/com/intellij/mock/MockRunManager.java @@ -4,6 +4,7 @@ import com.intellij.execution.*; import com.intellij.execution.configurations.ConfigurationFactory; import com.intellij.execution.configurations.ConfigurationType; import com.intellij.execution.configurations.RunConfiguration; +import com.intellij.execution.configurations.RunProfile; import com.intellij.openapi.util.Key; import org.jetbrains.annotations.NotNull; @@ -46,7 +47,7 @@ public class MockRunManager extends RunManagerEx { } @Override - public void makeStable(RunConfiguration configuration) { + public void makeStable(@NotNull RunConfiguration configuration) { } @Override @@ -164,4 +165,8 @@ public class MockRunManager extends RunManagerEx { @Override public void removeRunManagerListener(RunManagerListener listener) { } + + @Override + public void refreshUsagesList(RunProfile profile) { + } }