@Override public void navigate(MouseEvent mouseEvent, PsiElement element) { PsiElement parent = element.getParent(); if (!(parent instanceof DotNetVirtualImplementOwner) || !OverrideUtil.isAllowForOverride(parent)) { return; } Collection<DotNetVirtualImplementOwner> members = OverrideUtil.collectOverridenMembers(((DotNetVirtualImplementOwner) parent)); if (members.isEmpty()) { return; } if (members.size() == 1) { DotNetVirtualImplementOwner firstItem = ContainerUtil.getFirstItem(members); if (firstItem instanceof Navigatable) { ((Navigatable) firstItem).navigate(true); } } else { PsiElement[] elements = members.toArray(new PsiElement[members.size()]); JBPopup popup = NavigationUtil.getPsiElementPopup( elements, new ElementGutterRender(), "Open elements (" + elements.length + " " + "items)" + ""); popup.show(new RelativePoint(mouseEvent)); } }
public boolean convertLocalToField(final PsiLocalVariable local, final Editor editor) { boolean tempIsStatic = myIsConstant; PsiElement parent = local.getParent(); List<PsiClass> classes = new ArrayList<>(); if ("gr".equalsIgnoreCase(local.getContainingFile().getVirtualFile().getExtension())) { // this is special ij GW studio check for rule files CommonRefactoringUtil.showErrorHint( myProject, editor, "Introduce field is not supported for rule files", REFACTORING_NAME, HelpID.LOCAL_TO_FIELD); return false; } while (parent != null && parent.getContainingFile() != null) { if (parent instanceof PsiClass && !(myIsConstant && parent instanceof PsiAnonymousClass)) { classes.add((PsiClass) parent); } if (parent instanceof PsiFile && JspPsiUtil.isInJspFile(parent)) { String message = RefactoringBundle.message("error.not.supported.for.jsp", REFACTORING_NAME); CommonRefactoringUtil.showErrorHint( myProject, editor, message, REFACTORING_NAME, HelpID.LOCAL_TO_FIELD); return false; } if (parent instanceof PsiModifierListOwner && ((PsiModifierListOwner) parent).hasModifierProperty(PsiModifier.STATIC)) { tempIsStatic = true; } parent = parent.getParent(); } if (classes.isEmpty()) { return false; } if (classes.size() == 1 || ApplicationManager.getApplication().isUnitTestMode()) { if (convertLocalToField( local, classes.get(getChosenClassIndex(classes)), editor, tempIsStatic)) { return false; } } else { final boolean isStatic = tempIsStatic; NavigationUtil.getPsiElementPopup( classes.toArray(new PsiClass[classes.size()]), new PsiClassListCellRenderer(), "Choose class to introduce " + (myIsConstant ? "constant" : "field"), new PsiElementProcessor<PsiClass>() { @Override public boolean execute(@NotNull PsiClass aClass) { convertLocalToField(local, aClass, editor, isStatic); return false; } }) .showInBestPositionFor(editor); } return true; }
private static void createValueResource( @NotNull PsiFile file, @NotNull AndroidFacet facet, @NotNull PsiDirectory dir, @NotNull final String resName, @NotNull final String value, @NotNull final ResourceType type, @NotNull final String oldTagText) { final String filename = file.getName(); final List<String> dirNames = Collections.singletonList(dir.getName()); final Module module = facet.getModule(); final AtomicReference<PsiElement> openAfter = new AtomicReference<PsiElement>(); final WriteCommandAction<Void> action = new WriteCommandAction<Void>( facet.getModule().getProject(), "Override Resource " + resName, file) { @Override protected void run(@NotNull Result<Void> result) { List<ResourceElement> elements = Lists.newArrayListWithExpectedSize(1); // AndroidResourceUtil.createValueResource will create a new resource value in the given // resource // folder (and record the corresponding tags added in the elements list passed into it). // However, it only creates a new element and sets the name attribute on it; it does not // transfer attributes, child content etc. Therefore, we use this utility method first // to // create the corresponding tag, and then *afterwards* we will replace the tag with a // text copy // from the resource tag we are overriding. We do this all under a single write lock // such // that it becomes a single atomic operation. AndroidResourceUtil.createValueResource( module, resName, type, filename, dirNames, value, elements); if (elements.size() == 1) { final XmlTag tag = elements.get(0).getXmlTag(); if (tag != null && tag.isValid()) { try { XmlTag tagFromText = XmlElementFactory.getInstance(tag.getProject()).createTagFromText(oldTagText); PsiElement replaced = tag.replace(tagFromText); openAfter.set(replaced); } catch (IncorrectOperationException e) { // The user tried to override an invalid XML fragment: don't attempt to do a // replacement in that case openAfter.set(tag); } } } } }; action.execute(); PsiElement tag = openAfter.get(); if (tag != null) { NavigationUtil.openFileWithPsiElement(tag, true, true); } }
// returns true if processor is run or is going to be run after showing popup public static boolean chooseAmbiguousTarget( @NotNull Editor editor, int offset, @NotNull PsiElementProcessor<PsiElement> processor, @NotNull String titlePattern, @Nullable PsiElement[] elements) { if (TargetElementUtil.inVirtualSpace(editor, offset)) { return false; } final PsiReference reference = TargetElementUtil.findReference(editor, offset); if (elements == null || elements.length == 0) { elements = reference == null ? PsiElement.EMPTY_ARRAY : PsiUtilCore.toPsiElementArray( underModalProgress( reference.getElement().getProject(), "Resolving Reference...", () -> suggestCandidates(reference))); } if (elements.length == 1) { PsiElement element = elements[0]; LOG.assertTrue(element != null); processor.execute(element); return true; } if (elements.length > 1) { String title; if (reference == null) { title = titlePattern; } else { final TextRange range = reference.getRangeInElement(); final String elementText = reference.getElement().getText(); LOG.assertTrue( range.getStartOffset() >= 0 && range.getEndOffset() <= elementText.length(), Arrays.toString(elements) + ";" + reference); final String refText = range.substring(elementText); title = MessageFormat.format(titlePattern, refText); } NavigationUtil.getPsiElementPopup( elements, new DefaultPsiElementCellRenderer(), title, processor) .showInBestPositionFor(editor); return true; } return false; }
public boolean convertLocalToField(final PsiLocalVariable local, final Editor editor) { boolean tempIsStatic = myIsConstant; PsiElement parent = local.getParent(); List<PsiClass> classes = new ArrayList<PsiClass>(); while (parent != null && parent.getContainingFile() != null) { if (parent instanceof PsiClass && !(myIsConstant && parent instanceof PsiAnonymousClass)) { classes.add((PsiClass) parent); } if (parent instanceof PsiFile && FileTypeUtils.isInServerPageFile(parent)) { String message = RefactoringBundle.message("error.not.supported.for.jsp", REFACTORING_NAME); CommonRefactoringUtil.showErrorHint( myProject, editor, message, REFACTORING_NAME, HelpID.LOCAL_TO_FIELD); return false; } if (parent instanceof PsiModifierListOwner && ((PsiModifierListOwner) parent).hasModifierProperty(PsiModifier.STATIC)) { tempIsStatic = true; } parent = parent.getParent(); } if (classes.isEmpty()) return false; final AbstractInplaceIntroducer activeIntroducer = AbstractInplaceIntroducer.getActiveIntroducer(editor); final boolean shouldSuggestDialog = activeIntroducer instanceof InplaceIntroduceConstantPopup && activeIntroducer.startsOnTheSameElement(null, local); if (classes.size() == 1 || ApplicationManager.getApplication().isUnitTestMode() || shouldSuggestDialog) { if (convertLocalToField( local, classes.get(getChosenClassIndex(classes)), editor, tempIsStatic)) return false; } else { final boolean isStatic = tempIsStatic; NavigationUtil.getPsiElementPopup( classes.toArray(new PsiClass[classes.size()]), new PsiClassListCellRenderer(), "Choose class to introduce " + (myIsConstant ? "constant" : "field"), new PsiElementProcessor<PsiClass>() { @Override public boolean execute(@NotNull PsiClass aClass) { convertLocalToField(local, aClass, editor, isStatic); return false; } }) .showInBestPositionFor(editor); } return true; }
public void invoke(@NotNull final Project project, final Editor editor, final PsiFile file) { final Collection<JSQualifiedNamedElement> candidates = getCandidates(editor, file); if (candidates.isEmpty() || myUnambiguousTheFlyMode && candidates.size() != 1) { return; } if (candidates.size() > 1) { NavigationUtil.getPsiElementPopup( candidates.toArray(new JSQualifiedNamedElement[candidates.size()]), new JSQualifiedNamedElementRenderer(), JSBundle.message("choose.class.to.import.title"), new PsiElementProcessor<JSQualifiedNamedElement>() { public boolean execute(@NotNull final JSQualifiedNamedElement element) { CommandProcessor.getInstance() .executeCommand( project, () -> doImport(element.getQualifiedName()), "Import " + element.getQualifiedName(), this); return false; } }) .showInBestPositionFor(editor); } else { final JSQualifiedNamedElement element = candidates.iterator().next(); if (myUnambiguousTheFlyMode) { CommandProcessor.getInstance() .runUndoTransparentAction(() -> doImport(element.getQualifiedName())); } else { CommandProcessor.getInstance() .executeCommand( project, () -> doImport(element.getQualifiedName()), "Import " + element.getQualifiedName(), this); } } }