diff --git a/platform/vcs-impl/api-dump.txt b/platform/vcs-impl/api-dump.txt index 0000291ee9fe..083b314282f1 100644 --- a/platform/vcs-impl/api-dump.txt +++ b/platform/vcs-impl/api-dump.txt @@ -3955,11 +3955,27 @@ a:com.intellij.vcs.commit.ChangeListViewCommitPanel - f:setEditedCommit(com.intellij.platform.vcs.impl.shared.commit.EditedCommitPresentation):V - f:setInclusionModel(com.intellij.openapi.vcs.changes.InclusionModel):V f:com.intellij.vcs.commit.ChangesViewCommitPanel -- com.intellij.vcs.commit.ChangeListViewCommitPanel +- com.intellij.vcs.commit.NonModalCommitPanel +- com.intellij.vcs.commit.ChangesViewCommitWorkflowUi - activate():Z - deactivate(Z):V +- dispose():V +- endExecution():V +- expand(java.lang.Object):V +- getCommitProgressUi():com.intellij.vcs.commit.CommitProgressUi +- getDisplayedChanges():java.util.List +- getDisplayedUnversionedFiles():java.util.List +- getEditedCommit():com.intellij.platform.vcs.impl.shared.commit.EditedCommitPresentation +- getIncludedChanges():java.util.List +- getIncludedUnversionedFiles():java.util.List +- getInclusionModel():com.intellij.openapi.vcs.changes.InclusionModel - isActive():Z - refreshChangesViewBeforeCommit(kotlin.coroutines.Continuation):java.lang.Object +- select(java.lang.Object):V +- selectFirst(java.util.Collection):V +- setCompletionContext(java.util.List):V +- setEditedCommit(com.intellij.platform.vcs.impl.shared.commit.EditedCommitPresentation):V +- setInclusionModel(com.intellij.openapi.vcs.changes.InclusionModel):V com.intellij.vcs.commit.ChangesViewCommitWorkflowUi - com.intellij.vcs.commit.NonModalCommitWorkflowUi - a:deactivate(Z):V diff --git a/platform/vcs-impl/src/com/intellij/vcs/commit/ChangeListViewCommitPanel.kt b/platform/vcs-impl/src/com/intellij/vcs/commit/ChangeListViewCommitPanel.kt index f41cc07cb1d7..a8c78e117c21 100644 --- a/platform/vcs-impl/src/com/intellij/vcs/commit/ChangeListViewCommitPanel.kt +++ b/platform/vcs-impl/src/com/intellij/vcs/commit/ChangeListViewCommitPanel.kt @@ -123,7 +123,7 @@ abstract class ChangeListViewCommitPanel @ApiStatus.Internal constructor( } } -private class ChangeListViewCommitProgressPanel( +internal class ChangeListViewCommitProgressPanel( project: Project, private val commitWorkflowUi: ChangesViewCommitWorkflowUi, commitMessage: EditorTextComponent, diff --git a/platform/vcs-impl/src/com/intellij/vcs/commit/ChangesViewCommitPanel.kt b/platform/vcs-impl/src/com/intellij/vcs/commit/ChangesViewCommitPanel.kt index 364e952ff184..58ce7b1228f7 100644 --- a/platform/vcs-impl/src/com/intellij/vcs/commit/ChangesViewCommitPanel.kt +++ b/platform/vcs-impl/src/com/intellij/vcs/commit/ChangesViewCommitPanel.kt @@ -2,33 +2,135 @@ package com.intellij.vcs.commit import com.intellij.openapi.Disposable +import com.intellij.openapi.application.WriteIntentReadAction +import com.intellij.openapi.diagnostic.logger 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.ui.ChangesListView -import com.intellij.openapi.vcs.changes.ui.ChangesViewContentManager +import com.intellij.openapi.vcs.changes.InclusionModel +import com.intellij.openapi.vcs.changes.LocalChangeList +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.ChangesViewContentManagerListener -import com.intellij.openapi.vcs.changes.ui.isCommitToolWindowShown +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( project: Project, private val changesView: ChangesListView, -) : ChangeListViewCommitPanel(project, changesView) { +) : NonModalCommitPanel(project), ChangesViewCommitWorkflowUi { private var isHideToolWindowOnCommit = false + private val progressPanel = ChangeListViewCommitProgressPanel(project, this, commitMessage.editorField) + private val commitActions = commitActionsPanel.createActions() + private var rootComponent: JComponent? = null + init { val titleUpdater = ChangesViewCommitTabTitleUpdater(project) titleUpdater.initSubscription(this) titleUpdater.updateTitle() + + Disposer.register(this, commitMessage) + setProgressComponent(progressPanel) + + for (support in EditChangelistSupport.EP_NAME.getExtensionList(project)) { + support.installSearch(commitMessage.editorField, commitMessage.editorField) + } + + changesView.setInclusionListener { + WriteIntentReadAction.run { fireInclusionChanged() } + } + changesView.isShowCheckboxes = true + + commitActionsPanel.isCommitButtonDefault = { + !progressPanel.isDumbMode && UIUtil.isFocusAncestor(rootComponent ?: component) + } + + ChangesViewCommitTabTitleUpdater(project).initSubscription(this) } override val isActive: Boolean get() = component.isVisible + @ApiStatus.Internal + fun registerRootComponent(newRootComponent: JComponent) { + logger().assertTrue(rootComponent == null) + rootComponent = newRootComponent + commitActions.forEach { it.registerCustomShortcutSet(newRootComponent, this) } + } + + override var editedCommit: EditedCommitPresentation? by observable(null) { _, _, newValue -> + ChangesViewManager.getInstanceEx(project).scheduleRefresh { + application.invokeLater { newValue?.let { expand(it) } } + } + } + + override fun expand(item: Any) { + val node = changesView.findNodeInTree(item) + node?.let { changesView.expandSafe(it) } + } + + override fun select(item: Any) { + val path = changesView.findNodePathInTree(item) + path?.let { selectPath(changesView, it, false) } + } + + override fun selectFirst(items: Collection) { + if (items.isEmpty()) return + + val path = treePathTraverser(changesView).preOrderDfsTraversal().find { getLastUserObject(it) in items } + path?.let { selectPath(changesView, it, false) } + } + + override fun setCompletionContext(changeLists: List) { + commitMessage.setChangesSupplier(ChangeListChangesSupplier(changeLists)) + } + + override fun getDisplayedChanges(): List = all(changesView).userObjects(Change::class.java) + override fun getIncludedChanges(): List = included(changesView).userObjects(Change::class.java) + + override fun getDisplayedUnversionedFiles(): List = + allUnderTag(changesView, UNVERSIONED_FILES_TAG).userObjects(FilePath::class.java) + + override fun getIncludedUnversionedFiles(): List = + includedUnderTag(changesView, UNVERSIONED_FILES_TAG).userObjects(FilePath::class.java) + + override var inclusionModel: InclusionModel? + get() = changesView.inclusionModel + set(value) { + changesView.setInclusionModel(value) + } + + override val commitProgressUi: CommitProgressUi get() = progressPanel + + override fun endExecution(): Unit = closeEditorPreviewIfEmpty() + + private fun closeEditorPreviewIfEmpty() { + val changesViewManager = ChangesViewManager.getInstance(project) as? ChangesViewManager ?: return + ChangesViewManager.getInstanceEx(project).scheduleRefresh { + application.invokeLater { + changesViewManager.closeEditorPreview(true) + } + } + } + + override fun dispose() { + super.dispose() + changesView.isShowCheckboxes = false + changesView.setInclusionListener(null) + } + override fun activate(): Boolean { val toolWindow = getVcsToolWindow() ?: return false val contentManager = ChangesViewContentManager.getInstance(project) @@ -94,8 +196,7 @@ private class ChangesViewCommitTabTitleUpdater(private val project: Project) : C tabContent.displayName = when { contentsCount == 1 -> null project.isCommitToolWindowShown -> message("tab.title.commit") - else -> message("local.changes.tab") - } - } + else ->message("local.changes.tab") + }} } }