Jskad has two new menu items that are a shortcut for running a standalone

TMW->Unicode conversion: 'Save as Unicode RTF...' and 'Save as
Unicode UTF-8 Text...'.
This commit is contained in:
dchandler 2005-02-27 10:27:37 +00:00
parent 107fcce565
commit 24403bb395
4 changed files with 165 additions and 31 deletions

View file

@ -566,6 +566,7 @@ public class DuffPane extends TibetanPane implements FocusListener {
getTibDoc().insertString(offset, s, attr); getTibDoc().insertString(offset, s, attr);
} }
catch (BadLocationException ble) { catch (BadLocationException ble) {
ThdlDebug.noteIffyCode();
} }
} }
@ -1025,6 +1026,54 @@ public class DuffPane extends TibetanPane implements FocusListener {
} }
} }
} }
/** Saves the TMW document underlying this DuffPane as Unicode. Has to copy
@param utf8_text true if you want to save as UTF-8-encoded
Unicode text, false if you want to save as Unicode in RTF
@param out an OutputStream that will be closed when we're done
in every case
@returns true on perfect success, false otherwise */
public boolean saveAsUnicode(boolean utf8_text, OutputStream out)
throws IOException
{
boolean retval = true;
ThdlDebug.verify(getDocument() == getTibDoc());
// construct new document so that we can use
// TibetanDocument.convertToUnicode(..).
TibetanDocument newDoc = new TibetanDocument();
try {
for (int i = 0; i < getTibDoc().getLength(); i++) {
String s = getTibDoc().getText(i,1);
AttributeSet as
= getTibDoc().getCharacterElement(i).getAttributes();
String fontName = StyleConstants.getFontFamily(as);
if (0 != TibetanMachineWeb.getTMFontNumber(fontName))
retval = false;
newDoc.insertString(i, s, as);
}
} catch (BadLocationException ble) {
throw new Error("this cannot happen");
}
if (newDoc.convertToUnicode(0, newDoc.getLength(), null,
ThdlOptions.getStringOption("thdl.tmw.to.unicode.font").intern(),
new long[] { 0 })) {
retval = false;
}
if (utf8_text) {
BufferedWriter bw
= new BufferedWriter(new OutputStreamWriter(out, "UTF-8"));
newDoc.writeTextOutput(bw);
bw.close();
} else {
try {
rtfEd.write(out, newDoc, 0, newDoc.getLength());
} catch (BadLocationException ble) {
throw new Error("this cannot happen either");
}
out.close();
}
return retval;
}
/** Adds to the clipboard the Unicode you'd get if you used a /** Adds to the clipboard the Unicode you'd get if you used a
TMW->Unicode conversion on the specified portion of the TMW->Unicode conversion on the specified portion of the
@ -1038,8 +1087,8 @@ public class DuffPane extends TibetanPane implements FocusListener {
// TibetanDocument.convertToUnicode(..). // TibetanDocument.convertToUnicode(..).
TibetanDocument newDoc = new TibetanDocument(); TibetanDocument newDoc = new TibetanDocument();
boolean warn_about_tm = false; boolean warn_about_tm = false;
for (int i = start; i < end; i++) { try {
try { for (int i = start; i < end; i++) {
String s = getTibDoc().getText(i,1); String s = getTibDoc().getText(i,1);
AttributeSet as AttributeSet as
= getTibDoc().getCharacterElement(i).getAttributes(); = getTibDoc().getCharacterElement(i).getAttributes();
@ -1047,10 +1096,10 @@ public class DuffPane extends TibetanPane implements FocusListener {
if (0 != TibetanMachineWeb.getTMFontNumber(fontName)) if (0 != TibetanMachineWeb.getTMFontNumber(fontName))
warn_about_tm = true; warn_about_tm = true;
newDoc.insertString(i - start, s, as); newDoc.insertString(i - start, s, as);
} catch (BadLocationException ble) {
ble.printStackTrace();
ThdlDebug.noteIffyCode();
} }
} catch (BadLocationException ble) {
ble.printStackTrace();
ThdlDebug.noteIffyCode();
} }
String unicode = "[Jskad: Converting to Unicode failed.]"; String unicode = "[Jskad: Converting to Unicode failed.]";
if (newDoc.convertToUnicode(0, newDoc.getLength(), null, null, if (newDoc.convertToUnicode(0, newDoc.getLength(), null, null,
@ -1766,3 +1815,6 @@ class RTFSelection implements ClipboardOwner, Transferable {
} // inner class DuffPane.RTFSelection } // inner class DuffPane.RTFSelection
} // class DuffPane } // class DuffPane
// TODO(dchandler): search for 'catch (Throwable' and 'catch
// (Exception' and 'catch (Error'. These are rarely a good idea.

View file

@ -195,20 +195,20 @@ public class Jskad extends JPanel implements DocumentListener {
} }
} }
private int numItemsOnFileMenuBeforeRecentlyOpened = 0;
private void updateRecentlyOpenedFilesMenuItems() { private void updateRecentlyOpenedFilesMenuItems() {
int ic = fileMenu.getItemCount(); int menu_loc = numItemsOnFileMenuBeforeRecentlyOpened;
while (fileMenu.getItemCount() > 8) while (fileMenu.getItemCount() > menu_loc + 2)
fileMenu.remove(7); fileMenu.remove(menu_loc + 1);
int N = RecentlyOpenedFilesDatabase.getNumberOfFilesToShow(); int N = RecentlyOpenedFilesDatabase.getNumberOfFilesToShow();
// Avoid adding duplicate entries: // Avoid adding duplicate entries:
boolean addedSeparator = false; boolean addedSeparator = false;
for (int i = 0; i < N; i++) { for (int i = 0; i < N; i++) {
final File recentlyOpenedFile final File recentlyOpenedFile
= RecentlyOpenedFilesDatabase.getNthRecentlyOpenedFile(N-i-1); = RecentlyOpenedFilesDatabase.getNthRecentlyOpenedFile(N-i-1);
if (null != recentlyOpenedFile) { if (null != recentlyOpenedFile) {
if (!addedSeparator) { if (!addedSeparator) {
fileMenu.insertSeparator(6); fileMenu.insertSeparator(menu_loc);
addedSeparator = true; addedSeparator = true;
} }
JMenuItem item = new JMenuItem((N-i) + " " JMenuItem item = new JMenuItem((N-i) + " "
@ -218,7 +218,7 @@ public class Jskad extends JPanel implements DocumentListener {
openFile(recentlyOpenedFile); openFile(recentlyOpenedFile);
} }
}); });
fileMenu.add(item, 7); fileMenu.add(item, menu_loc + 1);
} }
} }
} }
@ -267,6 +267,8 @@ public class Jskad extends JPanel implements DocumentListener {
fileChooser.addChoosableFileFilter(rtfFilter); fileChooser.addChoosableFileFilter(rtfFilter);
fileMenu = new JMenu("File"); fileMenu = new JMenu("File");
numItemsOnFileMenuBeforeRecentlyOpened = 0;
JMenuItem newItem = new JMenuItem("New..."); JMenuItem newItem = new JMenuItem("New...");
// newItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_N,java.awt.Event.CTRL_MASK)); //Ctrl-n // newItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_N,java.awt.Event.CTRL_MASK)); //Ctrl-n
@ -275,6 +277,7 @@ public class Jskad extends JPanel implements DocumentListener {
newFile(); newFile();
} }
}); });
++numItemsOnFileMenuBeforeRecentlyOpened;
fileMenu.add(newItem); fileMenu.add(newItem);
JMenuItem openItem = new JMenuItem("Open..."); JMenuItem openItem = new JMenuItem("Open...");
@ -284,6 +287,7 @@ public class Jskad extends JPanel implements DocumentListener {
openFile(); openFile();
} }
}); });
++numItemsOnFileMenuBeforeRecentlyOpened;
fileMenu.add(openItem); fileMenu.add(openItem);
if (parentObject instanceof JFrame) { if (parentObject instanceof JFrame) {
@ -302,6 +306,7 @@ public class Jskad extends JPanel implements DocumentListener {
} }
} }
}); });
++numItemsOnFileMenuBeforeRecentlyOpened;
fileMenu.add(closeItem); fileMenu.add(closeItem);
} }
JMenuItem saveItem = new JMenuItem("Save"); JMenuItem saveItem = new JMenuItem("Save");
@ -309,23 +314,44 @@ public class Jskad extends JPanel implements DocumentListener {
saveItem.addActionListener(new ThdlActionListener() { saveItem.addActionListener(new ThdlActionListener() {
public void theRealActionPerformed(ActionEvent e) { public void theRealActionPerformed(ActionEvent e) {
if (fileName == null) if (fileName == null)
saveAsFile(); saveAsFile("legacy rtf");
else else
saveFile(); saveFile();
} }
}); });
++numItemsOnFileMenuBeforeRecentlyOpened;
fileMenu.addSeparator(); fileMenu.addSeparator();
++numItemsOnFileMenuBeforeRecentlyOpened;
fileMenu.add(saveItem); fileMenu.add(saveItem);
JMenuItem saveAsItem = new JMenuItem("Save as..."); JMenuItem saveAsItem = new JMenuItem("Save as...");
saveAsItem.addActionListener(new ThdlActionListener() { saveAsItem.addActionListener(new ThdlActionListener() {
public void theRealActionPerformed(ActionEvent e) { public void theRealActionPerformed(ActionEvent e) {
saveAsFile(); saveAsFile("legacy rtf");
} }
}); });
++numItemsOnFileMenuBeforeRecentlyOpened;
fileMenu.add(saveAsItem); fileMenu.add(saveAsItem);
JMenuItem saveAsUnicodeUtf8Item = new JMenuItem("Save as Unicode UTF-8 text...");
saveAsUnicodeUtf8Item.addActionListener(new ThdlActionListener() {
public void theRealActionPerformed(ActionEvent e) {
saveAsFile("unicode utf8 text");
}
});
++numItemsOnFileMenuBeforeRecentlyOpened;
fileMenu.add(saveAsUnicodeUtf8Item);
JMenuItem saveAsUnicodeRtfItem = new JMenuItem("Save as Unicode RTF...");
saveAsUnicodeRtfItem.addActionListener(new ThdlActionListener() {
public void theRealActionPerformed(ActionEvent e) {
saveAsFile("unicode rtf");
}
});
++numItemsOnFileMenuBeforeRecentlyOpened;
fileMenu.add(saveAsUnicodeRtfItem);
if (parentObject instanceof JFrame) { if (parentObject instanceof JFrame) {
JMenuItem exitItem = new JMenuItem("Exit"); JMenuItem exitItem = new JMenuItem("Exit");
exitItem.addActionListener(new ThdlActionListener() { exitItem.addActionListener(new ThdlActionListener() {
@ -1024,7 +1050,7 @@ public class Jskad extends JPanel implements DocumentListener {
/** Returns true iff the save was successful. */ /** Returns true iff the save was successful. */
private boolean saveFile() { private boolean saveFile() {
String s = getSave(fileName); String s = getSave("legacy rtf", fileName);
if (null != s) { if (null != s) {
if (parentObject instanceof JFrame) { if (parentObject instanceof JFrame) {
JFrame parentFrame = (JFrame)parentObject; JFrame parentFrame = (JFrame)parentObject;
@ -1042,9 +1068,11 @@ public class Jskad extends JPanel implements DocumentListener {
} }
} }
/** Returns true iff the save was successful. */ /** Returns true iff the save was successful.
private boolean saveAsFile() { * @param fileType either "legacy rtf", "unicode utf8 text", or
String s = getSaveAs(); * "unicode rtf" */
private boolean saveAsFile(String fileType) {
String s = getSaveAs(fileType);
if (null != s) { if (null != s) {
if (parentObject instanceof JFrame) { if (parentObject instanceof JFrame) {
JFrame parentFrame = (JFrame)parentObject; JFrame parentFrame = (JFrame)parentObject;
@ -1084,7 +1112,7 @@ public class Jskad extends JPanel implements DocumentListener {
case JOptionPane.YES_OPTION: //save and continue case JOptionPane.YES_OPTION: //save and continue
if (fileName == null) if (fileName == null)
return saveAsFile(); return saveAsFile("legacy rtf");
else else
return saveFile(); return saveFile();
@ -1093,14 +1121,35 @@ public class Jskad extends JPanel implements DocumentListener {
} }
} }
private String getSave(String f_name) { private String getSave(String fileType, String f_name) {
File fileChosen = new File(f_name); File fileChosen = new File(f_name);
try { try {
BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(fileChosen)); if (fileType == "legacy rtf") {
dp.rtfEd.write(out, dp.getDocument(), 0, dp.getDocument().getLength()); BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(fileChosen));
out.flush(); dp.rtfEd.write(out, dp.getDocument(), 0, dp.getDocument().getLength());
out.close(); out.flush();
out.close();
} else if (fileType == "unicode utf8 text") {
if (!dp.saveAsUnicode(true,
new BufferedOutputStream(new FileOutputStream(fileChosen)))) {
JOptionPane.showMessageDialog(Jskad.this,
"Saving as UTF-8 Unicode text did not go perfectly. Try using the standalone converter if you want a perfect document.",
"Save As UTF-8 Warning",
JOptionPane.WARNING_MESSAGE);
}
} else if (fileType == "unicode rtf") {
if (!dp.saveAsUnicode(false,
new BufferedOutputStream(new FileOutputStream(fileChosen)))) {
JOptionPane.showMessageDialog(Jskad.this,
"Saving as Unicode RTF did not go perfectly. Try using the standalone converter if you want a perfect document.",
"Save As Unicode RTF Warning",
JOptionPane.WARNING_MESSAGE);
}
} else {
throw new IllegalArgumentException("fileType " + fileType
+ " is not supported");
}
hasChanged = false; hasChanged = false;
} catch (IOException exception) { } catch (IOException exception) {
JOptionPane.showMessageDialog(Jskad.this, JOptionPane.showMessageDialog(Jskad.this,
@ -1116,9 +1165,13 @@ public class Jskad extends JPanel implements DocumentListener {
return f_name; return f_name;
} }
private String getSaveAs() { private String getSaveAs(String fileType) {
setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
if (fileType == "unicode utf8 text") {
fileChooser.removeChoosableFileFilter(rtfFilter);
fileChooser.addChoosableFileFilter(txtFilter);
}
if (fileName == null) if (fileName == null)
fileChooser.setSelectedFile(null); fileChooser.setSelectedFile(null);
else else
@ -1126,6 +1179,10 @@ public class Jskad extends JPanel implements DocumentListener {
if (fileChooser.showSaveDialog(this) != JFileChooser.APPROVE_OPTION) { if (fileChooser.showSaveDialog(this) != JFileChooser.APPROVE_OPTION) {
setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
if (fileType == "unicode utf8 text") {
fileChooser.removeChoosableFileFilter(txtFilter);
fileChooser.addChoosableFileFilter(rtfFilter);
}
return null; return null;
} }
@ -1135,12 +1192,23 @@ public class Jskad extends JPanel implements DocumentListener {
String fileName = fileChosen.getAbsolutePath(); String fileName = fileChosen.getAbsolutePath();
int i = fileName.lastIndexOf('.'); int i = fileName.lastIndexOf('.');
if (i < 0) String ext = ((fileType == "unicode utf8 text") ? ".txt" : ".rtf");
fileName += ".rtf";
else
fileName = fileName.substring(0, i) + ".rtf";
getSave(fileName); if (i < 0)
fileName += ext;
else if (!fileName.regionMatches(true, i, ext, 0, ext.length())
|| fileName.length() != i + ext.length()) {
JOptionPane.showMessageDialog(Jskad.this,
"Filename chosen does not have the extension '"
+ ext + "'",
"Save As Error",
JOptionPane.ERROR_MESSAGE);
setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
return null;
}
getSave(fileType, fileName);
fileChooser.rescanCurrentDirectory(); fileChooser.rescanCurrentDirectory();
setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));

View file

@ -466,7 +466,8 @@ public class TibetanConverter implements FontConverterConstants {
if (TMW_TO_WYLIE_TEXT == ct || TMW_TO_ACIP_TEXT == ct) { if (TMW_TO_WYLIE_TEXT == ct || TMW_TO_ACIP_TEXT == ct) {
try { try {
BufferedWriter bw BufferedWriter bw
= new BufferedWriter(new OutputStreamWriter(out)); = new BufferedWriter(new OutputStreamWriter(out,
"UTF-8"));
tdoc.writeTextOutput(bw); tdoc.writeTextOutput(bw);
bw.flush(); bw.flush();
} catch (IOException e) { } catch (IOException e) {

View file

@ -143,7 +143,8 @@ documents.&nbsp; In any case, if there is any text in the current
Jskad window, a new window will be opened up.&nbsp; To close a Jskad Jskad window, a new window will be opened up.&nbsp; To close a Jskad
window, choose 'Close' or press the 'X' button.&nbsp; To close all window, choose 'Close' or press the 'X' button.&nbsp; To close all
Jskad windows, choose 'Exit'.&nbsp; You will be prompted to save if Jskad windows, choose 'Exit'.&nbsp; You will be prompted to save if
you haven't already done so. you haven't already done so.<!-- done so in regular (non-Unicode) Rich
Text Format, that is -->
</p> </p>
<p> <p>
@ -152,6 +153,18 @@ other applications, 'Save' saves under the current name, while 'Save
As...' lets you save under a new name. As...' lets you save under a new name.
</p> </p>
<p>
As a convenience, 'Save as Unicode&nbsp;RTF...' and 'Save as
Unicode&nbsp;UTF-8...' are provided.&nbsp; An ordinary 'Save' or 'Save
As...' command saves as Rich Text Format using the legacy Tibetan
Machine Web font, but these two options convert the Tibetan Machine
Web to Unicode.&nbsp; These are convenient, but if you encounter
problems you will need to take the long road by first saving normally
and then choosing 'Tools - Launch Converter...' and converting from
TMW to Unicode.&nbsp; (A good Unicode font is Tibetan Machine Uni, by
the way.)
</p>
<p> <p>
The 'Edit' menu lets you cut, copy, and paste Tibetan text and set The 'Edit' menu lets you cut, copy, and paste Tibetan text and set
document preferences.&nbsp; These topics are covered elsewhere, in <a document preferences.&nbsp; These topics are covered elsewhere, in <a