diff --git a/java/compiler/openapi/src/com/intellij/packaging/ui/ArtifactProblemsHolder.java b/java/compiler/openapi/src/com/intellij/packaging/ui/ArtifactProblemsHolder.java index be3d257a4ad9..575292ece6c3 100644 --- a/java/compiler/openapi/src/com/intellij/packaging/ui/ArtifactProblemsHolder.java +++ b/java/compiler/openapi/src/com/intellij/packaging/ui/ArtifactProblemsHolder.java @@ -33,4 +33,6 @@ public interface ArtifactProblemsHolder { void registerError(@NotNull String message, @Nullable ArtifactProblemQuickFix quickFix); void registerError(@NotNull String message, @Nullable List> pathToPlace, ArtifactProblemQuickFix... quickFixes); + + void registerWarning(@NotNull String message, @Nullable List> pathToPlace, ArtifactProblemQuickFix... quickFixes); } diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactProblemsHolderImpl.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactProblemsHolderImpl.java index 2673df78ddc6..4ad1ad75b3b8 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactProblemsHolderImpl.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactProblemsHolderImpl.java @@ -39,7 +39,17 @@ public class ArtifactProblemsHolderImpl extends ArtifactProblemsHolderBase { } public void registerError(@NotNull String message, @Nullable List> pathToPlace, @Nullable ArtifactProblemQuickFix... quickFixes) { - myProblemsHolder.registerProblem(new ArtifactProblemDescription(message, ProjectStructureProblemDescription.Severity.ERROR, pathToPlace, Arrays.asList( - quickFixes))); + registerProblem(message, pathToPlace, ProjectStructureProblemDescription.Severity.ERROR, quickFixes); + } + + private void registerProblem(@NotNull String message, @Nullable List> pathToPlace, + final ProjectStructureProblemDescription.Severity severity, @Nullable ArtifactProblemQuickFix... quickFixes) { + myProblemsHolder.registerProblem(new ArtifactProblemDescription(message, severity, pathToPlace, Arrays.asList(quickFixes))); + } + + public void registerWarning(@NotNull String message, + @Nullable List> pathToPlace, + ArtifactProblemQuickFix... quickFixes) { + registerProblem(message, pathToPlace, ProjectStructureProblemDescription.Severity.WARNING, quickFixes); } } diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactValidationManagerImpl.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactValidationManagerImpl.java index 5f023e4c2f7e..0a390ab897ca 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactValidationManagerImpl.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactValidationManagerImpl.java @@ -21,10 +21,8 @@ import com.intellij.openapi.roots.ui.configuration.projectRoot.daemon.ProjectStr import com.intellij.openapi.roots.ui.configuration.projectRoot.daemon.ProjectStructureProblemsHolderImpl; import com.intellij.openapi.util.Disposer; import com.intellij.openapi.util.MultiValuesMap; -import com.intellij.openapi.util.Pair; import com.intellij.packaging.elements.PackagingElement; import com.intellij.packaging.ui.ArtifactProblemQuickFix; -import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.swing.*; @@ -39,8 +37,8 @@ import java.util.List; public class ArtifactValidationManagerImpl implements Disposable { private ArtifactErrorPanel myErrorPanel; private final ArtifactEditorImpl myArtifactEditor; - private MultiValuesMap, String> myErrorsForNodes = new MultiValuesMap, String>(true); - private List>>> myProblems = new ArrayList>>>(); + private MultiValuesMap, ArtifactProblemDescription> myProblemsForNodes = new MultiValuesMap, ArtifactProblemDescription>(true); + private List myProblems = new ArrayList(); ArtifactValidationManagerImpl(ArtifactEditorImpl artifactEditor) { Disposer.register(artifactEditor, this); @@ -56,23 +54,19 @@ public class ArtifactValidationManagerImpl implements Disposable { } public void onNodesAdded() { - for (Pair>> problem : myProblems) { - registerProblem(problem.getFirst(), problem.getSecond()); + for (ArtifactProblemDescription problem : myProblems) { + showProblemInTree(problem); } } - private void registerProblem(@NotNull PackagingElementNode node, @NotNull String message) { - myErrorsForNodes.put(node, message); - } - @Nullable - public Collection getProblems(PackagingElementNode node) { - return myErrorsForNodes.get(node); + public Collection getProblems(PackagingElementNode node) { + return myProblemsForNodes.get(node); } public void updateProblems(@Nullable ProjectStructureProblemsHolderImpl holder) { myErrorPanel.clearError(); - myErrorsForNodes.clear(); + myProblemsForNodes.clear(); myProblems.clear(); if (holder != null) { final List problemDescriptions = holder.getProblemDescriptions(); @@ -81,11 +75,11 @@ public class ArtifactValidationManagerImpl implements Disposable { final String message = description.getMessage(); List quickFix = Collections.emptyList(); if (description instanceof ArtifactProblemDescription) { - quickFix = ((ArtifactProblemDescription)description).getQuickFixes(); - final List> pathToPlace = ((ArtifactProblemDescription)description).getPathToPlace(); - if (pathToPlace != null) { - myProblems.add(Pair.create(message, pathToPlace)); - registerProblem(message, pathToPlace); + final ArtifactProblemDescription artifactProblem = (ArtifactProblemDescription)description; + quickFix = artifactProblem.getQuickFixes(); + if (artifactProblem.getPathToPlace() != null) { + myProblems.add(artifactProblem); + showProblemInTree(artifactProblem); } } myErrorPanel.showError(message, quickFix); @@ -95,13 +89,14 @@ public class ArtifactValidationManagerImpl implements Disposable { myArtifactEditor.getLayoutTreeComponent().updateTreeNodesPresentation(); } - private void registerProblem(String message, List> pathToPlace) { + private void showProblemInTree(ArtifactProblemDescription problem) { final LayoutTree layoutTree = myArtifactEditor.getLayoutTreeComponent().getLayoutTree(); PackagingElementNode node = layoutTree.getRootPackagingNode(); - if (node != null) { + final List> pathToPlace = problem.getPathToPlace(); + if (node != null && pathToPlace != null) { List> nodes = node.getNodesByPath(pathToPlace.subList(1, pathToPlace.size())); for (PackagingElementNode elementNode : nodes) { - registerProblem(elementNode, message); + myProblemsForNodes.put(elementNode, problem); } } } diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/nodes/PackagingElementNode.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/nodes/PackagingElementNode.java index 170850b1ea6a..349016a15a2e 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/nodes/PackagingElementNode.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/nodes/PackagingElementNode.java @@ -19,14 +19,16 @@ import com.intellij.ide.projectView.PresentationData; import com.intellij.openapi.editor.markup.EffectType; import com.intellij.openapi.editor.markup.TextAttributes; import com.intellij.openapi.roots.ui.configuration.artifacts.ArtifactEditorImpl; +import com.intellij.openapi.roots.ui.configuration.artifacts.ArtifactProblemDescription; +import com.intellij.openapi.roots.ui.configuration.projectRoot.daemon.ProjectStructureProblemDescription; import com.intellij.openapi.util.MultiValuesMap; -import com.intellij.openapi.util.text.StringUtil; import com.intellij.packaging.elements.CompositePackagingElement; import com.intellij.packaging.elements.PackagingElement; import com.intellij.packaging.ui.ArtifactEditorContext; import com.intellij.ui.SimpleTextAttributes; import com.intellij.ui.treeStructure.SimpleNode; import com.intellij.util.SmartList; +import com.intellij.util.StringBuilderSpinAllocator; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -93,22 +95,36 @@ public class PackagingElementNode> extends Artifac @Override protected void update(PresentationData presentation) { - final Collection problems = ((ArtifactEditorImpl)myContext.getThisArtifactEditor()).getValidationManager().getProblems(this); + final Collection problems = ((ArtifactEditorImpl)myContext.getThisArtifactEditor()).getValidationManager().getProblems(this); if (problems == null || problems.isEmpty()) { super.update(presentation); return; } - final String message = StringUtil.join(problems, "\n"); + StringBuilder buffer = StringBuilderSpinAllocator.alloc(); + final String tooltip; + boolean isError = false; + try { + buffer.append(""); + for (ArtifactProblemDescription problem : problems) { + isError |= problem.getSeverity() == ProjectStructureProblemDescription.Severity.ERROR; + buffer.append(problem.getMessage()).append("
"); + } + buffer.append(""); + tooltip = buffer.toString(); + } + finally { + StringBuilderSpinAllocator.dispose(buffer); + } - getElementPresentation().render(presentation, addErrorHighlighting(SimpleTextAttributes.REGULAR_ATTRIBUTES), - addErrorHighlighting(SimpleTextAttributes.GRAY_ATTRIBUTES)); - presentation.setTooltip(message); + getElementPresentation().render(presentation, addErrorHighlighting(isError, SimpleTextAttributes.REGULAR_ATTRIBUTES), + addErrorHighlighting(isError, SimpleTextAttributes.GRAY_ATTRIBUTES)); + presentation.setTooltip(tooltip); } - private static SimpleTextAttributes addErrorHighlighting(SimpleTextAttributes attributes) { + private static SimpleTextAttributes addErrorHighlighting(boolean error, SimpleTextAttributes attributes) { final TextAttributes textAttributes = attributes.toTextAttributes(); textAttributes.setEffectType(EffectType.WAVE_UNDERSCORE); - textAttributes.setEffectColor(Color.RED); + textAttributes.setEffectColor(error ? Color.RED : Color.GRAY); return SimpleTextAttributes.fromTextAttributes(textAttributes); }