Mercurial > cgi-bin > hgweb.cgi > ClipMan
comparison src/name/blackcap/clipman/Main.kt @ 13:fe0fcfc8b2aa
Braindead POS wasn't honoring <style> tags; fixed that.
author | David Barts <n5jrn@me.com> |
---|---|
date | Mon, 20 Jan 2020 21:53:15 -0800 |
parents | 0fb6da371b80 |
children | 0cd912d29184 |
comparison
equal
deleted
inserted
replaced
12:0fb6da371b80 | 13:fe0fcfc8b2aa |
---|---|
11 import java.awt.Toolkit; | 11 import java.awt.Toolkit; |
12 import java.awt.datatransfer.* | 12 import java.awt.datatransfer.* |
13 import java.awt.event.WindowEvent | 13 import java.awt.event.WindowEvent |
14 import java.awt.event.WindowListener | 14 import java.awt.event.WindowListener |
15 import java.util.Date | 15 import java.util.Date |
16 import java.util.concurrent.Semaphore | |
16 import java.util.logging.Level | 17 import java.util.logging.Level |
17 import java.util.logging.Logger | 18 import java.util.logging.Logger |
18 import java.util.concurrent.Semaphore | |
19 import javax.swing.* | 19 import javax.swing.* |
20 import javax.swing.border.* | 20 import javax.swing.border.* |
21 import javax.swing.text.JTextComponent | 21 import javax.swing.text.JTextComponent |
22 import javax.swing.text.html.StyleSheet | |
23 import javax.swing.text.html.HTMLEditorKit | |
22 import kotlin.concurrent.thread | 24 import kotlin.concurrent.thread |
23 import org.jsoup.Jsoup | 25 import org.jsoup.Jsoup |
24 import org.jsoup.nodes.* | 26 import org.jsoup.nodes.* |
25 | 27 |
26 /* name we call ourselves */ | 28 /* name we call ourselves */ |
34 val PANEL_BORDER = 9 | 36 val PANEL_BORDER = 9 |
35 val OUTER_BORDER_TOP = 3 | 37 val OUTER_BORDER_TOP = 3 |
36 val OUTER_BORDER = 9 | 38 val OUTER_BORDER = 9 |
37 val INNER_BORDER = 1 | 39 val INNER_BORDER = 1 |
38 val MARGIN_BORDER = 3 | 40 val MARGIN_BORDER = 3 |
41 | |
42 /* default font sizes in the text-display panes */ | |
43 val MONO_SIZE = 14 | |
44 val PROP_SIZE = 16 | |
39 | 45 |
40 /* kills the updating thread (and does a system exit) when needed */ | 46 /* kills the updating thread (and does a system exit) when needed */ |
41 class KillIt(val thr: Thread) : WindowListener { | 47 class KillIt(val thr: Thread) : WindowListener { |
42 // events we don't care about | 48 // events we don't care about |
43 override fun windowActivated(e: WindowEvent) {} | 49 override fun windowActivated(e: WindowEvent) {} |
78 if (enabled) { | 84 if (enabled) { |
79 var contents = PasteboardItem.read() | 85 var contents = PasteboardItem.read() |
80 if (contents != null) { | 86 if (contents != null) { |
81 newContents = when (contents) { | 87 newContents = when (contents) { |
82 is PasteboardItem.Plain -> contents.plain | 88 is PasteboardItem.Plain -> contents.plain |
83 is PasteboardItem.HTML -> contents.plain | 89 is PasteboardItem.HTML -> contents.html |
84 } | 90 } |
85 if (oldContents != newContents) { | 91 if (oldContents != newContents) { |
86 var stdWidth: Int? = null | 92 var stdWidth: Int? = null |
87 inSynSwingThread { | 93 inSynSwingThread { |
88 stdWidth = queue.parent.size.width - 2 * (PANEL_BORDER+OUTER_BORDER+INNER_BORDER+MARGIN_BORDER) | 94 stdWidth = queue.parent.size.width - 2 * (PANEL_BORDER+OUTER_BORDER+INNER_BORDER+MARGIN_BORDER) |
96 is PasteboardItem.Plain -> widget.run { | 102 is PasteboardItem.Plain -> widget.run { |
97 add(stdLabel("Plain text")) | 103 add(stdLabel("Plain text")) |
98 add(ClipText().apply { | 104 add(ClipText().apply { |
99 contentType = "text/plain" | 105 contentType = "text/plain" |
100 text = contents.plain | 106 text = contents.plain |
101 font = Font(Font.MONOSPACED, Font.PLAIN, 14) | 107 font = Font(Font.MONOSPACED, Font.PLAIN, MONO_SIZE) |
102 border = stdBorder | 108 border = stdBorder |
103 autoSize(stdWidth!!) | 109 autoSize(stdWidth!!) |
104 setEditable(false) | 110 setEditable(false) |
105 alignmentX = JTextPane.LEFT_ALIGNMENT | 111 alignmentX = JTextPane.LEFT_ALIGNMENT |
106 }) | 112 }) |
107 } | 113 } |
108 is PasteboardItem.HTML -> widget.run { | 114 is PasteboardItem.HTML -> widget.run { |
109 add(stdLabel("Styled text")) | 115 add(stdLabel("Styled text")) |
116 val (html, style) = preproc(contents.html) | |
117 val hek = HTMLEditorKit().apply { | |
118 styleSheet = style | |
119 } | |
110 add(ClipText().apply { | 120 add(ClipText().apply { |
111 contentType = "text/html" | 121 editorKit = hek |
112 text = scrub(contents.html) | 122 text = html |
113 border = stdBorder | 123 border = stdBorder |
114 autoSize(stdWidth!!) | 124 autoSize(stdWidth!!) |
115 setEditable(false) | 125 setEditable(false) |
116 alignmentX = JTextPane.LEFT_ALIGNMENT | 126 alignmentX = JTextPane.LEFT_ALIGNMENT |
117 }) | 127 }) |
136 private fun stdLabel(text: String) = JLabel(text).apply { | 146 private fun stdLabel(text: String) = JLabel(text).apply { |
137 horizontalAlignment = JLabel.LEFT | 147 horizontalAlignment = JLabel.LEFT |
138 alignmentX = JLabel.LEFT_ALIGNMENT | 148 alignmentX = JLabel.LEFT_ALIGNMENT |
139 } | 149 } |
140 | 150 |
141 private fun scrub(html: String): String { | 151 private fun preproc(html: String): Pair<String, StyleSheet> { |
142 return Jsoup.parse(html).run { | 152 val sty = StyleSheet().apply { |
153 addRule("html { font-family: serif; font-size: %d; }".format(PROP_SIZE)) | |
154 addRule("code, kbd, pre, samp { font-family: monospace; font-size: %d; }".format(MONO_SIZE)) | |
155 } | |
156 val scrubbed = Jsoup.parse(html).run { | |
157 select("style").forEach { | |
158 it.dataNodes().forEach { sty.addRule(it.wholeData) } | |
159 } | |
143 select(":root>head>meta").remove() | 160 select(":root>head>meta").remove() |
144 outputSettings() | 161 outputSettings() |
145 .charset(CHARSET_NAME) | 162 .charset(CHARSET_NAME) |
146 .syntax(Document.OutputSettings.Syntax.xml) | 163 .syntax(Document.OutputSettings.Syntax.xml) |
147 outerHtml() | 164 outerHtml() |
148 } | 165 } |
166 return Pair(scrubbed, sty) | |
149 } | 167 } |
150 } | 168 } |
151 | 169 |
152 fun main(args: Array<String>) { | 170 fun main(args: Array<String>) { |
153 LOGGER.log(Level.INFO, "beginning execution") | 171 LOGGER.log(Level.INFO, "beginning execution") |