view src/name/blackcap/clipman/Menus.kt @ 66:a8b04aa874e3
Update copyright date in about pane.
author |
David Barts <n5jrn@me.com> |
date |
Sun, 12 Jan 2025 12:13:20 -0800 (10 days ago) |
parents |
c56a0747c256 |
children |
|
line source
/*
* Menu-related stuff, pertaining to both the menu bar and popup menus.
*/
package name.blackcap.clipman
import java.awt.Container
import java.awt.Toolkit
import java.awt.event.ActionEvent
import java.awt.event.ActionListener
import java.awt.event.KeyEvent
import java.util.logging.Level
import java.util.logging.Logger
import javax.swing.*
import kotlin.collections.HashSet
/**
* Listen to actionEvents from both menu bar and popup menu selections.
*/
class MenuItemListener: ActionListener {
override fun actionPerformed(e: ActionEvent) {
when (e.actionCommand) {
"File.Quit" -> {
LOGGER.log(Level.INFO, "execution complete")
System.exit(0)
}
"File.Preferences" -> Application.settingsDialog.setVisible(true)
"Edit.Clone" -> onlyIfSelected { PasteboardItem.write(it.contents) }
"Edit.Coerce" -> onlyIfSelected { Application.coerceDialog.setVisible(true) }
"Edit.Find" -> Application.searchDialog.setVisible(true)
"Edit.FindAgain" -> Application.searchDialog.find()
"Edit.Plain" -> onlyIfSelected { if (suitedForCoercing(it)) { makePlain(it.contents) } }
"Edit.Troff" -> onlyIfSelected { if (suitedForCoercing(it)) { troffize(it.contents) } }
"Help.About" -> showAboutDialog()
else -> throw RuntimeException("unexpected actionCommand!")
}
}
private fun onlyIfSelected(block: (QueueItem) -> Unit) {
val selected = Application.queue.getSelected()
if (selected == null) {
JOptionPane.showMessageDialog(Application.frame,
"No item selected.",
"Error",
JOptionPane.ERROR_MESSAGE)
} else {
block(selected)
}
}
}
/**
* Track menu items that require something to be selected in order
* to work, and allow them to be enabled and disabled en masse.
*/
class SelectionRequired {
private val controls = HashSet<JMenuItem>()
fun add(item: JMenuItem): JMenuItem {
controls.add(item)
return item
}
private fun setEnabled(state: Boolean) {
controls.forEach {
it.setEnabled(state)
}
}
fun enable() = setEnabled(true)
fun disable() = setEnabled(false)
}
/**
* Our menu bar. What we display depends somewhat on the system type, as
* the Mac gives us a gratuitous menu bar entry for handling some stuff.
*/
class MyMenuBar: JMenuBar() {
init {
if (OS.type != OS.MAC) {
add(JMenu("File").apply {
add(JMenuItem("Quit").apply {
actionCommand = "File.Quit"
addActionListener(Application.menuItemListener)
makeShortcut(KeyEvent.VK_Q)
})
add(JMenuItem("Preferences…").apply {
actionCommand = "File.Preferences"
addActionListener(Application.menuItemListener)
makeShortcut(KeyEvent.VK_COMMA)
})
})
}
add(JMenu("Edit").apply {
add(Application.anyRequired.add(JMenuItem("Clone").apply {
setEnabled(false)
actionCommand = "Edit.Clone"
addActionListener(Application.menuItemListener)
makeShortcut(KeyEvent.VK_C)
}))
add(Application.styledRequired.add(JMenuItem("Coerce…").apply {
setEnabled(false)
actionCommand = "Edit.Coerce"
addActionListener(Application.menuItemListener)
makeShortcut(KeyEvent.VK_K)
}))
add(Application.styledRequired.add(JMenuItem("Convert to Troff").apply {
setEnabled(false)
actionCommand = "Edit.Troff"
addActionListener(Application.menuItemListener)
makeShortcut(KeyEvent.VK_T)
}))
add(Application.styledRequired.add(JMenuItem("Make Plain").apply {
setEnabled(false)
actionCommand = "Edit.Plain"
addActionListener(Application.menuItemListener)
makeShortcut(KeyEvent.VK_P)
}))
add(JMenuItem("Find…").apply {
actionCommand = "Edit.Find"
addActionListener(Application.menuItemListener)
makeShortcut(KeyEvent.VK_F)
})
add(JMenuItem("Find Again").apply {
actionCommand = "Edit.FindAgain"
addActionListener(Application.menuItemListener)
makeShortcut(KeyEvent.VK_G)
})
})
if (OS.type != OS.MAC) {
add(JMenu("Help").apply {
add(JMenuItem("About ClipMan…").apply {
actionCommand = "Help.About"
addActionListener(Application.menuItemListener)
})
})
}
}
fun getMenu(name: String): JMenu? {
subElements.forEach {
val jmenu = it.component as? JMenu
if (jmenu?.text == name) {
return jmenu
}
}
return null
}
}
/**
* The popup menu we display when the user requests so atop a clipboard
* item.
*/
class MyPopupMenu: JPopupMenu() {
init {
add(Application.anyRequired.add(JMenuItem("Clone").apply {
actionCommand = "Edit.Clone"
addActionListener(Application.menuItemListener)
}))
add(Application.styledRequired.add(JMenuItem("Convert to Troff").apply {
actionCommand = "Edit.Troff"
addActionListener(Application.menuItemListener)
}))
add(Application.styledRequired.add(JMenuItem("Make Plain").apply {
actionCommand = "Edit.Plain"
addActionListener(Application.menuItemListener)
}))
add(Application.styledRequired.add(JMenuItem("Coerce…").apply {
actionCommand = "Edit.Coerce"
addActionListener(Application.menuItemListener)
}))
}
}
fun makePlain(item: PasteboardItem): Unit {
val plain = when (item) {
is PasteboardItem.Plain ->
item.plain
is PasteboardItem.HTML ->
item.plain
is PasteboardItem.RTF ->
item.plain
}
PasteboardItem.write(PasteboardItem.Plain(plain))
}
/**
* Show an About dialog.
*/
fun showAboutDialog() {
JOptionPane.showMessageDialog(Application.frame,
"ClipMan, a clipboard manager.\n"
+ "© MMXXV, David W. Barts",
"About ClipMan",
JOptionPane.PLAIN_MESSAGE)
}