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() {
@Override
public void dispose() {
myUsageViewSettings.loadState(usageViewSettings);
usageViewSettings.loadState(savedGlobalSettings);
}
});
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");
boolean hadMoreSeparator = visibleNodes.remove(MORE_USAGES_SEPARATOR_NODE);
if (hadMoreSeparator) {
usages.add(MORE_USAGES_SEPARATOR);
visibleNodes.add(MORE_USAGES_SEPARATOR_NODE);
}
addUsageNodes(usageView.getRoot(), usageView, new ArrayList<UsageNode>());
TableScrollingUtil.installActions(table);
final List<UsageNode> data = collectData(usages, visibleNodes, usageView, presentation);
setTableModel(table, usageView, data);
SpeedSearchBase<JTable> speedSearch = new MySpeedSearch(table);
speedSearch.setComparator(new SpeedSearchComparator(false));
final JBPopup popup =
createUsagePopup(usages, descriptor, visibleNodes, handler, editor, popupPosition,
maxUsages, usageView, options, table, presentation, processIcon, hadMoreSeparator);
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();
}
}, 100, new Runnable() {
@Override
public void run() {
if (popup.isDisposed()) return;
final List<UsageNode> nodes = new ArrayList<UsageNode>();
List<Usage> copy;
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);
copy = new ArrayList<Usage>(usages);
}
rebuildPopup(usageView, copy, nodes, table, popup, presentation, popupPosition,
!processIcon.isDisposed());
}
}
);
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 UsageTarget myUsageTarget =
new PsiElement2UsageTargetAdapter(handler.getPsiElement());
@Override
public boolean process(@NotNull Usage usage) {
synchronized (usages) {
if (visibleNodes.size() >= maxUsages) return false;
if (UsageViewManager.isSelfUsage(usage, new UsageTarget[] { myUsageTarget })) {
return true;
}
Usage usageToAdd = decider.shouldShow(myUsageTarget, usage) ? usage : null;
if (usageToAdd == null) return true;
UsageNode node = usageView.doAppendUsage(usageToAdd);
usages.add(usageToAdd);
if (node != null) {
visibleNodes.add(node);
boolean continueSearch = true;