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