[gnome-builder/wip/libide-merge] allow reloading the buffer when it changes on disk



commit b9727de097225c4d6862885ab88e15c0ce95a5e0
Author: Christian Hergert <christian hergert me>
Date:   Sun Mar 22 19:25:31 2015 -0700

    allow reloading the buffer when it changes on disk

 libide/ide-buffer-manager.c         |    4 ++
 libide/ide-buffer.c                 |   14 +++++-
 libide/ide-internal.h               |    2 +
 src/editor/gb-editor-frame.c        |    7 +++
 src/editor/gb-editor-view-actions.c |    2 +
 src/editor/gb-editor-view.c         |   75 +++++++++++++++++++++++++++++++++++
 6 files changed, 101 insertions(+), 3 deletions(-)
---
diff --git a/libide/ide-buffer-manager.c b/libide/ide-buffer-manager.c
index 186b761..f5994c9 100644
--- a/libide/ide-buffer-manager.c
+++ b/libide/ide-buffer-manager.c
@@ -710,6 +710,8 @@ ide_buffer_manager_load_file_async (IdeBufferManager     *self,
                                       NULL);
     }
 
+  _ide_buffer_set_mtime (state->buffer, NULL);
+  _ide_buffer_set_changed_on_volume (state->buffer, FALSE);
   _ide_buffer_set_loading (state->buffer, TRUE);
 
   g_task_set_task_data (task, state, load_state_free);
@@ -875,6 +877,8 @@ ide_buffer_manager_save_file__load_settings_cb (GObject      *object,
   gtk_source_file_saver_set_encoding (saver, encoding);
   gtk_source_file_saver_set_newline_type (saver, newline_type);
 
+  _ide_buffer_set_mtime (state->buffer, NULL);
+
   gtk_source_file_saver_save_async (saver,
                                     G_PRIORITY_DEFAULT,
                                     g_task_get_cancellable (task),
diff --git a/libide/ide-buffer.c b/libide/ide-buffer.c
index 8e46aa6..901a222 100644
--- a/libide/ide-buffer.c
+++ b/libide/ide-buffer.c
@@ -1489,12 +1489,14 @@ ide_buffer_get_changed_on_volume (IdeBuffer *self)
   return priv->changed_on_volume;
 }
 
-static void
-ide_buffer_set_changed_on_volumne (IdeBuffer *self,
+void
+_ide_buffer_set_changed_on_volume (IdeBuffer *self,
                                    gboolean   changed_on_volume)
 {
   IdeBufferPrivate *priv = ide_buffer_get_instance_private (self);
 
+  IDE_ENTRY;
+
   g_return_if_fail (IDE_IS_BUFFER (self));
 
   changed_on_volume = !!changed_on_volume;
@@ -1504,6 +1506,8 @@ ide_buffer_set_changed_on_volumne (IdeBuffer *self,
       priv->changed_on_volume = changed_on_volume;
       g_object_notify_by_pspec (G_OBJECT (self), gParamSpecs [PROP_CHANGED_ON_VOLUME]);
     }
+
+  IDE_EXIT;
 }
 
 static void
@@ -1539,7 +1543,7 @@ ide_buffer__check_for_volume_cb (GObject      *object,
           g_file_info_get_modification_time (file_info, &tv);
 
           if (memcmp (&tv, &priv->mtime, sizeof tv) != 0)
-            ide_buffer_set_changed_on_volumne (self, TRUE);
+            _ide_buffer_set_changed_on_volume (self, TRUE);
         }
     }
 }
@@ -1575,6 +1579,8 @@ _ide_buffer_set_mtime (IdeBuffer      *self,
 {
   IdeBufferPrivate *priv = ide_buffer_get_instance_private (self);
 
+  IDE_ENTRY;
+
   g_return_if_fail (IDE_IS_BUFFER (self));
 
   if (mtime == NULL)
@@ -1588,4 +1594,6 @@ _ide_buffer_set_mtime (IdeBuffer      *self,
       priv->mtime = *mtime;
       priv->mtime_set = TRUE;
     }
+
+  IDE_EXIT;
 }
diff --git a/libide/ide-internal.h b/libide/ide-internal.h
index 201d8a4..6889e4c 100644
--- a/libide/ide-internal.h
+++ b/libide/ide-internal.h
@@ -50,6 +50,8 @@ gboolean            _ide_back_forward_list_save_finish (IdeBackForwardList    *s
                                                         GError               **error);
 IdeBackForwardItem *_ide_back_forward_list_find        (IdeBackForwardList    *self,
                                                         IdeFile               *file);
+void                _ide_buffer_set_changed_on_volume  (IdeBuffer             *self,
+                                                        gboolean               changed_on_volume);
 gboolean            _ide_buffer_get_loading            (IdeBuffer             *self);
 void                _ide_buffer_set_loading            (IdeBuffer             *self,
                                                         gboolean               loading);
diff --git a/src/editor/gb-editor-frame.c b/src/editor/gb-editor-frame.c
index 17d2c51..07852f8 100644
--- a/src/editor/gb-editor-frame.c
+++ b/src/editor/gb-editor-frame.c
@@ -330,11 +330,18 @@ gb_editor_frame__source_view_focus_in_event (GbEditorFrame *self,
                                              GdkEventKey   *event,
                                              IdeSourceView *source_view)
 {
+  GtkTextBuffer *buffer;
+
   g_assert (GB_IS_EDITOR_FRAME (self));
   g_assert (IDE_IS_SOURCE_VIEW (source_view));
 
   gtk_revealer_set_reveal_child (self->search_revealer, FALSE);
 
+  buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (source_view));
+
+  if (IDE_IS_BUFFER (buffer))
+    ide_buffer_check_for_volume_change (IDE_BUFFER (buffer));
+
   return FALSE;
 }
 
diff --git a/src/editor/gb-editor-view-actions.c b/src/editor/gb-editor-view-actions.c
index 868540a..b566273 100644
--- a/src/editor/gb-editor-view-actions.c
+++ b/src/editor/gb-editor-view-actions.c
@@ -522,6 +522,8 @@ gb_editor_view_actions_reload_buffer_cb (GObject      *object,
   g_assert (IDE_IS_BUFFER_MANAGER (buffer_manager));
   g_assert (GB_IS_EDITOR_VIEW (self));
 
+  gtk_revealer_set_reveal_child (self->modified_revealer, FALSE);
+
   if (!(buffer = ide_buffer_manager_load_file_finish (buffer_manager, result, &error)))
     {
       g_warning ("%s", error->message);
diff --git a/src/editor/gb-editor-view.c b/src/editor/gb-editor-view.c
index c1fd73f..b6ad449 100644
--- a/src/editor/gb-editor-view.c
+++ b/src/editor/gb-editor-view.c
@@ -119,6 +119,75 @@ gb_editor_view__buffer_modified_changed (GbEditorView  *self,
 }
 
 static void
+force_scroll_to_top (IdeSourceView *source_view)
+{
+  GtkAdjustment *vadj;
+  GtkAdjustment *hadj;
+  gdouble lower;
+
+  /*
+   * FIXME:
+   *
+   * See the comment in gb_editor_view__buffer_changed_on_volume()
+   */
+
+  vadj = gtk_scrollable_get_vadjustment (GTK_SCROLLABLE (source_view));
+  hadj = gtk_scrollable_get_hadjustment (GTK_SCROLLABLE (source_view));
+
+  lower = gtk_adjustment_get_lower (vadj);
+  gtk_adjustment_set_value (vadj, lower);
+
+  lower = gtk_adjustment_get_lower (hadj);
+  gtk_adjustment_set_value (hadj, lower);
+}
+
+static gboolean
+no_really_scroll_to_the_top (gpointer data)
+{
+  g_autoptr(GbEditorView) self = data;
+
+  force_scroll_to_top (self->frame1->source_view);
+  if (self->frame2 != NULL)
+    force_scroll_to_top (self->frame2->source_view);
+
+  return G_SOURCE_REMOVE;
+}
+
+static void
+gb_editor_view__buffer_changed_on_volume (GbEditorView *self,
+                                          GParamSpec   *pspec,
+                                          IdeBuffer    *buffer)
+{
+  g_assert (GB_IS_EDITOR_VIEW (self));
+  g_assert (IDE_IS_BUFFER (buffer));
+
+  if (ide_buffer_get_changed_on_volume (buffer))
+    gtk_revealer_set_reveal_child (self->modified_revealer, TRUE);
+  else if (gtk_revealer_get_reveal_child (self->modified_revealer))
+    {
+      GtkTextIter iter;
+
+      gtk_text_buffer_get_start_iter (GTK_TEXT_BUFFER (buffer), &iter);
+      gtk_text_buffer_select_range (GTK_TEXT_BUFFER (buffer), &iter, &iter);
+
+      /*
+       * FIXME:
+       *
+       * Without this delay, I see a condition with split view where the
+       * non-focused split will just render blank. Well that isn't totally
+       * correct, it renders empty gutters and proper line grid background. But
+       * no textual content. And the adjustment is way out of sync. Even
+       * changing the adjustment manually doesn't help. So whatever, I'll
+       * insert a short delay and we'll pick up after the textview has
+       * stablized.
+       */
+      g_timeout_add (10, no_really_scroll_to_the_top, g_object_ref (self));
+
+      gtk_revealer_set_reveal_child (self->modified_revealer, FALSE);
+    }
+}
+
+static void
 gb_editor_view_set_document (GbEditorView     *self,
                              GbEditorDocument *document)
 {
@@ -150,6 +219,12 @@ gb_editor_view_set_document (GbEditorView     *self,
                                self,
                                G_CONNECT_SWAPPED);
 
+      g_signal_connect_object (document,
+                               "notify::changed-on-volume",
+                               G_CALLBACK (gb_editor_view__buffer_changed_on_volume),
+                               self,
+                               G_CONNECT_SWAPPED);
+
       g_object_notify_by_pspec (G_OBJECT (self), gParamSpecs [PROP_DOCUMENT]);
 
       gb_editor_view_actions_update (self);


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