summaryrefslogtreecommitdiff
path: root/plugins/hg4idea/src/org/zmlx/hg4idea/branch/HgBranchPopupActions.java
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/hg4idea/src/org/zmlx/hg4idea/branch/HgBranchPopupActions.java')
-rw-r--r--plugins/hg4idea/src/org/zmlx/hg4idea/branch/HgBranchPopupActions.java270
1 files changed, 270 insertions, 0 deletions
diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/branch/HgBranchPopupActions.java b/plugins/hg4idea/src/org/zmlx/hg4idea/branch/HgBranchPopupActions.java
new file mode 100644
index 000000000000..10b97235f559
--- /dev/null
+++ b/plugins/hg4idea/src/org/zmlx/hg4idea/branch/HgBranchPopupActions.java
@@ -0,0 +1,270 @@
+/*
+ * Copyright 2000-2013 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 org.zmlx.hg4idea.branch;
+
+import com.intellij.dvcs.DvcsUtil;
+import com.intellij.dvcs.repo.Repository;
+import com.intellij.dvcs.ui.NewBranchAction;
+import com.intellij.openapi.actionSystem.ActionGroup;
+import com.intellij.openapi.actionSystem.AnAction;
+import com.intellij.openapi.actionSystem.AnActionEvent;
+import com.intellij.openapi.actionSystem.DefaultActionGroup;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.project.DumbAwareAction;
+import com.intellij.openapi.project.Project;
+import com.intellij.util.ArrayUtil;
+import com.intellij.util.Function;
+import com.intellij.util.PlatformIcons;
+import com.intellij.util.containers.ContainerUtil;
+import com.intellij.vcs.log.Hash;
+import com.intellij.vcs.log.impl.HashImpl;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.zmlx.hg4idea.HgNameWithHashInfo;
+import org.zmlx.hg4idea.HgRevisionNumber;
+import org.zmlx.hg4idea.action.HgAbstractGlobalAction;
+import org.zmlx.hg4idea.action.HgCommandResultNotifier;
+import org.zmlx.hg4idea.command.HgBookmarkCommand;
+import org.zmlx.hg4idea.command.HgBranchCreateCommand;
+import org.zmlx.hg4idea.command.HgWorkingCopyRevisionsCommand;
+import org.zmlx.hg4idea.execution.HgCommandException;
+import org.zmlx.hg4idea.execution.HgCommandResult;
+import org.zmlx.hg4idea.execution.HgCommandResultHandler;
+import org.zmlx.hg4idea.repo.HgRepository;
+import org.zmlx.hg4idea.ui.HgBookmarkDialog;
+import org.zmlx.hg4idea.util.HgErrorUtil;
+
+import java.util.*;
+
+import static org.zmlx.hg4idea.util.HgUtil.getNamesWithoutHashes;
+import static org.zmlx.hg4idea.util.HgUtil.getNewBranchNameFromUser;
+
+public class HgBranchPopupActions {
+
+ private final Project myProject;
+ private final HgRepository myRepository;
+
+ HgBranchPopupActions(Project project, HgRepository repository) {
+ myProject = project;
+ myRepository = repository;
+ }
+
+ ActionGroup createActions(@Nullable DefaultActionGroup toInsert) {
+ DefaultActionGroup popupGroup = new DefaultActionGroup(null, false);
+ popupGroup.addAction(new HgNewBranchAction(myProject, Collections.singletonList(myRepository), myRepository));
+ popupGroup.addAction(new HgNewBookmarkAction(myProject, Collections.singletonList(myRepository), myRepository));
+ popupGroup.addAction(new HgShowUnnamedHeadsForCurrentBranchAction(myProject, myRepository));
+ if (toInsert != null) {
+ popupGroup.addAll(toInsert);
+ }
+
+ popupGroup.addSeparator("Bookmarks");
+ List<String> bookmarkNames = getNamesWithoutHashes(myRepository.getBookmarks());
+ String currentBookmark = myRepository.getCurrentBookmark();
+ for (String bookmark : bookmarkNames) {
+ AnAction bookmarkAction = new BookmarkActions(myProject, Collections.singletonList(myRepository), bookmark);
+ if (bookmark.equals(currentBookmark)) {
+ bookmarkAction.getTemplatePresentation().setIcon(PlatformIcons.CHECK_ICON);
+ }
+ popupGroup.add(bookmarkAction);
+ }
+
+ popupGroup.addSeparator("Branches");
+ List<String> branchNamesList = new ArrayList<String>(myRepository.getOpenedBranches());//only opened branches have to be shown
+ Collections.sort(branchNamesList);
+ for (String branch : branchNamesList) {
+ if (!branch.equals(myRepository.getCurrentBranch())) { // don't show current branch in the list
+ popupGroup.add(new HgCommonBranchActions(myProject, Collections.singletonList(myRepository), branch));
+ }
+ }
+ return popupGroup;
+ }
+
+ public static class HgNewBranchAction extends NewBranchAction<HgRepository> {
+ @NotNull final HgRepository myPreselectedRepo;
+
+ HgNewBranchAction(@NotNull Project project, @NotNull List<HgRepository> repositories, @NotNull HgRepository preselectedRepo) {
+ super(project, repositories);
+ myPreselectedRepo = preselectedRepo;
+ }
+
+ @Override
+ public void actionPerformed(AnActionEvent e) {
+ final String name = getNewBranchNameFromUser(myPreselectedRepo, "Create New Branch");
+ if (name == null) {
+ return;
+ }
+ for (final HgRepository repository : myRepositories) {
+ try {
+ new HgBranchCreateCommand(myProject, repository.getRoot(), name).execute(new HgCommandResultHandler() {
+ @Override
+ public void process(@Nullable HgCommandResult result) {
+ repository.update();
+ if (HgErrorUtil.hasErrorsInCommandExecution(result)) {
+ new HgCommandResultNotifier(myProject)
+ .notifyError(result, "Creation failed", "Branch creation [" + name + "] failed");
+ }
+ }
+ });
+ }
+ catch (HgCommandException exception) {
+ HgAbstractGlobalAction.handleException(myProject, "Can't create new branch: ", exception);
+ }
+ }
+ }
+ }
+
+ public static class HgNewBookmarkAction extends DumbAwareAction {
+ @NotNull protected final List<HgRepository> myRepositories;
+ @NotNull protected Project myProject;
+ @NotNull final HgRepository myPreselectedRepo;
+
+ HgNewBookmarkAction(@NotNull Project project, @NotNull List<HgRepository> repositories, @NotNull HgRepository preselectedRepo) {
+ super("New Bookmark", "Create new bookmark", null);
+ myProject = project;
+ myRepositories = repositories;
+ myPreselectedRepo = preselectedRepo;
+ }
+
+ @Override
+ public void update(AnActionEvent e) {
+ if (DvcsUtil.anyRepositoryIsFresh(myRepositories)) {
+ e.getPresentation().setEnabled(false);
+ e.getPresentation().setDescription("Bookmark creation is not possible before the first commit.");
+ }
+ }
+
+ @Override
+ public void actionPerformed(AnActionEvent e) {
+
+ final HgBookmarkDialog bookmarkDialog = new HgBookmarkDialog(myPreselectedRepo);
+ bookmarkDialog.show();
+ if (bookmarkDialog.isOK()) {
+ final String name = bookmarkDialog.getName();
+ for (HgRepository repository : myRepositories) {
+ try {
+ new HgBookmarkCommand(myProject, repository.getRoot(), name).createBookmark(bookmarkDialog.isActive());
+ }
+ catch (HgCommandException exception) {
+ HgAbstractGlobalAction.handleException(myProject, exception);
+ }
+ }
+ }
+ }
+ }
+
+ public static class HgShowUnnamedHeadsForCurrentBranchAction extends ActionGroup {
+ @NotNull final Project myProject;
+ @NotNull final HgRepository myRepository;
+ @NotNull final String myCurrentBranchName;
+ @NotNull Collection<Hash> myHeads = new HashSet<Hash>();
+
+ public HgShowUnnamedHeadsForCurrentBranchAction(@NotNull Project project,
+ @NotNull HgRepository repository) {
+ super(null, true);
+ myProject = project;
+ myRepository = repository;
+ myCurrentBranchName = repository.getCurrentBranch();
+ getTemplatePresentation().setText(String.format("Unnamed heads for %s", myCurrentBranchName));
+ ApplicationManager.getApplication().executeOnPooledThread(new Runnable() {
+ @Override
+ public void run() {
+ myHeads = filterUnnamedHeads();
+ }
+ });
+ }
+
+ @NotNull
+ private Collection<Hash> filterUnnamedHeads() {
+ Collection<Hash> branchWithHashes = myRepository.getBranches().get(myCurrentBranchName);
+ if (branchWithHashes == null) {
+ // repository is fresh or branch is fresh.
+ return Collections.emptySet();
+ }
+ else {
+ List<HgRevisionNumber> parents = new HgWorkingCopyRevisionsCommand(myProject).parents(myRepository.getRoot());
+ if (parents.size() == 1) {
+ Collection<Hash> bookmarkHashes = ContainerUtil.map(myRepository.getBookmarks(), new Function<HgNameWithHashInfo, Hash>() {
+
+ @Override
+ public Hash fun(HgNameWithHashInfo info) {
+ return info.getHash();
+ }
+ });
+ branchWithHashes.removeAll(bookmarkHashes);
+ branchWithHashes.remove(HashImpl.build(parents.get(0).getChangeset()));
+ }
+ }
+ return branchWithHashes;
+ }
+
+ @NotNull
+ @Override
+ public AnAction[] getChildren(@Nullable AnActionEvent e) {
+ List<AnAction> branchHeadActions = new ArrayList<AnAction>();
+ for (Hash hash : myHeads) {
+ branchHeadActions.add(new HgCommonBranchActions(myProject, Collections.singletonList(myRepository), hash.toShortString()));
+ }
+ return ContainerUtil.toArray(branchHeadActions, new AnAction[branchHeadActions.size()]);
+ }
+
+ @Override
+ public void update(final AnActionEvent e) {
+ if (myRepository.isFresh()) {
+ e.getPresentation().setEnabled(false);
+ e.getPresentation().setDescription("Checkout of a new branch is not possible before the first commit.");
+ }
+ else if (!Repository.State.NORMAL.equals(myRepository.getState())) {
+ e.getPresentation().setEnabled(false);
+ }
+ }
+ }
+
+ /**
+ * Actions available for bookmarks.
+ */
+ static class BookmarkActions extends HgCommonBranchActions {
+
+ BookmarkActions(@NotNull Project project, @NotNull List<HgRepository> repositories, @NotNull String branchName) {
+ super(project, repositories, branchName);
+ }
+
+ @NotNull
+ @Override
+ public AnAction[] getChildren(@Nullable AnActionEvent e) {
+ return ArrayUtil.append(super.getChildren(e), new DeleteBookmarkAction(myProject, myRepositories, myBranchName));
+ }
+
+ private static class DeleteBookmarkAction extends HgBranchAbstractAction {
+
+ DeleteBookmarkAction(@NotNull Project project, @NotNull List<HgRepository> repositories, @NotNull String branchName) {
+ super(project, "Delete", repositories, branchName);
+ }
+
+ @Override
+ public void actionPerformed(AnActionEvent e) {
+ for (HgRepository repository : myRepositories) {
+ try {
+ new HgBookmarkCommand(myProject, repository.getRoot(), myBranchName).deleteBookmark();
+ }
+ catch (HgCommandException exception) {
+ HgAbstractGlobalAction.handleException(myProject, exception);
+ }
+ }
+ }
+ }
+ }
+}