void () { if (isShowing()) { ScrollingUtil.ensureSelectionExists(myResultsPreviewTable); } ModalityState state = ModalityState.current(); finishPreviousPreviewSearch(); mySearchRescheduleOnCancellationsAlarm.cancelAllRequests(); applyTo(myHelper.getModel()); FindModel findModel = new FindModel(); findModel.copyFrom(myHelper.getModel()); if (findModel.getStringToFind().contains("\n")) { findModel.setMultiline(true); } ValidationInfo result = getValidationInfo(myHelper.getModel()); myOKButton.setEnabled(result == null); myComponentValidator.updateInfo(result); ProgressIndicatorBase progressIndicatorWhenSearchStarted = new ProgressIndicatorBase() { @Override public void stop() { super.stop(); onStop(System.identityHashCode(this)); ApplicationManager.getApplication().invokeLater(() -> { if (myNeedReset.compareAndSet(true, false)) { //nothing is found, let's clear previous results reset(); } }); } }; myResultsPreviewSearchProgress = progressIndicatorWhenSearchStarted; int hash = System.identityHashCode(myResultsPreviewSearchProgress); // Use previously shown usage files as hint for faster search and better usage preview performance if pattern length increased Set<VirtualFile> filesToScanInitially = new LinkedHashSet<>(); if (myHelper.myPreviousModel != null && myHelper.myPreviousModel.getStringToFind().length() < myHelper.getModel().getStringToFind().length()) { DefaultTableModel previousModel = (DefaultTableModel)myResultsPreviewTable.getModel(); for (int i = 0, len = previousModel.getRowCount(); i < len; ++i) { Object value = previousModel.getValueAt(i, 0); if (value instanceof FindPopupItem) { UsageInfoAdapter usage = ((FindPopupItem)value).getUsage(); if (usage instanceof UsageInfo2UsageAdapter) { VirtualFile file = ((UsageInfo2UsageAdapter)usage).getFile(); if (file != null) filesToScanInitially.add(file); } } } } myHelper.myPreviousModel = myHelper.getModel().clone(); myReplaceAllButton.setEnabled(false); myReplaceSelectedButton.setEnabled(false); myReplaceSelectedButton.setText(FindBundle.message("find.popup.replace.selected.button", 0)); onStart(hash); if (result != null && result.component != myReplaceComponent) { onStop(hash, result.message); reset(); return; } FindInProjectExecutor projectExecutor = FindInProjectExecutor.Companion.getInstance(); TableCellRenderer renderer = projectExecutor.createTableCellRenderer(); if (renderer == null) renderer = new UsageTableCellRenderer(); myResultsPreviewTable.getColumnModel().getColumn(0).setCellRenderer(renderer); AtomicInteger resultsCount = new AtomicInteger(); AtomicInteger resultsFilesCount = new AtomicInteger(); FindInProjectUtil.setupViewPresentation(myUsageViewPresentation, findModel); Project project = myProject; ProgressManager.getInstance().runProcessWithProgressAsynchronously(new Task.Backgroundable( project, FindBundle.message("find.usages.progress.title")) { @Override public void run(@NotNull ProgressIndicator indicator) { GlobalSearchScope scope = ReadAction.nonBlocking( () -> GlobalSearchScopeUtil.toGlobalSearchScope(FindInProjectUtil.getScopeFromModel(project, myHelper.myPreviousModel), project) ).wrapProgress(indicator).executeSynchronously(); FindUsagesProcessPresentation processPresentation = FindInProjectUtil.setupProcessPresentation(myUsageViewPresentation); ThreadLocal<String> lastUsageFileRef = new ThreadLocal<>(); ThreadLocal<Reference<FindPopupItem>> recentItemRef = new ThreadLocal<>(); projectExecutor.findUsages(project, myResultsPreviewSearchProgress, processPresentation, findModel, filesToScanInitially, usage -> { if (isCancelled()) { onStop(hash); return false; } if (resultsCount.getAndIncrement() >= ShowUsagesAction.getUsagesPageSize()) { onStop(hash); return false; } String file = lastUsageFileRef.get(); String usageFile = PathUtil.toSystemIndependentName(usage.getPath()); if (!usageFile.equals(file)) { resultsFilesCount.incrementAndGet(); lastUsageFileRef.set(usageFile); } FindPopupItem recentItem = SoftReference.dereference(recentItemRef.get()); FindPopupItem newItem; boolean merged = !myHelper.isReplaceState() && recentItem != null && recentItem.getUsage().merge(usage); if (!merged) { if (usage instanceof UsageInfo2UsageAdapter) { ((UsageInfo2UsageAdapter)usage).updateCachedPresentation(); } newItem = new FindPopupItem(usage, usagePresentation(project, scope, usage)); } else { // recompute presentation of a merged instance UsageInfoAdapter recentItemUsage = recentItem.getUsage(); if (recentItemUsage instanceof UsageInfo2UsageAdapter) { ((UsageInfo2UsageAdapter)recentItemUsage).updateCachedPresentation(); } newItem = recentItem.withPresentation(usagePresentation(project, scope, recentItemUsage)); } recentItemRef.set(new WeakReference<>(newItem)); ApplicationManager.getApplication().invokeLater(() -> { if (isCancelled()) { onStop(hash); return; } myPreviewSplitter.getSecondComponent().setVisible(true); DefaultTableModel model = (DefaultTableModel)myResultsPreviewTable.getModel(); if (!merged) { model.addRow(new Object[]{newItem}); } else { model.fireTableRowsUpdated(model.getRowCount() - 1, model.getRowCount() - 1); } myCodePreviewComponent.setVisible(true); if (model.getRowCount() == 1) { myResultsPreviewTable.setRowSelectionInterval(0, 0); } int occurrences = resultsCount.get(); int filesWithOccurrences = resultsFilesCount.get(); myCodePreviewComponent.setVisible(occurrences > 0); myReplaceAllButton.setEnabled(occurrences > 0); myReplaceSelectedButton.setEnabled(occurrences > 0); if (occurrences > 0) { if (occurrences < ShowUsagesAction.getUsagesPageSize()) { myUsagesCount = String.valueOf(occurrences); myFilesCount = String.valueOf(filesWithOccurrences); header.infoLabel.setText(FindBundle.message("message.matches.in.files", occurrences, filesWithOccurrences)); } else { myUsagesCount = occurrences + "+"; myFilesCount = filesWithOccurrences + "+"; header.infoLabel.setText(FindBundle.message("message.matches.in.files.incomplete", occurrences, filesWithOccurrences)); } } else { header.infoLabel.setText(""); } }, state); return true; }); } @Override public void onCancel() { if (isShowing() && progressIndicatorWhenSearchStarted == myResultsPreviewSearchProgress) { scheduleResultsUpdate(); } } boolean isCancelled() { return progressIndicatorWhenSearchStarted != myResultsPreviewSearchProgress || progressIndicatorWhenSearchStarted.isCanceled(); } @Override public void onFinished() { ApplicationManager.getApplication().invokeLater(() -> { if (!isCancelled()) { boolean isEmpty = resultsCount.get() == 0; if (isEmpty) { showEmptyText(FindBundle.message("message.nothingFound")); } } onStop(hash); }, state); } }, myResultsPreviewSearchProgress); }