blob: d93a508f97bd399f37152b06c55e8921e4a04a03 [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.*;
import com.intellij.openapi.command.CommandProcessor;
import com.intellij.openapi.command.UndoConfirmationPolicy;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.project.DumbAware;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.awt.event.KeyEvent;
import static com.intellij.openapi.actionSystem.CommonDataKeys.EDITOR;
import static com.intellij.openapi.actionSystem.CommonDataKeys.PROJECT;
public abstract class EditorAction extends AnAction implements DumbAware {
private EditorActionHandler myHandler;
private boolean myHandlersLoaded;
public final EditorActionHandler getHandler() {
ensureHandlersLoaded();
return myHandler;
}
protected EditorAction(EditorActionHandler defaultHandler) {
myHandler = defaultHandler;
setEnabledInModalContext(true);
}
public final EditorActionHandler setupHandler(@NotNull EditorActionHandler newHandler) {
ensureHandlersLoaded();
EditorActionHandler tmp = myHandler;
myHandler = newHandler;
myHandler.setWorksInInjected(isInInjectedContext());
return tmp;
}
private void ensureHandlersLoaded() {
if (!myHandlersLoaded) {
myHandlersLoaded = true;
final String id = ActionManager.getInstance().getId(this);
EditorActionHandlerBean[] extensions = Extensions.getExtensions(EditorActionHandlerBean.EP_NAME);
for (int i = extensions.length - 1; i >= 0; i--) {
final EditorActionHandlerBean handlerBean = extensions[i];
if (handlerBean.action.equals(id)) {
myHandler = handlerBean.getHandler(myHandler);
myHandler.setWorksInInjected(isInInjectedContext());
}
}
}
}
@Override
public void setInjectedContext(boolean worksInInjected) {
super.setInjectedContext(worksInInjected);
// we assume that this method is called in constructor at the point
// where the chain of handlers is not initialized yet
// and it's enough to pass the flag to the default handler only
myHandler.setWorksInInjected(isInInjectedContext());
}
@Override
public final void actionPerformed(AnActionEvent e) {
DataContext dataContext = e.getDataContext();
Editor editor = getEditor(dataContext);
actionPerformed(editor, dataContext);
}
@Nullable
protected Editor getEditor(@NotNull DataContext dataContext) {
return EDITOR.getData(dataContext);
}
public final void actionPerformed(final Editor editor, @NotNull final DataContext dataContext) {
if (editor == null) return;
final EditorActionHandler handler = getHandler();
Runnable command = new Runnable() {
@Override
public void run() {
handler.execute(editor, null, getProjectAwareDataContext(editor, dataContext));
}
};
if (!handler.executeInCommand(editor, dataContext)) {
command.run();
return;
}
String commandName = getTemplatePresentation().getText();
if (commandName == null) commandName = "";
CommandProcessor.getInstance().executeCommand(editor.getProject(),
command,
commandName,
handler.getCommandGroupId(editor),
UndoConfirmationPolicy.DEFAULT,
editor.getDocument());
}
public void update(Editor editor, Presentation presentation, DataContext dataContext) {
presentation.setEnabled(getHandler().isEnabled(editor, null, dataContext));
}
public void updateForKeyboardAccess(Editor editor, Presentation presentation, DataContext dataContext) {
update(editor, presentation, dataContext);
}
@Override
public void update(AnActionEvent e) {
Presentation presentation = e.getPresentation();
DataContext dataContext = e.getDataContext();
Editor editor = getEditor(dataContext);
if (editor == null) {
presentation.setEnabled(false);
}
else {
if (e.getInputEvent() instanceof KeyEvent) {
updateForKeyboardAccess(editor, presentation, dataContext);
}
else {
update(editor, presentation, dataContext);
}
}
}
private static DataContext getProjectAwareDataContext(final Editor editor, @NotNull final DataContext original) {
if (PROJECT.getData(original) == editor.getProject()) {
return new DialogAwareDataContext(original);
}
return new DataContext() {
@Override
public Object getData(String dataId) {
if (PROJECT.is(dataId)) {
return editor.getProject();
}
return original.getData(dataId);
}
};
}
}