blob: 98d83656b58081d5fbde126b4c7bdfa50a721235 [file] [log] [blame]
/*
* 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.editor.actionSystem;
import com.intellij.openapi.actionSystem.CommonDataKeys;
import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.command.CommandProcessor;
import com.intellij.openapi.command.UndoConfirmationPolicy;
import com.intellij.openapi.editor.*;
import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.fileEditor.FileDocumentManager;
import com.intellij.openapi.project.Project;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* Provides services for registering actions which are activated by typing in the editor.
*
* @see EditorActionManager#getTypedAction()
*/
public class TypedAction {
private TypedActionHandler myHandler;
private boolean myHandlersLoaded;
public TypedAction() {
myHandler = new Handler();
}
private void ensureHandlersLoaded() {
if (!myHandlersLoaded) {
myHandlersLoaded = true;
for(EditorTypedHandlerBean handlerBean: Extensions.getExtensions(EditorTypedHandlerBean.EP_NAME)) {
myHandler = handlerBean.getHandler(myHandler);
}
}
}
private static class Handler implements TypedActionHandler {
@Override
public void execute(@NotNull final Editor editor, char charTyped, @NotNull DataContext dataContext) {
if (editor.isViewer()) return;
Document doc = editor.getDocument();
Project project = CommonDataKeys.PROJECT.getData(dataContext);
if (!FileDocumentManager.getInstance().requestWriting(doc, project)) {
return;
}
doc.startGuardedBlockChecking();
try {
final String str = String.valueOf(charTyped);
CommandProcessor.getInstance().setCurrentCommandName(EditorBundle.message("typing.in.editor.command.name"));
EditorModificationUtil.typeInStringAtCaretHonorMultipleCarets(editor, str, true);
}
catch (ReadOnlyFragmentModificationException e) {
EditorActionManager.getInstance().getReadonlyFragmentModificationHandler(doc).handle(e);
}
finally {
doc.stopGuardedBlockChecking();
}
}
}
/**
* Gets the current typing handler.
*
* @return the current typing handler.
*/
public TypedActionHandler getHandler() {
ensureHandlersLoaded();
return myHandler;
}
/**
* Replaces the typing handler with the specified handler. The handler should pass
* unprocessed typing to the previously registered handler.
*
* @param handler the handler to set.
* @return the previously registered handler.
*/
public TypedActionHandler setupHandler(TypedActionHandler handler) {
ensureHandlersLoaded();
TypedActionHandler tmp = myHandler;
myHandler = handler;
return tmp;
}
public final void actionPerformed(@Nullable final Editor editor, final char charTyped, final DataContext dataContext) {
if (editor == null) return;
Runnable command = new TypingCommand(editor, charTyped, dataContext);
CommandProcessor.getInstance().executeCommand(CommonDataKeys.PROJECT.getData(dataContext), command, "", editor.getDocument(), UndoConfirmationPolicy.DEFAULT, editor.getDocument());
}
private class TypingCommand implements Runnable {
private final Editor myEditor;
private final char myCharTyped;
private final DataContext myDataContext;
public TypingCommand(Editor editor, char charTyped, DataContext dataContext) {
myEditor = editor;
myCharTyped = charTyped;
myDataContext = dataContext;
}
@Override
public void run() {
ApplicationManager.getApplication().runWriteAction(new DocumentRunnable(myEditor.getDocument(), myEditor.getProject()) {
@Override
public void run() {
Document doc = myEditor.getDocument();
doc.startGuardedBlockChecking();
try {
getHandler().execute(myEditor, myCharTyped, myDataContext);
}
catch (ReadOnlyFragmentModificationException e) {
EditorActionManager.getInstance().getReadonlyFragmentModificationHandler(doc).handle(e);
}
finally {
doc.stopGuardedBlockChecking();
}
}
});
}
}
}