Merge remote-tracking branch 'origin/master'
@@ -145,6 +145,7 @@ binding.setVariable("loadProject", {
|
||||
def compilerOptions = JpsJavaExtensionService.instance.getOrCreateCompilerConfiguration(project).currentCompilerOptions
|
||||
compilerOptions.GENERATE_NO_WARNINGS = true
|
||||
compilerOptions.DEPRECATION = false
|
||||
compilerOptions.ADDITIONAL_OPTIONS_STRING = compilerOptions.ADDITIONAL_OPTIONS_STRING.replace("-Xlint:unchecked", "")
|
||||
})
|
||||
|
||||
boolean hasSourceRoots(JpsModule module) {
|
||||
|
||||
@@ -26,14 +26,14 @@ import org.jdom.Element;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
class IdeaProjectStoreImpl extends ProjectWithModulesStoreImpl {
|
||||
public IdeaProjectStoreImpl(@NotNull ProjectImpl project) {
|
||||
super(project);
|
||||
public IdeaProjectStoreImpl(@NotNull ProjectImpl project, @NotNull PathMacroManager pathMacroManager) {
|
||||
super(project, pathMacroManager);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
protected StateStorageManager createStateStorageManager() {
|
||||
return new ProjectStateStorageManager(PathMacroManager.getInstance(getComponentManager()).createTrackingSubstitutor(), myProject) {
|
||||
return new ProjectStateStorageManager(myPathMacroManager.createTrackingSubstitutor(), myProject) {
|
||||
@Override
|
||||
public StorageData createIprStorageData(@NotNull String filePath) {
|
||||
return new IdeaIprStorageData(ROOT_TAG_NAME, myProject, filePath);
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
public class Main {
|
||||
|
||||
|
||||
public int a = 3;
|
||||
protected Object obj = null;
|
||||
private long e = 4;
|
||||
|
||||
public static void main(String[] args) {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
import java.lang.Object;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Set;
|
||||
|
||||
public class Main {
|
||||
|
||||
|
||||
|
||||
public int a = 3;
|
||||
private long e = 4;
|
||||
|
||||
|
||||
protected Object obj = null;
|
||||
|
||||
public static void main(String[] args) {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Set;
|
||||
|
||||
public class Main {
|
||||
|
||||
|
||||
|
||||
public static void main(String[] args) {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
import java.util.List;
|
||||
|
||||
public class Test {
|
||||
|
||||
public long newRun;
|
||||
public int ab;
|
||||
public int awe;
|
||||
private int c;
|
||||
|
||||
public void run() {
|
||||
List<String> strings = null;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
import java.util.HashMap;
|
||||
import java.util.Set;
|
||||
import java.util.List;
|
||||
|
||||
public class Test {
|
||||
|
||||
public long newRun;
|
||||
|
||||
public void run() {
|
||||
List<String> strings = null;
|
||||
}
|
||||
|
||||
public int ab;
|
||||
private int c;
|
||||
|
||||
|
||||
public int awe;
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Set;
|
||||
|
||||
public class Main {
|
||||
|
||||
|
||||
public static void main(String[] args) {
|
||||
Runnable runnable = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
Set<String> test = new LinkedHashSet<String>();
|
||||
if (test.contains("AA")) {
|
||||
if (test.contains("AS")) {
|
||||
System.out.println("AAAA!");
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
runnable.run();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
import java.lang.Override;
|
||||
import java.lang.Runnable;
|
||||
import java.lang.String;
|
||||
import java.util.Set;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashSet;
|
||||
|
||||
public class Main {
|
||||
|
||||
|
||||
public static void main(String[] args) {
|
||||
Runnable runnable = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
Set<String> test = new LinkedHashSet<String>();
|
||||
if (test.contains("AA")) {
|
||||
if (test.contains("AS")) {
|
||||
System.out.println("AAAA!");
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
runnable.run();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
import com.intellij.util.containers.HashSet;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.HashSet;
|
||||
|
||||
public class Main {
|
||||
|
||||
|
||||
public static void main(String[] args) {
|
||||
Runnable runnable = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
Set<String> test = new HashSet<String>();
|
||||
if (test.contains("AA")) {
|
||||
System.out.println("AAAA!");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
runnable.run();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
import java.util.List;
|
||||
|
||||
public class Test {
|
||||
|
||||
|
||||
public void run() {
|
||||
List<String> strings = null;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
import java.util.HashMap;
|
||||
import java.util.Set;
|
||||
import java.util.List;
|
||||
|
||||
public class Test {
|
||||
|
||||
|
||||
public void run() {
|
||||
List<String> strings = null;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
class Test {
|
||||
|
||||
public int a = 3;
|
||||
private int b = 3;
|
||||
|
||||
|
||||
public void run () {}
|
||||
int aero = 12;
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
class Test {
|
||||
|
||||
<selection> private int b = 3;
|
||||
public int a = 3;</selection>
|
||||
|
||||
|
||||
public void run () {}
|
||||
int aero = 12;
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
public class Test {
|
||||
|
||||
int a = 3;
|
||||
|
||||
int c = 12;
|
||||
|
||||
public void run() {
|
||||
|
||||
int arr = 12;
|
||||
long test = 1;
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
public class Test {
|
||||
|
||||
int a = 3;
|
||||
|
||||
int c = 12;
|
||||
|
||||
public void run() {
|
||||
|
||||
<selection> int arr = 12;
|
||||
long test =1;</selection>
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
public class Test {
|
||||
|
||||
public void run() {
|
||||
|
||||
int a = 3;
|
||||
int b = 12;
|
||||
|
||||
}
|
||||
|
||||
public void test() {
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
public class Test {
|
||||
|
||||
public void run() {
|
||||
|
||||
int a = 3;
|
||||
int b = 12;
|
||||
|
||||
}
|
||||
|
||||
public void test() {
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
public class Test {
|
||||
|
||||
public void run() {
|
||||
|
||||
int a = 3;
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
public class Test {
|
||||
|
||||
int a = 3;
|
||||
|
||||
|
||||
void run() {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
public class Test {
|
||||
|
||||
int a = 3;
|
||||
|
||||
|
||||
void run()
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,121 @@
|
||||
/*
|
||||
* Copyright 2000-2014 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.codeInsight.actions;
|
||||
|
||||
import com.intellij.JavaTestUtil;
|
||||
import com.intellij.openapi.actionSystem.*;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.vcs.FilePath;
|
||||
import com.intellij.openapi.vcs.VcsException;
|
||||
import com.intellij.openapi.vcs.changes.Change;
|
||||
import com.intellij.openapi.vcs.changes.ContentRevision;
|
||||
import com.intellij.openapi.vcs.history.VcsRevisionNumber;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class ReformatCodeActionInEditorTest extends LightCodeInsightFixtureTestCase {
|
||||
|
||||
@Override
|
||||
protected String getTestDataPath() {
|
||||
return JavaTestUtil.getJavaTestDataPath() + "/actions/reformatFileInEditor/";
|
||||
}
|
||||
|
||||
public void doTest(@NotNull ReformatFilesOptions options) {
|
||||
setOptions(options);
|
||||
|
||||
String before = null;
|
||||
if (options.isProcessOnlyChangedText()) {
|
||||
myFixture.configureByFile(getTestDataPath() + getTestName(true) + "_revision.java");
|
||||
PsiFile file = myFixture.getFile();
|
||||
Document document = myFixture.getDocument(file);
|
||||
before = document.getText();
|
||||
}
|
||||
|
||||
myFixture.configureByFile(getTestDataPath() + getTestName(true) + "_before.java");
|
||||
|
||||
if (before != null) {
|
||||
myFixture.getFile().putUserData(FormatChangedTextUtil.TEST_REVISION_CONTENT, before);
|
||||
}
|
||||
|
||||
final String actionId = IdeActions.ACTION_EDITOR_REFORMAT;
|
||||
AnAction action = ActionManager.getInstance().getAction(actionId);
|
||||
|
||||
AnActionEvent event = createEventFor(action, getProject(), myFixture.getEditor());
|
||||
|
||||
action.actionPerformed(event);
|
||||
myFixture.checkResultByFile(getTestName(true) + "_after.java");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tearDown() throws Exception {
|
||||
myFixture.getFile().putUserData(FormatChangedTextUtil.TEST_REVISION_CONTENT, null);
|
||||
super.tearDown();
|
||||
}
|
||||
|
||||
protected AnActionEvent createEventFor(@NotNull AnAction action, @NotNull final Project project, @NotNull final Editor editor) {
|
||||
return new AnActionEvent(null, new DataContext() {
|
||||
@Nullable
|
||||
@Override
|
||||
public Object getData(@NonNls String dataId) {
|
||||
if (CommonDataKeys.PROJECT.is(dataId)) return project;
|
||||
if (CommonDataKeys.EDITOR.is(dataId)) return editor;
|
||||
return null;
|
||||
}
|
||||
}, "", action.getTemplatePresentation(), ActionManager.getInstance(), 0);
|
||||
}
|
||||
|
||||
protected void setOptions(ReformatFilesOptions options) {
|
||||
ReformatCodeAction.setTestOptions(options);
|
||||
}
|
||||
|
||||
public void testFormatWholeFile() {
|
||||
doTest(new MockReformatFileSettings().setProcessWholeFile(true));
|
||||
}
|
||||
|
||||
public void testFormatOptimizeWholeFile() {
|
||||
doTest(new MockReformatFileSettings().setProcessWholeFile(true).setOptimizeImports(true));
|
||||
}
|
||||
|
||||
public void testFormatOptimizeRearrangeWholeFile() {
|
||||
doTest(new MockReformatFileSettings().setProcessWholeFile(true).setOptimizeImports(true).setRearrange(true));
|
||||
}
|
||||
|
||||
public void testFormatSelection() {
|
||||
doTest(new MockReformatFileSettings().setProcessWholeFile(false));
|
||||
}
|
||||
|
||||
public void testFormatRearrangeSelection() {
|
||||
doTest(new MockReformatFileSettings().setProcessWholeFile(false).setRearrange(true));
|
||||
}
|
||||
|
||||
public void testFormatVcsChanges() {
|
||||
doTest(new MockReformatFileSettings().setProcessOnlyChangedText(true));
|
||||
}
|
||||
|
||||
public void testFormatOptimizeVcsChanges() {
|
||||
doTest(new MockReformatFileSettings().setProcessOnlyChangedText(true).setOptimizeImports(true));
|
||||
}
|
||||
|
||||
public void testFormatOptimizeRearrangeVcsChanges() {
|
||||
doTest(new MockReformatFileSettings().setProcessOnlyChangedText(true).setOptimizeImports(true).setRearrange(true));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -115,7 +115,7 @@ public class NavigateFromSourceTest extends BaseProjectViewTestCase {
|
||||
|
||||
pane.select(psiClass, psiClass.getContainingFile().getVirtualFile(), true);
|
||||
|
||||
assertEquals(9, tree.getSelectionCount());
|
||||
assertEquals(8, tree.getSelectionCount());
|
||||
}
|
||||
|
||||
private static void changeClassTextAndTryToNavigate(final String newClassString,
|
||||
|
||||
@@ -33,6 +33,7 @@ class JavaPredefinedConfigurations {
|
||||
createSearchTemplateInfo(SSRBundle.message("predefined.configuration.string.literals"),"\"'_String\"",EXPRESSION_TYPE),
|
||||
createSearchTemplateInfo(SSRBundle.message("predefined.configuration.all.expressions.of.some.type"),"'_Expression:[exprtype( SomeType )]",EXPRESSION_TYPE),
|
||||
createSearchTemplateInfo(SSRBundle.message("predefined.configuration.sample.method.invokation.with.constant.argument"),"Integer.parseInt('_a:[script( \"com.intellij.psi.util.PsiUtil.isConstantExpression(__context__)\" )])",EXPRESSION_TYPE),
|
||||
createSearchTemplateInfo(SSRBundle.message("predefined.configuration.method.references"), "'_Qualifier::'methodName", EXPRESSION_TYPE),
|
||||
|
||||
// Operators
|
||||
createSearchTemplateInfo(SSRBundle.message("predefined.configuration.block.dcls"),"{\n '_Type+ 'Var+ = '_Init*;\n '_BlockStatements*;\n}",OPERATOR_TYPE),
|
||||
@@ -90,7 +91,7 @@ class JavaPredefinedConfigurations {
|
||||
),
|
||||
createSearchTemplateInfo(
|
||||
SSRBundle.message("predefined.configuration.implementors.of.interface.within.hierarchy"),
|
||||
"class 'Class implements 'Interface:* {}",
|
||||
"class 'Class implements '_Interface:* {}",
|
||||
CLASS_TYPE
|
||||
),
|
||||
createSearchTemplateInfo(
|
||||
@@ -165,6 +166,7 @@ class JavaPredefinedConfigurations {
|
||||
createSearchTemplateInfo(SSRBundle.message("predefined.configuration.generic.casts"),"( '_Type <'_GenericArgument+> ) '_Expr", GENERICS_TYPE),
|
||||
createSearchTemplateInfo(SSRBundle.message("predefined.configuration.type.var.substitutions.in.intanceof.with.generic.types"),"'_Expr instanceof '_Type <'Substitutions+> ", GENERICS_TYPE),
|
||||
createSearchTemplateInfo(SSRBundle.message("predefined.configuration.variables.of.generic.types"),"'_Type <'_GenericArgument+> 'Var = 'Init?;", GENERICS_TYPE),
|
||||
createSearchTemplateInfo(SSRBundle.message("predefined.configuration.diamond.operators"), "new 'ClassName<>('_Argument*)", GENERICS_TYPE),
|
||||
|
||||
// Add comments and metadata
|
||||
createSearchTemplateInfo(SSRBundle.message("predefined.configuration.comments"),"/* 'CommentContent */", METADATA_TYPE),
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
*/
|
||||
package com.intellij.testFramework;
|
||||
|
||||
import com.intellij.ide.highlighter.ProjectFileType;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.application.ex.PathManagerEx;
|
||||
import com.intellij.openapi.fileEditor.ex.FileEditorManagerEx;
|
||||
@@ -101,7 +100,6 @@ import java.io.File;
|
||||
}
|
||||
|
||||
protected String getRootFiles() {
|
||||
return " " + myModule.getModuleFile().getName() + "\n" +
|
||||
" " + myProject.getName() + ProjectFileType.DOT_DEFAULT_EXTENSION + "\n";
|
||||
return " " + myModule.getModuleFile().getName() + "\n";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -602,8 +602,10 @@ public class JavaBuilder extends ModuleLevelBuilder {
|
||||
if (baseDirectory != null) {
|
||||
//this is a temporary workaround to allow passing per-module compiler options for Eclipse compiler in form
|
||||
// -properties $MODULE_DIR$/.settings/org.eclipse.jdt.core.prefs
|
||||
String stringToReplace = "$" + PathMacroUtil.MODULE_DIR_MACRO_NAME + "$";
|
||||
String moduleDirPath = FileUtil.toCanonicalPath(baseDirectory.getAbsolutePath());
|
||||
for (String s : cached) {
|
||||
options.add(StringUtil.replace(s, "$" + PathMacroUtil.MODULE_DIR_MACRO_NAME + "$", baseDirectory.getAbsolutePath()));
|
||||
options.add(StringUtil.replace(s, stringToReplace, moduleDirPath));
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
||||
@@ -120,11 +120,11 @@ public class HighlightDisplayLevel {
|
||||
|
||||
@NotNull
|
||||
public static Icon createIconByMask(final Color renderColor) {
|
||||
return new TheColorIcon(getEmptyIconDim(), renderColor);
|
||||
return new MyColorIcon(getEmptyIconDim(), renderColor);
|
||||
}
|
||||
|
||||
public static class TheColorIcon extends ColorIcon implements ColoredIcon {
|
||||
public TheColorIcon(int size, @NotNull Color color) {
|
||||
private static class MyColorIcon extends ColorIcon implements ColoredIcon {
|
||||
public MyColorIcon(int size, @NotNull Color color) {
|
||||
super(size, color);
|
||||
}
|
||||
|
||||
@@ -132,12 +132,12 @@ public class HighlightDisplayLevel {
|
||||
public Color getColor() {
|
||||
return getIconColor();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public interface ColoredIcon {
|
||||
Color getColor();
|
||||
}
|
||||
|
||||
|
||||
public static class SingleColorIcon implements Icon, ColoredIcon {
|
||||
private final TextAttributesKey myKey;
|
||||
|
||||
|
||||
@@ -94,16 +94,7 @@ public class SeverityRegistrar implements JDOMExternalizable, Comparator<Highlig
|
||||
myRendererColors.put(severity.getName(), renderColor);
|
||||
}
|
||||
myOrderMap = null;
|
||||
|
||||
final TextAttributes attributes = info.getAttributes();
|
||||
Color color = attributes.getErrorStripeColor();
|
||||
if (color == null) {
|
||||
color = attributes.getEffectColor();
|
||||
}
|
||||
if (color == null) {
|
||||
color = JBColor.GRAY;
|
||||
}
|
||||
new HighlightDisplayLevel(severity, new HighlightDisplayLevel.TheColorIcon(HighlightDisplayLevel.getEmptyIconDim(), color));
|
||||
HighlightDisplayLevel.registerSeverity(severity, getHighlightInfoTypeBySeverity(severity).getAttributesKey());
|
||||
severitiesChanged();
|
||||
}
|
||||
|
||||
|
||||
@@ -332,7 +332,7 @@ public abstract class VirtualFile extends UserDataHolderBase implements Modifica
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@NotNull
|
||||
public VirtualFile findOrCreateChildData(Object requestor, @NotNull @NonNls String name) throws IOException {
|
||||
final VirtualFile child = findChild(name);
|
||||
if (child != null) return child;
|
||||
|
||||
@@ -23,7 +23,7 @@ import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* @author peter
|
||||
* @see com.intellij.psi.LanguageSubstitutors
|
||||
* @see LanguageSubstitutors
|
||||
*/
|
||||
public abstract class LanguageSubstitutor {
|
||||
|
||||
|
||||
@@ -126,10 +126,24 @@ public class FileManagerImpl implements FileManager {
|
||||
}
|
||||
}
|
||||
removeInvalidFilesAndDirs(false);
|
||||
checkLanguageChange();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void checkLanguageChange() {
|
||||
Map<VirtualFile, FileViewProvider> fileToPsiFileMap = new THashMap<VirtualFile, FileViewProvider>(myVFileToViewProviderMap);
|
||||
myVFileToViewProviderMap.clear();
|
||||
for (Iterator<VirtualFile> iterator = fileToPsiFileMap.keySet().iterator(); iterator.hasNext();) {
|
||||
VirtualFile vFile = iterator.next();
|
||||
Language language = getLanguage(vFile);
|
||||
if (language != null && language != fileToPsiFileMap.get(vFile).getBaseLanguage()) {
|
||||
iterator.remove();
|
||||
}
|
||||
}
|
||||
myVFileToViewProviderMap.putAll(fileToPsiFileMap);
|
||||
}
|
||||
|
||||
public void forceReload(@NotNull VirtualFile vFile) {
|
||||
if (findCachedViewProvider(vFile) == null) {
|
||||
return;
|
||||
@@ -231,6 +245,11 @@ public class FileManagerImpl implements FileManager {
|
||||
@NotNull
|
||||
public FileViewProvider createFileViewProvider(@NotNull final VirtualFile file, boolean eventSystemEnabled) {
|
||||
Language language = getLanguage(file);
|
||||
return createFileViewProvider(file, eventSystemEnabled, language);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private FileViewProvider createFileViewProvider(@NotNull VirtualFile file, boolean eventSystemEnabled, Language language) {
|
||||
final FileViewProviderFactory factory = language == null
|
||||
? FileTypeFileViewProviders.INSTANCE.forFileType(file.getFileType())
|
||||
: LanguageFileViewProviders.INSTANCE.forLanguage(language);
|
||||
|
||||
|
After Width: | Height: | Size: 1.0 KiB |
|
After Width: | Height: | Size: 1.3 KiB |
|
After Width: | Height: | Size: 1.4 KiB |
|
After Width: | Height: | Size: 1.1 KiB |
|
After Width: | Height: | Size: 1.1 KiB |
|
After Width: | Height: | Size: 1.4 KiB |
|
After Width: | Height: | Size: 1.4 KiB |
|
After Width: | Height: | Size: 1.1 KiB |
@@ -114,26 +114,8 @@ class PrintManager {
|
||||
painter = new MultiFilePainter(filesList);
|
||||
}
|
||||
|
||||
Pageable document = new Pageable() {
|
||||
@Override
|
||||
public int getNumberOfPages() {
|
||||
return Pageable.UNKNOWN_NUMBER_OF_PAGES;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PageFormat getPageFormat(int pageIndex) throws IndexOutOfBoundsException {
|
||||
return pageFormat;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Printable getPrintable(int pageIndex) throws IndexOutOfBoundsException {
|
||||
return painter;
|
||||
}
|
||||
};
|
||||
|
||||
final PrinterJob printerJob = PrinterJob.getPrinterJob();
|
||||
try {
|
||||
printerJob.setPageable(document);
|
||||
printerJob.setPrintable(painter, pageFormat);
|
||||
if (!printerJob.printDialog()) {
|
||||
return;
|
||||
@@ -230,7 +212,8 @@ class PrintManager {
|
||||
if (doc == null) return null;
|
||||
EditorHighlighter highlighter = HighlighterFactory.createHighlighter(psiFile.getProject(), virtualFile);
|
||||
highlighter.setText(doc.getCharsSequence());
|
||||
return new TextPainter(doc, highlighter, virtualFile.getPresentableUrl(), psiFile, psiFile.getFileType(), editor);
|
||||
return new TextPainter(doc, highlighter, virtualFile.getPresentableUrl(), virtualFile.getPresentableName(),
|
||||
psiFile, psiFile.getFileType(), editor);
|
||||
}
|
||||
|
||||
private static TextPainter initTextPainter(@NotNull final DocumentEx doc, final Project project) {
|
||||
@@ -249,6 +232,6 @@ class PrintManager {
|
||||
private static TextPainter doInitTextPainter(@NotNull final DocumentEx doc, Project project) {
|
||||
EditorHighlighter highlighter = HighlighterFactory.createHighlighter(project, "unknown");
|
||||
highlighter.setText(doc.getCharsSequence());
|
||||
return new TextPainter(doc, highlighter, "unknown", project, FileTypes.PLAIN_TEXT, null);
|
||||
return new TextPainter(doc, highlighter, "unknown", "unknown", project, FileTypes.PLAIN_TEXT, null);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,6 +28,7 @@ import com.intellij.openapi.fileTypes.FileType;
|
||||
import com.intellij.openapi.progress.ProgressManager;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Computable;
|
||||
import com.intellij.openapi.util.Ref;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.codeStyle.CodeStyleSettings;
|
||||
import com.intellij.psi.codeStyle.CodeStyleSettingsManager;
|
||||
@@ -45,6 +46,8 @@ import java.awt.geom.Point2D;
|
||||
import java.awt.geom.Rectangle2D;
|
||||
import java.awt.print.PageFormat;
|
||||
import java.awt.print.PrinterException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
class TextPainter extends BasePainter {
|
||||
@@ -62,32 +65,48 @@ class TextPainter extends BasePainter {
|
||||
private final Font myHeaderFont;
|
||||
private final EditorHighlighter myHighlighter;
|
||||
private final PrintSettings myPrintSettings;
|
||||
private final String myFileName;
|
||||
private final String myFullFileName;
|
||||
private final String myShortFileName;
|
||||
private int myPageIndex;
|
||||
private int myNumberOfPages = -1;
|
||||
private int mySegmentEnd;
|
||||
private final LineMarkerInfo[] myMethodSeparators;
|
||||
private int myCurrentMethodSeparator;
|
||||
private final CodeStyleSettings myCodeStyleSettings;
|
||||
private final FileType myFileType;
|
||||
private boolean myPerformActualDrawing;
|
||||
|
||||
private final String myPrintDate;
|
||||
private final String myPrintTime;
|
||||
|
||||
@NonNls private static final String DEFAULT_MEASURE_HEIGHT_TEXT = "A";
|
||||
@NonNls private static final String DEFAULT_MEASURE_WIDTH_TEXT = "w";
|
||||
|
||||
@NonNls private static final String HEADER_TOKEN_PAGE = "PAGE";
|
||||
@NonNls private static final String HEADER_TOKEN_TOTALPAGES = "TOTALPAGES";
|
||||
@NonNls private static final String HEADER_TOKEN_FILE = "FILE";
|
||||
@NonNls private static final String HEADER_TOKEN_FILENAME = "FILENAME";
|
||||
@NonNls private static final String HEADER_TOKEN_DATE = "DATE";
|
||||
@NonNls private static final String HEADER_TOKEN_TIME = "TIME";
|
||||
|
||||
@NonNls private static final String DATE_FORMAT = "yyyy-MM-dd";
|
||||
@NonNls private static final String TIME_FORMAT = "HH:mm:ss";
|
||||
|
||||
public TextPainter(@NotNull DocumentEx editorDocument,
|
||||
EditorHighlighter highlighter,
|
||||
String fileName,
|
||||
String fullFileName,
|
||||
String shortFileName,
|
||||
@NotNull PsiFile psiFile,
|
||||
FileType fileType,
|
||||
Editor editor) {
|
||||
this(editorDocument, highlighter, fileName, psiFile.getProject(), fileType,
|
||||
this(editorDocument, highlighter, fullFileName, shortFileName, psiFile.getProject(), fileType,
|
||||
FileSeparatorProvider.getInstance().getFileSeparators(psiFile, editorDocument, editor));
|
||||
}
|
||||
|
||||
public TextPainter(@NotNull DocumentEx editorDocument,
|
||||
EditorHighlighter highlighter,
|
||||
String fileName,
|
||||
String fullFileName,
|
||||
String shortFileName,
|
||||
Project project,
|
||||
FileType fileType,
|
||||
List<LineMarkerInfo> separators) {
|
||||
@@ -102,18 +121,26 @@ class TextPainter extends BasePainter {
|
||||
myBoldItalicFont = new Font(fontName, Font.BOLD | Font.ITALIC, fontSize);
|
||||
myHighlighter = highlighter;
|
||||
myHeaderFont = new Font(myPrintSettings.FOOTER_HEADER_FONT_NAME, Font.PLAIN, myPrintSettings.FOOTER_HEADER_FONT_SIZE);
|
||||
myFileName = fileName;
|
||||
myFullFileName = fullFileName;
|
||||
myShortFileName = shortFileName;
|
||||
myRangeToPrint = editorDocument.createRangeMarker(0, myDocument.getTextLength());
|
||||
myFileType = fileType;
|
||||
myMethodSeparators = separators != null ? separators.toArray(new LineMarkerInfo[separators.size()]) : new LineMarkerInfo[0];
|
||||
myCurrentMethodSeparator = 0;
|
||||
Date date = new Date();
|
||||
myPrintDate = new SimpleDateFormat(DATE_FORMAT).format(date);
|
||||
myPrintTime = new SimpleDateFormat(TIME_FORMAT).format(date);
|
||||
}
|
||||
|
||||
public void setSegment(int segmentStart, int segmentEnd) {
|
||||
setSegment(myDocument.createRangeMarker(segmentStart, segmentEnd));
|
||||
}
|
||||
|
||||
private void setSegment(RangeMarker marker) {
|
||||
if (myRangeToPrint != null) {
|
||||
myRangeToPrint.dispose();
|
||||
}
|
||||
myRangeToPrint = myDocument.createRangeMarker(segmentStart, segmentEnd);
|
||||
myRangeToPrint = marker;
|
||||
}
|
||||
|
||||
private float getLineHeight(Graphics g) {
|
||||
@@ -151,42 +178,104 @@ class TextPainter extends BasePainter {
|
||||
|
||||
@Override
|
||||
public int print(final Graphics g, final PageFormat pageFormat, final int pageIndex) throws PrinterException {
|
||||
if (myProgress.isCanceled()) {
|
||||
return NO_SUCH_PAGE;
|
||||
}
|
||||
|
||||
final Graphics2D g2d = (Graphics2D)g;
|
||||
|
||||
if (myNumberOfPages < 0) {
|
||||
myProgress.setText(CodeEditorBundle.message("print.file.calculating.number.of.pages.progress"));
|
||||
|
||||
myPerformActualDrawing = false;
|
||||
|
||||
if (!calculateNumberOfPages(g2d, pageFormat)) {
|
||||
return NO_SUCH_PAGE;
|
||||
}
|
||||
}
|
||||
|
||||
myPerformActualDrawing = true;
|
||||
|
||||
return ApplicationManager.getApplication().runReadAction(new Computable<Integer>() {
|
||||
@Override
|
||||
public Integer compute() {
|
||||
if (myProgress.isCanceled() || myRangeToPrint == null || !myRangeToPrint.isValid()) {
|
||||
if (!isValidRange(myRangeToPrint)) {
|
||||
return NO_SUCH_PAGE;
|
||||
}
|
||||
int startOffset = myRangeToPrint.getStartOffset();
|
||||
myOffset = startOffset;
|
||||
mySegmentEnd = myRangeToPrint.getEndOffset();
|
||||
myLineNumber = myDocument.getLineNumber(myOffset) + 1;
|
||||
|
||||
if (myOffset >= mySegmentEnd) {
|
||||
return NO_SUCH_PAGE;
|
||||
}
|
||||
isPrintingPass = !isPrintingPass;
|
||||
if (!isPrintingPass) {
|
||||
return PAGE_EXISTS;
|
||||
}
|
||||
|
||||
myProgress.setText(CodeEditorBundle.message("print.file.page.progress", myFileName, (pageIndex + 1)));
|
||||
myProgress.setText(CodeEditorBundle.message("print.file.page.progress", myShortFileName, (pageIndex + 1), myNumberOfPages));
|
||||
myPageIndex = pageIndex;
|
||||
Graphics2D g2D = (Graphics2D) g;
|
||||
Rectangle2D.Double clip = new Rectangle2D.Double(pageFormat.getImageableX(), pageFormat.getImageableY(),
|
||||
pageFormat.getImageableWidth(),
|
||||
pageFormat.getImageableHeight());
|
||||
|
||||
draw(g2D, clip);
|
||||
RangeMarker newRange = printPage(g2d, pageFormat, myRangeToPrint);
|
||||
setSegment(newRange);
|
||||
|
||||
myRangeToPrint.dispose();
|
||||
// stop printing if there was no progress (to avoid an infinite loop) or if the whole range was processed
|
||||
myRangeToPrint = myOffset > startOffset && myOffset < mySegmentEnd ? myDocument.createRangeMarker(myOffset, mySegmentEnd) : null;
|
||||
return PAGE_EXISTS;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private boolean calculateNumberOfPages(final Graphics2D g2d, final PageFormat pageFormat) {
|
||||
myNumberOfPages = 0;
|
||||
final Ref<Boolean> firstPage = new Ref<Boolean>(Boolean.TRUE);
|
||||
final Ref<RangeMarker> tmpMarker = new Ref<RangeMarker>();
|
||||
while (ApplicationManager.getApplication().runReadAction(new Computable<Boolean>() {
|
||||
@Override
|
||||
public Boolean compute() {
|
||||
if (firstPage.get()) {
|
||||
if (!isValidRange(myRangeToPrint)) {
|
||||
return false;
|
||||
}
|
||||
tmpMarker.set(myDocument.createRangeMarker(myRangeToPrint.getStartOffset(), myRangeToPrint.getEndOffset()));
|
||||
firstPage.set(Boolean.FALSE);
|
||||
}
|
||||
RangeMarker range = tmpMarker.get();
|
||||
if (!isValidRange(range)) {
|
||||
return false;
|
||||
}
|
||||
tmpMarker.set(printPage(g2d, pageFormat, range));
|
||||
range.dispose();
|
||||
return true;
|
||||
}
|
||||
})) {
|
||||
if (myProgress.isCanceled()) {
|
||||
return false;
|
||||
}
|
||||
myNumberOfPages++;
|
||||
}
|
||||
if (!tmpMarker.isNull()) {
|
||||
tmpMarker.get().dispose();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private static boolean isValidRange(RangeMarker range) {
|
||||
return range != null && range.isValid() && range.getStartOffset() < range.getEndOffset();
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints a pageful of text from a given range. Return a remaining range to print, or null if there's nothing left.
|
||||
*/
|
||||
private RangeMarker printPage(Graphics2D g2d, PageFormat pageFormat, RangeMarker range) {
|
||||
assert isValidRange(range);
|
||||
int startOffset = range.getStartOffset();
|
||||
int endOffset = range.getEndOffset();
|
||||
|
||||
myOffset = startOffset;
|
||||
mySegmentEnd = endOffset;
|
||||
myLineNumber = myDocument.getLineNumber(myOffset) + 1;
|
||||
Rectangle2D.Double clip = new Rectangle2D.Double(pageFormat.getImageableX(), pageFormat.getImageableY(),
|
||||
pageFormat.getImageableWidth(), pageFormat.getImageableHeight());
|
||||
|
||||
draw(g2d, clip);
|
||||
|
||||
return myOffset > startOffset && myOffset < endOffset ? myDocument.createRangeMarker(myOffset, endOffset) : null;
|
||||
}
|
||||
|
||||
private void draw(Graphics2D g2D, Rectangle2D.Double clip) {
|
||||
double headerHeight = drawHeader(g2D, clip);
|
||||
clip.y += headerHeight;
|
||||
@@ -209,7 +298,7 @@ class TextPainter extends BasePainter {
|
||||
}
|
||||
|
||||
private void drawBorder(Graphics2D g, Rectangle2D clip) {
|
||||
if (myPrintSettings.DRAW_BORDER) {
|
||||
if (myPrintSettings.DRAW_BORDER && myPerformActualDrawing) {
|
||||
Color save = g.getColor();
|
||||
g.setColor(Color.black);
|
||||
g.draw(clip);
|
||||
@@ -270,10 +359,8 @@ class TextPainter extends BasePainter {
|
||||
Point2D position = new Point2D.Double(0, clip.getY());
|
||||
double lineY = position.getY();
|
||||
|
||||
while (myCurrentMethodSeparator < myMethodSeparators.length) {
|
||||
LineMarkerInfo marker = myMethodSeparators[myCurrentMethodSeparator];
|
||||
if (marker != null && marker.startOffset >= lIterator.getEnd()) break;
|
||||
myCurrentMethodSeparator++;
|
||||
if (myPerformActualDrawing) {
|
||||
setInitialMethodSeparatorIndex(lIterator.getEnd());
|
||||
}
|
||||
|
||||
while (!hIterator.atEnd() && !lIterator.atEnd()) {
|
||||
@@ -290,14 +377,13 @@ class TextPainter extends BasePainter {
|
||||
lIterator.advance();
|
||||
myLineNumber++;
|
||||
|
||||
if (myCurrentMethodSeparator < myMethodSeparators.length) {
|
||||
LineMarkerInfo marker = myMethodSeparators[myCurrentMethodSeparator];
|
||||
if (marker != null && marker.startOffset < lEnd) {
|
||||
if (myPerformActualDrawing) {
|
||||
LineMarkerInfo marker = getMethodSeparator(lEnd);
|
||||
if (marker != null) {
|
||||
Color save = g.getColor();
|
||||
setForegroundColor(g, marker.separatorColor);
|
||||
UIUtil.drawLine(g, 0, (int)lineY, (int)clip.getWidth(), (int)lineY);
|
||||
setForegroundColor(g, save);
|
||||
myCurrentMethodSeparator++;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -343,6 +429,25 @@ class TextPainter extends BasePainter {
|
||||
|
||||
g.translate(-clip.getX(), 0);
|
||||
}
|
||||
|
||||
private void setInitialMethodSeparatorIndex(int initialOffset) {
|
||||
while (myCurrentMethodSeparator < myMethodSeparators.length) {
|
||||
LineMarkerInfo marker = myMethodSeparators[myCurrentMethodSeparator];
|
||||
if (marker != null && marker.startOffset >= initialOffset) break;
|
||||
myCurrentMethodSeparator++;
|
||||
}
|
||||
}
|
||||
|
||||
private LineMarkerInfo getMethodSeparator(int currentOffset) {
|
||||
if (myCurrentMethodSeparator < myMethodSeparators.length) {
|
||||
LineMarkerInfo marker = myMethodSeparators[myCurrentMethodSeparator];
|
||||
if (marker != null && marker.startOffset < currentOffset) {
|
||||
myCurrentMethodSeparator++;
|
||||
return marker;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private double drawHeader(Graphics2D g, Rectangle2D clip) {
|
||||
LineMetrics lineMetrics = getHeaderFooterLineMetrics(g);
|
||||
@@ -407,21 +512,23 @@ class TextPainter extends BasePainter {
|
||||
|
||||
private double drawHeaderOrFooterLine(Graphics2D g, double x, double y, double w, String headerText,
|
||||
String alignment) {
|
||||
headerText = convertHeaderText(headerText);
|
||||
g.setFont(myHeaderFont);
|
||||
g.setColor(Color.black);
|
||||
FontRenderContext fontRenderContext = g.getFontRenderContext();
|
||||
LineMetrics lineMetrics = getHeaderFooterLineMetrics(g);
|
||||
float lineHeight = lineMetrics.getHeight();
|
||||
float descent = lineMetrics.getDescent();
|
||||
double width = myHeaderFont.getStringBounds(headerText, fontRenderContext).getWidth() + getCharWidth(g);
|
||||
float yPos = (float) (lineHeight - descent + y);
|
||||
if (PrintSettings.LEFT.equals(alignment)) {
|
||||
drawStringToGraphics(g, headerText, x, yPos);
|
||||
} else if (PrintSettings.CENTER.equals(alignment)) {
|
||||
drawStringToGraphics(g, headerText, (float) (x + (w - width) / 2), yPos);
|
||||
} else if (PrintSettings.RIGHT.equals(alignment)) {
|
||||
drawStringToGraphics(g, headerText, (float) (x + w - width), yPos);
|
||||
if (myPerformActualDrawing) {
|
||||
headerText = convertHeaderText(headerText);
|
||||
g.setFont(myHeaderFont);
|
||||
g.setColor(Color.black);
|
||||
float descent = lineMetrics.getDescent();
|
||||
double width = myHeaderFont.getStringBounds(headerText, fontRenderContext).getWidth() + getCharWidth(g);
|
||||
float yPos = (float) (lineHeight - descent + y);
|
||||
if (PrintSettings.LEFT.equals(alignment)) {
|
||||
drawStringToGraphics(g, headerText, x, yPos);
|
||||
} else if (PrintSettings.CENTER.equals(alignment)) {
|
||||
drawStringToGraphics(g, headerText, (float) (x + (w - width) / 2), yPos);
|
||||
} else if (PrintSettings.RIGHT.equals(alignment)) {
|
||||
drawStringToGraphics(g, headerText, (float) (x + w - width), yPos);
|
||||
}
|
||||
}
|
||||
return lineHeight;
|
||||
}
|
||||
@@ -437,8 +544,16 @@ class TextPainter extends BasePainter {
|
||||
if (isExpression) {
|
||||
if (HEADER_TOKEN_PAGE.equals(token)) {
|
||||
result.append(myPageIndex + 1);
|
||||
} else if (HEADER_TOKEN_TOTALPAGES.equals(token)) {
|
||||
result.append(myNumberOfPages);
|
||||
} else if (HEADER_TOKEN_FILE.equals(token)) {
|
||||
result.append(myFileName);
|
||||
result.append(myFullFileName);
|
||||
} else if (HEADER_TOKEN_FILENAME.equals(token)) {
|
||||
result.append(myShortFileName);
|
||||
} else if (HEADER_TOKEN_DATE.equals(token)) {
|
||||
result.append(myPrintDate);
|
||||
} else if (HEADER_TOKEN_TIME.equals(token)) {
|
||||
result.append(myPrintTime);
|
||||
}
|
||||
} else {
|
||||
result.append(token);
|
||||
@@ -475,7 +590,7 @@ class TextPainter extends BasePainter {
|
||||
}
|
||||
|
||||
private void drawLineNumber(Graphics2D g, double x, double y) {
|
||||
if (!myPrintSettings.PRINT_LINE_NUMBERS) {
|
||||
if (!myPrintSettings.PRINT_LINE_NUMBERS || !myPerformActualDrawing) {
|
||||
return;
|
||||
}
|
||||
FontRenderContext fontRenderContext = (g).getFontRenderContext();
|
||||
@@ -538,7 +653,7 @@ class TextPainter extends BasePainter {
|
||||
double xStart = position.getX();
|
||||
double x = position.getX();
|
||||
double y = getLineHeight(g) - getDescent(g) + position.getY();
|
||||
if (backColor != null) {
|
||||
if (backColor != null && myPerformActualDrawing) {
|
||||
Color savedColor = g.getColor();
|
||||
setBackgroundColor(g, backColor);
|
||||
double w = getTextSegmentWidth(text, myOffset, length, position.getX(), g);
|
||||
@@ -567,7 +682,7 @@ class TextPainter extends BasePainter {
|
||||
x += drawStringToGraphics(g, s, x, y);
|
||||
}
|
||||
|
||||
if (underscoredColor != null) {
|
||||
if (underscoredColor != null && myPerformActualDrawing) {
|
||||
Color savedColor = g.getColor();
|
||||
setForegroundColor(g, underscoredColor);
|
||||
double w = getTextSegmentWidth(text, myOffset, length, position.getX(), g);
|
||||
@@ -581,13 +696,17 @@ class TextPainter extends BasePainter {
|
||||
|
||||
private double drawStringToGraphics(Graphics2D g, String s, double x, double y) {
|
||||
if (!myPrintSettings.PRINT_AS_GRAPHICS) {
|
||||
g.drawString(s, (float) x, (float) y);
|
||||
if (myPerformActualDrawing) {
|
||||
g.drawString(s, (float)x, (float)y);
|
||||
}
|
||||
return g.getFontMetrics().stringWidth(s);
|
||||
} else {
|
||||
GlyphVector v = g.getFont().createGlyphVector(g.getFontRenderContext(), s);
|
||||
g.translate(x, y);
|
||||
g.fill(v.getOutline());
|
||||
g.translate(-x, -y);
|
||||
if (myPerformActualDrawing) {
|
||||
g.translate(x, y);
|
||||
g.fill(v.getOutline());
|
||||
g.translate(-x, -y);
|
||||
}
|
||||
|
||||
return v.getLogicalBounds().getWidth();
|
||||
}
|
||||
@@ -635,9 +754,6 @@ class TextPainter extends BasePainter {
|
||||
|
||||
@Override
|
||||
void dispose() {
|
||||
if (myRangeToPrint != null) {
|
||||
myRangeToPrint.dispose();
|
||||
myRangeToPrint = null;
|
||||
}
|
||||
setSegment(null);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
package com.intellij.codeInsight.actions;
|
||||
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.application.ReadAction;
|
||||
import com.intellij.openapi.application.Result;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
@@ -27,6 +28,7 @@ import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.module.ModuleManager;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.roots.ModuleRootManager;
|
||||
import com.intellij.openapi.util.Key;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.openapi.vcs.VcsException;
|
||||
import com.intellij.openapi.vcs.changes.Change;
|
||||
@@ -52,8 +54,9 @@ import org.jetbrains.annotations.Nullable;
|
||||
import java.util.*;
|
||||
|
||||
public class FormatChangedTextUtil {
|
||||
public static final Key<String> TEST_REVISION_CONTENT = Key.create("test.revision.content");
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.actions.FormatChangedTextUtil");
|
||||
|
||||
|
||||
private FormatChangedTextUtil() {
|
||||
}
|
||||
|
||||
@@ -251,6 +254,13 @@ public class FormatChangedTextUtil {
|
||||
return cachedChangedLines;
|
||||
}
|
||||
|
||||
if (ApplicationManager.getApplication().isUnitTestMode()) {
|
||||
String testContent = file.getUserData(TEST_REVISION_CONTENT);
|
||||
if (testContent != null) {
|
||||
return calculateChangedTextRanges(file.getProject(), file, testContent);
|
||||
}
|
||||
}
|
||||
|
||||
Change change = ChangeListManager.getInstance(project).getChange(file.getVirtualFile());
|
||||
if (change == null) {
|
||||
return ContainerUtilRt.emptyList();
|
||||
|
||||
@@ -45,6 +45,11 @@ public class RearrangeCodeProcessor extends AbstractLayoutCodeProcessor {
|
||||
public RearrangeCodeProcessor(@NotNull AbstractLayoutCodeProcessor previousProcessor) {
|
||||
super(previousProcessor, COMMAND_NAME, PROGRESS_TEXT);
|
||||
}
|
||||
|
||||
public RearrangeCodeProcessor(@NotNull AbstractLayoutCodeProcessor previousProcessor, @NotNull SelectionModel selectionModel) {
|
||||
super(previousProcessor, COMMAND_NAME, PROGRESS_TEXT);
|
||||
mySelectionModel = selectionModel;
|
||||
}
|
||||
|
||||
public RearrangeCodeProcessor(@NotNull Project project,
|
||||
@NotNull PsiFile file,
|
||||
|
||||
@@ -192,8 +192,13 @@ public class ReformatCodeAction extends AnAction implements DumbAware {
|
||||
processor = new ReformatCodeProcessor(project, file, range, !processSelectedText && processChangedTextOnly);
|
||||
}
|
||||
|
||||
if (rearrangeEntries && editor != null) {
|
||||
processor = new RearrangeCodeProcessor(processor);
|
||||
if (rearrangeEntries) {
|
||||
if (processSelectedText && editor != null) {
|
||||
processor = new RearrangeCodeProcessor(processor, editor.getSelectionModel());
|
||||
}
|
||||
else {
|
||||
processor = new RearrangeCodeProcessor(processor);
|
||||
}
|
||||
}
|
||||
|
||||
processor.run();
|
||||
|
||||
@@ -325,12 +325,24 @@ public class SeverityEditorDialog extends DialogWrapper {
|
||||
final ListModel listModel = myOptionsList.getModel();
|
||||
final List<HighlightSeverity> order = new ArrayList<HighlightSeverity>();
|
||||
for (int i = listModel.getSize() - 1; i >= 0; i--) {
|
||||
final SeverityBasedTextAttributes info =
|
||||
(SeverityBasedTextAttributes)listModel.getElementAt(i);
|
||||
SeverityBasedTextAttributes info = (SeverityBasedTextAttributes)listModel.getElementAt(i);
|
||||
order.add(info.getSeverity());
|
||||
if (!mySeverityRegistrar.isDefaultSeverity(info.getSeverity())) {
|
||||
infoTypes.remove(info);
|
||||
final Color stripeColor = info.getAttributes().getErrorStripeColor();
|
||||
final boolean exists = mySeverityRegistrar.getSeverity(info.getSeverity().getName()) != null;
|
||||
if (exists) {
|
||||
info.getType().getAttributesKey().getDefaultAttributes().setErrorStripeColor(stripeColor);
|
||||
} else {
|
||||
HighlightInfoType.HighlightInfoTypeImpl type = info.getType();
|
||||
TextAttributesKey key = type.getAttributesKey();
|
||||
final TextAttributes defaultAttributes = key.getDefaultAttributes().clone();
|
||||
defaultAttributes.setErrorStripeColor(stripeColor);
|
||||
key = TextAttributesKey.createTextAttributesKey(key.getExternalName(), defaultAttributes);
|
||||
type = new HighlightInfoType.HighlightInfoTypeImpl(type.getSeverity(null), key);
|
||||
info = new SeverityBasedTextAttributes(info.getAttributes(), type);
|
||||
}
|
||||
|
||||
mySeverityRegistrar.registerSeverity(info, stripeColor != null ? stripeColor : LightColors.YELLOW);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -149,7 +149,7 @@ public class FileTemplateConfigurable implements Configurable, Configurable.NoSc
|
||||
|
||||
@Override
|
||||
public String getDisplayName() {
|
||||
return IdeBundle.message("title.file.templates");
|
||||
return IdeBundle.message("title.edit.file.template");
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -33,7 +33,6 @@ import com.intellij.openapi.fileTypes.ex.FileTypeManagerEx;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.project.ProjectManager;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import com.intellij.util.SystemProperties;
|
||||
import com.intellij.util.text.DateFormatUtil;
|
||||
@@ -118,9 +117,7 @@ public class FileTemplateManagerImpl extends FileTemplateManager implements Pers
|
||||
@NotNull
|
||||
@Override
|
||||
public String getTemplatesDir() {
|
||||
VirtualFile file = project.getProjectFile();
|
||||
assert file != null;
|
||||
return new File(file.getParent().getCanonicalPath(), TEMPLATES_DIR).getPath();
|
||||
return new File(project.getBasePath(), Project.DIRECTORY_STORE_FOLDER + "/" + TEMPLATES_DIR).getPath();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -17,7 +17,6 @@ package com.intellij.openapi.components.impl.stores;
|
||||
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.components.*;
|
||||
import com.intellij.openapi.components.impl.ComponentManagerImpl;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.module.ModuleTypeManager;
|
||||
@@ -47,8 +46,9 @@ public class ModuleStoreImpl extends BaseFileConfigurableStoreImpl implements IM
|
||||
private final ModuleImpl myModule;
|
||||
|
||||
@SuppressWarnings({"UnusedDeclaration"})
|
||||
public ModuleStoreImpl(@NotNull ComponentManagerImpl componentManager, @NotNull ModuleImpl module) {
|
||||
super(componentManager);
|
||||
public ModuleStoreImpl(@NotNull ModuleImpl module, @NotNull PathMacroManager pathMacroManager) {
|
||||
super(pathMacroManager);
|
||||
|
||||
myModule = module;
|
||||
}
|
||||
|
||||
@@ -252,6 +252,6 @@ public class ModuleStoreImpl extends BaseFileConfigurableStoreImpl implements IM
|
||||
@NotNull
|
||||
@Override
|
||||
protected StateStorageManager createStateStorageManager() {
|
||||
return new ModuleStateStorageManager(PathMacroManager.getInstance(getComponentManager()).createTrackingSubstitutor(), myModule);
|
||||
return new ModuleStateStorageManager(myPathMacroManager.createTrackingSubstitutor(), myModule);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
package com.intellij.openapi.components.impl.stores;
|
||||
|
||||
import com.intellij.openapi.components.PathMacroManager;
|
||||
import com.intellij.openapi.components.StateStorage;
|
||||
import com.intellij.openapi.components.StateStorage.SaveSession;
|
||||
import com.intellij.openapi.components.TrackingPathMacroSubstitutor;
|
||||
@@ -32,8 +33,8 @@ import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
public class ProjectWithModulesStoreImpl extends ProjectStoreImpl {
|
||||
public ProjectWithModulesStoreImpl(@NotNull ProjectImpl project) {
|
||||
super(project);
|
||||
public ProjectWithModulesStoreImpl(@NotNull ProjectImpl project, @NotNull PathMacroManager pathMacroManager) {
|
||||
super(project, pathMacroManager);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -69,14 +69,59 @@ public class ScreenUtil {
|
||||
}
|
||||
|
||||
public static Shape getAllScreensShape() {
|
||||
Rectangle[] rectangles = getAllScreenBounds();
|
||||
GraphicsDevice[] devices = GraphicsEnvironment.getLocalGraphicsEnvironment().getScreenDevices();
|
||||
if (devices.length == 0) {
|
||||
return new Rectangle();
|
||||
}
|
||||
if (devices.length == 1) {
|
||||
return getScreenRectangle(devices[0]);
|
||||
}
|
||||
Area area = new Area();
|
||||
for (Rectangle rectangle : rectangles) {
|
||||
area.add(new Area(rectangle));
|
||||
for (GraphicsDevice device : devices) {
|
||||
area.add(new Area(getScreenRectangle(device)));
|
||||
}
|
||||
return area;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the smallest rectangle that encloses a visible area of every screen.
|
||||
*
|
||||
* @return the smallest rectangle that encloses a visible area of every screen
|
||||
*/
|
||||
public static Rectangle getAllScreensRectangle() {
|
||||
GraphicsDevice[] devices = GraphicsEnvironment.getLocalGraphicsEnvironment().getScreenDevices();
|
||||
if (devices.length == 0) {
|
||||
return new Rectangle();
|
||||
}
|
||||
if (devices.length == 1) {
|
||||
return getScreenRectangle(devices[0]);
|
||||
}
|
||||
int minX = 0;
|
||||
int maxX = 0;
|
||||
int minY = 0;
|
||||
int maxY = 0;
|
||||
for (GraphicsDevice device : devices) {
|
||||
Rectangle rectangle = getScreenRectangle(device);
|
||||
int x = rectangle.x;
|
||||
if (minX > x) {
|
||||
minX = x;
|
||||
}
|
||||
x += rectangle.width;
|
||||
if (maxX < x) {
|
||||
maxX = x;
|
||||
}
|
||||
int y = rectangle.y;
|
||||
if (minY > y) {
|
||||
minY = y;
|
||||
}
|
||||
y += rectangle.height;
|
||||
if (maxY < y) {
|
||||
maxY = y;
|
||||
}
|
||||
}
|
||||
return new Rectangle(minX, minY, maxX - minX, maxY - minY);
|
||||
}
|
||||
|
||||
public static Rectangle getScreenRectangle(@NotNull Point p) {
|
||||
return getScreenRectangle(p.x, p.y);
|
||||
}
|
||||
|
||||
@@ -19,8 +19,10 @@ import com.intellij.ide.BrowserUtil;
|
||||
import com.intellij.openapi.application.Application;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.ui.GraphicsConfig;
|
||||
import com.intellij.openapi.util.SystemInfo;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.util.ui.GraphicsUtil;
|
||||
import com.intellij.util.ui.JBInsets;
|
||||
import com.intellij.util.ui.JBUI;
|
||||
import com.intellij.util.ui.UIUtil;
|
||||
@@ -37,6 +39,8 @@ import javax.swing.*;
|
||||
import javax.swing.border.Border;
|
||||
import javax.swing.tree.TreeCellRenderer;
|
||||
import java.awt.*;
|
||||
import java.awt.geom.GeneralPath;
|
||||
import java.awt.geom.PathIterator;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
@@ -682,13 +686,24 @@ public class SimpleColoredComponent extends JComponent implements Accessible, Co
|
||||
}
|
||||
// 2. Waved effect
|
||||
if (attributes.isWaved()) {
|
||||
if (attributes.getWaveColor() != null) {
|
||||
g.setColor(attributes.getWaveColor());
|
||||
}
|
||||
final int wavedAt = textBaseline + 1;
|
||||
for (int x = offset; x <= offset + fragmentWidth; x += 4) {
|
||||
UIUtil.drawLine(g, x, wavedAt, x + 2, wavedAt + 2);
|
||||
UIUtil.drawLine(g, x + 3, wavedAt + 1, x + 4, wavedAt);
|
||||
GraphicsConfig config = GraphicsUtil.setupAAPainting(g);
|
||||
Stroke oldStroke = g.getStroke();
|
||||
try {
|
||||
g.setStroke(new BasicStroke(.7F));
|
||||
if (attributes.getWaveColor() != null) {
|
||||
g.setColor(attributes.getWaveColor());
|
||||
}
|
||||
final int wavedAt = textBaseline + 1;
|
||||
GeneralPath wavePath = new GeneralPath(PathIterator.WIND_EVEN_ODD);
|
||||
wavePath.moveTo(offset, wavedAt);
|
||||
for (int x = offset; x <= offset + fragmentWidth; x += 4) {
|
||||
wavePath.lineTo(x + 2, wavedAt + 2);
|
||||
wavePath.lineTo(x + 4, wavedAt);
|
||||
}
|
||||
g.draw(wavePath);
|
||||
} finally {
|
||||
config.restore();
|
||||
g.setStroke(oldStroke);
|
||||
}
|
||||
}
|
||||
// 3. Underline
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
package com.intellij.ide.ui;
|
||||
|
||||
import com.intellij.ide.ui.search.BooleanOptionDescription;
|
||||
import com.intellij.openapi.editor.ex.EditorSettingsExternalizable;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.SystemInfo;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
@@ -37,7 +38,18 @@ public class EditorOptionsTopHitProvider extends OptionsTopHitProvider {
|
||||
? "checkbox.enable.ctrl.mousewheel.changes.font.size.macos"
|
||||
: "checkbox.enable.ctrl.mousewheel.changes.font.size"), "IS_WHEEL_FONTCHANGE_ENABLED"),
|
||||
editor("Mouse: " + messageApp("checkbox.enable.drag.n.drop.functionality.in.editor"), "IS_DND_ENABLED"),
|
||||
editor("Virtual Space: " + messageApp("checkbox.show.all.softwraps"), "IS_ALL_SOFTWRAPS_SHOWN"),
|
||||
new EditorOptionDescription(null, messageApp("checkbox.show.softwraps.only.for.caret.line.action.text"), "preferences.editor") {
|
||||
@Override
|
||||
public boolean isOptionEnabled() {
|
||||
return !EditorSettingsExternalizable.getInstance().isAllSoftWrapsShown();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setOptionState(boolean enabled) {
|
||||
EditorSettingsExternalizable.getInstance().setAllSoftwrapsShown(!enabled);
|
||||
fireUpdated();
|
||||
}
|
||||
},
|
||||
editor("Virtual Space: " + messageApp("checkbox.allow.placement.of.caret.after.end.of.line"), "IS_VIRTUAL_SPACE"),
|
||||
editor("Virtual Space: " + messageApp("checkbox.allow.placement.of.caret.inside.tabs"), "IS_CARET_INSIDE_TABS"),
|
||||
editor("Virtual Space: " + messageApp("checkbox.show.virtual.space.at.file.bottom"), "ADDITIONAL_PAGE_AT_BOTTOM"),
|
||||
|
||||
@@ -15,11 +15,12 @@
|
||||
*/
|
||||
package com.intellij.openapi.application.ex;
|
||||
|
||||
import com.intellij.openapi.components.impl.stores.DirectoryStorageData;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.util.io.URLUtil;
|
||||
import gnu.trove.THashMap;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.io.IOException;
|
||||
@@ -32,46 +33,33 @@ public class DecodeDefaultsUtil {
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.application.ex.DecodeDefaultsUtil");
|
||||
private static final Map<String, URL> RESOURCE_CACHE = Collections.synchronizedMap(new THashMap<String, URL>());
|
||||
|
||||
@NonNls private static final String XML_EXTENSION = ".xml";
|
||||
|
||||
public static URL getDefaults(Object requestor, final String componentResourcePath) {
|
||||
if (RESOURCE_CACHE.containsKey(componentResourcePath)) {
|
||||
return RESOURCE_CACHE.get(componentResourcePath);
|
||||
public static URL getDefaults(Object requestor, @NotNull String componentResourcePath) {
|
||||
URL url = RESOURCE_CACHE.get(componentResourcePath);
|
||||
if (url == null) {
|
||||
Class<?> requestorClass = requestor.getClass();
|
||||
if (StringUtil.startsWithChar(componentResourcePath, '/')) {
|
||||
url = requestorClass.getResource(componentResourcePath + DirectoryStorageData.DEFAULT_EXT);
|
||||
}
|
||||
else {
|
||||
url = requestorClass.getResource('/' + ApplicationManagerEx.getApplicationEx().getName() + '/' + componentResourcePath + DirectoryStorageData.DEFAULT_EXT);
|
||||
if (url == null) {
|
||||
url = requestorClass.getResource('/' + componentResourcePath + DirectoryStorageData.DEFAULT_EXT);
|
||||
}
|
||||
}
|
||||
RESOURCE_CACHE.put(componentResourcePath, url);
|
||||
}
|
||||
|
||||
URL url = getDefaultsImpl(requestor, componentResourcePath);
|
||||
RESOURCE_CACHE.put(componentResourcePath, url);
|
||||
return url;
|
||||
}
|
||||
|
||||
private static URL getDefaultsImpl(final Object requestor, final String componentResourcePath) {
|
||||
boolean isPathAbsolute = StringUtil.startsWithChar(componentResourcePath, '/');
|
||||
if (isPathAbsolute) {
|
||||
return requestor.getClass().getResource(componentResourcePath + XML_EXTENSION);
|
||||
}
|
||||
else {
|
||||
return getResourceByRelativePath(requestor, componentResourcePath, XML_EXTENSION);
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static InputStream getDefaultsInputStream(Object requestor, final String componentResourcePath) {
|
||||
public static InputStream getDefaultsInputStream(Object requestor, @NotNull String componentResourcePath) {
|
||||
try {
|
||||
final URL defaults = getDefaults(requestor, componentResourcePath);
|
||||
return defaults != null ? URLUtil.openStream(defaults) : null;
|
||||
return defaults == null ? null : URLUtil.openStream(defaults);
|
||||
}
|
||||
catch (IOException e) {
|
||||
LOG.error(e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private static URL getResourceByRelativePath(Object requestor, final String componentResourcePath, String resourceExtension) {
|
||||
String appName = ApplicationManagerEx.getApplicationEx().getName();
|
||||
URL result = requestor.getClass().getResource("/" + appName + "/" + componentResourcePath + resourceExtension);
|
||||
if (result == null) {
|
||||
result = requestor.getClass().getResource("/" + componentResourcePath + resourceExtension);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,7 +18,10 @@ package com.intellij.openapi.components.impl.stores;
|
||||
import com.intellij.application.options.PathMacrosImpl;
|
||||
import com.intellij.openapi.application.PathManager;
|
||||
import com.intellij.openapi.application.impl.ApplicationImpl;
|
||||
import com.intellij.openapi.components.*;
|
||||
import com.intellij.openapi.components.PathMacroManager;
|
||||
import com.intellij.openapi.components.StateStorageOperation;
|
||||
import com.intellij.openapi.components.StoragePathMacros;
|
||||
import com.intellij.openapi.components.TrackingPathMacroSubstitutor;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.util.NamedJDOMExternalizable;
|
||||
import com.intellij.openapi.vfs.LocalFileSystem;
|
||||
@@ -33,13 +36,11 @@ import java.io.IOException;
|
||||
class ApplicationStoreImpl extends ComponentStoreImpl implements IApplicationStore {
|
||||
private static final Logger LOG = Logger.getInstance(ApplicationStoreImpl.class);
|
||||
|
||||
private static final String XML_EXTENSION = ".xml";
|
||||
private static final String DEFAULT_STORAGE_SPEC = StoragePathMacros.APP_CONFIG + "/" + PathManager.DEFAULT_OPTIONS_FILE_NAME + XML_EXTENSION;
|
||||
private static final String DEFAULT_STORAGE_SPEC = StoragePathMacros.APP_CONFIG + "/" + PathManager.DEFAULT_OPTIONS_FILE_NAME + DirectoryStorageData.DEFAULT_EXT;
|
||||
private static final String ROOT_ELEMENT_NAME = "application";
|
||||
|
||||
private final ApplicationImpl myApplication;
|
||||
private final StateStorageManager myStateStorageManager;
|
||||
private final DefaultsStateStorage myDefaultsStateStorage;
|
||||
|
||||
private String myConfigPath;
|
||||
|
||||
@@ -59,7 +60,7 @@ class ApplicationStoreImpl extends ComponentStoreImpl implements IApplicationSto
|
||||
@Override
|
||||
protected String getOldStorageSpec(@NotNull Object component, @NotNull String componentName, @NotNull StateStorageOperation operation) {
|
||||
if (component instanceof NamedJDOMExternalizable) {
|
||||
return StoragePathMacros.APP_CONFIG + "/" + ((NamedJDOMExternalizable)component).getExternalFileName() + XML_EXTENSION;
|
||||
return StoragePathMacros.APP_CONFIG + '/' + ((NamedJDOMExternalizable)component).getExternalFileName() + DirectoryStorageData.DEFAULT_EXT;
|
||||
}
|
||||
else {
|
||||
return DEFAULT_STORAGE_SPEC;
|
||||
@@ -68,7 +69,7 @@ class ApplicationStoreImpl extends ComponentStoreImpl implements IApplicationSto
|
||||
|
||||
@Override
|
||||
protected TrackingPathMacroSubstitutor getMacroSubstitutor(@NotNull final String fileSpec) {
|
||||
if (fileSpec.equals(StoragePathMacros.APP_CONFIG + "/" + PathMacrosImpl.EXT_FILE_NAME + XML_EXTENSION)) return null;
|
||||
if (fileSpec.equals(StoragePathMacros.APP_CONFIG + '/' + PathMacrosImpl.EXT_FILE_NAME + DirectoryStorageData.DEFAULT_EXT)) return null;
|
||||
return super.getMacroSubstitutor(fileSpec);
|
||||
}
|
||||
|
||||
@@ -92,7 +93,6 @@ class ApplicationStoreImpl extends ComponentStoreImpl implements IApplicationSto
|
||||
}
|
||||
}
|
||||
};
|
||||
myDefaultsStateStorage = new DefaultsStateStorage(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -139,7 +139,7 @@ class ApplicationStoreImpl extends ComponentStoreImpl implements IApplicationSto
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
protected StateStorage getDefaultsStorage() {
|
||||
return myDefaultsStateStorage;
|
||||
protected PathMacroManager getPathMacroManagerForDefaults() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,7 +15,9 @@
|
||||
*/
|
||||
package com.intellij.openapi.components.impl.stores;
|
||||
|
||||
import com.intellij.openapi.components.*;
|
||||
import com.intellij.openapi.components.PathMacroManager;
|
||||
import com.intellij.openapi.components.PathMacroSubstitutor;
|
||||
import com.intellij.openapi.components.StateStorageException;
|
||||
import com.intellij.openapi.project.impl.ProjectManagerImpl;
|
||||
import com.intellij.util.SmartList;
|
||||
import org.jdom.Element;
|
||||
@@ -34,18 +36,11 @@ abstract class BaseFileConfigurableStoreImpl extends ComponentStoreImpl {
|
||||
|
||||
private static final List<String> ourConversionProblemsStorage = new SmartList<String>();
|
||||
|
||||
private final ComponentManager myComponentManager;
|
||||
private final DefaultsStateStorage myDefaultsStateStorage;
|
||||
private StateStorageManager myStateStorageManager;
|
||||
protected final PathMacroManager myPathMacroManager;
|
||||
|
||||
protected BaseFileConfigurableStoreImpl(@NotNull ComponentManager componentManager) {
|
||||
myComponentManager = componentManager;
|
||||
myDefaultsStateStorage = new DefaultsStateStorage(PathMacroManager.getInstance(myComponentManager));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public ComponentManager getComponentManager() {
|
||||
return myComponentManager;
|
||||
protected BaseFileConfigurableStoreImpl(@NotNull PathMacroManager pathMacroManager) {
|
||||
myPathMacroManager = pathMacroManager;
|
||||
}
|
||||
|
||||
protected static class BaseStorageData extends StorageData {
|
||||
@@ -115,10 +110,10 @@ abstract class BaseFileConfigurableStoreImpl extends ComponentStoreImpl {
|
||||
return (BaseStorageData)getMainStorage().getStorageData();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@NotNull
|
||||
@Override
|
||||
protected StateStorage getDefaultsStorage() {
|
||||
return myDefaultsStateStorage;
|
||||
protected final PathMacroManager getPathMacroManagerForDefaults() {
|
||||
return myPathMacroManager;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
package com.intellij.openapi.components.impl.stores;
|
||||
|
||||
import com.intellij.openapi.application.*;
|
||||
import com.intellij.openapi.application.ex.DecodeDefaultsUtil;
|
||||
import com.intellij.openapi.components.*;
|
||||
import com.intellij.openapi.components.StateStorage.SaveSession;
|
||||
import com.intellij.openapi.components.impl.ComponentManagerImpl;
|
||||
@@ -29,6 +30,7 @@ import com.intellij.openapi.project.ProjectBundle;
|
||||
import com.intellij.openapi.ui.Messages;
|
||||
import com.intellij.openapi.util.InvalidDataException;
|
||||
import com.intellij.openapi.util.JDOMExternalizable;
|
||||
import com.intellij.openapi.util.JDOMUtil;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.util.ArrayUtilRt;
|
||||
@@ -37,12 +39,16 @@ import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.containers.MultiMap;
|
||||
import com.intellij.util.containers.SmartHashSet;
|
||||
import com.intellij.util.messages.MessageBus;
|
||||
import com.intellij.util.xmlb.JDOMXIncluder;
|
||||
import gnu.trove.THashMap;
|
||||
import org.jdom.Element;
|
||||
import org.jdom.JDOMException;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Type;
|
||||
import java.net.URL;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
|
||||
@@ -52,9 +58,6 @@ public abstract class ComponentStoreImpl implements IComponentStore.Reloadable {
|
||||
private final Map<String, Object> myComponents = Collections.synchronizedMap(new THashMap<String, Object>());
|
||||
private final List<SettingsSavingComponent> mySettingsSavingComponents = new CopyOnWriteArrayList<SettingsSavingComponent>();
|
||||
|
||||
@Nullable
|
||||
protected abstract StateStorage getDefaultsStorage();
|
||||
|
||||
@Override
|
||||
public void initComponent(@NotNull Object component, boolean service) {
|
||||
if (component instanceof SettingsSavingComponent) {
|
||||
@@ -158,7 +161,7 @@ public abstract class ComponentStoreImpl implements IComponentStore.Reloadable {
|
||||
return;
|
||||
}
|
||||
|
||||
Element element = getJdomState(component, componentName, stateStorage);
|
||||
Element element = stateStorage.getState(component, componentName, Element.class, null);
|
||||
if (element == null) {
|
||||
return;
|
||||
}
|
||||
@@ -185,30 +188,18 @@ public abstract class ComponentStoreImpl implements IComponentStore.Reloadable {
|
||||
myComponents.put(componentName, component);
|
||||
}
|
||||
|
||||
private void loadJdomDefaults(@NotNull Object component, @NotNull String componentName) {
|
||||
private void loadJdomDefaults(@NotNull JDOMExternalizable component, @NotNull String componentName) {
|
||||
try {
|
||||
StateStorage defaultsStorage = getDefaultsStorage();
|
||||
if (defaultsStorage == null) {
|
||||
return;
|
||||
Element defaultState = getDefaultState(component, componentName, Element.class);
|
||||
if (defaultState != null) {
|
||||
component.readExternal(defaultState);
|
||||
}
|
||||
|
||||
Element defaultState = getJdomState(component, componentName, defaultsStorage);
|
||||
if (defaultState == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
((JDOMExternalizable)component).readExternal(defaultState);
|
||||
}
|
||||
catch (Exception e) {
|
||||
LOG.error("Cannot load defaults for " + component.getClass(), e);
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static Element getJdomState(final Object component, @NotNull String componentName, @NotNull StateStorage defaultsStorage) {
|
||||
return defaultsStorage.getState(component, componentName, Element.class, null);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
protected Project getProject() {
|
||||
return null;
|
||||
@@ -239,11 +230,7 @@ public abstract class ComponentStoreImpl implements IComponentStore.Reloadable {
|
||||
}
|
||||
|
||||
Class<T> stateClass = getComponentStateClass(component);
|
||||
T state = null;
|
||||
StateStorage defaultsStorage = getDefaultsStorage();
|
||||
if (defaultsStorage != null) {
|
||||
state = defaultsStorage.getState(component, name, stateClass, null);
|
||||
}
|
||||
T state = getDefaultState(component, name, stateClass);
|
||||
|
||||
Storage[] storageSpecs = getComponentStorageSpecs(component, stateSpec, StateStorageOperation.READ);
|
||||
for (Storage storageSpec : storageSpecs) {
|
||||
@@ -264,6 +251,34 @@ public abstract class ComponentStoreImpl implements IComponentStore.Reloadable {
|
||||
return name;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
protected abstract PathMacroManager getPathMacroManagerForDefaults();
|
||||
|
||||
@Nullable
|
||||
protected <T> T getDefaultState(@NotNull Object component, @NotNull String componentName, @NotNull final Class<T> stateClass) {
|
||||
URL url = DecodeDefaultsUtil.getDefaults(component, componentName);
|
||||
if (url == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
Element documentElement = JDOMXIncluder.resolve(JDOMUtil.loadDocument(url), url.toExternalForm()).detachRootElement();
|
||||
|
||||
PathMacroManager pathMacroManager = getPathMacroManagerForDefaults();
|
||||
if (pathMacroManager != null) {
|
||||
pathMacroManager.expandPaths(documentElement);
|
||||
}
|
||||
|
||||
return DefaultStateSerializer.deserializeState(documentElement, stateClass, null);
|
||||
}
|
||||
catch (IOException e) {
|
||||
throw new StateStorageException("Error loading state from " + url, e);
|
||||
}
|
||||
catch (JDOMException e) {
|
||||
throw new StateStorageException("Error loading state from " + url, e);
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static <T> Class<T> getComponentStateClass(@NotNull final PersistentStateComponent<T> persistentStateComponent) {
|
||||
final Class persistentStateComponentClass = PersistentStateComponent.class;
|
||||
|
||||
@@ -31,17 +31,14 @@ import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
//todo: extends from base store class
|
||||
public class DefaultProjectStoreImpl extends ProjectStoreImpl {
|
||||
@Nullable private final Element myElement;
|
||||
private final ProjectManagerImpl myProjectManager;
|
||||
@NonNls private static final String ROOT_TAG_NAME = "defaultProject";
|
||||
|
||||
public DefaultProjectStoreImpl(@NotNull ProjectImpl project, @NotNull ProjectManagerImpl projectManager) {
|
||||
super(project);
|
||||
public DefaultProjectStoreImpl(@NotNull ProjectImpl project, @NotNull ProjectManagerImpl projectManager, @NotNull PathMacroManager pathMacroManager) {
|
||||
super(project, pathMacroManager);
|
||||
|
||||
myProjectManager = projectManager;
|
||||
myElement = projectManager.getDefaultProjectRootElement();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@@ -53,21 +50,12 @@ public class DefaultProjectStoreImpl extends ProjectStoreImpl {
|
||||
@NotNull
|
||||
@Override
|
||||
protected StateStorageManager createStateStorageManager() {
|
||||
Element _d = null;
|
||||
|
||||
if (myElement != null) {
|
||||
myElement.detach();
|
||||
_d = myElement;
|
||||
}
|
||||
|
||||
ComponentManager componentManager = getComponentManager();
|
||||
final Element element = _d;
|
||||
final XmlElementStorage storage = new XmlElementStorage("", RoamingType.DISABLED, PathMacroManager.getInstance(componentManager).createTrackingSubstitutor(),
|
||||
final XmlElementStorage storage = new XmlElementStorage("", RoamingType.DISABLED, myPathMacroManager.createTrackingSubstitutor(),
|
||||
ROOT_TAG_NAME, null) {
|
||||
@Override
|
||||
@Nullable
|
||||
protected Element loadLocalData() {
|
||||
return element;
|
||||
return myProjectManager.getDefaultProjectRootElement();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -176,9 +164,10 @@ public class DefaultProjectStoreImpl extends ProjectStoreImpl {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void load() throws IOException, StateStorageException {
|
||||
if (myElement == null) return;
|
||||
super.load();
|
||||
public void load() throws IOException {
|
||||
if (myProjectManager.getDefaultProjectRootElement() != null) {
|
||||
super.load();
|
||||
}
|
||||
}
|
||||
|
||||
private static class MyExternalizationSession implements StateStorageManager.ExternalizationSession {
|
||||
|
||||
@@ -1,89 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2014 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.components.impl.stores;
|
||||
|
||||
import com.intellij.openapi.application.ex.DecodeDefaultsUtil;
|
||||
import com.intellij.openapi.components.PathMacroManager;
|
||||
import com.intellij.openapi.components.StateStorage;
|
||||
import com.intellij.openapi.components.StateStorageException;
|
||||
import com.intellij.openapi.util.JDOMUtil;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.util.xmlb.JDOMXIncluder;
|
||||
import org.jdom.Document;
|
||||
import org.jdom.Element;
|
||||
import org.jdom.JDOMException;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import java.util.Collection;
|
||||
import java.util.Set;
|
||||
|
||||
class DefaultsStateStorage implements StateStorage {
|
||||
private final PathMacroManager myPathMacroManager;
|
||||
|
||||
public DefaultsStateStorage(@Nullable final PathMacroManager pathMacroManager) {
|
||||
myPathMacroManager = pathMacroManager;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private Element getState(final Object component, final String componentName) throws StateStorageException {
|
||||
final URL url = DecodeDefaultsUtil.getDefaults(component, componentName);
|
||||
if (url == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
Document document = JDOMUtil.loadDocument(url);
|
||||
document = JDOMXIncluder.resolve(document, url.toExternalForm());
|
||||
final Element documentElement = document.detachRootElement();
|
||||
|
||||
if (myPathMacroManager != null) {
|
||||
myPathMacroManager.expandPaths(documentElement);
|
||||
}
|
||||
|
||||
return documentElement;
|
||||
}
|
||||
catch (IOException e) {
|
||||
throw new StateStorageException("Error loading state from " + url, e);
|
||||
}
|
||||
catch (JDOMException e) {
|
||||
throw new StateStorageException("Error loading state from " + url, e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public <T> T getState(final Object component, @NotNull final String componentName, @NotNull final Class<T> stateClass, @Nullable final T mergeInto) {
|
||||
return DefaultStateSerializer.deserializeState(getState(component, componentName), stateClass, mergeInto);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasState(@Nullable final Object component, @NotNull final String componentName, final Class<?> aClass, final boolean reloadData) {
|
||||
return DecodeDefaultsUtil.getDefaults(component, componentName) != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public ExternalizationSession startExternalization() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void analyzeExternalChangesAndUpdateIfNeed(@NotNull Collection<VirtualFile> changedFiles, @NotNull Set<String> result) {
|
||||
}
|
||||
}
|
||||
@@ -63,8 +63,8 @@ class ProjectStoreImpl extends BaseFileConfigurableStoreImpl implements IProject
|
||||
private StorageScheme myScheme = StorageScheme.DEFAULT;
|
||||
private String myPresentableUrl;
|
||||
|
||||
ProjectStoreImpl(@NotNull ProjectImpl project) {
|
||||
super(project);
|
||||
ProjectStoreImpl(@NotNull ProjectImpl project, @NotNull PathMacroManager pathMacroManager) {
|
||||
super(pathMacroManager);
|
||||
|
||||
myProject = project;
|
||||
}
|
||||
@@ -359,16 +359,12 @@ class ProjectStoreImpl extends BaseFileConfigurableStoreImpl implements IProject
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadProjectFromTemplate(@NotNull final ProjectImpl defaultProject) {
|
||||
XmlElementStorage stateStorage = getProjectFileStorage();
|
||||
|
||||
public void loadProjectFromTemplate(@NotNull ProjectImpl defaultProject) {
|
||||
defaultProject.save();
|
||||
final IProjectStore projectStore = defaultProject.getStateStore();
|
||||
assert projectStore instanceof DefaultProjectStoreImpl;
|
||||
DefaultProjectStoreImpl defaultProjectStore = (DefaultProjectStoreImpl)projectStore;
|
||||
final Element element = defaultProjectStore.getStateCopy();
|
||||
|
||||
Element element = ((DefaultProjectStoreImpl)defaultProject.getStateStore()).getStateCopy();
|
||||
if (element != null) {
|
||||
stateStorage.setDefaultState(element);
|
||||
getProjectFileStorage().setDefaultState(element);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -387,7 +383,7 @@ class ProjectStoreImpl extends BaseFileConfigurableStoreImpl implements IProject
|
||||
@NotNull
|
||||
@Override
|
||||
protected StateStorageManager createStateStorageManager() {
|
||||
return new ProjectStateStorageManager(PathMacroManager.getInstance(getComponentManager()).createTrackingSubstitutor(), myProject);
|
||||
return new ProjectStateStorageManager(myPathMacroManager.createTrackingSubstitutor(), myProject);
|
||||
}
|
||||
|
||||
static class ProjectStorageData extends BaseStorageData {
|
||||
|
||||
@@ -155,25 +155,36 @@ public class FragmentBoundRenderer implements LineMarkerRenderer, LineSeparatorR
|
||||
final boolean mirrorX, final int mirrorSize) {
|
||||
final Iterator<Couple<Integer>> iterator = points.iterator();
|
||||
assert iterator.hasNext();
|
||||
final Convertor<Integer, Integer> c = new Convertor<Integer, Integer>() {
|
||||
@Override
|
||||
public Integer convert(Integer o) {
|
||||
final int val = x1 + o - subtractX;
|
||||
if (mirrorX) {
|
||||
return mirrorSize - val;
|
||||
}
|
||||
return val;
|
||||
}
|
||||
};
|
||||
|
||||
int[] xPoints = new int[points.size()];
|
||||
int[] yPoints1 = new int[points.size()];
|
||||
int[] yPoints2 = new int[points.size()];
|
||||
int n = 0;
|
||||
|
||||
Couple<Integer> previous = iterator.next();
|
||||
while (iterator.hasNext()) {
|
||||
final Couple<Integer> next = iterator.next();
|
||||
UIUtil.drawLine(g, c.convert(previous.getFirst()), y + offset + previous.getSecond() - myLineHeight/2, c.convert(next.getFirst()),
|
||||
y + offset + next.getSecond() - myLineHeight/2);
|
||||
UIUtil.drawLine(g, c.convert(previous.getFirst()), y - offset + previous.getSecond() - myLineHeight/2, c.convert(next.getFirst()),
|
||||
y - offset + next.getSecond() - myLineHeight/2);
|
||||
|
||||
xPoints[n] = convert(previous.getFirst(), x1, subtractX, mirrorX, mirrorSize);
|
||||
yPoints1[n] = y + offset + previous.getSecond() - myLineHeight / 2;
|
||||
yPoints2[n] = y - offset + previous.getSecond() - myLineHeight / 2;
|
||||
n++;
|
||||
previous = next;
|
||||
}
|
||||
xPoints[n] = convert(previous.getFirst(), x1, subtractX, mirrorX, mirrorSize);
|
||||
yPoints1[n] = y + offset + previous.getSecond() - myLineHeight / 2;
|
||||
yPoints2[n] = y - offset + previous.getSecond() - myLineHeight / 2;
|
||||
|
||||
g.drawPolyline(xPoints, yPoints1, points.size());
|
||||
g.drawPolyline(xPoints, yPoints2, points.size());
|
||||
}
|
||||
|
||||
private static int convert(int value, int x1, int subtractX, boolean mirrorX, int mirrorSize) {
|
||||
final int val = x1 + value - subtractX;
|
||||
if (mirrorX) {
|
||||
return mirrorSize - val;
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
private static class ShoeneLine {
|
||||
|
||||
@@ -94,6 +94,7 @@ public class ProjectManagerImpl extends ProjectManagerEx implements PersistentSt
|
||||
private ProjectImpl myDefaultProject; // Only used asynchronously in save and dispose, which itself are synchronized.
|
||||
@SuppressWarnings({"FieldAccessedSynchronizedAndUnsynchronized"})
|
||||
private Element myDefaultProjectRootElement; // Only used asynchronously in save and dispose, which itself are synchronized.
|
||||
private boolean myDefaultProjectConfigurationChanged;
|
||||
|
||||
private final List<Project> myOpenProjects = new ArrayList<Project>();
|
||||
private Project[] myOpenProjectsArrayCache = {};
|
||||
@@ -257,6 +258,18 @@ public class ProjectManagerImpl extends ProjectManagerEx implements PersistentSt
|
||||
}
|
||||
}
|
||||
|
||||
File projectFile = new File(filePath);
|
||||
if (projectFile.isFile()) {
|
||||
FileUtil.delete(projectFile);
|
||||
}
|
||||
else {
|
||||
File[] files = new File(projectFile, Project.DIRECTORY_STORE_FOLDER).listFiles();
|
||||
if (files != null) {
|
||||
for (File file : files) {
|
||||
FileUtil.delete(file);
|
||||
}
|
||||
}
|
||||
}
|
||||
ProjectImpl project = createProject(projectName, filePath, false, optimiseTestLoadSpeed);
|
||||
try {
|
||||
initProject(project, useDefaultProjectSettings ? (ProjectImpl)getDefaultProject() : null);
|
||||
@@ -387,7 +400,6 @@ public class ProjectManagerImpl extends ProjectManagerEx implements PersistentSt
|
||||
try {
|
||||
myDefaultProject = createProject(null, "", true, ApplicationManager.getApplication().isUnitTestMode());
|
||||
initProject(myDefaultProject, null);
|
||||
myDefaultProjectRootElement = null;
|
||||
}
|
||||
catch (Throwable t) {
|
||||
PluginManager.processException(t);
|
||||
@@ -990,7 +1002,7 @@ public class ProjectManagerImpl extends ProjectManagerEx implements PersistentSt
|
||||
myDefaultProject.save();
|
||||
}
|
||||
|
||||
if (myDefaultProjectRootElement == null) {
|
||||
if (!myDefaultProjectConfigurationChanged) {
|
||||
// we are not ready to save
|
||||
return null;
|
||||
}
|
||||
@@ -1007,10 +1019,12 @@ public class ProjectManagerImpl extends ProjectManagerEx implements PersistentSt
|
||||
if (myDefaultProjectRootElement != null) {
|
||||
myDefaultProjectRootElement.detach();
|
||||
}
|
||||
myDefaultProjectConfigurationChanged = false;
|
||||
}
|
||||
|
||||
public void setDefaultProjectRootElement(@NotNull Element defaultProjectRootElement) {
|
||||
myDefaultProjectRootElement = defaultProjectRootElement;
|
||||
myDefaultProjectConfigurationChanged = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -225,7 +225,7 @@ public final class WindowManagerImpl extends WindowManagerEx implements NamedCom
|
||||
|
||||
@Override
|
||||
public final Rectangle getScreenBounds() {
|
||||
return ScreenUtil.getAllScreensShape().getBounds();
|
||||
return ScreenUtil.getAllScreensRectangle();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -109,9 +109,11 @@ public class NewRecentProjectPanel extends RecentProjectPanel {
|
||||
|
||||
closeButtonCell.gridx = 1;
|
||||
closeButtonCell.gridy = 0;
|
||||
closeButtonCell.anchor = GridBagConstraints.FIRST_LINE_END;
|
||||
closeButtonCell.insets = new Insets(7, 7, 7, 7);
|
||||
closeButtonCell.gridheight = 2;
|
||||
|
||||
closeButtonCell.anchor = GridBagConstraints.WEST;
|
||||
//closeButtonCell.anchor = GridBagConstraints.WEST;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -47,7 +47,6 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.border.EmptyBorder;
|
||||
import javax.swing.border.LineBorder;
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
@@ -58,19 +57,38 @@ public class RecentProjectPanel extends JPanel {
|
||||
protected final UniqueNameBuilder<ReopenProjectAction> myPathShortener;
|
||||
protected AnAction removeRecentProjectAction;
|
||||
private int myHoverIndex = -1;
|
||||
private static final int closeButtonInset = 7;
|
||||
private Icon currentIcon = AllIcons.Welcome.RemoveRecentProject;
|
||||
|
||||
private final JPanel myCloseButtonForEditor = new JPanel() {
|
||||
{
|
||||
setPreferredSize(new Dimension(AllIcons.General.BalloonClose.getIconWidth(), AllIcons.General.BalloonClose.getIconHeight()));
|
||||
setPreferredSize(new Dimension(currentIcon.getIconWidth(), currentIcon.getIconHeight()));
|
||||
setOpaque(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void paintComponent(Graphics g) {
|
||||
AllIcons.General.BalloonClose.paintIcon(this, g, 0, 0);
|
||||
currentIcon.paintIcon(this, g, 0, 0);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
private boolean rectInListCoordinatesContains(Rectangle listCellBounds, Point p) {
|
||||
|
||||
int realCloseButtonInset = (UIUtil.isRetina(myList.getGraphicsConfiguration().getDevice())) ?
|
||||
closeButtonInset * 2 : closeButtonInset;
|
||||
|
||||
Rectangle closeButtonRect = new Rectangle(myCloseButtonForEditor.getX() - realCloseButtonInset,
|
||||
myCloseButtonForEditor.getY() - realCloseButtonInset,
|
||||
myCloseButtonForEditor.getWidth() + realCloseButtonInset * 2,
|
||||
myCloseButtonForEditor.getHeight() + realCloseButtonInset * 2);
|
||||
|
||||
Rectangle rectInListCoordinates = new Rectangle(new Point(closeButtonRect.x + listCellBounds.x,
|
||||
closeButtonRect.y + listCellBounds.y),
|
||||
closeButtonRect.getSize());
|
||||
return rectInListCoordinates.contains(p);
|
||||
}
|
||||
|
||||
public RecentProjectPanel(WelcomeScreen screen) {
|
||||
super(new BorderLayout());
|
||||
|
||||
@@ -93,12 +111,7 @@ public class RecentProjectPanel extends JPanel {
|
||||
Rectangle cellBounds = myList.getCellBounds(selectedIndex, selectedIndex);
|
||||
if (cellBounds.contains(event.getPoint())) {
|
||||
Object selection = myList.getSelectedValue();
|
||||
|
||||
Rectangle closeButtonRect = myCloseButtonForEditor.getBounds();
|
||||
|
||||
Rectangle rectInListCoordinates = new Rectangle(new Point(closeButtonRect.x + cellBounds.x, closeButtonRect.y + cellBounds.y), closeButtonRect.getSize());
|
||||
|
||||
if (Registry.is("removable.welcome.screen.projects") && rectInListCoordinates.contains(event.getPoint())) {
|
||||
if (Registry.is("removable.welcome.screen.projects") && rectInListCoordinatesContains(cellBounds, event.getPoint())) {
|
||||
removeRecentProjectAction.actionPerformed(null);
|
||||
} else if (selection != null) {
|
||||
((AnAction)selection).actionPerformed(
|
||||
@@ -203,11 +216,16 @@ public class RecentProjectPanel extends JPanel {
|
||||
int index = myList.locationToIndex(point);
|
||||
myList.setSelectedIndex(index);
|
||||
|
||||
final Rectangle bounds = myList.getCellBounds(index, index);
|
||||
if (bounds != null && bounds.contains(point)) {
|
||||
final Rectangle cellBounds = myList.getCellBounds(index, index);
|
||||
if (cellBounds != null && cellBounds.contains(point)) {
|
||||
myList.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
|
||||
if (rectInListCoordinatesContains(cellBounds, point)) {
|
||||
currentIcon = AllIcons.Welcome.RemoveRecentProjectHover;
|
||||
} else {
|
||||
currentIcon = AllIcons.Welcome.RemoveRecentProject;
|
||||
}
|
||||
myHoverIndex = index;
|
||||
myList.repaint(bounds);
|
||||
myList.repaint(cellBounds);
|
||||
}
|
||||
else {
|
||||
myList.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
|
||||
@@ -223,6 +241,7 @@ public class RecentProjectPanel extends JPanel {
|
||||
@Override
|
||||
public void mouseExited(MouseEvent e) {
|
||||
myHoverIndex = -1;
|
||||
currentIcon = AllIcons.Welcome.RemoveRecentProject;
|
||||
myList.repaint();
|
||||
}
|
||||
};
|
||||
@@ -261,7 +280,7 @@ public class RecentProjectPanel extends JPanel {
|
||||
private static class MyList extends JBList {
|
||||
private final Dimension mySize;
|
||||
|
||||
private MyList(Dimension size, @NotNull Object... listData) {
|
||||
private MyList(Dimension size, @NotNull Object ... listData) {
|
||||
super(listData);
|
||||
mySize = size;
|
||||
setEmptyText(" No Project Open Yet ");
|
||||
|
||||
@@ -301,10 +301,18 @@ public abstract class AbstractExpandableItemsHandler<KeyType, ComponentType exte
|
||||
hideHint();
|
||||
}
|
||||
else if (myPopup == null) {
|
||||
showHint(location);
|
||||
myPopup = new OurHeavyWeightPopup(myComponent, myTipComponent, location.x, location.y);
|
||||
Window popupWindow = SwingUtilities.getWindowAncestor(myTipComponent);
|
||||
WindowManagerEx.getInstanceEx().setWindowShadow(popupWindow, WindowManagerEx.WindowShadowMode.DISABLED);
|
||||
myPopup.show();
|
||||
repaintKeyItem();
|
||||
}
|
||||
else {
|
||||
repaintHint(location);
|
||||
Dimension size = myTipComponent.getPreferredSize();
|
||||
Window popupWindow = SwingUtilities.getWindowAncestor(myTipComponent);
|
||||
popupWindow.setBounds(location.x, location.y, size.width, size.height);
|
||||
myTipComponent.repaint();
|
||||
repaintKeyItem();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -339,31 +347,6 @@ public abstract class AbstractExpandableItemsHandler<KeyType, ComponentType exte
|
||||
return myPopup != null;
|
||||
}
|
||||
|
||||
private void showHint(Point location) {
|
||||
assert myPopup == null;
|
||||
|
||||
if (!myComponent.isShowing()) {
|
||||
return;
|
||||
}
|
||||
|
||||
SwingUtilities.convertPointToScreen(location, myComponent);
|
||||
myPopup = new OurHeavyWeightPopup(myComponent, myTipComponent, location.x, location.y);
|
||||
WindowManagerEx.getInstanceEx().setWindowShadow(SwingUtilities.getWindowAncestor(myTipComponent),
|
||||
WindowManagerEx.WindowShadowMode.DISABLED);
|
||||
myPopup.show();
|
||||
|
||||
repaintKeyItem();
|
||||
}
|
||||
|
||||
private void repaintHint(Point location) {
|
||||
if (myPopup != null && myKey != null && myComponent.isShowing()) {
|
||||
SwingUtilities.convertPointToScreen(location, myComponent);
|
||||
SwingUtilities.getWindowAncestor(myTipComponent).setBounds(new Rectangle(location, myTipComponent.getPreferredSize()));
|
||||
myTipComponent.repaint();
|
||||
repaintKeyItem();
|
||||
}
|
||||
}
|
||||
|
||||
private void repaintKeyItem() {
|
||||
if (myKeyItemBounds != null) {
|
||||
myComponent.repaint(myKeyItemBounds);
|
||||
@@ -380,20 +363,30 @@ public abstract class AbstractExpandableItemsHandler<KeyType, ComponentType exte
|
||||
|
||||
myKeyItemBounds = rendererAndBounds.second;
|
||||
|
||||
Point toolTipLocationOnScreen = myKeyItemBounds.getLocation();
|
||||
SwingUtilities.convertPointToScreen(toolTipLocationOnScreen, myComponent);
|
||||
int maximumWidth = Math.max(0, myComponent.getToolkit().getScreenSize().width - toolTipLocationOnScreen.x);
|
||||
myKeyItemBounds.width = Math.min(myKeyItemBounds.width, maximumWidth);
|
||||
|
||||
Rectangle cellBounds = myKeyItemBounds;
|
||||
Rectangle visibleRect = getVisibleRect(key);
|
||||
|
||||
int width = cellBounds.x + cellBounds.width - (visibleRect.x + visibleRect.width);
|
||||
if (cellBounds.y < visibleRect.y) return null;
|
||||
|
||||
int cellMaxY = cellBounds.y + cellBounds.height;
|
||||
int visMaxY = visibleRect.y + visibleRect.height;
|
||||
if (cellMaxY > visMaxY) return null;
|
||||
|
||||
int cellMaxX = cellBounds.x + cellBounds.width;
|
||||
int visMaxX = visibleRect.x + visibleRect.width;
|
||||
|
||||
Point location = new Point(visMaxX, cellBounds.y);
|
||||
SwingUtilities.convertPointToScreen(location, myComponent);
|
||||
|
||||
Rectangle screen = !Registry.is("ide.expansion.hints.on.all.screens")
|
||||
? ScreenUtil.getScreenRectangle(location)
|
||||
: ScreenUtil.getAllScreensRectangle();
|
||||
|
||||
int borderWidth = isPaintBorder() ? 1 : 0;
|
||||
int width = Math.min(screen.width + screen.x - location.x - borderWidth, cellMaxX - visMaxX);
|
||||
int height = cellBounds.height;
|
||||
|
||||
if (width <= 0 || height <= 0) return null;
|
||||
if (cellBounds.y < visibleRect.y) return null;
|
||||
if (cellBounds.y + cellBounds.height > visibleRect.y + visibleRect.height) return null;
|
||||
|
||||
Dimension size = getImageSize(width, height);
|
||||
myImage = UIUtil.createImage(size.width, size.height, BufferedImage.TYPE_INT_RGB);
|
||||
@@ -401,16 +394,15 @@ public abstract class AbstractExpandableItemsHandler<KeyType, ComponentType exte
|
||||
Graphics2D g = myImage.createGraphics();
|
||||
g.setClip(null);
|
||||
doFillBackground(height, width, g);
|
||||
g.translate(-(visibleRect.x + visibleRect.width - cellBounds.x), 0);
|
||||
g.translate(cellBounds.x - visMaxX, 0);
|
||||
doPaintTooltipImage(renderer, cellBounds, g, key);
|
||||
|
||||
Point location = new Point(visibleRect.x + visibleRect.width, cellBounds.y);
|
||||
CustomLineBorder border = null;
|
||||
if (isPaintBorder()) {
|
||||
border = new CustomLineBorder(getBorderColor(), 1, 0, 1, 1);
|
||||
location.y -= 1;
|
||||
size.width += 1;
|
||||
size.height += 2;
|
||||
if (borderWidth > 0) {
|
||||
border = new CustomLineBorder(getBorderColor(), borderWidth, 0, borderWidth, borderWidth);
|
||||
location.y -= borderWidth;
|
||||
size.width += borderWidth;
|
||||
size.height += borderWidth + borderWidth;
|
||||
}
|
||||
|
||||
g.dispose();
|
||||
|
||||
@@ -483,7 +483,7 @@ public abstract class JBListTable {
|
||||
* @return whether this row animation is complete
|
||||
*/
|
||||
public boolean doAnimationStep(long currentTime) {
|
||||
if (myTable.getRowCount() >= myRow) return true;
|
||||
if (myRow >= myTable.getRowCount()) return true;
|
||||
|
||||
int currentRowHeight = myTable.getRowHeight(myRow);
|
||||
int resizeAbs = (int) (RESIZE_AMOUNT_PER_STEP * ((currentTime - myLastUpdateTime) / (double)ANIMATION_STEP_MILLIS));
|
||||
|
||||
@@ -390,7 +390,8 @@ group.soft.wraps=Soft Wraps
|
||||
checkbox.use.soft.wraps.at.editor=Use soft wraps in editor
|
||||
checkbox.use.soft.wraps.at.console=Use soft wraps in console
|
||||
checkbox.use.custom.soft.wraps.indent=Use original line's indent for wrapped parts. Additional shift:
|
||||
checkbox.show.softwraps.only.for.caret.line=Show soft wrap symbols only for current line
|
||||
checkbox.show.softwraps.only.for.caret.line=Show soft wraps for current line only
|
||||
checkbox.show.softwraps.only.for.caret.line.action.text=Soft Wraps: Show for current line only
|
||||
group.virtual.space=Virtual Space
|
||||
checkbox.allow.placement.of.caret.after.end.of.line=Allow placement of caret after end of line
|
||||
checkbox.allow.placement.of.caret.inside.tabs=Allow placement of caret inside tabs
|
||||
|
||||
@@ -52,11 +52,12 @@ print.header.alignment.combobox=Alignment
|
||||
print.apply.button=A&pply
|
||||
print.progress=Printing...
|
||||
print.header.default.line.1=File - $FILE$
|
||||
print.header.default.line.2=Page $PAGE$
|
||||
print.header.default.line.2=Page $PAGE$ of $TOTALPAGES$
|
||||
print.header.placement.header=Header
|
||||
print.header.placement.footer=Footer
|
||||
print.header.alignment.left=Left
|
||||
print.header.alignment.center=Center
|
||||
print.header.alignment.right=Right
|
||||
print.file.page.progress=Printing {0}. Page {1}...
|
||||
print.file.calculating.number.of.pages.progress=Calculating number of pages...
|
||||
print.file.page.progress=Printing {0}. Page {1} of {2}
|
||||
file.not.found=File not found: {0}
|
||||
|
||||
@@ -131,6 +131,7 @@ title.select.template=Select Template
|
||||
label.name=Name:
|
||||
label.extension=Extension:
|
||||
title.file.templates=File and Code Templates
|
||||
title.edit.file.template=Edit File Template
|
||||
checkbox.reformat.according.to.style=Reformat according to style
|
||||
label.description=Description
|
||||
item.file.templates=File templates
|
||||
|
||||
@@ -214,7 +214,7 @@ public class ApplicationStoreTest extends LightPlatformLangTestCase {
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
protected StateStorage getDefaultsStorage() {
|
||||
protected PathMacroManager getPathMacroManagerForDefaults() {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@@ -18,14 +18,22 @@ package com.intellij.openapi.components.impl;
|
||||
import com.intellij.openapi.components.PersistentStateComponent;
|
||||
import com.intellij.openapi.components.State;
|
||||
import com.intellij.openapi.components.Storage;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.project.ex.ProjectManagerEx;
|
||||
import com.intellij.openapi.util.JDOMBuilder;
|
||||
import com.intellij.openapi.util.JDOMUtil;
|
||||
import com.intellij.openapi.vfs.CharsetToolkit;
|
||||
import com.intellij.testFramework.PlatformLangTestCase;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
|
||||
public abstract class ProjectStoreBaseTestCase extends PlatformLangTestCase {
|
||||
@Override
|
||||
protected Project doCreateProject(File projectFile) throws Exception {
|
||||
return ProjectManagerEx.getInstanceEx().loadProject(projectFile.getAbsolutePath());
|
||||
}
|
||||
|
||||
protected byte[] getIprFileContent() throws UnsupportedEncodingException {
|
||||
final String iprContent = JDOMUtil.writeDocument(
|
||||
JDOMBuilder.document(JDOMBuilder.tag("project",
|
||||
|
||||
@@ -101,6 +101,7 @@ predefined.configuration.class.implements.two.interfaces=class implementing two
|
||||
predefined.configuration.bean.info.classes=Bean info classes
|
||||
predefined.configuration.all.expressions.of.some.type=all expressions of some type
|
||||
predefined.configuration.variables.of.generic.types=variables of generic types
|
||||
predefined.configuration.diamond.operators=diamond operators
|
||||
predefined.configuration.comments=comments
|
||||
predefined.configuration.fields_variables.with.given.name.pattern.updated=fields/variables with given name pattern updated
|
||||
predefined.configuration.trys=try's
|
||||
@@ -145,6 +146,7 @@ predefined.configuration.packagelocal.fields.of.the.class=package local fields o
|
||||
predefined.configuration.classes=classes
|
||||
predefined.configuration.new.expressions=new expressions
|
||||
predefined.configuration.lambdas=lambdas
|
||||
predefined.configuration.method.references=method references
|
||||
|
||||
# edit variable constraint dialog options
|
||||
invalid.regular.expression=Invalid regular expression
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
*/
|
||||
package com.intellij.projectView;
|
||||
|
||||
import com.intellij.ide.highlighter.ProjectFileType;
|
||||
import com.intellij.ide.projectView.impl.AbstractProjectTreeStructure;
|
||||
import com.intellij.ide.projectView.impl.AbstractProjectViewPSIPane;
|
||||
import com.intellij.openapi.Disposable;
|
||||
@@ -97,8 +96,4 @@ public class TestProjectTreeStructure extends AbstractProjectTreeStructure imple
|
||||
@Override
|
||||
public void dispose() {
|
||||
}
|
||||
|
||||
public String getProjectFileRepresentation() {
|
||||
return " " + myProject.getName() + ProjectFileType.DOT_DEFAULT_EXTENSION + "\n";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -121,6 +121,7 @@ ide.tooltip.autoDismissDeadZone=300
|
||||
ide.balloon.shadowEnabled=true
|
||||
ide.balloon.shadow.size=15
|
||||
ide.expansion.hints.enabled=true
|
||||
ide.expansion.hints.on.all.screens=false
|
||||
ide.register.bundled.fonts=true
|
||||
ide.register.bundled.fonts.description=Disables automatic registration of bundled fonts: SourceCodePro, Inconsolata
|
||||
|
||||
@@ -515,7 +516,7 @@ check.power.supply.for.mbp.description=Check for discrete video card and power s
|
||||
force.subpixel.hinting=false
|
||||
force.subpixel.hinting.description=Force using sub-pixel antialiasing
|
||||
|
||||
lcd.contrast.value=140
|
||||
lcd.contrast.value=100
|
||||
lcd.contrast.value.description=Set LCD text contrast value from 100 to 250
|
||||
|
||||
removable.welcome.screen.projects=false
|
||||
|
||||
@@ -1185,6 +1185,9 @@ public class AllIcons {
|
||||
public static final Icon OpenProject = IconLoader.getIcon("/welcome/openProject.png"); // 16x16
|
||||
public static final Icon Register = IconLoader.getIcon("/welcome/register.png"); // 32x32
|
||||
|
||||
public static final Icon RemoveRecentProject = IconLoader.getIcon("/welcome/project/remove.png"); // 10x10
|
||||
public static final Icon RemoveRecentProjectHover = IconLoader.getIcon("/welcome/project/remove-hover.png"); // 10x10
|
||||
|
||||
}
|
||||
|
||||
public static class Xml {
|
||||
|
||||
@@ -385,6 +385,14 @@ public class UIUtil {
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isRetina (GraphicsDevice device) {
|
||||
if (SystemInfo.isMac && SystemInfo.isJavaVersionAtLeast("1.7")) {
|
||||
return DetectRetinaKit.isOracleMacRetinaDevice(device);
|
||||
} else {
|
||||
return isRetina();
|
||||
}
|
||||
}
|
||||
|
||||
//public static boolean isMacRetina(Graphics2D g) {
|
||||
// return DetectRetinaKit.isMacRetina(g);
|
||||
//}
|
||||
|
||||
@@ -109,7 +109,7 @@ public class HtmlTagCanBeJavadocTagInspection extends BaseInspection {
|
||||
}
|
||||
|
||||
private static void appendElementText(String text, int startOffset, int endOffset, StringBuilder out) {
|
||||
if (out.length() == 6 && endOffset - startOffset > 0 && !Character.isWhitespace(text.charAt(startOffset))) {
|
||||
if (out.length() == "{@code".length() && endOffset - startOffset > 0 && !Character.isWhitespace(text.charAt(startOffset))) {
|
||||
out.append(' ');
|
||||
}
|
||||
out.append(text, startOffset, endOffset);
|
||||
|
||||
@@ -161,7 +161,7 @@ public class ClassWriter {
|
||||
DecompilerContext.setProperty(DecompilerContext.CURRENT_CLASS_NODE, node);
|
||||
|
||||
int startLine = tracer != null ? tracer.getCurrentSourceLine() : 0;
|
||||
BytecodeMappingTracer dummy_tracer = new BytecodeMappingTracer();
|
||||
BytecodeMappingTracer dummy_tracer = new BytecodeMappingTracer(startLine);
|
||||
|
||||
try {
|
||||
// last minute processing
|
||||
@@ -184,6 +184,8 @@ public class ClassWriter {
|
||||
// fields
|
||||
boolean enumFields = false;
|
||||
|
||||
dummy_tracer.incrementCurrentSourceLine(buffer.countLines(start_class_def));
|
||||
|
||||
for (StructField fd : cl.getFields()) {
|
||||
boolean hide = fd.isSynthetic() && DecompilerContext.getOption(IFernflowerPreferences.REMOVE_SYNTHETIC) ||
|
||||
wrapper.getHiddenMembers().contains(InterpreterUtil.makeUniqueKey(fd.getName(), fd.getDescriptor()));
|
||||
@@ -193,6 +195,7 @@ public class ClassWriter {
|
||||
if (isEnum) {
|
||||
if (enumFields) {
|
||||
buffer.append(',').appendLineSeparator();
|
||||
dummy_tracer.incrementCurrentSourceLine();
|
||||
}
|
||||
enumFields = true;
|
||||
}
|
||||
@@ -200,6 +203,7 @@ public class ClassWriter {
|
||||
buffer.append(';');
|
||||
buffer.appendLineSeparator();
|
||||
buffer.appendLineSeparator();
|
||||
dummy_tracer.incrementCurrentSourceLine(2);
|
||||
enumFields = false;
|
||||
}
|
||||
|
||||
@@ -210,6 +214,7 @@ public class ClassWriter {
|
||||
|
||||
if (enumFields) {
|
||||
buffer.append(';').appendLineSeparator();
|
||||
dummy_tracer.incrementCurrentSourceLine();
|
||||
}
|
||||
|
||||
// FIXME: fields don't matter at the moment
|
||||
@@ -383,6 +388,7 @@ public class ClassWriter {
|
||||
}
|
||||
|
||||
private void fieldToJava(ClassWrapper wrapper, StructClass cl, StructField fd, TextBuffer buffer, int indent, BytecodeMappingTracer tracer) {
|
||||
int start = buffer.length();
|
||||
boolean isInterface = cl.hasModifier(CodeConstants.ACC_INTERFACE);
|
||||
boolean isDeprecated = fd.getAttributes().containsKey("Deprecated");
|
||||
boolean isEnum = fd.hasModifier(CodeConstants.ACC_ENUM) && DecompilerContext.getOption(IFernflowerPreferences.DECOMPILE_ENUM);
|
||||
@@ -430,6 +436,8 @@ public class ClassWriter {
|
||||
|
||||
buffer.append(fd.getName());
|
||||
|
||||
tracer.incrementCurrentSourceLine(buffer.countLines(start));
|
||||
|
||||
Exprent initializer;
|
||||
if (fd.hasModifier(CodeConstants.ACC_STATIC)) {
|
||||
initializer = wrapper.getStaticFieldInitializers().getWithKey(InterpreterUtil.makeUniqueKey(fd.getName(), fd.getDescriptor()));
|
||||
@@ -461,6 +469,7 @@ public class ClassWriter {
|
||||
|
||||
if (!isEnum) {
|
||||
buffer.append(";").appendLineSeparator();
|
||||
tracer.incrementCurrentSourceLine();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -771,6 +780,8 @@ public class ClassWriter {
|
||||
}
|
||||
}
|
||||
|
||||
tracer.incrementCurrentSourceLine(buffer.countLines(start_index_method));
|
||||
|
||||
if ((flags & (CodeConstants.ACC_ABSTRACT | CodeConstants.ACC_NATIVE)) != 0) { // native or abstract method (explicit or interface)
|
||||
if (isAnnotation) {
|
||||
StructAnnDefaultAttribute attr = (StructAnnDefaultAttribute)mt.getAttributes().getWithKey("AnnotationDefault");
|
||||
@@ -794,12 +805,12 @@ public class ClassWriter {
|
||||
buffer.setCurrentLine(lineNumberTable.getFirstLine() - 1);
|
||||
}
|
||||
buffer.append('{').appendLineSeparator();
|
||||
tracer.incrementCurrentSourceLine();
|
||||
|
||||
RootStatement root = wrapper.getMethodWrapper(mt.getName(), mt.getDescriptor()).root;
|
||||
|
||||
if (root != null && !methodWrapper.decompiledWithErrors) { // check for existence
|
||||
try {
|
||||
tracer.incrementCurrentSourceLine(buffer.countLines(start_index_method));
|
||||
int startLine = tracer.getCurrentSourceLine();
|
||||
|
||||
TextBuffer code = root.toJava(indent + 1, tracer);
|
||||
|
||||
@@ -307,7 +307,12 @@ public class TextBuffer {
|
||||
if (lineMapping.length > 0) {
|
||||
myLineMapping = new HashMap<Integer, Integer>();
|
||||
for (int i = 0; i < lineMapping.length; i+=2) {
|
||||
myLineMapping.put(lineMapping[i+1], lineMapping[i]);
|
||||
int key = lineMapping[i + 1];
|
||||
int value = lineMapping[i];
|
||||
Integer existing = myLineMapping.get(key);
|
||||
if (existing == null || value < existing) {
|
||||
myLineMapping.put(key, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -85,6 +85,7 @@ public class VarExprent extends Exprent {
|
||||
if (classDef) {
|
||||
ClassNode child = DecompilerContext.getClassProcessor().getMapRootClasses().get(varType.value);
|
||||
new ClassWriter().classToJava(child, buffer, indent, tracer);
|
||||
tracer.incrementCurrentSourceLine(buffer.countLines());
|
||||
}
|
||||
else {
|
||||
String name = null;
|
||||
|
||||
@@ -256,14 +256,13 @@ public class IfStatement extends Statement {
|
||||
elseif = true;
|
||||
}
|
||||
else {
|
||||
BytecodeMappingTracer else_tracer = new BytecodeMappingTracer(tracer.getCurrentSourceLine());
|
||||
BytecodeMappingTracer else_tracer = new BytecodeMappingTracer(tracer.getCurrentSourceLine() + 1);
|
||||
TextBuffer content = ExprProcessor.jmpWrapper(elsestat, indent + 1, false, else_tracer);
|
||||
|
||||
if (content.length() > 0) {
|
||||
buf.appendIndent(indent).append("} else {").appendLineSeparator();
|
||||
|
||||
else_tracer.shiftSourceLines(1);
|
||||
tracer.setCurrentSourceLine(else_tracer.getCurrentSourceLine() + 1);
|
||||
tracer.setCurrentSourceLine(else_tracer.getCurrentSourceLine());
|
||||
tracer.addTracer(else_tracer);
|
||||
|
||||
buf.append(content);
|
||||
|
||||
@@ -1,36 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2014 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.java.decompiler;
|
||||
|
||||
import org.jetbrains.java.decompiler.main.extern.IFernflowerPreferences;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class BytecodeToSourceMappingTest extends SingleClassesTestBase {
|
||||
@Override
|
||||
protected Map<String, Object> getDecompilerOptions() {
|
||||
return new HashMap<String, Object>() {{
|
||||
put(IFernflowerPreferences.BYTECODE_SOURCE_MAPPING, "1");
|
||||
put(IFernflowerPreferences.DUMP_ORIGINAL_LINES, "1");
|
||||
}};
|
||||
}
|
||||
|
||||
@Test public void testSimpleBytecodeMapping() { doTest("pkg/TestClassSimpleBytecodeMapping"); }
|
||||
@Test public void testSynchronizedMapping() { doTest("pkg/TestSynchronizedMapping"); }
|
||||
@Test public void testAbstractMethods() { doTest("pkg/TestAbstractMethods"); }
|
||||
}
|
||||
@@ -15,9 +15,21 @@
|
||||
*/
|
||||
package org.jetbrains.java.decompiler;
|
||||
|
||||
import org.jetbrains.java.decompiler.main.extern.IFernflowerPreferences;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class SingleClassesTest extends SingleClassesTestBase {
|
||||
@Override
|
||||
protected Map<String, Object> getDecompilerOptions() {
|
||||
return new HashMap<String, Object>() {{
|
||||
put(IFernflowerPreferences.BYTECODE_SOURCE_MAPPING, "1");
|
||||
put(IFernflowerPreferences.DUMP_ORIGINAL_LINES, "1");
|
||||
}};
|
||||
}
|
||||
|
||||
@Test public void testClassFields() { doTest("pkg/TestClassFields"); }
|
||||
@Test public void testClassLambda() { doTest("pkg/TestClassLambda"); }
|
||||
@Test public void testClassLoop() { doTest("pkg/TestClassLoop"); }
|
||||
@@ -39,4 +51,10 @@ public class SingleClassesTest extends SingleClassesTestBase {
|
||||
@Test public void testTryCatchFinally() { doTest("pkg/TestTryCatchFinally"); }
|
||||
@Test public void testAmbiguousCall() { doTest("pkg/TestAmbiguousCall"); }
|
||||
@Test public void testAmbiguousCallWithDebugInfo() { doTest("pkg/TestAmbiguousCallWithDebugInfo"); }
|
||||
@Test public void testSimpleBytecodeMapping() { doTest("pkg/TestClassSimpleBytecodeMapping"); }
|
||||
@Test public void testSynchronizedMapping() { doTest("pkg/TestSynchronizedMapping"); }
|
||||
@Test public void testAbstractMethods() { doTest("pkg/TestAbstractMethods"); }
|
||||
@Test public void testLocalClass() { doTest("pkg/TestLocalClass"); }
|
||||
@Test public void testAnonymousClass() { doTest("pkg/TestAnonymousClass"); }
|
||||
@Test public void testThrowException() { doTest("pkg/TestThrowException"); }
|
||||
}
|
||||
|
||||
@@ -13,14 +13,36 @@ class i implements bg {
|
||||
|
||||
i(b var1, j var2) {
|
||||
this.b = var1;
|
||||
this.a = var2;
|
||||
this.a = var2;// 1
|
||||
}
|
||||
|
||||
public void a(c var1, k var2, boolean var3) {
|
||||
File var4 = this.a.b().a(var1);
|
||||
b.a(this.b).add(var4);
|
||||
File var4 = this.a.b().a(var1);// 2
|
||||
b.a(this.b).add(var4);// 3
|
||||
}
|
||||
|
||||
public void a(a.a.a.a.c.b var1) {
|
||||
}
|
||||
}
|
||||
|
||||
class 'a/a/a/a/e/f/i' {
|
||||
method '<init> (La/a/a/a/e/f/b;La/a/a/a/c/j;)V' {
|
||||
2 14
|
||||
7 15
|
||||
}
|
||||
|
||||
method 'a (La/a/a/a/c/c;La/a/a/a/a/k;Z)V' {
|
||||
1 19
|
||||
4 19
|
||||
a 19
|
||||
f 19
|
||||
12 20
|
||||
15 20
|
||||
1a 20
|
||||
}
|
||||
}
|
||||
|
||||
Lines mapping:
|
||||
1 <-> 16
|
||||
2 <-> 20
|
||||
3 <-> 21
|
||||
|
||||