blob: 787391c405a711533927b7a24861fc42c79a71da [file] [log] [blame]
/*
* Copyright 2000-2014 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.compiler.options;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleManager;
import com.intellij.openapi.module.ModuleType;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.ui.configuration.ChooseModulesDialog;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.ui.SpeedSearchBase;
import com.intellij.ui.SpeedSearchComparator;
import com.intellij.ui.TableUtil;
import com.intellij.ui.ToolbarDecorator;
import com.intellij.ui.table.JBTable;
import com.intellij.util.ui.EditableModel;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import javax.swing.table.*;
import java.awt.*;
import java.util.*;
import java.util.List;
public class ProcessedModulesTable extends JPanel {
private JBTable myTable = null;
private MyTableModel myTableModel = null;
public ProcessedModulesTable(final Project project) {
super(new BorderLayout());
myTableModel = new MyTableModel(project);
myTable = new JBTable(myTableModel);
myTable.getEmptyText().setText("No modules configured");
//myTable.setShowGrid(false);
myTable.setIntercellSpacing(new Dimension(0, 0));
myTable.setAutoResizeMode(JTable.AUTO_RESIZE_LAST_COLUMN);
myTable.setColumnSelectionAllowed(false);
final TableColumnModel columnModel = myTable.getColumnModel();
final TableColumn dirNameColumn = columnModel.getColumn(myTableModel.DIRNAME_COLUMN_INDEX);
final String title = "Generated Sources Directory Name";
dirNameColumn.setHeaderValue(title);
final JTableHeader tableHeader = myTable.getTableHeader();
final FontMetrics metrics = tableHeader.getFontMetrics(tableHeader.getFont());
final int preferredWidth = metrics.stringWidth(title) + 12;
dirNameColumn.setPreferredWidth(preferredWidth);
dirNameColumn.setMaxWidth(preferredWidth + 20);
dirNameColumn.setCellRenderer(new MyElementColumnCellRenderer());
final TableColumn moduleColumn = columnModel.getColumn(myTableModel.ELEMENT_COLUMN_INDEX);
moduleColumn.setHeaderValue("Module");
moduleColumn.setCellRenderer(new MyElementColumnCellRenderer());
final JPanel panel = ToolbarDecorator.createDecorator(myTable)
.disableUpDownActions()
.setPreferredSize(new Dimension(100, 155))
.createPanel();
add(panel, BorderLayout.CENTER);
final SpeedSearchBase<JBTable> speedSearch = new SpeedSearchBase<JBTable>(myTable) {
public int getSelectedIndex() {
return myTable.getSelectedRow();
}
@Override
protected int convertIndexToModel(int viewIndex) {
return myTable.convertRowIndexToModel(viewIndex);
}
public Object[] getAllElements() {
final int count = myTableModel.getRowCount();
Object[] elements = new Object[count];
for (int idx = 0; idx < count; idx++) {
elements[idx] = myTableModel.getModuleAt(idx);
}
return elements;
}
public String getElementText(Object element) {
return ((Module)element).getName() + " (" + FileUtil.toSystemDependentName(((Module)element).getModuleFilePath()) + ")";
}
public void selectElement(Object element, String selectedText) {
final int count = myTableModel.getRowCount();
for (int row = 0; row < count; row++) {
if (element.equals(myTableModel.getModuleAt(row))) {
final int viewRow = myTable.convertRowIndexToView(row);
myTable.getSelectionModel().setSelectionInterval(viewRow, viewRow);
TableUtil.scrollSelectionToVisible(myTable);
break;
}
}
}
};
speedSearch.setComparator(new SpeedSearchComparator(false));
}
public void refresh() {
myTableModel.fireTableDataChanged();
}
public void refresh(Module element) {
final int row = myTableModel.getElementRow(element);
if (row >= 0) {
myTableModel.fireTableRowsUpdated(row, row);
}
}
private int[] mySavedSelection = null;
public void saveSelection() {
mySavedSelection = myTable.getSelectedRows();
}
public void restoreSelection() {
if (mySavedSelection != null) {
TableUtil.selectRows(myTable, mySavedSelection);
mySavedSelection = null;
}
}
public void addModule(Module element, String dirName) {
myTableModel.addElement(element, dirName);
selectRow(myTableModel.getRowCount() - 1);
myTable.requestFocus();
}
public void removeModule(Module element) {
final int elementRow = myTableModel.getElementRow(element);
if (elementRow < 0) {
return; // no such element
}
final boolean wasSelected = myTable.getSelectionModel().isSelectedIndex(elementRow);
myTableModel.removeElement(element);
if (wasSelected) {
final int rowCount = myTableModel.getRowCount();
if (rowCount > 0) {
selectRow(elementRow % rowCount);
}
else {
myTable.getSelectionModel().clearSelection();
}
}
myTable.requestFocus();
}
public void removeAllElements() {
myTableModel.removeAllElements();
myTable.getSelectionModel().clearSelection();
}
private void selectRow(final int row) {
myTable.getSelectionModel().setSelectionInterval(row, row);
myTable.scrollRectToVisible(myTable.getCellRect(row, 0, true));
}
@Nullable
public Module getSelectedElement() {
final int selectedRow = getSelectedElementRow();
return selectedRow < 0? null : myTableModel.getModuleAt(selectedRow);
}
public int getSelectedElementRow() {
return myTable.getSelectedRow();
}
public List<Module> getSelectedElements() {
final List<Module> elements = new ArrayList<Module>();
final int[] selectedRows = myTable.getSelectedRows();
for (int selectedRow : selectedRows) {
if (selectedRow < 0) {
continue;
}
elements.add(myTableModel.getModuleAt(selectedRow));
}
return elements;
}
public void selectElements(Collection<? extends Module> elements) {
if (elements.size() == 0) {
myTable.clearSelection();
return;
}
final int[] rows = getElementsRows(elements);
TableUtil.selectRows(myTable, rows);
TableUtil.scrollSelectionToVisible(myTable);
myTable.requestFocus();
}
private int[] getElementsRows(final Collection<? extends Module> elements) {
final int[] rows = new int[elements.size()];
int index = 0;
for (final Module element : elements) {
rows[index++] = myTableModel.getElementRow(element);
}
return rows;
}
public List<Pair<Module, String>> getAllModules() {
final int count = myTableModel.getRowCount();
List<Pair<Module, String>> elements = new ArrayList<Pair<Module, String>>();
for (int idx = 0; idx < count; idx++) {
final Module module = myTableModel.getModuleAt(idx);
elements.add(Pair.create(module, myTableModel.getGenDirName(module)));
}
return elements;
}
public void sort(Comparator<Module> comparator) {
myTableModel.sort(comparator);
}
public void setEnabled(boolean enabled) {
super.setEnabled(enabled);
myTable.setRowSelectionAllowed(enabled);
myTableModel.fireTableDataChanged();
}
public void stopEditing() {
TableCellEditor editor = myTable.getCellEditor();
if (editor != null) {
editor.stopCellEditing();
}
}
public JComponent getComponent() {
return myTable;
}
public void clear() {
myTableModel.clear();
}
public int getElementCount() {
return myTableModel.getRowCount();
}
public Module getElementAt(int row) {
return myTableModel.getModuleAt(row);
}
private final class MyTableModel extends AbstractTableModel implements EditableModel {
private final List<Module> myElements = new ArrayList<Module>();
private final Map<Module, String> myDirNameMap = new HashMap<Module, String>();
public final int ELEMENT_COLUMN_INDEX = 0;
public final int DIRNAME_COLUMN_INDEX = 1;
private final Project myProject;
private MyTableModel(Project project) {
myProject = project;
}
public void sort(Comparator<Module> comparator) {
Collections.sort(myElements, comparator);
fireTableDataChanged();
}
public List<Module> getAllModules() {
return Collections.unmodifiableList(myElements);
}
public Module getModuleAt(int index) {
return myElements.get(index);
}
public String getGenDirName(Module module) {
return myDirNameMap.get(module);
}
void addElement(Module module, final String dirName) {
myElements.add(module);
if (dirName != null && dirName.length() > 0) {
myDirNameMap.put(module, dirName);
}
int row = myElements.size() - 1;
fireTableRowsInserted(row, row);
}
@Override
public void addRow() {
final Set<Module> projectModules = new HashSet<Module>(Arrays.asList(ModuleManager.getInstance(myProject).getModules()));
projectModules.removeAll(getAllModules());
final ChooseModulesDialog chooser = new ChooseModulesDialog(ProcessedModulesTable.this, new ArrayList<Module>(projectModules), "ChooseModule");
chooser.show();
if (chooser.isOK()) {
final List<Module> chosen = chooser.getChosenElements();
for (Module module : chosen) {
addElement(module, null);
}
}
}
public void removeRow(int idx) {
final Module element = myElements.remove(idx);
myDirNameMap.remove(element);
fireTableRowsDeleted(idx, idx);
}
@Override
public void exchangeRows(int oldIndex, int newIndex) {
}
@Override
public boolean canExchangeRows(int oldIndex, int newIndex) {
return false;
}
public void removeElement(Module element) {
final boolean reallyRemoved = myElements.remove(element);
if (reallyRemoved) {
myDirNameMap.remove(element);
fireTableDataChanged();
}
}
public int getElementRow(Module element) {
return myElements.indexOf(element);
}
public void removeAllElements() {
myElements.clear();
fireTableDataChanged();
}
public int getRowCount() {
return myElements.size();
}
public int getColumnCount() {
return 2;
}
@Nullable
public Object getValueAt(int rowIndex, int columnIndex) {
Module element = myElements.get(rowIndex);
if (columnIndex == ELEMENT_COLUMN_INDEX) {
return element;
}
if (columnIndex == DIRNAME_COLUMN_INDEX) {
return myDirNameMap.get(element);
}
return null;
}
public void setValueAt(Object value, int rowIndex, int columnIndex) {
if (columnIndex == DIRNAME_COLUMN_INDEX) {
final Module module = myElements.get(rowIndex);
if (value != null) {
String dir = FileUtil.toSystemIndependentName((String)value);
while (dir.startsWith("/")) {
dir = dir.substring(1);
}
if (dir.length() > 0) {
myDirNameMap.put(module, dir);
}
else {
myDirNameMap.remove(module);
}
}
else {
myDirNameMap.remove(module);
}
fireTableRowsUpdated(rowIndex, rowIndex);
}
}
public Class getColumnClass(int columnIndex) {
if (columnIndex == DIRNAME_COLUMN_INDEX) {
return String.class;
}
return super.getColumnClass(columnIndex);
}
public boolean isCellEditable(int rowIndex, int columnIndex) {
if (!ProcessedModulesTable.this.isEnabled()) {
return false;
}
if (columnIndex == DIRNAME_COLUMN_INDEX) {
return true;
}
return false;
}
public void clear() {
myElements.clear();
myDirNameMap.clear();
fireTableDataChanged();
}
}
private class MyElementColumnCellRenderer extends DefaultTableCellRenderer {
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
final Color color = UIUtil.getTableFocusCellBackground();
Component component;
final Module module = value instanceof Module? (Module)value : null;
try {
UIManager.put(UIUtil.TABLE_FOCUS_CELL_BACKGROUND_PROPERTY, table.getSelectionBackground());
component = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
if (module != null) {
setText(module.getName() + " (" + FileUtil.toSystemDependentName(module.getModuleFilePath()) + ")");
}
if (component instanceof JLabel) {
((JLabel)component).setBorder(noFocusBorder);
}
}
finally {
UIManager.put(UIUtil.TABLE_FOCUS_CELL_BACKGROUND_PROPERTY, color);
}
component.setEnabled(ProcessedModulesTable.this.isEnabled());
if (component instanceof JLabel) {
final Icon icon = module != null ? ModuleType.get(module).getIcon() : null;
JLabel label = (JLabel)component;
label.setIcon(icon);
label.setDisabledIcon(icon);
}
component.setForeground(isSelected ? table.getSelectionForeground() : table.getForeground());
return component;
}
}
}