[meld] Rework external opening to better obey file types



commit 1b6bc4935269fbb3bb7423d9de6a29159bddb836
Author: Kai Willadsen <kai willadsen gmail com>
Date:   Sat Jun 2 07:48:55 2012 +1000

    Rework external opening to better obey file types
    
    Our existing code had several issues, most obvious of which was that
    it would try to open non-text files in a text editor when there was a
    custom editor set.
    
    This patch fixes _open_files to launch the correct application more
    reliably, using gio's file type functionality. In theory this is
    cross-platform, though in reality file sniffing on other systems
    appears less-than-awesome. Since the fallback goes to generic OS
    'open this file' calls in each case, this shouldn't be a big problem.

 meld/melddoc.py |   56 ++++++++++++++++++++++++++++++++++++------------------
 1 files changed, 37 insertions(+), 19 deletions(-)
---
diff --git a/meld/melddoc.py b/meld/melddoc.py
index 82b191a..55fe965 100644
--- a/meld/melddoc.py
+++ b/meld/melddoc.py
@@ -16,13 +16,16 @@
 ### Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
 
+import os
 import subprocess
 import sys
 
 import gobject
-import task
+import gio
 import gtk
-import os
+
+import task
+
 from gettext import gettext as _
 
 
@@ -65,26 +68,41 @@ class MeldDoc(gobject.GObject):
             self.scheduler.remove_task(self.scheduler.get_current_task())
 
     def _open_files(self, selected):
-        files = [f for f in selected if os.path.isfile(f)]
-        dirs = [d for d in selected if os.path.isdir(d)]
-
-        def os_open(paths):
-            for path in paths:
-                if sys.platform == "win32":
-                    subprocess.Popen(["start", path], shell=True)
-                elif sys.platform == "darwin":
-                    subprocess.Popen(["open", path])
+        query_attrs = ",".join((gio.FILE_ATTRIBUTE_STANDARD_TYPE,
+                                gio.FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE))
+
+        def os_open(path):
+            if not path:
+                return
+            if sys.platform == "win32":
+                subprocess.Popen(["start", path], shell=True)
+            elif sys.platform == "darwin":
+                subprocess.Popen(["open", path])
+            else:
+                subprocess.Popen(["xdg-open", path])
+
+        def open_cb(source, result, *data):
+            info = source.query_info_finish(result)
+            file_type = info.get_file_type()
+            if file_type == gio.FILE_TYPE_DIRECTORY:
+                os_open(source.get_path())
+            elif file_type == gio.FILE_TYPE_REGULAR:
+                content_type = info.get_content_type()
+                path = source.get_path()
+                if gio.content_type_is_a(content_type, "text/plain"):
+                    editor = self.prefs.get_editor_command([path])
+                    if editor:
+                        subprocess.Popen(editor)
+                    else:
+                        os_open(path)
                 else:
-                    subprocess.Popen(["xdg-open", path])
-
-        if len(files):
-            cmd = self.prefs.get_editor_command(files)
-            if cmd:
-                os.spawnvp(os.P_NOWAIT, cmd[0], cmd)
+                    os_open(path)
             else:
-                os_open(files)
+                # TODO: Add some kind of 'failed to open' notification
+                pass
 
-        os_open(dirs)
+        for f in [gio.File(s) for s in selected]:
+            f.query_info_async(query_attrs, open_cb)
 
     def open_external(self):
         pass



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]