show progress during applying quick fixes
authorAnna Kozlova <anna.kozlova@jetbrains.com>
Fri, 28 Aug 2015 14:09:04 +0000 (17:09 +0300)
committerAnna Kozlova <anna.kozlova@jetbrains.com>
Fri, 28 Aug 2015 15:33:19 +0000 (18:33 +0300)
platform/lang-impl/src/com/intellij/codeInspection/actions/CleanupInspectionIntention.java
platform/lang-impl/src/com/intellij/codeInspection/ex/PerformFixesModalTask.java [new file with mode: 0644]
platform/lang-impl/src/com/intellij/codeInspection/ex/QuickFixAction.java

index b6a68ef88fb079c4e624091e53c4a52e30f08c4f..3d16648f29c5842f067621867765b3eb96ed6de5 100644 (file)
@@ -24,16 +24,17 @@ import com.intellij.codeInsight.intention.IntentionAction;
 import com.intellij.codeInspection.*;
 import com.intellij.codeInspection.ex.InspectionToolWrapper;
 import com.intellij.codeInspection.ex.LocalInspectionToolWrapper;
-import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.codeInspection.ex.PerformFixesModalTask;
+import com.intellij.openapi.command.CommandProcessor;
 import com.intellij.openapi.editor.Editor;
 import com.intellij.openapi.progress.EmptyProgressIndicator;
 import com.intellij.openapi.progress.ProgressManager;
 import com.intellij.openapi.project.Project;
 import com.intellij.openapi.util.Computable;
-import com.intellij.psi.PsiDocumentManager;
 import com.intellij.psi.PsiElement;
 import com.intellij.psi.PsiFile;
 import com.intellij.util.IncorrectOperationException;
+import com.intellij.util.SequentialModalProgressTask;
 import org.jetbrains.annotations.NotNull;
 
 import java.util.Collections;
@@ -87,30 +88,22 @@ public class CleanupInspectionIntention implements IntentionAction, HighPriority
         return d2.getTextRange().getStartOffset() - d1.getTextRange().getStartOffset();
       }
     });
-    boolean applicableFixFound = false;
-    for (final ProblemDescriptor descriptor : descriptions) {
-      final QuickFix[] fixes = descriptor.getFixes();
-      if (fixes != null && fixes.length > 0) {
-        for (final QuickFix<CommonProblemDescriptor> fix : fixes) {
-          if (fix != null && fix.getClass().isAssignableFrom(myQuickfixClass)) {
-            final PsiElement element = descriptor.getPsiElement();
-            if (element != null && element.isValid()) {
-              applicableFixFound = true;
-              ApplicationManager.getApplication().runWriteAction(new Runnable() {
-                @Override
-                public void run() {
-                  fix.applyFix(project, descriptor);
-                }
-              });
-              PsiDocumentManager.getInstance(project).commitAllDocuments();
-            }
-            break;
-          }
-        }
+    
+    final String templatePresentationText = "Apply Fixes";
+    final SequentialModalProgressTask progressTask =
+      new SequentialModalProgressTask(project, templatePresentationText, false);
+    final PerformFixesTask fixesTask = new PerformFixesTask(project, descriptions.toArray(new CommonProblemDescriptor[descriptions.size()]), progressTask);
+    CommandProcessor.getInstance().executeCommand(project, new Runnable() {
+      @Override
+      public void run() {
+        CommandProcessor.getInstance().markCurrentCommandAsGlobal(project);
+        progressTask.setMinIterationTime(200);
+        progressTask.setTask(fixesTask);
+        ProgressManager.getInstance().run(progressTask);
       }
-    }
+    }, templatePresentationText, null);
 
-    if (!applicableFixFound) {
+    if (!fixesTask.isApplicableFixFound()) {
       HintManager.getInstance().showErrorHint(editor, "Unfortunately '" + myText + "' is currently not available for batch mode");
     }
   }
@@ -125,4 +118,35 @@ public class CleanupInspectionIntention implements IntentionAction, HighPriority
   public boolean startInWriteAction() {
     return false;
   }
+  
+  private class PerformFixesTask extends PerformFixesModalTask {
+    private boolean myApplicableFixFound = false;
+
+    public PerformFixesTask(@NotNull Project project,
+                            @NotNull CommonProblemDescriptor[] descriptors,
+                            @NotNull SequentialModalProgressTask task) {
+      super(project, descriptors, task);
+    }
+
+    @Override
+    protected void applyFix(Project project, CommonProblemDescriptor descriptor) {
+      final QuickFix[] fixes = descriptor.getFixes();
+      if (fixes != null && fixes.length > 0) {
+        for (final QuickFix<CommonProblemDescriptor> fix : fixes) {
+          if (fix != null && fix.getClass().isAssignableFrom(myQuickfixClass)) {
+            final PsiElement element = ((ProblemDescriptor)descriptor).getPsiElement();
+            if (element != null && element.isValid()) {
+              fix.applyFix(project, descriptor);
+              myApplicableFixFound = true;
+            }
+            break;
+          }
+        }
+      }
+    }
+
+    public boolean isApplicableFixFound() {
+      return myApplicableFixFound;
+    }
+  }
 }
diff --git a/platform/lang-impl/src/com/intellij/codeInspection/ex/PerformFixesModalTask.java b/platform/lang-impl/src/com/intellij/codeInspection/ex/PerformFixesModalTask.java
new file mode 100644 (file)
index 0000000..1001104
--- /dev/null
@@ -0,0 +1,85 @@
+/*
+ * Copyright 2000-2015 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.codeInspection.ex;
+
+import com.intellij.codeInspection.CommonProblemDescriptor;
+import com.intellij.codeInspection.ProblemDescriptor;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.progress.ProgressIndicator;
+import com.intellij.openapi.project.Project;
+import com.intellij.psi.PsiDocumentManager;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.presentation.java.SymbolPresentationUtil;
+import com.intellij.util.SequentialModalProgressTask;
+import com.intellij.util.SequentialTask;
+import org.jetbrains.annotations.NotNull;
+
+public abstract class PerformFixesModalTask implements SequentialTask {
+  @NotNull
+  protected final Project myProject;
+  private final CommonProblemDescriptor[] myDescriptors;
+  private final SequentialModalProgressTask myTask;
+  private final PsiDocumentManager myDocumentManager;
+  private int myCount = 0;
+
+  public PerformFixesModalTask(@NotNull Project project,
+                               @NotNull CommonProblemDescriptor[] descriptors,
+                               @NotNull SequentialModalProgressTask task) {
+    myProject = project;
+    myDescriptors = descriptors;
+    myTask = task;
+    myDocumentManager = PsiDocumentManager.getInstance(myProject);
+  }
+
+  @Override
+  public void prepare() {
+  }
+
+  @Override
+  public boolean isDone() {
+    return myCount > myDescriptors.length - 1;
+  }
+
+  @Override
+  public boolean iteration() {
+    final CommonProblemDescriptor descriptor = myDescriptors[myCount++];
+    ProgressIndicator indicator = myTask.getIndicator();
+    if (indicator != null) {
+      indicator.setFraction((double)myCount / myDescriptors.length);
+      String presentableText = "usages";
+      if (descriptor instanceof ProblemDescriptor) {
+        final PsiElement psiElement = ((ProblemDescriptor)descriptor).getPsiElement();
+        if (psiElement != null) {
+          presentableText = SymbolPresentationUtil.getSymbolPresentableText(psiElement);
+        }
+      }
+      indicator.setText("Processing " + presentableText);
+    }
+    ApplicationManager.getApplication().runWriteAction(new Runnable() {
+      @Override
+      public void run() {
+        myDocumentManager.commitAllDocuments();
+        applyFix(myProject, descriptor);
+      }
+    });
+    return isDone();
+  }
+
+  @Override
+  public void stop() {}
+  
+  protected abstract void applyFix(Project project, CommonProblemDescriptor descriptor);
+}
index 2be41efe93996e4fc0f0f74431066d0bd967423b..52d0133ee3640c576d4181ac665fdd49e4764757 100644 (file)
@@ -31,7 +31,6 @@ import com.intellij.openapi.actionSystem.AnActionEvent;
 import com.intellij.openapi.actionSystem.CustomShortcutSet;
 import com.intellij.openapi.application.ApplicationManager;
 import com.intellij.openapi.command.CommandProcessor;
-import com.intellij.openapi.progress.ProgressIndicator;
 import com.intellij.openapi.progress.ProgressManager;
 import com.intellij.openapi.project.Project;
 import com.intellij.openapi.vfs.ReadonlyStatusHandler;
@@ -40,9 +39,7 @@ import com.intellij.openapi.vfs.VirtualFile;
 import com.intellij.psi.PsiDocumentManager;
 import com.intellij.psi.PsiElement;
 import com.intellij.psi.PsiFile;
-import com.intellij.psi.presentation.java.SymbolPresentationUtil;
 import com.intellij.util.SequentialModalProgressTask;
-import com.intellij.util.SequentialTask;
 import gnu.trove.THashSet;
 import org.jetbrains.annotations.NotNull;
 
@@ -148,22 +145,19 @@ public class QuickFixAction extends AnAction {
     try {
       final Set<PsiElement> ignoredElements = new HashSet<PsiElement>();
 
+      final String templatePresentationText = getTemplatePresentation().getText();
+      assert templatePresentationText != null;
       CommandProcessor.getInstance().executeCommand(project, new Runnable() {
         @Override
         public void run() {
           CommandProcessor.getInstance().markCurrentCommandAsGlobal(project);
-          ApplicationManager.getApplication().runWriteAction(new Runnable() {
-            @Override
-            public void run() {
-              final SequentialModalProgressTask progressTask =
-                new SequentialModalProgressTask(project, getTemplatePresentation().getText(), false);
-              progressTask.setMinIterationTime(200);
-              progressTask.setTask(new PerformFixesTask(project, descriptors, ignoredElements, progressTask, context));
-              ProgressManager.getInstance().run(progressTask);
-            }
-          });
+          final SequentialModalProgressTask progressTask =
+            new SequentialModalProgressTask(project, templatePresentationText, false);
+          progressTask.setMinIterationTime(200);
+          progressTask.setTask(new PerformFixesTask(project, descriptors, ignoredElements, progressTask, context));
+          ProgressManager.getInstance().run(progressTask);
         }
-      }, getTemplatePresentation().getText(), null);
+      }, templatePresentationText, null);
 
       refreshViews(project, ignoredElements, myToolWrapper);
     }
@@ -300,52 +294,24 @@ public class QuickFixAction extends AnAction {
     return true;
   }
 
-  private class PerformFixesTask implements SequentialTask {
-    @NotNull
-    private final Project myProject;
-    private final CommonProblemDescriptor[] myDescriptors;
+  private class PerformFixesTask extends PerformFixesModalTask {
+    @NotNull private final GlobalInspectionContextImpl myContext;
     @NotNull
     private final Set<PsiElement> myIgnoredElements;
-    private final SequentialModalProgressTask myTask;
-    @NotNull private final GlobalInspectionContextImpl myContext;
-    private int myCount = 0;
 
     public PerformFixesTask(@NotNull Project project,
                             @NotNull CommonProblemDescriptor[] descriptors,
                             @NotNull Set<PsiElement> ignoredElements,
                             @NotNull SequentialModalProgressTask task,
                             @NotNull GlobalInspectionContextImpl context) {
-      myProject = project;
-      myDescriptors = descriptors;
-      myIgnoredElements = ignoredElements;
-      myTask = task;
+      super(project, descriptors, task);
       myContext = context;
+      myIgnoredElements = ignoredElements;
     }
 
     @Override
-    public void prepare() {
-    }
-
-    @Override
-    public boolean isDone() {
-      return myCount > myDescriptors.length - 1;
-    }
-
-    @Override
-    public boolean iteration() {
-      final CommonProblemDescriptor descriptor = myDescriptors[myCount++];
-      ProgressIndicator indicator = myTask.getIndicator();
-      if (indicator != null) {
-        indicator.setFraction((double)myCount / myDescriptors.length);
-        if (descriptor instanceof ProblemDescriptor) {
-          final PsiElement psiElement = ((ProblemDescriptor)descriptor).getPsiElement();
-          if (psiElement != null) {
-            indicator.setText("Processing " + SymbolPresentationUtil.getSymbolPresentableText(psiElement));
-          }
-        }
-      }
-      applyFix(myProject, myContext, new CommonProblemDescriptor[]{descriptor}, myIgnoredElements);
-      return isDone();
+    protected void applyFix(Project project, CommonProblemDescriptor descriptor) {
+      QuickFixAction.this.applyFix(myProject, myContext, new CommonProblemDescriptor[]{descriptor}, myIgnoredElements);
     }
 
     @Override