Jskad now has the ability to open its buffer with an external viewer, e.g.

Microsoft Word.

Better OOM error handling in the GUI converter; untested, though.
This commit is contained in:
dchandler 2003-06-29 20:49:30 +00:00
parent 646e23b4a4
commit ee14b7b97f
2 changed files with 114 additions and 65 deletions

View file

@ -56,20 +56,22 @@ class ConvertDialog extends JDialog
JFileChooser jfc; JFileChooser jfc;
final String BROWSENEW = "Browse..."; private static final String BROWSENEW = "Browse...";
final String BROWSEOLD = BROWSENEW; private static final String BROWSEOLD = BROWSENEW;
final String CONVERT = "Convert"; private static final String CONVERT = "Convert";
final String CANCEL = "Close"; private static final String CANCEL = "Close";
final String ABOUT = "About"; private static final String ABOUT = "About";
final String OPEN_WITH = "Open With..."; private static final String OPEN_WITH = "Open With...";
private static final String LOCATE_FILE = "Locate File";
private final ThdlActionListener tal = new ThdlActionListener() { private final ThdlActionListener tal = new ThdlActionListener() {
public void theRealActionPerformed(ActionEvent e) { public void theRealActionPerformed(ActionEvent e) {
ConvertDialog.this.theRealActionPerformed(e); ConvertDialog.this.theRealActionPerformed(e);
}}; }};
public void init() private void init()
{ {
jfc = new JFileChooser(controller.getDefaultDirectory()); jfc = new JFileChooser(controller.getDefaultDirectory());
jfc.setDialogTitle(LOCATE_FILE);
jfc.setFileFilter(new RTFFileFilter()); jfc.setFileFilter(new RTFFileFilter());
content = new JPanel(new GridLayout(0,1)); content = new JPanel(new GridLayout(0,1));
@ -138,7 +140,7 @@ class ConvertDialog extends JDialog
setSize(new Dimension(620,200)); setSize(new Dimension(620,200));
} }
public void setChoices(String[] choices) private void setChoices(String[] choices)
{ {
choiceNames = choices; choiceNames = choices;
this.choices = new JComboBox(choiceNames); this.choices = new JComboBox(choiceNames);
@ -146,26 +148,12 @@ class ConvertDialog extends JDialog
} }
// Accessors // Accessors
public void setController(FontConversion fc) private void setController(FontConversion fc)
{ {
controller = fc; controller = fc;
} }
public FontConversion getController() /** This constructor takes an owner; the other doesn't. */
{
return controller;
}
public String getType()
{
return (String)choices.getSelectedItem();
}
public void setCurrentDirectory(String dir)
{
jfc.setCurrentDirectory(new File(dir));
}
public ConvertDialog(Frame owner, public ConvertDialog(Frame owner,
FontConversion controller, FontConversion controller,
String[] choices, String[] choices,
@ -175,6 +163,15 @@ class ConvertDialog extends JDialog
initConvertDialog(controller, choices, modal); initConvertDialog(controller, choices, modal);
} }
/** This constructor does not take an owner; the other does. */
public ConvertDialog(FontConversion controller,
String[] choices,
boolean modal)
{
super(new JDialog(),PROGRAM_TITLE,modal);
initConvertDialog(controller, choices, modal);
}
private void initConvertDialog(FontConversion controller, private void initConvertDialog(FontConversion controller,
String[] choices, String[] choices,
boolean modal) { boolean modal) {
@ -186,14 +183,6 @@ class ConvertDialog extends JDialog
+ getDefaultCloseOperation()); + getDefaultCloseOperation());
} }
public ConvertDialog(FontConversion controller,
String[] choices,
boolean modal)
{
super(new JDialog(),PROGRAM_TITLE,modal);
initConvertDialog(controller, choices, modal);
}
void theRealActionPerformed(ActionEvent ae) void theRealActionPerformed(ActionEvent ae)
{ {
String cmd = ae.getActionCommand(); String cmd = ae.getActionCommand();
@ -267,10 +256,17 @@ class ConvertDialog extends JDialog
} }
} }
controller.doConversion(this, try {
origFile, controller.doConversion(this,
convertedFile, origFile,
(String)choices.getSelectedItem()); convertedFile,
(String)choices.getSelectedItem());
} catch (OutOfMemoryError e) {
JOptionPane.showMessageDialog(this,
"The converter ran out of memory. Please give the\nJVM more memory by using java -XmxYYYm where YYY\nis the amount of memory your system has, or\nsomething close to it. E.g., try\n'java -Xmx512m -jar Jskad.jar'.",
"Out of Memory",
JOptionPane.ERROR_MESSAGE);
}
} else if(cmd.equals(OPEN_WITH)) { } else if(cmd.equals(OPEN_WITH)) {
try { try {
JButton src = (JButton)ae.getSource(); JButton src = (JButton)ae.getSource();
@ -304,29 +300,7 @@ class ConvertDialog extends JDialog
return; return;
} }
boolean done = false; openWithExternalViewer(this, fileToOpen);
File prog
= new File(ThdlOptions.getStringOption("thdl.external.rtf.reader",
"C:\\Program Files\\Microsoft Office\\Office\\WINWORD.EXE"));
while (!done) {
String[] cmdArray = {prog.getPath(),fileToOpen};
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");
if(jfc.showOpenDialog(this) == jfc.APPROVE_OPTION) {
prog = jfc.getSelectedFile();
ThdlOptions.setUserPreference("thdl.external.rtf.reader",
prog.getAbsolutePath());
} else {
done = true;
}
}
}
} catch (SecurityException se) { } catch (SecurityException se) {
JOptionPane.showMessageDialog(this, JOptionPane.showMessageDialog(this,
"Cannot proceed because your security policy interfered.", "Cannot proceed because your security policy interfered.",
@ -345,6 +319,42 @@ class ConvertDialog extends JDialog
updateNewFileGuess(); updateNewFileGuess();
} }
} }
/** Invokes a user-specified external viewer (one that takes a
single command-line argument, the path to view) on the file
with path fileToOpen.
@param parent the owner of any dialogs that come up
@param fileToOpen the path to open in the external viewer */
static void openWithExternalViewer(Component parent, String fileToOpen) {
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(),fileToOpen};
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");
if(jfc.showOpenDialog(parent) == jfc.APPROVE_OPTION) {
prog = jfc.getSelectedFile();
ThdlOptions.setUserPreference("thdl.external.rtf.reader",
prog.getAbsolutePath());
} else {
done = true;
}
jfc.setDialogTitle(LOCATE_FILE);
}
}
}
/** Looks at the name of the original file and creates a name for
the converted file based on that. */
private void updateNewFileGuess() { private void updateNewFileGuess() {
String oldFileName = oldTextField.getText(); String oldFileName = oldTextField.getText();
if (oldFileName == null || oldFileName.equals("")) if (oldFileName == null || oldFileName.equals(""))

View file

@ -209,7 +209,7 @@ public class Jskad extends JPanel implements DocumentListener {
JMenuItem closeItem = new JMenuItem("Close"); JMenuItem closeItem = new JMenuItem("Close");
closeItem.addActionListener(new ThdlActionListener() { closeItem.addActionListener(new ThdlActionListener() {
public void theRealActionPerformed(ActionEvent e) { public void theRealActionPerformed(ActionEvent e) {
if (!hasChanged || hasChanged && checkSave()) { if (!hasChanged || hasChanged && checkSave(JOptionPane.YES_NO_CANCEL_OPTION)) {
Jskad.this.realCloseAction(true); Jskad.this.realCloseAction(true);
} }
} }
@ -351,6 +351,16 @@ public class Jskad extends JPanel implements DocumentListener {
toolsMenu.add(wylieTMWItem); toolsMenu.add(wylieTMWItem);
if (parentObject instanceof JFrame || parentObject instanceof JInternalFrame) { if (parentObject instanceof JFrame || parentObject instanceof JInternalFrame) {
JMenuItem openWithItem = new JMenuItem("Open With External Viewer...");
openWithItem.addActionListener(new ThdlActionListener() {
public void theRealActionPerformed(ActionEvent e) {
openWithExternalViewer();
}
});
toolsMenu.addSeparator();
toolsMenu.add(openWithItem);
JMenuItem importItem = new JMenuItem("Import Wylie as Tibetan"); JMenuItem importItem = new JMenuItem("Import Wylie as Tibetan");
importItem.addActionListener(new ThdlActionListener() { importItem.addActionListener(new ThdlActionListener() {
public void theRealActionPerformed(ActionEvent e) { public void theRealActionPerformed(ActionEvent e) {
@ -650,7 +660,7 @@ public class Jskad extends JPanel implements DocumentListener {
parentFrame.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE); parentFrame.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
parentFrame.addWindowListener(new WindowAdapter () { parentFrame.addWindowListener(new WindowAdapter () {
public void windowClosing (WindowEvent e) { public void windowClosing (WindowEvent e) {
if (!hasChanged || hasChanged && checkSave()) { if (!hasChanged || hasChanged && checkSave(JOptionPane.YES_NO_CANCEL_OPTION)) {
numberOfTibsRTFOpen--; numberOfTibsRTFOpen--;
if (numberOfTibsRTFOpen == 0) if (numberOfTibsRTFOpen == 0)
System.exit(0); System.exit(0);
@ -917,8 +927,12 @@ public class Jskad extends JPanel implements DocumentListener {
} }
/** Returns true iff the user says (possibly after a successful /** Returns true iff the user says (possibly after a successful
save) that it is OK to destroy this Jskad widget. */ save) that it is OK to destroy this Jskad widget.
private boolean checkSave() { @param dialogType either JOptionPane.YES_NO_CANCEL_OPTION or
JOptionPane.YES_NO_OPTION, depending on whether canceling is
different than saying no.
*/
private boolean checkSave(int dialogType) {
if (ThdlOptions.getBooleanOption("thdl.Jskad.do.not.confirm.quit")) { if (ThdlOptions.getBooleanOption("thdl.Jskad.do.not.confirm.quit")) {
return true; return true;
} }
@ -927,7 +941,7 @@ public class Jskad extends JPanel implements DocumentListener {
= JOptionPane.showConfirmDialog(this, = JOptionPane.showConfirmDialog(this,
"Do you want to save your changes?", "Do you want to save your changes?",
"Please select", "Please select",
JOptionPane.YES_NO_CANCEL_OPTION); dialogType);
switch (saveFirst) { switch (saveFirst) {
case JOptionPane.NO_OPTION: //don't save but do continue case JOptionPane.NO_OPTION: //don't save but do continue
@ -1270,7 +1284,7 @@ public class Jskad extends JPanel implements DocumentListener {
int sz = jskads.size(); int sz = jskads.size();
for (int i = 0; i < sz; i++) { for (int i = 0; i < sz; i++) {
Jskad j = (Jskad)jskads.elementAt(i); Jskad j = (Jskad)jskads.elementAt(i);
if (j.hasChanged && !j.checkSave()) { if (j.hasChanged && !j.checkSave(JOptionPane.YES_NO_CANCEL_OPTION)) {
return; return;
} }
} }
@ -1281,6 +1295,31 @@ public class Jskad extends JPanel implements DocumentListener {
} }
/** Checks if the current buffer has been modified or is not yet
saved. If so, the user is prompted to save. After that, the
current buffer is opened with a user-selected external viewer,
which defaults to Microsoft Word if we can find it with our
naive, "I bet it lives on everybody's machine where it lives
on mine" mechanism. */
private void openWithExternalViewer() {
if ((hasChanged && !checkSave(JOptionPane.YES_NO_OPTION)) || null == fileName) {
if (null == fileName) {
JOptionPane.showMessageDialog(Jskad.this,
"You must save the file before opening it with an external viewer.",
"Cannot View Unsaved File",
JOptionPane.ERROR_MESSAGE);
return;
} else {
if (JOptionPane.YES_OPTION
!= JOptionPane.showConfirmDialog(Jskad.this,
"Do you want to view the file as it exists on disk anyway?",
"Proceed Anyway?",
JOptionPane.YES_NO_OPTION))
return;
}
}
ConvertDialog.openWithExternalViewer(this, fileName);
}
/** /**
* Runs Jskad. System output, including errors, is redirected to * Runs Jskad. System output, including errors, is redirected to