diff --git a/build.xml b/build.xml
index 49ed85a..2039709 100644
--- a/build.xml
+++ b/build.xml
@@ -1,5 +1,11 @@
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -284,6 +303,10 @@
+
+
+
+
+
+
+
+
@@ -344,6 +371,10 @@
+
+
+
+
-
+
+
-
-
+
+
-
-
+
+
@@ -424,6 +454,7 @@
description="Builds the Java Web Start version of the translation tool">
+
@@ -548,7 +579,7 @@
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -689,11 +754,11 @@
-
-
+
+ because Ant doesn't always recompile when it should unless you use a
+ special task. -->
@@ -921,7 +986,7 @@
-
+
@@ -966,7 +1031,7 @@
-
+
@@ -1009,7 +1074,7 @@
-
+
@@ -1141,6 +1206,26 @@ public class ThdlVersion {
]]>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/jwsbuild.xml b/jwsbuild.xml
index 29c58cc..63408dd 100644
--- a/jwsbuild.xml
+++ b/jwsbuild.xml
@@ -43,7 +43,7 @@
+ description="Builds the Java Web Start version of ${my.app} given that you have compiled it to a JAR with the suffix ${jwsjarsuffix} (and from scratch, since our compilation procedure doesn't konw about dependencies)">
-
+
diff --git a/source/options.txt b/source/options.txt
index f6d272d..568bd0e 100644
--- a/source/options.txt
+++ b/source/options.txt
@@ -19,6 +19,16 @@
######################### User Preferences ###########################
############################################################################
+# Set this to the full path of the user preferences file, or to the
+# empty string if you wish to use the default values, which are
+# system-specific.
+thdl.user.options.directory =
+
+# Should the TibetanMachineWeb fonts not be loaded from within the JAR? Set
+# this to true if you can get away with it and want your THDL tools to load
+# faster.
+thdl.rely.on.system.tmw.fonts = false
+
# Set this to your preference of one of the following values:
#
# Framework: QuickTime for Java Value: org.thdl.media.SmartQT4JPlayer
@@ -32,8 +42,14 @@ thdl.media.player = org.thdl.media.SmartJMFPlayer
# 1: TCC Keyboard #1
# 2: TCC Keyboard #2
# 3: Sambhota Keymap One
+# 4: *ALPHA VERSION* ACIP Keyboard
thdl.default.tibetan.keyboard = 0
+# Should Jskad be in Roman input mode or Tibetan input mode upon startup?
+# 0: Tibetan
+# 1: Roman
+thdl.Jskad.input.method = 0
+
# Set this to the default font face for Roman input. No error is
# given if this font is not found.
thdl.default.roman.font.face = Serif
@@ -52,7 +68,7 @@ thdl.Jskad.disable.status.bar = false
# The message displayed in Jskad's status bar when you start it up
# with thdl.Jskad.disable.status.bar set to false:
-thdl.Jskad.initial.status.message = Welcome to Jskad!
+thdl.Jskad.initial.status.message = Welcome to Jskad\!
# Set this to true if you don't want Jskad to ask you "Do you really
# want to quit?" when you try to exit the program. (Your changes will
diff --git a/source/org/thdl/media/SmartPlayerFactory.java b/source/org/thdl/media/SmartPlayerFactory.java
index 7aa89c3..80c5c80 100644
--- a/source/org/thdl/media/SmartPlayerFactory.java
+++ b/source/org/thdl/media/SmartPlayerFactory.java
@@ -25,6 +25,7 @@ import java.util.ArrayList;
import org.thdl.util.*;
import org.thdl.util.ThdlDebug;
+import org.thdl.util.OperatingSystemUtils;
public class SmartPlayerFactory {
public static List moviePlayers;
@@ -33,23 +34,28 @@ public class SmartPlayerFactory {
private SmartPlayerFactory() { }
public static List getAllAvailableSmartPlayers() {
- String os;
- try {
- os = System.getProperty("os.name").toLowerCase();
- } catch (SecurityException e) {
- os = "unknown";
- }
+ String defaultPlayer, player;
+ switch (OperatingSystemUtils.getOSType()) {
+ case OperatingSystemUtils.MAC:
+ //macs default to org.thdl.media.SmartQT4JPlayer
+ defaultPlayer = "org.thdl.media.SmartQT4JPlayer";
+ break;
+ case OperatingSystemUtils.WIN32:
+ //windows defaults to SmartJMFPlayer
+ defaultPlayer = "org.thdl.media.SmartJMFPlayer";
+ break;
+ default:
+ //put linux etc. here
+ defaultPlayer = "org.thdl.media.SmartJMFPlayer";
+ break;
+ }
+
+ player
+ = ThdlOptions.getStringOption("thdl.media.player", defaultPlayer);
- String defaultPlayer;
- if (os.indexOf("mac") != -1) //macs default to org.thdl.media.SmartQT4JPlayer
- defaultPlayer = ThdlOptions.getStringOption("thdl.media.player", "org.thdl.media.SmartQT4JPlayer");
- else if (os.indexOf("windows") != -1) //windows defaults to SmartJMFPlayer
- defaultPlayer = ThdlOptions.getStringOption("thdl.media.player", "org.thdl.media.SmartJMFPlayer");
- else //put linux etc. here
- defaultPlayer = ThdlOptions.getStringOption("thdl.media.player", "org.thdl.media.SmartJMFPlayer");
String[] possiblePlayers;
- if (defaultPlayer.equals("org.thdl.media.SmartJMFPlayer"))
+ if (player.equals("org.thdl.media.SmartJMFPlayer"))
possiblePlayers = new String[] {"org.thdl.media.SmartJMFPlayer", "org.thdl.media.SmartQT4JPlayer"};
else
possiblePlayers = new String[] {"org.thdl.media.SmartQT4JPlayer", "org.thdl.media.SmartJMFPlayer"};
diff --git a/source/org/thdl/savant/SavantShell.java b/source/org/thdl/savant/SavantShell.java
index 220da44..23d1045 100644
--- a/source/org/thdl/savant/SavantShell.java
+++ b/source/org/thdl/savant/SavantShell.java
@@ -37,6 +37,7 @@ import org.thdl.util.ThdlActionListener;
import org.thdl.util.RTFPane;
import org.thdl.util.SimpleFrame;
import org.thdl.util.ThdlI18n;
+import org.thdl.util.ThdlOptions;
public class SavantShell extends JFrame
@@ -339,25 +340,34 @@ public class SavantShell extends JFrame
}
if (project.equals("THDL")) {
- GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
- String fonts[] = ge.getAvailableFontFamilyNames();
- int i=0;
- for (; iIn addition, this class optionally loads the TibetanMachineWeb
+* fonts manually via {@link #readInFontFiles()}.
* @author Edward Garrett, Tibetan and Himalayan Digital Library
* @version 1.0
*/
@@ -258,12 +264,51 @@ public class TibetanMachineWeb {
setKeyboard(keyboard);
}
+ /** Assumes that the TMW font files are resources associated with
+ * this class and loads those font files.
+ * @throws Error if that assumption does not hold */
+ private static void readInFontFiles() {
+ /* Note the leading slashes on these paths: */
+ readInFontFile("/Fonts/TibetanMachineWeb/timwn.ttf");
+ readInFontFile("/Fonts/TibetanMachineWeb/timwn1.ttf");
+ readInFontFile("/Fonts/TibetanMachineWeb/timwn2.ttf");
+ readInFontFile("/Fonts/TibetanMachineWeb/timwn3.ttf");
+ readInFontFile("/Fonts/TibetanMachineWeb/timwn4.ttf");
+ readInFontFile("/Fonts/TibetanMachineWeb/timwn5.ttf");
+ readInFontFile("/Fonts/TibetanMachineWeb/timwn6.ttf");
+ readInFontFile("/Fonts/TibetanMachineWeb/timwn7.ttf");
+ readInFontFile("/Fonts/TibetanMachineWeb/timwn8.ttf");
+ readInFontFile("/Fonts/TibetanMachineWeb/timwn9.ttf");
+ }
+
+ /** Assumes that the TMW font file at the given path is a resource
+ * associated with this class and loads that font file.
+ * @param path a path within the JAR containing this class file
+ * @throws Error if that assumption does not hold */
+ private static void readInFontFile(String path) {
+ try {
+ InputStream is = TibetanMachineWeb.class.getResourceAsStream(path);
+ if (null == is) {
+ throw new Error("You selected the optional behavior of loading the TibetanMachineWeb font family manually, but the resource "
+ + path + " could not be found.");
+ }
+ Font.createFont(Font.TRUETYPE_FONT, is);
+ } catch( Exception e ) {
+ e.printStackTrace();
+ ThdlDebug.noteIffyCode();
+ }
+ }
+
/**
* This method reads the data file ("tibwn.ini"), constructs
* the character, punctuation, and vowel lists, as well as
* performing other acts of initialization.
*/
private static void readData() {
+ if (!ThdlOptions.getBooleanOption("thdl.rely.on.system.tmw.fonts")) {
+ readInFontFiles();
+ }
+
webFontAttributeSet[0] = null;
for (int i=1; i
int ord = (int)ch;
diff --git a/source/org/thdl/util/OperatingSystemUtils.java b/source/org/thdl/util/OperatingSystemUtils.java
new file mode 100644
index 0000000..9162dda
--- /dev/null
+++ b/source/org/thdl/util/OperatingSystemUtils.java
@@ -0,0 +1,73 @@
+/*
+The contents of this file are subject to the THDL Open Community License
+Version 1.0 (the "License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License on the THDL web site
+(http://www.thdl.org/).
+
+Software distributed under the License is distributed on an "AS IS" basis,
+WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
+License for the specific terms governing rights and limitations under the
+License.
+
+The Initial Developer of this software is the Tibetan and Himalayan Digital
+Library (THDL). Portions created by the THDL are Copyright 2001 THDL.
+All Rights Reserved.
+
+Contributor(s): ______________________________________.
+*/
+
+package org.thdl.util;
+
+/** This class contains our operating-system-specific code. This
+ * class is not instantiable.
+ */
+public class OperatingSystemUtils {
+
+ /** This means that, because of security restrictions or the like,
+ * we cannot determine the OS. */
+ public static final int UNKNOWN = 0;
+ /** Not WIN32, not MAC -- maybe a *nix box. */
+ public static final int OTHER = 1;
+ /** Windows 9x, Me, 200*, or XP */
+ public static final int WIN32 = 2;
+ /** Mac (OS X or otherwise) */
+ public static final int MAC = 3;
+
+ /** Do not instantiate this class. */
+ private OperatingSystemUtils() { }
+
+ /** cached result of {@link #getOSName()} */
+ private static String OSName = null;
+
+ /** Returns the lowercase name of the operating system, or
+ * "unknown" if the operating system's identity cannot be
+ * determined. */
+ public static String getOSName() {
+ if (null == OSName) {
+ try {
+ OSName = System.getProperty("os.name").toLowerCase();
+ } catch (SecurityException e) {
+ OSName = null;
+ }
+ if (null == OSName) {
+ OSName = "unknown";
+ }
+ }
+ return OSName;
+ }
+
+ /** Returns either {@link #UNKNOWN}, {@link #WIN32}, {@link #MAC},
+ * or {@link #OTHER}. */
+ public static int getOSType() {
+ String os = getOSName();
+ if (os.startsWith("mac")) {
+ return MAC;
+ } else if (os.startsWith("win")) {
+ return WIN32;
+ } else if (os.equals("unknown")) {
+ return UNKNOWN;
+ } else {
+ return OTHER;
+ }
+ }
+}
diff --git a/source/org/thdl/util/ThdlActionListener.java b/source/org/thdl/util/ThdlActionListener.java
index 1e37521..349a098 100644
--- a/source/org/thdl/util/ThdlActionListener.java
+++ b/source/org/thdl/util/ThdlActionListener.java
@@ -138,6 +138,7 @@ public class ThdlActionListener implements ActionListener {
class. Handle it well so that users know what's up: */
ThdlDebug.handleClasspathError(null, err);
} catch (Throwable t) {
+ /* FIXME: make aborting optional, and have it off by default */
System.err.println("THDL_ERR 106: This application failed due to the following exception: ");
t.printStackTrace(System.err);
System.exit(1);
diff --git a/source/org/thdl/util/ThdlOptions.java b/source/org/thdl/util/ThdlOptions.java
index c8e4fcf..968c118 100644
--- a/source/org/thdl/util/ThdlOptions.java
+++ b/source/org/thdl/util/ThdlOptions.java
@@ -20,11 +20,14 @@ package org.thdl.util;
import java.io.InputStream;
import java.io.FileInputStream;
+import java.io.FileOutputStream;
import java.io.IOException;
+import java.io.File;
import java.io.FileNotFoundException;
import java.util.Properties;
import org.thdl.util.ThdlLazyException;
+import org.thdl.util.OperatingSystemUtils;
/**
* Provides a clean interface to the multi-tiered system of user
@@ -184,7 +187,10 @@ public final class ThdlOptions {
}
private static boolean suppressErrs() {
- return false; /* FIXME--make THIS configurable. */
+ return false;
+ /* FIXME--make THIS configurable. It's not a simple thing,
+ * though, since you can't use the usual prefences mechanism
+ * because it helps to implement that mechanism. */
}
private static void init() {
try {
@@ -246,10 +252,8 @@ public final class ThdlOptions {
// Get the user's properties, if they've set any:
userProperties
- = tryToGetPropsFromFile("thdl.user.options.file",
- // FIXME this default is
- // system-dependent:
- "C:\\thdl_uopt.txt",
+ = tryToGetPropsFromFile("thdl.user.options.directory", // DLC NOW FIXME: put in options.txt
+ getUserPreferencesPath(),
systemWideProperties,
suppressErrors);
} catch (SecurityException e) {
@@ -285,8 +289,13 @@ public final class ThdlOptions {
boolean suppressErrors)
throws FileNotFoundException, SecurityException
{
- Properties props = defaultProps;
String systemPropFileName = System.getProperty(pName, defaultLoc);
+
+ /* The empty string means "use the default location". See
+ * options.txt. */
+ if ("".equals(systemPropFileName))
+ systemPropFileName = defaultLoc;
+
FileInputStream fis = null;
try {
fis = new FileInputStream(systemPropFileName);
@@ -297,12 +306,12 @@ public final class ThdlOptions {
if (!suppressErrors)
throw e;
} else {
- // definitely suppress this. On a Mac or
- // Unix/Linux box, this'll happen every time
- // at present. (FIXME)
+ // definitely suppress this. On a Mac, I think
+ // this'll happen every time at present. (FIXME)
}
}
-
+
+ Properties props = defaultProps;
if (fis != null) {
props = getPropertiesFromStream(fis,
suppressErrors,
@@ -347,8 +356,112 @@ public final class ThdlOptions {
}
}
}
+
+ /** Saves the user's preferences to a file whose path is the value
+ * of {@link #getUserPreferencesPath()}. You must call
+ * setUserPreference(..)
for this to be effective.
+ * @throws IOException if an IO exception occurs while writing to
+ * the disk. */
+ public static void saveUserPreferences() throws IOException {
+ if (null != userProperties) {
+ userProperties.store(new FileOutputStream(getUserPreferencesPath()),
+ " This file was automatically created by a THDL tool.\n"
+ + "# You may edit this file, but it will be recreated,\n"
+ + "# so your comments will be lost.\n"
+ + "# \n"
+ + "# To understand this file's contents, please see\n"
+ + "# options.txt in the JAR file.\n"
+ + "# \n"
+ + "# Note that this is the user-specific preferences file.\n"
+ + "# This tool also supports a system-specific preferences\n"
+ + "# file, which the user-specific preferences override.\n"
+ + "# \n"
+ + "# Note also that you can set a JVM preference at run-time.\n"
+ + "# Doing so will override both system- and user-specific\n"
+ + "# preferences. On many systems, you do this like so:\n"
+ + "# 'java -Dthdl.default.tibetan.font.size=36 -jar Jskad.jar'\n"
+ + "# \n"
+ + "# There is, unfortunately, no further documentation on the\n"
+ + "# preferences mechanism at this time. Yell for it!\n"
+ + "# \n"
+ + "# Created at:"); // DLC FIXME: document the preferences mechanism.
+ }
+ }
+
+ /** This returns the location of the user's preferences file.
+ * This value may be overridden, by, you guessed it, a JVM,
+ * built-in, or system-wide preference
+ * thdl.user.options.directory
+ */
+ public static String getUserPreferencesPath() {
+ String defaultUserDir;
+ switch (OperatingSystemUtils.getOSType()) {
+ case OperatingSystemUtils.MAC:
+ // where? DLC FIXME
+ defaultUserDir = "/tmp";
+ break;
+ case OperatingSystemUtils.WIN32:
+ defaultUserDir = "C:\\";
+ break;
+ default:
+ //put linux etc. here
+ defaultUserDir = "/tmp";
+ break;
+ }
+
+ String defaultLoc = System.getProperty("user.home", defaultUserDir);
+ String systemsOverridingValue
+ = System.getProperty("thdl.user.options.directory", defaultLoc);
+
+ return (new File(systemsOverridingValue,
+ "my_thdl_preferences.txt")).getPath();
+ }
+
+ /** In order to save preferences, this class must know that the
+ * user (explicitly or implicitly) has changed a preference,
+ * either through selecting something in a ComboBox, going
+ * through a Preferences GUI, or the like. Calling this method
+ * indicates that the user has changed an integer-valued
+ * preference pref to value.
+ * @param pref the preference the user is setting
+ * @param value the user's new preference
+ */
+ public static void setUserPreference(String pref, int value) {
+ if (userProperties == null) {
+ userProperties = new Properties(); // empty
+ } // else leave it as is.
+ userProperties.setProperty(pref, String.valueOf(value));
+ }
+
+ /** In order to save preferences, this class must know that the
+ * user (explicitly or implicitly) has changed a preference,
+ * either through selecting something in a ComboBox, going
+ * through a Preferences GUI, or the like. Calling this method
+ * indicates that the user has changed a boolean-valued
+ * preference pref to value.
+ * @param pref the preference the user is setting
+ * @param value the user's new preference
+ */
+ public static void setUserPreference(String pref, boolean value) {
+ if (userProperties == null) {
+ userProperties = new Properties(); // empty
+ } // else leave it as is.
+ userProperties.setProperty(pref, String.valueOf(value));
+ }
+
+ /** In order to save preferences, this class must know that the
+ * user (explicitly or implicitly) has changed a preference,
+ * either through selecting something in a ComboBox, going
+ * through a Preferences GUI, or the like. Calling this method
+ * indicates that the user has changed a String-valued preference
+ * pref to value.
+ * @param pref the preference the user is setting
+ * @param value the user's new preference
+ */
+ public static void setUserPreference(String pref, String value) {
+ if (userProperties == null) {
+ userProperties = new Properties(); // empty
+ } // else leave it as is.
+ userProperties.setProperty(pref, value);
+ }
}
-
-
-
-