// 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. package git4idea.index.actions import com.intellij.openapi.actionSystem.AnActionEvent import com.intellij.openapi.actionSystem.Presentation import com.intellij.openapi.project.Project import git4idea.conflicts.GitMergeHandler import git4idea.conflicts.acceptConflictSide import git4idea.conflicts.getConflictOperationLock import git4idea.conflicts.showMergeWindow import git4idea.i18n.GitBundle import git4idea.index.ui.* import git4idea.repo.GitConflict import org.jetbrains.annotations.Nls import java.util.function.Supplier import kotlin.streams.asSequence class GitAcceptTheirsAction : GitAcceptConflictSideAction(true) class GitAcceptYoursAction : GitAcceptConflictSideAction(false) abstract class GitConflictAction(text: Supplier<@Nls String>) : GitFileStatusNodeAction(text, Presentation.NULL_STRING, null) { override fun update(e: AnActionEvent) { val project = e.project val statusInfoStream = e.getData(GIT_FILE_STATUS_NODES_STREAM) if (project == null || statusInfoStream == null || !statusInfoStream.anyMatch(this::matches)) { e.presentation.isEnabledAndVisible = false return } e.presentation.isVisible = true e.presentation.isEnabled = isEnabled(project, e.getRequiredData(GIT_FILE_STATUS_NODES_STREAM).asSequence().mapNotNull { it.createConflict() }) } override fun matches(statusNode: GitFileStatusNode): Boolean = statusNode.kind == NodeKind.CONFLICTED override fun perform(project: Project, nodes: List) { perform(project, createMergeHandler(project), nodes.mapNotNull { it.createConflict() }) } protected open fun isEnabled(project: Project, conflicts: Sequence): Boolean { return conflicts.any { conflict -> !getConflictOperationLock(project, conflict).isLocked } } protected abstract fun perform(project: Project, handler: GitMergeHandler, conflicts: List) } abstract class GitAcceptConflictSideAction(private val takeTheirs: Boolean) : GitConflictAction(getActionText(takeTheirs)) { override fun perform(project: Project, handler: GitMergeHandler, conflicts: List) { acceptConflictSide(project, createMergeHandler(project), conflicts, takeTheirs, project::isReversedRoot) } } private fun getActionText(takeTheirs: Boolean): Supplier<@Nls String> { return if (takeTheirs) GitBundle.messagePointer("conflicts.accept.theirs.action.text") else GitBundle.messagePointer("conflicts.accept.yours.action.text") } class GitMergeConflictAction : GitConflictAction(GitBundle.messagePointer("action.Git.Merge.text")) { override fun isEnabled(project: Project, conflicts: Sequence): Boolean { val handler = createMergeHandler(project) return conflicts.any { conflict -> !getConflictOperationLock(project, conflict).isLocked && handler.canResolveConflict(conflict) } } override fun perform(project: Project, handler: GitMergeHandler, conflicts: List) { showMergeWindow(project, handler, conflicts, project::isReversedRoot) } }