/*******************************************************************************
* Copyright (c) 2006-2013 The RCP Company 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:
* The RCP Company - initial API and implementation
*******************************************************************************/
package com.rcpcompany.uibindings.internal.handlers;
import java.util.HashMap;
import java.util.Map;
import org.eclipse.core.commands.AbstractHandler;
import org.eclipse.core.commands.ExecutionEvent;
import org.eclipse.core.commands.IHandler;
import org.eclipse.core.databinding.observable.IObservable;
import org.eclipse.core.databinding.observable.list.IObservableList;
import org.eclipse.core.databinding.observable.value.IObservableValue;
import org.eclipse.core.databinding.observable.value.WritableValue;
import org.eclipse.swt.dnd.Clipboard;
import org.eclipse.swt.dnd.TextTransfer;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.handlers.HandlerUtil;
import com.rcpcompany.uibindings.Constants;
import com.rcpcompany.uibindings.IBindingContext;
import com.rcpcompany.uibindings.IBindingContext.FinishOption;
import com.rcpcompany.uibindings.IContainerBinding;
import com.rcpcompany.uibindings.IManager;
import com.rcpcompany.uibindings.IUIAttribute;
import com.rcpcompany.uibindings.IUIBindingsPackage;
import com.rcpcompany.uibindings.IValueBinding;
import com.rcpcompany.uibindings.internal.Activator;
import com.rcpcompany.uibindings.internal.utils.dnd.BindingTransfer;
import com.rcpcompany.uibindings.uiAttributes.SimpleUIAttribute;
import com.rcpcompany.utils.logging.LogUtils;
/**
* Handler for org.eclipse.ui.edit.paste for within {@link IContainerBinding}...
*
* @author Tonny Madsen, The RCP Company
*/
public class ViewerPasteHandler extends AbstractHandler implements IHandler {
@Override
public Object execute(ExecutionEvent event) {
if (Activator.getDefault().TRACE_HANDLERS) {
LogUtils.debug(this, "");
}
final IValueBinding binding = (IValueBinding) HandlerUtil.getVariable(event, Constants.SOURCES_ACTIVE_BINDING);
final boolean ro = HandlerUtil.getVariable(event, Constants.SOURCES_ACTIVE_BINDING_RO) == Boolean.TRUE;
final Clipboard clipboard = IManager.Factory.getManager().getClipboard();
/*
* - Check that the cell can in fact be changed
*/
if (ro) {
Display.getCurrent().beep();
return null;
}
final Class<?> dataType = binding.getDataType().getDataType();
/*
* - if a binding based transfer is attempted, then check that the data type of the cell can
* be assigned to from the type of the content
*/
Object content = clipboard.getContents(BindingTransfer.getInstance());
if (content != null) {
if (isAssignableFrom(dataType, content.getClass())) {
final IObservable observable = binding.getModelObservable();
if (observable instanceof IObservableValue) {
((IObservableValue) observable).setValue(content);
}
if (observable instanceof IObservableList) {
((IObservableList) observable).add(content);
}
return null;
}
}
/*
* - otherwise attempt a text based assignment.
*/
content = clipboard.getContents(TextTransfer.getInstance());
if (content != null) {
final IBindingContext context = binding.getContext();
final WritableValue ov = new WritableValue("", String.class);
final IUIAttribute attribute = new SimpleUIAttribute(null, "", ov, true);
// TODO: Why are we sure about this being a value?
final IValueBinding pasteBinding = context.addBinding().model(binding.getModelObservableValue())
.ui(attribute);
if (binding.hasArguments()) {
pasteBinding.getExtraArgumentProviders().add(binding);
}
if (binding.getParentBinding() != null) {
pasteBinding.getExtraArgumentProviders().add(binding.getParentBinding());
}
if (binding.eIsSet(IUIBindingsPackage.Literals.BINDING__EXTRA_ARGUMENT_PROVIDERS)) {
pasteBinding.getExtraArgumentProviders().addAll(binding.getExtraArgumentProviders());
}
context.finish(FinishOption.FORCE);
ov.setValue(content);
// TODO check for errors and popup an info box
pasteBinding.dispose();
return null;
}
return null;
}
/**
* Mapping from the boxed type to the corresponding primitive type.
*/
private final Map<Class<?>, Class<?>> primitiveMap = new HashMap<Class<?>, Class<?>>();
{
primitiveMap.put(Integer.class, Integer.TYPE);
primitiveMap.put(Boolean.class, Boolean.TYPE);
primitiveMap.put(Character.class, Character.TYPE);
primitiveMap.put(Byte.class, Byte.TYPE);
primitiveMap.put(Short.class, Short.TYPE);
primitiveMap.put(Long.class, Long.TYPE);
primitiveMap.put(Float.class, Float.TYPE);
primitiveMap.put(Double.class, Double.TYPE);
}
private boolean isAssignableFrom(Class<?> destination, Class<?> source) {
if (destination.isAssignableFrom(source)) return true;
if (destination.isPrimitive()) {
final Class<?> s = primitiveMap.get(source);
if (s != null && destination.isAssignableFrom(s)) return true;
}
return false;
}
}