Mercurial > cgi-bin > hgweb.cgi > ImagePrep
diff src/name/blackcap/imageprep/SettingsDialog.kt @ 20:71029c9bf7cd
Commit overlooked files.
author | David Barts <n5jrn@me.com> |
---|---|
date | Sat, 21 Nov 2020 10:15:35 -0800 |
parents | |
children | 0f3634a0816d |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/name/blackcap/imageprep/SettingsDialog.kt Sat Nov 21 10:15:35 2020 -0800 @@ -0,0 +1,227 @@ +/* + * The dialog that controls font corecion. + */ +package name.blackcap.imageprep + +import java.awt.Dimension +import java.awt.event.ActionEvent +import java.awt.event.ActionListener +import java.io.BufferedWriter +import java.io.File +import java.io.FileOutputStream +import java.io.IOException +import java.io.OutputStreamWriter +import java.util.Hashtable +import java.util.Properties +import java.util.logging.Level +import java.util.logging.Logger +import javax.swing.* +import javax.swing.event.ChangeEvent +import javax.swing.event.ChangeListener +import kotlin.math.log10 +import kotlin.math.pow +import kotlin.math.roundToInt +import kotlin.text.toInt + +/* work around name shadowing */ +private val _PROPS = PROPERTIES + +class SettingsDialog: JDialog(Application.mainFrame) { + /* maximum allowed dimension in output */ + private val _maxDimension = MaxDimSpinner(_PROPS.getInt("maxDimension")) + val maxDimension: Int + get() { + return _maxDimension.value as Int + } + + /* JPEG output quality */ + private val _outputQuality = OutQualSpinner(_PROPS.getInt("outputQuality")) + val outputQuality: Int + get() { + return _outputQuality.value as Int + } + + /* file name output suffix */ + private val _outputSuffix = JTextField(_PROPS.getProperty("outputSuffix"), 24).apply { + noTaller() + } + val outputSuffix: String + get() { + return _outputSuffix.text + } + + /* output to input dir? */ + private val otid = _PROPS.getBoolean("outputToInputDir") + private val outputToInputButton = JRadioButton("Create output file in same folder as input.", otid) + val outputToInputDir: Boolean + get() { + return outputToInputButton.isSelected() + } + + /* output to some other directory */ + private val outputToButton = JRadioButton("Create output file in:", !otid) + + /* name of the other directory */ + private val oto = _getOutputTo() + protected val outputToText = JTextField(oto, 40).apply { + setEditable(false) + noTaller() + } + + /* chooser for other directory */ + private val _outputTo = JFileChooser(oto).apply { + fileSelectionMode = JFileChooser.DIRECTORIES_ONLY + setMultiSelectionEnabled(false) + } + val outputTo: String + get() { + return _outputTo.selectedFile?.getCanonicalPath() ?: oto + } + + /* button to change that other directory */ + protected val changeOutputTo = JButton("Change").also { + it.noTaller() + it.addActionListener(ActionListener { + val status = _outputTo.showOpenDialog(this) + if (status == JFileChooser.APPROVE_OPTION) { + val path = outputTo + outputToText.text = path + } + }) + it.setEnabled(!otid) + } + + /* radio button group */ + protected val buttonGroup = ButtonGroup().apply { + add(outputToButton) + add(outputToInputButton) + } + + /* standard spacing between elements (10 pixels ≅ 1/7") and half that */ + private val BW = 5 + private val BW2 = 10 + + /* buttons */ + private val _ok = JButton("OK").also { + it.noTaller() + it.addActionListener(ActionListener { + writeProperties() + setVisible(false) + }) + } + + private val _cancel = JButton("Cancel").also { + it.noTaller() + it.addActionListener(ActionListener { + revertValues() + setVisible(false) + }) + } + + /* initializer */ + init { + title = "Preferences" + contentPane.apply { + layout = BoxLayout(this, BoxLayout.Y_AXIS) + add(Box(BoxLayout.X_AXIS).apply { + border = BorderFactory.createEmptyBorder(BW2, BW2, BW, BW2) + add(leftLabel("Maximum dimension:")) + add(_maxDimension) + add(Box.createGlue()) + add(leftLabel("Output quality:")) + add(_outputQuality) + }) + add(Box(BoxLayout.X_AXIS).apply { + border = BorderFactory.createEmptyBorder(BW, BW2, BW, BW2) + add(leftLabel("Output filename suffix:")) + add(_outputSuffix) + add(Box.createGlue()) + }) + add(Box(BoxLayout.Y_AXIS).apply { + border = BorderFactory.createEmptyBorder(BW, BW2, BW2, BW2) + add(outputToInputButton) + add(outputToButton) + add(Box(BoxLayout.X_AXIS).apply { + add(outputToText) + add(changeOutputTo) + add(Box.createGlue()) + }) + }) + add(Box(BoxLayout.X_AXIS).apply { + add(_cancel) + add(Box.createGlue()) + add(_ok) + }) + } + rootPane.setDefaultButton(_ok) + pack() + setResizable(false) + } + + private fun leftLabel(text: String) = JLabel(text).apply { + alignmentX = JLabel.LEFT_ALIGNMENT + } + + private fun revertValues() + { + _maxDimension.value = _PROPS.getInt("maxDimension") + _outputQuality.value = _PROPS.getInt("outputQuality") + _outputSuffix.text = _PROPS.getProperty("outputSuffix") + val otid = _PROPS.getBoolean("outputToInputDir") + outputToInputButton.setSelected(otid) + outputToButton.setSelected(!otid) + val oto = _getOutputTo() + outputToText.text = oto + _outputTo.selectedFile = File(oto) + } + + private fun writeProperties() + { + _PROPS.setInt("maxDimension", maxDimension) + _PROPS.setInt("outputQuality", outputQuality) + _PROPS.setProperty("outputSuffix", outputSuffix) + _PROPS.setBoolean("outputToInputDir", outputToInputDir) + _PROPS.setProperty("outputTo", outputTo) + try { + BufferedWriter(OutputStreamWriter(FileOutputStream(PROP_FILE), CHARSET)).use { + _PROPS.store(it, " -*- coding: ${CHARSET} -*-") + } + } catch (e: IOException) { + LOGGER.log(Level.WARNING, "IOException writing properties file") + val message = e.message + if (message != null && !message.isEmpty()) { + LOGGER.log(Level.WARNING, message) + } + JOptionPane.showMessageDialog(Application.mainFrame, + "Unable to write settings.", + "Error", + JOptionPane.ERROR_MESSAGE) + } + } + + private fun _getOutputTo(): String = _PROPS.getProperty("outputTo") ?: System.getProperty("user.dir") +} + +fun Properties.getString(key: String): String = getProperty(key) as String + +fun Properties.getInt(key: String): Int = getString(key).toInt() + +fun Properties.setInt(key: String, value: Int): Unit { + setProperty(key, value.toString()) +} + +fun Properties.getBoolean(key: String): Boolean { + val raw = getProperty(key) + if (raw.isNullOrEmpty()) + return false + val c1 = raw[0].toLowerCase() + return c1 == 't' || c1 == 'y' +} + +fun Properties.setBoolean(key: String, value: Boolean): Unit { + setProperty(key, value.toString()) +} + +fun JComponent.noTaller() { + maximumSize = Dimension(maximumSize.width, preferredSize.height) +}