blob: d3e19216ab01ecaf1d6193ebfc111b890c49f869 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2015 Ericsson
*
* All rights reserved. This program and the accompanying materials are
* made available under the terms of the Eclipse Public License 2.0 which
* accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Patrick Tasse - Initial API and implementation
*******************************************************************************/
package org.eclipse.tracecompass.internal.tmf.ui.commands;
import java.util.List;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.swt.SWT;
import org.eclipse.swt.dnd.Clipboard;
import org.eclipse.swt.dnd.TextTransfer;
import org.eclipse.swt.dnd.Transfer;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.MessageBox;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.tracecompass.internal.tmf.ui.Activator;
import org.eclipse.tracecompass.internal.tmf.ui.Messages;
import org.eclipse.tracecompass.tmf.core.event.ITmfEvent;
import org.eclipse.tracecompass.tmf.core.filter.ITmfFilter;
import org.eclipse.tracecompass.tmf.core.request.ITmfEventRequest;
import org.eclipse.tracecompass.tmf.core.request.ITmfEventRequest.ExecutionType;
import org.eclipse.tracecompass.tmf.core.request.TmfEventRequest;
import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimeRange;
import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
import org.eclipse.tracecompass.tmf.ui.viewers.events.columns.TmfEventTableColumn;
import org.eclipse.ui.PlatformUI;
/**
* This operation copies the text of selected trace events to the clipboard.
*/
public class CopyToClipboardOperation implements IRunnableWithProgress {
private static final String LINE_SEPARATOR = System.getProperty("line.separator"); //$NON-NLS-1$
private final ITmfTrace fTrace;
private final ITmfFilter fFilter;
private final List<TmfEventTableColumn> fColumns;
private final long fStartRank;
private final long fEndRank;
/**
* Constructor.
*
* @param trace
* the trace to copy events from
* @param filter
* the filter to apply to trace events, or null
* @param columns
* the list of event table columns
* @param start
* the start rank of the selection
* @param end
* the end rank of the selection
*/
public CopyToClipboardOperation(ITmfTrace trace, ITmfFilter filter, List<TmfEventTableColumn> columns, long start, long end) {
fTrace = trace;
fFilter = filter;
fColumns = columns;
fStartRank = start;
fEndRank = end;
}
@Override
public void run(IProgressMonitor monitor) {
final StringBuilder sb = new StringBuilder();
monitor.beginTask(Messages.CopyToClipboardOperation_TaskName, (int) (fEndRank - fStartRank + 1));
boolean needTab = false;
for (TmfEventTableColumn column : fColumns) {
if (needTab) {
sb.append('\t');
}
sb.append(column.getHeaderName());
needTab = true;
}
sb.append(LINE_SEPARATOR);
copy(sb, monitor);
Display.getDefault().syncExec(() -> {
if (sb.length() == 0) {
return;
}
Clipboard clipboard = new Clipboard(Display.getDefault());
try {
clipboard.setContents(new Object[] { sb.toString() },
new Transfer[] { TextTransfer.getInstance() });
} catch (OutOfMemoryError e) {
sb.setLength(0);
sb.trimToSize();
showErrorDialog();
} finally {
clipboard.dispose();
}
});
monitor.done();
}
private IStatus copy(final StringBuilder sb, final IProgressMonitor monitor) {
ITmfEventRequest request = new TmfEventRequest(ITmfEvent.class, TmfTimeRange.ETERNITY, fStartRank, (int) (fEndRank - fStartRank + 1), ExecutionType.FOREGROUND) {
@Override
public void handleData(ITmfEvent event) {
super.handleData(event);
if (monitor.isCanceled()) {
cancel();
return;
}
monitor.worked(1);
if (fFilter == null || fFilter.matches(event)) {
try {
boolean needTab = false;
for (TmfEventTableColumn column : fColumns) {
if (needTab) {
sb.append('\t');
}
sb.append(column.getItemString(event));
needTab = true;
}
sb.append(LINE_SEPARATOR);
} catch (OutOfMemoryError e) {
sb.setLength(0);
sb.trimToSize();
showErrorDialog();
cancel();
}
}
}
};
fTrace.sendRequest(request);
try {
request.waitForCompletion();
} catch (InterruptedException e) {
Activator.getDefault().logError("Wait for completion interrupted for copy to clipboard ", e); //$NON-NLS-1$
Thread.currentThread().interrupt();
}
return Status.OK_STATUS;
}
private static void showErrorDialog() {
Display.getDefault().syncExec(() -> {
Shell shell = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell();
MessageBox confirmOperation = new MessageBox(shell, SWT.ICON_ERROR | SWT.OK);
confirmOperation.setText(Messages.CopyToClipboardOperation_OutOfMemoryErrorTitle);
confirmOperation.setMessage(Messages.CopyToClipboardOperation_OutOfMemoryErrorMessage);
confirmOperation.open();
});
}
}