/*
* Copyright 2013 Guidewire Software, Inc.
*/
package gw.plugin.ij.refactor.signature;
import com.intellij.openapi.fileTypes.FileType;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiCodeFragment;
import com.intellij.psi.PsiElement;
import com.intellij.refactoring.RefactoringBundle;
import com.intellij.refactoring.changeSignature.ParameterInfo;
import com.intellij.refactoring.changeSignature.ParameterInfoImpl;
import com.intellij.refactoring.ui.StringTableCellEditor;
import com.intellij.ui.*;
import com.intellij.util.ui.ColumnInfo;
import com.intellij.util.ui.ListTableModel;
import gw.plugin.ij.editors.LightweightGosuEditor;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import javax.swing.table.TableCellEditor;
import javax.swing.table.TableCellRenderer;
import java.awt.*;
import java.util.ArrayList;
import java.util.List;
public abstract class ParameterTableModelBase extends ListTableModel<ParameterTableModelItem> implements RowEditableTableModel {
protected final PsiElement myTypeContext;
protected final PsiElement myDefaultValueContext;
public ParameterTableModelBase(PsiElement typeContext,
PsiElement defaultValueContext,
ColumnInfo... columnInfos) {
super(columnInfos);
myTypeContext = typeContext;
myDefaultValueContext = defaultValueContext;
}
protected abstract ParameterTableModelItem createRowItem(@Nullable ParameterInfoImpl parameterInfo);
public void addRow() {
addRow(createRowItem(null));
}
public void setParameterInfos(List<ParameterInfoImpl> parameterInfos) {
List<ParameterTableModelItem> items = new ArrayList<ParameterTableModelItem>(parameterInfos.size());
for (ParameterInfoImpl parameterInfo : parameterInfos) {
items.add(createRowItem(parameterInfo));
}
setItems(items);
}
public void setValueAtWithoutUpdate(Object aValue, int rowIndex, int columnIndex) {
super.setValueAt(aValue, rowIndex, columnIndex);
}
@Override
public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
super.setValueAt(aValue, rowIndex, columnIndex);
fireTableCellUpdated(rowIndex, columnIndex); // to update signature
}
protected static abstract class ColumnInfoBase<Aspect>
extends ColumnInfo<ParameterTableModelItem, Aspect> {
private TableCellRenderer myRenderer;
private TableCellEditor myEditor;
public ColumnInfoBase(String name) {
super(name);
}
@Override
public final TableCellEditor getEditor(ParameterTableModelItem o) {
if (myEditor == null) {
myEditor = doCreateEditor(o);
}
return myEditor;
}
@Override
public final TableCellRenderer getRenderer(ParameterTableModelItem item) {
if (myRenderer == null) {
final TableCellRenderer original = doCreateRenderer(item);
myRenderer = new TableCellRenderer() {
public Component getTableCellRendererComponent(JTable table,
Object value,
boolean isSelected,
boolean hasFocus,
int row,
int column) {
Component component = original.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
if (!table.isCellEditable(row, table.convertColumnIndexToModel(column))) {
Color bg = table.getBackground().darker();
component.setBackground(ColorUtil.toAlpha(bg, 230));
}
if (component instanceof SimpleColoredComponent) {
((SimpleColoredComponent)component).setIpad(new Insets(0, 0, 0, 0));
}
return component;
}
};
}
return myRenderer;
}
protected abstract TableCellRenderer doCreateRenderer(ParameterTableModelItem item);
protected abstract TableCellEditor doCreateEditor(ParameterTableModelItem item);
}
protected static class TypeColumn extends ColumnInfoBase<LightweightGosuEditor> {
protected final Project myProject;
private final FileType myFileType;
public TypeColumn(Project project, FileType fileType) {
this(project, fileType, RefactoringBundle.message("column.name.type"));
}
public TypeColumn(Project project, FileType fileType, String title) {
super(title);
myProject = project;
myFileType = fileType;
}
@Override
public LightweightGosuEditor valueOf(ParameterTableModelItem item) {
return item.typeCodeFragment;
}
@Override
public boolean isCellEditable(ParameterTableModelItem pParameterTableModelItemBase) {
return true;
}
public TableCellRenderer doCreateRenderer(ParameterTableModelItem pParameterTableModelItemBase) {
return new LightEditorCellRenderer(myProject, myFileType);
}
public TableCellEditor doCreateEditor(ParameterTableModelItem o) {
return new LightEditorCellEditor(myProject, myFileType);
}
}
protected static class NameColumn extends ColumnInfoBase<String> {
private final Project myProject;
public NameColumn(Project project) {
this(project, RefactoringBundle.message("column.name.name"));
}
public NameColumn(Project project, String title) {
super(title);
myProject = project;
}
@Override
public String valueOf(ParameterTableModelItem item) {
return item.parameter.getName();
}
@Override
public void setValue(ParameterTableModelItem item, String value) {
item.parameter.setName(value);
}
@Override
public boolean isCellEditable(ParameterTableModelItem pParameterTableModelItemBase) {
return true;
}
public TableCellRenderer doCreateRenderer(ParameterTableModelItem item) {
return new ColoredTableCellRenderer() {
public void customizeCellRenderer(JTable table, Object value,
boolean isSelected, boolean hasFocus, int row, int column) {
if (value == null) return;
append((String)value, new SimpleTextAttributes(Font.PLAIN, null));
}
};
}
public TableCellEditor doCreateEditor(ParameterTableModelItem o) {
return new StringTableCellEditor(myProject);
}
}
protected static class DefaultValueColumn extends ColumnInfoBase<LightweightGosuEditor> {
private final Project myProject;
private final FileType myFileType;
public DefaultValueColumn(Project project, FileType fileType) {
this(project, fileType, RefactoringBundle.message("column.name.default.value"));
}
public DefaultValueColumn(Project project, FileType fileType, String title) {
super(title);
myProject = project;
myFileType = fileType;
}
@Override
public boolean isCellEditable(ParameterTableModelItem item) {
return item.parameter.getOldIndex() == -1;
}
@Override
public LightweightGosuEditor valueOf(ParameterTableModelItem item) {
return item.defaultValueCodeFragment;
}
public TableCellRenderer doCreateRenderer(ParameterTableModelItem item) {
return new LightEditorCellRenderer(myProject, myFileType);
}
public TableCellEditor doCreateEditor(ParameterTableModelItem item) {
return new LightEditorCellEditor(myProject, myFileType);
}
}
protected static class AnyVarColumn extends ColumnInfoBase<Boolean> {
public AnyVarColumn() {
super(RefactoringBundle.message("column.name.any.var"));
}
@Override
public boolean isCellEditable(ParameterTableModelItem item) {
return item.parameter.getOldIndex() == -1;
}
@Override
public Boolean valueOf(ParameterTableModelItem item) {
return item.parameter.isUseAnySingleVariable();
}
@Override
public void setValue(ParameterTableModelItem item, Boolean value) {
item.parameter.setUseAnySingleVariable(value);
}
public TableCellRenderer doCreateRenderer(ParameterTableModelItem item) {
return new BooleanTableCellRenderer();
}
public TableCellEditor doCreateEditor(ParameterTableModelItem item) {
return new BooleanTableCellEditor(false);
}
@Override
public int getWidth(JTable table) {
final int headerWidth = table.getFontMetrics(table.getFont()).stringWidth(getName()) + 8;
return Math.max(new JCheckBox().getPreferredSize().width, headerWidth);
}
}
}