blob: 6a2cd877faf8d14140210110ed6a85a806f2fbfb [file] [log] [blame]
/*
* Copyright 2000-2012 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.openapi.compiler.options;
import com.intellij.compiler.CompilerConfiguration;
import com.intellij.ide.IdeBundle;
import com.intellij.openapi.compiler.CompilerBundle;
import com.intellij.openapi.fileChooser.FileChooser;
import com.intellij.openapi.fileChooser.FileChooserDescriptor;
import com.intellij.openapi.options.UnnamedConfigurable;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.vcs.FileStatusManager;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.ui.*;
import com.intellij.ui.table.JBTable;
import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.table.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.Arrays;
public class ExcludedEntriesConfigurable implements UnnamedConfigurable {
private final Project myProject;
private final ArrayList<ExcludeEntryDescription> myExcludeEntryDescriptions = new ArrayList<ExcludeEntryDescription>();
private final FileChooserDescriptor myDescriptor;
private final ExcludedEntriesConfiguration myConfiguration;
private ExcludedEntriesPanel myExcludedEntriesPanel;
public ExcludedEntriesConfigurable(Project project) {
this(project, new FileChooserDescriptor(true, true, false, false, false, true),
CompilerConfiguration.getInstance(project).getExcludedEntriesConfiguration());
}
public ExcludedEntriesConfigurable(Project project, FileChooserDescriptor descriptor, final ExcludedEntriesConfiguration configuration) {
myDescriptor = descriptor;
myConfiguration = configuration;
myProject = project;
}
public void reset() {
ExcludeEntryDescription[] descriptions = myConfiguration.getExcludeEntryDescriptions();
disposeMyDescriptions();
for (ExcludeEntryDescription description : descriptions) {
myExcludeEntryDescriptions.add(description.copy(myProject));
}
((AbstractTableModel)myExcludedEntriesPanel.myExcludedTable.getModel()).fireTableDataChanged();
}
public void addEntry(ExcludeEntryDescription description) {
myExcludeEntryDescriptions.add(description);
((AbstractTableModel)myExcludedEntriesPanel.myExcludedTable.getModel()).fireTableDataChanged();
}
private void disposeMyDescriptions() {
for (ExcludeEntryDescription description : myExcludeEntryDescriptions) {
Disposer.dispose(description);
}
myExcludeEntryDescriptions.clear();
}
public void apply() {
myConfiguration.removeAllExcludeEntryDescriptions();
for (ExcludeEntryDescription description : myExcludeEntryDescriptions) {
myConfiguration.addExcludeEntryDescription(description.copy(myProject));
}
FileStatusManager.getInstance(myProject).fileStatusesChanged(); // refresh exclude from compile status
}
public boolean isModified() {
ExcludeEntryDescription[] excludeEntryDescriptions = myConfiguration.getExcludeEntryDescriptions();
if(excludeEntryDescriptions.length != myExcludeEntryDescriptions.size()) {
return true;
}
for(int i = 0; i < excludeEntryDescriptions.length; i++) {
ExcludeEntryDescription description = excludeEntryDescriptions[i];
if(!Comparing.equal(description, myExcludeEntryDescriptions.get(i))) {
return true;
}
}
return false;
}
public JComponent createComponent() {
if (myExcludedEntriesPanel == null) {
myExcludedEntriesPanel = new ExcludedEntriesPanel();
}
return myExcludedEntriesPanel;
}
public void disposeUIResources() {
myExcludedEntriesPanel = null;
}
private class ExcludedEntriesPanel extends PanelWithButtons {
private JButton myRemoveButton;
private JBTable myExcludedTable;
public ExcludedEntriesPanel() {
initPanel();
}
protected String getLabelText(){
return null;
}
protected JButton[] createButtons(){
final JButton addButton = new JButton(IdeBundle.message("button.add"));
addButton.addActionListener(
new ActionListener() {
public void actionPerformed(ActionEvent e){
addPath(myDescriptor);
}
}
);
myRemoveButton = new JButton(IdeBundle.message("button.remove"));
myRemoveButton.addActionListener(
new ActionListener(){
public void actionPerformed(ActionEvent e){
removePaths();
}
}
);
myRemoveButton.setEnabled(false);
myRemoveButton.getModel().addChangeListener(new ChangeListener() {
public void stateChanged(ChangeEvent e) {
if (myExcludedTable.getSelectedRow() == -1) {
myRemoveButton.setEnabled(false);
}
}
});
return new JButton[]{/*addButton, myRemoveButton*/};
}
private void addPath(FileChooserDescriptor descriptor) {
int selected = -1 /*myExcludedTable.getSelectedRow() + 1*/;
if(selected < 0) {
selected = myExcludeEntryDescriptions.size();
}
int savedSelected = selected;
VirtualFile[] chosen = FileChooser.chooseFiles(descriptor, myProject, null);
for (final VirtualFile chosenFile : chosen) {
if (isFileExcluded(chosenFile)) {
continue;
}
ExcludeEntryDescription description;
if (chosenFile.isDirectory()) {
description = new ExcludeEntryDescription(chosenFile, true, false, myProject);
}
else {
description = new ExcludeEntryDescription(chosenFile, false, true, myProject);
}
myExcludeEntryDescriptions.add(selected, description);
selected++;
}
if (selected > savedSelected) { // actually added something
AbstractTableModel model = (AbstractTableModel)myExcludedTable.getModel();
model.fireTableRowsInserted(savedSelected, selected-1);
myExcludedTable.setRowSelectionInterval(savedSelected, selected - 1);
}
}
private boolean isFileExcluded(VirtualFile file) {
for (final ExcludeEntryDescription description : myExcludeEntryDescriptions) {
final VirtualFile descriptionFile = description.getVirtualFile();
if (descriptionFile == null) {
continue;
}
if (file.equals(descriptionFile)) {
return true;
}
}
return false;
}
private void removePaths() {
int[] selected = myExcludedTable.getSelectedRows();
if(selected == null || selected.length <= 0) {
return;
}
if(myExcludedTable.isEditing()) {
TableCellEditor editor = myExcludedTable.getCellEditor();
if (editor != null) {
editor.stopCellEditing();
}
}
AbstractTableModel model = (AbstractTableModel)myExcludedTable.getModel();
Arrays.sort(selected);
int indexToSelect = selected[selected.length - 1];
int removedCount = 0;
for (int indexToRemove : selected) {
final int row = indexToRemove - removedCount;
ExcludeEntryDescription description = myExcludeEntryDescriptions.get(row);
Disposer.dispose(description);
myExcludeEntryDescriptions.remove(row);
model.fireTableRowsDeleted(row, row);
removedCount += 1;
}
if(indexToSelect >= myExcludeEntryDescriptions.size()) {
indexToSelect = myExcludeEntryDescriptions.size() - 1;
}
if(indexToSelect >= 0) {
myExcludedTable.setRowSelectionInterval(indexToSelect, indexToSelect);
}
myExcludedTable.requestFocus();
}
protected JComponent createMainComponent(){
final String[] names = {
CompilerBundle.message("exclude.from.compile.table.path.column.name"),
CompilerBundle.message("exclude.from.compile.table.recursively.column.name")
};
// Create a model of the data.
TableModel dataModel = new AbstractTableModel() {
public int getColumnCount() {
return names.length;
}
public int getRowCount() {
return myExcludeEntryDescriptions.size();
}
public Object getValueAt(int row, int col) {
ExcludeEntryDescription description = myExcludeEntryDescriptions.get(row);
if(col == 0) {
return description.getPresentableUrl();
}
if(col == 1) {
if(!description.isFile()) {
return description.isIncludeSubdirectories() ? 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;
}
public boolean isCellEditable(int row, int col) {
if(col == 1) {
ExcludeEntryDescription description = myExcludeEntryDescriptions.get(row);
return !description.isFile();
}
return true;
}
public void setValueAt(Object aValue, int row, int col) {
ExcludeEntryDescription description = myExcludeEntryDescriptions.get(row);
if (col == 1) {
description.setIncludeSubdirectories(aValue.equals(Boolean.TRUE));
} else {
final String path = (String)aValue;
description.setPresentableUrl(path);
}
}
};
myExcludedTable = new JBTable(dataModel);
myExcludedTable.setEnableAntialiasing(true);
myExcludedTable.getEmptyText().setText(CompilerBundle.message("no.excludes"));
myExcludedTable.setPreferredScrollableViewportSize(new Dimension(300, myExcludedTable.getRowHeight() * 6));
myExcludedTable.setDefaultRenderer(Boolean.class, new BooleanRenderer());
myExcludedTable.setDefaultRenderer(Object.class, new MyObjectRenderer());
myExcludedTable.getColumn(names[0]).setPreferredWidth(350);
final int cbWidth = 15 + myExcludedTable.getTableHeader().getFontMetrics(myExcludedTable.getTableHeader().getFont()).stringWidth(names[1]);
final TableColumn cbColumn = myExcludedTable.getColumn(names[1]);
cbColumn.setPreferredWidth(cbWidth);
cbColumn.setMaxWidth(cbWidth);
myExcludedTable.getSelectionModel().setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
myExcludedTable.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
public void valueChanged(ListSelectionEvent e) {
myRemoveButton.setEnabled(myExcludedTable.getSelectedRow() >= 0);
}
});
TableCellEditor editor = myExcludedTable.getDefaultEditor(String.class);
if(editor instanceof DefaultCellEditor) {
((DefaultCellEditor)editor).setClickCountToStart(1);
}
return ToolbarDecorator.createDecorator(myExcludedTable)
.disableUpAction()
.disableDownAction()
.setAddAction(new AnActionButtonRunnable() {
@Override
public void run(AnActionButton anActionButton) {
addPath(myDescriptor);
}
})
.setRemoveAction(new AnActionButtonRunnable() {
@Override
public void run(AnActionButton anActionButton) {
removePaths();
}
}).createPanel();
//return ScrollPaneFactory.createScrollPane(myExcludedTable);
}
}
private static class BooleanRenderer extends JCheckBox implements TableCellRenderer {
private final JPanel myPanel = new JPanel();
public BooleanRenderer() {
setHorizontalAlignment(CENTER);
}
public Component getTableCellRendererComponent(JTable table, Object value,
boolean isSelected, boolean hasFocus,
int row, int column) {
if(value == null) {
if(isSelected) {
myPanel.setBackground(table.getSelectionBackground());
}
else {
myPanel.setBackground(table.getBackground());
}
return myPanel;
}
if(isSelected) {
setForeground(table.getSelectionForeground());
super.setBackground(table.getSelectionBackground());
}
else {
setForeground(table.getForeground());
setBackground(table.getBackground());
}
setSelected(((Boolean)value).booleanValue());
return this;
}
}
private class MyObjectRenderer extends DefaultTableCellRenderer {
public MyObjectRenderer() {
setUI(new RightAlignedLabelUI());
}
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
final Component component = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
final ExcludeEntryDescription description = myExcludeEntryDescriptions.get(row);
component.setForeground(!description.isValid() ? JBColor.RED : isSelected ? table.getSelectionForeground() : table.getForeground());
component.setBackground(isSelected ? table.getSelectionBackground() : table.getBackground());
return component;
}
}
}