tmf: Dispose clipboard after Copy to Clipboard operation
[deliverable/tracecompass.git] / tmf / org.eclipse.tracecompass.tmf.ui / src / org / eclipse / tracecompass / internal / tmf / ui / commands / CopyToClipboardOperation.java
1 /*******************************************************************************
2 * Copyright (c) 2015 Ericsson
3 *
4 * All rights reserved. This program and the accompanying materials are
5 * made available under the terms of the Eclipse Public License v1.0 which
6 * accompanies this distribution, and is available at
7 * http://www.eclipse.org/legal/epl-v10.html
8 *
9 * Contributors:
10 * Patrick Tasse - Initial API and implementation
11 *******************************************************************************/
12
13 package org.eclipse.tracecompass.internal.tmf.ui.commands;
14
15 import java.util.List;
16
17 import org.eclipse.core.runtime.IProgressMonitor;
18 import org.eclipse.core.runtime.IStatus;
19 import org.eclipse.core.runtime.Status;
20 import org.eclipse.jface.operation.IRunnableWithProgress;
21 import org.eclipse.swt.SWT;
22 import org.eclipse.swt.dnd.Clipboard;
23 import org.eclipse.swt.dnd.TextTransfer;
24 import org.eclipse.swt.dnd.Transfer;
25 import org.eclipse.swt.widgets.Display;
26 import org.eclipse.swt.widgets.MessageBox;
27 import org.eclipse.swt.widgets.Shell;
28 import org.eclipse.tracecompass.internal.tmf.ui.Activator;
29 import org.eclipse.tracecompass.internal.tmf.ui.Messages;
30 import org.eclipse.tracecompass.tmf.core.event.ITmfEvent;
31 import org.eclipse.tracecompass.tmf.core.filter.ITmfFilter;
32 import org.eclipse.tracecompass.tmf.core.request.ITmfEventRequest;
33 import org.eclipse.tracecompass.tmf.core.request.ITmfEventRequest.ExecutionType;
34 import org.eclipse.tracecompass.tmf.core.request.TmfEventRequest;
35 import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimeRange;
36 import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
37 import org.eclipse.tracecompass.tmf.ui.viewers.events.columns.TmfEventTableColumn;
38 import org.eclipse.ui.PlatformUI;
39
40 /**
41 * This operation copies the text of selected trace events to the clipboard.
42 */
43 public class CopyToClipboardOperation implements IRunnableWithProgress {
44
45 private static final String LINE_SEPARATOR = System.getProperty("line.separator"); //$NON-NLS-1$
46 private final ITmfTrace fTrace;
47 private final ITmfFilter fFilter;
48 private final List<TmfEventTableColumn> fColumns;
49 private final long fStartRank;
50 private final long fEndRank;
51
52 /**
53 * Constructor.
54 *
55 * @param trace
56 * the trace to copy events from
57 * @param filter
58 * the filter to apply to trace events, or null
59 * @param columns
60 * the list of event table columns
61 * @param start
62 * the start rank of the selection
63 * @param end
64 * the end rank of the selection
65 */
66 public CopyToClipboardOperation(ITmfTrace trace, ITmfFilter filter, List<TmfEventTableColumn> columns, long start, long end) {
67 fTrace = trace;
68 fFilter = filter;
69 fColumns = columns;
70 fStartRank = start;
71 fEndRank = end;
72 }
73
74 @Override
75 public void run(IProgressMonitor monitor) {
76 final StringBuilder sb = new StringBuilder();
77 monitor.beginTask(Messages.CopyToClipboardOperation_TaskName, (int) (fEndRank - fStartRank + 1));
78
79 boolean needTab = false;
80 for (TmfEventTableColumn column : fColumns) {
81 if (needTab) {
82 sb.append('\t');
83 }
84 sb.append(column.getHeaderName());
85 needTab = true;
86 }
87 sb.append(LINE_SEPARATOR);
88
89 copy(sb, monitor);
90
91 Display.getDefault().syncExec(new Runnable() {
92 @Override
93 public void run() {
94 if (sb.length() == 0) {
95 return;
96 }
97 Clipboard clipboard = new Clipboard(Display.getDefault());
98 try {
99 clipboard.setContents(new Object[] { sb.toString() },
100 new Transfer[] { TextTransfer.getInstance() });
101 } catch (OutOfMemoryError e) {
102 sb.setLength(0);
103 sb.trimToSize();
104 showErrorDialog();
105 } finally {
106 clipboard.dispose();
107 }
108 }
109 });
110
111 monitor.done();
112 }
113
114 private IStatus copy(final StringBuilder sb, final IProgressMonitor monitor) {
115 ITmfEventRequest request = new TmfEventRequest(ITmfEvent.class, TmfTimeRange.ETERNITY, fStartRank, (int) (fEndRank - fStartRank + 1), ExecutionType.FOREGROUND) {
116 @Override
117 public void handleData(ITmfEvent event) {
118 super.handleData(event);
119 if (monitor.isCanceled()) {
120 cancel();
121 return;
122 }
123 monitor.worked(1);
124 if (fFilter == null || fFilter.matches(event)) {
125 try {
126 boolean needTab = false;
127 for (TmfEventTableColumn column : fColumns) {
128 if (needTab) {
129 sb.append('\t');
130 }
131 sb.append(column.getItemString(event));
132 needTab = true;
133 }
134 sb.append(LINE_SEPARATOR);
135 } catch (OutOfMemoryError e) {
136 sb.setLength(0);
137 sb.trimToSize();
138 showErrorDialog();
139 cancel();
140 }
141 }
142 }
143 };
144 fTrace.sendRequest(request);
145 try {
146 request.waitForCompletion();
147 } catch (InterruptedException e) {
148 Activator.getDefault().logError("Wait for completion interrupted for copy to clipboard ", e); //$NON-NLS-1$
149 }
150 return Status.OK_STATUS;
151 }
152
153 private static void showErrorDialog() {
154 Display.getDefault().syncExec(new Runnable() {
155 @Override
156 public void run() {
157 Shell shell = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell();
158 MessageBox confirmOperation = new MessageBox(shell, SWT.ICON_ERROR | SWT.OK);
159 confirmOperation.setText(Messages.CopyToClipboardOperation_OutOfMemoryErrorTitle);
160 confirmOperation.setMessage(Messages.CopyToClipboardOperation_OutOfMemoryErrorMessage);
161 confirmOperation.open();
162 }
163 });
164 }
165 }
This page took 0.035561 seconds and 5 git commands to generate.