diff --git a/.idea/libraries/JSch.xml b/.idea/libraries/JSch.xml index 196b08ba1091..27c51c853ea3 100644 --- a/.idea/libraries/JSch.xml +++ b/.idea/libraries/JSch.xml @@ -1,12 +1,12 @@ - + - - + + \ No newline at end of file diff --git a/build/scripts/libLicenses.gant b/build/scripts/libLicenses.gant index 081cc4cfccc1..cdf6fb10c823 100644 --- a/build/scripts/libLicenses.gant +++ b/build/scripts/libLicenses.gant @@ -196,7 +196,7 @@ libraryLicense(name: "JGoodies Forms", libraryName: "jgoodies-forms", version: " libraryLicense(name: "JGoodies Looks", libraryName: "jgoodies-looks", version: "2.4.2", license: "BSD ", url: "http://www.jgoodies.com/freeware/looks/", licenseUrl: "http://www.jgoodies.com/downloads/libraries.html") libraryLicense(name: "JGoodies Common", libraryName: "jgoodies-common", version: "1.2.1", license: "BSD ", url: "http://www.jgoodies.com/freeware/looks/", licenseUrl: "http://www.jgoodies.com/downloads/libraries.html") libraryLicense(name: "JNA", libraryName: "jna", version: "3.4.0", license: "LGPL 2.1", url: "https://jna.dev.java.net/", licenseUrl: "http://www.opensource.org/licenses/lgpl-2.1.php") -libraryLicense(name: "JSch", libraryName: "JSch", version: "0.1.50", license: "BSD", url: "http://www.jcraft.com/jsch/", licenseUrl: "http://www.jcraft.com/jsch/LICENSE.txt") +libraryLicense(name: "JSch", libraryName: "JSch", version: "0.1.51", license: "BSD", url: "http://www.jcraft.com/jsch/", licenseUrl: "http://www.jcraft.com/jsch/LICENSE.txt") libraryLicense(name: "jsch-agent-proxy", libraryName: "jsch-agent-proxy", version: "0.0.6", license: "BSD", url: "https://github.com/ymnk/jsch-agent-proxy", licenseUrl: "https://github.com/ymnk/jsch-agent-proxy/blob/master/LICENSE.txt") libraryLicense(name: "jsch-agent-proxy for svnkit trilead", libraryName: "jsch.agentproxy.svnkit-trilead-ssh2.jar", version: "0.0.6", license: "BSD", url: "https://github.com/ymnk/jsch-agent-proxy", licenseUrl: "https://github.com/ymnk/jsch-agent-proxy/blob/master/LICENSE.txt") libraryLicense(name: "JUnit", libraryName: "JUnit3", version: "3.8.1", license: "CPL 1.0", url: "http://junit.org/") diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/EvaluationDescriptor.java b/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/EvaluationDescriptor.java index 1f880513cacd..510a74e9e579 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/EvaluationDescriptor.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/EvaluationDescriptor.java @@ -27,12 +27,14 @@ import com.intellij.debugger.engine.evaluation.expression.Modifier; import com.intellij.debugger.impl.DebuggerUtilsEx; import com.intellij.debugger.impl.PositionUtil; import com.intellij.debugger.jdi.StackFrameProxyImpl; +import com.intellij.debugger.jdi.VirtualMachineProxyImpl; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.registry.Registry; import com.intellij.psi.PsiCodeFragment; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiExpression; import com.intellij.psi.PsiExpressionCodeFragment; +import com.sun.jdi.ObjectCollectedException; import com.sun.jdi.ObjectReference; import com.sun.jdi.Value; import org.jetbrains.annotations.NotNull; @@ -106,7 +108,11 @@ public abstract class EvaluationDescriptor extends ValueDescriptorImpl{ final Value value = evaluator.evaluate(thisEvaluationContext); if (value instanceof ObjectReference) { - thisEvaluationContext.getSuspendContext().keep(((ObjectReference)value)); + ObjectReference objRef = (ObjectReference)value; + if (VirtualMachineProxyImpl.isCollected(objRef)) { + throw EvaluateExceptionUtil.OBJECT_WAS_COLLECTED; + } + thisEvaluationContext.getSuspendContext().keep(objRef); } myModifier = evaluator.getModifier(); setLvalue(myModifier != null); @@ -116,6 +122,9 @@ public abstract class EvaluationDescriptor extends ValueDescriptorImpl{ catch (final EvaluateException ex) { throw new EvaluateException(ex.getLocalizedMessage(), ex); } + catch (ObjectCollectedException ex) { + throw EvaluateExceptionUtil.OBJECT_WAS_COLLECTED; + } } public String calcValueName() { diff --git a/lib/jsch-0.1.50.jar b/lib/jsch-0.1.50.jar deleted file mode 100644 index de6cd0cda26b..000000000000 Binary files a/lib/jsch-0.1.50.jar and /dev/null differ diff --git a/lib/jsch-0.1.51.jar b/lib/jsch-0.1.51.jar new file mode 100644 index 000000000000..70d13988ccec Binary files /dev/null and b/lib/jsch-0.1.51.jar differ diff --git a/lib/required_for_dist.txt b/lib/required_for_dist.txt index 094e94784836..05d8f7e23aeb 100644 --- a/lib/required_for_dist.txt +++ b/lib/required_for_dist.txt @@ -30,7 +30,7 @@ jgoodies-looks-2.4.2.jar jh.jar jna-utils.jar jna.jar -jsch-0.1.50.jar +jsch-0.1.51.jar jsch.agentproxy.connector-factory.jar jsch.agentproxy.core.jar jsch.agentproxy.pageant.jar diff --git a/lib/src/jsch-0.1.50.zip b/lib/src/jsch-0.1.50.zip deleted file mode 100644 index a90c40d2f272..000000000000 Binary files a/lib/src/jsch-0.1.50.zip and /dev/null differ diff --git a/lib/src/jsch-0.1.51.zip b/lib/src/jsch-0.1.51.zip new file mode 100644 index 000000000000..f4652c479d8c Binary files /dev/null and b/lib/src/jsch-0.1.51.zip differ diff --git a/platform/dvcs-api/src/com/intellij/dvcs/push/PushSupport.java b/platform/dvcs-api/src/com/intellij/dvcs/push/PushSupport.java index fbf6f148c3b1..d4939070038e 100644 --- a/platform/dvcs-api/src/com/intellij/dvcs/push/PushSupport.java +++ b/platform/dvcs-api/src/com/intellij/dvcs/push/PushSupport.java @@ -19,12 +19,9 @@ import com.intellij.dvcs.repo.Repository; import com.intellij.dvcs.repo.RepositoryManager; import com.intellij.openapi.extensions.ExtensionPointName; import com.intellij.openapi.vcs.AbstractVcs; -import com.intellij.ui.SimpleColoredText; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.util.List; - /** * Base class to provide vcs-specific info */ @@ -49,27 +46,12 @@ public abstract class PushSupport getTargetNames(@NotNull Repo repository); - /** * @return current source(branch) for repository */ @NotNull public abstract Source getSource(@NotNull Repo repository); - /** - * Parse user input string, and create the VALID target for push - * - * @see #validateSpec(Repository, PushSpec) - */ - @NotNull - public abstract Target createTarget(@NotNull Repo repository, @NotNull String targetName); - /** * @return RepositoryManager for vcs */ @@ -81,11 +63,6 @@ public abstract class PushSupport createTargetEditor(@NotNull Repo repository, @NotNull String defaultTargetName); } diff --git a/platform/dvcs-api/src/com/intellij/dvcs/push/TargetEditor.java b/platform/dvcs-api/src/com/intellij/dvcs/push/TargetEditor.java new file mode 100644 index 000000000000..0dfda391f401 --- /dev/null +++ b/platform/dvcs-api/src/com/intellij/dvcs/push/TargetEditor.java @@ -0,0 +1,45 @@ +/* + * 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 com.intellij.dvcs.push; + +import com.intellij.ui.ColoredTreeCellRenderer; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import javax.swing.*; +import java.awt.*; + +public abstract class TargetEditor extends JPanel { + + protected TargetEditor(BorderLayout layout) { + super(layout); + } + + abstract public void render(@NotNull ColoredTreeCellRenderer renderer); + + @NotNull + abstract public T getValue(); + + public abstract void fireOnCancel(); + + public abstract void fireOnChange(); + + @Nullable + public abstract VcsError verify(); + + @NotNull + public abstract JComponent getVerifiedComponent(); +} diff --git a/platform/dvcs-api/src/com/intellij/dvcs/push/VcsError.java b/platform/dvcs-api/src/com/intellij/dvcs/push/VcsError.java index b76095629ccd..e6c0e210429a 100644 --- a/platform/dvcs-api/src/com/intellij/dvcs/push/VcsError.java +++ b/platform/dvcs-api/src/com/intellij/dvcs/push/VcsError.java @@ -42,6 +42,6 @@ public class VcsError { } public static VcsError createEmptyTargetError(@NotNull String name) { - return new VcsError("Please, specify remote push path for repository " + name + "."); + return new VcsError("Please, specify not empty remote push path for repository " + name + "."); } } 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..e809bcabb354 100644 --- a/platform/dvcs-impl/src/com/intellij/dvcs/push/PushController.java +++ b/platform/dvcs-impl/src/com/intellij/dvcs/push/PushController.java @@ -26,14 +26,13 @@ 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; @@ -41,6 +40,7 @@ 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; @@ -162,33 +162,30 @@ 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 TargetEditor targetEditor = support.createTargetEditor(repository, target == null ? "" : target.getPresentation()); + RepositoryWithBranchPanel repoPanel = + new RepositoryWithBranchPanel(repoName, support.getSource(repository).getPresentation(), targetEditor); + repoPanel.setInputVerifier(new InputVerifier() { + @Override + public boolean verify(JComponent input) { + VcsError error = targetEditor.verify(); + if (error != null) { + PopupUtil.showBalloonForComponent(targetEditor.getVerifiedComponent(), error.getText(), 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() { @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(); } diff --git a/platform/dvcs-impl/src/com/intellij/dvcs/push/RepositoryNodeListener.java b/platform/dvcs-impl/src/com/intellij/dvcs/push/RepositoryNodeListener.java index 7ca285fc95aa..91bb711cc384 100644 --- a/platform/dvcs-impl/src/com/intellij/dvcs/push/RepositoryNodeListener.java +++ b/platform/dvcs-impl/src/com/intellij/dvcs/push/RepositoryNodeListener.java @@ -15,9 +15,9 @@ */ package com.intellij.dvcs.push; -public interface RepositoryNodeListener { +public interface RepositoryNodeListener { - void onTargetChanged(String newValue); + void onTargetChanged(T newTarget); void onSelectionChanged(boolean isSelected); } diff --git a/platform/dvcs-impl/src/com/intellij/dvcs/push/ui/EditableTreeNode.java b/platform/dvcs-impl/src/com/intellij/dvcs/push/ui/EditableTreeNode.java index b5747de91bf7..0d291bbb78c8 100644 --- a/platform/dvcs-impl/src/com/intellij/dvcs/push/ui/EditableTreeNode.java +++ b/platform/dvcs-impl/src/com/intellij/dvcs/push/ui/EditableTreeNode.java @@ -30,6 +30,4 @@ public interface EditableTreeNode extends CustomRenderedTreeNode { @NotNull ProgressIndicator startLoading(); - - String getValue(); } diff --git a/platform/dvcs-impl/src/com/intellij/dvcs/push/ui/PushLog.java b/platform/dvcs-impl/src/com/intellij/dvcs/push/ui/PushLog.java index 0b4bcb0fbef0..ed694c3c0b87 100644 --- a/platform/dvcs-impl/src/com/intellij/dvcs/push/ui/PushLog.java +++ b/platform/dvcs-impl/src/com/intellij/dvcs/push/ui/PushLog.java @@ -15,6 +15,7 @@ */ package com.intellij.dvcs.push.ui; +import com.intellij.dvcs.push.TargetEditor; import com.intellij.openapi.actionSystem.CommonShortcuts; import com.intellij.openapi.actionSystem.DataKey; import com.intellij.openapi.actionSystem.DataSink; @@ -25,7 +26,10 @@ import com.intellij.openapi.vcs.VcsDataKeys; import com.intellij.openapi.vcs.changes.Change; import com.intellij.openapi.vcs.changes.committed.CommittedChangesTreeBrowser; import com.intellij.openapi.vcs.changes.ui.ChangesBrowser; -import com.intellij.ui.*; +import com.intellij.ui.CheckboxTree; +import com.intellij.ui.CheckedTreeNode; +import com.intellij.ui.ColoredTreeCellRenderer; +import com.intellij.ui.ScrollPaneFactory; import com.intellij.ui.components.JBTextField; import com.intellij.util.ArrayUtil; import com.intellij.util.ui.tree.TreeUtil; @@ -89,6 +93,17 @@ public class PushLog extends JPanel implements TypeSafeDataProvider { } return ""; } + + @Override + public boolean stopEditing() { + DefaultMutableTreeNode node = (DefaultMutableTreeNode)myTree.getLastSelectedPathComponent(); + if (node instanceof EditableTreeNode) { + JComponent editedComponent = (JComponent)node.getUserObject(); + InputVerifier verifier = editedComponent.getInputVerifier(); + if (verifier != null && !verifier.verify(editedComponent)) return false; + } + return super.stopEditing(); + } }; myTree.setEditable(true); MyTreeCellEditor treeCellEditor = new MyTreeCellEditor(new JBTextField()); @@ -239,7 +254,7 @@ public class PushLog extends JPanel implements TypeSafeDataProvider { Object tag = me.getClickCount() >= clickCountToStart ? PushLogTreeUtil.getTagAtForRenderer(myTreeCellRenderer, me) : null; - return tag instanceof EditorTextField; + return tag instanceof TargetEditor; } //if keyboard event - then anEvent will be null =( See BasicTreeUi TreePath treePath = myTree.getAnchorSelectionPath(); @@ -251,7 +266,7 @@ public class PushLog extends JPanel implements TypeSafeDataProvider { //Implement the one CellEditor method that AbstractCellEditor doesn't. public Object getCellEditorValue() { - return ((RepositoryWithBranchPanel)editorComponent).getRemoteTargetName(); + return ((RepositoryWithBranchPanel)editorComponent).getEditableValue(); } } diff --git a/platform/dvcs-impl/src/com/intellij/dvcs/push/ui/RepositoryNode.java b/platform/dvcs-impl/src/com/intellij/dvcs/push/ui/RepositoryNode.java index 05e752c4be85..605d3a2be071 100644 --- a/platform/dvcs-impl/src/com/intellij/dvcs/push/ui/RepositoryNode.java +++ b/platform/dvcs-impl/src/com/intellij/dvcs/push/ui/RepositoryNode.java @@ -15,29 +15,25 @@ */ package com.intellij.dvcs.push.ui; +import com.intellij.dvcs.push.TargetEditor; import com.intellij.openapi.progress.EmptyProgressIndicator; import com.intellij.openapi.progress.ProgressIndicator; -import com.intellij.ui.*; +import com.intellij.ui.CheckedTreeNode; +import com.intellij.ui.ColoredTreeCellRenderer; +import com.intellij.ui.SimpleTextAttributes; import org.jetbrains.annotations.NotNull; import javax.swing.*; import javax.swing.border.EmptyBorder; import java.awt.*; -import java.util.ArrayList; public class RepositoryNode extends CheckedTreeNode implements EditableTreeNode, Comparable { @NotNull private final RepositoryWithBranchPanel myRepositoryPanel; - @NotNull protected SimpleColoredText myTargetPresentation; private ProgressIndicator myCurrentIndicator; - public RepositoryNode(@NotNull RepositoryWithBranchPanel repositoryPanel, @NotNull SimpleColoredText targetPresentation) { + public RepositoryNode(@NotNull RepositoryWithBranchPanel repositoryPanel) { super(repositoryPanel); myRepositoryPanel = repositoryPanel; - myTargetPresentation = targetPresentation; - } - - public void setTargetPresentation(@NotNull SimpleColoredText targetPresentation) { - myTargetPresentation = targetPresentation; } public boolean isCheckboxVisible() { @@ -51,31 +47,17 @@ public class RepositoryNode extends CheckedTreeNode implements EditableTreeNode, renderer.appendFixedTextFragmentWidth(120); renderer.append(myRepositoryPanel.getSourceName(), SimpleTextAttributes.REGULAR_ATTRIBUTES); renderer.append(myRepositoryPanel.getArrow(), SimpleTextAttributes.REGULAR_ATTRIBUTES); - EditorTextField textField = myRepositoryPanel.getRemoteTextFiled(); - renderTargetName(renderer, textField); - Insets insets = BorderFactory.createEmptyBorder().getBorderInsets(textField); + TargetEditor targetEditor = myRepositoryPanel.getTargetEditor(); + targetEditor.render(renderer); + Insets insets = BorderFactory.createEmptyBorder().getBorderInsets(targetEditor); renderer.setBorder(new EmptyBorder(insets)); } - protected void renderTargetName(@NotNull ColoredTreeCellRenderer renderer, @NotNull EditorTextField textField) { - ArrayList strings = myTargetPresentation.getTexts(); - ArrayList attributes = myTargetPresentation.getAttributes(); - for (int i = 0; i < strings.size(); i++) { - renderer.append(strings.get(i), attributes.get(i), textField); - } - } - @Override public Object getUserObject() { return myRepositoryPanel; } - @Override - @NotNull - public String getValue() { - return myRepositoryPanel.getRemoteTargetName(); - } - @Override public void fireOnChange() { myRepositoryPanel.fireOnChange(); diff --git a/platform/dvcs-impl/src/com/intellij/dvcs/push/ui/RepositoryWithBranchPanel.java b/platform/dvcs-impl/src/com/intellij/dvcs/push/ui/RepositoryWithBranchPanel.java index cd93d0653c36..8b7fb9e30ecb 100644 --- a/platform/dvcs-impl/src/com/intellij/dvcs/push/ui/RepositoryWithBranchPanel.java +++ b/platform/dvcs-impl/src/com/intellij/dvcs/push/ui/RepositoryWithBranchPanel.java @@ -15,18 +15,15 @@ */ package com.intellij.dvcs.push.ui; +import com.intellij.dvcs.push.PushTarget; import com.intellij.dvcs.push.RepositoryNodeListener; -import com.intellij.openapi.editor.ex.EditorEx; -import com.intellij.openapi.project.Project; +import com.intellij.dvcs.push.TargetEditor; import com.intellij.ui.ColoredTreeCellRenderer; import com.intellij.ui.SimpleTextAttributes; -import com.intellij.ui.TextFieldWithAutoCompletion; -import com.intellij.ui.TextFieldWithAutoCompletionListProvider; import com.intellij.ui.components.JBCheckBox; import com.intellij.ui.components.JBLabel; import com.intellij.ui.components.panels.NonOpaquePanel; import com.intellij.util.containers.ContainerUtil; -import com.intellij.util.ui.UIUtil; import org.jetbrains.annotations.NotNull; import javax.swing.*; @@ -34,23 +31,20 @@ import javax.swing.tree.TreeCellRenderer; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; -import java.awt.event.FocusAdapter; -import java.awt.event.FocusEvent; import java.util.List; -public class RepositoryWithBranchPanel extends NonOpaquePanel implements TreeCellRenderer { +public class RepositoryWithBranchPanel extends NonOpaquePanel implements TreeCellRenderer { private final JBCheckBox myRepositoryCheckbox; - private final TextFieldWithAutoCompletion myDestBranchTextField; + private final TargetEditor myDestTargetEditorComponent; private final JBLabel myLocalBranch; private final JLabel myArrowLabel; private final JLabel myRepositoryLabel; private final ColoredTreeCellRenderer myTextRenderer; - @NotNull private final List myListeners = ContainerUtil.createLockFreeCopyOnWriteList(); - private String myOldDestination; + @NotNull private final List> myListeners = ContainerUtil.createLockFreeCopyOnWriteList(); - public RepositoryWithBranchPanel(Project project, @NotNull String repoName, - @NotNull String sourceName, String targetName, @NotNull final List targetVariants) { + public RepositoryWithBranchPanel(@NotNull String repoName, + @NotNull String sourceName, @NotNull TargetEditor destTargetEditorComponent) { super(); setLayout(new BorderLayout()); myRepositoryCheckbox = new JBCheckBox(); @@ -65,37 +59,7 @@ public class RepositoryWithBranchPanel extends NonOpaquePanel implements TreeCel myRepositoryLabel = new JLabel(repoName); myLocalBranch = new JBLabel(sourceName); myArrowLabel = new JLabel(" -> "); - myOldDestination = targetName; - TextFieldWithAutoCompletionListProvider provider = - new TextFieldWithAutoCompletion.StringsCompletionProvider(targetVariants, null) { - @Override - public int compare(String item1, String item2) { - return Integer.valueOf(ContainerUtil.indexOf(targetVariants, item1)).compareTo(ContainerUtil.indexOf(targetVariants, item2)); - } - }; - myDestBranchTextField = new TextFieldWithAutoCompletion(project, provider, true, targetName) { - - @Override - public boolean shouldHaveBorder() { - return false; - } - - @Override - protected void updateBorder(@NotNull final EditorEx editor) { - } - }; - myDestBranchTextField.setBorder(UIUtil.getTableFocusCellHighlightBorder()); - myDestBranchTextField.setOneLineMode(true); - myDestBranchTextField.setOpaque(true); - FocusAdapter focusListener = new FocusAdapter() { - @Override - public void focusGained(FocusEvent e) { - myDestBranchTextField.selectAll(); - } - }; - myDestBranchTextField.addFocusListener(focusListener); - addFocusListener(focusListener); - + myDestTargetEditorComponent = destTargetEditorComponent; myTextRenderer = new ColoredTreeCellRenderer() { public void customizeCellRenderer(@NotNull JTree tree, Object value, @@ -115,7 +79,7 @@ public class RepositoryWithBranchPanel extends NonOpaquePanel implements TreeCel add(myRepositoryCheckbox, BorderLayout.WEST); JPanel panel = new NonOpaquePanel(new BorderLayout()); panel.add(myTextRenderer, BorderLayout.WEST); - panel.add(myDestBranchTextField, BorderLayout.CENTER); + panel.add(myDestTargetEditorComponent, BorderLayout.CENTER); add(panel, BorderLayout.CENTER); } @@ -132,15 +96,6 @@ public class RepositoryWithBranchPanel extends NonOpaquePanel implements TreeCel return myArrowLabel.getText(); } - public TextFieldWithAutoCompletion getRemoteTextFiled() { - return myDestBranchTextField; - } - - @NotNull - public String getRemoteTargetName() { - return myDestBranchTextField.getText(); - } - @Override public Component getTreeCellRendererComponent(JTree tree, Object value, @@ -168,20 +123,20 @@ public class RepositoryWithBranchPanel extends NonOpaquePanel implements TreeCel if (bounds != null) { setPreferredSize(new Dimension(tree.getWidth() - bounds.x, bounds.height)); } - myDestBranchTextField.grabFocus(); - myDestBranchTextField.requestFocus(); + myDestTargetEditorComponent.grabFocus(); + myDestTargetEditorComponent.requestFocus(); revalidate(); return this; } - public void addRepoNodeListener(@NotNull RepositoryNodeListener listener) { + public void addRepoNodeListener(@NotNull RepositoryNodeListener listener) { myListeners.add(listener); } public void fireOnChange() { - myOldDestination = myDestBranchTextField.getText(); - for (RepositoryNodeListener listener : myListeners) { - listener.onTargetChanged(myOldDestination); + myDestTargetEditorComponent.fireOnChange(); + for (RepositoryNodeListener listener : myListeners) { + listener.onTargetChanged(myDestTargetEditorComponent.getValue()); } } @@ -192,7 +147,15 @@ public class RepositoryWithBranchPanel extends NonOpaquePanel implements TreeCel } public void fireOnCancel() { - myDestBranchTextField.setText(myOldDestination); + myDestTargetEditorComponent.fireOnCancel(); + } + + public TargetEditor getTargetEditor() { + return myDestTargetEditorComponent; + } + + public T getEditableValue() { + return myDestTargetEditorComponent.getValue(); } } diff --git a/platform/dvcs-impl/src/com/intellij/dvcs/push/ui/SingleRepositoryNode.java b/platform/dvcs-impl/src/com/intellij/dvcs/push/ui/SingleRepositoryNode.java index 81fb2bd1a9d0..3642e7a04b51 100644 --- a/platform/dvcs-impl/src/com/intellij/dvcs/push/ui/SingleRepositoryNode.java +++ b/platform/dvcs-impl/src/com/intellij/dvcs/push/ui/SingleRepositoryNode.java @@ -15,9 +15,8 @@ */ package com.intellij.dvcs.push.ui; +import com.intellij.dvcs.push.TargetEditor; import com.intellij.ui.ColoredTreeCellRenderer; -import com.intellij.ui.EditorTextField; -import com.intellij.ui.SimpleColoredText; import com.intellij.ui.SimpleTextAttributes; import org.jetbrains.annotations.NotNull; @@ -29,8 +28,8 @@ public class SingleRepositoryNode extends RepositoryNode { @NotNull private final RepositoryWithBranchPanel myRepositoryPanel; - public SingleRepositoryNode(@NotNull RepositoryWithBranchPanel repositoryPanel, @NotNull SimpleColoredText customTargetPresentation) { - super(repositoryPanel, customTargetPresentation); + public SingleRepositoryNode(@NotNull RepositoryWithBranchPanel repositoryPanel) { + super(repositoryPanel); myRepositoryPanel = repositoryPanel; } @@ -43,9 +42,9 @@ public class SingleRepositoryNode extends RepositoryNode { public void render(@NotNull ColoredTreeCellRenderer renderer) { renderer.append(myRepositoryPanel.getSourceName(), SimpleTextAttributes.REGULAR_ATTRIBUTES); renderer.append(myRepositoryPanel.getArrow(), SimpleTextAttributes.REGULAR_ATTRIBUTES); - EditorTextField textField = myRepositoryPanel.getRemoteTextFiled(); - renderTargetName(renderer, textField); - Insets insets = BorderFactory.createEmptyBorder().getBorderInsets(textField); + TargetEditor targetEditor = myRepositoryPanel.getTargetEditor(); + targetEditor.render(renderer); + Insets insets = BorderFactory.createEmptyBorder().getBorderInsets(targetEditor); renderer.setBorder(new EmptyBorder(insets)); } } diff --git a/platform/dvcs-impl/src/com/intellij/dvcs/push/ui/VcsBranchEditorListener.java b/platform/dvcs-impl/src/com/intellij/dvcs/push/ui/VcsBranchEditorListener.java index d8e35fd25d53..15c2b8ad66d3 100644 --- a/platform/dvcs-impl/src/com/intellij/dvcs/push/ui/VcsBranchEditorListener.java +++ b/platform/dvcs-impl/src/com/intellij/dvcs/push/ui/VcsBranchEditorListener.java @@ -15,9 +15,9 @@ */ package com.intellij.dvcs.push.ui; +import com.intellij.dvcs.push.TargetEditor; import com.intellij.openapi.vcs.changes.issueLinks.LinkMouseListenerBase; import com.intellij.ui.CheckboxTree; -import com.intellij.ui.EditorTextField; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -35,7 +35,7 @@ public class VcsBranchEditorListener extends LinkMouseListenerBase { public void mouseMoved(MouseEvent e) { Component component = (Component)e.getSource(); Object tag = getTagAt(e); - if (tag != null && tag instanceof EditorTextField) { + if (tag != null && tag instanceof TargetEditor) { component.setCursor(Cursor.getPredefinedCursor(Cursor.TEXT_CURSOR)); } else if (tag != null && tag instanceof TextWithLinkNode) { diff --git a/plugins/hg4idea/hg4idea.iml b/plugins/hg4idea/hg4idea.iml index 93b5a5109bde..d765458336ea 100644 --- a/plugins/hg4idea/hg4idea.iml +++ b/plugins/hg4idea/hg4idea.iml @@ -20,6 +20,7 @@ + diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/push/HgPushSupport.java b/plugins/hg4idea/src/org/zmlx/hg4idea/push/HgPushSupport.java index 13f4aaa08f6a..bb865468e233 100644 --- a/plugins/hg4idea/src/org/zmlx/hg4idea/push/HgPushSupport.java +++ b/plugins/hg4idea/src/org/zmlx/hg4idea/push/HgPushSupport.java @@ -15,28 +15,19 @@ */ package org.zmlx.hg4idea.push; -import com.intellij.dvcs.DvcsUtil; import com.intellij.dvcs.push.*; import com.intellij.dvcs.repo.RepositoryManager; import com.intellij.openapi.project.Project; -import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vcs.AbstractVcs; -import com.intellij.ui.SimpleColoredText; -import com.intellij.ui.SimpleTextAttributes; -import com.intellij.util.Function; import com.intellij.util.ObjectUtils; -import com.intellij.util.containers.ContainerUtil; 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.util.HgUtil; -import java.util.List; - public class HgPushSupport extends PushSupport { - private final static String ENTER_REMOTE = "Enter Remote"; @NotNull private final Project myProject; @NotNull private final HgVcs myVcs; @@ -70,17 +61,6 @@ public class HgPushSupport extends PushSupport getTargetNames(@NotNull HgRepository repository) { - return ContainerUtil.sorted(ContainerUtil.map(repository.getRepositoryConfig().getPaths(), new Function() { - @Override - public String fun(String s) { - return HgUtil.removePasswordIfNeeded(s); - } - })); - } - @NotNull @Override public HgPushSource getSource(@NotNull HgRepository repository) { @@ -88,12 +68,6 @@ public class HgPushSupport extends PushSupport getRepositoryManager() { @@ -106,18 +80,8 @@ public class HgPushSupport extends PushSupport createTargetEditor(@NotNull HgRepository repository, @NotNull String defaultTargetName) { + return new HgTargetEditor(repository, defaultTargetName); } } diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/push/HgTargetEditor.java b/plugins/hg4idea/src/org/zmlx/hg4idea/push/HgTargetEditor.java new file mode 100644 index 000000000000..6e86c054e7d9 --- /dev/null +++ b/plugins/hg4idea/src/org/zmlx/hg4idea/push/HgTargetEditor.java @@ -0,0 +1,125 @@ +/* + * 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.push; + +import com.intellij.dvcs.DvcsUtil; +import com.intellij.dvcs.push.TargetEditor; +import com.intellij.dvcs.push.VcsError; +import com.intellij.openapi.editor.ex.EditorEx; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.ui.ColoredTreeCellRenderer; +import com.intellij.ui.SimpleTextAttributes; +import com.intellij.ui.TextFieldWithAutoCompletion; +import com.intellij.ui.TextFieldWithAutoCompletionListProvider; +import com.intellij.util.containers.ContainerUtil; +import com.intellij.util.ui.UIUtil; +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 java.awt.*; +import java.awt.event.FocusAdapter; +import java.awt.event.FocusEvent; +import java.util.List; + +public class HgTargetEditor extends TargetEditor { + + private final static String ENTER_REMOTE = "Enter Remote"; + private final HgRepository myRepository; + private final TextFieldWithAutoCompletion myDestTargetEditorComponent; + private String myOldText; + + public HgTargetEditor(@NotNull HgRepository repository, @NotNull String defaultTargetName) { + super(new BorderLayout()); + setOpaque(false); + myRepository = repository; + final List targetVariants = HgUtil.getTargetNames(repository); + TextFieldWithAutoCompletionListProvider provider = + new TextFieldWithAutoCompletion.StringsCompletionProvider(targetVariants, null) { + @Override + public int compare(String item1, String item2) { + return Integer.valueOf(ContainerUtil.indexOf(targetVariants, item1)).compareTo(ContainerUtil.indexOf(targetVariants, item2)); + } + }; + myDestTargetEditorComponent = new TextFieldWithAutoCompletion(repository.getProject(), provider, true, defaultTargetName) { + + @Override + public boolean shouldHaveBorder() { + return false; + } + + @Override + protected void updateBorder(@NotNull final EditorEx editor) { + } + }; + myOldText = defaultTargetName; + myDestTargetEditorComponent.setBorder(UIUtil.getTableFocusCellHighlightBorder()); + myDestTargetEditorComponent.setOneLineMode(true); + FocusAdapter focusListener = new FocusAdapter() { + @Override + public void focusGained(FocusEvent e) { + myDestTargetEditorComponent.selectAll(); + } + }; + myDestTargetEditorComponent.addFocusListener(focusListener); + add(myDestTargetEditorComponent, BorderLayout.CENTER); + } + + @Override + public void render(@NotNull ColoredTreeCellRenderer renderer) { + String targetText = myDestTargetEditorComponent.getText(); + if (StringUtil.isEmptyOrSpaces(targetText)) { + renderer.append(ENTER_REMOTE, SimpleTextAttributes.GRAY_ITALIC_ATTRIBUTES, this); + } + renderer.append(targetText, SimpleTextAttributes.SYNTHETIC_ATTRIBUTES, this); + } + + @Override + @NotNull + public HgTarget getValue() { + return createValidPushTarget(); + } + + @NotNull + private HgTarget createValidPushTarget() { + return new HgTarget(myDestTargetEditorComponent.getText()); + } + + @Override + public void fireOnCancel() { + myDestTargetEditorComponent.setText(myOldText); + } + + @Override + public void fireOnChange() { + myOldText = myDestTargetEditorComponent.getText(); + } + + @Nullable + public VcsError verify() { + return StringUtil.isEmptyOrSpaces(myDestTargetEditorComponent.getText()) + ? VcsError.createEmptyTargetError(DvcsUtil.getShortRepositoryName(myRepository)) + : null; + } + + @NotNull + @Override + public JComponent getVerifiedComponent() { + return myDestTargetEditorComponent; + } +} diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/util/HgUtil.java b/plugins/hg4idea/src/org/zmlx/hg4idea/util/HgUtil.java index 3bb14721f0a8..d055ca247129 100644 --- a/plugins/hg4idea/src/org/zmlx/hg4idea/util/HgUtil.java +++ b/plugins/hg4idea/src/org/zmlx/hg4idea/util/HgUtil.java @@ -41,6 +41,7 @@ import com.intellij.openapi.wm.StatusBar; import com.intellij.openapi.wm.WindowManager; import com.intellij.openapi.wm.impl.status.StatusBarUtil; import com.intellij.ui.GuiUtils; +import com.intellij.util.Function; import com.intellij.util.containers.ContainerUtil; import com.intellij.vcsUtil.VcsUtil; import org.jetbrains.annotations.NotNull; @@ -716,4 +717,14 @@ public abstract class HgUtil { } return Couple.of(userName, email); } + + @NotNull + public static List getTargetNames(@NotNull HgRepository repository) { + return ContainerUtil.sorted(ContainerUtil.map(repository.getRepositoryConfig().getPaths(), new Function() { + @Override + public String fun(String s) { + return removePasswordIfNeeded(s); + } + })); + } } diff --git a/python/edu/build/upload_pythonInfo.xml b/python/edu/build/upload_pythonInfo.xml index f8d9477d1a3f..0633ad82f8c0 100644 --- a/python/edu/build/upload_pythonInfo.xml +++ b/python/edu/build/upload_pythonInfo.xml @@ -20,7 +20,7 @@ - +