Completely rewrite src/data/format.[ch], to achieve better
[pspp-builds.git] / src / ui / gui / psppire-variable.c
1 /* 
2     PSPPIRE --- A Graphical User Interface for PSPP
3     Copyright (C) 2004, 2006  Free Software Foundation
4     Written by John Darrington
5
6     This program is free software; you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by
8     the Free Software Foundation; either version 2 of the License, or
9     (at your option) any later version.
10
11     This program is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14     GNU General Public License for more details.
15
16     You should have received a copy of the GNU General Public License
17     along with this program; if not, write to the Free Software
18     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19     02110-1301, USA. */
20
21 #include <string.h>
22 #include <stdlib.h>
23
24 #include <data/missing-values.h>
25 #include <data/value-labels.h>
26 #include <data/format.h>
27 #include <libpspp/message.h>
28
29 #include <libpspp/misc.h>
30
31 #include "psppire-variable.h"
32 #include "psppire-dict.h"
33
34
35
36 gboolean
37 psppire_variable_set_name(struct PsppireVariable *pv, const gchar *text)
38 {
39   g_return_val_if_fail(pv, FALSE);
40   g_return_val_if_fail(pv->dict, FALSE);
41   g_return_val_if_fail(pv->v, FALSE);
42
43   if ( !text) 
44     return FALSE;
45
46   if ( 0 == strcmp(pv->v->name, text))
47     return FALSE;
48
49   if ( ! psppire_dict_check_name(pv->dict, text, TRUE) )
50     return FALSE;
51
52   dict_rename_var(pv->dict->dict, pv->v, text);
53
54   psppire_dict_var_changed(pv->dict, pv->v->index);
55
56   return TRUE;
57 }
58
59
60 gboolean
61 psppire_variable_set_columns(struct PsppireVariable *pv, gint columns)
62 {
63   g_return_val_if_fail(pv, FALSE);
64   g_return_val_if_fail(pv->dict, FALSE);
65   g_return_val_if_fail(pv->v, FALSE);
66
67   pv->v->display_width = columns;
68   
69   psppire_dict_var_changed(pv->dict, pv->v->index);
70
71   return TRUE;
72 }
73
74 gboolean
75 psppire_variable_set_label(struct PsppireVariable *pv, const gchar *label)
76 {
77   g_return_val_if_fail(pv, FALSE);
78   g_return_val_if_fail(pv->dict, FALSE);
79   g_return_val_if_fail(pv->v, FALSE);
80
81   g_free(pv->v->label);
82   pv->v->label = g_strdup(label);
83
84   psppire_dict_var_changed(pv->dict, pv->v->index);
85
86   return TRUE;
87 }
88
89
90 gboolean
91 psppire_variable_set_decimals(struct PsppireVariable *pv, gint decimals)
92 {
93   struct fmt_spec fmt;
94
95   g_return_val_if_fail(pv, FALSE);
96   g_return_val_if_fail(pv->dict, FALSE);
97   g_return_val_if_fail(pv->v, FALSE);
98
99   fmt = pv->v->write;
100
101   fmt.d = decimals;
102
103   return psppire_variable_set_format(pv, &fmt);
104 }
105
106
107
108 gboolean
109 psppire_variable_set_width(struct PsppireVariable *pv, gint width)
110 {
111   struct fmt_spec fmt ;
112   g_return_val_if_fail(pv, FALSE);
113   g_return_val_if_fail(pv->dict, FALSE);
114   g_return_val_if_fail(pv->v, FALSE);
115
116   fmt = pv->v->write;
117
118   fmt.w = width;
119
120   if ( pv->v->type == ALPHA ) 
121     {
122       gint old_var_cnt , new_var_cnt ;
123
124       if ( pv->v->width == 0 ) 
125         old_var_cnt = 1;
126       else
127         old_var_cnt = DIV_RND_UP(pv->v->width, MAX_SHORT_STRING);
128       
129       new_var_cnt = DIV_RND_UP(width, MAX_SHORT_STRING);
130     pv->v->width = width;
131
132       psppire_dict_resize_variable(pv->dict, pv,
133                                    old_var_cnt, new_var_cnt);
134     }
135
136   return psppire_variable_set_format(pv, &fmt);
137 }
138
139
140 gboolean
141 psppire_variable_set_type(struct PsppireVariable *pv, int type)
142 {
143   gint old_var_cnt , new_var_cnt ;
144
145   g_return_val_if_fail(pv, FALSE);
146   g_return_val_if_fail(pv->dict, FALSE);
147   g_return_val_if_fail(pv->v, FALSE);
148
149   pv->v->type = type; 
150
151   if ( pv->v->width == 0 ) 
152     old_var_cnt = 1;
153   else
154     old_var_cnt = DIV_RND_UP(pv->v->width, MAX_SHORT_STRING);
155
156   if ( type == NUMERIC ) 
157     pv->v->width = 0;
158
159   if ( pv->v->width == 0 ) 
160     new_var_cnt = 1;
161   else
162     new_var_cnt = DIV_RND_UP(pv->v->width, MAX_SHORT_STRING);
163
164   psppire_dict_resize_variable(pv->dict, pv,
165                                old_var_cnt, new_var_cnt);
166
167   psppire_dict_var_changed(pv->dict, pv->v->index);
168   return TRUE;
169 }
170
171
172 gboolean
173 psppire_variable_set_format(struct PsppireVariable *pv, struct fmt_spec *fmt)
174 {
175   g_return_val_if_fail(pv, FALSE);
176   g_return_val_if_fail(pv->dict, FALSE);
177   g_return_val_if_fail(pv->v, FALSE);
178
179   msg_disable ();
180   if ( fmt_check_output(fmt) 
181        && fmt_check_type_compat (fmt, pv->v->type)
182        && fmt_check_width_compat (fmt, pv->v->width)) 
183     {
184       msg_enable ();
185       pv->v->write = pv->v->print = *fmt;
186       psppire_dict_var_changed(pv->dict, pv->v->index);
187       return TRUE;
188     }
189   msg_enable ();
190
191   return FALSE;
192 }
193
194
195 gboolean
196 psppire_variable_set_value_labels(const struct PsppireVariable *pv,
197                                const struct val_labs *vls)
198 {
199   g_return_val_if_fail(pv, FALSE);
200   g_return_val_if_fail(pv->dict, FALSE);
201   g_return_val_if_fail(pv->v, FALSE);
202
203   val_labs_destroy(pv->v->val_labs);
204   pv->v->val_labs = val_labs_copy(vls);
205
206   psppire_dict_var_changed(pv->dict, pv->v->index);
207   return TRUE;
208 }
209
210 gboolean 
211 psppire_variable_set_missing(const struct PsppireVariable *pv,
212                           const struct missing_values *miss)
213 {
214   g_return_val_if_fail(pv, FALSE);
215   g_return_val_if_fail(pv->dict, FALSE);
216   g_return_val_if_fail(pv->v, FALSE);
217
218   mv_copy(&pv->v->miss, miss);
219
220   psppire_dict_var_changed(pv->dict, pv->v->index);
221   return TRUE;
222 }
223
224 gboolean
225 psppire_variable_set_write_spec(const struct PsppireVariable *pv, struct fmt_spec fmt)
226 {
227   g_return_val_if_fail(pv, FALSE);
228   g_return_val_if_fail(pv->v, FALSE);
229
230   pv->v->write = fmt;
231
232   psppire_dict_var_changed(pv->dict, pv->v->index);
233   return TRUE;
234 }
235
236 gboolean
237 psppire_variable_set_print_spec(const struct PsppireVariable *pv, struct fmt_spec fmt)
238 {
239   g_return_val_if_fail(pv, FALSE);
240   g_return_val_if_fail(pv->v, FALSE);
241
242   pv->v->print = fmt;
243
244   psppire_dict_var_changed(pv->dict, pv->v->index);
245   return TRUE;
246 }
247
248
249
250 gboolean
251 psppire_variable_set_alignment(struct PsppireVariable *pv, gint align)
252 {
253   g_return_val_if_fail(pv, FALSE);
254   g_return_val_if_fail(pv->dict, FALSE);
255   g_return_val_if_fail(pv->v, FALSE);
256
257   pv->v->alignment = align;
258
259   psppire_dict_var_changed(pv->dict, pv->v->index);
260   return TRUE;
261 }
262
263
264 gboolean
265 psppire_variable_set_measure(struct PsppireVariable *pv, gint measure)
266 {
267   g_return_val_if_fail(pv, FALSE);
268   g_return_val_if_fail(pv->dict, FALSE);
269   g_return_val_if_fail(pv->v, FALSE);
270
271   pv->v->measure = measure + 1;
272
273   psppire_dict_var_changed(pv->dict, pv->v->index);
274   return TRUE;
275 }
276
277
278 const struct fmt_spec *
279 psppire_variable_get_write_spec(const struct PsppireVariable *pv)
280 {
281   g_return_val_if_fail(pv, NULL);
282   g_return_val_if_fail(pv->v, NULL);
283
284
285   return &pv->v->write;
286 }
287
288
289 const gchar *
290 psppire_variable_get_name(const struct PsppireVariable *pv)
291 {
292   g_return_val_if_fail(pv, NULL);
293   g_return_val_if_fail(pv->v, NULL);
294
295   return pv->v->name;
296 }
297
298
299 gint
300 psppire_variable_get_columns(const struct PsppireVariable *pv)
301 {
302   g_return_val_if_fail(pv, -1);
303   g_return_val_if_fail(pv->v, -1);
304
305   return pv->v->display_width;
306 }
307
308
309
310 const gchar *
311 psppire_variable_get_label(const struct PsppireVariable *pv)
312 {
313   g_return_val_if_fail(pv, NULL);
314   g_return_val_if_fail(pv->v, NULL);
315
316   return pv->v->label;
317 }
318
319
320 const struct missing_values *
321 psppire_variable_get_missing(const struct PsppireVariable *pv)
322 {
323   g_return_val_if_fail(pv, NULL);
324   g_return_val_if_fail(pv->v, NULL);
325
326   return &pv->v->miss;
327 }
328
329
330 const struct val_labs *
331 psppire_variable_get_value_labels(const struct PsppireVariable *pv)
332 {
333   g_return_val_if_fail(pv, NULL);
334   g_return_val_if_fail(pv->v, NULL);
335
336   return pv->v->val_labs;
337 }
338
339
340 gint
341 psppire_variable_get_alignment(const struct PsppireVariable *pv)
342 {
343   g_return_val_if_fail(pv, -1);
344   g_return_val_if_fail(pv->v, -1);
345
346   return pv->v->alignment;
347 }
348
349
350
351 gint
352 psppire_variable_get_measure(const struct PsppireVariable *pv)
353 {
354   g_return_val_if_fail(pv, -1);
355   g_return_val_if_fail(pv->v, -1);
356
357   return pv->v->measure - 1;
358 }
359
360 gint
361 psppire_variable_get_type(const struct PsppireVariable *pv)
362 {
363   g_return_val_if_fail(pv, -1);
364   g_return_val_if_fail(pv->v, -1);
365
366   return pv->v->type;
367 }
368
369
370 gint
371 psppire_variable_get_width(const struct PsppireVariable *pv)
372 {
373   g_return_val_if_fail(pv, -1);
374   g_return_val_if_fail(pv->v, -1);
375
376   return pv->v->width;
377 }
378
379
380 gint
381 psppire_variable_get_fv(const struct PsppireVariable *pv)
382 {
383   g_return_val_if_fail(pv, -1);
384   g_return_val_if_fail(pv->v, -1);
385
386   return pv->v->fv;
387 }
388
389
390
391 gint
392 psppire_variable_get_index(const struct PsppireVariable *pv)
393 {
394   g_return_val_if_fail(pv, -1);
395   g_return_val_if_fail(pv->v, -1);
396
397   return pv->v->index;
398 }
399