new inspection tool configurable ui

This commit is contained in:
Dmitry Batkovich
2014-11-12 17:00:18 +03:00
parent 1722466b8b
commit 6dec68de9f
12 changed files with 1158 additions and 501 deletions
@@ -35,7 +35,7 @@ import com.intellij.openapi.wm.ToolWindow;
import com.intellij.openapi.wm.ToolWindowAnchor;
import com.intellij.openapi.wm.ToolWindowId;
import com.intellij.openapi.wm.ToolWindowManager;
import com.intellij.profile.codeInspection.ui.InspectionToolsConfigurable;
import com.intellij.profile.codeInspection.ui.header.InspectionToolsConfigurable;
import com.intellij.psi.PsiElement;
import com.intellij.ui.content.ContentFactory;
import com.intellij.ui.content.ContentManager;
@@ -52,9 +52,12 @@ import java.util.concurrent.atomic.AtomicBoolean;
import java.util.regex.Pattern;
public class InspectionManagerEx extends InspectionManagerBase {
private GlobalInspectionContextImpl myGlobalInspectionContext;
private static final Pattern HTML_PATTERN = Pattern.compile("<[^<>]*>");
private final NotNullLazyValue<ContentManager> myContentManager;
private final Set<GlobalInspectionContextImpl> myRunningContexts = new HashSet<GlobalInspectionContextImpl>();
private final AtomicBoolean myToolsAreInitialized = new AtomicBoolean(false);
private GlobalInspectionContextImpl myGlobalInspectionContext;
public InspectionManagerEx(final Project project) {
super(project);
@@ -111,6 +114,15 @@ public class InspectionManagerEx extends InspectionManagerBase {
});
}
private static void processText(@NotNull @NonNls String descriptionText,
@NotNull InspectionToolWrapper tool,
@NotNull SearchableOptionsRegistrar myOptionsRegistrar) {
if (ApplicationManager.getApplication().isDisposed()) return;
final Set<String> words = myOptionsRegistrar.getProcessedWordsWithoutStemming(descriptionText);
for (String word : words) {
myOptionsRegistrar.addOption(word, tool.getShortName(), tool.getDisplayName(), InspectionToolsConfigurable.ID, InspectionToolsConfigurable.DISPLAY_NAME);
}
}
@NotNull
public ProblemDescriptor createProblemDescriptor(@NotNull final PsiElement psiElement,
@@ -170,8 +182,6 @@ public class InspectionManagerEx extends InspectionManagerBase {
return myContentManager;
}
private final AtomicBoolean myToolsAreInitialized = new AtomicBoolean(false);
private static final Pattern HTML_PATTERN = Pattern.compile("<[^<>]*>");
public void buildInspectionSearchIndexIfNecessary() {
if (!myToolsAreInitialized.getAndSet(true)) {
final SearchableOptionsRegistrar myOptionsRegistrar = SearchableOptionsRegistrar.getInstance();
@@ -196,14 +206,4 @@ public class InspectionManagerEx extends InspectionManagerBase {
});
}
}
private static void processText(@NotNull @NonNls String descriptionText,
@NotNull InspectionToolWrapper tool,
@NotNull SearchableOptionsRegistrar myOptionsRegistrar) {
if (ApplicationManager.getApplication().isDisposed()) return;
final Set<String> words = myOptionsRegistrar.getProcessedWordsWithoutStemming(descriptionText);
for (String word : words) {
myOptionsRegistrar.addOption(word, tool.getShortName(), tool.getDisplayName(), InspectionToolsConfigurable.ID, InspectionToolsConfigurable.DISPLAY_NAME);
}
}
}
@@ -25,6 +25,7 @@ import com.intellij.openapi.options.ConfigurationException;
import com.intellij.openapi.util.Comparing;
import com.intellij.profile.codeInspection.InspectionProfileManager;
import com.intellij.profile.codeInspection.InspectionProjectProfileManager;
import com.intellij.profile.codeInspection.ui.header.InspectionToolsConfigurable;
public class IDEInspectionToolsConfigurable extends InspectionToolsConfigurable {
private String myCurrentSelection;
@@ -1,110 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="com.intellij.profile.codeInspection.ui.InspectionToolsConfigurable">
<grid id="27dc6" binding="myWholePanel" layout-manager="GridLayoutManager" row-count="2" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<xy x="20" y="20" width="1033" height="471"/>
</constraints>
<properties/>
<border type="none"/>
<children>
<grid id="d67c2" binding="myPanel" layout-manager="CardLayout" hgap="0" vgap="0">
<constraints>
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="7" hsize-policy="7" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
</constraints>
<properties/>
<border type="none"/>
<children/>
</grid>
<scrollpane id="64d7f" class="com.intellij.ui.components.JBScrollPane" binding="myJBScrollPane">
<constraints>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="1" fill="1" indent="0" use-parent-layout="false">
<minimum-size width="-1" height="45"/>
<preferred-size width="-1" height="45"/>
</grid>
</constraints>
<properties/>
<border type="none"/>
<children>
<grid id="6012b" layout-manager="GridLayoutManager" row-count="1" column-count="4" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints/>
<properties/>
<border type="none"/>
<children>
<component id="a4fd5" class="javax.swing.JComboBox" binding="myProfiles">
<constraints>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="2" anchor="8" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
<properties/>
</component>
<grid id="316ed" layout-manager="GridLayoutManager" row-count="1" column-count="5" same-size-horizontally="true" same-size-vertically="false" hgap="5" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<grid row="0" column="2" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
</constraints>
<properties/>
<border type="none"/>
<children>
<component id="9715e" class="javax.swing.JButton" binding="myAddButton" default-binding="true">
<constraints>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="A&amp;dd"/>
</properties>
</component>
<component id="95fc" class="javax.swing.JButton" binding="myDeleteButton" default-binding="true">
<constraints>
<grid row="0" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="De&amp;lete"/>
</properties>
</component>
<component id="4aa90" class="javax.swing.JButton" binding="myImportButton" default-binding="true">
<constraints>
<grid row="0" column="3" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="&amp;Import"/>
</properties>
</component>
<component id="f1082" class="javax.swing.JButton" binding="myExportButton" default-binding="true">
<constraints>
<grid row="0" column="4" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="&amp;Export"/>
</properties>
</component>
<component id="6a3c2" class="javax.swing.JButton" binding="myCopyButton" default-binding="true">
<constraints>
<grid row="0" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="&amp;Copy"/>
</properties>
</component>
</children>
</grid>
<component id="3617d" class="javax.swing.JCheckBox" binding="myShareProfileCheckBox">
<constraints>
<grid row="0" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="&amp;Share profile"/>
</properties>
</component>
<hspacer id="2ef95">
<constraints>
<grid row="0" column="3" row-span="1" col-span="1" vsize-policy="1" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
</hspacer>
</children>
</grid>
</children>
</scrollpane>
</children>
</grid>
</form>
@@ -27,6 +27,7 @@ import com.intellij.openapi.util.Comparing;
import com.intellij.profile.codeInspection.InspectionProfileManager;
import com.intellij.profile.codeInspection.InspectionProfileManagerImpl;
import com.intellij.profile.codeInspection.InspectionProjectProfileManager;
import com.intellij.profile.codeInspection.ui.header.InspectionToolsConfigurable;
import java.util.Arrays;
@@ -45,7 +46,6 @@ public class ProjectInspectionToolsConfigurable extends InspectionToolsConfigura
public void apply() throws ConfigurationException {
super.apply();
final InspectionProfileImpl selectedObject = getSelectedObject();
LOG.assertTrue(selectedObject != null);
final String profileName = selectedObject.getName();
final SingleInspectionProfilePanel selectedPanel = getSelectedPanel();
LOG.assertTrue(selectedPanel != null, "selected profile: " + profileName + " panels: " + Arrays.toString(getKnownNames().toArray()));
@@ -61,7 +61,7 @@ public class ProjectInspectionToolsConfigurable extends InspectionToolsConfigura
@Override
public boolean isModified() {
final InspectionProfileImpl selectedObject = getSelectedObject();
if (selectedObject != null && !Comparing.strEqual(getCurrentProfile().getName(), selectedObject.getName())) return true;
if (!Comparing.strEqual(getCurrentProfile().getName(), selectedObject.getName())) return true;
return super.isModified();
}
}
@@ -101,7 +101,15 @@ public class SingleInspectionProfilePanel extends JPanel {
private static final Logger LOG = Logger.getInstance("#com.intellij.codeInspection.ex.InspectionToolsPanel");
@NonNls private static final String INSPECTION_FILTER_HISTORY = "INSPECTION_FILTER_HISTORY";
private static final String UNDER_CONSTRUCTION = InspectionsBundle.message("inspection.tool.description.under.construction.text");
@NonNls private static final String EMPTY_HTML = "<html><body></body></html>";
@NonNls private static final String VERTICAL_DIVIDER_PROPORTION = "VERTICAL_DIVIDER_PROPORTION";
@NonNls private static final String HORIZONTAL_DIVIDER_PROPORTION = "HORIZONTAL_DIVIDER_PROPORTION";
private final List<ToolDescriptors> myInitialToolDescriptors = new ArrayList<ToolDescriptors>();
private final InspectionConfigTreeNode myRoot =
new InspectionConfigTreeNode(InspectionsBundle.message("inspection.root.node.title"));
private final Alarm myAlarm = new Alarm();
private final StorageAccessors myProperties = StorageAccessors.createGlobal("SingleInspectionProfilePanel");
private final InspectionProjectProfileManager myProjectProfileManager;
private InspectionProfileImpl mySelectedProfile;
private JEditorPane myBrowser;
private JPanel myOptionsPanel;
@@ -113,22 +121,13 @@ public class SingleInspectionProfilePanel extends JPanel {
filterTree(myProfileFilter.getFilter());
}
};
private final InspectionConfigTreeNode myRoot =
new InspectionConfigTreeNode(InspectionsBundle.message("inspection.root.node.title"));
private final Alarm myAlarm = new Alarm();
private boolean myModified = false;
private InspectionsConfigTreeTable myTreeTable;
private TreeExpander myTreeExpander;
@NotNull
private String myInitialProfile;
@NonNls private static final String EMPTY_HTML = "<html><body></body></html>";
private boolean myIsInRestore = false;
@NonNls private static final String VERTICAL_DIVIDER_PROPORTION = "VERTICAL_DIVIDER_PROPORTION";
@NonNls private static final String HORIZONTAL_DIVIDER_PROPORTION = "HORIZONTAL_DIVIDER_PROPORTION";
private final StorageAccessors myProperties = StorageAccessors.createGlobal("SingleInspectionProfilePanel");
private boolean myShareProfile;
private final InspectionProjectProfileManager myProjectProfileManager;
private Splitter myRightSplitter;
private Splitter myMainSplitter;
@@ -158,6 +157,181 @@ public class SingleInspectionProfilePanel extends JPanel {
}
}
@Nullable
public static ModifiableModel createNewProfile(final int initValue,
ModifiableModel selectedProfile,
JPanel parent,
String profileName,
Set<String> existingProfileNames,
@NotNull Project project) {
profileName = Messages.showInputDialog(parent, profileName, "Create New Inspection Profile", Messages.getQuestionIcon());
if (profileName == null) return null;
final ProfileManager profileManager = selectedProfile.getProfileManager();
if (existingProfileNames.contains(profileName)) {
Messages.showErrorDialog(InspectionsBundle.message("inspection.unable.to.create.profile.message", profileName),
InspectionsBundle.message("inspection.unable.to.create.profile.dialog.title"));
return null;
}
InspectionProfileImpl inspectionProfile =
new InspectionProfileImpl(profileName, InspectionToolRegistrar.getInstance(), profileManager);
if (initValue == -1) {
inspectionProfile.initInspectionTools(project);
ModifiableModel profileModifiableModel = inspectionProfile.getModifiableModel();
final InspectionToolWrapper[] profileEntries = profileModifiableModel.getInspectionTools(null);
for (InspectionToolWrapper toolWrapper : profileEntries) {
profileModifiableModel.disableTool(toolWrapper.getShortName(), null, project);
}
profileModifiableModel.setLocal(true);
profileModifiableModel.setModified(true);
return profileModifiableModel;
} else if (initValue == 0) {
inspectionProfile.copyFrom(selectedProfile);
inspectionProfile.setName(profileName);
inspectionProfile.initInspectionTools(project);
inspectionProfile.setModified(true);
return inspectionProfile;
}
return null;
}
@Nullable
private static InspectionConfigTreeNode findNodeByKey(String name, InspectionConfigTreeNode root) {
for (int i = 0; i < root.getChildCount(); i++) {
final InspectionConfigTreeNode child = (InspectionConfigTreeNode)root.getChildAt(i);
final Descriptor descriptor = child.getDefaultDescriptor();
if (descriptor != null) {
if (descriptor.getKey().toString().equals(name)) {
return child;
}
}
else {
final InspectionConfigTreeNode node = findNodeByKey(name, child);
if (node != null) return node;
}
}
return null;
}
public static String renderSeverity(HighlightSeverity severity) {
return StringUtil.capitalizeWords(severity.getName().toLowerCase(), true);
}
private static void updateUpHierarchy(final InspectionConfigTreeNode node, final InspectionConfigTreeNode parent) {
if (parent != null) {
parent.dropCache();
updateUpHierarchy(parent, (InspectionConfigTreeNode)parent.getParent());
}
}
private static boolean isDescriptorAccepted(Descriptor descriptor,
@NonNls String filter,
final boolean forceInclude,
final List<Set<String>> keySetList, final Set<String> quoted) {
filter = filter.toLowerCase();
if (StringUtil.containsIgnoreCase(descriptor.getText(), filter)) {
return true;
}
final String[] groupPath = descriptor.getGroup();
for (String group : groupPath) {
if (StringUtil.containsIgnoreCase(group, filter)) {
return true;
}
}
for (String stripped : quoted) {
if (StringUtil.containsIgnoreCase(descriptor.getText(),stripped)) {
return true;
}
for (String group : groupPath) {
if (StringUtil.containsIgnoreCase(group,stripped)) {
return true;
}
}
final String description = descriptor.getToolWrapper().loadDescription();
if (description != null && StringUtil.containsIgnoreCase(description.toLowerCase(), stripped)) {
if (!forceInclude) return true;
} else if (forceInclude) return false;
}
for (Set<String> keySet : keySetList) {
if (keySet.contains(descriptor.getKey().toString())) {
if (!forceInclude) {
return true;
}
}
else {
if (forceInclude) {
return false;
}
}
}
return forceInclude;
}
private static void setConfigPanel(final JPanel configPanelAnchor, final ScopeToolState state) {
configPanelAnchor.removeAll();
final JComponent additionalConfigPanel = state.getAdditionalConfigPanel();
if (additionalConfigPanel != null) {
final JScrollPane pane = ScrollPaneFactory.createScrollPane(additionalConfigPanel, SideBorder.NONE);
FocusManager.getCurrentManager().addPropertyChangeListener("focusOwner", new PropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent evt) {
if (!(evt.getNewValue() instanceof JComponent)) {
return;
}
final JComponent component = (JComponent)evt.getNewValue();
if (component.isAncestorOf(pane)) {
pane.scrollRectToVisible(component.getBounds());
}
}
});
configPanelAnchor.add(pane);
}
UIUtil.setEnabled(configPanelAnchor, state.isEnabled(), true);
}
private static InspectionConfigTreeNode getGroupNode(InspectionConfigTreeNode root, String[] groupPath) {
InspectionConfigTreeNode currentRoot = root;
for (final String group : groupPath) {
currentRoot = getGroupNode(currentRoot, group);
}
return currentRoot;
}
private static InspectionConfigTreeNode getGroupNode(InspectionConfigTreeNode root, String group) {
final int childCount = root.getChildCount();
for (int i = 0; i < childCount; i++) {
InspectionConfigTreeNode child = (InspectionConfigTreeNode)root.getChildAt(i);
if (group.equals(child.getUserObject())) {
return child;
}
}
InspectionConfigTreeNode child = new InspectionConfigTreeNode(group);
root.add(child);
return child;
}
private static void copyUsedSeveritiesIfUndefined(final ModifiableModel selectedProfile, final ProfileManager profileManager) {
final SeverityRegistrar registrar = ((SeverityProvider)profileManager).getSeverityRegistrar();
final Set<HighlightSeverity> severities = ((InspectionProfileImpl)selectedProfile).getUsedSeverities();
for (Iterator<HighlightSeverity> iterator = severities.iterator(); iterator.hasNext();) {
HighlightSeverity severity = iterator.next();
if (registrar.isSeverityValid(severity.getName())) {
iterator.remove();
}
}
if (!severities.isEmpty()) {
final SeverityRegistrar oppositeRegister = ((SeverityProvider)selectedProfile.getProfileManager()).getSeverityRegistrar();
for (HighlightSeverity severity : severities) {
final TextAttributesKey attributesKey = TextAttributesKey.find(severity.getName());
final TextAttributes textAttributes = oppositeRegister.getTextAttributesBySeverity(severity);
LOG.assertTrue(textAttributes != null, severity);
HighlightInfoType.HighlightInfoTypeImpl info = new HighlightInfoType.HighlightInfoTypeImpl(severity, attributesKey);
registrar.registerSeverity(new SeverityRegistrar.SeverityBasedTextAttributes(textAttributes.clone(), info),
textAttributes.getErrorStripeColor());
}
}
}
private void initUI() {
myInspectionProfilePanel = createInspectionProfileSettingsPanel();
add(myInspectionProfilePanel, BorderLayout.CENTER);
@@ -317,43 +491,6 @@ public class SingleInspectionProfilePanel extends JPanel {
updateOptionsAndDescriptionPanel(myTreeTable.getTree().getSelectionPaths());
}
@Nullable
public static ModifiableModel createNewProfile(final int initValue,
ModifiableModel selectedProfile,
JPanel parent,
String profileName,
Set<String> existingProfileNames,
@NotNull Project project) {
profileName = Messages.showInputDialog(parent, profileName, "Create New Inspection Profile", Messages.getQuestionIcon());
if (profileName == null) return null;
final ProfileManager profileManager = selectedProfile.getProfileManager();
if (existingProfileNames.contains(profileName)) {
Messages.showErrorDialog(InspectionsBundle.message("inspection.unable.to.create.profile.message", profileName),
InspectionsBundle.message("inspection.unable.to.create.profile.dialog.title"));
return null;
}
InspectionProfileImpl inspectionProfile =
new InspectionProfileImpl(profileName, InspectionToolRegistrar.getInstance(), profileManager);
if (initValue == -1) {
inspectionProfile.initInspectionTools(project);
ModifiableModel profileModifiableModel = inspectionProfile.getModifiableModel();
final InspectionToolWrapper[] profileEntries = profileModifiableModel.getInspectionTools(null);
for (InspectionToolWrapper toolWrapper : profileEntries) {
profileModifiableModel.disableTool(toolWrapper.getShortName(), null, project);
}
profileModifiableModel.setLocal(true);
profileModifiableModel.setModified(true);
return profileModifiableModel;
} else if (initValue == 0) {
inspectionProfile.copyFrom(selectedProfile);
inspectionProfile.setName(profileName);
inspectionProfile.initInspectionTools(project);
inspectionProfile.setModified(true);
return inspectionProfile;
}
return null;
}
public void setFilter(String filter) {
myProfileFilter.setFilter(filter);
}
@@ -469,24 +606,6 @@ public class SingleInspectionProfilePanel extends JPanel {
myTreeTable.scrollRectToVisible(new Rectangle(new Point(0, Math.max(0, selectPoint.y - allHeight / 2)), new Dimension(0, allHeight)));
}
@Nullable
private static InspectionConfigTreeNode findNodeByKey(String name, InspectionConfigTreeNode root) {
for (int i = 0; i < root.getChildCount(); i++) {
final InspectionConfigTreeNode child = (InspectionConfigTreeNode)root.getChildAt(i);
final Descriptor descriptor = child.getDefaultDescriptor();
if (descriptor != null) {
if (descriptor.getKey().toString().equals(name)) {
return child;
}
}
else {
final InspectionConfigTreeNode node = findNodeByKey(name, child);
if (node != null) return node;
}
}
return null;
}
private JScrollPane initTreeScrollPane() {
fillTreeData(null, true);
@@ -647,60 +766,6 @@ public class SingleInspectionProfilePanel extends JPanel {
return menu.getComponent();
}
public static String renderSeverity(HighlightSeverity severity) {
return StringUtil.capitalizeWords(severity.getName().toLowerCase(), true);
}
private static void updateUpHierarchy(final InspectionConfigTreeNode node, final InspectionConfigTreeNode parent) {
if (parent != null) {
parent.dropCache();
updateUpHierarchy(parent, (InspectionConfigTreeNode)parent.getParent());
}
}
private static boolean isDescriptorAccepted(Descriptor descriptor,
@NonNls String filter,
final boolean forceInclude,
final List<Set<String>> keySetList, final Set<String> quoted) {
filter = filter.toLowerCase();
if (StringUtil.containsIgnoreCase(descriptor.getText(), filter)) {
return true;
}
final String[] groupPath = descriptor.getGroup();
for (String group : groupPath) {
if (StringUtil.containsIgnoreCase(group, filter)) {
return true;
}
}
for (String stripped : quoted) {
if (StringUtil.containsIgnoreCase(descriptor.getText(),stripped)) {
return true;
}
for (String group : groupPath) {
if (StringUtil.containsIgnoreCase(group,stripped)) {
return true;
}
}
final String description = descriptor.getToolWrapper().loadDescription();
if (description != null && StringUtil.containsIgnoreCase(description.toLowerCase(), stripped)) {
if (!forceInclude) return true;
} else if (forceInclude) return false;
}
for (Set<String> keySet : keySetList) {
if (keySet.contains(descriptor.getKey().toString())) {
if (!forceInclude) {
return true;
}
}
else {
if (forceInclude) {
return false;
}
}
}
return forceInclude;
}
private void fillTreeData(@Nullable String filter, boolean forceInclude) {
if (mySelectedProfile == null) return;
myRoot.removeAllChildren();
@@ -965,55 +1030,12 @@ public class SingleInspectionProfilePanel extends JPanel {
myOptionsPanel.repaint();
}
private static void setConfigPanel(final JPanel configPanelAnchor, final ScopeToolState state) {
configPanelAnchor.removeAll();
final JComponent additionalConfigPanel = state.getAdditionalConfigPanel();
if (additionalConfigPanel != null) {
final JScrollPane pane = ScrollPaneFactory.createScrollPane(additionalConfigPanel, SideBorder.NONE);
FocusManager.getCurrentManager().addPropertyChangeListener("focusOwner", new PropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent evt) {
if (!(evt.getNewValue() instanceof JComponent)) {
return;
}
final JComponent component = (JComponent)evt.getNewValue();
if (component.isAncestorOf(pane)) {
pane.scrollRectToVisible(component.getBounds());
}
}
});
configPanelAnchor.add(pane);
}
UIUtil.setEnabled(configPanelAnchor, state.isEnabled(), true);
}
private static InspectionConfigTreeNode getGroupNode(InspectionConfigTreeNode root, String[] groupPath) {
InspectionConfigTreeNode currentRoot = root;
for (final String group : groupPath) {
currentRoot = getGroupNode(currentRoot, group);
}
return currentRoot;
}
private static InspectionConfigTreeNode getGroupNode(InspectionConfigTreeNode root, String group) {
final int childCount = root.getChildCount();
for (int i = 0; i < childCount; i++) {
InspectionConfigTreeNode child = (InspectionConfigTreeNode)root.getChildAt(i);
if (group.equals(child.getUserObject())) {
return child;
}
}
InspectionConfigTreeNode child = new InspectionConfigTreeNode(group);
root.add(child);
return child;
}
public boolean setSelectedProfileModified(boolean modified) {
mySelectedProfile.setModified(modified);
return modified;
}
ModifiableModel getSelectedProfile() {
public ModifiableModel getSelectedProfile() {
return mySelectedProfile;
}
@@ -1150,29 +1172,6 @@ public class SingleInspectionProfilePanel extends JPanel {
myModified = false;
}
private static void copyUsedSeveritiesIfUndefined(final ModifiableModel selectedProfile, final ProfileManager profileManager) {
final SeverityRegistrar registrar = ((SeverityProvider)profileManager).getSeverityRegistrar();
final Set<HighlightSeverity> severities = ((InspectionProfileImpl)selectedProfile).getUsedSeverities();
for (Iterator<HighlightSeverity> iterator = severities.iterator(); iterator.hasNext();) {
HighlightSeverity severity = iterator.next();
if (registrar.isSeverityValid(severity.getName())) {
iterator.remove();
}
}
if (!severities.isEmpty()) {
final SeverityRegistrar oppositeRegister = ((SeverityProvider)selectedProfile.getProfileManager()).getSeverityRegistrar();
for (HighlightSeverity severity : severities) {
final TextAttributesKey attributesKey = TextAttributesKey.find(severity.getName());
final TextAttributes textAttributes = oppositeRegister.getTextAttributesBySeverity(severity);
LOG.assertTrue(textAttributes != null, severity);
HighlightInfoType.HighlightInfoTypeImpl info = new HighlightInfoType.HighlightInfoTypeImpl(severity, attributesKey);
registrar.registerSeverity(new SeverityRegistrar.SeverityBasedTextAttributes(textAttributes.clone(), info),
textAttributes.getErrorStripeColor());
}
}
}
private boolean descriptorsAreChanged() {
for (ToolDescriptors toolDescriptors : myInitialToolDescriptors) {
Descriptor desc = toolDescriptors.getDefaultDescriptor();
@@ -0,0 +1,154 @@
/*
* 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.openapi.ui.ex.MultiLineLabel;
import com.intellij.ui.ClickListener;
import com.intellij.ui.JBColor;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseEvent;
/**
* @author Dmitry Batkovich
*/
public class AuxiliaryRightPanel extends JPanel {
private static final String SHOW_DESCRIPTION_CARD = "show.description.card";
private static final String EDIT_DESCRIPTION_CARD = "edit.description.card";
private static final String ERROR_CARD = "error.card";
private final DescriptionLabel myDescriptionLabel;
private final JLabel myErrorLabel;
private final SaveInputComponent mySaveInputComponent;
private final CardLayout myLayout;
public AuxiliaryRightPanel(final DescriptionSaveListener descriptionListener) {
myDescriptionLabel = new DescriptionLabel();
myErrorLabel = new JLabel();
myErrorLabel.setBackground(UIUtil.isUnderDarcula() ? JBColor.PINK.darker() :JBColor.PINK);
myErrorLabel.setForeground(JBColor.BLACK);
myErrorLabel.setOpaque(true);
myErrorLabel.setBorder(BorderFactory.createEmptyBorder(0, 2, 0, 0));
mySaveInputComponent = new SaveInputComponent(new SaveInputComponentValidator() {
@Override
public void doSave(@NotNull String text) {
descriptionListener.saveDescription(text.trim());
}
@Override
public boolean checkValid(@NotNull String text) {
return true;
}
});
myLayout = new CardLayout();
setLayout(myLayout);
new ClickListener() {
@Override
public boolean onClick(@NotNull MouseEvent event, int clickCount) {
if (clickCount != 2) {
return false;
}
editDescription(myDescriptionLabel.getText());
return true;
}
}.installOn(myDescriptionLabel);
add(myDescriptionLabel, SHOW_DESCRIPTION_CARD);
add(myErrorLabel, ERROR_CARD);
add(mySaveInputComponent, EDIT_DESCRIPTION_CARD);
showDescription(null);
}
public void showDescription(@Nullable String newDescription) {
if (newDescription == null) {
newDescription = "";
}
myDescriptionLabel.setAllText(newDescription);
myLayout.show(this, SHOW_DESCRIPTION_CARD);
}
public void editDescription(@Nullable String startValue) {
if (startValue == null) {
startValue = "";
}
mySaveInputComponent.setText(startValue);
myLayout.show(this, EDIT_DESCRIPTION_CARD);
mySaveInputComponent.requestFocusToTextField();
}
public void showError(final @NotNull String errorText) {
myErrorLabel.setText(errorText);
myLayout.show(this, ERROR_CARD);
}
public interface DescriptionSaveListener {
void saveDescription(@NotNull String description);
}
private static class DescriptionLabel extends MultiLineLabel {
private String myAllText;
public DescriptionLabel() {
UIUtil.applyStyle(UIUtil.ComponentStyle.SMALL, this);
setVerticalAlignment(CENTER);
setHorizontalAlignment(LEFT);
}
public void setAllText(String allText) {
myAllText = allText;
}
@Override
protected void paintComponent(Graphics g) {
int width = getSize().width;
FontMetrics fontMetrics = getFontMetrics(getFont());
int charWidth = fontMetrics.charWidth('a');
int firstLineSize = Math.max(0, width / charWidth);
if (myAllText.length() <= firstLineSize) {
setText(myAllText);
setToolTipText(null);
} else {
String firstLine = myAllText.substring(0, firstLineSize);
String remainPart = myAllText.substring(firstLineSize);
int lastWhitespace = firstLine.lastIndexOf(' ');
if (lastWhitespace > -1) {
remainPart = firstLine.substring(lastWhitespace) + remainPart;
firstLine = firstLine.substring(0, lastWhitespace);
}
String visibleText = firstLine + "\n";
int secondLineSize = Math.max(0, (width - 3 * fontMetrics.charWidth('.')) / charWidth);
if (remainPart.length() <= secondLineSize) {
setText(visibleText + remainPart.trim());
setToolTipText(null);
} else {
setText(visibleText + remainPart.trim().substring(0, secondLineSize) + "...");
setToolTipText("..." + remainPart.substring(secondLineSize));
}
}
super.paintComponent(g);
}
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2012 JetBrains s.r.o.
* 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.
@@ -20,13 +20,11 @@
* Date: 31-Jul-2006
* Time: 17:44:39
*/
package com.intellij.profile.codeInspection.ui;
package com.intellij.profile.codeInspection.ui.header;
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;
@@ -53,83 +51,205 @@ 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.profile.codeInspection.ui.ErrorsConfigurable;
import com.intellij.profile.codeInspection.ui.SingleInspectionProfilePanel;
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.*;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.HashMap;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
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 abstract class InspectionToolsConfigurable extends BaseConfigurable
implements ErrorsConfigurable, SearchableConfigurable, Configurable.NoScroll {
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>();
private static final Logger LOG = Logger.getInstance("#" + InspectionToolsConfigurable.class.getName());
protected final InspectionProfileManager myProfileManager;
protected final InspectionProjectProfileManager myProjectProfileManager;
private static final Logger LOG = Logger.getInstance("#" + InspectionToolsConfigurable.class.getName());
private final CardLayout myLayout = new CardLayout();
private final AuxiliaryRightPanel myAuxiliaryRightPanel;
private final JPanel myProfilesHolder;
private final Map<Profile, SingleInspectionProfilePanel> myPanels =
new HashMap<Profile, SingleInspectionProfilePanel>();
private final List<String> myDeletedProfiles = new ArrayList<String>();
private final String myHeaderTitle = "Profile:";
protected ProfilesConfigurableComboBox myProfiles;
private JPanel myPanel;
private JPanel myWholePanel;
private JComponent myManageButton;
private Alarm mySelectionAlarm;
public InspectionToolsConfigurable(@NotNull final InspectionProjectProfileManager projectProfileManager,
InspectionProfileManager profileManager) {
myWholePanel = new JPanel();
public InspectionToolsConfigurable(@NotNull final InspectionProjectProfileManager projectProfileManager, InspectionProfileManager profileManager) {
((InspectionManagerEx)InspectionManager.getInstance(projectProfileManager.getProject())).buildInspectionSearchIndexIfNecessary();
myAddButton.addActionListener(new ActionListener() {
myWholePanel.setLayout(new BorderLayout());
final JPanel toolbar = new JPanel();
toolbar.setBorder(BorderFactory.createEmptyBorder(0, 0, 7, 0));
myPanel = new JPanel();
myWholePanel.add(toolbar, BorderLayout.PAGE_START);
myWholePanel.add(myPanel, BorderLayout.CENTER);
myProfiles = new ProfilesConfigurableComboBox(new ListCellRendererWrapper<Profile>() {
@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);
public void customize(final JList list, final Profile value, final int index, final boolean selected, final boolean hasFocus) {
final String profileName = value.getName();
final SingleInspectionProfilePanel singleInspectionProfilePanel = myPanels.get(value);
final boolean isShared = singleInspectionProfilePanel != null ? singleInspectionProfilePanel.isProfileShared() : false;
setIcon(isShared ? AllIcons.General.ProjectSettings : AllIcons.General.Settings);
setText(profileName);
}
}) {
@Override
public void onProfileChosen(InspectionProfileImpl inspectionProfile) {
myLayout.show(myPanel, inspectionProfile.getName());
myAuxiliaryRightPanel.showDescription(inspectionProfile.getDescription());
}
};
myProfilesHolder = new JPanel();
myProfilesHolder.setLayout(new CardLayout());
myManageButton = new ManageButton(new ManageButtonBuilder() {
@Override
public boolean isSharedToTeamMembers() {
SingleInspectionProfilePanel panel = getSelectedPanel();
return panel != null && panel.isProfileShared();
}
@Override
public void setShareToTeamMembers(boolean share) {
final SingleInspectionProfilePanel panel = getSelectedPanel();
LOG.assertTrue(panel != null, "No settings panel for: " + getSelectedObject());
panel.setProfileShared(share);
myProfiles.repaint();
}
@Override
public void copy() {
final InspectionProfileImpl newProfile = copyToNewProfile(0, getSelectedObject(), getProject());
if (newProfile != null) {
final InspectionProfileImpl modifiableModel = (InspectionProfileImpl)newProfile.getModifiableModel();
modifiableModel.setModified(true);
modifiableModel.setLocal(true);
addProfile(modifiableModel);
rename(modifiableModel);
}
}
});
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));
public boolean canRename() {
final InspectionProfileImpl profile = getSelectedObject();
return !profile.isProfileLocked();
}
});
final Project project = projectProfileManager.getProject();
myImportButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
public void rename() {
rename(getSelectedObject());
}
private void rename(@NotNull final InspectionProfileImpl inspectionProfile) {
final String initialName = inspectionProfile.getName();
myProfiles.showEditCard(inspectionProfile.getName(), new SaveInputComponentValidator() {
@Override
public void doSave(@NotNull String text) {
if (!text.equals(initialName)) {
deleteProfile(inspectionProfile);
myProfiles.getModel().removeElement(inspectionProfile);
inspectionProfile.setName(text);
inspectionProfile.setModified(true);
putProfile(inspectionProfile, myPanels.remove(inspectionProfile));
addProfile(inspectionProfile);
}
myProfiles.showComboBoxCard();
}
@Override
public boolean checkValid(@NotNull String text) {
final boolean isValid = text.equals(initialName) || !hasName(text);
if (isValid) {
myAuxiliaryRightPanel.showDescription(getSelectedObject().getDescription());
} else {
myAuxiliaryRightPanel.showError("Name is already in use. Please change name to unique.");
}
return isValid;
}
});
}
@Override
public boolean canDelete() {
return isDeleteEnabled(myProfiles.getSelectedProfile());
}
@Override
public void delete() {
final InspectionProfileImpl selectedProfile = myProfiles.getSelectedProfile();
myProfiles.getModel().removeElement(selectedProfile);
myDeletedProfiles.add(selectedProfile.getName());
}
@Override
public boolean canEditDescription() {
return true;
}
@Override
public void editDescription() {
myAuxiliaryRightPanel.editDescription(getSelectedObject().getDescription());
}
@Override
public void export() {
final FileChooserDescriptor descriptor = FileChooserDescriptorFactory.createSingleFolderDescriptor();
descriptor.setDescription("Choose directory to store profile file");
FileChooser.chooseFile(descriptor, getProject(), 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 = getSelectedObject();
LOG.assertTrue(true);
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);
}
}
});
}
@Override
public void doImport() {
final FileChooserDescriptor descriptor = new FileChooserDescriptor(true, false, false, false, false, false) {
@Override
public boolean isFileSelectable(VirtualFile file) {
@@ -137,7 +257,7 @@ public abstract class InspectionToolsConfigurable extends BaseConfigurable imple
}
};
descriptor.setDescription("Choose profile file");
FileChooser.chooseFile(descriptor, project, myWholePanel, null, new Consumer<VirtualFile>() {
FileChooser.chooseFile(descriptor, getProject(), myWholePanel, null, new Consumer<VirtualFile>() {
@Override
public void consume(VirtualFile file) {
if (file == null) return;
@@ -169,9 +289,10 @@ public abstract class InspectionToolsConfigurable extends BaseConfigurable imple
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));
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());
@@ -180,18 +301,21 @@ public abstract class InspectionToolsConfigurable extends BaseConfigurable imple
}
profile.readExternal(rootElement);
profile.setLocal(true);
profile.initInspectionTools(project);
profile.initInspectionTools(getProject());
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;
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);
//TODO myDeletedProfiles ? really need this
myDeletedProfiles.remove(profile.getName());
}
catch (InvalidDataException e1) {
LOG.error(e1);
@@ -205,75 +329,69 @@ public abstract class InspectionToolsConfigurable extends BaseConfigurable imple
}
});
}
});
}).build();
myExportButton.addActionListener(new ActionListener() {
myAuxiliaryRightPanel = new AuxiliaryRightPanel(new AuxiliaryRightPanel.DescriptionSaveListener() {
@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);
}
}
});
public void saveDescription(@NotNull String description) {
getSelectedObject().setDescription(description);
myAuxiliaryRightPanel.showDescription(description);
}
});
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);
}
}
});
toolbar.setLayout(new GridBagLayout());
toolbar.add(new JLabel(myHeaderTitle),
new GridBagConstraints(0, 0, 1, 1, 0, 0, GridBagConstraints.WEST, GridBagConstraints.VERTICAL, new Insets(10, 5, 0, 0), 0,
0));
toolbar.add(myProfiles,
new GridBagConstraints(1, 0, 1, 1, 0, 0, GridBagConstraints.WEST, GridBagConstraints.VERTICAL, new Insets(10, 5, 0, 0), 0,
0));
toolbar.add(myManageButton,
new GridBagConstraints(2, 0, 1, 1, 0, 0, GridBagConstraints.WEST, GridBagConstraints.VERTICAL, new Insets(10, 5, 0, 0), 0,
0));
toolbar.add(myAuxiliaryRightPanel,
new GridBagConstraints(3, 0, 1, 1, 1.0, 0, GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(10, 5, 0, 0), 0,
0));
((InspectionManagerEx)InspectionManager.getInstance(projectProfileManager.getProject())).buildInspectionSearchIndexIfNecessary();
myProjectProfileManager = projectProfileManager;
myProfileManager = profileManager;
}
myJBScrollPane.setBorder(null);
private Project getProject() {
return myProjectProfileManager.getProject();
}
@Nullable
private InspectionProfileImpl copyToNewProfile(final int initValue, ModifiableModel selectedProfile, @NotNull Project project) {
String profileDefaultName = selectedProfile.getName();
do {
profileDefaultName += " (copy)";
}
while (hasName(profileDefaultName));
final ProfileManager profileManager = selectedProfile.getProfileManager();
InspectionProfileImpl inspectionProfile =
new InspectionProfileImpl(profileDefaultName, InspectionToolRegistrar.getInstance(), profileManager);
inspectionProfile.copyFrom(selectedProfile);
inspectionProfile.setName(profileDefaultName);
inspectionProfile.initInspectionTools(project);
inspectionProfile.setModified(true);
return inspectionProfile;
}
private void addProfile(InspectionProfileImpl model) {
final String modelName = model.getName();
final SingleInspectionProfilePanel panel = createPanel(model, modelName, true);
final SingleInspectionProfilePanel panel = createPanel(model, modelName);
myPanel.add(modelName, panel);
if (!myPanels.containsKey(getProfilePrefix(model) + modelName)) {
myPanel.add(modelName, panel);
if (!myPanels.containsKey(modelName)) {
//noinspection unchecked
((DefaultComboBoxModel)myProfiles.getModel()).addElement(model);
myProfiles.getModel().addElement(model);
}
putProfile(model, panel);
myProfiles.setSelectedItem(model);
myProfiles.selectProfile(model);
}
@Override
@@ -294,7 +412,7 @@ public abstract class InspectionToolsConfigurable extends BaseConfigurable imple
@Override
public Runnable enableSearch(final String option) {
return new Runnable(){
return new Runnable() {
@Override
public void run() {
SingleInspectionProfilePanel panel = getSelectedPanel();
@@ -307,39 +425,6 @@ public abstract class InspectionToolsConfigurable extends BaseConfigurable imple
@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;
}
@@ -357,40 +442,32 @@ public abstract class InspectionToolsConfigurable extends BaseConfigurable imple
@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);
final Map<Profile, SingleInspectionProfilePanel> panels = new LinkedHashMap<Profile, SingleInspectionProfilePanel>();
for (final Profile inspectionProfile : myPanels.keySet()) {
if (myDeletedProfiles.remove(inspectionProfile.getName())) {
deleteProfile(getProfilePanel(inspectionProfile).getSelectedProfile());
}
else {
final SingleInspectionProfilePanel panel = getProfilePanel(name);
final SingleInspectionProfilePanel panel = getProfilePanel(inspectionProfile);
panel.apply();
final ModifiableModel profile = panel.getSelectedProfile();
panels.put(getProfilePrefix(profile) + profile.getName(), panel);
panels.put(profile, 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());
return myPanels.get(inspectionProfile);
}
private void putProfile(Profile profile, SingleInspectionProfilePanel panel) {
myPanels.put(getProfilePrefix(profile) + profile.getName(), panel);
myPanels.put(profile, panel);
}
private static String getProfilePrefix(Profile profile) {
return (profile.isLocal() ? "L" : "S");
}
protected void deleteProfile(String name) {
protected void deleteProfile(Profile profile) {
final String name = profile.getName();
if (myProfileManager.getProfile(name, false) != null) {
myProfileManager.deleteProfile(name);
}
@@ -402,24 +479,28 @@ public abstract class InspectionToolsConfigurable extends BaseConfigurable imple
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 Collection<Profile> profiles = getProfiles();
final List<Profile> modifiableProfiles = new ArrayList<Profile>(profiles.size());
for (Profile profile : profiles) {
final String profileName = profile.getName();
final SingleInspectionProfilePanel panel = createPanel((InspectionProfileImpl)profile, profileName, false);
putProfile(profile, panel);
final ModifiableModel modifiableProfile = ((InspectionProfileImpl)profile).getModifiableModel();
modifiableProfiles.add(modifiableProfile);
final SingleInspectionProfilePanel panel = createPanel((InspectionProfileImpl)modifiableProfile, profileName);
putProfile(modifiableProfile, panel);
myPanel.add(profileName, panel);
}
myProfiles.reset(modifiableProfiles);
myAuxiliaryRightPanel.showDescription(getSelectedObject().getDescription());
final InspectionProfileImpl inspectionProfile = getCurrentProfile();
myProfiles.setSelectedItem(inspectionProfile);
myProfiles.selectProfile(inspectionProfile);
myLayout.show(myPanel, inspectionProfile.getName());
myDeleteButton.setEnabled(isDeleteEnabled(inspectionProfile));
//myDeleteButton.setEnabled(isDeleteEnabled(inspectionProfile));
final SingleInspectionProfilePanel panel = getSelectedPanel();
if (panel != null) {
panel.setVisible(true);//make sure that UI was initialized
@@ -437,13 +518,11 @@ public abstract class InspectionToolsConfigurable extends BaseConfigurable imple
}
}
});
myShareProfileCheckBox.setSelected(panel.isProfileShared());
}
}
private SingleInspectionProfilePanel createPanel(InspectionProfileImpl profile, String profileName, boolean model) {
return new SingleInspectionProfilePanel(myProjectProfileManager, profileName, model ? profile : profile.getModifiableModel()) {
private SingleInspectionProfilePanel createPanel(InspectionProfileImpl profile, String profileName) {
return new SingleInspectionProfilePanel(myProjectProfileManager, profileName, profile) {
@Override
protected boolean accept(InspectionToolWrapper entry) {
return super.accept(entry) && InspectionToolsConfigurable.this.acceptTool(entry);
@@ -492,26 +571,19 @@ public abstract class InspectionToolsConfigurable extends BaseConfigurable imple
@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;
}
}
myProfiles.selectProfile(name);
}
@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());
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);
}
@@ -519,19 +591,33 @@ public abstract class InspectionToolsConfigurable extends BaseConfigurable imple
return "configured profiles: " + StringUtil.join(myPanels.keySet(), ", ");
}
protected Set<String> getKnownNames() {
return myPanels.keySet();
protected Collection<String> getKnownNames() {
return ContainerUtil.map(myPanels.keySet(), new Function<Profile, String>() {
@Override
public String fun(Profile profile) {
return profile.getName();
}
});
}
private boolean hasName(final @NotNull String name) {
for (Profile profile : myPanels.keySet()) {
if (name.equals(profile.getName())) {
return true;
}
}
return false;
}
@NotNull
@Override
public InspectionProfileImpl getSelectedObject() {
return (InspectionProfileImpl)myProfiles.getSelectedItem();
return myProfiles.getSelectedProfile();
}
@Override
public JComponent getPreferredFocusedComponent() {
final InspectionProfileImpl inspectionProfile = getSelectedObject();
assert inspectionProfile != null : configuredProfiles();
return getProfilePanel(inspectionProfile).getPreferredFocusedComponent();
}
}
@@ -0,0 +1,162 @@
/*
* 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.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.DefaultActionGroup;
import com.intellij.openapi.actionSystem.ex.CheckboxAction;
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");
}
public JComponent build() {
final JComponent component = createCustomComponent(getTemplatePresentation());
component.setBorder(BorderFactory.createEmptyBorder(0, 0, 1, 0));
return component;
}
@NotNull
@Override
protected DefaultActionGroup createPopupActionGroup(JComponent button) {
DefaultActionGroup group = new DefaultActionGroup();
group.add(new ShareToTeamCheckBoxAction());
group.addSeparator();
group.add(new CopyAction());
group.add(new RenameAction());
group.add(new DeleteAction());
group.add(new EditDescriptionAction());
group.add(new ExportAction());
group.addSeparator();
group.add(new ImportAction());
return group;
}
private class ShareToTeamCheckBoxAction extends CheckboxAction implements DumbAware {
public ShareToTeamCheckBoxAction() {
super("Share to team members");
}
@Override
public boolean isSelected(AnActionEvent e) {
return myBuilder.isSharedToTeamMembers();
}
@Override
public void setSelected(AnActionEvent e, boolean state) {
myBuilder.setShareToTeamMembers(state);
}
}
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();
}
@Override
public void update(AnActionEvent e) {
e.getPresentation().setEnabledAndVisible(myBuilder.canRename());
}
}
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() {
super("Edit 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();
}
}
}
@@ -0,0 +1,45 @@
/*
* 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;
/**
* @author Dmitry Batkovich
*/
public interface ManageButtonBuilder {
boolean isSharedToTeamMembers();
void setShareToTeamMembers(boolean share);
void copy();
boolean canRename();
void rename();
boolean canDelete();
void delete();
boolean canEditDescription();
void editDescription();
void export();
void doImport();
}
@@ -0,0 +1,108 @@
/*
* 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.codeInspection.ex.InspectionProfileImpl;
import com.intellij.openapi.util.Comparing;
import com.intellij.profile.Profile;
import com.intellij.ui.ListCellRendererWrapper;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Collection;
/**
* @author Dmitry Batkovich
*/
public abstract class ProfilesConfigurableComboBox extends JPanel {
private static final String COMBO_CARD = "combo.card";
private static final String EDIT_CARD = "edit.card";
private final JComboBox myProfilesComboBox;
private final CardLayout myCardLayout;
private final SaveInputComponent mySubmitNameComponent;
private final SaveInputComponentValidator.Wrapper mySaveListener;
public ProfilesConfigurableComboBox(final ListCellRendererWrapper<Profile> comboBoxItemsRenderer) {
myCardLayout = new CardLayout();
setLayout(myCardLayout);
myProfilesComboBox = new JComboBox();
add(myProfilesComboBox, COMBO_CARD);
mySaveListener = new SaveInputComponentValidator.Wrapper();
mySubmitNameComponent = new SaveInputComponent(mySaveListener);
add(mySubmitNameComponent, EDIT_CARD);
myProfilesComboBox.setRenderer(comboBoxItemsRenderer);
myProfilesComboBox.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
final InspectionProfileImpl profile = getSelectedProfile();
if (profile != null) {
onProfileChosen(profile);
}
}
});
showComboBoxCard();
}
protected abstract void onProfileChosen(final InspectionProfileImpl inspectionProfile);
public void showEditCard(final String initialValue, final SaveInputComponentValidator inputValidator) {
mySaveListener.setDelegate(inputValidator);
mySubmitNameComponent.setText(initialValue);
myCardLayout.show(this, EDIT_CARD);
mySubmitNameComponent.requestFocusToTextField();
}
public void reset(final Collection<Profile> profiles) {
final DefaultComboBoxModel aModel = new DefaultComboBoxModel();
myProfilesComboBox.setModel(aModel);
for (Profile profile : profiles) {
aModel.addElement(profile);
}
myProfilesComboBox.setSelectedIndex(0);
}
public DefaultComboBoxModel getModel() {
return (DefaultComboBoxModel)myProfilesComboBox.getModel();
}
public InspectionProfileImpl getSelectedProfile() {
return (InspectionProfileImpl)myProfilesComboBox.getSelectedItem();
}
public void selectProfile(InspectionProfileImpl inspectionProfile) {
myProfilesComboBox.setSelectedItem(inspectionProfile);
}
public void selectProfile(String name) {
for (int i = 0; i < myProfilesComboBox.getItemCount(); i++) {
if (Comparing.strEqual(((InspectionProfileImpl)myProfilesComboBox.getItemAt(i)).getName(), name)) {
myProfilesComboBox.setSelectedIndex(i);
break;
}
}
}
public void showComboBoxCard() {
myCardLayout.show(this, COMBO_CARD);
}
}
@@ -0,0 +1,160 @@
/*
* 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.ide.ui.laf.darcula.DarculaUIUtil;
import com.intellij.ide.ui.laf.darcula.ui.DarculaButtonPainter;
import com.intellij.ide.ui.laf.darcula.ui.DarculaButtonUI;
import com.intellij.openapi.ui.GraphicsConfig;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.ui.ClickListener;
import com.intellij.ui.ColorUtil;
import com.intellij.ui.Gray;
import com.intellij.ui.JBColor;
import com.intellij.ui.components.JBTextField;
import com.intellij.util.ui.GraphicsUtil;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
import javax.swing.border.Border;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.plaf.basic.BasicButtonUI;
import java.awt.*;
import java.awt.event.*;
/**
* @author Dmitry Batkovich
*/
public class SaveInputComponent extends JPanel {
private final JButton myButton;
private final JTextField myTextField;
private final SaveInputComponentValidator myInputValidator;
public SaveInputComponent(final SaveInputComponentValidator inputValidator) {
myButton = new JButton() {
@Override
public void paint(Graphics g) {
super.paint(g);
}
};
myButton.setText("Save");
myButton.setDefaultCapable(false);
myButton.setFocusable(false);
myButton.putClientProperty("JButton.buttonType", "square");
//myButton.setUI(new DarculaButtonUI() {
// @Override
// public void paint(Graphics g, JComponent c) {
// final Color color1 = getButtonColor1();
// final Color color2 = getButtonColor2();
// if (color1 != null && color2 != null) {
// ((Graphics2D)g).setPaint(UIUtil.getGradientPaint(0, 0, color1, 0, c.getHeight(), color2));
// }
// //g.fillRoundRect(2, 0, c.getWidth() - 3, c.getHeight() - 2, 5, 5);
// super.paint(g, c);n
// }
//});
myButton.setBorder(new DarculaButtonPainter() {
@Override
public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) {
final Graphics2D g2d = (Graphics2D)g;
final GraphicsConfig config = new GraphicsConfig(g);
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_DEFAULT);
((Graphics2D)g).setPaint(Gray._100.withAlpha(180));
//g.drawRoundRect(x + 2, y, width - 3, height - 2, 5, 5);
g.drawRoundRect(x + 2, y, width - 3 - 5, height - 2, 5, 5);
config.restore();
}
@Override
protected int getOffset() {
return 5;
}
@Override
public Insets getBorderInsets(Component c) {
return new Insets(2, 10, 2, 10);
}
});
myTextField = new JBTextField();
myTextField.setFocusable(true);
setFocusable(false);
setLayout(new BorderLayout());
add(myTextField, BorderLayout.CENTER);
add(myButton, BorderLayout.EAST);
myInputValidator = inputValidator;
myTextField.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(myTextField.getText());
myButton.setEnabled(isValid);
final Color color = isValid ? UIUtil.getTextAreaForeground() : JBColor.RED;
if (!color.equals(myTextField.getForeground())) {
myTextField.setForeground(color);
}
}
});
myTextField.addFocusListener(new FocusAdapter() {
@Override
public void focusLost(FocusEvent e) {
checkAndApply();
}
});
new ClickListener() {
@Override
public boolean onClick(@NotNull MouseEvent event, int clickCount) {
checkAndApply();
return true;
}
}.installOn(myButton);
}
public void requestFocusToTextField() {
myTextField.requestFocus();
}
public SaveInputComponent setText(final @NotNull String textFieldValue) {
myTextField.setText(textFieldValue);
return this;
}
private void checkAndApply() {
String text = myTextField.getText();
if (text == null) {
text = "";
}
if (myInputValidator.checkValid(text)) {
myInputValidator.doSave(text);
}
}
}
@@ -0,0 +1,52 @@
/*
* 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);
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());
}
}
}