mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
inspection tool window: replace quick fix preview with 2 separate components: 1st when loading 2nd when selected node is ready for fix or suppression
This commit is contained in:
@@ -468,9 +468,16 @@ public class InspectionResultsView extends JPanel implements Disposable, Occuren
|
||||
}
|
||||
editorPanel.add(previewPanel, BorderLayout.CENTER);
|
||||
if (problemCount > 0) {
|
||||
final QuickFixPreviewDecorator fixToolbar = new QuickFixPreviewDecorator(previewEditor, this);
|
||||
myLoadingProgressPreview = fixToolbar;
|
||||
editorPanel.add(fixToolbar, BorderLayout.NORTH);
|
||||
final JComponent fixToolbar = QuickFixPreviewPanelFactory.create(previewEditor, this);
|
||||
if (fixToolbar != null) {
|
||||
if (fixToolbar instanceof InspectionTreeLoadingProgressAware) {
|
||||
myLoadingProgressPreview = (InspectionTreeLoadingProgressAware)fixToolbar;
|
||||
}
|
||||
if (previewEditor != null) {
|
||||
previewPanel.setBorder(IdeBorderFactory.createBorder(SideBorder.TOP));
|
||||
}
|
||||
editorPanel.add(fixToolbar, BorderLayout.NORTH);
|
||||
}
|
||||
}
|
||||
mySplitter.setSecondComponent(editorPanel);
|
||||
}
|
||||
@@ -516,10 +523,10 @@ public class InspectionResultsView extends JPanel implements Disposable, Occuren
|
||||
settings.setAdditionalLinesCount(0);
|
||||
settings.setLeadingWhitespaceShown(true);
|
||||
myPreviewEditor.getColorsScheme().setColor(EditorColors.GUTTER_BACKGROUND, myPreviewEditor.getColorsScheme().getDefaultBackground());
|
||||
myPreviewEditor.getScrollPane().setBorder(IdeBorderFactory.createBorder(SideBorder.TOP));
|
||||
myPreviewEditor.getScrollPane().setBorder(IdeBorderFactory.createEmptyBorder());
|
||||
}
|
||||
myPreviewEditor.getSettings().setFoldingOutlineShown(problemCount != 1);
|
||||
|
||||
myPreviewEditor.getComponent().setBorder(IdeBorderFactory.createEmptyBorder());
|
||||
if (problemCount == 1) {
|
||||
final PsiElement finalSelectedElement = selectedElement;
|
||||
ApplicationManager.getApplication().invokeLater(() -> {
|
||||
|
||||
@@ -1,177 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.codeInspection.ui;
|
||||
|
||||
import com.intellij.codeInspection.CommonProblemDescriptor;
|
||||
import com.intellij.codeInspection.ex.InspectionToolWrapper;
|
||||
import com.intellij.codeInspection.ex.QuickFixAction;
|
||||
import com.intellij.codeInspection.ui.actions.SuppressActionWrapper;
|
||||
import com.intellij.icons.AllIcons;
|
||||
import com.intellij.ide.DataManager;
|
||||
import com.intellij.openapi.actionSystem.*;
|
||||
import com.intellij.openapi.actionSystem.ex.ComboBoxAction;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.editor.ex.EditorEx;
|
||||
import com.intellij.openapi.util.Disposer;
|
||||
import com.intellij.ui.IdeBorderFactory;
|
||||
import com.intellij.ui.SimpleColoredComponent;
|
||||
import com.intellij.util.ui.AsyncProcessIcon;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
|
||||
/**
|
||||
* @author Dmitry Batkovich
|
||||
*/
|
||||
public class QuickFixPreviewDecorator extends JPanel implements InspectionTreeLoadingProgressAware {
|
||||
private static final Logger LOG = Logger.getInstance(QuickFixPreviewDecorator.class);
|
||||
private static final int MAX_FIX_COUNT = 3;
|
||||
@NotNull private final InspectionResultsView myView;
|
||||
private final InspectionToolWrapper myWrapper;
|
||||
private final ProblemPreviewEditorPresentation myFoldings;
|
||||
|
||||
private SimpleColoredComponent myWaitingLabel;
|
||||
|
||||
public QuickFixPreviewDecorator(@Nullable EditorEx editor,
|
||||
@NotNull InspectionResultsView view) {
|
||||
myFoldings = editor == null ? null : new ProblemPreviewEditorPresentation(editor, view.getProject());
|
||||
myView = view;
|
||||
myWrapper = view.getTree().getSelectedToolWrapper();
|
||||
LOG.assertTrue(myWrapper != null);
|
||||
|
||||
setLayout(new FlowLayout(FlowLayout.LEFT, 0, 0));
|
||||
|
||||
if (view.isUpdating() && !view.getTree().areDescriptorNodesSelected()) {
|
||||
setBorder(IdeBorderFactory.createEmptyBorder(16, 9, 13, 0));
|
||||
AsyncProcessIcon waitingIcon = new AsyncProcessIcon("Inspection preview panel updating...");
|
||||
Disposer.register(this, waitingIcon);
|
||||
myWaitingLabel = getLabel(1);
|
||||
add(myWaitingLabel);
|
||||
add(waitingIcon);
|
||||
}
|
||||
else {
|
||||
CommonProblemDescriptor[] descriptors = myView.getTree().getSelectedDescriptors();
|
||||
setBorder(IdeBorderFactory.createEmptyBorder(2, 8, 0, 0));
|
||||
QuickFixAction[] fixes = view.getProvider().getQuickFixes(myWrapper, view.getTree());
|
||||
fillPanel(fixes, descriptors);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void treeLoaded() {
|
||||
if (myWaitingLabel != null) {
|
||||
removeAll();
|
||||
setBorder(IdeBorderFactory.createEmptyBorder(2, 8, 0, 0));
|
||||
final InspectionTree tree = myView.getTree();
|
||||
QuickFixAction[] fixes = myView.getProvider().getQuickFixes(myWrapper, tree);
|
||||
CommonProblemDescriptor[] descriptors = tree.getSelectedDescriptors();
|
||||
fillPanel(fixes, descriptors);
|
||||
revalidate();
|
||||
repaint();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateLoadingProgress() {
|
||||
if (myWaitingLabel != null) {
|
||||
myWaitingLabel.clear();
|
||||
final InspectionTree tree = myView.getTree();
|
||||
appendTextToLabel(myWaitingLabel, tree.getSelectedProblemCount());
|
||||
}
|
||||
}
|
||||
|
||||
private void fillPanel(@Nullable QuickFixAction[] fixes,
|
||||
CommonProblemDescriptor[] descriptors) {
|
||||
if (myFoldings != null) myFoldings.appendFoldings(descriptors);
|
||||
boolean hasFixes = fixes != null && fixes.length != 0;
|
||||
int problemCount = descriptors.length;
|
||||
boolean multipleDescriptors = problemCount > 1;
|
||||
setLayout(new BoxLayout(this, BoxLayout.LINE_AXIS));
|
||||
if (multipleDescriptors) {
|
||||
add(getLabel(problemCount));
|
||||
}
|
||||
|
||||
final DefaultActionGroup actions = new DefaultActionGroup();
|
||||
if (hasFixes) {
|
||||
actions.addAll(createFixActions(fixes, multipleDescriptors));
|
||||
}
|
||||
actions.add(createSuppressionCombo(myView));
|
||||
final ActionToolbar toolbar = ActionManager.getInstance().createActionToolbar(ActionPlaces.UNKNOWN, actions, true);
|
||||
final JComponent component = toolbar.getComponent();
|
||||
toolbar.setTargetComponent(this);
|
||||
add(component);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static SimpleColoredComponent getLabel(int problemsCount) {
|
||||
SimpleColoredComponent label = new SimpleColoredComponent();
|
||||
appendTextToLabel(label, problemsCount);
|
||||
label.setBorder(IdeBorderFactory.createEmptyBorder(0, 0, 0, 2));
|
||||
return label;
|
||||
}
|
||||
|
||||
private static void appendTextToLabel(SimpleColoredComponent label,
|
||||
int problemsCount) {
|
||||
label.append(problemsCount + " problems:");
|
||||
}
|
||||
|
||||
private static AnAction createSuppressionCombo(InspectionResultsView view) {
|
||||
final AnAction[] suppressors = new SuppressActionWrapper().getChildren(AnActionEvent.createFromDataContext(ActionPlaces.CODE_INSPECTION, null, DataManager.getInstance().getDataContext(view)));
|
||||
final ComboBoxAction action = new ComboBoxAction() {
|
||||
{
|
||||
getTemplatePresentation().setText("Suppress");
|
||||
getTemplatePresentation().setEnabledAndVisible(suppressors.length != 0);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
protected DefaultActionGroup createPopupActionGroup(JComponent button) {
|
||||
DefaultActionGroup group = new DefaultCompactActionGroup();
|
||||
group.addAll(suppressors);
|
||||
return group;
|
||||
}
|
||||
};
|
||||
action.setSmallVariant(false);
|
||||
return action;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static AnAction[] createFixActions(QuickFixAction[] fixes, boolean multipleDescriptors) {
|
||||
if (fixes.length > MAX_FIX_COUNT) {
|
||||
final ComboBoxAction fixComboBox = new ComboBoxAction() {
|
||||
{
|
||||
getTemplatePresentation().setText("Apply quick fixes" + (multipleDescriptors ? " to all the problems" : ""));
|
||||
getTemplatePresentation().setIcon(AllIcons.Actions.CreateFromUsage);
|
||||
setSmallVariant(false);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
protected DefaultActionGroup createPopupActionGroup(JComponent button) {
|
||||
final DefaultActionGroup actionGroup = new DefaultActionGroup();
|
||||
for (QuickFixAction fix : fixes) {
|
||||
actionGroup.add(fix);
|
||||
}
|
||||
return actionGroup;
|
||||
}
|
||||
};
|
||||
return new AnAction[] {fixComboBox};
|
||||
}
|
||||
return fixes;
|
||||
}
|
||||
}
|
||||
+224
@@ -0,0 +1,224 @@
|
||||
/*
|
||||
* Copyright 2000-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.codeInspection.ui;
|
||||
|
||||
import com.intellij.codeInspection.CommonProblemDescriptor;
|
||||
import com.intellij.codeInspection.ex.InspectionToolWrapper;
|
||||
import com.intellij.codeInspection.ex.QuickFixAction;
|
||||
import com.intellij.codeInspection.ui.actions.SuppressActionWrapper;
|
||||
import com.intellij.icons.AllIcons;
|
||||
import com.intellij.ide.DataManager;
|
||||
import com.intellij.openapi.actionSystem.*;
|
||||
import com.intellij.openapi.actionSystem.ex.ComboBoxAction;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.editor.ex.EditorEx;
|
||||
import com.intellij.openapi.util.Disposer;
|
||||
import com.intellij.ui.IdeBorderFactory;
|
||||
import com.intellij.ui.SimpleColoredComponent;
|
||||
import com.intellij.util.ui.AsyncProcessIcon;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.util.Arrays;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/**
|
||||
* @author Dmitry Batkovich
|
||||
*/
|
||||
public class QuickFixPreviewPanelFactory {
|
||||
private static final Logger LOG = Logger.getInstance(QuickFixPreviewPanelFactory.class);
|
||||
private static final int MAX_FIX_COUNT = 3;
|
||||
|
||||
@Nullable
|
||||
public static JComponent create(@Nullable EditorEx editor,
|
||||
@NotNull InspectionResultsView view) {
|
||||
if (view.isUpdating() && !view.getTree().areDescriptorNodesSelected()) {
|
||||
return new LoadingInProgressPreview(view);
|
||||
}
|
||||
else {
|
||||
final QuickFixReadyPanel panel = new QuickFixReadyPanel(view, editor);
|
||||
return panel.isEmpty() ? null : panel;
|
||||
}
|
||||
}
|
||||
|
||||
private static class QuickFixReadyPanel extends JPanel {
|
||||
@NotNull private final InspectionResultsView myView;
|
||||
private final InspectionToolWrapper myWrapper;
|
||||
private final ProblemPreviewEditorPresentation myFoldings;
|
||||
private final boolean myEmpty;
|
||||
|
||||
public QuickFixReadyPanel(@NotNull InspectionResultsView view, EditorEx editor) {
|
||||
myView = view;
|
||||
myWrapper = view.getTree().getSelectedToolWrapper();
|
||||
LOG.assertTrue(myWrapper != null);
|
||||
myFoldings = editor == null ? null : new ProblemPreviewEditorPresentation(editor, view.getProject());
|
||||
CommonProblemDescriptor[] descriptors = myView.getTree().getSelectedDescriptors();
|
||||
QuickFixAction[] fixes = view.getProvider().getQuickFixes(myWrapper, view.getTree());
|
||||
myEmpty = fillPanel(fixes, descriptors);
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
return myEmpty;
|
||||
}
|
||||
|
||||
private boolean fillPanel(@Nullable QuickFixAction[] fixes,
|
||||
CommonProblemDescriptor[] descriptors) {
|
||||
if (myFoldings != null) myFoldings.appendFoldings(descriptors);
|
||||
boolean hasFixes = fixes != null && fixes.length != 0;
|
||||
int problemCount = descriptors.length;
|
||||
boolean multipleDescriptors = problemCount > 1;
|
||||
setLayout(new BoxLayout(this, BoxLayout.LINE_AXIS));
|
||||
boolean hasComponents = false;
|
||||
|
||||
if (multipleDescriptors) {
|
||||
add(getLabel(problemCount));
|
||||
hasComponents = true;
|
||||
}
|
||||
|
||||
final DefaultActionGroup actions = new DefaultActionGroup();
|
||||
if (hasFixes) {
|
||||
actions.addAll(createFixActions(fixes, multipleDescriptors));
|
||||
}
|
||||
final AnAction suppressionCombo = createSuppressionCombo(myView);
|
||||
if (suppressionCombo != null) {
|
||||
actions.add(suppressionCombo);
|
||||
}
|
||||
if (actions.getChildrenCount() != 0) {
|
||||
final ActionToolbar toolbar = ActionManager.getInstance().createActionToolbar(ActionPlaces.UNKNOWN, actions, true);
|
||||
final JComponent component = toolbar.getComponent();
|
||||
toolbar.setTargetComponent(this);
|
||||
add(component);
|
||||
hasComponents = true;
|
||||
}
|
||||
|
||||
if (hasComponents) {
|
||||
setBorder(IdeBorderFactory.createEmptyBorder(2, 8, 0, 0));
|
||||
}
|
||||
return !hasComponents;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static AnAction createSuppressionCombo(InspectionResultsView view) {
|
||||
final AnActionEvent
|
||||
event = AnActionEvent.createFromDataContext(ActionPlaces.CODE_INSPECTION, null, DataManager.getInstance().getDataContext(view));
|
||||
final AnAction[] suppressors = new SuppressActionWrapper().getChildren(event);
|
||||
final Stream<AnAction> suppressActionStream = Arrays.stream(suppressors).filter(s -> {
|
||||
s.update(event);
|
||||
return event.getPresentation().isEnabled();
|
||||
});
|
||||
if (!suppressActionStream.findFirst().isPresent()) {
|
||||
return null;
|
||||
}
|
||||
final ComboBoxAction action = new ComboBoxAction() {
|
||||
{
|
||||
getTemplatePresentation().setText("Suppress");
|
||||
getTemplatePresentation().setEnabledAndVisible(suppressors.length != 0);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
protected DefaultActionGroup createPopupActionGroup(JComponent button) {
|
||||
DefaultActionGroup group = new DefaultCompactActionGroup();
|
||||
group.addAll(suppressors);
|
||||
return group;
|
||||
}
|
||||
};
|
||||
action.setSmallVariant(false);
|
||||
return action;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static AnAction[] createFixActions(QuickFixAction[] fixes, boolean multipleDescriptors) {
|
||||
if (fixes.length > MAX_FIX_COUNT) {
|
||||
final ComboBoxAction fixComboBox = new ComboBoxAction() {
|
||||
{
|
||||
getTemplatePresentation().setText("Apply quick fixes" + (multipleDescriptors ? " to all the problems" : ""));
|
||||
getTemplatePresentation().setIcon(AllIcons.Actions.CreateFromUsage);
|
||||
setSmallVariant(false);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
protected DefaultActionGroup createPopupActionGroup(JComponent button) {
|
||||
final DefaultActionGroup actionGroup = new DefaultActionGroup();
|
||||
for (QuickFixAction fix : fixes) {
|
||||
actionGroup.add(fix);
|
||||
}
|
||||
return actionGroup;
|
||||
}
|
||||
};
|
||||
return new AnAction[] {fixComboBox};
|
||||
}
|
||||
return fixes;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
private static class LoadingInProgressPreview extends JPanel implements InspectionTreeLoadingProgressAware {
|
||||
private final InspectionResultsView myView;
|
||||
private SimpleColoredComponent myWaitingLabel;
|
||||
|
||||
private LoadingInProgressPreview(InspectionResultsView view) {
|
||||
myView = view;
|
||||
setLayout(new FlowLayout(FlowLayout.LEFT, 0, 0));
|
||||
setBorder(IdeBorderFactory.createEmptyBorder(16, 9, 13, 0));
|
||||
AsyncProcessIcon waitingIcon = new AsyncProcessIcon("Inspection preview panel updating...");
|
||||
Disposer.register(this, waitingIcon);
|
||||
myWaitingLabel = getLabel(1);
|
||||
add(myWaitingLabel);
|
||||
add(waitingIcon);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateLoadingProgress() {
|
||||
if (myWaitingLabel != null) {
|
||||
myWaitingLabel.clear();
|
||||
final InspectionTree tree = myView.getTree();
|
||||
appendTextToLabel(myWaitingLabel, tree.getSelectedProblemCount());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void treeLoaded() {
|
||||
ApplicationManager.getApplication().invokeLater(() -> {
|
||||
if (myView.isValid()) {
|
||||
myView.syncRightPanel();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static SimpleColoredComponent getLabel(int problemsCount) {
|
||||
SimpleColoredComponent label = new SimpleColoredComponent();
|
||||
appendTextToLabel(label, problemsCount);
|
||||
label.setBorder(IdeBorderFactory.createEmptyBorder(0, 0, 0, 2));
|
||||
return label;
|
||||
}
|
||||
|
||||
private static void appendTextToLabel(SimpleColoredComponent label,
|
||||
int problemsCount) {
|
||||
label.append(problemsCount + " problems:");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user