Add temperature conversion
[gcalctool.git] / src / unit.c
blobed12c5ea884e079916a7aba6c246491ec32459db
1 #include <string.h>
3 #include "unit.h"
4 #include "mp-serializer.h"
5 #include "mp-equation.h"
6 #include "currency-manager.h" // FIXME: Move out of here
8 struct UnitPrivate
10 gchar *name;
11 gchar *display_name;
12 gchar *format;
13 GList *symbols;
14 gchar *from_function;
15 gchar *to_function;
16 MpSerializer *serializer;
19 G_DEFINE_TYPE (Unit, unit, G_TYPE_OBJECT);
22 Unit *
23 unit_new(const gchar *name,
24 const gchar *display_name,
25 const gchar *format,
26 const gchar *from_function,
27 const gchar *to_function,
28 const gchar *symbols)
30 Unit *unit = g_object_new(unit_get_type(), NULL);
31 gchar **symbol_names;
32 int i;
34 unit->priv->name = g_strdup(name);
35 unit->priv->display_name = g_strdup(display_name);
36 unit->priv->format = g_strdup(format);
37 unit->priv->from_function = g_strdup(from_function);
38 unit->priv->to_function = g_strdup(to_function);
39 symbol_names = g_strsplit(symbols, ",", 0);
40 for (i = 0; symbol_names[i]; i++)
41 unit->priv->symbols = g_list_append(unit->priv->symbols, g_strdup(symbol_names[i]));
42 g_free(symbol_names);
44 return unit;
48 const gchar *
49 unit_get_name(Unit *unit)
51 return unit->priv->name;
55 const gchar *
56 unit_get_display_name(Unit *unit)
58 return unit->priv->display_name;
62 gboolean
63 unit_matches_symbol(Unit *unit, const gchar *symbol)
65 GList *iter;
67 for (iter = unit->priv->symbols; iter; iter = iter->next) {
68 gchar *s = iter->data;
69 if (strcmp(s, symbol) == 0)
70 return TRUE;
73 return FALSE;
77 const GList *
78 unit_get_symbols(Unit *unit)
80 return unit->priv->symbols;
84 static int
85 variable_is_defined(const char *name, void *data)
87 return TRUE;
91 static int
92 get_variable(const char *name, MPNumber *z, void *data)
94 MPNumber *x = data;
95 mp_set_from_mp(x, z);
96 return TRUE;
100 static void
101 solve_function(const gchar *function, const MPNumber *x, MPNumber *z)
103 MPEquationOptions options;
104 int ret;
106 memset(&options, 0, sizeof(options));
107 options.base = 10;
108 options.wordlen = 32;
109 options.variable_is_defined = variable_is_defined;
110 options.get_variable = get_variable;
111 options.callback_data = (void *)x;
112 ret = mp_equation_parse(function, &options, z, NULL);
113 if (ret)
114 g_warning("Failed to convert value: %s", function);
118 void
119 unit_convert_from(Unit *unit, const MPNumber *x, MPNumber *z)
121 if (unit->priv->from_function)
122 solve_function(unit->priv->from_function, x, z);
123 else {
124 // FIXME: Hack to make currency work
125 const MPNumber *r;
126 r = currency_manager_get_value(currency_manager_get_default(), unit->priv->name);
127 mp_divide(x, r, z);
132 void
133 unit_convert_to(Unit *unit, const MPNumber *x, MPNumber *z)
135 if (unit->priv->from_function)
136 solve_function(unit->priv->to_function, x, z);
137 else {
138 // FIXME: Hack to make currency work
139 const MPNumber *r;
140 r = currency_manager_get_value(currency_manager_get_default(), unit->priv->name);
141 mp_multiply(x, r, z);
146 gchar *
147 unit_format(Unit *unit, MPNumber *x)
149 gchar *number_text, *text;
151 number_text = mp_serializer_to_string(unit->priv->serializer, x);
152 text = g_strdup_printf(unit->priv->format, number_text);
153 g_free(number_text);
155 return text;
159 static void
160 unit_class_init(UnitClass *klass)
162 g_type_class_add_private(klass, sizeof(UnitPrivate));
166 static void
167 unit_init(Unit *unit)
169 unit->priv = G_TYPE_INSTANCE_GET_PRIVATE(unit, unit_get_type(), UnitPrivate);
170 unit->priv->serializer = mp_serializer_new(MP_DISPLAY_FORMAT_AUTOMATIC, 10, 2);