Commits

Tom Yeh committed 83de5f4 Merge

Merge branch 'master' of ssh://bitbucket.org/doubleshow/sikuli-api

Comments (0)

Files changed (7)

src/main/java/org/sikuli/api/APILogger.java

 	public void typePerformed(String text){
 	}
 
+	public void copyPerformed(String text) {	
+	}
+
 	public void pastePerformed(String text){
 	}	
 	
 	
 	static public APILogger createVisualLogger(ScreenRegion screenRegion, File outputDir){
 		return new ScreenRegionImageLogger(screenRegion, outputDir);
-	}
-
-	
+	}	
 }
 
 class StdoutLogger extends DefaultLogger {
 	}
 	
 	@Override
+	public void copyPerformed(String text) {
+		out(now() + "\t" + (text==null?"could not copy text":"Copy text "+text));
+	}
+	
+	@Override
 	public void clickPerformed(ScreenLocation location){
 		out(now() + "\t" + "Click at " + location);
 	}

src/main/java/org/sikuli/api/robot/Keyboard.java

 
 public interface Keyboard {
 	
+	/**
+	 * Clears the clipboard, performs the "copy" keyboard shortcut, then attempts to return the 
+	 * clipboard contents as a String. 
+	 * 
+	 * Returns <code>null</code> if the clipboard couldn't be converted to a string or was empty.
+	 * 
+	 * @return The clipboard contents converted to a String or <code>null</code>
+	 */
+	public String copy();
+	
 	public void paste(String text);
 	public void type(String text);
 

src/main/java/org/sikuli/api/robot/desktop/Clipboard.java

    public static final TransferType BYTE_BUFFER = new TransferType(ByteBuffer.class);
 
    private Clipboard() {
+   }
+   
+   /**
+    * Empty the current clipboard so that future attempts to fetch text will fail.
+    */
+   public static void clear() {
+	   // from http://www.jroller.com/alexRuiz/entry/clearing_the_system_clipboard
+	   getSystemClipboard().setContents(new Transferable() {
+	        public DataFlavor[] getTransferDataFlavors() {
+	            return new DataFlavor[0];
+	          }
+
+	          public boolean isDataFlavorSupported(DataFlavor flavor) {
+	            return false;
+	          }
+
+	          public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException {
+	            throw new UnsupportedFlavorException(flavor);
+	          }
+	        }, null);
+   }
+   
+   /**
+    * Get the contents of the clipboard as a String.
+    * If they cannot be converted to a String or some other problem prevents the operation, return <code>null</code>
+    * @return the clipboard contents as a String, or <code>null</code>
+    */
+   public static String getText() {
+	   Transferable clipboardContents = getSystemClipboard().getContents(Clipboard.class);
+	   DataFlavor[] flavors = clipboardContents.getTransferDataFlavors();
+	   if (flavors.length == 0)
+		   return null;
+	   DataFlavor textFlavor = DataFlavor.selectBestTextFlavor(flavors);
+	   if (textFlavor == null)
+		   return null;
+	   Reader clipboardReader = null;
+	   try {
+		   clipboardReader = textFlavor.getReaderForText(clipboardContents);
+
+		   // This block could be replaced with apache-commons-io's IOUtils
+		   StringBuffer sb = new StringBuffer();
+		   char[] cbuf = new char[4096];
+		   int rcount = clipboardReader.read(cbuf);
+		   while (rcount != -1) {
+			   sb.append(cbuf, 0, rcount);
+			   rcount = clipboardReader.read(cbuf);
+		   }
+		   return sb.toString();
+	   } catch (UnsupportedFlavorException e) {
+		   return null;  // got the clipboard, but it couldn't be made into text
+	   } catch (IOException e) {
+		   return null;  // misc error
+	   } finally {
+		   if (clipboardReader != null)
+			   try {
+				   clipboardReader.close();
+			   } catch (IOException e) {}
+	   }
    }
 
    /**
       public String toString() {
          return dataClass.getName();
       }
-   }
-
+   }
 }

src/main/java/org/sikuli/api/robot/desktop/DesktopKeyboard.java

 	static private AWTRobot getRobot(){
 		return AWTDesktop.getCurrentRobot();
 	}
+	
+
+	public String copy() {
+		Clipboard.clear();
+
+		int mod = Env.getHotkeyModifier();
+		AWTRobot robot = getRobot();
+		robot.keyPress(mod);
+		robot.keyPress(KeyEvent.VK_C);
+		robot.keyRelease(KeyEvent.VK_C);
+		robot.keyRelease(mod);
+
+		String text = Clipboard.getText();
+		APILogger.getLogger().copyPerformed(text);
+		return text;
+	}
 
 	
 	public void paste(String text){

src/test/java/org/sikuli/api/robot/CopySource.java

+package org.sikuli.api.robot;
+
+import java.awt.GridLayout;
+
+import javax.swing.JFrame;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.JTextField;
+import javax.swing.border.EmptyBorder;
+import java.awt.event.FocusAdapter;
+import java.awt.event.FocusEvent;
+import java.awt.event.FocusListener;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+/**
+ * Simple JFrame so that we have something to copy text from in the test
+ *
+ */
+@SuppressWarnings("serial")
+public class CopySource extends JFrame {
+
+	private JPanel contentPane;
+	private JTextField textField1;
+	private JLabel lblField_1;
+	private JTextField textField2;
+	private JLabel lblField_2;
+	private JTextField textField3;
+	private FocusListener focusSelector = new FocusAdapter() {
+		@Override
+		public void focusGained(FocusEvent event) {
+			JTextField target = (JTextField) event.getComponent();
+			target.selectAll();
+			isReady.set(true);
+		}
+	};
+	private final AtomicBoolean isReady = new AtomicBoolean(false);
+
+	public boolean isReady() {
+		return isReady.get();
+	}
+	
+	/**
+	 * Create the frame.
+	 */
+	public CopySource() {
+		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+		setBounds(100, 100, 450, 300);
+		contentPane = new JPanel();
+		contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
+		setContentPane(contentPane);
+		contentPane.setLayout(new GridLayout(0, 2, 0, 0));
+		{
+			JLabel lblField = new JLabel("Field1");
+			contentPane.add(lblField);
+		}
+		{
+			textField1 = new JTextField();
+			textField1.addFocusListener(focusSelector);
+			textField1.setText("hello");
+			contentPane.add(textField1);
+			textField1.setColumns(10);
+		}
+		{
+			lblField_1 = new JLabel("Field2");
+			contentPane.add(lblField_1);
+		}
+		{
+			textField2 = new JTextField();
+			textField2.addFocusListener(focusSelector);
+			textField2.setText("world");
+			contentPane.add(textField2);
+			textField2.setColumns(10);
+		}
+		{
+			lblField_2 = new JLabel("Field3");
+			contentPane.add(lblField_2);
+		}
+		{
+			textField3 = new JTextField();
+			textField3.addFocusListener(focusSelector);
+			textField3.setText("test ü");
+			contentPane.add(textField3);
+			textField3.setColumns(10);
+		}
+	}
+
+}

src/test/java/org/sikuli/api/robot/TestKeyboard.java

+package org.sikuli.api.robot;
+
+import java.lang.reflect.InvocationTargetException;
+
+import javax.swing.SwingUtilities;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.sikuli.api.robot.desktop.DesktopKeyboard;
+import static org.junit.Assert.*;
+
+public class TestKeyboard {
+	private CopySource cs;
+	private Keyboard kb;
+	@Before
+	public void setup() throws InterruptedException, InvocationTargetException {
+		cs = new CopySource();
+		SwingUtilities.invokeAndWait(new Runnable(){
+			@Override
+			public void run() {
+				cs.setVisible(true);
+			}});
+		// make sure that the JFame is completely up before we attempt any test
+		while (!cs.isReady())
+			Thread.sleep(100);
+		kb = new DesktopKeyboard();
+	}
+	
+	@After
+	public void teardown() {
+		cs.setVisible(false);
+		cs.dispose();
+		cs = null;
+		kb = null;
+	}
+	
+	@Test
+	public void testCopyFirst() throws InterruptedException, InvocationTargetException {
+		String s = kb.copy();
+		assertEquals("hello", s);
+	}
+	
+	@Test
+	public void testCopySecond() {
+		kb.type(Key.TAB);
+		String s = kb.copy();
+		assertEquals("world", s);
+	}
+
+	@Test
+	public void testCopyThird() {
+		kb.type(Key.TAB);
+		kb.type(Key.TAB);
+		String s = kb.copy();
+		assertEquals("test ü", s);
+	}
+}

src/test/java/org/sikuli/api/robot/desktop/TestClipboard.java

+package org.sikuli.api.robot.desktop;
+
+import org.junit.Test;
+import static org.junit.Assert.*;
+
+public class TestClipboard {
+	@Test
+	public void testCopyPaste() {
+		String expected = "hello world";
+		Clipboard.putText(expected);
+		String found = Clipboard.getText();
+		assertEquals(expected, found);
+	}
+	
+	@Test
+	public void testClear() {
+		String expected = "hello world";
+		Clipboard.putText(expected);
+		String found = Clipboard.getText();
+		assertEquals(expected, found);
+		
+		Clipboard.clear();
+		found = Clipboard.getText();
+		assertNull(found);
+	}
+}