hg action dialog refactoring

*HgMergeDialog and HgUpdateToDialog unified using one common dialog;
*HgPushAction extended HgAbstractGlobalAction;
*HgRepository information used if possible;
*unnecessary hg classes removed;
*doValidate method implemented for common dialog;
*annotations added
This commit is contained in:
Nadya Zabrodina
2014-03-05 17:01:05 +04:00
parent d61ace7d0c
commit e4edbe9521
34 changed files with 383 additions and 1061 deletions
@@ -132,3 +132,4 @@ hg4idea.changelist.column.branch=Branch
hg4idea.annotation.tool.tip=commit {0}\nAuthor: {1}\nDate: {2}\n\n{3}
hg4idea.push.asNewBranch=push as &new remote branch
hg4idea.push.bookmark=Book&mark
@@ -23,27 +23,21 @@ import com.intellij.openapi.ui.MessageType;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vcs.ui.VcsBalloonProblemNotifier;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.zmlx.hg4idea.action.HgCommandResultNotifier;
import org.zmlx.hg4idea.command.HgPushCommand;
import org.zmlx.hg4idea.command.HgTagBranch;
import org.zmlx.hg4idea.command.HgTagBranchCommand;
import org.zmlx.hg4idea.execution.HgCommandResult;
import org.zmlx.hg4idea.execution.HgCommandResultHandler;
import org.zmlx.hg4idea.repo.HgRepository;
import org.zmlx.hg4idea.ui.HgPushDialog;
import org.zmlx.hg4idea.util.HgUtil;
import java.util.Collections;
import java.util.Collection;
import java.util.List;
import java.util.concurrent.atomic.AtomicReference;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* @author Kirill Likhodedov
*/
public class HgPusher {
private static final Logger LOG = Logger.getInstance(HgPusher.class);
@@ -59,52 +53,27 @@ public class HgPusher {
myProject = project;
}
public void showDialogAndPush(@Nullable final VirtualFile selectedRepo) {
HgUtil.executeOnPooledThreadIfNeeded(new Runnable() {
public void run() {
final List<VirtualFile> repositories = HgUtil.getHgRepositories(myProject);
if (repositories.isEmpty()) {
VcsBalloonProblemNotifier.showOverChangesView(myProject, "No Mercurial repositories in the project", MessageType.ERROR);
return;
}
VirtualFile firstRepo = repositories.get(0);
final List<HgTagBranch> branches = getBranches(myProject, firstRepo);
if (branches.isEmpty()) {
return;
}
final AtomicReference<HgPushCommand> pushCommand = new AtomicReference<HgPushCommand>();
UIUtil.invokeAndWaitIfNeeded(new Runnable() {
@Override
public void run() {
final HgPushDialog dialog = new HgPushDialog(myProject, repositories, branches, selectedRepo);
dialog.show();
if (dialog.isOK()) {
dialog.rememberSettings();
pushCommand.set(preparePushCommand(myProject, dialog));
new Task.Backgroundable(myProject, "Pushing...", false) {
@Override
public void run(@NotNull ProgressIndicator indicator) {
if (pushCommand.get() != null) {
push(myProject, pushCommand.get());
}
}
}.queue();
}
}
});
}
});
}
public void showDialogAndPush (@NotNull Collection<HgRepository> repositories,@Nullable final HgRepository selectedRepo) {
@NotNull
public static List<HgTagBranch> getBranches(@NotNull Project project, @NotNull VirtualFile root) {
HgCommandResult branchesResult = new HgTagBranchCommand(project, root).collectBranches();
if (branchesResult == null) {
new HgCommandResultNotifier(project)
.notifyError(branchesResult, "Mercurial command failed", HgVcsMessages.message("hg4idea.branches.error.description"));
return Collections.emptyList();
if (repositories.isEmpty()) {
VcsBalloonProblemNotifier.showOverChangesView(myProject, "No Mercurial repositories in the project", MessageType.ERROR);
return;
}
final AtomicReference<HgPushCommand> pushCommand = new AtomicReference<HgPushCommand>();
final HgPushDialog dialog = new HgPushDialog(myProject, repositories, selectedRepo);
dialog.show();
if (dialog.isOK()) {
dialog.rememberSettings();
pushCommand.set(preparePushCommand(myProject, dialog));
new Task.Backgroundable(myProject, "Pushing...", false) {
@Override
public void run(@NotNull ProgressIndicator indicator) {
if (pushCommand.get() != null) {
push(myProject, pushCommand.get());
}
}
}.queue();
}
return HgTagBranchCommand.parseResult(branchesResult);
}
private static void push(final Project project, HgPushCommand command) {
@@ -122,9 +91,11 @@ public class HgPusher {
String successDescription = String.format("Pushed %d %s [%s]", commitsNum, StringUtil.pluralize("commit", commitsNum),
repo.getPresentableName());
new HgCommandResultNotifier(project).notifySuccess(successTitle, successDescription);
} else if (result.getExitValue() == NOTHING_TO_PUSH_EXIT_VALUE) {
}
else if (result.getExitValue() == NOTHING_TO_PUSH_EXIT_VALUE) {
new HgCommandResultNotifier(project).notifySuccess("", "Nothing to push");
} else {
}
else {
new HgCommandResultNotifier(project).notifyError(result, "Push failed",
"Failed to push to [" + repo.getPresentableName() + "]");
}
@@ -133,10 +104,10 @@ public class HgPusher {
}
private static HgPushCommand preparePushCommand(Project project, HgPushDialog dialog) {
final HgPushCommand command = new HgPushCommand(project, dialog.getRepository(), dialog.getTarget());
final HgPushCommand command = new HgPushCommand(project, dialog.getRepository().getRoot(), dialog.getTarget());
command.setRevision(dialog.getRevision());
command.setForce(dialog.isForce());
command.setBranch(dialog.getBranch());
command.setBranchName(dialog.getBranch());
command.setIsNewBranch(dialog.isNewBranch());
return command;
}
@@ -159,5 +130,4 @@ public class HgPusher {
}
return numberOfCommitsInAllSubrepos;
}
}
@@ -23,6 +23,8 @@ import com.intellij.openapi.vfs.VirtualFile;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.zmlx.hg4idea.HgVcs;
import org.zmlx.hg4idea.repo.HgRepository;
import org.zmlx.hg4idea.repo.HgRepositoryManager;
import org.zmlx.hg4idea.util.HgUtil;
import javax.swing.*;
@@ -47,10 +49,11 @@ abstract class HgAbstractGlobalAction extends AnAction {
return;
}
VirtualFile file = event.getData(CommonDataKeys.VIRTUAL_FILE);
VirtualFile repo = file != null ? HgUtil.getHgRootOrNull(project, file) : null;
List<VirtualFile> repos = HgUtil.getHgRepositories(project);
if (!repos.isEmpty()) {
execute(project, repos, repo);
HgRepositoryManager repositoryManager = HgUtil.getRepositoryManager(project);
HgRepository repo = file != null ? repositoryManager.getRepositoryForFile(file): HgUtil.getCurrentRepository(project);
List<HgRepository> repositories = repositoryManager.getRepositories();
if (!repositories.isEmpty()) {
execute(project, repositories, repo);
}
}
@@ -62,8 +65,8 @@ abstract class HgAbstractGlobalAction extends AnAction {
}
protected abstract void execute(@NotNull Project project,
@NotNull Collection<VirtualFile> repositories,
@Nullable VirtualFile selectedRepo);
@NotNull Collection<HgRepository> repositories,
@Nullable HgRepository selectedRepo);
public static void handleException(@Nullable Project project, @NotNull Exception e) {
handleException(project, "Error", e);
@@ -1,61 +0,0 @@
/*
* Copyright 2000-2011 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.action;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.CommonDataKeys;
import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.openapi.actionSystem.PlatformDataKeys;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
import org.jetbrains.annotations.Nullable;
import org.zmlx.hg4idea.util.HgUtil;
import javax.swing.*;
/**
* @author Kirill Likhodedov
*/
public abstract class HgAction extends AnAction {
protected HgAction() {
}
protected HgAction(Icon icon) {
super(icon);
}
@Override
public void actionPerformed(AnActionEvent event) {
final DataContext dataContext = event.getDataContext();
final Project project = CommonDataKeys.PROJECT.getData(dataContext);
if (project == null) {
return;
}
VirtualFile file = event.getData(CommonDataKeys.VIRTUAL_FILE);
VirtualFile repo = file != null ? HgUtil.getHgRootOrNull(project, file) : null;
execute(project, repo);
}
@Override
public void update(AnActionEvent e) {
boolean enabled = HgAbstractGlobalAction.isEnabled(e);
e.getPresentation().setEnabled(enabled);
}
public abstract void execute(Project project, @Nullable VirtualFile selectedRepo);
}
@@ -298,14 +298,14 @@ public class HgBranchPopupActions {
public void actionPerformed(AnActionEvent e) {
final UpdatedFiles updatedFiles = UpdatedFiles.create();
final HgMergeCommand hgMergeCommand = new HgMergeCommand(myProject, mySelectedRepository.getRoot());
hgMergeCommand.setBranch(myBranchName);
hgMergeCommand.setRevision(myBranchName);
final HgCommandResultNotifier notifier = new HgCommandResultNotifier(myProject);
new Task.Backgroundable(myProject, "Merging changes...") {
@Override
public void run(@NotNull ProgressIndicator indicator) {
try {
new HgHeadMerger(myProject, hgMergeCommand)
.merge(mySelectedRepository.getRoot(), updatedFiles, HgRevisionNumber.NULL_REVISION_NUMBER);
.merge(mySelectedRepository.getRoot());
new HgConflictResolver(myProject, updatedFiles).resolve(mySelectedRepository.getRoot());
}
@@ -16,34 +16,18 @@
package org.zmlx.hg4idea.action;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.zmlx.hg4idea.repo.HgRepository;
import org.zmlx.hg4idea.util.HgUtil;
import java.util.Collection;
/**
* @author Nadya Zabrodina
*/
public class HgBranchesAction extends HgAbstractGlobalAction {
@Override
protected void execute(@NotNull Project project, @NotNull Collection<VirtualFile> repositories, @Nullable VirtualFile selectedRepo) {
HgRepository repository = null;
protected void execute(@NotNull Project project, @NotNull Collection<HgRepository> repositories, @Nullable HgRepository selectedRepo) {
if (selectedRepo != null) {
repository = HgUtil.getRepositoryManager(project).getRepositoryForRoot(selectedRepo);
}
else {
VirtualFile selectedRoot = HgUtil.getRootForSelectedFile(project);
if (selectedRoot != null) {
repository = HgUtil.getRepositoryManager(project).getRepositoryForRoot(selectedRoot);
}
}
if (repository != null) {
HgBranchPopup.getInstance(project, repository).asListPopup().showInFocusCenter();
HgBranchPopup.getInstance(project, selectedRepo).asListPopup().showInFocusCenter();
}
}
}
@@ -13,13 +13,13 @@
package org.zmlx.hg4idea.action;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.zmlx.hg4idea.command.HgTagCreateCommand;
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.HgTagDialog;
import org.zmlx.hg4idea.util.HgErrorUtil;
@@ -28,11 +28,10 @@ import java.util.Collection;
public class HgCreateTagAction extends HgAbstractGlobalAction {
public void execute(@NotNull final Project project,
@NotNull Collection<VirtualFile> repos,
@Nullable VirtualFile selectedRepo,
@NotNull Collection<HgRepository> repositories,
@Nullable HgRepository selectedRepo,
@Nullable final String reference) {
final HgTagDialog dialog = new HgTagDialog(project);
dialog.setRoots(repos, selectedRepo);
final HgTagDialog dialog = new HgTagDialog(project, repositories, selectedRepo);
dialog.show();
if (dialog.isOK()) {
try {
@@ -52,7 +51,9 @@ public class HgCreateTagAction extends HgAbstractGlobalAction {
}
}
protected void execute(@NotNull final Project project, @NotNull Collection<VirtualFile> repos, @Nullable VirtualFile selectedRepo) {
execute(project, repos, selectedRepo, null);
protected void execute(@NotNull final Project project,
@NotNull Collection<HgRepository> repositories,
@Nullable HgRepository selectedRepo) {
execute(project, repositories, selectedRepo, null);
}
}
@@ -19,15 +19,12 @@ import com.intellij.vcs.log.VcsFullCommitDetails;
import org.jetbrains.annotations.NotNull;
import org.zmlx.hg4idea.repo.HgRepository;
import java.util.Arrays;
import java.util.Collections;
/**
* @author Nadya Zabrodina
*/
public class HgCreateTagFromLogAction extends HgLogSingleCommitAction {
@Override
protected void actionPerformed(@NotNull HgRepository repository, @NotNull VcsFullCommitDetails commit) {
String revisionHash = commit.getHash().asString();
new HgCreateTagAction().execute(repository.getProject(), Arrays.asList(repository.getRoot()), repository.getRoot(), revisionHash);
new HgCreateTagAction().execute(repository.getProject(), Collections.singleton(repository), repository, revisionHash);
}
}
@@ -18,56 +18,37 @@ package org.zmlx.hg4idea.action;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.progress.Task;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vcs.VcsException;
import com.intellij.openapi.vcs.update.UpdatedFiles;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.Consumer;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.zmlx.hg4idea.HgRevisionNumber;
import org.zmlx.hg4idea.HgVcsMessages;
import org.zmlx.hg4idea.command.HgMergeCommand;
import org.zmlx.hg4idea.command.HgTagBranch;
import org.zmlx.hg4idea.execution.HgCommandException;
import org.zmlx.hg4idea.provider.update.HgConflictResolver;
import org.zmlx.hg4idea.provider.update.HgHeadMerger;
import org.zmlx.hg4idea.repo.HgRepository;
import org.zmlx.hg4idea.ui.HgMergeDialog;
import org.zmlx.hg4idea.util.HgBranchesAndTags;
import org.zmlx.hg4idea.util.HgUiUtil;
import java.util.Collection;
/**
* @author Nadya Zabrodina
*/
public class HgMerge extends HgAbstractGlobalAction {
@Override
public void execute(@NotNull final Project project,
@NotNull final Collection<VirtualFile> repos,
@Nullable final VirtualFile selectedRepo) {
HgUiUtil.loadBranchesInBackgroundableAndExecuteAction(project, repos, new Consumer<HgBranchesAndTags>() {
@Override
public void consume(HgBranchesAndTags info) {
showMergeDialogAndExecute(project, repos, selectedRepo, info);
}
});
}
private void showMergeDialogAndExecute(final Project project,
Collection<VirtualFile> repos,
@Nullable VirtualFile selectedRepo, HgBranchesAndTags branchesAndTags) {
final HgMergeDialog mergeDialog = new HgMergeDialog(project, repos, selectedRepo, branchesAndTags);
@NotNull final Collection<HgRepository> repos,
@Nullable final HgRepository selectedRepo) {
final HgMergeDialog mergeDialog = new HgMergeDialog(project, repos, selectedRepo);
mergeDialog.show();
if (mergeDialog.isOK()) {
final String targetValue = mergeDialog.getTargetValue();
final VirtualFile repoRoot = mergeDialog.getRepository().getRoot();
new Task.Backgroundable(project, "Merging changes...") {
@Override
public void run(@NotNull ProgressIndicator indicator) {
try {
executeMerge(mergeDialog, project);
markDirtyAndHandleErrors(project, mergeDialog.getRepository());
executeMerge(project, repoRoot, targetValue);
markDirtyAndHandleErrors(project, repoRoot);
}
catch (HgCommandException e) {
handleException(project, e);
@@ -77,63 +58,27 @@ public class HgMerge extends HgAbstractGlobalAction {
}
}
private static void executeMerge(final HgMergeDialog dialog, final Project project) throws HgCommandException {
private static void executeMerge(@NotNull final Project project, @NotNull VirtualFile repo, @NotNull String targetValue)
throws HgCommandException {
UpdatedFiles updatedFiles = UpdatedFiles.create();
HgCommandResultNotifier notifier = new HgCommandResultNotifier(project);
final VirtualFile repo = dialog.getRepository();
HgMergeCommand hgMergeCommand = new HgMergeCommand(project, repo);
hgMergeCommand.setRevision(targetValue);
HgRevisionNumber incomingRevision = null;
HgTagBranch branch = dialog.getBranch();
if (branch != null) {
hgMergeCommand.setBranch(branch.getName());
incomingRevision = branch.getHead();
try {
new HgHeadMerger(project, hgMergeCommand)
.merge(repo);
new HgConflictResolver(project, updatedFiles).resolve(repo);
}
HgTagBranch tag = dialog.getTag();
if (tag != null) {
hgMergeCommand.setRevision(tag.getName());
incomingRevision = tag.getHead();
}
HgTagBranch bookmark = dialog.getBookmark();
if (bookmark != null) {
hgMergeCommand.setRevision(bookmark.getName());
incomingRevision = bookmark.getHead();
}
String revision = dialog.getRevision();
if (revision != null) {
hgMergeCommand.setRevision(revision);
incomingRevision = HgRevisionNumber.getLocalInstance(revision);
}
HgRevisionNumber otherHead = dialog.getOtherHead();
if (otherHead != null) {
String changeset = otherHead.getChangeset();
hgMergeCommand.setRevision(StringUtil.isEmptyOrSpaces(changeset) ? otherHead.getRevision() : changeset);
incomingRevision = otherHead;
}
if (incomingRevision != null) {
try {
new HgHeadMerger(project, hgMergeCommand)
.merge(repo, updatedFiles, incomingRevision);
new HgConflictResolver(project, updatedFiles).resolve(repo);
catch (VcsException e) {
if (e.isWarning()) {
notifier.notifyWarning("Warning during merge", e.getMessage());
}
catch (VcsException e) {
if (e.isWarning()) {
notifier.notifyWarning("Warning during merge", e.getMessage());
}
else {
notifier.notifyError(null, "Exception during merge", e.getMessage());
}
else {
notifier.notifyError(null, "Exception during merge", e.getMessage());
}
}
else {
//noinspection ThrowableInstanceNeverThrown
notifier.notifyError(null, "Merge error", HgVcsMessages.message("hg4idea.error.invalidTarget"));
}
}
}
@@ -16,10 +16,10 @@ import com.intellij.icons.AllIcons;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.progress.Task;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.zmlx.hg4idea.command.HgPullCommand;
import org.zmlx.hg4idea.repo.HgRepository;
import org.zmlx.hg4idea.ui.HgPullDialog;
import java.util.Collection;
@@ -30,9 +30,8 @@ public class HgPullAction extends HgAbstractGlobalAction {
}
@Override
protected void execute(@NotNull final Project project, @NotNull Collection<VirtualFile> repos, @Nullable VirtualFile selectedRepo) {
final HgPullDialog dialog = new HgPullDialog(project);
dialog.setRoots(repos, selectedRepo);
protected void execute(@NotNull final Project project, @NotNull Collection<HgRepository> repos, @Nullable HgRepository selectedRepo) {
final HgPullDialog dialog = new HgPullDialog(project, repos, selectedRepo);
dialog.show();
if (dialog.isOK()) {
dialog.rememberSettings();
@@ -14,18 +14,22 @@ package org.zmlx.hg4idea.action;
import com.intellij.icons.AllIcons;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.zmlx.hg4idea.HgPusher;
import org.zmlx.hg4idea.repo.HgRepository;
public class HgPushAction extends HgAction {
import java.util.Collection;
public class HgPushAction extends HgAbstractGlobalAction {
public HgPushAction() {
super(AllIcons.Actions.Commit);
}
@Override
public void execute(final Project project, @Nullable final VirtualFile selectedRepo) {
new HgPusher(project).showDialogAndPush(selectedRepo);
public void execute(@NotNull final Project project,
@NotNull Collection<HgRepository> repositories,
@Nullable final HgRepository selectedRepo) {
new HgPusher(project).showDialogAndPush(repositories, selectedRepo);
}
}
@@ -15,11 +15,11 @@ package org.zmlx.hg4idea.action;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.progress.Task;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.zmlx.hg4idea.HgVcsMessages;
import org.zmlx.hg4idea.provider.update.HgConflictResolver;
import org.zmlx.hg4idea.repo.HgRepository;
import org.zmlx.hg4idea.ui.HgRunConflictResolverDialog;
import java.util.Collection;
@@ -27,13 +27,13 @@ import java.util.Collection;
public class HgRunConflictResolverAction extends HgAbstractGlobalAction {
@Override
public void execute(@NotNull final Project project, @NotNull Collection<VirtualFile> repos, @Nullable VirtualFile selectedRepo) {
final VirtualFile repository;
if (repos.size() > 1) {
repository = letUserSelectRepository(repos, project, selectedRepo);
public void execute(@NotNull final Project project, @NotNull Collection<HgRepository> repositories, @Nullable HgRepository selectedRepo) {
final HgRepository repository;
if (repositories.size() > 1) {
repository = letUserSelectRepository(project, repositories, selectedRepo);
}
else if (repos.size() == 1) {
repository = repos.iterator().next();
else if (repositories.size() == 1) {
repository = repositories.iterator().next();
}
else {
repository = null;
@@ -43,17 +43,18 @@ public class HgRunConflictResolverAction extends HgAbstractGlobalAction {
@Override
public void run(@NotNull ProgressIndicator indicator) {
new HgConflictResolver(project).resolve(repository);
markDirtyAndHandleErrors(project, repository);
new HgConflictResolver(project).resolve(repository.getRoot());
markDirtyAndHandleErrors(project, repository.getRoot());
}
}.queue();
}
}
private static VirtualFile letUserSelectRepository(Collection<VirtualFile> repos, Project project, @Nullable VirtualFile selectedRepo) {
HgRunConflictResolverDialog dialog = new HgRunConflictResolverDialog(project);
dialog.setRoots(repos, selectedRepo);
@Nullable
private static HgRepository letUserSelectRepository(@NotNull Project project, @NotNull Collection<HgRepository> repositories,
@Nullable HgRepository selectedRepo) {
HgRunConflictResolverDialog dialog = new HgRunConflictResolverDialog(project, repositories, selectedRepo);
dialog.show();
if (dialog.isOK()) {
return dialog.getRepository();
@@ -17,61 +17,43 @@ import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.progress.Task;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.Consumer;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.zmlx.hg4idea.HgVcsMessages;
import org.zmlx.hg4idea.command.HgUpdateCommand;
import org.zmlx.hg4idea.execution.HgCommandResult;
import org.zmlx.hg4idea.provider.update.HgConflictResolver;
import org.zmlx.hg4idea.repo.HgRepository;
import org.zmlx.hg4idea.ui.HgUpdateToDialog;
import org.zmlx.hg4idea.util.HgBranchesAndTags;
import org.zmlx.hg4idea.util.HgErrorUtil;
import org.zmlx.hg4idea.util.HgUiUtil;
import java.util.Collection;
public class HgUpdateToAction extends HgAbstractGlobalAction {
protected void execute(@NotNull final Project project,
@NotNull final Collection<VirtualFile> repos,
@Nullable final VirtualFile selectedRepo) {
HgUiUtil.loadBranchesInBackgroundableAndExecuteAction(project, repos, new Consumer<HgBranchesAndTags>() {
@Override
public void consume(HgBranchesAndTags info) {
showUpdateDialogAndExecute(project, repos, selectedRepo, info);
}
});
}
private static void showUpdateDialogAndExecute(@NotNull final Project project,
@NotNull Collection<VirtualFile> repos, @Nullable VirtualFile selectedRepo,
@NotNull HgBranchesAndTags branchesAndTags) {
final HgUpdateToDialog dialog = new HgUpdateToDialog(project);
dialog.setRoots(repos, selectedRepo, branchesAndTags);
@Override
protected void execute(@NotNull Project project, @NotNull Collection<HgRepository> repositories, @Nullable HgRepository selectedRepo) {
final HgUpdateToDialog dialog = new HgUpdateToDialog(project, repositories, selectedRepo);
dialog.show();
if (dialog.isOK()) {
FileDocumentManager.getInstance().saveAllDocuments();
final String updateToValue = dialog.isBranchSelected()
? dialog.getBranch().getName()
: dialog.isBookmarkSelected()
? dialog.getBookmark().getName()
: dialog.isTagSelected() ? dialog.getTag().getName() : dialog.getRevision();
final String updateToValue = dialog.getTargetValue();
boolean clean = dialog.isRemoveLocalChanges();
String title = HgVcsMessages.message("hg4idea.progress.updatingTo", updateToValue);
runUpdateToInBackground(project, title, dialog.getRepository(), updateToValue, dialog.isRemoveLocalChanges());
runUpdateToInBackground(project, title, dialog.getRepository().getRoot(), updateToValue, clean);
}
}
public static void runUpdateToInBackground(@NotNull final Project project,
@NotNull String title,
@NotNull final VirtualFile root,
@NotNull final String updateToNameOrRevision,
@NotNull final String updateToValue,
final boolean clean) {
new Task.Backgroundable(project, title) {
@Override
public void run(@NotNull ProgressIndicator indicator) {
final HgUpdateCommand command = new HgUpdateCommand(project, root);
command.setRevision(updateToNameOrRevision);
command.setRevision(updateToValue);
command.setClean(clean);
HgCommandResult result = command.execute();
new HgConflictResolver(project).resolve(root);
@@ -17,72 +17,31 @@ import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.containers.HashSet;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.zmlx.hg4idea.HgRevisionNumber;
import org.zmlx.hg4idea.execution.HgCommandExecutor;
import org.zmlx.hg4idea.execution.HgCommandResult;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class HgTagBranchCommand {
public class HgBranchesCommand {
private static final Pattern BRANCH_LINE = Pattern.compile("(.+)\\s([0-9]+):([0-9a-f]+).*");
private static final int NAME_INDEX = 1;
private static final int REVISION_INDEX = 2;
private static final int CHANGESET_INDEX = 3;
private final Project project;
private final VirtualFile repo;
public HgTagBranchCommand(Project project, @NotNull VirtualFile repo) {
public HgBranchesCommand(Project project, @NotNull VirtualFile repo) {
this.project = project;
this.repo = repo;
}
@Nullable
public String getCurrentBranch() {
final HgCommandExecutor executor = new HgCommandExecutor(project);
executor.setSilent(true);
HgCommandResult result = executor.executeInCurrentThread(repo, "branch", null);
if (result == null) {
return null;
}
List<String> output = result.getOutputLines();
if (output == null || output.isEmpty()) {
return null;
}
return output.get(0).trim();
}
public HgCommandResult collectBranches() {
return new HgCommandExecutor(project).executeInCurrentThread(repo, "branches", null);
}
public HgCommandResult collectTags() {
return new HgCommandExecutor(project).executeInCurrentThread(repo, "tags", null);
}
public HgCommandResult collectBookmarks() {
return new HgCommandExecutor(project).executeInCurrentThread(repo, "bookmarks", null);
}
public static List<HgTagBranch> parseResult(@NotNull HgCommandResult result) {
List<HgTagBranch> branches = new LinkedList<HgTagBranch>();
for (final String line : result.getOutputLines()) {
Matcher matcher = BRANCH_LINE.matcher(line);
if (matcher.matches()) {
HgRevisionNumber hgRevisionNumber = HgRevisionNumber.getInstance(
matcher.group(REVISION_INDEX), matcher.group(CHANGESET_INDEX)
);
branches.add(new HgTagBranch(matcher.group(NAME_INDEX).trim(), line.trim(), hgRevisionNumber));
}
}
return branches;
}
@NotNull
public static Set<String> collectNames(@NotNull HgCommandResult result) {
Set<String> branches = new HashSet<String>();
@@ -15,6 +15,7 @@ package org.zmlx.hg4idea.command;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VirtualFile;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.zmlx.hg4idea.HgVcs;
import org.zmlx.hg4idea.execution.HgCommandExecutor;
@@ -26,22 +27,17 @@ import java.util.List;
public class HgMergeCommand {
private final Project project;
private final VirtualFile repo;
@NotNull private final Project project;
@NotNull private final VirtualFile repo;
private String branch;
private String revision;
public HgMergeCommand(Project project, VirtualFile repo) {
public HgMergeCommand(@NotNull Project project, @NotNull VirtualFile repo) {
this.project = project;
this.repo = repo;
}
public void setBranch(String branch) {
this.branch = branch;
}
public void setRevision(String revision) {
public void setRevision(@NotNull String revision) {
this.revision = revision;
}
@@ -53,13 +49,10 @@ public class HgMergeCommand {
if (!StringUtil.isEmptyOrSpaces(revision)) {
arguments.add("--rev");
arguments.add(revision);
} else if (!StringUtil.isEmptyOrSpaces(branch)) {
arguments.add(branch);
}
final HgCommandResult result =
commandExecutor.executeInCurrentThread(repo, "merge", arguments, new HgDeleteModifyPromptHandler());
project.getMessageBus().syncPublisher(HgVcs.BRANCH_TOPIC).update(project, null);
return result;
}
}
@@ -33,7 +33,7 @@ public class HgPushCommand {
private String myRevision;
private boolean myForce;
private HgTagBranch myBranch;
private String myBranchName;
private boolean myIsNewBranch;
public HgPushCommand(Project project, @NotNull VirtualFile repo, String destination) {
@@ -50,13 +50,13 @@ public class HgPushCommand {
myForce = force;
}
public void setBranch(HgTagBranch branch) {
myBranch = branch;
public void setBranchName(String branch) {
myBranchName = branch;
}
public void setIsNewBranch(boolean isNewBranch) {
myIsNewBranch = isNewBranch;
}
myIsNewBranch = isNewBranch;
}
public void execute(final HgCommandResultHandler resultHandler) {
final List<String> arguments = new LinkedList<String>();
@@ -64,13 +64,13 @@ public class HgPushCommand {
arguments.add("-r");
arguments.add(myRevision);
}
if (myBranch != null) {
if (myBranchName != null) {
if (myIsNewBranch) {
arguments.add("--new-branch");
}
else {
arguments.add("-b");
arguments.add(myBranch.getName());
arguments.add(myBranchName);
}
}
if (myForce) {
@@ -1,52 +0,0 @@
// Copyright 2008-2010 Victor Iacoban
//
// 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.command;
import com.intellij.openapi.util.text.StringUtil;
import org.zmlx.hg4idea.HgRevisionNumber;
public final class HgTagBranch {
private static final int SPACINGAFTERFIRSTLETTER = 20;
private final String name;
private final String description;
private final HgRevisionNumber head;
private final String presentation;
public HgTagBranch(String name, String description, HgRevisionNumber head) {
this.name = name;
this.description = description;
this.head = head;
int whitespaceNum = SPACINGAFTERFIRSTLETTER - name.length();
String presentationName = whitespaceNum <= 0 ? name.substring(0, SPACINGAFTERFIRSTLETTER - 4).concat("...") : name;
presentation = String.format("%s%s%s", presentationName, whitespaceNum > 0 ? StringUtil.repeatSymbol(' ', whitespaceNum) : " ", head);
}
public String getName() {
return name;
}
public String getDescription() {
return description;
}
public HgRevisionNumber getHead() {
return head;
}
@Override
public String toString() {
return presentation;
}
}
@@ -40,6 +40,8 @@ import org.zmlx.hg4idea.command.*;
import org.zmlx.hg4idea.execution.HgCommandException;
import org.zmlx.hg4idea.execution.HgCommandExecutor;
import org.zmlx.hg4idea.execution.HgCommandResult;
import org.zmlx.hg4idea.repo.HgRepository;
import org.zmlx.hg4idea.repo.HgRepositoryManager;
import org.zmlx.hg4idea.util.HgUtil;
import java.util.*;
@@ -125,9 +127,12 @@ public class HgCheckinEnvironment implements CheckinEnvironment {
// push if needed
if (myNextCommitIsPushed && exceptions.isEmpty()) {
final VirtualFile preselectedRepo = repositoriesMap.size() == 1 ? repositoriesMap.keySet().iterator().next() : null;
HgRepositoryManager repositoryManager = HgUtil.getRepositoryManager(myProject);
final HgRepository repo = preselectedRepo != null ? repositoryManager.getRepositoryForFile(preselectedRepo) : null;
final Collection<HgRepository> repositories = repositoryManager.getRepositories();
UIUtil.invokeLaterIfNeeded(new Runnable() {
public void run() {
new HgPusher(myProject).showDialogAndPush(preselectedRepo);
new HgPusher(myProject).showDialogAndPush(repositories, repo);
}
});
}
@@ -15,8 +15,6 @@ package org.zmlx.hg4idea.provider.update;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vcs.VcsException;
import com.intellij.openapi.vcs.history.VcsRevisionNumber;
import com.intellij.openapi.vcs.update.UpdatedFiles;
import com.intellij.openapi.vfs.VirtualFile;
import org.jetbrains.annotations.NotNull;
import org.zmlx.hg4idea.command.HgMergeCommand;
@@ -38,11 +36,9 @@ public final class HgHeadMerger {
this.hgMergeCommand = hgMergeCommand;
}
public HgCommandResult merge(VirtualFile repo, UpdatedFiles updatedFiles,
VcsRevisionNumber revisionNumber) throws VcsException {
public HgCommandResult merge(VirtualFile repo) throws VcsException {
HgCommandResult commandResult = ensureSuccess(hgMergeCommand.execute());
try {
HgUtil.markDirectoryDirty(project, repo);
}
@@ -61,5 +57,4 @@ public final class HgHeadMerger {
LOG.info(msg, e);
throw new VcsException(msg);
}
}
@@ -113,7 +113,7 @@ public class HgRegularUpdater implements HgUpdater {
abortOnMultiplePulledHeads(pulledBranchHeads);
abortOnMultipleLocalHeads(remainingOriginalBranchHeads);
HgCommandResult mergeResult = doMerge(updatedFiles, indicator, pulledBranchHeads.get(0));
HgCommandResult mergeResult = doMerge(indicator);
if (shouldCommitAfterMerge()) {
commitOrWarnAboutConflicts(warnings, mergeResult);
@@ -198,15 +198,13 @@ public class HgRegularUpdater implements HgUpdater {
}
}
private HgCommandResult doMerge(UpdatedFiles updatedFiles,
ProgressIndicator indicator,
HgRevisionNumber headToMerge) throws VcsException {
private HgCommandResult doMerge(ProgressIndicator indicator) throws VcsException {
indicator.setText2(HgVcsMessages.message("hg4idea.update.progress.merging"));
HgMergeCommand mergeCommand = new HgMergeCommand(project, repoRoot);
//do not explicitly set the revision, that way mercurial itself checks that there are exactly
//two heads in this branch
// mergeCommand.setRevision(headToMerge.getRevision());
return new HgHeadMerger(project, mergeCommand).merge(repoRoot, updatedFiles, headToMerge);
return new HgHeadMerger(project, mergeCommand).merge(repoRoot);
}
private void abortOnLocalChanges() throws VcsException {
@@ -28,7 +28,7 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.zmlx.hg4idea.HgNameWithHashInfo;
import org.zmlx.hg4idea.HgVcs;
import org.zmlx.hg4idea.command.HgTagBranchCommand;
import org.zmlx.hg4idea.command.HgBranchesCommand;
import org.zmlx.hg4idea.execution.HgCommandResult;
import org.zmlx.hg4idea.util.HgUtil;
@@ -162,13 +162,13 @@ public class HgRepositoryImpl extends RepositoryImpl implements HgRepository {
// Then blinking and do not work properly;
if (!Disposer.isDisposed(getProject()) && !currentInfo.equals(myInfo)) {
myInfo = currentInfo;
HgCommandResult branchCommandResult = new HgTagBranchCommand(getProject(), getRoot()).collectBranches();
HgCommandResult branchCommandResult = new HgBranchesCommand(getProject(), getRoot()).collectBranches();
if (branchCommandResult == null || branchCommandResult.getExitValue() != 0) {
LOG.warn("Could not collect hg opened branches."); // hg executable is not valid
myOpenedBranches = myInfo.getBranches().keySet();
}
else {
myOpenedBranches = HgTagBranchCommand.collectNames(branchCommandResult);
myOpenedBranches = HgBranchesCommand.collectNames(branchCommandResult);
}
getProject().getMessageBus().syncPublisher(HgVcs.STATUS_TOPIC).update(getProject(), getRoot());
}
@@ -1,16 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="org.zmlx.hg4idea.ui.HgUpdateToDialog">
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="org.zmlx.hg4idea.ui.HgCommonDialogWithChoices">
<grid id="27dc6" binding="contentPanel" layout-manager="GridLayoutManager" row-count="4" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<xy x="20" y="20" width="500" height="400"/>
<xy x="22" y="20" width="498" height="291"/>
</constraints>
<properties/>
<border type="none"/>
<children>
<vspacer id="84392">
<constraints>
<grid row="3" column="0" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
<grid row="3" column="0" row-span="1" col-span="1" vsize-policy="2" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
</constraints>
</vspacer>
<hspacer id="af9e5">
@@ -23,10 +23,14 @@
<grid row="2" column="0" row-span="1" col-span="2" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<enabled value="false"/>
<text value="&amp;Overwrite locally modified files (no backup)"/>
</properties>
<clientProperties>
<html.disable class="java.lang.Boolean" value="false"/>
</clientProperties>
</component>
<grid id="814c5" layout-manager="GridLayoutManager" row-count="4" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<grid id="814c5" binding="myBranchesBorderPanel" layout-manager="GridLayoutManager" row-count="4" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<grid row="1" column="0" row-span="1" col-span="2" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
@@ -35,7 +39,7 @@
<clientProperties>
<BorderFactoryClass class="java.lang.String" value="com.intellij.ui.IdeBorderFactory$PlainSmallWithIndent"/>
</clientProperties>
<border type="none" title="Switch to"/>
<border type="none"/>
<children>
<component id="674b0" class="javax.swing.JRadioButton" binding="branchOption">
<constraints>
@@ -0,0 +1,152 @@
/*
* 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 org.zmlx.hg4idea.ui;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.openapi.ui.ValidationInfo;
import com.intellij.openapi.util.text.StringUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.zmlx.hg4idea.repo.HgRepository;
import org.zmlx.hg4idea.util.HgUtil;
import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Collection;
public class HgCommonDialogWithChoices extends DialogWrapper {
private JPanel contentPanel;
private JRadioButton branchOption;
private JRadioButton revisionOption;
private JRadioButton tagOption;
private JRadioButton bookmarkOption;
private JTextField revisionTxt;
protected JCheckBox cleanCbx;
private JComboBox branchSelector;
private JComboBox tagSelector;
private JComboBox bookmarkSelector;
protected HgRepositorySelectorComponent hgRepositorySelectorComponent;
protected JPanel myBranchesBorderPanel;
public HgCommonDialogWithChoices(@NotNull Project project, @NotNull Collection<HgRepository> repositories, @Nullable HgRepository selectedRepo) {
super(project, false);
hgRepositorySelectorComponent.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
updateRepository();
}
});
ChangeListener changeListener = new ChangeListener() {
public void stateChanged(ChangeEvent e) {
update();
}
};
branchOption.addChangeListener(changeListener);
tagOption.addChangeListener(changeListener);
bookmarkOption.addChangeListener(changeListener);
revisionOption.addChangeListener(changeListener);
cleanCbx.setVisible(false);
setRoots(repositories, selectedRepo);
init();
}
public void setRoots(Collection<HgRepository> repos,
@Nullable HgRepository selectedRepo) {
hgRepositorySelectorComponent.setRoots(repos);
hgRepositorySelectorComponent.setSelectedRoot(selectedRepo);
updateRepository();
}
public HgRepository getRepository() {
return hgRepositorySelectorComponent.getRepository();
}
public String getTag() {
return (String)tagSelector.getSelectedItem();
}
public boolean isTagSelected() {
return tagOption.isSelected();
}
public String getBranch() {
return (String)branchSelector.getSelectedItem();
}
public boolean isBranchSelected() {
return branchOption.isSelected();
}
public String getBookmark() {
return (String)bookmarkSelector.getSelectedItem();
}
public boolean isBookmarkSelected() {
return bookmarkOption.isSelected();
}
public String getRevision() {
return revisionTxt.getText();
}
private void update() {
revisionTxt.setEnabled(revisionOption.isSelected());
branchSelector.setEnabled(branchOption.isSelected());
tagSelector.setEnabled(tagOption.isSelected());
bookmarkSelector.setEnabled(bookmarkOption.isSelected());
}
private void updateRepository() {
HgRepository repo = hgRepositorySelectorComponent.getRepository();
branchSelector.setModel(new DefaultComboBoxModel(repo.getOpenedBranches().toArray()));
tagSelector.setModel(new DefaultComboBoxModel(HgUtil.getNamesWithoutHashes(repo.getTags()).toArray()));
DefaultComboBoxModel tagComboBoxModel = new DefaultComboBoxModel(HgUtil.getNamesWithoutHashes(repo.getTags()).toArray());
tagComboBoxModel.addElement("tip"); //HgRepository does not store 'tip' tag because it is internal and not included in tags file
tagSelector.setModel(tagComboBoxModel);
bookmarkSelector.setModel(new DefaultComboBoxModel(HgUtil.getNamesWithoutHashes(repo.getBookmarks()).toArray()));
update();
}
protected JComponent createCenterPanel() {
return contentPanel;
}
@Override
protected String getDimensionServiceKey() {
return getClass().getName();
}
protected void createUIComponents() {
}
public String getTargetValue() {
return isBranchSelected() ? getBranch() : isBookmarkSelected() ? getBookmark() : isTagSelected() ? getTag() : getRevision();
}
protected ValidationInfo doValidate() {
String message = "You have to specify appropriate name or revision.";
if (StringUtil.isEmptyOrSpaces(getTargetValue())) {
return new ValidationInfo(message, myBranchesBorderPanel);
}
return null;
}
}
@@ -1,139 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="org.zmlx.hg4idea.ui.HgMergeDialog">
<grid id="27dc6" binding="contentPanel" layout-manager="GridLayoutManager" row-count="3" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<xy x="20" y="20" width="500" height="400"/>
</constraints>
<properties/>
<border type="none"/>
<children>
<grid id="a0d6" layout-manager="GridLayoutManager" row-count="6" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<grid row="1" column="0" row-span="1" col-span="2" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
</constraints>
<properties/>
<clientProperties>
<BorderFactoryClass class="java.lang.String" value="com.intellij.ui.IdeBorderFactory$PlainSmallWithIndent"/>
</clientProperties>
<border type="none" title="Merge with"/>
<children>
<component id="99075" class="javax.swing.JRadioButton" binding="branchOption">
<constraints>
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<selected value="true"/>
<text value="&amp;Branch"/>
</properties>
</component>
<component id="653f0" class="javax.swing.JRadioButton" binding="tagOption">
<constraints>
<grid row="2" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="&amp;Tag"/>
</properties>
</component>
<component id="cefd6" class="javax.swing.JComboBox" binding="branchSelector">
<constraints>
<grid row="1" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="2" anchor="8" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<enabled value="true"/>
<font name="Monospaced"/>
</properties>
</component>
<component id="e6ad1" class="javax.swing.JComboBox" binding="tagSelector">
<constraints>
<grid row="2" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="2" anchor="8" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<enabled value="false"/>
<font name="Monospaced"/>
</properties>
</component>
<hspacer id="2892f">
<constraints>
<grid row="5" column="1" row-span="1" col-span="1" vsize-policy="1" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
</hspacer>
<component id="f1e00" class="javax.swing.JTextField" binding="revisionTxt">
<constraints>
<grid row="4" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false">
<preferred-size width="150" height="-1"/>
</grid>
</constraints>
<properties>
<enabled value="false"/>
</properties>
</component>
<component id="f198c" class="javax.swing.JRadioButton" binding="revisionOption">
<constraints>
<grid row="4" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<selected value="false"/>
<text value="&amp;Revision"/>
</properties>
</component>
<component id="8ad2b" class="javax.swing.JRadioButton" binding="otherHeadRadioButton" default-binding="true">
<constraints>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<selected value="false"/>
<text value="&amp;Other head:"/>
<toolTipText value="There is exactly one other head on this branch"/>
</properties>
</component>
<component id="10618" class="javax.swing.JLabel" binding="otherHeadLabel">
<constraints>
<grid row="0" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value=""/>
</properties>
</component>
<component id="dc07f" class="javax.swing.JRadioButton" binding="bookmarkOption">
<constraints>
<grid row="3" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="Book&amp;mark"/>
</properties>
</component>
<component id="14e6b" class="javax.swing.JComboBox" binding="bookmarkSelector">
<constraints>
<grid row="3" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="2" anchor="8" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<enabled value="false"/>
<font name="Monospaced"/>
</properties>
</component>
</children>
</grid>
<vspacer id="fe9e6">
<constraints>
<grid row="2" column="1" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
</constraints>
</vspacer>
<nested-form id="8b57e" form-file="org/zmlx/hg4idea/ui/HgRepositorySelectorComponent.form" binding="hgRepositorySelectorComponent">
<constraints>
<grid row="0" column="0" row-span="1" col-span="2" vsize-policy="3" hsize-policy="7" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
</nested-form>
</children>
</grid>
<buttonGroups>
<group name="mergeTarget">
<member id="f198c"/>
<member id="99075"/>
<member id="653f0"/>
<member id="8ad2b"/>
<member id="dc07f"/>
</group>
</buttonGroups>
</form>
@@ -12,181 +12,27 @@
// limitations under the License.
package org.zmlx.hg4idea.ui;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.ui.UIUtil;
import com.intellij.ui.IdeBorderFactory;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.zmlx.hg4idea.HgRevisionNumber;
import org.zmlx.hg4idea.command.HgHeadsCommand;
import org.zmlx.hg4idea.command.HgTagBranch;
import org.zmlx.hg4idea.command.HgWorkingCopyRevisionsCommand;
import org.zmlx.hg4idea.util.HgBranchesAndTags;
import org.zmlx.hg4idea.util.HgUiUtil;
import org.zmlx.hg4idea.repo.HgRepository;
import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
public class HgMergeDialog extends DialogWrapper {
public class HgMergeDialog extends HgCommonDialogWithChoices {
private final Project project;
private JRadioButton revisionOption;
private JTextField revisionTxt;
private JRadioButton branchOption;
private JRadioButton tagOption;
private JRadioButton bookmarkOption;
private JComboBox branchSelector;
private JComboBox tagSelector;
private JComboBox bookmarkSelector;
private JPanel contentPanel;
private HgRepositorySelectorComponent hgRepositorySelectorComponent;
private JRadioButton otherHeadRadioButton;
private JLabel otherHeadLabel;
private HgRevisionNumber otherHead;
private Map<VirtualFile, Collection<HgTagBranch>> branchesForRepos;
private Map<VirtualFile, Collection<HgTagBranch>> tagsForRepos;
private Map<VirtualFile, Collection<HgTagBranch>> bookmarksForRepos;
public HgMergeDialog(Project project,
Collection<VirtualFile> roots,
@Nullable VirtualFile selectedRepo, HgBranchesAndTags branchesAndTags) {
super(project, false);
this.project = project;
branchesForRepos = branchesAndTags.getBranchesForRepos();
tagsForRepos = branchesAndTags.getTagsForRepos();
bookmarksForRepos = branchesAndTags.getBookmarksForRepos();
setRoots(roots, selectedRepo);
public HgMergeDialog(@NotNull Project project,
@NotNull Collection<HgRepository> repositories,
@Nullable HgRepository selectedRepo) {
super(project, repositories, selectedRepo);
hgRepositorySelectorComponent.setTitle("Select repository to merge");
hgRepositorySelectorComponent.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
updateRepository();
}
});
ChangeListener changeListener = new ChangeListener() {
public void stateChanged(ChangeEvent e) {
updateOptions();
}
};
branchOption.addChangeListener(changeListener);
tagOption.addChangeListener(changeListener);
bookmarkOption.addChangeListener(changeListener);
revisionOption.addChangeListener(changeListener);
otherHeadRadioButton.addChangeListener(changeListener);
myBranchesBorderPanel.setBorder(IdeBorderFactory.createTitledBorder("Merge with", true));
setTitle("Merge");
init();
}
public void setRoots(Collection<VirtualFile> repos, @Nullable VirtualFile selectedRepo) {
hgRepositorySelectorComponent.setRoots(repos);
hgRepositorySelectorComponent.setSelectedRoot(selectedRepo);
updateRepository();
}
public VirtualFile getRepository() {
return hgRepositorySelectorComponent.getRepository();
}
public HgTagBranch getBranch() {
return branchOption.isSelected() ? (HgTagBranch) branchSelector.getSelectedItem() : null;
}
public HgTagBranch getTag() {
return tagOption.isSelected() ? (HgTagBranch) tagSelector.getSelectedItem() : null;
}
public HgTagBranch getBookmark() {
return bookmarkOption.isSelected() ? (HgTagBranch)bookmarkSelector.getSelectedItem() : null;
}
public String getRevision() {
return revisionOption.isSelected() ? revisionTxt.getText() : null;
}
public HgRevisionNumber getOtherHead() {
return otherHeadRadioButton.isSelected() ? otherHead : null;
}
private void updateRepository() {
VirtualFile repo = getRepository();
HgUiUtil.loadContentToDialog(repo, branchesForRepos, branchSelector);
HgUiUtil.loadContentToDialog(repo, tagsForRepos, tagSelector);
HgUiUtil.loadContentToDialog(repo, bookmarksForRepos, bookmarkSelector);
loadHeads(repo);
}
private void updateOptions() {
revisionTxt.setEnabled(revisionOption.isSelected());
branchSelector.setEnabled(branchOption.isSelected());
tagSelector.setEnabled(tagOption.isSelected());
bookmarkSelector.setEnabled(bookmarkOption.isSelected());
}
private void loadHeads(final VirtualFile root) {
ApplicationManager.getApplication().executeOnPooledThread(new Runnable() {
@Override
public void run() {
final List<HgRevisionNumber> heads = new HgHeadsCommand(project, root).execute();
if (heads.size() != 2) {
disableOtherHeadsChoice();
return;
}
HgRevisionNumber currentParent = new HgWorkingCopyRevisionsCommand(project).identify(root).getFirst();
for (Iterator<HgRevisionNumber> it = heads.iterator(); it.hasNext(); ) {
final HgRevisionNumber rev = it.next();
if (rev.getRevisionNumber().equals(currentParent.getRevisionNumber())) {
it.remove();
}
}
if (heads.size() == 1) {
UIUtil.invokeLaterIfNeeded(new Runnable() {
@Override
public void run() {
otherHeadRadioButton.setVisible(true);
otherHeadLabel.setVisible(true);
otherHead = heads.get(0);
otherHeadLabel.setText(" " + otherHead.asString());
}
});
}
else {
//apparently we are not at one of the heads
disableOtherHeadsChoice();
}
}
});
}
private void disableOtherHeadsChoice() {
UIUtil.invokeLaterIfNeeded(new Runnable() {
@Override
public void run() {
otherHeadLabel.setVisible(false);
otherHeadRadioButton.setVisible(false);
}
});
}
@Nullable
@Override
protected JComponent createCenterPanel() {
return contentPanel;
}
@Override
protected String getDimensionServiceKey() {
return getClass().getName();
protected String getHelpId() {
return "reference.mercurial.merge.dialog";
}
}
@@ -23,8 +23,10 @@ import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.ui.EditorComboBox;
import com.intellij.util.ArrayUtil;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.zmlx.hg4idea.HgRememberedInputs;
import org.zmlx.hg4idea.repo.HgRepository;
import org.zmlx.hg4idea.util.HgUtil;
import javax.swing.*;
@@ -40,7 +42,7 @@ public class HgPullDialog extends DialogWrapper {
private EditorComboBox myRepositoryURL;
private String myCurrentRepositoryUrl;
public HgPullDialog(Project project) {
public HgPullDialog(@NotNull Project project, @NotNull Collection<HgRepository> repositories, @Nullable final HgRepository selectedRepo) {
super(project, false);
this.project = project;
hgRepositorySelector.setTitle("Select repository to pull changesets for");
@@ -53,6 +55,7 @@ public class HgPullDialog extends DialogWrapper {
setTitle("Pull");
setOKButtonText("Pull");
init();
setRoots(repositories, selectedRepo);
}
public void createUIComponents() {
@@ -67,7 +70,7 @@ public class HgPullDialog extends DialogWrapper {
});
}
private void addPathsFromHgrc(VirtualFile repo) {
private void addPathsFromHgrc(@NotNull VirtualFile repo) {
Collection<String> paths = HgUtil.getRepositoryPaths(project, repo);
for (String path : paths) {
myRepositoryURL.prependItem(path);
@@ -80,15 +83,15 @@ public class HgPullDialog extends DialogWrapper {
}
public VirtualFile getRepository() {
return hgRepositorySelector.getRepository();
return hgRepositorySelector.getRepository().getRoot();
}
public String getSource() {
return myCurrentRepositoryUrl;
}
public void setRoots(Collection<VirtualFile> repos, @Nullable final VirtualFile selectedRepo) {
hgRepositorySelector.setRoots(repos);
private void setRoots(@NotNull Collection<HgRepository> repositories, @Nullable final HgRepository selectedRepo) {
hgRepositorySelector.setRoots(repositories);
hgRepositorySelector.setSelectedRoot(selectedRepo);
onChangeRepository();
}
@@ -106,8 +109,8 @@ public class HgPullDialog extends DialogWrapper {
ApplicationManager.getApplication().executeOnPooledThread(new Runnable() {
@Override
public void run() {
final VirtualFile repo = hgRepositorySelector.getRepository();
final String defaultPath = HgUtil.getRepositoryDefaultPath(project,repo);
final VirtualFile repo = hgRepositorySelector.getRepository().getRoot();
final String defaultPath = HgUtil.getRepositoryDefaultPath(project, repo);
if (!StringUtil.isEmptyOrSpaces(defaultPath)) {
UIUtil.invokeAndWaitIfNeeded(new Runnable() {
@Override
@@ -133,5 +136,4 @@ public class HgPullDialog extends DialogWrapper {
protected String getDimensionServiceKey() {
return HgPullDialog.class.getName();
}
}
@@ -24,10 +24,9 @@ import com.intellij.ui.EditorComboBox;
import com.intellij.util.ArrayUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.zmlx.hg4idea.HgPusher;
import org.zmlx.hg4idea.HgRememberedInputs;
import org.zmlx.hg4idea.HgVcsMessages;
import org.zmlx.hg4idea.command.HgTagBranch;
import org.zmlx.hg4idea.repo.HgRepository;
import org.zmlx.hg4idea.util.HgUtil;
import javax.swing.*;
@@ -38,7 +37,6 @@ import javax.swing.event.DocumentListener;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Collection;
import java.util.List;
public class HgPushDialog extends DialogWrapper {
@@ -55,7 +53,7 @@ public class HgPushDialog extends DialogWrapper {
private JCheckBox newBranchCheckBox;
private String myCurrentRepositoryUrl;
public HgPushDialog(Project project, Collection<VirtualFile> repos, List<HgTagBranch> branches, @Nullable VirtualFile selectedRepo) {
public HgPushDialog(Project project, Collection<HgRepository> repos, @Nullable HgRepository selectedRepo) {
super(project, false);
myProject = project;
@@ -75,9 +73,15 @@ public class HgPushDialog extends DialogWrapper {
setOKButtonText("Push");
init();
setRoots(repos, selectedRepo);
}
private void setRoots(@NotNull Collection<HgRepository> repos,
@Nullable HgRepository selectedRepo) {
hgRepositorySelectorComponent.setRoots(repos);
hgRepositorySelectorComponent.setSelectedRoot(selectedRepo);
updateBranchComboBox(branches);
HgRepository repo = hgRepositorySelectorComponent.getRepository();
updateComboBoxes(repo);
updateRepository();
}
@@ -101,10 +105,12 @@ public class HgPushDialog extends DialogWrapper {
}
}
public VirtualFile getRepository() {
@NotNull
public HgRepository getRepository() {
return hgRepositorySelectorComponent.getRepository();
}
@NotNull
public String getTarget() {
return myCurrentRepositoryUrl;
}
@@ -115,8 +121,8 @@ public class HgPushDialog extends DialogWrapper {
}
@Nullable
public HgTagBranch getBranch() {
return branchCheckBox.isSelected() ? (HgTagBranch) branchComboBox.getSelectedItem() : null;
public String getBranch() {
return branchCheckBox.isSelected() ? (String)branchComboBox.getSelectedItem() : null;
}
public boolean isForce() {
@@ -124,8 +130,8 @@ public class HgPushDialog extends DialogWrapper {
}
public boolean isNewBranch() {
return newBranchCheckBox.isSelected();
}
return newBranchCheckBox.isSelected();
}
protected JComponent createCenterPanel() {
return contentPanel;
@@ -140,24 +146,28 @@ public class HgPushDialog extends DialogWrapper {
ApplicationManager.getApplication().executeOnPooledThread(new Runnable() {
@Override
public void run() {
final VirtualFile repo = hgRepositorySelectorComponent.getRepository();
final String defaultPath = HgUtil.getRepositoryDefaultPushPath(myProject, repo);
final List<HgTagBranch> branches = HgPusher.getBranches(myProject, repo);
final HgRepository repo = hgRepositorySelectorComponent.getRepository();
final String defaultPath = HgUtil.getRepositoryDefaultPushPath(repo);
ApplicationManager.getApplication().invokeLater(new Runnable() {
@Override
public void run() {
addPathsFromHgrc(repo);
addPathsFromHgrc(repo.getRoot());
if (defaultPath != null) {
updateRepositoryUrlText(HgUtil.removePasswordIfNeeded(defaultPath));
myCurrentRepositoryUrl = defaultPath;
}
updateBranchComboBox(branches);
updateComboBoxes(repo);
}
}, ModalityState.stateForComponent(getRootPane()));
}
});
}
private void updateComboBoxes(HgRepository repo) {
final Collection<String> branches = repo.getOpenedBranches();
branchComboBox.setModel(new DefaultComboBoxModel(branches.toArray()));
}
private void updateRepositoryUrlText(String defaultPath) {
if (defaultPath != null) {
myRepositoryURL.setText(defaultPath);
@@ -165,10 +175,6 @@ public class HgPushDialog extends DialogWrapper {
}
}
private void updateBranchComboBox(@NotNull List<HgTagBranch> branches) {
branchComboBox.setModel(new DefaultComboBoxModel(branches.toArray()));
}
private void update() {
setOKActionEnabled(validateOptions());
revisionTxt.setEnabled(revisionCbx.isSelected());
@@ -213,5 +219,4 @@ public class HgPushDialog extends DialogWrapper {
update();
}
}
}
@@ -12,10 +12,10 @@
// limitations under the License.
package org.zmlx.hg4idea.ui;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.ui.IdeBorderFactory;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.zmlx.hg4idea.repo.HgRepository;
import javax.swing.*;
import java.awt.event.ActionListener;
@@ -25,54 +25,31 @@ public class HgRepositorySelectorComponent {
private JComboBox repositorySelector;
private JPanel mainPanel;
public void setRoots(Collection<VirtualFile> roots) {
public void setRoots(Collection<HgRepository> roots) {
DefaultComboBoxModel model = new DefaultComboBoxModel();
for (VirtualFile repo : roots) {
model.addElement(new RepositoryDisplay(repo));
for (HgRepository repo : roots) {
model.addElement(repo);
}
repositorySelector.setModel(model);
mainPanel.setVisible(roots.size() > 1);
}
public void setSelectedRoot(@Nullable VirtualFile repository) {
public void setSelectedRoot(@Nullable HgRepository repository) {
if (repository != null) {
repositorySelector.setSelectedItem(new RepositoryDisplay(repository));
repositorySelector.setSelectedItem(repository);
}
}
public void addActionListener(ActionListener actionListener) {
public void addActionListener(@NotNull ActionListener actionListener) {
repositorySelector.addActionListener(actionListener);
}
public void setTitle(String title) {
public void setTitle(@NotNull String title) {
mainPanel.setBorder(IdeBorderFactory.createTitledBorder(title, true));
}
public VirtualFile getRepository() {
return ((RepositoryDisplay) repositorySelector.getSelectedItem()).repo;
@NotNull
public HgRepository getRepository() {
return (HgRepository)repositorySelector.getSelectedItem();
}
private class RepositoryDisplay {
@NotNull private final VirtualFile repo;
public RepositoryDisplay(@NotNull VirtualFile repo) {
this.repo = repo;
}
@Override
public String toString() {
return repo.getPresentableUrl();
}
@Override
public boolean equals(Object obj) {
return obj instanceof RepositoryDisplay && this.repo.equals(((RepositoryDisplay)obj).repo);
}
@Override
public int hashCode() {
return repo.hashCode();
}
}
}
@@ -18,10 +18,12 @@ import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.Consumer;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.zmlx.hg4idea.HgFile;
import org.zmlx.hg4idea.command.HgResolveCommand;
import org.zmlx.hg4idea.command.HgResolveStatusEnum;
import org.zmlx.hg4idea.repo.HgRepository;
import javax.swing.*;
import java.awt.event.ActionEvent;
@@ -37,7 +39,9 @@ public class HgRunConflictResolverDialog extends DialogWrapper {
private final Project project;
public HgRunConflictResolverDialog(Project project) {
public HgRunConflictResolverDialog(@NotNull Project project,
@NotNull Collection<HgRepository> repositories,
@Nullable HgRepository selectedRepo) {
super(project, false);
this.project = project;
repositorySelector.addActionListener(new ActionListener() {
@@ -47,14 +51,16 @@ public class HgRunConflictResolverDialog extends DialogWrapper {
});
setTitle("Resolve Conflicts");
init();
setRoots(repositories, selectedRepo);
}
public VirtualFile getRepository() {
@NotNull
public HgRepository getRepository() {
return repositorySelector.getRepository();
}
public void setRoots(Collection<VirtualFile> repos, @Nullable VirtualFile selectedRepo) {
repositorySelector.setRoots(repos);
private void setRoots(@NotNull Collection<HgRepository> repositories, @Nullable HgRepository selectedRepo) {
repositorySelector.setRoots(repositories);
repositorySelector.setSelectedRoot(selectedRepo);
onChangeRepository();
}
@@ -64,7 +70,7 @@ public class HgRunConflictResolverDialog extends DialogWrapper {
}
private void onChangeRepository() {
VirtualFile repo = repositorySelector.getRepository();
VirtualFile repo = repositorySelector.getRepository().getRoot();
HgResolveCommand command = new HgResolveCommand(project);
final ModalityState modalityState = ApplicationManager.getApplication().getModalityStateForComponent(getRootPane());
command.list(repo, new Consumer<Map<HgFile, HgResolveStatusEnum>>() {
@@ -90,5 +96,4 @@ public class HgRunConflictResolverDialog extends DialogWrapper {
}
});
}
}
@@ -16,7 +16,9 @@ import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VirtualFile;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.zmlx.hg4idea.repo.HgRepository;
import javax.swing.*;
import javax.swing.event.DocumentEvent;
@@ -29,7 +31,7 @@ public class HgTagDialog extends DialogWrapper {
private JTextField tagTxt;
private HgRepositorySelectorComponent hgRepositorySelectorComponent;
public HgTagDialog(Project project) {
public HgTagDialog(@NotNull Project project, @NotNull Collection<HgRepository> repos, @Nullable HgRepository selectedRepo) {
super(project, false);
hgRepositorySelectorComponent.setTitle("Select repository to tag");
DocumentListener documentListener = new DocumentListener() {
@@ -50,6 +52,8 @@ public class HgTagDialog extends DialogWrapper {
setTitle("Tag");
init();
setRoots(repos, selectedRepo);
}
public String getTagName() {
@@ -57,10 +61,10 @@ public class HgTagDialog extends DialogWrapper {
}
public VirtualFile getRepository() {
return hgRepositorySelectorComponent.getRepository();
return hgRepositorySelectorComponent.getRepository().getRoot();
}
public void setRoots(Collection<VirtualFile> repos, @Nullable VirtualFile selectedRepo) {
private void setRoots(@NotNull Collection<HgRepository> repos, @Nullable HgRepository selectedRepo) {
hgRepositorySelectorComponent.setRoots(repos);
hgRepositorySelectorComponent.setSelectedRoot(selectedRepo);
update();
@@ -77,5 +81,4 @@ public class HgTagDialog extends DialogWrapper {
private boolean validateOptions() {
return !StringUtil.isEmptyOrSpaces(tagTxt.getText());
}
}
@@ -13,141 +13,30 @@
package org.zmlx.hg4idea.ui;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.ui.IdeBorderFactory;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.zmlx.hg4idea.command.HgTagBranch;
import org.zmlx.hg4idea.util.HgBranchesAndTags;
import org.zmlx.hg4idea.util.HgUiUtil;
import org.zmlx.hg4idea.repo.HgRepository;
import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Collection;
import java.util.Map;
public class HgUpdateToDialog extends DialogWrapper {
public class HgUpdateToDialog extends HgCommonDialogWithChoices {
private final Project project;
private JPanel contentPanel;
private JRadioButton branchOption;
private JRadioButton revisionOption;
private JRadioButton tagOption;
private JRadioButton bookmarkOption;
private JTextField revisionTxt;
private JCheckBox cleanCbx;
private JComboBox branchSelector;
private JComboBox tagSelector;
private JComboBox bookmarkSelector;
private HgRepositorySelectorComponent hgRepositorySelectorComponent;
@NotNull private Map<VirtualFile, Collection<HgTagBranch>> branchesForRepos;
@NotNull private Map<VirtualFile, Collection<HgTagBranch>> tagsForRepos;
@NotNull private Map<VirtualFile, Collection<HgTagBranch>> bookmarksForRepos;
public HgUpdateToDialog(Project project) {
super(project, false);
this.project = project;
public HgUpdateToDialog(Project project, @NotNull Collection<HgRepository> repos, @Nullable HgRepository selectedRepo) {
super(project, repos, selectedRepo);
myBranchesBorderPanel.setBorder(IdeBorderFactory.createTitledBorder("Switch to", true));
hgRepositorySelectorComponent.setTitle("Select repository to switch");
hgRepositorySelectorComponent.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
updateRepository();
}
});
ChangeListener changeListener = new ChangeListener() {
public void stateChanged(ChangeEvent e) {
update();
}
};
branchOption.addChangeListener(changeListener);
tagOption.addChangeListener(changeListener);
bookmarkOption.addChangeListener(changeListener);
revisionOption.addChangeListener(changeListener);
setTitle("Switch working directory");
init();
}
public void setRoots(Collection<VirtualFile> repos,
@Nullable VirtualFile selectedRepo, HgBranchesAndTags branchesAndTags) {
hgRepositorySelectorComponent.setRoots(repos);
branchesForRepos = branchesAndTags.getBranchesForRepos();
tagsForRepos = branchesAndTags.getTagsForRepos();
bookmarksForRepos = branchesAndTags.getBookmarksForRepos();
hgRepositorySelectorComponent.setSelectedRoot(selectedRepo);
updateRepository();
}
public VirtualFile getRepository() {
return hgRepositorySelectorComponent.getRepository();
}
public HgTagBranch getTag() {
return (HgTagBranch) tagSelector.getSelectedItem();
}
public boolean isTagSelected() {
return tagOption.isSelected();
}
public HgTagBranch getBranch() {
return (HgTagBranch) branchSelector.getSelectedItem();
}
public boolean isBranchSelected() {
return branchOption.isSelected();
}
public HgTagBranch getBookmark() {
return (HgTagBranch)bookmarkSelector.getSelectedItem();
}
public boolean isBookmarkSelected() {
return bookmarkOption.isSelected();
}
public String getRevision() {
return revisionTxt.getText();
}
public boolean isRevisionSelected() {
return revisionOption.isSelected();
setTitle("Switch Working Directory");
cleanCbx.setVisible(true);
cleanCbx.setEnabled(true);
}
public boolean isRemoveLocalChanges() {
return cleanCbx.isSelected();
}
private void update() {
revisionTxt.setEnabled(revisionOption.isSelected());
branchSelector.setEnabled(branchOption.isSelected());
tagSelector.setEnabled(tagOption.isSelected());
bookmarkSelector.setEnabled(bookmarkOption.isSelected());
}
private void updateRepository() {
VirtualFile repo = hgRepositorySelectorComponent.getRepository();
HgUiUtil.loadContentToDialog(repo, branchesForRepos, branchSelector);
HgUiUtil.loadContentToDialog(repo, tagsForRepos, tagSelector);
HgUiUtil.loadContentToDialog(repo, bookmarksForRepos, bookmarkSelector);
update();
}
protected JComponent createCenterPanel() {
return contentPanel;
}
@Override
protected String getHelpId() {
return "reference.mercurial.switch.working.directory";
}
@Override
protected String getDimensionServiceKey() {
return getClass().getName();
}
}
@@ -1,62 +0,0 @@
/*
* 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.util;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
import org.zmlx.hg4idea.command.HgTagBranch;
import java.util.Collection;
import java.util.Map;
/**
* @author Nadya Zabrodina
*/
public class HgBranchesAndTags {
@NotNull private final Map<VirtualFile, Collection<HgTagBranch>> branchesForRepos = ContainerUtil.newHashMap();
@NotNull private final Map<VirtualFile, Collection<HgTagBranch>> tagsForRepos = ContainerUtil.newHashMap();
@NotNull private final Map<VirtualFile, Collection<HgTagBranch>> bookmarks = ContainerUtil.newHashMap();
@NotNull
public Map<VirtualFile, Collection<HgTagBranch>> getBranchesForRepos() {
return branchesForRepos;
}
public void addBranches(@NotNull VirtualFile repo, @NotNull Collection<HgTagBranch> branches) {
branchesForRepos.put(repo, branches);
}
@NotNull
public Map<VirtualFile, Collection<HgTagBranch>> getTagsForRepos() {
return tagsForRepos;
}
public void addTags(@NotNull VirtualFile repo, @NotNull Collection<HgTagBranch> tags) {
tagsForRepos.put(repo, tags);
}
@NotNull
public Map<VirtualFile, Collection<HgTagBranch>> getBookmarksForRepos() {
return bookmarks;
}
public void addBookmarks(@NotNull VirtualFile repo, @NotNull Collection<HgTagBranch> tags) {
bookmarks.put(repo, tags);
}
}
@@ -1,89 +0,0 @@
/*
* 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.util;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.progress.Task;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.Consumer;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.zmlx.hg4idea.HgVcsMessages;
import org.zmlx.hg4idea.action.HgCommandResultNotifier;
import org.zmlx.hg4idea.command.HgTagBranch;
import org.zmlx.hg4idea.command.HgTagBranchCommand;
import org.zmlx.hg4idea.execution.HgCommandResult;
import javax.swing.*;
import java.util.Collection;
import java.util.Map;
/**
* @author Nadya Zabrodina
*/
public class HgUiUtil {
public static void loadBranchesInBackgroundableAndExecuteAction(@NotNull final Project project,
@NotNull final Collection<VirtualFile> repos,
@NotNull final Consumer<HgBranchesAndTags> successHandler) {
final HgBranchesAndTags branchTagInfo = new HgBranchesAndTags();
new Task.Backgroundable(project, "Collecting information...") {
@Override
public void run(@NotNull ProgressIndicator indicator) {
for (final VirtualFile repo : repos) {
HgTagBranchCommand tagBranchCommand = new HgTagBranchCommand(project, repo);
HgCommandResult result = tagBranchCommand.collectBranches();
if (result == null) {
indicator.cancel();
return;
}
branchTagInfo.addBranches(repo, HgTagBranchCommand.parseResult(result));
result = tagBranchCommand.collectTags();
if (result == null) {
indicator.cancel();
return;
}
branchTagInfo.addTags(repo, HgTagBranchCommand.parseResult(result));
result = tagBranchCommand.collectBookmarks();
if (result == null) {
indicator.cancel();
return;
}
branchTagInfo.addBookmarks(repo, HgTagBranchCommand.parseResult(result));
}
}
@Override
public void onCancel() {
new HgCommandResultNotifier(project)
.notifyError(null, "Mercurial command failed", HgVcsMessages.message("hg4idea.branches.error.description"));
}
@Override
public void onSuccess() {
successHandler.consume(branchTagInfo);
}
}.queue();
}
public static void loadContentToDialog(@Nullable VirtualFile root, @NotNull Map<VirtualFile, Collection<HgTagBranch>> contentMap,
@NotNull JComboBox selector) {
assert contentMap.get(root) != null : "No information about root " + root;
selector.setModel(new DefaultComboBoxModel(contentMap.get(root).toArray()));
}
}
@@ -611,6 +611,11 @@ public abstract class HgUtil {
return hgRepository.getRepositoryConfig().getDefaultPushPath();
}
@Nullable
public static String getRepositoryDefaultPushPath(@NotNull HgRepository repository) {
return repository.getRepositoryConfig().getDefaultPushPath();
}
@Nullable
public static String getConfig(@NotNull Project project,
@NotNull VirtualFile root,