Update Spanish translation
[gnumeric.git] / src / go-data-slicer-field.c
blob344bff5c27b56ce78f5b5eabff9e394b2916046e
1 /*
2 * go-data-slicer-field.h : The definition of a content for a data slicer
4 * Copyright (C) 2008 Jody Goldberg (jody@gnome.org)
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation; either version 2 of the
9 * License, or (at your option) version 3.
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.
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 St, Fifth Floor, Boston, MA 02110-1301
19 * USA
22 #include <gnumeric-config.h>
23 #include <go-data-slicer-field-impl.h>
24 #include <go-data-slicer-impl.h>
25 #include <go-data-cache-field.h>
26 #include <go-data-cache.h>
28 #include <gsf/gsf-impl-utils.h>
29 #include <glib/gi18n-lib.h>
30 #include <string.h>
32 #define GO_DATA_SLICER_FIELD_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), GO_DATA_SLICER_FIELD_TYPE, GODataSlicerFieldClass))
33 #define IS_GO_DATA_SLICER_FIELD_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GO_DATA_SLICER_FIELD_TYPE))
34 #define GO_DATA_SLICER_FIELD_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GO_DATA_SLICER_FIELD_TYPE, GODataSlicerFieldClass))
36 enum {
37 PROP_0,
38 PROP_SLICER, /* GODataSlicer * */
39 PROP_NAME, /* GOString * */
40 PROP_INDEX, /* int */
41 PROP_DATA_CACHE_FIELD_INDEX, /* int */
42 PROP_AGGREGATIONS
45 static void
46 go_data_slicer_field_init (GODataSlicerField *dsf)
48 int i;
50 dsf->ds = NULL;
51 dsf->name = NULL;
52 dsf->indx = -1;
53 dsf->data_cache_field_indx = -1;
54 dsf->aggregations = 0;
56 for (i = 0 ; i < GDS_FIELD_TYPE_UNSET ; i++)
57 dsf->field_type_pos[i] = -1;
60 static GObjectClass *parent_klass;
61 static void
62 go_data_slicer_field_finalize (GObject *obj)
64 GODataSlicerField *dsf = (GODataSlicerField *)obj;
66 go_string_unref (dsf->name);
67 dsf->name = NULL;
69 parent_klass->finalize (obj);
72 static void
73 go_data_slicer_field_set_property (GObject *obj, guint property_id,
74 GValue const *value, GParamSpec *pspec)
76 GODataSlicerField *dsf = (GODataSlicerField *)obj;
78 switch (property_id) {
79 /* we do not hold a ref */
80 case PROP_SLICER:
81 dsf->ds = g_value_get_object (value);
82 break;
83 case PROP_NAME:
84 go_string_unref (dsf->name);
85 dsf->name = g_value_dup_boxed (value);
86 break;
87 case PROP_DATA_CACHE_FIELD_INDEX:
88 dsf->data_cache_field_indx = g_value_get_int (value);
89 break;
90 case PROP_AGGREGATIONS:
91 dsf->aggregations = g_value_get_uint (value);
92 break;
93 default:
94 G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, property_id, pspec);
98 static void
99 go_data_slicer_field_get_property (GObject *obj, guint property_id,
100 GValue *value, GParamSpec *pspec)
102 GODataSlicerField const *dsf = (GODataSlicerField const *)obj;
103 switch (property_id) {
104 case PROP_SLICER:
105 g_value_set_object (value, dsf->ds);
106 break;
107 case PROP_NAME:
108 g_value_set_boxed (value, dsf->name);
109 break; /* actual name, do not fall back to cache */
110 case PROP_INDEX:
111 g_value_set_int (value, dsf->indx);
112 break;
113 case PROP_DATA_CACHE_FIELD_INDEX:
114 g_value_set_int (value, dsf->data_cache_field_indx);
115 break;
116 case PROP_AGGREGATIONS:
117 g_value_set_uint (value, dsf->aggregations);
118 break;
119 default:
120 G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, property_id, pspec);
124 static void
125 go_data_slicer_field_class_init (GODataSlicerFieldClass *klass)
127 GObjectClass *gobject_class = (GObjectClass *)klass;
128 gobject_class->finalize = go_data_slicer_field_finalize;
129 gobject_class->set_property = go_data_slicer_field_set_property;
130 gobject_class->get_property = go_data_slicer_field_get_property;
132 g_object_class_install_property (gobject_class, PROP_SLICER,
133 g_param_spec_object ("slicer", NULL, NULL,
134 GO_DATA_SLICER_TYPE, GSF_PARAM_STATIC | G_PARAM_READWRITE));
135 g_object_class_install_property (gobject_class, PROP_NAME,
136 g_param_spec_boxed ("name", NULL, NULL, go_string_get_type (),
137 GSF_PARAM_STATIC | G_PARAM_READWRITE));
138 g_object_class_install_property (gobject_class, PROP_INDEX,
139 g_param_spec_int ("index", NULL,
140 "Index of the field within the GODataSlicer",
141 -1, G_MAXINT, -1,
142 GSF_PARAM_STATIC | G_PARAM_READABLE));
143 g_object_class_install_property (gobject_class, PROP_DATA_CACHE_FIELD_INDEX,
144 g_param_spec_int ("data-cache-field-index", NULL,
145 "Index of the underlying GODataCacheField",
146 -1, G_MAXINT, -1,
147 GSF_PARAM_STATIC | G_PARAM_READWRITE));
148 g_object_class_install_property (gobject_class, PROP_AGGREGATIONS,
149 g_param_spec_uint ("aggregations", NULL,
150 "bitwise OR of the set of aggregations",
151 0, ~0, 0,
152 GSF_PARAM_STATIC | G_PARAM_READWRITE));
154 parent_klass = g_type_class_peek_parent (klass);
157 GSF_CLASS (GODataSlicerField, go_data_slicer_field,
158 go_data_slicer_field_class_init, go_data_slicer_field_init,
159 G_TYPE_OBJECT)
162 * go_data_slicer_field_get_cache_field:
163 * @dsf: #GODataSlicerField const
165 * Returns : the underlying cache field
167 GODataCacheField *
168 go_data_slicer_field_get_cache_field (GODataSlicerField const *dsf)
170 g_return_val_if_fail (IS_GO_DATA_SLICER_FIELD (dsf), NULL);
171 return go_data_cache_get_field (go_data_slicer_get_cache (dsf->ds),
172 dsf->data_cache_field_indx);
176 * go_data_slicer_field_get_name:
177 * @dsf: #GODataSlicerField const
179 * If @dsf has a name return that, otherwise default to the name of the
180 * underlying cache field. If there is a need (e.g. for export) to get the
181 * exact name without the default, use the properties.
183 * Returns: the name of the field.
185 GOString *
186 go_data_slicer_field_get_name (GODataSlicerField const *dsf)
188 g_return_val_if_fail (IS_GO_DATA_SLICER_FIELD (dsf), NULL);
189 if (dsf->name)
190 return dsf->name;
191 return go_data_cache_field_get_name (
192 go_data_slicer_field_get_cache_field (dsf));
196 go_data_slicer_field_get_field_type_pos (GODataSlicerField const *dsf,
197 GODataSlicerFieldType field_type)
199 g_return_val_if_fail (IS_GO_DATA_SLICER_FIELD (dsf), -1);
200 g_return_val_if_fail (field_type > GDS_FIELD_TYPE_UNSET &&
201 field_type < GDS_FIELD_TYPE_MAX, -1);
202 return dsf->field_type_pos[field_type];
206 * go_data_slicer_field_set_field_type_pos:
207 * @dsf: #GODataSlicerField
208 * @field_type: #GODataSlicerFieldType
209 * @pos: >= len => append, else move ahead of @pos, -1 removes
211 * Make @dsf a @field_type, and move it to position @pos other @field_type's
212 * in the slicer.
214 void
215 go_data_slicer_field_set_field_type_pos (GODataSlicerField *dsf,
216 GODataSlicerFieldType field_type,
217 int pos)
219 GArray *headers;
220 int cur_pos, i;
222 g_return_if_fail (IS_GO_DATA_SLICER_FIELD (dsf));
223 g_return_if_fail (IS_GO_DATA_SLICER (dsf->ds));
224 g_return_if_fail (field_type > GDS_FIELD_TYPE_UNSET &&
225 field_type < GDS_FIELD_TYPE_MAX);
227 headers = dsf->ds->fields [field_type];
228 if (pos < 0) pos = -1;
229 else if (pos >= (int)headers->len) pos = headers->len;
231 cur_pos = dsf->field_type_pos[field_type];
232 if (pos == cur_pos) return;
234 /* Remove it */
235 if (cur_pos >= 0) {
236 g_return_if_fail (cur_pos < (int)headers->len);
237 g_return_if_fail (g_array_index (headers, int, cur_pos) == dsf->indx);
239 g_array_remove_index (headers, cur_pos);
240 dsf->field_type_pos[field_type] = -1;
241 for (i = cur_pos; i < (int)headers->len ; i++) {
242 GODataSlicerField *other = go_data_slicer_get_field (dsf->ds,
243 g_array_index (headers, int, i));
244 if (NULL != other && other->field_type_pos[field_type] == (i+1))
245 --(other->field_type_pos[field_type]);
246 else
247 g_warning ("inconsistent field_type_pos");
250 /* adjust target index if our removal would change it */
251 if (cur_pos < pos) pos--;
254 /* put it back in the right place */
255 if (pos >= 0) {
256 if (pos < (int)headers->len) {
257 g_array_insert_val (headers, pos, dsf->indx);
258 for (i = pos; ++i < (int)headers->len ; ) {
259 GODataSlicerField *other = go_data_slicer_get_field (dsf->ds,
260 g_array_index (headers, int, i));
261 if (NULL != other && other->field_type_pos[field_type] == (i-1))
262 ++(other->field_type_pos[field_type]);
263 else
264 g_warning ("inconsistent field_type_pos");
266 } else
267 g_array_append_val (headers, dsf->indx);
269 dsf->field_type_pos[field_type] = pos;