mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Merge remote-tracking branch 'origin/master' into develar/is
This commit is contained in:
+1
-1
@@ -58,7 +58,7 @@ public class ConstructorInsertHandler implements InsertHandler<LookupElementDeco
|
||||
|
||||
boolean isAbstract = psiClass.hasModifierProperty(PsiModifier.ABSTRACT);
|
||||
|
||||
if (Lookup.REPLACE_SELECT_CHAR == context.getCompletionChar()) {
|
||||
if (Lookup.REPLACE_SELECT_CHAR == context.getCompletionChar() && context.getOffsetMap().containsOffset(PARAM_LIST_START)) {
|
||||
final int plStart = context.getOffset(PARAM_LIST_START);
|
||||
final int plEnd = context.getOffset(PARAM_LIST_END);
|
||||
if (plStart >= 0 && plEnd >= 0) {
|
||||
|
||||
-109
@@ -1,109 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2009 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.codeInsight.daemon.impl.quickfix;
|
||||
|
||||
import com.intellij.codeInsight.FileModificationService;
|
||||
import com.intellij.codeInsight.daemon.QuickFixBundle;
|
||||
import com.intellij.codeInsight.intention.PsiElementBaseIntentionAction;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.controlFlow.*;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.util.BitUtil;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* @author ven
|
||||
*/
|
||||
public class RemoveRedundantElseAction extends PsiElementBaseIntentionAction {
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.daemon.impl.quickfix.RemoveRedundantElseAction");
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public String getText() {
|
||||
return QuickFixBundle.message("remove.redundant.else.fix");
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public String getFamilyName() {
|
||||
return QuickFixBundle.message("remove.redundant.else.fix");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAvailable(@NotNull Project project, Editor editor, @NotNull PsiElement element) {
|
||||
if (element instanceof PsiKeyword &&
|
||||
element.getParent() instanceof PsiIfStatement &&
|
||||
PsiKeyword.ELSE.equals(element.getText())) {
|
||||
PsiIfStatement ifStatement = (PsiIfStatement)element.getParent();
|
||||
if (ifStatement.getElseBranch() == null) return false;
|
||||
PsiStatement thenBranch = ifStatement.getThenBranch();
|
||||
if (thenBranch == null) return false;
|
||||
PsiElement block = PsiTreeUtil.getParentOfType(ifStatement, PsiCodeBlock.class);
|
||||
if (block != null) {
|
||||
while (cantCompleteNormally(thenBranch, block)) {
|
||||
thenBranch = getPrevThenBranch(thenBranch);
|
||||
if (thenBranch == null) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static PsiStatement getPrevThenBranch(@NotNull PsiElement thenBranch) {
|
||||
final PsiElement ifStatement = thenBranch.getParent();
|
||||
final PsiElement parent = ifStatement.getParent();
|
||||
if (parent instanceof PsiIfStatement && ((PsiIfStatement)parent).getElseBranch() == ifStatement) {
|
||||
return ((PsiIfStatement)parent).getThenBranch();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static boolean cantCompleteNormally(@NotNull PsiStatement thenBranch, PsiElement block) {
|
||||
try {
|
||||
ControlFlow controlFlow = ControlFlowFactory.getInstance(thenBranch.getProject()).getControlFlow(block, LocalsOrMyInstanceFieldsControlFlowPolicy.getInstance());
|
||||
int startOffset = controlFlow.getStartOffset(thenBranch);
|
||||
int endOffset = controlFlow.getEndOffset(thenBranch);
|
||||
return startOffset != -1 && endOffset != -1 && !BitUtil.isSet(ControlFlowUtil.getCompletionReasons(controlFlow, startOffset, endOffset), ControlFlowUtil.NORMAL_COMPLETION_REASON);
|
||||
}
|
||||
catch (AnalysisCanceledException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void invoke(@NotNull Project project, Editor editor, @NotNull PsiElement element) throws IncorrectOperationException {
|
||||
if (!FileModificationService.getInstance().preparePsiElementForWrite(element)) return;
|
||||
PsiIfStatement ifStatement = (PsiIfStatement)element.getParent();
|
||||
LOG.assertTrue(ifStatement != null && ifStatement.getElseBranch() != null);
|
||||
PsiStatement elseBranch = ifStatement.getElseBranch();
|
||||
if (elseBranch instanceof PsiBlockStatement) {
|
||||
PsiElement[] statements = ((PsiBlockStatement)elseBranch).getCodeBlock().getStatements();
|
||||
if (statements.length > 0) {
|
||||
ifStatement.getParent().addRangeAfter(statements[0], statements[statements.length-1], ifStatement);
|
||||
}
|
||||
} else {
|
||||
ifStatement.getParent().addAfter(elseBranch, ifStatement);
|
||||
}
|
||||
ifStatement.getElseBranch().delete();
|
||||
}
|
||||
}
|
||||
+49
-32
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2012 JetBrains s.r.o.
|
||||
* Copyright 2000-2016 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.
|
||||
@@ -13,44 +13,43 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.codeInsight.daemon.quickFix;
|
||||
package com.intellij.codeInspection.lambda;
|
||||
|
||||
import com.intellij.codeInsight.intention.PsiElementBaseIntentionAction;
|
||||
import com.intellij.codeInspection.BaseJavaBatchLocalInspectionTool;
|
||||
import com.intellij.codeInspection.LocalQuickFix;
|
||||
import com.intellij.codeInspection.ProblemDescriptor;
|
||||
import com.intellij.codeInspection.ProblemsHolder;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.impl.source.resolve.DefaultParameterTypeInferencePolicy;
|
||||
import com.intellij.psi.infos.MethodCandidateInfo;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.util.Function;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import org.jetbrains.annotations.Nls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* User: anna
|
||||
*/
|
||||
public class RedundantLambdaParameterTypeIntention extends PsiElementBaseIntentionAction {
|
||||
public static final Logger LOG = Logger.getInstance("#" + RedundantLambdaParameterTypeIntention.class.getName());
|
||||
public class RedundantLambdaParameterTypeInspection extends BaseJavaBatchLocalInspectionTool {
|
||||
public static final Logger LOG = Logger.getInstance("#" + RedundantLambdaParameterTypeInspection.class.getName());
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getFamilyName() {
|
||||
return "Remove redundant types";
|
||||
public PsiElementVisitor buildVisitor(@NotNull ProblemsHolder holder, boolean isOnTheFly) {
|
||||
return new JavaElementVisitor() {
|
||||
@Override
|
||||
public void visitParameterList(PsiParameterList parameterList) {
|
||||
super.visitParameterList(parameterList);
|
||||
if (isApplicable(parameterList)) {
|
||||
holder.registerProblem(parameterList, "Remove redundant types", new LambdaParametersFix());
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getText() {
|
||||
return getFamilyName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAvailable(@NotNull Project project, Editor editor, @NotNull PsiElement element) {
|
||||
final PsiParameterList parameterList = PsiTreeUtil.getParentOfType(element, PsiParameterList.class);
|
||||
if (parameterList == null) return false;
|
||||
private static boolean isApplicable(@NotNull PsiParameterList parameterList) {
|
||||
final PsiElement parent = parameterList.getParent();
|
||||
if (!(parent instanceof PsiLambdaExpression)) return false;
|
||||
final PsiLambdaExpression expression = (PsiLambdaExpression)parent;
|
||||
@@ -73,9 +72,9 @@ public class RedundantLambdaParameterTypeIntention extends PsiElementBaseIntenti
|
||||
|
||||
final PsiTypeParameter[] typeParameters = method.getTypeParameters();
|
||||
final PsiExpression[] arguments = ((PsiExpressionList)lambdaParent).getExpressions();
|
||||
final JavaPsiFacade javaPsiFacade = JavaPsiFacade.getInstance(project);
|
||||
final JavaPsiFacade javaPsiFacade = JavaPsiFacade.getInstance(parameterList.getProject());
|
||||
arguments[idx] = javaPsiFacade.getElementFactory().createExpressionFromText(
|
||||
"(" + StringUtil.join(expression.getParameterList().getParameters(), parameter -> parameter.getName(), ", ") + ") -> {}", expression);
|
||||
"(" + StringUtil.join(expression.getParameterList().getParameters(), PsiParameter::getName, ", ") + ") -> {}", expression);
|
||||
final PsiParameter[] methodParams = method.getParameterList().getParameters();
|
||||
final PsiSubstitutor substitutor = javaPsiFacade.getResolveHelper()
|
||||
.inferTypeArguments(typeParameters, methodParams, arguments, ((MethodCandidateInfo)resolveResult).getSiteSubstitutor(),
|
||||
@@ -85,8 +84,7 @@ public class RedundantLambdaParameterTypeIntention extends PsiElementBaseIntenti
|
||||
final PsiType psiType = substitutor.substitute(parameter);
|
||||
if (psiType == null || dependsOnTypeParams(psiType, expression, parameter)) return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
final PsiType paramType;
|
||||
if (idx < methodParams.length) {
|
||||
paramType = methodParams[idx].getType();
|
||||
@@ -107,12 +105,6 @@ public class RedundantLambdaParameterTypeIntention extends PsiElementBaseIntenti
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void invoke(@NotNull Project project, Editor editor, @NotNull PsiElement element) throws IncorrectOperationException {
|
||||
final PsiLambdaExpression lambdaExpression = PsiTreeUtil.getParentOfType(element, PsiLambdaExpression.class);
|
||||
removeTypes(lambdaExpression);
|
||||
}
|
||||
|
||||
private static void removeTypes(PsiLambdaExpression lambdaExpression) {
|
||||
if (lambdaExpression != null) {
|
||||
final PsiParameter[] parameters = lambdaExpression.getParameterList().getParameters();
|
||||
@@ -121,7 +113,7 @@ public class RedundantLambdaParameterTypeIntention extends PsiElementBaseIntenti
|
||||
text = parameters[0].getName();
|
||||
}
|
||||
else {
|
||||
text = "(" + StringUtil.join(parameters, parameter -> parameter.getName(), ", ") + ")";
|
||||
text = "(" + StringUtil.join(parameters, PsiParameter::getName, ", ") + ")";
|
||||
}
|
||||
final PsiLambdaExpression expression = (PsiLambdaExpression)JavaPsiFacade.getElementFactory(lambdaExpression.getProject())
|
||||
.createExpressionFromText(text + "->{}", lambdaExpression);
|
||||
@@ -135,4 +127,29 @@ public class RedundantLambdaParameterTypeIntention extends PsiElementBaseIntenti
|
||||
return LambdaUtil.depends(type, new LambdaUtil.TypeParamsChecker(expr, PsiUtil
|
||||
.resolveGenericsClassInType(LambdaUtil.getFunctionalInterfaceType(expr, false)).getElement()), param2Check);
|
||||
}
|
||||
|
||||
private static class LambdaParametersFix implements LocalQuickFix {
|
||||
@Nls
|
||||
@NotNull
|
||||
@Override
|
||||
public String getName() {
|
||||
return getFamilyName();
|
||||
}
|
||||
|
||||
@Nls
|
||||
@NotNull
|
||||
@Override
|
||||
public String getFamilyName() {
|
||||
return "Remove redundant types";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
|
||||
final PsiElement element = descriptor.getPsiElement();
|
||||
final PsiElement parent = element.getParent();
|
||||
if (parent instanceof PsiLambdaExpression) {
|
||||
removeTypes((PsiLambdaExpression)parent);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -19,13 +19,11 @@ import com.intellij.openapi.progress.ProgressIndicator;
|
||||
import com.intellij.openapi.progress.ProgressIndicatorProvider;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.roots.ProjectFileIndex;
|
||||
import com.intellij.openapi.roots.ProjectRootManager;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.openapi.vfs.VirtualFileManager;
|
||||
import com.intellij.openapi.vfs.VirtualFileWithId;
|
||||
import com.intellij.psi.impl.java.stubs.hierarchy.IndexTree;
|
||||
import com.intellij.psi.search.DelegatingGlobalSearchScope;
|
||||
import com.intellij.psi.search.EverythingGlobalScope;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.psi.stubsHierarchy.HierarchyService;
|
||||
import com.intellij.psi.util.CachedValue;
|
||||
import com.intellij.psi.util.CachedValueProvider;
|
||||
@@ -33,17 +31,18 @@ import com.intellij.psi.util.CachedValuesManager;
|
||||
import com.intellij.psi.util.PsiModificationTracker;
|
||||
import com.intellij.util.CachedValueBase;
|
||||
import com.intellij.util.indexing.FileBasedIndex;
|
||||
import com.intellij.util.indexing.FileBasedIndexImpl;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.BitSet;
|
||||
|
||||
public class HierarchyServiceImpl extends HierarchyService {
|
||||
private static final SingleClassHierarchy EMPTY_HIERARCHY = new SingleClassHierarchy(Symbol.ClassSymbol.EMPTY_ARRAY);
|
||||
private final Project myProject;
|
||||
private final ProjectFileIndex myFileIndex;
|
||||
private final CachedValue<SingleClassHierarchy> myHierarchy;
|
||||
|
||||
public HierarchyServiceImpl(Project project) {
|
||||
myProject = project;
|
||||
myFileIndex = ProjectFileIndex.SERVICE.getInstance(project);
|
||||
myHierarchy = CachedValuesManager.getManager(project).createCachedValue(
|
||||
() -> CachedValueProvider.Result.create(buildHierarchy(), PsiModificationTracker.MODIFICATION_COUNT),
|
||||
false);
|
||||
@@ -69,38 +68,56 @@ public class HierarchyServiceImpl extends HierarchyService {
|
||||
private SingleClassHierarchy buildHierarchy() {
|
||||
Symbols symbols = new Symbols();
|
||||
StubEnter stubEnter = new StubEnter(symbols);
|
||||
IdSets idSets = IdSets.getIdSets(myProject);
|
||||
|
||||
loadUnits(false, symbols.myNameEnvironment, stubEnter);
|
||||
loadUnits(idSets.libraryFiles, StubHierarchyIndex.BINARY_FILES, symbols.myNameEnvironment, stubEnter);
|
||||
stubEnter.connect1();
|
||||
|
||||
loadUnits(true, symbols.myNameEnvironment, stubEnter);
|
||||
loadUnits(idSets.sourceFiles, StubHierarchyIndex.SOURCE_FILES, symbols.myNameEnvironment, stubEnter);
|
||||
stubEnter.connect2();
|
||||
|
||||
return symbols.createHierarchy();
|
||||
}
|
||||
|
||||
private void loadUnits(boolean sourceMode, NameEnvironment names, StubEnter stubEnter) {
|
||||
GlobalSearchScope scope = new DelegatingGlobalSearchScope(new EverythingGlobalScope(myProject)) {
|
||||
@Override
|
||||
public boolean contains(@NotNull VirtualFile file) {
|
||||
return sourceMode ? myFileIndex.isInSourceContent(file) : myFileIndex.isInLibraryClasses(file);
|
||||
}
|
||||
};
|
||||
private void loadUnits(BitSet files, int indexKey, NameEnvironment names, StubEnter stubEnter) {
|
||||
ProgressIndicator indicator = ProgressIndicatorProvider.getGlobalProgressIndicator();
|
||||
FileBasedIndex index = FileBasedIndex.getInstance();
|
||||
for (String packageName : index.getAllKeys(StubHierarchyIndex.INDEX_ID, myProject)) {
|
||||
QualifiedName pkg = StringUtil.isEmpty(packageName) ? null : names.fromString(packageName, true);
|
||||
index.processValues(StubHierarchyIndex.INDEX_ID, packageName, null, new FileBasedIndex.ValueProcessor<IndexTree.Unit>() {
|
||||
int count = 0;
|
||||
|
||||
@Override
|
||||
public boolean process(VirtualFile file, IndexTree.Unit unit) {
|
||||
if (indicator != null && ++count % 128 == 0) indicator.checkCanceled();
|
||||
stubEnter.unitEnter(Translator.internNames(names, unit, ((VirtualFileWithId)file).getId(), pkg));
|
||||
return true;
|
||||
FileBasedIndexImpl index = (FileBasedIndexImpl)FileBasedIndex.getInstance();
|
||||
index.processAllValues(StubHierarchyIndex.INDEX_ID, indexKey, myProject, new FileBasedIndexImpl.IdValueProcessor<IndexTree.Unit>() {
|
||||
int count = 0;
|
||||
@Override
|
||||
public boolean process(int fileId, IndexTree.Unit unit) {
|
||||
if (indicator != null && ++count % 128 == 0) indicator.checkCanceled();
|
||||
if (files.get(fileId)) {
|
||||
QualifiedName pkg = StringUtil.isEmpty(unit.myPackageId) ? null : names.fromString(unit.myPackageId, true);
|
||||
stubEnter.unitEnter(Translator.internNames(names, unit, fileId, pkg));
|
||||
}
|
||||
}, scope);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static class IdSets {
|
||||
final BitSet sourceFiles = new BitSet();
|
||||
final BitSet libraryFiles = new BitSet();
|
||||
|
||||
static IdSets getIdSets(@NotNull Project project) {
|
||||
return CachedValuesManager.getManager(project).getCachedValue(project, () -> {
|
||||
IdSets answer = new IdSets();
|
||||
ProjectFileIndex index = ProjectFileIndex.SERVICE.getInstance(project);
|
||||
FileBasedIndex.getInstance().iterateIndexableFiles(file -> {
|
||||
if (!file.isDirectory() && file instanceof VirtualFileWithId) {
|
||||
if (index.isInSourceContent(file)) {
|
||||
answer.sourceFiles.set(((VirtualFileWithId) file).getId());
|
||||
}
|
||||
else if (index.isInLibraryClasses(file)) {
|
||||
answer.libraryFiles.set(((VirtualFileWithId) file).getId());
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}, project, ProgressIndicatorProvider.getGlobalProgressIndicator());
|
||||
return CachedValueProvider.Result.create(answer, ProjectRootManager.getInstance(project), VirtualFileManager.VFS_STRUCTURE_MODIFICATIONS);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,7 +18,6 @@ package com.intellij.psi.stubsHierarchy.impl;
|
||||
import com.intellij.ide.highlighter.JavaClassFileType;
|
||||
import com.intellij.ide.highlighter.JavaFileType;
|
||||
import com.intellij.openapi.fileTypes.FileType;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.PsiModifier;
|
||||
import com.intellij.psi.PsiNameHelper;
|
||||
@@ -39,7 +38,10 @@ import com.intellij.util.indexing.FileContent;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
public class JavaStubIndexer extends StubHierarchyIndexer {
|
||||
|
||||
@@ -61,7 +63,7 @@ public class JavaStubIndexer extends StubHierarchyIndexer {
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public List<Pair<String, Unit>> indexFile(@NotNull FileContent content) {
|
||||
public Unit indexFile(@NotNull FileContent content) {
|
||||
Stub stubTree = StubTreeBuilder.buildStubTree(content);
|
||||
if (!(stubTree instanceof PsiJavaFileStub)) return null;
|
||||
|
||||
@@ -87,7 +89,7 @@ public class JavaStubIndexer extends StubHierarchyIndexer {
|
||||
ClassDecl[] classes = classList.isEmpty() ? ClassDecl.EMPTY_ARRAY : classList.toArray(new ClassDecl[classList.size()]);
|
||||
Import[] imports = importList.isEmpty() ? Import.EMPTY_ARRAY : importList.toArray(new Import[importList.size()]);
|
||||
byte type = javaFileStub.isCompiled() ? IndexTree.BYTECODE : IndexTree.JAVA;
|
||||
return Collections.singletonList(Pair.create(javaFileStub.getPackageName(), new Unit(type, imports, classes)));
|
||||
return new Unit(javaFileStub.getPackageName(), type, imports, classes);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
|
||||
@@ -18,47 +18,42 @@ package com.intellij.psi.stubsHierarchy.impl;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.project.ProjectManager;
|
||||
import com.intellij.openapi.roots.ProjectFileIndex;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.impl.java.stubs.hierarchy.IndexTree;
|
||||
import com.intellij.psi.impl.java.stubs.index.JavaUnitDescriptor;
|
||||
import com.intellij.psi.stubsHierarchy.StubHierarchyIndexer;
|
||||
import com.intellij.util.indexing.*;
|
||||
import com.intellij.util.io.DataExternalizer;
|
||||
import com.intellij.util.io.EnumeratorStringDescriptor;
|
||||
import com.intellij.util.io.EnumeratorIntegerDescriptor;
|
||||
import com.intellij.util.io.KeyDescriptor;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
|
||||
/**
|
||||
* @author peter
|
||||
*/
|
||||
public class StubHierarchyIndex extends FileBasedIndexExtension<String, IndexTree.Unit> implements PsiDependentIndex {
|
||||
static final ID<String, IndexTree.Unit> INDEX_ID = ID.create("jvm.hierarchy");
|
||||
public class StubHierarchyIndex extends FileBasedIndexExtension<Integer, IndexTree.Unit> implements PsiDependentIndex {
|
||||
public static final int BINARY_FILES = 0;
|
||||
public static final int SOURCE_FILES = 1;
|
||||
static final ID<Integer, IndexTree.Unit> INDEX_ID = ID.create("jvm.hierarchy");
|
||||
private static final StubHierarchyIndexer[] ourIndexers = StubHierarchyIndexer.EP_NAME.getExtensions();
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public ID<String, IndexTree.Unit> getName() {
|
||||
public ID<Integer, IndexTree.Unit> getName() {
|
||||
return INDEX_ID;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public DataIndexer<String, IndexTree.Unit, FileContent> getIndexer() {
|
||||
public DataIndexer<Integer, IndexTree.Unit, FileContent> getIndexer() {
|
||||
return inputData -> {
|
||||
for (StubHierarchyIndexer indexer : ourIndexers) {
|
||||
List<Pair<String, IndexTree.Unit>> pairs = indexer.handlesFile(inputData.getFile()) ? indexer.indexFile(inputData) : null;
|
||||
if (pairs != null && !pairs.isEmpty()) {
|
||||
Map<String, IndexTree.Unit> answer = new HashMap<>();
|
||||
for (Pair<String, IndexTree.Unit> entry : pairs) {
|
||||
if (entry.second.myDecls.length > 0) {
|
||||
answer.put(StringUtil.notNullize(entry.first), entry.second);
|
||||
}
|
||||
}
|
||||
return answer;
|
||||
IndexTree.Unit unit = indexer.handlesFile(inputData.getFile()) ? indexer.indexFile(inputData) : null;
|
||||
if (unit != null && unit.myDecls.length > 0) {
|
||||
return Collections.singletonMap(inputData.getFile().getFileType().isBinary() ? BINARY_FILES : SOURCE_FILES, unit);
|
||||
}
|
||||
}
|
||||
return Collections.emptyMap();
|
||||
@@ -67,8 +62,8 @@ public class StubHierarchyIndex extends FileBasedIndexExtension<String, IndexTre
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public KeyDescriptor<String> getKeyDescriptor() {
|
||||
return EnumeratorStringDescriptor.INSTANCE;
|
||||
public KeyDescriptor<Integer> getKeyDescriptor() {
|
||||
return EnumeratorIntegerDescriptor.INSTANCE;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -79,7 +74,7 @@ public class StubHierarchyIndex extends FileBasedIndexExtension<String, IndexTre
|
||||
|
||||
@Override
|
||||
public int getVersion() {
|
||||
return IndexTree.STUB_HIERARCHY_ENABLED ? 2 + Arrays.stream(ourIndexers).mapToInt(StubHierarchyIndexer::getVersion).sum() : 0;
|
||||
return IndexTree.STUB_HIERARCHY_ENABLED ? 3 + Arrays.stream(ourIndexers).mapToInt(StubHierarchyIndexer::getVersion).sum() : 0;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
+3
-1
@@ -29,6 +29,7 @@ public class JavaUnitDescriptor implements DataExternalizer<IndexTree.Unit> {
|
||||
|
||||
@Override
|
||||
public void save(@NotNull DataOutput out, IndexTree.Unit value) throws IOException {
|
||||
out.writeUTF(value.myPackageId);
|
||||
out.writeByte(value.myUnitType);
|
||||
if (value.myUnitType != IndexTree.BYTECODE) {
|
||||
DataInputOutputUtil.writeINT(out, value.imports.length);
|
||||
@@ -75,6 +76,7 @@ public class JavaUnitDescriptor implements DataExternalizer<IndexTree.Unit> {
|
||||
|
||||
@Override
|
||||
public IndexTree.Unit read(@NotNull DataInput in) throws IOException {
|
||||
String pid = in.readUTF();
|
||||
byte type = in.readByte();
|
||||
IndexTree.Import[] imports = IndexTree.Import.EMPTY_ARRAY;
|
||||
if (type != IndexTree.BYTECODE) {
|
||||
@@ -87,7 +89,7 @@ public class JavaUnitDescriptor implements DataExternalizer<IndexTree.Unit> {
|
||||
for (int i = 0; i < classes.length; i++) {
|
||||
classes[i] = readClassDecl(in);
|
||||
}
|
||||
return new IndexTree.Unit(type, imports, classes);
|
||||
return new IndexTree.Unit(pid, type, imports, classes);
|
||||
}
|
||||
|
||||
private IndexTree.ClassDecl readClassDecl(DataInput in) throws IOException {
|
||||
|
||||
+1
-4
@@ -16,15 +16,12 @@
|
||||
package com.intellij.psi.stubsHierarchy;
|
||||
|
||||
import com.intellij.openapi.extensions.ExtensionPointName;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.impl.java.stubs.hierarchy.IndexTree;
|
||||
import com.intellij.util.indexing.FileContent;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author peter
|
||||
*/
|
||||
@@ -37,7 +34,7 @@ public abstract class StubHierarchyIndexer {
|
||||
* @return a list of pairs <packageName, compilation unit> for a specified file content
|
||||
*/
|
||||
@Nullable
|
||||
public abstract List<Pair<String, IndexTree.Unit>> indexFile(@NotNull FileContent content);
|
||||
public abstract IndexTree.Unit indexFile(@NotNull FileContent content);
|
||||
|
||||
public abstract boolean handlesFile(@NotNull VirtualFile file);
|
||||
|
||||
|
||||
@@ -15,11 +15,15 @@
|
||||
*/
|
||||
package com.intellij.psi.util;
|
||||
|
||||
import com.intellij.openapi.roots.FileIndexFacade;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.util.containers.HashSet;
|
||||
import gnu.trove.THashMap;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
@@ -111,6 +115,7 @@ public class PsiSuperMethodUtil {
|
||||
public static Map<MethodSignature, Set<PsiMethod>> collectOverrideEquivalents(@NotNull PsiClass aClass) {
|
||||
final Map<MethodSignature, Set<PsiMethod>> overrideEquivalent =
|
||||
new THashMap<MethodSignature, Set<PsiMethod>>(MethodSignatureUtil.METHOD_PARAMETERS_ERASURE_EQUALITY);
|
||||
final GlobalSearchScope resolveScope = aClass.getResolveScope();
|
||||
PsiClass[] supers = aClass.getSupers();
|
||||
for (int i = 0; i < supers.length; i++) {
|
||||
PsiClass superClass = supers[i];
|
||||
@@ -122,10 +127,12 @@ public class PsiSuperMethodUtil {
|
||||
if (subType) continue;
|
||||
final PsiSubstitutor superClassSubstitutor = TypeConversionUtil.getSuperClassSubstitutor(superClass, aClass, PsiSubstitutor.EMPTY);
|
||||
for (HierarchicalMethodSignature hms : superClass.getVisibleSignatures()) {
|
||||
final PsiMethod method = hms.getMethod();
|
||||
PsiMethod method = hms.getMethod();
|
||||
if (MethodSignatureUtil.findMethodBySignature(aClass, method.getSignature(superClassSubstitutor), false) != null) continue;
|
||||
final PsiClass containingClass = method.getContainingClass();
|
||||
final PsiClass containingClass = mapClass(method.getContainingClass(), resolveScope);
|
||||
if (containingClass == null) continue;
|
||||
method = containingClass.findMethodBySignature(method, false);
|
||||
if (method == null) continue;
|
||||
final PsiSubstitutor containingClassSubstitutor = TypeConversionUtil.getClassSubstitutor(containingClass, aClass, PsiSubstitutor.EMPTY);
|
||||
if (containingClassSubstitutor == null) continue;
|
||||
final PsiSubstitutor finalSubstitutor =
|
||||
@@ -141,4 +148,30 @@ public class PsiSuperMethodUtil {
|
||||
}
|
||||
return overrideEquivalent;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static PsiClass mapClass(PsiClass psiClass, final GlobalSearchScope resolveScope) {
|
||||
if (psiClass == null) return null;
|
||||
String qualifiedName = psiClass.getQualifiedName();
|
||||
if (qualifiedName == null) {
|
||||
return psiClass;
|
||||
}
|
||||
|
||||
PsiFile file = psiClass.getContainingFile();
|
||||
if (file == null || !file.getViewProvider().isPhysical()) {
|
||||
return psiClass;
|
||||
}
|
||||
|
||||
final VirtualFile vFile = file.getVirtualFile();
|
||||
if (vFile == null) {
|
||||
return psiClass;
|
||||
}
|
||||
|
||||
final FileIndexFacade index = FileIndexFacade.getInstance(file.getProject());
|
||||
if (!index.isInSource(vFile) && !index.isInLibrarySource(vFile) && !index.isInLibraryClasses(vFile)) {
|
||||
return psiClass;
|
||||
}
|
||||
|
||||
return JavaPsiFacade.getInstance(psiClass.getProject()).findClass(qualifiedName, resolveScope);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,11 +15,10 @@
|
||||
*/
|
||||
package com.intellij.psi.impl;
|
||||
|
||||
import com.intellij.openapi.roots.FileIndexFacade;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.pom.java.LanguageLevel;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.psi.util.PsiSuperMethodUtil;
|
||||
import com.intellij.psi.util.PsiUtilCore;
|
||||
import com.intellij.util.Function;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
@@ -56,7 +55,7 @@ class TypeCorrector extends PsiTypeMapper {
|
||||
final PsiClassType.ClassResolveResult classResolveResult = classType.resolveGenerics();
|
||||
final PsiClass psiClass = classResolveResult.getElement();
|
||||
if (psiClass != null && classResolveResult.getSubstitutor() == PsiSubstitutor.EMPTY) {
|
||||
final PsiClass mappedClass = mapClass(psiClass);
|
||||
final PsiClass mappedClass = PsiSuperMethodUtil.mapClass(psiClass, myResolveScope);
|
||||
if (mappedClass == null || mappedClass == psiClass) return (T) classType;
|
||||
}
|
||||
}
|
||||
@@ -79,7 +78,7 @@ class TypeCorrector extends PsiTypeMapper {
|
||||
|
||||
PsiUtilCore.ensureValid(psiClass);
|
||||
|
||||
final PsiClass mappedClass = mapClass(psiClass);
|
||||
final PsiClass mappedClass = PsiSuperMethodUtil.mapClass(psiClass, myResolveScope);
|
||||
if (mappedClass == null) return classType;
|
||||
|
||||
PsiClassType mappedType = new PsiCorrectedClassType(classType.getLanguageLevel(),
|
||||
@@ -89,31 +88,6 @@ class TypeCorrector extends PsiTypeMapper {
|
||||
return mappedType;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private PsiClass mapClass(@NotNull PsiClass psiClass) {
|
||||
String qualifiedName = psiClass.getQualifiedName();
|
||||
if (qualifiedName == null) {
|
||||
return psiClass;
|
||||
}
|
||||
|
||||
PsiFile file = psiClass.getContainingFile();
|
||||
if (file == null || !file.getViewProvider().isPhysical()) {
|
||||
return psiClass;
|
||||
}
|
||||
|
||||
final VirtualFile vFile = file.getVirtualFile();
|
||||
if (vFile == null) {
|
||||
return psiClass;
|
||||
}
|
||||
|
||||
final FileIndexFacade index = FileIndexFacade.getInstance(file.getProject());
|
||||
if (!index.isInSource(vFile) && !index.isInLibrarySource(vFile) && !index.isInLibraryClasses(vFile)) {
|
||||
return psiClass;
|
||||
}
|
||||
|
||||
return JavaPsiFacade.getInstance(psiClass.getProject()).findClass(qualifiedName, myResolveScope);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private PsiSubstitutor mapSubstitutor(PsiClass originalClass, PsiClass mappedClass, PsiSubstitutor substitutor) {
|
||||
PsiTypeParameter[] typeParameters = mappedClass.getTypeParameters();
|
||||
|
||||
@@ -17,6 +17,9 @@ package com.intellij.psi.impl.java.stubs.hierarchy;
|
||||
|
||||
|
||||
import com.intellij.openapi.util.registry.Registry;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
@@ -37,11 +40,13 @@ public class IndexTree {
|
||||
public static final byte GROOVY = 2;
|
||||
|
||||
public static class Unit {
|
||||
@NotNull public final String myPackageId;
|
||||
public final byte myUnitType;
|
||||
public final Import[] imports;
|
||||
public final ClassDecl[] myDecls;
|
||||
|
||||
public Unit(byte unitType, Import[] imports, ClassDecl[] decls) {
|
||||
public Unit(@Nullable String packageId, byte unitType, Import[] imports, ClassDecl[] decls) {
|
||||
this.myPackageId = StringUtil.notNullize(packageId);
|
||||
this.myUnitType = unitType;
|
||||
this.imports = imports;
|
||||
this.myDecls = decls;
|
||||
@@ -54,6 +59,8 @@ public class IndexTree {
|
||||
|
||||
Unit unit = (Unit)o;
|
||||
|
||||
if (myUnitType != unit.myUnitType) return false;
|
||||
if (!myPackageId.equals(unit.myPackageId)) return false;
|
||||
if (!Arrays.equals(imports, unit.imports)) return false;
|
||||
if (!Arrays.equals(myDecls, unit.myDecls)) return false;
|
||||
|
||||
@@ -62,7 +69,14 @@ public class IndexTree {
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Arrays.hashCode(myDecls);
|
||||
int hash = myUnitType * 31 + myPackageId.hashCode();
|
||||
for (ClassDecl decl : myDecls) {
|
||||
String name = decl.myName;
|
||||
if (name != null) {
|
||||
return hash * 31 + name.hashCode();
|
||||
}
|
||||
}
|
||||
return hash;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+1
-3
@@ -237,9 +237,7 @@ public class PsiMethodCallExpressionImpl extends ExpressionPsiElement implements
|
||||
PsiType ret,
|
||||
JavaResolveResult result,
|
||||
LanguageLevel languageLevel) {
|
||||
PsiSubstitutor substitutor = result instanceof MethodCandidateInfo && !PsiPolyExpressionUtil.isMethodCallTypeDependsOnInference(call, method)
|
||||
? ((MethodCandidateInfo)result).getSiteSubstitutor()
|
||||
: result.getSubstitutor();
|
||||
PsiSubstitutor substitutor = result.getSubstitutor();
|
||||
PsiType substitutedReturnType = substitutor.substitute(ret);
|
||||
if (substitutedReturnType == null) {
|
||||
return TypeConversionUtil.erasure(ret);
|
||||
|
||||
-13
@@ -1,13 +0,0 @@
|
||||
// "Remove redundant 'else'" "true"
|
||||
class a {
|
||||
void foo() {
|
||||
int a = 0;
|
||||
int b = 0;
|
||||
if (a != b) {
|
||||
return;
|
||||
}
|
||||
a = b;
|
||||
a++;
|
||||
}
|
||||
}
|
||||
|
||||
-14
@@ -1,14 +0,0 @@
|
||||
// "Remove redundant 'else'" "true"
|
||||
class a {
|
||||
void foo() {
|
||||
int a = 0;
|
||||
int b = 0;
|
||||
if (a != b) {
|
||||
return;
|
||||
} e<caret>lse {
|
||||
a = b;
|
||||
}
|
||||
a++;
|
||||
}
|
||||
}
|
||||
|
||||
-15
@@ -1,15 +0,0 @@
|
||||
// "Remove redundant 'else'" "false"
|
||||
import java.io.IOException;
|
||||
class a {
|
||||
void foo(boolean condition) throws IOException{
|
||||
if (condition) {
|
||||
tMethod();
|
||||
}
|
||||
e<caret>lse {
|
||||
System.out.println("else");
|
||||
}
|
||||
}
|
||||
|
||||
void tMethod() throws IOException {}
|
||||
}
|
||||
|
||||
-17
@@ -1,17 +0,0 @@
|
||||
// "Remove redundant 'else'" "false"
|
||||
class a {
|
||||
void foo() {
|
||||
int a = 0;
|
||||
int b = 0;
|
||||
if (a != b) {
|
||||
a = 10;
|
||||
} else if (a + 1 == b) {
|
||||
return;
|
||||
}
|
||||
e<caret>lse {
|
||||
a = b;
|
||||
}
|
||||
a++;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
package p;
|
||||
interface I {
|
||||
default void foo();
|
||||
}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
package p;
|
||||
|
||||
public abstract class A implements I {}
|
||||
@@ -0,0 +1,4 @@
|
||||
package p;
|
||||
interface I {
|
||||
default void foo();
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
package p;
|
||||
|
||||
class EmptyValueIterator extends A implements ValueIterator {
|
||||
|
||||
}
|
||||
|
||||
interface ValueIterator extends I {}
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
import java.util.stream.Stream;
|
||||
|
||||
class InChain {
|
||||
public static void main(String[] args) {
|
||||
Stream.of("a").map((String<caret> s) -> s + "1").forEach(System.out::println);
|
||||
}
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
import java.util.stream.Stream;
|
||||
|
||||
class InChain {
|
||||
public static void main(String[] args) {
|
||||
Stream.of("a").map(s -> s + "1").forEach(System.out::println);
|
||||
}
|
||||
}
|
||||
@@ -18,7 +18,6 @@ package com.intellij.codeInsight;
|
||||
|
||||
import com.intellij.openapi.application.ex.PathManagerEx;
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.roots.ModifiableRootModel;
|
||||
import com.intellij.openapi.roots.ModuleRootModificationUtil;
|
||||
import com.intellij.openapi.vfs.VfsUtilCore;
|
||||
import com.intellij.pom.java.LanguageLevel;
|
||||
@@ -26,7 +25,6 @@ import com.intellij.testFramework.IdeaTestUtil;
|
||||
import com.intellij.testFramework.UsefulTestCase;
|
||||
import com.intellij.testFramework.builders.JavaModuleFixtureBuilder;
|
||||
import com.intellij.testFramework.fixtures.*;
|
||||
import com.intellij.util.Consumer;
|
||||
|
||||
public class MultipleJdksHighlightingTest extends UsefulTestCase {
|
||||
|
||||
@@ -197,6 +195,16 @@ public class MultipleJdksHighlightingTest extends UsefulTestCase {
|
||||
myFixture.checkHighlighting();
|
||||
}
|
||||
|
||||
public void testUnrelatedDefaultsFromDifferentJdkVersions() throws Exception {
|
||||
ModuleRootModificationUtil.addDependency(myJava8Module, myJava7Module);
|
||||
myFixture.copyFileToProject("java7/p/I.java");
|
||||
myFixture.copyFileToProject("java8/p/I.java");
|
||||
|
||||
final String testName = getTestName(false);
|
||||
myFixture.configureByFiles("java8/p/" + testName + ".java", "java7/p/" + testName + ".java");
|
||||
myFixture.checkHighlighting();
|
||||
}
|
||||
|
||||
private void doTestWithoutLibrary() {
|
||||
final String name = getTestName(false);
|
||||
myFixture.configureByFiles("java7/p/" + name + ".java", "java8/p/" + name + ".java");
|
||||
|
||||
-33
@@ -1,33 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2012 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.codeInsight.daemon.quickFix;
|
||||
|
||||
import com.intellij.openapi.projectRoots.Sdk;
|
||||
import com.intellij.testFramework.IdeaTestUtil;
|
||||
|
||||
public class RedundantLambdaParameterTypeIntentionTest extends LightQuickFixParameterizedTestCase {
|
||||
public void test() throws Exception { doAllTests(); }
|
||||
|
||||
@Override
|
||||
protected String getBasePath() {
|
||||
return "/codeInsight/daemonCodeAnalyzer/quickFix/redundantLambdaParameterType";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Sdk getProjectJDK() {
|
||||
return IdeaTestUtil.getMockJdk18();
|
||||
}
|
||||
}
|
||||
-32
@@ -1,32 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2010 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.daemon.quickFix;
|
||||
|
||||
/**
|
||||
* User: anna
|
||||
* Date: Aug 30, 2010
|
||||
*/
|
||||
public class RemoveRedundantElseActionTest extends LightQuickFixParameterizedTestCase {
|
||||
|
||||
public void test() throws Exception { doAllTests(); }
|
||||
|
||||
@Override
|
||||
protected String getBasePath() {
|
||||
return "/codeInsight/daemonCodeAnalyzer/quickFix/removeRedundantElse";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+112
@@ -0,0 +1,112 @@
|
||||
/*
|
||||
* Copyright 2000-2016 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:public void testwww() {}.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.codeInspection;
|
||||
|
||||
import com.intellij.JavaTestUtil;
|
||||
import com.intellij.codeInsight.intention.IntentionAction;
|
||||
import com.intellij.codeInspection.lambda.RedundantLambdaParameterTypeInspection;
|
||||
import com.intellij.idea.Bombed;
|
||||
import com.intellij.openapi.roots.ModuleRootModificationUtil;
|
||||
import com.intellij.testFramework.IdeaTestUtil;
|
||||
import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase;
|
||||
|
||||
import java.util.Calendar;
|
||||
import java.util.List;
|
||||
|
||||
public class RedundantLambdaParameterTypeInspectionTest extends LightCodeInsightFixtureTestCase {
|
||||
private RedundantLambdaParameterTypeInspection myInspection = new RedundantLambdaParameterTypeInspection();
|
||||
private String myIntentionName = "Remove redundant types";
|
||||
|
||||
@Override
|
||||
protected String getBasePath() {
|
||||
return JavaTestUtil.getRelativeJavaTestDataPath() + "/codeInspection/redundantLambdaParameterType";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
ModuleRootModificationUtil.setModuleSdk(myModule, IdeaTestUtil.getMockJdk18());
|
||||
myFixture.enableInspections(myInspection);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void tearDown() throws Exception {
|
||||
try {
|
||||
myFixture.disableInspections(myInspection);
|
||||
}
|
||||
finally {
|
||||
super.tearDown();
|
||||
}
|
||||
}
|
||||
|
||||
public void testAssignment() {
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testAssignmentNoParams() {
|
||||
assertIntentionNotAvailable();
|
||||
}
|
||||
|
||||
public void testAssignmentNoTypes() {
|
||||
assertIntentionNotAvailable();
|
||||
}
|
||||
|
||||
public void testAtVarargPlace() {
|
||||
assertIntentionNotAvailable();
|
||||
}
|
||||
|
||||
public void testCallNoTypeArgs() {
|
||||
assertIntentionNotAvailable();
|
||||
}
|
||||
|
||||
public void testCallNoTypeArgs1() {
|
||||
assertIntentionNotAvailable();
|
||||
}
|
||||
|
||||
public void testCallWithTypeArgs() {
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testInferredFromOtherArgs() {
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testNoSelfTypeParam() {
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testTypeParam() {
|
||||
assertIntentionNotAvailable();
|
||||
}
|
||||
|
||||
@Bombed(month = Calendar.AUGUST, day = 1, user = "Pavel Dolgov")
|
||||
public void testInChain() {
|
||||
doTest();
|
||||
}
|
||||
|
||||
private void doTest() {
|
||||
myFixture.configureByFiles(getTestName(false) + ".java");
|
||||
final IntentionAction singleIntention = myFixture.findSingleIntention(myIntentionName);
|
||||
myFixture.launchAction(singleIntention);
|
||||
myFixture.checkResultByFile(getTestName(false) + ".java", getTestName(false) + "_after.java", true);
|
||||
}
|
||||
|
||||
private void assertIntentionNotAvailable() {
|
||||
myFixture.configureByFiles(getTestName(false) + ".java");
|
||||
final List<IntentionAction> intentionActions = myFixture.filterAvailableIntentions(myIntentionName);
|
||||
assertEmpty(myIntentionName + " is not expected", intentionActions);
|
||||
}
|
||||
}
|
||||
+17
-4
@@ -58,10 +58,7 @@ import org.junit.Assert;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.ref.SoftReference;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
import java.util.Set;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@PlatformTestCase.WrapInCommand
|
||||
@@ -915,4 +912,20 @@ public class SmartPsiElementPointersTest extends CodeInsightTestCase {
|
||||
assertEquals(psiClass.getNameIdentifier().getTextRange(), TextRange.create(range));
|
||||
}
|
||||
|
||||
public void testManySmartPointersCreationDeletionPerformance() throws Exception {
|
||||
String text = StringUtil.repeatSymbol(' ', 100000);
|
||||
PsiFile file = createFile("a.txt", text);
|
||||
|
||||
PlatformTestUtil.startPerformanceTest("", 2000, () -> {
|
||||
List<SmartPsiFileRange> pointers = new ArrayList<>();
|
||||
for (int i = 0; i < text.length() - 1; i++) {
|
||||
pointers.add(getPointerManager().createSmartPsiFileRangePointer(file, new TextRange(i, i + 1)));
|
||||
}
|
||||
Collections.shuffle(pointers);
|
||||
for (SmartPsiFileRange pointer : pointers) {
|
||||
getPointerManager().removePointer(pointer);
|
||||
}
|
||||
}).cpuBound().assertTiming();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+68
-70
@@ -29,7 +29,7 @@ import com.intellij.psi.*;
|
||||
import com.intellij.psi.impl.PsiDocumentManagerBase;
|
||||
import com.intellij.psi.util.PsiUtilCore;
|
||||
import com.intellij.reference.SoftReference;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import com.intellij.util.CommonProcessors;
|
||||
import com.intellij.util.Processor;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -68,7 +68,7 @@ public class SmartPointerManagerImpl extends SmartPointerManager {
|
||||
|
||||
FilePointersList pointers = reference.file.getUserData(reference.key);
|
||||
if (pointers != null) {
|
||||
pointers.remove(reference);
|
||||
pointers.removeReference(reference);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -160,12 +160,13 @@ public class SmartPointerManagerImpl extends SmartPointerManager {
|
||||
SmartPointerElementInfo info = pointer.getElementInfo();
|
||||
if (!(info instanceof SelfElementInfo)) return;
|
||||
|
||||
PointerReference reference = new PointerReference(pointer, containingFile, POINTERS_KEY);
|
||||
while (true) {
|
||||
FilePointersList pointers = getPointers(containingFile);
|
||||
if (pointers == null) {
|
||||
pointers = containingFile.putUserDataIfAbsent(POINTERS_KEY, new FilePointersList());
|
||||
}
|
||||
if (pointers.add(new PointerReference(pointer, containingFile, ourQueue, POINTERS_KEY))) {
|
||||
if (pointers.add(reference)) {
|
||||
if (((SelfElementInfo)info).hasRange()) {
|
||||
pointers.markerCache.rangeChanged();
|
||||
}
|
||||
@@ -193,8 +194,10 @@ public class SmartPointerManagerImpl extends SmartPointerManager {
|
||||
if (containingFile == null) return;
|
||||
VirtualFile vFile = containingFile.getViewProvider().getVirtualFile();
|
||||
FilePointersList pointers = getPointers(vFile);
|
||||
if (pointers == null) return;
|
||||
pointers.remove(pointer);
|
||||
PointerReference reference = ((SmartPsiElementPointerImpl)pointer).pointerReference;
|
||||
if (pointers != null && reference != null) {
|
||||
pointers.removeReference(reference);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -264,17 +267,18 @@ public class SmartPointerManagerImpl extends SmartPointerManager {
|
||||
return myPsiDocManager;
|
||||
}
|
||||
|
||||
private static class PointerReference extends WeakReference<SmartPsiElementPointerImpl> {
|
||||
static class PointerReference extends WeakReference<SmartPsiElementPointerImpl> {
|
||||
@NotNull private final VirtualFile file;
|
||||
@NotNull private final Key<FilePointersList> key;
|
||||
private int index = -2;
|
||||
|
||||
private PointerReference(@NotNull SmartPsiElementPointerImpl<?> pointer,
|
||||
@NotNull VirtualFile containingFile,
|
||||
@NotNull ReferenceQueue<SmartPsiElementPointerImpl> queue,
|
||||
@NotNull Key<FilePointersList> key) {
|
||||
super(pointer, queue);
|
||||
super(pointer, ourQueue);
|
||||
file = containingFile;
|
||||
this.key = key;
|
||||
pointer.pointerReference = this;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -292,104 +296,98 @@ public class SmartPointerManagerImpl extends SmartPointerManager {
|
||||
}
|
||||
|
||||
if (nextAvailableIndex >= references.length || nextAvailableIndex > size*2) { // overflow or too many dead refs
|
||||
int newCapacity = nextAvailableIndex >= references.length ? references.length * 3/2 +1 : size * 3/2+1;
|
||||
PointerReference[] newReferences = new PointerReference[newCapacity];
|
||||
int newCapacity = (nextAvailableIndex >= references.length ? references.length : size) * 3 / 2 + 1;
|
||||
final PointerReference[] newReferences = new PointerReference[newCapacity];
|
||||
|
||||
int o = 0;
|
||||
for (PointerReference oldRef : references) {
|
||||
if (SoftReference.dereference(oldRef) != null) {
|
||||
newReferences[o++] = oldRef;
|
||||
final int[] o = {0};
|
||||
processAlivePointers(new Processor<SmartPsiElementPointerImpl>() {
|
||||
@Override
|
||||
public boolean process(SmartPsiElementPointerImpl pointer) {
|
||||
storePointerReference(newReferences, o[0]++, pointer.pointerReference);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
});
|
||||
references = newReferences;
|
||||
size = nextAvailableIndex = o;
|
||||
size = nextAvailableIndex = o[0];
|
||||
}
|
||||
references[nextAvailableIndex++] = reference;
|
||||
assert references[nextAvailableIndex] == null : references[nextAvailableIndex];
|
||||
storePointerReference(references, nextAvailableIndex++, reference);
|
||||
size++;
|
||||
mySorted = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
private synchronized void remove(@NotNull PointerReference reference) {
|
||||
int index = ArrayUtil.indexOf(references, reference, 0, nextAvailableIndex);
|
||||
if (index != -1) {
|
||||
removeReference(reference, index);
|
||||
}
|
||||
}
|
||||
private synchronized void removeReference(@NotNull PointerReference reference) {
|
||||
int index = reference.index;
|
||||
if (index < 0) return;
|
||||
|
||||
private synchronized void remove(@NotNull SmartPsiElementPointer smartPointer) {
|
||||
for (int i = 0; i < nextAvailableIndex; i++) {
|
||||
PointerReference reference = references[i];
|
||||
if (reference != null && reference.get() == smartPointer) {
|
||||
removeReference(reference, i);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void removeReference(@NotNull PointerReference reference, int index) {
|
||||
assert references[index] == reference : "At " + index + " expected " + reference + ", found " + references[index];
|
||||
references[index].index = -1;
|
||||
references[index] = null;
|
||||
if (--size == 0) {
|
||||
reference.file.replace(reference.key, this, null);
|
||||
}
|
||||
}
|
||||
|
||||
boolean processAlivePointers(@NotNull Processor<SmartPsiElementPointerImpl> processor) {
|
||||
synchronized boolean processAlivePointers(@NotNull Processor<SmartPsiElementPointerImpl> processor) {
|
||||
for (int i = 0; i < nextAvailableIndex; i++) {
|
||||
SmartPsiElementPointerImpl pointer = SoftReference.dereference(references[i]);
|
||||
if (pointer != null && !processor.process(pointer)) {
|
||||
PointerReference ref = references[i];
|
||||
if (ref == null) continue;
|
||||
|
||||
SmartPsiElementPointerImpl pointer = ref.get();
|
||||
if (pointer == null) {
|
||||
removeReference(ref);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!processor.process(pointer)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
synchronized List<SelfElementInfo> getSortedInfos() {
|
||||
private void ensureSorted() {
|
||||
if (!mySorted) {
|
||||
List<SmartPsiElementPointerImpl> hardRefs = ContainerUtil.newArrayListWithCapacity(size);
|
||||
for (int i = 0; i < nextAvailableIndex; i++) {
|
||||
PointerReference reference = references[i];
|
||||
if (reference == null) continue;
|
||||
List<SmartPsiElementPointerImpl> pointers = new ArrayList<SmartPsiElementPointerImpl>();
|
||||
processAlivePointers(new CommonProcessors.CollectProcessor<SmartPsiElementPointerImpl>(pointers));
|
||||
assert size == pointers.size();
|
||||
|
||||
SmartPsiElementPointerImpl pointer = reference.get();
|
||||
if (pointer != null) {
|
||||
hardRefs.add(pointer);
|
||||
}
|
||||
else {
|
||||
removeReference(reference, i);
|
||||
if (size == 0) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
||||
}
|
||||
assert size == hardRefs.size();
|
||||
|
||||
Arrays.sort(references, 0, nextAvailableIndex, new Comparator<PointerReference>() {
|
||||
Collections.sort(pointers, new Comparator<SmartPsiElementPointerImpl>() {
|
||||
@Override
|
||||
public int compare(PointerReference o1, PointerReference o2) {
|
||||
SmartPsiElementPointerImpl p1 = SoftReference.dereference(o1);
|
||||
SmartPsiElementPointerImpl p2 = SoftReference.dereference(o2);
|
||||
if (p1 == null || p2 == null) {
|
||||
return p1 != null ? -1 : p2 != null ? 1 : 0; // null references to the end
|
||||
}
|
||||
public int compare(SmartPsiElementPointerImpl p1, SmartPsiElementPointerImpl p2) {
|
||||
return MarkerCache.INFO_COMPARATOR.compare((SelfElementInfo)p1.getElementInfo(), (SelfElementInfo)p2.getElementInfo());
|
||||
}
|
||||
});
|
||||
nextAvailableIndex = hardRefs.size();
|
||||
|
||||
for (int i = 0; i < pointers.size(); i++) {
|
||||
storePointerReference(references, i, pointers.get(i).pointerReference);
|
||||
}
|
||||
Arrays.fill(references, pointers.size(), nextAvailableIndex, null);
|
||||
nextAvailableIndex = pointers.size();
|
||||
mySorted = true;
|
||||
}
|
||||
}
|
||||
|
||||
List<SelfElementInfo> infos = ContainerUtil.newArrayListWithCapacity(size);
|
||||
for (int i = 0; i < nextAvailableIndex; i++) {
|
||||
Reference<SmartPsiElementPointerImpl> reference = references[i];
|
||||
SmartPsiElementPointerImpl pointer = SoftReference.dereference(reference);
|
||||
if (pointer != null) {
|
||||
private static void storePointerReference(PointerReference[] references, int index, PointerReference ref) {
|
||||
references[index] = ref;
|
||||
ref.index = index;
|
||||
}
|
||||
|
||||
synchronized List<SelfElementInfo> getSortedInfos() {
|
||||
ensureSorted();
|
||||
|
||||
final List<SelfElementInfo> infos = ContainerUtil.newArrayListWithCapacity(size);
|
||||
processAlivePointers(new Processor<SmartPsiElementPointerImpl>() {
|
||||
@Override
|
||||
public boolean process(SmartPsiElementPointerImpl pointer) {
|
||||
SelfElementInfo info = (SelfElementInfo)pointer.getElementInfo();
|
||||
if (!info.hasRange()) break;
|
||||
if (!info.hasRange()) return false;
|
||||
|
||||
infos.add(info);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
});
|
||||
return infos;
|
||||
}
|
||||
|
||||
|
||||
+1
@@ -46,6 +46,7 @@ class SmartPsiElementPointerImpl<E extends PsiElement> implements SmartPointerEx
|
||||
private final SmartPointerElementInfo myElementInfo;
|
||||
private final Class<? extends PsiElement> myElementClass;
|
||||
private byte myReferenceCount = 1;
|
||||
@Nullable SmartPointerManagerImpl.PointerReference pointerReference;
|
||||
|
||||
SmartPsiElementPointerImpl(@NotNull Project project, @NotNull E element, @Nullable PsiFile containingFile, boolean forInjected) {
|
||||
this(element, createElementInfo(project, element, containingFile, forInjected), element.getClass());
|
||||
|
||||
+1
-3
@@ -54,9 +54,7 @@ import java.util.Set;
|
||||
* A: There are two ways. The easier and preferred one is to provide constructor in your contributor and register completion providers there:
|
||||
* {@link #extend(CompletionType, ElementPattern, CompletionProvider)}.<br>
|
||||
* A more generic way is to override default {@link #fillCompletionVariants(CompletionParameters, CompletionResultSet)} implementation
|
||||
* and provide your own. It's easier to debug, but harder to write. Remember, that completion variant collection is done in a dedicated thread
|
||||
* WITHOUT read action, so you'll have to manually invoke {@link com.intellij.openapi.application.Application#runReadAction(Runnable)} each time
|
||||
* you access PSI. Don't spend long time inside read action, since this will prevent user from selecting lookup element or cancelling completion.<p>
|
||||
* and provide your own. It's easier to debug, but harder to write.<p>
|
||||
*
|
||||
* Q: What does the {@link CompletionParameters#getPosition()} return?<br>
|
||||
* A: When completion is invoked, the file being edited is first copied (the original file can be accessed from {@link com.intellij.psi.PsiFile#getOriginalFile()}
|
||||
|
||||
@@ -19,10 +19,10 @@ import com.intellij.openapi.Disposable;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.editor.RangeMarker;
|
||||
import com.intellij.openapi.progress.ProgressManager;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import gnu.trove.THashMap;
|
||||
import gnu.trove.THashSet;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
@@ -48,10 +48,10 @@ public class OffsetMap implements Disposable {
|
||||
public int getOffset(OffsetKey key) {
|
||||
synchronized (myMap) {
|
||||
final RangeMarker marker = myMap.get(key);
|
||||
if (marker == null) return -1;
|
||||
if (marker == null) throw new IllegalArgumentException("Offset " + key + " is not registered");
|
||||
if (!marker.isValid()) {
|
||||
removeOffset(key);
|
||||
return -1;
|
||||
throw new IllegalStateException("Offset " + key + " is invalid: " + marker);
|
||||
}
|
||||
|
||||
final int endOffset = marker.getEndOffset();
|
||||
@@ -62,6 +62,11 @@ public class OffsetMap implements Disposable {
|
||||
}
|
||||
}
|
||||
|
||||
public boolean containsOffset(OffsetKey key) {
|
||||
final RangeMarker marker = myMap.get(key);
|
||||
return marker != null && marker.isValid();
|
||||
}
|
||||
|
||||
/**
|
||||
* Register key-offset binding. Offset will change together with {@link Document} editing operations
|
||||
* unless an operation replaces completely the offset vicinity.
|
||||
@@ -108,7 +113,7 @@ public class OffsetMap implements Disposable {
|
||||
synchronized (myMap) {
|
||||
ProgressManager.checkCanceled();
|
||||
assert !myDisposed;
|
||||
return new ArrayList<OffsetKey>(myMap.keySet());
|
||||
return ContainerUtil.filter(myMap.keySet(), this::containsOffset);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+3
-4
@@ -566,10 +566,9 @@ public class CodeCompletionHandlerBase {
|
||||
final Editor editor = indicator.getEditor();
|
||||
|
||||
final int caretOffset = indicator.getCaret().getOffset();
|
||||
int idEndOffset = indicator.getIdentifierEndOffset();
|
||||
if (idEndOffset < 0) {
|
||||
idEndOffset = CompletionInitializationContext.calcDefaultIdentifierEnd(editor, caretOffset);
|
||||
}
|
||||
final int idEndOffset = indicator.getOffsetMap().containsOffset(CompletionInitializationContext.IDENTIFIER_END_OFFSET) ?
|
||||
indicator.getIdentifierEndOffset() :
|
||||
CompletionInitializationContext.calcDefaultIdentifierEnd(editor, caretOffset);
|
||||
final int idEndOffsetDelta = idEndOffset - caretOffset;
|
||||
|
||||
CompletionAssertions.WatchingInsertionContext context;
|
||||
|
||||
+8
-2
@@ -18,6 +18,8 @@ package com.intellij.codeInsight.completion;
|
||||
import com.intellij.codeInsight.lookup.LookupElement;
|
||||
import com.intellij.codeInsight.lookup.LookupElementBuilder;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.project.DumbAware;
|
||||
import com.intellij.openapi.util.Key;
|
||||
import com.intellij.psi.PsiDocumentManager;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.ui.StringComboboxEditor;
|
||||
@@ -28,7 +30,9 @@ import javax.swing.*;
|
||||
/**
|
||||
* @author peter
|
||||
*/
|
||||
public class ComboEditorCompletionContributor extends CompletionContributor{
|
||||
public class ComboEditorCompletionContributor extends CompletionContributor implements DumbAware {
|
||||
|
||||
public static final Key<Boolean> CONTINUE_RUN_COMPLETION = Key.create("CONTINUE_RUN_COMPLETION");
|
||||
|
||||
@Override
|
||||
public void fillCompletionVariants(@NotNull final CompletionParameters parameters, @NotNull final CompletionResultSet result) {
|
||||
@@ -60,7 +64,9 @@ public class ComboEditorCompletionContributor extends CompletionContributor{
|
||||
}), count-i));
|
||||
}
|
||||
}
|
||||
result.stopHere();
|
||||
if (!Boolean.TRUE.equals(document.getUserData(CONTINUE_RUN_COMPLETION))) {
|
||||
result.stopHere();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+7
-1
@@ -462,6 +462,10 @@ public class CompletionLookupArranger extends LookupArranger {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!context.getOffsetMap().containsOffset(CompletionInitializationContext.START_OFFSET)) {
|
||||
return;
|
||||
}
|
||||
|
||||
final Document document = context.getDocument();
|
||||
int startOffset = context.getStartOffset();
|
||||
int tailOffset = context.getEditor().getCaretModel().getOffset();
|
||||
@@ -550,7 +554,9 @@ public class CompletionLookupArranger extends LookupArranger {
|
||||
|
||||
public void addSparedChars(CompletionProgressIndicator indicator, LookupElement item, InsertionContext context, char completionChar) {
|
||||
String textInserted;
|
||||
if (context.getStartOffset() >= 0 && context.getTailOffset() >= context.getStartOffset()) {
|
||||
if (context.getOffsetMap().containsOffset(CompletionInitializationContext.START_OFFSET) &&
|
||||
context.getOffsetMap().containsOffset(InsertionContext.TAIL_OFFSET) &&
|
||||
context.getTailOffset() >= context.getStartOffset()) {
|
||||
textInserted = context.getDocument().getImmutableCharSequence().subSequence(context.getStartOffset(), context.getTailOffset()).toString();
|
||||
} else {
|
||||
textInserted = item.getLookupString();
|
||||
|
||||
+14
-4
@@ -35,18 +35,17 @@ import com.intellij.openapi.fileEditor.FileEditor;
|
||||
import com.intellij.openapi.fileEditor.FileEditorManager;
|
||||
import com.intellij.openapi.fileEditor.TextEditor;
|
||||
import com.intellij.openapi.fileEditor.ex.FileEditorManagerEx;
|
||||
import com.intellij.openapi.fileTypes.FileType;
|
||||
import com.intellij.openapi.progress.ProcessCanceledException;
|
||||
import com.intellij.openapi.progress.ProgressIndicator;
|
||||
import com.intellij.openapi.progress.ProgressManager;
|
||||
import com.intellij.openapi.project.DumbAwareRunnable;
|
||||
import com.intellij.openapi.project.DumbService;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Condition;
|
||||
import com.intellij.openapi.util.Key;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.util.Consumer;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.containers.MultiMap;
|
||||
import gnu.trove.THashMap;
|
||||
@@ -57,7 +56,10 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.TestOnly;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.concurrent.*;
|
||||
import java.util.concurrent.CancellationException;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
@@ -506,10 +508,18 @@ class PassExecutorService implements Disposable {
|
||||
pass.applyInformationToEditor();
|
||||
}
|
||||
}
|
||||
catch (RuntimeException e) {
|
||||
catch (ProcessCanceledException e) {
|
||||
log(updateProgress, pass, "Error " + e);
|
||||
throw e;
|
||||
}
|
||||
catch (RuntimeException e) {
|
||||
Document document = pass.getDocument();
|
||||
VirtualFile file = document == null ? null : FileDocumentManager.getInstance().getFile(document);
|
||||
FileType fileType = file == null ? null : file.getFileType();
|
||||
String message = "Exception while applying information to " + fileEditor + "("+fileType+")";
|
||||
log(updateProgress, pass, message + e);
|
||||
throw new RuntimeException(message, e);
|
||||
}
|
||||
if (threadsToStartCountdown.decrementAndGet() == 0) {
|
||||
log(updateProgress, pass, "Stopping ");
|
||||
updateProgress.stopIfRunning();
|
||||
|
||||
@@ -767,13 +767,15 @@ public class FileBasedIndexImpl extends FileBasedIndex {
|
||||
}
|
||||
}
|
||||
|
||||
processValuesImpl(indexId, dataKey, true, restrictToFile, new ValueProcessor<V>() {
|
||||
@Override
|
||||
public boolean process(final VirtualFile file, final V value) {
|
||||
values.add(value);
|
||||
return true;
|
||||
}
|
||||
}, filter, null);
|
||||
ValueProcessor<V> processor = (file, value) -> {
|
||||
values.add(value);
|
||||
return true;
|
||||
};
|
||||
if (restrictToFile != null) {
|
||||
processValuesInOneFile(indexId, dataKey, restrictToFile, processor, filter);
|
||||
} else {
|
||||
processValuesInScope(indexId, dataKey, true, filter, null, processor);
|
||||
}
|
||||
return values;
|
||||
}
|
||||
|
||||
@@ -783,13 +785,10 @@ public class FileBasedIndexImpl extends FileBasedIndex {
|
||||
@NotNull K dataKey,
|
||||
@NotNull final GlobalSearchScope filter) {
|
||||
final Set<VirtualFile> files = new THashSet<VirtualFile>();
|
||||
processValuesImpl(indexId, dataKey, false, null, new ValueProcessor<V>() {
|
||||
@Override
|
||||
public boolean process(final VirtualFile file, final V value) {
|
||||
files.add(file);
|
||||
return true;
|
||||
}
|
||||
}, filter, null);
|
||||
processValuesInScope(indexId, dataKey, false, filter, null, (file, value) -> {
|
||||
files.add(file);
|
||||
return true;
|
||||
});
|
||||
return files;
|
||||
}
|
||||
|
||||
@@ -807,7 +806,40 @@ public class FileBasedIndexImpl extends FileBasedIndex {
|
||||
@NotNull ValueProcessor<V> processor,
|
||||
@NotNull GlobalSearchScope filter,
|
||||
@Nullable IdFilter idFilter) {
|
||||
return processValuesImpl(indexId, dataKey, false, inFile, processor, filter, idFilter);
|
||||
return inFile != null
|
||||
? processValuesInOneFile(indexId, dataKey, inFile, processor, filter)
|
||||
: processValuesInScope(indexId, dataKey, false, filter, idFilter, processor);
|
||||
}
|
||||
|
||||
public interface IdValueProcessor<V> {
|
||||
/**
|
||||
* @param fileId the id of the file that the value came from
|
||||
* @param value a value to process
|
||||
* @return false if no further processing is needed, true otherwise
|
||||
*/
|
||||
boolean process(int fileId, V value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Process values for a given index key together with their containing file ids. Note that project is supplied
|
||||
* only to ensure that all the indices in that project are up to date; there's no guarantee that the processed file ids belong
|
||||
* to this project.
|
||||
*/
|
||||
public <K, V> boolean processAllValues(@NotNull ID<K, V> indexId,
|
||||
@NotNull K key,
|
||||
@NotNull Project project,
|
||||
@NotNull IdValueProcessor<V> processor) {
|
||||
return processValueIterator(indexId, key, null, GlobalSearchScope.allScope(project), valueIt -> {
|
||||
while (valueIt.hasNext()) {
|
||||
V value = valueIt.next();
|
||||
for (ValueContainer.IntIterator inputIdsIterator = valueIt.getInputIdsIterator(); inputIdsIterator.hasNext(); ) {
|
||||
if (!processor.process(inputIdsIterator.next(), value)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@@ -854,54 +886,61 @@ public class FileBasedIndexImpl extends FileBasedIndex {
|
||||
return null;
|
||||
}
|
||||
|
||||
private <K, V> boolean processValuesImpl(@NotNull final ID<K, V> indexId, @NotNull final K dataKey, final boolean ensureValueProcessedOnce,
|
||||
@Nullable final VirtualFile restrictToFile, @NotNull final ValueProcessor<V> processor,
|
||||
@NotNull final GlobalSearchScope scope, @Nullable final IdFilter idFilter) {
|
||||
ThrowableConvertor<UpdatableIndex<K, V, FileContent>, Boolean, StorageException> keyProcessor =
|
||||
index -> {
|
||||
final ValueContainer<V> container = index.getData(dataKey);
|
||||
private <K, V> boolean processValuesInOneFile(@NotNull ID<K, V> indexId,
|
||||
@NotNull K dataKey,
|
||||
@NotNull VirtualFile restrictToFile,
|
||||
@NotNull ValueProcessor<V> processor, @NotNull GlobalSearchScope scope) {
|
||||
if (!(restrictToFile instanceof VirtualFileWithId)) return true;
|
||||
|
||||
boolean shouldContinue = true;
|
||||
int restrictedFileId = getFileId(restrictToFile);
|
||||
return processValueIterator(indexId, dataKey, restrictToFile, scope, valueIt -> {
|
||||
while (valueIt.hasNext()) {
|
||||
V value = valueIt.next();
|
||||
if (valueIt.getValueAssociationPredicate().contains(restrictedFileId) && !processor.process(restrictToFile, value)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
if (restrictToFile != null) {
|
||||
if (restrictToFile instanceof VirtualFileWithId) {
|
||||
final int restrictedFileId = getFileId(restrictToFile);
|
||||
for (final ValueContainer.ValueIterator<V> valueIt = container.getValueIterator(); valueIt.hasNext(); ) {
|
||||
final V value = valueIt.next();
|
||||
if (valueIt.getValueAssociationPredicate().contains(restrictedFileId)) {
|
||||
shouldContinue = processor.process(restrictToFile, value);
|
||||
if (!shouldContinue) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
private <K, V> boolean processValuesInScope(@NotNull ID<K, V> indexId,
|
||||
@NotNull K dataKey,
|
||||
boolean ensureValueProcessedOnce,
|
||||
@NotNull GlobalSearchScope scope,
|
||||
@Nullable IdFilter idFilter,
|
||||
@NotNull ValueProcessor<V> processor) {
|
||||
PersistentFS fs = (PersistentFS)ManagingFS.getInstance();
|
||||
IdFilter filter = idFilter != null ? idFilter : projectIndexableFiles(scope.getProject());
|
||||
|
||||
return processValueIterator(indexId, dataKey, null, scope, valueIt -> {
|
||||
while (valueIt.hasNext()) {
|
||||
final V value = valueIt.next();
|
||||
for (final ValueContainer.IntIterator inputIdsIterator = valueIt.getInputIdsIterator(); inputIdsIterator.hasNext(); ) {
|
||||
final int id = inputIdsIterator.next();
|
||||
if (filter != null && !filter.containsFileId(id)) continue;
|
||||
VirtualFile file = IndexInfrastructure.findFileByIdIfCached(fs, id);
|
||||
if (file != null && scope.accept(file)) {
|
||||
if (!processor.process(file, value)) {
|
||||
return false;
|
||||
}
|
||||
if (ensureValueProcessedOnce) {
|
||||
break; // continue with the next value
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
final PersistentFS fs = (PersistentFS)ManagingFS.getInstance();
|
||||
final IdFilter filter = idFilter != null ? idFilter : projectIndexableFiles(scope.getProject());
|
||||
VALUES_LOOP:
|
||||
for (final ValueContainer.ValueIterator<V> valueIt = container.getValueIterator(); valueIt.hasNext(); ) {
|
||||
final V value = valueIt.next();
|
||||
for (final ValueContainer.IntIterator inputIdsIterator = valueIt.getInputIdsIterator(); inputIdsIterator.hasNext(); ) {
|
||||
final int id = inputIdsIterator.next();
|
||||
if (filter != null && !filter.containsFileId(id)) continue;
|
||||
VirtualFile file = IndexInfrastructure.findFileByIdIfCached(fs, id);
|
||||
if (file != null && scope.accept(file)) {
|
||||
shouldContinue = processor.process(file, value);
|
||||
if (!shouldContinue) {
|
||||
break VALUES_LOOP;
|
||||
}
|
||||
if (ensureValueProcessedOnce) {
|
||||
break; // continue with the next value
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return shouldContinue;
|
||||
};
|
||||
final Boolean result = processExceptions(indexId, restrictToFile, scope, keyProcessor);
|
||||
}
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
private <K, V> boolean processValueIterator(@NotNull ID<K, V> indexId,
|
||||
@NotNull K dataKey,
|
||||
@Nullable VirtualFile restrictToFile,
|
||||
@NotNull GlobalSearchScope scope,
|
||||
@NotNull Processor<ValueContainer.ValueIterator<V>> valueProcessor) {
|
||||
final Boolean result = processExceptions(indexId, restrictToFile, scope,
|
||||
index -> valueProcessor.process(index.getData(dataKey).getValueIterator()));
|
||||
return result == null || result.booleanValue();
|
||||
}
|
||||
|
||||
|
||||
@@ -21,7 +21,6 @@ import com.intellij.util.SmartList;
|
||||
import com.intellij.util.containers.EmptyIterator;
|
||||
import com.intellij.util.indexing.containers.ChangeBufferingList;
|
||||
import com.intellij.util.indexing.containers.IdSet;
|
||||
import com.intellij.util.indexing.containers.SortedFileIdSetIterator;
|
||||
import com.intellij.util.io.DataExternalizer;
|
||||
import com.intellij.util.io.DataInputOutputUtil;
|
||||
import gnu.trove.THashMap;
|
||||
@@ -447,11 +446,8 @@ class ValueContainerImpl<Value> extends UpdatableValueContainer<Value> implement
|
||||
} else {
|
||||
// serialize positive file ids with delta encoding
|
||||
ChangeBufferingList originalInput = (ChangeBufferingList)fileSetObject;
|
||||
IntIterator intIterator = originalInput.rawIntIterator();
|
||||
if (!intIterator.hasAscendingOrder()) {
|
||||
// remove possible dupes
|
||||
intIterator = SortedFileIdSetIterator.getTransientIterator(intIterator);
|
||||
}
|
||||
IntIterator intIterator = originalInput.sortedIntIterator();
|
||||
if (DebugAssertions.DEBUG) DebugAssertions.assertTrue(intIterator.hasAscendingOrder());
|
||||
|
||||
if (intIterator.size() == 1) {
|
||||
DataInputOutputUtil.writeINT(out, intIterator.next());
|
||||
|
||||
+50
-21
@@ -19,6 +19,8 @@ import com.intellij.util.indexing.DebugAssertions;
|
||||
import com.intellij.util.indexing.ValueContainer;
|
||||
import gnu.trove.TIntProcedure;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import static com.intellij.util.indexing.DebugAssertions.EXTRA_SANITY_CHECKS;
|
||||
|
||||
/**
|
||||
@@ -122,7 +124,6 @@ public class ChangeBufferingList implements Cloneable {
|
||||
|
||||
if (randomAccessContainer == null) {
|
||||
int someElementsNumberEstimation = length;
|
||||
int[] minMax = calcMinMax(changes, length);
|
||||
|
||||
// todo we can check these lengths instead of only relying upon reaching MAX_FILES
|
||||
//int lengthOfBitSet = IdBitSet.sizeInBytes(minMax[1], minMax[0]);
|
||||
@@ -131,7 +132,7 @@ public class ChangeBufferingList implements Cloneable {
|
||||
if (someElementsNumberEstimation < MAX_FILES) {
|
||||
if (!hasRemovals) {
|
||||
if (mayHaveDupes) {
|
||||
mergeChangesRemovingDupes();
|
||||
removingDupesAndSort();
|
||||
}
|
||||
idSet = new SortedIdSet(currentChanges, length);
|
||||
|
||||
@@ -144,7 +145,7 @@ public class ChangeBufferingList implements Cloneable {
|
||||
idSet = new IdBitSet(changes, length, 0);
|
||||
copyChanges = false;
|
||||
} else {
|
||||
idSet = new IdBitSet(minMax, 0);
|
||||
idSet = new IdBitSet(calcMinMax(changes, length), 0);
|
||||
}
|
||||
} else if (checkSet != null) {
|
||||
idSet = (RandomAccessIntContainer)randomAccessContainer.clone();
|
||||
@@ -186,15 +187,40 @@ public class ChangeBufferingList implements Cloneable {
|
||||
}
|
||||
}
|
||||
|
||||
private void mergeChangesRemovingDupes() { // duplicated ids can be present for some index due to cancellation of indexing for next index
|
||||
int[] currentChanges = changes;
|
||||
ValueContainer.IntIterator sorted = SortedFileIdSetIterator.getTransientIterator(new ChangesIterator(currentChanges, length));
|
||||
int lastIndex = 0;
|
||||
while(sorted.hasNext()) {
|
||||
currentChanges[lastIndex++] = sorted.next();
|
||||
}
|
||||
private void removingDupesAndSort() { // duplicated ids can be present for some index due to cancellation of indexing for next index
|
||||
final int[] currentChanges = changes;
|
||||
final int intLength = length;
|
||||
|
||||
length = (short)lastIndex;
|
||||
if (intLength < 250) { // Plain sorting in Arrays works without allocations for small number of elements (see DualPivotQuicksort.QUICKSORT_THRESHOLD)
|
||||
Arrays.sort(currentChanges, 0, intLength);
|
||||
boolean hasDupes = false;
|
||||
|
||||
for(int i = 0, max = intLength - 1; i < max; ++i) {
|
||||
if (currentChanges[i] == currentChanges[i + 1]) {
|
||||
hasDupes = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (hasDupes) {
|
||||
int ptr = 0;
|
||||
for(int i = 1; i < intLength; ++i) {
|
||||
if (currentChanges[i] != currentChanges[ptr]) {
|
||||
currentChanges[++ptr] = currentChanges[i];
|
||||
}
|
||||
}
|
||||
length = (short)(ptr + 1);
|
||||
}
|
||||
} else {
|
||||
ValueContainer.IntIterator sorted =
|
||||
SortedFileIdSetIterator.getTransientIterator(new ChangesIterator(currentChanges, length, false));
|
||||
int lastIndex = 0;
|
||||
while (sorted.hasNext()) {
|
||||
currentChanges[lastIndex++] = sorted.next();
|
||||
}
|
||||
|
||||
length = (short)lastIndex;
|
||||
}
|
||||
mayHaveDupes = false;
|
||||
}
|
||||
|
||||
@@ -262,21 +288,22 @@ public class ChangeBufferingList implements Cloneable {
|
||||
if (currentChanges != null) {
|
||||
if (mayHaveDupes) {
|
||||
synchronized (currentChanges) {
|
||||
if (mayHaveDupes) mergeChangesRemovingDupes();
|
||||
if (mayHaveDupes) removingDupesAndSort();
|
||||
}
|
||||
}
|
||||
return new ChangesIterator(currentChanges, length);
|
||||
return new ChangesIterator(currentChanges, length, true);
|
||||
}
|
||||
}
|
||||
return getRandomAccessContainer().intIterator();
|
||||
}
|
||||
|
||||
public ValueContainer.IntIterator rawIntIterator() {
|
||||
RandomAccessIntContainer intContainer = randomAccessContainer;
|
||||
if (intContainer == null && !hasRemovals) {
|
||||
return new ChangesIterator(changes, length); // dupes are possible
|
||||
public ValueContainer.IntIterator sortedIntIterator() {
|
||||
ValueContainer.IntIterator intIterator = intIterator();
|
||||
|
||||
if (!intIterator.hasAscendingOrder()) {
|
||||
intIterator = SortedFileIdSetIterator.getTransientIterator(intIterator);
|
||||
}
|
||||
return getRandomAccessContainer().intIterator();
|
||||
return intIterator;
|
||||
}
|
||||
|
||||
public IdSet getCheckSet() {
|
||||
@@ -287,10 +314,12 @@ public class ChangeBufferingList implements Cloneable {
|
||||
private int cursor;
|
||||
private final int length;
|
||||
private final int[] changes;
|
||||
private final boolean sorted;
|
||||
|
||||
ChangesIterator(int[] _changes, int _length) {
|
||||
ChangesIterator(int[] _changes, int _length, boolean _sorted) {
|
||||
changes = _changes;
|
||||
length = _length;
|
||||
sorted = _sorted;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -312,12 +341,12 @@ public class ChangeBufferingList implements Cloneable {
|
||||
|
||||
@Override
|
||||
public boolean hasAscendingOrder() {
|
||||
return false;
|
||||
return sorted;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ValueContainer.IntIterator createCopyInInitialState() {
|
||||
return new ChangesIterator(changes, length);
|
||||
return new ChangesIterator(changes, length, sorted);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -50,7 +50,7 @@ public class TextEditorLocation implements FileEditorLocation {
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(FileEditorLocation fileEditorLocation) {
|
||||
public int compareTo(@NotNull FileEditorLocation fileEditorLocation) {
|
||||
TextEditorLocation otherLocation = (TextEditorLocation)fileEditorLocation;
|
||||
if (myEditor != otherLocation.myEditor) {
|
||||
LOG.error("Different editors: " + myEditor + "; and " + otherLocation.myEditor);
|
||||
|
||||
@@ -29,7 +29,7 @@ import java.awt.event.InputEvent;
|
||||
|
||||
public interface ToolWindow extends BusyObject {
|
||||
|
||||
Key<Boolean> SHOW_CONTENT_ICON = new Key<Boolean>("ContentIcon");
|
||||
Key<Boolean> SHOW_CONTENT_ICON = new Key<>("ContentIcon");
|
||||
|
||||
/**
|
||||
* @exception IllegalStateException if tool window isn't installed.
|
||||
@@ -74,7 +74,7 @@ public interface ToolWindow extends BusyObject {
|
||||
/**
|
||||
* @exception IllegalStateException if tool window isn't installed.
|
||||
*/
|
||||
void setAnchor(ToolWindowAnchor anchor, @Nullable Runnable runnable);
|
||||
void setAnchor(@NotNull ToolWindowAnchor anchor, @Nullable Runnable runnable);
|
||||
|
||||
/**
|
||||
* @exception IllegalStateException if tool window isn't installed.
|
||||
@@ -104,7 +104,7 @@ public interface ToolWindow extends BusyObject {
|
||||
/**
|
||||
* @exception IllegalStateException if tool window isn't installed.
|
||||
*/
|
||||
void setType(ToolWindowType type, @Nullable Runnable runnable);
|
||||
void setType(@NotNull ToolWindowType type, @Nullable Runnable runnable);
|
||||
|
||||
/**
|
||||
* @return window icon. Returns <code>null</code> if window has no icon.
|
||||
|
||||
@@ -17,6 +17,7 @@ package com.intellij.openapi.wm;
|
||||
|
||||
import com.intellij.ide.ui.UISettings;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.swing.*;
|
||||
|
||||
@@ -26,9 +27,10 @@ public final class ToolWindowAnchor {
|
||||
public static final ToolWindowAnchor BOTTOM = new ToolWindowAnchor("bottom");
|
||||
public static final ToolWindowAnchor RIGHT = new ToolWindowAnchor("right");
|
||||
|
||||
@NotNull
|
||||
private final String myText;
|
||||
|
||||
private ToolWindowAnchor(@NonNls String text){
|
||||
private ToolWindowAnchor(@NonNls @NotNull String text){
|
||||
myText = text;
|
||||
}
|
||||
|
||||
@@ -40,6 +42,7 @@ public final class ToolWindowAnchor {
|
||||
return this == TOP || this == BOTTOM;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static ToolWindowAnchor get(int swingOrientationConstant) {
|
||||
switch(swingOrientationConstant) {
|
||||
case SwingConstants.TOP:
|
||||
@@ -56,12 +59,16 @@ public final class ToolWindowAnchor {
|
||||
}
|
||||
|
||||
public boolean isSplitVertically() {
|
||||
return (this == LEFT && !UISettings.getInstance().LEFT_HORIZONTAL_SPLIT) || (this == RIGHT && !UISettings.getInstance().RIGHT_HORIZONTAL_SPLIT);
|
||||
return this == LEFT && !UISettings.getInstance().LEFT_HORIZONTAL_SPLIT
|
||||
|| this == RIGHT && !UISettings.getInstance().RIGHT_HORIZONTAL_SPLIT;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static ToolWindowAnchor fromText(String anchor) {
|
||||
for (ToolWindowAnchor a : new ToolWindowAnchor[]{TOP, LEFT, BOTTOM, RIGHT}) {
|
||||
if (a.myText.equals(anchor)) return a;
|
||||
if (a.myText.equals(anchor)) {
|
||||
return a;
|
||||
}
|
||||
}
|
||||
throw new IllegalArgumentException("Unknown anchor constant: " + anchor);
|
||||
}
|
||||
|
||||
@@ -73,7 +73,7 @@ public abstract class ToolWindowManager {
|
||||
public abstract ToolWindow registerToolWindow(@NotNull String id,
|
||||
@NotNull JComponent component,
|
||||
@NotNull ToolWindowAnchor anchor,
|
||||
Disposable parentDisposable,
|
||||
@NotNull Disposable parentDisposable,
|
||||
boolean canWorkInDumbMode);
|
||||
/**
|
||||
* @deprecated {@link ToolWindowManager#registerToolWindow(String, boolean, ToolWindowAnchor)}
|
||||
@@ -83,7 +83,7 @@ public abstract class ToolWindowManager {
|
||||
public abstract ToolWindow registerToolWindow(@NotNull String id,
|
||||
@NotNull JComponent component,
|
||||
@NotNull ToolWindowAnchor anchor,
|
||||
Disposable parentDisposable,
|
||||
@NotNull Disposable parentDisposable,
|
||||
boolean canWorkInDumbMode,
|
||||
boolean canCloseContents);
|
||||
|
||||
@@ -91,19 +91,31 @@ public abstract class ToolWindowManager {
|
||||
public abstract ToolWindow registerToolWindow(@NotNull String id, boolean canCloseContent, @NotNull ToolWindowAnchor anchor);
|
||||
|
||||
@NotNull
|
||||
public abstract ToolWindow registerToolWindow(@NotNull String id, boolean canCloseContent, @NotNull ToolWindowAnchor anchor, boolean secondary);
|
||||
public abstract ToolWindow registerToolWindow(@NotNull String id,
|
||||
boolean canCloseContent,
|
||||
@NotNull ToolWindowAnchor anchor,
|
||||
boolean secondary);
|
||||
|
||||
@NotNull
|
||||
public abstract ToolWindow registerToolWindow(@NotNull String id, boolean canCloseContent, @NotNull ToolWindowAnchor anchor, Disposable parentDisposable, boolean canWorkInDumbMode);
|
||||
public abstract ToolWindow registerToolWindow(@NotNull String id,
|
||||
boolean canCloseContent,
|
||||
@NotNull ToolWindowAnchor anchor,
|
||||
@NotNull Disposable parentDisposable,
|
||||
boolean canWorkInDumbMode);
|
||||
|
||||
@NotNull
|
||||
public abstract ToolWindow registerToolWindow(@NotNull String id, boolean canCloseContent, @NotNull ToolWindowAnchor anchor, Disposable parentDisposable, boolean canWorkInDumbMode, boolean secondary);
|
||||
public abstract ToolWindow registerToolWindow(@NotNull String id,
|
||||
boolean canCloseContent,
|
||||
@NotNull ToolWindowAnchor anchor,
|
||||
@NotNull Disposable parentDisposable,
|
||||
boolean canWorkInDumbMode,
|
||||
boolean secondary);
|
||||
|
||||
@NotNull
|
||||
public ToolWindow registerToolWindow(@NotNull final String id,
|
||||
final boolean canCloseContent,
|
||||
@NotNull final ToolWindowAnchor anchor,
|
||||
final Disposable parentDisposable) {
|
||||
@NotNull Disposable parentDisposable) {
|
||||
return registerToolWindow(id, canCloseContent, anchor, parentDisposable, false);
|
||||
}
|
||||
|
||||
|
||||
@@ -46,9 +46,9 @@ import java.awt.event.*;
|
||||
* @author Alexander Lobas
|
||||
*/
|
||||
public class LightToolWindow extends JPanel {
|
||||
public static final String LEFT_MIN_KEY = "left";
|
||||
public static final String RIGHT_MIN_KEY = "right";
|
||||
public static final int MINIMIZE_WIDTH = 25;
|
||||
static final String LEFT_MIN_KEY = "left";
|
||||
static final String RIGHT_MIN_KEY = "right";
|
||||
static final int MINIMIZE_WIDTH = 25;
|
||||
private static final String IGNORE_WIDTH_KEY = "ignore_width";
|
||||
|
||||
private final LightToolWindowContent myContent;
|
||||
@@ -139,12 +139,14 @@ public class LightToolWindow extends JPanel {
|
||||
add(contentWrapper, BorderLayout.CENTER);
|
||||
|
||||
addMouseListener(new MouseAdapter() {
|
||||
@Override
|
||||
public void mouseReleased(final MouseEvent e) {
|
||||
IdeFocusManager.getInstance(myProject).requestFocus(myFocusedComponent, true);
|
||||
}
|
||||
});
|
||||
|
||||
addMouseListener(new PopupHandler() {
|
||||
@Override
|
||||
public void invokePopup(Component component, int x, int y) {
|
||||
showGearPopup(component, x, y);
|
||||
}
|
||||
@@ -167,12 +169,9 @@ public class LightToolWindow extends JPanel {
|
||||
return myAnchor;
|
||||
}
|
||||
};
|
||||
myMinimizeButton.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
myMinimizeButton.setSelected(false);
|
||||
updateContent(true, true);
|
||||
}
|
||||
myMinimizeButton.addActionListener(e -> {
|
||||
myMinimizeButton.setSelected(false);
|
||||
updateContent(true, true);
|
||||
});
|
||||
myMinimizeButton.setBorder(BorderFactory.createEmptyBorder(5, 5, 0, 5));
|
||||
myMinimizeButton.setFocusable(false);
|
||||
@@ -233,7 +232,7 @@ public class LightToolWindow extends JPanel {
|
||||
}
|
||||
}
|
||||
|
||||
public void updateAnchor(ToolWindowAnchor newAnchor) {
|
||||
void updateAnchor(ToolWindowAnchor newAnchor) {
|
||||
JComponent minimizeParent = myContentSplitter.getInnerComponent();
|
||||
minimizeParent.putClientProperty(IGNORE_WIDTH_KEY, Boolean.TRUE);
|
||||
|
||||
@@ -374,7 +373,7 @@ public class LightToolWindow extends JPanel {
|
||||
}
|
||||
|
||||
private class GearAction extends AnAction {
|
||||
public GearAction() {
|
||||
GearAction() {
|
||||
Presentation presentation = getTemplatePresentation();
|
||||
presentation.setIcon(AllIcons.General.Gear);
|
||||
presentation.setHoveredIcon(AllIcons.General.GearHover);
|
||||
@@ -462,7 +461,7 @@ public class LightToolWindow extends JPanel {
|
||||
}
|
||||
|
||||
private class ToggleWindowedModeAction extends ToggleTypeModeAction {
|
||||
public ToggleWindowedModeAction() {
|
||||
ToggleWindowedModeAction() {
|
||||
super(ToolWindowType.WINDOWED, InternalDecorator.TOGGLE_WINDOWED_MODE_ACTION_ID);
|
||||
}
|
||||
|
||||
@@ -475,7 +474,7 @@ public class LightToolWindow extends JPanel {
|
||||
private class ToggleTypeModeAction extends ToggleAction {
|
||||
private final ToolWindowType myType;
|
||||
|
||||
public ToggleTypeModeAction(ToolWindowType type, String id) {
|
||||
ToggleTypeModeAction(@NotNull ToolWindowType type, @NotNull String id) {
|
||||
myType = type;
|
||||
copyFrom(ActionManager.getInstance().getAction(id));
|
||||
}
|
||||
|
||||
@@ -1,17 +1,16 @@
|
||||
package com.intellij.ide.actions;
|
||||
|
||||
import com.intellij.openapi.actionSystem.AnAction;
|
||||
import com.intellij.openapi.actionSystem.AnActionEvent;
|
||||
import com.intellij.openapi.actionSystem.CommonDataKeys;
|
||||
import com.intellij.openapi.actionSystem.PlatformDataKeys;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.fileEditor.FileDocumentManager;
|
||||
import com.intellij.openapi.project.DumbAwareAction;
|
||||
|
||||
/**
|
||||
* @author yole
|
||||
*/
|
||||
public class SaveDocumentAction extends AnAction {
|
||||
public class SaveDocumentAction extends DumbAwareAction {
|
||||
@Override
|
||||
public void actionPerformed(AnActionEvent e) {
|
||||
Document doc = getDocument(e);
|
||||
|
||||
+3
-2
@@ -2,6 +2,7 @@ package com.intellij.openapi.wm.ex;
|
||||
|
||||
import com.intellij.openapi.fileEditor.ex.FileEditorManagerEx;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.swing.*;
|
||||
|
||||
@@ -10,8 +11,8 @@ import javax.swing.*;
|
||||
*/
|
||||
public class DefaultFrameEditorComponentProvider implements FrameEditorComponentProvider {
|
||||
@Override
|
||||
public JComponent createEditorComponent(Project project) {
|
||||
public JComponent createEditorComponent(@NotNull Project project) {
|
||||
FileEditorManagerEx editorManager = FileEditorManagerEx.getInstanceEx(project);
|
||||
return editorManager.getComponent();
|
||||
return editorManager.getComponent();
|
||||
}
|
||||
}
|
||||
|
||||
+3
-1
@@ -2,14 +2,16 @@ package com.intellij.openapi.wm.ex;
|
||||
|
||||
import com.intellij.openapi.extensions.ExtensionPointName;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.swing.*;
|
||||
|
||||
/**
|
||||
* @author Konstantin Bulenkov
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface FrameEditorComponentProvider {
|
||||
ExtensionPointName<FrameEditorComponentProvider> EP = ExtensionPointName.create("com.intellij.frameEditorComponentProvider");
|
||||
|
||||
JComponent createEditorComponent(Project project);
|
||||
JComponent createEditorComponent(@NotNull Project project);
|
||||
}
|
||||
|
||||
@@ -35,9 +35,9 @@ public abstract class ToolWindowManagerEx extends ToolWindowManager {
|
||||
return (ToolWindowManagerEx)getInstance(project);
|
||||
}
|
||||
|
||||
public abstract void addToolWindowManagerListener(@NotNull ToolWindowManagerListener l);
|
||||
public abstract void addToolWindowManagerListener(@NotNull ToolWindowManagerListener l, @NotNull Disposable parentDisposable);
|
||||
public abstract void removeToolWindowManagerListener(@NotNull ToolWindowManagerListener l);
|
||||
public abstract void addToolWindowManagerListener(@NotNull ToolWindowManagerListener listener);
|
||||
public abstract void addToolWindowManagerListener(@NotNull ToolWindowManagerListener listener, @NotNull Disposable parentDisposable);
|
||||
public abstract void removeToolWindowManagerListener(@NotNull ToolWindowManagerListener listener);
|
||||
|
||||
/**
|
||||
* @return <code>ID</code> of tool window that was activated last time.
|
||||
@@ -69,5 +69,6 @@ public abstract class ToolWindowManagerEx extends ToolWindowManager {
|
||||
|
||||
public abstract void hideToolWindow(@NotNull String id, boolean hideSide);
|
||||
|
||||
@NotNull
|
||||
public abstract List<String> getIdsOn(@NotNull ToolWindowAnchor anchor);
|
||||
}
|
||||
|
||||
@@ -15,8 +15,10 @@
|
||||
*/
|
||||
package com.intellij.openapi.wm.impl;
|
||||
|
||||
import com.intellij.util.containers.Stack;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.Stack;
|
||||
|
||||
/**
|
||||
* Actually this class represent two stacks.
|
||||
@@ -43,8 +45,8 @@ final class ActiveStack {
|
||||
* Creates enabled window stack.
|
||||
*/
|
||||
ActiveStack() {
|
||||
myStack = new Stack<String>();
|
||||
myPersistentStack = new Stack<String>();
|
||||
myStack = new Stack<>();
|
||||
myPersistentStack = new Stack<>();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -61,10 +63,12 @@ final class ActiveStack {
|
||||
return myStack.isEmpty();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
String pop() {
|
||||
return myStack.pop();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
String peek() {
|
||||
return myStack.peek();
|
||||
}
|
||||
@@ -73,10 +77,12 @@ final class ActiveStack {
|
||||
return myStack.size();
|
||||
}
|
||||
|
||||
String peek(int i) {
|
||||
@NotNull
|
||||
private String peek(int i) {
|
||||
return myStack.get(getSize() - i - 1);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
String[] getStack() {
|
||||
String[] result = new String[getSize()];
|
||||
for (int i = 0; i < getSize(); i++) {
|
||||
@@ -85,6 +91,7 @@ final class ActiveStack {
|
||||
return result;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
String[] getPersistentStack() {
|
||||
String[] result = new String[getPersistentSize()];
|
||||
for (int i = 0; i < getPersistentSize(); i++) {
|
||||
@@ -93,7 +100,7 @@ final class ActiveStack {
|
||||
return result;
|
||||
}
|
||||
|
||||
void push(final String id) {
|
||||
void push(@NotNull String id) {
|
||||
remove(id, true);
|
||||
myStack.push(id);
|
||||
myPersistentStack.push(id);
|
||||
@@ -106,6 +113,7 @@ final class ActiveStack {
|
||||
/**
|
||||
* Peeks element at the persistent stack. <code>0</code> means the top of the stack.
|
||||
*/
|
||||
@NotNull
|
||||
String peekPersistent(final int index) {
|
||||
return myPersistentStack.get(myPersistentStack.size() - index - 1);
|
||||
}
|
||||
@@ -117,7 +125,7 @@ final class ActiveStack {
|
||||
* @param removePersistentAlso if <code>true</code> then clears last active <code>ID</code>
|
||||
* if it's the last active <code>ID</code>.
|
||||
*/
|
||||
void remove(final String id, final boolean removePersistentAlso) {
|
||||
void remove(@NotNull String id, final boolean removePersistentAlso) {
|
||||
for (Iterator i = myStack.iterator(); i.hasNext();) {
|
||||
if (id.equals(i.next())) {
|
||||
i.remove();
|
||||
|
||||
@@ -36,11 +36,11 @@ public final class DesktopLayout implements JDOMExternalizable {
|
||||
/**
|
||||
* Map between <code>id</code>s and registered <code>WindowInfo</code>s.
|
||||
*/
|
||||
private final Map<String, WindowInfoImpl> myRegisteredId2Info;
|
||||
private final Map<String, WindowInfoImpl> myRegisteredId2Info = new HashMap<>();
|
||||
/**
|
||||
* Map between <code>id</code>s and unregistered <code>WindowInfo</code>s.
|
||||
*/
|
||||
private final Map<String, WindowInfoImpl> myUnregisteredId2Info;
|
||||
private final Map<String, WindowInfoImpl> myUnregisteredId2Info = new HashMap<>();
|
||||
/**
|
||||
*
|
||||
*/
|
||||
@@ -63,19 +63,15 @@ public final class DesktopLayout implements JDOMExternalizable {
|
||||
* if the cached data is invalid.
|
||||
*/
|
||||
private WindowInfoImpl[] myAllInfos;
|
||||
@NonNls public static final String ID_ATTR = "id";
|
||||
@NonNls private static final String ID_ATTR = "id";
|
||||
|
||||
public DesktopLayout() {
|
||||
myRegisteredId2Info = new HashMap<String, WindowInfoImpl>();
|
||||
myUnregisteredId2Info = new HashMap<String, WindowInfoImpl>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Copies itself from the passed
|
||||
*
|
||||
* @param layout to be copied.
|
||||
*/
|
||||
public final void copyFrom(final DesktopLayout layout) {
|
||||
public final void copyFrom(@NotNull DesktopLayout layout) {
|
||||
final WindowInfoImpl[] infos = layout.getAllInfos();
|
||||
for (WindowInfoImpl info1 : infos) {
|
||||
WindowInfoImpl info = myRegisteredId2Info.get(info1.getId());
|
||||
@@ -128,7 +124,7 @@ public final class DesktopLayout implements JDOMExternalizable {
|
||||
return info;
|
||||
}
|
||||
|
||||
final void unregister(final String id) {
|
||||
final void unregister(@NotNull String id) {
|
||||
final WindowInfoImpl info = myRegisteredId2Info.remove(id).copy();
|
||||
myUnregisteredId2Info.put(id, info);
|
||||
// invalidate caches
|
||||
@@ -142,14 +138,12 @@ public final class DesktopLayout implements JDOMExternalizable {
|
||||
* If <code>onlyRegistered</code> is <code>true</code> then returns not <code>null</code>
|
||||
* value if and only if window with <code>id</code> is registered one.
|
||||
*/
|
||||
final WindowInfoImpl getInfo(final String id, final boolean onlyRegistered) {
|
||||
final WindowInfoImpl getInfo(String id, final boolean onlyRegistered) {
|
||||
final WindowInfoImpl info = myRegisteredId2Info.get(id);
|
||||
if (onlyRegistered || info != null) {
|
||||
return info;
|
||||
}
|
||||
else {
|
||||
return myUnregisteredId2Info.get(id);
|
||||
}
|
||||
return myUnregisteredId2Info.get(id);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@@ -166,6 +160,7 @@ public final class DesktopLayout implements JDOMExternalizable {
|
||||
/**
|
||||
* @return <code>WindowInfo</code>s for all registered tool windows.
|
||||
*/
|
||||
@NotNull
|
||||
final WindowInfoImpl[] getInfos() {
|
||||
if (myRegisteredInfos == null) {
|
||||
myRegisteredInfos = myRegisteredId2Info.values().toArray(new WindowInfoImpl[myRegisteredId2Info.size()]);
|
||||
@@ -176,6 +171,7 @@ public final class DesktopLayout implements JDOMExternalizable {
|
||||
/**
|
||||
* @return <code>WindowInfos</code>s for all windows that are currently unregistered.
|
||||
*/
|
||||
@NotNull
|
||||
private WindowInfoImpl[] getUnregisteredInfos() {
|
||||
if (myUnregisteredInfos == null) {
|
||||
myUnregisteredInfos = myUnregisteredId2Info.values().toArray(new WindowInfoImpl[myUnregisteredId2Info.size()]);
|
||||
@@ -186,7 +182,8 @@ public final class DesktopLayout implements JDOMExternalizable {
|
||||
/**
|
||||
* @return <code>WindowInfo</code>s of all (registered and unregistered) tool windows.
|
||||
*/
|
||||
WindowInfoImpl[] getAllInfos() {
|
||||
@NotNull
|
||||
private WindowInfoImpl[] getAllInfos() {
|
||||
final WindowInfoImpl[] registeredInfos = getInfos();
|
||||
final WindowInfoImpl[] unregisteredInfos = getUnregisteredInfos();
|
||||
myAllInfos = ArrayUtil.mergeArrays(registeredInfos, unregisteredInfos);
|
||||
@@ -197,9 +194,10 @@ public final class DesktopLayout implements JDOMExternalizable {
|
||||
* @return all (registered and not unregistered) <code>WindowInfos</code> for the specified <code>anchor</code>.
|
||||
* Returned infos are sorted by order.
|
||||
*/
|
||||
private WindowInfoImpl[] getAllInfos(final ToolWindowAnchor anchor) {
|
||||
@NotNull
|
||||
private WindowInfoImpl[] getAllInfos(@NotNull ToolWindowAnchor anchor) {
|
||||
WindowInfoImpl[] infos = getAllInfos();
|
||||
final ArrayList<WindowInfoImpl> list = new ArrayList<WindowInfoImpl>(infos.length);
|
||||
final ArrayList<WindowInfoImpl> list = new ArrayList<>(infos.length);
|
||||
for (WindowInfoImpl info : infos) {
|
||||
if (anchor == info.getAnchor()) {
|
||||
list.add(info);
|
||||
@@ -214,7 +212,7 @@ public final class DesktopLayout implements JDOMExternalizable {
|
||||
* Normalizes order of windows in the passed array. Note, that array should be
|
||||
* sorted by order (by ascending). Order of first window will be <code>0</code>.
|
||||
*/
|
||||
private static void normalizeOrder(final WindowInfoImpl[] infos) {
|
||||
private static void normalizeOrder(@NotNull WindowInfoImpl[] infos) {
|
||||
for (int i = 0; i < infos.length; i++) {
|
||||
infos[i].setOrder(i);
|
||||
}
|
||||
@@ -228,7 +226,8 @@ public final class DesktopLayout implements JDOMExternalizable {
|
||||
* @return comparator which compares <code>StripeButtons</code> in the stripe with
|
||||
* specified <code>anchor</code>.
|
||||
*/
|
||||
final Comparator<StripeButton> comparator(final ToolWindowAnchor anchor) {
|
||||
@NotNull
|
||||
final Comparator<StripeButton> comparator(@NotNull ToolWindowAnchor anchor) {
|
||||
return new MyStripeButtonComparator(anchor);
|
||||
}
|
||||
|
||||
@@ -237,7 +236,7 @@ public final class DesktopLayout implements JDOMExternalizable {
|
||||
* @return maximum ordinal number in the specified stripe. Returns <code>-1</code>
|
||||
* if there is no any tool window with the specified anchor.
|
||||
*/
|
||||
private int getMaxOrder(final ToolWindowAnchor anchor) {
|
||||
private int getMaxOrder(@NotNull ToolWindowAnchor anchor) {
|
||||
int res = -1;
|
||||
final WindowInfoImpl[] infos = getAllInfos();
|
||||
for (final WindowInfoImpl info : infos) {
|
||||
@@ -255,7 +254,7 @@ public final class DesktopLayout implements JDOMExternalizable {
|
||||
* @param newAnchor new anchor
|
||||
* @param newOrder new order
|
||||
*/
|
||||
final void setAnchor(final String id, final ToolWindowAnchor newAnchor, int newOrder) {
|
||||
final void setAnchor(@NotNull String id, @NotNull ToolWindowAnchor newAnchor, int newOrder) {
|
||||
if (newOrder == -1) { // if order isn't defined then the window will the last in the stripe
|
||||
newOrder = getMaxOrder(newAnchor) + 1;
|
||||
}
|
||||
@@ -279,11 +278,12 @@ public final class DesktopLayout implements JDOMExternalizable {
|
||||
}
|
||||
}
|
||||
|
||||
final void setSplitMode(final String id, boolean split) {
|
||||
final void setSplitMode(@NotNull String id, boolean split) {
|
||||
final WindowInfoImpl info = getInfo(id, true);
|
||||
info.setSplit(split);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void readExternal(final Element layoutElement) {
|
||||
myUnregisteredInfos = null;
|
||||
for (Object o : layoutElement.getChildren()) {
|
||||
@@ -301,6 +301,7 @@ public final class DesktopLayout implements JDOMExternalizable {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void writeExternal(final Element layoutElement) {
|
||||
final WindowInfoImpl[] infos = getAllInfos();
|
||||
for (WindowInfoImpl info : infos) {
|
||||
@@ -310,30 +311,30 @@ public final class DesktopLayout implements JDOMExternalizable {
|
||||
}
|
||||
}
|
||||
|
||||
public List<String> getVisibleIdsOn(final ToolWindowAnchor anchor, ToolWindowManagerImpl manager) {
|
||||
ArrayList<String> ids = new ArrayList<String>();
|
||||
@NotNull
|
||||
List<String> getVisibleIdsOn(@NotNull ToolWindowAnchor anchor, @NotNull ToolWindowManagerImpl manager) {
|
||||
List<String> ids = new ArrayList<>();
|
||||
for (WindowInfoImpl each : getAllInfos(anchor)) {
|
||||
if (manager == null) break;
|
||||
final ToolWindow window = manager.getToolWindow(each.getId());
|
||||
if (window == null) continue;
|
||||
if (window.isAvailable() || UISettings.getInstance().ALWAYS_SHOW_WINDOW_BUTTONS) {
|
||||
ids.add(each.getId());
|
||||
}
|
||||
final ToolWindow window = manager.getToolWindow(each.getId());
|
||||
if (window == null) continue;
|
||||
if (window.isAvailable() || UISettings.getInstance().ALWAYS_SHOW_WINDOW_BUTTONS) {
|
||||
ids.add(each.getId());
|
||||
}
|
||||
}
|
||||
return ids;
|
||||
}
|
||||
|
||||
private static final class MyWindowInfoComparator implements Comparator<WindowInfoImpl> {
|
||||
@Override
|
||||
public int compare(final WindowInfoImpl info1, final WindowInfoImpl info2) {
|
||||
return info1.getOrder() - info2.getOrder();
|
||||
}
|
||||
}
|
||||
|
||||
private final class MyStripeButtonComparator implements Comparator<StripeButton> {
|
||||
private final HashMap<String, WindowInfoImpl> myId2Info;
|
||||
private final HashMap<String, WindowInfoImpl> myId2Info = new HashMap<>();
|
||||
|
||||
public MyStripeButtonComparator(final ToolWindowAnchor anchor) {
|
||||
myId2Info = new HashMap<String, WindowInfoImpl>();
|
||||
public MyStripeButtonComparator(@NotNull ToolWindowAnchor anchor) {
|
||||
final WindowInfoImpl[] infos = getInfos();
|
||||
for (final WindowInfoImpl info : infos) {
|
||||
if (anchor == info.getAnchor()) {
|
||||
@@ -342,6 +343,7 @@ public final class DesktopLayout implements JDOMExternalizable {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public final int compare(final StripeButton obj1, final StripeButton obj2) {
|
||||
final WindowInfoImpl info1 = myId2Info.get(obj1.getWindowInfo().getId());
|
||||
final int order1 = info1 != null ? info1.getOrder() : 0;
|
||||
|
||||
@@ -28,6 +28,7 @@ import com.intellij.ui.JBColor;
|
||||
import com.intellij.ui.ScreenUtil;
|
||||
import com.intellij.util.Alarm;
|
||||
import com.intellij.util.ui.UIUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
@@ -66,7 +67,7 @@ public final class FloatingDecorator extends JDialog {
|
||||
private float myEndRatio; // start and end alpha ratio for transparency animation
|
||||
|
||||
|
||||
FloatingDecorator(final IdeFrameImpl owner,final WindowInfoImpl info,final InternalDecorator internalDecorator){
|
||||
FloatingDecorator(final IdeFrameImpl owner, @NotNull WindowInfoImpl info, @NotNull InternalDecorator internalDecorator){
|
||||
super(owner,internalDecorator.getToolWindow().getId());
|
||||
MnemonicHelper.init(getContentPane());
|
||||
myInternalDecorator=internalDecorator;
|
||||
@@ -154,7 +155,7 @@ public final class FloatingDecorator extends JDialog {
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
final void apply(final WindowInfoImpl info){
|
||||
final void apply(@NotNull WindowInfoImpl info){
|
||||
LOG.assertTrue(info.isFloating());
|
||||
myInfo=info;
|
||||
// Set alpha mode
|
||||
|
||||
@@ -116,7 +116,7 @@ public final class InternalDecorator extends JPanel implements Queryable, DataPr
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void toolWindowTypeChanged(ToolWindowType type) {
|
||||
protected void toolWindowTypeChanged(@NotNull ToolWindowType type) {
|
||||
fireTypeChanged(type);
|
||||
}
|
||||
|
||||
@@ -214,7 +214,7 @@ public final class InternalDecorator extends JPanel implements Queryable, DataPr
|
||||
myProject = null;
|
||||
}
|
||||
|
||||
private void fireAnchorChanged(ToolWindowAnchor anchor) {
|
||||
private void fireAnchorChanged(@NotNull ToolWindowAnchor anchor) {
|
||||
myDispatcher.getMulticaster().anchorChanged(this, anchor);
|
||||
}
|
||||
|
||||
@@ -243,7 +243,7 @@ public final class InternalDecorator extends JPanel implements Queryable, DataPr
|
||||
myDispatcher.getMulticaster().activated(this);
|
||||
}
|
||||
|
||||
private void fireTypeChanged(ToolWindowType type) {
|
||||
private void fireTypeChanged(@NotNull ToolWindowType type) {
|
||||
myDispatcher.getMulticaster().typeChanged(this, type);
|
||||
}
|
||||
|
||||
@@ -255,7 +255,7 @@ public final class InternalDecorator extends JPanel implements Queryable, DataPr
|
||||
myDispatcher.getMulticaster().sideStatusChanged(this, isSide);
|
||||
}
|
||||
|
||||
private void fireContentUiTypeChanges(ToolWindowContentUiType type) {
|
||||
private void fireContentUiTypeChanges(@NotNull ToolWindowContentUiType type) {
|
||||
myDispatcher.getMulticaster().contentUiTypeChanges(this, type);
|
||||
}
|
||||
|
||||
@@ -512,9 +512,9 @@ public final class InternalDecorator extends JPanel implements Queryable, DataPr
|
||||
}
|
||||
|
||||
private final class ChangeAnchorAction extends AnAction implements DumbAware {
|
||||
private final ToolWindowAnchor myAnchor;
|
||||
@NotNull private final ToolWindowAnchor myAnchor;
|
||||
|
||||
public ChangeAnchorAction(final String title, final ToolWindowAnchor anchor) {
|
||||
public ChangeAnchorAction(@NotNull String title, @NotNull ToolWindowAnchor anchor) {
|
||||
super(title);
|
||||
myAnchor = anchor;
|
||||
}
|
||||
|
||||
+10
-10
@@ -27,23 +27,23 @@ import java.util.EventListener;
|
||||
*/
|
||||
interface InternalDecoratorListener extends EventListener{
|
||||
|
||||
public void anchorChanged(InternalDecorator source,ToolWindowAnchor anchor);
|
||||
void anchorChanged(@NotNull InternalDecorator source, @NotNull ToolWindowAnchor anchor);
|
||||
|
||||
public void autoHideChanged(InternalDecorator source,boolean autoHide);
|
||||
void autoHideChanged(@NotNull InternalDecorator source, boolean autoHide);
|
||||
|
||||
public void hidden(InternalDecorator source);
|
||||
void hidden(@NotNull InternalDecorator source);
|
||||
|
||||
public void hiddenSide(InternalDecorator source);
|
||||
void hiddenSide(@NotNull InternalDecorator source);
|
||||
|
||||
public void resized(InternalDecorator source);
|
||||
void resized(@NotNull InternalDecorator source);
|
||||
|
||||
public void activated(InternalDecorator source);
|
||||
void activated(@NotNull InternalDecorator source);
|
||||
|
||||
public void typeChanged(InternalDecorator source,ToolWindowType type);
|
||||
void typeChanged(@NotNull InternalDecorator source, @NotNull ToolWindowType type);
|
||||
|
||||
public void sideStatusChanged(InternalDecorator source,boolean isSideTool);
|
||||
void sideStatusChanged(@NotNull InternalDecorator source, boolean isSideTool);
|
||||
|
||||
public void contentUiTypeChanges(InternalDecorator sources, @NotNull ToolWindowContentUiType type);
|
||||
void contentUiTypeChanges(@NotNull InternalDecorator sources, @NotNull ToolWindowContentUiType type);
|
||||
|
||||
public void visibleStripeButtonChanged(InternalDecorator source, boolean visible);
|
||||
void visibleStripeButtonChanged(@NotNull InternalDecorator source, boolean visible);
|
||||
}
|
||||
|
||||
@@ -28,6 +28,7 @@ import com.intellij.ui.ColorUtil;
|
||||
import com.intellij.ui.Gray;
|
||||
import com.intellij.ui.ScreenUtil;
|
||||
import com.intellij.util.ui.UIUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.border.Border;
|
||||
@@ -166,7 +167,7 @@ final class Stripe extends JPanel implements UISettingsListener {
|
||||
super.removeNotify();
|
||||
}
|
||||
|
||||
void addButton(final StripeButton button, final Comparator<StripeButton> comparator) {
|
||||
void addButton(@NotNull StripeButton button, final Comparator<StripeButton> comparator) {
|
||||
myPrefSize = null;
|
||||
myButtons.add(button);
|
||||
Collections.sort(myButtons, comparator);
|
||||
@@ -174,7 +175,7 @@ final class Stripe extends JPanel implements UISettingsListener {
|
||||
revalidate();
|
||||
}
|
||||
|
||||
void removeButton(final StripeButton button) {
|
||||
void removeButton(@NotNull StripeButton button) {
|
||||
myPrefSize = null;
|
||||
myButtons.remove(button);
|
||||
remove(button);
|
||||
@@ -475,7 +476,7 @@ final class Stripe extends JPanel implements UISettingsListener {
|
||||
}
|
||||
}
|
||||
|
||||
public boolean containsScreen(final Rectangle screenRec) {
|
||||
public boolean containsScreen(@NotNull Rectangle screenRec) {
|
||||
final Point point = screenRec.getLocation();
|
||||
SwingUtilities.convertPointFromScreen(point, this);
|
||||
return new Rectangle(point, screenRec.getSize()).intersects(
|
||||
|
||||
@@ -49,7 +49,6 @@ import javax.swing.plaf.PanelUI;
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.util.List;
|
||||
|
||||
@@ -74,7 +73,7 @@ public abstract class ToolWindowHeader extends JPanel implements Disposable, UIS
|
||||
private final DefaultActionGroup myActionGroup = new DefaultActionGroup();
|
||||
private List<AnAction> myVisibleActions = ContainerUtil.newArrayListWithCapacity(2);
|
||||
|
||||
public ToolWindowHeader(final ToolWindowImpl toolWindow, @NotNull WindowInfoImpl info, @NotNull final Producer<ActionGroup> gearProducer) {
|
||||
ToolWindowHeader(final ToolWindowImpl toolWindow, @NotNull WindowInfoImpl info, @NotNull final Producer<ActionGroup> gearProducer) {
|
||||
setLayout(new BorderLayout());
|
||||
|
||||
myToolWindow = toolWindow;
|
||||
@@ -89,7 +88,7 @@ public abstract class ToolWindowHeader extends JPanel implements Disposable, UIS
|
||||
|
||||
Component c = getComponent(0);
|
||||
Dimension size = c.getPreferredSize();
|
||||
if (size.width < (r.width - insets.left - insets.right)) {
|
||||
if (size.width < r.width - insets.left - insets.right) {
|
||||
c.setBounds(insets.left, insets.top, size.width, r.height - insets.top - insets.bottom);
|
||||
} else {
|
||||
c.setBounds(insets.left, insets.top, r.width - insets.left - insets.right, r.height - insets.top - insets.bottom);
|
||||
@@ -170,6 +169,7 @@ public abstract class ToolWindowHeader extends JPanel implements Disposable, UIS
|
||||
myButtonPanel = eastPanel;
|
||||
|
||||
westPanel.addMouseListener(new PopupHandler() {
|
||||
@Override
|
||||
public void invokePopup(final Component comp, final int x, final int y) {
|
||||
toolWindow.getContentUI().showContextMenu(comp, x, y, toolWindow.getPopupGroup(), toolWindow.getContentManager().getSelectedContent());
|
||||
}
|
||||
@@ -182,6 +182,7 @@ public abstract class ToolWindowHeader extends JPanel implements Disposable, UIS
|
||||
});
|
||||
|
||||
addMouseListener(new MouseAdapter() {
|
||||
@Override
|
||||
public void mouseReleased(final MouseEvent e) {
|
||||
if (!e.isPopupTrigger()) {
|
||||
if (UIUtil.isCloseClick(e, MouseEvent.MOUSE_RELEASED)) {
|
||||
@@ -227,7 +228,7 @@ public abstract class ToolWindowHeader extends JPanel implements Disposable, UIS
|
||||
@Override
|
||||
public void mouseReleased(final MouseEvent e) {
|
||||
Runnable runnable =
|
||||
() -> ToolWindowHeader.this.dispatchEvent(SwingUtilities.convertMouseEvent(e.getComponent(), e, ToolWindowHeader.this));
|
||||
() -> dispatchEvent(SwingUtilities.convertMouseEvent(e.getComponent(), e, ToolWindowHeader.this));
|
||||
//noinspection SSBasedInspection
|
||||
SwingUtilities.invokeLater(runnable);
|
||||
}
|
||||
@@ -253,7 +254,7 @@ public abstract class ToolWindowHeader extends JPanel implements Disposable, UIS
|
||||
myInfo = null;
|
||||
}
|
||||
|
||||
public void setAdditionalTitleActions(AnAction[] actions) {
|
||||
void setAdditionalTitleActions(AnAction[] actions) {
|
||||
myActionGroup.removeAll();
|
||||
myActionGroup.addAll(actions);
|
||||
myUpdater.updateActions(false, true);
|
||||
@@ -300,7 +301,7 @@ public abstract class ToolWindowHeader extends JPanel implements Disposable, UIS
|
||||
if (anchor == ToolWindowAnchor.BOTTOM) {
|
||||
return AllIcons.General.HideDownPart;
|
||||
}
|
||||
else if (anchor == ToolWindowAnchor.RIGHT) {
|
||||
if (anchor == ToolWindowAnchor.RIGHT) {
|
||||
return AllIcons.General.HideRightPart;
|
||||
}
|
||||
|
||||
@@ -312,7 +313,7 @@ public abstract class ToolWindowHeader extends JPanel implements Disposable, UIS
|
||||
if (anchor == ToolWindowAnchor.BOTTOM) {
|
||||
return AllIcons.General.HideDown;
|
||||
}
|
||||
else if (anchor == ToolWindowAnchor.RIGHT) {
|
||||
if (anchor == ToolWindowAnchor.RIGHT) {
|
||||
return AllIcons.General.HideRight;
|
||||
}
|
||||
|
||||
@@ -324,7 +325,7 @@ public abstract class ToolWindowHeader extends JPanel implements Disposable, UIS
|
||||
if (anchor == ToolWindowAnchor.BOTTOM) {
|
||||
return AllIcons.General.HideDownPartHover;
|
||||
}
|
||||
else if (anchor == ToolWindowAnchor.RIGHT) {
|
||||
if (anchor == ToolWindowAnchor.RIGHT) {
|
||||
return AllIcons.General.HideRightPartHover;
|
||||
}
|
||||
|
||||
@@ -336,7 +337,7 @@ public abstract class ToolWindowHeader extends JPanel implements Disposable, UIS
|
||||
if (anchor == ToolWindowAnchor.BOTTOM) {
|
||||
return AllIcons.General.HideDownHover;
|
||||
}
|
||||
else if (anchor == ToolWindowAnchor.RIGHT) {
|
||||
if (anchor == ToolWindowAnchor.RIGHT) {
|
||||
return AllIcons.General.HideRightHover;
|
||||
}
|
||||
|
||||
@@ -419,7 +420,7 @@ public abstract class ToolWindowHeader extends JPanel implements Disposable, UIS
|
||||
|
||||
protected abstract void sideHidden();
|
||||
|
||||
protected abstract void toolWindowTypeChanged(ToolWindowType type);
|
||||
protected abstract void toolWindowTypeChanged(@NotNull ToolWindowType type);
|
||||
|
||||
@Override
|
||||
public Dimension getPreferredSize() {
|
||||
@@ -468,18 +469,15 @@ public abstract class ToolWindowHeader extends JPanel implements Disposable, UIS
|
||||
|
||||
setIcon(getActiveIcon(), getInactiveIcon() == null ? getActiveIcon() : getInactiveIcon(), getActiveHoveredIcon());
|
||||
|
||||
PropertyChangeListener listener = new PropertyChangeListener() {
|
||||
@Override
|
||||
public void propertyChange(PropertyChangeEvent evt) {
|
||||
if (myAlternativeAction == null) return;
|
||||
if ("ancestor".equals(evt.getPropertyName())) {
|
||||
if (evt.getNewValue() == null) {
|
||||
AltStateManager.getInstance().removeListener(ActionButton.this);
|
||||
switchAlternativeAction(false);
|
||||
}
|
||||
else {
|
||||
AltStateManager.getInstance().addListener(ActionButton.this);
|
||||
}
|
||||
PropertyChangeListener listener = evt -> {
|
||||
if (myAlternativeAction == null) return;
|
||||
if ("ancestor".equals(evt.getPropertyName())) {
|
||||
if (evt.getNewValue() == null) {
|
||||
AltStateManager.getInstance().removeListener(this);
|
||||
switchAlternativeAction(false);
|
||||
}
|
||||
else {
|
||||
AltStateManager.getInstance().addListener(this);
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -487,7 +485,7 @@ public abstract class ToolWindowHeader extends JPanel implements Disposable, UIS
|
||||
addPropertyChangeListener(listener);
|
||||
}
|
||||
|
||||
public void updateTooltip() {
|
||||
void updateTooltip() {
|
||||
myButton.setToolTipText(getToolTipTextByAction(myCurrentAction));
|
||||
}
|
||||
|
||||
@@ -533,6 +531,7 @@ public abstract class ToolWindowHeader extends JPanel implements Disposable, UIS
|
||||
this(action, activeIcon, activeIcon);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(final ActionEvent e) {
|
||||
AnAction action =
|
||||
myAlternativeAction != null && BitUtil.isSet(e.getModifiers(), InputEvent.ALT_MASK) ? myAlternativeAction : myAction;
|
||||
@@ -557,6 +556,7 @@ public abstract class ToolWindowHeader extends JPanel implements Disposable, UIS
|
||||
myButton.setIcons(active, inactive, hovered);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setToolTipText(final String text) {
|
||||
myButton.setToolTipText(text);
|
||||
}
|
||||
@@ -588,15 +588,17 @@ public abstract class ToolWindowHeader extends JPanel implements Disposable, UIS
|
||||
}
|
||||
|
||||
private abstract class HideSideAction extends AnAction implements DumbAware {
|
||||
@NonNls public static final String HIDE_ACTIVE_SIDE_WINDOW_ACTION_ID = ToolWindowHeader.HIDE_ACTIVE_SIDE_WINDOW_ACTION_ID;
|
||||
@NonNls static final String HIDE_ACTIVE_SIDE_WINDOW_ACTION_ID = ToolWindowHeader.HIDE_ACTIVE_SIDE_WINDOW_ACTION_ID;
|
||||
|
||||
public HideSideAction() {
|
||||
copyFrom(ActionManager.getInstance().getAction(HIDE_ACTIVE_SIDE_WINDOW_ACTION_ID));
|
||||
getTemplatePresentation().setText(UIBundle.message("tool.window.hideSide.action.name"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public abstract void actionPerformed(@NotNull final AnActionEvent e);
|
||||
|
||||
@Override
|
||||
public final void update(@NotNull final AnActionEvent event) {
|
||||
final Presentation presentation = event.getPresentation();
|
||||
presentation.setEnabled(myInfo.isVisible());
|
||||
@@ -604,13 +606,14 @@ public abstract class ToolWindowHeader extends JPanel implements Disposable, UIS
|
||||
}
|
||||
|
||||
private abstract class HideAction extends AnAction implements DumbAware {
|
||||
@NonNls public static final String HIDE_ACTIVE_WINDOW_ACTION_ID = ToolWindowHeader.HIDE_ACTIVE_WINDOW_ACTION_ID;
|
||||
@NonNls static final String HIDE_ACTIVE_WINDOW_ACTION_ID = ToolWindowHeader.HIDE_ACTIVE_WINDOW_ACTION_ID;
|
||||
|
||||
public HideAction() {
|
||||
copyFrom(ActionManager.getInstance().getAction(HIDE_ACTIVE_WINDOW_ACTION_ID));
|
||||
getTemplatePresentation().setText(UIBundle.message("tool.window.hide.action.name"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void update(@NotNull final AnActionEvent event) {
|
||||
final Presentation presentation = event.getPresentation();
|
||||
presentation.setEnabled(myInfo.isVisible());
|
||||
|
||||
+15
-19
@@ -53,9 +53,9 @@ import java.beans.PropertyChangeListener;
|
||||
import java.util.*;
|
||||
import java.util.List;
|
||||
|
||||
@SuppressWarnings({"ConstantConditions"})
|
||||
@SuppressWarnings("ConstantConditions")
|
||||
public class ToolWindowHeadlessManagerImpl extends ToolWindowManagerEx {
|
||||
private final Map<String, ToolWindow> myToolWindows = new HashMap<String, ToolWindow>();
|
||||
private final Map<String, ToolWindow> myToolWindows = new HashMap<>();
|
||||
private final Project myProject;
|
||||
|
||||
public ToolWindowHeadlessManagerImpl(Project project) {
|
||||
@@ -75,12 +75,7 @@ public class ToolWindowHeadlessManagerImpl extends ToolWindowManagerEx {
|
||||
MockToolWindow tw = new MockToolWindow(myProject);
|
||||
myToolWindows.put(id, tw);
|
||||
if (parentDisposable != null) {
|
||||
Disposer.register(parentDisposable, new Disposable() {
|
||||
@Override
|
||||
public void dispose() {
|
||||
unregisterToolWindow(id);
|
||||
}
|
||||
});
|
||||
Disposer.register(parentDisposable, () -> unregisterToolWindow(id));
|
||||
}
|
||||
return tw;
|
||||
}
|
||||
@@ -90,7 +85,7 @@ public class ToolWindowHeadlessManagerImpl extends ToolWindowManagerEx {
|
||||
public ToolWindow registerToolWindow(@NotNull String id,
|
||||
@NotNull JComponent component,
|
||||
@NotNull ToolWindowAnchor anchor,
|
||||
Disposable parentDisposable,
|
||||
@NotNull Disposable parentDisposable,
|
||||
boolean canWorkInDumbMode) {
|
||||
return doRegisterToolWindow(id, parentDisposable);
|
||||
}
|
||||
@@ -106,7 +101,7 @@ public class ToolWindowHeadlessManagerImpl extends ToolWindowManagerEx {
|
||||
public ToolWindow registerToolWindow(@NotNull String id,
|
||||
@NotNull JComponent component,
|
||||
@NotNull ToolWindowAnchor anchor,
|
||||
Disposable parentDisposable,
|
||||
@NotNull Disposable parentDisposable,
|
||||
boolean canWorkInDumbMode,
|
||||
boolean canCloseContents) {
|
||||
return doRegisterToolWindow(id, parentDisposable);
|
||||
@@ -139,7 +134,7 @@ public class ToolWindowHeadlessManagerImpl extends ToolWindowManagerEx {
|
||||
@NotNull
|
||||
@Override
|
||||
public ToolWindow registerToolWindow(@NotNull final String id, final boolean canCloseContent, @NotNull final ToolWindowAnchor anchor,
|
||||
final Disposable parentDisposable, final boolean dumbAware) {
|
||||
@NotNull final Disposable parentDisposable, final boolean dumbAware) {
|
||||
return doRegisterToolWindow(id, parentDisposable);
|
||||
}
|
||||
|
||||
@@ -148,7 +143,7 @@ public class ToolWindowHeadlessManagerImpl extends ToolWindowManagerEx {
|
||||
public ToolWindow registerToolWindow(@NotNull String id,
|
||||
boolean canCloseContent,
|
||||
@NotNull ToolWindowAnchor anchor,
|
||||
Disposable parentDisposable,
|
||||
@NotNull Disposable parentDisposable,
|
||||
boolean canWorkInDumbMode,
|
||||
boolean secondary) {
|
||||
return doRegisterToolWindow(id, parentDisposable);
|
||||
@@ -222,16 +217,16 @@ public class ToolWindowHeadlessManagerImpl extends ToolWindowManagerEx {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addToolWindowManagerListener(@NotNull ToolWindowManagerListener l) {
|
||||
public void addToolWindowManagerListener(@NotNull ToolWindowManagerListener listener) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addToolWindowManagerListener(@NotNull ToolWindowManagerListener l, @NotNull Disposable parentDisposable) {
|
||||
public void addToolWindowManagerListener(@NotNull ToolWindowManagerListener listener, @NotNull Disposable parentDisposable) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeToolWindowManagerListener(@NotNull ToolWindowManagerListener l) {
|
||||
public void removeToolWindowManagerListener(@NotNull ToolWindowManagerListener listener) {
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -270,9 +265,10 @@ public class ToolWindowHeadlessManagerImpl extends ToolWindowManagerEx {
|
||||
public void hideToolWindow(@NotNull final String id, final boolean hideSide) {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public List<String> getIdsOn(@NotNull final ToolWindowAnchor anchor) {
|
||||
return new ArrayList<String>();
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
public static class MockToolWindow implements ToolWindowEx {
|
||||
@@ -330,7 +326,7 @@ public class ToolWindowHeadlessManagerImpl extends ToolWindowManagerEx {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAnchor(ToolWindowAnchor anchor, @Nullable Runnable runnable) {
|
||||
public void setAnchor(@NotNull ToolWindowAnchor anchor, @Nullable Runnable runnable) {
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -367,7 +363,7 @@ public class ToolWindowHeadlessManagerImpl extends ToolWindowManagerEx {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setType(ToolWindowType type, @Nullable Runnable runnable) {
|
||||
public void setType(@NotNull ToolWindowType type, @Nullable Runnable runnable) {
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -500,7 +496,7 @@ public class ToolWindowHeadlessManagerImpl extends ToolWindowManagerEx {
|
||||
|
||||
private static class MockContentManager implements ContentManager {
|
||||
private final EventDispatcher<ContentManagerListener> myDispatcher = EventDispatcher.create(ContentManagerListener.class);
|
||||
private final List<Content> myContents = new ArrayList<Content>();
|
||||
private final List<Content> myContents = new ArrayList<>();
|
||||
private Content mySelected;
|
||||
|
||||
@NotNull
|
||||
|
||||
@@ -60,11 +60,11 @@ import java.util.Set;
|
||||
* @author Vladimir Kondratyev
|
||||
*/
|
||||
public final class ToolWindowImpl implements ToolWindowEx {
|
||||
private final PropertyChangeSupport myChangeSupport;
|
||||
private final PropertyChangeSupport myChangeSupport = new PropertyChangeSupport(this);
|
||||
private final ToolWindowManagerImpl myToolWindowManager;
|
||||
private final String myId;
|
||||
private final JComponent myComponent;
|
||||
private boolean myAvailable;
|
||||
private boolean myAvailable = true;
|
||||
private final ContentManager myContentManager;
|
||||
private Icon myIcon;
|
||||
private String myStripeTitle;
|
||||
@@ -74,18 +74,18 @@ public final class ToolWindowImpl implements ToolWindowEx {
|
||||
|
||||
private InternalDecorator myDecorator;
|
||||
|
||||
private boolean myHideOnEmptyContent = false;
|
||||
private boolean myHideOnEmptyContent;
|
||||
private boolean myPlaceholderMode;
|
||||
private ToolWindowFactory myContentFactory;
|
||||
|
||||
private static Set<KeyStroke> FORWARD_TRAVERSAL_KEYSTROKES = new HashSet<KeyStroke>(Arrays.asList(
|
||||
new KeyStroke[] {
|
||||
private static final Set<KeyStroke> FORWARD_TRAVERSAL_KEYSTROKES = new HashSet<>(Arrays.asList(
|
||||
new KeyStroke[]{
|
||||
KeyStroke.getKeyStroke(KeyEvent.VK_TAB, 0)
|
||||
}
|
||||
));
|
||||
|
||||
private static Set<KeyStroke> BACKWARD_TRAVERSAL_KEYSTROKES = new HashSet<KeyStroke>(Arrays.asList(
|
||||
new KeyStroke[] {
|
||||
private static final Set<KeyStroke> BACKWARD_TRAVERSAL_KEYSTROKES = new HashSet<>(Arrays.asList(
|
||||
new KeyStroke[]{
|
||||
KeyStroke.getKeyStroke(KeyEvent.VK_TAB, InputEvent.SHIFT_DOWN_MASK)
|
||||
}
|
||||
));
|
||||
@@ -102,16 +102,13 @@ public final class ToolWindowImpl implements ToolWindowEx {
|
||||
|
||||
private static final Logger LOG = Logger.getInstance(ToolWindowImpl.class);
|
||||
|
||||
ToolWindowImpl(final ToolWindowManagerImpl toolWindowManager, final String id, boolean canCloseContent, @Nullable final JComponent component) {
|
||||
ToolWindowImpl(@NotNull ToolWindowManagerImpl toolWindowManager, @NotNull String id, boolean canCloseContent, @Nullable final JComponent component) {
|
||||
myToolWindowManager = toolWindowManager;
|
||||
myChangeSupport = new PropertyChangeSupport(this);
|
||||
myId = id;
|
||||
myAvailable = true;
|
||||
|
||||
final ContentFactory contentFactory = ServiceManager.getService(ContentFactory.class);
|
||||
myContentUI = new ToolWindowContentUi(this);
|
||||
myContentManager =
|
||||
contentFactory.createContentManager(myContentUI, canCloseContent, toolWindowManager.getProject());
|
||||
myContentManager = contentFactory.createContentManager(myContentUI, canCloseContent, toolWindowManager.getProject());
|
||||
|
||||
if (component != null) {
|
||||
final Content content = contentFactory.createContent(component, "", false);
|
||||
@@ -224,7 +221,7 @@ public final class ToolWindowImpl implements ToolWindowEx {
|
||||
public ActionCallback getReady(@NotNull final Object requestor) {
|
||||
final ActionCallback result = new ActionCallback();
|
||||
myShowing.getReady(this).doWhenDone(() -> {
|
||||
ArrayList<FinalizableCommand> cmd = new ArrayList<FinalizableCommand>();
|
||||
ArrayList<FinalizableCommand> cmd = new ArrayList<>();
|
||||
cmd.add(new FinalizableCommand(null) {
|
||||
@Override
|
||||
public void run() {
|
||||
@@ -268,7 +265,7 @@ public final class ToolWindowImpl implements ToolWindowEx {
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void setAnchor(final ToolWindowAnchor anchor, @Nullable final Runnable runnable) {
|
||||
public final void setAnchor(@NotNull final ToolWindowAnchor anchor, @Nullable final Runnable runnable) {
|
||||
ApplicationManager.getApplication().assertIsDispatchThread();
|
||||
myToolWindowManager.setToolWindowAnchor(myId, anchor);
|
||||
if (runnable != null) {
|
||||
@@ -330,7 +327,7 @@ public final class ToolWindowImpl implements ToolWindowEx {
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void setType(final ToolWindowType type, @Nullable final Runnable runnable) {
|
||||
public final void setType(@NotNull final ToolWindowType type, @Nullable final Runnable runnable) {
|
||||
ApplicationManager.getApplication().assertIsDispatchThread();
|
||||
myToolWindowManager.setToolWindowType(myId, type);
|
||||
if (runnable != null) {
|
||||
@@ -416,6 +413,7 @@ public final class ToolWindowImpl implements ToolWindowEx {
|
||||
//return getSelectedContent().getIcon();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public final String getId() {
|
||||
return myId;
|
||||
}
|
||||
@@ -531,11 +529,11 @@ public final class ToolWindowImpl implements ToolWindowEx {
|
||||
return myContentManager.isDisposed();
|
||||
}
|
||||
|
||||
public boolean isPlaceholderMode() {
|
||||
boolean isPlaceholderMode() {
|
||||
return myPlaceholderMode;
|
||||
}
|
||||
|
||||
public void setPlaceholderMode(final boolean placeholderMode) {
|
||||
void setPlaceholderMode(final boolean placeholderMode) {
|
||||
myPlaceholderMode = placeholderMode;
|
||||
}
|
||||
|
||||
@@ -546,7 +544,7 @@ public final class ToolWindowImpl implements ToolWindowEx {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public ActionCallback setActivation(@NotNull ActionCallback activation) {
|
||||
ActionCallback setActivation(@NotNull ActionCallback activation) {
|
||||
if (!myActivation.isProcessed() && !myActivation.equals(activation)) {
|
||||
myActivation.setRejected();
|
||||
}
|
||||
|
||||
+152
-220
@@ -95,26 +95,26 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements
|
||||
private final Project myProject;
|
||||
private final WindowManagerEx myWindowManager;
|
||||
private final EventDispatcher<ToolWindowManagerListener> myDispatcher = EventDispatcher.create(ToolWindowManagerListener.class);
|
||||
private final DesktopLayout myLayout;
|
||||
private final Map<String, InternalDecorator> myId2InternalDecorator;
|
||||
private final Map<String, FloatingDecorator> myId2FloatingDecorator;
|
||||
private final Map<String, WindowedDecorator> myId2WindowedDecorator;
|
||||
private final Map<String, StripeButton> myId2StripeButton;
|
||||
private final Map<String, FocusWatcher> myId2FocusWatcher;
|
||||
private final DesktopLayout myLayout = new DesktopLayout();
|
||||
private final Map<String, InternalDecorator> myId2InternalDecorator = new HashMap<>();
|
||||
private final Map<String, FloatingDecorator> myId2FloatingDecorator = new HashMap<>();
|
||||
private final Map<String, WindowedDecorator> myId2WindowedDecorator = new HashMap<>();
|
||||
private final Map<String, StripeButton> myId2StripeButton = new HashMap<>();
|
||||
private final Map<String, FocusWatcher> myId2FocusWatcher = new HashMap<>();
|
||||
private final Set<String> myDumbAwareIds = Collections.synchronizedSet(ContainerUtil.<String>newTroveSet());
|
||||
|
||||
private final EditorComponentFocusWatcher myEditorComponentFocusWatcher;
|
||||
private final MyToolWindowPropertyChangeListener myToolWindowPropertyChangeListener;
|
||||
private final InternalDecoratorListener myInternalDecoratorListener;
|
||||
private final EditorComponentFocusWatcher myEditorComponentFocusWatcher = new EditorComponentFocusWatcher();
|
||||
private final MyToolWindowPropertyChangeListener myToolWindowPropertyChangeListener = new MyToolWindowPropertyChangeListener();
|
||||
private final InternalDecoratorListener myInternalDecoratorListener = new MyInternalDecoratorListener();
|
||||
|
||||
private boolean myEditorWasActive;
|
||||
|
||||
private final ActiveStack myActiveStack;
|
||||
private final SideStack mySideStack;
|
||||
private final ActiveStack myActiveStack = new ActiveStack();
|
||||
private final SideStack mySideStack = new SideStack();
|
||||
|
||||
private ToolWindowsPane myToolWindowsPane;
|
||||
private IdeFrameImpl myFrame;
|
||||
private DesktopLayout myLayoutToRestoreLater = null;
|
||||
private DesktopLayout myLayoutToRestoreLater;
|
||||
@NonNls private static final String EDITOR_ELEMENT = "editor";
|
||||
@NonNls private static final String ACTIVE_ATTR_VALUE = "active";
|
||||
@NonNls private static final String FRAME_ELEMENT = "frame";
|
||||
@@ -127,8 +127,7 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements
|
||||
|
||||
private final FileEditorManager myFileEditorManager;
|
||||
private final LafManager myLafManager;
|
||||
private final Map<String, Balloon> myWindow2Balloon = new HashMap<String, Balloon>();
|
||||
private Pair<String, Integer> myMaximizedToolwindowSize = null;
|
||||
private final Map<String, Balloon> myWindow2Balloon = new HashMap<>();
|
||||
|
||||
private KeyState myCurrentState = KeyState.waiting;
|
||||
private final Alarm myWaiterForSecondPress = new Alarm();
|
||||
@@ -139,7 +138,7 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements
|
||||
};
|
||||
private final PropertyChangeListener myFocusListener;
|
||||
|
||||
public boolean isToolWindowRegistered(String id) {
|
||||
boolean isToolWindowRegistered(@NotNull String id) {
|
||||
return myLayout.isToolWindowRegistered(id);
|
||||
}
|
||||
|
||||
@@ -148,7 +147,6 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements
|
||||
}
|
||||
|
||||
private final Alarm myUpdateHeadersAlarm = new Alarm();
|
||||
private final Runnable myUpdateHeadersRunnable = () -> updateToolWindowHeaders();
|
||||
|
||||
/**
|
||||
* invoked by reflection
|
||||
@@ -182,22 +180,8 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements
|
||||
}, project);
|
||||
}
|
||||
|
||||
myLayout = new DesktopLayout();
|
||||
myLayout.copyFrom(windowManagerEx.getLayout());
|
||||
|
||||
myId2InternalDecorator = new HashMap<String, InternalDecorator>();
|
||||
myId2FloatingDecorator = new HashMap<String, FloatingDecorator>();
|
||||
myId2WindowedDecorator = new HashMap<String, WindowedDecorator>();
|
||||
myId2StripeButton = new HashMap<String, StripeButton>();
|
||||
myId2FocusWatcher = new HashMap<String, FocusWatcher>();
|
||||
|
||||
myEditorComponentFocusWatcher = new EditorComponentFocusWatcher();
|
||||
myToolWindowPropertyChangeListener = new MyToolWindowPropertyChangeListener();
|
||||
myInternalDecoratorListener = new MyInternalDecoratorListener();
|
||||
|
||||
myActiveStack = new ActiveStack();
|
||||
mySideStack = new SideStack();
|
||||
|
||||
project.getMessageBus().connect().subscribe(FileEditorManagerListener.FILE_EDITOR_MANAGER, new FileEditorManagerListener() {
|
||||
@Override
|
||||
public void fileOpened(@NotNull FileEditorManager source, @NotNull VirtualFile file) {
|
||||
@@ -220,13 +204,10 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements
|
||||
}
|
||||
});
|
||||
|
||||
myFocusListener = new PropertyChangeListener() {
|
||||
@Override
|
||||
public void propertyChange(PropertyChangeEvent evt) {
|
||||
if ("focusOwner".equals(evt.getPropertyName())) {
|
||||
myUpdateHeadersAlarm.cancelAllRequests();
|
||||
myUpdateHeadersAlarm.addRequest(myUpdateHeadersRunnable, 50);
|
||||
}
|
||||
myFocusListener = evt -> {
|
||||
if ("focusOwner".equals(evt.getPropertyName())) {
|
||||
myUpdateHeadersAlarm.cancelAllRequests();
|
||||
myUpdateHeadersAlarm.addRequest(this::updateToolWindowHeaders, 50);
|
||||
}
|
||||
};
|
||||
KeyboardFocusManager.getCurrentKeyboardFocusManager().addPropertyChangeListener(myFocusListener);
|
||||
@@ -253,7 +234,7 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements
|
||||
});
|
||||
}
|
||||
|
||||
public boolean dispatchKeyEvent(KeyEvent e) {
|
||||
public boolean dispatchKeyEvent(@NotNull KeyEvent e) {
|
||||
if (e.getKeyCode() != KeyEvent.VK_CONTROL &&
|
||||
e.getKeyCode() != KeyEvent.VK_ALT &&
|
||||
e.getKeyCode() != KeyEvent.VK_SHIFT &&
|
||||
@@ -299,8 +280,9 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements
|
||||
return false;
|
||||
}
|
||||
|
||||
public static Set<Integer> getActivateToolWindowVKs() {
|
||||
if (ApplicationManager.getApplication() == null) return new HashSet<Integer>();
|
||||
@NotNull
|
||||
private static Set<Integer> getActivateToolWindowVKs() {
|
||||
if (ApplicationManager.getApplication() == null) return new HashSet<>();
|
||||
|
||||
Keymap keymap = KeymapManager.getInstance().getActiveKeymap();
|
||||
Shortcut[] baseShortcut = keymap.getShortcuts("ActivateProjectToolWindow");
|
||||
@@ -373,7 +355,7 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements
|
||||
|
||||
@Override
|
||||
public void disposeComponent() {
|
||||
for (String id : new ArrayList<String>(myId2StripeButton.keySet())) {
|
||||
for (String id : new ArrayList<>(myId2StripeButton.keySet())) {
|
||||
unregisterToolWindow(id);
|
||||
}
|
||||
|
||||
@@ -390,21 +372,17 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements
|
||||
UIManager.addPropertyChangeListener(uiManagerPropertyListener);
|
||||
myLafManager.addLafManagerListener(lafManagerListener);
|
||||
|
||||
Disposer.register(myProject, new Disposable() {
|
||||
@Override
|
||||
public void dispose() {
|
||||
UIManager.removePropertyChangeListener(uiManagerPropertyListener);
|
||||
myLafManager.removeLafManagerListener(lafManagerListener);
|
||||
}
|
||||
Disposer.register(myProject, () -> {
|
||||
UIManager.removePropertyChangeListener(uiManagerPropertyListener);
|
||||
myLafManager.removeLafManagerListener(lafManagerListener);
|
||||
});
|
||||
myFrame = myWindowManager.allocateFrame(myProject);
|
||||
LOG.assertTrue(myFrame != null);
|
||||
|
||||
final ArrayList<FinalizableCommand> commandsList = new ArrayList<FinalizableCommand>();
|
||||
|
||||
myToolWindowsPane = new ToolWindowsPane(myFrame, this);
|
||||
Disposer.register(myProject, myToolWindowsPane);
|
||||
((IdeRootPane)myFrame.getRootPane()).setToolWindowsPane(myToolWindowsPane);
|
||||
List<FinalizableCommand> commandsList = new ArrayList<>();
|
||||
appendUpdateToolWindowsPaneCmd(commandsList);
|
||||
|
||||
myFrame.setTitle(FrameTitleBuilder.getInstance().getProjectTitle(myProject));
|
||||
@@ -432,13 +410,10 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements
|
||||
};
|
||||
myProject.getMessageBus().connect().subscribe(DumbService.DUMB_MODE, dumbModeListener);
|
||||
|
||||
StartupManager.getInstance(myProject).registerPostStartupActivity(new DumbAwareRunnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
registerToolWindowsFromBeans();
|
||||
if (DumbService.getInstance(myProject).isDumb()) {
|
||||
disableStripeButtons();
|
||||
}
|
||||
StartupManager.getInstance(myProject).registerPostStartupActivity((DumbAwareRunnable)() -> {
|
||||
registerToolWindowsFromBeans();
|
||||
if (DumbService.getInstance(myProject).isDumb()) {
|
||||
disableStripeButtons();
|
||||
}
|
||||
});
|
||||
|
||||
@@ -446,7 +421,7 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements
|
||||
if (e instanceof KeyEvent) {
|
||||
dispatchKeyEvent((KeyEvent)e);
|
||||
}
|
||||
if (e instanceof WindowEvent && (e.getID() == WindowEvent.WINDOW_LOST_FOCUS) && e.getSource() == myFrame) {
|
||||
if (e instanceof WindowEvent && e.getID() == WindowEvent.WINDOW_LOST_FOCUS && e.getSource() == myFrame) {
|
||||
resetHoldState();
|
||||
}
|
||||
return false;
|
||||
@@ -467,7 +442,7 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements
|
||||
}
|
||||
}
|
||||
|
||||
private JComponent createEditorComponent(Project project) {
|
||||
private static JComponent createEditorComponent(@NotNull Project project) {
|
||||
return FrameEditorComponentProvider.EP.getExtensions()[0].createEditorComponent(project);
|
||||
}
|
||||
|
||||
@@ -542,19 +517,16 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements
|
||||
|
||||
WindowInfoImpl info = getInfo(bean.id);
|
||||
if (!info.isSplit() && bean.secondary && !info.wasRead()) {
|
||||
toolWindow.setSplitMode(bean.secondary, null);
|
||||
toolWindow.setSplitMode(true, null);
|
||||
}
|
||||
|
||||
final ActionCallback activation = toolWindow.setActivation(new ActionCallback());
|
||||
|
||||
final DumbAwareRunnable runnable = new DumbAwareRunnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (toolWindow.isDisposed()) return;
|
||||
final DumbAwareRunnable runnable = () -> {
|
||||
if (toolWindow.isDisposed()) return;
|
||||
|
||||
toolWindow.ensureContentInitialized();
|
||||
activation.setDone();
|
||||
}
|
||||
toolWindow.ensureContentInitialized();
|
||||
activation.setDone();
|
||||
};
|
||||
if (ApplicationManager.getApplication().isUnitTestMode()) {
|
||||
runnable.run();
|
||||
@@ -566,7 +538,6 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements
|
||||
|
||||
@Override
|
||||
public void projectClosed() {
|
||||
final ArrayList<FinalizableCommand> commandsList = new ArrayList<FinalizableCommand>();
|
||||
final String[] ids = getToolWindowIds();
|
||||
|
||||
// Remove ToolWindowsPane
|
||||
@@ -574,6 +545,7 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements
|
||||
((IdeRootPane)myFrame.getRootPane()).setToolWindowsPane(null);
|
||||
myWindowManager.releaseFrame(myFrame);
|
||||
}
|
||||
List<FinalizableCommand> commandsList = new ArrayList<>();
|
||||
appendUpdateToolWindowsPaneCmd(commandsList);
|
||||
|
||||
// Hide all tool windows
|
||||
@@ -591,18 +563,18 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addToolWindowManagerListener(@NotNull ToolWindowManagerListener l) {
|
||||
myDispatcher.addListener(l);
|
||||
public void addToolWindowManagerListener(@NotNull ToolWindowManagerListener listener) {
|
||||
myDispatcher.addListener(listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addToolWindowManagerListener(@NotNull ToolWindowManagerListener l, @NotNull Disposable parentDisposable) {
|
||||
myDispatcher.addListener(l, parentDisposable);
|
||||
public void addToolWindowManagerListener(@NotNull ToolWindowManagerListener listener, @NotNull Disposable parentDisposable) {
|
||||
myDispatcher.addListener(listener, parentDisposable);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeToolWindowManagerListener(@NotNull ToolWindowManagerListener l) {
|
||||
myDispatcher.removeListener(l);
|
||||
public void removeToolWindowManagerListener(@NotNull ToolWindowManagerListener listener) {
|
||||
myDispatcher.removeListener(listener);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -641,7 +613,7 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements
|
||||
final ExpirableRunnable runnable = new ExpirableRunnable.ForProject(myProject) {
|
||||
@Override
|
||||
public void run() {
|
||||
final ArrayList<FinalizableCommand> commandList = new ArrayList<FinalizableCommand>();
|
||||
List<FinalizableCommand> commandList = new ArrayList<>();
|
||||
activateEditorComponentImpl(commandList, forced);
|
||||
execute(commandList);
|
||||
}
|
||||
@@ -669,15 +641,14 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements
|
||||
}
|
||||
}
|
||||
|
||||
private void activateEditorComponentImpl(List<FinalizableCommand> commandList, final boolean forced) {
|
||||
private void activateEditorComponentImpl(@NotNull List<FinalizableCommand> commandList, final boolean forced) {
|
||||
final String active = getActiveToolWindowId();
|
||||
// Now we have to request focus into most recent focused editor
|
||||
appendRequestFocusInEditorComponentCmd(commandList, forced).doWhenDone(() -> {
|
||||
final ArrayList<FinalizableCommand> commandList12 = new ArrayList<FinalizableCommand>();
|
||||
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("editor activated");
|
||||
}
|
||||
List<FinalizableCommand> commandList12 = new ArrayList<>();
|
||||
deactivateWindows(null, commandList12);
|
||||
myActiveStack.clear();
|
||||
|
||||
@@ -688,9 +659,9 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements
|
||||
@NotNull
|
||||
@Override
|
||||
public ActionCallback run() {
|
||||
final ArrayList<FinalizableCommand> commandList1 = new ArrayList<FinalizableCommand>();
|
||||
List<FinalizableCommand> commandList1 = new ArrayList<>();
|
||||
|
||||
final WindowInfoImpl toReactivate = getInfo(active);
|
||||
final WindowInfoImpl toReactivate = active == null ? null : getInfo(active);
|
||||
final boolean reactivateLastActive = toReactivate != null && !isToHideOnDeactivation(toReactivate);
|
||||
deactivateWindows(reactivateLastActive ? active : null, commandList1);
|
||||
execute(commandList1);
|
||||
@@ -714,7 +685,7 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements
|
||||
});
|
||||
}
|
||||
|
||||
private void deactivateWindows( @Nullable String idToIgnore, final List<FinalizableCommand> commandList) {
|
||||
private void deactivateWindows(@Nullable String idToIgnore, @NotNull List<FinalizableCommand> commandList) {
|
||||
final WindowInfoImpl[] infos = myLayout.getInfos();
|
||||
for (final WindowInfoImpl info : infos) {
|
||||
if (idToIgnore != null && idToIgnore.equals(info.getId())) {
|
||||
@@ -736,11 +707,10 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements
|
||||
*
|
||||
* @param dirtyMode if <code>true</code> then all UI operations are performed in "dirty" mode.
|
||||
* It means that UI isn't validated and repainted just after each add/remove operation.
|
||||
* @see ToolWindowManagerImpl#prepareForActivation
|
||||
*/
|
||||
private void showAndActivate(final String id,
|
||||
private void showAndActivate(@NotNull String id,
|
||||
final boolean dirtyMode,
|
||||
List<FinalizableCommand> commandsList,
|
||||
@NotNull List<FinalizableCommand> commandsList,
|
||||
boolean autoFocusContents,
|
||||
boolean forcedFocusRequest) {
|
||||
if (!getToolWindow(id).isAvailable()) {
|
||||
@@ -766,7 +736,7 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements
|
||||
}
|
||||
}
|
||||
|
||||
void activateToolWindow(final String id, boolean forced, boolean autoFocusContents) {
|
||||
void activateToolWindow(@NotNull String id, boolean forced, boolean autoFocusContents) {
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("enter: activateToolWindow(" + id + ")");
|
||||
}
|
||||
@@ -776,13 +746,13 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements
|
||||
return;
|
||||
}
|
||||
|
||||
final ArrayList<FinalizableCommand> commandList = new ArrayList<FinalizableCommand>();
|
||||
List<FinalizableCommand> commandList = new ArrayList<>();
|
||||
activateToolWindowImpl(id, commandList, forced, autoFocusContents);
|
||||
execute(commandList);
|
||||
}
|
||||
|
||||
private void activateToolWindowImpl(final String id,
|
||||
List<FinalizableCommand> commandList,
|
||||
private void activateToolWindowImpl(@NotNull String id,
|
||||
@NotNull List<FinalizableCommand> commandList,
|
||||
boolean forced,
|
||||
boolean autoFocusContents) {
|
||||
if (!FocusManagerImpl.getInstance().isUnforcedRequestAllowed() && !forced) return;
|
||||
@@ -810,7 +780,7 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements
|
||||
*
|
||||
* @throws IllegalStateException if tool window isn't installed.
|
||||
*/
|
||||
private void checkId(final String id) {
|
||||
private void checkId(@NotNull String id) {
|
||||
if (!myLayout.isToolWindowRegistered(id)) {
|
||||
throw new IllegalStateException("window with id=\"" + id + "\" isn't registered");
|
||||
}
|
||||
@@ -822,7 +792,7 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements
|
||||
* @param id <code>id</code> of the tool window to be deactivated.
|
||||
* @param shouldHide if <code>true</code> then also hides specified tool window.
|
||||
*/
|
||||
private void deactivateToolWindowImpl(final String id, final boolean shouldHide, final List<FinalizableCommand> commandsList) {
|
||||
private void deactivateToolWindowImpl(@NotNull String id, final boolean shouldHide, @NotNull List<FinalizableCommand> commandsList) {
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("enter: deactivateToolWindowImpl(" + id + "," + shouldHide + ")");
|
||||
}
|
||||
@@ -887,37 +857,38 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements
|
||||
/**
|
||||
* @return floating decorator for the tool window with specified <code>ID</code>.
|
||||
*/
|
||||
private FloatingDecorator getFloatingDecorator(final String id) {
|
||||
private FloatingDecorator getFloatingDecorator(@NotNull String id) {
|
||||
return myId2FloatingDecorator.get(id);
|
||||
}
|
||||
/**
|
||||
* @return windowed decorator for the tool window with specified <code>ID</code>.
|
||||
*/
|
||||
private WindowedDecorator getWindowedDecorator(String id) {
|
||||
private WindowedDecorator getWindowedDecorator(@NotNull String id) {
|
||||
return myId2WindowedDecorator.get(id);
|
||||
}
|
||||
/**
|
||||
* @return internal decorator for the tool window with specified <code>ID</code>.
|
||||
*/
|
||||
private InternalDecorator getInternalDecorator(final String id) {
|
||||
private InternalDecorator getInternalDecorator(@NotNull String id) {
|
||||
return myId2InternalDecorator.get(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return tool button for the window with specified <code>ID</code>.
|
||||
*/
|
||||
private StripeButton getStripeButton(final String id) {
|
||||
private StripeButton getStripeButton(@NotNull String id) {
|
||||
return myId2StripeButton.get(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return info for the tool window with specified <code>ID</code>.
|
||||
*/
|
||||
private WindowInfoImpl getInfo(final String id) {
|
||||
private WindowInfoImpl getInfo(@NotNull String id) {
|
||||
return myLayout.getInfo(id, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public List<String> getIdsOn(@NotNull final ToolWindowAnchor anchor) {
|
||||
return myLayout.getVisibleIdsOn(anchor, this);
|
||||
}
|
||||
@@ -931,12 +902,12 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements
|
||||
return decorator != null ? decorator.getToolWindow() : null;
|
||||
}
|
||||
|
||||
void showToolWindow(final String id) {
|
||||
void showToolWindow(@NotNull String id) {
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("enter: showToolWindow(" + id + ")");
|
||||
}
|
||||
ApplicationManager.getApplication().assertIsDispatchThread();
|
||||
final ArrayList<FinalizableCommand> commandList = new ArrayList<FinalizableCommand>();
|
||||
List<FinalizableCommand> commandList = new ArrayList<>();
|
||||
showToolWindowImpl(id, false, commandList);
|
||||
execute(commandList);
|
||||
}
|
||||
@@ -946,12 +917,12 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements
|
||||
hideToolWindow(id, hideSide, true);
|
||||
}
|
||||
|
||||
public void hideToolWindow(final String id, final boolean hideSide, final boolean moveFocus) {
|
||||
public void hideToolWindow(@NotNull String id, final boolean hideSide, final boolean moveFocus) {
|
||||
ApplicationManager.getApplication().assertIsDispatchThread();
|
||||
checkId(id);
|
||||
final WindowInfoImpl info = getInfo(id);
|
||||
if (!info.isVisible()) return;
|
||||
final ArrayList<FinalizableCommand> commandList = new ArrayList<FinalizableCommand>();
|
||||
List<FinalizableCommand> commandList = new ArrayList<>();
|
||||
final boolean wasActive = info.isActive();
|
||||
|
||||
// hide and deactivate
|
||||
@@ -1024,7 +995,7 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements
|
||||
}
|
||||
else {
|
||||
final String toBeActivatedId = myActiveStack.pop();
|
||||
if (toBeActivatedId != null && (getInfo(toBeActivatedId).isVisible() || isStackEnabled())) {
|
||||
if (getInfo(toBeActivatedId).isVisible() || isStackEnabled()) {
|
||||
activateToolWindowImpl(toBeActivatedId, commandList, false, true);
|
||||
}
|
||||
else {
|
||||
@@ -1044,7 +1015,7 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements
|
||||
/**
|
||||
* @param dirtyMode if <code>true</code> then all UI operations are performed in dirty mode.
|
||||
*/
|
||||
private void showToolWindowImpl(final String id, final boolean dirtyMode, final List<FinalizableCommand> commandsList) {
|
||||
private void showToolWindowImpl(@NotNull String id, final boolean dirtyMode, @NotNull List<FinalizableCommand> commandsList) {
|
||||
final WindowInfoImpl toBeShownInfo = getInfo(id);
|
||||
if (toBeShownInfo.isVisible() || !getToolWindow(id).isAvailable()) {
|
||||
return;
|
||||
@@ -1184,7 +1155,7 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements
|
||||
public ToolWindow registerToolWindow(@NotNull String id,
|
||||
boolean canCloseContent,
|
||||
@NotNull ToolWindowAnchor anchor,
|
||||
Disposable parentDisposable,
|
||||
@NotNull Disposable parentDisposable,
|
||||
boolean canWorkInDumbMode,
|
||||
boolean secondary) {
|
||||
ToolWindow window = registerToolWindow(id, null, anchor, secondary, canCloseContent, canWorkInDumbMode);
|
||||
@@ -1226,7 +1197,7 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements
|
||||
|
||||
final StripeButton button = new StripeButton(decorator, myToolWindowsPane);
|
||||
myId2StripeButton.put(id, button);
|
||||
List<FinalizableCommand> commandsList = new ArrayList<FinalizableCommand>();
|
||||
List<FinalizableCommand> commandsList = new ArrayList<>();
|
||||
appendAddButtonCmd(button, info, commandsList);
|
||||
|
||||
if (canWorkInDumbMode) {
|
||||
@@ -1260,12 +1231,7 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements
|
||||
|
||||
@NotNull
|
||||
private ToolWindow registerDisposable(@NotNull final String id, @NotNull final Disposable parentDisposable, @NotNull ToolWindow window) {
|
||||
Disposer.register(parentDisposable, new Disposable() {
|
||||
@Override
|
||||
public void dispose() {
|
||||
unregisterToolWindow(id);
|
||||
}
|
||||
});
|
||||
Disposer.register(parentDisposable, () -> unregisterToolWindow(id));
|
||||
return window;
|
||||
}
|
||||
|
||||
@@ -1284,7 +1250,7 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements
|
||||
// Save recent appearance of tool window
|
||||
myLayout.unregister(id);
|
||||
// Remove decorator and tool button from the screen
|
||||
final ArrayList<FinalizableCommand> commandsList = new ArrayList<FinalizableCommand>();
|
||||
List<FinalizableCommand> commandsList = new ArrayList<>();
|
||||
if (info.isVisible()) {
|
||||
info.setVisible(false);
|
||||
if (info.isFloating()) {
|
||||
@@ -1338,7 +1304,7 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements
|
||||
@Override
|
||||
public void setLayout(@NotNull final DesktopLayout layout) {
|
||||
ApplicationManager.getApplication().assertIsDispatchThread();
|
||||
final ArrayList<FinalizableCommand> commandList = new ArrayList<FinalizableCommand>();
|
||||
List<FinalizableCommand> commandList = new ArrayList<>();
|
||||
// hide tool window that are invisible in new layout
|
||||
final WindowInfoImpl[] currentInfos = myLayout.getInfos();
|
||||
for (final WindowInfoImpl currentInfo : currentInfos) {
|
||||
@@ -1400,7 +1366,7 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements
|
||||
|
||||
@Override
|
||||
public void invokeLater(@NotNull final Runnable runnable) {
|
||||
List<FinalizableCommand> commandList = new ArrayList<FinalizableCommand>();
|
||||
List<FinalizableCommand> commandList = new ArrayList<>();
|
||||
commandList.add(new InvokeLaterCmd(runnable, myWindowManager.getCommandProcessor()));
|
||||
execute(commandList);
|
||||
}
|
||||
@@ -1480,19 +1446,16 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements
|
||||
});
|
||||
listenerWrapper.myBalloon = balloon;
|
||||
myWindow2Balloon.put(toolWindowId, balloon);
|
||||
Disposer.register(balloon, new Disposable() {
|
||||
@Override
|
||||
public void dispose() {
|
||||
window.setPlaceholderMode(false);
|
||||
stripe.updatePresentation();
|
||||
stripe.revalidate();
|
||||
stripe.repaint();
|
||||
myWindow2Balloon.remove(toolWindowId);
|
||||
}
|
||||
Disposer.register(balloon, () -> {
|
||||
window.setPlaceholderMode(false);
|
||||
stripe.updatePresentation();
|
||||
stripe.revalidate();
|
||||
stripe.repaint();
|
||||
myWindow2Balloon.remove(toolWindowId);
|
||||
});
|
||||
Disposer.register(getProject(), balloon);
|
||||
|
||||
execute(new ArrayList<FinalizableCommand>(Arrays.<FinalizableCommand>asList(new FinalizableCommand(null) {
|
||||
execute(new ArrayList<>(Collections.<FinalizableCommand>singletonList(new FinalizableCommand(null) {
|
||||
@Override
|
||||
public void run() {
|
||||
final StripeButton button = stripe.getButtonFor(toolWindowId);
|
||||
@@ -1550,7 +1513,7 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements
|
||||
};
|
||||
|
||||
if (!button.isValid()) {
|
||||
SwingUtilities.invokeLater(() -> show.run());
|
||||
SwingUtilities.invokeLater(show);
|
||||
}
|
||||
else {
|
||||
show.run();
|
||||
@@ -1573,27 +1536,28 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements
|
||||
return splitters != null;
|
||||
}
|
||||
|
||||
ToolWindowAnchor getToolWindowAnchor(final String id) {
|
||||
@NotNull
|
||||
ToolWindowAnchor getToolWindowAnchor(@NotNull String id) {
|
||||
checkId(id);
|
||||
return getInfo(id).getAnchor();
|
||||
}
|
||||
|
||||
void setToolWindowAnchor(final String id, final ToolWindowAnchor anchor) {
|
||||
void setToolWindowAnchor(@NotNull String id, @NotNull ToolWindowAnchor anchor) {
|
||||
ApplicationManager.getApplication().assertIsDispatchThread();
|
||||
setToolWindowAnchor(id, anchor, -1);
|
||||
}
|
||||
|
||||
void setToolWindowAnchor(final String id, final ToolWindowAnchor anchor, final int order) {
|
||||
private void setToolWindowAnchor(@NotNull String id, @NotNull ToolWindowAnchor anchor, final int order) {
|
||||
ApplicationManager.getApplication().assertIsDispatchThread();
|
||||
final ArrayList<FinalizableCommand> commandList = new ArrayList<FinalizableCommand>();
|
||||
List<FinalizableCommand> commandList = new ArrayList<>();
|
||||
setToolWindowAnchorImpl(id, anchor, order, commandList);
|
||||
execute(commandList);
|
||||
}
|
||||
|
||||
private void setToolWindowAnchorImpl(final String id,
|
||||
final ToolWindowAnchor anchor,
|
||||
private void setToolWindowAnchorImpl(@NotNull String id,
|
||||
@NotNull ToolWindowAnchor anchor,
|
||||
final int order,
|
||||
final ArrayList<FinalizableCommand> commandsList) {
|
||||
@NotNull List<FinalizableCommand> commandsList) {
|
||||
checkId(id);
|
||||
final WindowInfoImpl info = getInfo(id);
|
||||
if (anchor == info.getAnchor() && order == info.getOrder()) {
|
||||
@@ -1630,42 +1594,42 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements
|
||||
}
|
||||
}
|
||||
|
||||
boolean isSplitMode(String id) {
|
||||
boolean isSplitMode(@NotNull String id) {
|
||||
ApplicationManager.getApplication().assertIsDispatchThread();
|
||||
checkId(id);
|
||||
return getInfo(id).isSplit();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
ToolWindowContentUiType getContentUiType(String id) {
|
||||
ToolWindowContentUiType getContentUiType(@NotNull String id) {
|
||||
ApplicationManager.getApplication().assertIsDispatchThread();
|
||||
checkId(id);
|
||||
return getInfo(id).getContentUiType();
|
||||
}
|
||||
|
||||
void setSideTool(String id, boolean isSide) {
|
||||
final ArrayList<FinalizableCommand> commandList = new ArrayList<FinalizableCommand>();
|
||||
void setSideTool(@NotNull String id, boolean isSide) {
|
||||
List<FinalizableCommand> commandList = new ArrayList<>();
|
||||
setSplitModeImpl(id, isSide, commandList);
|
||||
execute(commandList);
|
||||
}
|
||||
|
||||
public void setContentUiType(String id, @NotNull ToolWindowContentUiType type) {
|
||||
final ArrayList<FinalizableCommand> commandList = new ArrayList<FinalizableCommand>();
|
||||
void setContentUiType(@NotNull String id, @NotNull ToolWindowContentUiType type) {
|
||||
checkId(id);
|
||||
WindowInfoImpl info = getInfo(id);
|
||||
info.setContentUiType(type);
|
||||
List<FinalizableCommand> commandList = new ArrayList<>();
|
||||
appendApplyWindowInfoCmd(info, commandList);
|
||||
execute(commandList);
|
||||
}
|
||||
|
||||
void setSideToolAndAnchor(String id, ToolWindowAnchor anchor, int order, boolean isSide) {
|
||||
final ArrayList<FinalizableCommand> commandList = new ArrayList<FinalizableCommand>();
|
||||
void setSideToolAndAnchor(@NotNull String id, @NotNull ToolWindowAnchor anchor, int order, boolean isSide) {
|
||||
setToolWindowAnchor(id, anchor, order);
|
||||
List<FinalizableCommand> commandList = new ArrayList<>();
|
||||
setSplitModeImpl(id, isSide, commandList);
|
||||
execute(commandList);
|
||||
}
|
||||
|
||||
private void setSplitModeImpl(final String id, final boolean isSplit, final ArrayList<FinalizableCommand> commandList) {
|
||||
private void setSplitModeImpl(@NotNull String id, final boolean isSplit, @NotNull List<FinalizableCommand> commandList) {
|
||||
checkId(id);
|
||||
final WindowInfoImpl info = getInfo(id);
|
||||
if (isSplit == info.isSplit()) {
|
||||
@@ -1688,18 +1652,18 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements
|
||||
commandList.add(myToolWindowsPane.createUpdateButtonPositionCmd(id, myWindowManager.getCommandProcessor()));
|
||||
}
|
||||
|
||||
ToolWindowType getToolWindowInternalType(final String id) {
|
||||
ToolWindowType getToolWindowInternalType(@NotNull String id) {
|
||||
ApplicationManager.getApplication().assertIsDispatchThread();
|
||||
checkId(id);
|
||||
return getInfo(id).getInternalType();
|
||||
}
|
||||
|
||||
ToolWindowType getToolWindowType(final String id) {
|
||||
ToolWindowType getToolWindowType(@NotNull String id) {
|
||||
checkId(id);
|
||||
return getInfo(id).getType();
|
||||
}
|
||||
|
||||
private void fireToolWindowRegistered(final String id) {
|
||||
private void fireToolWindowRegistered(@NotNull String id) {
|
||||
myDispatcher.getMulticaster().toolWindowRegistered(id);
|
||||
}
|
||||
|
||||
@@ -1707,31 +1671,31 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements
|
||||
myDispatcher.getMulticaster().stateChanged();
|
||||
}
|
||||
|
||||
boolean isToolWindowActive(final String id) {
|
||||
boolean isToolWindowActive(@NotNull String id) {
|
||||
ApplicationManager.getApplication().assertIsDispatchThread();
|
||||
checkId(id);
|
||||
return getInfo(id).isActive();
|
||||
}
|
||||
|
||||
boolean isToolWindowAutoHide(final String id) {
|
||||
boolean isToolWindowAutoHide(@NotNull String id) {
|
||||
ApplicationManager.getApplication().assertIsDispatchThread();
|
||||
checkId(id);
|
||||
return getInfo(id).isAutoHide();
|
||||
}
|
||||
|
||||
boolean isToolWindowVisible(final String id) {
|
||||
boolean isToolWindowVisible(@NotNull String id) {
|
||||
checkId(id);
|
||||
return getInfo(id).isVisible();
|
||||
}
|
||||
|
||||
void setToolWindowAutoHide(final String id, final boolean autoHide) {
|
||||
void setToolWindowAutoHide(@NotNull String id, final boolean autoHide) {
|
||||
ApplicationManager.getApplication().assertIsDispatchThread();
|
||||
final ArrayList<FinalizableCommand> commandList = new ArrayList<FinalizableCommand>();
|
||||
List<FinalizableCommand> commandList = new ArrayList<>();
|
||||
setToolWindowAutoHideImpl(id, autoHide, commandList);
|
||||
execute(commandList);
|
||||
}
|
||||
|
||||
private void setToolWindowAutoHideImpl(final String id, final boolean autoHide, final ArrayList<FinalizableCommand> commandsList) {
|
||||
private void setToolWindowAutoHideImpl(@NotNull String id, final boolean autoHide, @NotNull List<FinalizableCommand> commandsList) {
|
||||
checkId(id);
|
||||
final WindowInfoImpl info = getInfo(id);
|
||||
if (info.isAutoHide() == autoHide) {
|
||||
@@ -1745,14 +1709,14 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements
|
||||
}
|
||||
}
|
||||
|
||||
void setToolWindowType(final String id, final ToolWindowType type) {
|
||||
void setToolWindowType(@NotNull String id, @NotNull ToolWindowType type) {
|
||||
ApplicationManager.getApplication().assertIsDispatchThread();
|
||||
final ArrayList<FinalizableCommand> commandList = new ArrayList<FinalizableCommand>();
|
||||
List<FinalizableCommand> commandList = new ArrayList<>();
|
||||
setToolWindowTypeImpl(id, type, commandList);
|
||||
execute(commandList);
|
||||
}
|
||||
|
||||
private void setToolWindowTypeImpl(final String id, final ToolWindowType type, final ArrayList<FinalizableCommand> commandsList) {
|
||||
private void setToolWindowTypeImpl(@NotNull String id, @NotNull ToolWindowType type, @NotNull List<FinalizableCommand> commandsList) {
|
||||
checkId(id);
|
||||
final WindowInfoImpl info = getInfo(id);
|
||||
if (info.getType() == type) {
|
||||
@@ -1782,7 +1746,7 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements
|
||||
}
|
||||
}
|
||||
|
||||
private void appendApplyWindowInfoCmd(final WindowInfoImpl info, final List<FinalizableCommand> commandsList) {
|
||||
private void appendApplyWindowInfoCmd(@NotNull WindowInfoImpl info, @NotNull List<FinalizableCommand> commandsList) {
|
||||
final StripeButton button = getStripeButton(info.getId());
|
||||
final InternalDecorator decorator = getInternalDecorator(info.getId());
|
||||
commandsList.add(new ApplyWindowInfoCmd(info, button, decorator, myWindowManager.getCommandProcessor()));
|
||||
@@ -1791,10 +1755,10 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements
|
||||
/**
|
||||
* @see ToolWindowsPane#createAddDecoratorCmd
|
||||
*/
|
||||
private void appendAddDecoratorCmd(final InternalDecorator decorator,
|
||||
final WindowInfoImpl info,
|
||||
private void appendAddDecoratorCmd(@NotNull InternalDecorator decorator,
|
||||
@NotNull WindowInfoImpl info,
|
||||
final boolean dirtyMode,
|
||||
final List<FinalizableCommand> commandsList) {
|
||||
@NotNull List<FinalizableCommand> commandsList) {
|
||||
final CommandProcessor commandProcessor = myWindowManager.getCommandProcessor();
|
||||
final FinalizableCommand command = myToolWindowsPane.createAddDecoratorCmd(decorator, info, dirtyMode, commandProcessor);
|
||||
commandsList.add(command);
|
||||
@@ -1803,17 +1767,17 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements
|
||||
/**
|
||||
* @see ToolWindowsPane#createRemoveDecoratorCmd
|
||||
*/
|
||||
private void appendRemoveDecoratorCmd(final String id, final boolean dirtyMode, final List<FinalizableCommand> commandsList) {
|
||||
private void appendRemoveDecoratorCmd(@NotNull String id, final boolean dirtyMode, @NotNull List<FinalizableCommand> commandsList) {
|
||||
final FinalizableCommand command = myToolWindowsPane.createRemoveDecoratorCmd(id, dirtyMode, myWindowManager.getCommandProcessor());
|
||||
commandsList.add(command);
|
||||
}
|
||||
|
||||
private void appendRemoveFloatingDecoratorCmd(final WindowInfoImpl info, final List<FinalizableCommand> commandsList) {
|
||||
private void appendRemoveFloatingDecoratorCmd(@NotNull WindowInfoImpl info, @NotNull List<FinalizableCommand> commandsList) {
|
||||
final RemoveFloatingDecoratorCmd command = new RemoveFloatingDecoratorCmd(info);
|
||||
commandsList.add(command);
|
||||
}
|
||||
|
||||
private void appendRemoveWindowedDecoratorCmd(final WindowInfoImpl info, final List<FinalizableCommand> commandsList) {
|
||||
private void appendRemoveWindowedDecoratorCmd(@NotNull WindowInfoImpl info, @NotNull List<FinalizableCommand> commandsList) {
|
||||
final RemoveWindowedDecoratorCmd command = new RemoveWindowedDecoratorCmd(info);
|
||||
commandsList.add(command);
|
||||
}
|
||||
@@ -1821,7 +1785,7 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements
|
||||
/**
|
||||
* @see ToolWindowsPane#createAddButtonCmd
|
||||
*/
|
||||
private void appendAddButtonCmd(final StripeButton button, final WindowInfoImpl info, final List<FinalizableCommand> commandsList) {
|
||||
private void appendAddButtonCmd(final StripeButton button, @NotNull WindowInfoImpl info, @NotNull List<FinalizableCommand> commandsList) {
|
||||
final Comparator<StripeButton> comparator = myLayout.comparator(info.getAnchor());
|
||||
final CommandProcessor commandProcessor = myWindowManager.getCommandProcessor();
|
||||
final FinalizableCommand command = myToolWindowsPane.createAddButtonCmd(button, info, comparator, commandProcessor);
|
||||
@@ -1831,7 +1795,7 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements
|
||||
/**
|
||||
* @see ToolWindowsPane#createAddButtonCmd
|
||||
*/
|
||||
private void appendRemoveButtonCmd(final String id, final List<FinalizableCommand> commandsList) {
|
||||
private void appendRemoveButtonCmd(@NotNull String id, @NotNull List<FinalizableCommand> commandsList) {
|
||||
final FinalizableCommand command = myToolWindowsPane.createRemoveButtonCmd(id, myWindowManager.getCommandProcessor());
|
||||
commandsList.add(command);
|
||||
}
|
||||
@@ -1855,7 +1819,7 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements
|
||||
/**
|
||||
* @see ToolWindowsPane#createSetEditorComponentCmd
|
||||
*/
|
||||
public void appendSetEditorComponentCmd(@Nullable final JComponent component, final List<FinalizableCommand> commandsList) {
|
||||
private void appendSetEditorComponentCmd(@Nullable final JComponent component, @NotNull List<FinalizableCommand> commandsList) {
|
||||
final CommandProcessor commandProcessor = myWindowManager.getCommandProcessor();
|
||||
final FinalizableCommand command = myToolWindowsPane.createSetEditorComponentCmd(component, commandProcessor);
|
||||
commandsList.add(command);
|
||||
@@ -1885,36 +1849,6 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements
|
||||
return splitters != null ? splitters : fem.getSplitters();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return <code>true</code> if tool window with the specified <code>id</code>
|
||||
* is floating and has modal showing child dialog. Such windows should not be closed
|
||||
* when auto-hide windows are gone.
|
||||
*/
|
||||
private boolean hasModalChild(final WindowInfoImpl info) {
|
||||
if (!info.isVisible() || !info.isFloating()) {
|
||||
return false;
|
||||
}
|
||||
final FloatingDecorator decorator = getFloatingDecorator(info.getId());
|
||||
LOG.assertTrue(decorator != null);
|
||||
return isModalOrHasModalChild(decorator);
|
||||
}
|
||||
|
||||
private static boolean isModalOrHasModalChild(final Window window) {
|
||||
if (window instanceof Dialog) {
|
||||
final Dialog dialog = (Dialog)window;
|
||||
if (dialog.isModal() && dialog.isShowing()) {
|
||||
return true;
|
||||
}
|
||||
final Window[] ownedWindows = dialog.getOwnedWindows();
|
||||
for (int i = ownedWindows.length - 1; i >= 0; i--) {
|
||||
if (isModalOrHasModalChild(ownedWindows[i])) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearSideStack() {
|
||||
mySideStack.clear();
|
||||
@@ -2000,14 +1934,14 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements
|
||||
}
|
||||
}
|
||||
|
||||
public void setDefaultContentUiType(ToolWindowImpl toolWindow, @NotNull ToolWindowContentUiType type) {
|
||||
void setDefaultContentUiType(@NotNull ToolWindowImpl toolWindow, @NotNull ToolWindowContentUiType type) {
|
||||
final WindowInfoImpl info = getInfo(toolWindow.getId());
|
||||
if (info.wasRead()) return;
|
||||
toolWindow.setContentUiType(type, null);
|
||||
}
|
||||
|
||||
|
||||
public void stretchWidth(ToolWindowImpl toolWindow, int value) {
|
||||
void stretchWidth(@NotNull ToolWindowImpl toolWindow, int value) {
|
||||
myToolWindowsPane.stretchWidth(toolWindow, value);
|
||||
}
|
||||
|
||||
@@ -2021,7 +1955,7 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements
|
||||
myToolWindowsPane.setMaximized(wnd, maximized);
|
||||
}
|
||||
|
||||
public void stretchHeight(ToolWindowImpl toolWindow, int value) {
|
||||
void stretchHeight(ToolWindowImpl toolWindow, int value) {
|
||||
myToolWindowsPane.stretchHeight(toolWindow, value);
|
||||
}
|
||||
|
||||
@@ -2029,7 +1963,7 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements
|
||||
private Balloon myBalloon;
|
||||
private final HyperlinkListener myListener;
|
||||
|
||||
public BalloonHyperlinkListener(HyperlinkListener listener) {
|
||||
BalloonHyperlinkListener(HyperlinkListener listener) {
|
||||
myListener = listener;
|
||||
}
|
||||
|
||||
@@ -2054,7 +1988,7 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements
|
||||
/**
|
||||
* Creates floating decorator for specified internal decorator.
|
||||
*/
|
||||
private AddFloatingDecoratorCmd(final InternalDecorator decorator, final WindowInfoImpl info) {
|
||||
private AddFloatingDecoratorCmd(@NotNull InternalDecorator decorator, @NotNull WindowInfoImpl info) {
|
||||
super(myWindowManager.getCommandProcessor());
|
||||
myFloatingDecorator = new FloatingDecorator(myFrame, info.copy(), decorator);
|
||||
myId2FloatingDecorator.put(info.getId(), myFloatingDecorator);
|
||||
@@ -2093,7 +2027,7 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements
|
||||
private final class RemoveFloatingDecoratorCmd extends FinalizableCommand {
|
||||
private final FloatingDecorator myFloatingDecorator;
|
||||
|
||||
private RemoveFloatingDecoratorCmd(final WindowInfoImpl info) {
|
||||
private RemoveFloatingDecoratorCmd(@NotNull WindowInfoImpl info) {
|
||||
super(myWindowManager.getCommandProcessor());
|
||||
myFloatingDecorator = getFloatingDecorator(info.getId());
|
||||
myId2FloatingDecorator.remove(info.getId());
|
||||
@@ -2126,7 +2060,7 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements
|
||||
/**
|
||||
* Creates windowed decorator for specified internal decorator.
|
||||
*/
|
||||
private AddWindowedDecoratorCmd(final InternalDecorator decorator, final WindowInfoImpl info) {
|
||||
private AddWindowedDecoratorCmd(@NotNull InternalDecorator decorator, @NotNull WindowInfoImpl info) {
|
||||
super(myWindowManager.getCommandProcessor());
|
||||
myWindowedDecorator = new WindowedDecorator(myProject, info.copy(), decorator);
|
||||
Window window = myWindowedDecorator.getFrame();
|
||||
@@ -2146,12 +2080,9 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements
|
||||
window.setLocationRelativeTo(myFrame);
|
||||
}
|
||||
myId2WindowedDecorator.put(info.getId(), myWindowedDecorator);
|
||||
myWindowedDecorator.addDisposable(new Disposable() {
|
||||
@Override
|
||||
public void dispose() {
|
||||
if (myId2WindowedDecorator.get(info.getId()) != null) {
|
||||
hideToolWindow(info.getId(), false);
|
||||
}
|
||||
myWindowedDecorator.addDisposable(() -> {
|
||||
if (myId2WindowedDecorator.get(info.getId()) != null) {
|
||||
hideToolWindow(info.getId(), false);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -2183,7 +2114,7 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements
|
||||
private final class RemoveWindowedDecoratorCmd extends FinalizableCommand {
|
||||
private final WindowedDecorator myWindowedDecorator;
|
||||
|
||||
private RemoveWindowedDecoratorCmd(final WindowInfoImpl info) {
|
||||
private RemoveWindowedDecoratorCmd(@NotNull WindowInfoImpl info) {
|
||||
super(myWindowManager.getCommandProcessor());
|
||||
myWindowedDecorator = getWindowedDecorator(info.getId());
|
||||
myId2WindowedDecorator.remove(info.getId());
|
||||
@@ -2255,8 +2186,7 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements
|
||||
private final String myId;
|
||||
private final ToolWindowImpl myToolWindow;
|
||||
|
||||
|
||||
private ToolWindowFocusWatcher(final ToolWindowImpl toolWindow) {
|
||||
private ToolWindowFocusWatcher(@NotNull ToolWindowImpl toolWindow) {
|
||||
myId = toolWindow.getId();
|
||||
install(toolWindow.getComponent());
|
||||
myToolWindow = toolWindow;
|
||||
@@ -2317,27 +2247,27 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements
|
||||
*/
|
||||
private final class MyInternalDecoratorListener implements InternalDecoratorListener {
|
||||
@Override
|
||||
public void anchorChanged(final InternalDecorator source, final ToolWindowAnchor anchor) {
|
||||
public void anchorChanged(@NotNull final InternalDecorator source, @NotNull final ToolWindowAnchor anchor) {
|
||||
setToolWindowAnchor(source.getToolWindow().getId(), anchor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void autoHideChanged(final InternalDecorator source, final boolean autoHide) {
|
||||
public void autoHideChanged(@NotNull final InternalDecorator source, final boolean autoHide) {
|
||||
setToolWindowAutoHide(source.getToolWindow().getId(), autoHide);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void hidden(final InternalDecorator source) {
|
||||
public void hidden(@NotNull final InternalDecorator source) {
|
||||
hideToolWindow(source.getToolWindow().getId(), false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void hiddenSide(final InternalDecorator source) {
|
||||
public void hiddenSide(@NotNull final InternalDecorator source) {
|
||||
hideToolWindow(source.getToolWindow().getId(), true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void contentUiTypeChanges(InternalDecorator source, @NotNull ToolWindowContentUiType type) {
|
||||
public void contentUiTypeChanges(@NotNull InternalDecorator source, @NotNull ToolWindowContentUiType type) {
|
||||
setContentUiType(source.getToolWindow().getId(), type);
|
||||
}
|
||||
|
||||
@@ -2346,13 +2276,12 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements
|
||||
* tool window depending on decoration type.
|
||||
*/
|
||||
@Override
|
||||
public void resized(final InternalDecorator source) {
|
||||
public void resized(@NotNull final InternalDecorator source) {
|
||||
if (!source.isShowing()) {
|
||||
return; // do not recalculate the tool window size if it is not yet shown (and, therefore, has 0,0,0,0 bounds)
|
||||
}
|
||||
|
||||
final WindowInfoImpl info = getInfo(source.getToolWindow().getId());
|
||||
InternalDecorator another = null;
|
||||
if (info.isFloating()) {
|
||||
final Window owner = SwingUtilities.getWindowAncestor(source);
|
||||
if (owner != null) {
|
||||
@@ -2367,6 +2296,7 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements
|
||||
}
|
||||
else { // docked and sliding windows
|
||||
ToolWindowAnchor anchor = info.getAnchor();
|
||||
InternalDecorator another = null;
|
||||
if (source.getParent() instanceof Splitter) {
|
||||
float sizeInSplit = anchor.isSplitVertically() ? source.getHeight() : source.getWidth();
|
||||
Splitter splitter = (Splitter)source.getParent();
|
||||
@@ -2399,21 +2329,22 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements
|
||||
}
|
||||
|
||||
@Override
|
||||
public void activated(final InternalDecorator source) {
|
||||
public void activated(@NotNull final InternalDecorator source) {
|
||||
activateToolWindow(source.getToolWindow().getId(), true, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void typeChanged(final InternalDecorator source, final ToolWindowType type) {
|
||||
public void typeChanged(@NotNull final InternalDecorator source, @NotNull final ToolWindowType type) {
|
||||
setToolWindowType(source.getToolWindow().getId(), type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sideStatusChanged(final InternalDecorator source, final boolean isSideTool) {
|
||||
public void sideStatusChanged(@NotNull final InternalDecorator source, final boolean isSideTool) {
|
||||
setSideTool(source.getToolWindow().getId(), isSideTool);
|
||||
}
|
||||
|
||||
public void visibleStripeButtonChanged(InternalDecorator source, boolean visible) {
|
||||
@Override
|
||||
public void visibleStripeButtonChanged(@NotNull InternalDecorator source, boolean visible) {
|
||||
setShowStripeButton(source.getToolWindow().getId(), visible);
|
||||
}
|
||||
}
|
||||
@@ -2546,11 +2477,12 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements
|
||||
return IdeFocusManager.getInstance(myProject).dispatch(e);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Expirable getTimestamp(boolean trackOnlyForcedCommands) {
|
||||
return IdeFocusManager.getInstance(myProject).getTimestamp(trackOnlyForcedCommands);
|
||||
}
|
||||
|
||||
public void setShowStripeButton(String id, boolean visibleOnPanel) {
|
||||
void setShowStripeButton(@NotNull String id, boolean visibleOnPanel) {
|
||||
checkId(id);
|
||||
WindowInfoImpl info = getInfo(id);
|
||||
if (visibleOnPanel == info.isShowStripeButton()) {
|
||||
@@ -2559,12 +2491,12 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements
|
||||
info.setShowStripeButton(visibleOnPanel);
|
||||
UsageTrigger.trigger("StripeButton[" + id + "]." + (visibleOnPanel ? "shown" : "hidden"));
|
||||
|
||||
final ArrayList<FinalizableCommand> commandList = new ArrayList<FinalizableCommand>();
|
||||
List<FinalizableCommand> commandList = new ArrayList<>();
|
||||
appendApplyWindowInfoCmd(info, commandList);
|
||||
execute(commandList);
|
||||
}
|
||||
|
||||
public boolean isShowStripeButton(String id) {
|
||||
boolean isShowStripeButton(@NotNull String id) {
|
||||
WindowInfoImpl info = getInfo(id);
|
||||
return info == null || info.isShowStripeButton();
|
||||
}
|
||||
|
||||
@@ -42,10 +42,10 @@ import org.jetbrains.annotations.Nullable;
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.lang.ref.Reference;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* This panel contains all tool stripes and JLayeredPanle at the center area. All tool windows are
|
||||
@@ -59,12 +59,12 @@ public final class ToolWindowsPane extends JBLayeredPane implements UISettingsLi
|
||||
|
||||
private final IdeFrameImpl myFrame;
|
||||
|
||||
private final HashMap<String, StripeButton> myId2Button;
|
||||
private final HashMap<String, InternalDecorator> myId2Decorator;
|
||||
private final HashMap<StripeButton, WindowInfoImpl> myButton2Info;
|
||||
private final HashMap<InternalDecorator, WindowInfoImpl> myDecorator2Info;
|
||||
private final HashMap<String, Float> myId2SplitProportion;
|
||||
private Pair<ToolWindow, Integer> myMaximizedProportion = null;
|
||||
private final HashMap<String, StripeButton> myId2Button = new HashMap<>();
|
||||
private final HashMap<String, InternalDecorator> myId2Decorator = new HashMap<>();
|
||||
private final HashMap<StripeButton, WindowInfoImpl> myButton2Info = new HashMap<>();
|
||||
private final HashMap<InternalDecorator, WindowInfoImpl> myDecorator2Info = new HashMap<>();
|
||||
private final HashMap<String, Float> myId2SplitProportion = new HashMap<>();
|
||||
private Pair<ToolWindow, Integer> myMaximizedProportion;
|
||||
/**
|
||||
* This panel is the layered pane where all sliding tool windows are located. The DEFAULT
|
||||
* layer contains splitters. The PALETTE layer contains all sliding tool windows.
|
||||
@@ -84,29 +84,23 @@ public final class ToolWindowsPane extends JBLayeredPane implements UISettingsLi
|
||||
private final Stripe myBottomStripe;
|
||||
private final Stripe myTopStripe;
|
||||
|
||||
private final ArrayList<Stripe> myStripes = new ArrayList<Stripe>();
|
||||
private final List<Stripe> myStripes = new ArrayList<>();
|
||||
|
||||
private final ToolWindowManagerImpl myManager;
|
||||
|
||||
private boolean myStripesOverlayed;
|
||||
private final Disposable myDisposable = Disposer.newDisposable();
|
||||
private boolean myWidescreen = false;
|
||||
private boolean myLeftHorizontalSplit = false;
|
||||
private boolean myRightHorizontalSplit = false;
|
||||
private boolean myWidescreen;
|
||||
private boolean myLeftHorizontalSplit;
|
||||
private boolean myRightHorizontalSplit;
|
||||
|
||||
ToolWindowsPane(final IdeFrameImpl frame, ToolWindowManagerImpl manager) {
|
||||
ToolWindowsPane(@NotNull IdeFrameImpl frame, @NotNull ToolWindowManagerImpl manager) {
|
||||
myManager = manager;
|
||||
|
||||
setOpaque(false);
|
||||
myFrame = frame;
|
||||
myId2Button = new HashMap<String, StripeButton>();
|
||||
myId2Decorator = new HashMap<String, InternalDecorator>();
|
||||
myButton2Info = new HashMap<StripeButton, WindowInfoImpl>();
|
||||
myDecorator2Info = new HashMap<InternalDecorator, WindowInfoImpl>();
|
||||
myId2SplitProportion = new HashMap<String, Float>();
|
||||
|
||||
// Splitters
|
||||
|
||||
myVerticalSplitter = new ThreeComponentsSplitter(true);
|
||||
Disposer.register(this, myVerticalSplitter);
|
||||
myVerticalSplitter.setDividerWidth(0);
|
||||
@@ -193,6 +187,7 @@ public final class ToolWindowsPane extends JBLayeredPane implements UISettingsLi
|
||||
/**
|
||||
* Invoked when enclosed frame is being shown.
|
||||
*/
|
||||
@Override
|
||||
public final void addNotify() {
|
||||
super.addNotify();
|
||||
}
|
||||
@@ -200,6 +195,7 @@ public final class ToolWindowsPane extends JBLayeredPane implements UISettingsLi
|
||||
/**
|
||||
* Invoked when enclosed frame is being disposed.
|
||||
*/
|
||||
@Override
|
||||
public final void removeNotify() {
|
||||
if (ScreenUtil.isStandardAddRemoveNotify(this)) {
|
||||
Disposer.dispose(myDisposable);
|
||||
@@ -211,6 +207,7 @@ public final class ToolWindowsPane extends JBLayeredPane implements UISettingsLi
|
||||
return myFrame.getProject();
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void uiSettingsChanged(final UISettings source) {
|
||||
updateToolStripesVisibility();
|
||||
updateLayout();
|
||||
@@ -225,10 +222,11 @@ public final class ToolWindowsPane extends JBLayeredPane implements UISettingsLi
|
||||
* @param comparator which is used to sort buttons within the stripe.
|
||||
* @param finishCallBack invoked when the command is completed.
|
||||
*/
|
||||
@NotNull
|
||||
final FinalizableCommand createAddButtonCmd(final StripeButton button,
|
||||
final WindowInfoImpl info,
|
||||
final Comparator<StripeButton> comparator,
|
||||
final Runnable finishCallBack) {
|
||||
@NotNull WindowInfoImpl info,
|
||||
@NotNull Comparator<StripeButton> comparator,
|
||||
@NotNull Runnable finishCallBack) {
|
||||
final WindowInfoImpl copiedInfo = info.copy();
|
||||
myId2Button.put(copiedInfo.getId(), button);
|
||||
myButton2Info.put(button, copiedInfo);
|
||||
@@ -242,12 +240,11 @@ public final class ToolWindowsPane extends JBLayeredPane implements UISettingsLi
|
||||
* @param dirtyMode if <code>true</code> then JRootPane will not be validated and repainted after adding
|
||||
* the decorator. Moreover in this (dirty) mode animation doesn't work.
|
||||
*/
|
||||
final FinalizableCommand createAddDecoratorCmd(
|
||||
final InternalDecorator decorator,
|
||||
final WindowInfoImpl info,
|
||||
final boolean dirtyMode,
|
||||
final Runnable finishCallBack
|
||||
) {
|
||||
@NotNull
|
||||
final FinalizableCommand createAddDecoratorCmd(@NotNull InternalDecorator decorator,
|
||||
@NotNull WindowInfoImpl info,
|
||||
final boolean dirtyMode,
|
||||
@NotNull Runnable finishCallBack) {
|
||||
final WindowInfoImpl copiedInfo = info.copy();
|
||||
final String id = copiedInfo.getId();
|
||||
|
||||
@@ -276,10 +273,11 @@ public final class ToolWindowsPane extends JBLayeredPane implements UISettingsLi
|
||||
*
|
||||
* @param id <code>ID</code> of the button to be removed.
|
||||
*/
|
||||
final FinalizableCommand createRemoveButtonCmd(final String id, final Runnable finishCallBack) {
|
||||
@NotNull
|
||||
final FinalizableCommand createRemoveButtonCmd(@NotNull String id, @NotNull Runnable finishCallBack) {
|
||||
final StripeButton button = getButtonById(id);
|
||||
final WindowInfoImpl info = getButtonInfoById(id);
|
||||
//
|
||||
|
||||
myButton2Info.remove(button);
|
||||
myId2Button.remove(id);
|
||||
return new RemoveToolStripeButtonCmd(button, info, finishCallBack);
|
||||
@@ -291,7 +289,8 @@ public final class ToolWindowsPane extends JBLayeredPane implements UISettingsLi
|
||||
* @param dirtyMode if <code>true</code> then JRootPane will not be validated and repainted after removing
|
||||
* the decorator. Moreover in this (dirty) mode animation doesn't work.
|
||||
*/
|
||||
final FinalizableCommand createRemoveDecoratorCmd(final String id, final boolean dirtyMode, final Runnable finishCallBack) {
|
||||
@NotNull
|
||||
final FinalizableCommand createRemoveDecoratorCmd(@NotNull String id, final boolean dirtyMode, @NotNull Runnable finishCallBack) {
|
||||
final Component decorator = getDecoratorById(id);
|
||||
final WindowInfoImpl info = getDecoratorInfoById(id);
|
||||
|
||||
@@ -321,14 +320,17 @@ public final class ToolWindowsPane extends JBLayeredPane implements UISettingsLi
|
||||
*
|
||||
* @param component component to be set.
|
||||
*/
|
||||
final FinalizableCommand createSetEditorComponentCmd(final JComponent component, final Runnable finishCallBack) {
|
||||
@NotNull
|
||||
final FinalizableCommand createSetEditorComponentCmd(final JComponent component, @NotNull Runnable finishCallBack) {
|
||||
return new SetEditorComponentCmd(component, finishCallBack);
|
||||
}
|
||||
|
||||
final FinalizableCommand createUpdateButtonPositionCmd(String id, final Runnable finishCallback) {
|
||||
@NotNull
|
||||
final FinalizableCommand createUpdateButtonPositionCmd(@NotNull String id, @NotNull Runnable finishCallback) {
|
||||
return new UpdateButtonPositionCmd(id, finishCallback);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public final JComponent getMyLayeredPane() {
|
||||
return myLayeredPane;
|
||||
}
|
||||
@@ -361,7 +363,7 @@ public final class ToolWindowsPane extends JBLayeredPane implements UISettingsLi
|
||||
/**
|
||||
* Sets (docks) specified component to the specified anchor.
|
||||
*/
|
||||
private void setComponent(final JComponent component, final ToolWindowAnchor anchor, final float weight) {
|
||||
private void setComponent(final JComponent component, @NotNull ToolWindowAnchor anchor, final float weight) {
|
||||
if (ToolWindowAnchor.TOP == anchor) {
|
||||
myVerticalSplitter.setFirstComponent(component);
|
||||
myVerticalSplitter.setFirstSize((int)(myLayeredPane.getHeight() * weight));
|
||||
@@ -383,7 +385,7 @@ public final class ToolWindowsPane extends JBLayeredPane implements UISettingsLi
|
||||
}
|
||||
}
|
||||
|
||||
private JComponent getComponentAt(ToolWindowAnchor anchor) {
|
||||
private JComponent getComponentAt(@NotNull ToolWindowAnchor anchor) {
|
||||
if (ToolWindowAnchor.TOP == anchor) {
|
||||
return myVerticalSplitter.getFirstComponent();
|
||||
}
|
||||
@@ -402,12 +404,12 @@ public final class ToolWindowsPane extends JBLayeredPane implements UISettingsLi
|
||||
}
|
||||
}
|
||||
|
||||
private float getPreferredSplitProportion(String id, float defaultValue) {
|
||||
private float getPreferredSplitProportion(@NotNull String id, float defaultValue) {
|
||||
Float f = myId2SplitProportion.get(id);
|
||||
return (f == null ? defaultValue : f);
|
||||
return f == null ? defaultValue : f;
|
||||
}
|
||||
|
||||
private WindowInfoImpl getDockedInfoAt(ToolWindowAnchor anchor, boolean side) {
|
||||
private WindowInfoImpl getDockedInfoAt(@NotNull ToolWindowAnchor anchor, boolean side) {
|
||||
for (WindowInfoImpl info : myDecorator2Info.values()) {
|
||||
if (info.isVisible() && info.isDocked() && info.getAnchor() == anchor && side == info.isSplit()) {
|
||||
return info;
|
||||
@@ -417,7 +419,7 @@ public final class ToolWindowsPane extends JBLayeredPane implements UISettingsLi
|
||||
return null;
|
||||
}
|
||||
|
||||
public void setDocumentComponent(final JComponent component) {
|
||||
private void setDocumentComponent(final JComponent component) {
|
||||
(myWidescreen ? myVerticalSplitter : myHorizontalSplitter).setInnerComponent(component);
|
||||
}
|
||||
|
||||
@@ -464,13 +466,13 @@ public final class ToolWindowsPane extends JBLayeredPane implements UISettingsLi
|
||||
if (ToolWindowAnchor.TOP == anchor) {
|
||||
return myTopStripe;
|
||||
}
|
||||
else if (ToolWindowAnchor.BOTTOM == anchor) {
|
||||
if (ToolWindowAnchor.BOTTOM == anchor) {
|
||||
return myBottomStripe;
|
||||
}
|
||||
else if (ToolWindowAnchor.LEFT == anchor) {
|
||||
if (ToolWindowAnchor.LEFT == anchor) {
|
||||
return myLeftStripe;
|
||||
}
|
||||
else if (ToolWindowAnchor.RIGHT == anchor) {
|
||||
if (ToolWindowAnchor.RIGHT == anchor) {
|
||||
return myRightStripe;
|
||||
}
|
||||
|
||||
@@ -478,7 +480,7 @@ public final class ToolWindowsPane extends JBLayeredPane implements UISettingsLi
|
||||
}
|
||||
|
||||
@Nullable
|
||||
Stripe getStripeFor(final Rectangle screenRec, Stripe preferred) {
|
||||
Stripe getStripeFor(@NotNull Rectangle screenRec, @NotNull Stripe preferred) {
|
||||
if (preferred.containsScreen(screenRec)) {
|
||||
return myStripes.get(myStripes.indexOf(preferred));
|
||||
}
|
||||
@@ -504,15 +506,15 @@ public final class ToolWindowsPane extends JBLayeredPane implements UISettingsLi
|
||||
}
|
||||
}
|
||||
|
||||
public void stretchWidth(ToolWindow wnd, int value) {
|
||||
void stretchWidth(@NotNull ToolWindow wnd, int value) {
|
||||
stretch(wnd, value);
|
||||
}
|
||||
|
||||
public void stretchHeight(ToolWindow wnd, int value) {
|
||||
void stretchHeight(@NotNull ToolWindow wnd, int value) {
|
||||
stretch(wnd, value);
|
||||
}
|
||||
|
||||
private void stretch(ToolWindow wnd, int value) {
|
||||
private void stretch(@NotNull ToolWindow wnd, int value) {
|
||||
Pair<Resizer, Component> pair = findResizerAndComponent(wnd);
|
||||
if (pair == null) return;
|
||||
|
||||
@@ -520,13 +522,13 @@ public final class ToolWindowsPane extends JBLayeredPane implements UISettingsLi
|
||||
int actualSize = (vertical ? pair.second.getHeight() : pair.second.getWidth()) + value;
|
||||
boolean first = wnd.getAnchor() == ToolWindowAnchor.LEFT || wnd.getAnchor() == ToolWindowAnchor.TOP;
|
||||
int maxValue = vertical ? myVerticalSplitter.getMaxSize(first) : myHorizontalSplitter.getMaxSize(first);
|
||||
int minValue = vertical ? myVerticalSplitter.getMinSize(first) : myHorizontalSplitter.getMinSize(first);;
|
||||
int minValue = vertical ? myVerticalSplitter.getMinSize(first) : myHorizontalSplitter.getMinSize(first);
|
||||
|
||||
pair.first.setSize(Math.max(minValue, Math.min(maxValue, actualSize)));
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private Pair<Resizer, Component> findResizerAndComponent(ToolWindow wnd) {
|
||||
private Pair<Resizer, Component> findResizerAndComponent(@NotNull ToolWindow wnd) {
|
||||
if (!wnd.isVisible()) return null;
|
||||
|
||||
Resizer resizer = null;
|
||||
@@ -620,7 +622,7 @@ public final class ToolWindowsPane extends JBLayeredPane implements UISettingsLi
|
||||
return myMaximizedProportion != null && myMaximizedProportion.first == wnd;
|
||||
}
|
||||
|
||||
public void setMaximized(@NotNull ToolWindow wnd, boolean maximized) {
|
||||
void setMaximized(@NotNull ToolWindow wnd, boolean maximized) {
|
||||
Pair<Resizer, Component> resizerAndComponent = findResizerAndComponent(wnd);
|
||||
if (resizerAndComponent == null) return;
|
||||
|
||||
@@ -638,6 +640,7 @@ public final class ToolWindowsPane extends JBLayeredPane implements UISettingsLi
|
||||
}
|
||||
|
||||
|
||||
@FunctionalInterface
|
||||
interface Resizer {
|
||||
void setSize(int size);
|
||||
|
||||
@@ -645,25 +648,27 @@ public final class ToolWindowsPane extends JBLayeredPane implements UISettingsLi
|
||||
abstract class Splitter implements Resizer {
|
||||
ThreeComponentsSplitter mySplitter;
|
||||
|
||||
Splitter(ThreeComponentsSplitter splitter) {
|
||||
Splitter(@NotNull ThreeComponentsSplitter splitter) {
|
||||
mySplitter = splitter;
|
||||
}
|
||||
|
||||
static class FirstComponent extends Splitter {
|
||||
FirstComponent(ThreeComponentsSplitter splitter) {
|
||||
FirstComponent(@NotNull ThreeComponentsSplitter splitter) {
|
||||
super(splitter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSize(int size) {
|
||||
mySplitter.setFirstSize(size);
|
||||
}
|
||||
}
|
||||
|
||||
static class LastComponent extends Splitter {
|
||||
LastComponent(ThreeComponentsSplitter splitter) {
|
||||
LastComponent(@NotNull ThreeComponentsSplitter splitter) {
|
||||
super(splitter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSize(int size) {
|
||||
mySplitter.setLastSize(size);
|
||||
}
|
||||
@@ -673,10 +678,11 @@ public final class ToolWindowsPane extends JBLayeredPane implements UISettingsLi
|
||||
abstract class LayeredPane implements Resizer {
|
||||
Component myComponent;
|
||||
|
||||
protected LayeredPane(Component component) {
|
||||
LayeredPane(@NotNull Component component) {
|
||||
myComponent = component;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void setSize(int size) {
|
||||
_setSize(size);
|
||||
if (myComponent.getParent() instanceof JComponent) {
|
||||
@@ -690,20 +696,22 @@ public final class ToolWindowsPane extends JBLayeredPane implements UISettingsLi
|
||||
|
||||
static class Left extends LayeredPane {
|
||||
|
||||
Left(Component component) {
|
||||
Left(@NotNull Component component) {
|
||||
super(component);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void _setSize(int size) {
|
||||
myComponent.setSize(size, myComponent.getHeight());
|
||||
}
|
||||
}
|
||||
|
||||
static class Right extends LayeredPane {
|
||||
Right(Component component) {
|
||||
Right(@NotNull Component component) {
|
||||
super(component);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void _setSize(int size) {
|
||||
Rectangle bounds = myComponent.getBounds();
|
||||
int delta = size - bounds.width;
|
||||
@@ -714,20 +722,22 @@ public final class ToolWindowsPane extends JBLayeredPane implements UISettingsLi
|
||||
}
|
||||
|
||||
static class Top extends LayeredPane {
|
||||
Top(Component component) {
|
||||
Top(@NotNull Component component) {
|
||||
super(component);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void _setSize(int size) {
|
||||
myComponent.setSize(myComponent.getWidth(), size);
|
||||
}
|
||||
}
|
||||
|
||||
static class Bottom extends LayeredPane {
|
||||
Bottom(Component component) {
|
||||
Bottom(@NotNull Component component) {
|
||||
super(component);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void _setSize(int size) {
|
||||
Rectangle bounds = myComponent.getBounds();
|
||||
int delta = size - bounds.height;
|
||||
@@ -744,16 +754,17 @@ public final class ToolWindowsPane extends JBLayeredPane implements UISettingsLi
|
||||
private final WindowInfoImpl myInfo;
|
||||
private final boolean myDirtyMode;
|
||||
|
||||
public AddDockedComponentCmd(final JComponent component,
|
||||
final WindowInfoImpl info,
|
||||
public AddDockedComponentCmd(@NotNull JComponent component,
|
||||
@NotNull WindowInfoImpl info,
|
||||
final boolean dirtyMode,
|
||||
final Runnable finishCallBack) {
|
||||
@NotNull Runnable finishCallBack) {
|
||||
super(finishCallBack);
|
||||
myComponent = component;
|
||||
myInfo = info;
|
||||
myDirtyMode = dirtyMode;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void run() {
|
||||
try {
|
||||
final ToolWindowAnchor anchor = myInfo.getAnchor();
|
||||
@@ -774,17 +785,19 @@ public final class ToolWindowsPane extends JBLayeredPane implements UISettingsLi
|
||||
private final WindowInfoImpl myInfo;
|
||||
private final boolean myDirtyMode;
|
||||
|
||||
private AddAndSplitDockedComponentCmd(final JComponent newComponent,
|
||||
final WindowInfoImpl info, final boolean dirtyMode, final Runnable finishCallBack) {
|
||||
private AddAndSplitDockedComponentCmd(@NotNull JComponent newComponent,
|
||||
@NotNull WindowInfoImpl info,
|
||||
final boolean dirtyMode,
|
||||
@NotNull Runnable finishCallBack) {
|
||||
super(finishCallBack);
|
||||
myNewComponent = newComponent;
|
||||
myInfo = info;
|
||||
myDirtyMode = dirtyMode;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
float newWeight;
|
||||
final ToolWindowAnchor anchor = myInfo.getAnchor();
|
||||
class MySplitter extends Splitter implements UISettingsListener {
|
||||
@Override
|
||||
@@ -801,28 +814,26 @@ public final class ToolWindowsPane extends JBLayeredPane implements UISettingsLi
|
||||
splitter.setOrientation(anchor.isSplitVertically());
|
||||
if (!anchor.isHorizontal()) {
|
||||
splitter.setAllowSwitchOrientationByMouseClick(true);
|
||||
splitter.addPropertyChangeListener(new PropertyChangeListener() {
|
||||
@Override
|
||||
public void propertyChange(PropertyChangeEvent evt) {
|
||||
if (!Splitter.PROP_ORIENTATION.equals(evt.getPropertyName())) return;
|
||||
boolean isSplitterHorizontalNow = !splitter.isVertical();
|
||||
UISettings settings = UISettings.getInstance();
|
||||
if (anchor == ToolWindowAnchor.LEFT) {
|
||||
if (settings.LEFT_HORIZONTAL_SPLIT != isSplitterHorizontalNow) {
|
||||
settings.LEFT_HORIZONTAL_SPLIT = isSplitterHorizontalNow;
|
||||
settings.fireUISettingsChanged();
|
||||
}
|
||||
splitter.addPropertyChangeListener(evt -> {
|
||||
if (!Splitter.PROP_ORIENTATION.equals(evt.getPropertyName())) return;
|
||||
boolean isSplitterHorizontalNow = !splitter.isVertical();
|
||||
UISettings settings = UISettings.getInstance();
|
||||
if (anchor == ToolWindowAnchor.LEFT) {
|
||||
if (settings.LEFT_HORIZONTAL_SPLIT != isSplitterHorizontalNow) {
|
||||
settings.LEFT_HORIZONTAL_SPLIT = isSplitterHorizontalNow;
|
||||
settings.fireUISettingsChanged();
|
||||
}
|
||||
if (anchor == ToolWindowAnchor.RIGHT) {
|
||||
if (settings.RIGHT_HORIZONTAL_SPLIT != isSplitterHorizontalNow) {
|
||||
settings.RIGHT_HORIZONTAL_SPLIT = isSplitterHorizontalNow;
|
||||
settings.fireUISettingsChanged();
|
||||
}
|
||||
}
|
||||
if (anchor == ToolWindowAnchor.RIGHT) {
|
||||
if (settings.RIGHT_HORIZONTAL_SPLIT != isSplitterHorizontalNow) {
|
||||
settings.RIGHT_HORIZONTAL_SPLIT = isSplitterHorizontalNow;
|
||||
settings.fireUISettingsChanged();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
JComponent c = getComponentAt(anchor);
|
||||
float newWeight;
|
||||
if (c instanceof InternalDecorator) {
|
||||
InternalDecorator oldComponent = (InternalDecorator)c;
|
||||
if (myInfo.isSplit()) {
|
||||
@@ -872,15 +883,16 @@ public final class ToolWindowsPane extends JBLayeredPane implements UISettingsLi
|
||||
private final WindowInfoImpl myInfo;
|
||||
private final boolean myDirtyMode;
|
||||
|
||||
public AddSlidingComponentCmd(final Component component,
|
||||
final WindowInfoImpl info,
|
||||
public AddSlidingComponentCmd(@NotNull Component component,
|
||||
@NotNull WindowInfoImpl info,
|
||||
final boolean dirtyMode,
|
||||
final Runnable finishCallBack) {
|
||||
@NotNull Runnable finishCallBack) {
|
||||
super(finishCallBack);
|
||||
myComponent = component;
|
||||
myInfo = info;
|
||||
myDirtyMode = dirtyMode;
|
||||
}
|
||||
@Override
|
||||
public final void run() {
|
||||
try {
|
||||
// Show component.
|
||||
@@ -946,15 +958,16 @@ public final class ToolWindowsPane extends JBLayeredPane implements UISettingsLi
|
||||
private final Comparator<StripeButton> myComparator;
|
||||
|
||||
public AddToolStripeButtonCmd(final StripeButton button,
|
||||
final WindowInfoImpl info,
|
||||
final Comparator<StripeButton> comparator,
|
||||
final Runnable finishCallBack) {
|
||||
@NotNull WindowInfoImpl info,
|
||||
@NotNull Comparator<StripeButton> comparator,
|
||||
@NotNull Runnable finishCallBack) {
|
||||
super(finishCallBack);
|
||||
myButton = button;
|
||||
myInfo = info;
|
||||
myComparator = comparator;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void run() {
|
||||
try {
|
||||
final ToolWindowAnchor anchor = myInfo.getAnchor();
|
||||
@@ -986,12 +999,13 @@ public final class ToolWindowsPane extends JBLayeredPane implements UISettingsLi
|
||||
private final StripeButton myButton;
|
||||
private final WindowInfoImpl myInfo;
|
||||
|
||||
public RemoveToolStripeButtonCmd(final StripeButton button, final WindowInfoImpl info, final Runnable finishCallBack) {
|
||||
public RemoveToolStripeButtonCmd(@NotNull StripeButton button, @NotNull WindowInfoImpl info, @NotNull Runnable finishCallBack) {
|
||||
super(finishCallBack);
|
||||
myButton = button;
|
||||
myInfo = info;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void run() {
|
||||
try {
|
||||
final ToolWindowAnchor anchor = myInfo.getAnchor();
|
||||
@@ -1023,12 +1037,13 @@ public final class ToolWindowsPane extends JBLayeredPane implements UISettingsLi
|
||||
private final WindowInfoImpl myInfo;
|
||||
private final boolean myDirtyMode;
|
||||
|
||||
public RemoveDockedComponentCmd(final WindowInfoImpl info, final boolean dirtyMode, final Runnable finishCallBack) {
|
||||
public RemoveDockedComponentCmd(@NotNull WindowInfoImpl info, final boolean dirtyMode, @NotNull Runnable finishCallBack) {
|
||||
super(finishCallBack);
|
||||
myInfo = info;
|
||||
myDirtyMode = dirtyMode;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void run() {
|
||||
try {
|
||||
setComponent(null, myInfo.getAnchor(), 0);
|
||||
@@ -1047,14 +1062,15 @@ public final class ToolWindowsPane extends JBLayeredPane implements UISettingsLi
|
||||
private final WindowInfoImpl myInfo;
|
||||
private final boolean myDirtyMode;
|
||||
|
||||
private RemoveSplitAndDockedComponentCmd(final WindowInfoImpl info,
|
||||
private RemoveSplitAndDockedComponentCmd(@NotNull WindowInfoImpl info,
|
||||
boolean dirtyMode,
|
||||
final Runnable finishCallBack) {
|
||||
@NotNull Runnable finishCallBack) {
|
||||
super(finishCallBack);
|
||||
myInfo = info;
|
||||
myDirtyMode = dirtyMode;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
ToolWindowAnchor anchor = myInfo.getAnchor();
|
||||
@@ -1086,12 +1102,13 @@ public final class ToolWindowsPane extends JBLayeredPane implements UISettingsLi
|
||||
private final WindowInfoImpl myInfo;
|
||||
private final boolean myDirtyMode;
|
||||
|
||||
public RemoveSlidingComponentCmd(Component component, WindowInfoImpl info, boolean dirtyMode, Runnable finishCallBack) {
|
||||
public RemoveSlidingComponentCmd(Component component, @NotNull WindowInfoImpl info, boolean dirtyMode, @NotNull Runnable finishCallBack) {
|
||||
super(finishCallBack);
|
||||
myComponent = component;
|
||||
myInfo = info;
|
||||
myDirtyMode = dirtyMode;
|
||||
}
|
||||
@Override
|
||||
public final void run() {
|
||||
try {
|
||||
final UISettings uiSettings = UISettings.getInstance();
|
||||
@@ -1147,11 +1164,12 @@ public final class ToolWindowsPane extends JBLayeredPane implements UISettingsLi
|
||||
private final class SetEditorComponentCmd extends FinalizableCommand {
|
||||
private final JComponent myComponent;
|
||||
|
||||
public SetEditorComponentCmd(final JComponent component, final Runnable finishCallBack) {
|
||||
public SetEditorComponentCmd(final JComponent component, @NotNull Runnable finishCallBack) {
|
||||
super(finishCallBack);
|
||||
myComponent = component;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
setDocumentComponent(myComponent);
|
||||
@@ -1167,11 +1185,12 @@ public final class ToolWindowsPane extends JBLayeredPane implements UISettingsLi
|
||||
private final class UpdateButtonPositionCmd extends FinalizableCommand {
|
||||
private final String myId;
|
||||
|
||||
private UpdateButtonPositionCmd(String id, final Runnable finishCallBack) {
|
||||
private UpdateButtonPositionCmd(@NotNull String id, @NotNull Runnable finishCallBack) {
|
||||
super(finishCallBack);
|
||||
myId = id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
StripeButton stripeButton = getButtonById(myId);
|
||||
@@ -1209,35 +1228,31 @@ public final class ToolWindowsPane extends JBLayeredPane implements UISettingsLi
|
||||
* These images are used to perform animated showing and hiding of components.
|
||||
* They are the member for performance reason.
|
||||
*/
|
||||
private SoftReference<BufferedImage> myBottomImageRef;
|
||||
private SoftReference<BufferedImage> myTopImageRef;
|
||||
private Reference<BufferedImage> myBottomImageRef;
|
||||
private Reference<BufferedImage> myTopImageRef;
|
||||
|
||||
public MyLayeredPane(final JComponent splitter) {
|
||||
myBottomImageRef = new SoftReference<BufferedImage>(null);
|
||||
myTopImageRef = new SoftReference<BufferedImage>(null);
|
||||
public MyLayeredPane(@NotNull JComponent splitter) {
|
||||
setOpaque(false);
|
||||
add(splitter, JLayeredPane.DEFAULT_LAYER);
|
||||
}
|
||||
|
||||
public final Image getBottomImage() {
|
||||
Pair<BufferedImage, SoftReference<BufferedImage>> result = getImage(myBottomImageRef);
|
||||
final Image getBottomImage() {
|
||||
Pair<BufferedImage, Reference<BufferedImage>> result = getImage(myBottomImageRef);
|
||||
myBottomImageRef = result.second;
|
||||
return result.first;
|
||||
}
|
||||
|
||||
public final Image getTopImage() {
|
||||
Pair<BufferedImage, SoftReference<BufferedImage>> result = getImage(myTopImageRef);
|
||||
final Image getTopImage() {
|
||||
Pair<BufferedImage, Reference<BufferedImage>> result = getImage(myTopImageRef);
|
||||
myTopImageRef = result.second;
|
||||
return result.first;
|
||||
}
|
||||
|
||||
private Pair<BufferedImage, SoftReference<BufferedImage>> getImage(SoftReference<BufferedImage> imageRef) {
|
||||
@NotNull
|
||||
private Pair<BufferedImage, Reference<BufferedImage>> getImage(@Nullable Reference<BufferedImage> imageRef) {
|
||||
LOG.assertTrue(UISettings.getInstance().ANIMATE_WINDOWS);
|
||||
BufferedImage image = imageRef.get();
|
||||
if (
|
||||
image == null ||
|
||||
image.getWidth(null) < getWidth() || image.getHeight(null) < getHeight()
|
||||
) {
|
||||
BufferedImage image = SoftReference.dereference(imageRef);
|
||||
if (image == null || image.getWidth(null) < getWidth() || image.getHeight(null) < getHeight()) {
|
||||
final int width = Math.max(Math.max(1, getWidth()), myFrame.getWidth());
|
||||
final int height = Math.max(Math.max(1, getHeight()), myFrame.getHeight());
|
||||
if (SystemInfo.isWindows) {
|
||||
@@ -1251,7 +1266,7 @@ public final class ToolWindowsPane extends JBLayeredPane implements UISettingsLi
|
||||
|
||||
image = UIUtil.createImage(width, height, BufferedImage.TYPE_INT_RGB);
|
||||
}
|
||||
imageRef = new SoftReference<BufferedImage>(image);
|
||||
imageRef = new SoftReference<>(image);
|
||||
}
|
||||
return Pair.create(image, imageRef);
|
||||
}
|
||||
@@ -1259,6 +1274,7 @@ public final class ToolWindowsPane extends JBLayeredPane implements UISettingsLi
|
||||
/**
|
||||
* When component size becomes larger then bottom and top images should be enlarged.
|
||||
*/
|
||||
@Override
|
||||
public void doLayout() {
|
||||
final int width = getWidth();
|
||||
final int height = getHeight();
|
||||
@@ -1295,7 +1311,7 @@ public final class ToolWindowsPane extends JBLayeredPane implements UISettingsLi
|
||||
}
|
||||
}
|
||||
|
||||
public final void setBoundsInPaletteLayer(final Component component, final ToolWindowAnchor anchor, float weight) {
|
||||
final void setBoundsInPaletteLayer(@NotNull Component component, @NotNull ToolWindowAnchor anchor, float weight) {
|
||||
if (weight < .0f) {
|
||||
weight = WindowInfoImpl.DEFAULT_WEIGHT;
|
||||
}
|
||||
@@ -1322,7 +1338,7 @@ public final class ToolWindowsPane extends JBLayeredPane implements UISettingsLi
|
||||
}
|
||||
}
|
||||
|
||||
public void setStripesOverlayed(boolean stripesOverlayed) {
|
||||
void setStripesOverlayed(boolean stripesOverlayed) {
|
||||
myStripesOverlayed = stripesOverlayed;
|
||||
updateToolStripesVisibility();
|
||||
}
|
||||
|
||||
@@ -32,16 +32,16 @@ public final class WindowInfoImpl implements Cloneable,JDOMExternalizable, Windo
|
||||
/**
|
||||
* XML tag.
|
||||
*/
|
||||
@NonNls static final String TAG="window_info";
|
||||
@NonNls static final String TAG = "window_info";
|
||||
/**
|
||||
* Default window weight.
|
||||
*/
|
||||
static final float DEFAULT_WEIGHT= 0.33f;
|
||||
static final float DEFAULT_SIDE_WEIGHT = 0.5f;
|
||||
static final float DEFAULT_WEIGHT = 0.33f;
|
||||
private static final float DEFAULT_SIDE_WEIGHT = 0.5f;
|
||||
|
||||
private boolean myActive;
|
||||
@NotNull
|
||||
private ToolWindowAnchor myAnchor;
|
||||
private ToolWindowAnchor myAnchor = ToolWindowAnchor.LEFT;
|
||||
private boolean myAutoHide;
|
||||
/**
|
||||
* Bounds of window in "floating" mode. It equals to <code>null</code> if
|
||||
@@ -52,9 +52,9 @@ public final class WindowInfoImpl implements Cloneable,JDOMExternalizable, Windo
|
||||
private ToolWindowType myInternalType;
|
||||
private ToolWindowType myType;
|
||||
private boolean myVisible;
|
||||
private boolean myShowStripeButton;
|
||||
private float myWeight;
|
||||
private float mySideWeight;
|
||||
private boolean myShowStripeButton = true;
|
||||
private float myWeight = DEFAULT_WEIGHT;
|
||||
private float mySideWeight = DEFAULT_SIDE_WEIGHT;
|
||||
private boolean mySplitMode;
|
||||
|
||||
@NotNull private ToolWindowContentUiType myContentUiType = ToolWindowContentUiType.TABBED;
|
||||
@@ -62,24 +62,24 @@ public final class WindowInfoImpl implements Cloneable,JDOMExternalizable, Windo
|
||||
* Defines order of tool window button inside the stripe.
|
||||
* The default value is <code>-1</code>.
|
||||
*/
|
||||
private int myOrder;
|
||||
@NonNls static final String ID_ATTR = "id";
|
||||
@NonNls static final String ACTIVE_ATTR = "active";
|
||||
@NonNls static final String ANCHOR_ATTR = "anchor";
|
||||
@NonNls static final String AUTOHIDE_ATTR = "auto_hide";
|
||||
@NonNls static final String INTERNAL_TYPE_ATTR = "internal_type";
|
||||
@NonNls static final String TYPE_ATTR = "type";
|
||||
@NonNls static final String VISIBLE_ATTR = "visible";
|
||||
@NonNls static final String WEIGHT_ATTR = "weight";
|
||||
@NonNls static final String SIDE_WEIGHT_ATTR = "sideWeight";
|
||||
@NonNls static final String ORDER_ATTR = "order";
|
||||
@NonNls static final String X_ATTR = "x";
|
||||
@NonNls static final String Y_ATTR = "y";
|
||||
@NonNls static final String WIDTH_ATTR = "width";
|
||||
@NonNls static final String HEIGHT_ATTR = "height";
|
||||
@NonNls static final String SIDE_TOOL_ATTR = "side_tool";
|
||||
@NonNls static final String CONTENT_UI_ATTR = "content_ui";
|
||||
@NonNls static final String SHOW_STRIPE_BUTTON = "show_stripe_button";
|
||||
private int myOrder = -1;
|
||||
@NonNls private static final String ID_ATTR = "id";
|
||||
@NonNls private static final String ACTIVE_ATTR = "active";
|
||||
@NonNls private static final String ANCHOR_ATTR = "anchor";
|
||||
@NonNls private static final String AUTOHIDE_ATTR = "auto_hide";
|
||||
@NonNls private static final String INTERNAL_TYPE_ATTR = "internal_type";
|
||||
@NonNls private static final String TYPE_ATTR = "type";
|
||||
@NonNls private static final String VISIBLE_ATTR = "visible";
|
||||
@NonNls private static final String WEIGHT_ATTR = "weight";
|
||||
@NonNls private static final String SIDE_WEIGHT_ATTR = "sideWeight";
|
||||
@NonNls private static final String ORDER_ATTR = "order";
|
||||
@NonNls private static final String X_ATTR = "x";
|
||||
@NonNls private static final String Y_ATTR = "y";
|
||||
@NonNls private static final String WIDTH_ATTR = "width";
|
||||
@NonNls private static final String HEIGHT_ATTR = "height";
|
||||
@NonNls private static final String SIDE_TOOL_ATTR = "side_tool";
|
||||
@NonNls private static final String CONTENT_UI_ATTR = "content_ui";
|
||||
@NonNls private static final String SHOW_STRIPE_BUTTON = "show_stripe_button";
|
||||
|
||||
|
||||
private boolean myWasRead;
|
||||
@@ -88,18 +88,8 @@ public final class WindowInfoImpl implements Cloneable,JDOMExternalizable, Windo
|
||||
* Creates <code>WindowInfo</code> for tool window with specified <code>ID</code>.
|
||||
*/
|
||||
WindowInfoImpl(@NotNull String id) {
|
||||
myActive = false;
|
||||
myAnchor = ToolWindowAnchor.LEFT;
|
||||
myAutoHide = false;
|
||||
myFloatingBounds = null;
|
||||
myId = id;
|
||||
setType(ToolWindowType.DOCKED);
|
||||
myVisible = false;
|
||||
myShowStripeButton = true;
|
||||
myWeight = DEFAULT_WEIGHT;
|
||||
mySideWeight = DEFAULT_SIDE_WEIGHT;
|
||||
myOrder = -1;
|
||||
mySplitMode = false;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -122,7 +112,7 @@ public final class WindowInfoImpl implements Cloneable,JDOMExternalizable, Windo
|
||||
/**
|
||||
* Copies all data from the passed <code>WindowInfo</code> into itself.
|
||||
*/
|
||||
void copyFrom(final WindowInfoImpl info){
|
||||
void copyFrom(@NotNull WindowInfoImpl info){
|
||||
myActive = info.myActive;
|
||||
myAnchor = info.myAnchor;
|
||||
myAutoHide = info.myAutoHide;
|
||||
@@ -178,15 +168,16 @@ public final class WindowInfoImpl implements Cloneable,JDOMExternalizable, Windo
|
||||
* window can be in floating mode, but this method has sense if you want to know what type
|
||||
* tool window had when it was internal one. The method never returns <code>null</code>.
|
||||
*/
|
||||
@NotNull
|
||||
ToolWindowType getInternalType(){
|
||||
return myInternalType;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return current type of tool window.
|
||||
* @see com.intellij.openapi.wm.ToolWindowType#DOCKED
|
||||
* @see com.intellij.openapi.wm.ToolWindowType#FLOATING
|
||||
* @see com.intellij.openapi.wm.ToolWindowType#SLIDING
|
||||
* @see ToolWindowType#DOCKED
|
||||
* @see ToolWindowType#FLOATING
|
||||
* @see ToolWindowType#SLIDING
|
||||
*/
|
||||
@Override
|
||||
public ToolWindowType getType(){
|
||||
@@ -248,11 +239,12 @@ public final class WindowInfoImpl implements Cloneable,JDOMExternalizable, Windo
|
||||
return myVisible;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isShowStripeButton() {
|
||||
return myShowStripeButton;
|
||||
}
|
||||
|
||||
public void setShowStripeButton(boolean showStripeButton) {
|
||||
void setShowStripeButton(boolean showStripeButton) {
|
||||
myShowStripeButton = showStripeButton;
|
||||
}
|
||||
|
||||
@@ -266,7 +258,7 @@ public final class WindowInfoImpl implements Cloneable,JDOMExternalizable, Windo
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings({"EmptyCatchBlock"})
|
||||
@SuppressWarnings("EmptyCatchBlock")
|
||||
public void readExternal(final Element element) {
|
||||
myId = element.getAttributeValue(ID_ATTR);
|
||||
myWasRead = true;
|
||||
@@ -353,7 +345,7 @@ public final class WindowInfoImpl implements Cloneable,JDOMExternalizable, Windo
|
||||
setTypeAndCheck(type);
|
||||
}
|
||||
//Hardcoded to avoid single-usage-API
|
||||
private void setTypeAndCheck(ToolWindowType type) {
|
||||
private void setTypeAndCheck(@NotNull ToolWindowType type) {
|
||||
myType = ToolWindowId.PREVIEW == myId && type == ToolWindowType.DOCKED ? ToolWindowType.SLIDING : type;
|
||||
}
|
||||
|
||||
@@ -420,7 +412,7 @@ public final class WindowInfoImpl implements Cloneable,JDOMExternalizable, Windo
|
||||
return myAnchor.hashCode()+myId.hashCode()+myType.hashCode()+myOrder;
|
||||
}
|
||||
|
||||
@SuppressWarnings({"HardCodedStringLiteral"})
|
||||
@SuppressWarnings("HardCodedStringLiteral")
|
||||
public String toString(){
|
||||
return getClass().getName() + "[myId=" + myId
|
||||
+ "; myVisible=" + myVisible
|
||||
@@ -439,7 +431,7 @@ public final class WindowInfoImpl implements Cloneable,JDOMExternalizable, Windo
|
||||
']';
|
||||
}
|
||||
|
||||
public boolean wasRead() {
|
||||
boolean wasRead() {
|
||||
return myWasRead;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,14 +15,11 @@
|
||||
*/
|
||||
package com.intellij.openapi.wm.impl;
|
||||
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.ui.FrameWrapper;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public final class WindowedDecorator extends FrameWrapper {
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.wm.impl.WindowedDecorator");
|
||||
|
||||
final class WindowedDecorator extends FrameWrapper {
|
||||
private final Project myProject;
|
||||
|
||||
WindowedDecorator(@NotNull Project project, @NotNull WindowInfoImpl info, @NotNull InternalDecorator internalDecorator) {
|
||||
|
||||
+4
-3
@@ -17,6 +17,7 @@ package com.intellij.openapi.wm.impl.commands;
|
||||
|
||||
import com.intellij.openapi.util.Condition;
|
||||
import com.intellij.openapi.wm.ToolWindowManager;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
@@ -27,15 +28,15 @@ public abstract class FinalizableCommand implements Runnable{
|
||||
|
||||
protected ToolWindowManager myManager;
|
||||
|
||||
public FinalizableCommand(final Runnable finishCallBack){
|
||||
myFinishCallBack=finishCallBack;
|
||||
public FinalizableCommand(Runnable finishCallBack){
|
||||
myFinishCallBack = finishCallBack;
|
||||
}
|
||||
|
||||
public final void finish(){
|
||||
myFinishCallBack.run();
|
||||
}
|
||||
|
||||
public void beforeExecute(final ToolWindowManager toolWindowManager) {
|
||||
public void beforeExecute(@NotNull ToolWindowManager toolWindowManager) {
|
||||
myManager = toolWindowManager;
|
||||
}
|
||||
|
||||
|
||||
@@ -562,7 +562,7 @@ public class Mock {
|
||||
public ToolWindow registerToolWindow(@NotNull String id,
|
||||
@NotNull JComponent component,
|
||||
@NotNull ToolWindowAnchor anchor,
|
||||
Disposable parentDisposable,
|
||||
@NotNull Disposable parentDisposable,
|
||||
boolean canWorkInDumbMode, boolean canCloseContents) {
|
||||
throw new RuntimeException();
|
||||
}
|
||||
@@ -572,7 +572,7 @@ public class Mock {
|
||||
public ToolWindow registerToolWindow(@NotNull String id,
|
||||
@NotNull JComponent component,
|
||||
@NotNull ToolWindowAnchor anchor,
|
||||
Disposable parentDisposable,
|
||||
@NotNull Disposable parentDisposable,
|
||||
boolean canWorkInDumbMode) {
|
||||
throw new RuntimeException();
|
||||
}
|
||||
@@ -592,7 +592,7 @@ public class Mock {
|
||||
@NotNull
|
||||
@Override
|
||||
public ToolWindow registerToolWindow(@NotNull final String id, final boolean canCloseContent, @NotNull final ToolWindowAnchor anchor,
|
||||
final Disposable parentDisposable, final boolean dumbAware) {
|
||||
@NotNull final Disposable parentDisposable, final boolean dumbAware) {
|
||||
throw new RuntimeException();
|
||||
}
|
||||
|
||||
@@ -601,7 +601,7 @@ public class Mock {
|
||||
public ToolWindow registerToolWindow(@NotNull String id,
|
||||
boolean canCloseContent,
|
||||
@NotNull ToolWindowAnchor anchor,
|
||||
Disposable parentDisposable,
|
||||
@NotNull Disposable parentDisposable,
|
||||
boolean canWorkInDumbMode,
|
||||
boolean secondary) {
|
||||
throw new RuntimeException();
|
||||
|
||||
@@ -17,6 +17,7 @@ package com.intellij.util;
|
||||
|
||||
import com.intellij.openapi.util.SystemInfo;
|
||||
import com.intellij.util.ui.UIUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.image.BufferedImage;
|
||||
@@ -50,6 +51,7 @@ public class RetinaImage {
|
||||
* @param observer the raw image observer
|
||||
* @return the Retina-aware wrapper
|
||||
*/
|
||||
@NotNull
|
||||
public static Image createFrom(Image image, final int scale, ImageObserver observer) {
|
||||
int w = image.getWidth(observer);
|
||||
int h = image.getHeight(observer);
|
||||
@@ -65,11 +67,13 @@ public class RetinaImage {
|
||||
return hidpi;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static BufferedImage create(final int width, int height, int type) {
|
||||
return create(null, width, height, type);
|
||||
}
|
||||
|
||||
|
||||
@NotNull
|
||||
private static BufferedImage create(Image image, final int width, int height, int type) {
|
||||
if (SystemInfo.isAppleJvm) {
|
||||
return AppleHiDPIScaledImage.create(width, height, type);
|
||||
|
||||
@@ -183,8 +183,7 @@ class SchedulingWrapper implements ScheduledExecutorService {
|
||||
|
||||
@Override
|
||||
public int compareTo(@NotNull Delayed other) {
|
||||
if (other == this) // compare zero if same object
|
||||
{
|
||||
if (other == this) {
|
||||
return 0;
|
||||
}
|
||||
if (other instanceof MyScheduledFutureTask) {
|
||||
|
||||
@@ -1779,6 +1779,7 @@ public class UIUtil {
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static BufferedImage createImage(int width, int height, int type) {
|
||||
if (isRetina()) {
|
||||
return RetinaImage.create(width, height, type);
|
||||
@@ -1787,6 +1788,7 @@ public class UIUtil {
|
||||
return new BufferedImage(width, height, type);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static BufferedImage createImageForGraphics(Graphics2D g, int width, int height, int type) {
|
||||
if (isRetina(g)) {
|
||||
return RetinaImage.create(width, height, type);
|
||||
|
||||
+12
-5
@@ -60,7 +60,6 @@ import com.intellij.ui.*;
|
||||
import com.intellij.util.Alarm;
|
||||
import com.intellij.util.Consumer;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.containers.Convertor;
|
||||
import com.intellij.util.containers.MultiMap;
|
||||
import com.intellij.util.ui.JBUI;
|
||||
import com.intellij.util.ui.UIUtil;
|
||||
@@ -196,7 +195,7 @@ public class ApplyPatchDifferentiatedDialog extends DialogWrapper {
|
||||
myReset = myCanChangePatchFile ? this::reset : EmptyRunnable.getInstance();
|
||||
|
||||
myChangeListChooser = new ChangeListChooserPanel(project, errorMessage -> {
|
||||
setOKActionEnabled(errorMessage == null);
|
||||
setOKActionEnabled(errorMessage == null && isChangeTreeEnabled());
|
||||
setErrorText(errorMessage);
|
||||
});
|
||||
ChangeListManager changeListManager = ChangeListManager.getInstance(project);
|
||||
@@ -244,7 +243,15 @@ public class ApplyPatchDifferentiatedDialog extends DialogWrapper {
|
||||
}
|
||||
|
||||
private void updateOkActions() {
|
||||
setOKActionEnabled(!myChangesTreeList.getIncludedChanges().isEmpty());
|
||||
boolean changeTreeEnabled = isChangeTreeEnabled();
|
||||
setOKActionEnabled(changeTreeEnabled);
|
||||
if (changeTreeEnabled) {
|
||||
myChangeListChooser.updateEnabled();
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isChangeTreeEnabled() {
|
||||
return !myChangesTreeList.getIncludedChanges().isEmpty();
|
||||
}
|
||||
|
||||
private void queueRequest() {
|
||||
@@ -371,6 +378,7 @@ public class ApplyPatchDifferentiatedDialog extends DialogWrapper {
|
||||
myReader = patchReader;
|
||||
updateTree(true);
|
||||
paintBusy(false);
|
||||
updateOkActions();
|
||||
}, ModalityState.stateForComponent(myCenterPanel));
|
||||
}
|
||||
}
|
||||
@@ -519,8 +527,7 @@ public class ApplyPatchDifferentiatedDialog extends DialogWrapper {
|
||||
protected DefaultTreeModel buildTreeModel(List<AbstractFilePatchInProgress.PatchChange> changes,
|
||||
ChangeNodeDecorator changeNodeDecorator) {
|
||||
TreeModelBuilder builder = new TreeModelBuilder(myProject, isShowFlatten());
|
||||
return builder.buildModel(ObjectsConvertor.convert(changes,
|
||||
(Convertor<AbstractFilePatchInProgress.PatchChange, Change>)o -> o), changeNodeDecorator);
|
||||
return builder.buildModel(ObjectsConvertor.convert(changes, o -> o), changeNodeDecorator);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1,50 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="com.intellij.openapi.vcs.changes.ui.ChangeListChooserPanel">
|
||||
<grid id="84622" binding="myPanel" layout-manager="GridLayoutManager" row-count="4" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
||||
<margin top="0" left="0" bottom="0" right="0"/>
|
||||
<constraints>
|
||||
<xy x="214" y="106" width="285" height="171"/>
|
||||
</constraints>
|
||||
<properties/>
|
||||
<border type="none"/>
|
||||
<children>
|
||||
<component id="cde9d" class="javax.swing.JRadioButton" binding="myRbExisting">
|
||||
<constraints>
|
||||
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<text resource-bundle="messages/VcsBundle" key="changes.changelist.chooser.existing.changelist"/>
|
||||
</properties>
|
||||
</component>
|
||||
<component id="e9094" class="javax.swing.JRadioButton" binding="myRbNew">
|
||||
<constraints>
|
||||
<grid row="2" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<text resource-bundle="messages/VcsBundle" key="changes.changelist.chooser.new.changelist"/>
|
||||
</properties>
|
||||
</component>
|
||||
<component id="6e64e" class="javax.swing.JComboBox" binding="myExistingListsCombo">
|
||||
<constraints>
|
||||
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="2" anchor="8" fill="1" indent="3" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties/>
|
||||
</component>
|
||||
<component id="54fed" class="com.intellij.openapi.vcs.changes.ui.NewEditChangelistPanel" binding="myNewListPanel" custom-create="true">
|
||||
<constraints>
|
||||
<grid row="3" column="0" row-span="1" col-span="1" vsize-policy="7" hsize-policy="7" anchor="0" fill="3" indent="3" use-parent-layout="false">
|
||||
<minimum-size width="300" height="150"/>
|
||||
<preferred-size width="300" height="150"/>
|
||||
</grid>
|
||||
</constraints>
|
||||
<properties/>
|
||||
</component>
|
||||
</children>
|
||||
</grid>
|
||||
<buttonGroups>
|
||||
<group name="buttonGroup1">
|
||||
<member id="cde9d"/>
|
||||
<member id="e9094"/>
|
||||
</group>
|
||||
</buttonGroups>
|
||||
</form>
|
||||
+134
-115
@@ -15,20 +15,23 @@
|
||||
*/
|
||||
package com.intellij.openapi.vcs.changes.ui;
|
||||
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.application.ModalityState;
|
||||
import com.intellij.openapi.editor.ex.EditorEx;
|
||||
import com.intellij.openapi.fileTypes.FileTypes;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.ui.Messages;
|
||||
import com.intellij.openapi.ui.ComboBox;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.vcs.VcsBundle;
|
||||
import com.intellij.openapi.vcs.VcsConfiguration;
|
||||
import com.intellij.openapi.vcs.changes.ChangeList;
|
||||
import com.intellij.openapi.vcs.changes.ChangeListManager;
|
||||
import com.intellij.openapi.vcs.changes.LocalChangeList;
|
||||
import com.intellij.openapi.vcs.changes.committed.CommittedChangeListRenderer;
|
||||
import com.intellij.openapi.vcs.changes.issueLinks.IssueLinkRenderer;
|
||||
import com.intellij.openapi.wm.IdeFocusManager;
|
||||
import com.intellij.ui.*;
|
||||
import com.intellij.util.NullableConsumer;
|
||||
import com.intellij.util.ui.UIUtil;
|
||||
import com.intellij.util.ObjectUtils;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import org.jetbrains.annotations.CalledInAwt;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -36,140 +39,144 @@ import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.awt.event.FocusAdapter;
|
||||
import java.awt.event.FocusEvent;
|
||||
import java.awt.event.ItemEvent;
|
||||
import java.awt.event.ItemListener;
|
||||
import java.util.*;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author yole
|
||||
*/
|
||||
public class ChangeListChooserPanel extends JPanel {
|
||||
private static final Comparator<ChangeList> CHANGE_LIST_COMPARATOR = new Comparator<ChangeList>() {
|
||||
@Override
|
||||
public int compare(ChangeList o1, ChangeList o2) {
|
||||
return o1.getName().compareToIgnoreCase(o2.getName());
|
||||
}
|
||||
};
|
||||
import static com.intellij.codeInsight.completion.ComboEditorCompletionContributor.CONTINUE_RUN_COMPLETION;
|
||||
|
||||
private JPanel myPanel;
|
||||
private JRadioButton myRbExisting;
|
||||
private JRadioButton myRbNew;
|
||||
private JComboBox myExistingListsCombo;
|
||||
private NewEditChangelistPanel myNewListPanel;
|
||||
public class ChangeListChooserPanel extends JPanel {
|
||||
|
||||
private final MyEditorComboBox myExistingListsCombo;
|
||||
private final NewEditChangelistPanel myListPanel;
|
||||
private final NullableConsumer<String> myOkEnabledListener;
|
||||
private Project myProject;
|
||||
private final Project myProject;
|
||||
private String myLastTypedDescription;
|
||||
|
||||
public ChangeListChooserPanel(final Project project, @NotNull final NullableConsumer<String> okEnabledListener) {
|
||||
super(new BorderLayout());
|
||||
myProject = project;
|
||||
myOkEnabledListener = okEnabledListener;
|
||||
add(myPanel, BorderLayout.CENTER);
|
||||
|
||||
myRbExisting.addItemListener(new ItemListener() {
|
||||
public void itemStateChanged(ItemEvent e) {
|
||||
updateEnabledItems();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void init() {
|
||||
myExistingListsCombo.setRenderer(new ColoredListCellRendererWrapper() {
|
||||
private final IssueLinkRenderer myLinkRenderer = new IssueLinkRenderer(myProject, this);
|
||||
|
||||
myExistingListsCombo = new MyEditorComboBox(project);
|
||||
myExistingListsCombo.setEditable(true);
|
||||
myExistingListsCombo.setRenderer(new ColoredListCellRenderer<String>() {
|
||||
@Override
|
||||
protected void doCustomize(JList list, Object value, int index, boolean selected, boolean hasFocus) {
|
||||
if (value instanceof LocalChangeList) {
|
||||
String name = ((LocalChangeList) value).getName();
|
||||
|
||||
if (myExistingListsCombo.getWidth() == 0) {
|
||||
protected void customizeCellRenderer(@NotNull JList<? extends String> list,
|
||||
String value,
|
||||
int index,
|
||||
boolean selected,
|
||||
boolean hasFocus) {
|
||||
if (value != null) {
|
||||
String name = value;
|
||||
LocalChangeList changeList = ChangeListManager.getInstance(myProject).findChangeList(name);
|
||||
int visibleWidth = myExistingListsCombo.getEditorTextField().getVisibleRect().width;
|
||||
if (visibleWidth == 0) {
|
||||
name = name.length() > 10 ? name.substring(0, 7) + " .." : name;
|
||||
}
|
||||
else {
|
||||
final FontMetrics fm = list.getFontMetrics(list.getFont());
|
||||
final int width = fm.stringWidth(name);
|
||||
final int listWidth = myExistingListsCombo.getWidth();
|
||||
if ((listWidth > 0) && (width > listWidth)) {
|
||||
final String truncated = CommittedChangeListRenderer.truncateDescription(name, fm, listWidth - fm.stringWidth(" ..") - 7);
|
||||
if ((visibleWidth > 0) && (width > visibleWidth)) {
|
||||
final String truncated = CommittedChangeListRenderer
|
||||
.truncateDescription(name, fm, visibleWidth - fm.stringWidth(" ..") - 7);
|
||||
if (truncated.length() > 5) {
|
||||
name = truncated + " ..";
|
||||
}
|
||||
}
|
||||
}
|
||||
myLinkRenderer.appendTextWithLinks(name, ((LocalChangeList)value).isDefault()
|
||||
? SimpleTextAttributes.REGULAR_BOLD_ATTRIBUTES : SimpleTextAttributes.REGULAR_ATTRIBUTES);
|
||||
append(name, changeList != null && changeList.isDefault()
|
||||
? SimpleTextAttributes.REGULAR_BOLD_ATTRIBUTES
|
||||
: SimpleTextAttributes.REGULAR_ATTRIBUTES);
|
||||
}
|
||||
}
|
||||
});
|
||||
myNewListPanel.init(null);
|
||||
myRbNew.addFocusListener(new FocusAdapter() {
|
||||
myListPanel = new NewEditChangelistPanel(myProject) {
|
||||
|
||||
@Override
|
||||
public void focusGained(FocusEvent e) {
|
||||
if (myRbNew.isSelected()) {
|
||||
IdeFocusManager.getInstance(myProject).requestFocus(myNewListPanel.getPreferredFocusedComponent(), true);
|
||||
}
|
||||
protected NewEditChangelistPanel.ComponentWithTextFieldWrapper createComponentWithTextField(Project project) {
|
||||
return new ComponentWithTextFieldWrapper(myExistingListsCombo) {
|
||||
@NotNull
|
||||
@Override
|
||||
public EditorTextField getEditorTextField() {
|
||||
return myExistingListsCombo.getEditorTextField();
|
||||
}
|
||||
};
|
||||
}
|
||||
});
|
||||
final ComboboxSpeedSearch search = new ComboboxSpeedSearch(myExistingListsCombo);
|
||||
search.setComparator(new SpeedSearchComparator(true, false));
|
||||
|
||||
@Override
|
||||
@CalledInAwt
|
||||
protected void nameChanged(String errorMessage) {
|
||||
//invoke later because of undo manager problem: when you try to undo changelist after description was already changed manually
|
||||
ApplicationManager.getApplication().invokeLater(() -> updateDescription(), ModalityState.current());
|
||||
myOkEnabledListener.consume(errorMessage);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(LocalChangeList initial) {
|
||||
super.init(initial);
|
||||
myDescriptionTextArea.addFocusListener(new FocusAdapter() {
|
||||
@Override
|
||||
public void focusLost(FocusEvent e) {
|
||||
super.focusLost(e);
|
||||
if (getExistingChangelist() == null) {
|
||||
myLastTypedDescription = myListPanel.getDescription();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void nameChangedImpl(Project project, LocalChangeList initial) {
|
||||
nameChanged(StringUtil.isEmptyOrSpaces(getChangeListName()) ? "Cannot create new changelist with empty name." : null);
|
||||
}
|
||||
};
|
||||
myOkEnabledListener = okEnabledListener;
|
||||
add(myListPanel, BorderLayout.CENTER);
|
||||
}
|
||||
|
||||
public void init() {
|
||||
myListPanel.init(null);
|
||||
}
|
||||
|
||||
public void setChangeLists(Collection<? extends ChangeList> changeLists) {
|
||||
List<ChangeList> list = new ArrayList<ChangeList>(changeLists);
|
||||
Collections.sort(list, CHANGE_LIST_COMPARATOR);
|
||||
myExistingListsCombo.setModel(new CollectionComboBoxModel(list, null));
|
||||
List<String> changelistNames = ContainerUtil.map(changeLists, ChangeList::getName);
|
||||
Collections.sort(changelistNames);
|
||||
myExistingListsCombo.setModel(new CollectionComboBoxModel<String>(changelistNames));
|
||||
}
|
||||
|
||||
public void setDefaultName(String name) {
|
||||
if (! StringUtil.isEmptyOrSpaces(name)) {
|
||||
myNewListPanel.setChangeListName(name);
|
||||
if (!StringUtil.isEmptyOrSpaces(name)) {
|
||||
myListPanel.setChangeListName(name);
|
||||
}
|
||||
}
|
||||
|
||||
private void updateEnabledItems() {
|
||||
if (myRbExisting.isSelected()) {
|
||||
myExistingListsCombo.setEnabled(true);
|
||||
UIUtil.setEnabled(myNewListPanel, false, true);
|
||||
myExistingListsCombo.requestFocus();
|
||||
}
|
||||
else {
|
||||
myExistingListsCombo.setEnabled(false);
|
||||
UIUtil.setEnabled(myNewListPanel, true, true);
|
||||
myNewListPanel.requestFocus();
|
||||
}
|
||||
public void updateEnabled() {
|
||||
if (myProject != null) {
|
||||
myNewListPanel.nameChangedImpl(myProject, null);
|
||||
myListPanel.nameChangedImpl(myProject, null);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Method used as getResult, usually invoked inside doOkAction
|
||||
*/
|
||||
@Nullable
|
||||
public LocalChangeList getSelectedList(Project project) {
|
||||
ChangeListManager manager = ChangeListManager.getInstance(project);
|
||||
if (myRbNew.isSelected()) {
|
||||
String newText = myNewListPanel.getChangeListName();
|
||||
if (manager.findChangeList(newText) != null) {
|
||||
Messages.showErrorDialog(project,
|
||||
VcsBundle.message("changes.newchangelist.warning.already.exists.text", newText),
|
||||
VcsBundle.message("changes.newchangelist.warning.already.exists.title"));
|
||||
return null;
|
||||
}
|
||||
}
|
||||
final boolean existingSelected = myRbExisting.isSelected();
|
||||
VcsConfiguration.getInstance(myProject).PRESELECT_EXISTING_CHANGELIST = existingSelected;
|
||||
String changeListName = myListPanel.getChangeListName();
|
||||
LocalChangeList localChangeList = manager.findChangeList(changeListName);
|
||||
|
||||
if (existingSelected) {
|
||||
return (LocalChangeList)myExistingListsCombo.getSelectedItem();
|
||||
if (localChangeList == null) {
|
||||
localChangeList = manager.addChangeList(changeListName, myListPanel.getDescription());
|
||||
myListPanel.changelistCreatedOrChanged(localChangeList);
|
||||
}
|
||||
else {
|
||||
LocalChangeList changeList = manager.addChangeList(myNewListPanel.getChangeListName(), myNewListPanel.getDescription());
|
||||
myNewListPanel.changelistCreatedOrChanged(changeList);
|
||||
if (myNewListPanel.getMakeActiveCheckBox().isSelected()) {
|
||||
manager.setDefaultChangeList(changeList);
|
||||
}
|
||||
VcsConfiguration.getInstance(project).MAKE_NEW_CHANGELIST_ACTIVE = myNewListPanel.getMakeActiveCheckBox().isSelected();
|
||||
|
||||
return changeList;
|
||||
//update description if changed
|
||||
localChangeList.setComment(myListPanel.getDescription());
|
||||
}
|
||||
if (myListPanel.getMakeActiveCheckBox().isSelected()) {
|
||||
manager.setDefaultChangeList(localChangeList);
|
||||
}
|
||||
VcsConfiguration.getInstance(project).MAKE_NEW_CHANGELIST_ACTIVE = myListPanel.getMakeActiveCheckBox().isSelected();
|
||||
return localChangeList;
|
||||
}
|
||||
|
||||
public void setDefaultSelection(final ChangeList defaultSelection) {
|
||||
@@ -177,34 +184,46 @@ public class ChangeListChooserPanel extends JPanel {
|
||||
myExistingListsCombo.setSelectedIndex(0);
|
||||
}
|
||||
else {
|
||||
myExistingListsCombo.setSelectedItem(defaultSelection);
|
||||
}
|
||||
//if defaultSelection was predefined as null then it means we could not use existing is this context
|
||||
if (defaultSelection != null && VcsConfiguration.getInstance(myProject).PRESELECT_EXISTING_CHANGELIST) {
|
||||
myRbExisting.setSelected(true);
|
||||
}
|
||||
else {
|
||||
myRbNew.setSelected(true);
|
||||
myExistingListsCombo.setSelectedItem(defaultSelection.getName());
|
||||
}
|
||||
updateDescription();
|
||||
updateEnabled();
|
||||
}
|
||||
|
||||
updateEnabledItems();
|
||||
private void updateDescription() {
|
||||
LocalChangeList list = getExistingChangelist();
|
||||
String newText = list != null ? list.getComment() : myLastTypedDescription;
|
||||
if (!StringUtil.equals(myListPanel.getDescription(), newText)) {
|
||||
myListPanel.setDescription(newText);
|
||||
}
|
||||
}
|
||||
|
||||
private LocalChangeList getExistingChangelist() {
|
||||
ChangeListManager manager = ChangeListManager.getInstance(myProject);
|
||||
String changeListName = myListPanel.getChangeListName();
|
||||
return manager.findChangeList(changeListName);
|
||||
}
|
||||
|
||||
public JComponent getPreferredFocusedComponent() {
|
||||
return myRbExisting.isSelected() ? myExistingListsCombo : myNewListPanel.getPreferredFocusedComponent();
|
||||
return myExistingListsCombo;
|
||||
}
|
||||
|
||||
private void createUIComponents() {
|
||||
myNewListPanel = new NewEditChangelistPanel(myProject) {
|
||||
private static class MyEditorComboBox extends ComboBox<String> {
|
||||
|
||||
@Override
|
||||
protected void nameChanged(String errorMessage) {
|
||||
if (myRbExisting.isSelected()) {
|
||||
myOkEnabledListener.consume(null);
|
||||
} else {
|
||||
myOkEnabledListener.consume(errorMessage);
|
||||
public MyEditorComboBox(Project project) {
|
||||
super();
|
||||
setEditor(new StringComboboxEditor(project, FileTypes.PLAIN_TEXT, this) {
|
||||
@Override
|
||||
protected void onEditorCreate(EditorEx editor) {
|
||||
super.onEditorCreate(editor);
|
||||
getDocument().putUserData(CONTINUE_RUN_COMPLETION, true);
|
||||
}
|
||||
}
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private EditorTextField getEditorTextField() {
|
||||
return ObjectUtils.assertNotNull((EditorTextField)getEditor().getEditorComponent());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+34
-14
@@ -17,8 +17,8 @@ package com.intellij.openapi.vcs.changes.ui;
|
||||
|
||||
import com.intellij.openapi.components.ServiceManager;
|
||||
import com.intellij.openapi.editor.SpellCheckingEditorCustomizationProvider;
|
||||
import com.intellij.openapi.editor.event.DocumentAdapter;
|
||||
import com.intellij.openapi.editor.event.DocumentEvent;
|
||||
import com.intellij.openapi.editor.event.DocumentListener;
|
||||
import com.intellij.openapi.extensions.Extensions;
|
||||
import com.intellij.openapi.fileTypes.FileTypes;
|
||||
import com.intellij.openapi.project.Project;
|
||||
@@ -30,19 +30,20 @@ import com.intellij.ui.*;
|
||||
import com.intellij.util.Consumer;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.ui.JBUI;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.util.Set;
|
||||
|
||||
public abstract class NewEditChangelistPanel extends JPanel {
|
||||
private EditorTextField myNameTextField;
|
||||
private EditorTextField myDescriptionTextArea;
|
||||
private JPanel myAdditionalControlsPanel;
|
||||
private JCheckBox myMakeActiveCheckBox;
|
||||
protected final EditorTextField myNameTextField;
|
||||
protected final EditorTextField myDescriptionTextArea;
|
||||
private final JPanel myAdditionalControlsPanel;
|
||||
private final JCheckBox myMakeActiveCheckBox;
|
||||
|
||||
private Consumer<LocalChangeList> myConsumer;
|
||||
private final Project myProject;
|
||||
protected final Project myProject;
|
||||
|
||||
public NewEditChangelistPanel(final Project project) {
|
||||
super(new GridBagLayout());
|
||||
@@ -52,14 +53,15 @@ public abstract class NewEditChangelistPanel extends JPanel {
|
||||
|
||||
final JLabel nameLabel = new JLabel(VcsBundle.message("edit.changelist.name"));
|
||||
add(nameLabel, gb);
|
||||
++ gb.gridx;
|
||||
++gb.gridx;
|
||||
gb.fill = GridBagConstraints.HORIZONTAL;
|
||||
gb.weightx = 1;
|
||||
myNameTextField = createEditorField(project, 1);
|
||||
ComponentWithTextFieldWrapper componentWithTextField = createComponentWithTextField(project);
|
||||
myNameTextField = componentWithTextField.getEditorTextField();
|
||||
myNameTextField.setOneLineMode(true);
|
||||
myNameTextField.setText("New changelist");
|
||||
myNameTextField.selectAll();
|
||||
add(myNameTextField, gb);
|
||||
add(componentWithTextField.myComponent, gb);
|
||||
nameLabel.setLabelFor(myNameTextField);
|
||||
|
||||
++ gb.gridy;
|
||||
@@ -100,11 +102,7 @@ public abstract class NewEditChangelistPanel extends JPanel {
|
||||
support.installSearch(myNameTextField, myDescriptionTextArea);
|
||||
myConsumer = support.addControls(myAdditionalControlsPanel, initial);
|
||||
}
|
||||
myNameTextField.getDocument().addDocumentListener(new DocumentListener() {
|
||||
@Override
|
||||
public void beforeDocumentChange(DocumentEvent event) {
|
||||
}
|
||||
|
||||
myNameTextField.getDocument().addDocumentListener(new DocumentAdapter() {
|
||||
@Override
|
||||
public void documentChanged(DocumentEvent event) {
|
||||
nameChangedImpl(myProject, initial);
|
||||
@@ -160,6 +158,17 @@ public abstract class NewEditChangelistPanel extends JPanel {
|
||||
|
||||
protected abstract void nameChanged(String errorMessage);
|
||||
|
||||
protected ComponentWithTextFieldWrapper createComponentWithTextField(Project project) {
|
||||
final EditorTextField editorTextField = createEditorField(project, 1);
|
||||
return new ComponentWithTextFieldWrapper(editorTextField) {
|
||||
@NotNull
|
||||
@Override
|
||||
public EditorTextField getEditorTextField() {
|
||||
return editorTextField;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private static EditorTextField createEditorField(final Project project, final int defaultLines) {
|
||||
final EditorTextFieldProvider service = ServiceManager.getService(project, EditorTextFieldProvider.class);
|
||||
final EditorTextField editorField;
|
||||
@@ -178,4 +187,15 @@ public abstract class NewEditChangelistPanel extends JPanel {
|
||||
editorField.getComponent().setMinimumSize(new Dimension(100, (int)(height * 1.3)));
|
||||
return editorField;
|
||||
}
|
||||
|
||||
protected abstract static class ComponentWithTextFieldWrapper {
|
||||
@NotNull private final Component myComponent;
|
||||
|
||||
public ComponentWithTextFieldWrapper(@NotNull Component component) {
|
||||
myComponent = component;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
abstract EditorTextField getEditorTextField();
|
||||
}
|
||||
}
|
||||
|
||||
+17
-4
@@ -33,6 +33,8 @@ import com.intellij.openapi.extensions.Extensions;
|
||||
import com.intellij.openapi.progress.ProcessCanceledException;
|
||||
import com.intellij.openapi.progress.ProgressManager;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.project.ProjectManager;
|
||||
import com.intellij.openapi.project.ProjectManagerAdapter;
|
||||
import com.intellij.openapi.roots.FileIndexFacade;
|
||||
import com.intellij.openapi.util.*;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
@@ -128,24 +130,35 @@ public class ProjectLevelVcsManagerImpl extends ProjectLevelVcsManagerEx impleme
|
||||
private final VcsFileListenerContextHelper myVcsFileListenerContextHelper;
|
||||
private final VcsAnnotationLocalChangesListenerImpl myAnnotationLocalChangesListener;
|
||||
|
||||
public ProjectLevelVcsManagerImpl(Project project, final FileStatusManager manager, MessageBus messageBus,
|
||||
final FileIndexFacade excludedFileIndex) {
|
||||
public ProjectLevelVcsManagerImpl(Project project,
|
||||
final FileStatusManager manager,
|
||||
MessageBus messageBus,
|
||||
final FileIndexFacade excludedFileIndex,
|
||||
ProjectManager projectManager,
|
||||
DefaultVcsRootPolicy defaultVcsRootPolicy,
|
||||
VcsFileListenerContextHelper vcsFileListenerContextHelper) {
|
||||
myProject = project;
|
||||
myMessageBus = messageBus;
|
||||
mySerialization = new ProjectLevelVcsManagerSerialization();
|
||||
myOptionsAndConfirmations = new OptionsAndConfirmations();
|
||||
|
||||
myDefaultVcsRootPolicy = DefaultVcsRootPolicy.getInstance(project);
|
||||
myDefaultVcsRootPolicy = defaultVcsRootPolicy;
|
||||
|
||||
myInitialization = new VcsInitialization(myProject);
|
||||
Disposer.register(project, myInitialization); // wait for the thread spawned in VcsInitialization to terminate
|
||||
projectManager.addProjectManagerListener(project, new ProjectManagerAdapter() {
|
||||
@Override
|
||||
public void projectClosing(Project project) {
|
||||
Disposer.dispose(myInitialization);
|
||||
}
|
||||
});
|
||||
myMappings = new NewMappings(myProject, myMessageBus, this, manager);
|
||||
myMappingsToRoots = new MappingsToRoots(myMappings, myProject);
|
||||
|
||||
myVcsHistoryCache = new VcsHistoryCache();
|
||||
myContentRevisionCache = new ContentRevisionCache();
|
||||
myConnect = myMessageBus.connect();
|
||||
myVcsFileListenerContextHelper = VcsFileListenerContextHelper.getInstance(myProject);
|
||||
myVcsFileListenerContextHelper = vcsFileListenerContextHelper;
|
||||
VcsListener vcsListener = new VcsListener() {
|
||||
@Override
|
||||
public void directoryMappingChanged() {
|
||||
|
||||
@@ -76,7 +76,7 @@ public class VcsInitialization implements Disposable {
|
||||
}
|
||||
}
|
||||
|
||||
public void execute() {
|
||||
private void execute() {
|
||||
final List<Pair<VcsInitObject, Runnable>> list;
|
||||
synchronized (myLock) {
|
||||
list = myList;
|
||||
@@ -103,6 +103,11 @@ public class VcsInitialization implements Disposable {
|
||||
@Override
|
||||
public void dispose() {
|
||||
myIndicator.cancel();
|
||||
cancelBackgroundInitialization();
|
||||
}
|
||||
|
||||
private void cancelBackgroundInitialization() {
|
||||
// do not leave VCS initialization run in background when the project is closed
|
||||
Future<?> future = myFuture;
|
||||
if (future != null) {
|
||||
future.cancel(false);
|
||||
|
||||
+7
-5
@@ -15,7 +15,6 @@
|
||||
*/
|
||||
package org.jetbrains.plugins.groovy.lang.psi.stubs.hierarchy;
|
||||
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.PsiNameHelper;
|
||||
import com.intellij.psi.impl.java.stubs.hierarchy.IndexTree;
|
||||
@@ -33,7 +32,10 @@ import org.jetbrains.plugins.groovy.GroovyFileType;
|
||||
import org.jetbrains.plugins.groovy.lang.parser.GroovyElementTypes;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.stubs.*;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
public class GrStubIndexer extends StubHierarchyIndexer {
|
||||
@Override
|
||||
@@ -48,14 +50,14 @@ public class GrStubIndexer extends StubHierarchyIndexer {
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public List<Pair<String, Unit>> indexFile(@NotNull FileContent content) {
|
||||
public Unit indexFile(@NotNull FileContent content) {
|
||||
Stub stubTree = StubTreeBuilder.buildStubTree(content);
|
||||
if (!(stubTree instanceof GrFileStub)) return null;
|
||||
|
||||
GrFileStub grFileStub = (GrFileStub)stubTree;
|
||||
new StubTree(grFileStub, false);
|
||||
|
||||
String pid = null;
|
||||
String pid = "";
|
||||
ArrayList<ClassDecl> classList = new ArrayList<ClassDecl>();
|
||||
Set<String> usedNames = new HashSet<String>();
|
||||
for (StubElement<?> el : grFileStub.getChildrenStubs()) {
|
||||
@@ -82,7 +84,7 @@ public class GrStubIndexer extends StubHierarchyIndexer {
|
||||
}
|
||||
ClassDecl[] classes = classList.isEmpty() ? ClassDecl.EMPTY_ARRAY : classList.toArray(new ClassDecl[classList.size()]);
|
||||
Import[] imports = importList.isEmpty() ? Import.EMPTY_ARRAY : importList.toArray(new Import[importList.size()]);
|
||||
return Collections.singletonList(Pair.create(pid, new Unit(IndexTree.GROOVY, imports, classes)));
|
||||
return new Unit(pid, IndexTree.GROOVY, imports, classes);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
|
||||
+5
@@ -56,6 +56,11 @@ public abstract class StudyBasePluginConfigurator implements StudyPluginConfigur
|
||||
|
||||
@Override
|
||||
public void fileClosed(@NotNull FileEditorManager source, @NotNull VirtualFile file) {
|
||||
for (VirtualFile openedFile : source.getOpenFiles()) {
|
||||
if (StudyUtils.getTaskFile(project, openedFile) != null) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
toolWindow.setEmptyText(project);
|
||||
}
|
||||
|
||||
|
||||
+4
@@ -26,6 +26,8 @@ import com.intellij.openapi.wm.ToolWindowAnchor;
|
||||
import com.intellij.openapi.wm.ToolWindowManager;
|
||||
import com.intellij.util.containers.hash.HashMap;
|
||||
import com.jetbrains.edu.learning.actions.StudyActionWithShortcut;
|
||||
import com.jetbrains.edu.learning.actions.StudyNextWindowAction;
|
||||
import com.jetbrains.edu.learning.actions.StudyPrevWindowAction;
|
||||
import com.jetbrains.edu.learning.core.EduNames;
|
||||
import com.jetbrains.edu.learning.core.EduUtils;
|
||||
import com.jetbrains.edu.learning.courseFormat.Course;
|
||||
@@ -113,6 +115,8 @@ public class StudyProjectComponent implements ProjectComponent {
|
||||
}
|
||||
}
|
||||
}
|
||||
addShortcut(StudyNextWindowAction.ACTION_ID, new String[]{StudyNextWindowAction.SHORTCUT, StudyNextWindowAction.SHORTCUT2});
|
||||
addShortcut(StudyPrevWindowAction.ACTION_ID, new String[]{StudyPrevWindowAction.SHORTCUT});
|
||||
}
|
||||
else {
|
||||
LOG.warn("Actions on toolbar are nulls");
|
||||
|
||||
+18
-9
@@ -8,7 +8,6 @@ import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.openapi.wm.ToolWindow;
|
||||
import com.intellij.openapi.wm.ToolWindowId;
|
||||
import com.intellij.openapi.wm.ToolWindowManager;
|
||||
import com.intellij.util.ui.tree.TreeUtil;
|
||||
import com.jetbrains.edu.learning.StudyState;
|
||||
import com.jetbrains.edu.learning.StudyUtils;
|
||||
import com.jetbrains.edu.learning.core.EduNames;
|
||||
@@ -44,9 +43,6 @@ abstract public class StudyTaskNavigationAction extends StudyActionWithShortcut
|
||||
int nextTaskIndex = nextTask.getIndex();
|
||||
int lessonIndex = nextTask.getLesson().getIndex();
|
||||
Map<String, TaskFile> nextTaskFiles = nextTask.getTaskFiles();
|
||||
if (nextTaskFiles.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
VirtualFile projectDir = project.getBaseDir();
|
||||
String lessonDirName = EduNames.LESSON + String.valueOf(lessonIndex);
|
||||
if (projectDir == null) {
|
||||
@@ -61,15 +57,26 @@ abstract public class StudyTaskNavigationAction extends StudyActionWithShortcut
|
||||
if (taskDir == null) {
|
||||
return;
|
||||
}
|
||||
if (nextTaskFiles.isEmpty()) {
|
||||
ProjectView.getInstance(project).select(taskDir, taskDir, false);
|
||||
return;
|
||||
}
|
||||
|
||||
VirtualFile shouldBeActive = getFileToActivate(project, nextTaskFiles, taskDir);
|
||||
JTree tree = ProjectView.getInstance(project).getCurrentProjectViewPane().getTree();
|
||||
TreePath path = TreeUtil.getFirstNodePath(tree);
|
||||
tree.collapsePath(path);
|
||||
TreePath path = tree.getSelectionPath();
|
||||
if (path != null) {
|
||||
TreePath oldSelectionPath = path.getParentPath();
|
||||
if (oldSelectionPath != null) {
|
||||
tree.collapsePath(oldSelectionPath);
|
||||
tree.fireTreeCollapsed(oldSelectionPath);
|
||||
}
|
||||
}
|
||||
if (shouldBeActive != null) {
|
||||
ProjectView.getInstance(project).select(shouldBeActive, shouldBeActive, false);
|
||||
FileEditorManager.getInstance(project).openFile(shouldBeActive, true);
|
||||
}
|
||||
|
||||
ToolWindow runToolWindow = ToolWindowManager.getInstance(project).getToolWindow(ToolWindowId.RUN);
|
||||
if (runToolWindow != null) {
|
||||
runToolWindow.hide(null);
|
||||
@@ -82,11 +89,13 @@ abstract public class StudyTaskNavigationAction extends StudyActionWithShortcut
|
||||
for (Map.Entry<String, TaskFile> entry : nextTaskFiles.entrySet()) {
|
||||
String name = entry.getKey();
|
||||
TaskFile taskFile = entry.getValue();
|
||||
VirtualFile srcDir = taskDir.findChild("src");
|
||||
VirtualFile srcDir = taskDir.findChild(EduNames.SRC);
|
||||
VirtualFile vf = srcDir == null ? taskDir.findChild(name) : srcDir.findChild(name);
|
||||
if (vf != null) {
|
||||
FileEditorManager.getInstance(project).openFile(vf, true);
|
||||
if (!taskFile.getAnswerPlaceholders().isEmpty()) {
|
||||
if (shouldBeActive != null) {
|
||||
FileEditorManager.getInstance(project).openFile(vf, true);
|
||||
}
|
||||
if (shouldBeActive == null && !taskFile.getAnswerPlaceholders().isEmpty()) {
|
||||
shouldBeActive = vf;
|
||||
}
|
||||
}
|
||||
|
||||
+2
-1
@@ -81,7 +81,8 @@ public class PyCCRunTestsConfigurationProducer extends RunConfigurationProducer<
|
||||
String testsPath = taskDir.findChild(EduNames.SRC) != null ?
|
||||
FileUtil.join(taskDirPath, EduNames.SRC, EduNames.TESTS_FILE) :
|
||||
FileUtil.join(taskDirPath, EduNames.TESTS_FILE);
|
||||
return file.getPath().equals(testsPath) ? testsPath : null;
|
||||
String filePath = FileUtil.toSystemDependentName(file.getPath());
|
||||
return filePath.equals(testsPath) ? testsPath : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+24
-1
@@ -56,10 +56,15 @@ import com.intellij.openapi.project.ProjectManagerAdapter;
|
||||
import com.intellij.openapi.project.ex.ProjectManagerEx;
|
||||
import com.intellij.openapi.startup.StartupManager;
|
||||
import com.intellij.openapi.util.Disposer;
|
||||
import com.intellij.openapi.util.Key;
|
||||
import com.intellij.openapi.vfs.VfsUtil;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.openapi.wm.*;
|
||||
import com.intellij.platform.DirectoryProjectConfigurator;
|
||||
import com.intellij.platform.PlatformProjectViewOpener;
|
||||
import com.intellij.profile.codeInspection.InspectionProjectProfileManager;
|
||||
import com.intellij.psi.PsiDirectory;
|
||||
import com.intellij.psi.PsiManager;
|
||||
import com.intellij.psi.codeStyle.CodeStyleSettings;
|
||||
import com.intellij.psi.codeStyle.CodeStyleSettingsManager;
|
||||
import com.intellij.ui.treeStructure.Tree;
|
||||
@@ -68,6 +73,7 @@ import com.intellij.util.messages.MessageBus;
|
||||
import com.intellij.util.ui.tree.TreeUtil;
|
||||
import com.jetbrains.python.PythonLanguage;
|
||||
import com.jetbrains.python.codeInsight.PyCodeInsightSettings;
|
||||
import com.jetbrains.python.inspections.PyPep8Inspection;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -77,6 +83,7 @@ import javax.swing.tree.DefaultMutableTreeNode;
|
||||
import javax.swing.tree.DefaultTreeModel;
|
||||
import javax.swing.tree.TreeNode;
|
||||
import javax.swing.tree.TreePath;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
@@ -201,7 +208,11 @@ public class PyCharmEduInitialConfigurator {
|
||||
@Override
|
||||
public void run() {
|
||||
if (project.isDisposed()) return;
|
||||
updateInspectionsProfile();
|
||||
openProjectStructure();
|
||||
}
|
||||
|
||||
private void openProjectStructure() {
|
||||
ToolWindowManager.getInstance(project).invokeLater(new Runnable() {
|
||||
int count = 0;
|
||||
|
||||
@@ -212,12 +223,24 @@ public class PyCharmEduInitialConfigurator {
|
||||
return;
|
||||
}
|
||||
ToolWindow toolWindow = ToolWindowManager.getInstance(project).getToolWindow("Project");
|
||||
if (toolWindow !=null && toolWindow.getType() != ToolWindowType.SLIDING) {
|
||||
if (toolWindow != null && toolWindow.getType() != ToolWindowType.SLIDING) {
|
||||
toolWindow.activate(null);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void updateInspectionsProfile() {
|
||||
final String[] codes = new String[]{"W29", "E501"};
|
||||
final VirtualFile baseDir = project.getBaseDir();
|
||||
final PsiDirectory directory = PsiManager.getInstance(project).findDirectory(baseDir);
|
||||
if (directory != null) {
|
||||
InspectionProjectProfileManager.getInstance(project).getInspectionProfile().modifyToolSettings(
|
||||
Key.<PyPep8Inspection>create(PyPep8Inspection.INSPECTION_SHORT_NAME), directory,
|
||||
inspection -> Collections.addAll(inspection.ignoredErrors, codes)
|
||||
);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
@@ -114,6 +114,31 @@ class StdIn(BaseStdIn):
|
||||
return '\n'
|
||||
|
||||
|
||||
#=======================================================================================================================
|
||||
# DebugConsoleStdIn
|
||||
#=======================================================================================================================
|
||||
class DebugConsoleStdIn(BaseStdIn):
|
||||
'''
|
||||
Object to be added to stdin (to emulate it as non-blocking while the next line arrives)
|
||||
'''
|
||||
|
||||
def __init__(self, dbg, original_stdin):
|
||||
BaseStdIn.__init__(self)
|
||||
self.debugger = dbg
|
||||
self.original_stdin = original_stdin
|
||||
|
||||
def readline(self, *args, **kwargs):
|
||||
# Notify Java side about input and call original function
|
||||
try:
|
||||
cmd = self.debugger.cmd_factory.make_input_requested_message()
|
||||
self.debugger.writer.add_command(cmd)
|
||||
except Exception:
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
return '\n'
|
||||
return self.original_stdin.readline(*args, **kwargs)
|
||||
|
||||
|
||||
class CodeFragment:
|
||||
def __init__(self, text, is_single_line=True):
|
||||
self.text = text
|
||||
|
||||
@@ -138,6 +138,7 @@ CMD_GET_ARRAY = 143
|
||||
CMD_STEP_INTO_MY_CODE = 144
|
||||
CMD_GET_CONCURRENCY_EVENT = 145
|
||||
CMD_SHOW_RETURN_VALUES = 146
|
||||
CMD_INPUT_REQUESTED = 147
|
||||
|
||||
CMD_VERSION = 501
|
||||
CMD_RETURN = 502
|
||||
@@ -191,6 +192,7 @@ ID_TO_MEANING = {
|
||||
'144': 'CMD_STEP_INTO_MY_CODE',
|
||||
'145': 'CMD_GET_CONCURRENCY_EVENT',
|
||||
'146': 'CMD_SHOW_RETURN_VALUES',
|
||||
'147': 'CMD_INPUT_REQUESTED',
|
||||
|
||||
'501': 'CMD_VERSION',
|
||||
'502': 'CMD_RETURN',
|
||||
@@ -779,6 +781,13 @@ class NetCommandFactory:
|
||||
except:
|
||||
return self.make_error_message(0, get_exception_traceback_str())
|
||||
|
||||
def make_input_requested_message(self):
|
||||
try:
|
||||
return NetCommand(CMD_INPUT_REQUESTED, 0, '')
|
||||
except:
|
||||
return self.make_error_message(0, get_exception_traceback_str())
|
||||
|
||||
|
||||
def make_exit_message(self):
|
||||
try:
|
||||
net = NetCommand(CMD_EXIT, 0, '')
|
||||
|
||||
@@ -1180,6 +1180,7 @@ def _locked_settrace(
|
||||
if bufferStdErrToServer:
|
||||
init_stderr_redirect()
|
||||
|
||||
patch_stdin(debugger)
|
||||
debugger.set_trace_for_frame_and_parents(get_frame(), False, overwrite_prev_trace=overwrite_prev_trace)
|
||||
|
||||
|
||||
@@ -1382,6 +1383,12 @@ def apply_debugger_options(setup_options):
|
||||
enable_qt_support()
|
||||
|
||||
|
||||
def patch_stdin(debugger):
|
||||
from _pydev_bundle.pydev_console_utils import DebugConsoleStdIn
|
||||
orig_stdin = sys.stdin
|
||||
sys.stdin = DebugConsoleStdIn(debugger, orig_stdin)
|
||||
|
||||
|
||||
#=======================================================================================================================
|
||||
# main
|
||||
#=======================================================================================================================
|
||||
@@ -1512,6 +1519,7 @@ if __name__ == '__main__':
|
||||
pass # It's ok not having stackless there...
|
||||
|
||||
is_module = setup['module']
|
||||
patch_stdin(debugger)
|
||||
|
||||
if fix_app_engine_debug:
|
||||
sys.stderr.write("pydev debugger: google app engine integration enabled\n")
|
||||
|
||||
+1
@@ -139,6 +139,7 @@ public class ProjectSpecificSettingsStep extends ProjectSettingsStepBase impleme
|
||||
super.initGeneratorListeners();
|
||||
if (myProjectGenerator instanceof PythonProjectGenerator) {
|
||||
((PythonProjectGenerator)myProjectGenerator).addSettingsStateListener(this::checkValid);
|
||||
myErrorLabel.addMouseListener(((PythonProjectGenerator)myProjectGenerator).getErrorLabelMouseListener());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -37,5 +37,7 @@ public interface IPyDebugProcess extends PyFrameAccessor {
|
||||
|
||||
boolean isSuspendedOnAllThreadsPolicy();
|
||||
|
||||
void consoleInputRequested();
|
||||
|
||||
XDebugSession getSession();
|
||||
}
|
||||
|
||||
@@ -50,6 +50,7 @@ public abstract class AbstractCommand<T> {
|
||||
public static final int STEP_INTO_MY_CODE = 144;
|
||||
public static final int LOG_CONCURRENCY_EVENT = 145;
|
||||
public static final int SHOW_RETURN_VALUES = 146;
|
||||
public static final int INPUT_REQUESTED = 147;
|
||||
|
||||
public static final int ERROR = 901;
|
||||
|
||||
@@ -197,6 +198,10 @@ public abstract class AbstractCommand<T> {
|
||||
return command == WRITE_TO_CONSOLE;
|
||||
}
|
||||
|
||||
public static boolean isInputRequested(final int command) {
|
||||
return command == INPUT_REQUESTED;
|
||||
}
|
||||
|
||||
public static boolean isExitEvent(final int command) {
|
||||
return command == EXIT;
|
||||
}
|
||||
|
||||
@@ -547,6 +547,9 @@ public class RemoteDebugger implements ProcessDebugger {
|
||||
else if (AbstractCommand.isConcurrencyEvent(frame.getCommand())) {
|
||||
recordConcurrencyEvent(ProtocolParser.parseConcurrencyEvent(frame.getPayload(), myDebugProcess.getPositionConverter()));
|
||||
}
|
||||
else if (AbstractCommand.isInputRequested(frame.getCommand())) {
|
||||
myDebugProcess.consoleInputRequested();
|
||||
}
|
||||
else {
|
||||
placeResponse(frame.getSequence(), frame);
|
||||
}
|
||||
|
||||
@@ -100,6 +100,10 @@ public class PydevConsoleExecuteActionHandler extends ProcessBackedConsoleExecut
|
||||
sendLineToConsole(new ConsoleCommunication.ConsoleCodeFragment(myInputBuffer.toString(), false));
|
||||
}
|
||||
|
||||
public void clearInputBuffer() {
|
||||
myInputBuffer = null;
|
||||
}
|
||||
|
||||
private void processOneLine(String line) {
|
||||
int indentSize = IndentHelperImpl.getIndent(getProject(), PythonFileType.INSTANCE, line, false);
|
||||
line = StringUtil.trimTrailing(line);
|
||||
|
||||
@@ -95,6 +95,18 @@ public class PythonConsoleView extends LanguageConsoleImpl implements Observable
|
||||
myExecuteActionHandler = consoleExecuteActionHandler;
|
||||
}
|
||||
|
||||
public void inputRequested() {
|
||||
if (myExecuteActionHandler != null) {
|
||||
final ConsoleCommunication consoleCommunication = myExecuteActionHandler.getConsoleCommunication();
|
||||
if (consoleCommunication instanceof PythonDebugConsoleCommunication) {
|
||||
((PythonDebugConsoleCommunication)consoleCommunication).waitingForInput = true;
|
||||
myExecuteActionHandler.inputRequested();
|
||||
myExecuteActionHandler.setEnabled(true);
|
||||
myExecuteActionHandler.clearInputBuffer();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void requestFocus() {
|
||||
IdeFocusManager.findInstance().requestFocus(getConsoleEditor().getContentComponent(), true);
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user