[recipes/unit_convert: 3/4] Added multiple_unit functionality to show e.g. 1 lb, 2 oz instead of 1 1/8 lb. fixed display for pr



commit 0c68a42255a0c79a1abd338df8564e9a9f7a232f
Author: Paxana Amanda Xander <veganbikepunk gmail com>
Date:   Mon Aug 28 15:19:25 2017 -0700

    Added multiple_unit functionality to show e.g. 1 lb, 2 oz instead of 1 1/8 lb.  fixed display for 
printout and shopping list to show the same.

 src/gr-convert-units.c      |  128 ++++++++++++++++++-
 src/gr-convert-units.h      |    4 +-
 src/gr-ingredients-list.c   |    4 +-
 src/gr-ingredients-list.h   |    1 -
 src/gr-ingredients-viewer.c |   36 +-----
 src/gr-recipe-printer.c     |   21 ++--
 src/gr-shopping-page.c      |   43 +++++--
 src/gr-unit.c               |  300 ++++++++++++++++++++++---------------------
 src/gr-unit.h               |  105 ++++++++--------
 9 files changed, 380 insertions(+), 262 deletions(-)
---
diff --git a/src/gr-convert-units.c b/src/gr-convert-units.c
index 6173850..dd43ec2 100644
--- a/src/gr-convert-units.c
+++ b/src/gr-convert-units.c
@@ -422,11 +422,129 @@ gr_convert_human_readable (double *amount, GrUnit *unit)
                 ;
     }
 
-                if (*unit == unit1) {
-                unit_changed = FALSE; 
+    if (*unit == unit1) {
+    unit_changed = FALSE; 
+    }
+    
+    *amount = amount1;
+    *unit = unit1;
+    }
+}
+
+void
+gr_convert_multiple_units (double *amount1, GrUnit *unit1, double *amount2, GrUnit *unit2)
+{
+
+    double n1 = *amount1;
+    double n2 = *amount2;
+    GrUnit u1 = *unit1;
+    GrUnit u2 = *unit2;
+    double fractional, integer;
+
+    gr_convert_human_readable(&n1, &u1);
+
+    fractional = modf(n1, &integer);
+
+    if (u1 != GR_UNIT_UNKNOWN) {
+            if (fractional > 0)
+            {
+                n2 = fractional;
+                u2 = u1;
+                gr_convert_human_readable(&n2, &u2);
+
+                if (u1 != u2)
+                {
+                        n1 = integer;
                 }
                 
-                *amount = amount1;
-                *unit = unit1;
+                else 
+                {
+                        n2 = 0;
+                        u2 = GR_UNIT_UNKNOWN;
+                }
+        }
+        
+        else
+        {
+                n2 = 0;
+                u2 = GR_UNIT_UNKNOWN;
+        }
+    }
+
+    else
+    {
+            n2 = 0;
+            u2 = GR_UNIT_UNKNOWN;
+    }
+
+    *amount1 = n1;
+    *unit1 = u1;
+    *amount2 = n2;
+    *unit2 = u2;
+}
+
+void
+gr_convert_format_for_display  (GString *s, double a1, GrUnit u1, double a2, GrUnit u2) 
+{
+
+    if (u1 == GR_UNIT_UNKNOWN || (!u1)) {
+        g_autofree char *num = NULL;
+        num = gr_number_format (a1);
+        g_string_append(s, num);
+    }
+
+    else if (u2 == GR_UNIT_UNKNOWN) {
+        g_autofree char *num = NULL;
+        num = gr_number_format (a1);
+        g_string_append (s, num);
+        g_string_append (s, " ");
+        g_string_append (s, gr_unit_get_display_name (u1));
+    }
+
+    else {
+        g_autofree char *num1 = NULL;
+        g_autofree char *num2 = NULL;
+
+        num1 = gr_number_format (a1);
+        num2 = gr_number_format (a2);
+        g_string_append(s, num1);
+        g_string_append(s, " ");
+        g_string_append(s, gr_unit_get_display_name (u1));
+        g_string_append(s, ", ");
+        g_string_append(s, num2);
+        g_string_append(s, " ");
+        g_string_append(s, gr_unit_get_display_name (u2));
     }
-}
\ No newline at end of file
+}
+
+void
+gr_convert_format (GString *s, double amount, GrUnit unit)
+{
+    GrPreferredUnit user_volume_unit = gr_convert_get_volume_unit();
+    GrPreferredUnit user_weight_unit = gr_convert_get_weight_unit();
+    double amount2 = 0;
+    GrUnit unit2 = GR_UNIT_UNKNOWN;
+        
+    GrDimension dimension = gr_unit_get_dimension(unit);
+
+        if (dimension) {
+
+            if (dimension == GR_DIMENSION_VOLUME) {
+                gr_convert_volume(&amount, &unit, user_volume_unit); 
+            }
+
+            if (dimension == GR_DIMENSION_MASS) {
+                gr_convert_weight(&amount, &unit, user_weight_unit);
+                }
+            }
+
+            if ((dimension == GR_DIMENSION_VOLUME && user_volume_unit == GR_PREFERRED_UNIT_IMPERIAL) || 
+                (dimension == GR_DIMENSION_MASS && user_weight_unit == GR_PREFERRED_UNIT_IMPERIAL)) {
+                    gr_convert_multiple_units(&amount, &unit, &amount2, &unit2);  
+            }
+            else {
+                    gr_convert_human_readable(&amount, &unit);
+            }
+                
+    gr_convert_format_for_display (s, amount, unit, amount2, unit2);
+}
diff --git a/src/gr-convert-units.h b/src/gr-convert-units.h
index f817063..59614d6 100644
--- a/src/gr-convert-units.h
+++ b/src/gr-convert-units.h
@@ -47,6 +47,8 @@ void                gr_convert_temp                     (int *num, int *unit, in
 void                gr_convert_volume                   (double *amount, GrUnit *unit, GrPreferredUnit 
user_volume_unit); 
 void                gr_convert_weight                   (double *amount, GrUnit *unit, GrPreferredUnit 
user_weight_unit);
 void                gr_convert_human_readable           (double *amount, GrUnit *unit);
-
+void                gr_convert_multiple_units           (double *amount1, GrUnit *unit1, double *amount2, 
GrUnit *unit2);
+void                gr_convert_format_for_display       (GString *s, double a1, GrUnit u1, double a2, GrUnit 
u2);
+void                gr_convert_format                   (GString *s, double amount, GrUnit unit);
 
 G_END_DECLS
\ No newline at end of file
diff --git a/src/gr-ingredients-list.c b/src/gr-ingredients-list.c
index 1cd2d61..ce3a11a 100644
--- a/src/gr-ingredients-list.c
+++ b/src/gr-ingredients-list.c
@@ -279,7 +279,6 @@ gr_ingredients_list_get_unit (GrIngredientsList *ingredients,
 
 double
 gr_ingredients_list_get_amount (GrIngredientsList *ingredients,
-                                const char        *segment,
                                 const char        *name)
 {
         GList *l;
@@ -287,8 +286,7 @@ gr_ingredients_list_get_amount (GrIngredientsList *ingredients,
         for (l = ingredients->ingredients; l; l = l->next) {
                 Ingredient *ing = (Ingredient *)l->data;
 
-                if (g_strcmp0 (segment, ing->segment) == 0 &&
-                    g_strcmp0 (name, ing->name) == 0) {
+                if (g_strcmp0 (name, ing->name) == 0) {
                         return ing->amount;
                 }
         }
diff --git a/src/gr-ingredients-list.h b/src/gr-ingredients-list.h
index 7b693f2..68e10fa 100644
--- a/src/gr-ingredients-list.h
+++ b/src/gr-ingredients-list.h
@@ -47,7 +47,6 @@ char             **gr_ingredients_list_get_ingredients (GrIngredientsList  *ingr
 GrUnit             gr_ingredients_list_get_unit        (GrIngredientsList  *list,
                                                         const char         *ingredient);
 double             gr_ingredients_list_get_amount      (GrIngredientsList  *list,
-                                                        const char         *segment,
                                                         const char         *ingredient);
 
 G_END_DECLS
diff --git a/src/gr-ingredients-viewer.c b/src/gr-ingredients-viewer.c
index cec050d..7b725de 100644
--- a/src/gr-ingredients-viewer.c
+++ b/src/gr-ingredients-viewer.c
@@ -322,43 +322,17 @@ gr_ingredients_viewer_set_ingredients (GrIngredientsViewer *viewer,
                 double amount;
                 GrUnit unit;
                 GtkWidget *row;
-                GrDimension dimension;
+                g_autoptr(GString) s = NULL;
+                s = g_string_new ("");
                 double scale = viewer->scale;
 
                 unit = gr_ingredients_list_get_unit(ingredients, ings[i]);
-                amount = gr_ingredients_list_get_amount(ingredients, viewer->title, ings[i]) * scale;
-                dimension = gr_unit_get_dimension(unit);
+                amount = gr_ingredients_list_get_amount(ingredients, ings[i]) * scale;
 
-                if (dimension) {
-                
-                        if (dimension == GR_DIMENSION_VOLUME) {
-                                GrPreferredUnit user_volume_unit = gr_convert_get_volume_unit();
-                                gr_convert_volume(&amount, &unit, user_volume_unit); 
-                        }
-
-                        if (dimension == GR_DIMENSION_MASS) {
-                                GrPreferredUnit user_weight_unit = gr_convert_get_weight_unit();
-                                gr_convert_weight(&amount, &unit, user_weight_unit);
-                        }
-                }
-
-                gr_convert_human_readable(&amount, &unit);
-
-                char *a_final = gr_number_format(amount);
-                const char *u_final = gr_unit_get_name(unit);
-        
-                char for_display[128];
-                if (u_final == NULL) {
-                        snprintf(for_display, sizeof for_display, "%s", a_final);
-                }
-                else {
-                        snprintf(for_display, sizeof for_display, "%s %s", a_final, u_final);
-                }
-
-                u_final = for_display;
+                gr_convert_format(s, amount, unit);
 
                 row = g_object_new (GR_TYPE_INGREDIENTS_VIEWER_ROW,
-                                        "unit", u_final,
+                                        "unit", g_strdup (s->str),
                                         "ingredient", ings[i],
                                         "size-group", viewer->group,
                                         "editable", viewer->editable,
diff --git a/src/gr-recipe-printer.c b/src/gr-recipe-printer.c
index 7f9b92b..515d191 100644
--- a/src/gr-recipe-printer.c
+++ b/src/gr-recipe-printer.c
@@ -193,16 +193,19 @@ begin_print (GtkPrintOperation *operation,
         pango_layout_set_width (layout, width * PANGO_SCALE);
         pango_layout_set_font_description (layout, body_font);
 
-        for (j = 0; segs[j]; j++) {
-                ings = gr_ingredients_list_get_ingredients (ingredients, segs[j]);
-                for (i = 0; ings[i]; i++) {
-                        g_autofree char *unit = NULL;
-
-                        unit = gr_ingredients_list_scale_unit (ingredients, segs[j], ings[i], 1.0);
-                        g_string_append (s, unit);
-                        g_string_append (s, " \n");
-                }
+        for (i = 0; ings && ings[i]; i++) {
+                
+                                double amount;
+                                GrUnit unit;       
+                                double scale = 1.0;
+                                
+                                unit = gr_ingredients_list_get_unit(ingredients, ings[i]);
+                
+                                amount = gr_ingredients_list_get_amount(ingredients, ings[i]) * scale;
+                
+                                gr_convert_format(s, amount, unit);
         }
+
         pango_layout_set_text (layout, s->str, s->len);
         pango_layout_get_size (layout, &amount_width, NULL);
         g_clear_object (&layout);
diff --git a/src/gr-shopping-page.c b/src/gr-shopping-page.c
index 27549e6..df7b1c0 100644
--- a/src/gr-shopping-page.c
+++ b/src/gr-shopping-page.c
@@ -34,6 +34,7 @@
 #include "gr-shopping-list-printer.h"
 #include "gr-shopping-list-formatter.h"
 #include "gr-mail.h"
+#include "gr-convert-units.h"
 
 
 struct _GrShoppingPage
@@ -208,21 +209,41 @@ ingredient_format_unit (Ingredient *ing)
 {
         g_autoptr(GString) s = NULL;
         int i;
-
+        GrPreferredUnit user_volume_unit = gr_convert_get_volume_unit();
+        GrPreferredUnit user_weight_unit = gr_convert_get_weight_unit();
+        GrUnit u1;
+        double a1;
+        GrDimension dimension;
         s = g_string_new ("");
 
         for (i = 0; i < ing->units->len; i++) {
-                Unit *u = &g_array_index (ing->units, Unit, i);
-                g_autofree char *num = NULL;
-                if (s->len > 0)
-                        g_string_append (s, ", ");
-                num = gr_number_format (u->amount);
-                g_string_append (s, num);
-                g_string_append (s, " ");
-                if (u->unit)
-                        g_string_append (s, gr_unit_get_abbreviation (u->unit));
+                Unit *unit = &g_array_index (ing->units, Unit, i);
+                double a = unit->amount;
+                GrUnit u = unit->unit;
+
+                dimension = gr_unit_get_dimension (u);
+
+                if (dimension == GR_DIMENSION_VOLUME) {
+                        gr_convert_volume (&a, &u, user_volume_unit);
+                }
+                else if (dimension == GR_DIMENSION_MASS) {
+                        gr_convert_weight (&a, &u, user_weight_unit);
+                }
+
+                if (i == 0) {
+                        u1 = u;
+                        a1 = a;
+                }
+                else if (u == u1) {
+                        a1 += a;
+                }
+                else {
+                        g_error ("conversion yielded different units...why...");
+                }
         }
 
+        gr_convert_format (s, a1, u1);
+
         return g_strdup (s->str);
 }
 
@@ -458,7 +479,7 @@ collect_ingredients_from_recipe (GrShoppingPage *page,
                         GrUnit unit;
                         double amount;
 
-                        amount = gr_ingredients_list_get_amount (il, seg[i], ing[j]);
+                        amount = gr_ingredients_list_get_amount (il, ing[j]);
                         amount = amount * yield / gr_recipe_get_yield (recipe);
                         unit = gr_ingredients_list_get_unit (il, ing[j]);
                         add_ingredient (page, amount, unit, ing[j]);
diff --git a/src/gr-unit.c b/src/gr-unit.c
index e81f6be..688e527 100644
--- a/src/gr-unit.c
+++ b/src/gr-unit.c
@@ -16,152 +16,154 @@
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-#include "config.h"
-
-#include <glib/gi18n.h>
-#include <gio/gio.h>
-
-#include "gr-unit.h"
-#include "gr-utils.h"
-
-static const char * const unit_names[] = {
-        "g", "kg", "lb", "oz", "l", "dl", "ml", "fl oz", "pt", "qt", "gal", "cup",
-        "tbsp", "tsp", "box", "pkg", "glass", "st", "pinch", "bunch",
-        NULL
-};
-
-typedef struct {
-        GrUnit unit;
-        GrDimension dimension;
-        const char *name;
-        const char *abbreviation;
-        const char *display_name;
-        const char *plural;
-} GrUnitData;
-
-static GrUnitData units[] = {
-        { GR_UNIT_GRAM,        GR_DIMENSION_MASS,     "g",       NC_("unit abbreviation", "g"),     
NC_("unit name", "gram"), NC_("unit plural", "grams") },
-        { GR_UNIT_KILOGRAM,    GR_DIMENSION_MASS,     "kg",      NC_("unit abbreviation", "kg"),    
NC_("unit name", "kilogram"), NC_("unit plural", "kilograms") },
-        { GR_UNIT_POUND,       GR_DIMENSION_MASS,     "lb",      NC_("unit abbreviation", "lb"),    
NC_("unit name", "pound"), NC_("unit plural", "pounds") },
-        { GR_UNIT_OUNCE,       GR_DIMENSION_VOLUME,   "oz",      NC_("unit abbreviation", "oz"),    
NC_("unit name", "ounce"), NC_("unit plural", "ounces") },
-        { GR_UNIT_LITER,       GR_DIMENSION_VOLUME,   "l",       NC_("unit abbreviation", "l"),     
NC_("unit name", "liter"), NC_("unit plural", "liters") },
-        { GR_UNIT_DECILITER,   GR_DIMENSION_VOLUME,   "dl",      NC_("unit abbreviation", "dl"),    
NC_("unit name", "deciliter"), NC_("unit plural", "deciliters") },
-        { GR_UNIT_MILLILITER,  GR_DIMENSION_VOLUME,   "ml",      NC_("unit abbreviation", "ml"),    
NC_("unit name", "milliliter"), NC_("unit plural", "milliliters") },
-        { GR_UNIT_FLUID_OUNCE, GR_DIMENSION_VOLUME,   "fl oz",   NC_("unit abbreviation", "fl oz"), 
NC_("unit name", "fluid ounce"), NC_("unit plural", "fluid ounces") },
-        { GR_UNIT_FLUID_OUNCE, GR_DIMENSION_VOLUME,   "fl. oz.", NC_("unit abbreviation", "fl oz"), 
NC_("unit name", "fluid ounce"), NC_("unit plural", "fluid ounces") },
-        { GR_UNIT_PINT,        GR_DIMENSION_VOLUME,   "pt",      NC_("unit abbreviation", "pt"),    
NC_("unit name", "pint"), NC_("unit plural", "pints") },
-        { GR_UNIT_QUART,       GR_DIMENSION_VOLUME,   "qt",      NC_("unit abbreviation", "qt"),    
NC_("unit name", "quart"), NC_("unit plural", "quarts") },
-        { GR_UNIT_GALLON,      GR_DIMENSION_VOLUME,   "gal",     NC_("unit abbreviation", "gal"),   
NC_("unit name", "gallon"), NC_("unit plural", "gallons") },
-        { GR_UNIT_CUP,         GR_DIMENSION_VOLUME,   "cup",     NC_("unit abbreviation", "cup"),   
NC_("unit name", "cup"), NC_("unit plural", "cups") },
-        { GR_UNIT_TABLESPOON,  GR_DIMENSION_VOLUME,   "tbsp",    NC_("unit abbreviation", "tbsp"),  
NC_("unit name", "tablespoon"), NC_("unit plural", "tablespoons") },
-        { GR_UNIT_TEASPOON,    GR_DIMENSION_VOLUME,   "tsp",     NC_("unit abbreviation", "tsp"),   
NC_("unit name", "teaspoon"), NC_("unit plural", "teaspoons") },
-        { GR_UNIT_BOX,         GR_DIMENSION_DISCRETE, "box",     NC_("unit abbreviation", "box"),   
NC_("unit name", "box"), NC_("unit plural", "boxes") },
-        { GR_UNIT_PACKAGE,     GR_DIMENSION_DISCRETE, "pkg",     NC_("unit abbreviation", "pkg"),   
NC_("unit name", "package"), NC_("unit plural", "packages") },
-        { GR_UNIT_GLASS,       GR_DIMENSION_DISCRETE, "glass",   NC_("unit abbreviation", "glass"), 
NC_("unit name", "glass"), NC_("unit plural", "glasses") },
-        { GR_UNIT_MILLIMETER,  GR_DIMENSION_LENGTH,   "mm",      NC_("unit abbreviation", "mm"),    
NC_("unit name", "millimeter"), NC_("unit plural", "millimeters") },
-        { GR_UNIT_CENTIMETER,  GR_DIMENSION_LENGTH,   "cm",      NC_("unit abbreviation", "cm"),    
NC_("unit name", "centimeter"), NC_("unit plural", "centimeters") },
-        { GR_UNIT_METER,       GR_DIMENSION_LENGTH,   "m",       NC_("unit abbreviation", "m"),     
NC_("unit name", "meter"), NC_("unit plural", "meters") },
-        { GR_UNIT_STONE,       GR_DIMENSION_MASS,     "st",      NC_("unit abbreviation", "st"),     
NC_("unit name", "stone"), NC_("unit plural", "stone") },
-        { GR_UNIT_PINCH,       GR_DIMENSION_DISCRETE, "pinch",   NC_("unit abbreviation", "pinch"),     
NC_("unit name", "pinch"), NC_("unit plural", "pinches") },
-        { GR_UNIT_BUNCH,       GR_DIMENSION_DISCRETE, "bunch",   NC_("unit abbreviation", "bunch"), 
NC_("unit name", "bunch"), NC_("unit plural", "bunches") },
-};
-
-const char **
-gr_unit_get_names (void)
-{
-        return (const char **)unit_names;
-}
-
-static GrUnitData *
-find_unit (GrUnit unit)
-{
-        int i;
-        for (i = 0; i < G_N_ELEMENTS (units); i++) {
-                if (units[i].unit == unit)
-                        return &(units[i]);
-        }
-        return NULL;
-}
-
-const char *
-gr_unit_get_name (GrUnit unit)
-{
-        GrUnitData *data = find_unit (unit);
-        if (data)
-                return data->name;
-        return NULL;
-}
-
-const char *
-gr_unit_get_display_name (GrUnit unit)
-{
-        GrUnitData *data = find_unit (unit);
-        if (data)
-                return g_dpgettext2 (NULL, "unit name", data->display_name);
-        return gr_unit_get_name (unit);
-}
-
-const char *
-gr_unit_get_plural (GrUnit unit)
-{
-        GrUnitData *data = find_unit (unit);
-        if (data)
-                return g_dpgettext2 (NULL, "unit plural", data->plural);
-        return gr_unit_get_display_name (unit);
-
-}
-
-const char *
-gr_unit_get_abbreviation (GrUnit unit)
-{
-        GrUnitData *data = find_unit (unit);
-        if (data)
-                return g_dpgettext2 (NULL, "unit abbreviation", data->abbreviation);
-        return gr_unit_get_display_name (unit);
-}
-
-GrDimension
-gr_unit_get_dimension (GrUnit unit)
-{
-        GrUnitData *data = find_unit (unit);
-        if (data)
-                return data->dimension;
-        return GR_DIMENSION_DISCRETE;
-}
-
-GrUnit
-gr_unit_parse (char   **input,
-               GError **error)
-{
-        int i;
-        const char *nu;
-
-        for (i = 0; i < G_N_ELEMENTS (units); i++) {
-                nu = g_dpgettext2 (NULL, "unit name", units[i].display_name);
-                if (g_str_has_prefix (*input, nu) && space_or_nul ((*input)[strlen (nu)])) {
-                        *input += strlen (nu);
-                        return units[i].unit;
-                }
-        }
-
-        for (i = 0; i < G_N_ELEMENTS (units); i++) {
-                nu = g_dpgettext2 (NULL, "unit abbreviation", units[i].abbreviation);
-                if (g_str_has_prefix (*input, nu) && space_or_nul ((*input)[strlen (nu)])) {
-                        *input += strlen (nu);
-                        return units[i].unit;
-                }
-        }
-
-        for (i = 0; i < G_N_ELEMENTS (units); i++) {
-                nu = units[i].name;
-                if (g_str_has_prefix (*input, nu) && space_or_nul ((*input)[strlen (nu)])) {
-                        *input += strlen (nu);
-                        return units[i].unit;
-                }
-        }
-
-        g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
-                     _("I don’t know this unit: %s"), *input);
-
-        return GR_UNIT_UNKNOWN;
-}
+ #include "config.h"
+ 
+ #include <glib/gi18n.h>
+ #include <gio/gio.h>
+ 
+ #include "gr-unit.h"
+ #include "gr-utils.h"
+ 
+ static const char * const unit_names[] = {
+         "g", "kg", "lb", "oz", "l", "dl", "ml", "fl oz", "pt", "qt", "gal", "cup",
+         "tbsp", "tsp", "box", "pkg", "glass", "st", "pinch", "bunch",
+         NULL
+ };
+ 
+ typedef struct {
+         GrUnit unit;
+         GrDimension dimension;
+         const char *name;
+         const char *abbreviation;
+         const char *display_name;
+         const char *plural;
+ } GrUnitData;
+ 
+ static GrUnitData units[] = {
+         { GR_UNIT_UNKNOWN,     GR_DIMENSION_DISCRETE, "",        NC_("unit abbreviation", ""),      
NC_("unit name", ""),      NC_("unit plural", "") },
+         { GR_UNIT_GRAM,        GR_DIMENSION_MASS,     "g",       NC_("unit abbreviation", "g"),     
NC_("unit name", "gram"), NC_("unit plural", "grams") },
+         { GR_UNIT_KILOGRAM,    GR_DIMENSION_MASS,     "kg",      NC_("unit abbreviation", "kg"),    
NC_("unit name", "kilogram"), NC_("unit plural", "kilograms") },
+         { GR_UNIT_POUND,       GR_DIMENSION_MASS,     "lb",      NC_("unit abbreviation", "lb"),    
NC_("unit name", "pound"), NC_("unit plural", "pounds") },
+         { GR_UNIT_OUNCE,       GR_DIMENSION_VOLUME,   "oz",      NC_("unit abbreviation", "oz"),    
NC_("unit name", "ounce"), NC_("unit plural", "ounces") },
+         { GR_UNIT_LITER,       GR_DIMENSION_VOLUME,   "l",       NC_("unit abbreviation", "l"),     
NC_("unit name", "liter"), NC_("unit plural", "liters") },
+         { GR_UNIT_DECILITER,   GR_DIMENSION_VOLUME,   "dl",      NC_("unit abbreviation", "dl"),    
NC_("unit name", "deciliter"), NC_("unit plural", "deciliters") },
+         { GR_UNIT_MILLILITER,  GR_DIMENSION_VOLUME,   "ml",      NC_("unit abbreviation", "ml"),    
NC_("unit name", "milliliter"), NC_("unit plural", "milliliters") },
+         { GR_UNIT_FLUID_OUNCE, GR_DIMENSION_VOLUME,   "fl oz",   NC_("unit abbreviation", "fl oz"), 
NC_("unit name", "fluid ounce"), NC_("unit plural", "fluid ounces") },
+         { GR_UNIT_FLUID_OUNCE, GR_DIMENSION_VOLUME,   "fl. oz.", NC_("unit abbreviation", "fl oz"), 
NC_("unit name", "fluid ounce"), NC_("unit plural", "fluid ounces") },
+         { GR_UNIT_PINT,        GR_DIMENSION_VOLUME,   "pt",      NC_("unit abbreviation", "pt"),    
NC_("unit name", "pint"), NC_("unit plural", "pints") },
+         { GR_UNIT_QUART,       GR_DIMENSION_VOLUME,   "qt",      NC_("unit abbreviation", "qt"),    
NC_("unit name", "quart"), NC_("unit plural", "quarts") },
+         { GR_UNIT_GALLON,      GR_DIMENSION_VOLUME,   "gal",     NC_("unit abbreviation", "gal"),   
NC_("unit name", "gallon"), NC_("unit plural", "gallons") },
+         { GR_UNIT_CUP,         GR_DIMENSION_VOLUME,   "cup",     NC_("unit abbreviation", "cup"),   
NC_("unit name", "cup"), NC_("unit plural", "cups") },
+         { GR_UNIT_TABLESPOON,  GR_DIMENSION_VOLUME,   "tbsp",    NC_("unit abbreviation", "tbsp"),  
NC_("unit name", "tablespoon"), NC_("unit plural", "tablespoons") },
+         { GR_UNIT_TEASPOON,    GR_DIMENSION_VOLUME,   "tsp",     NC_("unit abbreviation", "tsp"),   
NC_("unit name", "teaspoon"), NC_("unit plural", "teaspoons") },
+         { GR_UNIT_BOX,         GR_DIMENSION_DISCRETE, "box",     NC_("unit abbreviation", "box"),   
NC_("unit name", "box"), NC_("unit plural", "boxes") },
+         { GR_UNIT_PACKAGE,     GR_DIMENSION_DISCRETE, "pkg",     NC_("unit abbreviation", "pkg"),   
NC_("unit name", "package"), NC_("unit plural", "packages") },
+         { GR_UNIT_GLASS,       GR_DIMENSION_DISCRETE, "glass",   NC_("unit abbreviation", "glass"), 
NC_("unit name", "glass"), NC_("unit plural", "glasses") },
+         { GR_UNIT_MILLIMETER,  GR_DIMENSION_LENGTH,   "mm",      NC_("unit abbreviation", "mm"),    
NC_("unit name", "millimeter"), NC_("unit plural", "millimeters") },
+         { GR_UNIT_CENTIMETER,  GR_DIMENSION_LENGTH,   "cm",      NC_("unit abbreviation", "cm"),    
NC_("unit name", "centimeter"), NC_("unit plural", "centimeters") },
+         { GR_UNIT_METER,       GR_DIMENSION_LENGTH,   "m",       NC_("unit abbreviation", "m"),     
NC_("unit name", "meter"), NC_("unit plural", "meters") },
+         { GR_UNIT_STONE,       GR_DIMENSION_MASS,     "st",      NC_("unit abbreviation", "st"),     
NC_("unit name", "stone"), NC_("unit plural", "stone") },
+         { GR_UNIT_PINCH,       GR_DIMENSION_DISCRETE, "pinch",   NC_("unit abbreviation", "pinch"),     
NC_("unit name", "pinch"), NC_("unit plural", "pinches") },
+         { GR_UNIT_BUNCH,       GR_DIMENSION_DISCRETE, "bunch",   NC_("unit abbreviation", "bunch"), 
NC_("unit name", "bunch"), NC_("unit plural", "bunches") },
+ };
+ 
+ const char **
+ gr_unit_get_names (void)
+ {
+         return (const char **)unit_names;
+ }
+ 
+ static GrUnitData *
+ find_unit (GrUnit unit)
+ {
+         int i;
+         for (i = 0; i < G_N_ELEMENTS (units); i++) {
+                 if (units[i].unit == unit)
+                         return &(units[i]);
+         }
+         return NULL;
+ }
+ 
+ const char *
+ gr_unit_get_name (GrUnit unit)
+ {
+         GrUnitData *data = find_unit (unit);
+         if (data)
+                 return data->name;
+         return NULL;
+ }
+ 
+ const char *
+ gr_unit_get_display_name (GrUnit unit)
+ {
+         GrUnitData *data = find_unit (unit);
+         if (data)
+                 return g_dpgettext2 (NULL, "unit name", data->display_name);
+         return gr_unit_get_name (unit);
+ }
+ 
+ const char *
+ gr_unit_get_plural (GrUnit unit)
+ {
+         GrUnitData *data = find_unit (unit);
+         if (data)
+                 return g_dpgettext2 (NULL, "unit plural", data->plural);
+         return gr_unit_get_display_name (unit);
+ 
+ }
+ 
+ const char *
+ gr_unit_get_abbreviation (GrUnit unit)
+ {
+         GrUnitData *data = find_unit (unit);
+         if (data)
+                 return g_dpgettext2 (NULL, "unit abbreviation", data->abbreviation);
+         return gr_unit_get_display_name (unit);
+ }
+ 
+ GrDimension
+ gr_unit_get_dimension (GrUnit unit)
+ {
+         GrUnitData *data = find_unit (unit);
+         if (data)
+                 return data->dimension;
+         return GR_DIMENSION_DISCRETE;
+ }
+ 
+ GrUnit
+ gr_unit_parse (char   **input,
+                GError **error)
+ {
+         int i;
+         const char *nu;
+ 
+         for (i = 0; i < G_N_ELEMENTS (units); i++) {
+                 nu = g_dpgettext2 (NULL, "unit name", units[i].display_name);
+                 if (g_str_has_prefix (*input, nu) && space_or_nul ((*input)[strlen (nu)])) {
+                         *input += strlen (nu);
+                         return units[i].unit;
+                 }
+         }
+ 
+         for (i = 0; i < G_N_ELEMENTS (units); i++) {
+                 nu = g_dpgettext2 (NULL, "unit abbreviation", units[i].abbreviation);
+                 if (g_str_has_prefix (*input, nu) && space_or_nul ((*input)[strlen (nu)])) {
+                         *input += strlen (nu);
+                         return units[i].unit;
+                 }
+         }
+ 
+         for (i = 0; i < G_N_ELEMENTS (units); i++) {
+                 nu = units[i].name;
+                 if (g_str_has_prefix (*input, nu) && space_or_nul ((*input)[strlen (nu)])) {
+                         *input += strlen (nu);
+                         return units[i].unit;
+                 }
+         }
+ 
+         g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
+                      _("I don’t know this unit: %s"), *input);
+ 
+         return GR_UNIT_UNKNOWN;
+ }
+ 
\ No newline at end of file
diff --git a/src/gr-unit.h b/src/gr-unit.h
index 57a1395..c75a957 100644
--- a/src/gr-unit.h
+++ b/src/gr-unit.h
@@ -16,55 +16,56 @@
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-#pragma once
-
-#include <glib.h>
-
-G_BEGIN_DECLS
-
-typedef enum {
-        GR_UNIT_UNKNOWN,
-        GR_UNIT_GRAM,
-        GR_UNIT_KILOGRAM,
-        GR_UNIT_POUND,
-        GR_UNIT_OUNCE,
-        GR_UNIT_LITER,
-        GR_UNIT_DECILITER,
-        GR_UNIT_MILLILITER,
-        GR_UNIT_FLUID_OUNCE,
-        GR_UNIT_PINT,
-        GR_UNIT_QUART,
-        GR_UNIT_GALLON,
-        GR_UNIT_CUP,
-        GR_UNIT_TABLESPOON,
-        GR_UNIT_TEASPOON,
-        GR_UNIT_BOX,
-        GR_UNIT_PACKAGE,
-        GR_UNIT_GLASS,
-        GR_UNIT_MILLIMETER,
-        GR_UNIT_CENTIMETER,
-        GR_UNIT_METER,
-        GR_UNIT_STONE,
-        GR_UNIT_PINCH,
-        GR_UNIT_BUNCH,
-        GR_LAST_UNIT = GR_UNIT_BUNCH
-} GrUnit;
-
-typedef enum {
-        GR_DIMENSION_DISCRETE,
-        GR_DIMENSION_VOLUME,
-        GR_DIMENSION_MASS,
-        GR_DIMENSION_LENGTH
-} GrDimension;
-
-GrUnit       gr_unit_parse (char   **string,
-                            GError **error);
-
-const char **gr_unit_get_names (void);
-const char  *gr_unit_get_name (GrUnit unit);
-const char  *gr_unit_get_abbreviation (GrUnit unit);
-const char  *gr_unit_get_display_name (GrUnit unit);
-const char  *gr_unit_get_plural (GrUnit unit);
-GrDimension  gr_unit_get_dimension (GrUnit unit);
-
-G_END_DECLS
+ #pragma once
+ 
+ #include <glib.h>
+ 
+ G_BEGIN_DECLS
+ 
+ typedef enum {
+         GR_UNIT_UNKNOWN,
+         GR_UNIT_GRAM,
+         GR_UNIT_KILOGRAM,
+         GR_UNIT_POUND,
+         GR_UNIT_OUNCE,
+         GR_UNIT_LITER,
+         GR_UNIT_DECILITER,
+         GR_UNIT_MILLILITER,
+         GR_UNIT_FLUID_OUNCE,
+         GR_UNIT_PINT,
+         GR_UNIT_QUART,
+         GR_UNIT_GALLON,
+         GR_UNIT_CUP,
+         GR_UNIT_TABLESPOON,
+         GR_UNIT_TEASPOON,
+         GR_UNIT_BOX,
+         GR_UNIT_PACKAGE,
+         GR_UNIT_GLASS,
+         GR_UNIT_MILLIMETER,
+         GR_UNIT_CENTIMETER,
+         GR_UNIT_METER,
+         GR_UNIT_STONE,
+         GR_UNIT_PINCH,
+         GR_UNIT_BUNCH,
+         GR_LAST_UNIT = GR_UNIT_BUNCH
+ } GrUnit;
+ 
+ typedef enum {
+         GR_DIMENSION_DISCRETE,
+         GR_DIMENSION_VOLUME,
+         GR_DIMENSION_MASS,
+         GR_DIMENSION_LENGTH
+ } GrDimension;
+ 
+ GrUnit       gr_unit_parse (char   **string,
+                             GError **error);
+ 
+ const char **gr_unit_get_names (void);
+ const char  *gr_unit_get_name (GrUnit unit);
+ const char  *gr_unit_get_abbreviation (GrUnit unit);
+ const char  *gr_unit_get_display_name (GrUnit unit);
+ const char  *gr_unit_get_plural (GrUnit unit);
+ GrDimension  gr_unit_get_dimension (GrUnit unit);
+ 
+ G_END_DECLS
+ 
\ No newline at end of file


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