diff options
Diffstat (limited to 'platform/dvcs-impl/src/com/intellij/dvcs/push/PushController.java')
-rw-r--r-- | platform/dvcs-impl/src/com/intellij/dvcs/push/PushController.java | 131 |
1 files changed, 61 insertions, 70 deletions
diff --git a/platform/dvcs-impl/src/com/intellij/dvcs/push/PushController.java b/platform/dvcs-impl/src/com/intellij/dvcs/push/PushController.java index 45f5c68e1d0a..cd0cc7a1ef7a 100644 --- a/platform/dvcs-impl/src/com/intellij/dvcs/push/PushController.java +++ b/platform/dvcs-impl/src/com/intellij/dvcs/push/PushController.java @@ -20,31 +20,32 @@ import com.intellij.dvcs.push.ui.*; import com.intellij.dvcs.repo.Repository; import com.intellij.dvcs.repo.RepositoryManager; import com.intellij.openapi.Disposable; -import com.intellij.openapi.application.ModalityState; import com.intellij.openapi.extensions.Extensions; import com.intellij.openapi.progress.ProgressIndicator; import com.intellij.openapi.progress.Task; -import com.intellij.openapi.progress.impl.ProgressManagerImpl; import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.MessageType; import com.intellij.openapi.ui.ValidationInfo; +import com.intellij.openapi.ui.popup.util.PopupUtil; import com.intellij.openapi.util.Condition; import com.intellij.openapi.util.Disposer; -import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vcs.AbstractVcs; import com.intellij.ui.CheckedTreeNode; -import com.intellij.ui.SimpleColoredText; -import com.intellij.ui.SimpleTextAttributes; import com.intellij.util.Function; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.containers.hash.HashMap; +import com.intellij.util.ui.UIUtil; import com.intellij.vcs.log.VcsFullCommitDetails; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import javax.swing.*; import javax.swing.tree.DefaultMutableTreeNode; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.*; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; import java.util.concurrent.atomic.AtomicReference; public class PushController implements Disposable { @@ -56,6 +57,7 @@ public class PushController implements Disposable { private boolean mySingleRepoProject; private static final int DEFAULT_CHILDREN_PRESENTATION_NUMBER = 20; private final Map<PushSupport, MyPushOptionValueModel> myAdditionalValuesMap; + private final ExecutorService myExecutorService = Executors.newSingleThreadExecutor(); private final Map<RepositoryNode, MyRepoModel> myView2Model = new TreeMap<RepositoryNode, MyRepoModel>(); //todo need to sort repositories in ui tree using natural order @@ -162,33 +164,31 @@ public class PushController implements Disposable { if (target == null) { model.setError(VcsError.createEmptyTargetError(repoName)); } - RepositoryWithBranchPanel repoPanel = new RepositoryWithBranchPanel(myProject, repoName, - support.getSource(repository).getPresentation(), - target == null ? "" : target.getPresentation(), - support.getTargetNames(repository)); + final PushTargetPanel<T> pushTargetPanel = support.createTargetPanel(repository, target); + RepositoryWithBranchPanel<T> repoPanel = + new RepositoryWithBranchPanel<T>(repoName, support.getSource(repository).getPresentation(), pushTargetPanel); + repoPanel.setInputVerifier(new InputVerifier() { + @Override + public boolean verify(JComponent input) { + ValidationInfo error = pushTargetPanel.verify(); + if (error != null) { + //noinspection ConstantConditions + PopupUtil.showBalloonForComponent(error.component, error.message, MessageType.WARNING, false, myProject); + } + return error == null; + } + }); final RepositoryNode repoNode = isSingleRepositoryProject - ? new SingleRepositoryNode(repoPanel, support.renderTarget(target)) - : new RepositoryNode(repoPanel, support.renderTarget(target)); + ? new SingleRepositoryNode(repoPanel) + : new RepositoryNode(repoPanel); myView2Model.put(repoNode, model); repoNode.setChecked(model.isSelected()); - repoPanel.addRepoNodeListener(new RepositoryNodeListener() { + repoPanel.addRepoNodeListener(new RepositoryNodeListener<T>() { @Override - public void onTargetChanged(String newValue) { - VcsError validationError = support.validate(model.getRepository(), newValue); - if (validationError == null) { - T newTarget = support.createTarget(repository, newValue); - repoNode.setTargetPresentation(support.renderTarget(newTarget)); - model.setTarget(newTarget); - model.clearErrors(); - loadCommits(model, repoNode, false); - } - else { - repoNode.setTargetPresentation(StringUtil.isEmptyOrSpaces(newValue) - ? support.renderTarget(null) - : new SimpleColoredText(newValue, SimpleTextAttributes.ERROR_ATTRIBUTES)); - model.setError(validationError); // todo may be should accept and store errors collection, now store one major target error - model.setTarget(null); - } + public void onTargetChanged(T newTarget) { + model.setTarget(newTarget); + model.clearErrors(); + loadCommits(model, repoNode, false); myDialog.updateButtons(); } @@ -209,56 +209,49 @@ public class PushController implements Disposable { final T target = model.getTarget(); if (target == null) return; //todo should be removed when commit loader executor will be modified myPushLog.startLoading(node); - final ProgressIndicator indicator = node.startLoading(); final PushSupport<R, S, T> support = model.getSupport(); final AtomicReference<OutgoingResult> result = new AtomicReference<OutgoingResult>(); - Task.Backgroundable task = new Task.Backgroundable(myProject, "Loading Commits", true) { - + Runnable task = new Runnable() { @Override - public void onCancel() { - node.stopLoading(); - } - - @Override - public void onSuccess() { - OutgoingResult outgoing = result.get(); - List<VcsError> errors = outgoing.getErrors(); - if (!errors.isEmpty()) { - myPushLog.setChildren(node, ContainerUtil.map(errors, new Function<VcsError, DefaultMutableTreeNode>() { - @Override - public DefaultMutableTreeNode fun(final VcsError error) { - VcsLinkedText errorLinkText = new VcsLinkedText(error.getText(), new VcsLinkListener() { + public void run() { + OutgoingResult outgoing = support.getOutgoingCommitsProvider() + .getOutgoingCommits(model.getRepository(), new PushSpec<S, T>(model.getSource(), model.getTarget()), initial); + result.compareAndSet(null, outgoing); + UIUtil.invokeAndWaitIfNeeded(new Runnable() { + @Override + public void run() { + OutgoingResult outgoing = result.get(); + List<VcsError> errors = outgoing.getErrors(); + if (!errors.isEmpty()) { + myPushLog.setChildren(node, ContainerUtil.map(errors, new Function<VcsError, DefaultMutableTreeNode>() { @Override - public void hyperlinkActivated(@NotNull DefaultMutableTreeNode sourceNode) { - error.handleError(new CommitLoader() { + public DefaultMutableTreeNode fun(final VcsError error) { + VcsLinkedText errorLinkText = new VcsLinkedText(error.getText(), new VcsLinkListener() { @Override - public void reloadCommits() { - loadCommits(model, node, false); + public void hyperlinkActivated(@NotNull DefaultMutableTreeNode sourceNode) { + error.handleError(new CommitLoader() { + @Override + public void reloadCommits() { + loadCommits(model, node, false); + } + }); } }); + return new TextWithLinkNode(errorLinkText); } - }); - return new TextWithLinkNode(errorLinkText); + }), model.isSelected()); } - }), model.isSelected()); - } - else { - model.setLoadedCommits(outgoing.getCommits()); - myPushLog.setChildren(node, - getPresentationForCommits(PushController.this.myProject, model.getLoadedCommits(), - model.getNumberOfShownCommits()), model.isSelected()); - } - } - - @Override - public void run(@NotNull ProgressIndicator indicator) { - OutgoingResult outgoing = support.getOutgoingCommitsProvider() - .getOutgoingCommits(model.getRepository(), new PushSpec<S, T>(model.getSource(), model.getTarget()), initial); - result.compareAndSet(null, outgoing); + else { + model.setLoadedCommits(outgoing.getCommits()); + myPushLog.setChildren(node, + getPresentationForCommits(PushController.this.myProject, model.getLoadedCommits(), + model.getNumberOfShownCommits()), model.isSelected()); + } + } + }); } }; - - ProgressManagerImpl.runProcessWithProgressAsynchronously(task, indicator, null, ModalityState.any()); + node.startLoading(myExecutorService.submit(task, result)); } public PushLog getPushPanelLog() { @@ -315,9 +308,7 @@ public class PushController implements Disposable { @Override public void dispose() { - for (RepositoryNode node : myView2Model.keySet()) { - node.stopLoading(); - } + myExecutorService.shutdownNow(); } private void addMoreCommits(RepositoryNode repositoryNode) { |