vcs: non-modal: Move "Amend" checkbox and commit toolbar actions above commit message...
[idea/community.git] / platform / vcs-impl / src / com / intellij / vcs / commit / ChangesViewCommitStatusPanel.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.vcs.commit
3
4 import com.intellij.openapi.project.Project
5 import com.intellij.openapi.util.Disposer
6 import com.intellij.openapi.util.registry.Registry
7 import com.intellij.openapi.util.registry.RegistryValue
8 import com.intellij.openapi.util.registry.RegistryValueListener
9 import com.intellij.openapi.vcs.VcsBundle.message
10 import com.intellij.openapi.vcs.changes.InclusionListener
11 import com.intellij.openapi.vcs.changes.ui.*
12 import com.intellij.openapi.vcs.changes.ui.ChangesViewContentManager.Companion.LOCAL_CHANGES
13 import com.intellij.ui.content.Content
14 import com.intellij.util.ui.JBUI.Borders.empty
15 import com.intellij.util.ui.JBUI.Borders.emptyRight
16 import com.intellij.util.ui.JBUI.emptyInsets
17 import com.intellij.util.ui.components.BorderLayoutPanel
18
19 private val isCompactCommitLegend get() = Registry.get("vcs.non.modal.commit.legend.compact")
20
21 private fun Project.getLocalChangesTab(): Content? =
22   ChangesViewContentManager.getInstance(this).findContents { it.tabName == LOCAL_CHANGES }.firstOrNull()
23
24 internal class ChangesViewCommitStatusPanel(tree: ChangesTree, private val commitWorkflowUi: CommitWorkflowUi) :
25   BorderLayoutPanel(), ChangesViewContentManagerListener, InclusionListener {
26
27   private val branchComponent = CurrentBranchComponent(tree.project, tree, commitWorkflowUi)
28
29   private val commitLegendCalculator = ChangeInfoCalculator()
30   private val commitLegend = CommitLegendPanel(commitLegendCalculator).apply {
31     component.myBorder = empty(0, 1)
32     component.ipad = emptyInsets()
33   }
34
35   private val project get() = branchComponent.project
36
37   init {
38     setupLegend()
39
40     addToRight(commitLegend.component)
41     border = emptyRight(6)
42     background = tree.background
43
44     commitWorkflowUi.addInclusionListener(this, commitWorkflowUi)
45     setupTabUpdater()
46   }
47
48   private fun setupTabUpdater() {
49     branchComponent.addChangeListener(this::updateTab, commitWorkflowUi)
50     project.messageBus.connect(commitWorkflowUi).subscribe(ChangesViewContentManagerListener.TOPIC, this)
51
52     Disposer.register(commitWorkflowUi) {
53       val tab = project.getLocalChangesTab() ?: return@register
54
55       tab.displayName = message("local.changes.tab")
56       tab.description = null
57     }
58   }
59
60   override fun toolWindowMappingChanged() = updateTab()
61
62   private fun updateTab() {
63     if (!project.isCommitToolWindow) return
64     val tab = project.getLocalChangesTab() ?: return
65
66     val branch = branchComponent.text
67     tab.displayName = if (branch?.isBlank() == true) message("tab.title.commit") else message("tab.title.commit.to.branch", branch)
68     tab.description = branchComponent.toolTipText
69   }
70
71   override fun inclusionChanged() = updateLegend()
72
73   private fun setupLegend() {
74     setLegendCompact()
75     isCompactCommitLegend.addListener(object : RegistryValueListener {
76       override fun afterValueChanged(value: RegistryValue) = setLegendCompact()
77     }, commitWorkflowUi)
78   }
79
80   private fun setLegendCompact() {
81     commitLegend.isCompact = isCompactCommitLegend.asBoolean()
82   }
83
84   private fun updateLegend() {
85     // Displayed changes and unversioned files are not actually used in legend - so we don't pass them
86     commitLegendCalculator.update(
87       includedChanges = commitWorkflowUi.getIncludedChanges(),
88       includedUnversionedFilesCount = commitWorkflowUi.getIncludedUnversionedFiles().size
89     )
90     commitLegend.update()
91   }
92 }