diff options
Diffstat (limited to 'plugins/hg4idea/src/org/zmlx/hg4idea/branch/HgBranchPopupActions.java')
-rw-r--r-- | plugins/hg4idea/src/org/zmlx/hg4idea/branch/HgBranchPopupActions.java | 270 |
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); + } + } + } + } + } +} |