diff --git a/build.xml b/build.xml
index fbd7d40..326079b 100644
--- a/build.xml
+++ b/build.xml
@@ -947,6 +947,11 @@
+
+
+
+
+
diff --git a/source/keyboards.ini b/source/keyboards.ini
new file mode 100644
index 0000000..e2efe75
--- /dev/null
+++ b/source/keyboards.ini
@@ -0,0 +1,30 @@
+# Jskad keyboard init file
+#
+# This file must remain readable by the
+# java.util.Properties.load(InputStream) mechanism, so don't just edit
+# it willy-nilly. Follow the trend!
+#
+# "nil" is used to mean "there isn't one for this keyboard."
+
+# How many keyboards are there?
+number.of.keyboards = 5
+
+keyboard.name.for.popup.1 = Extended Wylie
+keyboard.rtf.help.file.1 = Wylie_keyboard.rtf
+keyboard.ini.file.1 = nil
+
+keyboard.name.for.popup.2 = TCC Keyboard \#1
+keyboard.rtf.help.file.2 = TCC_keyboard_1.rtf
+keyboard.ini.file.2 = tcc_keyboard_1.ini
+
+keyboard.name.for.popup.3 = TCC Keyboard \#2
+keyboard.rtf.help.file.3 = TCC_keyboard_2.rtf
+keyboard.ini.file.3 = tcc_keyboard_2.ini
+
+keyboard.name.for.popup.4 = Sambhota Keymap One
+keyboard.rtf.help.file.4 = Sambhota_keymap_one.rtf
+keyboard.ini.file.4 = sambhota_keyboard_1.ini
+
+keyboard.name.for.popup.5 = Asian Classics Input Project (ACIP) -- BUGGY
+keyboard.rtf.help.file.5 = nil
+keyboard.ini.file.5 = acip_keyboard.ini
diff --git a/source/org/thdl/tib/input/Jskad.java b/source/org/thdl/tib/input/Jskad.java
index e801b34..a231e0b 100644
--- a/source/org/thdl/tib/input/Jskad.java
+++ b/source/org/thdl/tib/input/Jskad.java
@@ -73,8 +73,16 @@ public class Jskad extends JPanel implements DocumentListener {
/** the middleman that keeps code regarding Tibetan keyboards
* clean */
- private final static JskadKeyboardManager keybdMgr
- = new JskadKeyboardManager(JskadKeyboardFactory.getAllAvailableJskadKeyboards());
+ private final static JskadKeyboardManager keybdMgr;
+
+ static {
+ try {
+ keybdMgr
+ = new JskadKeyboardManager(JskadKeyboardFactory.getAllAvailableJskadKeyboards());
+ } catch (Exception e) {
+ throw new ThdlLazyException(e);
+ }
+ }
private JComboBox fontFamilies, fontSizes;
private JFileChooser fileChooser;
diff --git a/source/org/thdl/tib/input/JskadKeyboardFactory.java b/source/org/thdl/tib/input/JskadKeyboardFactory.java
index 0537f42..228819f 100644
--- a/source/org/thdl/tib/input/JskadKeyboardFactory.java
+++ b/source/org/thdl/tib/input/JskadKeyboardFactory.java
@@ -18,31 +18,75 @@ Contributor(s): ______________________________________.
package org.thdl.tib.input;
+import java.util.Properties;
+
import org.thdl.tib.input.JskadKeyboard;
+import org.thdl.util.ThdlLazyException;
+import org.thdl.util.ThdlOptions;
/** A JskadKeyboardFactory determines which Tibetan keyboards Jskad
supports. Adding a new one is as easy as adding 3 lines of text
to this class's source code.
*/
public class JskadKeyboardFactory {
- public static JskadKeyboard[] getAllAvailableJskadKeyboards() {
- return new JskadKeyboard[] {
- new JskadKeyboard("Extended Wylie",
- null,
- "Wylie_keyboard.rtf"),
- new JskadKeyboard("TCC Keyboard #1",
- "tcc_keyboard_1.ini",
- "TCC_keyboard_1.rtf"),
- new JskadKeyboard("TCC Keyboard #2",
- "tcc_keyboard_2.ini",
- "TCC_keyboard_2.rtf"),
- new JskadKeyboard("Sambhota Keymap One",
- "sambhota_keyboard_1.ini",
- "Sambhota_keymap_one.rtf"),
- new JskadKeyboard("Asian Classics Input Project (ACIP)",
- "acip_keyboard.ini",
- null)
- };
+ private static final String keyIniPath = "/keyboards.ini";
+
+ /** Reads /keyboards.ini to learn which Tibetan keyboards are
+ * available. Returns them. */
+ public static JskadKeyboard[] getAllAvailableJskadKeyboards()
+ throws Exception
+ {
+ Properties keyboardProps
+ = ThdlOptions.getPropertiesFromResource(JskadKeyboardFactory.class,
+ keyIniPath,
+ false,
+ null);
+ String numberOfKeyboardsString
+ = keyboardProps.getProperty("number.of.keyboards", null);
+ if (null == numberOfKeyboardsString) {
+ throw new Exception(keyIniPath
+ + " doesn't contain a number.of.keyboards property");
+ }
+ int numberOfKeyboards;
+ try {
+ Integer num = new Integer(numberOfKeyboardsString);
+ numberOfKeyboards = num.intValue();
+ if (numberOfKeyboards < 0) throw new NumberFormatException();
+ } catch (NumberFormatException e) {
+ throw new Exception(keyIniPath
+ + " has a number.of.keyboards property, but it's not a nonnegative integer.");
+ }
+
+ JskadKeyboard[] keyboards;
+ keyboards = new JskadKeyboard[numberOfKeyboards];
+ for (int i = 1; i <= numberOfKeyboards; i++) {
+ String description
+ = keyboardProps.getProperty("keyboard.name.for.popup." + i,
+ null);
+ String iniFile
+ = keyboardProps.getProperty("keyboard.ini.file." + i,
+ null);
+ String rtfFile
+ = keyboardProps.getProperty("keyboard.rtf.help.file." + i,
+ null);
+ if (null == description)
+ throw new Exception(keyIniPath
+ + ": keyboard.name.for.popup." + i + " not defined.");
+ if (null == iniFile)
+ throw new Exception(keyIniPath
+ + ": keyboard.ini.file." + i + " not defined.");
+ if (null == rtfFile)
+ throw new Exception(keyIniPath
+ + ": keyboard.rtf.help.file." + i + " not defined.");
+ if (iniFile.equals("nil"))
+ iniFile = null;
+ if (rtfFile.equals("nil"))
+ rtfFile = null;
+ keyboards[i - 1] = new JskadKeyboard(description,
+ iniFile,
+ rtfFile);
+ }
+ return keyboards;
}
}
diff --git a/source/org/thdl/tib/text/TibetanMachineWeb.java b/source/org/thdl/tib/text/TibetanMachineWeb.java
index 146c53e..a366076 100644
--- a/source/org/thdl/tib/text/TibetanMachineWeb.java
+++ b/source/org/thdl/tib/text/TibetanMachineWeb.java
@@ -282,7 +282,8 @@ public class TibetanMachineWeb implements THDLWylieConstants {
InputStreamReader isr = new InputStreamReader(url.openStream());
BufferedReader in = new BufferedReader(isr);
- System.out.println("reading "+fileName);
+ System.out.println("Reading Tibetan Machine Web code table "
+ + fileName);
String line;
boolean hashOn = false;
boolean isSanskrit = false; //FIXME: this is never read.
diff --git a/source/org/thdl/util/ThdlOptions.java b/source/org/thdl/util/ThdlOptions.java
index d805b81..6975f88 100644
--- a/source/org/thdl/util/ThdlOptions.java
+++ b/source/org/thdl/util/ThdlOptions.java
@@ -332,8 +332,12 @@ public final class ThdlOptions {
}
- // FIXMEDOC
- private static Properties getPropertiesFromResource(Class resourceHolder,
+ /** The resource named resourceName is find and read in using
+ * resourceHolder for guidance. Default properties are provided
+ * by defaults if it is non-null. If suppressErrors is true, no
+ * exceptions will be thrown in normal operation. Otherwise, an
+ * unchecked exception may be thrown upon error. */
+ public static Properties getPropertiesFromResource(Class resourceHolder,
String resourceName,
boolean suppressErrors,
Properties defaults)