2 * Copyright (C) 1987-2008 Sun Microsystems, Inc. All Rights Reserved.
3 * Copyright (C) 2008-2011 Robert Ancell.
5 * This program is free software: you can redistribute it and/or modify it under
6 * the terms of the GNU General Public License as published by the Free Software
7 * Foundation, either version 2 of the License, or (at your option) any later
8 * version. See http://www.gnu.org/copyleft/gpl.html the full text of the
13 #include <glib/gi18n.h> // FIXME: Move out of here
15 #include "unit-manager.h"
16 #include "currency-manager.h" // FIXME: Move out of here
18 struct UnitManagerPrivate
23 G_DEFINE_TYPE (UnitManager
, unit_manager
, G_TYPE_OBJECT
);
26 static UnitManager
*default_unit_manager
= NULL
;
30 compare_currencies(gconstpointer a
, gconstpointer b
)
32 return strcmp(currency_get_display_name((Currency
*)a
), currency_get_display_name((Currency
*)b
));
37 unit_manager_get_default(void)
39 UnitCategory
*category
= NULL
;
40 GList
*currencies
, *iter
;
53 /* FIXME: Approximations of 1/(units in a circle), therefore, 360 deg != 400 grads */
54 {"angle", "degree", N_("Degrees"), NC_("unit-format", "%s degrees"), "π*x/180", "180x/π", NC_("unit-symbols", "degree,degrees,deg")},
55 {NULL
, "radian", N_("Radians"), NC_("unit-format", "%s radians"), "x", "x", NC_("unit-symbols", "radian,radians,rad")},
56 {NULL
, "gradian", N_("Gradians"), NC_("unit-format", "%s gradians"), "π*x/200", "200x/π", NC_("unit-symbols", "gradian,gradians,grad")},
57 {"length", "parsec", N_("Parsecs"), NC_("unit-format", "%s pc"), "30857000000000000x", "x/30857000000000000", NC_("unit-symbols", "parsec,parsecs,pc")},
58 {NULL
, "lightyear", N_("Light Years"), NC_("unit-format", "%s ly"), "9460730472580800x", "x/9460730472580800", NC_("unit-symbols", "lightyear,lightyears,ly")},
59 {NULL
, "astronomical-unit", N_("Astronomical Units"), NC_("unit-format", "%s au"), "149597870691x", "x/149597870691", NC_("unit-symbols", "au")},
60 {NULL
, "nautical-mile", N_("Nautical Miles"), NC_("unit-format", "%s nmi"), "1852x", "x/1852", NC_("unit-symbols", "nmi")},
61 {NULL
, "mile", N_("Miles"), NC_("unit-format", "%s mi"), "1609.344x", "x/1609.344", NC_("unit-symbols", "mile,miles,mi")},
62 {NULL
, "kilometer", N_("Kilometers"), NC_("unit-format", "%s km"), "1000x", "x/1000", NC_("unit-symbols", "kilometer,kilometers,km,kms")},
63 {NULL
, "cable", N_("Cables"), NC_("unit-format", "%s cb"), "219.456x", "x/219.456", NC_("unit-symbols", "cable,cables,cb")},
64 {NULL
, "fathom", N_("Fathoms"), NC_("unit-format", "%s ftm"), "1.8288x", "x/1.8288", NC_("unit-symbols", "fathom,fathoms,ftm")},
65 {NULL
, "meter", N_("Meters"), NC_("unit-format", "%s m"), "x", "x", NC_("unit-symbols", "meter,meters,m")},
66 {NULL
, "yard", N_("Yards"), NC_("unit-format", "%s yd"), "0.9144x", "x/0.9144", NC_("unit-symbols", "yard,yards,yd")},
67 {NULL
, "foot", N_("Feet"), NC_("unit-format", "%s ft"), "0.3048x", "x/0.3048", NC_("unit-symbols", "foot,feet,ft")},
68 {NULL
, "inch", N_("Inches"), NC_("unit-format", "%s in"), "0.0254x", "x/0.0254", NC_("unit-symbols", "inch,inches,in")},
69 {NULL
, "centimeter", N_("Centimeters"), NC_("unit-format", "%s cm"), "x/100", "100x", NC_("unit-symbols", "centimeter,centimeters,cm,cms")},
70 {NULL
, "millimeter", N_("Millimeters"), NC_("unit-format", "%s mm"), "x/1000", "1000x", NC_("unit-symbols", "millimeter,millimeters,mm")},
71 {NULL
, "micrometer", N_("Micrometers"), NC_("unit-format", "%s μm"), "x/1000000", "1000000x", NC_("unit-symbols", "micrometer,micrometers,um")},
72 {NULL
, "nanometer", N_("Nanometers"), NC_("unit-format", "%s nm"), "x/1000000000", "1000000000x", NC_("unit-symbols", "nanometer,nanometers,nm")},
73 {"area", "hectare", N_("Hectares"), NC_("unit-format", "%s ha"), "10000x", "x/10000", NC_("unit-symbols", "hectare,hectares,ha")},
74 {NULL
, "acre", N_("Acres"), NC_("unit-format", "%s acres"), "4046.8564224x", "x/4046.8564224", NC_("unit-symbols", "acre,acres")},
75 {NULL
, "square-meter", N_("Square Meters"), NC_("unit-format", "%s m²"), "x", "x", NC_("unit-symbols", "m²")},
76 {NULL
, "square-centimeter", N_("Square Centimeters"), NC_("unit-format", "%s cm²"), "0.0001x", "10000x", NC_("unit-symbols", "cm²")},
77 {NULL
, "square-millimeter", N_("Square Millimeters"), NC_("unit-format", "%s mm²"), "0.000001x", "1000000x", NC_("unit-symbols", "mm²")},
78 {"volume", "cubic-meter", N_("Cubic Meters"), NC_("unit-format", "%s m³"), "1000x", "x/1000", NC_("unit-symbols", "m³")},
79 {NULL
, "gallon", N_("Gallons"), NC_("unit-format", "%s gal"), "3.785412x", "x/3.785412", NC_("unit-symbols", "gallon,gallons,gal")},
80 {NULL
, "litre", N_("Litres"), NC_("unit-format", "%s L"), "x", "x", NC_("unit-symbols", "litre,litres,liter,liters,L")},
81 {NULL
, "quart", N_("Quarts"), NC_("unit-format", "%s qt"), "0.9463529x", "x/0.9463529", NC_("unit-symbols", "quart,quarts,qt")},
82 {NULL
, "pint", N_("Pints"), NC_("unit-format", "%s pt"), "0.4731765x", "x/0.4731765", NC_("unit-symbols", "pint,pints,pt")},
83 {NULL
, "millilitre", N_("Millilitres"), NC_("unit-format", "%s mL"), "0.001x", "1000x", NC_("unit-symbols", "millilitre,millilitres,milliliter,milliliters,mL,cm³")},
84 {NULL
, "microlitre", N_("Microlitres"), NC_("unit-format", "%s μL"), "0.000001x", "1000000x", NC_("unit-symbols", "mm³,μL,uL")},
85 {"weight", "tonne", N_("Tonnes"), NC_("unit-format", "%s T"), "1000x", "x/1000", NC_("unit-symbols", "tonne,tonnes")},
86 {NULL
, "kilograms", N_("Kilograms"), NC_("unit-format", "%s kg"), "x", "x", NC_("unit-symbols", "kilogram,kilograms,kilogramme,kilogrammes,kg,kgs")},
87 {NULL
, "pound", N_("Pounds"), NC_("unit-format", "%s lb"), "0.45359237x", "x/0.45359237", NC_("unit-symbols", "pound,pounds,lb")},
88 {NULL
, "ounce", N_("Ounces"), NC_("unit-format", "%s oz"), "0.02834952x", "x/0.02834952", NC_("unit-symbols", "ounce,ounces,oz")},
89 {NULL
, "gram", N_("Grams"), NC_("unit-format", "%s g"), "0.001x", "1000x", NC_("unit-symbols", "gram,grams,gramme,grammes,g")},
90 {"duration", "year", N_("Years"), NC_("unit-format", "%s years"), "31557600x", "x/31557600", NC_("unit-symbols", "year,years")},
91 {NULL
, "day", N_("Days"), NC_("unit-format", "%s days"), "86400x", "x/86400", NC_("unit-symbols", "day,days")},
92 {NULL
, "hour", N_("Hours"), NC_("unit-format", "%s hours"), "3600x", "x/3600", NC_("unit-symbols", "hour,hours")},
93 {NULL
, "minute", N_("Minutes"), NC_("unit-format", "%s minutes"), "60x", "x/60", NC_("unit-symbols", "minute,minutes")},
94 {NULL
, "second", N_("Seconds"), NC_("unit-format", "%s s"), "x", "x", NC_("unit-symbols", "second,seconds,s")},
95 {NULL
, "millisecond", N_("Milliseconds"), NC_("unit-format", "%s ms"), "0.001x", "1000x", NC_("unit-symbols", "millisecond,milliseconds,ms")},
96 {NULL
, "microsecond", N_("Microseconds"), NC_("unit-format", "%s μs"), "0.000001x", "1000000x", NC_("unit-symbols", "microsecond,microseconds,us,μs")},
97 {"temperature", "degree-celcius", N_("Celsius"), NC_("unit-format", "%s ˚C"), "x+273.15", "x-273.15", NC_("unit-symbols", "degC,˚C")},
98 {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")},
99 {NULL
, "degree-kelvin", N_("Kelvin"), NC_("unit-format", "%s K"), "x", "x", NC_("unit-symbols", "K")},
100 {NULL
, "degree-rankine", N_("Rankine"), NC_("unit-format", "%s ˚R"), "x*5/9", "x*9/5", NC_("unit-symbols", "degR,˚R,˚Ra")},
101 { NULL
, NULL
, NULL
, NULL
, NULL
, NULL
}
104 if (default_unit_manager
)
105 return default_unit_manager
;
107 default_unit_manager
= g_object_new(unit_manager_get_type(), NULL
);
109 unit_manager_add_category(default_unit_manager
, "angle", _("Angle"));
110 unit_manager_add_category(default_unit_manager
, "length", _("Length"));
111 unit_manager_add_category(default_unit_manager
, "area", _("Area"));
112 unit_manager_add_category(default_unit_manager
, "volume", _("Volume"));
113 unit_manager_add_category(default_unit_manager
, "weight", _("Weight"));
114 unit_manager_add_category(default_unit_manager
, "duration", _("Duration"));
115 unit_manager_add_category(default_unit_manager
, "temperature", _("Temperature"));
117 for (i
= 0; units
[i
].name
; i
++) {
118 if (units
[i
].category
)
119 category
= unit_manager_get_category(default_unit_manager
, units
[i
].category
);
120 unit_category_add_unit(category
, unit_new(units
[i
].name
,
121 _(units
[i
].display_name
),
122 g_dpgettext2(NULL
, "unit-format", units
[i
].format
),
123 units
[i
].from_function
, units
[i
].to_function
,
124 g_dpgettext2(NULL
, "unit-symbols", units
[i
].symbols
)));
127 category
= unit_manager_add_category(default_unit_manager
, "currency", _("Currency"));
128 currencies
= g_list_copy(currency_manager_get_currencies(currency_manager_get_default()));
129 currencies
= g_list_sort(currencies
, compare_currencies
);
130 for (iter
= currencies
; iter
; iter
= iter
->next
)
132 Currency
*currency
= iter
->data
;
136 /* Translators: result of currency conversion, %s is the symbol, %%s is the placeholder for amount, i.e.: USD100 */
137 format
= g_strdup_printf(_("%s%%s"), currency_get_symbol(currency
));
138 unit
= unit_new(currency_get_name(currency
), currency_get_display_name(currency
), format
, NULL
, NULL
, currency_get_name(currency
));
141 unit_category_add_unit(category
, unit
);
143 g_list_free(currencies
);
145 return default_unit_manager
;
150 unit_manager_add_category(UnitManager
*manager
, const gchar
*name
, const gchar
*display_name
)
152 UnitCategory
*category
;
154 g_return_val_if_fail(manager
!= NULL
, NULL
);
155 g_return_val_if_fail(name
!= NULL
, NULL
);
156 g_return_val_if_fail(display_name
!= NULL
, NULL
);
157 g_return_val_if_fail(unit_manager_get_category(manager
, name
) == NULL
, NULL
);
159 category
= unit_category_new(name
, display_name
);
160 manager
->priv
->categories
= g_list_append(manager
->priv
->categories
, category
);
167 unit_manager_get_categories(UnitManager
*manager
)
169 g_return_val_if_fail(manager
!= NULL
, NULL
);
170 return manager
->priv
->categories
;
175 unit_manager_get_category(UnitManager
*manager
, const gchar
*category
)
179 g_return_val_if_fail(manager
!= NULL
, NULL
);
180 g_return_val_if_fail(category
!= NULL
, NULL
);
182 for (iter
= manager
->priv
->categories
; iter
; iter
= iter
->next
) {
183 UnitCategory
*c
= iter
->data
;
184 if (strcmp(unit_category_get_name(c
), category
) == 0)
193 unit_manager_get_unit_by_name(UnitManager
*manager
, const gchar
*name
)
198 g_return_val_if_fail(manager
!= NULL
, NULL
);
199 g_return_val_if_fail(name
!= NULL
, NULL
);
201 for (iter
= manager
->priv
->categories
; iter
; iter
= iter
->next
) {
202 UnitCategory
*c
= iter
->data
;
203 u
= unit_category_get_unit_by_name(c
, name
);
213 unit_manager_get_unit_by_symbol(UnitManager
*manager
, const gchar
*symbol
)
218 g_return_val_if_fail(manager
!= NULL
, NULL
);
219 g_return_val_if_fail(symbol
!= NULL
, NULL
);
221 for (iter
= manager
->priv
->categories
; iter
; iter
= iter
->next
) {
222 UnitCategory
*c
= iter
->data
;
223 u
= unit_category_get_unit_by_symbol(c
, symbol
);
233 unit_manager_convert_by_symbol(UnitManager
*manager
, const MPNumber
*x
, const char *x_symbol
, const char *z_symbol
, MPNumber
*z
)
237 g_return_val_if_fail(manager
!= NULL
, FALSE
);
238 g_return_val_if_fail(x
!= NULL
, FALSE
);
239 g_return_val_if_fail(x_symbol
!= NULL
, FALSE
);
240 g_return_val_if_fail(z_symbol
!= NULL
, FALSE
);
241 g_return_val_if_fail(z
!= NULL
, FALSE
);
243 for (iter
= manager
->priv
->categories
; iter
; iter
= iter
->next
) {
244 UnitCategory
*c
= iter
->data
;
245 Unit
*x_units
, *z_units
;
247 x_units
= unit_category_get_unit_by_symbol(c
, x_symbol
);
248 z_units
= unit_category_get_unit_by_symbol(c
, z_symbol
);
249 if (x_units
&& z_units
&& unit_category_convert(c
, x
, x_units
, z_units
, z
))
258 unit_manager_class_init(UnitManagerClass
*klass
)
260 g_type_class_add_private(klass
, sizeof(UnitManagerPrivate
));
265 unit_manager_init(UnitManager
*manager
)
267 manager
->priv
= G_TYPE_INSTANCE_GET_PRIVATE(manager
, unit_manager_get_type(), UnitManagerPrivate
);