diff options
Diffstat (limited to 'java/com/tigervnc/vncviewer/ClipboardDialog.java')
-rw-r--r-- | java/com/tigervnc/vncviewer/ClipboardDialog.java | 122 |
1 files changed, 82 insertions, 40 deletions
diff --git a/java/com/tigervnc/vncviewer/ClipboardDialog.java b/java/com/tigervnc/vncviewer/ClipboardDialog.java index d4cde6e1..fff7dc3e 100644 --- a/java/com/tigervnc/vncviewer/ClipboardDialog.java +++ b/java/com/tigervnc/vncviewer/ClipboardDialog.java @@ -1,5 +1,5 @@ /* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved. - * Copyright (C) 2011 Brian P. Hinz + * Copyright (C) 2011-2014 Brian P. Hinz * * This is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -21,27 +21,83 @@ package com.tigervnc.vncviewer; import java.awt.*; import java.awt.event.*; -import java.awt.datatransfer.Clipboard; -import java.awt.datatransfer.StringSelection; +import java.awt.datatransfer.*; +import java.io.*; +import java.nio.*; import javax.swing.*; import javax.swing.border.*; +import javax.swing.text.*; + import com.tigervnc.rfb.LogWriter; class ClipboardDialog extends Dialog implements ActionListener { + private class VncTransferHandler extends TransferHandler { + // Custom TransferHandler designed to limit the size of outbound + // clipboard transfers to VncViewer.maxCutText.getValue() bytes. + private LogWriter vlog = new LogWriter("VncTransferHandler"); + + public boolean importData(JComponent c, Transferable t) { + if (canImport(c, t.getTransferDataFlavors())) { + try { + DataFlavor VncFlavor = null; + for (DataFlavor f : t.getTransferDataFlavors()) + if (f.isFlavorTextType() && f.isRepresentationClassInputStream()) + VncFlavor = f; + if (VncFlavor == null) return false; + Reader reader = (Reader)VncFlavor.getReaderForText(t); + CharBuffer cbuf = + CharBuffer.allocate(VncViewer.maxCutText.getValue()); + cbuf.limit(reader.read(cbuf.array(), 0, cbuf.length())); + reader.close(); + if (c instanceof JTextComponent) + ((JTextComponent)c).setText(cbuf.toString()); + return true; + } catch (OutOfMemoryError oome) { + vlog.error("ERROR: Too much data on local clipboard!"); + } catch (UnsupportedFlavorException ufe) { + // Skip import + vlog.info(ufe.toString()); + } catch (IOException ioe) { + // Skip import + vlog.info(ioe.toString()); + } + } + return false; + } + + public boolean canImport(JComponent c, DataFlavor[] flavors) { + for (DataFlavor f : flavors) + if (f.isFlavorTextType() && f.isRepresentationClassReader()) + return true; + return false; + } + } + public ClipboardDialog(CConn cc_) { super(false); + setTitle("VNC Clipboard Viewer"); + setPreferredSize(new Dimension(640, 480)); + addWindowFocusListener(new WindowAdapter() { + // Necessary to ensure that updates from the system clipboard + // still occur when the ClipboardDialog has the focus. + public void WindowGainedFocus(WindowEvent e) { + clientCutText(); + } + }); cc = cc_; - setTitle("VNC clipboard"); - JPanel pt = new JPanel(); - textArea = new JTextArea(5,50); - textArea.setBorder(BorderFactory.createLineBorder(Color.gray)); - textArea.setLineWrap(true); + textArea = new JTextArea(); + textArea.setTransferHandler(new VncTransferHandler()); + // If the textArea can receive the focus, then text within the textArea + // can be selected. On platforms that don't support separate selection + // and clipboard buffers, this triggers a replacement of the textAra's + // contents with the selected text. + textArea.setFocusable(false); + textArea.setLineWrap(false); textArea.setWrapStyleWord(true); JScrollPane sp = new JScrollPane(textArea); - pt.add(sp, BorderLayout.CENTER); - getContentPane().add("North", pt); - + getContentPane().add(sp, BorderLayout.CENTER); + // button panel placed below the scrollpane JPanel pb = new JPanel(); clearButton = new JButton("Clear"); pb.add(clearButton); @@ -53,40 +109,24 @@ class ClipboardDialog extends Dialog implements ActionListener { pb.add(cancelButton); cancelButton.addActionListener(this); getContentPane().add("South", pb); - pack(); } - public boolean compareContentsTo(String str) { - return str.equals(textArea.getText()); - - } - - public void setContents(String str) { + public void serverCutText(String str, int len) { textArea.setText(str); + textArea.selectAll(); + textArea.copy(); } - public String getContents() { - return textArea.getText(); - } - - public void serverCutText(String str, int len) { - setContents(str); - SecurityManager sm = System.getSecurityManager(); - try { - if (sm != null) sm.checkSystemClipboardAccess(); - Clipboard cb = Toolkit.getDefaultToolkit().getSystemClipboard(); - if (cb != null) { - StringSelection ss = new StringSelection(str); - try { - cb.setContents(ss, null); - } catch(Exception e) { - vlog.debug(e.getMessage()); - } - } - } catch(SecurityException e) { - vlog.debug("Cannot access the system clipboard: "+e.getMessage()); - } + public void clientCutText() { + int hc = textArea.getText().hashCode(); + textArea.setText(""); + textArea.paste(); + textArea.setCaretPosition(0); + String text = textArea.getText(); + if (cc.viewer.sendClipboard.getValue()) + if (hc != text.hashCode()) + cc.writeClientCutText(text, text.length()); } public void setSendingEnabled(boolean b) { @@ -98,7 +138,9 @@ class ClipboardDialog extends Dialog implements ActionListener { if (s instanceof JButton && (JButton)s == clearButton) { serverCutText(new String(""), 0); } else if (s instanceof JButton && (JButton)s == sendButton) { - cc.writeClientCutText(textArea.getText(), textArea.getText().length()); + String text = textArea.getText(); + if (cc.viewer.sendClipboard.getValue()) + cc.writeClientCutText(text, text.length()); endDialog(); } else if (s instanceof JButton && (JButton)s == cancelButton) { endDialog(); |