Example usage for com.intellij.openapi.ui.popup JBPopup isVisible

List of usage examples for com.intellij.openapi.ui.popup JBPopup isVisible

Introduction

In this page you can find the example usage for com.intellij.openapi.ui.popup JBPopup isVisible.

Prototype

boolean isVisible();

Source Link

Document

Checks if the popup is currently visible.

Usage

From source file:com.android.tools.idea.uibuilder.actions.TogglePanningDialogAction.java

License:Apache License

@Override
public boolean isSelected(AnActionEvent e) {
    if (myPopupReference == null) {
        return false;
    }//from  www.  j  a  va2  s . c  o  m
    JBPopup popup = myPopupReference.get();
    return popup != null && popup.isVisible();
}

From source file:com.android.tools.idea.uibuilder.surface.DesignSurface.java

License:Apache License

public void hover(@SwingCoordinate int x, @SwingCoordinate int y) {
    ScreenView current = getHoverScreenView(x, y);
    for (Layer layer : myLayers) {
        if (layer instanceof ConstraintsLayer) {
            // For constraint layer, set show on hover if they are above their screen view
            ConstraintsLayer constraintsLayer = (ConstraintsLayer) layer;
            boolean show = false;
            if (constraintsLayer.getScreenView() == current) {
                show = true;//  w w w .  j  av a 2 s.c  o m
            }
            if (constraintsLayer.isShowOnHover() != show) {
                constraintsLayer.setShowOnHover(show);
                repaint();
            }
        } else if (layer instanceof SceneLayer) {
            // For constraint layer, set show on hover if they are above their screen view
            SceneLayer sceneLayer = (SceneLayer) layer;
            boolean show = false;
            if (sceneLayer.getScreenView() == current) {
                show = true;
            }
            if (sceneLayer.isShowOnHover() != show) {
                sceneLayer.setShowOnHover(show);
                repaint();
            }
        } else if (layer instanceof CanvasResizeLayer) {
            if (((CanvasResizeLayer) layer).changeHovering(x, y)) {
                repaint();
            }
        }
    }

    if (myErrorPanel.isVisible() && myRenderHasProblems) {
        // don't show any warnings on hover if there is already some errors that are being displayed
        // TODO: we should really move this logic into the error panel itself
        return;
    }

    // Currently, we use the hover action only to check whether we need to show a warning.
    if (AndroidEditorSettings.getInstance().getGlobalState().isShowLint()) {
        ScreenView currentScreenView = getCurrentScreenView();
        LintAnnotationsModel lintModel = currentScreenView != null
                ? currentScreenView.getModel().getLintAnnotationsModel()
                : null;
        if (lintModel != null) {
            for (Layer layer : myLayers) {
                String tooltip = layer.getTooltip(x, y);
                if (tooltip != null) {
                    JBPopup lintPopup = myLintTooltipPopup.get();
                    if (lintPopup == null || !lintPopup.isVisible()) {
                        NlUsageTrackerManager.getInstance(this)
                                .logAction(LayoutEditorEvent.LayoutEditorEventType.LINT_TOOLTIP);
                        LintNotificationPanel lintPanel = new LintNotificationPanel(getCurrentScreenView(),
                                lintModel);
                        lintPanel.selectIssueAtPoint(Coordinates.getAndroidX(getCurrentScreenView(), x),
                                Coordinates.getAndroidY(getCurrentScreenView(), y));

                        Point point = new Point(x, y);
                        SwingUtilities.convertPointToScreen(point, this);
                        myLintTooltipPopup = new WeakReference<>(
                                lintPanel.showInScreenPosition(myProject, this, point));
                    }
                    break;
                }
            }
        }
    }
}

From source file:com.antoine.ideaplugin.greenrobot.ShowUsagesAction.java

License:Apache License

private void showElementUsages(@NotNull final FindUsagesHandler handler, final Editor editor,
        @NotNull final RelativePoint popupPosition, final int maxUsages,
        @NotNull final FindUsagesOptions options) {
    ApplicationManager.getApplication().assertIsDispatchThread();
    final UsageViewSettings usageViewSettings = UsageViewSettings.getInstance();
    final UsageViewSettings savedGlobalSettings = new UsageViewSettings();

    savedGlobalSettings.loadState(usageViewSettings);
    usageViewSettings.loadState(myUsageViewSettings);

    final Project project = handler.getProject();
    UsageViewManager manager = UsageViewManager.getInstance(project);
    FindUsagesManager findUsagesManager = ((FindManagerImpl) FindManager.getInstance(project))
            .getFindUsagesManager();/*from w ww  .j a  v  a2 s .com*/
    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 final 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, myUsageTarget)) {
                    return true;
                }

                Usage usageToAdd = transform(usage);
                if (usageToAdd == null)
                    return true;

                UsageNode node = usageView.doAppendUsage(usageToAdd);
                usages.add(usageToAdd);
                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();

                    return continueSearch;
                }
                return true;
            }
        }
    };

    final ProgressIndicator indicator = FindUsagesManager.startProcessUsages(handler,
            handler.getPrimaryElements(), handler.getSecondaryElements(), 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();
                            pingEDT.ping(); // repaint title
                            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();
                                        usage.navigate(true);
                                        //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();
                                        }
                                    }
                                } else {
                                    String title = presentation.getTabText();
                                    boolean shouldShowMoreSeparator = visibleNodes
                                            .contains(MORE_USAGES_SEPARATOR_NODE);
                                    String fullTitle = getFullTitle(usages, title, shouldShowMoreSeparator,
                                            visibleNodes.size() - (shouldShowMoreSeparator ? 1 : 0), false);
                                    ((AbstractPopup) popup).setCaption(fullTitle);
                                }
                            }
                        }
                    }, project.getDisposed());
                }
            });
    Disposer.register(popup, new Disposable() {
        @Override
        public void dispose() {
            indicator.cancel();
        }
    });
}

From source file:com.antoine.ideaplugin.greenrobot.ShowUsagesAction.java

License:Apache License

private static boolean showPopupIfNeedTo(@NotNull JBPopup popup, @NotNull RelativePoint popupPosition) {
    if (!popup.isDisposed() && !popup.isVisible()) {
        popup.show(popupPosition);/*w w w .j  av  a2  s  .  co  m*/
        return true;
    } else {
        return false;
    }
}

From source file:com.intellij.codeInsight.daemon.impl.HectorComponent.java

License:Apache License

@Nullable
private JBPopup getOldHector() {
    if (myHectorRef == null)
        return null;
    final JBPopup hector = myHectorRef.get();
    if (hector == null || !hector.isVisible()) {
        myHectorRef = null;/*from   www . j  a  va2 s.  co m*/
        return null;
    }
    return hector;
}

From source file:com.intellij.codeInsight.documentation.DocumentationManager.java

License:Apache License

private void doShowJavaDocInfo(@NotNull final PsiElement element, boolean requestFocus,
        PopupUpdateProcessor updateProcessor, final PsiElement originalElement,
        @Nullable final Runnable closeCallback) {
    Project project = getProject(element);
    if (!project.isOpen())
        return;/*from  w  w w  .ja v  a2  s.  com*/

    storeOriginalElement(project, originalElement, element);

    myPreviouslyFocused = WindowManagerEx.getInstanceEx().getFocusedComponent(project);

    JBPopup _oldHint = getDocInfoHint();

    if (myToolWindow == null
            && PropertiesComponent.getInstance().isTrueValue(SHOW_DOCUMENTATION_IN_TOOL_WINDOW)) {
        createToolWindow(element, originalElement);
    } else if (myToolWindow != null) {
        Content content = myToolWindow.getContentManager().getSelectedContent();
        if (content != null) {
            DocumentationComponent component = (DocumentationComponent) content.getComponent();
            if (element.getManager().areElementsEquivalent(component.getElement(), element)) {
                JComponent preferredFocusableComponent = content.getPreferredFocusableComponent();
                // focus toolwindow on the second actionPerformed
                boolean focus = requestFocus || CommandProcessor.getInstance().getCurrentCommand() != null;
                if (preferredFocusableComponent != null && focus) {
                    IdeFocusManager.getInstance(myProject).requestFocus(preferredFocusableComponent, true);
                }
            } else {
                content.setDisplayName(getTitle(element, true));
                fetchDocInfo(getDefaultCollector(element, originalElement), component, true);
            }
        }

        if (!myToolWindow.isVisible()) {
            myToolWindow.show(null);
        }
    } else if (_oldHint != null && _oldHint.isVisible() && _oldHint instanceof AbstractPopup) {
        DocumentationComponent oldComponent = (DocumentationComponent) ((AbstractPopup) _oldHint)
                .getComponent();
        fetchDocInfo(getDefaultCollector(element, originalElement), oldComponent);
    } else {
        showInPopup(element, requestFocus, updateProcessor, originalElement, closeCallback);
    }
}

From source file:com.intellij.codeInsight.documentation.DocumentationManager.java

License:Apache License

private void showInPopup(@NotNull final PsiElement element, boolean requestFocus,
        PopupUpdateProcessor updateProcessor, final PsiElement originalElement,
        @Nullable final Runnable closeCallback) {
    final DocumentationComponent component = new DocumentationComponent(this);
    component.setNavigateCallback(new Consumer<PsiElement>() {
        @Override/*from   ww  w  . jav  a  2s.co m*/
        public void consume(PsiElement psiElement) {
            final AbstractPopup jbPopup = (AbstractPopup) getDocInfoHint();
            if (jbPopup != null) {
                final String title = getTitle(psiElement, false);
                jbPopup.setCaption(title);
            }
        }
    });
    Processor<JBPopup> pinCallback = new Processor<JBPopup>() {
        @Override
        public boolean process(JBPopup popup) {
            createToolWindow(element, originalElement);
            myToolWindow.setAutoHide(false);
            popup.cancel();
            return false;
        }
    };

    ActionListener actionListener = new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent e) {
            createToolWindow(element, originalElement);
            final JBPopup hint = getDocInfoHint();
            if (hint != null && hint.isVisible())
                hint.cancel();
        }
    };
    List<Pair<ActionListener, KeyStroke>> actions = ContainerUtil.newSmartList();
    AnAction quickDocAction = ActionManagerEx.getInstanceEx().getAction(IdeActions.ACTION_QUICK_JAVADOC);
    for (Shortcut shortcut : quickDocAction.getShortcutSet().getShortcuts()) {
        if (!(shortcut instanceof KeyboardShortcut))
            continue;
        actions.add(Pair.create(actionListener, ((KeyboardShortcut) shortcut).getFirstKeyStroke()));
    }

    boolean hasLookup = LookupManager.getActiveLookup(myEditor) != null;
    final JBPopup hint = JBPopupFactory.getInstance().createComponentPopupBuilder(component, component)
            .setProject(element.getProject()).addListener(updateProcessor).addUserData(updateProcessor)
            .setKeyboardActions(actions).setDimensionServiceKey(myProject, JAVADOC_LOCATION_AND_SIZE, false)
            .setResizable(true).setMovable(true).setRequestFocus(requestFocus)
            .setCancelOnClickOutside(!hasLookup) // otherwise selecting lookup items by mouse would close the doc
            .setTitle(getTitle(element, false)).setCouldPin(pinCallback).setModalContext(false)
            .setCancelCallback(new Computable<Boolean>() {
                @Override
                public Boolean compute() {
                    myCloseOnSneeze = false;
                    if (closeCallback != null) {
                        closeCallback.run();
                    }
                    if (fromQuickSearch()) {
                        ((ChooseByNameBase.JPanelProvider) myPreviouslyFocused.getParent()).unregisterHint();
                    }

                    Disposer.dispose(component);
                    myEditor = null;
                    myPreviouslyFocused = null;
                    return Boolean.TRUE;
                }
            }).setKeyEventHandler(new BooleanFunction<KeyEvent>() {
                @Override
                public boolean fun(KeyEvent e) {
                    if (myCloseOnSneeze) {
                        closeDocHint();
                    }
                    if ((AbstractPopup.isCloseRequest(e) && getDocInfoHint() != null)) {
                        closeDocHint();
                        return true;
                    }
                    return false;
                }
            }).createPopup();

    component.setHint(hint);

    if (myEditor == null) {
        // subsequent invocation of javadoc popup from completion will have myEditor == null because of cancel invoked, 
        // so reevaluate the editor for proper popup placement
        Lookup lookup = LookupManager.getInstance(myProject).getActiveLookup();
        myEditor = lookup != null ? lookup.getEditor() : null;
    }
    fetchDocInfo(getDefaultCollector(element, originalElement), component);

    myDocInfoHintRef = new WeakReference<JBPopup>(hint);

    if (fromQuickSearch() && myPreviouslyFocused != null) {
        ((ChooseByNameBase.JPanelProvider) myPreviouslyFocused.getParent()).registerHint(hint);
    }
}

From source file:com.intellij.codeInsight.documentation.DocumentationManager.java

License:Apache License

@Nullable
public JBPopup getDocInfoHint() {
    if (myDocInfoHintRef == null)
        return null;
    JBPopup hint = myDocInfoHintRef.get();
    if (hint == null || !hint.isVisible()) {
        myDocInfoHintRef = null;//from ww w  .  ja  v a2 s  . co m
        return null;
    }
    return hint;
}

From source file:com.intellij.codeInsight.hint.actions.ShowImplementationsAction.java

License:Apache License

protected void showImplementations(final PsiElement[] impls, final Project project, final String text,
        final Editor editor, final PsiFile file, final PsiElement element, boolean invokedFromEditor,
        boolean invokedByShortcut) {
    if (impls == null || impls.length == 0)
        return;//from   w w w  . j  av  a  2s  .  c  o  m

    FeatureUsageTracker.getInstance().triggerFeatureUsed(CODEASSISTS_QUICKDEFINITION_FEATURE);
    if (LookupManager.getInstance(project).getActiveLookup() != null) {
        FeatureUsageTracker.getInstance().triggerFeatureUsed(CODEASSISTS_QUICKDEFINITION_LOOKUP_FEATURE);
    }

    int index = 0;
    if (invokedFromEditor && file != null && impls.length > 1) {
        final VirtualFile virtualFile = file.getVirtualFile();
        final PsiFile containingFile = impls[0].getContainingFile();
        if (virtualFile != null && containingFile != null
                && virtualFile.equals(containingFile.getVirtualFile())) {
            final PsiFile secondContainingFile = impls[1].getContainingFile();
            if (secondContainingFile != containingFile) {
                index = 1;
            }
        }
    }

    final Ref<UsageView> usageView = new Ref<UsageView>();
    final String title = CodeInsightBundle.message("implementation.view.title", text);
    if (myPopupRef != null) {
        final JBPopup popup = myPopupRef.get();
        if (popup != null && popup.isVisible() && popup instanceof AbstractPopup) {
            final ImplementationViewComponent component = (ImplementationViewComponent) ((AbstractPopup) popup)
                    .getComponent();
            ((AbstractPopup) popup).setCaption(title);
            component.update(impls, index);
            updateInBackground(editor, element, component, title, (AbstractPopup) popup, usageView);
            if (invokedByShortcut) {
                ((AbstractPopup) popup).focusPreferredComponent();
            }
            return;
        }
    }

    final ImplementationViewComponent component = new ImplementationViewComponent(impls, index);
    if (component.hasElementsToShow()) {
        final PopupUpdateProcessor updateProcessor = new PopupUpdateProcessor(project) {
            @Override
            public void updatePopup(Object lookupItemObject) {
                final PsiElement element = lookupItemObject instanceof PsiElement
                        ? (PsiElement) lookupItemObject
                        : DocumentationManager.getInstance(project).getElementFromLookup(editor, file);
                updateElementImplementations(element, editor, project, file);
            }
        };

        final JBPopup popup = JBPopupFactory.getInstance()
                .createComponentPopupBuilder(component, component.getPreferredFocusableComponent())
                .setRequestFocusCondition(project, NotLookupOrSearchCondition.INSTANCE).setProject(project)
                .addListener(updateProcessor).addUserData(updateProcessor)
                .setDimensionServiceKey(project, DocumentationManager.JAVADOC_LOCATION_AND_SIZE, false)
                .setResizable(true).setMovable(true)
                .setRequestFocus(invokedFromEditor && LookupManager.getActiveLookup(editor) == null)
                .setTitle(title).setCouldPin(new Processor<JBPopup>() {
                    @Override
                    public boolean process(JBPopup popup) {
                        usageView.set(component.showInUsageView());
                        popup.cancel();
                        return false;
                    }
                }).createPopup();

        updateInBackground(editor, element, component, title, (AbstractPopup) popup, usageView);

        PopupPositionManager.positionPopupInBestPosition(popup, editor,
                DataManager.getInstance().getDataContext());
        component.setHint(popup, title);

        myPopupRef = new WeakReference<JBPopup>(popup);
    }
}

From source file:com.intellij.find.actions.ShowUsagesAction.java

License:Apache License

private void showElementUsages(final Editor editor, @NotNull final RelativePoint popupPosition,
        @NotNull final FindUsagesHandler handler, final int maxUsages,
        @NotNull final FindUsagesOptions options) {
    ApplicationManager.getApplication().assertIsDispatchThread();
    final UsageViewSettings usageViewSettings = UsageViewSettings.getInstance();
    final UsageViewSettings savedGlobalSettings = new UsageViewSettings();

    savedGlobalSettings.loadState(usageViewSettings);
    usageViewSettings.loadState(myUsageViewSettings);

    final Project project = handler.getProject();
    UsageViewManager manager = UsageViewManager.getInstance(project);
    FindUsagesManager findUsagesManager = ((FindManagerImpl) FindManager.getInstance(project))
            .getFindUsagesManager();//w w w .j a  v a2s.  com
    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 AtomicInteger outOfScopeUsages = new AtomicInteger();

    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");

    addUsageNodes(usageView.getRoot(), usageView, new ArrayList<UsageNode>());

    TableScrollingUtil.installActions(table);

    final List<UsageNode> data = collectData(usages, visibleNodes, usageView, presentation);
    setTableModel(table, usageView, data, outOfScopeUsages, options.searchScope);

    boolean isPreviewMode = false;
    Runnable itemChosenCallback = prepareTable(table, editor, popupPosition, handler, maxUsages, options,
            isPreviewMode);

    @Nullable
    final JBPopup popup = isPreviewMode ? null
            : createUsagePopup(usages, visibleNodes, handler, editor, popupPosition, maxUsages, usageView,
                    options, table, itemChosenCallback, presentation, processIcon);
    if (popup != null) {
        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 != null && popup.isDisposed();
        }
    }, 100, new Runnable() {
        @Override
        public void run() {
            if (popup != null && 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 != null && (!popup.isVisible()
                        && (usages.size() <= 1 || !showPopupIfNeedTo(popup, popupPosition)))) {
                    return;
                }
                addUsageNodes(usageView.getRoot(), usageView, nodes);
                copy = new ArrayList<Usage>(usages);
            }

            rebuildTable(usageView, copy, nodes, table, popup, presentation, popupPosition,
                    !processIcon.isDisposed(), outOfScopeUsages, options.searchScope);
        }
    });

    final MessageBusConnection messageBusConnection = project.getMessageBus().connect(usageView);
    messageBusConnection.subscribe(UsageFilteringRuleProvider.RULES_CHANGED, new Runnable() {
        @Override
        public void run() {
            pingEDT.ping();
        }
    });

    final UsageTarget[] myUsageTarget = { new PsiElement2UsageTargetAdapter(handler.getPsiElement()) };
    Processor<Usage> collect = new Processor<Usage>() {
        @Override
        public boolean process(@NotNull final Usage usage) {
            if (!UsageViewManagerImpl.isInScope(usage, options.searchScope)) {
                if (outOfScopeUsages.getAndIncrement() == 0) {
                    visibleNodes.add(USAGES_OUTSIDE_SCOPE_NODE);
                    usages.add(USAGES_OUTSIDE_SCOPE_SEPARATOR);
                }
                return true;
            }
            synchronized (usages) {
                if (visibleNodes.size() >= maxUsages)
                    return false;
                if (UsageViewManager.isSelfUsage(usage, myUsageTarget))
                    return true;
                UsageNode node = ApplicationManager.getApplication().runReadAction(new Computable<UsageNode>() {
                    @Override
                    public UsageNode compute() {
                        return usageView.doAppendUsage(usage);
                    }
                });
                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();

                    return continueSearch;
                }
            }

            return true;
        }
    };

    final ProgressIndicator indicator = FindUsagesManager.startProcessUsages(handler,
            handler.getPrimaryElements(), handler.getSecondaryElements(), collect, options, new Runnable() {
                @Override
                public void run() {
                    ApplicationManager.getApplication().invokeLater(new Runnable() {
                        @Override
                        public void run() {
                            Disposer.dispose(processIcon);
                            Container parent = processIcon.getParent();
                            if (parent != null) {
                                parent.remove(processIcon);
                                parent.repaint();
                            }
                            pingEDT.ping(); // repaint title
                            synchronized (usages) {
                                if (visibleNodes.isEmpty()) {
                                    if (usages.isEmpty()) {
                                        String text = UsageViewBundle.message("no.usages.found.in",
                                                searchScopePresentableName(options));
                                        hint(editor, text, handler, popupPosition, maxUsages, options, false);
                                        cancel(popup);
                                    } else {
                                        // all usages filtered out
                                    }
                                } else if (visibleNodes.size() == 1) {
                                    if (usages.size() == 1) {
                                        //the only usage
                                        Usage usage = visibleNodes.iterator().next().getUsage();
                                        if (usage == USAGES_OUTSIDE_SCOPE_SEPARATOR) {
                                            hint(editor,
                                                    UsageViewManagerImpl.outOfScopeMessage(
                                                            outOfScopeUsages.get(), options.searchScope),
                                                    handler, popupPosition, maxUsages, options, true);
                                        } else {
                                            String message = UsageViewBundle.message("show.usages.only.usage",
                                                    searchScopePresentableName(options));
                                            navigateAndHint(usage, message, handler, popupPosition, maxUsages,
                                                    options);
                                        }
                                        cancel(popup);
                                    } 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));
                                            navigateAndHint(visibleUsage, hint, handler, popupPosition,
                                                    maxUsages, options);
                                            cancel(popup);
                                        }
                                    }
                                } else {
                                    if (popup != null) {
                                        String title = presentation.getTabText();
                                        boolean shouldShowMoreSeparator = visibleNodes
                                                .contains(MORE_USAGES_SEPARATOR_NODE);
                                        String fullTitle = getFullTitle(usages, title, shouldShowMoreSeparator,
                                                visibleNodes.size() - (shouldShowMoreSeparator ? 1 : 0), false);
                                        ((AbstractPopup) popup).setCaption(fullTitle);
                                    }
                                }
                            }
                        }
                    }, project.getDisposed());
                }
            });
    if (popup != null) {
        Disposer.register(popup, new Disposable() {
            @Override
            public void dispose() {
                indicator.cancel();
            }
        });
    }
}