~ubuntu-branches/ubuntu/precise/gcalctool/precise-proposed

« back to all changes in this revision

Viewing changes to src/unit.c

  • Committer: Bazaar Package Importer
  • Author(s): Robert Ancell
  • Date: 2011-02-01 14:37:04 UTC
  • mfrom: (1.3.17 upstream)
  • Revision ID: james.westby@ubuntu.com-20110201143704-ipo3nv351hrcfrlf
Tags: 5.91.6-0ubuntu1
New upstream release

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#include <string.h>
 
2
 
 
3
#include "unit.h"
 
4
#include "mp-serializer.h"
 
5
#include "mp-equation.h"
 
6
#include "currency-manager.h" // FIXME: Move out of here
 
7
 
 
8
struct UnitPrivate
 
9
{
 
10
    gchar *name;
 
11
    gchar *display_name;
 
12
    gchar *format;
 
13
    GList *symbols;
 
14
    gchar *from_function;
 
15
    gchar *to_function;
 
16
    MpSerializer *serializer;
 
17
};
 
18
 
 
19
G_DEFINE_TYPE (Unit, unit, G_TYPE_OBJECT);
 
20
 
 
21
 
 
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)
 
29
{
 
30
    Unit *unit = g_object_new(unit_get_type(), NULL);
 
31
    gchar **symbol_names;
 
32
    int i;
 
33
 
 
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);
 
43
 
 
44
    return unit;
 
45
}
 
46
 
 
47
 
 
48
const gchar *
 
49
unit_get_name(Unit *unit)
 
50
{
 
51
    return unit->priv->name;
 
52
}
 
53
 
 
54
 
 
55
const gchar *
 
56
unit_get_display_name(Unit *unit)
 
57
{
 
58
    return unit->priv->display_name;
 
59
}
 
60
 
 
61
 
 
62
gboolean
 
63
unit_matches_symbol(Unit *unit, const gchar *symbol)
 
64
{
 
65
    GList *iter;
 
66
 
 
67
    for (iter = unit->priv->symbols; iter; iter = iter->next) {
 
68
        gchar *s = iter->data;
 
69
        if (strcmp(s, symbol) == 0)
 
70
            return TRUE;
 
71
    }
 
72
 
 
73
    return FALSE;
 
74
}
 
75
 
 
76
 
 
77
const GList *
 
78
unit_get_symbols(Unit *unit)
 
79
{
 
80
    return unit->priv->symbols;
 
81
}
 
82
 
 
83
 
 
84
static int
 
85
variable_is_defined(const char *name, void *data)
 
86
{
 
87
    return TRUE;
 
88
}
 
89
 
 
90
 
 
91
static int
 
92
get_variable(const char *name, MPNumber *z, void *data)
 
93
{
 
94
    MPNumber *x = data;
 
95
    mp_set_from_mp(x, z);
 
96
    return TRUE;
 
97
}
 
98
 
 
99
 
 
100
static gboolean
 
101
solve_function(const gchar *function, const MPNumber *x, MPNumber *z)
 
102
{
 
103
    MPEquationOptions options;
 
104
    int ret;
 
105
 
 
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);
 
115
        return FALSE;
 
116
    }
 
117
 
 
118
    return TRUE;
 
119
}
 
120
 
 
121
 
 
122
gboolean
 
123
unit_convert_from(Unit *unit, const MPNumber *x, MPNumber *z)
 
124
{
 
125
    if (unit->priv->from_function)
 
126
        return solve_function(unit->priv->from_function, x, z);
 
127
    else {
 
128
        // FIXME: Hack to make currency work
 
129
        const MPNumber *r;
 
130
        r = currency_manager_get_value(currency_manager_get_default(), unit->priv->name);
 
131
        if (!r)
 
132
            return FALSE;
 
133
        mp_divide(x, r, z);
 
134
 
 
135
        return TRUE;
 
136
    }
 
137
}
 
138
 
 
139
 
 
140
gboolean
 
141
unit_convert_to(Unit *unit, const MPNumber *x, MPNumber *z)
 
142
{
 
143
    if (unit->priv->from_function)
 
144
        return solve_function(unit->priv->to_function, x, z);
 
145
    else {
 
146
        // FIXME: Hack to make currency work
 
147
        const MPNumber *r;
 
148
        r = currency_manager_get_value(currency_manager_get_default(), unit->priv->name);
 
149
        if (!r)
 
150
            return FALSE;
 
151
        mp_multiply(x, r, z);
 
152
 
 
153
        return TRUE;
 
154
    }
 
155
}
 
156
 
 
157
 
 
158
gchar *
 
159
unit_format(Unit *unit, MPNumber *x)
 
160
{
 
161
    gchar *number_text, *text;
 
162
 
 
163
    number_text = mp_serializer_to_string(unit->priv->serializer, x);
 
164
    text = g_strdup_printf(unit->priv->format, number_text);
 
165
    g_free(number_text);
 
166
 
 
167
    return text;
 
168
}
 
169
 
 
170
 
 
171
static void
 
172
unit_class_init(UnitClass *klass)
 
173
{
 
174
    g_type_class_add_private(klass, sizeof(UnitPrivate));
 
175
}
 
176
 
 
177
 
 
178
static void
 
179
unit_init(Unit *unit)
 
180
{
 
181
    unit->priv = G_TYPE_INSTANCE_GET_PRIVATE(unit, unit_get_type(), UnitPrivate);
 
182
    unit->priv->serializer = mp_serializer_new(MP_DISPLAY_FORMAT_AUTOMATIC, 10, 2);
 
183
}