From 38756d53da82f87dbe49812fb9295bc67cfdcdcf Mon Sep 17 00:00:00 2001 From: John Ralls Date: Thu, 29 Aug 2013 23:25:09 +0000 Subject: [PATCH] Bug 7017 GUI stuck when external viewer launched subprocess.checked_call seems to wait on the process that xdg-open starts, but subprocess.wait doesn't. svn: r22949 --- gramps/gui/editors/editmedia.py | 6 ++--- gramps/gui/utils.py | 43 +++++++++++++++++++++++++++++---- 2 files changed, 41 insertions(+), 8 deletions(-) diff --git a/gramps/gui/editors/editmedia.py b/gramps/gui/editors/editmedia.py index b08daf4d3..bb7a01886 100644 --- a/gramps/gui/editors/editmedia.py +++ b/gramps/gui/editors/editmedia.py @@ -28,9 +28,7 @@ # Standard python modules # #------------------------------------------------------------------------- -from gramps.gen.const import GRAMPS_LOCALE as glocale -_ = glocale.translation.gettext - +import os #------------------------------------------------------------------------- # # GTK/Gnome modules @@ -44,6 +42,8 @@ from gi.repository import Gdk # gramps modules # #------------------------------------------------------------------------- +from gramps.gen.const import GRAMPS_LOCALE as glocale +_ = glocale.translation.gettext from ..utils import open_file_with_default_application from gramps.gen.lib import MediaObject, NoteType from gramps.gen.db import DbTxn diff --git a/gramps/gui/utils.py b/gramps/gui/utils.py index 9fc3fce9c..e5e0a9b52 100644 --- a/gramps/gui/utils.py +++ b/gramps/gui/utils.py @@ -358,6 +358,34 @@ class SystemFonts(object): # # #------------------------------------------------------------------------- +def poll_external ((proc, errorstrings)): + """ + Check the for completion of a task launched with + subprocess.Popen(). This function is intended to be passed to + GLib.timeout_add_seconds, so the arguments are in a tuple because that + function takes only a single data argument. + + @proc the process, returned from subprocess.Popen() + @errorstrings a dict of possible response values and the corresponding messages to display. + @returns False when the function has completed. + """ + from .dialog import ErrorDialog + resp = proc.poll() + if resp is None: + return True + + if resp != 0: + error = "The external program failed to launch or experienced an error" + if errorstrings: + try: + error = errorstrings[resp] + except KeyError: + pass + + ErrorDialog(_("Error from external program"), error) + + return False + def open_file_with_default_application( file_path ): """ Launch a program to open an arbitrary file. The file will be opened using @@ -369,7 +397,6 @@ def open_file_with_default_application( file_path ): @type file_path: string @return: nothing """ - from .dialog import ErrorDialog norm_path = os.path.normpath( file_path ) if not os.path.exists(norm_path): ErrorDialog(_("Error Opening File"), _("File does not exist")) @@ -382,14 +409,20 @@ def open_file_with_default_application( file_path ): ErrorDialog(_("Error Opening File"), str(msg)) return + errstrings = None if mac(): utility = '/usr/bin/open' else: utility = 'xdg-open' - try: - subprocess.check_output([utility, norm_path], stderr=subprocess.STDOUT) - except subprocess.CalledProcessError as err: - ErrorDialog(_("Error Opening File"), err.output) + errstrings = {1:'Error in command line syntax.', + 2:'One of the files passed on the command line did not exist.', + 3:' A required tool could not be found.', + 4:'The action failed.'} + + proc = subprocess.Popen([utility, norm_path], stderr=subprocess.STDOUT) + + from gi.repository import GLib + GLib.timeout_add_seconds(1, poll_external, (proc, errstrings)) return def process_pending_events(max_count=10):