IDEA-154251 Enable "Replace" action in "Analyze Stacktrace" console
authorSergey Simonchik <sergey.simonchik@jetbrains.com>
Thu, 7 Apr 2016 16:57:48 +0000 (19:57 +0300)
committerSergey Simonchik <sergey.simonchik@jetbrains.com>
Thu, 7 Apr 2016 16:57:48 +0000 (19:57 +0300)
platform/lang-impl/src/com/intellij/unscramble/AnalyzeStacktraceUtil.java

index bbc2c2410dee68d732a75a24e1ddaedde0668a83..761e9e35a83e92641e99c0544ee2bc33c8ca1982 100644 (file)
@@ -23,13 +23,12 @@ import com.intellij.execution.filters.Filter;
 import com.intellij.execution.filters.TextConsoleBuilder;
 import com.intellij.execution.filters.TextConsoleBuilderFactory;
 import com.intellij.execution.impl.ConsoleViewImpl;
-import com.intellij.execution.ui.ConsoleView;
-import com.intellij.execution.ui.ConsoleViewContentType;
-import com.intellij.execution.ui.ExecutionConsole;
-import com.intellij.execution.ui.RunContentDescriptor;
+import com.intellij.execution.ui.*;
 import com.intellij.execution.ui.actions.CloseAction;
+import com.intellij.ide.DataManager;
 import com.intellij.openapi.Disposable;
 import com.intellij.openapi.actionSystem.*;
+import com.intellij.openapi.actionSystem.ex.ActionUtil;
 import com.intellij.openapi.application.ApplicationManager;
 import com.intellij.openapi.command.CommandProcessor;
 import com.intellij.openapi.editor.Document;
@@ -42,13 +41,17 @@ import com.intellij.openapi.ide.CopyPasteManager;
 import com.intellij.openapi.project.Project;
 import com.intellij.openapi.util.Disposer;
 import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.openapi.wm.IdeFocusManager;
 import com.intellij.util.ui.JBUI;
+import com.intellij.util.ui.update.UiNotifyConnector;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
 import javax.swing.*;
 import java.awt.*;
 import java.awt.datatransfer.DataFlavor;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
 
 /**
  * @author yole
@@ -103,6 +106,7 @@ public class AnalyzeStacktraceUtil {
         return true;
       }
     };
+    registerReplaceAction(project, descriptor, consoleView, text);
 
     final Executor executor = DefaultRunExecutor.getRunExecutorInstance();
     for (AnAction action: consoleView.createConsoleActions()) {
@@ -120,6 +124,70 @@ public class AnalyzeStacktraceUtil {
     return descriptor;
   }
 
+  /**
+   * Regular "Replace" editor action is unavailable for console editors (see com.intellij.openapi.editor.actions.IncrementalFindAction.Handler#isEnabled).
+   * However, it can be convenient to be able to replace user-specific paths with local paths
+   * if stacktrace links involves absolute paths (e.g. Node.js stack-traces contain absolute paths).
+   *
+   * @param consoleView
+   */
+  private static void registerReplaceAction(@NotNull Project project,
+                                            @NotNull RunContentDescriptor descriptor,
+                                            @NotNull ConsoleView consoleView,
+                                            @NotNull String stacktrace) {
+    AnAction replaceAction = ActionManager.getInstance().getAction("Replace");
+    if (replaceAction == null) {
+      return;
+    }
+    ActionUtil.registerForEveryKeyboardShortcut(consoleView.getComponent(), new ActionListener() {
+      @Override
+      public void actionPerformed(ActionEvent e) {
+        AnalyzeStacktraceDialog dialog = new AnalyzeStacktraceDialog(project) {
+          @Override
+          protected JComponent createCenterPanel() {
+            JComponent result = super.createCenterPanel();
+            myEditorPanel.setText(stacktrace);
+            UiNotifyConnector.doWhenFirstShown(myEditorPanel, new Runnable() {
+              @Override
+              public void run() {
+                performReplaceAction(project, replaceAction, myEditorPanel);
+              }
+            });
+            return result;
+          }
+
+          @Override
+          protected void doOKAction() {
+            super.doOKAction();
+            RunContentManager contentManager = ExecutionManager.getInstance(project).getContentManager();
+            contentManager.removeRunContent(DefaultRunExecutor.getRunExecutorInstance(), descriptor);
+          }
+        };
+        dialog.show();
+      }
+    }, replaceAction.getShortcutSet());
+  }
+
+  private static void performReplaceAction(@NotNull Project project, @NotNull AnAction replaceAction,
+                                           @NotNull JComponent contextComponent) {
+    IdeFocusManager.getInstance(project).doWhenFocusSettlesDown(new Runnable() {
+      @Override
+      public void run() {
+        DataContext context = DataManager.getInstance().getDataContext(contextComponent);
+        AnActionEvent actionEvent = AnActionEvent.createFromAnAction(replaceAction, null, ActionPlaces.UNKNOWN, context);
+        replaceAction.update(actionEvent);
+        if (actionEvent.getPresentation().isEnabledAndVisible()) {
+          ActionUtil.performActionDumbAware(replaceAction, actionEvent);
+        }
+      }
+    });
+    //ApplicationManager.getApplication().invokeLater(new Runnable() {
+    //  @Override
+    //  public void run() {
+    //  }
+    //}, ModalityState.stateForComponent(contextComponent));
+  }
+
   private static final class MyConsolePanel extends JPanel {
     public MyConsolePanel(ExecutionConsole consoleView, ActionGroup toolbarActions) {
       super(new BorderLayout());