Skip to content

Commit

Permalink
Use xdg-open instead of java.awt.Desktop if possible. Resolves #433.
Browse files Browse the repository at this point in the history
  • Loading branch information
bengtmartensson committed Jul 1, 2021
1 parent de18e9b commit 58293c5
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 34 deletions.
75 changes: 47 additions & 28 deletions src/main/java/org/harctoolbox/guicomponents/GuiUtils.java
Expand Up @@ -31,6 +31,7 @@
import java.net.URL;
import java.net.UnknownHostException;
import java.text.ParseException;
import java.util.concurrent.TimeUnit;
import javax.swing.ImageIcon;
import javax.swing.JOptionPane;
import org.harctoolbox.ircore.IrCoreUtils;
Expand All @@ -44,12 +45,29 @@ public class GuiUtils implements Serializable {
private static boolean offerStackTrace = false;
private static String programName = "unknown";
private static boolean verbose = false;
private static boolean useXdbOpen = false;
private static final String XDG_COMMAND = "xdg-open";
private static final String XDG_COMMAND_TEST_OPTION = "--version";

static {
// Determine if there is a working xdg-open command;
// if so, we will use it instead of the java.awt.Desptop functions.
try {
ProcessBuilder processBuilder = new ProcessBuilder(XDG_COMMAND, XDG_COMMAND_TEST_OPTION);
Process process = processBuilder.start();
process.waitFor(1, TimeUnit.SECONDS);
int exit = process.exitValue();
useXdbOpen = exit == 0;
} catch (IOException | InterruptedException ex) {
useXdbOpen = false;
}
}

public static void fatal(Exception ex, int errorcode) {
fatal(ex, errorcode, null);
}

@SuppressWarnings("CallToPrintStackTrace")
@SuppressWarnings({"CallToPrintStackTrace", "UseOfSystemOutOrSystemErr"})
public static void fatal(Exception ex, int errorcode, EmergencyFixer fixer) {
String message = ex.getClass().getSimpleName() + ": " + ex.getMessage();
if (System.console() != null)
Expand Down Expand Up @@ -121,6 +139,7 @@ private String truncate(String message) {
: message.substring(0, maxGuiMessageLength - 3) + "...";
}

@SuppressWarnings("UseOfSystemOutOrSystemErr")
public void info(String message) {
if (usePopupsForErrors) {
JOptionPane.showMessageDialog(frame, truncate(message), programName + " information",
Expand All @@ -131,16 +150,19 @@ public void info(String message) {
}
}

@SuppressWarnings("UseOfSystemOutOrSystemErr")
public void trace(String message) {
System.err.println(message);
}

// A message is there to be used, not to be clicked away.
// Do not use popups here.
@SuppressWarnings("UseOfSystemOutOrSystemErr")
public void message(String message) {
System.err.println(message);
}

@SuppressWarnings("UseOfSystemOutOrSystemErr")
public void warning(String message) {
if (usePopupsForErrors) {
JOptionPane.showMessageDialog(frame, truncate(message), programName + " warning",
Expand All @@ -155,6 +177,7 @@ public void error(String message) {
error(message, false);
}

@SuppressWarnings("UseOfSystemOutOrSystemErr")
private boolean error(String message, boolean offerStackTrace) {
int ans = 0;
if (usePopupsForErrors) {
Expand Down Expand Up @@ -182,6 +205,7 @@ public void error(Throwable ex) {
error(ex, ex.getMessage());
}

@SuppressWarnings({"UseOfSystemOutOrSystemErr", "null"})
public void error(Throwable ex, String msg) {
String message = msg.replaceFirst("^java.lang.RuntimeException: ", "");
String errorMessage = ex instanceof ParseException
Expand Down Expand Up @@ -221,11 +245,6 @@ public boolean confirm(String message, int optionType) {
return confirm(frame, message, optionType);
}

public void mail(String address, String subject, String body) throws URISyntaxException, IOException {
URI uri = new URI("mailto:" + address + "?subject=" + subject + "&body=" + body);
Desktop.getDesktop().mail(uri);
}

// There is, deliberately, no public void browse(String string)
// rationale: too easy to confuse file names and URLs,
// thereby too error prone.
Expand All @@ -234,25 +253,33 @@ public void browse(File file) throws MalformedURLException, URISyntaxException {
browse(file.toURI());
}

@SuppressWarnings("UseOfSystemOutOrSystemErr")
public void browse(URI uri) {
if (! Desktop.isDesktopSupported()) {
error("Desktop not supported");
return;
}
if (uri == null || uri.toString().isEmpty()) {
error("No URI.");
return;
}

try {
if (verbose)
trace("Browsing URI \"" + uri.toString() + "\"");
Desktop.getDesktop().browse(uri);

if (useXdbOpen)
xdgOpen(uri.toURL().toString());
else if (Desktop.isDesktopSupported())
Desktop.getDesktop().browse(uri);
else
error("Desktop not supported");
} catch (IOException ex) {
boolean stacktrace = error("Could not start browser using uri \"" + uri.toString() + "\".", offerStackTrace);
if (stacktrace)
ex.printStackTrace(System.err);
}
}

private void xdgOpen(String string) throws IOException {
new ProcessBuilder(XDG_COMMAND, string).start();
}

// Do NOT add an edit(...) function!

Expand All @@ -262,43 +289,34 @@ public void browse(URI uri) {
*
* @param file file or directory to be opened/edited.
*/
public void open(File file) {
if (!Desktop.isDesktopSupported()) {
error("Desktop not supported");
return;
}

if (Desktop.getDesktop().isSupported(Desktop.Action.OPEN)) {
public void open(File file) throws IOException {
if (useXdbOpen)
xdgOpen(file.getAbsolutePath());
else if (Desktop.getDesktop().isSupported(Desktop.Action.OPEN)) {
try {
Desktop.getDesktop().open(file);
if (verbose)
trace("open file \"" + file.toString() + "\" succeeded");
return;
} catch (IllegalArgumentException ex) {
error(file.getAbsolutePath() + " does not exist.");
return;
} catch (IOException ex) {
if (verbose)
trace("open file \"" + file.toString() + "\" failed: " + ex.getLocalizedMessage());
}
}

if (Desktop.getDesktop().isSupported(Desktop.Action.EDIT)) {
} else if (Desktop.getDesktop().isSupported(Desktop.Action.EDIT)) {
try {
Desktop.getDesktop().edit(file);
if (verbose)
trace("edit file \"" + file.toString() + "\" succeeded");
return;
} catch (IOException ex) {
if (verbose)
trace("edit file \"" + file.toString() + "\" failed: " + ex.getLocalizedMessage());
}
}

error("Neither edit nor open supported/working");
} else
error("Neither edit nor open supported/working");
}

public void browseOrEdit(String urlOrFilename) {
public void browseOrEdit(String urlOrFilename) throws IOException {
try {
URL url = new URL(urlOrFilename);
browse(url.toURI());
Expand All @@ -307,6 +325,7 @@ public void browseOrEdit(String urlOrFilename) {
}
}

@SuppressWarnings("UseOfSystemOutOrSystemErr")
public void help(String helpText) {
if (usePopupsForHelp)
HelpPopup.newHelpPopup(frame, helpText);
Expand Down
22 changes: 17 additions & 5 deletions src/main/java/org/harctoolbox/irscrutinizer/GuiMain.java
Expand Up @@ -8344,7 +8344,11 @@ private void exportDirSelectButtonActionPerformed(java.awt.event.ActionEvent evt
}//GEN-LAST:event_exportDirSelectButtonActionPerformed

private void exportDirOpenButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_exportDirOpenButtonActionPerformed
guiUtils.open(new File(properties.getExportDir()));
try {
guiUtils.open(new File(properties.getExportDir()));
} catch (IOException ex) {
guiUtils.error(ex);
}
}//GEN-LAST:event_exportDirOpenButtonActionPerformed

private void automaticExportFilenamesCheckBoxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_automaticExportFilenamesCheckBoxActionPerformed
Expand Down Expand Up @@ -8634,8 +8638,12 @@ private void pasteScrutinizeToDataWindowMenuItemActionPerformed(java.awt.event.A
}//GEN-LAST:event_pasteScrutinizeToDataWindowMenuItemActionPerformed

private void irpProtocolsEditMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_irpProtocolsEditMenuItemActionPerformed
guiUtils.open(new File(properties.mkPathAbsolute(properties.getIrpProtocolsPath())));
guiUtils.warning("If editing the file, changes will not take effect before you save the file AND restart the program.");
try {
guiUtils.open(new File(properties.mkPathAbsolute(properties.getIrpProtocolsPath())));
guiUtils.warning("If editing the file, changes will not take effect before you save the file AND restart the program.");
} catch (IOException ex) {
guiUtils.error(ex);
}
}//GEN-LAST:event_irpProtocolsEditMenuItemActionPerformed

private void irpProtocolsSelectMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_irpProtocolsSelectMenuItemActionPerformed
Expand All @@ -8649,8 +8657,12 @@ private void irpProtocolsSelectMenuItemActionPerformed(java.awt.event.ActionEven
}//GEN-LAST:event_irpProtocolsSelectMenuItemActionPerformed

private void exportFormatsEditMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_exportFormatsEditMenuItemActionPerformed
guiUtils.open(new File(properties.mkPathAbsolute(properties.getExportFormatFilePath())));
guiUtils.warning("If editing, changes will not take effect before reloading.");
try {
guiUtils.open(new File(properties.mkPathAbsolute(properties.getExportFormatFilePath())));
guiUtils.warning("If editing, changes will not take effect before reloading.");
} catch (IOException ex) {
guiUtils.error(ex);
}
}//GEN-LAST:event_exportFormatsEditMenuItemActionPerformed

private void exportFormatsSelectMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_exportFormatsSelectMenuItemActionPerformed
Expand Down
Expand Up @@ -336,7 +336,11 @@ private void editBrowseButtonActionPerformed(java.awt.event.ActionEvent evt) {//
guiUtils.error("File/URL empty");
return;
}
guiUtils.browseOrEdit(filename);
try {
guiUtils.browseOrEdit(filename);
} catch (IOException ex) {
guiUtils.error(ex);
}
}//GEN-LAST:event_editBrowseButtonActionPerformed

private void loadClipboardButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_loadClipboardButtonActionPerformed
Expand Down

0 comments on commit 58293c5

Please sign in to comment.