There is now a status bar in Jskad unless you set a system property stating

that you don't want one.  It's on by default.

If you set another system property, every keypress in "Tibetan" input mode
causes an update to the status bar.  The messages are for developers, not
users, so this option is off by default.

Updated to use the new log file facility.
This commit is contained in:
dchandler 2002-10-13 19:22:56 +00:00
parent a2dc57313a
commit 02e55d6819
2 changed files with 137 additions and 6 deletions

View file

@ -33,6 +33,7 @@ import java.io.*;
import javax.swing.text.rtf.*; import javax.swing.text.rtf.*;
import org.thdl.util.ThdlDebug; import org.thdl.util.ThdlDebug;
import org.thdl.util.StatusBar;
/** /**
* Enables input of Tibetan text * Enables input of Tibetan text
@ -45,6 +46,13 @@ import org.thdl.util.ThdlDebug;
* @version 1.0 * @version 1.0
*/ */
public class DuffPane extends JTextPane implements KeyListener, FocusListener { public class DuffPane extends JTextPane implements KeyListener, FocusListener {
/**
* The status bar to update with messages about the current input mode.
* Are we expecting a vowel? a subscript? et cetera.
*/
private StatusBar statBar = null;
/** /**
* A central part of the Tibetan keyboard. As keys are typed, they are * A central part of the Tibetan keyboard. As keys are typed, they are
* added to charList if they constitute a valid Wylie character. charList * added to charList if they constitute a valid Wylie character. charList
@ -206,6 +214,14 @@ public Clipboard rtfBoard;
public DataFlavor rtfFlavor; public DataFlavor rtfFlavor;
public RTFEditorKit rtfEd = null; public RTFEditorKit rtfEd = null;
/** Creates a new DuffPane that updates sb, if sb is not null,
with messages about how the users' keypresses are being
interpreted. */
public DuffPane(StatusBar sb) {
this();
setStatusBar(sb);
}
public DuffPane() { public DuffPane() {
setupKeyboard(); setupKeyboard();
setupEditor(); setupEditor();
@ -226,6 +242,32 @@ public RTFEditorKit rtfEd = null;
// this(new StyledEditorKit(), keyboardURL); // this(new StyledEditorKit(), keyboardURL);
} }
/** Sets the status bar to update with mode information. If sb is
null, no status bar will be updated. */
public void setStatusBar(StatusBar sb) {
statBar = sb;
}
/** If we have a status bar, update it. */
private void updateStatus(String newStatus) {
if (statBar != null) {
/* If we've seen this message just before, append " x2" to
the end of it. The third message will cause a toggle,
which you can tell is different, so that's fine. */
if (newStatus.equals(statBar.currentStatus())) {
newStatus = newStatus + " x2";
}
statBar.replaceStatus((isTopHypothesis ? "Guess: " : "Fact: ") + newStatus);
}
}
/** If we have a status bar, append msg to its current status. */
private void appendStatus(String msg) {
if (statBar != null) {
statBar.replaceStatus(statBar.currentStatus() + msg);
}
}
/* /*
public DuffPane() { public DuffPane() {
setupKeyboard(); setupKeyboard();
@ -381,6 +423,7 @@ public RTFEditorKit rtfEd = null;
* backspacing, redrawing, etc. * backspacing, redrawing, etc.
*/ */
private void initKeyboard() { private void initKeyboard() {
updateStatus("Jskad is in its basic input mode");
charList.clear(); charList.clear();
oldGlyphList.clear(); oldGlyphList.clear();
holdCurrent = new StringBuffer(); holdCurrent = new StringBuffer();
@ -1034,9 +1077,18 @@ public void paste(int offset) {
* and also of whether or not the user is in stacking * and also of whether or not the user is in stacking
* mode. Most of the keyboard logic can be found here. * mode. Most of the keyboard logic can be found here.
* *
* @param e a KeyEvent * If there is a nonnull status bar to be updated (passed to the
*/ * constructor), let's explain to the user which mode we're in, why
* their keypress has changed nothing, etc. At present, this is really
* for developers to understand what's going on. For example, if you
* type s-g-r, you see a single glyph, a three-letter stack, but if you
* type s-d-r, you see two glyphs. If you examine the status bar,
* you'll see that the thing determining that is
* TibetanDocument.getGlyphs, which in turn relies on 'tibwn.ini'.
*
* @param e a KeyEvent */
public void processTibetan(KeyEvent e) { public void processTibetan(KeyEvent e) {
boolean changedStatus = false;
char c = e.getKeyChar(); char c = e.getKeyChar();
int start = getSelectionStart(); int start = getSelectionStart();
@ -1064,6 +1116,8 @@ public void paste(int offset) {
if (TibetanMachineWeb.hasDisambiguatingKey()) if (TibetanMachineWeb.hasDisambiguatingKey())
if (c == TibetanMachineWeb.getDisambiguatingKey()) { if (c == TibetanMachineWeb.getDisambiguatingKey()) {
initKeyboard(); initKeyboard();
changedStatus = true;
appendStatus(" (because you pressed the disambiguating key)");
break key_block; break key_block;
}; };
@ -1074,6 +1128,8 @@ public void paste(int offset) {
if (size == 0) { if (size == 0) {
initKeyboard(); initKeyboard();
changedStatus = true;
appendStatus(" (because you pressed the stacking key with nothing to stack on)");
} else if (size > 1 && isStackingRightToLeft) { } else if (size > 1 && isStackingRightToLeft) {
String s = (String)charList.remove(charList.size() - 1); String s = (String)charList.remove(charList.size() - 1);
newGlyphList = TibetanDocument.getGlyphs(charList, isStackingRightToLeft, isDefinitelyTibetan, isDefinitelySanskrit); newGlyphList = TibetanDocument.getGlyphs(charList, isStackingRightToLeft, isDefinitelyTibetan, isDefinitelySanskrit);
@ -1088,6 +1144,8 @@ public void paste(int offset) {
isStackingRightToLeft = false; isStackingRightToLeft = false;
isDefinitelyTibetan = isDefinitelyTibetan_withStackKey; isDefinitelyTibetan = isDefinitelyTibetan_withStackKey;
isDefinitelySanskrit = isDefinitelySanskrit_withStackKey; isDefinitelySanskrit = isDefinitelySanskrit_withStackKey;
changedStatus = true;
updateStatus("You have stacked a letter atop another.");
} else { } else {
holdCurrent = new StringBuffer(); holdCurrent = new StringBuffer();
isTopHypothesis = false; isTopHypothesis = false;
@ -1095,6 +1153,8 @@ public void paste(int offset) {
isStackingRightToLeft = false; isStackingRightToLeft = false;
isDefinitelyTibetan = isDefinitelyTibetan_withStackKey; isDefinitelyTibetan = isDefinitelyTibetan_withStackKey;
isDefinitelySanskrit = isDefinitelySanskrit_withStackKey; isDefinitelySanskrit = isDefinitelySanskrit_withStackKey;
changedStatus = true;
updateStatus("Some sort of stack-fu is happening/has happened.");
} }
break key_block; break key_block;
} }
@ -1105,6 +1165,8 @@ public void paste(int offset) {
isStackingRightToLeft = false; isStackingRightToLeft = false;
isDefinitelyTibetan = isDefinitelyTibetan_withStackKey; isDefinitelyTibetan = isDefinitelyTibetan_withStackKey;
isDefinitelySanskrit = isDefinitelySanskrit_withStackKey; isDefinitelySanskrit = isDefinitelySanskrit_withStackKey;
changedStatus = true;
updateStatus("!isStackingOn || (isStackingOn && isDefinitelyTibetan==isDefinitelyTibetan_default)");
} }
else {try { else {try {
char ch = doc.getText(caret.getDot()-1, 1).charAt(0); char ch = doc.getText(caret.getDot()-1, 1).charAt(0);
@ -1118,6 +1180,8 @@ public void paste(int offset) {
isStackingRightToLeft = false; isStackingRightToLeft = false;
isDefinitelyTibetan = isDefinitelyTibetan_withStackKey; isDefinitelyTibetan = isDefinitelyTibetan_withStackKey;
isDefinitelySanskrit = isDefinitelySanskrit_withStackKey; isDefinitelySanskrit = isDefinitelySanskrit_withStackKey;
changedStatus = true;
appendStatus(" (because 0 == fontNum)");
} else { } else {
initKeyboard(); initKeyboard();
DuffCode dc = new DuffCode(fontNum, ch); DuffCode dc = new DuffCode(fontNum, ch);
@ -1128,10 +1192,14 @@ public void paste(int offset) {
isDefinitelyTibetan = isDefinitelyTibetan_withStackKey; isDefinitelyTibetan = isDefinitelyTibetan_withStackKey;
isDefinitelySanskrit = isDefinitelySanskrit_withStackKey; isDefinitelySanskrit = isDefinitelySanskrit_withStackKey;
} }
changedStatus = true;
appendStatus(" (because 0 != fontNum)");
} }
} }
catch (BadLocationException ble) { catch (BadLocationException ble) {
initKeyboard(); initKeyboard();
changedStatus = true;
appendStatus(" (because a BadLocationException was thrown)");
}} }}
break key_block; break key_block;
} }
@ -1143,6 +1211,8 @@ public void paste(int offset) {
case KeyEvent.VK_ENTER: case KeyEvent.VK_ENTER:
case KeyEvent.VK_ESCAPE: case KeyEvent.VK_ESCAPE:
initKeyboard(); initKeyboard();
changedStatus = true;
appendStatus(" (because you typed enter, tab, or escape)");
break; break;
case KeyEvent.VK_BACK_SPACE: case KeyEvent.VK_BACK_SPACE:
@ -1167,6 +1237,8 @@ public void paste(int offset) {
} }
initKeyboard(); initKeyboard();
changedStatus = true;
appendStatus(" (because you typed punctuation)");
break key_block; /* DLC is this right? */ break key_block; /* DLC is this right? */
} }
@ -1182,6 +1254,8 @@ public void paste(int offset) {
putVowel(s); putVowel(s);
isTypingVowel = true; isTypingVowel = true;
changedStatus = true;
updateStatus("You typed a vowel (the simple way).");
} else { } else {
if (isTypingVowel) { if (isTypingVowel) {
isTypingVowel = false; isTypingVowel = false;
@ -1193,12 +1267,16 @@ public void paste(int offset) {
s = TibetanMachineWeb.getWylieForVowel(s); s = TibetanMachineWeb.getWylieForVowel(s);
putVowel(s); putVowel(s);
isTypingVowel = true; isTypingVowel = true;
changedStatus = true;
updateStatus("You typed a vowel (the other way).");
} else if (TibetanMachineWeb.isChar(s)) { } else if (TibetanMachineWeb.isChar(s)) {
s = TibetanMachineWeb.getWylieForChar(s); s = TibetanMachineWeb.getWylieForChar(s);
charList.add(s); charList.add(s);
isTopHypothesis = true; isTopHypothesis = true;
newGlyphList = TibetanDocument.getGlyphs(charList, isStackingRightToLeft, isDefinitelyTibetan, isDefinitelySanskrit); newGlyphList = TibetanDocument.getGlyphs(charList, isStackingRightToLeft, isDefinitelyTibetan, isDefinitelySanskrit);
oldGlyphList = redrawGlyphs(oldGlyphList, newGlyphList); oldGlyphList = redrawGlyphs(oldGlyphList, newGlyphList);
changedStatus = true;
updateStatus("You typed a non-vowel, Tibetan character.");
} else } else
isTopHypothesis = false; isTopHypothesis = false;
} }
@ -1211,6 +1289,8 @@ public void paste(int offset) {
initKeyboard(); initKeyboard();
isTypingVowel = true; isTypingVowel = true;
putVowel(s); putVowel(s);
changedStatus = true;
updateStatus("You typed another vowel, so the first vowel was discarded.");
} else if (TibetanMachineWeb.isChar(s)) { //the holding string is a character } else if (TibetanMachineWeb.isChar(s)) { //the holding string is a character
String s2 = TibetanMachineWeb.getWylieForChar(s); String s2 = TibetanMachineWeb.getWylieForChar(s);
@ -1221,6 +1301,8 @@ public void paste(int offset) {
oldGlyphList = redrawGlyphs(oldGlyphList, newGlyphList); oldGlyphList = redrawGlyphs(oldGlyphList, newGlyphList);
putVowel(TibetanMachineWeb.A_VOWEL); putVowel(TibetanMachineWeb.A_VOWEL);
initKeyboard(); initKeyboard();
changedStatus = true;
appendStatus(" (because we put a vowel and there's some achung stuff happening)");
break key_block; break key_block;
} }
charList.set(charList.size()-1, s2); charList.set(charList.size()-1, s2);
@ -1230,9 +1312,13 @@ public void paste(int offset) {
if (!isStackingOn) { if (!isStackingOn) {
initKeyboard(); initKeyboard();
holdCurrent = new StringBuffer(s); holdCurrent = new StringBuffer(s);
changedStatus = true;
appendStatus(" (because you weren't stacking, and there was a character already)");
} else if (TibetanMachineWeb.isAChungConsonant() && s2.equals(TibetanMachineWeb.ACHUNG)) { } else if (TibetanMachineWeb.isAChungConsonant() && s2.equals(TibetanMachineWeb.ACHUNG)) {
putVowel(TibetanMachineWeb.A_VOWEL); putVowel(TibetanMachineWeb.A_VOWEL);
initKeyboard(); initKeyboard();
changedStatus = true;
appendStatus(" (because you were stacking, and we put a vowel, and there was some achung business)");
break key_block; break key_block;
} }
@ -1253,6 +1339,8 @@ public void paste(int offset) {
initKeyboard(); initKeyboard();
isTypingVowel = true; isTypingVowel = true;
holdCurrent = new StringBuffer(s); holdCurrent = new StringBuffer(s);
changedStatus = true;
appendStatus(" (because we put a vowel and the previous...)");
} else { } else {
if (TibetanMachineWeb.isStackingMedial() && !isStackingRightToLeft) if (TibetanMachineWeb.isStackingMedial() && !isStackingRightToLeft)
initKeyboard(); initKeyboard();
@ -1265,23 +1353,35 @@ public void paste(int offset) {
} else if (TibetanMachineWeb.isAChungConsonant() && s2.equals(TibetanMachineWeb.ACHUNG)) { } else if (TibetanMachineWeb.isAChungConsonant() && s2.equals(TibetanMachineWeb.ACHUNG)) {
putVowel(TibetanMachineWeb.A_VOWEL); putVowel(TibetanMachineWeb.A_VOWEL);
initKeyboard(); initKeyboard();
changedStatus = true;
appendStatus("we put a vowel");
break key_block; break key_block;
} }
charList.add(s2); charList.add(s2);
newGlyphList = TibetanDocument.getGlyphs(charList, isStackingRightToLeft, isDefinitelyTibetan, isDefinitelySanskrit); newGlyphList = TibetanDocument.getGlyphs(charList, isStackingRightToLeft, isDefinitelyTibetan, isDefinitelySanskrit);
oldGlyphList = redrawGlyphs(oldGlyphList, newGlyphList); oldGlyphList = redrawGlyphs(oldGlyphList, newGlyphList);
changedStatus = true;
updateStatus("added character to charList");
} else { } else {
holdCurrent = new StringBuffer(s); holdCurrent = new StringBuffer(s);
isTopHypothesis = false; isTopHypothesis = false;
changedStatus = true;
updateStatus("voodoo no. 5");
} }
} }
} else { //top char is just a guess! just keep it in holdCurrent } else { //top char is just a guess! just keep it in holdCurrent
changedStatus = true;
updateStatus("top char is just a guess! just keep it in holdCurrent");
} }
} }
} }
} //end switch } //end switch
} //end key_block } //end key_block
if (changedStatus == false) {
updateStatus("THAT KEY DID NOTHING BECAUSE OF THE CURRENT INPUT MODE.");
}
} }
/** /**

View file

@ -33,9 +33,11 @@ import javax.swing.text.rtf.*;
import org.thdl.tib.text.*; import org.thdl.tib.text.*;
import org.thdl.util.ThdlDebug; import org.thdl.util.ThdlDebug;
import org.thdl.util.StatusBar;
import org.thdl.util.ThdlActionListener; import org.thdl.util.ThdlActionListener;
/** /**
* A simple Tibetan text editor. Jskad editors lack most of the * A simple Tibetan text editor. Jskad editors lack most of the
* functionality of a word-processor, but they do provide * functionality of a word-processor, but they do provide
@ -53,6 +55,13 @@ import org.thdl.util.ThdlActionListener;
* @version 1.0 * @version 1.0
*/ */
public class Jskad extends JPanel implements DocumentListener { public class Jskad extends JPanel implements DocumentListener {
/** the name of the property a developer should set to see
low-level info on how keypresses in "Tibetan" input mode are
being interpreted */
private final static String enableKeypressStatusProp
= "thdl.Jskad.enable.tibetan.mode.status";
private String fontName = ""; private String fontName = "";
private JComboBox fontFamilies, fontSizes; private JComboBox fontFamilies, fontSizes;
private JFileChooser fileChooser; private JFileChooser fileChooser;
@ -79,12 +88,20 @@ public class Jskad extends JPanel implements DocumentListener {
*/ */
public String fileName = null; public String fileName = null;
/** the status bar for this frame */
private StatusBar statusBar;
/** /**
* @param parent the object that embeds this instance of Jskad. * @param parent the object that embeds this instance of Jskad.
* Supported objects include JFrames and JApplets. If the parent * Supported objects include JFrames and JApplets. If the parent
* is a JApplet then the File menu is omitted from the menu bar. * is a JApplet then the File menu is omitted from the menu bar.
*/ */
public Jskad(final Object parent) { public Jskad(final Object parent) {
if (Boolean.getBoolean("thdl.Jskad.disable.status.bar")) {
statusBar = null;
} else {
statusBar = new StatusBar("Welcome to Jskad!");
}
parentObject = parent; parentObject = parent;
numberOfTibsRTFOpen++; numberOfTibsRTFOpen++;
JMenuBar menuBar = new JMenuBar(); JMenuBar menuBar = new JMenuBar();
@ -283,11 +300,13 @@ public class Jskad extends JPanel implements DocumentListener {
case 0: //Tibetan case 0: //Tibetan
if (dp.isRomanMode()) if (dp.isRomanMode())
dp.toggleLanguage(); dp.toggleLanguage();
statusBar.replaceStatus("Now inputting Tibetan script");
break; break;
case 1: //Roman case 1: //Roman
if (!dp.isRomanMode() && dp.isRomanEnabled()) if (!dp.isRomanMode() && dp.isRomanEnabled())
dp.toggleLanguage(); dp.toggleLanguage();
statusBar.replaceStatus("Now inputting Roman script");
break; break;
} }
} }
@ -335,7 +354,11 @@ public class Jskad extends JPanel implements DocumentListener {
toolBar.add(keyboards); toolBar.add(keyboards);
toolBar.add(Box.createHorizontalGlue()); toolBar.add(Box.createHorizontalGlue());
if (Boolean.getBoolean(Jskad.enableKeypressStatusProp)) {
dp = new DuffPane(statusBar);
} else {
dp = new DuffPane(); dp = new DuffPane();
}
JScrollPane sp = new JScrollPane(dp, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_NEVER); JScrollPane sp = new JScrollPane(dp, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
dp.getDocument().addDocumentListener(this); dp.getDocument().addDocumentListener(this);
@ -370,6 +393,8 @@ public class Jskad extends JPanel implements DocumentListener {
setLayout(new BorderLayout()); setLayout(new BorderLayout());
add("North", toolBar); add("North", toolBar);
add("Center", sp); add("Center", sp);
if (statusBar != null)
add("South", statusBar);
} }
private void getPreferences() { private void getPreferences() {
@ -698,7 +723,12 @@ public class Jskad extends JPanel implements DocumentListener {
try { try {
BufferedReader in = new BufferedReader(new FileReader(txt_fileChosen)); BufferedReader in = new BufferedReader(new FileReader(txt_fileChosen));
DuffPane dp2 = new DuffPane(); DuffPane dp2;
if (Boolean.getBoolean(Jskad.enableKeypressStatusProp)) {
dp2 = new DuffPane(statusBar);
} else {
dp2 = new DuffPane();
}
try { try {
String val = in.readLine(); String val = in.readLine();
@ -908,7 +938,7 @@ public class Jskad extends JPanel implements DocumentListener {
* you discover a bug, please send us an email, making sure to include * you discover a bug, please send us an email, making sure to include
* the jskad.log file as an attachment. */ * the jskad.log file as an attachment. */
public static void main(String[] args) { public static void main(String[] args) {
ThdlDebug.attemptToSetUpLogFile("jskad.log"); ThdlDebug.attemptToSetUpLogFile("jskad", ".log");
try { try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
@ -926,3 +956,4 @@ public class Jskad extends JPanel implements DocumentListener {
f.setVisible(true); f.setVisible(true);
} }
} }