mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
javafx: navigation from controller fields to corresponding components (IDEA-100145)
This commit is contained in:
@@ -18,5 +18,6 @@
|
||||
<codeInsight.unresolvedReferenceQuickFixProvider implementation="org.jetbrains.plugins.javaFX.fxml.refs.JavaFxTagNameReference$JavaFxUnresolvedTagRefsProvider"/>
|
||||
<multiHostInjector implementation="org.jetbrains.plugins.javaFX.fxml.ScriptLanguageInjector"/>
|
||||
<annotator language="XML" implementationClass="org.jetbrains.plugins.javaFX.fxml.refs.JavaFxAnnotator"/>
|
||||
<codeInsight.lineMarkerProvider language="JAVA" implementationClass="org.jetbrains.plugins.javaFX.fxml.codeInsight.JavaFxRelatedItemLineMarkerProvider"/>
|
||||
</extensions>
|
||||
</idea-plugin>
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
package org.jetbrains.plugins.javaFX.fxml;
|
||||
|
||||
import com.intellij.codeInsight.AnnotationUtil;
|
||||
import com.intellij.lang.ASTNode;
|
||||
import com.intellij.lang.xml.XMLLanguage;
|
||||
import com.intellij.openapi.project.Project;
|
||||
@@ -246,4 +247,9 @@ public class JavaFxPsiUtil {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static boolean isVisibleInFxml(PsiMember psiMember) {
|
||||
return psiMember.hasModifierProperty(PsiModifier.PUBLIC) ||
|
||||
AnnotationUtil.isAnnotated(psiMember, JavaFxCommonClassNames.JAVAFX_FXML_ANNOTATION, false);
|
||||
}
|
||||
}
|
||||
|
||||
+108
@@ -0,0 +1,108 @@
|
||||
/*
|
||||
* Copyright 2000-2013 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.javaFX.fxml.codeInsight;
|
||||
|
||||
import com.intellij.codeHighlighting.Pass;
|
||||
import com.intellij.codeInsight.daemon.GutterIconNavigationHandler;
|
||||
import com.intellij.codeInsight.daemon.RelatedItemLineMarkerInfo;
|
||||
import com.intellij.codeInsight.daemon.RelatedItemLineMarkerProvider;
|
||||
import com.intellij.codeInsight.navigation.NavigationUtil;
|
||||
import com.intellij.icons.AllIcons;
|
||||
import com.intellij.navigation.GotoRelatedItem;
|
||||
import com.intellij.openapi.editor.markup.GutterIconRenderer;
|
||||
import com.intellij.openapi.ui.popup.JBPopup;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.search.searches.ReferencesSearch;
|
||||
import com.intellij.psi.xml.XmlAttribute;
|
||||
import com.intellij.psi.xml.XmlAttributeValue;
|
||||
import com.intellij.ui.awt.RelativePoint;
|
||||
import com.intellij.util.CommonProcessors;
|
||||
import com.intellij.util.ConstantFunction;
|
||||
import com.intellij.util.Function;
|
||||
import com.intellij.util.Processor;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.plugins.javaFX.fxml.JavaFxFileTypeFactory;
|
||||
import org.jetbrains.plugins.javaFX.fxml.JavaFxPsiUtil;
|
||||
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* User: anna
|
||||
*/
|
||||
public class JavaFxRelatedItemLineMarkerProvider extends RelatedItemLineMarkerProvider {
|
||||
@Override
|
||||
protected void collectNavigationMarkers(@NotNull PsiElement element, final Collection<? super RelatedItemLineMarkerInfo> result) {
|
||||
if (element instanceof PsiField) {
|
||||
final PsiField field = (PsiField)element;
|
||||
if (JavaFxPsiUtil.isVisibleInFxml(field) && !field.hasModifierProperty(PsiModifier.STATIC)) {
|
||||
final PsiClass containingClass = field.getContainingClass();
|
||||
if (containingClass != null && containingClass.hasModifierProperty(PsiModifier.PUBLIC)) {
|
||||
final ArrayList<GotoRelatedItem> targets = new ArrayList<GotoRelatedItem>();
|
||||
collectTargets(element, targets, new Function<PsiElement, GotoRelatedItem>() {
|
||||
@Override
|
||||
public GotoRelatedItem fun(PsiElement element) {
|
||||
return new GotoRelatedItem(element);
|
||||
}
|
||||
}, true);
|
||||
if (targets.isEmpty()) return;
|
||||
|
||||
result.add(new RelatedItemLineMarkerInfo<PsiField>(field, field.getNameIdentifier().getTextRange(),
|
||||
AllIcons.FileTypes.Xml, Pass.UPDATE_OVERRIDEN_MARKERS, null,
|
||||
new JavaFXIdIconNavigationHandler(), GutterIconRenderer.Alignment.LEFT,
|
||||
targets));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static <T> void collectTargets(PsiElement element, final ArrayList<T> targets, final Function<PsiElement, T> fun, final boolean stopAtFirst) {
|
||||
ReferencesSearch.search(element).forEach(new Processor<PsiReference>() {
|
||||
@Override
|
||||
public boolean process(PsiReference reference) {
|
||||
final PsiElement referenceElement = reference.getElement();
|
||||
if (referenceElement == null) return true;
|
||||
if (!(referenceElement instanceof XmlAttributeValue)) return true;
|
||||
final XmlAttributeValue attributeValue = (XmlAttributeValue)referenceElement;
|
||||
final PsiElement parent = attributeValue.getParent();
|
||||
if (!(parent instanceof XmlAttribute)) return true;
|
||||
final PsiFile containingFile = referenceElement.getContainingFile();
|
||||
if (containingFile == null) return true;
|
||||
if (JavaFxFileTypeFactory.isFxml(containingFile)) {
|
||||
targets.add(fun.fun(parent));
|
||||
if (stopAtFirst) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static class JavaFXIdIconNavigationHandler implements GutterIconNavigationHandler<PsiField> {
|
||||
@Override
|
||||
public void navigate(MouseEvent e, PsiField field) {
|
||||
final ArrayList<PsiElement> relatedItems = new ArrayList<PsiElement>();
|
||||
collectTargets(field, relatedItems, Function.ID, false);
|
||||
if (relatedItems.size() == 1) {
|
||||
NavigationUtil.activateFileWithPsiElement(relatedItems.get(0));
|
||||
return;
|
||||
}
|
||||
final JBPopup popup = NavigationUtil
|
||||
.getPsiElementPopup(relatedItems.toArray(new PsiElement[relatedItems.size()]), "<html>Choose component with fx:id <b>" + field.getName() + "<b></html>");
|
||||
popup.show(new RelativePoint(e));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -59,8 +59,7 @@ public class JavaFxAnnotator implements Annotator {
|
||||
for (PsiReference reference : references) {
|
||||
final PsiElement resolve = reference.resolve();
|
||||
if (resolve instanceof PsiMember) {
|
||||
if (!((PsiMember)resolve).hasModifierProperty(PsiModifier.PUBLIC) &&
|
||||
!AnnotationUtil.isAnnotated((PsiMember)resolve, Collections.singleton(JavaFxCommonClassNames.JAVAFX_FXML_ANNOTATION))) {
|
||||
if (!JavaFxPsiUtil.isVisibleInFxml((PsiMember)resolve)) {
|
||||
final String symbolPresentation = "'" + SymbolPresentationUtil.getSymbolPresentableText(resolve) + "'";
|
||||
final Annotation annotation = holder.createErrorAnnotation(element,
|
||||
symbolPresentation + (resolve instanceof PsiClass ? " should be public" : " should be public or annotated with @FXML"));
|
||||
|
||||
+2
-3
@@ -15,14 +15,13 @@
|
||||
*/
|
||||
package org.jetbrains.plugins.javaFX.fxml.refs;
|
||||
|
||||
import com.intellij.codeInsight.AnnotationUtil;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.xml.XmlAttributeValue;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import com.intellij.util.ProcessingContext;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.plugins.javaFX.fxml.JavaFxCommonClassNames;
|
||||
import org.jetbrains.plugins.javaFX.fxml.JavaFxPsiUtil;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@@ -51,7 +50,7 @@ class JavaFxFieldIdReferenceProvider extends JavaFxControllerBasedReferenceProvi
|
||||
final PsiField[] fields = aClass.getFields();
|
||||
for (PsiField psiField : fields) {
|
||||
if (!psiField.hasModifierProperty(PsiModifier.STATIC)) {
|
||||
if (psiField.hasModifierProperty(PsiModifier.PUBLIC) || AnnotationUtil.isAnnotated(psiField, JavaFxCommonClassNames.JAVAFX_FXML_ANNOTATION, false)) {
|
||||
if (JavaFxPsiUtil.isVisibleInFxml(psiField)) {
|
||||
fieldsToSuggest.add(psiField);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user