From 75928f058a6deff90594ad0975a20bf199f01f43 Mon Sep 17 00:00:00 2001 From: Fred Bricon Date: Sat, 1 Jul 2023 22:45:18 +0200 Subject: [PATCH] feat: improve extension (de)selection in Quarkus wizard Signed-off-by: Fred Bricon --- .../quarkus/module/QuarkusExtensionsStep.java | 83 ++++++++++++++++++- 1 file changed, 82 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/redhat/devtools/intellij/quarkus/module/QuarkusExtensionsStep.java b/src/main/java/com/redhat/devtools/intellij/quarkus/module/QuarkusExtensionsStep.java index f0ab6da47..7e8c82348 100644 --- a/src/main/java/com/redhat/devtools/intellij/quarkus/module/QuarkusExtensionsStep.java +++ b/src/main/java/com/redhat/devtools/intellij/quarkus/module/QuarkusExtensionsStep.java @@ -39,6 +39,7 @@ import javax.swing.tree.TreeNode; import javax.swing.tree.TreePath; import java.awt.*; +import java.awt.event.*; import java.util.ArrayList; import java.util.Enumeration; import java.util.HashSet; @@ -204,6 +205,7 @@ public void hyperlinkUpdate(HyperlinkEvent e) { } } }); + extensionsTree.addCheckboxTreeListener(new CheckboxTreeListener() { @Override public void nodeStateChanged(@NotNull CheckedTreeNode node) { @@ -220,6 +222,57 @@ public void nodeStateChanged(@NotNull CheckedTreeNode node) { selectedExtensions.setModel(new SelectedExtensionsModel(categories)); } }); + + //(Un)Check extension on double-click + extensionsTree.addMouseListener(new MouseAdapter() { + public void mouseClicked(MouseEvent e) { + if (e.getClickCount() == 2) { + TreePath path = extensionsTree.getPathForLocation(e.getX(), e.getY()); + if (path != null && path.getLastPathComponent() instanceof CheckedTreeNode) { + var treeNode = (CheckedTreeNode) path.getLastPathComponent(); + extensionsTree.setNodeState(treeNode, !treeNode.isChecked()); + } + } + } + }); + + //Unselect extensions on double-click + selectedExtensions.addMouseListener(new MouseAdapter() { + @Override + public void mouseClicked(MouseEvent e) { + if (e.getClickCount() == 2) { + int selectedIndex = selectedExtensions.getSelectedIndex(); + if (selectedIndex > -1) { + QuarkusExtension extension = selectedExtensions.getModel().getElementAt(selectedIndex); + if (unselectExtension(extensionsTree, extension)) { + // The extensions was not visible in the tree so didn't trigger a selectedExtension model refresh + // so we force it manually + selectedExtensions.setModel(new SelectedExtensionsModel(categories)); + }; + } + } + } + }); + + //Unselect extensions when pressing the DELETE or BACKSPACE key + selectedExtensions.addKeyListener(new KeyAdapter() { + @Override + public void keyPressed(KeyEvent e) { + if (e.getKeyCode() == KeyEvent.VK_DELETE || e.getKeyCode() == KeyEvent.VK_BACK_SPACE) { + boolean requiresModelRefresh = false; + for (QuarkusExtension extension : selectedExtensions.getSelectedValuesList()) { + requiresModelRefresh = unselectExtension(extensionsTree, extension) || requiresModelRefresh; + } + selectedExtensions.clearSelection(); + if (requiresModelRefresh) { + // Some extensions were not visible in the tree so didn't trigger a selectedExtension model refresh + // so we force it manually + selectedExtensions.setModel(new SelectedExtensionsModel(categories)); + } + } + } + }); + extensionsTree.getSelectionModel().addTreeSelectionListener(new TreeSelectionListener() { @Override public void valueChanged(TreeSelectionEvent e) { @@ -228,7 +281,7 @@ public void valueChanged(TreeSelectionEvent e) { if (comp instanceof QuarkusExtension) { StringBuilder builder = new StringBuilder("" + ((QuarkusExtension) comp).getDescription() + "."); if (StringUtils.isNotBlank(((QuarkusExtension) comp).getGuide())) { - builder.append(" Click to open guide"); + builder.append(" Click to open guide"); } builder.append(""); extensionDetailTextPane.setText(builder.toString()); @@ -274,6 +327,34 @@ private CheckedTreeNode getModel(List categories, SearchTextFie return root; } + /** + * Unselects a selected extension from the extension tree. Returns true if the extension was not found in the tree, false otherwise. + */ + private boolean unselectExtension(@NotNull CheckboxTree extensionsTree, @NotNull QuarkusExtension extension) { + var treeNodes = findTreeNodesForExtension(extensionsTree, extension); + for (var treeNode : treeNodes) { + extensionsTree.setNodeState(treeNode, false); + } + extension.setSelected(false); + return treeNodes.isEmpty(); + } + + /** + * Find CheckedTreeNode for a given extension, as it can belong to several categories + */ + private @NotNull Set findTreeNodesForExtension(@NotNull CheckboxTree extensionsTree, @NotNull QuarkusExtension extension) { + DefaultMutableTreeNode rootNode = (DefaultMutableTreeNode) extensionsTree.getModel().getRoot(); + Enumeration enumeration = rootNode.depthFirstEnumeration(); + Set nodes = new HashSet<>(); + while (enumeration.hasMoreElements()) { + TreeNode node = enumeration.nextElement(); + if (node instanceof CheckedTreeNode && ((CheckedTreeNode)node).getUserObject() == extension) { + nodes.add( (CheckedTreeNode)node); + } + } + return nodes; + } + /** * Use reflection to get IntelliJ specific HTML editor kit as it has moved in 2020.1 *