| /******************************************************************************* |
| * Copyright (c) 2009, 2011 EclipseSource 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: |
| * EclipseSource - initial API and implementation |
| ******************************************************************************/ |
| package org.eclipse.swt.internal.widgets.displaykit; |
| |
| |
| import static org.eclipse.rap.rwt.lifecycle.WidgetUtil.getId; |
| import static org.eclipse.rap.rwt.testfixture.Fixture.getProtocolMessage; |
| import static org.mockito.Matchers.any; |
| import static org.mockito.Mockito.mock; |
| import static org.mockito.Mockito.times; |
| import static org.mockito.Mockito.verify; |
| |
| import java.util.ArrayList; |
| import java.util.Arrays; |
| import java.util.Date; |
| import java.util.HashMap; |
| import java.util.List; |
| import java.util.Map; |
| |
| import junit.framework.TestCase; |
| |
| import org.eclipse.rap.rwt.lifecycle.PhaseId; |
| import org.eclipse.rap.rwt.testfixture.Fixture; |
| import org.eclipse.rap.rwt.testfixture.Message; |
| import org.eclipse.rap.rwt.testfixture.Message.CallOperation; |
| import org.eclipse.swt.SWT; |
| import org.eclipse.swt.SWTException; |
| import org.eclipse.swt.dnd.DND; |
| import org.eclipse.swt.dnd.DragSource; |
| import org.eclipse.swt.dnd.DragSourceAdapter; |
| import org.eclipse.swt.dnd.DragSourceEvent; |
| import org.eclipse.swt.dnd.DragSourceListener; |
| import org.eclipse.swt.dnd.DropTarget; |
| import org.eclipse.swt.dnd.DropTargetAdapter; |
| import org.eclipse.swt.dnd.DropTargetEvent; |
| import org.eclipse.swt.dnd.DropTargetListener; |
| import org.eclipse.swt.dnd.HTMLTransfer; |
| import org.eclipse.swt.dnd.RTFTransfer; |
| import org.eclipse.swt.dnd.TextTransfer; |
| import org.eclipse.swt.dnd.Transfer; |
| import org.eclipse.swt.dnd.TransferData; |
| import org.eclipse.swt.events.DragDetectEvent; |
| import org.eclipse.swt.events.DragDetectListener; |
| import org.eclipse.swt.events.TypedEvent; |
| import org.eclipse.swt.widgets.Control; |
| import org.eclipse.swt.widgets.Display; |
| import org.eclipse.swt.widgets.Label; |
| import org.eclipse.swt.widgets.Shell; |
| import org.json.JSONArray; |
| import org.json.JSONException; |
| |
| public class DNDSupport_Test extends TestCase { |
| |
| private Display display; |
| private Shell shell; |
| private List<TypedEvent> log; |
| private Control sourceControl; |
| private Control targetControl; |
| private DragSource dragSource; |
| private DropTarget dropTarget; |
| private Transfer[] transfers; |
| |
| @Override |
| protected void setUp() throws Exception { |
| Fixture.setUp(); |
| display = new Display(); |
| shell = new Shell( display ); |
| shell.open(); |
| sourceControl = new Label( shell, SWT.NONE ); |
| targetControl = new Label( shell, SWT.NONE ); |
| log = new ArrayList<TypedEvent>(); |
| Fixture.fakeNewRequest( display ); |
| Fixture.fakePhase( PhaseId.PROCESS_ACTION ); |
| transfers = new Transfer[] { |
| HTMLTransfer.getInstance(), |
| TextTransfer.getInstance() |
| }; |
| } |
| |
| @Override |
| protected void tearDown() throws Exception { |
| Fixture.tearDown(); |
| } |
| |
| public void testDragDetectEvent() { |
| createDragSource( DND.DROP_MOVE ); |
| DragDetectListener listener = mock( DragDetectListener.class ); |
| sourceControl.addDragDetectListener( listener ); |
| |
| fakeDragSourceEvent( "dragStart", 1 ); |
| Fixture.executeLifeCycleFromServerThread(); |
| |
| verify( listener, times( 1 ) ).dragDetected( any( DragDetectEvent.class ) ); |
| } |
| |
| public void testDragStartEvent() { |
| createDragSource( DND.DROP_MOVE ); |
| DragSourceListener listener = mock( DragSourceListener.class ); |
| dragSource.addDragListener( listener ); |
| |
| fakeDragSourceEvent( "dragStart", 1 ); |
| Fixture.executeLifeCycleFromServerThread(); |
| |
| verify( listener, times( 1 ) ).dragStart( any( DragSourceEvent.class ) ); |
| } |
| |
| public void testCancelStart() { |
| createDragSource( DND.DROP_MOVE ); |
| dragSource.addDragListener( new DragSourceAdapter() { |
| @Override |
| public void dragStart( DragSourceEvent event ) { |
| event.doit = false; |
| } |
| } ); |
| |
| fakeDragSourceEvent( "dragStart", 1 ); |
| Fixture.executeLifeCycleFromServerThread(); |
| |
| assertNotNull( getProtocolMessage().findCallOperation( dragSource, "cancel" ) ); |
| } |
| |
| public void testDragDetectAndDragStartOrder() { |
| createDragSource( DND.DROP_MOVE ); |
| addLogger( dragSource ); |
| sourceControl.addDragDetectListener( new DragDetectListener() { |
| public void dragDetected( DragDetectEvent event ) { |
| log.add( event ); |
| } |
| } ); |
| |
| fakeDragSourceEvent( "dragStart", 1 ); |
| Fixture.executeLifeCycleFromServerThread(); |
| |
| int[] expected = new int[]{ SWT.DragDetect, DND.DragStart }; |
| assertTrue( Arrays.equals( expected, getEventOrder() ) ); |
| } |
| |
| public void testDragStartCoordinates() { |
| shell.setLocation( 5, 5 ); |
| sourceControl.setLocation( 10, 20 ); |
| createDragSource( DND.DROP_MOVE ); |
| new DropTarget( targetControl, DND.DROP_MOVE ); |
| dragSource.addDragListener( new DragSourceAdapter() { |
| @Override |
| public void dragStart( DragSourceEvent event ) { |
| log.add( event ); |
| } |
| } ); |
| |
| Fixture.fakeNewRequest( display ); |
| createDragSourceEvent( "dragStart", 20, 30, "move", 1 ); |
| Fixture.executeLifeCycleFromServerThread(); |
| |
| DragSourceEvent dragSourceEvent = ( DragSourceEvent )log.get( 0 ); |
| assertEquals( 4, dragSourceEvent.x ); |
| assertEquals( 4, dragSourceEvent.y ); |
| } |
| |
| public void testDropTargetLeaveBeforeEnter() { |
| createDragSource( DND.DROP_MOVE ); |
| createDropTarget( DND.DROP_MOVE ); |
| fakeDropTargetEvent( "dragEnter", 1 ); |
| Fixture.executeLifeCycleFromServerThread(); |
| addLogger( dropTarget ); |
| |
| Fixture.fakeNewRequest( display ); |
| fakeDropTargetEvent( "dragLeave", 2 ); |
| fakeDropTargetEvent( "dragEnter", 3 ); |
| fakeDropTargetEvent( "dragOver", 4 ); |
| Fixture.executeLifeCycleFromServerThread(); |
| |
| int[] expected = new int[]{ DND.DragLeave, DND.DragEnter, DND.DragOver }; |
| assertTrue( Arrays.equals( expected, getEventOrder() ) ); |
| } |
| |
| public void testDropOverValidTarget() { |
| createDragSource( DND.DROP_MOVE ); |
| createDropTarget( DND.DROP_MOVE ); |
| addLogger( dragSource ); |
| addLogger( dropTarget ); |
| addSetDragDataListener( dragSource, "text" ); |
| |
| fakeDropTargetEvent( "dropAccept", 1 ); |
| fakeDragSourceEvent( "dragFinished", 2 ); |
| Fixture.readDataAndProcessAction( display ); |
| |
| int[] expected = new int[]{ DND.DragLeave, DND.DropAccept, DND.DragSetData, DND.Drop, DND.DragEnd }; |
| assertTrue( Arrays.equals( expected, getEventOrder() ) ); |
| } |
| |
| public void testDataTransferOnDrop() { |
| createDragSource( DND.DROP_MOVE ); |
| createDropTarget( DND.DROP_MOVE ); |
| addLogger( dragSource ); |
| addLogger( dropTarget ); |
| addSetDragDataListener( dragSource, "Hello World!" ); |
| |
| |
| createDropTargetEvent( "dropAccept", 0, 0, "move", getTextType(), 1 ); |
| Fixture.readDataAndProcessAction( display ); |
| |
| DragSourceEvent dragSetDataEvent = getDragSourceEvent( 2 ); |
| DropTargetEvent dropEvent = getDropTargetEvent( 3 ); |
| assertEquals( dragSetDataEvent.dataType, dropEvent.currentDataType ); |
| assertEquals( "Hello World!", dropEvent.data ); |
| } |
| |
| public void testInvalidDataOnDragSetData() { |
| createDragSource( DND.DROP_MOVE ); |
| createDropTarget( DND.DROP_MOVE ); |
| addLogger( dragSource ); |
| addLogger( dropTarget ); |
| addSetDragDataListener( dragSource, new Date() ); |
| |
| SWTException exception = null; |
| |
| fakeDropTargetEvent( "dropAccept", 1 ); |
| try { |
| Fixture.executeLifeCycleFromServerThread(); |
| fail(); |
| } catch( SWTException e ) { |
| exception = e; |
| } |
| |
| int[] expected = new int[]{ DND.DragLeave, DND.DropAccept, DND.DragSetData }; |
| assertTrue( Arrays.equals( expected, getEventOrder() ) ); |
| assertEquals( DND.ERROR_INVALID_DATA, exception.code ); |
| } |
| |
| public void testChangeDataTypeOnDrop() { |
| createDragSource( DND.DROP_MOVE ); |
| createDropTarget( DND.DROP_MOVE ); |
| final TransferData[] originalType = new TransferData[ 1 ]; |
| dropTarget.addDropListener( new DropTargetAdapter() { |
| @Override |
| public void dropAccept( DropTargetEvent event ) { |
| originalType[ 0 ] = event.currentDataType; |
| boolean isFirstType = event.currentDataType.type == getType( transfers[ 0 ] ).type; |
| event.currentDataType = getType( transfers[ isFirstType ? 1 : 0 ] ); |
| } |
| @Override |
| public void drop( DropTargetEvent event ) { |
| log.add( event ); |
| } |
| } ); |
| addLogger( dragSource ); |
| addSetDragDataListener( dragSource, "data" ); |
| |
| |
| fakeDropTargetEvent( "dropAccept", 1 ); |
| Fixture.readDataAndProcessAction( display ); |
| |
| DragSourceEvent dragSetDataEvent = getDragSourceEvent( 0 ); |
| DropTargetEvent dropEvent = getDropTargetEvent( 1 ); |
| assertTrue( dragSetDataEvent.dataType.type != originalType[ 0 ].type ); |
| assertTrue( dragSetDataEvent.dataType.type == dropEvent.currentDataType.type ); |
| } |
| |
| public void testChangeDataTypeInvalidOnDrop() { |
| createDragSource( DND.DROP_MOVE ); |
| createDropTarget( DND.DROP_MOVE ); |
| dropTarget.addDropListener( new DropTargetAdapter() { |
| @Override |
| public void dropAccept( DropTargetEvent event ) { |
| RTFTransfer rtfTransfer = RTFTransfer.getInstance(); |
| event.currentDataType = rtfTransfer.getSupportedTypes()[ 0 ]; |
| } |
| } ); |
| addLogger( dragSource ); |
| addLogger( dropTarget ); |
| |
| fakeDropTargetEvent( "dropAccept", 1 ); |
| Fixture.readDataAndProcessAction( display ); |
| |
| int[] expected = new int[]{ DND.DragLeave, DND.DropAccept }; |
| assertTrue( Arrays.equals( expected, getEventOrder() ) ); |
| } |
| |
| public void testNoDropAfterDropAcceptEvent() { |
| createDragSource( DND.DROP_MOVE ); |
| createDropTarget( DND.DROP_MOVE ); |
| dropTarget.addDropListener( new DropTargetAdapter() { |
| @Override |
| public void dropAccept( DropTargetEvent event ) { |
| log.add( event ); |
| event.detail = DND.DROP_NONE; |
| } |
| @Override |
| public void drop( DropTargetEvent event ) { |
| log.add( event ); |
| } |
| } ); |
| addLogger( dragSource ); |
| |
| fakeDropTargetEvent( "dropAccept", 1 ); |
| fakeDragSourceEvent( "dragFinished", 2 ); |
| Fixture.readDataAndProcessAction( display ); |
| |
| int[] expected = new int[]{ DND.DropAccept, DND.DragEnd }; |
| assertTrue( Arrays.equals( expected, getEventOrder() ) ); |
| assertTrue( getDragSourceEvent( 1 ).doit ); // Actual SWT behavior |
| } |
| |
| public void testDropOverNonTarget() { |
| createDragSource( DND.DROP_MOVE ); |
| createDropTarget( DND.DROP_MOVE ); |
| addLogger( dragSource ); |
| addLogger( dropTarget ); |
| |
| fakeDragSourceEvent( "dragFinished", 1 ); |
| Fixture.readDataAndProcessAction( display ); |
| |
| assertEquals( 1, log.size() ); |
| DragSourceEvent event = getDragSourceEvent( 0 ); |
| assertEquals( DND.DragEnd, event.getID() ); |
| assertTrue( event.doit ); // Actual SWT behavior |
| } |
| |
| public void testChangeDetailInDropAccept() { |
| createDragSource( DND.DROP_MOVE | DND.DROP_COPY ); |
| createDropTarget( DND.DROP_MOVE | DND.DROP_COPY ); |
| addLogger( dragSource ); |
| addSetDragDataListener( dragSource, "text Data" ); |
| dropTarget.addDropListener( new DropTargetAdapter() { |
| @Override |
| public void dropAccept( DropTargetEvent event ) { |
| log.add( event ); |
| event.detail = DND.DROP_COPY; |
| } |
| @Override |
| public void drop( DropTargetEvent event ) { |
| log.add( event ); |
| } |
| } ); |
| |
| fakeDropTargetEvent( "dropAccept", 1 ); |
| fakeDragSourceEvent( "dragFinished", 2 ); |
| Fixture.readDataAndProcessAction( display ); |
| |
| assertEquals( DND.DROP_COPY, getDropTargetEvent( 0 ).detail ); |
| assertEquals( DND.DROP_NONE, getDragSourceEvent( 1 ).detail ); |
| assertEquals( DND.DROP_COPY, getDropTargetEvent( 2 ).detail ); |
| assertEquals( DND.DROP_COPY, getDragSourceEvent( 3 ).detail ); |
| assertTrue( getDragSourceEvent( 3 ).doit ); |
| } |
| |
| public void testChangeDetailInvalidInDropAccept() { |
| createDragSource( DND.DROP_MOVE | DND.DROP_COPY ); |
| createDropTarget( DND.DROP_MOVE ); |
| addLogger( dragSource ); |
| dropTarget.addDropListener( new DropTargetAdapter() { |
| @Override |
| public void dropAccept( DropTargetEvent event ) { |
| event.detail = DND.DROP_COPY; |
| } |
| } ); |
| |
| fakeDropTargetEvent( "dropAccept", 1 ); |
| fakeDragSourceEvent( "dragFinished", 2 ); |
| Fixture.readDataAndProcessAction( display ); |
| |
| assertTrue( getDragSourceEvent( 0 ).doit ); // This is still true in SWT/Win |
| assertEquals( DND.DROP_NONE, getDragSourceEvent( 0 ).detail ); |
| } |
| |
| public void testDragSetDataDoitIsFalse() { |
| createDragSource( DND.DROP_MOVE ); |
| createDropTarget( DND.DROP_MOVE ); |
| addLogger( dragSource ); |
| addLogger( dropTarget ); |
| dragSource.addDragListener( new DragSourceAdapter() { |
| @Override |
| public void dragSetData( DragSourceEvent event ) { |
| event.data = "TestData"; |
| event.doit = false; |
| } |
| } ); |
| |
| fakeDropTargetEvent( "dropAccept", 1 ); |
| fakeDragSourceEvent( "dragFinished", 2 ); |
| Fixture.readDataAndProcessAction( display ); |
| |
| int[] expected = new int[]{ |
| DND.DragLeave, |
| DND.DropAccept, |
| DND.DragSetData, |
| DND.Drop, |
| DND.DragEnd |
| }; |
| assertTrue( Arrays.equals( expected, getEventOrder() ) ); |
| // NOTE: This is not the behavior documented for SWT, but how SWT behaves in Windows (SWT bug?) |
| assertNull( getDropTargetEvent( 3 ).data ); |
| assertTrue( getDragSourceEvent( 4 ).doit ); |
| } |
| |
| public void testDragSetDataDataType() { |
| createDragSource( DND.DROP_MOVE ); |
| createDropTarget( DND.DROP_MOVE ); |
| addSetDragDataListener( dragSource, "string" ); |
| addLogger( dropTarget ); |
| addLogger( dragSource ); |
| |
| fakeDropTargetEvent( "dropAccept", 0 ); |
| Fixture.readDataAndProcessAction( display ); |
| |
| DragSourceEvent setDataEvent = getDragSourceEvent( 2 ); |
| DropTargetEvent dropEvent = getDropTargetEvent( 3 ); |
| assertNotNull( setDataEvent.dataType ); |
| assertEquals( setDataEvent.data, dropEvent.data ); |
| assertTrue( TransferData.sameType( setDataEvent.dataType, dropEvent.currentDataType ) ); |
| } |
| |
| public void testResponseNoDetailChange() { |
| createDragSource( DND.DROP_MOVE | DND.DROP_LINK | DND.DROP_COPY ); |
| createDropTarget( DND.DROP_MOVE | DND.DROP_LINK | DND.DROP_COPY ); |
| |
| createDropTargetEvent( "dragEnter", 10, 10, "copy", getTextType(), 1 ); |
| createDropTargetEvent( "dragOver", 10, 10, "copy", getTextType(), 2 ); |
| Fixture.executeLifeCycleFromServerThread(); |
| |
| Message message = Fixture.getProtocolMessage(); |
| assertNull( message.findSetOperation( dragSource, "changeDetail" ) ); |
| } |
| |
| public void testResponseDetailChangedOnEnter() { |
| createDragSource( DND.DROP_MOVE | DND.DROP_LINK | DND.DROP_COPY ); |
| createDropTarget( DND.DROP_MOVE | DND.DROP_LINK | DND.DROP_COPY ); |
| dropTarget.addDropListener( new DropTargetAdapter() { |
| @Override |
| public void dragEnter( DropTargetEvent event ) { |
| event.detail = DND.DROP_LINK; |
| } |
| } ); |
| |
| fakeDropTargetEvent( "dragEnter", 1 ); |
| fakeDropTargetEvent( "dragOver", 2 ); |
| Fixture.executeLifeCycleFromServerThread(); |
| |
| Message message = Fixture.getProtocolMessage(); |
| CallOperation call = message.findCallOperation( dragSource, "changeDetail" ); |
| assertEquals( getId( targetControl ), call.getProperty( "control" ) ); |
| assertEquals( "DROP_LINK", call.getProperty( "detail" ) ); |
| } |
| |
| public void testResponseDetailChangedOnOver() { |
| createDragSource( DND.DROP_MOVE | DND.DROP_LINK | DND.DROP_COPY ); |
| createDropTarget( DND.DROP_MOVE | DND.DROP_LINK | DND.DROP_COPY ); |
| dropTarget.addDropListener( new DropTargetAdapter() { |
| @Override |
| public void dragOver( DropTargetEvent event ) { |
| event.detail = DND.DROP_LINK; |
| } |
| } ); |
| |
| createDropTargetEvent( "dragEnter", 10, 10, "move", getTextType(), 1 ); |
| createDropTargetEvent( "dragOver", 10, 10, "copy", getTextType(), 2 ); |
| Fixture.executeLifeCycleFromServerThread(); |
| |
| Message message = Fixture.getProtocolMessage(); |
| CallOperation call = message.findCallOperation( dragSource, "changeDetail" ); |
| assertEquals( getId( targetControl ), call.getProperty( "control" ) ); |
| assertEquals( "DROP_LINK", call.getProperty( "detail" ) ); |
| } |
| |
| public void testDropAcceptWithDetailChangedOnEnter() { |
| createDragSource( DND.DROP_MOVE | DND.DROP_LINK | DND.DROP_COPY ); |
| createDropTarget( DND.DROP_MOVE | DND.DROP_LINK | DND.DROP_COPY ); |
| addSetDragDataListener( dragSource, "some data" ); |
| dropTarget.addDropListener( new DropTargetAdapter() { |
| @Override |
| public void dragEnter( DropTargetEvent event ) { |
| event.detail = DND.DROP_COPY; |
| } |
| } ); |
| addLogger( dropTarget ); |
| |
| Fixture.executeLifeCycleFromServerThread(); // clear pending message operations |
| Fixture.fakeNewRequest( display ); |
| fakeDropTargetEvent( "dragEnter", 1 ); |
| fakeDropTargetEvent( "dragOver", 2 ); |
| fakeDropTargetEvent( "dropAccept", 3 ); |
| fakeDragSourceEvent( "dragFinished", 3 ); |
| Fixture.executeLifeCycleFromServerThread(); |
| |
| Message message = Fixture.getProtocolMessage(); |
| assertEquals( 0, message.getOperationCount() ); |
| assertEquals( DND.DROP_COPY, getDropTargetEvent( 0 ).detail ); |
| assertEquals( DND.DROP_COPY, getDropTargetEvent( 1 ).detail ); |
| assertEquals( DND.DROP_COPY, getDropTargetEvent( 2 ).detail ); |
| assertEquals( DND.DROP_COPY, getDropTargetEvent( 3 ).detail ); |
| assertEquals( DND.DROP_COPY, getDropTargetEvent( 4 ).detail ); |
| } |
| |
| public void testDetermineDataType() { |
| createDragSource( DND.DROP_MOVE ); |
| createDropTarget( DND.DROP_MOVE ); |
| dropTarget.setTransfer( new Transfer[]{ |
| RTFTransfer.getInstance(), |
| HTMLTransfer.getInstance() |
| } ); |
| |
| TransferData[] dataTypes = DNDSupport.determineDataTypes( dragSource, dropTarget ); |
| |
| assertEquals( 1, dataTypes.length ); |
| assertTrue( HTMLTransfer.getInstance().isSupportedType( dataTypes[ 0 ] ) ); |
| } |
| |
| public void testResponseFeedbackChangedOnEnter() throws JSONException { |
| createDragSource( DND.DROP_MOVE | DND.DROP_LINK | DND.DROP_COPY ); |
| createDropTarget( DND.DROP_MOVE | DND.DROP_LINK | DND.DROP_COPY ); |
| dropTarget.addDropListener( new DropTargetAdapter() { |
| @Override |
| public void dragEnter( DropTargetEvent event ) { |
| event.feedback = DND.FEEDBACK_SELECT; |
| } |
| } ); |
| Fixture.executeLifeCycleFromServerThread(); // clear message |
| Fixture.fakeNewRequest( display ); |
| |
| fakeDropTargetEvent( "dragEnter", 1 ); |
| fakeDropTargetEvent( "dragOver", 2 ); |
| Fixture.executeLifeCycleFromServerThread(); |
| |
| Message message = Fixture.getProtocolMessage(); |
| CallOperation call = message.findCallOperation( dragSource, "changeFeedback" ); |
| assertEquals( getId( targetControl ), call.getProperty( "control" ) ); |
| assertEquals( new Integer( DND.FEEDBACK_SELECT ), call.getProperty( "flags" ) ); |
| JSONArray feedbackArr = ( JSONArray )call.getProperty( "feedback" ); |
| assertEquals( 1, feedbackArr.length() ); |
| assertEquals( "FEEDBACK_SELECT", feedbackArr.getString( 0 ) ); |
| } |
| |
| public void testResponseFeedbackChangedOnOver() throws JSONException { |
| createDragSource( DND.DROP_MOVE | DND.DROP_LINK | DND.DROP_COPY ); |
| createDropTarget( DND.DROP_MOVE | DND.DROP_LINK | DND.DROP_COPY ); |
| dropTarget.addDropListener( new DropTargetAdapter() { |
| @Override |
| public void dragOver( DropTargetEvent event ) { |
| event.feedback = DND.FEEDBACK_EXPAND | DND.FEEDBACK_SCROLL; |
| } |
| } ); |
| Fixture.executeLifeCycleFromServerThread(); // clear message |
| Fixture.fakeNewRequest( display ); |
| |
| fakeDropTargetEvent( "dragEnter", 1 ); |
| fakeDropTargetEvent( "dragOver", 2 ); |
| Fixture.executeLifeCycleFromServerThread(); |
| |
| Message message = Fixture.getProtocolMessage(); |
| CallOperation call = message.findCallOperation( dragSource, "changeFeedback" ); |
| assertEquals( getId( targetControl ), call.getProperty( "control" ) ); |
| Integer expectedFlags = new Integer( DND.FEEDBACK_SCROLL | DND.FEEDBACK_EXPAND ); |
| assertEquals( expectedFlags, call.getProperty( "flags" ) ); |
| JSONArray feedbackArr = ( JSONArray )call.getProperty( "feedback" ); |
| assertEquals( 2, feedbackArr.length() ); |
| assertEquals( "FEEDBACK_EXPAND", feedbackArr.getString( 0 ) ); |
| assertEquals( "FEEDBACK_SCROLL", feedbackArr.getString( 1 ) ); |
| |
| } |
| |
| public void testResponseInitDataType() { |
| createDragSource( DND.DROP_MOVE | DND.DROP_LINK | DND.DROP_COPY ); |
| createDropTarget( DND.DROP_MOVE | DND.DROP_LINK | DND.DROP_COPY ); |
| Transfer[] types = new Transfer[] { |
| TextTransfer.getInstance(), |
| RTFTransfer.getInstance() |
| }; |
| dragSource.setTransfer( types ); |
| dropTarget.setTransfer( types ); |
| Fixture.executeLifeCycleFromServerThread(); |
| |
| Fixture.fakeNewRequest( display ); |
| fakeDropTargetEvent( "dragEnter", 1 ); |
| Fixture.executeLifeCycleFromServerThread(); |
| |
| Message message = Fixture.getProtocolMessage(); |
| CallOperation call = message.findCallOperation( dragSource, "changeDataType" ); |
| assertEquals( getId( targetControl ), call.getProperty( "control" ) ); |
| } |
| |
| public void testResponseChangeDataTypeOnOver() { |
| createDragSource( DND.DROP_MOVE | DND.DROP_LINK | DND.DROP_COPY ); |
| createDropTarget( DND.DROP_MOVE | DND.DROP_LINK | DND.DROP_COPY ); |
| addLogger( dropTarget ); |
| dropTarget.addDropListener( new DropTargetAdapter() { |
| @Override |
| public void dragOver( DropTargetEvent event ) { |
| event.currentDataType = TextTransfer.getInstance().getSupportedTypes()[ 0 ]; |
| } |
| } ); |
| Fixture.executeLifeCycleFromServerThread(); |
| Fixture.fakeNewRequest( display ); |
| |
| fakeDropTargetEvent( "dragEnter", 1 ); |
| fakeDropTargetEvent( "dragOver", 2 ); |
| Fixture.executeLifeCycleFromServerThread(); |
| |
| DropTargetEvent dragEnter = getDropTargetEvent( 0 ); |
| assertTrue( HTMLTransfer.getInstance().isSupportedType( dragEnter.currentDataType ) ); |
| Message message = Fixture.getProtocolMessage(); |
| CallOperation call = message.findCallOperation( dragSource, "changeDataType" ); |
| assertEquals( getId( targetControl ), call.getProperty( "control" ) ); |
| assertEquals( new Integer( getTextType() ), call.getProperty( "dataType" ) ); |
| } |
| |
| public void testResponseChangeDataTypeOnEnter() { |
| int operations = DND.DROP_MOVE | DND.DROP_LINK | DND.DROP_COPY; |
| createDragSource( operations ); |
| createDropTarget( operations ); |
| addLogger( dropTarget ); |
| dropTarget.addDropListener( new DropTargetAdapter() { |
| @Override |
| public void dragEnter( DropTargetEvent event ) { |
| event.currentDataType = TextTransfer.getInstance().getSupportedTypes()[ 0 ]; |
| } |
| } ); |
| Fixture.executeLifeCycleFromServerThread(); |
| Fixture.fakeNewRequest( display ); |
| |
| fakeDropTargetEvent( "dragEnter", 1 ); |
| fakeDropTargetEvent( "dragOver", 2 ); |
| Fixture.executeLifeCycleFromServerThread(); |
| |
| DropTargetEvent dragOver = getDropTargetEvent( 1 ); |
| assertTrue( TextTransfer.getInstance().isSupportedType( dragOver.currentDataType ) ); |
| Message message = Fixture.getProtocolMessage(); |
| CallOperation call = message.findCallOperation( dragSource, "changeDataType" ); |
| assertEquals( getId( targetControl ), call.getProperty( "control" ) ); |
| Integer expectedType = new Integer( TextTransfer.getInstance().getSupportedTypes()[ 0 ].type ); |
| assertEquals( expectedType, call.getProperty( "dataType" ) ); |
| } |
| |
| public void testResponseChangeDataTypeInvalid() { |
| // NOTE : Setting an invalid value on currentDataType reverts the field |
| // back to the next-best valid value. This is NOT SWT-like behavior! |
| // SWT would set null and display the DROP_NONE cursor. |
| createDragSource( DND.DROP_MOVE | DND.DROP_LINK | DND.DROP_COPY ); |
| createDropTarget( DND.DROP_MOVE | DND.DROP_LINK | DND.DROP_COPY ); |
| dragSource.setTransfer( new Transfer[] { TextTransfer.getInstance() } ); |
| dropTarget.setTransfer( new Transfer[] { TextTransfer.getInstance() } ); |
| dropTarget.addDropListener( new DropTargetAdapter() { |
| @Override |
| public void dragOver( DropTargetEvent event ) { |
| event.currentDataType = RTFTransfer.getInstance().getSupportedTypes()[ 0 ]; |
| } |
| } ); |
| Fixture.executeLifeCycleFromServerThread(); |
| Fixture.fakeNewRequest( display ); |
| |
| fakeDropTargetEvent( "dragOver", 1 ); |
| Fixture.executeLifeCycleFromServerThread(); |
| |
| Message message = Fixture.getProtocolMessage(); |
| CallOperation call = message.findCallOperation( dragSource, "changeDataType" ); |
| assertEquals( getId( targetControl ), call.getProperty( "control" ) ); |
| Integer expectedType = new Integer( getTextType() ); |
| assertEquals( expectedType, call.getProperty( "dataType" ) ); |
| |
| } |
| |
| public void testOperationChangedEvent() { |
| createDragSource( DND.DROP_MOVE | DND.DROP_LINK | DND.DROP_COPY ); |
| createDropTarget( DND.DROP_MOVE | DND.DROP_LINK | DND.DROP_COPY ); |
| addLogger( dropTarget ); |
| |
| fakeDropTargetEvent( "dragEnter", 2 ); |
| createDropTargetEvent( "dragOperationChanged", 0, 0, "copy", getTextType(), 3 ); |
| fakeDropTargetEvent( "dragOver", 5 ); |
| Fixture.executeLifeCycleFromServerThread(); |
| |
| DropTargetEvent dragOperationChanged = getDropTargetEvent( 1 ); |
| assertEquals( DND.DragOperationChanged, dragOperationChanged.getID() ); |
| assertTrue( ( dragOperationChanged.detail & DND.DROP_COPY ) != 0 ); |
| DropTargetEvent dragOver = getDropTargetEvent( 2 ); |
| assertEquals( DND.DragOver, dragOver.getID() ); |
| } |
| |
| public void testOperationsField() { |
| createDragSource( DND.DROP_MOVE | DND.DROP_LINK ); |
| createDropTarget( DND.DROP_MOVE | DND.DROP_LINK ); |
| dragSource.addDragListener( new DragSourceAdapter(){ |
| @Override |
| public void dragSetData( DragSourceEvent event ) { |
| event.data = "text"; |
| } |
| } ); |
| addLogger( dropTarget ); |
| |
| fakeDropTargetEvent( "dragEnter", 2 ); |
| fakeDropTargetEvent( "dragOver", 5 ); |
| fakeDropTargetEvent( "dragOperationChanged", 7 ); |
| fakeDropTargetEvent( "dropAccept", 8 ); |
| Fixture.readDataAndProcessAction( display ); |
| |
| assertEquals( 6, log.size() ); |
| assertEquals( DND.DROP_MOVE | DND.DROP_LINK, getDropTargetEvent( 0 ).operations ); |
| assertEquals( DND.DROP_MOVE | DND.DROP_LINK, getDropTargetEvent( 1 ).operations ); |
| assertEquals( DND.DROP_MOVE | DND.DROP_LINK, getDropTargetEvent( 2 ).operations ); |
| assertEquals( 0, getDropTargetEvent( 3 ).operations ); |
| assertEquals( DND.DROP_MOVE | DND.DROP_LINK, getDropTargetEvent( 4 ).operations ); |
| assertEquals( DND.DROP_MOVE | DND.DROP_LINK, getDropTargetEvent( 5 ).operations ); |
| } |
| |
| ///////// |
| // Helper |
| |
| private void fakeDragSourceEvent( String eventType, int time ) { |
| createDragSourceEvent( eventType, 0, 0, "move", time ); |
| } |
| |
| private void createDragSourceEvent( String eventType, int x, int y, String operation, int time ) { |
| Map<String, Object> parameters = new HashMap<String, Object>(); |
| parameters.put( "x", String.valueOf( x ) ); |
| parameters.put( "y", String.valueOf( y ) ); |
| parameters.put( "time", String.valueOf( time ) ); |
| Fixture.fakeNotifyOperation( getId( sourceControl ), eventType, parameters ); |
| } |
| |
| private void fakeDropTargetEvent( String eventType, int time ) { |
| createDropTargetEvent( eventType, 0, 0, "move", getTextType(), time ); |
| } |
| |
| private void createDropTargetEvent( String eventType, |
| int x, |
| int y, |
| String operation, |
| int dataType, |
| int time ) |
| { |
| Map<String, Object> parameters = new HashMap<String, Object>(); |
| parameters.put( "x", String.valueOf( x ) ); |
| parameters.put( "y", String.valueOf( y ) ); |
| parameters.put( "time", String.valueOf( time ) ); |
| parameters.put( "operation", operation ); |
| parameters.put( "feedback", String.valueOf( 0 ) ); |
| parameters.put( "source", getId( sourceControl ) ); |
| parameters.put( "dataType", String.valueOf( dataType ) ); |
| Fixture.fakeNotifyOperation( getId( targetControl ), eventType, parameters ); |
| |
| } |
| |
| private void createDropTarget( int style ) { |
| dropTarget = new DropTarget( targetControl, style ); |
| dropTarget.setTransfer( transfers ); |
| } |
| |
| private void createDragSource( int style ) { |
| dragSource = new DragSource( sourceControl, style ); |
| dragSource.setTransfer( transfers ); |
| } |
| |
| TransferData getType( Transfer transfer ) { |
| return transfer.getSupportedTypes()[ 0 ]; |
| } |
| |
| private int getTextType() { |
| return getType( TextTransfer.getInstance()).type; |
| } |
| |
| private void addLogger( DragSource dragSource ) { |
| dragSource.addDragListener( new DragSourceListener() { |
| public void dragStart( DragSourceEvent event ) { |
| log.add( event ); |
| } |
| public void dragSetData( DragSourceEvent event ) { |
| log.add( event ); |
| } |
| public void dragFinished( DragSourceEvent event ) { |
| log.add( event ); |
| } |
| } ); |
| } |
| |
| private void addLogger( DropTarget dropTarget ) { |
| dropTarget.addDropListener( new LoggingDropTargetListener() ); |
| } |
| |
| private class LoggingDropTargetListener implements DropTargetListener { |
| public void dragEnter( DropTargetEvent event ) { |
| log.add( event ); |
| } |
| public void dragLeave( DropTargetEvent event ) { |
| log.add( event ); |
| } |
| public void dragOperationChanged( DropTargetEvent event ) { |
| log.add( event ); |
| } |
| public void dragOver( DropTargetEvent event ) { |
| log.add( event ); |
| } |
| public void drop( DropTargetEvent event ) { |
| log.add( event ); |
| } |
| public void dropAccept( DropTargetEvent event ) { |
| log.add( event ); |
| } |
| } |
| |
| private int[] getEventOrder() { |
| int[] result = new int[ log.size() ]; |
| for( int i = 0; i < result.length; i++ ) { |
| result[ i ] = log.get( i ).getID(); |
| } |
| return result; |
| } |
| |
| private void addSetDragDataListener( DragSource dragSource, final Object data ) { |
| dragSource.addDragListener( new DragSourceAdapter() { |
| @Override |
| public void dragSetData( DragSourceEvent event ) { |
| event.data = data; |
| } |
| } ); |
| } |
| |
| private DropTargetEvent getDropTargetEvent( int index ) { |
| return ( DropTargetEvent )log.get( index ); |
| } |
| |
| private DragSourceEvent getDragSourceEvent( int index ) { |
| return ( DragSourceEvent )log.get( index ); |
| } |
| |
| } |