From 3201557bfbed7ad81e0e5a34ece48bbd93ad709b Mon Sep 17 00:00:00 2001
From: Sebastian Koslowski <koslowski@kit.edu>
Date: Tue, 23 Feb 2016 21:47:52 +0100
Subject: grc-refactor: move gui prefs to gui

---
 grc/gui/Executor.py | 123 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 123 insertions(+)
 create mode 100644 grc/gui/Executor.py

(limited to 'grc/gui/Executor.py')

diff --git a/grc/gui/Executor.py b/grc/gui/Executor.py
new file mode 100644
index 0000000000..96b95f4c7a
--- /dev/null
+++ b/grc/gui/Executor.py
@@ -0,0 +1,123 @@
+# Copyright 2016 Free Software Foundation, Inc.
+# This file is part of GNU Radio
+#
+# GNU Radio Companion is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# GNU Radio Companion is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+
+import gobject
+import os
+import threading
+import shlex
+import subprocess
+import sys
+import re
+from distutils.spawn import find_executable
+
+from ..core import Messages
+from .Constants import XTERM_EXECUTABLE
+
+
+class ExecFlowGraphThread(threading.Thread):
+    """Execute the flow graph as a new process and wait on it to finish."""
+
+    def __init__(self, action_handler):
+        """
+        ExecFlowGraphThread constructor.
+
+        Args:
+            action_handler: an instance of an ActionHandler
+        """
+        threading.Thread.__init__(self)
+        self.update_exec_stop = action_handler.update_exec_stop
+        self.flow_graph = action_handler.get_flow_graph()
+        #store page and dont use main window calls in run
+        self.page = action_handler.get_page()
+        #get the popen
+        try:
+            self.p = self._popen()
+            self.page.set_proc(self.p)
+            #update
+            self.update_exec_stop()
+            self.start()
+        except Exception, e:
+            Messages.send_verbose_exec(str(e))
+            Messages.send_end_exec()
+
+    def _popen(self):
+        """
+        Execute this python flow graph.
+        """
+        run_command = self.flow_graph.get_option('run_command')
+        generator = self.page.get_generator()
+
+        try:
+            run_command = run_command.format(
+                python=shlex_quote(sys.executable),
+                filename=shlex_quote(generator.file_path))
+            run_command_args = shlex.split(run_command)
+        except Exception as e:
+            raise ValueError("Can't parse run command {!r}: {}".format(run_command, e))
+
+        # When in no gui mode on linux, use a graphical terminal (looks nice)
+        xterm_executable = find_executable(XTERM_EXECUTABLE)
+        if generator.generate_options == 'no_gui' and xterm_executable:
+            run_command_args = [xterm_executable, '-e', run_command]
+
+        # this does not reproduce a shell executable command string, if a graphical
+        # terminal is used. Passing run_command though shlex_quote would do it but
+        # it looks really ugly and confusing in the console panel.
+        Messages.send_start_exec(' '.join(run_command_args))
+
+        return subprocess.Popen(
+            args=run_command_args,
+            stdout=subprocess.PIPE, stderr=subprocess.STDOUT,
+            shell=False, universal_newlines=True
+        )
+
+    def run(self):
+        """
+        Wait on the executing process by reading from its stdout.
+        Use gobject.idle_add when calling functions that modify gtk objects.
+        """
+        #handle completion
+        r = "\n"
+        while r:
+            gobject.idle_add(Messages.send_verbose_exec, r)
+            r = os.read(self.p.stdout.fileno(), 1024)
+        self.p.poll()
+        gobject.idle_add(self.done)
+
+    def done(self):
+        """Perform end of execution tasks."""
+        Messages.send_end_exec(self.p.returncode)
+        self.page.set_proc(None)
+        self.update_exec_stop()
+
+
+###########################################################
+# back-port from python3
+###########################################################
+_find_unsafe = re.compile(r'[^\w@%+=:,./-]').search
+
+
+def shlex_quote(s):
+    """Return a shell-escaped version of the string *s*."""
+    if not s:
+        return "''"
+    if _find_unsafe(s) is None:
+        return s
+
+    # use single quotes, and put single quotes into double quotes
+    # the string $'b is then quoted as '$'"'"'b'
+    return "'" + s.replace("'", "'\"'\"'") + "'"
-- 
cgit v1.2.3