mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Merge remote branch 'origin/master'
This commit is contained in:
+1
-3
@@ -504,9 +504,7 @@
|
||||
<inspection_tool class="ShiftOutOfRangeJS" enabled="false" level="WARNING" enabled_by_default="false" />
|
||||
<inspection_tool class="SillyAssignmentJS" enabled="false" level="WARNING" enabled_by_default="false" />
|
||||
<inspection_tool class="SimplifiableIfStatement" enabled="false" level="WARNING" enabled_by_default="false" />
|
||||
<inspection_tool class="Since15" enabled="true" level="ERROR" enabled_by_default="true">
|
||||
<scope name="Tests" level="ERROR" enabled="false" />
|
||||
</inspection_tool>
|
||||
<inspection_tool class="Since15" enabled="true" level="ERROR" enabled_by_default="true" />
|
||||
<inspection_tool class="SingletonInjectsScoped" enabled="false" level="WARNING" enabled_by_default="false" />
|
||||
<inspection_tool class="SocketResource" enabled="true" level="WARNING" enabled_by_default="true">
|
||||
<option name="insideTryAllowed" value="false" />
|
||||
|
||||
+1
-3
@@ -667,9 +667,7 @@
|
||||
<inspection_tool class="SillyAssignmentJS" enabled="false" level="WARNING" enabled_by_default="false" />
|
||||
<inspection_tool class="SimplifiableConditionalExpression" enabled="false" level="WARNING" enabled_by_default="false" />
|
||||
<inspection_tool class="SimplifiableIfStatement" enabled="false" level="WARNING" enabled_by_default="false" />
|
||||
<inspection_tool class="Since15" enabled="true" level="ERROR" enabled_by_default="true">
|
||||
<scope name="Tests" level="ERROR" enabled="false" />
|
||||
</inspection_tool>
|
||||
<inspection_tool class="Since15" enabled="true" level="ERROR" enabled_by_default="true" />
|
||||
<inspection_tool class="SingletonInjectsScoped" enabled="false" level="WARNING" enabled_by_default="false" />
|
||||
<inspection_tool class="SocketResource" enabled="true" level="WARNING" enabled_by_default="true">
|
||||
<option name="insideTryAllowed" value="false" />
|
||||
|
||||
+4
-2
@@ -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<String> processors = config.getProcessors();
|
||||
if (!processors.isEmpty()) {
|
||||
additionalOptions.add("-processor");
|
||||
additionalOptions.add(processorName);
|
||||
additionalOptions.add(StringUtil.join(processors, ","));
|
||||
}
|
||||
for (Map.Entry<String, String> entry : config.getProcessorOptions().entrySet()) {
|
||||
additionalOptions.add("-A" + entry.getKey() + "=" +entry.getValue());
|
||||
|
||||
@@ -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);
|
||||
|
||||
+4
-1
@@ -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<Pair<PsiMethod, JavaArrangementMethodDependencyInfo>> toProcess
|
||||
= new Stack<Pair<PsiMethod, JavaArrangementMethodDependencyInfo>>();
|
||||
toProcess.push(Pair.create(method, result));
|
||||
Set<PsiMethod> usedMethods = ContainerUtilRt.newHashSet();
|
||||
while (!toProcess.isEmpty()) {
|
||||
Pair<PsiMethod, JavaArrangementMethodDependencyInfo> pair = toProcess.pop();
|
||||
Set<PsiMethod> 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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
+4
-1
@@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -92,7 +92,7 @@ public class IntroduceFieldPopupPanel extends IntroduceFieldCentralPanel {
|
||||
|
||||
@Override
|
||||
public boolean isDeclareFinal() {
|
||||
return allowFinal();
|
||||
return ourLastCbFinalState && allowFinal();
|
||||
}
|
||||
|
||||
private void selectInCurrentMethod() {
|
||||
|
||||
+1
-1
@@ -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) ||
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
@@ -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());
|
||||
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
class TcpConnection extends ClientConnection {
|
||||
ConnectionEventDelegate<? extends ClientConnection> eventDelegate;
|
||||
{
|
||||
eventDelegate.<ClientConnection> onDisconnect<error descr="'onDisconnect(capture<? extends ClientConnection>)' in 'ConnectionEventDelegate' cannot be applied to '(TcpConnection)'">(this)</error>;
|
||||
}
|
||||
}
|
||||
|
||||
class ClientConnection {}
|
||||
interface ConnectionEventDelegate<T extends ClientConnection> {
|
||||
void onDisconnect(T t);
|
||||
}
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
import java.util.List;
|
||||
|
||||
interface ExampleInterface {
|
||||
public List exampleMethod();
|
||||
}
|
||||
|
||||
class ExampleSuperClass {
|
||||
public List<String> exampleMethod() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public class ExampleSubClass extends ExampleSuperClass implements ExampleInterface {
|
||||
}
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
class NodeProperty<A, B> {}
|
||||
|
||||
class NodeType {}
|
||||
class NumberExpression extends NodeType {}
|
||||
class Node<NodeTypeT extends NodeType> {
|
||||
public <ValueT> ValueT get(NodeProperty<? super NodeTypeT, ValueT> prop) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
class Main {
|
||||
public static void main(NodeProperty<NumberExpression, Integer> nval, Node<? extends NodeType> expr) {
|
||||
int val = expr.get<error descr="'get(NodeProperty<? super capture<? extends NodeType>,java.lang.Integer>)' in 'Node' cannot be applied to '(NodeProperty<NumberExpression,java.lang.Integer>)'">(nval)</error>;
|
||||
}
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
class A {
|
||||
int f() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
void m() {
|
||||
f<caret>();
|
||||
f();
|
||||
}
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
class A {
|
||||
int f() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
void m(int f) {
|
||||
f();
|
||||
}
|
||||
}
|
||||
@@ -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()));
|
||||
|
||||
+1
@@ -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); }
|
||||
}
|
||||
|
||||
@@ -128,6 +128,6 @@ public class LossyEncodingTest extends LightDaemonAnalyzerTestCase {
|
||||
doHighlighting();
|
||||
List<HighlightInfo> 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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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>");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -69,6 +69,14 @@ public class InplaceIntroduceParameterTest extends AbstractJavaInplaceIntroduceT
|
||||
});
|
||||
}
|
||||
|
||||
public void testParamNameEqMethodName() throws Exception {
|
||||
doTest(new Pass<AbstractInplaceIntroducer>() {
|
||||
@Override
|
||||
public void pass(AbstractInplaceIntroducer inplaceIntroducePopup) {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getBasePath() {
|
||||
return BASE_PATH;
|
||||
|
||||
@@ -58,6 +58,7 @@
|
||||
</item>
|
||||
<item name='java.lang.String byte[] getBytes(java.lang.String) 0'>
|
||||
<annotation name='org.jetbrains.annotations.NonNls'/>
|
||||
<annotation name='org.jetbrains.annotations.NotNull'/>
|
||||
</item>
|
||||
<item name='java.lang.RuntimeException RuntimeException(java.lang.String) 0'>
|
||||
<annotation name='org.jetbrains.annotations.NonNls'/>
|
||||
@@ -98,4 +99,7 @@
|
||||
<item name='java.lang.Class java.lang.reflect.Field getField(java.lang.String) 0'>
|
||||
<annotation name='org.jetbrains.annotations.NonNls'/>
|
||||
</item>
|
||||
<item name='java.lang.String byte[] getBytes(java.nio.charset.Charset) 0'>
|
||||
<annotation name='org.jetbrains.annotations.NotNull'/>
|
||||
</item>
|
||||
</root>
|
||||
|
||||
+1
@@ -0,0 +1 @@
|
||||
org.jetbrains.jps.incremental.java.AnnotationsExcludedJavaSourceRootProvider
|
||||
@@ -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<JpsJavaClasspathKind, Map<ModuleChunk, List<String>>> myCachedClasspath = new HashMap<JpsJavaClasspathKind, Map<ModuleChunk, List<String>>>();
|
||||
|
||||
public ProjectPaths(@NotNull JpsProject project) {
|
||||
myProject = project;
|
||||
private ProjectPaths() {
|
||||
}
|
||||
|
||||
public Collection<File> getCompilationClasspathFiles(ModuleChunk chunk,
|
||||
public static Collection<File> getCompilationClasspathFiles(ModuleChunk chunk,
|
||||
boolean includeTests,
|
||||
final boolean excludeMainModuleOutput,
|
||||
final boolean exportedOnly) {
|
||||
return getClasspathFiles(chunk, JpsJavaClasspathKind.compile(includeTests), excludeMainModuleOutput, ClasspathPart.WHOLE, exportedOnly);
|
||||
}
|
||||
|
||||
public Collection<File> getPlatformCompilationClasspath(ModuleChunk chunk, boolean excludeMainModuleOutput) {
|
||||
public static Collection<File> getPlatformCompilationClasspath(ModuleChunk chunk, boolean excludeMainModuleOutput) {
|
||||
return getClasspathFiles(chunk, JpsJavaClasspathKind.compile(chunk.containsTests()), excludeMainModuleOutput, ClasspathPart.BEFORE_JDK, true);
|
||||
}
|
||||
|
||||
public Collection<File> getCompilationClasspath(ModuleChunk chunk, boolean excludeMainModuleOutput) {
|
||||
public static Collection<File> getCompilationClasspath(ModuleChunk chunk, boolean excludeMainModuleOutput) {
|
||||
return getClasspathFiles(chunk, JpsJavaClasspathKind.compile(chunk.containsTests()), excludeMainModuleOutput, ClasspathPart.AFTER_JDK, true);
|
||||
}
|
||||
|
||||
private Collection<File> getClasspathFiles(ModuleChunk chunk,
|
||||
private static Collection<File> 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<String> roots = module.getContentRootsList().getUrls();
|
||||
|
||||
+1
@@ -20,6 +20,7 @@ import org.jetbrains.jps.model.module.JpsModule;
|
||||
import org.jetbrains.jps.model.module.JpsModuleSourceRoot;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author nik
|
||||
*/
|
||||
public abstract class ExcludedJavaSourceRootProvider {
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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<ModuleBuildTarget> myNonIncrementalModules = new HashSet<ModuleBuildTarget>();
|
||||
|
||||
private final ProjectPaths myProjectPaths;
|
||||
private volatile long myCompilationStartStamp;
|
||||
private final ProjectDescriptor myProjectDescriptor;
|
||||
private final Map<String, String> myBuilderParams;
|
||||
private final CanceledStatus myCancelStatus;
|
||||
private volatile float myDone = -1.0f;
|
||||
private EventDispatcher<BuildListener> myListeners = EventDispatcher.create(BuildListener.class);
|
||||
private Map<JpsModule, ProcessorConfigProfile> 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<JpsModule, ProcessorConfigProfile> map = myAnnotationProcessingProfileMap;
|
||||
if (map == null) {
|
||||
map = new HashMap<JpsModule, ProcessorConfigProfile>();
|
||||
final Map<String, JpsModule> namesMap = new HashMap<String, JpsModule>();
|
||||
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()) {
|
||||
|
||||
@@ -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<JavaSourceRoot
|
||||
if (outputDir != null) {
|
||||
result.add(outputDir);
|
||||
}
|
||||
final ProcessorConfigProfile profile = context.getAnnotationProcessingProfile(getModule());
|
||||
final JpsModule module = getModule();
|
||||
final JpsJavaCompilerConfiguration configuration = JpsJavaExtensionService.getInstance().getOrCreateCompilerConfiguration(module.getProject());
|
||||
final ProcessorConfigProfile profile = configuration.getAnnotationProcessingProfile(module);
|
||||
if (profile.isEnabled()) {
|
||||
final File annotationOut = context.getProjectPaths().getAnnotationProcessorGeneratedSourcesOutputDir(getModule(), isTests(), profile);
|
||||
final File annotationOut = ProjectPaths.getAnnotationProcessorGeneratedSourcesOutputDir(module, isTests(), profile);
|
||||
if (annotationOut != null) {
|
||||
result.add(annotationOut);
|
||||
}
|
||||
|
||||
@@ -20,7 +20,6 @@ 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.BuildRootIndex;
|
||||
import org.jetbrains.jps.builders.BuildTarget;
|
||||
import org.jetbrains.jps.builders.BuildTargetRegistry;
|
||||
@@ -37,7 +36,6 @@ import org.jetbrains.jps.model.java.JavaSourceRootProperties;
|
||||
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.JpsTypedModuleSourceRoot;
|
||||
import org.jetbrains.jps.service.JpsServiceManager;
|
||||
@@ -113,34 +111,9 @@ public final class ResourcesTarget extends JVMModuleBuildTarget<ResourceRootDesc
|
||||
addedRoots.add(rootFile);
|
||||
}
|
||||
|
||||
final ProcessorConfigProfile profile = findAnnotationProcessingProfile(model);
|
||||
if (profile != null) {
|
||||
final File annotationOut = new ProjectPaths(model.getProject()).getAnnotationProcessorGeneratedSourcesOutputDir(getModule(), isTests(), profile);
|
||||
if (annotationOut != null && !addedRoots.contains(annotationOut) && !FileUtil.filesEqual(annotationOut, getOutputDir())) {
|
||||
roots.add(new ResourceRootDescriptor(annotationOut, this, true, "", computeRootExcludes(annotationOut, index)));
|
||||
}
|
||||
}
|
||||
|
||||
return roots;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private ProcessorConfigProfile findAnnotationProcessingProfile(JpsModel model) {
|
||||
final Collection<ProcessorConfigProfile> 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() {
|
||||
|
||||
+2
-4
@@ -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<File> platformCp = paths.getPlatformCompilationClasspath(chunk, false);
|
||||
|
||||
final Collection<File> platformCp = ProjectPaths.getPlatformCompilationClasspath(chunk, false);
|
||||
final Collection<File> classpath = new ArrayList<File>();
|
||||
classpath.addAll(paths.getCompilationClasspath(chunk, false));
|
||||
classpath.addAll(ProjectPaths.getCompilationClasspath(chunk, false));
|
||||
classpath.addAll(ProjectPaths.getSourceRootsWithDependents(chunk).keySet());
|
||||
|
||||
finder = createInstrumentationClassFinder(platformCp, classpath, outputConsumer);
|
||||
|
||||
+2
-1
@@ -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<File> classpath = context.getProjectPaths().getCompilationClasspath(chunk, false);
|
||||
final Collection<File> classpath = ProjectPaths.getCompilationClasspath(chunk, false);
|
||||
final StringBuilder buf = new StringBuilder();
|
||||
for (File file : classpath) {
|
||||
if (buf.length() > 0) {
|
||||
|
||||
+49
@@ -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());
|
||||
}
|
||||
}
|
||||
@@ -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<Integer> JAVA_COMPILER_VERSION_KEY = Key.create("_java_compiler_version_");
|
||||
private static final Key<Boolean> IS_ENABLED = Key.create("_java_compiler_enabled_");
|
||||
private static final Key<AtomicReference<String>> COMPILER_VERSION_INFO = Key.create("_java_compiler_version_info_");
|
||||
|
||||
private static final Set<String> FILTERED_OPTIONS = new HashSet<String>(Arrays.<String>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<String>(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<File> classpath = paths.getCompilationClasspath(chunk, false/*context.isProjectRebuild()*/);
|
||||
final Collection<File> platformCp = paths.getPlatformCompilationClasspath(chunk, false/*context.isProjectRebuild()*/);
|
||||
final Collection<File> classpath = ProjectPaths.getCompilationClasspath(chunk, false/*context.isProjectRebuild()*/);
|
||||
final Collection<File> 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<String> 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<File> srcPath = new HashSet<File>();
|
||||
@@ -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<JpsModule> 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<String, LanguageLevel> 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<File, Set<File>> outs = buildOutputDirectoriesMap(context, chunk);
|
||||
final List<String> 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<String> processors = profile.getProcessors();
|
||||
if (!processors.isEmpty()) {
|
||||
options.add("-processor");
|
||||
options.add(procFQName);
|
||||
options.add(StringUtil.join(processors, ","));
|
||||
}
|
||||
|
||||
for (Map.Entry<String, String> 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) {
|
||||
|
||||
@@ -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<String> expected) {
|
||||
ModuleChunk chunk = createChunk(moduleName)
|
||||
final List<String> classpath = getPathsList(new ProjectPaths(myProject).getCompilationClasspathFiles(chunk, includeTests, true, true))
|
||||
final List<String> classpath = getPathsList(new ProjectPaths().getCompilationClasspathFiles(chunk, includeTests, true, true))
|
||||
assertClasspath(expected, toSystemIndependentPaths(classpath))
|
||||
}
|
||||
|
||||
|
||||
+14
-2
@@ -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<ProcessorConfigProfile> getAnnotationProcessingConfigurations();
|
||||
Collection<ProcessorConfigProfile> getAnnotationProcessingProfiles();
|
||||
|
||||
/**
|
||||
* @param module
|
||||
* @return annotation profile with which the given module is associated
|
||||
*/
|
||||
@NotNull
|
||||
ProcessorConfigProfile getAnnotationProcessingProfile(JpsModule module);
|
||||
|
||||
void addResourcePattern(String pattern);
|
||||
List<String> getResourcePatterns();
|
||||
|
||||
+30
-2
@@ -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<Jp
|
||||
private Map<String, String> myModulesByteCodeTargetLevels = new HashMap<String, String>();
|
||||
private Map<String, JpsJavaCompilerOptions> myCompilerOptions = new HashMap<String, JpsJavaCompilerOptions>();
|
||||
private String myJavaCompilerId = "Javac";
|
||||
private Map<JpsModule, ProcessorConfigProfile> myAnnotationProcessingProfileMap;
|
||||
|
||||
public JpsJavaCompilerConfigurationImpl() {
|
||||
}
|
||||
@@ -84,13 +86,13 @@ public class JpsJavaCompilerConfigurationImpl extends JpsCompositeElementBase<Jp
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public ProcessorConfigProfile getDefaultAnnotationProcessingConfiguration() {
|
||||
public ProcessorConfigProfile getDefaultAnnotationProcessingProfile() {
|
||||
return myDefaultAnnotationProcessingProfile;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Collection<ProcessorConfigProfile> getAnnotationProcessingConfigurations() {
|
||||
public Collection<ProcessorConfigProfile> getAnnotationProcessingProfiles() {
|
||||
return myAnnotationProcessingProfiles;
|
||||
}
|
||||
|
||||
@@ -163,4 +165,30 @@ public class JpsJavaCompilerConfigurationImpl extends JpsCompositeElementBase<Jp
|
||||
myAnnotationProcessingProfiles.add(profile);
|
||||
return profile;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public ProcessorConfigProfile getAnnotationProcessingProfile(JpsModule module) {
|
||||
Map<JpsModule, ProcessorConfigProfile> map = myAnnotationProcessingProfileMap;
|
||||
if (map == null) {
|
||||
map = new HashMap<JpsModule, ProcessorConfigProfile>();
|
||||
final Map<String, JpsModule> namesMap = new HashMap<String, JpsModule>();
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -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);
|
||||
|
||||
+1
-1
@@ -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());
|
||||
|
||||
@@ -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, byte[]> CHARSET_TO_BOM = new THashMap<Charset, byte[]>(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 <code>Charset</code>s 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 {
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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<Charset, CharsetToolkit.GuessedEncoding, byte[]> guessFromContent(VirtualFile virtualFile, byte[] content, int length) {
|
||||
public static Trinity<Charset, CharsetToolkit.GuessedEncoding, byte[]> 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<Charset, byte[]> 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<Charset, byte[]> charsetForWriting(@Nullable Project project,
|
||||
@NotNull VirtualFile virtualFile,
|
||||
@NotNull String text,
|
||||
@Nullable Charset existing) {
|
||||
Charset specified = extractCharsetFromFileContent(project, virtualFile, text);
|
||||
Pair<Charset, byte[]> 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<Charset, byte[]> 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<Boolean> CHARSET_WAS_DETECTED_FROM_BYTES = new Key<Boolean>("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<String> 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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<String> getContentRootUrls() {
|
||||
throw new UnsupportedOperationException()
|
||||
|
||||
@@ -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<PsiFile> psiRoots = file.getViewProvider().getAllFiles();
|
||||
Set<PsiElement> processed = new HashSet<PsiElement>(psiRoots.size() * 2, (float)0.5);
|
||||
Set<PsiElement> processed = new THashSet<PsiElement>(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;
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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<ProblemDescriptor> descriptors = new SmartList<ProblemDescriptor>();
|
||||
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<ProblemDescriptor> descriptors) {
|
||||
@NotNull String text,
|
||||
@NotNull VirtualFile virtualFile,
|
||||
@NotNull Charset charset,
|
||||
@NotNull List<ProblemDescriptor> 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<ProblemDescriptor> descriptors) {
|
||||
@NotNull String text,
|
||||
@NotNull Charset charset,
|
||||
@NotNull List<ProblemDescriptor> 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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -107,6 +107,7 @@ class BeforeRunStepsPanel extends JPanel {
|
||||
BeforeRunTaskProvider<BeforeRunTask> 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<BeforeRunTask> 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) {
|
||||
|
||||
@@ -206,7 +206,7 @@ public class FavoritesManager implements ProjectComponent, JDOMExternalizable {
|
||||
}
|
||||
|
||||
private void appendChildNodes(AbstractTreeNode node, TreeItem<Pair<AbstractUrl, String>> treeItem) {
|
||||
final Collection<AbstractTreeNode> children = node.getChildren();
|
||||
final Collection<? extends AbstractTreeNode> children = node.getChildren();
|
||||
for (AbstractTreeNode child : children) {
|
||||
final TreeItem<Pair<AbstractUrl, String>> childTreeItem = new TreeItem<Pair<AbstractUrl, String>>(createPairForNode(child));
|
||||
treeItem.addChild(childTreeItem);
|
||||
|
||||
+87
-5
@@ -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<Project> myProcessedProjects = new HashSet<Project>();
|
||||
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<VirtualFile> filesToSync = new ArrayList<VirtualFile>();
|
||||
for (VirtualFile file : files) {
|
||||
if (addFile(file)) {
|
||||
filesToSync.add(file);
|
||||
FileBasedIndex.getInstance().requestReindex(file);
|
||||
}
|
||||
}
|
||||
fireRootsChanged();
|
||||
fireRootsChanged(filesToSync, true);
|
||||
}
|
||||
|
||||
public void unmarkPlainText(VirtualFile... files) {
|
||||
List<VirtualFile> filesToSync = new ArrayList<VirtualFile>();
|
||||
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<VirtualFile> 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;
|
||||
}
|
||||
}
|
||||
|
||||
+46
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
+1
@@ -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
|
||||
|
||||
+33
-27
@@ -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<Charset> {
|
||||
public FileTreeTable(final Project project) {
|
||||
super(project, Charset.class, "Default Encoding");
|
||||
class EncodingFileTreeTable extends AbstractFileTreeTable<Charset> {
|
||||
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<Charset> {
|
||||
final Charset t = (Charset)value;
|
||||
final Object userObject = table.getModel().getValueAt(row, 0);
|
||||
final VirtualFile file = userObject instanceof VirtualFile ? (VirtualFile)userObject : null;
|
||||
final Pair<String,Boolean> 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<Charset, String> 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<Charset> {
|
||||
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("<Clear>", 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<Charset> {
|
||||
}
|
||||
};
|
||||
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<Charset> {
|
||||
|
||||
@Override
|
||||
protected boolean isValueEditableForFile(final VirtualFile virtualFile) {
|
||||
return ChooseFileEncodingAction.update(virtualFile).getSecond();
|
||||
return virtualFile == null || virtualFile.isDirectory() ||
|
||||
ChooseFileEncodingAction.checkCanReload(virtualFile).second == null;
|
||||
}
|
||||
}
|
||||
+54
-14
@@ -3,7 +3,7 @@
|
||||
<grid id="27dc6" binding="myPanel" layout-manager="GridLayoutManager" row-count="4" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
||||
<margin top="0" left="0" bottom="0" right="0"/>
|
||||
<constraints>
|
||||
<xy x="20" y="86" width="454" height="334"/>
|
||||
<xy x="20" y="86" width="466" height="334"/>
|
||||
</constraints>
|
||||
<properties/>
|
||||
<clientProperties>
|
||||
@@ -21,7 +21,7 @@
|
||||
</border>
|
||||
<children/>
|
||||
</scrollpane>
|
||||
<grid id="7187a" layout-manager="GridLayoutManager" row-count="1" column-count="3" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
||||
<grid id="7187a" layout-manager="GridLayoutManager" row-count="1" column-count="4" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
||||
<margin top="0" left="0" bottom="0" right="0"/>
|
||||
<constraints>
|
||||
<grid row="3" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
|
||||
@@ -34,7 +34,7 @@
|
||||
<children>
|
||||
<grid id="9ed8f" binding="myPropertiesFilesEncodingCombo" layout-manager="BorderLayout" hgap="0" vgap="0">
|
||||
<constraints>
|
||||
<grid row="0" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="7" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
|
||||
<grid row="0" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties/>
|
||||
<border type="none"/>
|
||||
@@ -56,9 +56,14 @@
|
||||
<text resource-bundle="messages/IdeBundle" key="checkbox.transparent.native.to.ascii.conversion"/>
|
||||
</properties>
|
||||
</component>
|
||||
<hspacer id="6003d">
|
||||
<constraints>
|
||||
<grid row="0" column="3" row-span="1" col-span="1" vsize-policy="1" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
</hspacer>
|
||||
</children>
|
||||
</grid>
|
||||
<grid id="f15cb" layout-manager="GridLayoutManager" row-count="1" column-count="3" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
||||
<grid id="f15cb" layout-manager="GridLayoutManager" row-count="2" column-count="3" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
||||
<margin top="0" left="0" bottom="0" right="0"/>
|
||||
<constraints>
|
||||
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
|
||||
@@ -84,23 +89,58 @@
|
||||
</grid>
|
||||
<component id="29b05" class="javax.swing.JCheckBox" binding="myAutodetectUTFEncodedFilesCheckBox" default-binding="true">
|
||||
<constraints>
|
||||
<grid row="0" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="0" fill="0" indent="0" use-parent-layout="false"/>
|
||||
<grid row="0" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<horizontalAlignment value="4"/>
|
||||
<horizontalAlignment value="2"/>
|
||||
<horizontalTextPosition value="11"/>
|
||||
<text resource-bundle="messages/IdeBundle" key="checkbox.autodetect.utf"/>
|
||||
</properties>
|
||||
</component>
|
||||
<component id="6435b" class="javax.swing.JLabel">
|
||||
<constraints>
|
||||
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<text value="Project Encoding:"/>
|
||||
</properties>
|
||||
</component>
|
||||
<grid id="fac05" binding="myProjectEncodingListCombo" layout-manager="BorderLayout" hgap="0" vgap="0">
|
||||
<constraints>
|
||||
<grid row="1" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties/>
|
||||
<border type="none"/>
|
||||
<children/>
|
||||
</grid>
|
||||
<hspacer id="f9e85">
|
||||
<constraints>
|
||||
<grid row="1" column="2" row-span="1" col-span="1" vsize-policy="1" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
</hspacer>
|
||||
</children>
|
||||
</grid>
|
||||
<grid id="63e2d" layout-manager="GridLayoutManager" row-count="1" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
||||
<margin top="0" left="0" bottom="0" right="0"/>
|
||||
<constraints>
|
||||
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties/>
|
||||
<clientProperties>
|
||||
<BorderFactoryClass class="java.lang.String" value="com.intellij.ui.IdeBorderFactory$PlainSmallWithIndent"/>
|
||||
</clientProperties>
|
||||
<border type="etched" title="Override Encoding for Files/Directories"/>
|
||||
<children>
|
||||
<component id="e9af6" class="javax.swing.JLabel" binding="myTitleLabel">
|
||||
<constraints>
|
||||
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<text resource-bundle="messages/IdeBundle" key="encodings.dialog.caption"/>
|
||||
</properties>
|
||||
</component>
|
||||
</children>
|
||||
</grid>
|
||||
<component id="e9af6" class="javax.swing.JLabel" binding="myTitleLabel">
|
||||
<constraints>
|
||||
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<text resource-bundle="messages/IdeBundle" key="encodings.dialog.caption"/>
|
||||
</properties>
|
||||
</component>
|
||||
</children>
|
||||
</grid>
|
||||
</form>
|
||||
|
||||
+25
-12
@@ -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<Charset> mySelectedCharsetForPropertiesFiles = new Ref<Charset>();
|
||||
private final Ref<Charset> mySelectedIdeCharset = new Ref<Charset>();
|
||||
private final Ref<Charset> mySelectedProjectCharset = new Ref<Charset>();
|
||||
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("<System Default>");
|
||||
return createGroup("<System Default>", 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<VirtualFile, Charset> 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
|
||||
|
||||
+1
-1
@@ -32,7 +32,7 @@ import org.jetbrains.annotations.Nullable;
|
||||
* @author peter
|
||||
*/
|
||||
public class TemplateDataLanguageConfigurable extends LanguagePerFileConfigurable<Language> {
|
||||
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"),
|
||||
|
||||
@@ -52,11 +52,11 @@ public abstract class AbstractFileTreeTable<T> extends TreeTable {
|
||||
private final MyModel<T> myModel;
|
||||
private final Project myProject;
|
||||
|
||||
public AbstractFileTreeTable(final Project project, final Class<T> valueClass, final String valueTitle) {
|
||||
this(project, valueClass, valueTitle, VirtualFileFilter.ALL);
|
||||
}
|
||||
|
||||
public AbstractFileTreeTable(final Project project, final Class<T> valueClass, final String valueTitle, @NotNull VirtualFileFilter filter) {
|
||||
public AbstractFileTreeTable(@NotNull Project project,
|
||||
@NotNull Class<T> valueClass,
|
||||
@NotNull String valueTitle,
|
||||
@NotNull VirtualFileFilter filter,
|
||||
boolean showProjectNode) {
|
||||
super(new MyModel<T>(project, valueClass, valueTitle, filter));
|
||||
myProject = project;
|
||||
|
||||
@@ -83,7 +83,7 @@ public abstract class AbstractFileTreeTable<T> 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<T> extends TreeTable {
|
||||
return false;
|
||||
}
|
||||
|
||||
private String getProjectNodeText() {
|
||||
private static String getProjectNodeText() {
|
||||
return "Project";
|
||||
}
|
||||
|
||||
@@ -176,6 +176,7 @@ public abstract class AbstractFileTreeTable<T> extends TreeTable {
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Map<VirtualFile, T> getValues() {
|
||||
return myModel.getValues();
|
||||
}
|
||||
@@ -190,12 +191,13 @@ public abstract class AbstractFileTreeTable<T> extends TreeTable {
|
||||
return tableRenderer;
|
||||
}
|
||||
|
||||
public void reset(final Map<VirtualFile, T> mappings) {
|
||||
public void reset(@NotNull Map<VirtualFile, T> 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<T> extends TreeTable {
|
||||
private final String myValueTitle;
|
||||
private AbstractFileTreeTable<T> myTreeTable;
|
||||
|
||||
private MyModel(final Project project, final Class<T> valueClass, final String valueTitle, VirtualFileFilter filter) {
|
||||
private MyModel(@NotNull Project project, @NotNull Class<T> valueClass, @NotNull String valueTitle, @NotNull VirtualFileFilter filter) {
|
||||
super(new ProjectRootNode(project, filter));
|
||||
myValueClass = valueClass;
|
||||
myValueTitle = valueTitle;
|
||||
@@ -324,7 +326,7 @@ public abstract class AbstractFileTreeTable<T> extends TreeTable {
|
||||
fireTreeNodesChanged(this, new Object[]{getRoot()}, null, null);
|
||||
}
|
||||
|
||||
public void reset(final Map<VirtualFile, T> mappings) {
|
||||
public void reset(@NotNull Map<VirtualFile, T> mappings) {
|
||||
myCurrentMapping.clear();
|
||||
myCurrentMapping.putAll(mappings);
|
||||
((ProjectRootNode)getRoot()).clearCachedChildren();
|
||||
@@ -348,7 +350,7 @@ public abstract class AbstractFileTreeTable<T> extends TreeTable {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void appendChildrenTo(final Collection<ConvenientNode> children) {
|
||||
protected void appendChildrenTo(@NotNull final Collection<ConvenientNode> children) {
|
||||
Project project = getObject();
|
||||
VirtualFile[] roots = ProjectRootManager.getInstance(project).getContentRoots();
|
||||
|
||||
@@ -375,7 +377,7 @@ public abstract class AbstractFileTreeTable<T> extends TreeTable {
|
||||
return myObject;
|
||||
}
|
||||
|
||||
protected abstract void appendChildrenTo(final Collection<ConvenientNode> children);
|
||||
protected abstract void appendChildrenTo(@NotNull Collection<ConvenientNode> children);
|
||||
|
||||
@Override
|
||||
public int getChildCount() {
|
||||
@@ -450,7 +452,7 @@ public abstract class AbstractFileTreeTable<T> extends TreeTable {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void appendChildrenTo(final Collection<ConvenientNode> children) {
|
||||
protected void appendChildrenTo(@NotNull final Collection<ConvenientNode> children) {
|
||||
VirtualFile[] childrenf = getObject().getChildren();
|
||||
ProjectFileIndex fileIndex = ProjectRootManager.getInstance(myProject).getFileIndex();
|
||||
for (VirtualFile child : childrenf) {
|
||||
|
||||
@@ -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<T> implements SearchableConfig
|
||||
private JPanel myPanel;
|
||||
private JLabel myLabel;
|
||||
|
||||
protected LanguagePerFileConfigurable(final Project project, Class<T> valueClass, PerFileMappings<T> mappings, String caption, String treeTableTitle, String overrideQuestion, String overrideTitle) {
|
||||
protected LanguagePerFileConfigurable(@NotNull Project project, Class<T> valueClass, PerFileMappings<T> mappings, String caption, String treeTableTitle, String overrideQuestion, String overrideTitle) {
|
||||
myProject = project;
|
||||
myValueClass = valueClass;
|
||||
myMappings = mappings;
|
||||
@@ -131,9 +132,8 @@ public abstract class LanguagePerFileConfigurable<T> implements SearchableConfig
|
||||
}
|
||||
|
||||
private class MyTreeTable extends AbstractFileTreeTable<T> {
|
||||
|
||||
public MyTreeTable() {
|
||||
super(myProject, myValueClass, myTreeTableTitle);
|
||||
super(myProject, myValueClass, myTreeTableTitle, VirtualFileFilter.ALL, true);
|
||||
getValueColumn().setCellEditor(new DefaultCellEditor(new JComboBox()) {
|
||||
private VirtualFile myVirtualFile;
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -65,9 +65,10 @@ public class AnActionEvent implements PlaceProvider<String> {
|
||||
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,
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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<VirtualFile> files) {
|
||||
return ensureFilesWritable(VfsUtil.toVirtualFileArray(files));
|
||||
return ensureFilesWritable(VfsUtilCore.toVirtualFileArray(files));
|
||||
}
|
||||
|
||||
public static ReadonlyStatusHandler getInstance(Project project) {
|
||||
|
||||
+3
-1
@@ -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<VirtualFile, Charset> getAllMappings();
|
||||
|
||||
public abstract void setMapping(Map<VirtualFile, Charset> result);
|
||||
public abstract void setMapping(@NotNull Map<VirtualFile, Charset> result);
|
||||
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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";
|
||||
}
|
||||
}
|
||||
|
||||
+3
@@ -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);
|
||||
}
|
||||
|
||||
+62
-82
@@ -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<Runnable> myDisposeActions = new ArrayList<Runnable>();
|
||||
private final List<Runnable> myDisposeActions = new ArrayList<Runnable>();
|
||||
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.
|
||||
* <code>parent</code> cannot be <code>null</code> 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<DialogWrapper> 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>(dialogWrapper);
|
||||
myProject = project != null ? new WeakReference<Project>(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>(dialogWrapper);
|
||||
myProject = project != null ? new WeakReference<Project>(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<IdeFocusManager> focusManager = new Ref<IdeFocusManager>(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;
|
||||
}
|
||||
|
||||
|
||||
+9
-5
@@ -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<PluginDownloader> 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);
|
||||
}
|
||||
|
||||
+10
-7
@@ -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<VirtualFile> denied = ContainerUtil.filter(files, new Condition<VirtualFile>() {
|
||||
@@ -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()) {
|
||||
|
||||
-79
@@ -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<Charset> charsets = new ArrayList<Charset>(EncodingManager.getInstance().getFavorites());
|
||||
Collections.sort(charsets);
|
||||
Charset current = virtualFile.getCharset();
|
||||
charsets.remove(current);
|
||||
|
||||
List<AnAction> children = new ArrayList<AnAction>(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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+6
-19
@@ -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<String, Boolean> 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);
|
||||
}
|
||||
|
||||
+89
-97
@@ -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<String, Boolean> 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<Charset, String> 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<Charset> charsets,
|
||||
@Nullable final Condition<Charset> 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("<Clear>");
|
||||
}
|
||||
|
||||
private void fillCharsetActions(DefaultActionGroup group, final VirtualFile virtualFile, List<Charset> 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<String,Boolean> 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<Charset, String> 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<Charset, String> 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<Charset, String> 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<Charset> charsetFilter,
|
||||
@NotNull String pattern,
|
||||
Charset alreadySelected) {
|
||||
DefaultActionGroup group = new DefaultActionGroup();
|
||||
List<Charset> favorites = new ArrayList<Charset>(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;
|
||||
}
|
||||
|
||||
+124
@@ -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<Document, String> 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<Charset, byte[]> 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()));
|
||||
}
|
||||
}
|
||||
}
|
||||
+26
-2
@@ -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<Charset>() {
|
||||
@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();
|
||||
|
||||
+52
-16
@@ -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<Element> files = element.getChildren("file");
|
||||
final Map<VirtualFile, Charset> mapping = new HashMap<VirtualFile, Charset>();
|
||||
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<VirtualFile, Charset> getAllMappings() {
|
||||
return myMapping;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setMapping(final Map<VirtualFile, Charset> result) {
|
||||
Map<VirtualFile, Charset> map = new HashMap<VirtualFile, Charset>(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<VirtualFile, Charset> result) {
|
||||
Map<VirtualFile, Charset> map = new HashMap<VirtualFile, Charset>(result.size());
|
||||
ProjectFileIndex fileIndex = ProjectRootManager.getInstance(myProject).getFileIndex();
|
||||
for (Map.Entry<VirtualFile, Charset> entry : result.entrySet()) {
|
||||
VirtualFile virtualFile = entry.getKey();
|
||||
Charset charset = entry.getValue();
|
||||
if (virtualFile != null && !fileIndex.isInContent(virtualFile)) {
|
||||
continue;
|
||||
}
|
||||
Pair<Charset, String> 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<VirtualFile, Charset> entry : map.entrySet()) {
|
||||
Charset charset = entry.getValue();
|
||||
assert charset != null;
|
||||
VirtualFile virtualFile = entry.getKey();
|
||||
setAndSaveOrReload(virtualFile, charset);
|
||||
}
|
||||
if (!myProject.isDefault()) {
|
||||
|
||||
+18
-7
@@ -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<String, Boolean> 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;
|
||||
+151
@@ -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<Charset> {
|
||||
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<Document, String> 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<Document, String> 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<Document, String> 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;
|
||||
}
|
||||
}
|
||||
+59
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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<String,Boolean> 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<String, Boolean> 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<Charset,String> 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);
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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<AnAction> 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<AnAction> 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<AnAction> preselectActionCondition, @Nullable String actionPlace) {
|
||||
Condition<AnAction> 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<ActionItem> 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<ActionItem> 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()) {
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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<Object> step = myPopup.getListStep();
|
||||
boolean isSelectable = step.isSelectable(value);
|
||||
|
||||
@@ -232,6 +232,7 @@ public class WebServer {
|
||||
}
|
||||
|
||||
if (tryAnyPort) {
|
||||
LOG.info("We cannot bind to our default range, so, try to bind to any free port");
|
||||
try {
|
||||
Channel channel = bootstrap.bind(new InetSocketAddress(0));
|
||||
openChannels.add(channel);
|
||||
|
||||
@@ -1043,7 +1043,7 @@ finished.with.exit.code.text.message=Process finished with exit code {0}
|
||||
# Encodings
|
||||
file.encodings.configurable=File Encodings
|
||||
file.encodings.not.configured=Encodings are not configured
|
||||
encodings.dialog.caption=<html>To change encoding $productName uses for a file, directory, or an entire project, click an item and then select encoding from the Default Encoding list.<br>Notes\:<br>Built-in file encoding (e.g. JSP, HTML or XML) overrides encoding you specify here. If not specified, files and directories inherit encoding settings from parent.</html>
|
||||
encodings.dialog.caption=<html>To change encoding $productName uses for a file or directory, click an item and then select encoding from the Default Encoding list.<br><br>Built-in file encoding (e.g. JSP, HTML or XML) overrides encoding you specify here.<br>If not specified, files and directories inherit encoding settings from the parent.</html>
|
||||
encoding.name.system.default=<System Default>
|
||||
quick.lists.presentable.name=Quick lists
|
||||
|
||||
|
||||
@@ -161,8 +161,7 @@
|
||||
<action id="Synchronize" class="com.intellij.ide.actions.SynchronizeAction" icon="AllIcons.Actions.Refresh"/>
|
||||
<action id="InvalidateCaches" class="com.intellij.ide.actions.InvalidateCachesAction"/>
|
||||
|
||||
<group id="ChangeFileEncodingGroup" popup="true" class="com.intellij.openapi.vfs.encoding.ChangeEncodingUpdateGroup">
|
||||
<action id="ChangeFileEncodingGroupAction" class="com.intellij.openapi.vfs.encoding.ChangeFileEncodingGroup" text=""/>
|
||||
<group id="ChangeFileEncodingGroup" popup="true" class="com.intellij.openapi.vfs.encoding.FileChangeEncodingGroup">
|
||||
</group>
|
||||
<action id="ToggleReadOnlyAttribute" class="com.intellij.ide.actions.ToggleReadOnlyAttributeAction"/>
|
||||
<separator/>
|
||||
|
||||
@@ -54,7 +54,7 @@ public class Splitter extends JPanel {
|
||||
private final float myMaxProp;
|
||||
|
||||
|
||||
protected float myProportion;
|
||||
protected float myProportion;// first size divided by total size
|
||||
|
||||
private final Divider myDivider;
|
||||
private JComponent mySecondComponent;
|
||||
@@ -177,7 +177,7 @@ public class Splitter extends JPanel {
|
||||
if (myFirstComponent != null && myFirstComponent.isVisible() && mySecondComponent != null && mySecondComponent.isVisible()) {
|
||||
final Dimension firstMinSize = myFirstComponent.getMinimumSize();
|
||||
final Dimension secondMinSize = mySecondComponent.getMinimumSize();
|
||||
return getOrientation()
|
||||
return isVertical()
|
||||
? new Dimension(Math.max(firstMinSize.width, secondMinSize.width), firstMinSize.height + dividerWidth + secondMinSize.height)
|
||||
: new Dimension(firstMinSize.width + dividerWidth + secondMinSize.width, Math.max(firstMinSize.height, secondMinSize.height));
|
||||
}
|
||||
@@ -199,7 +199,7 @@ public class Splitter extends JPanel {
|
||||
if (myFirstComponent != null && myFirstComponent.isVisible() && mySecondComponent != null && mySecondComponent.isVisible()) {
|
||||
final Dimension firstPrefSize = myFirstComponent.getPreferredSize();
|
||||
final Dimension secondPrefSize = mySecondComponent.getPreferredSize();
|
||||
return getOrientation()
|
||||
return isVertical()
|
||||
? new Dimension(Math.max(firstPrefSize.width, secondPrefSize.width),
|
||||
firstPrefSize.height + dividerWidth + secondPrefSize.height)
|
||||
: new Dimension(firstPrefSize.width + dividerWidth + secondPrefSize.width,
|
||||
@@ -225,11 +225,11 @@ public class Splitter extends JPanel {
|
||||
mySkipNextLayouting = false;
|
||||
return;
|
||||
}
|
||||
final double width = getWidth();
|
||||
final double height = getHeight();
|
||||
int width = getWidth();
|
||||
int height = getHeight();
|
||||
|
||||
final double componentSize = getOrientation() ? height : width;
|
||||
if (componentSize <= 0) return;
|
||||
int total = isVertical() ? height : width;
|
||||
if (total <= 0) return;
|
||||
|
||||
if (!isNull(myFirstComponent) && myFirstComponent.isVisible() && !isNull(mySecondComponent) && mySecondComponent.isVisible()) {
|
||||
// both first and second components are visible
|
||||
@@ -237,64 +237,52 @@ public class Splitter extends JPanel {
|
||||
Rectangle dividerRect = new Rectangle();
|
||||
Rectangle secondRect = new Rectangle();
|
||||
|
||||
double dividerWidth = getDividerWidth();
|
||||
double firstComponentSize;
|
||||
double secondComponentSize;
|
||||
int d = getDividerWidth();
|
||||
double size1;
|
||||
|
||||
if (componentSize <= dividerWidth) {
|
||||
firstComponentSize = 0;
|
||||
secondComponentSize = 0;
|
||||
dividerWidth = componentSize;
|
||||
if (total <= d) {
|
||||
size1 = 0;
|
||||
d = total;
|
||||
}
|
||||
else {
|
||||
firstComponentSize = myProportion * (float)(componentSize - dividerWidth);
|
||||
secondComponentSize = getOrientation() ? height - firstComponentSize - dividerWidth : width - firstComponentSize - dividerWidth;
|
||||
size1 = myProportion * total;
|
||||
double size2 = total - size1 - d;
|
||||
|
||||
if (isHonorMinimumSize()) {
|
||||
|
||||
final double firstMinSize =
|
||||
getOrientation() ? myFirstComponent.getMinimumSize().getHeight() : myFirstComponent.getMinimumSize().getWidth();
|
||||
final double secondMinSize =
|
||||
getOrientation() ? mySecondComponent.getMinimumSize().getHeight() : mySecondComponent.getMinimumSize().getWidth();
|
||||
double mSize1 = isVertical() ? myFirstComponent.getMinimumSize().getHeight() : myFirstComponent.getMinimumSize().getWidth();
|
||||
double mSize2 = isVertical() ? mySecondComponent.getMinimumSize().getHeight() : mySecondComponent.getMinimumSize().getWidth();
|
||||
|
||||
if (firstComponentSize + secondComponentSize < firstMinSize + secondMinSize) {
|
||||
double proportion = firstMinSize / (firstMinSize + secondMinSize);
|
||||
firstComponentSize = (int)(proportion * (float)(componentSize - dividerWidth));
|
||||
secondComponentSize = getOrientation() ? height - firstComponentSize - dividerWidth : width - firstComponentSize - dividerWidth;
|
||||
if (size1 + size2 < mSize1 + mSize2) {
|
||||
double proportion = mSize1 / (mSize1 + mSize2);
|
||||
size1 = proportion * total;
|
||||
}
|
||||
else {
|
||||
if (firstComponentSize < firstMinSize) {
|
||||
secondComponentSize -= firstMinSize - firstComponentSize;
|
||||
firstComponentSize = firstMinSize;
|
||||
if (size1 < mSize1) {
|
||||
size1 = mSize1;
|
||||
}
|
||||
else if (secondComponentSize < secondMinSize) {
|
||||
firstComponentSize -= secondMinSize - secondComponentSize;
|
||||
secondComponentSize = secondMinSize;
|
||||
else if (size2 < mSize2) {
|
||||
size2 = mSize2;
|
||||
size1 = total - size2 - d;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
myProportion = (float)(firstComponentSize / (firstComponentSize + secondComponentSize));
|
||||
myProportion = (float)(size1 / total);
|
||||
|
||||
firstComponentSize = Math.floor(firstComponentSize);
|
||||
secondComponentSize = Math.floor(secondComponentSize);
|
||||
int iSize1 = (int)Math.round(Math.floor(size1));
|
||||
int iSize2 = (int)Math.round(total - size1 - d);
|
||||
|
||||
if (getOrientation()) {
|
||||
// fix flooring
|
||||
secondComponentSize += (int)(height - firstComponentSize - secondComponentSize - dividerWidth);
|
||||
|
||||
firstRect.setBounds(0, 0, (int)width, (int)firstComponentSize);
|
||||
dividerRect.setBounds(0, (int)firstComponentSize, (int)width, (int)dividerWidth);
|
||||
secondRect.setBounds(0, (int)(firstComponentSize + dividerWidth), (int)width, (int)secondComponentSize);
|
||||
if (isVertical()) {
|
||||
firstRect.setBounds(0, 0, width, iSize1);
|
||||
dividerRect.setBounds(0, iSize1, width, d);
|
||||
secondRect.setBounds(0, iSize1 + d, width, iSize2);
|
||||
}
|
||||
else {
|
||||
// fix flooring
|
||||
secondComponentSize += (int)(width - firstComponentSize - secondComponentSize - dividerWidth);
|
||||
|
||||
firstRect.setBounds(0, 0, (int)firstComponentSize, (int)height);
|
||||
dividerRect.setBounds((int)firstComponentSize, 0, (int)dividerWidth, (int)height);
|
||||
secondRect.setBounds((int)(firstComponentSize + dividerWidth), 0, (int)secondComponentSize, (int)height);
|
||||
firstRect.setBounds(0, 0, iSize1, height);
|
||||
dividerRect.setBounds(iSize1, 0, d, height);
|
||||
secondRect.setBounds((iSize1 + d), 0, iSize2, height);
|
||||
}
|
||||
myDivider.setVisible(true);
|
||||
myFirstComponent.setBounds(firstRect);
|
||||
@@ -306,13 +294,13 @@ public class Splitter extends JPanel {
|
||||
else if (!isNull(myFirstComponent) && myFirstComponent.isVisible()) { // only first component is visible
|
||||
hideNull(mySecondComponent);
|
||||
myDivider.setVisible(false);
|
||||
myFirstComponent.setBounds(0, 0, (int)width, (int)height);
|
||||
myFirstComponent.setBounds(0, 0, width, height);
|
||||
myFirstComponent.revalidate();
|
||||
}
|
||||
else if (!isNull(mySecondComponent) && mySecondComponent.isVisible()) { // only second component is visible
|
||||
hideNull(myFirstComponent);
|
||||
myDivider.setVisible(false);
|
||||
mySecondComponent.setBounds(0, 0, (int)width, (int)height);
|
||||
mySecondComponent.setBounds(0, 0, width, height);
|
||||
mySecondComponent.revalidate();
|
||||
}
|
||||
else { // both components are null or invisible
|
||||
@@ -401,6 +389,13 @@ public class Splitter extends JPanel {
|
||||
return myVerticalSplit;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if |-|
|
||||
*/
|
||||
public boolean isVertical() {
|
||||
return myVerticalSplit;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param verticalSplit <code>true</code> means that splitter will have vertical split
|
||||
*/
|
||||
@@ -486,7 +481,7 @@ public class Splitter extends JPanel {
|
||||
private void setOrientation(boolean isVerticalSplit) {
|
||||
removeAll();
|
||||
|
||||
setCursor(getOrientation() ?
|
||||
setCursor(isVertical() ?
|
||||
Cursor.getPredefinedCursor(Cursor.N_RESIZE_CURSOR) :
|
||||
Cursor.getPredefinedCursor(Cursor.W_RESIZE_CURSOR));
|
||||
|
||||
@@ -570,7 +565,7 @@ public class Splitter extends JPanel {
|
||||
if (MouseEvent.MOUSE_DRAGGED == e.getID()) {
|
||||
myPoint = SwingUtilities.convertPoint(this, e.getPoint(), Splitter.this);
|
||||
float proportion;
|
||||
if (getOrientation()) {
|
||||
if (isVertical()) {
|
||||
if (getHeight() > 0) {
|
||||
proportion = Math.min(1.0f, Math.max(.0f, Math
|
||||
.min(Math.max(getMinProportion(myFirstComponent), (float)myPoint.y / (float)Splitter.this.getHeight()),
|
||||
@@ -593,7 +588,7 @@ public class Splitter extends JPanel {
|
||||
if (isHonorMinimumSize()) {
|
||||
if (component != null && myFirstComponent != null && myFirstComponent.isVisible() && mySecondComponent != null &&
|
||||
mySecondComponent.isVisible()) {
|
||||
if (getOrientation()) {
|
||||
if (isVertical()) {
|
||||
return (float)component.getMinimumSize().height / (float)(Splitter.this.getHeight() - getDividerWidth());
|
||||
}
|
||||
else {
|
||||
@@ -623,7 +618,7 @@ public class Splitter extends JPanel {
|
||||
setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
|
||||
}
|
||||
else {
|
||||
setCursor(getOrientation() ?
|
||||
setCursor(isVertical() ?
|
||||
Cursor.getPredefinedCursor(Cursor.N_RESIZE_CURSOR) :
|
||||
Cursor.getPredefinedCursor(Cursor.W_RESIZE_CURSOR));
|
||||
}
|
||||
|
||||
@@ -43,7 +43,7 @@ import static com.intellij.util.BitUtil.notSet;
|
||||
* @version 11.1
|
||||
*/
|
||||
public class FileSystemUtil {
|
||||
public static final String FORCE_USE_NIO2_KEY = "idea.io.use.nio2";
|
||||
private static final String FORCE_USE_NIO2_KEY = "idea.io.use.nio2";
|
||||
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.util.io.FileSystemUtil");
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ import java.awt.*;
|
||||
/**
|
||||
* @author Konstantin Bulenkov
|
||||
*/
|
||||
@SuppressWarnings("InspectionUsingJBColors")
|
||||
@SuppressWarnings("UseJBColor")
|
||||
public class JBColor extends Color {
|
||||
public JBColor(int rgb, int darkRGB) {
|
||||
super(isDark() ? darkRGB : rgb);
|
||||
|
||||
@@ -437,21 +437,21 @@ public class ArrayUtil extends ArrayUtilRt {
|
||||
return indexOf(src, obj);
|
||||
}
|
||||
|
||||
public static boolean startsWith(byte[] array, byte[] subArray) {
|
||||
if (array == subArray) {
|
||||
public static boolean startsWith(byte[] array, byte[] prefix) {
|
||||
if (array == prefix) {
|
||||
return true;
|
||||
}
|
||||
if (array == null || subArray == null) {
|
||||
if (array == null || prefix == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int length = subArray.length;
|
||||
int length = prefix.length;
|
||||
if (array.length < length) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (int i = 0; i < length; i++) {
|
||||
if (array[i] != subArray[i]) {
|
||||
if (array[i] != prefix[i]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -96,7 +96,7 @@ public class PagedFileStorage implements Forceable {
|
||||
}
|
||||
|
||||
private final byte[] myTypedIOBuffer;
|
||||
private boolean isDirty = false;
|
||||
private volatile boolean isDirty = false;
|
||||
private final File myFile;
|
||||
protected long mySize = -1;
|
||||
protected final int myPageSize;
|
||||
@@ -125,7 +125,6 @@ public class PagedFileStorage implements Forceable {
|
||||
|
||||
public void putInt(int addr, int value) {
|
||||
if (myValuesAreBufferAligned) {
|
||||
isDirty = true;
|
||||
int page = addr / myPageSize;
|
||||
int page_offset = addr % myPageSize;
|
||||
getBuffer(page).putInt(page_offset, value);
|
||||
@@ -148,7 +147,6 @@ public class PagedFileStorage implements Forceable {
|
||||
|
||||
public final void putShort(int addr, short value) {
|
||||
if (myValuesAreBufferAligned) {
|
||||
isDirty = true;
|
||||
int page = addr / myPageSize;
|
||||
int page_offset = addr % myPageSize;
|
||||
getBuffer(page).putShort(page_offset, value);
|
||||
@@ -179,7 +177,6 @@ public class PagedFileStorage implements Forceable {
|
||||
|
||||
public void putLong(int addr, long value) {
|
||||
if (myValuesAreBufferAligned) {
|
||||
isDirty = true;
|
||||
int page = addr / myPageSize;
|
||||
int page_offset = addr % myPageSize;
|
||||
getBuffer(page).putLong(page_offset, value);
|
||||
@@ -217,7 +214,6 @@ public class PagedFileStorage implements Forceable {
|
||||
}
|
||||
|
||||
public void put(int index, byte value) {
|
||||
isDirty = true;
|
||||
int page = index / myPageSize;
|
||||
int offset = index % myPageSize;
|
||||
|
||||
@@ -254,7 +250,6 @@ public class PagedFileStorage implements Forceable {
|
||||
}
|
||||
|
||||
public void put(int index, byte[] src, int offset, int length) {
|
||||
isDirty = true;
|
||||
int i = index;
|
||||
int o = offset;
|
||||
int l = length;
|
||||
@@ -364,19 +359,19 @@ public class PagedFileStorage implements Forceable {
|
||||
if (myLastPage == page) {
|
||||
ByteBuffer buf = myLastBuffer.getCachedBuffer();
|
||||
if (buf != null && myLastChangeCount == myStorageLockContext.myStorageLock.myMappingChangeCount) {
|
||||
if (modify) myLastBuffer.markDirty();
|
||||
if (modify) markDirty(myLastBuffer);
|
||||
return buf;
|
||||
}
|
||||
} else if (myLastPage2 == page) {
|
||||
ByteBuffer buf = myLastBuffer2.getCachedBuffer();
|
||||
if (buf != null && myLastChangeCount2 == myStorageLockContext.myStorageLock.myMappingChangeCount) {
|
||||
if (modify) myLastBuffer2.markDirty();
|
||||
if (modify) markDirty(myLastBuffer2);
|
||||
return buf;
|
||||
}
|
||||
} else if (myLastPage3 == page) {
|
||||
ByteBuffer buf = myLastBuffer3.getCachedBuffer();
|
||||
if (buf != null && myLastChangeCount3 == myStorageLockContext.myStorageLock.myMappingChangeCount) {
|
||||
if (modify) myLastBuffer3.markDirty();
|
||||
if (modify) markDirty(myLastBuffer3);
|
||||
return buf;
|
||||
}
|
||||
}
|
||||
@@ -388,7 +383,7 @@ public class PagedFileStorage implements Forceable {
|
||||
myStorageIndex = myStorageLockContext.myStorageLock.registerPagedFileStorage(this);
|
||||
}
|
||||
ByteBufferWrapper byteBufferWrapper = myStorageLockContext.myStorageLock.get(myStorageIndex | page);
|
||||
if (modify) byteBufferWrapper.markDirty();
|
||||
if (modify) markDirty(byteBufferWrapper);
|
||||
ByteBuffer buf = byteBufferWrapper.getBuffer();
|
||||
|
||||
if (myLastPage != page) {
|
||||
@@ -415,6 +410,11 @@ public class PagedFileStorage implements Forceable {
|
||||
}
|
||||
}
|
||||
|
||||
private void markDirty(ByteBufferWrapper buffer) {
|
||||
if (!isDirty) isDirty = true;
|
||||
buffer.markDirty();
|
||||
}
|
||||
|
||||
public void force() {
|
||||
long started = IOStatistics.DEBUG ? System.currentTimeMillis():0;
|
||||
if (isDirty) {
|
||||
|
||||
@@ -20,10 +20,7 @@ import junit.framework.TestCase;
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
|
||||
import com.intellij.util.concurrency.Semaphore;
|
||||
|
||||
public class SplitterTest extends TestCase{
|
||||
private static final int RATHER_LATER_INVOKES = 10;
|
||||
|
||||
public void testResizeVert() {
|
||||
resizeTest(new Splitter(true));
|
||||
@@ -43,44 +40,51 @@ public class SplitterTest extends TestCase{
|
||||
splitter.setHonorComponentsMinimumSize(true);
|
||||
|
||||
|
||||
// disabled since honoring min size is rather confusing, reasonable min size is hardcoded instead
|
||||
//splitter.setSize(new Dimension(500, 500));
|
||||
//splitter.doLayout();
|
||||
//checkBounds(splitter);
|
||||
//
|
||||
//splitter.setSize(new Dimension(300, 300));
|
||||
//splitter.doLayout();
|
||||
//checkBounds(splitter);
|
||||
//
|
||||
//splitter.setProportion(.1f);
|
||||
//splitter.doLayout();
|
||||
//checkBounds(splitter);
|
||||
//
|
||||
////assertTrue(Math.abs(splitter.getProportion() - jPanel1.getMinimumSize().height / (splitter.getSize().height - splitter.getDividerWidth())) < .00001);
|
||||
//
|
||||
//splitter.setProportion(.9f);
|
||||
//splitter.doLayout();
|
||||
//checkBounds(splitter);
|
||||
//
|
||||
//splitter.setSize(new Dimension(100, 100));
|
||||
//splitter.doLayout();
|
||||
//checkBounds(splitter);
|
||||
//
|
||||
//splitter.setProportion(.1f);
|
||||
//splitter.doLayout();
|
||||
//checkBounds(splitter);
|
||||
//
|
||||
//splitter.setSize(new Dimension(10, 10));
|
||||
//splitter.doLayout();
|
||||
//checkBounds(splitter);
|
||||
//
|
||||
//splitter.setSize(new Dimension(100, 100));
|
||||
//splitter.doLayout();
|
||||
//checkBounds(splitter);
|
||||
//
|
||||
//splitter.setSize(new Dimension(150, 150));
|
||||
//splitter.doLayout();
|
||||
//checkBounds(splitter);
|
||||
splitter.setSize(new Dimension(500, 500));
|
||||
splitter.doLayout();
|
||||
checkBounds(splitter);
|
||||
|
||||
splitter.setSize(new Dimension(300, 300));
|
||||
splitter.doLayout();
|
||||
checkBounds(splitter);
|
||||
|
||||
splitter.setProportion(.1f);
|
||||
splitter.doLayout();
|
||||
checkBounds(splitter);
|
||||
|
||||
splitter.setProportion(.9f);
|
||||
splitter.doLayout();
|
||||
checkBounds(splitter);
|
||||
|
||||
splitter.setSize(new Dimension(100, 100));
|
||||
splitter.doLayout();
|
||||
checkBounds(splitter);
|
||||
|
||||
splitter.setProportion(.1f);
|
||||
splitter.doLayout();
|
||||
checkBounds(splitter);
|
||||
|
||||
splitter.setSize(new Dimension(10, 10));
|
||||
splitter.doLayout();
|
||||
checkBounds(splitter);
|
||||
|
||||
splitter.setSize(new Dimension(100, 100));
|
||||
splitter.doLayout();
|
||||
checkBounds(splitter);
|
||||
|
||||
splitter.setSize(new Dimension(150, 150));
|
||||
splitter.doLayout();
|
||||
checkBounds(splitter);
|
||||
|
||||
splitter.setSize(splitter.isVertical() ? new Dimension(150, 1000) : new Dimension(1000, 150));
|
||||
for (float f = .01F; f < 1F; f+=.01F) {
|
||||
splitter.setProportion(f);
|
||||
splitter.doLayout();
|
||||
float proportion = splitter.getProportion();
|
||||
assertTrue (proportion>=.1 && proportion<=9);
|
||||
if (f>=.1 && f<=.89)
|
||||
assertEquals(f, proportion, 1e-4);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -107,24 +111,4 @@ public class SplitterTest extends TestCase{
|
||||
assertTrue(firstSize.height < firstMinimum.height == secondSize.height < secondMinimum.height);
|
||||
}
|
||||
}
|
||||
|
||||
private void invokeRatherLater(final Runnable runnable) {
|
||||
invokeRatherLater(runnable, RATHER_LATER_INVOKES);
|
||||
}
|
||||
|
||||
private void invokeRatherLater(final Runnable runnable, final int n) {
|
||||
if(n == 0) {
|
||||
runnable.run();
|
||||
}
|
||||
else {
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
invokeRatherLater(runnable, n - 1);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
+16
-2
@@ -19,22 +19,36 @@ import com.intellij.openapi.util.SystemInfo;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.BeforeClass;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assume.assumeTrue;
|
||||
|
||||
public class FileAttributesNio2ReadingTest extends FileAttributesReadingTest {
|
||||
private static final String FORCE_USE_NIO_2_KEY;
|
||||
static {
|
||||
try {
|
||||
Field field = FileSystemUtil.class.getDeclaredField("FORCE_USE_NIO2_KEY");
|
||||
field.setAccessible(true);
|
||||
FORCE_USE_NIO_2_KEY = (String)field.get(null);
|
||||
}
|
||||
catch (Exception e) {
|
||||
throw new AssertionError("Please keep constants in sync: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@BeforeClass
|
||||
public static void setUpClass() throws Exception {
|
||||
assumeTrue(SystemInfo.isJavaVersionAtLeast("1.7"));
|
||||
|
||||
System.setProperty(FileSystemUtil.FORCE_USE_NIO2_KEY, "true");
|
||||
System.setProperty(FORCE_USE_NIO_2_KEY, "true");
|
||||
FileSystemUtil.resetMediator();
|
||||
assertEquals("NIO2", FileSystemUtil.getMediatorName());
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void tearDownClass() throws Exception {
|
||||
System.setProperty(FileSystemUtil.FORCE_USE_NIO2_KEY, "");
|
||||
System.setProperty(FORCE_USE_NIO_2_KEY, "");
|
||||
FileSystemUtil.resetMediator();
|
||||
}
|
||||
}
|
||||
|
||||
+11
-3
@@ -188,8 +188,12 @@ public class PointlessBooleanExpressionInspection extends BaseInspection {
|
||||
private void buildSimplifiedExpression(List<PsiExpression> expressions, String token, boolean negate, StringBuilder out) {
|
||||
if (expressions.size() == 1) {
|
||||
final PsiExpression expression = expressions.get(0);
|
||||
final String expressionText = expression.getText();
|
||||
if (isBoxedTypeComparison(token, expression)) {
|
||||
out.append(expressionText).append(" != null && ");
|
||||
}
|
||||
if (!negate) {
|
||||
out.append(expression.getText());
|
||||
out.append(expressionText);
|
||||
return;
|
||||
}
|
||||
if (ComparisonUtils.isComparison(expression)) {
|
||||
@@ -202,10 +206,10 @@ public class PointlessBooleanExpressionInspection extends BaseInspection {
|
||||
}
|
||||
else {
|
||||
if (ParenthesesUtils.getPrecedence(expression) > ParenthesesUtils.PREFIX_PRECEDENCE) {
|
||||
out.append("!(").append(expression.getText()).append(')');
|
||||
out.append("!(").append(expressionText).append(')');
|
||||
}
|
||||
else {
|
||||
out.append('!').append(expression.getText());
|
||||
out.append('!').append(expressionText);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -229,6 +233,10 @@ public class PointlessBooleanExpressionInspection extends BaseInspection {
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isBoxedTypeComparison(String token, PsiExpression expression) {
|
||||
return ("==".equals(token) || "!=".equals(token)) && expression instanceof PsiReferenceExpression && expression.getType() instanceof PsiClassType;
|
||||
}
|
||||
|
||||
private void buildSimplifiedPrefixExpression(PsiPrefixExpression expression, StringBuilder out) {
|
||||
final PsiJavaToken sign = expression.getOperationSign();
|
||||
final IElementType tokenType = sign.getTokenType();
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2003-2007 Dave Griffith, Bas Leijdekkers
|
||||
* Copyright 2003-2012 Dave Griffith, Bas Leijdekkers
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -18,12 +18,15 @@ package com.siyeh.ig.jdk;
|
||||
import com.intellij.codeInspection.ProblemDescriptor;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.codeStyle.CodeStyleSettings;
|
||||
import com.intellij.psi.codeStyle.CodeStyleSettingsManager;
|
||||
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import com.siyeh.InspectionGadgetsBundle;
|
||||
import com.siyeh.ig.BaseInspection;
|
||||
import com.siyeh.ig.BaseInspectionVisitor;
|
||||
import com.siyeh.ig.InspectionGadgetsFix;
|
||||
import com.siyeh.ig.psiutils.ParenthesesUtils;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@@ -31,14 +34,12 @@ public class ForeachStatementInspection extends BaseInspection {
|
||||
|
||||
@NotNull
|
||||
public String getDisplayName() {
|
||||
return InspectionGadgetsBundle.message(
|
||||
"extended.for.statement.display.name");
|
||||
return InspectionGadgetsBundle.message("extended.for.statement.display.name");
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String buildErrorString(Object... infos) {
|
||||
return InspectionGadgetsBundle.message(
|
||||
"extended.for.statement.problem.descriptor");
|
||||
return InspectionGadgetsBundle.message("extended.for.statement.problem.descriptor");
|
||||
}
|
||||
|
||||
protected InspectionGadgetsFix buildFix(Object... infos) {
|
||||
@@ -49,85 +50,62 @@ public class ForeachStatementInspection extends BaseInspection {
|
||||
|
||||
@NotNull
|
||||
public String getName() {
|
||||
return InspectionGadgetsBundle.message(
|
||||
"extended.for.statement.replace.quickfix");
|
||||
return InspectionGadgetsBundle.message("extended.for.statement.replace.quickfix");
|
||||
}
|
||||
|
||||
public void doFix(Project project, ProblemDescriptor descriptor)
|
||||
throws IncorrectOperationException {
|
||||
public void doFix(Project project, ProblemDescriptor descriptor) throws IncorrectOperationException {
|
||||
final PsiElement element = descriptor.getPsiElement();
|
||||
final PsiForeachStatement statement =
|
||||
(PsiForeachStatement)element.getParent();
|
||||
final JavaCodeStyleManager codeStyleManager =
|
||||
JavaCodeStyleManager.getInstance(project);
|
||||
final PsiForeachStatement statement = (PsiForeachStatement)element.getParent();
|
||||
final JavaCodeStyleManager codeStyleManager = JavaCodeStyleManager.getInstance(project);
|
||||
assert statement != null;
|
||||
final PsiExpression iteratedValue = statement.getIteratedValue();
|
||||
if (iteratedValue == null) {
|
||||
return;
|
||||
}
|
||||
@NonNls final StringBuffer newStatement = new StringBuffer();
|
||||
final PsiParameter iterationParameter =
|
||||
statement.getIterationParameter();
|
||||
@NonNls final StringBuilder newStatement = new StringBuilder();
|
||||
final PsiParameter iterationParameter = statement.getIterationParameter();
|
||||
final CodeStyleSettings codeStyleSettings = CodeStyleSettingsManager.getSettings(project);
|
||||
if (iteratedValue.getType() instanceof PsiArrayType) {
|
||||
final PsiType type = iterationParameter.getType();
|
||||
final String index =
|
||||
codeStyleManager.suggestUniqueVariableName("i",
|
||||
statement, true);
|
||||
newStatement.append("for(int ");
|
||||
newStatement.append(index);
|
||||
newStatement.append(" = 0;");
|
||||
newStatement.append(index);
|
||||
newStatement.append('<');
|
||||
newStatement.append(iteratedValue.getText());
|
||||
newStatement.append(".length;");
|
||||
newStatement.append(index);
|
||||
newStatement.append("++)");
|
||||
newStatement.append("{ ");
|
||||
newStatement.append(type.getCanonicalText());
|
||||
newStatement.append(' ');
|
||||
newStatement.append(iterationParameter.getName());
|
||||
newStatement.append(" = ");
|
||||
newStatement.append(iteratedValue.getText());
|
||||
newStatement.append('[');
|
||||
newStatement.append(index);
|
||||
newStatement.append("];");
|
||||
final String index = codeStyleManager.suggestUniqueVariableName("i", statement, true);
|
||||
newStatement.append("for(int ").append(index).append(" = 0;");
|
||||
newStatement.append(index).append('<').append(iteratedValue.getText()).append(".length;");
|
||||
newStatement.append(index).append("++)").append("{ ");
|
||||
if (codeStyleSettings.GENERATE_FINAL_LOCALS) {
|
||||
newStatement.append("final ");
|
||||
}
|
||||
newStatement.append(type.getCanonicalText()).append(' ').append(iterationParameter.getName());
|
||||
newStatement.append(" = ").append(iteratedValue.getText()).append('[').append(index).append("];");
|
||||
}
|
||||
else {
|
||||
final PsiType iteratedType = iteratedValue.getType();
|
||||
final PsiType type;
|
||||
if (iteratedType instanceof PsiClassType) {
|
||||
final PsiClassType classType = (PsiClassType)iteratedType;
|
||||
final PsiType[] types = classType.getParameters();
|
||||
type = types[0];
|
||||
@NonNls final StringBuilder methodCall = new StringBuilder();
|
||||
if (ParenthesesUtils.getPrecedence(iteratedValue) > ParenthesesUtils.METHOD_CALL_PRECEDENCE) {
|
||||
methodCall.append('(').append(iteratedValue.getText()).append(')');
|
||||
}
|
||||
else {
|
||||
type = iterationParameter.getType();
|
||||
methodCall.append(iteratedValue.getText());
|
||||
}
|
||||
final String iterator =
|
||||
codeStyleManager.suggestUniqueVariableName("it",
|
||||
statement, true);
|
||||
final String typeText = type.getCanonicalText();
|
||||
newStatement.append("for(java.util.Iterator<");
|
||||
newStatement.append(typeText);
|
||||
newStatement.append("> ");
|
||||
newStatement.append(iterator);
|
||||
newStatement.append(" = ");
|
||||
newStatement.append(iteratedValue.getText());
|
||||
newStatement.append(".iterator();");
|
||||
newStatement.append(iterator);
|
||||
newStatement.append(".hasNext();)");
|
||||
newStatement.append('{');
|
||||
newStatement.append(typeText);
|
||||
newStatement.append(' ');
|
||||
newStatement.append(iterationParameter.getName());
|
||||
newStatement.append(" = ");
|
||||
newStatement.append(iterator);
|
||||
newStatement.append(".next();");
|
||||
methodCall.append(".iterator()");
|
||||
final PsiElementFactory factory = JavaPsiFacade.getInstance(project).getElementFactory();
|
||||
final PsiExpression iteratorCall = factory.createExpressionFromText(methodCall.toString(), iteratedValue);
|
||||
final PsiType variableType = GenericsUtil.getVariableTypeByExpressionType(iteratorCall.getType());
|
||||
if (variableType == null) {
|
||||
return;
|
||||
}
|
||||
final PsiType parameterType = iterationParameter.getType();
|
||||
final String typeText = parameterType.getCanonicalText();
|
||||
newStatement.append("for(").append(variableType.getCanonicalText()).append(' ');
|
||||
final String iterator = codeStyleManager.suggestUniqueVariableName("iterator", statement, true);
|
||||
newStatement.append(iterator).append("=").append(iteratorCall.getText()).append(';');
|
||||
newStatement.append(iterator).append(".hasNext();){");
|
||||
if (codeStyleSettings.GENERATE_FINAL_LOCALS) {
|
||||
newStatement.append("final ");
|
||||
}
|
||||
newStatement.append(typeText).append(' ').append(iterationParameter.getName()).append(" = ").append(iterator).append(".next();");
|
||||
}
|
||||
final PsiStatement body = statement.getBody();
|
||||
if (body instanceof PsiBlockStatement) {
|
||||
final PsiBlockStatement blockStatement =
|
||||
(PsiBlockStatement)body;
|
||||
final PsiBlockStatement blockStatement = (PsiBlockStatement)body;
|
||||
final PsiCodeBlock block = blockStatement.getCodeBlock();
|
||||
final PsiElement[] children = block.getChildren();
|
||||
for (int i = 1; i < children.length - 1; i++) {
|
||||
@@ -146,7 +124,7 @@ public class ForeachStatementInspection extends BaseInspection {
|
||||
newStatement.append(bodyText);
|
||||
}
|
||||
newStatement.append('}');
|
||||
replaceStatement(statement, newStatement.toString());
|
||||
replaceStatementAndShortenClassNames(statement, newStatement.toString());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -154,12 +132,10 @@ public class ForeachStatementInspection extends BaseInspection {
|
||||
return new ForeachStatementVisitor();
|
||||
}
|
||||
|
||||
private static class ForeachStatementVisitor
|
||||
extends BaseInspectionVisitor {
|
||||
private static class ForeachStatementVisitor extends BaseInspectionVisitor {
|
||||
|
||||
@Override
|
||||
public void visitForeachStatement(
|
||||
@NotNull PsiForeachStatement statement) {
|
||||
public void visitForeachStatement(@NotNull PsiForeachStatement statement) {
|
||||
super.visitForeachStatement(statement);
|
||||
registerStatementError(statement);
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user