blob: 20a461adfdafd9b719d142e177b67e92e809eadb [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2007 IBM Corporation and Others
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Daisuke SATO - initial API and implementation
*******************************************************************************/
package org.eclipse.actf.ai.screenreader.jaws.script;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.HashSet;
import java.util.Vector;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
public class KeybindScriptGenerator {
private String defaultPath = ".";
private String userPath = ".";
//private String userName = "";
private String appName;
private String flagName;
private String keySettingFile = "keysettings.xml";
private Vector<Key> keys = new Vector<Key>();
//private static final int TYPE_ALL = 7;
private static final int TYPE_COMMON = 1;
private static final int TYPE_QUICK = 2;
private static final int TYPE_VIRTUAL = 4;
private Vector<Keymap> keymaps_common = new Vector<Keymap>();
private Vector<Keymap> keymaps_quick = new Vector<Keymap>();
private Vector<Keymap> keymaps_virtual = new Vector<Keymap>();
public static void main(String args[]) {
KeybindScriptGenerator ksg = new KeybindScriptGenerator();
for (int i = 0; i < args.length; i++) {
if (args[i].equals("-dp")) {
ksg.defaultPath = args[++i];
} else if (args[i].equals("-up")) {
ksg.userPath = args[++i];
} else if (args[i].equals("-name")) {
ksg.appName = args[++i];
ksg.flagName = "g_" + ksg.appName.replaceAll(" ", "") + "Flag";
} else if (args[i].equals("-key")) {
ksg.keySettingFile = args[++i];
}
}
ksg.generate();
}
public void generate() {
readKeySettings();
readDefaultKeymap();
writeScript();
}
private void readKeySettings() {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
try {
DocumentBuilder builder = factory.newDocumentBuilder();
InputSource input = new InputSource(new FileInputStream(keySettingFile));
Document doc = builder.parse(input);
String[] tags = new String[] { "Commands", "Functions" };
for (int i = 0; i < tags.length; i++) {
NodeList commandsList = doc.getElementsByTagName(tags[i]);
for (int j = 0; j < commandsList.getLength(); j++) {
Node commands = commandsList.item(j);
NodeList commandList = commands.getChildNodes();
for (int k = 0; k < commandList.getLength(); k++) {
Node command = commandList.item(k);
if (command.getNodeType() == Node.ELEMENT_NODE) {
Element commandElement = (Element) command;
NodeList keyList = command.getChildNodes();
for (int l = 0; l < keyList.getLength(); l++) {
Node keyNode = keyList.item(l);
if ("key".equals(keyNode.getNodeName())) {
Key key = new Key(keyNode, commandElement);
keys.add(key);
}
}
}
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
private void readDefaultKeymap() {
try {
BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(defaultPath
+ "\\Default.JKM")));
String line;
boolean flag = false;
int type = TYPE_COMMON;
while ((line = br.readLine()) != null) {
if (line.length() > 0 && line.charAt(0) == '[') {
if (line.toLowerCase().equals("[common keys]")) {
flag = true;
type = TYPE_COMMON;
} else if (line.toLowerCase().equals("[quick navigation keys]")) {
flag = true;
type = TYPE_QUICK;
} else if (line.toLowerCase().equals("[virtual keys]")) {
flag = true;
type = TYPE_VIRTUAL;
} else
flag = false;
}
if (line.length() > 0 && line.charAt(0) != ';' && line.charAt(0) != '[' && flag
&& !line.toLowerCase().startsWith("braille")) {
Keymap keymap = new Keymap(line);
switch (type) {
case TYPE_COMMON:
keymaps_common.add(keymap);
break;
case TYPE_QUICK:
keymaps_quick.add(keymap);
break;
case TYPE_VIRTUAL:
keymaps_virtual.add(keymap);
break;
}
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
private void writeScript() {
try {
File jss = new File(userPath + "\\" + appName + ".jss");
PrintWriter jssw = new PrintWriter(new FileOutputStream(jss));
writeFunctions(jssw);
jssw.close();
File jkm = new File(userPath + "\\" + appName + ".jkm");
PrintWriter jkmw = new PrintWriter(new FileOutputStream(jkm));
writeKeyMap(jkmw);
jkmw.close();
File jsh = new File(userPath + "\\" + appName + ".jsh");
PrintWriter jshw = new PrintWriter(new FileOutputStream(jsh));
writeGlobals(jshw);
jshw.close();
} catch (Exception e) {
e.printStackTrace();
}
}
private void writeGlobals(PrintWriter pw) {
pw.println("Globals");
pw.println(" int " + flagName + ",");
pw.println(" int g_aiBrowserSayAllFlag,");
pw.println(" handle g_aiBrowserSayAllWindow,");
pw.println(" int g_aiBrowserSayAllMessage");
}
private void writeFixedCode(PrintWriter pw) {
pw.print(";--------------------------------------------------------------------------------\r\n"
+ "Script AiBrowserSayAllOff ()\r\n"
+ " If g_aiBrowserSayAllFlag Then\r\n"
+ " let g_aiBrowserSayAllFlag = 0\r\n"
+ " StopSpeech()\r\n"
+ " Delay(5, 1)\r\n"
+ " EndIf\r\n"
+ "EndScript\r\n"
+ "\r\n"
+ "Void Function FocusChangedEvent(Handle hCurWin, Handle hPrevWin)\r\n"
+ "If g_aiBrowserSayAllFlag Then\r\n"
+ " return\r\n"
+ " Else\r\n"
+ " FocusChangedEvent(hCurWin, hPrevWin)\r\n"
+ " EndIf\r\n"
+ "EndFunction\r\n"
+ "\r\n"
+ "void function FocusChangedEventEx(Handle hwndFocus, int nObject, int nChild,\r\n"
+ " Handle hwndPrevFocus, int nPrevObject, int nPrevChild,\r\n"
+ " int nChangeDepth)\r\n"
+ " If g_aiBrowserSayAllFlag Then\r\n"
+ " return\r\n"
+ " Else\r\n"
+ " FocusChangedEventEx(hwndFocus, nObject, nChild, hwndPrevFocus, nPrevObject, nPrevChild, nChangeDepth)\r\n"
+ " EndIf\r\n"
+ "EndFunction\r\n"
+ "\r\n"
+ "int function FocusRedirected(Handle focusWindow, Handle prevWindow)\r\n"
+ " If g_aiBrowserSayAllFlag Then\r\n"
+ " return 1\r\n"
+ " Else\r\n"
+ " FocusRedirected(focusWindow, prevWindow)\r\n"
+ " EndIf\r\n"
+ "EndFunction\r\n"
+ "\r\n"
+ "Void Function SayTutorialHelp (int iObjType, int IsScriptKey)\r\n"
+ " If g_aiBrowserSayAllFlag Then\r\n"
+ " return\r\n"
+ " Else\r\n"
+ " SayTutorialHelp(iObjType, IsScriptKey)\r\n"
+ " EndIf\r\n"
+ "EndFunction\r\n"
+ "\r\n"
+ "Void Function SendaiBrowserMessage (Int param)\r\n"
+ " SendMessage(g_aiBrowserSayAllWindow, g_aiBrowserSayAllMessage, param, 0);\r\n"
+ "EndFunction\r\n"
+ "\r\n"
+ "Void Function SayAllStoppedEvent ()\r\n"
+ " PCCursor()\r\n"
+ " If (!SayAllInProgress()) Then\r\n"
+ " SendaiBrowserMessage(0)\r\n"
+ " PCCursor()\r\n"
+ " EndIf\r\n"
+ "EndFunction\r\n"
+ "\r\n"
+ "Script JAWSCursor ()\r\n"
+ "EndScript\r\n"
+ "\r\n"
+ "Script InvisibleCursor ()\r\n"
+ "EndScript\r\n"
+ "\r\n"
+ "Void Function ObserveSpeechFunction ()\r\n"
+ " If (SayAllInProgress()) Then\r\n"
+ " Else\r\n"
+ " If g_aiBrowserSayAllFlag != 1 Then\r\n"
+ " let g_aiBrowserSayAllWindow = FindWindow(GetAppMainWindow(GetFocus()), \"Jaws-aiBrowser-Communication\", \"\")\r\n"
+ " ;SayInteger(g_aiBrowserSayAllWindow)\r\n"
+ " ;SetActiveCursor(1)\r\n"
+ " ;MoveToWindow(g_aiBrowserSayAllWindow)\r\n"
+ " let g_aiBrowserSayAllMessage = RegisterWindowMessage(\"WM_JAWS_AIBROWSER_MESSAGE\")\r\n"
+ " let g_aiBrowserSayAllFlag = 1\r\n"
+ " PCCursor()\r\n"
+ " SetFocus(g_aiBrowserSayAllWindow)\r\n"
+ " PCCursor()\r\n"
+ " Delay(5, 0)\r\n"
+ " Else\r\n"
+ " If (GetFocus() != g_aiBrowserSayAllWindow) Then\r\n"
+ " SetFocus(g_aiBrowserSayAllWindow)\r\n"
+ " EndIf\r\n"
+ " PCCursor()\r\n"
+ " EndIf\r\n"
+ "\r\n"
+ " PCCursor()\r\n"
+ " SayAll(0)\r\n"
+ " ;SkimRead()\r\n"
+ " PCCursor()\r\n"
+ " EndIf\r\n"
+ "EndFunction\r\n"
+ "\r\n"
+ "Script ObserveSpeech ()\r\n"
+ " ObserveSpeechFunction()\r\n"
+ "EndScript\r\n"
+ ";--------------------------------------------------------------------------------\r\n"
);
}
private void outputPerformScript(PrintWriter pw, String func, String funcExec) {
if (func.endsWith(")"))
pw.println(" PerformScript " + funcExec + "");
else
pw.println(" PerformScript " + func + "()");
}
private void outputJawsSayAllStop(PrintWriter pw, Key key) {
if (key.jawsSayAllStop) {
pw.println(" If g_aiBrowserSayAllFlag Then");
if (key.jawsSayAllStopIgnore) {
pw.println(" return");
} else {
pw.println(" PerformScript AiBrowserSayAllOff()");
pw.println(" SendaiBrowserMessage(1)");
pw.println(" Delay(5, 1)");
}
pw.println(" EndIf");
}
}
private void writeFunctions(PrintWriter pw) {
pw.println("include \"" + appName + ".jsh\"");
pw.println();
pw.println("Script JawsOn ()");
pw.println(" let " + flagName + " = 1");
pw.println("EndScript");
pw.println();
pw.println("Script JawsOff ()");
pw.println(" let " + flagName + " = 0");
pw.println("EndScript");
pw.println();
writeFixedCode(pw);
pw.println();
pw.println();
HashSet<String> generated = new HashSet<String>();
for (int i = 0; i < keys.size(); i++) {
Key key = keys.get(i);
if (!key.jawsScript)
continue;
String func = getFuncName(key, TYPE_COMMON);
if (func != null) {
pw.println("Script " + key.toFuncString() + "()");
if (key.jawsHandle) {
outputPerformScript(pw, func, func);
} else {
pw.println(" If " + flagName + " Then");
outputPerformScript(pw, func, func);
pw.println(" Else");
outputJawsSayAllStop(pw, key);
pw.println(" TypeKey(\"" + key.toTypeString() + "\")");
pw.println(" EndIf");
}
pw.println("EndScript");
pw.println();
pw.println();
continue;
}
func = getFuncName(key, TYPE_COMMON | TYPE_QUICK | TYPE_VIRTUAL);
String funcName = "";
String funcExec = "";
if (func != null) {
funcName = func.replaceAll("\\([0-9]\\)", "(int n)");
funcExec = func.replaceAll("\\([0-9]\\)", "(n)");
}
if (!generated.contains(funcName)) {
generated.add(funcName);
if (func != null) {
if (func.endsWith(")"))
pw.println("Script " + funcName);
else
pw.println("Script " + func + "()");
pw.println(" If " + flagName + " Then");
outputPerformScript(pw, func, funcExec);
pw.println(" Else");
outputJawsSayAllStop(pw, key);
pw.println(" TypeCurrentScriptKey()");
pw.println(" EndIf");
pw.println("EndScript");
pw.println();
pw.println();
}
}
pw.println("Script " + key.toFuncString() + "()");
pw.println(" If " + flagName + " Then");
pw.println(" SayString(\"" + key.toString() + "\")");
pw.println(" EndIf");
outputJawsSayAllStop(pw, key);
if (key.jawsKey != null) {
if (key.jawsKey.currentScript) {
pw.println(" TypeCurrentScriptKey()");
} else {
pw.println(" TypeKey(\"" + key.jawsKey.toTypeString() + "\")");
}
} else {
pw.println(" TypeKey(\"" + key.toTypeString() + "\")");
}
pw.println("EndScript");
pw.println();
pw.println();
}
}
private String getFuncName(Key key, int type) {
String ret;
if (isIt(type, TYPE_COMMON)) {
ret = getFucnName(keymaps_common, key);
if (ret != null)
return ret;
}
if (isIt(type, TYPE_QUICK)) {
ret = getFucnName(keymaps_quick, key);
if (ret != null)
return ret;
}
if (isIt(type, TYPE_VIRTUAL)) {
ret = getFucnName(keymaps_virtual, key);
if (ret != null)
return ret;
}
return null;
}
private boolean isIt(int type, int mask) {
return (type & mask) == mask;
}
private String getFucnName(Vector<Keymap> keymaps, Key key) {
for (int i = 0; i < keymaps.size(); i++) {
if (keymaps.get(i).equals(key)) {
return keymaps.get(i).scriptName;
}
}
return null;
}
private void writeKeyMap(PrintWriter pw) {
pw.println("[Common keys]");
for (int i = 0; i < keys.size(); i++) {
Key key = keys.get(i);
if (!key.jawsScript) continue;
pw.println(key.toString() + "=" + key.toFuncString());
}
}
}