vcs: Show "Commit" tool window on explicit action for projects without vcs mappings...
[idea/community.git] / platform / vcs-impl / src / com / intellij / openapi / vcs / changes / ui / VcsToolWindowEmptyState.kt
1 // Copyright 2000-2021 JetBrains s.r.o. and contributors. 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.openapi.vcs.changes.ui
3
4 import com.intellij.icons.AllIcons
5 import com.intellij.ide.IdeBundle
6 import com.intellij.ide.actions.ActivateToolWindowAction
7 import com.intellij.openapi.actionSystem.*
8 import com.intellij.openapi.actionSystem.CommonDataKeys.PROJECT
9 import com.intellij.openapi.actionSystem.CommonDataKeys.VIRTUAL_FILE
10 import com.intellij.openapi.actionSystem.IdeActions.ACTION_CONTEXT_HELP
11 import com.intellij.openapi.actionSystem.PlatformCoreDataKeys.HELP_ID
12 import com.intellij.openapi.actionSystem.ex.ActionUtil.invokeAction
13 import com.intellij.openapi.actionSystem.impl.SimpleDataContext
14 import com.intellij.openapi.project.Project
15 import com.intellij.openapi.project.guessProjectDir
16 import com.intellij.openapi.vcs.VcsBundle.message
17 import com.intellij.openapi.wm.ToolWindow
18 import com.intellij.openapi.wm.ToolWindowId
19 import com.intellij.openapi.wm.impl.content.ToolWindowContentUi
20 import com.intellij.openapi.wm.impl.content.ToolWindowContentUi.HIDE_ID_LABEL
21 import com.intellij.ui.SimpleTextAttributes.LINK_PLAIN_ATTRIBUTES
22 import com.intellij.ui.content.ContentManager
23 import com.intellij.ui.content.ContentManagerEvent
24 import com.intellij.ui.content.ContentManagerListener
25 import com.intellij.ui.content.impl.ContentManagerImpl
26 import com.intellij.util.ui.StatusText
27 import java.awt.event.InputEvent
28
29 private const val ACTION_LOCAL_HISTORY = "LocalHistory.ShowHistory"
30
31 internal fun StatusText.setChangesViewEmptyState(project: Project) {
32   appendLine(message("status.text.vcs.toolwindow"))
33   findCreateRepositoryAction()?.let { action ->
34     appendLine(message("status.text.vcs.toolwindow.create.repository"), LINK_PLAIN_ATTRIBUTES) {
35       invokeAction(project, it.source, action)
36     }
37   }
38   appendLine(message("status.text.vcs.toolwindow.local.history"), LINK_PLAIN_ATTRIBUTES) {
39     invokeAction(project, it.source, ACTION_LOCAL_HISTORY)
40   }
41   appendLine("")
42   appendLine(AllIcons.General.ContextHelp, message("status.text.vcs.toolwindow.help"), LINK_PLAIN_ATTRIBUTES) {
43     invokeAction(project, it.source, ACTION_CONTEXT_HELP)
44   }
45 }
46
47 internal fun StatusText.setCommitViewEmptyState(project: Project) {
48   findCreateRepositoryAction()?.let { action ->
49     appendLine(message("status.text.commit.toolwindow.create.repository.prefix"))
50       .appendText(" ")
51       .appendText(message("status.text.commit.toolwindow.create.repository"), LINK_PLAIN_ATTRIBUTES) {
52         invokeAction(project, it.source, action)
53       }
54   }
55   appendLine(message("status.text.commit.toolwindow.local.history.prefix"))
56     .appendText(" ")
57     .appendText(message("status.text.commit.toolwindow.local.history"), LINK_PLAIN_ATTRIBUTES) {
58       invokeAction(project, it.source, ACTION_LOCAL_HISTORY)
59     }
60   appendLine("")
61   appendLine(AllIcons.General.ContextHelp, message("status.text.vcs.toolwindow.help"), LINK_PLAIN_ATTRIBUTES) {
62     invokeAction(project, it.source, ACTION_CONTEXT_HELP)
63   }
64 }
65
66 internal class ActivateCommitToolWindowAction : ActivateToolWindowAction(ToolWindowId.COMMIT) {
67   init {
68     templatePresentation.setText(IdeBundle.messagePointer("toolwindow.stripe.Commit"))
69     templatePresentation.icon = AllIcons.Toolwindows.ToolWindowCommit
70   }
71
72   override fun hasEmptyState(): Boolean = true
73 }
74
75 private fun findCreateRepositoryAction(): AnAction? {
76   val group = ActionManager.getInstance().getAction("Vcs.ToolWindow.CreateRepository") as? ActionGroup
77   return group?.getChildren(null)?.firstOrNull()
78 }
79
80 private fun invokeAction(project: Project, source: Any?, actionId: String) {
81   val action = ActionManager.getInstance().getAction(actionId) ?: return
82   invokeAction(project, source, action)
83 }
84
85 private fun invokeAction(project: Project, source: Any?, action: AnAction) =
86   invokeAction(action, createDataContext(project), ActionPlaces.UNKNOWN, source as? InputEvent, null)
87
88 private fun createDataContext(project: Project): DataContext =
89   SimpleDataContext.builder()
90     .add(PROJECT, project)
91     .add(VIRTUAL_FILE, project.guessProjectDir())
92     .add(HELP_ID, "version.control.empty.state")
93     .build()
94
95
96 internal fun ToolWindow.hideIdLabelIfNotEmptyState() =
97   contentManager.addContentManagerListener(object : ContentManagerListener {
98     override fun contentAdded(event: ContentManagerEvent) {
99       if (contentManager.contentCount != 1) return
100
101       component.putClientProperty(HIDE_ID_LABEL, "true")
102       contentManager.updateContentUi()
103     }
104
105     override fun contentRemoved(event: ContentManagerEvent) {
106       if (!contentManager.isEmpty) return
107
108       component.putClientProperty(HIDE_ID_LABEL, null)
109       contentManager.updateContentUi()
110     }
111   })
112
113 private fun ContentManager.updateContentUi() {
114   if (this !is ContentManagerImpl) return
115
116   (ui as? ToolWindowContentUi)?.update()
117 }