Merge branch 'master' of git@git.labs.intellij.net:idea/community

This commit is contained in:
Kirill Kalishev
2011-03-29 15:30:17 +04:00
48 changed files with 1064 additions and 331 deletions
@@ -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;
}
@@ -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);
@@ -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")));
@@ -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);
}
}
};
@@ -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));
}
}
@@ -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);
}
@@ -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;
}
}
}
@@ -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);
}
@@ -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");
}
@@ -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);
@@ -60,7 +60,7 @@
</constraints>
<properties>
<selected value="true"/>
<text value="Create &quot;&amp;Hello, World!&quot; project"/>
<text value="Create &quot;&amp;Hello, World!&quot; 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&amp;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 &amp;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();
}
}