mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Merge branch 'master' of git@git.labs.intellij.net:idea/community
This commit is contained in:
@@ -234,6 +234,7 @@ public class JavaMethodCallElement extends LookupItem<PsiMethod> implements Type
|
||||
presentation.setItemTextBold(getAttribute(HIGHLIGHTED_ATTR) != null);
|
||||
|
||||
MemberLookupHelper helper = myHelper != null ? myHelper : new MemberLookupHelper(myMethod, myContainingClass, false, false);
|
||||
helper.renderElement(presentation, getAttribute(FORCE_QUALIFY) != null, getSubstitutor());
|
||||
final Boolean qualify = getAttribute(FORCE_QUALIFY) != null ? Boolean.TRUE : myHelper == null ? Boolean.FALSE : null;
|
||||
helper.renderElement(presentation, qualify, getSubstitutor());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,18 +45,18 @@ public class MemberLookupHelper {
|
||||
return myShouldImport;
|
||||
}
|
||||
|
||||
public void renderElement(LookupElementPresentation presentation, boolean forceQualify, PsiSubstitutor substitutor) {
|
||||
public void renderElement(LookupElementPresentation presentation, @Nullable Boolean qualify, PsiSubstitutor substitutor) {
|
||||
final String className = myContainingClass == null ? "???" : myContainingClass.getName();
|
||||
|
||||
final String memberName = myMember.getName();
|
||||
if (!myShouldImport && StringUtil.isNotEmpty(className) || forceQualify) {
|
||||
if (!Boolean.FALSE.equals(qualify) && (!myShouldImport && StringUtil.isNotEmpty(className) || Boolean.TRUE.equals(qualify))) {
|
||||
presentation.setItemText(className + "." + memberName);
|
||||
} else {
|
||||
presentation.setItemText(memberName);
|
||||
}
|
||||
|
||||
final String qname = myContainingClass == null ? "" : myContainingClass.getQualifiedName();
|
||||
String pkg = StringUtil.getPackageName(qname);
|
||||
String pkg = qname == null ? "" : StringUtil.getPackageName(qname);
|
||||
String location = StringUtil.isEmpty(pkg) ? "" : " (" + pkg + ")";
|
||||
|
||||
final String params = myMergedOverloads
|
||||
|
||||
@@ -57,7 +57,6 @@ import java.util.*;
|
||||
*/
|
||||
public class PsiClassImplUtil {
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.PsiClassImplUtil");
|
||||
private static final Key<Boolean> NAME_MAPS_BUILT_FLAG = Key.create("NAME_MAPS_BUILT_FLAG");
|
||||
|
||||
private static final Key<CachedValue<Map>> MAP_IN_CLASS_KEY = Key.create("MAP_KEY");
|
||||
|
||||
@@ -102,35 +101,6 @@ public class PsiClassImplUtil {
|
||||
final PsiMethod patternMethod,
|
||||
final boolean checkBases,
|
||||
final boolean stopOnFirst) {
|
||||
/* final MethodSignature patternSignature = MethodSignatureBackedByPsiMethod.create(patternMethod, PsiSubstitutor.EMPTY);
|
||||
if (!checkBases) {
|
||||
final PsiMethod[] methodsByName = aClass.findMethodsByName(patternMethod.getName(), false);
|
||||
if (methodsByName.length == 0) return PsiMethod.EMPTY_ARRAY;
|
||||
List<PsiMethod> result = new ArrayList<PsiMethod>();
|
||||
for (PsiMethod method : methodsByName) {
|
||||
final MethodSignature otherSignature = method.getSignature(PsiSubstitutor.EMPTY);
|
||||
if (otherSignature.equals(patternSignature)) {
|
||||
result.add(method);
|
||||
if (stopOnFirst) break;
|
||||
}
|
||||
}
|
||||
|
||||
return result.toArray(new PsiMethod[result.size()]);
|
||||
}
|
||||
else {
|
||||
final Set<HierarchicalMethodSignature> signatures = getOverrideEquivalentSignatures(aClass);
|
||||
final HierarchicalMethodSignature signatureWithSupers = signatures.get(patternSignature);
|
||||
if (signatureWithSupers == null) return PsiMethod.EMPTY_ARRAY;
|
||||
final List<PsiMethod> result = new ArrayList<PsiMethod>();
|
||||
MethodSignatureUtil.processMethodHierarchy(signatureWithSupers, new Processor<HierarchicalMethodSignature>() {
|
||||
public boolean process(final HierarchicalMethodSignature sig) {
|
||||
result.add(sig.getSignature().getMethod());
|
||||
return !stopOnFirst;
|
||||
}
|
||||
});
|
||||
return result.toArray(new PsiMethod[result.size()]);
|
||||
}*/
|
||||
|
||||
final PsiMethod[] methodsByName = aClass.findMethodsByName(patternMethod.getName(), checkBases);
|
||||
if (methodsByName.length == 0) return Collections.emptyList();
|
||||
final List<PsiMethod> methods = new SmartList<PsiMethod>();
|
||||
@@ -238,14 +208,12 @@ public class PsiClassImplUtil {
|
||||
}
|
||||
}
|
||||
};
|
||||
PsiElementFactory factory = JavaPsiFacade.getInstance(psiClass.getProject()).getElementFactory();
|
||||
processDeclarationsInClassNotCached(psiClass, processor, ResolveState.initial(), new THashSet<PsiClass>(), null, psiClass, false, factory);
|
||||
processDeclarationsInClassNotCached(psiClass, processor, ResolveState.initial(), new THashSet<PsiClass>(), null, psiClass, false);
|
||||
|
||||
Map<Class<? extends PsiMember>, Map<String, List<Pair<PsiMember, PsiSubstitutor>>>> result = new HashMap<Class<? extends PsiMember>, Map<String, List<Pair<PsiMember, PsiSubstitutor>>>>(3);
|
||||
result.put(PsiClass.class, generateMapByList(classes));
|
||||
result.put(PsiMethod.class, generateMapByList(methods));
|
||||
result.put(PsiField.class, generateMapByList(fields));
|
||||
psiClass.putUserData(NAME_MAPS_BUILT_FLAG, Boolean.TRUE);
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -275,6 +243,12 @@ public class PsiClassImplUtil {
|
||||
value = ((UserDataHolderEx)aClass).putUserDataIfAbsent(MAP_IN_CLASS_KEY, value);
|
||||
}
|
||||
}
|
||||
return getCachedMembers(value, memberClazz);
|
||||
}
|
||||
|
||||
private static <T extends PsiMember> Map<String, List<Pair<T, PsiSubstitutor>>> getCachedMembers(CachedValue<Map> value,
|
||||
Class<T> memberClazz) {
|
||||
//noinspection unchecked
|
||||
return (Map<String, List<Pair<T, PsiSubstitutor>>>)value.getValue().get(memberClazz);
|
||||
}
|
||||
|
||||
@@ -308,7 +282,7 @@ public class PsiClassImplUtil {
|
||||
}
|
||||
}
|
||||
|
||||
private static final Function<ClassIconRequest, Icon> FULL_ICON_EVALUATOR = new Function<ClassIconRequest, Icon>() {
|
||||
private static final Function<ClassIconRequest, Icon> FULL_ICON_EVALUATOR = new NullableFunction<ClassIconRequest, Icon>() {
|
||||
public Icon fun(ClassIconRequest r) {
|
||||
if (!r.psiClass.isValid() || r.psiClass.getProject().isDisposed()) return null;
|
||||
|
||||
@@ -406,112 +380,140 @@ public class PsiClassImplUtil {
|
||||
PsiElement last,
|
||||
PsiElement place,
|
||||
boolean isRaw) {
|
||||
if (last instanceof PsiTypeParameterList || last instanceof PsiModifierList) return true; //TypeParameterList and ModifierList do not see our declarations
|
||||
if (visited != null && visited.contains(aClass)) return true;
|
||||
|
||||
PsiSubstitutor substitutor = state.get(PsiSubstitutor.KEY);
|
||||
isRaw = isRaw || PsiUtil.isRawSubstitutor(aClass, substitutor);
|
||||
if (last instanceof PsiTypeParameterList || last instanceof PsiModifierList) return true; //TypeParameterList and ModifierList do not see our declarations
|
||||
final Boolean built = aClass.getUserData(NAME_MAPS_BUILT_FLAG);
|
||||
PsiElementFactory factory = JavaPsiFacade.getInstance(aClass.getProject()).getElementFactory();
|
||||
if (built == null) {
|
||||
return processDeclarationsInClassNotCached(aClass, processor, state, visited, last, place, isRaw, factory);
|
||||
}
|
||||
|
||||
final NameHint nameHint = processor.getHint(NameHint.KEY);
|
||||
CachedValue<Map> cache = aClass.getUserData(MAP_IN_CLASS_KEY);
|
||||
if (cache != null && cache.hasUpToDateValue()) {
|
||||
final NameHint nameHint = processor.getHint(NameHint.KEY);
|
||||
if (nameHint != null) {
|
||||
return processCachedMembersByName(aClass, processor, state, visited, last, place, isRaw, substitutor, cache, nameHint);
|
||||
}
|
||||
}
|
||||
return processDeclarationsInClassNotCached(aClass, processor, state, visited, last, place, isRaw);
|
||||
}
|
||||
|
||||
private static boolean processCachedMembersByName(PsiClass aClass,
|
||||
PsiScopeProcessor processor,
|
||||
ResolveState state,
|
||||
Set<PsiClass> visited,
|
||||
PsiElement last,
|
||||
PsiElement place,
|
||||
boolean isRaw,
|
||||
PsiSubstitutor substitutor,
|
||||
CachedValue<Map> cache, NameHint nameHint) {
|
||||
final ElementClassHint classHint = processor.getHint(ElementClassHint.KEY);
|
||||
|
||||
if (nameHint != null) {
|
||||
if (classHint == null || classHint.shouldProcess(ElementClassHint.DeclarationKind.FIELD)) {
|
||||
final PsiField fieldByName = aClass.findFieldByName(nameHint.getName(state), false);
|
||||
if (fieldByName != null) {
|
||||
processor.handleEvent(PsiScopeProcessor.Event.SET_DECLARATION_HOLDER, aClass);
|
||||
if (!processor.execute(fieldByName, state)) return false;
|
||||
}
|
||||
else {
|
||||
final Map<String, List<Pair<PsiField, PsiSubstitutor>>> allFieldsMap = getMap(aClass, PsiField.class);
|
||||
PsiElementFactory factory = JavaPsiFacade.getInstance(aClass.getProject()).getElementFactory();
|
||||
|
||||
final List<Pair<PsiField, PsiSubstitutor>> list = allFieldsMap.get(nameHint.getName(state));
|
||||
if (list != null) {
|
||||
for (final Pair<PsiField, PsiSubstitutor> candidate : list) {
|
||||
PsiField candidateField = candidate.getFirst();
|
||||
PsiSubstitutor finalSubstitutor = obtainFinalSubstitutor(candidateField.getContainingClass(), candidate.getSecond(), aClass,
|
||||
substitutor, place, factory);
|
||||
if (classHint == null || classHint.shouldProcess(ElementClassHint.DeclarationKind.FIELD)) {
|
||||
final PsiField fieldByName = aClass.findFieldByName(nameHint.getName(state), false);
|
||||
if (fieldByName != null) {
|
||||
processor.handleEvent(PsiScopeProcessor.Event.SET_DECLARATION_HOLDER, aClass);
|
||||
if (!processor.execute(fieldByName, state)) return false;
|
||||
}
|
||||
else {
|
||||
final Map<String, List<Pair<PsiField, PsiSubstitutor>>> allFieldsMap = getCachedMembers(cache, PsiField.class);
|
||||
|
||||
processor.handleEvent(PsiScopeProcessor.Event.SET_DECLARATION_HOLDER, candidateField.getContainingClass());
|
||||
if (!processor.execute(candidateField, state.put(PsiSubstitutor.KEY, finalSubstitutor))) return false;
|
||||
}
|
||||
final List<Pair<PsiField, PsiSubstitutor>> list = allFieldsMap.get(nameHint.getName(state));
|
||||
if (list != null) {
|
||||
for (final Pair<PsiField, PsiSubstitutor> candidate : list) {
|
||||
PsiField candidateField = candidate.getFirst();
|
||||
PsiSubstitutor finalSubstitutor = obtainFinalSubstitutor(candidateField.getContainingClass(), candidate.getSecond(), aClass,
|
||||
substitutor, place, factory);
|
||||
|
||||
processor.handleEvent(PsiScopeProcessor.Event.SET_DECLARATION_HOLDER, candidateField.getContainingClass());
|
||||
if (!processor.execute(candidateField, state.put(PsiSubstitutor.KEY, finalSubstitutor))) return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (classHint == null || classHint.shouldProcess(ElementClassHint.DeclarationKind.CLASS)) {
|
||||
if (last != null && last.getParent() == aClass) {
|
||||
if (last instanceof PsiClass) {
|
||||
if (!processor.execute(last, state)) return false;
|
||||
}
|
||||
// Parameters
|
||||
final PsiTypeParameterList list = aClass.getTypeParameterList();
|
||||
if (list != null && !list.processDeclarations(processor, state, last, place)) return false;
|
||||
}
|
||||
if (classHint == null || classHint.shouldProcess(ElementClassHint.DeclarationKind.CLASS)) {
|
||||
if (last != null && last.getParent() == aClass) {
|
||||
if (last instanceof PsiClass) {
|
||||
if (!processor.execute(last, state)) return false;
|
||||
}
|
||||
if (!(last instanceof PsiReferenceList)) {
|
||||
final PsiClass classByName = aClass.findInnerClassByName(nameHint.getName(state), false);
|
||||
if (classByName != null) {
|
||||
processor.handleEvent(PsiScopeProcessor.Event.SET_DECLARATION_HOLDER, aClass);
|
||||
if (!processor.execute(classByName, state)) return false;
|
||||
}
|
||||
else {
|
||||
final Map<String, List<Pair<PsiClass, PsiSubstitutor>>> allClassesMap = getMap(aClass, PsiClass.class);
|
||||
// Parameters
|
||||
final PsiTypeParameterList list = aClass.getTypeParameterList();
|
||||
if (list != null && !list.processDeclarations(processor, state, last, place)) return false;
|
||||
}
|
||||
if (!(last instanceof PsiReferenceList)) {
|
||||
final PsiClass classByName = aClass.findInnerClassByName(nameHint.getName(state), false);
|
||||
if (classByName != null) {
|
||||
processor.handleEvent(PsiScopeProcessor.Event.SET_DECLARATION_HOLDER, aClass);
|
||||
if (!processor.execute(classByName, state)) return false;
|
||||
}
|
||||
else {
|
||||
final Map<String, List<Pair<PsiClass, PsiSubstitutor>>> allClassesMap = getCachedMembers(cache, PsiClass.class);
|
||||
|
||||
final List<Pair<PsiClass, PsiSubstitutor>> list = allClassesMap.get(nameHint.getName(state));
|
||||
if (list != null) {
|
||||
for (final Pair<PsiClass, PsiSubstitutor> candidate : list) {
|
||||
final PsiClass inner = candidate.getFirst();
|
||||
final PsiClass containingClass = inner.getContainingClass();
|
||||
if (containingClass != null) {
|
||||
PsiSubstitutor finalSubstitutor = obtainFinalSubstitutor(containingClass, candidate.getSecond(), aClass,
|
||||
substitutor, place, factory);
|
||||
processor.handleEvent(PsiScopeProcessor.Event.SET_DECLARATION_HOLDER, containingClass);
|
||||
if (!processor.execute(inner, state.put(PsiSubstitutor.KEY, finalSubstitutor))) return false;
|
||||
}
|
||||
final List<Pair<PsiClass, PsiSubstitutor>> list = allClassesMap.get(nameHint.getName(state));
|
||||
if (list != null) {
|
||||
for (final Pair<PsiClass, PsiSubstitutor> candidate : list) {
|
||||
final PsiClass inner = candidate.getFirst();
|
||||
final PsiClass containingClass = inner.getContainingClass();
|
||||
if (containingClass != null) {
|
||||
PsiSubstitutor finalSubstitutor = obtainFinalSubstitutor(containingClass, candidate.getSecond(), aClass,
|
||||
substitutor, place, factory);
|
||||
processor.handleEvent(PsiScopeProcessor.Event.SET_DECLARATION_HOLDER, containingClass);
|
||||
if (!processor.execute(inner, state.put(PsiSubstitutor.KEY, finalSubstitutor))) return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (classHint == null || classHint.shouldProcess(ElementClassHint.DeclarationKind.METHOD)) {
|
||||
if (processor instanceof MethodResolverProcessor) {
|
||||
final MethodResolverProcessor methodResolverProcessor = (MethodResolverProcessor)processor;
|
||||
if (methodResolverProcessor.isConstructor()) {
|
||||
final PsiMethod[] constructors = aClass.getConstructors();
|
||||
methodResolverProcessor.handleEvent(PsiScopeProcessor.Event.SET_DECLARATION_HOLDER, aClass);
|
||||
for (PsiMethod constructor : constructors) {
|
||||
if (!methodResolverProcessor.execute(constructor, state)) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
final Map<String, List<Pair<PsiMethod, PsiSubstitutor>>> allMethodsMap = getMap(aClass, PsiMethod.class);
|
||||
final List<Pair<PsiMethod, PsiSubstitutor>> list = allMethodsMap.get(nameHint.getName(state));
|
||||
if (list != null) {
|
||||
for (final Pair<PsiMethod, PsiSubstitutor> candidate : list) {
|
||||
PsiMethod candidateMethod = candidate.getFirst();
|
||||
if (processor instanceof MethodResolverProcessor) {
|
||||
if (candidateMethod.isConstructor() != ((MethodResolverProcessor)processor).isConstructor()) continue;
|
||||
}
|
||||
final PsiClass containingClass = candidateMethod.getContainingClass();
|
||||
PsiSubstitutor finalSubstitutor = obtainFinalSubstitutor(containingClass, candidate.getSecond(), aClass,
|
||||
substitutor, place, factory);
|
||||
if (isRaw && !candidateMethod.hasModifierProperty(PsiModifier.STATIC)) { //static methods are not erased due to raw overriding
|
||||
PsiTypeParameter[] methodTypeParameters = candidateMethod.getTypeParameters();
|
||||
finalSubstitutor = factory.createRawSubstitutor(finalSubstitutor, methodTypeParameters);
|
||||
}
|
||||
processor.handleEvent(PsiScopeProcessor.Event.SET_DECLARATION_HOLDER, containingClass);
|
||||
if (!processor.execute(candidateMethod, state.put(PsiSubstitutor.KEY, finalSubstitutor))) return false;
|
||||
}
|
||||
if (classHint == null || classHint.shouldProcess(ElementClassHint.DeclarationKind.METHOD)) {
|
||||
if (processor instanceof MethodResolverProcessor) {
|
||||
final MethodResolverProcessor methodResolverProcessor = (MethodResolverProcessor)processor;
|
||||
if (methodResolverProcessor.isConstructor()) {
|
||||
final PsiMethod[] constructors = aClass.getConstructors();
|
||||
methodResolverProcessor.handleEvent(PsiScopeProcessor.Event.SET_DECLARATION_HOLDER, aClass);
|
||||
for (PsiMethod constructor : constructors) {
|
||||
if (!methodResolverProcessor.execute(constructor, state)) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
final Map<String, List<Pair<PsiMethod, PsiSubstitutor>>> allMethodsMap = getCachedMembers(cache, PsiMethod.class);
|
||||
final List<Pair<PsiMethod, PsiSubstitutor>> list = allMethodsMap.get(nameHint.getName(state));
|
||||
if (list != null) {
|
||||
for (final Pair<PsiMethod, PsiSubstitutor> candidate : list) {
|
||||
PsiMethod candidateMethod = candidate.getFirst();
|
||||
if (processor instanceof MethodResolverProcessor) {
|
||||
if (candidateMethod.isConstructor() != ((MethodResolverProcessor)processor).isConstructor()) continue;
|
||||
}
|
||||
final PsiClass containingClass = candidateMethod.getContainingClass();
|
||||
if (visited != null && visited.contains(candidateMethod.getContainingClass())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
PsiSubstitutor finalSubstitutor = obtainFinalSubstitutor(containingClass, candidate.getSecond(), aClass,
|
||||
substitutor, place, factory);
|
||||
finalSubstitutor = checkRaw(isRaw, factory, candidateMethod, finalSubstitutor);
|
||||
processor.handleEvent(PsiScopeProcessor.Event.SET_DECLARATION_HOLDER, containingClass);
|
||||
if (!processor.execute(candidateMethod, state.put(PsiSubstitutor.KEY, finalSubstitutor))) return false;
|
||||
}
|
||||
|
||||
if (visited != null) {
|
||||
for (Pair<PsiMethod, PsiSubstitutor> aList : list) {
|
||||
visited.add(aList.getFirst().getContainingClass());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
return processDeclarationsInClassNotCached(aClass, processor, state, visited, last, place, isRaw, factory);
|
||||
private static PsiSubstitutor checkRaw(boolean isRaw, PsiElementFactory factory, PsiMethod candidateMethod, PsiSubstitutor substitutor) {
|
||||
if (isRaw && !candidateMethod.hasModifierProperty(PsiModifier.STATIC)) { //static methods are not erased due to raw overriding
|
||||
PsiTypeParameter[] methodTypeParameters = candidateMethod.getTypeParameters();
|
||||
substitutor = factory.createRawSubstitutor(substitutor, methodTypeParameters);
|
||||
}
|
||||
return substitutor;
|
||||
}
|
||||
|
||||
public static PsiSubstitutor obtainFinalSubstitutor(@NotNull PsiClass candidateClass, PsiSubstitutor candidateSubstitutor, PsiClass aClass,
|
||||
@@ -531,8 +533,7 @@ public class PsiClassImplUtil {
|
||||
private static boolean processDeclarationsInClassNotCached(PsiClass aClass, PsiScopeProcessor processor, ResolveState state, Set<PsiClass> visited,
|
||||
PsiElement last,
|
||||
PsiElement place,
|
||||
boolean isRaw,
|
||||
PsiElementFactory factory) {
|
||||
boolean isRaw) {
|
||||
if (visited == null) visited = new THashSet<PsiClass>();
|
||||
if (!visited.add(aClass)) return true;
|
||||
processor.handleEvent(PsiScopeProcessor.Event.SET_DECLARATION_HOLDER, aClass);
|
||||
@@ -555,15 +556,15 @@ public class PsiClassImplUtil {
|
||||
}
|
||||
}
|
||||
|
||||
PsiElementFactory factory = JavaPsiFacade.getInstance(aClass.getProject()).getElementFactory();
|
||||
|
||||
if (classHint == null || classHint.shouldProcess(ElementClassHint.DeclarationKind.METHOD)) {
|
||||
PsiSubstitutor baseSubstitutor = state.get(PsiSubstitutor.KEY);
|
||||
final PsiMethod[] methods = nameHint != null ? aClass.findMethodsByName(nameHint.getName(state), false) : aClass.getMethods();
|
||||
for (final PsiMethod method : methods) {
|
||||
if (isRaw && !method.hasModifierProperty(PsiModifier.STATIC)) { //static methods are not erased due to raw overriding
|
||||
PsiTypeParameter[] methodTypeParameters = method.getTypeParameters();
|
||||
PsiSubstitutor raw = factory.createRawSubstitutor(state.get(PsiSubstitutor.KEY), methodTypeParameters);
|
||||
state = state.put(PsiSubstitutor.KEY, raw);
|
||||
}
|
||||
if (!processor.execute(method, state)) return false;
|
||||
PsiSubstitutor finalSubstitutor = checkRaw(isRaw, factory, method, baseSubstitutor);
|
||||
ResolveState methodState = finalSubstitutor == baseSubstitutor ? state : state.put(PsiSubstitutor.KEY, finalSubstitutor);
|
||||
if (!processor.execute(method, methodState)) return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
interface N1 {
|
||||
String getName();
|
||||
}
|
||||
interface N2 {
|
||||
String getName();
|
||||
}
|
||||
interface NN extends N1 {}
|
||||
|
||||
interface N3 {
|
||||
String getName();
|
||||
}
|
||||
interface VeryNamed extends NN, N2, N3, N1 {}
|
||||
|
||||
class MyClass {
|
||||
|
||||
void foo(VeryNamed f) {
|
||||
f.getNa<ref>me();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -262,4 +262,14 @@ public class ResolveMethodTest extends ResolveTestCase {
|
||||
PsiMethod method = (PsiMethod) target;
|
||||
assertEquals("PublicCloneable", method.getContainingClass().getName());
|
||||
}
|
||||
|
||||
public void testMultipleInheritancePathsToMethod() throws Exception {
|
||||
PsiReference ref = configureByFile("method/" + getTestName(false) + ".java");
|
||||
|
||||
// just assume this is called by some highlighting inspection/intention/pass before the resolve
|
||||
JavaPsiFacade.getInstance(getProject()).findClass("NN").getAllMethods();
|
||||
|
||||
PsiElement target = ref.resolve();
|
||||
assertInstanceOf(target, PsiMethod.class);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright 2000-2011 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.navigation;
|
||||
|
||||
import com.intellij.psi.PsiFile;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
|
||||
/**
|
||||
* @author Dmitry Avdeev
|
||||
*/
|
||||
public abstract class GotoRelatedItem {
|
||||
|
||||
public abstract void navigate();
|
||||
|
||||
@NotNull
|
||||
public abstract String getText();
|
||||
|
||||
@Nullable
|
||||
public abstract Icon getIcon();
|
||||
|
||||
@Nullable
|
||||
public abstract PsiFile getContainingFile();
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright 2000-2011 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.navigation;
|
||||
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.extensions.ExtensionPointName;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Dmitry Avdeev
|
||||
*/
|
||||
public abstract class GotoRelatedProvider {
|
||||
|
||||
public static final ExtensionPointName<GotoRelatedProvider> EP_NAME = ExtensionPointName.create("com.intellij.gotoRelatedProvider");
|
||||
|
||||
@NotNull
|
||||
public abstract List<GotoRelatedItem> getItems(PsiElement context);
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright 2000-2011 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.navigation;
|
||||
|
||||
import com.intellij.psi.NavigatablePsiElement;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.swing.*;
|
||||
|
||||
/**
|
||||
* @author Dmitry Avdeev
|
||||
*/
|
||||
public class PsiGotoRelatedItem extends GotoRelatedItem {
|
||||
|
||||
private final NavigatablePsiElement myElement;
|
||||
|
||||
public PsiGotoRelatedItem(@NotNull NavigatablePsiElement element) {
|
||||
myElement = element;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void navigate() {
|
||||
myElement.navigate(true);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getText() {
|
||||
return myElement.getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Icon getIcon() {
|
||||
return myElement.getIcon(0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PsiFile getContainingFile() {
|
||||
return myElement.getContainingFile();
|
||||
}
|
||||
}
|
||||
@@ -59,8 +59,8 @@ public abstract class ElementBase extends UserDataHolderBase implements Iconable
|
||||
};
|
||||
private TIntObjectHashMap<Icon> myBaseIcon;
|
||||
|
||||
private static final Icon VISIBILITY_ICON_PLACHOLDER = new EmptyIcon(Icons.PUBLIC_ICON);
|
||||
public static final Icon ICON_PLACHOLDER = IconLoader.getIcon("/nodes/nodePlaceholder.png");
|
||||
private static final Icon VISIBILITY_ICON_PLACEHOLDER = new EmptyIcon(Icons.PUBLIC_ICON);
|
||||
public static final Icon ICON_PLACEHOLDER = IconLoader.getIcon("/nodes/nodePlaceholder.png");
|
||||
|
||||
@Nullable
|
||||
public Icon getIcon(int flags) {
|
||||
@@ -132,7 +132,7 @@ public abstract class ElementBase extends UserDataHolderBase implements Iconable
|
||||
}
|
||||
}
|
||||
}
|
||||
return ICON_PLACHOLDER;
|
||||
return ICON_PLACEHOLDER;
|
||||
}
|
||||
|
||||
public static boolean isNativeFileType(FileType fileType) {
|
||||
@@ -144,7 +144,7 @@ public abstract class ElementBase extends UserDataHolderBase implements Iconable
|
||||
if ((flags & ICON_FLAG_VISIBILITY) > 0) {
|
||||
RowIcon rowIcon = new RowIcon(2);
|
||||
rowIcon.setIcon(icon, 0);
|
||||
rowIcon.setIcon(VISIBILITY_ICON_PLACHOLDER, 1);
|
||||
rowIcon.setIcon(VISIBILITY_ICON_PLACEHOLDER, 1);
|
||||
result = rowIcon;
|
||||
}
|
||||
|
||||
|
||||
+5
-3
@@ -15,7 +15,7 @@
|
||||
*/
|
||||
package com.intellij.codeInsight.completion;
|
||||
|
||||
import com.intellij.codeInsight.documentation.actions.ShowJavaDocInfoAction;
|
||||
import com.intellij.codeInsight.documentation.actions.ShowQuickDocInfoAction;
|
||||
import com.intellij.codeInsight.hint.actions.ShowImplementationsAction;
|
||||
import com.intellij.codeInsight.lookup.LookupElement;
|
||||
import com.intellij.lang.LangBundle;
|
||||
@@ -23,6 +23,7 @@ import com.intellij.openapi.actionSystem.IdeActions;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
@@ -31,6 +32,7 @@ import java.util.Random;
|
||||
*/
|
||||
public class DefaultCompletionContributor extends CompletionContributor {
|
||||
|
||||
@Nullable
|
||||
public static String getDefaultAdvertisementText(@NotNull final CompletionParameters parameters) {
|
||||
final Random random = new Random();
|
||||
if (random.nextInt(5) < 2 && CompletionUtil.shouldShowFeature(parameters, CodeCompletionFeatures.EDITING_COMPLETION_FINISH_BY_DOT_ETC)) {
|
||||
@@ -56,8 +58,8 @@ public class DefaultCompletionContributor extends CompletionContributor {
|
||||
}
|
||||
|
||||
if (random.nextInt(5) < 2 &&
|
||||
(CompletionUtil.shouldShowFeature(parameters, ShowJavaDocInfoAction.CODEASSISTS_QUICKJAVADOC_FEATURE) ||
|
||||
CompletionUtil.shouldShowFeature(parameters, ShowJavaDocInfoAction.CODEASSISTS_QUICKJAVADOC_LOOKUP_FEATURE))) {
|
||||
(CompletionUtil.shouldShowFeature(parameters, ShowQuickDocInfoAction.CODEASSISTS_QUICKJAVADOC_FEATURE) ||
|
||||
CompletionUtil.shouldShowFeature(parameters, ShowQuickDocInfoAction.CODEASSISTS_QUICKJAVADOC_LOOKUP_FEATURE))) {
|
||||
final String shortcut = getActionShortcut(IdeActions.ACTION_QUICK_JAVADOC);
|
||||
if (shortcut != null) {
|
||||
return LangBundle.message("completion.quick.javadoc.ad", shortcut);
|
||||
|
||||
+11
-2
@@ -62,8 +62,8 @@ import java.awt.event.*;
|
||||
import java.util.List;
|
||||
import java.util.Stack;
|
||||
|
||||
public class DocumentationComponent extends JPanel implements Disposable {
|
||||
|
||||
public class DocumentationComponent extends JPanel implements Disposable, DataProvider {
|
||||
|
||||
private static final DataContext EMPTY_DATA_CONTEXT = new DataContext() {
|
||||
@Override
|
||||
public Object getData(@NonNls String dataId) {
|
||||
@@ -318,6 +318,15 @@ public class DocumentationComponent extends JPanel implements Disposable {
|
||||
this(manager, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getData(@NonNls String dataId) {
|
||||
if (DocumentationManager.SELECTED_QUICK_DOC_TEXT.getName().equals(dataId)) {
|
||||
return myEditorPane.getSelectedText();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private JComponent createSettingsPanel() {
|
||||
JPanel result = new JPanel(new FlowLayout(FlowLayout.RIGHT, 3, 0));
|
||||
result.add(new JLabel(ApplicationBundle.message("label.font.size")));
|
||||
|
||||
+33
-27
@@ -43,7 +43,6 @@ import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.components.ServiceManager;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.extensions.Extensions;
|
||||
import com.intellij.openapi.project.IndexNotReadyException;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.roots.OrderEntry;
|
||||
@@ -83,10 +82,14 @@ import java.util.*;
|
||||
import java.util.List;
|
||||
|
||||
public class DocumentationManager {
|
||||
|
||||
@NonNls public static final String JAVADOC_LOCATION_AND_SIZE = "javadoc.popup";
|
||||
public static final DataKey<String> SELECTED_QUICK_DOC_TEXT = DataKey.create("QUICK_DOC.SELECTED_TEXT");
|
||||
|
||||
private static final Logger LOG = Logger.getInstance("#" + DocumentationManager.class.getName());
|
||||
private static final String SHOW_DOCUMENTATION_IN_TOOL_WINDOW = "ShowDocumentationInToolWindow";
|
||||
private static final String DOCUMENTATION_AUTO_UPDATE_ENABLED = "DocumentationAutoUpdateEnabled";
|
||||
@NonNls public static final String JAVADOC_LOCATION_AND_SIZE = "javadoc.popup";
|
||||
|
||||
private final Project myProject;
|
||||
private Editor myEditor = null;
|
||||
private ParameterInfoController myParameterInfoController;
|
||||
@@ -203,14 +206,11 @@ public class DocumentationManager {
|
||||
|
||||
DocumentationProvider documentationProvider = getProviderFromElement(file);
|
||||
|
||||
PsiElement element = null;
|
||||
if (documentationProvider!=null) {
|
||||
element = documentationProvider.getDocumentationElementForLookupItem(
|
||||
PsiManager.getInstance(myProject),
|
||||
lookupIteObject,
|
||||
originalElement
|
||||
);
|
||||
}
|
||||
PsiElement element = documentationProvider.getDocumentationElementForLookupItem(
|
||||
PsiManager.getInstance(myProject),
|
||||
lookupIteObject,
|
||||
originalElement
|
||||
);
|
||||
|
||||
if (element == null) return;
|
||||
|
||||
@@ -235,7 +235,7 @@ public class DocumentationManager {
|
||||
Project project = getProject(element);
|
||||
|
||||
if (myToolWindow == null && PropertiesComponent.getInstance().isTrueValue(SHOW_DOCUMENTATION_IN_TOOL_WINDOW)) {
|
||||
createToolWindow(element, originalElement, true);
|
||||
createToolWindow(element, originalElement);
|
||||
return;
|
||||
}
|
||||
else if (myToolWindow != null) {
|
||||
@@ -270,7 +270,7 @@ public class DocumentationManager {
|
||||
});
|
||||
Processor<JBPopup> pinCallback = new Processor<JBPopup>() {
|
||||
public boolean process(JBPopup popup) {
|
||||
createToolWindow(element, originalElement, true);
|
||||
createToolWindow(element, originalElement);
|
||||
popup.cancel();
|
||||
return false;
|
||||
}
|
||||
@@ -279,7 +279,7 @@ public class DocumentationManager {
|
||||
final KeyboardShortcut keyboardShortcut = ActionManagerEx.getInstanceEx().getKeyboardShortcut("QuickJavaDoc");
|
||||
final List<Pair<ActionListener, KeyStroke>> actions = Collections.singletonList(Pair.<ActionListener, KeyStroke>create(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
createToolWindow(element, originalElement, false);
|
||||
createToolWindow(element, originalElement);
|
||||
final JBPopup hint = getDocInfoHint();
|
||||
if (hint != null && hint.isVisible()) hint.cancel();
|
||||
}
|
||||
@@ -344,7 +344,7 @@ public class DocumentationManager {
|
||||
}
|
||||
}
|
||||
|
||||
private void createToolWindow(final PsiElement element, PsiElement originalElement, final boolean automatic) {
|
||||
private void createToolWindow(final PsiElement element, PsiElement originalElement) {
|
||||
assert myToolWindow == null;
|
||||
|
||||
final DocumentationComponent component = new DocumentationComponent(this, new AnAction[]{
|
||||
@@ -423,24 +423,30 @@ public class DocumentationManager {
|
||||
public void run() {
|
||||
if (myProject.isDisposed()) return;
|
||||
|
||||
final DataContext dataContext = DataManager.getInstance().getDataContext();
|
||||
AsyncResult<DataContext> asyncResult = DataManager.getInstance().getDataContextFromFocus();
|
||||
DataContext dataContext = asyncResult.getResult();
|
||||
if (dataContext == null) {
|
||||
return;
|
||||
}
|
||||
final Editor editor = PlatformDataKeys.EDITOR.getData(dataContext);
|
||||
if (editor != null) {
|
||||
final PsiFile file = PsiUtilBase.getPsiFileInEditor(editor, myProject);
|
||||
if (editor == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
final Editor injectedEditor = InjectedLanguageUtil.getEditorForInjectedLanguageNoCommit(editor, file);
|
||||
if (injectedEditor != null) {
|
||||
final PsiFile psiFile = PsiUtilBase.getPsiFileInEditor(injectedEditor, myProject);
|
||||
if (psiFile != null) {
|
||||
showJavaDocInfo(injectedEditor, psiFile, false, true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
final PsiFile file = PsiUtilBase.getPsiFileInEditor(editor, myProject);
|
||||
|
||||
if (file != null) {
|
||||
showJavaDocInfo(editor, file, false, true);
|
||||
final Editor injectedEditor = InjectedLanguageUtil.getEditorForInjectedLanguageNoCommit(editor, file);
|
||||
if (injectedEditor != null) {
|
||||
final PsiFile psiFile = PsiUtilBase.getPsiFileInEditor(injectedEditor, myProject);
|
||||
if (psiFile != null) {
|
||||
showJavaDocInfo(injectedEditor, psiFile, false, true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (file != null) {
|
||||
showJavaDocInfo(editor, file, false, true);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
+46
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright 2000-2011 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.codeInsight.documentation.actions;
|
||||
|
||||
import com.intellij.codeInsight.documentation.DocumentationManager;
|
||||
import com.intellij.codeInsight.hint.HintManagerImpl;
|
||||
import com.intellij.openapi.actionSystem.AnAction;
|
||||
import com.intellij.openapi.actionSystem.AnActionEvent;
|
||||
import com.intellij.openapi.ide.CopyPasteManager;
|
||||
import com.intellij.openapi.project.DumbAware;
|
||||
|
||||
import java.awt.datatransfer.StringSelection;
|
||||
|
||||
/**
|
||||
* @author Denis Zhdanov
|
||||
* @since 3/29/11 1:28 PM
|
||||
*/
|
||||
public class CopyQuickDocAction extends AnAction implements DumbAware, HintManagerImpl.ActionToIgnore {
|
||||
|
||||
public CopyQuickDocAction() {
|
||||
setEnabledInModalContext(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(AnActionEvent e) {
|
||||
String selected = e.getData(DocumentationManager.SELECTED_QUICK_DOC_TEXT);
|
||||
if (selected == null || selected.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
CopyPasteManager.getInstance().setContents(new StringSelection(selected));
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -34,11 +34,11 @@ import com.intellij.psi.*;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class ShowJavaDocInfoAction extends BaseCodeInsightAction implements HintManagerImpl.ActionToIgnore, DumbAware, PopupAction {
|
||||
public class ShowQuickDocInfoAction extends BaseCodeInsightAction implements HintManagerImpl.ActionToIgnore, DumbAware, PopupAction {
|
||||
@NonNls public static final String CODEASSISTS_QUICKJAVADOC_LOOKUP_FEATURE = "codeassists.quickjavadoc.lookup";
|
||||
@NonNls public static final String CODEASSISTS_QUICKJAVADOC_FEATURE = "codeassists.quickjavadoc";
|
||||
|
||||
public ShowJavaDocInfoAction() {
|
||||
public ShowQuickDocInfoAction() {
|
||||
setEnabledInModalContext(true);
|
||||
setInjectedContext(true);
|
||||
}
|
||||
+2
-1
@@ -138,6 +138,7 @@ public class LivePreviewControllerBase implements LivePreview.Delegate, FindUtil
|
||||
if (findModel == null) return;
|
||||
final boolean unitTestMode = ApplicationManager.getApplication().isUnitTestMode();
|
||||
final FindModel copy = (FindModel)findModel.clone();
|
||||
final ModalityState modalityState = ModalityState.current();
|
||||
Runnable request = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
@@ -150,7 +151,7 @@ public class LivePreviewControllerBase implements LivePreview.Delegate, FindUtil
|
||||
if (unitTestMode) {
|
||||
denyReplace.run();
|
||||
} else {
|
||||
ApplicationManager.getApplication().invokeAndWait(denyReplace, ModalityState.NON_MODAL);
|
||||
ApplicationManager.getApplication().invokeAndWait(denyReplace, modalityState);
|
||||
}
|
||||
mySearchResults.updateThreadSafe(copy, allowedToChangedEditorSelection, null);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,128 @@
|
||||
/*
|
||||
* Copyright 2000-2011 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.ide.actions;
|
||||
|
||||
import com.intellij.navigation.GotoRelatedItem;
|
||||
import com.intellij.navigation.GotoRelatedProvider;
|
||||
import com.intellij.openapi.actionSystem.*;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.extensions.Extensions;
|
||||
import com.intellij.openapi.ui.popup.JBPopupFactory;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.ui.CollectionListModel;
|
||||
import com.intellij.ui.components.JBList;
|
||||
import com.intellij.util.ui.UIUtil;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Dmitry Avdeev
|
||||
*/
|
||||
public class GotoRelatedFileAction extends AnAction {
|
||||
|
||||
@Override
|
||||
public void actionPerformed(AnActionEvent e) {
|
||||
|
||||
DataContext context = e.getDataContext();
|
||||
Editor editor = PlatformDataKeys.EDITOR.getData(context);
|
||||
PsiFile psiFile = LangDataKeys.PSI_FILE.getData(context);
|
||||
if (psiFile == null) return;
|
||||
|
||||
List<GotoRelatedItem> items = getItems(editor, psiFile);
|
||||
if (items.isEmpty()) return;
|
||||
if (items.size() == 1) {
|
||||
items.get(0).navigate();
|
||||
return;
|
||||
}
|
||||
|
||||
final JBList list = new JBList(new CollectionListModel(items));
|
||||
list.setCellRenderer(new ItemCellRenderer());
|
||||
|
||||
JBPopupFactory.getInstance()
|
||||
.createListPopupBuilder(list)
|
||||
.setTitle("Goto Related")
|
||||
.setItemChoosenCallback(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
Object value = list.getSelectedValue();
|
||||
if (value instanceof GotoRelatedItem) {
|
||||
((GotoRelatedItem)value).navigate();
|
||||
}
|
||||
}
|
||||
})
|
||||
.createPopup()
|
||||
.showInBestPositionFor(context);
|
||||
}
|
||||
|
||||
public static List<GotoRelatedItem> getItems(Editor editor, PsiFile psiFile) {
|
||||
|
||||
PsiElement psiElement = psiFile;
|
||||
if (editor != null) {
|
||||
psiElement = psiFile.findElementAt(editor.getCaretModel().getOffset());
|
||||
}
|
||||
|
||||
List<GotoRelatedItem> items = new ArrayList<GotoRelatedItem>();
|
||||
|
||||
for (GotoRelatedProvider provider : Extensions.getExtensions(GotoRelatedProvider.EP_NAME)) {
|
||||
items.addAll(provider.getItems(psiElement));
|
||||
}
|
||||
return items;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(AnActionEvent e) {
|
||||
e.getPresentation().setEnabled(LangDataKeys.PSI_FILE.getData(e.getDataContext()) != null);
|
||||
}
|
||||
|
||||
private static class ItemCellRenderer extends JPanel implements ListCellRenderer {
|
||||
|
||||
private final JLabel myLeft = new JLabel();
|
||||
private final JLabel myRight = new JLabel();
|
||||
private final JPanel mySpacer = new JPanel();
|
||||
|
||||
private ItemCellRenderer() {
|
||||
super(new BorderLayout());
|
||||
setBorder(BorderFactory.createEmptyBorder(2, 2, 2, 2));
|
||||
add(myLeft, BorderLayout.WEST);
|
||||
add(myRight, BorderLayout.EAST);
|
||||
|
||||
mySpacer.setBorder(BorderFactory.createEmptyBorder(0, 2, 0, 2));
|
||||
mySpacer.setOpaque(false);
|
||||
add(mySpacer, BorderLayout.CENTER);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
|
||||
GotoRelatedItem item = (GotoRelatedItem)value;
|
||||
myLeft.setText(item.getText());
|
||||
myLeft.setIcon(item.getIcon());
|
||||
|
||||
PsiFile file = item.getContainingFile();
|
||||
myRight.setText(file == null ? null : file.getName());
|
||||
myRight.setIcon(file == null ? null : file.getIcon(0));
|
||||
|
||||
setBackground(UIUtil.getListBackground(isSelected));
|
||||
Color foreground = UIUtil.getListForeground(isSelected);
|
||||
myLeft.setForeground(foreground);
|
||||
myRight.setForeground(foreground);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -68,7 +68,7 @@ public class NativeFileIconProvider implements FileIconProvider {
|
||||
if (icon != null) {
|
||||
return icon;
|
||||
}
|
||||
return new DeferredIconImpl<VirtualFile>(ElementBase.ICON_PLACHOLDER, file, false, new Function<VirtualFile, Icon>() {
|
||||
return new DeferredIconImpl<VirtualFile>(ElementBase.ICON_PLACEHOLDER, file, false, new Function<VirtualFile, Icon>() {
|
||||
public Icon fun(VirtualFile virtualFile) {
|
||||
final File f = new File(filePath);
|
||||
if (!f.exists()) {
|
||||
|
||||
@@ -180,10 +180,10 @@ public abstract class PsiAnchor {
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
int result = myClass != null ? myClass.getName().hashCode() : 0;
|
||||
result = 31 * result + myStartOffset; //todo
|
||||
int result = myClass.getName().hashCode();
|
||||
result = 31 * result + myStartOffset;
|
||||
result = 31 * result + myEndOffset;
|
||||
result = 31 * result + myVirtualFile.getName().hashCode();
|
||||
result = 31 * result + myVirtualFile.hashCode();
|
||||
|
||||
return result;
|
||||
}
|
||||
@@ -326,6 +326,17 @@ public abstract class PsiAnchor {
|
||||
return ((31 * myVirtualFile.hashCode() + myIndex) * 31 + myElementType.hashCode()) * 31 + myLanguage.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "StubIndexReference{" +
|
||||
"myVirtualFile=" + myVirtualFile +
|
||||
", myProject=" + myProject +
|
||||
", myIndex=" + myIndex +
|
||||
", myLanguage=" + myLanguage +
|
||||
", myElementType=" + myElementType +
|
||||
'}';
|
||||
}
|
||||
|
||||
public int getStartOffset() {
|
||||
final PsiElement resolved = retrieve();
|
||||
if (resolved == null) throw new PsiInvalidElementAccessException(null);
|
||||
|
||||
@@ -48,7 +48,7 @@ public class PopupChooserBuilder {
|
||||
private JComponent myChooserComponent;
|
||||
private String myTitle;
|
||||
private final ArrayList<KeyStroke> myAdditionalKeystrokes = new ArrayList<KeyStroke>();
|
||||
private Runnable myItemChoosenRunnable;
|
||||
private Runnable myItemChosenRunnable;
|
||||
private JComponent mySouthComponent;
|
||||
private JComponent myEastComponent;
|
||||
|
||||
@@ -103,7 +103,7 @@ public class PopupChooserBuilder {
|
||||
|
||||
@NotNull
|
||||
public PopupChooserBuilder setItemChoosenCallback(@NotNull Runnable runnable) {
|
||||
myItemChoosenRunnable = runnable;
|
||||
myItemChosenRunnable = runnable;
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -283,7 +283,7 @@ public class PopupChooserBuilder {
|
||||
|
||||
private void closePopup(boolean shouldPerformAction, MouseEvent e, boolean isOk) {
|
||||
if (shouldPerformAction) {
|
||||
myPopup.setFinalRunnable(myItemChoosenRunnable);
|
||||
myPopup.setFinalRunnable(myItemChosenRunnable);
|
||||
}
|
||||
|
||||
if (isOk) {
|
||||
|
||||
@@ -138,6 +138,8 @@
|
||||
<extensionPoint name="gotoFileContributor"
|
||||
interface="com.intellij.navigation.ChooseByNameContributor"/>
|
||||
|
||||
<extensionPoint name="gotoRelatedProvider" interface="com.intellij.navigation.GotoRelatedProvider"/>
|
||||
|
||||
<extensionPoint name="projectExtension" interface="com.intellij.openapi.roots.ProjectExtension" area="IDEA_PROJECT"/>
|
||||
<extensionPoint name="roots.watchedRootsProvider" interface="com.intellij.openapi.roots.WatchedRootsProvider" area="IDEA_PROJECT"/>
|
||||
<extensionPoint name="moduleExtension" interface="com.intellij.openapi.roots.ModuleExtension" area="IDEA_MODULE"/>
|
||||
|
||||
@@ -136,7 +136,7 @@
|
||||
<separator/>
|
||||
<group id="CodeEditorViewGroup">
|
||||
<action id="FileStructurePopup" class="com.intellij.ide.actions.ViewStructureAction"/>
|
||||
<action id="QuickJavaDoc" class="com.intellij.codeInsight.documentation.actions.ShowJavaDocInfoAction"/>
|
||||
<action id="QuickJavaDoc" class="com.intellij.codeInsight.documentation.actions.ShowQuickDocInfoAction"/>
|
||||
<action id="ExternalJavaDoc" class="com.intellij.ide.actions.ExternalJavaDocAction"/>
|
||||
<action id="SelectIn" class="com.intellij.ide.actions.SelectInAction"/>
|
||||
<action id="ParameterInfo" class="com.intellij.codeInsight.hint.actions.ShowParameterInfoAction"/>
|
||||
@@ -225,6 +225,9 @@
|
||||
<action id="GotoTypeDeclaration" class="com.intellij.codeInsight.navigation.actions.GotoTypeDeclarationAction"/>
|
||||
<action id="GotoSuperMethod" class="com.intellij.codeInsight.navigation.actions.GotoSuperAction"/>
|
||||
<action id="GotoTest" class="com.intellij.testIntegration.GotoTestOrCodeAction"/>
|
||||
<action id="GotoRelated" class="com.intellij.ide.actions.GotoRelatedFileAction" text="_Related File">
|
||||
<keyboard-shortcut keymap="$default" first-keystroke="ctrl shift Q"/>
|
||||
</action>
|
||||
<separator/>
|
||||
|
||||
<add-to-group group-id="GoToMenu" anchor="before" relative-to-action="GoToErrorGroup"/>
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
|
||||
<action id="TextComponent.ClearAction" class="com.intellij.ui.ClearTextAction"/>
|
||||
<action id="Switcher" class="com.intellij.ide.actions.Switcher" text="Switcher"/>
|
||||
<action id="QuickDocCopy" class="com.intellij.codeInsight.documentation.actions.CopyQuickDocAction" use-shortcut-of="$Copy"/>
|
||||
|
||||
<group id="EditorActions">
|
||||
<action id="EditorPageUp" class="com.intellij.openapi.editor.actions.PageUpAction"/>
|
||||
|
||||
@@ -17,10 +17,7 @@ package com.intellij.testFramework;
|
||||
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileReader;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.io.*;
|
||||
import java.math.BigInteger;
|
||||
|
||||
/**
|
||||
@@ -28,6 +25,9 @@ import java.math.BigInteger;
|
||||
*/
|
||||
@SuppressWarnings({"UtilityClassWithoutPrivateConstructor"})
|
||||
public class Timings {
|
||||
private static final int CPU_PROBES = 1000000;
|
||||
private static final int IO_PROBES = 42;
|
||||
|
||||
public static final long CPU_TIMING;
|
||||
public static final long IO_TIMING;
|
||||
public static final long MACHINE_TIMING;
|
||||
@@ -37,13 +37,13 @@ public class Timings {
|
||||
|
||||
start = System.currentTimeMillis();
|
||||
BigInteger k = new BigInteger("1");
|
||||
for (int i = 0; i < 1000000; i++) {
|
||||
for (int i = 0; i < CPU_PROBES; i++) {
|
||||
k = k.add(new BigInteger("1"));
|
||||
}
|
||||
CPU_TIMING = System.currentTimeMillis() - start;
|
||||
|
||||
start = System.currentTimeMillis();
|
||||
for (int i = 0; i < 42; i++) {
|
||||
for (int i = 0; i < IO_PROBES; i++) {
|
||||
try {
|
||||
final File tempFile = FileUtil.createTempFile("test", "test" + i);
|
||||
|
||||
@@ -66,6 +66,16 @@ public class Timings {
|
||||
reader.close();
|
||||
}
|
||||
|
||||
if (i == IO_PROBES - 1) {
|
||||
final FileOutputStream stream = new FileOutputStream(tempFile);
|
||||
try {
|
||||
stream.getFD().sync();
|
||||
}
|
||||
finally {
|
||||
stream.close();
|
||||
}
|
||||
}
|
||||
|
||||
if (!tempFile.delete()) {
|
||||
throw new IOException("Unable to delete: " + tempFile);
|
||||
}
|
||||
|
||||
+11
-4
@@ -758,7 +758,6 @@ public class CodeInsightTestFixtureImpl extends BaseFixture implements CodeInsig
|
||||
@Nullable
|
||||
public GutterIconRenderer findGutter(final String filePath) {
|
||||
assertInitialized();
|
||||
final Ref<GutterIconRenderer> result = new Ref<GutterIconRenderer>();
|
||||
configureByFilesInner(filePath);
|
||||
int offset = myEditor.getCaretModel().getOffset();
|
||||
|
||||
@@ -767,12 +766,20 @@ public class CodeInsightTestFixtureImpl extends BaseFixture implements CodeInsig
|
||||
if (info.endOffset >= offset && info.startOffset <= offset) {
|
||||
final GutterIconRenderer renderer = info.getGutterIconRenderer();
|
||||
if (renderer != null) {
|
||||
result.set(renderer);
|
||||
break;
|
||||
return renderer;
|
||||
}
|
||||
}
|
||||
}
|
||||
return result.get();
|
||||
RangeHighlighter[] highlighters = myEditor.getDocument().getMarkupModel(getProject()).getAllHighlighters();
|
||||
for (RangeHighlighter highlighter : highlighters) {
|
||||
if (highlighter.getEndOffset() >= offset && highlighter.getStartOffset() <= offset) {
|
||||
GutterIconRenderer renderer = highlighter.getGutterIconRenderer();
|
||||
if (renderer != null) {
|
||||
return renderer;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -435,10 +435,18 @@ public class UIUtil {
|
||||
return isUnderGTKLookAndFeel() ? getTreeTextBackground() : UIManager.getColor("List.background");
|
||||
}
|
||||
|
||||
public static Color getListBackground(boolean isSelected) {
|
||||
return isSelected ? getListSelectionBackground() : getListBackground();
|
||||
}
|
||||
|
||||
public static Color getListForeground() {
|
||||
return UIManager.getColor("List.foreground");
|
||||
}
|
||||
|
||||
public static Color getListForeground(boolean isSelected) {
|
||||
return isSelected ? getListSelectionForeground() : getListForeground();
|
||||
}
|
||||
|
||||
public static Color getPanelBackground() {
|
||||
return UIManager.getColor("Panel.background");
|
||||
}
|
||||
|
||||
+19
-18
@@ -22,16 +22,16 @@ import com.intellij.openapi.vcs.*;
|
||||
import com.intellij.openapi.vcs.history.VcsHistoryProvider;
|
||||
import com.intellij.openapi.vfs.LocalFileSystem;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
|
||||
|
||||
public class TabbedShowHistoryAction extends AbstractVcsAction {
|
||||
protected void update(VcsContext context, Presentation presentation) {
|
||||
presentation.setEnabled(isEnabled(context));
|
||||
final Project project = context.getProject();
|
||||
presentation.setVisible(project != null && ProjectLevelVcsManager.getInstance(project).getAllActiveVcss().length > 0);
|
||||
presentation.setVisible(project != null && ProjectLevelVcsManager.getInstance(project).hasActiveVcss());
|
||||
}
|
||||
|
||||
protected VcsHistoryProvider getProvider(AbstractVcs activeVcs) {
|
||||
@@ -39,50 +39,51 @@ public class TabbedShowHistoryAction extends AbstractVcsAction {
|
||||
}
|
||||
|
||||
protected boolean isEnabled(VcsContext context) {
|
||||
FilePath[] selectedFiles = getSelectedFiles(context);
|
||||
if (selectedFiles == null) return false;
|
||||
if (selectedFiles.length != 1) return false;
|
||||
FilePath path = selectedFiles[0];
|
||||
FilePath selectedFile = getSelectedFileOrNull(context);
|
||||
if (selectedFile == null) return false;
|
||||
Project project = context.getProject();
|
||||
if (project == null) return false;
|
||||
VirtualFile someVFile = path.getVirtualFile() != null ? path.getVirtualFile() : path.getVirtualFileParent();
|
||||
VirtualFile someVFile = selectedFile.getVirtualFile() != null ?
|
||||
selectedFile.getVirtualFile() : selectedFile.getVirtualFileParent();
|
||||
AbstractVcs vcs = ProjectLevelVcsManager.getInstance(project).getVcsFor(someVFile);
|
||||
if (vcs == null) return false;
|
||||
VcsHistoryProvider vcsHistoryProvider = getProvider(vcs);
|
||||
if (vcsHistoryProvider == null) return false;
|
||||
if (selectedFiles[0].isDirectory() && (! vcsHistoryProvider.supportsHistoryForDirectories())) return false;
|
||||
if (selectedFile.isDirectory() && (! vcsHistoryProvider.supportsHistoryForDirectories())) return false;
|
||||
final FileStatus fileStatus = FileStatusManager.getInstance(project).getStatus(someVFile);
|
||||
return fileStatus != FileStatus.ADDED && fileStatus != FileStatus.UNKNOWN && fileStatus != FileStatus.IGNORED;
|
||||
}
|
||||
|
||||
protected static FilePath[] getSelectedFiles(VcsContext context) {
|
||||
ArrayList<FilePath> result = new ArrayList<FilePath>();
|
||||
@Nullable
|
||||
protected static FilePath getSelectedFileOrNull(VcsContext context) {
|
||||
FilePath result = null;
|
||||
VirtualFile[] virtualFileArray = context.getSelectedFiles();
|
||||
if (virtualFileArray != null) {
|
||||
for (VirtualFile virtualFile : virtualFileArray) {
|
||||
result.add(new FilePathImpl(virtualFile));
|
||||
if (virtualFileArray.length > 1) return null;
|
||||
if (virtualFileArray.length > 0) {
|
||||
result = new FilePathImpl(virtualFileArray[0]);
|
||||
}
|
||||
}
|
||||
|
||||
File[] fileArray = context.getSelectedIOFiles();
|
||||
if (fileArray != null) {
|
||||
if (fileArray != null && fileArray.length > 0) {
|
||||
for (File file : fileArray) {
|
||||
final File parentIoFile = file.getParentFile();
|
||||
if (parentIoFile == null) continue;
|
||||
final VirtualFile parent = LocalFileSystem.getInstance().findFileByIoFile(parentIoFile);
|
||||
if (parent != null) {
|
||||
final FilePathImpl child = new FilePathImpl(parent, file.getName(), false);
|
||||
if (! result.contains(child)) {
|
||||
result.add(child);
|
||||
}
|
||||
if (result != null) return null;
|
||||
result = child;
|
||||
}
|
||||
}
|
||||
}
|
||||
return result.toArray(new FilePath[result.size()]);
|
||||
return result;
|
||||
}
|
||||
|
||||
protected void actionPerformed(VcsContext context) {
|
||||
FilePath path = getSelectedFiles(context)[0];
|
||||
FilePath path = getSelectedFileOrNull(context);
|
||||
if (path == null) return;
|
||||
Project project = context.getProject();
|
||||
VirtualFile someVFile = path.getVirtualFile() != null ? path.getVirtualFile() : path.getVirtualFileParent();
|
||||
AbstractVcs activeVcs = ProjectLevelVcsManager.getInstance(project).getVcsFor(someVFile);
|
||||
|
||||
@@ -162,7 +162,7 @@ public class AndroidIdlCompiler implements SourceGeneratingCompiler {
|
||||
if (myContext.getProject().isDisposed()) {
|
||||
return EMPTY_GENERATION_ITEM_ARRAY;
|
||||
}
|
||||
VirtualFile[] files = myContext.getProjectCompileScope().getFiles(AndroidIdlFileType.ourFileType, false);
|
||||
VirtualFile[] files = myContext.getProjectCompileScope().getFiles(AndroidIdlFileType.ourFileType, true);
|
||||
List<GenerationItem> items = new ArrayList<GenerationItem>(files.length);
|
||||
for (VirtualFile file : files) {
|
||||
Module module = myContext.getModuleByFile(file);
|
||||
|
||||
+1
-1
@@ -60,7 +60,7 @@
|
||||
</constraints>
|
||||
<properties>
|
||||
<selected value="true"/>
|
||||
<text value="Create "&Hello, World!" project"/>
|
||||
<text value="Create "&Hello, World!" activity"/>
|
||||
</properties>
|
||||
</component>
|
||||
<grid id="f0788" binding="myActivtiyPanel" layout-manager="GridLayoutManager" row-count="1" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
||||
|
||||
@@ -29,6 +29,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.event.DocumentEvent;
|
||||
import java.awt.*;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
|
||||
@@ -71,6 +72,7 @@ public class AndroidAppPropertiesEditor {
|
||||
}
|
||||
|
||||
public void updateActivityPanel() {
|
||||
myErrorLabel.setForeground(Color.RED);
|
||||
UIUtil.setEnabled(myActivtiyPanel, myHelloAndroidCheckBox.isSelected(), true);
|
||||
}
|
||||
|
||||
|
||||
@@ -49,10 +49,12 @@ import com.intellij.psi.PsiManager;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import org.jetbrains.android.AndroidFileTemplateProvider;
|
||||
import org.jetbrains.android.dom.manifest.Manifest;
|
||||
import org.jetbrains.android.dom.resources.ResourceElement;
|
||||
import org.jetbrains.android.dom.resources.ResourceValue;
|
||||
import org.jetbrains.android.facet.AndroidFacet;
|
||||
import org.jetbrains.android.facet.AndroidFacetConfiguration;
|
||||
import org.jetbrains.android.facet.AndroidRootUtil;
|
||||
import org.jetbrains.android.resourceManagers.LocalResourceManager;
|
||||
import org.jetbrains.android.run.testing.AndroidTestRunConfiguration;
|
||||
import org.jetbrains.android.run.testing.AndroidTestRunConfigurationType;
|
||||
import org.jetbrains.android.sdk.AndroidPlatform;
|
||||
@@ -90,6 +92,10 @@ public class AndroidModuleBuilder extends JavaModuleBuilder {
|
||||
|
||||
rootModel.setSdk(mySdk);
|
||||
|
||||
if (myProjectType == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
VirtualFile[] files = rootModel.getContentRoots();
|
||||
if (files.length > 0) {
|
||||
final VirtualFile contentRoot = files[0];
|
||||
@@ -253,10 +259,7 @@ public class AndroidModuleBuilder extends JavaModuleBuilder {
|
||||
return;
|
||||
}
|
||||
if (myProjectType == ProjectType.APPLICATION) {
|
||||
Manifest manifest = facet.getManifest();
|
||||
if (manifest != null && myApplicationName.length() > 0) {
|
||||
manifest.getApplication().getLabel().setValue(ResourceValue.literal(myApplicationName));
|
||||
}
|
||||
assignApplicationName(facet);
|
||||
createChildDirectoryIfNotExist(project, contentRoot, SdkConstants.FD_ASSETS);
|
||||
createChildDirectoryIfNotExist(project, contentRoot, SdkConstants.FD_NATIVE_LIBS);
|
||||
}
|
||||
@@ -284,6 +287,35 @@ public class AndroidModuleBuilder extends JavaModuleBuilder {
|
||||
return true;
|
||||
}
|
||||
|
||||
private void assignApplicationName(AndroidFacet facet) {
|
||||
if (myApplicationName == null || myApplicationName.length() == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
final LocalResourceManager manager = facet.getLocalResourceManager();
|
||||
ResourceElement appNameResElement = null;
|
||||
final String appNameResource = "app_name";
|
||||
|
||||
for (ResourceElement resElement : manager.getValueResources("string")) {
|
||||
if (appNameResource.equals(resElement.getName().getValue())) {
|
||||
appNameResElement = resElement;
|
||||
}
|
||||
}
|
||||
|
||||
if (appNameResElement == null) {
|
||||
manager.addValueResource("string", appNameResource, myApplicationName);
|
||||
}
|
||||
else {
|
||||
appNameResElement.setStringValue(myApplicationName);
|
||||
}
|
||||
|
||||
final Manifest manifest = facet.getManifest();
|
||||
|
||||
if (manifest != null) {
|
||||
manifest.getApplication().getLabel().setValue(ResourceValue.referenceTo('@', null, "string", appNameResource));
|
||||
}
|
||||
}
|
||||
|
||||
private static void moveContentAndRemoveDir(Project project, @NotNull VirtualFile from, @NotNull VirtualFile to) throws IOException {
|
||||
for (VirtualFile child : from.getChildren()) {
|
||||
child.move(project, to);
|
||||
@@ -386,9 +418,8 @@ public class AndroidModuleBuilder extends JavaModuleBuilder {
|
||||
FileDocumentManager.getInstance().saveAllDocuments();
|
||||
}
|
||||
});
|
||||
if (myApplicationName.length() > 0) {
|
||||
manifest.getApplication().getLabel().setValue(ResourceValue.literal(myApplicationName));
|
||||
}
|
||||
|
||||
assignApplicationName(facet);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="org.jetbrains.android.newProject.AndroidModuleWizardStep">
|
||||
<grid id="27dc6" binding="myPanel" layout-manager="GridLayoutManager" row-count="4" column-count="4" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
||||
<grid id="27dc6" binding="myPanel" layout-manager="GridLayoutManager" row-count="4" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
||||
<margin top="0" left="0" bottom="0" right="0"/>
|
||||
<constraints>
|
||||
<xy x="20" y="20" width="371" height="346"/>
|
||||
<xy x="20" y="20" width="388" height="346"/>
|
||||
</constraints>
|
||||
<properties/>
|
||||
<border type="etched"/>
|
||||
@@ -13,44 +13,6 @@
|
||||
<grid row="3" column="0" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
</vspacer>
|
||||
<component id="fcf3f" class="javax.swing.JRadioButton" binding="myApplicationProjectButton">
|
||||
<constraints>
|
||||
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<text resource-bundle="messages/AndroidBundle" key="android.wizard.application.project.button"/>
|
||||
</properties>
|
||||
</component>
|
||||
<component id="f868f" class="javax.swing.JRadioButton" binding="myLibProjectButton">
|
||||
<constraints>
|
||||
<grid row="1" column="1" 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/AndroidBundle" key="android.wizard.lib.project.button"/>
|
||||
</properties>
|
||||
</component>
|
||||
<component id="1d479" class="javax.swing.JRadioButton" binding="myTestProjectButton">
|
||||
<constraints>
|
||||
<grid row="1" column="2" 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/AndroidBundle" key="android.wizard.test.project.button"/>
|
||||
</properties>
|
||||
</component>
|
||||
<grid id="de9a9" binding="myPropertiesPanel" layout-manager="GridLayoutManager" row-count="1" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
||||
<margin top="0" left="0" bottom="0" right="0"/>
|
||||
<constraints>
|
||||
<grid row="2" column="0" row-span="1" col-span="4" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties/>
|
||||
<border type="etched" title="Project properties"/>
|
||||
<children/>
|
||||
</grid>
|
||||
<hspacer id="dcf5b">
|
||||
<constraints>
|
||||
<grid row="1" column="3" row-span="1" col-span="1" vsize-policy="1" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
</hspacer>
|
||||
<component id="1b82d" class="javax.swing.JLabel">
|
||||
<constraints>
|
||||
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||
@@ -61,10 +23,67 @@
|
||||
</component>
|
||||
<component id="ad4b3" class="org.jetbrains.android.newProject.AndroidSdkComboBoxWithBrowseButton" binding="mySdkComboBoxWithBrowseButton">
|
||||
<constraints>
|
||||
<grid row="0" column="1" row-span="1" col-span="3" vsize-policy="0" hsize-policy="3" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
|
||||
<grid row="0" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties/>
|
||||
</component>
|
||||
<component id="58e73" class="javax.swing.JCheckBox" binding="myCreateDefaultStructure">
|
||||
<constraints>
|
||||
<grid row="1" column="0" row-span="1" col-span="2" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<selected value="true"/>
|
||||
<text value="C&reate default Android application structure"/>
|
||||
</properties>
|
||||
</component>
|
||||
<grid id="a718b" binding="myApplicationPanel" layout-manager="GridLayoutManager" row-count="2" column-count="4" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
||||
<margin top="0" left="0" bottom="0" right="0"/>
|
||||
<constraints>
|
||||
<grid row="2" column="0" row-span="1" col-span="2" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties/>
|
||||
<border type="etched" title="Project properties"/>
|
||||
<children>
|
||||
<component id="fcf3f" class="javax.swing.JRadioButton" binding="myApplicationProjectButton">
|
||||
<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/AndroidBundle" key="android.wizard.application.project.button"/>
|
||||
</properties>
|
||||
</component>
|
||||
<hspacer id="92c4f">
|
||||
<constraints>
|
||||
<grid row="0" column="3" row-span="1" col-span="1" vsize-policy="1" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
</hspacer>
|
||||
<component id="f868f" class="javax.swing.JRadioButton" binding="myLibProjectButton">
|
||||
<constraints>
|
||||
<grid row="0" column="1" 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/AndroidBundle" key="android.wizard.lib.project.button"/>
|
||||
</properties>
|
||||
</component>
|
||||
<component id="1d479" class="javax.swing.JRadioButton" binding="myTestProjectButton">
|
||||
<constraints>
|
||||
<grid row="0" column="2" 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/AndroidBundle" key="android.wizard.test.project.button"/>
|
||||
</properties>
|
||||
</component>
|
||||
<grid id="de9a9" binding="myPropertiesPanel" layout-manager="GridLayoutManager" row-count="1" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
||||
<margin top="0" left="0" bottom="0" right="0"/>
|
||||
<constraints>
|
||||
<grid row="1" column="0" row-span="1" col-span="4" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties/>
|
||||
<border type="none"/>
|
||||
<children/>
|
||||
</grid>
|
||||
</children>
|
||||
</grid>
|
||||
</children>
|
||||
</grid>
|
||||
<buttonGroups>
|
||||
|
||||
@@ -57,6 +57,8 @@ public class AndroidModuleWizardStep extends ModuleWizardStep {
|
||||
private JPanel myPropertiesPanel;
|
||||
|
||||
private AndroidSdkComboBoxWithBrowseButton mySdkComboBoxWithBrowseButton;
|
||||
private JCheckBox myCreateDefaultStructure;
|
||||
private JPanel myApplicationPanel;
|
||||
|
||||
private final WizardContext myWizardContext;
|
||||
|
||||
@@ -84,31 +86,47 @@ public class AndroidModuleWizardStep extends ModuleWizardStep {
|
||||
ActionListener listener = new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
if (myApplicationProjectButton.isSelected() || myLibProjectButton.isSelected()) {
|
||||
myAppPropertiesEditor.getContentPanel().setVisible(true);
|
||||
if (myTestPropertiesEditor != null) {
|
||||
myTestPropertiesEditor.getContentPanel().setVisible(false);
|
||||
}
|
||||
boolean app = myApplicationProjectButton.isSelected();
|
||||
myAppPropertiesEditor.getApplicationNameField().setEnabled(app);
|
||||
myAppPropertiesEditor.getHelloAndroidCheckBox().setEnabled(app);
|
||||
if (app) {
|
||||
myAppPropertiesEditor.updateActivityPanel();
|
||||
}
|
||||
else {
|
||||
UIUtil.setEnabled(myAppPropertiesEditor.getActivtiyPanel(), app, true);
|
||||
}
|
||||
}
|
||||
else {
|
||||
myAppPropertiesEditor.getContentPanel().setVisible(false);
|
||||
assert myTestPropertiesEditor != null;
|
||||
myTestPropertiesEditor.getContentPanel().setVisible(true);
|
||||
}
|
||||
updatePropertiesEditor();
|
||||
}
|
||||
};
|
||||
myApplicationProjectButton.addActionListener(listener);
|
||||
myLibProjectButton.addActionListener(listener);
|
||||
myTestProjectButton.addActionListener(listener);
|
||||
|
||||
myCreateDefaultStructure.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
final boolean enabled = myCreateDefaultStructure.isSelected();
|
||||
UIUtil.setEnabled(myApplicationPanel, enabled, true);
|
||||
|
||||
if (enabled) {
|
||||
updatePropertiesEditor();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void updatePropertiesEditor() {
|
||||
if (myApplicationProjectButton.isSelected() || myLibProjectButton.isSelected()) {
|
||||
myAppPropertiesEditor.getContentPanel().setVisible(true);
|
||||
if (myTestPropertiesEditor != null) {
|
||||
myTestPropertiesEditor.getContentPanel().setVisible(false);
|
||||
}
|
||||
boolean app = myApplicationProjectButton.isSelected();
|
||||
myAppPropertiesEditor.getApplicationNameField().setEnabled(app);
|
||||
myAppPropertiesEditor.getHelloAndroidCheckBox().setEnabled(app);
|
||||
if (app) {
|
||||
myAppPropertiesEditor.updateActivityPanel();
|
||||
}
|
||||
else {
|
||||
UIUtil.setEnabled(myAppPropertiesEditor.getActivtiyPanel(), app, true);
|
||||
}
|
||||
}
|
||||
else {
|
||||
myAppPropertiesEditor.getContentPanel().setVisible(false);
|
||||
assert myTestPropertiesEditor != null;
|
||||
myTestPropertiesEditor.getContentPanel().setVisible(true);
|
||||
}
|
||||
}
|
||||
|
||||
public JComponent getComponent() {
|
||||
@@ -135,6 +153,10 @@ public class AndroidModuleWizardStep extends ModuleWizardStep {
|
||||
throw new ConfigurationException(AndroidBundle.message("select.platform.error"));
|
||||
}
|
||||
|
||||
if (!myCreateDefaultStructure.isSelected()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (myApplicationProjectButton.isSelected() || myLibProjectButton.isSelected()) {
|
||||
myAppPropertiesEditor.validate(myTestProjectButton.isSelected());
|
||||
}
|
||||
@@ -153,6 +175,10 @@ public class AndroidModuleWizardStep extends ModuleWizardStep {
|
||||
PropertiesComponent.getInstance().setValue(AndroidSdkUtils.DEFAULT_PLATFORM_NAME_PROPERTY, selectedSdk.getName());
|
||||
myModuleBuilder.setSdk(selectedSdk);
|
||||
|
||||
if (!myCreateDefaultStructure.isSelected()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (myApplicationProjectButton.isSelected() || myLibProjectButton.isSelected()) {
|
||||
myModuleBuilder.setProjectType(myApplicationProjectButton.isSelected() ? ProjectType.APPLICATION : ProjectType.LIBRARY);
|
||||
myModuleBuilder.setActivityName(myAppPropertiesEditor.getActivityName());
|
||||
|
||||
@@ -277,19 +277,23 @@ public abstract class AndroidRunConfigurationBase extends ModuleBasedConfigurati
|
||||
}
|
||||
|
||||
private static boolean activateDdmsIfNeccessary(@NotNull AndroidFacet facet) {
|
||||
Project project = facet.getModule().getProject();
|
||||
boolean ddmsEnabled = AndroidEnableDdmsAction.isDdmsEnabled();
|
||||
final Project project = facet.getModule().getProject();
|
||||
final boolean ddmsEnabled = AndroidEnableDdmsAction.isDdmsEnabled();
|
||||
boolean shouldRestartDdms = !ddmsEnabled;
|
||||
|
||||
if (ddmsEnabled && isDdmsCorrupted(facet)) {
|
||||
ddmsEnabled = false;
|
||||
shouldRestartDdms = true;
|
||||
AndroidEnableDdmsAction.setDdmsEnabled(project, false);
|
||||
}
|
||||
|
||||
if (!ddmsEnabled) {
|
||||
int result = Messages.showYesNoDialog(project, AndroidBundle.message("android.ddms.disabled.error"),
|
||||
AndroidBundle.message("android.ddms.disabled.dialog.title"),
|
||||
Messages.getQuestionIcon());
|
||||
if (result != 0) {
|
||||
return false;
|
||||
if (shouldRestartDdms) {
|
||||
if (!ddmsEnabled) {
|
||||
int result = Messages.showYesNoDialog(project, AndroidBundle.message("android.ddms.disabled.error"),
|
||||
AndroidBundle.message("android.ddms.disabled.dialog.title"),
|
||||
Messages.getQuestionIcon());
|
||||
if (result != 0) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
AndroidEnableDdmsAction.setDdmsEnabled(project, true);
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@ import com.intellij.openapi.vcs.changes.Change;
|
||||
import com.intellij.openapi.vcs.changes.ChangeListManager;
|
||||
import com.intellij.openapi.vcs.changes.ContentRevision;
|
||||
import com.intellij.openapi.vcs.changes.VcsDirtyScope;
|
||||
import com.intellij.openapi.vfs.VfsUtil;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.vcsUtil.VcsUtil;
|
||||
import git4idea.GitContentRevision;
|
||||
@@ -190,6 +191,10 @@ class ChangeCollector {
|
||||
*/
|
||||
private static boolean isAncestor(FilePath parentCandidate, FilePath childCandidate, boolean strict) {
|
||||
try {
|
||||
if (childCandidate.getPath().length() < parentCandidate.getPath().length()) return false;
|
||||
if (childCandidate.getVirtualFile() != null && parentCandidate.getVirtualFile() != null) {
|
||||
return VfsUtil.isAncestor(parentCandidate.getVirtualFile(), childCandidate.getVirtualFile(), strict);
|
||||
}
|
||||
return FileUtil.isAncestor(parentCandidate.getIOFile(), childCandidate.getIOFile(), strict);
|
||||
}
|
||||
catch (IOException e) {
|
||||
|
||||
@@ -19,6 +19,7 @@ import com.intellij.ide.GeneralSettings;
|
||||
import com.intellij.openapi.application.ApplicationNamesInfo;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.ui.Messages;
|
||||
import com.intellij.openapi.util.Computable;
|
||||
import com.intellij.openapi.vcs.CheckoutProvider;
|
||||
import com.intellij.openapi.vfs.LocalFileSystem;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
@@ -82,21 +83,32 @@ public class GithubCheckoutProvider implements CheckoutProvider {
|
||||
}
|
||||
|
||||
// All the preliminary work is already done, go and clone the selected repository!
|
||||
final RepositoryInfo selectedRepository = checkoutDialog.getSelectedRepository();
|
||||
RepositoryInfo selectedRepository = checkoutDialog.getSelectedRepository();
|
||||
// Check if selected repository exists
|
||||
final String owner = selectedRepository.getOwner();
|
||||
final String name = selectedRepository.getName();
|
||||
if (selectedRepository instanceof UnknownRepositoryInfo) {
|
||||
selectedRepository = GithubUtil.getDetailedRepositoryInfo(project, owner, name);
|
||||
}
|
||||
if (selectedRepository == null){
|
||||
Messages.showErrorDialog(project, "Selected repository ''" + owner +"/" + name + "'' doesn't exist.", "Cannot clone repository");
|
||||
return;
|
||||
}
|
||||
|
||||
final boolean writeAccessAllowed = GithubUtil.isWriteAccessAllowed(project, selectedRepository);
|
||||
if (!writeAccessAllowed){
|
||||
Messages.showErrorDialog(project, "It seems that you have only read access to the selected repository.\n" +
|
||||
"GitHub supports only https protocol for readonly access, which is not supported yet.\n" +
|
||||
"As a workaround, please fork it and clone your forked repository instead.\n" +
|
||||
"More details are available here: http://youtrack.jetbrains.net/issue/IDEA-55298", "Cannot clone this repository");
|
||||
"More details are available here: http://youtrack.jetbrains.net/issue/IDEA-55298", "Cannot clone repository");
|
||||
return;
|
||||
}
|
||||
final String host = writeAccessAllowed ? "git@" + settings.getHost() + ":" : "https://github.com" + settings.getHost() + "/";
|
||||
final String selectedPath = checkoutDialog.getSelectedPath();
|
||||
final VirtualFile selectedPathFile = LocalFileSystem.getInstance().findFileByPath(selectedPath);
|
||||
final String projectName = checkoutDialog.getProjectName();
|
||||
final String repositoryName = selectedRepository.getName();
|
||||
final String repositoryOwner = selectedRepository.getOwner();
|
||||
final String repositoryName = name;
|
||||
final String repositoryOwner = owner;
|
||||
final String checkoutUrl = host + repositoryOwner + "/" + repositoryName + ".git";
|
||||
GitCheckoutProvider.checkout(project, listener, selectedPathFile, checkoutUrl, projectName, "origin", selectedPath);
|
||||
}
|
||||
|
||||
@@ -106,7 +106,7 @@ public class GithubRebaseAction extends DumbAwareAction {
|
||||
repoName = repoName.substring(0, repoName.length() - 4);
|
||||
}
|
||||
|
||||
final RepositoryInfo repositoryInfo = GithubUtil.getDetailedRepositoryInfo(project, repoName);
|
||||
final RepositoryInfo repositoryInfo = GithubUtil.getDetailedRepositoryInfo(project, login, repoName);
|
||||
if (repositoryInfo == null) {
|
||||
Messages
|
||||
.showErrorDialog(project, "Github repository doesn't seem to be your own repository: " + pushUrl, CANNOT_PERFORM_GITHUB_REBASE);
|
||||
|
||||
@@ -182,9 +182,9 @@ public class GithubUtil {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static RepositoryInfo getDetailedRepoInfo(final String url, final String login, final String password, final String name) {
|
||||
public static RepositoryInfo getDetailedRepoInfo(final String url, final String login, final String password, final String owner, final String name) {
|
||||
try {
|
||||
final String request = "/repos/show/" + login + "/" + name;
|
||||
final String request = "/repos/show/" + owner + "/" + name;
|
||||
final HttpMethod method = doREST(url, login, password, request, false);
|
||||
final InputStream stream = method.getResponseBodyAsStream();
|
||||
final Element element = new SAXBuilder(false).build(stream).getRootElement();
|
||||
@@ -302,7 +302,7 @@ public class GithubUtil {
|
||||
* @return
|
||||
*/
|
||||
@Nullable
|
||||
public static RepositoryInfo getDetailedRepositoryInfo(final Project project, final String name) {
|
||||
public static RepositoryInfo getDetailedRepositoryInfo(final Project project, final String owner, final String name) {
|
||||
final GithubSettings settings = GithubSettings.getInstance();
|
||||
final boolean validCredentials;
|
||||
try {
|
||||
@@ -330,7 +330,7 @@ public class GithubUtil {
|
||||
@Override
|
||||
public RepositoryInfo compute() {
|
||||
ProgressManager.getInstance().getProgressIndicator().setText("Extracting detailed info about repository ''" + name + "''");
|
||||
return getDetailedRepoInfo(settings.getHost(), settings.getLogin(), settings.getPassword(), name);
|
||||
return getDetailedRepoInfo(settings.getHost(), settings.getLogin(), settings.getPassword(), owner, name);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -30,6 +30,10 @@ public class RepositoryInfo {
|
||||
return myRepository.getChildText("parent");
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return getOwner() + "/" + getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (!(obj instanceof RepositoryInfo)){
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright 2000-2011 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jetbrains.plugins.github;
|
||||
|
||||
/**
|
||||
* @author oleg
|
||||
*/
|
||||
public class UnknownRepositoryInfo extends RepositoryInfo {
|
||||
private final String myId;
|
||||
private final String myName;
|
||||
private final String myOwner;
|
||||
|
||||
public UnknownRepositoryInfo(final String id) {
|
||||
super(null);
|
||||
myId = id;
|
||||
myName = myId.substring(myId.lastIndexOf('/') + 1);
|
||||
myOwner = myId.substring(0, myId.lastIndexOf('/'));
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return myName;
|
||||
}
|
||||
|
||||
public String getOwner() {
|
||||
return myOwner;
|
||||
}
|
||||
|
||||
public boolean isFork() {
|
||||
throw new UnsupportedOperationException("UnknownRepositoryInfo#isFork() shouldn't be called");
|
||||
}
|
||||
|
||||
public String getParent() {
|
||||
throw new UnsupportedOperationException("UnknownRepositoryInfo#isFork() shouldn't be called");
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return myId;
|
||||
}
|
||||
}
|
||||
@@ -4,9 +4,14 @@ import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.ui.DialogWrapper;
|
||||
import com.intellij.openapi.vfs.LocalFileSystem;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.util.containers.HashMap;
|
||||
import org.intellij.lang.annotations.Pattern;
|
||||
import org.jetbrains.plugins.github.RepositoryInfo;
|
||||
import org.jetbrains.plugins.github.UnknownRepositoryInfo;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@@ -14,14 +19,21 @@ import java.util.List;
|
||||
*/
|
||||
public class GithubCloneProjectDialog extends DialogWrapper {
|
||||
|
||||
private static final java.util.regex.Pattern PATTERN = java.util.regex.Pattern.compile("[\\w\\d-_]+/[\\w\\d-_]+");
|
||||
private GithubCloneProjectPane myGithubCloneProjectPane;
|
||||
private HashMap<String, RepositoryInfo> myRepositoryInfoHashMap;
|
||||
|
||||
public GithubCloneProjectDialog(final Project project, final List<RepositoryInfo> repos) {
|
||||
super(project, true);
|
||||
myGithubCloneProjectPane = new GithubCloneProjectPane(this);
|
||||
setTitle("Select repository to clone");
|
||||
setOKButtonText("Clone");
|
||||
myGithubCloneProjectPane.setAvailableRepos(repos);
|
||||
myRepositoryInfoHashMap = new HashMap<String, RepositoryInfo>();
|
||||
for (RepositoryInfo repo : repos) {
|
||||
myRepositoryInfoHashMap.put(repo.getId(), repo);
|
||||
}
|
||||
final ArrayList<String> ids = new ArrayList<String>(myRepositoryInfoHashMap.keySet());
|
||||
myGithubCloneProjectPane.setAvailableRepos(ids);
|
||||
init();
|
||||
setOKActionEnabled(false);
|
||||
}
|
||||
@@ -46,8 +58,9 @@ public class GithubCloneProjectDialog extends DialogWrapper {
|
||||
}
|
||||
|
||||
public void updateOkButton() {
|
||||
if (getSelectedRepository() == null){
|
||||
setErrorText("No repository selected");
|
||||
final String selectedRepositoryId = getSelectedRepositoryId();
|
||||
if (!PATTERN.matcher(selectedRepositoryId).matches()){
|
||||
setErrorText("Wrong repository format. owner/repository expected");
|
||||
setOKActionEnabled(false);
|
||||
return;
|
||||
}
|
||||
@@ -79,6 +92,11 @@ public class GithubCloneProjectDialog extends DialogWrapper {
|
||||
}
|
||||
|
||||
public RepositoryInfo getSelectedRepository() {
|
||||
final String id = getSelectedRepositoryId();
|
||||
return myRepositoryInfoHashMap.containsKey(id) ? myRepositoryInfoHashMap.get(id) : new UnknownRepositoryInfo(id);
|
||||
}
|
||||
|
||||
private String getSelectedRepositoryId() {
|
||||
return myGithubCloneProjectPane.getSelectedRepository();
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<grid id="27dc6" binding="myPanel" layout-manager="GridLayoutManager" row-count="4" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
||||
<margin top="0" left="0" bottom="0" right="0"/>
|
||||
<constraints>
|
||||
<xy x="20" y="20" width="402" height="112"/>
|
||||
<xy x="20" y="20" width="402" height="137"/>
|
||||
</constraints>
|
||||
<properties/>
|
||||
<border type="none"/>
|
||||
@@ -32,12 +32,6 @@
|
||||
<text value="Directory &Name:"/>
|
||||
</properties>
|
||||
</component>
|
||||
<component id="7ac75" class="javax.swing.JComboBox" binding="mySelectRepositoryComboBox">
|
||||
<constraints>
|
||||
<grid row="0" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="2" anchor="8" fill="1" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties/>
|
||||
</component>
|
||||
<component id="f9011" class="com.intellij.openapi.ui.TextFieldWithBrowseButton" binding="myTextFieldWithBrowseButton" custom-create="true">
|
||||
<constraints>
|
||||
<grid row="1" column="1" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
|
||||
@@ -60,6 +54,12 @@
|
||||
<grid row="3" column="0" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
</vspacer>
|
||||
<component id="21a0c" class="com.intellij.openapi.ui.ComboBox" binding="myRepositoryComboBox">
|
||||
<constraints>
|
||||
<grid row="0" column="1" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties/>
|
||||
</component>
|
||||
</children>
|
||||
</grid>
|
||||
</form>
|
||||
|
||||
@@ -1,11 +1,20 @@
|
||||
package org.jetbrains.plugins.github.ui;
|
||||
|
||||
import com.intellij.ide.ui.ListCellRendererWrapper;
|
||||
import com.intellij.openapi.editor.event.DocumentAdapter;
|
||||
import com.intellij.openapi.fileChooser.FileChooser;
|
||||
import com.intellij.openapi.fileChooser.FileChooserDescriptor;
|
||||
import com.intellij.openapi.fileTypes.FileType;
|
||||
import com.intellij.openapi.fileTypes.FileTypes;
|
||||
import com.intellij.openapi.project.ProjectManager;
|
||||
import com.intellij.openapi.ui.ComboBox;
|
||||
import com.intellij.openapi.ui.TextFieldWithBrowseButton;
|
||||
import com.intellij.openapi.vfs.LocalFileSystem;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.ui.EditorComboBoxEditor;
|
||||
import com.intellij.ui.EditorComboBoxRenderer;
|
||||
import com.intellij.ui.EditorTextField;
|
||||
import com.intellij.ui.StringComboboxEditor;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import com.intellij.util.Consumer;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -26,31 +35,31 @@ import java.util.List;
|
||||
*/
|
||||
public class GithubCloneProjectPane {
|
||||
private JPanel myPanel;
|
||||
private JComboBox mySelectRepositoryComboBox;
|
||||
private TextFieldWithBrowseButton myTextFieldWithBrowseButton;
|
||||
private JTextField myProjectNameText;
|
||||
private ComboBox myRepositoryComboBox;
|
||||
private final GithubCloneProjectDialog myDialog;
|
||||
|
||||
public GithubCloneProjectPane(final GithubCloneProjectDialog dialog) {
|
||||
myDialog = dialog;
|
||||
mySelectRepositoryComboBox.setRenderer(new ListCellRendererWrapper<RepositoryInfo>(mySelectRepositoryComboBox.getRenderer()){
|
||||
@Override
|
||||
public void customize(final JList list, final RepositoryInfo value, final int index, final boolean selected, final boolean cellHasFocus) {
|
||||
setText(value.getOwner() + "/" + value.getName());
|
||||
}
|
||||
});
|
||||
mySelectRepositoryComboBox.addItemListener(new ItemListener() {
|
||||
@Override
|
||||
public void itemStateChanged(final ItemEvent e) {
|
||||
final RepositoryInfo repositoryInfo = (RepositoryInfo)e.getItem();
|
||||
if (repositoryInfo != null) {
|
||||
myProjectNameText.setText(repositoryInfo.getName());
|
||||
myDialog.updateOkButton();
|
||||
final EditorComboBoxEditor comboEditor = new StringComboboxEditor(ProjectManager.getInstance().getDefaultProject(), FileTypes.PLAIN_TEXT, myRepositoryComboBox);
|
||||
myRepositoryComboBox.setEditor(comboEditor);
|
||||
((EditorTextField) comboEditor.getEditorComponent()).addDocumentListener(
|
||||
new DocumentAdapter() {
|
||||
@Override
|
||||
public void beforeDocumentChange(final com.intellij.openapi.editor.event.DocumentEvent e) {
|
||||
updateControls();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
final DocumentListener updateOkButtonListener = new DocumentListener() {
|
||||
@Override
|
||||
public void documentChanged(final com.intellij.openapi.editor.event.DocumentEvent e) {
|
||||
updateControls();
|
||||
}
|
||||
});
|
||||
myRepositoryComboBox.setRenderer(new EditorComboBoxRenderer(comboEditor));
|
||||
myRepositoryComboBox.setEditable(true);
|
||||
|
||||
myProjectNameText.getDocument().addDocumentListener(new DocumentListener() {
|
||||
// update Ok button state depending on the current state of the fields
|
||||
public void insertUpdate(final DocumentEvent e) {
|
||||
myDialog.updateOkButton();
|
||||
@@ -63,9 +72,21 @@ public class GithubCloneProjectPane {
|
||||
public void changedUpdate(final DocumentEvent e) {
|
||||
myDialog.updateOkButton();
|
||||
}
|
||||
};
|
||||
myProjectNameText.getDocument().addDocumentListener(updateOkButtonListener);
|
||||
myTextFieldWithBrowseButton.getChildComponent().getDocument().addDocumentListener(updateOkButtonListener);
|
||||
});
|
||||
myTextFieldWithBrowseButton.getChildComponent().getDocument().addDocumentListener(new DocumentListener() {
|
||||
// update Ok button state depending on the current state of the fields
|
||||
public void insertUpdate(final DocumentEvent e) {
|
||||
myDialog.updateOkButton();
|
||||
}
|
||||
|
||||
public void removeUpdate(final DocumentEvent e) {
|
||||
myDialog.updateOkButton();
|
||||
}
|
||||
|
||||
public void changedUpdate(final DocumentEvent e) {
|
||||
myDialog.updateOkButton();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public JComponent getPanel() {
|
||||
@@ -73,11 +94,11 @@ public class GithubCloneProjectPane {
|
||||
}
|
||||
|
||||
public JComponent getPreferrableFocusComponent() {
|
||||
return mySelectRepositoryComboBox;
|
||||
return myRepositoryComboBox;
|
||||
}
|
||||
|
||||
public RepositoryInfo getSelectedRepository(){
|
||||
return (RepositoryInfo) mySelectRepositoryComboBox.getModel().getSelectedItem();
|
||||
public String getSelectedRepository(){
|
||||
return (String) myRepositoryComboBox.getEditor().getItem();
|
||||
}
|
||||
|
||||
public String getSelectedPath(){
|
||||
@@ -120,12 +141,18 @@ public class GithubCloneProjectPane {
|
||||
});
|
||||
}
|
||||
|
||||
public void setAvailableRepos(final List<RepositoryInfo> repos) {
|
||||
mySelectRepositoryComboBox.setModel(new DefaultComboBoxModel(ArrayUtil.toObjectArray(repos)));
|
||||
final RepositoryInfo preselectedRepository = (RepositoryInfo)mySelectRepositoryComboBox.getSelectedItem();
|
||||
public void setAvailableRepos(final List<String> repos) {
|
||||
myRepositoryComboBox.setModel(new DefaultComboBoxModel(ArrayUtil.toObjectArray(repos)));
|
||||
updateControls();
|
||||
}
|
||||
|
||||
private void updateControls() {
|
||||
final String preselectedRepository = (String)myRepositoryComboBox.getEditor().getItem();
|
||||
if (preselectedRepository != null) {
|
||||
myProjectNameText.setText(preselectedRepository.getName());
|
||||
final int i = preselectedRepository.lastIndexOf('/');
|
||||
myProjectNameText.setText(i != -1 ? preselectedRepository.substring(i + 1) : "");
|
||||
}
|
||||
myDialog.updateOkButton();
|
||||
}
|
||||
|
||||
public void setSelectedPath(final String path) {
|
||||
|
||||
@@ -111,6 +111,7 @@
|
||||
<paletteItemProvider implementation="com.intellij.uiDesigner.palette.UIDesignerPaletteProvider"/>
|
||||
|
||||
<lang.foldingBuilder language="JAVA" implementationClass="com.intellij.uiDesigner.binding.GeneratedCodeFoldingBuilder"/>
|
||||
<gotoRelatedProvider implementation="com.intellij.uiDesigner.binding.FormRelatedFilesProvider"/>
|
||||
</extensions>
|
||||
|
||||
<project-components>
|
||||
|
||||
@@ -23,7 +23,8 @@ import org.jetbrains.annotations.NotNull;
|
||||
* @author yole
|
||||
*/
|
||||
public class FormFileTypeFactory extends FileTypeFactory {
|
||||
|
||||
public void createFileTypes(@NotNull FileTypeConsumer consumer) {
|
||||
consumer.consume(new GuiFormFileType(), GuiFormFileType.DEFAULT_EXTENSION);
|
||||
consumer.consume(GuiFormFileType.INSTANCE);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,6 +26,9 @@ import org.jetbrains.annotations.NotNull;
|
||||
import javax.swing.*;
|
||||
|
||||
public class GuiFormFileType implements FileType {
|
||||
|
||||
public static final GuiFormFileType INSTANCE = new GuiFormFileType();
|
||||
|
||||
@NonNls public static final String DEFAULT_EXTENSION = "form";
|
||||
@NonNls public static final String DOT_DEFAULT_EXTENSION = "." + DEFAULT_EXTENSION;
|
||||
|
||||
|
||||
@@ -122,7 +122,7 @@ public class FormClassIndex extends ScalarIndexExtension<String> {
|
||||
});
|
||||
}
|
||||
|
||||
public static List<PsiFile> findFormsBoundToClass(PsiClass psiClass) {
|
||||
public static List<PsiFile> findFormsBoundToClass(@NotNull PsiClass psiClass) {
|
||||
String qName = FormReferencesSearcher.getQualifiedName(psiClass);
|
||||
if (qName == null) return Collections.emptyList();
|
||||
return findFormsBoundToClass(psiClass.getProject(), qName);
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* Copyright 2000-2011 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.uiDesigner.binding;
|
||||
|
||||
import com.intellij.navigation.GotoRelatedItem;
|
||||
import com.intellij.navigation.GotoRelatedProvider;
|
||||
import com.intellij.navigation.PsiGotoRelatedItem;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.JavaPsiFacade;
|
||||
import com.intellij.psi.PsiClass;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.uiDesigner.GuiFormFileType;
|
||||
import com.intellij.uiDesigner.compiler.Utils;
|
||||
import com.intellij.util.Function;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Dmitry Avdeev
|
||||
*/
|
||||
public class FormRelatedFilesProvider extends GotoRelatedProvider {
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public List<GotoRelatedItem> getItems(PsiElement context) {
|
||||
PsiClass psiClass = PsiTreeUtil.getParentOfType(context, PsiClass.class, false);
|
||||
if (psiClass != null) {
|
||||
List<PsiFile> forms = FormClassIndex.findFormsBoundToClass(psiClass);
|
||||
return ContainerUtil.map(forms, new Function<PsiFile, GotoRelatedItem>() {
|
||||
@Override
|
||||
public GotoRelatedItem fun(PsiFile psiFile) {
|
||||
return new PsiGotoRelatedItem(psiFile);
|
||||
}
|
||||
});
|
||||
}
|
||||
else {
|
||||
PsiFile file = context.getContainingFile();
|
||||
if (file.getFileType() == GuiFormFileType.INSTANCE) {
|
||||
try {
|
||||
String className = Utils.getBoundClassName(file.getText());
|
||||
if (className != null) {
|
||||
Project project = file.getProject();
|
||||
PsiClass aClass = JavaPsiFacade.getInstance(project).findClass(className, GlobalSearchScope.allScope(project));
|
||||
if (aClass != null) {
|
||||
return Collections.<GotoRelatedItem>singletonList(new PsiGotoRelatedItem(aClass));
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ignore) {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright 2000-2011 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.codeInsight.navigation;
|
||||
|
||||
import com.intellij.navigation.GotoRelatedItem;
|
||||
import com.intellij.psi.DelegatePsiTarget;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.util.xml.DomElement;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.swing.*;
|
||||
|
||||
/**
|
||||
* @author Dmitry Avdeev
|
||||
*/
|
||||
public class DomGotoRelatedItem extends GotoRelatedItem {
|
||||
|
||||
private final DomElement myElement;
|
||||
|
||||
public DomGotoRelatedItem(DomElement element) {
|
||||
|
||||
myElement = element;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void navigate() {
|
||||
new DelegatePsiTarget(myElement.getXmlElement()).navigate(true);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getText() {
|
||||
return myElement.getPresentation().getElementName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Icon getIcon() {
|
||||
return myElement.getPresentation().getIcon();
|
||||
}
|
||||
|
||||
@Override
|
||||
public PsiFile getContainingFile() {
|
||||
return myElement.getXmlElement().getContainingFile();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user