/*
* Copyright 2000-2012 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.openapi.vcs.actions;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vcs.*;
import com.intellij.openapi.vcs.changes.Change;
import com.intellij.openapi.vcs.changes.ChangeListManager;
import com.intellij.openapi.vcs.changes.LocalChangeList;
import com.intellij.openapi.vcs.checkin.CheckinEnvironment;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.ObjectUtils;
import com.intellij.vcsUtil.VcsUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Collection;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import static com.intellij.util.containers.UtilKt.getIfSingle;
public class CommonCheckinFilesAction extends AbstractCommonCheckinAction {
@Override
protected String getActionName(@NotNull VcsContext dataContext) {
String actionName = Optional.ofNullable(dataContext.getProject())
.map(project -> getCommonVcs(getRootsStream(dataContext), project))
.map(AbstractVcs::getCheckinEnvironment)
.map(CheckinEnvironment::getCheckinOperationName)
.orElse(VcsBundle.message("vcs.command.name.checkin"));
return modifyCheckinActionName(dataContext, actionName);
}
private String modifyCheckinActionName(@NotNull VcsContext dataContext, String checkinActionName) {
String result = checkinActionName;
List<FilePath> roots = getRootsStream(dataContext).limit(2).collect(Collectors.toList());
if (!roots.isEmpty()) {
String messageKey = roots.get(0).isDirectory() ? "action.name.checkin.directory" : "action.name.checkin.file";
result = VcsBundle.message(StringUtil.pluralize(messageKey, roots.size()), checkinActionName);
}
return result;
}
@Override
protected String getMnemonicsFreeActionName(@NotNull VcsContext context) {
return modifyCheckinActionName(context, VcsBundle.message("vcs.command.name.checkin.no.mnemonics"));
}
@Nullable
@Override
protected LocalChangeList getInitiallySelectedChangeList(@NotNull VcsContext context, @NotNull Project project) {
ChangeListManager manager = ChangeListManager.getInstance(project);
LocalChangeList defaultChangeList = manager.getDefaultChangeList();
LocalChangeList result = null;
for (FilePath root : getRoots(context)) {
if (root.getVirtualFile() == null) continue;
Collection<Change> changes = manager.getChangesIn(root);
if (defaultChangeList != null && containsAnyChange(defaultChangeList, changes)) {
return defaultChangeList;
}
result = changes.stream().findFirst().map(manager::getChangeList).orElse(null);
}
return ObjectUtils.chooseNotNull(result, defaultChangeList);
}
@Override
protected boolean approximatelyHasRoots(@NotNull VcsContext dataContext) {
FileStatusManager manager = FileStatusManager.getInstance(dataContext.getProject());
return getRootsStream(dataContext)
.map(FilePath::getVirtualFile)
.filter(Objects::nonNull)
.anyMatch(file -> isApplicableRoot(file, manager.getStatus(file), dataContext));
}
protected boolean isApplicableRoot(@NotNull VirtualFile file, @NotNull FileStatus status, @NotNull VcsContext dataContext) {
return status != FileStatus.UNKNOWN && status != FileStatus.IGNORED;
}
@NotNull
@Override
protected FilePath[] getRoots(@NotNull VcsContext context) {
return context.getSelectedFilePaths();
}
@NotNull
protected Stream<FilePath> getRootsStream(@NotNull VcsContext context) {
return context.getSelectedFilePathsStream();
}
private static boolean containsAnyChange(@NotNull LocalChangeList changeList, @NotNull Collection<Change> changes) {
return changes.stream().anyMatch(changeList.getChanges()::contains);
}
@Nullable
private static AbstractVcs getCommonVcs(@NotNull Stream<FilePath> roots, @NotNull Project project) {
return getIfSingle(
roots.map(root -> VcsUtil.getVcsFor(project, root))
.filter(Objects::nonNull)
.distinct()
.limit(Math.min(2, ProjectLevelVcsManager.getInstance(project).getAllActiveVcss().length))
);
}
}