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 }