[gnome-builder/document-manager] GbDocument: add simple document interface



commit eb201772c0026c2364fd7f2cb63a8bfcf77fbad1
Author: Christian Hergert <christian hergert me>
Date:   Wed Dec 3 14:35:33 2014 -0800

    GbDocument: add simple document interface
    
    The goal here is to have the "buffers" behind various tab implementations
    implement this and then we can create widgets for them dynamically.

 src/documents/gb-document.c     |   68 +++++++++++++++++++++++++
 src/documents/gb-document.h     |   48 ++++++++++++++++++
 src/editor/gb-editor-document.c |  106 ++++++++++++++++++++++++++++++++++++++-
 src/gnome-builder.mk            |    2 +
 4 files changed, 222 insertions(+), 2 deletions(-)
---
diff --git a/src/documents/gb-document.c b/src/documents/gb-document.c
new file mode 100644
index 0000000..a66282e
--- /dev/null
+++ b/src/documents/gb-document.c
@@ -0,0 +1,68 @@
+/* gb-document.c
+ *
+ * Copyright (C) 2014 Christian Hergert <christian hergert me>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <glib/gi18n.h>
+
+#include "gb-document.h"
+
+G_DEFINE_INTERFACE (GbDocument, gb_document, G_TYPE_OBJECT)
+
+enum {
+  PROP_0,
+  PROP_CAN_SAVE,
+  PROP_TITLE,
+  LAST_PROP
+};
+
+static GParamSpec *gParamSpecs [LAST_PROP];
+
+gboolean
+gb_document_get_can_save (GbDocument *document)
+{
+  g_return_val_if_fail (GB_IS_DOCUMENT (document), FALSE);
+
+  return GB_DOCUMENT_GET_INTERFACE (document)->get_can_save (document);
+}
+
+const gchar *
+gb_document_get_title (GbDocument *document)
+{
+  g_return_val_if_fail (GB_IS_DOCUMENT (document), NULL);
+
+  return GB_DOCUMENT_GET_INTERFACE (document)->get_title (document);
+}
+
+static void
+gb_document_default_init (GbDocumentInterface *iface)
+{
+  gParamSpecs [PROP_CAN_SAVE] =
+    g_param_spec_boolean ("can-save",
+                          _("Can Save"),
+                          _("If the document can be saved."),
+                          FALSE,
+                          (G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
+  g_object_interface_install_property (iface, gParamSpecs [PROP_CAN_SAVE]);
+
+  gParamSpecs [PROP_TITLE] =
+    g_param_spec_string ("title",
+                         _("Title"),
+                         _("The title of the document."),
+                         NULL,
+                         (G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
+  g_object_interface_install_property (iface, gParamSpecs [PROP_TITLE]);
+}
diff --git a/src/documents/gb-document.h b/src/documents/gb-document.h
new file mode 100644
index 0000000..219ef81
--- /dev/null
+++ b/src/documents/gb-document.h
@@ -0,0 +1,48 @@
+/* gb-document.h
+ *
+ * Copyright (C) 2014 Christian Hergert <christian hergert me>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GB_DOCUMENT_H
+#define GB_DOCUMENT_H
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define GB_TYPE_DOCUMENT               (gb_document_get_type ())
+#define GB_DOCUMENT(obj)               (G_TYPE_CHECK_INSTANCE_CAST ((obj), GB_TYPE_DOCUMENT, GbDocument))
+#define GB_IS_DOCUMENT(obj)            (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GB_TYPE_DOCUMENT))
+#define GB_DOCUMENT_GET_INTERFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), GB_TYPE_DOCUMENT, 
GbDocumentInterface))
+
+typedef struct _GbDocument      GbDocument;
+typedef struct _GbDocumentInterface GbDocumentInterface;
+
+struct _GbDocumentInterface
+{
+  GTypeInterface parent;
+
+  gboolean     (*get_can_save) (GbDocument *document);
+  const gchar *(*get_title)    (GbDocument *document);
+};
+
+GType        gb_document_get_type     (void) G_GNUC_CONST;
+gboolean     gb_document_get_can_save (GbDocument *document);
+const gchar *gb_document_get_title    (GbDocument *document);
+
+G_END_DECLS
+
+#endif /* GB_DOCUMENT_H */
diff --git a/src/editor/gb-editor-document.c b/src/editor/gb-editor-document.c
index e8c9695..672dc94 100644
--- a/src/editor/gb-editor-document.c
+++ b/src/editor/gb-editor-document.c
@@ -21,6 +21,8 @@
 #include <glib/gi18n.h>
 #include <gtksourceview/gtksource.h>
 
+#include "gb-document.h"
+#include "gb-doc-seq.h"
 #include "gb-editor-document.h"
 #include "gb-editor-file-marks.h"
 #include "gb-log.h"
@@ -31,15 +33,19 @@ struct _GbEditorDocumentPrivate
   GtkSourceFile         *file;
   GbSourceChangeMonitor *change_monitor;
   GbSourceCodeAssistant *code_assistant;
+  gchar                 *title;
 
-  guint trim_trailing_whitespace : 1;
+  guint                  doc_seq_id;
+  guint                  trim_trailing_whitespace : 1;
 };
 
 enum {
   PROP_0,
+  PROP_CAN_SAVE,
   PROP_CHANGE_MONITOR,
   PROP_FILE,
   PROP_STYLE_SCHEME_NAME,
+  PROP_TITLE,
   PROP_TRIM_TRAILING_WHITESPACE,
   LAST_PROP
 };
@@ -49,7 +55,16 @@ enum {
   LAST_SIGNAL
 };
 
-G_DEFINE_TYPE_WITH_PRIVATE (GbEditorDocument, gb_editor_document, GTK_SOURCE_TYPE_BUFFER)
+static void
+gb_editor_document_init_document (GbDocumentInterface *iface);
+
+G_DEFINE_TYPE_EXTENDED (GbEditorDocument,
+                        gb_editor_document,
+                        GTK_SOURCE_TYPE_BUFFER,
+                        0,
+                        G_ADD_PRIVATE (GbEditorDocument)
+                        G_IMPLEMENT_INTERFACE (GB_TYPE_DOCUMENT,
+                                               gb_editor_document_init_document))
 
 static GParamSpec *gParamSpecs [LAST_PROP];
 static guint gSignals [LAST_SIGNAL];
@@ -437,6 +452,28 @@ gb_editor_document_guess_language (GbEditorDocument *document)
 }
 
 static void
+gb_editor_document_update_title (GbEditorDocument *document)
+{
+  GbEditorDocumentPrivate *priv;
+  GFile *location;
+
+  g_return_if_fail (GB_IS_EDITOR_DOCUMENT (document));
+
+  priv = document->priv;
+
+  g_clear_pointer (&priv->title, g_free);
+
+  location = gtk_source_file_get_location (priv->file);
+
+  if (location)
+    priv->title = g_file_get_basename (location);
+  else
+    priv->title = g_strdup_printf (_("untitled document %u"), priv->doc_seq_id);
+
+  g_object_notify (G_OBJECT (document), "title");
+}
+
+static void
 gb_editor_document_notify_file_location (GbEditorDocument *document,
                                          GParamSpec       *pspec,
                                          GtkSourceFile    *file)
@@ -450,6 +487,23 @@ gb_editor_document_notify_file_location (GbEditorDocument *document,
   priv = document->priv;
 
   location = gtk_source_file_get_location (file);
+
+  if (!location)
+    {
+      if (!priv->doc_seq_id)
+        priv->doc_seq_id = gb_doc_seq_acquire ();
+    }
+  else
+    {
+      if (priv->doc_seq_id)
+        {
+          gb_doc_seq_release (priv->doc_seq_id);
+          priv->doc_seq_id = 0;
+        }
+    }
+
+  gb_editor_document_update_title (document);
+
   gb_source_change_monitor_set_file (priv->change_monitor, location);
 
   gb_editor_document_guess_language (document);
@@ -663,6 +717,34 @@ gb_editor_document_load_finish (GbEditorDocument  *document,
 }
 
 static void
+gb_editor_document_modified_changed (GtkTextBuffer *buffer)
+{
+  g_return_if_fail (GB_IS_EDITOR_DOCUMENT (buffer));
+
+  if (GTK_TEXT_BUFFER_CLASS (gb_editor_document_parent_class)->modified_changed)
+    GTK_TEXT_BUFFER_CLASS (gb_editor_document_parent_class)->
+      modified_changed (buffer);
+
+  g_object_notify (G_OBJECT (buffer), "can-save");
+}
+
+gboolean
+gb_editor_document_get_can_save (GbDocument *document)
+{
+  g_return_val_if_fail (GB_IS_EDITOR_DOCUMENT (document), FALSE);
+
+  return gtk_text_buffer_get_modified (GTK_TEXT_BUFFER (document));
+}
+
+const gchar *
+gb_editor_document_get_title (GbDocument *document)
+{
+  g_return_val_if_fail (GB_IS_EDITOR_DOCUMENT (document), NULL);
+
+  return GB_EDITOR_DOCUMENT (document)->priv->title;
+}
+
+static void
 gb_editor_document_finalize (GObject *object)
 {
   GbEditorDocumentPrivate *priv = GB_EDITOR_DOCUMENT (object)->priv;
@@ -688,6 +770,11 @@ gb_editor_document_get_property (GObject    *object,
 
   switch (prop_id)
     {
+    case PROP_CAN_SAVE:
+      g_value_set_boolean (value,
+                           gb_editor_document_get_can_save (GB_DOCUMENT (self)));
+      break;
+
     case PROP_CHANGE_MONITOR:
       g_value_set_object (value, gb_editor_document_get_change_monitor (self));
       break;
@@ -696,6 +783,10 @@ gb_editor_document_get_property (GObject    *object,
       g_value_set_object (value, gb_editor_document_get_file (self));
       break;
 
+    case PROP_TITLE:
+      g_value_set_string (value,
+                          gb_editor_document_get_title (GB_DOCUMENT (self)));
+
     case PROP_TRIM_TRAILING_WHITESPACE:
       g_value_set_boolean (value,
                            gb_editor_document_get_trim_trailing_whitespace (self));
@@ -744,6 +835,10 @@ gb_editor_document_class_init (GbEditorDocumentClass *klass)
 
   text_buffer_class->mark_set = gb_editor_document_mark_set;
   text_buffer_class->changed = gb_editor_document_changed;
+  text_buffer_class->modified_changed = gb_editor_document_modified_changed;
+
+  g_object_class_override_property (object_class, PROP_CAN_SAVE, "can-save");
+  g_object_class_override_property (object_class, PROP_TITLE, "title");
 
   gParamSpecs [PROP_CHANGE_MONITOR] =
     g_param_spec_object ("change-monitor",
@@ -820,3 +915,10 @@ gb_editor_document_init (GbEditorDocument *document)
                     G_CALLBACK (gb_editor_document_notify_style_scheme),
                     NULL);
 }
+
+static void
+gb_editor_document_init_document (GbDocumentInterface *iface)
+{
+  iface->get_can_save = gb_editor_document_get_can_save;
+  iface->get_title = gb_editor_document_get_title;
+}
diff --git a/src/gnome-builder.mk b/src/gnome-builder.mk
index 62bbd45..53c8953 100644
--- a/src/gnome-builder.mk
+++ b/src/gnome-builder.mk
@@ -43,6 +43,8 @@ libgnome_builder_la_SOURCES = \
        src/credits/gb-credits-widget.h \
        src/devhelp/gb-devhelp-tab.c \
        src/devhelp/gb-devhelp-tab.h \
+       src/documents/gb-document.c \
+       src/documents/gb-document.h \
        src/documents/gb-document-manager.c \
        src/documents/gb-document-manager.h \
        src/editor/c-parse-helper.c \


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