diff --git a/build.xml b/build.xml index 2a02aa7..d3bfbad 100644 --- a/build.xml +++ b/build.xml @@ -51,6 +51,7 @@ subdirectories of ${bin}. --> + @@ -272,11 +273,11 @@ description="JARs up everything into self-contained JARs for double-click, classpath-worry-free joy" /> @@ -309,6 +310,11 @@ + + + + @@ -331,6 +337,30 @@ + + + + + + + + + + + + + + + + + + + + @@ -603,6 +633,18 @@ + + + + + + + + + + diff --git a/source/org/thdl/tib/input/ConvertDialog.java b/source/org/thdl/tib/input/ConvertDialog.java new file mode 100644 index 0000000..ba31859 --- /dev/null +++ b/source/org/thdl/tib/input/ConvertDialog.java @@ -0,0 +1,412 @@ +/* +The contents of this file are subject to the THDL Open Community License +Version 1.0 (the "License"); you may not use this file except in compliance +with the License. You may obtain a copy of the License on the THDL web site +(http://www.thdl.org/). + +Software distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTY OF ANY KIND, either express or implied. See the +License for the specific terms governing rights and limitations under the +License. + +The Initial Developer of this software is the Tibetan and Himalayan Digital +Library (THDL). Portions created by the THDL are Copyright 2003 THDL. +All Rights Reserved. + +Contributor(s): ______________________________________. +*/ + +package org.thdl.tib.input; + +import java.awt.*; +import java.awt.event.*; +import java.io.*; +import java.util.*; +import javax.swing.*; +import javax.swing.event.*; +import javax.swing.filechooser.*; + +import org.thdl.util.*; + +/** A GUI widget used to convert Tibetan documents from one encoding + to another. + + @author Nathaniel Garson, Tibetan and Himalayan Digital Library */ +class ConvertDialog extends JDialog + implements FontConverterConstants +{ + private static final boolean debug = false; + + // Attributes + FontConversion controller; + + Box fileBox, buttonBox; + + JPanel content, choicePanel; + + JComboBox choices; + + JTextField oldTextField, newTextField; + + JButton browseOld, browseNew, convert, cancel, openDoc; + + JLabel type, oldLabel, newLabel; + + String[] choiceNames; + + boolean oldFieldChanged, newFieldChanged; + + JFileChooser jfc; + File oldFile, newFile; + String default_directory; + + final String BROWSENEW = "Browse"; + final String BROWSEOLD = BROWSENEW; + final String CONVERT = "Convert"; + final String CANCEL = "Cancel"; + + private final ThdlActionListener tal = new ThdlActionListener() { + public void theRealActionPerformed(ActionEvent e) { + ConvertDialog.this.theRealActionPerformed(e); + }}; + public void init() + { + default_directory = controller.getDefaultDirectory(); + jfc = new JFileChooser(default_directory); + jfc.setFileFilter(new RTFFileFilter()); + + content = new JPanel(new GridLayout(0,1)); + JPanel temp = new JPanel(new FlowLayout(FlowLayout.CENTER,5,5)); + type = new JLabel("Type of Conversion: "); + temp.add(type); + temp.add(choices); + content.add(temp); + + temp = new JPanel(new FlowLayout(FlowLayout.CENTER,5,5)); + oldLabel = new JLabel("Original File: "); + temp.add(oldLabel); + + oldTextField = new JTextField(25); + oldFieldChanged = false; + oldTextField.addCaretListener(new CaretListener() { + public void caretUpdate(CaretEvent ce) { + oldFieldChanged = true; + } + }); + JPanel tfTemp = new JPanel(); + tfTemp.add(oldTextField); + temp.add(tfTemp); + + browseOld = new JButton(BROWSEOLD); + browseOld.addActionListener(tal); + temp.add(browseOld); + content.add(temp); + + temp = new JPanel(new FlowLayout(FlowLayout.CENTER,5,5)); + newLabel = new JLabel("Converted File: "); + temp.add(newLabel); + + newTextField = new JTextField(25); + newFieldChanged = false; + newTextField.addCaretListener(new CaretListener() { + public void caretUpdate(CaretEvent ce) { + newFieldChanged = true; + } + }); + tfTemp = new JPanel(); + tfTemp.add(newTextField); + temp.add(tfTemp); + + if (true) { // DLC + browseNew = new JButton(BROWSENEW); + browseNew.addActionListener(tal); + } + temp.add(browseNew); + // DLC temp.add(new JLabel(" ")); + content.add(temp); + + buttonBox = Box.createHorizontalBox(); + buttonBox.add(Box.createHorizontalGlue()); + convert = new JButton(CONVERT); + convert.addActionListener(tal); + buttonBox.add(convert); + buttonBox.add(Box.createHorizontalGlue()); + + cancel = new JButton(CANCEL); + cancel.addActionListener(tal); + buttonBox.add(cancel); + buttonBox.add(Box.createHorizontalGlue()); + + openDoc = new JButton("Open Document"); + openDoc.addActionListener(tal); + buttonBox.add(openDoc); + buttonBox.add(Box.createHorizontalGlue()); + openDoc.setVisible(false); + + content.add(buttonBox); + setContentPane(content); + pack(); + setSize(new Dimension(500,200)); + } + + public void setChoices(String[] choices) + { + choiceNames = choices; + this.choices = new JComboBox(choiceNames); + this.choices.addActionListener(tal); + } + + // Accessors + public void setController(FontConversion fc) + { + controller = fc; + } + + public FontConversion getController() + { + return controller; + } + + public String getType() + { + return (String)choices.getSelectedItem(); + } + + public void setCurrentDirectory(String dir) + { + jfc.setCurrentDirectory(new File(dir)); + } + + public void setOldFile(File f) + { + oldFile = f; + } + + public void setNewFile(File f) + { + newFile = f; + } + + public File getOldFile() + { + if(debug && oldFile == null) {System.out.println("Old file is null!");} + return oldFile; + } + + public File getNewFile() + { + if(debug && newFile == null) {System.out.println("New file is null!");} + return newFile; + } + + public ConvertDialog(FontConversion controller, String[] choices, boolean modal) + { + super(new JDialog(),PROGRAM_TITLE,modal); + setController(controller); + setChoices(choices); + init(); + if (debug) + System.out.println("Default close operation: " + + getDefaultCloseOperation()); + } + + void theRealActionPerformed(ActionEvent ae) + { + String cmd = ae.getActionCommand(); + if (cmd.equals(BROWSEOLD) + || cmd.equals(BROWSENEW)) + { + JButton src = (JButton)ae.getSource(); + jfc.showOpenDialog(this); + File chosenFile = jfc.getSelectedFile(); + if(chosenFile == null) { return; } + if(src.equals(browseOld)) { + String fileName = chosenFile.getPath(); + oldTextField.setText(fileName); + updateNewFileGuess(); + oldFieldChanged = false; + oldFile = jfc.getSelectedFile(); + } else if(src.equals(browseNew)) { + newTextField.setText(chosenFile.getPath()); + newFieldChanged = false; + newFile = jfc.getSelectedFile(); + openDoc.setVisible(false); + } + } else if(cmd.equals(CONVERT)) { + if (debug) + System.out.println("Need to write checks for complete info..."); + + if(oldFieldChanged || getOldFile() == null) { + if (debug) + System.out.println("DLC: old field changed"); + setOldFile(updateFile(oldFile,oldTextField)); + } + if(newFieldChanged || getNewFile() == null) { + if (debug) + System.out.println("DLC: new field changed"); + setNewFile(updateFile(newFile,newTextField)); + } + + if(null == oldFile || !oldFile.exists()) { + JOptionPane.showMessageDialog(this, + "The original file does not exist. Choose again.", + "No such file", + JOptionPane.ERROR_MESSAGE); + return; + } + if(null == newFile) { + JOptionPane.showMessageDialog(this, + "Please name the new file before proceeding.", + "No output file named", + JOptionPane.ERROR_MESSAGE); + return; + } + try { + if(getNewFile().getCanonicalPath().equals(getOldFile().getCanonicalPath())) { + JOptionPane.showMessageDialog(this, + "Please name the new file something different from the old file.", + "Input and output are the same", + JOptionPane.ERROR_MESSAGE); + return; + } + } catch (IOException e) { + // allow it. + } + + // Success or failure is immaterial; we still want to bust + // out the "Open Document" button. + controller.doConversion(this, + getOldFile(), + getNewFile(), + (String)choices.getSelectedItem()); + oldFieldChanged = false; + newFieldChanged = false; + openDoc.setVisible(true); + } else if(cmd.equals("Open Document")) { + try { + if(newFile == null) {return;} + boolean done = false; + File prog = new File(ThdlOptions.getStringOption("thdl.external.rtf.reader", "C:\\Program Files\\Microsoft Office\\Office\\WINWORD.EXE")); + while (!done) { + String[] cmdArray = {prog.getPath(),newFile.getPath()}; + Runtime rtime = Runtime.getRuntime(); + try { + Process proc = rtime.exec(cmdArray); + proc = null; + done = true; + } catch (IOException ioe) { + JFileChooser jfc = new JFileChooser("C:\\Program Files\\"); + jfc.setDialogTitle("Locate Program to Read RTF"); + int returnValue = jfc.showOpenDialog(this); + if(returnValue != jfc.CANCEL_OPTION) { + prog = jfc.getSelectedFile(); + ThdlOptions.setUserPreference("thdl.external.rtf.reader", + prog.getAbsolutePath()); + } else { + done = true; + } + } + } + } catch (SecurityException se) { + JOptionPane.showMessageDialog(this, + "Cannot proceed because your security policy interfered.", + "Access denied", + JOptionPane.ERROR_MESSAGE); + } + } else if(cmd.equals(CANCEL)) { + System.runFinalization(); + this.dispose(); + System.exit(0); + } else if (cmd.equals("comboBoxChanged")) { + updateNewFileGuess(); + } + } + private void updateNewFileGuess() { + String oldFileName = oldTextField.getText(); + if (oldFileName == null || oldFileName.equals("")) + return; + + String newFileNamePrefix; + + + File of = new File(oldFileName); + String oldFileDirName = of.getParent(); + if (oldFileDirName == null) + oldFileDirName = ""; + else + oldFileDirName = oldFileDirName + File.separator; + String oldFileNameSansThingy = of.getName(); + if (oldFileNameSansThingy.startsWith("TMW_")) { + oldFileNameSansThingy + = oldFileNameSansThingy.substring("TMW_".length(), + oldFileNameSansThingy.length()); + } else if (oldFileNameSansThingy.startsWith("TM_")) { + oldFileNameSansThingy + = oldFileNameSansThingy.substring("TM_".length(), + oldFileNameSansThingy.length()); + } else if (oldFileNameSansThingy.startsWith("TMW")) { + oldFileNameSansThingy + = oldFileNameSansThingy.substring("TMW".length(), + oldFileNameSansThingy.length()); + } else if (oldFileNameSansThingy.startsWith("TM")) { + oldFileNameSansThingy + = oldFileNameSansThingy.substring("TM".length(), + oldFileNameSansThingy.length()); + } + + String ct = (String)choices.getSelectedItem(); + if ("Find all non-TMW" == ct) { + newFileNamePrefix = "FindAllNonTMW__"; + } else if ("Find some non-TMW" == ct) { + newFileNamePrefix = "FindSomeNonTMW__"; + } else if ("Find some non-TM" == ct) { + newFileNamePrefix = "FindSomeNonTM__"; + } else if ("Find all non-TM" == ct) { + newFileNamePrefix = "FindAllNonTM__"; + } else { // conversion {to Wylie or TM} mode + if ("TMW to Wylie" == ct) { + newFileNamePrefix = "THDL_Wylie_"; + } else if ("TMW to Unicode" == ct) { + newFileNamePrefix = "Uni_"; + } else if ("TM to TMW" == ct) { + newFileNamePrefix = "TMW_"; + } else { + ThdlDebug.verify("TMW to TM" == ct); + newFileNamePrefix = "TM_"; + } + } + newTextField.setText(oldFileDirName + + newFileNamePrefix + + oldFileNameSansThingy); + } + + public File updateFile(File setFile, JTextField textField) + { + if(textField.equals(newTextField)) {openDoc.setVisible(false);} + String txt = textField.getText(); + if (txt.equals("")) + return null; + if(txt.indexOf(".rtf")==-1) { txt += ".rtf"; } + if(setFile == null) {return new File(txt); } + String fileName = setFile.getPath(); + String filePath = setFile.getPath(); + if(txt.equals(fileName) || txt.equals(filePath)) { return setFile; } + if(txt.indexOf("\\")>-1) { return new File(txt); } + return new File(setFile.getParent() + "\\" + txt); + } + + public class RTFFileFilter extends javax.swing.filechooser.FileFilter + { + public boolean accept(File f) + { + if(f.isDirectory() || f.getName().indexOf(".rtf")>-1) { return true; } + return false; + } + + public String getDescription() + { + return "RTF files only"; + } + } +} + diff --git a/source/org/thdl/tib/input/ConverterGUI.java b/source/org/thdl/tib/input/ConverterGUI.java new file mode 100644 index 0000000..3f05c9c --- /dev/null +++ b/source/org/thdl/tib/input/ConverterGUI.java @@ -0,0 +1,138 @@ +/* +The contents of this file are subject to the THDL Open Community License +Version 1.0 (the "License"); you may not use this file except in compliance +with the License. You may obtain a copy of the License on the THDL web site +(http://www.thdl.org/). + +Software distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTY OF ANY KIND, either express or implied. See the +License for the specific terms governing rights and limitations under the +License. + +The Initial Developer of this software is the Tibetan and Himalayan Digital +Library (THDL). Portions created by the THDL are Copyright 2003 THDL. +All Rights Reserved. + +Contributor(s): ______________________________________. +*/ + +package org.thdl.tib.input; + +import java.io.*; + +import org.thdl.util.*; +import org.thdl.tib.text.*; +import javax.swing.JOptionPane; + +/** DLC FIXMEDOC + * @author David Chandler */ +public class ConverterGUI implements FontConversion { + /** Default constructor; does nothing */ + ConverterGUI() { } + + static { + // No need for the TM or TMW fonts. + System.setProperty("thdl.rely.on.system.tmw.fonts", "true"); + System.setProperty("thdl.do.not.rely.on.system.tmw.fonts", "false"); + } + + /** + * Runs the converter. */ + public static void main(String[] args) { + System.exit(realMain(args, System.out)); + } + + // DLC FIXMEDOC returns true on success + public boolean doConversion(ConvertDialog cd, File oldFile, File newFile, + String whichConversion) { + System.err.println("DLC NOW " + oldFile + " " + newFile + " " + whichConversion); + PrintStream ps; + try { + returnCode + = TibetanConverter.reallyConvert(new FileInputStream(oldFile), + ps = new PrintStream(new FileOutputStream(newFile), + false), + whichConversion); + ps.close(); + } catch (FileNotFoundException e) { + returnCode = 39; + } + if (0 != returnCode) { + JOptionPane.showMessageDialog(cd, + "The conversion failed with code " + returnCode + "; please e-mail\ndchandler@users.sourceforge.net to learn what that means if\nyou can't find out from the output.", + "Conversion failed", + JOptionPane.ERROR_MESSAGE); + return false; + } else { + if (!ThdlOptions.getBooleanOption("thdl.skip.conversion.success.message")) + JOptionPane.showMessageDialog(cd, + "The conversion went perfectly.", + "Conversion succeeded", + JOptionPane.PLAIN_MESSAGE); + return true; + } + } + + // DLC FIXMEDOC + public String getDefaultDirectory() { + return ThdlOptions.getStringOption("thdl.Jskad.working.directory", + null); + } + + private static int returnCode = 0; + + /** Runs the converter without exiting the program. + * @return the exit code. */ + public static int realMain(String[] args, PrintStream out) { + try { + + final ConvertDialog convDialog + = new ConvertDialog(new ConverterGUI(), + new String[]{ + // DLC FIXME: use variables + // for these, because they're + // used in + // TibetanConverter.java too. + "TM to TMW", + "TMW to Unicode", + "TMW to Wylie", + "TMW to TM", + "Find some non-TMW", + "Find some non-TM", + "Find all non-TMW", + "Find all non-TM" + }, + true); + + /* Make it so that any time the user exits this program by + * (almost) any means, the user's preferences are saved if + * the SecurityManager allows it and the path is correct. + * This means that the program used to "Open Document" + * will be remembered. */ + Runtime.getRuntime().addShutdownHook(new Thread() { + public void run() { + try { + if (!ThdlOptions.saveUserPreferences()) { + JOptionPane.showMessageDialog(convDialog, + "You previously cleared preferences,\nso you cannot now save them.", + "Cannot Save User Preferences", + JOptionPane.PLAIN_MESSAGE); + } + } catch (IOException ioe) { + System.out.println("IO Exception saving user preferences to " + ThdlOptions.getUserPreferencesPath()); + ioe.printStackTrace(); + ThdlDebug.noteIffyCode(); + } + + } + }); + + convDialog.setVisible(true); + return returnCode; + } catch (ThdlLazyException e) { + out.println("ConverterGUI has a BUG:"); + e.getRealException().printStackTrace(out); + return 7; + } + } +} diff --git a/source/org/thdl/tib/input/FontConversion.java b/source/org/thdl/tib/input/FontConversion.java new file mode 100644 index 0000000..bb2d6da --- /dev/null +++ b/source/org/thdl/tib/input/FontConversion.java @@ -0,0 +1,29 @@ +/* +The contents of this file are subject to the THDL Open Community License +Version 1.0 (the "License"); you may not use this file except in compliance +with the License. You may obtain a copy of the License on the THDL web site +(http://www.thdl.org/). + +Software distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTY OF ANY KIND, either express or implied. See the +License for the specific terms governing rights and limitations under the +License. + +The Initial Developer of this software is the Tibetan and Himalayan Digital +Library (THDL). Portions created by the THDL are Copyright 2003 THDL. +All Rights Reserved. + +Contributor(s): ______________________________________. +*/ + +package org.thdl.tib.input; + +import java.io.File; + +// DLC FIXMEDOC +interface FontConversion +{ + String getDefaultDirectory(); + boolean doConversion(ConvertDialog cd, File oldFile, + File newFile, String whichConversion); +} diff --git a/source/org/thdl/tib/input/FontConverterConstants.java b/source/org/thdl/tib/input/FontConverterConstants.java new file mode 100644 index 0000000..2529053 --- /dev/null +++ b/source/org/thdl/tib/input/FontConverterConstants.java @@ -0,0 +1,62 @@ +/* +The contents of this file are subject to the THDL Open Community License +Version 1.0 (the "License"); you may not use this file except in compliance +with the License. You may obtain a copy of the License on the THDL web site +(http://www.thdl.org/). + +Software distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTY OF ANY KIND, either express or implied. See the +License for the specific terms governing rights and limitations under the +License. + +The Initial Developer of this software is the Tibetan and Himalayan Digital +Library (THDL). Portions created by the THDL are Copyright 2003 THDL. +All Rights Reserved. + +Contributor(s): ______________________________________. +*/ + +package org.thdl.tib.input; + +import java.io.*; +import java.awt.*; + +/** Constants used by ConvertDialog. + + @author Nathaniel Garson, Tibetan and Himalayan Digital Library */ +interface FontConverterConstants +{ + // DLC prune + + // File Constants + String HOME_PATH = System.getProperties().getProperty("user.dir"); + File HOME_FOLDER = new File(HOME_PATH); + + // GUI Constants + // Sizes + Dimension WIN_SIZE = new Dimension(600,400); + + + // Colors + Color BG_COLOR = Color.white; + + // Data Delimiters + String COMMENT_DELIM = "////"; + String HEADER_DELIM = "Unicode failed because the following constitute a bad position: startOffset " + startOffset + ", endOffset " + endOffset); } } + // DLC NOW do I stick to these rules in TMW->Unicode mappings? +// Chris Fynn wrote: +// +// By normal Tibetan & Dzongkha spelling, writing, and input rules +// Tibetan script stacks should be entered and written: 1 headline +// consonant (0F40->0F6A), any subjoined consonant(s) (0F90-> +// 0F9C), achung (0F71), shabkyu (0F74), any above headline +// vowel(s) (0F72 0F7A 0F7B 0F7C 0F7D and 0F80) ; any ngaro (0F7E, +// 0F82 and 0F83) + private int insertDuff(int fontSize, int pos, DuffData[] glyphs, boolean asTMW) { if (glyphs == null) @@ -544,7 +554,7 @@ public class TibetanDocument extends DefaultStyledDocument { @param errors if non-null, then notes about all exceptional cases will be appended to this StringBuffer @param unicodeFont the name of the Unicode font to use; - defaults to Arial Unicode MS if null + defaults to Ximalaya if null */ public boolean convertToUnicode(int begin, int end, StringBuffer errors, String unicodeFont) { @@ -974,7 +984,7 @@ public class TibetanDocument extends DefaultStyledDocument { /** Returns all the paragraph elements in this document that * contain glyphs with offsets in the range [start, end) where * end < 0 is treated as the document's length. Note that roman, - * TM, Arial Unicode MS, and TMW text can all be intermingled + * TM, Ximalaya, and TMW text can all be intermingled * within a paragraph. It's the correct level of abstraction to * use, however, because the next finer grain is roughly one * Element per glyph. */ diff --git a/source/org/thdl/tib/text/TibetanMachineWeb.java b/source/org/thdl/tib/text/TibetanMachineWeb.java index de16c9b..4d1f338 100644 --- a/source/org/thdl/tib/text/TibetanMachineWeb.java +++ b/source/org/thdl/tib/text/TibetanMachineWeb.java @@ -285,7 +285,7 @@ public class TibetanMachineWeb implements THDLWylieConstants { defaultUnicodeFontAttributeSet = new SimpleAttributeSet(); StyleConstants.setFontFamily(defaultUnicodeFontAttributeSet, - "Arial Unicode MS"); + "Ximalaya"); webFontAttributeSet[0] = null; for (int i=1; i