[recipes] Make save button sensitive or insensitive as needed



commit fa4395fcb5c33b793f9c575e143c07aba1d5a0cf
Author: Ekta Nandwani <mailnandwaniekta gmail com>
Date:   Thu Mar 9 02:21:46 2017 +0530

    Make save button sensitive or insensitive as needed
    
    Opening edit page for the recipe makes save insensitive
    and Changing any field in gr-edit-page makes it sensitive
    
    https://bugzilla.gnome.org/show_bug.cgi?id=778200

 src/gr-edit-page.c  |   78 +++++++++++++++++++++++++++++++++++++++++++++++++-
 src/gr-edit-page.ui |   24 +++++++++++++++
 src/gr-window.c     |   21 +++++++++++++
 src/gr-window.ui    |    2 +-
 4 files changed, 122 insertions(+), 3 deletions(-)
---
diff --git a/src/gr-edit-page.c b/src/gr-edit-page.c
index a07aa25..ae574f5 100644
--- a/src/gr-edit-page.c
+++ b/src/gr-edit-page.c
@@ -137,10 +137,19 @@ struct _GrEditPage
         guint index_handler_id;
 
         char *author;
+        gboolean unsaved;
 };
 
 G_DEFINE_TYPE (GrEditPage, gr_edit_page, GTK_TYPE_BOX)
 
+enum {
+        PROP_0,
+        PROP_UNSAVED,
+        N_PROPS
+};
+
+static GParamSpec *props [N_PROPS];
+
 static char *get_text_view_text (GtkTextView *textview);
 static void  set_text_view_text (GtkTextView *textview,
                                  const char  *text);
@@ -152,6 +161,7 @@ dismiss_error (GrEditPage *page)
 }
 
 static void add_image_cb (GrEditPage *page);
+static void set_unsaved (GrEditPage *page);
 
 static void
 populate_image_flowbox (GrEditPage *page)
@@ -225,6 +235,7 @@ set_default_image_cb (GrEditPage *page)
 
         if (page->recipe)
                 g_object_set (page->recipe, "default-image", index, NULL);
+        set_unsaved (page);
 }
 
 static void
@@ -245,6 +256,7 @@ static void
 add_image_cb (GrEditPage *page)
 {
         gr_image_viewer_add_image (GR_IMAGE_VIEWER (page->images));
+        set_unsaved (page);
 }
 
 static char *
@@ -312,18 +324,21 @@ remove_image_cb (GrEditPage *page)
         instructions = get_text_view_text (GTK_TEXT_VIEW (page->instructions_field));
         rewritten = rewrite_instructions_for_removed_image (instructions, index);
         set_text_view_text (GTK_TEXT_VIEW (page->instructions_field), rewritten);
+        set_unsaved (page);
 }
 
 static void
 rotate_image_left_cb (GrEditPage *page)
 {
         gr_image_viewer_rotate_image (GR_IMAGE_VIEWER (page->images), 90);
+        set_unsaved (page);
 }
 
 static void
 rotate_image_right_cb (GrEditPage *page)
 {
         gr_image_viewer_rotate_image (GR_IMAGE_VIEWER (page->images), 270);
+        set_unsaved (page);
 }
 
 static void
@@ -442,6 +457,7 @@ remove_ingredient (GtkButton *button, GrEditPage *page)
                 page->active_row = NULL;
 
         gtk_widget_destroy (row);
+        set_unsaved (page);
 }
 
 static void
@@ -688,6 +704,7 @@ add_ingredient2 (GtkButton *button, GrEditPage *page)
                                  gtk_entry_get_text (GTK_ENTRY (page->new_ingredient_unit)),
                                  &amount, &unit);
         update_ingredient_row (row, amount, unit, ingredient);
+        set_unsaved (page);
 }
 
 static char *
@@ -1239,6 +1256,7 @@ add_step (GtkButton *button, GrEditPage *self)
         gtk_text_buffer_get_end_iter (buffer, &end);
         gtk_text_buffer_place_cursor (buffer, &end);
         gtk_text_buffer_insert_at_cursor (buffer, "\n\n", 2);
+        set_unsaved (self);
 }
 
 static void update_author_label (GrEditPage *page,
@@ -1278,6 +1296,8 @@ edit_chef (GrEditPage *page)
         return TRUE;
 }
 
+
+
 static void
 gr_edit_page_init (GrEditPage *page)
 {
@@ -1337,7 +1357,7 @@ popover_keypress_handler (GtkWidget  *widget,
                         }
                 }
         }
-
+        
         return GDK_EVENT_PROPAGATE;
 }
 
@@ -1406,12 +1426,62 @@ next_step (GrEditPage *page)
 }
 
 static void
+gr_edit_page_set_property (GObject      *object,
+                           guint         prop_id,
+                           const GValue *value,
+                           GParamSpec   *pspec)
+{    
+        GrEditPage *self = GR_EDIT_PAGE (object);
+        switch (prop_id) {
+        case PROP_UNSAVED:
+                self->unsaved = g_value_get_boolean (value);
+                break;
+        default:
+                G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+        }
+}
+
+
+static void
+gr_edit_page_get_property (GObject    *object,
+                              guint       prop_id,
+                              GValue     *value,
+                              GParamSpec *pspec)
+{
+        GrEditPage *self = GR_EDIT_PAGE (object);
+
+        switch (prop_id) {
+        case PROP_UNSAVED:
+                g_value_set_boolean (value, self->unsaved);
+                break;
+        default:
+                G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+        }
+}
+
+static
+void set_unsaved (GrEditPage *page)
+{
+        g_object_set (G_OBJECT (page),"unsaved", TRUE, NULL);
+}
+
+static void
 gr_edit_page_class_init (GrEditPageClass *klass)
 {
         GObjectClass *object_class = G_OBJECT_CLASS (klass);
         GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+        
 
         object_class->finalize = edit_page_finalize;
+        object_class->set_property = gr_edit_page_set_property;
+        object_class->get_property = gr_edit_page_get_property;
+
+
+        props [PROP_UNSAVED] = g_param_spec_boolean ("unsaved",
+                                                      NULL, NULL,
+                                                      TRUE, G_PARAM_READWRITE);
+        g_object_class_install_properties (object_class, N_PROPS, props);
+        
 
         gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/Recipes/gr-edit-page.ui");
 
@@ -1510,6 +1580,8 @@ gr_edit_page_class_init (GrEditPageClass *klass)
         gtk_widget_class_bind_template_callback (widget_class, preview_visible_changed);
         gtk_widget_class_bind_template_callback (widget_class, prev_step);
         gtk_widget_class_bind_template_callback (widget_class, next_step);
+        gtk_widget_class_bind_template_callback (widget_class, set_unsaved);
+
 }
 
 GtkWidget *
@@ -1655,6 +1727,8 @@ add_ingredients_segment (GrEditPage *page,
 
                 gspell_entry = gspell_entry_get_from_gtk_entry (GTK_ENTRY (entry));
                 gspell_entry_basic_setup (gspell_entry);
+                g_signal_connect_swapped (GTK_WIDGET (entry), "changed", G_CALLBACK (set_unsaved),page);
+
         }
 #endif
 
@@ -1739,6 +1813,7 @@ remove_list (GtkButton *button, GrEditPage *page)
 
         update_segments (page);
         set_active_row (page, NULL);
+        set_unsaved (page);
 }
 
 static void
@@ -1806,7 +1881,6 @@ populate_ingredients (GrEditPage *page,
         gtk_widget_set_margin_top (button, 20);
         gtk_box_pack_end (GTK_BOX (page->ingredients_box), button, FALSE, TRUE, 0);
         g_signal_connect (button, "clicked", G_CALLBACK (add_list), page);
-
         update_segments (page);
 }
 
diff --git a/src/gr-edit-page.ui b/src/gr-edit-page.ui
index 57409ee..d37abdd 100644
--- a/src/gr-edit-page.ui
+++ b/src/gr-edit-page.ui
@@ -6,6 +6,7 @@
     <property name="upper">99</property>
     <property name="step-increment">1</property>
     <property name="page-increment">10</property>
+    <signal name="value-changed" handler="set_unsaved" swapped="yes"/>
   </object>
   <template class="GrEditPage" parent="GtkBox">
     <property name="visible">True</property>
@@ -294,6 +295,7 @@
                         <property name="valign">baseline</property>
                         <property name="margin-bottom">10</property>
                         <property name="width-chars">30</property>
+                        <signal name="changed" handler="set_unsaved" swapped="yes"/>
                       </object>
                       <packing>
                         <property name="left-attach">1</property>
@@ -354,6 +356,7 @@
                         <property name="has-entry">1</property>
                         <property name="valign">center</property>
                         <property name="margin-bottom">10</property>
+                        <signal name="changed" handler="set_unsaved" swapped="yes"/>
                         <items>
                           <item translatable="yes" id="Less than 15 minutes">Less than 15 minutes</item>
                           <item translatable="yes" id="15 to 30 minutes">15 to 30 minutes</item>
@@ -391,6 +394,7 @@
                         <property name="has-entry">1</property>
                         <property name="valign">center</property>
                         <property name="margin-bottom">40</property>
+                        <signal name="changed" handler="set_unsaved" swapped="yes"/>
                         <items>
                           <item translatable="yes" id="Less than 15 minutes">Less than 15 minutes</item>
                           <item translatable="yes" id="15 to 30 minutes">15 to 30 minutes</item>
@@ -428,6 +432,7 @@
                         <property name="has-entry">1</property>
                         <property name="valign">center</property>
                         <property name="margin-bottom">10</property>
+                        <signal name="changed" handler="set_unsaved" swapped="yes"/>
                       </object>
                       <packing>
                         <property name="left-attach">1</property>
@@ -458,6 +463,7 @@
                         <property name="has-entry">1</property>
                         <property name="valign">center</property>
                         <property name="margin-bottom">10</property>
+                        <signal name="changed" handler="set_unsaved" swapped="yes"/>
                       </object>
                       <packing>
                         <property name="left-attach">1</property>
@@ -488,6 +494,7 @@
                         <property name="has-entry">1</property>
                         <property name="valign">center</property>
                         <property name="margin-bottom">10</property>
+                        <signal name="changed" handler="set_unsaved" swapped="yes"/>
                       </object>
                       <packing>
                         <property name="left-attach">1</property>
@@ -517,6 +524,7 @@
                         <property name="visible">1</property>
                         <property name="valign">center</property>
                         <property name="margin-bottom">20</property>
+                        <signal name="changed" handler="set_unsaved" swapped="yes"/>
                         <items>
                           <item translatable="yes" id="mild">Mild</item>
                           <item translatable="yes" id="spicy">Somewhat spicy</item>
@@ -551,6 +559,7 @@
                         <property name="min-content-height">120</property>
                         <child>
                           <object class="GtkTextView" id="description_field">
+                            <property name="buffer">instructions_buffer</property>
                             <property name="visible">1</property>
                             <property name="wrap-mode">word</property>
                             <property name="top-margin">10</property>
@@ -591,30 +600,35 @@
                           <object class="GtkCheckButton" id="gluten_free_check">
                             <property name="visible">1</property>
                             <property name="label" translatable="yes">Gluten free</property>
+                            <signal name="clicked" handler="set_unsaved" swapped="yes" />
                           </object>
                         </child>
                         <child>
                           <object class="GtkCheckButton" id="nut_free_check">
                             <property name="visible">1</property>
                             <property name="label" translatable="yes">Nut free</property>
+                            <signal name="clicked" handler="set_unsaved" swapped="yes"/>
                           </object>
                         </child>
                         <child>
                           <object class="GtkCheckButton" id="vegan_check">
                             <property name="visible">1</property>
                             <property name="label" translatable="yes">Vegan</property>
+                            <signal name="clicked" handler="set_unsaved" swapped="yes"/>
                           </object>
                         </child>
                         <child>
                           <object class="GtkCheckButton" id="vegetarian_check">
                             <property name="visible">1</property>
                             <property name="label" translatable="yes">Vegetarian</property>
+                            <signal name="clicked" handler="set_unsaved" swapped="yes"/>
                           </object>
                         </child>
                         <child>
                           <object class="GtkCheckButton" id="milk_free_check">
                             <property name="visible">1</property>
                             <property name="label" translatable="yes">Milk free</property>
+                            <signal name="clicked" handler="set_unsaved" swapped="yes"/>
                           </object>
                         </child>
                       </object>
@@ -690,6 +704,7 @@
                     <property name="min-content-height">300</property>
                     <child>
                       <object class="GtkTextView" id="instructions_field">
+                        <property name="buffer">instructions_buffer</property>
                         <property name="visible">1</property>
                         <property name="wrap-mode">word</property>
                         <property name="top-margin">10</property>
@@ -1034,6 +1049,7 @@
             <signal name="input" handler="time_spin_input"/>
             <signal name="output" handler="time_spin_output"/>
             <signal name="activate" handler="time_spin_activate"/>
+            <signal name="change-value" handler="set_unsaved" swapped="yes"/>
           </object>
         </child>
         <child>
@@ -1052,6 +1068,7 @@
     <property name="lower">-50</property>
     <property name="step-increment">1</property>
     <property name="page-increment">10</property>
+    <signal name="changed" handler="set_unsaved" swapped="yes"/>
   </object>
   <object class="GtkPopover" id="temperature_popover">
     <property name="relative-to">temperature_button</property>
@@ -1068,6 +1085,7 @@
             <property name="width-chars">4</property>
             <property name="adjustment">temperature_adjustment</property>
             <signal name="activate" handler="temperature_spin_activate"/>
+            <signal name="change-value" handler="set_unsaved" swapped="yes"/>
           </object>
         </child>
         <child>
@@ -1218,4 +1236,10 @@
       </object>
     </child>
   </object>
+  <object class="GtkTextBuffer" id="instructions_buffer">
+    <signal name="changed" handler="set_unsaved" swapped="yes"/>
+  </object>
+  <object class="GtkTextBuffer" id="description_buffer">
+    <signal name="changed" handler="set_unsaved" swapped="yes"/>
+  </object>
 </interface>
diff --git a/src/gr-window.c b/src/gr-window.c
index 4005370..325fd18 100644
--- a/src/gr-window.c
+++ b/src/gr-window.c
@@ -58,6 +58,7 @@ struct _GrWindow
         GtkWidget *back_button;
         GtkWidget *search_button;
         GtkWidget *cooking_button;
+        GtkWidget *save_button;
         GtkWidget *search_bar;
         GtkWidget *main_stack;
         GtkWidget *recipes_page;
@@ -107,6 +108,20 @@ typedef struct
         char **search;
 } BackEntry;
 
+
+static
+void make_save_sensitive (GrEditPage *edit_page, GParamSpec *pspec, gpointer data)
+{
+        GrWindow *window = GR_WINDOW (data);
+        gboolean unsaved;
+
+        g_object_get (G_OBJECT (edit_page), "unsaved", &unsaved, NULL);
+        if (unsaved)
+                gtk_widget_set_sensitive (window->save_button,TRUE);
+        else
+                gtk_widget_set_sensitive (window->save_button,FALSE);
+}
+
 static void
 back_entry_free (BackEntry *entry)
 {
@@ -190,6 +205,7 @@ new_recipe (GrWindow *window)
         gtk_stack_set_visible_child_name (GTK_STACK (window->header_end_stack), "edit");
 
         gtk_stack_set_visible_child_name (GTK_STACK (window->main_stack), "edit");
+        gtk_widget_set_sensitive(window->save_button,FALSE);
 }
 
 static void
@@ -651,6 +667,7 @@ gr_window_class_init (GrWindowClass *klass)
         gtk_widget_class_bind_template_child (widget_class, GrWindow, back_button);
         gtk_widget_class_bind_template_child (widget_class, GrWindow, search_button);
         gtk_widget_class_bind_template_child (widget_class, GrWindow, cooking_button);
+        gtk_widget_class_bind_template_child (widget_class, GrWindow, save_button);
         gtk_widget_class_bind_template_child (widget_class, GrWindow, search_bar);
         gtk_widget_class_bind_template_child (widget_class, GrWindow, main_stack);
         gtk_widget_class_bind_template_child (widget_class, GrWindow, recipes_page);
@@ -743,6 +760,7 @@ gr_window_init (GrWindow *self)
         gtk_widget_init_template (GTK_WIDGET (self));
         self->back_entry_stack = g_queue_new ();
 
+        g_signal_connect (self->edit_page, "notify::unsaved", G_CALLBACK (make_save_sensitive), self);
         g_action_map_add_action_entries (G_ACTION_MAP (self),
                                          entries, G_N_ELEMENTS (entries),
                                          self);
@@ -801,6 +819,7 @@ gr_window_edit_recipe (GrWindow *window,
         gtk_stack_set_visible_child_name (GTK_STACK (window->header_end_stack), "edit");
 
         gtk_stack_set_visible_child_name (GTK_STACK (window->main_stack), "edit");
+        gtk_widget_set_sensitive(window->save_button,FALSE);
 }
 
 static void
@@ -1320,3 +1339,5 @@ gr_window_show_report_issue (GrWindow *window)
         if (error)
                 g_warning ("Unable to show '%s': %s", uri, error->message);
 }
+
+
diff --git a/src/gr-window.ui b/src/gr-window.ui
index 39d8ed7..835d2eb 100644
--- a/src/gr-window.ui
+++ b/src/gr-window.ui
@@ -124,7 +124,7 @@
               </packing>
             </child>
             <child>
-              <object class="GtkButton">
+              <object class="GtkButton" id="save_button">
                 <property name="visible">1</property>
                 <property name="use-underline">1</property>
                 <property name="label" translatable="yes">_Save</property>


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