[vcs] IJPL-173924 Operate BackendChangesView in ChangesViewCommitPanel

GitOrigin-RevId: 6f8540692734381792167207e22306155f1f5843
This commit is contained in:
Ilia.Shulgin
2025-10-20 19:19:33 +00:00
committed by intellij-monorepo-bot
parent 2d95b8520b
commit a212b24e51
3 changed files with 101 additions and 33 deletions
@@ -10,8 +10,10 @@ import com.intellij.openapi.project.Project
import com.intellij.openapi.util.Disposer
import com.intellij.openapi.vcs.FilePath
import com.intellij.openapi.vcs.changes.CommitChangesViewWithToolbarPanel.ModelProvider.ExtendedTreeModel
import com.intellij.openapi.vcs.changes.ui.ChangesBrowserNode.UNVERSIONED_FILES_TAG
import com.intellij.openapi.vcs.changes.ui.ChangesGroupingPolicyFactory
import com.intellij.openapi.vcs.changes.ui.ChangesListView
import com.intellij.openapi.vcs.changes.ui.VcsTreeModelData.*
import com.intellij.openapi.vfs.VirtualFile
import com.intellij.platform.kernel.ids.BackendValueIdType
import com.intellij.platform.kernel.ids.storeValueGlobally
@@ -21,6 +23,7 @@ import com.intellij.platform.vcs.impl.shared.changes.ChangesViewSettings
import com.intellij.ui.components.JBLabel
import com.intellij.ui.split.createComponent
import com.intellij.util.ui.tree.TreeUtil
import com.intellij.util.ui.tree.TreeUtil.*
import com.intellij.vcs.commit.ChangesViewCommitWorkflowHandler
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.cancel
@@ -40,10 +43,11 @@ internal class BackendChangesView private constructor(
if (RdLocalChanges.isEnabled()) {
val viewModel = BackendRemoteCommitChangesViewModel(project)
val id = storeValueGlobally(scope, viewModel, BackendChangesViewValueIdType)
val id = storeValueGlobally(scope, viewModel, BackendChangesViewValueIdType)
val panel = ChangesViewSplitComponentBinding.createComponent(project, scope, id)
return BackendChangesView(panel, viewModel)
} else {
}
else {
val panel = CommitChangesViewWithToolbarPanel(LocalChangesListView(project), scope)
val backendChangesView = BackendChangesView(panel, BackendLocalCommitChangesViewModel(panel))
val id = storeValueGlobally(scope, backendChangesView.viewModel, BackendChangesViewValueIdType)
@@ -74,11 +78,25 @@ internal interface BackendCommitChangesViewModel {
fun setGrouping(groupingKey: String)
fun resetViewImmediatelyAndRefreshLater()
fun setInclusionListener(listener: Runnable?)
var inclusionModel: InclusionModel?
fun setShowCheckboxes(value: Boolean)
fun getDisplayedChanges(): List<Change>
fun getIncludedChanges(): List<Change>
fun getDisplayedUnversionedFiles(): List<FilePath>
fun getIncludedUnversionedFiles(): List<FilePath>
fun expand(item: Any)
fun select(item: Any)
fun selectFirst(items: Collection<Any>)
fun selectFile(vFile: VirtualFile?)
fun selectChanges(changes: List<Change>)
@ApiStatus.Obsolete
fun getTree(): ChangesListView
@ApiStatus.Obsolete
fun getPreferredFocusableComponent(): JComponent
}
@@ -88,6 +106,8 @@ private class BackendRemoteCommitChangesViewModel(private val project: Project)
private var horizontal: Boolean = true
private val treeView: ChangesListView by lazy { LocalChangesListView(project) }
override var inclusionModel: InclusionModel? = null
override fun initPanel() {
}
@@ -118,6 +138,27 @@ private class BackendRemoteCommitChangesViewModel(private val project: Project)
override fun resetViewImmediatelyAndRefreshLater() {
}
override fun setInclusionListener(listener: Runnable?) {}
override fun setShowCheckboxes(value: Boolean) {}
override fun getDisplayedChanges(): List<Change> = emptyList()
override fun getIncludedChanges(): List<Change> = emptyList()
override fun getDisplayedUnversionedFiles(): List<FilePath> = emptyList()
override fun getIncludedUnversionedFiles(): List<FilePath> = emptyList()
override fun expand(item: Any) {
}
override fun select(item: Any) {
}
override fun selectFirst(items: Collection<Any>) {
}
override fun selectFile(vFile: VirtualFile?) {
}
@@ -129,9 +170,15 @@ private class BackendRemoteCommitChangesViewModel(private val project: Project)
override fun getPreferredFocusableComponent(): JComponent = treeView.preferredFocusedComponent
}
private class BackendLocalCommitChangesViewModel(private val panel: CommitChangesViewWithToolbarPanel): BackendCommitChangesViewModel {
private class BackendLocalCommitChangesViewModel(private val panel: CommitChangesViewWithToolbarPanel) : BackendCommitChangesViewModel {
private var commitWorkflowHandler: ChangesViewCommitWorkflowHandler? = null
override var inclusionModel: InclusionModel?
get() = panel.changesView.inclusionModel
set(value) {
panel.changesView.setInclusionModel(value)
}
override fun initPanel() {
panel.initPanel(ModelProvider())
}
@@ -168,6 +215,38 @@ private class BackendLocalCommitChangesViewModel(private val panel: CommitChange
panel.resetViewImmediatelyAndRefreshLater()
}
override fun setInclusionListener(listener: Runnable?) {
panel.changesView.setInclusionListener(listener)
}
override fun setShowCheckboxes(value: Boolean) {
panel.changesView.isShowCheckboxes = value
}
override fun getDisplayedChanges(): List<Change> = all(panel.changesView).userObjects(Change::class.java)
override fun getIncludedChanges(): List<Change> = included(panel.changesView).userObjects(Change::class.java)
override fun getDisplayedUnversionedFiles(): List<FilePath> = allUnderTag(panel.changesView, UNVERSIONED_FILES_TAG).userObjects(FilePath::class.java)
override fun getIncludedUnversionedFiles(): List<FilePath> = includedUnderTag(panel.changesView, UNVERSIONED_FILES_TAG).userObjects(FilePath::class.java)
override fun expand(item: Any) {
val node = panel.changesView.findNodeInTree(item)
node?.let { panel.changesView.expandSafe(it) }
}
override fun select(item: Any) {
val path = panel.changesView.findNodePathInTree(item)
path?.let { selectPath(panel.changesView, it, false) }
}
override fun selectFirst(items: Collection<Any>) {
if (items.isEmpty()) return
val path = treePathTraverser(panel.changesView).preOrderDfsTraversal().find { getLastUserObject(it) in items }
path?.let { selectPath(panel.changesView, it, false) }
}
override fun selectFile(vFile: VirtualFile?) {
panel.changesView.selectFile(vFile)
}
@@ -42,7 +42,7 @@ internal class ChangesViewWorkflowManagerImpl(
// ChangesViewPanel can be reused between workflow instances -> should clean up after ourselves
val changesView = (ChangesViewManager.getInstance(project) as ChangesViewManager).initChangesView()
val workflow = ChangesViewCommitWorkflow(project)
val commitPanel = ChangesViewCommitPanel(project, changesView.viewModel.getTree())
val commitPanel = ChangesViewCommitPanel(project, changesView)
_commitWorkflowHandler = ChangesViewCommitWorkflowHandler(workflow, commitPanel)
project.messageBus.syncPublisher(TOPIC).commitWorkflowChanged()
@@ -8,28 +8,22 @@ import com.intellij.openapi.project.Project
import com.intellij.openapi.util.Disposer
import com.intellij.openapi.vcs.FilePath
import com.intellij.openapi.vcs.VcsBundle.message
import com.intellij.openapi.vcs.changes.Change
import com.intellij.openapi.vcs.changes.ChangesViewManager
import com.intellij.openapi.vcs.changes.InclusionModel
import com.intellij.openapi.vcs.changes.LocalChangeList
import com.intellij.openapi.vcs.changes.*
import com.intellij.openapi.vcs.changes.ui.*
import com.intellij.openapi.vcs.changes.ui.ChangesBrowserNode.UNVERSIONED_FILES_TAG
import com.intellij.openapi.vcs.changes.ui.ChangesViewContentManager.Companion.LOCAL_CHANGES
import com.intellij.openapi.vcs.changes.ui.ChangesViewContentManager.Companion.getToolWindowFor
import com.intellij.openapi.vcs.changes.ui.VcsTreeModelData.*
import com.intellij.openapi.wm.ToolWindow
import com.intellij.platform.vcs.impl.shared.commit.EditedCommitPresentation
import com.intellij.util.application
import com.intellij.util.ui.UIUtil
import com.intellij.util.ui.tree.TreeUtil.*
import kotlinx.coroutines.CompletableDeferred
import org.jetbrains.annotations.ApiStatus
import javax.swing.JComponent
import kotlin.properties.Delegates.observable
class ChangesViewCommitPanel @ApiStatus.Internal constructor(
class ChangesViewCommitPanel internal constructor(
project: Project,
private val changesView: ChangesListView,
private val changesView: BackendChangesView,
) : NonModalCommitPanel(project), ChangesViewCommitWorkflowUi {
private var isHideToolWindowOnCommit = false
@@ -49,10 +43,10 @@ class ChangesViewCommitPanel @ApiStatus.Internal constructor(
support.installSearch(commitMessage.editorField, commitMessage.editorField)
}
changesView.setInclusionListener {
changesView.viewModel.setInclusionListener {
WriteIntentReadAction.run { fireInclusionChanged() }
}
changesView.isShowCheckboxes = true
changesView.viewModel.setShowCheckboxes(true)
commitActionsPanel.isCommitButtonDefault = {
!progressPanel.isDumbMode && UIUtil.isFocusAncestor(rootComponent ?: component)
@@ -77,39 +71,34 @@ class ChangesViewCommitPanel @ApiStatus.Internal constructor(
}
override fun expand(item: Any) {
val node = changesView.findNodeInTree(item)
node?.let { changesView.expandSafe(it) }
changesView.viewModel.expand(item)
}
override fun select(item: Any) {
val path = changesView.findNodePathInTree(item)
path?.let { selectPath(changesView, it, false) }
changesView.viewModel.select(item)
}
override fun selectFirst(items: Collection<Any>) {
if (items.isEmpty()) return
val path = treePathTraverser(changesView).preOrderDfsTraversal().find { getLastUserObject(it) in items }
path?.let { selectPath(changesView, it, false) }
changesView.viewModel.selectFirst(items)
}
override fun setCompletionContext(changeLists: List<LocalChangeList>) {
commitMessage.setChangesSupplier(ChangeListChangesSupplier(changeLists))
}
override fun getDisplayedChanges(): List<Change> = all(changesView).userObjects(Change::class.java)
override fun getIncludedChanges(): List<Change> = included(changesView).userObjects(Change::class.java)
override fun getDisplayedChanges(): List<Change> = changesView.viewModel.getDisplayedChanges()
override fun getIncludedChanges(): List<Change> = changesView.viewModel.getIncludedChanges()
override fun getDisplayedUnversionedFiles(): List<FilePath> =
allUnderTag(changesView, UNVERSIONED_FILES_TAG).userObjects(FilePath::class.java)
changesView.viewModel.getDisplayedUnversionedFiles()
override fun getIncludedUnversionedFiles(): List<FilePath> =
includedUnderTag(changesView, UNVERSIONED_FILES_TAG).userObjects(FilePath::class.java)
changesView.viewModel.getIncludedUnversionedFiles()
override var inclusionModel: InclusionModel?
get() = changesView.inclusionModel
get() = changesView.viewModel.inclusionModel
set(value) {
changesView.setInclusionModel(value)
changesView.viewModel.inclusionModel = value
}
override val commitProgressUi: CommitProgressUi get() = progressPanel
@@ -127,8 +116,8 @@ class ChangesViewCommitPanel @ApiStatus.Internal constructor(
override fun dispose() {
super.dispose()
changesView.isShowCheckboxes = false
changesView.setInclusionListener(null)
changesView.viewModel.setShowCheckboxes(false)
changesView.viewModel.setInclusionListener(null)
}
override fun activate(): Boolean {
@@ -136,7 +125,7 @@ class ChangesViewCommitPanel @ApiStatus.Internal constructor(
val contentManager = ChangesViewContentManager.getInstance(project)
saveToolWindowState()
changesView.isShowCheckboxes = true
changesView.viewModel.setShowCheckboxes(true)
component.isVisible = true
commitActionsPanel.isActive = true
@@ -153,7 +142,7 @@ class ChangesViewCommitPanel @ApiStatus.Internal constructor(
}
clearToolWindowState()
changesView.isShowCheckboxes = false
changesView.viewModel.setShowCheckboxes(false)
component.isVisible = false
commitActionsPanel.isActive = false