aboutsummaryrefslogtreecommitdiffstats
path: root/java/com/tigervnc/vncviewer/ClipboardDialog.java
diff options
context:
space:
mode:
Diffstat (limited to 'java/com/tigervnc/vncviewer/ClipboardDialog.java')
-rw-r--r--java/com/tigervnc/vncviewer/ClipboardDialog.java122
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();