blob: 7c7efc1e299b8ac6d0e2e3ec5d3f1cbf9996853d [file] [log] [blame]
/*=============================================================================#
# Copyright (c) 2008, 2021 Stephan Wahlbrink and others.
#
# This program and the accompanying materials are made available under the
# terms of the Eclipse Public License 2.0 which is available at
# https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
# which is available at https://www.apache.org/licenses/LICENSE-2.0.
#
# SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
#
# Contributors:
# Stephan Wahlbrink <sw@wahlbrink.eu> - initial API and implementation
#=============================================================================*/
package org.eclipse.statet.internal.r.debug.ui.launcher;
import java.util.List;
import java.util.Map;
import org.eclipse.core.commands.AbstractHandler;
import org.eclipse.core.commands.ExecutionEvent;
import org.eclipse.core.commands.ExecutionException;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.jface.text.AbstractDocument;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.BadPartitioningException;
import org.eclipse.jface.text.ITextSelection;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.commands.IElementUpdater;
import org.eclipse.ui.handlers.HandlerUtil;
import org.eclipse.ui.menus.UIElement;
import org.eclipse.statet.jcommons.text.core.TextRegion;
import org.eclipse.statet.ecommons.ui.workbench.WorkbenchUIUtils;
import org.eclipse.statet.internal.r.debug.ui.RLaunchingMessages;
import org.eclipse.statet.ltk.model.core.element.SourceStructElement;
import org.eclipse.statet.ltk.model.core.element.SourceUnit;
import org.eclipse.statet.ltk.ui.util.LTKSelectionUtils;
import org.eclipse.statet.ltk.ui.util.LTKWorkbenchUIUtil;
import org.eclipse.statet.r.core.refactoring.RRefactoringAdapter;
import org.eclipse.statet.r.core.source.RHeuristicTokenScanner;
import org.eclipse.statet.r.launching.ICodeSubmitContentHandler;
import org.eclipse.statet.r.launching.RCodeLaunching;
/**
* Launch shortcut, which submits
* - the current line/selection directly to R (text editor)
* - code of selected model element (outline etc.)
* and does not change the focus by default.
*
* Low requirements: ITextSelection is sufficient
*/
public class SubmitUptoSelectionHandler extends AbstractHandler implements IElementUpdater {
private final boolean fGotoConsole;
private RRefactoringAdapter fModelUtil;
public SubmitUptoSelectionHandler() {
this(false);
}
protected SubmitUptoSelectionHandler(final boolean gotoConsole) {
fGotoConsole = gotoConsole;
}
@Override
public void updateElement(final UIElement element, final Map parameters) {
// element.setText(appendVariant(RLaunchingMessages.SubmitCode_UptoElementSelection_label));
}
protected String appendVariant(final String label) {
return label;
}
@Override
public Object execute(final ExecutionEvent event) throws ExecutionException {
final IWorkbenchPart activePart = HandlerUtil.getActivePart(event);
final ISelection selection = WorkbenchUIUtils.getCurrentSelection(event.getApplicationContext());
final String contentTypeId= LTKWorkbenchUIUtil.getContentTypeId(activePart);
try {
final IProgressMonitor progress = null;
// text selection
if (selection instanceof ITextSelection) {
final ITextSelection textSelection = (ITextSelection) selection;
List<String> lines = null;
final AbstractDocument document = LTKWorkbenchUIUtil.getDocument(activePart);
if (document != null) {
final ICodeSubmitContentHandler contentHandler = RCodeLaunching
.getCodeSubmitContentHandler(contentTypeId);
lines = contentHandler.getCodeLines(document, 0, textSelection.getOffset());
}
else {
lines = LaunchShortcutUtil.getSelectedCodeLines(event);
}
if (lines != null) {
RCodeLaunching.runRCodeDirect(lines, fGotoConsole, progress);
}
return null;
}
else
// selection of model elements
if (selection instanceof IStructuredSelection) {
final SourceStructElement[] elements = LTKSelectionUtils.getSelectedSourceStructElements(selection);
if (elements != null && elements.length == 1) {
final List<String> lines = getCodeLinesUpto(elements[0], contentTypeId, progress);
RCodeLaunching.runRCodeDirect(lines, fGotoConsole, progress);
return null;
}
}
}
catch (final Exception e) {
LaunchShortcutUtil.handleRLaunchException(e,
RLaunchingMessages.RSelectionLaunch_error_message, event);
return null;
}
LaunchShortcutUtil.handleUnsupportedExecution(event);
return null;
}
protected List<String> getCodeLinesUpto(final SourceStructElement element,
final String contentTypeId, final IProgressMonitor monitor)
throws BadLocationException, BadPartitioningException, CoreException {
final SourceUnit su = element.getSourceUnit();
if (su == null) {
return null;
}
if (fModelUtil == null) {
fModelUtil = new RSourceCodeAdapter();
}
su.connect(monitor);
try {
final AbstractDocument document = su.getDocument(monitor);
final RHeuristicTokenScanner scanner = fModelUtil.getScanner(su);
final TextRegion range = fModelUtil.expandElementRange(element, document, scanner);
if (range == null) {
return null;
}
final ICodeSubmitContentHandler contentHandler = RCodeLaunching
.getCodeSubmitContentHandler(contentTypeId);
return contentHandler.getCodeLines(document, 0, range.getStartOffset());
}
finally {
su.disconnect(monitor);
}
}
}