blob: 6d924a38097459c532c0529ab1cb23c9a696eca9 [file] [log] [blame]
/*
* Copyright 2000-2009 JetBrains s.r.o.
*
* 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.
*/
/*
* Class ClassFilterEditor
* @author Jeka
*/
package com.intellij.ui.classFilter;
import com.intellij.ide.util.ClassFilter;
import com.intellij.ide.util.TreeClassChooser;
import com.intellij.ide.util.TreeClassChooserFactory;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiClass;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.ui.*;
import com.intellij.ui.table.JBTable;
import com.intellij.util.IconUtil;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.ui.ComponentWithEmptyText;
import com.intellij.util.ui.ItemRemovable;
import com.intellij.util.ui.StatusText;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import javax.swing.table.*;
import java.awt.*;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
public class ClassFilterEditor extends JPanel implements ComponentWithEmptyText {
protected JBTable myTable = null;
protected FilterTableModel myTableModel = null;
protected final Project myProject;
private final ClassFilter myChooserFilter;
@Nullable
private final String myPatternsHelpId;
private String classDelimiter = "$";
public ClassFilterEditor(Project project) {
this(project, null);
}
public ClassFilterEditor(Project project, ClassFilter classFilter) {
this(project, classFilter, null);
}
public ClassFilterEditor(Project project, ClassFilter classFilter, @Nullable String patternsHelpId) {
super(new BorderLayout());
myPatternsHelpId = patternsHelpId;
myTable = new JBTable();
final ToolbarDecorator decorator = ToolbarDecorator.createDecorator(myTable)
.addExtraAction(new AnActionButton(getAddButtonText(), getAddButtonIcon()) {
@Override
public void actionPerformed(AnActionEvent e) {
addClassFilter();
}
@Override
public void updateButton(AnActionEvent e) {
super.updateButton(e);
setEnabled(!myProject.isDefault());
}
});
if (addPatternButtonVisible()) {
decorator.addExtraAction(new AnActionButton(getAddPatternButtonText(), getAddPatternButtonIcon()) {
@Override
public void actionPerformed(AnActionEvent e) {
addPatternFilter();
}
@Override
public void updateButton(AnActionEvent e) {
super.updateButton(e);
setEnabled(!myProject.isDefault());
}
});
}
add(decorator.setRemoveAction(new AnActionButtonRunnable() {
@Override
public void run(AnActionButton button) {
TableUtil.removeSelectedItems(myTable);
}
}).setButtonComparator(getAddButtonText(), getAddPatternButtonText(), "Remove")
.disableUpDownActions().createPanel(), BorderLayout.CENTER);
myChooserFilter = classFilter;
myProject = project;
myTableModel = new FilterTableModel();
myTable.setModel(myTableModel);
myTable.setShowGrid(false);
myTable.setIntercellSpacing(new Dimension(0, 0));
myTable.setTableHeader(null);
myTable.setAutoResizeMode(JTable.AUTO_RESIZE_LAST_COLUMN);
myTable.setColumnSelectionAllowed(false);
myTable.setPreferredScrollableViewportSize(new Dimension(200, myTable.getRowHeight() * JBTable.PREFERRED_SCROLLABLE_VIEWPORT_HEIGHT_IN_ROWS));
TableColumnModel columnModel = myTable.getColumnModel();
TableColumn column = columnModel.getColumn(FilterTableModel.CHECK_MARK);
TableUtil.setupCheckboxColumn(column);
column.setCellRenderer(new EnabledCellRenderer(myTable.getDefaultRenderer(Boolean.class)));
columnModel.getColumn(FilterTableModel.FILTER).setCellRenderer(new FilterCellRenderer());
getEmptyText().setText(UIBundle.message("no.patterns"));
}
@NotNull
@Override
public StatusText getEmptyText() {
return myTable.getEmptyText();
}
protected String getAddButtonText() {
return UIBundle.message("button.add.class");
}
protected String getAddPatternButtonText() {
return UIBundle.message("button.add.pattern");
}
protected Icon getAddButtonIcon() {
return IconUtil.getAddClassIcon();
}
protected Icon getAddPatternButtonIcon() {
return IconUtil.getAddPatternIcon();
}
protected boolean addPatternButtonVisible() {
return true;
}
public void setFilters(com.intellij.ui.classFilter.ClassFilter[] filters) {
myTableModel.setFilters(filters);
}
public com.intellij.ui.classFilter.ClassFilter[] getFilters() {
return myTableModel.getFilters();
}
public void setEnabled(boolean enabled) {
super.setEnabled(enabled);
myTable.setEnabled(enabled);
myTable.setRowSelectionAllowed(enabled);
myTableModel.fireTableDataChanged();
}
public void stopEditing() {
TableCellEditor editor = myTable.getCellEditor();
if (editor != null) {
editor.stopCellEditing();
}
}
protected final class FilterTableModel extends AbstractTableModel implements ItemRemovable {
private final List<com.intellij.ui.classFilter.ClassFilter> myFilters = new LinkedList<com.intellij.ui.classFilter.ClassFilter>();
public static final int CHECK_MARK = 0;
public static final int FILTER = 1;
public final void setFilters(com.intellij.ui.classFilter.ClassFilter[] filters) {
myFilters.clear();
if (filters != null) {
ContainerUtil.addAll(myFilters, filters);
}
fireTableDataChanged();
}
public com.intellij.ui.classFilter.ClassFilter[] getFilters() {
for (Iterator<com.intellij.ui.classFilter.ClassFilter> it = myFilters.iterator(); it.hasNext(); ) {
com.intellij.ui.classFilter.ClassFilter filter = it.next();
String pattern = filter.getPattern();
if (pattern == null || "".equals(pattern)) {
it.remove();
}
}
return myFilters.toArray(new com.intellij.ui.classFilter.ClassFilter[myFilters.size()]);
}
public com.intellij.ui.classFilter.ClassFilter getFilterAt(int index) {
return myFilters.get(index);
}
public int getFilterIndex(com.intellij.ui.classFilter.ClassFilter filter) {
return myFilters.indexOf(filter);
}
public void addRow(com.intellij.ui.classFilter.ClassFilter filter) {
myFilters.add(filter);
int row = myFilters.size() - 1;
fireTableRowsInserted(row, row);
}
public int getRowCount() {
return myFilters.size();
}
public int getColumnCount() {
return 2;
}
public Object getValueAt(int rowIndex, int columnIndex) {
com.intellij.ui.classFilter.ClassFilter filter = myFilters.get(rowIndex);
if (columnIndex == FILTER) {
return filter;
}
if (columnIndex == CHECK_MARK) {
return filter.isEnabled() ? Boolean.TRUE : Boolean.FALSE;
}
return null;
}
public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
com.intellij.ui.classFilter.ClassFilter filter = myFilters.get(rowIndex);
if (columnIndex == FILTER) {
filter.setPattern(aValue != null ? aValue.toString() : "");
}
else if (columnIndex == CHECK_MARK) {
filter.setEnabled(aValue == null || ((Boolean)aValue).booleanValue());
}
// fireTableCellUpdated(rowIndex, columnIndex);
fireTableRowsUpdated(rowIndex, rowIndex);
}
public Class getColumnClass(int columnIndex) {
if (columnIndex == CHECK_MARK) {
return Boolean.class;
}
return super.getColumnClass(columnIndex);
}
public boolean isCellEditable(int rowIndex, int columnIndex) {
return isEnabled();
}
public void removeRow(final int idx) {
myFilters.remove(idx);
fireTableDataChanged();
}
}
private class FilterCellRenderer extends DefaultTableCellRenderer {
public Component getTableCellRendererComponent(JTable table, Object value,
boolean isSelected, boolean hasFocus, int row, int column) {
Color color = UIUtil.getTableFocusCellBackground();
UIManager.put(UIUtil.TABLE_FOCUS_CELL_BACKGROUND_PROPERTY, table.getSelectionBackground());
Component component = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
if (component instanceof JLabel) {
((JLabel)component).setBorder(noFocusBorder);
}
UIManager.put(UIUtil.TABLE_FOCUS_CELL_BACKGROUND_PROPERTY, color);
com.intellij.ui.classFilter.ClassFilter filter =
(com.intellij.ui.classFilter.ClassFilter)table.getValueAt(row, FilterTableModel.FILTER);
component.setEnabled(ClassFilterEditor.this.isEnabled() && filter.isEnabled());
return component;
}
}
private class EnabledCellRenderer extends DefaultTableCellRenderer {
private final TableCellRenderer myDelegate;
public EnabledCellRenderer(TableCellRenderer delegate) {
myDelegate = delegate;
}
public Component getTableCellRendererComponent(JTable table, Object value,
boolean isSelected, boolean hasFocus, int row, int column) {
Component component = myDelegate.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
component.setEnabled(ClassFilterEditor.this.isEnabled());
return component;
}
}
@NotNull
protected com.intellij.ui.classFilter.ClassFilter createFilter(String pattern) {
return new com.intellij.ui.classFilter.ClassFilter(pattern);
}
protected void addPatternFilter() {
ClassFilterEditorAddDialog dialog = new ClassFilterEditorAddDialog(myProject, myPatternsHelpId);
dialog.show();
if (dialog.isOK()) {
String pattern = dialog.getPattern();
if (pattern != null) {
com.intellij.ui.classFilter.ClassFilter filter = createFilter(pattern);
myTableModel.addRow(filter);
int row = myTableModel.getRowCount() - 1;
myTable.getSelectionModel().setSelectionInterval(row, row);
myTable.scrollRectToVisible(myTable.getCellRect(row, 0, true));
myTable.requestFocus();
}
}
}
protected void addClassFilter() {
TreeClassChooser chooser = TreeClassChooserFactory.getInstance(myProject).createNoInnerClassesScopeChooser(
UIBundle.message("class.filter.editor.choose.class.title"), GlobalSearchScope.allScope(myProject), myChooserFilter, null);
chooser.showDialog();
PsiClass selectedClass = chooser.getSelected();
if (selectedClass != null) {
com.intellij.ui.classFilter.ClassFilter filter = createFilter(getJvmClassName(selectedClass));
myTableModel.addRow(filter);
int row = myTableModel.getRowCount() - 1;
myTable.getSelectionModel().setSelectionInterval(row, row);
myTable.scrollRectToVisible(myTable.getCellRect(row, 0, true));
myTable.requestFocus();
}
}
@Nullable
private String getJvmClassName(PsiClass aClass) {
PsiClass parentClass = PsiTreeUtil.getParentOfType(aClass, PsiClass.class, true);
if (parentClass != null) {
final String parentName = getJvmClassName(parentClass);
if (parentName == null) {
return null;
}
return parentName + classDelimiter + aClass.getName();
}
return aClass.getQualifiedName();
}
public void setClassDelimiter(String classDelimiter) {
this.classDelimiter = classDelimiter;
}
public void addPattern(String pattern) {
com.intellij.ui.classFilter.ClassFilter filter = createFilter(pattern);
myTableModel.addRow(filter);
}
}