IDEADEV-8718

This commit is contained in:
Alexey Kudravtsev
2009-10-23 10:49:48 +04:00
parent fa4527f21c
commit e70f10ded2
13 changed files with 734 additions and 779 deletions
@@ -16,21 +16,24 @@
package com.intellij.application.options;
import com.intellij.openapi.application.ApplicationBundle;
import com.intellij.openapi.editor.SyntaxHighlighterColors;
import com.intellij.openapi.editor.markup.TextAttributes;
import com.intellij.openapi.ui.VerticalFlowLayout;
import com.intellij.openapi.ui.ex.MultiLineLabel;
import com.intellij.psi.codeStyle.CodeStyleSettings;
import com.intellij.psi.codeStyle.PackageEntry;
import com.intellij.psi.codeStyle.PackageEntryTable;
import com.intellij.ui.*;
import com.intellij.util.ui.Table;
import javax.swing.*;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.TableCellEditor;
import javax.swing.table.TableModel;
import javax.swing.event.*;
import javax.swing.table.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
public class CodeStyleImportsPanel extends JPanel {
private JCheckBox myCbUseFQClassNames;
@@ -41,9 +44,8 @@ public class CodeStyleImportsPanel extends JPanel {
private JCheckBox myCbAddUnambiguousImportsOnTheFly;
private JTextField myClassCountField;
private JTextField myNamesCountField;
private final CodeStyleSettings.ImportLayoutTable myImportLayoutList = new CodeStyleSettings.ImportLayoutTable();
private CodeStyleSettings.PackageTable myPackageList = new CodeStyleSettings.PackageTable();
private CodeStyleSettings.ImportLayoutTable.PackageEntry myOtherPackageEntry = null;
private final PackageEntryTable myImportLayoutList = new PackageEntryTable();
private final PackageEntryTable myPackageList = new PackageEntryTable();
private Table myImportLayoutTable;
private JButton myMoveUpButton;
@@ -60,6 +62,7 @@ public class CodeStyleImportsPanel extends JPanel {
private JPanel myPackagesPanel;
private JPanel myImportsLayoutPanel;
private JPanel myWholePanel;
private JCheckBox myCbLayoutStaticImportsSeparately;
public CodeStyleImportsPanel(CodeStyleSettings settings){
mySettings = settings;
@@ -69,8 +72,8 @@ public class CodeStyleImportsPanel extends JPanel {
myGeneralPanel.add(createGeneralOptionsPanel(), BorderLayout.CENTER);
myJSPPanel.add(createJspImportLayoutPanel(), BorderLayout.CENTER);
myPackagesPanel.add(createPackagesPanel(), BorderLayout.NORTH);
myImportsLayoutPanel.add(createImportLayoutPanel(), BorderLayout.NORTH);
myPackagesPanel.add(createPackagesPanel(), BorderLayout.NORTH);
}
private JPanel createJspImportLayoutPanel() {
@@ -157,12 +160,57 @@ public class CodeStyleImportsPanel extends JPanel {
private JPanel createImportLayoutPanel() {
JPanel panel = new JPanel(new BorderLayout());
panel.setBorder(IdeBorderFactory.createTitledBorder(ApplicationBundle.message("title.import.layout")));
myCbLayoutStaticImportsSeparately = new JCheckBox("Layout static imports separately");
myCbLayoutStaticImportsSeparately.addItemListener(new ItemListener(){
public void itemStateChanged(ItemEvent e) {
if (areStaticImportsEnabled()) {
boolean found = false;
for (int i=myImportLayoutList.getEntryCount()-1; i>=0; i--) {
PackageEntry entry = myImportLayoutList.getEntryAt(i);
if (entry == PackageEntry.ALL_OTHER_STATIC_IMPORTS_ENTRY) {
found = true;
break;
}
}
if (!found) {
int index = myImportLayoutList.getEntryCount();
if (index != 0 && myImportLayoutList.getEntryAt(index-1) != PackageEntry.BLANK_LINE_ENTRY) {
myImportLayoutList.addEntry(PackageEntry.BLANK_LINE_ENTRY);
}
myImportLayoutList.addEntry(PackageEntry.ALL_OTHER_STATIC_IMPORTS_ENTRY);
}
}
else {
for (int i=myImportLayoutList.getEntryCount()-1; i>=0; i--) {
PackageEntry entry = myImportLayoutList.getEntryAt(i);
if (entry.isStatic()) {
myImportLayoutList.removeEntryAt(i);
}
}
}
refreshTable(myImportLayoutTable, myImportLayoutList);
refreshTable(myPackageTable, myPackageList);
}
});
panel.add(myCbLayoutStaticImportsSeparately, BorderLayout.NORTH);
panel.add(createImportLayoutTable(), BorderLayout.CENTER);
panel.add(createImportLayoutButtonsPanel(), BorderLayout.EAST);
panel.setPreferredSize(new Dimension(-1, 200));
return panel;
}
private void refreshTable(final Table table, final PackageEntryTable packageTable) {
AbstractTableModel model = (AbstractTableModel)table.getModel();
table.createDefaultColumnsFromModel();
model.fireTableDataChanged();
resizeColumns(packageTable, table);
}
private boolean areStaticImportsEnabled() {
return myCbLayoutStaticImportsSeparately.isSelected();
}
private JPanel createImportLayoutButtonsPanel() {
JPanel tableButtonsPanel = new JPanel(new VerticalFlowLayout());
@@ -258,7 +306,7 @@ public class CodeStyleImportsPanel extends JPanel {
if(selected < 0) {
selected = myImportLayoutList.getEntryCount();
}
CodeStyleSettings.ImportLayoutTable.PackageEntry entry = new CodeStyleSettings.ImportLayoutTable.PackageEntry("", true);
PackageEntry entry = new PackageEntry(false,"", true);
myImportLayoutList.insertEntryAt(entry, selected);
refreshTableModel(selected, myImportLayoutTable);
}
@@ -267,8 +315,6 @@ public class CodeStyleImportsPanel extends JPanel {
AbstractTableModel model = (AbstractTableModel)table.getModel();
model.fireTableRowsInserted(selectedRow, selectedRow);
table.setRowSelectionInterval(selectedRow, selectedRow);
// myImportLayoutTable.requestFocus();
// myImportLayoutTable.editCellAt(selected, 0);
TableUtil.editCellAt(table, selectedRow, 0);
Component editorComp = table.getEditorComponent();
if(editorComp != null) {
@@ -281,7 +327,7 @@ public class CodeStyleImportsPanel extends JPanel {
if(selected < 0) {
selected = myPackageList.getEntryCount();
}
CodeStyleSettings.PackageTable.Entry entry = new CodeStyleSettings.PackageTable.Entry("", true);
PackageEntry entry = new PackageEntry(false,"", true);
myPackageList.insertEntryAt(entry, selected);
refreshTableModel(selected, myPackageTable);
}
@@ -291,8 +337,7 @@ public class CodeStyleImportsPanel extends JPanel {
if(selected < 0) {
selected = myImportLayoutList.getEntryCount();
}
CodeStyleSettings.ImportLayoutTable.EmptyLineEntry entry = new CodeStyleSettings.ImportLayoutTable.EmptyLineEntry();
myImportLayoutList.insertEntryAt(entry, selected);
myImportLayoutList.insertEntryAt(PackageEntry.BLANK_LINE_ENTRY, selected);
AbstractTableModel model = (AbstractTableModel)myImportLayoutTable.getModel();
model.fireTableRowsInserted(selected, selected);
myImportLayoutTable.setRowSelectionInterval(selected, selected);
@@ -302,26 +347,11 @@ public class CodeStyleImportsPanel extends JPanel {
int selected = myImportLayoutTable.getSelectedRow();
if(selected < 0)
return;
CodeStyleSettings.ImportLayoutTable.Entry entry = myImportLayoutList.getEntryAt(selected);
if(isOtherEntry(entry)) {
boolean isFound = false;
CodeStyleSettings.ImportLayoutTable.Entry[] entries = myImportLayoutList.getEntries();
for(int i = 0; i < entries.length; i++){
if(i != selected && isOtherEntry(entries[i])) {
isFound = true;
break;
}
}
if(!isFound) {
return;
}
}
if(myImportLayoutTable.isEditing()) {
TableCellEditor editor = myImportLayoutTable.getCellEditor();
if (editor != null) {
editor.stopCellEditing();
}
PackageEntry entry = myImportLayoutList.getEntryAt(selected);
if(entry == PackageEntry.ALL_OTHER_STATIC_IMPORTS_ENTRY || entry == PackageEntry.ALL_OTHER_IMPORTS_ENTRY) {
return;
}
TableUtil.stopEditing(myImportLayoutTable);
myImportLayoutList.removeEntryAt(selected);
AbstractTableModel model = (AbstractTableModel)myImportLayoutTable.getModel();
model.fireTableRowsDeleted(selected, selected);
@@ -335,14 +365,8 @@ public class CodeStyleImportsPanel extends JPanel {
private void removeEntryFromPackages() {
int selected = myPackageTable.getSelectedRow();
if(selected < 0)
return;
if(myPackageTable.isEditing()) {
TableCellEditor editor = myPackageTable.getCellEditor();
if (editor != null) {
editor.stopCellEditing();
}
}
if(selected < 0) return;
TableUtil.stopEditing(myPackageTable);
myPackageList.removeEntryAt(selected);
AbstractTableModel model = (AbstractTableModel)myPackageTable.getModel();
model.fireTableRowsDeleted(selected, selected);
@@ -359,14 +383,9 @@ public class CodeStyleImportsPanel extends JPanel {
if(selected < 1) {
return;
}
if(myImportLayoutTable.isEditing()) {
TableCellEditor editor = myImportLayoutTable.getCellEditor();
if (editor != null) {
editor.stopCellEditing();
}
}
CodeStyleSettings.ImportLayoutTable.Entry entry = myImportLayoutList.getEntryAt(selected);
CodeStyleSettings.ImportLayoutTable.Entry previousEntry = myImportLayoutList.getEntryAt(selected-1);
TableUtil.stopEditing(myImportLayoutTable);
PackageEntry entry = myImportLayoutList.getEntryAt(selected);
PackageEntry previousEntry = myImportLayoutList.getEntryAt(selected-1);
myImportLayoutList.setEntryAt(previousEntry, selected);
myImportLayoutList.setEntryAt(entry, selected-1);
@@ -380,14 +399,9 @@ public class CodeStyleImportsPanel extends JPanel {
if(selected >= myImportLayoutList.getEntryCount()-1) {
return;
}
if(myImportLayoutTable.isEditing()) {
TableCellEditor editor = myImportLayoutTable.getCellEditor();
if (editor != null) {
editor.stopCellEditing();
}
}
CodeStyleSettings.ImportLayoutTable.Entry entry = myImportLayoutList.getEntryAt(selected);
CodeStyleSettings.ImportLayoutTable.Entry nextEntry = myImportLayoutList.getEntryAt(selected+1);
TableUtil.stopEditing(myImportLayoutTable);
PackageEntry entry = myImportLayoutList.getEntryAt(selected);
PackageEntry nextEntry = myImportLayoutList.getEntryAt(selected+1);
myImportLayoutList.setEntryAt(nextEntry, selected);
myImportLayoutList.setEntryAt(entry, selected+1);
@@ -397,66 +411,110 @@ public class CodeStyleImportsPanel extends JPanel {
}
private JComponent createPackagesTable() {
myPackageTable = createTableForPackageEntries(myPackageList);
return ScrollPaneFactory.createScrollPane(myPackageTable);
}
private Table createTableForPackageEntries(final PackageEntryTable packageTable) {
final String[] names = {
ApplicationBundle.message("listbox.import.package"),
ApplicationBundle.message("listbox.import.with.subpackages")
ApplicationBundle.message("listbox.import.with.subpackages"),
};
// Create a model of the data.
TableModel dataModel = new AbstractTableModel() {
public int getColumnCount() { return names.length; }
public int getRowCount() { return myPackageList.getEntryCount();}
public Object getValueAt(int row, int col) {
CodeStyleSettings.PackageTable.Entry entry = myPackageList.getEntryAt(row);
if(col == 0) {
if(entry != null) {
return entry.getPackageName();
}
}
if(col == 1) {
if(entry != null) {
return entry.isWithSubpackages() ? Boolean.TRUE : Boolean.FALSE;
}
}
return null;
public int getColumnCount() {
return names.length + (areStaticImportsEnabled()?1:0);
}
public String getColumnName(int column) { return names[column]; }
public Class getColumnClass(int c) {
if(c == 0) {
return String.class;
public int getRowCount() {
return packageTable.getEntryCount();
}
public Object getValueAt(int row, int col) {
PackageEntry entry = packageTable.getEntryAt(row);
if (entry == null || !isCellEditable(row, col)) return null;
col += areStaticImportsEnabled() ? 0 : 1;
if(col == 0) {
return entry.isStatic();
}
if(c == 1) {
if(col == 1) {
return entry.getPackageName();
}
if(col == 2) {
return entry.isWithSubpackages() ? Boolean.TRUE : Boolean.FALSE;
}
throw new IllegalArgumentException(String.valueOf(col));
}
public String getColumnName(int column) {
if (areStaticImportsEnabled() && column == 0) return "Static";
column -= areStaticImportsEnabled() ? 1 : 0;
return names[column];
}
public Class getColumnClass(int col) {
col += areStaticImportsEnabled() ? 0 : 1;
if(col == 0) {
return Boolean.class;
}
return null;
if(col == 1) {
return String.class;
}
if(col == 2) {
return Boolean.class;
}
throw new IllegalArgumentException(String.valueOf(col));
}
public boolean isCellEditable(int row, int col) {
return true;
PackageEntry packageEntry = packageTable.getEntryAt(row);
return !packageEntry.isSpecial();
}
public void setValueAt(Object aValue, int row, int col) {
CodeStyleSettings.PackageTable.Entry packageEntry = myPackageList.getEntryAt(row);
PackageEntry packageEntry = packageTable.getEntryAt(row);
col += areStaticImportsEnabled() ? 0 : 1;
if(col == 0) {
CodeStyleSettings.PackageTable.Entry newPackageEntry = new CodeStyleSettings.PackageTable.Entry(((String)aValue).trim(), packageEntry.isWithSubpackages());
myPackageList.setEntryAt(newPackageEntry, row);
PackageEntry newPackageEntry = new PackageEntry((Boolean)aValue, packageEntry.getPackageName(), packageEntry.isWithSubpackages());
packageTable.setEntryAt(newPackageEntry, row);
}
if(col == 1) {
CodeStyleSettings.PackageTable.Entry newPackageEntry = new CodeStyleSettings.PackageTable.Entry(packageEntry.getPackageName(), ((Boolean)aValue).booleanValue());
myPackageList.setEntryAt(newPackageEntry, row);
else if(col == 1) {
PackageEntry newPackageEntry = new PackageEntry(packageEntry.isStatic(), ((String)aValue).trim(), packageEntry.isWithSubpackages());
packageTable.setEntryAt(newPackageEntry, row);
}
else if(col == 2) {
PackageEntry newPackageEntry = new PackageEntry(packageEntry.isStatic(), packageEntry.getPackageName(), ((Boolean)aValue).booleanValue());
packageTable.setEntryAt(newPackageEntry, row);
}
else {
throw new IllegalArgumentException(String.valueOf(col));
}
}
};
// Create the table
myPackageTable = new Table(dataModel);
myPackageTable.getSelectionModel().setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
TableCellEditor editor = myPackageTable.getDefaultEditor(String.class);
myPackageTable.fixColumnWidthToHeader(1);
final Table result = new Table(dataModel);
result.getSelectionModel().setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
resizeColumns(packageTable, result);
TableCellEditor editor = result.getDefaultEditor(String.class);
if (editor instanceof DefaultCellEditor) {
((DefaultCellEditor)editor).setClickCountToStart(1);
}
myPackageTable.getSelectionModel().addListSelectionListener(
TableCellEditor beditor = result.getDefaultEditor(Boolean.class);
beditor.addCellEditorListener(new CellEditorListener() {
public void editingStopped(ChangeEvent e) {
if (areStaticImportsEnabled()) {
result.repaint(); // add/remove static keyword
}
}
public void editingCanceled(ChangeEvent e) {
}
});
result.getSelectionModel().addListSelectionListener(
new ListSelectionListener(){
public void valueChanged(ListSelectionEvent e){
updateButtons();
@@ -464,124 +522,64 @@ public class CodeStyleImportsPanel extends JPanel {
}
);
return ScrollPaneFactory.createScrollPane(myPackageTable);
return result;
}
private void resizeColumns(final PackageEntryTable packageTable, Table result) {
ColoredTableCellRenderer packageRenderer = new ColoredTableCellRenderer() {
@Override
protected void customizeCellRenderer(JTable table, Object value, boolean selected, boolean hasFocus, int row, int column) {
PackageEntry entry = packageTable.getEntryAt(row);
if (entry == PackageEntry.BLANK_LINE_ENTRY) {
append(" <blank line>", SimpleTextAttributes.LINK_ATTRIBUTES);
}
else {
TextAttributes attributes = SyntaxHighlighterColors.KEYWORD.getDefaultAttributes();
append("import", SimpleTextAttributes.fromTextAttributes(attributes));
if (entry.isStatic()) {
append(" ", SimpleTextAttributes.REGULAR_ATTRIBUTES);
append("static", SimpleTextAttributes.fromTextAttributes(attributes));
}
append(" ", SimpleTextAttributes.REGULAR_ATTRIBUTES);
if (entry == PackageEntry.ALL_OTHER_IMPORTS_ENTRY || entry == PackageEntry.ALL_OTHER_STATIC_IMPORTS_ENTRY) {
append("all other imports", SimpleTextAttributes.REGULAR_ATTRIBUTES);
}
else {
append(entry.getPackageName() + ".*", SimpleTextAttributes.REGULAR_ATTRIBUTES);
}
}
}
};
if (areStaticImportsEnabled()) {
result.fixColumnWidthToHeader(0);
result.fixColumnWidthToHeader(2);
result.getColumnModel().getColumn(1).setCellRenderer(packageRenderer);
result.getColumnModel().getColumn(0).setCellRenderer(new BooleanTableCellRenderer());
result.getColumnModel().getColumn(2).setCellRenderer(new BooleanTableCellRenderer());
}
else {
result.fixColumnWidthToHeader(1);
result.getColumnModel().getColumn(0).setCellRenderer(packageRenderer);
result.getColumnModel().getColumn(1).setCellRenderer(new BooleanTableCellRenderer());
}
}
private void updateButtons(){
int selectedImport = myImportLayoutTable.getSelectedRow();
myMoveUpButton.setEnabled(selectedImport >= 1);
myMoveDownButton.setEnabled(selectedImport < myImportLayoutTable.getRowCount()-1);
if(selectedImport < 0 || myOtherPackageEntry == myImportLayoutList.getEntryAt(selectedImport)) {
myRemovePackageFromImportLayoutButton.setEnabled(false);
}
else {
myRemovePackageFromImportLayoutButton.setEnabled(true);
}
PackageEntry entry = selectedImport < 0 ? null : myImportLayoutList.getEntryAt(selectedImport);
boolean canRemove = entry != null && entry != PackageEntry.ALL_OTHER_STATIC_IMPORTS_ENTRY && entry != PackageEntry.ALL_OTHER_IMPORTS_ENTRY;
myRemovePackageFromImportLayoutButton.setEnabled(canRemove);
int selectedPackage = myPackageTable.getSelectedRow();
myRemovePackageFromPackagesButton.setEnabled(selectedPackage >= 0);
}
private static boolean isOtherEntry(CodeStyleSettings.ImportLayoutTable.Entry entry) {
if(!(entry instanceof CodeStyleSettings.ImportLayoutTable.PackageEntry)) {
return false;
}
CodeStyleSettings.ImportLayoutTable.PackageEntry packageEntry = (CodeStyleSettings.ImportLayoutTable.PackageEntry)entry;
String packageName = packageEntry.getPackageName();
return packageName.length() == 0 && packageEntry.isWithSubpackages();
}
private JComponent createImportLayoutTable() {
final String[] names = {
ApplicationBundle.message("listbox.import.package"),
ApplicationBundle.message("listbox.import.with.subpackages")
};
// Create a model of the data.
TableModel dataModel = new AbstractTableModel() {
public int getColumnCount() { return names.length; }
public int getRowCount() { return myImportLayoutList.getEntryCount();}
public Object getValueAt(int row, int col) {
CodeStyleSettings.ImportLayoutTable.Entry entry = myImportLayoutList.getEntryAt(row);
if(col == 0) {
if(isOtherEntry(entry) && entry == myOtherPackageEntry) {
return ApplicationBundle.message("listbox.import.all.other.imports");
}
else if(entry instanceof CodeStyleSettings.ImportLayoutTable.PackageEntry) {
CodeStyleSettings.ImportLayoutTable.PackageEntry packageEntry = (CodeStyleSettings.ImportLayoutTable.PackageEntry)entry;
return packageEntry.getPackageName();
}
else {
return ApplicationBundle.message("listbox.import.blank.line");
}
}
if(col == 1) {
if(isOtherEntry(entry) && entry == myOtherPackageEntry) {
return null;
}
else if(entry instanceof CodeStyleSettings.ImportLayoutTable.PackageEntry) {
CodeStyleSettings.ImportLayoutTable.PackageEntry packageEntry = (CodeStyleSettings.ImportLayoutTable.PackageEntry)entry;
return packageEntry.isWithSubpackages() ? Boolean.TRUE : Boolean.FALSE;
}
else {
return null;
}
}
return null;
}
public String getColumnName(int column) { return names[column]; }
public Class getColumnClass(int c) {
if(c == 0) {
return String.class;
}
if(c == 1) {
return Boolean.class;
}
return null;
// return CodeStyleSettings.ImportLayoutTable.Entry.class;
}
public boolean isCellEditable(int row, int col) {
CodeStyleSettings.ImportLayoutTable.Entry entry = myImportLayoutList.getEntryAt(row);
if (isOtherEntry(entry) && entry == myOtherPackageEntry) {
return false;
}
return entry instanceof CodeStyleSettings.ImportLayoutTable.PackageEntry;
}
public void setValueAt(Object aValue, int row, int col) {
CodeStyleSettings.ImportLayoutTable.Entry entry = myImportLayoutList.getEntryAt(row);
if(col == 0 && entry instanceof CodeStyleSettings.ImportLayoutTable.PackageEntry) {
CodeStyleSettings.ImportLayoutTable.PackageEntry packageEntry = (CodeStyleSettings.ImportLayoutTable.PackageEntry)entry;
CodeStyleSettings.ImportLayoutTable.PackageEntry newPackageEntry = new CodeStyleSettings.ImportLayoutTable.PackageEntry(((String)aValue).trim(), packageEntry.isWithSubpackages());
myImportLayoutList.setEntryAt(newPackageEntry, row);
}
if(col == 1 && entry instanceof CodeStyleSettings.ImportLayoutTable.PackageEntry) {
CodeStyleSettings.ImportLayoutTable.PackageEntry packageEntry = (CodeStyleSettings.ImportLayoutTable.PackageEntry)entry;
CodeStyleSettings.ImportLayoutTable.PackageEntry newPackageEntry = new CodeStyleSettings.ImportLayoutTable.PackageEntry(packageEntry.getPackageName(), aValue.equals(Boolean.TRUE));
myImportLayoutList.setEntryAt(newPackageEntry, row);
}
}
};
// Create the table
myImportLayoutTable = new Table(dataModel);
myImportLayoutTable.setDefaultRenderer(Boolean.class, new BooleanTableCellRenderer());
myImportLayoutTable.fixColumnWidthToHeader(1);
myImportLayoutTable.getSelectionModel().setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
TableCellEditor editor = myImportLayoutTable.getDefaultEditor(String.class);
if (editor instanceof DefaultCellEditor) {
((DefaultCellEditor)editor).setClickCountToStart(1);
}
myImportLayoutTable.getSelectionModel().addListSelectionListener(
new ListSelectionListener(){
public void valueChanged(ListSelectionEvent e){
updateButtons();
}
}
);
myImportLayoutTable = createTableForPackageEntries(myImportLayoutList);
return ScrollPaneFactory.createScrollPane(myImportLayoutTable);
}
@@ -596,14 +594,9 @@ public class CodeStyleImportsPanel extends JPanel {
myCbOptimizeImportsOnTheFly.setSelected(mySettings.OPTIMIZE_IMPORTS_ON_THE_FLY);
myImportLayoutList.copyFrom(mySettings.IMPORT_LAYOUT_TABLE);
CodeStyleSettings.ImportLayoutTable.Entry[] entries = myImportLayoutList.getEntries();
for (CodeStyleSettings.ImportLayoutTable.Entry entry : entries) {
if (isOtherEntry(entry)) {
myOtherPackageEntry = (CodeStyleSettings.ImportLayoutTable.PackageEntry)entry;
}
}
myPackageList = new CodeStyleSettings.PackageTable();
myPackageList.copyFrom(mySettings.PACKAGES_TO_USE_IMPORT_ON_DEMAND);
myCbLayoutStaticImportsSeparately.setSelected(mySettings.LAYOUT_STATIC_IMPORTS_SEPARATELY);
AbstractTableModel model = (AbstractTableModel)myImportLayoutTable.getModel();
model.fireTableDataChanged();
@@ -630,6 +623,7 @@ public class CodeStyleImportsPanel extends JPanel {
public void apply() {
stopTableEditing();
mySettings.LAYOUT_STATIC_IMPORTS_SEPARATELY = areStaticImportsEnabled();
mySettings.USE_FQ_CLASS_NAMES = myCbUseFQClassNames.isSelected();
mySettings.USE_FQ_CLASS_NAMES_IN_JAVADOC = myCbUseFQClassNamesInJavaDoc.isSelected();
mySettings.USE_SINGLE_CLASS_IMPORTS = myCbUseSingleClassImports.isSelected();
@@ -649,41 +643,25 @@ public class CodeStyleImportsPanel extends JPanel {
//just a bad number
}
myImportLayoutList.removeEmptyPackages();
mySettings.IMPORT_LAYOUT_TABLE.copyFrom(myImportLayoutList);
CodeStyleSettings.ImportLayoutTable.Entry[] entries = myImportLayoutList.getEntries();
int removedEntryCount = 0;
for(int i = 0; i < entries.length; i++){
CodeStyleSettings.ImportLayoutTable.Entry entry = entries[i];
if(isOtherEntry(entry) && entry != myOtherPackageEntry) {
mySettings.IMPORT_LAYOUT_TABLE.removeEntryAt(i-removedEntryCount);
removedEntryCount++;
}
}
mySettings.PACKAGES_TO_USE_IMPORT_ON_DEMAND = myPackageList;
myPackageList.removeEmptyPackages();
mySettings.PACKAGES_TO_USE_IMPORT_ON_DEMAND.copyFrom(myPackageList);
mySettings.JSP_PREFER_COMMA_SEPARATED_IMPORT_LIST = myJspImportCommaSeparated.isSelected();
}
private void stopTableEditing() {
if(myImportLayoutTable.isEditing()) {
TableCellEditor editor = myImportLayoutTable.getCellEditor();
if (editor != null) {
editor.stopCellEditing();
}
}
if(myPackageTable.isEditing()) {
TableCellEditor editor = myPackageTable.getCellEditor();
if (editor != null) {
editor.stopCellEditing();
}
}
TableUtil.stopEditing(myImportLayoutTable);
TableUtil.stopEditing(myPackageTable);
}
public boolean isModified() {
boolean isModified = isModified(myCbUseFQClassNames, mySettings.USE_FQ_CLASS_NAMES);
boolean
isModified = isModified(myCbLayoutStaticImportsSeparately, mySettings.LAYOUT_STATIC_IMPORTS_SEPARATELY);
isModified |= isModified(myCbUseFQClassNames, mySettings.USE_FQ_CLASS_NAMES);
isModified |= isModified(myCbUseFQClassNamesInJavaDoc, mySettings.USE_FQ_CLASS_NAMES_IN_JAVADOC);
isModified |= isModified(myCbUseSingleClassImports, mySettings.USE_SINGLE_CLASS_IMPORTS);
isModified |= isModified(myCbInsertInnerClassImports, mySettings.INSERT_INNER_CLASS_IMPORTS);
@@ -713,30 +691,14 @@ public class CodeStyleImportsPanel extends JPanel {
return checkBox.isSelected() != value;
}
private static boolean isModified(CodeStyleSettings.ImportLayoutTable list, CodeStyleSettings.ImportLayoutTable table) {
private static boolean isModified(PackageEntryTable list, PackageEntryTable table) {
if(list.getEntryCount() != table.getEntryCount()) {
return true;
}
for(int i=0; i<list.getEntryCount(); i++) {
CodeStyleSettings.ImportLayoutTable.Entry entry1 = list.getEntryAt(i);
CodeStyleSettings.ImportLayoutTable.Entry entry2 = table.getEntryAt(i);
if(!entry1.equals(entry2)) {
return true;
}
}
return false;
}
private static boolean isModified(CodeStyleSettings.PackageTable list, CodeStyleSettings.PackageTable table) {
if(list.getEntryCount() != table.getEntryCount()) {
return true;
}
for(int i=0; i<list.getEntryCount(); i++) {
CodeStyleSettings.PackageTable.Entry entry1 = list.getEntryAt(i);
CodeStyleSettings.PackageTable.Entry entry2 = table.getEntryAt(i);
PackageEntry entry1 = list.getEntryAt(i);
PackageEntry entry2 = table.getEntryAt(i);
if(!entry1.equals(entry2)) {
return true;
}
@@ -17,6 +17,7 @@ package com.intellij.application.options;
import com.intellij.openapi.application.ApplicationBundle;
import com.intellij.psi.codeStyle.CodeStyleSettings;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
@@ -65,7 +66,7 @@ public class JavaIndentOptionsEditor extends SmartIndentOptionsEditor {
settings.DO_NOT_INDENT_TOP_LEVEL_CLASS_MEMBERS = myCbDontIndentTopLevelMembers.isSelected();
}
public void reset(final CodeStyleSettings settings, final CodeStyleSettings.IndentOptions options) {
public void reset(@NotNull final CodeStyleSettings settings, @NotNull final CodeStyleSettings.IndentOptions options) {
super.reset(settings, options);
myLabelIndent.setText(Integer.toString(options.LABEL_INDENT_SIZE));
myLabelIndentAbsolute.setSelected(options.LABEL_INDENT_ABSOLUTE);
@@ -20,13 +20,12 @@ import com.intellij.lang.StdLanguages;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.fileTypes.StdFileTypes;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.Pair;
import com.intellij.psi.*;
import com.intellij.psi.codeStyle.CodeStyleManager;
import com.intellij.psi.codeStyle.CodeStyleSettings;
import com.intellij.psi.codeStyle.CodeStyleSettings.ImportLayoutTable;
import com.intellij.psi.codeStyle.CodeStyleSettings.ImportLayoutTable.EmptyLineEntry;
import com.intellij.psi.codeStyle.CodeStyleSettings.ImportLayoutTable.Entry;
import com.intellij.psi.codeStyle.CodeStyleSettings.ImportLayoutTable.PackageEntry;
import com.intellij.psi.codeStyle.PackageEntry;
import com.intellij.psi.codeStyle.PackageEntryTable;
import com.intellij.psi.impl.source.PsiJavaCodeReferenceElementImpl;
import com.intellij.psi.impl.source.SourceTreeToPsiMap;
import com.intellij.psi.impl.source.jsp.jspJava.JspxImportStatement;
@@ -58,44 +57,47 @@ public class ImportHelper{
}
public PsiImportList prepareOptimizeImportsResult(@NotNull final PsiJavaFile file) {
CodeStyleManager codeStyleManager = CodeStyleManager.getInstance(file.getProject());
final Set<String> namesToImportStaticly = new THashSet<String>();
String[] names = collectNamesToImport(file, namesToImportStaticly); // Note: this array may contain "<packageOrClassName>.*" for unresolved imports!
Arrays.sort(names);
ArrayList<String> namesList = new ArrayList<String>();
ImportLayoutTable table = mySettings.IMPORT_LAYOUT_TABLE;
if (table != null){
int[] entriesForName = ArrayUtil.newIntArray(names.length);
for(int i = 0; i < names.length; i++){
entriesForName[i] = findEntryIndex(names[i]);
// Note: this array may contain "<packageOrClassName>.*" for unresolved imports!
List<Pair<String, Boolean>> names = new ArrayList<Pair<String, Boolean>>(collectNamesToImport(file));
Collections.sort(names, new Comparator<Pair<String, Boolean>>() {
public int compare(Pair<String, Boolean> o1, Pair<String, Boolean> o2) {
return o1.getFirst().compareTo(o2.getFirst());
}
});
Entry[] entries = table.getEntries();
for(int i = 0; i < entries.length; i++){
Entry entry = entries[i];
if (entry instanceof PackageEntry){
for(int j = 0; j < names.length; j++){
if (entriesForName[j] == i){
namesList.add(names[j]);
names[j] = null;
}
int[] entryForName = ArrayUtil.newIntArray(names.size());
PackageEntry[] entries = mySettings.IMPORT_LAYOUT_TABLE.getEntries();
for(int i = 0; i < names.size(); i++){
Pair<String, Boolean> pair = names.get(i);
String packageName = pair.getFirst();
Boolean isStatic = pair.getSecond();
entryForName[i] = findEntryIndex(packageName, isStatic, entries);
}
List<Pair<String, Boolean>> resultList = new ArrayList<Pair<String, Boolean>>(names.size());
for(int i = 0; i < entries.length; i++){
PackageEntry entry = entries[i];
//if (!entry.isSpecial()) {
for(int j = 0; j < names.size(); j++){
if (entryForName[j] == i){
resultList.add(names.get(j));
names.set(j, null);
}
}
}
//}
}
for (String name : names) {
if (name != null) namesList.add(name);
for (Pair<String, Boolean> name : names) {
if (name != null) resultList.add(name);
}
names = ArrayUtil.toStringArray(namesList);
TObjectIntHashMap<String> packageToCountMap = new TObjectIntHashMap<String>();
TObjectIntHashMap<String> classToCountMap = new TObjectIntHashMap<String>();
for (String name : names) {
for (Pair<String, Boolean> pair : resultList) {
String name = pair.getFirst();
Boolean isStatic = pair.getSecond();
String packageOrClassName = getPackageOrClassName(name);
if (packageOrClassName.length() == 0) continue;
if (namesToImportStaticly.contains(name)) {
if (isStatic) {
int count = classToCountMap.get(packageOrClassName);
classToCountMap.put(packageOrClassName, count + 1);
}
@@ -123,19 +125,20 @@ public class ImportHelper{
classToCountMap.forEachEntry(new MyVisitorProcedure(false));
packageToCountMap.forEachEntry(new MyVisitorProcedure(true));
Set<String> classesToUseSingle = findSingleImports(file, names, classesOrPackagesToImportOnDemand, namesToImportStaticly);
Set<String> classesToUseSingle = findSingleImports(file, resultList, classesOrPackagesToImportOnDemand);
try {
final String text = buildImportListText(names, classesOrPackagesToImportOnDemand, classesToUseSingle, namesToImportStaticly);
StringBuilder text = buildImportListText(resultList, classesOrPackagesToImportOnDemand, classesToUseSingle);
String ext = StdFileTypes.JAVA.getDefaultExtension();
final PsiJavaFile dummyFile = (PsiJavaFile)PsiFileFactory.getInstance(file.getProject())
.createFileFromText("_Dummy_." + ext, StdFileTypes.JAVA, text);
PsiFileFactory factory = PsiFileFactory.getInstance(file.getProject());
final PsiJavaFile dummyFile = (PsiJavaFile)factory.createFileFromText("_Dummy_." + ext, StdFileTypes.JAVA, text);
CodeStyleManager codeStyleManager = CodeStyleManager.getInstance(file.getProject());
codeStyleManager.reformat(dummyFile);
PsiImportList resultList = dummyFile.getImportList();
PsiImportList result = dummyFile.getImportList();
PsiImportList oldList = file.getImportList();
if (oldList.isReplaceEquivalent(resultList)) return null;
return resultList;
if (oldList.isReplaceEquivalent(result)) return null;
return result;
}
catch(IncorrectOperationException e) {
LOG.error(e);
@@ -145,15 +148,17 @@ public class ImportHelper{
@NotNull
private static Set<String> findSingleImports(@NotNull final PsiJavaFile file,
@NotNull String[] names,
@NotNull final Set<String> onDemandImports,
@NotNull Set<String> namesToImportStaticly) {
@NotNull List<Pair<String,Boolean>> names,
@NotNull final Set<String> onDemandImports
) {
final GlobalSearchScope resolveScope = file.getResolveScope();
Set<String> namesToUseSingle = new THashSet<String>();
final String thisPackageName = file.getPackageName();
final Set<String> implicitlyImportedPackages = new THashSet<String>(Arrays.asList(file.getImplicitlyImportedPackages()));
final PsiManager manager = file.getManager();
for (String name : names) {
for (Pair<String, Boolean> pair : names) {
String name = pair.getFirst();
Boolean isStatic = pair.getSecond();
String prefix = getPackageOrClassName(name);
if (prefix.length() == 0) continue;
final boolean isImplicitlyImported = implicitlyImportedPackages.contains(prefix);
@@ -174,7 +179,7 @@ public class ImportHelper{
}
for (String onDemandName : onDemandImports) {
if (prefix.equals(onDemandName)) continue;
if (namesToImportStaticly.contains(name)) {
if (isStatic) {
PsiClass aClass = JavaPsiFacade.getInstance(manager.getProject()).findClass(onDemandName, resolveScope);
if (aClass != null) {
PsiField field = aClass.findFieldByName(shortName, true);
@@ -209,13 +214,14 @@ public class ImportHelper{
}
@NotNull
private static String buildImportListText(@NotNull String[] names,
@NotNull final Set<String> packagesOrClassesToImportOnDemand,
@NotNull final Set<String> namesToUseSingle,
@NotNull Set<String> namesToImportStaticly) {
private static StringBuilder buildImportListText(@NotNull List<Pair<String, Boolean>> names,
@NotNull final Set<String> packagesOrClassesToImportOnDemand,
@NotNull final Set<String> namesToUseSingle) {
final Set<String> importedPackagesOrClasses = new THashSet<String>();
@NonNls final StringBuilder buffer = new StringBuilder();
for (String name : names) {
for (Pair<String, Boolean> pair : names) {
String name = pair.getFirst();
Boolean isStatic = pair.getSecond();
String packageOrClassName = getPackageOrClassName(name);
final boolean implicitlyImported = JAVA_LANG_PACKAGE.equals(packageOrClassName);
boolean useOnDemand = implicitlyImported || packagesOrClassesToImportOnDemand.contains(packageOrClassName);
@@ -224,7 +230,7 @@ public class ImportHelper{
}
if (useOnDemand && (importedPackagesOrClasses.contains(packageOrClassName) || implicitlyImported)) continue;
buffer.append("import ");
if (namesToImportStaticly.contains(name)) buffer.append("static ");
if (isStatic) buffer.append("static ");
if (useOnDemand) {
importedPackagesOrClasses.add(packageOrClassName);
buffer.append(packageOrClassName);
@@ -236,7 +242,7 @@ public class ImportHelper{
buffer.append(";\n");
}
return buffer.toString();
return buffer;
}
/**
@@ -326,7 +332,8 @@ public class ImportHelper{
PsiImportStatement statement;
if (useOnDemand) {
statement = factory.createImportStatementOnDemand(packageName);
} else {
}
else {
statement = factory.createImportStatement(refClass);
}
importList.add(statement);
@@ -463,14 +470,14 @@ public class ImportHelper{
index1 = index2;
index2 = t;
}
Entry[] entries = mySettings.IMPORT_LAYOUT_TABLE.getEntries();
PackageEntry[] entries = mySettings.IMPORT_LAYOUT_TABLE.getEntries();
int maxSpace = 0;
for(int i = index1 + 1; i < index2; i++){
if (entries[i] instanceof EmptyLineEntry){
if (entries[i] == PackageEntry.BLANK_LINE_ENTRY){
int space = 0;
do{
space++;
} while(entries[++i] instanceof EmptyLineEntry);
} while(entries[++i] == PackageEntry.BLANK_LINE_ENTRY);
maxSpace = Math.max(maxSpace, space);
}
}
@@ -483,34 +490,31 @@ public class ImportHelper{
mySettings.CLASS_COUNT_TO_USE_IMPORT_ON_DEMAND;
if (classCount >= limitCount) return true;
if (packageName.length() == 0) return false;
CodeStyleSettings.PackageTable table = mySettings.PACKAGES_TO_USE_IMPORT_ON_DEMAND;
PackageEntryTable table = mySettings.PACKAGES_TO_USE_IMPORT_ON_DEMAND;
return table != null && table.contains(packageName);
}
private int findEntryIndex(@NotNull String packageName){
Entry[] entries = mySettings.IMPORT_LAYOUT_TABLE.getEntries();
private static int findEntryIndex(@NotNull String packageName, boolean isStatic, @NotNull PackageEntry[] entries) {
PackageEntry bestEntry = null;
int bestEntryIndex = -1;
int allOtherStaticIndex = -1;
int allOtherIndex = -1;
for(int i = 0; i < entries.length; i++){
Entry entry = entries[i];
if (entry instanceof PackageEntry){
PackageEntry packageEntry = (PackageEntry)entry;
if (packageEntry.matchesPackageName(packageName)){
if (bestEntry == null){
bestEntry = packageEntry;
bestEntryIndex = i;
}
else{
String package1 = bestEntry.getPackageName();
String package2 = packageEntry.getPackageName();
if (!bestEntry.isWithSubpackages()) continue;
if (!packageEntry.isWithSubpackages() || package2.length() > package1.length()) {
bestEntry = packageEntry;
bestEntryIndex = i;
}
}
}
PackageEntry entry = entries[i];
if (entry == PackageEntry.ALL_OTHER_STATIC_IMPORTS_ENTRY) {
allOtherStaticIndex = i;
}
if (entry == PackageEntry.ALL_OTHER_IMPORTS_ENTRY) {
allOtherIndex = i;
}
if (entry.isBetterMatchForPackageThan(bestEntry, packageName, isStatic)) {
bestEntry = entry;
bestEntryIndex = i;
}
}
if (bestEntryIndex == -1 && isStatic && allOtherStaticIndex == -1 && allOtherIndex != -1) {
// if no layout for static imports specified, put them among all others
bestEntryIndex = allOtherIndex;
}
return bestEntryIndex;
}
@@ -526,46 +530,45 @@ public class ImportHelper{
String className = ref.getCanonicalText();
packageName = getPackageOrClassName(className);
}
return findEntryIndex(packageName);
return findEntryIndex(packageName, statement instanceof PsiImportStaticStatement, mySettings.IMPORT_LAYOUT_TABLE.getEntries());
}
@NotNull
private static String[] collectNamesToImport(@NotNull PsiJavaFile file, @NotNull Set<String> namesToImportStaticly){
Set<String> names = new THashSet<String>();
// returns list of (name, isImportStatic) pairs
private static Collection<Pair<String,Boolean>> collectNamesToImport(@NotNull PsiJavaFile file){
Set<Pair<String,Boolean>> names = new THashSet<Pair<String,Boolean>>();
final JspFile jspFile = JspPsiUtil.getJspFile(file);
collectNamesToImport(names, file, namesToImportStaticly, jspFile);
collectNamesToImport(names, file, jspFile);
if (jspFile != null) {
PsiFile[] files = ArrayUtil.mergeArrays(JspSpiUtil.getIncludingFiles(jspFile), JspSpiUtil.getIncludedFiles(jspFile), PsiFile.class);
for (PsiFile includingFile : files) {
final PsiFile javaRoot = includingFile.getViewProvider().getPsi(StdLanguages.JAVA);
if (javaRoot instanceof PsiJavaFile && file != javaRoot) {
collectNamesToImport(names, (PsiJavaFile)javaRoot, namesToImportStaticly, jspFile);
collectNamesToImport(names, (PsiJavaFile)javaRoot, jspFile);
}
}
}
addUnresolvedImportNames(names, file, namesToImportStaticly);
addUnresolvedImportNames(names, file);
return ArrayUtil.toStringArray(names);
return names;
}
private static void collectNamesToImport(@NotNull final Set<String> names,
private static void collectNamesToImport(@NotNull final Set<Pair<String, Boolean>> names,
@NotNull final PsiJavaFile file,
@NotNull final Set<String> namesToImportStaticly,
PsiFile context) {
String packageName = file.getPackageName();
final PsiElement[] roots = file.getPsiRoots();
for (PsiElement root : roots) {
addNamesToImport(names, root, packageName, namesToImportStaticly, context);
addNamesToImport(names, root, packageName, context);
}
}
private static void addNamesToImport(@NotNull Set<String> names,
private static void addNamesToImport(@NotNull Set<Pair<String, Boolean>> names,
@NotNull PsiElement scope,
@NotNull String thisPackageName,
@NotNull Set<String> namesToImportStaticly,
PsiFile context){
if (scope instanceof PsiImportList) return;
@@ -579,9 +582,7 @@ public class ImportHelper{
for(final PsiReference reference : child.getReferences()){
if (!(reference instanceof PsiJavaReference)) continue;
final PsiJavaReference javaReference = (PsiJavaReference)reference;
if (javaReference instanceof JavaClassReference){
if(((JavaClassReference)javaReference).getContextReference() != null) continue;
}
if (javaReference instanceof JavaClassReference && ((JavaClassReference)javaReference).getContextReference() != null) continue;
PsiJavaCodeReferenceElement referenceElement = null;
if (reference instanceof PsiJavaCodeReferenceElement) {
referenceElement = (PsiJavaCodeReferenceElement)child;
@@ -599,6 +600,7 @@ public class ImportHelper{
if (refElement == null && referenceElement != null) {
refElement = ResolveClassUtil.resolveClass(referenceElement); // might be uncomplete code
}
if (refElement == null) continue;
PsiElement currentFileResolveScope = resolveResult.getCurrentFileResolveScope();
if (!(currentFileResolveScope instanceof PsiImportStatementBase)) continue;
@@ -606,35 +608,29 @@ public class ImportHelper{
continue;
}
if (refElement != null) {
//Add names imported statically
if (referenceElement != null) {
if (currentFileResolveScope instanceof PsiImportStaticStatement) {
PsiImportStaticStatement importStaticStatement = (PsiImportStaticStatement)currentFileResolveScope;
String name = importStaticStatement.getImportReference().getCanonicalText();
if (importStaticStatement.isOnDemand()) {
String refName = referenceElement.getReferenceName();
if (refName != null) name = name + "." + refName;
}
names.add(name);
namesToImportStaticly.add(name);
continue;
if (referenceElement != null) {
if (currentFileResolveScope instanceof PsiImportStaticStatement) {
PsiImportStaticStatement importStaticStatement = (PsiImportStaticStatement)currentFileResolveScope;
String name = importStaticStatement.getImportReference().getCanonicalText();
if (importStaticStatement.isOnDemand()) {
String refName = referenceElement.getReferenceName();
if (refName != null) name = name + "." + refName;
}
names.add(Pair.create(name, Boolean.TRUE));
continue;
}
}
if (refElement instanceof PsiClass) {
String qName = ((PsiClass)refElement).getQualifiedName();
if (hasPackage(qName, thisPackageName)) continue;
names.add(qName);
}
if (refElement instanceof PsiClass) {
String qName = ((PsiClass)refElement).getQualifiedName();
if (hasPackage(qName, thisPackageName)) continue;
names.add(Pair.create(qName, Boolean.FALSE));
}
}
}
}
private static void addUnresolvedImportNames(@NotNull Set<String> set,
@NotNull PsiJavaFile file,
@NotNull Set<String> namesToImportStaticly) {
private static void addUnresolvedImportNames(@NotNull Set<Pair<String, Boolean>> names, @NotNull PsiJavaFile file) {
PsiImportStatementBase[] imports = file.getImportList().getAllImportStatements();
for (PsiImportStatementBase anImport : imports) {
PsiJavaCodeReferenceElement ref = anImport.getImportReference();
@@ -645,10 +641,7 @@ public class ImportHelper{
if (anImport.isOnDemand()) {
text += ".*";
}
if (anImport instanceof PsiImportStaticStatement) {
namesToImportStaticly.add(text);
}
set.add(text);
names.add(Pair.create(text, anImport instanceof PsiImportStaticStatement));
}
}
}
@@ -16,9 +16,10 @@
package com.intellij.application.options;
import com.intellij.ui.OptionGroup;
import com.intellij.openapi.application.ApplicationBundle;
import com.intellij.psi.codeStyle.CodeStyleSettings;
import com.intellij.ui.OptionGroup;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
@@ -108,7 +109,7 @@ public class IndentOptionsEditor extends OptionGroup {
options.USE_TAB_CHARACTER = myCbUseTab.isSelected();
}
public void reset(final CodeStyleSettings settings, CodeStyleSettings.IndentOptions options) {
public void reset(@NotNull CodeStyleSettings settings, @NotNull CodeStyleSettings.IndentOptions options) {
myTabSizeField.setText(String.valueOf(options.TAB_SIZE));
myCbUseTab.setSelected(options.USE_TAB_CHARACTER);
@@ -18,6 +18,7 @@ package com.intellij.application.options;
import com.intellij.openapi.application.ApplicationBundle;
import com.intellij.psi.codeStyle.CodeStyleSettings;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
@@ -63,7 +64,7 @@ public class SmartIndentOptionsEditor extends IndentOptionsEditor {
options.SMART_TABS = isSmartTabValid(options.INDENT_SIZE, options.TAB_SIZE) && myCbSmartTabs.isSelected();
}
public void reset(final CodeStyleSettings settings, final CodeStyleSettings.IndentOptions options) {
public void reset(@NotNull final CodeStyleSettings settings, @NotNull final CodeStyleSettings.IndentOptions options) {
super.reset(settings, options);
myContinuationIndentField.setText(String.valueOf(options.CONTINUATION_INDENT_SIZE));
myCbSmartTabs.setSelected(options.SMART_TABS);
@@ -35,7 +35,7 @@ import java.lang.reflect.Modifier;
import java.util.*;
public class CodeStyleSettings implements Cloneable, JDOMExternalizable {
private ClassMap<CustomCodeStyleSettings> myCustomSettings = new ClassMap<CustomCodeStyleSettings>();
private final ClassMap<CustomCodeStyleSettings> myCustomSettings = new ClassMap<CustomCodeStyleSettings>();
@NonNls private static final String ADDITIONAL_INDENT_OPTIONS = "ADDITIONAL_INDENT_OPTIONS";
@NonNls private static final String FILETYPE = "fileType";
@@ -56,12 +56,12 @@ public class CodeStyleSettings implements Cloneable, JDOMExternalizable {
}
private void initImports() {
PACKAGES_TO_USE_IMPORT_ON_DEMAND.insertEntryAt(new PackageTable.Entry("java.awt", false), 0);
PACKAGES_TO_USE_IMPORT_ON_DEMAND.insertEntryAt(new PackageTable.Entry("javax.swing", false), 1);
IMPORT_LAYOUT_TABLE.insertEntryAt(new ImportLayoutTable.PackageEntry("", true), 0);
IMPORT_LAYOUT_TABLE.insertEntryAt(new ImportLayoutTable.EmptyLineEntry(), 1);
IMPORT_LAYOUT_TABLE.insertEntryAt(new ImportLayoutTable.PackageEntry("javax", true), 2);
IMPORT_LAYOUT_TABLE.insertEntryAt(new ImportLayoutTable.PackageEntry("java", true), 3);
PACKAGES_TO_USE_IMPORT_ON_DEMAND.addEntry(new PackageEntry(false, "java.awt", false));
PACKAGES_TO_USE_IMPORT_ON_DEMAND.addEntry(new PackageEntry(false,"javax.swing", false));
IMPORT_LAYOUT_TABLE.addEntry(PackageEntry.ALL_OTHER_IMPORTS_ENTRY);
IMPORT_LAYOUT_TABLE.addEntry(PackageEntry.BLANK_LINE_ENTRY);
IMPORT_LAYOUT_TABLE.addEntry(new PackageEntry(false, "javax", true));
IMPORT_LAYOUT_TABLE.addEntry(new PackageEntry(false, "java", true));
}
private void initTypeToName() {
@@ -102,67 +102,64 @@ public class CodeStyleSettings implements Cloneable, JDOMExternalizable {
}
public CodeStyleSettings clone() {
try {
CodeStyleSettings clone = (CodeStyleSettings)super.clone();
copyCustomSettings(this, clone);
return clone;
}
catch (CloneNotSupportedException e) {
throw new RuntimeException(e);
}
CodeStyleSettings clone = new CodeStyleSettings();
clone.copyFrom(this);
return clone;
}
private static void copyCustomSettings(CodeStyleSettings from, final CodeStyleSettings to) throws CloneNotSupportedException {
to.myCustomSettings = new ClassMap<CustomCodeStyleSettings>();
private void copyCustomSettingsFrom(CodeStyleSettings from) {
assert from != this;
myCustomSettings.clear();
for (final CustomCodeStyleSettings settings : from.myCustomSettings.values()) {
to.addCustomSettings((CustomCodeStyleSettings) settings.clone());
addCustomSettings((CustomCodeStyleSettings) settings.clone());
}
to.FIELD_TYPE_TO_NAME = (TypeToNameMap)from.FIELD_TYPE_TO_NAME.clone();
to.STATIC_FIELD_TYPE_TO_NAME = (TypeToNameMap)from.STATIC_FIELD_TYPE_TO_NAME.clone();
to.PARAMETER_TYPE_TO_NAME = (TypeToNameMap)from.PARAMETER_TYPE_TO_NAME.clone();
to.LOCAL_VARIABLE_TYPE_TO_NAME = (TypeToNameMap)from.LOCAL_VARIABLE_TYPE_TO_NAME.clone();
FIELD_TYPE_TO_NAME.copyFrom(from.FIELD_TYPE_TO_NAME);
STATIC_FIELD_TYPE_TO_NAME.copyFrom(from.STATIC_FIELD_TYPE_TO_NAME);
PARAMETER_TYPE_TO_NAME.copyFrom(from.PARAMETER_TYPE_TO_NAME);
LOCAL_VARIABLE_TYPE_TO_NAME.copyFrom(from.LOCAL_VARIABLE_TYPE_TO_NAME);
to.PACKAGES_TO_USE_IMPORT_ON_DEMAND = (PackageTable)from.PACKAGES_TO_USE_IMPORT_ON_DEMAND.clone();
to.IMPORT_LAYOUT_TABLE = (ImportLayoutTable)from.IMPORT_LAYOUT_TABLE.clone();
PACKAGES_TO_USE_IMPORT_ON_DEMAND.copyFrom(from.PACKAGES_TO_USE_IMPORT_ON_DEMAND);
IMPORT_LAYOUT_TABLE.copyFrom(from.IMPORT_LAYOUT_TABLE);
to.OTHER_INDENT_OPTIONS = (IndentOptions)from.OTHER_INDENT_OPTIONS.clone();
OTHER_INDENT_OPTIONS.copyFrom(from.OTHER_INDENT_OPTIONS);
to.myAdditionalIndentOptions = new LinkedHashMap<FileType, IndentOptions>();
myAdditionalIndentOptions.clear();
for(Map.Entry<FileType, IndentOptions> optionEntry: from.myAdditionalIndentOptions.entrySet()) {
to.myAdditionalIndentOptions.put(optionEntry.getKey(),(IndentOptions)optionEntry.getValue().clone());
IndentOptions options = optionEntry.getValue();
myAdditionalIndentOptions.put(optionEntry.getKey(),(IndentOptions)options.clone());
}
}
public void copyFrom(CodeStyleSettings settings) {
Field[] fields = getClass().getDeclaredFields();
public void copyFrom(CodeStyleSettings from) {
copyPublicFields(from, this);
this.copyCustomSettingsFrom(from);
}
private static void copyPublicFields(Object from, Object to) {
assert from != to;
Field[] fields = to.getClass().getDeclaredFields();
for (Field field : fields) {
if (isPublic(field) && !isFinal(field)) {
try {
copyFieldValue(settings, field);
copyFieldValue(from, to, field);
}
catch (Exception e) {
throw new RuntimeException(e);
}
}
}
try {
copyCustomSettings(settings, this);
}
catch (CloneNotSupportedException e) {
throw new RuntimeException(e);
}
}
private void copyFieldValue(final CodeStyleSettings settings, final Field field)
throws IllegalAccessException, CloneNotSupportedException {
private static void copyFieldValue(final Object from, Object to, final Field field)
throws IllegalAccessException {
Class<?> fieldType = field.getType();
if (fieldType.isPrimitive()) {
field.set(this, field.get(settings));
field.set(to, field.get(from));
}
else if (fieldType.equals(String.class)) {
field.set(this, field.get(settings));
field.set(to, field.get(from));
}
else {
System.out.println("Field not copied " + field.getName());
@@ -248,18 +245,22 @@ public class CodeStyleSettings implements Cloneable, JDOMExternalizable {
result = 31 * result + (LABEL_INDENT_ABSOLUTE ? 1 : 0);
return result;
}
public void copyFrom(IndentOptions other) {
copyPublicFields(other, this);
}
}
@Deprecated
public IndentOptions JAVA_INDENT_OPTIONS = new IndentOptions();
public final IndentOptions JAVA_INDENT_OPTIONS = new IndentOptions();
@Deprecated
public IndentOptions JSP_INDENT_OPTIONS = new IndentOptions();
public final IndentOptions JSP_INDENT_OPTIONS = new IndentOptions();
@Deprecated
public IndentOptions XML_INDENT_OPTIONS = new IndentOptions();
public final IndentOptions XML_INDENT_OPTIONS = new IndentOptions();
public IndentOptions OTHER_INDENT_OPTIONS = new IndentOptions();
public final IndentOptions OTHER_INDENT_OPTIONS = new IndentOptions();
private Map<FileType,IndentOptions> myAdditionalIndentOptions = new LinkedHashMap<FileType, IndentOptions>();
private final Map<FileType,IndentOptions> myAdditionalIndentOptions = new LinkedHashMap<FileType, IndentOptions>();
private static final String ourSystemLineSeparator = SystemProperties.getLineSeparator();
@@ -720,10 +721,10 @@ public class CodeStyleSettings implements Cloneable, JDOMExternalizable {
public boolean PREFER_LONGER_NAMES = true;
public TypeToNameMap FIELD_TYPE_TO_NAME = new TypeToNameMap();
public TypeToNameMap STATIC_FIELD_TYPE_TO_NAME = new TypeToNameMap();
@NonNls public TypeToNameMap PARAMETER_TYPE_TO_NAME = new TypeToNameMap();
public TypeToNameMap LOCAL_VARIABLE_TYPE_TO_NAME = new TypeToNameMap();
public final TypeToNameMap FIELD_TYPE_TO_NAME = new TypeToNameMap();
public final TypeToNameMap STATIC_FIELD_TYPE_TO_NAME = new TypeToNameMap();
@NonNls public final TypeToNameMap PARAMETER_TYPE_TO_NAME = new TypeToNameMap();
public final TypeToNameMap LOCAL_VARIABLE_TYPE_TO_NAME = new TypeToNameMap();
//----------------- 'final' modifier settings -------
public boolean GENERATE_FINAL_LOCALS = false;
@@ -735,14 +736,15 @@ public class CodeStyleSettings implements Cloneable, JDOMExternalizable {
//----------------- IMPORTS --------------------
public boolean LAYOUT_STATIC_IMPORTS_SEPARATELY = true;
public boolean USE_FQ_CLASS_NAMES = false;
public boolean USE_FQ_CLASS_NAMES_IN_JAVADOC = true;
public boolean USE_SINGLE_CLASS_IMPORTS = true;
public boolean INSERT_INNER_CLASS_IMPORTS = false;
public int CLASS_COUNT_TO_USE_IMPORT_ON_DEMAND = 5;
public int NAMES_COUNT_TO_USE_IMPORT_ON_DEMAND = 3;
public PackageTable PACKAGES_TO_USE_IMPORT_ON_DEMAND = new PackageTable();
public ImportLayoutTable IMPORT_LAYOUT_TABLE = new ImportLayoutTable();
public final PackageEntryTable PACKAGES_TO_USE_IMPORT_ON_DEMAND = new PackageEntryTable();
public final PackageEntryTable IMPORT_LAYOUT_TABLE = new PackageEntryTable();
public boolean OPTIMIZE_IMPORTS_ON_THE_FLY = false;
public boolean ADD_UNAMBIGIOUS_IMPORTS_ON_THE_FLY = false;
@@ -1115,6 +1117,19 @@ public class CodeStyleSettings implements Cloneable, JDOMExternalizable {
public void readExternal(Element element) throws InvalidDataException {
DefaultJDOMExternalizer.readExternal(this, element);
if (LAYOUT_STATIC_IMPORTS_SEPARATELY) {
// add <all other static imports> entry if there is none
boolean found = false;
for (PackageEntry entry : IMPORT_LAYOUT_TABLE.getEntries()) {
if (entry == PackageEntry.ALL_OTHER_STATIC_IMPORTS_ENTRY) {
found = true;
break;
}
}
if (!found) {
IMPORT_LAYOUT_TABLE.addEntry(PackageEntry.ALL_OTHER_STATIC_IMPORTS_ENTRY);
}
}
importOldIndentOptions(element);
for (final CustomCodeStyleSettings settings : myCustomSettings.values()) {
settings.readExternal(element);
@@ -1269,9 +1284,9 @@ public class CodeStyleSettings implements Cloneable, JDOMExternalizable {
return getIndentOptions(fileType).USE_TAB_CHARACTER;
}
public static class TypeToNameMap implements JDOMExternalizable, Cloneable {
private ArrayList<String> myPatterns = new ArrayList<String>();
private ArrayList<String> myNames = new ArrayList<String>();
public static class TypeToNameMap implements JDOMExternalizable {
private final List<String> myPatterns = new ArrayList<String>();
private final List<String> myNames = new ArrayList<String>();
public void addPair(String pattern, String name) {
myPatterns.add(pattern);
@@ -1323,11 +1338,12 @@ public class CodeStyleSettings implements Cloneable, JDOMExternalizable {
}
}
public Object clone() throws CloneNotSupportedException {
TypeToNameMap clon = (TypeToNameMap)TypeToNameMap.super.clone();
clon.myPatterns = (ArrayList<String>)myPatterns.clone();
clon.myNames = (ArrayList<String>)myNames.clone();
return clon;
public void copyFrom(TypeToNameMap from) {
assert from != this;
myPatterns.clear();
myPatterns.addAll(from.myPatterns);
myNames.clear();
myNames.addAll(from.myNames);
}
public boolean equals(Object other) {
@@ -1371,311 +1387,6 @@ public class CodeStyleSettings implements Cloneable, JDOMExternalizable {
}
public static class PackageTable implements JDOMExternalizable, Cloneable {
public static class Entry implements Cloneable {
final String packageName;
final boolean withSubpackages;
public Entry(@NonNls String packageName, boolean withSubpackages) {
this.packageName = packageName;
this.withSubpackages = withSubpackages;
}
public String getPackageName() {
return packageName;
}
public boolean isWithSubpackages() {
return withSubpackages;
}
public boolean equals(Object obj) {
if (!(obj instanceof Entry)) {
return false;
}
Entry entry = (Entry)obj;
return entry.withSubpackages == withSubpackages
&& Comparing.equal(entry.packageName, packageName);
}
public int hashCode() {
if (packageName == null) {
return 0;
}
return packageName.hashCode();
}
}
private ArrayList<Entry> myEntries = new ArrayList<Entry>();
public boolean equals(Object obj) {
if (!(obj instanceof PackageTable)) {
return false;
}
PackageTable other = (PackageTable)obj;
if (other.myEntries.size() != myEntries.size()) {
return false;
}
for (int i = 0; i < myEntries.size(); i++) {
Entry entry = myEntries.get(i);
Entry otherentry = other.myEntries.get(i);
if (!Comparing.equal(entry, otherentry)) {
return false;
}
}
return true;
}
public int hashCode() {
if (!myEntries.isEmpty() && myEntries.get(0) != null) {
return myEntries.get(0).hashCode();
}
return 0;
}
public Object clone() throws CloneNotSupportedException {
PackageTable clon = (PackageTable)PackageTable.super.clone();
clon.myEntries = (ArrayList<Entry>)myEntries.clone();
return clon;
}
public void copyFrom(PackageTable packageTable) {
myEntries = (ArrayList<Entry>)packageTable.myEntries.clone();
}
public Entry[] getEntries() {
return myEntries.toArray(new Entry[myEntries.size()]);
}
public void insertEntryAt(Entry entry, int i) {
myEntries.add(i, entry);
}
public void removeEntryAt(int i) {
myEntries.remove(i);
}
public Entry getEntryAt(int i) {
return myEntries.get(i);
}
public int getEntryCount() {
return myEntries.size();
}
public void setEntryAt(Entry entry, int i) {
myEntries.set(i, entry);
}
public boolean contains(String packageName) {
for (Entry entry : myEntries) {
if (packageName.startsWith(entry.packageName)) {
if (packageName.length() == entry.packageName.length()) return true;
if (entry.withSubpackages) {
if (packageName.charAt(entry.packageName.length()) == '.') return true;
}
}
}
return false;
}
public void readExternal(@NonNls Element element) throws InvalidDataException {
myEntries.clear();
for (final Object o : element.getChildren("package")) {
@NonNls Element e = (Element)o;
String packageName = e.getAttributeValue("name");
boolean withSubpackages = Boolean.parseBoolean(e.getAttributeValue("withSubpackages"));
if (packageName == null) {
throw new InvalidDataException();
}
myEntries.add(new Entry(packageName, withSubpackages));
}
}
public void writeExternal(Element parentNode) throws WriteExternalException {
for (Entry entry : myEntries) {
@NonNls Element element = new Element("package");
parentNode.addContent(element);
element.setAttribute("name", entry.packageName);
element.setAttribute("withSubpackages", Boolean.toString(entry.withSubpackages));
}
}
}
public static class ImportLayoutTable implements JDOMExternalizable, Cloneable {
private ArrayList<Entry> myEntries = new ArrayList<Entry>();
public interface Entry {
}
public static class PackageEntry implements Entry {
private final String myPackageName;
private final boolean myWithSubpackages;
public PackageEntry(@NonNls String packageName, boolean withSubpackages) {
myPackageName = packageName;
myWithSubpackages = withSubpackages;
}
public String getPackageName() {
return myPackageName;
}
public boolean isWithSubpackages() {
return myWithSubpackages;
}
public boolean matchesPackageName(String packageName) {
if (myPackageName.length() == 0 && myWithSubpackages) return true;
if (packageName.startsWith(myPackageName)) {
if (packageName.length() == myPackageName.length()) return true;
if (myWithSubpackages) {
if (packageName.charAt(myPackageName.length()) == '.') return true;
}
}
return false;
}
public boolean matchesClassName(String className) {
int dotIndex = className.lastIndexOf('.');
String packageName = dotIndex < 0 ? "" : className.substring(0, dotIndex);
return matchesPackageName(packageName);
}
public boolean equals(Object obj) {
if (!(obj instanceof PackageEntry)) {
return false;
}
PackageEntry entry = (PackageEntry)obj;
return entry.myWithSubpackages == myWithSubpackages
&& Comparing.equal(entry.myPackageName, myPackageName);
}
public int hashCode() {
if (myPackageName == null) {
return 0;
}
return myPackageName.hashCode();
}
}
public static class EmptyLineEntry implements Entry {
public boolean equals(Object obj) {
return obj instanceof EmptyLineEntry;
}
public int hashCode() {
return 100;
}
}
public void copyFrom(ImportLayoutTable importLayoutTable) {
myEntries = (ArrayList<Entry>)importLayoutTable.myEntries.clone();
}
public Entry[] getEntries() {
return myEntries.toArray(new Entry[myEntries.size()]);
}
public void insertEntryAt(Entry entry, int i) {
myEntries.add(i, entry);
}
public void removeEntryAt(int i) {
myEntries.remove(i);
}
public Entry getEntryAt(int i) {
return myEntries.get(i);
}
public int getEntryCount() {
return myEntries.size();
}
public void setEntryAt(Entry entry, int i) {
myEntries.set(i, entry);
}
public void readExternal(Element element) throws InvalidDataException {
myEntries.clear();
List children = element.getChildren();
for (final Object aChildren : children) {
@NonNls Element e = (Element)aChildren;
@NonNls String name = e.getName();
if ("package".equals(name)) {
String packageName = e.getAttributeValue("name");
boolean withSubpackages = Boolean.parseBoolean(e.getAttributeValue("withSubpackages"));
if (packageName == null) {
throw new InvalidDataException();
}
myEntries.add(new PackageEntry(packageName, withSubpackages));
}
else {
if ("emptyLine".equals(name)) {
myEntries.add(new EmptyLineEntry());
}
}
}
}
public void writeExternal(Element parentNode) throws WriteExternalException {
for (Entry myEntry : myEntries) {
if (myEntry instanceof PackageEntry) {
PackageEntry entry = (PackageEntry)myEntry;
@NonNls Element element = new Element("package");
parentNode.addContent(element);
element.setAttribute("name", entry.getPackageName());
element.setAttribute("withSubpackages", entry.isWithSubpackages() ? "true" : "false");
}
else {
if (myEntry instanceof EmptyLineEntry) {
@NonNls Element element = new Element("emptyLine");
parentNode.addContent(element);
}
}
}
}
public boolean equals(Object obj) {
if (!(obj instanceof ImportLayoutTable)) {
return false;
}
ImportLayoutTable other = (ImportLayoutTable)obj;
if (other.myEntries.size() != myEntries.size()) {
return false;
}
for (int i = 0; i < myEntries.size(); i++) {
Entry entry = myEntries.get(i);
Entry otherentry = other.myEntries.get(i);
if (!Comparing.equal(entry, otherentry)) {
return false;
}
}
return true;
}
public int hashCode() {
if (!myEntries.isEmpty() && myEntries.get(0) != null) {
return myEntries.get(0).hashCode();
}
return 0;
}
public Object clone() throws CloneNotSupportedException {
ImportLayoutTable clon = (ImportLayoutTable)ImportLayoutTable.super.clone();
clon.myEntries = (ArrayList<Entry>)myEntries.clone();
return clon;
}
}
private void registerAdditionalIndentOptions(FileType fileType, IndentOptions options) {
myAdditionalIndentOptions.put(fileType, options);
}
@@ -1689,9 +1400,8 @@ public class CodeStyleSettings implements Cloneable, JDOMExternalizable {
private void loadAdditionalIndentOptions() {
myLoadedAdditionalIndentOptions = true;
final FileTypeIndentOptionsProvider[] fileTypeIndentOptionsProviders =
Extensions.getExtensions(FileTypeIndentOptionsProvider.EP_NAME);
for (final FileTypeIndentOptionsProvider provider : fileTypeIndentOptionsProviders) {
final FileTypeIndentOptionsProvider[] providers = Extensions.getExtensions(FileTypeIndentOptionsProvider.EP_NAME);
for (final FileTypeIndentOptionsProvider provider : providers) {
if (!myAdditionalIndentOptions.containsKey(provider.getFileType())) {
registerAdditionalIndentOptions(provider.getFileType(), provider.createIndentOptions());
}
@@ -1710,7 +1420,7 @@ public class CodeStyleSettings implements Cloneable, JDOMExternalizable {
}
private static class TempFileType implements FileType {
private String myExtension;
private final String myExtension;
private TempFileType(@NotNull final String extension) {
myExtension = extension;
@@ -0,0 +1,114 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.psi.codeStyle;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.text.StringUtil;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* User: cdr
*/
public class PackageEntry {
private final String myPackageName;
private final boolean myWithSubpackages;
private final boolean isStatic;
public PackageEntry(boolean isStatic, @NotNull @NonNls String packageName, boolean withSubpackages) {
this.isStatic = isStatic;
myPackageName = packageName;
myWithSubpackages = withSubpackages;
}
public String getPackageName() {
return myPackageName;
}
public boolean isWithSubpackages() {
return myWithSubpackages;
}
public boolean isStatic() {
return isStatic;
}
public boolean matchesPackageName(String packageName) {
if (packageName.startsWith(myPackageName)) {
if (packageName.length() == myPackageName.length()) return true;
if (myWithSubpackages) {
if (packageName.charAt(myPackageName.length()) == '.') return true;
}
}
return false;
}
public boolean equals(Object obj) {
if (!(obj instanceof PackageEntry)) {
return false;
}
PackageEntry entry = (PackageEntry)obj;
return entry.myWithSubpackages == myWithSubpackages
&& entry.isStatic() == isStatic()
&& Comparing.equal(entry.myPackageName, myPackageName);
}
public int hashCode() {
return myPackageName.hashCode();
}
public static final PackageEntry BLANK_LINE_ENTRY = new PackageEntry(false, "<blank line>", true){
@Override
public boolean matchesPackageName(String packageName) {
return false;
}
};
public static final PackageEntry ALL_OTHER_IMPORTS_ENTRY = new PackageEntry(false, "<all other imports>", true){
@Override
public boolean matchesPackageName(String packageName) {
return true;
}
};
public static final PackageEntry ALL_OTHER_STATIC_IMPORTS_ENTRY = new PackageEntry(true, "<all other static imports>", true){
@Override
public boolean matchesPackageName(String packageName) {
return true;
}
};
public boolean isSpecial() {
return this == BLANK_LINE_ENTRY || this == ALL_OTHER_IMPORTS_ENTRY || this == ALL_OTHER_STATIC_IMPORTS_ENTRY;
}
public boolean isBetterMatchForPackageThan(@Nullable PackageEntry entry, @NotNull String packageName, boolean isStatic) {
if (isStatic() != isStatic || !matchesPackageName(packageName)) return false;
if (entry == null) {
return true;
}
if (entry.isStatic() != isStatic) return false;
if (entry.isWithSubpackages() != isWithSubpackages()) {
return !isWithSubpackages();
}
return StringUtil.countChars(entry.getPackageName(), '.') < StringUtil.countChars(getPackageName(), '.');
}
@Override
public String toString() {
return (isStatic() ? "static " : "") + getPackageName();
}
}
@@ -0,0 +1,166 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.psi.codeStyle;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.InvalidDataException;
import com.intellij.openapi.util.JDOMExternalizable;
import com.intellij.openapi.util.WriteExternalException;
import com.intellij.openapi.util.text.StringUtil;
import org.jdom.Element;
import org.jetbrains.annotations.NonNls;
import java.util.ArrayList;
import java.util.List;
/**
* User: cdr
*/
public class PackageEntryTable implements JDOMExternalizable, Cloneable {
private final List<PackageEntry> myEntries = new ArrayList<PackageEntry>();
public boolean equals(Object obj) {
if (!(obj instanceof PackageEntryTable)) {
return false;
}
PackageEntryTable other = (PackageEntryTable)obj;
if (other.myEntries.size() != myEntries.size()) {
return false;
}
for (int i = 0; i < myEntries.size(); i++) {
PackageEntry entry = myEntries.get(i);
PackageEntry otherentry = other.myEntries.get(i);
if (!Comparing.equal(entry, otherentry)) {
return false;
}
}
return true;
}
public int hashCode() {
if (!myEntries.isEmpty() && myEntries.get(0) != null) {
return myEntries.get(0).hashCode();
}
return 0;
}
public Object clone() throws CloneNotSupportedException {
PackageEntryTable clon = new PackageEntryTable();
clon.copyFrom(this);
return clon;
}
public void copyFrom(PackageEntryTable packageTable) {
myEntries.clear();
myEntries.addAll(packageTable.myEntries);
}
public PackageEntry[] getEntries() {
return myEntries.toArray(new PackageEntry[myEntries.size()]);
}
public void insertEntryAt(PackageEntry entry, int i) {
myEntries.add(i, entry);
}
public void removeEntryAt(int i) {
myEntries.remove(i);
}
public PackageEntry getEntryAt(int i) {
return myEntries.get(i);
}
public int getEntryCount() {
return myEntries.size();
}
public void setEntryAt(PackageEntry entry, int i) {
myEntries.set(i, entry);
}
public boolean contains(String packageName) {
for (PackageEntry entry : myEntries) {
if (packageName.startsWith(entry.getPackageName())) {
if (packageName.length() == entry.getPackageName().length()) return true;
if (entry.isWithSubpackages()) {
if (packageName.charAt(entry.getPackageName().length()) == '.') return true;
}
}
}
return false;
}
public void readExternal(Element element) throws InvalidDataException {
myEntries.clear();
List children = element.getChildren();
for (final Object aChildren : children) {
@NonNls Element e = (Element)aChildren;
@NonNls String name = e.getName();
if ("package".equals(name)) {
String packageName = e.getAttributeValue("name");
boolean isStatic = Boolean.parseBoolean(e.getAttributeValue("static"));
boolean withSubpackages = Boolean.parseBoolean(e.getAttributeValue("withSubpackages"));
if (packageName == null) {
throw new InvalidDataException();
}
PackageEntry entry;
if (packageName.length() == 0) {
entry = isStatic ? PackageEntry.ALL_OTHER_STATIC_IMPORTS_ENTRY : PackageEntry.ALL_OTHER_IMPORTS_ENTRY;
}
else {
entry = new PackageEntry(isStatic, packageName, withSubpackages);
}
myEntries.add(entry);
}
else {
if ("emptyLine".equals(name)) {
myEntries.add(PackageEntry.BLANK_LINE_ENTRY);
}
}
}
}
public void writeExternal(Element parentNode) throws WriteExternalException {
for (PackageEntry entry : myEntries) {
if (entry == PackageEntry.BLANK_LINE_ENTRY) {
@NonNls Element element = new Element("emptyLine");
parentNode.addContent(element);
}
else {
@NonNls Element element = new Element("package");
parentNode.addContent(element);
String packageName = entry.getPackageName();
element.setAttribute("name", entry == PackageEntry.ALL_OTHER_IMPORTS_ENTRY || entry == PackageEntry.ALL_OTHER_STATIC_IMPORTS_ENTRY ? "": packageName);
element.setAttribute("withSubpackages", entry.isWithSubpackages() ? "true" : "false");
element.setAttribute("static", entry.isStatic() ? "true" : "false");
}
}
}
public void removeEmptyPackages() {
for(int i = myEntries.size()-1; i>=0; i--){
PackageEntry entry = myEntries.get(i);
if(StringUtil.isEmptyOrSpaces(entry.getPackageName())) {
removeEntryAt(i);
}
}
}
public void addEntry(PackageEntry entry) {
myEntries.add(entry);
}
}
@@ -16,7 +16,6 @@
package com.intellij.application.options;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.application.ApplicationBundle;
import com.intellij.openapi.editor.colors.EditorColorsScheme;
import com.intellij.openapi.editor.highlighter.EditorHighlighter;
@@ -129,13 +128,7 @@ public class GeneralCodeStylePanel extends CodeStyleAbstractPanel {
for(Map.Entry<FileType, IndentOptionsEditor> entry: myAdditionalIndentOptions.entrySet()) {
FileType ft = entry.getKey();
String tabName;
if (ft instanceof LanguageFileType) {
tabName = ((LanguageFileType) ft).getLanguage().getDisplayName();
}
else {
tabName = ft.getName();
}
String tabName = ft instanceof LanguageFileType ? ((LanguageFileType)ft).getLanguage().getDisplayName() : ft.getName();
myIndentOptionsTabs.addTab(tabName, entry.getValue().createPanel());
}
@@ -195,7 +188,7 @@ public class GeneralCodeStylePanel extends CodeStyleAbstractPanel {
@Nullable
private static FileTypeIndentOptionsProvider getDefaultIndentProvider() {
FileTypeIndentOptionsProvider[] providers = Extensions.getExtensions(FileTypeIndentOptionsProvider.EP_NAME);
return (providers.length == 0) ? null : providers[0];
return providers.length == 0 ? null : providers[0];
}
public void apply(CodeStyleSettings settings) {
@@ -208,8 +201,10 @@ public class GeneralCodeStylePanel extends CodeStyleAbstractPanel {
else {
myOtherIndentOptions.apply(settings, settings.OTHER_INDENT_OPTIONS);
for(FileType fileType: myAdditionalIndentOptions.keySet()) {
myAdditionalIndentOptions.get(fileType).apply(settings, settings.getAdditionalIndentOptions(fileType));
for(Map.Entry<FileType, IndentOptionsEditor> entry : myAdditionalIndentOptions.entrySet()) {
FileType fileType = entry.getKey();
IndentOptionsEditor editor = entry.getValue();
editor.apply(settings, settings.getAdditionalIndentOptions(fileType));
}
}
@@ -221,14 +216,7 @@ public class GeneralCodeStylePanel extends CodeStyleAbstractPanel {
}
private IndentOptionsEditor findEditorForSameIndents() {
IndentOptionsEditor theEditor;
if (myAdditionalIndentOptions.isEmpty()) {
theEditor = myOtherIndentOptions;
}
else {
theEditor = myAdditionalIndentOptions.values().iterator().next();
}
return theEditor;
return myAdditionalIndentOptions.isEmpty() ? myOtherIndentOptions : myAdditionalIndentOptions.values().iterator().next();
}
private int getRightMarginImpl() {
@@ -275,18 +263,16 @@ public class GeneralCodeStylePanel extends CodeStyleAbstractPanel {
return true;
}
for(FileType fileType: myAdditionalIndentOptions.keySet()) {
if (myAdditionalIndentOptions.get(fileType).isModified(settings, settings.getAdditionalIndentOptions(fileType))) {
for(Map.Entry<FileType, IndentOptionsEditor> entry : myAdditionalIndentOptions.entrySet()) {
IndentOptionsEditor editor = entry.getValue();
FileType fileType = entry.getKey();
if (editor.isModified(settings, settings.getAdditionalIndentOptions(fileType))) {
return true;
}
}
}
if (!myRightMarginField.getText().equals(String.valueOf(settings.RIGHT_MARGIN))) {
return true;
}
return false;
return !myRightMarginField.getText().equals(String.valueOf(settings.RIGHT_MARGIN));
}
public JComponent getPanel() {
@@ -299,14 +285,15 @@ public class GeneralCodeStylePanel extends CodeStyleAbstractPanel {
myOtherIndentOptions.reset(settings, settings.OTHER_INDENT_OPTIONS);
boolean first = true;
for(FileType fileType: myAdditionalIndentOptions.keySet()) {
final IndentOptionsEditor editor = myAdditionalIndentOptions.get(fileType);
for(Map.Entry<FileType, IndentOptionsEditor> entry : myAdditionalIndentOptions.entrySet()) {
final IndentOptionsEditor editor = entry.getValue();
if (settings.USE_SAME_INDENTS && first) {
first = false;
editor.reset(settings, settings.OTHER_INDENT_OPTIONS);
}
else {
editor.reset(settings, settings.getAdditionalIndentOptions(fileType));
FileType type = entry.getKey();
editor.reset(settings, settings.getAdditionalIndentOptions(type));
}
}
@@ -53,8 +53,9 @@ public class BooleanTableCellRenderer extends JCheckBox implements TableCellRend
setBackground(table.getBackground());
}
if (value instanceof String) {
setSelected((Boolean.parseBoolean((String)value)));
} else {
setSelected(Boolean.parseBoolean((String)value));
}
else {
setSelected(((Boolean)value).booleanValue());
}
return this;
@@ -165,8 +165,20 @@ public class DefaultJDOMExternalizer {
Field field = data.getClass().getField(fieldName);
Class type = field.getType();
int modifiers = field.getModifiers();
if ((modifiers & Modifier.PUBLIC) == 0 || (modifiers & Modifier.STATIC) != 0 || (modifiers & Modifier.FINAL) != 0) continue;
if ((modifiers & Modifier.PUBLIC) == 0 || (modifiers & Modifier.STATIC) != 0) continue;
field.setAccessible(true); // class might be non-public
if ((modifiers & Modifier.FINAL) != 0) {
// read external contents of final field
Object value = field.get(data);
if (ReflectionCache.isInstance(value, JDOMExternalizable.class)) {
final List children = e.getChildren("value");
for (Object child : children) {
Element valueTag = (Element)child;
((JDOMExternalizable)value).readExternal(valueTag);
}
}
continue;
}
String value = e.getAttributeValue("value");
if (type.isPrimitive()) {
if (value != null) {
@@ -1274,17 +1274,20 @@ public class StringUtil {
return result;
}
public static int countNewLines(final CharSequence text) {
int lineShift = 0;
public static int countNewLines(@NotNull CharSequence text) {
return countChars(text, '\n');
}
public static int countChars(@NotNull CharSequence text, char c) {
int count = 0;
for(int i = 0; i < text.length(); ++i) {
final char ch = text.charAt(i);
if (ch == '\n') {
++lineShift;
if (ch == c) {
++count;
}
}
return lineShift;
return count;
}
public static String capitalsOnly(String s) {
@@ -31,7 +31,7 @@ public class ClassMap<T> {
this(new THashMap<Class, T>());
}
protected ClassMap(Map<Class, T> map) {
myMap = map;
myMap = map;
}
public void put(Class aClass, T value) {
@@ -67,4 +67,8 @@ public class ClassMap<T> {
public final Collection<T> values() {
return myMap.values();
}
public void clear() {
myMap.clear();
}
}