IDEA-246047 Reader Mode shouldn't be available in Previews
[idea/community.git] / platform / lang-impl / src / com / intellij / codeInsight / actions / ReaderModeActionProvider.kt
1 // 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.
2 package com.intellij.codeInsight.actions
3
4 import com.intellij.icons.AllIcons
5 import com.intellij.ide.HelpTooltip
6 import com.intellij.lang.LangBundle
7 import com.intellij.openapi.actionSystem.*
8 import com.intellij.openapi.actionSystem.ex.CustomComponentAction
9 import com.intellij.openapi.actionSystem.impl.ActionButtonWithText
10 import com.intellij.openapi.application.Experiments
11 import com.intellij.openapi.editor.Editor
12 import com.intellij.openapi.editor.colors.ColorKey
13 import com.intellij.openapi.editor.markup.InspectionWidgetActionProvider
14 import com.intellij.openapi.options.ShowSettingsUtil
15 import com.intellij.openapi.project.DumbAwareAction
16 import com.intellij.openapi.util.SystemInfo
17 import com.intellij.openapi.util.registry.Registry
18 import com.intellij.psi.PsiDocumentManager
19 import com.intellij.ui.JBColor
20 import com.intellij.ui.scale.JBUIScale
21 import com.intellij.util.NotNullProducer
22 import com.intellij.util.ui.EmptyIcon
23 import com.intellij.util.ui.JBUI
24 import com.intellij.util.ui.UIUtil
25 import java.awt.Insets
26 import javax.swing.JComponent
27 import javax.swing.plaf.FontUIResource
28
29 class ReaderModeActionProvider : InspectionWidgetActionProvider {
30   override fun createAction(editor: Editor): AnAction {
31     val action = object : DumbAwareAction(LangBundle.messagePointer("action.ReaderModeProvider.text"),
32                                                    LangBundle.messagePointer("action.ReaderModeProvider.description"), null), CustomComponentAction {
33       override fun createCustomComponent(presentation: Presentation, place: String): JComponent =
34         object : ActionButtonWithText(this, presentation, place, JBUI.size(18)) {
35           override fun iconTextSpace() = JBUI.scale(2)
36
37           override fun updateToolTipText() {
38             val project = editor.project
39             if (Registry.`is`("ide.helptooltip.enabled") && project != null) {
40               HelpTooltip.dispose(this)
41               HelpTooltip()
42                 .setTitle(myPresentation.description)
43                 .setDescription(LangBundle.message("action.ReaderModeProvider.description"))
44                 .setLink(LangBundle.message("action.ReaderModeProvider.link.configure"))
45                 { ShowSettingsUtil.getInstance().showSettingsDialog(project, ReaderModeConfigurable::class.java) }
46                 .installOn(this)
47             }
48             else {
49               toolTipText = myPresentation.description
50             }
51           }
52
53           override fun getInsets(): Insets = JBUI.insets(2)
54           override fun getMargins(): Insets = if (myPresentation.icon == AllIcons.General.ReaderMode) JBUI.emptyInsets() else JBUI.insetsRight(5)
55
56           override fun updateUI() {
57             super.updateUI()
58             if (!SystemInfo.isWindows) {
59               font = FontUIResource(font.deriveFont(font.style, font.size - JBUIScale.scale(2).toFloat()))
60             }
61           }
62         }.
63         apply {
64           foreground = JBColor(NotNullProducer { editor.colorsScheme.getColor(FOREGROUND) ?: FOREGROUND.defaultColor })
65           if (!SystemInfo.isWindows) {
66             font = FontUIResource(font.deriveFont(font.style, font.size - JBUIScale.scale(2).toFloat()))
67           }
68         }
69
70       override fun actionPerformed(e: AnActionEvent) {
71         val project = e.project?: return
72
73         ReaderModeSettings.instance(project).enabled = !ReaderModeSettings.instance(project).enabled
74         project.messageBus.syncPublisher(READER_MODE_TOPIC).modeChanged(project)
75       }
76
77       override fun update(e: AnActionEvent) {
78         val project = editor.project?: return
79         val presentation = e.presentation
80
81         if (!ReaderModeSettings.instance(project).enabled) {
82           presentation.text = null
83           presentation.icon = AllIcons.General.ReaderMode
84           presentation.hoveredIcon = null
85           presentation.description = LangBundle.message("action.ReaderModeProvider.text.enter")
86         }
87         else {
88           presentation.text = LangBundle.message("action.ReaderModeProvider.text")
89           presentation.icon = EmptyIcon.ICON_16
90           presentation.hoveredIcon = AllIcons.Actions.CloseDarkGrey
91           presentation.description = LangBundle.message("action.ReaderModeProvider.text.exit")
92         }
93       }
94     }
95
96      return object : DefaultActionGroup(action, Separator.create()) {
97       override fun update(e: AnActionEvent) {
98         if (!Experiments.getInstance().isFeatureEnabled("editor.reader.mode")) {
99           e.presentation.isEnabledAndVisible = false
100         }
101         else {
102           val project = editor.project
103           if (project != null) {
104             val file = PsiDocumentManager.getInstance(project).getPsiFile(editor.document)?.virtualFile
105             e.presentation.isEnabledAndVisible = ReaderModeFileEditorListener.matchMode(project, file)
106           }
107           else {
108             e.presentation.isEnabledAndVisible = false
109           }
110         }
111       }
112     }
113   }
114
115   companion object {
116     val FOREGROUND = ColorKey.createColorKey("ActionButton.iconTextForeground", UIUtil.getContextHelpForeground())
117   }
118 }