package de.jigp.plugin.actions.builder;
import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.psi.PsiField;
import javax.swing.*;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.TableModel;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
public class PsiFieldFilterDialog extends DialogWrapper implements ActionListener {
private List<PsiField> psiFields;
private Object[][] rowData;
private TableModel tableModel;
private JButton attributesSelection;
private JButton assertionsSelection;
private PsiFieldComparator psiFieldComparator = new PsiFieldComparator();
private JPanel panel;
private JTable table;
private static final int COL_INDEX_ATTRIBUTESELECTION = 0;
private static final int COL_INDEX_ASSERTIONSELECTION = 1;
private boolean isAllAttributesSelected = true;
private boolean isAllAssertionsSelected = true;
private String attributesAllText = "all attributes";
private String attributesNonText = "no attributes";
private String assertionsAllText = "all assertions";
private String assertionsNonText = "no assertions";
public PsiFieldFilterDialog(PsiField[] psiFields) {
super(true);
this.psiFields = Arrays.asList(psiFields);
this.init();
}
protected void init() {
setTitle("Attribute selection");
setResizable(true);
super.init();
}
protected JComponent createCenterPanel() {
createPanel();
addTableToPanel();
addSelectionButtons();
return panel;
}
private void addTableToPanel() {
createTable();
JScrollPane tablePane = new JScrollPane(table);
panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
panel.add(tablePane);
}
private void createTable() {
createTableRowData();
createTableModel();
table = new JTable(tableModel);
setTableColumnWidths();
}
private void setTableColumnWidths() {
table.getColumnModel().getColumn(COL_INDEX_ATTRIBUTESELECTION).setPreferredWidth(150);
table.getColumnModel().getColumn(COL_INDEX_ASSERTIONSELECTION).setPreferredWidth(250);
table.getColumnModel().getColumn(2).setPreferredWidth(550);
table.getColumnModel().getColumn(3).setPreferredWidth(350);
}
private void createTableRowData() {
rowData = new Object[psiFields.size()][3];
int i = 0;
Collections.sort(psiFields, psiFieldComparator);
for (PsiField psiField : psiFields) {
rowData[i++] = createRowEntry(psiField);
}
}
private void createPanel() {
panel = new JPanel();
}
private Object[] createRowEntry(PsiField psiField) {
return new Object[]{true, true, psiField.getName(), psiField.getTypeElement().getType().getPresentableText()};
}
protected void addSelectionButtons() {
JPanel buttonPanel = new JPanel();
buttonPanel.setLayout(new BoxLayout(buttonPanel, BoxLayout.X_AXIS));
attributesSelection = new JButton(attributesNonText);
attributesSelection.addActionListener(this);
assertionsSelection = new JButton(assertionsNonText);
assertionsSelection.addActionListener(this);
buttonPanel.add(attributesSelection);
buttonPanel.add(assertionsSelection);
panel.add(buttonPanel);
}
protected void createTableModel() {
tableModel = new AbstractTableModel() {
String[] columnNames = new String[]{"attribute", "with assertion", "name", "type"};
public String getColumnName(int col) {
return columnNames[col];
}
public int getRowCount() {
return rowData.length;
}
public int getColumnCount() {
return columnNames.length;
}
public Object getValueAt(int row, int col) {
return rowData[row][col];
}
public boolean isCellEditable(int row, int col) {
return isColumnSelectable(col);
}
public void setValueAt(Object value, int row, int col) {
rowData[row][col] = value;
fireTableCellUpdated(row, col);
}
@Override
public Class<?> getColumnClass(int i) {
if (isColumnSelectable(i)) {
return Boolean.class;
}
return super.getColumnClass(i);
}
};
}
private boolean isColumnSelectable(int col) {
return col == COL_INDEX_ATTRIBUTESELECTION || col == COL_INDEX_ASSERTIONSELECTION;
}
public Collection<PsiField> getSelectedPsiFields() {
return getSelectedFieldsForColumn(COL_INDEX_ATTRIBUTESELECTION);
}
public Collection<PsiField> getAssertionPsiFields() {
return getSelectedFieldsForColumn(COL_INDEX_ASSERTIONSELECTION);
}
private Collection<PsiField> getSelectedFieldsForColumn(int column) {
Collection<PsiField> selectedPsiFields = new ArrayList<PsiField>();
int row = COL_INDEX_ATTRIBUTESELECTION;
for (PsiField psiField : psiFields) {
Boolean isSelected = (Boolean) tableModel.getValueAt(row, column);
row++;
if (isSelected) {
selectedPsiFields.add(psiField);
}
}
return selectedPsiFields;
}
public void actionPerformed(ActionEvent actionEvent) {
if (attributesSelection.equals(actionEvent.getSource())) {
toggleAllAttributesSelection();
} else if (assertionsSelection.equals(actionEvent.getSource())) {
toggleAllAssertionsSelection();
}
this.table.updateUI();
}
private void toggleAllAssertionsSelection() {
assertionsSelection.setText(toggledAssertionSelection());
if (isAllAssertionsSelected) {
setAllAssertionsSelected();
} else {
updateSelectionColumn(COL_INDEX_ASSERTIONSELECTION, isAllAssertionsSelected);
}
}
private void toggleAllAttributesSelection() {
attributesSelection.setText(toggledAttributeSelection());
updateSelectionColumn(COL_INDEX_ATTRIBUTESELECTION, isAllAttributesSelected);
if (!isAllAttributesSelected) {
assertionsSelection.setText(assertionsAllText);
isAllAssertionsSelected = false;
updateSelectionColumn(COL_INDEX_ASSERTIONSELECTION, isAllAssertionsSelected);
}
}
private String toggledAssertionSelection() {
if (isAllAssertionsSelected) {
isAllAssertionsSelected = !isAllAssertionsSelected;
return assertionsAllText;
} else {
isAllAssertionsSelected = !isAllAssertionsSelected;
return assertionsNonText;
}
}
private String toggledAttributeSelection() {
if (isAllAttributesSelected) {
isAllAttributesSelected = !isAllAttributesSelected;
return attributesAllText;
} else {
isAllAttributesSelected = !isAllAttributesSelected;
return attributesNonText;
}
}
private void updateSelectionColumn(int colIndex, boolean isSelected) {
for (Object[] row : rowData) {
row[colIndex] = isSelected;
}
}
private void setAllAssertionsSelected() {
for (Object[] row : rowData) {
if ((Boolean) row[COL_INDEX_ATTRIBUTESELECTION]) {
row[COL_INDEX_ASSERTIONSELECTION] = true;
}
}
}
public static class PsiFieldComparator implements Comparator<PsiField>, Serializable {
public int compare(PsiField psiField, PsiField psiField1) {
if (psiField == null || psiField1 == null) {
return -1;
}
return psiField.getName().compareTo(psiField1.getName());
}
}
}