mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
SpeedSearch support for sortable tables + different model to view conversion fixes
This commit is contained in:
@@ -111,6 +111,11 @@ public class ProcessedModulesTable extends JPanel {
|
||||
return myTable.getSelectedRow();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int convertIndexToModel(int viewIndex) {
|
||||
return myTable.convertRowIndexToModel(viewIndex);
|
||||
}
|
||||
|
||||
public Object[] getAllElements() {
|
||||
final int count = myTableModel.getRowCount();
|
||||
Object[] elements = new Object[count];
|
||||
@@ -128,7 +133,8 @@ public class ProcessedModulesTable extends JPanel {
|
||||
final int count = myTableModel.getRowCount();
|
||||
for (int row = 0; row < count; row++) {
|
||||
if (element.equals(myTableModel.getModuleAt(row))) {
|
||||
myTable.getSelectionModel().setSelectionInterval(row, row);
|
||||
final int viewRow = myTable.convertRowIndexToView(row);
|
||||
myTable.getSelectionModel().setSelectionInterval(viewRow, viewRow);
|
||||
TableUtil.scrollSelectionToVisible(myTable);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -111,6 +111,11 @@ public class ClasspathPanel extends JPanel {
|
||||
return myEntryTable.getSelectedRow();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int convertIndexToModel(int viewIndex) {
|
||||
return myEntryTable.convertRowIndexToModel(viewIndex);
|
||||
}
|
||||
|
||||
public Object[] getAllElements() {
|
||||
final int count = myModel.getRowCount();
|
||||
Object[] elements = new Object[count];
|
||||
@@ -128,7 +133,8 @@ public class ClasspathPanel extends JPanel {
|
||||
final int count = myModel.getRowCount();
|
||||
for (int row = 0; row < count; row++) {
|
||||
if (element.equals(myModel.getItemAt(row))) {
|
||||
myEntryTable.getSelectionModel().setSelectionInterval(row, row);
|
||||
final int viewRow = myEntryTable.convertRowIndexToView(row);
|
||||
myEntryTable.getSelectionModel().setSelectionInterval(viewRow, viewRow);
|
||||
TableUtil.scrollSelectionToVisible(myEntryTable);
|
||||
break;
|
||||
}
|
||||
@@ -146,14 +152,14 @@ public class ClasspathPanel extends JPanel {
|
||||
final int[] selectedRows = myEntryTable.getSelectedRows();
|
||||
boolean currentlyMarked = true;
|
||||
for (final int selectedRow : selectedRows) {
|
||||
final TableItem item = myModel.getItemAt(selectedRow);
|
||||
final TableItem item = myModel.getItemAt(myEntryTable.convertRowIndexToModel(selectedRow));
|
||||
if (selectedRow < 0 || !item.isExportable()) {
|
||||
return;
|
||||
}
|
||||
currentlyMarked &= item.isExported();
|
||||
}
|
||||
for (final int selectedRow : selectedRows) {
|
||||
myModel.getItemAt(selectedRow).setExported(!currentlyMarked);
|
||||
myModel.getItemAt(myEntryTable.convertRowIndexToModel(selectedRow)).setExported(!currentlyMarked);
|
||||
}
|
||||
myModel.fireTableDataChanged();
|
||||
TableUtil.selectRows(myEntryTable, selectedRows);
|
||||
|
||||
@@ -377,6 +377,11 @@ public class ShowUsagesAction extends AnAction {
|
||||
return table.getSelectedRow();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int convertIndexToModel(int viewIndex) {
|
||||
return table.convertRowIndexToModel(viewIndex);
|
||||
}
|
||||
|
||||
protected Object[] getAllElements() {
|
||||
return ArrayUtil.toObjectArray(data);
|
||||
}
|
||||
@@ -393,7 +398,8 @@ public class ShowUsagesAction extends AnAction {
|
||||
protected void selectElement(Object element, String selectedText) {
|
||||
int i = data.indexOf(element);
|
||||
if (i == -1) return;
|
||||
table.getSelectionModel().setSelectionInterval(i, i);
|
||||
final int viewRow = table.convertRowIndexToView(i);
|
||||
table.getSelectionModel().setSelectionInterval(viewRow, viewRow);
|
||||
}
|
||||
};
|
||||
speedSearch.setComparator(new SpeedSearchBase.SpeedSearchComparator(false));
|
||||
|
||||
@@ -24,7 +24,6 @@ import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.event.TableModelEvent;
|
||||
import javax.swing.event.TableModelListener;
|
||||
import javax.swing.table.*;
|
||||
import java.awt.*;
|
||||
import java.util.ArrayList;
|
||||
@@ -45,14 +44,6 @@ public class TableView<Item> extends BaseTableView implements ItemsProvider, Sel
|
||||
public void setModel(final TableModel dataModel) {
|
||||
assert dataModel instanceof SortableColumnModel : "SortableColumnModel required";
|
||||
super.setModel(dataModel);
|
||||
dataModel.addTableModelListener(new TableModelListener() {
|
||||
public void tableChanged(final TableModelEvent e) {
|
||||
JTableHeader header = getTableHeader();
|
||||
if (header != null) {
|
||||
header.repaint();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void setModel(final ListTableModel<Item> model) {
|
||||
@@ -66,7 +57,7 @@ public class TableView<Item> extends BaseTableView implements ItemsProvider, Sel
|
||||
|
||||
public TableCellRenderer getCellRenderer(int row, int column) {
|
||||
final ColumnInfo<Item, ?> columnInfo = getListTableModel().getColumnInfos()[convertColumnIndexToModel(column)];
|
||||
TableCellRenderer renderer = columnInfo.getRenderer(getListTableModel().getItems().get(row));
|
||||
TableCellRenderer renderer = columnInfo.getRenderer(getListTableModel().getItems().get(convertRowIndexToModel(row)));
|
||||
if (renderer == null) {
|
||||
return super.getCellRenderer(row, column);
|
||||
}
|
||||
@@ -128,9 +119,9 @@ public class TableView<Item> extends BaseTableView implements ItemsProvider, Sel
|
||||
final List<Item> items = getItems();
|
||||
if (! items.isEmpty()) {
|
||||
for (int selectedRow : selectedRows) {
|
||||
final int correctedIndex = convertRowIndexToModel(selectedRow);
|
||||
if (correctedIndex >= 0 && correctedIndex < items.size()) {
|
||||
result.add(items.get(correctedIndex));
|
||||
final int modelIndex = convertRowIndexToModel(selectedRow);
|
||||
if (modelIndex >= 0 && modelIndex < items.size()) {
|
||||
result.add(items.get(modelIndex));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -141,7 +132,7 @@ public class TableView<Item> extends BaseTableView implements ItemsProvider, Sel
|
||||
public Item getSelectedObject() {
|
||||
final int row = getSelectedRow();
|
||||
final List<Item> list = getItems();
|
||||
return row >= 0 && row < list.size() ? list.get(row) : null;
|
||||
return row >= 0 && row < list.size() ? list.get(convertRowIndexToModel(row)) : null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@@ -151,7 +142,7 @@ public class TableView<Item> extends BaseTableView implements ItemsProvider, Sel
|
||||
final List<Item> items = getItems();
|
||||
final List<Item> result = new ArrayList<Item>();
|
||||
for (int selectedRow : selectedRows) {
|
||||
result.add(items.get(selectedRow));
|
||||
result.add(items.get(convertRowIndexToModel(selectedRow)));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@@ -160,14 +151,14 @@ public class TableView<Item> extends BaseTableView implements ItemsProvider, Sel
|
||||
List items = getItems();
|
||||
if (!items.contains(item)) return;
|
||||
int index = items.indexOf(item);
|
||||
getSelectionModel().addSelectionInterval(index, index);
|
||||
getSelectionModel().addSelectionInterval(convertRowIndexToView(index), convertRowIndexToView(index));
|
||||
// fix cell selection case
|
||||
getColumnModel().getSelectionModel().addSelectionInterval(0, getColumnCount()-1);
|
||||
}
|
||||
|
||||
public TableCellEditor getCellEditor(int row, int column) {
|
||||
final ColumnInfo<Item, ?> columnInfo = getListTableModel().getColumnInfos()[convertColumnIndexToModel(column)];
|
||||
final TableCellEditor editor = columnInfo.getEditor(getListTableModel().getItems().get(row));
|
||||
final TableCellEditor editor = columnInfo.getEditor(getListTableModel().getItems().get(convertRowIndexToModel(row)));
|
||||
return editor == null ? super.getCellEditor(row, column) : editor;
|
||||
}
|
||||
|
||||
|
||||
@@ -557,6 +557,11 @@ public class PluginManagerMain implements Disposable {
|
||||
super(cmp);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int convertIndexToModel(int viewIndex) {
|
||||
return getComponent().convertRowIndexToModel(viewIndex);
|
||||
}
|
||||
|
||||
public int getSelectedIndex() {
|
||||
return myComponent.getSelectedRow();
|
||||
}
|
||||
|
||||
@@ -100,6 +100,11 @@ public class ElementsChooser<T> extends JPanel {
|
||||
return myTable.getSelectedRow();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int convertIndexToModel(int viewIndex) {
|
||||
return myTable.convertRowIndexToModel(viewIndex);
|
||||
}
|
||||
|
||||
public Object[] getAllElements() {
|
||||
final int count = myTableModel.getRowCount();
|
||||
Object[] elements = new Object[count];
|
||||
@@ -117,7 +122,8 @@ public class ElementsChooser<T> extends JPanel {
|
||||
final int count = myTableModel.getRowCount();
|
||||
for (int row = 0; row < count; row++) {
|
||||
if (element.equals(myTableModel.getElementAt(row))) {
|
||||
myTable.getSelectionModel().setSelectionInterval(row, row);
|
||||
final int viewRow = myTable.convertRowIndexToView(row);
|
||||
myTable.getSelectionModel().setSelectionInterval(viewRow, viewRow);
|
||||
TableUtil.scrollSelectionToVisible(myTable);
|
||||
break;
|
||||
}
|
||||
@@ -302,7 +308,7 @@ public class ElementsChooser<T> extends JPanel {
|
||||
final int[] rows = new int[elements.size()];
|
||||
int index = 0;
|
||||
for (final T element : elements) {
|
||||
rows[index++] = myTableModel.getElementRow(element);
|
||||
rows[index++] = myTable.convertRowIndexToView(myTableModel.getElementRow(element));
|
||||
}
|
||||
return rows;
|
||||
}
|
||||
|
||||
@@ -29,6 +29,7 @@ import com.intellij.openapi.wm.ex.ToolWindowManagerListener;
|
||||
import com.intellij.util.StringBuilderSpinAllocator;
|
||||
import com.intellij.util.ui.UIUtil;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
@@ -42,8 +43,8 @@ import java.awt.event.KeyAdapter;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.beans.PropertyChangeSupport;
|
||||
import java.util.Arrays;
|
||||
import java.util.ListIterator;
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.regex.PatternSyntaxException;
|
||||
@@ -87,17 +88,31 @@ public abstract class SpeedSearchBase<Comp extends JComponent> {
|
||||
return speedSearch != null && speedSearch.mySearchPopup != null && speedSearch.mySearchPopup.isVisible();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns visual (view) selection index.
|
||||
*/
|
||||
protected abstract int getSelectedIndex();
|
||||
|
||||
protected abstract Object[] getAllElements();
|
||||
|
||||
protected abstract String getElementText(Object element);
|
||||
|
||||
/**
|
||||
* Should convert given view index to model index
|
||||
*/
|
||||
protected int convertIndexToModel(final int viewIndex) {
|
||||
return viewIndex;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param element Element to select. Don't forget to convert model index to view index if needed (i.e. table.convertRowIndexToView(modelIndex), etc).
|
||||
* @param selectedText search text
|
||||
*/
|
||||
protected abstract void selectElement(Object element, String selectedText);
|
||||
|
||||
protected ListIterator<Object> getElementIterator(int startingIndex) {
|
||||
final Object[] allElements = getAllElements();
|
||||
return Arrays.asList(allElements).listIterator(startingIndex < 0? allElements.length : startingIndex);
|
||||
return new ViewIterator(this, startingIndex < 0 ? allElements.length : startingIndex);
|
||||
}
|
||||
|
||||
public void addChangeListener(PropertyChangeListener listener) {
|
||||
@@ -536,4 +551,70 @@ public abstract class SpeedSearchBase<Comp extends JComponent> {
|
||||
manageSearchPopup(null);
|
||||
}
|
||||
}
|
||||
|
||||
protected class ViewIterator implements ListIterator {
|
||||
private SpeedSearchBase mySpeedSearch;
|
||||
private int myCurrentIndex;
|
||||
private Object[] myElements;
|
||||
|
||||
public ViewIterator(@NotNull final SpeedSearchBase speedSearch, final int startIndex) {
|
||||
mySpeedSearch = speedSearch;
|
||||
myCurrentIndex = startIndex;
|
||||
myElements = speedSearch.getAllElements();
|
||||
|
||||
if (startIndex < 0 || startIndex > myElements.length) {
|
||||
throw new IndexOutOfBoundsException("Index: " + startIndex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasPrevious() {
|
||||
return myCurrentIndex != 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object previous() {
|
||||
final int i = myCurrentIndex - 1;
|
||||
if (i < 0) throw new NoSuchElementException();
|
||||
final Object previous = myElements[mySpeedSearch.convertIndexToModel(i)];
|
||||
myCurrentIndex = i;
|
||||
return previous;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int nextIndex() {
|
||||
return myCurrentIndex;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int previousIndex() {
|
||||
return myCurrentIndex - 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
return myCurrentIndex != myElements.length;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object next() {
|
||||
if (myCurrentIndex + 1 > myElements.length) throw new NoSuchElementException();
|
||||
return myElements[mySpeedSearch.convertIndexToModel(myCurrentIndex++)];
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove() {
|
||||
throw new UnsupportedOperationException("Not implemented in: " + getClass().getCanonicalName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void set(Object o) {
|
||||
throw new UnsupportedOperationException("Not implemented in: " + getClass().getCanonicalName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void add(Object o) {
|
||||
throw new UnsupportedOperationException("Not implemented in: " + getClass().getCanonicalName());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -62,6 +62,7 @@ public class TableSpeedSearch extends SpeedSearchBase<JTable> {
|
||||
protected int getSelectedIndex() {
|
||||
final int row = myComponent.getSelectedRow();
|
||||
final int col = myComponent.getSelectedColumn();
|
||||
// TODO: WTF?! getComponent().getSelectedRow() should be enough for everyone.
|
||||
return row > -1 && col > -1? row * myComponent.getModel().getColumnCount() + col : -1;
|
||||
}
|
||||
|
||||
|
||||
@@ -33,6 +33,11 @@ public abstract class TableViewSpeedSearch extends SpeedSearchBase<TableView> {
|
||||
return getComponent().getSelectedRow();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int convertIndexToModel(int viewIndex) {
|
||||
return myComponent.convertRowIndexToModel(viewIndex);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Object[] getAllElements() {
|
||||
return getComponent().getItems().toArray();
|
||||
@@ -47,7 +52,8 @@ public abstract class TableViewSpeedSearch extends SpeedSearchBase<TableView> {
|
||||
for (int i = 0, itemsSize = items.size(); i < itemsSize; i++) {
|
||||
final Object o = items.get(i);
|
||||
if (o == element) {
|
||||
getComponent().getSelectionModel().setSelectionInterval(i, i);
|
||||
final int viewIndex = myComponent.convertRowIndexToView(i);
|
||||
getComponent().getSelectionModel().setSelectionInterval(viewIndex, viewIndex);
|
||||
TableUtil.scrollSelectionToVisible(getComponent());
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -47,7 +47,7 @@ public class TreeTableSpeedSearch extends SpeedSearchBase<TreeTable> {
|
||||
|
||||
protected void selectElement(Object element, String selectedText) {
|
||||
final TreePath treePath = (TreePath)element;
|
||||
TableUtil.selectRows(myComponent, new int[] {myComponent.getTree().getRowForPath(treePath)});
|
||||
TableUtil.selectRows(myComponent, new int[] {myComponent.convertRowIndexToView(myComponent.getTree().getRowForPath(treePath))});
|
||||
TableUtil.scrollSelectionToVisible(myComponent);
|
||||
}
|
||||
|
||||
|
||||
@@ -39,11 +39,11 @@ public class TableUtil {
|
||||
return removeSelectedItems(table, null);
|
||||
}
|
||||
|
||||
public static void selectRows(JTable table, int[] rows) {
|
||||
public static void selectRows(final JTable table, final int[] viewRows) {
|
||||
ListSelectionModel selectionModel = table.getSelectionModel();
|
||||
selectionModel.clearSelection();
|
||||
int count = table.getRowCount();
|
||||
for (int row : rows) {
|
||||
for (int row : viewRows) {
|
||||
if (row >= 0 && row < count) {
|
||||
selectionModel.addSelectionInterval(row, row);
|
||||
}
|
||||
|
||||
+6
-1
@@ -238,6 +238,11 @@ public class CompareWithSelectedRevisionAction extends AbstractVcsAction {
|
||||
return table.getSelectedRow();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int convertIndexToModel(int viewIndex) {
|
||||
return table.convertRowIndexToModel(viewIndex);
|
||||
}
|
||||
|
||||
protected Object[] getAllElements() {
|
||||
return revisions.toArray();
|
||||
}
|
||||
@@ -249,7 +254,7 @@ public class CompareWithSelectedRevisionAction extends AbstractVcsAction {
|
||||
|
||||
protected void selectElement(Object element, String selectedText) {
|
||||
VcsFileRevision revision = (VcsFileRevision) element;
|
||||
TableUtil.selectRows(myComponent, new int[] {revisions.indexOf(revision)});
|
||||
TableUtil.selectRows(myComponent, new int[] {myComponent.convertRowIndexToView(revisions.indexOf(revision))});
|
||||
TableUtil.scrollSelectionToVisible(myComponent);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -87,7 +87,7 @@ class StatisticsPanel extends JPanel implements DataProvider{
|
||||
myTimeLabel.clear();
|
||||
myTimeLabel.append("Total time: " + Formatters.statisticsFor(proxy).getTime(), SimpleTextAttributes.REGULAR_BOLD_ATTRIBUTES);
|
||||
final int idx = myChildInfo.getIndexOf(myCurrentTest);
|
||||
TableUtil.selectRows(myTable, new int[]{idx});
|
||||
TableUtil.selectRows(myTable, new int[]{myTable.convertRowIndexToView(idx)});
|
||||
TableUtil.scrollSelectionToVisible(myTable);
|
||||
}
|
||||
|
||||
|
||||
+6
-1
@@ -260,6 +260,11 @@ public final class KeyChooserDialog extends DialogWrapper{
|
||||
super(component);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int convertIndexToModel(int viewIndex) {
|
||||
return getComponent().convertRowIndexToModel(viewIndex);
|
||||
}
|
||||
|
||||
public int getSelectedIndex() {
|
||||
return myComponent.getSelectedRow();
|
||||
}
|
||||
@@ -283,7 +288,7 @@ public final class KeyChooserDialog extends DialogWrapper{
|
||||
|
||||
public void selectElement(final Object element, final String selectedText) {
|
||||
final int index = myElements.get(element);
|
||||
selectElementAt(index);
|
||||
selectElementAt(getComponent().convertRowIndexToView(index));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user