blob: f4e15639766f198fd962a7946814ab9c82505a1c [file] [log] [blame]
/*=============================================================================#
# Copyright (c) 2008, 2019 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.redocs.r.ui.debug;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.debug.ui.ILaunchShortcut;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.jface.text.AbstractDocument;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.ITextSelection;
import org.eclipse.jface.text.source.SourceViewer;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.statushandlers.StatusManager;
import org.eclipse.statet.jcommons.text.core.TextRegion;
import org.eclipse.statet.ecommons.text.TextUtil;
import org.eclipse.statet.ecommons.text.core.sections.IDocContentSections;
import org.eclipse.statet.ecommons.ui.util.UIAccess;
import org.eclipse.statet.internal.redocs.r.Messages;
import org.eclipse.statet.ltk.ui.sourceediting.ISourceEditor;
import org.eclipse.statet.r.launching.RCodeLaunching;
import org.eclipse.statet.r.ui.RUI;
import org.eclipse.statet.redocs.r.RedocsRweave;
import org.eclipse.statet.redocs.r.core.source.DocContentSectionsRweaveExtension;
/**
* Launch shortcut, which submits the chunks (touched by selection).
*
* Supports only text editors.
*/
public class SubmitRChunkDirectLaunchShortcut implements ILaunchShortcut {
public static class AndGotoConsole extends SubmitRChunkDirectLaunchShortcut {
public AndGotoConsole() {
super(true);
}
}
private static class Data {
private AbstractDocument document;
private DocContentSectionsRweaveExtension docContentSections;
private ITextSelection selection;
public boolean isComplete() {
return (this.document != null && this.docContentSections != null && this.selection != null);
}
}
private final boolean gotoConsole;
public SubmitRChunkDirectLaunchShortcut() {
this(false);
}
protected SubmitRChunkDirectLaunchShortcut(final boolean gotoConsole) {
this.gotoConsole= gotoConsole;
}
@Override
public void launch(final ISelection selection, final String mode) {
// not supported
}
@Override
public void launch(final IEditorPart editor, final String mode) {
assert mode.equals("run"); //$NON-NLS-1$
final Data data= new Data();
try {
final ISourceEditor sourceEditor= editor.getAdapter(ISourceEditor.class);
if (sourceEditor != null) {
UIAccess.getDisplay().syncExec(new Runnable() {
@Override
public void run() {
final SourceViewer viewer= sourceEditor.getViewer();
if (UIAccess.isOkToUse(viewer)) {
data.document= (AbstractDocument) viewer.getDocument();
final IDocContentSections docContentInfo= sourceEditor.getDocumentContentInfo();
if (docContentInfo instanceof DocContentSectionsRweaveExtension) {
data.docContentSections= (DocContentSectionsRweaveExtension) docContentInfo;
}
data.selection= (ITextSelection) viewer.getSelection();
}
}
});
}
if (data.isComplete()) {
PlatformUI.getWorkbench().getProgressService().busyCursorWhile(new IRunnableWithProgress() {
@Override
public void run(final IProgressMonitor monitor) throws InvocationTargetException {
try {
doLaunch(data, monitor);
}
catch (final CoreException e) {
throw new InvocationTargetException(e);
}
}
});
}
}
catch (final InvocationTargetException e) {
StatusManager.getManager().handle(new Status(IStatus.ERROR, RUI.BUNDLE_ID, 0,
Messages.RChunkLaunch_error_message, e.getTargetException() ));
}
catch (final InterruptedException e) {
}
}
private void doLaunch(final Data data, final IProgressMonitor monitor) throws CoreException {
try {
final List<? extends TextRegion> rCodeRegions= data.docContentSections.getRChunkCodeRegions(
data.document, data.selection.getOffset(), data.selection.getLength() );
final ArrayList<String> lines= new ArrayList<>();
for (final TextRegion region : rCodeRegions) {
TextUtil.addLines(data.document, region.getStartOffset(), region.getLength(), lines);
}
if (monitor.isCanceled()) {
return;
}
if (lines.size() == 0 || monitor.isCanceled()) {
return;
}
RCodeLaunching.runRCodeDirect(lines, this.gotoConsole, monitor);
}
catch (final BadLocationException e) {
throw new CoreException(new Status(IStatus.ERROR, RedocsRweave.BUNDLE_ID, -1,
"An error occurred when picking code lines.", e ));
}
}
}