/*=============================================================================# # Copyright (c) 2009-2016 Stephan Wahlbrink (WalWare.de) 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: # Stephan Wahlbrink - initial API and implementation #=============================================================================*/ package de.walware.statet.nico.internal.ui; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.swt.dnd.ByteArrayTransfer; import org.eclipse.swt.dnd.DragSourceListener; import org.eclipse.swt.dnd.TransferData; import org.eclipse.ui.statushandlers.StatusManager; import de.walware.ecommons.ICommonStatusConstants; import de.walware.ecommons.ts.IToolRunnable; import de.walware.statet.nico.core.runtime.ToolProcess; import de.walware.statet.nico.ui.NicoUI; /** * Transfer type for {@link IToolRunnable} */ public final class LocalTaskTransfer extends ByteArrayTransfer { // First attempt to create a UUID for the type name to make sure that // different Eclipse applications use different "types" of // <code>LocalTaskTransfer</code> private static final String TYPE_NAME = "de.walware.statet.nico-task-transfer-format" + (new Long(System.currentTimeMillis())).toString(); //$NON-NLS-1$; private static final int TYPEID = registerType(TYPE_NAME); private static final LocalTaskTransfer INSTANCE = new LocalTaskTransfer(); /** * The transfered data */ public static class Data { public final ToolProcess process; public IToolRunnable[] runnables; private Data(final ToolProcess process) { this.process = process; } } /** * Returns the singleton. * * @return the singleton */ public static LocalTaskTransfer getTransfer() { return INSTANCE; } private ToolProcess fProcess; private Data fData; /** * Only the singleton instance of this class may be used. */ protected LocalTaskTransfer() { // do nothing } /** * 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(final Object result) { return !(result instanceof byte[]) || !TYPE_NAME.equals(new String((byte[]) result)); } /** * Returns the type id used to identify this transfer. * * @return the type id used to identify this transfer. */ @Override protected int[] getTypeIds() { return new int[] { TYPEID }; } /** * Returns the type name used to identify this transfer. * * @return the type name used to identify this transfer. */ @Override protected String[] getTypeNames() { return new String[] { TYPE_NAME }; } /** * Overrides org.eclipse.swt.dnd.ByteArrayTransfer#javaToNative(Object, TransferData). * Only encode the transfer type name since the selection is read and * written in the same process. * * @see org.eclipse.swt.dnd.ByteArrayTransfer#javaToNative(java.lang.Object, org.eclipse.swt.dnd.TransferData) */ @Override public void javaToNative(final Object object, final TransferData transferData) { if (object instanceof Data) { fData = (Data) object; } final byte[] check = TYPE_NAME.getBytes(); super.javaToNative(check, transferData); } /** * Overrides org.eclipse.swt.dnd.ByteArrayTransfer#nativeToJava(TransferData). * Test if the native drop data matches this transfer type. * * @see org.eclipse.swt.dnd.ByteArrayTransfer#nativeToJava(TransferData) */ @Override public Object nativeToJava(final TransferData transferData) { final Object result = super.nativeToJava(transferData); if (isInvalidNativeType(result)) { StatusManager.getManager().handle(new Status(IStatus.ERROR, NicoUI.PLUGIN_ID, ICommonStatusConstants.INTERNAL_ERROR, "invalid transfer type", null)); //$NON-NLS-1$ } return fData; } /** * Must be called by the drag adapter to initialize new dnd * (usually in {@link DragSourceListener#dragStart(org.eclipse.swt.dnd.DragSourceEvent)}) * @param process */ public void init(final ToolProcess process) { fProcess = process; } /** * Must be called by the drag adapter to create the transfer data * for the current dnd * * @return new data object or <code>null</code> if no current dnd */ public Data createData() { if (fProcess != null) { return new Data(fProcess); } return null; } /** * Must be called by the drag adapter to finish current dnd * (usually in {@link DragSourceListener#dragFinished(org.eclipse.swt.dnd.DragSourceEvent)}) */ public void finished() { fProcess = null; fData = null; } /** * Returns the main tool type for the current dnd * so the drop adapter can check the type * @return main type or <code>null</code> if no current dnd */ public String getMainType() { if (fProcess != null) { return fProcess.getMainType(); } return null; } }