package jetbrains.mps.ide.icons; /*Generated by MPS */ import org.apache.log4j.Logger; import org.apache.log4j.LogManager; import java.awt.MediaTracker; import java.util.Map; import org.jetbrains.mps.openapi.language.SAbstractConcept; import jetbrains.mps.smodel.runtime.IconResource; import jetbrains.mps.internal.collections.runtime.MapSequence; import java.util.HashMap; import javax.swing.Icon; import java.util.Set; import jetbrains.mps.module.ReloadableModule; import org.jetbrains.annotations.NotNull; import org.jetbrains.mps.openapi.model.SNode; import jetbrains.mps.lang.smodel.generator.smodelAdapter.SNodeOperations; import jetbrains.mps.lang.smodel.generator.smodelAdapter.SConceptOperations; import jetbrains.mps.smodel.adapter.structure.MetaAdapterFactory; import org.jetbrains.mps.openapi.model.SModel; import jetbrains.mps.smodel.language.LanguageAspectDescriptor; import jetbrains.mps.smodel.language.LanguageAspectSupport; import jetbrains.mps.smodel.SModelStereotype; import jetbrains.mps.smodel.Language; import org.jetbrains.mps.openapi.module.SModule; import jetbrains.mps.smodel.Generator; import jetbrains.mps.project.Solution; import jetbrains.mps.project.DevKit; import jetbrains.mps.smodel.language.ConceptRegistry; import org.jetbrains.mps.openapi.model.EditableSModel; import com.intellij.ui.LayeredIcon; import com.intellij.util.PlatformIcons; import com.intellij.ui.RowIcon; import jetbrains.mps.smodel.behaviour.BHReflection; import jetbrains.mps.core.aspects.behaviour.SMethodTrimmedId; import java.util.List; import jetbrains.mps.internal.collections.runtime.ListSequence; import jetbrains.mps.internal.collections.runtime.ISelector; import jetbrains.mps.internal.collections.runtime.IWhereFilter; import jetbrains.mps.smodel.adapter.structure.concept.SAbstractConceptAdapter; import jetbrains.mps.smodel.adapter.structure.concept.SConceptAdapter; import jetbrains.mps.smodel.runtime.ConceptPresentation; import org.jetbrains.annotations.Nullable; import com.intellij.openapi.util.IconLoader; import java.io.InputStream; import java.io.IOException; import org.apache.log4j.Level; import javax.swing.ImageIcon; public class BaseIconManager { private static final Logger LOG = LogManager.getLogger(BaseIconManager.class); private static final int IMAGE_LOADED = ~(((MediaTracker.ABORTED | MediaTracker.ERRORED | MediaTracker.LOADING))); private Map<SAbstractConcept, IconResource> myConceptToIcon = MapSequence.fromMap(new HashMap<SAbstractConcept, IconResource>()); private Map<IconResource, Icon> myResToIcon = MapSequence.fromMap(new HashMap<IconResource, Icon>()); public void invalidate(Set<ReloadableModule> modules) { // todo by-module invalidation MapSequence.fromMap(myConceptToIcon).clear(); MapSequence.fromMap(myResToIcon).clear(); } public Icon getIconFor(SAbstractConcept concept) { IconResource cached = MapSequence.fromMap(myConceptToIcon).get(concept); if (!(MapSequence.fromMap(myConceptToIcon).containsKey(concept))) { IconResource ir = getIconForConceptNoCache(concept); MapSequence.fromMap(myConceptToIcon).put(concept, ir); } IconResource actual = MapSequence.fromMap(myConceptToIcon).get(concept); if (actual == null) { return IdeIcons.DEFAULT_CONCEPT_ICON; } Icon icon = getIconForResource(actual); if (icon == null) { return IdeIcons.DEFAULT_CONCEPT_ICON; } return icon; } public Icon getIconFor(@NotNull final SNode node) { if (!(SNodeOperations.getConcept(node).isValid())) { return IdeIcons.UNKNOWN_ICON; } Icon mainIcon = null; if (SConceptOperations.isSubConceptOf(SNodeOperations.asSConcept(SNodeOperations.getConcept(node)), MetaAdapterFactory.getConcept(0xc72da2b97cce4447L, 0x8389f407dc1158b7L, 0xf979ba0450L, "jetbrains.mps.lang.structure.structure.ConceptDeclaration"))) { mainIcon = getIconFromConstraints(node); } if (mainIcon == null) { mainIcon = getIconFor(SNodeOperations.getConcept(node)); } if (mainIcon == null) { if ((SNodeOperations.getParent(node) == null)) { return IdeIcons.DEFAULT_ROOT_ICON; } else { return IdeIcons.DEFAULT_NODE_ICON; } } return addIconFeatures(mainIcon, node); } public Icon getIconFor(SModel model) { if (model == null) { return IdeIcons.UNKNOWN_ICON; } LanguageAspectDescriptor newAspect = LanguageAspectSupport.getNewAspect(model); if (newAspect != null) { return getIconForResource(newAspect.getIconResource()); } if (SModelStereotype.isGeneratorModel(model)) { return IdeIcons.TEMPLATES_MODEL_ICON; } if (Language.isLanguageOwnedAccessoryModel(model)) { return IdeIcons.ACCESSORY_MODEL_ICON; } if (SModelStereotype.isTestModel(model)) { return IdeIcons.TEST_MODEL_ICON; } return IdeIcons.MODEL_ICON; } public Icon getIconFor(SModule module) { if (module instanceof Generator) { return IdeIcons.GENERATOR_ICON; } if (module instanceof Language) { return IdeIcons.LANGUAGE_ICON; } if (module instanceof Solution) { return IdeIcons.SOLUTION_ICON; } if (module instanceof DevKit) { return IdeIcons.DEVKIT_ICON; } return IdeIcons.DEFAULT_ICON; } private Icon getIconFromConstraints(final SNode node) { IconResource altIcon = ConceptRegistry.getInstance().getConstraintsDescriptor(SNodeOperations.getConcept(node)).getInstanceIcon(node); if (altIcon == null) { return null; } return getIconForResource(altIcon); } private Icon addIconFeatures(Icon mainIcon, final SNode node) { SModel model = SNodeOperations.getModel(node); if (model == null) { return mainIcon; } if ((!((model instanceof EditableSModel))) || ((EditableSModel) model).isReadOnly()) { mainIcon = new LayeredIcon(mainIcon, PlatformIcons.LOCKED_ICON); } RowIcon result = new RowIcon(2); result.setIcon(mainIcon, 0); result.setIcon(getIconForResource(((IconResource) BHReflection.invoke(node, SMethodTrimmedId.create("getSideIcon", null, "6TtJ6IUjtJX")))), 1); List<Icon> markIcons = ListSequence.fromList(((List<IconResource>) BHReflection.invoke(node, SMethodTrimmedId.create("getIconMarks", null, "6TtJ6IUkhQJ")))).select(new ISelector<IconResource, Icon>() { public Icon select(IconResource it) { return getIconForResource(it); } }).where(new IWhereFilter<Icon>() { public boolean accept(Icon it) { return it != null; } }).toListSequence(); if (ListSequence.fromList(markIcons).isNotEmpty()) { LayeredIcon layeredIcon = new LayeredIcon(ListSequence.fromList(markIcons).count() + 1); layeredIcon.setIcon(result, 0); for (int i = 0; i < ListSequence.fromList(markIcons).count(); i++) { layeredIcon.setIcon(ListSequence.fromList(markIcons).getElement(i), i + 1); } return layeredIcon; } return result; } private IconResource getIconForConceptNoCache(SAbstractConcept concept) { SAbstractConceptAdapter current = ((SAbstractConceptAdapter) concept); while (current != null) { IconResource ir = getIconForExactConcept(current); if (ir != null) { return ir; } current = ((current instanceof SConceptAdapter) ? ((SConceptAdapter) ((SConceptAdapter) current).getSuperConcept()) : null); } return null; } private IconResource getIconForExactConcept(SAbstractConcept concept) { ConceptPresentation pres = ConceptRegistry.getInstance().getConceptProperties(concept); if (pres == null) { return null; } return pres.getIcon(); } public Icon getIconForResource(@Nullable IconResource ir) { if (ir == null) { return null; } if (ir.isAlreadyReloaded()) { MapSequence.fromMap(myResToIcon).removeKey(ir); } if (MapSequence.fromMap(myResToIcon).containsKey(ir)) { return MapSequence.fromMap(myResToIcon).get(ir); } Icon icon = IconLoader.findIcon(ir.getResourceId(), ir.getProvider()); if (icon == null) { return null; } MapSequence.fromMap(myResToIcon).put(ir, icon); return icon; } private Icon loadIcon(@NotNull InputStream is) { byte[] image = new byte[0]; try { image = new byte[is.available()]; } catch (IOException e) { if (LOG.isEnabledFor(Level.ERROR)) { LOG.error("", e); } } try { int current = 0; while (true) { int result = is.read(image, current, image.length - current); if (result == -1 || result == 0) { break; } else { current += result; } } } catch (IOException e) { if (LOG.isEnabledFor(Level.ERROR)) { LOG.error("", e); } } ImageIcon icon = new ImageIcon(image); if ((icon.getImageLoadStatus() & IMAGE_LOADED) != 0) { return icon; } return null; } }