Mercurial > cgi-bin > hgweb.cgi > ClipMan
view src/name/blackcap/clipman/PasteboardQueue.kt @ 21:c10a447b9e1b
Add some searching hooks.
author | David Barts <n5jrn@me.com> |
---|---|
date | Thu, 23 Jan 2020 00:02:07 -0800 |
parents | 88703ca72fc3 |
children | 8aa2dfac27eb |
line wrap: on
line source
/* * The queue of pasteboard items we manage. New stuff gets added to the * tail, and old stuff truncated off the head. */ package name.blackcap.clipman import java.awt.Container import java.awt.Rectangle import java.util.Collections import java.util.LinkedList import java.util.logging.Level import java.util.logging.Logger import javax.swing.* import javax.swing.text.JTextComponent /** * A queue that tracks the data we display and the widgets used to * display them. We never explicitly remove stuff from the queue, * though items will get silently discarded to prevent the queue from * exceeding the specified maximum size. */ class PasteboardQueue(val parent: Container, maxSize: Int) { private val queue = LinkedList<QueueItem>() private var _maxSize = maxSize private var scrollPane: JScrollPane? = null init { var sp: Container? = parent while (sp != null) { if (sp is JScrollPane) { scrollPane = sp break } sp = sp.parent } } data class Offset(var inQueue: Int, var inItem: Int) enum class Direction { FORWARDS, BACKWARDS } /** * The maximum allowed size of this queue. Attempts to make the queue * larger than this size, or specifying a size smaller than the current * size, will result in the oldest item(s) being discarded. A size less * than or equal to zero means an unlimited size. */ var maxSize: Int get() { return _maxSize } @Synchronized set(value) { _maxSize = value truncate() } /** * Add a QueueItem to the end of the queue. * @param item QueueItem to add */ @Synchronized fun add(item: QueueItem) { inSwingThread { parent.add(item.component) scrollPane?.run { validate() verticalScrollBar.run { value = maximum + 1 } } } queue.addLast(item) truncate() } /** * Find and highlight the next occurrence of the specified string * @param string to search * @param whether to search backwards (default forwards) * @param case-folding flag (default true) * @param starting point (0, 0) for forwards, (m, n) for backwards * @return position where start of string was found, or null */ fun find(needle: String, direction: Direction = Direction.FORWARDS, foldCase: Boolean = true, origin: Offset? = null): Offset? { /* canonicalize the origin */ val norigin = if (origin == null) { if (direction == Direction.FORWARDS) { Offset(0, 0) } else { Offset(queue.size - 1, queue.last.searchable.document.length) } } else { origin } /* XXX - not finished */ return null } private fun truncate() { if (_maxSize > 0) { var size = queue.size var dirty = false while (size > _maxSize) { var extra = queue.removeFirst().component inSwingThread { parent.remove(extra) } dirty = true size -= 1 } if (dirty) { inSwingThread { parent.validate() } } } } } /** * An item in the above queue. */ data class QueueItem( val component: JComponent, val searchable: JTextComponent, val contents: PasteboardItem)