blob: 62364402f1d5a0267c833fe90bb1d1735bac2c57 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2006, 2010 Soyatec (http://www.soyatec.com) 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: *
* Soyatec - initial API and implementation *
*******************************************************************************/
package org.eclipse.xwt.ui.editor.dnd;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.core.resources.IFile;
import org.eclipse.xwt.XWT;
import org.eclipse.xwt.metadata.IMetaclass;
import org.eclipse.xwt.utils.PathHelper;
import org.eclipse.jface.text.templates.Template;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.dnd.DND;
import org.eclipse.swt.dnd.DropTargetEvent;
import org.eclipse.ui.part.FileEditorInput;
import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;
import org.eclipse.xwt.ui.editor.XWTEditor;
import org.eclipse.xwt.vex.VEXContext;
import org.eclipse.xwt.vex.dom.DomHelper;
import org.eclipse.xwt.vex.toolpalette.ContextType;
import org.w3c.dom.NamedNodeMap;
/**
* @author jliu jin.liu@soyatec.com
*/
public class ImageDnDAdapter extends DnDAdapterImpl {
private static List<String> supportedImageExts = new ArrayList<String>();
private static List<String> supportedImageAttrs = new ArrayList<String>();
static {
supportedImageExts.add("png");
supportedImageExts.add("gif");
supportedImageExts.add("bmp");
}
static {
supportedImageAttrs.add("image");
supportedImageAttrs.add("backgroundImage");
}
private IFile image;
private IFile editorInput;
private IDOMNode acceptAttr;
/**
* @param editor
*/
public ImageDnDAdapter(XWTEditor editor) {
super(editor);
editorInput = ((FileEditorInput) editor.getEditorInput()).getFile();
}
/*
* (non-Javadoc)
*
* @see org.eclipse.xwt.ui.editor.dnd.DnDAdapterImpl#createTemplate(java.lang.Object)
*/
protected Template createTemplate(Object selection) {
String pattern = computePath();
if (acceptAttr == null) {
pattern = "image=\"" + pattern + "\"";
}
return new Template("image", "", getContextType().getName(), pattern, true);
}
/**
* @return
*/
private String computePath() {
if (editorInput != null) {
return PathHelper.getRelativePath(editorInput.getLocation().toString(), image.getLocation().toString());
}
return image.getLocation().toString();
}
/*
* (non-Javadoc)
*
* @see org.eclipse.xwt.ui.editor.dnd.DnDAdapterImpl#isAccept(java.lang.Object)
*/
protected boolean isAccept(Object selection) {
if (selection instanceof IFile) {
String ext = ((IFile) selection).getFileExtension();
boolean contains = supportedImageExts.contains(ext);
if (contains) {
image = (IFile) selection;
}
return contains;
}
return false;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.xwt.ui.editor.dnd.DnDAdapterImpl#drop(org.eclipse.swt.dnd.DropTargetEvent)
*/
@Override
public void drop(DropTargetEvent event) {
Object selection = getSelection();
if (!isAccept()) {
return;
}
Template template = createTemplate(selection);
if (template == null) {
return;
}
String nodeValue = acceptAttr == null ? "" : acceptAttr.getNodeValue();
drop(template, getDropCaretOffset(), nodeValue == null ? 0 : nodeValue.length());
}
/*
* (non-Javadoc)
*
* @see org.eclipse.xwt.ui.editor.dnd.DnDAdapterImpl#dragOver(org.eclipse.swt.dnd.DropTargetEvent)
*/
@Override
public void dragOver(DropTargetEvent event) {
if (!isAccept()) {
return;
}
IDOMNode node = (IDOMNode) getCurrentNode(event);
int cursor = getCursor(event);
VEXContext context = getEditor().getContext();
int position = context.findDropPosition(node, getScope(), getContextType(), cursor);
if (position >= 0) {
NamedNodeMap attributes = node.getAttributes();
if (attributes != null) {
acceptAttr = getAttr(node, cursor);
StyledText styledText = getEditor().getTextWidget();
if (acceptAttr == null && hasImageFeature(node)) {
setDropCaretOffset(cursor);
refreshCaret(styledText, getDropCaretOffset());
return;
} else if (acceptAttr != null && supportedImageAttrs.contains(acceptAttr.getNodeName())) {
setDropCaretOffset(getInsertion(acceptAttr, cursor));
refreshCaret(styledText, getDropCaretOffset());
return;
}
}
}
event.detail = DND.DROP_NONE;
}
/**
* @param node
* @return
*/
private boolean hasImageFeature(IDOMNode node) {
boolean hasImageAttr = getImageAttr(node) == null;
String nodeName = node.getNodeName();
IMetaclass metaclass = XWT.getMetaclass(nodeName, DomHelper.lookupNamespaceURI(node));
if (metaclass != null) {
hasImageAttr &= metaclass.findProperty("image") != null;
}
return hasImageAttr;
}
/**
* @param acceptAttr
* @param cursor
* @return
*/
private int getInsertion(IDOMNode acceptAttr, int cursor) {
if (acceptAttr == null) {
return cursor;
}
return acceptAttr.getStartOffset() + acceptAttr.getNodeName().length() + 2;
}
private IDOMNode getAttr(IDOMNode node, int cursor) {
NamedNodeMap attributes = node.getAttributes();
if (attributes == null) {
return null;
}
for (int i = 0; i < attributes.getLength(); i++) {
IDOMNode attr = (IDOMNode) attributes.item(i);
int startOffset = attr.getStartOffset();
int endOffset = attr.getEndOffset();
if (cursor >= startOffset && cursor < endOffset) {
return attr;
}
}
return null;
}
private IDOMNode getImageAttr(IDOMNode node) {
NamedNodeMap attributes = node.getAttributes();
if (attributes == null) {
return null;
}
for (int i = 0; i < attributes.getLength(); i++) {
IDOMNode attr = (IDOMNode) attributes.item(i);
if (supportedImageAttrs.contains(attr.getNodeName())) {
return attr;
}
}
return null;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.xwt.ui.editor.dnd.DnDAdapter#getContextType()
*/
public ContextType getContextType() {
return ContextType.XML_ATTRIBUTE_VALUE;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.xwt.ui.editor.dnd.DnDAdapter#getScope()
*/
public String getScope() {
return null;
}
}