diff options
author | Xavier Coulon | 2016-01-12 15:58:21 +0000 |
---|---|---|
committer | Xavier Coulon | 2016-01-19 07:57:47 +0000 |
commit | 74009a4c16dd7d815428a428cde147b63dead303 (patch) | |
tree | bc7c97dd119d1ba6970fdce35780b82a9ce07764 | |
parent | 71dce61d031b429041d048f10c80f7f896b69ed5 (diff) | |
download | org.eclipse.linuxtools-74009a4c16dd7d815428a428cde147b63dead303.tar.gz org.eclipse.linuxtools-74009a4c16dd7d815428a428cde147b63dead303.tar.xz org.eclipse.linuxtools-74009a4c16dd7d815428a428cde147b63dead303.zip |
Bug 469372 - Improve contextual menus
Added a Show In>Properties context menu for:
- connections
- images
- containers
Added SWTBot tests to verify that the menus are available
and that the properties view is opened when clicking on the
menu.
Change-Id: I857df72bd705afe7a92dec72b3b43c61b1cde9ff
Signed-off-by: Xavier Coulon <xcoulon@redhat.com>
Reviewed-on: https://git.eclipse.org/r/64148
Tested-by: Hudson CI
Reviewed-by: Jeff Johnston <jjohnstn@redhat.com>
Reviewed-on: https://git.eclipse.org/r/64611
8 files changed, 403 insertions, 90 deletions
diff --git a/containers/org.eclipse.linuxtools.docker.ui.tests/src/org/eclipse/linuxtools/internal/docker/ui/testutils/swt/SWTUtils.java b/containers/org.eclipse.linuxtools.docker.ui.tests/src/org/eclipse/linuxtools/internal/docker/ui/testutils/swt/SWTUtils.java index 2132a5ec4e..16277e7c7d 100644 --- a/containers/org.eclipse.linuxtools.docker.ui.tests/src/org/eclipse/linuxtools/internal/docker/ui/testutils/swt/SWTUtils.java +++ b/containers/org.eclipse.linuxtools.docker.ui.tests/src/org/eclipse/linuxtools/internal/docker/ui/testutils/swt/SWTUtils.java @@ -11,14 +11,25 @@ import java.util.stream.Collectors; import java.util.stream.Stream; import org.eclipse.core.runtime.jobs.Job; +import org.eclipse.swt.SWT; import org.eclipse.swt.SWTException; import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Menu; import org.eclipse.swt.widgets.Tree; import org.eclipse.swtbot.eclipse.finder.widgets.SWTBotView; +import org.eclipse.swtbot.swt.finder.finders.UIThreadRunnable; +import org.eclipse.swtbot.swt.finder.results.Result; +import org.eclipse.swtbot.swt.finder.results.VoidResult; +import org.eclipse.swtbot.swt.finder.widgets.SWTBotMenu; import org.eclipse.swtbot.swt.finder.widgets.SWTBotTree; import org.eclipse.swtbot.swt.finder.widgets.SWTBotTreeItem; +import org.junit.Assert; import org.junit.ComparisonFailure; +/** + * Utility class for SWT + */ public class SWTUtils { /** @@ -61,7 +72,8 @@ public class SWTUtils { * the {@link Runnable} to execute * @throws ComparisonFailure * if an assertion failed. - * @throws SWTException if an {@link SWTException} occurred + * @throws SWTException + * if an {@link SWTException} occurred */ public static void syncAssert(final Runnable runnable) throws SWTException, ComparisonFailure { final Queue<ComparisonFailure> failure = new ArrayBlockingQueue<>(1); @@ -121,7 +133,7 @@ public class SWTUtils { } /** - * Waits for all {@link Job} to complete. + * Waits for all {@link Job} to complete. * * @throws InterruptedException */ @@ -133,33 +145,47 @@ public class SWTUtils { } /** - * @param viewBot the {@link SWTBotView} containing the {@link Tree} to traverse - * @param paths the node path in the {@link SWTBotTree} associated with the given {@link SWTBotView} + * @param viewBot + * the {@link SWTBotView} containing the {@link Tree} to traverse + * @param paths + * the node path in the {@link SWTBotTree} associated with the + * given {@link SWTBotView} * @return the first {@link SWTBotTreeItem} matching the given node names */ public static SWTBotTreeItem getTreeItem(final SWTBotView viewBot, final String... paths) { final SWTBotTree tree = viewBot.bot().tree(); return getTreeItem(tree.getAllItems(), paths); } - + + /** + * + * @param parentTreeItem the parent tree item from which to start + * @param paths the relative path to the item to return + * @return the {@link SWTBotTreeItem} that matches the given path from the given parent tree item + */ public static SWTBotTreeItem getTreeItem(final SWTBotTreeItem parentTreeItem, final String... paths) { - if(paths.length == 1) { + if (paths.length == 1) { return getTreeItem(parentTreeItem, paths[0]); } - final String[] remainingPaths = new String[paths.length-1]; - System.arraycopy(paths, 1, remainingPaths, 0, paths.length-1); + final String[] remainingPaths = new String[paths.length - 1]; + System.arraycopy(paths, 1, remainingPaths, 0, paths.length - 1); return getTreeItem(getTreeItem(parentTreeItem, paths[0]), remainingPaths); } /** - * Returns the first child node in the given parent tree item whose text matches (ie, begins with) the given path argument. - * @param parentTreeItem the parent tree item - * @param path the text of the node that should match - * @return the first matching node or <code>null</code> if none could be found + * Returns the first child node in the given parent tree item whose text + * matches (ie, begins with) the given path argument. + * + * @param parentTreeItem + * the parent tree item + * @param path + * the text of the node that should match + * @return the first matching node or <code>null</code> if none could be + * found */ public static SWTBotTreeItem getTreeItem(final SWTBotTreeItem parentTreeItem, final String path) { for (SWTBotTreeItem child : parentTreeItem.getItems()) { - if(child.getText().startsWith(path)) { + if (child.getText().startsWith(path)) { return child; } } @@ -167,15 +193,21 @@ public class SWTUtils { } private static SWTBotTreeItem getTreeItem(final SWTBotTreeItem[] treeItems, final String[] paths) { - final SWTBotTreeItem swtBotTreeItem = Stream.of(treeItems).filter(item -> item.getText().startsWith(paths[0])).findFirst().get(); - if(paths.length > 1) { - final String[] remainingPath = new String[paths.length -1]; + final SWTBotTreeItem swtBotTreeItem = Stream.of(treeItems).filter(item -> item.getText().startsWith(paths[0])) + .findFirst().get(); + if (paths.length > 1) { + final String[] remainingPath = new String[paths.length - 1]; System.arraycopy(paths, 1, remainingPath, 0, remainingPath.length); return getTreeItem(swtBotTreeItem.getItems(), remainingPath); } return swtBotTreeItem; } + /** + * Waits for the given duration + * @param duration the duration + * @param unit the duration unit + */ public static void wait(final int duration, final TimeUnit unit) { try { Thread.sleep(unit.toMillis(duration)); @@ -185,9 +217,13 @@ public class SWTUtils { } /** - * Selects all child items in the given <code>parentTreeItm</code> whose labels match the given <code>items</code>. - * @param parentTreeItem the parent tree item - * @param matchItems the items to select + * Selects <strong> all child items</strong> in the given <code>parentTreeItem</code> whose + * labels match the given <code>items</code>. + * + * @param parentTreeItem + * the parent tree item + * @param matchItems + * the items to select */ public static void select(SWTBotTreeItem parentTreeItem, String... matchItems) { final List<String> fullyQualifiedItems = Stream.of(parentTreeItem.getItems()) @@ -196,5 +232,69 @@ public class SWTUtils { .map(item -> item.getText()).collect(Collectors.toList()); parentTreeItem.select(fullyQualifiedItems.toArray(new String[0])); } + + /** + * @param tree the root {@link SWTBotTree} + * @param path the path for the menu + * @return the child {@link SWTBotMenu} named with the first item in the given <code>path</code> from the given {@link SWTBotTree} + */ + public static SWTBotMenu getContextMenu(final SWTBotTree tree, String... path) { + final SWTBotMenu contextMenu = tree.contextMenu(path[0]); + if(contextMenu == null) { + Assert.fail("Failed to find context menu '" + path[0] +"'."); + } + if(path.length == 1) { + return contextMenu; + } + final String[] remainingPath = new String[path.length -1]; + System.arraycopy(path, 1, remainingPath, 0, remainingPath.length); + return getSubMenu(contextMenu, remainingPath); + } + + /** + * Hides the menu for the given <code>tree</code> + * @param tree the tree whose {@link Menu} should be hidden + */ + public static void hideMenu(final SWTBotTree tree) { + final Menu menu = UIThreadRunnable.syncExec(new Result<Menu>() { + + @Override + public Menu run() { + return tree.widget.getMenu(); + } + }); + UIThreadRunnable.syncExec(new VoidResult() { + + @Override + public void run() { + hide(menu); + } + + private void hide(final Menu menu) { + menu.notifyListeners(SWT.Hide, new Event()); + if (menu.getParentMenu() != null) { + hide(menu.getParentMenu()); + } + } + }); + } + + /** + * @param menu the parent menu + * @param path the path for the menu + * @return the child {@link SWTBotMenu} named with the first item in the given <code>path</code> from the given {@link SWTBotMenu} + */ + public static SWTBotMenu getSubMenu(final SWTBotMenu menu, String... path) { + final SWTBotMenu subMenu = menu.menu(path[0]); + if(subMenu == null) { + Assert.fail("Failed to find submenu '" + path[0] +"'."); + } + if(path.length == 1) { + return subMenu; + } + final String[] remainingPath = new String[path.length -1]; + System.arraycopy(path, 1, remainingPath, 0, remainingPath.length); + return getSubMenu(subMenu, remainingPath); + } } diff --git a/containers/org.eclipse.linuxtools.docker.ui.tests/src/org/eclipse/linuxtools/internal/docker/ui/views/DockerExplorerViewSWTBotTest.java b/containers/org.eclipse.linuxtools.docker.ui.tests/src/org/eclipse/linuxtools/internal/docker/ui/views/DockerExplorerViewSWTBotTest.java index ac6dc2e9ee..ec26621b1f 100644 --- a/containers/org.eclipse.linuxtools.docker.ui.tests/src/org/eclipse/linuxtools/internal/docker/ui/views/DockerExplorerViewSWTBotTest.java +++ b/containers/org.eclipse.linuxtools.docker.ui.tests/src/org/eclipse/linuxtools/internal/docker/ui/views/DockerExplorerViewSWTBotTest.java @@ -33,11 +33,12 @@ import org.eclipse.linuxtools.internal.docker.ui.testutils.swt.TestLoggerRule; import org.eclipse.swtbot.eclipse.finder.SWTWorkbenchBot; import org.eclipse.swtbot.eclipse.finder.waits.Conditions; import org.eclipse.swtbot.eclipse.finder.widgets.SWTBotView; +import org.eclipse.swtbot.swt.finder.exceptions.WidgetNotFoundException; import org.eclipse.swtbot.swt.finder.junit.SWTBotJunit4ClassRunner; import org.eclipse.swtbot.swt.finder.widgets.SWTBotMenu; -import org.eclipse.swtbot.swt.finder.widgets.SWTBotTree; import org.eclipse.swtbot.swt.finder.widgets.SWTBotTreeItem; import org.eclipse.ui.PlatformUI; +import org.junit.After; import org.junit.Assert; import org.junit.Before; import org.junit.ClassRule; @@ -56,7 +57,6 @@ public class DockerExplorerViewSWTBotTest { private SWTWorkbenchBot bot = new SWTWorkbenchBot(); private SWTBotView dockerExplorerViewBot; private DockerExplorerView dockerExplorerView; - private SWTBotTree dockerExplorerViewTreeBot; @ClassRule public static CloseWelcomePageRule closeWelcomePage = new CloseWelcomePageRule(); @@ -81,11 +81,49 @@ public class DockerExplorerViewSWTBotTest { this.dockerExplorerView = (DockerExplorerView) (dockerExplorerViewBot.getViewReference().getView(true)); this.bot.views().stream() .filter(v -> v.getReference().getId().equals("org.eclipse.linuxtools.docker.ui.dockerContainersView") - || v.getReference().getId().equals("org.eclipse.linuxtools.docker.ui.dockerImagesView")) + || v.getReference().getId().equals("org.eclipse.linuxtools.docker.ui.dockerImagesView") + || v.getReference().getId().equals("org.eclipse.ui.views.PropertySheet")) .forEach(v -> v.close()); } + + @After + public void hideMenu() { + try { + SWTUtils.hideMenu(dockerExplorerViewBot.bot().tree()); + } catch(WidgetNotFoundException e) { + // ignore if widget is not found, that's probably because there's no tree in the + // Docker Explorer view for the test that just ran. + } + } + + private void selectConnectionInTreeView(final String connectionName) { + final SWTBotTreeItem connectionTreeItem = SWTUtils.getTreeItem(dockerExplorerViewBot, connectionName); + connectionTreeItem.select(); + } - @Test + private void selectContainersInTreeView(final String connectionName, final String... containerNames) { + SWTUtils.asyncExec(() -> dockerExplorerView.getCommonViewer().expandAll()); + // When a second call to expand the container is done (because the first + // expandAll stopped with a "Loading..." job that retrieved the + // containers) + final SWTBotTreeItem containersTreeItem = SWTUtils.getTreeItem(dockerExplorerViewBot, connectionName, "Containers"); + SWTUtils.asyncExec(() -> containersTreeItem.expand()); + // select both containers + SWTUtils.select(containersTreeItem, containerNames); + } + + private void selectImagesInTreeView(final String connectionName, final String... imageNames) { + SWTUtils.asyncExec(() -> dockerExplorerView.getCommonViewer().expandAll()); + // when a second call to expand the container is done (because the first + // expandAll stopped with a "Loading..." job that retrieved the + // containers) + final SWTBotTreeItem imagesTreeItem = SWTUtils.getTreeItem(dockerExplorerViewBot, connectionName, "Images"); + SWTUtils.asyncExec(() -> imagesTreeItem.expand()); + // select both containers + SWTUtils.select(imagesTreeItem, imageNames); + } + + @Test public void shouldDisplayExplanationPane() { // given DockerConnectionManagerUtils.configureConnectionManager(); @@ -93,7 +131,7 @@ public class DockerExplorerViewSWTBotTest { DockerExplorerViewAssertion.assertThat(dockerExplorerView).isEmpty(); } - @Test + @Test public void shouldDisplayConnectionsPane() { // given final DockerClient client = MockDockerClientFactory.build(); @@ -103,7 +141,7 @@ public class DockerExplorerViewSWTBotTest { DockerExplorerViewAssertion.assertThat(dockerExplorerView).isNotEmpty(); } - @Test + @Test public void shouldRefreshImagesAndShowChanges() { // given final DockerClient client = MockDockerClientFactory.build(); @@ -123,9 +161,8 @@ public class DockerExplorerViewSWTBotTest { .build(); dockerConnection.setClient(updatedClient); // when locating the 'Images' node and hit refresh - dockerExplorerViewTreeBot = dockerExplorerViewBot.bot().tree(); - dockerExplorerViewTreeBot.select(imagesTreeItem); - dockerExplorerViewTreeBot.contextMenu("Refresh").click(); + dockerExplorerViewBot.bot().tree().select(imagesTreeItem); + dockerExplorerViewBot.bot().tree().contextMenu("Refresh").click(); SWTUtils.wait(2, TimeUnit.SECONDS); imagesTreeItem.expand(); Conditions.waitForJobs(DockerExplorerView.class, "Docker Explorer View jobs"); @@ -134,7 +171,7 @@ public class DockerExplorerViewSWTBotTest { Assertions.assertThat(imagesTreeItem.getItems().length).isEqualTo(1); } - @Test + @Test public void shouldRefreshContainersAndShowChanges() { // given final DockerClient client = MockDockerClientFactory.build(); @@ -154,9 +191,8 @@ public class DockerExplorerViewSWTBotTest { // update the client final DockerClient updatedClient = MockDockerClientFactory.container(MockDockerContainerFactory.name("foo_bar").build()).build(); dockerConnection.setClient(updatedClient); - dockerExplorerViewTreeBot = dockerExplorerViewBot.bot().tree(); - dockerExplorerViewTreeBot.select(containersTreeItem); - dockerExplorerViewTreeBot.contextMenu("Refresh").click(); + dockerExplorerViewBot.bot().tree().select(containersTreeItem); + dockerExplorerViewBot.bot().tree().contextMenu("Refresh").click(); SWTUtils.asyncExec(() -> containersTreeItem.expand()); // then check that there are images now @@ -164,7 +200,7 @@ public class DockerExplorerViewSWTBotTest { Assertions.assertThat(containersTreeItem.getItems().length).isEqualTo(1); } - @Test + @Test public void shouldShowContainerPortMapping() { // given final DockerClient client = MockDockerClientFactory @@ -193,7 +229,7 @@ public class DockerExplorerViewSWTBotTest { }); } - @Test + @Test public void shouldShowContainerLinks() { // given final DockerClient client = MockDockerClientFactory @@ -219,7 +255,7 @@ public class DockerExplorerViewSWTBotTest { }); } - @Test + @Test public void shouldShowContainerVolumes() { // given final DockerClient client = MockDockerClientFactory @@ -250,7 +286,7 @@ public class DockerExplorerViewSWTBotTest { }); } - @Test + @Test public void shouldRemainExpandedAfterRefresh() { // given final DockerClient client = MockDockerClientFactory @@ -277,9 +313,8 @@ public class DockerExplorerViewSWTBotTest { SWTBotTreeItemAssertions.assertThat(SWTUtils.getTreeItem(containerTreeItem, "Volumes")).isExpanded(); }); // when refreshing the container - dockerExplorerViewTreeBot = dockerExplorerViewBot.bot().tree(); - dockerExplorerViewTreeBot.select(containersTreeItem); - dockerExplorerViewTreeBot.contextMenu("Refresh").click(); + dockerExplorerViewBot.bot().tree().select(containersTreeItem); + dockerExplorerViewBot.bot().tree().contextMenu("Refresh").click(); SWTUtils.asyncExec(() -> containersTreeItem.expand()); // then all items should remain expanded (after they were reloaded) SWTUtils.syncAssert(() -> { @@ -289,7 +324,7 @@ public class DockerExplorerViewSWTBotTest { }); } - @Test + @Test public void shouldProvideEnabledStartCommandOnMultipleContainersAtOnce() { // given final DockerClient client = MockDockerClientFactory @@ -298,14 +333,14 @@ public class DockerExplorerViewSWTBotTest { final DockerConnection dockerConnection = MockDockerConnectionFactory.from("Test", client).get(); DockerConnectionManagerUtils.configureConnectionManager(dockerConnection); // open the context menu on one of the containers - selectMultipleContainersInTreeView(); + selectContainersInTreeView("Test", "gentle_foo", "angry_bar"); final SWTBotMenu menuCommand = dockerExplorerViewBot.bot().tree().contextMenu("Start"); // then assertThat(menuCommand.isVisible()).isEqualTo(true); assertThat(menuCommand.isEnabled()).isEqualTo(true); } - @Test + @Test public void shouldProvideDisabledStartCommandOnMultipleContainersAtOnce() { // given final DockerClient client = MockDockerClientFactory @@ -314,14 +349,14 @@ public class DockerExplorerViewSWTBotTest { final DockerConnection dockerConnection = MockDockerConnectionFactory.from("Test", client).get(); DockerConnectionManagerUtils.configureConnectionManager(dockerConnection); // open the context menu on one of the containers - selectMultipleContainersInTreeView(); + selectContainersInTreeView("Test", "gentle_foo", "angry_bar"); final SWTBotMenu menuCommand = dockerExplorerViewBot.bot().tree().contextMenu("Start"); // then assertThat(menuCommand.isVisible()).isEqualTo(true); assertThat(menuCommand.isEnabled()).isEqualTo(false); } - @Test + @Test public void shouldProvideEnabledStopCommandOnMultipleContainersAtOnce() { // given final DockerClient client = MockDockerClientFactory @@ -330,14 +365,14 @@ public class DockerExplorerViewSWTBotTest { final DockerConnection dockerConnection = MockDockerConnectionFactory.from("Test", client).get(); DockerConnectionManagerUtils.configureConnectionManager(dockerConnection); // open the context menu on one of the containers - selectMultipleContainersInTreeView(); + selectContainersInTreeView("Test", "gentle_foo", "angry_bar"); final SWTBotMenu menuCommand = dockerExplorerViewBot.bot().tree().contextMenu("Stop"); // then assertThat(menuCommand.isVisible()).isEqualTo(true); assertThat(menuCommand.isEnabled()).isEqualTo(true); } - @Test + @Test public void shouldProvideDisabledStopCommandOnMultipleContainersAtOnce() { // given final DockerClient client = MockDockerClientFactory @@ -346,14 +381,14 @@ public class DockerExplorerViewSWTBotTest { final DockerConnection dockerConnection = MockDockerConnectionFactory.from("Test", client).get(); DockerConnectionManagerUtils.configureConnectionManager(dockerConnection); // open the context menu on one of the containers - selectMultipleContainersInTreeView(); + selectContainersInTreeView("Test", "gentle_foo", "angry_bar"); final SWTBotMenu menuCommand = dockerExplorerViewBot.bot().tree().contextMenu("Stop"); // then assertThat(menuCommand.isVisible()).isEqualTo(true); assertThat(menuCommand.isEnabled()).isEqualTo(false); } - @Test + @Test public void shouldProvideEnabledPauseCommandOnMultipleContainersAtOnce() { // given final DockerClient client = MockDockerClientFactory @@ -362,14 +397,14 @@ public class DockerExplorerViewSWTBotTest { final DockerConnection dockerConnection = MockDockerConnectionFactory.from("Test", client).get(); DockerConnectionManagerUtils.configureConnectionManager(dockerConnection); // open the context menu on one of the containers - selectMultipleContainersInTreeView(); + selectContainersInTreeView("Test", "gentle_foo", "angry_bar"); final SWTBotMenu menuCommand = dockerExplorerViewBot.bot().tree().contextMenu("Pause"); // then assertThat(menuCommand.isVisible()).isEqualTo(true); assertThat(menuCommand.isEnabled()).isEqualTo(true); } - @Test + @Test public void shouldProvideDisabledPauseCommandOnMultipleContainersAtOnce() { // given final DockerClient client = MockDockerClientFactory @@ -378,14 +413,14 @@ public class DockerExplorerViewSWTBotTest { final DockerConnection dockerConnection = MockDockerConnectionFactory.from("Test", client).get(); DockerConnectionManagerUtils.configureConnectionManager(dockerConnection); // open the context menu on one of the containers - selectMultipleContainersInTreeView(); + selectContainersInTreeView("Test", "gentle_foo", "angry_bar"); final SWTBotMenu menuCommand = dockerExplorerViewBot.bot().tree().contextMenu("Pause"); // then assertThat(menuCommand.isVisible()).isEqualTo(true); assertThat(menuCommand.isEnabled()).isEqualTo(false); } - @Test + @Test public void shouldProvideEnabledUnpauseCommandOnMultipleContainersAtOnce() { // given final DockerClient client = MockDockerClientFactory @@ -394,14 +429,14 @@ public class DockerExplorerViewSWTBotTest { final DockerConnection dockerConnection = MockDockerConnectionFactory.from("Test", client).get(); DockerConnectionManagerUtils.configureConnectionManager(dockerConnection); // open the context menu on one of the containers - selectMultipleContainersInTreeView(); + selectContainersInTreeView("Test", "gentle_foo", "angry_bar"); final SWTBotMenu menuCommand = dockerExplorerViewBot.bot().tree().contextMenu("Unpause"); // then assertThat(menuCommand.isVisible()).isEqualTo(true); assertThat(menuCommand.isEnabled()).isEqualTo(true); } - @Test + @Test public void shouldProvideDisabledUnpauseCommandOnMultipleContainersAtOnce() { // given final DockerClient client = MockDockerClientFactory @@ -410,14 +445,14 @@ public class DockerExplorerViewSWTBotTest { final DockerConnection dockerConnection = MockDockerConnectionFactory.from("Test", client).get(); DockerConnectionManagerUtils.configureConnectionManager(dockerConnection); // open the context menu on one of the containers - selectMultipleContainersInTreeView(); + selectContainersInTreeView("Test", "gentle_foo", "angry_bar"); final SWTBotMenu menuCommand = dockerExplorerViewBot.bot().tree().contextMenu("Unpause"); // then assertThat(menuCommand.isVisible()).isEqualTo(true); assertThat(menuCommand.isEnabled()).isEqualTo(false); } - @Test + @Test public void shouldProvideEnabledKillCommandOnMultipleContainersAtOnce() { // given final DockerClient client = MockDockerClientFactory @@ -426,14 +461,14 @@ public class DockerExplorerViewSWTBotTest { final DockerConnection dockerConnection = MockDockerConnectionFactory.from("Test", client).get(); DockerConnectionManagerUtils.configureConnectionManager(dockerConnection); // open the context menu on one of the containers - selectMultipleContainersInTreeView(); + selectContainersInTreeView("Test", "gentle_foo", "angry_bar"); final SWTBotMenu menuCommand = dockerExplorerViewBot.bot().tree().contextMenu("Kill"); // then assertThat(menuCommand.isVisible()).isEqualTo(true); assertThat(menuCommand.isEnabled()).isEqualTo(true); } - @Test + @Test public void shouldProvideDisabledKillCommandOnMultipleContainersAtOnce() { // given final DockerClient client = MockDockerClientFactory @@ -442,14 +477,14 @@ public class DockerExplorerViewSWTBotTest { final DockerConnection dockerConnection = MockDockerConnectionFactory.from("Test", client).get(); DockerConnectionManagerUtils.configureConnectionManager(dockerConnection); // open the context menu on one of the containers - selectMultipleContainersInTreeView(); + selectContainersInTreeView("Test", "gentle_foo", "angry_bar"); final SWTBotMenu menuCommand = dockerExplorerViewBot.bot().tree().contextMenu("Kill"); // then assertThat(menuCommand.isVisible()).isEqualTo(true); assertThat(menuCommand.isEnabled()).isEqualTo(false); } - @Test + @Test public void shouldProvideEnabledRemoveCommandOnMultipleContainersAtOnce() { // given final DockerClient client = MockDockerClientFactory @@ -458,14 +493,14 @@ public class DockerExplorerViewSWTBotTest { final DockerConnection dockerConnection = MockDockerConnectionFactory.from("Test", client).get(); DockerConnectionManagerUtils.configureConnectionManager(dockerConnection); // open the context menu on one of the containers - selectMultipleContainersInTreeView(); + selectContainersInTreeView("Test", "gentle_foo", "angry_bar"); final SWTBotMenu menuCommand = dockerExplorerViewBot.bot().tree().contextMenu("Remove"); // then assertThat(menuCommand.isVisible()).isEqualTo(true); assertThat(menuCommand.isEnabled()).isEqualTo(true); } - @Test + @Test public void shouldProvideRemoveCommandOnMultipleContainersAtOnce() { // given final DockerClient client = MockDockerClientFactory @@ -474,23 +509,55 @@ public class DockerExplorerViewSWTBotTest { final DockerConnection dockerConnection = MockDockerConnectionFactory.from("Test", client).get(); DockerConnectionManagerUtils.configureConnectionManager(dockerConnection); // open the context menu on one of the containers - selectMultipleContainersInTreeView(); + selectContainersInTreeView("Test", "gentle_foo", "angry_bar"); final SWTBotMenu menuCommand = dockerExplorerViewBot.bot().tree().contextMenu("Remove"); // then assertThat(menuCommand.isVisible()).isEqualTo(true); assertThat(menuCommand.isEnabled()).isEqualTo(false); } - private SWTBotTreeItem selectMultipleContainersInTreeView() { - SWTUtils.asyncExec(() -> dockerExplorerView.getCommonViewer().expandAll()); - // when a second call to expand the container is done (because the first - // expandAll stopped with a "Loading..." job that retrieved the - // containers) - final SWTBotTreeItem containersTreeItem = SWTUtils.getTreeItem(dockerExplorerViewBot, "Test", "Containers"); - SWTUtils.asyncExec(() -> containersTreeItem.expand()); - // select both containers - SWTUtils.select(containersTreeItem, "gentle_foo", "angry_bar"); - final SWTBotTreeItem containerTreeItem = SWTUtils.getTreeItem(containersTreeItem, "gentle_foo"); - return containerTreeItem; + @Test + public void shouldShowSelectedConnectionInPropertiesView() { + // given + final DockerClient client = MockDockerClientFactory + .build(); + final DockerConnection dockerConnection = MockDockerConnectionFactory.from("Test", client).get(); + DockerConnectionManagerUtils.configureConnectionManager(dockerConnection); + // open the context menu on one the container + selectConnectionInTreeView("Test"); + // show container info in Properties view + SWTUtils.getContextMenu(dockerExplorerViewBot.bot().tree(), "Show In", "Properties").click(); + // the properties view should be visible + assertThat(this.bot.viewById("org.eclipse.ui.views.PropertySheet").isActive()).isEqualTo(true); + } + + @Test + public void shouldShowSelectedContainerInPropertiesView() { + // given + final DockerClient client = MockDockerClientFactory + .container(MockDockerContainerFactory.name("angry_bar").status("Stopped").build()).build(); + final DockerConnection dockerConnection = MockDockerConnectionFactory.from("Test", client).get(); + DockerConnectionManagerUtils.configureConnectionManager(dockerConnection); + // open the context menu on one the container + selectContainersInTreeView("Test", "angry_bar"); + // show container info in Properties view + SWTUtils.getContextMenu(dockerExplorerViewBot.bot().tree(), "Show In", "Properties").click(); + // the properties view should be visible + assertThat(this.bot.viewById("org.eclipse.ui.views.PropertySheet").isActive()).isEqualTo(true); + } + + @Test + public void shouldShowSelectedImageInPropertiesView() { + // given + final DockerClient client = MockDockerClientFactory + .image(MockDockerImageFactory.name("angry_bar").build()).build(); + final DockerConnection dockerConnection = MockDockerConnectionFactory.from("Test", client).get(); + DockerConnectionManagerUtils.configureConnectionManager(dockerConnection); + // open the context menu on one the container + selectImagesInTreeView("Test", "angry_bar"); + // show container info in Properties view + SWTUtils.getContextMenu(dockerExplorerViewBot.bot().tree(), "Show In", "Properties").click(); + // the properties view should be visible + assertThat(this.bot.viewById("org.eclipse.ui.views.PropertySheet").isActive()).isEqualTo(true); } } diff --git a/containers/org.eclipse.linuxtools.docker.ui/plugin.properties b/containers/org.eclipse.linuxtools.docker.ui/plugin.properties index b9db73e2e5..266149b0b7 100644 --- a/containers/org.eclipse.linuxtools.docker.ui/plugin.properties +++ b/containers/org.eclipse.linuxtools.docker.ui/plugin.properties @@ -101,10 +101,14 @@ command.removeconnection.label=&Remove Connection command.addconnection.label=&Add Connection command.runimage.name=Run +command.runimage.description=Run an Image command.runimage.label=Run... menu.showIn=Show In +command.showInPropertiesView.menu.name=Properties +command.showInPropertiesView.menu.description=Show in Properties View + command.showInWebBrowser.menu.name=Web Browser command.showInWebBrowser.menu.description=Show in Web Browser diff --git a/containers/org.eclipse.linuxtools.docker.ui/plugin.xml b/containers/org.eclipse.linuxtools.docker.ui/plugin.xml index 7bf1bf8562..18c56269dd 100644 --- a/containers/org.eclipse.linuxtools.docker.ui/plugin.xml +++ b/containers/org.eclipse.linuxtools.docker.ui/plugin.xml @@ -69,10 +69,10 @@ id="org.eclipse.linuxtools.docker.ui.dockerExplorerView#PopupMenu"> <insertionPoint name="group.run" separator="true"/> <insertionPoint name="group.refresh" separator="true"/> + <insertionPoint name="group.navigate" separator="true"/> <insertionPoint name="group.edit" separator="true"/> <insertionPoint name="group.logs" separator="true"/> <insertionPoint name="group.tags" separator="true"/> - <insertionPoint name="group.showIn" separator="true"/> </popupMenu> <options> <property @@ -255,6 +255,11 @@ name="%command.runimage.name"> </command> <command + name="%command.showInPropertiesView.menu.name" + description="%command.showInPropertiesView.menu.description" + id="org.eclipse.linuxtools.docker.ui.commands.showInPropertiesView"> + </command> + <command name="%command.showInWebBrowser.menu.name" description="%command.showInWebBrowser.menu.description" id="org.eclipse.linuxtools.docker.ui.commands.showInWebBrowser"> @@ -510,6 +515,10 @@ </enabledWhen> </handler> <handler + commandId="org.eclipse.linuxtools.docker.ui.commands.showInPropertiesView" + class="org.eclipse.ui.views.properties.NewPropertySheetHandler"> + </handler> + <handler commandId="org.eclipse.linuxtools.docker.ui.commands.showInWebBrowser" class="org.eclipse.linuxtools.internal.docker.ui.commands.ShowInWebBrowserCommandHandler"> </handler> @@ -563,6 +572,32 @@ style="push"> </command> </menuContribution> + <!-- explorer view context menu: Show In --> + <menuContribution + locationURI="popup:org.eclipse.linuxtools.docker.ui.dockerExplorerView#PopupMenu?after=group.navigate"> + <menu + id="org.eclipse.linuxtools.docker.ui.dockerExplorerView#PopupMenu.showIn" + label="%menu.showIn"> + </menu> + </menuContribution> + <!-- explorer view context menu: Show In>Properties (on Connection)--> + <menuContribution + locationURI="popup:org.eclipse.linuxtools.docker.ui.dockerExplorerView#PopupMenu.showIn"> + <command + commandId="org.eclipse.linuxtools.docker.ui.commands.showInPropertiesView" + label="%command.showInPropertiesView.menu.name" + id="org.eclipse.linuxtools.docker.ui.showConnectionInPropertiesView" + style="push"> + <visibleWhen> + <with variable="selection"> + <count value="1"/> + <iterate ifEmpty="false"> + <instanceof value="org.eclipse.linuxtools.docker.core.IDockerConnection"></instanceof> + </iterate> + </with> + </visibleWhen> + </command> + </menuContribution> <!-- explorer view context menu: start containers --> <menuContribution locationURI="popup:org.eclipse.linuxtools.docker.ui.dockerExplorerView#PopupMenu?after=group.run"> @@ -695,6 +730,24 @@ </visibleWhen> </command> </menuContribution> + <!-- explorer view context menu: Show In>Properties (on container)--> + <menuContribution + locationURI="popup:org.eclipse.linuxtools.docker.ui.dockerExplorerView#PopupMenu.showIn"> + <command + commandId="org.eclipse.linuxtools.docker.ui.commands.showInPropertiesView" + label="%command.showInPropertiesView.menu.name" + id="org.eclipse.linuxtools.docker.ui.showContainerInPropertiesView" + style="push"> + <visibleWhen> + <with variable="selection"> + <count value="1"/> + <iterate ifEmpty="false"> + <instanceof value="org.eclipse.linuxtools.docker.core.IDockerContainer"></instanceof> + </iterate> + </with> + </visibleWhen> + </command> + </menuContribution> <!-- explorer view context menu: commit container --> <menuContribution locationURI="popup:org.eclipse.linuxtools.docker.ui.dockerExplorerView#PopupMenu?after=org.eclipse.linuxtools.docker.ui.commands.removeContainers"> @@ -875,6 +928,24 @@ </visibleWhen> </command> </menuContribution> + <!-- explorer view context menu: Show In>Properties (on Image)--> + <menuContribution + locationURI="popup:org.eclipse.linuxtools.docker.ui.dockerExplorerView#PopupMenu.showIn"> + <command + commandId="org.eclipse.linuxtools.docker.ui.commands.showInPropertiesView" + label="%command.showInPropertiesView.menu.name" + id="org.eclipse.linuxtools.docker.ui.showImageInPropertiesView" + style="push"> + <visibleWhen> + <with variable="selection"> + <count value="1"/> + <iterate ifEmpty="false"> + <instanceof value="org.eclipse.linuxtools.docker.core.IDockerImage"></instanceof> + </iterate> + </with> + </visibleWhen> + </command> + </menuContribution> <!-- explorer view context menu: push image --> <menuContribution locationURI="popup:org.eclipse.linuxtools.docker.ui.dockerExplorerView#PopupMenu?after=org.eclipse.linuxtools.docker.ui.commands.removeImages"> @@ -949,14 +1020,7 @@ </visibleWhen> </command> </menuContribution> - <!-- explorer view context menu: Show In --> - <menuContribution - locationURI="popup:org.eclipse.linuxtools.docker.ui.dockerExplorerView#PopupMenu?after=group.showIn"> - <menu - id="org.eclipse.linuxtools.docker.ui.dockerExplorerView#PopupMenu.showIn" - label="%menu.showIn"> - </menu> - </menuContribution> + <!-- explorer view context menu: Show In>Web Browser (on container ports)--> <menuContribution locationURI="popup:org.eclipse.linuxtools.docker.ui.dockerExplorerView#PopupMenu.showIn"> diff --git a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/commands/CommandMessages.properties b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/commands/CommandMessages.properties index 64eb748baf..b4c272d431 100644 --- a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/commands/CommandMessages.properties +++ b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/commands/CommandMessages.properties @@ -1,3 +1,6 @@ +command.showIn.propertiesView=Opening in Properties View... +command.showIn.propertiesView.failure=Failed to open in Properties View + command.showIn.webBrowser=Opening in Web Browser... command.showIn.webBrowser.failure=Failed to open in Web Browser diff --git a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/commands/ShowInPropertiesViewCommandHandler.java b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/commands/ShowInPropertiesViewCommandHandler.java new file mode 100644 index 0000000000..053727c3ac --- /dev/null +++ b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/commands/ShowInPropertiesViewCommandHandler.java @@ -0,0 +1,68 @@ +/******************************************************************************* + * Copyright (c) 2016 Red Hat. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Red Hat - Initial Contribution + *******************************************************************************/ + +package org.eclipse.linuxtools.internal.docker.ui.commands; + +import java.util.List; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.linuxtools.docker.core.Activator; +import org.eclipse.linuxtools.docker.core.IDockerContainer; +import org.eclipse.swt.widgets.Display; +import org.eclipse.ui.IWorkbenchPart; +import org.eclipse.ui.PartInitException; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.handlers.HandlerUtil; +import org.eclipse.ui.views.properties.PropertySheet; +import org.eclipse.ui.views.properties.PropertyShowInContext; + +/** + * Command handler to open the selection in the Properties View. + */ +public class ShowInPropertiesViewCommandHandler extends AbstractHandler { + + @Override + public Object execute(final ExecutionEvent event) { + final IWorkbenchPart activePart = HandlerUtil.getActivePart(event); + final List<IDockerContainer> containers = CommandUtils + .getSelectedContainers(activePart); + if (containers == null || containers.isEmpty()) { + return null; + } + Display.getDefault().asyncExec(new Runnable() { + @Override + public void run() { + try { + final PropertySheet propertySheet = (PropertySheet) PlatformUI + .getWorkbench().getActiveWorkbenchWindow() + .getActivePage() + .showView("org.eclipse.ui.views.PropertySheet"); + final PropertyShowInContext showInContext = new PropertyShowInContext( + activePart, + HandlerUtil.getCurrentSelection(event)); + propertySheet.show(showInContext); + // final TabbedPropertySheetPage tabbedPropertySheetPage = + // activePart + // .getAdapter(TabbedPropertySheetPage.class); + // tabbedPropertySheetPage.setFocus(); + } catch (PartInitException e) { + Activator.logErrorMessage( + CommandMessages.getString( + "command.showIn.propertiesView.failure"), //$NON-NLS-1$ + e); + + } + } + }); + return null; + } +} diff --git a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/views/DockerExplorerContentProvider.java b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/views/DockerExplorerContentProvider.java index ce91b64b9a..9bdfffe2a1 100644 --- a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/views/DockerExplorerContentProvider.java +++ b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/views/DockerExplorerContentProvider.java @@ -95,16 +95,22 @@ public class DockerExplorerContentProvider implements ITreeContentProvider { final DockerContainer container = (DockerContainer) parentElement; if (container.isInfoLoaded()) { final IDockerContainerInfo info = container.info(); - final IDockerNetworkSettings networkSettings = info - .networkSettings(); - final IDockerHostConfig hostConfig = info.hostConfig(); + final IDockerNetworkSettings networkSettings = (info != null) + ? info.networkSettings() : null; + final IDockerHostConfig hostConfig = (info != null) + ? info.hostConfig() : null; return new Object[] { new DockerContainerPortMappingsCategory(container, - networkSettings.ports()), + (networkSettings != null) + ? networkSettings.ports() + : Collections + .<String, List<IDockerPortBinding>> emptyMap()), new DockerContainerVolumesCategory(container, - hostConfig.binds()), + (hostConfig != null) ? hostConfig.binds() + : Collections.<String> emptyList()), new DockerContainerLinksCategory(container, - hostConfig.links()) }; + (hostConfig != null) ? hostConfig.links() + : Collections.<String> emptyList()) }; } loadContainerInfo(container); return new Object[] { new LoadingStub(container) }; diff --git a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/views/DockerExplorerView.java b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/views/DockerExplorerView.java index a683fb8c68..9715383c94 100644 --- a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/views/DockerExplorerView.java +++ b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/views/DockerExplorerView.java @@ -64,6 +64,7 @@ public class DockerExplorerView extends CommonNavigator implements private static final String NO_CONNECTION_LABEL = "NoConnection.label"; //$NON-NLS-1$ + /** the id of the {@link DockerExplorerView}. */ public static final String VIEW_ID = "org.eclipse.linuxtools.docker.ui.dockerExplorerView"; private Control connectionsPane; @@ -97,7 +98,7 @@ public class DockerExplorerView extends CommonNavigator implements @Override public Object getAdapter(@SuppressWarnings("rawtypes") final Class adapter) { - if (adapter == IPropertySheetPage.class) { + if (IPropertySheetPage.class.isAssignableFrom(adapter)) { return new TabbedPropertySheetPage(this, true); } return super.getAdapter(adapter); |