package net.xoetrope.swing.dnd;
import java.awt.Component;
import java.awt.Container;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.io.IOException;
import java.util.Hashtable;
import javax.swing.DefaultListModel;
import javax.swing.JComponent;
import javax.swing.TransferHandler;
import net.xoetrope.xui.data.XModelHelper;
import net.xoetrope.swing.XImage;
import net.xoetrope.swing.XList;
import net.xoetrope.xui.XPage;
import net.xoetrope.xui.XProject;
import net.xoetrope.xui.data.XDataBinding;
import net.xoetrope.xui.data.XModel;
import net.xoetrope.xui.registry.XRegistrationSetup;
/**
* A transfer handler for transferring an XModel node from one component to
* another via drag and drop
* <p>Copyright (c) Xoetrope Ltd., 1998-2006. See license.txt for more details</p>
* @author luano
*/
public class XModelTransferHandler extends TransferHandler implements XRegistrationSetup
{
protected DataFlavor[] dataFlavors;
/** Creates a new instance of XModelTransferHandler */
public XModelTransferHandler()
{
dataFlavors = new DataFlavor[ 3 ];
try {
dataFlavors[ 0 ] = new DataFlavor( "application/x-xui-xmodeldockable" );
dataFlavors[ 1 ] = new DataFlavor( "application/x-xui-xcomponent" );
dataFlavors[ 2 ] = new DataFlavor( "application/x-xui-xdraginfo" );
}
catch ( Exception e )
{
e.printStackTrace();
}
}
public DataFlavor[] getTransferDataFlavors()
{
return dataFlavors;
}
/**
* Configure the transfer handler
* @param project the current project
* @param comp the source component
* @param handlerConfig extra configuration parameters
* @param instConfig the instance configuration parameters
*/
public void setup( XProject project, Object comp, Hashtable handlerConfig, Hashtable instConfig )
{
}
protected Transferable createTransferable( JComponent c )
{
Container p = c.getParent();
while (( p != null ) && !( p instanceof XPage ))
p = p.getParent();
if ( p != null ) {
if ( p instanceof XDragManager ){
XPage page = (XPage)p;
String key = (String)page.getAttribute( "dragInfo", c.getName() );
if ( key != null ) {
XDragManager dragManager = (XDragManager)p;
XDragInfo dragInfo = dragManager.getDragInfo( key );
return new XDragInfoTransferable( dragInfo, dataFlavors[ 2 ] );
}
}
else{
XDataBinding binding = ((XPage)p).getBinding( c );
if ( binding != null ) {
binding.set();
DataFlavor[] dragFlavors = new DataFlavor[ 2 ];
dragFlavors[ 0 ] = dataFlavors[ 0 ];
dragFlavors[ 1 ] = dataFlavors[ 1 ];
return new XModelTransfereable( binding.getSource(), binding.getOutput(), dragFlavors );
}
else
return new XComponentTransferable( c, dataFlavors[ 1 ] );
}
}
return null;
}
public int getSourceActions( JComponent c )
{
return COPY_OR_MOVE;
}
public boolean importData( JComponent c, Transferable t )
{
if ( canImport( ((JComponent)c), t.getTransferDataFlavors() )) {
try {
if( c instanceof XImage ){
XModel[] model = (XModel[])t.getTransferData( dataFlavors[ 0 ] );
XModel srcModel = model[ 0 ];
String selection = model[ 1 ].get().toString();
XModel data = XModelHelper.getFirstChild( srcModel, selection );
((XImage)c).setAttribute( "content", data.getAttribValueAsString( data.getAttribute( "image" )));
}
else if( c instanceof XList ){
XDragInfo dragInfo = (XDragInfo)t.getTransferData( dataFlavors[ 2 ] );
DefaultListModel model = (DefaultListModel)((XList)c).getModel();
model.add( model.getSize(), dragInfo );
}
}
catch ( UnsupportedFlavorException ex )
{
try {
Component comp = (Component)t.getTransferData( dataFlavors[ 1 ] );
if ( comp instanceof XImage )
((XImage)c).setImageName( ((XImage)comp).getImageName() );
}
catch ( Exception exception )
{
exception.printStackTrace();
}
}
catch ( Exception ufe )
{
return false;
}
}
return true;
}
protected void exportDone( JComponent c, Transferable data, int action )
{
// cleanup(c, action == MOVE);
}
public boolean canImport( JComponent c, DataFlavor[] flavors )
{
for ( int i = 0; i < flavors.length; i++ ) {
int numFlavors = dataFlavors.length;
for ( int j = 0; j < numFlavors; j++ ) {
if (( flavors[ i ] != null ) && flavors[ i ].equals( dataFlavors[ j ] ))
return true;
}
}
return false;
}
}