From faa19394c30749ccfa66a5c1acebeb5a17118744 Mon Sep 17 00:00:00 2001 From: Dmitry Batkovich Date: Tue, 14 Feb 2017 15:18:48 +0300 Subject: [PATCH] schemes ui: move inspection settings to schemes management ui --- .../actions/CodeInspectionAction.java | 8 +- .../ui/InspectionProfileImporter.java | 49 ++ .../header/InspectionProfileSchemesModel.java | 203 +++++++++ .../header/InspectionProfileSchemesPanel.java | 271 +++++++++++ .../header/InspectionToolsConfigurable.java | 427 ++---------------- .../ui/header/ManageButton.java | 158 ------- .../ui/header/ManageButtonBuilder.java | 45 -- .../ui/header/ProfilesChooser.java | 86 ---- .../ui/header/ProfilesComboBox.java | 167 ------- .../header/SaveInputComponentValidator.java | 61 --- .../ui/header/ValidatedTextField.java | 132 ------ .../src/META-INF/LangExtensions.xml | 9 + 12 files changed, 577 insertions(+), 1039 deletions(-) create mode 100644 platform/lang-impl/src/com/intellij/profile/codeInspection/ui/InspectionProfileImporter.java create mode 100644 platform/lang-impl/src/com/intellij/profile/codeInspection/ui/header/InspectionProfileSchemesModel.java create mode 100644 platform/lang-impl/src/com/intellij/profile/codeInspection/ui/header/InspectionProfileSchemesPanel.java delete mode 100644 platform/lang-impl/src/com/intellij/profile/codeInspection/ui/header/ManageButton.java delete mode 100644 platform/lang-impl/src/com/intellij/profile/codeInspection/ui/header/ManageButtonBuilder.java delete mode 100644 platform/lang-impl/src/com/intellij/profile/codeInspection/ui/header/ProfilesChooser.java delete mode 100644 platform/lang-impl/src/com/intellij/profile/codeInspection/ui/header/ProfilesComboBox.java delete mode 100644 platform/lang-impl/src/com/intellij/profile/codeInspection/ui/header/SaveInputComponentValidator.java delete mode 100644 platform/lang-impl/src/com/intellij/profile/codeInspection/ui/header/ValidatedTextField.java diff --git a/platform/lang-impl/src/com/intellij/codeInspection/actions/CodeInspectionAction.java b/platform/lang-impl/src/com/intellij/codeInspection/actions/CodeInspectionAction.java index e4179b204bf7..c7b07ec9bcd0 100644 --- a/platform/lang-impl/src/com/intellij/codeInspection/actions/CodeInspectionAction.java +++ b/platform/lang-impl/src/com/intellij/codeInspection/actions/CodeInspectionAction.java @@ -34,6 +34,7 @@ import com.intellij.profile.codeInspection.InspectionProfileManager; import com.intellij.profile.codeInspection.InspectionProjectProfileManager; import com.intellij.profile.codeInspection.ProjectInspectionProfileManager; import com.intellij.profile.codeInspection.ui.ErrorsConfigurable; +import com.intellij.profile.codeInspection.ui.header.InspectionProfileSchemesModel; import com.intellij.profile.codeInspection.ui.header.InspectionToolsConfigurable; import com.intellij.ui.ComboboxWithBrowseButton; import com.intellij.ui.SimpleTextAttributes; @@ -43,8 +44,6 @@ import org.jetbrains.annotations.NotNull; import javax.swing.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; -import java.util.ArrayList; -import java.util.List; public class CodeInspectionAction extends BaseAnalysisAction { private static final Logger LOG = Logger.getInstance(CodeInspectionAction.class); @@ -176,10 +175,7 @@ public class CodeInspectionAction extends BaseAnalysisAction { InspectionProfileManager appProfileManager, InspectionProjectProfileManager projectProfileManager, Project project) { - List profiles = new ArrayList<>(); - profiles.addAll(appProfileManager.getProfiles()); - profiles.addAll(projectProfileManager.getProfiles()); - profilesCombo.resetSchemes(profiles); + profilesCombo.resetSchemes(InspectionProfileSchemesModel.getSortedProfiles(appProfileManager, projectProfileManager)); InspectionProfileImpl selectedProfile = getProfileToUse(project, appProfileManager, projectProfileManager); profilesCombo.selectScheme(selectedProfile); } diff --git a/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/InspectionProfileImporter.java b/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/InspectionProfileImporter.java new file mode 100644 index 000000000000..9b3028ad346e --- /dev/null +++ b/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/InspectionProfileImporter.java @@ -0,0 +1,49 @@ +/* + * Copyright 2000-2017 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.profile.codeInspection.ui; + +import com.intellij.codeInspection.ex.NewInspectionProfile; +import com.intellij.openapi.options.SchemeFactory; +import com.intellij.openapi.options.SchemeImportException; +import com.intellij.openapi.options.SchemeImporter; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.vfs.VirtualFile; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +//TODO should replace current implementation +public class InspectionProfileImporter implements SchemeImporter { + @NotNull + @Override + public String[] getSourceExtensions() { + return new String[] {"xml"}; + } + + @Nullable + @Override + public NewInspectionProfile importScheme(@NotNull Project project, + @NotNull VirtualFile selectedFile, + @NotNull NewInspectionProfile currentScheme, + @NotNull SchemeFactory schemeFactory) throws SchemeImportException { + throw new UnsupportedOperationException(); + } + + @Nullable + @Override + public String getAdditionalImportInfo(@NotNull NewInspectionProfile scheme) { + return null; + } +} diff --git a/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/header/InspectionProfileSchemesModel.java b/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/header/InspectionProfileSchemesModel.java new file mode 100644 index 000000000000..db4399ca09f0 --- /dev/null +++ b/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/header/InspectionProfileSchemesModel.java @@ -0,0 +1,203 @@ +/* + * Copyright 2000-2017 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.profile.codeInspection.ui.header; + +import com.intellij.application.options.schemes.SchemesModel; +import com.intellij.codeInspection.ex.InspectionProfileImpl; +import com.intellij.codeInspection.ex.InspectionProfileModifiableModel; +import com.intellij.profile.codeInspection.InspectionProfileManager; +import com.intellij.profile.codeInspection.ui.SingleInspectionProfilePanel; +import com.intellij.util.Consumer; +import com.intellij.util.SmartList; +import com.intellij.util.containers.ContainerUtil; +import org.jetbrains.annotations.NotNull; + +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + +public abstract class InspectionProfileSchemesModel implements SchemesModel { + private final List myProfilePanels = new ArrayList<>(); + private final List myDeletedProfiles = new SmartList<>(); + + private final InspectionProfileManager myApplicationProfileManager; + private final InspectionProfileManager myProjectProfileManager; + + protected InspectionProfileSchemesModel(@NotNull InspectionProfileManager appProfileManager, + @NotNull InspectionProfileManager projectProfileManager) { + myApplicationProfileManager = appProfileManager; + myProjectProfileManager = projectProfileManager; + } + + @Override + public boolean canDuplicateScheme(@NotNull InspectionProfileModifiableModel profile) { + return true; + } + + @Override + public boolean canResetScheme(@NotNull InspectionProfileModifiableModel profile) { + return true; + } + + @Override + public boolean canDeleteScheme(@NotNull InspectionProfileModifiableModel profile) { + boolean projectProfileFound = false; + boolean ideProfileFound = false; + + for (SingleInspectionProfilePanel profilePanel : myProfilePanels) { + final InspectionProfileModifiableModel profile1 = profilePanel.getProfile(); + if (profile == profile1) continue; + final boolean isProjectProfile = profile1.getProfileManager() == myProjectProfileManager; + projectProfileFound |= isProjectProfile; + ideProfileFound |= !isProjectProfile; + + if (ideProfileFound && projectProfileFound) break; + } + + return profile.getProfileManager() == myProjectProfileManager ? projectProfileFound : ideProfileFound; + } + + @Override + public boolean isProjectScheme(@NotNull InspectionProfileModifiableModel profile) { + return profile.isProjectLevel(); + } + + @Override + public boolean canRenameScheme(@NotNull InspectionProfileModifiableModel profile) { + return true; + } + + @Override + public boolean containsScheme(@NotNull String name, boolean isProjectProfile) { + return hasName(name, isProjectProfile); + } + + @Override + public boolean differsFromDefault(@NotNull InspectionProfileModifiableModel profile) { + return false; + } + + @Override + public void removeScheme(@NotNull InspectionProfileModifiableModel profile) { + final SingleInspectionProfilePanel panel = getProfilePanel(profile); + removeProfile(profile); + myDeletedProfiles.add(profile); + onProfileRemoved(panel); + } + + protected abstract void onProfileRemoved(@NotNull SingleInspectionProfilePanel profilePanel); + + @Override + public boolean supportsProjectSchemes() { + return true; + } + + void addProfile(InspectionProfileModifiableModel profile) { + myProfilePanels.add(createPanel(profile)); + } + + void removeProfile(InspectionProfileImpl profile) { + for (SingleInspectionProfilePanel panel : myProfilePanels) { + if (panel.getProfile().equals(profile)) { + myProfilePanels.remove(panel); + break; + } + } + } + + void updatePanel(@NotNull InspectionProfileSchemesPanel panel) { + final List allProfiles = myProfilePanels.stream().map(p -> p.getProfile()).collect(Collectors.toList()); + panel.resetSchemes(allProfiles); + } + + void apply(InspectionProfileModifiableModel selected, Consumer applyRootProfileAction) { + for (InspectionProfileImpl profile : myDeletedProfiles) { + profile.getProfileManager().deleteProfile(profile); + } + myDeletedProfiles.clear(); + + SingleInspectionProfilePanel selectedPanel = getProfilePanel(selected); + for (SingleInspectionProfilePanel panel : getProfilePanels()) { + panel.apply(); + if (panel == selectedPanel) { + applyRootProfileAction.consume(panel.getProfile()); + } + } + } + + void reset() { + disposeUI(); + myDeletedProfiles.clear(); + getSortedProfiles(myApplicationProfileManager, myProjectProfileManager) + .stream() + .map(InspectionProfileModifiableModel::new) + .forEach(this::addProfile); + } + + void disposeUI() { + for (SingleInspectionProfilePanel panel : myProfilePanels) { + panel.disposeUI(); + } + myProfilePanels.clear(); + } + + public SingleInspectionProfilePanel getProfilePanel(InspectionProfileImpl profile) { + return myProfilePanels.stream().filter(panel -> panel.getProfile().equals(profile)).findFirst().orElse(null); + } + + protected abstract SingleInspectionProfilePanel createPanel(InspectionProfileModifiableModel model); + + boolean hasName(@NotNull final String name, boolean shared) { + final boolean hasName = myProfilePanels.stream().map(SingleInspectionProfilePanel::getProfile).anyMatch(p -> name.equals(p.getName()) && p.isProjectLevel() == shared); + if (hasName) return true; + return myProfilePanels.stream().anyMatch(p -> { + final InspectionProfileModifiableModel profile = p.getProfile(); + return name.equals(profile.getName()) && profile.isProjectLevel() == shared; + }); + } + + List getProfilePanels() { + return myProfilePanels; + } + + int getSize() { + return myProfilePanels.size(); + } + + boolean hasDeletedProfiles() { + return !myDeletedProfiles.isEmpty(); + } + + @NotNull + InspectionProfileModifiableModel getModifiableModelFor(@NotNull InspectionProfileImpl profile) { + if (profile instanceof InspectionProfileModifiableModel) { + return (InspectionProfileModifiableModel)profile; + } + for (SingleInspectionProfilePanel panel : myProfilePanels) { + final InspectionProfileModifiableModel modifiableModel = panel.getProfile(); + if (modifiableModel.getSource().equals(profile)) { + return modifiableModel; + } + } + throw new AssertionError(); + } + + public static List getSortedProfiles(InspectionProfileManager appManager, + InspectionProfileManager projectManager) { + return ContainerUtil.concat(ContainerUtil.sorted(appManager.getProfiles()), + ContainerUtil.sorted(projectManager.getProfiles())); + } +} diff --git a/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/header/InspectionProfileSchemesPanel.java b/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/header/InspectionProfileSchemesPanel.java new file mode 100644 index 000000000000..1289e2c2945c --- /dev/null +++ b/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/header/InspectionProfileSchemesPanel.java @@ -0,0 +1,271 @@ +/* + * Copyright 2000-2017 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.profile.codeInspection.ui.header; + +import com.intellij.application.options.schemes.AbstractDescriptionAwareSchemesPanel; +import com.intellij.application.options.schemes.AbstractSchemeActions; +import com.intellij.application.options.schemes.DescriptionAwareSchemeActions; +import com.intellij.application.options.schemes.SchemeNameGenerator; +import com.intellij.codeInspection.ex.InspectionProfileImpl; +import com.intellij.codeInspection.ex.InspectionProfileModifiableModel; +import com.intellij.codeInspection.ex.InspectionToolRegistrar; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.fileChooser.FileChooser; +import com.intellij.openapi.fileChooser.FileChooserDescriptor; +import com.intellij.openapi.fileChooser.FileChooserDescriptorFactory; +import com.intellij.openapi.fileTypes.StdFileTypes; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.Messages; +import com.intellij.openapi.util.Comparing; +import com.intellij.openapi.util.InvalidDataException; +import com.intellij.openapi.util.JDOMUtil; +import com.intellij.openapi.util.io.FileUtil; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.profile.codeInspection.BaseInspectionProfileManager; +import com.intellij.profile.codeInspection.ui.SingleInspectionProfilePanel; +import com.intellij.util.containers.ContainerUtil; +import org.jdom.Element; +import org.jdom.JDOMException; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.io.File; +import java.io.IOException; +import java.util.List; +import java.util.stream.Collectors; + +import static com.intellij.openapi.util.io.FileUtil.sanitizeFileName; + +public class InspectionProfileSchemesPanel extends AbstractDescriptionAwareSchemesPanel { + private final static Logger LOG = Logger.getInstance(InspectionProfileSchemesPanel.class); + + private final Project myProject; + private final BaseInspectionProfileManager myAppProfileManager; + private final BaseInspectionProfileManager myProjectProfileManager; + private final InspectionToolsConfigurable myConfigurable; + private final InspectionProfileSchemesModel myModel; + + InspectionProfileSchemesPanel(@NotNull Project project, + @NotNull BaseInspectionProfileManager appProfileManager, + @NotNull BaseInspectionProfileManager projectProfileManager, + @NotNull InspectionToolsConfigurable configurable) { + myProject = project; + myAppProfileManager = appProfileManager; + myProjectProfileManager = projectProfileManager; + myConfigurable = configurable; + myModel = new InspectionProfileSchemesModel(appProfileManager, projectProfileManager) { + @Override + protected void onProfileRemoved(@NotNull SingleInspectionProfilePanel profilePanel) { + myConfigurable.removeProfilePanel(profilePanel); + final List currentProfiles = getModel() + .getProfilePanels() + .stream() + .map(SingleInspectionProfilePanel::getProfile) + .collect(Collectors.toList()); + resetSchemes(currentProfiles); + selectScheme(ContainerUtil.getFirstItem(currentProfiles)); + } + + @Override + protected SingleInspectionProfilePanel createPanel(InspectionProfileModifiableModel model) { + return myConfigurable.createPanel(model); + } + }; + } + + @NotNull + @Override + public InspectionProfileSchemesModel getModel() { + return myModel; + } + + @Override + protected AbstractSchemeActions createSchemeActions() { + return new DescriptionAwareSchemeActions(this) { + @Nullable + @Override + public String getDescription(@NotNull InspectionProfileModifiableModel scheme) { + SingleInspectionProfilePanel inspectionProfile = ((InspectionProfileSchemesModel) getModel()).getProfilePanel(scheme); + return inspectionProfile.getProfile().getDescription(); + } + + @Override + protected void setDescription(@NotNull InspectionProfileModifiableModel scheme, @NotNull String newDescription) { + InspectionProfileModifiableModel inspectionProfile = InspectionProfileSchemesPanel.this.getModel().getProfilePanel(scheme).getProfile(); + if (!Comparing.strEqual(newDescription, inspectionProfile.getDescription())) { + inspectionProfile.setDescription(newDescription); + inspectionProfile.setModified(true); + } + } + + @Override + protected void importScheme(@NotNull String importerName) { + final FileChooserDescriptor descriptor = new FileChooserDescriptor(true, false, false, false, false, false) { + @Override + public boolean isFileSelectable(VirtualFile file) { + return file.getFileType().equals(StdFileTypes.XML); + } + }; + descriptor.setDescription("Choose profile file"); + FileChooser.chooseFile(descriptor, myProject, null, file -> { + if (file != null) { + final InspectionProfileImpl profile; + try { + profile = InspectionToolsConfigurable + .importInspectionProfile(JDOMUtil.load(file.getInputStream()), myAppProfileManager, myProject); + final SingleInspectionProfilePanel existed = InspectionProfileSchemesPanel.this.getModel().getProfilePanel(profile); + if (existed != null) { + if (Messages.showOkCancelDialog(myProject, "Profile with name \'" + + profile.getName() + + "\' already exists. Do you want to overwrite it?", "Warning", + Messages.getInformationIcon()) != Messages.OK) { + return; + } + getModel().removeScheme(existed.getProfile()); + } + InspectionProfileModifiableModel model = new InspectionProfileModifiableModel(profile); + model.setModified(true); + addProfile(model); + selectScheme(model); + } + catch (JDOMException | InvalidDataException | IOException e) { + LOG.error(e); + } + } + }); + } + + @Override + protected void resetScheme(@NotNull InspectionProfileModifiableModel scheme) { + throw new UnsupportedOperationException(); + } + + @Override + protected void duplicateScheme(@NotNull InspectionProfileModifiableModel scheme, @NotNull String newName) { + final InspectionProfileModifiableModel newProfile = copyToNewProfile(scheme, myProject, newName, false); + addProfile(newProfile); + myConfigurable.selectProfile(newProfile); + selectScheme(newProfile); + } + + @Override + protected void exportScheme(@NotNull InspectionProfileModifiableModel scheme, @NotNull String exporterName) { + FileChooserDescriptor descriptor = FileChooserDescriptorFactory.createSingleFolderDescriptor(); + descriptor.setDescription("Choose directory to store profile file"); + FileChooser.chooseFile(descriptor, myProject, null, dir -> { + try { + LOG.assertTrue(true); + Element element = scheme.writeScheme(false); + File file = new File(FileUtil.toSystemDependentName(dir.getPath()), sanitizeFileName(scheme.getName()) + ".xml"); + if (file.isFile() && + Messages.showOkCancelDialog(myProject, "File \'" + file + "\' already exist. Do you want to overwrite it?", "Warning", + Messages.getQuestionIcon()) != Messages.OK) { + return; + } + + JDOMUtil.writeParent(element, file, "\n"); + } + catch (IOException e1) { + LOG.error(e1); + } + }); + + } + + @Override + protected void onSchemeChanged(@Nullable InspectionProfileModifiableModel scheme) { + super.onSchemeChanged(scheme); + if (scheme != null) { + myConfigurable.selectProfile(scheme); + } + } + + @Override + protected void renameScheme(@NotNull InspectionProfileModifiableModel scheme, @NotNull String newName) { + scheme.setName(newName); + } + + @Override + protected void copyToProject(@NotNull InspectionProfileModifiableModel scheme) { + copyToAnotherLevel(scheme, true); + } + + @Override + protected void copyToIDE(@NotNull InspectionProfileModifiableModel scheme) { + copyToAnotherLevel(scheme, false); + } + + @Override + protected Class getSchemeType() { + return InspectionProfileModifiableModel.class; + } + + private void copyToAnotherLevel(InspectionProfileModifiableModel profile, boolean copyToProject) { + String name = SchemeNameGenerator.getUniqueName(profile.getName(), schemeName -> ((InspectionProfileSchemesModel)getModel()).hasName(schemeName, copyToProject)); + final InspectionProfileModifiableModel newProfile = copyToNewProfile(profile, myProject, name, true); + addProfile(newProfile); + selectScheme(newProfile); + getSchemesPanel().startEdit(); + } + }; + } + + @Override + protected String getTitle() { + return "Profile:"; + } + + void apply() { + getModel().apply(getSelectedScheme(), (p) -> { + if (myConfigurable.setActiveProfileAsDefaultOnApply()) { + myConfigurable.applyRootProfile(p.getName(), p.isProjectLevel()); + } + }); + } + + void reset() { + getModel().reset(); + getModel().updatePanel(this); + } + + @NotNull + private InspectionProfileModifiableModel copyToNewProfile(@NotNull InspectionProfileImpl selectedProfile, + @NotNull Project project, + @NotNull String newName, + boolean modifyLevel) { + final boolean isProjectLevel = selectedProfile.isProjectLevel() ^ modifyLevel; + + BaseInspectionProfileManager profileManager = isProjectLevel ? myProjectProfileManager : myAppProfileManager; + InspectionProfileImpl inspectionProfile = + new InspectionProfileImpl(newName, InspectionToolRegistrar.getInstance(), profileManager); + + inspectionProfile.copyFrom(selectedProfile); + inspectionProfile.setName(newName); + inspectionProfile.initInspectionTools(project); + inspectionProfile.setProjectLevel(isProjectLevel); + + InspectionProfileModifiableModel modifiableModel = new InspectionProfileModifiableModel(inspectionProfile); + modifiableModel.setModified(true); + return modifiableModel; + } + + private void addProfile(InspectionProfileModifiableModel profile) { + final InspectionProfileModifiableModel selected = getSelectedScheme(); + getModel().addProfile(profile); + getModel().updatePanel(this); + selectScheme(selected); + } +} diff --git a/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/header/InspectionToolsConfigurable.java b/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/header/InspectionToolsConfigurable.java index b17af0755073..364cda9bedef 100644 --- a/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/header/InspectionToolsConfigurable.java +++ b/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/header/InspectionToolsConfigurable.java @@ -24,14 +24,9 @@ import com.intellij.codeInspection.ex.InspectionToolRegistrar; import com.intellij.codeInspection.ex.InspectionToolWrapper; import com.intellij.lang.annotation.HighlightSeverity; import com.intellij.openapi.application.ApplicationManager; -import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.editor.colors.CodeInsightColors; import com.intellij.openapi.editor.colors.TextAttributesKey; import com.intellij.openapi.editor.markup.TextAttributes; -import com.intellij.openapi.fileChooser.FileChooser; -import com.intellij.openapi.fileChooser.FileChooserDescriptor; -import com.intellij.openapi.fileChooser.FileChooserDescriptorFactory; -import com.intellij.openapi.fileTypes.StdFileTypes; import com.intellij.openapi.options.BaseConfigurable; import com.intellij.openapi.options.Configurable; import com.intellij.openapi.options.SearchableConfigurable; @@ -39,126 +34,44 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.Messages; import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.Disposer; -import com.intellij.openapi.util.InvalidDataException; -import com.intellij.openapi.util.JDOMUtil; -import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.util.text.StringUtil; -import com.intellij.openapi.vfs.VirtualFile; import com.intellij.profile.codeInspection.BaseInspectionProfileManager; import com.intellij.profile.codeInspection.InspectionProfileManager; import com.intellij.profile.codeInspection.ProjectInspectionProfileManager; import com.intellij.profile.codeInspection.ui.ErrorsConfigurable; import com.intellij.profile.codeInspection.ui.SingleInspectionProfilePanel; -import com.intellij.ui.IdeBorderFactory; import com.intellij.util.Alarm; -import com.intellij.util.SmartList; +import com.intellij.util.ArrayUtil; import com.intellij.util.ui.JBInsets; -import com.intellij.util.ui.JBUI; -import com.intellij.util.ui.UIUtil; import org.jdom.Element; -import org.jdom.JDOMException; import org.jetbrains.annotations.NotNull; import javax.swing.*; import java.awt.*; -import java.io.File; -import java.io.IOException; -import java.util.*; -import java.util.List; -import java.util.regex.Matcher; -import java.util.regex.Pattern; -import java.util.stream.Collectors; - -import static com.intellij.openapi.util.io.FileUtil.sanitizeFileName; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Set; public abstract class InspectionToolsConfigurable extends BaseConfigurable implements ErrorsConfigurable, SearchableConfigurable, Configurable.NoScroll { public static final String ID = "Errors"; public static final String DISPLAY_NAME = "Inspections"; - private static final String HEADER_TITLE = "Profile:"; - - private static final Logger LOG = Logger.getInstance(InspectionToolsConfigurable.class); - private static final Pattern COPIED_PROFILE_SUFFIX_PATTERN = Pattern.compile("(.*\\s*copy)\\s*(\\d*)"); protected final BaseInspectionProfileManager myApplicationProfileManager; protected final ProjectInspectionProfileManager myProjectProfileManager; - private final List myPanels = new ArrayList<>(); - private final List myDeletedProfiles = new SmartList<>(); - protected ProfilesChooser myProfiles; private JPanel myProfilePanelHolder; - private AuxiliaryRightPanel myAuxiliaryRightPanel; private Alarm mySelectionAlarm; + private InspectionProfileSchemesPanel myAbstractSchemesPanel; public InspectionToolsConfigurable(@NotNull ProjectInspectionProfileManager projectProfileManager) { myProjectProfileManager = projectProfileManager; myApplicationProfileManager = (BaseInspectionProfileManager)InspectionProfileManager.getInstance(); } - private static JComponent withBorderOnTop(final JComponent component) { - final JPanel panel = new JPanel(); - panel.add(component); - panel.setBorder(IdeBorderFactory.createEmptyBorder(UIUtil.isUnderDarcula() ? 10 : 13, 0, 0, 0)); - return panel; - } - private Project getProject() { return myProjectProfileManager.getProject(); } - @NotNull - private InspectionProfileImpl copyToNewProfile(@NotNull InspectionProfileImpl selectedProfile, - @NotNull Project project, - boolean modifyName, - boolean modifyLevel) { - LOG.assertTrue(modifyLevel || modifyName); - String profileDefaultName = selectedProfile.getName(); - - final boolean isProjectLevel = selectedProfile.isProjectLevel() ^ modifyLevel; - if (modifyName) { - final Matcher matcher = COPIED_PROFILE_SUFFIX_PATTERN.matcher(profileDefaultName); - int nextIdx; - if (matcher.matches()) { - profileDefaultName = matcher.group(1); - nextIdx = matcher.group(2).isEmpty() ? 1 : Integer.valueOf(matcher.group(2)); - } - else { - profileDefaultName += " copy"; - nextIdx = 1; - } - if (hasName(profileDefaultName, isProjectLevel)) { - String currentProfileDefaultName; - do { - currentProfileDefaultName = profileDefaultName + " " + String.valueOf(nextIdx); - nextIdx++; - } - while (hasName(currentProfileDefaultName, isProjectLevel)); - profileDefaultName = currentProfileDefaultName; - } - } - - BaseInspectionProfileManager profileManager = isProjectLevel ? myProjectProfileManager : myApplicationProfileManager; - InspectionProfileImpl inspectionProfile = - new InspectionProfileImpl(profileDefaultName, InspectionToolRegistrar.getInstance(), profileManager); - - inspectionProfile.copyFrom(selectedProfile); - inspectionProfile.setName(profileDefaultName); - inspectionProfile.initInspectionTools(project); - inspectionProfile.setProjectLevel(isProjectLevel); - - InspectionProfileModifiableModel modifiableModel = new InspectionProfileModifiableModel(inspectionProfile); - modifiableModel.setModified(true); - addProfile(modifiableModel); - return modifiableModel; - } - - protected void addProfile(InspectionProfileModifiableModel model) { - final SingleInspectionProfilePanel panel = createPanel(model); - myPanels.add(panel); - myProfilePanelHolder.add(panel); - myProfiles.getProfilesComboBox().addProfile(model); - myProfiles.getProfilesComboBox().selectProfile(model); - } - protected boolean setActiveProfileAsDefaultOnApply() { return true; } @@ -194,9 +107,6 @@ public abstract class InspectionToolsConfigurable extends BaseConfigurable final JPanel wholePanel = new JPanel(); wholePanel.setLayout(new BorderLayout()); - final JPanel toolbar = new JPanel(); - toolbar.setBorder(BorderFactory.createEmptyBorder(0, 0, 7, 0)); - myProfilePanelHolder = new JPanel() { @Override public void doLayout() { @@ -227,208 +137,15 @@ public abstract class InspectionToolsConfigurable extends BaseConfigurable return super.getMinimumSize(); } }; - - wholePanel.add(toolbar, BorderLayout.PAGE_START); wholePanel.add(myProfilePanelHolder, BorderLayout.CENTER); - myAuxiliaryRightPanel = new AuxiliaryRightPanel(new AuxiliaryRightPanel.DescriptionSaveListener() { - @Override - public void saveDescription(@NotNull String description) { - InspectionProfileModifiableModel inspectionProfile = getSelectedObject(); - if (!Comparing.strEqual(description, inspectionProfile.getDescription())) { - inspectionProfile.setDescription(description); - inspectionProfile.setModified(true); - } - myAuxiliaryRightPanel.showDescription(description); - } - - @Override - public void cancel() { - myAuxiliaryRightPanel.showDescription(getSelectedObject().getDescription()); - } - }); - - myProfiles = new ProfilesChooser(myProjectProfileManager.getProject()) { - @Override - public void onProfileChosen(InspectionProfileImpl inspectionProfile) { - showProfile(inspectionProfile); - myAuxiliaryRightPanel.showDescription(inspectionProfile.getDescription()); - } - }; JPanel profilesHolder = new JPanel(); profilesHolder.setLayout(new CardLayout()); - - - JComponent manageButton = new ManageButton(new ManageButtonBuilder() { - @Override - public boolean isProjectLevel() { - SingleInspectionProfilePanel panel = getSelectedPanel(); - return panel != null && panel.getProfile().isProjectLevel(); - } - - @Override - public boolean canChangeProfileLevel() { - return !hasName(getSelectedPanel().getProfile().getName(), !isProjectLevel()); - } - - @Override - public void copyToAnotherLevel() { - final SingleInspectionProfilePanel selectedPanel = getSelectedPanel(); - LOG.assertTrue(selectedPanel != null, "No settings selectedPanel for: " + getSelectedObject()); - copyToNewProfile(getSelectedObject(), getProject(), false, true); - } - - @Override - public void copy() { - rename(copyToNewProfile(getSelectedObject(), getProject(), true, false)); - } - - @Override - public void rename() { - rename(getSelectedObject()); - } - - private void rename(@NotNull final InspectionProfileImpl inspectionProfile) { - final String initialName = getSelectedPanel().getProfile().getName(); - myProfiles.showEditCard(initialName, new SaveInputComponentValidator() { - @Override - public void doSave(@NotNull String text) { - if (!text.equals(initialName)) { - inspectionProfile.setName(text); - myProfiles.getProfilesComboBox().resort(); - } - myProfiles.showComboBoxCard(); - } - - @Override - public boolean checkValid(@NotNull String text) { - final boolean isValid = text.equals(initialName) || !hasName(text, inspectionProfile.isProjectLevel()); - if (isValid) { - myAuxiliaryRightPanel.showDescription(getSelectedObject().getDescription()); - } - else { - myAuxiliaryRightPanel.showError("Name is already in use. Please change name to unique."); - } - return isValid; - } - - @Override - public void cancel() { - myProfiles.showComboBoxCard(); - myAuxiliaryRightPanel.showDescription(getSelectedObject().getDescription()); - } - }); - } - - @Override - public boolean canDelete() { - return isDeleteEnabled(myProfiles.getProfilesComboBox().getSelectedProfile()); - } - - @Override - public void delete() { - InspectionProfileModifiableModel selectedProfile = myProfiles.getProfilesComboBox().getSelectedProfile(); - myProfiles.getProfilesComboBox().removeProfile(selectedProfile); - myPanels.remove(getProfilePanel(selectedProfile)); - myDeletedProfiles.add(selectedProfile); - myProfiles.getProfilesComboBox().setSelectedIndex(0); - } - - @Override - public boolean canEditDescription() { - return true; - } - - @Override - public void editDescription() { - myAuxiliaryRightPanel.editDescription(getSelectedObject().getDescription()); - } - - @Override - public boolean hasDescription() { - return !StringUtil.isEmpty(getSelectedObject().getDescription()); - } - - @Override - public void export() { - FileChooserDescriptor descriptor = FileChooserDescriptorFactory.createSingleFolderDescriptor(); - descriptor.setDescription("Choose directory to store profile file"); - FileChooser.chooseFile(descriptor, getProject(), wholePanel, null, dir -> { - try { - SingleInspectionProfilePanel panel = getSelectedPanel(); - LOG.assertTrue(panel != null); - InspectionProfileImpl profile = getSelectedObject(); - LOG.assertTrue(true); - Element element = profile.writeScheme(false); - File file = new File(FileUtil.toSystemDependentName(dir.getPath()), sanitizeFileName(profile.getName()) + ".xml"); - if (file.isFile() && - Messages.showOkCancelDialog(wholePanel, "File \'" + file + "\' already exist. Do you want to overwrite it?", "Warning", - Messages.getQuestionIcon()) != Messages.OK) { - return; - } - - JDOMUtil.writeParent(element, file, "\n"); - } - catch (IOException e1) { - LOG.error(e1); - } - }); - } - - @Override - public void doImport() { - final FileChooserDescriptor descriptor = new FileChooserDescriptor(true, false, false, false, false, false) { - @Override - public boolean isFileSelectable(VirtualFile file) { - return file.getFileType().equals(StdFileTypes.XML); - } - }; - descriptor.setDescription("Choose profile file"); - FileChooser.chooseFile(descriptor, getProject(), wholePanel, null, file -> { - if (file != null) { - final InspectionProfileImpl profile; - try { - profile = importInspectionProfile(JDOMUtil.load(file.getInputStream()), myApplicationProfileManager, getProject()); - final SingleInspectionProfilePanel existed = getProfilePanel(profile); - if (existed != null) { - if (Messages.showOkCancelDialog(wholePanel, "Profile with name \'" + - profile.getName() + - "\' already exists. Do you want to overwrite it?", "Warning", - Messages.getInformationIcon()) != Messages.OK) { - return; - } - myProfiles.getProfilesComboBox().removeProfile(existed.getProfile()); - myPanels.remove(existed); - } - InspectionProfileModifiableModel model = new InspectionProfileModifiableModel(profile); - model.setModified(true); - addProfile(model); - selectProfile(model); - } - catch (JDOMException | InvalidDataException | IOException e) { - LOG.error(e); - } - } - }); - } - }).build(); - - - toolbar.setLayout(new GridBagLayout()); - final JLabel headerTitleLabel = new JLabel(HEADER_TITLE); - headerTitleLabel.setBorder(IdeBorderFactory.createEmptyBorder(10, 0, 0, 0)); - toolbar.add(headerTitleLabel, new GridBagConstraints(0, 0, 1, 1, 0, 0, GridBagConstraints.CENTER, GridBagConstraints.NONE, - JBUI.emptyInsets(), 0, 0)); - - toolbar.add(myProfiles, new GridBagConstraints(1, 0, 1, 1, 0, 1.0, GridBagConstraints.CENTER, GridBagConstraints.VERTICAL, - JBUI.insetsLeft(6), 0, 0)); - - toolbar.add(withBorderOnTop(manageButton), new GridBagConstraints(2, 0, 1, 1, 0, 0, GridBagConstraints.CENTER, GridBagConstraints.VERTICAL, - JBUI.insetsLeft(10), 0, 0)); - - toolbar.add(myAuxiliaryRightPanel, new GridBagConstraints(3, 0, 1, 1, 1.0, 1.0, GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, - JBUI.insetsLeft(15), 0, 0)); - + myAbstractSchemesPanel = new InspectionProfileSchemesPanel(getProject(), + myApplicationProfileManager, + myProjectProfileManager, + this); + wholePanel.add(myAbstractSchemesPanel, BorderLayout.NORTH); return wholePanel; } @@ -497,26 +214,17 @@ public abstract class InspectionToolsConfigurable extends BaseConfigurable if (!Comparing.equal(selectedProfile, currentProfile)) { return true; } - for (SingleInspectionProfilePanel panel : myPanels) { + final InspectionProfileSchemesModel model = myAbstractSchemesPanel.getModel(); + for (SingleInspectionProfilePanel panel : model.getProfilePanels()) { if (panel.isModified()) return true; } - return getProfiles().size() != myPanels.size() || !myDeletedProfiles.isEmpty(); + return model.hasDeletedProfiles() || + InspectionProfileSchemesModel.getSortedProfiles(myApplicationProfileManager, myProjectProfileManager).size() != model.getSize(); } @Override public void apply() { - for (InspectionProfileModifiableModel profile : myDeletedProfiles) { - profile.getProfileManager().deleteProfile(profile.getSource()); - } - myDeletedProfiles.clear(); - - SingleInspectionProfilePanel selectedPanel = getSelectedPanel(); - for (SingleInspectionProfilePanel panel : myPanels) { - panel.apply(); - if (setActiveProfileAsDefaultOnApply() && panel == selectedPanel) { - applyRootProfile(panel.getProfile().getName(), panel.getProfile().isProjectLevel()); - } - } + myAbstractSchemesPanel.apply(); } protected abstract void applyRootProfile(@NotNull String name, boolean isProjectLevel); @@ -531,22 +239,12 @@ public abstract class InspectionToolsConfigurable extends BaseConfigurable } private void doReset() { - myDeletedProfiles.clear(); disposeUIResources(); - final Collection profiles = getProfiles(); - final List modifiableProfiles = new ArrayList<>(profiles.size()); - for (InspectionProfileImpl profile : profiles) { - InspectionProfileModifiableModel inspectionProfile = new InspectionProfileModifiableModel(profile); - modifiableProfiles.add(inspectionProfile); - final SingleInspectionProfilePanel panel = createPanel(inspectionProfile); - myPanels.add(panel); - myProfilePanelHolder.add(panel); - } - myProfiles.getProfilesComboBox().reset(modifiableProfiles); - myAuxiliaryRightPanel.showDescription(getSelectedObject().getDescription()); - final InspectionProfileImpl inspectionProfile = getCurrentProfile(); - myProfiles.getProfilesComboBox().selectProfile(inspectionProfile); - showProfile(inspectionProfile); + myAbstractSchemesPanel.reset(); + final InspectionProfileModifiableModel currentModifiableModel = myAbstractSchemesPanel.getModel().getModifiableModelFor(getCurrentProfile()); + myAbstractSchemesPanel.selectScheme(currentModifiableModel); + showProfile(currentModifiableModel); + final SingleInspectionProfilePanel panel = getSelectedPanel(); if (panel != null) { panel.setVisible(true);//make sure that UI was initialized @@ -556,7 +254,7 @@ public abstract class InspectionToolsConfigurable extends BaseConfigurable } } - private SingleInspectionProfilePanel createPanel(InspectionProfileModifiableModel profile) { + public SingleInspectionProfilePanel createPanel(InspectionProfileModifiableModel profile) { return new SingleInspectionProfilePanel(myProjectProfileManager, profile) { @Override protected boolean accept(InspectionToolWrapper entry) { @@ -565,90 +263,39 @@ public abstract class InspectionToolsConfigurable extends BaseConfigurable }; } - private boolean isDeleteEnabled(@NotNull InspectionProfileImpl inspectionProfile) { - boolean projectProfileFound = false; - boolean ideProfileFound = false; - - for (InspectionProfileImpl profile : myProfiles.getProfilesComboBox().getProfiles()) { - if (inspectionProfile == profile) continue; - final boolean isProjectProfile = profile.getProfileManager() == myProjectProfileManager; - projectProfileFound |= isProjectProfile; - ideProfileFound |= !isProjectProfile; - - if (ideProfileFound && projectProfileFound) break; - } - - return inspectionProfile.getProfileManager() == myProjectProfileManager ? projectProfileFound : ideProfileFound; - } - - protected Collection getProfiles() { - final Collection result = new ArrayList<>(); - result.addAll(new TreeSet<>(myApplicationProfileManager.getProfiles())); - result.addAll(myProjectProfileManager.getProfiles()); - return result; - } - @Override public void disposeUIResources() { - for (SingleInspectionProfilePanel panel : myPanels) { - panel.disposeUI(); - } - myPanels.clear(); if (mySelectionAlarm != null) { Disposer.dispose(mySelectionAlarm); mySelectionAlarm = null; } + myProfilePanelHolder.removeAll(); + myAbstractSchemesPanel.getModel().disposeUI(); } @Override public void selectProfile(InspectionProfileImpl profile) { - myProfiles.getProfilesComboBox().selectProfile(profile); - } - - private SingleInspectionProfilePanel getProfilePanel(InspectionProfileImpl profile) { - for (SingleInspectionProfilePanel panel : myPanels) { - if (panel.getProfile().equals(profile)) { - return panel; - } - } - return null; + final InspectionProfileModifiableModel modifiableModel = myAbstractSchemesPanel.getModel().getModifiableModelFor(profile); + showProfile(modifiableModel); } @Override public void selectInspectionTool(String selectedToolShortName) { - final InspectionProfileImpl inspectionProfile = getSelectedObject(); - final SingleInspectionProfilePanel panel = getProfilePanel(inspectionProfile); - LOG.assertTrue(panel != null, "No settings panel for: " + inspectionProfile + "; " + configuredProfiles()); + final InspectionProfileModifiableModel inspectionProfile = getSelectedObject(); + final SingleInspectionProfilePanel panel = myAbstractSchemesPanel.getModel().getProfilePanel(inspectionProfile); panel.selectInspectionTool(selectedToolShortName); } @Override public void selectInspectionGroup(String[] groupPath) { - getProfilePanel(getSelectedObject()).selectInspectionGroup(groupPath); + myAbstractSchemesPanel.getModel().getProfilePanel(getSelectedObject()).selectInspectionGroup(groupPath); } - protected SingleInspectionProfilePanel getSelectedPanel() { - final InspectionProfileImpl inspectionProfile = getSelectedObject(); - return getProfilePanel(inspectionProfile); - } - - private String configuredProfiles() { - return "configured profiles: " + StringUtil.join(myPanels.stream().map(p -> p.getProfile().getName()).collect(Collectors.toList()), ", "); - } - - private boolean hasName(@NotNull final String name, boolean shared) { - for (SingleInspectionProfilePanel p : myPanels) { - if (name.equals(p.getProfile().getName()) && shared == p.getProfile().isProjectLevel()) { - return true; - } - } - return false; - } @NotNull @Override public InspectionProfileModifiableModel getSelectedObject() { - return myProfiles.getProfilesComboBox().getSelectedProfile(); + return myAbstractSchemesPanel.getSelectedScheme(); } @Override @@ -657,8 +304,20 @@ public abstract class InspectionToolsConfigurable extends BaseConfigurable return panel == null ? null : panel.getPreferredFocusedComponent(); } - private void showProfile(InspectionProfileImpl profile) { - final SingleInspectionProfilePanel panel = getProfilePanel(profile); + void removeProfilePanel(SingleInspectionProfilePanel profilePanel) { + myProfilePanelHolder.remove(profilePanel); + } + + private SingleInspectionProfilePanel getSelectedPanel() { + final InspectionProfileModifiableModel inspectionProfile = getSelectedObject(); + return myAbstractSchemesPanel.getModel().getProfilePanel(inspectionProfile); + } + + private void showProfile(InspectionProfileModifiableModel profile) { + final SingleInspectionProfilePanel panel = myAbstractSchemesPanel.getModel().getProfilePanel(profile); + if (!ArrayUtil.contains(panel, myAbstractSchemesPanel.getModel().getProfilePanels())) { + myProfilePanelHolder.add(panel); + } for (Component component : myProfilePanelHolder.getComponents()) { component.setVisible(component == panel); } diff --git a/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/header/ManageButton.java b/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/header/ManageButton.java deleted file mode 100644 index 1cde43d3ee31..000000000000 --- a/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/header/ManageButton.java +++ /dev/null @@ -1,158 +0,0 @@ -/* - * Copyright 2000-2015 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.profile.codeInspection.ui.header; - -import com.intellij.openapi.actionSystem.AnAction; -import com.intellij.openapi.actionSystem.AnActionEvent; -import com.intellij.openapi.actionSystem.DefaultActionGroup; -import com.intellij.openapi.actionSystem.ex.ComboBoxAction; -import com.intellij.openapi.project.DumbAware; -import org.jetbrains.annotations.NotNull; - -import javax.swing.*; - -/** - * @author Dmitry Batkovich - */ -public class ManageButton extends ComboBoxAction implements DumbAware { - - private final ManageButtonBuilder myBuilder; - - public ManageButton(final ManageButtonBuilder builder) { - myBuilder = builder; - getTemplatePresentation().setText("Manage"); - setSmallVariant(false); - } - - public JComponent build() { - return createCustomComponent(getTemplatePresentation()); - } - - @NotNull - @Override - protected DefaultActionGroup createPopupActionGroup(JComponent button) { - DefaultActionGroup group = new DefaultActionGroup(); - - group.add(new ShareWithTeamCheckBoxAction()); - group.addSeparator(); - - group.add(new CopyAction()); - group.add(new RenameAction()); - group.add(new DeleteAction()); - group.add(new EditDescriptionAction(myBuilder.hasDescription())); - group.add(new ExportAction()); - group.addSeparator(); - - group.add(new ImportAction()); - - return group; - } - - @Override - protected boolean shouldShowDisabledActions() { - return true; - } - - private class ShareWithTeamCheckBoxAction extends AnAction implements DumbAware { - @Override - public void update(AnActionEvent e) { - final boolean isProjectLevel = myBuilder.isProjectLevel(); - e.getPresentation().setText(isProjectLevel ? "Copy as Global" : "Copy to Project"); - e.getPresentation().setEnabled(myBuilder.canChangeProfileLevel()); - } - - @Override - public void actionPerformed(AnActionEvent e) { - myBuilder.copyToAnotherLevel(); - } - } - - private class CopyAction extends AnAction implements DumbAware { - public CopyAction() { - super("Copy"); - } - - @Override - public void actionPerformed(AnActionEvent e) { - myBuilder.copy(); - } - } - - private class RenameAction extends AnAction implements DumbAware { - public RenameAction() { - super("Rename"); - } - - @Override - public void actionPerformed(AnActionEvent e) { - myBuilder.rename(); - } - } - - private class DeleteAction extends AnAction implements DumbAware { - public DeleteAction() { - super("Delete"); - } - - @Override - public void actionPerformed(AnActionEvent e) { - myBuilder.delete(); - } - - @Override - public void update(AnActionEvent e) { - e.getPresentation().setEnabledAndVisible(myBuilder.canDelete()); - } - } - - private class EditDescriptionAction extends AnAction implements DumbAware { - public EditDescriptionAction(boolean hasDescription) { - super(hasDescription ? "Edit description" : "Add description"); - } - - @Override - public void actionPerformed(AnActionEvent e) { - myBuilder.editDescription(); - } - - @Override - public void update(@NotNull AnActionEvent e) { - e.getPresentation().setEnabledAndVisible(myBuilder.canEditDescription()); - } - } - - private class ExportAction extends AnAction implements DumbAware { - public ExportAction() { - super("Export..."); - } - - @Override - public void actionPerformed(AnActionEvent e) { - myBuilder.export(); - } - } - - private class ImportAction extends AnAction implements DumbAware { - public ImportAction() { - super("Import..."); - } - - @Override - public void actionPerformed(AnActionEvent e) { - myBuilder.doImport(); - } - } -} diff --git a/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/header/ManageButtonBuilder.java b/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/header/ManageButtonBuilder.java deleted file mode 100644 index eb330800f06d..000000000000 --- a/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/header/ManageButtonBuilder.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright 2000-2015 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.profile.codeInspection.ui.header; - -/** - * @author Dmitry Batkovich - */ -public interface ManageButtonBuilder { - boolean isProjectLevel(); - - boolean canChangeProfileLevel(); - - void copyToAnotherLevel(); - - void copy(); - - void rename(); - - boolean canDelete(); - - void delete(); - - boolean canEditDescription(); - - void editDescription(); - - boolean hasDescription(); - - void export(); - - void doImport(); -} diff --git a/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/header/ProfilesChooser.java b/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/header/ProfilesChooser.java deleted file mode 100644 index 4a279d600077..000000000000 --- a/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/header/ProfilesChooser.java +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright 2000-2016 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.profile.codeInspection.ui.header; - -import com.intellij.codeInspection.ex.InspectionProfileImpl; -import com.intellij.codeInspection.ex.InspectionProfileModifiableModel; -import com.intellij.openapi.application.ApplicationManager; -import com.intellij.openapi.project.Project; -import com.intellij.openapi.wm.IdeFocusManager; -import com.intellij.ui.IdeBorderFactory; -import com.intellij.util.ui.JBUI; - -import javax.swing.*; -import java.awt.*; - -/** - * @author Dmitry Batkovich - */ -public abstract class ProfilesChooser extends JPanel { - private static final String COMBO_CARD = "combo.card"; - private static final String EDIT_CARD = "edit.card"; - - private final ProfilesComboBox myProfilesComboBox; - private final CardLayout myCardLayout; - private final ValidatedTextField mySubmitNameComponent; - private final SaveInputComponentValidator.Wrapper mySaveListener; - private final JPanel myComboBoxPanel; - private final Project myProject; - - public ProfilesChooser(Project project) { - myProject = project; - myComboBoxPanel = new JPanel(); - - myCardLayout = new CardLayout(); - myComboBoxPanel.setLayout(myCardLayout); - setBorder(IdeBorderFactory.createEmptyBorder(JBUI.insets(4, 0, 6, 0))); - myProfilesComboBox = new ProfilesComboBox() { - @Override - protected void onProfileChosen(InspectionProfileImpl inspectionProfile) { - ProfilesChooser.this.onProfileChosen(inspectionProfile); - } - }; - myComboBoxPanel.add(myProfilesComboBox, COMBO_CARD); - - mySaveListener = new SaveInputComponentValidator.Wrapper(); - mySubmitNameComponent = new ValidatedTextField(mySaveListener); - myComboBoxPanel.add(mySubmitNameComponent, EDIT_CARD); - - //noinspection GtkPreferredJComboBoxRenderer - setLayout(new BorderLayout()); - add(mySubmitNameComponent.getHintLabel(), BorderLayout.NORTH); - add(myComboBoxPanel, BorderLayout.CENTER); - - showComboBoxCard(); - } - - ProfilesComboBox getProfilesComboBox() { - return myProfilesComboBox; - } - - protected abstract void onProfileChosen(InspectionProfileImpl profile); - - void showEditCard(final String initialValue, final SaveInputComponentValidator inputValidator) { - mySaveListener.setDelegate(inputValidator); - mySubmitNameComponent.setText(initialValue); - myCardLayout.show(myComboBoxPanel, EDIT_CARD); - ApplicationManager.getApplication().invokeLater(() -> IdeFocusManager.getInstance(myProject).requestFocus(mySubmitNameComponent, true)); - } - - void showComboBoxCard() { - myCardLayout.show(myComboBoxPanel, COMBO_CARD); - } -} diff --git a/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/header/ProfilesComboBox.java b/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/header/ProfilesComboBox.java deleted file mode 100644 index 950b26251264..000000000000 --- a/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/header/ProfilesComboBox.java +++ /dev/null @@ -1,167 +0,0 @@ -/* - * Copyright 2000-2016 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.profile.codeInspection.ui.header; - -import com.intellij.codeInspection.ex.InspectionProfileImpl; -import com.intellij.icons.AllIcons; -import com.intellij.openapi.ui.ComboBox; -import com.intellij.ui.IdeBorderFactory; -import com.intellij.ui.ListCellRendererWrapper; -import com.intellij.ui.SortedComboBoxModel; -import com.intellij.ui.TitledSeparator; -import com.intellij.util.ui.UIUtil; -import org.jetbrains.annotations.NotNull; - -import javax.swing.*; -import java.awt.*; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.util.Collection; -import java.util.Comparator; -import java.util.List; - -/** - * @author Dmitry Batkovich - */ -public abstract class ProfilesComboBox extends ComboBox { - private static final String PROJECT_LEVEL_SEPARATOR_TEXT = "Project Level"; - private static final String GLOBAL_LEVEL_SEPARATOR_TEXT = "Global Level"; - - private SortedComboBoxModel myComboModel; - private T myFirstGlobalProfile; - - public ProfilesComboBox() { - myComboModel = new SortedComboBoxModel<>(Comparator.comparing(T::isProjectLevel) - .reversed() - .thenComparing(InspectionProfileImpl::getDisplayName)); - setModel(myComboModel); - //noinspection GtkPreferredJComboBoxRenderer - setRenderer(new ListCellRenderer() { - ListCellRendererWrapper baseRenderer = new ListCellRendererWrapper() { - @Override - public void customize(final JList list, - final InspectionProfileImpl value, - final int index, - final boolean selected, - final boolean hasFocus) { - if (index == -1) { - setIcon(value.isProjectLevel() ? AllIcons.General.ProjectSettings : AllIcons.General.Settings); - } - setText(value.getDisplayName()); - } - }; - - @Override - public Component getListCellRendererComponent(JList list, - InspectionProfileImpl o, - int index, - boolean isSelected, - boolean cellHasFocus) { - TitledSeparator separator = null; - if (index != -1) { - if (!o.isProjectLevel()) { - if (o == myFirstGlobalProfile) { - separator = new TitledSeparator(GLOBAL_LEVEL_SEPARATOR_TEXT); - } - } - else { - if (o == myComboModel.get(0)) { - separator = new TitledSeparator(PROJECT_LEVEL_SEPARATOR_TEXT); - } - } - } - Component renderedComponent = baseRenderer.getListCellRendererComponent(list, o, index, isSelected, cellHasFocus); - if (separator == null) { - return renderedComponent; - } - UIUtil.applyStyle(UIUtil.ComponentStyle.MINI, separator.getLabel()); - separator.getLabel().setIcon( - separator.getText().equals(PROJECT_LEVEL_SEPARATOR_TEXT) ? AllIcons.General.ProjectSettings : AllIcons.General.Settings); - separator.setBackground(renderedComponent.getBackground()); - separator.setBorder(IdeBorderFactory.createEmptyBorder(2, 2, 0, 2)); - JPanel p = new JPanel(); - p.setLayout(new BorderLayout()); - p.add(separator, BorderLayout.NORTH); - p.add(renderedComponent, BorderLayout.CENTER); - p.setBackground(renderedComponent.getBackground()); - return p; - } - }); - addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - final InspectionProfileImpl profile = getSelectedProfile(); - if (profile != null) { - onProfileChosen(profile); - } - } - }); - } - - protected abstract void onProfileChosen(final InspectionProfileImpl inspectionProfile); - - public void selectProfile(InspectionProfileImpl inspectionProfile) { - setSelectedItem(inspectionProfile); - } - - public void reset(final Collection profiles) { - myComboModel.clear(); - for (T profile : profiles) { - myComboModel.add(profile); - } - findFirstGlobalProfile(); - setSelectedIndex(0); - resort(); - } - - void removeProfile(T profile) { - myComboModel.remove(profile); - if (!profile.isProjectLevel() && profile == myFirstGlobalProfile) { - findFirstGlobalProfile(); - } - } - - public void addProfile(T inspectionProfile) { - myComboModel.add(inspectionProfile); - if (!inspectionProfile.isProjectLevel()) { - findFirstGlobalProfile(); - } - } - - T getSelectedProfile() { - return myComboModel.getSelectedItem(); - } - - @NotNull - List getProfiles() { - return myComboModel.getItems(); - } - - private void findFirstGlobalProfile() { - myFirstGlobalProfile = null; - for (T profile : getProfiles()) { - if (!profile.isProjectLevel()) { - myFirstGlobalProfile = profile; - break; - } - } - } - - public void resort() { - myComboModel.setAll(myComboModel.getItems()); - findFirstGlobalProfile(); - } -} diff --git a/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/header/SaveInputComponentValidator.java b/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/header/SaveInputComponentValidator.java deleted file mode 100644 index 5d002b32cde7..000000000000 --- a/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/header/SaveInputComponentValidator.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright 2000-2014 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.profile.codeInspection.ui.header; - -import org.jetbrains.annotations.NotNull; - -/** -* @author Dmitry Batkovich -*/ -public interface SaveInputComponentValidator { - - void doSave(@NotNull String text); - - boolean checkValid(@NotNull String text); - - void cancel(); - - class Wrapper implements SaveInputComponentValidator { - private SaveInputComponentValidator myDelegate; - private boolean myActive; - - public void setDelegate(SaveInputComponentValidator delegate) { - myDelegate = delegate; - myActive = true; - } - - @Override - public void doSave(@NotNull String text) { - text = text.trim(); - if (myActive && myDelegate != null) { - myDelegate.doSave(text); - myActive = false; - } - } - - @Override - public boolean checkValid(@NotNull String text) { - return myActive && myDelegate != null && myDelegate.checkValid(text.trim()); - } - - @Override - public void cancel() { - if (myActive && myDelegate != null) { - myDelegate.cancel(); - } - } - } -} diff --git a/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/header/ValidatedTextField.java b/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/header/ValidatedTextField.java deleted file mode 100644 index 2925bd8681a7..000000000000 --- a/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/header/ValidatedTextField.java +++ /dev/null @@ -1,132 +0,0 @@ -/* - * Copyright 2000-2014 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.profile.codeInspection.ui.header; - -import com.intellij.ui.JBColor; -import com.intellij.ui.components.JBTextField; -import com.intellij.util.ui.UIUtil; - -import javax.swing.*; -import javax.swing.event.DocumentEvent; -import javax.swing.event.DocumentListener; -import java.awt.*; -import java.awt.event.*; - -/** - * @author Dmitry Batkovich - */ -public class ValidatedTextField extends JBTextField { - private static final String LABEL_CARD = "label"; - private static final String NO_LABEL_CARD = "no_label"; - - private final SaveInputComponentValidator myInputValidator; - private final JPanel myHintPanel; - - private boolean myIgnoreFocus; - - public ValidatedTextField(final SaveInputComponentValidator inputValidator) { - myInputValidator = inputValidator; - getDocument().addDocumentListener(new DocumentListener() { - @Override - public void insertUpdate(DocumentEvent e) { - changedUpdate(e); - } - - @Override - public void removeUpdate(DocumentEvent e) { - changedUpdate(e); - } - - @Override - public void changedUpdate(DocumentEvent e) { - final boolean isValid = myInputValidator.checkValid(getText()); - final Color color = isValid ? UIUtil.getTextAreaForeground() : JBColor.RED; - if (!color.equals(getForeground())) { - setForeground(color); - } - } - }); - - addFocusListener(new FocusAdapter() { - @Override - public void focusLost(FocusEvent e) { - if (!myIgnoreFocus) { - checkAndApply(); - } - } - }); - - addKeyListener(new KeyAdapter() { - @Override - public void keyPressed(KeyEvent e) { - if (e.getKeyCode() == KeyEvent.VK_ENTER || e.getKeyCode() == KeyEvent.VK_ESCAPE) { - e.consume(); - } - } - - @Override - public void keyReleased(KeyEvent e) { - if (e.getKeyCode() == KeyEvent.VK_ENTER) { - checkAndApply(); - e.consume(); - } else if (e.getKeyCode() == KeyEvent.VK_ESCAPE) { - myIgnoreFocus = true; - myInputValidator.cancel(); - e.consume(); - } - } - }); - - myHintPanel = new JPanel(); - final CardLayout cardLayout = new CardLayout(); - myHintPanel.setLayout(cardLayout); - - JLabel hintLabel = new JLabel("Save: Enter, Cancel: Esc"); - UIUtil.applyStyle(UIUtil.ComponentStyle.SMALL, hintLabel); - hintLabel.setForeground(UIUtil.getLabelDisabledForeground()); - myHintPanel.add(hintLabel, LABEL_CARD); - myHintPanel.add(new JPanel(), NO_LABEL_CARD); - - addComponentListener(new ComponentAdapter() { - @Override - public void componentShown(ComponentEvent e) { - cardLayout.show(myHintPanel, LABEL_CARD); - myIgnoreFocus = false; - } - - @Override - public void componentHidden(ComponentEvent e) { - cardLayout.show(myHintPanel, NO_LABEL_CARD); - } - }); - - cardLayout.show(myHintPanel, NO_LABEL_CARD); - } - - public JPanel getHintLabel() { - return myHintPanel; - } - - private void checkAndApply() { - String text = getText(); - if (text == null) { - text = ""; - } - if (myInputValidator.checkValid(text)) { - myInputValidator.doSave(text); - } - } -} diff --git a/platform/platform-resources/src/META-INF/LangExtensions.xml b/platform/platform-resources/src/META-INF/LangExtensions.xml index ae5f947e3540..7c8b684e385b 100644 --- a/platform/platform-resources/src/META-INF/LangExtensions.xml +++ b/platform/platform-resources/src/META-INF/LangExtensions.xml @@ -981,6 +981,15 @@ schemeClass="com.intellij.psi.codeStyle.CodeStyleScheme" implementationClass="com.intellij.psi.impl.source.codeStyle.CodeStyleSchemeXmlImporter"/> + + +