[gnome-builder/wip/chergert/bug1: 34/42] debugger: load various sources from debugger



commit a0d9cea9f6903d89ca07e79889f10b288e48d994
Author: Christian Hergert <chergert redhat com>
Date:   Mon Aug 28 18:24:48 2017 -0700

    debugger: load various sources from debugger

 libide/debugger/ide-debugger-perspective.c |   94 +++++++++++----
 libide/debugger/ide-debugger-view.c        |  186 ++++++++++++++++++----------
 libide/debugger/ide-debugger-view.h        |   10 +-
 libide/debugger/ide-debugger-view.ui       |    4 +
 4 files changed, 198 insertions(+), 96 deletions(-)
---
diff --git a/libide/debugger/ide-debugger-perspective.c b/libide/debugger/ide-debugger-perspective.c
index 4114da2..8cd0096 100644
--- a/libide/debugger/ide-debugger-perspective.c
+++ b/libide/debugger/ide-debugger-perspective.c
@@ -33,6 +33,7 @@
 #include "debugger/ide-debugger-registers-view.h"
 #include "debugger/ide-debugger-threads-view.h"
 #include "debugger/ide-debugger-view.h"
+#include "files/ide-file.h"
 #include "layout/ide-layout-grid.h"
 #include "workbench/ide-perspective.h"
 #include "util/ide-gtk.h"
@@ -452,6 +453,7 @@ ide_debugger_perspective_disassemble_cb (GObject      *object,
   g_autoptr(GError) error = NULL;
   g_autoptr(GPtrArray) instructions = NULL;
   IdeDebuggerDisassemblyView *view = NULL;
+  GtkWidget *stack;
 
   IDE_ENTRY;
 
@@ -482,6 +484,10 @@ ide_debugger_perspective_disassemble_cb (GObject      *object,
   ide_debugger_disassembly_view_set_instructions (view, instructions);
 
   /* TODO: Set current instruction */
+
+  stack = gtk_widget_get_ancestor (GTK_WIDGET (view), IDE_TYPE_LAYOUT_STACK);
+  if (stack != NULL)
+    ide_layout_stack_set_visible_child (IDE_LAYOUT_STACK (stack), IDE_LAYOUT_VIEW (view));
 }
 
 void
@@ -521,7 +527,7 @@ ide_debugger_perspective_locate_by_file (GtkWidget *widget,
                                          gpointer   user_data)
 {
   struct {
-    const gchar     *file;
+    GFile *file;
     IdeDebuggerView *view;
   } *lookup = user_data;
 
@@ -530,15 +536,64 @@ ide_debugger_perspective_locate_by_file (GtkWidget *widget,
 
   if (IDE_IS_DEBUGGER_VIEW (widget))
     {
+      GFile *file = ide_debugger_view_get_file (IDE_DEBUGGER_VIEW (widget));
+
+      if (file != NULL && lookup->file != NULL && g_file_equal (file, lookup->file))
+        lookup->view = IDE_DEBUGGER_VIEW (widget);
+    }
+}
+
+static void
+ide_debugger_perspective_navigate_to_file (IdeDebuggerPerspective *self,
+                                           GFile                  *file,
+                                           guint                   line)
+{
+  GtkWidget *stack;
+  struct {
+    GFile *file;
+    IdeDebuggerView *view;
+  } lookup = { file, NULL };
+
+  g_assert (IDE_IS_DEBUGGER_PERSPECTIVE (self));
+  g_assert (G_IS_FILE (file));
+
+  ide_layout_grid_foreach_view (self->layout_grid,
+                                ide_debugger_perspective_locate_by_file,
+                                &lookup);
+
+  if (lookup.view == NULL)
+    {
+      lookup.view = g_object_new (IDE_TYPE_DEBUGGER_VIEW,
+                                  "visible", TRUE,
+                                  NULL);
+      gtk_container_add (GTK_CONTAINER (self->layout_grid), GTK_WIDGET (lookup.view));
     }
+
+  ide_debugger_view_set_file (lookup.view, lookup.file);
+  ide_debugger_view_set_current_line (lookup.view, line);
+
+  stack = gtk_widget_get_ancestor (GTK_WIDGET (lookup.view), IDE_TYPE_LAYOUT_STACK);
+  if (stack != NULL)
+    ide_layout_stack_set_visible_child (IDE_LAYOUT_STACK (stack), IDE_LAYOUT_VIEW (lookup.view));
 }
 
 void
 ide_debugger_perspective_navigate_to_location (IdeDebuggerPerspective *self,
                                                IdeSourceLocation      *location)
 {
+  IdeFile *file;
+  guint line;
+
   g_assert (IDE_IS_DEBUGGER_PERSPECTIVE (self));
   g_assert (location != NULL);
+
+  file = ide_source_location_get_file (location);
+  line = ide_source_location_get_line (location);
+
+  if (line > 0)
+    line--;
+
+  ide_debugger_perspective_navigate_to_file (self, ide_file_get_file (file), line);
 }
 
 void
@@ -546,10 +601,8 @@ ide_debugger_perspective_navigate_to_breakpoint (IdeDebuggerPerspective *self,
                                                  IdeDebuggerBreakpoint  *breakpoint)
 {
   IdeDebuggerAddress addr;
-  struct {
-    const gchar     *file;
-    IdeDebuggerView *view;
-  } lookup = { 0 };
+  const gchar *path;
+  guint line;
 
   IDE_ENTRY;
 
@@ -557,32 +610,25 @@ ide_debugger_perspective_navigate_to_breakpoint (IdeDebuggerPerspective *self,
   g_return_if_fail (IDE_IS_DEBUGGER_BREAKPOINT (breakpoint));
   g_return_if_fail (IDE_IS_DEBUGGER (self->debugger));
 
-  lookup.file = ide_debugger_breakpoint_get_file (breakpoint);
-  addr = ide_debugger_breakpoint_get_address (breakpoint);
+  path = ide_debugger_breakpoint_get_file (breakpoint);
+  line = ide_debugger_breakpoint_get_line (breakpoint);
 
-  /* Some breakpoints require disassembling */
-  if (lookup.file == NULL)
+  if (path != NULL)
     {
-      if (addr != IDE_DEBUGGER_ADDRESS_INVALID)
-        ide_debugger_perspective_navigate_to_address (self, addr);
-      IDE_EXIT;
-    }
+      g_autoptr(GFile) file = g_file_new_for_path (path);
 
-  g_return_if_fail (lookup.file != NULL);
+      if (line > 0)
+        line--;
 
-  ide_layout_grid_foreach_view (self->layout_grid,
-                                ide_debugger_perspective_locate_by_file,
-                                &lookup);
+      ide_debugger_perspective_navigate_to_file (self, file, line);
 
-  if (lookup.view != NULL)
-    {
-      //ide_debugger_view_scroll_to_line (lookup.view,
-                                        //ide_debugger_breakpoint_get_line (breakpoint));
-      gtk_widget_grab_focus (GTK_WIDGET (lookup.view));
-      return;
+      IDE_EXIT;
     }
 
-  g_print ("Need to load source\n");
+  addr = ide_debugger_breakpoint_get_address (breakpoint);
+
+  if (addr != IDE_DEBUGGER_ADDRESS_INVALID)
+    ide_debugger_perspective_navigate_to_address (self, addr);
 
   IDE_EXIT;
 }
diff --git a/libide/debugger/ide-debugger-view.c b/libide/debugger/ide-debugger-view.c
index 69149cc..4c8ffb9 100644
--- a/libide/debugger/ide-debugger-view.c
+++ b/libide/debugger/ide-debugger-view.c
@@ -30,77 +30,38 @@ struct _IdeDebuggerView
 {
   IdeLayoutView              parent_instance;
 
+  /* Owned references */
+  GFile                     *file;
+
+  /* Unowned references */
   GtkSourceView             *source_view;
+  GtkSourceBuffer           *source_buffer;
   IdeDebuggerGutterRenderer *breakpoints_gutter;
-};
 
-enum {
-  PROP_0,
-  PROP_BUFFER,
-  N_PROPS
+  guint                      current_line;
 };
 
 G_DEFINE_TYPE (IdeDebuggerView, ide_debugger_view, IDE_TYPE_LAYOUT_VIEW)
 
-static GParamSpec *properties [N_PROPS];
-
-static void
-ide_debugger_view_get_property (GObject    *object,
-                                guint       prop_id,
-                                GValue     *value,
-                                GParamSpec *pspec)
-{
-  IdeDebuggerView *self = IDE_DEBUGGER_VIEW (object);
-
-  switch (prop_id)
-    {
-    case PROP_BUFFER:
-      g_value_set_object (value, ide_debugger_view_get_buffer (self));
-      break;
-
-    default:
-      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
-    }
-}
-
 static void
-ide_debugger_view_set_property (GObject      *object,
-                                guint         prop_id,
-                                const GValue *value,
-                                GParamSpec   *pspec)
+ide_debugger_view_destroy (GtkWidget *widget)
 {
-  IdeDebuggerView *self = IDE_DEBUGGER_VIEW (object);
+  IdeDebuggerView *self = (IdeDebuggerView *)widget;
 
-  switch (prop_id)
-    {
-    case PROP_BUFFER:
-      ide_debugger_view_set_buffer (self, g_value_get_object (value));
-      break;
+  g_clear_object (&self->file);
 
-    default:
-      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
-    }
+  GTK_WIDGET_CLASS (ide_debugger_view_parent_class)->destroy (widget);
 }
 
 static void
 ide_debugger_view_class_init (IdeDebuggerViewClass *klass)
 {
-  GObjectClass *object_class = G_OBJECT_CLASS (klass);
   GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
 
-  object_class->get_property = ide_debugger_view_get_property;
-  object_class->set_property = ide_debugger_view_set_property;
-
-  properties [PROP_BUFFER] =
-    g_param_spec_object ("buffer",
-                         "Buffer",
-                         "The buffer for the view",
-                         GTK_SOURCE_TYPE_BUFFER,
-                         (G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS));
-
-  g_object_class_install_properties (object_class, N_PROPS, properties);
+  widget_class->destroy = ide_debugger_view_destroy;
 
   gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/builder/ui/ide-debugger-view.ui");
+  gtk_widget_class_bind_template_child (widget_class, IdeDebuggerView, source_buffer);
   gtk_widget_class_bind_template_child (widget_class, IdeDebuggerView, source_view);
 }
 
@@ -118,38 +79,127 @@ ide_debugger_view_init (IdeDebuggerView *self)
   gtk_source_gutter_insert (gutter, GTK_SOURCE_GUTTER_RENDERER (self->breakpoints_gutter), -100);
 }
 
-GtkWidget *
-ide_debugger_view_new (void)
+static void
+ide_debugger_view_apply_line (IdeDebuggerView *self)
+{
+  GtkTextIter iter;
+
+  g_assert (IDE_IS_DEBUGGER_VIEW (self));
+
+  gtk_text_buffer_get_iter_at_line_offset (GTK_TEXT_BUFFER (self->source_buffer),
+                                           &iter, self->current_line, 0);
+  gtk_text_buffer_select_range (GTK_TEXT_BUFFER (self->source_buffer), &iter, &iter);
+  gtk_text_view_scroll_to_iter (GTK_TEXT_VIEW (self->source_view), &iter, 0.25, TRUE, 1.0, 0.5);
+}
+
+static void
+progress_callback (goffset  current,
+                   goffset  total,
+                   gpointer user_data)
+{
+  /* TODO: Progress overlay */
+}
+
+static void
+ide_debugger_view_load_cb (GObject      *object,
+                           GAsyncResult *result,
+                           gpointer      user_data)
+{
+  GtkSourceFileLoader *loader = (GtkSourceFileLoader *)object;
+  g_autoptr(IdeDebuggerView) self = user_data;
+  g_autoptr(GError) error = NULL;
+
+  g_assert (GTK_SOURCE_IS_FILE_LOADER (loader));
+  g_assert (G_IS_ASYNC_RESULT (result));
+
+  if (!gtk_source_file_loader_load_finish (loader, result, &error))
+    {
+      ide_layout_view_report_error (IDE_LAYOUT_VIEW (self), "%s", error->message);
+      ide_layout_view_set_failed (IDE_LAYOUT_VIEW (self), TRUE);
+      return;
+    }
+
+  ide_debugger_view_apply_line (self);
+}
+
+void
+ide_debugger_view_set_file (IdeDebuggerView *self,
+                            GFile           *file)
 {
-  return g_object_new (IDE_TYPE_DEBUGGER_VIEW, NULL);
+  g_autoptr(GtkSourceFileLoader) loader = NULL;
+  g_autoptr(GtkSourceFile) source_file = NULL;
+  g_autofree gchar *title = NULL;
+  g_autofree gchar *name = NULL;
+
+  g_return_if_fail (IDE_IS_DEBUGGER_VIEW (self));
+  g_return_if_fail (!file || G_IS_FILE (file));
+
+  g_set_object (&self->file, file);
+
+  if (file == NULL)
+    {
+      gtk_text_buffer_set_text (GTK_TEXT_BUFFER (self->source_buffer), "", 0);
+      ide_layout_view_set_title (IDE_LAYOUT_VIEW (self), NULL);
+      ide_layout_view_set_icon_name (IDE_LAYOUT_VIEW (self), NULL);
+      return;
+    }
+
+  source_file = gtk_source_file_new ();
+  gtk_source_file_set_location (source_file, file);
+
+  loader = gtk_source_file_loader_new (self->source_buffer, source_file);
+
+  gtk_source_file_loader_load_async (loader,
+                                     G_PRIORITY_LOW,
+                                     NULL,
+                                     progress_callback,
+                                     self,
+                                     NULL,
+                                     ide_debugger_view_load_cb,
+                                     g_object_ref (self));
+
+  name = g_file_get_basename (file);
+
+  ide_layout_view_set_title (IDE_LAYOUT_VIEW (self), name);
+
+  /* TODO: Icon name */
 }
 
 /**
- * ide_debugger_view_get_buffer:
+ * ide_debugger_view_get_file:
  * @self: a #IdeDebuggerView
  *
- * Gets the buffer for the view.
+ * Gets the file being viewed.
  *
- * Returns: (transfer none): A #GtkSourceBuffer
+ * Returns: (transfer none) (nullable): A #GFile or %NULL
  */
-GtkSourceBuffer *
-ide_debugger_view_get_buffer (IdeDebuggerView *self)
+GFile *
+ide_debugger_view_get_file (IdeDebuggerView *self)
 {
   g_return_val_if_fail (IDE_IS_DEBUGGER_VIEW (self), NULL);
 
-  return GTK_SOURCE_BUFFER (gtk_text_view_get_buffer (GTK_TEXT_VIEW (self->source_view)));
+  return self->file;
 }
 
+/**
+ * ide_debugger_view_set_current_line:
+ * @self: a #IdeDebuggerView
+ * @current_line: the line number, starting from 0
+ *
+ * The line number to set as the current execution point of the debugger.
+ *
+ * Since: 3.26
+ */
 void
-ide_debugger_view_set_buffer (IdeDebuggerView *self,
-                              GtkSourceBuffer *buffer)
+ide_debugger_view_set_current_line (IdeDebuggerView *self,
+                                    guint            current_line)
 {
+  IDE_ENTRY;
+
   g_return_if_fail (IDE_IS_DEBUGGER_VIEW (self));
-  g_return_if_fail (GTK_SOURCE_IS_BUFFER (buffer));
 
-  if (buffer != ide_debugger_view_get_buffer (self))
-    {
-      gtk_text_view_set_buffer (GTK_TEXT_VIEW (self->source_view), GTK_TEXT_BUFFER (buffer));
-      g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_BUFFER]);
-    }
+  self->current_line = current_line;
+  ide_debugger_view_apply_line (self);
+
+  IDE_EXIT;
 }
diff --git a/libide/debugger/ide-debugger-view.h b/libide/debugger/ide-debugger-view.h
index 5151c04..cdbe042 100644
--- a/libide/debugger/ide-debugger-view.h
+++ b/libide/debugger/ide-debugger-view.h
@@ -28,9 +28,11 @@ G_BEGIN_DECLS
 
 G_DECLARE_FINAL_TYPE (IdeDebuggerView, ide_debugger_view, IDE, DEBUGGER_VIEW, IdeLayoutView)
 
-GtkWidget       *ide_debugger_view_new        (void);
-GtkSourceBuffer *ide_debugger_view_get_buffer (IdeDebuggerView *self);
-void             ide_debugger_view_set_buffer (IdeDebuggerView *self,
-                                               GtkSourceBuffer *buffer);
+GtkWidget       *ide_debugger_view_new              (void);
+GFile           *ide_debugger_view_get_file         (IdeDebuggerView *self);
+void             ide_debugger_view_set_file         (IdeDebuggerView *self,
+                                                     GFile           *file);
+void             ide_debugger_view_set_current_line (IdeDebuggerView *self,
+                                                     guint            current_line);
 
 G_END_DECLS
diff --git a/libide/debugger/ide-debugger-view.ui b/libide/debugger/ide-debugger-view.ui
index 42c911e..42d279b 100644
--- a/libide/debugger/ide-debugger-view.ui
+++ b/libide/debugger/ide-debugger-view.ui
@@ -7,6 +7,8 @@
         <property name="visible">true</property>
         <child>
           <object class="GtkSourceView" id="source_view">
+            <property name="buffer">source_buffer</property>
+            <property name="cursor-visible">false</property>
             <property name="highlight-current-line">true</property>
             <property name="show-line-numbers">true</property>
             <property name="monospace">true</property>
@@ -17,4 +19,6 @@
       </object>
     </child>
   </template>
+  <object class="GtkSourceBuffer" id="source_buffer">
+  </object>
 </interface>


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