[gnome-builder/document-manager] documents: add support for documents to create preview documents



commit b17f0f0c1d487396bda5245b2aa5f028891872ec
Author: Christian Hergert <christian hergert me>
Date:   Mon Dec 8 20:07:40 2014 -0800

    documents: add support for documents to create preview documents
    
    These preview documents can then have views created for them to be shown
    in the document stacks.
    
    I find the whole thing simpler to just use docments and call create_view()
    rather than allowing the documents to create the preview view directly.
    This way, the same code gets exercised more rather than duplicate code.

 src/documents/gb-document-stack.c |   61 ++++++++++++++++++++++++++++++++-----
 src/documents/gb-document-view.c  |   36 ++++++++++++++++++++++
 src/documents/gb-document-view.h  |   18 +++++++----
 src/resources/gtk/menus.ui        |    6 ++++
 4 files changed, 106 insertions(+), 15 deletions(-)
---
diff --git a/src/documents/gb-document-stack.c b/src/documents/gb-document-stack.c
index fb615c5..cc51773 100644
--- a/src/documents/gb-document-stack.c
+++ b/src/documents/gb-document-stack.c
@@ -28,9 +28,11 @@ struct _GbDocumentStackPrivate
 {
   /* Objects ownen by GbDocumentStack */
   GbDocumentManager    *document_manager;
+  GActionGroup         *actions;
 
   /* Weak references */
   GbDocumentView       *active_view;
+  GBinding             *preview_binding;
 
   /* GtkWidgets owned by GtkWidgetClass template */
   GbDocumentMenuButton *document_button;
@@ -228,13 +230,29 @@ gb_document_stack_set_active_view (GbDocumentStack *stack,
 
   if (active_view != stack->priv->active_view)
     {
-      gb_clear_weak_pointer (&stack->priv->active_view);
-      gb_set_weak_pointer (active_view, &stack->priv->active_view);
+      if (stack->priv->active_view)
+        {
+          if (stack->priv->preview_binding)
+            {
+              g_binding_unbind (stack->priv->preview_binding);
+              gb_clear_weak_pointer (&stack->priv->preview_binding);
+            }
+          gb_clear_weak_pointer (&stack->priv->active_view);
+        }
 
       if (active_view)
         {
           GtkWidget *controls;
 
+          stack->priv->preview_binding =
+            g_object_bind_property (active_view, "can-preview",
+                                    g_action_map_lookup_action (G_ACTION_MAP (stack->priv->actions), 
"preview"), "enabled",
+                                    G_BINDING_SYNC_CREATE);
+          gb_set_weak_pointer (stack->priv->preview_binding,
+                               &stack->priv->preview_binding);
+
+          gb_set_weak_pointer (active_view, &stack->priv->active_view);
+
           gtk_stack_set_visible_child (stack->priv->stack,
                                        GTK_WIDGET (active_view));
 
@@ -394,6 +412,33 @@ gb_document_stack_close (GSimpleAction *action,
 }
 
 static void
+gb_document_stack_preview_activate (GSimpleAction *action,
+                                    GVariant      *parameter,
+                                    gpointer       user_data)
+{
+  GbDocumentStackPrivate *priv;
+  GbDocumentStack *stack = user_data;
+
+  g_return_if_fail (GB_IS_DOCUMENT_STACK (stack));
+
+  priv = stack->priv;
+
+  if (priv->active_view)
+    {
+      if (gb_document_view_get_can_preview (priv->active_view))
+        {
+          GbDocument *document;
+
+          document = gb_document_view_create_preview (priv->active_view);
+          gb_document_manager_add (priv->document_manager, document);
+
+          g_signal_emit (stack, gSignals [CREATE_VIEW], 0, document,
+                         GB_DOCUMENT_SPLIT_RIGHT);
+        }
+    }
+}
+
+static void
 gb_document_stack_grab_focus (GtkWidget *widget)
 {
   GbDocumentStack *stack = (GbDocumentStack *)widget;
@@ -584,6 +629,7 @@ gb_document_stack_finalize (GObject *object)
 
   gb_clear_weak_pointer (&priv->active_view);
   g_clear_object (&priv->document_manager);
+  g_clear_object (&priv->actions);
 
   G_OBJECT_CLASS (gb_document_stack_parent_class)->finalize (object);
 }
@@ -737,17 +783,16 @@ gb_document_stack_init (GbDocumentStack *self)
     { "focus-right", gb_document_stack_focus_right },
     { "focus-search", gb_document_stack_focus_search },
     { "close", gb_document_stack_close },
+    { "preview", gb_document_stack_preview_activate },
   };
-  GSimpleActionGroup *actions;
 
   self->priv = gb_document_stack_get_instance_private (self);
 
   gtk_widget_init_template (GTK_WIDGET (self));
 
-  actions = g_simple_action_group_new ();
-  g_action_map_add_action_entries (G_ACTION_MAP (actions), entries,
-                                   G_N_ELEMENTS (entries), self);
+  self->priv->actions = G_ACTION_GROUP (g_simple_action_group_new ());
+  g_action_map_add_action_entries (G_ACTION_MAP (self->priv->actions),
+                                   entries, G_N_ELEMENTS (entries), self);
   gtk_widget_insert_action_group (GTK_WIDGET (self), "stack",
-                                  G_ACTION_GROUP (actions));
-  g_clear_object (&actions);
+                                  G_ACTION_GROUP (self->priv->actions));
 }
diff --git a/src/documents/gb-document-view.c b/src/documents/gb-document-view.c
index 2c6f92b..4953389 100644
--- a/src/documents/gb-document-view.c
+++ b/src/documents/gb-document-view.c
@@ -38,6 +38,7 @@ G_DEFINE_ABSTRACT_TYPE_WITH_CODE (GbDocumentView,
 
 enum {
   PROP_0,
+  PROP_CAN_PREVIEW,
   PROP_CONTROLS,
   PROP_DOCUMENT,
   LAST_PROP
@@ -97,6 +98,28 @@ gb_document_view_close (GbDocumentView *view)
   g_signal_emit (view, gSignals [CLOSE], 0);
 }
 
+gboolean
+gb_document_view_get_can_preview (GbDocumentView *view)
+{
+  g_return_val_if_fail (GB_IS_DOCUMENT_VIEW (view), FALSE);
+
+  if (GB_DOCUMENT_VIEW_GET_CLASS (view)->get_can_preview)
+    return GB_DOCUMENT_VIEW_GET_CLASS (view)->get_can_preview (view);
+
+  return FALSE;
+}
+
+GbDocument *
+gb_document_view_create_preview (GbDocumentView *view)
+{
+  g_return_val_if_fail (GB_IS_DOCUMENT_VIEW (view), NULL);
+
+  if (GB_DOCUMENT_VIEW_GET_CLASS (view)->create_preview)
+    return GB_DOCUMENT_VIEW_GET_CLASS (view)->create_preview (view);
+
+  return NULL;
+}
+
 static GObject *
 gb_document_view_get_internal_child (GtkBuildable *buildable,
                                      GtkBuilder   *builder,
@@ -130,6 +153,10 @@ gb_document_view_get_property (GObject    *object,
 
   switch (prop_id)
     {
+    case PROP_CAN_PREVIEW:
+      g_value_set_boolean (value, gb_document_view_get_can_preview (self));
+      break;
+
     case PROP_CONTROLS:
       g_value_set_object (value, gb_document_view_get_controls (self));
       break;
@@ -153,6 +180,15 @@ gb_document_view_class_init (GbDocumentViewClass *klass)
 
   widget_class->destroy = gb_document_view_destroy;
 
+  gParamSpecs [PROP_CAN_PREVIEW] =
+    g_param_spec_boolean ("can-preview",
+                         _("Can Preview"),
+                         _("If the view can preview."),
+                         FALSE,
+                         (G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
+  g_object_class_install_property (object_class, PROP_CAN_PREVIEW,
+                                   gParamSpecs [PROP_CAN_PREVIEW]);
+
   gParamSpecs [PROP_CONTROLS] =
     g_param_spec_object ("controls",
                          _("Controls"),
diff --git a/src/documents/gb-document-view.h b/src/documents/gb-document-view.h
index b50be8c..5c2e3f9 100644
--- a/src/documents/gb-document-view.h
+++ b/src/documents/gb-document-view.h
@@ -49,15 +49,19 @@ struct _GbDocumentViewClass
 {
   GtkBoxClass parent;
 
-  GbDocument *(*get_document) (GbDocumentView *view);
-  gboolean    (*close)        (GbDocumentView *view);
+  GbDocument  *(*get_document)    (GbDocumentView *view);
+  gboolean     (*get_can_preview) (GbDocumentView *view);
+  gboolean     (*close)           (GbDocumentView *view);
+  GbDocument  *(*create_preview)  (GbDocumentView *view);
 };
 
-GType               gb_document_view_get_type     (void);
-GbDocumentView     *gb_document_view_new          (void);
-void                gb_document_view_close        (GbDocumentView *view);
-GbDocument         *gb_document_view_get_document (GbDocumentView *view);
-GtkWidget          *gb_document_view_get_controls (GbDocumentView *view);
+GType           gb_document_view_get_type        (void);
+GbDocumentView *gb_document_view_new             (void);
+GbDocument     *gb_document_view_create_preview  (GbDocumentView *view);
+void            gb_document_view_close           (GbDocumentView *view);
+GbDocument     *gb_document_view_get_document    (GbDocumentView *view);
+GtkWidget      *gb_document_view_get_controls    (GbDocumentView *view);
+gboolean        gb_document_view_get_can_preview (GbDocumentView *view);
 
 G_END_DECLS
 
diff --git a/src/resources/gtk/menus.ui b/src/resources/gtk/menus.ui
index 28ac026..93ae4af 100644
--- a/src/resources/gtk/menus.ui
+++ b/src/resources/gtk/menus.ui
@@ -126,6 +126,12 @@
     </section>
     <section>
       <item>
+        <attribute name="label" translatable="yes">Preview</attribute>
+        <attribute name="action">stack.preview</attribute>
+      </item>
+    </section>
+    <section>
+      <item>
         <attribute name="label" translatable="yes">Close Document</attribute>
         <attribute name="action">stack.close</attribute>
       </item>


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