mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
moved CommandProcessor to core
This commit is contained in:
@@ -25,6 +25,8 @@ import com.intellij.mock.MockFileDocumentManagerImpl;
|
||||
import com.intellij.mock.MockReferenceProvidersRegistry;
|
||||
import com.intellij.openapi.Disposable;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.command.CommandProcessor;
|
||||
import com.intellij.openapi.command.impl.CoreCommandProcessor;
|
||||
import com.intellij.openapi.components.ExtensionAreas;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.editor.impl.DocumentImpl;
|
||||
@@ -76,23 +78,22 @@ import java.util.concurrent.TimeoutException;
|
||||
*/
|
||||
public class CoreApplicationEnvironment {
|
||||
private final CoreFileTypeRegistry myFileTypeRegistry;
|
||||
private final CoreEncodingRegistry myEncodingRegistry;
|
||||
protected final MockApplication myApplication;
|
||||
private final CoreLocalFileSystem myLocalFileSystem;
|
||||
protected final VirtualFileSystem myJarFileSystem;
|
||||
private final Disposable myParentDisposable;
|
||||
@NotNull private final Disposable myParentDisposable;
|
||||
|
||||
public CoreApplicationEnvironment(@NotNull Disposable parentDisposable) {
|
||||
myParentDisposable = parentDisposable;
|
||||
Extensions.cleanRootArea(myParentDisposable);
|
||||
|
||||
myFileTypeRegistry = new CoreFileTypeRegistry();
|
||||
myEncodingRegistry = new CoreEncodingRegistry();
|
||||
CoreEncodingRegistry encodingRegistry = new CoreEncodingRegistry();
|
||||
|
||||
myApplication = createApplication(myParentDisposable);
|
||||
ApplicationManager.setApplication(myApplication,
|
||||
new StaticGetter<FileTypeRegistry>(myFileTypeRegistry),
|
||||
new StaticGetter<EncodingRegistry>(myEncodingRegistry),
|
||||
new StaticGetter<EncodingRegistry>(encodingRegistry),
|
||||
myParentDisposable);
|
||||
myLocalFileSystem = createLocalFileSystem();
|
||||
myJarFileSystem = createJarFileSystem();
|
||||
@@ -112,12 +113,12 @@ public class CoreApplicationEnvironment {
|
||||
registerComponentInstance(appContainer, VirtualFileManager.class, virtualFileManager);
|
||||
|
||||
registerApplicationService(VirtualFilePointerManager.class, createVirtualFilePointerManager());
|
||||
myApplication.registerService(DefaultASTFactory.class, new CoreASTFactory());
|
||||
myApplication.registerService(PsiBuilderFactory.class, new PsiBuilderFactoryImpl());
|
||||
myApplication.registerService(ReferenceProvidersRegistry.class, new MockReferenceProvidersRegistry());
|
||||
myApplication.registerService(StubTreeLoader.class, new CoreStubTreeLoader());
|
||||
myApplication.registerService(PsiReferenceService.class, new PsiReferenceServiceImpl());
|
||||
myApplication.registerService(MetaDataRegistrar.class, new MetaRegistry());
|
||||
registerApplicationService(DefaultASTFactory.class, new CoreASTFactory());
|
||||
registerApplicationService(PsiBuilderFactory.class, new PsiBuilderFactoryImpl());
|
||||
registerApplicationService(ReferenceProvidersRegistry.class, new MockReferenceProvidersRegistry());
|
||||
registerApplicationService(StubTreeLoader.class, new CoreStubTreeLoader());
|
||||
registerApplicationService(PsiReferenceService.class, new PsiReferenceServiceImpl());
|
||||
registerApplicationService(MetaDataRegistrar.class, new MetaRegistry());
|
||||
|
||||
registerApplicationExtensionPoint(ContentBasedFileSubstitutor.EP_NAME, ContentBasedFileSubstitutor.class);
|
||||
registerExtensionPoint(Extensions.getRootArea(), BinaryFileStubBuilders.EP_NAME, FileTypeExtensionPoint.class);
|
||||
@@ -127,8 +128,9 @@ public class CoreApplicationEnvironment {
|
||||
|
||||
ProgressIndicatorProvider.ourInstance = createProgressIndicatorProvider();
|
||||
|
||||
myApplication.registerService(JobLauncher.class, createJobLauncher());
|
||||
myApplication.registerService(CodeFoldingSettings.class, new CodeFoldingSettings());
|
||||
registerApplicationService(JobLauncher.class, createJobLauncher());
|
||||
registerApplicationService(CodeFoldingSettings.class, new CodeFoldingSettings());
|
||||
registerApplicationService(CommandProcessor.class, new CoreCommandProcessor());
|
||||
}
|
||||
|
||||
public <T> void registerApplicationService(@NotNull Class<T> serviceInterface, @NotNull T serviceImplementation) {
|
||||
@@ -256,32 +258,33 @@ public class CoreApplicationEnvironment {
|
||||
return myApplication;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Disposable getParentDisposable() {
|
||||
return myParentDisposable;
|
||||
}
|
||||
|
||||
public <T> void registerApplicationComponent(final Class<T> interfaceClass, final T implementation) {
|
||||
public <T> void registerApplicationComponent(@NotNull Class<T> interfaceClass, @NotNull T implementation) {
|
||||
registerComponentInstance(myApplication.getPicoContainer(), interfaceClass, implementation);
|
||||
}
|
||||
|
||||
public void registerFileType(FileType fileType, String extension) {
|
||||
public void registerFileType(@NotNull FileType fileType, @NotNull String extension) {
|
||||
myFileTypeRegistry.registerFileType(fileType, extension);
|
||||
}
|
||||
|
||||
public void registerParserDefinition(ParserDefinition definition) {
|
||||
public void registerParserDefinition(@NotNull ParserDefinition definition) {
|
||||
addExplicitExtension(LanguageParserDefinitions.INSTANCE, definition.getFileNodeType().getLanguage(), definition);
|
||||
}
|
||||
|
||||
public static <T> void registerComponentInstance(final MutablePicoContainer container, final Class<T> key, final T implementation) {
|
||||
public static <T> void registerComponentInstance(@NotNull MutablePicoContainer container, @NotNull Class<T> key, @NotNull T implementation) {
|
||||
container.unregisterComponent(key);
|
||||
container.registerComponentInstance(key, implementation);
|
||||
}
|
||||
|
||||
public <T> void addExplicitExtension(final LanguageExtension<T> instance, final Language language, final T object) {
|
||||
public <T> void addExplicitExtension(@NotNull LanguageExtension<T> instance, @NotNull Language language, @NotNull T object) {
|
||||
doAddExplicitExtension(instance, language, object);
|
||||
}
|
||||
|
||||
public void registerParserDefinition(Language language, ParserDefinition parserDefinition) {
|
||||
public void registerParserDefinition(@NotNull Language language, @NotNull ParserDefinition parserDefinition) {
|
||||
addExplicitExtension(LanguageParserDefinitions.INSTANCE, language, parserDefinition);
|
||||
}
|
||||
|
||||
@@ -303,7 +306,7 @@ public class CoreApplicationEnvironment {
|
||||
doAddExplicitExtension(instance, aClass, object);
|
||||
}
|
||||
|
||||
public <T> void addExtension(ExtensionPointName<T> name, final T extension) {
|
||||
public <T> void addExtension(@NotNull ExtensionPointName<T> name, @NotNull final T extension) {
|
||||
final ExtensionPoint<T> extensionPoint = Extensions.getRootArea().getExtensionPoint(name);
|
||||
extensionPoint.registerExtension(extension);
|
||||
Disposer.register(myParentDisposable, new Disposable() {
|
||||
@@ -315,28 +318,31 @@ public class CoreApplicationEnvironment {
|
||||
}
|
||||
|
||||
|
||||
public static <T> void registerExtensionPoint(final ExtensionsArea area, final ExtensionPointName<T> extensionPointName,
|
||||
final Class<? extends T> aClass) {
|
||||
public static <T> void registerExtensionPoint(@NotNull ExtensionsArea area,
|
||||
@NotNull ExtensionPointName<T> extensionPointName,
|
||||
@NotNull Class<? extends T> aClass) {
|
||||
final String name = extensionPointName.getName();
|
||||
registerExtensionPoint(area, name, aClass);
|
||||
}
|
||||
|
||||
public static <T> void registerExtensionPoint(ExtensionsArea area, String name, Class<? extends T> aClass) {
|
||||
public static <T> void registerExtensionPoint(@NotNull ExtensionsArea area, @NotNull String name, @NotNull Class<? extends T> aClass) {
|
||||
if (!area.hasExtensionPoint(name)) {
|
||||
ExtensionPoint.Kind kind = aClass.isInterface() || (aClass.getModifiers() & Modifier.ABSTRACT) != 0 ? ExtensionPoint.Kind.INTERFACE : ExtensionPoint.Kind.BEAN_CLASS;
|
||||
area.registerExtensionPoint(name, aClass.getName(), kind);
|
||||
}
|
||||
}
|
||||
|
||||
public static <T> void registerApplicationExtensionPoint(final ExtensionPointName<T> extensionPointName, final Class<? extends T> aClass) {
|
||||
public static <T> void registerApplicationExtensionPoint(@NotNull ExtensionPointName<T> extensionPointName, @NotNull Class<? extends T> aClass) {
|
||||
final String name = extensionPointName.getName();
|
||||
registerExtensionPoint(Extensions.getRootArea(), name, aClass);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public CoreLocalFileSystem getLocalFileSystem() {
|
||||
return myLocalFileSystem;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public VirtualFileSystem getJarFileSystem() {
|
||||
return myJarFileSystem;
|
||||
}
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2009 JetBrains s.r.o.
|
||||
* Copyright 2000-2014 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2009 JetBrains s.r.o.
|
||||
* Copyright 2000-2014 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -0,0 +1,361 @@
|
||||
/*
|
||||
* Copyright 2000-2014 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.openapi.command.impl;
|
||||
|
||||
import com.intellij.openapi.Disposable;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.command.CommandEvent;
|
||||
import com.intellij.openapi.command.CommandListener;
|
||||
import com.intellij.openapi.command.CommandProcessorEx;
|
||||
import com.intellij.openapi.command.UndoConfirmationPolicy;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Disposer;
|
||||
import com.intellij.openapi.util.EmptyRunnable;
|
||||
import com.intellij.openapi.util.Ref;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import org.jetbrains.annotations.Nls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Stack;
|
||||
|
||||
public class CoreCommandProcessor extends CommandProcessorEx {
|
||||
private static class CommandDescriptor {
|
||||
public final Runnable myCommand;
|
||||
public final Project myProject;
|
||||
public String myName;
|
||||
public Object myGroupId;
|
||||
public final Document myDocument;
|
||||
public final UndoConfirmationPolicy myUndoConfirmationPolicy;
|
||||
|
||||
public CommandDescriptor(Runnable command,
|
||||
Project project,
|
||||
String name,
|
||||
Object groupId,
|
||||
UndoConfirmationPolicy undoConfirmationPolicy,
|
||||
Document document) {
|
||||
myCommand = command;
|
||||
myProject = project;
|
||||
myName = name;
|
||||
myGroupId = groupId;
|
||||
myUndoConfirmationPolicy = undoConfirmationPolicy;
|
||||
myDocument = document;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "'" + myName + "', group: '" + myGroupId + "'";
|
||||
}
|
||||
}
|
||||
|
||||
protected CommandDescriptor myCurrentCommand = null;
|
||||
private final Stack<CommandDescriptor> myInterruptedCommands = new Stack<CommandDescriptor>();
|
||||
|
||||
// private HashMap myStatisticsMap = new HashMap(); // command name --> count
|
||||
|
||||
// private HashMap myStatisticsMap = new HashMap(); // command name --> count
|
||||
|
||||
private final List<CommandListener> myListeners = ContainerUtil.createLockFreeCopyOnWriteList();
|
||||
|
||||
private int myUndoTransparentCount = 0;
|
||||
|
||||
@Override
|
||||
public void executeCommand(@NotNull Runnable runnable, String name, Object groupId) {
|
||||
executeCommand(null, runnable, name, groupId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void executeCommand(Project project, @NotNull Runnable runnable, String name, Object groupId) {
|
||||
executeCommand(project, runnable, name, groupId, UndoConfirmationPolicy.DEFAULT);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void executeCommand(Project project, @NotNull Runnable runnable, String name, Object groupId, Document document) {
|
||||
executeCommand(project, runnable, name, groupId, UndoConfirmationPolicy.DEFAULT, document);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void executeCommand(Project project,
|
||||
@NotNull final Runnable command,
|
||||
final String name,
|
||||
final Object groupId,
|
||||
@NotNull UndoConfirmationPolicy confirmationPolicy) {
|
||||
executeCommand(project, command, name, groupId, confirmationPolicy, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void executeCommand(Project project,
|
||||
@NotNull final Runnable command,
|
||||
final String name,
|
||||
final Object groupId,
|
||||
@NotNull UndoConfirmationPolicy confirmationPolicy,
|
||||
Document document) {
|
||||
ApplicationManager.getApplication().assertIsDispatchThread();
|
||||
if (project != null && project.isDisposed()) return;
|
||||
|
||||
if (CommandLog.LOG.isDebugEnabled()) {
|
||||
CommandLog.LOG.debug("executeCommand: " + command + ", name = " + name + ", groupId = " + groupId);
|
||||
}
|
||||
|
||||
if (myCurrentCommand != null) {
|
||||
command.run();
|
||||
return;
|
||||
}
|
||||
Throwable throwable = null;
|
||||
try {
|
||||
myCurrentCommand = new CommandDescriptor(command, project, name, groupId, confirmationPolicy, document);
|
||||
fireCommandStarted();
|
||||
command.run();
|
||||
}
|
||||
catch (Throwable th) {
|
||||
throwable = th;
|
||||
}
|
||||
finally {
|
||||
finishCommand(project, myCurrentCommand, throwable);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public Object startCommand(final Project project,
|
||||
@Nls final String name,
|
||||
final Object groupId,
|
||||
final UndoConfirmationPolicy undoConfirmationPolicy) {
|
||||
ApplicationManager.getApplication().assertIsDispatchThread();
|
||||
if (project != null && project.isDisposed()) return null;
|
||||
|
||||
if (CommandLog.LOG.isDebugEnabled()) {
|
||||
CommandLog.LOG.debug("startCommand: name = " + name + ", groupId = " + groupId);
|
||||
}
|
||||
|
||||
if (myCurrentCommand != null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
Document document = groupId instanceof Ref && ((Ref)groupId).get() instanceof Document ? (Document)((Ref)groupId).get() : null;
|
||||
myCurrentCommand = new CommandDescriptor(EmptyRunnable.INSTANCE, project, name, groupId, undoConfirmationPolicy, document);
|
||||
fireCommandStarted();
|
||||
return myCurrentCommand;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void finishCommand(final Project project, final Object command, final Throwable throwable) {
|
||||
ApplicationManager.getApplication().assertIsDispatchThread();
|
||||
CommandLog.LOG.assertTrue(myCurrentCommand != null, "no current command in progress");
|
||||
}
|
||||
|
||||
protected void fireCommandFinished() {
|
||||
ApplicationManager.getApplication().assertIsDispatchThread();
|
||||
CommandDescriptor currentCommand = myCurrentCommand;
|
||||
CommandEvent event = new CommandEvent(this, currentCommand.myCommand,
|
||||
currentCommand.myName,
|
||||
currentCommand.myGroupId,
|
||||
currentCommand.myProject,
|
||||
currentCommand.myUndoConfirmationPolicy,
|
||||
currentCommand.myDocument);
|
||||
try {
|
||||
for (CommandListener listener : myListeners) {
|
||||
try {
|
||||
listener.beforeCommandFinished(event);
|
||||
}
|
||||
catch (Throwable e) {
|
||||
CommandLog.LOG.error(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
finally {
|
||||
myCurrentCommand = null;
|
||||
for (CommandListener listener : myListeners) {
|
||||
try {
|
||||
listener.commandFinished(event);
|
||||
}
|
||||
catch (Throwable e) {
|
||||
CommandLog.LOG.error(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void enterModal() {
|
||||
ApplicationManager.getApplication().assertIsDispatchThread();
|
||||
CommandDescriptor currentCommand = myCurrentCommand;
|
||||
myInterruptedCommands.push(currentCommand);
|
||||
if (currentCommand != null) {
|
||||
fireCommandFinished();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void leaveModal() {
|
||||
ApplicationManager.getApplication().assertIsDispatchThread();
|
||||
CommandLog.LOG.assertTrue(myCurrentCommand == null, "Command must not run: " + String.valueOf(myCurrentCommand));
|
||||
|
||||
myCurrentCommand = myInterruptedCommands.pop();
|
||||
if (myCurrentCommand != null) {
|
||||
fireCommandStarted();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCurrentCommandName(String name) {
|
||||
ApplicationManager.getApplication().assertIsDispatchThread();
|
||||
CommandDescriptor currentCommand = myCurrentCommand;
|
||||
CommandLog.LOG.assertTrue(currentCommand != null);
|
||||
currentCommand.myName = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCurrentCommandGroupId(Object groupId) {
|
||||
ApplicationManager.getApplication().assertIsDispatchThread();
|
||||
CommandDescriptor currentCommand = myCurrentCommand;
|
||||
CommandLog.LOG.assertTrue(currentCommand != null);
|
||||
currentCommand.myGroupId = groupId;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public Runnable getCurrentCommand() {
|
||||
CommandDescriptor currentCommand = myCurrentCommand;
|
||||
return currentCommand != null ? currentCommand.myCommand : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public String getCurrentCommandName() {
|
||||
CommandDescriptor currentCommand = myCurrentCommand;
|
||||
if (currentCommand != null) return currentCommand.myName;
|
||||
if (!myInterruptedCommands.isEmpty()) {
|
||||
final CommandDescriptor command = myInterruptedCommands.peek();
|
||||
return command != null ? command.myName : null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public Object getCurrentCommandGroupId() {
|
||||
CommandDescriptor currentCommand = myCurrentCommand;
|
||||
if (currentCommand != null) return currentCommand.myGroupId;
|
||||
if (!myInterruptedCommands.isEmpty()) {
|
||||
final CommandDescriptor command = myInterruptedCommands.peek();
|
||||
return command != null ? command.myGroupId : null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public Project getCurrentCommandProject() {
|
||||
CommandDescriptor currentCommand = myCurrentCommand;
|
||||
return currentCommand != null ? currentCommand.myProject : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addCommandListener(@NotNull CommandListener listener) {
|
||||
myListeners.add(listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addCommandListener(@NotNull final CommandListener listener, @NotNull Disposable parentDisposable) {
|
||||
addCommandListener(listener);
|
||||
Disposer.register(parentDisposable, new Disposable() {
|
||||
@Override
|
||||
public void dispose() {
|
||||
removeCommandListener(listener);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeCommandListener(@NotNull CommandListener listener) {
|
||||
myListeners.remove(listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void runUndoTransparentAction(@NotNull Runnable action) {
|
||||
if (myUndoTransparentCount++ == 0) fireUndoTransparentStarted();
|
||||
try {
|
||||
action.run();
|
||||
}
|
||||
finally {
|
||||
if (--myUndoTransparentCount == 0) fireUndoTransparentFinished();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isUndoTransparentActionInProgress() {
|
||||
return myUndoTransparentCount > 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void markCurrentCommandAsGlobal(Project project) {
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void addAffectedDocuments(Project project, @NotNull Document... docs) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addAffectedFiles(Project project, @NotNull VirtualFile... files) {
|
||||
}
|
||||
|
||||
private void fireCommandStarted() {
|
||||
ApplicationManager.getApplication().assertIsDispatchThread();
|
||||
CommandDescriptor currentCommand = myCurrentCommand;
|
||||
CommandEvent event = new CommandEvent(this,
|
||||
currentCommand.myCommand,
|
||||
currentCommand.myName,
|
||||
currentCommand.myGroupId,
|
||||
currentCommand.myProject,
|
||||
currentCommand.myUndoConfirmationPolicy,
|
||||
currentCommand.myDocument);
|
||||
for (CommandListener listener : myListeners) {
|
||||
try {
|
||||
listener.commandStarted(event);
|
||||
}
|
||||
catch (Throwable e) {
|
||||
CommandLog.LOG.error(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void fireUndoTransparentStarted() {
|
||||
for (CommandListener listener : myListeners) {
|
||||
try {
|
||||
listener.undoTransparentActionStarted();
|
||||
}
|
||||
catch (Throwable e) {
|
||||
CommandLog.LOG.error(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void fireUndoTransparentFinished() {
|
||||
for (CommandListener listener : myListeners) {
|
||||
try {
|
||||
listener.undoTransparentActionFinished();
|
||||
}
|
||||
catch (Throwable e) {
|
||||
CommandLog.LOG.error(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+4
-319
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2011 JetBrains s.r.o.
|
||||
* Copyright 2000-2014 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -15,149 +15,20 @@
|
||||
*/
|
||||
package com.intellij.openapi.command.impl;
|
||||
|
||||
import com.intellij.openapi.Disposable;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.command.*;
|
||||
import com.intellij.openapi.command.AbnormalCommandTerminationException;
|
||||
import com.intellij.openapi.command.undo.UndoManager;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.fileEditor.FileEditor;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.ui.Messages;
|
||||
import com.intellij.openapi.util.Disposer;
|
||||
import com.intellij.openapi.util.EmptyRunnable;
|
||||
import com.intellij.openapi.util.Ref;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import org.jetbrains.annotations.Nls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Stack;
|
||||
|
||||
public class CommandProcessorImpl extends CommandProcessorEx {
|
||||
private static class CommandDescriptor {
|
||||
public final Runnable myCommand;
|
||||
public final Project myProject;
|
||||
public String myName;
|
||||
public Object myGroupId;
|
||||
public final Document myDocument;
|
||||
public final UndoConfirmationPolicy myUndoConfirmationPolicy;
|
||||
|
||||
public CommandDescriptor(Runnable command,
|
||||
Project project,
|
||||
String name,
|
||||
Object groupId,
|
||||
UndoConfirmationPolicy undoConfirmationPolicy,
|
||||
Document document) {
|
||||
myCommand = command;
|
||||
myProject = project;
|
||||
myName = name;
|
||||
myGroupId = groupId;
|
||||
myUndoConfirmationPolicy = undoConfirmationPolicy;
|
||||
myDocument = document;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "'" + myName + "', group: '" + myGroupId + "'";
|
||||
}
|
||||
}
|
||||
|
||||
private CommandDescriptor myCurrentCommand = null;
|
||||
private final Stack<CommandDescriptor> myInterruptedCommands = new Stack<CommandDescriptor>();
|
||||
|
||||
// private HashMap myStatisticsMap = new HashMap(); // command name --> count
|
||||
|
||||
// private HashMap myStatisticsMap = new HashMap(); // command name --> count
|
||||
|
||||
private final List<CommandListener> myListeners = ContainerUtil.createLockFreeCopyOnWriteList();
|
||||
|
||||
private int myUndoTransparentCount = 0;
|
||||
|
||||
@Override
|
||||
public void executeCommand(@NotNull Runnable runnable, String name, Object groupId) {
|
||||
executeCommand(null, runnable, name, groupId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void executeCommand(Project project, @NotNull Runnable runnable, String name, Object groupId) {
|
||||
executeCommand(project, runnable, name, groupId, UndoConfirmationPolicy.DEFAULT);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void executeCommand(Project project, @NotNull Runnable runnable, String name, Object groupId, Document document) {
|
||||
executeCommand(project, runnable, name, groupId, UndoConfirmationPolicy.DEFAULT, document);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void executeCommand(Project project,
|
||||
@NotNull final Runnable command,
|
||||
final String name,
|
||||
final Object groupId,
|
||||
@NotNull UndoConfirmationPolicy confirmationPolicy) {
|
||||
executeCommand(project, command, name, groupId, confirmationPolicy, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void executeCommand(Project project,
|
||||
@NotNull final Runnable command,
|
||||
final String name,
|
||||
final Object groupId,
|
||||
@NotNull UndoConfirmationPolicy confirmationPolicy,
|
||||
Document document) {
|
||||
ApplicationManager.getApplication().assertIsDispatchThread();
|
||||
if (project != null && project.isDisposed()) return;
|
||||
|
||||
if (CommandLog.LOG.isDebugEnabled()) {
|
||||
CommandLog.LOG.debug("executeCommand: " + command + ", name = " + name + ", groupId = " + groupId);
|
||||
}
|
||||
|
||||
if (myCurrentCommand != null) {
|
||||
command.run();
|
||||
return;
|
||||
}
|
||||
Throwable throwable = null;
|
||||
try {
|
||||
myCurrentCommand = new CommandDescriptor(command, project, name, groupId, confirmationPolicy, document);
|
||||
fireCommandStarted();
|
||||
command.run();
|
||||
}
|
||||
catch (Throwable th) {
|
||||
throwable = th;
|
||||
}
|
||||
finally {
|
||||
finishCommand(project, myCurrentCommand, throwable);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public Object startCommand(final Project project,
|
||||
@Nls final String name,
|
||||
final Object groupId,
|
||||
final UndoConfirmationPolicy undoConfirmationPolicy) {
|
||||
ApplicationManager.getApplication().assertIsDispatchThread();
|
||||
if (project != null && project.isDisposed()) return null;
|
||||
|
||||
if (CommandLog.LOG.isDebugEnabled()) {
|
||||
CommandLog.LOG.debug("startCommand: name = " + name + ", groupId = " + groupId);
|
||||
}
|
||||
|
||||
if (myCurrentCommand != null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
Document document = groupId instanceof Ref && ((Ref)groupId).get() instanceof Document ? (Document)((Ref)groupId).get() : null;
|
||||
myCurrentCommand = new CommandDescriptor(EmptyRunnable.INSTANCE, project, name, groupId, undoConfirmationPolicy, document);
|
||||
fireCommandStarted();
|
||||
return myCurrentCommand;
|
||||
}
|
||||
|
||||
class CommandProcessorImpl extends CoreCommandProcessor {
|
||||
@Override
|
||||
public void finishCommand(final Project project, final Object command, final Throwable throwable) {
|
||||
ApplicationManager.getApplication().assertIsDispatchThread();
|
||||
CommandLog.LOG.assertTrue(myCurrentCommand != null, "no current command in progress");
|
||||
super.finishCommand(project, command, throwable);
|
||||
if (myCurrentCommand != command) return;
|
||||
final boolean failed;
|
||||
try {
|
||||
@@ -195,150 +66,6 @@ public class CommandProcessorImpl extends CommandProcessorEx {
|
||||
}
|
||||
}
|
||||
|
||||
private void fireCommandFinished() {
|
||||
ApplicationManager.getApplication().assertIsDispatchThread();
|
||||
CommandDescriptor currentCommand = myCurrentCommand;
|
||||
CommandEvent event = new CommandEvent(this, currentCommand.myCommand,
|
||||
currentCommand.myName,
|
||||
currentCommand.myGroupId,
|
||||
currentCommand.myProject,
|
||||
currentCommand.myUndoConfirmationPolicy,
|
||||
currentCommand.myDocument);
|
||||
try {
|
||||
for (CommandListener listener : myListeners) {
|
||||
try {
|
||||
listener.beforeCommandFinished(event);
|
||||
}
|
||||
catch (Throwable e) {
|
||||
CommandLog.LOG.error(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
finally {
|
||||
myCurrentCommand = null;
|
||||
for (CommandListener listener : myListeners) {
|
||||
try {
|
||||
listener.commandFinished(event);
|
||||
}
|
||||
catch (Throwable e) {
|
||||
CommandLog.LOG.error(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void enterModal() {
|
||||
ApplicationManager.getApplication().assertIsDispatchThread();
|
||||
CommandDescriptor currentCommand = myCurrentCommand;
|
||||
myInterruptedCommands.push(currentCommand);
|
||||
if (currentCommand != null) {
|
||||
fireCommandFinished();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void leaveModal() {
|
||||
ApplicationManager.getApplication().assertIsDispatchThread();
|
||||
CommandLog.LOG.assertTrue(myCurrentCommand == null, "Command must not run: " + String.valueOf(myCurrentCommand));
|
||||
|
||||
myCurrentCommand = myInterruptedCommands.pop();
|
||||
if (myCurrentCommand != null) {
|
||||
fireCommandStarted();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCurrentCommandName(String name) {
|
||||
ApplicationManager.getApplication().assertIsDispatchThread();
|
||||
CommandDescriptor currentCommand = myCurrentCommand;
|
||||
CommandLog.LOG.assertTrue(currentCommand != null);
|
||||
currentCommand.myName = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCurrentCommandGroupId(Object groupId) {
|
||||
ApplicationManager.getApplication().assertIsDispatchThread();
|
||||
CommandDescriptor currentCommand = myCurrentCommand;
|
||||
CommandLog.LOG.assertTrue(currentCommand != null);
|
||||
currentCommand.myGroupId = groupId;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public Runnable getCurrentCommand() {
|
||||
CommandDescriptor currentCommand = myCurrentCommand;
|
||||
return currentCommand != null ? currentCommand.myCommand : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public String getCurrentCommandName() {
|
||||
CommandDescriptor currentCommand = myCurrentCommand;
|
||||
if (currentCommand != null) return currentCommand.myName;
|
||||
if (!myInterruptedCommands.isEmpty()) {
|
||||
final CommandDescriptor command = myInterruptedCommands.peek();
|
||||
return command != null ? command.myName : null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public Object getCurrentCommandGroupId() {
|
||||
CommandDescriptor currentCommand = myCurrentCommand;
|
||||
if (currentCommand != null) return currentCommand.myGroupId;
|
||||
if (!myInterruptedCommands.isEmpty()) {
|
||||
final CommandDescriptor command = myInterruptedCommands.peek();
|
||||
return command != null ? command.myGroupId : null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public Project getCurrentCommandProject() {
|
||||
CommandDescriptor currentCommand = myCurrentCommand;
|
||||
return currentCommand != null ? currentCommand.myProject : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addCommandListener(@NotNull CommandListener listener) {
|
||||
myListeners.add(listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addCommandListener(@NotNull final CommandListener listener, @NotNull Disposable parentDisposable) {
|
||||
addCommandListener(listener);
|
||||
Disposer.register(parentDisposable, new Disposable() {
|
||||
@Override
|
||||
public void dispose() {
|
||||
removeCommandListener(listener);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeCommandListener(@NotNull CommandListener listener) {
|
||||
myListeners.remove(listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void runUndoTransparentAction(@NotNull Runnable action) {
|
||||
if (myUndoTransparentCount++ == 0) fireUndoTransparentStarted();
|
||||
try {
|
||||
action.run();
|
||||
}
|
||||
finally {
|
||||
if (--myUndoTransparentCount == 0) fireUndoTransparentFinished();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isUndoTransparentActionInProgress() {
|
||||
return myUndoTransparentCount > 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void markCurrentCommandAsGlobal(Project project) {
|
||||
getUndoManager(project).markCurrentCommandAsGlobal();
|
||||
@@ -357,46 +84,4 @@ public class CommandProcessorImpl extends CommandProcessorEx {
|
||||
public void addAffectedFiles(Project project, @NotNull VirtualFile... files) {
|
||||
getUndoManager(project).addAffectedFiles(files);
|
||||
}
|
||||
|
||||
private void fireCommandStarted() {
|
||||
ApplicationManager.getApplication().assertIsDispatchThread();
|
||||
CommandDescriptor currentCommand = myCurrentCommand;
|
||||
CommandEvent event = new CommandEvent(this,
|
||||
currentCommand.myCommand,
|
||||
currentCommand.myName,
|
||||
currentCommand.myGroupId,
|
||||
currentCommand.myProject,
|
||||
currentCommand.myUndoConfirmationPolicy,
|
||||
currentCommand.myDocument);
|
||||
for (CommandListener listener : myListeners) {
|
||||
try {
|
||||
listener.commandStarted(event);
|
||||
}
|
||||
catch (Throwable e) {
|
||||
CommandLog.LOG.error(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void fireUndoTransparentStarted() {
|
||||
for (CommandListener listener : myListeners) {
|
||||
try {
|
||||
listener.undoTransparentActionStarted();
|
||||
}
|
||||
catch (Throwable e) {
|
||||
CommandLog.LOG.error(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void fireUndoTransparentFinished() {
|
||||
for (CommandListener listener : myListeners) {
|
||||
try {
|
||||
listener.undoTransparentActionFinished();
|
||||
}
|
||||
catch (Throwable e) {
|
||||
CommandLog.LOG.error(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user