Mercurial > cgi-bin > hgweb.cgi > ClipMan
annotate src/name/blackcap/clipman/Pasteboard.kt @ 1:fb224c3aebdf
Got it auto-scrolling to the bottom.
author | David Barts <n5jrn@me.com> |
---|---|
date | Sat, 18 Jan 2020 09:12:58 -0800 |
parents | be282c48010a |
children | 9dd58db4d15a |
rev | line source |
---|---|
0
be282c48010a
Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
1 /* |
be282c48010a
Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
2 * We call the clipboard a "pasteboard" for our internal class name, not |
be282c48010a
Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
3 * because I prefer that term (I don't) but so as to not clash with the |
be282c48010a
Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
4 * AWT's Clipboard class. |
be282c48010a
Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
5 */ |
be282c48010a
Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
6 package name.blackcap.clipman |
be282c48010a
Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
7 |
be282c48010a
Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
8 import java.awt.Toolkit |
be282c48010a
Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
9 import java.awt.datatransfer.Clipboard |
be282c48010a
Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
10 import java.awt.datatransfer.ClipboardOwner |
be282c48010a
Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
11 import java.awt.datatransfer.DataFlavor |
be282c48010a
Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
12 import java.awt.datatransfer.Transferable |
be282c48010a
Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
13 import java.awt.datatransfer.UnsupportedFlavorException |
be282c48010a
Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
14 import java.io.IOException |
be282c48010a
Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
15 import java.io.InputStream |
be282c48010a
Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
16 import java.nio.charset.Charset |
be282c48010a
Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
17 import java.util.logging.Level |
be282c48010a
Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
18 import java.util.logging.Logger |
be282c48010a
Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
19 import kotlin.collections.HashMap |
be282c48010a
Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
20 |
be282c48010a
Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
21 /* Constants, etc. */ |
be282c48010a
Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
22 val CHARSET_NAME = "UTF-8" |
be282c48010a
Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
23 |
be282c48010a
Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
24 /* |
be282c48010a
Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
25 * Represents an error dealing with pasteboard items. |
be282c48010a
Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
26 */ |
be282c48010a
Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
27 class PasteboardError(): Exception() |
be282c48010a
Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
28 |
be282c48010a
Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
29 /** |
be282c48010a
Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
30 * Represents an item of data in the clipboard and how to read and |
be282c48010a
Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
31 * write it. |
be282c48010a
Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
32 */ |
be282c48010a
Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
33 sealed class PasteboardItem { |
be282c48010a
Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
34 data class Plain(val plain: String): PasteboardItem() |
be282c48010a
Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
35 data class HTML(val plain: String, val html: String): PasteboardItem() |
be282c48010a
Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
36 |
be282c48010a
Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
37 private class PasteboardData(val item: PasteboardItem): |
be282c48010a
Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
38 Transferable, ClipboardOwner { |
be282c48010a
Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
39 private val CHARSET = Charset.forName(CHARSET_NAME) |
be282c48010a
Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
40 private val HTML_FLAVOR = DataFlavor("text/html; document=all; class=\"[B\"; charset=" + CHARSET_NAME) |
be282c48010a
Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
41 private val _data: HashMap<DataFlavor, Any> |
be282c48010a
Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
42 private val flavors: Array<DataFlavor> |
be282c48010a
Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
43 |
be282c48010a
Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
44 init { |
be282c48010a
Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
45 _data = HashMap<DataFlavor, Any>().apply { |
be282c48010a
Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
46 when (item) { |
be282c48010a
Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
47 is Plain -> put(DataFlavor.stringFlavor, item.plain as Any) |
be282c48010a
Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
48 is HTML -> { |
be282c48010a
Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
49 put(DataFlavor.stringFlavor, item.plain as Any) |
be282c48010a
Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
50 put(HTML_FLAVOR, item.html as Any) |
be282c48010a
Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
51 } |
be282c48010a
Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
52 } |
be282c48010a
Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
53 } |
be282c48010a
Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
54 _data.keys.asIterable().run { |
be282c48010a
Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
55 flavors = Array<DataFlavor>(count()) { elementAt(it) } |
be282c48010a
Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
56 } |
be282c48010a
Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
57 } |
be282c48010a
Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
58 |
be282c48010a
Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
59 override fun getTransferData(flavor: DataFlavor): Any { |
be282c48010a
Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
60 return _data.get(flavor) ?: throw UnsupportedFlavorException(flavor) |
be282c48010a
Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
61 } |
be282c48010a
Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
62 |
be282c48010a
Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
63 override fun getTransferDataFlavors(): Array<DataFlavor> = flavors |
be282c48010a
Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
64 override fun isDataFlavorSupported(flavor: DataFlavor) = _data.containsKey(flavor) |
be282c48010a
Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
65 override fun lostOwnership(clipboard: Clipboard, contents: Transferable) {} |
be282c48010a
Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
66 } |
be282c48010a
Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
67 |
be282c48010a
Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
68 companion object { |
be282c48010a
Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
69 private val CLIPBOARD = Toolkit.getDefaultToolkit().systemClipboard |
be282c48010a
Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
70 |
be282c48010a
Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
71 /** |
be282c48010a
Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
72 * Read the item in the pasteboard. |
be282c48010a
Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
73 * @return a PasteboardItem? object, null if nothing could be read |
be282c48010a
Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
74 */ |
be282c48010a
Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
75 fun read() : PasteboardItem? { |
be282c48010a
Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
76 check() |
be282c48010a
Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
77 var plain = getClipboardData(DataFlavor.stringFlavor) |
be282c48010a
Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
78 if (plain == null) { |
be282c48010a
Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
79 return null |
be282c48010a
Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
80 } |
be282c48010a
Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
81 var html = getClipboardData(DataFlavor.allHtmlFlavor) |
be282c48010a
Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
82 if (html == null) { |
be282c48010a
Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
83 html = htmlFromRTF() |
be282c48010a
Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
84 } |
be282c48010a
Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
85 return if (html == null) { Plain(plain) } else { HTML(plain, html) } |
be282c48010a
Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
86 } |
be282c48010a
Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
87 |
be282c48010a
Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
88 /** |
be282c48010a
Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
89 * Write an item to the pasteboard. |
be282c48010a
Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
90 * @param item a PasteboardItem to write |
be282c48010a
Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
91 */ |
be282c48010a
Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
92 fun write(item: PasteboardItem) { |
be282c48010a
Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
93 check() |
be282c48010a
Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
94 val pbdata = PasteboardData(item) |
be282c48010a
Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
95 CLIPBOARD.setContents(pbdata, pbdata) |
be282c48010a
Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
96 } |
be282c48010a
Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
97 |
be282c48010a
Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
98 private fun check() { |
be282c48010a
Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
99 if (CLIPBOARD == null) { |
be282c48010a
Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
100 throw RuntimeException("no clipboard available!") |
be282c48010a
Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
101 } |
be282c48010a
Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
102 } |
be282c48010a
Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
103 |
be282c48010a
Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
104 private fun getClipboardData(flavor: DataFlavor): String? { |
be282c48010a
Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
105 try { |
be282c48010a
Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
106 return CLIPBOARD.getData(flavor) as String? |
be282c48010a
Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
107 } catch (e: IOException) { |
be282c48010a
Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
108 return null |
be282c48010a
Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
109 } catch (e: UnsupportedFlavorException) { |
be282c48010a
Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
110 return null |
be282c48010a
Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
111 } |
be282c48010a
Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
112 } |
be282c48010a
Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
113 |
be282c48010a
Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
114 private fun htmlFromRTF(): String? { |
be282c48010a
Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
115 /* see if there's an appropriate flavor */ |
be282c48010a
Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
116 var rtf: DataFlavor? = null |
be282c48010a
Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
117 for (flavor in CLIPBOARD.availableDataFlavors) { |
be282c48010a
Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
118 if (flavor.isRepresentationClassInputStream() && |
be282c48010a
Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
119 "text".equals(flavor.primaryType ?: "", ignoreCase=true) && |
be282c48010a
Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
120 "rtf".equals(flavor.subType ?: "", ignoreCase=true)) { |
be282c48010a
Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
121 rtf = flavor |
be282c48010a
Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
122 break |
be282c48010a
Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
123 } |
be282c48010a
Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
124 } |
be282c48010a
Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
125 if (rtf == null) { |
be282c48010a
Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
126 return null |
be282c48010a
Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
127 } |
be282c48010a
Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
128 |
be282c48010a
Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
129 (CLIPBOARD.getData(rtf) as InputStream).use { |
be282c48010a
Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
130 val (html, errors) = rtfToHtml(it) |
be282c48010a
Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
131 if (errors != null) { |
be282c48010a
Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
132 LOGGER.log(Level.WARNING, errors) |
be282c48010a
Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
133 return null |
be282c48010a
Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
134 } |
be282c48010a
Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
135 return html |
be282c48010a
Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
136 } |
be282c48010a
Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
137 } |
be282c48010a
Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
138 } |
be282c48010a
Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
139 } |