project structure dialog: improved navigation to error places

This commit is contained in:
nik
2011-09-29 12:06:30 +04:00
parent ef68b69e40
commit 3dc8bdf84a
18 changed files with 246 additions and 77 deletions
@@ -49,15 +49,6 @@ public class PackagingElementPath {
return new PackagingElementPath(this, element);
}
@Nullable
public PackagingElementPath getParentPath() {
return myParentPath;
}
public PackagingElement<?> getLastElement() {
return myLastElement;
}
@NotNull
public String getPathString() {
return getPathString("/");
@@ -123,10 +114,6 @@ public class PackagingElementPath {
}
return null;
}
public boolean isEmpty() {
return myParentPath == null;
}
@Nullable
public Artifact findLastArtifact(PackagingElementResolvingContext context) {
@@ -140,4 +127,12 @@ public class PackagingElementPath {
}
return null;
}
public static PackagingElementPath createPath(@NotNull List<PackagingElement<?>> elements) {
PackagingElementPath path = EMPTY;
for (PackagingElement<?> element : elements) {
path = new PackagingElementPath(path, element);
}
return path;
}
}
@@ -20,7 +20,6 @@ import com.intellij.openapi.roots.ui.configuration.projectRoot.daemon.ProjectStr
import com.intellij.packaging.elements.PackagingElement;
import com.intellij.packaging.ui.ArtifactEditor;
import com.intellij.packaging.ui.ArtifactProblemQuickFix;
import com.intellij.ui.navigation.Place;
import com.intellij.util.SmartList;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -38,7 +37,7 @@ public class ArtifactProblemDescription extends ProjectStructureProblemDescripti
@NotNull Severity severity,
@Nullable List<PackagingElement<?>> pathToPlace,
@NotNull List<ArtifactProblemQuickFix> quickFixes,
@NotNull Place place,
@NotNull PlaceInArtifact place,
@NotNull ArtifactEditor artifactEditor) {
super(message, null, severity, place, convertQuickFixed(quickFixes, artifactEditor));
myPathToPlace = pathToPlace;
@@ -15,14 +15,13 @@
*/
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.artifacts.PackagingElementPath;
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;
@@ -47,7 +46,17 @@ public class ArtifactProblemsHolderImpl extends ArtifactProblemsHolderBase {
private void registerProblem(@NotNull String message, @Nullable List<PackagingElement<?>> pathToPlace,
final ProjectStructureProblemDescription.Severity severity, @NotNull ArtifactProblemQuickFix... quickFixes) {
final ArtifactEditorContext context = getContext();
final Place place = ProjectStructureConfigurable.getInstance(context.getProject()).createArtifactPlace(context.getArtifact());
String parentPath;
PackagingElement<?> element;
if (pathToPlace != null && !pathToPlace.isEmpty()) {
parentPath = PackagingElementPath.createPath(pathToPlace.subList(0, pathToPlace.size()-1)).getPathString();
element = pathToPlace.get(pathToPlace.size() - 1);
}
else {
parentPath = null;
element = null;
}
final PlaceInArtifact place = new PlaceInArtifact(context.getArtifact(), ((ArtifactEditorContextImpl)context).getParent(), parentPath, element);
myProblemsHolder.registerProblem(new ArtifactProblemDescription(message, severity, pathToPlace, Arrays.asList(quickFixes), place, context.getThisArtifactEditor()));
}
@@ -53,7 +53,8 @@ public class ArtifactProjectStructureElement extends ProjectStructureElement {
public void check(final ProjectStructureProblemsHolder problemsHolder) {
final ArtifactEditorEx artifactEditor = (ArtifactEditorEx)myArtifactsStructureContext.getOrCreateEditor(myOriginalArtifact);
final Artifact artifact = artifactEditor.getArtifact();
artifact.getArtifactType().checkRootElement(artifactEditor.getRootElement(), artifact, new ArtifactProblemsHolderImpl(artifactEditor.getContext(), problemsHolder));
final ArtifactProblemsHolderImpl artifactProblemsHolder = new ArtifactProblemsHolderImpl(artifactEditor.getContext(), problemsHolder);
artifact.getArtifactType().checkRootElement(artifactEditor.getRootElement(), artifact, artifactProblemsHolder);
}
public Artifact getOriginalArtifact() {
@@ -0,0 +1,56 @@
/*
* Copyright 2000-2011 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.artifacts;
import com.intellij.openapi.roots.ui.configuration.ProjectStructureConfigurable;
import com.intellij.openapi.roots.ui.configuration.projectRoot.daemon.PlaceInProjectStructure;
import com.intellij.openapi.util.ActionCallback;
import com.intellij.packaging.artifacts.Artifact;
import com.intellij.packaging.elements.PackagingElement;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* @author nik
*/
public class PlaceInArtifact extends PlaceInProjectStructure {
private final Artifact myArtifact;
private final ArtifactsStructureConfigurableContext myContext;
private final String myParentPath;
private final PackagingElement<?> myPackagingElement;
public PlaceInArtifact(Artifact artifact, ArtifactsStructureConfigurableContext context, @Nullable String parentPath,
@Nullable PackagingElement<?> packagingElement) {
myArtifact = artifact;
myContext = context;
myParentPath = parentPath;
myPackagingElement = packagingElement;
}
@NotNull
@Override
public ActionCallback navigate() {
final Artifact artifact = myContext.getArtifactModel().getArtifactByOriginal(myArtifact);
return ProjectStructureConfigurable.getInstance(myContext.getProject()).select(myArtifact, true).doWhenDone(new Runnable() {
public void run() {
final ArtifactEditorEx artifactEditor = (ArtifactEditorEx)myContext.getOrCreateEditor(artifact);
if (myParentPath != null && myPackagingElement != null) {
artifactEditor.getLayoutTreeComponent().selectNode(myParentPath, myPackagingElement);
}
}
});
}
}
@@ -1,6 +1,6 @@
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.PlaceInProjectStructure;
import com.intellij.openapi.roots.ui.configuration.projectRoot.daemon.ProjectStructureElement;
import com.intellij.openapi.roots.ui.configuration.projectRoot.daemon.ProjectStructureElementUsage;
import com.intellij.packaging.artifacts.Artifact;
@@ -40,17 +40,6 @@ public class UsageInArtifact extends ProjectStructureElementUsage {
return myContainingElement;
}
@Override
public void navigate() {
final Artifact artifact = myContext.getArtifactModel().getArtifactByOriginal(myOriginalArtifact);
ProjectStructureConfigurable.getInstance(myContext.getProject()).select(myOriginalArtifact, true).doWhenDone(new Runnable() {
public void run() {
final ArtifactEditorEx artifactEditor = (ArtifactEditorEx)myContext.getOrCreateEditor(artifact);
artifactEditor.getLayoutTreeComponent().selectNode(myParentPath, myPackagingElement);
}
});
}
public void removeElement() {
getOrCreateEditor().removePackagingElement(myParentPath, myPackagingElement);
}
@@ -68,6 +57,11 @@ public class UsageInArtifact extends ProjectStructureElementUsage {
return myOriginalArtifact.getName();
}
@Override
public PlaceInProjectStructure getPlace() {
return new PlaceInArtifact(myOriginalArtifact, myContext, myParentPath, myPackagingElement);
}
@Override
public int hashCode() {
return myOriginalArtifact.hashCode();
@@ -81,7 +81,7 @@ public abstract class FindUsagesInProjectStructureActionBase extends AnAction im
JBPopupFactory.getInstance().createListPopup(new BaseListPopupStep<ProjectStructureElementUsage>(ProjectBundle.message("dependencies.used.in.popup.title"), usagesArray) {
@Override
public PopupStep onChosen(final ProjectStructureElementUsage selected, final boolean finalChoice) {
selected.navigate();
selected.getPlace().navigate();
return FINAL_CHOICE;
}
@@ -1,5 +1,6 @@
package com.intellij.openapi.roots.ui.configuration.projectRoot.daemon;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.project.ProjectBundle;
import com.intellij.openapi.roots.JavadocOrderRootType;
import com.intellij.openapi.roots.OrderRootType;
@@ -16,7 +17,6 @@ import com.intellij.openapi.roots.ui.configuration.projectRoot.LibraryConfigurab
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;
@@ -80,8 +80,9 @@ public class LibraryProjectStructureElement extends ProjectStructureElement {
}
@NotNull
private Place createPlace() {
return ProjectStructureConfigurable.getInstance(myContext.getProject()).createProjectOrGlobalLibraryPlace(myLibrary);
private PlaceInProjectStructure createPlace() {
final Project project = myContext.getProject();
return new PlaceInProjectStructureBase(project, ProjectStructureConfigurable.getInstance(project).createProjectOrGlobalLibraryPlace(myLibrary));
}
@Override
@@ -144,7 +145,7 @@ public class LibraryProjectStructureElement extends ProjectStructureElement {
}
myContext.getDaemonAnalyzer().queueUpdate(LibraryProjectStructureElement.this);
final ProjectStructureConfigurable structureConfigurable = ProjectStructureConfigurable.getInstance(myContext.getProject());
structureConfigurable.navigateTo(createPlace(), true).doWhenDone(new Runnable() {
createPlace().navigate().doWhenDone(new Runnable() {
@Override
public void run() {
final NamedConfigurable configurable = structureConfigurable.getConfigurableFor(myLibrary).getSelectedConfugurable();
@@ -2,6 +2,7 @@ package com.intellij.openapi.roots.ui.configuration.projectRoot.daemon;
import com.intellij.openapi.module.ModifiableModuleModel;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.project.ProjectBundle;
import com.intellij.openapi.projectRoots.Sdk;
import com.intellij.openapi.roots.*;
@@ -9,7 +10,6 @@ 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;
@@ -52,10 +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"), null, createPlace(), null);
} else {
problemsHolder.registerError(ProjectBundle.message("project.roots.module.jdk.problem.message"), null, createPlace(entry), null);
}
else {
problemsHolder.registerError(ProjectBundle.message("project.roots.library.problem.message", entry.getPresentableName()), null,
createPlace(),
createPlace(entry),
null);
}
}
@@ -74,8 +75,13 @@ public class ModuleProjectStructureElement extends ProjectStructureElement {
}
}
private Place createPlace() {
return ProjectStructureConfigurable.getInstance(myContext.getProject()).createModulePlace(myModule);
private PlaceInProjectStructure createPlace() {
final Project project = myContext.getProject();
return new PlaceInProjectStructureBase(project, ProjectStructureConfigurable.getInstance(project).createModulePlace(myModule));
}
private PlaceInProjectStructure createPlace(OrderEntry entry) {
return new PlaceInModuleClasspath(myContext, myModule, entry);
}
@Override
@@ -0,0 +1,64 @@
/*
* Copyright 2000-2011 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.module.Module;
import com.intellij.openapi.roots.ModuleRootModel;
import com.intellij.openapi.roots.OrderEntry;
import com.intellij.openapi.roots.impl.OrderEntryUtil;
import com.intellij.openapi.roots.ui.configuration.ProjectStructureConfigurable;
import com.intellij.openapi.roots.ui.configuration.projectRoot.StructureConfigurableContext;
import com.intellij.openapi.util.ActionCallback;
import org.jetbrains.annotations.NotNull;
/**
* @author nik
*/
public class PlaceInModuleClasspath extends PlaceInProjectStructure {
private StructureConfigurableContext myContext;
private Module myModule;
private OrderEntry myOrderEntry;
public PlaceInModuleClasspath(StructureConfigurableContext context, Module module, OrderEntry orderEntry) {
myContext = context;
myModule = module;
myOrderEntry = orderEntry;
}
public PlaceInModuleClasspath(@NotNull StructureConfigurableContext context, @NotNull Module module, @NotNull ProjectStructureElement elementInClasspath) {
myContext = context;
myModule = module;
ModuleRootModel rootModel = myContext.getModulesConfigurator().getRootModel(myModule);
if (elementInClasspath instanceof LibraryProjectStructureElement) {
myOrderEntry = OrderEntryUtil.findLibraryOrderEntry(rootModel, ((LibraryProjectStructureElement)elementInClasspath).getLibrary());
}
else if (elementInClasspath instanceof ModuleProjectStructureElement) {
myOrderEntry = OrderEntryUtil.findModuleOrderEntry(rootModel, ((ModuleProjectStructureElement)elementInClasspath).getModule());
}
else if (elementInClasspath instanceof SdkProjectStructureElement) {
myOrderEntry = OrderEntryUtil.findJdkOrderEntry(rootModel, ((SdkProjectStructureElement)elementInClasspath).getSdk());
}
else {
myOrderEntry = null;
}
}
@NotNull
@Override
public ActionCallback navigate() {
return ProjectStructureConfigurable.getInstance(myContext.getProject()).selectOrderEntry(myModule, myOrderEntry);
}
}
@@ -0,0 +1,27 @@
/*
* Copyright 2000-2011 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.util.ActionCallback;
import org.jetbrains.annotations.NotNull;
/**
* @author nik
*/
public abstract class PlaceInProjectStructure {
@NotNull
public abstract ActionCallback navigate();
}
@@ -0,0 +1,41 @@
/*
* Copyright 2000-2011 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.project.Project;
import com.intellij.openapi.roots.ui.configuration.ProjectStructureConfigurable;
import com.intellij.openapi.util.ActionCallback;
import com.intellij.ui.navigation.Place;
import org.jetbrains.annotations.NotNull;
/**
* @author nik
*/
public class PlaceInProjectStructureBase extends PlaceInProjectStructure {
private final Project myProject;
private final Place myPlace;
public PlaceInProjectStructureBase(Project project, Place place) {
myProject = project;
myPlace = place;
}
@NotNull
@Override
public ActionCallback navigate() {
return ProjectStructureConfigurable.getInstance(myProject).navigateTo(myPlace, true);
}
}
@@ -38,7 +38,7 @@ class ProjectConfigurationProblem extends ConfigurationError {
@Override
public void navigate() {
ProjectStructureConfigurable.getInstance(myContext.getProject()).navigateTo(myDescription.getPlace(), true);
myDescription.getPlace().navigate();
}
@Override
@@ -12,7 +12,7 @@ public abstract class ProjectStructureElementUsage {
public abstract String getPresentableName();
public abstract void navigate();
public abstract PlaceInProjectStructure getPlace();
@Override
public abstract int hashCode();
@@ -15,7 +15,6 @@
*/
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;
@@ -28,10 +27,10 @@ public class ProjectStructureProblemDescription {
private final String myMessage;
private final String myDescription;
private final Severity mySeverity;
private final Place myPlace;
private final PlaceInProjectStructure myPlace;
private final List<ConfigurationErrorQuickFix> myFixes;
public ProjectStructureProblemDescription(@NotNull String message, @Nullable String description, @NotNull Severity severity, @NotNull Place place,
public ProjectStructureProblemDescription(@NotNull String message, @Nullable String description, @NotNull Severity severity, @NotNull PlaceInProjectStructure place,
@NotNull List<ConfigurationErrorQuickFix> fixes) {
myMessage = message;
myDescription = description;
@@ -57,7 +56,7 @@ public class ProjectStructureProblemDescription {
return mySeverity;
}
public Place getPlace() {
public PlaceInProjectStructure getPlace() {
return myPlace;
}
@@ -15,7 +15,6 @@
*/
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;
@@ -23,9 +22,9 @@ import org.jetbrains.annotations.Nullable;
* @author nik
*/
public interface ProjectStructureProblemsHolder {
void registerError(@NotNull String message, @Nullable String description, @NotNull Place place, @Nullable ConfigurationErrorQuickFix fix);
void registerError(@NotNull String message, @Nullable String description, @NotNull PlaceInProjectStructure place, @Nullable ConfigurationErrorQuickFix fix);
void registerWarning(@NotNull String message, @Nullable String description, @NotNull Place place, @Nullable ConfigurationErrorQuickFix fix);
void registerWarning(@NotNull String message, @Nullable String description, @NotNull PlaceInProjectStructure place, @Nullable ConfigurationErrorQuickFix fix);
void registerProblem(@NotNull ProjectStructureProblemDescription description);
}
@@ -1,7 +1,6 @@
package com.intellij.openapi.roots.ui.configuration.projectRoot.daemon;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.ui.navigation.Place;
import com.intellij.util.SmartList;
import com.intellij.util.StringBuilderSpinAllocator;
import org.jetbrains.annotations.NotNull;
@@ -16,12 +15,12 @@ import java.util.List;
public class ProjectStructureProblemsHolderImpl implements ProjectStructureProblemsHolder {
private List<ProjectStructureProblemDescription> myProblemDescriptions;
public void registerError(@NotNull String message, String description, @NotNull Place place, @Nullable ConfigurationErrorQuickFix fix) {
public void registerError(@NotNull String message, String description, @NotNull PlaceInProjectStructure 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, String description, @NotNull Place place, @Nullable ConfigurationErrorQuickFix fix) {
public void registerWarning(@NotNull String message, String description, @NotNull PlaceInProjectStructure place, @Nullable ConfigurationErrorQuickFix fix) {
final List<ConfigurationErrorQuickFix> fixes = Collections.singletonList(fix);
registerProblem(new ProjectStructureProblemDescription(message, description, ProjectStructureProblemDescription.Severity.WARNING, place, fixes));
}
@@ -2,11 +2,6 @@ package com.intellij.openapi.roots.ui.configuration.projectRoot.daemon;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleType;
import com.intellij.openapi.roots.ModuleRootModel;
import com.intellij.openapi.roots.OrderEntry;
import com.intellij.openapi.roots.impl.OrderEntryUtil;
import com.intellij.openapi.roots.ui.configuration.ModulesConfigurator;
import com.intellij.openapi.roots.ui.configuration.ProjectStructureConfigurable;
import com.intellij.openapi.roots.ui.configuration.projectRoot.StructureConfigurableContext;
import org.jetbrains.annotations.NotNull;
@@ -49,24 +44,8 @@ public class UsageInModuleClasspath extends ProjectStructureElementUsage {
}
@Override
public void navigate() {
ModulesConfigurator modulesConfigurator = myContext.getModulesConfigurator();
ModuleRootModel rootModel = modulesConfigurator.getRootModel(myModule);
OrderEntry entry;
if (mySourceElement instanceof LibraryProjectStructureElement) {
entry = OrderEntryUtil.findLibraryOrderEntry(rootModel, ((LibraryProjectStructureElement)mySourceElement).getLibrary());
}
else if (mySourceElement instanceof ModuleProjectStructureElement) {
entry = OrderEntryUtil.findModuleOrderEntry(rootModel, ((ModuleProjectStructureElement)mySourceElement).getModule());
}
else if (mySourceElement instanceof SdkProjectStructureElement) {
entry = OrderEntryUtil.findJdkOrderEntry(rootModel, ((SdkProjectStructureElement)mySourceElement).getSdk());
}
else {
entry = null;
}
ProjectStructureConfigurable.getInstance(myContext.getProject()).selectOrderEntry(myModule, entry);
public PlaceInProjectStructure getPlace() {
return new PlaceInModuleClasspath(myContext, myModule, mySourceElement);
}
@Override