package jetbrains.mps.ide.icons; /*Generated by MPS */ import jetbrains.mps.util.annotation.ToRemove; import org.apache.log4j.Logger; import org.apache.log4j.LogManager; import javax.swing.Icon; import java.awt.Component; import java.awt.Graphics; 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 org.jetbrains.mps.openapi.language.SConcept; 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 jetbrains.mps.smodel.ModuleRepositoryFacade; import java.lang.reflect.Method; import jetbrains.mps.module.ModuleClassLoaderIsNullException; import org.jetbrains.annotations.NonNls; import jetbrains.mps.smodel.MPSModuleOwner; import jetbrains.mps.project.MPSProject; import jetbrains.mps.project.AbstractModule; /** * * @deprecated use GlobalIconManager */ @Deprecated @ToRemove(version = 3.5) public final class IconManager { private static final Logger LOG = LogManager.getLogger(IconManager.class); public static final Icon EMPTY_ICON = new Icon() { @Override public void paintIcon(Component c, Graphics g, int x, int y) { } @Override public int getIconWidth() { return 18; } @Override public int getIconHeight() { return 18; } }; @Deprecated private IconManager() { } /** * This field should be used in getIcon(concept) method only */ private static Map<SAbstractConcept, IconResource> ourConceptToIcon = MapSequence.fromMap(new HashMap<SAbstractConcept, IconResource>()); public static Icon getIconFor(SAbstractConcept concept) { // tmp solution to invalidate reloaded icons. May lead to constrained memleaks. Should be rewritten later IconResource cached = MapSequence.fromMap(ourConceptToIcon).get(concept); if (cached != null && cached.isAlreadyReloaded()) { MapSequence.fromMap(ourConceptToIcon).removeKey(concept); } if (!(MapSequence.fromMap(ourConceptToIcon).containsKey(concept))) { IconResource ir = getIconForConceptNoCache(concept); MapSequence.fromMap(ourConceptToIcon).put(concept, ir); } IconResource actual = MapSequence.fromMap(ourConceptToIcon).get(concept); if (actual == null) { return getDefaultConceptIcon(concept); } Icon icon = getIconForResource(actual); if (icon == null) { return getDefaultConceptIcon(concept); } return icon; } private static Icon getDefaultConceptIcon(SAbstractConcept concept) { return (concept instanceof SConcept && ((SConcept) concept).isRootable() ? IdeIcons.DEFAULT_ROOT_ICON : IdeIcons.DEFAULT_CONCEPT_ICON); } public static 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 = IconManager.getIconFromConstraints(node); } if (mainIcon == null) { mainIcon = getIcon(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 static 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 static 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 static Icon getIconFromConstraints(final SNode node) { IconResource altIcon = ConceptRegistry.getInstance().getConstraintsDescriptor(SNodeOperations.getConcept(node)).getInstanceIcon(node); if (altIcon == null) { return null; } return getIconForResource(altIcon); } private static Icon addIconFeatures(Icon mainIcon, final SNode node) { SModel model = SNodeOperations.getModel(node); if (model == null || jetbrains.mps.util.SNodeOperations.isModelDisposed(model)) { 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 static 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 static IconResource getIconForExactConcept(SAbstractConcept concept) { ConceptPresentation pres = ConceptRegistry.getInstance().getConceptProperties(concept); if (pres == null) { return null; } return pres.getIcon(); } /** * This field should be used in getIcon(resource) method only */ private static Map<IconResource, Icon> ourResToIcon = MapSequence.fromMap(new HashMap<IconResource, Icon>()); public static Icon getIconForResource(@Nullable IconResource ir) { if (ir == null) { return null; } if (ir.isAlreadyReloaded()) { MapSequence.fromMap(ourResToIcon).removeKey(ir); } if (MapSequence.fromMap(ourResToIcon).containsKey(ir)) { return MapSequence.fromMap(ourResToIcon).get(ir); } Icon icon; if (ir.getResourceId() != null && ir.getProvider() != null) { icon = IconLoader.findIcon(ir.getResourceId(), ir.getProvider()); if (icon == null) { return null; } } else { // compatibility code till 3.4 InputStream resource = ir.getResource(); if (resource == null) { return null; } icon = (resource == null ? null : IconLoadHelper.loadIcon(resource)); try { resource.close(); } catch (IOException e) { if (LOG.isEnabledFor(Level.WARN)) { LOG.warn("", e); } } } MapSequence.fromMap(ourResToIcon).put(ir, icon); return icon; } @Deprecated public static Icon getIcon(SAbstractConcept concept) { return getIconFor(concept); } @Deprecated @ToRemove(version = 3.4) public static Icon getIconFor(String namespace) { String className = namespace + ".icons.Icons"; try { Language language = ModuleRepositoryFacade.getInstance().getModule(namespace, Language.class); if (language == null) { if (LOG.isEnabledFor(Level.ERROR)) { LOG.error("Can't find a language " + namespace); } } else { try { Class<?> iconClass = language.getOwnClass(className); Method method; try { method = iconClass.getMethod("getLanguageIcon"); } catch (NoSuchMethodException e) { return EMPTY_ICON; } Icon icon = (Icon) method.invoke(null); if (icon != null) { return icon; } } catch (ModuleClassLoaderIsNullException e) { return EMPTY_ICON; } catch (ClassNotFoundException e) { return EMPTY_ICON; } } } catch (Exception e) { if (LOG.isEnabledFor(Level.ERROR)) { LOG.error("", e); } } return EMPTY_ICON; } @Deprecated public static Icon getIconForNamespace(String namespace) { return getIconFor(namespace); } @Deprecated public static Icon loadIcon(@NonNls String iconPath, boolean cache) { return IconLoadHelper.loadIcon(iconPath); } @Deprecated public static Icon getIconFor(MPSModuleOwner owner) { if (owner instanceof MPSProject) { return IdeIcons.PROJECT_ICON; } if (owner instanceof SModule) { return getIconFor((AbstractModule) owner); } return IdeIcons.DEFAULT_ICON; } }