notifications for unknown macros
[fedora-idea.git] / platform / platform-impl / src / com / intellij / application / options / pathMacros / PathMacroTable.java
blob6d18697f2054162471c5956d77f06e418585cfd8
1 package com.intellij.application.options.pathMacros;
3 import com.intellij.openapi.application.ApplicationBundle;
4 import com.intellij.openapi.application.PathMacros;
5 import com.intellij.openapi.diagnostic.Logger;
6 import com.intellij.openapi.ui.Messages;
7 import com.intellij.openapi.util.Pair;
8 import com.intellij.util.ui.Table;
10 import javax.swing.*;
11 import javax.swing.table.AbstractTableModel;
12 import javax.swing.table.DefaultTableCellRenderer;
13 import javax.swing.table.TableColumn;
14 import java.awt.*;
15 import java.io.File;
16 import java.util.*;
17 import java.util.List;
19 /**
20 * @author dsl
22 public class PathMacroTable extends Table {
23 private static final Logger LOG = Logger.getInstance("#com.intellij.application.options.pathMacros.PathMacroTable");
24 private final PathMacros myPathMacros = PathMacros.getInstance();
25 private final MyTableModel myTableModel = new MyTableModel();
26 private static final int NAME_COLUMN = 0;
27 private static final int VALUE_COLUMN = 1;
29 private final List<Pair<String, String>> myMacros = new ArrayList<Pair<String, String>>();
30 private static final Comparator<Pair<String, String>> MACRO_COMPARATOR = new Comparator<Pair<String, String>>() {
31 public int compare(Pair<String, String> pair, Pair<String, String> pair1) {
32 return pair.getFirst().compareTo(pair1.getFirst());
36 private final Collection<String> myUndefinedMacroNames;
38 public PathMacroTable() {
39 this(null);
42 public PathMacroTable(final Collection<String> undefinedMacroNames) {
43 myUndefinedMacroNames = undefinedMacroNames;
44 setModel(myTableModel);
45 TableColumn column = getColumnModel().getColumn(NAME_COLUMN);
46 column.setCellRenderer(new DefaultTableCellRenderer() {
47 public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
48 final Component component = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
49 final String macroValue = getMacroValueAt(row);
50 component.setForeground(macroValue.length() == 0
51 ? Color.RED
52 : isSelected ? table.getSelectionForeground() : table.getForeground());
53 return component;
55 });
56 setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
57 //obtainData();
60 public String getMacroValueAt(int row) {
61 return (String) getValueAt(row, VALUE_COLUMN);
64 public String getMacroNameAt(int row) {
65 return (String)getValueAt(row, NAME_COLUMN);
68 public void addMacro() {
69 final String title = ApplicationBundle.message("title.add.variable");
70 final PathMacroEditor macroEditor = new PathMacroEditor(title, "", "", new AddValidator(title));
71 macroEditor.show();
72 if (macroEditor.isOK()) {
73 final String name = macroEditor.getName();
74 myMacros.add(new Pair<String, String>(name, macroEditor.getValue()));
75 Collections.sort(myMacros, MACRO_COMPARATOR);
76 final int index = indexOfMacroWithName(name);
77 LOG.assertTrue(index >= 0);
78 myTableModel.fireTableDataChanged();
79 setRowSelectionInterval(index, index);
83 private boolean isValidRow(int selectedRow) {
84 return selectedRow >= 0 && selectedRow < myMacros.size();
87 public void removeSelectedMacros() {
88 final int[] selectedRows = getSelectedRows();
89 if(selectedRows.length == 0) return;
90 Arrays.sort(selectedRows);
91 final int originalRow = selectedRows[0];
92 for (int i = selectedRows.length - 1; i >= 0; i--) {
93 final int selectedRow = selectedRows[i];
94 if (isValidRow(selectedRow)) {
95 myMacros.remove(selectedRow);
98 myTableModel.fireTableDataChanged();
99 if (originalRow < getRowCount()) {
100 setRowSelectionInterval(originalRow, originalRow);
101 } else if (getRowCount() > 0) {
102 final int index = getRowCount() - 1;
103 setRowSelectionInterval(index, index);
107 public void commit() {
108 myPathMacros.removeAllMacros();
109 for (Pair<String, String> pair : myMacros) {
110 myPathMacros.setMacro(pair.getFirst(), pair.getSecond().replace(File.separatorChar, '/'));
114 public void reset() {
115 obtainData();
118 private boolean hasMacroWithName(String name) {
119 for (Pair<String, String> macro : myMacros) {
120 if (name.equals(macro.getFirst())) {
121 return true;
124 return false;
127 private int indexOfMacroWithName(String name) {
128 for (int i = 0; i < myMacros.size(); i++) {
129 final Pair<String, String> pair = myMacros.get(i);
130 if (name.equals(pair.getFirst())) {
131 return i;
134 return -1;
137 private void obtainData() {
138 obtainMacroPairs(myMacros);
139 myTableModel.fireTableDataChanged();
142 private void obtainMacroPairs(final List<Pair<String, String>> macros) {
143 macros.clear();
144 final Set<String> macroNames = myPathMacros.getUserMacroNames();
145 for (String name : macroNames) {
146 macros.add(Pair.create(name, myPathMacros.getValue(name).replace('/', File.separatorChar)));
149 if (myUndefinedMacroNames != null) {
150 for (String undefinedMacroName : myUndefinedMacroNames) {
151 macros.add(new Pair<String, String>(undefinedMacroName, ""));
154 Collections.sort(macros, MACRO_COMPARATOR);
157 public void editMacro() {
158 if (getSelectedRowCount() != 1) {
159 return;
161 final int selectedRow = getSelectedRow();
162 final Pair<String, String> pair = myMacros.get(selectedRow);
163 final String title = ApplicationBundle.message("title.edit.variable");
164 final String macroName = pair.getFirst();
165 final PathMacroEditor macroEditor = new PathMacroEditor(title, macroName, pair.getSecond(), new EditValidator());
166 macroEditor.show();
167 if (macroEditor.isOK()) {
168 myMacros.remove(selectedRow);
169 myMacros.add(Pair.create(macroEditor.getName(), macroEditor.getValue()));
170 Collections.sort(myMacros, MACRO_COMPARATOR);
171 myTableModel.fireTableDataChanged();
175 public boolean isModified() {
176 final ArrayList<Pair<String, String>> macros = new ArrayList<Pair<String, String>>();
177 obtainMacroPairs(macros);
178 return !macros.equals(myMacros);
181 private class MyTableModel extends AbstractTableModel{
182 public int getColumnCount() {
183 return 2;
186 public int getRowCount() {
187 return myMacros.size();
190 public Class getColumnClass(int columnIndex) {
191 return String.class;
194 public Object getValueAt(int rowIndex, int columnIndex) {
195 final Pair<String, String> pair = myMacros.get(rowIndex);
196 switch (columnIndex) {
197 case NAME_COLUMN: return pair.getFirst();
198 case VALUE_COLUMN: return pair.getSecond();
200 LOG.error("Wrong indices");
201 return null;
204 public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
207 public String getColumnName(int columnIndex) {
208 switch (columnIndex) {
209 case NAME_COLUMN: return ApplicationBundle.message("column.name");
210 case VALUE_COLUMN: return ApplicationBundle.message("column.value");
212 return null;
215 public boolean isCellEditable(int rowIndex, int columnIndex) {
216 return false;
220 private class AddValidator implements PathMacroEditor.Validator {
221 private final String myTitle;
223 public AddValidator(String title) {
224 myTitle = title;
227 public boolean checkName(String name) {
228 return name.length() > 0 && name.indexOf('$') < 0;
231 public boolean isOK(String name, String value) {
232 if(name.length() == 0) return false;
233 if (hasMacroWithName(name)) {
234 Messages.showErrorDialog(PathMacroTable.this,
235 ApplicationBundle.message("error.variable.already.exists", name), myTitle);
236 return false;
238 return true;
242 private static class EditValidator implements PathMacroEditor.Validator {
243 public boolean checkName(String name) {
244 return name.length() > 0 && name.indexOf('$') < 0;
247 public boolean isOK(String name, String value) {
248 return checkName(name);