From 8ec15b9b746bb8c8c8c9191b74da3df808e0a668 Mon Sep 17 00:00:00 2001 From: Sergey Evdokimov Date: Thu, 8 Dec 2011 13:16:04 +0300 Subject: [PATCH 01/62] Group some action in Grails View. --- .../plugins/groovy/mvc/projectView/MvcProjectViewPane.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/mvc/projectView/MvcProjectViewPane.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/mvc/projectView/MvcProjectViewPane.java index cd9db60656bb..b8e88faf0ca2 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/mvc/projectView/MvcProjectViewPane.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/mvc/projectView/MvcProjectViewPane.java @@ -141,10 +141,10 @@ public class MvcProjectViewPane extends AbstractProjectViewPSIPane implements Id final TreeExpander expander = new DefaultTreeExpander(myTree); final CommonActionsManager actionsManager = CommonActionsManager.getInstance(); group.addAction(new ScrollFromSourceAction()); - group.addAction(myAutoScrollFromSourceHandler.createToggleAction()); - group.addAction(myAutoScrollToSourceHandler.createToggleAction()); + group.addAction(myAutoScrollFromSourceHandler.createToggleAction()).setAsSecondary(true); + group.addAction(myAutoScrollToSourceHandler.createToggleAction()).setAsSecondary(true); group.add(actionsManager.createCollapseAllAction(expander, myTree)); - group.addAction(new HideEmptyMiddlePackagesAction()); + group.addAction(new HideEmptyMiddlePackagesAction()).setAsSecondary(true); return ActionManager.getInstance().createActionToolbar(ActionPlaces.UNKNOWN, group, true).getComponent(); } From 809b2fdb08255977862f717a577bfd1cd7ec2ea4 Mon Sep 17 00:00:00 2001 From: Maxim Shafirov Date: Thu, 8 Dec 2011 13:22:02 +0400 Subject: [PATCH 02/62] Allow for lazy LightClass delegates --- .../psi/impl/light/AbstractLightClass.java | 360 ++++++++++++++++++ .../intellij/psi/impl/light/LightClass.java | 316 +-------------- .../psi/impl/light/LightTypeParameter.java | 2 +- 3 files changed, 365 insertions(+), 313 deletions(-) create mode 100644 java/java-psi-impl/src/com/intellij/psi/impl/light/AbstractLightClass.java diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/light/AbstractLightClass.java b/java/java-psi-impl/src/com/intellij/psi/impl/light/AbstractLightClass.java new file mode 100644 index 000000000000..c6b10b2623c4 --- /dev/null +++ b/java/java-psi-impl/src/com/intellij/psi/impl/light/AbstractLightClass.java @@ -0,0 +1,360 @@ +/* + * Copyright 2000-2011 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * @author max + */ +package com.intellij.psi.impl.light; + +import com.intellij.lang.Language; +import com.intellij.lang.java.JavaLanguage; +import com.intellij.openapi.util.Pair; +import com.intellij.psi.*; +import com.intellij.psi.impl.PsiClassImplUtil; +import com.intellij.psi.impl.PsiImplUtil; +import com.intellij.psi.javadoc.PsiDocComment; +import com.intellij.psi.scope.PsiScopeProcessor; +import com.intellij.util.IncorrectOperationException; +import org.jetbrains.annotations.NonNls; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.Collection; +import java.util.List; + +public abstract class AbstractLightClass extends LightElement implements PsiClass { + protected AbstractLightClass(PsiManager manager, Language language) { + super(manager, language); + } + + protected AbstractLightClass(PsiManager manager) { + super(manager, JavaLanguage.INSTANCE); + } + + public abstract PsiClass getDelegate(); + public abstract PsiElement copy(); + + @Override + @NonNls + @Nullable + public String getName() { + return getDelegate().getName(); + } + + @Override + @Nullable + public PsiModifierList getModifierList() { + return getDelegate().getModifierList(); + } + + @Override + public boolean hasModifierProperty(@Modifier @NonNls @NotNull String name) { + return getDelegate().hasModifierProperty(name); + } + + @Override + @Nullable + public PsiDocComment getDocComment() { + return null; + } + + @Override + public boolean isDeprecated() { + return getDelegate().isDeprecated(); + } + + @Override + public boolean hasTypeParameters() { + return PsiImplUtil.hasTypeParameters(this); + } + + @Override + @Nullable + public PsiTypeParameterList getTypeParameterList() { + return getDelegate().getTypeParameterList(); + } + + @Override + @NotNull + public PsiTypeParameter[] getTypeParameters() { + return getDelegate().getTypeParameters(); + } + + @Override + @NonNls + @Nullable + public String getQualifiedName() { + return getDelegate().getQualifiedName(); + } + + @Override + public boolean isInterface() { + return getDelegate().isInterface(); + } + + @Override + public boolean isAnnotationType() { + return getDelegate().isAnnotationType(); + } + + @Override + public boolean isEnum() { + return getDelegate().isEnum(); + } + + @Override + @Nullable + public PsiReferenceList getExtendsList() { + return getDelegate().getExtendsList(); + } + + @Override + @Nullable + public PsiReferenceList getImplementsList() { + return getDelegate().getImplementsList(); + } + + @Override + @NotNull + public PsiClassType[] getExtendsListTypes() { + return PsiClassImplUtil.getExtendsListTypes(this); + } + + @Override + @NotNull + public PsiClassType[] getImplementsListTypes() { + return PsiClassImplUtil.getImplementsListTypes(this); + } + + @Override + @Nullable + public PsiClass getSuperClass() { + return getDelegate().getSuperClass(); + } + + @Override + public PsiClass[] getInterfaces() { + return getDelegate().getInterfaces(); + } + + @NotNull + @Override + public PsiElement getNavigationElement() { + return getDelegate().getNavigationElement(); + } + + @Override + @NotNull + public PsiClass[] getSupers() { + return getDelegate().getSupers(); + } + + @Override + @NotNull + public PsiClassType[] getSuperTypes() { + return getDelegate().getSuperTypes(); + } + + @Override + @NotNull + public PsiField[] getFields() { + return getDelegate().getFields(); + } + + @Override + @NotNull + public PsiMethod[] getMethods() { + return getDelegate().getMethods(); + } + + @Override + @NotNull + public PsiMethod[] getConstructors() { + return getDelegate().getConstructors(); + } + + @Override + @NotNull + public PsiClass[] getInnerClasses() { + return getDelegate().getInnerClasses(); + } + + @Override + @NotNull + public PsiClassInitializer[] getInitializers() { + return getDelegate().getInitializers(); + } + + @Override + public boolean processDeclarations(@NotNull PsiScopeProcessor processor, + @NotNull ResolveState state, + PsiElement lastParent, + @NotNull PsiElement place) { + return PsiClassImplUtil.processDeclarationsInClass(this, processor, state, null, lastParent, place, false); + } + + @Override + @NotNull + public PsiField[] getAllFields() { + return getDelegate().getAllFields(); + } + + @Override + @NotNull + public PsiMethod[] getAllMethods() { + return getDelegate().getAllMethods(); + } + + @Override + @NotNull + public PsiClass[] getAllInnerClasses() { + return getDelegate().getAllInnerClasses(); + } + + @Override + @Nullable + public PsiField findFieldByName(@NonNls String name, boolean checkBases) { + return PsiClassImplUtil.findFieldByName(this, name, checkBases); + } + + @Override + @Nullable + public PsiMethod findMethodBySignature(PsiMethod patternMethod, boolean checkBases) { + return PsiClassImplUtil.findMethodBySignature(this, patternMethod, checkBases); + } + + @Override + @NotNull + public PsiMethod[] findMethodsBySignature(PsiMethod patternMethod, boolean checkBases) { + return PsiClassImplUtil.findMethodsBySignature(this, patternMethod, checkBases); + } + + @Override + @NotNull + public PsiMethod[] findMethodsByName(@NonNls String name, boolean checkBases) { + return PsiClassImplUtil.findMethodsByName(this, name, checkBases); + } + + @Override + @NotNull + public List> findMethodsAndTheirSubstitutorsByName(@NonNls String name, boolean checkBases) { + return PsiClassImplUtil.findMethodsAndTheirSubstitutorsByName(this, name, checkBases); + } + + @Override + @NotNull + public List> getAllMethodsAndTheirSubstitutors() { + return PsiClassImplUtil.getAllWithSubstitutorsByMap(this, PsiMethod.class); + } + + @Override + @Nullable + public PsiClass findInnerClassByName(@NonNls String name, boolean checkBases) { + return getDelegate().findInnerClassByName(name, checkBases); + } + + @Override + @Nullable + public PsiElement getLBrace() { + return getDelegate().getLBrace(); + } + + @Override + @Nullable + public PsiElement getRBrace() { + return getDelegate().getRBrace(); + } + + @Override + @Nullable + public PsiIdentifier getNameIdentifier() { + return getDelegate().getNameIdentifier(); + } + + @Override + public PsiElement getScope() { + return getDelegate().getScope(); + } + + @Override + public boolean isInheritor(@NotNull PsiClass baseClass, boolean checkDeep) { + return getDelegate().isInheritor(baseClass, checkDeep); + } + + @Override + public boolean isInheritorDeep(PsiClass baseClass, @Nullable PsiClass classToByPass) { + return getDelegate().isInheritorDeep(baseClass, classToByPass); + } + + @Override + @Nullable + public PsiClass getContainingClass() { + return getDelegate().getContainingClass(); + } + + @Override + @NotNull + public Collection getVisibleSignatures() { + return getDelegate().getVisibleSignatures(); + } + + @Override + public PsiElement setName(@NonNls @NotNull String name) throws IncorrectOperationException { + return getDelegate().setName(name); + } + + @Override + public String toString() { + return "PsiClass:" + getName(); + } + + @Override + public String getText() { + return getDelegate().getText(); + } + + @Override + public void accept(@NotNull PsiElementVisitor visitor) { + if (visitor instanceof JavaElementVisitor) { + ((JavaElementVisitor)visitor).visitClass(this); + } else { + visitor.visitElement(this); + } + } + + @Override + public PsiFile getContainingFile() { + return getDelegate().getContainingFile(); + } + + @Override + public PsiElement getContext() { + return getDelegate(); + } + + @Override + public boolean isValid() { + return getDelegate().isValid(); + } + + @Override + public boolean isEquivalentTo(PsiElement another) { + return this == another || + (another instanceof AbstractLightClass && getDelegate().isEquivalentTo(((AbstractLightClass)another).getDelegate())) || + getDelegate().isEquivalentTo(another); + } + +} diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/light/LightClass.java b/java/java-psi-impl/src/com/intellij/psi/impl/light/LightClass.java index 1c1707bc3e3e..91f6e7c822d4 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/light/LightClass.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/light/LightClass.java @@ -34,8 +34,8 @@ import java.util.List; /** * @author peter */ -public class LightClass extends LightElement implements PsiClass { - protected final PsiClass myDelegate; +public class LightClass extends AbstractLightClass { + private final PsiClass myDelegate; public LightClass(PsiClass delegate) { this(delegate, JavaLanguage.INSTANCE); @@ -47,291 +47,8 @@ public class LightClass extends LightElement implements PsiClass { } @Override - @NonNls - @Nullable - public String getName() { - return myDelegate.getName(); - } - - @Override - @Nullable - public PsiModifierList getModifierList() { - return myDelegate.getModifierList(); - } - - @Override - public boolean hasModifierProperty(@Modifier @NonNls @NotNull String name) { - return myDelegate.hasModifierProperty(name); - } - - @Override - @Nullable - public PsiDocComment getDocComment() { - return null; - } - - @Override - public boolean isDeprecated() { - return myDelegate.isDeprecated(); - } - - @Override - public boolean hasTypeParameters() { - return PsiImplUtil.hasTypeParameters(this); - } - - @Override - @Nullable - public PsiTypeParameterList getTypeParameterList() { - return myDelegate.getTypeParameterList(); - } - - @Override - @NotNull - public PsiTypeParameter[] getTypeParameters() { - return myDelegate.getTypeParameters(); - } - - @Override - @NonNls - @Nullable - public String getQualifiedName() { - return myDelegate.getQualifiedName(); - } - - @Override - public boolean isInterface() { - return myDelegate.isInterface(); - } - - @Override - public boolean isAnnotationType() { - return myDelegate.isAnnotationType(); - } - - @Override - public boolean isEnum() { - return myDelegate.isEnum(); - } - - @Override - @Nullable - public PsiReferenceList getExtendsList() { - return myDelegate.getExtendsList(); - } - - @Override - @Nullable - public PsiReferenceList getImplementsList() { - return myDelegate.getImplementsList(); - } - - @Override - @NotNull - public PsiClassType[] getExtendsListTypes() { - return PsiClassImplUtil.getExtendsListTypes(this); - } - - @Override - @NotNull - public PsiClassType[] getImplementsListTypes() { - return PsiClassImplUtil.getImplementsListTypes(this); - } - - @Override - @Nullable - public PsiClass getSuperClass() { - return myDelegate.getSuperClass(); - } - - @Override - public PsiClass[] getInterfaces() { - return myDelegate.getInterfaces(); - } - - @NotNull - @Override - public PsiElement getNavigationElement() { - return myDelegate.getNavigationElement(); - } - - @Override - @NotNull - public PsiClass[] getSupers() { - return myDelegate.getSupers(); - } - - @Override - @NotNull - public PsiClassType[] getSuperTypes() { - return myDelegate.getSuperTypes(); - } - - @Override - @NotNull - public PsiField[] getFields() { - return myDelegate.getFields(); - } - - @Override - @NotNull - public PsiMethod[] getMethods() { - return myDelegate.getMethods(); - } - - @Override - @NotNull - public PsiMethod[] getConstructors() { - return myDelegate.getConstructors(); - } - - @Override - @NotNull - public PsiClass[] getInnerClasses() { - return myDelegate.getInnerClasses(); - } - - @Override - @NotNull - public PsiClassInitializer[] getInitializers() { - return myDelegate.getInitializers(); - } - - @Override - public boolean processDeclarations(@NotNull PsiScopeProcessor processor, - @NotNull ResolveState state, - PsiElement lastParent, - @NotNull PsiElement place) { - return PsiClassImplUtil.processDeclarationsInClass(this, processor, state, null, lastParent, place, false); - } - - @Override - @NotNull - public PsiField[] getAllFields() { - return myDelegate.getAllFields(); - } - - @Override - @NotNull - public PsiMethod[] getAllMethods() { - return myDelegate.getAllMethods(); - } - - @Override - @NotNull - public PsiClass[] getAllInnerClasses() { - return myDelegate.getAllInnerClasses(); - } - - @Override - @Nullable - public PsiField findFieldByName(@NonNls String name, boolean checkBases) { - return PsiClassImplUtil.findFieldByName(this, name, checkBases); - } - - @Override - @Nullable - public PsiMethod findMethodBySignature(PsiMethod patternMethod, boolean checkBases) { - return PsiClassImplUtil.findMethodBySignature(this, patternMethod, checkBases); - } - - @Override - @NotNull - public PsiMethod[] findMethodsBySignature(PsiMethod patternMethod, boolean checkBases) { - return PsiClassImplUtil.findMethodsBySignature(this, patternMethod, checkBases); - } - - @Override - @NotNull - public PsiMethod[] findMethodsByName(@NonNls String name, boolean checkBases) { - return PsiClassImplUtil.findMethodsByName(this, name, checkBases); - } - - @Override - @NotNull - public List> findMethodsAndTheirSubstitutorsByName(@NonNls String name, boolean checkBases) { - return PsiClassImplUtil.findMethodsAndTheirSubstitutorsByName(this, name, checkBases); - } - - @Override - @NotNull - public List> getAllMethodsAndTheirSubstitutors() { - return PsiClassImplUtil.getAllWithSubstitutorsByMap(this, PsiMethod.class); - } - - @Override - @Nullable - public PsiClass findInnerClassByName(@NonNls String name, boolean checkBases) { - return myDelegate.findInnerClassByName(name, checkBases); - } - - @Override - @Nullable - public PsiElement getLBrace() { - return myDelegate.getLBrace(); - } - - @Override - @Nullable - public PsiElement getRBrace() { - return myDelegate.getRBrace(); - } - - @Override - @Nullable - public PsiIdentifier getNameIdentifier() { - return myDelegate.getNameIdentifier(); - } - - @Override - public PsiElement getScope() { - return myDelegate.getScope(); - } - - @Override - public boolean isInheritor(@NotNull PsiClass baseClass, boolean checkDeep) { - return myDelegate.isInheritor(baseClass, checkDeep); - } - - @Override - public boolean isInheritorDeep(PsiClass baseClass, @Nullable PsiClass classToByPass) { - return myDelegate.isInheritorDeep(baseClass, classToByPass); - } - - @Override - @Nullable - public PsiClass getContainingClass() { - return myDelegate.getContainingClass(); - } - - @Override - @NotNull - public Collection getVisibleSignatures() { - return myDelegate.getVisibleSignatures(); - } - - @Override - public PsiElement setName(@NonNls @NotNull String name) throws IncorrectOperationException { - return myDelegate.setName(name); - } - - @Override - public String toString() { - return "PsiClass:" + getName(); - } - - @Override - public String getText() { - return myDelegate.getText(); - } - - @Override - public void accept(@NotNull PsiElementVisitor visitor) { - if (visitor instanceof JavaElementVisitor) { - ((JavaElementVisitor)visitor).visitClass(this); - } else { - visitor.visitElement(this); - } + public PsiClass getDelegate() { + return myDelegate; } @Override @@ -339,29 +56,4 @@ public class LightClass extends LightElement implements PsiClass { return new LightClass(this); } - @Override - public PsiFile getContainingFile() { - return myDelegate.getContainingFile(); - } - - public PsiClass getDelegate() { - return myDelegate; - } - - @Override - public PsiElement getContext() { - return myDelegate; - } - - @Override - public boolean isValid() { - return myDelegate.isValid(); - } - - @Override - public boolean isEquivalentTo(PsiElement another) { - return this == another || - (another instanceof LightClass && getDelegate().isEquivalentTo(((LightClass)another).getDelegate())) || - getDelegate().isEquivalentTo(another); - } } diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/light/LightTypeParameter.java b/java/java-psi-impl/src/com/intellij/psi/impl/light/LightTypeParameter.java index 9eef9a6fb8d8..54e5d84da927 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/light/LightTypeParameter.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/light/LightTypeParameter.java @@ -26,7 +26,7 @@ public class LightTypeParameter extends LightClass implements PsiTypeParameter { @Override public PsiTypeParameter getDelegate() { - return (PsiTypeParameter)myDelegate; + return (PsiTypeParameter)super.getDelegate(); } @Override From c3cb49dba48caf9e184bf7bb4b536f82f3560e60 Mon Sep 17 00:00:00 2001 From: irengrig Date: Thu, 8 Dec 2011 14:55:52 +0400 Subject: [PATCH 03/62] VCS tests: write modification ts when changing files --- .../src/com/intellij/testFramework/AbstractVcsTestCase.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/platform/testFramework/src/com/intellij/testFramework/AbstractVcsTestCase.java b/platform/testFramework/src/com/intellij/testFramework/AbstractVcsTestCase.java index bb765b69ed25..c88b41fbe9fc 100644 --- a/platform/testFramework/src/com/intellij/testFramework/AbstractVcsTestCase.java +++ b/platform/testFramework/src/com/intellij/testFramework/AbstractVcsTestCase.java @@ -337,7 +337,11 @@ public abstract class AbstractVcsTestCase { @Override protected void run() throws Throwable { try { - file.setBinaryContent(newContent.getBytes()); + final long newModTs = Math.max(System.currentTimeMillis(), file.getModificationStamp() + 1); + final long newTs = Math.max(System.currentTimeMillis(), file.getTimeStamp() + 1); + file.setBinaryContent(newContent.getBytes(), newModTs, newTs); + final File file1 = new File(file.getPath()); + file1.setLastModified(newModTs); } catch(IOException ex) { throw new RuntimeException(ex); From 50b28aca39a19b309bb0a162ece479e5e87c70cc Mon Sep 17 00:00:00 2001 From: Eugene Zhuravlev Date: Thu, 8 Dec 2011 11:58:31 +0100 Subject: [PATCH 04/62] correctly remove null values from index --- .../util/indexing/ValueContainerImpl.java | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/util/indexing/ValueContainerImpl.java b/platform/lang-impl/src/com/intellij/util/indexing/ValueContainerImpl.java index 5cacf273efe6..b5a4913b32a6 100644 --- a/platform/lang-impl/src/com/intellij/util/indexing/ValueContainerImpl.java +++ b/platform/lang-impl/src/com/intellij/util/indexing/ValueContainerImpl.java @@ -16,6 +16,7 @@ package com.intellij.util.indexing; +import com.intellij.openapi.diagnostic.Logger; import gnu.trove.TIntHashSet; import gnu.trove.TIntIterator; @@ -26,6 +27,8 @@ import java.util.*; * Date: Dec 20, 2007 */ class ValueContainerImpl extends UpdatableValueContainer implements Cloneable{ + private static final Logger LOG = Logger.getInstance("#com.intellij.util.indexing.ValueContainerImpl"); + private HashMap myInputIdMapping; public ValueContainerImpl() { @@ -60,17 +63,19 @@ class ValueContainerImpl extends UpdatableValueContainer implement @Override public void removeAssociatedValue(int inputId) { - Value toRemove = null; + final List toRemove = new ArrayList(1); for (final Iterator valueIterator = getValueIterator(); valueIterator.hasNext();) { final Value value = valueIterator.next(); if (isAssociated(value, inputId)) { - assert toRemove == null; - toRemove = value; + LOG.assertTrue(toRemove.isEmpty(), "Expected only one value per-inputId"); + toRemove.add(value); } } - if (toRemove != null) { - removeValue(inputId, toRemove); + if (!toRemove.isEmpty()) { + for (Value value : toRemove) { + removeValue(inputId, value); + } } } From 5a62d0380157b3637ab815a7a82b9023b36e0969 Mon Sep 17 00:00:00 2001 From: irengrig Date: Thu, 8 Dec 2011 15:08:38 +0400 Subject: [PATCH 05/62] system-dependent slashes in file paths for show diff & show merge conflict dialogs/frames --- .../vcs/changes/actions/ChangeDiffRequestPresentable.java | 4 ++++ .../vcs/changes/patch/MergedDiffRequestPresentable.java | 5 +++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/actions/ChangeDiffRequestPresentable.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/actions/ChangeDiffRequestPresentable.java index e2bbf1b169a5..896753e6c56d 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/actions/ChangeDiffRequestPresentable.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/actions/ChangeDiffRequestPresentable.java @@ -83,12 +83,16 @@ public class ChangeDiffRequestPresentable implements DiffRequestPresentable { String afterPath = aRev != null ? aRev.getFile().getPath() : null; String title; if (beforePath != null && afterPath != null && !beforePath.equals(afterPath)) { + beforePath = FileUtil.toSystemDependentName(beforePath); + afterPath = FileUtil.toSystemDependentName(afterPath); title = beforePath + " -> " + afterPath; } else if (beforePath != null) { + beforePath = FileUtil.toSystemDependentName(beforePath); title = beforePath; } else if (afterPath != null) { + afterPath = FileUtil.toSystemDependentName(afterPath); title = afterPath; } else { diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/patch/MergedDiffRequestPresentable.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/patch/MergedDiffRequestPresentable.java index cfa453a07882..4a08b11121d4 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/patch/MergedDiffRequestPresentable.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/patch/MergedDiffRequestPresentable.java @@ -21,6 +21,7 @@ import com.intellij.openapi.diff.MergeRequest; import com.intellij.openapi.diff.SimpleDiffRequest; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Getter; +import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.vcs.FilePathImpl; import com.intellij.openapi.vcs.VcsBundle; import com.intellij.openapi.vcs.changes.actions.*; @@ -57,8 +58,8 @@ public class MergedDiffRequestPresentable implements DiffRequestPresentable { } final MergeRequest request = DiffRequestFactory.getInstance() .create3WayDiffRequest(revisionTexts.getLocal().toString(), revisionTexts.getPatched(), revisionTexts.getBase().toString(), myProject, null, null); - request.setWindowTitle(VcsBundle.message("patch.apply.conflict.title", myFile.getPresentableUrl())); - request.setVersionTitles(new String[] {"Current Version", "Base Version", myAfterTitle}); + request.setWindowTitle(VcsBundle.message("patch.apply.conflict.title", FileUtil.toSystemDependentName(myFile.getPresentableUrl()))); + request.setVersionTitles(new String[] {"Current Version", "Base Version", FileUtil.toSystemDependentName(myAfterTitle)}); return new MyResult(request, DiffPresentationReturnValue.useRequest); } From 999c12dc5de1a61691225b6a2e2bfedaff59f479 Mon Sep 17 00:00:00 2001 From: Roman Chernyatchik Date: Thu, 8 Dec 2011 14:48:01 +0300 Subject: [PATCH 06/62] rspec: workaround for negative line numbers (bug in cucumber+jruby) --- .../execution/testframework/sm/FileUrlProvider.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/platform/smRunner/src/com/intellij/execution/testframework/sm/FileUrlProvider.java b/platform/smRunner/src/com/intellij/execution/testframework/sm/FileUrlProvider.java index a10a86bffcbc..746baebfa6e5 100644 --- a/platform/smRunner/src/com/intellij/execution/testframework/sm/FileUrlProvider.java +++ b/platform/smRunner/src/com/intellij/execution/testframework/sm/FileUrlProvider.java @@ -81,9 +81,13 @@ public class FileUrlProvider implements TestLocationProvider, DumbAware { return Collections.emptyList(); } + if (lineNumber < 0) { + LOG.warn("Tests location provider: line number should be >= 1. Path: " + path); + } + final List locations = new ArrayList(2); for (VirtualFile file : virtualFiles) { - locations.add(createLocationFor(project, file, lineNumber)); + locations.add(createLocationFor(project, file, lineNumber < 1 ? 1 : lineNumber)); } return locations; } From 387c6b4d2cea1d9e847e53417ceabef3940bb535 Mon Sep 17 00:00:00 2001 From: Roman Chernyatchik Date: Thu, 8 Dec 2011 14:52:03 +0300 Subject: [PATCH 07/62] plugin manager: handle optional dependencies correctly when IDEA is launched from sources and optional dependency config xml isn't in the same folder with plugin.xml --- .../intellij/ide/plugins/PluginManager.java | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/ide/plugins/PluginManager.java b/platform/platform-impl/src/com/intellij/ide/plugins/PluginManager.java index c53aa37430c9..10ba954a4e0f 100644 --- a/platform/platform-impl/src/com/intellij/ide/plugins/PluginManager.java +++ b/platform/platform-impl/src/com/intellij/ide/plugins/PluginManager.java @@ -908,11 +908,26 @@ public class PluginManager { if (descriptor != null && !descriptor.getOptionalConfigs().isEmpty()) { final Map descriptors = new HashMap(descriptor.getOptionalConfigs().size()); for (Map.Entry entry: descriptor.getOptionalConfigs().entrySet()) { - assert !Comparing.equal(fileName, entry.getValue()) : "recursive dependency: "+fileName; - final IdeaPluginDescriptorImpl optionalDescriptor = loadDescriptor(file, entry.getValue()); + String optionalDescriptorName = entry.getValue(); + assert !Comparing.equal(fileName, optionalDescriptorName) : "recursive dependency: "+ fileName; + + IdeaPluginDescriptorImpl optionalDescriptor = loadDescriptor(file, optionalDescriptorName); + if (optionalDescriptor == null && !ClassloaderUtil.isJarOrZip(file)) { + for (URL url : getClassLoaderUrls()) { + if ("file".equals(url.getProtocol())) { + optionalDescriptor = loadDescriptor(new File(URLDecoder.decode(url.getFile())), optionalDescriptorName); + if (optionalDescriptor != null) { + break; + } + } + } + } if (optionalDescriptor != null) { descriptors.put(entry.getKey(), optionalDescriptor); } + else { + getLogger().info("Cannot find optional descriptor " + optionalDescriptorName); + } } descriptor.setOptionalDescriptors(descriptors); } From 173684937dfa717f41ee9d2ec15aceed76c801e7 Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Thu, 8 Dec 2011 15:17:06 +0400 Subject: [PATCH 08/62] assertion --- .../src/com/intellij/psi/impl/DocumentCommitThread.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/psi/impl/DocumentCommitThread.java b/platform/lang-impl/src/com/intellij/psi/impl/DocumentCommitThread.java index 5031f3986d35..7533c674ee76 100644 --- a/platform/lang-impl/src/com/intellij/psi/impl/DocumentCommitThread.java +++ b/platform/lang-impl/src/com/intellij/psi/impl/DocumentCommitThread.java @@ -18,6 +18,7 @@ package com.intellij.psi.impl; import com.intellij.ide.startup.impl.StartupManagerImpl; import com.intellij.openapi.Disposable; import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.application.ModalityState; import com.intellij.openapi.application.ex.ApplicationManagerEx; import com.intellij.openapi.components.ServiceManager; import com.intellij.openapi.diagnostic.Logger; @@ -53,7 +54,6 @@ import com.intellij.util.IncorrectOperationException; import com.intellij.util.Processor; import com.intellij.util.SmartList; import com.intellij.util.containers.Queue; -import com.intellij.util.ui.UIUtil; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -156,6 +156,7 @@ public class DocumentCommitThread implements Runnable, Disposable { Object[] documentTasks = documentsToCommit.toArray(); for (Object o : documentTasks) { + assert o != null : "Null element in:" + documentsToCommit; CommitTask task = (CommitTask)o; if (task.document == document) { ProgressIndicator current = document.getUserData(COMMIT_PROGRESS); @@ -316,7 +317,8 @@ public class DocumentCommitThread implements Runnable, Disposable { success = false; } if (success) { - UIUtil.invokeLaterIfNeeded(finishRunnable); + assert !ApplicationManager.getApplication().isDispatchThread(); + ApplicationManager.getApplication().invokeLater(finishRunnable, ModalityState.NON_MODAL); // do not commit while modal progress is running log("Invoked later finishRunnable", document, false, success, finishRunnable, indicator); } } @@ -422,6 +424,7 @@ public class DocumentCommitThread implements Runnable, Disposable { @NotNull final Object reason) { final List> finishRunnables = new SmartList>(); Runnable runnable = new Runnable() { + @Override public void run() { if (project.isDisposed()) return; final PsiDocumentManagerImpl documentManager = (PsiDocumentManagerImpl)PsiDocumentManager.getInstance(project); @@ -672,6 +675,7 @@ public class DocumentCommitThread implements Runnable, Disposable { final PomModel model = PomManager.getModel(fileImpl.getProject()); model.runTransaction(new PomTransactionBase(fileImpl, model.getModelAspect(TreeAspect.class)) { + @Override public PomModelEvent runInner() { return new TreeAspectEvent(model, diffLog.performActualPsiChange(file)); } From e5c908c96ba2ed464c4d77f1e8fbe49667ea35d3 Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Thu, 8 Dec 2011 15:17:26 +0400 Subject: [PATCH 09/62] cleanup --- .../intellij/codeInsight/daemon/LineMarkerInfo.java | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/platform/lang-api/src/com/intellij/codeInsight/daemon/LineMarkerInfo.java b/platform/lang-api/src/com/intellij/codeInsight/daemon/LineMarkerInfo.java index e993113a46ae..c944eec2ffb4 100644 --- a/platform/lang-api/src/com/intellij/codeInsight/daemon/LineMarkerInfo.java +++ b/platform/lang-api/src/com/intellij/codeInsight/daemon/LineMarkerInfo.java @@ -48,22 +48,14 @@ public class LineMarkerInfo { private final GutterIconRenderer.Alignment myIconAlignment; @Nullable private final GutterIconNavigationHandler myNavigationHandler; - - public LineMarkerInfo(T element, + public LineMarkerInfo(@NotNull T element, int startOffset, Icon icon, int updatePass, @Nullable Function tooltipProvider, @Nullable GutterIconNavigationHandler navHandler, GutterIconRenderer.Alignment alignment) { - myIcon = icon; - myTooltipProvider = tooltipProvider; - myIconAlignment = alignment; - elementRef = new WeakReference(element); - myNavigationHandler = navHandler; - this.startOffset = startOffset; - this.updatePass = updatePass; - endOffset = startOffset; + this(element, new TextRange(startOffset, startOffset), icon, updatePass, tooltipProvider, navHandler, alignment); } public LineMarkerInfo(@NotNull T element, @NotNull TextRange range, From 5459b91c409c70e7258ec4afda1a0ed58e946365 Mon Sep 17 00:00:00 2001 From: Eugene Zhuravlev Date: Thu, 8 Dec 2011 12:20:42 +0100 Subject: [PATCH 10/62] advance index version --- .../src/com/intellij/util/indexing/IndexInfrastructure.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/lang-impl/src/com/intellij/util/indexing/IndexInfrastructure.java b/platform/lang-impl/src/com/intellij/util/indexing/IndexInfrastructure.java index cd07cd508c41..290080cb23fc 100644 --- a/platform/lang-impl/src/com/intellij/util/indexing/IndexInfrastructure.java +++ b/platform/lang-impl/src/com/intellij/util/indexing/IndexInfrastructure.java @@ -35,7 +35,7 @@ import java.util.Locale; @SuppressWarnings({"HardCodedStringLiteral"}) public class IndexInfrastructure { - private static final int VERSION = 8; + private static final int VERSION = 9; private static final TObjectLongHashMap> ourIndexIdToCreationStamp = new TObjectLongHashMap>(); private static final boolean ourUnitTestMode = ApplicationManager.getApplication().isUnitTestMode(); From 146c33ae14c50c24686fdb8e8553edb1761d8549 Mon Sep 17 00:00:00 2001 From: anna Date: Thu, 8 Dec 2011 12:22:36 +0100 Subject: [PATCH 11/62] do not update plugins list when exception occurs during retrieval (IDEA-78482) --- .../src/com/intellij/ide/plugins/PluginManagerMain.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/platform-impl/src/com/intellij/ide/plugins/PluginManagerMain.java b/platform/platform-impl/src/com/intellij/ide/plugins/PluginManagerMain.java index 4e2f4395a292..b5039dbd36c0 100644 --- a/platform/platform-impl/src/com/intellij/ide/plugins/PluginManagerMain.java +++ b/platform/platform-impl/src/com/intellij/ide/plugins/PluginManagerMain.java @@ -234,7 +234,7 @@ public abstract class PluginManagerMain implements Disposable { public void finished() { UIUtil.invokeLaterIfNeeded(new Runnable() { public void run() { - if (list != null) { + if (list != null && errorMessages.isEmpty()) { modifyPluginsList(list); propagateUpdates(list); setDownloadStatus(false); From 2a4458056e87a5f391ebf55362056342ecaffddf Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Thu, 8 Dec 2011 15:41:33 +0400 Subject: [PATCH 12/62] diagnostics --- .../util/src/com/intellij/util/containers/Queue.java | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/platform/util/src/com/intellij/util/containers/Queue.java b/platform/util/src/com/intellij/util/containers/Queue.java index 1dbe2e36756c..21570b3b0fe1 100644 --- a/platform/util/src/com/intellij/util/containers/Queue.java +++ b/platform/util/src/com/intellij/util/containers/Queue.java @@ -127,4 +127,13 @@ public class Queue { } return true; } + + @Override + public String toString() { + List list = Arrays.asList(myArray); + if (isWrapped) { + return "[[[ " +list.subList(0, myLast) + " ||| ... " + list.subList(myLast, myFirst) + " ... ||| " + list.subList(myFirst, myArray.length) + " ]]]"; + } + return "[[[ ... " +list.subList(0, myFirst) + " ... ||| " + list.subList(myFirst, myLast) + " ||| ... " + list.subList(myFirst, myArray.length) + " ... ]]]"; + } } From e6c584b0cb3a2dec0c6adb6822388dea9ac50da7 Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Thu, 8 Dec 2011 16:37:53 +0400 Subject: [PATCH 13/62] NPE in tests fixed --- platform/util/src/com/intellij/util/containers/Queue.java | 1 + 1 file changed, 1 insertion(+) diff --git a/platform/util/src/com/intellij/util/containers/Queue.java b/platform/util/src/com/intellij/util/containers/Queue.java index 21570b3b0fe1..94e5b230c5eb 100644 --- a/platform/util/src/com/intellij/util/containers/Queue.java +++ b/platform/util/src/com/intellij/util/containers/Queue.java @@ -106,6 +106,7 @@ public class Queue { public void clear() { Arrays.fill(myArray, null); myFirst = myLast = 0; + isWrapped = false; } public boolean process(@NotNull Processor processor) { From 5873c7e3bceb239360b173e824c91eabbfef9a4c Mon Sep 17 00:00:00 2001 From: "kirill.safonov" Date: Wed, 7 Dec 2011 22:08:03 +0400 Subject: [PATCH 14/62] strip '&' from action description --- .../src/com/intellij/ide/util/DirectoryChooser.java | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/ide/util/DirectoryChooser.java b/platform/lang-impl/src/com/intellij/ide/util/DirectoryChooser.java index 68cdb0468c71..bc0f6718c494 100644 --- a/platform/lang-impl/src/com/intellij/ide/util/DirectoryChooser.java +++ b/platform/lang-impl/src/com/intellij/ide/util/DirectoryChooser.java @@ -18,7 +18,6 @@ package com.intellij.ide.util; import com.intellij.openapi.actionSystem.*; import com.intellij.openapi.project.Project; -import com.intellij.openapi.project.ProjectUtil; import com.intellij.openapi.roots.FileIndex; import com.intellij.openapi.roots.ProjectRootManager; import com.intellij.openapi.ui.DialogWrapper; @@ -33,14 +32,13 @@ import com.intellij.refactoring.RefactoringBundle; import com.intellij.ui.ScrollPaneFactory; import com.intellij.util.ArrayUtil; import com.intellij.util.PlatformIcons; +import com.intellij.util.ui.UIUtil; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.Nullable; import javax.swing.*; -import javax.swing.tree.DefaultTreeModel; import java.awt.*; import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; import java.awt.event.KeyEvent; import java.io.File; import java.util.ArrayList; @@ -77,7 +75,7 @@ public class DirectoryChooser extends DialogWrapper { final JPanel panel = new JPanel(new BorderLayout()); final DefaultActionGroup actionGroup = new DefaultActionGroup(); actionGroup.add(new ToggleAction(RefactoringBundle.message("directory.chooser.hide.non.existent.checkBox.text"), - RefactoringBundle.message("directory.chooser.hide.non.existent.checkBox.text"), + UIUtil.removeMnemonic(RefactoringBundle.message("directory.chooser.hide.non.existent.checkBox.text")), IconLoader.getIcon("/ant/filter.png")) { @Override public boolean isSelected(AnActionEvent e) { From 67d2c0c697521d180147e634efcc3b660aaa87a9 Mon Sep 17 00:00:00 2001 From: Eugene Zhuravlev Date: Thu, 8 Dec 2011 14:15:43 +0100 Subject: [PATCH 15/62] [r=nik] annotation processing option fix --- .../javaCompiler/javac/JavacCompiler.java | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/javac/JavacCompiler.java b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/javac/JavacCompiler.java index 5a66b0f9c6a3..85133995723e 100644 --- a/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/javac/JavacCompiler.java +++ b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/javac/JavacCompiler.java @@ -274,11 +274,12 @@ public class JavacCompiler extends ExternalCompiler { } public static List addAdditionalSettings(List commandLine, JavacSettings javacSettings, boolean isAnnotationProcessing, - JavaSdkVersion version, Project project, final boolean annotationProcessorsEnabled) { + JavaSdkVersion version, Project project, boolean annotationProcessorsEnabled) { final List additionalOptions = new ArrayList(); StringTokenizer tokenizer = new StringTokenizer(javacSettings.getOptionsString(project), " "); if (!version.isAtLeast(JavaSdkVersion.JDK_1_6)) { isAnnotationProcessing = false; // makes no sense for these versions + annotationProcessorsEnabled = false; } if (isAnnotationProcessing) { final CompilerConfiguration config = CompilerConfiguration.getInstance(project); @@ -311,7 +312,7 @@ public class JavacCompiler extends ExternalCompiler { } } else { - if (version.isAtLeast(JavaSdkVersion.JDK_1_6) && annotationProcessorsEnabled) { + if (annotationProcessorsEnabled) { // Unless explicitly specified by user, disable annotation processing by default for 'java compilation' mode // This is needed to suppress unwanted side-effects from auto-discovered processors from compilation classpath additionalOptions.add("-proc:none"); @@ -326,14 +327,22 @@ public class JavacCompiler extends ExternalCompiler { if (!version.isAtLeast(JavaSdkVersion.JDK_1_5) && "-Xlint".equals(token)) { continue; // not supported in these versions } - if (token.startsWith("-proc:")) { - continue; - } if (isAnnotationProcessing) { + if (token.startsWith("-proc:")) { + continue; + } if (token.startsWith("-implicit:")) { continue; } } + else { // compiling java + if (annotationProcessorsEnabled) { + // in this mode we have -proc:none already added above, so user's settings should be ignored + if (token.startsWith("-proc:")) { + continue; + } + } + } if (token.startsWith("-J-")) { commandLine.add(token.substring("-J".length())); } From 095c3f4f36d817603395ff03b1d8d43de87d229c Mon Sep 17 00:00:00 2001 From: Alexey Pegov Date: Thu, 8 Dec 2011 17:20:25 +0400 Subject: [PATCH 16/62] ui inspector improved --- .../internal/inspector/UiInspectorAction.java | 243 ++++++++++++++++-- 1 file changed, 216 insertions(+), 27 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/internal/inspector/UiInspectorAction.java b/platform/platform-impl/src/com/intellij/internal/inspector/UiInspectorAction.java index f4c1acd64ac3..75a098b5906b 100644 --- a/platform/platform-impl/src/com/intellij/internal/inspector/UiInspectorAction.java +++ b/platform/platform-impl/src/com/intellij/internal/inspector/UiInspectorAction.java @@ -15,6 +15,10 @@ */ package com.intellij.internal.inspector; +import com.intellij.notification.Notification; +import com.intellij.notification.NotificationType; +import com.intellij.notification.Notifications; +import com.intellij.notification.NotificationsManager; import com.intellij.openapi.Disposable; import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.actionSystem.ToggleAction; @@ -25,16 +29,20 @@ import com.intellij.openapi.util.IconLoader; import com.intellij.openapi.util.text.StringUtil; import com.intellij.util.containers.HashMap; import com.intellij.util.ui.UIUtil; +import com.intellij.util.ui.tree.TreeUtil; import org.jetbrains.annotations.NotNull; import javax.swing.*; import javax.swing.border.Border; import javax.swing.border.EmptyBorder; +import javax.swing.event.TreeSelectionEvent; +import javax.swing.event.TreeSelectionListener; import javax.swing.plaf.ColorUIResource; import javax.swing.table.AbstractTableModel; import javax.swing.table.TableCellRenderer; import javax.swing.table.TableColumn; import javax.swing.table.TableColumnModel; +import javax.swing.tree.*; import java.awt.*; import java.awt.event.*; import java.lang.reflect.InvocationTargetException; @@ -42,6 +50,7 @@ import java.lang.reflect.Method; import java.util.ArrayList; import java.util.List; import java.util.Map; +import java.util.Vector; /** * User: spLeaner @@ -62,6 +71,12 @@ public class UiInspectorAction extends ToggleAction implements DumbAware { myInspector = new UiInspector(); Toolkit.getDefaultToolkit().addAWTEventListener(myInspector, AWTEvent.MOUSE_EVENT_MASK); } + + UiInspectorNotification[] existing = + NotificationsManager.getNotificationsManager().getNotificationsOfType(UiInspectorNotification.class, null); + if (existing.length == 0) { + Notifications.Bus.notify(new UiInspectorNotification(), null); + } } else { if (myInspector != null) { @@ -71,41 +86,36 @@ public class UiInspectorAction extends ToggleAction implements DumbAware { } } } + + private static class UiInspectorNotification extends Notification { + private UiInspectorNotification() { + super(Notifications.SYSTEM_MESSAGES_GROUP_ID, "UI Inspector", "Control-Alt-Click to view component info!", + NotificationType.INFORMATION); + } + } private static class InspectorWindow extends JFrame { private InspectorTable myInspectorTable; private UiInspector myUiInspector; private JComponent myComponent; - private boolean myHighlighted = false; + private boolean myHighlighted = true; private HighlightComponent myHighlightComponent; + private HierarchyTree myHierarchyTree; + private final JPanel myWrapperPanel; private InspectorWindow(@NotNull final JComponent component, UiInspector uiInspector) throws HeadlessException { myComponent = component; myUiInspector = uiInspector; getRootPane().setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); - setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); + setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE); setLayout(new BorderLayout()); final String simpleName = component.getClass().getSimpleName(); setTitle(simpleName.length() == 0 ? component.getClass().getName() : simpleName); - JToolBar bar = new JToolBar(JToolBar.HORIZONTAL); + JToolBar bar = new JToolBar(SwingConstants.HORIZONTAL); bar.setFloatable(false); - bar.add(new AbstractAction("Show parent", IconLoader.getIcon("/nodes/parentsIntroduction.png")) { - public void actionPerformed(ActionEvent e) { - Container parent = component.getParent(); - if (parent instanceof JComponent) { - myUiInspector.showInspector((JComponent) parent); - } - } - - @Override - public boolean isEnabled() { - return myComponent.getParent() != null; - } - }); - bar.add(new AbstractAction("Highlight", IconLoader.getIcon("/toolbar/unknown.png")) { public void actionPerformed(ActionEvent e) { myHighlighted = !myHighlighted; @@ -122,7 +132,7 @@ public class UiInspectorAction extends ToggleAction implements DumbAware { bar.add(new AbstractAction("Refresh", IconLoader.getIcon("/vcs/refresh.png")) { public void actionPerformed(ActionEvent e) { - myInspectorTable.refresh(); + getCurrentTable().refresh(); } @Override @@ -133,9 +143,31 @@ public class UiInspectorAction extends ToggleAction implements DumbAware { add(bar, BorderLayout.NORTH); + + myWrapperPanel = new JPanel(new BorderLayout()); + add(new JLabel(component.getClass().getName()), BorderLayout.SOUTH); myInspectorTable = new InspectorTable(component); - add(myInspectorTable, BorderLayout.CENTER); + myHierarchyTree = new HierarchyTree(component) { + @Override + public void onComponentChanged(Component c) { + highlight(myComponent, true); + switchInfo(c); + if (myHighlighted) highlight(c, false); + } + }; + + myWrapperPanel.add(myInspectorTable, BorderLayout.CENTER); + + JSplitPane splitPane = new JSplitPane(); + splitPane.setDividerLocation(0.5); + splitPane.setRightComponent(myWrapperPanel); + + JScrollPane pane = new JScrollPane(myHierarchyTree); + splitPane.setLeftComponent(pane); + add(splitPane, BorderLayout.CENTER); + + myHierarchyTree.expandPath(); addWindowListener(new WindowAdapter() { @Override @@ -157,6 +189,18 @@ public class UiInspectorAction extends ToggleAction implements DumbAware { getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), "CLOSE"); } + private InspectorTable getCurrentTable() { + return myInspectorTable; + } + + private void switchInfo(Component c) { + myInspectorTable = new InspectorTable(c); + myWrapperPanel.removeAll(); + myWrapperPanel.add(myInspectorTable, BorderLayout.CENTER); + myWrapperPanel.revalidate(); + myWrapperPanel.repaint(); + } + public void close() { highlight(myComponent, true); myComponent = null; @@ -193,7 +237,150 @@ public class UiInspectorAction extends ToggleAction implements DumbAware { return myComponent; } } + + private static class ComponentTreeCellRenderer extends JLabel implements TreeCellRenderer { + private ComponentTreeCellRenderer() { + setOpaque(true); + setFont(UIUtil.getLabelFont().deriveFont(11f)); + setBorder(BorderFactory.createEmptyBorder(0, 3, 0, 3)); + } + @Override + public Component getTreeCellRendererComponent(JTree tree, + Object value, + boolean selected, + boolean expanded, + boolean leaf, + int row, + boolean hasFocus) { + Color foreground = selected ? UIUtil.getTreeSelectionForeground() : UIUtil.getTreeForeground(); + Color background = selected ? UIUtil.getTreeSelectionBackground() : null; + if (value instanceof HierarchyTree.ComponentNode) { + HierarchyTree.ComponentNode componentNode = (HierarchyTree.ComponentNode)value; + Component component = componentNode.getOwnComponent(); + String name = component.getClass().getSimpleName(); + if (name.length() == 0) { + name = component.getClass().getSuperclass().getSimpleName(); + } + + if (!selected) { + if (!component.isVisible()) { + foreground = Color.GRAY; + } else if (component.getWidth() == 0 || component.getHeight() == 0) { + foreground = new Color(128, 10, 0); + } + + if (componentNode.getToSelect() == componentNode.getOwnComponent()) { + background = new Color(31, 128, 8, 58); + } + } + setText(name); + } + + setForeground(foreground); + setBackground(background); + + return this; + } + } + + private abstract static class HierarchyTree extends JTree implements TreeSelectionListener { + private final JComponent myComponent; + + private HierarchyTree(JComponent c) { + myComponent = c; + setModel(buildModel(c)); + setCellRenderer(new ComponentTreeCellRenderer()); + getSelectionModel().addTreeSelectionListener(this); + } + + public void expandPath() { + TreeUtil.expandAll(this); + int count = getRowCount(); + ComponentNode node = new ComponentNode(myComponent, myComponent.getParent()); + + for (int i = 0; i < count; i++) { + TreePath row = getPathForRow(i); + if (row.getLastPathComponent().equals(node)) { + setSelectionPath(row); + scrollPathToVisible(getSelectionPath()); + break; + } + } + } + + @Override + public void valueChanged(TreeSelectionEvent e) { + TreePath path = e.getNewLeadSelectionPath(); + Object component = path.getLastPathComponent(); + if (component instanceof ComponentNode) { + Component c = ((ComponentNode)component).getOwnComponent(); + onComponentChanged(c); + } + } + + private static TreeModel buildModel(JComponent c) { + return new DefaultTreeModel(new ComponentNode(c, null)); + } + + public abstract void onComponentChanged(Component c); + + private static class ComponentNode extends DefaultMutableTreeNode { + private final Component myParent; + private final Component myToSelect; + + private ComponentNode(Object userObject, Component parent) { + super(userObject); + myParent = parent == null ? SwingUtilities.getWindowAncestor((Component) userObject) : parent; + myToSelect = (Component)userObject; + children = prepareChildren(myToSelect, parent); + } + + public Component getOwnComponent() { + return myParent; + } + + public Component getToSelect() { + return myToSelect; + } + + @Override + public String toString() { + return myParent.getClass().getName(); + } + + @Override + public boolean equals(Object obj) { + return obj instanceof ComponentNode && ((ComponentNode)obj).getOwnComponent() == getOwnComponent(); + } + + @SuppressWarnings("UseOfObsoleteCollectionType") + private static Vector prepareChildren(Component toSelect, Component parent) { + Vector result = new Vector(); + if (parent == null) { + Container root = toSelect.getParent(); + while (true) { + Container _superRoot = root.getParent(); + if (_superRoot == null) break; + root = _superRoot; + } + + for (Component component : root.getComponents()) { + result.add(new ComponentNode(toSelect, component)); + } + } else { + if (parent instanceof Container) { + for (Component component : ((Container)parent).getComponents()) { + result.add(new ComponentNode(toSelect, component)); + } + } + } + + return result; + } + } + } + private static class HighlightComponent extends JComponent { private Color myColor; @@ -226,7 +413,7 @@ public class UiInspectorAction extends ToggleAction implements DumbAware { private InspectorTableModel myModel; private DimensionsComponent myDimensionComponent; - private InspectorTable(@NotNull final JComponent component) { + private InspectorTable(@NotNull final Component component) { setLayout(new BorderLayout()); myModel = new InspectorTableModel(component); @@ -258,13 +445,13 @@ public class UiInspectorAction extends ToggleAction implements DumbAware { } private static class DimensionsComponent extends JComponent { - private JComponent myComponent; + private Component myComponent; private int myWidth; private int myHeight; private Border myBorder; private Insets myInsets; - private DimensionsComponent(@NotNull final JComponent component) { + private DimensionsComponent(@NotNull final Component component) { myComponent = component; setOpaque(true); setBackground(Color.WHITE); @@ -278,8 +465,10 @@ public class UiInspectorAction extends ToggleAction implements DumbAware { public void update() { myWidth = myComponent.getWidth(); myHeight = myComponent.getHeight(); - myBorder = myComponent.getBorder(); - myInsets = myComponent.getInsets(); + if (myComponent instanceof JComponent) { + myBorder = ((JComponent)myComponent).getBorder(); + myInsets = ((JComponent)myComponent).getInsets(); + } } @Override @@ -485,17 +674,17 @@ public class UiInspectorAction extends ToggleAction implements DumbAware { "isShowing", "isEnabled", "isLightweight", "isFocusable", "isFocusOwner" }; - private JComponent myComponent; + private Component myComponent; private List myProperties = new ArrayList(); - public InspectorTableModel(@NotNull final JComponent c) { + public InspectorTableModel(@NotNull final Component c) { myComponent = c; fillTable(); } private void fillTable() { - final Class cls = myComponent.getClass(); + final Class cls = myComponent.getClass(); for (final String methodName: JCOMPONENT_METHODS) { try { final Method method = cls.getMethod(methodName); From 3e70c147a54dd296fc767b0614062f9cd9b6b43b Mon Sep 17 00:00:00 2001 From: nik Date: Thu, 8 Dec 2011 17:48:26 +0400 Subject: [PATCH 17/62] create project from existing sources: select suitable project sdk --- .../com/intellij/ide/impl/NewProjectUtil.java | 15 +++++---- .../impl/ProjectFromSourcesBuilderImpl.java | 33 ++++++++++++------- 2 files changed, 30 insertions(+), 18 deletions(-) diff --git a/java/idea-ui/src/com/intellij/ide/impl/NewProjectUtil.java b/java/idea-ui/src/com/intellij/ide/impl/NewProjectUtil.java index f725208093ba..41ce665cc145 100644 --- a/java/idea-ui/src/com/intellij/ide/impl/NewProjectUtil.java +++ b/java/idea-ui/src/com/intellij/ide/impl/NewProjectUtil.java @@ -192,15 +192,16 @@ public class NewProjectUtil { } public static void applyJdkToProject(@NotNull Project project, @NotNull Sdk jdk) { - JavaSdkVersion version = JavaSdk.getInstance().getVersion(jdk); - if (version == null) return; - ProjectRootManagerEx rootManager = ProjectRootManagerEx.getInstanceEx(project); rootManager.setProjectSdk(jdk); - LanguageLevel level = version.getMaxLanguageLevel(); - LanguageLevelProjectExtension ext = LanguageLevelProjectExtension.getInstance(project); - if (level.compareTo(ext.getLanguageLevel()) < 0) { - ext.setLanguageLevel(level); + + JavaSdkVersion version = JavaSdk.getInstance().getVersion(jdk); + if (version != null) { + LanguageLevel level = version.getMaxLanguageLevel(); + LanguageLevelProjectExtension ext = LanguageLevelProjectExtension.getInstance(project); + if (level.compareTo(ext.getLanguageLevel()) < 0) { + ext.setLanguageLevel(level); + } } } diff --git a/java/idea-ui/src/com/intellij/ide/util/projectWizard/importSources/impl/ProjectFromSourcesBuilderImpl.java b/java/idea-ui/src/com/intellij/ide/util/projectWizard/importSources/impl/ProjectFromSourcesBuilderImpl.java index d7f56497e4f6..1ed00b0c054a 100644 --- a/java/idea-ui/src/com/intellij/ide/util/projectWizard/importSources/impl/ProjectFromSourcesBuilderImpl.java +++ b/java/idea-ui/src/com/intellij/ide/util/projectWizard/importSources/impl/ProjectFromSourcesBuilderImpl.java @@ -35,7 +35,6 @@ import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.module.*; import com.intellij.openapi.options.ConfigurationException; import com.intellij.openapi.project.Project; -import com.intellij.openapi.projectRoots.JavaSdk; import com.intellij.openapi.projectRoots.Sdk; import com.intellij.openapi.roots.*; import com.intellij.openapi.roots.libraries.Library; @@ -55,6 +54,7 @@ import com.intellij.util.containers.MultiMap; import org.jdom.Element; import org.jdom.JDOMException; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.io.File; import java.io.IOException; @@ -357,20 +357,31 @@ public class ProjectFromSourcesBuilderImpl extends ProjectBuilder implements Pro for (ProjectDescriptor projectDescriptor : getSelectedDescriptors()) { for (ModuleDescriptor moduleDescriptor : projectDescriptor.getModules()) { try { - final File file = new File(moduleDescriptor.computeModuleFilePath()); - if (file.exists()) { - final Element rootElement = JDOMUtil.loadDocument(file).getRootElement(); - final String type = rootElement.getAttributeValue("type"); - if (type != null) { - final ModuleType moduleType = ModuleTypeManager.getInstance().findByID(type); - if (moduleType != null && !moduleType.createModuleBuilder().isSuitableSdk(sdk)) return false; - } - } + final ModuleType moduleType = getModuleType(moduleDescriptor); + if (moduleType != null && !moduleType.createModuleBuilder().isSuitableSdk(sdk)) return false; } catch (Exception ignore) { } } } - return sdk.getSdkType() == JavaSdk.getInstance(); + return true; + } + + @Nullable + private static ModuleType getModuleType(ModuleDescriptor moduleDescriptor) throws InvalidDataException, JDOMException, IOException { + if (moduleDescriptor.isReuseExistingElement()) { + final File file = new File(moduleDescriptor.computeModuleFilePath()); + if (file.exists()) { + final Element rootElement = JDOMUtil.loadDocument(file).getRootElement(); + final String type = rootElement.getAttributeValue("type"); + if (type != null) { + return ModuleTypeManager.getInstance().findByID(type); + } + } + return null; + } + else { + return moduleDescriptor.getModuleType(); + } } } From 86c79185d6d3a271ef6bcda1781ed8f767df5dd2 Mon Sep 17 00:00:00 2001 From: irengrig Date: Thu, 8 Dec 2011 18:23:27 +0400 Subject: [PATCH 18/62] vcs tests, bigger differences in ts when changing files --- .../src/com/intellij/testFramework/AbstractVcsTestCase.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/platform/testFramework/src/com/intellij/testFramework/AbstractVcsTestCase.java b/platform/testFramework/src/com/intellij/testFramework/AbstractVcsTestCase.java index c88b41fbe9fc..742765f3cc98 100644 --- a/platform/testFramework/src/com/intellij/testFramework/AbstractVcsTestCase.java +++ b/platform/testFramework/src/com/intellij/testFramework/AbstractVcsTestCase.java @@ -337,8 +337,8 @@ public abstract class AbstractVcsTestCase { @Override protected void run() throws Throwable { try { - final long newModTs = Math.max(System.currentTimeMillis(), file.getModificationStamp() + 1); - final long newTs = Math.max(System.currentTimeMillis(), file.getTimeStamp() + 1); + final long newModTs = Math.max(System.currentTimeMillis(), file.getModificationStamp() + 1100); + final long newTs = Math.max(System.currentTimeMillis(), file.getTimeStamp() + 1100); file.setBinaryContent(newContent.getBytes(), newModTs, newTs); final File file1 = new File(file.getPath()); file1.setLastModified(newModTs); From e742f7c465c28a0cdd207f41e8acd694254cf18d Mon Sep 17 00:00:00 2001 From: anna Date: Thu, 8 Dec 2011 13:52:09 +0100 Subject: [PATCH 19/62] plugins: do not "reinit" deleted plugins (IDEA-78531) --- .../com/intellij/ide/plugins/InstalledPluginsTableModel.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/platform-impl/src/com/intellij/ide/plugins/InstalledPluginsTableModel.java b/platform/platform-impl/src/com/intellij/ide/plugins/InstalledPluginsTableModel.java index 2559f56f8d17..e4eb8a3ccf27 100644 --- a/platform/platform-impl/src/com/intellij/ide/plugins/InstalledPluginsTableModel.java +++ b/platform/platform-impl/src/com/intellij/ide/plugins/InstalledPluginsTableModel.java @@ -241,7 +241,7 @@ public class InstalledPluginsTableModel extends PluginTableModel { final PluginId pluginId = existing.getPluginId(); final String idString = pluginId.getIdString(); final JDOMExternalizableStringList installedPlugins = PluginManagerUISettings.getInstance().myInstalledPlugins; - if (!installedPlugins.contains(idString)){ + if (!installedPlugins.contains(idString) && !((IdeaPluginDescriptorImpl)existing).isDeleted()){ installedPlugins.add(idString); } final PluginManagerUISettings updateSettings = PluginManagerUISettings.getInstance(); From 6fb0eb3a89161c03f1c566bae11c7055447b191d Mon Sep 17 00:00:00 2001 From: Dmitry Jemerov Date: Thu, 8 Dec 2011 16:49:22 +0100 Subject: [PATCH 20/62] use ApplicationInfoEx.getShadowInstance() for loading application name when logging (avoids SOE when everything is badly broken) --- .../src/com/intellij/idea/IdeaLogger.java | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/idea/IdeaLogger.java b/platform/platform-impl/src/com/intellij/idea/IdeaLogger.java index 8f66c2870029..b6959f86205c 100644 --- a/platform/platform-impl/src/com/intellij/idea/IdeaLogger.java +++ b/platform/platform-impl/src/com/intellij/idea/IdeaLogger.java @@ -15,10 +15,10 @@ */ package com.intellij.idea; -import com.intellij.openapi.application.ApplicationInfo; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.application.ex.ApplicationInfoEx; import com.intellij.openapi.application.impl.ApplicationImpl; +import com.intellij.openapi.application.impl.ApplicationInfoImpl; import com.intellij.openapi.command.CommandProcessor; import com.intellij.openapi.diagnostic.ApplicationInfoProvider; import com.intellij.openapi.diagnostic.IdeaLoggingEvent; @@ -185,14 +185,8 @@ public class IdeaLogger extends Logger { private static ApplicationInfoProvider getIdeaInfoProvider() { return new ApplicationInfoProvider() { public String getInfo() { - ApplicationImpl application = (ApplicationImpl)ApplicationManager.getApplication(); - if (application != null && application.isComponentsCreated()) { - if (application.hasComponent(ApplicationInfo.class)) { - ApplicationInfoEx ideInfo = (ApplicationInfoEx)application.getComponent(ApplicationInfo.class); - return ideInfo.getFullApplicationName() + " " + "Build #" + ideInfo.getBuild().asString(); - } - } - return null; + final ApplicationInfoEx info = ApplicationInfoImpl.getShadowInstance(); + return info.getFullApplicationName() + " " + "Build #" + info.getBuild().asString(); } }; } From 86659ffa7d4400d456455bb4814896646513557f Mon Sep 17 00:00:00 2001 From: Sergey Evdokimov Date: Thu, 8 Dec 2011 19:07:06 +0300 Subject: [PATCH 21/62] IDEA-78396 (Grails 2.0 RC3 controller not auto-reloading) --- .../groovy/debugger/GroovyHotSwapper.java | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/debugger/GroovyHotSwapper.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/debugger/GroovyHotSwapper.java index 8b38ae20f06e..3bd9e960a01c 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/debugger/GroovyHotSwapper.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/debugger/GroovyHotSwapper.java @@ -30,6 +30,7 @@ import java.io.IOException; import java.util.ArrayList; import java.util.List; import java.util.jar.Attributes; +import java.util.regex.Pattern; /** @@ -39,6 +40,8 @@ public class GroovyHotSwapper extends JavaProgramPatcher { private static final Logger LOG = Logger.getInstance("#org.jetbrains.plugins.groovy.debugger.GroovyHotSwapper"); private static final String GROOVY_HOTSWAP_AGENT_PATH = "groovy.hotswap.agent.path"; + private static final Pattern SPRING_LOADED_PATTERN = Pattern.compile("-javaagent:.+springloaded-core-[^/\\\\]+\\.jar"); + private static boolean endsWithAny(String s, List endings) { for (String extension : endings) { if (s.endsWith(extension)) { @@ -64,6 +67,16 @@ public class GroovyHotSwapper extends JavaProgramPatcher { return false; } + private static boolean hasSpringLoadedReloader(JavaParameters javaParameters) { + for (String param : javaParameters.getVMParametersList().getParameters()) { + if (SPRING_LOADED_PATTERN.matcher(param).matches()) { + return true; + } + } + + return false; + } + public void patchJavaParameters(Executor executor, RunProfile configuration, JavaParameters javaParameters) { if (!executor.getId().equals(DefaultDebugExecutor.EXECUTOR_ID)) { return; @@ -72,7 +85,11 @@ public class GroovyHotSwapper extends JavaProgramPatcher { if (!Registry.is("enable.groovy.hotswap")) { return; } - + + if (hasSpringLoadedReloader(javaParameters)) { + return; + } + if (!(configuration instanceof RunConfiguration)) { return; } From f12d8225a617c66bf30c0127fcf1dcfa38f90690 Mon Sep 17 00:00:00 2001 From: Maxim Shafirov Date: Tue, 6 Dec 2011 14:56:36 +0400 Subject: [PATCH 22/62] RCOD mute --- build/scripts/dist.gant | 3 +++ 1 file changed, 3 insertions(+) diff --git a/build/scripts/dist.gant b/build/scripts/dist.gant index 49bebb6899da..dab08a968c34 100644 --- a/build/scripts/dist.gant +++ b/build/scripts/dist.gant @@ -143,6 +143,9 @@ private def layoutMac(Map args, String home, Paths paths) { """ args["idea.properties.path"] = "$home/bin/idea.properties" + if (!isEap()) { + args["idea.properties"] = ["idea.fatal.error.notification":"disabled"]; + } def system_selector = args.system_selector // TODO remove the next line when system_selector for Mac and other OS will be unified system_selector = args.system_selector_mac From eaef6ec632875c1439ec426c355b43db1fd7eb5d Mon Sep 17 00:00:00 2001 From: Maxim Shafirov Date: Tue, 6 Dec 2011 20:02:22 +0400 Subject: [PATCH 23/62] NPE --- .../intellij/openapi/wm/impl/status/IdeStatusBarImpl.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/IdeStatusBarImpl.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/IdeStatusBarImpl.java index c5ae1e9efeb6..e7735ffaf980 100644 --- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/IdeStatusBarImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/IdeStatusBarImpl.java @@ -259,9 +259,9 @@ public class IdeStatusBarImpl extends JComponent implements StatusBarEx { myWidgetMap.clear(); myChildren.clear(); - myLeftPanel.removeAll(); - myRightPanel.removeAll(); - myCenterPanel.removeAll(); + if (myLeftPanel != null) myLeftPanel.removeAll(); + if (myRightPanel != null) myRightPanel.removeAll(); + if (myCenterPanel != null) myCenterPanel.removeAll(); } private void addWidget(@NotNull final StatusBarWidget widget, @NotNull final Position pos, @NotNull final String anchor) { From aae53042ca7dc1a8026855356f40ca3cabe49148 Mon Sep 17 00:00:00 2001 From: Eugene Zhuravlev Date: Thu, 8 Dec 2011 17:33:55 +0100 Subject: [PATCH 24/62] minor optimizations --- .../impl/src/com/intellij/compiler/impl/CompilerUtil.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/CompilerUtil.java b/java/compiler/impl/src/com/intellij/compiler/impl/CompilerUtil.java index 6176e0fee201..a7637185dc21 100644 --- a/java/compiler/impl/src/com/intellij/compiler/impl/CompilerUtil.java +++ b/java/compiler/impl/src/com/intellij/compiler/impl/CompilerUtil.java @@ -102,7 +102,9 @@ public class CompilerUtil { * @param files */ public static void refreshIOFiles(@NotNull final Collection files) { - LocalFileSystem.getInstance().refreshIoFiles(files); + if (!files.isEmpty()) { + LocalFileSystem.getInstance().refreshIoFiles(files); + } } public static void refreshIODirectories(@NotNull final Collection files) { @@ -114,7 +116,9 @@ public class CompilerUtil { filesToRefresh.add(virtualFile); } } - RefreshQueue.getInstance().refresh(false, true, null, VfsUtil.toVirtualFileArray(filesToRefresh)); + if (!filesToRefresh.isEmpty()) { + RefreshQueue.getInstance().refresh(false, true, null, VfsUtil.toVirtualFileArray(filesToRefresh)); + } } public static void refreshIOFile(final File file) { From 4396b9ac2ec55b76676757b5177654abe806c141 Mon Sep 17 00:00:00 2001 From: Konstantin Bulenkov Date: Thu, 8 Dec 2011 17:31:11 +0100 Subject: [PATCH 25/62] IDEA-78522 File chooser: Don't show hidden directories if corresponding option is unset --- .../openapi/fileChooser/FileTypeDescriptor.java | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/platform/platform-api/src/com/intellij/openapi/fileChooser/FileTypeDescriptor.java b/platform/platform-api/src/com/intellij/openapi/fileChooser/FileTypeDescriptor.java index 95941fac6b78..dab5da47eec7 100644 --- a/platform/platform-api/src/com/intellij/openapi/fileChooser/FileTypeDescriptor.java +++ b/platform/platform-api/src/com/intellij/openapi/fileChooser/FileTypeDescriptor.java @@ -35,7 +35,15 @@ public class FileTypeDescriptor extends FileChooserDescriptor { } @Override - public boolean isFileVisible(VirtualFile file, boolean showHiddenFiles) { + public boolean isFileVisible(VirtualFile file, boolean showHiddenFiles) { + if (!showHiddenFiles && FileElement.isFileHidden(file)) { + return false; + } + + if (file.isDirectory()) { + return true; + } + final String ex = file.getExtension(); return file.isDirectory() || (ex != null && ext.contains(ex.toLowerCase())); } From 08e893528cafbf9a8cf99d418a0f2c1a16c3afef Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Thu, 8 Dec 2011 17:55:46 +0100 Subject: [PATCH 26/62] [davdeev] Symlink support reloaded --- .../vfs/newvfs/impl/SymlinkDirectory.java | 68 ++++++++++++++++--- .../vfs/newvfs/impl/VirtualDirectoryImpl.java | 4 +- 2 files changed, 60 insertions(+), 12 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/impl/SymlinkDirectory.java b/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/impl/SymlinkDirectory.java index 28dfa5d2226e..dc12c2d4b485 100644 --- a/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/impl/SymlinkDirectory.java +++ b/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/impl/SymlinkDirectory.java @@ -15,9 +15,11 @@ */ package com.intellij.openapi.vfs.newvfs.impl; +import com.intellij.openapi.util.AtomicNotNullLazyValue; import com.intellij.openapi.util.NullableComputable; import com.intellij.openapi.util.RecursionManager; import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.vfs.newvfs.NewVirtualFile; import com.intellij.openapi.vfs.newvfs.NewVirtualFileSystem; import com.intellij.openapi.vfs.newvfs.VfsImplUtil; import org.jetbrains.annotations.NotNull; @@ -25,28 +27,72 @@ import org.jetbrains.annotations.Nullable; /** * @author Dmitry Avdeev - * Date: 10/31/11 + * @since 31.10.2011 */ +@SuppressWarnings("NonSynchronizedMethodOverridesSynchronizedMethod") public class SymlinkDirectory extends VirtualDirectoryImpl { + private final AtomicNotNullLazyValue myTarget = new AtomicNotNullLazyValue() { + @NotNull + @Override + protected VirtualDirectoryImpl compute() { + final String path = getFileSystem().resolveSymLink(SymlinkDirectory.this); + VirtualFile file = null; + if (path != null) { + file = findFile(path, false); + } + if (file == SymlinkDirectory.this && file != null) { + final VirtualFile parent = file.getParent(); + if (parent instanceof VirtualDirectoryImpl) { + ((VirtualDirectoryImpl)parent).removeChild(file); + file = findFile(path, true); + } + } + return file instanceof VirtualDirectoryImpl ? (VirtualDirectoryImpl)file : new VirtualDirectoryImpl("foo", SymlinkDirectory.this, getFileSystem(), 0); + } - @Nullable - private final VirtualFile myTarget; + @Nullable + private VirtualFile findFile(final String path, final boolean refresh) { + return RecursionManager.doPreventingRecursion(SymlinkDirectory.this, false, new NullableComputable() { + @Override + public VirtualFile compute() { + return refresh ? VfsImplUtil.refreshAndFindFileByPath(getFileSystem(), path) : VfsImplUtil.findFileByPath(getFileSystem(), path); + } + }); + } + }; public SymlinkDirectory(@NotNull String name, final VirtualDirectoryImpl parent, @NotNull final NewVirtualFileSystem fs, final int id) { super(name, parent, fs, id); - final String path = fs.resolveSymLink(this); + } - myTarget = path == null ? null : RecursionManager.doPreventingRecursion("", false, new NullableComputable() { - @Override - public VirtualFile compute() { - return VfsImplUtil.findFileByPath(getFileSystem(), path); - } - }); + @Override + public VirtualFileSystemEntry findChild(@NotNull String name) { + return myTarget.getValue().findChild(name); + } + + @Override + public NewVirtualFile findChildIfCached(@NotNull String name) { + return myTarget.getValue().findChildIfCached(name); + } + + @Override + public NewVirtualFile findChildById(int id) { + return myTarget.getValue().findChildById(id); + } + + @Override + public NewVirtualFile findChildByIdIfCached(int id) { + return myTarget.getValue().findChildByIdIfCached(id); + } + + @Override + public NewVirtualFile refreshAndFindChild(@NotNull String name) { + return myTarget.getValue().refreshAndFindChild(name); } @NotNull @Override public VirtualFile[] getChildren() { - return myTarget == null ? VirtualFile.EMPTY_ARRAY : myTarget.getChildren(); + return myTarget.getValue().getChildren(); } } diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/impl/VirtualDirectoryImpl.java b/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/impl/VirtualDirectoryImpl.java index 1f2a85384360..128963c96843 100644 --- a/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/impl/VirtualDirectoryImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/impl/VirtualDirectoryImpl.java @@ -63,6 +63,8 @@ import java.util.*; * @author max */ public class VirtualDirectoryImpl extends VirtualFileSystemEntry { + private static final boolean ALT_SYMLINK_HANDLING = "true".equals(System.getProperty("idea.io.alt.symlink")); + private static final VirtualFileSystemEntry NULL_VIRTUAL_FILE = new VirtualFileImpl("*?;%NULL", null, -42); private final NewVirtualFileSystem myFS; @@ -165,7 +167,7 @@ public class VirtualDirectoryImpl extends VirtualFileSystemEntry { final VirtualFileSystemEntry child; final NewVirtualFileSystem fs = getFileSystem(); if (PersistentFS.isDirectory(id)) { - child = /*PersistentFS.isSymLink(id) ? new SymlinkDirectory(name, this, fs, id) :*/ new VirtualDirectoryImpl(name, this, fs, id); + child = ALT_SYMLINK_HANDLING && PersistentFS.isSymLink(id) ? new SymlinkDirectory(name, this, fs, id) : new VirtualDirectoryImpl(name, this, fs, id); } else { child = new VirtualFileImpl(name, this, id); From 97191d8774f9d383953b3a4c115b7b70ca9ffd26 Mon Sep 17 00:00:00 2001 From: Dmitry Jemerov Date: Thu, 8 Dec 2011 18:24:24 +0100 Subject: [PATCH 27/62] towards reducing stub -> AST switches --- .../intellij/extapi/psi/StubBasedPsiElementBase.java | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/platform/core-impl/src/com/intellij/extapi/psi/StubBasedPsiElementBase.java b/platform/core-impl/src/com/intellij/extapi/psi/StubBasedPsiElementBase.java index aa68f383aebb..3e723b6d87e2 100644 --- a/platform/core-impl/src/com/intellij/extapi/psi/StubBasedPsiElementBase.java +++ b/platform/core-impl/src/com/intellij/extapi/psi/StubBasedPsiElementBase.java @@ -314,6 +314,16 @@ public class StubBasedPsiElementBase extends ASTDelegateP return PsiTreeUtil.getParentOfType(this, parentClass); } + @Nullable + protected PsiElement getStubOrPsiParent() { + T stub = myStub; + if (stub != null) { + //noinspection unchecked + return stub.getParentStub().getPsi(); + } + return getParent(); + } + @Override protected Object clone() { final StubBasedPsiElementBase stubbless = (StubBasedPsiElementBase)super.clone(); From 0891cd804a0703f6a9c50033beb818088a55c97f Mon Sep 17 00:00:00 2001 From: anna Date: Thu, 8 Dec 2011 18:39:59 +0100 Subject: [PATCH 28/62] CCE --- .../src/com/intellij/refactoring/copy/CopyClassesHandler.java | 1 + 1 file changed, 1 insertion(+) diff --git a/java/java-impl/src/com/intellij/refactoring/copy/CopyClassesHandler.java b/java/java-impl/src/com/intellij/refactoring/copy/CopyClassesHandler.java index 20f222c4e3a5..b4eea0e90ce1 100644 --- a/java/java-impl/src/com/intellij/refactoring/copy/CopyClassesHandler.java +++ b/java/java-impl/src/com/intellij/refactoring/copy/CopyClassesHandler.java @@ -91,6 +91,7 @@ public class CopyClassesHandler extends CopyHandlerDelegateBase { } continue; } + if (!(element instanceof PsiFileSystemItem)) return null; } fillResultsMap(result, containingFile, topLevelClasses); if (relativeMap != null) { From b5967d62b2e01d25b87e08264b263016eed38341 Mon Sep 17 00:00:00 2001 From: Dmitry Jemerov Date: Thu, 8 Dec 2011 18:42:46 +0100 Subject: [PATCH 29/62] avoid stack overflow in handleInitComponentError (when trying to show message dialog tries to load another component again) --- .../application/impl/ApplicationImpl.java | 64 +++++++++++-------- 1 file changed, 38 insertions(+), 26 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/openapi/application/impl/ApplicationImpl.java b/platform/platform-impl/src/com/intellij/openapi/application/impl/ApplicationImpl.java index 9c7c302d025b..f6b736c31f7d 100644 --- a/platform/platform-impl/src/com/intellij/openapi/application/impl/ApplicationImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/application/impl/ApplicationImpl.java @@ -108,6 +108,8 @@ public class ApplicationImpl extends ComponentManagerImpl implements Application private int myRestartCode = 0; private volatile int myExitCode = 0; private final Disposable myLastDisposable = Disposer.newDisposable(); // will be disposed last + + private boolean myHandlingInitComponentError; private final AtomicBoolean mySaveSettingsIsInProgress = new AtomicBoolean(false); @SuppressWarnings({"UseOfArchaicSystemPropertyAccessors"}) @@ -332,36 +334,46 @@ public class ApplicationImpl extends ComponentManagerImpl implements Application @Override protected void handleInitComponentError(final Throwable ex, final boolean fatal, final String componentClassName) { - if (PluginManager.isPluginClass(componentClassName)) { - LOG.error(ex); - PluginId pluginId = PluginManager.getPluginByClassName(componentClassName); - @NonNls final String errorMessage = "Plugin " + pluginId.getIdString() + " failed to initialize and will be disabled:\n" + ex.getMessage() + - "\nPlease restart " + ApplicationNamesInfo.getInstance().getFullProductName() + "."; - PluginManager.disablePlugin(pluginId.getIdString()); - if (!myHeadlessMode) { - JOptionPane.showMessageDialog(null, errorMessage); - } - else { - //noinspection UseOfSystemOutOrSystemErr - System.out.println(errorMessage); - System.exit(1); - } - return; // do not call super + if (myHandlingInitComponentError) { + return; } - if (fatal) { - LOG.error(ex); - @NonNls final String errorMessage = "Fatal error initializing class " + componentClassName + ":\n" + - ex.toString() + - "\nComplete error stacktrace was written to " + PathManager.getLogPath() + "/idea.log"; - if (!myHeadlessMode) { - JOptionPane.showMessageDialog(null, errorMessage); + myHandlingInitComponentError = true; + try { + if (PluginManager.isPluginClass(componentClassName)) { + LOG.error(ex); + PluginId pluginId = PluginManager.getPluginByClassName(componentClassName); + @NonNls final String errorMessage = + "Plugin " + pluginId.getIdString() + " failed to initialize and will be disabled:\n" + ex.getMessage() + + "\nPlease restart " + ApplicationNamesInfo.getInstance().getFullProductName() + "."; + PluginManager.disablePlugin(pluginId.getIdString()); + if (!myHeadlessMode) { + JOptionPane.showMessageDialog(null, errorMessage); + } + else { + //noinspection UseOfSystemOutOrSystemErr + System.out.println(errorMessage); + System.exit(1); + } + return; // do not call super } - else { - //noinspection UseOfSystemOutOrSystemErr - System.out.println(errorMessage); + if (fatal) { + LOG.error(ex); + @NonNls final String errorMessage = "Fatal error initializing class " + componentClassName + ":\n" + + ex.toString() + + "\nComplete error stacktrace was written to " + PathManager.getLogPath() + "/idea.log"; + if (!myHeadlessMode) { + JOptionPane.showMessageDialog(null, errorMessage); + } + else { + //noinspection UseOfSystemOutOrSystemErr + System.out.println(errorMessage); + } } + super.handleInitComponentError(ex, fatal, componentClassName); + } + finally { + myHandlingInitComponentError = false; } - super.handleInitComponentError(ex, fatal, componentClassName); } private void loadApplicationComponents() { From 45ffe2182db265f939d8216ea202ed3d6bb621c2 Mon Sep 17 00:00:00 2001 From: Dmitry Jemerov Date: Thu, 8 Dec 2011 19:02:50 +0100 Subject: [PATCH 30/62] PY-5260 --- .../application/options/InitialConfigurationDialog.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/application/options/InitialConfigurationDialog.java b/platform/lang-impl/src/com/intellij/application/options/InitialConfigurationDialog.java index a3b4ba723c13..4108a31888d0 100644 --- a/platform/lang-impl/src/com/intellij/application/options/InitialConfigurationDialog.java +++ b/platform/lang-impl/src/com/intellij/application/options/InitialConfigurationDialog.java @@ -228,7 +228,9 @@ public class InitialConfigurationDialog extends DialogWrapper { @Override public void dispose() { - myPreviewEditor.disposeUIResources(); + if (myPreviewEditor != null) { + myPreviewEditor.disposeUIResources(); + } myPreviewOptions.disposeUIResources(); } @@ -282,7 +284,9 @@ public class InitialConfigurationDialog extends DialogWrapper { super.doOKAction(); - myPreviewEditor.disposeUIResources(); + if (myPreviewEditor != null) { + myPreviewEditor.disposeUIResources(); + } myPreviewOptions.disposeUIResources(); // set keymap ((KeymapManagerImpl)KeymapManager.getInstance()).setActiveKeymap((Keymap)myKeymapComboBox.getSelectedItem()); From 9b945405537378fd2d75d07effa8bbe460376420 Mon Sep 17 00:00:00 2001 From: Alexander Kirillin Date: Thu, 8 Dec 2011 21:49:23 +0300 Subject: [PATCH 31/62] add/delete elements refactoring --- .../introduce/inplace/AbstractInplaceIntroducer.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/platform/lang-impl/src/com/intellij/refactoring/introduce/inplace/AbstractInplaceIntroducer.java b/platform/lang-impl/src/com/intellij/refactoring/introduce/inplace/AbstractInplaceIntroducer.java index 4d145a50c43d..ab4f8908dcc3 100644 --- a/platform/lang-impl/src/com/intellij/refactoring/introduce/inplace/AbstractInplaceIntroducer.java +++ b/platform/lang-impl/src/com/intellij/refactoring/introduce/inplace/AbstractInplaceIntroducer.java @@ -417,6 +417,11 @@ public abstract class AbstractInplaceIntroducer Date: Thu, 8 Dec 2011 19:08:52 +0100 Subject: [PATCH 32/62] fix NotNull assertion --- .../debugger/settings/CompoundRendererConfigurable.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/java/debugger/impl/src/com/intellij/debugger/settings/CompoundRendererConfigurable.java b/java/debugger/impl/src/com/intellij/debugger/settings/CompoundRendererConfigurable.java index f068f11df306..4a08f8867bc6 100644 --- a/java/debugger/impl/src/com/intellij/debugger/settings/CompoundRendererConfigurable.java +++ b/java/debugger/impl/src/com/intellij/debugger/settings/CompoundRendererConfigurable.java @@ -176,7 +176,8 @@ public class CompoundRendererConfigurable implements UnnamedConfigurable{ private void updateContext(final String qName) { ApplicationManager.getApplication().runReadAction(new Runnable() { public void run() { - final PsiClass psiClass = DebuggerUtils.findClass(qName, myProject, GlobalSearchScope.allScope(myProject)); + final Project project = myProject; + final PsiClass psiClass = project != null? DebuggerUtils.findClass(qName, project, GlobalSearchScope.allScope(project)) : null; myLabelEditor.setContext(psiClass); myChildrenEditor.setContext(psiClass); myChildrenExpandedEditor.setContext(psiClass); From e92760e076870083a7c00ac828844b13815c097d Mon Sep 17 00:00:00 2001 From: Dmitry Jemerov Date: Thu, 8 Dec 2011 21:01:54 +0100 Subject: [PATCH 33/62] PY-5260 take 2 --- .../application/options/InitialConfigurationDialog.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/platform/lang-impl/src/com/intellij/application/options/InitialConfigurationDialog.java b/platform/lang-impl/src/com/intellij/application/options/InitialConfigurationDialog.java index 4108a31888d0..e7816ffcbc94 100644 --- a/platform/lang-impl/src/com/intellij/application/options/InitialConfigurationDialog.java +++ b/platform/lang-impl/src/com/intellij/application/options/InitialConfigurationDialog.java @@ -287,7 +287,9 @@ public class InitialConfigurationDialog extends DialogWrapper { if (myPreviewEditor != null) { myPreviewEditor.disposeUIResources(); } - myPreviewOptions.disposeUIResources(); + if (myPreviewOptions != null) { + myPreviewOptions.disposeUIResources(); + } // set keymap ((KeymapManagerImpl)KeymapManager.getInstance()).setActiveKeymap((Keymap)myKeymapComboBox.getSelectedItem()); // set color scheme From e0ba52f4503df8269ef31c8503f106168d892f4b Mon Sep 17 00:00:00 2001 From: anna Date: Thu, 8 Dec 2011 21:16:02 +0100 Subject: [PATCH 34/62] commit document after modifications in a command! --- .../refactoring/rename/inplace/VariableInplaceRenamer.java | 1 + 1 file changed, 1 insertion(+) diff --git a/platform/lang-impl/src/com/intellij/refactoring/rename/inplace/VariableInplaceRenamer.java b/platform/lang-impl/src/com/intellij/refactoring/rename/inplace/VariableInplaceRenamer.java index 257eab81c3c4..15c1267fd004 100644 --- a/platform/lang-impl/src/com/intellij/refactoring/rename/inplace/VariableInplaceRenamer.java +++ b/platform/lang-impl/src/com/intellij/refactoring/rename/inplace/VariableInplaceRenamer.java @@ -669,6 +669,7 @@ public class VariableInplaceRenamer { }); } }, RENAME_TITLE, null); + PsiDocumentManager.getInstance(myProject).commitDocument(myEditor.getDocument()); } private static VirtualFile getTopLevelVirtualFile(final FileViewProvider fileViewProvider) { From c2780c731fc841a30168ee52d854b9de7b47c264 Mon Sep 17 00:00:00 2001 From: anna Date: Thu, 8 Dec 2011 21:34:44 +0100 Subject: [PATCH 35/62] tets --- .../plugins/groovy/refactoring/copy/GroovyCopyClassTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/copy/GroovyCopyClassTest.java b/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/copy/GroovyCopyClassTest.java index f02f6534306a..cc774f8591cb 100644 --- a/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/copy/GroovyCopyClassTest.java +++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/copy/GroovyCopyClassTest.java @@ -59,7 +59,7 @@ public class GroovyCopyClassTest extends LightCodeInsightFixtureTestCase { myFixture.copyFileToProject(testName + ".groovy", "/foo/" + testName + ".groovy"); //would be copied as file - assertTrue( + assertFalse( CopyClassesHandler.canCopyClass(myFixture.getJavaFacade().findClass("foo." + testName, GlobalSearchScope.allScope(getProject())))); } From 38832551eb6ab13dac02020354d80ff0d38823dc Mon Sep 17 00:00:00 2001 From: Konstantin Bulenkov Date: Thu, 8 Dec 2011 22:02:51 +0100 Subject: [PATCH 36/62] fix wrong maximization under Alloy LaF --- .../src/com/intellij/openapi/ui/FrameWrapper.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/platform/platform-impl/src/com/intellij/openapi/ui/FrameWrapper.java b/platform/platform-impl/src/com/intellij/openapi/ui/FrameWrapper.java index 67f5ec6b52f5..f45e1bcd8aa2 100644 --- a/platform/platform-impl/src/com/intellij/openapi/ui/FrameWrapper.java +++ b/platform/platform-impl/src/com/intellij/openapi/ui/FrameWrapper.java @@ -152,6 +152,11 @@ public class FrameWrapper implements Disposable, DataProvider { myFocusWatcher.install(myComponent); myShown = true; frame.setVisible(true); + + if (UIUtil.isUnderAlloyLookAndFeel()) { + //please ask [kb] before remove it + frame.setMaximizedBounds(null); + } } public void close() { From de1a11f92fc30e031425d7cb50080f2ff69c4244 Mon Sep 17 00:00:00 2001 From: irengrig Date: Fri, 9 Dec 2011 13:50:44 +0400 Subject: [PATCH 37/62] IDEA-53015 Ask for subversion credentials right away! --- .../openapi/vcs/impl/GenericNotifierImpl.java | 14 +++++++-- .../idea/svn17/SvnAuthenticationNotifier.java | 4 +-- .../idea/svn/SvnAuthenticationNotifier.java | 30 +++++++++++++++---- .../jetbrains/idea/svn/SvnConfiguration.java | 2 +- .../dialogs/SvnAuthenticationProvider.java | 10 +++++-- .../idea/svn/SvnAuthenticationTest.java | 3 +- 6 files changed, 50 insertions(+), 13 deletions(-) diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/GenericNotifierImpl.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/GenericNotifierImpl.java index f8defdf183f0..1eb2f2347d47 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/GenericNotifierImpl.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/GenericNotifierImpl.java @@ -107,17 +107,27 @@ public abstract class GenericNotifierImpl { } } - public void ensureNotify(final T obj) { + public boolean ensureNotify(final T obj) { final MyNotification notification; synchronized (myLock) { final Key key = getKey(obj); if (myState.containsKey(key)) { - return; + return false; } notification = new MyNotification(myGroupId, myTitle, getNotificationContent(obj), myType, myListener, obj, getToString(obj)); myState.put(key, notification); } + final boolean state = onFirstNotification(obj); + if (state) { + removeLazyNotification(obj); + return true; + } Notifications.Bus.notify(notification, myProject); + return false; + } + + protected boolean onFirstNotification(T obj) { + return false; } public void removeLazyNotificationByKey(final Key key) { diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn17/SvnAuthenticationNotifier.java b/plugins/svn4idea/src/org/jetbrains/idea/svn17/SvnAuthenticationNotifier.java index b52507b49238..95edf056f9f5 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn17/SvnAuthenticationNotifier.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn17/SvnAuthenticationNotifier.java @@ -156,12 +156,12 @@ public class SvnAuthenticationNotifier extends GenericNotifierImpl resultRef = new Ref(); - ApplicationManager.getApplication().executeOnPooledThread(new Runnable() { + final Runnable checker = new Runnable() { @Override public void run() { try { @@ -106,11 +108,20 @@ public class SvnAuthenticationNotifier extends GenericNotifierImpl { myAuthManager = new SvnAuthenticationManager(myProject, new File(getConfigurationDirectory())); getInteractiveManager(svnVcs); // to init - myAuthManager.setAuthenticationProvider(new SvnAuthenticationProvider(svnVcs, myInteractiveProvider)); + myAuthManager.setAuthenticationProvider(new SvnAuthenticationProvider(svnVcs, myInteractiveProvider, RUNTIME_AUTH_CACHE)); myAuthManager.setRuntimeStorage(RUNTIME_AUTH_CACHE); } return myAuthManager; diff --git a/plugins/svn4ideaOld/src/org/jetbrains/idea/svn/dialogs/SvnAuthenticationProvider.java b/plugins/svn4ideaOld/src/org/jetbrains/idea/svn/dialogs/SvnAuthenticationProvider.java index 23081a7edbb0..a46d4b5bc400 100644 --- a/plugins/svn4ideaOld/src/org/jetbrains/idea/svn/dialogs/SvnAuthenticationProvider.java +++ b/plugins/svn4ideaOld/src/org/jetbrains/idea/svn/dialogs/SvnAuthenticationProvider.java @@ -27,6 +27,7 @@ import org.tmatesoft.svn.core.auth.ISVNAuthenticationManager; import org.tmatesoft.svn.core.auth.ISVNAuthenticationProvider; import org.tmatesoft.svn.core.auth.SVNAuthentication; import org.tmatesoft.svn.core.auth.SVNUserNameAuthentication; +import org.tmatesoft.svn.core.internal.wc.ISVNAuthenticationStorage; /** * @author alex @@ -36,8 +37,11 @@ public class SvnAuthenticationProvider implements ISVNAuthenticationProvider { private final Project myProject; private final SvnAuthenticationNotifier myAuthenticationNotifier; private final ISVNAuthenticationProvider mySvnInteractiveAuthenticationProvider; + private final ISVNAuthenticationStorage myAuthenticationStorage; - public SvnAuthenticationProvider(final SvnVcs svnVcs, final ISVNAuthenticationProvider provider) { + public SvnAuthenticationProvider(final SvnVcs svnVcs, final ISVNAuthenticationProvider provider, + final ISVNAuthenticationStorage authenticationStorage) { + myAuthenticationStorage = authenticationStorage; myProject = svnVcs.getProject(); myAuthenticationNotifier = svnVcs.getAuthNotifier(); mySvnInteractiveAuthenticationProvider = provider; @@ -64,7 +68,9 @@ public class SvnAuthenticationProvider implements ISVNAuthenticationProvider { // outside-project url return mySvnInteractiveAuthenticationProvider.requestClientAuthentication(kind, url, realm, errorMessage, previousAuth, authMayBeStored); } else { - myAuthenticationNotifier.ensureNotify(obj); + if (myAuthenticationNotifier.ensureNotify(obj)) { + return (SVNAuthentication) myAuthenticationStorage.getData(kind, realm); + } } return null; } diff --git a/plugins/svn4ideaOld/testSource/org/jetbrains/idea/svn/SvnAuthenticationTest.java b/plugins/svn4ideaOld/testSource/org/jetbrains/idea/svn/SvnAuthenticationTest.java index fb525e325f21..1fcbf1a4f0f8 100644 --- a/plugins/svn4ideaOld/testSource/org/jetbrains/idea/svn/SvnAuthenticationTest.java +++ b/plugins/svn4ideaOld/testSource/org/jetbrains/idea/svn/SvnAuthenticationTest.java @@ -80,7 +80,8 @@ public class SvnAuthenticationTest extends PlatformTestCase { myAuthenticationManager = new SvnAuthenticationManager(myProject, configFile); myInteractiveProvider = new SvnTestInteractiveAuthentication(myAuthenticationManager); - myAuthenticationManager.setAuthenticationProvider(new SvnAuthenticationProvider(vcs, myInteractiveProvider)); + myAuthenticationManager.setAuthenticationProvider(new SvnAuthenticationProvider(vcs, myInteractiveProvider, + SvnConfiguration.RUNTIME_AUTH_CACHE)); myAuthenticationManager.setRuntimeStorage(SvnConfiguration.RUNTIME_AUTH_CACHE); myTestInteraction = new TestInteraction(); From f86c2c15248e51195a0901b87a152c3e4a40d061 Mon Sep 17 00:00:00 2001 From: nik Date: Fri, 9 Dec 2011 14:03:14 +0400 Subject: [PATCH 38/62] IDEA-77092: Non-standard border for modules and libraries lists --- .../intellij/ide/util/importProject/ProjectLayoutPanel.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/java/idea-ui/src/com/intellij/ide/util/importProject/ProjectLayoutPanel.java b/java/idea-ui/src/com/intellij/ide/util/importProject/ProjectLayoutPanel.java index be7e9fec14a4..503bdc2287f5 100644 --- a/java/idea-ui/src/com/intellij/ide/util/importProject/ProjectLayoutPanel.java +++ b/java/idea-ui/src/com/intellij/ide/util/importProject/ProjectLayoutPanel.java @@ -81,9 +81,8 @@ abstract class ProjectLayoutPanel extends JPanel { final Splitter splitter = new Splitter(false); - final JScrollPane entriesPane = ScrollPaneFactory.createScrollPane(myEntriesChooser); final JPanel entriesPanel = new JPanel(new BorderLayout()); - entriesPanel.add(entriesPane, BorderLayout.CENTER); + entriesPanel.add(myEntriesChooser, BorderLayout.CENTER); entriesPanel.setBorder(IdeBorderFactory.createTitledBorder(StringUtil.capitalize(StringUtil.pluralize(getElementTypeName())), false, false, true)); splitter.setFirstComponent(entriesPanel); From 9e4ba252e1baebc261b614970708ad4c9159e37d Mon Sep 17 00:00:00 2001 From: Alexey Pegov Date: Fri, 9 Dec 2011 14:40:39 +0400 Subject: [PATCH 39/62] fix double shifting --- .../com/intellij/ui/EngravedTextGraphics.java | 42 ++++++++++++------- 1 file changed, 26 insertions(+), 16 deletions(-) diff --git a/platform/util/src/com/intellij/ui/EngravedTextGraphics.java b/platform/util/src/com/intellij/ui/EngravedTextGraphics.java index 94ee8c265c2e..a82bd87bf0c3 100644 --- a/platform/util/src/com/intellij/ui/EngravedTextGraphics.java +++ b/platform/util/src/com/intellij/ui/EngravedTextGraphics.java @@ -51,10 +51,13 @@ public class EngravedTextGraphics extends Graphics2DDelegate { public void drawChars(char[] data, int offset, int length, int x, int y) { if (ALLOW_ENGRAVEMENT) { final Color color = getColor(); - setColor(myShadowColor); - super.drawChars(data, offset, length, x + myXOffset, y + myYOffset); + + if (color != myShadowColor) { + setColor(myShadowColor); + super.drawChars(data, offset, length, x + myXOffset, y + myYOffset); - setColor(color); + setColor(color); + } } super.drawChars(data, offset, length, x, y); @@ -64,11 +67,12 @@ public class EngravedTextGraphics extends Graphics2DDelegate { public void drawString(String str, int x, int y) { if (ALLOW_ENGRAVEMENT) { final Color color = getColor(); + if (color != myShadowColor) { + setColor(myShadowColor); + super.drawString(str, x + myXOffset, y + myYOffset); - setColor(myShadowColor); - super.drawString(str, x + myXOffset, y + myYOffset); - - setColor(color); + setColor(color); + } } super.drawString(str, x, y); } @@ -78,10 +82,12 @@ public class EngravedTextGraphics extends Graphics2DDelegate { if (ALLOW_ENGRAVEMENT) { final Color color = getColor(); - setColor(myShadowColor); - super.drawString(iterator, x + myXOffset, y + myYOffset); + if (color != myShadowColor) { + setColor(myShadowColor); + super.drawString(iterator, x + myXOffset, y + myYOffset); - setColor(color); + setColor(color); + } } super.drawString(iterator, x, y); } @@ -91,10 +97,12 @@ public class EngravedTextGraphics extends Graphics2DDelegate { if (ALLOW_ENGRAVEMENT) { final Color color = getColor(); - setColor(myShadowColor); - super.drawString(iterator, x + myXOffset, y + myYOffset); + if (color != myShadowColor) { + setColor(myShadowColor); + super.drawString(iterator, x + myXOffset, y + myYOffset); - setColor(color); + setColor(color); + } } super.drawString(iterator, x, y); } @@ -104,10 +112,12 @@ public class EngravedTextGraphics extends Graphics2DDelegate { if (ALLOW_ENGRAVEMENT) { final Color color = getColor(); - setColor(myShadowColor); - super.drawString(s, x + myXOffset, y + myYOffset); + if (color != myShadowColor) { + setColor(myShadowColor); + super.drawString(s, x + myXOffset, y + myYOffset); - setColor(color); + setColor(color); + } } super.drawString(s, x, y); } From a8c4abdca59aa88f65c6584e1f0cc45d62dbb50d Mon Sep 17 00:00:00 2001 From: nik Date: Fri, 9 Dec 2011 15:15:09 +0400 Subject: [PATCH 40/62] form builder: fixed mnemonics and corrected indent for vertical=true --- .../src/com/intellij/util/ui/FormBuilder.java | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/platform/util/src/com/intellij/util/ui/FormBuilder.java b/platform/util/src/com/intellij/util/ui/FormBuilder.java index 33f0d68b71ef..540b3af3c6fc 100644 --- a/platform/util/src/com/intellij/util/ui/FormBuilder.java +++ b/platform/util/src/com/intellij/util/ui/FormBuilder.java @@ -51,21 +51,17 @@ public class FormBuilder { } public FormBuilder addLabeledComponent(String labelText, JComponent component, final int verticalSpace) { - JLabel label = null; - if (labelText != null) { - label = new JLabel(UIUtil.removeMnemonic(labelText)); - label.setDisplayedMnemonicIndex(UIUtil.getDisplayMnemonicIndex(labelText)); - label.setLabelFor(component); - } - - return addLabelAndValueComponents(label, component, verticalSpace, false, false); + return addLabeledComponent(labelText, component, verticalSpace, false); } public FormBuilder addLabeledComponent(String labelText, JComponent component, final int verticalSpace, boolean labelOnTop) { JLabel label = null; if (labelText != null) { label = new JLabel(UIUtil.removeMnemonic(labelText)); - label.setDisplayedMnemonicIndex(UIUtil.getDisplayMnemonicIndex(labelText)); + final int index = UIUtil.getDisplayMnemonicIndex(labelText); + if (index != -1) { + label.setDisplayedMnemonic(labelText.charAt(index+1)); + } label.setLabelFor(component); } @@ -104,7 +100,7 @@ public class FormBuilder { c.weightx = 1.0; c.fill = GridBagConstraints.NONE; c.anchor = GridBagConstraints.WEST; - c.insets = new Insets(verticalInset, 0, 0, this.indent); + c.insets = new Insets(verticalInset, 0, this.indent, 0); if (label != null) panel.add(label, c); From b7cf731b7e7eefd0503b0abb9042cbd84257f6ae Mon Sep 17 00:00:00 2001 From: nik Date: Fri, 9 Dec 2011 15:18:54 +0400 Subject: [PATCH 41/62] IDEA-77088: Split library dialog problems --- .../importProject/LibrariesLayoutPanel.java | 2 +- .../importProject/ModulesLayoutPanel.java | 2 +- .../importProject/ProjectLayoutPanel.java | 44 ++++++++++++------- 3 files changed, 30 insertions(+), 18 deletions(-) diff --git a/java/idea-ui/src/com/intellij/ide/util/importProject/LibrariesLayoutPanel.java b/java/idea-ui/src/com/intellij/ide/util/importProject/LibrariesLayoutPanel.java index 65d287d4e337..3f556fbc2788 100644 --- a/java/idea-ui/src/com/intellij/ide/util/importProject/LibrariesLayoutPanel.java +++ b/java/idea-ui/src/com/intellij/ide/util/importProject/LibrariesLayoutPanel.java @@ -84,7 +84,7 @@ public class LibrariesLayoutPanel extends ProjectLayoutPanel{ } protected String getSplitDialogChooseFilesPrompt() { - return "Select jars to extract to the new library:"; + return "&Select jars to extract to the new library:"; } protected String getNameAlreadyUsedMessage(final String name) { diff --git a/java/idea-ui/src/com/intellij/ide/util/importProject/ModulesLayoutPanel.java b/java/idea-ui/src/com/intellij/ide/util/importProject/ModulesLayoutPanel.java index b24fe9eabf72..c77a7e08c45c 100644 --- a/java/idea-ui/src/com/intellij/ide/util/importProject/ModulesLayoutPanel.java +++ b/java/idea-ui/src/com/intellij/ide/util/importProject/ModulesLayoutPanel.java @@ -100,7 +100,7 @@ public class ModulesLayoutPanel extends ProjectLayoutPanel{ } protected String getSplitDialogChooseFilesPrompt() { - return "Select content roots to extract to the new module:"; + return "&Select content roots to extract to the new module:"; } protected String getNameAlreadyUsedMessage(final String name) { diff --git a/java/idea-ui/src/com/intellij/ide/util/importProject/ProjectLayoutPanel.java b/java/idea-ui/src/com/intellij/ide/util/importProject/ProjectLayoutPanel.java index 503bdc2287f5..f1d7449494a7 100644 --- a/java/idea-ui/src/com/intellij/ide/util/importProject/ProjectLayoutPanel.java +++ b/java/idea-ui/src/com/intellij/ide/util/importProject/ProjectLayoutPanel.java @@ -25,15 +25,19 @@ import com.intellij.openapi.ui.Splitter; import com.intellij.openapi.ui.ex.MultiLineLabel; import com.intellij.openapi.util.IconLoader; import com.intellij.openapi.util.text.StringUtil; +import com.intellij.ui.DocumentAdapter; import com.intellij.ui.IdeBorderFactory; import com.intellij.ui.ScrollPaneFactory; import com.intellij.ui.components.JBList; import com.intellij.util.PlatformIcons; import com.intellij.util.StringBuilderSpinAllocator; +import com.intellij.util.containers.ContainerUtil; +import com.intellij.util.ui.FormBuilder; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.swing.*; +import javax.swing.event.DocumentEvent; import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionListener; import java.awt.*; @@ -482,7 +486,26 @@ abstract class ProjectLayoutPanel extends JPanel { } }); } + myChooser.selectElements(ContainerUtil.createMaybeSingletonList(ContainerUtil.getFirstItem(files))); + myChooser.addElementsMarkListener(new ElementsChooser.ElementsMarkListener() { + @Override + public void elementMarkChanged(File element, boolean isMarked) { + updateOkButton(); + } + }); + myNameField.getDocument().addDocumentListener(new DocumentAdapter() { + @Override + protected void textChanged(DocumentEvent e) { + updateOkButton(); + } + }); + init(); + updateOkButton(); + } + + private void updateOkButton() { + setOKActionEnabled(!getName().isEmpty() && !getChosenFiles().isEmpty()); } protected void doOKAction() { @@ -496,22 +519,11 @@ abstract class ProjectLayoutPanel extends JPanel { @Nullable protected JComponent createCenterPanel() { - final JPanel panel = new JPanel(new BorderLayout()); - - final JPanel labelNameField = new JPanel(new BorderLayout()); - labelNameField.add(new JLabel("Name:"), BorderLayout.NORTH); - labelNameField.add(myNameField, BorderLayout.CENTER); - labelNameField.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); - - final JPanel labelChooser = new JPanel(new BorderLayout()); - labelChooser.add(new JLabel(getSplitDialogChooseFilesPrompt()), BorderLayout.NORTH); - labelChooser.add(ScrollPaneFactory.createScrollPane(myChooser), BorderLayout.CENTER); - labelChooser.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); - - panel.add(labelNameField, BorderLayout.NORTH); - panel.add(labelChooser, BorderLayout.CENTER); - panel.setPreferredSize(new Dimension(450, 300)); - return panel; + FormBuilder builder = new FormBuilder(true); + builder.addLabeledComponent("&Name:", myNameField); + builder.addLabeledComponent(getSplitDialogChooseFilesPrompt(), myChooser); + myChooser.setPreferredSize(new Dimension(450, 300)); + return builder.getPanel(); } public JComponent getPreferredFocusedComponent() { From e486e97c77703fea0d5e9f623c674bab9f358991 Mon Sep 17 00:00:00 2001 From: anna Date: Fri, 9 Dec 2011 12:34:57 +0100 Subject: [PATCH 42/62] plugins: sort by status (IDEA-22992); restore selection --- .../plugins/AvailablePluginsManagerMain.java | 20 +------ .../plugins/InstalledPluginsManagerMain.java | 5 ++ .../plugins/InstalledPluginsTableModel.java | 60 +++++++++++++------ .../ide/plugins/PluginManagerColumnInfo.java | 2 +- .../plugins/PluginManagerConfigurable.java | 10 ++-- .../ide/plugins/PluginManagerMain.java | 27 +++++++-- .../ide/plugins/PluginManagerUISettings.java | 1 + 7 files changed, 79 insertions(+), 46 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/ide/plugins/AvailablePluginsManagerMain.java b/platform/platform-impl/src/com/intellij/ide/plugins/AvailablePluginsManagerMain.java index ffbc169b464f..4b9139ed5d51 100644 --- a/platform/platform-impl/src/com/intellij/ide/plugins/AvailablePluginsManagerMain.java +++ b/platform/platform-impl/src/com/intellij/ide/plugins/AvailablePluginsManagerMain.java @@ -21,7 +21,6 @@ import com.intellij.openapi.actionSystem.ex.ComboBoxAction; import com.intellij.openapi.options.ShowSettingsUtil; import com.intellij.openapi.project.DumbAware; import com.intellij.openapi.updateSettings.impl.UpdateSettings; -import com.intellij.openapi.util.IconLoader; import com.intellij.ui.ScrollPaneFactory; import com.intellij.util.net.HTTPProxySettingsDialog; import com.intellij.util.ui.update.UiNotifyConnector; @@ -105,7 +104,7 @@ public class AvailablePluginsManagerMain extends PluginManagerMain { actionGroup.add(new RefreshAction()); actionGroup.add(new ActionInstallPlugin(this, installed)); if (inToolbar) { - actionGroup.add(new SortByStatusAction()); + actionGroup.add(new SortByStatusAction("Sort installed first")); actionGroup.add(new MyFilterRepositoryAction()); actionGroup.add(new MyFilterCategoryAction()); } @@ -188,21 +187,4 @@ public class AvailablePluginsManagerMain extends PluginManagerMain { }; } } - - private class SortByStatusAction extends ToggleAction { - private SortByStatusAction() { - super("Sort installed first", "Sort installed first", IconLoader.getIcon("/objectBrowser/sortByType.png")); - } - - @Override - public boolean isSelected(AnActionEvent e) { - return pluginsModel.isSortByStatus(); - } - - @Override - public void setSelected(AnActionEvent e, boolean state) { - pluginsModel.setSortByStatus(state); - pluginsModel.sort(); - } - } } diff --git a/platform/platform-impl/src/com/intellij/ide/plugins/InstalledPluginsManagerMain.java b/platform/platform-impl/src/com/intellij/ide/plugins/InstalledPluginsManagerMain.java index 3bb9aebc9941..5abc980f9788 100644 --- a/platform/platform-impl/src/com/intellij/ide/plugins/InstalledPluginsManagerMain.java +++ b/platform/platform-impl/src/com/intellij/ide/plugins/InstalledPluginsManagerMain.java @@ -158,6 +158,7 @@ public class InstalledPluginsManagerMain extends PluginManagerMain { actionGroup.add(new ActionInstallPlugin(this, this)); actionGroup.add(new ActionUninstallPlugin(this, pluginTable)); if (inToolbar) { + actionGroup.add(new SortByStatusAction("Sort by status")); actionGroup.add(new MyFilterEnabledAction()); //actionGroup.add(new MyFilterBundleAction()); } @@ -256,8 +257,12 @@ public class InstalledPluginsManagerMain extends PluginManagerMain { gr.add(new AnAction(enabledValue) { @Override public void actionPerformed(AnActionEvent e) { + final IdeaPluginDescriptor[] selection = pluginTable.getSelectedObjects(); final String filter = myFilter.getFilter().toLowerCase(); ((InstalledPluginsTableModel)pluginsModel).setEnabledFilter(enabledValue, filter); + if (selection != null) { + select(selection); + } } }); } diff --git a/platform/platform-impl/src/com/intellij/ide/plugins/InstalledPluginsTableModel.java b/platform/platform-impl/src/com/intellij/ide/plugins/InstalledPluginsTableModel.java index e4eb8a3ccf27..4b57faa754d6 100644 --- a/platform/platform-impl/src/com/intellij/ide/plugins/InstalledPluginsTableModel.java +++ b/platform/platform-impl/src/com/intellij/ide/plugins/InstalledPluginsTableModel.java @@ -609,25 +609,49 @@ public class InstalledPluginsTableModel extends PluginTableModel { return true; } - /*@Override + @Override public Comparator getComparator() { - final Comparator comparator = super.getComparator(); - return new Comparator() { - @Override - public int compare(IdeaPluginDescriptor o1, IdeaPluginDescriptor o2) { - if (o1.isBundled() && o2.isBundled()) return comparator.compare(o1, o2); - if (o1.isBundled()) return -1; - if (o2.isBundled()) return 1; - final String host1 = myPlugin2host.get(o1.getPluginId().getIdString()); - final String host2 = myPlugin2host.get(o2.getPluginId().getIdString()); - if (host1 == null && host2 == null) return comparator.compare(o1, o2); - if (host1 == null) return 1; - if (host2 == null) return -1; - if (host1.equals(host2)) return comparator.compare(o1, o2); - return host1.compareToIgnoreCase(host2); - } - }; + final Comparator comparator = super.getColumnComparator(); + return new Comparator() { + @Override + public int compare(IdeaPluginDescriptor o1, IdeaPluginDescriptor o2) { + if (isSortByStatus()) { + final boolean hasNewerVersion1 = hasNewerVersion(o1.getPluginId()); + final boolean hasNewerVersion2 = hasNewerVersion(o2.getPluginId()); + if (hasNewerVersion1) { + if (hasNewerVersion2) return comparator.compare(o1, o2); + return -1; + } + if (hasNewerVersion2) return 1; - }*/ + + final boolean wasUpdated1 = wasUpdated(o1.getPluginId()); + final boolean wasUpdated2 = wasUpdated(o2.getPluginId()); + if (wasUpdated1) { + if (wasUpdated2) return comparator.compare(o1, o2); + return -1; + } + if (wasUpdated2) return 1; + + + if (o1 instanceof PluginNode) { + if (o2 instanceof PluginNode) return comparator.compare(o1, o2); + return -1; + } + if (o2 instanceof PluginNode) return 1; + + + final boolean deleted1 = o1 instanceof IdeaPluginDescriptorImpl && ((IdeaPluginDescriptorImpl)o1).isDeleted(); + final boolean deleted2 = o2 instanceof IdeaPluginDescriptorImpl && ((IdeaPluginDescriptorImpl)o2).isDeleted(); + if (deleted1) { + if (deleted2) return comparator.compare(o1, o2); + return -1; + } + if (deleted2) return 1; + } + return comparator.compare(o1, o2); + } + }; + } } } diff --git a/platform/platform-impl/src/com/intellij/ide/plugins/PluginManagerColumnInfo.java b/platform/platform-impl/src/com/intellij/ide/plugins/PluginManagerColumnInfo.java index cdf73b4a1bd5..3f2c2566c9cf 100644 --- a/platform/platform-impl/src/com/intellij/ide/plugins/PluginManagerColumnInfo.java +++ b/platform/platform-impl/src/com/intellij/ide/plugins/PluginManagerColumnInfo.java @@ -165,7 +165,7 @@ class PluginManagerColumnInfo extends ColumnInfo { return comparator; } - private Comparator getColumnComparator() { + protected Comparator getColumnComparator() { if (isSortByName()) { return new Comparator() { public int compare(IdeaPluginDescriptor o1, IdeaPluginDescriptor o2) { diff --git a/platform/platform-impl/src/com/intellij/ide/plugins/PluginManagerConfigurable.java b/platform/platform-impl/src/com/intellij/ide/plugins/PluginManagerConfigurable.java index 6a8603b1876b..ccbb01a82fac 100644 --- a/platform/platform-impl/src/com/intellij/ide/plugins/PluginManagerConfigurable.java +++ b/platform/platform-impl/src/com/intellij/ide/plugins/PluginManagerConfigurable.java @@ -73,11 +73,11 @@ public class PluginManagerConfigurable extends BaseConfigurable implements Searc if (column >= 0) { myPluginManagerMain.pluginsModel.setSortKey(new RowSorter.SortKey(column, SortOrder.ASCENDING)); } - if (myUISettings.AVAILABLE_SORT_BY_STATUS) { - myPluginManagerMain.pluginsModel.setSortByStatus(true); - } - myPluginManagerMain.pluginsModel.sort(); + myPluginManagerMain.pluginsModel.setSortByStatus(myUISettings.AVAILABLE_SORT_BY_STATUS); + } else { + myPluginManagerMain.pluginsModel.setSortByStatus(myUISettings.INSTALLED_SORT_BY_STATUS); } + myPluginManagerMain.pluginsModel.sort(); getSplitterProportions().restoreSplitterProportions(myPluginManagerMain.getMainPanel()); } @@ -99,6 +99,8 @@ public class PluginManagerConfigurable extends BaseConfigurable implements Searc } } myUISettings.AVAILABLE_SORT_BY_STATUS = myPluginManagerMain.pluginsModel.isSortByStatus(); + } else { + myUISettings.INSTALLED_SORT_BY_STATUS = myPluginManagerMain.pluginsModel.isSortByStatus(); } Disposer.dispose(myPluginManagerMain); diff --git a/platform/platform-impl/src/com/intellij/ide/plugins/PluginManagerMain.java b/platform/platform-impl/src/com/intellij/ide/plugins/PluginManagerMain.java index b5039dbd36c0..2fcbe1aff3dc 100644 --- a/platform/platform-impl/src/com/intellij/ide/plugins/PluginManagerMain.java +++ b/platform/platform-impl/src/com/intellij/ide/plugins/PluginManagerMain.java @@ -21,10 +21,7 @@ import com.intellij.ide.IdeBundle; import com.intellij.ide.ui.search.SearchUtil; import com.intellij.ide.ui.search.SearchableOptionsRegistrar; import com.intellij.openapi.Disposable; -import com.intellij.openapi.actionSystem.ActionGroup; -import com.intellij.openapi.actionSystem.ActionManager; -import com.intellij.openapi.actionSystem.ActionToolbar; -import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.*; import com.intellij.openapi.application.PathManager; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.progress.ProgressManager; @@ -488,6 +485,28 @@ public abstract class PluginManagerMain implements Disposable { return false; } + protected class SortByStatusAction extends ToggleAction { + + protected SortByStatusAction(final String title) { + super(title, title, IconLoader.getIcon("/objectBrowser/sortByType.png")); + } + + @Override + public boolean isSelected(AnActionEvent e) { + return pluginsModel.isSortByStatus(); + } + + @Override + public void setSelected(AnActionEvent e, boolean state) { + IdeaPluginDescriptor[] selected = pluginTable.getSelectedObjects(); + pluginsModel.setSortByStatus(state); + pluginsModel.sort(); + if (selected != null) { + select(selected); + } + } + } + public class MyPluginsFilter extends FilterComponent { public MyPluginsFilter() { diff --git a/platform/platform-impl/src/com/intellij/ide/plugins/PluginManagerUISettings.java b/platform/platform-impl/src/com/intellij/ide/plugins/PluginManagerUISettings.java index 9fbd978a736a..0085d5301d7b 100644 --- a/platform/platform-impl/src/com/intellij/ide/plugins/PluginManagerUISettings.java +++ b/platform/platform-impl/src/com/intellij/ide/plugins/PluginManagerUISettings.java @@ -44,6 +44,7 @@ public class PluginManagerUISettings implements PersistentStateComponent Date: Fri, 9 Dec 2011 12:48:07 +0100 Subject: [PATCH 43/62] plugins: ensure selection exist during filtering (IDEA-57385) --- .../src/com/intellij/ide/plugins/PluginManagerMain.java | 1 + 1 file changed, 1 insertion(+) diff --git a/platform/platform-impl/src/com/intellij/ide/plugins/PluginManagerMain.java b/platform/platform-impl/src/com/intellij/ide/plugins/PluginManagerMain.java index 2fcbe1aff3dc..8891bb01c92c 100644 --- a/platform/platform-impl/src/com/intellij/ide/plugins/PluginManagerMain.java +++ b/platform/platform-impl/src/com/intellij/ide/plugins/PluginManagerMain.java @@ -515,6 +515,7 @@ public abstract class PluginManagerMain implements Disposable { public void filter() { pluginsModel.filter(getFilter().toLowerCase()); + TableUtil.ensureSelectionExists(getPluginTable()); } } From 0bebe511f7dc938d8a34862d7b3df313b16ccb10 Mon Sep 17 00:00:00 2001 From: Sergey Evdokimov Date: Fri, 9 Dec 2011 16:03:12 +0300 Subject: [PATCH 44/62] Revert wrong changes in DefaultPicoContainer. --- .../util/pico/DefaultPicoContainer.java | 107 +++++++----------- 1 file changed, 39 insertions(+), 68 deletions(-) diff --git a/platform/util/src/com/intellij/util/pico/DefaultPicoContainer.java b/platform/util/src/com/intellij/util/pico/DefaultPicoContainer.java index c7dc592bb474..842cd469f4a4 100644 --- a/platform/util/src/com/intellij/util/pico/DefaultPicoContainer.java +++ b/platform/util/src/com/intellij/util/pico/DefaultPicoContainer.java @@ -17,7 +17,6 @@ package com.intellij.util.pico; import com.intellij.util.ReflectionCache; import com.intellij.util.containers.ConcurrentHashMap; -import com.intellij.util.containers.FList; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.picocontainer.*; @@ -25,6 +24,7 @@ import org.picocontainer.defaults.*; import java.io.Serializable; import java.util.*; +import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.atomic.AtomicReference; public class DefaultPicoContainer implements MutablePicoContainer, Serializable { @@ -34,11 +34,11 @@ public class DefaultPicoContainer implements MutablePicoContainer, Serializable private final Set children = new HashSet(); private final Map componentKeyToAdapterCache = new ConcurrentHashMap(); - private final LinkedHashSetWrapper componentAdapters = new LinkedHashSetWrapper(); + private final AtomicReference> componentAdapters = new AtomicReference>(new LinkedHashSet()); // Keeps track of instantiation order. - private final LinkedHashSetWrapper orderedComponentAdapters = new LinkedHashSetWrapper(); + private final AtomicReference> orderedComponentAdapters = new AtomicReference>(new LinkedHashSet()); private final Map classNameToAdapter = new ConcurrentHashMap(); - private final AtomicReference> nonAssignableComponentAdapters = new AtomicReference>(FList.emptyList()); + private final CopyOnWriteArrayList nonAssignableComponentAdapters = new CopyOnWriteArrayList(); public DefaultPicoContainer(@NotNull ComponentAdapterFactory componentAdapterFactory, PicoContainer parent) { this.componentAdapterFactory = componentAdapterFactory; @@ -50,7 +50,7 @@ public class DefaultPicoContainer implements MutablePicoContainer, Serializable } public Collection getComponentAdapters() { - return componentAdapters.getImmutableSet(); + return Collections.unmodifiableCollection(componentAdapters.get()); } public Map getAssignablesCache() { @@ -59,7 +59,7 @@ public class DefaultPicoContainer implements MutablePicoContainer, Serializable public Collection getNonAssignableAdapters() { - return nonAssignableComponentAdapters.get().getReversedList(); + return nonAssignableComponentAdapters; } @Nullable @@ -141,34 +141,51 @@ public class DefaultPicoContainer implements MutablePicoContainer, Serializable classNameToAdapter.put(classKey, componentAdapter); } else { - do { - FList oldList = nonAssignableComponentAdapters.get(); - FList newList = oldList.prepend(componentAdapter); - if (nonAssignableComponentAdapters.compareAndSet(oldList, newList)) { - break; - } - } while (true); + nonAssignableComponentAdapters.add(componentAdapter); } - componentAdapters.add(componentAdapter); + addElement(componentAdapters, componentAdapter); componentKeyToAdapterCache.put(componentKey, componentAdapter); return componentAdapter; } + private static void addElement(AtomicReference> collectionHolder, T element) { + do { + LinkedHashSet oldCollection = collectionHolder.get(); + if (oldCollection.contains(element)) { + return; + } + + LinkedHashSet newCollection = new LinkedHashSet(oldCollection); + newCollection.add(element); + + if (collectionHolder.compareAndSet(oldCollection, newCollection)) break; + } while (true); + } + + private static void removeElement(AtomicReference> collectionHolder, T element) { + do { + LinkedHashSet oldCollection = collectionHolder.get(); + + LinkedHashSet newCollection = new LinkedHashSet(oldCollection); + newCollection.remove(element); + + if (collectionHolder.compareAndSet(oldCollection, newCollection)) break; + } while (true); + } + public ComponentAdapter unregisterComponent(Object componentKey) { ComponentAdapter adapter = componentKeyToAdapterCache.remove(componentKey); - componentAdapters.remove(adapter); - orderedComponentAdapters.remove(adapter); + removeElement(componentAdapters, adapter); + removeElement(orderedComponentAdapters, adapter); return adapter; } private void addOrderedComponentAdapter(ComponentAdapter componentAdapter) { - if (!orderedComponentAdapters.contains(componentAdapter)) { - orderedComponentAdapters.add(componentAdapter); - } + addElement(orderedComponentAdapters, componentAdapter); } public List getComponentInstances() throws PicoException { @@ -181,7 +198,7 @@ public class DefaultPicoContainer implements MutablePicoContainer, Serializable } Map adapterToInstanceMap = new HashMap(); - for (final ComponentAdapter componentAdapter : componentAdapters.getImmutableSet()) { + for (final ComponentAdapter componentAdapter : componentAdapters.get()) { if (ReflectionCache.isAssignable(componentType, componentAdapter.getComponentImplementation())) { Object componentInstance = getInstance(componentAdapter); adapterToInstanceMap.put(componentAdapter, componentInstance); @@ -193,7 +210,7 @@ public class DefaultPicoContainer implements MutablePicoContainer, Serializable } List result = new ArrayList(); - for (ComponentAdapter componentAdapter : orderedComponentAdapters.getImmutableSet()) { + for (ComponentAdapter componentAdapter : orderedComponentAdapters.get()) { final Object componentInstance = adapterToInstanceMap.get(componentAdapter); if (componentInstance != null) { // may be null in the case of the "implicit" adapter @@ -223,7 +240,7 @@ public class DefaultPicoContainer implements MutablePicoContainer, Serializable @Nullable private Object getInstance(ComponentAdapter componentAdapter) { - final boolean isLocal = componentAdapters.contains(componentAdapter); + final boolean isLocal = componentAdapters.get().contains(componentAdapter); if (isLocal) { return getLocalInstance(componentAdapter); @@ -342,50 +359,4 @@ public class DefaultPicoContainer implements MutablePicoContainer, Serializable public PicoContainer getParent() { return parent; } - - private static class LinkedHashSetWrapper { - - private volatile Set immutableSet; - - private final LinkedHashSet synchronizedSet = new LinkedHashSet(); - - private final ConcurrentHashMap concurrentSet = new ConcurrentHashMap(); - - public boolean contains(@Nullable T element) { - return element != null && concurrentSet.containsKey(element); - } - - public void add(@NotNull T element) { - synchronized (synchronizedSet) { - immutableSet = null; - synchronizedSet.add(element); - concurrentSet.put(element, element); - } - } - - public void remove(@Nullable T element) { - if (element == null) return; - synchronized (synchronizedSet) { - immutableSet = null; - synchronizedSet.remove(element); - concurrentSet.remove(element); - } - } - - @NotNull - public Set getImmutableSet() { - Set res = immutableSet; - if (res == null) { - synchronized (synchronizedSet) { - res = immutableSet; - if (res == null) { - res = Collections.unmodifiableSet((Set)synchronizedSet.clone()); - immutableSet = res; - } - } - } - - return res; - } - } } \ No newline at end of file From 6b6a9ca09a69b9c8e286b59073acd46d785546ff Mon Sep 17 00:00:00 2001 From: Kirill Likhodedov Date: Wed, 7 Dec 2011 20:09:44 +0300 Subject: [PATCH 45/62] IDEA-78398 Git pull from URL If remote is given as an URL rather than as a remote name, don't look for a remote, just pull from that url. --- plugins/git4idea/src/git4idea/actions/GitPull.java | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/plugins/git4idea/src/git4idea/actions/GitPull.java b/plugins/git4idea/src/git4idea/actions/GitPull.java index 0b799e47c79c..98304bc1a462 100644 --- a/plugins/git4idea/src/git4idea/actions/GitPull.java +++ b/plugins/git4idea/src/git4idea/actions/GitPull.java @@ -73,12 +73,11 @@ public class GitPull extends GitRepositoryAction { public void run(@NotNull ProgressIndicator indicator) { GitRepository repository = GitRepositoryManager.getInstance(project).getRepositoryForRoot(dialog.gitRoot()); assert repository != null : "Repository can't be null for root " + dialog.gitRoot(); - String remoteName = dialog.getRemote(); - GitRemote remote = GitUtil.findRemoteByName(repository, remoteName); - if (remote == null) { - return; - } - String url = remote.getFirstUrl(); + String remoteOrUrl = dialog.getRemote(); + + + GitRemote remote = GitUtil.findRemoteByName(repository, remoteOrUrl); + String url = (remote == null) ? remoteOrUrl : remote.getFirstUrl(); if (url == null) { return; } From 22b31b249ebbf77daf18b54dd002690f5ba457af Mon Sep 17 00:00:00 2001 From: Kirill Likhodedov Date: Thu, 8 Dec 2011 16:35:30 +0300 Subject: [PATCH 46/62] IDEA-78458 Patch ini4j to let comment be on the same line as section header --- ...e_on_the_same_line_as_section_header.patch | 39 ++++++++++++++++++ .../lib/ini4j/ini4j-0.5.2-patched-sources.zip | Bin 65715 -> 65840 bytes .../lib/ini4j/ini4j-0.5.2-patched.jar | Bin 102450 -> 105423 bytes 3 files changed, 39 insertions(+) create mode 100644 plugins/git4idea/lib/ini4j/0002-Let_comment_be_on_the_same_line_as_section_header.patch diff --git a/plugins/git4idea/lib/ini4j/0002-Let_comment_be_on_the_same_line_as_section_header.patch b/plugins/git4idea/lib/ini4j/0002-Let_comment_be_on_the_same_line_as_section_header.patch new file mode 100644 index 000000000000..3920b1ba0453 --- /dev/null +++ b/plugins/git4idea/lib/ini4j/0002-Let_comment_be_on_the_same_line_as_section_header.patch @@ -0,0 +1,39 @@ +Index: src/main/java/org/ini4j/spi/IniParser.java +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>x-MacCyrillic +=================================================================== +--- src/main/java/org/ini4j/spi/IniParser.java (date 1319206062000) ++++ src/main/java/org/ini4j/spi/IniParser.java (revision ) +@@ -114,10 +114,19 @@ + { + String sectionName; + +- if (line.charAt(line.length() - 1) != SECTION_END) ++ if (line.charAt(line.length() - 1) != SECTION_END) + { ++ int sectionEnd = line.lastIndexOf(SECTION_END); ++ String afterSectionEnd = line.substring(sectionEnd + 1).trim(); ++ if (afterSectionEnd.isEmpty() || isComment(afterSectionEnd.charAt(0))) ++ { ++ line = line.substring(0, sectionEnd + 1); ++ } ++ else ++ { + parseError(line, source.getLineNumber()); +- } ++ } ++ } + + sectionName = unescapeFilter(line.substring(1, line.length() - 1).trim()); + if ((sectionName.length() == 0) && !getConfig().isUnnamedSection()) +@@ -133,5 +142,9 @@ + handler.startSection(sectionName); + + return sectionName; ++ } ++ ++ private boolean isComment(char c) { ++ return COMMENTS.indexOf(c) >= 0; + } + } diff --git a/plugins/git4idea/lib/ini4j/ini4j-0.5.2-patched-sources.zip b/plugins/git4idea/lib/ini4j/ini4j-0.5.2-patched-sources.zip index 253722c7abbd945c2cd40488516250b9e6f00e37..46cf85f7a36692113b16c567dc30c059fd20b773 100644 GIT binary patch delta 2039 zcmZ9Nc|6qlAIE15CUTCe9R@kZncOLAT_aZ%NYox_aUx&JpSi z!K`CH%0htf z`$IFZHyijF+)=kg9{e#bWhgKdL23ozOl1@}zph4tOXzUy&y8i8*LZm#ka-bcjI2WZ zvB8foBKjx<%Dn-FK)A&r5XgwzrJzYek;LyW-^7|~M7+qAoP3AGC$Wsk7ss?TZ(vRd zz)lPq8mD2^dK_MTYWbpiNmrR^NAaPT!+X(Rns=I6Qyynxrtd6hBbLbc<*a14ii#Ow zHVe+KziYu>H$K3nq9<;)niG5UkY@dg>Sni81)LG{eJcX9D(ZS@qql1gj3M3x>PXap zejB;#`0;xBy=0TJREDm5Z6Q|^AE7!aHvTb#8F#p6hkmQI3Vwe~i&_b!SAiSv1Z(%uu=tUVt{ z;$TXK&nz4!xHfd{ZOPS>v#j8Aat>1aMoCN=E9w%dg?+<$H-hKgl1lV~<4L%wj^DAA z>E})wrbYG@fE9+g%4I7p?ppdhkED;+kSx`2?(Z&Y_57vkW91Pib+Lja-@XUl&wX$O z+8Au@hanQIpGt zD+9rJ8do@gw=+ST5U<~&eUC1xF}1PH?Vm12;AdJ{*cjs2x=nzAo8|^uK}n~*ME@Gj z!1S1yJ!OCiSD-3mwTKiKKI)`y86}{W@Yn|!x@hcRU!u1}Kao8QHEWK@O@wj)HMH$6dKgWiN1%-b822%7V}Kf3APr>`e} z=39_pHjZ`{H*q$c9+BdHwrL`av?=S{>?+-PPm2BLhzCVBQ%EHv#D$R)b644G{(-;( z!7}K&M(6!kIX%IO8W_Jpv#!uRnKa()d;2FSYrzJDjkJP4lNlW-m8wRJ+O?MX5S3w#FALs|`%%w5Vix)y-BDYQ+`GHx1vuWX=mJhX*M0R>lsq3kmxA zTcQIb^QPrJKHyi11;?R3QsP0c^=+60oz<*q8uVHPx&;XStqEXgvHdqtN$)BG6_xkH za894S;Y<)RC-cA@#p!JD6{%zCfXd?EkHD(rC87Z5&EVe9g&n#z09}`-dTjV}|JTt6 zwhjIt2UK>DT+&ovZd(lKqX+_B2WTK|2MNn>fB>RRlEB*?2Utkc4@Ltf+i1XJ7YW1C z!C2<51MEpF$m_coV8=Tk0HYlRc<-4)>A_0Naz G4dj2!%Fyco delta 1933 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 delta 10108 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 PC;a*iM&`jH1b_M;VEO@+ From a849ad2b22b318a6694287bbad4ac66e7687118d Mon Sep 17 00:00:00 2001 From: Kirill Likhodedov Date: Thu, 8 Dec 2011 16:57:14 +0300 Subject: [PATCH 47/62] IDEA-78516 EA-32502 Allow [branch] sections (for common branch options) in .git/config --- plugins/git4idea/src/git4idea/repo/GitConfig.java | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/plugins/git4idea/src/git4idea/repo/GitConfig.java b/plugins/git4idea/src/git4idea/repo/GitConfig.java index e106bc5ef83d..a1165a955bc5 100644 --- a/plugins/git4idea/src/git4idea/repo/GitConfig.java +++ b/plugins/git4idea/src/git4idea/repo/GitConfig.java @@ -53,7 +53,8 @@ class GitConfig { private static final Pattern REMOTE_SECTION = Pattern.compile("remote \"(.*)\""); private static final Pattern URL_SECTION = Pattern.compile("url \"(.*)\""); - private static final Pattern BRANCH_SECTION = Pattern.compile("branch \"(.*)\""); + private static final Pattern BRANCH_INFO_SECTION = Pattern.compile("branch \"(.*)\""); + private static final Pattern BRANCH_COMMON_PARAMS_SECTION = Pattern.compile("branch"); private final Collection myRemotes; private final Collection myBranchTrackInfos; @@ -156,7 +157,7 @@ class GitConfig { return null; } boolean merge = mergeName != null; - String remoteBranch = (merge ? mergeName : rebaseName); + final String remoteBranch = (merge ? mergeName : rebaseName); GitRemote branchRemote = null; for (GitRemote remote : remotes) { @@ -170,17 +171,22 @@ class GitConfig { return null; } + assert remoteBranch != null; // this is checked in StringUtil.isEmptyOrSpaces return new GitBranchTrackInfo(branchName, branchRemote, remoteBranch, merge); } @Nullable private static BranchConfig parseBranchSection(String sectionName, Profile.Section section, ClassLoader classLoader) { BranchBean branchBean = section.as(BranchBean.class, classLoader); - Matcher matcher = BRANCH_SECTION.matcher(sectionName); + Matcher matcher = BRANCH_INFO_SECTION.matcher(sectionName); if (matcher.matches()) { return new BranchConfig(matcher.group(1), branchBean); } - LOG.error(String.format("Invalid branch section format in .git/config. sectionName: %s section: %s", sectionName, section)); + if (BRANCH_COMMON_PARAMS_SECTION.matcher(sectionName).matches()) { + LOG.debug(String.format("Common branch option(s) defined .git/config. sectionName: %s%n section: %s", sectionName, section)); + return null; + } + LOG.error(String.format("Invalid branch section format in .git/config. sectionName: %s%n section: %s", sectionName, section)); return null; } From 167db4740393d44a69f554023abe0daf2188cd45 Mon Sep 17 00:00:00 2001 From: Kirill Likhodedov Date: Thu, 8 Dec 2011 18:49:22 +0300 Subject: [PATCH 48/62] GitConfig: don't throw RuntimeException in case of parse error, LOG the error instead. --- plugins/git4idea/src/git4idea/repo/GitConfig.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/plugins/git4idea/src/git4idea/repo/GitConfig.java b/plugins/git4idea/src/git4idea/repo/GitConfig.java index a1165a955bc5..830233ff0f76 100644 --- a/plugins/git4idea/src/git4idea/repo/GitConfig.java +++ b/plugins/git4idea/src/git4idea/repo/GitConfig.java @@ -110,7 +110,8 @@ class GitConfig { ini.load(configFile); } catch (IOException e) { - throw new GitRepoStateException("Couldn't load .git/config file at " + configFile.getPath(), e); + LOG.error(new GitRepoStateException("Couldn't load .git/config file at " + configFile.getPath(), e)); + return new GitConfig(Collections.emptyList(), Collections.emptyList()); } IdeaPluginDescriptor plugin = PluginManager.getPlugin(PluginManager.getPluginByClassName(GitConfig.class.getName())); From 3df2e8c1fe7e1883da301c0df9f857a3af8a255a Mon Sep 17 00:00:00 2001 From: Kirill Likhodedov Date: Thu, 8 Dec 2011 20:17:18 +0300 Subject: [PATCH 49/62] IDEA-78087 Log (in VCS console and logger) fetch, push and clone made by http. Log in the finally block to log just once (in case of several auth attempts or exceptions that IDEA handles and retries) - after success or after total fail. --- .../src/git4idea/jgit/GitHttpAdapter.java | 19 ++++++-- .../git4idea/jgit/GitHttpRemoteCommand.java | 47 ++++++++++++++++++- 2 files changed, 60 insertions(+), 6 deletions(-) diff --git a/plugins/git4idea/src/git4idea/jgit/GitHttpAdapter.java b/plugins/git4idea/src/git4idea/jgit/GitHttpAdapter.java index 4d8c40d18cd6..35099745630d 100644 --- a/plugins/git4idea/src/git4idea/jgit/GitHttpAdapter.java +++ b/plugins/git4idea/src/git4idea/jgit/GitHttpAdapter.java @@ -22,6 +22,7 @@ import com.intellij.ide.passwordSafe.impl.PasswordSafeImpl; import com.intellij.ide.passwordSafe.impl.PasswordSafeProvider; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.project.Project; +import git4idea.GitVcs; import git4idea.push.GitSimplePushResult; import git4idea.remote.GitRememberedInputs; import git4idea.repo.GitRemote; @@ -83,7 +84,8 @@ public final class GitHttpAdapter { try { final Git git = convertToGit(repository); final GitHttpCredentialsProvider provider = new GitHttpCredentialsProvider(repository.getProject(), remoteUrl); - GeneralResult result = callWithAuthRetry(new GitHttpRemoteCommand.Fetch(git, provider, remoteUrl, convertRefSpecs(remote.getFetchRefSpecs()))); + GeneralResult result = callWithAuthRetry(new GitHttpRemoteCommand.Fetch(git, provider, remoteUrl, convertRefSpecs(remote.getFetchRefSpecs())), + repository.getProject()); resultType = convertToFetchResultType(result); } catch (IOException e) { logException(repository, remote.getName(), remoteUrl, e, "fetching"); @@ -128,7 +130,7 @@ public final class GitHttpAdapter { final Git git = convertToGit(repository); final GitHttpCredentialsProvider provider = new GitHttpCredentialsProvider(repository.getProject(), remoteUrl); GitHttpRemoteCommand.Push pushCommand = new GitHttpRemoteCommand.Push(git, provider, remote.getName(), remoteUrl, convertRefSpecs(Collections.singletonList(pushSpec))); - GeneralResult result = callWithAuthRetry(pushCommand); + GeneralResult result = callWithAuthRetry(pushCommand, repository.getProject()); GitSimplePushResult pushResult = pushCommand.getResult(); if (pushResult == null) { return convertToPushResultType(result); @@ -161,7 +163,7 @@ public final class GitHttpAdapter { GitFetchResult.Type resultType; try { final GitHttpCredentialsProvider provider = new GitHttpCredentialsProvider(project, url); - GeneralResult result = callWithAuthRetry(new GitHttpRemoteCommand.Clone(directory, provider, url)); + GeneralResult result = callWithAuthRetry(new GitHttpRemoteCommand.Clone(directory, provider, url), project); resultType = convertToFetchResultType(result); } catch (InvalidRemoteException e) { @@ -205,7 +207,7 @@ public final class GitHttpAdapter { * If user enters incorrect data, he has 2 more attempts to go before failure. * Cleanups are executed after each incorrect attempt to enter password, and after other retriable actions. */ - private static GeneralResult callWithAuthRetry(@NotNull GitHttpRemoteCommand command) throws InvalidRemoteException, IOException, URISyntaxException { + private static GeneralResult callWithAuthRetry(@NotNull GitHttpRemoteCommand command, @NotNull Project project) throws InvalidRemoteException, IOException, URISyntaxException { ProxySelector defaultProxySelector = ProxySelector.getDefault(); if (GitHttpProxySupport.shouldUseProxy()) { ProxySelector.setDefault(GitHttpProxySupport.newProxySelector()); @@ -271,10 +273,19 @@ public final class GitHttpAdapter { return GeneralResult.NOT_AUTHORIZED; } finally { + log(command, project); ProxySelector.setDefault(defaultProxySelector); } } + private static void log(@NotNull GitHttpRemoteCommand command, @NotNull Project project) { + GitVcs vcs = GitVcs.getInstance(project); + if (vcs != null) { + vcs.showCommandLine(command.getCommandString()); + } + LOG.info(command.getLogString()); + } + private static boolean smartHttpPushNotSupported(JGitInternalException e) { if (e.getCause() instanceof NotSupportedException) { NotSupportedException nse = (NotSupportedException)e.getCause(); diff --git a/plugins/git4idea/src/git4idea/jgit/GitHttpRemoteCommand.java b/plugins/git4idea/src/git4idea/jgit/GitHttpRemoteCommand.java index 5f67a781697f..7d4f58b219a1 100644 --- a/plugins/git4idea/src/git4idea/jgit/GitHttpRemoteCommand.java +++ b/plugins/git4idea/src/git4idea/jgit/GitHttpRemoteCommand.java @@ -16,6 +16,8 @@ package git4idea.jgit; import com.intellij.openapi.util.io.FileUtil; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.util.Function; import git4idea.push.GitSimplePushResult; import org.eclipse.jgit.JGitText; import org.eclipse.jgit.api.CloneCommand; @@ -52,6 +54,8 @@ interface GitHttpRemoteCommand { void run() throws InvalidRemoteException, URISyntaxException; void cleanup(); GitHttpCredentialsProvider getCredentialsProvider(); + String getLogString(); + String getCommandString(); class Fetch implements GitHttpRemoteCommand { @@ -60,7 +64,7 @@ interface GitHttpRemoteCommand { private String myUrl; private final List myRefSpecs; - Fetch(@NotNull Git git, @NotNull GitHttpCredentialsProvider credentialsProvider, String url, List refSpecs) { + Fetch(@NotNull Git git, @NotNull GitHttpCredentialsProvider credentialsProvider, @NotNull String url, @NotNull List refSpecs) { myGit = git; myCredentialsProvider = credentialsProvider; myUrl = url; @@ -91,6 +95,25 @@ interface GitHttpRemoteCommand { return myCredentialsProvider; } + @Override + public String getLogString() { + return getCommandString(); + } + + @Override + public String getCommandString() { + return String.format("git fetch %s %s", myUrl, getRefspecsAsString(myRefSpecs)); + } + + static String getRefspecsAsString(@NotNull List refSpecs) { + return StringUtil.join(refSpecs, new Function() { + @Override + public String fun(RefSpec spec) { + return spec.toString(); + } + }, ","); + } + @Override public void cleanup() { } @@ -132,6 +155,16 @@ interface GitHttpRemoteCommand { return myCredentialsProvider; } + @Override + public String getLogString() { + return getCommandString(); + } + + @Override + public String getCommandString() { + return String.format("git clone %s %s", myUrl, myTargetDirectory.getPath()); + } + @Override public void cleanup() { if (myTargetDirectory.exists()) { @@ -200,7 +233,17 @@ interface GitHttpRemoteCommand { public GitHttpCredentialsProvider getCredentialsProvider() { return myCredentialsProvider; } - + + @Override + public String getLogString() { + return String.format("git push %s (%s) %s", myRemoteName, myUrl, GitHttpRemoteCommand.Fetch.getRefspecsAsString(myPushSpecs)); + } + + @Override + public String getCommandString() { + return String.format("git push %s %s", myRemoteName, GitHttpRemoteCommand.Fetch.getRefspecsAsString(myPushSpecs)); + } + @Override public void cleanup() { } From fe9eb948d33877098ecd4269f8ce98292eddfe95 Mon Sep 17 00:00:00 2001 From: Kirill Likhodedov Date: Thu, 8 Dec 2011 21:00:56 +0300 Subject: [PATCH 50/62] IDEA-78542 Fix "no changes" message when branches are identical --- .../src/git4idea/process/GitBranchOperationsProcessor.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/git4idea/src/git4idea/process/GitBranchOperationsProcessor.java b/plugins/git4idea/src/git4idea/process/GitBranchOperationsProcessor.java index d0c695bc6be5..0c2dc295431d 100644 --- a/plugins/git4idea/src/git4idea/process/GitBranchOperationsProcessor.java +++ b/plugins/git4idea/src/git4idea/process/GitBranchOperationsProcessor.java @@ -453,7 +453,7 @@ public final class GitBranchOperationsProcessor { private void displayCompareDialog(List headToBranch, List branchToHead, String branchName) { if (headToBranch.isEmpty() && branchToHead.isEmpty()) { String currentBranch = GitBranchUiUtil.getBranchNameOrRev(myRepository); - Messages.showInfoMessage(myProject, String.format("There are no changes in the Git log between %s and %s", + Messages.showInfoMessage(myProject, String.format("There are no changes between %s and %s", currentBranch, branchName), "No Changes Detected"); } else { new GitCompareBranchesDialog(myRepository, branchName, headToBranch, branchToHead).show(); From 4b2474246b7ccb17194e61e8030a85d1695a05fa Mon Sep 17 00:00:00 2001 From: Kirill Likhodedov Date: Fri, 9 Dec 2011 13:24:20 +0300 Subject: [PATCH 51/62] IDEA-78537 Fix GitPullDialog -> get remote branches for HTTP 1. GitPullDialog: move getting remote branches to a separate method; if the remote has http url, query GitHttpAdapter. 2. GitHttpAdapter.lsRemote - standard http command call. After successful call, get remote references as strings without refs/heads/ prefix. In case of failure, return empty. 3. GitHttpRemoteCommand - a fixed copy of org.eclipse.jgit.api.LsRemoteCommand#call, which declares proper exceptions and uses CredentialsProvider. --- .../src/git4idea/jgit/GitHttpAdapter.java | 36 ++++++ .../git4idea/jgit/GitHttpRemoteCommand.java | 118 +++++++++++++++++- .../src/git4idea/merge/GitPullDialog.java | 59 ++++++--- 3 files changed, 194 insertions(+), 19 deletions(-) diff --git a/plugins/git4idea/src/git4idea/jgit/GitHttpAdapter.java b/plugins/git4idea/src/git4idea/jgit/GitHttpAdapter.java index 35099745630d..b3a356756735 100644 --- a/plugins/git4idea/src/git4idea/jgit/GitHttpAdapter.java +++ b/plugins/git4idea/src/git4idea/jgit/GitHttpAdapter.java @@ -22,6 +22,7 @@ import com.intellij.ide.passwordSafe.impl.PasswordSafeImpl; import com.intellij.ide.passwordSafe.impl.PasswordSafeProvider; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.project.Project; +import git4idea.GitBranch; import git4idea.GitVcs; import git4idea.push.GitSimplePushResult; import git4idea.remote.GitRememberedInputs; @@ -34,6 +35,7 @@ import org.eclipse.jgit.api.errors.JGitInternalException; import org.eclipse.jgit.errors.NoRemoteRepositoryException; import org.eclipse.jgit.errors.NotSupportedException; import org.eclipse.jgit.errors.TransportException; +import org.eclipse.jgit.lib.Ref; import org.eclipse.jgit.lib.Repository; import org.eclipse.jgit.storage.file.FileRepositoryBuilder; import org.eclipse.jgit.transport.RefSpec; @@ -45,6 +47,7 @@ import java.io.IOException; import java.net.ProxySelector; import java.net.URISyntaxException; import java.util.ArrayList; +import java.util.Collection; import java.util.Collections; import java.util.List; import java.util.regex.Pattern; @@ -158,6 +161,39 @@ public final class GitHttpAdapter { } } + @NotNull + public static Collection lsRemote(@NotNull GitRepository repository, @NotNull String remoteName, @NotNull String remoteUrl) { + try { + final Git git = convertToGit(repository); + final GitHttpCredentialsProvider provider = new GitHttpCredentialsProvider(repository.getProject(), remoteUrl); + GitHttpRemoteCommand.LsRemote lsRemoteCommand = new GitHttpRemoteCommand.LsRemote(git, provider, remoteUrl); + callWithAuthRetry(lsRemoteCommand, repository.getProject()); + return convertRefsToStrings(lsRemoteCommand.getRefs()); + } catch (IOException e) { + logException(repository, remoteName, remoteUrl, e, "fetching"); + } + catch (InvalidRemoteException e) { + logException(repository, remoteName, remoteUrl, e, "fetching"); + } + catch (URISyntaxException e) { + logException(repository, remoteName, remoteUrl, e, "fetching"); + } + return Collections.emptyList(); + } + + @NotNull + private static Collection convertRefsToStrings(@NotNull Collection lsRemoteCommandRefs) { + Collection refs = new ArrayList(); + for (Ref ref : lsRemoteCommandRefs) { + String refName = ref.getName(); + if (refName.startsWith(GitBranch.REFS_HEADS_PREFIX)) { + refName = refName.substring(GitBranch.REFS_HEADS_PREFIX.length()); + } + refs.add(refName); + } + return refs; + } + @NotNull public static GitFetchResult cloneRepository(@NotNull Project project, @NotNull final File directory, @NotNull final String url) { GitFetchResult.Type resultType; diff --git a/plugins/git4idea/src/git4idea/jgit/GitHttpRemoteCommand.java b/plugins/git4idea/src/git4idea/jgit/GitHttpRemoteCommand.java index 7d4f58b219a1..5c9477d6f415 100644 --- a/plugins/git4idea/src/git4idea/jgit/GitHttpRemoteCommand.java +++ b/plugins/git4idea/src/git4idea/jgit/GitHttpRemoteCommand.java @@ -40,9 +40,7 @@ import java.io.File; import java.io.IOException; import java.net.URISyntaxException; import java.text.MessageFormat; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; +import java.util.*; /** * @author Kirill Likhodedov @@ -51,7 +49,7 @@ interface GitHttpRemoteCommand { String getUrl(); void setUrl(String url); - void run() throws InvalidRemoteException, URISyntaxException; + void run() throws InvalidRemoteException, URISyntaxException, TransportException; void cleanup(); GitHttpCredentialsProvider getCredentialsProvider(); String getLogString(); @@ -382,6 +380,118 @@ interface GitHttpRemoteCommand { } } + class LsRemote implements GitHttpRemoteCommand { + + private final Git myGit; + private final GitHttpCredentialsProvider myCredentialsProvider; + private String myUrl; + private Collection myResultRefs; + + public LsRemote(@NotNull Git git, @NotNull GitHttpCredentialsProvider credentialsProvider, @NotNull String url) { + myGit = git; + myCredentialsProvider = credentialsProvider; + myUrl = url; + } + + @Override + public void run() throws InvalidRemoteException, TransportException { + myResultRefs = call(); + } + + @Override + public void cleanup() { + } + + @Override + public GitHttpCredentialsProvider getCredentialsProvider() { + return myCredentialsProvider; + } + + @Override + public String getLogString() { + return getCommandString(); + } + + @Override + public String getCommandString() { + return String.format("git ls-remote --heads %s ", myUrl); + } + + @Override + public String getUrl() { + return myUrl; + } + + @Override + public void setUrl(@NotNull String url) { + myUrl = url; + } + + @NotNull + public Collection getRefs() { + return myResultRefs == null ? Collections.emptyList() : myResultRefs; + } + + /* + Copy-paste of org.eclipse.jgit.api.LsRemote#call with the following changes: + 1. More specific exceptions declaration. + 2. Use CredentialsProvider. + 3. We don't need --tags, we always need --heads. + */ + private Collection call() throws TransportException, InvalidRemoteException { + try { + Transport transport = Transport.open(myGit.getRepository(), myUrl); + + try { + Collection refSpecs = new ArrayList(1); + refSpecs.add(new RefSpec("refs/heads/*:refs/remotes/origin/*")); + Collection refs; + Map refmap = new HashMap(); + transport.setCredentialsProvider(myCredentialsProvider); + FetchConnection fc = transport.openFetch(); + try { + refs = fc.getRefs(); + if (refSpecs.isEmpty()) { + for (Ref r : refs) { + refmap.put(r.getName(), r); + } + } + else { + for (Ref r : refs) { + for (RefSpec rs : refSpecs) { + if (rs.matchSource(r)) { + refmap.put(r.getName(), r); + break; + } + } + } + } + } + finally { + fc.close(); + } + return refmap.values(); + } + catch (TransportException e) { + throw new JGitInternalException( + JGitText.get().exceptionCaughtDuringExecutionOfLsRemoteCommand, + e); + } + finally { + transport.close(); + } + } + catch (URISyntaxException e) { + throw new InvalidRemoteException(MessageFormat.format( + JGitText.get().invalidRemote, myUrl)); + } + catch (NotSupportedException e) { + throw new JGitInternalException( + JGitText.get().exceptionCaughtDuringExecutionOfLsRemoteCommand, + e); + } + } + } } diff --git a/plugins/git4idea/src/git4idea/merge/GitPullDialog.java b/plugins/git4idea/src/git4idea/merge/GitPullDialog.java index 78e9f5dc0e29..dd4056af5133 100644 --- a/plugins/git4idea/src/git4idea/merge/GitPullDialog.java +++ b/plugins/git4idea/src/git4idea/merge/GitPullDialog.java @@ -29,13 +29,19 @@ import git4idea.commands.GitHandlerUtil; import git4idea.commands.GitLineHandler; import git4idea.commands.GitSimpleHandler; import git4idea.i18n.GitBundle; +import git4idea.jgit.GitHttpAdapter; +import git4idea.repo.GitRepository; +import git4idea.repo.GitRepositoryManager; import git4idea.ui.GitUIUtil; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.swing.*; import javax.swing.event.DocumentEvent; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; +import java.util.ArrayList; +import java.util.Collection; import java.util.Collections; import java.util.List; @@ -165,27 +171,50 @@ public class GitPullDialog extends DialogWrapper { listener.changedUpdate(null); myGetBranchesButton.addActionListener(new ActionListener() { public void actionPerformed(final ActionEvent e) { - GitSimpleHandler h = new GitSimpleHandler(myProject, gitRoot(), GitCommand.LS_REMOTE); - h.addParameters("--heads", myRemote.getSelectedItem().toString()); - String output = GitHandlerUtil.doSynchronously(h, GitBundle.getString("pull.getting.remote.branches"), h.printableCommandLine()); - if (output == null) { - return; - } myBranchChooser.removeAllElements(); - for (String line : output.split("\n")) { - if (line.length() == 0) { - continue; - } - int pos = line.lastIndexOf('/'); - if (pos == -1) { - pos = line.lastIndexOf('\t'); - } - myBranchChooser.addElement(line.substring(pos + 1), false); + Collection remoteBranches = getRemoteBranches((GitDeprecatedRemote)myRemote.getSelectedItem()); + for (String branch : remoteBranches) { + myBranchChooser.addElement(branch, false); } } }); } + @NotNull + private Collection getRemoteBranches(@NotNull GitDeprecatedRemote remote) { + if (GitHttpAdapter.isHttpUrlWithoutUserCredentials(remote.fetchUrl())) { + GitRepository repository = GitRepositoryManager.getInstance(myProject).getRepositoryForRoot(gitRoot()); + if (repository == null) { + return Collections.emptyList(); + } + return GitHttpAdapter.lsRemote(repository, remote.name(), remote.fetchUrl()); + } + return lsRemoteNatively(remote); + } + + @NotNull + private Collection lsRemoteNatively(@NotNull GitDeprecatedRemote remote) { + GitSimpleHandler h = new GitSimpleHandler(myProject, gitRoot(), GitCommand.LS_REMOTE); + h.addParameters("--heads", remote.toString()); + String output = GitHandlerUtil.doSynchronously(h, GitBundle.getString("pull.getting.remote.branches"), h.printableCommandLine()); + if (output == null) { + return Collections.emptyList(); + } + + Collection remoteBranches = new ArrayList(); + for (String line : output.split("\n")) { + if (line.length() == 0) { + continue; + } + int pos = line.lastIndexOf('/'); + if (pos == -1) { + pos = line.lastIndexOf('\t'); + } + remoteBranches.add(line.substring(pos + 1)); + } + return remoteBranches; + } + /** * @return a pull handler configured according to dialog options */ From 0ffcf6052df4e153a312108af1be0b8bc77640f4 Mon Sep 17 00:00:00 2001 From: Kirill Likhodedov Date: Fri, 9 Dec 2011 13:39:28 +0300 Subject: [PATCH 52/62] IDEA-78003 Update failure due to no tracked branch should show affected repository --- .../src/git4idea/update/GitUpdateProcess.java | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/plugins/git4idea/src/git4idea/update/GitUpdateProcess.java b/plugins/git4idea/src/git4idea/update/GitUpdateProcess.java index 3918b54e7f3d..10ea5e2df3a4 100644 --- a/plugins/git4idea/src/git4idea/update/GitUpdateProcess.java +++ b/plugins/git4idea/src/git4idea/update/GitUpdateProcess.java @@ -34,6 +34,7 @@ import git4idea.merge.GitConflictResolver; import git4idea.merge.GitMerger; import git4idea.rebase.GitRebaser; import git4idea.stash.GitChangesSaver; +import git4idea.ui.GitUIUtil; import org.jetbrains.annotations.NotNull; import java.util.*; @@ -242,7 +243,8 @@ public class GitUpdateProcess { if (branch == null) { LOG.info("checkTrackedBranchesConfigured current branch is null"); notifyImportantError(myProject, "Can't update: no current branch", - "You are in 'detached HEAD' state, which means that you're not on any branch.
" + + "You are in 'detached HEAD' state, which means that you're not on any branch" + + rootStringIfNeeded(root) + "Checkout a branch to make update possible."); return false; } @@ -251,15 +253,17 @@ public class GitUpdateProcess { final String branchName = branch.getName(); LOG.info("checkTrackedBranchesConfigured tracked branch is null for current branch " + branch); notifyImportantError(myProject, "Can't update: no tracked branch", - "No tracked branch configured for branch " + branchName + - "
To make your branch track a remote branch call, for example,
" + + "No tracked branch configured for branch " + GitUIUtil.code(branchName) + + rootStringIfNeeded(root) + + "To make your branch track a remote branch call, for example,
" + "git branch --set-upstream " + branchName + " origin/" + branchName + ""); return false; } if (!tracked.exists(root)) { LOG.info("checkTrackedBranchesConfigured tracked branch " + tracked + " doesn't exist."); notifyMessage(myProject, "Can't update: tracked branch doesn't exist.", - "Tracked branch " + tracked.getName() + " doesn't exist, so there is nothing to update.
" + + "Tracked branch " + tracked.getName() + " doesn't exist, so there is nothing to update" + + rootStringIfNeeded(root) + "The branch will be automatically created when you push to it.", NotificationType.WARNING, true, null); return false; @@ -274,6 +278,13 @@ public class GitUpdateProcess { return true; } + private String rootStringIfNeeded(@NotNull VirtualFile root) { + if (myRoots.size() < 2) { + return ".
"; + } + return "
in Git repository " + GitUIUtil.code(root.getPresentableUrl()) + "
"; + } + /** * Check if merge is in progress, propose to resolve conflicts. * @return true if merge is in progress, which means that update can't continue. From bb84bd7cfdc3c85d017f06c87934d36b5318301f Mon Sep 17 00:00:00 2001 From: Kirill Likhodedov Date: Fri, 9 Dec 2011 13:49:24 +0300 Subject: [PATCH 53/62] GitPusher: limit number of push-rejected-update-push attempts to 10 --- plugins/git4idea/src/git4idea/push/GitPusher.java | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/plugins/git4idea/src/git4idea/push/GitPusher.java b/plugins/git4idea/src/git4idea/push/GitPusher.java index 53899779c8aa..5236891380ec 100644 --- a/plugins/git4idea/src/git4idea/push/GitPusher.java +++ b/plugins/git4idea/src/git4idea/push/GitPusher.java @@ -63,6 +63,7 @@ public final class GitPusher { private static final Logger LOG = Logger.getInstance(GitPusher.class); private static final String INDICATOR_TEXT = "Pushing"; + private static final int MAX_PUSH_ATTEMPTS = 10; private final Project myProject; private final ProgressIndicator myProgressIndicator; @@ -202,7 +203,7 @@ public final class GitPusher { * Makes push, shows the result in a notification. If push for current branch is rejected, shows a dialog proposing to update. */ public void push(@NotNull GitPushInfo pushInfo) { - push(pushInfo, null, null); + push(pushInfo, null, null, 0); } /** @@ -212,9 +213,9 @@ public final class GitPusher { * option. * Also, at the end results are merged and are shown in a single notification. */ - private void push(@NotNull GitPushInfo pushInfo, @Nullable GitPushResult previousResult, @Nullable UpdateSettings updateSettings) { + private void push(@NotNull GitPushInfo pushInfo, @Nullable GitPushResult previousResult, @Nullable UpdateSettings updateSettings, int attempt) { GitPushResult result = tryPushAndGetResult(pushInfo); - handleResult(pushInfo, result, previousResult, updateSettings); + handleResult(pushInfo, result, previousResult, updateSettings, attempt); } @NotNull @@ -427,7 +428,8 @@ public final class GitPusher { // if in a failed repo, a branch was rejected that had nothing to push, don't notify about the rejection. // Besides all of the above, don't confuse users with 1 repository with all this "repository/root" stuff; // don't confuse users which push only a single branch with all this "branch" stuff. - private void handleResult(@NotNull GitPushInfo pushInfo, @NotNull GitPushResult result, @Nullable GitPushResult previousResult, @Nullable UpdateSettings updateSettings) { + private void handleResult(@NotNull GitPushInfo pushInfo, @NotNull GitPushResult result, @Nullable GitPushResult previousResult, @Nullable UpdateSettings updateSettings, + int pushAttempt) { result.mergeFrom(previousResult); if (result.isEmpty()) { @@ -442,7 +444,7 @@ public final class GitPusher { // => for current branch propose to update and re-push it. For others just warn Map rejectedPushesForCurrentBranch = result.getRejectedPushesForCurrentBranch(); - if (!rejectedPushesForCurrentBranch.isEmpty()) { + if (pushAttempt <= MAX_PUSH_ATTEMPTS && !rejectedPushesForCurrentBranch.isEmpty()) { if (updateSettings == null) { // show dialog only when push is rejected for the first time in a row, otherwise reuse previously chosen update method @@ -464,7 +466,7 @@ public final class GitPusher { if (updateResult) { myProgressIndicator.setText(INDICATOR_TEXT); GitPushInfo newPushInfo = pushInfo.retain(rejectedPushesForCurrentBranch); - push(newPushInfo, adjustedPushResult, updateSettings); + push(newPushInfo, adjustedPushResult, updateSettings, pushAttempt + 1); return; // don't notify - next push will notify all results in compound } } From 342786f95096cf27fd24709b8eb34c405364d6ca Mon Sep 17 00:00:00 2001 From: Kirill Likhodedov Date: Fri, 9 Dec 2011 14:42:19 +0300 Subject: [PATCH 54/62] GitUIUtil.notifyMessages: don't allow Notification description to be empty --- plugins/git4idea/src/git4idea/ui/GitUIUtil.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/plugins/git4idea/src/git4idea/ui/GitUIUtil.java b/plugins/git4idea/src/git4idea/ui/GitUIUtil.java index a8a04ac9eeb5..f4c947ebc396 100644 --- a/plugins/git4idea/src/git4idea/ui/GitUIUtil.java +++ b/plugins/git4idea/src/git4idea/ui/GitUIUtil.java @@ -58,13 +58,17 @@ public class GitUIUtil { private GitUIUtil() { } public static void notifyMessages(Project project, @Nullable String title, @Nullable String description, NotificationType type, boolean important, @Nullable Collection messages) { - if (StringUtil.isEmptyOrSpaces(title)) { - title = description; + if (title == null) { + title = ""; } String desc = (description != null ? description.replace("\n", "
") : ""); if (messages != null && !messages.isEmpty()) { desc += "
" + StringUtil.join(messages, "
"); } + if (StringUtil.isEmptyOrSpaces(desc)) { + desc = StringUtil.isEmptyOrSpaces(title) ? "Error" : title; // description is not allowed to be empty, title is => moving title text to description + title = ""; + } NotificationGroup group = important ? GitVcs.IMPORTANT_ERROR_NOTIFICATION : GitVcs.NOTIFICATION_GROUP_ID; group.createNotification(title, desc, type, null).notify(project.isDefault() ? null : project); } From a8a8e1ee81548ab5c3c07bbbadf9bbe0ea29a9fd Mon Sep 17 00:00:00 2001 From: Kirill Likhodedov Date: Fri, 9 Dec 2011 14:48:05 +0300 Subject: [PATCH 55/62] GitPusher: add logging --- plugins/git4idea/src/git4idea/push/GitPusher.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/plugins/git4idea/src/git4idea/push/GitPusher.java b/plugins/git4idea/src/git4idea/push/GitPusher.java index 5236891380ec..34d5e3837b8d 100644 --- a/plugins/git4idea/src/git4idea/push/GitPusher.java +++ b/plugins/git4idea/src/git4idea/push/GitPusher.java @@ -106,6 +106,11 @@ public final class GitPusher { public boolean shouldUpdate() { return getUpdateMethod() != null; } + + @Override + public String toString() { + return String.format("UpdateSettings{myUpdateAllRoots=%s, myUpdateMethod=%s}", myUpdateAllRoots, myUpdateMethod); + } } public GitPusher(@NotNull Project project, @NotNull ProgressIndicator indicator) { @@ -446,6 +451,9 @@ public final class GitPusher { if (pushAttempt <= MAX_PUSH_ATTEMPTS && !rejectedPushesForCurrentBranch.isEmpty()) { + LOG.info( + String.format("Rejected pushes for current branches: %n%s%nUpdate settings: %s", rejectedPushesForCurrentBranch, updateSettings)); + if (updateSettings == null) { // show dialog only when push is rejected for the first time in a row, otherwise reuse previously chosen update method // and don't show the dialog again if user has chosen not to ask again From 6051fa73b3e358861ca9b122f1f570c93891d1cd Mon Sep 17 00:00:00 2001 From: Kirill Likhodedov Date: Fri, 9 Dec 2011 14:50:40 +0300 Subject: [PATCH 56/62] GitLogStatusInfo: better assertion --- plugins/git4idea/src/git4idea/history/GitLogStatusInfo.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/git4idea/src/git4idea/history/GitLogStatusInfo.java b/plugins/git4idea/src/git4idea/history/GitLogStatusInfo.java index b2685b659a6d..5dd30712ca6e 100644 --- a/plugins/git4idea/src/git4idea/history/GitLogStatusInfo.java +++ b/plugins/git4idea/src/git4idea/history/GitLogStatusInfo.java @@ -44,9 +44,9 @@ class GitLogStatusInfo { */ private static void verifyParameters(@NotNull GitChangeType type, @NotNull String path, @Nullable String secondPath) { if (type.requiresSecondPath()) { - LOG.assertTrue(secondPath != null, "Rename change should have the second path"); + LOG.assertTrue(secondPath != null, String.format("Rename change should have the second path. type=%s, path1=%s, path2=%s", type, path, secondPath)); } else { - LOG.assertTrue(secondPath == null, "Second path should be null in case of change type [" + type + "]"); + LOG.assertTrue(secondPath == null, String.format("Second path should be null. type=%s, path1=%s, path2=%s", type, path, secondPath)); } } From 91e127359d3bbe97b1da08fbffbf446da6f6492b Mon Sep 17 00:00:00 2001 From: Kirill Likhodedov Date: Thu, 8 Dec 2011 19:05:17 +0300 Subject: [PATCH 57/62] IDEA-78533 On rejected push to not tracked branch don't propose to update For auto-update collect rejected pushes only from current branch to the tracked branch --- .../src/git4idea/push/GitPushResult.java | 26 +++++++++++++++++-- .../git4idea/src/git4idea/push/GitPusher.java | 2 +- 2 files changed, 25 insertions(+), 3 deletions(-) diff --git a/plugins/git4idea/src/git4idea/push/GitPushResult.java b/plugins/git4idea/src/git4idea/push/GitPushResult.java index 1f4df573ee11..ee16ee2d3357 100644 --- a/plugins/git4idea/src/git4idea/push/GitPushResult.java +++ b/plugins/git4idea/src/git4idea/push/GitPushResult.java @@ -174,7 +174,7 @@ class GitPushResult { } @NotNull - Map getRejectedPushesForCurrentBranch() { + Map getRejectedPushesFromCurrentBranchToTrackedBranch(GitPushInfo pushInfo) { final Map rejectedPushesForCurrentBranch = new HashMap(); for (Map.Entry entry : group().myRejectedResults.entrySet()) { GitRepository repository = entry.getKey(); @@ -184,7 +184,29 @@ class GitPushResult { } GitPushRepoResult repoResult = entry.getValue(); GitPushBranchResult curBranchResult = repoResult.getBranchResults().get(currentBranch); - if (curBranchResult != null && curBranchResult.isRejected()) { + + if (curBranchResult == null) { + continue; + } + + String trackedBranchName; + try { + String simpleName = currentBranch.getTrackedBranchName(myProject, repository.getRoot()); + if (simpleName != null && simpleName.startsWith(GitBranch.REFS_HEADS_PREFIX)) { + simpleName = simpleName.substring(GitBranch.REFS_HEADS_PREFIX.length()); + } + String remote = currentBranch.getTrackedRemoteName(myProject, repository.getRoot()); + trackedBranchName = remote + "/" + simpleName; + } + catch (VcsException e) { + LOG.info("Couldn't get tracked branch for branch " + currentBranch, e); + continue; + } + if (!pushInfo.getPushSpecs().get(repository).getDest().getName().equals(trackedBranchName)) { + // push from current branch was rejected, but it was a push not to the tracked branch => ignore + continue; + } + if (curBranchResult.isRejected()) { rejectedPushesForCurrentBranch.put(repository, currentBranch); } } diff --git a/plugins/git4idea/src/git4idea/push/GitPusher.java b/plugins/git4idea/src/git4idea/push/GitPusher.java index 34d5e3837b8d..ed83f78e39b7 100644 --- a/plugins/git4idea/src/git4idea/push/GitPusher.java +++ b/plugins/git4idea/src/git4idea/push/GitPusher.java @@ -447,7 +447,7 @@ public final class GitPusher { else { // there were no errors, but there might be some rejected branches on some of the repositories // => for current branch propose to update and re-push it. For others just warn - Map rejectedPushesForCurrentBranch = result.getRejectedPushesForCurrentBranch(); + Map rejectedPushesForCurrentBranch = result.getRejectedPushesFromCurrentBranchToTrackedBranch(pushInfo); if (pushAttempt <= MAX_PUSH_ATTEMPTS && !rejectedPushesForCurrentBranch.isEmpty()) { From 0c40400be2f6921af2c373d24f9c030eff6cffbc Mon Sep 17 00:00:00 2001 From: anna Date: Fri, 9 Dec 2011 13:14:25 +0100 Subject: [PATCH 58/62] preselect final fields on constructor generation (IDEA-78512) --- .../GenerateConstructorHandler.java | 26 +++++++++++++++++++ .../GenerateMembersHandlerBase.java | 14 +++++++--- .../afterFinalFieldPreselection.java | 11 ++++++++ .../beforeFinalFieldPreselection.java | 6 +++++ .../codeInsight/GenerateConstructorTest.java | 18 +++++++++++++ 5 files changed, 72 insertions(+), 3 deletions(-) create mode 100644 java/java-tests/testData/codeInsight/generateConstructor/afterFinalFieldPreselection.java create mode 100644 java/java-tests/testData/codeInsight/generateConstructor/beforeFinalFieldPreselection.java diff --git a/java/java-impl/src/com/intellij/codeInsight/generation/GenerateConstructorHandler.java b/java/java-impl/src/com/intellij/codeInsight/generation/GenerateConstructorHandler.java index a3c5b5c68a15..116da27861d4 100644 --- a/java/java-impl/src/com/intellij/codeInsight/generation/GenerateConstructorHandler.java +++ b/java/java-impl/src/com/intellij/codeInsight/generation/GenerateConstructorHandler.java @@ -134,6 +134,32 @@ public class GenerateConstructorHandler extends GenerateMembersHandlerBase { return members; } + @Override + protected MemberChooser createMembersChooser(ClassMember[] members, + boolean allowEmptySelection, + boolean copyJavadocCheckbox, + Project project) { + final MemberChooser chooser = super.createMembersChooser(members, allowEmptySelection, copyJavadocCheckbox, project); + final List preselection = preselect(members); + if (!preselection.isEmpty()) { + chooser.selectElements(preselection.toArray(new ClassMember[preselection.size()])); + } + return chooser; + } + + protected static List preselect(ClassMember[] members) { + final List preselection = new ArrayList(); + for (ClassMember member : members) { + if (member instanceof PsiFieldMember) { + final PsiField psiField = ((PsiFieldMember)member).getElement(); + if (psiField != null && psiField.hasModifierProperty(PsiModifier.FINAL)) { + preselection.add(member); + } + } + } + return preselection; + } + @NotNull protected List generateMemberPrototypes(PsiClass aClass, ClassMember[] members) throws IncorrectOperationException { List baseConstructors = new ArrayList(); diff --git a/java/java-impl/src/com/intellij/codeInsight/generation/GenerateMembersHandlerBase.java b/java/java-impl/src/com/intellij/codeInsight/generation/GenerateMembersHandlerBase.java index 79cbfe47eef0..a42018e62eb8 100644 --- a/java/java-impl/src/com/intellij/codeInsight/generation/GenerateMembersHandlerBase.java +++ b/java/java-impl/src/com/intellij/codeInsight/generation/GenerateMembersHandlerBase.java @@ -183,15 +183,23 @@ public abstract class GenerateMembersHandlerBase implements CodeInsightActionHan @Nullable protected ClassMember[] chooseMembers(ClassMember[] members, boolean allowEmptySelection, boolean copyJavadocCheckbox, Project project) { - MemberChooser chooser = new MemberChooser(members, allowEmptySelection, true, project); - chooser.setTitle(myChooserTitle); - chooser.setCopyJavadocVisible(copyJavadocCheckbox); + MemberChooser chooser = createMembersChooser(members, allowEmptySelection, copyJavadocCheckbox, project); chooser.show(); myToCopyJavaDoc = chooser.isCopyJavadoc(); final List list = chooser.getSelectedElements(); return list == null ? null : list.toArray(new ClassMember[list.size()]); } + protected MemberChooser createMembersChooser(ClassMember[] members, + boolean allowEmptySelection, + boolean copyJavadocCheckbox, + Project project) { + MemberChooser chooser = new MemberChooser(members, allowEmptySelection, true, project); + chooser.setTitle(myChooserTitle); + chooser.setCopyJavadocVisible(copyJavadocCheckbox); + return chooser; + } + @NotNull protected List generateMemberPrototypes(PsiClass aClass, ClassMember[] members) throws IncorrectOperationException { ArrayList array = new ArrayList(); diff --git a/java/java-tests/testData/codeInsight/generateConstructor/afterFinalFieldPreselection.java b/java/java-tests/testData/codeInsight/generateConstructor/afterFinalFieldPreselection.java new file mode 100644 index 000000000000..bd402a9b28b7 --- /dev/null +++ b/java/java-tests/testData/codeInsight/generateConstructor/afterFinalFieldPreselection.java @@ -0,0 +1,11 @@ +class Test { + private int a; + private final int b; + private int c; + private final int d; + + Test(int b, int d) { + this.b = b; + this.d = d; + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/generateConstructor/beforeFinalFieldPreselection.java b/java/java-tests/testData/codeInsight/generateConstructor/beforeFinalFieldPreselection.java new file mode 100644 index 000000000000..57459a5e4b37 --- /dev/null +++ b/java/java-tests/testData/codeInsight/generateConstructor/beforeFinalFieldPreselection.java @@ -0,0 +1,6 @@ +class Test { + private int a; + private final int b; + private int c; + private final int d; +} \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/GenerateConstructorTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/GenerateConstructorTest.java index 21efe1f59f4a..c04ab6a28d4c 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/GenerateConstructorTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/GenerateConstructorTest.java @@ -10,6 +10,8 @@ import com.intellij.psi.codeStyle.CodeStyleSettings; import com.intellij.psi.codeStyle.CodeStyleSettingsManager; import com.intellij.testFramework.LightCodeInsightTestCase; +import java.util.List; + public class GenerateConstructorTest extends LightCodeInsightTestCase { public void testAbstractClass() throws Exception { doTest(); } public void testPackageLocalClass() throws Exception { doTest(); } @@ -38,6 +40,22 @@ public class GenerateConstructorTest extends LightCodeInsightTestCase { doTest(); } + public void testFinalFieldPreselection() throws Exception { + String name = getTestName(false); + configureByFile("/codeInsight/generateConstructor/before" + name + ".java"); + new GenerateConstructorHandler() { + @Override + protected ClassMember[] chooseMembers(ClassMember[] members, + boolean allowEmptySelection, + boolean copyJavadocCheckbox, + Project project) { + final List preselection = GenerateConstructorHandler.preselect(members); + return preselection.toArray(new ClassMember[preselection.size()]); + } + }.invoke(getProject(), getEditor(), getFile()); + checkResultByFile("/codeInsight/generateConstructor/after" + name +".java"); + } + private void doTest() throws Exception { String name = getTestName(false); configureByFile("/codeInsight/generateConstructor/before" + From c2604c42d43aaffc57f1d1c50052dba143bc42ea Mon Sep 17 00:00:00 2001 From: Eugene Zhuravlev Date: Fri, 9 Dec 2011 14:12:46 +0100 Subject: [PATCH 59/62] introduced PromptingMacro base class --- .../intellij/ide/macro/FilePromptMacro.java | 10 ++--- .../com/intellij/ide/macro/MacroManager.java | 19 ++++---- .../com/intellij/ide/macro/PromptMacro.java | 11 +++-- .../intellij/ide/macro/PromptingMacro.java | 44 +++++++++++++++++++ 4 files changed, 63 insertions(+), 21 deletions(-) create mode 100644 platform/lang-impl/src/com/intellij/ide/macro/PromptingMacro.java diff --git a/platform/lang-impl/src/com/intellij/ide/macro/FilePromptMacro.java b/platform/lang-impl/src/com/intellij/ide/macro/FilePromptMacro.java index a6096602a02e..7346a6865e00 100644 --- a/platform/lang-impl/src/com/intellij/ide/macro/FilePromptMacro.java +++ b/platform/lang-impl/src/com/intellij/ide/macro/FilePromptMacro.java @@ -29,7 +29,7 @@ import com.intellij.openapi.vfs.VirtualFile; /** * @author yole */ -public class FilePromptMacro extends Macro implements SecondQueueExpandMacro { +public class FilePromptMacro extends PromptingMacro implements SecondQueueExpandMacro { @Override public String getName() { return "FilePrompt"; @@ -40,16 +40,12 @@ public class FilePromptMacro extends Macro implements SecondQueueExpandMacro { return "Shows a file chooser dialog"; } - @Override - public String expand(DataContext dataContext) throws ExecutionCancelledException { + protected String promptUser(DataContext dataContext) { Project project = PlatformDataKeys.PROJECT.getData(dataContext); final FileChooserDescriptor descriptor = FileChooserDescriptorFactory.createSingleLocalFileDescriptor(); final FileChooserDialog fileChooser = FileChooserFactory.getInstance().createFileChooser(descriptor, project); final VirtualFile[] result = fileChooser.choose(null, project); - if (result.length != 1) { - throw new ExecutionCancelledException(); - } - return FileUtil.toSystemDependentName(result [0].getPath()); + return result.length == 1? FileUtil.toSystemDependentName(result[0].getPath()) : null; } @Override diff --git a/platform/lang-impl/src/com/intellij/ide/macro/MacroManager.java b/platform/lang-impl/src/com/intellij/ide/macro/MacroManager.java index 1cfccc09c07d..378ad9777bc3 100644 --- a/platform/lang-impl/src/com/intellij/ide/macro/MacroManager.java +++ b/platform/lang-impl/src/com/intellij/ide/macro/MacroManager.java @@ -158,14 +158,17 @@ public final class MacroManager { } public String expandSilentMarcos(String str, boolean firstQueueExpand, DataContext dataContext) throws Macro.ExecutionCancelledException { - return expandMacroSet(str, firstQueueExpand, dataContext, - ConvertingIterator.create(getMacros().iterator(), new Convertor() { - public Macro convert(Macro macro) { - if (macro instanceof PromptMacro) - return new Macro.Silent(macro, ""); - return macro; - } - })); + final Convertor convertor = new Convertor() { + public Macro convert(Macro macro) { + if (macro instanceof PromptingMacro) { + return new Macro.Silent(macro, ""); + } + return macro; + } + }; + return expandMacroSet( + str, firstQueueExpand, dataContext, ConvertingIterator.create(getMacros().iterator(), convertor) + ); } } diff --git a/platform/lang-impl/src/com/intellij/ide/macro/PromptMacro.java b/platform/lang-impl/src/com/intellij/ide/macro/PromptMacro.java index 5aa4eec96baa..4d3caab3f275 100644 --- a/platform/lang-impl/src/com/intellij/ide/macro/PromptMacro.java +++ b/platform/lang-impl/src/com/intellij/ide/macro/PromptMacro.java @@ -19,8 +19,9 @@ package com.intellij.ide.macro; import com.intellij.ide.IdeBundle; import com.intellij.openapi.actionSystem.DataContext; import com.intellij.openapi.ui.Messages; +import org.jetbrains.annotations.Nullable; -public final class PromptMacro extends Macro implements SecondQueueExpandMacro { +public final class PromptMacro extends PromptingMacro implements SecondQueueExpandMacro { public String getName() { return "Prompt"; } @@ -29,11 +30,9 @@ public final class PromptMacro extends Macro implements SecondQueueExpandMacro { return IdeBundle.message("macro.prompt"); } - public String expand(DataContext dataContext) throws ExecutionCancelledException { - String userInput = Messages.showInputDialog(IdeBundle.message("prompt.enter.parameters"), - IdeBundle.message("title.input"), Messages.getQuestionIcon()); - if (userInput == null) throw new ExecutionCancelledException(); - return userInput; + @Nullable + protected String promptUser(DataContext dataContext) { + return Messages.showInputDialog(IdeBundle.message("prompt.enter.parameters"), IdeBundle.message("title.input"), Messages.getQuestionIcon()); } public void cachePreview(DataContext dataContext) { diff --git a/platform/lang-impl/src/com/intellij/ide/macro/PromptingMacro.java b/platform/lang-impl/src/com/intellij/ide/macro/PromptingMacro.java new file mode 100644 index 000000000000..41453dedcf68 --- /dev/null +++ b/platform/lang-impl/src/com/intellij/ide/macro/PromptingMacro.java @@ -0,0 +1,44 @@ +/* + * Copyright 2000-2011 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.ide.macro; + +import com.intellij.openapi.actionSystem.DataContext; +import org.jetbrains.annotations.Nullable; + +/** + * @author Eugene Zhuravlev + * Date: 12/9/11 + */ +public abstract class PromptingMacro extends Macro{ + + public final String expand(DataContext dataContext) throws ExecutionCancelledException { + final String userInput = promptUser(dataContext); + if (userInput == null) { + throw new ExecutionCancelledException(); + } + return userInput; + } + + + /** + * Called from expand() method + * + * @param dataContext + * @return user input. If null is returned, ExecutionCancelledException is thrown by expand() method + */ + @Nullable + protected abstract String promptUser(DataContext dataContext); +} From fb42af421d70fab00db7854edb0648b961b07106 Mon Sep 17 00:00:00 2001 From: peter Date: Fri, 9 Dec 2011 14:32:19 +0100 Subject: [PATCH 60/62] live template settings mnemonics (IDEA-78615) --- .../src/messages/CodeInsightBundle.properties | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/platform/platform-resources-en/src/messages/CodeInsightBundle.properties b/platform/platform-resources-en/src/messages/CodeInsightBundle.properties index bd92a2f434ea..aa4dedba329e 100644 --- a/platform/platform-resources-en/src/messages/CodeInsightBundle.properties +++ b/platform/platform-resources-en/src/messages/CodeInsightBundle.properties @@ -290,10 +290,10 @@ dialog.edit.template.label.abbreviation=&Abbreviation: dialog.edit.template.label.group=&Group: dialog.edit.template.label.description=&Description: dialog.edit.template.options.title=Options -dialog.edit.template.label.expand.with=&Expand with +dialog.edit.template.label.expand.with=E&xpand with dialog.edit.template.checkbox.reformat.according.to.style=&Reformat according to style dialog.edit.template.checkbox.shorten.fq.names=Shorten &FQ names -dialog.edit.template.checkbox.use.static.import=Use static import if possible +dialog.edit.template.checkbox.use.static.import=Use static &import if possible dialog.edit.template.context.title=Context dialog.edit.template.checkbox.html=&HTML dialog.edit.template.checkbox.xml=&XML From fa7bc38a0f74aa21adac990f5ec3dab9b59ece43 Mon Sep 17 00:00:00 2001 From: Eugene Zhuravlev Date: Fri, 9 Dec 2011 15:07:31 +0100 Subject: [PATCH 61/62] show error when it is not possible to determine polyadic expression's expected type --- .../evaluation/expression/EvaluatorBuilderImpl.java | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/EvaluatorBuilderImpl.java b/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/EvaluatorBuilderImpl.java index da7c37b380b7..a994be84e76c 100644 --- a/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/EvaluatorBuilderImpl.java +++ b/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/EvaluatorBuilderImpl.java @@ -41,6 +41,7 @@ import com.intellij.psi.util.PsiTypesUtil; import com.intellij.psi.util.TypeConversionUtil; import com.intellij.util.IncorrectOperationException; import com.sun.jdi.Value; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.ArrayList; @@ -321,7 +322,10 @@ public class EvaluatorBuilderImpl implements EvaluatorBuilder { if (rType == null) { throwEvaluateException(DebuggerBundle.message("evaluation.error.unknown.expression.type", expression.getText())); } - PsiType typeForBinOp = TypeConversionUtil.calcTypeForBinaryExpression(lType, rType, opType, true); + final PsiType typeForBinOp = TypeConversionUtil.calcTypeForBinaryExpression(lType, rType, opType, true); + if (typeForBinOp == null) { + throwEvaluateException(DebuggerBundle.message("evaluation.error.unknown.expression.type", wideExpression.getText())); + } myResult = createBinaryEvaluator(result, lType, rResult, rType, opType, typeForBinOp); lType = typeForBinOp; result = myResult; @@ -330,7 +334,7 @@ public class EvaluatorBuilderImpl implements EvaluatorBuilder { // constructs binary evaluator handling unboxing and numeric promotion issues private static BinaryExpressionEvaluator createBinaryEvaluator( - Evaluator lResult, final PsiType lType, Evaluator rResult, final PsiType rType, final IElementType operation, final PsiType expressionExpectedType) { + Evaluator lResult, final PsiType lType, Evaluator rResult, final PsiType rType, final IElementType operation, final @NotNull PsiType expressionExpectedType) { // handle unboxing if neccesary if (isUnboxingInBinaryExpressionApplicable(lType, rType, operation)) { if (rType instanceof PsiClassType && UnBoxingEvaluator.isTypeUnboxable(rType.getCanonicalText())) { @@ -394,7 +398,7 @@ public class EvaluatorBuilderImpl implements EvaluatorBuilder { } } - return new BinaryExpressionEvaluator(lResult, rResult, operation, expressionExpectedType == null ? null : expressionExpectedType.getCanonicalText()); + return new BinaryExpressionEvaluator(lResult, rResult, operation, expressionExpectedType.getCanonicalText()); } private static boolean isBinaryNumericPromotionApplicable(PsiType lType, PsiType rType, IElementType opType) { From 6ac2b1de788644300535918ab0b8ca6636a32360 Mon Sep 17 00:00:00 2001 From: "andrey.zaytsev" Date: Fri, 9 Dec 2011 18:33:01 +0400 Subject: [PATCH 62/62] IDEA-78548 Alt-F3 doesn't work in analyze stacktrace dialog --- .../src/com/intellij/find/EditorSearchComponent.java | 2 +- .../com/intellij/find/impl/livePreview/SearchResults.java | 8 +++++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/find/EditorSearchComponent.java b/platform/lang-impl/src/com/intellij/find/EditorSearchComponent.java index 1d6084f48763..ff8f2b8913e0 100644 --- a/platform/lang-impl/src/com/intellij/find/EditorSearchComponent.java +++ b/platform/lang-impl/src/com/intellij/find/EditorSearchComponent.java @@ -226,7 +226,7 @@ public class EditorSearchComponent extends JPanel implements DataProvider, Selec myProject = project; myEditor = editor; - mySearchResults = new SearchResults(myEditor); + mySearchResults = new SearchResults(myEditor, myProject); myDefaultBackground = new JTextField().getBackground(); diff --git a/platform/lang-impl/src/com/intellij/find/impl/livePreview/SearchResults.java b/platform/lang-impl/src/com/intellij/find/impl/livePreview/SearchResults.java index b4f147d91239..6bf025589d68 100644 --- a/platform/lang-impl/src/com/intellij/find/impl/livePreview/SearchResults.java +++ b/platform/lang-impl/src/com/intellij/find/impl/livePreview/SearchResults.java @@ -58,6 +58,7 @@ public class SearchResults implements DocumentListener { private Set myExcluded = new HashSet(); private Editor myEditor; + private Project myProject; private FindModel myFindModel; private int myMatchesLimit = 100; @@ -72,8 +73,9 @@ public class SearchResults implements DocumentListener { private Stack> myCursorPositions = new Stack>(); - public SearchResults(Editor editor) { + public SearchResults(Editor editor, Project project) { myEditor = editor; + myProject = project; myEditor.getDocument().addDocumentListener(this); } @@ -161,7 +163,7 @@ public class SearchResults implements DocumentListener { @Nullable public Project getProject() { - return myEditor.getProject(); + return myProject; } public synchronized void setEditor(Editor editor) { @@ -328,7 +330,7 @@ public class SearchResults implements DocumentListener { int offset = r.getStartOffset(); while (true) { - FindManager findManager = FindManager.getInstance(editor.getProject()); + FindManager findManager = FindManager.getInstance(getProject()); FindResult result; try { BombedCharSequence