ICU-3713 add translit input method tool to icu4j

X-SVN-Rev: 15010
This commit is contained in:
Doug Felt 2004-04-20 14:44:09 +00:00
parent 24bc2f870c
commit 9a8ce89bc6
6 changed files with 627 additions and 0 deletions

View file

@ -81,6 +81,9 @@
<property name="icu4j.manifest" value="${src.dir}/com/ibm/icu/manifest.stub"/>
<property name="icu4j.module.manifest" value="${src.dir}/com/ibm/icu/manifest.module.stub"/>
<property name="icu4j.tests.manifest" value="${src.dir}/com/ibm/icu/dev/test/manifest.test.stub"/>
<property name="ime.manifest" value="${src.dir}/com/ibm/icu/dev/tool/ime/manifest.stub"/>
<property name="ime.jar.file" value="icutransime.jar"/>
<property name="ime.dir" value="tmp${DSTAMP}"/>
<property name="zip.file" value="../icu4j${DSTAMP}.zip"/>
<property name="zipSrc.file" value="../icu4jSrc${DSTAMP}.zip"/>
@ -266,6 +269,43 @@
manifest="${icu4j.manifest}"/>
</target>
<target name="imeJar" depends="collator, transliterator">
<javac includes="com/ibm/icu/dev/tool/ime/*.java"
excludes="**/CVS/**/*"
srcdir="${src.dir}"
destdir="${build.dir}"
classpathref="build.classpath"
debug="on" deprecation="off"/>
<jar jarfile="${ime.jar.file}"
compress="true"
basedir="${build.dir}"
includes="com/ibm/icu/dev/tool/ime/**/*"
manifest="${ime.manifest}">
<metainf dir="${src.dir}/com/ibm/icu/dev/tool/ime" includes="services/*"/>
</jar>
</target>
<target name="imeStandaloneJar" depends="collator, transliterator">
<javac includes="com/ibm/icu/dev/tool/ime/*.java"
excludes="**/CVS/**/*"
srcdir="${src.dir}"
destdir="${build.dir}"
classpathref="build.classpath"
debug="on" deprecation="off"/>
<copy toDir="${build.dir}/com/ibm/icu/dev/tool/ime">
<fileset dir="${src.dir}/com/ibm/icu/dev/tool/ime" includes="*.properties"/>
</copy>
<jar jarfile="${ime.jar.file}"
compress="true"
basedir="${build.dir}"
includes="com/ibm/icu/util/**/*,com/ibm/icu/text/**/*,com/ibm/icu/math/**/*,com/ibm/icu/impl/**/*,com/ibm/icu/lang/**/*,com/ibm/icu/dev/tool/ime/**/*"
manifest="${ime.manifest}">
<metainf dir="${src.dir}/com/ibm/icu/dev/tool/ime" includes="services/*"/>
</jar>
</target>
<!-- jars up richedit but without tests -->
<target name="richeditJar" depends="richedit">
<mkdir dir="${richedit.dir}"/>

View file

@ -0,0 +1,11 @@
name=ICU Transliterator
title=ICU Transliterator Input Method
start=Please wait, loading transliterators
activeError=Dispatch method called while the IME was inactive
disposedError=Dispatch called after IME was disposed
inputError=Dispatch called without an InputEvent
activateError=IME is already active
deactivateError=IME is already deactivated
hideError=Cannot hide IME while active
disposeError=Cannot dispose IME while active
multipleDisposeError=IME is already disposed

View file

@ -0,0 +1,467 @@
/*
* ===========================================================================
* IBM ICU Transliterator IME - TransliteratorInputMethod.java version 1.0
* (C) Copyright IBM Corp. 2004. All Rights Reserved
* ===========================================================================
*/
package com.ibm.icu.dev.tool.ime;
import java.awt.*;
import java.util.*;
import javax.swing.*;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
import java.awt.event.InputEvent;
import java.awt.event.InputMethodEvent;
import java.awt.event.KeyEvent;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.font.TextAttribute;
import java.awt.font.TextHitInfo;
import java.awt.im.InputMethodHighlight;
import java.awt.im.spi.InputMethod;
import java.awt.im.spi.InputMethodContext;
import java.text.AttributedString;
import com.ibm.icu.text.Transliterator;
import com.ibm.icu.text.ReplaceableString;
import com.ibm.icu.text.Collator;
public class TransliteratorInputMethod implements InputMethod {
// windows - shared by all instances of this input method
private static Window statusWindow;
// current or last statusWindow owner instance
private static TransliteratorInputMethod statusWindowOwner;
// true if Solaris style; false if PC style
private static boolean attachedStatusWindow = false;
// remember the statusWindow location per instance
private Rectangle clientWindowLocation;
// status window location in PC style
private static Point globalStatusWindowLocation;
// keep live input method instances (synchronized using statusWindow)
private static HashSet inputMethodInstances = new HashSet(5);
// per-instance state
InputMethodContext inputMethodContext;
private boolean active;
private boolean disposed;
private StringBuffer rawText;
private Transliterator transliterator = null;
private Transliterator.Position index = null;
private ReplaceableString replaceableText = null;
private ResourceBundle rb = null;
public TransliteratorInputMethod() {
rawText = new StringBuffer();
replaceableText = new ReplaceableString(rawText);
try {
rb = ResourceBundle.getBundle("com.ibm.icu.dev.tool.ime.Transliterator");
}
catch(MissingResourceException m) {
System.out.println("Transliterator resources missing: " + m);
}
}
public void setInputMethodContext(InputMethodContext context) {
inputMethodContext = context;
String title = null;
if (statusWindow == null) {
try {
title = rb.getString("title");
}
catch (MissingResourceException m) {
title = "Transliterator Input Method";
}
Window sw = context.createInputMethodWindow(title, false);
// This is to fix a problem in Java 1.4
try {
sw.setFocusableWindowState(true);
}
catch(NoSuchMethodError err) {
/* we do not need to worry about catching this, the setFocusableWindowState
only exists in Java 1.4. In Java 1.3 it is not necessary to make the
status window focusable, because the default setting is focusable. */
}
// get all the ICU Transliterators
Enumeration e = Transliterator.getAvailableIDs();
TreeSet types = new TreeSet(new LabelComparator());
while(e.hasMoreElements()) {
String id = (String) e.nextElement();
String name = Transliterator.getDisplayName(id);
JLabel label = new JLabel(name);
label.setName(id);
types.add(label);
}
// add the transliterators to the combo box
System.out.println("types: " + types);
JComboBox choices = new JComboBox(types.toArray());
choices.setEditable(false);
choices.setRenderer(new NameRenderer());
choices.setActionCommand("transliterator");
synchronized (this.getClass()) {
if (statusWindow == null) {
statusWindow = sw;
statusWindow.addComponentListener(new ComponentListener() {
public void componentResized(ComponentEvent e) {}
public void componentMoved(ComponentEvent e) {
synchronized (statusWindow) {
if (!attachedStatusWindow) {
Component comp = e.getComponent();
if (comp.isVisible()) {
globalStatusWindowLocation = comp.getLocation();
}
}
}
}
public void componentShown(ComponentEvent e) {}
public void componentHidden(ComponentEvent e) {}
});
// setup the listener, to handle selection of a transliterator
choices.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
JComboBox cb = (JComboBox)e.getSource();
JLabel item = (JLabel)cb.getSelectedItem();
// construct the actual transliterator
// commit any text that may be present first
commitAll();
transliterator = Transliterator.getInstance(item.getName());
index = new Transliterator.Position();
rawText.setLength(0);
index.contextLimit = replaceableText.length();
index.contextStart = 0;
index.start = 0;
index.limit = replaceableText.length();
}
});
statusWindow.add(choices);
statusWindowOwner = this;
updateStatusWindow();
statusWindow.pack();
choices.setSelectedIndex(0);
}
}
}
inputMethodContext.enableClientWindowNotification(this, attachedStatusWindow);
synchronized (statusWindow) {
inputMethodInstances.add(this);
}
}
public boolean setLocale(Locale locale) {
return false;
}
public Locale getLocale() {
return Locale.getDefault();
}
void updateStatusWindow() {
synchronized (statusWindow) {
statusWindow.pack();
if (attachedStatusWindow) {
if (clientWindowLocation != null) {
statusWindow.setLocation(clientWindowLocation.x,
clientWindowLocation.y + clientWindowLocation.height);
}
} else {
setPCStyleStatusWindow();
}
}
}
private void setPCStyleStatusWindow() {
synchronized (statusWindow) {
if (globalStatusWindowLocation == null) {
Dimension d = Toolkit.getDefaultToolkit().getScreenSize();
globalStatusWindowLocation = new Point(d.width - statusWindow.getWidth(),
d.height - statusWindow.getHeight() - 25);
}
statusWindow.setLocation(globalStatusWindowLocation.x, globalStatusWindowLocation.y);
}
}
private void setStatusWindowForeground(Color fg) {
synchronized (statusWindow) {
if (statusWindowOwner != this) {
return;
}
}
}
private void toggleStatusWindowStyle() {
synchronized (statusWindow) {
if (attachedStatusWindow) {
attachedStatusWindow = false;
setPCStyleStatusWindow();
} else {
attachedStatusWindow = true;
}
Iterator itr = inputMethodInstances.iterator();
while (itr.hasNext()) {
TransliteratorInputMethod im = (TransliteratorInputMethod)itr.next();
im.inputMethodContext.enableClientWindowNotification(im, attachedStatusWindow);
}
}
}
public void setCharacterSubsets(Character.Subset[] subsets) {
// ignore
}
public void reconvert() {
// not supported yet
throw new UnsupportedOperationException();
}
public void dispatchEvent(AWTEvent event) {
if (!active && (event instanceof KeyEvent)) {
System.out.println(rb.getString("activeError"));
}
if (disposed) {
System.out.println(rb.getString("disposedError"));
}
if (!(event instanceof InputEvent)) {
System.out.println(rb.getString("inputError"));
}
if (event.getID() == KeyEvent.KEY_TYPED) {
KeyEvent e = (KeyEvent) event;
if (handleCharacter(e.getKeyChar())) {
e.consume();
}
}
}
public void activate() {
if (active) {
System.out.println(rb.getString("activateError"));
}
System.out.println("activate");
active = true;
synchronized (statusWindow) {
statusWindowOwner = this;
updateStatusWindow();
if (!statusWindow.isVisible()) {
statusWindow.setVisible(true);
}
setStatusWindowForeground(Color.black);
}
}
public void deactivate(boolean isTemporary) {
if (!active) {
System.out.println(rb.getString("deactivateError"));
}
System.out.println("deactivate");
setStatusWindowForeground(Color.lightGray);
active = false;
}
public void hideWindows() {
if (active) {
System.out.println(rb.getString("hideError"));
}
synchronized (statusWindow) {
if (statusWindowOwner == this) {
statusWindow.setVisible(false);
}
}
}
public void removeNotify() {
}
public void endComposition() {
commitAll();
}
public void notifyClientWindowChange(Rectangle location) {
clientWindowLocation = location;
synchronized (statusWindow) {
if (!attachedStatusWindow || statusWindowOwner != this) {
return;
}
if (location != null) {
statusWindow.setLocation(location.x, location.y+location.height);
if (!statusWindow.isVisible()) {
if (active) {
setStatusWindowForeground(Color.black);
} else {
setStatusWindowForeground(Color.lightGray);
}
statusWindow.setVisible(true);
}
} else {
statusWindow.setVisible(false);
}
}
}
public void dispose() {
if (active) {
System.out.println(rb.getString("disposeError"));
}
if (disposed) {
System.out.println(rb.getString("multipleDisposeError"));
}
synchronized (statusWindow) {
inputMethodInstances.remove(this);
}
disposed = true;
}
public Object getControlObject() {
return null;
}
public void setCompositionEnabled(boolean enable) {
// not supported yet
throw new UnsupportedOperationException();
}
public boolean isCompositionEnabled() {
// always enabled
return true;
}
/**
* Attempts to handle a typed character.
* @return whether the character was handled
*/
private boolean handleCharacter(char ch) {
if (ch == '\n') {
commitAll();
return true;
}
else if (ch == '\b') {
if (index.contextLimit > index.contextStart) {
rawText.deleteCharAt(index.contextLimit - 1);
--index.limit;
--index.contextLimit;
sendText();
return true;
}
}
else {
rawText.append(ch);
index.limit = rawText.length();
index.contextLimit = rawText.length();
transliterator.transliterate(replaceableText, index);
sendText();
index.contextStart = index.start;
return true;
}
return false;
}
/* commits all chunks */
void commitAll() {
if(transliterator != null) {
transliterator.finishTransliteration(replaceableText, index);
sendText();
rawText.setLength(0);
index.start = 0;
index.contextStart = 0;
index.limit = 0;
index.contextLimit = 0;
}
}
void sendText() {
AttributedString as = null;
TextHitInfo caret = null;
int committedCharacterCount = 0;
InputMethodHighlight highlight = InputMethodHighlight.SELECTED_RAW_TEXT_HIGHLIGHT;
String text = null;
if(index.start > index.contextStart) {
text = rawText.substring(index.contextStart, index.start);
as = new AttributedString(text);
committedCharacterCount = text.length();
inputMethodContext.dispatchInputMethodEvent(
InputMethodEvent.INPUT_METHOD_TEXT_CHANGED,
as.getIterator(),
committedCharacterCount,
null,
null);
}
if(index.contextLimit > index.start) {
text = rawText.substring(index.start, index.contextLimit);
as = new AttributedString(text);
committedCharacterCount = 0;
as.addAttribute(TextAttribute.INPUT_METHOD_HIGHLIGHT, highlight);
caret = TextHitInfo.leading(text.length());
inputMethodContext.dispatchInputMethodEvent(
InputMethodEvent.INPUT_METHOD_TEXT_CHANGED,
as.getIterator(),
committedCharacterCount,
caret,
null);
}
}
}
class NameRenderer extends JLabel implements ListCellRenderer {
public Component getListCellRendererComponent(
JList list,
Object value,
int index,
boolean isSelected,
boolean cellHasFocus) {
String s = ((JLabel)value).getText();
setText(s);
if(isSelected) {
setBackground(list.getSelectionBackground());
setForeground(list.getSelectionForeground());
}
else {
setBackground(list.getBackground());
setForeground(list.getForeground());
}
setEnabled(list.isEnabled());
setFont(list.getFont());
setOpaque(true);
return this;
}
}
class LabelComparator implements Comparator {
public int compare(Object obj1, Object obj2) {
Collator collator = Collator.getInstance();
return collator.compare(((JLabel)obj1).getText(), ((JLabel)obj2).getText());
}
public boolean equals(Object obj1) {
return this.equals(obj1);
}
}

View file

@ -0,0 +1,91 @@
/*
* ===========================================================================
* IBM ICU Transliterator IME - TransliteratorInputMethodDescriptor.java version 1.0
* (C) Copyright IBM Corp. 2004. All Rights Reserved
* ===========================================================================
*/
package com.ibm.icu.dev.tool.ime;
import java.awt.Image;
import java.awt.im.spi.InputMethod;
import java.awt.im.spi.InputMethodDescriptor;
import java.util.Locale;
import java.util.ResourceBundle;
import java.util.MissingResourceException;
/**
* The TransliteratorInputMethodDescriptor class is used to identify this package
* as an input method editor.
*/
public class TransliteratorInputMethodDescriptor implements InputMethodDescriptor {
private ResourceBundle rb = null;
/**
* Creates the Transliterator IME this is automatically callled by the
* JVM when the Transliterator IME is selected from the input method list.
*
* @return InputMethod The Transliterator IME object.
*/
public InputMethod createInputMethod() throws Exception {
return new TransliteratorInputMethod();
}
/**
* Get the list of locales that this IME supports.
*
* @return Locale[] This will always have one locale. By default
* we just return the current locale. Therefore
* the Transliterator IME works in all locales.
*/
// use the current active locale
public Locale[] getAvailableLocales() {
return new Locale[] {Locale.getDefault()};
}
/**
* The Transliterator IME does not support dynamic locales. The Transliterator
* IME's functionality does not depend upon any locale.
*
* @return boolean This will always be false.
*/
public boolean hasDynamicLocaleList() {
return false;
}
/**
* Obtain the localized name of the Transliterator IME
*
* @param inputLocale.
* @param displayLanguge The requested translation of the Transliterator IME.
*
* @return String The localized name for the Transliterator IME.
*/
public String getInputMethodDisplayName(Locale inputLocale,
Locale displayLanguage) {
String name = null;
try {
rb = ResourceBundle.getBundle("com.ibm.icu.dev.tool.ime.Transliterator", displayLanguage);
name = rb.getString("name");
}
catch (MissingResourceException m) {
// use a hardcoded value
name = "Transliterator";
}
return name;
}
/**
* Get the icon for the Transliterator IME. This is not supported.
*
* @param inputLocale (This is ignored).
*
* @return Image This will always be null.
*/
public Image getInputMethodIcon(Locale inputLocale) {
return null;
}
}

View file

@ -0,0 +1,11 @@
Manifest-Version: 1.0
Created-By: 1.0 (IBM Corporation)
Extension-Name: com.ibm.icu.dev.tool.ime
Implementation-Vendor: IBM Corporation
Implementation-Version: 1.0
Implementation-Title: ICU Transliterator IME
Specification-Vendor: IBM
Specification-Version: 1.0
Specification-Title: ICU Transliterator IME
Name: com/ibm/icu/dev/tool/ime

View file

@ -0,0 +1,7 @@
#
#
# fully-qualified name of the java.awt.im.spi.InputMethodDescriptor
# implementation class
#
com.ibm.icu.dev.tool.ime.TransliteratorInputMethodDescriptor