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 com
.intellij
.application
.options
.pathMacros
;
18 import com
.intellij
.application
.options
.PathMacrosCollector
;
19 import com
.intellij
.openapi
.application
.ApplicationBundle
;
20 import com
.intellij
.openapi
.application
.PathMacros
;
21 import com
.intellij
.openapi
.diagnostic
.Logger
;
22 import com
.intellij
.openapi
.ui
.Messages
;
23 import com
.intellij
.openapi
.util
.Pair
;
24 import com
.intellij
.openapi
.util
.text
.StringUtil
;
25 import com
.intellij
.util
.ui
.Table
;
28 import javax
.swing
.table
.AbstractTableModel
;
29 import javax
.swing
.table
.DefaultTableCellRenderer
;
30 import javax
.swing
.table
.TableColumn
;
34 import java
.util
.List
;
35 import java
.util
.regex
.Pattern
;
40 public class PathMacroTable
extends Table
{
41 private static final Logger LOG
= Logger
.getInstance("#com.intellij.application.options.pathMacros.PathMacroTable");
42 private final PathMacros myPathMacros
= PathMacros
.getInstance();
43 private final MyTableModel myTableModel
= new MyTableModel();
44 private static final int NAME_COLUMN
= 0;
45 private static final int VALUE_COLUMN
= 1;
47 private final List
<Pair
<String
, String
>> myMacros
= new ArrayList
<Pair
<String
, String
>>();
48 private static final Comparator
<Pair
<String
, String
>> MACRO_COMPARATOR
= new Comparator
<Pair
<String
, String
>>() {
49 public int compare(Pair
<String
, String
> pair
, Pair
<String
, String
> pair1
) {
50 return pair
.getFirst().compareTo(pair1
.getFirst());
54 private final Collection
<String
> myUndefinedMacroNames
;
56 public PathMacroTable() {
60 public PathMacroTable(final Collection
<String
> undefinedMacroNames
) {
61 myUndefinedMacroNames
= undefinedMacroNames
;
62 setModel(myTableModel
);
63 TableColumn column
= getColumnModel().getColumn(NAME_COLUMN
);
64 column
.setCellRenderer(new DefaultTableCellRenderer() {
65 public Component
getTableCellRendererComponent(JTable table
, Object value
, boolean isSelected
, boolean hasFocus
, int row
, int column
) {
66 final Component component
= super.getTableCellRendererComponent(table
, value
, isSelected
, hasFocus
, row
, column
);
67 final String macroValue
= getMacroValueAt(row
);
68 component
.setForeground(macroValue
.length() == 0
70 : isSelected ? table
.getSelectionForeground() : table
.getForeground());
74 setSelectionMode(ListSelectionModel
.MULTIPLE_INTERVAL_SELECTION
);
78 public String
getMacroValueAt(int row
) {
79 return (String
) getValueAt(row
, VALUE_COLUMN
);
82 public String
getMacroNameAt(int row
) {
83 return (String
)getValueAt(row
, NAME_COLUMN
);
86 public void addMacro() {
87 final String title
= ApplicationBundle
.message("title.add.variable");
88 final PathMacroEditor macroEditor
= new PathMacroEditor(title
, "", "", new AddValidator(title
));
90 if (macroEditor
.isOK()) {
91 final String name
= macroEditor
.getName();
92 myMacros
.add(new Pair
<String
, String
>(name
, macroEditor
.getValue()));
93 Collections
.sort(myMacros
, MACRO_COMPARATOR
);
94 final int index
= indexOfMacroWithName(name
);
95 LOG
.assertTrue(index
>= 0);
96 myTableModel
.fireTableDataChanged();
97 setRowSelectionInterval(index
, index
);
101 private boolean isValidRow(int selectedRow
) {
102 return selectedRow
>= 0 && selectedRow
< myMacros
.size();
105 public void removeSelectedMacros() {
106 final int[] selectedRows
= getSelectedRows();
107 if(selectedRows
.length
== 0) return;
108 Arrays
.sort(selectedRows
);
109 final int originalRow
= selectedRows
[0];
110 for (int i
= selectedRows
.length
- 1; i
>= 0; i
--) {
111 final int selectedRow
= selectedRows
[i
];
112 if (isValidRow(selectedRow
)) {
113 myMacros
.remove(selectedRow
);
116 myTableModel
.fireTableDataChanged();
117 if (originalRow
< getRowCount()) {
118 setRowSelectionInterval(originalRow
, originalRow
);
119 } else if (getRowCount() > 0) {
120 final int index
= getRowCount() - 1;
121 setRowSelectionInterval(index
, index
);
125 public void commit() {
126 myPathMacros
.removeAllMacros();
127 for (Pair
<String
, String
> pair
: myMacros
) {
128 final String value
= pair
.getSecond();
129 if (value
!= null && value
.trim().length() > 0) {
130 myPathMacros
.setMacro(pair
.getFirst(), value
.replace(File
.separatorChar
, '/'));
135 public void reset() {
139 private boolean hasMacroWithName(String name
) {
140 for (Pair
<String
, String
> macro
: myMacros
) {
141 if (name
.equals(macro
.getFirst())) {
148 private int indexOfMacroWithName(String name
) {
149 for (int i
= 0; i
< myMacros
.size(); i
++) {
150 final Pair
<String
, String
> pair
= myMacros
.get(i
);
151 if (name
.equals(pair
.getFirst())) {
158 private void obtainData() {
159 obtainMacroPairs(myMacros
);
160 myTableModel
.fireTableDataChanged();
163 private void obtainMacroPairs(final List
<Pair
<String
, String
>> macros
) {
165 final Set
<String
> macroNames
= myPathMacros
.getUserMacroNames();
166 for (String name
: macroNames
) {
167 macros
.add(Pair
.create(name
, myPathMacros
.getValue(name
).replace('/', File
.separatorChar
)));
170 if (myUndefinedMacroNames
!= null) {
171 for (String undefinedMacroName
: myUndefinedMacroNames
) {
172 macros
.add(new Pair
<String
, String
>(undefinedMacroName
, ""));
175 Collections
.sort(macros
, MACRO_COMPARATOR
);
178 public void editMacro() {
179 if (getSelectedRowCount() != 1) {
182 final int selectedRow
= getSelectedRow();
183 final Pair
<String
, String
> pair
= myMacros
.get(selectedRow
);
184 final String title
= ApplicationBundle
.message("title.edit.variable");
185 final String macroName
= pair
.getFirst();
186 final PathMacroEditor macroEditor
= new PathMacroEditor(title
, macroName
, pair
.getSecond(), new EditValidator());
188 if (macroEditor
.isOK()) {
189 myMacros
.remove(selectedRow
);
190 myMacros
.add(Pair
.create(macroEditor
.getName(), macroEditor
.getValue()));
191 Collections
.sort(myMacros
, MACRO_COMPARATOR
);
192 myTableModel
.fireTableDataChanged();
196 public boolean isModified() {
197 final ArrayList
<Pair
<String
, String
>> macros
= new ArrayList
<Pair
<String
, String
>>();
198 obtainMacroPairs(macros
);
199 return !macros
.equals(myMacros
);
202 private class MyTableModel
extends AbstractTableModel
{
203 public int getColumnCount() {
207 public int getRowCount() {
208 return myMacros
.size();
211 public Class
getColumnClass(int columnIndex
) {
215 public Object
getValueAt(int rowIndex
, int columnIndex
) {
216 final Pair
<String
, String
> pair
= myMacros
.get(rowIndex
);
217 switch (columnIndex
) {
218 case NAME_COLUMN
: return pair
.getFirst();
219 case VALUE_COLUMN
: return pair
.getSecond();
221 LOG
.error("Wrong indices");
225 public void setValueAt(Object aValue
, int rowIndex
, int columnIndex
) {
228 public String
getColumnName(int columnIndex
) {
229 switch (columnIndex
) {
230 case NAME_COLUMN
: return ApplicationBundle
.message("column.name");
231 case VALUE_COLUMN
: return ApplicationBundle
.message("column.value");
236 public boolean isCellEditable(int rowIndex
, int columnIndex
) {
241 private class AddValidator
implements PathMacroEditor
.Validator
{
242 private final String myTitle
;
244 public AddValidator(String title
) {
248 public boolean checkName(String name
) {
249 if (name
.length() == 0) return false;
250 return PathMacrosCollector
.MACRO_PATTERN
.matcher("$" + name
+ "$").matches();
253 public boolean isOK(String name
, String value
) {
254 if(name
.length() == 0) return false;
255 if (hasMacroWithName(name
)) {
256 Messages
.showErrorDialog(PathMacroTable
.this,
257 ApplicationBundle
.message("error.variable.already.exists", name
), myTitle
);
264 private static class EditValidator
implements PathMacroEditor
.Validator
{
265 public boolean checkName(String name
) {
266 if (name
.length() == 0) return false;
267 return PathMacrosCollector
.MACRO_PATTERN
.matcher("$" + name
+ "$").matches();
270 public boolean isOK(String name
, String value
) {
271 return checkName(name
);