package com.cedricziel.idea.typo3.codeInsight; import com.cedricziel.idea.typo3.TYPO3CMSIcons; import com.cedricziel.idea.typo3.TYPO3CMSProjectComponent; import com.cedricziel.idea.typo3.container.IconProvider; import com.cedricziel.idea.typo3.domain.TYPO3IconDefinition; import com.cedricziel.idea.typo3.psi.PhpElementsUtil; import com.intellij.codeInsight.daemon.RelatedItemLineMarkerInfo; import com.intellij.codeInsight.daemon.RelatedItemLineMarkerProvider; import com.intellij.codeInsight.navigation.NavigationGutterIconBuilder; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.PsiElement; import com.intellij.psi.util.PsiTreeUtil; import com.jetbrains.php.lang.psi.elements.MethodReference; import com.jetbrains.php.lang.psi.elements.PhpClass; import com.jetbrains.php.lang.psi.elements.StringLiteralExpression; import org.jetbrains.annotations.NotNull; import javax.swing.*; import java.io.IOException; import java.util.Collection; import java.util.List; import java.util.Map; import static com.cedricziel.idea.typo3.util.IconUtil.createIconFromFile; public class IconLineMarkerProvider extends RelatedItemLineMarkerProvider { @Override protected void collectNavigationMarkers(@NotNull PsiElement element, Collection<? super RelatedItemLineMarkerInfo> result) { renderDefinitionMarker(element, result); renderUsageMarker(element, result); } private void renderUsageMarker(PsiElement element, Collection<? super RelatedItemLineMarkerInfo> result) { if (!(element instanceof StringLiteralExpression)) { return; } StringLiteralExpression literalExpression = (StringLiteralExpression) element; String value = literalExpression.getContents(); if (value.isEmpty()) { return; } PsiElement methodReference = PsiTreeUtil.getParentOfType(element, MethodReference.class); if (PhpElementsUtil.isMethodWithFirstStringOrFieldReference(methodReference, "getIcon")) { IconProvider iconProvider = IconProvider.getInstance(element.getProject()); if (!iconProvider.has(element.getProject(), value)) { return; } List<TYPO3IconDefinition> iconsForLine = iconProvider.get(element.getProject(), value); iconsForLine.forEach(iconForLine -> { markLineForIcon(element, result, iconForLine); }); } } private void renderDefinitionMarker(PsiElement element, Collection<? super RelatedItemLineMarkerInfo> result) { PhpClass parentClass = PsiTreeUtil.getParentOfType(element, PhpClass.class); if (parentClass == null) { return; } String presentableFQN = parentClass.getPresentableFQN(); if (!presentableFQN.equals(IconProvider.ICON_REGISTRY_CLASS)) { return; } IconProvider iconProvider = IconProvider.getInstance(element.getProject()); Map<PsiElement, TYPO3IconDefinition> elementMap = iconProvider.getElementMap(element.getProject()); if (!elementMap.containsKey(element)) { return; } TYPO3IconDefinition iconForLine = elementMap.get(element); markLineForIcon(element, result, iconForLine); } private void markLineForIcon(PsiElement element, Collection<? super RelatedItemLineMarkerInfo> result, TYPO3IconDefinition iconForLine) { NavigationGutterIconBuilder<PsiElement> builder; VirtualFile virtualFile = iconForLine.getVirtualFile(); if (virtualFile == null) { builder = NavigationGutterIconBuilder .create(TYPO3CMSIcons.ICON_NOT_RESOLVED) .setTarget(iconForLine.getElement()) .setTooltipText("Navigate to icon definition"); } else { try { Icon icon = createIconFromFile(virtualFile); if (icon == null) { icon = TYPO3CMSIcons.ICON_NOT_RESOLVED; } builder = NavigationGutterIconBuilder .create(icon) .setTarget(iconForLine.getElement()) .setTooltipText("Navigate to icon definition"); } catch (IOException e) { // icon could not be loaded TYPO3CMSProjectComponent.getLogger().error("Could not find image."); return; } } result.add(builder.createLineMarkerInfo(element)); } }