diff options
| author | Emmanuel Chebbi | 2019-10-05 17:58:37 +0000 |
|---|---|---|
| committer | Karsten Thoms | 2019-10-14 10:47:14 +0000 |
| commit | 3e49f9ea3130e7ba80887b4638db2bfe6eb18360 (patch) | |
| tree | 193091284315255db8e375da0e35f2ec3c4fa934 | |
| parent | 218f04425af8f4e83645e21c390a4f5d05b10213 (diff) | |
| download | eclipse.platform.ui-3e49f9ea3130e7ba80887b4638db2bfe6eb18360.tar.gz eclipse.platform.ui-3e49f9ea3130e7ba80887b4638db2bfe6eb18360.tar.xz eclipse.platform.ui-3e49f9ea3130e7ba80887b4638db2bfe6eb18360.zip | |
Bug 214491 - Make FilteredItemsSelectionDialog respect its initial selections
Change-Id: I5059e118977da98ee0e8fe373c10fabf3a442b81
Signed-off-by: Emmanuel Chebbi <emmanuel.chebbi@outlook.fr>
3 files changed, 412 insertions, 4 deletions
diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/dialogs/FilteredItemsSelectionDialog.java b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/dialogs/FilteredItemsSelectionDialog.java index 81f76328eab..f6728cb2fb1 100644 --- a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/dialogs/FilteredItemsSelectionDialog.java +++ b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/dialogs/FilteredItemsSelectionDialog.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2018 IBM Corporation and others. + * Copyright (c) 2000, 2019 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -18,6 +18,8 @@ * Lars Vogel <Lars.Vogel@gmail.com> - Bug 440810 * Patrik Suzzi <psuzzi@gmail.com> - Bug 485133 * Lucas Bullen <lbullen@redhat.com> - Bug 525974, 531332 + * Emmanuel Chebbi <emmanuel.chebbi@outlook.fr> - Bug 214491 + * - [Dialogs] FilteredItemsSelectionDialog should respect setInitialSelections() *******************************************************************************/ package org.eclipse.ui.dialogs; @@ -230,6 +232,11 @@ public abstract class FilteredItemsSelectionDialog extends SelectionStatusDialog private IStyledStringHighlighter styledStringHighlighter; /** + * Used to set initial selection in {@link #refresh()}. + */ + private boolean isShownForTheFirstTime = true; + + /** * Creates a new instance of the class. * * @param shell shell to parent the dialog on @@ -857,13 +864,17 @@ public abstract class FilteredItemsSelectionDialog extends SelectionStatusDialog public void refresh() { if (tableViewer != null && !tableViewer.getTable().isDisposed()) { - List<?> lastRefreshSelection = ((StructuredSelection) tableViewer.getSelection()).toList(); + List<Object> lastRefreshSelection = ((StructuredSelection) tableViewer.getSelection()).toList(); tableViewer.getTable().deselectAll(); tableViewer.setItemCount(contentProvider.getNumberOfElements()); tableViewer.refresh(); if (tableViewer.getTable().getItemCount() > 0) { + if (isShownForTheFirstTime) { + isShownForTheFirstTime = false; + lastRefreshSelection = prepareInitialSelection(lastRefreshSelection); + } // preserve previous selection if (refreshWithLastSelection && lastRefreshSelection != null && lastRefreshSelection.size() > 0) { tableViewer.setSelection(new StructuredSelection(lastRefreshSelection)); @@ -882,6 +893,31 @@ public abstract class FilteredItemsSelectionDialog extends SelectionStatusDialog } /** + * Gets the elements that should be selected when the dialog opens. + * <p> + * Sets the <code>refreshWithLastSelection</code> to true if needed to make sure + * that the initial selection is properly set. + * + * @param currentSelection the elements selected by default. + * + * @return the initial selection specified by the user or the currentSelection + * if no initial selection has been set. + */ + private List<Object> prepareInitialSelection(List<Object> currentSelection) { + boolean hasNoInitialSelection = getInitialElementSelections().isEmpty(); + if (hasNoInitialSelection) { + return currentSelection; + } + refreshWithLastSelection = true; + if (!multi) { + // if multi selection is disabled then only the first item is selected + Object firstSelectedItem = getInitialElementSelections().get(0); + return Collections.singletonList(firstSelectedItem); + } + return getInitialElementSelections(); + } + + /** * Updates the progress label. */ @Deprecated diff --git a/tests/org.eclipse.ui.tests/Eclipse UI Tests/org/eclipse/ui/tests/dialogs/FilteredResourcesSelectionDialogTestSuite.java b/tests/org.eclipse.ui.tests/Eclipse UI Tests/org/eclipse/ui/tests/dialogs/FilteredResourcesSelectionDialogTestSuite.java index 48885ee46a1..40673c63e74 100644 --- a/tests/org.eclipse.ui.tests/Eclipse UI Tests/org/eclipse/ui/tests/dialogs/FilteredResourcesSelectionDialogTestSuite.java +++ b/tests/org.eclipse.ui.tests/Eclipse UI Tests/org/eclipse/ui/tests/dialogs/FilteredResourcesSelectionDialogTestSuite.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2017 Red Hat Inc. and others. + * Copyright (c) 2017-2019 Red Hat Inc. and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -10,6 +10,7 @@ * * Contributors: * Lucas Bullen (Red Hat Inc.) - initial API and implementation + * Emmanuel Chebbi - test dialog's initial selection - Bug 214491 *******************************************************************************/ package org.eclipse.ui.tests.dialogs; @@ -19,7 +20,7 @@ import junit.framework.Test; import junit.framework.TestSuite; /** - * The suite of tests for the filteredResourcesSelectionDialog. + * The suite of tests for the FilteredResourcesSelectionDialog. * * @since 3.14 */ @@ -40,5 +41,6 @@ public class FilteredResourcesSelectionDialogTestSuite extends TestSuite { */ public FilteredResourcesSelectionDialogTestSuite() { addTestSuite(ResourceItemLabelTest.class); + addTestSuite(ResourceInitialSelectionTest.class); } } diff --git a/tests/org.eclipse.ui.tests/Eclipse UI Tests/org/eclipse/ui/tests/dialogs/ResourceInitialSelectionTest.java b/tests/org.eclipse.ui.tests/Eclipse UI Tests/org/eclipse/ui/tests/dialogs/ResourceInitialSelectionTest.java new file mode 100644 index 00000000000..b24a9540160 --- /dev/null +++ b/tests/org.eclipse.ui.tests/Eclipse UI Tests/org/eclipse/ui/tests/dialogs/ResourceInitialSelectionTest.java @@ -0,0 +1,370 @@ +/******************************************************************************* + * Copyright (c) 2019 Emmanuel Chebbi + * + * 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: + * Emmanuel Chebbi - initial API and implementation + *******************************************************************************/ +package org.eclipse.ui.tests.dialogs; + +import static java.util.Arrays.asList; + +import java.io.ByteArrayInputStream; +import java.io.InputStream; +import java.util.Arrays; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; + +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.NullProgressMonitor; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Table; +import org.eclipse.swt.widgets.TableItem; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.dialogs.FilteredResourcesSelectionDialog; +import org.eclipse.ui.tests.harness.util.DisplayHelper; +import org.eclipse.ui.tests.harness.util.UITestCase; + +/** + * Tests that FilteredResourcesSelectionDialog selects its initial selection + * when opened. See also bug 214491. + * + * @since 3.14 + */ +public class ResourceInitialSelectionTest extends UITestCase { + + /** The names of the files created within the test project. */ + private final static List<String> FILE_NAMES = asList("foo.txt", "bar.txt", "foofoo"); + + /** The test files stored by name. */ + private final static Map<String, IFile> FILES = new HashMap<>(); + + /** Used to fill created files with an empty content. */ + private static InputStream stream = new ByteArrayInputStream(new byte[0]); + + private FilteredResourcesSelectionDialog dialog; + + private IProject project; + + /** + * Constructs a new instance of <code>ResourceItemInitialSelectionTest</code>. + * + * @param name The name of the test to be run. + */ + public ResourceInitialSelectionTest(String name) { + super(name); + } + + @Override + protected void doSetUp() throws Exception { + super.doSetUp(); + FILES.clear(); + createProject(); + } + + /** + * Test that a resource is selected by default even without initial selection. + */ + public void testSingleSelectionAndNoInitialSelectionWithInitialPattern() { + boolean hasMultiSelection = false; + dialog = createDialog(hasMultiSelection); + + dialog.setInitialPattern("**"); + dialog.open(); + dialog.refresh(); + + List<Object> selected = getSelectedItems(dialog); + + assertFalse("One file should be selected by default", selected.isEmpty()); + } + + /** + * Test that a specific resource can be selected by default. + */ + public void testSingleSelectionAndOneInitialSelectionWithInitialPattern() { + boolean hasMultiSelection = false; + dialog = createDialog(hasMultiSelection); + + dialog.setInitialPattern("**"); + dialog.setInitialElementSelections(asList(FILES.get("foo.txt"))); + dialog.open(); + dialog.refresh(); + + List<Object> selected = getSelectedItems(dialog); + + assertEquals("One file should be selected by default", asList(FILES.get("foo.txt")), selected); + } + + /** + * Test that no resource is selected by default when the specified one does not + * exist. + */ + public void testSingleSelectionAndOneInitialNonExistingSelectionWithInitialPattern() { + boolean hasMultiSelection = false; + dialog = createDialog(hasMultiSelection); + + dialog.setInitialPattern("**"); + dialog.setInitialElementSelections(asList("not an available item")); + dialog.open(); + dialog.refresh(); + + List<Object> selected = getSelectedItems(dialog); + + assertTrue("No file should be selected by default", selected.isEmpty()); + } + + /** + * Test that no resource is selected by default when no initial pattern is set. + */ + public void testSingleSelectionAndOneInitialSelectionWithoutInitialPattern() { + boolean hasMultiSelection = false; + dialog = createDialog(hasMultiSelection); + + dialog.setInitialElementSelections(asList(FILES.get("foo.txt"))); + dialog.open(); + dialog.refresh(); + + List<Object> selected = getSelectedItems(dialog); + + assertTrue("No file should be selected by default", selected.isEmpty()); + } + + /** + * Test that no resource is selected by default when the initial pattern does + * not match. + */ + public void testSingleSelectionAndOneFilteredSelection() { + boolean hasMultiSelection = false; + dialog = createDialog(hasMultiSelection); + + dialog.setInitialPattern("*.txt"); + dialog.setInitialElementSelections(asList(FILES.get("foofoo"))); + dialog.open(); + dialog.refresh(); + + List<Object> selected = getSelectedItems(dialog); + + assertTrue("No file should be selected by default", selected.isEmpty()); + } + + /** + * Test that only the first specified resource is selected when multi selection + * is disabled. + */ + public void testSingleSelectionAndTwoInitialSelectionsWithInitialPattern() { + boolean hasMultiSelection = false; + dialog = createDialog(hasMultiSelection); + + dialog.setInitialPattern("**"); + dialog.setInitialElementSelections(asList(FILES.get("foo.txt"), FILES.get("bar.txt"))); + dialog.open(); + dialog.refresh(); + + List<Object> selected = getSelectedItems(dialog); + + assertEquals("The first file should be selected by default", asList(FILES.get("foo.txt")), selected); + } + + /** + * Test that one resource is selected by default multi selection is enabled but + * no initial selection is specified. + */ + public void testMultiSelectionAndNoInitialSelectionWithInitialPattern() { + boolean hasMultiSelection = true; + dialog = createDialog(hasMultiSelection); + + dialog.setInitialPattern("**"); + dialog.open(); + dialog.refresh(); + + List<Object> selected = getSelectedItems(dialog); + + assertFalse("One file should be selected by default", selected.isEmpty()); + } + + /** + * Test that a specified resource can be selected by default when multi + * selection is enabled. + */ + public void testMultiSelectionAndOneInitialSelectionWithInitialPattern() { + boolean hasMultiSelection = true; + dialog = createDialog(hasMultiSelection); + + dialog.setInitialPattern("**"); + dialog.setInitialElementSelections(asList(FILES.get("foo.txt"))); + dialog.open(); + dialog.refresh(); + + List<Object> selected = getSelectedItems(dialog); + + assertEquals("One file should be selected by default", asList(FILES.get("foo.txt")), selected); + } + + /** + * Test that no resource is selected by default when no initial pattern is set. + */ + public void testMultiSelectionAndOneInitialSelectionWithoutInitialPattern() { + boolean hasMultiSelection = true; + dialog = createDialog(hasMultiSelection); + + dialog.setInitialElementSelections(asList(FILES.get("foo.txt"))); + dialog.open(); + dialog.refresh(); + + List<Object> selected = getSelectedItems(dialog); + + assertTrue("No file should be selected by default", selected.isEmpty()); + } + + /** + * Test that no item is selected by default when non existing items are + * specified. + */ + public void testMultiSelectionAndTwoInitialNonExistingSelectionWithInitialPattern() { + boolean hasMultiSelection = true; + dialog = createDialog(hasMultiSelection); + + dialog.setInitialPattern("**"); + dialog.setInitialElementSelections(asList("not an available item", "still not an available item")); + dialog.open(); + dialog.refresh(); + + List<Object> selected = getSelectedItems(dialog); + + assertTrue("No file should be selected by default", selected.isEmpty()); + } + + /** + * Test that only existing items are selected by default when some of the + * specified initial selections do not exist. + */ + public void testMultiSelectionAndSomeInitialNonExistingSelectionWithInitialPattern() { + boolean hasMultiSelection = true; + dialog = createDialog(hasMultiSelection); + + dialog.setInitialPattern("**"); + dialog.setInitialElementSelections(asList(FILES.get("bar.txt"), "not an available item", FILES.get("foofoo"))); + dialog.open(); + dialog.refresh(); + + List<Object> selected = getSelectedItems(dialog); + Set<IFile> expectedSelection = new HashSet<>(asList(FILES.get("bar.txt"), FILES.get("foofoo"))); + boolean allInitialElementsAreSelected = expectedSelection.equals(new HashSet<>(selected)); + + assertTrue("Two files should be selected by default", allInitialElementsAreSelected); + } + + /** + * Test that several specified resources can be selected by default. + */ + public void testMultiSelectionAndTwoInitialSelectionsWithInitialPattern() { + boolean hasMultiSelection = true; + List<IFile> initialSelection = asList(FILES.get("foo.txt"), FILES.get("bar.txt")); + + dialog = createDialog(hasMultiSelection); + dialog.setInitialPattern("**"); + dialog.setInitialElementSelections(initialSelection); + dialog.open(); + dialog.refresh(); + + List<Object> selected = getSelectedItems(dialog); + boolean initialElementsAreSelected = selected.containsAll(initialSelection) + && initialSelection.containsAll(selected); + + assertTrue("Two files should be selected by default", initialElementsAreSelected); + } + + /** + * Test that several specified resources can be selected by default but are + * ignored if the initial pattern does not match. + */ + public void testMultiSelectionAndTwoInitialFilteredSelections() { + boolean hasMultiSelection = true; + + dialog = createDialog(hasMultiSelection); + dialog.setInitialPattern("*.txt"); + dialog.setInitialElementSelections(asList(FILES.get("foo.txt"), FILES.get("bar.txt"), FILES.get("foofoo"))); + dialog.open(); + dialog.refresh(); + + List<Object> selected = getSelectedItems(dialog); + List<IFile> expectedSelection = asList(FILES.get("foo.txt"), FILES.get("bar.txt")); + boolean initialElementsAreSelected = selected.containsAll(expectedSelection) + && expectedSelection.containsAll(selected); + + assertTrue("Two files should be selected by default", initialElementsAreSelected); + } + + private FilteredResourcesSelectionDialog createDialog(boolean multiSelection) { + FilteredResourcesSelectionDialog dialog = new FilteredResourcesSelectionDialog( + PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(), multiSelection, project, + IResource.FILE); + dialog.setBlockOnOpen(false); + return dialog; + } + + private List<Object> getSelectedItems(FilteredResourcesSelectionDialog dialog) { + Table table = (Table) ((Composite) ((Composite) ((Composite) dialog.getShell().getChildren()[0]) + .getChildren()[0]).getChildren()[0]).getChildren()[3]; + List<Object> selected = Arrays.stream(table.getSelection()).map(TableItem::getData) + .collect(Collectors.toList()); + return selected; + } + + private void createProject() throws CoreException { + project = ResourcesPlugin.getWorkspace().getRoot() + .getProject(getClass().getName() + "_" + System.currentTimeMillis()); + project.create(new NullProgressMonitor()); + project.open(new NullProgressMonitor()); + + // Create files + + for (String fileName : FILE_NAMES) { + IFile file = project.getFile(fileName); + file.create(stream, true, new NullProgressMonitor()); + FILES.put(fileName, file); + } + project.refreshLocal(IResource.DEPTH_INFINITE, new NullProgressMonitor()); + + // Assert files have been properly created + + Shell shell = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(); + + for (String fileName : FILE_NAMES) { + new DisplayHelper() { + @Override + protected boolean condition() { + return project.getFile(fileName).exists(); + } + }.waitForCondition(shell.getDisplay(), 1000); + + assertTrue("File was not created", project.getFile(fileName).exists()); + } + } + + @Override + protected void doTearDown() throws Exception { + if (dialog != null) { + dialog.close(); + } + if (project != null) { + project.delete(true, null); + } + super.doTearDown(); + } +} |
