/* * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.intellij.dvcs.cherrypick; import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.actionSystem.CommonDataKeys; import com.intellij.openapi.fileEditor.FileDocumentManager; import com.intellij.openapi.project.DumbAwareAction; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vcs.AbstractVcs; import com.intellij.openapi.vcs.ProjectLevelVcsManager; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.util.containers.ContainerUtil; import com.intellij.vcs.log.CommitId; import com.intellij.vcs.log.Hash; import com.intellij.vcs.log.VcsLog; import com.intellij.vcs.log.VcsLogDataKeys; import com.intellij.vcs.log.impl.VcsLogUtil; import icons.DvcsImplIcons; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.Collection; import java.util.List; import java.util.Map; public class VcsCherryPickAction extends DumbAwareAction { private static final String NAME = "Cherry-Pick"; private static final String SEVERAL_VCS_DESCRIPTION = "Selected commits are tracked by different vcses"; public VcsCherryPickAction() { super(NAME, null, DvcsImplIcons.CherryPick); } @Override public void actionPerformed(AnActionEvent e) { FileDocumentManager.getInstance().saveAllDocuments(); Project project = e.getRequiredData(CommonDataKeys.PROJECT); VcsLog log = e.getRequiredData(VcsLogDataKeys.VCS_LOG); VcsCherryPickManager.getInstance(project).cherryPick(log); } @Override public void update(@NotNull AnActionEvent e) { super.update(e); e.getPresentation().setVisible(true); final VcsLog log = e.getData(VcsLogDataKeys.VCS_LOG); Project project = e.getProject(); if (project == null) { e.getPresentation().setEnabledAndVisible(false); return; } VcsCherryPickManager cherryPickManager = VcsCherryPickManager.getInstance(project); List<VcsCherryPicker> cherryPickers = getActiveCherryPickersForProject(project); if (log == null || cherryPickers.isEmpty()) { e.getPresentation().setEnabledAndVisible(false); return; } List<CommitId> commits = VcsLogUtil.collectFirstPack(log.getSelectedCommits(), VcsLogUtil.MAX_SELECTED_COMMITS); if (commits.isEmpty() || cherryPickManager.isCherryPickAlreadyStartedFor(commits)) { e.getPresentation().setEnabled(false); return; } final Map<VirtualFile, List<Hash>> groupedByRoot = groupByRoot(commits); VcsCherryPicker activeCherryPicker = getActiveCherryPicker(cherryPickers, groupedByRoot.keySet()); String description = activeCherryPicker != null ? activeCherryPicker.getInfo(log, groupedByRoot) : SEVERAL_VCS_DESCRIPTION; e.getPresentation().setEnabled(description == null); e.getPresentation() .setText(activeCherryPicker == null ? concatActionNamesForAllAvailable(cherryPickers) : activeCherryPicker.getActionTitle()); e.getPresentation().setDescription(description == null ? "" : description); } @Nullable private static VcsCherryPicker getActiveCherryPicker(@NotNull List<VcsCherryPicker> cherryPickers, @NotNull Collection<VirtualFile> roots) { return ContainerUtil.find(cherryPickers, picker -> picker.canHandleForRoots(roots)); } @NotNull private static Map<VirtualFile, List<Hash>> groupByRoot(@NotNull List<CommitId> details) { Map<VirtualFile, List<Hash>> result = ContainerUtil.newHashMap(); for (CommitId commit : details) { List<Hash> hashes = result.get(commit.getRoot()); if (hashes == null) { hashes = ContainerUtil.newArrayList(); result.put(commit.getRoot(), hashes); } hashes.add(commit.getHash()); } return result; } @NotNull private static String concatActionNamesForAllAvailable(@NotNull final List<VcsCherryPicker> pickers) { return StringUtil.join(pickers, VcsCherryPicker::getActionTitle, "/"); } @NotNull private static List<VcsCherryPicker> getActiveCherryPickersForProject(@Nullable final Project project) { if (project != null) { final ProjectLevelVcsManager projectLevelVcsManager = ProjectLevelVcsManager.getInstance(project); AbstractVcs[] vcss = projectLevelVcsManager.getAllActiveVcss(); return ContainerUtil.mapNotNull(vcss, vcs -> vcs != null ? VcsCherryPickManager.getInstance(project) .getCherryPickerFor(vcs.getKeyInstanceMethod()) : null); } return ContainerUtil.emptyList(); } }