mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-10-01 19:02:13 +07:00
new inspection tool configurable ui
This commit is contained in:
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+1
@@ -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;
|
||||
|
||||
-110
@@ -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&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&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="&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="&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="&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="&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>
|
||||
+2
-2
@@ -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();
|
||||
}
|
||||
}
|
||||
+184
-185
@@ -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();
|
||||
|
||||
+154
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
+276
-190
@@ -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();
|
||||
}
|
||||
}
|
||||
+162
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
+45
@@ -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();
|
||||
|
||||
}
|
||||
+108
@@ -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);
|
||||
}
|
||||
}
|
||||
+160
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
+52
@@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user