2 * Copyright 2000-2009 JetBrains s.r.o.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
16 package org.jetbrains.plugins.groovy.annotator.intentions.dynamic.ui;
18 import com.intellij.psi.PsiType;
19 import com.intellij.util.IncorrectOperationException;
20 import com.intellij.util.ui.AbstractTableCellEditor;
21 import com.intellij.util.ui.ColumnInfo;
22 import com.intellij.util.ui.ListTableModel;
23 import org.jetbrains.plugins.groovy.GroovyBundle;
24 import org.jetbrains.plugins.groovy.annotator.intentions.QuickfixUtil;
25 import org.jetbrains.plugins.groovy.annotator.intentions.dynamic.MyPair;
26 import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElementFactory;
27 import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression;
28 import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression;
29 import org.jetbrains.plugins.groovy.lang.psi.expectedTypes.GroovyExpectedTypesUtil;
32 import javax.swing.event.CellEditorListener;
33 import javax.swing.event.ChangeEvent;
34 import javax.swing.event.TableModelEvent;
35 import javax.swing.event.TableModelListener;
36 import javax.swing.table.TableColumn;
38 import java.util.EventObject;
39 import java.util.List;
42 * User: Dmitry.Krasilschikov
45 public class DynamicMethodDialog extends DynamicDialog {
46 private final GrReferenceExpression myReferenceExpression;
48 public DynamicMethodDialog(GrReferenceExpression referenceExpression) {
49 super(referenceExpression, QuickfixUtil.createSettings(referenceExpression), GroovyExpectedTypesUtil.calculateTypeConstraints((GrExpression)referenceExpression.getParent()));
50 myReferenceExpression = referenceExpression;
51 assert getSettings().isMethod();
53 final List<MyPair> pairs = getSettings().getPairs();
54 setupParameterTable(pairs);
55 setupParameterList(pairs);
56 setTitle(GroovyBundle.message("add.dynamic.method"));
57 setUpTypeLabel(GroovyBundle.message("dynamic.method.return.type"));
60 protected void setUpTableNameLabel(String text) {
61 super.setUpTableNameLabel(getSettings().getPairs().isEmpty() ? GroovyBundle.message("dynamic.properties.table.no.arguments") : text);
64 private void setupParameterTable(final List<MyPair> pairs) {
65 final JTable table = getParametersTable();
67 MySuggestedNameCellEditor suggestedNameCellEditor = new MySuggestedNameCellEditor(QuickfixUtil.getArgumentsNames(pairs));
68 table.setDefaultEditor(String.class, suggestedNameCellEditor);
70 suggestedNameCellEditor.addCellEditorListener(new CellEditorListener() {
71 public void editingStopped(ChangeEvent e) {
72 final int editingColumn = table.getSelectedColumn();
73 if (editingColumn != 0) return;
75 final int editingRow = table.getSelectedRow();
76 if (editingRow < 0 || editingRow >= pairs.size()) return;
78 String newNameValue = ((MySuggestedNameCellEditor)e.getSource()).getCellEditorValue();
80 final MyPair editingPair = pairs.get(editingRow);
81 editingPair.setFirst(newNameValue);
84 public void editingCanceled(ChangeEvent e) {
89 protected boolean isTableVisible() {
93 private void setupParameterList(List<MyPair> arguments) {
94 final JTable table = getParametersTable();
97 final ListTableModel<MyPair> dataModel = new ListTableModel<MyPair>(new NameColumnInfo(), new TypeColumnInfo());
98 dataModel.addTableModelListener(new TableModelListener() {
99 public void tableChanged(TableModelEvent e) {
103 dataModel.setItems(arguments);
104 table.setModel(dataModel);
105 if (!arguments.isEmpty()) {
106 String max0 = arguments.get(0).first;
107 String max1 = arguments.get(0).second;
108 for (MyPair argument : arguments) {
109 if (argument.first.length() > max0.length()) max0 = argument.first;
110 if (argument.second.length() > max1.length()) max1 = argument.second;
113 final FontMetrics metrics = table.getFontMetrics(table.getFont());
114 final TableColumn column0 = table.getColumnModel().getColumn(0);
115 column0.setPreferredWidth(metrics.stringWidth(max0 + " "));
117 final TableColumn column1 = table.getColumnModel().getColumn(1);
118 column1.setPreferredWidth(metrics.stringWidth(max1 + " "));
123 private class TypeColumnInfo extends ColumnInfo<MyPair, String> {
124 public TypeColumnInfo() {
125 super(GroovyBundle.message("dynamic.name"));
128 public String valueOf(MyPair pair) {
132 public boolean isCellEditable(MyPair stringPsiTypeMyPair) {
136 public void setValue(MyPair pair, String value) {
139 type = GroovyPsiElementFactory.getInstance(getProject()).createTypeElement(value).getType();
141 catch (IncorrectOperationException e) {
145 if (type == null) return;
146 pair.setSecond(type.getCanonicalText());
150 private static class NameColumnInfo extends ColumnInfo<MyPair, String> {
151 public NameColumnInfo() {
152 super(GroovyBundle.message("dynamic.type"));
155 public boolean isCellEditable(MyPair myPair) {
159 public String valueOf(MyPair pair) {
164 protected void updateOkStatus() {
165 super.updateOkStatus();
167 if (getParametersTable().isEditing()) setOKActionEnabled(false);
170 private static class MySuggestedNameCellEditor extends AbstractTableCellEditor {
171 JTextField myNameField;
173 public MySuggestedNameCellEditor(String[] names) {
174 myNameField = names.length == 0 ? new JTextField() : new JTextField(names[0]);
177 public String getCellEditorValue() {
178 return myNameField.getText();
181 public boolean isCellEditable(EventObject e) {
185 public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
186 if (value instanceof String) {
187 myNameField.setText((String)value);