comparison src/name/blackcap/imageprep/Menus.kt @ 0:e0efe7848130

Initial commit. Untested!
author David Barts <davidb@stashtea.com>
date Thu, 16 Jul 2020 19:57:23 -0700
parents
children 0bded24f746e
comparison
equal deleted inserted replaced
-1:000000000000 0:e0efe7848130
1 /*
2 * Menus.
3 */
4 package name.blackcap.imageprep
5
6 import java.awt.Graphics2D
7 import java.awt.RenderingHints
8 import java.awt.Window
9 import java.awt.event.ActionEvent
10 import java.awt.event.ActionListener
11 import java.awt.event.KeyEvent
12 import java.awt.image.BufferedImage
13 import java.io.File
14 import java.util.logging.Level
15 import java.util.logging.Logger
16 import javax.imageio.IIOImage
17 import javax.imageio.ImageIO
18 import javax.imageio.ImageWriteParam
19 import javax.imageio.ImageWriter
20 import javax.imageio.stream.ImageOutputStream
21 import javax.swing.*
22
23 /**
24 * Our menu bar. What we display depends somewhat on the system type, as
25 * the Mac gives us a gratuitous menu bar entry for handling some stuff.
26 */
27 class MyMenuBar: JMenuBar() {
28 init {
29 add(JMenu("File").apply {
30 add(JMenuItem("Open & Scale…").apply {
31 addActionListener(ActionListener { doOpen() })
32 makeShortcut(KeyEvent.VK_O)
33 })
34 add(JMenuItem("Discard").apply {
35 addActionListener(ActionListener { doDiscard() })
36 })
37 add(JMenuItem("Save & Close…").apply {
38 addActionListener(ActionListener { doClose() })
39 makeShortcut(KeyEvent.VK_S)
40 })
41 if (OS.type != OS.MAC) {
42 add(JMenuItem("Preferences…").apply {
43 addActionListener(ActionListener {
44 Application.settingsDialog.setVisible(true)
45 })
46 makeShortcut(KeyEvent.VK_COMMA)
47 })
48 add(JMenuItem("Quit").apply {
49 addActionListener(ActionListener {
50 LOGGER.log(Level.INFO, "execution complete")
51 System.exit(0)
52 })
53 makeShortcut(KeyEvent.VK_Q)
54 })
55 }
56 })
57 add(JMenu("Help").apply {
58 if (OS.type != OS.MAC) {
59 add(JMenuItem("About ${Application.MYNAME}…").apply {
60 addActionListener(ActionListener { showAboutDialog() })
61 })
62 }
63 add(JMenuItem("${Application.MYNAME} Help…").apply {
64 addActionListener(ActionListener { Application.helpDialog.setVisible(true) })
65 })
66 })
67 }
68
69 fun getMenu(name: String): JMenu? {
70 subElements.forEach {
71 val jmenu = it.component as? JMenu
72 if (jmenu?.text == name) {
73 return jmenu
74 }
75 }
76 return null
77 }
78
79 private fun doOpen() {
80 val chooser = JFileChooser().apply {
81 fileFilter = FileNameExtensionFilter("Image files", ImageIO.getReaderFileSuffixes())
82 }
83 if (chooser.showOpenDialog(Application.mainFrame) == JFileChooser.APPROVE_OPTION) {
84 RotateDialog.makeDialog(chooser.selectedFile)
85 }
86 }
87
88 private fun doDiscard() {
89 val w = FocusManager.currentManager.activeWindow as? RotateDialog
90 if (w == null) {
91 Toolkit.defaultToolkit.beep()
92 return
93 }
94 w.setVisible(false)
95 w.dispose()
96 }
97
98 private fun doClose() {
99 val w = FocusManager.currentManager.activeWindow as? RotateDialog
100 if (w == null) {
101 Toolkit.defaultToolkit.beep()
102 return
103 }
104 val outName = splitext(w.file.name).first + Settings.outputSuffix + ".jpg"
105 val chooser = JFileChooser(w).apply {
106 selectedFile = File(
107 if (Settings.outputToInputDir) w.file.parent else Settings.outputTo,
108 outName)
109 }
110 if (chooser.showOpenDialog(Application.mainFrame) != JFileChooser.APPROVE_OPTION) {
111 return
112 }
113 val (name, ext) = splitext(chooser.selectedFile.name)
114 val file = if (ext.toLowerCase() in setOf(".jpg", ".jpeg")) {
115 chooser.selectedFile
116 } else {
117 File(chooser.selectedFile.parent, name + ".jpg")
118 }
119 if (file.exists() && JOptionPane.showConfirmDialog(w, "File ${file.name} already exists. Overwrite?", "Confirm Overwrite", JOptionPane.YES_NO_OPTION) != JOptionPane.YES_OPTION) {
120 return
121 }
122 w.useWaitCursor()
123 swingWorker<IOException?> {
124 inBackground {
125 try {
126 val ios = ImageIO.createImageOutputStream(file)
127 val writer = ImageIO.getImageWritersByFormatName("jpeg").next()
128 val iwp = writer.getDefaultWriteParam().apply {
129 setCompressionMode(ImageWriteParam.MODE_EXPLICIT)
130 setCompressionQuality(Settings.outputQuality.toFloat() / 100.0f)
131 }
132 writer.setOutput(ios)
133 writer.write(null, IIOImage(w.image, null, null), iwp)
134 null
135 } catch (e: IOException) {
136 e
137 }
138 }
139 whenDone {
140 w.useNormalCursor()
141 val error = get()
142 if (error == null) {
143 w.setVisible(false)
144 w.dispose()
145 } else {
146 ioExceptionDialog(w, file, "write", e)
147 }
148 }
149 }
150 }
151
152 private fun splitext(s: String): Pair<String, String> {
153 val pos = s.lastIndexOf('.')
154 if (pos == -1) {
155 return Pair(s, "")
156 }
157 return Pair(s.substring(0, pos), s.substring(pos))
158 }
159 }
160
161 /**
162 * Show an About dialog.
163 */
164 fun showAboutDialog() {
165 JOptionPane.showMessageDialog(Application.mainFrame,
166 "\nImagePrep\n"
167 + "\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0© MMXX, David W. Barts\n",
168 "About ImagePrep",
169 JOptionPane.PLAIN_MESSAGE)
170 }