| /* |
| * Copyright 2000-2012 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. |
| */ |
| |
| /* |
| * Created by IntelliJ IDEA. |
| * User: Anna.Kozlova |
| * Date: 31-Jul-2006 |
| * Time: 17:44:39 |
| */ |
| package com.intellij.profile.codeInspection.ui; |
| |
| import com.intellij.codeHighlighting.HighlightDisplayLevel; |
| import com.intellij.codeInsight.daemon.impl.HighlightInfoType; |
| import com.intellij.codeInsight.daemon.impl.SeverityRegistrar; |
| import com.intellij.codeInspection.InspectionManager; |
| import com.intellij.codeInspection.InspectionProfileEntry; |
| import com.intellij.codeInspection.ModifiableModel; |
| import com.intellij.codeInspection.ex.*; |
| import com.intellij.icons.AllIcons; |
| import com.intellij.lang.annotation.HighlightSeverity; |
| import com.intellij.openapi.diagnostic.Logger; |
| import com.intellij.openapi.editor.colors.CodeInsightColors; |
| 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.ConfigurationException; |
| import com.intellij.openapi.options.SearchableConfigurable; |
| import com.intellij.openapi.project.Project; |
| import com.intellij.openapi.ui.Messages; |
| import com.intellij.openapi.util.*; |
| import com.intellij.openapi.util.io.FileUtil; |
| import com.intellij.openapi.util.text.StringUtil; |
| import com.intellij.openapi.vfs.VfsUtilCore; |
| import com.intellij.openapi.vfs.VirtualFile; |
| import com.intellij.profile.Profile; |
| import com.intellij.profile.ProfileManager; |
| import com.intellij.profile.codeInspection.InspectionProfileManager; |
| import com.intellij.profile.codeInspection.InspectionProjectProfileManager; |
| import com.intellij.ui.ListCellRendererWrapper; |
| import com.intellij.ui.components.JBScrollPane; |
| import com.intellij.util.Alarm; |
| import com.intellij.util.Consumer; |
| import com.intellij.util.SystemProperties; |
| import com.intellij.util.containers.HashMap; |
| import org.jdom.Document; |
| import org.jdom.Element; |
| import org.jdom.JDOMException; |
| import org.jetbrains.annotations.NotNull; |
| |
| import javax.swing.*; |
| import java.awt.*; |
| import java.awt.event.ActionEvent; |
| import java.awt.event.ActionListener; |
| import java.io.File; |
| import java.io.IOException; |
| import java.util.*; |
| import java.util.List; |
| |
| public abstract class InspectionToolsConfigurable extends BaseConfigurable implements ErrorsConfigurable, SearchableConfigurable, |
| Configurable.NoScroll { |
| private final CardLayout myLayout = new CardLayout(); |
| private JPanel myPanel; |
| |
| public static final String ID = "Errors"; |
| public static final String DISPLAY_NAME = "Inspections"; |
| |
| protected JComboBox myProfiles; |
| private final Map<String, SingleInspectionProfilePanel> myPanels = new HashMap<String, SingleInspectionProfilePanel>(); |
| |
| private JPanel myWholePanel; |
| private JButton myAddButton; |
| private JButton myDeleteButton; |
| private JButton myImportButton; |
| private JButton myExportButton; |
| private JCheckBox myShareProfileCheckBox; |
| private JButton myCopyButton; |
| private JBScrollPane myJBScrollPane; |
| |
| private final List<String> myDeletedProfiles = new ArrayList<String>(); |
| protected final InspectionProfileManager myProfileManager; |
| protected final InspectionProjectProfileManager myProjectProfileManager; |
| private static final Logger LOG = Logger.getInstance("#" + InspectionToolsConfigurable.class.getName()); |
| private Alarm mySelectionAlarm; |
| |
| |
| public InspectionToolsConfigurable(@NotNull final InspectionProjectProfileManager projectProfileManager, InspectionProfileManager profileManager) { |
| ((InspectionManagerEx)InspectionManager.getInstance(projectProfileManager.getProject())).buildInspectionSearchIndexIfNecessary(); |
| myAddButton.addActionListener(new ActionListener() { |
| @Override |
| public void actionPerformed(ActionEvent e) { |
| final Set<String> existingProfileNames = myPanels.keySet(); |
| final ModifiableModel model = SingleInspectionProfilePanel.createNewProfile(-1, getSelectedObject(), myWholePanel, "", existingProfileNames, |
| projectProfileManager.getProject()); |
| if (model != null) { |
| addProfile((InspectionProfileImpl)model); |
| myDeletedProfiles.remove(getProfilePrefix(model) + model.getName()); |
| myDeleteButton.setEnabled(true); |
| } |
| } |
| }); |
| |
| myDeleteButton.addActionListener(new ActionListener() { |
| @Override |
| public void actionPerformed(ActionEvent e) { |
| final InspectionProfileImpl selectedProfile = (InspectionProfileImpl)myProfiles.getSelectedItem(); |
| ((DefaultComboBoxModel)myProfiles.getModel()).removeElement(selectedProfile); |
| myDeletedProfiles.add(getProfilePrefix(selectedProfile) + selectedProfile.getName()); |
| myDeleteButton.setEnabled(isDeleteEnabled(selectedProfile)); |
| } |
| }); |
| |
| final Project project = projectProfileManager.getProject(); |
| myImportButton.addActionListener(new ActionListener() { |
| @Override |
| public void actionPerformed(ActionEvent e) { |
| 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, project, myWholePanel, null, new Consumer<VirtualFile>() { |
| @Override |
| public void consume(VirtualFile file) { |
| if (file == null) return; |
| InspectionProfileImpl profile = |
| new InspectionProfileImpl("TempProfile", InspectionToolRegistrar.getInstance(), myProfileManager); |
| try { |
| Element rootElement = JDOMUtil.loadDocument(VfsUtilCore.virtualToIoFile(file)).getRootElement(); |
| if (Comparing.strEqual(rootElement.getName(), "component")) {//import right from .idea/inspectProfiles/xxx.xml |
| rootElement = rootElement.getChildren().get(0); |
| } |
| final Set<String> levels = new HashSet<String>(); |
| for (Object o : rootElement.getChildren("inspection_tool")) { |
| final Element inspectElement = (Element)o; |
| levels.add(inspectElement.getAttributeValue("level")); |
| for (Object s : inspectElement.getChildren("scope")) { |
| levels.add(((Element)s).getAttributeValue("level")); |
| } |
| } |
| for (Iterator<String> iterator = levels.iterator(); iterator.hasNext(); ) { |
| String level = iterator.next(); |
| if (myProfileManager.getOwnSeverityRegistrar().getSeverity(level) != null) { |
| iterator.remove(); |
| } |
| } |
| if (!levels.isEmpty()) { |
| if (Messages.showYesNoDialog(myWholePanel, "Undefined severities detected: " + |
| StringUtil.join(levels, ", ") + |
| ". Do you want to create them?", "Warning", Messages.getWarningIcon()) == |
| Messages.YES) { |
| for (String level : levels) { |
| final TextAttributes textAttributes = CodeInsightColors.WARNINGS_ATTRIBUTES.getDefaultAttributes(); |
| HighlightInfoType.HighlightInfoTypeImpl info |
| = new HighlightInfoType.HighlightInfoTypeImpl(new HighlightSeverity(level, 50), com.intellij.openapi.editor.colors |
| .TextAttributesKey.createTextAttributesKey(level)); |
| myProfileManager.getOwnSeverityRegistrar() |
| .registerSeverity(new SeverityRegistrar.SeverityBasedTextAttributes(textAttributes.clone(), info), |
| textAttributes.getErrorStripeColor()); |
| } |
| } |
| } |
| profile.readExternal(rootElement); |
| profile.setLocal(true); |
| profile.initInspectionTools(project); |
| if (getProfilePanel(profile) != null) { |
| if (Messages.showOkCancelDialog(myWholePanel, "Profile with name \'" + |
| profile.getName() + |
| "\' already exists. Do you want to overwrite it?", "Warning", |
| Messages.getInformationIcon()) != Messages.OK) return; |
| } |
| final ModifiableModel model = profile.getModifiableModel(); |
| model.setModified(true); |
| addProfile((InspectionProfileImpl)model); |
| myDeletedProfiles.remove(getProfilePrefix(profile) + profile.getName()); |
| myDeleteButton.setEnabled(true); |
| } |
| catch (InvalidDataException e1) { |
| LOG.error(e1); |
| } |
| catch (JDOMException e1) { |
| LOG.error(e1); |
| } |
| catch (IOException e1) { |
| LOG.error(e1); |
| } |
| } |
| }); |
| } |
| }); |
| |
| myExportButton.addActionListener(new ActionListener() { |
| @Override |
| public void actionPerformed(ActionEvent e) { |
| final FileChooserDescriptor descriptor = FileChooserDescriptorFactory.createSingleFolderDescriptor(); |
| descriptor.setDescription("Choose directory to store profile file"); |
| FileChooser.chooseFile(descriptor, project, myWholePanel, null, new Consumer<VirtualFile>() { |
| @Override |
| public void consume(VirtualFile file) { |
| final Element element = new Element("inspections"); |
| try { |
| final SingleInspectionProfilePanel panel = getSelectedPanel(); |
| LOG.assertTrue(panel != null); |
| final InspectionProfileImpl profile = (InspectionProfileImpl)panel.getSelectedProfile(); |
| profile.writeExternal(element); |
| final String filePath = |
| FileUtil.toSystemDependentName(file.getPath()) + File.separator + FileUtil.sanitizeFileName(profile.getName()) + ".xml"; |
| if (new File(filePath).isFile()) { |
| if (Messages |
| .showOkCancelDialog(myWholePanel, "File \'" + filePath + "\' already exist. Do you want to overwrite it?", "Warning", |
| Messages.getQuestionIcon()) != Messages.OK) return; |
| } |
| JDOMUtil.writeDocument(new Document(element), filePath, SystemProperties.getLineSeparator()); |
| } |
| catch (WriteExternalException e1) { |
| LOG.error(e1); |
| } |
| catch (IOException e1) { |
| LOG.error(e1); |
| } |
| } |
| }); |
| |
| } |
| }); |
| |
| myCopyButton.addActionListener(new ActionListener() { |
| @Override |
| public void actionPerformed(ActionEvent e) { |
| final Set<String> existingProfileNames = myPanels.keySet(); |
| final InspectionProfileImpl model = (InspectionProfileImpl) |
| SingleInspectionProfilePanel.createNewProfile(0, getSelectedObject(), myWholePanel, "", existingProfileNames, project); |
| if (model != null) { |
| final InspectionProfileImpl modifiableModel = (InspectionProfileImpl)model.getModifiableModel(); |
| modifiableModel.setModified(true); |
| addProfile(modifiableModel); |
| myDeletedProfiles.remove(getProfilePrefix(model) + model.getName()); |
| myDeleteButton.setEnabled(true); |
| } |
| } |
| }); |
| |
| myProjectProfileManager = projectProfileManager; |
| myProfileManager = profileManager; |
| |
| myJBScrollPane.setBorder(null); |
| } |
| |
| private void addProfile(InspectionProfileImpl model) { |
| final String modelName = model.getName(); |
| final SingleInspectionProfilePanel panel = createPanel(model, modelName, true); |
| myPanel.add(modelName, panel); |
| if (!myPanels.containsKey(getProfilePrefix(model) + modelName)) { |
| //noinspection unchecked |
| ((DefaultComboBoxModel)myProfiles.getModel()).addElement(model); |
| } |
| putProfile(model, panel); |
| myProfiles.setSelectedItem(model); |
| } |
| |
| @Override |
| public String getDisplayName() { |
| return DISPLAY_NAME; |
| } |
| |
| @Override |
| public String getHelpTopic() { |
| return "preferences.inspections"; |
| } |
| |
| @Override |
| @NotNull |
| public String getId() { |
| return ID; |
| } |
| |
| @Override |
| public Runnable enableSearch(final String option) { |
| return new Runnable(){ |
| @Override |
| public void run() { |
| SingleInspectionProfilePanel panel = getSelectedPanel(); |
| if (panel != null) { |
| panel.setFilter(option); |
| } |
| } |
| }; |
| } |
| |
| @Override |
| public JComponent createComponent() { |
| myProfiles.setRenderer(new ListCellRendererWrapper<Profile>() { |
| @Override |
| public void customize(final JList list, final Profile value, final int index, final boolean selected, final boolean hasFocus) { |
| final String profileName = value.getName(); |
| setText(profileName); |
| final SingleInspectionProfilePanel panel = getProfilePanel(value); |
| setIcon(panel != null && panel.isProfileShared() ? AllIcons.General.ProjectSettings : AllIcons.General.Settings); |
| } |
| }); |
| myProfiles.addActionListener(new ActionListener() { |
| @Override |
| public void actionPerformed(ActionEvent e) { |
| final InspectionProfileImpl profile = (InspectionProfileImpl)myProfiles.getSelectedItem(); |
| if (profile != null) { |
| myDeleteButton.setEnabled(isDeleteEnabled(profile)); |
| myLayout.show(myPanel, profile.getName()); |
| SingleInspectionProfilePanel panel = getSelectedPanel(); |
| if (panel != null) { |
| myShareProfileCheckBox.setSelected(panel.isProfileShared()); |
| } |
| } |
| } |
| }); |
| myShareProfileCheckBox.addActionListener(new ActionListener() { |
| @Override |
| public void actionPerformed(ActionEvent e) { |
| final SingleInspectionProfilePanel panel = getSelectedPanel(); |
| LOG.assertTrue(panel != null, "No settings panel for: " + getSelectedObject()); |
| panel.setProfileShared(myShareProfileCheckBox.isSelected()); |
| myProfiles.repaint(); |
| } |
| }); |
| |
| myPanel.setLayout(myLayout); |
| return myWholePanel; |
| } |
| |
| protected abstract InspectionProfileImpl getCurrentProfile(); |
| |
| @Override |
| public boolean isModified() { |
| for (SingleInspectionProfilePanel panel : myPanels.values()) { |
| if (panel.isModified()) return true; |
| } |
| if (getProfiles().size() != myPanels.size()) return true; |
| return !myDeletedProfiles.isEmpty(); |
| } |
| |
| @Override |
| public void apply() throws ConfigurationException { |
| final Map<String, SingleInspectionProfilePanel> panels = new LinkedHashMap<String, SingleInspectionProfilePanel>(); |
| for (final String name : myPanels.keySet()) { |
| if (myDeletedProfiles.remove(name)) { |
| final String profileName = getProfilePanel(name).getSelectedProfile().getName(); |
| deleteProfile(profileName); |
| } |
| else { |
| final SingleInspectionProfilePanel panel = getProfilePanel(name); |
| panel.apply(); |
| final ModifiableModel profile = panel.getSelectedProfile(); |
| panels.put(getProfilePrefix(profile) + profile.getName(), panel); |
| } |
| } |
| myPanels.clear(); |
| myPanels.putAll(panels); |
| } |
| |
| private SingleInspectionProfilePanel getProfilePanel(String name) { |
| return myPanels.get(name); |
| } |
| |
| private SingleInspectionProfilePanel getProfilePanel(Profile inspectionProfile) { |
| return getProfilePanel(getProfilePrefix(inspectionProfile) + inspectionProfile.getName()); |
| } |
| |
| private void putProfile(Profile profile, SingleInspectionProfilePanel panel) { |
| myPanels.put(getProfilePrefix(profile) + profile.getName(), panel); |
| } |
| |
| private static String getProfilePrefix(Profile profile) { |
| return (profile.isLocal() ? "L" : "S"); |
| } |
| |
| protected void deleteProfile(String name) { |
| if (myProfileManager.getProfile(name, false) != null) { |
| myProfileManager.deleteProfile(name); |
| } |
| if (myProjectProfileManager.getProfile(name, false) != null) { |
| myProjectProfileManager.deleteProfile(name); |
| } |
| } |
| |
| protected boolean acceptTool(InspectionToolWrapper entry) { |
| return true; |
| } |
| |
| @Override |
| public void reset() { |
| myDeletedProfiles.clear(); |
| myPanels.clear(); |
| final DefaultComboBoxModel model = new DefaultComboBoxModel(); |
| myProfiles.setModel(model); |
| for (Profile profile : getProfiles()) { |
| model.addElement(profile); |
| final String profileName = profile.getName(); |
| final SingleInspectionProfilePanel panel = createPanel((InspectionProfileImpl)profile, profileName, false); |
| putProfile(profile, panel); |
| myPanel.add(profileName, panel); |
| } |
| final InspectionProfileImpl inspectionProfile = getCurrentProfile(); |
| myProfiles.setSelectedItem(inspectionProfile); |
| myLayout.show(myPanel, inspectionProfile.getName()); |
| myDeleteButton.setEnabled(isDeleteEnabled(inspectionProfile)); |
| final SingleInspectionProfilePanel panel = getSelectedPanel(); |
| if (panel != null) { |
| panel.setVisible(true);//make sure that UI was initialized |
| mySelectionAlarm = new Alarm(Alarm.ThreadToUse.SWING_THREAD); |
| SwingUtilities.invokeLater(new Runnable() { |
| @Override |
| public void run() { |
| if (mySelectionAlarm != null) { |
| mySelectionAlarm.addRequest(new Runnable() { |
| @Override |
| public void run() { |
| panel.updateSelection(); |
| } |
| }, 200); |
| } |
| } |
| }); |
| |
| myShareProfileCheckBox.setSelected(panel.isProfileShared()); |
| } |
| } |
| |
| private SingleInspectionProfilePanel createPanel(InspectionProfileImpl profile, String profileName, boolean model) { |
| return new SingleInspectionProfilePanel(myProjectProfileManager, profileName, model ? profile : profile.getModifiableModel()) { |
| @Override |
| protected boolean accept(InspectionToolWrapper entry) { |
| return super.accept(entry) && InspectionToolsConfigurable.this.acceptTool(entry); |
| } |
| }; |
| } |
| |
| private boolean isDeleteEnabled(@NotNull InspectionProfileImpl inspectionProfile) { |
| final ProfileManager profileManager = inspectionProfile.getProfileManager(); |
| |
| boolean projectProfileFound = false; |
| boolean ideProfileFound = false; |
| |
| final ComboBoxModel model = myProfiles.getModel(); |
| for (int i = 0; i < model.getSize(); i++) { |
| Profile profile = (Profile)model.getElementAt(i); |
| if (inspectionProfile == profile) continue; |
| final boolean isProjectProfile = profile.getProfileManager() == myProjectProfileManager; |
| projectProfileFound |= isProjectProfile; |
| ideProfileFound |= !isProjectProfile; |
| |
| if (ideProfileFound && projectProfileFound) break; |
| } |
| |
| return profileManager == myProjectProfileManager ? projectProfileFound : ideProfileFound; |
| } |
| |
| protected Collection<Profile> getProfiles() { |
| final Collection<Profile> result = new ArrayList<Profile>(); |
| result.addAll(new TreeSet<Profile>(myProfileManager.getProfiles())); |
| result.addAll(myProjectProfileManager.getProfiles()); |
| return result; |
| } |
| |
| @Override |
| public void disposeUIResources() { |
| for (SingleInspectionProfilePanel panel : myPanels.values()) { |
| panel.disposeUI(); |
| } |
| myPanels.clear(); |
| if (mySelectionAlarm != null) { |
| Disposer.dispose(mySelectionAlarm); |
| mySelectionAlarm = null; |
| } |
| } |
| |
| @Override |
| public void selectProfile(String name) { |
| for (int i = 0; i < myProfiles.getItemCount(); i++) { |
| if (Comparing.strEqual(((InspectionProfileImpl)myProfiles.getItemAt(i)).getName(), name)) { |
| myProfiles.setSelectedIndex(i); |
| break; |
| } |
| } |
| } |
| |
| @Override |
| public void selectInspectionTool(String selectedToolShortName) { |
| final InspectionProfileImpl inspectionProfile = getSelectedObject(); |
| assert inspectionProfile != null : configuredProfiles(); |
| final SingleInspectionProfilePanel panel = getProfilePanel(inspectionProfile); |
| LOG.assertTrue(panel != null, "No settings panel for: " + inspectionProfile + "; " + configuredProfiles()); |
| panel.selectInspectionTool(selectedToolShortName); |
| } |
| |
| protected SingleInspectionProfilePanel getSelectedPanel() { |
| final InspectionProfileImpl inspectionProfile = getSelectedObject(); |
| assert inspectionProfile != null : configuredProfiles(); |
| return getProfilePanel(inspectionProfile); |
| } |
| |
| private String configuredProfiles() { |
| return "configured profiles: " + StringUtil.join(myPanels.keySet(), ", "); |
| } |
| |
| protected Set<String> getKnownNames() { |
| return myPanels.keySet(); |
| } |
| |
| @Override |
| public InspectionProfileImpl getSelectedObject() { |
| return (InspectionProfileImpl)myProfiles.getSelectedItem(); |
| } |
| |
| @Override |
| public JComponent getPreferredFocusedComponent() { |
| final InspectionProfileImpl inspectionProfile = getSelectedObject(); |
| assert inspectionProfile != null : configuredProfiles(); |
| return getProfilePanel(inspectionProfile).getPreferredFocusedComponent(); |
| } |
| } |