6bd9c1bd78f0eb181c967f4cb43e16f68242a27b
[idea/community.git] / platform / diff-impl / src / com / intellij / diff / editor / DiffRequestProcessorEditor.kt
1 // Copyright 2000-2021 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.
2 package com.intellij.diff.editor
3
4 import com.intellij.diff.impl.DiffRequestProcessor
5 import com.intellij.diff.util.DiffUserDataKeysEx
6 import com.intellij.diff.util.DiffUtil
7 import com.intellij.diff.util.FileEditorBase
8 import com.intellij.openapi.Disposable
9 import com.intellij.openapi.actionSystem.CommonShortcuts
10 import com.intellij.openapi.diagnostic.logger
11 import com.intellij.openapi.diff.DiffBundle
12 import com.intellij.openapi.fileEditor.FileEditor
13 import com.intellij.openapi.fileEditor.impl.EditorWindow
14 import com.intellij.openapi.util.Disposer
15 import com.intellij.openapi.vfs.VirtualFile
16 import java.awt.BorderLayout
17 import java.awt.event.ContainerAdapter
18 import java.awt.event.ContainerEvent
19 import java.awt.event.KeyEvent
20 import javax.swing.JComponent
21 import javax.swing.JComponent.WHEN_IN_FOCUSED_WINDOW
22 import javax.swing.JPanel
23 import javax.swing.KeyStroke
24
25 open class DiffRequestProcessorEditor(
26   private val file: DiffVirtualFile,
27   val processor: DiffRequestProcessor
28 ) : FileEditorBase() {
29   companion object {
30     private val LOG = logger<DiffRequestProcessorEditor>()
31   }
32
33   private var disposed = false
34
35   private val panel = MyPanel(processor.component)
36
37   init {
38     putUserData(EditorWindow.HIDE_TABS, true)
39     if (!DiffUtil.isUserDataFlagSet(DiffUserDataKeysEx.DIFF_IN_EDITOR_WITH_EXPLICIT_DISPOSABLE, processor.context)) {
40       Disposer.register(this, Disposable {
41         Disposer.dispose(processor)
42       })
43     }
44     Disposer.register(processor, Disposable {
45       propertyChangeSupport.firePropertyChange(FileEditor.PROP_VALID, true, false)
46     })
47
48     processor.component.registerKeyboardAction({ Disposer.dispose(this) },
49                                                KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), WHEN_IN_FOCUSED_WINDOW)
50
51     file.getUserData(DiffVirtualFile.ESCAPE_HANDLER)?.registerCustomShortcutSet(CommonShortcuts.ESCAPE, component, this)
52   }
53
54   override fun getComponent(): JComponent = panel
55   override fun getPreferredFocusedComponent(): JComponent? = processor.preferredFocusedComponent
56
57   override fun dispose() {
58     disposed = true
59   }
60   override fun isValid(): Boolean = !disposed && !processor.isDisposed
61   override fun getFile(): VirtualFile = file
62   override fun getName(): String = DiffBundle.message("diff.file.editor.name")
63
64   override fun selectNotify() {
65     processor.updateRequest()
66   }
67
68   private inner class MyPanel(component: JComponent) : JPanel(BorderLayout()) {
69     init {
70       add(component, BorderLayout.CENTER)
71
72       addContainerListener(object : ContainerAdapter() {
73         override fun componentRemoved(e: ContainerEvent?) {
74           if (disposed) return
75           LOG.error("DiffRequestProcessor cannot be shown twice, see com.intellij.ide.actions.SplitAction.FORBID_TAB_SPLIT, file: $file")
76         }
77       })
78     }
79   }
80 }