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



commit 1fc2de9477fea4f75deba32dafecdfadcb552bf5
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      |  105 +++++++++++++++
 src/gr-convert-units.h      |    4 +-
 src/gr-ingredients-viewer.c |   34 +----
 src/gr-recipe-printer.c     |   12 +-
 src/gr-shopping-page.c      |   41 +++++--
 src/gr-unit.c               |  300 ++++++++++++++++++++++---------------------
 src/gr-unit.h               |  105 ++++++++--------
 7 files changed, 356 insertions(+), 245 deletions(-)
---
diff --git a/src/gr-convert-units.c b/src/gr-convert-units.c
index d3ea057..5b10eb6 100644
--- a/src/gr-convert-units.c
+++ b/src/gr-convert-units.c
@@ -419,3 +419,108 @@ gr_convert_human_readable (double *amount, GrUnit *unit)
                 *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;
+                        }
+                        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) {
+                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_abbreviation (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_abbreviation (u1));
+                g_string_append (s, ", ");
+                g_string_append (s, num2);
+                g_string_append (s, " ");
+                g_string_append (s, gr_unit_get_abbreviation (u2));
+        }
+}
+
+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 == 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 f5553d7..88f4913 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
diff --git a/src/gr-ingredients-viewer.c b/src/gr-ingredients-viewer.c
index 68d0f1e..04099fe 100644
--- a/src/gr-ingredients-viewer.c
+++ b/src/gr-ingredients-viewer.c
@@ -321,46 +321,22 @@ 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, viewer->title, ings[i]);
                 amount = gr_ingredients_list_get_amount (ingredients, viewer->title, ings[i]) * scale;
-                dimension = gr_unit_get_dimension (unit);
-
-                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", s->str,
                                     "ingredient", ings[i],
                                     "size-group", viewer->group,
                                     "editable", viewer->editable,
                                     NULL);
+
                 g_signal_connect (row, "delete", G_CALLBACK (delete_row), viewer);
                 g_signal_connect (row, "move", G_CALLBACK (move_row), viewer);
                 g_signal_connect (row, "edit", G_CALLBACK (edit_ingredient_row), viewer);
diff --git a/src/gr-recipe-printer.c b/src/gr-recipe-printer.c
index 7f9b92b..624509b 100644
--- a/src/gr-recipe-printer.c
+++ b/src/gr-recipe-printer.c
@@ -32,6 +32,7 @@
 #include "gr-meal.h"
 #include "gr-season.h"
 #include "gr-utils.h"
+#include "gr-convert-units.h"
 
 
 struct _GrRecipePrinter
@@ -196,13 +197,16 @@ begin_print (GtkPrintOperation *operation,
         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;
+                        double amount;
+                        GrUnit unit;
+                        double scale = 1.0;
 
-                        unit = gr_ingredients_list_scale_unit (ingredients, segs[j], ings[i], 1.0);
-                        g_string_append (s, unit);
-                        g_string_append (s, " \n");
+                        unit = gr_ingredients_list_get_unit (ingredients, segs[j], ings[i]);
+                        amount = gr_ingredients_list_get_amount (ingredients, segs[j], 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 b64f58a..0d05ede 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);
 }
 
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]