/* * 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;} }