[latexila] SyncTeX: backward search



commit 68b43fe0e43a8acf67c05b4ffee5f508bbd86329
Author: SÃbastien Wilmet <swilmet gnome org>
Date:   Mon Sep 10 02:23:28 2012 +0200

    SyncTeX: backward search

 src/build_tool_runner.vala |    2 +-
 src/build_view.vala        |   11 +-----
 src/document_view.vala     |    2 +-
 src/file_browser.vala      |    2 +-
 src/main_window.vala       |   15 ++++++++-
 src/structure.vala         |    2 +-
 src/synctex.vala           |   72 +++++++++++++++++++++++++++++++++++++++----
 src/utils.vala             |   13 ++++++++
 8 files changed, 98 insertions(+), 21 deletions(-)
---
diff --git a/src/build_tool_runner.vala b/src/build_tool_runner.vala
index e2f9dbc..97121a7 100644
--- a/src/build_tool_runner.vala
+++ b/src/build_tool_runner.vala
@@ -277,7 +277,7 @@ public class BuildToolRunner : GLib.Object
 
         try
         {
-            Gtk.show_uri (_view.get_screen (), uri, Gdk.CURRENT_TIME);
+            Utils.show_uri (_view.get_screen (), uri);
         }
         catch (Error e)
         {
diff --git a/src/build_view.vala b/src/build_view.vala
index f1adafc..02cc0c2 100644
--- a/src/build_view.vala
+++ b/src/build_view.vala
@@ -233,15 +233,8 @@ public class BuildView : TreeView
 
     private void jump_to_file_lines (File file, int start_line, int end_line)
     {
-        return_if_fail (start_line >= 0 && end_line >= 0);
-
-        DocumentTab tab = _main_window.open_document (file);
-
-        // Ensure that the file is fully loaded before selecting the lines.
-        Utils.flush_queue ();
-
-        // start_line and end_line begins at 1, but select_lines() begins at 0
-        tab.document.select_lines (start_line - 1, end_line - 1);
+        return_if_fail (start_line >= 1 && end_line >= 1);
+        _main_window.jump_to_file_position (file, start_line - 1, end_line - 1);
     }
 
     public void clear ()
diff --git a/src/document_view.vala b/src/document_view.vala
index 85291c4..51381c6 100644
--- a/src/document_view.vala
+++ b/src/document_view.vala
@@ -218,7 +218,7 @@ public class DocumentView : Gtk.SourceView
         if (event.button == 1 &&
             Gdk.ModifierType.CONTROL_MASK in event.state)
         {
-            Synctex synctex = new Synctex ();
+            Synctex synctex = Synctex.get_default ();
             synctex.forward_search (this.buffer as Document);
         }
 
diff --git a/src/file_browser.vala b/src/file_browser.vala
index 57cdadf..c0297e4 100644
--- a/src/file_browser.vala
+++ b/src/file_browser.vala
@@ -186,7 +186,7 @@ public class FileBrowser : Grid
 
             try
             {
-                Gtk.show_uri (this.get_screen (), file.get_uri (), Gdk.CURRENT_TIME);
+                Utils.show_uri (this.get_screen (), file.get_uri ());
             }
             catch (Error e)
             {
diff --git a/src/main_window.vala b/src/main_window.vala
index 06d093e..4c2ddf9 100644
--- a/src/main_window.vala
+++ b/src/main_window.vala
@@ -985,6 +985,19 @@ public class MainWindow : Window
         _main_window_build_tools.save_state ();
     }
 
+    // start_line and end_line begins at 0.
+    public void jump_to_file_position (File file, int start_line, int end_line)
+    {
+        return_if_fail (start_line >= 0 && end_line >= 0);
+
+        DocumentTab tab = open_document (file);
+
+        // Ensure that the file is fully loaded before selecting the lines.
+        Utils.flush_queue ();
+
+        tab.document.select_lines (start_line, end_line);
+    }
+
     /*************************************************************************/
     // Sensitivity
 
@@ -1088,7 +1101,7 @@ public class MainWindow : Window
     {
         return_if_fail (active_tab != null);
 
-        Synctex synctex = new Synctex ();
+        Synctex synctex = Synctex.get_default ();
         synctex.forward_search (active_document);
     }
 
diff --git a/src/structure.vala b/src/structure.vala
index 30340fd..e8f498b 100644
--- a/src/structure.vala
+++ b/src/structure.vala
@@ -702,7 +702,7 @@ public class Structure : Grid
     {
         try
         {
-            show_uri (get_screen (), referenced_file.get_uri (), Gdk.CURRENT_TIME);
+            Utils.show_uri (get_screen (), referenced_file.get_uri ());
         }
         catch (Error e)
         {
diff --git a/src/synctex.vala b/src/synctex.vala
index 15eda08..01b5f0b 100644
--- a/src/synctex.vala
+++ b/src/synctex.vala
@@ -50,10 +50,31 @@ interface EvinceWindow : Object
 
     public signal void sync_source (string source_file, DocPosition source_point,
         uint32 timestamp);
+
+    public signal void closed ();
 }
 
 public class Synctex : Object
 {
+    private static Synctex _instance = null;
+
+    // PDF uri -> evince window
+    private Gee.HashMap<string, EvinceWindow?> _ev_windows;
+
+    // Singleton
+    private Synctex ()
+    {
+        _ev_windows = new Gee.HashMap<string, EvinceWindow?> ();
+    }
+
+    public static Synctex get_default ()
+    {
+        if (_instance == null)
+            _instance = new Synctex ();
+
+        return _instance;
+    }
+
     public void forward_search (Document doc)
     {
         string? pdf_uri = get_pdf_uri (doc);
@@ -136,6 +157,18 @@ public class Synctex : Object
 
     private EvinceWindow? get_evince_window (string pdf_uri)
     {
+        if (create_evince_window (pdf_uri))
+            return _ev_windows[pdf_uri];
+        else
+            return null;
+    }
+
+    // Returns true on success.
+    public bool create_evince_window (string pdf_uri)
+    {
+        if (_ev_windows.has_key (pdf_uri))
+            return true;
+
         EvinceDaemon daemon = null;
 
         try
@@ -146,7 +179,7 @@ public class Synctex : Object
         catch (IOError e)
         {
             warning ("SyncTeX: can not connect to evince daemon: %s", e.message);
-            return null;
+            return false;
         }
 
         string owner = null;
@@ -158,7 +191,7 @@ public class Synctex : Object
         catch (IOError e)
         {
             warning ("SyncTeX: find document: %s", e.message);
-            return null;
+            return false;
         }
 
         EvinceApplication app = null;
@@ -170,7 +203,7 @@ public class Synctex : Object
         catch (IOError e)
         {
             warning ("SyncTeX: can not connect to evince application: %s", e.message);
-            return null;
+            return false;
         }
 
         string[] window_list = {};
@@ -182,13 +215,13 @@ public class Synctex : Object
         catch (IOError e)
         {
             warning ("SyncTeX: can not get window list: %s", e.message);
-            return null;
+            return false;
         }
 
         if (window_list.length == 0)
         {
             warning ("SyncTeX: the window list is empty.");
-            return null;
+            return false;
         }
 
         // There is normally only one window.
@@ -202,10 +235,35 @@ public class Synctex : Object
         catch (IOError e)
         {
             warning ("SyncTeX: can not connect to evince window: %s", e.message);
-            return null;
+            return false;
         }
 
-        return window;
+        add_evince_window (pdf_uri, window);
+        return true;
+    }
+
+    private void add_evince_window (string pdf_uri, EvinceWindow window)
+    {
+        _ev_windows[pdf_uri] = window;
+
+        window.sync_source.connect ((tex_uri, pos, timestamp) =>
+        {
+            File tex_file = File.new_for_uri (tex_uri);
+            if (! tex_file.query_exists ())
+            {
+                warning (@"Backward search: the file \"$tex_uri\" doesn't exist.");
+                return;
+            }
+
+            MainWindow main_window = Latexila.get_instance ().active_window;
+            main_window.jump_to_file_position (tex_file, pos.line - 1, pos.line);
+            main_window.present_with_time (timestamp);
+        });
+
+        window.closed.connect (() =>
+        {
+            _ev_windows.unset (pdf_uri);
+        });
     }
 
     private void sync_view (EvinceWindow window, string tex_path, DocPosition pos)
diff --git a/src/utils.vala b/src/utils.vala
index db8922b..85c7ecd 100644
--- a/src/utils.vala
+++ b/src/utils.vala
@@ -285,6 +285,19 @@ namespace Utils
         return relative_path;
     }
 
+    public void show_uri (Gdk.Screen? screen, string uri) throws Error
+    {
+        if (! Gtk.show_uri (screen, uri, Gdk.CURRENT_TIME))
+            return;
+
+        // Backward search for PDF documents.
+        if (get_extension (uri) == ".pdf")
+        {
+            Synctex synctex = Synctex.get_default ();
+            synctex.create_evince_window (uri);
+        }
+    }
+
 
     /*************************************************************************/
     // UI stuff



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