[git-index] rename GitAcceptConflictSideAction file to GitConflictActions
[idea/community.git] / plugins / git4idea / src / git4idea / index / actions / GitConflictActions.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 git4idea.index.actions
3
4 import com.intellij.openapi.actionSystem.AnActionEvent
5 import com.intellij.openapi.actionSystem.Presentation
6 import com.intellij.openapi.project.Project
7 import git4idea.conflicts.GitMergeHandler
8 import git4idea.conflicts.acceptConflictSide
9 import git4idea.conflicts.getConflictOperationLock
10 import git4idea.conflicts.showMergeWindow
11 import git4idea.i18n.GitBundle
12 import git4idea.index.ui.*
13 import git4idea.repo.GitConflict
14 import org.jetbrains.annotations.Nls
15 import java.util.function.Supplier
16 import kotlin.streams.asSequence
17
18 class GitAcceptTheirsAction : GitAcceptConflictSideAction(true)
19 class GitAcceptYoursAction : GitAcceptConflictSideAction(false)
20
21 abstract class GitConflictAction(text: Supplier<@Nls String>) :
22   GitFileStatusNodeAction(text, Presentation.NULL_STRING, null) {
23
24   override fun update(e: AnActionEvent) {
25     val project = e.project
26     val statusInfoStream = e.getData(GIT_FILE_STATUS_NODES_STREAM)
27     if (project == null || statusInfoStream == null || !statusInfoStream.anyMatch(this::matches)) {
28       e.presentation.isEnabledAndVisible = false
29       return
30     }
31
32     e.presentation.isVisible = true
33     e.presentation.isEnabled = isEnabled(project,
34                                          e.getRequiredData(GIT_FILE_STATUS_NODES_STREAM).asSequence().mapNotNull { it.createConflict() })
35   }
36
37   override fun matches(statusNode: GitFileStatusNode): Boolean = statusNode.kind == NodeKind.CONFLICTED
38
39   override fun perform(project: Project, nodes: List<GitFileStatusNode>) {
40     perform(project, createMergeHandler(project), nodes.mapNotNull { it.createConflict() })
41   }
42
43   protected open fun isEnabled(project: Project, conflicts: Sequence<GitConflict>): Boolean {
44     return conflicts.any { conflict -> !getConflictOperationLock(project, conflict).isLocked }
45   }
46
47   protected abstract fun perform(project: Project, handler: GitMergeHandler, conflicts: List<GitConflict>)
48 }
49
50 abstract class GitAcceptConflictSideAction(private val takeTheirs: Boolean) : GitConflictAction(getActionText(takeTheirs)) {
51   override fun perform(project: Project, handler: GitMergeHandler, conflicts: List<GitConflict>) {
52     acceptConflictSide(project, createMergeHandler(project), conflicts, takeTheirs, project::isReversedRoot)
53   }
54 }
55
56 private fun getActionText(takeTheirs: Boolean): Supplier<@Nls String> {
57   return if (takeTheirs) GitBundle.messagePointer("conflicts.accept.theirs.action.text")
58   else GitBundle.messagePointer("conflicts.accept.yours.action.text")
59 }
60
61 class GitMergeConflictAction : GitConflictAction(GitBundle.messagePointer("action.Git.Merge.text")) {
62
63   override fun isEnabled(project: Project, conflicts: Sequence<GitConflict>): Boolean {
64     val handler = createMergeHandler(project)
65     return conflicts.any { conflict ->
66       !getConflictOperationLock(project, conflict).isLocked && handler.canResolveConflict(conflict)
67     }
68   }
69
70   override fun perform(project: Project, handler: GitMergeHandler, conflicts: List<GitConflict>) {
71     showMergeWindow(project, handler, conflicts, project::isReversedRoot)
72   }
73 }