[gnome-builder] glade: allow reloading GladeProject for view
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-builder] glade: allow reloading GladeProject for view
- Date: Mon, 22 Oct 2018 23:05:55 +0000 (UTC)
commit 226e17dd75237a0ac2afd7fd228a2baf2709e54e
Author: Christian Hergert <chergert redhat com>
Date: Mon Oct 22 16:04:10 2018 -0700
glade: allow reloading GladeProject for view
This allows us to reload a glade project in what seems like "in-place".
Supporting this will allow us to track changes from the editor immediately.
src/plugins/glade/gbp-glade-private.h | 2 +
src/plugins/glade/gbp-glade-view.c | 154 ++++++++++++++++++++++++++++++++--
2 files changed, 149 insertions(+), 7 deletions(-)
---
diff --git a/src/plugins/glade/gbp-glade-private.h b/src/plugins/glade/gbp-glade-private.h
index 00098dee2..4408e40b7 100644
--- a/src/plugins/glade/gbp-glade-private.h
+++ b/src/plugins/glade/gbp-glade-private.h
@@ -35,11 +35,13 @@ struct _GbpGladeView
GladeProject *project;
GladeDesignView *designer;
GladeAdaptorChooser *chooser;
+ GtkBox *main_box;
};
void _gbp_glade_view_init_actions (GbpGladeView *self);
void _gbp_glade_view_init_shortcuts (GtkWidget *widget);
void _gbp_glade_view_update_actions (GbpGladeView *self);
+gboolean _gbp_glade_view_reload (GbpGladeView *self);
gboolean _gbp_glade_view_save (GbpGladeView *self,
GError **error);
diff --git a/src/plugins/glade/gbp-glade-view.c b/src/plugins/glade/gbp-glade-view.c
index 92d235435..a930fe006 100644
--- a/src/plugins/glade/gbp-glade-view.c
+++ b/src/plugins/glade/gbp-glade-view.c
@@ -29,6 +29,14 @@
G_DEFINE_TYPE (GbpGladeView, gbp_glade_view, IDE_TYPE_LAYOUT_VIEW)
+enum {
+ PROP_0,
+ PROP_PROJECT,
+ N_PROPS
+};
+
+static GParamSpec *properties [N_PROPS];
+
/**
* gbp_glade_view_new:
*
@@ -58,6 +66,101 @@ gbp_glade_view_changed_cb (GbpGladeView *self,
_gbp_glade_view_update_actions (self);
}
+static void
+gbp_glade_view_set_project (GbpGladeView *self,
+ GladeProject *project)
+{
+ g_assert (GBP_IS_GLADE_VIEW (self));
+ g_assert (GLADE_IS_PROJECT (project));
+
+ if (project == self->project)
+ return;
+
+ if (gtk_widget_in_destruction (GTK_WIDGET (self)))
+ return;
+
+ if (self->project != NULL)
+ {
+ g_signal_handlers_disconnect_by_func (self->project,
+ G_CALLBACK (gbp_glade_view_changed_cb),
+ self);
+ g_clear_object (&self->project);
+ }
+
+ if (project != NULL)
+ {
+ self->project = g_object_ref (project);
+ g_signal_connect_object (self->project,
+ "changed",
+ G_CALLBACK (gbp_glade_view_changed_cb),
+ self,
+ G_CONNECT_SWAPPED);
+ }
+
+ if (self->designer != NULL)
+ {
+ gtk_widget_destroy (GTK_WIDGET (self->designer));
+ g_assert (self->designer == NULL);
+
+ if (self->project != NULL)
+ {
+ self->designer = g_object_new (GLADE_TYPE_DESIGN_VIEW,
+ "project", self->project,
+ "vexpand", TRUE,
+ "visible", TRUE,
+ NULL);
+ g_signal_connect (self->designer,
+ "destroy",
+ G_CALLBACK (gtk_widget_destroyed),
+ &self->designer);
+ dzl_gtk_widget_add_style_class (GTK_WIDGET (self->designer), "glade-designer");
+ gtk_container_add_with_properties (GTK_CONTAINER (self->main_box), GTK_WIDGET (self->designer),
+ "pack-type", GTK_PACK_START,
+ "position", 0,
+ NULL);
+ }
+ }
+
+ if (self->chooser != NULL)
+ glade_adaptor_chooser_set_project (self->chooser, self->project);
+
+ g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_PROJECT]);
+}
+
+gboolean
+_gbp_glade_view_reload (GbpGladeView *self)
+{
+ GladeProject *project;
+ gboolean ret;
+
+ g_return_val_if_fail (GBP_IS_GLADE_VIEW (self), FALSE);
+ g_return_val_if_fail (GLADE_IS_PROJECT (self->project), FALSE);
+
+ /*
+ * Switch to a new GladeProject object, which is rather tricky
+ * because we need to update everything that connected to it.
+ * Sadly we can't reuse existing GladeProject objects.
+ */
+ project = glade_project_new ();
+ gbp_glade_view_set_project (self, project);
+ gbp_glade_view_load_file_async (self, self->file, NULL, NULL, NULL);
+ g_clear_object (&project);
+
+ /*
+ * This is sort of a hack, buf if we want everything to adapt to our
+ * new project, we need to signal that the view changed so that it
+ * grabs the new version of our GladeProject.
+ */
+ if (gtk_widget_get_visible (GTK_WIDGET (self)) &&
+ gtk_widget_get_child_visible (GTK_WIDGET (self)))
+ {
+ gtk_widget_hide (GTK_WIDGET (self));
+ gtk_widget_show (GTK_WIDGET (self));
+ }
+
+ return ret;
+}
+
gboolean
_gbp_glade_view_save (GbpGladeView *self,
GError **error)
@@ -148,6 +251,25 @@ gbp_glade_view_dispose (GObject *object)
G_OBJECT_CLASS (gbp_glade_view_parent_class)->dispose (object);
}
+static void
+gbp_glade_view_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ GbpGladeView *self = GBP_GLADE_VIEW (object);
+
+ switch (prop_id)
+ {
+ case PROP_PROJECT:
+ g_value_set_object (value, gbp_glade_view_get_project (self));
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
static void
gbp_glade_view_class_init (GbpGladeViewClass *klass)
{
@@ -156,10 +278,20 @@ gbp_glade_view_class_init (GbpGladeViewClass *klass)
IdeLayoutViewClass *view_class = IDE_LAYOUT_VIEW_CLASS (klass);
object_class->dispose = gbp_glade_view_dispose;
+ object_class->get_property = gbp_glade_view_get_property;
view_class->agree_to_close_async = gbp_glade_view_agree_to_close_async;
view_class->agree_to_close_finish = gbp_glade_view_agree_to_close_finish;
+ properties [PROP_PROJECT] =
+ g_param_spec_object ("project",
+ "Project",
+ "The project for the view",
+ GLADE_TYPE_PROJECT,
+ (G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
+
+ g_object_class_install_properties (object_class, N_PROPS, properties);
+
gtk_widget_class_set_css_name (widget_class, "gbpgladeview");
}
@@ -193,18 +325,22 @@ gbp_glade_view_init (GbpGladeView *self)
self,
G_CONNECT_SWAPPED);
- box = g_object_new (GTK_TYPE_BOX,
- "orientation", GTK_ORIENTATION_VERTICAL,
- "visible", TRUE,
- NULL);
- gtk_container_add (GTK_CONTAINER (self), GTK_WIDGET (box));
+ self->main_box = g_object_new (GTK_TYPE_BOX,
+ "orientation", GTK_ORIENTATION_VERTICAL,
+ "visible", TRUE,
+ NULL);
+ gtk_container_add (GTK_CONTAINER (self), GTK_WIDGET (self->main_box));
self->chooser = g_object_new (GLADE_TYPE_ADAPTOR_CHOOSER,
"project", self->project,
"visible", TRUE,
NULL);
+ g_signal_connect (self->chooser,
+ "destroy",
+ G_CALLBACK (gtk_widget_destroyed),
+ &self->chooser);
dzl_gtk_widget_add_style_class (GTK_WIDGET (self->chooser), "glade-chooser");
- gtk_container_add_with_properties (GTK_CONTAINER (box), GTK_WIDGET (self->chooser),
+ gtk_container_add_with_properties (GTK_CONTAINER (self->main_box), GTK_WIDGET (self->chooser),
"pack-type", GTK_PACK_END,
NULL);
@@ -213,8 +349,12 @@ gbp_glade_view_init (GbpGladeView *self)
"vexpand", TRUE,
"visible", TRUE,
NULL);
+ g_signal_connect (self->designer,
+ "destroy",
+ G_CALLBACK (gtk_widget_destroyed),
+ &self->designer);
dzl_gtk_widget_add_style_class (GTK_WIDGET (self->designer), "glade-designer");
- gtk_container_add (GTK_CONTAINER (box), GTK_WIDGET (self->designer));
+ gtk_container_add (GTK_CONTAINER (self->main_box), GTK_WIDGET (self->designer));
/* Discover viewport so that we can track the background color changes
* from CSS. That is used to set our primary color.
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]