'navigate' and 'fix' actions implemented for new project structure errors

This commit is contained in:
nik
2010-11-09 10:24:22 +03:00
parent 4b6cbf3185
commit 8b758ade5d
18 changed files with 297 additions and 58 deletions
@@ -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<ConfigurationErro
/**
* Called when user invokes "Fix" action
*/
public void fix() {
public void fix(JComponent contextComponent) {
}
public boolean canBeFixed() {
@@ -31,6 +31,7 @@ import com.intellij.util.messages.MessageBusConnection;
import com.intellij.util.ui.BaseButtonBehavior;
import com.intellij.util.ui.TimedDeadzone;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -59,6 +60,9 @@ public class ConfigurationErrorsComponent extends JPanel implements Disposable,
private static final Icon IGNORE = IconLoader.findIcon("/toolbar/unknown.png");
private static final Icon NAVIGATE = IconLoader.findIcon("/general/autoscrollToSource.png");
@NonNls private static final String FIX_ACTION_NAME = "FIX";
@NonNls private static final String NAVIGATE_ACTION_NAME = "NAVIGATE";
private ConfigurationErrorsListModel myConfigurationErrorsListModel;
private ErrorView myCurrentView;
@@ -212,10 +216,13 @@ public class ConfigurationErrorsComponent extends JPanel implements Disposable,
final Component deepestComponentAt = SwingUtilities.getDeepestComponentAt(renderer, point.x, point.y);
if (deepestComponentAt instanceof ToolbarAlikeButton) {
final String name = ((ToolbarAlikeButton)deepestComponentAt).getButtonName();
if ("FIX".equals(name)) {
onClickFix(error);
error.fix();
} else {
if (FIX_ACTION_NAME.equals(name)) {
onClickFix(error, (JComponent)deepestComponentAt);
}
else if (NAVIGATE_ACTION_NAME.equals(name)) {
error.navigate();
}
else {
onClickIgnore(error);
}
}
@@ -232,8 +239,8 @@ public class ConfigurationErrorsComponent extends JPanel implements Disposable,
}
}
private void onClickFix(@NotNull final ConfigurationError error) {
error.fix();
private void onClickFix(@NotNull final ConfigurationError error, JComponent component) {
error.fix(component);
}
@Override
@@ -386,11 +393,11 @@ public class ConfigurationErrorsComponent extends JPanel implements Disposable,
myFixGroup.setOpaque(false);
myFixGroup.setLayout(new BoxLayout(myFixGroup, BoxLayout.Y_AXIS));
myFixGroup.add(new ToolbarAlikeButton(FIX, "FIX") {});
myFixGroup.add(new ToolbarAlikeButton(FIX, FIX_ACTION_NAME) {});
myFixGroup.add(Box.createHorizontalStrut(3));
buttons.add(myFixGroup);
buttons.add(new ToolbarAlikeButton(NAVIGATE, "NAVIGATE") {});
buttons.add(new ToolbarAlikeButton(NAVIGATE, NAVIGATE_ACTION_NAME) {});
buttons.add(Box.createHorizontalStrut(3));
buttons.add(new ToolbarAlikeButton(IGNORE, "IGNORE") {});
@@ -572,7 +579,7 @@ public class ConfigurationErrorsComponent extends JPanel implements Disposable,
public void onClick() {
final Object o = myModel.getElementAt(0);
if (o instanceof ConfigurationError) {
((ConfigurationError)o).fix();
((ConfigurationError)o).fix(this);
updateView();
final Container ancestor = SwingUtilities.getAncestorOfClass(ConfigurationErrorsComponent.class, this);
if (ancestor != null && ancestor instanceof JComponent) {
@@ -346,7 +346,7 @@ public class ProjectConfigurable extends NamedConfigurable<Project> implements D
}
@Override
public void fix() {
public void fix(JComponent contextComponent) {
}
@Override
@@ -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) {
@@ -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<ArtifactProblemQuickFix> myQuickFixes;
private List<PackagingElement<?>> myPathToPlace;
public ArtifactProblemDescription(@NotNull String message, @NotNull Severity severity) {
this(message, severity, null, Collections.<ArtifactProblemQuickFix>emptyList());
}
public ArtifactProblemDescription(@NotNull String message,
@NotNull Severity severity,
@Nullable List<PackagingElement<?>> pathToPlace,
@NotNull List<ArtifactProblemQuickFix> quickFixes) {
super(message, severity);
@NotNull List<ArtifactProblemQuickFix> quickFixes, @NotNull Place place) {
super(message, null, severity, place, Collections.<ConfigurationErrorQuickFix>emptyList());
myPathToPlace = pathToPlace;
myQuickFixes = quickFixes;
}
@@ -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<PackagingElement<?>> 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,
@@ -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();
}
@@ -171,4 +171,10 @@ public class LibraryConfigurable extends ProjectStructureElementConfigurable<Lib
public String getHelpTopic() {
return "preferences.jdkGlobalLibs"; //todo
}
public void updateComponent() {
if (myLibraryEditorComponent != null) {
myLibraryEditorComponent.updateRootsTree();
}
}
}
@@ -0,0 +1,30 @@
/*
* 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;
/**
* @author nik
*/
public abstract class ConfigurationErrorQuickFix {
private final String myActionName;
protected ConfigurationErrorQuickFix(String actionName) {
myActionName = actionName;
}
public String getActionName() {
return myActionName;
}
public abstract void performFix();
}
@@ -9,13 +9,23 @@ import com.intellij.openapi.roots.libraries.Library;
import com.intellij.openapi.roots.libraries.LibraryTable;
import com.intellij.openapi.roots.libraries.LibraryTablesRegistrar;
import com.intellij.openapi.roots.ui.configuration.ModuleEditor;
import com.intellij.openapi.roots.ui.configuration.ProjectStructureConfigurable;
import com.intellij.openapi.roots.ui.configuration.libraryEditor.ExistingLibraryEditor;
import com.intellij.openapi.roots.ui.configuration.projectRoot.LibrariesModifiableModel;
import com.intellij.openapi.roots.ui.configuration.projectRoot.LibraryConfigurable;
import com.intellij.openapi.roots.ui.configuration.projectRoot.StructureConfigurableContext;
import com.intellij.openapi.ui.NamedConfigurable;
import com.intellij.openapi.vfs.VfsUtil;
import com.intellij.ui.navigation.Place;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @author nik
@@ -39,14 +49,41 @@ public class LibraryProjectStructureElement extends ProjectStructureElement {
if (library == null || library.isDisposed()) return;
final String libraryName = library.getName();
if (!library.allPathsValid(OrderRootType.CLASSES)) {
problemsHolder.registerError(ProjectBundle.message("project.roots.tooltip.library.misconfigured", libraryName));
final List<String> 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<String> invalidJavadocs = library.getInvalidRootUrls(JavadocOrderRootType.getInstance());
final List<String> invalidSources = library.getInvalidRootUrls(OrderRootType.SOURCES);
if (!invalidJavadocs.isEmpty() || !invalidSources.isEmpty()) {
final Map<OrderRootType, List<String>> invalidRoots = new HashMap<OrderRootType, List<String>>();
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<String> invalidClasses, String libraryName) {
StringBuilder buffer = new StringBuilder();
buffer.append("<html>");
buffer.append("Library '").append(libraryName).append("' has broken paths:");
for (String url : invalidClasses) {
buffer.append("<br>&nbsp;&nbsp;");
buffer.append(VfsUtil.urlToPath(url));
}
buffer.append("</html>");
return buffer.toString();
}
@NotNull
private Place createPlace() {
return ProjectStructureConfigurable.getInstance(myContext.getProject()).createProjectOrGlobalLibraryPlace(myLibrary);
}
@Override
public List<ProjectStructureElementUsage> 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<OrderRootType, List<String>> myInvalidRoots;
private final Library myLibrary;
public RemoveInvalidRootsQuickFix(Map<OrderRootType, List<String>> 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();
}
}
});
}
}
}
}
@@ -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<ProjectStructureElementUsage> getUsagesInElement() {
final List<ProjectStructureElementUsage> usages = new ArrayList<ProjectStructureElementUsage>();
@@ -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<ConfigurationErrorQuickFix> fixes = myDescription.getFixes();
if (fixes.size() == 1) {
fixes.get(0).performFix();
}
else {
JBPopupFactory.getInstance().createListPopup(new BaseListPopupStep<ConfigurationErrorQuickFix>(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);
}
}
}
@@ -67,7 +67,7 @@ public class ProjectConfigurationProblems {
final List<ProjectStructureProblemDescription> 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() {
}
}
}
@@ -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<ConfigurationErrorQuickFix> 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<ConfigurationErrorQuickFix> fixes) {
myMessage = message;
myDescription = description;
mySeverity = severity;
myPlace = place;
myFixes = fixes;
}
public String getMessage() {
return myMessage;
}
@Nullable
public String getDescription() {
return myDescription;
}
public List<ConfigurationErrorQuickFix> getFixes() {
return myFixes;
}
public Severity getSeverity() {
return mySeverity;
}
public Place getPlace() {
return myPlace;
}
public enum Severity { ERROR, WARNING }
}
@@ -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);
}
@@ -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<ProjectStructureProblemDescription> 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<ConfigurationErrorQuickFix> fixes = fix != null ? Collections.singletonList(fix) : Collections.<ConfigurationErrorQuickFix>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<ConfigurationErrorQuickFix> fixes = Collections.singletonList(fix);
registerProblem(new ProjectStructureProblemDescription(message, description, ProjectStructureProblemDescription.Severity.WARNING, place, fixes));
}
public void registerProblem(final @NotNull ProjectStructureProblemDescription description) {
@@ -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<String> 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();
@@ -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<String> getInvalidRootUrls(OrderRootType type) {
final List<VirtualFilePointer> pointers = myRoots.get(type).getList();
List<String> invalidPaths = null;
for (VirtualFilePointer pointer : pointers) {
if (!pointer.isValid()) {
return false;
if (invalidPaths == null) {
invalidPaths = new SmartList<String>();
}
invalidPaths.add(pointer.getUrl());
}
}
return true;
return invalidPaths != null ? invalidPaths : Collections.<String>emptyList();
}
@Override