vcs: Refactor "committed changes"-related actions

GitOrigin-RevId: 83b4df5a0f5ae5c87ed3e6b8b5ed619b66a2cd06
This commit is contained in:
Konstantin Kolosovsky
2019-12-21 19:41:55 +00:00
committed by intellij-monorepo-bot
parent 36c68935b9
commit aa831c44e3
8 changed files with 173 additions and 257 deletions
@@ -1,103 +1,80 @@
// Copyright 2000-2019 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.openapi.vcs.changes.committed;
package com.intellij.openapi.vcs.changes.committed
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.CommonDataKeys;
import com.intellij.openapi.actionSystem.Presentation;
import com.intellij.openapi.components.ServiceKt;
import com.intellij.openapi.project.DumbAware;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.MessageType;
import com.intellij.openapi.vcs.AbstractVcs;
import com.intellij.openapi.vcs.AbstractVcsHelper;
import com.intellij.openapi.vcs.CommittedChangesProvider;
import com.intellij.openapi.vcs.RepositoryLocation;
import com.intellij.openapi.vcs.versionBrowser.ChangeBrowserSettings;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.vcsUtil.VcsUtil;
import org.jetbrains.annotations.NotNull;
import com.intellij.CommonBundle.getCancelButtonText
import com.intellij.openapi.actionSystem.AnActionEvent
import com.intellij.openapi.actionSystem.CommonDataKeys.VIRTUAL_FILE
import com.intellij.openapi.components.stateStore
import com.intellij.openapi.project.DumbAwareAction
import com.intellij.openapi.project.Project
import com.intellij.openapi.ui.MessageType
import com.intellij.openapi.ui.Messages
import com.intellij.openapi.ui.Messages.getQuestionIcon
import com.intellij.openapi.ui.Messages.showYesNoCancelDialog
import com.intellij.openapi.vcs.AbstractVcs
import com.intellij.openapi.vcs.AbstractVcs.fileInVcsByFileStatus
import com.intellij.openapi.vcs.AbstractVcsHelper
import com.intellij.openapi.vcs.VcsBundle.message
import com.intellij.openapi.vcs.changes.ChangesUtil.getVcsForFile
import com.intellij.openapi.vcs.changes.committed.CommittedChangesViewManager.Companion.isCommittedChangesAvailable
import com.intellij.openapi.vcs.ui.VcsBalloonProblemNotifier.showOverVersionControlView
import com.intellij.openapi.vcs.versionBrowser.ChangeBrowserSettings
import com.intellij.openapi.vfs.VirtualFile
import com.intellij.vcsUtil.VcsUtil.getFilePath
import static com.intellij.CommonBundle.getCancelButtonText;
import static com.intellij.openapi.ui.Messages.*;
import static com.intellij.openapi.vcs.AbstractVcs.fileInVcsByFileStatus;
import static com.intellij.openapi.vcs.VcsBundle.message;
import static com.intellij.openapi.vcs.changes.ChangesUtil.getVcsForFile;
import static com.intellij.openapi.vcs.ui.VcsBalloonProblemNotifier.showOverVersionControlView;
import static com.intellij.util.ObjectUtils.notNull;
class BrowseCommittedChangesAction : DumbAwareAction() {
override fun update(e: AnActionEvent) {
e.presentation.isEnabledAndVisible = false
public class BrowseCommittedChangesAction extends AnAction implements DumbAware {
@Override
public void actionPerformed(@NotNull AnActionEvent e) {
Project project = e.getRequiredData(CommonDataKeys.PROJECT);
VirtualFile file = e.getRequiredData(CommonDataKeys.VIRTUAL_FILE);
AbstractVcs vcs = notNull(getVcsForFile(file, project));
CommittedChangesProvider provider = notNull(vcs.getCommittedChangesProvider());
ChangeBrowserSettings settings = getChangeBrowserSettings(project, vcs, provider);
CommittedChangesFilterDialog dialog = new CommittedChangesFilterDialog(project, provider.createFilterUI(true), settings);
val project = e.project ?: return
val file = e.getData(VIRTUAL_FILE) ?: return
val vcs = getVcsForFile(file, project) ?: return
if (!isCommittedChangesAvailable(vcs)) return
if (dialog.showAndGet()) {
showChanges(vcs, provider, file, settings);
e.presentation.isVisible = true
e.presentation.isEnabled = vcs.allowsRemoteCalls(file) && fileInVcsByFileStatus(vcs.project, file)
}
override fun actionPerformed(e: AnActionEvent) {
val project = e.project!!
val file = e.getData(VIRTUAL_FILE)!!
val vcs = getVcsForFile(file, project)!!
val settings = getChangeBrowserSettings(vcs)
if (CommittedChangesFilterDialog(project, vcs.committedChangesProvider!!.createFilterUI(true), settings).showAndGet()) {
showCommittedChanges(vcs, file, settings)
}
}
}
private fun getChangeBrowserSettings(vcs: AbstractVcs): ChangeBrowserSettings =
vcs.configuration.changeBrowserSettings.computeIfAbsent(vcs.name) { vcsName ->
vcs.committedChangesProvider!!.createDefaultSettings().also {
vcs.project.stateStore.initPersistencePlainComponent(it, "VcsManager.ChangeBrowser.$vcsName")
}
}
private static ChangeBrowserSettings getChangeBrowserSettings(@NotNull Project project, @NotNull AbstractVcs vcs, @NotNull CommittedChangesProvider provider) {
return vcs.getConfiguration().changeBrowserSettings.computeIfAbsent(vcs.getName(), key -> {
ChangeBrowserSettings result = provider.createDefaultSettings();
ServiceKt.getStateStore(project).initPersistencePlainComponent(result, "VcsManager.ChangeBrowser." + key);
return result;
});
private fun showCommittedChanges(vcs: AbstractVcs, file: VirtualFile, settings: ChangeBrowserSettings) {
val maxCount = if (!settings.isAnyFilterSpecified) askMaxCount(vcs.project) else 0
if (maxCount < 0) return
val repositoryLocation = CommittedChangesCache.getInstance(vcs.project).locationCache.getLocation(vcs, getFilePath(file), false)
if (repositoryLocation == null) {
showOverVersionControlView(vcs.project, "Repository location not found for ${file.presentableUrl}", MessageType.ERROR)
return
}
@Override
public void update(@NotNull AnActionEvent e) {
Project project = e.getData(CommonDataKeys.PROJECT);
VirtualFile file = e.getData(CommonDataKeys.VIRTUAL_FILE);
Presentation presentation = e.getPresentation();
if (project == null || file == null) {
presentation.setEnabledAndVisible(false);
return;
}
AbstractVcs vcs = getVcsForFile(file, project);
if (vcs == null || !CommittedChangesViewManager.Companion.isCommittedChangesAvailable(vcs)) {
presentation.setEnabledAndVisible(false);
return;
}
presentation.setVisible(true);
presentation.setEnabled(isEnabled(project, vcs, file));
AbstractVcsHelper.getInstance(vcs.project).openCommittedChangesTab(
vcs.committedChangesProvider!!, repositoryLocation, settings, maxCount, null)
}
private fun askMaxCount(project: Project): Int =
when (
showYesNoCancelDialog(
project, message("browse.changes.no.filter.prompt"), message("browse.changes.title"), message("browse.changes.show.recent.button"),
message("browse.changes.show.all.button"), getCancelButtonText(), getQuestionIcon())
) {
Messages.CANCEL -> -1
Messages.YES -> 50
else -> 0
}
private static boolean isEnabled(@NotNull Project project, @NotNull AbstractVcs vcs, @NotNull VirtualFile file) {
return vcs.allowsRemoteCalls(file) && fileInVcsByFileStatus(project, file);
}
private static void showChanges(@NotNull AbstractVcs vcs,
@NotNull CommittedChangesProvider<?, ?> provider,
@NotNull VirtualFile file,
@NotNull ChangeBrowserSettings settings) {
int maxCount = !settings.isAnyFilterSpecified() ? askMaxCount(vcs.getProject()) : 0;
if (maxCount < 0) return;
RepositoryLocationCache cache = CommittedChangesCache.getInstance(vcs.getProject()).getLocationCache();
RepositoryLocation location = cache.getLocation(vcs, VcsUtil.getFilePath(file), false);
if (location == null) {
showOverVersionControlView(vcs.getProject(), "Repository location not found for " + file.getPresentableUrl(), MessageType.ERROR);
return;
}
AbstractVcsHelper.getInstance(vcs.getProject()).openCommittedChangesTab(provider, location, settings, maxCount, null);
}
private static int askMaxCount(@NotNull Project project) {
switch (showYesNoCancelDialog(project, message("browse.changes.no.filter.prompt"), message("browse.changes.title"),
message("browse.changes.show.recent.button"), message("browse.changes.show.all.button"),
getCancelButtonText(), getQuestionIcon())) {
case CANCEL:
return -1;
case YES:
return 50;
default:
return 0;
}
}
}
@@ -2,22 +2,20 @@
package com.intellij.openapi.vcs.changes.committed
import com.intellij.openapi.actionSystem.AnActionEvent
import com.intellij.openapi.actionSystem.CommonDataKeys
import com.intellij.openapi.project.DumbAwareAction
import com.intellij.openapi.vcs.changes.ui.ChangesViewContentManager
import javax.swing.JComponent
class ClearCommittedAction : DumbAwareAction() {
override fun actionPerformed(e: AnActionEvent) {
val project = e.getData(CommonDataKeys.PROJECT)!!
val panel = ChangesViewContentManager.getInstance(project).getActiveComponent(ProjectCommittedChangesPanel::class.java)!!
panel.clearCaches()
override fun update(e: AnActionEvent) {
e.presentation.isEnabledAndVisible = e.getSelectedChangesViewContent<ProjectCommittedChangesPanel>() != null
}
override fun update(e: AnActionEvent) {
val project = e.getData(CommonDataKeys.PROJECT)
val panel = project?.let { ChangesViewContentManager.getInstance(it).getActiveComponent(ProjectCommittedChangesPanel::class.java) }
override fun actionPerformed(e: AnActionEvent) =
e.getSelectedChangesViewContent<ProjectCommittedChangesPanel>()!!.clearCaches()
e.presentation.isEnabledAndVisible = panel != null
companion object {
internal inline fun <reified T : JComponent> AnActionEvent.getSelectedChangesViewContent(): T? =
project?.let { ChangesViewContentManager.getInstance(it) }?.getActiveComponent(T::class.java)
}
}
@@ -14,7 +14,7 @@ import javax.swing.Box
import javax.swing.BoxLayout
import javax.swing.JPanel
abstract class CommittedChangesPanel(protected val project: Project) : BorderLayoutPanel(), DataProvider, Disposable {
abstract class CommittedChangesPanel(val project: Project) : BorderLayoutPanel(), DataProvider, Disposable {
protected val browser: CommittedChangesTreeBrowser =
CommittedChangesTreeBrowser(project, emptyList()).also { Disposer.register(this, it) }
@@ -1,50 +1,40 @@
// Copyright 2000-2019 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.openapi.vcs.changes.committed;
package com.intellij.openapi.vcs.changes.committed
import com.intellij.icons.AllIcons;
import com.intellij.ide.actions.EditSourceAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.CommonDataKeys;
import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.openapi.application.ModalityState;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vcs.VcsDataKeys;
import com.intellij.openapi.vcs.changes.Change;
import com.intellij.openapi.vcs.changes.ui.ChangesBrowserBase;
import com.intellij.pom.Navigatable;
import org.jetbrains.annotations.NotNull;
import com.intellij.icons.AllIcons
import com.intellij.ide.actions.EditSourceAction
import com.intellij.openapi.actionSystem.AnActionEvent
import com.intellij.openapi.actionSystem.CommonDataKeys.PROJECT
import com.intellij.openapi.actionSystem.DataContext
import com.intellij.openapi.application.ModalityState
import com.intellij.openapi.application.ModalityState.NON_MODAL
import com.intellij.openapi.vcs.VcsDataKeys.SELECTED_CHANGES
import com.intellij.openapi.vcs.changes.ChangesUtil.getFiles
import com.intellij.openapi.vcs.changes.ChangesUtil.getNavigatableArray
import com.intellij.openapi.vcs.changes.committed.CommittedChangesBrowserUseCase.IN_AIR
import com.intellij.openapi.vcs.changes.ui.ChangesBrowserBase
import com.intellij.pom.Navigatable
import com.intellij.util.containers.stream
import javax.swing.*;
import java.util.stream.Stream;
internal class EditSourceFromChangesBrowserAction : EditSourceAction() {
override fun update(e: AnActionEvent) {
super.update(e)
import static com.intellij.openapi.vcs.changes.ChangesUtil.getFiles;
import static com.intellij.openapi.vcs.changes.ChangesUtil.getNavigatableArray;
e.presentation.apply {
icon = AllIcons.Actions.EditSource
text = "Edit Source"
class EditSourceFromChangesBrowserAction extends EditSourceAction {
private final Icon myEditSourceIcon;
EditSourceFromChangesBrowserAction() {
myEditSourceIcon = AllIcons.Actions.EditSource;
}
@Override
public void update(@NotNull final AnActionEvent event) {
super.update(event);
event.getPresentation().setIcon(myEditSourceIcon);
event.getPresentation().setText("Edit Source");
if (event.getData(ChangesBrowserBase.DATA_KEY) == null) {
event.getPresentation().setEnabledAndVisible(false);
}
else if ((!ModalityState.NON_MODAL.equals(ModalityState.current())) ||
CommittedChangesBrowserUseCase.IN_AIR.equals(event.getData(CommittedChangesBrowserUseCase.DATA_KEY))) {
event.getPresentation().setEnabled(false);
val changesBrowser = e.getData(ChangesBrowserBase.DATA_KEY)
isVisible = isVisible && changesBrowser != null
isEnabled = isEnabled && changesBrowser != null && ModalityState.current() == NON_MODAL &&
e.getData(CommittedChangesBrowserUseCase.DATA_KEY) != IN_AIR
}
}
@Override
protected Navigatable[] getNavigatables(DataContext dataContext) {
Project project = CommonDataKeys.PROJECT.getData(dataContext);
Change[] changes = VcsDataKeys.SELECTED_CHANGES.getData(dataContext);
return changes != null && project != null ? getNavigatableArray(project, getFiles(Stream.of(changes))) : null;
override fun getNavigatables(dataContext: DataContext): Array<Navigatable>? {
val project = PROJECT.getData(dataContext) ?: return null
val changes = SELECTED_CHANGES.getData(dataContext) ?: return null
return getNavigatableArray(project, getFiles(changes.stream()))
}
}
}
@@ -1,39 +1,25 @@
// Copyright 2000-2019 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.openapi.vcs.changes.committed;
package com.intellij.openapi.vcs.changes.committed
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.CommonDataKeys;
import com.intellij.openapi.project.DumbAware;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vcs.changes.ui.ChangesViewContentManager;
import org.jetbrains.annotations.NotNull;
import com.intellij.openapi.actionSystem.AnActionEvent
import com.intellij.openapi.project.DumbAwareAction
import com.intellij.openapi.vcs.changes.committed.ClearCommittedAction.Companion.getSelectedChangesViewContent
import com.intellij.openapi.vcs.versionBrowser.ChangeBrowserSettings
/**
* @author yole
*/
public class FilterCommittedAction extends AnAction implements DumbAware {
@Override
public void actionPerformed(@NotNull AnActionEvent e) {
Project project = e.getData(CommonDataKeys.PROJECT);
if (project != null) {
RepositoryLocationCommittedChangesPanel panel =
ChangesViewContentManager.getInstance(project).getActiveComponent(RepositoryLocationCommittedChangesPanel.class);
assert panel != null;
panel.setChangesFilter();
}
}
private fun <S : ChangeBrowserSettings> RepositoryLocationCommittedChangesPanel<S>.setCommittedChangesFilter() {
val dialog = CommittedChangesFilterDialog(project, provider.createFilterUI(true), settings)
if (!dialog.showAndGet()) return
@Override
public void update(@NotNull final AnActionEvent e) {
Project project = e.getData(CommonDataKeys.PROJECT);
if (project != null) {
RepositoryLocationCommittedChangesPanel panel =
ChangesViewContentManager.getInstance(project).getActiveComponent(RepositoryLocationCommittedChangesPanel.class);
e.getPresentation().setEnabledAndVisible(panel != null);
}
else {
e.getPresentation().setEnabledAndVisible(false);
}
}
@Suppress("UNCHECKED_CAST")
settings = dialog.settings as S
refreshChanges()
}
class FilterCommittedAction : DumbAwareAction() {
override fun update(e: AnActionEvent) {
e.presentation.isEnabledAndVisible = e.getSelectedChangesViewContent<RepositoryLocationCommittedChangesPanel<*>>() != null
}
override fun actionPerformed(e: AnActionEvent) =
e.getSelectedChangesViewContent<RepositoryLocationCommittedChangesPanel<*>>()!!.setCommittedChangesFilter()
}
@@ -1,42 +1,24 @@
// Copyright 2000-2019 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.openapi.vcs.changes.committed;
package com.intellij.openapi.vcs.changes.committed
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.CommonDataKeys;
import com.intellij.openapi.project.DumbAware;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vcs.changes.ui.ChangesViewContentManager;
import org.jetbrains.annotations.NotNull;
import com.intellij.openapi.actionSystem.AnActionEvent
import com.intellij.openapi.project.DumbAwareAction
import com.intellij.openapi.vcs.changes.committed.ClearCommittedAction.Companion.getSelectedChangesViewContent
/**
* @author yole
*/
public class RefreshCommittedAction extends AnAction implements DumbAware {
@Override
public void actionPerformed(@NotNull AnActionEvent e) {
Project project = e.getData(CommonDataKeys.PROJECT);
CommittedChangesPanel panel = ChangesViewContentManager.getInstance(project).getActiveComponent(CommittedChangesPanel.class);
assert panel != null;
if (panel instanceof RepositoryLocationCommittedChangesPanel) {
panel.refreshChanges();
}
else {
RefreshIncomingChangesAction.doRefresh(project);
}
class RefreshCommittedAction : DumbAwareAction() {
override fun update(e: AnActionEvent) {
val panel = e.getSelectedChangesViewContent<CommittedChangesPanel>()
val isLoading = panel is RepositoryLocationCommittedChangesPanel<*> && panel.isLoading
e.presentation.isEnabled = panel != null && !isLoading
}
@Override
public void update(@NotNull final AnActionEvent e) {
Project project = e.getData(CommonDataKeys.PROJECT);
if (project != null) {
CommittedChangesPanel panel = ChangesViewContentManager.getInstance(project).getActiveComponent(CommittedChangesPanel.class);
boolean isLoading =
panel instanceof RepositoryLocationCommittedChangesPanel && ((RepositoryLocationCommittedChangesPanel)panel).isLoading();
e.getPresentation().setEnabled(panel != null && !isLoading);
}
else {
e.getPresentation().setEnabled(false);
}
override fun actionPerformed(e: AnActionEvent) {
val panel = e.getSelectedChangesViewContent<CommittedChangesPanel>()!!
if (panel is RepositoryLocationCommittedChangesPanel<*>)
panel.refreshChanges()
else
RefreshIncomingChangesAction.doRefresh(panel.project)
}
}
}
@@ -1,39 +1,31 @@
// 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.openapi.vcs.changes.committed;
// Copyright 2000-2019 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.openapi.vcs.changes.committed
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.CommonDataKeys;
import com.intellij.openapi.project.DumbAware;
import com.intellij.openapi.project.Project;
import org.jetbrains.annotations.NotNull;
import com.intellij.openapi.actionSystem.AnActionEvent
import com.intellij.openapi.project.DumbAwareAction
import com.intellij.openapi.project.Project
import com.intellij.openapi.vcs.changes.committed.CacheSettingsDialog.showSettingsDialog
/**
* @author yole
*/
public class RefreshIncomingChangesAction extends AnAction implements DumbAware {
@Override
public void actionPerformed(@NotNull AnActionEvent e) {
Project project = e.getData(CommonDataKeys.PROJECT);
if (project != null) {
doRefresh(project);
private fun Project.getCommittedChangesCache(): CommittedChangesCache = CommittedChangesCache.getInstance(this)
class RefreshIncomingChangesAction : DumbAwareAction() {
override fun update(e: AnActionEvent) {
e.presentation.isEnabled = e.project?.getCommittedChangesCache()?.isRefreshingIncomingChanges == false
}
override fun actionPerformed(e: AnActionEvent) = doRefresh(e.project!!)
companion object {
@JvmStatic
fun doRefresh(project: Project) {
val cache = project.getCommittedChangesCache()
cache.hasCachesForAnyRoot { hasCaches ->
if (!hasCaches && !showSettingsDialog(project)) return@hasCachesForAnyRoot
cache.refreshAllCachesAsync(true, false)
cache.refreshIncomingChangesAsync()
}
}
}
public static void doRefresh(final Project project) {
final CommittedChangesCache cache = CommittedChangesCache.getInstance(project);
cache.hasCachesForAnyRoot(notEmpty -> {
if ((! notEmpty) && (!CacheSettingsDialog.showSettingsDialog(project))) {
return;
}
cache.refreshAllCachesAsync(true, false);
cache.refreshIncomingChangesAsync();
});
}
@Override
public void update(@NotNull final AnActionEvent e) {
Project project = e.getData(CommonDataKeys.PROJECT);
e.getPresentation().setEnabled(project != null && !CommittedChangesCache.getInstance(project).isRefreshingIncomingChanges());
}
}
@@ -44,15 +44,6 @@ internal class RepositoryLocationCommittedChangesPanel<S : ChangeBrowserSettings
setup(extraActions, provider.createActions(browser, repositoryLocation))
}
fun setChangesFilter() {
val dialog = CommittedChangesFilterDialog(project, provider.createFilterUI(true), settings)
if (!dialog.showAndGet()) return
@Suppress("UNCHECKED_CAST")
settings = dialog.settings as S
refreshChanges()
}
override fun refreshChanges() = LoadCommittedChangesTask().queue()
override fun getData(dataId: String): Any? =