diff options
Diffstat (limited to 'src/unit-manager.c')
-rw-r--r-- | src/unit-manager.c | 268 |
1 files changed, 268 insertions, 0 deletions
diff --git a/src/unit-manager.c b/src/unit-manager.c new file mode 100644 index 0000000..9943a31 --- /dev/null +++ b/src/unit-manager.c @@ -0,0 +1,268 @@ +/* + * Copyright (C) 1987-2008 Sun Microsystems, Inc. All Rights Reserved. + * Copyright (C) 2008-2011 Robert Ancell. + * + * This program is free software: you can redistribute it and/or modify it under + * the terms of the GNU General Public License as published by the Free Software + * Foundation, either version 2 of the License, or (at your option) any later + * version. See http://www.gnu.org/copyleft/gpl.html the full text of the + * license. + */ + +#include <string.h> +#include <glib/gi18n.h> // FIXME: Move out of here + +#include "unit-manager.h" +#include "currency-manager.h" // FIXME: Move out of here + +struct UnitManagerPrivate +{ + GList *categories; +}; + +G_DEFINE_TYPE (UnitManager, unit_manager, G_TYPE_OBJECT); + + +static UnitManager *default_unit_manager = NULL; + + +static gint +compare_currencies(gconstpointer a, gconstpointer b) +{ + return strcmp(currency_get_display_name((Currency *)a), currency_get_display_name((Currency *)b)); +} + + +UnitManager * +unit_manager_get_default(void) +{ + UnitCategory *category = NULL; + GList *currencies, *iter; + int i; + const struct + { + gchar *category; + gchar *name; + gchar *display_name; + gchar *format; + gchar *from_function; + gchar *to_function; + gchar *symbols; + } units[] = + { + /* FIXME: Approximations of 1/(units in a circle), therefore, 360 deg != 400 grads */ + {"angle", "degree", N_("Degrees"), NC_("unit-format", "%s degrees"), "π*x/180", "180x/π", NC_("unit-symbols", "degree,degrees,deg")}, + {NULL, "radian", N_("Radians"), NC_("unit-format", "%s radians"), "x", "x", NC_("unit-symbols", "radian,radians,rad")}, + {NULL, "gradian", N_("Gradians"), NC_("unit-format", "%s gradians"), "π*x/200", "200x/π", NC_("unit-symbols", "gradian,gradians,grad")}, + {"length", "parsec", N_("Parsecs"), NC_("unit-format", "%s pc"), "30857000000000000x", "x/30857000000000000", NC_("unit-symbols", "parsec,parsecs,pc")}, + {NULL, "lightyear", N_("Light Years"), NC_("unit-format", "%s ly"), "9460730472580800x", "x/9460730472580800", NC_("unit-symbols", "lightyear,lightyears,ly")}, + {NULL, "astronomical-unit", N_("Astronomical Units"), NC_("unit-format", "%s au"), "149597870691x", "x/149597870691", NC_("unit-symbols", "au")}, + {NULL, "nautical-mile", N_("Nautical Miles"), NC_("unit-format", "%s nmi"), "1852x", "x/1852", NC_("unit-symbols", "nmi")}, + {NULL, "mile", N_("Miles"), NC_("unit-format", "%s mi"), "1609.344x", "x/1609.344", NC_("unit-symbols", "mile,miles,mi")}, + {NULL, "kilometer", N_("Kilometers"), NC_("unit-format", "%s km"), "1000x", "x/1000", NC_("unit-symbols", "kilometer,kilometers,km,kms")}, + {NULL, "cable", N_("Cables"), NC_("unit-format", "%s cb"), "219.456x", "x/219.456", NC_("unit-symbols", "cable,cables,cb")}, + {NULL, "fathom", N_("Fathoms"), NC_("unit-format", "%s ftm"), "1.8288x", "x/1.8288", NC_("unit-symbols", "fathom,fathoms,ftm")}, + {NULL, "meter", N_("Meters"), NC_("unit-format", "%s m"), "x", "x", NC_("unit-symbols", "meter,meters,m")}, + {NULL, "yard", N_("Yards"), NC_("unit-format", "%s yd"), "0.9144x", "x/0.9144", NC_("unit-symbols", "yard,yards,yd")}, + {NULL, "foot", N_("Feet"), NC_("unit-format", "%s ft"), "0.3048x", "x/0.3048", NC_("unit-symbols", "foot,feet,ft")}, + {NULL, "inch", N_("Inches"), NC_("unit-format", "%s in"), "0.0254x", "x/0.0254", NC_("unit-symbols", "inch,inches,in")}, + {NULL, "centimeter", N_("Centimeters"), NC_("unit-format", "%s cm"), "x/100", "100x", NC_("unit-symbols", "centimeter,centimeters,cm,cms")}, + {NULL, "millimeter", N_("Millimeters"), NC_("unit-format", "%s mm"), "x/1000", "1000x", NC_("unit-symbols", "millimeter,millimeters,mm")}, + {NULL, "micrometer", N_("Micrometers"), NC_("unit-format", "%s μm"), "x/1000000", "1000000x", NC_("unit-symbols", "micrometer,micrometers,um")}, + {NULL, "nanometer", N_("Nanometers"), NC_("unit-format", "%s nm"), "x/1000000000", "1000000000x", NC_("unit-symbols", "nanometer,nanometers,nm")}, + {"area", "hectare", N_("Hectares"), NC_("unit-format", "%s ha"), "10000x", "x/10000", NC_("unit-symbols", "hectare,hectares,ha")}, + {NULL, "acre", N_("Acres"), NC_("unit-format", "%s acres"), "4046.8564224x", "x/4046.8564224", NC_("unit-symbols", "acre,acres")}, + {NULL, "square-meter", N_("Square Meters"), NC_("unit-format", "%s m²"), "x", "x", NC_("unit-symbols", "m²")}, + {NULL, "square-centimeter", N_("Square Centimeters"), NC_("unit-format", "%s cm²"), "0.0001x", "10000x", NC_("unit-symbols", "cm²")}, + {NULL, "square-millimeter", N_("Square Millimeters"), NC_("unit-format", "%s mm²"), "0.000001x", "1000000x", NC_("unit-symbols", "mm²")}, + {"volume", "cubic-meter", N_("Cubic Meters"), NC_("unit-format", "%s m³"), "1000x", "x/1000", NC_("unit-symbols", "m³")}, + {NULL, "gallon", N_("Gallons"), NC_("unit-format", "%s gal"), "3.785412x", "x/3.785412", NC_("unit-symbols", "gallon,gallons,gal")}, + {NULL, "litre", N_("Litres"), NC_("unit-format", "%s L"), "x", "x", NC_("unit-symbols", "litre,litres,liter,liters,L")}, + {NULL, "quart", N_("Quarts"), NC_("unit-format", "%s qt"), "0.9463529x", "x/0.9463529", NC_("unit-symbols", "quart,quarts,qt")}, + {NULL, "pint", N_("Pints"), NC_("unit-format", "%s pt"), "0.4731765x", "x/0.4731765", NC_("unit-symbols", "pint,pints,pt")}, + {NULL, "millilitre", N_("Millilitres"), NC_("unit-format", "%s mL"), "0.001x", "1000x", NC_("unit-symbols", "millilitre,millilitres,milliliter,milliliters,mL,cm³")}, + {NULL, "microlitre", N_("Microlitres"), NC_("unit-format", "%s μL"), "0.000001x", "1000000x", NC_("unit-symbols", "mm³,μL,uL")}, + {"weight", "tonne", N_("Tonnes"), NC_("unit-format", "%s T"), "1000x", "x/1000", NC_("unit-symbols", "tonne,tonnes")}, + {NULL, "kilograms", N_("Kilograms"), NC_("unit-format", "%s kg"), "x", "x", NC_("unit-symbols", "kilogram,kilograms,kilogramme,kilogrammes,kg,kgs")}, + {NULL, "pound", N_("Pounds"), NC_("unit-format", "%s lb"), "0.45359237x", "x/0.45359237", NC_("unit-symbols", "pound,pounds,lb")}, + {NULL, "ounce", N_("Ounces"), NC_("unit-format", "%s oz"), "0.02834952x", "x/0.02834952", NC_("unit-symbols", "ounce,ounces,oz")}, + {NULL, "gram", N_("Grams"), NC_("unit-format", "%s g"), "0.001x", "1000x", NC_("unit-symbols", "gram,grams,gramme,grammes,g")}, + {"duration", "year", N_("Years"), NC_("unit-format", "%s years"), "31557600x", "x/31557600", NC_("unit-symbols", "year,years")}, + {NULL, "day", N_("Days"), NC_("unit-format", "%s days"), "86400x", "x/86400", NC_("unit-symbols", "day,days")}, + {NULL, "hour", N_("Hours"), NC_("unit-format", "%s hours"), "3600x", "x/3600", NC_("unit-symbols", "hour,hours")}, + {NULL, "minute", N_("Minutes"), NC_("unit-format", "%s minutes"), "60x", "x/60", NC_("unit-symbols", "minute,minutes")}, + {NULL, "second", N_("Seconds"), NC_("unit-format", "%s s"), "x", "x", NC_("unit-symbols", "second,seconds,s")}, + {NULL, "millisecond", N_("Milliseconds"), NC_("unit-format", "%s ms"), "0.001x", "1000x", NC_("unit-symbols", "millisecond,milliseconds,ms")}, + {NULL, "microsecond", N_("Microseconds"), NC_("unit-format", "%s μs"), "0.000001x", "1000000x", NC_("unit-symbols", "microsecond,microseconds,us,μs")}, + {"temperature", "degree-celcius", N_("Celsius"), NC_("unit-format", "%s ˚C"), "x+273.15", "x-273.15", NC_("unit-symbols", "degC,˚C")}, + {NULL, "degree-farenheit", N_("Farenheit"), NC_("unit-format", "%s ˚F"), "(x+459.67)*5/9", "x*9/5-459.67", NC_("unit-symbols", "degF,˚F")}, + {NULL, "degree-kelvin", N_("Kelvin"), NC_("unit-format", "%s K"), "x", "x", NC_("unit-symbols", "K")}, + {NULL, "degree-rankine", N_("Rankine"), NC_("unit-format", "%s ˚R"), "x*5/9", "x*9/5", NC_("unit-symbols", "degR,˚R,˚Ra")}, + { NULL, NULL, NULL, NULL, NULL, NULL } + }; + + if (default_unit_manager) + return default_unit_manager; + + default_unit_manager = g_object_new(unit_manager_get_type(), NULL); + + unit_manager_add_category(default_unit_manager, "angle", _("Angle")); + unit_manager_add_category(default_unit_manager, "length", _("Length")); + unit_manager_add_category(default_unit_manager, "area", _("Area")); + unit_manager_add_category(default_unit_manager, "volume", _("Volume")); + unit_manager_add_category(default_unit_manager, "weight", _("Weight")); + unit_manager_add_category(default_unit_manager, "duration", _("Duration")); + unit_manager_add_category(default_unit_manager, "temperature", _("Temperature")); + + for (i = 0; units[i].name; i++) { + if (units[i].category) + category = unit_manager_get_category(default_unit_manager, units[i].category); + unit_category_add_unit(category, unit_new(units[i].name, + _(units[i].display_name), + g_dpgettext2(NULL, "unit-format", units[i].format), + units[i].from_function, units[i].to_function, + g_dpgettext2(NULL, "unit-symbols", units[i].symbols))); + } + + category = unit_manager_add_category(default_unit_manager, "currency", _("Currency")); + currencies = g_list_copy(currency_manager_get_currencies(currency_manager_get_default())); + currencies = g_list_sort(currencies, compare_currencies); + for (iter = currencies; iter; iter = iter->next) + { + Currency *currency = iter->data; + gchar *format; + Unit *unit; + + /* Translators: result of currency conversion, %s is the symbol, %%s is the placeholder for amount, i.e.: USD100 */ + format = g_strdup_printf(_("%s%%s"), currency_get_symbol(currency)); + unit = unit_new(currency_get_name(currency), currency_get_display_name(currency), format, NULL, NULL, currency_get_name(currency)); + g_free(format); + + unit_category_add_unit(category, unit); + } + g_list_free(currencies); + + return default_unit_manager; +} + + +UnitCategory * +unit_manager_add_category(UnitManager *manager, const gchar *name, const gchar *display_name) +{ + UnitCategory *category; + + g_return_val_if_fail(manager != NULL, NULL); + g_return_val_if_fail(name != NULL, NULL); + g_return_val_if_fail(display_name != NULL, NULL); + g_return_val_if_fail(unit_manager_get_category(manager, name) == NULL, NULL); + + category = unit_category_new(name, display_name); + manager->priv->categories = g_list_append(manager->priv->categories, category); + + return category; +} + + +const GList * +unit_manager_get_categories(UnitManager *manager) +{ + g_return_val_if_fail(manager != NULL, NULL); + return manager->priv->categories; +} + + +UnitCategory * +unit_manager_get_category(UnitManager *manager, const gchar *category) +{ + GList *iter; + + g_return_val_if_fail(manager != NULL, NULL); + g_return_val_if_fail(category != NULL, NULL); + + for (iter = manager->priv->categories; iter; iter = iter->next) { + UnitCategory *c = iter->data; + if (strcmp(unit_category_get_name(c), category) == 0) + return c; + } + + return NULL; +} + + +Unit * +unit_manager_get_unit_by_name(UnitManager *manager, const gchar *name) +{ + GList *iter; + Unit *u; + + g_return_val_if_fail(manager != NULL, NULL); + g_return_val_if_fail(name != NULL, NULL); + + for (iter = manager->priv->categories; iter; iter = iter->next) { + UnitCategory *c = iter->data; + u = unit_category_get_unit_by_name(c, name); + if (u) + return u; + } + + return NULL; +} + + +Unit * +unit_manager_get_unit_by_symbol(UnitManager *manager, const gchar *symbol) +{ + GList *iter; + Unit *u; + + g_return_val_if_fail(manager != NULL, NULL); + g_return_val_if_fail(symbol != NULL, NULL); + + for (iter = manager->priv->categories; iter; iter = iter->next) { + UnitCategory *c = iter->data; + u = unit_category_get_unit_by_symbol(c, symbol); + if (u) + return u; + } + + return NULL; +} + + +gboolean +unit_manager_convert_by_symbol(UnitManager *manager, const MPNumber *x, const char *x_symbol, const char *z_symbol, MPNumber *z) +{ + GList *iter; + + g_return_val_if_fail(manager != NULL, FALSE); + g_return_val_if_fail(x != NULL, FALSE); + g_return_val_if_fail(x_symbol != NULL, FALSE); + g_return_val_if_fail(z_symbol != NULL, FALSE); + g_return_val_if_fail(z != NULL, FALSE); + + for (iter = manager->priv->categories; iter; iter = iter->next) { + UnitCategory *c = iter->data; + Unit *x_units, *z_units; + + x_units = unit_category_get_unit_by_symbol(c, x_symbol); + z_units = unit_category_get_unit_by_symbol(c, z_symbol); + if (x_units && z_units && unit_category_convert(c, x, x_units, z_units, z)) + return TRUE; + } + + return FALSE; +} + + +static void +unit_manager_class_init(UnitManagerClass *klass) +{ + g_type_class_add_private(klass, sizeof(UnitManagerPrivate)); +} + + +static void +unit_manager_init(UnitManager *manager) +{ + manager->priv = G_TYPE_INSTANCE_GET_PRIVATE(manager, unit_manager_get_type(), UnitManagerPrivate); +} |