Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorUwe Stieber2015-06-25 07:46:08 +0000
committerUwe Stieber2015-06-25 07:46:08 +0000
commitf1f8ca416937b26507c799791727cb07cf132f3a (patch)
treeae768a838e00ebbc314d156d76f5da95d2240281
parent4c5d3ab5fa55ddec1c5584ef56171f9e849b9e80 (diff)
downloadorg.eclipse.tcf-f1f8ca416937b26507c799791727cb07cf132f3a.tar.gz
org.eclipse.tcf-f1f8ca416937b26507c799791727cb07cf132f3a.tar.xz
org.eclipse.tcf-f1f8ca416937b26507c799791727cb07cf132f3a.zip
Target Explorer: Fix file system explorer clipboard handling
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/operations/FsClipboard.java202
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/operations/FsClipboardTransfer.java110
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/nls/Messages.java1
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/nls/Messages.properties2
4 files changed, 258 insertions, 57 deletions
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/operations/FsClipboard.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/operations/FsClipboard.java
index d2b186a04..e7145bdcb 100644
--- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/operations/FsClipboard.java
+++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/operations/FsClipboard.java
@@ -11,66 +11,145 @@ package org.eclipse.tcf.te.tcf.filesystem.ui.internal.operations;
import java.beans.PropertyChangeEvent;
import java.util.List;
+import java.util.concurrent.atomic.AtomicReference;
+import org.eclipse.core.runtime.Assert;
import org.eclipse.swt.SWTException;
import org.eclipse.swt.dnd.Clipboard;
+import org.eclipse.swt.dnd.Transfer;
import org.eclipse.swt.widgets.Display;
import org.eclipse.tcf.te.core.utils.PropertyChangeProvider;
import org.eclipse.tcf.te.tcf.filesystem.core.interfaces.runtime.IFSTreeNode;
+import org.eclipse.tcf.te.ui.swt.DisplayUtil;
import org.eclipse.ui.PlatformUI;
/**
* The clip board to which copy or cut files/folders.
*/
public class FsClipboard extends PropertyChangeProvider {
- // The constants to define the current operation type of the clip board.
- private static final int NONE = -1;
- private static final int CUT = 0;
- private static final int COPY = 1;
- // The operation type, CUT, COPY or NONE.
- private int operation;
- // The currently selected files/folders.
- private List<IFSTreeNode> files;
- private Clipboard clipboard;
+ /* default */ static class FsClipboardContent {
+ // The constants to define the current operation type of the clip board.
+ public static final int CUT = 0;
+ public static final int COPY = 1;
+
+ // The operation type, CUT, COPY or NONE.
+ public final int operation;
+ // The currently selected files/folders.
+ public final List<IFSTreeNode> files;
+
+ /**
+ * Constructor
+ */
+ public FsClipboardContent(int operation, List<IFSTreeNode> files) {
+ Assert.isTrue(operation == CUT || operation == COPY);
+ this.operation = operation;
+ Assert.isNotNull(files);
+ this.files = files;
+ }
+ }
+
+ /* default */ final Clipboard clipboard;
/**
* Create a clip board instance.
*/
public FsClipboard() {
clipboard = new Clipboard(PlatformUI.getWorkbench().getDisplay());
- operation = NONE;
}
public boolean isCutOp() {
- return operation == CUT;
+ final AtomicReference<Object> object = new AtomicReference<Object>();
+
+ Runnable runnable = new Runnable() {
+ @Override
+ public void run() {
+ object.set(clipboard.getContents(FsClipboardTransfer.getInstance()));
+ }
+ };
+
+ exec(runnable);
+
+ FsClipboardContent content = (FsClipboardContent) object.get();
+
+ return content != null && content.operation == FsClipboardContent.CUT;
}
public boolean isCopyOp() {
- return operation == COPY;
+ final AtomicReference<Object> object = new AtomicReference<Object>();
+
+ Runnable runnable = new Runnable() {
+ @Override
+ public void run() {
+ object.set(clipboard.getContents(FsClipboardTransfer.getInstance()));
+ }
+ };
+
+ exec(runnable);
+
+ FsClipboardContent content = (FsClipboardContent) object.get();
+
+ return content != null && content.operation == FsClipboardContent.COPY;
}
public boolean isEmpty() {
- return operation == NONE && (files == null || files.isEmpty());
+ final AtomicReference<Object> object = new AtomicReference<Object>();
+
+ Runnable runnable = new Runnable() {
+ @Override
+ public void run() {
+ object.set(clipboard.getContents(FsClipboardTransfer.getInstance()));
+ }
+ };
+
+ exec(runnable);
+
+ FsClipboardContent content = (FsClipboardContent) object.get();
+
+ return content == null || content.files.isEmpty();
}
/**
* Get the currently selected files/folders to operated.
*/
public List<IFSTreeNode> getFiles() {
- return files;
+ final AtomicReference<Object> object = new AtomicReference<Object>();
+
+ Runnable runnable = new Runnable() {
+ @Override
+ public void run() {
+ object.set(clipboard.getContents(FsClipboardTransfer.getInstance()));
+ }
+ };
+
+ exec(runnable);
+
+ FsClipboardContent content = (FsClipboardContent) object.get();
+
+ return content.files;
}
/**
* Cut the specified files/folders to the clip board.
*/
public void cutFiles(List<IFSTreeNode> files) {
- operation = CUT;
- this.files = files;
- PropertyChangeEvent event = new PropertyChangeEvent(this, "cut", null, null); //$NON-NLS-1$
- firePropertyChange(event);
+ Assert.isNotNull(files);
+
+ final FsClipboardContent content = new FsClipboardContent(FsClipboardContent.CUT, files);
+ final FsClipboardTransfer transfer = FsClipboardTransfer.getInstance();
+ transfer.setContent(content);
+
+ Runnable runnable = new Runnable() {
+ @Override
+ public void run() {
+ clipboard.setContents(new Object[] { content }, new Transfer[] { transfer });
+
+ PropertyChangeEvent event = new PropertyChangeEvent(this, "cut", null, null); //$NON-NLS-1$
+ firePropertyChange(event);
+ }
+ };
- clearSystemClipboard();
+ exec(runnable);
}
/**
@@ -79,70 +158,79 @@ public class FsClipboard extends PropertyChangeProvider {
* @param files The file/folder nodes.
*/
public void copyFiles(List<IFSTreeNode> files) {
- operation = COPY;
- this.files = files;
- PropertyChangeEvent event = new PropertyChangeEvent(this, "copy", null, null); //$NON-NLS-1$
- firePropertyChange(event);
+ Assert.isNotNull(files);
+
+ final FsClipboardContent content = new FsClipboardContent(FsClipboardContent.COPY, files);
+ final FsClipboardTransfer transfer = FsClipboardTransfer.getInstance();
+ transfer.setContent(content);
+
+ Runnable runnable = new Runnable() {
+ @Override
+ public void run() {
+ clipboard.setContents(new Object[] { content }, new Transfer[] { transfer });
+
+ PropertyChangeEvent event = new PropertyChangeEvent(this, "copy", null, null); //$NON-NLS-1$
+ firePropertyChange(event);
+ }
+ };
- clearSystemClipboard();
+ exec(runnable);
}
/**
* Clear the clip board.
*/
public void clear() {
- operation = NONE;
- this.files = null;
- PropertyChangeEvent event = new PropertyChangeEvent(this, "clear", null, null); //$NON-NLS-1$
- firePropertyChange(event);
+ Runnable runnable = new Runnable() {
+ @Override
+ public void run() {
+ clipboard.clearContents();
- clearSystemClipboard();
+ PropertyChangeEvent event = new PropertyChangeEvent(this, "clear", null, null); //$NON-NLS-1$
+ firePropertyChange(event);
+ }
+ };
+
+ exec(runnable);
}
/**
- * Make sure the system clip board is cleared in a UI thread.
+ * Executes the given runnable in the UI thread synchronously.
+ *
+ * @param runnable The runnable. Must not be <code>null</code>.
*/
- void clearSystemClipboard() {
+ private void exec(Runnable runnable) {
+ Assert.isNotNull(runnable);
+
if (Display.getCurrent() != null) {
- clipboard.clearContents();
- }
- else {
- PlatformUI.getWorkbench().getDisplay().syncExec(new Runnable(){
- @Override
- public void run() {
- clearSystemClipboard();
- }});
+ runnable.run();
+ } else {
+ DisplayUtil.safeSyncExec(runnable);
}
}
/**
- * Dispose the clipboard.
+ * Dispose the clip board.
*/
public void dispose() {
- if(Display.getCurrent() != null) {
- if (!clipboard.isDisposed()) {
- try {
- clipboard.dispose();
- }
- catch (SWTException e) {
+ Runnable runnable = new Runnable() {
+ @Override
+ public void run() {
+ if (!clipboard.isDisposed()) {
+ try { clipboard.dispose(); } catch (SWTException e) {}
}
}
- }
- else {
- PlatformUI.getWorkbench().getDisplay().syncExec(new Runnable(){
- @Override
- public void run() {
- dispose();
- }});
- }
+ };
+
+ exec(runnable);
}
/**
- * Get the system clipboard.
+ * Get the system clip board.
*
- * @return The system clipboard.
+ * @return The system clip board.
*/
- public Clipboard getSystemClipboard() {
+ public final Clipboard getSystemClipboard() {
return clipboard;
}
}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/operations/FsClipboardTransfer.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/operations/FsClipboardTransfer.java
new file mode 100644
index 000000000..799c06a43
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/operations/FsClipboardTransfer.java
@@ -0,0 +1,110 @@
+/*******************************************************************************
+ * Copyright (c) 2015 Wind River Systems, Inc. and others. All rights reserved.
+ * This program and the accompanying materials are made available under the terms
+ * of the Eclipse Public License v1.0 which accompanies this distribution, and is
+ * available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tcf.te.tcf.filesystem.ui.internal.operations;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.swt.dnd.ByteArrayTransfer;
+import org.eclipse.swt.dnd.TransferData;
+import org.eclipse.tcf.te.tcf.filesystem.ui.activator.UIPlugin;
+import org.eclipse.tcf.te.tcf.filesystem.ui.nls.Messages;
+
+/**
+ * Internal clip board transfer implementation used by the file system clip board.
+ */
+/* default */ class FsClipboardTransfer extends ByteArrayTransfer {
+
+ private static final String TYPE_NAME= "fs-clipboard-transfer-format" + Long.toString(System.currentTimeMillis()); //$NON-NLS-1$;
+ private static final int TYPEID= registerType(TYPE_NAME);
+
+ private FsClipboard.FsClipboardContent content;
+
+ private static class LazyInstance {
+ public static FsClipboardTransfer instance = new FsClipboardTransfer();
+ }
+
+ /**
+ * Constructor
+ */
+ /* default */ FsClipboardTransfer() {
+ }
+
+ /**
+ * Returns the singleton.
+ */
+ public static FsClipboardTransfer getInstance() {
+ return LazyInstance.instance;
+ }
+
+ /**
+ * Returns the transfer data.
+ *
+ * @return The transfer data or <code>null</code>.
+ */
+ public FsClipboard.FsClipboardContent getContent() {
+ return content;
+ }
+
+ /**
+ * Sets the transfer data.
+ *
+ * @param content The transfer data or <code>null</code>.
+ */
+ public void setContent(FsClipboard.FsClipboardContent content) {
+ this.content = content;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.swt.dnd.Transfer#getTypeIds()
+ */
+ @Override
+ protected int[] getTypeIds() {
+ return new int[] {TYPEID};
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.swt.dnd.Transfer#getTypeNames()
+ */
+ @Override
+ protected String[] getTypeNames() {
+ return new String[] {TYPE_NAME};
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.swt.dnd.Transfer#javaToNative(java.lang.Object, org.eclipse.swt.dnd.TransferData)
+ */
+ @Override
+ protected void javaToNative(Object object, TransferData transferData) {
+ byte[] check= TYPE_NAME.getBytes();
+ super.javaToNative(check, transferData);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.swt.dnd.Transfer#nativeToJava(org.eclipse.swt.dnd.TransferData)
+ */
+ @Override
+ protected Object nativeToJava(TransferData transferData) {
+ Object result= super.nativeToJava(transferData);
+ if (isInvalidNativeType(result)) {
+ UIPlugin.getDefault().getLog().log(new Status(IStatus.ERROR, UIPlugin.getUniqueIdentifier(), Messages.FsClipboardTransfer_errorMessage));
+ }
+ return content;
+ }
+ /**
+ * Tests whether native drop data matches this transfer type.
+ *
+ * @param result result of converting the native drop data to Java
+ * @return true if the native drop data does not match this transfer type.
+ * false otherwise.
+ */
+ private boolean isInvalidNativeType(Object result) {
+ return !(result instanceof byte[]) || !TYPE_NAME.equals(new String((byte[])result));
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/nls/Messages.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/nls/Messages.java
index 9250f3c5c..464b24eb7 100644
--- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/nls/Messages.java
+++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/nls/Messages.java
@@ -254,4 +254,5 @@ public class Messages extends NLS {
public static String ContentProvider_notConnected;
public static String UiExecutor_errorRunningOperation;
+ public static String FsClipboardTransfer_errorMessage;
}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/nls/Messages.properties b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/nls/Messages.properties
index 07046839b..b3feec316 100644
--- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/nls/Messages.properties
+++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/nls/Messages.properties
@@ -175,3 +175,5 @@ TreeViewerSearchDialog_BtnPreciseText=Precise matching
ContentProvider_notConnected=Please connect to see the file system on the target.
UiExecutor_errorRunningOperation=Operation completed with errors
+
+FsClipboardTransfer_errorMessage=Received wrong transfer data

Back to the top