From ff25311a54abfded47c9f2e4b46fbbe841fb127b Mon Sep 17 00:00:00 2001 From: Aleksey Pivovarov Date: Tue, 29 Nov 2016 19:28:01 +0300 Subject: [PATCH] ui: support SelectAll action in TableSpeedSearch --- .../src/com/intellij/ui/TableSpeedSearch.java | 85 +++++++++++++++++++ 1 file changed, 85 insertions(+) diff --git a/platform/platform-impl/src/com/intellij/ui/TableSpeedSearch.java b/platform/platform-impl/src/com/intellij/ui/TableSpeedSearch.java index 124c8226eb8a..adf96e37e5bf 100644 --- a/platform/platform-impl/src/com/intellij/ui/TableSpeedSearch.java +++ b/platform/platform-impl/src/com/intellij/ui/TableSpeedSearch.java @@ -16,12 +16,21 @@ package com.intellij.ui; +import com.intellij.openapi.actionSystem.ActionManager; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.IdeActions; +import com.intellij.openapi.project.DumbAwareAction; import com.intellij.util.PairFunction; import com.intellij.util.containers.Convertor; +import gnu.trove.TIntArrayList; +import org.jetbrains.annotations.NotNull; import javax.swing.*; +import java.util.Arrays; import java.util.ListIterator; +import static javax.swing.ListSelectionModel.MULTIPLE_INTERVAL_SELECTION; + public class TableSpeedSearch extends SpeedSearchBase { private static final PairFunction TO_STRING = (o, cell) -> o == null || o instanceof Boolean ? "" : o.toString(); private final PairFunction myToStringConvertor; @@ -40,6 +49,8 @@ public class TableSpeedSearch extends SpeedSearchBase { myToStringConvertor = toStringConvertor; // edit on F2 & double click, do not interfere with quick search table.putClientProperty("JTable.autoStartsEdit", Boolean.FALSE); + + new MySelectAllAction(table, this).registerCustomShortcutSet(table, null); } @Override @@ -150,4 +161,78 @@ public class TableSpeedSearch extends SpeedSearchBase { throw new AssertionError("Not Implemented"); } } + + @NotNull + private TIntArrayList findAllFilteredRows(String s) { + TIntArrayList rows = new TIntArrayList(); + String _s = s.trim(); + + for (int row = 0; row < myComponent.getRowCount(); row++) { + for (int col = 0; col < myComponent.getColumnCount(); col++) { + int index = row * myComponent.getColumnCount() + col; + if (isMatchingElement(index, _s)) { + rows.add(row); + break; + } + } + } + return rows; + } + + private static class MySelectAllAction extends DumbAwareAction { + @NotNull private final JTable myTable; + @NotNull private final TableSpeedSearch mySearch; + + public MySelectAllAction(@NotNull JTable table, @NotNull TableSpeedSearch search) { + myTable = table; + mySearch = search; + copyShortcutFrom(ActionManager.getInstance().getAction(IdeActions.ACTION_SELECT_ALL)); + setEnabledInModalContext(true); + } + + @Override + public void update(AnActionEvent e) { + e.getPresentation().setEnabled(mySearch.isPopupActive() && + myTable.getRowSelectionAllowed() && + myTable.getSelectionModel().getSelectionMode() == MULTIPLE_INTERVAL_SELECTION); + } + + @Override + public void actionPerformed(AnActionEvent e) { + ListSelectionModel sm = myTable.getSelectionModel(); + + String query = mySearch.getEnteredPrefix(); + if (query == null) return; + + TIntArrayList filtered = mySearch.findAllFilteredRows(query); + if (filtered.isEmpty()) return; + + boolean alreadySelected = Arrays.equals(filtered.toNativeArray(), myTable.getSelectedRows()); + + if (alreadySelected) { + int anchor = sm.getAnchorSelectionIndex(); + + sm.setSelectionInterval(anchor, anchor); + sm.setAnchorSelectionIndex(anchor); + + mySearch.findAndSelectElement(query); + } + else { + int anchor = -1; + Object currentElement = mySearch.findElement(query); + if (currentElement instanceof Integer) { + int index = (Integer)currentElement; + anchor = index / myTable.getColumnCount(); + } + if (anchor == -1) anchor = filtered.get(0); + + sm.clearSelection(); + for (int i = 0; i < filtered.size(); i++) { + int value = filtered.get(i); + sm.addSelectionInterval(value, value); + } + sm.setAnchorSelectionIndex(anchor); + } + } + } }