diff --git a/.idea/inspectionProfiles/idea_default.xml b/.idea/inspectionProfiles/idea_default.xml
index 95664e3124f2..cb79a6725114 100644
--- a/.idea/inspectionProfiles/idea_default.xml
+++ b/.idea/inspectionProfiles/idea_default.xml
@@ -504,9 +504,7 @@
-
-
-
+
diff --git a/.idea/inspectionProfiles/idea_default_no_spellchecker.xml b/.idea/inspectionProfiles/idea_default_no_spellchecker.xml
index 9d537767a0e3..828ddb73cf11 100644
--- a/.idea/inspectionProfiles/idea_default_no_spellchecker.xml
+++ b/.idea/inspectionProfiles/idea_default_no_spellchecker.xml
@@ -667,9 +667,7 @@
-
-
-
+
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 06a59793daa0..e962a9373913 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
@@ -38,6 +38,7 @@ import com.intellij.openapi.roots.ModuleRootManager;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.util.Computable;
import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.pom.java.LanguageLevel;
import com.intellij.rt.compiler.JavacRunner;
@@ -295,9 +296,10 @@ public class JavacCompiler extends ExternalCompiler {
additionalOptions.add("-processorpath");
additionalOptions.add(FileUtil.toSystemDependentName(processorPath));
}
- for (String processorName : config.getProcessors()) {
+ final Set processors = config.getProcessors();
+ if (!processors.isEmpty()) {
additionalOptions.add("-processor");
- additionalOptions.add(processorName);
+ additionalOptions.add(StringUtil.join(processors, ","));
}
for (Map.Entry entry : config.getProcessorOptions().entrySet()) {
additionalOptions.add("-A" + entry.getKey() + "=" +entry.getValue());
diff --git a/java/compiler/impl/src/com/intellij/compiler/server/BuildManager.java b/java/compiler/impl/src/com/intellij/compiler/server/BuildManager.java
index 9c4693d31f7b..2c5be8979639 100644
--- a/java/compiler/impl/src/com/intellij/compiler/server/BuildManager.java
+++ b/java/compiler/impl/src/com/intellij/compiler/server/BuildManager.java
@@ -807,7 +807,7 @@ public class BuildManager implements ApplicationComponent{
cmdLine.setCharset(mySystemCharset);
cmdLine.addParameter("-D" + CharsetToolkit.FILE_ENCODING_PROPERTY + "=" + mySystemCharset.name());
}
- for (String name : new String[]{"user.language", "user.country", "user.region"}) {
+ for (String name : new String[]{"user.language", "user.country", "user.region", PathManager.PROPERTY_HOME_PATH}) {
final String value = System.getProperty(name);
if (value != null) {
cmdLine.addParameter("-D" + name + "=" + value);
diff --git a/java/java-impl/src/com/intellij/psi/codeStyle/arrangement/JavaArrangementParseInfo.java b/java/java-impl/src/com/intellij/psi/codeStyle/arrangement/JavaArrangementParseInfo.java
index 7429b648d968..3497c235e18e 100644
--- a/java/java-impl/src/com/intellij/psi/codeStyle/arrangement/JavaArrangementParseInfo.java
+++ b/java/java-impl/src/com/intellij/psi/codeStyle/arrangement/JavaArrangementParseInfo.java
@@ -19,6 +19,7 @@ import com.intellij.openapi.util.Pair;
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiMethod;
import com.intellij.util.containers.ContainerUtil;
+import com.intellij.util.containers.ContainerUtilRt;
import com.intellij.util.containers.Stack;
import gnu.trove.TObjectIntHashMap;
import org.jetbrains.annotations.NotNull;
@@ -104,14 +105,16 @@ public class JavaArrangementParseInfo {
Stack> toProcess
= new Stack>();
toProcess.push(Pair.create(method, result));
+ Set usedMethods = ContainerUtilRt.newHashSet();
while (!toProcess.isEmpty()) {
Pair pair = toProcess.pop();
Set dependentMethods = myMethodDependencies.get(pair.first);
if (dependentMethods == null) {
continue;
}
+ usedMethods.add(pair.first);
for (PsiMethod dependentMethod : dependentMethods) {
- if (dependentMethod == method) {
+ if (usedMethods.contains(dependentMethod)) {
// Prevent cyclic dependencies.
return null;
}
diff --git a/java/java-impl/src/com/intellij/psi/formatter/java/AbstractJavaBlock.java b/java/java-impl/src/com/intellij/psi/formatter/java/AbstractJavaBlock.java
index ef0cf6652e03..82dabf200e99 100644
--- a/java/java-impl/src/com/intellij/psi/formatter/java/AbstractJavaBlock.java
+++ b/java/java-impl/src/com/intellij/psi/formatter/java/AbstractJavaBlock.java
@@ -21,7 +21,6 @@ import com.intellij.formatting.alignment.AlignmentInColumnsHelper;
import com.intellij.formatting.alignment.AlignmentStrategy;
import com.intellij.lang.ASTNode;
import com.intellij.openapi.diagnostic.Logger;
-import com.intellij.openapi.fileTypes.StdFileTypes;
import com.intellij.openapi.util.TextRange;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.*;
@@ -156,7 +155,7 @@ public abstract class AbstractJavaBlock extends AbstractBlock implements JavaBlo
Wrap wrap,
@NotNull AlignmentStrategy alignmentStrategy,
int startOffset) {
- Indent actualIndent = indent == null ? getDefaultSubtreeIndent(child, settings.getRootSettings().getIndentOptions(StdFileTypes.JAVA)) : indent;
+ Indent actualIndent = indent == null ? getDefaultSubtreeIndent(child, getJavaIndentOptions(settings)) : indent;
final IElementType elementType = child.getElementType();
Alignment alignment = alignmentStrategy.getAlignment(elementType);
@@ -207,10 +206,17 @@ public abstract class AbstractJavaBlock extends AbstractBlock implements JavaBlo
@NotNull
public static Block createJavaBlock(@NotNull ASTNode child, @NotNull CommonCodeStyleSettings settings) {
- return createJavaBlock(child, settings, getDefaultSubtreeIndent(child, settings.getRootSettings().getIndentOptions(StdFileTypes.JAVA)),
+ return createJavaBlock(child, settings, getDefaultSubtreeIndent(child, getJavaIndentOptions(settings)),
null, AlignmentStrategy.getNullStrategy());
}
+ @NotNull
+ private static CommonCodeStyleSettings.IndentOptions getJavaIndentOptions(CommonCodeStyleSettings settings) {
+ CommonCodeStyleSettings.IndentOptions indentOptions = settings.getIndentOptions();
+ assert indentOptions != null : "Java indent options are not initialized";
+ return indentOptions;
+ }
+
private static boolean isLikeExtendsList(final IElementType elementType) {
return elementType == JavaElementType.EXTENDS_LIST
|| elementType == JavaElementType.IMPLEMENTS_LIST
diff --git a/java/java-impl/src/com/intellij/refactoring/introduceField/IntroduceFieldCentralPanel.java b/java/java-impl/src/com/intellij/refactoring/introduceField/IntroduceFieldCentralPanel.java
index cc07e950aa43..68d5e99cc536 100644
--- a/java/java-impl/src/com/intellij/refactoring/introduceField/IntroduceFieldCentralPanel.java
+++ b/java/java-impl/src/com/intellij/refactoring/introduceField/IntroduceFieldCentralPanel.java
@@ -15,6 +15,7 @@
*/
package com.intellij.refactoring.introduceField;
+import com.intellij.ide.util.PropertiesComponent;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.psi.*;
import com.intellij.psi.util.PsiTreeUtil;
@@ -37,7 +38,8 @@ import java.awt.event.ItemListener;
public abstract class IntroduceFieldCentralPanel {
protected static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.introduceField.IntroduceFieldDialog");
- public static boolean ourLastCbFinalState = false;
+ private static final String INTRODUCE_FIELD_FINAL_CHECKBOX = "introduce.final.checkbox";
+ public static boolean ourLastCbFinalState = PropertiesComponent.getInstance().getBoolean(INTRODUCE_FIELD_FINAL_CHECKBOX, true);
protected final PsiClass myParentClass;
protected final PsiExpression myInitializerExpression;
@@ -273,6 +275,7 @@ public abstract class IntroduceFieldCentralPanel {
public void saveFinalState() {
if (myCbFinal != null && myCbFinal.isEnabled()) {
ourLastCbFinalState = myCbFinal.isSelected();
+ PropertiesComponent.getInstance().setValue(INTRODUCE_FIELD_FINAL_CHECKBOX, String.valueOf(ourLastCbFinalState));
}
}
diff --git a/java/java-impl/src/com/intellij/refactoring/introduceField/IntroduceFieldPopupPanel.java b/java/java-impl/src/com/intellij/refactoring/introduceField/IntroduceFieldPopupPanel.java
index 41a16ece2667..e0e26cbaf4dd 100644
--- a/java/java-impl/src/com/intellij/refactoring/introduceField/IntroduceFieldPopupPanel.java
+++ b/java/java-impl/src/com/intellij/refactoring/introduceField/IntroduceFieldPopupPanel.java
@@ -92,7 +92,7 @@ public class IntroduceFieldPopupPanel extends IntroduceFieldCentralPanel {
@Override
public boolean isDeclareFinal() {
- return allowFinal();
+ return ourLastCbFinalState && allowFinal();
}
private void selectInCurrentMethod() {
diff --git a/java/java-impl/src/com/intellij/refactoring/introduceParameter/AbstractJavaInplaceIntroducer.java b/java/java-impl/src/com/intellij/refactoring/introduceParameter/AbstractJavaInplaceIntroducer.java
index 5424f7086e51..9e94d3250263 100644
--- a/java/java-impl/src/com/intellij/refactoring/introduceParameter/AbstractJavaInplaceIntroducer.java
+++ b/java/java-impl/src/com/intellij/refactoring/introduceParameter/AbstractJavaInplaceIntroducer.java
@@ -139,7 +139,7 @@ public abstract class AbstractJavaInplaceIntroducer extends AbstractInplaceIntro
PsiExpression expression = refVariableElement instanceof PsiKeyword && refVariableElementParent instanceof PsiNewExpression
? (PsiNewExpression)refVariableElementParent
: PsiTreeUtil.getParentOfType(refVariableElement, PsiReferenceExpression.class);
- if (expression instanceof PsiReferenceExpression) {
+ if (expression instanceof PsiReferenceExpression && !(expression.getParent() instanceof PsiMethodCallExpression)) {
final String referenceName = ((PsiReferenceExpression)expression).getReferenceName();
if (((PsiReferenceExpression)expression).resolve() == psiVariable ||
Comparing.strEqual(psiVariable.getName(), referenceName) ||
diff --git a/java/java-psi-api/src/com/intellij/psi/infos/MethodCandidateInfo.java b/java/java-psi-api/src/com/intellij/psi/infos/MethodCandidateInfo.java
index 8404d5e822e6..c1cd36855658 100644
--- a/java/java-psi-api/src/com/intellij/psi/infos/MethodCandidateInfo.java
+++ b/java/java-psi-api/src/com/intellij/psi/infos/MethodCandidateInfo.java
@@ -132,8 +132,11 @@ public class MethodCandidateInfo extends CandidateInfo{
public boolean isTypeArgumentsApplicable() {
- PsiTypeParameter[] typeParams = getElement().getTypeParameters();
- if (myTypeArguments != null && typeParams.length != myTypeArguments.length) return false;
+ final PsiMethod psiMethod = getElement();
+ PsiTypeParameter[] typeParams = psiMethod.getTypeParameters();
+ if (myTypeArguments != null && typeParams.length != myTypeArguments.length && !PsiUtil.isLanguageLevel7OrHigher(psiMethod)){
+ return false;
+ }
PsiSubstitutor substitutor = getSubstitutor();
return GenericsUtil.isTypeArgumentsApplicable(typeParams, substitutor, getParent());
}
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/PsiSubstitutorImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/PsiSubstitutorImpl.java
index b21bc6bb3415..013ed3cd366d 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/PsiSubstitutorImpl.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/PsiSubstitutorImpl.java
@@ -159,7 +159,13 @@ public class PsiSubstitutorImpl implements PsiSubstitutor {
if (newBound instanceof PsiCapturedWildcardType) {
final PsiWildcardType wildcard = ((PsiCapturedWildcardType)newBound).getWildcard();
if (wildcardType.isExtends() != wildcard.isExtends()) {
- return wildcard.isBounded() ? PsiWildcardType.createUnbounded(wildcardType.getManager()) : newBound;
+ if (wildcard.isBounded()) {
+ return wildcardType.isExtends() ? PsiWildcardType.createExtends(wildcardType.getManager(), newBound)
+ : PsiWildcardType.createSuper(wildcardType.getManager(), newBound);
+ }
+ else {
+ return newBound;
+ }
}
if (!wildcard.isBounded()) return PsiWildcardType.createUnbounded(wildcardType.getManager());
}
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/PsiSuperMethodImplUtil.java b/java/java-psi-impl/src/com/intellij/psi/impl/PsiSuperMethodImplUtil.java
index 61d7d54c077b..70f80b470158 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/PsiSuperMethodImplUtil.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/PsiSuperMethodImplUtil.java
@@ -215,15 +215,15 @@ public class PsiSuperMethodImplUtil {
LOG.assertTrue(copy.getMethod().isValid());
map.put(signature, copy);
}
+ else if (isSuperMethod(aClass, existing, hierarchicalMethodSignature)) {
+ mergeSupers(existing, hierarchicalMethodSignature);
+ }
else if (isReturnTypeIsMoreSpecificThan(hierarchicalMethodSignature, existing) && isSuperMethod(aClass, hierarchicalMethodSignature, existing)) {
HierarchicalMethodSignatureImpl newSuper = copy(hierarchicalMethodSignature);
mergeSupers(newSuper, existing);
LOG.assertTrue(newSuper.getMethod().isValid());
map.put(signature, newSuper);
}
- else if (isSuperMethod(aClass, existing, hierarchicalMethodSignature)) {
- mergeSupers(existing, hierarchicalMethodSignature);
- }
// just drop an invalid method declaration there - to highlight accordingly
else if (!result.containsKey(signature)) {
LOG.assertTrue(hierarchicalMethodSignature.getMethod().isValid());
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting7/WrongArgsAndUnknownTypeParams.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting7/WrongArgsAndUnknownTypeParams.java
new file mode 100644
index 000000000000..5bfe17caf57c
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting7/WrongArgsAndUnknownTypeParams.java
@@ -0,0 +1,11 @@
+class TcpConnection extends ClientConnection {
+ ConnectionEventDelegate extends ClientConnection> eventDelegate;
+ {
+ eventDelegate. onDisconnect(this);
+ }
+}
+
+class ClientConnection {}
+interface ConnectionEventDelegate {
+ void onDisconnect(T t);
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/OverrideWithMoreSpecificReturn.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/OverrideWithMoreSpecificReturn.java
new file mode 100644
index 000000000000..c2f68775cbfb
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/OverrideWithMoreSpecificReturn.java
@@ -0,0 +1,15 @@
+import java.util.List;
+
+interface ExampleInterface {
+ public List exampleMethod();
+}
+
+class ExampleSuperClass {
+ public List exampleMethod() {
+ return null;
+ }
+}
+
+
+public class ExampleSubClass extends ExampleSuperClass implements ExampleInterface {
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/WildcardsBoundsIntersection.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/WildcardsBoundsIntersection.java
new file mode 100644
index 000000000000..c84c5890e8c5
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/WildcardsBoundsIntersection.java
@@ -0,0 +1,15 @@
+class NodeProperty {}
+
+class NodeType {}
+class NumberExpression extends NodeType {}
+class Node {
+ public ValueT get(NodeProperty super NodeTypeT, ValueT> prop) {
+ return null;
+ }
+}
+
+class Main {
+ public static void main(NodeProperty nval, Node extends NodeType> expr) {
+ int val = expr.get(nval);
+ }
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/refactoring/inplaceIntroduceParameter/paramNameEqMethodName.java b/java/java-tests/testData/refactoring/inplaceIntroduceParameter/paramNameEqMethodName.java
new file mode 100644
index 000000000000..8a724c88aa5b
--- /dev/null
+++ b/java/java-tests/testData/refactoring/inplaceIntroduceParameter/paramNameEqMethodName.java
@@ -0,0 +1,10 @@
+class A {
+ int f() {
+ return 0;
+ }
+
+ void m() {
+ f();
+ f();
+ }
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/refactoring/inplaceIntroduceParameter/paramNameEqMethodName_after.java b/java/java-tests/testData/refactoring/inplaceIntroduceParameter/paramNameEqMethodName_after.java
new file mode 100644
index 000000000000..7216093f6f37
--- /dev/null
+++ b/java/java-tests/testData/refactoring/inplaceIntroduceParameter/paramNameEqMethodName_after.java
@@ -0,0 +1,9 @@
+class A {
+ int f() {
+ return 0;
+ }
+
+ void m(int f) {
+ f();
+ }
+}
\ No newline at end of file
diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/GenericsHighlightingTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/GenericsHighlightingTest.java
index 8bc65e0cb36d..efd46470ee23 100644
--- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/GenericsHighlightingTest.java
+++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/GenericsHighlightingTest.java
@@ -205,6 +205,8 @@ public class GenericsHighlightingTest extends LightDaemonAnalyzerTestCase {
public void testInstanceClassInStaticContextAccess() throws Exception { doTest17Incompatibility(false); }
public void testFlattenIntersectionType() throws Exception { doTest17Incompatibility(false); }
public void testIDEA97276() throws Exception { doTest17Incompatibility(false); }
+ public void testWildcardsBoundsIntersection() throws Exception { doTest17Incompatibility(false); }
+ public void testOverrideWithMoreSpecificReturn() throws Exception { doTest17Incompatibility(false); }
public void testJavaUtilCollections_NoVerify() throws Exception {
PsiClass collectionsClass = getJavaFacade().findClass("java.util.Collections", GlobalSearchScope.moduleWithLibrariesScope(getModule()));
diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/LightAdvHighlightingJdk7Test.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/LightAdvHighlightingJdk7Test.java
index 1b5b9acab8e3..70e53c04b4b2 100644
--- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/LightAdvHighlightingJdk7Test.java
+++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/LightAdvHighlightingJdk7Test.java
@@ -160,4 +160,5 @@ public class LightAdvHighlightingJdk7Test extends LightDaemonAnalyzerTestCase {
public void testUncheckedWarningIDEA26738() throws Exception { doTest(true, false); }
public void testDefaultMethodVisibility() throws Exception { doTest(true, false); }
public void testEnclosingInstance() throws Exception { doTest(false, false); }
+ public void testWrongArgsAndUnknownTypeParams() throws Exception { doTest(false, false); }
}
diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/LossyEncodingTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/LossyEncodingTest.java
index fec6cdb4e793..bac292138b6b 100644
--- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/LossyEncodingTest.java
+++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/LossyEncodingTest.java
@@ -128,6 +128,6 @@ public class LossyEncodingTest extends LightDaemonAnalyzerTestCase {
doHighlighting();
List infos = DaemonCodeAnalyzerImpl.getFileLevelHighlights(getProject(), getFile());
HighlightInfo info = assertOneElement(infos);
- assertEquals("File was loaded in a wrong encoding: 'UTF-8'", info.description);
+ assertEquals("File was loaded in the wrong encoding: 'UTF-8'", info.description);
}
}
diff --git a/java/java-tests/testSrc/com/intellij/codeInspection/InspectionProfileTest.java b/java/java-tests/testSrc/com/intellij/codeInspection/InspectionProfileTest.java
index 35071ac99f04..409426b19c0b 100644
--- a/java/java-tests/testSrc/com/intellij/codeInspection/InspectionProfileTest.java
+++ b/java/java-tests/testSrc/com/intellij/codeInspection/InspectionProfileTest.java
@@ -255,7 +255,8 @@ public class InspectionProfileTest extends LightIdeaTestCase {
InspectionProfileEntry[] tools = profile.getInspectionTools(null);
assertTrue(tools.length > 0);
InspectionProfileEntry tool = tools[0];
- String id = tool.getShortName();
+ String id = tool.getShortName();
+ System.out.println(id);
if (profile.isToolEnabled(HighlightDisplayKey.findById(id))) {
profile.disableTool(id);
}
diff --git a/java/java-tests/testSrc/com/intellij/psi/resolve/TypeInferenceTest.java b/java/java-tests/testSrc/com/intellij/psi/resolve/TypeInferenceTest.java
index cfa1c9348144..58e71599b153 100644
--- a/java/java-tests/testSrc/com/intellij/psi/resolve/TypeInferenceTest.java
+++ b/java/java-tests/testSrc/com/intellij/psi/resolve/TypeInferenceTest.java
@@ -152,6 +152,6 @@ public class TypeInferenceTest extends Resolve15TestCase {
}
public void testBoundComposition() throws Exception {
- checkResolvesTo("java.lang.Class>");
+ checkResolvesTo("java.lang.Class super ? extends java.lang.Object>");
}
}
diff --git a/java/java-tests/testSrc/com/intellij/refactoring/InplaceIntroduceParameterTest.java b/java/java-tests/testSrc/com/intellij/refactoring/InplaceIntroduceParameterTest.java
index 97c475910e9e..b5ec296e7bc5 100644
--- a/java/java-tests/testSrc/com/intellij/refactoring/InplaceIntroduceParameterTest.java
+++ b/java/java-tests/testSrc/com/intellij/refactoring/InplaceIntroduceParameterTest.java
@@ -69,6 +69,14 @@ public class InplaceIntroduceParameterTest extends AbstractJavaInplaceIntroduceT
});
}
+ public void testParamNameEqMethodName() throws Exception {
+ doTest(new Pass() {
+ @Override
+ public void pass(AbstractInplaceIntroducer inplaceIntroducePopup) {
+ }
+ });
+ }
+
@Override
protected String getBasePath() {
return BASE_PATH;
diff --git a/java/jdkAnnotations/java/lang/annotations.xml b/java/jdkAnnotations/java/lang/annotations.xml
index 686dcd3e96c4..6a1922ae86ab 100644
--- a/java/jdkAnnotations/java/lang/annotations.xml
+++ b/java/jdkAnnotations/java/lang/annotations.xml
@@ -58,6 +58,7 @@
-
+
-
@@ -98,4 +99,7 @@
-
+ -
+
+
diff --git a/jps/jps-builders/src/META-INF/services/org.jetbrains.jps.builders.java.ExcludedJavaSourceRootProvider b/jps/jps-builders/src/META-INF/services/org.jetbrains.jps.builders.java.ExcludedJavaSourceRootProvider
new file mode 100644
index 000000000000..e398bfd69f5c
--- /dev/null
+++ b/jps/jps-builders/src/META-INF/services/org.jetbrains.jps.builders.java.ExcludedJavaSourceRootProvider
@@ -0,0 +1 @@
+org.jetbrains.jps.incremental.java.AnnotationsExcludedJavaSourceRootProvider
\ No newline at end of file
diff --git a/jps/jps-builders/src/org/jetbrains/jps/ProjectPaths.java b/jps/jps-builders/src/org/jetbrains/jps/ProjectPaths.java
index 156d9240ba6e..caa7e58a4338 100644
--- a/jps/jps-builders/src/org/jetbrains/jps/ProjectPaths.java
+++ b/jps/jps-builders/src/org/jetbrains/jps/ProjectPaths.java
@@ -21,7 +21,6 @@ import com.intellij.util.Consumer;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jps.model.JpsDummyElement;
-import org.jetbrains.jps.model.JpsProject;
import org.jetbrains.jps.model.JpsSimpleElement;
import org.jetbrains.jps.model.java.*;
import org.jetbrains.jps.model.java.compiler.ProcessorConfigProfile;
@@ -41,30 +40,25 @@ import java.util.*;
* Date: 9/30/11
*/
public class ProjectPaths {
- @NotNull
- private final JpsProject myProject;
- //private final Map>> myCachedClasspath = new HashMap>>();
-
- public ProjectPaths(@NotNull JpsProject project) {
- myProject = project;
+ private ProjectPaths() {
}
- public Collection getCompilationClasspathFiles(ModuleChunk chunk,
+ public static Collection getCompilationClasspathFiles(ModuleChunk chunk,
boolean includeTests,
final boolean excludeMainModuleOutput,
final boolean exportedOnly) {
return getClasspathFiles(chunk, JpsJavaClasspathKind.compile(includeTests), excludeMainModuleOutput, ClasspathPart.WHOLE, exportedOnly);
}
- public Collection getPlatformCompilationClasspath(ModuleChunk chunk, boolean excludeMainModuleOutput) {
+ public static Collection getPlatformCompilationClasspath(ModuleChunk chunk, boolean excludeMainModuleOutput) {
return getClasspathFiles(chunk, JpsJavaClasspathKind.compile(chunk.containsTests()), excludeMainModuleOutput, ClasspathPart.BEFORE_JDK, true);
}
- public Collection getCompilationClasspath(ModuleChunk chunk, boolean excludeMainModuleOutput) {
+ public static Collection getCompilationClasspath(ModuleChunk chunk, boolean excludeMainModuleOutput) {
return getClasspathFiles(chunk, JpsJavaClasspathKind.compile(chunk.containsTests()), excludeMainModuleOutput, ClasspathPart.AFTER_JDK, true);
}
- private Collection getClasspathFiles(ModuleChunk chunk,
+ private static Collection getClasspathFiles(ModuleChunk chunk,
JpsJavaClasspathKind kind,
final boolean excludeMainModuleOutput,
ClasspathPart classpathPart, final boolean exportedOnly) {
@@ -159,12 +153,12 @@ public class ProjectPaths {
}
@Nullable
- public File getModuleOutputDir(JpsModule module, boolean forTests) {
+ public static File getModuleOutputDir(JpsModule module, boolean forTests) {
return JpsJavaExtensionService.getInstance().getOutputDirectory(module, forTests);
}
@Nullable
- public File getAnnotationProcessorGeneratedSourcesOutputDir(JpsModule module, final boolean forTests, ProcessorConfigProfile profile) {
+ public static File getAnnotationProcessorGeneratedSourcesOutputDir(JpsModule module, final boolean forTests, ProcessorConfigProfile profile) {
final String sourceDirName = profile.getGeneratedSourcesDirectoryName(forTests);
if (profile.isOutputRelativeToContentRoot()) {
List roots = module.getContentRootsList().getUrls();
diff --git a/jps/jps-builders/src/org/jetbrains/jps/builders/java/ExcludedJavaSourceRootProvider.java b/jps/jps-builders/src/org/jetbrains/jps/builders/java/ExcludedJavaSourceRootProvider.java
index 64dbd190e72e..18b1a52a9ffb 100644
--- a/jps/jps-builders/src/org/jetbrains/jps/builders/java/ExcludedJavaSourceRootProvider.java
+++ b/jps/jps-builders/src/org/jetbrains/jps/builders/java/ExcludedJavaSourceRootProvider.java
@@ -20,6 +20,7 @@ import org.jetbrains.jps.model.module.JpsModule;
import org.jetbrains.jps.model.module.JpsModuleSourceRoot;
/**
+ *
* @author nik
*/
public abstract class ExcludedJavaSourceRootProvider {
diff --git a/jps/jps-builders/src/org/jetbrains/jps/incremental/CompileContext.java b/jps/jps-builders/src/org/jetbrains/jps/incremental/CompileContext.java
index 23d081c336d7..b878c75b3180 100644
--- a/jps/jps-builders/src/org/jetbrains/jps/incremental/CompileContext.java
+++ b/jps/jps-builders/src/org/jetbrains/jps/incremental/CompileContext.java
@@ -16,15 +16,11 @@
package org.jetbrains.jps.incremental;
import com.intellij.openapi.util.UserDataHolder;
-import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jps.ModuleChunk;
-import org.jetbrains.jps.ProjectPaths;
import org.jetbrains.jps.api.CanceledStatus;
import org.jetbrains.jps.builders.logging.BuildLoggingManager;
import org.jetbrains.jps.cmdline.ProjectDescriptor;
-import org.jetbrains.jps.model.java.compiler.ProcessorConfigProfile;
-import org.jetbrains.jps.model.module.JpsModule;
/**
* @author Eugene Zhuravlev
@@ -33,8 +29,6 @@ import org.jetbrains.jps.model.module.JpsModule;
public interface CompileContext extends UserDataHolder, MessageHandler {
ProjectDescriptor getProjectDescriptor();
- ProjectPaths getProjectPaths();
-
CompileScope getScope();
boolean isMake();
@@ -48,10 +42,6 @@ public interface CompileContext extends UserDataHolder, MessageHandler {
void removeBuildListener(BuildListener listener);
- @NotNull
- ProcessorConfigProfile getAnnotationProcessingProfile(JpsModule module);
-
-
boolean shouldDifferentiate(ModuleChunk chunk);
CanceledStatus getCancelStatus();
diff --git a/jps/jps-builders/src/org/jetbrains/jps/incremental/CompileContextImpl.java b/jps/jps-builders/src/org/jetbrains/jps/incremental/CompileContextImpl.java
index 8b1ae2062ed7..5ccf72e73312 100644
--- a/jps/jps-builders/src/org/jetbrains/jps/incremental/CompileContextImpl.java
+++ b/jps/jps-builders/src/org/jetbrains/jps/incremental/CompileContextImpl.java
@@ -18,10 +18,8 @@ package org.jetbrains.jps.incremental;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.UserDataHolderBase;
import com.intellij.util.EventDispatcher;
-import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jps.ModuleChunk;
-import org.jetbrains.jps.ProjectPaths;
import org.jetbrains.jps.api.CanceledStatus;
import org.jetbrains.jps.builders.java.JavaModuleBuildTargetType;
import org.jetbrains.jps.builders.logging.BuildLoggingManager;
@@ -30,10 +28,6 @@ import org.jetbrains.jps.incremental.messages.BuildMessage;
import org.jetbrains.jps.incremental.messages.FileDeletedEvent;
import org.jetbrains.jps.incremental.messages.FileGeneratedEvent;
import org.jetbrains.jps.incremental.messages.ProgressMessage;
-import org.jetbrains.jps.model.java.JpsJavaExtensionService;
-import org.jetbrains.jps.model.java.compiler.JpsJavaCompilerConfiguration;
-import org.jetbrains.jps.model.java.compiler.ProcessorConfigProfile;
-import org.jetbrains.jps.model.module.JpsModule;
import java.util.*;
@@ -49,14 +43,12 @@ public class CompileContextImpl extends UserDataHolderBase implements CompileCon
private final MessageHandler myDelegateMessageHandler;
private final Set myNonIncrementalModules = new HashSet();
- private final ProjectPaths myProjectPaths;
private volatile long myCompilationStartStamp;
private final ProjectDescriptor myProjectDescriptor;
private final Map myBuilderParams;
private final CanceledStatus myCancelStatus;
private volatile float myDone = -1.0f;
private EventDispatcher myListeners = EventDispatcher.create(BuildListener.class);
- private Map myAnnotationProcessingProfileMap;
public CompileContextImpl(CompileScope scope,
ProjectDescriptor pd, boolean isMake,
@@ -72,7 +64,6 @@ public class CompileContextImpl extends UserDataHolderBase implements CompileCon
myIsProjectRebuild = isProjectRebuild;
myIsMake = !isProjectRebuild && isMake;
myDelegateMessageHandler = delegateMessageHandler;
- myProjectPaths = new ProjectPaths(pd.getProject());
}
@Override
@@ -85,11 +76,6 @@ public class CompileContextImpl extends UserDataHolderBase implements CompileCon
myCompilationStartStamp = System.currentTimeMillis();
}
- @Override
- public ProjectPaths getProjectPaths() {
- return myProjectPaths;
- }
-
@Override
public boolean isMake() {
return myIsMake;
@@ -121,34 +107,6 @@ public class CompileContextImpl extends UserDataHolderBase implements CompileCon
myListeners.removeListener(listener);
}
- @Override
- @NotNull
- public ProcessorConfigProfile getAnnotationProcessingProfile(JpsModule module) {
- final JpsJavaCompilerConfiguration compilerConfig = JpsJavaExtensionService.getInstance().getOrCreateCompilerConfiguration(
- getProjectDescriptor().getProject());
- Map map = myAnnotationProcessingProfileMap;
- if (map == null) {
- map = new HashMap();
- final Map namesMap = new HashMap();
- for (JpsModule m : getProjectDescriptor().getProject().getModules()) {
- namesMap.put(m.getName(), m);
- }
- if (!namesMap.isEmpty()) {
- for (ProcessorConfigProfile profile : compilerConfig.getAnnotationProcessingConfigurations()) {
- for (String name : profile.getModuleNames()) {
- final JpsModule mod = namesMap.get(name);
- if (mod != null) {
- map.put(mod, profile);
- }
- }
- }
- }
- myAnnotationProcessingProfileMap = map;
- }
- final ProcessorConfigProfile profile = map.get(module);
- return profile != null? profile : compilerConfig.getDefaultAnnotationProcessingConfiguration();
- }
-
@Override
public void markNonIncremental(ModuleBuildTarget target) {
if (!target.isTests()) {
diff --git a/jps/jps-builders/src/org/jetbrains/jps/incremental/ModuleBuildTarget.java b/jps/jps-builders/src/org/jetbrains/jps/incremental/ModuleBuildTarget.java
index 42be4576b4dd..e27534b98d40 100644
--- a/jps/jps-builders/src/org/jetbrains/jps/incremental/ModuleBuildTarget.java
+++ b/jps/jps-builders/src/org/jetbrains/jps/incremental/ModuleBuildTarget.java
@@ -21,6 +21,7 @@ import com.intellij.util.SmartList;
import gnu.trove.THashSet;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
+import org.jetbrains.jps.ProjectPaths;
import org.jetbrains.jps.builders.*;
import org.jetbrains.jps.builders.java.ExcludedJavaSourceRootProvider;
import org.jetbrains.jps.builders.java.JavaModuleBuildTargetType;
@@ -69,9 +70,11 @@ public final class ModuleBuildTarget extends JVMModuleBuildTarget allProfiles =
- JpsJavaExtensionService.getInstance().getOrCreateCompilerConfiguration(model.getProject()).getAnnotationProcessingConfigurations();
- ProcessorConfigProfile profile = null;
- final String moduleName = getModule().getName();
- for (ProcessorConfigProfile p : allProfiles) {
- if (p.getModuleNames().contains(moduleName)) {
- if (p.isEnabled()) {
- profile = p;
- }
- break;
- }
- }
- return profile;
- }
-
@NotNull
@Override
public String getPresentableName() {
diff --git a/jps/jps-builders/src/org/jetbrains/jps/incremental/instrumentation/ClassProcessingBuilder.java b/jps/jps-builders/src/org/jetbrains/jps/incremental/instrumentation/ClassProcessingBuilder.java
index 475be1ed2564..8131cfd62739 100644
--- a/jps/jps-builders/src/org/jetbrains/jps/incremental/instrumentation/ClassProcessingBuilder.java
+++ b/jps/jps-builders/src/org/jetbrains/jps/incremental/instrumentation/ClassProcessingBuilder.java
@@ -79,11 +79,9 @@ public abstract class ClassProcessingBuilder extends ModuleLevelBuilder {
try {
InstrumentationClassFinder finder = CLASS_FINDER.get(context); // try using shared finder
if (finder == null) {
- final ProjectPaths paths = context.getProjectPaths();
- final Collection platformCp = paths.getPlatformCompilationClasspath(chunk, false);
-
+ final Collection platformCp = ProjectPaths.getPlatformCompilationClasspath(chunk, false);
final Collection classpath = new ArrayList();
- classpath.addAll(paths.getCompilationClasspath(chunk, false));
+ classpath.addAll(ProjectPaths.getCompilationClasspath(chunk, false));
classpath.addAll(ProjectPaths.getSourceRootsWithDependents(chunk).keySet());
finder = createInstrumentationClassFinder(platformCp, classpath, outputConsumer);
diff --git a/jps/jps-builders/src/org/jetbrains/jps/incremental/instrumentation/RmiStubsGenerator.java b/jps/jps-builders/src/org/jetbrains/jps/incremental/instrumentation/RmiStubsGenerator.java
index f4322364aca1..02c5cc1c1c30 100644
--- a/jps/jps-builders/src/org/jetbrains/jps/incremental/instrumentation/RmiStubsGenerator.java
+++ b/jps/jps-builders/src/org/jetbrains/jps/incremental/instrumentation/RmiStubsGenerator.java
@@ -30,6 +30,7 @@ import gnu.trove.THashMap;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jps.ModuleChunk;
+import org.jetbrains.jps.ProjectPaths;
import org.jetbrains.jps.incremental.*;
import org.jetbrains.jps.incremental.messages.BuildMessage;
import org.jetbrains.jps.incremental.messages.CompilerMessage;
@@ -118,7 +119,7 @@ public class RmiStubsGenerator extends ClassProcessingBuilder {
OutputConsumer outputConsumer) {
ExitCode exitCode = ExitCode.NOTHING_DONE;
- final Collection classpath = context.getProjectPaths().getCompilationClasspath(chunk, false);
+ final Collection classpath = ProjectPaths.getCompilationClasspath(chunk, false);
final StringBuilder buf = new StringBuilder();
for (File file : classpath) {
if (buf.length() > 0) {
diff --git a/jps/jps-builders/src/org/jetbrains/jps/incremental/java/AnnotationsExcludedJavaSourceRootProvider.java b/jps/jps-builders/src/org/jetbrains/jps/incremental/java/AnnotationsExcludedJavaSourceRootProvider.java
new file mode 100644
index 000000000000..4634be644d28
--- /dev/null
+++ b/jps/jps-builders/src/org/jetbrains/jps/incremental/java/AnnotationsExcludedJavaSourceRootProvider.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2000-2012 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jetbrains.jps.incremental.java;
+
+import com.intellij.openapi.util.io.FileUtil;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.jps.ProjectPaths;
+import org.jetbrains.jps.builders.java.ExcludedJavaSourceRootProvider;
+import org.jetbrains.jps.model.java.JavaSourceRootType;
+import org.jetbrains.jps.model.java.JpsJavaExtensionService;
+import org.jetbrains.jps.model.java.compiler.JpsJavaCompilerConfiguration;
+import org.jetbrains.jps.model.java.compiler.ProcessorConfigProfile;
+import org.jetbrains.jps.model.module.JpsModule;
+import org.jetbrains.jps.model.module.JpsModuleSourceRoot;
+
+import java.io.File;
+
+/**
+ * @author Eugene Zhuravlev
+ * Date: 12/14/12
+ */
+public class AnnotationsExcludedJavaSourceRootProvider extends ExcludedJavaSourceRootProvider{
+ @Override
+ public boolean isExcludedFromCompilation(@NotNull JpsModule module, @NotNull JpsModuleSourceRoot root) {
+ final JpsJavaCompilerConfiguration compilerConfig = JpsJavaExtensionService.getInstance().getOrCreateCompilerConfiguration(module.getProject());
+ final ProcessorConfigProfile profile = compilerConfig.getAnnotationProcessingProfile(module);
+ if (!profile.isEnabled()) {
+ return false;
+ }
+
+ final File outputDir =
+ ProjectPaths.getAnnotationProcessorGeneratedSourcesOutputDir(module, JavaSourceRootType.TEST_SOURCE == root.getRootType(), profile);
+
+ return outputDir != null && FileUtil.filesEqual(outputDir, root.getFile());
+ }
+}
diff --git a/jps/jps-builders/src/org/jetbrains/jps/incremental/java/JavaBuilder.java b/jps/jps-builders/src/org/jetbrains/jps/incremental/java/JavaBuilder.java
index 73fae619652e..b4870b523ff3 100644
--- a/jps/jps-builders/src/org/jetbrains/jps/incremental/java/JavaBuilder.java
+++ b/jps/jps-builders/src/org/jetbrains/jps/incremental/java/JavaBuilder.java
@@ -62,6 +62,7 @@ import java.net.ServerSocket;
import java.util.*;
import java.util.concurrent.Executor;
import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicReference;
/**
* @author Eugene Zhuravlev
@@ -74,6 +75,8 @@ public class JavaBuilder extends ModuleLevelBuilder {
public static final boolean USE_EMBEDDED_JAVAC = System.getProperty(GlobalOptions.USE_EXTERNAL_JAVAC_OPTION) == null;
private static final Key JAVA_COMPILER_VERSION_KEY = Key.create("_java_compiler_version_");
private static final Key IS_ENABLED = Key.create("_java_compiler_enabled_");
+ private static final Key> COMPILER_VERSION_INFO = Key.create("_java_compiler_version_info_");
+
private static final Set FILTERED_OPTIONS = new HashSet(Arrays.asList(
"-target"
));
@@ -130,10 +133,7 @@ public class JavaBuilder extends ModuleLevelBuilder {
else if (isEclipse) {
messageText = "Using eclipse compiler to compile java sources";
}
- if (messageText != null) {
- LOG.info(messageText);
- context.processMessage(new CompilerMessage("", BuildMessage.Kind.INFO, messageText));
- }
+ COMPILER_VERSION_INFO.set(context, new AtomicReference(messageText));
}
public ExitCode build(final CompileContext context,
@@ -207,12 +207,11 @@ public class JavaBuilder extends ModuleLevelBuilder {
return exitCode;
}
- final ProjectPaths paths = context.getProjectPaths();
final ProjectDescriptor pd = context.getProjectDescriptor();
JavaBuilderUtil.ensureModuleHasJdk(chunk.representativeTarget().getModule(), context, BUILDER_NAME);
- final Collection classpath = paths.getCompilationClasspath(chunk, false/*context.isProjectRebuild()*/);
- final Collection platformCp = paths.getPlatformCompilationClasspath(chunk, false/*context.isProjectRebuild()*/);
+ final Collection classpath = ProjectPaths.getCompilationClasspath(chunk, false/*context.isProjectRebuild()*/);
+ final Collection platformCp = ProjectPaths.getPlatformCompilationClasspath(chunk, false/*context.isProjectRebuild()*/);
// begin compilation round
final DiagnosticSink diagnosticSink = new DiagnosticSink(context);
@@ -221,6 +220,12 @@ public class JavaBuilder extends ModuleLevelBuilder {
final OutputFilesSink outputSink = new OutputFilesSink(context, outputConsumer, mappingsCallback, chunk.getName());
try {
if (hasSourcesToCompile) {
+ final AtomicReference ref = COMPILER_VERSION_INFO.get(context);
+ final String versionInfo = ref.getAndSet(null); // display compiler version info only once per compile session
+ if (versionInfo != null) {
+ LOG.info(versionInfo);
+ context.processMessage(new CompilerMessage("", BuildMessage.Kind.INFO, versionInfo));
+ }
exitCode = ExitCode.OK;
final Set srcPath = new HashSet();
@@ -291,14 +296,18 @@ public class JavaBuilder extends ModuleLevelBuilder {
final TasksCounter counter = new TasksCounter();
COUNTER_KEY.set(context, counter);
+ final JpsJavaExtensionService javaExt = JpsJavaExtensionService.getInstance();
+ final JpsJavaCompilerConfiguration compilerConfig = javaExt.getCompilerConfiguration(context.getProjectDescriptor().getProject());
+ assert compilerConfig != null;
+
final Set modules = chunk.getModules();
ProcessorConfigProfile profile = null;
if (modules.size() == 1) {
- profile = context.getAnnotationProcessingProfile(modules.iterator().next());
+ final JpsModule module = modules.iterator().next();
+ profile = compilerConfig.getAnnotationProcessingProfile(module);
}
else {
// perform cycle-related validations
- final JpsJavaExtensionService javaExt = JpsJavaExtensionService.getInstance();
Pair pair = null;
for (JpsModule module : modules) {
final LanguageLevel moduleLevel = javaExt.getLanguageLevel(module);
@@ -316,7 +325,7 @@ public class JavaBuilder extends ModuleLevelBuilder {
// check that all chunk modules are excluded from annotation processing
for (JpsModule module : modules) {
- final ProcessorConfigProfile prof = context.getAnnotationProcessingProfile(module);
+ final ProcessorConfigProfile prof = compilerConfig.getAnnotationProcessingProfile(module);
if (prof.isEnabled()) {
final String message = "Annotation processing is not supported for module cycles. Please ensure that all modules from cycle [" + chunk.getName() + "] are excluded from annotation processing";
diagnosticSink.report(new PlainMessageDiagnostic(Diagnostic.Kind.ERROR, message));
@@ -328,6 +337,9 @@ public class JavaBuilder extends ModuleLevelBuilder {
final Map> outs = buildOutputDirectoriesMap(context, chunk);
final List options = getCompilationOptions(context, chunk, profile);
final ClassProcessingConsumer classesConsumer = new ClassProcessingConsumer(context, outputSink);
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Compiling chunk [" + chunk.getName() + "] with options: \"" + StringUtil.join(options, " ") + "\"");
+ }
try {
final boolean rc;
if (USE_EMBEDDED_JAVAC) {
@@ -581,16 +593,17 @@ public class JavaBuilder extends ModuleLevelBuilder {
options.add(processorsPath == null? "" : FileUtil.toSystemDependentName(processorsPath.trim()));
}
- for (String procFQName : profile.getProcessors()) {
+ final Set processors = profile.getProcessors();
+ if (!processors.isEmpty()) {
options.add("-processor");
- options.add(procFQName);
+ options.add(StringUtil.join(processors, ","));
}
for (Map.Entry optionEntry : profile.getProcessorOptions().entrySet()) {
options.add("-A" + optionEntry.getKey() + "=" + optionEntry.getValue());
}
- final File srcOutput = context.getProjectPaths().getAnnotationProcessorGeneratedSourcesOutputDir(
+ final File srcOutput = ProjectPaths.getAnnotationProcessorGeneratedSourcesOutputDir(
chunk.getModules().iterator().next(), chunk.containsTests(), profile
);
if (srcOutput != null) {
diff --git a/jps/jps-builders/testSrc/org/jetbrains/jps/builders/ModuleClasspathTest.groovy b/jps/jps-builders/testSrc/org/jetbrains/jps/builders/ModuleClasspathTest.groovy
index 55f8a86d4170..6c33c437cfd7 100644
--- a/jps/jps-builders/testSrc/org/jetbrains/jps/builders/ModuleClasspathTest.groovy
+++ b/jps/jps-builders/testSrc/org/jetbrains/jps/builders/ModuleClasspathTest.groovy
@@ -59,18 +59,14 @@ public class ModuleClasspathTest extends JpsRebuildTestCase {
public void testCompilationClasspath() {
ModuleChunk chunk = createChunk('main')
assertClasspath(["util/lib/exported.jar", "out/production/util", "/jdk.jar"],
- getPathsList(getProjectPaths().getPlatformCompilationClasspath(chunk, true)))
+ getPathsList(ProjectPaths.getPlatformCompilationClasspath(chunk, true)))
assertClasspath(["main/lib/service.jar"],
- getPathsList(getProjectPaths().getCompilationClasspath(chunk, true)))
- }
-
- private ProjectPaths getProjectPaths() {
- return new ProjectPaths(myProject)
+ getPathsList(ProjectPaths.getCompilationClasspath(chunk, true)))
}
private def assertClasspath(String moduleName, boolean includeTests, List expected) {
ModuleChunk chunk = createChunk(moduleName)
- final List classpath = getPathsList(new ProjectPaths(myProject).getCompilationClasspathFiles(chunk, includeTests, true, true))
+ final List classpath = getPathsList(new ProjectPaths().getCompilationClasspathFiles(chunk, includeTests, true, true))
assertClasspath(expected, toSystemIndependentPaths(classpath))
}
diff --git a/jps/model-api/src/org/jetbrains/jps/model/java/compiler/JpsJavaCompilerConfiguration.java b/jps/model-api/src/org/jetbrains/jps/model/java/compiler/JpsJavaCompilerConfiguration.java
index 04c15923e086..8aaf77b1687d 100644
--- a/jps/model-api/src/org/jetbrains/jps/model/java/compiler/JpsJavaCompilerConfiguration.java
+++ b/jps/model-api/src/org/jetbrains/jps/model/java/compiler/JpsJavaCompilerConfiguration.java
@@ -18,6 +18,7 @@ package org.jetbrains.jps.model.java.compiler;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jps.model.JpsElement;
+import org.jetbrains.jps.model.module.JpsModule;
import java.util.Collection;
import java.util.List;
@@ -36,10 +37,21 @@ public interface JpsJavaCompilerConfiguration extends JpsElement {
JpsCompilerExcludes getCompilerExcludes();
@NotNull
- ProcessorConfigProfile getDefaultAnnotationProcessingConfiguration();
+ ProcessorConfigProfile getDefaultAnnotationProcessingProfile();
ProcessorConfigProfile addAnnotationProcessingProfile();
+
+ /**
+ * @return a list of currently configured profiles excluding default one
+ */
@NotNull
- Collection getAnnotationProcessingConfigurations();
+ Collection getAnnotationProcessingProfiles();
+
+ /**
+ * @param module
+ * @return annotation profile with which the given module is associated
+ */
+ @NotNull
+ ProcessorConfigProfile getAnnotationProcessingProfile(JpsModule module);
void addResourcePattern(String pattern);
List getResourcePatterns();
diff --git a/jps/model-impl/src/org/jetbrains/jps/model/java/impl/compiler/JpsJavaCompilerConfigurationImpl.java b/jps/model-impl/src/org/jetbrains/jps/model/java/impl/compiler/JpsJavaCompilerConfigurationImpl.java
index 65851a20a549..12d01689ea0a 100644
--- a/jps/model-impl/src/org/jetbrains/jps/model/java/impl/compiler/JpsJavaCompilerConfigurationImpl.java
+++ b/jps/model-impl/src/org/jetbrains/jps/model/java/impl/compiler/JpsJavaCompilerConfigurationImpl.java
@@ -24,6 +24,7 @@ import org.jetbrains.jps.model.java.compiler.JpsCompilerExcludes;
import org.jetbrains.jps.model.java.compiler.JpsJavaCompilerConfiguration;
import org.jetbrains.jps.model.java.compiler.JpsJavaCompilerOptions;
import org.jetbrains.jps.model.java.compiler.ProcessorConfigProfile;
+import org.jetbrains.jps.model.module.JpsModule;
import java.util.*;
@@ -42,6 +43,7 @@ public class JpsJavaCompilerConfigurationImpl extends JpsCompositeElementBase myModulesByteCodeTargetLevels = new HashMap();
private Map myCompilerOptions = new HashMap();
private String myJavaCompilerId = "Javac";
+ private Map myAnnotationProcessingProfileMap;
public JpsJavaCompilerConfigurationImpl() {
}
@@ -84,13 +86,13 @@ public class JpsJavaCompilerConfigurationImpl extends JpsCompositeElementBase getAnnotationProcessingConfigurations() {
+ public Collection getAnnotationProcessingProfiles() {
return myAnnotationProcessingProfiles;
}
@@ -163,4 +165,30 @@ public class JpsJavaCompilerConfigurationImpl extends JpsCompositeElementBase map = myAnnotationProcessingProfileMap;
+ if (map == null) {
+ map = new HashMap();
+ final Map namesMap = new HashMap();
+ for (JpsModule m : module.getProject().getModules()) {
+ namesMap.put(m.getName(), m);
+ }
+ if (!namesMap.isEmpty()) {
+ for (ProcessorConfigProfile profile : getAnnotationProcessingProfiles()) {
+ for (String name : profile.getModuleNames()) {
+ final JpsModule mod = namesMap.get(name);
+ if (mod != null) {
+ map.put(mod, profile);
+ }
+ }
+ }
+ }
+ myAnnotationProcessingProfileMap = map;
+ }
+ final ProcessorConfigProfile profile = map.get(module);
+ return profile != null? profile : getDefaultAnnotationProcessingProfile();
+ }
}
diff --git a/jps/model-serialization/src/org/jetbrains/jps/model/serialization/java/compiler/AnnotationProcessorProfileSerializer.java b/jps/model-serialization/src/org/jetbrains/jps/model/serialization/java/compiler/AnnotationProcessorProfileSerializer.java
index 4760cfb0d247..5fcc0b41d73c 100644
--- a/jps/model-serialization/src/org/jetbrains/jps/model/serialization/java/compiler/AnnotationProcessorProfileSerializer.java
+++ b/jps/model-serialization/src/org/jetbrains/jps/model/serialization/java/compiler/AnnotationProcessorProfileSerializer.java
@@ -68,7 +68,7 @@ public class AnnotationProcessorProfileSerializer {
profile.clearProcessors();
for (Object procElement : element.getChildren("processor")) {
final String name = ((Element)procElement).getAttributeValue(NAME);
- if (StringUtil.isEmptyOrSpaces(name)) {
+ if (!StringUtil.isEmptyOrSpaces(name)) {
profile.addProcessor(name);
}
}
diff --git a/jps/model-serialization/src/org/jetbrains/jps/model/serialization/java/compiler/JpsJavaCompilerConfigurationSerializer.java b/jps/model-serialization/src/org/jetbrains/jps/model/serialization/java/compiler/JpsJavaCompilerConfigurationSerializer.java
index 253f9434225f..b5cefb3b8b06 100644
--- a/jps/model-serialization/src/org/jetbrains/jps/model/serialization/java/compiler/JpsJavaCompilerConfigurationSerializer.java
+++ b/jps/model-serialization/src/org/jetbrains/jps/model/serialization/java/compiler/JpsJavaCompilerConfigurationSerializer.java
@@ -80,7 +80,7 @@ public class JpsJavaCompilerConfigurationSerializer extends JpsProjectExtensionS
for (Element profileTag : profiles) {
boolean isDefault = Boolean.parseBoolean(profileTag.getAttributeValue("default"));
if (isDefault) {
- AnnotationProcessorProfileSerializer.readExternal(configuration.getDefaultAnnotationProcessingConfiguration(), profileTag);
+ AnnotationProcessorProfileSerializer.readExternal(configuration.getDefaultAnnotationProcessingProfile(), profileTag);
}
else {
AnnotationProcessorProfileSerializer.readExternal(configuration.addAnnotationProcessingProfile(), profileTag);
diff --git a/jps/model-serialization/testSrc/org/jetbrains/jps/model/serialization/JpsCompilerConfigurationTest.java b/jps/model-serialization/testSrc/org/jetbrains/jps/model/serialization/JpsCompilerConfigurationTest.java
index b39b76f536c2..654f349a96a2 100644
--- a/jps/model-serialization/testSrc/org/jetbrains/jps/model/serialization/JpsCompilerConfigurationTest.java
+++ b/jps/model-serialization/testSrc/org/jetbrains/jps/model/serialization/JpsCompilerConfigurationTest.java
@@ -38,7 +38,7 @@ public class JpsCompilerConfigurationTest extends JpsSerializationTestCase {
assertNotNull(configuration);
assertFalse(configuration.isClearOutputDirectoryOnRebuild());
assertFalse(configuration.isAddNotNullAssertions());
- ProcessorConfigProfile defaultProfile = configuration.getDefaultAnnotationProcessingConfiguration();
+ ProcessorConfigProfile defaultProfile = configuration.getDefaultAnnotationProcessingProfile();
assertTrue(defaultProfile.isEnabled());
assertFalse(defaultProfile.isObtainProcessorsFromClasspath());
assertEquals(FileUtil.toSystemDependentName(JpsPathUtil.urlToPath(getUrl("src"))), defaultProfile.getProcessorPath());
diff --git a/platform/core-api/src/com/intellij/openapi/vfs/CharsetToolkit.java b/platform/core-api/src/com/intellij/openapi/vfs/CharsetToolkit.java
index 43df4d7a20a3..bbb4e3ed2eca 100644
--- a/platform/core-api/src/com/intellij/openapi/vfs/CharsetToolkit.java
+++ b/platform/core-api/src/com/intellij/openapi/vfs/CharsetToolkit.java
@@ -78,6 +78,9 @@ public class CharsetToolkit {
public static final Charset UTF8_CHARSET = Charset.forName(UTF8);
public static final Charset UTF_16LE_CHARSET = Charset.forName("UTF-16LE");
public static final Charset UTF_16BE_CHARSET = Charset.forName("UTF-16BE");
+ public static final Charset UTF_32BE_CHARSET = Charset.forName("UTF-32BE");
+ public static final Charset UTF_32LE_CHARSET = Charset.forName("UTF-32LE");
+ public static final Charset UTF_16_CHARSET = Charset.forName("UTF-16");
private final byte[] buffer;
private final Charset defaultCharset;
@@ -86,12 +89,16 @@ public class CharsetToolkit {
public static final byte[] UTF8_BOM = {0xffffffef, 0xffffffbb, 0xffffffbf, };
public static final byte[] UTF16LE_BOM = {-1, -2, };
public static final byte[] UTF16BE_BOM = {-2, -1, };
+ public static final byte[] UTF32BE_BOM = {0, 0, -2, -1, };
+ public static final byte[] UTF32LE_BOM = {-1, -2, 0, 0 };
@NonNls public static final String FILE_ENCODING_PROPERTY = "file.encoding";
@NonNls private static final Map CHARSET_TO_BOM = new THashMap(2);
static {
CHARSET_TO_BOM.put(UTF_16LE_CHARSET, UTF16LE_BOM);
CHARSET_TO_BOM.put(UTF_16BE_CHARSET, UTF16BE_BOM);
+ CHARSET_TO_BOM.put(UTF_32BE_CHARSET, UTF32BE_BOM);
+ CHARSET_TO_BOM.put(UTF_32LE_CHARSET, UTF32LE_BOM);
}
/**
@@ -320,6 +327,8 @@ public class CharsetToolkit {
@Nullable
public static Charset guessFromBOM(@NotNull byte[] buffer) {
if (hasUTF8Bom(buffer)) return UTF8_CHARSET;
+ if (hasUTF32BEBom(buffer)) return UTF_32BE_CHARSET;
+ if (hasUTF32LEBom(buffer)) return UTF_32LE_CHARSET;
if (hasUTF16LEBom(buffer)) return UTF_16LE_CHARSET;
if (hasUTF16BEBom(buffer)) return UTF_16BE_CHARSET;
@@ -456,6 +465,12 @@ public class CharsetToolkit {
public static boolean hasUTF16BEBom(@NotNull byte[] bom) {
return ArrayUtil.startsWith(bom, UTF16BE_BOM);
}
+ public static boolean hasUTF32BEBom(@NotNull byte[] bom) {
+ return ArrayUtil.startsWith(bom, UTF32BE_BOM);
+ }
+ public static boolean hasUTF32LEBom(@NotNull byte[] bom) {
+ return ArrayUtil.startsWith(bom, UTF32LE_BOM);
+ }
/**
* Retrieves all the available Charsets on the platform,
@@ -483,6 +498,12 @@ public class CharsetToolkit {
if (charset != null && charset.name().contains(UTF8) && hasUTF8Bom(content)) {
return UTF8_BOM.length;
}
+ if (hasUTF32BEBom(content)) {
+ return UTF32BE_BOM.length;
+ }
+ if (hasUTF32BEBom(content)) {
+ return UTF32BE_BOM.length;
+ }
if (hasUTF16LEBom(content)) {
return UTF16LE_BOM.length;
}
@@ -519,37 +540,94 @@ public class CharsetToolkit {
return charset;
}
+ private static final byte FF = (byte)0xff;
+ private static final byte FE = (byte)0xfe;
+ private static final byte EF = (byte)0xef;
+ private static final byte BB = (byte)0xbb;
+ private static final byte BF = (byte)0xbf;
@NotNull
public static InputStream inputStreamSkippingBOM(@NotNull InputStream stream) throws IOException {
assert stream.markSupported() :stream;
- stream.mark(3);
+ stream.mark(4);
boolean mustReset = true;
try {
int ret = stream.read();
if (ret == -1) {
- return stream;
+ return stream; // no bom
}
byte b0 = (byte)ret;
- if (b0 != UTF8_BOM[0] && b0 != UTF16LE_BOM[0] && b0 != UTF16BE_BOM[0]) return stream;
+ if (b0 != EF && b0 != FF && b0 != FE && b0 != 0) return stream; // no bom
ret = stream.read();
if (ret == -1) {
- return stream;
+ return stream; // no bom
}
byte b1 = (byte)ret;
- if (b0 == UTF16LE_BOM[0] && b1 == UTF16LE_BOM[1]) { mustReset = false; return stream; }
- if (b0 == UTF16BE_BOM[0] && b1 == UTF16BE_BOM[1]) { mustReset = false; return stream; }
- if (b0 != UTF8_BOM[0] || b1 != UTF8_BOM[1]) {
+ if (b0 == FF && b1 == FE) {
+ stream.mark(2);
+ ret = stream.read();
+ if (ret == -1) {
+ return stream; // utf-16 LE
+ }
+ byte b2 = (byte)ret;
+ if (b2 != 0) {
+ return stream; // utf-16 LE
+ }
+ ret = stream.read();
+ if (ret == -1) {
+ return stream;
+ }
+ byte b3 = (byte)ret;
+ if (b3 != 0) {
+ return stream; // utf-16 LE
+ }
+
+ // utf-32 LE
+ mustReset = false;
+ return stream;
+ }
+ if (b0 == FE && b1 == FF) {
+ mustReset = false;
+ return stream; // utf-16 BE
+ }
+ if (b0 == EF && b1 == BB) {
+ ret = stream.read();
+ if (ret == -1) {
+ return stream; // no bom
+ }
+ byte b2 = (byte)ret;
+ if (b2 == BF) {
+ mustReset = false;
+ return stream; // utf-8 bom
+ }
+
+ // no bom
return stream;
}
- ret = stream.read();
- if (ret == -1) {
- return stream;
- }
- byte b2 = (byte)ret;
- if (b2 == UTF8_BOM[2]) { mustReset = false; return stream; }
+ if (b0 == 0 && b1 == 0) {
+ ret = stream.read();
+ if (ret == -1) {
+ return stream; // no bom
+ }
+ byte b2 = (byte)ret;
+ if (b2 != FE) {
+ return stream; // no bom
+ }
+ ret = stream.read();
+ if (ret == -1) {
+ return stream; // no bom
+ }
+ byte b3 = (byte)ret;
+ if (b3 != FF) {
+ return stream; // no bom
+ }
+ mustReset = false;
+ return stream; // UTF-32 BE
+ }
+
+ // no bom
return stream;
}
finally {
diff --git a/platform/core-api/src/com/intellij/openapi/vfs/VirtualFile.java b/platform/core-api/src/com/intellij/openapi/vfs/VirtualFile.java
index d2608239d3bf..282ba42ee492 100644
--- a/platform/core-api/src/com/intellij/openapi/vfs/VirtualFile.java
+++ b/platform/core-api/src/com/intellij/openapi/vfs/VirtualFile.java
@@ -495,8 +495,8 @@ public abstract class VirtualFile extends UserDataHolderBase implements Modifica
if (Comparing.equal(charset, old)) return;
byte[] bom = charset == null ? null : CharsetToolkit.getBom(charset);
byte[] existingBOM = getBOM();
- if (bom == null && charset != null && CharsetToolkit.canHaveBom(charset, existingBOM)) {
- bom = existingBOM;
+ if (bom == null && charset != null) {
+ bom = CharsetToolkit.canHaveBom(charset, existingBOM) ? existingBOM : null;
}
setBOM(bom);
diff --git a/platform/core-impl/src/com/intellij/openapi/fileEditor/impl/LoadTextUtil.java b/platform/core-impl/src/com/intellij/openapi/fileEditor/impl/LoadTextUtil.java
index f85dd78ec18d..f846f677e78c 100644
--- a/platform/core-impl/src/com/intellij/openapi/fileEditor/impl/LoadTextUtil.java
+++ b/platform/core-impl/src/com/intellij/openapi/fileEditor/impl/LoadTextUtil.java
@@ -34,7 +34,8 @@ import com.intellij.util.text.CharArrayUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
-import java.io.*;
+import java.io.IOException;
+import java.io.OutputStream;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.charset.Charset;
@@ -142,28 +143,33 @@ public final class LoadTextUtil {
}
@Nullable("null means no luck, otherwise it's tuple(guessed encoding, hint about content if was unable to guess, BOM)")
- public static Trinity guessFromContent(VirtualFile virtualFile, byte[] content, int length) {
+ public static Trinity guessFromContent(@NotNull VirtualFile virtualFile, @NotNull byte[] content, int length) {
EncodingRegistry settings = EncodingRegistry.getInstance();
boolean shouldGuess = settings != null && settings.isUseUTFGuessing(virtualFile);
CharsetToolkit toolkit = shouldGuess ? new CharsetToolkit(content, EncodingRegistry.getInstance().getDefaultCharset()) : null;
- setCharsetWasDetectedFromBytes(virtualFile, false);
- if (shouldGuess) {
- toolkit.setEnforce8Bit(true);
- Charset charset = toolkit.guessFromBOM();
- if (charset != null) {
- setCharsetWasDetectedFromBytes(virtualFile, true);
- byte[] bom = CharsetToolkit.getBom(charset);
- if (bom == null) bom = CharsetToolkit.UTF8_BOM;
- return Trinity.create(charset, null, bom);
+ String detectedFromBytes = null;
+ try {
+ if (shouldGuess) {
+ toolkit.setEnforce8Bit(true);
+ Charset charset = toolkit.guessFromBOM();
+ if (charset != null) {
+ detectedFromBytes = "auto-detected from BOM";
+ byte[] bom = CharsetToolkit.getBom(charset);
+ if (bom == null) bom = CharsetToolkit.UTF8_BOM;
+ return Trinity.create(charset, null, bom);
+ }
+ CharsetToolkit.GuessedEncoding guessed = toolkit.guessFromContent(length);
+ if (guessed == CharsetToolkit.GuessedEncoding.VALID_UTF8) {
+ detectedFromBytes = "auto-detected from bytes";
+ return Trinity.create(CharsetToolkit.UTF8_CHARSET, guessed, null); //UTF detected, ignore all directives
+ }
+ return Trinity.create(null, guessed,null);
}
- CharsetToolkit.GuessedEncoding guessed = toolkit.guessFromContent(length);
- if (guessed == CharsetToolkit.GuessedEncoding.VALID_UTF8) {
- setCharsetWasDetectedFromBytes(virtualFile, true);
- return Trinity.create(CharsetToolkit.UTF8_CHARSET,null,null); //UTF detected, ignore all directives
- }
- return Trinity.create(null, guessed,null);
+ return null;
+ }
+ finally {
+ setCharsetWasDetectedFromBytes(virtualFile, detectedFromBytes);
}
- return null;
}
@NotNull
@@ -172,11 +178,9 @@ public final class LoadTextUtil {
return Pair.create(charset, CharsetToolkit.UTF8_BOM);
}
try {
- if (CharsetToolkit.hasUTF16LEBom(content)) {
- return Pair.create(CharsetToolkit.UTF_16LE_CHARSET, CharsetToolkit.UTF16LE_BOM);
- }
- if (CharsetToolkit.hasUTF16BEBom(content)) {
- return Pair.create(CharsetToolkit.UTF_16BE_CHARSET, CharsetToolkit.UTF16BE_BOM);
+ Charset fromBOM = CharsetToolkit.guessFromBOM(content);
+ if (fromBOM != null) {
+ return Pair.create(fromBOM, CharsetToolkit.getBom(fromBOM));
}
}
catch (UnsupportedCharsetException ignore) {
@@ -200,68 +204,87 @@ public final class LoadTextUtil {
* @throws java.io.IOException if an I/O error occurs
* @see VirtualFile#getModificationStamp()
*/
- @SuppressWarnings({"IOResourceOpenedButNotSafelyClosed"})
public static void write(@Nullable Project project,
@NotNull VirtualFile virtualFile,
@NotNull Object requestor,
@NotNull String text,
long newModificationStamp) throws IOException {
Charset existing = virtualFile.getCharset();
- Charset specified = extractCharsetFromFileContent(project, virtualFile, text);
- Charset charset = chooseMostlyHarmlessCharset(existing, specified, text);
+ Pair chosen = charsetForWriting(project, virtualFile, text, existing);
+ Charset charset = chosen.first;
+ byte[] buffer = chosen.second;
if (charset != null) {
if (!charset.equals(existing)) {
virtualFile.setCharset(charset);
}
- setDetectedFromBytesFlagBack(virtualFile, charset, text);
}
+ setDetectedFromBytesFlagBack(virtualFile, buffer);
- // in c ase of "UTF-16", OutputStreamWriter sometimes adds BOM on it's own.
+ OutputStream outputStream = virtualFile.getOutputStream(requestor, newModificationStamp, -1);
+ try {
+ outputStream.write(buffer);
+ }
+ finally {
+ outputStream.close();
+ }
+ }
+
+
+ @NotNull
+ private static Pair charsetForWriting(@Nullable Project project,
+ @NotNull VirtualFile virtualFile,
+ @NotNull String text,
+ @Nullable Charset existing) {
+ Charset specified = extractCharsetFromFileContent(project, virtualFile, text);
+ Pair chosen = chooseMostlyHarmlessCharset(existing, specified, text);
+ Charset charset = chosen.first;
+
+ // in case of "UTF-16", OutputStreamWriter sometimes adds BOM on it's own.
// see http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6800103
byte[] bom = virtualFile.getBOM();
Charset fromBom = bom == null ? null : CharsetToolkit.guessFromBOM(bom);
- if (fromBom != null) charset = fromBom;
-
- OutputStream outputStream = virtualFile.getOutputStream(requestor, newModificationStamp, -1);
- OutputStreamWriter writer = charset == null ? new OutputStreamWriter(outputStream) : new OutputStreamWriter(outputStream, charset);
- // no need to buffer ByteArrayOutputStream
- Writer w = outputStream instanceof ByteArrayOutputStream ? writer : new BufferedWriter(writer);
- try {
- w.write(text);
- }
- finally {
- w.close();
+ if (fromBom != null && !fromBom.equals(charset)) {
+ chosen = Pair.create(fromBom, toBytes(text, fromBom));
}
+ return chosen;
}
- private static void setDetectedFromBytesFlagBack(@NotNull VirtualFile virtualFile, @NotNull Charset charset, @NotNull String text) {
+ public static void setDetectedFromBytesFlagBack(@NotNull VirtualFile virtualFile, @NotNull byte[] content) {
if (virtualFile.getBOM() != null) {
// prevent file to be reloaded in other encoding after save with BOM
- setCharsetWasDetectedFromBytes(virtualFile, true);
- return;
+ setCharsetWasDetectedFromBytes(virtualFile, "auto-detected from BOM");
}
-
- byte[] content = text.getBytes(charset);
- CharsetToolkit.GuessedEncoding guessedEncoding = new CharsetToolkit(content).guessFromContent(content.length);
- if (guessedEncoding == CharsetToolkit.GuessedEncoding.VALID_UTF8) {
- setCharsetWasDetectedFromBytes(virtualFile, true);
+ else {
+ guessFromContent(virtualFile, content, content.length);
}
}
- private static Charset chooseMostlyHarmlessCharset(Charset existing, Charset specified, String text) {
- if (existing == null) return specified;
- if (specified == null) return existing;
- if (specified.equals(existing)) return specified;
- if (isSupported(specified, text)) return specified; //if explicitly specified encoding is safe, return it
- if (isSupported(existing, text)) return existing; //otherwise stick to the old encoding if it's ok
- return specified; //if both are bad there is no difference
+ @NotNull
+ public static Pair chooseMostlyHarmlessCharset(Charset existing, Charset specified, @NotNull String text) {
+ if (existing == null) return Pair.create(specified, toBytes(text, specified));
+ if (specified == null || specified.equals(existing)) return Pair.create(specified, toBytes(text, existing));
+
+ byte[] out = isSupported(specified, text);
+ if (out != null) return Pair.create(specified, out); //if explicitly specified encoding is safe, return it
+ out = isSupported(existing, text);
+ if (out != null) return Pair.create(existing, out); //otherwise stick to the old encoding if it's ok
+ return Pair.create(specified, toBytes(text, specified)); //if both are bad there is no difference
}
- private static boolean isSupported(@NotNull Charset charset, @NotNull String str) {
- if (!charset.canEncode()) return false;
- ByteBuffer out = charset.encode(str);
- CharBuffer buffer = charset.decode(out);
- return str.equals(buffer.toString());
+ @NotNull
+ private static byte[] toBytes(@NotNull String text, @Nullable Charset charset) {
+ return charset == null ? text.getBytes() : text.getBytes(charset);
+ }
+
+ @Nullable("null means not supported, otherwise it is converted byte stream")
+ private static byte[] isSupported(@NotNull Charset charset, @NotNull String str) {
+ if (!charset.canEncode()) return null;
+ byte[] bytes = str.getBytes(charset);
+ if (!str.equals(new String(bytes, charset))) {
+ return null;
+ }
+
+ return bytes;
}
public static Charset extractCharsetFromFileContent(@Nullable Project project, @NotNull VirtualFile virtualFile, @NotNull String text) {
@@ -381,18 +404,20 @@ public final class LoadTextUtil {
charset = CharsetToolkit.getDefaultSystemCharset();
}
if (charset == null) {
- //noinspection HardCodedStringLiteral
charset = Charset.forName("ISO-8859-1");
}
CharBuffer charBuffer = charset.decode(byteBuffer);
return convertLineSeparators(charBuffer);
}
- private static final Key CHARSET_WAS_DETECTED_FROM_BYTES = new Key("CHARSET_WAS_DETECTED_FROM_BYTES");
- public static boolean wasCharsetDetectedFromBytes(@NotNull VirtualFile virtualFile) {
- return virtualFile.getUserData(CHARSET_WAS_DETECTED_FROM_BYTES) != null;
+ private static final Key CHARSET_WAS_DETECTED_FROM_BYTES = Key.create("CHARSET_WAS_DETECTED_FROM_BYTES");
+ @Nullable("null if was not detected, otherwise the reason it was")
+ public static String wasCharsetDetectedFromBytes(@NotNull VirtualFile virtualFile) {
+ return virtualFile.getUserData(CHARSET_WAS_DETECTED_FROM_BYTES);
}
- public static void setCharsetWasDetectedFromBytes(@NotNull VirtualFile virtualFile, boolean flag) {
- virtualFile.putUserData(CHARSET_WAS_DETECTED_FROM_BYTES, flag ? Boolean.TRUE : null);
+
+ public static void setCharsetWasDetectedFromBytes(@NotNull VirtualFile virtualFile,
+ @Nullable("null if was not detected, otherwise the reason it was") String reason) {
+ virtualFile.putUserData(CHARSET_WAS_DETECTED_FROM_BYTES, reason);
}
}
diff --git a/platform/dvcs/testFramework/com/intellij/dvcs/test/MockProjectRootManager.groovy b/platform/dvcs/testFramework/com/intellij/dvcs/test/MockProjectRootManager.groovy
index 0dc382d5cd40..954439c25b1c 100644
--- a/platform/dvcs/testFramework/com/intellij/dvcs/test/MockProjectRootManager.groovy
+++ b/platform/dvcs/testFramework/com/intellij/dvcs/test/MockProjectRootManager.groovy
@@ -19,6 +19,7 @@ import com.intellij.openapi.module.Module
import com.intellij.openapi.projectRoots.Sdk
import com.intellij.openapi.vfs.VirtualFile
import com.intellij.openapi.roots.*
+import org.jetbrains.annotations.NotNull
/**
*
@@ -32,11 +33,13 @@ class MockProjectRootManager extends ProjectRootManager {
}
+ @NotNull
@Override
VirtualFile[] getContentRoots() {
myContentRoots
}
+ @NotNull
@Override
ProjectFileIndex getFileIndex() {
throw new UnsupportedOperationException()
@@ -46,13 +49,15 @@ class MockProjectRootManager extends ProjectRootManager {
+ @NotNull
@Override
OrderEnumerator orderEntries() {
throw new UnsupportedOperationException()
}
+ @NotNull
@Override
- OrderEnumerator orderEntries(Collection extends Module> modules) {
+ OrderEnumerator orderEntries(@NotNull Collection extends Module> modules) {
throw new UnsupportedOperationException()
}
@@ -61,6 +66,7 @@ class MockProjectRootManager extends ProjectRootManager {
throw new UnsupportedOperationException()
}
+ @NotNull
@Override
List getContentRootUrls() {
throw new UnsupportedOperationException()
diff --git a/platform/indexing-impl/src/com/intellij/psi/impl/search/PsiSearchHelperImpl.java b/platform/indexing-impl/src/com/intellij/psi/impl/search/PsiSearchHelperImpl.java
index 4714408b1b7c..3057be214ed5 100644
--- a/platform/indexing-impl/src/com/intellij/psi/impl/search/PsiSearchHelperImpl.java
+++ b/platform/indexing-impl/src/com/intellij/psi/impl/search/PsiSearchHelperImpl.java
@@ -44,11 +44,11 @@ import com.intellij.util.containers.MultiMap;
import com.intellij.util.indexing.FileBasedIndex;
import com.intellij.util.text.CharArrayUtil;
import com.intellij.util.text.StringSearcher;
+import gnu.trove.THashSet;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.*;
-import java.util.concurrent.ExecutionException;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
@@ -239,19 +239,13 @@ public class PsiSearchHelperImpl implements PsiSearchHelper {
try {
if (myManager.getProject().isDisposed()) throw new ProcessCanceledException();
List psiRoots = file.getViewProvider().getAllFiles();
- Set processed = new HashSet(psiRoots.size() * 2, (float)0.5);
+ Set processed = new THashSet(psiRoots.size() * 2, (float)0.5);
for (PsiElement psiRoot : psiRoots) {
if (progress != null) progress.checkCanceled();
+ assert psiRoot != null : "One of the roots of file " + file + " is null. All roots: " + psiRoots +
+ "; ViewProvider: " + file.getViewProvider() + "; Virtual file: " + file.getViewProvider().getVirtualFile();
if (!processed.add(psiRoot)) continue;
if (!psiRoot.isValid()) continue;
- assert psiRoot != null : "One of the roots of file " +
- file +
- " is null. All roots: " +
- Arrays.asList(psiRoots) +
- "; Viewprovider: " +
- file.getViewProvider() +
- "; Virtual file: " +
- file.getViewProvider().getVirtualFile();
if (!psiRootProcessor.process(psiRoot)) {
canceled.set(true);
return;
diff --git a/platform/lang-api/src/com/intellij/execution/filters/CompositeFilter.java b/platform/lang-api/src/com/intellij/execution/filters/CompositeFilter.java
index 2b651b68c911..47be6c1a5ece 100644
--- a/platform/lang-api/src/com/intellij/execution/filters/CompositeFilter.java
+++ b/platform/lang-api/src/com/intellij/execution/filters/CompositeFilter.java
@@ -56,7 +56,7 @@ public class CompositeFilter implements Filter, FilterMixin {
Result result = filter.applyFilter(line, entireLength);
finalResult = merge(finalResult, result);
t0 = System.currentTimeMillis() - t0;
- if (t0 > 100) {
+ if (t0 > 1000) {
LOG.warn(filter.getClass().getSimpleName() + ".applyFilter() took " + t0 + " ms on '''" + line + "'''");
}
if (finalResult != null && finalResult.getNextAction() == NextAction.EXIT) {
diff --git a/platform/lang-api/src/com/intellij/ide/util/projectWizard/WizardContext.java b/platform/lang-api/src/com/intellij/ide/util/projectWizard/WizardContext.java
index 0996c8588b0f..33d9ec5fbe5e 100644
--- a/platform/lang-api/src/com/intellij/ide/util/projectWizard/WizardContext.java
+++ b/platform/lang-api/src/com/intellij/ide/util/projectWizard/WizardContext.java
@@ -94,7 +94,7 @@ public class WizardContext {
if (myProjectFileDirectory != null) {
return myProjectFileDirectory;
}
- final String lastProjectLocation = GeneralSettings.getInstance().getLastProjectLocation();
+ final String lastProjectLocation = GeneralSettings.getInstance().getLastProjectCreationLocation();
if (lastProjectLocation != null) {
return lastProjectLocation.replace('/', File.separatorChar);
}
diff --git a/platform/lang-impl/src/com/intellij/codeInspection/LossyEncodingInspection.java b/platform/lang-impl/src/com/intellij/codeInspection/LossyEncodingInspection.java
index 062e91eacf94..fd1b2724e125 100644
--- a/platform/lang-impl/src/com/intellij/codeInspection/LossyEncodingInspection.java
+++ b/platform/lang-impl/src/com/intellij/codeInspection/LossyEncodingInspection.java
@@ -22,23 +22,25 @@
*/
package com.intellij.codeInspection;
-import com.intellij.ide.DataManager;
import com.intellij.lang.injection.InjectedLanguageManager;
import com.intellij.lang.properties.charset.Native2AsciiCharset;
+import com.intellij.openapi.actionSystem.ActionManager;
+import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.DataContext;
-import com.intellij.openapi.actionSystem.DefaultActionGroup;
+import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.fileEditor.FileDocumentManager;
import com.intellij.openapi.fileEditor.impl.LoadTextUtil;
import com.intellij.openapi.project.Project;
-import com.intellij.openapi.ui.popup.JBPopupFactory;
import com.intellij.openapi.util.TextRange;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.encoding.ChooseFileEncodingAction;
-import com.intellij.openapi.vfs.encoding.EncodingManager;
+import com.intellij.openapi.vfs.encoding.ReloadFileInOtherEncodingAction;
import com.intellij.openapi.vfs.ex.temp.TempFileSystem;
+import com.intellij.openapi.wm.impl.status.EncodingActionsPair;
import com.intellij.psi.PsiFile;
+import com.intellij.psi.util.PsiUtilBase;
import com.intellij.util.ArrayUtil;
import com.intellij.util.SmartList;
import org.jetbrains.annotations.Nls;
@@ -57,24 +59,28 @@ public class LossyEncodingInspection extends LocalInspectionTool {
private static final LocalQuickFix CHANGE_ENCODING_FIX = new ChangeEncodingFix();
private static final LocalQuickFix RELOAD_ENCODING_FIX = new ReloadInAnotherEncodingFix();
+ @Override
@Nls
@NotNull
public String getGroupDisplayName() {
return InspectionsBundle.message("group.names.internationalization.issues");
}
+ @Override
@Nls
@NotNull
public String getDisplayName() {
return InspectionsBundle.message("lossy.encoding");
}
+ @Override
@NonNls
@NotNull
public String getShortName() {
return "LossyEncoding";
}
+ @Override
@Nullable
public ProblemDescriptor[] checkFile(@NotNull PsiFile file, @NotNull InspectionManager manager, boolean isOnTheFly) {
if (InjectedLanguageManager.getInstance(file.getProject()).isInjectedFragment(file)) return null;
@@ -93,44 +99,61 @@ public class LossyEncodingInspection extends LocalInspectionTool {
List descriptors = new SmartList();
checkIfCharactersWillBeLostAfterSave(file, manager, isOnTheFly, text, charset, descriptors);
- checkFileLoadedInWrongEncoding(file, manager, isOnTheFly, virtualFile, charset, descriptors);
+ checkFileLoadedInWrongEncoding(file, manager, isOnTheFly, text, virtualFile, charset, descriptors);
return descriptors.toArray(new ProblemDescriptor[descriptors.size()]);
}
- private static void checkFileLoadedInWrongEncoding(PsiFile file,
- InspectionManager manager,
+ private static void checkFileLoadedInWrongEncoding(@NotNull PsiFile file,
+ @NotNull InspectionManager manager,
boolean isOnTheFly,
- VirtualFile virtualFile,
- Charset charset, List descriptors) {
+ @NotNull String text,
+ @NotNull VirtualFile virtualFile,
+ @NotNull Charset charset,
+ @NotNull List descriptors) {
if (FileDocumentManager.getInstance().isFileModified(virtualFile) // when file is modified, it's too late to reload it
- || ChooseFileEncodingAction.isEnabledAndWhyNot(virtualFile) != null // can't reload in another encoding, no point trying
+ || ChooseFileEncodingAction.checkCanReload(virtualFile).second != null // can't reload in another encoding, no point trying
) {
return;
}
- // check if file was loaded in correct encoding
+ boolean ok = isGoodCharset(file.getProject(), virtualFile, text, charset);
+ if (!ok) {
+ descriptors.add(manager.createProblemDescriptor(file, "File was loaded in the wrong encoding: '"+charset+"'",
+ RELOAD_ENCODING_FIX, ProblemHighlightType.GENERIC_ERROR, isOnTheFly));
+ }
+ }
+
+ // check if file was loaded in correct encoding
+ // returns true if text converted with charset is equals to the bytes currently on disk
+ public static boolean isGoodCharset(@NotNull Project project,
+ @NotNull VirtualFile virtualFile,
+ @NotNull String text,
+ @NotNull Charset charset) {
byte[] bytes;
try {
bytes = virtualFile.contentsToByteArray();
}
catch (IOException e) {
- return;
+ return true;
}
- String separator = FileDocumentManager.getInstance().getLineSeparator(virtualFile, file.getProject());
- String toSave = StringUtil.convertLineSeparators(file.getText(), separator);
+ String separator = FileDocumentManager.getInstance().getLineSeparator(virtualFile, project);
+ String toSave = StringUtil.convertLineSeparators(text, separator);
byte[] bom = virtualFile.getBOM();
- byte[] bytesToSave = ArrayUtil.mergeArrays(bom == null ? ArrayUtil.EMPTY_BYTE_ARRAY : bom, toSave.getBytes(charset));
- if (!Arrays.equals(bytesToSave, bytes)) {
- descriptors.add(manager.createProblemDescriptor(file, "File was loaded in a wrong encoding: '"+charset+"'",
- RELOAD_ENCODING_FIX, ProblemHighlightType.GENERIC_ERROR, isOnTheFly));
+ bom = bom == null ? ArrayUtil.EMPTY_BYTE_ARRAY : bom;
+ byte[] bytesToSave = toSave.getBytes(charset);
+ if (!ArrayUtil.startsWith(bytesToSave, bom)) {
+ bytesToSave = ArrayUtil.mergeArrays(bom, bytesToSave); // for 2-byte encodings String.getBytes(Charset) adds BOM automatically
}
+
+ return Arrays.equals(bytesToSave, bytes);
}
- private static void checkIfCharactersWillBeLostAfterSave(PsiFile file,
- InspectionManager manager,
+ private static void checkIfCharactersWillBeLostAfterSave(@NotNull PsiFile file,
+ @NotNull InspectionManager manager,
boolean isOnTheFly,
- String text,
- Charset charset, List descriptors) {
+ @NotNull String text,
+ @NotNull Charset charset,
+ @NotNull List descriptors) {
int errorCount = 0;
int start = -1;
for (int i = 0; i <= text.length(); i++) {
@@ -153,7 +176,7 @@ public class LossyEncodingInspection extends LocalInspectionTool {
}
}
- private static boolean isRepresentable(final char c, final Charset charset) {
+ private static boolean isRepresentable(final char c, @NotNull Charset charset) {
String str = Character.toString(c);
ByteBuffer out = charset.encode(str);
CharBuffer buffer = charset.decode(out);
@@ -191,17 +214,12 @@ public class LossyEncodingInspection extends LocalInspectionTool {
public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
PsiFile psiFile = descriptor.getPsiElement().getContainingFile();
VirtualFile virtualFile = psiFile.getVirtualFile();
- ChooseFileEncodingAction action = new ChooseFileEncodingAction(virtualFile) {
- @Override
- protected void chosen(VirtualFile virtualFile, @NotNull Charset charset) {
- if (virtualFile != null) {
- EncodingManager.getInstance().setEncoding(virtualFile, charset);
- }
- }
- };
- DefaultActionGroup group = action.createGroup(null);
- DataContext dataContext = DataManager.getInstance().getDataContext();
- JBPopupFactory.getInstance().createActionGroupPopup(null, group, dataContext, false, false, false, null, 30, null).showInBestPositionFor(dataContext);
+
+ Editor editor = PsiUtilBase.findEditor(psiFile);
+ DataContext dataContext =
+ EncodingActionsPair.createDataContext(editor, editor == null ? null : editor.getComponent(), virtualFile, project);
+ ReloadFileInOtherEncodingAction reloadAction = new ReloadFileInOtherEncodingAction();
+ reloadAction.actionPerformed(new AnActionEvent(null, dataContext, "", reloadAction.getTemplatePresentation(), ActionManager.getInstance(), 0));
}
}
}
diff --git a/platform/lang-impl/src/com/intellij/execution/impl/BeforeRunStepsPanel.java b/platform/lang-impl/src/com/intellij/execution/impl/BeforeRunStepsPanel.java
index aee7558811b7..6e80b6aefec6 100644
--- a/platform/lang-impl/src/com/intellij/execution/impl/BeforeRunStepsPanel.java
+++ b/platform/lang-impl/src/com/intellij/execution/impl/BeforeRunStepsPanel.java
@@ -107,6 +107,7 @@ class BeforeRunStepsPanel extends JPanel {
BeforeRunTaskProvider provider = selection.getSecond();
if (provider.configureTask(myRunConfiguration, task)) {
myModel.setElementAt(task, index);
+ updateText();
}
}
});
@@ -173,7 +174,7 @@ class BeforeRunStepsPanel extends JPanel {
StringBuilder sb = new StringBuilder();
if (myShowSettingsBeforeRunCheckBox.isSelected()) {
- sb.append(ExecutionBundle.message("configuration.edit.before.run")).append(", ");
+ sb.append(ExecutionBundle.message("configuration.edit.before.run"));
}
List tasks = myModel.getItems();
@@ -199,12 +200,13 @@ class BeforeRunStepsPanel extends JPanel {
if (name.startsWith("Run ")) {
name = name.substring(4);
}
+ if (sb.length() > 0) {
+ sb.append(", ");
+ }
sb.append(name);
if (entry.getValue() > 1) {
sb.append(" (").append(entry.getValue().intValue()).append(")");
}
- if (iterator.hasNext())
- sb.append(", ");
}
}
if (sb.length() > 0) {
diff --git a/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/FavoritesManager.java b/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/FavoritesManager.java
index 1b0bdfec2164..3d7bbb119b79 100644
--- a/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/FavoritesManager.java
+++ b/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/FavoritesManager.java
@@ -206,7 +206,7 @@ public class FavoritesManager implements ProjectComponent, JDOMExternalizable {
}
private void appendChildNodes(AbstractTreeNode node, TreeItem> treeItem) {
- final Collection children = node.getChildren();
+ final Collection extends AbstractTreeNode> children = node.getChildren();
for (AbstractTreeNode child : children) {
final TreeItem> childTreeItem = new TreeItem>(createPairForNode(child));
treeItem.addChild(childTreeItem);
diff --git a/platform/lang-impl/src/com/intellij/openapi/file/exclude/EnforcedPlainTextFileTypeManager.java b/platform/lang-impl/src/com/intellij/openapi/file/exclude/EnforcedPlainTextFileTypeManager.java
index 44b8a5089ef2..b095b17fb7ce 100644
--- a/platform/lang-impl/src/com/intellij/openapi/file/exclude/EnforcedPlainTextFileTypeManager.java
+++ b/platform/lang-impl/src/com/intellij/openapi/file/exclude/EnforcedPlainTextFileTypeManager.java
@@ -26,21 +26,51 @@ import com.intellij.openapi.fileTypes.FileTypes;
import com.intellij.openapi.fileTypes.StdFileTypes;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.project.ProjectManager;
+import com.intellij.openapi.project.ProjectManagerListener;
import com.intellij.openapi.roots.ex.ProjectRootManagerEx;
+import com.intellij.openapi.roots.impl.DirectoryIndex;
import com.intellij.openapi.util.EmptyRunnable;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.indexing.FileBasedIndex;
+import java.util.*;
+
/**
+ * Maintains a list of files marked as plain text in a local environment (configuration). Every time a project is loaded/open, it reads
+ * files marked as plain text from a project into local environment (configuration). User actions (mark/unmark as plain text) are
+ * synchronized between local and project configurations.
+ *
* @author Rustam Vishnyakov
*/
@State(name = "EnforcedPlainTextFileTypeManager", storages = {@Storage( file = StoragePathMacros.APP_CONFIG + "/plainTextFiles.xml")})
-public class EnforcedPlainTextFileTypeManager extends PersistentFileSetManager {
-
+public class EnforcedPlainTextFileTypeManager extends PersistentFileSetManager implements ProjectManagerListener {
+
+ private Set myProcessedProjects = new HashSet();
+ private boolean myNeedsSync = true;
+
+ public EnforcedPlainTextFileTypeManager() {
+ ProjectManager.getInstance().addProjectManagerListener(this);
+ }
+
public boolean isMarkedAsPlainText(VirtualFile file) {
+ if (myNeedsSync) {
+ myNeedsSync = !syncWithOpenProject();
+ }
return containsFile(file);
}
+ public boolean syncWithOpenProject() {
+ Project[] openProjects = ProjectManager.getInstance().getOpenProjects();
+ if (openProjects.length > 0) {
+ Project firstOpenProject = openProjects[0];
+ if (!myProcessedProjects.contains(firstOpenProject)) {
+ return syncWithProject(firstOpenProject);
+ }
+ return true;
+ }
+ return false;
+ }
+
public static boolean isApplicableFor(VirtualFile file) {
if (file.isDirectory()) return false;
FileType originalType = FileTypeManager.getInstance().getFileTypeByFileName(file.getName());
@@ -53,29 +83,44 @@ public class EnforcedPlainTextFileTypeManager extends PersistentFileSetManager {
}
public void markAsPlainText(VirtualFile... files) {
+ List filesToSync = new ArrayList();
for (VirtualFile file : files) {
if (addFile(file)) {
+ filesToSync.add(file);
FileBasedIndex.getInstance().requestReindex(file);
}
}
- fireRootsChanged();
+ fireRootsChanged(filesToSync, true);
}
public void unmarkPlainText(VirtualFile... files) {
+ List filesToSync = new ArrayList();
for (VirtualFile file : files) {
if (removeFile(file)) {
+ filesToSync.add(file);
FileBasedIndex.getInstance().requestReindex(file);
}
}
- fireRootsChanged();
+ fireRootsChanged(filesToSync, false);
}
- private static void fireRootsChanged() {
+ private static void fireRootsChanged(final Collection files, final boolean isAdded) {
ApplicationManager.getApplication().runWriteAction(new Runnable() {
@Override
public void run() {
for (Project project : ProjectManager.getInstance().getOpenProjects()) {
ProjectRootManagerEx.getInstanceEx(project).makeRootsChange(EmptyRunnable.getInstance(), false, true);
+ ProjectPlainTextFileTypeManager projectPlainTextFileTypeManager = ProjectPlainTextFileTypeManager.getInstance(project);
+ for (VirtualFile file : files) {
+ if (projectPlainTextFileTypeManager.hasProjectContaining(file)) {
+ if (isAdded) {
+ projectPlainTextFileTypeManager.addFile(file);
+ }
+ else {
+ projectPlainTextFileTypeManager.removeFile(file);
+ }
+ }
+ }
}
}
});
@@ -89,4 +134,41 @@ public class EnforcedPlainTextFileTypeManager extends PersistentFileSetManager {
}
return ourInstance;
}
+
+ @Override
+ public void projectOpened(Project project) {
+ syncWithProject(project);
+ }
+
+ @Override
+ public boolean canCloseProject(Project project) {
+ return true;
+ }
+
+ @Override
+ public void projectClosed(Project project) {
+ if (myProcessedProjects.contains(project)) {
+ myProcessedProjects.remove(project);
+ }
+ }
+
+ @Override
+ public void projectClosing(Project project) {
+ }
+
+ private boolean syncWithProject(Project project) {
+ if (!DirectoryIndex.getInstance(project).isInitialized()) return false;
+ myProcessedProjects.add(project);
+ ProjectPlainTextFileTypeManager projectPlainTextFileTypeManager = ProjectPlainTextFileTypeManager.getInstance(project);
+ if (projectPlainTextFileTypeManager == null) return true;
+ for (VirtualFile file : projectPlainTextFileTypeManager.getFiles()) {
+ addFile(file);
+ }
+ for (VirtualFile file : getFiles()) {
+ if (projectPlainTextFileTypeManager.hasProjectContaining(file)) {
+ projectPlainTextFileTypeManager.addFile(file);
+ }
+ }
+ return true;
+ }
}
diff --git a/platform/lang-impl/src/com/intellij/openapi/file/exclude/ProjectPlainTextFileTypeManager.java b/platform/lang-impl/src/com/intellij/openapi/file/exclude/ProjectPlainTextFileTypeManager.java
new file mode 100644
index 000000000000..ba74997c8433
--- /dev/null
+++ b/platform/lang-impl/src/com/intellij/openapi/file/exclude/ProjectPlainTextFileTypeManager.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2000-2012 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.openapi.file.exclude;
+
+import com.intellij.openapi.components.ServiceManager;
+import com.intellij.openapi.components.State;
+import com.intellij.openapi.components.Storage;
+import com.intellij.openapi.components.StoragePathMacros;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.roots.ProjectFileIndex;
+import com.intellij.openapi.roots.ProjectRootManager;
+import com.intellij.openapi.vfs.VirtualFile;
+
+/**
+ * @author Rustam Vishnyakov
+ */
+@State(name = "ProjectPlainTextFileTypeManager", storages = {@Storage( file = StoragePathMacros.PROJECT_FILE)})
+public class ProjectPlainTextFileTypeManager extends PersistentFileSetManager {
+ private ProjectFileIndex myIndex;
+
+ public ProjectPlainTextFileTypeManager(Project project) {
+ myIndex = ProjectRootManager.getInstance(project).getFileIndex();
+ }
+
+ public boolean hasProjectContaining(VirtualFile file) {
+ return myIndex.isInContent(file);
+ }
+
+ public static ProjectPlainTextFileTypeManager getInstance(Project project) {
+ return ServiceManager.getService(project, ProjectPlainTextFileTypeManager.class);
+ }
+
+}
diff --git a/platform/lang-impl/src/com/intellij/openapi/vfs/encoding/ConfigureFileDefaultEncodingAction.java b/platform/lang-impl/src/com/intellij/openapi/vfs/encoding/ConfigureFileDefaultEncodingAction.java
index 23a574257e88..0dbfc68d0c88 100644
--- a/platform/lang-impl/src/com/intellij/openapi/vfs/encoding/ConfigureFileDefaultEncodingAction.java
+++ b/platform/lang-impl/src/com/intellij/openapi/vfs/encoding/ConfigureFileDefaultEncodingAction.java
@@ -29,6 +29,7 @@ public class ConfigureFileDefaultEncodingAction extends AnAction {
final Project project = e.getData(PlatformDataKeys.PROJECT);
final VirtualFile virtualFile = e.getData(PlatformDataKeys.VIRTUAL_FILE);
+ assert project != null;
final FileEncodingConfigurable configurable = new FileEncodingConfigurable(project);
ShowSettingsUtil.getInstance().editConfigurable(project, configurable, new Runnable(){
@Override
diff --git a/platform/lang-impl/src/com/intellij/openapi/vfs/encoding/FileTreeTable.java b/platform/lang-impl/src/com/intellij/openapi/vfs/encoding/EncodingFileTreeTable.java
similarity index 73%
rename from platform/lang-impl/src/com/intellij/openapi/vfs/encoding/FileTreeTable.java
rename to platform/lang-impl/src/com/intellij/openapi/vfs/encoding/EncodingFileTreeTable.java
index dca897b2c4b0..c625cd807153 100644
--- a/platform/lang-impl/src/com/intellij/openapi/vfs/encoding/FileTreeTable.java
+++ b/platform/lang-impl/src/com/intellij/openapi/vfs/encoding/EncodingFileTreeTable.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2012 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -24,10 +24,10 @@ package com.intellij.openapi.vfs.encoding;
import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.actionSystem.impl.SimpleDataContext;
-import com.intellij.openapi.fileEditor.impl.LoadTextUtil;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.openapi.vfs.VirtualFileFilter;
import com.intellij.util.ui.tree.AbstractFileTreeTable;
import org.jetbrains.annotations.NotNull;
@@ -39,9 +39,9 @@ import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.nio.charset.Charset;
-public class FileTreeTable extends AbstractFileTreeTable {
- public FileTreeTable(final Project project) {
- super(project, Charset.class, "Default Encoding");
+class EncodingFileTreeTable extends AbstractFileTreeTable {
+ public EncodingFileTreeTable(@NotNull Project project) {
+ super(project, Charset.class, "Default Encoding", VirtualFileFilter.ALL, false);
reset(EncodingProjectManager.getInstance(project).getAllMappings());
getValueColumn().setCellRenderer(new DefaultTableCellRenderer(){
@@ -52,24 +52,19 @@ public class FileTreeTable extends AbstractFileTreeTable {
final Charset t = (Charset)value;
final Object userObject = table.getModel().getValueAt(row, 0);
final VirtualFile file = userObject instanceof VirtualFile ? (VirtualFile)userObject : null;
- final Pair pair = ChooseFileEncodingAction.update(file);
- final boolean enabled = file == null || pair.getSecond();
- if (t != null) {
- setText(t.displayName());
- }
- else if (file != null) {
- String failReason;
- Charset charset = ChooseFileEncodingAction.cachedCharsetFromContent(file);
- if (charset != null) {
- setText(charset.displayName()+ " (Hardcoded in the text)");
- }
- else if (LoadTextUtil.wasCharsetDetectedFromBytes(file)) {
- setText(file.getCharset().displayName() + " (Auto-detected)");
- }
- else if ((failReason = ChooseFileEncodingAction.isEnabledAndWhyNot(file)) != null) {
- setText("N/A ("+failReason+")");
- }
+ Pair check = file == null || file.isDirectory() ? null : ChooseFileEncodingAction.checkCanReload(file);
+ String failReason = check == null ? null : check.second;
+ boolean enabled = failReason == null;
+
+ // show existing encoding only if it was specified explicitly or it is unchangeable (with reason)
+ boolean toShow = t != null || failReason != null;
+
+ if (toShow) {
+ Charset existing = check == null ? null : check.first;
+ String encodingText = t != null ? t.displayName() : existing == null ? "N/A" : existing.displayName();
+ setText(encodingText + (failReason == null ? "" : " (" + failReason + ")"));
}
+
setEnabled(enabled);
return this;
}
@@ -96,7 +91,17 @@ public class FileTreeTable extends AbstractFileTreeTable {
final Object o = table.getModel().getValueAt(row, 0);
myVirtualFile = o instanceof Project ? null : (VirtualFile)o;
- final ChooseFileEncodingAction changeAction = new ChooseFileEncodingAction(myVirtualFile){
+ ChooseFileEncodingAction changeAction = new ChooseFileEncodingAction(myVirtualFile) {
+ @NotNull
+ @Override
+ protected DefaultActionGroup createPopupActionGroup(JComponent button) {
+ return createGroup("", null, "Encoding ''{1}''", null);
+ }
+
+ @Override
+ public void update(AnActionEvent e) {
+ }
+
@Override
protected void chosen(VirtualFile virtualFile, @NotNull Charset charset) {
getValueColumn().getCellEditor().stopCellEditing();
@@ -107,15 +112,15 @@ public class FileTreeTable extends AbstractFileTreeTable {
}
};
Presentation templatePresentation = changeAction.getTemplatePresentation();
- final JComponent comboComponent = changeAction.createCustomComponent(templatePresentation);
+ JComponent comboComponent = changeAction.createCustomComponent(templatePresentation);
DataContext dataContext = SimpleDataContext.getSimpleContext(PlatformDataKeys.VIRTUAL_FILE.getName(), myVirtualFile,
SimpleDataContext.getProjectContext(getProject()));
AnActionEvent event = new AnActionEvent(null, dataContext, ActionPlaces.UNKNOWN, templatePresentation, ActionManager.getInstance(), 0);
changeAction.update(event);
- changeAction.getTemplatePresentation().setDescription(null);
+ templatePresentation.setDescription(null);
if (myVirtualFile == null) {
- changeAction.getTemplatePresentation().setEnabled(true); // enable changing encoding for tree root (entire project)
+ templatePresentation.setEnabled(true); // enable changing encoding for tree root (entire project)
}
editorComponent = comboComponent;
comboComponent.addComponentListener(new ComponentAdapter() {
@@ -141,6 +146,7 @@ public class FileTreeTable extends AbstractFileTreeTable {
@Override
protected boolean isValueEditableForFile(final VirtualFile virtualFile) {
- return ChooseFileEncodingAction.update(virtualFile).getSecond();
+ return virtualFile == null || virtualFile.isDirectory() ||
+ ChooseFileEncodingAction.checkCanReload(virtualFile).second == null;
}
}
diff --git a/platform/lang-impl/src/com/intellij/openapi/vfs/encoding/FileEncodingConfigurable.form b/platform/lang-impl/src/com/intellij/openapi/vfs/encoding/FileEncodingConfigurable.form
index bc395378367e..6edeb8fa9dff 100644
--- a/platform/lang-impl/src/com/intellij/openapi/vfs/encoding/FileEncodingConfigurable.form
+++ b/platform/lang-impl/src/com/intellij/openapi/vfs/encoding/FileEncodingConfigurable.form
@@ -3,7 +3,7 @@
-
+
@@ -21,7 +21,7 @@
-
+
@@ -34,7 +34,7 @@
-
+
@@ -56,9 +56,14 @@
+
+
+
+
+
-
+
@@ -84,23 +89,58 @@
-
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
diff --git a/platform/lang-impl/src/com/intellij/openapi/vfs/encoding/FileEncodingConfigurable.java b/platform/lang-impl/src/com/intellij/openapi/vfs/encoding/FileEncodingConfigurable.java
index 21d6b6545ae6..4a94cd891809 100644
--- a/platform/lang-impl/src/com/intellij/openapi/vfs/encoding/FileEncodingConfigurable.java
+++ b/platform/lang-impl/src/com/intellij/openapi/vfs/encoding/FileEncodingConfigurable.java
@@ -46,7 +46,7 @@ import java.util.Map;
public class FileEncodingConfigurable implements SearchableConfigurable, OptionalConfigurable, Configurable.NoScroll {
private static final String SYSTEM_DEFAULT = IdeBundle.message("encoding.name.system.default");
private final Project myProject;
- private FileTreeTable myTreeView;
+ private EncodingFileTreeTable myTreeView;
private JScrollPane myTreePanel;
private JPanel myPanel;
private JCheckBox myAutodetectUTFEncodedFilesCheckBox;
@@ -54,12 +54,15 @@ public class FileEncodingConfigurable implements SearchableConfigurable, Optiona
private JPanel myPropertiesFilesEncodingCombo;
private final Ref mySelectedCharsetForPropertiesFiles = new Ref();
private final Ref mySelectedIdeCharset = new Ref();
+ private final Ref mySelectedProjectCharset = new Ref();
private JLabel myTitleLabel;
private JPanel myIdeEncodingsListCombo;
+ private JPanel myProjectEncodingListCombo;
private ChooseFileEncodingAction myPropertiesEncodingAction;
private ChooseFileEncodingAction myIdeEncodingAction;
+ private ChooseFileEncodingAction myProjectEncodingAction;
- public FileEncodingConfigurable(Project project) {
+ public FileEncodingConfigurable(@NotNull Project project) {
myProject = project;
myTitleLabel.setText(myTitleLabel.getText().replace("$productName", ApplicationNamesInfo.getInstance().getFullProductName()));
}
@@ -100,19 +103,19 @@ public class FileEncodingConfigurable implements SearchableConfigurable, Optiona
@Override
protected void chosen(final VirtualFile virtualFile, @NotNull final Charset charset) {
selected.set(charset == NO_ENCODING ? null : charset);
- update((AnActionEvent)null);
+ update(null);
}
@NotNull
@Override
protected DefaultActionGroup createPopupActionGroup(JComponent button) {
- return createGroup("");
+ return createGroup("", null, "Choose encoding ''{1}''", selected.get());
}
};
parentPanel.removeAll();
Presentation templatePresentation = myAction.getTemplatePresentation();
parentPanel.add(myAction.createCustomComponent(templatePresentation), BorderLayout.CENTER);
- myAction.update((AnActionEvent)null);
+ myAction.update(null);
return myAction;
}
@@ -120,7 +123,8 @@ public class FileEncodingConfigurable implements SearchableConfigurable, Optiona
public JComponent createComponent() {
myPropertiesEncodingAction = installChooseEncodingCombo(myPropertiesFilesEncodingCombo, mySelectedCharsetForPropertiesFiles);
myIdeEncodingAction = installChooseEncodingCombo(myIdeEncodingsListCombo, mySelectedIdeCharset);
- myTreeView = new FileTreeTable(myProject);
+ myProjectEncodingAction = installChooseEncodingCombo(myProjectEncodingListCombo, mySelectedProjectCharset);
+ myTreeView = new EncodingFileTreeTable(myProject);
myTreePanel.setViewportView(myTreeView);
myTreeView.getEmptyText().setText(IdeBundle.message("file.encodings.not.configured"));
return myPanel;
@@ -128,7 +132,8 @@ public class FileEncodingConfigurable implements SearchableConfigurable, Optiona
@Override
public boolean isModified() {
- if (isEncodingModified()) return true;
+ if (isIdeEncodingModified()) return true;
+ if (isProjectEncodingModified()) return true;
EncodingProjectManager encodingManager = EncodingProjectManager.getInstance(myProject);
Map editing = myTreeView.getValues();
@@ -141,7 +146,7 @@ public class FileEncodingConfigurable implements SearchableConfigurable, Optiona
return !same;
}
- public boolean isEncodingModified() {
+ private boolean isIdeEncodingModified() {
Charset charset = mySelectedIdeCharset.get();
if (null == charset) {
return !StringUtil.isEmpty(EncodingManager.getInstance().getDefaultCharsetName());
@@ -149,6 +154,10 @@ public class FileEncodingConfigurable implements SearchableConfigurable, Optiona
return !Comparing.equal(charset, EncodingManager.getInstance().getDefaultCharset());
}
+ private boolean isProjectEncodingModified() {
+ Charset charset = mySelectedProjectCharset.get();
+ return !Comparing.equal(charset, EncodingProjectManager.getInstance(myProject).getEncoding(null, false));
+ }
@Override
public void apply() throws ConfigurationException {
@@ -159,8 +168,10 @@ public class FileEncodingConfigurable implements SearchableConfigurable, Optiona
encodingManager.setNative2AsciiForPropertiesFiles(null, myTransparentNativeToAsciiCheckBox.isSelected());
encodingManager.setUseUTFGuessing(null, myAutodetectUTFEncodedFilesCheckBox.isSelected());
- Charset charset = mySelectedIdeCharset.get();
- EncodingManager.getInstance().setDefaultCharsetName(charset == null ? "" : charset.name());
+ Charset ideCharset = mySelectedIdeCharset.get();
+ EncodingManager.getInstance().setDefaultCharsetName(ideCharset == null ? "" : ideCharset.name());
+ Charset projectCharset = mySelectedIdeCharset.get();
+ EncodingProjectManager.getInstance(myProject).setEncoding(null, projectCharset);
}
@Override
@@ -172,8 +183,10 @@ public class FileEncodingConfigurable implements SearchableConfigurable, Optiona
mySelectedCharsetForPropertiesFiles.set(encodingManager.getDefaultCharsetForPropertiesFiles(null));
mySelectedIdeCharset.set(EncodingManager.getInstance().getDefaultCharset());
- myPropertiesEncodingAction.update((AnActionEvent)null);
- myIdeEncodingAction.update((AnActionEvent)null);
+ mySelectedProjectCharset.set(EncodingProjectManager.getInstance(myProject).getEncoding(null, false));
+ myPropertiesEncodingAction.update(null);
+ myIdeEncodingAction.update(null);
+ myProjectEncodingAction.update(null);
}
@Override
diff --git a/platform/lang-impl/src/com/intellij/psi/templateLanguages/TemplateDataLanguageConfigurable.java b/platform/lang-impl/src/com/intellij/psi/templateLanguages/TemplateDataLanguageConfigurable.java
index 0db98442af21..525775904145 100644
--- a/platform/lang-impl/src/com/intellij/psi/templateLanguages/TemplateDataLanguageConfigurable.java
+++ b/platform/lang-impl/src/com/intellij/psi/templateLanguages/TemplateDataLanguageConfigurable.java
@@ -32,7 +32,7 @@ import org.jetbrains.annotations.Nullable;
* @author peter
*/
public class TemplateDataLanguageConfigurable extends LanguagePerFileConfigurable {
- public TemplateDataLanguageConfigurable(Project project) {
+ public TemplateDataLanguageConfigurable(@NotNull Project project) {
super(project, Language.class, TemplateDataLanguageMappings.getInstance(project),
LangBundle.message("dialog.template.data.language.caption", ApplicationNamesInfo.getInstance().getFullProductName()),
LangBundle.message("template.data.language.configurable.tree.table.title"),
diff --git a/platform/lang-impl/src/com/intellij/util/ui/tree/AbstractFileTreeTable.java b/platform/lang-impl/src/com/intellij/util/ui/tree/AbstractFileTreeTable.java
index 6a0bcc0225de..372645bd038d 100644
--- a/platform/lang-impl/src/com/intellij/util/ui/tree/AbstractFileTreeTable.java
+++ b/platform/lang-impl/src/com/intellij/util/ui/tree/AbstractFileTreeTable.java
@@ -52,11 +52,11 @@ public abstract class AbstractFileTreeTable extends TreeTable {
private final MyModel myModel;
private final Project myProject;
- public AbstractFileTreeTable(final Project project, final Class valueClass, final String valueTitle) {
- this(project, valueClass, valueTitle, VirtualFileFilter.ALL);
- }
-
- public AbstractFileTreeTable(final Project project, final Class valueClass, final String valueTitle, @NotNull VirtualFileFilter filter) {
+ public AbstractFileTreeTable(@NotNull Project project,
+ @NotNull Class valueClass,
+ @NotNull String valueTitle,
+ @NotNull VirtualFileFilter filter,
+ boolean showProjectNode) {
super(new MyModel(project, valueClass, valueTitle, filter));
myProject = project;
@@ -83,7 +83,7 @@ public abstract class AbstractFileTreeTable extends TreeTable {
getTree().setShowsRootHandles(true);
getTree().setLineStyleAngled();
- getTree().setRootVisible(true);
+ getTree().setRootVisible(showProjectNode);
getTree().setCellRenderer(new DefaultTreeCellRenderer() {
@Override
public Component getTreeCellRendererComponent(final JTree tree, final Object value, final boolean sel, final boolean expanded,
@@ -122,7 +122,7 @@ public abstract class AbstractFileTreeTable extends TreeTable {
return false;
}
- private String getProjectNodeText() {
+ private static String getProjectNodeText() {
return "Project";
}
@@ -176,6 +176,7 @@ public abstract class AbstractFileTreeTable extends TreeTable {
}
}
+ @NotNull
public Map getValues() {
return myModel.getValues();
}
@@ -190,12 +191,13 @@ public abstract class AbstractFileTreeTable extends TreeTable {
return tableRenderer;
}
- public void reset(final Map mappings) {
+ public void reset(@NotNull Map mappings) {
myModel.reset(mappings);
final TreeNode root = (TreeNode)myModel.getRoot();
myModel.nodeChanged(root);
getTree().setModel(null);
getTree().setModel(myModel);
+ TreeUtil.expandRootChildIfOnlyOne(getTree());
}
public void select(@Nullable final VirtualFile toSelect) {
@@ -230,7 +232,7 @@ public abstract class AbstractFileTreeTable extends TreeTable {
private final String myValueTitle;
private AbstractFileTreeTable myTreeTable;
- private MyModel(final Project project, final Class valueClass, final String valueTitle, VirtualFileFilter filter) {
+ private MyModel(@NotNull Project project, @NotNull Class valueClass, @NotNull String valueTitle, @NotNull VirtualFileFilter filter) {
super(new ProjectRootNode(project, filter));
myValueClass = valueClass;
myValueTitle = valueTitle;
@@ -324,7 +326,7 @@ public abstract class AbstractFileTreeTable extends TreeTable {
fireTreeNodesChanged(this, new Object[]{getRoot()}, null, null);
}
- public void reset(final Map mappings) {
+ public void reset(@NotNull Map mappings) {
myCurrentMapping.clear();
myCurrentMapping.putAll(mappings);
((ProjectRootNode)getRoot()).clearCachedChildren();
@@ -348,7 +350,7 @@ public abstract class AbstractFileTreeTable extends TreeTable {
}
@Override
- protected void appendChildrenTo(final Collection children) {
+ protected void appendChildrenTo(@NotNull final Collection children) {
Project project = getObject();
VirtualFile[] roots = ProjectRootManager.getInstance(project).getContentRoots();
@@ -375,7 +377,7 @@ public abstract class AbstractFileTreeTable extends TreeTable {
return myObject;
}
- protected abstract void appendChildrenTo(final Collection children);
+ protected abstract void appendChildrenTo(@NotNull Collection children);
@Override
public int getChildCount() {
@@ -450,7 +452,7 @@ public abstract class AbstractFileTreeTable extends TreeTable {
}
@Override
- protected void appendChildrenTo(final Collection children) {
+ protected void appendChildrenTo(@NotNull final Collection children) {
VirtualFile[] childrenf = getObject().getChildren();
ProjectFileIndex fileIndex = ProjectRootManager.getInstance(myProject).getFileIndex();
for (VirtualFile child : childrenf) {
diff --git a/platform/lang-impl/src/com/intellij/util/ui/tree/LanguagePerFileConfigurable.java b/platform/lang-impl/src/com/intellij/util/ui/tree/LanguagePerFileConfigurable.java
index c2d234fbaa51..4e445b2e1d1a 100644
--- a/platform/lang-impl/src/com/intellij/util/ui/tree/LanguagePerFileConfigurable.java
+++ b/platform/lang-impl/src/com/intellij/util/ui/tree/LanguagePerFileConfigurable.java
@@ -26,6 +26,7 @@ import com.intellij.openapi.options.ConfigurationException;
import com.intellij.openapi.options.SearchableConfigurable;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.openapi.vfs.VirtualFileFilter;
import com.intellij.ui.ColoredTableCellRenderer;
import com.intellij.ui.ScrollPaneFactory;
import com.intellij.ui.SimpleTextAttributes;
@@ -56,7 +57,7 @@ public abstract class LanguagePerFileConfigurable implements SearchableConfig
private JPanel myPanel;
private JLabel myLabel;
- protected LanguagePerFileConfigurable(final Project project, Class valueClass, PerFileMappings mappings, String caption, String treeTableTitle, String overrideQuestion, String overrideTitle) {
+ protected LanguagePerFileConfigurable(@NotNull Project project, Class valueClass, PerFileMappings mappings, String caption, String treeTableTitle, String overrideQuestion, String overrideTitle) {
myProject = project;
myValueClass = valueClass;
myMappings = mappings;
@@ -131,9 +132,8 @@ public abstract class LanguagePerFileConfigurable implements SearchableConfig
}
private class MyTreeTable extends AbstractFileTreeTable {
-
public MyTreeTable() {
- super(myProject, myValueClass, myTreeTableTitle);
+ super(myProject, myValueClass, myTreeTableTitle, VirtualFileFilter.ALL, true);
getValueColumn().setCellEditor(new DefaultCellEditor(new JComboBox()) {
private VirtualFile myVirtualFile;
diff --git a/platform/platform-api/src/com/intellij/ide/GeneralSettings.java b/platform/platform-api/src/com/intellij/ide/GeneralSettings.java
index ca2980cabc61..3c5ae9b5708b 100644
--- a/platform/platform-api/src/com/intellij/ide/GeneralSettings.java
+++ b/platform/platform-api/src/com/intellij/ide/GeneralSettings.java
@@ -129,11 +129,11 @@ public class GeneralSettings implements NamedJDOMExternalizable, ExportableAppli
/**
* @return a path pointing to a directory where the last project was created or null if not available
*/
- public String getLastProjectLocation() {
+ public String getLastProjectCreationLocation() {
return myLastProjectLocation;
}
- public void setLastProjectLocation(String lastProjectLocation) {
+ public void setLastProjectCreationLocation(String lastProjectLocation) {
myLastProjectLocation = lastProjectLocation;
}
diff --git a/platform/platform-api/src/com/intellij/openapi/actionSystem/AnActionEvent.java b/platform/platform-api/src/com/intellij/openapi/actionSystem/AnActionEvent.java
index 937c6efb6e52..37035e382e14 100644
--- a/platform/platform-api/src/com/intellij/openapi/actionSystem/AnActionEvent.java
+++ b/platform/platform-api/src/com/intellij/openapi/actionSystem/AnActionEvent.java
@@ -65,9 +65,10 @@ public class AnActionEvent implements PlaceProvider {
myModifiers = modifiers;
}
- public static AnActionEvent createFromInputEvent(AnAction action, InputEvent event, String place) {
- DataContext context = event != null ? DataManager.getInstance().getDataContext(event.getComponent()) : DataManager.getInstance().getDataContext();
- int modifiers = event != null ? event.getModifiers() : 0;
+ @NotNull
+ public static AnActionEvent createFromInputEvent(@NotNull AnAction action, InputEvent event, @NotNull String place) {
+ DataContext context = event == null ? DataManager.getInstance().getDataContext() : DataManager.getInstance().getDataContext(event.getComponent());
+ int modifiers = event == null ? 0 : event.getModifiers();
return new AnActionEvent(
event,
context,
diff --git a/platform/platform-api/src/com/intellij/openapi/actionSystem/DefaultActionGroup.java b/platform/platform-api/src/com/intellij/openapi/actionSystem/DefaultActionGroup.java
index 1bb4be43e4ce..b4bbc2056d6c 100644
--- a/platform/platform-api/src/com/intellij/openapi/actionSystem/DefaultActionGroup.java
+++ b/platform/platform-api/src/com/intellij/openapi/actionSystem/DefaultActionGroup.java
@@ -56,7 +56,7 @@ public class DefaultActionGroup extends ActionGroup {
* @param actions the actions to add to the group
* @since 9.0
*/
- public DefaultActionGroup(AnAction... actions) {
+ public DefaultActionGroup(@NotNull AnAction... actions) {
this(null, false);
for (AnAction action : actions) {
add(action);
diff --git a/platform/platform-api/src/com/intellij/openapi/actionSystem/ex/ComboBoxAction.java b/platform/platform-api/src/com/intellij/openapi/actionSystem/ex/ComboBoxAction.java
index 9bed852c693b..920532158bd0 100644
--- a/platform/platform-api/src/com/intellij/openapi/actionSystem/ex/ComboBoxAction.java
+++ b/platform/platform-api/src/com/intellij/openapi/actionSystem/ex/ComboBoxAction.java
@@ -27,7 +27,6 @@ import com.intellij.openapi.wm.IdeFocusManager;
import com.intellij.ui.ColorUtil;
import com.intellij.ui.IdeBorderFactory;
import com.intellij.ui.awt.RelativePoint;
-import com.intellij.util.Consumer;
import com.intellij.util.ui.GraphicsUtil;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.NotNull;
@@ -48,9 +47,11 @@ public abstract class ComboBoxAction extends AnAction implements CustomComponent
protected ComboBoxAction() {
}
+ @Override
public void actionPerformed(AnActionEvent e) {
}
+ @Override
public JComponent createCustomComponent(Presentation presentation) {
JPanel panel = new JPanel(new GridBagLayout());
ComboBoxButton button = createComboBoxButton(presentation);
@@ -114,9 +115,11 @@ public abstract class ComboBoxAction extends AnAction implements CustomComponent
}
addActionListener(
new ActionListener() {
+ @Override
public void actionPerformed(ActionEvent e) {
if (!myForcePressed) {
IdeFocusManager.getGlobalInstance().doWhenFocusSettlesDown(new Runnable() {
+ @Override
public void run() {
showPopup();
}
@@ -197,9 +200,11 @@ public abstract class ComboBoxAction extends AnAction implements CustomComponent
repaint();
Runnable onDispose = new Runnable() {
+ @Override
public void run() {
// give button chance to handle action listener
UIUtil.invokeLaterIfNeeded(new Runnable() {
+ @Override
public void run() {
myForcePressed = false;
myPopup = null;
@@ -210,7 +215,7 @@ public abstract class ComboBoxAction extends AnAction implements CustomComponent
};
myPopup = createPopup(onDispose);
- myPopup.show(new RelativePoint(this, new Point(0, this.getHeight() - 1)));
+ myPopup.show(new RelativePoint(this, new Point(0, getHeight() - 1)));
}
@Nullable
@@ -263,7 +268,7 @@ public abstract class ComboBoxAction extends AnAction implements CustomComponent
private void updateTooltipText(String description) {
String tooltip = AnAction.createTooltipText(description, ComboBoxAction.this);
- setToolTipText(tooltip.length() > 0 ? tooltip : null);
+ setToolTipText(!tooltip.isEmpty() ? tooltip : null);
}
@Override
@@ -275,16 +280,19 @@ public abstract class ComboBoxAction extends AnAction implements CustomComponent
}
protected class MyButtonModel extends DefaultButtonModel {
+ @Override
public boolean isPressed() {
return myForcePressed || super.isPressed();
}
+ @Override
public boolean isArmed() {
return myForcePressed || super.isArmed();
}
}
private class MyButtonSynchronizer implements PropertyChangeListener {
+ @Override
public void propertyChange(PropertyChangeEvent evt) {
String propertyName = evt.getPropertyName();
if (Presentation.PROP_TEXT.equals(propertyName)) {
@@ -390,7 +398,7 @@ public abstract class ComboBoxAction extends AnAction implements CustomComponent
}
}
else {
- super.paintComponent(g);
+ paintComponent(g);
}
final Insets insets = super.getInsets();
final Icon icon = isEnabled() ? AllIcons.General.ComboArrow : DISABLED_ARROW_ICON;
diff --git a/platform/platform-api/src/com/intellij/openapi/vfs/ReadonlyStatusHandler.java b/platform/platform-api/src/com/intellij/openapi/vfs/ReadonlyStatusHandler.java
index 21ddd3bd36c4..c5bd39e7a905 100644
--- a/platform/platform-api/src/com/intellij/openapi/vfs/ReadonlyStatusHandler.java
+++ b/platform/platform-api/src/com/intellij/openapi/vfs/ReadonlyStatusHandler.java
@@ -32,7 +32,10 @@ public abstract class ReadonlyStatusHandler {
public static boolean ensureDocumentWritable(@NotNull Project project, @NotNull Document document) {
final PsiFile psiFile = PsiDocumentManager.getInstance(project).getPsiFile(document);
boolean okWritable;
- if (psiFile != null) {
+ if (psiFile == null) {
+ okWritable = document.isWritable();
+ }
+ else {
final VirtualFile virtualFile = psiFile.getVirtualFile();
if (virtualFile != null) {
okWritable = ensureFilesWritable(project, virtualFile);
@@ -41,9 +44,6 @@ public abstract class ReadonlyStatusHandler {
okWritable = psiFile.isWritable();
}
}
- else {
- okWritable = document.isWritable();
- }
return okWritable;
}
@@ -60,7 +60,7 @@ public abstract class ReadonlyStatusHandler {
public abstract OperationStatus ensureFilesWritable(@NotNull VirtualFile... files);
public OperationStatus ensureFilesWritable(@NotNull Collection files) {
- return ensureFilesWritable(VfsUtil.toVirtualFileArray(files));
+ return ensureFilesWritable(VfsUtilCore.toVirtualFileArray(files));
}
public static ReadonlyStatusHandler getInstance(Project project) {
diff --git a/platform/platform-api/src/com/intellij/openapi/vfs/encoding/EncodingProjectManager.java b/platform/platform-api/src/com/intellij/openapi/vfs/encoding/EncodingProjectManager.java
index 27ed79d0835e..2282163668ba 100644
--- a/platform/platform-api/src/com/intellij/openapi/vfs/encoding/EncodingProjectManager.java
+++ b/platform/platform-api/src/com/intellij/openapi/vfs/encoding/EncodingProjectManager.java
@@ -20,6 +20,7 @@ import com.intellij.openapi.components.ProjectComponent;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
import org.jdom.Element;
+import org.jetbrains.annotations.NotNull;
import java.nio.charset.Charset;
import java.util.Map;
@@ -32,8 +33,9 @@ public abstract class EncodingProjectManager extends EncodingManager implements
return project.getComponent(EncodingProjectManager.class);
}
+ @NotNull
public abstract Map getAllMappings();
- public abstract void setMapping(Map result);
+ public abstract void setMapping(@NotNull Map result);
}
diff --git a/platform/platform-api/src/com/intellij/ui/ErrorLabel.java b/platform/platform-api/src/com/intellij/ui/ErrorLabel.java
index 3f7df6fb4b60..b398c70b613c 100644
--- a/platform/platform-api/src/com/intellij/ui/ErrorLabel.java
+++ b/platform/platform-api/src/com/intellij/ui/ErrorLabel.java
@@ -37,7 +37,7 @@ public class ErrorLabel extends JLabel {
}
public ErrorLabel(String text, Icon icon) {
- super(text, icon, JLabel.LEFT);
+ super(text, icon, SwingConstants.LEFT);
setOpaque(false);
}
@@ -52,6 +52,7 @@ public class ErrorLabel extends JLabel {
}
}
+ @Override
public void setToolTipText(String text) {
if (myUnderline) {
myTooltip = text;
@@ -69,24 +70,26 @@ public class ErrorLabel extends JLabel {
repaint();
}
+ @Override
protected void paintComponent(Graphics g) {
-
super.paintComponent(g);
- if (getText() != null & myUnderline) {
+ String text = getText();
+ if (text != null && myUnderline) {
g.setColor(myForeground);
int x = 0;
- if (getIcon() != null) {
- x = getIcon().getIconWidth() + getIconTextGap();
+ Icon icon = getIcon();
+ if (icon != null) {
+ x = icon.getIconWidth() + getIconTextGap();
}
if (getHorizontalAlignment() == CENTER) {
- int w = g.getFontMetrics().stringWidth(getText());
+ int w = g.getFontMetrics().stringWidth(text);
x += (getWidth() - x - w) >> 1;
}
- drawWave(this, g, x, getText());
+ drawWave(this, g, x, text);
}
}
@@ -117,6 +120,6 @@ public class ErrorLabel extends JLabel {
private static int getTextBaseLine(Component c) {
FontMetrics fm = c.getFontMetrics(c.getFont());
- return (c.getHeight() >> 1) + ((fm.getHeight() >> 1) - fm.getDescent());
+ return (c.getHeight() >> 1) + (fm.getHeight() >> 1) - fm.getDescent();
}
}
diff --git a/platform/platform-api/src/com/intellij/ui/GroupedElementsRenderer.java b/platform/platform-api/src/com/intellij/ui/GroupedElementsRenderer.java
index 32472df76248..2293d45bf329 100644
--- a/platform/platform-api/src/com/intellij/ui/GroupedElementsRenderer.java
+++ b/platform/platform-api/src/com/intellij/ui/GroupedElementsRenderer.java
@@ -113,57 +113,66 @@ public abstract class GroupedElementsRenderer {
return getBorder();
}
- private Border getSelectedBorder() {
+ private static Border getSelectedBorder() {
return UIUtil.isToUseDottedCellBorder() ? new DottedBorder(UIUtil.getListCellPadding(), SELECTED_FRAME_FOREGROUND) : new EmptyBorder(UIUtil.getListCellPadding());
}
- private Border getBorder() {
+ private static Border getBorder() {
return new EmptyBorder(UIUtil.getListCellPadding());
}
- public static abstract class List extends GroupedElementsRenderer {
-
+ public abstract static class List extends GroupedElementsRenderer {
+ @Override
protected final void layout() {
myRendererComponent.add(mySeparatorComponent, BorderLayout.NORTH);
myRendererComponent.add(myComponent, BorderLayout.CENTER);
}
+ @Override
protected final Color getSelectionBackground() {
return UIUtil.getListSelectionBackground();
}
+ @Override
protected final Color getSelectionForeground() {
return UIUtil.getListSelectionForeground();
}
+ @Override
protected final Color getBackground() {
return UIUtil.getListBackground();
}
+ @Override
protected final Color getForeground() {
return UIUtil.getListForeground();
}
}
- public static abstract class Tree extends GroupedElementsRenderer implements TreeCellRenderer {
+ public abstract static class Tree extends GroupedElementsRenderer implements TreeCellRenderer {
+ @Override
protected void layout() {
myRendererComponent.add(mySeparatorComponent, BorderLayout.NORTH);
myRendererComponent.add(myComponent, BorderLayout.WEST);
}
+ @Override
protected final Color getSelectionBackground() {
return UIUtil.getTreeSelectionBackground();
}
+ @Override
protected final Color getSelectionForeground() {
return UIUtil.getTreeSelectionForeground();
}
+ @Override
protected final Color getBackground() {
return UIUtil.getTreeTextBackground();
}
+ @Override
protected final Color getForeground() {
return UIUtil.getTreeTextForeground();
}
diff --git a/platform/platform-impl/src/com/intellij/ide/impl/ProjectUtil.java b/platform/platform-impl/src/com/intellij/ide/impl/ProjectUtil.java
index c72131529adf..51f30aa244dd 100644
--- a/platform/platform-impl/src/com/intellij/ide/impl/ProjectUtil.java
+++ b/platform/platform-impl/src/com/intellij/ide/impl/ProjectUtil.java
@@ -20,6 +20,7 @@ import com.intellij.ide.GeneralSettings;
import com.intellij.ide.IdeBundle;
import com.intellij.ide.highlighter.ProjectFileType;
import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.application.ApplicationNamesInfo;
import com.intellij.openapi.application.ModalityState;
import com.intellij.openapi.components.StorageScheme;
import com.intellij.openapi.components.impl.stores.IProjectStore;
@@ -37,6 +38,7 @@ import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.wm.*;
import com.intellij.projectImport.ProjectOpenProcessor;
import com.intellij.ui.AppIcon;
+import com.intellij.util.SystemProperties;
import org.jdom.JDOMException;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -73,7 +75,7 @@ public class ProjectUtil {
LOG.info(e);
return;
}
- GeneralSettings.getInstance().setLastProjectLocation(path.replace(File.separatorChar, '/'));
+ GeneralSettings.getInstance().setLastProjectCreationLocation(path.replace(File.separatorChar, '/'));
}
/**
@@ -275,4 +277,15 @@ public class ProjectUtil {
public static boolean isProjectOrWorkspaceFile(final VirtualFile file) {
return com.intellij.openapi.project.ProjectUtil.isProjectOrWorkspaceFile(file);
}
+
+ public static String getBaseDir() {
+ final String lastProjectLocation = GeneralSettings.getInstance().getLastProjectCreationLocation();
+ if (lastProjectLocation != null) {
+ return lastProjectLocation.replace('/', File.separatorChar);
+ }
+ final String userHome = SystemProperties.getUserHome();
+ //noinspection HardCodedStringLiteral
+ return userHome.replace('/', File.separatorChar) + File.separator + ApplicationNamesInfo.getInstance().getLowercaseProductName() +
+ "Projects";
+ }
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/FileDocumentManagerImpl.java b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/FileDocumentManagerImpl.java
index ed799699675f..cfa64deb84f5 100644
--- a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/FileDocumentManagerImpl.java
+++ b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/FileDocumentManagerImpl.java
@@ -120,6 +120,9 @@ public class FileDocumentManagerImpl extends FileDocumentManager implements Appl
try {
method.invoke(myBus.syncPublisher(AppTopics.FILE_DOCUMENT_SYNC), args);
}
+ catch (ClassCastException e) {
+ LOG.error("Arguments: "+ Arrays.toString(args), e);
+ }
catch (Exception e) {
LOG.error(e);
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/ui/impl/DialogWrapperPeerImpl.java b/platform/platform-impl/src/com/intellij/openapi/ui/impl/DialogWrapperPeerImpl.java
index 31aeaf50fdab..b6f9d07ed1f7 100644
--- a/platform/platform-impl/src/com/intellij/openapi/ui/impl/DialogWrapperPeerImpl.java
+++ b/platform/platform-impl/src/com/intellij/openapi/ui/impl/DialogWrapperPeerImpl.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2012 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -45,7 +45,6 @@ import com.intellij.ui.*;
import com.intellij.ui.mac.foundation.Foundation;
import com.intellij.ui.mac.foundation.ID;
import com.intellij.ui.mac.foundation.MacUtil;
-import com.intellij.ui.popup.StackingPopupDispatcherImpl;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
@@ -67,11 +66,8 @@ public class DialogWrapperPeerImpl extends DialogWrapperPeer implements FocusTra
private DialogWrapper myWrapper;
private AbstractDialog myDialog;
private boolean myCanBeParent = true;
- /*
- * Default dialog's actions.
- */
private WindowManagerEx myWindowManager;
- private final java.util.List myDisposeActions = new ArrayList();
+ private final List myDisposeActions = new ArrayList();
private Project myProject;
private final ActionCallback myWindowFocusedCallback = new ActionCallback("DialogFocusedCallback");
@@ -89,7 +85,7 @@ public class DialogWrapperPeerImpl extends DialogWrapperPeer implements FocusTra
*/
protected DialogWrapperPeerImpl(DialogWrapper wrapper, @Nullable Project project, boolean canBeParent) {
myWrapper = wrapper;
- myTypeAheadCallback = myWrapper.isTypeAheadEnabled() ? new ActionCallback() : (ActionCallback)null;
+ myTypeAheadCallback = myWrapper.isTypeAheadEnabled() ? new ActionCallback() : null;
myWindowManager = null;
Application application = ApplicationManager.getApplication();
if (application != null && application.hasComponent(WindowManager.class)) {
@@ -100,6 +96,7 @@ public class DialogWrapperPeerImpl extends DialogWrapperPeer implements FocusTra
if (myWindowManager != null) {
if (project == null) {
+ //noinspection deprecation
project = PlatformDataKeys.PROJECT.getData(DataManager.getInstance().getDataContext());
}
@@ -150,7 +147,7 @@ public class DialogWrapperPeerImpl extends DialogWrapperPeer implements FocusTra
}
/**
- * @param parent parent component whicg is used to canculate heavy weight window ancestor.
+ * @param parent parent component which is used to calculate heavy weight window ancestor.
* parent cannot be null and must be showing.
*/
protected DialogWrapperPeerImpl(DialogWrapper wrapper, @NotNull Component parent, boolean canBeParent) {
@@ -211,18 +208,11 @@ public class DialogWrapperPeerImpl extends DialogWrapperPeer implements FocusTra
return;
}
- if (owner instanceof Frame) {
- myDialog = new MyDialog((Frame)owner, myWrapper, myProject, myWindowFocusedCallback, myTypeAheadDone, myTypeAheadCallback);
- }
- else {
- myDialog = new MyDialog((Dialog)owner, myWrapper, myProject, myWindowFocusedCallback, myTypeAheadDone, myTypeAheadCallback);
- }
+ myDialog = new MyDialog(owner, myWrapper, myProject, myWindowFocusedCallback, myTypeAheadDone, myTypeAheadCallback);
myDialog.setModal(true);
myCanBeParent = canBeParent;
-
}
-
public void toFront() {
myDialog.toFront();
}
@@ -231,6 +221,7 @@ public class DialogWrapperPeerImpl extends DialogWrapperPeer implements FocusTra
myDialog.toBack();
}
+ @SuppressWarnings("SSBasedInspection")
protected void dispose() {
LOG.assertTrue(EventQueue.isDispatchThread(), "Access is allowed from event dispatch thread only");
for (Runnable runnable : myDisposeActions) {
@@ -243,14 +234,6 @@ public class DialogWrapperPeerImpl extends DialogWrapperPeer implements FocusTra
public void run() {
myDialog.dispose();
myProject = null;
- /*
- if (myWindowManager == null) {
- myDialog.dispose();
- }
- else {
- myWindowManager.hideDialog(myDialog, myProject);
- }
- */
SwingUtilities.invokeLater(new Runnable() {
public void run() {
@@ -403,14 +386,6 @@ public class DialogWrapperPeerImpl extends DialogWrapperPeer implements FocusTra
final boolean appStarted = commandProcessor != null;
if (myDialog.isModal() && !isProgressDialog()) {
- /*
- if (ApplicationManager.getApplication() != null) {
- if (ApplicationManager.getApplication().getCurrentWriteAction(null) != null) {
- LOG.warn(
- "Showing of a modal dialog inside write-action may be dangerous and resulting in unpredictable behavior! Current modalityState=" + ModalityState.current(), new Exception());
- }
- }
- */
if (appStarted) {
commandProcessor.enterModal();
LaterInvocator.enterModal(myDialog);
@@ -438,16 +413,14 @@ public class DialogWrapperPeerImpl extends DialogWrapperPeer implements FocusTra
return result;
}
-//[kirillk] for now it only deals with the TaskWindow under Mac OS X: modal dialogs are shown behind JBPopup
-
//hopefully this whole code will go away
private void hidePopupsIfNeeded() {
if (!SystemInfo.isMac) return;
- StackingPopupDispatcherImpl.getInstance().hidePersistentPopups();
+ StackingPopupDispatcher.getInstance().hidePersistentPopups();
myDisposeActions.add(new Runnable() {
public void run() {
- StackingPopupDispatcherImpl.getInstance().restorePersistentPopups();
+ StackingPopupDispatcher.getInstance().restorePersistentPopups();
}
});
}
@@ -488,6 +461,7 @@ public class DialogWrapperPeerImpl extends DialogWrapperPeer implements FocusTra
private static class MyDialog extends JDialog implements DialogWrapperDialog, DataProvider, FocusTrackback.Provider, Queryable, AbstractDialog {
private final WeakReference myDialogWrapper;
+
/**
* Initial size of the dialog. When the dialog is being closed and
* current size of the dialog is not equals to the initial size then the
@@ -507,16 +481,12 @@ public class DialogWrapperPeerImpl extends DialogWrapperPeer implements FocusTra
private ActionCallback myTypeAheadCallback;
private MyComponentListener myComponentListener;
- public MyDialog(Dialog owner, DialogWrapper dialogWrapper, Project project, ActionCallback focused, ActionCallback typeAheadDone, ActionCallback typeAheadCallback) {
- super(owner);
- myDialogWrapper = new WeakReference(dialogWrapper);
- myProject = project != null ? new WeakReference(project) : null;
- initDialog(focused, typeAheadDone, typeAheadCallback);
- }
-
-
-
- public MyDialog(Frame owner, DialogWrapper dialogWrapper, Project project, ActionCallback focused, ActionCallback typeAheadDone, ActionCallback typeAheadCallback) {
+ public MyDialog(Window owner,
+ DialogWrapper dialogWrapper,
+ Project project,
+ ActionCallback focused,
+ ActionCallback typeAheadDone,
+ ActionCallback typeAheadCallback) {
super(owner);
myDialogWrapper = new WeakReference(dialogWrapper);
myProject = project != null ? new WeakReference(project) : null;
@@ -605,6 +575,7 @@ public class DialogWrapperPeerImpl extends DialogWrapperPeer implements FocusTra
return new DialogRootPane();
}
+ @SuppressWarnings("deprecation")
public void show() {
myFocusTrackback = new FocusTrackback(getDialogWrapper(), getParent(), true);
@@ -628,7 +599,7 @@ public class DialogWrapperPeerImpl extends DialogWrapperPeer implements FocusTra
location = DimensionService.getInstance().getLocation(myDimensionServiceKey, projectGuess);
Dimension size = DimensionService.getInstance().getSize(myDimensionServiceKey, projectGuess);
if (size != null) {
- myInitialSize = (Dimension)size.clone();
+ myInitialSize = new Dimension(size);
_setSizeForLocation(myInitialSize.width, myInitialSize.height, location);
}
}
@@ -653,7 +624,8 @@ public class DialogWrapperPeerImpl extends DialogWrapperPeer implements FocusTra
setBounds(bounds);
addWindowListener(new WindowAdapter() {
- public void windowActivated(final WindowEvent e) {
+ @Override
+ public void windowActivated(WindowEvent e) {
final DialogWrapper wrapper = getDialogWrapper();
if (wrapper != null && myFocusTrackback != null) {
myFocusTrackback.cleanParentWindow();
@@ -665,10 +637,12 @@ public class DialogWrapperPeerImpl extends DialogWrapperPeer implements FocusTra
}
}
- public void windowDeactivated(final WindowEvent e) {
+ @Override
+ public void windowDeactivated(WindowEvent e) {
if (!isModal()) {
final Ref focusManager = new Ref(null);
- if (myProject != null && myProject.get() != null && !myProject.get().isDisposed()) {
+ Project project = getProject();
+ if (project != null && !project.isDisposed()) {
focusManager.set(getFocusManager());
focusManager.get().doWhenFocusSettlesDown(new Runnable() {
public void run() {
@@ -681,6 +655,20 @@ public class DialogWrapperPeerImpl extends DialogWrapperPeer implements FocusTra
}
}
}
+
+ @Override
+ public void windowOpened(WindowEvent e) {
+ if (!SystemInfo.isMacOSLion) return;
+ Window window = e.getWindow();
+ if (window instanceof Dialog) {
+ ID _native = MacUtil.findWindowForTitle(((Dialog)window).getTitle());
+ if (_native != null && _native.intValue() > 0) {
+ // see MacMainFrameDecorator
+ // NSCollectionBehaviorFullScreenAuxiliary = 1 << 8
+ Foundation.invoke(_native, "setCollectionBehavior:", 1 << 8);
+ }
+ }
+ }
});
if (Registry.is("actionSystem.fixLostTyping")) {
@@ -697,40 +685,28 @@ public class DialogWrapperPeerImpl extends DialogWrapperPeer implements FocusTra
}
}
- if (SystemInfo.isMacOSLion) {
- final WindowAdapter macFullScreenPatchListener = new WindowAdapter() {
- @Override
- public void windowOpened(WindowEvent e) {
- Window window = e.getWindow();
- if (window instanceof Dialog) {
- ID _native = MacUtil.findWindowForTitle(((Dialog)window).getTitle());
- if (_native != null && _native.intValue() > 0) {
- // see MacMainFrameDecorator
- // NSCollectionBehaviorFullScreenAuxiliary = 1 << 8
- Foundation.invoke(_native, "setCollectionBehavior:", 1 << 8);
- }
- }
- }
- };
-
- addWindowListener(macFullScreenPatchListener);
- }
if (SystemInfo.isMac && myProject != null && Registry.is("ide.mac.fix.dialog.showing") && !dialogWrapper.isModalProgress()) {
final IdeFrame frame = WindowManager.getInstance().getIdeFrame(myProject.get());
AppIcon.getInstance().requestFocus(frame);
}
- setBackground(UIUtil.getPanelBackground());
- superShow();
- }
- private void superShow() {
+ setBackground(UIUtil.getPanelBackground());
+
super.show();
}
+ @Nullable
+ private Project getProject() {
+ return myProject != null ? myProject.get() : null;
+ }
+
+ @Override
public IdeFocusManager getFocusManager() {
- if (myProject != null && myProject.get() != null && !myProject.get().isDisposed()) {
- return IdeFocusManager.getInstance(myProject.get());
- } else {
+ Project project = getProject();
+ if (project != null && !project.isDisposed()) {
+ return IdeFocusManager.getInstance(project);
+ }
+ else {
return IdeFocusManager.findInstance();
}
}
@@ -758,7 +734,8 @@ public class DialogWrapperPeerImpl extends DialogWrapperPeer implements FocusTra
}
}
- @Deprecated
+ @Override
+ @SuppressWarnings("deprecation")
public void hide() {
super.hide();
if (myFocusTrackback != null && !(myFocusTrackback.isSheduledForRestore() || myFocusTrackback.isWillBeSheduledForRestore())) {
@@ -774,6 +751,7 @@ public class DialogWrapperPeerImpl extends DialogWrapperPeer implements FocusTra
}
}
+ @Override
public void dispose() {
if (isShowing()) {
hide();
@@ -858,6 +836,7 @@ public class DialogWrapperPeerImpl extends DialogWrapperPeer implements FocusTra
super.paint(g);
}
+ @SuppressWarnings("SSBasedInspection")
private class MyWindowListener extends WindowAdapter {
public void windowClosing(WindowEvent e) {
DialogWrapper dialogWrapper = getDialogWrapper();
@@ -866,6 +845,7 @@ public class DialogWrapperPeerImpl extends DialogWrapperPeer implements FocusTra
}
}
+ @Override
public void windowClosed(WindowEvent e) {
saveSize();
}
@@ -888,7 +868,6 @@ public class DialogWrapperPeerImpl extends DialogWrapperPeer implements FocusTra
}
}
-
@Override
public void windowOpened(WindowEvent e) {
SwingUtilities.invokeLater(new Runnable() {
@@ -904,6 +883,7 @@ public class DialogWrapperPeerImpl extends DialogWrapperPeer implements FocusTra
});
}
+ @Override
public void windowActivated(final WindowEvent e) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
@@ -979,8 +959,8 @@ public class DialogWrapperPeerImpl extends DialogWrapperPeer implements FocusTra
Robot robot = new Robot();
robot.mouseMove(p.x + r.width / 2, p.y + r.height / 2);
}
- catch (AWTException exc) {
- exc.printStackTrace();
+ catch (AWTException e) {
+ LOG.warn(e);
}
}
}
@@ -1016,7 +996,7 @@ public class DialogWrapperPeerImpl extends DialogWrapperPeer implements FocusTra
public Object getData(@NonNls String dataId) {
final DialogWrapper wrapper = myDialogWrapper.get();
- return PlatformDataKeys.UI_DISPOSABLE.is(dataId) ? wrapper.getDisposable() : null;
+ return wrapper != null && PlatformDataKeys.UI_DISPOSABLE.is(dataId) ? wrapper.getDisposable() : null;
}
}
@@ -1057,7 +1037,7 @@ public class DialogWrapperPeerImpl extends DialogWrapperPeer implements FocusTra
myEvents.addAll(context.getQueue());
context.getQueue().clear();
- if (isToDipatchToDialogNow(e)) {
+ if (isToDispatchToDialogNow(e)) {
return false;
} else {
myEvents.add(e);
@@ -1065,7 +1045,7 @@ public class DialogWrapperPeerImpl extends DialogWrapperPeer implements FocusTra
}
}
- private boolean isToDipatchToDialogNow(KeyEvent e) {
+ private boolean isToDispatchToDialogNow(KeyEvent e) {
return e.getKeyCode() == KeyEvent.VK_ENTER || e.getKeyCode() == KeyEvent.VK_ESCAPE || e.getKeyCode() == KeyEvent.VK_TAB;
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/CheckForUpdateAction.java b/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/CheckForUpdateAction.java
index 315706a84900..c7b15139569e 100644
--- a/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/CheckForUpdateAction.java
+++ b/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/CheckForUpdateAction.java
@@ -52,15 +52,19 @@ public class CheckForUpdateAction extends AnAction implements DumbAware {
indicator.setIndeterminate(true);
final CheckForUpdateResult result = UpdateChecker.checkForUpdates(instance, true);
+ if (result.getState() == UpdateStrategy.State.CONNECTION_ERROR) {
+ ApplicationManager.getApplication().invokeLater(new Runnable() {
+ public void run() {
+ UpdateChecker.showConnectionErrorDialog();
+ }
+ });
+ return;
+ }
+
final List updatedPlugins = UpdateChecker.updatePlugins(true, hostsConfigurable, indicator);
ApplicationManager.getApplication().invokeLater(new Runnable() {
@Override
public void run() {
- if (result.getState() == UpdateStrategy.State.CONNECTION_ERROR) {
- UpdateChecker.showConnectionErrorDialog();
- return;
- }
-
instance.saveLastCheckedInfo();
UpdateChecker.showUpdateResult(result, updatedPlugins, true, enableLink, true);
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/vcs/readOnlyHandler/ReadonlyStatusHandlerImpl.java b/platform/platform-impl/src/com/intellij/openapi/vcs/readOnlyHandler/ReadonlyStatusHandlerImpl.java
index 2bc5f2586219..2848d019acb3 100644
--- a/platform/platform-impl/src/com/intellij/openapi/vcs/readOnlyHandler/ReadonlyStatusHandlerImpl.java
+++ b/platform/platform-impl/src/com/intellij/openapi/vcs/readOnlyHandler/ReadonlyStatusHandlerImpl.java
@@ -26,10 +26,7 @@ import com.intellij.openapi.components.StoragePathMacros;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Condition;
import com.intellij.openapi.util.MultiValuesMap;
-import com.intellij.openapi.vfs.ReadonlyStatusHandler;
-import com.intellij.openapi.vfs.VfsUtil;
-import com.intellij.openapi.vfs.VirtualFile;
-import com.intellij.openapi.vfs.WritingAccessProvider;
+import com.intellij.openapi.vfs.*;
import com.intellij.util.containers.ContainerUtil;
import gnu.trove.THashSet;
import org.jetbrains.annotations.NotNull;
@@ -59,14 +56,17 @@ public class ReadonlyStatusHandlerImpl extends ReadonlyStatusHandler implements
myAccessProviders = WritingAccessProvider.getProvidersForProject(myProject);
}
+ @Override
public State getState() {
return myState;
}
+ @Override
public void loadState(State state) {
myState = state;
}
+ @Override
public OperationStatus ensureFilesWritable(@NotNull VirtualFile... files) {
if (files.length == 0) {
return new OperationStatusImpl(VirtualFile.EMPTY_ARRAY);
@@ -80,7 +80,7 @@ public class ReadonlyStatusHandlerImpl extends ReadonlyStatusHandler implements
realFiles.add(file);
}
}
- files = VfsUtil.toVirtualFileArray(realFiles);
+ files = VfsUtilCore.toVirtualFileArray(realFiles);
for (final WritingAccessProvider accessProvider : myAccessProviders) {
Collection denied = ContainerUtil.filter(files, new Condition() {
@@ -94,7 +94,7 @@ public class ReadonlyStatusHandlerImpl extends ReadonlyStatusHandler implements
denied = accessProvider.requestWriting(files);
}
if (!denied.isEmpty()) {
- return new OperationStatusImpl(VfsUtil.toVirtualFileArray(denied));
+ return new OperationStatusImpl(VfsUtilCore.toVirtualFileArray(denied));
}
}
@@ -131,7 +131,7 @@ public class ReadonlyStatusHandlerImpl extends ReadonlyStatusHandler implements
}
}
- return new OperationStatusImpl(VfsUtil.toVirtualFileArray(readOnlyFiles));
+ return new OperationStatusImpl(VfsUtilCore.toVirtualFileArray(readOnlyFiles));
}
private FileInfo[] createFileInfos(VirtualFile[] files) {
@@ -170,15 +170,18 @@ public class ReadonlyStatusHandlerImpl extends ReadonlyStatusHandler implements
myReadonlyFiles = readonlyFiles;
}
+ @Override
@NotNull
public VirtualFile[] getReadonlyFiles() {
return myReadonlyFiles;
}
+ @Override
public boolean hasReadonlyFiles() {
return myReadonlyFiles.length > 0;
}
+ @Override
@NotNull
public String getReadonlyFilesMessage() {
if (hasReadonlyFiles()) {
diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/encoding/ChangeFileEncodingGroup.java b/platform/platform-impl/src/com/intellij/openapi/vfs/encoding/ChangeFileEncodingGroup.java
deleted file mode 100644
index 2c86df555602..000000000000
--- a/platform/platform-impl/src/com/intellij/openapi/vfs/encoding/ChangeFileEncodingGroup.java
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Copyright 2000-2009 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.openapi.vfs.encoding;
-
-import com.intellij.openapi.actionSystem.*;
-import com.intellij.openapi.project.DumbAware;
-import com.intellij.openapi.vfs.CharsetToolkit;
-import com.intellij.openapi.vfs.VirtualFile;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-
-import java.nio.charset.Charset;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
-/**
- * @author cdr
- */
-public class ChangeFileEncodingGroup extends ActionGroup {
- @Override
- @NotNull
- public AnAction[] getChildren(@Nullable final AnActionEvent e) {
- if (e == null) return EMPTY_ARRAY;
- VirtualFile virtualFile = e.getData(PlatformDataKeys.VIRTUAL_FILE);
- if(virtualFile == null || !virtualFile.isInLocalFileSystem()){
- return EMPTY_ARRAY;
- }
-
- List charsets = new ArrayList(EncodingManager.getInstance().getFavorites());
- Collections.sort(charsets);
- Charset current = virtualFile.getCharset();
- charsets.remove(current);
-
- List children = new ArrayList(charsets.size());
- for (Charset charset : charsets) {
- ChangeFileEncodingTo action = new ChangeFileEncodingTo(virtualFile, charset);
- children.add(action);
- }
-
- children.add(new More(virtualFile));
- children.add(new Separator());
- return children.toArray(new AnAction[children.size()]);
- }
-
- private static class More extends AnAction implements DumbAware {
- private final VirtualFile myVirtualFile;
-
- private More(VirtualFile virtualFile) {
- myVirtualFile = virtualFile;
- getTemplatePresentation().setText("more...");
- }
-
- @Override
- public void actionPerformed(final AnActionEvent e) {
- Charset[] charsets = CharsetToolkit.getAvailableCharsets();
-
- ChooseEncodingDialog dialog = new ChooseEncodingDialog(charsets, myVirtualFile.getCharset(), myVirtualFile);
- dialog.show();
- Charset charset = dialog.getChosen();
- if (dialog.isOK() && charset != null) {
- EncodingManager.getInstance().setEncoding(myVirtualFile, charset);
- }
- }
- }
-}
diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/encoding/ChangeFileEncodingTo.java b/platform/platform-impl/src/com/intellij/openapi/vfs/encoding/ChangeFileEncodingTo.java
index 2a01bfa7a7aa..89ef1c34d02c 100644
--- a/platform/platform-impl/src/com/intellij/openapi/vfs/encoding/ChangeFileEncodingTo.java
+++ b/platform/platform-impl/src/com/intellij/openapi/vfs/encoding/ChangeFileEncodingTo.java
@@ -17,36 +17,25 @@ package com.intellij.openapi.vfs.encoding;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
-import com.intellij.openapi.util.Pair;
-import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.project.DumbAware;
+import com.intellij.openapi.vfs.VirtualFile;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.nio.charset.Charset;
+import java.text.MessageFormat;
/**
* @author cdr
*/
-class ChangeFileEncodingTo extends AnAction implements DumbAware {
+abstract class ChangeFileEncodingTo extends AnAction implements DumbAware {
private final VirtualFile myFile;
private final Charset myCharset;
- ChangeFileEncodingTo(@Nullable VirtualFile file, @NotNull Charset charset) {
- super(charset.displayName());
+ ChangeFileEncodingTo(@Nullable VirtualFile file, @NotNull Charset charset, @NotNull String pattern) {
+ super(charset.displayName(), MessageFormat.format(pattern, file == null ? null : file.getName(), charset.displayName()), null);
myFile = file;
myCharset = charset;
-
- String description;
- if (file == null) {
- description = "Change default encoding to '"+charset.displayName()+"'.";
- }
- else {
- Pair result = ChooseFileEncodingAction.update(file);
- boolean enabled = result.second;
- description = enabled ? result.first + " '" + charset.displayName() + "'" : result.first;
- }
- getTemplatePresentation().setDescription(description);
}
@Override
@@ -54,7 +43,5 @@ class ChangeFileEncodingTo extends AnAction implements DumbAware {
chosen(myFile, myCharset);
}
- protected void chosen(@Nullable VirtualFile file, @NotNull Charset charset) {
- EncodingManager.getInstance().setEncoding(file, charset);
- }
+ protected abstract void chosen(@Nullable VirtualFile file, @NotNull Charset charset);
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/encoding/ChooseFileEncodingAction.java b/platform/platform-impl/src/com/intellij/openapi/vfs/encoding/ChooseFileEncodingAction.java
index 17cf9d238eca..a831e990df61 100644
--- a/platform/platform-impl/src/com/intellij/openapi/vfs/encoding/ChooseFileEncodingAction.java
+++ b/platform/platform-impl/src/com/intellij/openapi/vfs/encoding/ChooseFileEncodingAction.java
@@ -22,6 +22,7 @@
*/
package com.intellij.openapi.vfs.encoding;
+import com.intellij.icons.AllIcons;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.DefaultActionGroup;
@@ -32,13 +33,13 @@ import com.intellij.openapi.fileEditor.impl.LoadTextUtil;
import com.intellij.openapi.fileTypes.FileType;
import com.intellij.openapi.fileTypes.FileTypes;
import com.intellij.openapi.fileTypes.StdFileTypes;
+import com.intellij.openapi.util.Condition;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.vfs.CharsetToolkit;
import com.intellij.openapi.vfs.VirtualFile;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
-import javax.swing.*;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import java.nio.charset.CharsetEncoder;
@@ -56,68 +57,44 @@ public abstract class ChooseFileEncodingAction extends ComboBoxAction {
}
@Override
- public void update(final AnActionEvent e) {
- Pair result = update(myVirtualFile);
+ public abstract void update(final AnActionEvent e);
- boolean enabled = result.second;
- if (myVirtualFile != null) {
- Charset charset = cachedCharsetFromContent(myVirtualFile);
- String prefix = charset == null ? "" : "Encoding (auto-detected):";
- if (charset == null) charset = myVirtualFile.getCharset();
- e.getPresentation().setText(prefix + " " + charset.toString());
- }
- e.getPresentation().setEnabled(enabled);
- e.getPresentation().setDescription(result.first);
- }
-
- // returns null if "change encoding" action is enabled for the file;
- // reason why not, if it is disabled
- public static String isEnabledAndWhyNot(@Nullable VirtualFile virtualFile) {
- if (virtualFile == null) {
- return "file not specified";
- }
- Charset charset = cachedCharsetFromContent(virtualFile);
- if (charset != null) {
- return "charset specified inside the file";
- }
- if (virtualFile.isDirectory()) {
- return null;
- }
+ @NotNull
+ private static Pair checkFileType(@NotNull VirtualFile virtualFile) {
FileType fileType = virtualFile.getFileType();
- if (fileType.isBinary()) return "binary file";
- if (fileType == StdFileTypes.GUI_DESIGNER_FORM) return "IDEA GUI Designer form";
- if (fileType == StdFileTypes.IDEA_MODULE) return "IDEA module file";
- if (fileType == StdFileTypes.IDEA_PROJECT) return "IDEA project file";
- if (fileType == StdFileTypes.IDEA_WORKSPACE) return "IDEA workspace file";
+ if (fileType.isBinary()) return Pair.create(null, "binary file");
+ if (fileType == StdFileTypes.GUI_DESIGNER_FORM) return Pair.create(CharsetToolkit.UTF8_CHARSET, "IDEA GUI Designer form");
+ if (fileType == StdFileTypes.IDEA_MODULE) return Pair.create(CharsetToolkit.UTF8_CHARSET, "IDEA module file");
+ if (fileType == StdFileTypes.IDEA_PROJECT) return Pair.create(CharsetToolkit.UTF8_CHARSET, "IDEA project file");
+ if (fileType == StdFileTypes.IDEA_WORKSPACE) return Pair.create(CharsetToolkit.UTF8_CHARSET, "IDEA workspace file");
- if (fileType == StdFileTypes.PROPERTIES) return ".properties file";
+ if (fileType == StdFileTypes.PROPERTIES) return Pair.create(virtualFile.getCharset(), ".properties file");
if (fileType == StdFileTypes.XML
|| fileType == StdFileTypes.JSPX && fileType != FileTypes.PLAIN_TEXT // in community tests JSPX==PLAIN_TEXT
) {
- return "XML file";
+ return Pair.create(virtualFile.getCharset(), "XML file");
}
- return null;
+ return Pair.create(null, null);
}
- @Nullable("returns null if charset set cannot be determined from content")
- public static Charset cachedCharsetFromContent(final VirtualFile virtualFile) {
- if (virtualFile == null) return null;
- final Document document = FileDocumentManager.getInstance().getDocument(virtualFile);
- if (document == null) return null;
+ private void fillCharsetActions(@NotNull DefaultActionGroup group,
+ @Nullable VirtualFile virtualFile,
+ @NotNull List charsets,
+ @Nullable final Condition charsetFilter,
+ @NotNull String pattern) {
+ for (final Charset slave : charsets) {
+ ChangeFileEncodingTo action = new ChangeFileEncodingTo(virtualFile, slave, pattern) {
+ {
+ if (charsetFilter != null && !charsetFilter.value(slave)) {
+ getTemplatePresentation().setIcon(AllIcons.General.Warning);
+ }
+ }
- return EncodingManager.getInstance().getCachedCharsetFromContent(document);
- }
+ @Override
+ public void update(AnActionEvent e) {
+ }
- @Override
- @NotNull
- protected DefaultActionGroup createPopupActionGroup(final JComponent button) {
- return createGroup("");
- }
-
- private void fillCharsetActions(DefaultActionGroup group, final VirtualFile virtualFile, List charsets) {
- for (Charset slave : charsets) {
- ChangeFileEncodingTo action = new ChangeFileEncodingTo(virtualFile, slave){
@Override
protected void chosen(final VirtualFile file, @NotNull final Charset charset) {
ChooseFileEncodingAction.this.chosen(file, charset);
@@ -127,60 +104,71 @@ public abstract class ChooseFileEncodingAction extends ComboBoxAction {
}
}
- // returns (action text, enabled flag)
- @NotNull
- public static Pair update(@Nullable VirtualFile virtualFile) {
- String pattern;
- String failReason = isEnabledAndWhyNot(virtualFile);
- boolean enabled = failReason == null;
- Charset charsetFromContent = cachedCharsetFromContent(virtualFile);
- if (virtualFile != null && FileDocumentManager.getInstance().isFileModified(virtualFile)) {
- //no sense to reload file with UTF-detected chars using other encoding
- if (charsetFromContent != null) {
- pattern = "Encoding (content-specified): {0}";
- enabled = false;
- }
- else if (enabled) {
- pattern = "Save ''{0}'' file in another encoding";
- }
- else {
- pattern = "Encoding ''{0}'' ("+failReason+")";
- }
+ @Nullable("null means enabled, notnull means disabled and contains error message")
+ public static String checkCanConvert(@NotNull VirtualFile virtualFile) {
+ if (virtualFile.isDirectory()) {
+ return "file is a directory";
+ }
+ String reason = LoadTextUtil.wasCharsetDetectedFromBytes(virtualFile);
+ if (reason == null) {
+ return null;
+ }
+ String failReason = null;
+
+ Charset charsetFromContent = ((EncodingManagerImpl)EncodingManager.getInstance()).computeCharsetFromContent(virtualFile);
+ if (charsetFromContent != null) {
+ failReason = "hard coded in text, encoding: {0}";
}
else {
- // try to reload
- // no sense in reloading file with UTF-detected chars using other encoding
- if (virtualFile != null && LoadTextUtil.wasCharsetDetectedFromBytes(virtualFile)) {
- pattern = "Encoding (auto-detected): {0}";
- enabled = false;
- }
- else if (enabled && virtualFile != null && virtualFile.isDirectory()) {
- pattern = "Reload ''{0}'' files under the directory in";
- }
- else if (enabled) {
- pattern = "Reload ''{0}'' file in another encoding";
- }
- else if (charsetFromContent != null) {
- pattern = "Encoding (content-specified): {0}";
- }
- else {
- pattern = "Encoding ''{0}'' ("+failReason+")";
+ Pair check = checkFileType(virtualFile);
+ if (check.second != null) {
+ failReason = check.second;
}
}
- Charset charset = charsetFromContent != null ? charsetFromContent : virtualFile != null ? virtualFile.getCharset() : NO_ENCODING;
- String text = charset == NO_ENCODING ? "Change file encoding" : MessageFormat.format(pattern, charset.displayName());
+ if (failReason != null) {
+ return MessageFormat.format(failReason, charsetFromContent == null ? "" : charsetFromContent.displayName());
+ }
+ return null;
+ }
- return Pair.create(text, enabled);
+ @NotNull
+ // returns existing charset (null means N/A), failReason: null means enabled, notnull means disabled and contains error message
+ public static Pair checkCanReload(@NotNull VirtualFile virtualFile) {
+ if (virtualFile.isDirectory()) {
+ return Pair.create(null, "file is a directory");
+ }
+ FileDocumentManager documentManager = FileDocumentManager.getInstance();
+ Document document = documentManager.getDocument(virtualFile);
+ if (document == null) return Pair.create(null, "binary file");
+ Charset charsetFromContent = ((EncodingManagerImpl)EncodingManager.getInstance()).computeCharsetFromContent(virtualFile);
+ Charset existing = charsetFromContent;
+ String failReason = LoadTextUtil.wasCharsetDetectedFromBytes(virtualFile);
+ if (failReason != null) {
+ // no point changing encoding if it was auto-detected
+ existing = virtualFile.getCharset();
+ }
+ else if (charsetFromContent != null) {
+ failReason = "hard coded in text";
+ }
+ else {
+ Pair fileTypeCheck = checkFileType(virtualFile);
+ if (fileTypeCheck.second != null) {
+ failReason = fileTypeCheck.second;
+ existing = fileTypeCheck.first;
+ }
+ }
+ if (failReason != null) {
+ return Pair.create(existing, failReason);
+ }
+ return Pair.create(virtualFile.getCharset(), null);
}
private class ClearThisFileEncodingAction extends AnAction {
private final VirtualFile myFile;
private ClearThisFileEncodingAction(@Nullable VirtualFile file, @NotNull String clearItemText) {
- super(clearItemText, "Clear " +
- (file == null ? "default" : "file '"+file.getName()+"'") +
- " encoding.", null);
+ super(clearItemText, "Clear " + (file == null ? "default" : "file '"+file.getName()+"'") + " encoding.", null);
myFile = file;
}
@@ -209,25 +197,29 @@ public abstract class ChooseFileEncodingAction extends ComboBoxAction {
protected abstract void chosen(@Nullable VirtualFile virtualFile, @NotNull Charset charset);
@NotNull
- public DefaultActionGroup createGroup(@Nullable String clearItemText) {
+ public DefaultActionGroup createGroup(@Nullable("null means do not show 'clear' text") String clearItemText,
+ @Nullable Condition charsetFilter,
+ @NotNull String pattern,
+ Charset alreadySelected) {
DefaultActionGroup group = new DefaultActionGroup();
List favorites = new ArrayList(EncodingManager.getInstance().getFavorites());
Collections.sort(favorites);
Charset current = myVirtualFile == null ? null : myVirtualFile.getCharset();
favorites.remove(current);
+ favorites.remove(alreadySelected);
if (clearItemText != null) {
group.add(new ClearThisFileEncodingAction(myVirtualFile, clearItemText));
}
if (favorites.isEmpty() && clearItemText == null) {
- fillCharsetActions(group, myVirtualFile, Arrays.asList(CharsetToolkit.getAvailableCharsets()));
+ fillCharsetActions(group, myVirtualFile, Arrays.asList(CharsetToolkit.getAvailableCharsets()), charsetFilter, pattern);
}
else {
- fillCharsetActions(group, myVirtualFile, favorites);
+ fillCharsetActions(group, myVirtualFile, favorites, charsetFilter, pattern);
DefaultActionGroup more = new DefaultActionGroup("more", true);
group.add(more);
- fillCharsetActions(more, myVirtualFile, Arrays.asList(CharsetToolkit.getAvailableCharsets()));
+ fillCharsetActions(more, myVirtualFile, Arrays.asList(CharsetToolkit.getAvailableCharsets()), charsetFilter, pattern);
}
return group;
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/encoding/ConvertFileEncodingAction.java b/platform/platform-impl/src/com/intellij/openapi/vfs/encoding/ConvertFileEncodingAction.java
new file mode 100644
index 000000000000..b12dfa53a5a5
--- /dev/null
+++ b/platform/platform-impl/src/com/intellij/openapi/vfs/encoding/ConvertFileEncodingAction.java
@@ -0,0 +1,124 @@
+/*
+ * Copyright 2000-2012 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.openapi.vfs.encoding;
+
+import com.intellij.icons.AllIcons;
+import com.intellij.openapi.editor.Document;
+import com.intellij.openapi.editor.Editor;
+import com.intellij.openapi.fileEditor.FileDocumentManager;
+import com.intellij.openapi.fileEditor.impl.LoadTextUtil;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.project.ProjectLocator;
+import com.intellij.openapi.ui.Messages;
+import com.intellij.openapi.util.Pair;
+import com.intellij.openapi.vfs.ReadonlyStatusHandler;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.openapi.vfs.VirtualFileEvent;
+import com.intellij.openapi.vfs.VirtualFileListener;
+import com.intellij.refactoring.util.CommonRefactoringUtil;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.io.IOException;
+import java.nio.charset.Charset;
+import java.text.MessageFormat;
+
+/**
+ * @author cdr
+*/
+public class ConvertFileEncodingAction extends ReloadFileInOtherEncodingAction {
+ public ConvertFileEncodingAction() {
+ text = "Convert to...";
+ }
+
+ @Nullable
+ @Override
+ // document, description
+ public Pair checkEnabled(@NotNull VirtualFile virtualFile) {
+ String failReason = ChooseFileEncodingAction.checkCanConvert(virtualFile);
+ if (failReason != null) return null;
+ FileDocumentManager documentManager = FileDocumentManager.getInstance();
+ Document document = documentManager.getDocument(virtualFile);
+ if (document == null) return null;
+
+ Charset charsetFromContent = EncodingManager.getInstance().getCachedCharsetFromContent(document);
+ Charset charset = charsetFromContent != null ? charsetFromContent : virtualFile.getCharset();
+ String text = MessageFormat.format("Convert ''{0}''-encoded file ''{1}'' to another encoding", charset.displayName(), virtualFile.getName());
+
+ return Pair.create(document, text);
+ }
+
+ @Override
+ public boolean value(Charset charset) {
+ return canBeConvertedTo(myFile, charset);
+ }
+
+ public static boolean canBeConvertedTo(@NotNull VirtualFile virtualFile, @NotNull Charset charset) {
+ FileDocumentManager documentManager = FileDocumentManager.getInstance();
+ Document document = documentManager.getDocument(virtualFile);
+ if (document == null) return false;
+ String text = document.getText();
+ Pair chosen = LoadTextUtil.chooseMostlyHarmlessCharset(virtualFile.getCharset(), charset, text);
+
+ byte[] buffer = chosen.second;
+
+ CharSequence textLoadedBack = LoadTextUtil.getTextByBinaryPresentation(buffer, charset);
+
+ return text.equals(textLoadedBack.toString());
+ }
+
+ @Override
+ protected void chosen(@NotNull Document document, Editor editor, @NotNull VirtualFile virtualFile, @NotNull final Charset charset) {
+ if (!canBeConvertedTo(virtualFile, charset)) {
+ int res = Messages.showDialog("Encoding '" + charset.displayName() + "' does not support some characters from the text.",
+ "Incompatible Encoding: "+charset.displayName(), new String[]{"Convert anyway", "Cancel"}, 1, AllIcons.General.WarningDialog);
+ if (res != 0) return;
+ }
+ convert(document, editor, virtualFile, charset);
+ }
+
+ public static void convert(@NotNull Document document, Editor editor, @NotNull VirtualFile virtualFile, @NotNull Charset charset) {
+ FileDocumentManager documentManager = FileDocumentManager.getInstance();
+ if (documentManager.isFileModified(virtualFile)) {
+ EncodingManager.getInstance().setEncoding(virtualFile, charset);
+
+ LoadTextUtil.setCharsetWasDetectedFromBytes(virtualFile, null);
+
+ documentManager.saveDocument(document);
+ }
+ else {
+ Project project = ProjectLocator.getInstance().guessProjectForFile(virtualFile);
+ boolean writable = project == null ? virtualFile.isWritable() : ReadonlyStatusHandler.ensureFilesWritable(project, virtualFile);
+ if (!writable) {
+ CommonRefactoringUtil
+ .showErrorHint(project, editor, "Cannot save the file " + virtualFile.getPresentableUrl(), "Unable to Save", null);
+ return;
+ }
+
+ virtualFile.setCharset(charset);
+ try {
+ LoadTextUtil.write(project, virtualFile, virtualFile, document.getText(), document.getModificationStamp());
+ }
+ catch (IOException io) {
+ Messages.showErrorDialog(project, io.getMessage(), "Error Writing File");
+ }
+
+ EncodingManager.getInstance().setEncoding(virtualFile, charset);
+
+ ((VirtualFileListener)documentManager).contentsChanged(new VirtualFileEvent(null, virtualFile, virtualFile.getName(), virtualFile.getParent()));
+ }
+ }
+}
diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/encoding/EncodingManagerImpl.java b/platform/platform-impl/src/com/intellij/openapi/vfs/encoding/EncodingManagerImpl.java
index 3700a5432ad1..fcc7d6165274 100644
--- a/platform/platform-impl/src/com/intellij/openapi/vfs/encoding/EncodingManagerImpl.java
+++ b/platform/platform-impl/src/com/intellij/openapi/vfs/encoding/EncodingManagerImpl.java
@@ -41,6 +41,7 @@ import com.intellij.openapi.project.Project;
import com.intellij.openapi.project.ProjectLocator;
import com.intellij.openapi.project.ProjectManager;
import com.intellij.openapi.util.Comparing;
+import com.intellij.openapi.util.Computable;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.vfs.CharsetToolkit;
@@ -126,13 +127,36 @@ public class EncodingManagerImpl extends EncodingManager implements PersistentSt
Charset charset = LoadTextUtil.charsetFromContentOrNull(project, virtualFile, document.getText());
Charset oldCached = getCachedCharsetFromContent(document);
if (!Comparing.equal(charset, oldCached)) {
- document.putUserData(CACHED_CHARSET_FROM_CONTENT, charset);
- firePropertyChange(PROP_CACHED_ENCODING_CHANGED, oldCached, charset);
+ setCachedCharsetFromContent(charset, oldCached, document);
}
}
});
}
+ private void setCachedCharsetFromContent(Charset charset, Charset oldCached, Document document) {
+ document.putUserData(CACHED_CHARSET_FROM_CONTENT, charset);
+ firePropertyChange(PROP_CACHED_ENCODING_CHANGED, oldCached, charset);
+ }
+
+ @Nullable("returns null if charset set cannot be determined from content")
+ public Charset computeCharsetFromContent(@NotNull final VirtualFile virtualFile) {
+ final Document document = FileDocumentManager.getInstance().getDocument(virtualFile);
+ if (document == null) return null;
+ final Charset cached = EncodingManager.getInstance().getCachedCharsetFromContent(document);
+ if (cached != null) return cached;
+ final Project project = ProjectLocator.getInstance().guessProjectForFile(virtualFile);
+ return ApplicationManager.getApplication().runReadAction(new Computable() {
+ @Override
+ public Charset compute() {
+ Charset charsetFromContent = LoadTextUtil.charsetFromContentOrNull(project, virtualFile, document.getText());
+ if (charsetFromContent != null) {
+ setCachedCharsetFromContent(charsetFromContent, cached, document);
+ }
+ return charsetFromContent;
+ }
+ });
+ }
+
@Override
public void dispose() {
updateEncodingFromContent.cancelAllRequests();
diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/encoding/EncodingProjectManagerImpl.java b/platform/platform-impl/src/com/intellij/openapi/vfs/encoding/EncodingProjectManagerImpl.java
index ae0e2cb5feeb..e98ae8f275b7 100644
--- a/platform/platform-impl/src/com/intellij/openapi/vfs/encoding/EncodingProjectManagerImpl.java
+++ b/platform/platform-impl/src/com/intellij/openapi/vfs/encoding/EncodingProjectManagerImpl.java
@@ -36,8 +36,12 @@ import com.intellij.openapi.fileEditor.impl.LoadTextUtil;
import com.intellij.openapi.fileTypes.StdFileTypes;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.project.ProjectManager;
+import com.intellij.openapi.roots.ProjectFileIndex;
+import com.intellij.openapi.roots.ProjectRootManager;
+import com.intellij.openapi.startup.StartupManager;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.ModificationTracker;
+import com.intellij.openapi.util.Pair;
import com.intellij.openapi.vfs.*;
import com.intellij.psi.PsiDocumentManager;
import com.intellij.psi.PsiFile;
@@ -75,7 +79,10 @@ public class EncodingProjectManagerImpl extends EncodingProjectManager {
}
};
- public EncodingProjectManagerImpl(Project project, GeneralSettings generalSettings, EditorSettingsExternalizable editorSettings, PsiDocumentManager documentManager) {
+ public EncodingProjectManagerImpl(Project project,
+ GeneralSettings generalSettings,
+ EditorSettingsExternalizable editorSettings,
+ PsiDocumentManager documentManager) {
myProject = project;
myGeneralSettings = generalSettings;
myEditorSettings = editorSettings;
@@ -123,6 +130,7 @@ public class EncodingProjectManagerImpl extends EncodingProjectManager {
@Override
public void loadState(Element element) {
List files = element.getChildren("file");
+ final Map mapping = new HashMap();
for (Element fileElement : files) {
String url = fileElement.getAttributeValue("url");
String charsetName = fileElement.getAttributeValue("charset");
@@ -130,9 +138,23 @@ public class EncodingProjectManagerImpl extends EncodingProjectManager {
if (charset == null) continue;
VirtualFile file = url.equals("PROJECT") ? null : VirtualFileManager.getInstance().findFileByUrl(url);
if (file != null || url.equals("PROJECT")) {
- myMapping.put(file, charset);
+ mapping.put(file, charset);
}
}
+ StartupManager.getInstance(myProject).runWhenProjectIsInitialized(new Runnable() {
+ @Override
+ public void run() {
+ if (myProject.isDisposed()) {
+ // give last chance to save
+ myMapping.clear();
+ myMapping.putAll(mapping);
+ }
+ else {
+ setMapping(mapping);
+ }
+ }
+ });
+
myUseUTFGuessing = Boolean.parseBoolean(element.getAttributeValue("useUTFGuessing"));
myNative2AsciiForPropertiesFiles = Boolean.parseBoolean(element.getAttributeValue("native2AsciiForPropertiesFiles"));
myDefaultCharsetForPropertiesFiles = CharsetToolkit.forName(element.getAttributeValue("defaultCharsetForPropertiesFiles"));
@@ -206,12 +228,11 @@ public class EncodingProjectManagerImpl extends EncodingProjectManager {
setAndSaveOrReload(virtualFileOrDir, charset);
}
- private static void setAndSaveOrReload(final VirtualFile virtualFileOrDir, final Charset charset) {
- if (virtualFileOrDir == null || virtualFileOrDir.isDirectory()) {
+ private static void setAndSaveOrReload(VirtualFile virtualFileOrDir, Charset charset) {
+ if (virtualFileOrDir == null) {
return;
}
virtualFileOrDir.setCharset(charset);
- LoadTextUtil.setCharsetWasDetectedFromBytes(virtualFileOrDir, false);
saveOrReload(virtualFileOrDir);
}
@@ -235,29 +256,44 @@ public class EncodingProjectManagerImpl extends EncodingProjectManager {
result.addAll(myMapping.values());
result.add(CharsetToolkit.UTF8_CHARSET);
result.add(CharsetToolkit.getDefaultSystemCharset());
+ result.add(CharsetToolkit.UTF_16_CHARSET);
+ result.add(CharsetToolkit.forName("ISO-8859-1"));
+ result.add(CharsetToolkit.forName("US-ASCII"));
+ result.add(EncodingManager.getInstance().getDefaultCharset());
+ result.add(EncodingManager.getInstance().getDefaultCharsetForPropertiesFiles(null));
return result;
}
+ @NotNull
@Override
public Map getAllMappings() {
return myMapping;
}
@Override
- public void setMapping(final Map result) {
- Map map = new HashMap(result);
- //todo return it back as soon as FileIndex get to the platform
- //ProjectFileIndex fileIndex = ProjectRootManager.getInstance(myProject).getFileIndex();
- //for (VirtualFile file : result.keySet()) {
- // if (file != null && !fileIndex.isInContent(file)) {
- // map.remove(file);
- // }
- //}
+ public void setMapping(@NotNull final Map result) {
+ Map map = new HashMap(result.size());
+ ProjectFileIndex fileIndex = ProjectRootManager.getInstance(myProject).getFileIndex();
+ for (Map.Entry entry : result.entrySet()) {
+ VirtualFile virtualFile = entry.getKey();
+ Charset charset = entry.getValue();
+ if (virtualFile != null && !fileIndex.isInContent(virtualFile)) {
+ continue;
+ }
+ Pair check = virtualFile == null || virtualFile.isDirectory() ? null : ChooseFileEncodingAction.checkCanReload(virtualFile);
+ String failReason = check == null ? null : check.second;
+ boolean enabled = failReason == null;
+ if (!enabled) {
+ continue; // file became autodetected, exclude from explicitly specified
+ }
+ map.put(virtualFile, charset);
+ }
myMapping.clear();
myMapping.putAll(map);
- for (VirtualFile virtualFile : map.keySet()) {
- Charset charset = map.get(virtualFile);
+ for (Map.Entry entry : map.entrySet()) {
+ Charset charset = entry.getValue();
assert charset != null;
+ VirtualFile virtualFile = entry.getKey();
setAndSaveOrReload(virtualFile, charset);
}
if (!myProject.isDefault()) {
diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/encoding/ChangeEncodingUpdateGroup.java b/platform/platform-impl/src/com/intellij/openapi/vfs/encoding/FileChangeEncodingGroup.java
similarity index 71%
rename from platform/platform-impl/src/com/intellij/openapi/vfs/encoding/ChangeEncodingUpdateGroup.java
rename to platform/platform-impl/src/com/intellij/openapi/vfs/encoding/FileChangeEncodingGroup.java
index b6797822d0bd..43b4265e91e0 100644
--- a/platform/platform-impl/src/com/intellij/openapi/vfs/encoding/ChangeEncodingUpdateGroup.java
+++ b/platform/platform-impl/src/com/intellij/openapi/vfs/encoding/FileChangeEncodingGroup.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2012 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -18,20 +18,24 @@ package com.intellij.openapi.vfs.encoding;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.DefaultActionGroup;
import com.intellij.openapi.actionSystem.PlatformDataKeys;
+import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.fileEditor.OpenFileDescriptor;
import com.intellij.openapi.project.DumbAware;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.openapi.wm.impl.status.EncodingActionsPair;
import com.intellij.pom.Navigatable;
/**
* @author cdr
*/
-public class ChangeEncodingUpdateGroup extends DefaultActionGroup implements DumbAware {
+public class FileChangeEncodingGroup extends DefaultActionGroup implements DumbAware {
private boolean myUpdating;
-
+
+ private final EncodingActionsPair encodingActionsPair = new EncodingActionsPair();
+
@Override
- public void update(final AnActionEvent e) {
+ public void update(AnActionEvent e) {
if (myUpdating) {
return;
}
@@ -51,12 +55,19 @@ public class ChangeEncodingUpdateGroup extends DefaultActionGroup implements Dum
virtualFile = null;
}
- Pair result = ChooseFileEncodingAction.update(virtualFile);
+ Editor editor = e.getData(PlatformDataKeys.EDITOR);
+ boolean enabled =
+ encodingActionsPair.areActionsEnabled(null, editor, editor == null ? null : editor.getComponent(), virtualFile, getEventProject(e));
+ removeAll();
+ if (enabled) {
+ addAll(encodingActionsPair.createActionGroup());
+ }
+
myUpdating = true;
try {
- e.getPresentation().setText(result.getFirst());
+ e.getPresentation().setText("File encoding");
// updating the enabled state of the action can trigger the menuSelected handler, which updates the action group again
- e.getPresentation().setEnabled(result.getSecond());
+ e.getPresentation().setEnabled(enabled);
}
finally {
myUpdating = false;
diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/encoding/ReloadFileInOtherEncodingAction.java b/platform/platform-impl/src/com/intellij/openapi/vfs/encoding/ReloadFileInOtherEncodingAction.java
new file mode 100644
index 000000000000..130d320b43b0
--- /dev/null
+++ b/platform/platform-impl/src/com/intellij/openapi/vfs/encoding/ReloadFileInOtherEncodingAction.java
@@ -0,0 +1,151 @@
+/*
+ * Copyright 2000-2012 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.openapi.vfs.encoding;
+
+import com.intellij.AppTopics;
+import com.intellij.openapi.Disposable;
+import com.intellij.openapi.actionSystem.AnAction;
+import com.intellij.openapi.actionSystem.AnActionEvent;
+import com.intellij.openapi.actionSystem.DefaultActionGroup;
+import com.intellij.openapi.actionSystem.PlatformDataKeys;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.editor.Document;
+import com.intellij.openapi.editor.Editor;
+import com.intellij.openapi.fileEditor.FileDocumentManager;
+import com.intellij.openapi.fileEditor.FileDocumentManagerAdapter;
+import com.intellij.openapi.fileEditor.impl.LoadTextUtil;
+import com.intellij.openapi.project.DumbAware;
+import com.intellij.openapi.ui.popup.JBPopupFactory;
+import com.intellij.openapi.ui.popup.ListPopup;
+import com.intellij.openapi.util.Condition;
+import com.intellij.openapi.util.Disposer;
+import com.intellij.openapi.util.Pair;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.openapi.vfs.VirtualFileEvent;
+import com.intellij.openapi.vfs.VirtualFileListener;
+import com.intellij.util.messages.MessageBusConnection;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import javax.swing.*;
+import java.nio.charset.Charset;
+import java.text.MessageFormat;
+
+/**
+ * @author cdr
+*/
+public class ReloadFileInOtherEncodingAction extends AnAction implements DumbAware, Condition {
+ protected VirtualFile myFile;
+ protected String text;
+
+ public ReloadFileInOtherEncodingAction() {
+ text = "Reload in...";
+ }
+
+ @Nullable("null means disabled, otherwise it's the document and the action description")
+ protected Pair checkEnabled(@NotNull VirtualFile virtualFile) {
+ String failReason = ChooseFileEncodingAction.checkCanReload(virtualFile).second;
+ if (failReason != null) return null;
+ FileDocumentManager documentManager = FileDocumentManager.getInstance();
+ Document document = documentManager.getDocument(virtualFile);
+ if (document == null) return null;
+
+ Charset charsetFromContent = EncodingManager.getInstance().getCachedCharsetFromContent(document);
+ Charset charset = charsetFromContent != null ? charsetFromContent : virtualFile.getCharset();
+ String text = MessageFormat.format("Reload ''{0}''-encoded file ''{1}'' in another encoding", charset.displayName(), virtualFile.getName());
+
+ return Pair.create(document, text);
+ }
+
+ @Override
+ public void update(AnActionEvent e) {
+ myFile = e.getData(PlatformDataKeys.VIRTUAL_FILE);
+ Pair pair = myFile == null ? null : checkEnabled(myFile);
+ e.getPresentation().setEnabled(pair != null);
+ if (pair != null) {
+ e.getPresentation().setDescription(pair.second);
+ e.getPresentation().setText(text);
+ }
+ }
+
+ @Override
+ public final void actionPerformed(final AnActionEvent e) {
+ Pair pair = checkEnabled(myFile);
+ if (pair == null) return;
+ final Document document = pair.first;
+ final Editor editor = e.getData(PlatformDataKeys.EDITOR);
+
+ DefaultActionGroup group =
+ new ChooseFileEncodingAction(myFile) {
+ @Override
+ public void update(final AnActionEvent e) {
+ }
+
+ @NotNull
+ @Override
+ protected DefaultActionGroup createPopupActionGroup(JComponent button) {
+ return createGroup(null, ReloadFileInOtherEncodingAction.this, "Reload file ''{0}'' in''{1}''", myFile.getCharset()); // no 'clear'
+ }
+
+ @Override
+ protected void chosen(@Nullable VirtualFile virtualFile, @NotNull Charset charset) {
+ if (virtualFile != null) {
+ ReloadFileInOtherEncodingAction.this.chosen(document, editor, virtualFile, charset);
+ }
+ }
+ }
+ .createPopupActionGroup(null);
+
+ final ListPopup popup = JBPopupFactory.getInstance().createActionGroupPopup(
+ text, group, e.getDataContext(), JBPopupFactory.ActionSelectionAid.SPEEDSEARCH, false);
+ popup.showInBestPositionFor(e.getDataContext());
+ }
+
+ protected void chosen(@NotNull Document document, Editor editor, @NotNull VirtualFile virtualFile, @NotNull final Charset charset) {
+ FileDocumentManager documentManager = FileDocumentManager.getInstance();
+ //Project project = ProjectLocator.getInstance().guessProjectForFile(myFile);
+ //if (documentManager.isFileModified(myFile)) {
+ // int result = Messages.showDialog(project, "File is modified. Reload file anyway?", "File is Modified", new String[]{"Reload", "Cancel"}, 0, AllIcons.General.WarningDialog);
+ // if (result != 0) return;
+ //}
+
+ Disposable disposable = Disposer.newDisposable();
+ MessageBusConnection connection = ApplicationManager.getApplication().getMessageBus().connect(disposable);
+ connection.subscribe(AppTopics.FILE_DOCUMENT_SYNC, new FileDocumentManagerAdapter() {
+ @Override
+ public void beforeFileContentReload(VirtualFile file, @NotNull Document document) {
+ EncodingManager.getInstance().setEncoding(myFile, charset);
+
+ myFile.setCharset(charset);
+ LoadTextUtil.setCharsetWasDetectedFromBytes(myFile, null);
+ }
+ });
+
+ // if file was modified, the user will be asked here
+ try {
+ ((VirtualFileListener)documentManager).contentsChanged(new VirtualFileEvent(null, myFile, myFile.getName(), myFile.getParent()));
+ }
+ finally {
+ Disposer.dispose(disposable);
+ }
+ }
+
+ // charset filter
+ @Override
+ public boolean value(Charset charset) {
+ return true;
+ }
+}
diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/EncodingActionsPair.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/EncodingActionsPair.java
new file mode 100644
index 000000000000..0987e584b90f
--- /dev/null
+++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/EncodingActionsPair.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2000-2012 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.openapi.wm.impl.status;
+
+import com.intellij.ide.DataManager;
+import com.intellij.openapi.actionSystem.*;
+import com.intellij.openapi.actionSystem.impl.SimpleDataContext;
+import com.intellij.openapi.editor.Editor;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.openapi.vfs.encoding.ConvertFileEncodingAction;
+import com.intellij.openapi.vfs.encoding.ReloadFileInOtherEncodingAction;
+import org.jetbrains.annotations.NotNull;
+
+import java.awt.*;
+import java.awt.event.InputEvent;
+
+public class EncodingActionsPair {
+ private final ConvertFileEncodingAction convert = new ConvertFileEncodingAction();
+ private final ReloadFileInOtherEncodingAction reload = new ReloadFileInOtherEncodingAction();
+
+ public boolean areActionsEnabled(InputEvent e,Editor editor, Component component, VirtualFile selectedFile, Project project) {
+ DataContext dataContext = createDataContext(editor, component, selectedFile, project);
+ convert.update(new AnActionEvent(e, dataContext, "", convert.getTemplatePresentation(), ActionManager.getInstance(), 0));
+ reload.update(new AnActionEvent(e, dataContext, "", reload.getTemplatePresentation(), ActionManager.getInstance(), 0));
+ return convert.getTemplatePresentation().isEnabled() || reload.getTemplatePresentation().isEnabled();
+ }
+
+ @NotNull
+ public static DataContext createDataContext(Editor editor, Component component, VirtualFile selectedFile, Project project) {
+ DataContext parent = DataManager.getInstance().getDataContext(component);
+ return SimpleDataContext.getSimpleContext(PlatformDataKeys.VIRTUAL_FILE.getName(), selectedFile,
+ SimpleDataContext.getSimpleContext(PlatformDataKeys.PROJECT.getName(), project,
+ SimpleDataContext.getSimpleContext(PlatformDataKeys.CONTEXT_COMPONENT.getName(), editor == null ? null : editor.getComponent(),
+ parent)));
+ }
+
+ public DefaultActionGroup createActionGroup() {
+ DefaultActionGroup group = new DefaultActionGroup();
+ group.add(convert);
+ group.add(reload);
+
+ return group;
+ }
+
+}
diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/EncodingPanel.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/EncodingPanel.java
index d7818ff0dec9..a747593654de 100644
--- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/EncodingPanel.java
+++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/EncodingPanel.java
@@ -17,7 +17,9 @@ package com.intellij.openapi.wm.impl.status;
import com.intellij.icons.AllIcons;
import com.intellij.ide.DataManager;
-import com.intellij.openapi.actionSystem.*;
+import com.intellij.openapi.actionSystem.DataContext;
+import com.intellij.openapi.actionSystem.DefaultActionGroup;
+import com.intellij.openapi.actionSystem.PlatformDataKeys;
import com.intellij.openapi.actionSystem.impl.SimpleDataContext;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.editor.Document;
@@ -25,6 +27,7 @@ import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.EditorFactory;
import com.intellij.openapi.editor.event.DocumentAdapter;
import com.intellij.openapi.editor.event.DocumentEvent;
+import com.intellij.openapi.fileEditor.FileDocumentManager;
import com.intellij.openapi.fileEditor.FileEditorManager;
import com.intellij.openapi.fileEditor.FileEditorManagerEvent;
import com.intellij.openapi.project.Project;
@@ -47,7 +50,9 @@ import com.intellij.ui.ClickListener;
import com.intellij.ui.awt.RelativePoint;
import com.intellij.util.Alarm;
import com.intellij.util.ui.UIUtil;
+import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.awt.*;
@@ -66,7 +71,7 @@ public class EncodingPanel extends EditorBasedWidget implements StatusBarWidget.
public EncodingPanel(@NotNull final Project project) {
super(project);
- myComponent = new TextPanel(getMaxValue()){
+ myComponent = new TextPanel(getMaxValue()) {
@Override
protected void paintComponent(@NotNull final Graphics g) {
super.paintComponent(g);
@@ -78,6 +83,7 @@ public class EncodingPanel extends EditorBasedWidget implements StatusBarWidget.
}
}
};
+
new ClickListener() {
@Override
public boolean onClick(MouseEvent e, int clickCount) {
@@ -89,6 +95,15 @@ public class EncodingPanel extends EditorBasedWidget implements StatusBarWidget.
myComponent.setBorder(WidgetBorder.INSTANCE);
}
+ @Nullable("returns null if charset set cannot be determined from content")
+ private static Charset cachedCharsetFromContent(final VirtualFile virtualFile) {
+ if (virtualFile == null) return null;
+ final Document document = FileDocumentManager.getInstance().getDocument(virtualFile);
+ if (document == null) return null;
+
+ return EncodingManager.getInstance().getCachedCharsetFromContent(document);
+ }
+
@Override
public void selectionChanged(FileEditorManagerEvent event) {
if (ApplicationManager.getApplication().isUnitTestMode()) return;
@@ -105,15 +120,18 @@ public class EncodingPanel extends EditorBasedWidget implements StatusBarWidget.
return new EncodingPanel(getProject());
}
+ @Override
@NotNull
public String ID() {
return "Encoding";
}
+ @Override
public WidgetPresentation getPresentation(@NotNull PlatformType type) {
return null;
}
+ @NonNls
@NotNull
private static String getMaxValue() {
return "windows-1251";
@@ -157,59 +175,49 @@ public class EncodingPanel extends EditorBasedWidget implements StatusBarWidget.
}, this);
}
+ private final EncodingActionsPair encodingActionsPair = new EncodingActionsPair();
private void showPopup(MouseEvent e) {
- ListPopup popup = getPopupStep();
- if (popup == null) return;
- final Dimension dimension = popup.getContent().getPreferredSize();
- final Point at = new Point(0, -dimension.height);
+ if (!actionEnabled) {
+ return;
+ }
+ DataContext dataContext = getContext();
+ DefaultActionGroup group = encodingActionsPair.createActionGroup();
+
+ ListPopup popup =
+ JBPopupFactory.getInstance().createActionGroupPopup("File Encoding", group, dataContext, true, false, false, null, 2, null);
+
+ Dimension dimension = popup.getContent().getPreferredSize();
+ Point at = new Point(0, -dimension.height);
popup.show(new RelativePoint(e.getComponent(), at));
- Disposer.register(this, popup); // do not forget to destroy popup on unexpected project close
+ Disposer.register(this, popup); // destroy popup on unexpected project close
}
- private ListPopup getPopupStep() {
- Pair result = ChooseFileEncodingAction.update(getSelectedFile());
- boolean enabled = result.second;
- final DataContext parent = DataManager.getInstance().getDataContext((Component)myStatusBar);
- final DataContext dataContext =
- SimpleDataContext.getSimpleContext(PlatformDataKeys.VIRTUAL_FILE.getName(), getSelectedFile(),
- SimpleDataContext.getSimpleContext(PlatformDataKeys.PROJECT.getName(), getProject(), parent));
- if (!enabled) {
- return null;
- }
- DefaultActionGroup group = new ChooseFileEncodingAction(getSelectedFile()) {
- @Override
- protected void chosen(VirtualFile virtualFile, @NotNull Charset charset) {
- if (virtualFile != null) {
- EncodingManager.getInstance().setEncoding(virtualFile, charset);
- update(new AnActionEvent(null, dataContext, ActionPlaces.EDITOR_TOOLBAR, getTemplatePresentation(), ActionManager.getInstance(), 0));
- EncodingPanel.this.update();
- }
- }
- }.createGroup(null);
- return JBPopupFactory.getInstance().createActionGroupPopup(null, group, dataContext, false, false, false, null, 30, null);
+ @NotNull
+ private DataContext getContext() {
+ Editor editor = getEditor();
+ DataContext parent = DataManager.getInstance().getDataContext((Component)myStatusBar);
+ return SimpleDataContext.getSimpleContext(PlatformDataKeys.VIRTUAL_FILE.getName(), getSelectedFile(),
+ SimpleDataContext.getSimpleContext(PlatformDataKeys.PROJECT.getName(), getProject(),
+ SimpleDataContext.getSimpleContext(PlatformDataKeys.CONTEXT_COMPONENT.getName(), editor == null ? null : editor.getComponent(), parent)
+ ));
}
private void update() {
UIUtil.invokeLaterIfNeeded(new Runnable() {
@Override
public void run() {
- final VirtualFile file = getSelectedFile();
- Pair result = ChooseFileEncodingAction.update(file);
- String text;
- String toolTip;
- if (file != null) {
- Charset charset = ChooseFileEncodingAction.cachedCharsetFromContent(file);
- if (charset == null) charset = file.getCharset();
+ VirtualFile file = getSelectedFile();
+ Charset charset = cachedCharsetFromContent(file);
+ if (charset == null && file != null) charset = file.getCharset();
- text = charset.displayName();
- actionEnabled = result.second;
- toolTip = result.first;
- }
- else {
- text = "";
- actionEnabled = false;
- toolTip = "";
- }
+ String text = charset == null ? "" : charset.displayName();
+ actionEnabled = encodingActionsPair.areActionsEnabled(null,getEditor(), (Component)myStatusBar, file, getProject());
+
+ Pair check = file == null ? null : ChooseFileEncodingAction.checkCanReload(file);
+ String failReason = check == null ? null : check.second;
+ String toolTip = "File Encoding" +
+ (check == null || check.first == null ? "" : ": "+check.first.displayName()) +
+ (actionEnabled || failReason == null ? "" : " (change disabled: " + failReason + ")");
myComponent.setToolTipText(toolTip);
myComponent.setText(text);
diff --git a/platform/platform-impl/src/com/intellij/platform/NewDirectoryProjectAction.java b/platform/platform-impl/src/com/intellij/platform/NewDirectoryProjectAction.java
index dce4d144b390..eccd9fde6319 100644
--- a/platform/platform-impl/src/com/intellij/platform/NewDirectoryProjectAction.java
+++ b/platform/platform-impl/src/com/intellij/platform/NewDirectoryProjectAction.java
@@ -90,7 +90,7 @@ public class NewDirectoryProjectAction extends AnAction implements DumbAware {
return null;
}
}
- GeneralSettings.getInstance().setLastProjectLocation(location.getParent());
+ GeneralSettings.getInstance().setLastProjectCreationLocation(location.getParent());
final Object finalSettings = settings;
return PlatformProjectOpenProcessor.doOpenProject(baseDir, null, false, -1, new ProjectOpenedCallback() {
@Override
diff --git a/platform/platform-impl/src/com/intellij/platform/NewDirectoryProjectDialog.java b/platform/platform-impl/src/com/intellij/platform/NewDirectoryProjectDialog.java
index c5ff7cf862c7..757782851e80 100644
--- a/platform/platform-impl/src/com/intellij/platform/NewDirectoryProjectDialog.java
+++ b/platform/platform-impl/src/com/intellij/platform/NewDirectoryProjectDialog.java
@@ -18,15 +18,13 @@ package com.intellij.platform;
import com.intellij.facet.ui.FacetEditorValidator;
import com.intellij.facet.ui.FacetValidatorsManager;
import com.intellij.facet.ui.ValidationResult;
-import com.intellij.ide.GeneralSettings;
-import com.intellij.openapi.application.ApplicationNamesInfo;
+import com.intellij.ide.impl.ProjectUtil;
import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.openapi.ui.TextFieldWithBrowseButton;
import com.intellij.ui.DocumentAdapter;
import com.intellij.ui.ListCellRendererWrapper;
-import com.intellij.util.SystemProperties;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -36,7 +34,6 @@ import javax.swing.event.DocumentEvent;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
-import java.io.File;
import java.util.List;
/**
@@ -66,7 +63,7 @@ public class NewDirectoryProjectDialog extends DialogWrapper {
myLocationLabel.setLabelFor(myLocationField.getChildComponent());
- new LocationNameFieldsBinding(project, myLocationField, myProjectNameTextField, getBaseDir(), "Select Location for Project Directory");
+ new LocationNameFieldsBinding(project, myLocationField, myProjectNameTextField, ProjectUtil.getBaseDir(), "Select Location for Project Directory");
final DirectoryProjectGenerator[] generators = getGenerators();
if (generators.length == 0) {
@@ -217,17 +214,6 @@ public class NewDirectoryProjectDialog extends DialogWrapper {
});
}
- public static String getBaseDir() {
- final String lastProjectLocation = GeneralSettings.getInstance().getLastProjectLocation();
- if (lastProjectLocation != null) {
- return lastProjectLocation.replace('/', File.separatorChar);
- }
- final String userHome = SystemProperties.getUserHome();
- //noinspection HardCodedStringLiteral
- return userHome.replace('/', File.separatorChar) + File.separator + ApplicationNamesInfo.getInstance().getLowercaseProductName() +
- "Projects";
- }
-
protected JComponent createCenterPanel() {
return myRootPane;
}
diff --git a/platform/platform-impl/src/com/intellij/ui/popup/PopupFactoryImpl.java b/platform/platform-impl/src/com/intellij/ui/popup/PopupFactoryImpl.java
index 152541c2e95c..2ecb1572519d 100644
--- a/platform/platform-impl/src/com/intellij/ui/popup/PopupFactoryImpl.java
+++ b/platform/platform-impl/src/com/intellij/ui/popup/PopupFactoryImpl.java
@@ -199,9 +199,16 @@ public class PopupFactoryImpl extends JBPopupFactory {
private final Runnable myDisposeCallback;
private final Component myComponent;
- public ActionGroupPopup(final String title, @NotNull ActionGroup actionGroup, @NotNull DataContext dataContext,
- boolean showNumbers, boolean useAlphaAsNumbers, boolean showDisabledActions, boolean honorActionMnemonics,
- final Runnable disposeCallback, final int maxRowCount, final Condition preselectActionCondition,
+ public ActionGroupPopup(final String title,
+ @NotNull ActionGroup actionGroup,
+ @NotNull DataContext dataContext,
+ boolean showNumbers,
+ boolean useAlphaAsNumbers,
+ boolean showDisabledActions,
+ boolean honorActionMnemonics,
+ final Runnable disposeCallback,
+ final int maxRowCount,
+ final Condition preselectActionCondition,
@Nullable final String actionPlace) {
super(createStep(title, actionGroup, dataContext, showNumbers, useAlphaAsNumbers, showDisabledActions, honorActionMnemonics,
preselectActionCondition, actionPlace),
@@ -226,10 +233,15 @@ public class PopupFactoryImpl extends JBPopupFactory {
});
}
- private static ListPopupStep createStep(String title, @NotNull ActionGroup actionGroup, @NotNull DataContext dataContext,
- boolean showNumbers, boolean useAlphaAsNumbers, boolean showDisabledActions,
+ private static ListPopupStep createStep(String title,
+ @NotNull ActionGroup actionGroup,
+ @NotNull DataContext dataContext,
+ boolean showNumbers,
+ boolean useAlphaAsNumbers,
+ boolean showDisabledActions,
boolean honorActionMnemonics,
- Condition preselectActionCondition, @Nullable String actionPlace) {
+ Condition preselectActionCondition,
+ @Nullable String actionPlace) {
final Component component = PlatformDataKeys.CONTEXT_COMPONENT.getData(dataContext);
final ActionStepBuilder builder =
@@ -347,8 +359,9 @@ public class PopupFactoryImpl extends JBPopupFactory {
}, autoSelectionEnabled, showDisabledActions);
}
+ @NotNull
private static List makeActionItemsFromActionGroup(@NotNull ActionGroup actionGroup,
- DataContext dataContext,
+ @NotNull DataContext dataContext,
boolean showNumbers,
boolean useAlphaAsNumbers,
boolean showDisabledActions,
@@ -359,6 +372,7 @@ public class PopupFactoryImpl extends JBPopupFactory {
return builder.getItems();
}
+ @NotNull
private static ListPopupStep createActionsStep(@NotNull ActionGroup actionGroup, @NotNull DataContext dataContext,
boolean showNumbers, boolean useAlphaAsNumbers, boolean showDisabledActions,
String title, Component component, boolean honorActionMnemonics,
@@ -815,6 +829,7 @@ public class PopupFactoryImpl extends JBPopupFactory {
myActionPlace = actionPlace;
}
+ @NotNull
public List getItems() {
return myListModel;
}
@@ -831,8 +846,7 @@ public class PopupFactoryImpl extends JBPopupFactory {
}
private void calcMaxIconSize(final ActionGroup actionGroup) {
- AnAction[] actions = actionGroup.getChildren(new AnActionEvent(null, myDataContext, myActionPlace,
- getPresentation(actionGroup), ActionManager.getInstance(), 0));
+ AnAction[] actions = actionGroup.getChildren(createActionEvent(actionGroup));
for (AnAction action : actions) {
if (action == null) continue;
if (action instanceof ActionGroup) {
@@ -857,9 +871,13 @@ public class PopupFactoryImpl extends JBPopupFactory {
}
}
+ @NotNull
+ private AnActionEvent createActionEvent(@NotNull AnAction actionGroup) {
+ return new AnActionEvent(null, myDataContext, myActionPlace, getPresentation(actionGroup), ActionManager.getInstance(), 0);
+ }
+
private void appendActionsFromGroup(@NotNull ActionGroup actionGroup) {
- AnAction[] actions = actionGroup.getChildren(new AnActionEvent(null, myDataContext, myActionPlace,
- getPresentation(actionGroup), ActionManager.getInstance(), 0));
+ AnAction[] actions = actionGroup.getChildren(createActionEvent(actionGroup));
for (AnAction action : actions) {
if (action == null) {
LOG.error("null action in group " + actionGroup);
@@ -888,7 +906,7 @@ public class PopupFactoryImpl extends JBPopupFactory {
private void appendAction(@NotNull AnAction action) {
Presentation presentation = getPresentation(action);
- AnActionEvent event = new AnActionEvent(null, myDataContext, myActionPlace, presentation, ActionManager.getInstance(), 0);
+ AnActionEvent event = createActionEvent(action);
ActionUtil.performDumbAwareUpdate(action, event, true);
if ((myShowDisabled || presentation.isEnabled()) && presentation.isVisible()) {
diff --git a/platform/platform-impl/src/com/intellij/ui/popup/list/GroupedItemsListRenderer.java b/platform/platform-impl/src/com/intellij/ui/popup/list/GroupedItemsListRenderer.java
index 5863a5481a92..30c609029630 100644
--- a/platform/platform-impl/src/com/intellij/ui/popup/list/GroupedItemsListRenderer.java
+++ b/platform/platform-impl/src/com/intellij/ui/popup/list/GroupedItemsListRenderer.java
@@ -25,8 +25,6 @@ import javax.swing.*;
import java.awt.*;
public class GroupedItemsListRenderer extends GroupedElementsRenderer.List implements ListCellRenderer {
-
-
protected ListItemDescriptor myDescriptor;
protected JLabel myNextStepLabel;
@@ -40,20 +38,22 @@ public class GroupedItemsListRenderer extends GroupedElementsRenderer.List imple
myDescriptor = descriptor;
}
+ @Override
public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
String caption = myDescriptor.getCaptionAboveOf(value);
boolean hasSeparator = myDescriptor.hasSeparatorAboveOf(value);
if (index == 0 && StringUtil.isEmptyOrSpaces(caption)) hasSeparator = false;
+ Icon icon = myDescriptor.getIconFor(value);
final JComponent result = configureComponent(myDescriptor.getTextFor(value), myDescriptor.getTooltipFor(value),
- myDescriptor.getIconFor(value), myDescriptor.getIconFor(value), isSelected, hasSeparator,
+ icon, icon, isSelected, hasSeparator,
caption, -1);
-
customizeComponent(list, value, isSelected);
return result;
}
+ @Override
protected JComponent createItemComponent() {
myTextLabel = new ErrorLabel();
myTextLabel.setOpaque(true);
diff --git a/platform/platform-impl/src/com/intellij/ui/popup/list/PopupListElementRenderer.java b/platform/platform-impl/src/com/intellij/ui/popup/list/PopupListElementRenderer.java
index f3bb77260a10..5d657487f6a5 100644
--- a/platform/platform-impl/src/com/intellij/ui/popup/list/PopupListElementRenderer.java
+++ b/platform/platform-impl/src/com/intellij/ui/popup/list/PopupListElementRenderer.java
@@ -28,22 +28,27 @@ public class PopupListElementRenderer extends GroupedItemsListRenderer {
public PopupListElementRenderer(final ListPopupImpl aPopup) {
super(new ListItemDescriptor() {
+ @Override
public String getTextFor(Object value) {
return aPopup.getListStep().getTextFor(value);
}
+ @Override
public String getTooltipFor(Object value) {
return null;
}
+ @Override
public Icon getIconFor(Object value) {
return aPopup.getListStep().getIconFor(value);
}
+ @Override
public boolean hasSeparatorAboveOf(Object value) {
return aPopup.getListModel().isSeparatorAboveOf(value);
}
+ @Override
public String getCaptionAboveOf(Object value) {
return aPopup.getListModel().getCaptionAboveOf(value);
}
@@ -51,6 +56,7 @@ public class PopupListElementRenderer extends GroupedItemsListRenderer {
myPopup = aPopup;
}
+ @Override
protected void customizeComponent(JList list, Object value, boolean isSelected) {
ListPopupStep