package jetbrains.mps.editor.contextActionsTool.pluginSolution.plugin;
/*Generated by MPS */
import org.apache.log4j.Logger;
import org.apache.log4j.LogManager;
import jetbrains.mps.project.IProject;
import jetbrains.mps.nodeEditor.assist.SelectionMenuProvider;
import jetbrains.mps.openapi.editor.selection.Selection;
import javax.swing.Timer;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import jetbrains.mps.openapi.editor.extensions.EditorExtensionRegistry;
import org.jetbrains.annotations.NotNull;
import com.intellij.openapi.application.ApplicationManager;
import jetbrains.mps.baseLanguage.closures.runtime.Wrappers;
import java.util.List;
import jetbrains.mps.internal.collections.runtime.ListSequence;
import jetbrains.mps.internal.collections.runtime.IWhereFilter;
import jetbrains.mps.internal.collections.runtime.ISelector;
import jetbrains.mps.ide.ThreadUtils;
import org.apache.log4j.Level;
import jetbrains.mps.nodeEditor.EditorComponent;
import jetbrains.mps.editor.runtime.commands.EditorCommand;
import jetbrains.mps.openapi.editor.extensions.EditorExtension;
import jetbrains.mps.openapi.editor.selection.SelectionListener;
public class ToolController implements ItemExecutor {
private static final Logger LOG = LogManager.getLogger(ToolController.class);
private final IProject myProject;
private final ToolComponent myToolComponent;
private final SelectionMenuProvider myMenuProvider;
private volatile Selection myLastSelection;
private volatile Selection myNextSelection;
private final Timer myUpdateTimer = new Timer(1000, new ActionListener() {
public void actionPerformed(ActionEvent p0) {
checkActiveEditorChanged();
}
});
private final ToolController.ProjectSelectionListener mySelectionListener = new ToolController.ProjectSelectionListener();
public ToolController(IProject project, ToolComponent toolComponent, SelectionMenuProvider menuProvider) {
myProject = project;
myToolComponent = toolComponent;
myMenuProvider = menuProvider;
myUpdateTimer.start();
myProject.getComponent(EditorExtensionRegistry.class).registerExtension(mySelectionListener);
myToolComponent.setItemExecutor(this);
}
public void dispose() {
myToolComponent.setItemExecutor(null);
myProject.getComponent(EditorExtensionRegistry.class).unregisterExtension(mySelectionListener);
myUpdateTimer.stop();
}
private void update(@NotNull final Selection selection) {
if (!(myToolComponent.isToolVisible())) {
return;
}
if (selection.isSame(myLastSelection)) {
return;
}
myNextSelection = selection;
ApplicationManager.getApplication().executeOnPooledThread(new Runnable() {
public void run() {
try {
Thread.sleep(500);
} catch (InterruptedException ex) {
return;
}
if (myNextSelection != selection) {
return;
}
myLastSelection = selection;
try {
final Wrappers._T<List<ToolComponent.IItem>> items = new Wrappers._T<List<ToolComponent.IItem>>(null);
myProject.getRepository().getModelAccess().runReadAction(new Runnable() {
public void run() {
items.value = queryItems(selection);
items.value = ListSequence.fromList(items.value).where(new IWhereFilter<ToolComponent.IItem>() {
public boolean accept(ToolComponent.IItem it) {
return it.isVisible();
}
}).sort(new ISelector<ToolComponent.IItem, String>() {
public String select(ToolComponent.IItem it) {
return it.getLabel();
}
}, true).toListSequence();
}
});
ThreadUtils.runInUIThreadNoWait(new Runnable() {
public void run() {
myToolComponent.loadItems(items.value);
}
});
} catch (Exception ex) {
if (LOG.isEnabledFor(Level.ERROR)) {
LOG.error("Context actions update failed", ex);
}
}
}
});
}
private List<ToolComponent.IItem> queryItems(@NotNull Selection selection) {
return ItemConverter.convertItems(myMenuProvider.getMenuItems(selection));
}
private void checkActiveEditorChanged() {
EditorComponent activeEditor = ContextActionsUtil.findActiveEditor(myToolComponent);
if (activeEditor == null) {
return;
}
if (check_ae45oa_a0c0s(myLastSelection) == null) {
return;
}
if (activeEditor == check_ae45oa_a0d0s(myLastSelection)) {
return;
}
if (activeEditor == check_ae45oa_a0e0s(myNextSelection)) {
return;
}
Selection selection = activeEditor.getSelectionManager().getSelection();
if (selection != null) {
update(selection);
}
}
@Override
public void execute(final ToolComponent.IItem item) {
EditorComponent editorComponent = ((EditorComponent) myLastSelection.getEditorComponent());
switch (item.getCommandPolicy()) {
case COMMAND_REQUIRED:
editorComponent.getEditorContext().getRepository().getModelAccess().executeCommand(new EditorCommand(editorComponent) {
protected void doExecute() {
item.execute();
}
});
break;
case COMMAND_UNSUPPORTED:
item.execute();
break;
default:
throw new IllegalArgumentException("Unknown command policy " + item.getCommandPolicy());
}
editorComponent.requestFocusInWindow();
}
private class ProjectSelectionListener implements EditorExtension, SelectionListener {
@Override
public boolean isApplicable(@NotNull jetbrains.mps.openapi.editor.EditorComponent component) {
return true;
}
@Override
public void install(@NotNull jetbrains.mps.openapi.editor.EditorComponent component) {
component.getSelectionManager().addSelectionListener(this);
}
@Override
public void uninstall(@NotNull jetbrains.mps.openapi.editor.EditorComponent component) {
component.getSelectionManager().removeSelectionListener(this);
}
@Override
public void selectionChanged(jetbrains.mps.openapi.editor.EditorComponent component, Selection oldSelection, Selection newSelection) {
if (newSelection == null) {
return;
}
try {
update(newSelection);
} catch (Exception ex) {
}
}
}
private static jetbrains.mps.openapi.editor.EditorComponent check_ae45oa_a0c0s(Selection checkedDotOperand) {
if (null != checkedDotOperand) {
return checkedDotOperand.getEditorComponent();
}
return null;
}
private static jetbrains.mps.openapi.editor.EditorComponent check_ae45oa_a0d0s(Selection checkedDotOperand) {
if (null != checkedDotOperand) {
return checkedDotOperand.getEditorComponent();
}
return null;
}
private static jetbrains.mps.openapi.editor.EditorComponent check_ae45oa_a0e0s(Selection checkedDotOperand) {
if (null != checkedDotOperand) {
return checkedDotOperand.getEditorComponent();
}
return null;
}
}