mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Merge remote-tracking branch 'origin/master'
This commit is contained in:
+6
-1
@@ -36,6 +36,7 @@ import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Condition;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.openapi.util.registry.Registry;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.packageDependencies.DependencyRule;
|
||||
import com.intellij.packageDependencies.DependencyValidationManager;
|
||||
@@ -319,13 +320,17 @@ public abstract class ImportClassFixBase<T extends PsiElement, R extends PsiRefe
|
||||
|
||||
boolean canImportHere = true;
|
||||
|
||||
boolean isInModlessContext = Registry.is("ide.perProjectModality") ?
|
||||
!LaterInvocator.isInModalContextForProject(editor.getProject()) :
|
||||
!LaterInvocator.isInModalContext();
|
||||
|
||||
if (classes.length == 1 &&
|
||||
(canImportHere = canImportHere(allowCaretNearRef, editor, psiFile, classes[0].getName())) &&
|
||||
(FileTypeUtils.isInServerPageFile(psiFile) ?
|
||||
CodeInsightSettings.getInstance().JSP_ADD_UNAMBIGIOUS_IMPORTS_ON_THE_FLY :
|
||||
CodeInsightSettings.getInstance().ADD_UNAMBIGIOUS_IMPORTS_ON_THE_FLY) &&
|
||||
(ApplicationManager.getApplication().isUnitTestMode() || DaemonListeners.canChangeFileSilently(psiFile)) &&
|
||||
!LaterInvocator.isInModalContext() &&
|
||||
isInModlessContext &&
|
||||
!autoImportWillInsertUnexpectedCharacters(classes[0])
|
||||
) {
|
||||
CommandProcessor.getInstance().runUndoTransparentAction(() -> action.execute());
|
||||
|
||||
+1
-1
@@ -142,7 +142,7 @@ public class MigrateAssertToMatcherAssertInspection extends LocalInspectionTool
|
||||
replaced = TypeConversionDescriptor.replaceExpression(methodCall, templatePair.getFirst(), templatePair.getSecond());
|
||||
}
|
||||
catch (IncorrectOperationException e) {
|
||||
LOG.error("Replacer can't can't match expression:\n" +
|
||||
LOG.error("Replacer can't match expression:\n" +
|
||||
methodCall.getText() +
|
||||
"\nwith replacement template:\n(" +
|
||||
templatePair.getFirst() +
|
||||
|
||||
+88
-9
@@ -23,6 +23,7 @@ import com.intellij.openapi.diagnostic.FrequentEventDetector;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.progress.ProcessCanceledException;
|
||||
import com.intellij.openapi.progress.ProgressIndicator;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.ActionCallback;
|
||||
import com.intellij.openapi.util.Condition;
|
||||
import com.intellij.openapi.util.Conditions;
|
||||
@@ -33,6 +34,7 @@ import com.intellij.util.ExceptionUtil;
|
||||
import com.intellij.util.concurrency.Semaphore;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.containers.Stack;
|
||||
import com.intellij.util.containers.WeakHashMap;
|
||||
import com.intellij.util.ui.UIUtil;
|
||||
import io.netty.util.internal.SystemPropertyUtil;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
@@ -80,7 +82,13 @@ public class LaterInvocator {
|
||||
}
|
||||
}
|
||||
|
||||
// Application modal entities
|
||||
private static final List<Object> ourModalEntities = ContainerUtil.createLockFreeCopyOnWriteList();
|
||||
|
||||
// Per-project modal entities
|
||||
private static WeakHashMap<Project, List<Dialog>> projectToModalEntities = new WeakHashMap<>();
|
||||
private static WeakHashMap<Project, Stack<ModalityState>> projectToModalEntitiesStack = new WeakHashMap<>();
|
||||
|
||||
private static final Stack<ModalityState> ourModalityStack = new Stack<>(ModalityState.NON_MODAL);
|
||||
private static final List<RunnableInfo> ourQueue = new ArrayList<>(); //protected by LOCK
|
||||
private static volatile int ourQueueSkipCount; // optimization
|
||||
@@ -204,6 +212,60 @@ public class LaterInvocator {
|
||||
}
|
||||
}
|
||||
|
||||
public static void enterModal(Project project, Dialog dialog) {
|
||||
LOG.assertTrue(isDispatchThread(), "enterModal() should be invoked in event-dispatch thread");
|
||||
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("enterModal:" + dialog.getName() + " ; for project: " + project.getName());
|
||||
}
|
||||
|
||||
if (project == null) {
|
||||
enterModal(dialog);
|
||||
}
|
||||
|
||||
List<Dialog> modalEntitiesList = projectToModalEntities.getOrDefault(project, ContainerUtil.createLockFreeCopyOnWriteList());
|
||||
projectToModalEntities.put(project, modalEntitiesList);
|
||||
modalEntitiesList.add(dialog);
|
||||
|
||||
Stack<ModalityState> modalEntitiesStack = projectToModalEntitiesStack.getOrDefault(project, new Stack<>(ModalityState.NON_MODAL));
|
||||
projectToModalEntitiesStack.put(project, modalEntitiesStack);
|
||||
modalEntitiesStack.push(new ModalityStateEx(ArrayUtil.toObjectArray(ourModalEntities)));
|
||||
}
|
||||
|
||||
|
||||
public static void leaveModal(Project project, Dialog dialog) {
|
||||
LOG.assertTrue(isDispatchThread(), "leaveModal() should be invoked in event-dispatch thread");
|
||||
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("leaveModal:" + dialog.getName() + " ; for project: " + project.getName());
|
||||
}
|
||||
|
||||
ourModalityStateMulticaster.getMulticaster().beforeModalityStateChanged(false);
|
||||
|
||||
int index = ourModalEntities.indexOf(dialog);
|
||||
|
||||
if (index != -1) {
|
||||
ourModalEntities.remove(index);
|
||||
ourModalityStack.remove(index + 1);
|
||||
for (int i = 1; i < ourModalityStack.size(); i++) {
|
||||
((ModalityStateEx)ourModalityStack.get(i)).removeModality(dialog);
|
||||
}
|
||||
} else {
|
||||
List<Dialog> dialogs = projectToModalEntities.get(project);
|
||||
int perProjectIndex = dialogs.indexOf(dialog);
|
||||
LOG.assertTrue(perProjectIndex >= 0);
|
||||
dialogs.remove(perProjectIndex);
|
||||
Stack<ModalityState> states = projectToModalEntitiesStack.get(project);
|
||||
states.remove(perProjectIndex + 1);
|
||||
for (int i = 1; i < states.size(); i++) {
|
||||
((ModalityStateEx)states.get(i)).removeModality(dialog);
|
||||
}
|
||||
}
|
||||
|
||||
ourQueueSkipCount = 0;
|
||||
requestFlush();
|
||||
}
|
||||
|
||||
public static void leaveModal(@NotNull Object modalEntity) {
|
||||
LOG.assertTrue(isDispatchThread(), "leaveModal() should be invoked in event-dispatch thread");
|
||||
|
||||
@@ -235,13 +297,17 @@ public class LaterInvocator {
|
||||
requestFlush();
|
||||
}
|
||||
|
||||
public static Object[] getCurrentModalEntitiesForProject(Project project) {
|
||||
ApplicationManager.getApplication().assertIsDispatchThread();
|
||||
if (ourModalEntities.isEmpty()) {
|
||||
return ArrayUtil.toObjectArray(ourModalEntities);
|
||||
}
|
||||
return ArrayUtil.toObjectArray(projectToModalEntities.get(project));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static Object[] getCurrentModalEntities() {
|
||||
ApplicationManager.getApplication().assertIsDispatchThread();
|
||||
//TODO!
|
||||
//LOG.assertTrue(IdeEventQueue.getInstance().isInInputEvent() || isInMyRunnable());
|
||||
|
||||
return ArrayUtil.toObjectArray(ourModalEntities);
|
||||
return getCurrentModalEntitiesForProject(null);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -249,9 +315,22 @@ public class LaterInvocator {
|
||||
return ourModalityStack.peek();
|
||||
}
|
||||
|
||||
public static boolean isInModalContext() {
|
||||
public static boolean isInModalContextForProject(final Project project) {
|
||||
LOG.assertTrue(isDispatchThread());
|
||||
return !ourModalEntities.isEmpty();
|
||||
|
||||
if (ourModalEntities.isEmpty()) return false;
|
||||
|
||||
List<Dialog> modalEntitiesForProject = getModalEntitiesForProject(project);
|
||||
|
||||
return modalEntitiesForProject == null || modalEntitiesForProject.isEmpty();
|
||||
}
|
||||
|
||||
private static List<Dialog> getModalEntitiesForProject(Project project) {
|
||||
return projectToModalEntities.get(project);
|
||||
}
|
||||
|
||||
public static boolean isInModalContext() {
|
||||
return isInModalContextForProject(null);
|
||||
}
|
||||
|
||||
private static boolean isDispatchThread() {
|
||||
@@ -268,8 +347,8 @@ public class LaterInvocator {
|
||||
* There might be some requests in the queue, but ourFlushQueueRunnable might not be scheduled yet. In these circumstances
|
||||
* {@link EventQueue#peekEvent()} default implementation would return null, and {@link UIUtil#dispatchAllInvocationEvents()} would
|
||||
* stop processing events too early and lead to spurious test failures.
|
||||
*
|
||||
* @see IdeEventQueue#peekEvent()
|
||||
*
|
||||
* @see IdeEventQueue#peekEvent()
|
||||
*/
|
||||
public static boolean ensureFlushRequested() {
|
||||
if (getNextEvent(false) != null) {
|
||||
|
||||
@@ -438,9 +438,15 @@ public class DialogWrapperPeerImpl extends DialogWrapperPeer implements FocusTra
|
||||
|
||||
boolean changeModalityState = appStarted && myDialog.isModal()
|
||||
&& !isProgressDialog(); // ProgressWindow starts a modality state itself
|
||||
Project project = myProject;
|
||||
|
||||
if (changeModalityState) {
|
||||
commandProcessor.enterModal();
|
||||
LaterInvocator.enterModal(myDialog);
|
||||
if (Registry.is("ide.perProjectModality")) {
|
||||
LaterInvocator.enterModal(project, myDialog.getWindow());
|
||||
} else {
|
||||
LaterInvocator.enterModal(myDialog);
|
||||
}
|
||||
}
|
||||
|
||||
if (appStarted) {
|
||||
@@ -453,7 +459,11 @@ public class DialogWrapperPeerImpl extends DialogWrapperPeer implements FocusTra
|
||||
finally {
|
||||
if (changeModalityState) {
|
||||
commandProcessor.leaveModal();
|
||||
LaterInvocator.leaveModal(myDialog);
|
||||
if (Registry.is("ide.perProjectModality")) {
|
||||
LaterInvocator.leaveModal(project, myDialog.getWindow());
|
||||
} else {
|
||||
LaterInvocator.leaveModal(myDialog);
|
||||
}
|
||||
}
|
||||
|
||||
myDialog.getFocusManager().doWhenFocusSettlesDown(result.createSetDoneRunnable());
|
||||
|
||||
Reference in New Issue
Block a user