diff options
author | Torbjörn Svensson | 2020-11-29 21:06:37 +0000 |
---|---|---|
committer | Torbjörn Svensson | 2021-02-06 12:57:46 +0000 |
commit | ae96a18fe17a463dd6b412a885d842f79cee7528 (patch) | |
tree | 51333aa29ce990eb4c3da905641378d70fafdce2 | |
parent | 80e5c732e89a8f0102a825505c69bde1cc609843 (diff) | |
download | eclipse.platform.debug-ae96a18fe17a463dd6b412a885d842f79cee7528.tar.gz eclipse.platform.debug-ae96a18fe17a463dd6b412a885d842f79cee7528.tar.xz eclipse.platform.debug-ae96a18fe17a463dd6b412a885d842f79cee7528.zip |
Bug 569373: Use ViewFilter to filter launch configsY20210211-1200Y20210211-0600Y20210210-1200Y20210210-0100Y20210209-1200I20210210-1800I20210210-0910I20210209-1800I20210208-1800I20210207-1800I20210206-1800
The content provider is only called when the launch configuration
tree is initialized. Any following add/remove of a launch
configuration is handled in LaunchConfigurationView without
fetching the new tree from the content provider.
Forcibly refresh the list in the viewer when the added launch
configuration is shared. To avoid having dangling launch
configurations in the tree.
Change-Id: Id67d550dddc6df583229013c1c71bcfc5f320f38
Signed-off-by: Torbjörn Svensson <azoff@svenskalinuxforeningen.se>
4 files changed, 113 insertions, 62 deletions
diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/launchConfigurations/LaunchConfigurationTreeContentProvider.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/launchConfigurations/LaunchConfigurationTreeContentProvider.java index ae4c31c4a..d8fe82eda 100644 --- a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/launchConfigurations/LaunchConfigurationTreeContentProvider.java +++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/launchConfigurations/LaunchConfigurationTreeContentProvider.java @@ -18,12 +18,7 @@ package org.eclipse.debug.internal.ui.launchConfigurations; import java.util.ArrayList; import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; @@ -98,7 +93,6 @@ public class LaunchConfigurationTreeContentProvider implements ITreeContentProvi configs.add(launchConfig); } } - configs = filterUniqueLaunchConfigurations(configs); ILaunchConfiguration[] prototypes = getLaunchManager().getLaunchConfigurations(type, ILaunchConfiguration.PROTOTYPE); Collections.addAll(configs, prototypes); @@ -230,56 +224,4 @@ public class LaunchConfigurationTreeContentProvider implements ITreeContentProvi private Shell getShell() { return fShell; } - - /** - * Returns unique launch configurations from the input list Launch - * configurations are unique if the following criteria are fulfilled: - * <ol> - * <li>The name is unique within the list</li> - * <li>The set of attributes (key and value) for the launch configuration is - * unique within the list</li> - * </ol> - * - * @param launchConfigurations The list of launch configurations to filter - * @return List of unique launch configurations based on criteria above - * @throws CoreException If unable to fetch attributes for launch configuration - */ - private List<ILaunchConfiguration> filterUniqueLaunchConfigurations(List<ILaunchConfiguration> launchConfigurations) throws CoreException { - List<ILaunchConfiguration> configs = new ArrayList<>(); - - // Create map between name and list of launch configurations with same - // name - Map<String, List<ILaunchConfiguration>> configNameMap = new HashMap<>(); - - for (ILaunchConfiguration launchConfig : launchConfigurations) { - String name = launchConfig.getName(); - if (!configNameMap.containsKey(name)) { - configNameMap.put(name, new ArrayList<>()); - } - configNameMap.get(name).add(launchConfig); - } - - // Identify unique configurations - for (Entry<String, List<ILaunchConfiguration>> entry : configNameMap.entrySet()) { - List<ILaunchConfiguration> configsWithSameName = entry.getValue(); - if (configsWithSameName.size() == 1) { - // Only one configuration, add it - configs.add(configsWithSameName.get(0)); - } else if (configsWithSameName.size() > 1) { - // More than one configuration detected with same name, - // verify that they are unique - Set<Map<String, Object>> seenConfigContent = new HashSet<>(); - for (ILaunchConfiguration config : configsWithSameName) { - Map<String, Object> content = config.getAttributes(); - if (!seenConfigContent.contains(content)) { - // Only add the first one with the same content - seenConfigContent.add(content); - configs.add(config); - } - } - } - } - - return configs; - } } diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/launchConfigurations/LaunchConfigurationView.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/launchConfigurations/LaunchConfigurationView.java index 908120415..415a6f781 100644 --- a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/launchConfigurations/LaunchConfigurationView.java +++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/launchConfigurations/LaunchConfigurationView.java @@ -319,11 +319,11 @@ public class LaunchConfigurationView extends AbstractDebugView implements ILaunc if (viewer != null) { try { viewer.getControl().setRedraw(false); - if (configuration.getPrototype() != null) { - viewer.add(configuration.getPrototype(), configuration); - } else { - viewer.add(configuration.getType(), configuration); + Object parentElement = configuration.getPrototype(); + if (parentElement == null) { + parentElement = configuration.getType(); } + viewer.add(parentElement, configuration); // if moved, remove original now if (from != null) { viewer.remove(from); @@ -332,6 +332,10 @@ public class LaunchConfigurationView extends AbstractDebugView implements ILaunc viewer.setSelection(new StructuredSelection(configuration), true); } updateFilterLabel(); + // Need to refresh here, bug 559758 + if (!configuration.isLocal()) { + viewer.refresh(parentElement); + } } catch (CoreException e) {} finally { diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/launchConfigurations/LaunchConfigurationsDialog.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/launchConfigurations/LaunchConfigurationsDialog.java index c6550db2d..af6d76e18 100644 --- a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/launchConfigurations/LaunchConfigurationsDialog.java +++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/launchConfigurations/LaunchConfigurationsDialog.java @@ -233,6 +233,7 @@ public class LaunchConfigurationsDialog extends TitleAreaDialog implements ILaun private DeletedProjectFilter fDeletedProjectFilter; private LaunchConfigurationTypeFilter fLCTFilter; private WorkingSetsFilter fWorkingSetsFilter; + private UniqueLaunchConfigurationFileFilter fUniqueLaunchConfugurationFileFilter; /** * set of reserved names that should not be considered when generating a new name for a launch configuration @@ -645,6 +646,8 @@ public class LaunchConfigurationsDialog extends TitleAreaDialog implements ILaun if(DebugUIPlugin.getDefault().getPreferenceStore().getBoolean(IInternalDebugUIConstants.PREF_FILTER_WORKING_SETS)) { filters.add(fWorkingSetsFilter); } + fUniqueLaunchConfugurationFileFilter = new UniqueLaunchConfigurationFileFilter(); + filters.add(fUniqueLaunchConfugurationFileFilter); return filters.toArray(new ViewerFilter[filters.size()]); } diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/launchConfigurations/UniqueLaunchConfigurationFileFilter.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/launchConfigurations/UniqueLaunchConfigurationFileFilter.java new file mode 100644 index 000000000..9880db0e0 --- /dev/null +++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/launchConfigurations/UniqueLaunchConfigurationFileFilter.java @@ -0,0 +1,102 @@ +/******************************************************************************* + * Copyright (c) 2020 Torbjörn Svensson 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: + * Torbjörn Svensson - initial API and implementation + *******************************************************************************/ +package org.eclipse.debug.internal.ui.launchConfigurations; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; + +import org.eclipse.core.resources.IFile; +import org.eclipse.core.runtime.IPath; +import org.eclipse.debug.core.ILaunchConfiguration; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.jface.viewers.ViewerFilter; + +/** + * Filters out the instance of ILaunchCOnfiguration where the, possibly nested, + * launch configuration files are stored. If the launch configuration is local, + * it's simply returned. + */ +public class UniqueLaunchConfigurationFileFilter extends ViewerFilter { + @Override + public Object[] filter(Viewer viewer, Object parent, Object[] elements) { + int size = elements.length; + if (size == 0) { + return elements; + } + + List<Object> filteredElements = new ArrayList<>(size); + + Map<String, List<ILaunchConfiguration>> configPathMap = new HashMap<>(); + for (Object element : elements) { + if (element instanceof ILaunchConfiguration) { + ILaunchConfiguration config = (ILaunchConfiguration) element; + + String path = toLaunchFileLocation(config); + if (!configPathMap.containsKey(path)) { + configPathMap.put(path, new ArrayList<>()); + } + configPathMap.get(path).add(config); + } else { + filteredElements.add(element); + } + } + + for (Entry<String, List<ILaunchConfiguration>> entry : configPathMap.entrySet()) { + List<ILaunchConfiguration> configsWithSamePath = entry.getValue(); + if (entry.getKey() == null) { + // Local configurations ends up here, add them without further filter + filteredElements.addAll(configsWithSamePath); + } else if (configsWithSamePath.size() == 1) { + // Only one configuration, add it + filteredElements.add(configsWithSamePath.get(0)); + } else if (configsWithSamePath.size() > 1) { + // More than one config with same path. + // Order them with the shortest project relative path first + configsWithSamePath.sort((o1, o2) -> { + IPath path1 = o1.getFile().getProjectRelativePath(); + IPath path2 = o2.getFile().getProjectRelativePath(); + return Integer.compare(path1.segmentCount(), path2.segmentCount()); + }); + // Use the configuration with the shortest path. + // The other configurations in the list are "identical" but with + // the container set to one of the parent project(s) in the + // workspace hierarchy. + filteredElements.add(configsWithSamePath.get(0)); + } + } + + return filteredElements.toArray(); + } + + private String toLaunchFileLocation(ILaunchConfiguration config) { + if (!config.isLocal()) { + IFile file = config.getFile(); + if (file != null) { + IPath path = file.getLocation(); + if (path != null) { + return path.toOSString(); + } + } + } + return null; + } + + @Override + public boolean select(Viewer viewer, Object parentElement, Object element) { + return true; + } +} |