Bump version number
[gcalctool.git] / src / unit.c
blobf7c027739f6388734dd4c183824ca506283bc17f
1 /*
2 * Copyright (C) 1987-2008 Sun Microsystems, Inc. All Rights Reserved.
3 * Copyright (C) 2008-2011 Robert Ancell.
4 *
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
9 * license.
12 #include <string.h>
14 #include "unit.h"
15 #include "mp-serializer.h"
16 #include "mp-equation.h"
17 #include "currency-manager.h" // FIXME: Move out of here
19 struct UnitPrivate
21 gchar *name;
22 gchar *display_name;
23 gchar *format;
24 GList *symbols;
25 gchar *from_function;
26 gchar *to_function;
27 MpSerializer *serializer;
30 G_DEFINE_TYPE (Unit, unit, G_TYPE_OBJECT);
33 Unit *
34 unit_new(const gchar *name,
35 const gchar *display_name,
36 const gchar *format,
37 const gchar *from_function,
38 const gchar *to_function,
39 const gchar *symbols)
41 Unit *unit = g_object_new(unit_get_type(), NULL);
42 gchar **symbol_names;
43 int i;
45 unit->priv->name = g_strdup(name);
46 unit->priv->display_name = g_strdup(display_name);
47 unit->priv->format = g_strdup(format);
48 unit->priv->from_function = g_strdup(from_function);
49 unit->priv->to_function = g_strdup(to_function);
50 symbol_names = g_strsplit(symbols, ",", 0);
51 for (i = 0; symbol_names[i]; i++)
52 unit->priv->symbols = g_list_append(unit->priv->symbols, g_strdup(symbol_names[i]));
53 g_free(symbol_names);
55 return unit;
59 const gchar *
60 unit_get_name(Unit *unit)
62 g_return_val_if_fail (unit != NULL, NULL);
63 return unit->priv->name;
67 const gchar *
68 unit_get_display_name(Unit *unit)
70 g_return_val_if_fail (unit != NULL, NULL);
71 return unit->priv->display_name;
75 gboolean
76 unit_matches_symbol(Unit *unit, const gchar *symbol)
78 GList *iter;
80 g_return_val_if_fail (unit != NULL, FALSE);
81 g_return_val_if_fail (symbol != NULL, FALSE);
83 for (iter = unit->priv->symbols; iter; iter = iter->next) {
84 gchar *s = iter->data;
85 if (strcmp(s, symbol) == 0)
86 return TRUE;
89 return FALSE;
93 const GList *
94 unit_get_symbols(Unit *unit)
96 g_return_val_if_fail (unit != NULL, NULL);
97 return unit->priv->symbols;
101 static int
102 variable_is_defined(const char *name, void *data)
104 return TRUE;
108 static int
109 get_variable(const char *name, MPNumber *z, void *data)
111 MPNumber *x = data;
112 mp_set_from_mp(x, z);
113 return TRUE;
117 static gboolean
118 solve_function(const gchar *function, const MPNumber *x, MPNumber *z)
120 MPEquationOptions options;
121 int ret;
123 memset(&options, 0, sizeof(options));
124 options.base = 10;
125 options.wordlen = 32;
126 options.variable_is_defined = variable_is_defined;
127 options.get_variable = get_variable;
128 options.callback_data = (void *)x;
129 ret = mp_equation_parse(function, &options, z, NULL);
130 if (ret) {
131 g_warning("Failed to convert value: %s", function);
132 return FALSE;
135 return TRUE;
139 gboolean
140 unit_convert_from(Unit *unit, const MPNumber *x, MPNumber *z)
142 g_return_val_if_fail(unit != NULL, FALSE);
143 g_return_val_if_fail(x != NULL, FALSE);
144 g_return_val_if_fail(x != NULL, FALSE);
146 if (unit->priv->from_function)
147 return solve_function(unit->priv->from_function, x, z);
148 else {
149 // FIXME: Hack to make currency work
150 const MPNumber *r;
151 r = currency_manager_get_value(currency_manager_get_default(), unit->priv->name);
152 if (!r)
153 return FALSE;
154 mp_divide(x, r, z);
156 return TRUE;
161 gboolean
162 unit_convert_to(Unit *unit, const MPNumber *x, MPNumber *z)
164 g_return_val_if_fail(unit != NULL, FALSE);
165 g_return_val_if_fail(x != NULL, FALSE);
166 g_return_val_if_fail(x != NULL, FALSE);
168 if (unit->priv->from_function)
169 return solve_function(unit->priv->to_function, x, z);
170 else {
171 // FIXME: Hack to make currency work
172 const MPNumber *r;
173 r = currency_manager_get_value(currency_manager_get_default(), unit->priv->name);
174 if (!r)
175 return FALSE;
176 mp_multiply(x, r, z);
178 return TRUE;
183 gchar *
184 unit_format(Unit *unit, MPNumber *x)
186 gchar *number_text, *text;
188 g_return_val_if_fail(unit != NULL, FALSE);
189 g_return_val_if_fail(x != NULL, FALSE);
191 number_text = mp_serializer_to_string(unit->priv->serializer, x);
192 text = g_strdup_printf(unit->priv->format, number_text);
193 g_free(number_text);
195 return text;
199 static void
200 unit_class_init(UnitClass *klass)
202 g_type_class_add_private(klass, sizeof(UnitPrivate));
206 static void
207 unit_init(Unit *unit)
209 unit->priv = G_TYPE_INSTANCE_GET_PRIVATE(unit, unit_get_type(), UnitPrivate);
210 unit->priv->serializer = mp_serializer_new(MP_DISPLAY_FORMAT_AUTOMATIC, 10, 2);
211 mp_serializer_set_leading_digits(unit->priv->serializer, 6);