diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ConfigurationError.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ConfigurationError.java index fdd29a300176..66a8de47a85a 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ConfigurationError.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ConfigurationError.java @@ -17,6 +17,8 @@ package com.intellij.openapi.roots.ui.configuration; import org.jetbrains.annotations.NotNull; +import javax.swing.*; + /** * User: spLeaner */ @@ -65,7 +67,7 @@ public abstract class ConfigurationError implements Comparable implements D } @Override - public void fix() { + public void fix(JComponent contextComponent) { } @Override diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ProjectStructureConfigurable.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ProjectStructureConfigurable.java index f7a6784e2e3d..fac45969b2a7 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ProjectStructureConfigurable.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ProjectStructureConfigurable.java @@ -364,6 +364,10 @@ public class ProjectStructureConfigurable extends BaseConfigurable implements Se return navigateTo(place, requestFocus); } + public Place createModulePlace(@NotNull Module module) { + return createPlaceFor(myModulesConfig).putPath(ModuleStructureConfigurable.TREE_OBJECT, module); + } + public ActionCallback select(@Nullable final Facet facetToSelect, final boolean requestFocus) { Place place = createPlaceFor(myModulesConfig); if (facetToSelect != null) { @@ -379,17 +383,27 @@ public class ProjectStructureConfigurable extends BaseConfigurable implements Se } public ActionCallback selectProjectOrGlobalLibrary(@NotNull Library library, boolean requestFocus) { - Place place = createPlaceFor(getConfigurableFor(library)); - place.putPath(BaseStructureConfigurable.TREE_NAME, library.getName()); + Place place = createProjectOrGlobalLibraryPlace(library); return navigateTo(place, requestFocus); } + public Place createProjectOrGlobalLibraryPlace(Library library) { + Place place = createPlaceFor(getConfigurableFor(library)); + place.putPath(BaseStructureConfigurable.TREE_NAME, library.getName()); + return place; + } + public ActionCallback select(@Nullable Artifact artifact, boolean requestFocus) { + Place place = createArtifactPlace(artifact); + return navigateTo(place, requestFocus); + } + + public Place createArtifactPlace(Artifact artifact) { Place place = createPlaceFor(myArtifactsStructureConfigurable); if (artifact != null) { place.putPath(BaseStructureConfigurable.TREE_NAME, artifact.getName()); } - return navigateTo(place, requestFocus); + return place; } public ActionCallback select(@NotNull LibraryOrderEntry libraryOrderEntry, final boolean requestFocus) { diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactProblemDescription.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactProblemDescription.java index 8595333d1d6f..20317b52c8d1 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactProblemDescription.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactProblemDescription.java @@ -15,9 +15,11 @@ */ package com.intellij.openapi.roots.ui.configuration.artifacts; +import com.intellij.openapi.roots.ui.configuration.projectRoot.daemon.ConfigurationErrorQuickFix; import com.intellij.openapi.roots.ui.configuration.projectRoot.daemon.ProjectStructureProblemDescription; import com.intellij.packaging.elements.PackagingElement; import com.intellij.packaging.ui.ArtifactProblemQuickFix; +import com.intellij.ui.navigation.Place; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -31,15 +33,11 @@ public class ArtifactProblemDescription extends ProjectStructureProblemDescripti private List myQuickFixes; private List> myPathToPlace; - public ArtifactProblemDescription(@NotNull String message, @NotNull Severity severity) { - this(message, severity, null, Collections.emptyList()); - } - public ArtifactProblemDescription(@NotNull String message, @NotNull Severity severity, @Nullable List> pathToPlace, - @NotNull List quickFixes) { - super(message, severity); + @NotNull List quickFixes, @NotNull Place place) { + super(message, null, severity, place, Collections.emptyList()); myPathToPlace = pathToPlace; myQuickFixes = 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 4cca595a799c..380260c8885f 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 @@ -15,12 +15,14 @@ */ package com.intellij.openapi.roots.ui.configuration.artifacts; +import com.intellij.openapi.roots.ui.configuration.ProjectStructureConfigurable; import com.intellij.openapi.roots.ui.configuration.projectRoot.daemon.ProjectStructureProblemDescription; import com.intellij.openapi.roots.ui.configuration.projectRoot.daemon.ProjectStructureProblemsHolder; import com.intellij.packaging.elements.PackagingElement; import com.intellij.packaging.impl.ui.ArtifactProblemsHolderBase; import com.intellij.packaging.ui.ArtifactEditorContext; import com.intellij.packaging.ui.ArtifactProblemQuickFix; +import com.intellij.ui.navigation.Place; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -44,7 +46,9 @@ public class ArtifactProblemsHolderImpl extends ArtifactProblemsHolderBase { private void registerProblem(@NotNull String message, @Nullable List> pathToPlace, final ProjectStructureProblemDescription.Severity severity, @NotNull ArtifactProblemQuickFix... quickFixes) { - myProblemsHolder.registerProblem(new ArtifactProblemDescription(message, severity, pathToPlace, Arrays.asList(quickFixes))); + final ArtifactEditorContext context = getContext(); + final Place place = ProjectStructureConfigurable.getInstance(context.getProject()).createArtifactPlace(context.getArtifact()); + myProblemsHolder.registerProblem(new ArtifactProblemDescription(message, severity, pathToPlace, Arrays.asList(quickFixes), place)); } public void registerWarning(@NotNull String message, diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/libraryEditor/LibraryRootsComponent.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/libraryEditor/LibraryRootsComponent.java index 3f95273100f7..1f7b946148da 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/libraryEditor/LibraryRootsComponent.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/libraryEditor/LibraryRootsComponent.java @@ -256,6 +256,12 @@ public class LibraryRootsComponent implements Disposable, LibraryEditorComponent } } + public void updateRootsTree() { + if (myTreeBuilder != null) { + myTreeBuilder.queueUpdate(); + } + } + private class AttachItemAction implements ActionListener { private VirtualFile myLastChosen = null; private final AttachRootButtonDescriptor myDescriptor; @@ -328,7 +334,7 @@ public class LibraryRootsComponent implements Disposable, LibraryEditorComponent } }); updateProperties(); - myTreeBuilder.updateFromRoot(); + myTreeBuilder.queueUpdate(); } return filesToAttach; } @@ -368,7 +374,7 @@ public class LibraryRootsComponent implements Disposable, LibraryEditorComponent protected void librariesChanged(boolean putFocusIntoTree) { updateProperties(); - myTreeBuilder.updateFromRoot(); + myTreeBuilder.queueUpdate(); if (putFocusIntoTree) { myTree.requestFocus(); } diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/LibraryConfigurable.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/LibraryConfigurable.java index f98a4eed68d0..d3b7fa5e27e2 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/LibraryConfigurable.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/LibraryConfigurable.java @@ -171,4 +171,10 @@ public class LibraryConfigurable extends ProjectStructureElementConfigurable invalidClasses = library.getInvalidRootUrls(OrderRootType.CLASSES); + if (!invalidClasses.isEmpty()) { + final String description = createInvalidRootsDescription(invalidClasses, libraryName); + problemsHolder.registerError(ProjectBundle.message("project.roots.tooltip.library.misconfigured", libraryName), description, createPlace(), + new RemoveInvalidRootsQuickFix(Collections.singletonMap(OrderRootType.CLASSES, invalidClasses), library)); } - else if (!library.allPathsValid(JavadocOrderRootType.getInstance()) || !library.allPathsValid(OrderRootType.SOURCES)) { - problemsHolder.registerWarning(ProjectBundle.message("project.roots.tooltip.library.misconfigured", libraryName)); + final List invalidJavadocs = library.getInvalidRootUrls(JavadocOrderRootType.getInstance()); + final List invalidSources = library.getInvalidRootUrls(OrderRootType.SOURCES); + if (!invalidJavadocs.isEmpty() || !invalidSources.isEmpty()) { + final Map> invalidRoots = new HashMap>(); + invalidRoots.put(OrderRootType.SOURCES, invalidSources); + invalidRoots.put(JavadocOrderRootType.getInstance(), invalidJavadocs); + final String description = createInvalidRootsDescription(ContainerUtil.concat(invalidJavadocs, invalidSources), libraryName); + problemsHolder.registerWarning(ProjectBundle.message("project.roots.tooltip.library.misconfigured", libraryName), description, createPlace(), + new RemoveInvalidRootsQuickFix(invalidRoots, library)); } } + private static String createInvalidRootsDescription(List invalidClasses, String libraryName) { + StringBuilder buffer = new StringBuilder(); + buffer.append(""); + buffer.append("Library '").append(libraryName).append("' has broken paths:"); + for (String url : invalidClasses) { + buffer.append("
  "); + buffer.append(VfsUtil.urlToPath(url)); + } + buffer.append(""); + return buffer.toString(); + } + + @NotNull + private Place createPlace() { + return ProjectStructureConfigurable.getInstance(myContext.getProject()).createProjectOrGlobalLibraryPlace(myLibrary); + } + @Override public List getUsagesInElement() { return Collections.emptyList(); @@ -84,4 +121,39 @@ public class LibraryProjectStructureElement extends ProjectStructureElement { final LibraryTable libraryTable = myLibrary.getTable(); return libraryTable != null && LibraryTablesRegistrar.PROJECT_LEVEL.equals(libraryTable.getTableLevel()); } + + private class RemoveInvalidRootsQuickFix extends ConfigurationErrorQuickFix { + private final Map> myInvalidRoots; + private final Library myLibrary; + + public RemoveInvalidRootsQuickFix(Map> invalidRoots, Library library) { + super("Remove invalid roots"); + myInvalidRoots = invalidRoots; + myLibrary = library; + } + + @Override + public void performFix() { + final LibraryTable.ModifiableModel libraryTable = myContext.getModifiableLibraryTable(myLibrary.getTable()); + if (libraryTable instanceof LibrariesModifiableModel) { + for (OrderRootType rootType : myInvalidRoots.keySet()) { + for (String invalidRoot : myInvalidRoots.get(rootType)) { + final ExistingLibraryEditor libraryEditor = ((LibrariesModifiableModel)libraryTable).getLibraryEditor(myLibrary); + libraryEditor.removeRoot(invalidRoot, rootType); + } + } + myContext.getDaemonAnalyzer().queueUpdate(LibraryProjectStructureElement.this); + final ProjectStructureConfigurable structureConfigurable = ProjectStructureConfigurable.getInstance(myContext.getProject()); + structureConfigurable.navigateTo(createPlace(), true).doWhenDone(new Runnable() { + @Override + public void run() { + final NamedConfigurable configurable = structureConfigurable.getConfigurableFor(myLibrary).getSelectedConfugurable(); + if (configurable instanceof LibraryConfigurable) { + ((LibraryConfigurable)configurable).updateComponent(); + } + } + }); + } + } + } } diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/daemon/ModuleProjectStructureElement.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/daemon/ModuleProjectStructureElement.java index 52832d69a6a8..a457a840cbd5 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/daemon/ModuleProjectStructureElement.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/daemon/ModuleProjectStructureElement.java @@ -7,7 +7,9 @@ import com.intellij.openapi.projectRoots.Sdk; import com.intellij.openapi.roots.*; import com.intellij.openapi.roots.libraries.Library; import com.intellij.openapi.roots.ui.configuration.ModuleEditor; +import com.intellij.openapi.roots.ui.configuration.ProjectStructureConfigurable; import com.intellij.openapi.roots.ui.configuration.projectRoot.StructureConfigurableContext; +import com.intellij.ui.navigation.Place; import com.intellij.util.ArrayUtil; import org.jetbrains.annotations.NotNull; @@ -39,7 +41,7 @@ public class ModuleProjectStructureElement extends ProjectStructureElement { for (Module each : all) { if (each != myModule && myContext.getRealName(each).equals(myContext.getRealName(myModule))) { - problemsHolder.registerError(ProjectBundle.message("project.roots.module.duplicate.name.message")); + problemsHolder.registerError(ProjectBundle.message("project.roots.module.duplicate.name.message"), null, createPlace(), null); break; } } @@ -50,9 +52,11 @@ public class ModuleProjectStructureElement extends ProjectStructureElement { for (OrderEntry entry : entries) { if (!entry.isValid()){ if (entry instanceof JdkOrderEntry && ((JdkOrderEntry)entry).getJdkName() == null) { - problemsHolder.registerError(ProjectBundle.message("project.roots.module.jdk.problem.message")); + problemsHolder.registerError(ProjectBundle.message("project.roots.module.jdk.problem.message"), null, createPlace(), null); } else { - problemsHolder.registerError(ProjectBundle.message("project.roots.library.problem.message", entry.getPresentableName())); + problemsHolder.registerError(ProjectBundle.message("project.roots.library.problem.message", entry.getPresentableName()), null, + createPlace(), + null); } } //todo[nik] highlight libraries with invalid paths in ClasspathEditor @@ -70,6 +74,10 @@ public class ModuleProjectStructureElement extends ProjectStructureElement { } } + private Place createPlace() { + return ProjectStructureConfigurable.getInstance(myContext.getProject()).createModulePlace(myModule); + } + @Override public List getUsagesInElement() { final List usages = new ArrayList(); diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/daemon/ProjectConfigurationProblem.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/daemon/ProjectConfigurationProblem.java new file mode 100644 index 000000000000..500b7460a792 --- /dev/null +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/daemon/ProjectConfigurationProblem.java @@ -0,0 +1,71 @@ +/* + * Copyright 2000-2010 JetBrains s.r.o. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.openapi.roots.ui.configuration.projectRoot.daemon; + +import com.intellij.openapi.roots.ui.configuration.ConfigurationError; +import com.intellij.openapi.roots.ui.configuration.ProjectStructureConfigurable; +import com.intellij.openapi.roots.ui.configuration.projectRoot.StructureConfigurableContext; +import com.intellij.openapi.ui.popup.JBPopupFactory; +import com.intellij.openapi.ui.popup.PopupStep; +import com.intellij.openapi.ui.popup.util.BaseListPopupStep; +import org.jetbrains.annotations.NotNull; + +import javax.swing.*; +import java.util.List; + +/** +* @author nik +*/ +class ProjectConfigurationProblem extends ConfigurationError { + private final StructureConfigurableContext myContext; + private final ProjectStructureProblemDescription myDescription; + + public ProjectConfigurationProblem(StructureConfigurableContext context, ProjectStructureProblemDescription description) { + super(description.getMessage(), description.getDescription() != null ? description.getDescription() : description.getMessage()); + myContext = context; + myDescription = description; + } + + @Override + public void navigate() { + ProjectStructureConfigurable.getInstance(myContext.getProject()).navigateTo(myDescription.getPlace(), true); + } + + @Override + public boolean canBeFixed() { + return !myDescription.getFixes().isEmpty(); + } + + @Override + public void fix(JComponent contextComponent) { + final List fixes = myDescription.getFixes(); + if (fixes.size() == 1) { + fixes.get(0).performFix(); + } + else { + JBPopupFactory.getInstance().createListPopup(new BaseListPopupStep(null, fixes) { + @NotNull + @Override + public String getTextFor(ConfigurationErrorQuickFix value) { + return value.getActionName(); + } + + @Override + public PopupStep onChosen(ConfigurationErrorQuickFix selectedValue, boolean finalChoice) { + selectedValue.performFix(); + return FINAL_CHOICE; + } + }).showUnderneathOf(contextComponent); + } + } +} diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/daemon/ProjectConfigurationProblems.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/daemon/ProjectConfigurationProblems.java index bae70d3391ca..049fe43a80e6 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/daemon/ProjectConfigurationProblems.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/daemon/ProjectConfigurationProblems.java @@ -67,7 +67,7 @@ public class ProjectConfigurationProblems { final List descriptions = problemsHolder.getProblemDescriptions(); if (descriptions != null) { for (ProjectStructureProblemDescription description : descriptions) { - final ProjectConfigurationProblem error = new ProjectConfigurationProblem(description); + final ProjectConfigurationProblem error = new ProjectConfigurationProblem(myContext, description); myErrors.put(element, error); ConfigurationErrors.Bus.addError(error, myContext.getProject()); } @@ -81,18 +81,4 @@ public class ProjectConfigurationProblems { ConfigurationErrors.Bus.removeError(error, myContext.getProject()); } } - - private static class ProjectConfigurationProblem extends ConfigurationError { - public ProjectConfigurationProblem(ProjectStructureProblemDescription description) { - super(description.getMessage(), description.getMessage()); - } - - @Override - public void navigate() { - } - - @Override - public void fix() { - } - } } diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/daemon/ProjectStructureProblemDescription.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/daemon/ProjectStructureProblemDescription.java index 6dd988ad3f19..d4b125dc58fb 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/daemon/ProjectStructureProblemDescription.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/daemon/ProjectStructureProblemDescription.java @@ -15,27 +15,51 @@ */ package com.intellij.openapi.roots.ui.configuration.projectRoot.daemon; +import com.intellij.ui.navigation.Place; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.List; /** * @author nik */ public class ProjectStructureProblemDescription { private final String myMessage; + private final String myDescription; private final Severity mySeverity; + private final Place myPlace; + private final List myFixes; - public ProjectStructureProblemDescription(@NotNull String message, @NotNull Severity severity) { + public ProjectStructureProblemDescription(@NotNull String message, @Nullable String description, @NotNull Severity severity, @NotNull Place place, + @NotNull List fixes) { myMessage = message; + myDescription = description; mySeverity = severity; + myPlace = place; + myFixes = fixes; } public String getMessage() { return myMessage; } + @Nullable + public String getDescription() { + return myDescription; + } + + public List getFixes() { + return myFixes; + } + public Severity getSeverity() { return mySeverity; } + public Place getPlace() { + return myPlace; + } + public enum Severity { ERROR, WARNING } } diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/daemon/ProjectStructureProblemsHolder.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/daemon/ProjectStructureProblemsHolder.java index 9094b4ac654c..411451abfdcc 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/daemon/ProjectStructureProblemsHolder.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/daemon/ProjectStructureProblemsHolder.java @@ -15,15 +15,17 @@ */ package com.intellij.openapi.roots.ui.configuration.projectRoot.daemon; +import com.intellij.ui.navigation.Place; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; /** * @author nik */ public interface ProjectStructureProblemsHolder { - void registerError(@NotNull String message); + void registerError(@NotNull String message, @Nullable String description, @NotNull Place place, @Nullable ConfigurationErrorQuickFix fix); - void registerWarning(@NotNull String message); + void registerWarning(@NotNull String message, @Nullable String description, @NotNull Place place, @Nullable ConfigurationErrorQuickFix fix); void registerProblem(@NotNull ProjectStructureProblemDescription description); } diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/daemon/ProjectStructureProblemsHolderImpl.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/daemon/ProjectStructureProblemsHolderImpl.java index 82cb561b8fd8..ea515d43263f 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/daemon/ProjectStructureProblemsHolderImpl.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/daemon/ProjectStructureProblemsHolderImpl.java @@ -1,10 +1,12 @@ package com.intellij.openapi.roots.ui.configuration.projectRoot.daemon; +import com.intellij.ui.navigation.Place; import com.intellij.util.SmartList; import com.intellij.util.StringBuilderSpinAllocator; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.util.Collections; import java.util.List; /** @@ -13,12 +15,14 @@ import java.util.List; public class ProjectStructureProblemsHolderImpl implements ProjectStructureProblemsHolder { private List myProblemDescriptions; - public void registerError(@NotNull String message) { - registerProblem(new ProjectStructureProblemDescription(message, ProjectStructureProblemDescription.Severity.ERROR)); + public void registerError(@NotNull String message, String description, @NotNull Place place, @Nullable ConfigurationErrorQuickFix fix) { + final List fixes = fix != null ? Collections.singletonList(fix) : Collections.emptyList(); + registerProblem(new ProjectStructureProblemDescription(message, description, ProjectStructureProblemDescription.Severity.ERROR, place, fixes)); } - public void registerWarning(@NotNull String message) { - registerProblem(new ProjectStructureProblemDescription(message, ProjectStructureProblemDescription.Severity.WARNING)); + public void registerWarning(@NotNull String message, String description, @NotNull Place place, @Nullable ConfigurationErrorQuickFix fix) { + final List fixes = Collections.singletonList(fix); + registerProblem(new ProjectStructureProblemDescription(message, description, ProjectStructureProblemDescription.Severity.WARNING, place, fixes)); } public void registerProblem(final @NotNull ProjectStructureProblemDescription description) { diff --git a/platform/lang-impl/src/com/intellij/openapi/roots/impl/libraries/LibraryEx.java b/platform/lang-impl/src/com/intellij/openapi/roots/impl/libraries/LibraryEx.java index 839ee0b2b79e..54ac21a3ffd3 100644 --- a/platform/lang-impl/src/com/intellij/openapi/roots/impl/libraries/LibraryEx.java +++ b/platform/lang-impl/src/com/intellij/openapi/roots/impl/libraries/LibraryEx.java @@ -22,13 +22,15 @@ import com.intellij.openapi.roots.libraries.Library; import com.intellij.openapi.roots.libraries.LibraryProperties; import com.intellij.openapi.roots.libraries.LibraryType; +import java.util.List; + /** * @author dsl */ public interface LibraryEx extends Library { Library cloneLibrary(RootModelImpl rootModel); - boolean allPathsValid(OrderRootType type); + List getInvalidRootUrls(OrderRootType type); boolean isDisposed(); @@ -37,8 +39,6 @@ public interface LibraryEx extends Library { LibraryProperties getProperties(); interface ModifiableModelEx extends ModifiableModel { - boolean allPathsValid(OrderRootType type); - void setProperties(LibraryProperties properties); LibraryProperties getProperties(); diff --git a/platform/lang-impl/src/com/intellij/openapi/roots/impl/libraries/LibraryImpl.java b/platform/lang-impl/src/com/intellij/openapi/roots/impl/libraries/LibraryImpl.java index d3e6aa18ffad..5af2d67121e0 100644 --- a/platform/lang-impl/src/com/intellij/openapi/roots/impl/libraries/LibraryImpl.java +++ b/platform/lang-impl/src/com/intellij/openapi/roots/impl/libraries/LibraryImpl.java @@ -39,6 +39,7 @@ import com.intellij.openapi.vfs.pointers.VirtualFilePointerContainer; import com.intellij.openapi.vfs.pointers.VirtualFilePointerManager; import com.intellij.util.ArrayUtil; import com.intellij.util.ReflectionUtil; +import com.intellij.util.SmartList; import com.intellij.util.containers.HashMap; import com.intellij.util.messages.MessageBusConnection; import com.intellij.util.xmlb.SkipDefaultValuesSerializationFilters; @@ -204,14 +205,18 @@ public class LibraryImpl implements LibraryEx.ModifiableModelEx, LibraryEx { return clone; } - public boolean allPathsValid(OrderRootType type) { + public List getInvalidRootUrls(OrderRootType type) { final List pointers = myRoots.get(type).getList(); + List invalidPaths = null; for (VirtualFilePointer pointer : pointers) { if (!pointer.isValid()) { - return false; + if (invalidPaths == null) { + invalidPaths = new SmartList(); + } + invalidPaths.add(pointer.getUrl()); } } - return true; + return invalidPaths != null ? invalidPaths : Collections.emptyList(); } @Override