Merge commit 'origin/master'

This commit is contained in:
sweinreuter
2012-08-22 11:10:42 +02:00
26 changed files with 755 additions and 346 deletions
@@ -192,13 +192,21 @@ public abstract class FindManager {
public abstract boolean canFindUsages(@NotNull PsiElement element);
/**
* Shows the Find Usages dialog and performs the Find Usages operation for the
* specified element.
* Performs the Find Usages operation for the specified element.
*
* @param element the element to find the usages for.
*/
public abstract void findUsages(@NotNull PsiElement element);
/**
* Shows the Find Usages dialog (if {@code showDialog} is true} and performs the Find Usages operation for the
* specified element.
*
* @param element the element to find the usages for.
* @param showDialog true if find usages settings dialog needs to be shown.
*/
public abstract void findUsages(@NotNull PsiElement element, boolean showDialog);
/**
* Performs a "Find Usages in File" operation for the specified element.
*
@@ -143,7 +143,7 @@ public class TargetElementUtilBase {
return result;
}
public static boolean inVirtualSpace(Editor editor, int offset) {
public static boolean inVirtualSpace(@NotNull Editor editor, int offset) {
if (offset == editor.getCaretModel().getOffset()) {
return EditorUtil.inVirtualSpace(editor, editor.getCaretModel().getLogicalPosition());
}
@@ -48,12 +48,17 @@ public final class NavigationUtil {
private NavigationUtil() {
}
public static JBPopup getPsiElementPopup(PsiElement[] elements, String title) {
@NotNull
public static JBPopup getPsiElementPopup(@NotNull PsiElement[] elements, String title) {
return getPsiElementPopup(elements, new DefaultPsiElementCellRenderer(), title);
}
public static JBPopup getPsiElementPopup(final PsiElement[] elements, final PsiElementListCellRenderer<PsiElement> renderer, final String title) {
@NotNull
public static JBPopup getPsiElementPopup(@NotNull PsiElement[] elements,
@NotNull final PsiElementListCellRenderer<PsiElement> renderer,
final String title) {
return getPsiElementPopup(elements, renderer, title, new PsiElementProcessor<PsiElement>() {
@Override
public boolean execute(@NotNull final PsiElement element) {
Navigatable descriptor = EditSourceUtil.getDescriptor(element);
if (descriptor != null && descriptor.canNavigate()) {
@@ -64,15 +69,19 @@ public final class NavigationUtil {
});
}
public static <T extends PsiElement> JBPopup getPsiElementPopup(final T[] elements, final PsiElementListCellRenderer<T> renderer,
final String title, final PsiElementProcessor<T> processor) {
@NotNull
public static <T extends PsiElement> JBPopup getPsiElementPopup(@NotNull T[] elements,
@NotNull final PsiElementListCellRenderer<T> renderer,
final String title,
@NotNull final PsiElementProcessor<T> processor) {
return getPsiElementPopup(elements, renderer, title, processor, null);
}
public static <T extends PsiElement> JBPopup getPsiElementPopup(final T[] elements,
final PsiElementListCellRenderer<T> renderer,
final String title,
final PsiElementProcessor<T> processor,
@NotNull
public static <T extends PsiElement> JBPopup getPsiElementPopup(@NotNull T[] elements,
@NotNull final PsiElementListCellRenderer<T> renderer,
@Nullable final String title,
@NotNull final PsiElementProcessor<T> processor,
@Nullable final T selection) {
final JList list = new JBList(elements);
list.setCellRenderer(renderer);
@@ -81,6 +90,7 @@ public final class NavigationUtil {
}
final Runnable runnable = new Runnable() {
@Override
public void run() {
int[] ids = list.getSelectedIndices();
if (ids == null || ids.length == 0) return;
@@ -116,7 +126,8 @@ public final class NavigationUtil {
if (searchForOpen) {
elt.putUserData(FileEditorManager.USE_CURRENT_WINDOW, null);
} else {
}
else {
elt.putUserData(FileEditorManager.USE_CURRENT_WINDOW, true);
}
@@ -130,11 +141,9 @@ public final class NavigationUtil {
}
private static boolean activatePsiElementIfOpen(@NotNull PsiElement elt, boolean searchForOpen) {
if (!elt.isValid()) return false;
elt = elt.getNavigationElement();
if (elt == null) return false;
final PsiFile file = elt.getContainingFile();
if (file == null || !file.isValid()) return false;
@@ -124,11 +124,11 @@ public class GotoDeclarationAction extends BaseCodeInsightAction implements Code
}
// returns true if processor is run or is going to be run after showing popup
public static boolean chooseAmbiguousTarget(final Editor editor,
public static boolean chooseAmbiguousTarget(@NotNull Editor editor,
int offset,
PsiElementProcessor<PsiElement> processor,
String titlePattern,
PsiElement[] elements) {
@NotNull PsiElementProcessor<PsiElement> processor,
@NotNull String titlePattern,
@Nullable PsiElement[] elements) {
if (TargetElementUtilBase.inVirtualSpace(editor, offset)) {
return false;
}
@@ -149,16 +149,16 @@ public class GotoDeclarationAction extends BaseCodeInsightAction implements Code
if (elements.length > 1) {
String title;
if (reference != null) {
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));
final String refText = range.substring(elementText);
title = MessageFormat.format(titlePattern, refText);
}
else {
title = titlePattern;
}
NavigationUtil.getPsiElementPopup(elements, new DefaultPsiElementCellRenderer(), title, processor).showInBestPositionFor(editor);
return true;
@@ -35,7 +35,7 @@ public class FindBundle {
private FindBundle() {
}
public static String message(@PropertyKey(resourceBundle = BUNDLE)String key, Object... params) {
public static String message(@PropertyKey(resourceBundle = BUNDLE) String key, Object... params) {
return CommonBundle.message(getBundle(), key, params);
}
@@ -0,0 +1,49 @@
/*
* Copyright 2000-2012 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.actions;
import com.intellij.ui.ActiveComponent;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
import java.awt.*;
class CompositeActiveComponent implements ActiveComponent {
private final ActiveComponent[] myComponents;
private final JPanel myComponent;
public CompositeActiveComponent(@NotNull ActiveComponent... components) {
myComponents = components;
myComponent = new JPanel(new FlowLayout());
myComponent.setOpaque(false);
for (ActiveComponent component : components) {
myComponent.add(component.getComponent());
}
}
@Override
public void setActive(boolean active) {
for (ActiveComponent component : myComponents) {
component.setActive(active);
}
}
@Override
public JComponent getComponent() {
return myComponent;
}
}
@@ -20,6 +20,7 @@ import com.intellij.CommonBundle;
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;
@@ -30,6 +31,7 @@ import com.intellij.openapi.ui.Messages;
import com.intellij.psi.PsiDocumentManager;
import com.intellij.psi.PsiElement;
import com.intellij.psi.search.PsiElementProcessor;
import com.intellij.usages.PsiElementUsageTarget;
import com.intellij.usages.UsageTarget;
import com.intellij.usages.UsageView;
import org.jetbrains.annotations.NotNull;
@@ -50,7 +52,11 @@ public class FindUsagesAction extends AnAction {
UsageTarget[] usageTargets = e.getData(UsageView.USAGE_TARGETS_KEY);
if (usageTargets != null) {
usageTargets[0].findUsages();
UsageTarget target = usageTargets[0];
if (target instanceof PsiElementUsageTarget) {
PsiElement element = ((PsiElementUsageTarget)target).getElement();
startFindUsages(element);
}
return;
}
@@ -58,19 +64,24 @@ public class FindUsagesAction extends AnAction {
chooseAmbiguousTargetAndPerform(project, editor, new PsiElementProcessor<PsiElement>() {
@Override
public boolean execute(@NotNull final PsiElement element) {
new PsiElement2UsageTargetAdapter(element).findUsages();
startFindUsages(element);
return false;
}
});
}
protected void startFindUsages(@NotNull PsiElement element) {
new PsiElement2UsageTargetAdapter(element).findUsages();
}
@Override
public void update(AnActionEvent event){
FindUsagesInFileAction.updateFindUsagesAction(event);
}
static void chooseAmbiguousTargetAndPerform(@NotNull final Project project, final Editor editor,
PsiElementProcessor<PsiElement> processor) {
static void chooseAmbiguousTargetAndPerform(@NotNull final Project project,
Editor editor,
@NotNull PsiElementProcessor<PsiElement> processor) {
if (editor == null) {
Messages.showMessageDialog(project, FindBundle.message("find.no.usages.at.cursor.error"), CommonBundle.getErrorTitle(),
Messages.getErrorIcon());
@@ -83,5 +94,11 @@ public class FindUsagesAction extends AnAction {
}
}
}
public static class ShowSettingsAndFindUsages extends FindUsagesAction {
@Override
protected void startFindUsages(@NotNull PsiElement element) {
FindManager.getInstance(element.getProject()).findUsages(element, true);
}
}
}
@@ -101,7 +101,7 @@ public class FindUsagesInFileAction extends AnAction {
Presentation presentation = event.getPresentation();
DataContext dataContext = event.getDataContext();
boolean enabled = isEnabled(dataContext);
presentation.setVisible(ActionPlaces.isPopupPlace(event.getPlace()) ? enabled : true);
presentation.setVisible(enabled || !ActionPlaces.isPopupPlace(event.getPlace()));
presentation.setEnabled(enabled);
}
}
@@ -0,0 +1,107 @@
/*
* Copyright 2000-2012 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.actions;
import com.intellij.openapi.util.Condition;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
import java.util.concurrent.atomic.AtomicBoolean;
/**
* Runs activity in the EDT.
* To schedule activity, call {@link #ping()}. It sets the flag telling that the activity should be run. Once it has run, the flag is cleared.
* So you can call ping() several times, but the activity will be executed only once.
* If activity took more than {@code maxUnitOfWorkThresholdMs} ms, it will yield till the next invokeLater.
*/
class PingEDT {
@SuppressWarnings({"FieldCanBeLocal", "UnusedDeclaration"})
private final String myName;
private final Runnable pingAction;
private volatile boolean stopped;
private volatile boolean pinged;
private final Condition<?> myShutUpCondition;
private final int myMaxUnitOfWorkThresholdMs; //-1 means indefinite
private final AtomicBoolean invokeLaterScheduled = new AtomicBoolean();
private final Runnable myUpdateRunnable = new Runnable() {
@Override
public void run() {
boolean b = invokeLaterScheduled.compareAndSet(true, false);
assert b;
if (stopped || myShutUpCondition.value(null)) {
stop();
return;
}
long start = System.currentTimeMillis();
int processed = 0;
while (true) {
if (processNext()) {
processed++;
}
else {
break;
}
long finish = System.currentTimeMillis();
if (myMaxUnitOfWorkThresholdMs != -1 && finish - start > myMaxUnitOfWorkThresholdMs) break;
}
if (!isEmpty()) {
scheduleUpdate();
}
}
};
public PingEDT(@NotNull @NonNls String name,
@NotNull Condition<?> shutUpCondition,
int maxUnitOfWorkThresholdMs,
@NotNull Runnable pingAction) {
myName = name;
myShutUpCondition = shutUpCondition;
myMaxUnitOfWorkThresholdMs = maxUnitOfWorkThresholdMs;
this.pingAction = pingAction;
}
private boolean isEmpty() {
return !pinged;
}
private boolean processNext() {
pinged = false;
pingAction.run();
return pinged;
}
public boolean ping() {
pinged = true;
scheduleUpdate();
return true;
}
private void scheduleUpdate() {
if (!stopped && invokeLaterScheduled.compareAndSet(false, true)) {
schedule(myUpdateRunnable);
}
}
protected void schedule(@NotNull Runnable updateRunnable) {
SwingUtilities.invokeLater(updateRunnable);
}
public void stop() {
stopped = true;
}
}
@@ -26,12 +26,13 @@ import com.intellij.icons.AllIcons;
import com.intellij.ide.DataManager;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.actionSystem.ex.ActionManagerEx;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.fileEditor.FileEditor;
import com.intellij.openapi.fileEditor.FileEditorLocation;
import com.intellij.openapi.fileEditor.TextEditor;
import com.intellij.openapi.keymap.KeymapUtil;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.project.DumbAwareAction;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.ProjectFileIndex;
@@ -39,6 +40,7 @@ import com.intellij.openapi.ui.popup.JBPopup;
import com.intellij.openapi.ui.popup.JBPopupFactory;
import com.intellij.openapi.ui.popup.PopupChooserBuilder;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.Condition;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.wm.IdeFocusManager;
@@ -49,14 +51,17 @@ import com.intellij.psi.search.PsiElementProcessor;
import com.intellij.psi.search.SearchScope;
import com.intellij.ui.*;
import com.intellij.ui.awt.RelativePoint;
import com.intellij.ui.popup.AbstractPopup;
import com.intellij.usageView.UsageViewBundle;
import com.intellij.usages.*;
import com.intellij.usages.impl.*;
import com.intellij.usages.rules.UsageFilteringRuleProvider;
import com.intellij.util.Alarm;
import com.intellij.util.ArrayUtil;
import com.intellij.util.PlatformIcons;
import com.intellij.util.Processor;
import com.intellij.util.messages.MessageBusConnection;
import com.intellij.util.ui.AsyncProcessIcon;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -72,24 +77,27 @@ import java.util.List;
public class ShowUsagesAction extends AnAction implements PopupAction {
private final boolean showSettingsDialogBefore;
private static final int USAGES_PAGE_SIZE = 100;
private static final Comparator<Object> USAGE_COMPARATOR = new Comparator<Object>() {
static final NullUsage MORE_USAGES_SEPARATOR = NullUsage.INSTANCE;
private static final UsageNode MORE_USAGES_SEPARATOR_NODE = UsageViewImpl.NULL_NODE;
private static final Comparator<Object> USAGE_NODE_COMPARATOR = new Comparator<Object>() {
@Override
public int compare(Object c1, Object c2) {
if (!(c1 instanceof UsageNode)) return 1;
if (!(c2 instanceof UsageNode)) return -1;
Usage o1 = ((UsageNode)c1).getUsage();
Usage o2 = ((UsageNode)c2).getUsage();
if (o1 == NullUsage.INSTANCE) return 1;
if (o2 == NullUsage.INSTANCE) return -1;
if (o1 == MORE_USAGES_SEPARATOR) return 1;
if (o2 == MORE_USAGES_SEPARATOR) return -1;
VirtualFile v1 = UsageListCellRenderer.getVirtualFile(o1);
VirtualFile v2 = UsageListCellRenderer.getVirtualFile(o2);
String name1 = v1 == null ? null : v1.getName();
String name2 = v2 == null ? null : v2.getName();
int i = Comparing.compare(name1, name2);
if (i!=0) return i;
if (i != 0) return i;
if (o1 instanceof Comparable && o2 instanceof Comparable) {
return ((Comparable)o1).compareTo(o2);
@@ -129,11 +137,6 @@ public class ShowUsagesAction extends AnAction implements PopupAction {
myUsageViewSettings.GROUP_BY_SCOPE = false;
}
public static class ShowSettings extends ShowUsagesAction {
public ShowSettings() {
super(true);
}
}
@Override
public void actionPerformed(@NotNull AnActionEvent e) {
@@ -149,7 +152,6 @@ public class ShowUsagesAction extends AnAction implements PopupAction {
return;
}
myWidth = -1;
final RelativePoint popupPosition = JBPopupFactory.getInstance().guessBestPopupLocation(e.getDataContext());
PsiDocumentManager.getInstance(project).commitAllDocuments();
FeatureUsageTracker.getInstance().triggerFeatureUsed("navigation.goto.usages");
@@ -199,16 +201,17 @@ public class ShowUsagesAction extends AnAction implements PopupAction {
@NotNull final RelativePoint popupPosition,
final int maxUsages,
@NotNull final FindUsagesOptions options) {
UsageViewPresentation presentation = new UsageViewPresentation();
presentation.setDetachedMode(true);
final UsageViewSettings usageViewSettings = UsageViewSettings.getInstance();
final UsageViewSettings savedGlobalSettings = new UsageViewSettings();
savedGlobalSettings.loadState(usageViewSettings);
usageViewSettings.loadState(myUsageViewSettings);
UsageViewManager manager = UsageViewManager.getInstance(handler.getProject());
final Project project = handler.getProject();
UsageViewManager manager = UsageViewManager.getInstance(project);
FindUsagesManager findUsagesManager = ((FindManagerImpl)FindManager.getInstance(project)).getFindUsagesManager();
final UsageViewPresentation presentation = findUsagesManager.createPresentation(handler, options);
presentation.setDetachedMode(true);
final UsageViewImpl usageView = (UsageViewImpl)manager.createUsageView(UsageTarget.EMPTY_ARRAY, Usage.EMPTY_ARRAY, presentation, null);
Disposer.register(usageView, new Disposable() {
@@ -221,42 +224,131 @@ public class ShowUsagesAction extends AnAction implements PopupAction {
final List<Usage> usages = new ArrayList<Usage>();
final Set<UsageNode> visibleNodes = new LinkedHashSet<UsageNode>();
final MyTable table = new MyTable();
final AsyncProcessIcon processIcon = new AsyncProcessIcon("xxx");
final JBPopup popup = createUsagePopup(usages, visibleNodes, handler, editor, popupPosition, maxUsages, usageView, options, table, presentation,
processIcon);
Disposer.register(popup, usageView);
// show popup only if find usages takes more than 300ms, otherwise it would flicker needlessly
Alarm alarm = new Alarm(usageView);
alarm.addRequest(new Runnable() {
@Override
public void run() {
showPopupIfNeedTo(popup, popupPosition);
}
}, 300);
final PingEDT pingEDT = new PingEDT("Rebuild popup in EDT", new Condition<Object>() {
@Override
public boolean value(Object o) {
return popup.isDisposed();
}
}, 1000, new Runnable() {
@Override
public void run() {
rebuildPopup(usageView, usages, table, popup, presentation, popupPosition);
}
});
final MessageBusConnection messageBusConnection = project.getMessageBus().connect(usageView);
messageBusConnection.subscribe(UsageFilteringRuleProvider.RULES_CHANGED, new Runnable() {
@Override
public void run() {
pingEDT.ping();
}
});
Processor<Usage> collect = new Processor<Usage>() {
private final UsageTarget[] myUsageTarget = {new PsiElement2UsageTargetAdapter(handler.getPsiElement())};
@Override
public boolean process(@NotNull Usage usage) {
synchronized (usages) {
if (visibleNodes.size() > maxUsages) return false;
if (visibleNodes.size() >= maxUsages) return false;
if(UsageViewManager.isSelfUsage(usage, myUsageTarget)) return true;
UsageNode node = usageView.doAppendUsage(usage);
if (node != null) {
if (visibleNodes.size() == maxUsages) {
usageView.removeUsage(usage);
visibleNodes.add(UsageViewImpl.NULL_NODE);
return false;
}
visibleNodes.add(node);
}
usages.add(usage);
if (node != null) {
visibleNodes.add(node);
boolean continueSearch = true;
if (visibleNodes.size() == maxUsages) {
visibleNodes.add(MORE_USAGES_SEPARATOR_NODE);
usages.add(MORE_USAGES_SEPARATOR);
continueSearch = false;
}
pingEDT.ping();
//rebuildPopup(usageView, usages, table, popup, presentation, popupPosition);
return continueSearch;
}
}
return true;
}
};
FindUsagesManager findUsagesManager = ((FindManagerImpl)FindManager.getInstance(handler.getProject())).getFindUsagesManager();
presentation = findUsagesManager.processUsages(handler, collect, options);
if (presentation == null) {
Disposer.dispose(usageView);
return;
}
final String title = presentation.getTabText();
JBPopup popup = createUsagePopup(usages, visibleNodes, title, handler, editor, popupPosition, maxUsages, usageView, options);
if (popup == null) {
Disposer.dispose(usageView);
final ProgressIndicator indicator = FindUsagesManager.startProcessUsages(handler, collect, options, new Runnable() {
@Override
public void run() {
ApplicationManager.getApplication().invokeLater(new Runnable() {
@Override
public void run() {
Disposer.dispose(processIcon);
Container parent = processIcon.getParent();
parent.remove(processIcon);
parent.repaint();
synchronized (usages) {
if (visibleNodes.isEmpty()) {
if (usages.isEmpty()) {
String text = UsageViewBundle.message("no.usages.found.in", searchScopePresentableName(options, project));
showHint(text, editor, popupPosition, handler, maxUsages, options);
popup.cancel();
}
else {
// all usages filtered out
}
}
else if (visibleNodes.size() == 1) {
if (usages.size() == 1) {
//the only usage
Usage usage = visibleNodes.iterator().next().getUsage();
String message = UsageViewBundle.message("show.usages.only.usage", searchScopePresentableName(options, project));
navigateAndHint(usage, message, handler, popupPosition, maxUsages, options);
popup.cancel();
}
else {
assert usages.size() > 1 : usages;
// usage view can filter usages down to one
Usage visibleUsage = visibleNodes.iterator().next().getUsage();
if (areAllUsagesInOneLine(visibleUsage, usages)) {
String hint = UsageViewBundle.message("all.usages.are.in.this.line", usages.size(), searchScopePresentableName(options, project));
navigateAndHint(visibleUsage, hint, handler, popupPosition, maxUsages, options);
popup.cancel();
}
}
}
}
}
}, project.getDisposed());
}
});
Disposer.register(popup, new Disposable() {
@Override
public void dispose() {
indicator.cancel();
}
});
}
private static boolean showPopupIfNeedTo(@NotNull JBPopup popup, @NotNull RelativePoint popupPosition) {
if (!popup.isDisposed() && !popup.isVisible()) {
popup.show(popupPosition);
return true;
}
else {
Disposer.register(popup, usageView);
popup.show(popupPosition);
return false;
}
}
@@ -284,7 +376,7 @@ public class ShowUsagesAction extends AnAction implements PopupAction {
@NotNull final Runnable cancelAction,
final int maxUsages,
@NotNull final FindUsagesOptions options) {
JComponent label = HintUtil.createInformationLabel(suggestSecondInvocation(options, handler, text));
JComponent label = HintUtil.createInformationLabel(suggestSecondInvocation(options, handler, text+"&nbsp;"));
InplaceButton button = createSettingsButton(handler, popupPosition, editor, maxUsages, cancelAction);
JPanel panel = new JPanel(new BorderLayout()) {
@@ -363,71 +455,52 @@ public class ShowUsagesAction extends AnAction implements PopupAction {
return scope;
}
@Nullable
@NotNull
private JBPopup createUsagePopup(@NotNull final List<Usage> usages,
@NotNull Set<UsageNode> visibleNodes,
@Nullable final String title,
@NotNull final FindUsagesHandler handler,
final Editor editor,
@NotNull final RelativePoint popupPosition,
final int maxUsages,
@NotNull final UsageViewImpl usageView,
@NotNull final FindUsagesOptions options) {
boolean hasMore = visibleNodes.remove(UsageViewImpl.NULL_NODE);
@NotNull final FindUsagesOptions options,
@NotNull final JTable table,
@NotNull final UsageViewPresentation presentation,
@NotNull final AsyncProcessIcon processIcon) {
final String title = presentation.getTabText();
boolean hadMoreSeparator = visibleNodes.remove(MORE_USAGES_SEPARATOR_NODE);
final Project project = handler.getProject();
if (visibleNodes.isEmpty()) {
if (usages.isEmpty()) {
String text = UsageViewBundle.message("no.usages.found.in", searchScopePresentableName(options, project));
showHint(text, editor, popupPosition, handler, maxUsages, options);
return null;
}
else {
// all usages filtered out
}
}
if (visibleNodes.size() == 1 && usages.size() == 1) {
//the only usage
Usage usage = visibleNodes.iterator().next().getUsage();
navigateAndHint(usage, UsageViewBundle.message("show.usages.only.usage",
searchScopePresentableName(options, project)), handler, popupPosition,
maxUsages, options);
return null;
}
if (visibleNodes.size() == 1 && usages.size() >= 1) {
// usage view can filter usages down to one
Usage usage = visibleNodes.iterator().next().getUsage();
if (areAllUsagesInThisLine(usage, usages)) {
String hint = UsageViewBundle.message("all.usages.are.in.this.line", usages.size(),
searchScopePresentableName(options, project));
navigateAndHint(usage, hint, handler, popupPosition, maxUsages, options);
return null;
}
}
if (hasMore) {
usages.add(NullUsage.INSTANCE);
visibleNodes.add(UsageViewImpl.NULL_NODE);
if (hadMoreSeparator) {
usages.add(MORE_USAGES_SEPARATOR);
visibleNodes.add(MORE_USAGES_SEPARATOR_NODE);
}
List<UsageNode> outNodes = new ArrayList<UsageNode>();
addUsageNodes(usageView.getRoot(), usageView, outNodes);
int filtered = filtered(usages, usageView);
final JTable table = new MyTable();
TableScrollingUtil.installActions(table);
final Vector<Object> data = new Vector<Object>();
setModel(table, visibleNodes, usageView, data, filtered);
setTableModel(table, visibleNodes, usageView, data, filtered, presentation);
table.setRowHeight(PlatformIcons.CLASS_ICON.getIconHeight()+2);
table.setShowGrid(false);
table.setShowVerticalLines(false);
table.setShowHorizontalLines(false);
table.setTableHeader(null);
table.setAutoResizeMode(JTable.AUTO_RESIZE_LAST_COLUMN);
table.setIntercellSpacing(new Dimension(0, 0));
final Runnable navigateRunnable = new Runnable() {
@Override
public void run() {
int[] selected = table.getSelectedRows();
for (int i : selected) {
Object value = table.getValueAt(i,0);
Object value = table.getValueAt(i, 0);
if (value instanceof UsageNode) {
Usage usage = ((UsageNode)value).getUsage();
if (usage == NullUsage.INSTANCE) {
if (usage == MORE_USAGES_SEPARATOR) {
appendMoreUsages(editor, popupPosition, handler, maxUsages);
return;
}
@@ -460,7 +533,7 @@ public class ShowUsagesAction extends AnAction implements PopupAction {
UsageNode node = (UsageNode)element;
GroupNode group = (GroupNode)node.getParent();
Usage usage = node.getUsage();
if (usage == NullUsage.INSTANCE) return "";
if (usage == MORE_USAGES_SEPARATOR) return "";
return usage.getPresentation().getPlainText() + group.toString();
}
@@ -476,14 +549,8 @@ public class ShowUsagesAction extends AnAction implements PopupAction {
PopupChooserBuilder builder = new PopupChooserBuilder(table);
if (title != null) {
String s;
if (hasMore) {
s = "<b>Some</b> " + title + " " + "<b>(Only " + (visibleNodes.size() - 1) + " usages shown)</b>";
}
else {
s = title + " (" + UsageViewBundle.message("usages.n", usages.size()) + " found)";
}
builder.setTitle("<html>" + s + "</html>");
String result = getFullTitle(usages, title, hadMoreSeparator, visibleNodes.size() - 1);
builder.setTitle(result);
builder.setAdText(getSecondInvocationTitle(options, handler));
}
@@ -518,7 +585,18 @@ public class ShowUsagesAction extends AnAction implements PopupAction {
popup[0].cancel();
}
});
builder.setCommandButton(button);
ActiveComponent iconComp = new ActiveComponent() {
@Override
public void setActive(boolean active) {
}
@Override
public JComponent getComponent() {
return processIcon;
}
};
builder.setCommandButton(new CompositeActiveComponent(iconComp, button));
DefaultActionGroup toolbar = new DefaultActionGroup();
usageView.addFilteringActions(toolbar);
@@ -549,22 +627,32 @@ public class ShowUsagesAction extends AnAction implements PopupAction {
builder.setSettingButton(toolBar);
popup[0] = builder.createPopup();
JComponent content = popup[0].getContent();
myWidth = (int)(toolBar.getPreferredSize().getWidth()
+ new JLabel(getFullTitle(usages, title, hadMoreSeparator, visibleNodes.size() - 1)).getPreferredSize().getWidth()
+ button.getPreferredSize().getWidth());
myWidth = -1;
for (AnAction action : toolbar.getChildren(null)) {
action.unregisterCustomShortcutSet(usageView.getComponent());
action.registerCustomShortcutSet(action.getShortcutSet(), popup[0].getContent());
action.registerCustomShortcutSet(action.getShortcutSet(), content);
}
final MessageBusConnection messageBusConnection = project.getMessageBus().connect(usageView);
messageBusConnection.subscribe(UsageFilteringRuleProvider.RULES_CHANGED, new Runnable() {
@Override
public void run() {
rebuildPopup(usageView, usages, table, popup[0]);
}
});
return popup[0];
}
@NotNull
private static String getFullTitle(@NotNull List<Usage> usages, @NotNull String title, boolean hadMoreSeparator, int visibleNodesCount) {
String s;
if (hadMoreSeparator) {
s = "<b>Some</b> " + title + " " + "<b>(Only " + visibleNodesCount + " usages shown)</b>";
}
else {
s = title + " (" + UsageViewBundle.message("usages.n", usages.size()) + ")";
}
return "<html><nobr>" + s + "</nobr></html>";
}
@NotNull
private static GlobalSearchScope getMaximalScope(@NotNull FindUsagesHandler handler) {
PsiElement element = handler.getPsiElement();
@@ -591,8 +679,7 @@ public class ShowUsagesAction extends AnAction implements PopupAction {
if (getShowUsagesShortcut() != null) {
GlobalSearchScope maximalScope = getMaximalScope(handler);
if (!notNullizeScope(options, handler.getProject()).equals(maximalScope)) {
return "Press " + KeymapUtil.getShortcutText(getShowUsagesShortcut()) +
" again to search in " + maximalScope.getDisplayName();
return "Press " + KeymapUtil.getShortcutText(getShowUsagesShortcut()) + " again to search in " + maximalScope.getDisplayName();
}
}
return null;
@@ -610,7 +697,7 @@ public class ShowUsagesAction extends AnAction implements PopupAction {
@Nullable
private static KeyboardShortcut getShowUsagesShortcut() {
return ActionManagerEx.getInstanceEx().getKeyboardShortcut("ShowUsages");
return ActionManager.getInstance().getKeyboardShortcut("ShowUsages");
}
private static int filtered(@NotNull List<Usage> usages, @NotNull UsageViewImpl usageView) {
@@ -628,10 +715,10 @@ public class ShowUsagesAction extends AnAction implements PopupAction {
return element.getTextRange().getStartOffset();
}
private static boolean areAllUsagesInThisLine(@NotNull Usage usage, @NotNull List<Usage> usages) {
Editor editor = getEditorFor(usage);
private static boolean areAllUsagesInOneLine(@NotNull Usage visibleUsage, @NotNull List<Usage> usages) {
Editor editor = getEditorFor(visibleUsage);
if (editor == null) return false;
int offset = getUsageOffset(usage);
int offset = getUsageOffset(visibleUsage);
if (offset == -1) return false;
int lineNumber = editor.getDocument().getLineNumber(offset);
for (Usage other : usages) {
@@ -645,16 +732,22 @@ public class ShowUsagesAction extends AnAction implements PopupAction {
return true;
}
private static int setModel(@NotNull JTable table,
@NotNull Collection<UsageNode> visibleNodes,
@NotNull UsageViewImpl usageView,
@NotNull final Vector<Object> data,
int filtered) {
private static int setTableModel(@NotNull JTable table,
@NotNull Collection<UsageNode> visibleNodes,
@NotNull UsageViewImpl usageView,
@NotNull final Vector<Object> data,
int filtered,
@NotNull UsageViewPresentation presentation) {
ApplicationManager.getApplication().assertIsDispatchThread();
if (filtered != 0) {
data.add(UsageViewBundle.message("usages.were.filtered.out", filtered));
}
data.addAll(visibleNodes);
Collections.sort(data, USAGE_COMPARATOR);
if (data.isEmpty()) {
String progressText = UsageViewManagerImpl.getProgressTitle(presentation);
data.add(progressText);
}
Collections.sort(data, USAGE_NODE_COMPARATOR);
AbstractTableModel model = new AbstractTableModel() {
@Override
public int getRowCount() {
@@ -673,18 +766,11 @@ public class ShowUsagesAction extends AnAction implements PopupAction {
};
table.setModel(model);
table.setRowHeight(PlatformIcons.CLASS_ICON.getIconHeight()+2);
table.setShowGrid(false);
table.setShowVerticalLines(false);
table.setShowHorizontalLines(false);
table.setTableHeader(null);
table.setAutoResizeMode(JTable.AUTO_RESIZE_LAST_COLUMN);
ShowUsagesTableCellRenderer renderer = new ShowUsagesTableCellRenderer(usageView);
for (int i=0;i<table.getColumnModel().getColumnCount();i++) {
TableColumn column = table.getColumnModel().getColumn(i);
column.setCellRenderer(renderer);
}
table.setIntercellSpacing(new Dimension(0, 0));
int colsNum = table.getColumnModel().getColumnCount();
@@ -702,13 +788,6 @@ public class ShowUsagesAction extends AnAction implements PopupAction {
totalWidth += calcMaxWidth(table, colsNum - 1);
Dimension dimension = new Dimension(totalWidth, table.getRowHeight() * data.size());
table.setMinimumSize(dimension);
table.setSize(dimension);
table.setPreferredSize(dimension);
table.setMaximumSize(dimension);
table.setPreferredScrollableViewportSize(dimension);
return totalWidth;
}
@@ -729,33 +808,88 @@ public class ShowUsagesAction extends AnAction implements PopupAction {
private void rebuildPopup(@NotNull final UsageViewImpl usageView,
@NotNull final List<Usage> usages,
@NotNull final JTable table,
@NotNull final JBPopup popup) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
JComponent content = popup.getContent();
Window window = SwingUtilities.windowForComponent(content);
Dimension d = window.getSize();
@NotNull final JBPopup popup,
@NotNull final UsageViewPresentation presentation,
@NotNull final RelativePoint popupPosition) {
ApplicationManager.getApplication().assertIsDispatchThread();
if (popup.isDisposed()) return;
final List<UsageNode> nodes = new ArrayList<UsageNode>();
addUsageNodes(usageView.getRoot(), usageView, nodes);
int filtered = filtered(usages, usageView);
int old = table.getModel().getRowCount();
Vector<Object> data = new Vector<Object>();
int width = setModel(table, nodes, usageView, data, filtered);
if (myWidth == -1) myWidth = width;
Dimension newDim = new Dimension(Math.max(width, d.width + width - myWidth), d.height + (data.size() - old) * table.getRowHeight());
myWidth = width;
window.setSize(newDim);
window.validate();
window.repaint();
table.revalidate();
table.repaint();
final List<UsageNode> nodes = new ArrayList<UsageNode>();
int filtered;
String fullTitle;
synchronized (usages) {
// open up popup as soon as several usages 've been found
if (!popup.isVisible() && (usages.size() <= 1 || !showPopupIfNeedTo(popup, popupPosition))) {
return;
}
});
addUsageNodes(usageView.getRoot(), usageView, nodes);
boolean shouldShowMoreSeparator = usages.contains(MORE_USAGES_SEPARATOR);
if (shouldShowMoreSeparator) {
nodes.add(MORE_USAGES_SEPARATOR_NODE);
}
filtered = filtered(usages, usageView);
String title = presentation.getTabText();
fullTitle = getFullTitle(usages, title, shouldShowMoreSeparator, nodes.size() - (shouldShowMoreSeparator ? 1 : 0));
}
((AbstractPopup)popup).setCaption(fullTitle);
JComponent content = popup.getContent();
Window window = SwingUtilities.windowForComponent(content);
Dimension d = window.getSize();
Vector<Object> data = new Vector<Object>();
int width = setTableModel(table, nodes, usageView, data, filtered, presentation);
width = (int)Math.max(d.getWidth(), width);
Dimension headerSize = ((AbstractPopup)popup).getHeaderPreferredSize();
width = Math.max((int)headerSize.getWidth(), width);
width = Math.max(myWidth, width);
if (myWidth == -1) myWidth = width;
int newWidth = Math.max(width, d.width + width - myWidth);
myWidth = newWidth;
int rowsToShow = Math.min(30, data.size());
Dimension dimension = new Dimension(newWidth, table.getRowHeight() * rowsToShow);
Rectangle rectangle = fitToScreen(dimension, popupPosition, table);
dimension = rectangle.getSize();
Point location = window.getLocation();
if (!location.equals(rectangle.getLocation())) {
window.setLocation(rectangle.getLocation());
}
table.setSize(dimension);
//table.setPreferredSize(dimension);
//table.setMaximumSize(dimension);
//table.setPreferredScrollableViewportSize(dimension);
Dimension footerSize = ((AbstractPopup)popup).getFooterPreferredSize();
int newHeight = (int)(dimension.height + headerSize.getHeight() + footerSize.getHeight()) + 4/* invisible borders, margins etc*/;
Dimension newDim = new Dimension(dimension.width, newHeight);
window.setSize(newDim);
window.setMinimumSize(newDim);
window.setMaximumSize(newDim);
window.validate();
window.repaint();
table.revalidate();
table.repaint();
}
private static Rectangle fitToScreen(@NotNull Dimension newDim, @NotNull RelativePoint popupPosition, JTable table) {
Rectangle rectangle = new Rectangle(popupPosition.getScreenPoint(), newDim);
ScreenUtil.fitToScreen(rectangle);
if (rectangle.getHeight() != newDim.getHeight()) {
int newHeight = (int)rectangle.getHeight();
int roundedHeight = newHeight - newHeight % table.getRowHeight();
rectangle.setSize((int)rectangle.getWidth(), Math.max(roundedHeight, table.getRowHeight()));
}
return rectangle;
}
private void appendMoreUsages(Editor editor, @NotNull RelativePoint popupPosition, @NotNull FindUsagesHandler handler, int maxUsages) {
@@ -28,7 +28,6 @@ import com.intellij.usages.Usage;
import com.intellij.usages.UsageGroup;
import com.intellij.usages.UsagePresentation;
import com.intellij.usages.impl.GroupNode;
import com.intellij.usages.impl.NullUsage;
import com.intellij.usages.impl.UsageNode;
import com.intellij.usages.impl.UsageViewImpl;
import com.intellij.usages.rules.UsageInFile;
@@ -78,13 +77,13 @@ class ShowUsagesTableCellRenderer implements TableCellRenderer {
if (column == 0) {
GroupNode parent = (GroupNode)usageNode.getParent();
appendGroupText(parent, panel, fileBgColor);
if (usage == NullUsage.INSTANCE) {
if (usage == ShowUsagesAction.MORE_USAGES_SEPARATOR) {
textChunks.append("...<");
textChunks.append("more usages", SimpleTextAttributes.REGULAR_BOLD_ATTRIBUTES);
textChunks.append(">...");
}
}
else if (usage != NullUsage.INSTANCE) {
else if (usage != ShowUsagesAction.MORE_USAGES_SEPARATOR) {
UsagePresentation presentation = usage.getPresentation();
TextChunk[] text = presentation.getText();
@@ -37,7 +37,7 @@ import com.intellij.openapi.fileEditor.TextEditor;
import com.intellij.openapi.keymap.KeymapUtil;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.progress.Task;
import com.intellij.openapi.progress.util.ProgressIndicatorBase;
import com.intellij.openapi.project.DumbService;
import com.intellij.openapi.project.IndexNotReadyException;
import com.intellij.openapi.project.Project;
@@ -51,7 +51,6 @@ import com.intellij.psi.search.LocalSearchScope;
import com.intellij.psi.search.PsiSearchHelper;
import com.intellij.psi.search.SearchRequestCollector;
import com.intellij.psi.search.SearchSession;
import com.intellij.psi.util.PsiUtilBase;
import com.intellij.psi.util.PsiUtilCore;
import com.intellij.ui.LightweightHint;
import com.intellij.ui.content.Content;
@@ -59,7 +58,6 @@ import com.intellij.usageView.UsageInfo;
import com.intellij.usageView.UsageViewManager;
import com.intellij.usageView.UsageViewUtil;
import com.intellij.usages.*;
import com.intellij.usages.impl.UsageViewManagerImpl;
import com.intellij.util.CommonProcessors;
import com.intellij.util.Processor;
import com.intellij.util.containers.ContainerUtil;
@@ -76,7 +74,6 @@ import java.util.Collections;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
public class FindUsagesManager implements JDOMExternalizable {
private static final Logger LOG = Logger.getInstance("#com.intellij.find.findParameterUsages.FindUsagesManager");
@@ -163,7 +160,7 @@ public class FindUsagesManager implements JDOMExternalizable {
JDOMExternalizer.write(element, "OPEN_NEW_TAB", myToOpenInNewTab);
}
private boolean findUsageInFile(@NotNull FileEditor editor, FileSearchScope direction) {
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 invalidated
@@ -251,20 +248,19 @@ public class FindUsagesManager implements JDOMExternalizable {
return null;
}
public void findUsages(@NotNull PsiElement psiElement, final PsiFile scopeFile, final FileEditor editor) {
//FindUsagesHandler handler = getFindUsagesHandler(psiElement, false);
public void findUsages(@NotNull PsiElement psiElement, final PsiFile scopeFile, final FileEditor editor, boolean showDialog) {
FindUsagesHandler handler = getNewFindUsagesHandler(psiElement, false);
if (handler == null) return;
boolean singleFile = scopeFile != null;
final AbstractFindUsagesDialog dialog = handler.getFindUsagesDialog(singleFile, shouldOpenInNewTab(), mustOpenInNewTab());
if (true | singleFile) {
dialog.close(DialogWrapper.OK_EXIT_CODE);
}
else {
if (showDialog) {
dialog.show();
if (!dialog.isOK()) return;
}
else {
dialog.close(DialogWrapper.OK_EXIT_CODE);
}
setOpenInNewTab(dialog.isShowInSeparateWindow());
@@ -287,7 +283,7 @@ public class FindUsagesManager implements JDOMExternalizable {
}
}
private static void checkNotNull(PsiElement[] primaryElements, FindUsagesHandler handler, @NonNls String methodName) {
private static void checkNotNull(@NotNull PsiElement[] primaryElements, @NotNull FindUsagesHandler handler, @NonNls @NotNull String methodName) {
for (PsiElement element : primaryElements) {
if (element == null) {
LOG.error(handler + "." + methodName +" has returned array with null elements: " + Arrays.asList(primaryElements));
@@ -311,47 +307,42 @@ public class FindUsagesManager implements JDOMExternalizable {
return used.get();
}
// return null on failure or cancel
@Nullable
public UsageViewPresentation processUsages(FindUsagesHandler handler,
@NotNull final Processor<Usage> processor, FindUsagesOptions findUsagesOptions) {
if (handler == null) return null;
PsiElement element = handler.getPsiElement();
LOG.assertTrue(element.isValid());
@NotNull
public static ProgressIndicator startProcessUsages(@NotNull FindUsagesHandler handler,
@NotNull final Processor<Usage> processor,
@NotNull FindUsagesOptions findUsagesOptions,
@NotNull final Runnable onComplete) {
final UsageInfoToUsageConverter.TargetElementsDescriptor descriptor =
new UsageInfoToUsageConverter.TargetElementsDescriptor(handler.getPrimaryElements(), handler.getSecondaryElements());
UsageViewPresentation presentation = createPresentation(element, findUsagesOptions, myToOpenInNewTab);
final UsageSearcher usageSearcher = createUsageSearcher(descriptor, handler, findUsagesOptions, null);
final boolean[] canceled = {false};
final AtomicInteger usageCount = new AtomicInteger();
Task task = new Task.Modal(myProject, UsageViewManagerImpl.getProgressTitle(presentation), true) {
@Override
public void run(@NotNull final ProgressIndicator indicator) {
usageSearcher.generate(new Processor<Usage>() {
@Override
public boolean process(final Usage usage) {
usageCount.incrementAndGet();
return processor.process(usage);
}
});
}
final ProgressIndicatorBase indicator = new ProgressIndicatorBase();
ApplicationManager.getApplication().executeOnPooledThread(new Runnable() {
@Override
@Nullable
public NotificationInfo getNotificationInfo() {
return new NotificationInfo("Find Usages", "Find Usages Finished", usageCount.get() + " Usage(s) Found");
public void run() {
try {
ProgressManager.getInstance().runProcess(new Runnable() {
@Override
public void run() {
usageSearcher.generate(processor);
}
}, indicator);
}
finally {
onComplete.run();
}
}
});
@Override
public void onCancel() {
canceled[0] = true;
}
};
ProgressManager.getInstance().run(task);
if (canceled[0]) return null;
return presentation;
return indicator;
}
@NotNull
public UsageViewPresentation createPresentation(@NotNull FindUsagesHandler handler, @NotNull FindUsagesOptions findUsagesOptions) {
PsiElement element = handler.getPsiElement();
LOG.assertTrue(element.isValid());
return createPresentation(element, findUsagesOptions, myToOpenInNewTab);
}
private void setOpenInNewTab(final boolean toOpenInNewTab) {
@@ -468,21 +459,18 @@ public class FindUsagesManager implements JDOMExternalizable {
addToHistory(elements, findUsagesOptions);
}
private static UsageViewPresentation createPresentation(PsiElement psiElement,
final FindUsagesOptions findUsagesOptions,
boolean toOpenInNewTab) {
@NotNull
private static UsageViewPresentation createPresentation(@NotNull PsiElement psiElement,
@NotNull FindUsagesOptions findUsagesOptions,
boolean toOpenInNewTab) {
UsageViewPresentation presentation = new UsageViewPresentation();
String scopeString = findUsagesOptions.searchScope != null ? findUsagesOptions.searchScope.getDisplayName() : null;
String scopeString = findUsagesOptions.searchScope == null ? null : findUsagesOptions.searchScope.getDisplayName();
presentation.setScopeText(scopeString);
String usagesString = generateUsagesString(findUsagesOptions);
presentation.setUsagesString(usagesString);
String title;
if (scopeString == null) {
title = FindBundle.message("find.usages.of.element.panel.title", usagesString, UsageViewUtil.getLongName(psiElement));
}
else {
title = FindBundle.message("find.usages.of.element.in.scope.panel.title", usagesString, UsageViewUtil.getLongName(psiElement), scopeString);
}
String title = scopeString == null
? FindBundle.message("find.usages.of.element.panel.title", usagesString, UsageViewUtil.getLongName(psiElement))
: FindBundle.message("find.usages.of.element.in.scope.panel.title", usagesString, UsageViewUtil.getLongName(psiElement), scopeString);
presentation.setTabText(title);
presentation.setTabName(FindBundle.message("find.usages.of.element.tab.name", usagesString, UsageViewUtil.getShortName(psiElement)));
presentation.setTargetsNodeText(StringUtil.capitalize(UsageViewUtil.getType(psiElement)));
@@ -490,10 +478,10 @@ public class FindUsagesManager implements JDOMExternalizable {
return presentation;
}
private void findUsagesInEditor(final UsageInfoToUsageConverter.TargetElementsDescriptor descriptor,
final FindUsagesHandler handler,
final PsiFile scopeFile,
final FileSearchScope direction,
private void findUsagesInEditor(@NotNull UsageInfoToUsageConverter.TargetElementsDescriptor descriptor,
@NotNull FindUsagesHandler handler,
@NotNull PsiFile scopeFile,
@NotNull FileSearchScope direction,
@NotNull final FindUsagesOptions findUsagesOptions,
@NotNull FileEditor fileEditor) {
initLastSearchElement(findUsagesOptions, descriptor);
@@ -683,7 +671,6 @@ public class FindUsagesManager implements JDOMExternalizable {
UsageTarget[] usageTargets = (UsageTarget[])targets;
PsiElement[] elements = getPsiElements(usageTargets);
if (elements.length == 0) return;
//final FindUsagesHandler handler = getFindUsagesHandler(elements[0], false);
final FindUsagesHandler handler = getNewFindUsagesHandler(elements[0], false);
if (handler == null) {
@@ -721,6 +708,6 @@ public class FindUsagesManager implements JDOMExternalizable {
}
}
}
return PsiUtilBase.toPsiElementArray(result);
return PsiUtilCore.toPsiElementArray(result);
}
}
@@ -700,7 +700,12 @@ public class FindManagerImpl extends FindManager implements PersistentStateCompo
@Override
public void findUsages(@NotNull PsiElement element) {
myFindUsagesManager.findUsages(element, null, null);
findUsages(element, false);
}
@Override
public void findUsages(@NotNull PsiElement element, boolean showDialog) {
myFindUsagesManager.findUsages(element, null, null, showDialog);
}
@Override
@@ -716,7 +721,7 @@ public class FindManagerImpl extends FindManager implements PersistentStateCompo
Document document = editor.getDocument();
PsiFile psiFile = PsiDocumentManager.getInstance(myProject).getPsiFile(document);
myFindUsagesManager.findUsages(element, psiFile, fileEditor);
myFindUsagesManager.findUsages(element, psiFile, fileEditor, false);
}
}
@@ -46,7 +46,7 @@ public abstract class DataManager {
/**
* @return {@link DataContext} constructed by the specified <code>component</code>
*/
public abstract DataContext getDataContext(@NotNull Component component);
public abstract DataContext getDataContext(Component component);
/**
* @return {@link DataContext} constructed be the specified <code>component</code>
@@ -71,9 +71,9 @@ public abstract class DataManager {
* @return value stored by {@link #saveInDataContext(com.intellij.openapi.actionSystem.DataContext, com.intellij.openapi.util.Key, Object)}
*/
@Nullable
public abstract <T> T loadFromDataContext(DataContext dataContext, Key<T> dataKey);
public abstract <T> T loadFromDataContext(@NotNull DataContext dataContext, @NotNull Key<T> dataKey);
public static void registerDataProvider(JComponent component, DataProvider provider) {
public static void registerDataProvider(@NotNull JComponent component, @NotNull DataProvider provider) {
component.putClientProperty(CLIENT_PROPERTY_DATA_PROVIDER, provider);
}
@@ -46,17 +46,15 @@ public class AnActionEvent implements PlaceProvider<String> {
private static final Map<String, String> ourInjectedIds = new HashMap<String, String>();
/**
* @throws IllegalArgumentException <code>dataContext</code> is <code>null</code> or
* @throws IllegalArgumentException if <code>dataContext</code> is <code>null</code> or
* <code>place</code> is <code>null</code> or <code>presentation</code> is <code>null</code>
*/
public AnActionEvent(
InputEvent inputEvent,
@NotNull DataContext dataContext,
@NotNull @NonNls String place,
@NotNull Presentation presentation,
ActionManager actionManager,
@JdkConstants.InputEventMask int modifiers
){
public AnActionEvent(InputEvent inputEvent,
@NotNull DataContext dataContext,
@NotNull @NonNls String place,
@NotNull Presentation presentation,
ActionManager actionManager,
@JdkConstants.InputEventMask int modifiers) {
// TODO[vova,anton] make this constructor package local. No one is allowed to create AnActionEvents
myInputEvent = inputEvent;
myActionManager = actionManager;
@@ -96,7 +94,7 @@ public class AnActionEvent implements PlaceProvider<String> {
}
@NonNls
public static String uninjectedId(String dataId) {
public static String uninjectedId(@NotNull String dataId) {
return StringUtil.trimStart(dataId, ourInjectedPrefix);
}
@@ -112,6 +110,7 @@ public class AnActionEvent implements PlaceProvider<String> {
return myDataContext;
}
return new DataContext() {
@Override
@Nullable
public Object getData(@NonNls String dataId) {
Object injected = myDataContext.getData(injectedId(dataId));
@@ -140,6 +139,7 @@ public class AnActionEvent implements PlaceProvider<String> {
* @return the place identifier
* @see ActionPlaces
*/
@Override
@NotNull
public String getPlace() {
return myPlace;
@@ -176,7 +176,7 @@ public class AnActionEvent implements PlaceProvider<String> {
return myWorksInInjected;
}
public void accept(AnActionEventVisitor visitor) {
public void accept(@NotNull AnActionEventVisitor visitor) {
visitor.visitEvent(this);
}
}
@@ -29,6 +29,7 @@ import com.intellij.util.ui.ComponentWithEmptyText;
import com.intellij.util.ui.StatusText;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.awt.*;
@@ -42,7 +43,7 @@ public class JBList extends JList implements ComponentWithEmptyText, ComponentWi
private StatusText myEmptyText;
private ExpandableItemsHandler<Integer> myExpandableItemsHandler;
private AsyncProcessIcon myBusyIcon;
@Nullable private AsyncProcessIcon myBusyIcon;
private boolean myBusy;
@@ -50,17 +51,18 @@ public class JBList extends JList implements ComponentWithEmptyText, ComponentWi
init();
}
public JBList(ListModel dataModel) {
public JBList(@NotNull ListModel dataModel) {
super(dataModel);
init();
}
public JBList(Object... listData) {
public JBList(@NotNull Object... listData) {
super(createDefaultListModel(listData));
init();
}
public static DefaultListModel createDefaultListModel(Object... items) {
@NotNull
public static DefaultListModel createDefaultListModel(@NotNull Object... items) {
final DefaultListModel model = new DefaultListModel();
for (Object item : items) {
model.add(model.getSize(), item);
@@ -68,7 +70,7 @@ public class JBList extends JList implements ComponentWithEmptyText, ComponentWi
return model;
}
public JBList(Collection items) {
public JBList(@NotNull Collection items) {
this(ArrayUtil.toObjectArray(items));
}
@@ -199,17 +201,23 @@ public class JBList extends JList implements ComponentWithEmptyText, ComponentWi
return myExpandableItemsHandler;
}
public <T> void installCellRenderer(final @NotNull NotNullFunction<T, JComponent> fun) {
public <T> void installCellRenderer(@NotNull final NotNullFunction<T, JComponent> fun) {
setCellRenderer(new DefaultListCellRenderer() {
@NotNull
@Override
public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
public Component getListCellRendererComponent(@NotNull JList list,
Object value,
int index,
boolean isSelected,
boolean cellHasFocus) {
@SuppressWarnings({"unchecked"})
final JComponent comp = fun.fun((T)value);
final JComponent comp = fun.fun((T)value);
comp.setOpaque(true);
if (isSelected) {
comp.setBackground(list.getSelectionBackground());
comp.setForeground(list.getSelectionForeground());
} else {
}
else {
comp.setBackground(list.getBackground());
comp.setForeground(list.getForeground());
}
@@ -218,7 +226,7 @@ public class JBList extends JList implements ComponentWithEmptyText, ComponentWi
});
}
public void setDataProvider(DataProvider provider) {
public void setDataProvider(@NotNull DataProvider provider) {
DataManager.registerDataProvider(this, provider);
}
@@ -33,9 +33,9 @@ import com.intellij.openapi.util.registry.Registry;
import com.intellij.openapi.wm.IdeFocusManager;
import com.intellij.openapi.wm.ex.WindowManagerEx;
import com.intellij.util.KeyedLazyInstanceEP;
import com.intellij.util.StringSetSpinAllocator;
import com.intellij.util.containers.WeakValueHashMap;
import gnu.trove.THashMap;
import gnu.trove.THashSet;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -57,44 +57,40 @@ public class DataManagerImpl extends DataManager implements ApplicationComponent
registerRules();
}
@Override
public void initComponent() {
}
@Override
public void disposeComponent() {
}
@Nullable
private Object getData(String dataId, final Component focusedComponent) {
private Object getData(@NotNull String dataId, final Component focusedComponent) {
for (Component c = focusedComponent; c != null; c = c.getParent()) {
final DataProvider dataProvider = getDataProvider(c);
if (dataProvider == null) continue;
final Set<String> set = StringSetSpinAllocator.alloc();
try {
Object data = getDataFromProvider(dataProvider, dataId, set);
if (data != null) return data;
}
finally {
StringSetSpinAllocator.dispose(set);
}
Object data = getDataFromProvider(dataProvider, dataId, null);
if (data != null) return data;
}
return null;
}
@Nullable
private Object getDataFromProvider(final DataProvider provider, String dataId, final Set<String> alreadyComputedIds) {
if (alreadyComputedIds.contains(dataId)) return null;
alreadyComputedIds.add(dataId);
private Object getDataFromProvider(@NotNull final DataProvider provider, @NotNull String dataId, @Nullable Set<String> alreadyComputedIds) {
if (alreadyComputedIds != null && alreadyComputedIds.contains(dataId)) return null;
try {
Object data = provider.getData(dataId);
if (data != null) return validated(data, dataId, provider);
GetDataRule dataRule = getDataRule(dataId);
if (dataRule != null) {
final Set<String> ids = alreadyComputedIds == null ? new THashSet<String>() : alreadyComputedIds;
ids.add(dataId);
data = dataRule.getData(new DataProvider() {
@Override
public Object getData(String dataId) {
return getDataFromProvider(provider, dataId, alreadyComputedIds);
return getDataFromProvider(provider, dataId, ids);
}
});
@@ -104,7 +100,7 @@ public class DataManagerImpl extends DataManager implements ApplicationComponent
return null;
}
finally {
alreadyComputedIds.remove(dataId);
if (alreadyComputedIds != null) alreadyComputedIds.remove(dataId);
}
}
@@ -125,7 +121,7 @@ public class DataManagerImpl extends DataManager implements ApplicationComponent
}
@Nullable
public GetDataRule getDataRule(String dataId) {
public GetDataRule getDataRule(@NotNull String dataId) {
GetDataRule rule = getRuleFromMap(dataId);
if (rule != null) {
return rule;
@@ -134,8 +130,10 @@ public class DataManagerImpl extends DataManager implements ApplicationComponent
final GetDataRule plainRule = getRuleFromMap(AnActionEvent.uninjectedId(dataId));
if (plainRule != null) {
return new GetDataRule() {
@Override
public Object getData(final DataProvider dataProvider) {
return plainRule.getData(new DataProvider() {
@Override
@Nullable
public Object getData(@NonNls String dataId) {
return dataProvider.getData(AnActionEvent.injectedId(dataId));
@@ -149,7 +147,7 @@ public class DataManagerImpl extends DataManager implements ApplicationComponent
}
@Nullable
private GetDataRule getRuleFromMap(final String dataId) {
private GetDataRule getRuleFromMap(@NotNull String dataId) {
GetDataRule rule = myDataConstantToRuleMap.get(dataId);
if (rule == null && !myDataConstantToRuleMap.containsKey(dataId)) {
final KeyedLazyInstanceEP<GetDataRule>[] eps = Extensions.getExtensions(GetDataRule.EP_NAME);
@@ -164,7 +162,7 @@ public class DataManagerImpl extends DataManager implements ApplicationComponent
}
@Nullable
private static Object validated(Object data, String dataId, Object dataSource) {
private static Object validated(@NotNull Object data, @NotNull String dataId, @NotNull Object dataSource) {
Object invalidData = DataValidator.findInvalidData(dataId, data, dataSource);
if (invalidData != null) {
return null;
@@ -176,10 +174,12 @@ public class DataManagerImpl extends DataManager implements ApplicationComponent
return data;
}
@Override
public DataContext getDataContext(Component component) {
return new MyDataContext(component);
}
@Override
public DataContext getDataContext(@NotNull Component component, int x, int y) {
if (x < 0 || x >= component.getWidth() || y < 0 || y >= component.getHeight()) {
throw new IllegalArgumentException("wrong point: x=" + x + "; y=" + y);
@@ -201,6 +201,7 @@ public class DataManagerImpl extends DataManager implements ApplicationComponent
myWindowManager = windowManager;
}
@Override
@NotNull
public DataContext getDataContext() {
return getDataContext(getFocusedComponent());
@@ -211,6 +212,7 @@ public class DataManagerImpl extends DataManager implements ApplicationComponent
final AsyncResult<DataContext> context = new AsyncResult<DataContext>();
IdeFocusManager.getGlobalInstance().doWhenFocusSettlesDown(new Runnable() {
@Override
public void run() {
context.setDone(getDataContext());
}
@@ -280,19 +282,22 @@ public class DataManagerImpl extends DataManager implements ApplicationComponent
myDataConstantToRuleMap.put(PlatformDataKeys.EDITOR_EVEN_IF_INACTIVE.getName(), new InactiveEditorRule());
}
@Override
@NotNull
public String getComponentName() {
return "DataManager";
}
@Override
public <T> void saveInDataContext(DataContext dataContext, @NotNull Key<T> dataKey, @Nullable T data) {
if (dataContext instanceof UserDataHolder) {
((UserDataHolder)dataContext).putUserData(dataKey, data);
}
}
@Override
@Nullable
public <T> T loadFromDataContext(DataContext dataContext, Key<T> dataKey) {
public <T> T loadFromDataContext(@NotNull DataContext dataContext, @NotNull Key<T> dataKey) {
return dataContext instanceof UserDataHolder ? ((UserDataHolder)dataContext).getUserData(dataKey) : null;
}
@@ -300,7 +305,7 @@ public class DataManagerImpl extends DataManager implements ApplicationComponent
public static final NullResult INSTANCE = new NullResult();
}
private static Set<String> ourSafeKeys = new HashSet<String>(Arrays.asList(
private static final Set<String> ourSafeKeys = new HashSet<String>(Arrays.asList(
PlatformDataKeys.PROJECT.getName(),
PlatformDataKeys.EDITOR.getName(),
PlatformDataKeys.IS_MODAL_CONTEXT.getName(),
@@ -314,8 +319,8 @@ public class DataManagerImpl extends DataManager implements ApplicationComponent
// the weak reference. For example, Swing often remembers menu items
// that have DataContext as a field.
private final WeakReference<Component> myRef;
private WeakValueHashMap<Key, Object> mySavedData;
private WeakValueHashMap<String, Object> myCachedData = new WeakValueHashMap<String, Object>();
private WeakValueHashMap<Key, Object> myUserData;
private final WeakValueHashMap<String, Object> myCachedData = new WeakValueHashMap<String, Object>();
public MyDataContext(final Component component) {
myEventCount = -1;
@@ -329,7 +334,9 @@ public class DataManagerImpl extends DataManager implements ApplicationComponent
myEventCount = eventCount;
}
@Override
public Object getData(String dataId) {
if (dataId == null) return null;
int currentEventCount = IdeEventQueue.getInstance().getEventCount();
if (myEventCount != -1 && myEventCount != currentEventCount) {
LOG.error("cannot share data context between Swing events; initial event count = " + myEventCount + "; current event count = " +
@@ -351,33 +358,29 @@ public class DataManagerImpl extends DataManager implements ApplicationComponent
}
@Nullable
private Object doGetData(String dataId) {
Component _component = myRef.get();
private Object doGetData(@NotNull String dataId) {
Component component = myRef.get();
if (PlatformDataKeys.IS_MODAL_CONTEXT.is(dataId)) {
if (_component != null) {
return IdeKeyEventDispatcher.isModalContext(_component) ? Boolean.TRUE : Boolean.FALSE;
}
else {
if (component == null) {
return null;
}
return IdeKeyEventDispatcher.isModalContext(component) ? Boolean.TRUE : Boolean.FALSE;
}
else if (PlatformDataKeys.CONTEXT_COMPONENT.is(dataId)) {
return _component;
if (PlatformDataKeys.CONTEXT_COMPONENT.is(dataId)) {
return component;
}
else if (PlatformDataKeys.MODALITY_STATE.is(dataId)) {
return _component != null ? ModalityState.stateForComponent(_component) : ModalityState.NON_MODAL;
if (PlatformDataKeys.MODALITY_STATE.is(dataId)) {
return component != null ? ModalityState.stateForComponent(component) : ModalityState.NON_MODAL;
}
else if (PlatformDataKeys.EDITOR.is(dataId)) {
Editor editor = (Editor)(((DataManagerImpl)DataManager.getInstance()).getData(dataId, _component));
if (PlatformDataKeys.EDITOR.is(dataId)) {
Editor editor = (Editor)((DataManagerImpl)DataManager.getInstance()).getData(dataId, component);
return validateEditor(editor);
}
else {
return (((DataManagerImpl)DataManager.getInstance()).getData(dataId, _component));
}
return ((DataManagerImpl)DataManager.getInstance()).getData(dataId, component);
}
@Nullable
private Editor validateEditor(Editor editor) {
private static Editor validateEditor(Editor editor) {
Component focusOwner = KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner();
if (focusOwner instanceof JComponent) {
final JComponent jComponent = (JComponent)focusOwner;
@@ -389,11 +392,12 @@ public class DataManagerImpl extends DataManager implements ApplicationComponent
@NonNls
public String toString() {
return "component=" + String.valueOf(myRef.get());
return "component=" + myRef.get();
}
@Override
public <T> T getUserData(@NotNull Key<T> key) {
//noinspection unchecked
return (T)getOrCreateMap().get(key);
}
@@ -403,11 +407,11 @@ public class DataManagerImpl extends DataManager implements ApplicationComponent
}
private WeakValueHashMap<Key, Object> getOrCreateMap() {
if (mySavedData == null) {
mySavedData = new WeakValueHashMap<Key, Object>();
WeakValueHashMap<Key, Object> userData = myUserData;
if (userData == null) {
myUserData = userData = new WeakValueHashMap<Key, Object>();
}
return mySavedData;
return userData;
}
}
}
@@ -18,6 +18,7 @@ package com.intellij.openapi.keymap.impl.keyGestures;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.AnActionEventVisitor;
import com.intellij.openapi.actionSystem.ActionManager;
import org.jetbrains.annotations.NotNull;
public class GestureActionEvent extends AnActionEvent {
public GestureActionEvent(KeyboardGestureProcessor processor) {
@@ -34,7 +35,7 @@ public class GestureActionEvent extends AnActionEvent {
}
@Override
public void accept(final AnActionEventVisitor visitor) {
public void accept(@NotNull final AnActionEventVisitor visitor) {
visitor.visitGestureInitEvent(this);
}
}
@@ -45,7 +46,7 @@ public class GestureActionEvent extends AnActionEvent {
}
@Override
public void accept(final AnActionEventVisitor visitor) {
public void accept(@NotNull final AnActionEventVisitor visitor) {
visitor.visitGesturePerformedEvent(this);
}
}
@@ -56,7 +57,7 @@ public class GestureActionEvent extends AnActionEvent {
}
@Override
public void accept(final AnActionEventVisitor visitor) {
public void accept(@NotNull final AnActionEventVisitor visitor) {
visitor.visitGestureFinishEvent(this);
}
}
@@ -57,6 +57,7 @@ public class ProgressManagerImpl extends ProgressManager implements Disposable{
public ProgressManagerImpl(Application application) {
if (/*!application.isUnitTestMode() && */!DISABLED) {
final Thread thread = new Thread(NAME) {
@Override
public void run() {
while (enabled) {
try {
@@ -113,6 +114,7 @@ public class ProgressManagerImpl extends ProgressManager implements Disposable{
myOld = old;
}
@Override
public void done() {
ProgressIndicator currentIndicator = myThreadIndicator.get();
if (currentIndicator != this) {
@@ -127,12 +129,14 @@ public class ProgressManagerImpl extends ProgressManager implements Disposable{
}
}
@Override
public NonCancelableSection startNonCancelableSection() {
NonCancelableIndicator nonCancelor = new NonCancelableIndicator(myThreadIndicator.get());
myThreadIndicator.set(nonCancelor);
return nonCancelor;
}
@Override
public void executeNonCancelableSection(@NotNull Runnable runnable) {
NonCancelableSection nonCancelor = startNonCancelableSection();
try {
@@ -143,6 +147,7 @@ public class ProgressManagerImpl extends ProgressManager implements Disposable{
}
}
@Override
public void setCancelButtonText(String cancelButtonText) {
ProgressIndicator progressIndicator = getProgressIndicator();
if (progressIndicator != null) {
@@ -156,20 +161,25 @@ public class ProgressManagerImpl extends ProgressManager implements Disposable{
}
@Override
public boolean hasProgressIndicator() {
return getProgressIndicator() != null;
}
@Override
public boolean hasUnsafeProgressIndicator() {
return myCurrentUnsafeProgressCount.get() > 0;
}
@Override
public boolean hasModalProgressIndicator() {
return myCurrentModalProgressCount.get() > 0;
}
@Override
public void runProcess(@NotNull final Runnable process, final ProgressIndicator progress) {
executeProcessUnderProgress(new Runnable(){
@Override
public void run() {
synchronized (process) {
process.notifyAll();
@@ -234,10 +244,12 @@ public class ProgressManagerImpl extends ProgressManager implements Disposable{
}
}
@Override
public ProgressIndicator getProgressIndicator() {
return myThreadIndicator.get();
}
@Override
public boolean runProcessWithProgressSynchronously(@NotNull final Runnable process,
@NotNull String progressTitle,
boolean canBeCanceled,
@@ -254,6 +266,7 @@ public class ProgressManagerImpl extends ProgressManager implements Disposable{
final Ref<T> result = new Ref<T>();
final Ref<E> exceptionRef = new Ref<E>();
Task.Modal task = new Task.Modal(project, progressTitle, canBeCanceled) {
@Override
public void run(@NotNull ProgressIndicator indicator) {
try {
T compute = process.compute();
@@ -269,12 +282,14 @@ public class ProgressManagerImpl extends ProgressManager implements Disposable{
return result.get();
}
@Override
public boolean runProcessWithProgressSynchronously(@NotNull final Runnable process,
@NotNull String progressTitle,
boolean canBeCanceled,
@Nullable Project project,
@Nullable JComponent parentComponent) {
Task.Modal task = new Task.Modal(project, progressTitle, canBeCanceled) {
@Override
public void run(@NotNull ProgressIndicator indicator) {
process.run();
}
@@ -287,6 +302,7 @@ public class ProgressManagerImpl extends ProgressManager implements Disposable{
long time = 0;
final boolean result = ((ApplicationEx)ApplicationManager.getApplication())
.runProcessWithProgressSynchronously(new TaskContainer(task) {
@Override
public void run() {
new TaskRunnable(task, ProgressManager.getInstance().getProgressIndicator()).run();
}
@@ -315,6 +331,7 @@ public class ProgressManagerImpl extends ProgressManager implements Disposable{
notificationInfo.getNotificationText());
}
@Override
public void runProcessWithProgressAsynchronously(@NotNull Project project,
@NotNull String progressTitle,
@NotNull final Runnable process,
@@ -323,6 +340,7 @@ public class ProgressManagerImpl extends ProgressManager implements Disposable{
runProcessWithProgressAsynchronously(project, progressTitle, process, successRunnable, canceledRunnable, PerformInBackgroundOption.DEAF);
}
@Override
public void runProcessWithProgressAsynchronously(@NotNull final Project project,
@Nls @NotNull final String progressTitle,
@NotNull final Runnable process,
@@ -331,17 +349,20 @@ public class ProgressManagerImpl extends ProgressManager implements Disposable{
@NotNull final PerformInBackgroundOption option) {
runProcessWithProgressAsynchronously(new Task.Backgroundable(project, progressTitle, true, option) {
@Override
public void run(@NotNull final ProgressIndicator indicator) {
process.run();
}
@Override
public void onCancel() {
if (canceledRunnable != null) {
canceledRunnable.run();
}
}
@Override
public void onSuccess() {
if (successRunnable != null) {
successRunnable.run();
@@ -374,6 +395,7 @@ public class ProgressManagerImpl extends ProgressManager implements Disposable{
final Runnable process = new TaskRunnable(task, progressIndicator, continuation);
TaskContainer action = new TaskContainer(task) {
@Override
public void run() {
boolean canceled = false;
final long start = System.currentTimeMillis();
@@ -388,6 +410,7 @@ public class ProgressManagerImpl extends ProgressManager implements Disposable{
if (canceled || progressIndicator.isCanceled()) {
ApplicationManager.getApplication().invokeLater(new Runnable() {
@Override
public void run() {
task.onCancel();
}
@@ -402,6 +425,7 @@ public class ProgressManagerImpl extends ProgressManager implements Disposable{
}
}
ApplicationManager.getApplication().invokeLater(new Runnable() {
@Override
public void run() {
task.onSuccess();
}
@@ -421,6 +445,7 @@ public class ProgressManagerImpl extends ProgressManager implements Disposable{
}
}
@Override
public void run(@NotNull final Task task) {
if (task.isHeadless()) {
new TaskRunnable(task, new EmptyProgressIndicator()).run();
@@ -467,6 +492,7 @@ public class ProgressManagerImpl extends ProgressManager implements Disposable{
myContinuation = continuation;
}
@Override
public void run() {
try {
getTask().run(myIndicator);
@@ -66,7 +66,7 @@ public class AbstractPopup implements JBPopup {
private static final Icon ourMacCorner = AllIcons.General.MacCorner;
private static final Object SUPPRESS_MAC_CORNER = new Object();
public static final String SHOW_HINTS = "ShowHints";
@NonNls public static final String SHOW_HINTS = "ShowHints";
private PopupComponent myPopup;
private MyContentPanel myContent;
@@ -130,6 +130,7 @@ public class AbstractPopup implements JBPopup {
protected final SpeedSearch mySpeedSearch = new SpeedSearch() {
boolean searchFieldShown = false;
@Override
public void update() {
mySpeedSearchPatternField.setBackground(new JTextField().getBackground());
onSpeedSearchPatternChanged();
@@ -239,7 +240,7 @@ public class AbstractPopup implements JBPopup {
myHeaderPanel = new JPanel(new BorderLayout());
if (caption != null) {
if (caption.length() > 0) {
if (!caption.isEmpty()) {
myCaption = new TitlePanel(actualIcon.getRegular(), actualIcon.getInactive());
((TitlePanel)myCaption).setText(caption);
}
@@ -252,6 +253,7 @@ public class AbstractPopup implements JBPopup {
AllIcons.General.AutohideOff,
AllIcons.General.AutohideOffInactive),
new ActionListener() {
@Override
public void actionPerformed(final ActionEvent e) {
pinCallback.process(AbstractPopup.this);
}
@@ -259,6 +261,7 @@ public class AbstractPopup implements JBPopup {
}
else if (cancelButton != null) {
myCaption.setButtonComponent(new InplaceButton(cancelButton, new ActionListener() {
@Override
public void actionPerformed(final ActionEvent e) {
cancel();
}
@@ -359,6 +362,7 @@ public class AbstractPopup implements JBPopup {
myDimensionServiceKey = dimensionServiceKey;
}
@Override
public void showInCenterOf(@NotNull Component aContainer) {
final Point popupPoint = getCenterOf(aContainer, myContent);
show(aContainer, popupPoint.x, popupPoint.y, false);
@@ -368,6 +372,7 @@ public class AbstractPopup implements JBPopup {
setAdText(s, SwingConstants.LEFT);
}
@Override
public void setAdText(@NotNull final String s, int alignment) {
if (myAdComponent == null) {
myAdComponent = HintUtil.createAdComponent(s, BorderFactory.createEmptyBorder(1, 5, 1, 5), alignment);
@@ -399,6 +404,7 @@ public class AbstractPopup implements JBPopup {
return UIUtil.getCenterPoint(new Rectangle(containerScreenPoint, component.getVisibleRect().getSize()), content.getPreferredSize());
}
@Override
public void showCenteredInCurrentWindow(@NotNull Project project) {
Window window = null;
@@ -418,19 +424,23 @@ public class AbstractPopup implements JBPopup {
}
}
@Override
public void showUnderneathOf(@NotNull Component aComponent) {
show(new RelativePoint(aComponent, new Point(0, aComponent.getHeight())));
}
@Override
public void show(@NotNull RelativePoint aPoint) {
final Point screenPoint = aPoint.getScreenPoint();
show(aPoint.getComponent(), screenPoint.x, screenPoint.y, false);
}
@Override
public void showInScreenCoordinates(@NotNull Component owner, @NotNull Point point) {
show(owner, point.x, point.y, false);
}
@Override
public void showInBestPositionFor(@NotNull DataContext dataContext) {
final Editor editor = PlatformDataKeys.EDITOR.getData(dataContext);
if (editor != null) {
@@ -441,6 +451,7 @@ public class AbstractPopup implements JBPopup {
}
}
@Override
public void showInFocusCenter() {
final Component focused = getWndManager().getFocusedComponent(myProject);
if (focused != null) {
@@ -478,6 +489,7 @@ public class AbstractPopup implements JBPopup {
return JBPopupFactory.getInstance().guessBestPopupLocation(dataContext);
}
@Override
public void showInBestPositionFor(@NotNull Editor editor) {
assert editor.getComponent().isShowing() : "Editor must be showing on the screen";
@@ -508,7 +520,7 @@ public class AbstractPopup implements JBPopup {
if (preferredBounds.y - adjustedBounds.y <= 0) {
return preferredLocation;
}
int adjustedY = preferredBounds.y - (editor.getLineHeight() * 3 / 2) - preferredSize.height;
int adjustedY = preferredBounds.y - editor.getLineHeight() * 3 / 2 - preferredSize.height;
return adjustedY >= 0 ? RelativePoint.fromScreen(new Point(preferredBounds.x, adjustedY)) : preferredLocation;
}
@@ -540,7 +552,7 @@ public class AbstractPopup implements JBPopup {
setDimensionServiceKey(null); // going to cut width
Rectangle screen = ScreenUtil.getScreenRectangle(leftTopCornerScreen.x, leftTopCornerScreen.y);
final int spaceOnTheLeft = bounds.x;
final int spaceOnTheRight = (screen.x + screen.width) - leftTopCornerScreen.x;
final int spaceOnTheRight = screen.x + screen.width - leftTopCornerScreen.x;
if (spaceOnTheLeft > spaceOnTheRight) {
relativePoint = new RelativePoint(layeredPane, new Point(0, bounds.y));
myComponent.setPreferredSize(new Dimension(spaceOnTheLeft, Math.max(preferredSize.height, 200)));
@@ -554,19 +566,23 @@ public class AbstractPopup implements JBPopup {
return relativePoint;
}
@Override
public final void closeOk(@Nullable InputEvent e) {
setOk(true);
cancel(e);
}
@Override
public final void cancel() {
cancel(null);
}
@Override
public void setRequestFocus(boolean requestFocus) {
myRequestFocus = requestFocus;
}
@Override
public void cancel(InputEvent e) {
if (isDisposed()) return;
@@ -586,7 +602,7 @@ public class AbstractPopup implements JBPopup {
}
if (e instanceof MouseEvent) {
IdeEventQueue.getInstance().blockNextEvents(((MouseEvent)e));
IdeEventQueue.getInstance().blockNextEvents((MouseEvent)e);
}
myPopup.hide(false);
@@ -627,14 +643,17 @@ public class AbstractPopup implements JBPopup {
myPopup = null;
}
@Override
public boolean canClose() {
return myCallBack == null || myCallBack.compute().booleanValue();
}
@Override
public boolean isVisible() {
return myPopup != null;
}
@Override
public void show(final Component owner) {
show(owner, -1, -1, true);
}
@@ -744,7 +763,7 @@ public class AbstractPopup implements JBPopup {
myRequestorComponent = owner;
boolean forcedDialog = myMayBeParent
|| (SystemInfo.isMac && !(myOwner instanceof IdeFrame) && (myOwner != null && myOwner.isShowing()));
|| SystemInfo.isMac && !(myOwner instanceof IdeFrame) && myOwner != null && myOwner.isShowing();
PopupComponent.Factory factory = getFactory(myForcedHeavyweight || myResizable, forcedDialog);
myNativePopup = factory.isNativePopup();
@@ -762,6 +781,7 @@ public class AbstractPopup implements JBPopup {
if (myCaption != null && myMovable) {
final MoveComponentListener moveListener = new MoveComponentListener(myCaption) {
@Override
public void mousePressed(final MouseEvent e) {
super.mousePressed(e);
if (e.isConsumed()) return;
@@ -777,6 +797,7 @@ public class AbstractPopup implements JBPopup {
ListenerUtil.addMouseMotionListener(myCaption, moveListener);
final MyContentPanel saved = myContent;
Disposer.register(this, new Disposable() {
@Override
public void dispose() {
ListenerUtil.removeMouseListener(saved, moveListener);
ListenerUtil.removeMouseMotionListener(saved, moveListener);
@@ -815,6 +836,7 @@ public class AbstractPopup implements JBPopup {
final Runnable afterShow = new Runnable() {
@Override
public void run() {
if (myPreferredFocusedComponent != null && myInStack && myFocusable) {
myFocusTrackback.registerFocusComponent(myPreferredFocusedComponent);
@@ -948,6 +970,7 @@ public class AbstractPopup implements JBPopup {
private void prepareToShow() {
final MouseAdapter mouseAdapter = new MouseAdapter() {
@Override
public void mousePressed(MouseEvent e) {
Point point = (Point)e.getPoint().clone();
SwingUtilities.convertPointToScreen(point, e.getComponent());
@@ -964,12 +987,14 @@ public class AbstractPopup implements JBPopup {
};
myContent.addMouseListener(mouseAdapter);
Disposer.register(this, new Disposable() {
@Override
public void dispose() {
myContent.removeMouseListener(mouseAdapter);
}
});
myContent.registerKeyboardAction(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if (myCancelKeyEnabled) {
cancel();
@@ -989,10 +1014,12 @@ public class AbstractPopup implements JBPopup {
myFocusWatcher = new ChildFocusWatcher(myContent) {
@Override
protected void onFocusGained(final FocusEvent event) {
setWindowActive(true);
}
@Override
protected void onFocusLost(final FocusEvent event) {
setWindowActive(false);
}
@@ -1036,6 +1063,7 @@ public class AbstractPopup implements JBPopup {
return ApplicationManagerEx.getApplicationEx() != null ? WindowManagerEx.getInstanceEx() : null;
}
@Override
public boolean isDisposed() {
return myContent == null;
}
@@ -1075,19 +1103,17 @@ public class AbstractPopup implements JBPopup {
if (myProject != null) {
return IdeFocusManager.getInstance(myProject);
}
else if (myOwner != null) {
if (myOwner != null) {
return IdeFocusManager.findInstanceByComponent(myOwner);
}
else {
return IdeFocusManager.findInstance();
}
return IdeFocusManager.findInstance();
}
private static JComponent getTargetComponent(Component aComponent) {
if (aComponent instanceof JComponent) {
return (JComponent)aComponent;
}
else if (aComponent instanceof RootPaneContainer) {
if (aComponent instanceof RootPaneContainer) {
return ((RootPaneContainer)aComponent).getRootPane();
}
@@ -1102,23 +1128,22 @@ public class AbstractPopup implements JBPopup {
if (!cannotBeDialog && (isPersistent() || forceDialog)) {
return new PopupComponent.Factory.Dialog();
}
else if (forceHeavyweight) {
if (forceHeavyweight) {
return new PopupComponent.Factory.AwtHeavyweight();
}
else {
return new PopupComponent.Factory.AwtDefault();
}
return new PopupComponent.Factory.AwtDefault();
}
@Override
public JComponent getContent() {
return myContent;
}
public void setLocation(RelativePoint p) {
setLocation(p, myPopup, myContent);
setLocation(p, myPopup);
}
private static void setLocation(final RelativePoint p, final PopupComponent popup, Component content) {
private static void setLocation(final RelativePoint p, final PopupComponent popup) {
if (popup == null) return;
final Window wnd = popup.getWindow();
@@ -1129,7 +1154,7 @@ public class AbstractPopup implements JBPopup {
@Override
public void pack(boolean width, boolean height) {
if (!isVisible() || (!width && !height)) return;
if (!isVisible() || !width && !height) return;
Dimension size = getSize();
Dimension prefSize = myContent.computePreferredSize();
@@ -1163,6 +1188,7 @@ public class AbstractPopup implements JBPopup {
}
@Override
public void dispose() {
if (myDisposed) {
return;
@@ -1266,6 +1292,7 @@ public class AbstractPopup implements JBPopup {
setBorder(border);
}
@Override
public void paint(Graphics g) {
super.paint(g);
@@ -1278,8 +1305,7 @@ public class AbstractPopup implements JBPopup {
public Dimension computePreferredSize() {
if (isPreferredSizeSet()) {
Dimension setSize;
setSize = getPreferredSize();
Dimension setSize = getPreferredSize();
setPreferredSize(null);
Dimension result = getPreferredSize();
setPreferredSize(setSize);
@@ -1294,7 +1320,7 @@ public class AbstractPopup implements JBPopup {
return myDataProvider != null ? myDataProvider.getData(dataId) : null;
}
public void setDataProvider(DataProvider dataProvider) {
public void setDataProvider(@Nullable DataProvider dataProvider) {
myDataProvider = dataProvider;
}
}
@@ -1315,6 +1341,7 @@ public class AbstractPopup implements JBPopup {
private boolean myEverEntered = false;
@Override
public void eventDispatched(final AWTEvent event) {
if (event.getID() == WindowEvent.WINDOW_ACTIVATED) {
if (myCancelOnWindow && myPopup != null && !myPopup.isPopupWindow(((WindowEvent)event).getWindow())) {
@@ -1345,6 +1372,7 @@ public class AbstractPopup implements JBPopup {
}
}
@Override
public void setLocation(@NotNull final Point screenPoint) {
if (myPopup == null) {
myForcedLocation = screenPoint;
@@ -1376,6 +1404,7 @@ public class AbstractPopup implements JBPopup {
}
@Override
public void setSize(@NotNull final Dimension size) {
setSize(size, true);
}
@@ -1451,19 +1480,23 @@ public class AbstractPopup implements JBPopup {
}
private class MyWindowListener extends WindowAdapter {
@Override
public void windowClosed(final WindowEvent e) {
resetWindow();
}
}
@Override
public boolean isPersistent() {
return !myCancelOnClickOutside && !myCancelOnWindow;
}
@Override
public boolean isNativePopup() {
return myNativePopup;
}
@Override
public void setUiVisible(final boolean visible) {
if (myPopup != null) {
if (visible) {
@@ -1492,6 +1525,7 @@ public class AbstractPopup implements JBPopup {
myUserData = userData;
}
@Override
public <T> T getUserData(final Class<T> userDataClass) {
if (myUserData != null) {
for (Object o : myUserData) {
@@ -1504,10 +1538,12 @@ public class AbstractPopup implements JBPopup {
return null;
}
@Override
public boolean isModalContext() {
return myModalContext;
}
@Override
public boolean isFocused() {
if (myComponent != null && isFocused(new Component[]{SwingUtilities.getWindowAncestor(myComponent)})) {
return true;
@@ -1525,7 +1561,8 @@ public class AbstractPopup implements JBPopup {
Window wnd;
if (owner instanceof Window) {
wnd = (Window)owner;
} else {
}
else {
wnd = SwingUtilities.getWindowAncestor(owner);
}
@@ -1541,6 +1578,7 @@ public class AbstractPopup implements JBPopup {
return false;
}
@Override
public boolean isCancelKeyEnabled() {
return myCancelKeyEnabled;
}
@@ -1578,17 +1616,19 @@ public class AbstractPopup implements JBPopup {
public void setWarning(@NotNull String text) {
JBLabel label = new JBLabel(text, UIUtil.getBalloonWarningIcon(), SwingConstants.CENTER);
Color color = HintUtil.INFORMATION_COLOR;
label.setOpaque(true);
Color color = HintUtil.INFORMATION_COLOR;
label.setBackground(color);
label.setBorder(BorderFactory.createLineBorder(color, 3));
myHeaderPanel.add(label, BorderLayout.SOUTH);
}
@Override
public void addListener(final JBPopupListener listener) {
myListeners.add(listener);
}
@Override
public void removeListener(final JBPopupListener listener) {
myListeners.remove(listener);
}
@@ -1596,10 +1636,12 @@ public class AbstractPopup implements JBPopup {
protected void onSpeedSearchPatternChanged() {
}
@Override
public Component getOwner() {
return myRequestorComponent;
}
@Override
public void setMinimumSize(Dimension size) {
myMinSize = size;
}
@@ -1608,6 +1650,7 @@ public class AbstractPopup implements JBPopup {
return myFinalRunnable;
}
@Override
public void setFinalRunnable(Runnable finalRunnable) {
myFinalRunnable = finalRunnable;
}
@@ -1630,16 +1673,28 @@ public class AbstractPopup implements JBPopup {
}
private class SpeedSearchKeyListener implements KeyListener {
@Override
public void keyTyped(final KeyEvent e) {
mySpeedSearch.process(e);
}
@Override
public void keyPressed(final KeyEvent e) {
mySpeedSearch.process(e);
}
@Override
public void keyReleased(final KeyEvent e) {
mySpeedSearch.process(e);
}
}
@NotNull
public Dimension getHeaderPreferredSize() {
return myHeaderPanel.getPreferredSize();
}
@NotNull
public Dimension getFooterPreferredSize() {
return myAdComponent == null ? new Dimension(0,0) : myAdComponent.getPreferredSize();
}
}
@@ -317,8 +317,8 @@ action.FindUsages.text=Find _Usages...
action.FindUsages.description=Find usages of the symbol at caret
action.ShowUsages.text=_Show Usages
action.ShowUsages.description=Show usages of the symbol at caret
action.ShowUsagesSettings.text=_Show Usages Settings
action.ShowUsagesSettings.description=Choose scope and edit options for the Show Usages action
action.ShowSettingsAndFindUsages.text=Find Usages _Settings
action.ShowSettingsAndFindUsages.description=Choose scope and edit options for the Find Usages action
action.FindUsagesInFile.text=F_ind Usages in File
action.FindUsagesInFile.description=Find usages of the symbol at caret in active editor
action.HighlightUsagesInFile.text=_Highlight Usages in File
@@ -3,7 +3,7 @@ node.non.code.usages=Non-code usages
node.found.usages=Found usages
usage.name=usage
usages.title=Usages
usages.n={0,choice, 1#1 usage|2#{0,number} usages}
usages.n={0,choice, 0#no usages|1#1 usage|2#{0,number} usages} found{0,choice, 0# yet|1#|2#}
action.show.import.statements=Show import statements
action.show.read.access=Show read access
action.show.write.access=Show write access
@@ -61,7 +61,7 @@
<action id="ShowUsages">
<keyboard-shortcut first-keystroke="control alt F7"/>
</action>
<action id="ShowUsagesSettings">
<action id="ShowSettingsAndFindUsages">
<keyboard-shortcut first-keystroke="control shift alt F7"/>
</action>
<action id="UsageView.Include">
@@ -10,7 +10,7 @@
<action id="ShowUsages">
<keyboard-shortcut first-keystroke="control alt 7"/>
</action>
<action id="ShowUsagesSettings">
<action id="ShowSettingsAndFindUsages">
<keyboard-shortcut first-keystroke="control shift alt 7"/>
</action>
<action id="SwitchCoverage">
@@ -167,7 +167,7 @@
<add-to-group group-id="EditorToggleActions"/>
</action>
<action id="ShowUsagesSettings" class="com.intellij.find.actions.ShowUsagesAction$ShowSettings"/>
<action id="ShowSettingsAndFindUsages" class="com.intellij.find.actions.FindUsagesAction$ShowSettingsAndFindUsages"/>
<action id="ProjectViewChangeView" class="com.intellij.ide.projectView.actions.ChangeProjectViewAction"/>
<action id="RecentChanges" class="com.intellij.history.integration.ui.actions.RecentChangesAction">
@@ -616,7 +616,7 @@ public class UsageViewImpl implements UsageView, UsageModelTracker.UsageModelTra
@Nullable
public static KeyboardShortcut getShowUsagesWithSettingsShortcut() {
return ActionManager.getInstance().getKeyboardShortcut("ShowUsagesSettings");
return ActionManager.getInstance().getKeyboardShortcut("ShowSettingsAndFindUsages");
}
private class CloseAction extends CloseTabToolbarAction {