[vcs-log] extract compare action to use in log

This commit is contained in:
Julia Beliaeva
2018-10-02 21:16:27 +03:00
parent ac3efaf27d
commit 790a1c558c
4 changed files with 85 additions and 32 deletions
@@ -42,7 +42,8 @@
<getDataRule key="Vcs.FileHistory.Ui" implementationClass="com.intellij.vcs.log.history.FileHistoryUiDataRule"/>
<diff.actions.ShowDiffAction.ExtensionProvider implementation="com.intellij.vcs.log.ui.actions.history.CompareRevisionsFromHistoryActionProvider"/>
<diff.actions.ShowDiffAction.ExtensionProvider
implementation="com.intellij.vcs.log.ui.actions.history.CompareRevisionsFromFolderHistoryActionProvider"/>
<diff.actions.ShowDiffAction.ExtensionProvider
implementation="com.intellij.vcs.log.ui.actions.history.CompareRevisionsFromFileHistoryActionProvider"/>
<openapi.vcs.history.actions.ShowDiffAfterWithLocalAction.ExtensionProvider implementation="com.intellij.vcs.log.ui.actions.history.ShowDiffAfterWithLocalFromHistoryActionProvider"/>
@@ -97,6 +98,9 @@
<action class="com.intellij.vcs.log.ui.actions.history.ShowAllAffectedFromHistoryAction" id="Vcs.Log.ShowAllAffected"
use-shortcut-of="VcsHistory.ShowAllAffected" icon="AllIcons.Actions.ListChanges" text="Show All Affected Files"
description="Show all changes made in the chosen revision"/>
<action class="com.intellij.vcs.log.ui.actions.CompareRevisionsFromLogAction" id="Vcs.Log.CompareRevisions"
text="Compare Versions" description="Compare selected versions"
icon="AllIcons.Actions.Diff"/>
<group id="Vcs.Log.PresentationSettings" class="com.intellij.vcs.log.ui.actions.VcsLogToolbarPopupActionGroup"
icon="AllIcons.Actions.Show" text="Presentation Settings" description="Presentation Settings" popup="true">
@@ -124,6 +128,7 @@
<group id="Vcs.Log.ContextMenu">
<reference id="Vcs.CopyRevisionNumberAction"/>
<reference id="ChangesView.CreatePatchFromChanges"/>
<reference id="Vcs.Log.CompareRevisions"/>
</group>
<group id="Vcs.Log.ChangesBrowser.Toolbar">
<reference id="Vcs.RepositoryChangesBrowserToolbar"/>
@@ -166,6 +171,7 @@
<group id="Log.KeymapGroup" text="Log">
<reference ref="ChangesView.CreatePatchFromChanges"/>
<reference ref="Vcs.Log.CompareRevisions"/>
<separator/>
<reference ref="Vcs.Log.GoToRef"/>
<reference ref="Vcs.Log.FocusTextFilter"/>
@@ -0,0 +1,47 @@
// Copyright 2000-2018 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 com.intellij.vcs.log.ui.actions
import com.intellij.openapi.actionSystem.AnActionEvent
import com.intellij.openapi.project.DumbAwareAction
import com.intellij.openapi.vcs.FilePath
import com.intellij.vcs.log.VcsLogDataKeys
import com.intellij.vcs.log.statistics.VcsLogUsageTriggerCollector
import com.intellij.vcs.log.ui.VcsLogInternalDataKeys
import com.intellij.vcsUtil.VcsUtil
open class CompareRevisionsFromLogAction : DumbAwareAction() {
protected open fun getFilePath(e: AnActionEvent): FilePath? {
val log = e.getData(VcsLogDataKeys.VCS_LOG) ?: return null
val selectedCommits = log.selectedCommits
if (selectedCommits.isEmpty() || selectedCommits.size > 2) return null
if (selectedCommits.first().root != selectedCommits.last().root) return null
return VcsUtil.getFilePath(selectedCommits.first().root)
}
override fun update(e: AnActionEvent) {
val log = e.getData(VcsLogDataKeys.VCS_LOG)
val handler = e.getData(VcsLogInternalDataKeys.LOG_DIFF_HANDLER)
val filePath = getFilePath(e)
if (log == null || filePath == null || handler == null) {
e.presentation.isEnabledAndVisible = false
return
}
e.presentation.isVisible = true
e.presentation.isEnabled = log.selectedCommits.size == 2
}
override fun actionPerformed(e: AnActionEvent) {
val log = e.getRequiredData(VcsLogDataKeys.VCS_LOG)
val handler = e.getRequiredData(VcsLogInternalDataKeys.LOG_DIFF_HANDLER)
val filePath = getFilePath(e)!!
VcsLogUsageTriggerCollector.triggerUsage(e)
val commits = log.selectedCommits
if (commits.size == 2) {
handler.showDiff(commits[1].root, filePath, commits[1].hash, filePath, commits[0].hash)
}
}
}
@@ -35,7 +35,7 @@ public class CompareRevisionsFromFileHistoryActionProvider implements AnActionEx
return;
}
CompareRevisionsFromHistoryActionProvider.updateActionText(e, log);
CompareRevisionsFromFolderHistoryActionProvider.updateActionText(e, log);
e.getPresentation().setVisible(true);
if (e.getInputEvent() instanceof KeyEvent) {
@@ -20,80 +20,80 @@ import com.intellij.openapi.actionSystem.AnActionExtensionProvider
import com.intellij.openapi.actionSystem.CommonDataKeys
import com.intellij.openapi.ui.MessageType
import com.intellij.openapi.util.Condition
import com.intellij.openapi.vcs.FilePath
import com.intellij.openapi.vcs.VcsDataKeys
import com.intellij.openapi.vcs.history.VcsDiffUtil
import com.intellij.openapi.vcs.ui.VcsBalloonProblemNotifier
import com.intellij.util.ObjectUtils.notNull
import com.intellij.util.containers.ContainerUtil
import com.intellij.vcs.log.VcsLog
import com.intellij.vcs.log.VcsLogDataKeys
import com.intellij.vcs.log.history.FileHistoryUtil
import com.intellij.vcs.log.ui.VcsLogInternalDataKeys
import com.intellij.vcs.log.statistics.VcsLogUsageTriggerCollector
import com.intellij.vcs.log.ui.VcsLogInternalDataKeys
import com.intellij.vcs.log.ui.actions.CompareRevisionsFromLogAction
import java.awt.event.KeyEvent
class CompareRevisionsFromHistoryActionProvider : AnActionExtensionProvider {
class CompareRevisionsFromFolderHistoryActionProvider : CompareRevisionsFromLogAction(), AnActionExtensionProvider {
override fun getFilePath(e: AnActionEvent): FilePath? {
return e.getData(VcsDataKeys.FILE_PATH)
}
override fun isActive(e: AnActionEvent): Boolean {
val filePath = e.getData(VcsDataKeys.FILE_PATH)
return e.getData(VcsLogInternalDataKeys.FILE_HISTORY_UI) != null && filePath != null && filePath.isDirectory
if (e.getData(VcsLogInternalDataKeys.FILE_HISTORY_UI) == null) return false
val filePath = getFilePath(e)
return filePath != null && filePath.isDirectory
}
override fun update(e: AnActionEvent) {
val project = e.project
val ui = e.getData(VcsLogInternalDataKeys.FILE_HISTORY_UI)
val filePath = e.getData(VcsDataKeys.FILE_PATH)
if (project == null || ui == null || filePath == null) {
val logData = e.getData(VcsLogInternalDataKeys.LOG_DATA)
val log = e.getData(VcsLogDataKeys.VCS_LOG)
val filePath = getFilePath(e)
if (log == null || project == null || logData == null || filePath == null) {
e.presentation.isEnabledAndVisible = false
return
}
e.presentation.isVisible = true
val log = ui.vcsLog
updateActionText(e, log)
e.presentation.isVisible = true
if (e.inputEvent is KeyEvent) {
e.presentation.isEnabled = true
return
}
val commits = log.selectedCommits
if (commits.size == 2) {
e.presentation.isEnabled = e.getData(VcsLogInternalDataKeys.LOG_DIFF_HANDLER) != null
if (log.selectedCommits.size >= 2) {
super.update(e)
}
else {
e.presentation.isEnabled = commits.size == 1
e.presentation.isEnabled = log.selectedCommits.isNotEmpty()
}
}
override fun actionPerformed(e: AnActionEvent) {
val project = e.getRequiredData(CommonDataKeys.PROJECT)
val ui = e.getRequiredData(VcsLogInternalDataKeys.FILE_HISTORY_UI)
val filePath = e.getRequiredData(VcsDataKeys.FILE_PATH)
val logData = e.getRequiredData(VcsLogInternalDataKeys.LOG_DATA)
val log = e.getRequiredData(VcsLogDataKeys.VCS_LOG)
val filePath = getFilePath(e)!!
VcsLogUsageTriggerCollector.triggerUsage(e)
val commits = ui.vcsLog.selectedCommits
if (commits.size == 2) {
val handler = e.getData(VcsLogInternalDataKeys.LOG_DIFF_HANDLER) ?: return
// this check is needed here since we may come on key event without performing proper checks
val newestId = commits[0]
val olderId = commits[1]
notNull(handler).showDiff(olderId.root, filePath, olderId.hash, filePath, newestId.hash)
val commits = log.selectedCommits
if (commits.size >= 2) {
super.actionPerformed(e)
return
}
if (commits.size != 1) return
val commitIds = ContainerUtil.map(commits) { c -> ui.logData.getCommitIndex(c.hash, c.root) }
ui.logData.commitDetailsGetter.loadCommitsData(commitIds, { details ->
val commitIds = ContainerUtil.map(commits) { c -> logData.getCommitIndex(c.hash, c.root) }
logData.commitDetailsGetter.loadCommitsData(commitIds, { details ->
val detail = notNull(ContainerUtil.getFirstItem(details))
val changes = FileHistoryUtil.collectRelevantChanges(detail,
Condition { change -> FileHistoryUtil.affectsDirectory(change, filePath) })
VcsDiffUtil.showChangesDialog(project, "Changes in " + detail.id.toShortString() + " for " + filePath.name,
ContainerUtil.newArrayList(changes))
}, { t -> VcsBalloonProblemNotifier.showOverChangesView(project, "Could not load selected commits: " + t.message, MessageType.ERROR) },
null)
null)
}
companion object {