diff --git a/java/java-impl/src/com/intellij/codeInsight/ChangeContextUtil.java b/java/java-impl/src/com/intellij/codeInsight/ChangeContextUtil.java index 605346cf8950..df3ccb729865 100644 --- a/java/java-impl/src/com/intellij/codeInsight/ChangeContextUtil.java +++ b/java/java-impl/src/com/intellij/codeInsight/ChangeContextUtil.java @@ -287,6 +287,7 @@ public class ChangeContextUtil { try{ PsiExpression qualifier = refExpr.getQualifierExpression(); if (!(qualifier instanceof PsiReferenceExpression)) return false; + if (refExpr.getTypeParameters().length > 0) return false; PsiElement qualifierRefElement = ((PsiReferenceExpression)qualifier).resolve(); if (!(qualifierRefElement instanceof PsiClass)) return false; PsiElement refElement = refExpr.resolve(); diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/PreferByKindWeigher.java b/java/java-impl/src/com/intellij/codeInsight/completion/PreferByKindWeigher.java index 65e988341ead..97f03eae8ab1 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/PreferByKindWeigher.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/PreferByKindWeigher.java @@ -93,7 +93,13 @@ public class PreferByKindWeigher extends LookupElementWeigher { assert annotation != null; PsiAnnotationOwner owner = annotation.getOwner(); if (owner instanceof PsiModifierList || owner instanceof PsiTypeElement || owner instanceof PsiTypeParameter) { - PsiElement member = owner instanceof PsiModifierList ? ((PsiElement)owner).getParent() : (PsiElement)owner; + PsiElement member = (PsiElement)owner; + if (member instanceof PsiModifierList) { + member = member.getParent(); + } + if (member instanceof PsiTypeElement && member.getParent() instanceof PsiMethod) { + member = member.getParent(); + } final String[] elementTypeFields = PsiAnnotationImpl.getApplicableElementTypeFields(member); return new Condition() { @Override diff --git a/java/java-impl/src/com/intellij/codeInspection/LambdaCanBeMethReferenceInspection.java b/java/java-impl/src/com/intellij/codeInspection/LambdaCanBeMethReferenceInspection.java index 8c61532d14e9..4cacb741f178 100644 --- a/java/java-impl/src/com/intellij/codeInspection/LambdaCanBeMethReferenceInspection.java +++ b/java/java-impl/src/com/intellij/codeInspection/LambdaCanBeMethReferenceInspection.java @@ -18,11 +18,13 @@ package com.intellij.codeInspection; import com.intellij.codeInsight.daemon.GroupNames; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Ref; import com.intellij.pom.java.LanguageLevel; import com.intellij.psi.*; import com.intellij.psi.codeStyle.JavaCodeStyleManager; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.psi.util.PsiUtil; +import com.intellij.util.ArrayUtilRt; import org.jetbrains.annotations.Nls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -115,6 +117,7 @@ public class LambdaCanBeMethReferenceInspection extends BaseJavaLocalInspectionT if (psiMethod == null) { isConstructor = true; if (!(methodCall instanceof PsiNewExpression)) return null; + if (((PsiNewExpression)methodCall).getAnonymousClass() != null) return null; final PsiJavaCodeReferenceElement classReference = ((PsiNewExpression)methodCall).getClassOrAnonymousClassReference(); if (classReference == null) return null; containingClass = (PsiClass)classReference.resolve(); @@ -145,22 +148,37 @@ public class LambdaCanBeMethReferenceInspection extends BaseJavaLocalInspectionT if (parameters[i + offset] != resolve) return null; } + final PsiExpression qualifierExpression; + if (methodCall instanceof PsiMethodCallExpression) { + qualifierExpression = ((PsiMethodCallExpression)methodCall).getMethodExpression().getQualifierExpression(); + } + else if (methodCall instanceof PsiNewExpression) { + qualifierExpression = ((PsiNewExpression)methodCall).getQualifier(); + } + else { + qualifierExpression = null; + } if (offset > 0) { - final PsiExpression qualifierExpression; - if (methodCall instanceof PsiMethodCallExpression) { - qualifierExpression = ((PsiMethodCallExpression)methodCall).getMethodExpression().getQualifierExpression(); - } - else if (methodCall instanceof PsiNewExpression) { - qualifierExpression = ((PsiNewExpression)methodCall).getQualifier(); - } - else { - qualifierExpression = null; - } if (!(qualifierExpression instanceof PsiReferenceExpression) || ((PsiReferenceExpression)qualifierExpression).resolve() != parameters[0]) { return null; } } + else if (qualifierExpression != null) { + final Ref usedInQualifier = new Ref(false); + qualifierExpression.accept(new JavaRecursiveElementWalkingVisitor() { + @Override + public void visitReferenceExpression(PsiReferenceExpression expression) { + final PsiElement resolve = expression.resolve(); + if (resolve instanceof PsiParameter && ArrayUtilRt.find(parameters, resolve) > -1) { + usedInQualifier.set(true); + return; + } + super.visitReferenceExpression(expression); + } + }); + if (usedInQualifier.get()) return null; + } return methodCall; } } @@ -181,7 +199,7 @@ public class LambdaCanBeMethReferenceInspection extends BaseJavaLocalInspectionT final String methodReferenceName = methodExpression.getReferenceName(); if (qualifierExpression != null) { boolean isReceiverType = LambdaUtil.isReceiverType(functionalInterfaceType, containingClass, psiMethod); - methodRefText = (isReceiverType ? containingClass.getQualifiedName() : qualifierExpression.getText()) + "::" + methodReferenceName; + methodRefText = (isReceiverType ? containingClass.getQualifiedName() : qualifierExpression.getText()) + "::" + ((PsiMethodCallExpression)element).getTypeArgumentList().getText() + methodReferenceName; } else { methodRefText = diff --git a/java/java-impl/src/com/intellij/refactoring/move/moveMembers/MoveJavaMemberHandler.java b/java/java-impl/src/com/intellij/refactoring/move/moveMembers/MoveJavaMemberHandler.java index 48e0d0ba1432..85e01e2c19a4 100644 --- a/java/java-impl/src/com/intellij/refactoring/move/moveMembers/MoveJavaMemberHandler.java +++ b/java/java-impl/src/com/intellij/refactoring/move/moveMembers/MoveJavaMemberHandler.java @@ -17,8 +17,10 @@ package com.intellij.refactoring.move.moveMembers; import com.intellij.codeInsight.ChangeContextUtil; import com.intellij.codeInsight.highlighting.ReadWriteAccessDetector; +import com.intellij.openapi.project.Project; import com.intellij.psi.*; import com.intellij.psi.impl.source.resolve.JavaResolveUtil; +import com.intellij.psi.search.GlobalSearchScope; import com.intellij.psi.search.LocalSearchScope; import com.intellij.psi.search.searches.ReferencesSearch; import com.intellij.psi.util.*; @@ -171,7 +173,17 @@ public class MoveJavaMemberHandler implements MoveMemberHandler { changeQualifier(refExpr, usage.qualifierClass, usage.member); } else { - refExpr.setQualifierExpression(null); + final PsiReferenceParameterList parameterList = refExpr.getParameterList(); + if (parameterList != null && parameterList.getTypeArguments().length == 0){ + refExpr.setQualifierExpression(null); + } else { + final Project project = element.getProject(); + final PsiClass targetClass = + JavaPsiFacade.getInstance(project).findClass(options.getTargetClassName(), GlobalSearchScope.projectScope(project)); + if (targetClass != null) { + changeQualifier(refExpr, targetClass, usage.member); + } + } } } else { // no qualifier diff --git a/java/java-tests/testData/codeInsight/completion/normalSorting/PreferApplicableAnnotationsMethod.java b/java/java-tests/testData/codeInsight/completion/normalSorting/PreferApplicableAnnotationsMethod.java new file mode 100644 index 000000000000..345e8cccbcf0 --- /dev/null +++ b/java/java-tests/testData/codeInsight/completion/normalSorting/PreferApplicableAnnotationsMethod.java @@ -0,0 +1,6 @@ +class Foo { + @T + public static void main(String[] args) { + + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/anonymous2methodReference/afterQualifierDoesntUseParams.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/anonymous2methodReference/afterQualifierDoesntUseParams.java new file mode 100644 index 000000000000..02d8ad5ed0fd --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/anonymous2methodReference/afterQualifierDoesntUseParams.java @@ -0,0 +1,12 @@ +// "Replace with method reference" "true" +interface Foo { + B f(A a); +} + +interface DeeBee { + A run(Void c) throws SQLException; + + DeeBee bind(final Foo> f) default { + return f.f(null)::run; + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/anonymous2methodReference/beforeQualifierDoesntUseParams.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/anonymous2methodReference/beforeQualifierDoesntUseParams.java new file mode 100644 index 000000000000..6aa032f10471 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/anonymous2methodReference/beforeQualifierDoesntUseParams.java @@ -0,0 +1,16 @@ +// "Replace with method reference" "true" +interface Foo { + B f(A a); +} + +interface DeeBee { + A run(Void c) throws SQLException; + + DeeBee bind(final Foo> f) default { + return new DeeBee () { + public B run(final Void c) throws SQLException { + return f.f(null).run(c); + } + }; + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/anonymous2methodReference/beforeQualifierUsesParams.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/anonymous2methodReference/beforeQualifierUsesParams.java new file mode 100644 index 000000000000..0526753c4b73 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/anonymous2methodReference/beforeQualifierUsesParams.java @@ -0,0 +1,16 @@ +// "Replace with method reference" "false" +interface Foo { + B f(A a); +} + +interface DeeBee { + A run(Void c) throws SQLException; + + DeeBee bind(final Foo> f) default { + return new DeeBee () { + public B run(final Void c) throws SQLException { + return f.f(DeeBee.this.run(c)).run(c); + } + }; + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/lambda2methodReference/beforeAnonymous.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/lambda2methodReference/beforeAnonymous.java new file mode 100644 index 000000000000..168aec918dc5 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/lambda2methodReference/beforeAnonymous.java @@ -0,0 +1,13 @@ +// "Replace lambda with method reference" "false" +class NonStaticInner3 { + class Foo { + } + + interface I1 { + X m(); + } + + { + I1 b2 = () -> new Foo(){}; + } +} \ No newline at end of file diff --git a/java/java-tests/testData/refactoring/moveMembers/parameterizedRefOn/after/pack1/A.java b/java/java-tests/testData/refactoring/moveMembers/parameterizedRefOn/after/pack1/A.java new file mode 100644 index 000000000000..0b6baaf5c142 --- /dev/null +++ b/java/java-tests/testData/refactoring/moveMembers/parameterizedRefOn/after/pack1/A.java @@ -0,0 +1,16 @@ +package pack1; + +interface Eff { + B f(A a); +} + +abstract class POne { + abstract A _1(); + +} + +final class Hooray { + public Hooray map(final Eff f) { + return null; + } +} diff --git a/java/java-tests/testData/refactoring/moveMembers/parameterizedRefOn/after/pack1/C.java b/java/java-tests/testData/refactoring/moveMembers/parameterizedRefOn/after/pack1/C.java new file mode 100644 index 000000000000..c1d4bd54f34b --- /dev/null +++ b/java/java-tests/testData/refactoring/moveMembers/parameterizedRefOn/after/pack1/C.java @@ -0,0 +1,15 @@ +package pack1; + +public class C { + static POne> sequence(final Hooray> as) { + return new POne>() { + public Hooray _1() { + return as.map(C.__1()); + } + }; + } + + static Eff, A> __1() { + return POne::_1; + } +} \ No newline at end of file diff --git a/java/java-tests/testData/refactoring/moveMembers/parameterizedRefOn/before/pack1/A.java b/java/java-tests/testData/refactoring/moveMembers/parameterizedRefOn/before/pack1/A.java new file mode 100644 index 000000000000..6bdd2e6aaaa0 --- /dev/null +++ b/java/java-tests/testData/refactoring/moveMembers/parameterizedRefOn/before/pack1/A.java @@ -0,0 +1,28 @@ +package pack1; + +interface Eff { + B f(A a); +} + +abstract class POne { + abstract A _1(); + + static POne> sequence(final Hooray> as) { + return new POne>() { + public Hooray _1() { + return as.map(POne.__1()); + } + }; + } + + static Eff, A> __1() { + return POne::_1; + } + +} + +final class Hooray { + public Hooray map(final Eff f) { + return null; + } +} diff --git a/java/java-tests/testData/refactoring/moveMembers/parameterizedRefOn/before/pack1/C.java b/java/java-tests/testData/refactoring/moveMembers/parameterizedRefOn/before/pack1/C.java new file mode 100644 index 000000000000..bb7e3e001607 --- /dev/null +++ b/java/java-tests/testData/refactoring/moveMembers/parameterizedRefOn/before/pack1/C.java @@ -0,0 +1,4 @@ +package pack1; + +public class C { +} \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/CopyReferenceTest.groovy b/java/java-tests/testSrc/com/intellij/codeInsight/CopyReferenceTest.groovy index d2cc160b61f9..116b0f211ad3 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/CopyReferenceTest.groovy +++ b/java/java-tests/testSrc/com/intellij/codeInsight/CopyReferenceTest.groovy @@ -1,4 +1,4 @@ -package com.intellij.codeInsight; +package com.intellij.codeInsight import com.intellij.JavaTestUtil; import com.intellij.ide.actions.CopyReferenceAction; @@ -7,7 +7,6 @@ import com.intellij.openapi.actionSystem.IdeActions; import com.intellij.psi.PsiFile; import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase; import org.jetbrains.annotations.NonNls -import com.intellij.openapi.util.io.FileUtil; public class CopyReferenceTest extends LightCodeInsightFixtureTestCase { @NonNls private static final String BASE_PATH = "/codeInsight/copyReference"; @@ -53,11 +52,10 @@ public class CopyReferenceTest extends LightCodeInsightFixtureTestCase { myFixture.configureByText 'a.java', ''' class Foo { }''' - def path = FileUtil.toSystemDependentName(myFixture.file.virtualFile.path) performCopy() myFixture.configureByText 'a.txt', '' performPaste() - myFixture.checkResult "$path:2" + myFixture.checkResult "/a.java:2" } private void doTest() throws Exception { diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/completion/NormalCompletionOrderingTest.groovy b/java/java-tests/testSrc/com/intellij/codeInsight/completion/NormalCompletionOrderingTest.groovy index ad2ec9d61555..9b292a5f2c2e 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/completion/NormalCompletionOrderingTest.groovy +++ b/java/java-tests/testSrc/com/intellij/codeInsight/completion/NormalCompletionOrderingTest.groovy @@ -356,6 +356,19 @@ import java.lang.annotation.Target; checkPreferredItems 0, 'TMetaAnno', 'Target', 'TreeSelectionMode', 'TLocalAnno' } + public void testPreferApplicableAnnotationsMethod() throws Throwable { + myFixture.addClass ''' +import java.lang.annotation.ElementType; +import java.lang.annotation.Target; + +@Target({ElementType.TYPE}) +@interface TClassAnno {} + +@Target({ElementType.METHOD}) +@interface TMethodAnno {}''' + checkPreferredItems 0, 'TMethodAnno', 'TClassAnno' + } + public void testJComponentAddNewWithStats() throws Throwable { final LookupImpl lookup = invokeCompletion("/../smartTypeSorting/JComponentAddNew.java"); assertPreferredItems(0, "FooBean3", "JComponent", "Component"); diff --git a/java/java-tests/testSrc/com/intellij/refactoring/MoveMembersTest.java b/java/java-tests/testSrc/com/intellij/refactoring/MoveMembersTest.java index 62692954cc93..fbb83329f740 100644 --- a/java/java-tests/testSrc/com/intellij/refactoring/MoveMembersTest.java +++ b/java/java-tests/testSrc/com/intellij/refactoring/MoveMembersTest.java @@ -57,6 +57,10 @@ public class MoveMembersTest extends MultiFileTestCase { doTest("pack1.A", "pack1.C", 0, 1, 2); } + public void testParameterizedRefOn() throws Exception { + doTest("pack1.POne", "pack1.C", 1, 2); + } + public void testIDEADEV12448() throws Exception { doTest("B", "A", false, 0); } diff --git a/platform/core-api/src/com/intellij/lang/injection/InjectedLanguageManager.java b/platform/core-api/src/com/intellij/lang/injection/InjectedLanguageManager.java index f8b7d1a4014a..40d6fcacdbe5 100644 --- a/platform/core-api/src/com/intellij/lang/injection/InjectedLanguageManager.java +++ b/platform/core-api/src/com/intellij/lang/injection/InjectedLanguageManager.java @@ -55,10 +55,17 @@ public abstract class InjectedLanguageManager { public abstract TextRange injectedToHost(@NotNull PsiElement injectedContext, @NotNull TextRange injectedTextRange); public abstract int injectedToHost(@NotNull PsiElement injectedContext, int injectedOffset); - /** @see com.intellij.lang.injection.MultiHostInjector#MULTIHOST_INJECTOR_EP_NAME */ + /** + * Test-only method. + * @see com.intellij.lang.injection.MultiHostInjector#MULTIHOST_INJECTOR_EP_NAME + */ @Deprecated public abstract void registerMultiHostInjector(@NotNull MultiHostInjector injector); - /** @see com.intellij.lang.injection.MultiHostInjector#MULTIHOST_INJECTOR_EP_NAME */ + + /** + * Test-only method. + * @see com.intellij.lang.injection.MultiHostInjector#MULTIHOST_INJECTOR_EP_NAME + */ @Deprecated public abstract boolean unregisterMultiHostInjector(@NotNull MultiHostInjector injector); diff --git a/platform/core-impl/src/com/intellij/util/DocumentUtil.java b/platform/core-impl/src/com/intellij/util/DocumentUtil.java index d24da8a3caef..6eb84897d985 100644 --- a/platform/core-impl/src/com/intellij/util/DocumentUtil.java +++ b/platform/core-impl/src/com/intellij/util/DocumentUtil.java @@ -29,8 +29,15 @@ public class DocumentUtil { private DocumentUtil() { } - - // TODO den add doc + + /** + * Ensures that given task is executed when given document is at the given 'in bulk' mode. + * + * @param document target document + * @param executeInBulk true to force given document to be in bulk mode when given task is executed; + * false to force given document to be not in bulk mode when given task is executed + * @param task task to execute + */ public static void executeInBulk(@NotNull Document document, final boolean executeInBulk, @NotNull Runnable task) { if (!(document instanceof DocumentEx)) { task.run(); diff --git a/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/settings/ArrangementColorsAware.java b/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/settings/ArrangementColorsAware.java index 8935573ca0f3..8884a845a6d3 100644 --- a/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/settings/ArrangementColorsAware.java +++ b/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/settings/ArrangementColorsAware.java @@ -15,13 +15,27 @@ */ package com.intellij.psi.codeStyle.arrangement.settings; +import com.intellij.openapi.editor.colors.TextAttributesKey; +import com.intellij.psi.codeStyle.arrangement.model.ArrangementSettingType; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.awt.*; + /** - * Strategy which hints on what colors should be used at arrangement setting UI. + * Callback which allows to customize colors used at the arrangement UI on the basis of existing coloring scheme. * * @author Denis Zhdanov * @since 10/23/12 11:53 PM */ public interface ArrangementColorsAware { - // TODO den implement + @Nullable + TextAttributesKey getTextKey(@NotNull ArrangementSettingType type, boolean selected); + + @Nullable + TextAttributesKey getTextBackgroundKey(@NotNull ArrangementSettingType type, boolean selected); + + @Nullable + Color getBorderColor(boolean selected); } diff --git a/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/AbstractArrangementColorsProvider.java b/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/AbstractArrangementColorsProvider.java deleted file mode 100644 index ae79c9c8e6a0..000000000000 --- a/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/AbstractArrangementColorsProvider.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2000-2012 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.application.options.codeStyle.arrangement; - -import com.intellij.ui.GroupedElementsRenderer; -import com.intellij.util.ui.UIUtil; -import org.jetbrains.annotations.NotNull; - -import java.awt.*; - -/** - * @author Denis Zhdanov - * @since 10/23/12 11:47 PM - */ -public abstract class AbstractArrangementColorsProvider implements ArrangementColorsProvider { - - @NotNull private Color myNormalBorderColor; - @NotNull private Color mySelectedBorderColor; - - @NotNull - public Color getBorderColor(boolean selected) { - return selected ? mySelectedBorderColor : myNormalBorderColor; - } - - public void updateColors() { - myNormalBorderColor = UIUtil.getBorderColor(); - Color selectionBorderColor = UIUtil.getTreeSelectionBorderColor(); - if (selectionBorderColor == null) { - selectionBorderColor = GroupedElementsRenderer.SELECTED_FRAME_FOREGROUND; - } - mySelectedBorderColor = selectionBorderColor; - } -} diff --git a/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/ArrangementColorsProvider.java b/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/ArrangementColorsProvider.java index 5a9d29c7b06b..117bc1b8c409 100644 --- a/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/ArrangementColorsProvider.java +++ b/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/ArrangementColorsProvider.java @@ -25,18 +25,13 @@ import java.awt.*; * @since 10/23/12 11:46 PM */ public interface ArrangementColorsProvider { + @NotNull Color getBorderColor(boolean selected); @NotNull - Color getTextColor(@NotNull ArrangementSettingType type); + Color getTextColor(@NotNull ArrangementSettingType type, boolean selected); @NotNull - Color getTextBackgroundColor(@NotNull ArrangementSettingType type); - - @NotNull - Color getSelectedTextColor(@NotNull ArrangementSettingType type); - - @NotNull - Color getSelectedTextBackgroundColor(@NotNull ArrangementSettingType type); + Color getTextBackgroundColor(@NotNull ArrangementSettingType type, boolean selected); } diff --git a/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/ArrangementColorsProviderImpl.java b/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/ArrangementColorsProviderImpl.java new file mode 100644 index 000000000000..9b1858692ae3 --- /dev/null +++ b/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/ArrangementColorsProviderImpl.java @@ -0,0 +1,155 @@ +/* + * Copyright 2000-2012 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.application.options.codeStyle.arrangement; + +import com.intellij.openapi.editor.colors.EditorColorsManager; +import com.intellij.openapi.editor.colors.EditorColorsScheme; +import com.intellij.openapi.editor.colors.TextAttributesKey; +import com.intellij.openapi.editor.markup.TextAttributes; +import com.intellij.psi.codeStyle.arrangement.model.ArrangementSettingType; +import com.intellij.psi.codeStyle.arrangement.settings.ArrangementColorsAware; +import com.intellij.ui.GroupedElementsRenderer; +import com.intellij.util.ui.UIUtil; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.awt.*; +import java.util.EnumMap; +import java.util.Map; + +/** + * @author Denis Zhdanov + * @since 10/24/12 4:25 PM + */ +public class ArrangementColorsProviderImpl implements ArrangementColorsProvider { + + @Nullable private final ArrangementColorsAware myColorsAware; + + @NotNull private final Map myTextColors + = new EnumMap(ArrangementSettingType.class); + @NotNull private final Map myBackgroundColors + = new EnumMap(ArrangementSettingType.class); + @NotNull private final Map mySelectedTextColors + = new EnumMap(ArrangementSettingType.class); + @NotNull private final Map mySelectedBackgroundColors + = new EnumMap(ArrangementSettingType.class); + + @NotNull private Color myBorderColor; + @NotNull private Color mySelectedBorderColor; + + public ArrangementColorsProviderImpl(@Nullable ArrangementColorsAware colorsAware) { + myColorsAware = colorsAware; + applyDefaultColors(); + if (colorsAware != null) { + applyCustomColors(colorsAware); + } + } + + @NotNull + @Override + public Color getBorderColor(boolean selected) { + return selected ? myBorderColor : mySelectedBorderColor; + } + + @NotNull + @Override + public Color getTextColor(@NotNull ArrangementSettingType type, boolean selected) { + return selected ? mySelectedTextColors.get(type) : myTextColors.get(type); + } + + @NotNull + @Override + public Color getTextBackgroundColor(@NotNull ArrangementSettingType type, boolean selected) { + return selected ? mySelectedBackgroundColors.get(type) : myBackgroundColors.get(type); + } + + /** + * Asks the implementation to ensure that it uses the most up-to-date colors. + *

+ * I.e. this method is assumed to be called when color settings has been changed and gives a chance to reflect the changes + * accordingly. + */ + public void refresh() { + if (myColorsAware == null) { + return; + } + + myTextColors.clear(); + myBackgroundColors.clear(); + mySelectedTextColors.clear(); + mySelectedBackgroundColors.clear(); + + applyDefaultColors(); + applyCustomColors(myColorsAware); + } + + private void applyDefaultColors() { + Color textColor = UIUtil.getTreeTextForeground(); + Color selectedTextColor = UIUtil.getTreeSelectionForeground(); + Color backgroundColor = UIUtil.getPanelBackground(); + Color selectedBackgroundColor = UIUtil.getTreeSelectionBackground(); + for (ArrangementSettingType type : ArrangementSettingType.values()) { + myTextColors.put(type, textColor); + mySelectedTextColors.put(type, selectedTextColor); + myBackgroundColors.put(type, backgroundColor); + mySelectedBackgroundColors.put(type, selectedBackgroundColor); + } + + myBorderColor = UIUtil.getBorderColor(); + Color selectionBorderColor = UIUtil.getTreeSelectionBorderColor(); + if (selectionBorderColor == null) { + selectionBorderColor = GroupedElementsRenderer.SELECTED_FRAME_FOREGROUND; + } + mySelectedBorderColor = selectionBorderColor; + } + + private void applyCustomColors(@NotNull ArrangementColorsAware colorsAware) { + EditorColorsScheme scheme = EditorColorsManager.getInstance().getGlobalScheme(); + for (ArrangementSettingType type : ArrangementSettingType.values()) { + applyColorIfPossible(scheme, colorsAware.getTextKey(type, false), type, myTextColors); + applyColorIfPossible(scheme, colorsAware.getTextKey(type, true), type, mySelectedTextColors); + applyColorIfPossible(scheme, colorsAware.getTextBackgroundKey(type, false), type, myBackgroundColors); + applyColorIfPossible(scheme, colorsAware.getTextBackgroundKey(type, true), type, mySelectedBackgroundColors); + } + + Color borderColor = colorsAware.getBorderColor(false); + if (borderColor != null) { + myBorderColor = borderColor; + } + Color selectedBorderColor = colorsAware.getBorderColor(true); + if (selectedBorderColor != null) { + mySelectedBorderColor = selectedBorderColor; + } + } + + private static void applyColorIfPossible(@NotNull EditorColorsScheme scheme, + @Nullable TextAttributesKey key, + @NotNull ArrangementSettingType type, + @NotNull Map holder) + { + if (key == null) { + return; + } + TextAttributes attributes = scheme.getAttributes(key); + if (attributes == null) { + return; + } + Color color = attributes.getForegroundColor(); + if (color != null) { + holder.put(type, color); + } + } +} diff --git a/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/ArrangementColorsService.java b/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/ArrangementColorsService.java deleted file mode 100644 index f7d2bb280b62..000000000000 --- a/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/ArrangementColorsService.java +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright 2000-2012 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.application.options.codeStyle.arrangement; - -import com.intellij.ide.ui.LafManager; -import com.intellij.ide.ui.LafManagerListener; -import com.intellij.ui.GroupedElementsRenderer; -import com.intellij.util.ui.UIUtil; -import org.jetbrains.annotations.NotNull; - -import java.awt.*; - -/** - * @author Denis Zhdanov - * @since 9/6/12 2:30 PM - */ -public class ArrangementColorsService { - - @NotNull private Color myNormalTextColor; - @NotNull private Color mySelectedTextColor; - @NotNull private Color myNormalBackgroundColor; - @NotNull private Color mySelectedBackgroundColor; - @NotNull private Color myNormalBorderColor; - @NotNull private Color mySelectedBorderColor; - - public ArrangementColorsService(@NotNull LafManager lafManager) { - lafManager.addLafManagerListener(new LafManagerListener() { - @Override - public void lookAndFeelChanged(LafManager source) { - updateColors(); - } - }); - updateColors(); - } - - @NotNull - public Color getTextColor(boolean selected) { - return selected ? mySelectedTextColor : myNormalTextColor; - } - - @NotNull - public Color getBackgroundColor(boolean selected) { - return selected ? mySelectedBackgroundColor : myNormalBackgroundColor; - } - - @NotNull - public Color getBorderColor(boolean selected) { - return selected ? mySelectedBorderColor : myNormalBorderColor; - } - - private void updateColors() { - myNormalTextColor = UIUtil.getTreeTextForeground(); - mySelectedTextColor = UIUtil.getTreeSelectionForeground(); - myNormalBackgroundColor = UIUtil.getPanelBackground(); - mySelectedBackgroundColor = UIUtil.getTreeSelectionBackground(); - myNormalBorderColor = UIUtil.getBorderColor(); - Color selectionBorderColor = UIUtil.getTreeSelectionBorderColor(); - if (selectionBorderColor == null) { - selectionBorderColor = GroupedElementsRenderer.SELECTED_FRAME_FOREGROUND; - } - mySelectedBorderColor = selectionBorderColor; - } -} diff --git a/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/ArrangementRuleEditor.java b/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/ArrangementRuleEditor.java index 3768fab1eeef..ae81b35468ff 100644 --- a/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/ArrangementRuleEditor.java +++ b/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/ArrangementRuleEditor.java @@ -49,10 +49,14 @@ public class ArrangementRuleEditor extends JPanel { new HashMap(); @NotNull private final ArrangementStandardSettingsAware myFilter; + @NotNull private final ArrangementColorsProvider myColorsProvider; @Nullable private ArrangementRuleEditingModel myModel; - public ArrangementRuleEditor(@NotNull ArrangementStandardSettingsAware filter, @NotNull ArrangementNodeDisplayManager displayManager) { + public ArrangementRuleEditor(@NotNull ArrangementStandardSettingsAware filter, + @NotNull ArrangementColorsProvider provider, + @NotNull ArrangementNodeDisplayManager displayManager) { myFilter = filter; + myColorsProvider = provider; init(displayManager); addMouseListener(new MouseAdapter() { @Override @@ -82,7 +86,7 @@ public class ArrangementRuleEditor extends JPanel { JPanel valuesPanel = new MultiRowFlowPanel(FlowLayout.LEFT, 8, 5); for (Object value : manager.sort(values)) { ArrangementAtomMatchNodeComponent component = - new ArrangementAtomMatchNodeComponent(manager, new ArrangementAtomMatchCondition(key, value), null); + new ArrangementAtomMatchNodeComponent(manager, myColorsProvider, new ArrangementAtomMatchCondition(key, value), null); myComponents.put(value, component); valuesPanel.add(component.getUiComponent()); } diff --git a/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/ArrangementRuleTree.java b/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/ArrangementRuleTree.java index 38d8b5c2c725..afc042f73807 100644 --- a/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/ArrangementRuleTree.java +++ b/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/ArrangementRuleTree.java @@ -42,7 +42,6 @@ import org.jetbrains.annotations.Nullable; import javax.swing.*; import javax.swing.event.TreeSelectionEvent; import javax.swing.event.TreeSelectionListener; -import javax.swing.plaf.TreeUI; import javax.swing.tree.*; import java.awt.*; import java.awt.event.ActionEvent; @@ -92,10 +91,11 @@ public class ArrangementRuleTree { public ArrangementRuleTree(@Nullable StdArrangementSettings settings, @NotNull List> uiGroupingRules, @NotNull ArrangementNodeDisplayManager displayManager, + @NotNull ArrangementColorsProvider colorsProvider, @NotNull ArrangementStandardSettingsAware settingsFilter) { myUiGroupingRules = uiGroupingRules; - myFactory = new ArrangementMatchNodeComponentFactory(displayManager, new Runnable() { + myFactory = new ArrangementMatchNodeComponentFactory(displayManager, colorsProvider, new Runnable() { @Override public void run() { notifySelectionListeners(); diff --git a/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/ArrangementSettingsPanel.java b/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/ArrangementSettingsPanel.java index 51fb899b95b0..e72d642e24a0 100644 --- a/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/ArrangementSettingsPanel.java +++ b/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/ArrangementSettingsPanel.java @@ -32,10 +32,7 @@ import com.intellij.psi.codeStyle.CodeStyleSettings; import com.intellij.psi.codeStyle.arrangement.Rearranger; import com.intellij.psi.codeStyle.arrangement.StdArrangementSettings; import com.intellij.psi.codeStyle.arrangement.model.ArrangementMatchCondition; -import com.intellij.psi.codeStyle.arrangement.settings.ArrangementConditionsGrouper; -import com.intellij.psi.codeStyle.arrangement.settings.ArrangementStandardSettingsAware; -import com.intellij.psi.codeStyle.arrangement.settings.ArrangementStandardSettingsRepresentationAware; -import com.intellij.psi.codeStyle.arrangement.settings.DefaultArrangementSettingsRepresentationManager; +import com.intellij.psi.codeStyle.arrangement.settings.*; import com.intellij.ui.IdeBorderFactory; import com.intellij.ui.SideBorder; import com.intellij.ui.components.JBScrollPane; @@ -94,6 +91,13 @@ public abstract class ArrangementSettingsPanel extends CodeStyleAbstractPanel { final ArrangementNodeDisplayManager displayManager = new ArrangementNodeDisplayManager( mySettingsAware, representationManager, groupingRules ); + final ArrangementColorsProvider colorsProvider; + if (rearranger instanceof ArrangementColorsAware) { + colorsProvider = new ArrangementColorsProviderImpl((ArrangementColorsAware)rearranger); + } + else { + colorsProvider = new ArrangementColorsProviderImpl(null); + } final ActionManager actionManager = ActionManager.getInstance(); final ActionGroup actionGroup = (ActionGroup)actionManager.getAction(ArrangementConstants.ACTION_GROUP_RULE_EDITOR_TOOL_WINDOW); @@ -103,7 +107,7 @@ public abstract class ArrangementSettingsPanel extends CodeStyleAbstractPanel { toolbarControl.setBorder(IdeBorderFactory.createBorder(SideBorder.LEFT | SideBorder.TOP | SideBorder.RIGHT)); myContent.add(toolbarControl, new GridBag().weightx(1).fillCellHorizontally().coverLine()); - myRuleTree = new ArrangementRuleTree(getSettings(settings), groupingRules, displayManager, mySettingsAware); + myRuleTree = new ArrangementRuleTree(getSettings(settings), groupingRules, displayManager, colorsProvider, mySettingsAware); final Tree treeComponent = myRuleTree.getTreeComponent(); actionToolbar.setTargetComponent(treeComponent); JBScrollPane scrollPane = new JBScrollPane(treeComponent); @@ -113,7 +117,7 @@ public abstract class ArrangementSettingsPanel extends CodeStyleAbstractPanel { ); final JXTaskPane editorPane = new JXTaskPane(ApplicationBundle.message("arrangement.title.editor")); - final ArrangementRuleEditor ruleEditor = new ArrangementRuleEditor(mySettingsAware, displayManager); + final ArrangementRuleEditor ruleEditor = new ArrangementRuleEditor(mySettingsAware, colorsProvider, displayManager); ruleEditor.applyBackground(treeComponent.getBackground()); editorPane.getContentPane().setBackground(treeComponent.getBackground()); editorPane.add(ruleEditor); diff --git a/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/DefaultArrangementColorsProvider.java b/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/DefaultArrangementColorsProvider.java deleted file mode 100644 index 5a19c477973b..000000000000 --- a/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/DefaultArrangementColorsProvider.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright 2000-2012 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.application.options.codeStyle.arrangement; - -import com.intellij.psi.codeStyle.arrangement.model.ArrangementSettingType; -import com.intellij.util.ui.UIUtil; -import org.jetbrains.annotations.NotNull; - -import java.awt.*; - -/** - * @author Denis Zhdanov - * @since 10/23/12 11:50 PM - */ -public class DefaultArrangementColorsProvider extends AbstractArrangementColorsProvider { - - @NotNull private Color myNormalTextColor; - @NotNull private Color mySelectedTextColor; - @NotNull private Color myNormalBackgroundColor; - @NotNull private Color mySelectedBackgroundColor; - - @NotNull - @Override - public Color getTextColor(@NotNull ArrangementSettingType type) { - return myNormalTextColor; - } - - @NotNull - @Override - public Color getTextBackgroundColor(@NotNull ArrangementSettingType type) { - return myNormalBackgroundColor; - } - - @NotNull - @Override - public Color getSelectedTextColor(@NotNull ArrangementSettingType type) { - return mySelectedTextColor; - } - - @NotNull - @Override - public Color getSelectedTextBackgroundColor(@NotNull ArrangementSettingType type) { - return mySelectedBackgroundColor; - } - - @Override - public void updateColors() { - super.updateColors(); - myNormalTextColor = UIUtil.getTreeTextForeground(); - mySelectedTextColor = UIUtil.getTreeSelectionForeground(); - myNormalBackgroundColor = UIUtil.getPanelBackground(); - mySelectedBackgroundColor = UIUtil.getTreeSelectionBackground(); - } -} diff --git a/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/node/match/ArrangementAtomMatchNodeComponent.java b/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/node/match/ArrangementAtomMatchNodeComponent.java index deb96ee2c09a..ca55456b1b61 100644 --- a/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/node/match/ArrangementAtomMatchNodeComponent.java +++ b/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/node/match/ArrangementAtomMatchNodeComponent.java @@ -43,8 +43,6 @@ public class ArrangementAtomMatchNodeComponent implements ArrangementMatchNodeCo public static final int VERTICAL_PADDING = 2; public static final int HORIZONTAL_PADDING = 8; - @NotNull private final ArrangementColorsService myColorsService = ServiceManager.getService(ArrangementColorsService.class); - @NotNull private final JPanel myRenderer = new JPanel(new GridBagLayout()) { @Override public void paint(Graphics g) { @@ -77,11 +75,13 @@ public class ArrangementAtomMatchNodeComponent implements ArrangementMatchNodeCo return myLabelSize == null ? super.getPreferredSize() : myLabelSize; } }; - @NotNull private final RoundedLineBorder myBorder; - @NotNull private final ArrangementAtomMatchCondition myCondition; - @Nullable private final ActionButton myCloseButton; - @Nullable private final Runnable myCloseCallback; + @NotNull private final ArrangementColorsProvider myColorsProvider; + @NotNull private final RoundedLineBorder myBorder; + @NotNull private final ArrangementAtomMatchCondition myCondition; + + @Nullable private final ActionButton myCloseButton; + @Nullable private final Runnable myCloseCallback; @NotNull private Color myBackgroundColor; @@ -93,9 +93,11 @@ public class ArrangementAtomMatchNodeComponent implements ArrangementMatchNodeCo private boolean myCloseButtonHovered; public ArrangementAtomMatchNodeComponent(@NotNull ArrangementNodeDisplayManager manager, + @NotNull ArrangementColorsProvider colorsProvider, @NotNull ArrangementAtomMatchCondition condition, @Nullable Runnable closeCallback) { + myColorsProvider = colorsProvider; myCondition = condition; myCloseCallback = closeCallback; myLabel.setHorizontalAlignment(SwingConstants.CENTER); @@ -186,9 +188,9 @@ public class ArrangementAtomMatchNodeComponent implements ArrangementMatchNodeCo * @param selected flag that indicates if current component should be drawn as 'selected' */ public void setSelected(boolean selected) { - myLabel.setForeground(myColorsService.getTextColor(selected)); - myBorder.setColor(myColorsService.getBorderColor(selected)); - myBackgroundColor = myColorsService.getBackgroundColor(selected); + myLabel.setForeground(myColorsProvider.getTextColor(myCondition.getType(), selected)); + myBorder.setColor(myColorsProvider.getBorderColor(selected)); + myBackgroundColor = myColorsProvider.getTextBackgroundColor(myCondition.getType(), selected); } public boolean isEnabled() { diff --git a/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/node/match/ArrangementGroupingMatchNodeComponent.java b/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/node/match/ArrangementGroupingMatchNodeComponent.java index 4d76c007e4b6..ecef8af22361 100644 --- a/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/node/match/ArrangementGroupingMatchNodeComponent.java +++ b/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/node/match/ArrangementGroupingMatchNodeComponent.java @@ -15,10 +15,8 @@ */ package com.intellij.application.options.codeStyle.arrangement.node.match; -import com.intellij.application.options.codeStyle.arrangement.ArrangementColorsService; import com.intellij.application.options.codeStyle.arrangement.ArrangementConfigUtil; import com.intellij.application.options.codeStyle.arrangement.ArrangementNodeDisplayManager; -import com.intellij.openapi.components.ServiceManager; import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.codeStyle.arrangement.model.ArrangementAtomMatchCondition; import com.intellij.psi.codeStyle.arrangement.model.ArrangementMatchCondition; @@ -40,12 +38,10 @@ public class ArrangementGroupingMatchNodeComponent extends JPanel implements Arr private static final int TOP_INSET = 3; - @NotNull private final ArrangementColorsService myColorsService = ServiceManager.getService(ArrangementColorsService.class); @NotNull private final ArrangementAtomMatchCondition myCondition; @Nullable private Rectangle myScreenBounds; @NotNull private Dimension myPreferredSize; - private boolean mySelected; public ArrangementGroupingMatchNodeComponent(@NotNull ArrangementNodeDisplayManager manager, @NotNull ArrangementAtomMatchCondition condition) @@ -104,7 +100,6 @@ public class ArrangementGroupingMatchNodeComponent extends JPanel implements Arr @Override public void setSelected(boolean selected) { - mySelected = selected; } @Nullable @@ -126,10 +121,6 @@ public class ArrangementGroupingMatchNodeComponent extends JPanel implements Arr int y = TOP_INSET; g.drawLine(cornerX, y, bounds.width, y); g.drawLine(cornerX, y, cornerX, y + bounds.height); - if (mySelected) { - g.setColor(myColorsService.getBackgroundColor(true)); - g.fillRect(cornerX + 1, y + 1, bounds.width - 1, bounds.height - 1); - } Point point = ArrangementConfigUtil.getLocationOnScreen(this); if (point != null) { diff --git a/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/node/match/ArrangementMatchNodeComponentFactory.java b/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/node/match/ArrangementMatchNodeComponentFactory.java index 72542769a6c5..6fb7e6b6a9a0 100644 --- a/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/node/match/ArrangementMatchNodeComponentFactory.java +++ b/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/node/match/ArrangementMatchNodeComponentFactory.java @@ -15,6 +15,7 @@ */ package com.intellij.application.options.codeStyle.arrangement.node.match; +import com.intellij.application.options.codeStyle.arrangement.ArrangementColorsProvider; import com.intellij.application.options.codeStyle.arrangement.ArrangementNodeDisplayManager; import com.intellij.application.options.codeStyle.arrangement.ArrangementRuleEditingModel; import com.intellij.openapi.util.Ref; @@ -37,13 +38,15 @@ public class ArrangementMatchNodeComponentFactory { @NotNull private final Set myGroupingConditions = ContainerUtilRt.newHashSet(); @NotNull private final ArrangementNodeDisplayManager myDisplayManager; + @NotNull private final ArrangementColorsProvider myColorsProvider; @NotNull private final Runnable myRemoveConditionCallback; public ArrangementMatchNodeComponentFactory(@NotNull ArrangementNodeDisplayManager manager, - @NotNull Runnable removeConditionCallback, + @NotNull ArrangementColorsProvider provider, @NotNull Runnable removeConditionCallback, @NotNull List> groupingRules) { myDisplayManager = manager; + myColorsProvider = provider; myRemoveConditionCallback = removeConditionCallback; for (Set rules : groupingRules) { myGroupingConditions.addAll(rules); @@ -63,7 +66,9 @@ public class ArrangementMatchNodeComponentFactory { component = new ArrangementGroupingMatchNodeComponent(myDisplayManager, condition); } else { - component = new ArrangementAtomMatchNodeComponent(myDisplayManager, condition, prepareRemoveCallback(condition, model)); + component = new ArrangementAtomMatchNodeComponent( + myDisplayManager, myColorsProvider, condition, prepareRemoveCallback(condition, model) + ); } ref.set(component); } diff --git a/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionLookupArranger.java b/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionLookupArranger.java index 9d15ee126cf1..44140daccd81 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionLookupArranger.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionLookupArranger.java @@ -236,7 +236,7 @@ public class CompletionLookupArranger extends LookupArranger { private static void ensureEverythingVisibleAdded(LookupImpl lookup, final LinkedHashSet model, Iterator byRelevance) { JList list = lookup.getList(); final boolean testMode = ApplicationManager.getApplication().isUnitTestMode(); - final int limit = Math.max(list.getLastVisibleIndex(), model.size()) + list.getVisibleRowCount() * 3; + final int limit = Math.max(list.getLastVisibleIndex(), model.size()) + ourUISettings.MAX_LOOKUP_LIST_HEIGHT * 3; addSomeItems(model, byRelevance, new Condition() { @Override public boolean value(LookupElement lastAdded) { diff --git a/platform/lang-impl/src/com/intellij/codeInsight/completion/impl/CompletionServiceImpl.java b/platform/lang-impl/src/com/intellij/codeInsight/completion/impl/CompletionServiceImpl.java index 8ab05d80133f..7806c2fbf413 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/completion/impl/CompletionServiceImpl.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/completion/impl/CompletionServiceImpl.java @@ -243,7 +243,7 @@ public class CompletionServiceImpl extends CompletionService{ for (final Weigher weigher : WeighingService.getWeighers(CompletionService.RELEVANCE_KEY)) { final String id = weigher.toString(); if ("prefix".equals(id)) { - sorter = sorter.withClassifier(CompletionSorterImpl.weighingFactory(new PrefixMatchingClassifier(location))); + sorter = sorter.withClassifier(CompletionSorterImpl.weighingFactory(new RealPrefixMatchingWeigher(location))); } else if ("stats".equals(id)) { sorter = sorter.withClassifier(CompletionSorterImpl.weighingFactory(new StatisticsWeigher.LookupStatisticsWeigher(location))); @@ -276,25 +276,11 @@ public class CompletionServiceImpl extends CompletionService{ return new CompletionSorterImpl(new ArrayList>()); } - private static class PreferStartMatching extends LookupElementWeigher { - private final CompletionLocation myLocation; - - public PreferStartMatching(CompletionLocation location) { - super("middleMatching", false, true); - myLocation = location; - } - - @Override - public Comparable weigh(@NotNull LookupElement element) { - return !isStartMatch(element, myLocation.getCompletionParameters().getLookup()); - } - } - public static boolean isStartMatch(LookupElement element, Lookup lookup) { return getItemMatcher(element, lookup).isStartMatch(element); } - private static PrefixMatcher getItemMatcher(LookupElement element, Lookup lookup) { + static PrefixMatcher getItemMatcher(LookupElement element, Lookup lookup) { PrefixMatcher itemMatcher = lookup.itemMatcher(element); String pattern = lookup.itemPattern(element); if (!pattern.equals(itemMatcher.getPrefix())) { @@ -302,25 +288,4 @@ public class CompletionServiceImpl extends CompletionService{ } return itemMatcher; } - - private static class PrefixMatchingClassifier extends LookupElementWeigher { - private final CompletionLocation myLocation; - - public PrefixMatchingClassifier(CompletionLocation location) { - super("prefix", false, true); - myLocation = location; - } - - @Override - public Comparable weigh(@NotNull LookupElement element) { - final PrefixMatcher matcher = getItemMatcher(element, myLocation.getCompletionParameters().getLookup()); - - int max = Integer.MIN_VALUE; - for (String lookupString : element.getAllLookupStrings()) { - max = Math.max(max, matcher.matchingDegree(lookupString)); - } - return -max; - } - - } } diff --git a/platform/lang-impl/src/com/intellij/codeInsight/completion/impl/PreferStartMatching.java b/platform/lang-impl/src/com/intellij/codeInsight/completion/impl/PreferStartMatching.java new file mode 100644 index 000000000000..569806405562 --- /dev/null +++ b/platform/lang-impl/src/com/intellij/codeInsight/completion/impl/PreferStartMatching.java @@ -0,0 +1,23 @@ +package com.intellij.codeInsight.completion.impl; + +import com.intellij.codeInsight.completion.CompletionLocation; +import com.intellij.codeInsight.lookup.LookupElement; +import com.intellij.codeInsight.lookup.LookupElementWeigher; +import org.jetbrains.annotations.NotNull; + +/** +* @author Peter +*/ +public class PreferStartMatching extends LookupElementWeigher { + private final CompletionLocation myLocation; + + public PreferStartMatching(CompletionLocation location) { + super("middleMatching", false, true); + myLocation = location; + } + + @Override + public Comparable weigh(@NotNull LookupElement element) { + return !CompletionServiceImpl.isStartMatch(element, myLocation.getCompletionParameters().getLookup()); + } +} diff --git a/platform/lang-impl/src/com/intellij/codeInsight/completion/impl/RealPrefixMatchingWeigher.java b/platform/lang-impl/src/com/intellij/codeInsight/completion/impl/RealPrefixMatchingWeigher.java new file mode 100644 index 000000000000..26491a0bb36d --- /dev/null +++ b/platform/lang-impl/src/com/intellij/codeInsight/completion/impl/RealPrefixMatchingWeigher.java @@ -0,0 +1,31 @@ +package com.intellij.codeInsight.completion.impl; + +import com.intellij.codeInsight.completion.CompletionLocation; +import com.intellij.codeInsight.completion.PrefixMatcher; +import com.intellij.codeInsight.lookup.LookupElement; +import com.intellij.codeInsight.lookup.LookupElementWeigher; +import org.jetbrains.annotations.NotNull; + +/** +* @author Peter +*/ +public class RealPrefixMatchingWeigher extends LookupElementWeigher { + private final CompletionLocation myLocation; + + public RealPrefixMatchingWeigher(CompletionLocation location) { + super("prefix", false, true); + myLocation = location; + } + + @Override + public Comparable weigh(@NotNull LookupElement element) { + final PrefixMatcher matcher = CompletionServiceImpl.getItemMatcher(element, myLocation.getCompletionParameters().getLookup()); + + int max = Integer.MIN_VALUE; + for (String lookupString : element.getAllLookupStrings()) { + max = Math.max(max, matcher.matchingDegree(lookupString)); + } + return -max; + } + +} diff --git a/platform/lang-impl/src/com/intellij/codeInsight/editorActions/PasteHandler.java b/platform/lang-impl/src/com/intellij/codeInsight/editorActions/PasteHandler.java index c59007aa2643..a419d07e811d 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/editorActions/PasteHandler.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/editorActions/PasteHandler.java @@ -28,6 +28,7 @@ import com.intellij.openapi.editor.*; import com.intellij.openapi.editor.actionSystem.EditorActionHandler; import com.intellij.openapi.editor.actionSystem.EditorActionManager; import com.intellij.openapi.editor.actionSystem.EditorTextInsertHandler; +import com.intellij.openapi.editor.ex.DocumentEx; import com.intellij.openapi.editor.ex.EditorEx; import com.intellij.openapi.extensions.ExtensionPointName; import com.intellij.openapi.extensions.Extensions; @@ -39,6 +40,7 @@ import com.intellij.openapi.util.TextRange; import com.intellij.psi.PsiDocumentManager; import com.intellij.psi.PsiFile; import com.intellij.psi.codeStyle.CodeStyleManager; +import com.intellij.util.DocumentUtil; import com.intellij.util.IncorrectOperationException; import com.intellij.util.Producer; import com.intellij.util.containers.HashMap; @@ -365,15 +367,23 @@ public class PasteHandler extends EditorActionHandler implements EditorTextInser } } - private static void reformatBlock(Project project, Editor editor, int startOffset, int endOffset) { + private static void reformatBlock(final Project project, final Editor editor, final int startOffset, final int endOffset) { PsiDocumentManager.getInstance(project).commitAllDocuments(); - PsiFile file = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument()); + Runnable task = new Runnable() { + @Override + public void run() { + PsiFile file = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument()); + try { + CodeStyleManager.getInstance(project).reformatRange(file, startOffset, endOffset, true); + } + catch (IncorrectOperationException e) { + LOG.error(e); + } + } + }; - try { - CodeStyleManager.getInstance(project).reformatRange(file, startOffset, endOffset, true); - } - catch (IncorrectOperationException e) { - LOG.error(e); + if (endOffset - startOffset > 1000) { + DocumentUtil.executeInBulk(editor.getDocument(), true, task); } } diff --git a/platform/lang-impl/src/com/intellij/formatting/FormatProcessor.java b/platform/lang-impl/src/com/intellij/formatting/FormatProcessor.java index 54a2ab6e1e14..6ef3916b343d 100644 --- a/platform/lang-impl/src/com/intellij/formatting/FormatProcessor.java +++ b/platform/lang-impl/src/com/intellij/formatting/FormatProcessor.java @@ -321,8 +321,9 @@ class FormatProcessor { * false otherwise */ @SuppressWarnings({"deprecation"}) - private boolean applyChangesAtBulkMode(final List blocksToModify, final FormattingModel model, - @NotNull CommonCodeStyleSettings.IndentOptions indentOption) + private boolean applyChangesAtRewriteMode(@NotNull final List blocksToModify, + @NotNull final FormattingModel model, + @NotNull CommonCodeStyleSettings.IndentOptions indentOption) { FormattingDocumentModel documentModel = model.getDocumentModel(); Document document = documentModel.getDocument(); @@ -366,14 +367,13 @@ class FormatProcessor { @Nullable private static DocumentEx getAffectedDocument(final FormattingModel model) { - if (model instanceof DocumentBasedFormattingModel) { - final Document document = ((DocumentBasedFormattingModel)model).getDocument(); - if (document instanceof DocumentEx) return (DocumentEx)document; - }/* else if (false) { // till issue with persistent range markers dropped fixed - Document document = model.getDocumentModel().getDocument(); - if (document instanceof DocumentEx) return (DocumentEx)document; - }*/ - return null; + final Document document = model.getDocumentModel().getDocument(); + if (document instanceof DocumentEx) { + return (DocumentEx)document; + } + else { + return null; + } } private static int replaceWhiteSpace(final FormattingModel model, @@ -1397,7 +1397,7 @@ class FormatProcessor { myResetBulkUpdateState = true; } if (blocksToModifyCount > BULK_REPLACE_OPTIMIZATION_CRITERIA - && applyChangesAtBulkMode(myBlocksToModify, myModel, myDefaultIndentOption)) + && applyChangesAtRewriteMode(myBlocksToModify, myModel, myDefaultIndentOption)) { setDone(true); } diff --git a/platform/lang-impl/src/com/intellij/ide/actions/CopyReferenceAction.java b/platform/lang-impl/src/com/intellij/ide/actions/CopyReferenceAction.java index 14689d0bdc4d..145d46b9688c 100644 --- a/platform/lang-impl/src/com/intellij/ide/actions/CopyReferenceAction.java +++ b/platform/lang-impl/src/com/intellij/ide/actions/CopyReferenceAction.java @@ -29,6 +29,7 @@ import com.intellij.openapi.editor.markup.TextAttributes; import com.intellij.openapi.extensions.Extensions; import com.intellij.openapi.fileEditor.FileDocumentManager; import com.intellij.openapi.ide.CopyPasteManager; +import com.intellij.openapi.project.DumbAwareAction; import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.ProjectRootManager; import com.intellij.openapi.util.io.FileUtil; @@ -36,9 +37,7 @@ import com.intellij.openapi.vfs.VfsUtil; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.wm.WindowManager; import com.intellij.openapi.wm.ex.StatusBarEx; -import com.intellij.psi.PsiElement; -import com.intellij.psi.PsiFile; -import com.intellij.psi.PsiReference; +import com.intellij.psi.*; import com.intellij.util.ArrayUtil; import com.intellij.util.LogicalRoot; import com.intellij.util.LogicalRootsManager; @@ -58,7 +57,7 @@ import java.util.zip.ZipEntry; /** * @author Alexey */ -public class CopyReferenceAction extends AnAction { +public class CopyReferenceAction extends DumbAwareAction { public static final DataFlavor ourFlavor; static { try { @@ -141,9 +140,9 @@ public class CopyReferenceAction extends AnAction { if (!doCopy(element, project, editor) && editor != null) { Document document = editor.getDocument(); - VirtualFile file = FileDocumentManager.getInstance().getFile(document); + PsiFile file = PsiDocumentManager.getInstance(project).getCachedPsiFile(document); if (file != null) { - String toCopy = FileUtil.toSystemDependentName(file.getPath()) + ":" + (editor.getCaretModel().getLogicalPosition().line + 1); + String toCopy = getFileFqn(file) + ":" + (editor.getCaretModel().getLogicalPosition().line + 1); CopyPasteManager.getInstance().setContents(new StringSelection(toCopy)); setStatusBarText(project, toCopy + " has been copied"); } @@ -181,6 +180,13 @@ public class CopyReferenceAction extends AnAction { if (element == null) { element = LangDataKeys.PSI_ELEMENT.getData(dataContext); } + if (element == null && editor == null) { + VirtualFile virtualFile = PlatformDataKeys.VIRTUAL_FILE.getData(dataContext); + Project project = PlatformDataKeys.PROJECT.getData(dataContext); + if (virtualFile != null && project != null) { + element = PsiManager.getInstance(project).findFile(virtualFile); + } + } if (element instanceof PsiFile && !((PsiFile)element).getViewProvider().isPhysical()) { return null; } diff --git a/platform/lang-impl/src/com/intellij/ide/util/AbstractTreeClassChooserDialog.java b/platform/lang-impl/src/com/intellij/ide/util/AbstractTreeClassChooserDialog.java index 1bfbac3e4004..81c9146ba8ca 100644 --- a/platform/lang-impl/src/com/intellij/ide/util/AbstractTreeClassChooserDialog.java +++ b/platform/lang-impl/src/com/intellij/ide/util/AbstractTreeClassChooserDialog.java @@ -65,6 +65,7 @@ import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; import java.awt.event.MouseEvent; import java.util.ArrayList; +import java.util.LinkedHashSet; import java.util.List; import java.util.Set; @@ -288,7 +289,7 @@ public abstract class AbstractTreeClassChooserDialog } private Set doFilter(Set elements) { - Set result = new HashSet(); + Set result = new LinkedHashSet(); for (Object o : elements) { if (myElementClass.isInstance(o) && getFilter().isAccepted((T)o)) { result.add(o); diff --git a/platform/lang-impl/src/com/intellij/openapi/options/colors/pages/ANSIColoredConsoleColorsPage.java b/platform/lang-impl/src/com/intellij/openapi/options/colors/pages/ANSIColoredConsoleColorsPage.java index 5993ef66f2bd..0606ffd44da9 100644 --- a/platform/lang-impl/src/com/intellij/openapi/options/colors/pages/ANSIColoredConsoleColorsPage.java +++ b/platform/lang-impl/src/com/intellij/openapi/options/colors/pages/ANSIColoredConsoleColorsPage.java @@ -70,8 +70,8 @@ public class ANSIColoredConsoleColorsPage implements ColorSettingsPage, DisplayP ADDITIONAL_HIGHLIGHT_DESCRIPTORS.put("stdout", ConsoleViewContentType.NORMAL_OUTPUT_KEY); ADDITIONAL_HIGHLIGHT_DESCRIPTORS.put("stdin", ConsoleViewContentType.USER_INPUT_KEY); ADDITIONAL_HIGHLIGHT_DESCRIPTORS.put("stderr", ConsoleViewContentType.ERROR_OUTPUT_KEY); - ADDITIONAL_HIGHLIGHT_DESCRIPTORS.put("logError", ConsoleViewContentType.LOG_WARNING_OUTPUT_KEY); - ADDITIONAL_HIGHLIGHT_DESCRIPTORS.put("logWarning", ConsoleViewContentType.LOG_ERROR_OUTPUT_KEY); + ADDITIONAL_HIGHLIGHT_DESCRIPTORS.put("logError", ConsoleViewContentType.LOG_ERROR_OUTPUT_KEY); + ADDITIONAL_HIGHLIGHT_DESCRIPTORS.put("logWarning", ConsoleViewContentType.LOG_WARNING_OUTPUT_KEY); ADDITIONAL_HIGHLIGHT_DESCRIPTORS.put("logExpired", ConsoleViewContentType.LOG_EXPIRED_ENTRY); ADDITIONAL_HIGHLIGHT_DESCRIPTORS.put("red", ConsoleHighlighter.RED); diff --git a/platform/lang-impl/src/com/intellij/psi/formatter/common/InjectedLanguageBlockBuilder.java b/platform/lang-impl/src/com/intellij/psi/formatter/common/InjectedLanguageBlockBuilder.java index 7070493c72a1..a1dee26b1e67 100644 --- a/platform/lang-impl/src/com/intellij/psi/formatter/common/InjectedLanguageBlockBuilder.java +++ b/platform/lang-impl/src/com/intellij/psi/formatter/common/InjectedLanguageBlockBuilder.java @@ -56,24 +56,49 @@ public abstract class InjectedLanguageBlockBuilder { final Ref injectedRangeInsideHost = new Ref(); final Ref prefixLength = new Ref(); final Ref suffixLength = new Ref(); + final Ref injectionHostToUse = new Ref(injectionHost); final PsiLanguageInjectionHost.InjectedPsiVisitor injectedPsiVisitor = new PsiLanguageInjectionHost.InjectedPsiVisitor() { @Override public void visit(@NotNull final PsiFile injectedPsi, @NotNull final List places) { - if (places.size() == 1) { - final PsiLanguageInjectionHost.Shred shred = places.get(0); - final TextRange textRange = shred.getRangeInsideHost(); - String childText; - + if (places.size() != 1) { + return; + } + final PsiLanguageInjectionHost.Shred shred = places.get(0); + TextRange textRange = shred.getRangeInsideHost(); + PsiLanguageInjectionHost shredHost = shred.getHost(); + if (shredHost == null) { + return; + } + ASTNode node = shredHost.getNode(); + if (node == null) { + return; + } + if (node != injectionHost) { + int shift = 0; + boolean canProcess = false; + for (ASTNode n = injectionHost.getTreeParent(), prev = injectionHost; n != null; prev = n, n = n.getTreeParent()) { + shift += n.getStartOffset() - prev.getStartOffset(); + if (n == node) { + textRange = textRange.shiftRight(shift); + canProcess = true; + break; + } + } + if (!canProcess) { + return; + } + } + + String childText; if ((injectionHost.getTextLength() == textRange.getEndOffset() && textRange.getStartOffset() == 0) || (canProcessFragment((childText = injectionHost.getText()).substring(0, textRange.getStartOffset()), injectionHost) && canProcessFragment(childText.substring(textRange.getEndOffset()), injectionHost))) { injectedFile[0] = injectedPsi; injectedRangeInsideHost.set(textRange); - prefixLength.set(shred.getPrefix() != null ? shred.getPrefix().length() : 0); - suffixLength.set(shred.getSuffix() != null ? shred.getSuffix().length() : 0); + prefixLength.set(shred.getPrefix().length()); + suffixLength.set(shred.getSuffix().length()); } - } } }; InjectedLanguageUtil.enumerate(injectionHost.getPsi(), injectedPsiVisitor); @@ -85,19 +110,19 @@ public abstract class InjectedLanguageBlockBuilder { if (builder != null) { final int startOffset = injectedRangeInsideHost.get().getStartOffset(); final int endOffset = injectedRangeInsideHost.get().getEndOffset(); - TextRange range = injectionHost.getTextRange(); + TextRange range = injectionHostToUse.get().getTextRange(); int childOffset = range.getStartOffset(); if (startOffset != 0) { - final ASTNode leaf = injectionHost.findLeafElementAt(startOffset - 1); + final ASTNode leaf = injectionHostToUse.get().findLeafElementAt(startOffset - 1); result.add(createBlockBeforeInjection(leaf, wrap, alignment, indent, new TextRange(childOffset, childOffset + startOffset))); } addInjectedLanguageBlockWrapper(result, injectedFile[0].getNode(), indent, childOffset + startOffset, new TextRange(prefixLength.get(), injectedFile[0].getTextLength() - suffixLength.get())); - if (endOffset != injectionHost.getTextLength()) { - final ASTNode leaf = injectionHost.findLeafElementAt(endOffset); + if (endOffset != injectionHostToUse.get().getTextLength()) { + final ASTNode leaf = injectionHostToUse.get().findLeafElementAt(endOffset); result.add(createBlockAfterInjection(leaf, wrap, alignment, indent, new TextRange(childOffset + endOffset, range.getEndOffset()))); } return true; diff --git a/platform/platform-impl/src/com/intellij/internal/ToggleLaggingModeAction.java b/platform/platform-impl/src/com/intellij/internal/ToggleLaggingModeAction.java new file mode 100644 index 000000000000..f2c1bedf295f --- /dev/null +++ b/platform/platform-impl/src/com/intellij/internal/ToggleLaggingModeAction.java @@ -0,0 +1,72 @@ +/* + * Copyright 2000-2012 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.internal; + +import com.intellij.ide.caches.CacheUpdater; +import com.intellij.ide.caches.FileContent; +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.PlatformDataKeys; +import com.intellij.openapi.actionSystem.Presentation; +import com.intellij.openapi.progress.ProgressIndicator; +import com.intellij.openapi.project.DumbAware; +import com.intellij.openapi.project.DumbServiceImpl; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.impl.DebugUtil; +import com.intellij.util.Alarm; +import com.intellij.util.TimeoutUtil; + +import java.util.Arrays; + +/** + * @author peter + */ +public class ToggleLaggingModeAction extends AnAction implements DumbAware { + private volatile boolean myLagging = false; + private final Alarm myAlarm = new Alarm(Alarm.ThreadToUse.SWING_THREAD); + + public void actionPerformed(final AnActionEvent e) { + if (myLagging) { + myLagging = false; + myAlarm.cancelAllRequests(); + } + else { + myLagging = true; + for (int i = 0; i < 100; i++) { + new Runnable() { + @Override + public void run() { + myAlarm.addRequest(this, 1); + } + }.run(); + } + } + } + + @Override + public void update(final AnActionEvent e) { + final Presentation presentation = e.getPresentation(); + final Project project = PlatformDataKeys.PROJECT.getData(e.getDataContext()); + presentation.setEnabled(project != null && myLagging == DumbServiceImpl.getInstance(project).isDumb()); + if (myLagging) { + presentation.setText("Exit dumb mode"); + } + else { + presentation.setText("Enter dumb mode"); + } + } +} diff --git a/platform/platform-impl/src/com/intellij/notification/impl/NotificationsManagerImpl.java b/platform/platform-impl/src/com/intellij/notification/impl/NotificationsManagerImpl.java index 33ee10cc5cbc..01d057056854 100644 --- a/platform/platform-impl/src/com/intellij/notification/impl/NotificationsManagerImpl.java +++ b/platform/platform-impl/src/com/intellij/notification/impl/NotificationsManagerImpl.java @@ -252,7 +252,7 @@ public class NotificationsManagerImpl extends NotificationsManager { text.setCaretPosition(0); JScrollPane pane = ScrollPaneFactory.createScrollPane(text, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, - ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER); + ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED); pane.setBorder(null); pane.setOpaque(false); pane.getViewport().setOpaque(false); @@ -268,8 +268,10 @@ public class NotificationsManagerImpl extends NotificationsManager { text.setSize(preferredSize); preferredSize = text.getPreferredSize(); int maxHeight = Math.min(400, window.getComponent().getHeight() - 20); - if (preferredSize.height > maxHeight) { - pane.setPreferredSize(new Dimension(preferredSize.width, maxHeight)); + int maxWidth = Math.min(500, window.getComponent().getWidth() - 20); + Dimension maxSize = new Dimension(Math.min(preferredSize.width, maxWidth), Math.min(preferredSize.height, maxHeight)); + if (!maxSize.equals(preferredSize)) { + pane.setPreferredSize(maxSize); } final BalloonBuilder builder = JBPopupFactory.getInstance().createBalloonBuilder(content); diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java index f0b9fba78eef..fbed924fac7d 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java @@ -715,6 +715,7 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi myMousePressedEvent = null; myMouseMovedEvent = null; Disposer.dispose(myCaretModel); + Disposer.dispose(mySoftWrapModel); clearCaretThread(); myFocusListeners.clear(); diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/SoftWrapModelImpl.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/SoftWrapModelImpl.java index 2dcdb0caf56e..8f8627072794 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/SoftWrapModelImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/SoftWrapModelImpl.java @@ -16,6 +16,7 @@ package com.intellij.openapi.editor.impl; import com.intellij.diagnostic.Dumpable; +import com.intellij.openapi.Disposable; import com.intellij.openapi.application.Application; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.diagnostic.Logger; @@ -52,7 +53,9 @@ import java.util.List; * @author Denis Zhdanov * @since Jun 8, 2010 12:47:32 PM */ -public class SoftWrapModelImpl implements SoftWrapModelEx, PrioritizedDocumentListener, FoldingListener, PropertyChangeListener, Dumpable { +public class SoftWrapModelImpl implements SoftWrapModelEx, PrioritizedDocumentListener, DocumentBulkUpdateListener, FoldingListener, + PropertyChangeListener, Dumpable, Disposable +{ /** * Holds name of JVM property which presence should trigger debug-aware soft wraps processing. @@ -109,6 +112,8 @@ public class SoftWrapModelImpl implements SoftWrapModelEx, PrioritizedDocumentLi * Current field serves as a flag that indicates if all preliminary actions necessary for successful soft wraps processing is done. */ private boolean myUpdateInProgress; + + private boolean myBulkUpdateInProgress; /** * There is a possible case that target document is changed while its editor is inactive (e.g. user opens two editors for classes @@ -169,6 +174,8 @@ public class SoftWrapModelImpl implements SoftWrapModelEx, PrioritizedDocumentLi myUseSoftWraps = settings.isUseSoftWraps(); editor.addPropertyChangeListener(this); + + ApplicationManager.getApplication().getMessageBus().connect(this).subscribe(DocumentBulkUpdateListener.TOPIC, this); } /** @@ -370,7 +377,7 @@ public class SoftWrapModelImpl implements SoftWrapModelEx, PrioritizedDocumentLi @NotNull @Override public LogicalPosition visualToLogicalPosition(@NotNull VisualPosition visual) { - if (myUpdateInProgress || !prepareToMapping()) { + if (myBulkUpdateInProgress || myUpdateInProgress || !prepareToMapping()) { return myEditor.visualToLogicalPosition(visual, false); } myActive++; @@ -386,7 +393,7 @@ public class SoftWrapModelImpl implements SoftWrapModelEx, PrioritizedDocumentLi @NotNull @Override public LogicalPosition offsetToLogicalPosition(int offset) { - if (myUpdateInProgress || !prepareToMapping()) { + if (myBulkUpdateInProgress || myUpdateInProgress || !prepareToMapping()) { return myEditor.offsetToLogicalPosition(offset, false); } myActive++; @@ -401,7 +408,7 @@ public class SoftWrapModelImpl implements SoftWrapModelEx, PrioritizedDocumentLi @NotNull public LogicalPosition adjustLogicalPosition(LogicalPosition defaultLogical, int offset) { - if (myUpdateInProgress || !prepareToMapping()) { + if (myBulkUpdateInProgress || myUpdateInProgress || !prepareToMapping()) { return defaultLogical; } @@ -418,7 +425,7 @@ public class SoftWrapModelImpl implements SoftWrapModelEx, PrioritizedDocumentLi @Override @NotNull public VisualPosition adjustVisualPosition(@NotNull LogicalPosition logical, @NotNull VisualPosition defaultVisual) { - if (myUpdateInProgress || !prepareToMapping()) { + if (myBulkUpdateInProgress || myUpdateInProgress || !prepareToMapping()) { return defaultVisual; } @@ -566,6 +573,9 @@ public class SoftWrapModelImpl implements SoftWrapModelEx, PrioritizedDocumentLi @Override public void beforeDocumentChange(DocumentEvent event) { + if (myBulkUpdateInProgress) { + return; + } myUpdateInProgress = true; if (!isSoftWrappingEnabled()) { myDirty = true; @@ -578,6 +588,9 @@ public class SoftWrapModelImpl implements SoftWrapModelEx, PrioritizedDocumentLi @Override public void documentChanged(DocumentEvent event) { + if (myBulkUpdateInProgress) { + return; + } myUpdateInProgress = false; if (!isSoftWrappingEnabled()) { return; @@ -587,6 +600,20 @@ public class SoftWrapModelImpl implements SoftWrapModelEx, PrioritizedDocumentLi } } + @Override + public void updateStarted(@NotNull Document doc) { + myBulkUpdateInProgress = true; + } + + @Override + public void updateFinished(@NotNull Document doc) { + myBulkUpdateInProgress = false; + if (!isSoftWrappingEnabled()) { + return; + } + recalculate(); + } + @Override public void onFoldRegionStateChange(@NotNull FoldRegion region) { myUpdateInProgress = true; @@ -619,6 +646,11 @@ public class SoftWrapModelImpl implements SoftWrapModelEx, PrioritizedDocumentLi return myDataMapper; } + @Override + public void dispose() { + release(); + } + @Override public void release() { myDataMapper.release(); @@ -632,6 +664,7 @@ public class SoftWrapModelImpl implements SoftWrapModelEx, PrioritizedDocumentLi myApplianceManager.reset(); myDeferredFoldRegions.clear(); myEditor.getScrollingModel().scrollToCaret(ScrollType.CENTER); + myApplianceManager.recalculateIfNecessary(); } public SoftWrapApplianceManager getApplianceManager() { diff --git a/platform/platform-impl/src/com/intellij/ui/HideableDecorator.java b/platform/platform-impl/src/com/intellij/ui/HideableDecorator.java new file mode 100644 index 000000000000..6e3ef43c25bf --- /dev/null +++ b/platform/platform-impl/src/com/intellij/ui/HideableDecorator.java @@ -0,0 +1,180 @@ +/* + * Copyright 2000-2012 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.ui; + +import com.intellij.icons.AllIcons; +import com.intellij.openapi.util.IconLoader; +import com.intellij.util.ui.UIUtil; +import org.jetbrains.annotations.Nullable; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.InputEvent; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; + +/** + * @author evgeny zakrevsky + */ +public class HideableDecorator { + + private final JPanel myPanel; + + private final TitledSeparator myTitledSeparator; + private final boolean myAdjustWindow; + + private boolean myOn; + private JComponent myContent; + private Dimension myPreviousContentSize; + + public HideableDecorator(JPanel panel, String title, boolean adjustWindow) { + myPanel = panel; + myAdjustWindow = adjustWindow; + myTitledSeparator = new TitledSeparator(title, null) { + @Override + public void addNotify() { + super.addNotify(); + registerMnemonic(); + } + }; + myPanel.add(myTitledSeparator, BorderLayout.NORTH); + myTitledSeparator.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); + myTitledSeparator.addMouseListener(new MouseAdapter() { + @Override + public void mouseReleased(MouseEvent e) { + if (myOn) { + off(); + } + else { + on(); + } + } + }); + } + + public void setContentComponent(@Nullable JComponent content) { + if (content == null && myContent != null) { + myPanel.remove(myContent); + } + myContent = content; + if (myContent != null) { + myContent.setVisible(myOn); + myPanel.add(myContent, BorderLayout.CENTER); + } + } + + public void setOn(boolean on) { + myOn = on; + if (myOn) { + on(); + } + else { + off(); + } + } + + public boolean isExpanded() { + return myOn; + } + + public void setTitle(String title) { + myTitledSeparator.setText(title); + } + + public String getTitle() { + return myTitledSeparator.getText(); + } + + protected void on() { + myOn = true; + myTitledSeparator.getLabel().setIcon(AllIcons.General.ComboArrowDown); + myTitledSeparator.getLabel().setDisabledIcon(IconLoader.getTransparentIcon(AllIcons.General.ComboArrowDown, 0.5f)); + myTitledSeparator.getLabel().setIconTextGap(5); + if (myContent != null) { + myContent.setVisible(true); + } + adjustWindow(); + myPanel.invalidate(); + myPanel.repaint(); + } + + protected void off() { + myOn = false; + myTitledSeparator.getLabel().setIcon(AllIcons.General.ComboArrowRight); + myTitledSeparator.getLabel().setDisabledIcon(IconLoader.getTransparentIcon(AllIcons.General.ComboArrowRight, 0.5f)); + myTitledSeparator.getLabel() + .setIconTextGap(5 + AllIcons.General.ComboArrowDown.getIconWidth() - AllIcons.General.ComboArrowRight.getIconWidth()); + if (myContent != null) { + myContent.setVisible(false); + myPreviousContentSize = myContent.getSize(); + } + adjustWindow(); + myPanel.invalidate(); + myPanel.repaint(); + } + + private void adjustWindow() { + if (!myAdjustWindow) return; + final Window window = SwingUtilities.getWindowAncestor(myPanel); + if (window == null) return; + final Dimension size = window.getSize(); + final Dimension contentSize = myPreviousContentSize != null && myPreviousContentSize.width > 0 && myPreviousContentSize.height > 0 + ? myPreviousContentSize + : myContent.getPreferredSize(); + final Dimension newSize; + if (myOn) { + newSize = new Dimension(Math.max(size.width, myContent.getSize().width), size.height + contentSize.height); + } + else { + newSize = new Dimension(size.width, size.height - contentSize.height); + } + if (!newSize.equals(size)) { + SwingUtilities.invokeLater(new Runnable() { + public void run() { + if (window.isShowing()) { + window.setSize(newSize); + } + } + }); + } + } + + public void setEnabled(boolean enabled) { + myTitledSeparator.setEnabled(enabled); + myContent.setEnabled(enabled); + } + + private void registerMnemonic() { + final int mnemonicIndex = UIUtil.getDisplayMnemonicIndex(getTitle()); + if (mnemonicIndex != -1) { + myPanel.getActionMap().put("Collapse/Expand on mnemonic", new AbstractAction() { + @Override + public void actionPerformed(ActionEvent e) { + if (myOn) { + off(); + } + else { + on(); + } + } + }); + final Character mnemonicCharacter = UIUtil.removeMnemonic(getTitle()).toUpperCase().charAt(mnemonicIndex); + myPanel.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW) + .put(KeyStroke.getKeyStroke(mnemonicCharacter, InputEvent.ALT_MASK, false), "Collapse/Expand on mnemonic"); + } + } +} diff --git a/platform/platform-impl/src/com/intellij/ui/HideableTitledPanel.java b/platform/platform-impl/src/com/intellij/ui/HideableTitledPanel.java index 36fa137a0a2e..f9787489333a 100644 --- a/platform/platform-impl/src/com/intellij/ui/HideableTitledPanel.java +++ b/platform/platform-impl/src/com/intellij/ui/HideableTitledPanel.java @@ -1,28 +1,16 @@ package com.intellij.ui; -import com.intellij.icons.AllIcons; -import com.intellij.openapi.util.IconLoader; -import com.intellij.util.ui.UIUtil; import org.jetbrains.annotations.Nullable; import javax.swing.*; import java.awt.*; -import java.awt.event.ActionEvent; -import java.awt.event.InputEvent; -import java.awt.event.MouseAdapter; -import java.awt.event.MouseEvent; /** * @author evgeny zakrevsky */ public class HideableTitledPanel extends JPanel { - private final TitledSeparator myTitledSeparator; - private final boolean myAdjustWindow; - - private boolean myOn; - private JComponent myContent; - private Dimension myPreviousContentSize; + private final HideableDecorator myDecorator; public HideableTitledPanel(String title) { this(title, true); @@ -30,21 +18,7 @@ public class HideableTitledPanel extends JPanel { public HideableTitledPanel(String title, boolean adjustWindow) { super(new BorderLayout()); - myAdjustWindow = adjustWindow; - myTitledSeparator = new TitledSeparator(title, null); - add(myTitledSeparator, BorderLayout.NORTH); - myTitledSeparator.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); - myTitledSeparator.addMouseListener(new MouseAdapter() { - @Override - public void mouseReleased(MouseEvent e) { - if (myOn) { - off(); - } - else { - on(); - } - } - }); + myDecorator = new HideableDecorator(this, title, adjustWindow); } public HideableTitledPanel(String title, JComponent content, boolean on) { @@ -54,117 +28,27 @@ public class HideableTitledPanel extends JPanel { } public void setContentComponent(@Nullable JComponent content) { - if (content == null && myContent != null) { - remove(myContent); - } - myContent = content; - if (myContent != null) { - myContent.setVisible(myOn); - add(myContent, BorderLayout.CENTER); - } + myDecorator.setContentComponent(content); } public void setOn(boolean on) { - myOn = on; - if (myOn) { - on(); - } - else { - off(); - } + myDecorator.setOn(on); } public boolean isExpanded() { - return myOn; + return myDecorator.isExpanded(); } public void setTitle(String title) { - myTitledSeparator.setText(title); + myDecorator.setTitle(title); } public String getTitle() { - return myTitledSeparator.getText(); - } - - protected void on() { - myOn = true; - myTitledSeparator.getLabel().setIcon(AllIcons.General.ComboArrowDown); - myTitledSeparator.getLabel().setDisabledIcon(IconLoader.getTransparentIcon(AllIcons.General.ComboArrowDown, 0.5f)); - myTitledSeparator.getLabel().setIconTextGap(5); - if (myContent != null) { - myContent.setVisible(true); - } - adjustWindow(); - invalidate(); - repaint(); - } - - protected void off() { - myOn = false; - myTitledSeparator.getLabel().setIcon(AllIcons.General.ComboArrowRight); - myTitledSeparator.getLabel().setDisabledIcon(IconLoader.getTransparentIcon(AllIcons.General.ComboArrowRight, 0.5f)); - myTitledSeparator.getLabel() - .setIconTextGap(5 + AllIcons.General.ComboArrowDown.getIconWidth() - AllIcons.General.ComboArrowRight.getIconWidth()); - if (myContent != null) { - myContent.setVisible(false); - myPreviousContentSize = myContent.getSize(); - } - adjustWindow(); - invalidate(); - repaint(); - } - - private void adjustWindow() { - if (!myAdjustWindow) return; - final Window window = SwingUtilities.getWindowAncestor(this); - if (window == null) return; - final Dimension size = window.getSize(); - final Dimension contentSize = myPreviousContentSize != null && myPreviousContentSize.width > 0 && myPreviousContentSize.height > 0 - ? myPreviousContentSize - : myContent.getPreferredSize(); - final Dimension newSize; - if (myOn) { - newSize = new Dimension(Math.max(size.width, myContent.getSize().width), size.height + contentSize.height); - } - else { - newSize = new Dimension(size.width, size.height - contentSize.height); - } - if (!newSize.equals(size)) { - SwingUtilities.invokeLater(new Runnable() { - public void run() { - if (window.isShowing()) { - window.setSize(newSize); - } - } - }); - } + return myDecorator.getTitle(); } @Override public void setEnabled(boolean enabled) { - myTitledSeparator.setEnabled(enabled); - myContent.setEnabled(enabled); - } - - @Override - public void addNotify() { - super.addNotify(); - final int mnemonicIndex = UIUtil.getDisplayMnemonicIndex(getTitle()); - if (mnemonicIndex != -1) { - getActionMap().put("Collapse/Expand on mnemonic", new AbstractAction() { - @Override - public void actionPerformed(ActionEvent e) { - if (myOn) { - off(); - } - else { - on(); - } - } - }); - final Character mnemonicCharacter = UIUtil.removeMnemonic(getTitle()).toUpperCase().charAt(mnemonicIndex); - getInputMap(WHEN_IN_FOCUSED_WINDOW) - .put(KeyStroke.getKeyStroke(mnemonicCharacter, InputEvent.ALT_MASK, false), "Collapse/Expand on mnemonic"); - } + myDecorator.setEnabled(enabled); } } diff --git a/platform/platform-resources/src/META-INF/LangExtensions.xml b/platform/platform-resources/src/META-INF/LangExtensions.xml index fbba86501d4e..9c0e12d04f60 100644 --- a/platform/platform-resources/src/META-INF/LangExtensions.xml +++ b/platform/platform-resources/src/META-INF/LangExtensions.xml @@ -185,7 +185,6 @@ - diff --git a/platform/platform-resources/src/idea/LangActions.xml b/platform/platform-resources/src/idea/LangActions.xml index 0200a15fa9a7..ba9fbcbc20a0 100644 --- a/platform/platform-resources/src/idea/LangActions.xml +++ b/platform/platform-resources/src/idea/LangActions.xml @@ -87,6 +87,7 @@ + diff --git a/platform/platform-resources/src/idea/PlatformActions.xml b/platform/platform-resources/src/idea/PlatformActions.xml index 995dd9afa8e4..705b8f7f9599 100644 --- a/platform/platform-resources/src/idea/PlatformActions.xml +++ b/platform/platform-resources/src/idea/PlatformActions.xml @@ -537,6 +537,7 @@ + diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/committed/CommittedChangeListRenderer.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/committed/CommittedChangeListRenderer.java index a513d13095b0..dadfcc485e3f 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/committed/CommittedChangeListRenderer.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/committed/CommittedChangeListRenderer.java @@ -57,13 +57,7 @@ public class CommittedChangeListRenderer extends ColoredTreeCellRenderer { } public static Pair getDescriptionOfChangeList(final String text) { - String description = text; - int pos = description.indexOf("\n"); - if (pos >= 0) { - description = description.substring(0, pos).trim(); - return new Pair(description, Boolean.TRUE); - } - return new Pair(description, Boolean.FALSE); + return new Pair(text.replaceAll("\n", " // "), text.contains("\n")); } public static String truncateDescription(final String initDescription, final FontMetrics fontMetrics, int maxWidth) { diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/ui/VcsBalloonProblemNotifier.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/ui/VcsBalloonProblemNotifier.java index e9d5c2e90bd7..00c7b67f916d 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/ui/VcsBalloonProblemNotifier.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/ui/VcsBalloonProblemNotifier.java @@ -22,12 +22,15 @@ import com.intellij.notification.NotificationType; import com.intellij.openapi.application.Application; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.project.Project; +import com.intellij.openapi.project.ProjectManager; import com.intellij.openapi.ui.MessageType; import com.intellij.openapi.ui.popup.Balloon; import com.intellij.openapi.ui.popup.BalloonBuilder; import com.intellij.openapi.ui.popup.JBPopupFactory; import com.intellij.openapi.util.NamedRunnable; import com.intellij.openapi.vcs.changes.ui.ChangesViewContentManager; +import com.intellij.openapi.wm.IdeFocusManager; +import com.intellij.openapi.wm.IdeFrame; import com.intellij.ui.awt.RelativePoint; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -35,7 +38,6 @@ import org.jetbrains.annotations.Nullable; import javax.swing.*; import javax.swing.event.HyperlinkEvent; import java.awt.*; -import java.util.concurrent.TimeUnit; /** * Shows a notification balloon over one of version control related tool windows: Changes View or Version Control View. @@ -127,7 +129,35 @@ public class VcsBalloonProblemNotifier implements Runnable { notification.notify(myProject.isDefault() ? null : myProject); } - public static void showBalloonForComponent(@NotNull JComponent component, @NotNull final String message, final MessageType type, + public static void showBalloonForActiveComponent(@NotNull final String message, final MessageType type) { + Window[] windows = Window.getWindows(); + Window targetWindow = null; + for (Window each : windows) { + if (each.isActive()) { + targetWindow = each; + break; + } + } + + if (targetWindow == null) { + targetWindow = JOptionPane.getRootFrame(); + } + + if (targetWindow == null) { + final IdeFrame frame = IdeFocusManager.findInstance().getLastFocusedFrame(); + if (frame == null) { + final Project[] projects = ProjectManager.getInstance().getOpenProjects(); + showOverChangesView(projects == null || projects.length == 0 ? ProjectManager.getInstance().getDefaultProject() : projects[0], + message, type); + return; + } + showBalloonForComponent(frame.getComponent(), message, type, true); + } else { + showBalloonForComponent(targetWindow, message, type, true); + } + } + + public static void showBalloonForComponent(@NotNull Component component, @NotNull final String message, final MessageType type, final boolean atTop) { BalloonBuilder balloonBuilder = JBPopupFactory.getInstance().createHtmlTextBalloonBuilder(message, type, null); Balloon balloon = balloonBuilder.createBalloon(); diff --git a/plugins/git4idea/src/git4idea/GitStandardRemoteBranch.java b/plugins/git4idea/src/git4idea/GitStandardRemoteBranch.java index 07c7496b9b03..15dbcbd6385b 100644 --- a/plugins/git4idea/src/git4idea/GitStandardRemoteBranch.java +++ b/plugins/git4idea/src/git4idea/GitStandardRemoteBranch.java @@ -15,6 +15,7 @@ */ package git4idea; +import git4idea.branch.GitBranchUtil; import git4idea.repo.GitRemote; import org.jetbrains.annotations.NotNull; @@ -27,9 +28,9 @@ public class GitStandardRemoteBranch extends GitRemoteBranch { @NotNull private final String myNameAtRemote; public GitStandardRemoteBranch(@NotNull GitRemote remote, @NotNull String nameAtRemote, @NotNull Hash hash) { - super(formStandardName(remote, nameAtRemote), hash); + super(formStandardName(remote, GitBranchUtil.stripRefsPrefix(nameAtRemote)), hash); myRemote = remote; - myNameAtRemote = nameAtRemote; + myNameAtRemote = GitBranchUtil.stripRefsPrefix(nameAtRemote); } @NotNull diff --git a/plugins/git4idea/src/git4idea/branch/GitBranchUtil.java b/plugins/git4idea/src/git4idea/branch/GitBranchUtil.java index fc3b6ae018ad..e955afd18a0f 100644 --- a/plugins/git4idea/src/git4idea/branch/GitBranchUtil.java +++ b/plugins/git4idea/src/git4idea/branch/GitBranchUtil.java @@ -94,7 +94,7 @@ public class GitBranchUtil { */ @Deprecated @Nullable - public static GitBranch getCurrentBranch(@NotNull Project project, @NotNull VirtualFile root) { + public static GitLocalBranch getCurrentBranch(@NotNull Project project, @NotNull VirtualFile root) { GitRepository repository = GitUtil.getRepositoryManager(project).getRepositoryForRoot(root); if (repository != null) { return repository.getCurrentBranch(); @@ -137,7 +137,7 @@ public class GitBranchUtil { */ @Deprecated @Nullable - public static GitBranch tracked(@NotNull Project project, @NotNull VirtualFile root, @NotNull String branchName) throws VcsException { + public static GitRemoteBranch tracked(@NotNull Project project, @NotNull VirtualFile root, @NotNull String branchName) throws VcsException { final HashMap result = new HashMap(); GitConfigUtil.getValues(project, root, null, result); String remoteName = result.get(trackedRemoteKey(branchName)); diff --git a/plugins/github/src/org/jetbrains/plugins/github/GithubOpenInBrowserAction.java b/plugins/github/src/org/jetbrains/plugins/github/GithubOpenInBrowserAction.java index 88d6066ce7ff..57feddaafb3a 100644 --- a/plugins/github/src/org/jetbrains/plugins/github/GithubOpenInBrowserAction.java +++ b/plugins/github/src/org/jetbrains/plugins/github/GithubOpenInBrowserAction.java @@ -27,7 +27,8 @@ import com.intellij.openapi.vcs.VcsException; import com.intellij.openapi.vcs.changes.Change; import com.intellij.openapi.vcs.changes.ChangeListManager; import com.intellij.openapi.vfs.VirtualFile; -import git4idea.GitBranch; +import git4idea.GitLocalBranch; +import git4idea.GitRemoteBranch; import git4idea.GitUtil; import git4idea.branch.GitBranchUtil; import git4idea.repo.GitRepository; @@ -143,9 +144,9 @@ public class GithubOpenInBrowserAction extends DumbAwareAction { @Nullable public static String getBranchNameOnRemote(@NotNull Project project, @NotNull VirtualFile root) { - final GitBranch tracked; + final GitRemoteBranch tracked; try { - final GitBranch current = GitBranchUtil.getCurrentBranch(project, root); + final GitLocalBranch current = GitBranchUtil.getCurrentBranch(project, root); if (current == null) { Messages.showErrorDialog(project, "Cannot find local branch", CANNOT_OPEN_IN_BROWSER); return null; @@ -160,11 +161,7 @@ public class GithubOpenInBrowserAction extends DumbAwareAction { Messages.showErrorDialog(project, "Error occurred while inspecting branches: " + e1, CANNOT_OPEN_IN_BROWSER); return null; } - String branch = tracked.getName(); - if (branch.startsWith("origin/")) { - branch = branch.substring(7); - } - return branch; + return tracked.getNameForRemoteOperations(); } } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/GroovyBlockGenerator.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/GroovyBlockGenerator.java index 5fc6fc946ec7..588fd7482fca 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/GroovyBlockGenerator.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/GroovyBlockGenerator.java @@ -110,16 +110,6 @@ public class GroovyBlockGenerator implements GroovyElementTypes { if (first.getElementType() == GroovyTokenTypes.mLCURLY) children.remove(0); } -/* if (!children.isEmpty()) { - ASTNode second = children.get(0); - if (second.getElementType() == GroovyElementTypes.PARAMETERS_LIST) children.remove(0); - } - - if (!children.isEmpty()) { - ASTNode second = children.get(0); - if (second.getElementType() == GroovyTokenTypes.mCLOSABLE_BLOCK_OP) children.remove(0); - }*/ - if (!children.isEmpty()) { ASTNode last = children.get(children.size() - 1); if (last.getElementType() == GroovyTokenTypes.mRCURLY) children.remove(children.size() - 1); @@ -132,14 +122,14 @@ public class GroovyBlockGenerator implements GroovyElementTypes { //For binary expressions PsiElement blockPsi = myNode.getPsi(); + IElementType elementType = myNode.getElementType(); if (blockPsi instanceof GrBinaryExpression && !(blockPsi.getParent() instanceof GrBinaryExpression)) { return generateForBinaryExpr(); } //For multiline strings - if ((myNode.getElementType() == mSTRING_LITERAL || myNode.getElementType() == mGSTRING_LITERAL) && - myBlock.getTextRange().equals(myNode.getTextRange())) { + if ((elementType == mSTRING_LITERAL || elementType == mGSTRING_LITERAL) && myBlock.getTextRange().equals(myNode.getTextRange())) { String text = myNode.getText(); if (text.length() > 6) { if (text.substring(0, 3).equals("'''") && text.substring(text.length() - 3).equals("'''") || @@ -149,19 +139,8 @@ public class GroovyBlockGenerator implements GroovyElementTypes { } } - if (myNode.getElementType() == mGSTRING_BEGIN && - myBlock.getTextRange().equals(myNode.getTextRange())) { - String text = myNode.getText(); - if (text.length() > 3) { - if (text.substring(0, 3).equals("\"\"\"")) { - return generateForMultiLineGStringBegin(); - } - } - - } - //for gstrings - if (myNode.getElementType() == GSTRING) { + if (elementType == GSTRING || elementType == REGEX || elementType == mREGEX_LITERAL || elementType == mDOLLAR_SLASH_REGEX_LITERAL) { final ArrayList subBlocks = new ArrayList(); ASTNode[] children = getGroovyChildren(myNode); for (ASTNode childNode : children) { @@ -174,7 +153,7 @@ public class GroovyBlockGenerator implements GroovyElementTypes { } // chained properties, calls, indexing, etc - if (NESTED.contains(myNode.getElementType()) && blockPsi.getParent() != null && !NESTED.contains(blockPsi.getParent().getNode().getElementType())) { + if (NESTED.contains(elementType) && blockPsi.getParent() != null && !NESTED.contains(blockPsi.getParent().getNode().getElementType())) { final List subBlocks = new ArrayList(); AlignmentProvider.Aligner dotsAligner = mySettings.ALIGN_MULTILINE_CHAINED_METHODS ? myAlignmentProvider.createAligner(true) : null; addNestedChildren(myNode.getPsi(), subBlocks, dotsAligner, true); @@ -490,26 +469,6 @@ public class GroovyBlockGenerator implements GroovyElementTypes { return subBlocks; } - private List generateForMultiLineGStringBegin() { - final ArrayList subBlocks = new ArrayList(); - final int start = myNode.getTextRange().getStartOffset(); - final int end = myNode.getTextRange().getEndOffset(); - - subBlocks.add(new GroovyBlock(myNode, Indent.getNoneIndent(), myWrap, mySettings, myGroovySettings, myAlignmentProvider) { - @NotNull - public TextRange getTextRange() { - return new TextRange(start, start + 3); - } - }); - subBlocks.add(new GroovyBlock(myNode, Indent.getAbsoluteNoneIndent(), myWrap, mySettings, myGroovySettings, myAlignmentProvider) { - @NotNull - public TextRange getTextRange() { - return new TextRange(start + 3, end); - } - }); - return subBlocks; - } - /** * @param node Tree node * @return true, if the current node can be myBlock node, else otherwise diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/formatter/FormatterTest.groovy b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/formatter/FormatterTest.groovy index 77dcd8f88370..51b36d1d74fc 100644 --- a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/formatter/FormatterTest.groovy +++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/formatter/FormatterTest.groovy @@ -81,6 +81,7 @@ public class FormatterTest extends GroovyFormatterTestCase { public void testPointer1() throws Throwable { doTest(); } public void testRange1() throws Throwable { doTest(); } public void testRegex1() throws Throwable { doTest(); } + public void testRegex2() { doTest() } public void testSh1() throws Throwable { doTest(); } public void testSh2() throws Throwable { doTest(); } public void testSqr1() throws Throwable { doTest(); } @@ -248,7 +249,6 @@ public class FormatterTest extends GroovyFormatterTestCase { void testAssertDescriptionIndent() { doTest() } - private void doGeeseTest() { GroovyCodeStyleSettings customSettings = myTempSettings.getCustomSettings(GroovyCodeStyleSettings.class); boolean oldvalue = customSettings.USE_FLYING_GEESE_BRACES; diff --git a/plugins/groovy/testdata/groovy/formatter/regex2.test b/plugins/groovy/testdata/groovy/formatter/regex2.test new file mode 100644 index 000000000000..40ddf46ecd31 --- /dev/null +++ b/plugins/groovy/testdata/groovy/formatter/regex2.test @@ -0,0 +1,11 @@ +print(/ /) +print(/ $x /) + +print($/ /$) +print($/ $x /$) +----- +print(/ /) +print(/ $x /) + +print($/ /$) +print($/ $x /$) \ No newline at end of file diff --git a/plugins/maven/maven3-server-impl/src/org/jetbrains/idea/maven/server/embedder/CustomMaven3Artifact.java b/plugins/maven/maven3-server-impl/src/org/jetbrains/idea/maven/server/embedder/CustomMaven3Artifact.java index 18e1a845b889..63693f295863 100644 --- a/plugins/maven/maven3-server-impl/src/org/jetbrains/idea/maven/server/embedder/CustomMaven3Artifact.java +++ b/plugins/maven/maven3-server-impl/src/org/jetbrains/idea/maven/server/embedder/CustomMaven3Artifact.java @@ -316,6 +316,7 @@ public class CustomMaven3Artifact implements Artifact { } public int compareTo(Artifact o) { + if (o instanceof CustomMaven3Artifact) o = ((CustomMaven3Artifact)o).myWrapee; return myWrapee.compareTo(o); } diff --git a/plugins/maven/maven3-server-impl/src/org/jetbrains/idea/maven/server/embedder/CustomMaven3ArtifactResolver.java b/plugins/maven/maven3-server-impl/src/org/jetbrains/idea/maven/server/embedder/CustomMaven3ArtifactResolver.java index 3b990a11f2d8..ed3b524bc67f 100644 --- a/plugins/maven/maven3-server-impl/src/org/jetbrains/idea/maven/server/embedder/CustomMaven3ArtifactResolver.java +++ b/plugins/maven/maven3-server-impl/src/org/jetbrains/idea/maven/server/embedder/CustomMaven3ArtifactResolver.java @@ -29,9 +29,11 @@ import org.jetbrains.idea.maven.server.MavenModelConverter; import org.jetbrains.idea.maven.server.UnresolvedArtifactsCollector; import org.sonatype.aether.RepositorySystem; import org.sonatype.aether.RepositorySystemSession; +import org.sonatype.aether.repository.LocalRepository; import org.sonatype.aether.repository.LocalRepositoryManager; import org.sonatype.aether.resolution.ArtifactRequest; import org.sonatype.aether.resolution.ArtifactResult; +import org.sonatype.aether.util.FilterRepositorySystemSession; import java.io.File; import java.util.*; @@ -108,9 +110,16 @@ public class CustomMaven3ArtifactResolver } } - private RepositorySystemSession getSession( ArtifactRepository localRepository ) - { - return LegacyLocalRepositoryManager.overlay( localRepository, legacySupport.getRepositorySession(), repoSystem ); + private RepositorySystemSession getSession(ArtifactRepository localRepository) { + RepositorySystemSession session = + LegacyLocalRepositoryManager.overlay(localRepository, legacySupport.getRepositorySession(), repoSystem); + + return new FilterRepositorySystemSession(session) { + @Override + public LocalRepository getLocalRepository() { + return getLocalRepositoryManager().getRepository(); // avoid NPE in DefaultMetadataResolver.resolve(RepositorySystemSession,Collection) : 318 + } + }; } private void injectSession1( RepositoryRequest request, MavenSession session ) diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnBundle.properties b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnBundle.properties index ba6e615f19ff..d75e4899d1d6 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnBundle.properties +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnBundle.properties @@ -262,6 +262,7 @@ progress.text2.processing.file=Processing file {0} progress.title.lock.files=Lock Files exception.text.locking.file.failed=Failed to lock file: {0} message.title.lock.failures=Lock Failures +message.text.files.lock.failed={0,choice, 0#Failed to lock file.|1#Failed to lock files.} message.text.files.locked={0,choice, 0#Failed to lock files.|1#1 file locked|2#{0,number} files locked} progress.text.unlocking.files=Unlocking files in repository... progress.title.unlock.files=Unlock Files diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnUtil.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnUtil.java index d574e6117faa..90d04f74f42d 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnUtil.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnUtil.java @@ -196,11 +196,16 @@ public class SvnUtil { if (!failedLocks.isEmpty()) { String[] failedFiles = ArrayUtil.toStringArray(failedLocks); List exceptions = new ArrayList(); - for (String file : failedFiles) { exceptions.add(new VcsException(SvnBundle.message("exception.text.locking.file.failed", file))); } + final StringBuilder sb = new StringBuilder(SvnBundle.message("message.text.files.lock.failed", failedFiles.length == 1 ? 0 : 1)); + for (VcsException vcsException : exceptions) { + if (sb.length() > 0) sb.append('\n'); + sb.append(vcsException.getMessage()); + } AbstractVcsHelper.getInstance(project).showErrors(exceptions, SvnBundle.message("message.title.lock.failures")); + throw new VcsException(sb.toString()); } StatusBarUtil.setStatusBarInfo(project, SvnBundle.message("message.text.files.locked", count[0])); diff --git a/xml/dom-impl/src/com/intellij/util/xml/stubs/DomStub.java b/xml/dom-impl/src/com/intellij/util/xml/stubs/DomStub.java index 3db8247eb27a..bd0bc2105d82 100644 --- a/xml/dom-impl/src/com/intellij/util/xml/stubs/DomStub.java +++ b/xml/dom-impl/src/com/intellij/util/xml/stubs/DomStub.java @@ -39,11 +39,10 @@ import java.util.List; public abstract class DomStub extends ObjectStubBase { protected final StringRef myLocalName; - @Nullable private final StringRef myNamespace; private DomInvocationHandler myHandler; - public DomStub(DomStub parent, @NotNull StringRef localName, @Nullable StringRef namespace) { + public DomStub(DomStub parent, @NotNull StringRef localName, StringRef namespace) { super(parent); myNamespace = namespace; if (parent != null) { @@ -69,11 +68,12 @@ public abstract class DomStub extends ObjectStubBase { } public List getChildrenByName(final CharSequence name, @Nullable final String nsKey) { + final String s = nsKey == null ? "" : nsKey; return ContainerUtil.filter(getChildrenStubs(), new Condition() { @Override public boolean value(DomStub stub) { return XmlUtil.getLocalName(stub.getName()).equals(name) && - Comparing.equal(nsKey, stub.getNamespaceKey()); + Comparing.equal(s, stub.getNamespaceKey()); } }); }