2
* Copyright (C) 2008-2012 Robert Ancell.
4
* This program is free software: you can redistribute it and/or modify it under
5
* the terms of the GNU General Public License as published by the Free Software
6
* Foundation, either version 2 of the License, or (at your option) any later
7
* version. See http://www.gnu.org/copyleft/gpl.html the full text of the
11
private UnitManager? default_unit_manager = null;
13
public class UnitManager : Object
15
private List<UnitCategory> categories;
19
categories = new List<UnitCategory> ();
22
public static UnitManager get_default ()
24
if (default_unit_manager != null)
25
return default_unit_manager;
27
default_unit_manager = new UnitManager ();
29
var angle_category = default_unit_manager.add_category ("angle", _("Angle"));
30
var length_category = default_unit_manager.add_category ("length", _("Length"));
31
var area_category = default_unit_manager.add_category ("area", _("Area"));
32
var volume_category = default_unit_manager.add_category ("volume", _("Volume"));
33
var weight_category = default_unit_manager.add_category ("weight", _("Weight"));
34
var duration_category = default_unit_manager.add_category ("duration", _("Duration"));
35
var temperature_category = default_unit_manager.add_category ("temperature", _("Temperature"));
37
/* FIXME: Approximations of 1/(units in a circle), therefore, 360 deg != 400 grads */
38
angle_category.add_unit (new Unit ("degree", _("Degrees"), dpgettext2 (null, "unit-format", "%s degrees"), "π*x/180", "180x/π", dpgettext2 (null, "unit-symbols", "degree,degrees,deg")));
39
angle_category.add_unit (new Unit ("radian", _("Radians"), dpgettext2 (null, "unit-format", "%s radians"), "x", "x", dpgettext2 (null, "unit-symbols", "radian,radians,rad")));
40
angle_category.add_unit (new Unit ("gradian", _("Gradians"), dpgettext2 (null, "unit-format", "%s gradians"), "π*x/200", "200x/π", dpgettext2 (null, "unit-symbols", "gradian,gradians,grad")));
41
length_category.add_unit (new Unit ("parsec", _("Parsecs"), dpgettext2 (null, "unit-format", "%s pc"), "30857000000000000x", "x/30857000000000000", dpgettext2 (null, "unit-symbols", "parsec,parsecs,pc")));
42
length_category.add_unit (new Unit ("lightyear", _("Light Years"), dpgettext2 (null, "unit-format", "%s ly"), "9460730472580800x", "x/9460730472580800", dpgettext2 (null, "unit-symbols", "lightyear,lightyears,ly")));
43
length_category.add_unit (new Unit ("astronomical-unit", _("Astronomical Units"), dpgettext2 (null, "unit-format", "%s au"), "149597870691x", "x/149597870691", dpgettext2 (null, "unit-symbols", "au")));
44
length_category.add_unit (new Unit ("nautical-mile", _("Nautical Miles"), dpgettext2 (null, "unit-format", "%s nmi"), "1852x", "x/1852", dpgettext2 (null, "unit-symbols", "nmi")));
45
length_category.add_unit (new Unit ("mile", _("Miles"), dpgettext2 (null, "unit-format", "%s mi"), "1609.344x", "x/1609.344", dpgettext2 (null, "unit-symbols", "mile,miles,mi")));
46
length_category.add_unit (new Unit ("kilometer", _("Kilometers"), dpgettext2 (null, "unit-format", "%s km"), "1000x", "x/1000", dpgettext2 (null, "unit-symbols", "kilometer,kilometers,km,kms")));
47
length_category.add_unit (new Unit ("cable", _("Cables"), dpgettext2 (null, "unit-format", "%s cb"), "219.456x", "x/219.456", dpgettext2 (null, "unit-symbols", "cable,cables,cb")));
48
length_category.add_unit (new Unit ("fathom", _("Fathoms"), dpgettext2 (null, "unit-format", "%s ftm"), "1.8288x", "x/1.8288", dpgettext2 (null, "unit-symbols", "fathom,fathoms,ftm")));
49
length_category.add_unit (new Unit ("meter", _("Meters"), dpgettext2 (null, "unit-format", "%s m"), "x", "x", dpgettext2 (null, "unit-symbols", "meter,meters,m")));
50
length_category.add_unit (new Unit ("yard", _("Yards"), dpgettext2 (null, "unit-format", "%s yd"), "0.9144x", "x/0.9144", dpgettext2 (null, "unit-symbols", "yard,yards,yd")));
51
length_category.add_unit (new Unit ("foot", _("Feet"), dpgettext2 (null, "unit-format", "%s ft"), "0.3048x", "x/0.3048", dpgettext2 (null, "unit-symbols", "foot,feet,ft")));
52
length_category.add_unit (new Unit ("inch", _("Inches"), dpgettext2 (null, "unit-format", "%s in"), "0.0254x", "x/0.0254", dpgettext2 (null, "unit-symbols", "inch,inches,in")));
53
length_category.add_unit (new Unit ("centimeter", _("Centimeters"), dpgettext2 (null, "unit-format", "%s cm"), "x/100", "100x", dpgettext2 (null, "unit-symbols", "centimeter,centimeters,cm,cms")));
54
length_category.add_unit (new Unit ("millimeter", _("Millimeters"), dpgettext2 (null, "unit-format", "%s mm"), "x/1000", "1000x", dpgettext2 (null, "unit-symbols", "millimeter,millimeters,mm")));
55
length_category.add_unit (new Unit ("micrometer", _("Micrometers"), dpgettext2 (null, "unit-format", "%s μm"), "x/1000000", "1000000x", dpgettext2 (null, "unit-symbols", "micrometer,micrometers,um")));
56
length_category.add_unit (new Unit ("nanometer", _("Nanometers"), dpgettext2 (null, "unit-format", "%s nm"), "x/1000000000", "1000000000x", dpgettext2 (null, "unit-symbols", "nanometer,nanometers,nm")));
57
area_category.add_unit (new Unit ("hectare", _("Hectares"), dpgettext2 (null, "unit-format", "%s ha"), "10000x", "x/10000", dpgettext2 (null, "unit-symbols", "hectare,hectares,ha")));
58
area_category.add_unit (new Unit ("acre", _("Acres"), dpgettext2 (null, "unit-format", "%s acres"), "4046.8564224x", "x/4046.8564224", dpgettext2 (null, "unit-symbols", "acre,acres")));
59
area_category.add_unit (new Unit ("square-meter", _("Square Meters"), dpgettext2 (null, "unit-format", "%s m²"), "x", "x", dpgettext2 (null, "unit-symbols", "m²")));
60
area_category.add_unit (new Unit ("square-centimeter", _("Square Centimeters"), dpgettext2 (null, "unit-format", "%s cm²"), "0.0001x", "10000x", dpgettext2 (null, "unit-symbols", "cm²")));
61
area_category.add_unit (new Unit ("square-millimeter", _("Square Millimeters"), dpgettext2 (null, "unit-format", "%s mm²"), "0.000001x", "1000000x", dpgettext2 (null, "unit-symbols", "mm²")));
62
volume_category.add_unit (new Unit ("cubic-meter", _("Cubic Meters"), dpgettext2 (null, "unit-format", "%s m³"), "1000x", "x/1000", dpgettext2 (null, "unit-symbols", "m³")));
63
volume_category.add_unit (new Unit ("gallon", _("Gallons"), dpgettext2 (null, "unit-format", "%s gal"), "3.785412x", "x/3.785412", dpgettext2 (null, "unit-symbols", "gallon,gallons,gal")));
64
volume_category.add_unit (new Unit ("litre", _("Litres"), dpgettext2 (null, "unit-format", "%s L"), "x", "x", dpgettext2 (null, "unit-symbols", "litre,litres,liter,liters,L")));
65
volume_category.add_unit (new Unit ("quart", _("Quarts"), dpgettext2 (null, "unit-format", "%s qt"), "0.9463529x", "x/0.9463529", dpgettext2 (null, "unit-symbols", "quart,quarts,qt")));
66
volume_category.add_unit (new Unit ("pint", _("Pints"), dpgettext2 (null, "unit-format", "%s pt"), "0.4731765x", "x/0.4731765", dpgettext2 (null, "unit-symbols", "pint,pints,pt")));
67
volume_category.add_unit (new Unit ("millilitre", _("Millilitres"), dpgettext2 (null, "unit-format", "%s mL"), "0.001x", "1000x", dpgettext2 (null, "unit-symbols", "millilitre,millilitres,milliliter,milliliters,mL,cm³")));
68
volume_category.add_unit (new Unit ("microlitre", _("Microlitres"), dpgettext2 (null, "unit-format", "%s μL"), "0.000001x", "1000000x", dpgettext2 (null, "unit-symbols", "mm³,μL,uL")));
69
weight_category.add_unit (new Unit ("tonne", _("Tonnes"), dpgettext2 (null, "unit-format", "%s T"), "1000x", "x/1000", dpgettext2 (null, "unit-symbols", "tonne,tonnes")));
70
weight_category.add_unit (new Unit ("kilograms", _("Kilograms"), dpgettext2 (null, "unit-format", "%s kg"), "x", "x", dpgettext2 (null, "unit-symbols", "kilogram,kilograms,kilogramme,kilogrammes,kg,kgs")));
71
weight_category.add_unit (new Unit ("pound", _("Pounds"), dpgettext2 (null, "unit-format", "%s lb"), "0.45359237x", "x/0.45359237", dpgettext2 (null, "unit-symbols", "pound,pounds,lb")));
72
weight_category.add_unit (new Unit ("ounce", _("Ounces"), dpgettext2 (null, "unit-format", "%s oz"), "0.02834952x", "x/0.02834952", dpgettext2 (null, "unit-symbols", "ounce,ounces,oz")));
73
weight_category.add_unit (new Unit ("gram", _("Grams"), dpgettext2 (null, "unit-format", "%s g"), "0.001x", "1000x", dpgettext2 (null, "unit-symbols", "gram,grams,gramme,grammes,g")));
74
duration_category.add_unit (new Unit ("year", _("Years"), dpgettext2 (null, "unit-format", "%s years"), "31557600x", "x/31557600", dpgettext2 (null, "unit-symbols", "year,years")));
75
duration_category.add_unit (new Unit ("day", _("Days"), dpgettext2 (null, "unit-format", "%s days"), "86400x", "x/86400", dpgettext2 (null, "unit-symbols", "day,days")));
76
duration_category.add_unit (new Unit ("hour", _("Hours"), dpgettext2 (null, "unit-format", "%s hours"), "3600x", "x/3600", dpgettext2 (null, "unit-symbols", "hour,hours")));
77
duration_category.add_unit (new Unit ("minute", _("Minutes"), dpgettext2 (null, "unit-format", "%s minutes"), "60x", "x/60", dpgettext2 (null, "unit-symbols", "minute,minutes")));
78
duration_category.add_unit (new Unit ("second", _("Seconds"), dpgettext2 (null, "unit-format", "%s s"), "x", "x", dpgettext2 (null, "unit-symbols", "second,seconds,s")));
79
duration_category.add_unit (new Unit ("millisecond", _("Milliseconds"), dpgettext2 (null, "unit-format", "%s ms"), "0.001x", "1000x", dpgettext2 (null, "unit-symbols", "millisecond,milliseconds,ms")));
80
duration_category.add_unit (new Unit ("microsecond", _("Microseconds"), dpgettext2 (null, "unit-format", "%s μs"), "0.000001x", "1000000x", dpgettext2 (null, "unit-symbols", "microsecond,microseconds,us,μs")));
81
temperature_category.add_unit (new Unit ("degree-celcius", _("Celsius"), dpgettext2 (null, "unit-format", "%s ˚C"), "x+273.15", "x-273.15", dpgettext2 (null, "unit-symbols", "degC,˚C")));
82
temperature_category.add_unit (new Unit ("degree-farenheit", _("Farenheit"), dpgettext2 (null, "unit-format", "%s ˚F"), "(x+459.67)*5/9", "x*9/5-459.67", dpgettext2 (null, "unit-symbols", "degF,˚F")));
83
temperature_category.add_unit (new Unit ("degree-kelvin", _("Kelvin"), dpgettext2 (null, "unit-format", "%s K"), "x", "x", dpgettext2 (null, "unit-symbols", "K")));
84
temperature_category.add_unit (new Unit ("degree-rankine", _("Rankine"), dpgettext2 (null, "unit-format", "%s ˚R"), "x*5/9", "x*9/5", dpgettext2 (null, "unit-symbols", "degR,˚R,˚Ra")));
86
var currency_category = default_unit_manager.add_category ("currency", _("Currency"));
87
var currencies = CurrencyManager.get_default ().get_currencies ();
88
currencies.sort ((a, b) => { return strcmp (a.display_name, b.display_name); });
89
foreach (var currency in currencies)
91
/* Translators: result of currency conversion, %s is the symbol, %%s is the placeholder for amount, i.e.: USD100 */
92
var format = _("%s%%s").printf (currency.symbol);
93
var unit = new Unit (currency.name, currency.display_name, format, null, null, currency.name);
94
currency_category.add_unit ( unit);
97
return default_unit_manager;
100
public UnitCategory add_category (string name, string display_name)
102
var category = new UnitCategory (name, display_name);
103
categories.append (category);
107
public List<UnitCategory> get_categories ()
109
var r = new List<UnitCategory> ();
110
foreach (var c in categories)
115
public UnitCategory? get_category (string category)
117
foreach (var c in categories)
118
if (c.name == category)
124
public Unit? get_unit_by_name (string name)
126
foreach (var c in categories)
128
var u = c.get_unit_by_name (name);
136
public Unit? get_unit_by_symbol (string symbol)
138
foreach (var c in categories)
140
var u = c.get_unit_by_symbol (symbol);
148
public Number? convert_by_symbol (Number x, string x_symbol, string z_symbol)
150
foreach (var c in categories)
152
var x_units = c.get_unit_by_symbol (x_symbol);
153
var z_units = c.get_unit_by_symbol (z_symbol);
154
if (x_units != null && z_units != null)
155
return c.convert (x, x_units, z_units);
162
public class UnitCategory : Object
164
private List<Unit> units;
166
private string _name;
167
public string name { owned get { return _name; } }
169
private string _display_name;
170
public string display_name { owned get { return _display_name; } }
172
public UnitCategory (string name, string display_name)
175
_display_name = display_name;
176
units = new List<Unit> ();
179
public void add_unit (Unit unit)
184
public Unit? get_unit_by_name (string name)
186
foreach (var unit in units)
187
if (unit.name == name)
193
public Unit? get_unit_by_symbol (string symbol)
195
foreach (var unit in units)
196
if (unit.matches_symbol (symbol))
202
public unowned List<Unit> get_units ()
207
public Number? convert (Number x, Unit x_units, Unit z_units)
209
var t = x_units.convert_from (x);
212
return z_units.convert_to (t);
216
public class Unit : Object
218
private string _name;
219
public string name { owned get { return _name; } }
221
private string _display_name;
222
public string display_name { owned get { return _display_name; } }
224
private string _format;
225
private List<string> _symbols;
226
private string? from_function;
227
private string? to_function;
228
private Serializer serializer;
230
public Unit (string name, string display_name, string format, string? from_function, string? to_function, string symbols)
232
serializer = new Serializer (DisplayFormat.AUTOMATIC, 10, 2);
233
serializer.set_leading_digits (6);
236
_display_name = display_name;
237
this._format = format;
238
this.from_function = from_function;
239
this.to_function = to_function;
240
_symbols = new List<string> ();
241
var symbol_names = symbols.split (",", 0);
242
foreach (var symbol_name in symbol_names)
243
_symbols.append (symbol_name);
246
public bool matches_symbol (string symbol)
248
foreach (var s in _symbols)
255
public unowned List<string> get_symbols ()
260
public Number? convert_from (Number x)
262
if (from_function != null)
263
return solve_function (from_function, x);
266
// FIXME: Hack to make currency work
267
var r = CurrencyManager.get_default ().get_value (name);
274
public Number? convert_to (Number x)
276
if (to_function != null)
277
return solve_function (to_function, x);
280
// FIXME: Hack to make currency work
281
var r = CurrencyManager.get_default ().get_value (name);
284
return x.multiply (r);
288
public string format (Number x)
290
var number_text = serializer.to_string (x);
291
return _format.printf (number_text);
294
private Number? solve_function (string function, Number x)
296
var equation = new UnitSolveEquation (function, x);
298
equation.wordlen = 32;
300
var z = equation.parse ();
302
warning ("Failed to convert value: %s", function);
308
private class UnitSolveEquation : Equation
312
public UnitSolveEquation (string function, Number x)
318
public override bool variable_is_defined (string name)
323
public override Number? get_variable (string name)
b'\\ No newline at end of file'