00001
00002
00013
import java.awt.event.*;
00014
import java.awt.*;
00015
import java.util.*;
00016
import javax.swing.*;
00017
import java.io.*;
00018
import java.net.*;
00019
import javax.swing.event.*;
00020
import javax.swing.text.*;
00021
import java.awt.datatransfer.*;
00022
import java.awt.font.*;
00023
import java.awt.geom.*;
00024
import java.awt.print.*;
00025
00029 class IITextArea extends JTextPane
00030 implements KeyListener,
InputViewer {
00031
00032 InputManager inputManager = null;
00033 String
temporaryInput =
"";
00034 int tempStart = -1, tempEnd;
00035 Keymap
keymap;
00036 InternationalInputContext context = null;
00037 InternationalInput internationalInput = null;
00038 SimpleAttributeSet
tempStyle;
00039 StyledDocument
document = (StyledDocument)getDocument();
00040
00041 public void addFinal(String input) {
00042
if (
tempStart != -1)
00043
throw new IllegalStateException
00044 (
"addFinal called while there was temporary input "+
00045
temporaryInput);
00046
00047
internationalInput.
noCaretCheck =
true;
00048
if (getSelectionStart()!=getSelectionEnd())
00049 replaceSelection(
"");
00050
if (
internationalInput.
lastCaret>getText().length())
00051
internationalInput.
lastCaret = getText().length();
00052
insert(input,
internationalInput.
lastCaret);
00053
int normalizeStart =
internationalInput.
lastCaret;
00054
try {
00055 normalizeStart =
internationalInput.
normalize
00056 (normalizeStart,getCaretPosition());
00057 }
catch (BadLocationException e) {
00058 e.printStackTrace();
00059
throw new RuntimeException(
"Internal error: "+e);
00060 }
00061
internationalInput.
lastCaret = getCaretPosition();
00062
00063
try {
00064
internationalInput.
iconify(normalizeStart,
internationalInput.
lastCaret);
00065 }
catch (BadLocationException e) {
00066 e.printStackTrace();
00067
throw new RuntimeException(
"Internal error: "+e);
00068 }
00069
00070
if (
internationalInput.
autoSetFont)
internationalInput.
autoSetFont(input,
true);
00071
00072
00073
00074 Element e =
document.getParagraphElement(getCaretPosition());
00075 System.out.print(
"Paragraph: "+e);
00076 AttributeSet a = e.getAttributes();
00077
while (a!=null) {
00078 System.out.println(
"===");
00079
for (Enumeration en = a.getAttributeNames();
00080 en.hasMoreElements();) {
00081 Object name = en.nextElement();
00082 System.out.println(name+
" = "+a.getAttribute(name));
00083 }
00084 a = a.getResolveParent();
00085 }
00086
00087
internationalInput.
noCaretCheck =
false;
00088 }
00089
00090
00091 public void insert(String txt,
int pos) {
00092 setCaretPosition(pos);
00093 replaceSelection(txt); };
00094
00095
00096 public void replaceRange(String txt,
int start,
int end) {
00097 setSelectionStart(start);
00098 setSelectionEnd(end);
00099 replaceSelection(txt);
00100 }
00101
00102 public void addTemporary(String input) {
00103
if (
tempStart != -1)
00104
throw new IllegalStateException
00105 (
"addTemporary called while there was temporary input "+
00106
temporaryInput);
00107
00108
internationalInput.
noCaretCheck =
true;
00109
if (getSelectionStart()!=getSelectionEnd())
00110 replaceSelection(
"");
00111
00112
if (
internationalInput.
lastCaret>getText().length())
00113
internationalInput.
lastCaret = getText().length();
00114
try {
00115
document.insertString(
internationalInput.
lastCaret,input,
tempStyle);
00116 }
catch (BadLocationException e) {
00117
throw new RuntimeException(e.toString());
00118 }
00119
temporaryInput = input;
00120
tempStart =
internationalInput.
lastCaret;
00121
internationalInput.
lastCaret = tempEnd =
tempStart+input.length();
00122 setCaretPosition(
internationalInput.
lastCaret);
00123
internationalInput.
noCaretCheck =
false;
00124
if (
internationalInput.
autoSetFont)
internationalInput.
autoSetFont(
temporaryInput,
true);
00125 }
00126
00127 public void removeTemporary() {
00128
if (
tempStart == -1)
return;
00129
00130
internationalInput.
noCaretCheck =
true;
00131
if (
tempStart > tempEnd)
00132
throw new IllegalArgumentException
00133 (
"tempStart > tempEnd");
00134
try {
00135 replaceRange(
"",
tempStart,tempEnd);
00136 }
catch (IllegalArgumentException e) {
00137 e.printStackTrace();
00138 }
00139
internationalInput.
lastCaret =
tempStart;
00140
tempStart = -1;
00141
internationalInput.
noCaretCheck =
false;
00142 }
00143
00144 public IITextArea(
InputManager _inputManager,
00145
InternationalInputContext _context,
00146
InternationalInput _internationalInput) {
00147
inputManager = _inputManager;
00148
internationalInput = _internationalInput;
00149
context = _context;
00150 addKeyListener(
this);
00151
00152
00153
keymap = addKeymap(
"IITextArea-keymap",null);
00154
keymap.setDefaultAction(
new AbstractAction() {
00155
public void actionPerformed(ActionEvent e) {
00156
internationalInput.
keyStroke(e);
00157 }});
00158 tempStyle =
new SimpleAttributeSet();
00159 StyleConstants.setForeground(tempStyle, Color.blue);
00160 setKeymap(keymap);
00161 }
00162
00163 public void specialKey(
int key) {
00164
switch (key) {
00165
case InputManager.KEY_BACKSPACE:
00166
int car = getCaretPosition();
00167
if (getSelectionStart()!=getSelectionEnd())
00168 replaceSelection(
"");
00169
else if (car>0) {
00170
try {
00171 String str = document.getText(car-1,1);
00172
if (car>=2 &&
Normalizer.isLowSurrogate(str.charAt(0))) {
00173 str = document.getText(car-2,1);
00174
if (
Normalizer.isHighSurrogate(str.charAt(0)))
00175 replaceRange(
"",car-2,car);
00176
else
00177 replaceRange(
"",car-1,car);
00178 }
00179
else
00180 replaceRange(
"",car-1,car);
00181 }
catch (BadLocationException e) {
00182 e.printStackTrace();
00183
throw new RuntimeException
00184 (
"Internal error: "+e);
00185 }
00186 }
00187 internationalInput.lastCaret = getCaretPosition();
00188
break;
00189
default:
00190
throw new IllegalArgumentException(
"Unknown special key "+key);
00191 }
00192 }
00193
00194 public void keyPressed(KeyEvent e) {
00195
00196
int c = e.getKeyCode();
00197
if (c==KeyEvent.VK_ENTER || c==KeyEvent.VK_BACK_SPACE)
00198 e.consume();
00199 internationalInput.checkCaret();
00200 };
00201 public void keyReleased(KeyEvent e) {
00202 internationalInput.checkCaret();
00203 };
00204 public void keyTyped(KeyEvent e) {
00205 internationalInput.checkCaret();
00206
if (e.getKeyChar()==
'\b')
00207 { e.consume(); internationalInput.backSpace(); };
00208 };
00209 }
00210
00211 public class InternationalInput extends JPanel
00212 implements
InputManagerContext, MouseListener,
00213 KeyListener {
00214 public static final int MIN_FONT_SIZE = 10;
00215 public static final int MAX_FONT_SIZE = 40;
00216 public static final int FONT_SIZE_STEPPING = 2;
00217 public static final int DEFAULT_FONT_SIZE = 14;
00218
00219
00220 InputManager inputManager;
00221 IITextArea inputField;
00222 JScrollPane
scrollPane;
00223 boolean disableButtons =
false;
00224 JPanel
buttons;
00225 JPanel
fKeyPanel;
00226 LinkedList
fkeys =
new LinkedList();
00227 InternationalInputContext context = null;
00228 Properties
properties = null;
00229 String
fonts[] = null;
00230 JMenuItem
fontMenuItems[] = null;
00231 JMenuItem
fontSizeMenuItems[] = null;
00232 JButton
noFontItem =
new JButton();
00233 JButton
noSizeItem =
new JButton();
00234 JMenu
inputMethodMenu = null;
00235 JCheckBoxMenuItem
inputMethodMenuItems[] = null;
00236 String
inputMethodMenuItemNames[] = null;
00237 JMenu
webPageMenu = null;
00238 Clipboard
clipboard = null;
00239 boolean noSystemClipboard =
false;
00240 Documentation currentDocumentation =
00241
new Documentation() {
00242
public String getFullDocuName() {
return "nothing"; }
00243
public String
getDocumentation() {
00244
return "<html><head><title>Nothing activated.</title></head><body>"+
00245
"<h1>Nothing activated</h1>Please activate something (e.g. an input method) "+
00246
"before trying to access its documentation.</body></html>"; }};
00247 int fontSize =
InternationalInput.DEFAULT_FONT_SIZE;
00248 boolean autoSetFont =
false;
00249 boolean noCaretCheck =
false;
00250 int lastCaret = 0;
00251 FileChooser fileChooser = null;
00252 File
currentFile = null;
00253 PrinterJob
printerJob = null;
00254 PageFormat
pageFormat = null;
00255 JFrame
previewFrame = null;
00256
00257 interface
FKey {
00258 AbstractButton getComponent();
00259
void setKey(String key);
00260
boolean isValid();
00261 }
00262 public static String
fKeyCombineString(String key, String name) {
00263
return "<html><font face=sansserif size=-1><b>"+key+
"</b> "+name;
00264 }
00265 class WebPageFKey implements FKey {
00266 JButton
button;
00267 InputManager.WebPage
webpage;
00268 public void init() {
00269
if (
button!=null)
return;
00270
button =
new JButton(
"uninitialized");
00271
button.addActionListener(
new ActionListener() {
00272
public void actionPerformed(ActionEvent e) {
00273 callWebPage(
webpage);
00274 inputField.requestFocus();
00275 }});
00276 button.setToolTipText(webpage.getName());
00277 button.setBorderPainted(
false);
00278 button.setMargin(
new Insets(0,0,0,0));
00279 button.setFont(button.getFont().deriveFont(Font.PLAIN));
00280 }
00281 public boolean isValid() {
return true; };
00282 public WebPageFKey(
InputManager.WebPage wp) {
00283 webpage = wp; }
00284 public AbstractButton getComponent() {
00285
return button; }
00286 public void setKey(String key) {
00287
if (button==null) init();
00288 button.setText(fKeyCombineString(key,webpage.getShortName()));
00289 }
00290 public boolean equals(Object a) {
00291
if (!(a instanceof
WebPageFKey))
return false;
00292
if (webpage != ((
WebPageFKey)a).webpage)
return false;
00293
return true;
00294 }
00295 }
00296 class GroupFKey implements FKey {
00297 JCheckBox button;
00298 String name;
00299 String screenName;
00300 public void init() {
00301
if (button!=null)
return;
00302 button =
new JCheckBox(
"uninitialized",
00303 inputManager.isInputMethodActive(name));
00304 screenName = inputManager.getInputMethodScreenName(name);
00305 button.addActionListener(
new ActionListener() {
00306
public void actionPerformed(ActionEvent e) {
00307
try {
00308 breakComposition();
00309
if (button.isSelected()) {
00310 inputManager.activateGroup(name);
00311
00312
00313 }
else
00314 inputManager.deactivateGroup(name);
00315 }
catch (IOException ex) {
00316 ex.printStackTrace();
00317 showMessage(
"Could not activate "+name+
": "+ex.toString());
00318 }
00319 inputField.requestFocus();
00320 }});
00321 button.setMargin(
new Insets(0,0,0,0));
00322 button.setFont(button.getFont().deriveFont(Font.PLAIN));
00323 }
00324 public boolean isValid() {
00325
if (button==null) init();
00326
boolean newState = inputManager.isInputMethodActive(name);
00327
if (newState!=button.isSelected())
00328 button.setSelected(newState);
00329
return !inputManager.getGroup(name).isHidden();
00330 };
00331 public GroupFKey(String _name) {
00332 name = _name; }
00333 public AbstractButton getComponent() {
00334
return button; }
00335 public void setKey(String key) {
00336
if (button==null) init();
00337 button.setText(fKeyCombineString(key,screenName));
00338 }
00339 public boolean equals(Object a) {
00340
if (!(a instanceof
GroupFKey))
return false;
00341
if (!name.equals(((
GroupFKey)a).name))
return false;
00342
return true;
00343 }
00344 }
00345
00346 public InternationalInput(
InternationalInputContext _context) {
00347 context = _context;
00348
try {
00349 inputManager =
new InputManager(
this);
00350 }
catch (IOException e) {
00351
throw new RuntimeException(e.getMessage());
00352 }
00353
00354 setLayout(
new BorderLayout());
00355
00356 inputField =
new IITextArea(inputManager,context,
this);
00357 inputManager.setViewer(inputField);
00358 scrollPane =
new JScrollPane();
00359 scrollPane.setViewportView(inputField);
00360 add(
"Center",scrollPane);
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383 fKeyPanel =
new JPanel();
00384
00385 fKeyPanel.setLayout(
new VerticalFlowLayout(FlowLayout.LEFT,0,0));
00386
00387 add(
"South",fKeyPanel);
00388
00389 initMenu();
00390 applyProperties();
00391
00392 updateFKeys();
00393
00394
00395
00396
00397 addKeyListener(
this);
00398
00399 inputField.addMouseListener(
this);
00400
00401 inputField.addKeyListener(
this);
00402
00403
00404
00405 }
00406
00407
00408 public static final String fKeyNames[] = {
00409
"F2",
"F3",
"F4",
"F5",
"F6",
00410
"F7",
"F8",
"F9",
"F10",
"F11",
"F12" };
00411 public static final int fKeyCodes[] = {
00412 KeyEvent.VK_F2, KeyEvent.VK_F3, KeyEvent.VK_F4,
00413 KeyEvent.VK_F5, KeyEvent.VK_F6, KeyEvent.VK_F7, KeyEvent.VK_F8,
00414 KeyEvent.VK_F9, KeyEvent.VK_F10, KeyEvent.VK_F11, KeyEvent.VK_F12,
00415 };
00416 public void updateFKeys() {
00417
if (fKeyPanel==null)
return;
00418 fKeyPanel.removeAll();
00419
int keyNum = 0;
00420
boolean empty =
true;
00421
for (ListIterator it = fkeys.listIterator();
00422 it.hasNext();) {
00423
FKey fkey = (
FKey)it.next();
00424
if (!fkey.
isValid()) { it.remove();
continue; };
00425
if (keyNum < fKeyNames.length) fkey.
setKey(fKeyNames[keyNum]);
00426
else fkey.
setKey(
"");
00427 AbstractButton button = fkey.
getComponent();
00428
if (keyNum < fKeyCodes.length)
00429 button.setMnemonic(fKeyCodes[keyNum]);
00430
else button.setMnemonic(KeyEvent.VK_UNDEFINED);
00431 fKeyPanel.add(button);
00432 keyNum++; empty =
false;
00433 }
00434 fKeyPanel.setVisible(!empty);
00435 repaint(getBounds());
00436
00437
00438 }
00439
00440 boolean checkFKeyHotKey(
int code) {
00441
int num = 0;
00442 ListIterator it = fkeys.listIterator();
00443
while (it.hasNext() && num < fKeyCodes.length) {
00444
FKey fkey = (
FKey)it.next();
00445
if (fKeyCodes[num]==code) {
00446 fkey.
getComponent().doClick();
00447
return true;
00448 }
00449 num++;
00450 }
00451
return false;
00452 }
00453
00454 public void addFKey(
FKey fkey) {
00455
int num = 0;
00456
for (ListIterator it = fkeys.listIterator();
00457 it.hasNext(); num++)
00458
if (fkey.equals(it.next()))
return;
00459
if (num>fKeyCodes.length-1 || num>fKeyNames.length-1)
00460 fkeys.removeFirst();
00461 fkeys.add(fkey);
00462 updateFKeys();
00463 revalidate();
00464 }
00465
00466 public InternationalInputContext getInternationalInputContext() {
00467
return context; };
00468
00469 public void showMessage(String msg) {
00470 System.out.println(msg);
00471
try {
00472 context.showInfo(msg,
true);
00473 }
catch (UnsupportedOperationException e) {};
00474 }
00475
00476 public void createIMMenu(String im[]) {
00477 inputMethodMenuItems =
new JCheckBoxMenuItem[im.length];
00478 inputMethodMenuItemNames =
new String[im.length];
00479 HashMap groups =
new HashMap(im.length);
00480 JMenu imMenus[] =
new JMenu[27];
00481
char h[] =
new char[1];
00482
boolean createSubMenus = (im.length>27);
00483
00484 inputMethodMenu.removeAll();
00485
00486
00487 JMenuItem clearMenu =
new JMenuItem(
"None (0)");
00488 clearMenu.setMnemonic(KeyEvent.VK_0);
00489 clearMenu.addActionListener(
new ActionListener() {
00490
public void actionPerformed(ActionEvent e) {
00491 inputManager.deselectNonHiddenGroups();
00492 }});
00493 inputMethodMenu.add(clearMenu);
00494
00495
00496 JCheckBoxMenuItem singleMenuItem =
new JCheckBoxMenuItem
00497 (
"Single (1)",inputManager.getSingleInputMethod());
00498 singleMenuItem.setMnemonic(KeyEvent.VK_1);
00499 singleMenuItem.addActionListener(
new ActionListener() {
00500
public void actionPerformed(ActionEvent e) {
00501 JCheckBoxMenuItem item =
00502 (JCheckBoxMenuItem)(e.getSource());
00503
try {
00504 inputManager.setSingleInputMethod(item.isSelected());
00505 }
catch (IOException ex) {
00506 showMessage(ex.toString()); ex.printStackTrace(); }
00507 }});
00508 inputMethodMenu.add(singleMenuItem);
00509 inputMethodMenu.add(
new JSeparator());
00510
00511
for (
int i=0; i<im.length; i++) {
00512
if (im[i]==null)
continue;
00513 String screenName = inputManager.getInputMethodScreenName(im[i]);
00514 JCheckBoxMenuItem menuItem =
new JCheckBoxMenuItem(screenName);
00515
00516 inputMethodMenuItemNames[i] = im[i];
00517 inputMethodMenuItems[i] = menuItem;
00518 menuItem.addActionListener((
new ActionListener() {
00519 String name = null;
00520 ActionListener init(String n) { name = n;
return this; };
00521
public void actionPerformed(ActionEvent e) {
00522
try {
00523 JCheckBoxMenuItem m = (JCheckBoxMenuItem)e.getSource();
00524 breakComposition();
00525
if (m.isSelected()) {
00526 inputManager.activateGroup(name);
00527
00528
00529 }
else
00530 inputManager.deactivateGroup(name);
00531 }
catch (IOException ex) {
00532 ex.printStackTrace();
00533 showMessage(
"Could not activate "+name+
": "+ex.toString());
00534 }
00535 }}).init(im[i]));
00536
00537 String groupName = screenName.replaceFirst(
"\\s*[\\(-/].*",
"");
00538 JMenu container = (JMenu)groups.get(groupName);
00539
if (container == null) {
00540 container =
new JMenu(groupName);
00541 groups.put(groupName,container);
00542 }
00543 container.add(menuItem);
00544 }
00545
00546 Iterator it=groups.values().iterator();
00547
while (it.hasNext()) {
00548 JMenuItem menuItem = (JMenu)it.next();
00549
if (menuItem == null)
continue;
00550
if (((JMenu)menuItem).getItemCount()==1)
00551 menuItem = ((JMenu)menuItem).getItem(0);
00552
if (createSubMenus) {
00553 h[0] = menuItem.getText().charAt(0);
00554
int num;
00555 String name;
00556
if (h[0] >=
'A' && h[0] <=
'Z') {
00557 num = h[0]-
'A';
00558 name =
new String(h)+
"...";
00559 }
else if (h[0] >=
'a' && h[0] <=
'z') {
00560 num = h[0]-
'a';
00561 h[0] +=
'A'-
'a';
00562 name =
new String(h)+
"...";
00563 }
else {
00564 num = 26;
00565 name =
"others (*)";
00566 }
00567
if (imMenus[num]==null)
00568 imMenus[num] =
new JMenu(name);
00569 imMenus[num].add(menuItem);
00570 }
else {
00571 inputMethodMenu.add(menuItem);
00572 }
00573 }
00574
00575
00576
if (createSubMenus) {
00577
for (
int i=0; i<27; i++) {
00578
if (imMenus[i]==null)
continue;
00579
if (imMenus[i].getItemCount()==1) {
00580 JMenuItem sub = imMenus[i].getItem(0);
00581 sub.setMnemonic((i<26)?(
'A'+i):
'*');
00582 inputMethodMenu.add(sub);
00583 }
else {
00584 imMenus[i].setMnemonic((i<26)?(
'A'+i):
'*');
00585 mnemonifyMenu(imMenus[i],
true);
00586 inputMethodMenu.add(imMenus[i]);
00587 }
00588 };
00589 }
else
00590 mnemonifyMenu(inputMethodMenu,
false);
00591 updateIMMenu();
00592 };
00593
00594 public void createWebPageMenu(
InputManager.WebPage wp[]) {
00595 JMenuItem webPageMenuItems[] =
new JMenuItem[wp.length];
00596
00597 JMenu wpMenus[] =
new JMenu[27];
00598
char h[] =
new char[1];
00599
boolean createSubMenus = (wp.length>20);
00600
00601 webPageMenu.removeAll();
00602
00603
for (
int i=0; i<wp.length; i++) {
00604
if (wp[i]==null)
continue;
00605 String screenName = wp[i].getName();
00606 JMenuItem menuItem =
new JMenuItem(screenName);
00607
00608 webPageMenuItems[i] = menuItem;
00609 menuItem.addActionListener((
new ActionListener() {
00610
InputManager.WebPage wp;
00611 ActionListener init(
InputManager.WebPage _wp) {
00612 wp=_wp;
return this; };
00613
public void actionPerformed(ActionEvent e) {
00614 addFKey(
new WebPageFKey(wp));
00615 callWebPage(wp);
00616 }}).init(wp[i]));
00617
00618
00619
00620
if (createSubMenus) {
00621 h[0] = screenName.charAt(0);
00622
int num;
00623 String name;
00624
if (h[0] >=
'A' && h[0] <=
'Z') {
00625 num = h[0]-
'A';
00626 name =
new String(h)+
"...";
00627 }
else if (h[0] >=
'a' && h[0] <=
'z') {
00628 num = h[0]-
'a';
00629 h[0] +=
'A'-
'a';
00630 name =
new String(h)+
"...";
00631 }
else {
00632 num = 26;
00633 name =
"others (*)";
00634 }
00635
if (wpMenus[num]==null)
00636 wpMenus[num] =
new JMenu(name);
00637 wpMenus[num].add(menuItem);
00638 }
else {
00639 webPageMenu.add(menuItem);
00640 }
00641 }
00642
if (createSubMenus) {
00643
for (
int i=0; i<27; i++) {
00644
if (wpMenus[i]==null)
continue;
00645 wpMenus[i].setMnemonic((i<26)?(
'A'+i):
'*');
00646 mnemonifyMenu(wpMenus[i],
true);
00647 webPageMenu.add(wpMenus[i]);
00648 };
00649 }
else
00650 mnemonifyMenu(webPageMenu,
false);
00651 };
00652
00653 public void groupStateChanged(String name,
boolean active) {
00654
FKey fkey =
new GroupFKey(name);
00655
if (active) currentDocumentation = inputManager.getGroup(name);
00656 addFKey(fkey);
00657 updateFKeys();
00658 updateIMMenu();
00659 }
00660
00661 public void updateIMMenu() {
00662
if (inputMethodMenuItems==null)
return;
00663
for (
int i=0; i<inputMethodMenuItems.length; i++) {
00664 JCheckBoxMenuItem item = inputMethodMenuItems[i];
00665
if (item==null)
continue;
00666 String name = inputMethodMenuItemNames[i];
00667 item.setSelected(inputManager.isInputMethodActive(name));
00668 }
00669 }
00670
00671 void applyProperties() {
00672
try {
00673 properties = context.getProperties(
new String[] {
"config",
"font",
"text" });
00674 }
catch (UnsupportedOperationException e) {
00675 properties =
new Properties();
00676 }
00677
00678 String paramConfig = properties.getProperty(
"config",
"config.inp.gz");
00679
try {
00680 URL configURL;
00681
try {
00682 configURL =
new URL(context.getDocumentBase(),paramConfig);
00683 }
catch (UnsupportedOperationException e) {
00684 configURL =
new URL(paramConfig);
00685 };
00686 inputManager.loadConfig(configURL);
00687 }
catch (Exception e) {
00688 e.printStackTrace();
00689 showMessage(
"While trying to load initial config file "+
00690 paramConfig+
":\n"+e);
00691 }
00692
00693 String defaultFont = properties.getProperty
00694 (
"font",
"Arial Unicode MS, Code2000, Bitstream Cyberbit");
00695
if (defaultFont!=null) {
00696 String fontList = defaultFont;
00697
boolean fontLoaded =
false;
00698 StringBuffer errors =
new StringBuffer();
00699
while (fontList!=null && !fontLoaded) {
00700 String font;
00701
int index = fontList.indexOf(
',');
00702
if (index==-1) {
00703 font = fontList.trim();
00704 fontList = null;
00705 }
else {
00706 font = fontList.substring(0,index).trim();
00707 fontList = fontList.substring(index+1).trim();
00708 }
00709
00710
try {
00711 setInputFont(font);
00712 fontLoaded =
true;
00713 }
catch (RuntimeException e) {
00714 errors.append(e.getMessage());
00715 errors.append(
'\n');
00716 }
00717 }
00718
if (!fontLoaded) {
00719 System.out.println(
"Could not load default font "+
00720 defaultFont+
":");
00721 System.out.print(errors); }
00722 }
00723
00724 String initialText = properties.getProperty(
"text");
00725
if (initialText!=null) {
00726 inputField.setText(initialText);
00727 }
00728 }
00729
00735 public static void mnemonifyMenu(JMenu menu,
boolean override) {
00736
final int maxCharCode = 127;
00737 Component components[] = menu.getMenuComponents();
00738
00739 HashSet usedMnemonics =
new HashSet();
00740
if (!override) {
00741
for (
int i=0; i<components.length; i++) {
00742
if (!(components[i] instanceof JMenuItem))
continue;
00743 JMenuItem item = (JMenuItem)components[i];
00744
int mnemonic = item.getMnemonic();
00745
if (mnemonic==KeyEvent.VK_UNDEFINED)
continue;
00746 usedMnemonics.add(
new Integer(mnemonic));
00747 }
00748 }
00749
for (
int i=0; i<components.length; i++) {
00750
00751
if (!(components[i] instanceof JMenuItem))
continue;
00752 JMenuItem item = (JMenuItem)components[i];
00753
if (item instanceof JMenu) mnemonifyMenu((JMenu)item,override);
00754
if (!override && item.getMnemonic()!=KeyEvent.VK_UNDEFINED)
00755
continue;
00756 String text = item.getText().toUpperCase();
00757
int strLen = text.length();
00758
for (
int j=0; j<=strLen; j++) {
00759
if (j==strLen) {
00760 item.setMnemonic(KeyEvent.VK_UNDEFINED);
break; }
00761
char c = text.charAt(j);
00762
if (c<=maxCharCode) {
00763 item.setMnemonic(c);
00764
int mnemonic = item.getMnemonic();
00765
if (!usedMnemonics.contains(
new Integer(mnemonic))) {
00766 usedMnemonics.add(
new Integer(mnemonic));
00767
break;
00768 }
00769 }
00770 }
00771 }
00772 }
00773
00774 final static int PERMISSION_READ = 1;
00775 final static int PERMISSION_WRITE = 2;
00776 final static int PERMISSION_PRINT = 3;
00777 final static int PERMISSION_EXIT = 4;
00778 boolean checkPossiblePermission(
int permission) {
00779 SecurityManager securityManager;
00780
switch (permission) {
00781
case PERMISSION_READ:
00782 File roots[] = File.listRoots();
00783
return (roots!=null && roots.length>0);
00784
case PERMISSION_WRITE:
00785 securityManager = System.getSecurityManager();
00786
if (securityManager==null)
return true;;
00787 roots = File.listRoots();
00788
if (roots!=null) {
00789
for (
int i=0; i<roots.length; i++) {
00790
try {
00791 securityManager.checkWrite(roots[i].toString());
00792
return true;
00793 }
catch (SecurityException e) {};
00794 }
00795 }
00796
return false;
00797
case PERMISSION_PRINT:
00798
00799
00800
return true;
00801
00802
00803
00804
00805
00806
00807
case PERMISSION_EXIT:
00808
try {
00809 securityManager = System.getSecurityManager();
00810
if (securityManager != null) securityManager.checkExit(0);
00811
return true;
00812 }
catch (SecurityException e) {};
00813
return false;
00814
default:
00815
throw new IllegalArgumentException
00816 (
"Internal Error: Unknown permission "+permission);
00817 }
00818 }
00819
00820 void initMenu() {
00821 SecurityManager securityManager = System.getSecurityManager();
00822 JMenuBar menuBar =
new JMenuBar();
00823 JMenuItem menuItem = null;
00824 JMenu subMenu = null;
00825 JMenu menu = null;
00826
00827 menu =
new JMenu(
"File");
00828 menu.setMnemonic(KeyEvent.VK_F);
00829
boolean emptyMenu =
true;
00830
00831
00832
if (checkPossiblePermission(PERMISSION_READ)) {
00833 menuItem =
new JMenuItem(
"Open...");
00834 menuItem.setMnemonic(KeyEvent.VK_O);
00835 menuItem.addActionListener(
new ActionListener() {
00836
public void actionPerformed(ActionEvent e) {
00837
try {
00838 initFileChooser(); fileChooser.setSelectedFile(currentFile);
00839
if (fileChooser.showDialog(
FileChooser.MODE_OPEN)
00840 == JFileChooser.APPROVE_OPTION)
00841 openFile(fileChooser.getSelectedFile(),
00842 fileChooser.getEncoding(),
00843 fileChooser.getOptionInsert(),
00844 fileChooser.getOptionAsInput());
00845 }
catch (Exception ex) {
00846 ex.printStackTrace();
00847 showMessage(
"Could not open file: "+ex); }
00848 }});
00849 menu.add(menuItem);
00850
00851 emptyMenu =
false;
00852 }
00853
00854
if (checkPossiblePermission(PERMISSION_WRITE)) {
00855
00856 menuItem =
new JMenuItem(
"Save as...");
00857 menuItem.setMnemonic(KeyEvent.VK_A);
00858 menuItem.addActionListener(
new ActionListener() {
00859
public void actionPerformed(ActionEvent e) {
00860
try {
00861 initFileChooser(); fileChooser.setSelectedFile(currentFile);
00862
if (fileChooser.showDialog(
FileChooser.MODE_SAVE)
00863 == JFileChooser.APPROVE_OPTION)
00864 saveFile(fileChooser.getSelectedFile(),
00865 fileChooser.getEncoding(),
00866 fileChooser.getOptionSaveSelection());
00867 }
catch (Exception ex) {
00868 ex.printStackTrace();
00869 showMessage(
"Could not open file: "+ex); }
00870 }});
00871 menu.add(menuItem);
00872 emptyMenu =
false;
00873 }
00874
00875
if (checkPossiblePermission(PERMISSION_READ)) {
00876
00877 menuItem =
new JMenuItem(
"Load config...");
00878 menuItem.setMnemonic(
'l');
00879 menuItem.addActionListener(
new ActionListener() {
00880
public void actionPerformed(ActionEvent e) {
00881
try {
00882 initFileChooser(); fileChooser.setSelectedFile(null);
00883
if (fileChooser.showDialog(
FileChooser.MODE_LOAD)
00884 == JFileChooser.APPROVE_OPTION)
00885 loadConfig(fileChooser.getSelectedFile());
00886 }
catch (Exception ex) {
00887 ex.printStackTrace();
00888 showMessage(
"Could not open file: "+ex); }
00889 }});
00890 menu.add(menuItem);
00891 emptyMenu =
false;
00892 }
00893
00894
if (checkPossiblePermission(PERMISSION_PRINT)) {
00895
if (!emptyMenu) menu.add(
new JSeparator());
00896
00897
00898 menuItem =
new JMenuItem(
"Print...");
00899 menuItem.setMnemonic(
'p');
00900 menuItem.addActionListener(
new ActionListener() {
00901
public void actionPerformed(ActionEvent e) {
00902
try {
00903
if (printerJob==null) {
00904 printerJob = PrinterJob.getPrinterJob();
00905 pageFormat = printerJob.defaultPage(); }
00906
00907
PrintableText job =
00908
new PrintableText(getSelected(),
00909 inputField.getFont());
00910 printerJob.setPrintable(job,pageFormat);
00911
if (printerJob.printDialog()) {
00912 printerJob.print();
00913 }
00914 }
catch (Exception ex) {
00915 ex.printStackTrace();
00916 showMessage(
"Could not print: "+ex);
00917 }
00918 }});
00919 menu.add(menuItem);
00920
00921
00922 menuItem =
new JMenuItem(
"Page setup...");
00923 menuItem.setMnemonic(
'u');
00924 menuItem.addActionListener(
new ActionListener() {
00925
public void actionPerformed(ActionEvent e) {
00926
try {
00927
if (printerJob==null) {
00928 printerJob = PrinterJob.getPrinterJob();
00929 pageFormat = printerJob.defaultPage(); }
00930 pageFormat = printerJob.pageDialog(pageFormat);
00931 }
catch (Exception ex) {
00932 ex.printStackTrace();
00933 showMessage(
"Could not change page format: "+ex);
00934 }
00935 }});
00936 menu.add(menuItem);
00937
00938
00939 menuItem =
new JMenuItem(
"Print preview");
00940 menuItem.setMnemonic(
'v');
00941 menuItem.addActionListener(
new ActionListener() {
00942
public void actionPerformed(ActionEvent e) {
00943
try {
00944
if (printerJob==null) {
00945 printerJob = PrinterJob.getPrinterJob();
00946 pageFormat = printerJob.defaultPage(); }
00947
PrintableText job =
00948
new PrintableText(getSelected(),
00949 inputField.getFont());
00950 previewFrame = job.
showPreview(previewFrame,pageFormat);
00951 }
catch (Exception ex) {
00952 ex.printStackTrace();
00953 showMessage(
"Could not show print preview: "+ex);
00954 }
00955 }});
00956 menu.add(menuItem);
00957
00958 emptyMenu =
false;
00959 }
00960
00961
boolean mayExit =
true;
00962
try {
00963 mayExit = context.isExitAllowed();
00964 }
catch (UnsupportedOperationException e) {};
00965
if (mayExit &&
00966 checkPossiblePermission(PERMISSION_EXIT)) {
00967
00968
if (!emptyMenu) menu.add(
new JSeparator());
00969 menuItem =
new JMenuItem(
"Exit");
00970 menuItem.setMnemonic(KeyEvent.VK_X);
00971 menuItem.addActionListener(
new ActionListener() {
00972
public void actionPerformed(ActionEvent e) {
00973
try {
00974 System.exit(0);
00975 }
catch (Exception ex) {
00976 ex.printStackTrace();
00977 showMessage(
"Could not open file: "+ex); }
00978 }});
00979 menu.add(menuItem);
00980 emptyMenu =
false;
00981 }
00982
00983
00984
if (!emptyMenu) menuBar.add(menu);
00985
00986 menu =
new JMenu(
"Edit");
00987 menu.setMnemonic(KeyEvent.VK_E);
00988 menuBar.add(menu);
00989
00990
00991 menuItem =
new JMenuItem(
"Copy");
00992 menuItem.setMnemonic(KeyEvent.VK_C);
00993 menuItem.addActionListener(
new ActionListener() {
00994
public void actionPerformed(ActionEvent e) {
00995 copyText(
false);
00996 }});
00997 menu.add(menuItem);
00998
00999
01000 menuItem =
new JMenuItem(
"Paste");
01001 menuItem.setMnemonic(KeyEvent.VK_P);
01002 menuItem.addActionListener(
new ActionListener() {
01003
public void actionPerformed(ActionEvent e) {
01004 pasteText(
false);
01005 }});
01006 menu.add(menuItem);
01007
01008
01009 menuItem =
new JMenuItem(
"Paste as input");
01010 menuItem.setMnemonic(KeyEvent.VK_I);
01011 menuItem.addActionListener(
new ActionListener() {
01012
public void actionPerformed(ActionEvent e) {
01013 pasteText(
true);
01014 }});
01015 menu.add(menuItem);
01016
01017
01018 menuItem =
new JMenuItem(
"Clear");
01019 menuItem.setMnemonic(KeyEvent.VK_L);
01020 menuItem.addActionListener(
new ActionListener() {
01021
public void actionPerformed(ActionEvent e) {
01022 clearText();
01023 }});
01024 menu.add(menuItem);
01025
01026 inputMethodMenu =
new JMenu(
"Input method");
01027 inputMethodMenu.setMnemonic(KeyEvent.VK_I);
01028 menuBar.add(inputMethodMenu);
01029
01030 webPageMenu =
new JMenu(
"Web page");
01031 webPageMenu.setMnemonic(KeyEvent.VK_W);
01032 menuBar.add(webPageMenu);
01033
01034 menu =
new JMenu(
"Font");
01035 menu.setMnemonic(KeyEvent.VK_O);
01036 menuBar.add(menu);
01037
01038
01039 menuItem =
new JMenuItem(
"Select best (!)");
01040 menuItem.setMnemonic(
'!');
01041 menuItem.addActionListener(
new ActionListener() {
01042
public void actionPerformed(ActionEvent e) {
01043 String name = autoSetFont(getSelected(),
false);
01044 String info;
01045
if (name==null) {
01046 info =
"Font not changed ("+
01047 inputField.getFont().getFamily()+
")";
01048 }
else {
01049 info =
"Font changed to "+name;
01050 }
01051 showMessage(info);
01052 }});
01053 menu.add(menuItem);
01054
01055
01056 menuItem =
new JCheckBoxMenuItem(
"Auto select (@)",
false);
01057 menuItem.setMnemonic(
'@');
01058 menuItem.addActionListener(
new ActionListener() {
01059
public void actionPerformed(ActionEvent e) {
01060 JCheckBoxMenuItem item = (JCheckBoxMenuItem)e.getSource();
01061 setAutoSetFont(item.isSelected());
01062 }});
01063 menu.add(menuItem);
01064
01065
01066 subMenu =
new JMenu(
"Font Viewer (?)");
01067 subMenu.setMnemonic(
'?');
01068 menu.add(subMenu);
01069
01070
01071 menuItem =
new JMenuItem(
"All fonts (sample)");
01072 menuItem.setMnemonic(
'a');
01073 menuItem.addActionListener(
new ActionListener() {
01074
public void actionPerformed(ActionEvent e) {
01075
new FontViewer().showSample(getSelected());
01076 }});
01077 subMenu.add(menuItem);
01078
01079
01080 menuItem =
new JMenuItem(
"Current font (repertoire)");
01081 menuItem.setMnemonic(
'c');
01082 menuItem.addActionListener(
new ActionListener() {
01083
public void actionPerformed(ActionEvent e) {
01084
new FontViewer().showFont
01085 (inputField.getFont().getFamily());
01086 }});
01087 subMenu.add(menuItem);
01088
01089
01090 subMenu =
new JMenu(
"Size (=)");
01091 subMenu.setMnemonic(
'=');
01092 menu.add(subMenu);
01093
01094
01095 menuItem =
new JMenuItem(
"Larger");
01096 menuItem.setMnemonic(KeyEvent.VK_L);
01097 menuItem.addActionListener(
new ActionListener() {
01098
public void actionPerformed(ActionEvent e) {
01099 setFontSize(getFontSize()+FONT_SIZE_STEPPING);
01100 }});
01101 subMenu.add(menuItem);
01102
01103
01104 menuItem =
new JMenuItem(
"Smaller");
01105 menuItem.setMnemonic(KeyEvent.VK_S);
01106 menuItem.addActionListener(
new ActionListener() {
01107
public void actionPerformed(ActionEvent e) {
01108
int size = getFontSize()-FONT_SIZE_STEPPING;
01109
if (size<=0) size = 1;
01110 setFontSize(size);
01111 }});
01112 subMenu.add(menuItem);
01113
01114 subMenu.add(
new JSeparator());
01115
01116
01117 ButtonGroup buttonGroup =
new ButtonGroup();
01118 fontSizeMenuItems =
new JMenuItem[MAX_FONT_SIZE+1];
01119
for (
int i=MIN_FONT_SIZE; i<=MAX_FONT_SIZE; i+=FONT_SIZE_STEPPING) {
01120 menuItem =
new JRadioButtonMenuItem(
""+i);
01121 subMenu.add(menuItem);
01122 buttonGroup.add(menuItem);
01123 menuItem.addActionListener((
new ActionListener() {
01124
int size = 0;
01125 ActionListener setSize(
int s) { size = s;
return this; };
01126
public void actionPerformed(ActionEvent e) {
01127 setFontSize(size);
01128 }}).setSize(i));
01129 fontSizeMenuItems[i] = menuItem;
01130 }
01131 buttonGroup.add(noSizeItem);
01132
01133 menu.add(
new JSeparator());
01134
01135
char h[] =
new char[1];
01136 JMenu fontMenus[] =
new JMenu[27];
01137 buttonGroup =
new ButtonGroup();
01138 fonts = getAvailableFontFamilyNames();
01139 fontMenuItems =
new JMenuItem[fonts.length];
01140
for (
int i=0; i<fonts.length; i++) {
01141
if (fonts[i].length()==0)
continue;
01142 menuItem =
new JRadioButtonMenuItem(fonts[i]);
01143 buttonGroup.add(menuItem);
01144 menuItem.setActionCommand(fonts[i]);
01145 menuItem.addActionListener(
new ActionListener() {
01146
public void actionPerformed(ActionEvent e) {
01147
try {
01148 setInputFont(e.getActionCommand());
01149 showMessage(
"Font changed to "+
01150 e.getActionCommand());
01151 }
catch (IllegalArgumentException e1) {
01152 showMessage(
"Font not changed: "+e1.getMessage());
01153 }
01154 }});
01155 h[0] = fonts[i].charAt(0);
01156
int num;
01157 String name;
01158
if (h[0] >=
'A' && h[0] <=
'Z') {
01159 num = h[0]-
'A';
01160 name =
new String(h)+
"...";
01161 }
else if (h[0] >=
'a' && h[0] <=
'z') {
01162 num = h[0]-
'a';
01163 h[0] +=
'A'-
'a';
01164 name =
new String(h)+
"...";
01165 }
else {
01166 num = 26;
01167 name =
"others (*)";
01168 }
01169
if (fontMenus[num]==null)
01170 fontMenus[num] =
new JMenu(name);
01171 fontMenus[num].add(menuItem);
01172 fontMenuItems[i] = menuItem;
01173 }
01174
for (
int i=0; i<27; i++) {
01175
if (fontMenus[i]==null)
continue;
01176 fontMenus[i].setMnemonic((i<26)?(
'A'+i):
'*');
01177
01178 mnemonifyMenu(fontMenus[i],
true);
01179 menu.add(fontMenus[i]);
01180 };
01181 buttonGroup.add(noFontItem);
01182
01183 menuBar.add(Box.createHorizontalGlue());
01184 menu =
new JMenu(
"Help");
01185 menu.setMnemonic(KeyEvent.VK_H);
01186 menuBar.add(menu);
01187
01188
01189 menuItem =
new JMenuItem(
"General");
01190 menuItem.setMnemonic(KeyEvent.VK_G);
01191 menuItem.addActionListener(
new ActionListener() {
01192
public void actionPerformed(ActionEvent e) {
01193 showHelp();
01194 }});
01195 menu.add(menuItem);
01196
01197
01198 menuItem =
new JMenuItem(
"Current object");
01199 menuItem.setMnemonic(
'c');
01200 menuItem.addActionListener(
new ActionListener() {
01201
public void actionPerformed(ActionEvent e) {
01202 showCurrentDocumentation();
01203 }});
01204 menu.add(menuItem);
01205
01206
try {
01207 context.addMenuBar(menuBar);
01208 }
catch (UnsupportedOperationException e) {
01209 System.out.println(
"Cannot add menu bar: "+e.getMessage()); }
01210 }
01211
01212 String[] getAvailableFontFamilyNames() {
01213 Font fonts[] = GraphicsEnvironment.getLocalGraphicsEnvironment().getAllFonts();
01214 TreeSet set =
new TreeSet();
01215
for (
int i=0; i<fonts.length; i++) {
01216 String fam = fonts[i].getFamily();
01217
if (fam.endsWith(
".bold"))
continue;
01218
if (fam.endsWith(
".bolditalic"))
continue;
01219
if (fam.endsWith(
".italic"))
continue;
01220 set.add(fonts[i].getFamily());
01221 }
01222 String fn[] =
new String[set.size()];
01223 Iterator it=set.iterator();
01224
for (
int i=0; it.hasNext(); i++) {
01225 fn[i] = (String)it.next();
01226
01227 }
01228
return fn;
01229 }
01230
01231 void initFileChooser() {
01232
if (fileChooser==null) {
01233 fileChooser =
new FileChooser(
this);
01234 fileChooser.setCurrentDirectory(
new File(
"."));
01235 }
01236 }
01237
01238 void selectSizeItem(
int size) {
01239 AbstractButton item = null;
01240
if (size<fontSizeMenuItems.length)
01241 item = fontSizeMenuItems[size];
01242
if (item==null) item = noSizeItem;
01243 item.setSelected(
true);
01244 }
01245
01246 void selectFontItem(String name) {
01247
for (
int i=0; i<fonts.length; i++) {
01248
if (fonts[i]==null || fontMenuItems[i]==null ||
01249 !fonts[i].equals(name))
continue;
01250 fontMenuItems[i].setSelected(
true);
01251
return;
01252 }
01253 noFontItem.setSelected(
true);
01254 }
01255
01256 void showHelp() {
01257
try {
01258 context.showDocument
01259 (
new URL(context.getDocumentBase(),
"documentation.html"),
false);
01260 }
catch (Exception e1) {
01261 showMessage(
"Could not display help: "+e1);
01262 e1.printStackTrace();
01263 }
01264 }
01265
01270 public void loadConfig(String config) {
01271
try {
01272 inputManager.loadConfig(
new URL(context.getDocumentBase(),config));
01273 }
catch (Exception e) {
01274 showMessage(
"Loading of "+config+
" failed:\n"+e);
01275 e.printStackTrace();
01276 }
01277 }
01278
01283 public void loadConfig(File config) {
01284
try {
01285 inputManager.loadConfig(config.toURL());
01286 }
catch (Exception e) {
01287 showMessage(
"Loading of "+config+
" failed:\n"+e);
01288 e.printStackTrace();
01289 }
01290 }
01291
01296 public void loadConfigString(String config)
throws IOException {
01297 System.out.println(
"InternationalInput::loadConfigString("+config+
")");
01298
try {
01299 inputManager.loadConfigString(config);
01300 }
catch (Exception e) {
01301 showMessage(
"Executing config string failed:\n"+e);
01302 }
01303 }
01304
01308 public String getSelected() {
01309 breakComposition();
01310 String text = inputField.getSelectedText();
01311
if (text==null) text = inputField.getText();
01312
try {
01313
if (text!=null)
01314 text =
Normalizer.normalize(
Normalizer.C,text);
01315 }
catch (IOException e) {
01316 showMessage(
"Normalization not possible: "+e);
01317 e.printStackTrace();
01318 }
01319
return text;
01320 }
01321
01322 public boolean hasSelection() {
01323
return (inputField.getSelectionStart()!=inputField.getSelectionEnd());
01324 }
01325
01326
01327
01328
01329
01330
01331
01332
01333
01334
01335
01336
01337
01338
01342 public void noButtons() {
01343 disableButtons =
true;
01344
if (buttons==null)
return;
01345 remove(buttons);
01346 buttons = null;
01347 revalidate();
01348 }
01353 public String getDocumentation(String group) {
01354
try {
01355
return inputManager.getGroup(group).getDocumentation();
01356 }
catch (IOException e) {
01357 e.printStackTrace();
01358
return "Could not load documentation for "+group;
01359 }
01360 }
01361
01364 public String getCurrentDocumentation() {
01365
try {
01366
return currentDocumentation.getDocumentation();
01367 }
catch (Exception e) {
01368 e.printStackTrace();
01369 showMessage(
"Could not load documentation for "+
01370 currentDocumentation.getFullDocuName()+
": "+e);
01371
return "Could not load documentation for "+
01372 currentDocumentation.getFullDocuName()+
": "+e;
01373 }
01374 }
01375
01376 public void showCurrentDocumentation() {
01377
try {
01378 context.showDocumentFromString
01379 (currentDocumentation.getDocumentation());
01380 }
catch (Exception e) {
01381 e.printStackTrace();
01382 showMessage(
"Could not show documentation for "+
01383 currentDocumentation.getFullDocuName()+
": "+e);
01384 }
01385 }
01386
01387
01391
01392
01393
01394
01397
01398
01399
01400
01403 public void ready() {
01404 inputField.requestFocus();
01405 setFontSize(DEFAULT_FONT_SIZE);
01406 }
01407
01408
01409 public void mouseExited(MouseEvent e) { checkCaret(); };
01410 public void mouseEntered(MouseEvent e) { checkCaret(); };
01411 public void mouseClicked(MouseEvent e) { checkCaret(); };
01412 public void mousePressed(MouseEvent e) { checkCaret(); };
01413 public void mouseReleased(MouseEvent e) { checkCaret(); };
01414
01415
01416
01417
01418 public void textWindow(String text) {
01419
try {
01420 URL url;
01421
try {
01422 url =
new URL(context.getDocumentBase(),
01423
"reflect/"+
InputManager.urlEncode(text));
01424 }
catch (MalformedURLException e) {
01425 e.printStackTrace();
01426
throw new RuntimeException(e.getMessage());
01427 }
01428 System.out.println(
"Text: "+text);
01429 System.out.println(
"URL: "+url);
01430 context.showDocument(url,
false);
01431 }
catch (UnsupportedOperationException e) {
01432 showMessage(
"Copying impossible: "+e.getMessage());
01433 }
01434 }
01435 private void initClipboard() {
01436
if (noSystemClipboard)
return;
01437
01438
try {
01439 clipboard = getToolkit().getSystemClipboard();
01440 }
catch (SecurityException e) {
01441 noSystemClipboard =
true;
01442 clipboard =
new Clipboard(
"local");
01443 }
01444 }
01445 public String copyText(
boolean dontUseTextWindow) {
01446 initClipboard();
01447 String text = getSelected();
01448 clipboard.setContents(
new StringSelection(text),null);
01449
if (noSystemClipboard && !dontUseTextWindow) textWindow(text);
01450
return text;
01451 }
01456 public void setClipboardContent(String data) {
01457 initClipboard();
01458 clipboard.setContents(
new StringSelection(data),null);
01459 }
01460
01461 public void pasteText(
boolean temporary) {
01462 initClipboard();
01463 String text;
01464 Transferable data = clipboard.getContents(clipboard);
01465
if (data==null) {
01466 showMessage(noSystemClipboard?
01467
"Local clipboard is empty (system clipboard not accessible)":
01468
"Clipboard is empty");
01469
return; }
01470
01471
try {
01472 text = (String)data.getTransferData
01473 (DataFlavor.stringFlavor);
01474 }
catch (UnsupportedFlavorException ee) {
01475 showMessage(
"Clipboard not readable: "+ee);
01476
return;
01477 }
catch (IOException ee) {
01478 showMessage(
"Clipboard not readable: "+ee);
01479
return;
01480 }
01481
01482
if (temporary) {
01483 inputManager.input(
InputManager.SOURCE_CLIPBOARD,
01484 text);
01485 }
else {
01486 breakComposition();
01487 inputField.addFinal(text);
01488 }
01489 }
01490
01491 public void keyTyped(KeyEvent e) {};
01492 public void keyPressed(KeyEvent e) {};
01493 public void keyReleased(KeyEvent e) {
01494
if (checkFKeyHotKey(e.getKeyCode()))
01495 e.consume();
01496
if (e.getKeyCode()==KeyEvent.VK_F1) {
01497 showHelp(); e.consume(); }
01498 };
01499 public void breakComposition() {
01500 inputManager.input(
InputManager.SOURCE_KEYBOARD,
01501
InputManager.INPUT_BREAK);
01502 }
01503 void callWebPage(
InputManager.WebPage webpage) {
01504
try {
01505 currentDocumentation = webpage;
01506 URL result = webpage.run(getSelected());
01507 System.out.println(
"Webpage: "+result);
01508 context.showDocument(result,webpage.getNeedsTopFrame());
01509 }
catch (Exception ex) {
01510 showMessage(
"Could not create URL: "+ex);
01511 ex.printStackTrace();
01512 }
01513 }
01514
01524 public String autoSetFont(String str,
boolean lazy) {
01525 Font current = getFont();
01526
if (str==null) str =
"";
01527
int upto = current.canDisplayUpTo(str.replace(
'\n',
' '));
01528
boolean canDisplayStr = (upto == -1 || upto == str.length());
01529
01530
if (canDisplayStr && lazy)
return null;
01531 String content = inputField.getText();
01532 upto = current.canDisplayUpTo(content.replace(
'\n',
' '));
01533
boolean canDisplayContent = (upto == -1 || upto == content.length());
01534
if (canDisplayStr && canDisplayContent)
return null;
01535
01536 System.out.println(
"autoSetFont("+str+
","+lazy+
") searches...");
01537 String[] fontNames = GraphicsEnvironment.getLocalGraphicsEnvironment().
01538 getAvailableFontFamilyNames();
01539
01540 Font[] fonts =
new Font[fontNames.length];
01541 FontRenderContext frc =
01542 ((Graphics2D)getGraphics()).getFontRenderContext();
01543
for (
int i=0; i<fontNames.length; i++) {
01544
if (fontNames[i]==null || fontNames[i].length()==0)
continue;
01545 fonts[i] =
new Font(fontNames[i],Font.PLAIN,fontSize);
01546 Rectangle2D rect = fonts[i].getStringBounds(content,frc);
01547
01548
if (rect.getWidth() < 1 || rect.getHeight() < 1) fonts[i] = null;
01549 }
01550
int best0 = -1, best1 = -1, best2 = 0;
01551 String best = current.getFamily();
01552
01553
for (
int fontnum=0; fontnum<fonts.length; fontnum++) {
01554 Font font = fonts[fontnum];
01555
if (font==null)
continue;
01556
int q0 = 0, q1 = 0, q2 = 0;
01557
if (font.getFamily().equals(current.getFamily())) q2 = 1;
01558
for (
int i=0; i<str.length(); i++) {
01559
char c = str.charAt(i);
01560
if (c!=
' ' && c!=
'\t' && c!=
'\n')
01561
if (font.canDisplay(c)) q0++; };
01562
for (
int i=0; i<content.length(); i++) {
01563
char c = content.charAt(i);
01564
if (c!=
' ' && c!=
'\t' && c!=
'\n')
01565
if (font.canDisplay(c)) q1++; };
01566
if (q0>best0 ||
01567 (q0==best0 && (q1>best1 ||
01568 (q1==best1 && q2>best2)))) {
01569 best = font.getFamily();
01570 best0 = q0; best1 = q1; best2 = q2;
01571 }
01572 }
01573
01574
if (best.equals(current.getFamily()))
return null;
01575 setInputFont(best);
01576
return best;
01577 }
01578
01579 public void setAutoSetFont(
boolean on) {
01580 autoSetFont = on;
01581
if (autoSetFont) autoSetFont(inputField.temporaryInput,
true);
01582 }
01586 public void setFontSize(
int size) {
01587 fontSize = size;
01588 inputField.setFont(inputField.getFont().deriveFont(Font.PLAIN,size));
01589 selectSizeItem(size);
01590 };
01591
01594 public int getFontSize() {
01595
return fontSize; };
01596
01600 public void setInputFont(String fontName) {
01601 Font oldFont = inputField.getFont();
01602 Font newFont =
new Font(fontName,Font.PLAIN,fontSize);
01603
if (!newFont.getFamily().equals(fontName)) {
01604 selectFontItem(oldFont.getFamily());
01605
throw new IllegalArgumentException
01606 (
"No such font: "+fontName); }
01607 System.out.println(
"New font: "+newFont);
01608 inputField.setFont(newFont);
01609 selectFontItem(fontName);
01610 }
01611
01612 public void clearText() {
01613 inputManager.input(
InputManager.SOURCE_GUI,
01614
InputManager.INPUT_BREAK);
01615
try {
01616 inputField.document.remove
01617 (0,inputField.document.getLength());
01618 }
catch (BadLocationException e) {
01619 inputField.setText(
"");
01620 }
01621 };
01622
01623 private static final Hashtable iconify_iconHash =
new Hashtable();
01624 Icon iconify_getIcon(
int cp) {
01625
01626 Icon icon =
01627 (Icon)iconify_iconHash.get(
new Integer(cp));
01628
if (icon!=null)
return icon;
01629 String name;
01630
switch (cp) {
01631
case 0x1B: name =
"ESC";
break;
01632
case 0x200E: name =
"LRM";
break;
01633
case 0x200F: name =
"RLM";
break;
01634
case 0x200B: name =
"ZWSP";
break;
01635
case 0x200C: name =
"ZWNJ";
break;
01636
case 0x200D: name =
"ZWJ";
break;
01637
case 0x2028: name =
"LSEP";
break;
01638
case 0x2029: name =
"PSEP";
break;
01639
case 0x202A: name =
"LRE";
break;
01640
case 0x202B: name =
"RLE";
break;
01641
case 0x202C: name =
"PDF";
break;
01642
case 0x202D: name =
"LRO";
break;
01643
case 0x202E: name =
"RLO";
break;
01644
case 0xFFFD: name =
"?";
break;
01645
01646
default:
01647 name =
"U+"+Integer.toHexString(cp).toUpperCase();
01648 }
01649
01650 icon =
new TextIcon(name,
this,
new Color(165,42,42));
01651 iconify_iconHash.put(
new Integer(cp),icon);
01652
return icon;
01653 }
01654
01655
01656
01657
01658
01659
01660
01661
01662
01663
01664
01665
01666
01667
01668
01669
01670
01671
01672
01673
01674
01675
01676
01677
01678
01679
01680
01681
01682
01683
01684
01685
01686
01687
01688
01689
01690
01691
01692 public void keyStroke(ActionEvent e) {
01693 checkCaret();
01694 String stroke = e.getActionCommand();
01695
char c =
'\000';
01696
if (stroke.length()==1) c = stroke.charAt(0);
01697
switch (c+
'A'-1) {
01698
01699
case 'A':
case 'B':
case 'C':
case 'D':
case 'E':
01700
case 'F':
case 'H':
case 'I':
case 'K':
01701
case 'L':
case 'M':
case 'N':
case 'O':
case 'P':
01702
case 'Q':
case 'R':
case 'S':
case 'T':
case 'U':
01703
case 'V':
case 'W':
case 'X':
case 'Z':
01704 System.out.println(
"^"+(
char)(c+
'A'-1)+
" pressed, ignoring.");
01705
return;
01706
case 'G':
01707 stroke =
InputManager.INPUT_BREAK;
01708
break;
01709
default:
01710
switch (c) {
01711
case '\377':
01712 System.out.println(
"DEL pressed, ignoring.");
01713
return;
01714 }
01715 }
01716 inputManager.input(
InputManager.SOURCE_KEYBOARD,stroke);
01717 }
01718 public void backSpace() {
01719 inputManager.input(
InputManager.SOURCE_KEYBOARD,
01720
InputManager.INPUT_BACKSPACE);
01721 }
01722
01723 void normalize() {
01724
try {
01725 normalize(0,inputField.getText().length());
01726 }
catch (BadLocationException e) {
01727 e.printStackTrace();
01728
throw new RuntimeException(
"Internal error: "+e);
01729 }}
01730
01731 int normalize(
int from,
int upto)
throws BadLocationException {
01732
try {
01733 String preCaret = inputField.getText(0,upto);
01734
01735 StringBuffer target =
new StringBuffer();
01736 from =
Normalizer.normalize(
Normalizer.C,preCaret,from,upto,target);
01737
01738
if (target.length()!=0)
01739 inputField.replaceRange(target.toString(),from,upto);
01740 }
catch (IOException e) {
01741 System.out.println(
"Normalization not possible: "+e);
01742 }
01743
return from;
01744 }
01745
01746
01747 void iconify() {
01748
try {
01749 iconify(0,inputField.document.getLength());
01750 }
catch (BadLocationException e) {
01751 e.printStackTrace();
01752
throw new RuntimeException(
"Internal error: "+e);
01753 }
01754 };
01755
01756 int iconify_tempColor = 0;
01757 void iconify(
int from,
int upto)
throws BadLocationException {
01758
01759
int len = upto-from;
01760 String str = inputField.document.getText(from,len);
01761 SimpleAttributeSet noStyle =
new SimpleAttributeSet();
01762 StringBuffer normalText =
new StringBuffer();
01763
int doneUpto = 0;
01764
try {
01765 inputField.document.remove(from,len);
01766 }
catch (BadLocationException e) {
01767 e.printStackTrace();
return; }
01768
for (
int i=0; i<len; i++) {
01769
char c = str.charAt(i);
01770
boolean isControl =
false;
01771
01772
01773
switch (Character.getType(c)) {
01774
case Character.CONTROL:
01775
case Character.FORMAT:
01776
case Character.LINE_SEPARATOR:
01777
case Character.SPACE_SEPARATOR:
01778
case Character.PARAGRAPH_SEPARATOR:
01779
01780 isControl =
true;
01781 }
01782
switch (c) {
01783
case '\n':
case ' ':
01784 isControl =
false;
break;
01785
case 0xFFFD:
01786 isControl =
true;
break;
01787 }
01788
if (isControl) {
01789
try {
01790 inputField.document.insertString(from+doneUpto,normalText.toString(),noStyle);
01791 normalText.setLength(0); doneUpto = i+1;
01792
01793 SimpleAttributeSet style =
new SimpleAttributeSet();
01794 StyleConstants.setIcon(style,iconify_getIcon(c));
01795
01796
01797 StyleConstants.setForeground
01798 (style,
new Color(iconify_tempColor++));
01799 inputField.document.insertString(from+i,
""+c,style);
01800 }
catch (BadLocationException e) {
01801 e.printStackTrace(); }
01802 }
else {
01803 normalText.append(c);
01804 }
01805 }
01806
try {
01807 inputField.document.insertString(from+doneUpto,normalText.toString(),noStyle);
01808 }
catch (BadLocationException e) {
01809 e.printStackTrace(); }
01810 }
01811
01812
01813 void checkCaret() {
01814
if (noCaretCheck)
return;
01815 noCaretCheck =
true;
01816
int newCaret = inputField.getCaretPosition();
01817
if (newCaret != lastCaret)
01818 inputManager.input(
InputManager.SOURCE_KEYBOARD,
01819
InputManager.INPUT_BREAK);
01820
if (newCaret>inputField.getText().length())
01821 newCaret = inputField.getText().length();
01822
if (newCaret!=inputField.getCaretPosition())
01823 inputField.setCaretPosition(newCaret);
01824 lastCaret = newCaret;
01825 noCaretCheck =
false;
01826 }
01827
01828 void saveFile(File file, String encoding,
boolean selection) {
01829 Writer writer = null;
01830 currentFile = file;
01831
try {
01832 inputManager.input(
InputManager.SOURCE_GUI,
01833
InputManager.INPUT_BREAK);
01834 writer =
01835
new OutputStreamWriter(
new FileOutputStream(file),encoding);
01836 String text = selection?getSelected():inputField.getText();
01837 writer.write(text);
01838 writer.close();
01839 showMessage(
"File "+file+
" written.");
01840
try { context.setTitleInfo(file.getName()); }
01841
catch (UnsupportedOperationException e) {};
01842 }
catch (IOException e) {
01843 e.printStackTrace();
01844 showMessage(
"Could not write to "+file+
": "+e);
01845
try {
if (writer!=null) writer.close(); }
01846
catch (IOException e1) {};
01847 }
01848 }
01849
01850 void openFile(File file, String encoding,
boolean insert,
boolean temporary) {
01851 Reader reader = null;
01852 currentFile = file;
01853
try {
01854 reader =
01855
new InputStreamReader(
new FileInputStream(file),encoding);
01856
if (!temporary) inputManager.input(
InputManager.SOURCE_GUI,
01857
InputManager.INPUT_BREAK);
01858
if (!insert) clearText();
01859
char buff[] =
new char[4096];
01860
while (
true) {
01861
int numread = reader.read(buff);
01862
01863
if (numread==-1)
break;
01864
01865 String sbuff =
new String(buff,0,numread);
01866
if (temporary) {
01867 inputManager.input(
InputManager.SOURCE_FILE,sbuff);
01868 }
else {
01869 breakComposition();
01870 inputField.addFinal(sbuff);
01871 }
01872 }
01873 reader.close();
01874 showMessage(
"File "+file+
" loaded.");
01875
try { context.setTitleInfo(file.getName()); }
01876
catch (UnsupportedOperationException e) {};
01877 }
catch (IOException e) {
01878 e.printStackTrace();
01879 showMessage(
"Could not read from "+file+
": "+e);
01880
try {
if (reader!=null) reader.close(); }
01881
catch (IOException e1) {};
01882 }
01883 }
01884 }