From 0d14b54297000adecd681755cf20cc97f6048c28 Mon Sep 17 00:00:00 2001 From: Denis Zhdanov Date: Thu, 3 Feb 2011 16:04:22 +0300 Subject: [PATCH 1/4] IDEA-65031 Javadoc: Avoid unnecessary indent when enter is pressed after empty tag 1. Corrected processing after empty javadoc tag; 2. Corresponding tests are added; --- .../editorActions/enter/EnterAfterJavadocTagHandler.java | 8 ++++++-- .../enter/EnterAfterJavadocTagHandlerTest.java | 6 ++++++ 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/codeInsight/editorActions/enter/EnterAfterJavadocTagHandler.java b/platform/lang-impl/src/com/intellij/codeInsight/editorActions/enter/EnterAfterJavadocTagHandler.java index 17792d644ce1..e59da238cd1b 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/editorActions/enter/EnterAfterJavadocTagHandler.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/editorActions/enter/EnterAfterJavadocTagHandler.java @@ -135,8 +135,12 @@ public class EnterAfterJavadocTagHandler implements EnterHandlerDelegate { continue; } - if (c == '>') { - if (startTagEndOffset < 0) { + if (c == '>' && (startTagEndOffset < 0)) { + if (i > startOffset && text.charAt(i - 1) == '/') { + // Handle situation like '

[offset]' + break; + } + else { startTagEndOffset = i; continue; } diff --git a/platform/lang-impl/testSrc/com/intellij/codeInsight/editorActions/enter/EnterAfterJavadocTagHandlerTest.java b/platform/lang-impl/testSrc/com/intellij/codeInsight/editorActions/enter/EnterAfterJavadocTagHandlerTest.java index 85af3f831cd6..f23e85569751 100644 --- a/platform/lang-impl/testSrc/com/intellij/codeInsight/editorActions/enter/EnterAfterJavadocTagHandlerTest.java +++ b/platform/lang-impl/testSrc/com/intellij/codeInsight/editorActions/enter/EnterAfterJavadocTagHandlerTest.java @@ -82,6 +82,12 @@ public class EnterAfterJavadocTagHandlerTest { context = parse(text); assertEmpty(context); } + + @Test + public void emptyTag() { + EnterAfterJavadocTagHandler.Context context = parse("*

"); + assertEmpty(context); + } private static EnterAfterJavadocTagHandler.Context parse(String text) { return parse(text, text.length()); From c76595096ec4b0a17382eb22f0ee0eaae6b8d650 Mon Sep 17 00:00:00 2001 From: andrey zaytsev Date: Thu, 3 Feb 2011 16:05:31 +0300 Subject: [PATCH 2/4] idea-65026: abusing error message when replacement is bad. --- .../src/com/intellij/find/FindManager.java | 15 +++++++++-- .../src/com/intellij/find/FindUtil.java | 22 +++++++++++----- .../com/intellij/find/impl/FindDialog.java | 1 + .../intellij/find/impl/FindManagerImpl.java | 26 +++++-------------- .../find/impl/LivePreviewController.java | 9 +++++-- .../ReplaceInProjectManager.java | 10 +++++-- 6 files changed, 52 insertions(+), 31 deletions(-) diff --git a/platform/lang-api/src/com/intellij/find/FindManager.java b/platform/lang-api/src/com/intellij/find/FindManager.java index f4e85c0496a6..c2866ebe6d94 100644 --- a/platform/lang-api/src/com/intellij/find/FindManager.java +++ b/platform/lang-api/src/com/intellij/find/FindManager.java @@ -108,6 +108,16 @@ public abstract class FindManager { public abstract FindResult findString(@NotNull CharSequence text, int offset, @NotNull FindModel model, @Nullable VirtualFile findContextFile); + public static class MalformedReplacementStringException extends Exception { + public MalformedReplacementStringException(String s) { + super(s); //To change body of overridden methods use File | Settings | File Templates. + } + + public MalformedReplacementStringException(String s, Throwable throwable) { + super(s, throwable); //To change body of overridden methods use File | Settings | File Templates. + } + } + /** * Gets the string to replace with, given the specified found string and find/replace * settings. Supports case-preserving and regular expression replaces. @@ -116,8 +126,9 @@ public abstract class FindManager { * @param model the search and replace settings, including the replace string. * @return the string to replace the specified found string. */ - public abstract String getStringToReplace(@NotNull String foundString, @NotNull FindModel model); - public abstract String getStringToReplace(@NotNull String foundString, @NotNull FindModel model, int startOffset, @NotNull String documentText); + public abstract String getStringToReplace(@NotNull String foundString, @NotNull FindModel model) throws MalformedReplacementStringException; + public abstract String getStringToReplace(@NotNull String foundString, @NotNull FindModel model, + int startOffset, @NotNull String documentText) throws MalformedReplacementStringException; /** * Gets the flag indicating whether the "Find Next" and "Find Previous" actions are diff --git a/platform/lang-impl/src/com/intellij/find/FindUtil.java b/platform/lang-impl/src/com/intellij/find/FindUtil.java index 9cb56e56b840..2a3108a8ace5 100644 --- a/platform/lang-impl/src/com/intellij/find/FindUtil.java +++ b/platform/lang-impl/src/com/intellij/find/FindUtil.java @@ -46,6 +46,7 @@ import com.intellij.openapi.fileEditor.TextEditor; import com.intellij.openapi.fileEditor.ex.IdeDocumentHistory; import com.intellij.openapi.keymap.KeymapUtil; import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.Messages; import com.intellij.openapi.util.Key; import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.TextRange; @@ -440,6 +441,21 @@ public class FindUtil { } int startResultOffset = result.getStartOffset(); model.setFromCursor(true); + + int startOffset = result.getStartOffset(); + int endOffset = result.getEndOffset(); + String foundString = document.getCharsSequence().subSequence(startOffset, endOffset).toString(); + String toReplace; + try { + toReplace = findManager.getStringToReplace(foundString, model, startOffset, document.getText()); + } + catch (FindManager.MalformedReplacementStringException e) { + if (!ApplicationManager.getApplication().isUnitTestMode()) { + Messages.showErrorDialog(project, e.getMessage(), FindBundle.message("find.replace.invalid.replacement.string.title")); + } + break; + } + if (toPrompt) { int promptResult = findManager.showPromptDialog(model, FindBundle.message("find.replace.dialog.title")); if (promptResult == FindManager.PromptResult.SKIP) { @@ -455,12 +471,6 @@ public class FindUtil { } } - int startOffset = result.getStartOffset(); - int endOffset = result.getEndOffset(); - String foundString = document.getCharsSequence().subSequence(startOffset, endOffset).toString(); - String toReplace = findManager.getStringToReplace(foundString, model, startOffset, document.getText()); - if (toReplace == null) break; - boolean reallyReplace = toPrompt; TextRange textRange = doReplace(project, document, model, result, toReplace, reallyReplace, rangesToChange); diff --git a/platform/lang-impl/src/com/intellij/find/impl/FindDialog.java b/platform/lang-impl/src/com/intellij/find/impl/FindDialog.java index 9c5b0286cfed..2bcee259eec9 100644 --- a/platform/lang-impl/src/com/intellij/find/impl/FindDialog.java +++ b/platform/lang-impl/src/com/intellij/find/impl/FindDialog.java @@ -19,6 +19,7 @@ package com.intellij.find.impl; import com.intellij.CommonBundle; import com.intellij.find.FindBundle; +import com.intellij.find.FindManager; import com.intellij.find.FindModel; import com.intellij.find.FindSettings; import com.intellij.ide.util.scopeChooser.ScopeChooserCombo; diff --git a/platform/lang-impl/src/com/intellij/find/impl/FindManagerImpl.java b/platform/lang-impl/src/com/intellij/find/impl/FindManagerImpl.java index e264af03df3c..e2234b3194c0 100644 --- a/platform/lang-impl/src/com/intellij/find/impl/FindManagerImpl.java +++ b/platform/lang-impl/src/com/intellij/find/impl/FindManagerImpl.java @@ -50,7 +50,6 @@ import com.intellij.openapi.fileTypes.SyntaxHighlighterFactory; import com.intellij.openapi.keymap.KeymapUtil; import com.intellij.openapi.project.Project; import com.intellij.openapi.project.ProjectManager; -import com.intellij.openapi.ui.Messages; import com.intellij.openapi.util.*; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.VirtualFile; @@ -512,7 +511,7 @@ public class FindManagerImpl extends FindManager implements PersistentStateCompo return pattern == null ? null : pattern.matcher(text); } - public String getStringToReplace(@NotNull String foundString, @NotNull FindModel model) { + public String getStringToReplace(@NotNull String foundString, @NotNull FindModel model) throws MalformedReplacementStringException { String toReplace = model.getStringToReplace(); if (model.isRegularExpressions()) { return getStringToReplaceByRegexp0(foundString, model); @@ -524,7 +523,8 @@ public class FindManagerImpl extends FindManager implements PersistentStateCompo } @Override - public String getStringToReplace(@NotNull String foundString, @NotNull FindModel model, int startOffset, @NotNull String documentText) { + public String getStringToReplace(@NotNull String foundString, @NotNull FindModel model, + int startOffset, @NotNull String documentText) throws MalformedReplacementStringException{ String toReplace = model.getStringToReplace(); if (model.isRegularExpressions()) { return getStringToReplaceByRegexp(model, documentText, startOffset); @@ -535,7 +535,7 @@ public class FindManagerImpl extends FindManager implements PersistentStateCompo return toReplace; } - private String getStringToReplaceByRegexp(@NotNull final FindModel model, @NotNull String text, int startOffset) { + private String getStringToReplaceByRegexp(@NotNull final FindModel model, @NotNull String text, int startOffset) throws MalformedReplacementStringException{ Matcher matcher = compileRegExp(model, text); if (model.isForward()){ @@ -563,17 +563,11 @@ public class FindManagerImpl extends FindManager implements PersistentStateCompo return replaced.substring(matcher.start()); } catch (Exception e) { - ApplicationManager.getApplication().invokeLater(new Runnable() { - public void run() { - Messages.showErrorDialog(myProject, FindBundle.message("find.replace.invalid.replacement.string", model.getStringToReplace()), - FindBundle.message("find.replace.invalid.replacement.string.title")); - } - }); - return null; + throw new MalformedReplacementStringException(FindBundle.message("find.replace.invalid.replacement.string", model.getStringToReplace()), e); } } - private String getStringToReplaceByRegexp0(String foundString, final FindModel model) { + private String getStringToReplaceByRegexp0(String foundString, final FindModel model) throws MalformedReplacementStringException{ String toFind = model.getStringToFind(); String toReplace = model.getStringToReplace(); Pattern pattern; @@ -594,13 +588,7 @@ public class FindManagerImpl extends FindManager implements PersistentStateCompo return matcher.replaceAll(StringUtil.unescapeStringCharacters(toReplace)); } catch (Exception e) { - ApplicationManager.getApplication().invokeLater(new Runnable() { - public void run() { - Messages.showErrorDialog(myProject, FindBundle.message("find.replace.invalid.replacement.string", model.getStringToReplace()), - FindBundle.message("find.replace.invalid.replacement.string.title")); - } - }); - return null; + throw new MalformedReplacementStringException(FindBundle.message("find.replace.invalid.replacement.string", model.getStringToReplace()), e); } } else { diff --git a/platform/lang-impl/src/com/intellij/find/impl/LivePreviewController.java b/platform/lang-impl/src/com/intellij/find/impl/LivePreviewController.java index b8d787f19919..755d6424f69c 100644 --- a/platform/lang-impl/src/com/intellij/find/impl/LivePreviewController.java +++ b/platform/lang-impl/src/com/intellij/find/impl/LivePreviewController.java @@ -113,8 +113,13 @@ public class LivePreviewController implements LivePreview.Delegate, UserActivity if (currentModel != null) { if (currentModel.isReplaceState()) { FindManager findManager = FindManager.getInstance(editor.getProject()); - stringToReplace = findManager.getStringToReplace(foundString, currentModel, - liveOccurrence.getPrimaryRange().getStartOffset(), documentText); + try { + stringToReplace = findManager.getStringToReplace(foundString, currentModel, + liveOccurrence.getPrimaryRange().getStartOffset(), documentText); + } + catch (FindManager.MalformedReplacementStringException e) { + return null; + } if (stringToReplace != null && stringToReplace.isEmpty()) { stringToReplace = EMPTY_STRING_DISPLAY_TEXT; } diff --git a/platform/lang-impl/src/com/intellij/find/replaceInProject/ReplaceInProjectManager.java b/platform/lang-impl/src/com/intellij/find/replaceInProject/ReplaceInProjectManager.java index d031a7dc5964..08fe256dfad2 100644 --- a/platform/lang-impl/src/com/intellij/find/replaceInProject/ReplaceInProjectManager.java +++ b/platform/lang-impl/src/com/intellij/find/replaceInProject/ReplaceInProjectManager.java @@ -341,8 +341,14 @@ public class ReplaceInProjectManager { if (!findResult.isStringFound()) { return; } - String stringToReplace = - findManager.getStringToReplace(foundString.toString(), replaceContext.getFindModel(), textOffset, document.getText()); + String stringToReplace = null; + try { + stringToReplace = + findManager.getStringToReplace(foundString.toString(), replaceContext.getFindModel(), textOffset, document.getText()); + } + catch (FindManager.MalformedReplacementStringException e) { + Messages.showErrorDialog(myProject, e.getMessage(), FindBundle.message("find.replace.invalid.replacement.string.title")); + } if (stringToReplace != null) { document.replaceString(textOffset, textEndOffset, stringToReplace); } From b34bb91f6883dbd092444a26de671872d0ebfec8 Mon Sep 17 00:00:00 2001 From: peter Date: Thu, 3 Feb 2011 14:05:30 +0100 Subject: [PATCH 3/4] stub element should have stub element type --- .../extapi/psi/StubBasedPsiElementBase.java | 3 ++ .../lang/parser/GroovyElementTypes.java | 45 +++++++++++++++++-- .../stubs/elements/GrStubFileElementType.java | 2 +- .../groovy/lang/GroovyHighlightingTest.java | 4 ++ .../highlighting/TestMarkupStubs.groovy | 7 +++ 5 files changed, 57 insertions(+), 4 deletions(-) create mode 100644 plugins/groovy/testdata/highlighting/TestMarkupStubs.groovy diff --git a/platform/lang-impl/src/com/intellij/extapi/psi/StubBasedPsiElementBase.java b/platform/lang-impl/src/com/intellij/extapi/psi/StubBasedPsiElementBase.java index 6fe0c326741a..383a1204608c 100644 --- a/platform/lang-impl/src/com/intellij/extapi/psi/StubBasedPsiElementBase.java +++ b/platform/lang-impl/src/com/intellij/extapi/psi/StubBasedPsiElementBase.java @@ -184,6 +184,9 @@ public class StubBasedPsiElementBase extends ASTDelegateP @NotNull public IStubElementType getElementType() { + if (!(myElementType instanceof IStubElementType)) { + throw new AssertionError("Not a stub type: " + myElementType + " in " + getClass()); + } return (IStubElementType)myElementType; } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/GroovyElementTypes.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/GroovyElementTypes.java index 6fb3bafe4c6b..f520efaac419 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/GroovyElementTypes.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/GroovyElementTypes.java @@ -16,6 +16,7 @@ package org.jetbrains.plugins.groovy.lang.parser; +import com.intellij.lang.ASTNode; import com.intellij.psi.stubs.*; import com.intellij.psi.tree.IElementType; import com.intellij.psi.tree.TokenSet; @@ -27,6 +28,7 @@ import org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes; import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.modifiers.GrModifierList; import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.modifiers.annotation.GrAnnotation; import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrField; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrVariable; import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrVariableDeclaration; import org.jetbrains.plugins.groovy.lang.psi.api.statements.params.GrParameter; import org.jetbrains.plugins.groovy.lang.psi.api.statements.params.GrParameterList; @@ -356,7 +358,17 @@ public interface GroovyElementTypes extends GroovyTokenTypes, GroovyDocElementTy GroovyElementType SYNCHRONIZED_STATEMENT = new GroovyElementType("synchronized block statement"); GroovyElementType CLASS_INITIALIZER = new GroovyElementType("static compound statement"); - GroovyElementType VARIABLE_DEFINITION_ERROR = new GroovyElementType("variable definitions with errors"); + EmptyStubElementType VARIABLE_DEFINITION_ERROR = new EmptyStubElementType("variable definitions with errors", GroovyFileType.GROOVY_LANGUAGE) { + @Override + public boolean shouldCreateStub(ASTNode node) { + return false; + } + + @Override + public GrVariableDeclaration createPsi(EmptyStub stub) { + throw new UnsupportedOperationException("Not implemented"); + } + }; EmptyStubElementType VARIABLE_DEFINITION = new EmptyStubElementType("variable definitions", GroovyFileType.GROOVY_LANGUAGE) { @Override @@ -371,7 +383,34 @@ public interface GroovyElementTypes extends GroovyTokenTypes, GroovyDocElementTy GroovyElementType TUPLE_ERROR = new GroovyElementType("tuple with error"); - GroovyElementType VARIABLE = new GroovyElementType("assigned variable"); + GrStubElementType VARIABLE = new GrStubElementType("assigned variable") { + + @Override + public boolean shouldCreateStub(ASTNode node) { + return false; + } + + @Override + public GrVariable createPsi(StubElement stub) { + throw new UnsupportedOperationException("Not implemented"); + } + + @Override + public StubElement createStub(GrVariable psi, StubElement parentStub) { + throw new UnsupportedOperationException("Not implemented"); + } + + @Override + public void serialize(StubElement stub, StubOutputStream dataStream) throws IOException { + throw new UnsupportedOperationException("Not implemented"); + } + + @Override + public StubElement deserialize(StubInputStream dataStream, StubElement parentStub) throws IOException { + throw new UnsupportedOperationException("Not implemented"); + } + }; + //modifiers GrStubElementType MODIFIERS = new GrModifierListElementType("modifier list"); @@ -391,4 +430,4 @@ public interface GroovyElementTypes extends GroovyTokenTypes, GroovyDocElementTy TokenSet VARIABLES = TokenSet.create(VARIABLE, FIELD); TokenSet TYPE_ELEMENTS = TokenSet.create(CLASS_TYPE_ELEMENT, ARRAY_TYPE, BUILT_IN_TYPE, TYPE_ARGUMENT); -} \ No newline at end of file +} diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/stubs/elements/GrStubFileElementType.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/stubs/elements/GrStubFileElementType.java index 77e62a6a469c..893daddfc483 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/stubs/elements/GrStubFileElementType.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/stubs/elements/GrStubFileElementType.java @@ -53,7 +53,7 @@ public class GrStubFileElementType extends IStubFileElementType { @Override public int getStubVersion() { - return super.getStubVersion() + 9; + return super.getStubVersion() + 10; } public String getExternalId() { diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/GroovyHighlightingTest.java b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/GroovyHighlightingTest.java index abf11cd65bb9..60b284be13b2 100644 --- a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/GroovyHighlightingTest.java +++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/GroovyHighlightingTest.java @@ -334,4 +334,8 @@ public class GroovyHighlightingTest extends LightCodeInsightFixtureTestCase { public void testMethodImplementedByDelegate() { doTest(); } + + public void testTestMarkupStubs() { + doTest(); + } } \ No newline at end of file diff --git a/plugins/groovy/testdata/highlighting/TestMarkupStubs.groovy b/plugins/groovy/testdata/highlighting/TestMarkupStubs.groovy new file mode 100644 index 000000000000..8175bc3a4981 --- /dev/null +++ b/plugins/groovy/testdata/highlighting/TestMarkupStubs.groovy @@ -0,0 +1,7 @@ +abstract class X { + abstract def foo<caret>(String s, int a) + + def foo(String s) { + return foo(s, 5); + } +} From e2e4719f73470e618c1d685d68a213471d6d4160 Mon Sep 17 00:00:00 2001 From: irengrig Date: Thu, 3 Feb 2011 16:22:50 +0300 Subject: [PATCH 4/4] IDEA-64967 Subversion connection thread never times out --- .../idea/svn/SvnAuthenticationManager.java | 21 +++++- .../jetbrains/idea/svn/SvnConfigurable.form | 75 ++++++++++++++++++- .../jetbrains/idea/svn/SvnConfigurable.java | 20 ++++- .../jetbrains/idea/svn/SvnConfiguration.java | 4 + 4 files changed, 115 insertions(+), 5 deletions(-) diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnAuthenticationManager.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnAuthenticationManager.java index 74846f450921..a683ee9a8aa1 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnAuthenticationManager.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnAuthenticationManager.java @@ -56,6 +56,9 @@ import java.util.*; public class SvnAuthenticationManager extends DefaultSVNAuthenticationManager implements SvnAuthenticationListener { // while Mac storage not working for IDEA, we use this key to check whether to prompt abt plaintext or just store private static final Logger LOG = Logger.getInstance(SvnAuthenticationManager.class.getName()); + public static final String SVN_SSH = "svn+ssh"; + public static final String HTTP = "http"; + public static final String HTTPS = "https"; private final Project myProject; private File myConfigDirectory; private PersistentAuthenticationProviderProxy myPersistentAuthenticationProviderProxy; @@ -400,7 +403,7 @@ public class SvnAuthenticationManager extends DefaultSVNAuthenticationManager im @Override public int getReadTimeout(final SVNRepository repository) { String protocol = repository.getLocation().getProtocol(); - if ("http".equals(protocol) || "https".equals(protocol)) { + if (HTTP.equals(protocol) || HTTPS.equals(protocol)) { String host = repository.getLocation().getHost(); String timeout = getServersPropertyIdea(host, "http-timeout"); if (timeout != null) { @@ -412,9 +415,25 @@ public class SvnAuthenticationManager extends DefaultSVNAuthenticationManager im } return DEFAULT_READ_TIMEOUT; } + if (SVN_SSH.equals(protocol)) { + return (int) myConfig.mySSHReadTimeout; + } return 0; } + @Override + public int getConnectTimeout(SVNRepository repository) { + String protocol = repository.getLocation().getProtocol(); + if (SVN_SSH.equals(protocol)) { + return (int) myConfig.mySSHConnectionTimeout; + } + final int connectTimeout = super.getConnectTimeout(repository); + if ((HTTP.equals(protocol) || HTTPS.equals(protocol)) && (connectTimeout <= 0)) { + return DEFAULT_READ_TIMEOUT; + } + return connectTimeout; + } + // taken from default manager as is private String getServersPropertyIdea(String host, final String name) { final SVNCompositeConfigFile serversFile = getHostOptionsProvider().getServersFile(); diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnConfigurable.form b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnConfigurable.form index da771de23f12..d10d3b6dcc5b 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnConfigurable.form +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnConfigurable.form @@ -1,16 +1,16 @@

- + - + - + @@ -188,6 +188,75 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnConfigurable.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnConfigurable.java index abf476929546..f0eb2258165a 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnConfigurable.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnConfigurable.java @@ -58,6 +58,8 @@ public class SvnConfigurable implements Configurable { private JCheckBox myShowMergeSourceInAnnotate; private JSpinner myNumRevsInAnnotations; private JCheckBox myMaximumNumberOfRevisionsCheckBox; + private JSpinner mySSHConnectionTimeout; + private JSpinner mySSHReadTimeout; @NonNls private static final String HELP_ID = "project.propSubversion"; @@ -128,7 +130,7 @@ public class SvnConfigurable implements Configurable { } }); myNumRevsInAnnotations.setEnabled(myMaximumNumberOfRevisionsCheckBox.isSelected()); - } + } private FileChooserDescriptor createFileDescriptor() { final FileChooserDescriptor descriptor = new FileChooserDescriptor(false, true, false, false, false, false); @@ -192,6 +194,12 @@ public class SvnConfigurable implements Configurable { return true; } } + if (configuration.mySSHConnectionTimeout != ((SpinnerNumberModel) mySSHConnectionTimeout.getModel()).getNumber().longValue()) { + return true; + } + if (configuration.mySSHReadTimeout != ((SpinnerNumberModel) mySSHReadTimeout.getModel()).getNumber().longValue()) { + return true; + } return !configuration.getConfigurationDirectory().equals(myConfigurationDirectoryText.getText().trim()); } @@ -213,6 +221,8 @@ public class SvnConfigurable implements Configurable { } else { configuration.setMaxAnnotateRevisions(((SpinnerNumberModel) myNumRevsInAnnotations.getModel()).getNumber().intValue()); } + configuration.mySSHConnectionTimeout = ((SpinnerNumberModel) mySSHConnectionTimeout.getModel()).getNumber().longValue() * 1000; + configuration.mySSHReadTimeout = ((SpinnerNumberModel) mySSHReadTimeout.getModel()).getNumber().longValue() * 1000; } public void reset() { @@ -243,6 +253,8 @@ public class SvnConfigurable implements Configurable { myNumRevsInAnnotations.setValue(annotateRevisions); } myNumRevsInAnnotations.setEnabled(myMaximumNumberOfRevisionsCheckBox.isSelected()); + mySSHConnectionTimeout.setValue(configuration.mySSHConnectionTimeout / 1000); + mySSHReadTimeout.setValue(configuration.mySSHReadTimeout / 1000); } public void disposeUIResources() { @@ -264,6 +276,12 @@ public class SvnConfigurable implements Configurable { int value = configuration.getMaxAnnotateRevisions(); value = (value == -1) ? SvnConfiguration.ourMaxAnnotateRevisionsDefault : value; myNumRevsInAnnotations = new JSpinner(new SpinnerNumberModel(value, 10, 100000, 100)); + + final int maximum = 30 * 60 * 1000; + final long connection = configuration.mySSHConnectionTimeout <= maximum ? configuration.mySSHConnectionTimeout : maximum; + final long read = configuration.mySSHReadTimeout <= maximum ? configuration.mySSHReadTimeout : maximum; + mySSHConnectionTimeout = new JSpinner(new SpinnerNumberModel(connection / 1000, 0, maximum, 10)); + mySSHReadTimeout = new JSpinner(new SpinnerNumberModel(read / 1000, 0, maximum, 10)); } } diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnConfiguration.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnConfiguration.java index 7c0333e99354..b334ae07c122 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnConfiguration.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnConfiguration.java @@ -28,6 +28,7 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.util.*; import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.vcs.annotate.AnnotationListener; +import com.intellij.util.io.DataExternalizer; import org.jdom.Attribute; import org.jdom.DataConversionException; import org.jdom.Element; @@ -80,6 +81,9 @@ public class SvnConfiguration implements ProjectComponent, JDOMExternalizable { private String myUpgradeMode; private SvnSupportOptions mySupportOptions; private int myMaxAnnotateRevisions = ourMaxAnnotateRevisionsDefault; + private final static long DEFAULT_SSH_TIMEOUT = 30 * 1000; + public long mySSHConnectionTimeout = DEFAULT_SSH_TIMEOUT; + public long mySSHReadTimeout = DEFAULT_SSH_TIMEOUT; public static final AuthStorage RUNTIME_AUTH_CACHE = new AuthStorage(); public String LAST_MERGED_REVISION = null;