/*
* Copyright 2003-2016 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 jetbrains.mps.ide.ui.dialogs.properties.tables.models;
import com.intellij.util.ui.ItemRemovable;
import jetbrains.mps.ide.ui.dialogs.properties.PropertiesBundle;
import jetbrains.mps.ide.ui.dialogs.properties.tables.items.DependenciesTableItem;
import jetbrains.mps.ide.ui.dialogs.properties.tables.items.DependenciesTableItem.ModuleType;
import jetbrains.mps.project.structure.modules.Dependency;
import org.jetbrains.mps.openapi.module.SDependencyScope;
import org.jetbrains.mps.openapi.ui.Modifiable;
import javax.swing.table.AbstractTableModel;
import java.util.ArrayList;
import java.util.List;
/**
* Collection of Dependency objects as content of a table. Dependency is wrapped into DependenciesTableItem
* to track additional values (model kind and is re-exportable).
* Though this class initially deemed to hold any DependenciesTableItems (with ModuleDependTableModel to address dependencies
* between modules), there seems to be little code reuse with this approach (and high coupling), and new approach is to merge
* both classes into one (as well as ModuleDependenciesTab and DependenciesTab). Alternative is to refactor DTM and DT, (e.g. to
* split DT.getDependTableModel() into create and get, so that subclasses can override getDependTableModel with correct return type
* to use own model without explicit casts; to move ModuleType out from DependenciesTableItem, etc)
* @param <T> WTF?
*/
public abstract class DependTableModel<T> extends AbstractTableModel implements ItemRemovable, Modifiable {
protected List<DependenciesTableItem> myTableItems = new ArrayList<DependenciesTableItem>();
protected T myItem;
private final String myExportColumnName = PropertiesBundle.message("mps.properties.configurable.tablemodel.dependency.column.export");
private final String myRoleColumnName = PropertiesBundle.message("mps.properties.configurable.tablemodel.dependency.column.scope");
public DependTableModel(T item) {
myItem = item;
}
public void addItem(DependenciesTableItem item) {
if(myTableItems.contains(item)) {
// I know it's linear, once proves to take noticeable time, refactor.
return;
}
myTableItems.add(item);
fireTableDataChanged();
}
public void addLanguageItem(Dependency dep) {
addItem(new DependenciesTableItem(dep).setModuleType(ModuleType.LANGUAGE));
}
public void addGeneratorItem(Dependency dep) {
addItem(new DependenciesTableItem(dep).setModuleType(ModuleType.GENERATOR));
}
public void addDevkitItem(Dependency dep) {
addItem(new DependenciesTableItem(dep).setModuleType(ModuleType.DEVKIT));
}
public void addSolutionItem(Dependency dep) {
addItem(new DependenciesTableItem(dep).setModuleType(ModuleType.SOLUTION));
}
public void addUnspecifiedItem(Dependency dep) {
addItem(new DependenciesTableItem(dep).setModuleType(ModuleType.UNSPECIFIED));
}
public T getSource() {
return myItem;
}
@Override
public void removeRow(int idx) {
myTableItems.remove(idx);
}
@Override
public int getRowCount() {
return myTableItems.size();
}
@Override
public int getColumnCount() {
return 3;
}
@Override
public String getColumnName(int column) {
if(column == this.getRoleColumnIndex())
return myRoleColumnName;
if(column == this.getExportColumnIndex())
return myExportColumnName;
return "";
}
@Override
public Class<?> getColumnClass(int columnIndex) {
if(columnIndex == this.getItemColumnIndex())
return DependenciesTableItem.class; // @see getValueAt, below
if(columnIndex == this.getExportColumnIndex())
return Boolean.class;
if(columnIndex == this.getRoleColumnIndex())
return SDependencyScope.class;
return super.getColumnClass(columnIndex);
}
public DependenciesTableItem getValueAt(int rowIndex) {
return myTableItems.get(rowIndex);
}
@Override
public Object getValueAt(int rowIndex, int columnIndex) {
final DependenciesTableItem tableItem = myTableItems.get(rowIndex);
Dependency item = tableItem.getItem();
if(columnIndex == this.getItemColumnIndex()) {
// There's ugly hack in MPSPropertiesConfigurable, where CellRenderer(SModuleReference) is installed for DependenciesTableItem.
// I'm not aware of a reason for that.
return item.getModuleRef();
}
if(columnIndex == this.getRoleColumnIndex())
return item.getScope().toString();
if(columnIndex == this.getExportColumnIndex() && tableItem.isReExportable()) {
return item.isReexport();
}
return null;
}
@Override
public boolean isCellEditable(int rowIndex, int columnIndex) {
if(columnIndex == this.getExportColumnIndex()) {
final DependenciesTableItem item = myTableItems.get(rowIndex);
return item != null && item.isReExportable();
}
return false;
}
@Override
public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
final DependenciesTableItem item = myTableItems.get(rowIndex);
if (columnIndex == this.getExportColumnIndex() && aValue instanceof Boolean) {
item.setReExport((Boolean)aValue);
}
else if (columnIndex == this.getRoleColumnIndex() && aValue instanceof SDependencyScope) {
item.setRole((SDependencyScope)aValue);
}
}
public int getExportColumnIndex() {return 0;}
public int getItemColumnIndex() {return 1;}
public int getRoleColumnIndex() {return 2;}
}