[gnome-builder] editor: implement opening of files.



commit 6c9cc28d846a2a156ef7aa30ce5ee34f97028fef
Author: Christian Hergert <christian hergert me>
Date:   Mon Sep 8 17:06:38 2014 -0700

    editor: implement opening of files.

 src/editor/gb-editor-tab.c            |   90 +++++++++++++++++++++++++++++++++
 src/editor/gb-editor-tab.h            |   34 +++++++------
 src/editor/gb-editor-workspace.c      |   69 +++++++++++++++++++++++++
 src/resources/keybindings/default.ini |    1 +
 src/tabs/gb-notebook.c                |   23 ++++++++
 src/tabs/gb-notebook.h                |   12 ++--
 6 files changed, 208 insertions(+), 21 deletions(-)
---
diff --git a/src/editor/gb-editor-tab.c b/src/editor/gb-editor-tab.c
index 984deb2..a8ca342 100644
--- a/src/editor/gb-editor-tab.c
+++ b/src/editor/gb-editor-tab.c
@@ -126,6 +126,37 @@ G_DEFINE_TYPE_WITH_PRIVATE (GbEditorTab, gb_editor_tab, GB_TYPE_TAB)
 static guint       gUnsaved;
 static GParamSpec *gParamSpecs[LAST_PROP];
 
+GtkWidget *
+gb_editor_tab_new (void)
+{
+  return g_object_new (GB_TYPE_EDITOR_TAB, NULL);
+}
+
+gboolean
+gb_editor_tab_get_is_default (GbEditorTab *tab)
+{
+  GbEditorTabPrivate *priv;
+  GtkTextIter begin;
+  GtkTextIter end;
+
+  g_return_val_if_fail (GB_IS_EDITOR_TAB (tab), FALSE);
+
+  priv = tab->priv;
+
+  if (gtk_source_file_get_location (priv->file))
+    return FALSE;
+
+  if (gtk_text_buffer_get_modified (GTK_TEXT_BUFFER (priv->document)))
+    return FALSE;
+
+  gtk_text_buffer_get_bounds (GTK_TEXT_BUFFER (priv->document), &begin, &end);
+
+  if (gtk_text_iter_compare (&begin, &end) != 0)
+    return FALSE;
+
+  return TRUE;
+}
+
 /**
  * gb_editor_tab_get_document:
  * @tab: A #GbEditorTab.
@@ -749,6 +780,63 @@ hide_progress_bar_cb (gpointer data)
 }
 
 static void
+on_load_cb (GtkSourceFileLoader *loader,
+            GAsyncResult        *result,
+            GbEditorTab         *tab)
+{
+  GError *error = NULL;
+
+  g_return_if_fail (GTK_SOURCE_IS_FILE_LOADER (loader));
+  g_return_if_fail (G_IS_ASYNC_RESULT (result));
+  g_return_if_fail (GB_IS_EDITOR_TAB (tab));
+
+  /*
+   * Hide the progress bar after a timeout period.
+   */
+  g_timeout_add (350, hide_progress_bar_cb, g_object_ref (tab));
+
+  if (!gtk_source_file_loader_load_finish (loader, result, &error))
+    {
+      /*
+       * TODO: Propagate error to tab.
+       */
+      g_warning ("%s", error->message);
+      g_clear_error (&error);
+    }
+
+  g_object_unref (tab);
+}
+
+void
+gb_editor_tab_open_file (GbEditorTab *tab,
+                         GFile       *file)
+{
+  GbEditorTabPrivate *priv;
+  GtkSourceFileLoader *loader;
+
+  g_return_if_fail (GB_IS_EDITOR_TAB (tab));
+  g_return_if_fail (G_IS_FILE (file));
+
+  priv = tab->priv;
+
+  gtk_source_file_set_location (priv->file, file);
+
+  loader = gtk_source_file_loader_new (GTK_SOURCE_BUFFER (priv->document),
+                                       priv->file);
+
+  gtk_source_file_loader_load_async (loader,
+                                     G_PRIORITY_DEFAULT,
+                                     NULL, /* TODO: Cancellable */
+                                     (GFileProgressCallback)file_progress_cb,
+                                     tab,
+                                     NULL,
+                                     (GAsyncReadyCallback)on_load_cb,
+                                     g_object_ref (tab));
+
+  g_object_unref (loader);
+}
+
+static void
 on_save_cb (GtkSourceFileSaver *saver,
             GAsyncResult       *result,
             GbEditorTab        *tab)
@@ -807,6 +895,8 @@ gb_editor_tab_do_save (GbEditorTab *tab)
                                     NULL,
                                     (GAsyncReadyCallback)on_save_cb,
                                     g_object_ref (tab));
+
+  g_object_unref (saver);
 }
 
 void
diff --git a/src/editor/gb-editor-tab.h b/src/editor/gb-editor-tab.h
index ef83399..fa98d5b 100644
--- a/src/editor/gb-editor-tab.h
+++ b/src/editor/gb-editor-tab.h
@@ -50,21 +50,25 @@ struct _GbEditorTabClass
   GbTabClass parent_class;
 };
 
-GType             gb_editor_tab_get_type      (void) G_GNUC_CONST;
-GbEditorDocument *gb_editor_tab_get_document  (GbEditorTab                *tab);
-GtkSourceFile    *gb_editor_tab_get_file      (GbEditorTab                *tab);
-GbEditorSettings *gb_editor_tab_get_settings  (GbEditorTab                *tab);
-void              gb_editor_tab_set_settings  (GbEditorTab                *tab,
-                                               GbEditorSettings           *settings);
-void              gb_editor_tab_set_font_desc (GbEditorTab                *tab,
-                                               const PangoFontDescription *font_desc);
-void              gb_editor_tab_set_show_find (GbEditorTab                *tab,
-                                               gboolean                    show_find);
-void              gb_editor_tab_reformat      (GbEditorTab                *tab);
-void              gb_editor_tab_go_to_end     (GbEditorTab                *tab);
-void              gb_editor_tab_go_to_start   (GbEditorTab                *tab);
-void              gb_editor_tab_save_as       (GbEditorTab                *tab);
-void              gb_editor_tab_save          (GbEditorTab                *tab);
+GType             gb_editor_tab_get_type       (void) G_GNUC_CONST;
+GtkWidget        *gb_editor_tab_new            (void);
+GbEditorDocument *gb_editor_tab_get_document   (GbEditorTab                *tab);
+GtkSourceFile    *gb_editor_tab_get_file       (GbEditorTab                *tab);
+GbEditorSettings *gb_editor_tab_get_settings   (GbEditorTab                *tab);
+void              gb_editor_tab_set_settings   (GbEditorTab                *tab,
+                                                GbEditorSettings           *settings);
+void              gb_editor_tab_set_font_desc  (GbEditorTab                *tab,
+                                                const PangoFontDescription *font_desc);
+void              gb_editor_tab_set_show_find  (GbEditorTab                *tab,
+                                                gboolean                    show_find);
+gboolean          gb_editor_tab_get_is_default (GbEditorTab                *tab);
+void              gb_editor_tab_reformat       (GbEditorTab                *tab);
+void              gb_editor_tab_go_to_end      (GbEditorTab                *tab);
+void              gb_editor_tab_go_to_start    (GbEditorTab                *tab);
+void              gb_editor_tab_save_as        (GbEditorTab                *tab);
+void              gb_editor_tab_save           (GbEditorTab                *tab);
+void              gb_editor_tab_open_file      (GbEditorTab                *tab,
+                                                GFile                      *file);
 
 G_END_DECLS
 
diff --git a/src/editor/gb-editor-workspace.c b/src/editor/gb-editor-workspace.c
index 4f3e9d7..8d75496 100644
--- a/src/editor/gb-editor-workspace.c
+++ b/src/editor/gb-editor-workspace.c
@@ -104,6 +104,74 @@ on_reformat_activate (GSimpleAction *action,
 }
 
 static void
+on_open_activate (GSimpleAction *action,
+                  GVariant      *parameter,
+                  gpointer       user_data)
+{
+  GbEditorWorkspacePrivate *priv;
+  GbEditorWorkspace *workspace = user_data;
+  GtkFileChooserDialog *dialog;
+  GtkWidget *toplevel;
+  GtkWidget *suggested;
+  GtkResponseType response;
+  GbNotebook *notebook;
+  GbTab *tab;
+
+  g_return_if_fail (GB_IS_EDITOR_WORKSPACE (workspace));
+
+  priv = workspace->priv;
+
+  tab = gb_multi_notebook_get_active_tab (priv->multi_notebook);
+  notebook = gb_multi_notebook_get_active_notebook (priv->multi_notebook);
+
+  g_assert (!tab || GB_IS_EDITOR_TAB (tab));
+
+  toplevel = gtk_widget_get_toplevel (GTK_WIDGET (tab));
+
+  dialog = g_object_new (GTK_TYPE_FILE_CHOOSER_DIALOG,
+                         "action", GTK_FILE_CHOOSER_ACTION_OPEN,
+                         "local-only", FALSE,
+                         "select-multiple", FALSE,
+                         "show-hidden", FALSE,
+                         "transient-for", toplevel,
+                         "title", _("Open"),
+                         NULL);
+
+  gtk_dialog_add_buttons (GTK_DIALOG (dialog),
+                          _("Cancel"), GTK_RESPONSE_CANCEL,
+                          _("Open"), GTK_RESPONSE_OK,
+                          NULL);
+
+  gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);
+
+  suggested = gtk_dialog_get_widget_for_response (GTK_DIALOG (dialog),
+                                                  GTK_RESPONSE_OK);
+  gtk_style_context_add_class (gtk_widget_get_style_context (suggested),
+                               GTK_STYLE_CLASS_SUGGESTED_ACTION);
+
+  response = gtk_dialog_run (GTK_DIALOG (dialog));
+
+  if (response == GTK_RESPONSE_OK)
+    {
+      GFile *file = gtk_file_chooser_get_file (GTK_FILE_CHOOSER (dialog));
+
+      if (!gb_editor_tab_get_is_default (GB_EDITOR_TAB (tab)))
+        {
+          tab = GB_TAB (gb_editor_tab_new ());
+          gb_notebook_add_tab (notebook, tab);
+          gtk_widget_show (GTK_WIDGET (tab));
+        }
+
+      gb_editor_tab_open_file (GB_EDITOR_TAB (tab), file);
+      gb_notebook_raise_tab (notebook, tab);
+
+      g_clear_object (&file);
+    }
+
+  gtk_widget_destroy (GTK_WIDGET (dialog));
+}
+
+static void
 on_save_activate (GSimpleAction *action,
                   GVariant      *parameter,
                   gpointer       user_data)
@@ -225,6 +293,7 @@ gb_editor_workspace_init (GbEditorWorkspace *workspace)
   static const GActionEntry action_entries[] = {
     { "go-to-end", on_go_to_end_activate },
     { "go-to-start", on_go_to_start_activate },
+    { "open", on_open_activate },
     { "reformat", on_reformat_activate },
     { "save", on_save_activate },
     { "save-as", on_save_as_activate },
diff --git a/src/resources/keybindings/default.ini b/src/resources/keybindings/default.ini
index 62d82c2..0a638ba 100644
--- a/src/resources/keybindings/default.ini
+++ b/src/resources/keybindings/default.ini
@@ -5,6 +5,7 @@ find = <Control>F
 [editor]
 go-to-end = <Control>Page_Down
 go-to-start = <Control>Page_Up
+open = <Control>O
 reformat = <Control><Shift>R
 save = <Control>S
 save-as = <Control><Shift>S
diff --git a/src/tabs/gb-notebook.c b/src/tabs/gb-notebook.c
index dcb9e0f..9956955 100644
--- a/src/tabs/gb-notebook.c
+++ b/src/tabs/gb-notebook.c
@@ -31,6 +31,29 @@ gb_notebook_new (void)
 }
 
 void
+gb_notebook_raise_tab (GbNotebook *notebook,
+                       GbTab      *tab)
+{
+  gint page = -1;
+
+  g_return_if_fail (GB_IS_NOTEBOOK (notebook));
+  g_return_if_fail (GB_IS_TAB (tab));
+
+  if (gtk_widget_get_parent (GTK_WIDGET (tab)) != GTK_WIDGET (notebook))
+    {
+      g_warning ("Cannot raise tab, does not belong to requested notebook.");
+      return;
+    }
+
+  gtk_container_child_get (GTK_CONTAINER (notebook), GTK_WIDGET (tab),
+                           "position", &page,
+                           NULL);
+
+  if (page != -1)
+    gtk_notebook_set_current_page (GTK_NOTEBOOK (notebook), page);
+}
+
+void
 gb_notebook_add_tab (GbNotebook *notebook,
                      GbTab      *tab)
 {
diff --git a/src/tabs/gb-notebook.h b/src/tabs/gb-notebook.h
index 59ec3b7..44a57a2 100644
--- a/src/tabs/gb-notebook.h
+++ b/src/tabs/gb-notebook.h
@@ -50,12 +50,12 @@ struct _GbNotebookClass
   GtkNotebookClass parent_class;
 };
 
-GType      gb_notebook_get_type (void) G_GNUC_CONST;
-GtkWidget *gb_notebook_new      (void);
-void       gb_notebook_add_tab  (GbNotebook *notebook,
-                                 GbTab      *tab);
-void       gb_notebook_move     (GbNotebook *notebook,
-                                 GbNotebook *new_notebook);
+GType      gb_notebook_get_type  (void) G_GNUC_CONST;
+GtkWidget *gb_notebook_new       (void);
+void       gb_notebook_add_tab   (GbNotebook *notebook,
+                                  GbTab      *tab);
+void       gb_notebook_raise_tab (GbNotebook *notebook,
+                                  GbTab      *tab);
 
 G_END_DECLS
 


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