[recipes] Allow entering recipes on somebody elses behalf



commit 85ab72c53b33f4cdcfb2841dcb2e476adaf3add6
Author: Matthias Clasen <mclasen redhat com>
Date:   Mon Jan 30 12:57:29 2017 +0100

    Allow entering recipes on somebody elses behalf
    
    This will let you enter your mom's recipe, and create a chef
    entry for her, if that is what you prefer.

 src/gr-app.c          |   15 +++-
 src/gr-chef-dialog.c  |  241 ++++++++++++++++++++++++++++++++++++++++---------
 src/gr-chef-dialog.h  |   10 ++-
 src/gr-chef-dialog.ui |   74 +++++++++++++++-
 src/gr-edit-page.c    |  103 ++++++++++++++++++----
 src/gr-edit-page.ui   |    2 +
 6 files changed, 380 insertions(+), 65 deletions(-)
---
diff --git a/src/gr-app.c b/src/gr-app.c
index 922ce48..f8b7890 100644
--- a/src/gr-app.c
+++ b/src/gr-app.c
@@ -72,11 +72,24 @@ chef_information_activated (GSimpleAction *action,
                             GVariant      *parameter,
                             gpointer       app)
 {
+        GrRecipeStore *store;
+        const char *id;
+        g_autoptr(GrChef) chef = NULL;
         GrChefDialog *dialog;
         GtkWindow *win;
 
+        store = gr_app_get_recipe_store (GR_APP (g_application_get_default ()));
+
+        id = gr_recipe_store_get_user_key (store);
+
+        if (id != NULL && id[0] != '\0')
+                chef = gr_recipe_store_get_chef (store, id);
+        else
+                chef = gr_chef_new ();
+
         win = gtk_application_get_active_window (GTK_APPLICATION (app));
-        dialog = gr_chef_dialog_new (win);
+        dialog = gr_chef_dialog_new (win, chef);
+        gr_chef_dialog_can_create (dialog, FALSE);
         gtk_window_set_title (GTK_WINDOW (dialog), _("My Chef Information"));
         gtk_window_present (GTK_WINDOW (dialog));
 }
diff --git a/src/gr-chef-dialog.c b/src/gr-chef-dialog.c
index cc26208..f5ec8e3 100644
--- a/src/gr-chef-dialog.c
+++ b/src/gr-chef-dialog.c
@@ -36,19 +36,28 @@
 
 struct _GrChefDialog
 {
-        GtkDialog parent_instance;
+        GtkWindow parent_instance;
 
         GtkWidget *fullname;
         GtkWidget *name;
         GtkWidget *description;
         GtkWidget *image;
+        GtkWidget *button;
         GtkWidget *error_revealer;
         GtkWidget *error_label;
+        GtkWidget *create_button;
+        GtkWidget *chef_popover;
+        GtkWidget *chef_list;
+        GtkWidget *save_button;
 
         char *image_path;
+
+        GrChef *chef;
 };
 
-G_DEFINE_TYPE (GrChefDialog, gr_chef_dialog, GTK_TYPE_DIALOG)
+G_DEFINE_TYPE (GrChefDialog, gr_chef_dialog, GTK_TYPE_WINDOW)
+
+static int done_signal;
 
 static void
 dismiss_error (GrChefDialog *self)
@@ -114,6 +123,7 @@ gr_chef_dialog_finalize (GObject *object)
         GrChefDialog *self = GR_CHEF_DIALOG (object);
 
         g_free (self->image_path);
+        g_clear_object (&self->chef);
 
         G_OBJECT_CLASS (gr_chef_dialog_parent_class)->finalize (object);
 }
@@ -122,7 +132,6 @@ static gboolean
 save_chef_dialog (GrChefDialog  *self,
                   GError        **error)
 {
-        g_autoptr(GrChef) chef = NULL;
         GrRecipeStore *store;
         const char *id;
         const char *name;
@@ -131,58 +140,93 @@ save_chef_dialog (GrChefDialog  *self,
         GtkTextBuffer *buffer;
         GtkTextIter start, end;
 
-        store = gr_app_get_recipe_store (GR_APP (g_application_get_default ()));
-
-        id = gr_recipe_store_get_user_key (store);
+        if (gr_chef_is_readonly (self->chef))
+                return TRUE;
 
+        id = gr_chef_get_id (self->chef);
         name = gtk_entry_get_text (GTK_ENTRY (self->name));
         fullname = gtk_entry_get_text (GTK_ENTRY (self->fullname));
         buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (self->description));
         gtk_text_buffer_get_bounds (buffer, &start, &end);
         description = gtk_text_buffer_get_text (buffer, &start, &end, FALSE);
 
-        chef = g_object_new (GR_TYPE_CHEF,
-                             "id", id,
-                             "fullname", fullname,
-                             "name", name,
-                             "description", description,
-                             "image-path", self->image_path,
-                             NULL);
+        store = gr_app_get_recipe_store (GR_APP (g_application_get_default ()));
 
-        return gr_recipe_store_update_user (store, chef, error);
+        if (id[0] != '\0') {
+                g_object_set (self->chef,
+                              "fullname", fullname,
+                              "name", name,
+                              "description", description,
+                              "image-path", self->image_path,
+                              NULL);
+                return gr_recipe_store_update_chef (store, self->chef, id, error);
+        }
+        else {
+                g_auto(GStrv) strv = NULL;
+                g_autofree char *new_id = NULL;
+
+                strv = g_strsplit (fullname, " ", -1);
+                if (strv[1])
+                        new_id = generate_id (strv[0], "_", strv[1], NULL);
+                else
+                        new_id = generate_id (strv[0], NULL);
+
+                g_object_set (self->chef,
+                              "id", new_id,
+                              "fullname", fullname,
+                              "name", name,
+                              "description", description,
+                              "image-path", self->image_path,
+                              NULL);
+
+                return gr_recipe_store_add_chef (store, self->chef, error);
+        }
 }
 
-static gboolean
-window_close (GrChefDialog *self)
+static void
+save_chef (GrChefDialog *self)
 {
         g_autoptr(GError) error = NULL;
 
         if (!save_chef_dialog (self, &error)) {
                 gtk_label_set_label (GTK_LABEL (self->error_label), error->message);
                 gtk_revealer_set_reveal_child (GTK_REVEALER (self->error_revealer), TRUE);
-        return TRUE;
+                return;
         }
 
-        return FALSE;
+        g_signal_emit (self, done_signal, 0, self->chef);
+        gtk_widget_destroy (GTK_WIDGET (self));
 }
 
 static void
-gr_chef_dialog_init (GrChefDialog *self)
+close_dialog (GrChefDialog *self)
 {
-        GrRecipeStore *store;
-        g_autoptr(GrChef) chef = NULL;
-        const char *id;
+        gtk_widget_destroy (GTK_WIDGET (self));
+}
 
+static void
+gr_chef_dialog_init (GrChefDialog *self)
+{
         gtk_widget_init_template (GTK_WIDGET (self));
 
-        store = gr_app_get_recipe_store (GR_APP (g_application_get_default ()));
+        gtk_list_box_set_header_func (GTK_LIST_BOX (self->chef_list),
+                                      all_headers, self, NULL);
 
-        id = gr_recipe_store_get_user_key (store);
+#ifdef ENABLE_GSPELL
+        {
+                GspellTextView *gspell_view;
 
-        if (id != NULL && id[0] != '\0')
-                chef = gr_recipe_store_get_chef (store, id);
+                gspell_view = gspell_text_view_get_from_gtk_text_view (GTK_TEXT_VIEW (self->description));
+                gspell_text_view_basic_setup (gspell_view);
+        }
+#endif
+}
 
-        if (chef) {
+static void
+gr_chef_dialog_set_chef (GrChefDialog *self,
+                         GrChef       *chef)
+{
+        if (g_set_object (&self->chef, chef)) {
                 const char *fullname;
                 const char *name;
                 const char *description;
@@ -199,20 +243,35 @@ gr_chef_dialog_init (GrChefDialog *self)
                                           description ? description : "", -1);
 
                 self->image_path = g_strdup (image_path);
-        }
-
-        update_image (self);
 
-        g_signal_connect_swapped (self, "delete-event", G_CALLBACK (window_close), self);
+                if (gr_chef_is_readonly (chef)) {
+                        gtk_widget_set_sensitive (self->fullname, FALSE);
+                        gtk_widget_set_sensitive (self->name, FALSE);
+                        gtk_widget_set_sensitive (self->description, FALSE);
+                        gtk_widget_set_sensitive (self->button, FALSE);
+                        gtk_widget_set_sensitive (self->save_button, FALSE);
+                }
+                else {
+                        gtk_widget_set_sensitive (self->fullname, TRUE);
+                        gtk_widget_set_sensitive (self->name, TRUE);
+                        gtk_widget_set_sensitive (self->description, TRUE);
+                        gtk_widget_set_sensitive (self->button, TRUE);
+                        gtk_widget_set_sensitive (self->save_button, TRUE);
+                }
+
+                update_image (self);
+        }
+}
 
-#ifdef ENABLE_GSPELL
-        {
-                GspellTextView *gspell_view;
+static void
+chef_selected (GrChefDialog  *dialog,
+               GtkListBoxRow *row)
+{
+        GrChef *chef;
 
-                gspell_view = gspell_text_view_get_from_gtk_text_view (GTK_TEXT_VIEW (self->description));
-                gspell_text_view_basic_setup (gspell_view);
-        }
-#endif
+        chef = g_object_get_data (G_OBJECT (row), "chef");
+        gr_chef_dialog_set_chef (dialog, chef);
+        gtk_popover_popdown (GTK_POPOVER (dialog->chef_popover));
 }
 
 static void
@@ -223,6 +282,14 @@ gr_chef_dialog_class_init (GrChefDialogClass *klass)
 
         object_class->finalize = gr_chef_dialog_finalize;
 
+        done_signal = g_signal_new ("done",
+                                    G_TYPE_FROM_CLASS (klass),
+                                    G_SIGNAL_RUN_LAST,
+                                    0,
+                                    NULL, NULL,
+                                    NULL,
+                                    G_TYPE_NONE, 1, GR_TYPE_CHEF);
+
         gtk_widget_class_set_template_from_resource (GTK_WIDGET_CLASS (klass),
                                                      "/org/gnome/Recipes/gr-chef-dialog.ui");
 
@@ -230,18 +297,106 @@ gr_chef_dialog_class_init (GrChefDialogClass *klass)
         gtk_widget_class_bind_template_child (widget_class, GrChefDialog, name);
         gtk_widget_class_bind_template_child (widget_class, GrChefDialog, description);
         gtk_widget_class_bind_template_child (widget_class, GrChefDialog, image);
+        gtk_widget_class_bind_template_child (widget_class, GrChefDialog, button);
         gtk_widget_class_bind_template_child (widget_class, GrChefDialog, error_revealer);
         gtk_widget_class_bind_template_child (widget_class, GrChefDialog, error_label);
+        gtk_widget_class_bind_template_child (widget_class, GrChefDialog, create_button);
+        gtk_widget_class_bind_template_child (widget_class, GrChefDialog, chef_popover);
+        gtk_widget_class_bind_template_child (widget_class, GrChefDialog, chef_list);
+        gtk_widget_class_bind_template_child (widget_class, GrChefDialog, save_button);
 
         gtk_widget_class_bind_template_callback (widget_class, dismiss_error);
         gtk_widget_class_bind_template_callback (widget_class, image_button_clicked);
+        gtk_widget_class_bind_template_callback (widget_class, chef_selected);
+        gtk_widget_class_bind_template_callback (widget_class, save_chef);
+        gtk_widget_class_bind_template_callback (widget_class, close_dialog);
 }
 
 GrChefDialog *
-gr_chef_dialog_new (GtkWindow *win)
+gr_chef_dialog_new (GtkWindow *win,
+                    GrChef    *chef)
+{
+        GrChefDialog *dialog;
+
+        dialog = g_object_new (GR_TYPE_CHEF_DIALOG,
+                               "transient-for", win,
+                               NULL);
+
+        gr_chef_dialog_set_chef (dialog, chef);
+
+        return dialog;
+}
+
+static void
+add_chef_row (GrChefDialog *dialog,
+              GrChef       *chef)
+{
+        GtkWidget *row;
+
+        row = gtk_label_new ("");
+        g_object_set (row, "margin", 10, NULL);
+
+        if (chef) {
+                gtk_label_set_label (GTK_LABEL (row), gr_chef_get_fullname (chef));
+                gtk_label_set_xalign (GTK_LABEL (row), 0.0);
+        }
+        else {
+                g_autofree char *tmp = NULL;
+
+                tmp = g_strdup_printf ("<b>%s</b>", _("New Chef"));
+                gtk_label_set_markup (GTK_LABEL (row), tmp);
+        }
+
+        gtk_widget_show (row);
+
+        gtk_container_add (GTK_CONTAINER (dialog->chef_list), row);
+        row = gtk_widget_get_parent (row);
+        if (chef)
+                g_object_set_data_full (G_OBJECT (row), "chef", g_object_ref (chef), g_object_unref);
+        else
+                g_object_set_data_full (G_OBJECT (row), "chef", g_object_new (GR_TYPE_CHEF,
+                                                                              "id", "",
+                                                                              "name", "",
+                                                                              "fullname", "",
+                                                                              "description", "",
+                                                                              "image-path", "",
+                                                                              "readonly", FALSE,
+                                                                              NULL), g_object_unref);
+}
+
+static void
+populate_chef_list (GrChefDialog *dialog)
+{
+        GrRecipeStore *store;
+        g_autofree char **keys = NULL;
+        guint length;
+        int i;
+
+        store = gr_app_get_recipe_store (GR_APP (g_application_get_default ()));
+        keys = gr_recipe_store_get_chef_keys (store, &length);
+
+        for (i = 0; keys[i]; i++) {
+                g_autoptr(GrChef) chef = gr_recipe_store_get_chef (store, keys[i]);
+
+                if (g_strcmp0 (gr_chef_get_id (chef), gr_recipe_store_get_user_key (store)) == 0)
+                        add_chef_row (dialog, chef);
+                else if (!gr_chef_is_readonly (chef))
+                        add_chef_row (dialog, chef);
+        }
+
+        add_chef_row (dialog, NULL);
+}
+
+void
+gr_chef_dialog_can_create (GrChefDialog *dialog,
+                           gboolean      create)
+{
+        gtk_widget_set_visible (dialog->create_button, create);
+        populate_chef_list (dialog);
+}
+
+GrChef *
+gr_chef_dialog_get_chef (GrChefDialog *dialog)
 {
-        return g_object_new (GR_TYPE_CHEF_DIALOG,
-                             "transient-for", win,
-                             "use-header-bar", TRUE,
-                             NULL);
+        return dialog->chef;
 }
diff --git a/src/gr-chef-dialog.h b/src/gr-chef-dialog.h
index f84f1de..bb55998 100644
--- a/src/gr-chef-dialog.h
+++ b/src/gr-chef-dialog.h
@@ -22,12 +22,18 @@
 
 #include <gtk/gtk.h>
 
+#include "gr-chef.h"
+
 G_BEGIN_DECLS
 
 #define GR_TYPE_CHEF_DIALOG (gr_chef_dialog_get_type())
 
-G_DECLARE_FINAL_TYPE (GrChefDialog, gr_chef_dialog, GR, CHEF_DIALOG, GtkDialog)
+G_DECLARE_FINAL_TYPE (GrChefDialog, gr_chef_dialog, GR, CHEF_DIALOG, GtkWindow)
 
-GrChefDialog *gr_chef_dialog_new (GtkWindow *win);
+GrChefDialog *gr_chef_dialog_new (GtkWindow *win,
+                                  GrChef    *chef);
+void          gr_chef_dialog_can_create (GrChefDialog *dialog,
+                                         gboolean      create);
+GrChef       *gr_chef_dialog_get_chef   (GrChefDialog *dialog);
 
 G_END_DECLS
diff --git a/src/gr-chef-dialog.ui b/src/gr-chef-dialog.ui
index 70cb465..6a1a3cf 100644
--- a/src/gr-chef-dialog.ui
+++ b/src/gr-chef-dialog.ui
@@ -1,12 +1,41 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <interface domain="recipes">
   <!-- interface-requires gtk+ 3.8 -->
-  <template class="GrChefDialog" parent="GtkDialog">
+  <template class="GrChefDialog" parent="GtkWindow">
     <property name="title" translatable="yes">Chef Information</property>
     <property name="resizable">False</property>
     <property name="modal">True</property>
-    <child internal-child="vbox">
-      <object class="GtkBox" id="vbox">
+    <child type="titlebar">
+      <object class="GtkHeaderBar">
+        <property name="visible">1</property>
+        <child>
+          <object class="GtkButton" id="cancel_button">
+            <property name="visible">1</property>
+            <property name="label" translatable="yes">_Cancel</property>
+            <property name="use-underline">1</property>
+            <signal name="clicked" handler="close_dialog" swapped="yes"/>
+          </object>
+        </child>
+        <child>
+          <object class="GtkButton" id="save_button">
+            <property name="visible">1</property>
+            <property name="label" translatable="yes">_Save</property>
+            <property name="use-underline">1</property>
+            <signal name="clicked" handler="save_chef" swapped="yes"/>
+            <style>
+              <class name="suggested-action"/>
+            </style>
+          </object>
+          <packing>
+            <property name="pack-type">end</property>
+          </packing>
+        </child>
+      </object>
+    </child>
+    <child>
+      <object class="GtkBox">
+        <property name="visible">1</property>
+        <property name="orientation">vertical</property>
         <child>
           <object class="GtkOverlay">
             <property name="visible">1</property>
@@ -82,6 +111,27 @@
                     <property name="margin-top">20</property>
                     <property name="margin-bottom">20</property>
                     <child>
+                      <object class="GtkMenuButton" id="create_button">
+                        <property name="visible">1</property>
+                        <property name="halign">center</property>
+                        <property name="popover">chef_popover</property>
+                        <style>
+                          <class name="text-button"/>
+                        </style>
+                        <child>
+                          <object class="GtkLabel">
+                            <property name="visible">1</property>
+                            <property name="label" translatable="yes">Other Chef</property>
+                          </object>
+                        </child>
+                      </object>
+                      <packing>
+                        <property name="left-attach">0</property>
+                        <property name="top-attach">0</property>
+                        <property name="width">2</property>
+                      </packing>
+                    </child>
+                    <child>
                       <object class="GtkEntry" id="fullname">
                         <property name="visible">1</property>
                         <property name="placeholder-text" translatable="yes">Nameā€¦</property>
@@ -151,4 +201,22 @@
       </object>
     </child>
   </template>
+  <object class="GtkPopover" id="chef_popover">
+    <child>
+      <object class="GtkScrolledWindow">
+        <property name="visible">1</property>
+        <property name="margin">10</property>
+        <property name="shadow-type">in</property>
+        <property name="hscrollbar-policy">never</property>
+        <property name="vscrollbar-policy">never</property>
+        <child>
+          <object class="GtkListBox" id="chef_list">
+            <property name="visible">1</property>
+            <property name="selection-mode">none</property>
+            <signal name="row-activated" handler="chef_selected" swapped="yes"/>
+          </object>
+        </child>
+      </object>
+    </child>
+  </object>
 </interface>
diff --git a/src/gr-edit-page.c b/src/gr-edit-page.c
index 415855f..d59b224 100644
--- a/src/gr-edit-page.c
+++ b/src/gr-edit-page.c
@@ -42,6 +42,7 @@
 #include "gr-ingredient.h"
 #include "gr-number.h"
 #include "gr-unit.h"
+#include "gr-chef-dialog.h"
 
 #ifdef GDK_WINDOWING_X11
 #include <gdk/gdkx.h>
@@ -122,6 +123,8 @@ struct _GrEditPage
         char *recipe_term;
 
         guint index_handler_id;
+
+        char *author;
 };
 
 G_DEFINE_TYPE (GrEditPage, gr_edit_page, GTK_TYPE_BOX)
@@ -245,6 +248,8 @@ edit_page_finalize (GObject *object)
 {
         GrEditPage *self = GR_EDIT_PAGE (object);
 
+        if (self->index_handler_id)
+                g_signal_handler_disconnect (self->recipe, self->index_handler_id);
         g_clear_object (&self->recipe);
         g_clear_object (&self->group);
         g_list_free (self->segments);
@@ -255,6 +260,8 @@ edit_page_finalize (GObject *object)
 
         g_clear_object (&self->search);
 
+        g_free (self->author);
+
         G_OBJECT_CLASS (gr_edit_page_parent_class)->finalize (object);
 }
 
@@ -1035,6 +1042,7 @@ search_hits_added (GrRecipeSearch *search,
                 gtk_widget_show (label);
                 gtk_box_pack_start (GTK_BOX (box), label, TRUE, TRUE, 0);
 
+                store = gr_app_get_recipe_store (GR_APP (g_application_get_default ()));
                 author = gr_recipe_get_author (recipe);
                 chef = gr_recipe_store_get_chef (store, author ? author : "");
                 if (chef) {
@@ -1257,6 +1265,44 @@ add_image_link (GtkButton *button, GrEditPage *page)
         gtk_popover_popup (GTK_POPOVER (page->image_popover));
 }
 
+static void update_author_label (GrEditPage *page,
+                                 GrChef     *chef);
+
+static void
+chef_done (GrChefDialog *dialog, GrChef *chef, GrEditPage *page)
+{
+        g_free (page->author);
+        page->author = g_strdup (gr_chef_get_id (chef));
+
+        update_author_label (page, chef);
+}
+
+static gboolean
+edit_chef (GrEditPage *page)
+{
+        GrChefDialog *dialog;
+        GtkWidget *win;
+        const char *author;
+        GrRecipeStore *store;
+        g_autoptr(GrChef) chef = NULL;
+
+        win = gtk_widget_get_ancestor (GTK_WIDGET (page), GTK_TYPE_APPLICATION_WINDOW);
+
+        store = gr_app_get_recipe_store (GR_APP (g_application_get_default ()));
+
+        author = page->author;
+        chef = gr_recipe_store_get_chef (store, author ? author : "");
+
+        dialog = gr_chef_dialog_new (GTK_WINDOW (win), chef);
+        gr_chef_dialog_can_create (dialog, TRUE);
+        g_signal_connect (dialog, "done", G_CALLBACK (chef_done), page);
+
+        gtk_window_set_title (GTK_WINDOW (dialog), _("Recipe Author"));
+        gtk_window_present (GTK_WINDOW (dialog));
+
+        return TRUE;
+}
+
 static void
 gr_edit_page_init (GrEditPage *page)
 {
@@ -1410,6 +1456,7 @@ gr_edit_page_class_init (GrEditPageClass *klass)
         gtk_widget_class_bind_template_callback (widget_class, recipe_filter_stop);
         gtk_widget_class_bind_template_callback (widget_class, recipe_filter_activated);
         gtk_widget_class_bind_template_callback (widget_class, set_default_image);
+        gtk_widget_class_bind_template_callback (widget_class, edit_chef);
 }
 
 GtkWidget *
@@ -1711,6 +1758,9 @@ void
 gr_edit_page_clear (GrEditPage *page)
 {
         GArray *images;
+        GrRecipeStore *store;
+
+        store = gr_app_get_recipe_store (GR_APP (g_application_get_default ()));
 
         gtk_label_set_label (GTK_LABEL (page->name_label), _("Name your recipe"));
         gtk_entry_set_text (GTK_ENTRY (page->name_entry), "");
@@ -1735,7 +1785,15 @@ gr_edit_page_clear (GrEditPage *page)
         g_object_set (page->images, "images", images, NULL);
         g_array_unref (images);
 
+        if (page->index_handler_id) {
+                g_signal_handler_disconnect (page->recipe, page->index_handler_id);
+                page->index_handler_id = 0;
+        }
+
         g_clear_object (&page->recipe);
+
+        g_free (page->author);
+        page->author = g_strdup (gr_recipe_store_get_user_key (store));
 }
 
 static void
@@ -1812,6 +1870,24 @@ set_instructions (GtkTextView *text_view,
         gtk_text_buffer_insert (buffer, &iter, p, -1);
 }
 
+static void
+update_author_label (GrEditPage *page,
+                     GrChef     *chef)
+{
+        if (chef) {
+                g_autofree char *tmp = NULL;
+                g_autofree char *link = NULL;
+
+                link = g_strdup_printf ("<a href=\"edit\">%s</a>", gr_chef_get_name (chef));
+                tmp = g_strdup_printf (_("Recipe by %s"), link);
+                gtk_label_set_label (GTK_LABEL (page->author_label), tmp);
+                gtk_widget_show (page->author_label);
+        }
+        else {
+                gtk_widget_hide (page->author_label);
+        }
+}
+
 void
 gr_edit_page_edit (GrEditPage *page,
                    GrRecipe   *recipe)
@@ -1853,6 +1929,8 @@ gr_edit_page_edit (GrEditPage *page,
 
         g_object_get (recipe, "images", &images, NULL);
 
+        page->author = g_strdup (author);
+
         chef = gr_recipe_store_get_chef (store, author ? author : "");
 
         gtk_label_set_label (GTK_LABEL (page->name_label), _("Name"));
@@ -1879,15 +1957,7 @@ gr_edit_page_edit (GrEditPage *page,
         gr_image_viewer_set_images (GR_IMAGE_VIEWER (page->images), images);
         gr_image_viewer_show_image (GR_IMAGE_VIEWER (page->images), index);
 
-        if (chef) {
-                g_autofree char *tmp = NULL;
-                tmp = g_strdup_printf (_("Recipe by %s"), gr_chef_get_name (chef));
-                gtk_label_set_label (GTK_LABEL (page->author_label), tmp);
-                gtk_widget_show (page->author_label);
-        }
-        else {
-                gtk_widget_hide (page->author_label);
-        }
+        update_author_label (page, chef);
 
         if (page->index_handler_id) {
                 g_signal_handler_disconnect (page->recipe, page->index_handler_id);
@@ -2209,13 +2279,12 @@ gr_edit_page_save (GrEditPage *page)
         if (page->recipe) {
                 g_autofree char *old_id = NULL;
                 g_autofree char *id = NULL;
-                const char *author;
 
-                author = gr_recipe_get_author (page->recipe);
-                id = generate_id ("R_", name, "_by_", author, NULL);
+                id = generate_id ("R_", name, "_by_", page->author, NULL);
                 old_id = g_strdup (gr_recipe_get_id (page->recipe));
                 g_object_set (page->recipe,
                               "id", id,
+                              "author", page->author,
                               "name", name,
                               "cuisine", cuisine,
                               "category", category,
@@ -2239,16 +2308,14 @@ gr_edit_page_save (GrEditPage *page)
         }
         else {
                 g_autoptr(GrRecipe) recipe = NULL;
-                const char *author;
                 g_autofree char *id = NULL;
 
-                author = gr_recipe_store_get_user_key (store);
                 ensure_user_chef (store, page);
-                id = generate_id ("R_", name, "_by_", author, NULL);
+                id = generate_id ("R_", name, "_by_", page->author, NULL);
                 recipe = g_object_new (GR_TYPE_RECIPE,
                                        "id", id,
+                                       "author", page->author,
                                        "name", name,
-                                       "author", author,
                                        "cuisine", cuisine,
                                        "category", category,
                                        "season", season,
@@ -2272,6 +2339,10 @@ gr_edit_page_save (GrEditPage *page)
         gtk_label_set_label (GTK_LABEL (page->error_label), error->message);
         gtk_revealer_set_reveal_child (GTK_REVEALER (page->error_revealer), TRUE);
 
+        if (page->index_handler_id) {
+                g_signal_handler_disconnect (page->recipe, page->index_handler_id);
+                page->index_handler_id = 0;
+        }
         g_clear_object (&page->recipe);
 
         return FALSE;
diff --git a/src/gr-edit-page.ui b/src/gr-edit-page.ui
index be41b49..3cf54ec 100644
--- a/src/gr-edit-page.ui
+++ b/src/gr-edit-page.ui
@@ -695,8 +695,10 @@
                     <child>
                       <object class="GtkLabel" id="author_label">
                         <property name="visible">1</property>
+                        <property name="use-markup">1</property>
                         <property name="xalign">0</property>
                         <property name="margin-top">20</property>
+                        <signal name="activate-link" handler="edit_chef" swapped="yes"/>
                       </object>
                       <packing>
                         <property name="left-attach">0</property>


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