mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
goto class: if background process is canceled and not restarted, the list should become empty and "in background update" status should be cleared
* fixes unresponsiveness after typing a slash and quickly pressing Enter
This commit is contained in:
@@ -35,6 +35,7 @@ import com.intellij.openapi.actionSystem.*;
|
||||
import com.intellij.openapi.application.ApplicationAdapter;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.application.ModalityState;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.editor.colors.EditorColorsManager;
|
||||
import com.intellij.openapi.editor.colors.EditorColorsScheme;
|
||||
import com.intellij.openapi.fileTypes.UnknownFileType;
|
||||
@@ -102,6 +103,7 @@ import java.util.List;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
public abstract class ChooseByNameBase {
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.ide.util.gotoByName.ChooseByNameBase");
|
||||
protected final Project myProject;
|
||||
protected final ChooseByNameModel myModel;
|
||||
protected ChooseByNameItemProvider myProvider;
|
||||
@@ -133,7 +135,6 @@ public abstract class ChooseByNameBase {
|
||||
|
||||
private final ListUpdater myListUpdater = new ListUpdater();
|
||||
|
||||
private volatile boolean myListIsUpToDate = false;
|
||||
private boolean myDisposedFlag = false;
|
||||
private ActionCallback myPostponedOkAction;
|
||||
|
||||
@@ -278,7 +279,7 @@ public abstract class ChooseByNameBase {
|
||||
if (PlatformDataKeys.HELP_ID.is(dataId)) {
|
||||
return myModel.getHelpId();
|
||||
}
|
||||
if (!myListIsUpToDate) {
|
||||
if (myCalcElementsThread != null) {
|
||||
return null;
|
||||
}
|
||||
if (CommonDataKeys.PSI_ELEMENT.is(dataId)) {
|
||||
@@ -499,7 +500,7 @@ public abstract class ChooseByNameBase {
|
||||
myTextField.addFocusListener(new FocusAdapter() {
|
||||
@Override
|
||||
public void focusLost(@NotNull final FocusEvent e) {
|
||||
cancelCalcElementsThread(); // cancel thread as early as possible
|
||||
cancelListUpdater(); // cancel thread as early as possible
|
||||
myHideAlarm.addRequest(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
@@ -759,24 +760,29 @@ public abstract class ChooseByNameBase {
|
||||
}
|
||||
|
||||
protected void doClose(final boolean ok) {
|
||||
try {
|
||||
if (checkDisposed()) return;
|
||||
if (checkDisposed()) return;
|
||||
|
||||
if (postponeCloseWhenListReady(ok)) return;
|
||||
if (postponeCloseWhenListReady(ok)) return;
|
||||
|
||||
cancelListUpdater();
|
||||
close(ok);
|
||||
cancelListUpdater();
|
||||
close(ok);
|
||||
|
||||
clearPostponedOkAction(ok);
|
||||
}
|
||||
finally {
|
||||
myListModel.clear();
|
||||
cancelCalcElementsThread();
|
||||
}
|
||||
clearPostponedOkAction(ok);
|
||||
myListModel.clear();
|
||||
}
|
||||
|
||||
protected void cancelListUpdater() {
|
||||
cancelCalcElementsThread();
|
||||
final CalcElementsThread calcElementsThread = myCalcElementsThread;
|
||||
if (calcElementsThread != null && calcElementsThread.cancel()) {
|
||||
UIUtil.invokeLaterIfNeeded(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (!checkDisposed() && calcElementsThread == myCalcElementsThread) {
|
||||
backgroundCalculationFinished(Collections.emptyList(), 0);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
myListUpdater.cancelAll();
|
||||
}
|
||||
|
||||
@@ -784,7 +790,7 @@ public abstract class ChooseByNameBase {
|
||||
if (!isToFixLostTyping()) return false;
|
||||
|
||||
final String text = myTextField.getText();
|
||||
if (ok && !myListIsUpToDate && text != null && !text.trim().isEmpty()) {
|
||||
if (ok && myCalcElementsThread != null && text != null && !text.trim().isEmpty()) {
|
||||
myPostponedOkAction = new ActionCallback();
|
||||
IdeFocusManager.getInstance(myProject).typeAheadUntil(myPostponedOkAction);
|
||||
return true;
|
||||
@@ -885,7 +891,7 @@ public abstract class ChooseByNameBase {
|
||||
Disposer.register(myTextPopup, new Disposable() {
|
||||
@Override
|
||||
public void dispose() {
|
||||
cancelCalcElementsThread();
|
||||
cancelListUpdater();
|
||||
}
|
||||
});
|
||||
myTextPopup.show(layeredPane);
|
||||
@@ -917,8 +923,6 @@ public abstract class ChooseByNameBase {
|
||||
return layeredPane;
|
||||
}
|
||||
|
||||
private final Object myRebuildMutex = new Object();
|
||||
|
||||
protected void rebuildList(final int pos,
|
||||
final int delay,
|
||||
@NotNull final ModalityState modalityState,
|
||||
@@ -928,11 +932,13 @@ public abstract class ChooseByNameBase {
|
||||
return;
|
||||
}
|
||||
|
||||
myListIsUpToDate = false;
|
||||
myAlarm.cancelAllRequests();
|
||||
myListUpdater.cancelAll();
|
||||
|
||||
cancelCalcElementsThread();
|
||||
final CalcElementsThread calcElementsThread = myCalcElementsThread;
|
||||
if (calcElementsThread != null) {
|
||||
calcElementsThread.cancel();
|
||||
}
|
||||
|
||||
final String text = myTextField.getText();
|
||||
if (!canShowListForEmptyPattern() &&
|
||||
@@ -960,24 +966,14 @@ public abstract class ChooseByNameBase {
|
||||
scheduleCalcElements(text, myCheckBox.isSelected(), modalityState, new Consumer<Set<?>>() {
|
||||
@Override
|
||||
public void consume(Set<?> elements) {
|
||||
synchronized (myRebuildMutex) {
|
||||
ApplicationManager.getApplication().assertIsDispatchThread();
|
||||
if (checkDisposed()) {
|
||||
return;
|
||||
}
|
||||
ApplicationManager.getApplication().assertIsDispatchThread();
|
||||
if (checkDisposed()) {
|
||||
return;
|
||||
}
|
||||
backgroundCalculationFinished(elements, pos);
|
||||
|
||||
myListIsUpToDate = true;
|
||||
setElementsToList(pos, elements);
|
||||
myList.repaint();
|
||||
chosenElementMightChange();
|
||||
|
||||
if (elements.isEmpty()) {
|
||||
myTextFieldPanel.hideHint();
|
||||
}
|
||||
|
||||
if (postRunnable != null) {
|
||||
postRunnable.run();
|
||||
}
|
||||
if (postRunnable != null) {
|
||||
postRunnable.run();
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -992,6 +988,17 @@ public abstract class ChooseByNameBase {
|
||||
}
|
||||
}
|
||||
|
||||
private void backgroundCalculationFinished(Collection<?> result, int toSelect) {
|
||||
myCalcElementsThread = null;
|
||||
setElementsToList(toSelect, result);
|
||||
myList.repaint();
|
||||
chosenElementMightChange();
|
||||
|
||||
if (result.isEmpty()) {
|
||||
myTextFieldPanel.hideHint();
|
||||
}
|
||||
}
|
||||
|
||||
public void scheduleCalcElements(String text,
|
||||
boolean checkboxState,
|
||||
ModalityState modalityState,
|
||||
@@ -1008,16 +1015,7 @@ public abstract class ChooseByNameBase {
|
||||
return myShowListAfterCompletionKeyStroke;
|
||||
}
|
||||
|
||||
private CalcElementsThread cancelCalcElementsThread() {
|
||||
CalcElementsThread calcElementsThread = myCalcElementsThread;
|
||||
if (calcElementsThread != null) {
|
||||
calcElementsThread.cancel();
|
||||
myCalcElementsThread = null;
|
||||
}
|
||||
return calcElementsThread;
|
||||
}
|
||||
|
||||
private void setElementsToList(int pos, @NotNull Set<?> elements) {
|
||||
private void setElementsToList(int pos, @NotNull Collection<?> elements) {
|
||||
myListUpdater.cancelAll();
|
||||
if (checkDisposed()) return;
|
||||
if (elements.isEmpty()) {
|
||||
@@ -1207,7 +1205,7 @@ public abstract class ChooseByNameBase {
|
||||
values.remove(EXTRA_ELEM);
|
||||
values.remove(NON_PREFIX_SEPARATOR);
|
||||
|
||||
if (myListIsUpToDate || !values.isEmpty()) {
|
||||
if (myCalcElementsThread == null || !values.isEmpty()) {
|
||||
return values;
|
||||
}
|
||||
|
||||
@@ -1565,6 +1563,7 @@ public abstract class ChooseByNameBase {
|
||||
@Override
|
||||
public void run() {
|
||||
if (!myCancelled.isCanceled()) {
|
||||
LOG.assertTrue(myCalcElementsThread == CalcElementsThread.this);
|
||||
myCallback.consume(edt ? filter(elements) : filtered);
|
||||
}
|
||||
}
|
||||
@@ -1622,8 +1621,12 @@ public abstract class ChooseByNameBase {
|
||||
return elementsArray.size() >= myMaximumListSizeLimit;
|
||||
}
|
||||
|
||||
private void cancel() {
|
||||
private boolean cancel() {
|
||||
if (myCancelled.isCanceled()) {
|
||||
return false;
|
||||
}
|
||||
myCancelled.cancel();
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1705,7 +1708,7 @@ public abstract class ChooseByNameBase {
|
||||
final LinkedHashSet<Object> nonPrefixMatchElementsArray = new LinkedHashSet<Object>();
|
||||
hideHint();
|
||||
ProgressManager.getInstance().run(new Task.Modal(myProject, prefixPattern, true) {
|
||||
private ChooseByNameBase.CalcElementsThread myCalcElementsThread;
|
||||
private ChooseByNameBase.CalcElementsThread myCalcUsagesThread;
|
||||
|
||||
@Override
|
||||
public void run(@NotNull final ProgressIndicator indicator) {
|
||||
@@ -1716,7 +1719,7 @@ public abstract class ChooseByNameBase {
|
||||
@Override
|
||||
public void run() {
|
||||
final boolean[] overFlow = {false};
|
||||
myCalcElementsThread = new CalcElementsThread(text, everywhere, null, ModalityState.NON_MODAL, false) {
|
||||
myCalcUsagesThread = new CalcElementsThread(text, everywhere, null, ModalityState.NON_MODAL, false) {
|
||||
private final AtomicBoolean userAskedToAbort = new AtomicBoolean();
|
||||
@Override
|
||||
protected boolean isOverflow(@NotNull Set<Object> elementsArray) {
|
||||
@@ -1734,11 +1737,11 @@ public abstract class ChooseByNameBase {
|
||||
|
||||
boolean anyPlace = isSearchInAnyPlace();
|
||||
setSearchInAnyPlace(false);
|
||||
myCalcElementsThread.addElementsByPattern(text, prefixMatchElementsArray, indicator, everywhere);
|
||||
myCalcUsagesThread.addElementsByPattern(text, prefixMatchElementsArray, indicator, everywhere);
|
||||
setSearchInAnyPlace(anyPlace);
|
||||
|
||||
if (anyPlace && !overFlow[0]) {
|
||||
myCalcElementsThread.addElementsByPattern(text, nonPrefixMatchElementsArray, indicator, everywhere);
|
||||
myCalcUsagesThread.addElementsByPattern(text, nonPrefixMatchElementsArray, indicator, everywhere);
|
||||
nonPrefixMatchElementsArray.removeAll(prefixMatchElementsArray);
|
||||
}
|
||||
|
||||
@@ -1756,7 +1759,7 @@ public abstract class ChooseByNameBase {
|
||||
|
||||
@Override
|
||||
public void onCancel() {
|
||||
cancelCalcElementsThread();
|
||||
myCalcUsagesThread.cancel();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user