annotate src/name/blackcap/clipman/Main.kt @ 3:70caa73e32f7

Stop it from spinning on non-textual clipboard data.
author David Barts <n5jrn@me.com>
date Sat, 18 Jan 2020 11:13:27 -0800
parents be282c48010a
children debe0413280f
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
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 * The entry point and most of the view logic is here.
be282c48010a Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff changeset
3 */
be282c48010a Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff changeset
4 package name.blackcap.clipman
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 import java.awt.BorderLayout
be282c48010a Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff changeset
7 import java.awt.Color
be282c48010a Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff changeset
8 import java.awt.Container
be282c48010a Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff changeset
9 import java.awt.Dimension
be282c48010a Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff changeset
10 import java.awt.Font
be282c48010a Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff changeset
11 import java.awt.Toolkit;
be282c48010a Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff changeset
12 import java.awt.datatransfer.*
be282c48010a Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff changeset
13 import java.awt.event.WindowEvent
be282c48010a Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff changeset
14 import java.awt.event.WindowListener
be282c48010a Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff changeset
15 import java.util.Date
be282c48010a Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff changeset
16 import java.util.logging.Level
be282c48010a Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff changeset
17 import java.util.logging.Logger
be282c48010a Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff changeset
18 import javax.swing.*
be282c48010a Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff changeset
19 import javax.swing.border.CompoundBorder
be282c48010a Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff changeset
20 import javax.swing.border.EmptyBorder
be282c48010a Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff changeset
21 import javax.swing.border.LineBorder
be282c48010a Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff changeset
22 import javax.swing.text.JTextComponent
be282c48010a Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff changeset
23 import kotlin.concurrent.thread
be282c48010a Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff changeset
24 import org.jsoup.Jsoup
be282c48010a Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff changeset
25 import org.jsoup.nodes.*
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
be282c48010a Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff changeset
28 /* kills the updating thread (and does a system exit) when needed */
be282c48010a Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff changeset
29 class KillIt(val thr: Thread) : WindowListener {
be282c48010a Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff changeset
30 // events we don't care about
be282c48010a Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff changeset
31 override fun windowActivated(e: WindowEvent) {}
be282c48010a Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff changeset
32 override fun windowClosed(e: WindowEvent) {}
be282c48010a Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff changeset
33 override fun windowDeactivated(e: WindowEvent) {}
be282c48010a Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff changeset
34 override fun windowDeiconified(e: WindowEvent) {}
be282c48010a Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff changeset
35 override fun windowIconified(e: WindowEvent) {}
be282c48010a Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff changeset
36 override fun windowOpened(e: WindowEvent) {}
be282c48010a Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff changeset
37
be282c48010a Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff changeset
38 // and the one we do
be282c48010a Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff changeset
39 override fun windowClosing(e: WindowEvent) {
be282c48010a Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff changeset
40 thr.run { interrupt(); join() }
be282c48010a Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff changeset
41 System.exit(0)
be282c48010a Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff changeset
42 }
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
be282c48010a Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff changeset
45 /* the updating thread */
be282c48010a Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff changeset
46 class UpdateIt(val queue: PasteboardQueue, val interval: Int): Thread() {
be282c48010a Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff changeset
47 @Volatile var enabled = true
be282c48010a Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff changeset
48 private val stdBorder =
be282c48010a Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff changeset
49 CompoundBorder(EmptyBorder(5, 10, 5, 10), LineBorder(Color.GRAY, 1))
be282c48010a Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff changeset
50
be282c48010a Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff changeset
51 override fun run() {
be282c48010a Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff changeset
52 var oldContents = ""
be282c48010a Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff changeset
53 var newContents = ""
be282c48010a Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff changeset
54 while (true) {
be282c48010a Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff changeset
55 if (enabled) {
be282c48010a Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff changeset
56 var contents = PasteboardItem.read()
3
70caa73e32f7 Stop it from spinning on non-textual clipboard data.
David Barts <n5jrn@me.com>
parents: 0
diff changeset
57 if (contents != null) {
70caa73e32f7 Stop it from spinning on non-textual clipboard data.
David Barts <n5jrn@me.com>
parents: 0
diff changeset
58 newContents = when (contents) {
70caa73e32f7 Stop it from spinning on non-textual clipboard data.
David Barts <n5jrn@me.com>
parents: 0
diff changeset
59 is PasteboardItem.Plain -> contents.plain
70caa73e32f7 Stop it from spinning on non-textual clipboard data.
David Barts <n5jrn@me.com>
parents: 0
diff changeset
60 is PasteboardItem.HTML -> contents.plain
70caa73e32f7 Stop it from spinning on non-textual clipboard data.
David Barts <n5jrn@me.com>
parents: 0
diff changeset
61 }
70caa73e32f7 Stop it from spinning on non-textual clipboard data.
David Barts <n5jrn@me.com>
parents: 0
diff changeset
62 if (oldContents != newContents) {
70caa73e32f7 Stop it from spinning on non-textual clipboard data.
David Barts <n5jrn@me.com>
parents: 0
diff changeset
63 var widget: JComponent = when(contents) {
70caa73e32f7 Stop it from spinning on non-textual clipboard data.
David Barts <n5jrn@me.com>
parents: 0
diff changeset
64 is PasteboardItem.Plain -> JTextPane().apply {
70caa73e32f7 Stop it from spinning on non-textual clipboard data.
David Barts <n5jrn@me.com>
parents: 0
diff changeset
65 contentType = "text/plain"
70caa73e32f7 Stop it from spinning on non-textual clipboard data.
David Barts <n5jrn@me.com>
parents: 0
diff changeset
66 toolTipText = "Plain text"
70caa73e32f7 Stop it from spinning on non-textual clipboard data.
David Barts <n5jrn@me.com>
parents: 0
diff changeset
67 text = contents.plain
70caa73e32f7 Stop it from spinning on non-textual clipboard data.
David Barts <n5jrn@me.com>
parents: 0
diff changeset
68 font = Font(Font.MONOSPACED, Font.PLAIN, 14)
70caa73e32f7 Stop it from spinning on non-textual clipboard data.
David Barts <n5jrn@me.com>
parents: 0
diff changeset
69 border = stdBorder
70caa73e32f7 Stop it from spinning on non-textual clipboard data.
David Barts <n5jrn@me.com>
parents: 0
diff changeset
70 autoSize(600)
70caa73e32f7 Stop it from spinning on non-textual clipboard data.
David Barts <n5jrn@me.com>
parents: 0
diff changeset
71 setEditable(false)
70caa73e32f7 Stop it from spinning on non-textual clipboard data.
David Barts <n5jrn@me.com>
parents: 0
diff changeset
72 }
70caa73e32f7 Stop it from spinning on non-textual clipboard data.
David Barts <n5jrn@me.com>
parents: 0
diff changeset
73 is PasteboardItem.HTML -> JTextPane().apply {
70caa73e32f7 Stop it from spinning on non-textual clipboard data.
David Barts <n5jrn@me.com>
parents: 0
diff changeset
74 contentType = "text/html"
70caa73e32f7 Stop it from spinning on non-textual clipboard data.
David Barts <n5jrn@me.com>
parents: 0
diff changeset
75 toolTipText = "Styled text"
70caa73e32f7 Stop it from spinning on non-textual clipboard data.
David Barts <n5jrn@me.com>
parents: 0
diff changeset
76 text = scrub(contents.html)
70caa73e32f7 Stop it from spinning on non-textual clipboard data.
David Barts <n5jrn@me.com>
parents: 0
diff changeset
77 border = stdBorder
70caa73e32f7 Stop it from spinning on non-textual clipboard data.
David Barts <n5jrn@me.com>
parents: 0
diff changeset
78 autoSize(600)
70caa73e32f7 Stop it from spinning on non-textual clipboard data.
David Barts <n5jrn@me.com>
parents: 0
diff changeset
79 setEditable(false)
70caa73e32f7 Stop it from spinning on non-textual clipboard data.
David Barts <n5jrn@me.com>
parents: 0
diff changeset
80 }
0
be282c48010a Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff changeset
81 }
3
70caa73e32f7 Stop it from spinning on non-textual clipboard data.
David Barts <n5jrn@me.com>
parents: 0
diff changeset
82 queue.add(QueueItem(widget, contents))
70caa73e32f7 Stop it from spinning on non-textual clipboard data.
David Barts <n5jrn@me.com>
parents: 0
diff changeset
83 oldContents = newContents
0
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 }
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 if (Thread.interrupted()) {
be282c48010a Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff changeset
88 return
be282c48010a Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff changeset
89 }
be282c48010a Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff changeset
90 try {
be282c48010a Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff changeset
91 Thread.sleep(interval - System.currentTimeMillis() % interval)
be282c48010a Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff changeset
92 } catch (e: InterruptedException) {
be282c48010a Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff changeset
93 return
be282c48010a Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff changeset
94 }
be282c48010a Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff changeset
95 }
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 scrub(html: String): String {
be282c48010a Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff changeset
99 return Jsoup.parse(html).run {
be282c48010a Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff changeset
100 select(":root>head>meta").remove()
be282c48010a Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff changeset
101 outputSettings()
be282c48010a Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff changeset
102 .charset(CHARSET_NAME)
be282c48010a Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff changeset
103 .syntax(Document.OutputSettings.Syntax.xml)
be282c48010a Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff changeset
104 outerHtml()
be282c48010a Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff changeset
105 }
be282c48010a Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff changeset
106 }
be282c48010a Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff changeset
107 }
be282c48010a Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff changeset
108
be282c48010a Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff changeset
109 fun main(args: Array<String>) {
be282c48010a Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff changeset
110 LOGGER.log(Level.INFO, "beginning execution")
be282c48010a Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff changeset
111 val con = Container().apply {
be282c48010a Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff changeset
112 layout = BoxLayout(this, BoxLayout.Y_AXIS)
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 var frame: JFrame? = null
be282c48010a Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff changeset
115 inSwingThread {
be282c48010a Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff changeset
116 frame = JFrame("ClipMan").apply {
be282c48010a Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff changeset
117 preferredSize = Dimension(640, 480)
be282c48010a Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff changeset
118 contentPane.add(
be282c48010a Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff changeset
119 JScrollPane(con).apply {
be282c48010a Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff changeset
120 verticalScrollBarPolicy = ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED
be282c48010a Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff changeset
121 horizontalScrollBarPolicy = ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER
be282c48010a Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff changeset
122 preferredSize = Dimension(640, 480)
be282c48010a Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff changeset
123 }, BorderLayout.CENTER)
be282c48010a Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff changeset
124 pack()
be282c48010a Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff changeset
125 setVisible(true)
be282c48010a Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff changeset
126 }
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 val queue = PasteboardQueue(con, 10)
be282c48010a Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff changeset
129 val updater = UpdateIt(queue, 1000).apply { start() }
be282c48010a Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff changeset
130 inSwingThread { frame?.addWindowListener(KillIt(updater)) }
be282c48010a Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff changeset
131 LOGGER.log(Level.INFO, "execution complete")
be282c48010a Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff changeset
132 }
be282c48010a Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff changeset
133
be282c48010a Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff changeset
134 fun inSwingThread(block: () -> Unit) {
be282c48010a Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff changeset
135 SwingUtilities.invokeLater(Runnable(block))
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 fun JTextComponent.autoSize(width: Int): Unit {
be282c48010a Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff changeset
139 val SLOP = 10
be282c48010a Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff changeset
140 val dim = Dimension(width, width)
be282c48010a Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff changeset
141 preferredSize = dim
be282c48010a Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff changeset
142 size = dim
be282c48010a Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff changeset
143 val r = modelToView(document.length)
be282c48010a Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff changeset
144 preferredSize = Dimension(width, r.y + r.height + SLOP)
be282c48010a Incomplete; checking it in as a backup.
David Barts <n5jrn@me.com>
parents:
diff changeset
145 }