[recipes] Handle serves count properly with shopping
- From: Matthias Clasen <matthiasc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [recipes] Handle serves count properly with shopping
- Date: Sat, 11 Feb 2017 14:07:21 +0000 (UTC)
commit 545410b04ebe0d0db5ff2ee4ac15803138bcaee5
Author: Matthias Clasen <mclasen redhat com>
Date: Sat Feb 11 09:02:59 2017 -0500
Handle serves count properly with shopping
Persist the serves count for the recipes on the shopping list,
and transfer the count from the details page when adding
recipes to the shopping list.
src/gr-details-page.c | 4 ++-
src/gr-recipe-small-tile.c | 24 +++++++++++-------
src/gr-recipe-small-tile.h | 4 ++-
src/gr-recipe-store.c | 57 ++++++++++++++++++++++++++++++++++++++++----
src/gr-recipe-store.h | 5 +++-
src/gr-shopping-page.c | 30 ++++++++++++++++++++--
6 files changed, 104 insertions(+), 20 deletions(-)
---
diff --git a/src/gr-details-page.c b/src/gr-details-page.c
index 16df194..687ed41 100644
--- a/src/gr-details-page.c
+++ b/src/gr-details-page.c
@@ -183,9 +183,11 @@ shop_it (GrDetailsPage *page)
{
GrRecipeStore *store;
GtkWidget *window;
+ int serves;
store = gr_app_get_recipe_store (GR_APP (g_application_get_default ()));
- gr_recipe_store_add_to_shopping (store, page->recipe);
+ serves = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (page->serves_spin));
+ gr_recipe_store_add_to_shopping (store, page->recipe, serves);
window = gtk_widget_get_ancestor (GTK_WIDGET (page), GTK_TYPE_APPLICATION_WINDOW);
gr_window_offer_shopping (GR_WINDOW (window));
diff --git a/src/gr-recipe-small-tile.c b/src/gr-recipe-small-tile.c
index 182a062..6e30989 100644
--- a/src/gr-recipe-small-tile.c
+++ b/src/gr-recipe-small-tile.c
@@ -57,8 +57,8 @@ enum {
};
static void
-set_serves (GrRecipeSmallTile *tile,
- int serves)
+recipe_small_tile_set_serves (GrRecipeSmallTile *tile,
+ int serves)
{
g_autofree char *tmp = NULL;
@@ -109,8 +109,6 @@ recipe_small_tile_set_recipe (GrRecipeSmallTile *tile,
tmp = g_strdup_printf (_("by %s"), chef ? gr_chef_get_name (chef) : _("Anonymous"));
gtk_label_set_label (GTK_LABEL (tile->author), tmp);
}
-
- set_serves (tile, gr_recipe_get_serves (recipe));
}
static void
@@ -125,7 +123,7 @@ serves_value_changed (GrRecipeSmallTile *tile)
int serves;
serves = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (tile->serves_spin));
- set_serves (tile, serves);
+ recipe_small_tile_set_serves (tile, serves);
}
static void
@@ -153,7 +151,7 @@ gr_recipe_small_tile_init (GrRecipeSmallTile *tile)
{
gtk_widget_set_has_window (GTK_WIDGET (tile), FALSE);
gtk_widget_init_template (GTK_WIDGET (tile));
- set_serves (tile, 1);
+ recipe_small_tile_set_serves (tile, 1);
}
static void
@@ -183,7 +181,7 @@ recipe_small_tile_set_property (GObject *object,
switch (prop_id) {
case PROP_SERVES:
- set_serves (self, g_value_get_int (value));
+ recipe_small_tile_set_serves (self, g_value_get_int (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@@ -223,12 +221,14 @@ gr_recipe_small_tile_class_init (GrRecipeSmallTileClass *klass)
}
GtkWidget *
-gr_recipe_small_tile_new (GrRecipe *recipe)
+gr_recipe_small_tile_new (GrRecipe *recipe,
+ int serves)
{
GrRecipeSmallTile *tile;
tile = g_object_new (GR_TYPE_RECIPE_SMALL_TILE, NULL);
- recipe_small_tile_set_recipe (GR_RECIPE_SMALL_TILE (tile), recipe);
+ recipe_small_tile_set_recipe (tile, recipe);
+ recipe_small_tile_set_serves (tile, serves);
return GTK_WIDGET (tile);
}
@@ -238,3 +238,9 @@ gr_recipe_small_tile_get_recipe (GrRecipeSmallTile *tile)
{
return tile->recipe;
}
+
+int
+gr_recipe_small_tile_get_serves (GrRecipeSmallTile *tile)
+{
+ return tile->serves;
+}
diff --git a/src/gr-recipe-small-tile.h b/src/gr-recipe-small-tile.h
index 38a40ba..59fb82f 100644
--- a/src/gr-recipe-small-tile.h
+++ b/src/gr-recipe-small-tile.h
@@ -30,7 +30,9 @@ G_BEGIN_DECLS
G_DECLARE_FINAL_TYPE (GrRecipeSmallTile, gr_recipe_small_tile, GR, RECIPE_SMALL_TILE, GtkButton)
-GtkWidget *gr_recipe_small_tile_new (GrRecipe *recipe);
+GtkWidget *gr_recipe_small_tile_new (GrRecipe *recipe,
+ int serves);
GrRecipe *gr_recipe_small_tile_get_recipe (GrRecipeSmallTile *tile);
+int gr_recipe_small_tile_get_serves (GrRecipeSmallTile *tile);
G_END_DECLS
diff --git a/src/gr-recipe-store.c b/src/gr-recipe-store.c
index 66095d1..8b2d20a 100644
--- a/src/gr-recipe-store.c
+++ b/src/gr-recipe-store.c
@@ -45,6 +45,7 @@ struct _GrRecipeStore
char **picks;
char **favorites;
char **shopping;
+ int *shopping_serves;
char **featured_chefs;
char *user;
@@ -654,6 +655,7 @@ load_shopping (GrRecipeStore *self,
g_autoptr(GKeyFile) keyfile = NULL;
g_autoptr(GError) error = NULL;
g_autofree char *tmp = NULL;
+ gsize len1, len2;
keyfile = g_key_file_new ();
@@ -669,13 +671,24 @@ load_shopping (GrRecipeStore *self,
g_message ("Load shopping db: %s", path);
- self->shopping = g_key_file_get_string_list (keyfile, "Content", "Recipes", NULL, &error);
+ self->shopping = g_key_file_get_string_list (keyfile, "Content", "Recipes", &len1, &error);
if (error) {
if (!g_error_matches (error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_KEY_NOT_FOUND)) {
g_warning ("Failed to load shopping: %s", error->message);
}
g_clear_error (&error);
}
+ self->shopping_serves = g_key_file_get_integer_list (keyfile, "Content", "Serves", &len2, &error);
+ if (error) {
+ if (!g_error_matches (error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_KEY_NOT_FOUND)) {
+ g_warning ("Failed to load shopping: %s", error->message);
+ }
+ g_clear_error (&error);
+ }
+
+ if (len1 != len2) {
+ g_warning ("Failed to load shopping: Recipes and Serves lists have different lengths");
+ }
tmp = g_key_file_get_string (keyfile, "Content", "LastChange", &error);
if (error) {
@@ -704,6 +717,8 @@ save_shopping (GrRecipeStore *self)
g_key_file_set_string_list (keyfile, "Content", "Recipes", (const char * const *)self->shopping,
g_strv_length (self->shopping));
+ g_key_file_set_integer_list (keyfile, "Content", "Serves", self->shopping_serves, g_strv_length
(self->shopping));
+
if (self->shopping_change) {
g_autofree char *tmp = NULL;
@@ -1483,28 +1498,41 @@ gr_recipe_store_last_favorite_change (GrRecipeStore *self)
void
gr_recipe_store_add_to_shopping (GrRecipeStore *self,
- GrRecipe *recipe)
+ GrRecipe *recipe,
+ int serves)
{
char **strv;
+ int *intv;
int length;
int i;
const char *id;
id = gr_recipe_get_id (recipe);
- if (g_strv_contains ((const char * const*)self->shopping, id))
- return;
+ for (i = 0; self->shopping[i]; i++) {
+ if (strcmp (self->shopping[i], id) == 0) {
+ self->shopping_serves[i] = serves;
+ goto save;
+ }
+ }
length = g_strv_length (self->shopping);
strv = g_new (char *, length + 2);
strv[0] = g_strdup (id);
- for (i = 0; i < length; i++)
+ intv = g_new (int, length + 1);
+ intv[0] = serves;
+ for (i = 0; i < length; i++) {
strv[i + 1] = self->shopping[i];
+ intv[i + 1] = self->shopping_serves[i];
+ }
strv[length + 1] = NULL;
g_free (self->shopping);
+ g_free (self->shopping_serves);
self->shopping = strv;
+ self->shopping_serves = intv;
+save:
if (self->shopping_change)
g_date_time_unref (self->shopping_change);
self->shopping_change = g_date_time_new_now_utc ();
@@ -1528,6 +1556,7 @@ gr_recipe_store_remove_from_shopping (GrRecipeStore *self,
g_free (self->shopping[i]);
for (j = i; self->shopping[j]; j++) {
self->shopping[j] = self->shopping[j + 1];
+ self->shopping_serves[j] = self->shopping_serves[j + 1];
}
break;
}
@@ -1556,6 +1585,24 @@ gr_recipe_store_is_in_shopping (GrRecipeStore *self,
return g_strv_contains ((const char *const*)self->shopping, id);
}
+int
+gr_recipe_store_get_shopping_serves (GrRecipeStore *self,
+ GrRecipe *recipe)
+{
+ const char *id;
+ int i;
+
+ id = gr_recipe_get_id (recipe);
+
+ for (i = 0; self->shopping[i]; i++) {
+ if (strcmp (self->shopping[i], id) == 0) {
+ return self->shopping_serves[i];
+ }
+ }
+
+ return 0;
+}
+
GDateTime *
gr_recipe_store_last_shopping_change (GrRecipeStore *self)
{
diff --git a/src/gr-recipe-store.h b/src/gr-recipe-store.h
index f1da9c3..8018974 100644
--- a/src/gr-recipe-store.h
+++ b/src/gr-recipe-store.h
@@ -76,11 +76,14 @@ gboolean gr_recipe_store_is_favorite (GrRecipeStore *self,
GrRecipe *recipe);
GDateTime *gr_recipe_store_last_favorite_change (GrRecipeStore *self);
void gr_recipe_store_add_to_shopping (GrRecipeStore *self,
- GrRecipe *recipe);
+ GrRecipe *recipe,
+ int serves);
void gr_recipe_store_remove_from_shopping (GrRecipeStore *self,
GrRecipe *recipe);
gboolean gr_recipe_store_is_in_shopping (GrRecipeStore *self,
GrRecipe *recipe);
+int gr_recipe_store_get_shopping_serves (GrRecipeStore *store,
+ GrRecipe *recipe);
GDateTime *gr_recipe_store_last_shopping_change (GrRecipeStore *self);
gboolean gr_recipe_store_has_diet (GrRecipeStore *self,
GrDiets diet);
diff --git a/src/gr-shopping-page.c b/src/gr-shopping-page.c
index 07cfc3f..40eaa1e 100644
--- a/src/gr-shopping-page.c
+++ b/src/gr-shopping-page.c
@@ -465,7 +465,7 @@ collect_ingredients (GrShoppingPage *page)
int serves;
recipe = gr_recipe_small_tile_get_recipe (GR_RECIPE_SMALL_TILE (tile));
- g_object_get (tile, "serves", &serves, NULL);
+ serves = gr_recipe_small_tile_get_serves (GR_RECIPE_SMALL_TILE (tile));
collect_ingredients_from_recipe (page, recipe, serves);
}
g_list_free (children);
@@ -497,6 +497,24 @@ recipes_changed (GrShoppingPage *page)
}
static void
+serves_changed (GObject *object, GParamSpec *pspec, GrShoppingPage *page)
+{
+ GrRecipeSmallTile *tile = GR_RECIPE_SMALL_TILE (object);
+ GrRecipeStore *store;
+ GrRecipe *recipe;
+ int serves;
+
+ recipe = gr_recipe_small_tile_get_recipe (tile);
+ serves = gr_recipe_small_tile_get_serves (tile);
+
+ store = gr_app_get_recipe_store (GR_APP (g_application_get_default ()));
+
+ gr_recipe_store_add_to_shopping (store, recipe, serves);
+
+ recipes_changed (page);
+}
+
+static void
search_started (GrRecipeSearch *search,
GrShoppingPage *page)
{
@@ -509,13 +527,19 @@ search_hits_added (GrRecipeSearch *search,
GList *hits,
GrShoppingPage *page)
{
+ GrRecipeStore *store;
GList *l;
+ store = gr_app_get_recipe_store (GR_APP (g_application_get_default ()));
+
for (l = hits; l; l = l->next) {
GrRecipe *recipe = l->data;
GtkWidget *tile;
- tile = gr_recipe_small_tile_new (recipe);
- g_signal_connect_swapped (tile, "notify::serves", G_CALLBACK (recipes_changed), page);
+ int serves;
+
+ serves = gr_recipe_store_get_shopping_serves (store, recipe);
+ tile = gr_recipe_small_tile_new (recipe, serves);
+ g_signal_connect (tile, "notify::serves", G_CALLBACK (serves_changed), page);
gtk_container_add (GTK_CONTAINER (page->recipe_list), tile);
page->recipe_count++;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]