/* * 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.project.DevKit; import jetbrains.mps.smodel.Language; import jetbrains.mps.smodel.ModelAccessHelper; import jetbrains.mps.smodel.adapter.structure.MetaAdapterFactory; import jetbrains.mps.smodel.language.LanguageRegistry; import jetbrains.mps.util.Computable; import org.jetbrains.annotations.NotNull; import org.jetbrains.mps.openapi.language.SLanguage; import org.jetbrains.mps.openapi.module.SModule; import org.jetbrains.mps.openapi.module.SModuleReference; import org.jetbrains.mps.openapi.module.SRepository; import org.jetbrains.mps.util.Condition; import javax.swing.table.AbstractTableModel; import java.util.ArrayList; import java.util.Collection; import java.util.List; public class UsedLangsTableModel extends AbstractTableModel implements ItemRemovable { private final SRepository myRepository; private final String myColumnName; private List<SLanguage> myLanguageItems = new ArrayList<SLanguage>(); private List<SModuleReference> myDevKitItems = new ArrayList<SModuleReference>(); public static final int ITEM_COLUMN = 0; private Collection<SLanguage> myInitialLanguages; private Collection<SModuleReference> myInitialDevKits; public UsedLangsTableModel(SRepository repository) { this(repository, PropertiesBundle.message("mps.properties.configurable.tablemodel.usedlanguages.column.item")); } public UsedLangsTableModel(SRepository repository, String columnName) { myRepository = repository; myColumnName = columnName; } public void init(Collection<SLanguage> usedLanguages, Collection<SModuleReference> usedDevKits) { myInitialLanguages = usedLanguages; myInitialDevKits = usedDevKits; myLanguageItems.addAll(usedLanguages); myDevKitItems.addAll(usedDevKits); } public void addItem(final SModuleReference item) { SModule m = new ModelAccessHelper(myRepository).runReadAction(new Computable<SModule>() { @Override public SModule compute() { return item.resolve(myRepository); } }); if (m instanceof Language) { final SLanguage lang = MetaAdapterFactory.getLanguage(item); addItem(lang); } else if (m instanceof DevKit) { if (!myDevKitItems.contains(item)) { myDevKitItems.add(item); } } } public void addItem(SLanguage lang) { if (!myLanguageItems.contains(lang)) { myLanguageItems.add(lang); } } @Override public void removeRow(int idx) { if (idx >= myLanguageItems.size()) { idx -= myLanguageItems.size(); myDevKitItems.remove(idx); } else { myLanguageItems.remove(idx); } } @Override public int getRowCount() { return myLanguageItems.size() + myDevKitItems.size(); } @Override public int getColumnCount() { return 1; } @Override public String getColumnName(int column) { assert column == ITEM_COLUMN; return myColumnName; } @Override public Class<?> getColumnClass(int columnIndex) { if(columnIndex == ITEM_COLUMN) { return Import.class; } return super.getColumnClass(columnIndex); } @Override public Object getValueAt(int rowIndex, int columnIndex) { assert columnIndex == ITEM_COLUMN; return getValueAt(rowIndex); } public Import getValueAt(int rowIndex) { if (rowIndex >= myLanguageItems.size()) { rowIndex -= myLanguageItems.size(); return new Import(myDevKitItems.get(rowIndex)); } else { return new Import(myLanguageItems.get(rowIndex)); } } public boolean isModified() { return !(myLanguageItems.containsAll(myInitialLanguages) && myInitialLanguages.containsAll(myLanguageItems) && myDevKitItems.containsAll(myInitialDevKits) && myInitialDevKits.containsAll(myDevKitItems) ); } public void fillResult(Collection<SLanguage> languages, Collection<SModuleReference> devkits) { languages.addAll(myLanguageItems); devkits.addAll(myDevKitItems); } // union (SLanguage | DevKit) public static final class Import { public final SLanguage myLanguage; public final SModuleReference myDevKit; public Import(SLanguage lang) { myLanguage = lang; myDevKit = null; } public Import(SModuleReference devkit) { myDevKit = devkit; myLanguage = null; } @Override public int hashCode() { return 31 * (myLanguage == null ? myDevKit.hashCode() : myLanguage.hashCode()); } @Override public boolean equals(Object obj) { if (obj instanceof Import) { Import o = (Import) obj; return myLanguage == o.myLanguage && myDevKit == o.myDevKit; } return false; } @Override public String toString() { return myLanguage != null ? myLanguage.getQualifiedName() : myDevKit.getModuleName(); } } public static final class ValidImportCondition implements Condition<Import> { private final SRepository myContextRepo; private final LanguageRegistry myLanguageRegistry; public ValidImportCondition(@NotNull SRepository contextRepo) { myContextRepo = contextRepo; myLanguageRegistry = LanguageRegistry.getInstance(contextRepo); } @Override public boolean met(Import anImport) { if (anImport.myLanguage != null) { return myLanguageRegistry.getLanguage(anImport.myLanguage) != null; } return anImport.myDevKit.resolve(myContextRepo) != null; } } }