// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.openapi.wm.impl.status;

import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.impl.EditorComponentImpl;
import com.intellij.openapi.fileEditor.FileDocumentManager;
import com.intellij.openapi.fileEditor.FileEditorManagerListener;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.wm.IdeFocusManager;
import com.intellij.openapi.wm.StatusBar;
import com.intellij.openapi.wm.StatusBarWidget;
import com.intellij.openapi.wm.WindowManager;
import com.intellij.ui.EditorTextField;
import com.intellij.util.messages.MessageBusConnection;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.awt.*;

public abstract class EditorBasedWidget implements StatusBarWidget, FileEditorManagerListener {
  public static final String SWING_FOCUS_OWNER_PROPERTY = "focusOwner";

  @NotNull
  protected final Project myProject;

  protected StatusBar myStatusBar;
  protected MessageBusConnection myConnection;
  private volatile boolean myDisposed;

  protected EditorBasedWidget(@NotNull Project project) {
    myProject = project;
  }

  @Nullable
  protected Editor getEditor() {
    return StatusBarUtil.getCurrentTextEditor(myStatusBar);
  }

  public boolean isOurEditor(Editor editor) {
    return editor != null &&
           editor.getComponent().isShowing() &&
           !Boolean.TRUE.equals(editor.getUserData(EditorTextField.SUPPLEMENTARY_KEY)) &&
           WindowManager.getInstance().getStatusBar(editor.getComponent(), editor.getProject()) == myStatusBar;
  }

  @Nullable
  Component getFocusedComponent() {
    Component focusOwner = KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner();
    if (focusOwner == null) {
      IdeFocusManager focusManager = IdeFocusManager.getInstance(myProject);
      Window frame = focusManager.getLastFocusedIdeWindow();
      if (frame != null) {
        focusOwner = focusManager.getLastFocusedFor(frame);
      }
    }
    return focusOwner;
  }

  @Nullable
  Editor getFocusedEditor() {
    Component component = getFocusedComponent();
    Editor editor = component instanceof EditorComponentImpl ? ((EditorComponentImpl)component).getEditor() : getEditor();
    return editor != null && !editor.isDisposed() ? editor : null;
  }

  @Nullable
  protected VirtualFile getSelectedFile() {
    final Editor editor = getEditor();
    if (editor == null) return null;
    Document document = editor.getDocument();
    return FileDocumentManager.getInstance().getFile(document);
  }

  @NotNull
  protected final Project getProject() {
    return myProject;
  }

  @Override
  public void install(@NotNull StatusBar statusBar) {
    assert statusBar.getProject() == null ||
           statusBar.getProject().equals(myProject) : "Cannot install widget from one project on status bar of another project";

    myStatusBar = statusBar;
    Disposer.register(myStatusBar, this);
    myConnection = myProject.getMessageBus().connect(this);
    myConnection.subscribe(FileEditorManagerListener.FILE_EDITOR_MANAGER, this);
  }

  @Override
  public void dispose() {
    myDisposed = true;
    myStatusBar = null;
    myConnection = null;
  }

  protected final boolean isDisposed() {
    return myDisposed;
  }
}

@@ -180,16 +180,76 @@
 tatus;%0A%0A
+import com.intellij.openapi.application.ApplicationManager;%0A
 import c
@@ -441,32 +441,90 @@
 ocumentManager;%0A
+import com.intellij.openapi.fileEditor.FileEditorManager;%0A
 import com.intel
@@ -1569,22 +1569,31 @@
 ) %7B%0A    
-return
+Editor editor =
  StatusB
@@ -1634,16 +1634,235 @@
 usBar);%0A
+    if (editor != null) %7B%0A      return editor;%0A    %7D%0A    if (ApplicationManager.getApplication().isUnitTestMode()) %7B%0A      return FileEditorManager.getInstance(myProject).getSelectedTextEditor();%0A    %7D%0A    return null;%0A
   %7D%0A%0A  p

Fix OC widget test