Mercurial > cgi-bin > hgweb.cgi > ImagePrep
annotate src/name/blackcap/imageprep/Menus.kt @ 5:884f1415a330
Rationalized directory management.
author | David Barts <n5jrn@me.com> |
---|---|
date | Fri, 17 Jul 2020 17:11:43 -0700 |
parents | 09dcd475d1bf |
children | 801cdc780ca8 |
rev | line source |
---|---|
0 | 1 /* |
2 * Menus. | |
3 */ | |
4 package name.blackcap.imageprep | |
5 | |
6 import java.awt.Graphics2D | |
7 import java.awt.RenderingHints | |
1 | 8 import java.awt.Toolkit |
0 | 9 import java.awt.Window |
10 import java.awt.event.ActionEvent | |
11 import java.awt.event.ActionListener | |
12 import java.awt.event.KeyEvent | |
13 import java.awt.image.BufferedImage | |
14 import java.io.File | |
1 | 15 import java.io.IOException |
0 | 16 import java.util.logging.Level |
17 import java.util.logging.Logger | |
18 import javax.imageio.IIOImage | |
19 import javax.imageio.ImageIO | |
20 import javax.imageio.ImageWriteParam | |
21 import javax.imageio.ImageWriter | |
22 import javax.imageio.stream.ImageOutputStream | |
23 import javax.swing.* | |
1 | 24 import javax.swing.filechooser.FileNameExtensionFilter |
0 | 25 |
26 /** | |
27 * Our menu bar. What we display depends somewhat on the system type, as | |
28 * the Mac gives us a gratuitous menu bar entry for handling some stuff. | |
29 */ | |
30 class MyMenuBar: JMenuBar() { | |
5
884f1415a330
Rationalized directory management.
David Barts <n5jrn@me.com>
parents:
3
diff
changeset
|
31 var currentInputDirectory = File(System.getProperty("user.dir")) |
884f1415a330
Rationalized directory management.
David Barts <n5jrn@me.com>
parents:
3
diff
changeset
|
32 var currentOutputDirectory = File(Settings.outputTo) |
884f1415a330
Rationalized directory management.
David Barts <n5jrn@me.com>
parents:
3
diff
changeset
|
33 |
0 | 34 init { |
35 add(JMenu("File").apply { | |
36 add(JMenuItem("Open & Scale…").apply { | |
37 addActionListener(ActionListener { doOpen() }) | |
38 makeShortcut(KeyEvent.VK_O) | |
39 }) | |
40 add(JMenuItem("Discard").apply { | |
41 addActionListener(ActionListener { doDiscard() }) | |
42 }) | |
43 add(JMenuItem("Save & Close…").apply { | |
44 addActionListener(ActionListener { doClose() }) | |
45 makeShortcut(KeyEvent.VK_S) | |
46 }) | |
47 if (OS.type != OS.MAC) { | |
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 { | |
5
884f1415a330
Rationalized directory management.
David Barts <n5jrn@me.com>
parents:
3
diff
changeset
|
81 currentDirectory = currentInputDirectory |
3 | 82 fileFilter = FileNameExtensionFilter("Image Files", *ImageIO.getReaderFileSuffixes()) |
0 | 83 } |
84 if (chooser.showOpenDialog(Application.mainFrame) == JFileChooser.APPROVE_OPTION) { | |
5
884f1415a330
Rationalized directory management.
David Barts <n5jrn@me.com>
parents:
3
diff
changeset
|
85 currentInputDirectory = chooser.selectedFile.canonicalFile.parentFile |
0 | 86 RotateDialog.makeDialog(chooser.selectedFile) |
87 } | |
88 } | |
89 | |
90 private fun doDiscard() { | |
1 | 91 val w = FocusManager.getCurrentManager().activeWindow as? RotateDialog |
0 | 92 if (w == null) { |
1 | 93 Toolkit.getDefaultToolkit().beep() |
0 | 94 return |
95 } | |
96 w.setVisible(false) | |
97 w.dispose() | |
98 } | |
99 | |
100 private fun doClose() { | |
1 | 101 val w = FocusManager.getCurrentManager().activeWindow as? RotateDialog |
0 | 102 if (w == null) { |
1 | 103 Toolkit.getDefaultToolkit().beep() |
0 | 104 return |
105 } | |
106 val outName = splitext(w.file.name).first + Settings.outputSuffix + ".jpg" | |
1 | 107 val chooser = JFileChooser().apply { |
5
884f1415a330
Rationalized directory management.
David Barts <n5jrn@me.com>
parents:
3
diff
changeset
|
108 currentDirectory = currentOutputDirectory |
884f1415a330
Rationalized directory management.
David Barts <n5jrn@me.com>
parents:
3
diff
changeset
|
109 selectedFile = File(currentOutputDirectory, outName) |
0 | 110 } |
3 | 111 if (chooser.showSaveDialog(Application.mainFrame) != JFileChooser.APPROVE_OPTION) { |
0 | 112 return |
113 } | |
5
884f1415a330
Rationalized directory management.
David Barts <n5jrn@me.com>
parents:
3
diff
changeset
|
114 currentOutputDirectory = chooser.selectedFile.canonicalFile.parentFile |
0 | 115 val (name, ext) = splitext(chooser.selectedFile.name) |
116 val file = if (ext.toLowerCase() in setOf(".jpg", ".jpeg")) { | |
117 chooser.selectedFile | |
118 } else { | |
5
884f1415a330
Rationalized directory management.
David Barts <n5jrn@me.com>
parents:
3
diff
changeset
|
119 File(currentOutputDirectory, name + ".jpg") |
0 | 120 } |
121 if (file.exists() && JOptionPane.showConfirmDialog(w, "File ${file.name} already exists. Overwrite?", "Confirm Overwrite", JOptionPane.YES_NO_OPTION) != JOptionPane.YES_OPTION) { | |
122 return | |
123 } | |
124 w.useWaitCursor() | |
125 swingWorker<IOException?> { | |
126 inBackground { | |
127 try { | |
128 val ios = ImageIO.createImageOutputStream(file) | |
129 val writer = ImageIO.getImageWritersByFormatName("jpeg").next() | |
130 val iwp = writer.getDefaultWriteParam().apply { | |
131 setCompressionMode(ImageWriteParam.MODE_EXPLICIT) | |
132 setCompressionQuality(Settings.outputQuality.toFloat() / 100.0f) | |
133 } | |
134 writer.setOutput(ios) | |
135 writer.write(null, IIOImage(w.image, null, null), iwp) | |
136 null | |
137 } catch (e: IOException) { | |
138 e | |
139 } | |
140 } | |
141 whenDone { | |
142 w.useNormalCursor() | |
143 val error = get() | |
144 if (error == null) { | |
145 w.setVisible(false) | |
146 w.dispose() | |
147 } else { | |
1 | 148 ioExceptionDialog(w, file, "write", error) |
0 | 149 } |
150 } | |
151 } | |
152 } | |
153 | |
154 private fun splitext(s: String): Pair<String, String> { | |
155 val pos = s.lastIndexOf('.') | |
156 if (pos == -1) { | |
157 return Pair(s, "") | |
158 } | |
159 return Pair(s.substring(0, pos), s.substring(pos)) | |
160 } | |
161 } | |
162 | |
163 /** | |
164 * Show an About dialog. | |
165 */ | |
166 fun showAboutDialog() { | |
167 JOptionPane.showMessageDialog(Application.mainFrame, | |
168 "\nImagePrep\n" | |
169 + "\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0© MMXX, David W. Barts\n", | |
170 "About ImagePrep", | |
171 JOptionPane.PLAIN_MESSAGE) | |
172 } |