[gnome-builder/wip/libide-merge] wire up forward/backward navigation



commit d4ec632766c118dbde11ad59cb96fba50d572598
Author: Christian Hergert <christian hergert me>
Date:   Fri Mar 20 23:36:08 2015 -0700

    wire up forward/backward navigation
    
    Both:
    
      gb_view_navigate_to()
      gb_view_stack_focus_location()
    
    will be useful once we do more code exploring tools

 src/editor/gb-editor-view.c       |   41 ++++++++++++++
 src/views/gb-view-stack-private.h |    2 +
 src/views/gb-view-stack.c         |  104 ++++++++++++++++++++++++++++++------
 src/views/gb-view-stack.h         |   21 ++++---
 src/views/gb-view.c               |   11 ++++
 src/views/gb-view.h               |    4 ++
 6 files changed, 156 insertions(+), 27 deletions(-)
---
diff --git a/src/editor/gb-editor-view.c b/src/editor/gb-editor-view.c
index ed4fd55..bf2a6e9 100644
--- a/src/editor/gb-editor-view.c
+++ b/src/editor/gb-editor-view.c
@@ -44,6 +44,46 @@ gb_editor_view_get_document (GbView *view)
   return GB_DOCUMENT (self->document);
 }
 
+static GbEditorFrame *
+gb_editor_view_get_last_focused (GbEditorView *self)
+{
+  /* TODO: track focus */
+  return self->frame1;
+}
+
+static void
+gb_editor_view_navigate_to (GbView            *view,
+                            IdeSourceLocation *location)
+{
+  GbEditorView *self = (GbEditorView *)view;
+  GbEditorFrame *frame;
+  GtkTextBuffer *buffer;
+  GtkTextIter iter;
+  guint line;
+  guint line_offset;
+
+  IDE_ENTRY;
+
+  g_assert (GB_IS_EDITOR_VIEW (self));
+  g_assert (location != NULL);
+
+  frame = gb_editor_view_get_last_focused (self);
+  buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (frame->source_view));
+
+  line = ide_source_location_get_line (location);
+  line_offset = ide_source_location_get_line_offset (location);
+
+  gtk_text_buffer_get_iter_at_line (buffer, &iter, line);
+  for (; line_offset; line_offset--)
+    if (gtk_text_iter_ends_line (&iter) || !gtk_text_iter_forward_char (&iter))
+      break;
+
+  gtk_text_buffer_select_range (buffer, &iter, &iter);
+  ide_source_view_scroll_to_iter (frame->source_view, &iter, 0.0, TRUE, 1.0, 0.5);
+
+  IDE_EXIT;
+}
+
 static gboolean
 language_to_string (GBinding     *binding,
                     const GValue *from_value,
@@ -234,6 +274,7 @@ gb_editor_view_class_init (GbEditorViewClass *klass)
   view_class->get_document = gb_editor_view_get_document;
   view_class->set_split_view = gb_editor_view_set_split_view;
   view_class->set_back_forward_list = gb_editor_view_set_back_forward_list;
+  view_class->navigate_to = gb_editor_view_navigate_to;
 
   gParamSpecs [PROP_DOCUMENT] =
     g_param_spec_object ("document",
diff --git a/src/views/gb-view-stack-private.h b/src/views/gb-view-stack-private.h
index 9905a68..7671dfc 100644
--- a/src/views/gb-view-stack-private.h
+++ b/src/views/gb-view-stack-private.h
@@ -20,6 +20,7 @@
 #define GB_VIEW_STACK_PRIVATE_H
 
 #include <gtk/gtk.h>
+#include <ide.h>
 
 G_BEGIN_DECLS
 
@@ -32,6 +33,7 @@ struct _GbViewStack
 
   /* Weak references */
   GtkWidget          *active_view;
+  IdeContext         *context;
   GBinding           *title_binding;
 
   /* Template references */
diff --git a/src/views/gb-view-stack.c b/src/views/gb-view-stack.c
index fdc2840..8862984 100644
--- a/src/views/gb-view-stack.c
+++ b/src/views/gb-view-stack.c
@@ -167,30 +167,13 @@ navigate_to_cb (GbViewStack        *self,
                 IdeBackForwardList *back_forward_list)
 {
   IdeSourceLocation *srcloc;
-  IdeFile *file;
-  guint line;
-  guint line_offset;
 
   g_assert (GB_IS_VIEW_STACK (self));
   g_assert (IDE_IS_BACK_FORWARD_ITEM (item));
   g_assert (IDE_IS_BACK_FORWARD_LIST (back_forward_list));
 
   srcloc = ide_back_forward_item_get_location (item);
-  file = ide_source_location_get_file (srcloc);
-  line = ide_source_location_get_line (srcloc);
-  line_offset = ide_source_location_get_line_offset (srcloc);
-
-  /* implausable ... but defensive */
-  if (file == NULL)
-    return;
-
-  /* TODO: get buffer for file, move cursor to location */
-
-  {
-    gchar *path = g_file_get_path (ide_file_get_file (file));
-    g_print (">>> Load document %s +%u:%u\n", path, line, line_offset);
-    g_free (path);
-  }
+  gb_view_stack_focus_location (self, srcloc);
 }
 
 static void
@@ -205,6 +188,8 @@ gb_view_stack_context_handler (GtkWidget  *widget,
 
   if (context)
     {
+      ide_set_weak_pointer (&self->context, context);
+
       back_forward = ide_context_get_back_forward_list (context);
 
       g_clear_object (&self->back_forward_list);
@@ -241,6 +226,7 @@ gb_view_stack_finalize (GObject *object)
   GbViewStack *self = (GbViewStack *)object;
 
   g_clear_pointer (&self->focus_history, g_list_free);
+  ide_clear_weak_pointer (&self->context);
   ide_clear_weak_pointer (&self->title_binding);
   ide_clear_weak_pointer (&self->active_view);
   g_clear_object (&self->back_forward_list);
@@ -493,3 +479,85 @@ gb_view_stack_focus_document (GbViewStack *self,
   gb_view_stack_set_active_view (self, view);
   gtk_widget_grab_focus (view);
 }
+
+static void
+gb_view_stack__navigate_to_load_cb (GObject      *object,
+                                    GAsyncResult *result,
+                                    gpointer      user_data)
+{
+  IdeBufferManager *buffer_manager = (IdeBufferManager *)object;
+  GbViewStack *self;
+  g_autoptr(GTask) task = user_data;
+  IdeSourceLocation *location;
+  g_autoptr(IdeBuffer) buffer = NULL;
+  g_autoptr(GError) error = NULL;
+  GtkWidget *active_view;
+
+  g_assert (IDE_IS_BUFFER_MANAGER (buffer_manager));
+
+  self = g_task_get_source_object (task);
+  location = g_task_get_task_data (task);
+
+  buffer = ide_buffer_manager_load_file_finish (buffer_manager, result, &error);
+
+  if (buffer == NULL)
+    {
+      /* todo: message dialog? */
+      g_warning ("%s", error->message);
+      return;
+    }
+
+  g_assert (GB_IS_DOCUMENT (buffer));
+  g_assert (location != NULL);
+
+  gb_view_stack_focus_document (self, GB_DOCUMENT (buffer));
+  active_view = gb_view_stack_get_active_view (self);
+  g_assert (GB_DOCUMENT (buffer) == gb_view_get_document (GB_VIEW (active_view)));
+  gb_view_navigate_to (GB_VIEW (active_view), location);
+
+  g_task_return_boolean (task, TRUE);
+}
+
+void
+gb_view_stack_focus_location (GbViewStack       *self,
+                              IdeSourceLocation *location)
+{
+  IdeBufferManager *buffer_manager;
+  IdeBuffer *buffer;
+  IdeFile *file;
+
+  g_return_if_fail (GB_IS_VIEW_STACK (self));
+  g_return_if_fail (location != NULL);
+
+  if (self->context == NULL)
+    return;
+
+  file = ide_source_location_get_file (location);
+
+  g_assert (file != NULL);
+  g_assert (IDE_IS_FILE (file));
+
+  buffer_manager = ide_context_get_buffer_manager (self->context);
+  buffer = ide_buffer_manager_find_buffer (buffer_manager, file);
+
+  if (buffer != NULL && GB_IS_DOCUMENT (buffer))
+    {
+      GtkWidget *active_view;
+
+      gb_view_stack_focus_document (self, GB_DOCUMENT (buffer));
+      active_view = gb_view_stack_get_active_view (self);
+      g_assert (GB_DOCUMENT (buffer) == gb_view_get_document (GB_VIEW (active_view)));
+      gb_view_navigate_to (GB_VIEW (active_view), location);
+    }
+  else
+    {
+      g_autoptr(GTask) task = NULL;
+
+      task = g_task_new (self, NULL, NULL, NULL);
+      g_task_set_task_data (task, ide_source_location_ref (location),
+                            (GDestroyNotify)ide_source_location_unref);
+      ide_buffer_manager_load_file_async (buffer_manager, file, FALSE, NULL, NULL,
+                                          gb_view_stack__navigate_to_load_cb,
+                                          g_object_ref (task));
+    }
+}
diff --git a/src/views/gb-view-stack.h b/src/views/gb-view-stack.h
index 4113264..c641f96 100644
--- a/src/views/gb-view-stack.h
+++ b/src/views/gb-view-stack.h
@@ -20,6 +20,7 @@
 #define GB_VIEW_STACK_H
 
 #include <gtk/gtk.h>
+#include <ide.h>
 
 #include "gb-document.h"
 #include "gb-view.h"
@@ -31,15 +32,17 @@ G_BEGIN_DECLS
 G_DECLARE_FINAL_TYPE (GbViewStack, gb_view_stack, GB, VIEW_STACK, GtkBin)
 
 GtkWidget *gb_view_stack_new                (void);
-void       gb_view_stack_remove             (GbViewStack *self,
-                                             GbView      *view);
-GtkWidget *gb_view_stack_get_active_view    (GbViewStack *self);
-void       gb_view_stack_set_active_view    (GbViewStack *self,
-                                             GtkWidget   *active_view);
-GtkWidget *gb_view_stack_find_with_document (GbViewStack *self,
-                                             GbDocument  *document);
-void       gb_view_stack_focus_document     (GbViewStack *self,
-                                             GbDocument  *document);
+void       gb_view_stack_remove             (GbViewStack       *self,
+                                             GbView            *view);
+GtkWidget *gb_view_stack_get_active_view    (GbViewStack       *self);
+void       gb_view_stack_set_active_view    (GbViewStack       *self,
+                                             GtkWidget         *active_view);
+GtkWidget *gb_view_stack_find_with_document (GbViewStack       *self,
+                                             GbDocument        *document);
+void       gb_view_stack_focus_document     (GbViewStack       *self,
+                                             GbDocument        *document);
+void      gb_view_stack_focus_location      (GbViewStack       *self,
+                                             IdeSourceLocation *location);
 
 G_END_DECLS
 
diff --git a/src/views/gb-view.c b/src/views/gb-view.c
index 535ae81..12ad936 100644
--- a/src/views/gb-view.c
+++ b/src/views/gb-view.c
@@ -177,6 +177,17 @@ gb_view_set_back_forward_list (GbView             *self,
     GB_VIEW_GET_CLASS (self)->set_back_forward_list (self, back_forward_list);
 }
 
+void
+gb_view_navigate_to (GbView            *self,
+                     IdeSourceLocation *location)
+{
+  g_return_if_fail (GB_IS_VIEW (self));
+  g_return_if_fail (location != NULL);
+
+  if (GB_VIEW_GET_CLASS (self)->navigate_to)
+    GB_VIEW_GET_CLASS (self)->navigate_to (self, location);
+}
+
 static void
 gb_view_destroy (GtkWidget *widget)
 {
diff --git a/src/views/gb-view.h b/src/views/gb-view.h
index 208509c..ecdb7a7 100644
--- a/src/views/gb-view.h
+++ b/src/views/gb-view.h
@@ -43,6 +43,8 @@ struct _GbViewClass
                                          gboolean            split_view);
   void         (*set_back_forward_list) (GbView             *self,
                                          IdeBackForwardList *back_forward_list);
+  void         (*navigate_to)           (GbView             *self,
+                                         IdeSourceLocation  *location);
 };
 
 GbView      *gb_view_create_split          (GbView             *self);
@@ -55,6 +57,8 @@ void         gb_view_set_split_view        (GbView             *self,
                                             gboolean            split_view);
 void         gb_view_set_back_forward_list (GbView             *self,
                                             IdeBackForwardList *back_forward_list);
+void         gb_view_navigate_to           (GbView             *self,
+                                            IdeSourceLocation  *location);
 
 G_END_DECLS
 


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