From a9748cdea757c60d7e0111dc4a21c933e2a661ae Mon Sep 17 00:00:00 2001 From: marhali Date: Mon, 10 Jan 2022 22:18:49 +0100 Subject: [PATCH] improve keyboard shortcuts to edit or delete translations Resolves #71 --- CHANGELOG.md | 9 +- .../easyi18n/listener/DeleteKeyListener.java | 8 +- .../easyi18n/listener/ReturnKeyListener.java | 30 ++++++ .../de/marhali/easyi18n/tabs/TableView.java | 42 ++++---- .../de/marhali/easyi18n/tabs/TreeView.java | 100 +++++++++--------- 5 files changed, 110 insertions(+), 79 deletions(-) create mode 100644 src/main/java/de/marhali/easyi18n/listener/ReturnKeyListener.java diff --git a/CHANGELOG.md b/CHANGELOG.md index 2e2ef32..543bbb7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,16 +4,17 @@ ## [Unreleased] ### Added +- Full keyboard shortcut support inside tool-window - Support for dots within key nodes in YAML files -### Fixed -- First row inside table view is not editable -- Key focus within tree or table view after translation change - ### Changed - Update Qodana to latest version - Allow tool-window rendering in dumb mode +### Fixed +- First row inside table view is not editable +- Key focus within tree or table view after translation change + ## [1.7.1] ### Fixed - Vue.js template folding support diff --git a/src/main/java/de/marhali/easyi18n/listener/DeleteKeyListener.java b/src/main/java/de/marhali/easyi18n/listener/DeleteKeyListener.java index 2c45b1f..1fd4c7c 100644 --- a/src/main/java/de/marhali/easyi18n/listener/DeleteKeyListener.java +++ b/src/main/java/de/marhali/easyi18n/listener/DeleteKeyListener.java @@ -9,16 +9,16 @@ import java.awt.event.KeyListener; */ public class DeleteKeyListener implements KeyListener { - private final Runnable deleteRunnable; + private final Runnable onActivate; - public DeleteKeyListener(Runnable deleteRunnable) { - this.deleteRunnable = deleteRunnable; + public DeleteKeyListener(Runnable onActivate) { + this.onActivate = onActivate; } @Override public void keyTyped(KeyEvent e) { if(e.getKeyChar() == KeyEvent.VK_DELETE) { - deleteRunnable.run(); + this.onActivate.run(); } } diff --git a/src/main/java/de/marhali/easyi18n/listener/ReturnKeyListener.java b/src/main/java/de/marhali/easyi18n/listener/ReturnKeyListener.java new file mode 100644 index 0000000..59a27b2 --- /dev/null +++ b/src/main/java/de/marhali/easyi18n/listener/ReturnKeyListener.java @@ -0,0 +1,30 @@ +package de.marhali.easyi18n.listener; + +import java.awt.event.KeyEvent; +import java.awt.event.KeyListener; + +/** + * Return (\n) keystroke listener. + * @author marhali + */ +public class ReturnKeyListener implements KeyListener { + + private final Runnable onActivate; + + public ReturnKeyListener(Runnable onActivate) { + this.onActivate = onActivate; + } + + @Override + public void keyTyped(KeyEvent e) { + if(e.getKeyChar() == KeyEvent.VK_ENTER) { + this.onActivate.run(); + } + } + + @Override + public void keyPressed(KeyEvent e) {} + + @Override + public void keyReleased(KeyEvent e) {} +} \ No newline at end of file diff --git a/src/main/java/de/marhali/easyi18n/tabs/TableView.java b/src/main/java/de/marhali/easyi18n/tabs/TableView.java index 3ffd338..94b4f22 100644 --- a/src/main/java/de/marhali/easyi18n/tabs/TableView.java +++ b/src/main/java/de/marhali/easyi18n/tabs/TableView.java @@ -5,6 +5,7 @@ import com.intellij.ui.components.JBScrollPane; import com.intellij.ui.table.JBTable; import de.marhali.easyi18n.InstanceManager; +import de.marhali.easyi18n.listener.ReturnKeyListener; import de.marhali.easyi18n.model.*; import de.marhali.easyi18n.dialog.EditDialog; import de.marhali.easyi18n.listener.DeleteKeyListener; @@ -18,11 +19,11 @@ import org.jetbrains.annotations.Nullable; import javax.swing.*; import java.awt.*; -import java.awt.event.MouseEvent; import java.util.ResourceBundle; /** * Shows translation state as table. + * * @author marhali */ public class TableView implements BusListener { @@ -41,36 +42,35 @@ public class TableView implements BusListener { table = new JBTable(); table.getEmptyText().setText(ResourceBundle.getBundle("messages").getString("view.empty")); - table.addMouseListener(new PopupClickListener(this::handlePopup)); - table.addKeyListener(new DeleteKeyListener(handleDeleteKey())); + table.addMouseListener(new PopupClickListener(e -> showEditPopup(table.rowAtPoint(e.getPoint())))); + table.addKeyListener(new ReturnKeyListener(() -> showEditPopup(table.getSelectedRow()))); + table.addKeyListener(new DeleteKeyListener(this::deleteSelectedRows)); table.setDefaultRenderer(String.class, new TableRenderer()); containerPanel.add(new JBScrollPane(table)); } - private void handlePopup(MouseEvent e) { - int row = table.rowAtPoint(e.getPoint()); + private void showEditPopup(int row) { + if (row < 0) { + return; + } - if(row >= 0) { - String fullPath = String.valueOf(table.getValueAt(row, 0)); - Translation translation = InstanceManager.get(project).store().getData().getTranslation(fullPath); + String fullPath = String.valueOf(table.getValueAt(row, 0)); + Translation translation = InstanceManager.get(project).store().getData().getTranslation(fullPath); - if(translation != null) { - new EditDialog(project, new KeyedTranslation(fullPath, translation)).showAndHandle(); - } + if (translation != null) { + new EditDialog(project, new KeyedTranslation(fullPath, translation)).showAndHandle(); } } - private Runnable handleDeleteKey() { - return () -> { - for (int selectedRow : table.getSelectedRows()) { - String fullPath = String.valueOf(table.getValueAt(selectedRow, 0)); + private void deleteSelectedRows() { + for (int selectedRow : table.getSelectedRows()) { + String fullPath = String.valueOf(table.getValueAt(selectedRow, 0)); - InstanceManager.get(project).processUpdate( - new TranslationDelete(new KeyedTranslation(fullPath, null)) - ); - } - }; + InstanceManager.get(project).processUpdate( + new TranslationDelete(new KeyedTranslation(fullPath, null)) + ); + } } @Override @@ -97,7 +97,7 @@ public class TableView implements BusListener { @Override public void onSearchQuery(@Nullable String query) { - if(this.currentMapper != null) { + if (this.currentMapper != null) { this.currentMapper.onSearchQuery(query); this.table.updateUI(); } diff --git a/src/main/java/de/marhali/easyi18n/tabs/TreeView.java b/src/main/java/de/marhali/easyi18n/tabs/TreeView.java index b351ac8..d49f907 100644 --- a/src/main/java/de/marhali/easyi18n/tabs/TreeView.java +++ b/src/main/java/de/marhali/easyi18n/tabs/TreeView.java @@ -9,6 +9,7 @@ import com.intellij.ui.components.JBScrollPane; import com.intellij.ui.treeStructure.Tree; import de.marhali.easyi18n.InstanceManager; +import de.marhali.easyi18n.listener.ReturnKeyListener; import de.marhali.easyi18n.model.KeyedTranslation; import de.marhali.easyi18n.model.Translation; import de.marhali.easyi18n.model.TranslationData; @@ -30,11 +31,11 @@ import org.jetbrains.annotations.Nullable; import javax.swing.*; import javax.swing.tree.DefaultMutableTreeNode; import javax.swing.tree.TreePath; -import java.awt.event.MouseEvent; import java.util.ResourceBundle; /** * Show translation state as tree. + * * @author marhali */ public class TreeView implements BusListener { @@ -56,8 +57,9 @@ public class TreeView implements BusListener { tree.setCellRenderer(new TreeRenderer()); tree.setRootVisible(false); tree.getEmptyText().setText(ResourceBundle.getBundle("messages").getString("view.empty")); - tree.addMouseListener(new PopupClickListener(this::handlePopup)); - tree.addKeyListener(new DeleteKeyListener(handleDeleteKey())); + tree.addMouseListener(new PopupClickListener(e -> showEditPopup(tree.getPathForLocation(e.getX(), e.getY())))); + tree.addKeyListener(new ReturnKeyListener(() -> showEditPopup(tree.getSelectionPath()))); + tree.addKeyListener(new DeleteKeyListener(this::deleteSelectedNodes)); containerPanel.add(new JBScrollPane(tree)); placeActions(); @@ -66,8 +68,8 @@ public class TreeView implements BusListener { private void placeActions() { DefaultActionGroup group = new DefaultActionGroup("TranslationsGroup", false); - ExpandTreeViewAction expand = new ExpandTreeViewAction(expandAll()); - CollapseTreeViewAction collapse = new CollapseTreeViewAction(collapseAll()); + ExpandTreeViewAction expand = new ExpandTreeViewAction(this::expandAll); + CollapseTreeViewAction collapse = new CollapseTreeViewAction(this::collapseAll); group.add(collapse); group.add(expand); @@ -86,13 +88,13 @@ public class TreeView implements BusListener { @Override public void onFocusKey(@Nullable String key) { - if(key != null && currentMapper != null) { + if (key != null && currentMapper != null) { TreePath path = currentMapper.findTreePath(key); this.tree.getSelectionModel().setSelectionPath(path); this.tree.scrollPathToVisible(path); - if(this.tree.isCollapsed(path)) { + if (this.tree.isCollapsed(path)) { this.tree.expandPath(path); } } @@ -100,62 +102,60 @@ public class TreeView implements BusListener { @Override public void onSearchQuery(@Nullable String query) { - if(this.currentMapper != null) { + if (this.currentMapper != null) { this.currentMapper.onSearchQuery(query); - this.expandAll().run(); + this.expandAll(); this.tree.updateUI(); } } - private void handlePopup(MouseEvent e) { - TreePath path = tree.getPathForLocation(e.getX(), e.getY()); + private void showEditPopup(@Nullable TreePath path) { + if (path == null) { + return; + } - if(path != null) { - DefaultMutableTreeNode node = (DefaultMutableTreeNode) path.getLastPathComponent(); + DefaultMutableTreeNode node = (DefaultMutableTreeNode) path.getLastPathComponent(); - if(node.getUserObject() instanceof PresentationData) { - String fullPath = TreeUtil.getFullPath(path); - Translation translation = InstanceManager.get(project).store().getData().getTranslation(fullPath); + if (!(node.getUserObject() instanceof PresentationData)) { + return; + } - if(translation != null) { - new EditDialog(project, new KeyedTranslation(fullPath, translation)).showAndHandle(); - } - } + String fullPath = TreeUtil.getFullPath(path); + Translation translation = InstanceManager.get(project).store().getData().getTranslation(fullPath); + + if (translation == null) { + return; + } + + new EditDialog(project, new KeyedTranslation(fullPath, translation)).showAndHandle(); + } + + private void deleteSelectedNodes() { + TreePath[] paths = tree.getSelectionPaths(); + + if (paths == null) { + return; + } + + for (TreePath path : tree.getSelectionPaths()) { + String fullPath = TreeUtil.getFullPath(path); + + InstanceManager.get(project).processUpdate( + new TranslationDelete(new KeyedTranslation(fullPath, null)) + ); } } - private Runnable handleDeleteKey() { - return () -> { - TreePath[] paths = tree.getSelectionPaths(); - - if (paths == null) { - return; - } - - for (TreePath path : tree.getSelectionPaths()) { - String fullPath = TreeUtil.getFullPath(path); - - InstanceManager.get(project).processUpdate( - new TranslationDelete(new KeyedTranslation(fullPath, null)) - ); - } - }; + private void expandAll() { + for (int i = 0; i < tree.getRowCount(); i++) { + tree.expandRow(i); + } } - private Runnable expandAll() { - return () -> { - for(int i = 0; i < tree.getRowCount(); i++) { - tree.expandRow(i); - } - }; - } - - private Runnable collapseAll() { - return () -> { - for(int i = 0; i < tree.getRowCount(); i++) { - tree.collapseRow(i); - } - }; + private void collapseAll() { + for (int i = 0; i < tree.getRowCount(); i++) { + tree.collapseRow(i); + } } public JPanel getRootPanel() {