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
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>
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))
38 PROP_SLICER
, /* GODataSlicer * */
39 PROP_NAME
, /* GOString * */
41 PROP_DATA_CACHE_FIELD_INDEX
, /* int */
46 go_data_slicer_field_init (GODataSlicerField
*dsf
)
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
;
62 go_data_slicer_field_finalize (GObject
*obj
)
64 GODataSlicerField
*dsf
= (GODataSlicerField
*)obj
;
66 go_string_unref (dsf
->name
);
69 parent_klass
->finalize (obj
);
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 */
81 dsf
->ds
= g_value_get_object (value
);
84 go_string_unref (dsf
->name
);
85 dsf
->name
= g_value_dup_boxed (value
);
87 case PROP_DATA_CACHE_FIELD_INDEX
:
88 dsf
->data_cache_field_indx
= g_value_get_int (value
);
90 case PROP_AGGREGATIONS
:
91 dsf
->aggregations
= g_value_get_uint (value
);
94 G_OBJECT_WARN_INVALID_PROPERTY_ID (obj
, property_id
, pspec
);
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
) {
105 g_value_set_object (value
, dsf
->ds
);
108 g_value_set_boxed (value
, dsf
->name
);
109 break; /* actual name, do not fall back to cache */
111 g_value_set_int (value
, dsf
->indx
);
113 case PROP_DATA_CACHE_FIELD_INDEX
:
114 g_value_set_int (value
, dsf
->data_cache_field_indx
);
116 case PROP_AGGREGATIONS
:
117 g_value_set_uint (value
, dsf
->aggregations
);
120 G_OBJECT_WARN_INVALID_PROPERTY_ID (obj
, property_id
, pspec
);
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",
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",
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",
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
,
162 * go_data_slicer_field_get_cache_field:
163 * @dsf: #GODataSlicerField const
165 * Returns : the underlying cache field
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.
186 go_data_slicer_field_get_name (GODataSlicerField
const *dsf
)
188 g_return_val_if_fail (IS_GO_DATA_SLICER_FIELD (dsf
), NULL
);
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
215 go_data_slicer_field_set_field_type_pos (GODataSlicerField
*dsf
,
216 GODataSlicerFieldType field_type
,
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;
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
]);
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 */
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
]);
264 g_warning ("inconsistent field_type_pos");
267 g_array_append_val (headers
, dsf
->indx
);
269 dsf
->field_type_pos
[field_type
] = pos
;