ability to search tests candidates in project content by relative path from TC agent
[idea/community.git] / java / java-impl / src / com / intellij / application / options / CodeStyleImportsPanel.java
1 /*
2  * Copyright 2000-2009 JetBrains s.r.o.
3  *
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
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16 package com.intellij.application.options;
17
18 import com.intellij.openapi.application.ApplicationBundle;
19 import com.intellij.openapi.ui.VerticalFlowLayout;
20 import com.intellij.openapi.ui.ex.MultiLineLabel;
21 import com.intellij.psi.codeStyle.CodeStyleSettings;
22 import com.intellij.ui.*;
23 import com.intellij.util.ui.Table;
24
25 import javax.swing.*;
26 import javax.swing.event.ListSelectionEvent;
27 import javax.swing.event.ListSelectionListener;
28 import javax.swing.table.AbstractTableModel;
29 import javax.swing.table.TableCellEditor;
30 import javax.swing.table.TableModel;
31 import java.awt.*;
32 import java.awt.event.ActionEvent;
33 import java.awt.event.ActionListener;
34
35 public class CodeStyleImportsPanel extends JPanel {
36   private JCheckBox myCbUseFQClassNames;
37   private JCheckBox myCbUseFQClassNamesInJavaDoc;
38   private JCheckBox myCbUseSingleClassImports;
39   private JCheckBox myCbInsertInnerClassImports;
40   private JCheckBox myCbOptimizeImportsOnTheFly;
41   private JCheckBox myCbAddUnambiguousImportsOnTheFly;
42   private JTextField myClassCountField;
43   private JTextField myNamesCountField;
44   private final CodeStyleSettings.ImportLayoutTable myImportLayoutList = new CodeStyleSettings.ImportLayoutTable();
45   private CodeStyleSettings.PackageTable myPackageList = new CodeStyleSettings.PackageTable();
46   private CodeStyleSettings.ImportLayoutTable.PackageEntry myOtherPackageEntry = null;
47
48   private Table myImportLayoutTable;
49   private JButton myMoveUpButton;
50   private JButton myMoveDownButton;
51   private JButton myRemovePackageFromImportLayoutButton;
52   private JButton myRemovePackageFromPackagesButton;
53   private Table myPackageTable;
54   private final CodeStyleSettings mySettings;
55   private JRadioButton myJspImportCommaSeparated;
56   private JRadioButton myJspOneImportPerDirective;
57
58   private JPanel myGeneralPanel;
59   private JPanel myJSPPanel;
60   private JPanel myPackagesPanel;
61   private JPanel myImportsLayoutPanel;
62   private JPanel myWholePanel;
63
64   public CodeStyleImportsPanel(CodeStyleSettings settings){
65     mySettings = settings;
66     setLayout(new BorderLayout());
67     setBorder(BorderFactory.createEmptyBorder(8, 4, 4, 4));
68     add(myWholePanel, BorderLayout.CENTER);
69
70     myGeneralPanel.add(createGeneralOptionsPanel(), BorderLayout.CENTER);
71     myJSPPanel.add(createJspImportLayoutPanel(), BorderLayout.CENTER);
72     myPackagesPanel.add(createPackagesPanel(), BorderLayout.NORTH);
73     myImportsLayoutPanel.add(createImportLayoutPanel(), BorderLayout.NORTH);
74   }
75
76   private JPanel createJspImportLayoutPanel() {
77     ButtonGroup buttonGroup = new ButtonGroup();
78     myJspImportCommaSeparated = new JRadioButton(ApplicationBundle.message("radio.prefer.comma.separated.import.list"));
79     myJspOneImportPerDirective = new JRadioButton(ApplicationBundle.message("radio.prefer.one.import.statement.per.page.directive"));
80     buttonGroup.add(myJspImportCommaSeparated);
81     buttonGroup.add(myJspOneImportPerDirective);
82     JPanel btnPanel = new JPanel(new BorderLayout());
83     btnPanel.add(myJspImportCommaSeparated, BorderLayout.NORTH);
84     btnPanel.add(myJspOneImportPerDirective, BorderLayout.CENTER);
85
86     //noinspection HardCodedStringLiteral
87     final MultiLineLabel commaSeparatedLabel = new MultiLineLabel("<% page import=\"com.company.Boo, \n" +
88                                                                   "                 com.company.Far\"%>");
89     //noinspection HardCodedStringLiteral
90     final MultiLineLabel oneImportPerDirectiveLabel = new MultiLineLabel("<% page import=\"com.company.Boo\"%>\n" +
91                                                                          "<% page import=\"com.company.Far\"%>");
92     final JPanel labelPanel = new JPanel(new BorderLayout());
93     labelPanel.setBorder(IdeBorderFactory.createTitledBorder(ApplicationBundle.message("title.preview")));
94
95     JPanel resultPanel = new JPanel(new BorderLayout());
96     resultPanel.add(btnPanel, BorderLayout.NORTH);
97     resultPanel.add(labelPanel, BorderLayout.CENTER);
98     resultPanel.setBorder(IdeBorderFactory.createTitledBorder(ApplicationBundle.message("title.jsp.imports.layout")));
99
100
101     ActionListener actionListener = new ActionListener() {
102       public void actionPerformed(ActionEvent e) {
103         boolean isComma = myJspImportCommaSeparated.isSelected();
104         labelPanel.removeAll();
105         labelPanel.add(isComma ? commaSeparatedLabel : oneImportPerDirectiveLabel, BorderLayout.CENTER);
106         labelPanel.repaint();
107         labelPanel.revalidate();
108       }
109     };
110     myJspImportCommaSeparated.addActionListener(actionListener);
111     myJspOneImportPerDirective.addActionListener(actionListener);
112     return resultPanel;
113   }
114
115   private JPanel createGeneralOptionsPanel() {
116     OptionGroup group = new OptionGroup(ApplicationBundle.message("title.general"));
117     myCbUseSingleClassImports = new JCheckBox(ApplicationBundle.message("checkbox.use.single.class.import"));
118     group.add(myCbUseSingleClassImports);
119
120     myCbUseFQClassNames = new JCheckBox(ApplicationBundle.message("checkbox.use.fully.qualified.class.names"));
121     group.add(myCbUseFQClassNames);
122
123     myCbInsertInnerClassImports = new JCheckBox(ApplicationBundle.message("checkbox.insert.imports.for.inner.classes"));
124     group.add(myCbInsertInnerClassImports);
125
126     myCbUseFQClassNamesInJavaDoc = new JCheckBox(ApplicationBundle.message("checkbox.use.fully.qualified.class.names.in.javadoc"));
127     group.add(myCbUseFQClassNamesInJavaDoc);
128
129     myCbOptimizeImportsOnTheFly = new JCheckBox(ApplicationBundle.message("checkbox.optimize.imports.on.the.fly"));
130     group.add(myCbOptimizeImportsOnTheFly);
131
132     myCbAddUnambiguousImportsOnTheFly = new JCheckBox(ApplicationBundle.message("checkbox.add.unambiguous.imports.on.the.fly"));
133     group.add(myCbAddUnambiguousImportsOnTheFly);
134
135     myClassCountField = new JTextField(3);
136     myNamesCountField = new JTextField(3);
137     final JPanel panel = new JPanel(new GridBagLayout());
138     panel.add(new JLabel(ApplicationBundle.message("editbox.class.count.to.use.import.with.star")), new GridBagConstraints(0, GridBagConstraints.RELATIVE, 1, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(0, 3, 0, 0), 0, 0));
139     panel.add(myClassCountField, new GridBagConstraints(1, GridBagConstraints.RELATIVE, 1, 1, 1.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(0, 1, 0, 0), 0, 0));
140     panel.add(new JLabel(ApplicationBundle.message("editbox.names.count.to.use.static.import.with.star")), new GridBagConstraints(0, GridBagConstraints.RELATIVE, 1, 1, 0.0, 1.0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(0, 3, 0, 0), 0, 0));
141     panel.add(myNamesCountField, new GridBagConstraints(1, GridBagConstraints.RELATIVE, 1, 1, 1.0, 1.0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(0, 1, 0, 0), 0, 0));
142
143     group.add(panel);
144     return group.createPanel();
145   }
146
147   private JPanel createPackagesPanel() {
148     JPanel panel = new JPanel(new BorderLayout());
149     panel.setBorder(IdeBorderFactory.createTitledBorder(ApplicationBundle.message("title.packages.to.use.import.with")));
150
151     panel.add(createPackagesTable(), BorderLayout.CENTER);
152     panel.add(createPackagesButtonsPanel(), BorderLayout.EAST);
153     panel.setPreferredSize(new Dimension(-1, 200));
154     return panel;
155   }
156
157   private JPanel createImportLayoutPanel() {
158     JPanel panel = new JPanel(new BorderLayout());
159     panel.setBorder(IdeBorderFactory.createTitledBorder(ApplicationBundle.message("title.import.layout")));
160     panel.add(createImportLayoutTable(), BorderLayout.CENTER);
161     panel.add(createImportLayoutButtonsPanel(), BorderLayout.EAST);
162     panel.setPreferredSize(new Dimension(-1, 200));
163     return panel;
164   }
165
166   private JPanel createImportLayoutButtonsPanel() {
167     JPanel tableButtonsPanel = new JPanel(new VerticalFlowLayout());
168
169     JButton addPackageToImportLayoutButton = new JButton(ApplicationBundle.message("button.add.package"));
170     tableButtonsPanel.add(addPackageToImportLayoutButton);
171
172     JButton addBlankLineButton = new JButton(ApplicationBundle.message("button.add.blank"));
173     tableButtonsPanel.add(addBlankLineButton);
174
175     myMoveUpButton = new JButton(ApplicationBundle.message("button.move.up"));
176     tableButtonsPanel.add(myMoveUpButton);
177
178     myMoveDownButton = new JButton(ApplicationBundle.message("button.move.down"));
179     tableButtonsPanel.add(myMoveDownButton);
180
181     myRemovePackageFromImportLayoutButton = new JButton(ApplicationBundle.message("button.remove"));
182     tableButtonsPanel.add(myRemovePackageFromImportLayoutButton);
183
184     addPackageToImportLayoutButton.addActionListener(
185       new ActionListener(){
186         public void actionPerformed(ActionEvent e){
187           addPackageToImportLayouts();
188         }
189       }
190     );
191
192     addBlankLineButton.addActionListener(
193       new ActionListener(){
194         public void actionPerformed(ActionEvent e){
195           addBlankLine();
196         }
197       }
198     );
199
200     myRemovePackageFromImportLayoutButton.addActionListener(
201       new ActionListener(){
202         public void actionPerformed(ActionEvent e){
203           removeEntryFromImportLayouts();
204         }
205       }
206     );
207
208     myMoveUpButton.addActionListener(
209       new ActionListener(){
210         public void actionPerformed(ActionEvent e){
211           moveRowUp();
212         }
213       }
214     );
215
216     myMoveDownButton.addActionListener(
217       new ActionListener(){
218         public void actionPerformed(ActionEvent e){
219           moveRowDown();
220         }
221       }
222     );
223
224     return tableButtonsPanel;
225   }
226
227   private JPanel createPackagesButtonsPanel() {
228     JPanel tableButtonsPanel = new JPanel(new VerticalFlowLayout());
229     tableButtonsPanel.setBorder(BorderFactory.createEmptyBorder(4,4,4,4));
230
231     JButton addPackageToPackagesButton = new JButton(ApplicationBundle.message("button.add.package.p"));
232     tableButtonsPanel.add(addPackageToPackagesButton);
233
234     myRemovePackageFromPackagesButton = new JButton(ApplicationBundle.message("button.remove.r"));
235     tableButtonsPanel.add(myRemovePackageFromPackagesButton);
236
237     addPackageToPackagesButton.addActionListener(
238       new ActionListener(){
239         public void actionPerformed(ActionEvent e){
240           addPackageToPackages();
241         }
242       }
243     );
244
245     myRemovePackageFromPackagesButton.addActionListener(
246       new ActionListener(){
247         public void actionPerformed(ActionEvent e){
248           removeEntryFromPackages();
249         }
250       }
251     );
252
253     return tableButtonsPanel;
254   }
255
256   private void addPackageToImportLayouts() {
257     int selected = myImportLayoutTable.getSelectedRow() + 1;
258     if(selected < 0) {
259       selected = myImportLayoutList.getEntryCount();
260     }
261     CodeStyleSettings.ImportLayoutTable.PackageEntry entry = new CodeStyleSettings.ImportLayoutTable.PackageEntry("", true);
262     myImportLayoutList.insertEntryAt(entry, selected);
263     refreshTableModel(selected, myImportLayoutTable);
264   }
265
266   private static void refreshTableModel(int selectedRow, Table table) {
267     AbstractTableModel model = (AbstractTableModel)table.getModel();
268     model.fireTableRowsInserted(selectedRow, selectedRow);
269     table.setRowSelectionInterval(selectedRow, selectedRow);
270 //    myImportLayoutTable.requestFocus();
271 //    myImportLayoutTable.editCellAt(selected, 0);
272     TableUtil.editCellAt(table, selectedRow, 0);
273     Component editorComp = table.getEditorComponent();
274     if(editorComp != null) {
275       editorComp.requestFocus();
276     }
277   }
278
279   private void addPackageToPackages() {
280     int selected = myPackageTable.getSelectedRow() + 1;
281     if(selected < 0) {
282       selected = myPackageList.getEntryCount();
283     }
284     CodeStyleSettings.PackageTable.Entry entry = new CodeStyleSettings.PackageTable.Entry("", true);
285     myPackageList.insertEntryAt(entry, selected);
286     refreshTableModel(selected, myPackageTable);
287   }
288
289   private void addBlankLine() {
290     int selected = myImportLayoutTable.getSelectedRow() + 1;
291     if(selected < 0) {
292       selected = myImportLayoutList.getEntryCount();
293     }
294     CodeStyleSettings.ImportLayoutTable.EmptyLineEntry entry = new CodeStyleSettings.ImportLayoutTable.EmptyLineEntry();
295     myImportLayoutList.insertEntryAt(entry, selected);
296     AbstractTableModel model = (AbstractTableModel)myImportLayoutTable.getModel();
297     model.fireTableRowsInserted(selected, selected);
298     myImportLayoutTable.setRowSelectionInterval(selected, selected);
299   }
300
301   private void removeEntryFromImportLayouts() {
302     int selected = myImportLayoutTable.getSelectedRow();
303     if(selected < 0)
304       return;
305     CodeStyleSettings.ImportLayoutTable.Entry entry = myImportLayoutList.getEntryAt(selected);
306     if(isOtherEntry(entry)) {
307       boolean isFound = false;
308       CodeStyleSettings.ImportLayoutTable.Entry[] entries = myImportLayoutList.getEntries();
309       for(int i = 0; i < entries.length; i++){
310         if(i != selected && isOtherEntry(entries[i])) {
311           isFound = true;
312           break;
313         }
314       }
315       if(!isFound) {
316         return;
317       }
318     }
319     if(myImportLayoutTable.isEditing()) {
320       TableCellEditor editor = myImportLayoutTable.getCellEditor();
321       if (editor != null) {
322         editor.stopCellEditing();
323       }
324     }
325     myImportLayoutList.removeEntryAt(selected);
326     AbstractTableModel model = (AbstractTableModel)myImportLayoutTable.getModel();
327     model.fireTableRowsDeleted(selected, selected);
328     if(selected >= myImportLayoutList.getEntryCount()) {
329       selected --;
330     }
331     if(selected >= 0) {
332       myImportLayoutTable.setRowSelectionInterval(selected, selected);
333     }
334   }
335
336   private void removeEntryFromPackages() {
337     int selected = myPackageTable.getSelectedRow();
338     if(selected < 0)
339       return;
340     if(myPackageTable.isEditing()) {
341       TableCellEditor editor = myPackageTable.getCellEditor();
342       if (editor != null) {
343         editor.stopCellEditing();
344       }
345     }
346     myPackageList.removeEntryAt(selected);
347     AbstractTableModel model = (AbstractTableModel)myPackageTable.getModel();
348     model.fireTableRowsDeleted(selected, selected);
349     if(selected >= myPackageList.getEntryCount()) {
350       selected --;
351     }
352     if(selected >= 0) {
353       myPackageTable.setRowSelectionInterval(selected, selected);
354     }
355   }
356
357   private void moveRowUp() {
358     int selected = myImportLayoutTable.getSelectedRow();
359     if(selected < 1) {
360       return;
361     }
362     if(myImportLayoutTable.isEditing()) {
363       TableCellEditor editor = myImportLayoutTable.getCellEditor();
364       if (editor != null) {
365         editor.stopCellEditing();
366       }
367     }
368     CodeStyleSettings.ImportLayoutTable.Entry entry = myImportLayoutList.getEntryAt(selected);
369     CodeStyleSettings.ImportLayoutTable.Entry previousEntry = myImportLayoutList.getEntryAt(selected-1);
370     myImportLayoutList.setEntryAt(previousEntry, selected);
371     myImportLayoutList.setEntryAt(entry, selected-1);
372
373     AbstractTableModel model = (AbstractTableModel)myImportLayoutTable.getModel();
374     model.fireTableRowsUpdated(selected-1, selected);
375     myImportLayoutTable.setRowSelectionInterval(selected-1, selected-1);
376   }
377
378   private void moveRowDown() {
379     int selected = myImportLayoutTable.getSelectedRow();
380     if(selected >= myImportLayoutList.getEntryCount()-1) {
381       return;
382     }
383     if(myImportLayoutTable.isEditing()) {
384       TableCellEditor editor = myImportLayoutTable.getCellEditor();
385       if (editor != null) {
386         editor.stopCellEditing();
387       }
388     }
389     CodeStyleSettings.ImportLayoutTable.Entry entry = myImportLayoutList.getEntryAt(selected);
390     CodeStyleSettings.ImportLayoutTable.Entry nextEntry = myImportLayoutList.getEntryAt(selected+1);
391     myImportLayoutList.setEntryAt(nextEntry, selected);
392     myImportLayoutList.setEntryAt(entry, selected+1);
393
394     AbstractTableModel model = (AbstractTableModel)myImportLayoutTable.getModel();
395     model.fireTableRowsUpdated(selected, selected+1);
396     myImportLayoutTable.setRowSelectionInterval(selected+1, selected+1);
397   }
398
399   private JComponent createPackagesTable() {
400     final String[] names = {
401       ApplicationBundle.message("listbox.import.package"),
402       ApplicationBundle.message("listbox.import.with.subpackages")
403     };
404     // Create a model of the data.
405     TableModel dataModel = new AbstractTableModel() {
406       public int getColumnCount() { return names.length; }
407       public int getRowCount() { return myPackageList.getEntryCount();}
408       public Object getValueAt(int row, int col) {
409         CodeStyleSettings.PackageTable.Entry entry = myPackageList.getEntryAt(row);
410         if(col == 0) {
411           if(entry != null) {
412             return entry.getPackageName();
413           }
414         }
415
416         if(col == 1) {
417           if(entry != null) {
418             return entry.isWithSubpackages() ? Boolean.TRUE : Boolean.FALSE;
419           }
420         }
421         return null;
422       }
423       public String getColumnName(int column) { return names[column]; }
424       public Class getColumnClass(int c) {
425         if(c == 0) {
426           return String.class;
427         }
428         if(c == 1) {
429           return Boolean.class;
430         }
431         return null;
432       }
433       public boolean isCellEditable(int row, int col) {
434         return true;
435       }
436
437       public void setValueAt(Object aValue, int row, int col) {
438         CodeStyleSettings.PackageTable.Entry packageEntry = myPackageList.getEntryAt(row);
439         if(col == 0) {
440           CodeStyleSettings.PackageTable.Entry newPackageEntry = new CodeStyleSettings.PackageTable.Entry(((String)aValue).trim(), packageEntry.isWithSubpackages());
441           myPackageList.setEntryAt(newPackageEntry, row);
442         }
443
444         if(col == 1) {
445           CodeStyleSettings.PackageTable.Entry newPackageEntry = new CodeStyleSettings.PackageTable.Entry(packageEntry.getPackageName(), ((Boolean)aValue).booleanValue());
446           myPackageList.setEntryAt(newPackageEntry, row);
447         }
448       }
449     };
450
451     // Create the table
452     myPackageTable = new Table(dataModel);
453     myPackageTable.getSelectionModel().setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
454     TableCellEditor editor = myPackageTable.getDefaultEditor(String.class);
455     myPackageTable.fixColumnWidthToHeader(1);
456     if (editor instanceof DefaultCellEditor) {
457       ((DefaultCellEditor)editor).setClickCountToStart(1);
458     }
459     myPackageTable.getSelectionModel().addListSelectionListener(
460       new ListSelectionListener(){
461         public void valueChanged(ListSelectionEvent e){
462           updateButtons();
463         }
464       }
465     );
466
467     return ScrollPaneFactory.createScrollPane(myPackageTable);
468   }
469
470   private void updateButtons(){
471     int selectedImport = myImportLayoutTable.getSelectedRow();
472     myMoveUpButton.setEnabled(selectedImport >= 1);
473     myMoveDownButton.setEnabled(selectedImport < myImportLayoutTable.getRowCount()-1);
474     if(selectedImport < 0 || myOtherPackageEntry == myImportLayoutList.getEntryAt(selectedImport)) {
475       myRemovePackageFromImportLayoutButton.setEnabled(false);
476     }
477     else {
478       myRemovePackageFromImportLayoutButton.setEnabled(true);
479     }
480
481     int selectedPackage = myPackageTable.getSelectedRow();
482     myRemovePackageFromPackagesButton.setEnabled(selectedPackage >= 0);
483
484   }
485
486   private static boolean isOtherEntry(CodeStyleSettings.ImportLayoutTable.Entry entry) {
487     if(!(entry instanceof CodeStyleSettings.ImportLayoutTable.PackageEntry)) {
488       return false;
489     }
490     CodeStyleSettings.ImportLayoutTable.PackageEntry packageEntry = (CodeStyleSettings.ImportLayoutTable.PackageEntry)entry;
491     String packageName = packageEntry.getPackageName();
492     return packageName.length() == 0 && packageEntry.isWithSubpackages();
493   }
494
495   private JComponent createImportLayoutTable() {
496     final String[] names = {
497       ApplicationBundle.message("listbox.import.package"),
498       ApplicationBundle.message("listbox.import.with.subpackages")
499     };
500     // Create a model of the data.
501     TableModel dataModel = new AbstractTableModel() {
502       public int getColumnCount() { return names.length; }
503       public int getRowCount() { return myImportLayoutList.getEntryCount();}
504       public Object getValueAt(int row, int col) {
505         CodeStyleSettings.ImportLayoutTable.Entry entry = myImportLayoutList.getEntryAt(row);
506         if(col == 0) {
507           if(isOtherEntry(entry) && entry == myOtherPackageEntry) {
508             return ApplicationBundle.message("listbox.import.all.other.imports");
509           }
510           else if(entry instanceof CodeStyleSettings.ImportLayoutTable.PackageEntry) {
511             CodeStyleSettings.ImportLayoutTable.PackageEntry packageEntry = (CodeStyleSettings.ImportLayoutTable.PackageEntry)entry;
512             return packageEntry.getPackageName();
513           }
514           else {
515             return ApplicationBundle.message("listbox.import.blank.line");
516           }
517         }
518
519         if(col == 1) {
520           if(isOtherEntry(entry) && entry == myOtherPackageEntry) {
521             return null;
522           }
523           else if(entry instanceof CodeStyleSettings.ImportLayoutTable.PackageEntry) {
524             CodeStyleSettings.ImportLayoutTable.PackageEntry packageEntry = (CodeStyleSettings.ImportLayoutTable.PackageEntry)entry;
525             return packageEntry.isWithSubpackages() ? Boolean.TRUE : Boolean.FALSE;
526           }
527           else {
528             return null;
529           }
530         }
531         return null;
532       }
533       public String getColumnName(int column) { return names[column]; }
534       public Class getColumnClass(int c) {
535         if(c == 0) {
536           return String.class;
537         }
538         if(c == 1) {
539           return Boolean.class;
540         }
541         return null;
542 //        return CodeStyleSettings.ImportLayoutTable.Entry.class;
543       }
544       public boolean isCellEditable(int row, int col) {
545         CodeStyleSettings.ImportLayoutTable.Entry entry = myImportLayoutList.getEntryAt(row);
546         if (isOtherEntry(entry) && entry == myOtherPackageEntry) {
547           return false;
548         }
549         return entry instanceof CodeStyleSettings.ImportLayoutTable.PackageEntry;
550       }
551
552       public void setValueAt(Object aValue, int row, int col) {
553         CodeStyleSettings.ImportLayoutTable.Entry entry = myImportLayoutList.getEntryAt(row);
554         if(col == 0 && entry instanceof CodeStyleSettings.ImportLayoutTable.PackageEntry) {
555           CodeStyleSettings.ImportLayoutTable.PackageEntry packageEntry = (CodeStyleSettings.ImportLayoutTable.PackageEntry)entry;
556           CodeStyleSettings.ImportLayoutTable.PackageEntry newPackageEntry = new CodeStyleSettings.ImportLayoutTable.PackageEntry(((String)aValue).trim(), packageEntry.isWithSubpackages());
557           myImportLayoutList.setEntryAt(newPackageEntry, row);
558         }
559         if(col == 1 && entry instanceof CodeStyleSettings.ImportLayoutTable.PackageEntry) {
560           CodeStyleSettings.ImportLayoutTable.PackageEntry packageEntry = (CodeStyleSettings.ImportLayoutTable.PackageEntry)entry;
561           CodeStyleSettings.ImportLayoutTable.PackageEntry newPackageEntry = new CodeStyleSettings.ImportLayoutTable.PackageEntry(packageEntry.getPackageName(), aValue.equals(Boolean.TRUE));
562           myImportLayoutList.setEntryAt(newPackageEntry, row);
563         }
564       }
565     };
566
567     // Create the table
568     myImportLayoutTable = new Table(dataModel);
569     myImportLayoutTable.setDefaultRenderer(Boolean.class, new BooleanTableCellRenderer());
570     myImportLayoutTable.fixColumnWidthToHeader(1);
571     myImportLayoutTable.getSelectionModel().setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
572     TableCellEditor editor = myImportLayoutTable.getDefaultEditor(String.class);
573     if (editor instanceof DefaultCellEditor) {
574       ((DefaultCellEditor)editor).setClickCountToStart(1);
575     }
576
577     myImportLayoutTable.getSelectionModel().addListSelectionListener(
578       new ListSelectionListener(){
579         public void valueChanged(ListSelectionEvent e){
580           updateButtons();
581         }
582       }
583     );
584
585     return ScrollPaneFactory.createScrollPane(myImportLayoutTable);
586   }
587
588   public void reset() {
589     myCbUseFQClassNames.setSelected(mySettings.USE_FQ_CLASS_NAMES);
590     myCbUseFQClassNamesInJavaDoc.setSelected(mySettings.USE_FQ_CLASS_NAMES_IN_JAVADOC);
591     myCbUseSingleClassImports.setSelected(mySettings.USE_SINGLE_CLASS_IMPORTS);
592     myCbInsertInnerClassImports.setSelected(mySettings.INSERT_INNER_CLASS_IMPORTS);
593     myClassCountField.setText(Integer.toString(mySettings.CLASS_COUNT_TO_USE_IMPORT_ON_DEMAND));
594     myNamesCountField.setText(Integer.toString(mySettings.NAMES_COUNT_TO_USE_IMPORT_ON_DEMAND));
595     myCbAddUnambiguousImportsOnTheFly.setSelected(mySettings.ADD_UNAMBIGIOUS_IMPORTS_ON_THE_FLY);
596     myCbOptimizeImportsOnTheFly.setSelected(mySettings.OPTIMIZE_IMPORTS_ON_THE_FLY);
597
598     myImportLayoutList.copyFrom(mySettings.IMPORT_LAYOUT_TABLE);
599     CodeStyleSettings.ImportLayoutTable.Entry[] entries = myImportLayoutList.getEntries();
600     for (CodeStyleSettings.ImportLayoutTable.Entry entry : entries) {
601       if (isOtherEntry(entry)) {
602         myOtherPackageEntry = (CodeStyleSettings.ImportLayoutTable.PackageEntry)entry;
603       }
604     }
605     myPackageList = new CodeStyleSettings.PackageTable();
606     myPackageList.copyFrom(mySettings.PACKAGES_TO_USE_IMPORT_ON_DEMAND);
607
608     AbstractTableModel model = (AbstractTableModel)myImportLayoutTable.getModel();
609     model.fireTableDataChanged();
610
611     model = (AbstractTableModel)myPackageTable.getModel();
612     model.fireTableDataChanged();
613
614     if(myImportLayoutTable.getRowCount() > 0) {
615       myImportLayoutTable.getSelectionModel().setSelectionInterval(0, 0);
616     }
617     if(myPackageTable.getRowCount() > 0) {
618       myPackageTable.getSelectionModel().setSelectionInterval(0, 0);
619     }
620
621     if (mySettings.JSP_PREFER_COMMA_SEPARATED_IMPORT_LIST) {
622       myJspImportCommaSeparated.doClick();
623     }
624     else {
625       myJspOneImportPerDirective.doClick();
626     }
627     updateButtons();
628   }
629
630   public void apply() {
631     stopTableEditing();
632
633     mySettings.USE_FQ_CLASS_NAMES = myCbUseFQClassNames.isSelected();
634     mySettings.USE_FQ_CLASS_NAMES_IN_JAVADOC = myCbUseFQClassNamesInJavaDoc.isSelected();
635     mySettings.USE_SINGLE_CLASS_IMPORTS = myCbUseSingleClassImports.isSelected();
636     mySettings.INSERT_INNER_CLASS_IMPORTS = myCbInsertInnerClassImports.isSelected();
637     mySettings.OPTIMIZE_IMPORTS_ON_THE_FLY = myCbOptimizeImportsOnTheFly.isSelected();
638     mySettings.ADD_UNAMBIGIOUS_IMPORTS_ON_THE_FLY = myCbAddUnambiguousImportsOnTheFly.isSelected();
639     try{
640       mySettings.CLASS_COUNT_TO_USE_IMPORT_ON_DEMAND = Integer.parseInt(myClassCountField.getText());
641     }
642     catch(NumberFormatException e){
643       //just a bad number
644     }
645     try{
646       mySettings.NAMES_COUNT_TO_USE_IMPORT_ON_DEMAND = Integer.parseInt(myNamesCountField.getText());
647     }
648     catch(NumberFormatException e){
649       //just a bad number
650     }
651
652     mySettings.IMPORT_LAYOUT_TABLE.copyFrom(myImportLayoutList);
653
654     CodeStyleSettings.ImportLayoutTable.Entry[] entries = myImportLayoutList.getEntries();
655     int removedEntryCount = 0;
656     for(int i = 0; i < entries.length; i++){
657       CodeStyleSettings.ImportLayoutTable.Entry entry = entries[i];
658       if(isOtherEntry(entry) && entry != myOtherPackageEntry) {
659         mySettings.IMPORT_LAYOUT_TABLE.removeEntryAt(i-removedEntryCount);
660         removedEntryCount++;
661       }
662     }
663
664     mySettings.PACKAGES_TO_USE_IMPORT_ON_DEMAND = myPackageList;
665
666     mySettings.JSP_PREFER_COMMA_SEPARATED_IMPORT_LIST = myJspImportCommaSeparated.isSelected();
667   }
668
669   private void stopTableEditing() {
670     if(myImportLayoutTable.isEditing()) {
671       TableCellEditor editor = myImportLayoutTable.getCellEditor();
672       if (editor != null) {
673         editor.stopCellEditing();
674       }
675     }
676     if(myPackageTable.isEditing()) {
677       TableCellEditor editor = myPackageTable.getCellEditor();
678       if (editor != null) {
679         editor.stopCellEditing();
680       }
681     }
682   }
683
684   public boolean isModified() {
685
686     boolean isModified = isModified(myCbUseFQClassNames, mySettings.USE_FQ_CLASS_NAMES);
687     isModified |= isModified(myCbUseFQClassNamesInJavaDoc, mySettings.USE_FQ_CLASS_NAMES_IN_JAVADOC);
688     isModified |= isModified(myCbUseSingleClassImports, mySettings.USE_SINGLE_CLASS_IMPORTS);
689     isModified |= isModified(myCbInsertInnerClassImports, mySettings.INSERT_INNER_CLASS_IMPORTS);
690     isModified |= isModified(myCbOptimizeImportsOnTheFly, mySettings.OPTIMIZE_IMPORTS_ON_THE_FLY);
691     isModified |= isModified(myCbAddUnambiguousImportsOnTheFly, mySettings.ADD_UNAMBIGIOUS_IMPORTS_ON_THE_FLY);
692     isModified |= isModified(myClassCountField, mySettings.CLASS_COUNT_TO_USE_IMPORT_ON_DEMAND);
693     isModified |= isModified(myNamesCountField, mySettings.NAMES_COUNT_TO_USE_IMPORT_ON_DEMAND);
694
695     isModified |= isModified(myImportLayoutList, mySettings.IMPORT_LAYOUT_TABLE);
696     isModified |= isModified(myPackageList, mySettings.PACKAGES_TO_USE_IMPORT_ON_DEMAND);
697     isModified |= mySettings.JSP_PREFER_COMMA_SEPARATED_IMPORT_LIST != myJspImportCommaSeparated.isSelected();
698
699     return isModified;
700   }
701
702   private static boolean isModified(JTextField textField, int value) {
703     try {
704       int fieldValue = Integer.parseInt(textField.getText().trim());
705       return fieldValue != value;
706     }
707     catch(NumberFormatException e) {
708       return false;
709     }
710   }
711
712   private static boolean isModified(JCheckBox checkBox, boolean value) {
713     return checkBox.isSelected() != value;
714   }
715
716   private static boolean isModified(CodeStyleSettings.ImportLayoutTable list, CodeStyleSettings.ImportLayoutTable table) {
717     if(list.getEntryCount() != table.getEntryCount()) {
718       return true;
719     }
720
721     for(int i=0; i<list.getEntryCount(); i++) {
722       CodeStyleSettings.ImportLayoutTable.Entry entry1 = list.getEntryAt(i);
723       CodeStyleSettings.ImportLayoutTable.Entry entry2 = table.getEntryAt(i);
724       if(!entry1.equals(entry2)) {
725         return true;
726       }
727     }
728
729     return false;
730   }
731
732   private static boolean isModified(CodeStyleSettings.PackageTable list, CodeStyleSettings.PackageTable table) {
733     if(list.getEntryCount() != table.getEntryCount()) {
734       return true;
735     }
736
737     for(int i=0; i<list.getEntryCount(); i++) {
738       CodeStyleSettings.PackageTable.Entry entry1 = list.getEntryAt(i);
739       CodeStyleSettings.PackageTable.Entry entry2 = table.getEntryAt(i);
740       if(!entry1.equals(entry2)) {
741         return true;
742       }
743     }
744
745     return false;
746   }
747 }