private static void gotoTargetElement( @NotNull PsiElement element, @NotNull Editor currentEditor, @NotNull PsiFile currentFile) { if (navigateInCurrentEditor(element, currentFile, currentEditor)) return; Navigatable navigatable = element instanceof Navigatable ? (Navigatable) element : EditSourceUtil.getDescriptor(element); if (navigatable != null && navigatable.canNavigate()) { navigatable.navigate(true); } }
@Nullable private Info getInfoAt(@NotNull Editor editor, PsiFile file, int offset, BrowseMode browseMode) { PsiElement targetElement = null; if (browseMode == BrowseMode.TypeDeclaration) { try { targetElement = GotoTypeDeclarationAction.findSymbolType(editor, offset); } catch (IndexNotReadyException e) { showDumbModeNotification(myProject); } } else if (browseMode == BrowseMode.Declaration) { final PsiReference ref = TargetElementUtilBase.findReference(editor, offset); final List<PsiElement> resolvedElements = ref != null ? resolve(ref) : Collections.<PsiElement>emptyList(); final PsiElement resolvedElement = resolvedElements.size() == 1 ? resolvedElements.get(0) : null; final PsiElement[] targetElements = GotoDeclarationAction.findTargetElementsNoVS(myProject, editor, offset, false); final PsiElement elementAtPointer = file.findElementAt( TargetElementUtilBase.adjustOffset(file, editor.getDocument(), offset)); if (targetElements != null) { if (targetElements.length == 0) { return null; } else if (targetElements.length == 1) { if (targetElements[0] != resolvedElement && elementAtPointer != null && targetElements[0].isPhysical()) { return ref != null ? new InfoSingle(ref, targetElements[0]) : new InfoSingle(elementAtPointer, targetElements[0]); } } else { return elementAtPointer != null ? new InfoMultiple(elementAtPointer) : null; } } if (resolvedElements.size() == 1) { return new InfoSingle(ref, resolvedElements.get(0)); } else if (resolvedElements.size() > 1) { return elementAtPointer != null ? new InfoMultiple(elementAtPointer, ref) : null; } } else if (browseMode == BrowseMode.Implementation) { final PsiElement element = TargetElementUtilBase.getInstance() .findTargetElement(editor, ImplementationSearcher.getFlags(), offset); PsiElement[] targetElements = new ImplementationSearcher() { @Override @NotNull protected PsiElement[] searchDefinitions(final PsiElement element, Editor editor) { final List<PsiElement> found = new ArrayList<PsiElement>(2); DefinitionsScopedSearch.search(element, getSearchScope(element, editor)) .forEach( new Processor<PsiElement>() { @Override public boolean process(final PsiElement psiElement) { found.add(psiElement); return found.size() != 2; } }); return PsiUtilCore.toPsiElementArray(found); } }.searchImplementations(editor, element, offset); if (targetElements.length > 1) { PsiElement elementAtPointer = file.findElementAt(offset); if (elementAtPointer != null) { return new InfoMultiple(elementAtPointer); } return null; } if (targetElements.length == 1) { Navigatable descriptor = EditSourceUtil.getDescriptor(targetElements[0]); if (descriptor == null || !descriptor.canNavigate()) { return null; } targetElement = targetElements[0]; } } if (targetElement != null && targetElement.isPhysical()) { PsiElement elementAtPointer = file.findElementAt(offset); if (elementAtPointer != null) { return new InfoSingle(elementAtPointer, targetElement); } } return null; }
private void show( @NotNull final Project project, @NotNull Editor editor, @NotNull PsiFile file, @NotNull final GotoData gotoData) { final PsiElement[] targets = gotoData.targets; final List<AdditionalAction> additionalActions = gotoData.additionalActions; if (targets.length == 0 && additionalActions.isEmpty()) { HintManager.getInstance().showErrorHint(editor, getNotFoundMessage(project, editor, file)); return; } if (targets.length == 1 && additionalActions.isEmpty()) { Navigatable descriptor = targets[0] instanceof Navigatable ? (Navigatable) targets[0] : EditSourceUtil.getDescriptor(targets[0]); if (descriptor != null && descriptor.canNavigate()) { navigateToElement(descriptor); } return; } for (PsiElement eachTarget : targets) { gotoData.renderers.put(eachTarget, createRenderer(gotoData, eachTarget)); } final String name = ((PsiNamedElement) gotoData.source).getName(); boolean finished = gotoData.listUpdaterTask == null || gotoData.listUpdaterTask.isFinished(); final String title = getChooserTitle(gotoData.source, name, targets.length, finished); if (shouldSortTargets()) { Arrays.sort(targets, createComparator(gotoData.renderers, gotoData)); } List<Object> allElements = new ArrayList<Object>(targets.length + additionalActions.size()); Collections.addAll(allElements, targets); allElements.addAll(additionalActions); final JBListWithHintProvider list = new JBListWithHintProvider(new CollectionListModel<Object>(allElements)) { @Override protected PsiElement getPsiElementForHint(final Object selectedValue) { return selectedValue instanceof PsiElement ? (PsiElement) selectedValue : null; } }; list.setFont(EditorUtil.getEditorFont()); list.setCellRenderer( new DefaultListCellRenderer() { @Override public Component getListCellRendererComponent( JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { if (value == null) return super.getListCellRendererComponent( list, value, index, isSelected, cellHasFocus); if (value instanceof AdditionalAction) { return myActionElementRenderer.getListCellRendererComponent( list, value, index, isSelected, cellHasFocus); } PsiElementListCellRenderer renderer = getRenderer(value, gotoData.renderers, gotoData); return renderer.getListCellRendererComponent( list, value, index, isSelected, cellHasFocus); } }); final Runnable runnable = () -> { int[] ids = list.getSelectedIndices(); if (ids == null || ids.length == 0) return; Object[] selectedElements = list.getSelectedValues(); for (Object element : selectedElements) { if (element instanceof AdditionalAction) { ((AdditionalAction) element).execute(); } else { Navigatable nav = element instanceof Navigatable ? (Navigatable) element : EditSourceUtil.getDescriptor((PsiElement) element); try { if (nav != null && nav.canNavigate()) { navigateToElement(nav); } } catch (IndexNotReadyException e) { DumbService.getInstance(project) .showDumbModeNotification("Navigation is not available while indexing"); } } } }; final PopupChooserBuilder builder = new PopupChooserBuilder(list); builder.setFilteringEnabled( o -> { if (o instanceof AdditionalAction) { return ((AdditionalAction) o).getText(); } return getRenderer(o, gotoData.renderers, gotoData).getElementText((PsiElement) o); }); final Ref<UsageView> usageView = new Ref<UsageView>(); final JBPopup popup = builder .setTitle(title) .setItemChoosenCallback(runnable) .setMovable(true) .setCancelCallback( () -> { HintUpdateSupply.hideHint(list); final ListBackgroundUpdaterTask task = gotoData.listUpdaterTask; if (task != null) { task.cancelTask(); } return true; }) .setCouldPin( popup1 -> { usageView.set( FindUtil.showInUsageView( gotoData.source, gotoData.targets, getFindUsagesTitle(gotoData.source, name, gotoData.targets.length), project)); popup1.cancel(); return false; }) .setAdText(getAdText(gotoData.source, targets.length)) .createPopup(); builder.getScrollPane().setBorder(null); builder.getScrollPane().setViewportBorder(null); if (gotoData.listUpdaterTask != null) { gotoData.listUpdaterTask.init((AbstractPopup) popup, list, usageView); ProgressManager.getInstance().run(gotoData.listUpdaterTask); } popup.showInBestPositionFor(editor); }
private void show(Project project, Editor editor, PsiFile file, final GotoData gotoData) { final PsiElement[] targets = gotoData.targets; final List<AdditionalAction> additionalActions = gotoData.additionalActions; if (targets.length == 0 && additionalActions.isEmpty()) { HintManager.getInstance().showErrorHint(editor, getNotFoundMessage(project, editor, file)); return; } if (targets.length == 1 && additionalActions.isEmpty()) { Navigatable descriptor = targets[0] instanceof Navigatable ? (Navigatable) targets[0] : EditSourceUtil.getDescriptor(targets[0]); if (descriptor != null && descriptor.canNavigate()) { navigateToElement(descriptor); } return; } for (PsiElement eachTarget : targets) { gotoData.renderers.put(eachTarget, createRenderer(gotoData, eachTarget)); } String name = ((PsiNamedElement) gotoData.source).getName(); String title = getChooserTitle(gotoData.source, name, targets.length); if (shouldSortTargets()) { Arrays.sort(targets, createComparator(gotoData.renderers, gotoData)); } List<Object> allElements = new ArrayList<Object>(targets.length + additionalActions.size()); Collections.addAll(allElements, targets); allElements.addAll(additionalActions); final JBListWithHintProvider list = new JBListWithHintProvider(new CollectionListModel<Object>(allElements)) { @Override protected PsiElement getPsiElementForHint(final Object selectedValue) { return selectedValue instanceof PsiElement ? (PsiElement) selectedValue : null; } }; list.setCellRenderer( new DefaultListCellRenderer() { @Override public Component getListCellRendererComponent( JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { if (value == null) return super.getListCellRendererComponent( list, value, index, isSelected, cellHasFocus); if (value instanceof AdditionalAction) { return myActionElementRenderer.getListCellRendererComponent( list, value, index, isSelected, cellHasFocus); } PsiElementListCellRenderer renderer = getRenderer(value, gotoData.renderers, gotoData); return renderer.getListCellRendererComponent( list, value, index, isSelected, cellHasFocus); } }); final Runnable runnable = new Runnable() { @Override public void run() { int[] ids = list.getSelectedIndices(); if (ids == null || ids.length == 0) return; Object[] selectedElements = list.getSelectedValues(); for (Object element : selectedElements) { if (element instanceof AdditionalAction) { ((AdditionalAction) element).execute(); } else { Navigatable nav = element instanceof Navigatable ? (Navigatable) element : EditSourceUtil.getDescriptor((PsiElement) element); if (nav != null && nav.canNavigate()) { navigateToElement(nav); } } } } }; final PopupChooserBuilder builder = new PopupChooserBuilder(list); builder.setFilteringEnabled( new Function<Object, String>() { @Override public String fun(Object o) { if (o instanceof AdditionalAction) { return ((AdditionalAction) o).getText(); } return getRenderer(o, gotoData.renderers, gotoData).getElementText((PsiElement) o); } }); final JBPopup popup = builder .setTitle(title) .setItemChoosenCallback(runnable) .setMovable(true) .setCancelCallback( new Computable<Boolean>() { @Override public Boolean compute() { list.hideHint(); return true; } }) .setAdText(getAdText(gotoData.source, targets.length)) .createPopup(); if (gotoData.listUpdaterTask != null) { gotoData.listUpdaterTask.init((AbstractPopup) popup, list); ProgressManager.getInstance().run(gotoData.listUpdaterTask); } popup.showInBestPositionFor(editor); }