IDEA-66430 "Find In Path" doesn't show up in "Recent Find Usages"

This commit is contained in:
Alexey Kudravtsev
2014-01-23 14:13:29 +04:00
parent 3c9a856960
commit a88096804f
27 changed files with 545 additions and 540 deletions
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
* Copyright 2000-2014 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.
@@ -851,7 +851,7 @@ public class InheritanceToDelegationProcessor extends BaseRefactoringProcessor {
UsageViewManager manager = UsageViewManager.getInstance(myProject);
manager.showUsages(
new UsageTarget[]{new PsiElement2UsageTargetAdapter(myClass)},
UsageInfoToUsageConverter.convert(new UsageInfoToUsageConverter.TargetElementsDescriptor(myClass), usages),
UsageInfoToUsageConverter.convert(new PsiElement[]{myClass}, usages),
presentation
);
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2013 JetBrains s.r.o.
* Copyright 2000-2014 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.
@@ -170,7 +170,7 @@ public class JavaSafeDeleteProcessor extends SafeDeleteProcessorDelegateBase {
}
return manager.showUsages(targets,
UsageInfoToUsageConverter.convert(new UsageInfoToUsageConverter.TargetElementsDescriptor(elements),
UsageInfoToUsageConverter.convert(elements,
others.toArray(new UsageInfo[others.size()])),
presentation
);
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2011 JetBrains s.r.o.
* Copyright 2000-2014 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.
@@ -17,8 +17,8 @@ package com.intellij.refactoring.typeMigration.ui;
import com.intellij.openapi.project.Project;
import com.intellij.packageDependencies.ui.UsagesPanel;
import com.intellij.psi.PsiElement;
import com.intellij.usageView.UsageInfo;
import com.intellij.usages.UsageInfoToUsageConverter;
import org.jetbrains.annotations.NotNull;
/**
@@ -39,7 +39,7 @@ public class MigrationConflictsPanel extends UsagesPanel{
}
@Override
public void showUsages(@NotNull final UsageInfoToUsageConverter.TargetElementsDescriptor descriptor, @NotNull final UsageInfo[] usageInfos) {
super.showUsages(descriptor, usageInfos);
public void showUsages(@NotNull final PsiElement[] primaryElements, @NotNull final UsageInfo[] usageInfos) {
super.showUsages(primaryElements, usageInfos);
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2013 JetBrains s.r.o.
* Copyright 2000-2014 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.
@@ -163,7 +163,7 @@ public class MigrationPanel extends JPanel implements Disposable {
final MigrationNode migrationNode = (MigrationNode)userObject;
final UsageInfo[] failedUsages = myLabeler.getFailedUsages();
if (failedUsages.length > 0) {
myConflictsPanel.showUsages(new UsageInfoToUsageConverter.TargetElementsDescriptor(new PsiElement[0]), failedUsages);
myConflictsPanel.showUsages(PsiElement.EMPTY_ARRAY, failedUsages);
}
final AbstractTreeNode rootNode = migrationNode.getParent();
if (rootNode instanceof MigrationNode) {
@@ -450,7 +450,7 @@ public class MigrationPanel extends JPanel implements Disposable {
}
if (typeElement == null) typeElement = element;
PsiDocumentManager.getInstance(element.getProject()).commitAllDocuments();
final UsagePresentation presentation = UsageInfoToUsageConverter.convert(new UsageInfoToUsageConverter.TargetElementsDescriptor(typeElement), new UsageInfo(typeElement)).getPresentation();
final UsagePresentation presentation = UsageInfoToUsageConverter.convert(new PsiElement[]{typeElement}, new UsageInfo(typeElement)).getPresentation();
boolean isPrefix = true; //skip usage position
for (TextChunk chunk : presentation.getText()) {
if (!isPrefix) append(chunk.getText(), patchAttrs(usageInfo, chunk.getSimpleAttributesIgnoreBackground()));
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2011 JetBrains s.r.o.
* Copyright 2000-2014 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.
@@ -21,7 +21,6 @@ import com.intellij.psi.PsiElement;
import com.intellij.refactoring.typeMigration.TypeMigrationLabeler;
import com.intellij.refactoring.typeMigration.usageInfo.TypeMigrationUsageInfo;
import com.intellij.usageView.UsageInfo;
import com.intellij.usages.UsageInfoToUsageConverter;
import java.awt.*;
import java.util.ArrayList;
@@ -48,8 +47,6 @@ public class MigrationUsagesPanel extends UsagesPanel {
public void showRootUsages(UsageInfo root, UsageInfo migration, final TypeMigrationLabeler labeler) {
final PsiElement rootElement = root.getElement();
if (rootElement == null) return;
final UsageInfoToUsageConverter.TargetElementsDescriptor targetElementsDescriptor =
new UsageInfoToUsageConverter.TargetElementsDescriptor(rootElement);
final Set<PsiElement> usages = labeler.getTypeUsages((TypeMigrationUsageInfo)migration, ((TypeMigrationUsageInfo)root));
if (usages != null) {
final List<UsageInfo> infos = new ArrayList<UsageInfo>(usages.size());
@@ -58,9 +55,10 @@ public class MigrationUsagesPanel extends UsagesPanel {
infos.add(new UsageInfo(usage));
}
}
showUsages(targetElementsDescriptor, infos.toArray(new UsageInfo[infos.size()]));
} else {
showUsages(targetElementsDescriptor, new UsageInfo[] {migration});
showUsages(new PsiElement[]{rootElement}, infos.toArray(new UsageInfo[infos.size()]));
}
else {
showUsages(new PsiElement[]{rootElement}, new UsageInfo[] {migration});
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2013 JetBrains s.r.o.
* Copyright 2000-2014 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.
@@ -307,7 +307,7 @@ public class FindUtil {
public static void findAllAndShow(@NotNull Project project, @NotNull Editor editor, @NotNull FindModel findModel) {
List<Usage> usages = findAll(project, editor, findModel);
if (usages == null) return;
final UsageTarget[] usageTargets = {new FindInProjectUtil.StringUsageTarget(project, findModel.getStringToFind())};
final UsageTarget[] usageTargets = {new FindInProjectUtil.StringUsageTarget(project, findModel)};
final UsageViewPresentation usageViewPresentation = FindInProjectUtil.setupViewPresentation(false, findModel);
UsageViewManager.getInstance(project).showUsages(usageTargets, usages.toArray(new Usage[usages.size()]), usageViewPresentation);
}
@@ -931,23 +931,20 @@ public class FindUtil {
final UsageTarget[] usageTargets =
sourceElement == null ? UsageTarget.EMPTY_ARRAY : new UsageTarget[]{new PsiElement2UsageTargetAdapter(sourceElement)};
final UsageInfoToUsageConverter.TargetElementsDescriptor targetElementsDescriptor =
sourceElement != null ? new UsageInfoToUsageConverter.TargetElementsDescriptor(sourceElement)
: new UsageInfoToUsageConverter.TargetElementsDescriptor(PsiElement.EMPTY_ARRAY);
final Usage[] usages = {UsageInfoToUsageConverter.convert(targetElementsDescriptor, new UsageInfo(targets[0]))};
final PsiElement[] primary = sourceElement == null ? PsiElement.EMPTY_ARRAY : new PsiElement[]{sourceElement};
final Usage[] usages = {UsageInfoToUsageConverter.convert(primary, new UsageInfo(targets[0]))};
final UsageView view =
UsageViewManager.getInstance(project).showUsages(usageTargets, usages, presentation);
ProgressManager.getInstance().run(new Task.Backgroundable(project, "Updating Usage View ...") {
@Override
public void run(@NotNull ProgressIndicator indicator) {
for (int i = 1; i < targets.length; i++) {
if (((UsageViewImpl)view).isDisposed()) break;
final PsiElement target = targets[i];
ApplicationManager.getApplication().runReadAction(new Runnable() {
@Override
public void run() {
final Usage usage = UsageInfoToUsageConverter.convert(targetElementsDescriptor, new UsageInfo(target));
final Usage usage = UsageInfoToUsageConverter.convert(primary, new UsageInfo(target));
view.appendUsage(usage);
}
});
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2013 JetBrains s.r.o.
* Copyright 2000-2014 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.
@@ -21,7 +21,6 @@ import com.intellij.codeInsight.hint.HintManager;
import com.intellij.codeInsight.navigation.actions.GotoDeclarationAction;
import com.intellij.find.FindBundle;
import com.intellij.find.FindManager;
import com.intellij.find.findUsages.PsiElement2UsageTargetAdapter;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.CommonDataKeys;
@@ -73,7 +72,7 @@ public class FindUsagesAction extends AnAction {
}
protected void startFindUsages(@NotNull PsiElement element) {
new PsiElement2UsageTargetAdapter(element).findUsages();
FindManager.getInstance(element.getProject()).findUsages(element);
}
@Override
@@ -20,6 +20,7 @@ import com.intellij.codeInsight.hint.HintManager;
import com.intellij.codeInsight.hint.HintUtil;
import com.intellij.featureStatistics.FeatureUsageTracker;
import com.intellij.find.FindManager;
import com.intellij.find.FindSettings;
import com.intellij.find.findUsages.*;
import com.intellij.find.impl.FindManagerImpl;
import com.intellij.icons.AllIcons;
@@ -47,7 +48,6 @@ import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.wm.IdeFocusManager;
import com.intellij.psi.PsiDocumentManager;
import com.intellij.psi.PsiElement;
import com.intellij.psi.SmartPsiElementPointer;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.search.ProjectScope;
import com.intellij.psi.search.PsiElementProcessor;
@@ -232,8 +232,6 @@ public class ShowUsagesAction extends AnAction implements PopupAction {
final List<Usage> usages = new ArrayList<Usage>();
final Set<UsageNode> visibleNodes = new LinkedHashSet<UsageNode>();
UsageInfoToUsageConverter.TargetElementsDescriptor descriptor =
new UsageInfoToUsageConverter.TargetElementsDescriptor(handler.getPrimaryElements(), handler.getSecondaryElements());
final MyTable table = new MyTable();
final AsyncProcessIcon processIcon = new AsyncProcessIcon("xxx");
@@ -253,7 +251,7 @@ public class ShowUsagesAction extends AnAction implements PopupAction {
SpeedSearchBase<JTable> speedSearch = new MySpeedSearch(table);
speedSearch.setComparator(new SpeedSearchComparator(false));
final JBPopup popup = createUsagePopup(usages, descriptor, visibleNodes, handler, editor, popupPosition,
final JBPopup popup = createUsagePopup(usages, visibleNodes, handler, editor, popupPosition,
maxUsages, usageView, options, table, presentation, processIcon, hadMoreSeparator);
Disposer.register(popup, usageView);
@@ -333,7 +331,7 @@ public class ShowUsagesAction extends AnAction implements PopupAction {
}
};
final ProgressIndicator indicator = FindUsagesManager.startProcessUsages(handler, descriptor, collect, options, new Runnable() {
final ProgressIndicator indicator = FindUsagesManager.startProcessUsages(handler, handler.getPrimaryElements(), handler.getSecondaryElements(), collect, options, new Runnable() {
@Override
public void run() {
ApplicationManager.getApplication().invokeLater(new Runnable() {
@@ -552,7 +550,6 @@ public class ShowUsagesAction extends AnAction implements PopupAction {
@NotNull
private JBPopup createUsagePopup(@NotNull final List<Usage> usages,
@NotNull final UsageInfoToUsageConverter.TargetElementsDescriptor descriptor,
@NotNull Set<UsageNode> visibleNodes,
@NotNull final FindUsagesHandler handler,
final Editor editor,
@@ -639,7 +636,7 @@ public class ShowUsagesAction extends AnAction implements PopupAction {
}
};
final DefaultActionGroup pinGroup = new DefaultActionGroup();
final ActiveComponent pin = createPinButton(descriptor, usageView, options, popup, pinGroup);
final ActiveComponent pin = createPinButton(handler, usageView, options, popup, pinGroup);
builder.setCommandButton(new CompositeActiveComponent(spinningProgress, settingsButton, pin));
DefaultActionGroup toolbar = new DefaultActionGroup();
@@ -672,9 +669,11 @@ public class ShowUsagesAction extends AnAction implements PopupAction {
return popup[0];
}
private ActiveComponent createPinButton(final UsageInfoToUsageConverter.TargetElementsDescriptor descriptor,
final UsageViewImpl usageView,
final FindUsagesOptions options, final JBPopup[] popup, DefaultActionGroup pinGroup) {
private ActiveComponent createPinButton(@NotNull final FindUsagesHandler handler,
@NotNull final UsageViewImpl usageView,
@NotNull final FindUsagesOptions options,
@NotNull final JBPopup[] popup,
@NotNull DefaultActionGroup pinGroup) {
final AnAction pinAction =
new AnAction("Open Find Usages Toolwindow", "Show all usages in a separate toolwindow", AllIcons.General.AutohideOff) {
{
@@ -687,12 +686,8 @@ public class ShowUsagesAction extends AnAction implements PopupAction {
hideHints();
popup[0].cancel();
FindUsagesManager findUsagesManager = ((FindManagerImpl)FindManager.getInstance(usageView.getProject())).getFindUsagesManager();
FindUsagesManager.SearchData data = new FindUsagesManager.SearchData();
data.myOptions = options;
List<SmartPsiElementPointer<PsiElement>> plist = descriptor.getAllElementPointers();
data.myElements = plist.toArray(new SmartPsiElementPointer[plist.size()]);
findUsagesManager.rerunAndRecallFromHistory(data);
findUsagesManager.findUsages(handler.getPrimaryElements(), handler.getSecondaryElements(), handler, options,
FindSettings.getInstance().isSkipResultsWithOneUsage());
}
};
pinGroup.add(pinAction);
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2013 JetBrains s.r.o.
* Copyright 2000-2014 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.
@@ -21,30 +21,21 @@ import com.intellij.find.FindModel;
import com.intellij.find.FindSettings;
import com.intellij.find.FindUtil;
import com.intellij.find.impl.FindInProjectUtil;
import com.intellij.find.impl.FindManagerImpl;
import com.intellij.find.replaceInProject.ReplaceInProjectManager;
import com.intellij.ide.DataManager;
import com.intellij.navigation.ItemPresentation;
import com.intellij.openapi.actionSystem.CommonDataKeys;
import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.fileEditor.FileEditor;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Factory;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiDirectory;
import com.intellij.psi.PsiFile;
import com.intellij.ui.content.Content;
import com.intellij.usageView.UsageInfo;
import com.intellij.usageView.UsageViewManager;
import com.intellij.usages.*;
import com.intellij.util.IncorrectOperationException;
import com.intellij.util.Processor;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
public class FindInProjectManager {
private final Project myProject;
@@ -87,151 +78,68 @@ public class FindInProjectManager {
@Override
public void run() {
findModel.setOpenInNewTabVisible(false);
final PsiDirectory psiDirectory = FindInProjectUtil.getPsiDirectory(findModel, myProject);
if (findModel.getDirectoryName() != null && psiDirectory == null){
return;
}
if (isOpenInNewTabEnabled) {
myToOpenInNewTab = toOpenInNewTab[0] = findModel.isOpenInNewTab();
}
com.intellij.usages.UsageViewManager manager = com.intellij.usages.UsageViewManager.getInstance(myProject);
if (manager == null) return;
findManager.getFindInProjectModel().copyFrom(findModel);
final FindModel findModelCopy = (FindModel)findModel.clone();
final UsageViewPresentation presentation = FindInProjectUtil.setupViewPresentation(myToOpenInNewTab, findModelCopy);
final boolean showPanelIfOnlyOneUsage = !FindSettings.getInstance().isSkipResultsWithOneUsage();
final FindUsagesProcessPresentation processPresentation = FindInProjectUtil.setupProcessPresentation(myProject, showPanelIfOnlyOneUsage, presentation);
UsageTarget usageTarget = StringUtil.isEmpty(findModel.getStringToFind()) ? createFileByTypeTarget(findModel)
: new FindInProjectUtil.StringUsageTarget(myProject, findModel.getStringToFind());
manager.searchAndShowUsages(new UsageTarget[] {usageTarget},
new Factory<UsageSearcher>() {
@Override
public UsageSearcher create() {
return new UsageSearcher() {
@Override
public void generate(@NotNull final Processor<Usage> processor) {
myIsFindInProgress = true;
try {
Processor<UsageInfo> consumer = new Processor<UsageInfo>() {
@Override
public boolean process(UsageInfo info) {
Usage usage = UsageInfo2UsageAdapter.CONVERTER.fun(info);
usage.getPresentation().getIcon(); // cache icon
return processor.process(usage);
}
};
FindInProjectUtil.findUsages(findModelCopy, psiDirectory, myProject, true, consumer, processPresentation);
}
finally {
myIsFindInProgress = false;
}
}
};
}
},
processPresentation,
presentation,
null
);
startFindInProject(findModel);
}
});
findModel.setOpenInNewTabVisible(false);
}
@NotNull
private ConfigurableUsageTarget createFileByTypeTarget(@NotNull FindModel model) {
final String filter = model.getFileFilter();
return new ConfigurableUsageTarget() {
@Override
public void showSettings() {
Content selectedContent = UsageViewManager.getInstance(myProject).getSelectedContent(true);
JComponent component = selectedContent == null ? null : selectedContent.getComponent();
findInProject(DataManager.getInstance().getDataContext(component));
}
public void startFindInProject(@NotNull FindModel findModel) {
final PsiDirectory psiDirectory = FindInProjectUtil.getPsiDirectory(findModel, myProject);
if (findModel.getDirectoryName() != null && psiDirectory == null){
return;
}
@Override
public void findUsages() {
throw new IncorrectOperationException();
}
com.intellij.usages.UsageViewManager manager = com.intellij.usages.UsageViewManager.getInstance(myProject);
@Override
public void findUsagesInEditor(@NotNull FileEditor editor) {
throw new IncorrectOperationException();
}
if (manager == null) return;
final FindManager findManager = FindManager.getInstance(myProject);
findManager.getFindInProjectModel().copyFrom(findModel);
final FindModel findModelCopy = (FindModel)findModel.clone();
final UsageViewPresentation presentation = FindInProjectUtil.setupViewPresentation(myToOpenInNewTab, findModelCopy);
final boolean showPanelIfOnlyOneUsage = !FindSettings.getInstance().isSkipResultsWithOneUsage();
@Override
public void highlightUsages(@NotNull PsiFile file, @NotNull Editor editor, boolean clearHighlights) {
throw new IncorrectOperationException();
}
final FindUsagesProcessPresentation processPresentation = FindInProjectUtil.setupProcessPresentation(myProject, showPanelIfOnlyOneUsage, presentation);
ConfigurableUsageTarget usageTarget = new FindInProjectUtil.StringUsageTarget(myProject, findModel);
@Override
public boolean isValid() {
return true;
}
((FindManagerImpl)FindManager.getInstance(myProject)).getFindUsagesManager().addToHistory(usageTarget);
@Override
public boolean isReadOnly() {
return false;
}
manager.searchAndShowUsages(new UsageTarget[] {usageTarget},
new Factory<UsageSearcher>() {
@Override
public UsageSearcher create() {
return new UsageSearcher() {
@Override
public void generate(@NotNull final Processor<Usage> processor) {
myIsFindInProgress = true;
@Nullable
@Override
public VirtualFile[] getFiles() {
return VirtualFile.EMPTY_ARRAY;
}
@Override
public void update() {
}
@Nullable
@Override
public String getName() {
return "Files with mask \""+filter+"\"";
}
@Nullable
@Override
public ItemPresentation getPresentation() {
return new ItemPresentation() {
@Nullable
@Override
public String getPresentableText() {
return getName();
}
@Nullable
@Override
public String getLocationString() {
return null;
}
@Nullable
@Override
public Icon getIcon(boolean unused) {
return null;
}
};
}
@Override
public void navigate(boolean requestFocus) {
}
@Override
public boolean canNavigate() {
return false;
}
@Override
public boolean canNavigateToSource() {
return false;
}
};
try {
Processor<UsageInfo> consumer = new Processor<UsageInfo>() {
@Override
public boolean process(UsageInfo info) {
Usage usage = UsageInfo2UsageAdapter.CONVERTER.fun(info);
usage.getPresentation().getIcon(); // cache icon
return processor.process(usage);
}
};
FindInProjectUtil.findUsages(findModelCopy, psiDirectory, myProject, true, consumer, processPresentation);
}
finally {
myIsFindInProgress = false;
}
}
};
}
},
processPresentation,
presentation,
null
);
}
public boolean isWorkInProgress() {
@@ -20,6 +20,7 @@ import com.intellij.codeInsight.hint.HintManager;
import com.intellij.codeInsight.hint.HintManagerImpl;
import com.intellij.codeInsight.hint.HintUtil;
import com.intellij.find.FindBundle;
import com.intellij.find.FindSettings;
import com.intellij.lang.findUsages.LanguageFindUsages;
import com.intellij.navigation.NavigationItem;
import com.intellij.openapi.actionSystem.ActionManager;
@@ -49,7 +50,6 @@ import com.intellij.openapi.wm.StatusBar;
import com.intellij.openapi.wm.ex.ProgressIndicatorEx;
import com.intellij.psi.*;
import com.intellij.psi.search.*;
import com.intellij.psi.util.PsiUtilCore;
import com.intellij.ui.LightweightHint;
import com.intellij.ui.content.Content;
import com.intellij.usageView.UsageInfo;
@@ -57,6 +57,7 @@ import com.intellij.usageView.UsageViewManager;
import com.intellij.usageView.UsageViewUtil;
import com.intellij.usages.*;
import com.intellij.util.CommonProcessors;
import com.intellij.util.Function;
import com.intellij.util.Processor;
import com.intellij.util.containers.ContainerUtil;
import org.jdom.Element;
@@ -66,13 +67,14 @@ import org.jetbrains.annotations.Nullable;
import org.picocontainer.defaults.ConstructorInjectionComponentAdapter;
import javax.swing.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicReference;
/**
* see {@link com.intellij.find.impl.FindManagerImpl#getFindUsagesManager()}
*/
public class FindUsagesManager implements JDOMExternalizable {
private static final Logger LOG = Logger.getInstance("#com.intellij.find.findParameterUsages.FindUsagesManager");
@@ -89,27 +91,9 @@ public class FindUsagesManager implements JDOMExternalizable {
private final com.intellij.usages.UsageViewManager myAnotherManager;
private boolean myToOpenInNewTab = true;
public static class SearchData {
public SmartPsiElementPointer[] myElements = null;
public FindUsagesOptions myOptions = null;
public boolean equals(final Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
final SearchData that = (SearchData)o;
return Arrays.equals(myElements, that.myElements)
&& (myOptions != null ? myOptions.equals(that.myOptions) : that.myOptions == null);
}
public int hashCode() {
return myElements != null ? Arrays.hashCode(myElements) : 0;
}
}
private SearchData myLastSearchInFileData = new SearchData();
private final List<SearchData> myFindUsagesHistory = ContainerUtil.createLockFreeCopyOnWriteList();
private PsiElement2UsageTargetComposite myLastSearchInFileData;
private final UsageHistory myHistory = new UsageHistory();
public FindUsagesManager(@NotNull Project project, @NotNull com.intellij.usages.UsageViewManager anotherManager) {
myProject = project;
@@ -134,8 +118,7 @@ public class FindUsagesManager implements JDOMExternalizable {
}
public void clearFindingNextUsageInFile() {
myLastSearchInFileData.myOptions = null;
myLastSearchInFileData.myElements = null;
myLastSearchInFileData = null;
}
public boolean findNextUsageInFile(@NotNull FileEditor editor) {
@@ -157,11 +140,16 @@ public class FindUsagesManager implements JDOMExternalizable {
}
private boolean findUsageInFile(@NotNull FileEditor editor, @NotNull FileSearchScope direction) {
PsiElement[] elements = restorePsiElements(myLastSearchInFileData, true);
if (elements == null) return false;
if (elements.length == 0) return true; //all elements have been invalidated
UsageInfoToUsageConverter.TargetElementsDescriptor descriptor = new UsageInfoToUsageConverter.TargetElementsDescriptor(elements);
if (myLastSearchInFileData == null) return false;
PsiElement[] primaryElements = myLastSearchInFileData.getPrimaryElements();
PsiElement[] secondaryElements = myLastSearchInFileData.getSecondaryElements();
if (primaryElements.length == 0) {//all elements have been invalidated
Messages.showMessageDialog(myProject, FindBundle.message("find.searched.elements.have.been.changed.error"),
FindBundle.message("cannot.search.for.usages.title"), Messages.getInformationIcon());
// SCR #10022
//clearFindingNextUsageInFile();
return false;
}
//todo
TextEditor textEditor = (TextEditor)editor;
@@ -169,49 +157,15 @@ public class FindUsagesManager implements JDOMExternalizable {
PsiFile psiFile = PsiDocumentManager.getInstance(myProject).getPsiFile(document);
if (psiFile == null) return false;
final FindUsagesHandler handler = getFindUsagesHandler(elements[0], false);
final FindUsagesHandler handler = getFindUsagesHandler(primaryElements[0], false);
if (handler == null) return false;
findUsagesInEditor(descriptor, handler, psiFile, direction, myLastSearchInFileData.myOptions, textEditor);
findUsagesInEditor(primaryElements, secondaryElements, handler, psiFile, direction, myLastSearchInFileData.myOptions, textEditor);
return true;
}
// returns null if cannot find, empty Pair if all elements have been changed
@Nullable
private PsiElement[] restorePsiElements(@NotNull SearchData searchData, final boolean showErrorMessage) {
SmartPsiElementPointer[] lastSearchElements = searchData.myElements;
if (lastSearchElements == null) return null;
List<PsiElement> elements = new ArrayList<PsiElement>();
for (SmartPsiElementPointer pointer : lastSearchElements) {
PsiElement element = pointer.getElement();
if (element != null) elements.add(element);
}
if (elements.isEmpty() && showErrorMessage) {
Messages.showMessageDialog(myProject, FindBundle.message("find.searched.elements.have.been.changed.error"),
FindBundle.message("cannot.search.for.usages.title"), Messages.getInformationIcon());
// SCR #10022
//clearFindingNextUsageInFile();
return PsiElement.EMPTY_ARRAY;
}
return PsiUtilCore.toPsiElementArray(elements);
}
private void initLastSearchElement(@NotNull FindUsagesOptions findUsagesOptions,
@NotNull UsageInfoToUsageConverter.TargetElementsDescriptor descriptor) {
myLastSearchInFileData = createSearchData(descriptor.getAllElements(), findUsagesOptions);
}
@NotNull
private SearchData createSearchData(@NotNull List<? extends PsiElement> psiElements, final FindUsagesOptions findUsagesOptions) {
SearchData data = new SearchData();
data.myElements = new SmartPsiElementPointer[psiElements.size()];
int idx = 0;
for (PsiElement psiElement : psiElements) {
data.myElements[idx++] = SmartPointerManager.getInstance(myProject).createSmartPsiElementPointer(psiElement);
}
data.myOptions = findUsagesOptions;
return data;
private void initLastSearchElement(@NotNull FindUsagesOptions findUsagesOptions, @NotNull PsiElement[] primaryElements,@NotNull PsiElement[] secondaryElements) {
myLastSearchInFileData = new PsiElement2UsageTargetComposite(primaryElements, secondaryElements, findUsagesOptions);
}
@Nullable
@@ -274,21 +228,40 @@ public class FindUsagesManager implements JDOMExternalizable {
findUsagesOptions.searchScope = getMaximalScope(handler);
}
clearFindingNextUsageInFile();
startFindUsages(findUsagesOptions, handler, scopeFile, editor);
}
void startFindUsages(@NotNull PsiElement psiElement,
@NotNull FindUsagesOptions findUsagesOptions,
PsiFile scopeFile,
FileEditor editor) {
FindUsagesHandler handler = getNewFindUsagesHandler(psiElement, false);
if (handler == null) return;
startFindUsages(findUsagesOptions, handler, scopeFile, editor);
}
void startFindUsages(@NotNull FindUsagesOptions findUsagesOptions,
@NotNull FindUsagesHandler handler,
PsiFile scopeFile,
FileEditor editor) {
boolean singleFile = scopeFile != null;
clearFindingNextUsageInFile();
LOG.assertTrue(handler.getPsiElement().isValid());
PsiElement[] primaryElements = handler.getPrimaryElements();
checkNotNull(primaryElements, handler, "getPrimaryElements()");
PsiElement[] secondaryElements = handler.getSecondaryElements();
checkNotNull(secondaryElements, handler, "getSecondaryElements()");
UsageInfoToUsageConverter.TargetElementsDescriptor descriptor =
new UsageInfoToUsageConverter.TargetElementsDescriptor(primaryElements, secondaryElements);
if (singleFile) {
findUsagesOptions = findUsagesOptions.clone();
editor.putUserData(KEY_START_USAGE_AGAIN, null);
findUsagesInEditor(descriptor, handler, scopeFile, FileSearchScope.FROM_START, findUsagesOptions, editor);
findUsagesInEditor(primaryElements, secondaryElements, handler, scopeFile, FileSearchScope.FROM_START, findUsagesOptions, editor);
}
else {
findUsages(descriptor, handler, dialog.isSkipResultsWhenOneUsage(), dialog.isShowInSeparateWindow(), findUsagesOptions);
boolean skipResultsWithOneUsage = FindSettings.getInstance().isSkipResultsWithOneUsage();
findUsages(primaryElements, secondaryElements, handler, findUsagesOptions, skipResultsWithOneUsage);
}
}
@@ -299,12 +272,12 @@ public class FindUsagesManager implements JDOMExternalizable {
((ConfigurableUsageTarget)target).showSettings();
}
private static void checkNotNull(@NotNull PsiElement[] primaryElements,
private static void checkNotNull(@NotNull PsiElement[] elements,
@NotNull FindUsagesHandler handler,
@NonNls @NotNull String methodName) {
for (PsiElement element : primaryElements) {
for (PsiElement element : elements) {
if (element == null) {
LOG.error(handler + "." + methodName + " has returned array with null elements: " + Arrays.asList(primaryElements));
LOG.error(handler + "." + methodName + " has returned array with null elements: " + Arrays.asList(elements));
}
}
}
@@ -312,8 +285,7 @@ public class FindUsagesManager implements JDOMExternalizable {
public boolean isUsed(@NotNull PsiElement element, @NotNull FindUsagesOptions findUsagesOptions) {
FindUsagesHandler handler = getFindUsagesHandler(element, true);
if (handler == null) return false;
UsageInfoToUsageConverter.TargetElementsDescriptor descriptor = new UsageInfoToUsageConverter.TargetElementsDescriptor(element);
UsageSearcher usageSearcher = createUsageSearcher(descriptor, handler, findUsagesOptions, null);
UsageSearcher usageSearcher = createUsageSearcher(new PsiElement[]{element}, PsiElement.EMPTY_ARRAY, handler, findUsagesOptions, null);
final AtomicBoolean used = new AtomicBoolean();
usageSearcher.generate(new Processor<Usage>() {
@Override
@@ -341,11 +313,12 @@ public class FindUsagesManager implements JDOMExternalizable {
@NotNull
public static ProgressIndicator startProcessUsages(@NotNull FindUsagesHandler handler,
@NotNull UsageInfoToUsageConverter.TargetElementsDescriptor descriptor,
@NotNull final PsiElement[] primaryElements,
@NotNull final PsiElement[] secondaryElements,
@NotNull final Processor<Usage> processor,
@NotNull FindUsagesOptions findUsagesOptions,
@NotNull final Runnable onComplete) {
final UsageSearcher usageSearcher = createUsageSearcher(descriptor, handler, findUsagesOptions, null);
final UsageSearcher usageSearcher = createUsageSearcher(primaryElements, secondaryElements, handler, findUsagesOptions, null);
final ProgressIndicatorBase indicator = new ProgressIndicatorBase();
dropResolveCacheRegularly(indicator, handler.getProject());
@@ -393,16 +366,17 @@ public class FindUsagesManager implements JDOMExternalizable {
@NotNull
private static UsageSearcher createUsageSearcher(@NotNull final UsageInfoToUsageConverter.TargetElementsDescriptor descriptor,
private static UsageSearcher createUsageSearcher(@NotNull final PsiElement[] primaryElements,
@NotNull final PsiElement[] secondaryElements,
@NotNull final FindUsagesHandler handler,
@NotNull FindUsagesOptions _options,
@NotNull FindUsagesOptions options,
final PsiFile scopeFile) {
final FindUsagesOptions options = _options.clone();
final FindUsagesOptions optionsClone = options.clone();
return new UsageSearcher() {
@Override
public void generate(@NotNull final Processor<Usage> processor) {
if (scopeFile != null) {
options.searchScope = new LocalSearchScope(scopeFile);
optionsClone.searchScope = new LocalSearchScope(scopeFile);
}
final Processor<UsageInfo> usageInfoProcessor = new CommonProcessors.UniqueProcessor<UsageInfo>(new Processor<UsageInfo>() {
@Override
@@ -410,21 +384,15 @@ public class FindUsagesManager implements JDOMExternalizable {
Usage usage = ApplicationManager.getApplication().runReadAction(new Computable<Usage>() {
@Override
public Usage compute() {
return UsageInfoToUsageConverter.convert(descriptor, usageInfo);
return UsageInfoToUsageConverter.convert(primaryElements, usageInfo);
}
});
return processor.process(usage);
}
});
final List<? extends PsiElement> elements =
ApplicationManager.getApplication().runReadAction(new Computable<List<? extends PsiElement>>() {
@Override
public List<? extends PsiElement> compute() {
return descriptor.getAllElements();
}
});
final Iterable<PsiElement> elements = ContainerUtil.concat(primaryElements, secondaryElements);
options.fastTrack = new SearchRequestCollector(new SearchSession());
optionsClone.fastTrack = new SearchRequestCollector(new SearchSession());
try {
for (final PsiElement element : elements) {
@@ -434,10 +402,10 @@ public class FindUsagesManager implements JDOMExternalizable {
LOG.assertTrue(element.isValid());
}
});
handler.processElementUsages(element, usageInfoProcessor, options);
handler.processElementUsages(element, usageInfoProcessor, optionsClone);
for (CustomUsageSearcher searcher : Extensions.getExtensions(CustomUsageSearcher.EP_NAME)) {
try {
searcher.processElementUsages(element, processor, options);
searcher.processElementUsages(element, processor, optionsClone);
}
catch (IndexNotReadyException e) {
DumbService.getInstance(element.getProject()).showDumbModeNotification("Find usages is not available during indexing");
@@ -451,11 +419,11 @@ public class FindUsagesManager implements JDOMExternalizable {
Project project = ApplicationManager.getApplication().runReadAction(new Computable<Project>() {
@Override
public Project compute() {
return scopeFile != null ? scopeFile.getProject() : !elements.isEmpty() ? elements.get(0).getProject() : handler.getProject();
return scopeFile != null ? scopeFile.getProject() : primaryElements[0].getProject();
}
});
PsiSearchHelper.SERVICE.getInstance(project)
.processRequests(options.fastTrack, new Processor<PsiReference>() {
.processRequests(optionsClone.fastTrack, new Processor<PsiReference>() {
@Override
public boolean process(final PsiReference ref) {
UsageInfo info = ApplicationManager.getApplication().runReadAction(new Computable<UsageInfo>() {
@@ -470,40 +438,45 @@ public class FindUsagesManager implements JDOMExternalizable {
});
}
finally {
options.fastTrack = null;
optionsClone.fastTrack = null;
}
}
};
}
@NotNull
private static PsiElement2UsageTargetAdapter[] convertToUsageTargets(@NotNull List<? extends PsiElement> elementsToSearch) {
final List<PsiElement2UsageTargetAdapter> targets = new ArrayList<PsiElement2UsageTargetAdapter>(elementsToSearch.size());
for (PsiElement element : elementsToSearch) {
convertToUsageTarget(targets, element);
}
private static PsiElement2UsageTargetAdapter[] convertToUsageTargets(@NotNull Iterable<PsiElement> elementsToSearch,
@NotNull final FindUsagesOptions findUsagesOptions) {
final List<PsiElement2UsageTargetAdapter> targets = ContainerUtil.map(elementsToSearch,
new Function<PsiElement, PsiElement2UsageTargetAdapter>() {
@Override
public PsiElement2UsageTargetAdapter fun(PsiElement element) {
return convertToUsageTarget(element, findUsagesOptions);
}
});
return targets.toArray(new PsiElement2UsageTargetAdapter[targets.size()]);
}
private void findUsages(@NotNull final UsageInfoToUsageConverter.TargetElementsDescriptor descriptor,
@NotNull final FindUsagesHandler handler,
final boolean toSkipUsagePanelWhenOneUsage,
final boolean toOpenInNewTab,
@NotNull final FindUsagesOptions findUsagesOptions) {
List<? extends PsiElement> elements = descriptor.getAllElements();
if (elements.isEmpty()) {
public void findUsages(@NotNull final PsiElement[] primaryElements,
@NotNull final PsiElement[] secondaryElements,
@NotNull final FindUsagesHandler handler,
@NotNull final FindUsagesOptions findUsagesOptions,
final boolean toSkipUsagePanelWhenOneUsage) {
if (primaryElements.length == 0) {
throw new AssertionError(handler + " " + findUsagesOptions);
}
final UsageTarget[] targets = convertToUsageTargets(elements);
Iterable<PsiElement> allElements = ContainerUtil.concat(primaryElements, secondaryElements);
final UsageTarget[] targets = convertToUsageTargets(allElements, findUsagesOptions);
myAnotherManager.searchAndShowUsages(targets, new Factory<UsageSearcher>() {
@Override
public UsageSearcher create() {
dropResolveCacheRegularly(ProgressManager.getInstance().getProgressIndicator(), myProject);
return createUsageSearcher(descriptor, handler, findUsagesOptions, null);
return createUsageSearcher(primaryElements, secondaryElements, handler, findUsagesOptions, null);
}
}, !toSkipUsagePanelWhenOneUsage, true, createPresentation(elements.get(0), findUsagesOptions, toOpenInNewTab), null);
addToHistory(elements, findUsagesOptions);
}, !toSkipUsagePanelWhenOneUsage, true, createPresentation(primaryElements[0], findUsagesOptions, shouldOpenInNewTab()), null);
myHistory.add((ConfigurableUsageTarget)targets[0]);
//addToHistory(allElements, findUsagesOptions);
}
private static void dropResolveCacheRegularly(ProgressIndicator indicator, final Project project) {
@@ -546,19 +519,20 @@ public class FindUsagesManager implements JDOMExternalizable {
return presentation;
}
private void findUsagesInEditor(@NotNull UsageInfoToUsageConverter.TargetElementsDescriptor descriptor,
private void findUsagesInEditor(@NotNull final PsiElement[] primaryElements,
@NotNull final PsiElement[] secondaryElements,
@NotNull FindUsagesHandler handler,
@NotNull PsiFile scopeFile,
@NotNull FileSearchScope direction,
@NotNull final FindUsagesOptions findUsagesOptions,
@NotNull FileEditor fileEditor) {
initLastSearchElement(findUsagesOptions, descriptor);
initLastSearchElement(findUsagesOptions, primaryElements, secondaryElements);
clearStatusBar();
final FileEditorLocation currentLocation = fileEditor.getCurrentLocation();
final UsageSearcher usageSearcher = createUsageSearcher(descriptor, handler, findUsagesOptions, scopeFile);
final UsageSearcher usageSearcher = createUsageSearcher(primaryElements, secondaryElements, handler, findUsagesOptions, scopeFile);
AtomicBoolean usagesWereFound = new AtomicBoolean();
Usage fUsage = findSiblingUsage(usageSearcher, direction, currentLocation, usagesWereFound, fileEditor);
@@ -568,12 +542,12 @@ public class FindUsagesManager implements JDOMExternalizable {
fUsage.selectInEditor();
}
else if (!usagesWereFound.get()) {
String message = getNoUsagesFoundMessage(descriptor.getPrimaryElements()[0]) + " in " + scopeFile.getName();
String message = getNoUsagesFoundMessage(primaryElements[0]) + " in " + scopeFile.getName();
showHintOrStatusBarMessage(message, fileEditor);
}
else {
fileEditor.putUserData(KEY_START_USAGE_AGAIN, VALUE_START_USAGE_AGAIN);
showHintOrStatusBarMessage(getSearchAgainMessage(descriptor.getPrimaryElements()[0], direction), fileEditor);
showHintOrStatusBarMessage(getSearchAgainMessage(primaryElements[0], direction), fileEditor);
}
}
@@ -675,13 +649,12 @@ public class FindUsagesManager implements JDOMExternalizable {
return foundUsage.get();
}
private static void convertToUsageTarget(@NotNull List<PsiElement2UsageTargetAdapter> targets, @NotNull PsiElement elementToSearch) {
private static PsiElement2UsageTargetAdapter convertToUsageTarget(@NotNull PsiElement elementToSearch,
@NotNull FindUsagesOptions findUsagesOptions) {
if (elementToSearch instanceof NavigationItem) {
targets.add(new PsiElement2UsageTargetAdapter(elementToSearch));
}
else {
throw new IllegalArgumentException("Wrong usage target:" + elementToSearch + "; " + elementToSearch.getClass());
return new PsiElement2UsageTargetAdapter(elementToSearch,findUsagesOptions);
}
throw new IllegalArgumentException("Wrong usage target:" + elementToSearch + "; " + elementToSearch.getClass());
}
@NotNull
@@ -702,55 +675,21 @@ public class FindUsagesManager implements JDOMExternalizable {
return LanguageFindUsages.INSTANCE.forLanguage(element.getLanguage()).getHelpId(element);
}
private void addToHistory(final List<? extends PsiElement> elements, final FindUsagesOptions findUsagesOptions) {
SearchData data = createSearchData(elements, findUsagesOptions);
myFindUsagesHistory.remove(data);
myFindUsagesHistory.add(data);
// todo configure history depth limit
if (myFindUsagesHistory.size() > 15) {
myFindUsagesHistory.remove(0);
}
public void rerunAndRecallFromHistory(@NotNull ConfigurableUsageTarget usageTarget) {
usageTarget.findUsages();
addToHistory(usageTarget);
}
public void rerunAndRecallFromHistory(@NotNull SearchData searchData) {
myFindUsagesHistory.remove(searchData);
PsiElement[] elements = restorePsiElements(searchData, true);
if (elements == null || elements.length == 0) return;
UsageInfoToUsageConverter.TargetElementsDescriptor descriptor = new UsageInfoToUsageConverter.TargetElementsDescriptor(elements);
final FindUsagesHandler handler = getFindUsagesHandler(elements[0], false);
if (handler == null) return;
findUsages(descriptor, handler, false, false, searchData.myOptions);
public void addToHistory(@NotNull ConfigurableUsageTarget usageTarget) {
myHistory.add(usageTarget);
}
// most recent entry is at the end of the list
public List<SearchData> getFindUsageHistory() {
removeInvalidElementsFromHistory();
return Collections.unmodifiableList(myFindUsagesHistory);
}
private void removeInvalidElementsFromHistory() {
for (SearchData data : myFindUsagesHistory) {
PsiElement[] elements = restorePsiElements(data, false);
if (elements == null || elements.length == 0) myFindUsagesHistory.remove(data);
}
}
@NotNull
private static PsiElement[] getPsiElements(@NotNull UsageTarget[] targets) {
List<PsiElement> result = new ArrayList<PsiElement>();
for (UsageTarget target : targets) {
if (target instanceof PsiElementUsageTarget) {
PsiElement element = ((PsiElementUsageTarget)target).getElement();
if (element != null) {
result.add(element);
}
}
}
return PsiUtilCore.toPsiElementArray(result);
public UsageHistory getHistory() {
return myHistory;
}
@NotNull
public static GlobalSearchScope getMaximalScope(@NotNull FindUsagesHandler handler) {
PsiElement element = handler.getPsiElement();
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2013 JetBrains s.r.o.
* Copyright 2000-2014 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.
@@ -17,31 +17,40 @@
package com.intellij.find.findUsages;
import com.intellij.codeInsight.highlighting.HighlightUsagesHandler;
import com.intellij.find.FindBundle;
import com.intellij.find.FindManager;
import com.intellij.find.impl.FindManagerImpl;
import com.intellij.lang.findUsages.DescriptiveNameUtil;
import com.intellij.lang.injection.InjectedLanguageManager;
import com.intellij.navigation.ItemPresentation;
import com.intellij.navigation.NavigationItem;
import com.intellij.navigation.PsiElementNavigationItem;
import com.intellij.openapi.actionSystem.DataKey;
import com.intellij.openapi.actionSystem.DataSink;
import com.intellij.openapi.actionSystem.KeyboardShortcut;
import com.intellij.openapi.actionSystem.TypeSafeDataProvider;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.fileEditor.FileEditor;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.pom.Navigatable;
import com.intellij.psi.*;
import com.intellij.psi.meta.PsiMetaData;
import com.intellij.psi.meta.PsiMetaOwner;
import com.intellij.psi.meta.PsiPresentableMetaData;
import com.intellij.psi.search.LocalSearchScope;
import com.intellij.psi.search.ProjectScope;
import com.intellij.psi.search.SearchScope;
import com.intellij.psi.search.searches.ReferencesSearch;
import com.intellij.ui.ComputableIcon;
import com.intellij.usageView.UsageInfo;
import com.intellij.usageView.UsageViewBundle;
import com.intellij.usageView.UsageViewUtil;
import com.intellij.usages.ConfigurableUsageTarget;
import com.intellij.usages.PsiElementUsageTarget;
import com.intellij.usages.UsageView;
import com.intellij.usages.impl.UsageViewImpl;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
@@ -51,49 +60,55 @@ import java.util.Collection;
/**
* @author max
*/
public class PsiElement2UsageTargetAdapter implements PsiElementUsageTarget, TypeSafeDataProvider, PsiElementNavigationItem {
public class PsiElement2UsageTargetAdapter
implements PsiElementUsageTarget, TypeSafeDataProvider, PsiElementNavigationItem, ItemPresentation, ConfigurableUsageTarget {
private final SmartPsiElementPointer myPointer;
private final MyItemPresentation myPresentation;
@NotNull protected final FindUsagesOptions myOptions;
public PsiElement2UsageTargetAdapter(@NotNull PsiElement element) {
public PsiElement2UsageTargetAdapter(@NotNull PsiElement element, @NotNull FindUsagesOptions options) {
myOptions = options;
myPointer = SmartPointerManager.getInstance(element.getProject()).createSmartPsiElementPointer(element);
if (!(element instanceof NavigationItem)) {
throw new IllegalArgumentException("Element is not a navigation item: " + element);
}
update(element);
}
myPresentation = new MyItemPresentation();
public PsiElement2UsageTargetAdapter(@NotNull PsiElement element) {
this(element, new FindUsagesOptions(element.getProject()));
}
@Override
public String getName() {
return getNavigationItem().getName();
PsiElement element = getElement();
return element instanceof NavigationItem ? ((NavigationItem)element).getName() : null;
}
@Override
@NotNull
public ItemPresentation getPresentation() {
return myPresentation;
return this;
}
@Override
public void navigate(boolean requestFocus) {
if (!canNavigate()) return;
getNavigationItem().navigate(requestFocus);
PsiElement element = getElement();
if (element instanceof Navigatable && ((Navigatable)element).canNavigate()) {
((Navigatable)element).navigate(requestFocus);
}
}
@Override
public boolean canNavigate() {
return isValid() && getNavigationItem().canNavigate();
PsiElement element = getElement();
return element instanceof Navigatable && ((Navigatable)element).canNavigate();
}
@Override
public boolean canNavigateToSource() {
return isValid() && getNavigationItem().canNavigateToSource();
}
private NavigationItem getNavigationItem() {
return (NavigationItem)getElement();
PsiElement element = getElement();
return element instanceof Navigatable && ((Navigatable)element).canNavigateToSource();
}
@Override
@@ -102,13 +117,14 @@ public class PsiElement2UsageTargetAdapter implements PsiElementUsageTarget, Typ
}
public String toString() {
return myPresentation.getPresentableText();
return getPresentableText();
}
@Override
public void findUsages() {
PsiElement element = getElement();
FindManager.getInstance(element.getProject()).findUsages(element);
if (element == null) return;
((FindManagerImpl)FindManager.getInstance(element.getProject())).getFindUsagesManager().startFindUsages(element, myOptions, null, null);
}
@Override
@@ -164,12 +180,8 @@ public class PsiElement2UsageTargetAdapter implements PsiElementUsageTarget, Typ
return virtualFile == null ? null : new VirtualFile[]{virtualFile};
}
@Override
public void update() {
myPresentation.update();
}
public static PsiElement2UsageTargetAdapter[] convert(PsiElement[] psiElements) {
@NotNull
public static PsiElement2UsageTargetAdapter[] convert(@NotNull PsiElement[] psiElements) {
PsiElement2UsageTargetAdapter[] targets = new PsiElement2UsageTargetAdapter[psiElements.length];
for (int i = 0; i < targets.length; i++) {
targets[i] = new PsiElement2UsageTargetAdapter(psiElements[i]);
@@ -188,6 +200,27 @@ public class PsiElement2UsageTargetAdapter implements PsiElementUsageTarget, Typ
}
}
@Override
public KeyboardShortcut getShortcut() {
return UsageViewImpl.getShowUsagesWithSettingsShortcut();
}
@NotNull
@Override
public String getLongDescriptiveName() {
SearchScope searchScope = myOptions.searchScope;
String scopeString = searchScope == null ? null : searchScope.getDisplayName();
PsiElement psiElement = getElement();
return psiElement == null ? UsageViewBundle.message("node.invalid") :
FindBundle.message("recent.find.usages.action.popup", StringUtil.capitalize(UsageViewUtil.getType(psiElement)),
DescriptiveNameUtil.getDescriptiveName(psiElement),
scopeString == null
? ProjectScope.getAllScope(psiElement.getProject()).getDisplayName()
: scopeString
);
}
@Override
public void showSettings() {
FindUsagesManager findUsagesManager = ((FindManagerImpl)FindManager.getInstance(myPointer.getProject())).getFindUsagesManager();
@@ -197,58 +230,56 @@ public class PsiElement2UsageTargetAdapter implements PsiElementUsageTarget, Typ
}
}
private class MyItemPresentation implements ItemPresentation {
private String myPresentableText;
private ComputableIcon myIconOpen;
private ComputableIcon myIconClosed;
private String myPresentableText;
private ComputableIcon myIconOpen;
private ComputableIcon myIconClosed;
public MyItemPresentation() {
update();
}
@Override
public void update() {
update(getElement());
}
public void update() {
final PsiElement element = getElement();
if (element != null && element.isValid()) {
final ItemPresentation presentation = ((NavigationItem)element).getPresentation();
myIconOpen = presentation != null ? ComputableIcon.create(presentation, true) : null;
myIconClosed = presentation != null ? ComputableIcon.create(presentation, false) : null;
myPresentableText = presentation != null ? presentation.getPresentableText() : UsageViewUtil.createNodeText(element);
if (myIconOpen == null || myIconClosed == null) {
if (element instanceof PsiMetaOwner) {
final PsiMetaOwner psiMetaOwner = (PsiMetaOwner)element;
final PsiMetaData metaData = psiMetaOwner.getMetaData();
if (metaData instanceof PsiPresentableMetaData) {
final PsiPresentableMetaData psiPresentableMetaData = (PsiPresentableMetaData)metaData;
if (myIconOpen == null) myIconOpen = ComputableIcon.create(psiPresentableMetaData);
if (myIconClosed == null) myIconClosed = ComputableIcon.create(psiPresentableMetaData);
}
private void update(PsiElement element) {
if (element != null && element.isValid()) {
final ItemPresentation presentation = ((NavigationItem)element).getPresentation();
myIconOpen = presentation == null ? null : ComputableIcon.create(presentation, true);
myIconClosed = presentation == null ? null : ComputableIcon.create(presentation, false);
myPresentableText = presentation == null ? UsageViewUtil.createNodeText(element) : presentation.getPresentableText();
if (myIconOpen == null || myIconClosed == null) {
if (element instanceof PsiMetaOwner) {
final PsiMetaOwner psiMetaOwner = (PsiMetaOwner)element;
final PsiMetaData metaData = psiMetaOwner.getMetaData();
if (metaData instanceof PsiPresentableMetaData) {
final PsiPresentableMetaData psiPresentableMetaData = (PsiPresentableMetaData)metaData;
if (myIconOpen == null) myIconOpen = ComputableIcon.create(psiPresentableMetaData);
if (myIconClosed == null) myIconClosed = ComputableIcon.create(psiPresentableMetaData);
}
else if (element instanceof PsiFile) {
final PsiFile psiFile = (PsiFile)element;
final VirtualFile virtualFile = psiFile.getVirtualFile();
if (virtualFile != null) {
myIconOpen = ComputableIcon.create(virtualFile);
myIconClosed = ComputableIcon.create(virtualFile);
}
}
else if (element instanceof PsiFile) {
final PsiFile psiFile = (PsiFile)element;
final VirtualFile virtualFile = psiFile.getVirtualFile();
if (virtualFile != null) {
myIconOpen = ComputableIcon.create(virtualFile);
myIconClosed = ComputableIcon.create(virtualFile);
}
}
}
}
}
@Override
public String getPresentableText() {
return myPresentableText;
}
@Override
public String getPresentableText() {
return myPresentableText;
}
@Override
public String getLocationString() {
return null;
}
@Override
public String getLocationString() {
return null;
}
@Override
public Icon getIcon(boolean open) {
final ComputableIcon computableIcon = open ? myIconOpen : myIconClosed;
return computableIcon == null? null : computableIcon.getIcon();
}
@Override
public Icon getIcon(boolean open) {
final ComputableIcon computableIcon = open ? myIconOpen : myIconClosed;
return computableIcon == null ? null : computableIcon.getIcon();
}
}
@@ -0,0 +1,70 @@
/*
* Copyright 2000-2014 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.find.findUsages;
import com.intellij.find.FindManager;
import com.intellij.find.FindSettings;
import com.intellij.find.impl.FindManagerImpl;
import com.intellij.openapi.vfs.VfsUtilCore;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiElement;
import com.intellij.psi.util.PsiUtilCore;
import com.intellij.usages.UsageInfoToUsageConverter;
import com.intellij.util.Function;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
import java.util.Set;
public class PsiElement2UsageTargetComposite extends PsiElement2UsageTargetAdapter {
private final UsageInfoToUsageConverter.TargetElementsDescriptor myDescriptor;
public PsiElement2UsageTargetComposite(@NotNull PsiElement[] primaryElements,
@NotNull PsiElement[] secondaryElements,
@NotNull FindUsagesOptions options) {
super(primaryElements[0], options);
myDescriptor = new UsageInfoToUsageConverter.TargetElementsDescriptor(primaryElements, secondaryElements);
}
@Override
public void findUsages() {
PsiElement element = getElement();
if (element == null) return;
FindUsagesManager findUsagesManager = ((FindManagerImpl)FindManager.getInstance(element.getProject())).getFindUsagesManager();
FindUsagesHandler handler = findUsagesManager.getNewFindUsagesHandler(element, false);
boolean skipResultsWithOneUsage = FindSettings.getInstance().isSkipResultsWithOneUsage();
findUsagesManager.findUsages(myDescriptor.getPrimaryElements(), myDescriptor.getAdditionalElements(), handler, myOptions, skipResultsWithOneUsage);
}
@Override
public VirtualFile[] getFiles() {
Set<VirtualFile> files = ContainerUtil.map2Set(myDescriptor.getAllElements(), new Function<PsiElement, VirtualFile>() {
@Override
public VirtualFile fun(PsiElement element) {
return PsiUtilCore.getVirtualFile(element);
}
});
return VfsUtilCore.toVirtualFileArray(files);
}
@NotNull
public PsiElement[] getPrimaryElements() {
return myDescriptor.getPrimaryElements();
}
@NotNull
public PsiElement[] getSecondaryElements() {
return myDescriptor.getAdditionalElements();
}
}
@@ -0,0 +1,58 @@
/*
* Copyright 2000-2014 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.find.findUsages;
import com.intellij.openapi.util.Condition;
import com.intellij.usages.ConfigurableUsageTarget;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
import java.util.Collections;
import java.util.List;
public class UsageHistory {
// the last element is the most recent
private final List<ConfigurableUsageTarget> myHistory = ContainerUtil.createLockFreeCopyOnWriteList();
public void add(@NotNull ConfigurableUsageTarget usageTarget) {
final String descriptiveName = usageTarget.getLongDescriptiveName();
ContainerUtil.retainAll(myHistory, new Condition<ConfigurableUsageTarget>() {
@Override
public boolean value(ConfigurableUsageTarget existing) {
return !existing.getLongDescriptiveName().equals(descriptiveName);
}
});
myHistory.add(usageTarget);
// todo configure history depth limit
if (myHistory.size() > 15) {
myHistory.remove(0);
}
}
@NotNull
public List<ConfigurableUsageTarget> getAll() {
removeInvalidElementsFromHistory();
return Collections.unmodifiableList(myHistory);
}
private void removeInvalidElementsFromHistory() {
for (ConfigurableUsageTarget target : myHistory) {
if (!target.isValid()) myHistory.remove(target);
}
}
}
@@ -20,11 +20,10 @@ import com.intellij.BundleBase;
import com.intellij.find.*;
import com.intellij.find.findInProject.FindInProjectManager;
import com.intellij.find.ngrams.TrigramIndex;
import com.intellij.icons.AllIcons;
import com.intellij.ide.DataManager;
import com.intellij.navigation.ItemPresentation;
import com.intellij.openapi.actionSystem.CommonDataKeys;
import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.openapi.actionSystem.LangDataKeys;
import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.ApplicationNamesInfo;
import com.intellij.openapi.editor.Document;
@@ -459,7 +458,8 @@ public class FindInProjectUtil {
@NotNull final Project project,
@Nullable final PsiDirectory psiDirectory,
final Pattern fileMaskRegExp,
@Nullable final Module module, FileIndex fileIndex) {
@Nullable final Module module,
@NotNull FileIndex fileIndex) {
if (DumbService.getInstance(project).isDumb()) {
return new Pair<Boolean, Collection<PsiFile>>(false, Collections.<PsiFile>emptyList());
}
@@ -577,7 +577,7 @@ public class FindInProjectUtil {
}
private static int addToUsages(@NotNull Document document, @NotNull Processor<UsageInfo> consumer, @NotNull FindModel findModel,
@NotNull final PsiFile psiFile, int[] offsetRef, int maxUsages) {
@NotNull final PsiFile psiFile, @NotNull int[] offsetRef, int maxUsages) {
int count = 0;
CharSequence text = document.getCharsSequence();
int textLength = document.getTextLength();
@@ -616,39 +616,40 @@ public class FindInProjectUtil {
return count;
}
@NotNull
private static String getTitleForScope(@NotNull final FindModel findModel) {
String result;
String scopeName;
if (findModel.isProjectScope()) {
result = FindBundle.message("find.scope.project.title");
scopeName = FindBundle.message("find.scope.project.title");
}
else if (findModel.getModuleName() != null) {
result = FindBundle.message("find.scope.module.title", findModel.getModuleName());
scopeName = FindBundle.message("find.scope.module.title", findModel.getModuleName());
}
else if(findModel.getCustomScopeName() != null) {
result = findModel.getCustomScopeName();
scopeName = findModel.getCustomScopeName();
}
else {
result = FindBundle.message("find.scope.directory.title", findModel.getDirectoryName());
scopeName = FindBundle.message("find.scope.directory.title", findModel.getDirectoryName());
}
String result = scopeName;
if (findModel.getFileFilter() != null) {
result = FindBundle.message("find.scope.files.with.mask", result, findModel.getFileFilter());
result += " "+FindBundle.message("find.scope.files.with.mask", findModel.getFileFilter());
}
return result;
}
@NotNull
public static UsageViewPresentation setupViewPresentation(final boolean toOpenInNewTab, @NotNull final FindModel findModelCopy) {
public static UsageViewPresentation setupViewPresentation(final boolean toOpenInNewTab, @NotNull FindModel findModel) {
final UsageViewPresentation presentation = new UsageViewPresentation();
final String scope = getTitleForScope(findModelCopy);
final String stringToFind = findModelCopy.getStringToFind();
final String scope = getTitleForScope(findModel);
final String stringToFind = findModel.getStringToFind();
presentation.setScopeText(scope);
if (stringToFind.isEmpty()) {
presentation.setTabText("Files");
presentation.setToolwindowTitle(BundleBase.format("Files in ''{0}''", scope));
presentation.setToolwindowTitle(BundleBase.format("Files in {0}", scope));
presentation.setUsagesString("files");
}
else {
@@ -668,7 +669,6 @@ public class FindInProjectUtil {
@NotNull final UsageViewPresentation presentation) {
FindUsagesProcessPresentation processPresentation = new FindUsagesProcessPresentation();
processPresentation.setShowNotFoundMessage(true);
processPresentation.setShowFindOptionsPrompt(false);
processPresentation.setShowPanelIfOnlyOneUsage(showPanelIfOnlyOneUsage);
processPresentation.setProgressIndicatorFactory(
new Factory<ProgressIndicator>() {
@@ -682,34 +682,43 @@ public class FindInProjectUtil {
return processPresentation;
}
public static class StringUsageTarget implements ConfigurableUsageTarget {
public static class StringUsageTarget implements ConfigurableUsageTarget, ItemPresentation {
@NotNull private final Project myProject;
private final String myStringToFind;
@NotNull private final FindModel myFindModel;
private final ItemPresentation myItemPresentation = new ItemPresentation() {
@Override
public String getPresentableText() {
return FindBundle.message("find.usage.target.string.text", myStringToFind);
}
@Override
public String getLocationString() {
return myStringToFind + "!!";
}
@Override
public Icon getIcon(boolean open) {
return null;
}
};
public StringUsageTarget(@NotNull Project project, @NotNull String _stringToFind) {
public StringUsageTarget(@NotNull Project project, @NotNull FindModel findModel) {
myProject = project;
myStringToFind = _stringToFind;
myFindModel = findModel;
}
@Override
public void findUsages() {}
@NotNull
public String getPresentableText() {
UsageViewPresentation presentation = setupViewPresentation(false, myFindModel);
return presentation.getToolwindowTitle();
}
@NotNull
@Override
public String getLongDescriptiveName() {
return getPresentableText();
}
@Override
public String getLocationString() {
return myFindModel + "!!";
}
@Override
public Icon getIcon(boolean open) {
return AllIcons.Actions.Menu_find;
}
@Override
public void findUsages() {
FindInProjectManager.getInstance(myProject).startFindInProject(myFindModel);
}
@Override
public void findUsagesInEditor(@NotNull FileEditor editor) {}
@Override
@@ -737,12 +746,12 @@ public class FindInProjectUtil {
@Override
public String getName() {
return myStringToFind;
return myFindModel.getStringToFind().isEmpty() ? myFindModel.getFileFilter() : myFindModel.getStringToFind();
}
@Override
public ItemPresentation getPresentation() {
return myItemPresentation;
return this;
}
@Override
@@ -767,5 +776,10 @@ public class FindInProjectUtil {
FindInProjectManager findInProjectManager = FindInProjectManager.getInstance(myProject);
findInProjectManager.findInProject(DataManager.getInstance().getDataContext(component));
}
@Override
public KeyboardShortcut getShortcut() {
return ActionManager.getInstance().getKeyboardShortcut("FindInPath");
}
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
* Copyright 2000-2014 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.
@@ -19,21 +19,16 @@ package com.intellij.find.impl;
import com.intellij.find.FindBundle;
import com.intellij.find.FindManager;
import com.intellij.find.findUsages.FindUsagesManager;
import com.intellij.lang.findUsages.DescriptiveNameUtil;
import com.intellij.navigation.ItemPresentation;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.CommonDataKeys;
import com.intellij.openapi.actionSystem.PlatformDataKeys;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.popup.JBPopupFactory;
import com.intellij.openapi.ui.popup.PopupStep;
import com.intellij.openapi.ui.popup.util.BaseListPopupStep;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.PsiElement;
import com.intellij.psi.search.ProjectScope;
import com.intellij.ui.awt.RelativePoint;
import com.intellij.usageView.UsageViewBundle;
import com.intellij.usageView.UsageViewUtil;
import com.intellij.usages.ConfigurableUsageTarget;
import com.intellij.usages.UsageView;
import org.jetbrains.annotations.NotNull;
@@ -60,7 +55,7 @@ public class ShowRecentFindUsagesAction extends AnAction {
UsageView usageView = e.getData(UsageView.USAGE_VIEW_KEY);
Project project = e.getData(CommonDataKeys.PROJECT);
final FindUsagesManager findUsagesManager = ((FindManagerImpl)FindManager.getInstance(project)).getFindUsagesManager();
List<FindUsagesManager.SearchData> history = new ArrayList<FindUsagesManager.SearchData>(findUsagesManager.getFindUsageHistory());
List<ConfigurableUsageTarget> history = new ArrayList<ConfigurableUsageTarget>(findUsagesManager.getHistory().getAll());
if (!history.isEmpty()) {
// skip most recent find usage, it's under your nose
@@ -68,42 +63,32 @@ public class ShowRecentFindUsagesAction extends AnAction {
Collections.reverse(history);
}
if (history.isEmpty()) {
history.add(new FindUsagesManager.SearchData()); // to fill the popup
history.add(null); // to fill the popup
}
BaseListPopupStep<FindUsagesManager.SearchData> step =
new BaseListPopupStep<FindUsagesManager.SearchData>(FindBundle.message("recent.find.usages.action.title"), history) {
BaseListPopupStep<ConfigurableUsageTarget> step =
new BaseListPopupStep<ConfigurableUsageTarget>(FindBundle.message("recent.find.usages.action.title"), history) {
@Override
public Icon getIconFor(final FindUsagesManager.SearchData data) {
if (data.myElements == null) {
return null;
}
PsiElement psiElement = data.myElements[0].getElement();
if (psiElement == null) return null;
return psiElement.getIcon(0);
public Icon getIconFor(final ConfigurableUsageTarget data) {
ItemPresentation presentation = data == null ? null : data.getPresentation();
return presentation == null ? null : presentation.getIcon(false);
}
@Override
@NotNull
public String getTextFor(final FindUsagesManager.SearchData data) {
if (data.myElements == null) {
public String getTextFor(final ConfigurableUsageTarget data) {
if (data == null) {
return FindBundle.message("recent.find.usages.action.nothing");
}
PsiElement psiElement = data.myElements[0].getElement();
if (psiElement == null) return UsageViewBundle.message("node.invalid");
String scopeString = data.myOptions.searchScope == null ? null : data.myOptions.searchScope.getDisplayName();
return FindBundle.message("recent.find.usages.action.description",
StringUtil.capitalize(UsageViewUtil.getType(psiElement)),
DescriptiveNameUtil.getDescriptiveName(psiElement),
scopeString == null ? ProjectScope.getAllScope(psiElement.getProject()).getDisplayName() : scopeString);
return data.getLongDescriptiveName();
}
@Override
public PopupStep onChosen(final FindUsagesManager.SearchData selectedValue, final boolean finalChoice) {
public PopupStep onChosen(final ConfigurableUsageTarget selectedValue, final boolean finalChoice) {
return doFinalStep(new Runnable() {
@Override
public void run() {
if (selectedValue.myElements != null) {
if (selectedValue != null) {
findUsagesManager.rerunAndRecallFromHistory(selectedValue);
}
}
@@ -118,6 +103,5 @@ public class ShowRecentFindUsagesAction extends AnAction {
point = new RelativePoint(usageView.getComponent(), new Point(4, 4));
}
JBPopupFactory.getInstance().createListPopup(step).show(point);
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
* Copyright 2000-2014 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.
@@ -16,16 +16,11 @@
package com.intellij.find.impl;
import com.intellij.find.FindBundle;
import com.intellij.find.FindManager;
import com.intellij.find.findUsages.FindUsagesManager;
import com.intellij.lang.findUsages.DescriptiveNameUtil;
import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.PsiElement;
import com.intellij.psi.search.ProjectScope;
import com.intellij.usageView.UsageViewUtil;
import com.intellij.usages.ConfigurableUsageTarget;
import com.intellij.usages.impl.UsageViewImpl;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -52,27 +47,22 @@ public class ShowRecentFindUsagesGroup extends ActionGroup {
Project project = e.getData(CommonDataKeys.PROJECT);
if (project == null) return EMPTY_ARRAY;
final FindUsagesManager findUsagesManager = ((FindManagerImpl)FindManager.getInstance(project)).getFindUsagesManager();
List<FindUsagesManager.SearchData> history = new ArrayList<FindUsagesManager.SearchData>(findUsagesManager.getFindUsageHistory());
List<ConfigurableUsageTarget> history = new ArrayList<ConfigurableUsageTarget>(findUsagesManager.getHistory().getAll());
Collections.reverse(history);
String description =
ActionManager.getInstance().getAction(UsageViewImpl.SHOW_RECENT_FIND_USAGES_ACTION_ID).getTemplatePresentation().getDescription();
List<AnAction> children = new ArrayList<AnAction>(history.size());
for (final FindUsagesManager.SearchData data : history) {
if (data.myElements == null) {
for (final ConfigurableUsageTarget usageTarget : history) {
if (!usageTarget.isValid()) {
continue;
}
PsiElement psiElement = data.myElements[0].getElement();
if (psiElement == null) continue;
String scopeString = data.myOptions.searchScope == null ? null : data.myOptions.searchScope.getDisplayName();
String text = FindBundle.message("recent.find.usages.action.popup", StringUtil.capitalize(UsageViewUtil.getType(psiElement)),
DescriptiveNameUtil.getDescriptiveName(psiElement),
scopeString == null ? ProjectScope.getAllScope(psiElement.getProject()).getDisplayName() : scopeString);
AnAction action = new AnAction(text, description, psiElement.getIcon(0)) {
String text = usageTarget.getLongDescriptiveName();
AnAction action = new AnAction(text, description, null) {
@Override
public void actionPerformed(final AnActionEvent e) {
findUsagesManager.rerunAndRecallFromHistory(data);
findUsagesManager.rerunAndRecallFromHistory(usageTarget);
}
};
children.add(action);
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2013 JetBrains s.r.o.
* Copyright 2000-2014 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.
@@ -162,7 +162,7 @@ public class ReplaceInProjectManager {
final FindManager findManager) {
presentation.setMergeDupLinesAvailable(false);
final ReplaceContext[] context = new ReplaceContext[1];
manager.searchAndShowUsages(new UsageTarget[]{new FindInProjectUtil.StringUsageTarget(myProject, findModelCopy.getStringToFind())},
manager.searchAndShowUsages(new UsageTarget[]{new FindInProjectUtil.StringUsageTarget(myProject, findModelCopy)},
usageSearcherFactory, processPresentation, presentation, new UsageViewManager.UsageViewStateListener() {
@Override
public void usageViewCreated(@NotNull UsageView usageView) {
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
* Copyright 2000-2014 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.
@@ -32,7 +32,6 @@ import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.util.PsiUtilCore;
import com.intellij.usageView.UsageInfo;
import com.intellij.usages.UsageInfoToUsageConverter;
import com.intellij.util.Consumer;
import javax.swing.*;
@@ -110,7 +109,7 @@ public class DependenciesUsagesPanel extends UsagesPanel {
ApplicationManager.getApplication().invokeLater(new Runnable() {
@Override
public void run() {
showUsages(new UsageInfoToUsageConverter.TargetElementsDescriptor(_elementsToSearch), finalUsages);
showUsages(_elementsToSearch, finalUsages);
}
}, ModalityState.stateForComponent(DependenciesUsagesPanel.this));
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
* Copyright 2000-2014 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.
@@ -25,6 +25,7 @@ import com.intellij.openapi.progress.ProcessCanceledException;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Disposer;
import com.intellij.psi.PsiElement;
import com.intellij.usageView.UsageInfo;
import com.intellij.usages.*;
import com.intellij.util.Alarm;
@@ -64,12 +65,12 @@ public abstract class UsagesPanel extends JPanel implements Disposable, DataProv
}
}
protected void showUsages(@NotNull UsageInfoToUsageConverter.TargetElementsDescriptor descriptor, @NotNull UsageInfo[] usageInfos) {
protected void showUsages(@NotNull PsiElement[] primaryElements, @NotNull UsageInfo[] usageInfos) {
if (myCurrentUsageView != null) {
Disposer.dispose(myCurrentUsageView);
}
try {
Usage[] usages = UsageInfoToUsageConverter.convert(descriptor, usageInfos);
Usage[] usages = UsageInfoToUsageConverter.convert(primaryElements, usageInfos);
UsageViewPresentation presentation = new UsageViewPresentation();
presentation.setCodeUsagesString(getCodeUsagesString());
myCurrentUsageView = UsageViewManager.getInstance(myProject).createUsageView(UsageTarget.EMPTY_ARRAY, usages, presentation, null);
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
* Copyright 2000-2014 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.
@@ -279,7 +279,7 @@ public class SafeDeleteProcessor extends BaseRefactoringProcessor {
}
return manager.showUsages(targets,
UsageInfoToUsageConverter.convert(new UsageInfoToUsageConverter.TargetElementsDescriptor(myElements), usages),
UsageInfoToUsageConverter.convert(myElements, usages),
presentation
);
}
@@ -100,16 +100,15 @@ find.searching.for.string.in.file.occurrences.progress={0,choice,0#No|1#{0}} {0,
find.excessive.total.size.prompt=Usages in files of total size {0} found. {1} may become unresponsive or even fail with OutOfMemoryError if you continue. Continue?
find.progress.search.completed=Search completed
find.scope.project.title=Project
find.scope.module.title=Module {0}
find.scope.module.title=Module ''{0}''
find.scope.directory.title=Directory {0}
find.scope.files.with.mask={0} Files with mask {1}
find.usage.target.string.text=String ''{0}''
find.scope.files.with.mask=with mask ''{0}''
find.replace.invalid.replacement.string=You have entered malformed replacement string: ''{0}''
find.replace.invalid.replacement.string.title=Replace Error
find.highlight.no.more.highlights.found=No more highlights found
find.scope.all.project.classes=All Project Classes
find.usage.view.tab.text=Occurrences of ''{0}''
find.usage.view.toolwindow.title=Occurrences of ''{0}'' in ''{1}''
find.usage.view.toolwindow.title=Occurrences of ''{0}'' in {1}
find.usage.view.usages.text=occurrences of ''{0}''
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2013 JetBrains s.r.o.
* Copyright 2000-2014 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.
@@ -15,6 +15,12 @@
*/
package com.intellij.usages;
import com.intellij.openapi.actionSystem.KeyboardShortcut;
import org.jetbrains.annotations.NotNull;
public interface ConfigurableUsageTarget extends UsageTarget {
void showSettings();
KeyboardShortcut getShortcut();
@NotNull
String getLongDescriptiveName();
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
* Copyright 2000-2014 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.
@@ -39,7 +39,7 @@ public class FindUsagesProcessPresentation {
private boolean myShowNotFoundMessage;
private Factory<ProgressIndicator> myProgressIndicatorFactory;
private Collection<PsiFile> myLargeFiles;
private boolean myShowFindOptionsPrompt = true; // in the case of find in path, "find options" does not make sense
private boolean myShowFindOptionsPrompt = true;
public FindUsagesProcessPresentation() {
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2013 JetBrains s.r.o.
* Copyright 2000-2014 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.
@@ -20,6 +20,6 @@ import com.intellij.psi.PsiElement;
/**
* @author max
*/
public interface PsiElementUsageTarget extends ConfigurableUsageTarget {
public interface PsiElementUsageTarget extends UsageTarget {
PsiElement getElement();
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
* Copyright 2000-2014 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.
@@ -128,6 +128,11 @@ public class UsageInfoToUsageConverter {
public static Usage convert(@NotNull TargetElementsDescriptor descriptor, @NotNull UsageInfo usageInfo) {
PsiElement[] primaryElements = descriptor.getPrimaryElements();
return convert(primaryElements, usageInfo);
}
@NotNull
public static Usage convert(@NotNull PsiElement[] primaryElements, @NotNull UsageInfo usageInfo) {
PsiElement usageElement = usageInfo.getElement();
for(ReadWriteAccessDetector detector: Extensions.getExtensions(ReadWriteAccessDetector.EP_NAME)) {
if (isReadWriteAccessibleElements(primaryElements, detector)) {
@@ -149,6 +154,17 @@ public class UsageInfoToUsageConverter {
return usages;
}
@NotNull
public static Usage[] convert(@NotNull final PsiElement[] primaryElements, @NotNull UsageInfo[] usageInfos) {
Usage[] usages = ContainerUtil.map(usageInfos, new Function<UsageInfo, Usage>() {
@Override
public Usage fun(UsageInfo info) {
return convert(primaryElements, info);
}
}, new Usage[usageInfos.length]);
return usages;
}
private static boolean isReadWriteAccessibleElements(@NotNull PsiElement[] elements, @NotNull ReadWriteAccessDetector detector) {
if (elements.length == 0) {
return false;
@@ -755,13 +755,13 @@ public class UsageViewImpl implements UsageView, UsageModelTracker.UsageModelTra
return ActionManager.getInstance().getKeyboardShortcut("ShowSettingsAndFindUsages");
}
private static KeyboardShortcut getShowUsagesWithSettingsShortcut(@NotNull UsageTarget[] targets) {
//if (targets.length != 0) {
// NavigationItem target = targets[0];
// if (target instanceof ConfigurableUsageTarget) {
// return ((ConfigurableUsageTarget)target).getShortcut();
// }
//}
static KeyboardShortcut getShowUsagesWithSettingsShortcut(@NotNull UsageTarget[] targets) {
if (targets.length != 0) {
NavigationItem target = targets[0];
if (target instanceof ConfigurableUsageTarget) {
return ((ConfigurableUsageTarget)target).getShortcut();
}
}
return getShowUsagesWithSettingsShortcut();
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2013 JetBrains s.r.o.
* Copyright 2000-2014 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.
@@ -418,7 +418,7 @@ public class UsageViewManagerImpl extends UsageViewManager {
myPresentation.getScopeText());
if (notFoundActions.isEmpty()) {
String[] lines = myProcessPresentation.isShowFindOptionsPrompt() ? new String[] {StringUtil.escapeXml(message), createOptionsHtml()} : new String[]{StringUtil.escapeXml(message)};
String[] lines = myProcessPresentation.isShowFindOptionsPrompt() ? new String[] {StringUtil.escapeXml(message), createOptionsHtml(mySearchFor)} : new String[]{StringUtil.escapeXml(message)};
notifyByFindBalloon(createGotToOptionsListener(mySearchFor),
MessageType.INFO, myProcessPresentation, UsageViewManagerImpl.this.myProject, lines);
findStartedBalloonShown.set(false);
@@ -453,7 +453,8 @@ public class UsageViewManagerImpl extends UsageViewManager {
flashUsageScriptaculously(usage);
}
notifyByFindBalloon(createGotToOptionsListener(mySearchFor),
MessageType.INFO, myProcessPresentation, UsageViewManagerImpl.this.myProject,"Only one usage found.", createOptionsHtml());
MessageType.INFO, myProcessPresentation, UsageViewManagerImpl.this.myProject,"Only one usage found.", createOptionsHtml(
mySearchFor));
}
}, ModalityState.NON_MODAL, myProject.getDisposed());
}
@@ -593,9 +594,9 @@ public class UsageViewManagerImpl extends UsageViewManager {
}
@NotNull
private static String createOptionsHtml() {
private static String createOptionsHtml(@NonNls UsageTarget[] searchFor) {
KeyboardShortcut shortcut = UsageViewImpl.getShowUsagesWithSettingsShortcut(searchFor);
String shortcutText = "";
KeyboardShortcut shortcut = UsageViewImpl.getShowUsagesWithSettingsShortcut();
if (shortcut != null) {
shortcutText = "&nbsp;(" + KeymapUtil.getShortcutText(shortcut) + ")";
}