Mercurial > cgi-bin > hgweb.cgi > JpegWasher
comparison src/name/blackcap/exifwasher/SettingsDialog.kt @ 6:aafc9c127c7b
Fix many bugs; get settings (apparently) working.
author | David Barts <n5jrn@me.com> |
---|---|
date | Thu, 09 Apr 2020 22:29:48 -0700 |
parents | dc1f4359659d |
children | 40911898ed23 |
comparison
equal
deleted
inserted
replaced
5:dc1f4359659d | 6:aafc9c127c7b |
---|---|
1 /* | 1 /* |
2 * The dialog that controls our settings. | 2 * The dialog that controls our settings. |
3 */ | 3 */ |
4 package name.blackcap.exifwasher | 4 package name.blackcap.exifwasher |
5 | 5 |
6 import java.awt.Dimension | |
6 import java.awt.Toolkit | 7 import java.awt.Toolkit |
7 import java.awt.event.ActionEvent | 8 import java.awt.event.ActionEvent |
8 import java.awt.event.ActionListener | 9 import java.awt.event.ActionListener |
9 import java.io.BufferedWriter | 10 import java.io.BufferedWriter |
10 import java.io.File | 11 import java.io.File |
28 class SettingsDialog : JDialog(Application.mainFrame) { | 29 class SettingsDialog : JDialog(Application.mainFrame) { |
29 protected val BW = 9 | 30 protected val BW = 9 |
30 protected val BW2 = BW * 2 | 31 protected val BW2 = BW * 2 |
31 | 32 |
32 /* where to send output, if not outputToInputDir */ | 33 /* where to send output, if not outputToInputDir */ |
33 protected var _outputTo = _PROPS.getProperty("outputTo") | 34 private var homeDir = System.getProperty("user.home") |
34 protected var _dOutputTo = DPROPERTIES.getProperty("outputTo") | 35 protected var _outputTo = _PROPS.getNotEmpty("outputTo", homeDir) |
36 protected var _dOutputTo = DPROPERTIES.getNotEmpty("outputTo", homeDir) | |
35 val outputTo: String | 37 val outputTo: String |
36 get() = _outputTo | 38 get() = _outputTo |
37 | 39 |
38 /* make output where input was found */ | 40 /* make output where input was found */ |
39 protected var _outputToInputDir = _PROPS.getProperty("outputToInputDir", "false").toBoolean() | 41 protected var _outputToInputDir = _PROPS.getProperty("outputToInputDir", "false").toBoolean() |
49 /* the default whitelist, for factory resets */ | 51 /* the default whitelist, for factory resets */ |
50 protected val _oWhitelist = _whitelist.clone() | 52 protected val _oWhitelist = _whitelist.clone() |
51 protected val _dWhitelist = Whitelist.parse(DPROPERTIES.getProperty("whitelist", "")) | 53 protected val _dWhitelist = Whitelist.parse(DPROPERTIES.getProperty("whitelist", "")) |
52 | 54 |
53 /* radio buttons to choose output directory policy */ | 55 /* radio buttons to choose output directory policy */ |
54 protected val outputToButton = JRadioButton("Output to:", !outputToInputDir).apply { | 56 protected val outputToButton = JRadioButton("Output to:", !outputToInputDir).also { |
55 addActionListener(ActionListener { setOutputOpts(isSelected()) }) | 57 it.addActionListener(ActionListener { _ -> setOutputOpts(it.isSelected()) }) |
58 it.noTaller() | |
56 } | 59 } |
57 protected val outputToInputButton = JRadioButton( | 60 protected val outputToInputButton = JRadioButton( |
58 "Output to directory containing input file.", outputToInputDir).apply { | 61 "Output to directory containing input file.", outputToInputDir).also { |
59 addActionListener(ActionListener { setOutputOpts(!isSelected()) }) | 62 it.addActionListener(ActionListener { _ -> setOutputOpts(!it.isSelected()) }) |
63 it.noTaller() | |
60 } | 64 } |
61 protected val buttonGroup = ButtonGroup().apply { | 65 protected val buttonGroup = ButtonGroup().apply { |
62 add(outputToButton) | 66 add(outputToButton) |
63 add(outputToInputButton) | 67 add(outputToInputButton) |
64 } | 68 } |
66 _outputToInputDir = !toSpecific | 70 _outputToInputDir = !toSpecific |
67 changeOutputTo.setEnabled(toSpecific) | 71 changeOutputTo.setEnabled(toSpecific) |
68 } | 72 } |
69 | 73 |
70 /* displays the OutputTo directory */ | 74 /* displays the OutputTo directory */ |
71 protected val outputToText = JTextField(outputTo, 50).apply { | 75 protected val outputToText = JTextField(outputTo, 40).apply { |
72 setEditable(false) | 76 setEditable(false) |
77 noTaller() | |
73 } | 78 } |
74 | 79 |
75 /* pops up to change the above directory */ | 80 /* pops up to change the above directory */ |
76 protected val outputToChooser = JFileChooser(outputToText.text).apply { | 81 protected val outputToChooser = JFileChooser(outputToText.text).apply { |
77 fileSelectionMode = JFileChooser.DIRECTORIES_ONLY | 82 fileSelectionMode = JFileChooser.DIRECTORIES_ONLY |
88 }) | 93 }) |
89 it.setEnabled(!outputToInputDir) | 94 it.setEnabled(!outputToInputDir) |
90 } | 95 } |
91 | 96 |
92 /* bottom buttons to restore defaults, cancel, save */ | 97 /* bottom buttons to restore defaults, cancel, save */ |
93 protected val restoreButton = JButton("Restore All Defaults").apply { | 98 protected val restoreButton = JButton("Restore All Defaults").also { |
94 addActionListener(ActionListener { | 99 it.addActionListener(ActionListener { |
95 restore(_dOutputToInputDir, _dOutputTo, _dWhitelist) | 100 restore(_dOutputToInputDir, _dOutputTo, _dWhitelist) |
96 }) | 101 }) |
97 } | 102 } |
98 protected val cancelButton = JButton("Cancel").apply { | 103 protected val cancelButton = JButton("Cancel").also { |
99 addActionListener(ActionListener { | 104 it.addActionListener(ActionListener { |
100 setVisible(false) | 105 setVisible(false) |
101 restore(outputToInputDir, outputTo, whitelist) | 106 restore(outputToInputDir, outputTo, whitelist) |
102 }) | 107 }) |
103 } | 108 } |
104 protected val saveButton = JButton("Save").apply { | 109 protected val saveButton = JButton("Save").also { |
105 addActionListener(ActionListener { | 110 it.addActionListener(ActionListener { |
106 setVisible(false) | 111 setVisible(false) |
107 writeProperties() | 112 writeProperties() |
108 }) | 113 }) |
109 } | 114 } |
110 | 115 |
111 protected fun writeProperties() { | 116 protected fun writeProperties() { |
117 _whitelist = Whitelist().apply { | |
118 wlSelectorModel.toList().forEach { add(it) } | |
119 } | |
112 _PROPS.run { | 120 _PROPS.run { |
113 setProperty("outputTo", outputTo) | 121 setProperty("outputTo", outputTo) |
114 setProperty("outputToInputDir", outputToInputDir.toString()) | 122 setProperty("outputToInputDir", outputToInputDir.toString()) |
115 setProperty("whitelist", whitelist.toString()) | 123 setProperty("whitelist", whitelist.toString()) |
116 } | 124 } |
131 outputToButton.setSelected(!outputToInput) | 139 outputToButton.setSelected(!outputToInput) |
132 changeOutputTo.setEnabled(!outputToInput) | 140 changeOutputTo.setEnabled(!outputToInput) |
133 outputToText.text = output | 141 outputToText.text = output |
134 outputToInputButton.setSelected(outputToInput) | 142 outputToInputButton.setSelected(outputToInput) |
135 wlSelectorModel.reset(wl.toList()) | 143 wlSelectorModel.reset(wl.toList()) |
144 validate() | |
136 } | 145 } |
137 | 146 |
138 /* so we can present a list of strings that is always sorted */ | 147 /* so we can present a list of strings that is always sorted */ |
139 protected class WhiteListModel(basedOn: Collection<String>): ListModel<String> { | 148 protected class WhiteListModel(basedOn: Collection<String>): ListModel<String> { |
140 private val storage = ArrayList<String>(basedOn).apply { sort() } | 149 private val storage = ArrayList<String>(basedOn).apply { sort() } |
210 private val toAdd = JTextField(40).apply { | 219 private val toAdd = JTextField(40).apply { |
211 alignmentX = CENTER_ALIGNMENT | 220 alignmentX = CENTER_ALIGNMENT |
212 border = BorderFactory.createEmptyBorder(BW, BW, BW, BW) | 221 border = BorderFactory.createEmptyBorder(BW, BW, BW, BW) |
213 } | 222 } |
214 | 223 |
215 private val cancelButton = JButton("Cancel").apply { | 224 private val cancelButton = JButton("Cancel").also { |
216 addActionListener(ActionListener { | 225 it.addActionListener(ActionListener { |
217 toAdd.text = "" | 226 toAdd.text = "" |
218 setVisible(false) | 227 setVisible(false) |
219 }) | 228 }) |
220 } | 229 } |
221 | 230 |
222 private val addButton = JButton("Add").apply { | 231 private val addButton = JButton("Add").also { |
223 addActionListener(ActionListener { | 232 it.addActionListener(ActionListener { |
224 val newItem = toAdd.text?.trim() | 233 val newItem = toAdd.text?.trim() |
225 if (newItem.isNullOrEmpty()) { | 234 if (newItem.isNullOrEmpty()) { |
226 Toolkit.getDefaultToolkit().beep() | 235 Toolkit.getDefaultToolkit().beep() |
227 } else { | 236 } else { |
228 parent.wlSelectorModel.add(newItem) | 237 parent.wlSelectorModel.add(newItem) |
253 } | 262 } |
254 | 263 |
255 /* the JList that holds our whitelist */ | 264 /* the JList that holds our whitelist */ |
256 protected val wlSelectorModel = WhiteListModel(whitelist.toList()) | 265 protected val wlSelectorModel = WhiteListModel(whitelist.toList()) |
257 protected val wlSelector: JList<String> = JList<String>().apply { | 266 protected val wlSelector: JList<String> = JList<String>().apply { |
258 visibleRowCount = -1 | 267 visibleRowCount = 6 |
259 model = wlSelectorModel | 268 model = wlSelectorModel |
260 clearSelection() | 269 clearSelection() |
261 addListSelectionListener(ListSelectionListener { | 270 addListSelectionListener(ListSelectionListener { |
262 wlDeleteButton.setEnabled(!isSelectionEmpty()) | 271 wlDeleteButton.setEnabled(!isSelectionEmpty()) |
263 }) | 272 }) |
264 } | 273 } |
265 | 274 |
266 /* buttons for managing the whitelist */ | 275 /* buttons for managing the whitelist */ |
267 protected val wlAddButton = JButton("Add").apply { | 276 protected val wlAddButton = JButton("Add").also { |
268 addActionListener(ActionListener { wlAddDialog.setVisible(true) }) | 277 it.addActionListener(ActionListener { wlAddDialog.setVisible(true) }) |
269 } | 278 } |
270 protected val wlDeleteButton = JButton("Delete").apply { | 279 protected val wlDeleteButton = JButton("Delete").also { |
271 addActionListener(ActionListener { | 280 it.addActionListener(ActionListener { |
272 wlSelector.selectedIndices.forEach { wlSelectorModel.removeAt(it) } | 281 wlSelector.selectedIndices.forEach { wlSelectorModel.removeAt(it) } |
273 setEnabled(false) | 282 setEnabled(false) |
274 }) | 283 }) |
275 setEnabled(false) | 284 it.setEnabled(false) |
276 } | 285 } |
277 | 286 |
278 /* the dialog that the Add button pops up */ | 287 /* the dialog that the Add button pops up */ |
279 protected val wlAddDialog = WLAddDialog(this) | 288 protected val wlAddDialog = WLAddDialog(this) |
280 | 289 |
281 init { | 290 init { |
282 val home = System.getProperty("user.dir") | |
283 if (_outputTo.isNullOrEmpty()) { | |
284 _outputTo = home | |
285 } | |
286 if (_dOutputTo.isNullOrEmpty()) { | |
287 _dOutputTo = home | |
288 } | |
289 title = "Settings" | 291 title = "Settings" |
290 contentPane.apply { | 292 contentPane.apply { |
291 layout = BoxLayout(this, BoxLayout.Y_AXIS) | 293 layout = BoxLayout(this, BoxLayout.Y_AXIS) |
292 add(JTabbedPane().apply { | 294 add(JTabbedPane().apply { |
293 addTab("Folders", JPanel().apply { | 295 addTab("Folders", JPanel().apply { |
294 border = BorderFactory.createEmptyBorder(BW, BW, BW, BW) | 296 border = BorderFactory.createEmptyBorder(BW, BW, BW, BW) |
295 layout = BoxLayout(this, BoxLayout.Y_AXIS) | 297 layout = BoxLayout(this, BoxLayout.Y_AXIS) |
296 add(outputToInputButton.apply { | 298 // yes, a one-item box. POS mis-aligns things if only |
297 alignmentX = LEFT_ALIGNMENT | 299 // some stuff is boxed, border widths be damned. sigh. |
298 border = BorderFactory.createEmptyBorder(BW, BW, BW, BW) | |
299 }) | |
300 add(Box(BoxLayout.X_AXIS).apply { | 300 add(Box(BoxLayout.X_AXIS).apply { |
301 alignmentX = LEFT_ALIGNMENT | 301 alignmentX = LEFT_ALIGNMENT |
302 border = BorderFactory.createEmptyBorder(BW, BW, BW, BW) | 302 border = BorderFactory.createEmptyBorder(BW, BW, 0, BW) |
303 add(outputToInputButton) | |
304 add(Box.createHorizontalGlue()) | |
305 pack() | |
306 noTaller() | |
307 }) | |
308 add(Box(BoxLayout.X_AXIS).apply { | |
309 alignmentX = LEFT_ALIGNMENT | |
310 border = BorderFactory.createEmptyBorder(BW, BW, 0, BW) | |
303 add(outputToButton) | 311 add(outputToButton) |
304 add(Box.createHorizontalStrut(BW2)) | 312 add(Box.createHorizontalStrut(BW2)) |
305 add(outputToText) | 313 add(outputToText) |
306 add(Box.createHorizontalGlue()) | 314 add(Box.createHorizontalGlue()) |
315 pack() | |
316 noTaller() | |
307 }) | 317 }) |
308 add(Box(BoxLayout.X_AXIS).apply { | 318 add(Box(BoxLayout.X_AXIS).apply { |
309 alignmentX = LEFT_ALIGNMENT | 319 alignmentX = LEFT_ALIGNMENT |
310 border = BorderFactory.createEmptyBorder(0, BW, BW, BW) | 320 border = BorderFactory.createEmptyBorder(0, BW, BW, BW) |
311 add(Box.createHorizontalGlue()) | 321 add(Box.createHorizontalGlue()) |
312 add(changeOutputTo) | 322 add(changeOutputTo) |
313 }) | 323 pack() |
324 noTaller() | |
325 }) | |
326 add(Box.createVerticalGlue()) | |
314 }) | 327 }) |
315 addTab("Whitelist", JPanel().apply { | 328 addTab("Whitelist", JPanel().apply { |
316 border = BorderFactory.createEmptyBorder(BW, BW, BW, BW) | 329 border = BorderFactory.createEmptyBorder(BW, BW, BW, BW) |
317 layout = BoxLayout(this, BoxLayout.Y_AXIS) | 330 layout = BoxLayout(this, BoxLayout.Y_AXIS) |
318 add(JScrollPane(wlSelector).apply { | 331 add(JScrollPane(wlSelector).apply { |
319 alignmentX = CENTER_ALIGNMENT | 332 alignmentX = CENTER_ALIGNMENT |
320 border = BorderFactory.createEmptyBorder(BW, BW, BW, BW) | 333 border = BorderFactory.createEmptyBorder(BW, BW, BW, BW) |
321 verticalScrollBarPolicy = ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS | 334 verticalScrollBarPolicy = ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS |
322 horizontalScrollBarPolicy = ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER | 335 horizontalScrollBarPolicy = ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER |
323 }) | 336 }) |
337 add(Box.createVerticalGlue()) | |
324 add(Box(BoxLayout.X_AXIS).apply { | 338 add(Box(BoxLayout.X_AXIS).apply { |
325 alignmentX = CENTER_ALIGNMENT | 339 alignmentX = CENTER_ALIGNMENT |
326 border = BorderFactory.createEmptyBorder(BW, BW, BW, BW) | 340 border = BorderFactory.createEmptyBorder(BW, BW, BW, BW) |
327 add(Box.createHorizontalGlue()) | 341 add(Box.createHorizontalGlue()) |
328 add(wlAddButton) | 342 add(wlAddButton) |
343 } | 357 } |
344 pack() | 358 pack() |
345 minimumSize = size | 359 minimumSize = size |
346 } | 360 } |
347 } | 361 } |
362 | |
363 fun Properties.getNotEmpty(key: String, default: String): String { | |
364 val ret = getProperty(key) | |
365 return if (ret.isNullOrEmpty()) default else ret | |
366 } | |
367 | |
368 fun JComponent.noTaller() { | |
369 maximumSize = Dimension(maximumSize.width, preferredSize.height) | |
370 } |