Mercurial > cgi-bin > hgweb.cgi > ClipMan
diff src/name/blackcap/clipman/SearchDialog.kt @ 27:8aa2dfac27eb
Big reorg; compiled but untested.
author | David Barts <n5jrn@me.com> |
---|---|
date | Wed, 29 Jan 2020 10:50:07 -0800 |
parents | |
children | f1fcc1281dad |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/name/blackcap/clipman/SearchDialog.kt Wed Jan 29 10:50:07 2020 -0800 @@ -0,0 +1,140 @@ +/* + * The dialog that controls a search. + */ +package name.blackcap.clipman + +import java.awt.Color +import java.awt.Toolkit +import java.awt.event.ActionEvent +import java.awt.event.ActionListener +import javax.swing.* +import javax.swing.border.* +import javax.swing.event.DocumentEvent +import javax.swing.event.DocumentListener + +class SearchDialog: JDialog(frame.v), ActionListener, DocumentListener { + /* the search term */ + private val _searchFor = JTextField(50).also { + it.border = LineBorder(Color.GRAY, 1) + it.horizontalAlignment = JTextField.LEFT + it.alignmentX = JTextField.LEFT_ALIGNMENT + it.text = "" + it.document.addDocumentListener(this) + } + val searchFor: String + get() { + return _searchFor.text + } + + /* whether or not we should ignore case */ + private val _ignoreCase = JCheckBox("Ignore case", true) + val ignoreCase: Boolean + get() { + return _ignoreCase.isSelected() + } + + /* whether or not searches should wrap around */ + private val _autoWrap = JCheckBox("Auto wrap", false) + val autoWrap: Boolean + get() { + return _autoWrap.isSelected() + } + + /* which direction to search */ + private val _forwards = JRadioButton("Forward", true) + private val _backwards = JRadioButton("Backward", false) + private val _direction = ButtonGroup().apply { + add(_forwards) + add(_backwards) + } + val direction: PasteboardQueue.Direction + get() { + if (_forwards.isSelected()) { + return PasteboardQueue.Direction.FORWARDS + } + if (_backwards.isSelected()) { + return PasteboardQueue.Direction.BACKWARDS + } + throw RuntimeException("impossible button state!") + } + + /* where to begin searching from. unlike the other properties, this + one is read/write. null means to start from the beginning on + forward searches, and from the end on backward searches (i.e. + search everything) */ + var origin: PasteboardQueue.Offset? = null + + private val _find = JButton("Find").also { + it.actionCommand = "Find" + it.addActionListener(this) + } + + /* initializer */ + init { + title = "Find" + contentPane.apply { + add(Box(BoxLayout.Y_AXIS).apply { + add(Box(BoxLayout.Y_AXIS).apply { + add(JLabel("Search for").apply { + horizontalAlignment = JLabel.LEFT + alignmentX = JLabel.LEFT_ALIGNMENT + }) + add(_searchFor) + }) + add(Box(BoxLayout.X_AXIS).apply { + add(Box(BoxLayout.Y_AXIS).apply { + add(_ignoreCase) + add(_autoWrap) + }) + add(Box(BoxLayout.Y_AXIS).apply { + add(_forwards) + add(_backwards) + }) + }) + add(_find) + }) + } + rootPane.setDefaultButton(_find) + } + + override fun actionPerformed(e: ActionEvent) { + if (e.actionCommand == "Find") { + setVisible(false) + find() + } + } + + override fun setVisible(visible: Boolean) { + if (visible) { + _searchFor.run { + requestFocusInWindow() + selectAll() + } + } + super.setVisible(visible) + } + + fun find(): Unit { + fun doFind(o: PasteboardQueue.Offset?) = queue.v.find(searchFor, + direction = direction, foldCase = ignoreCase, origin = o) + var result = doFind(origin) + if (result == null && origin != null && autoWrap) { + result = doFind(null) + } + if (result == null) { + Toolkit.getDefaultToolkit().beep() + } + origin = result + } + + /* changing the search string resets the search origin */ + override fun changedUpdate(e: DocumentEvent) { + if (e.document === _searchFor.document) { + origin = null + } + } + override fun insertUpdate(e: DocumentEvent) = changedUpdate(e) + override fun removeUpdate(e: DocumentEvent) = changedUpdate(e) +} + +val searchDialog = SearchDialog() \ No newline at end of file