artifacts editor: error highlighting improved
authornik <Nikolay.Chashnikov@jetbrains.com>
Wed, 25 Nov 2009 12:24:46 +0000 (15:24 +0300)
committernik <Nikolay.Chashnikov@jetbrains.com>
Wed, 25 Nov 2009 12:24:46 +0000 (15:24 +0300)
java/compiler/openapi/src/com/intellij/packaging/ui/ArtifactProblemsHolder.java
java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactProblemsHolderImpl.java
java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactValidationManagerImpl.java
java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/nodes/PackagingElementNode.java

index be3d257a4ad93b4d52df62ba6d31ee951e8bb43b..575292ece6c3a67c959c2566523582e8275e02c3 100644 (file)
@@ -33,4 +33,6 @@ public interface ArtifactProblemsHolder {
   void registerError(@NotNull String message, @Nullable ArtifactProblemQuickFix quickFix);
 
   void registerError(@NotNull String message, @Nullable List<PackagingElement<?>> pathToPlace, ArtifactProblemQuickFix... quickFixes);
+
+  void registerWarning(@NotNull String message, @Nullable List<PackagingElement<?>> pathToPlace, ArtifactProblemQuickFix... quickFixes);
 }
index 2673df78ddc6f7fee6bd5b3e0c2950e674bbc223..4ad1ad75b3b8e662bf9927a19e0236d424d415a5 100644 (file)
@@ -39,7 +39,17 @@ public class ArtifactProblemsHolderImpl extends ArtifactProblemsHolderBase {
   }
 
   public void registerError(@NotNull String message, @Nullable List<PackagingElement<?>> 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<PackagingElement<?>> 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<PackagingElement<?>> pathToPlace,
+                              ArtifactProblemQuickFix... quickFixes) {
+    registerProblem(message, pathToPlace, ProjectStructureProblemDescription.Severity.WARNING, quickFixes);
   }
 }
index 5f023e4c2f7e0a3438191c37c10b60dce57ef5a9..0a390ab897ca0544280a16541be5f59988e586a3 100644 (file)
@@ -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<PackagingElementNode<?>, String> myErrorsForNodes = new MultiValuesMap<PackagingElementNode<?>, String>(true);
-  private List<Pair<String, List<PackagingElement<?>>>> myProblems = new ArrayList<Pair<String, List<PackagingElement<?>>>>();
+  private MultiValuesMap<PackagingElementNode<?>, ArtifactProblemDescription> myProblemsForNodes = new MultiValuesMap<PackagingElementNode<?>, ArtifactProblemDescription>(true);
+  private List<ArtifactProblemDescription> myProblems = new ArrayList<ArtifactProblemDescription>();
 
   ArtifactValidationManagerImpl(ArtifactEditorImpl artifactEditor) {
     Disposer.register(artifactEditor, this);
@@ -56,23 +54,19 @@ public class ArtifactValidationManagerImpl implements Disposable {
   }
 
   public void onNodesAdded() {
-    for (Pair<String, List<PackagingElement<?>>> 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<String> getProblems(PackagingElementNode<?> node) {
-    return myErrorsForNodes.get(node);
+  public Collection<ArtifactProblemDescription> 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<ProjectStructureProblemDescription> problemDescriptions = holder.getProblemDescriptions();
@@ -81,11 +75,11 @@ public class ArtifactValidationManagerImpl implements Disposable {
           final String message = description.getMessage();
           List<ArtifactProblemQuickFix> quickFix = Collections.emptyList();
           if (description instanceof ArtifactProblemDescription) {
-            quickFix = ((ArtifactProblemDescription)description).getQuickFixes();
-            final List<PackagingElement<?>> 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<PackagingElement<?>> pathToPlace) {
+  private void showProblemInTree(ArtifactProblemDescription problem) {
     final LayoutTree layoutTree = myArtifactEditor.getLayoutTreeComponent().getLayoutTree();
     PackagingElementNode<?> node = layoutTree.getRootPackagingNode();
-    if (node != null) {
+    final List<PackagingElement<?>> pathToPlace = problem.getPathToPlace();
+    if (node != null && pathToPlace != null) {
       List<PackagingElementNode<?>> nodes = node.getNodesByPath(pathToPlace.subList(1, pathToPlace.size()));
       for (PackagingElementNode<?> elementNode : nodes) {
-        registerProblem(elementNode, message);
+        myProblemsForNodes.put(elementNode, problem);
       }
     }
   }
index 170850b1ea6aeba54b5195cd69e1559aa3663cfd..349016a15a2e8a8e7bc833fd66df0fc7352c3c20 100644 (file)
@@ -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<E extends PackagingElement<?>> extends Artifac
 
   @Override
   protected void update(PresentationData presentation) {
-    final Collection<String> problems = ((ArtifactEditorImpl)myContext.getThisArtifactEditor()).getValidationManager().getProblems(this);
+    final Collection<ArtifactProblemDescription> 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("<html>");
+      for (ArtifactProblemDescription problem : problems) {
+        isError |= problem.getSeverity() == ProjectStructureProblemDescription.Severity.ERROR;
+        buffer.append(problem.getMessage()).append("<br>");
+      }
+      buffer.append("</html>");
+      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);
   }