blob: 711df9f6be275753452e396014d6c6c887482975 [file] [log] [blame]
/*
* Copyright 2010-2013 Bas Leijdekkers
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.siyeh.ig.ui;
import com.intellij.codeInspection.ui.ListTable;
import com.intellij.codeInspection.ui.ListWrappingTableModel;
import com.intellij.ide.DataManager;
import com.intellij.ide.util.ClassFilter;
import com.intellij.ide.util.TreeClassChooser;
import com.intellij.ide.util.TreeClassChooserFactory;
import com.intellij.openapi.actionSystem.CommonDataKeys;
import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.openapi.actionSystem.PlatformDataKeys;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiClass;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.util.InheritanceUtil;
import com.intellij.ui.*;
import com.intellij.ui.components.JBList;
import org.jetbrains.annotations.NonNls;
import javax.swing.*;
import javax.swing.table.TableCellEditor;
import java.awt.*;
import java.util.Collection;
public class UiUtils {
private UiUtils() {
}
public static void setComponentSize(Component component, int rows, int columns) {
final FontMetrics fontMetrics = component.getFontMetrics(component.getFont());
final int width = fontMetrics.charWidth('m') * columns;
component.setPreferredSize(new Dimension(width, fontMetrics.getHeight() * rows));
}
public static JPanel createAddRemovePanel(final ListTable table) {
return ToolbarDecorator.createDecorator(table)
.setAddAction(new AnActionButtonRunnable() {
@Override
public void run(AnActionButton button) {
final ListWrappingTableModel tableModel = table.getModel();
tableModel.addRow();
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
final int lastRowIndex = tableModel.getRowCount() - 1;
editTableCell(table, lastRowIndex, 0);
}
});
}
}).setRemoveAction(new RemoveAction(table))
.disableUpDownActions().createPanel();
}
public static JPanel createAddRemoveTreeClassChooserPanel(final ListTable table, final String chooserTitle,
@NonNls String... ancestorClasses) {
final ClassFilter filter;
if (ancestorClasses.length == 0) {
filter = ClassFilter.ALL;
}
else {
filter = new SubclassFilter(ancestorClasses);
}
return ToolbarDecorator.createDecorator(table)
.setAddAction(new AnActionButtonRunnable() {
@Override
public void run(AnActionButton button) {
final DataContext dataContext = DataManager.getInstance().getDataContext(table);
final Project project = CommonDataKeys.PROJECT.getData(dataContext);
final int rowIndex;
final ListWrappingTableModel tableModel = table.getModel();
if (project == null) {
tableModel.addRow();
rowIndex = tableModel.getRowCount() - 1;
}
else {
final TreeClassChooserFactory chooserFactory = TreeClassChooserFactory.getInstance(project);
final TreeClassChooser classChooser =
chooserFactory.createWithInnerClassesScopeChooser(chooserTitle, GlobalSearchScope.allScope(project), filter, null);
classChooser.showDialog();
final PsiClass selectedClass = classChooser.getSelected();
if (selectedClass == null) {
return;
}
final String qualifiedName = selectedClass.getQualifiedName();
final int index = tableModel.indexOf(qualifiedName, 0);
if (index < 0) {
tableModel.addRow(qualifiedName);
rowIndex = tableModel.getRowCount() - 1;
}
else {
rowIndex = index;
}
}
editTableCell(table, rowIndex, table.getColumnCount() > 1 && project != null ? 1 : 0);
}
}).setRemoveAction(new RemoveAction(table))
.disableUpDownActions().createPanel();
}
private static void editTableCell(final ListTable table, final int row, final int column) {
final ListSelectionModel selectionModel = table.getSelectionModel();
selectionModel.setSelectionInterval(row, row);
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
final ListWrappingTableModel tableModel = table.getModel();
table.requestFocus();
final Rectangle rectangle = table.getCellRect(row, column, true);
table.scrollRectToVisible(rectangle);
table.editCellAt(row, column);
final TableCellEditor editor = table.getCellEditor();
final Component component = editor.getTableCellEditorComponent(table, tableModel.getValueAt(row, column), true, row, column);
component.requestFocus();
}
});
}
public static JPanel createTreeClassChooserList(final Collection<String> collection,
String borderTitle,
final String chooserTitle,
String... ancestorClasses) {
final ClassFilter filter;
if (ancestorClasses.length == 0) {
filter = ClassFilter.ALL;
}
else {
filter = new SubclassFilter(ancestorClasses);
}
final JPanel optionsPanel = new JPanel(new BorderLayout());
final JBList list = new JBList(collection);
final JPanel panel = ToolbarDecorator.createDecorator(list)
.disableUpDownActions()
.setAddAction(new AnActionButtonRunnable() {
@Override
public void run(AnActionButton anActionButton) {
final DataContext dataContext = DataManager.getInstance().getDataContext(list);
final Project project = CommonDataKeys.PROJECT.getData(dataContext);
if (project == null) {
return;
}
final TreeClassChooser chooser = TreeClassChooserFactory.getInstance(project)
.createNoInnerClassesScopeChooser(chooserTitle, GlobalSearchScope.allScope(project), filter, null);
chooser.showDialog();
final PsiClass selected = chooser.getSelected();
if (selected == null) {
return;
}
final String qualifiedName = selected.getQualifiedName();
final DefaultListModel model = (DefaultListModel)list.getModel();
final int index = model.indexOf(qualifiedName);
if (index < 0) {
model.addElement(qualifiedName);
collection.add(qualifiedName);
}
else {
list.setSelectedIndex(index);
}
}
})
.setRemoveAction(new AnActionButtonRunnable() {
@Override
public void run(AnActionButton anActionButton) {
collection.remove(list.getSelectedValue());
ListUtil.removeSelectedItems(list);
}
}).createPanel();
optionsPanel.setBorder(IdeBorderFactory.createTitledBorder(borderTitle,
false, new Insets(10, 0, 0, 0)));
optionsPanel.add(panel);
return optionsPanel;
}
private static class RemoveAction implements AnActionButtonRunnable {
private final ListTable table;
public RemoveAction(ListTable table) {
this.table = table;
}
@Override
public void run(AnActionButton button) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
final TableCellEditor editor = table.getCellEditor();
if (editor != null) {
editor.stopCellEditing();
}
final ListSelectionModel selectionModel = table.getSelectionModel();
final int minIndex = selectionModel.getMinSelectionIndex();
final int maxIndex = selectionModel.getMaxSelectionIndex();
if (minIndex == -1 || maxIndex == -1) {
return;
}
final ListWrappingTableModel tableModel = table.getModel();
for (int i = minIndex; i <= maxIndex; i++) {
if (selectionModel.isSelectedIndex(i)) {
tableModel.removeRow(i);
}
}
final int count = tableModel.getRowCount();
if (count <= minIndex) {
selectionModel.setSelectionInterval(count - 1, count - 1);
}
else if (minIndex <= 0) {
if (count > 0) {
selectionModel.setSelectionInterval(0, 0);
}
}
else {
selectionModel.setSelectionInterval(minIndex - 1, minIndex - 1);
}
}
});
}
}
private static class SubclassFilter implements ClassFilter {
private final String[] ancestorClasses;
private SubclassFilter(String[] ancestorClasses) {
this.ancestorClasses = ancestorClasses;
}
@Override
public boolean isAccepted(PsiClass aClass) {
for (String ancestorClass : ancestorClasses) {
if (InheritanceUtil.isInheritor(aClass, ancestorClass)) {
return true;
}
}
return false;
}
}
}