From 99a5747bbfe3696aaf0870424fbd45da38599ca8 Mon Sep 17 00:00:00 2001 From: nik Date: Thu, 27 Apr 2017 09:18:14 +0300 Subject: [PATCH] project structure: show warning if any part of configuration for a module imported from an external system is changed manually (IDEA-171948) Previously it showed notification only after change on 'Dependencies' tab, now it listens for changes in all module editors. --- .../ui/configuration/AnnotationsEditor.java | 1 + .../ui/configuration/BuildElementsEditor.java | 4 +++ .../configuration/ContentEntriesEditor.java | 2 +- .../roots/ui/configuration/JavadocEditor.java | 1 + .../LanguageLevelConfigurable.java | 3 ++- .../roots/ui/configuration/ModuleEditor.java | 7 +++++ .../roots/ui/configuration/OutputEditor.java | 18 ++++++------- .../CommonContentEntriesEditor.java | 26 +++++++++++++++++++ .../configuration/ModuleElementsEditor.java | 15 +++++++++++ 9 files changed, 66 insertions(+), 11 deletions(-) diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/AnnotationsEditor.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/AnnotationsEditor.java index bd0f3d58ad52..a30f3e0337f8 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/AnnotationsEditor.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/AnnotationsEditor.java @@ -68,6 +68,7 @@ public class AnnotationsEditor extends ModuleElementsEditor { urls[row] = item.getUrl(); } getModel().getModuleExtension(JavaModuleExternalPaths.class).setExternalAnnotationUrls(urls); + fireConfigurationChanged(); } @Override diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/BuildElementsEditor.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/BuildElementsEditor.java index 72fb6ce4eecb..5364fac750d1 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/BuildElementsEditor.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/BuildElementsEditor.java @@ -76,6 +76,7 @@ public class BuildElementsEditor extends ModuleElementsEditor { public void saveUrl(String url) { if (myInheritCompilerOutput.isSelected()) return; //do not override settings if any getCompilerExtension().setCompilerOutputPath(url); + fireConfigurationChanged(); } }); myTestsOutputPathPanel = createOutputPathPanel(ProjectBundle.message("module.paths.test.output.title"), new CommitPathRunnable() { @@ -83,6 +84,7 @@ public class BuildElementsEditor extends ModuleElementsEditor { public void saveUrl(String url) { if (myInheritCompilerOutput.isSelected()) return; //do not override settings if any getCompilerExtension().setCompilerOutputPathForTests(url); + fireConfigurationChanged(); } }); @@ -91,6 +93,7 @@ public class BuildElementsEditor extends ModuleElementsEditor { @Override public void actionPerformed(final ActionEvent e) { getCompilerExtension().setExcludeOutput(myCbExcludeOutput.isSelected()); + fireConfigurationChanged(); } }); @@ -187,6 +190,7 @@ public class BuildElementsEditor extends ModuleElementsEditor { myCbExcludeOutput.setEnabled(enabled); getCompilerExtension().inheritCompilerOutputPath(!enabled); updateOutputPathPresentation(); + fireConfigurationChanged(); } private CommitableFieldPanel createOutputPathPanel(final String title, final CommitPathRunnable commitPathRunnable) { diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ContentEntriesEditor.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ContentEntriesEditor.java index 9bb8ef5c9c5c..62489a497fe9 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ContentEntriesEditor.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ContentEntriesEditor.java @@ -47,7 +47,7 @@ public class ContentEntriesEditor extends JavaContentEntriesEditor { @Override protected void addAdditionalSettingsToPanel(final JPanel mainPanel) { - myLanguageLevelConfigurable = new LanguageLevelConfigurable(myProject) { + myLanguageLevelConfigurable = new LanguageLevelConfigurable(myProject, this::fireConfigurationChanged) { @NotNull @Override public LanguageLevelModuleExtensionImpl getLanguageLevelExtension() { diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/JavadocEditor.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/JavadocEditor.java index a12c0fe1427e..327f9a4c6827 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/JavadocEditor.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/JavadocEditor.java @@ -71,6 +71,7 @@ public class JavadocEditor extends ModuleElementsEditor { urls[row] = item.getUrl(); } getModel().getModuleExtension(JavaModuleExternalPaths.class).setJavadocUrls(urls); + fireConfigurationChanged(); } @Override diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/LanguageLevelConfigurable.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/LanguageLevelConfigurable.java index 106a0f5f603b..8b8ee7db7705 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/LanguageLevelConfigurable.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/LanguageLevelConfigurable.java @@ -39,7 +39,7 @@ public abstract class LanguageLevelConfigurable implements UnnamedConfigurable { private LanguageLevelCombo myLanguageLevelCombo; private JPanel myPanel = new JPanel(new GridBagLayout()); - public LanguageLevelConfigurable(final Project project) { + public LanguageLevelConfigurable(final Project project, Runnable onChange) { myLanguageLevelCombo = new LanguageLevelCombo(ProjectBundle.message("project.language.level.combo.item")) { @Override protected LanguageLevel getDefaultLevel() { @@ -52,6 +52,7 @@ public abstract class LanguageLevelConfigurable implements UnnamedConfigurable { public void actionPerformed(final ActionEvent e) { final Object languageLevel = myLanguageLevelCombo.getSelectedItem(); getLanguageLevelExtension().setLanguageLevel(languageLevel instanceof LanguageLevel ? (LanguageLevel)languageLevel : null); + onChange.run(); } }); diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ModuleEditor.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ModuleEditor.java index 2a92fc673387..addc09c7cabc 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ModuleEditor.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ModuleEditor.java @@ -221,6 +221,11 @@ public abstract class ModuleEditor implements Place.Navigator, Disposable { } } } + for (ModuleConfigurationEditor editor : myEditors) { + if (editor instanceof ModuleElementsEditor) { + ((ModuleElementsEditor)editor).addListener(this::updateImportedModelWarning); + } + } } private static Set> ourReportedDeprecatedClasses = new HashSet<>(); @@ -297,6 +302,8 @@ public abstract class ModuleEditor implements Place.Navigator, Disposable { } private void updateImportedModelWarning() { + if (!myEditorsInitialized) return; + ProjectModelExternalSource externalSource = ModuleRootManager.getInstance(myModule).getExternalSource(); if (externalSource != null && isModified()) { myModificationOfImportedModelWarningLabel.setVisible(true); diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/OutputEditor.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/OutputEditor.java index deef891e724e..ca9b77d16605 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/OutputEditor.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/OutputEditor.java @@ -32,18 +32,23 @@ import org.jetbrains.annotations.Nullable; import javax.swing.*; import javax.swing.border.EmptyBorder; import java.awt.*; +import java.util.Arrays; +import java.util.List; public class OutputEditor extends ModuleElementsEditor { public static final String NAME = ProjectBundle.message("project.roots.path.tab.title"); private final BuildElementsEditor myCompilerOutputEditor; private final JavadocEditor myJavadocEditor; private final AnnotationsEditor myAnnotationsEditor; + private final List myEditors; protected OutputEditor(final ModuleConfigurationState state) { super(state); myCompilerOutputEditor = new BuildElementsEditor(state); myJavadocEditor = new JavadocEditor(state); myAnnotationsEditor = new AnnotationsEditor(state); + myEditors = Arrays.asList(myCompilerOutputEditor, myJavadocEditor, myAnnotationsEditor); + myEditors.forEach(editor -> editor.addListener(this::fireConfigurationChanged)); } @Override @@ -65,9 +70,8 @@ public class OutputEditor extends ModuleElementsEditor { @Override public void saveData() { - myCompilerOutputEditor.saveData(); - myJavadocEditor.saveData(); - myAnnotationsEditor.saveData(); + super.saveData(); + myEditors.forEach(ModuleElementsEditor::saveData); } @Override @@ -78,18 +82,14 @@ public class OutputEditor extends ModuleElementsEditor { @Override public void moduleStateChanged() { super.moduleStateChanged(); - myCompilerOutputEditor.moduleStateChanged(); - myJavadocEditor.moduleStateChanged(); - myAnnotationsEditor.moduleStateChanged(); + myEditors.forEach(ModuleElementsEditor::moduleStateChanged); } @Override public void moduleCompileOutputChanged(final String baseUrl, final String moduleName) { super.moduleCompileOutputChanged(baseUrl, moduleName); - myCompilerOutputEditor.moduleCompileOutputChanged(baseUrl, moduleName); - myJavadocEditor.moduleCompileOutputChanged(baseUrl, moduleName); - myAnnotationsEditor.moduleCompileOutputChanged(baseUrl, moduleName); + myEditors.forEach(editor -> editor.moduleCompileOutputChanged(baseUrl, moduleName)); } @Override diff --git a/platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/CommonContentEntriesEditor.java b/platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/CommonContentEntriesEditor.java index 16fe5b9a40bc..d27ad9bf8e7a 100644 --- a/platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/CommonContentEntriesEditor.java +++ b/platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/CommonContentEntriesEditor.java @@ -30,6 +30,7 @@ import com.intellij.openapi.project.ProjectBundle; import com.intellij.openapi.roots.ContentEntry; import com.intellij.openapi.roots.ModifiableRootModel; import com.intellij.openapi.roots.ModuleRootModel; +import com.intellij.openapi.roots.SourceFolder; import com.intellij.openapi.roots.ui.componentsList.components.ScrollablePanel; import com.intellij.openapi.roots.ui.componentsList.layout.VerticalStackLayout; import com.intellij.openapi.roots.ui.configuration.actions.IconWithTextAction; @@ -355,6 +356,31 @@ public class CommonContentEntriesEditor extends ModuleElementsEditor { } private final class MyContentEntryEditorListener extends ContentEntryEditorListenerAdapter { + @Override + public void sourceFolderAdded(@NotNull ContentEntryEditor editor, SourceFolder folder) { + fireConfigurationChanged(); + } + + @Override + public void sourceFolderRemoved(@NotNull ContentEntryEditor editor, VirtualFile file) { + fireConfigurationChanged(); + } + + @Override + public void folderExcluded(@NotNull ContentEntryEditor editor, VirtualFile file) { + fireConfigurationChanged(); + } + + @Override + public void folderIncluded(@NotNull ContentEntryEditor editor, String fileUrl) { + fireConfigurationChanged(); + } + + @Override + public void sourceRootPropertiesChanged(@NotNull ContentEntryEditor editor, @NotNull SourceFolder folder) { + fireConfigurationChanged(); + } + @Override public void editingStarted(@NotNull ContentEntryEditor editor) { selectContentEntry(editor.getContentEntryUrl(), true); diff --git a/platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/ModuleElementsEditor.java b/platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/ModuleElementsEditor.java index 786b06bad6f9..e387a973a68c 100644 --- a/platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/ModuleElementsEditor.java +++ b/platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/ModuleElementsEditor.java @@ -24,9 +24,11 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.ModifiableRootModel; import com.intellij.openapi.util.Disposer; import com.intellij.ui.navigation.History; +import com.intellij.util.EventDispatcher; import org.jetbrains.annotations.NotNull; import javax.swing.*; +import java.util.EventListener; /** * @author Eugene Zhuravlev @@ -37,6 +39,7 @@ public abstract class ModuleElementsEditor implements ModuleConfigurationEditor @NotNull protected final Project myProject; protected JComponent myComponent; private final CompositeDisposable myDisposables = new CompositeDisposable(); + private final EventDispatcher myDispatcher = EventDispatcher.create(ModuleElementsEditorListener.class); protected History myHistory; private final ModuleConfigurationState myState; @@ -50,6 +53,14 @@ public abstract class ModuleElementsEditor implements ModuleConfigurationEditor myHistory = history; } + public void addListener(ModuleElementsEditorListener listener) { + myDispatcher.addListener(listener); + } + + protected void fireConfigurationChanged() { + myDispatcher.getMulticaster().configurationChanged(); + } + @Override public boolean isModified() { return getModel() != null && getModel().isChanged(); @@ -98,4 +109,8 @@ public abstract class ModuleElementsEditor implements ModuleConfigurationEditor } protected abstract JComponent createComponentImpl(); + + interface ModuleElementsEditorListener extends EventListener { + void configurationChanged(); + } }