summaryrefslogtreecommitdiff
path: root/support/arara/source/src/main/kotlin/org/islandoftex/arara/utils/MessageUtils.kt
diff options
context:
space:
mode:
Diffstat (limited to 'support/arara/source/src/main/kotlin/org/islandoftex/arara/utils/MessageUtils.kt')
-rw-r--r--support/arara/source/src/main/kotlin/org/islandoftex/arara/utils/MessageUtils.kt266
1 files changed, 266 insertions, 0 deletions
diff --git a/support/arara/source/src/main/kotlin/org/islandoftex/arara/utils/MessageUtils.kt b/support/arara/source/src/main/kotlin/org/islandoftex/arara/utils/MessageUtils.kt
new file mode 100644
index 0000000000..ae695c44fb
--- /dev/null
+++ b/support/arara/source/src/main/kotlin/org/islandoftex/arara/utils/MessageUtils.kt
@@ -0,0 +1,266 @@
+// SPDX-License-Identifier: BSD-3-Clause
+package org.islandoftex.arara.utils
+
+import javax.swing.JOptionPane
+import javax.swing.UIManager
+import org.islandoftex.arara.Arara
+import org.islandoftex.arara.configuration.AraraSpec
+
+/**
+ * Implements utilitary methods for displaying messages.
+ *
+ * @author Island of TeX
+ * @version 5.0
+ * @since 4.0
+ */
+object MessageUtils {
+ // holds the default width for the
+ // message body, in pixels
+ private const val WIDTH = 250
+
+ // let's start the UI manager and set
+ // the default look and feel to be as
+ // close as possible to the system
+ init {
+ // get the current look and feel
+ var laf = Arara.config[AraraSpec.UserInteraction.lookAndFeel]
+
+ // check if one is actually set
+ if (laf != "none") {
+ // use a special keyword to indicate
+ // the use of a system look and feel
+ if (laf == "system") {
+ laf = UIManager.getSystemLookAndFeelClassName()
+ }
+
+ // let's try it, in case it fails,
+ // rely to the default look and feel
+ try {
+ // get the system look and feel name
+ // and try to set it as default
+ UIManager.setLookAndFeel(laf)
+ } catch (_: Exception) {
+ // quack, quack, quack
+ }
+ }
+ }
+
+ /**
+ * Normalizes the icon type to one of the five available icons.
+ * @param value An integer value.
+ * @return The normalized integer value.
+ */
+ @Suppress("MagicNumber")
+ private fun normalizeIconType(value: Int): Int {
+ // do the normalization according to the available
+ // icons in the underlying message implementation
+ return when (value) {
+ 1 -> JOptionPane.ERROR_MESSAGE
+ 2 -> JOptionPane.INFORMATION_MESSAGE
+ 3 -> JOptionPane.WARNING_MESSAGE
+ 4 -> JOptionPane.QUESTION_MESSAGE
+ else -> JOptionPane.PLAIN_MESSAGE
+ }
+ }
+
+ /**
+ * Normalizes the message width, so only valid nonzero values are accepted.
+ * @param value An integer value corresponding to the message width.
+ * @return The normalized width.
+ */
+ private fun normalizeMessageWidth(value: Int): Int {
+ return if (value > 0) value else WIDTH
+ }
+
+ /**
+ * Shows the message.
+ * @param width Integer value, in pixels.
+ * @param type Type of message.
+ * @param title Title of the message.
+ * @param text Text of the message.
+ */
+ fun showMessage(
+ width: Int,
+ type: Int,
+ title: String,
+ text: String
+ ) {
+ // effectively shows the message based
+ // on the provided parameters
+ JOptionPane.showMessageDialog(null,
+ String.format(
+ "<html><body style=\"width:%dpx\">%s</body></html>",
+ normalizeMessageWidth(width),
+ text),
+ title,
+ normalizeIconType(type)
+ )
+ }
+
+ /**
+ * Shows the message. It relies on the default width.
+ * @param type Type of message.
+ * @param title Title of the message.
+ * @param text Text of the message.
+ */
+ fun showMessage(type: Int, title: String, text: String) {
+ showMessage(WIDTH, type, title, text)
+ }
+
+ /**
+ * Shows a message with options presented as an array of buttons.
+ * @param width Integer value, in pixels.
+ * @param type Type of message.
+ * @param title Title of the message.
+ * @param text Text of the message.
+ * @param buttons An array of objects to be presented as buttons.
+ * @return The index of the selected button, starting from 1.
+ */
+ fun showOptions(
+ width: Int,
+ type: Int,
+ title: String,
+ text: String,
+ vararg buttons: Any
+ ): Int {
+ // returns the index of the selected button,
+ // zero if nothing is selected
+ return JOptionPane.showOptionDialog(null,
+ String.format(
+ "<html><body style=\"width:%dpx\">%s</body></html>",
+ normalizeMessageWidth(width),
+ text),
+ title,
+ JOptionPane.DEFAULT_OPTION,
+ normalizeIconType(type), null,
+ buttons,
+ buttons[0]
+ ) + 1
+ }
+
+ /**
+ * Shows a message with options presented as an array of buttons. It relies
+ * on the default width.
+ * @param type Type of message.
+ * @param title Title of the message.
+ * @param text Text of the message.
+ * @param buttons An array of objects to be presented as buttons.
+ * @return The index of the selected button, starting from 1.
+ */
+ @Suppress("SpreadOperator")
+ fun showOptions(
+ type: Int,
+ title: String,
+ text: String,
+ vararg buttons: Any
+ ): Int {
+ return showOptions(WIDTH, type, title, text, *buttons)
+ }
+
+ /**
+ * Shows a message with a text input.
+ * @param width Integer value, in pixels.
+ * @param type Type of message.
+ * @param title Title of the message.
+ * @param text Text of the message.
+ * @return The string representing the input text.
+ */
+ fun showInput(
+ width: Int,
+ type: Int,
+ title: String,
+ text: String
+ ): String {
+ // get the string from the
+ // input text, if any
+ val input = JOptionPane.showInputDialog(null,
+ String.format(
+ "<html><body style=\"width:%dpx\">%s</body></html>",
+ normalizeMessageWidth(width),
+ text),
+ title,
+ normalizeIconType(type))
+
+ // if the input is not null, that is,
+ // the user actually typed something
+ // return the trimmed string otherwise
+ // an empty string
+ return input?.trim() ?: ""
+ }
+
+ /**
+ * Shows a message with a text input. It relies on the default width.
+ * @param type Type of message.
+ * @param title Title of the message.
+ * @param text Text of the message.
+ * @return The string representing the input text.
+ */
+ fun showInput(type: Int, title: String, text: String): String {
+ return showInput(WIDTH, type, title, text)
+ }
+
+ /**
+ * Shows a message with options presented as a dropdown list of elements.
+ * @param width Integer value, in pixels.
+ * @param type Type of message.
+ * @param title Title of the message.
+ * @param text Text of the message.
+ * @param elements An array of objects representing the elements.
+ * @return The index of the selected element, starting from 1.
+ */
+ fun showDropdown(
+ width: Int,
+ type: Int,
+ title: String,
+ text: String,
+ vararg elements: Any
+ ): Int {
+ // show the dropdown list and get
+ // the selected object, if any
+ val index = JOptionPane.showInputDialog(null,
+ String.format(
+ "<html><body style=\"width:%dpx\">%s</body></html>",
+ normalizeMessageWidth(width),
+ text),
+ title,
+ normalizeIconType(type), null,
+ elements,
+ elements[0])
+
+ // if it's not a null object, let's
+ // find the corresponding index
+ if (index != null) {
+ elements.forEachIndexed { i, value ->
+ // if the element is found, simply
+ // return the index plus 1, as zero
+ // corresponds to no selection at all
+ if (value == index) {
+ return i + 1
+ }
+ }
+ }
+
+ // nothing was selected,
+ // simply return zero
+ return 0
+ }
+
+ /**
+ * Shows a message with options presented as a dropdown list of elements. It
+ * relies on the default width.
+ * @param type Type of message.
+ * @param title Title of the message.
+ * @param text Text of the message.
+ * @param elements An array of objects representing the elements.
+ * @return The index of the selected element, starting from 1.
+ */
+ @Suppress("SpreadOperator")
+ fun showDropdown(
+ type: Int,
+ title: String,
+ text: String,
+ vararg elements: Any
+ ): Int {
+ return showDropdown(WIDTH, type, title, text, *elements)
+ }
+}