package org.infernus.idea.checkstyle.ui; import org.infernus.idea.checkstyle.CheckStyleBundle; import org.infernus.idea.checkstyle.model.ConfigurationLocation; import org.jetbrains.annotations.Nullable; import javax.swing.table.AbstractTableModel; import java.util.ArrayList; import java.util.Collections; import java.util.List; /** * A table model for editing CheckStyle file locations. */ public class LocationTableModel extends AbstractTableModel { private static final long serialVersionUID = -7914774770821623832L; private static final int COLUMN_ACTIVE = 0; private static final int COLUMN_DESCRIPTION = 1; private static final int COLUMN_FILE = 2; private static final int NUMBER_OF_COLUMNS = 3; private final List<ConfigurationLocation> locations = new ArrayList<>(); private ConfigurationLocation activeLocation; /** * Create a new empty table model. */ public LocationTableModel() { } public void setLocations(final List<ConfigurationLocation> newLocations) { locations.clear(); if (newLocations != null) { locations.addAll(newLocations); } if (activeLocation != null && !locations.contains(activeLocation)) { activeLocation = null; } fireTableDataChanged(); } public void addLocation(final ConfigurationLocation location) { if (location != null) { locations.add(location); fireTableRowsInserted(locations.size() - 1, locations.size() - 1); } } public void updateLocation(final ConfigurationLocation location, final ConfigurationLocation newLocation) { if (location != null && newLocation != null) { final int index = locations.indexOf(location); if (index != -1) { locations.remove(index); locations.add(index, newLocation); fireTableRowsUpdated(index, index); } } } public void removeLocationAt(final int index) { if (equals(locations.get(index), activeLocation)) { setActiveLocation(null); } locations.remove(index); fireTableRowsDeleted(index, index); } public ConfigurationLocation getLocationAt(final int index) { return locations.get(index); } public void setActiveLocation(@Nullable final ConfigurationLocation activeLocation) { if (activeLocation != null && !locations.contains(activeLocation)) { throw new IllegalArgumentException("Active location is not in location list"); } if (activeLocation != null) { updateActiveLocation(activeLocation, locations.indexOf(activeLocation), false); } else { updateActiveLocation(null, -1, false); } } private void updateActiveLocation(@Nullable final ConfigurationLocation newLocation, final int newRow, final boolean allowToggle) { int oldRow = -1; for (int currentRow = 0; currentRow < locations.size(); ++currentRow) { if (equals(locations.get(currentRow), this.activeLocation)) { oldRow = currentRow; break; } } if (oldRow == newRow && allowToggle) { this.activeLocation = null; } else { this.activeLocation = newLocation; } if (newRow >= 0) { fireTableCellUpdated(newRow, COLUMN_ACTIVE); } if (oldRow >= 0) { fireTableCellUpdated(oldRow, COLUMN_ACTIVE); } } /* * This is a port from commons-lang 2.4, in order to get around the absence of commons-lang in * some packages of IDEA 7.x. */ private boolean equals(final Object object1, final Object object2) { if (object1 == object2) { return true; } if ((object1 == null) || (object2 == null)) { return false; } return object1.equals(object2); } public ConfigurationLocation getActiveLocation() { return activeLocation; } /** * Clear all data from this table model. */ public void clear() { locations.clear(); fireTableDataChanged(); } /** * Get the properties from the table. * * @return the map of properties to values. */ public List<ConfigurationLocation> getLocations() { return Collections.unmodifiableList(locations); } @Override public int getColumnCount() { return NUMBER_OF_COLUMNS; } @Override public Class<?> getColumnClass(final int columnIndex) { if (columnIndex == COLUMN_ACTIVE) { return Boolean.class; } else { return String.class; } } @Override public String getColumnName(final int column) { return CheckStyleBundle.message("config.file.locations.table." + column); } @Override public boolean isCellEditable(final int rowIndex, final int columnIndex) { return columnIndex == COLUMN_ACTIVE; } @Override public void setValueAt(final Object aValue, final int rowIndex, final int columnIndex) { final ConfigurationLocation rowLocation = locations.get(rowIndex); if (columnIndex == COLUMN_ACTIVE) { updateActiveLocation(rowLocation, rowIndex, true); } else { throw new IllegalArgumentException("Column is not editable: " + columnIndex); } } @Override public int getRowCount() { return locations.size(); } @Override public Object getValueAt(final int rowIndex, final int columnIndex) { switch (columnIndex) { case COLUMN_ACTIVE: return equals(locations.get(rowIndex), activeLocation); case COLUMN_DESCRIPTION: return locations.get(rowIndex).getDescription(); case COLUMN_FILE: return locations.get(rowIndex).getLocation(); default: throw new IllegalArgumentException("Invalid column: " + columnIndex); } } }